[PATCH][match-and-simplify] More TLC to genmatch
Richard Biener
rguenther@suse.de
Tue Oct 14 10:09:00 GMT 2014
This applies more comment / whitespace TLC to genmatch and does
minor refactoring on-the-fly.
Bootstrap running on x86_64-unknown-linux-gnu.
Richard.
2014-10-14 Richard Biener <rguenther@suse.de>
* genmatch.c: Whitespace and comment fixes, some minor
refactoring.
Index: gcc/genmatch.c
===================================================================
--- gcc/genmatch.c (revision 216146)
+++ gcc/genmatch.c (working copy)
@@ -390,7 +390,8 @@ struct expr : public operand
/* Whether the operation is to be applied commutatively. This is
later lowered to two separate patterns. */
bool is_commutative;
- virtual void gen_transform (FILE *f, const char *, bool, int, const char *, dt_operand ** = 0);
+ virtual void gen_transform (FILE *f, const char *, bool, int,
+ const char *, dt_operand ** = 0);
};
/* An operator that is represented by native C code. This is always
@@ -419,7 +420,8 @@ struct c_expr : public operand
unsigned nr_stmts;
/* The identifier replacement vector. */
vec<id_tab> ids;
- virtual void gen_transform (FILE *f, const char *, bool, int, const char *, dt_operand **);
+ virtual void gen_transform (FILE *f, const char *, bool, int,
+ const char *, dt_operand **);
};
/* A wrapper around another operand that captures its value. */
@@ -432,7 +434,8 @@ struct capture : public operand
unsigned where;
/* The captured value. */
operand *what;
- virtual void gen_transform (FILE *f, const char *, bool, int, const char *, dt_operand ** = 0);
+ virtual void gen_transform (FILE *f, const char *, bool, int,
+ const char *, dt_operand ** = 0);
};
template<>
@@ -569,7 +572,8 @@ print_matches (struct simplify *s, FILE
/* Lowering of commutative operators. */
static void
-cartesian_product (const vec< vec<operand *> >& ops_vector, vec< vec<operand *> >& result, vec<operand *>& v, unsigned n)
+cartesian_product (const vec< vec<operand *> >& ops_vector,
+ vec< vec<operand *> >& result, vec<operand *>& v, unsigned n)
{
if (n == ops_vector.length ())
{
@@ -584,14 +588,8 @@ cartesian_product (const vec< vec<operan
cartesian_product (ops_vector, result, v, n + 1);
}
}
-
-static void
-cartesian_product (const vec< vec<operand *> >& ops_vector, vec< vec<operand *> >& result, unsigned n_ops)
-{
- vec<operand *> v = vNULL;
- v.safe_grow_cleared (n_ops);
- cartesian_product (ops_vector, result, v, 0);
-}
+
+/* Lower OP to two operands in case it is marked as commutative. */
static vec<operand *>
commutate (operand *op)
@@ -625,8 +623,11 @@ commutate (operand *op)
for (unsigned i = 0; i < e->ops.length (); ++i)
ops_vector.safe_push (commutate (e->ops[i]));
- vec< vec<operand *> > result = vNULL;
- cartesian_product (ops_vector, result, e->ops.length ());
+ auto_vec< vec<operand *> > result;
+ auto_vec<operand *> v (e->ops.length ());
+ v.quick_grow_cleared (e->ops.length ());
+ cartesian_product (ops_vector, result, v, 0);
+
for (unsigned i = 0; i < result.length (); ++i)
{
@@ -651,6 +652,9 @@ commutate (operand *op)
return ret;
}
+/* Lower operations marked as commutative in the AST of S and push
+ the resulting patterns to SIMPLIFIERS. */
+
static void
lower_commutative (simplify *s, vec<simplify *>& simplifiers)
{
@@ -664,15 +668,16 @@ lower_commutative (simplify *s, vec<simp
}
}
-/* Lowering of conditional converts. */
+/* Strip conditional conversios using operator OPER from O and its
+ children if STRIP, else replace them with an unconditional convert. */
-static operand *
-lower_opt_convert (operand *o, enum tree_code oper)
+operand *
+lower_opt_convert (operand *o, enum tree_code oper, bool strip)
{
- if (capture *c = dyn_cast<capture *> (o))
+ if (capture *c = dyn_cast<capture *> (o))
{
if (c->what)
- return new capture (c->where, lower_opt_convert (c->what, oper));
+ return new capture (c->where, lower_opt_convert (c->what, oper, strip));
else
return c;
}
@@ -683,42 +688,23 @@ lower_opt_convert (operand *o, enum tree
if (*e->operation == oper)
{
+ if (strip)
+ return lower_opt_convert (e->ops[0], oper, strip);
+
expr *ne = new expr (get_operator ("CONVERT_EXPR"));
- ne->append_op (lower_opt_convert (e->ops[0], oper));
+ ne->append_op (lower_opt_convert (e->ops[0], oper, strip));
return ne;
}
expr *ne = new expr (e->operation, e->is_commutative);
for (unsigned i = 0; i < e->ops.length (); ++i)
- ne->append_op (lower_opt_convert (e->ops[i], oper));
+ ne->append_op (lower_opt_convert (e->ops[i], oper, strip));
return ne;
}
-operand *
-remove_opt_convert (operand *o, enum tree_code oper)
-{
- if (capture *c = dyn_cast<capture *> (o))
- {
- if (c->what)
- return new capture (c->where, remove_opt_convert (c->what, oper));
- else
- return c;
- }
-
- expr *e = as_a<expr *> (o);
- if (!e)
- return o;
-
- if (*e->operation == oper)
- return remove_opt_convert (e->ops[0], oper);
-
- expr *ne = new expr (e->operation, e->is_commutative);
- for (unsigned i = 0; i < e->ops.length (); ++i)
- ne->append_op (remove_opt_convert (e->ops[i], oper));
-
- return ne;
-}
+/* Determine whether O or its children uses the conditional conversion
+ operator OPER. */
static bool
has_opt_convert (operand *o, enum tree_code oper)
@@ -745,15 +731,8 @@ has_opt_convert (operand *o, enum tree_c
return false;
}
-static void
-lower_opt_convert (vec<operand *>& v, operand *o, enum tree_code oper)
-{
- if (has_opt_convert (o, oper))
- {
- v.safe_push (lower_opt_convert (o, oper));
- v.safe_push (remove_opt_convert (o, oper));
- }
-}
+/* Lower conditional convert operators in O, expanding it to a vector
+ if required. */
static vec<operand *>
lower_opt_convert (operand *o)
@@ -764,11 +743,19 @@ lower_opt_convert (operand *o)
enum tree_code opers[] = { CONVERT0, CONVERT1, CONVERT2 };
+ /* Conditional converts are lowered to a pattern with the
+ conversion and one without. The three different conditional
+ convert codes are lowered separately. */
+
for (unsigned i = 0; i < 3; ++i)
{
v2 = vNULL;
for (unsigned j = 0; j < v1.length (); ++j)
- lower_opt_convert (v2, v1[j], opers[i]);
+ if (has_opt_convert (v1[j], opers[i]))
+ {
+ v2.safe_push (lower_opt_convert (v1[j], opers[i], false));
+ v2.safe_push (lower_opt_convert (v1[j], opers[i], true));
+ }
if (v2 != vNULL)
{
@@ -781,6 +768,9 @@ lower_opt_convert (operand *o)
return v1;
}
+/* Lower conditional convert operators in the AST of S and push
+ the resulting multiple patterns to SIMPLIFIERS. */
+
static void
lower_opt_convert (simplify *s, vec<simplify *>& simplifiers)
{
@@ -911,6 +901,8 @@ lower (vec<simplify *>& simplifiers)
matching code. It represents the 'match' expression of all
simplifies and has those as its leafs. */
+/* Decision tree base class, used for DT_TRUE and DT_NODE. */
+
struct dt_node
{
enum dt_type { DT_NODE, DT_OPERAND, DT_TRUE, DT_MATCH, DT_SIMPLIFY };
@@ -920,7 +912,7 @@ struct dt_node
vec<dt_node *> kids;
dt_node (enum dt_type type_): type (type_), level (0), kids (vNULL) {}
-
+
dt_node *append_node (dt_node *);
dt_node *append_op (operand *, dt_node *parent = 0, unsigned pos = 0);
dt_node *append_true_op (dt_node *parent = 0, unsigned pos = 0);
@@ -932,6 +924,8 @@ struct dt_node
void gen_kids (FILE *, bool);
};
+/* Generic decision tree node used for DT_OPERAND and DT_MATCH. */
+
struct dt_operand : public dt_node
{
operand *op;
@@ -955,6 +949,8 @@ struct dt_operand : public dt_node
void gen_opname (char *, unsigned);
};
+/* Leaf node of the decision tree, used for DT_SIMPLIFY. */
+
struct dt_simplify : public dt_node
{
simplify *s;
@@ -977,6 +973,8 @@ is_a_helper <dt_operand *>::test (dt_nod
|| n->type == dt_node::DT_MATCH);
}
+/* A container for the actual decision tree. */
+
struct decision_tree
{
dt_node *root;
@@ -995,6 +993,8 @@ struct decision_tree
static void print_node (dt_node *, FILE *f = stderr, unsigned = 0);
};
+/* Compare two AST operands O1 and O2 and return true if they are equal. */
+
bool
cmp_operand (operand *o1, operand *o2)
{
@@ -1017,6 +1017,9 @@ cmp_operand (operand *o1, operand *o2)
return false;
}
+/* Compare two decision tree nodes N1 and N2 and return true if they
+ are equal. */
+
bool
decision_tree::cmp_node (dt_node *n1, dt_node *n2)
{
@@ -1035,16 +1038,21 @@ decision_tree::cmp_node (dt_node *n1, dt
return false;
}
+/* Search OPS for a decision tree node like P and return it if found. */
+
dt_node *
decision_tree::find_node (vec<dt_node *>& ops, dt_node *p)
{
for (unsigned i = 0; i < ops.length (); ++i)
if (decision_tree::cmp_node (ops[i], p))
- return ops[i];
-
- return 0;
+ return ops[i];
+
+ return NULL;
}
+/* Append N to the decision tree if it there is not already an existing
+ identical child. */
+
dt_node *
dt_node::append_node (dt_node *n)
{
@@ -1069,54 +1077,52 @@ dt_node::append_node (dt_node *n)
return n;
}
+/* Append OP to the decision tree. */
+
dt_node *
dt_node::append_op (operand *op, dt_node *parent, unsigned pos)
{
dt_operand *parent_ = safe_as_a<dt_operand *> (parent);
- dt_node *n = new dt_operand (DT_OPERAND, op, 0, parent_, pos);
- dt_node *p = append_node (n);
-
- if (p != n)
- free (n);
-
- return p;
+ dt_operand *n = new dt_operand (DT_OPERAND, op, 0, parent_, pos);
+ return append_node (n);
}
+/* Append a DT_TRUE decision tree node. */
+
dt_node *
dt_node::append_true_op (dt_node *parent, unsigned pos)
{
dt_operand *parent_ = as_a<dt_operand *> (parent);
- dt_node *n = new dt_operand (DT_TRUE, 0, 0, parent_, pos);
- dt_node *p = append_node (n);
-
- if (p != n)
- free (n);
-
- return p;
+ dt_operand *n = new dt_operand (DT_TRUE, 0, 0, parent_, pos);
+ return append_node (n);
}
+/* Append a DT_MATCH decision tree node. */
+
dt_node *
dt_node::append_match_op (dt_operand *match_dop, dt_node *parent, unsigned pos)
{
- dt_operand *parent_ = static_cast<dt_operand *> (parent);
- dt_node *n = new dt_operand (DT_MATCH, 0, match_dop, parent_, pos);
- dt_node *p = append_node (n);
-
- if (p != n)
- free (n);
-
- return p;
+ dt_operand *parent_ = as_a<dt_operand *> (parent);
+ dt_operand *n = new dt_operand (DT_MATCH, 0, match_dop, parent_, pos);
+ return append_node (n);
}
+/* Append S to the decision tree. */
+
dt_node *
-dt_node::append_simplify (simplify *s, unsigned pattern_no, dt_operand **indexes)
+dt_node::append_simplify (simplify *s, unsigned pattern_no,
+ dt_operand **indexes)
{
- dt_node *n = new dt_simplify (s, pattern_no, indexes);
+ dt_simplify *n = new dt_simplify (s, pattern_no, indexes);
return append_node (n);
}
+/* Insert O into the decision tree and return the decision tree node found
+ or created. */
+
dt_node *
-decision_tree::insert_operand (dt_node *p, operand *o, dt_operand **indexes, unsigned pos, dt_node *parent)
+decision_tree::insert_operand (dt_node *p, operand *o, dt_operand **indexes,
+ unsigned pos, dt_node *parent)
{
dt_node *q, *elm = 0;
@@ -1187,6 +1193,8 @@ at_assert_elm:
return q;
}
+/* Insert S into the decision tree. */
+
void
decision_tree::insert (struct simplify *s, unsigned pattern_no)
{
@@ -1219,7 +1227,7 @@ decision_tree::print_node (dt_node *p, F
else if (p->type == dt_node::DT_TRUE)
fprintf (f, "true");
else if (p->type == dt_node::DT_MATCH)
- fprintf (f, "match (%p)", (void *) ((static_cast<dt_operand *>(p))->match_dop));
+ fprintf (f, "match (%p)", (void *)((as_a<dt_operand *>(p))->match_dop));
else if (p->type == dt_node::DT_SIMPLIFY)
{
dt_simplify *s = static_cast<dt_simplify *> (p);
@@ -1288,6 +1296,8 @@ get_operand_type (id_base *op, const cha
}
}
+/* Generate transform code for an expression. */
+
void
expr::gen_transform (FILE *f, const char *dest, bool gimple, int depth,
const char *in_type, dt_operand **indexes)
@@ -1310,7 +1320,7 @@ expr::gen_transform (FILE *f, const char
type = optype;
}
else if (is_a <operator_id *> (operation)
- && strcmp (as_a <operator_id *> (operation)->tcc, "tcc_comparison") == 0)
+ && !strcmp (as_a <operator_id *> (operation)->tcc, "tcc_comparison"))
{
/* comparisons use boolean_type_node (or what gets in), but
their operands need to figure out the types themselves. */
@@ -1447,8 +1457,11 @@ c_expr::gen_transform (FILE *f, const ch
}
}
+/* Generate transform code for a capture. */
+
void
-capture::gen_transform (FILE *f, const char *dest, bool gimple, int depth, const char *in_type, dt_operand **indexes)
+capture::gen_transform (FILE *f, const char *dest, bool gimple, int depth,
+ const char *in_type, dt_operand **indexes)
{
if (what && is_a<expr *> (what))
{
@@ -1463,6 +1476,9 @@ capture::gen_transform (FILE *f, const c
fprintf (f, "%s = captures[%u];\n", dest, where);
}
+/* Return the name of the operand representing the decision tree node.
+ Use NAME as space to generate it. */
+
char *
dt_operand::get_name (char *name)
{
@@ -1477,6 +1493,8 @@ dt_operand::get_name (char *name)
return name;
}
+/* Fill NAME with the operand name at position POS. */
+
void
dt_operand::gen_opname (char *name, unsigned pos)
{
@@ -1486,6 +1504,9 @@ dt_operand::gen_opname (char *name, unsi
sprintf (name, "o%u%u", level, pos);
}
+/* Generate matching code for the decision tree operand which is
+ a predicate. */
+
unsigned
dt_operand::gen_predicate (FILE *f, const char *opname, bool gimple)
{
@@ -1506,6 +1527,9 @@ dt_operand::gen_predicate (FILE *f, cons
return 1;
}
+/* Generate matching code for the decision tree operand which is
+ a capture-match. */
+
unsigned
dt_operand::gen_match_op (FILE *f, const char *opname)
{
@@ -1517,6 +1541,8 @@ dt_operand::gen_match_op (FILE *f, const
return 1;
}
+/* Generate GIMPLE matching code for the decision tree operand. */
+
unsigned
dt_operand::gen_gimple_expr (FILE *f)
{
@@ -1561,6 +1587,8 @@ dt_operand::gen_gimple_expr (FILE *f)
return n_ops;
}
+/* Generate GENERIC matching code for the decision tree operand. */
+
unsigned
dt_operand::gen_generic_expr (FILE *f, const char *opname)
{
@@ -1583,6 +1611,8 @@ dt_operand::gen_generic_expr (FILE *f, c
return 0;
}
+/* Generate matching code for the children of the decision tree node. */
+
void
dt_node::gen_kids (FILE *f, bool gimple)
{
@@ -1789,6 +1819,8 @@ dt_node::gen_kids (FILE *f, bool gimple)
true_operand->gen (f, gimple);
}
+/* Generate matching code for the decision tree operand. */
+
void
dt_operand::gen (FILE *f, bool gimple)
{
@@ -1973,7 +2005,8 @@ dt_simplify::gen (FILE *f, bool gimple)
fprintf (f, " return fold_build%d (%s, type",
e->ops.length (), e->operation->id);
else
- fprintf (f, " return build_call_expr (builtin_decl_implicit (%s), %d",
+ fprintf (f, " return build_call_expr "
+ "(builtin_decl_implicit (%s), %d",
e->operation->id, e->ops.length());
for (unsigned j = 0; j < e->ops.length (); ++j)
fprintf (f, ", res_op%d", j);
@@ -2872,6 +2905,8 @@ parser::parser (cpp_reader *r_)
}
+/* Helper for the linemap code. */
+
static size_t
round_alloc_size (size_t s)
{
More information about the Gcc-patches
mailing list