Commit bd93aa1a by David Malcolm Committed by David Malcolm

PR jit/66539: Add parentheses as needed to gcc_jit_object_get_debug_string

gcc/jit/ChangeLog:
	PR jit/66539
	* jit-recording.c: Within namespace gcc::jit::recording::
	(rvalue::get_debug_string_parens): New function.
	(binary_op::make_debug_string): Update to mimic C precedence
	rules.
	(binary_op_precedence): New array.
	(binary_op::get_precedence): New function.
	(comparison::make_debug_string): Update to mimic C precedence
	rules.
	(comparison_precedence): New array.
	(comparison::get_precedence): New function.
	(cast::make_debug_string): Update to mimic C precedence rules.
	(call::make_debug_string): Likewise.
	(call_through_ptr::make_debug_string): Likewise.
	(array_access::make_debug_string): Likewise.
	(access_field_of_lvalue::make_debug_string): Likewise.
	(access_field_rvalue::make_debug_string): Likewise.
	(dereference_field_rvalue::make_debug_string): Likewise.
	(dereference_rvalue::make_debug_string): Likewise.
	(get_address_of_lvalue::make_debug_string): Likewise.
	* jit-recording.h: Within namespace gcc::jit::recording::
	(precedence): New enum.
	(rvalue::rvalue): Initialize field "m_parenthesized_string".
	(rvalue::get_debug_string_parens): New method.
	(rvalue::get_precedence): New pure virtual function.
	(rvalue::m_parenthesized_string): New field.
	(param::get_precedence): New function.
	(global::get_precedence): New function.
	(memento_of_new_rvalue_from_const::get_precedence): New function.
	(memento_of_new_string_literal::get_precedence): New function.
	(unary_op::get_precedence): New function.
	(binary_op::get_precedence): New function.
	(comparison::get_precedence): New function.
	(cast::get_precedence): New function.
	(call::get_precedence): New function.
	(call_through_ptr::get_precedence): New function.
	(array_access::get_precedence): New function.
	(access_field_of_lvalue::get_precedence): New function.
	(access_field_rvalue::get_precedence): New function.
	(dereference_field_rvalue::get_precedence): New function.
	(dereference_rvalue::get_precedence): New function.
	(get_address_of_lvalue::get_precedence): New function.
	(local::get_precedence): New function.

gcc/testsuite/ChangeLog:
	PR jit/66539
	* jit.dg/all-non-failing-tests.h: Add test-debug-strings.c.
	* jit.dg/test-debug-strings.c: New test case.
	* jit.dg/test-quadratic.c (make_calc_discriminant): Verify that
	the discriminant has a sane debug string.

