aboutsummaryrefslogtreecommitdiff
path: root/gcc/jit
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2015-06-16 18:13:44 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2015-06-16 18:13:44 +0000
commitbd93aa1a976dca96267efb36d6d909ff9813a414 (patch)
tree00d13dc4a930d4f40d356e647478fa1189c80329 /gcc/jit
parent0dc3cba1bd0a9310fc53325cfa26be9537ea5369 (diff)
downloadgcc-bd93aa1a976dca96267efb36d6d909ff9813a414.zip
gcc-bd93aa1a976dca96267efb36d6d909ff9813a414.tar.gz
gcc-bd93aa1a976dca96267efb36d6d909ff9813a414.tar.bz2
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
Diffstat (limited to 'gcc/jit')
-rw-r--r--gcc/jit/ChangeLog46
-rw-r--r--gcc/jit/jit-recording.c150
-rw-r--r--gcc/jit/jit-recording.h49
3 files changed, 225 insertions, 20 deletions
diff --git a/gcc/jit/ChangeLog b/gcc/jit/ChangeLog
index 0d00f3b..0ba2fd6 100644
--- a/gcc/jit/ChangeLog
+++ b/gcc/jit/ChangeLog
@@ -1,3 +1,49 @@
+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.
diff --git a/gcc/jit/jit-recording.c b/gcc/jit/jit-recording.c
index 32d7f31..f379b58 100644
--- a/gcc/jit/jit-recording.c
+++ b/gcc/jit/jit-recording.c
@@ -3021,6 +3021,63 @@ recording::rvalue::access_as_rvalue (reproducer &r)
return r.get_identifier (this);
}
+/* Return a debug string for the given rvalue, wrapping it in parentheses
+ if needed to mimic C's precedence rules, i.e. if OUTER_PREC is of
+ stronger precedence that this rvalue's precedence.
+
+ For example, given:
+
+ MULT
+ / \
+ PLUS MINUS
+ / \ / \
+ A B C D
+
+ we want to emit:
+
+ (A + B) * (C - D)
+
+ since MULT has strong precedence than PLUS and MINUS, whereas for:
+
+ PLUS
+ / \
+ MULT DIVIDE
+ / \ / \
+ A B C D
+
+ we can simply emit:
+
+ A * B + C / D
+
+ since PLUS has weaker precedence than MULT and DIVIDE. */
+
+const char *
+recording::rvalue::get_debug_string_parens (enum precedence outer_prec)
+{
+ enum precedence this_prec = get_precedence ();
+
+ /* If this_prec has stronger precedence than outer_prec, we don't
+ need to wrap this in parens within the outer debug string.
+ Stronger precedences occur earlier than weaker within the enum,
+ so this is a less than test. Equal precedences don't need
+ parentheses. */
+ if (this_prec <= outer_prec)
+ return get_debug_string();
+
+ /* Otherwise, we need parentheses. */
+
+ /* Lazily-build and cache m_parenthesized_string. */
+ if (!m_parenthesized_string)
+ {
+ const char *debug_string = get_debug_string ();
+ m_parenthesized_string = string::from_printf (get_context (),
+ "(%s)",
+ debug_string);
+ }
+ gcc_assert (m_parenthesized_string);
+ return m_parenthesized_string->c_str ();
+}
+
/* The implementation of class gcc::jit::recording::lvalue. */
@@ -4251,11 +4308,12 @@ static const char * const binary_op_strings[] = {
recording::string *
recording::binary_op::make_debug_string ()
{
+ enum precedence prec = get_precedence ();
return string::from_printf (m_ctxt,
"%s %s %s",
- m_a->get_debug_string (),
+ m_a->get_debug_string_parens (prec),
binary_op_strings[m_op],
- m_b->get_debug_string ());
+ m_b->get_debug_string_parens (prec));
}
static const char * const binary_op_reproducer_strings[] = {
@@ -4295,6 +4353,31 @@ recording::binary_op::write_reproducer (reproducer &r)
r.get_identifier_as_rvalue (m_b));
}
+namespace recording {
+static const enum precedence binary_op_precedence[] = {
+ PRECEDENCE_ADDITIVE, /* GCC_JIT_BINARY_OP_PLUS */
+ PRECEDENCE_ADDITIVE, /* GCC_JIT_BINARY_OP_MINUS */
+
+ PRECEDENCE_MULTIPLICATIVE, /* GCC_JIT_BINARY_OP_MULT */
+ PRECEDENCE_MULTIPLICATIVE, /* GCC_JIT_BINARY_OP_DIVIDE */
+ PRECEDENCE_MULTIPLICATIVE, /* GCC_JIT_BINARY_OP_MODULO */
+
+ PRECEDENCE_BITWISE_AND, /* GCC_JIT_BINARY_OP_BITWISE_AND */
+ PRECEDENCE_BITWISE_XOR, /* GCC_JIT_BINARY_OP_BITWISE_XOR */
+ PRECEDENCE_BITWISE_IOR, /* GCC_JIT_BINARY_OP_BITWISE_OR */
+ PRECEDENCE_LOGICAL_AND, /* GCC_JIT_BINARY_OP_LOGICAL_AND */
+ PRECEDENCE_LOGICAL_OR, /* GCC_JIT_BINARY_OP_LOGICAL_OR */
+ PRECEDENCE_SHIFT, /* GCC_JIT_BINARY_OP_LSHIFT */
+ PRECEDENCE_SHIFT, /* GCC_JIT_BINARY_OP_RSHIFT */
+};
+} /* namespace recording */
+
+enum recording::precedence
+recording::binary_op::get_precedence () const
+{
+ return binary_op_precedence[m_op];
+}
+
/* The implementation of class gcc::jit::recording::comparison. */
/* Implementation of recording::memento::make_debug_string for
@@ -4313,11 +4396,12 @@ static const char * const comparison_strings[] =
recording::string *
recording::comparison::make_debug_string ()
{
+ enum precedence prec = get_precedence ();
return string::from_printf (m_ctxt,
"%s %s %s",
- m_a->get_debug_string (),
+ m_a->get_debug_string_parens (prec),
comparison_strings[m_op],
- m_b->get_debug_string ());
+ m_b->get_debug_string_parens (prec));
}
/* A table of enum gcc_jit_comparison values expressed in string
@@ -4375,6 +4459,25 @@ recording::comparison::visit_children (rvalue_visitor *v)
v->visit (m_b);
}
+namespace recording {
+static const enum precedence comparison_precedence[] =
+{
+ PRECEDENCE_EQUALITY, /* GCC_JIT_COMPARISON_EQ */
+ PRECEDENCE_EQUALITY, /* GCC_JIT_COMPARISON_NE */
+
+ PRECEDENCE_RELATIONAL, /* GCC_JIT_COMPARISON_LT */
+ PRECEDENCE_RELATIONAL, /* GCC_JIT_COMPARISON_LE */
+ PRECEDENCE_RELATIONAL, /* GCC_JIT_COMPARISON_GT */
+ PRECEDENCE_RELATIONAL, /* GCC_JIT_COMPARISON_GE */
+};
+} /* namespace recording */
+
+enum recording::precedence
+recording::comparison::get_precedence () const
+{
+ return comparison_precedence[m_op];
+}
+
/* Implementation of pure virtual hook recording::memento::replay_into
for recording::cast. */
@@ -4400,10 +4503,11 @@ recording::cast::visit_children (rvalue_visitor *v)
recording::string *
recording::cast::make_debug_string ()
{
+ enum precedence prec = get_precedence ();
return string::from_printf (m_ctxt,
"(%s)%s",
get_type ()->get_debug_string (),
- m_rvalue->get_debug_string ());
+ m_rvalue->get_debug_string_parens (prec));
}
/* Implementation of recording::memento::write_reproducer for casts. */
@@ -4473,12 +4577,13 @@ recording::call::visit_children (rvalue_visitor *v)
recording::string *
recording::call::make_debug_string ()
{
+ enum precedence prec = get_precedence ();
/* First, build a buffer for the arguments. */
/* Calculate length of said buffer. */
size_t sz = 1; /* nil terminator */
for (unsigned i = 0; i< m_args.length (); i++)
{
- sz += strlen (m_args[i]->get_debug_string ());
+ sz += strlen (m_args[i]->get_debug_string_parens (prec));
sz += 2; /* ", " separator */
}
@@ -4488,8 +4593,8 @@ recording::call::make_debug_string ()
for (unsigned i = 0; i< m_args.length (); i++)
{
- strcpy (argbuf + len, m_args[i]->get_debug_string ());
- len += strlen (m_args[i]->get_debug_string ());
+ strcpy (argbuf + len, m_args[i]->get_debug_string_parens (prec));
+ len += strlen (m_args[i]->get_debug_string_parens (prec));
if (i + 1 < m_args.length ())
{
strcpy (argbuf + len, ", ");
@@ -4586,12 +4691,13 @@ recording::call_through_ptr::visit_children (rvalue_visitor *v)
recording::string *
recording::call_through_ptr::make_debug_string ()
{
+ enum precedence prec = get_precedence ();
/* First, build a buffer for the arguments. */
/* Calculate length of said buffer. */
size_t sz = 1; /* nil terminator */
for (unsigned i = 0; i< m_args.length (); i++)
{
- sz += strlen (m_args[i]->get_debug_string ());
+ sz += strlen (m_args[i]->get_debug_string_parens (prec));
sz += 2; /* ", " separator */
}
@@ -4601,8 +4707,8 @@ recording::call_through_ptr::make_debug_string ()
for (unsigned i = 0; i< m_args.length (); i++)
{
- strcpy (argbuf + len, m_args[i]->get_debug_string ());
- len += strlen (m_args[i]->get_debug_string ());
+ strcpy (argbuf + len, m_args[i]->get_debug_string_parens (prec));
+ len += strlen (m_args[i]->get_debug_string_parens (prec));
if (i + 1 < m_args.length ())
{
strcpy (argbuf + len, ", ");
@@ -4614,7 +4720,7 @@ recording::call_through_ptr::make_debug_string ()
/* ...and use it to get the string for the call as a whole. */
string *result = string::from_printf (m_ctxt,
"%s (%s)",
- m_fn_ptr->get_debug_string (),
+ m_fn_ptr->get_debug_string_parens (prec),
argbuf);
delete[] argbuf;
@@ -4680,10 +4786,11 @@ recording::array_access::visit_children (rvalue_visitor *v)
recording::string *
recording::array_access::make_debug_string ()
{
+ enum precedence prec = get_precedence ();
return string::from_printf (m_ctxt,
"%s[%s]",
- m_ptr->get_debug_string (),
- m_index->get_debug_string ());
+ m_ptr->get_debug_string_parens (prec),
+ m_index->get_debug_string_parens (prec));
}
/* Implementation of recording::memento::write_reproducer for
@@ -4735,9 +4842,10 @@ recording::access_field_of_lvalue::visit_children (rvalue_visitor *v)
recording::string *
recording::access_field_of_lvalue::make_debug_string ()
{
+ enum precedence prec = get_precedence ();
return string::from_printf (m_ctxt,
"%s.%s",
- m_lvalue->get_debug_string (),
+ m_lvalue->get_debug_string_parens (prec),
m_field->get_debug_string ());
}
@@ -4787,9 +4895,10 @@ recording::access_field_rvalue::visit_children (rvalue_visitor *v)
recording::string *
recording::access_field_rvalue::make_debug_string ()
{
+ enum precedence prec = get_precedence ();
return string::from_printf (m_ctxt,
"%s.%s",
- m_rvalue->get_debug_string (),
+ m_rvalue->get_debug_string_parens (prec),
m_field->get_debug_string ());
}
@@ -4840,9 +4949,10 @@ recording::dereference_field_rvalue::visit_children (rvalue_visitor *v)
recording::string *
recording::dereference_field_rvalue::make_debug_string ()
{
+ enum precedence prec = get_precedence ();
return string::from_printf (m_ctxt,
"%s->%s",
- m_rvalue->get_debug_string (),
+ m_rvalue->get_debug_string_parens (prec),
m_field->get_debug_string ());
}
@@ -4891,9 +5001,10 @@ recording::dereference_rvalue::visit_children (rvalue_visitor *v)
recording::string *
recording::dereference_rvalue::make_debug_string ()
{
+ enum precedence prec = get_precedence ();
return string::from_printf (m_ctxt,
"*%s",
- m_rvalue->get_debug_string ());
+ m_rvalue->get_debug_string_parens (prec));
}
/* Implementation of recording::memento::write_reproducer for
@@ -4939,9 +5050,10 @@ recording::get_address_of_lvalue::visit_children (rvalue_visitor *v)
recording::string *
recording::get_address_of_lvalue::make_debug_string ()
{
+ enum precedence prec = get_precedence ();
return string::from_printf (m_ctxt,
"&%s",
- m_lvalue->get_debug_string ());
+ m_lvalue->get_debug_string_parens (prec));
}
/* Implementation of recording::memento::write_reproducer for
diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h
index 439e7ce..d3170fe 100644
--- a/gcc/jit/jit-recording.h
+++ b/gcc/jit/jit-recording.h
@@ -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;