From-SVN: r224531
parent 0dc3cba1
2015-06-16 David Malcolm <dmalcolm@redhat.com>
PR jit/66539
* jit-recording.c: Within namespace gcc::jit::recording::
(rvalue::get_debug_string_parens): New function.
(binary_op::make_debug_string): Update to mimic C precedence
rules.
(binary_op_precedence): New array.
(binary_op::get_precedence): New function.
(comparison::make_debug_string): Update to mimic C precedence
rules.
(comparison_precedence): New array.
(comparison::get_precedence): New function.
(cast::make_debug_string): Update to mimic C precedence rules.
(call::make_debug_string): Likewise.
(call_through_ptr::make_debug_string): Likewise.
(array_access::make_debug_string): Likewise.
(access_field_of_lvalue::make_debug_string): Likewise.
(access_field_rvalue::make_debug_string): Likewise.
(dereference_field_rvalue::make_debug_string): Likewise.
(dereference_rvalue::make_debug_string): Likewise.
(get_address_of_lvalue::make_debug_string): Likewise.
* jit-recording.h: Within namespace gcc::jit::recording::
(precedence): New enum.
(rvalue::rvalue): Initialize field "m_parenthesized_string".
(rvalue::get_debug_string_parens): New method.
(rvalue::get_precedence): New pure virtual function.
(rvalue::m_parenthesized_string): New field.
(param::get_precedence): New function.
(global::get_precedence): New function.
(memento_of_new_rvalue_from_const::get_precedence): New function.
(memento_of_new_string_literal::get_precedence): New function.
(unary_op::get_precedence): New function.
(binary_op::get_precedence): New function.
(comparison::get_precedence): New function.
(cast::get_precedence): New function.
(call::get_precedence): New function.
(call_through_ptr::get_precedence): New function.
(array_access::get_precedence): New function.
(access_field_of_lvalue::get_precedence): New function.
(access_field_rvalue::get_precedence): New function.
(dereference_field_rvalue::get_precedence): New function.
(dereference_rvalue::get_precedence): New function.
(get_address_of_lvalue::get_precedence): New function.
(local::get_precedence): New function.
2015-06-09 Matthias Klose <doko@ubuntu.com>
* Make-lang.in (jit.install-common): Install headers using INSTALL_DATA.
......
......@@ -858,6 +858,27 @@ class rvalue_visitor
virtual void visit (rvalue *rvalue) = 0;
};
/* When generating debug strings for rvalues we mimic C, so we need to
mimic C's precedence levels when handling compound expressions.
These are in order from strongest precedence to weakest. */
enum precedence
{
PRECEDENCE_PRIMARY,
PRECEDENCE_POSTFIX,
PRECEDENCE_UNARY,
PRECEDENCE_CAST,
PRECEDENCE_MULTIPLICATIVE,
PRECEDENCE_ADDITIVE,
PRECEDENCE_SHIFT,
PRECEDENCE_RELATIONAL,
PRECEDENCE_EQUALITY,
PRECEDENCE_BITWISE_AND,
PRECEDENCE_BITWISE_XOR,
PRECEDENCE_BITWISE_IOR,
PRECEDENCE_LOGICAL_AND,
PRECEDENCE_LOGICAL_OR
};
class rvalue : public memento
{
public:
......@@ -867,7 +888,8 @@ public:
: memento (ctxt),
m_loc (loc),
m_type (type_),
m_scope (NULL)
m_scope (NULL),
m_parenthesized_string (NULL)
{
gcc_assert (type_);
}
......@@ -909,12 +931,20 @@ public:
virtual const char *access_as_rvalue (reproducer &r);
/* Get the debug string, wrapped in parentheses. */
const char *
get_debug_string_parens (enum precedence outer_prec);
private:
virtual enum precedence get_precedence () const = 0;
protected:
location *m_loc;
type *m_type;
private:
function *m_scope; /* NULL for globals, non-NULL for locals/params */
string *m_parenthesized_string;
};
class lvalue : public rvalue
......@@ -977,6 +1007,7 @@ public:
private:
string * make_debug_string () { return m_name; }
void write_reproducer (reproducer &r);
enum precedence get_precedence () const { return PRECEDENCE_PRIMARY; }
private:
string *m_name;
......@@ -1161,6 +1192,7 @@ public:
private:
string * make_debug_string () { return m_name; }
void write_reproducer (reproducer &r);
enum precedence get_precedence () const { return PRECEDENCE_PRIMARY; }
private:
enum gcc_jit_global_kind m_kind;
......@@ -1185,6 +1217,7 @@ public:
private:
string * make_debug_string ();
void write_reproducer (reproducer &r);
enum precedence get_precedence () const { return PRECEDENCE_PRIMARY; }
private:
HOST_TYPE m_value;
......@@ -1206,6 +1239,7 @@ public:
private:
string * make_debug_string ();
void write_reproducer (reproducer &r);
enum precedence get_precedence () const { return PRECEDENCE_PRIMARY; }
private:
string *m_value;
......@@ -1231,6 +1265,7 @@ public:
private:
string * make_debug_string ();
void write_reproducer (reproducer &r);
enum precedence get_precedence () const {return PRECEDENCE_UNARY;}
private:
enum gcc_jit_unary_op m_op;
......@@ -1257,6 +1292,7 @@ public:
private:
string * make_debug_string ();
void write_reproducer (reproducer &r);
enum precedence get_precedence () const;
private:
enum gcc_jit_binary_op m_op;
......@@ -1284,6 +1320,7 @@ public:
private:
string * make_debug_string ();
void write_reproducer (reproducer &r);
enum precedence get_precedence () const;
private:
enum gcc_jit_comparison m_op;
......@@ -1309,6 +1346,7 @@ public:
private:
string * make_debug_string ();
void write_reproducer (reproducer &r);
enum precedence get_precedence () const { return PRECEDENCE_CAST; }
private:
rvalue *m_rvalue;
......@@ -1330,6 +1368,7 @@ public:
private:
string * make_debug_string ();
void write_reproducer (reproducer &r);
enum precedence get_precedence () const { return PRECEDENCE_POSTFIX; }
private:
function *m_func;
......@@ -1352,6 +1391,7 @@ public:
private:
string * make_debug_string ();
void write_reproducer (reproducer &r);
enum precedence get_precedence () const { return PRECEDENCE_POSTFIX; }
private:
rvalue *m_fn_ptr;
......@@ -1377,6 +1417,7 @@ public:
private:
string * make_debug_string ();
void write_reproducer (reproducer &r);
enum precedence get_precedence () const { return PRECEDENCE_POSTFIX; }
private:
rvalue *m_ptr;
......@@ -1402,6 +1443,7 @@ public:
private:
string * make_debug_string ();
void write_reproducer (reproducer &r);
enum precedence get_precedence () const { return PRECEDENCE_POSTFIX; }
private:
lvalue *m_lvalue;
......@@ -1427,6 +1469,7 @@ public:
private:
string * make_debug_string ();
void write_reproducer (reproducer &r);
enum precedence get_precedence () const { return PRECEDENCE_POSTFIX; }
private:
rvalue *m_rvalue;
......@@ -1452,6 +1495,7 @@ public:
private:
string * make_debug_string ();
void write_reproducer (reproducer &r);
enum precedence get_precedence () const { return PRECEDENCE_POSTFIX; }
private:
rvalue *m_rvalue;
......@@ -1474,6 +1518,7 @@ public:
private:
string * make_debug_string ();
void write_reproducer (reproducer &r);
enum precedence get_precedence () const { return PRECEDENCE_UNARY; }
private:
rvalue *m_rvalue;
......@@ -1496,6 +1541,7 @@ public:
private:
string * make_debug_string ();
void write_reproducer (reproducer &r);
enum precedence get_precedence () const { return PRECEDENCE_UNARY; }
private:
lvalue *m_lvalue;
......@@ -1521,6 +1567,7 @@ public:
private:
string * make_debug_string () { return m_name; }
void write_reproducer (reproducer &r);
enum precedence get_precedence () const { return PRECEDENCE_PRIMARY; }
private:
function *m_func;
......
2015-06-16 David Malcolm <dmalcolm@redhat.com>
PR jit/66539
* jit.dg/all-non-failing-tests.h: Add test-debug-strings.c.
* jit.dg/test-debug-strings.c: New test case.
* jit.dg/test-quadratic.c (make_calc_discriminant): Verify that
the discriminant has a sane debug string.
2015-06-16 Uros Bizjak <ubizjak@gmail.com>
PR target/56766
......
......@@ -64,6 +64,13 @@
#undef create_code
#undef verify_code
/* test-debug-strings.c */
#define create_code create_code_debug_strings
#define verify_code verify_code_debug_strings
#include "test-debug-strings.c"
#undef create_code
#undef verify_code
/* test-dot-product.c */
#define create_code create_code_dot_product
#define verify_code verify_code_dot_product
......
#include <stdlib.h>
#include <stdio.h>
#include "libgccjit.h"
#include "harness.h"
/* Build various compound expressions, and verify that they have sane debug
strings. */
void
create_code (gcc_jit_context *ctxt, void *user_data)
{
/* Make a singly-linked list type:
struct node
{
struct node *next;
int value;
};
*/
gcc_jit_type *t_int =
gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
gcc_jit_struct *t_node =
gcc_jit_context_new_opaque_struct (ctxt, NULL, "node");
gcc_jit_type *t_node_ptr =
gcc_jit_type_get_pointer (gcc_jit_struct_as_type (t_node));
gcc_jit_field *f_next =
gcc_jit_context_new_field (ctxt, NULL, t_node_ptr, "next");
gcc_jit_field *f_value =
gcc_jit_context_new_field (ctxt, NULL, t_int, "value");
gcc_jit_field *fields[] = {f_next, f_value};
gcc_jit_struct_set_fields (t_node, NULL, 2, fields);
/* Create a dummy function so that we have locals/params to build
expressions with. */
gcc_jit_type *t_void =
gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
gcc_jit_function *fn =
gcc_jit_context_new_function (ctxt, NULL,
GCC_JIT_FUNCTION_EXPORTED,
t_void,
"test_debug_strings",
0, NULL, 0);
gcc_jit_rvalue *ptr =
gcc_jit_lvalue_as_rvalue (
gcc_jit_function_new_local (fn,
NULL,
t_node_ptr,
"ptr"));
gcc_jit_rvalue *a =
gcc_jit_lvalue_as_rvalue (
gcc_jit_function_new_local (fn, NULL, t_int, "a"));
gcc_jit_rvalue *b =
gcc_jit_lvalue_as_rvalue (
gcc_jit_function_new_local (fn, NULL, t_int, "b"));
gcc_jit_rvalue *c =
gcc_jit_lvalue_as_rvalue (
gcc_jit_function_new_local (fn, NULL, t_int, "c"));
gcc_jit_rvalue *d =
gcc_jit_lvalue_as_rvalue (
gcc_jit_function_new_local (fn, NULL, t_int, "d"));
#define CHECK_RVALUE_DEBUG_STRING(RVALUE, EXPECTED) \
CHECK_STRING_VALUE ( \
gcc_jit_object_get_debug_string (gcc_jit_rvalue_as_object (RVALUE)), \
(EXPECTED))
#define CHECK_LVALUE_DEBUG_STRING(LVALUE, EXPECTED) \
CHECK_STRING_VALUE ( \
gcc_jit_object_get_debug_string (gcc_jit_lvalue_as_object (LVALUE)), \
(EXPECTED))
/* Verify various simple compound expressions. */
{
CHECK_RVALUE_DEBUG_STRING (ptr, "ptr");
gcc_jit_lvalue *deref =
gcc_jit_rvalue_dereference_field (ptr,
NULL,
f_value);
CHECK_LVALUE_DEBUG_STRING (deref, "ptr->value");
gcc_jit_rvalue *deref_as_rvalue = gcc_jit_lvalue_as_rvalue (deref);
#define BINOP(OP, A, B) \
gcc_jit_context_new_binary_op (ctxt, NULL, \
GCC_JIT_BINARY_OP_##OP, t_int, (A), (B))
#define COMPARISON(OP, A, B) \
gcc_jit_context_new_comparison (ctxt, NULL, \
GCC_JIT_COMPARISON_##OP,(A), (B))
CHECK_RVALUE_DEBUG_STRING (
BINOP (PLUS, deref_as_rvalue, deref_as_rvalue),
"ptr->value + ptr->value");
CHECK_RVALUE_DEBUG_STRING (
BINOP (MULT, deref_as_rvalue, deref_as_rvalue),
"ptr->value * ptr->value");
/* Multiplication has higher precedence in C than addition, so this
dump shouldn't contain parentheses. */
CHECK_RVALUE_DEBUG_STRING (
BINOP (PLUS,
BINOP (MULT, a, b),
BINOP (MULT, c, d)),
"a * b + c * d");
/* ...but this one should. */
CHECK_RVALUE_DEBUG_STRING (
BINOP (MULT,
BINOP (PLUS, a, b),
BINOP (PLUS, c, d)),
"(a + b) * (c + d)");
/* Equal precedences don't need parentheses. */
CHECK_RVALUE_DEBUG_STRING (
BINOP (MULT,
BINOP (MULT, a, b),
BINOP (MULT, c, d)),
"a * b * c * d");
/* Comparisons and logical ops. */
CHECK_RVALUE_DEBUG_STRING (
COMPARISON (LT, a, b),
"a < b");
CHECK_RVALUE_DEBUG_STRING (
BINOP (LOGICAL_AND,
COMPARISON (LT, a, b),
COMPARISON (GT, c, d)),
"a < b && c > d");
CHECK_RVALUE_DEBUG_STRING (
BINOP (LOGICAL_AND,
BINOP (LOGICAL_OR,
COMPARISON (LT, a, b),
COMPARISON (LT, a, c)),
BINOP (LOGICAL_OR,
COMPARISON (GT, d, b),
COMPARISON (GT, d, c))),
"(a < b || a < c) && (d > b || d > c)");
CHECK_RVALUE_DEBUG_STRING (
BINOP (LOGICAL_OR,
BINOP (LOGICAL_AND,
COMPARISON (LT, a, b),
COMPARISON (LT, a, c)),
BINOP (LOGICAL_AND,
COMPARISON (GT, d, b),
COMPARISON (GT, d, c))),
"a < b && a < c || d > b && d > c");
#undef BINOP
#undef COMPARISON
}
/* PR jit/66539 "Missing parentheses in jit dumps".
Construct the equivalent of
((cast)ptr->next)->next
and verify that the appropriate parentheses appear in the debug
string. */
{
/* "ptr->next". */
gcc_jit_lvalue *inner_deref =
gcc_jit_rvalue_dereference_field (ptr,
NULL,
f_next);
/* "((node *)ptr->next)"; the cast is redundant, purely
to exercise dumping. */
gcc_jit_rvalue *test_cast =
gcc_jit_context_new_cast (ctxt, NULL,
gcc_jit_lvalue_as_rvalue (inner_deref),
t_node_ptr);
/* "((node *)ptr->next)->next". */
gcc_jit_lvalue *outer_deref =
gcc_jit_rvalue_dereference_field (test_cast, /* gcc_jit_rvalue *ptr */
NULL, /* gcc_jit_location *loc */
f_next); /* gcc_jit_field *field */
CHECK_LVALUE_DEBUG_STRING (outer_deref,
"((struct node *)ptr->next)->next");
}
#undef CHECK_LVALUE_DEBUG_STRING
}
void
verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
{
CHECK_NON_NULL (result);
/* We don't actually build any functions above;
nothing more to verify. */
}
......@@ -176,16 +176,8 @@ make_calc_discriminant (struct quadratic_test *testcase)
gcc_jit_param_as_rvalue (param_q),
NULL, testcase->c));
gcc_jit_block_add_assignment (
blk, NULL,
/* q->discriminant =... */
gcc_jit_rvalue_dereference_field (
gcc_jit_param_as_rvalue (param_q),
NULL,
testcase->discriminant),
/* (q->b * q->b) - (4 * q->a * q->c) */
/* (q->b * q->b) - (4 * q->a * q->c) */
gcc_jit_rvalue *rhs =
gcc_jit_context_new_binary_op (
testcase->ctxt, NULL,
GCC_JIT_BINARY_OP_MINUS,
......@@ -213,7 +205,21 @@ make_calc_discriminant (struct quadratic_test *testcase)
testcase->ctxt, NULL,
GCC_JIT_BINARY_OP_MULT,
testcase->numeric_type,
q_a, q_c)))); /* end of gcc_jit_function_add_assignment call. */
q_a, q_c)));
CHECK_STRING_VALUE (
gcc_jit_object_get_debug_string (gcc_jit_rvalue_as_object (rhs)),
"q->b * q->b - (double)4 * q->a * q->c");
gcc_jit_block_add_assignment (
blk, NULL,
/* q->discriminant =... */
gcc_jit_rvalue_dereference_field (
gcc_jit_param_as_rvalue (param_q),
NULL,
testcase->discriminant),
rhs);
gcc_jit_block_end_with_void_return (blk, NULL);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment