On Tue, Jun 24, 2014 at 9:00 PM, Richard Biener <rguent...@suse.de> wrote: > > This massages things so GENERIC code-gen works (well, is emitted > and compiles). The GENERIC interface matches that of > fold_{unary,binary,ternary} with also supporting calls here. > It's supposed to be called at the start of those functions > (and if it returns NULL_TREE their remains is executed). > > At the moment it just creates dead code. I'll see if it works > to wire it in tomorrow. > > Committed. Small point: I renamed dt_operand::gen_gimple_predicate/gen_gimple_match_op to gen_predicate/gen_match_op.
* genmatch.c (dt_operand::gen_gimple_predicate): Rename to ... (dt_operand::gen_predicate): ... this. (dt_operand::gen_gimple_match_op): Rename to ... (dt_operand::gen_match_op): ... this. Thanks and Regards, Prathamesh. > > Richard. > > 2014-06-24 Richard Biener <rguent...@suse.de> > > * genmatch.c (operand::gen_gimple_transform): Rename to... > (operand::gen_transform): ... this and add a flag argument for > the kind of IL to generate. > (predicate::gen_gimple_transform): Likewise. > (expr::gen_gimple_transform): Likewise. > (c_expr::gen_gimple_transform): Likewise. > (capture::gen_gimple_transform): Likewise. > (dt_node::gen_generic): Add. > (dt_operand::gen_generic_expr): Add flag whether to valueize. > (dt_operand::gen_generic_expr_expr): Likewise. > (dt_operand::gen_generic_expr_fn): Likewise. > (dt_simplify::gen_genric): Add. > (decision_tree::gen_generic): Likewise. > (main): Uncomment generic codegen. > > Index: genmatch.c > =================================================================== > --- genmatch.c (revision 211941) > +++ genmatch.c (working copy) > @@ -206,14 +206,14 @@ struct operand { > enum op_type { OP_PREDICATE, OP_EXPR, OP_CAPTURE, OP_C_EXPR }; > operand (enum op_type type_) : type (type_) {} > enum op_type type; > - virtual void gen_gimple_transform (FILE *f, const char *) = 0; > + virtual void gen_transform (FILE *f, const char *, bool) = 0; > }; > > struct predicate : public operand > { > predicate (const char *ident_) : operand (OP_PREDICATE), ident (ident_) {} > const char *ident; > - virtual void gen_gimple_transform (FILE *, const char *) { gcc_unreachable > (); } > + virtual void gen_transform (FILE *, const char *, bool) { gcc_unreachable > (); } > }; > > struct e_operation { > @@ -230,7 +230,7 @@ struct expr : public operand > void append_op (operand *op) { ops.safe_push (op); } > e_operation *operation; > vec<operand *> ops; > - virtual void gen_gimple_transform (FILE *f, const char *); > + virtual void gen_transform (FILE *f, const char *, bool); > }; > > struct c_expr : public operand > @@ -242,7 +242,7 @@ struct c_expr : public operand > vec<cpp_token> code; > unsigned nr_stmts; > char *fname; > - virtual void gen_gimple_transform (FILE *f, const char *); > + virtual void gen_transform (FILE *f, const char *, bool); > }; > > struct capture : public operand > @@ -251,7 +251,7 @@ struct capture : public operand > : operand (OP_CAPTURE), where (where_), what (what_) {} > const char *where; > operand *what; > - virtual void gen_gimple_transform (FILE *f, const char *); > + virtual void gen_transform (FILE *f, const char *, bool); > }; > > > @@ -324,6 +324,7 @@ struct dt_node > dt_node *append_simplify (simplify *, unsigned, dt_operand **); > > virtual void gen_gimple (FILE *) {} > + virtual void gen_generic (FILE *) {} > }; > > struct dt_operand: public dt_node > @@ -337,6 +338,7 @@ struct dt_operand: public dt_node > : dt_node (type), op (op_), match_dop (match_dop_), parent (parent_), > pos (pos_) {} > > virtual void gen_gimple (FILE *); > + virtual void gen_generic (FILE *); > unsigned gen_gimple_predicate (FILE *, const char *); > unsigned gen_gimple_match_op (FILE *, const char *); > > @@ -344,9 +346,9 @@ struct dt_operand: public dt_node > void gen_gimple_expr_expr (FILE *, expr *); > void gen_gimple_expr_fn (FILE *, expr *); > > - unsigned gen_generic_expr (FILE *, const char *); > - void gen_generic_expr_expr (FILE *, expr *, const char *); > - void gen_generic_expr_fn (FILE *, expr *, const char *); > + unsigned gen_generic_expr (FILE *, const char *, bool); > + void gen_generic_expr_expr (FILE *, expr *, const char *, bool); > + void gen_generic_expr_fn (FILE *, expr *, const char *, bool); > > char *get_name (char *); > void gen_opname (char *, unsigned); > @@ -369,6 +371,7 @@ struct dt_simplify: public dt_node > } > > virtual void gen_gimple (FILE *f); > + virtual void gen_generic (FILE *f); > }; > > struct decision_tree > @@ -377,6 +380,7 @@ struct decision_tree > > void insert (struct simplify *, unsigned); > void gen_gimple (FILE *f = stderr); > + void gen_generic (FILE *f = stderr); > void print (FILE *f = stderr); > > decision_tree () { root = new dt_node (dt_node::DT_NODE); } > @@ -535,7 +539,7 @@ commutate (operand *op) > /* Code gen off the AST. */ > > void > -expr::gen_gimple_transform (FILE *f, const char *dest) > +expr::gen_transform (FILE *f, const char *dest, bool gimple) > { > fprintf (f, "{\n"); > fprintf (f, " tree ops[%u], res;\n", ops.length ()); > @@ -543,31 +547,46 @@ expr::gen_gimple_transform (FILE *f, con > { > char dest[32]; > snprintf (dest, 32, " ops[%u]", i); > - ops[i]->gen_gimple_transform (f, dest); > + ops[i]->gen_transform (f, dest, gimple); > + } > + if (gimple) > + { > + /* ??? Have another helper that is like gimple_build but may > + fail if seq == NULL. */ > + fprintf (f, " if (!seq)\n" > + " {\n" > + " res = gimple_match_and_simplify (%s, TREE_TYPE > (ops[0])", > + operation->op->id); > + for (unsigned i = 0; i < ops.length (); ++i) > + fprintf (f, ", ops[%u]", i); > + fprintf (f, ", seq, valueize);\n"); > + fprintf (f, " if (!res) return false;\n"); > + fprintf (f, " }\n"); > + fprintf (f, " else\n"); > + fprintf (f, " res = gimple_build (seq, UNKNOWN_LOCATION, %s, " > + "TREE_TYPE (ops[0])", operation->op->id); > + for (unsigned i = 0; i < ops.length (); ++i) > + fprintf (f, ", ops[%u]", i); > + fprintf (f, ", valueize);\n"); > + } > + else > + { > + if (operation->op->kind == id_base::CODE) > + fprintf (f, " res = fold_build%d (%s, TREE_TYPE (ops[0])", > + ops.length(), operation->op->id); > + else > + fprintf (f, " res = build_call_expr (builtin_decl_implicit (%s), %d", > + operation->op->id, ops.length()); > + for (unsigned i = 0; i < ops.length (); ++i) > + fprintf (f, ", ops[%u]", i); > + fprintf (f, ");\n"); > } > - /* ??? Have another helper that is like gimple_build but may > - fail if seq == NULL. */ > - fprintf (f, " if (!seq)\n" > - " {\n" > - " res = gimple_match_and_simplify (%s, TREE_TYPE (ops[0])", > - operation->op->id); > - for (unsigned i = 0; i < ops.length (); ++i) > - fprintf (f, ", ops[%u]", i); > - fprintf (f, ", seq, valueize);\n"); > - fprintf (f, " if (!res) return false;\n"); > - fprintf (f, " }\n"); > - fprintf (f, " else\n"); > - fprintf (f, " res = gimple_build (seq, UNKNOWN_LOCATION, %s, " > - "TREE_TYPE (ops[0])", operation->op->id); > - for (unsigned i = 0; i < ops.length (); ++i) > - fprintf (f, ", ops[%u]", i); > - fprintf (f, ", valueize);\n"); > fprintf (f, " %s = res;\n", dest); > fprintf (f, "}"); > } > > void > -c_expr::gen_gimple_transform (FILE *f, const char *dest) > +c_expr::gen_transform (FILE *f, const char *dest, bool gimple) > { > /* If this expression has an outlined function variant, call it. */ > if (fname) > @@ -614,7 +633,7 @@ c_expr::gen_gimple_transform (FILE *f, c > } > > void > -capture::gen_gimple_transform (FILE *f, const char *dest) > +capture::gen_transform (FILE *f, const char *dest, bool) > { > fprintf (f, "%s = captures[%s];\n", dest, where); > } > @@ -949,7 +968,8 @@ dt_operand::gen_gimple_expr (FILE *f, co > > > void > -dt_operand::gen_generic_expr_expr (FILE *f, expr *e, const char *opname) > +dt_operand::gen_generic_expr_expr (FILE *f, expr *e, const char *opname, > + bool valueize) > { > unsigned n_ops = e->ops.length (); > > @@ -962,13 +982,16 @@ dt_operand::gen_generic_expr_expr (FILE > gen_opname (child_opname, i); > > fprintf (f, "tree %s = TREE_OPERAND (%s, %u);\n", child_opname, > opname, i); > - fprintf (f, "if ((%s = do_valueize (valueize, %s)) != 0)\n", > child_opname, child_opname); > - fprintf (f, "{\n"); > + if (valueize) > + { > + fprintf (f, "if ((%s = do_valueize (valueize, %s)) != 0)\n", > child_opname, child_opname); > + fprintf (f, "{\n"); > + } > } > } > > void > -dt_operand::gen_generic_expr_fn (FILE *f, expr *e, const char *opname) > +dt_operand::gen_generic_expr_fn (FILE *f, expr *e, const char *opname, bool > valueize) > { > unsigned n_ops = e->ops.length (); > fn_id *op = static_cast <fn_id *> (e->operation->op); > @@ -987,17 +1010,20 @@ dt_operand::gen_generic_expr_fn (FILE *f > gen_opname (child_opname, i); > > fprintf (f, "tree %s = CALL_EXPR_ARG (%s, %u);\n", child_opname, > opname, i); > - fprintf (f, "if ((%s = do_valueize (valueize, %s)) != 0)\n", > child_opname, child_opname); > - fprintf (f, "{\n"); > + if (valueize) > + { > + fprintf (f, "if ((%s = do_valueize (valueize, %s)) != 0)\n", > child_opname, child_opname); > + fprintf (f, "{\n"); > + } > } > } > > unsigned > -dt_operand::gen_generic_expr (FILE *f, const char *opname) > +dt_operand::gen_generic_expr (FILE *f, const char *opname, bool valueize) > { > expr *e = static_cast<expr *> (op); > - (e->operation->op->kind == id_base::CODE) ? gen_generic_expr_expr (f, e, > opname) : gen_generic_expr_fn (f, e, opname); > - return e->ops.length () + 1; > + (e->operation->op->kind == id_base::CODE) ? gen_generic_expr_expr (f, e, > opname, valueize) : gen_generic_expr_fn (f, e, opname, valueize); > + return valueize ? e->ops.length () + 1 : 1; > } > > void > @@ -1024,14 +1050,14 @@ dt_operand::gen_gimple (FILE *f) > enum tree_code code = op_id->code; > > if (code == REALPART_EXPR || code == IMAGPART_EXPR || code == > VIEW_CONVERT_EXPR || code == BIT_FIELD_REF) > - n_braces = gen_generic_expr (f, opname); > + n_braces = gen_generic_expr (f, opname, true); > > // check for cond_expr, 0th operand -> generic > else if (parent->type == dt_node::DT_OPERAND && parent->op->type == > operand::OP_EXPR) > { > e = static_cast<expr *> (parent->op); > op_id = static_cast <operator_id *> (e->operation->op); > - n_braces = (op_id->code == COND_EXPR && pos == 0) ? > gen_generic_expr (f, opname) : gen_gimple_expr (f, opname); > + n_braces = (op_id->code == COND_EXPR && pos == 0) ? > gen_generic_expr (f, opname, true) : gen_gimple_expr (f, opname); > } > else > n_braces = gen_gimple_expr (f, opname); > @@ -1060,6 +1086,48 @@ dt_operand::gen_gimple (FILE *f) > } > > void > +dt_operand::gen_generic (FILE *f) > +{ > + char opname[20]; > + get_name (opname); > + > + fprintf (f, "{\n"); > + > + unsigned n_braces = 0; > + > + if (type == DT_OPERAND) > + switch (op->type) > + { > + case operand::OP_PREDICATE: > + n_braces = gen_gimple_predicate (f, opname); > + break; > + > + case operand::OP_EXPR: > + n_braces = gen_generic_expr (f, opname, false); > + break; > + > + default: > + gcc_unreachable (); > + } > + else if (type == DT_TRUE) > + ; > + else if (type == DT_MATCH) > + n_braces = gen_gimple_match_op (f, opname); > + else > + gcc_unreachable (); > + > + unsigned i; > + > + for (i = 0; i < kids.length (); ++i) > + kids[i]->gen_generic (f); > + > + for (i = 0; i < n_braces; ++i) > + fprintf (f, "}\n"); > + > + fprintf (f, "}\n"); > +} > + > +void > dt_simplify::gen_gimple (FILE *f) > { > > @@ -1079,7 +1147,7 @@ dt_simplify::gen_gimple (FILE *f) > { > output_line_directive (f, s->ifexpr_location); > fprintf (f, "if ("); > - s->ifexpr->gen_gimple_transform (f, NULL); > + s->ifexpr->gen_transform (f, NULL, true); > fprintf (f, ")\n"); > fprintf (f, "{\n"); > } > @@ -1093,7 +1161,7 @@ dt_simplify::gen_gimple (FILE *f) > { > char dest[32]; > snprintf (dest, 32, " res_ops[%d]", j); > - e->ops[j]->gen_gimple_transform (f, dest); > + e->ops[j]->gen_transform (f, dest, true); > } > /* Re-fold the toplevel result. It's basically an embedded > gimple_build w/o actually building the stmt. */ > @@ -1103,8 +1171,7 @@ dt_simplify::gen_gimple (FILE *f) > else if (s->result->type == operand::OP_CAPTURE > || s->result->type == operand::OP_C_EXPR) > { > - s->result->gen_gimple_transform (f, > - "res_ops[0]"); > + s->result->gen_transform (f, "res_ops[0]", true); > fprintf (f, "*res_code = TREE_CODE (res_ops[0]);\n"); > } > else > @@ -1118,6 +1185,70 @@ dt_simplify::gen_gimple (FILE *f) > } > > > +void > +dt_simplify::gen_generic (FILE *f) > +{ > + > + fprintf (f, "/* simplify %u */\n", pattern_no); > + > + fprintf (f, "{\n"); > + fprintf (f, "tree captures[4] = {};\n"); > + > + for (unsigned i = 0; i < dt_simplify::capture_max; ++i) > + if (indexes[i]) > + { > + char opname[20]; > + fprintf (f, "captures[%u] = %s;\n", i, indexes[i]->get_name (opname)); > + } > + > + if (s->ifexpr) > + { > + output_line_directive (f, s->ifexpr_location); > + fprintf (f, "if ("); > + s->ifexpr->gen_transform (f, NULL, false); > + fprintf (f, ")\n"); > + fprintf (f, "{\n"); > + } > + output_line_directive (f, s->result_location); > + > + if (s->result->type == operand::OP_EXPR) > + { > + expr *e = static_cast <expr *> (s->result); > + for (unsigned j = 0; j < e->ops.length (); ++j) > + { > + fprintf (f, " tree res_op%d;\n", j); > + char dest[32]; > + snprintf (dest, 32, " res_op%d", j); > + e->ops[j]->gen_transform (f, dest, false); > + } > + /* Re-fold the toplevel result. */ > + if (e->operation->op->kind == id_base::CODE) > + fprintf (f, " return fold_build%d (%s, TREE_TYPE (res_op0)", > + e->ops.length (), e->operation->op->id); > + else > + fprintf (f, " return build_call_expr (builtin_decl_implicit > (%s), %d", > + e->operation->op->id, e->ops.length()); > + for (unsigned j = 0; j < e->ops.length (); ++j) > + fprintf (f, ", res_op%d", j); > + fprintf (f, ");\n"); > + } > + else if (s->result->type == operand::OP_CAPTURE > + || s->result->type == operand::OP_C_EXPR) > + { > + fprintf (f, " tree res;\n"); > + s->result->gen_transform (f, " res", false); > + fprintf (f, " return res;\n"); > + } > + else > + gcc_unreachable (); > + > + if (s->ifexpr) > + fprintf (f, "}\n"); > + > + fprintf (f, "}\n"); > +} > + > + > > void > decision_tree::gen_gimple (FILE *f) > @@ -1152,6 +1283,37 @@ decision_tree::gen_gimple (FILE *f) > } > > > +void > +decision_tree::gen_generic (FILE *f) > +{ > + fprintf (f, "tree\n" > + "generic_match_and_simplify (code_helper code, tree type"); > + for (unsigned i = 0; i < 3; ++i) > + fprintf (f, ", tree op%d", i); > + fprintf (f, ")\n"); > + fprintf (f, "{\n"); > + > + for (unsigned i = 0; i < root->kids.length (); i++) > + { > + dt_operand *dop = static_cast<dt_operand *>(root->kids[i]); > + expr *e = static_cast<expr *>(dop->op); > + > + if (i) > + fprintf (f, "else "); > + fprintf (f, "if (code == %s)\n", e->operation->op->id); > + fprintf (f, "{\n"); > + > + for (unsigned j = 0; j < dop->kids.length (); ++j) > + dop->kids[j]->gen_generic (f); > + > + fprintf (f, "}\n"); > + } > + > + fprintf (f, "return NULL_TREE;\n"); > + fprintf (f, "}\n"); > +} > + > + > static void > outline_c_exprs (FILE *f, struct operand *op) > { > @@ -1602,7 +1764,7 @@ main(int argc, char **argv) > else if (strcmp (argv[1], "-generic") == 0) > { > write_header (stdout, simplifiers, "generic-match-head.c"); > - //dt.gen_generic (stdout); > + dt.gen_generic (stdout); > } > else > return 1;
Index: gcc/genmatch.c =================================================================== --- gcc/genmatch.c (revision 211950) +++ gcc/genmatch.c (working copy) @@ -339,8 +339,8 @@ struct dt_operand: public dt_node virtual void gen_gimple (FILE *); virtual void gen_generic (FILE *); - unsigned gen_gimple_predicate (FILE *, const char *); - unsigned gen_gimple_match_op (FILE *, const char *); + unsigned gen_predicate (FILE *, const char *); + unsigned gen_match_op (FILE *, const char *); unsigned gen_gimple_expr (FILE *, const char *); void gen_gimple_expr_expr (FILE *, expr *); @@ -887,7 +887,7 @@ dt_operand::gen_opname (char *name, unsi } unsigned -dt_operand::gen_gimple_predicate (FILE *f, const char *opname) +dt_operand::gen_predicate (FILE *f, const char *opname) { predicate *p = static_cast<predicate *> (op); @@ -897,7 +897,7 @@ dt_operand::gen_gimple_predicate (FILE * } unsigned -dt_operand::gen_gimple_match_op (FILE *f, const char *opname) +dt_operand::gen_match_op (FILE *f, const char *opname) { char match_opname[20]; match_dop->get_name (match_opname); @@ -1040,7 +1040,7 @@ dt_operand::gen_gimple (FILE *f) switch (op->type) { case operand::OP_PREDICATE: - n_braces = gen_gimple_predicate (f, opname); + n_braces = gen_predicate (f, opname); break; case operand::OP_EXPR: @@ -1070,7 +1070,7 @@ dt_operand::gen_gimple (FILE *f) else if (type == DT_TRUE) ; else if (type == DT_MATCH) - n_braces = gen_gimple_match_op (f, opname); + n_braces = gen_match_op (f, opname); else gcc_unreachable (); @@ -1099,7 +1099,7 @@ dt_operand::gen_generic (FILE *f) switch (op->type) { case operand::OP_PREDICATE: - n_braces = gen_gimple_predicate (f, opname); + n_braces = gen_predicate (f, opname); break; case operand::OP_EXPR: @@ -1112,7 +1112,7 @@ dt_operand::gen_generic (FILE *f) else if (type == DT_TRUE) ; else if (type == DT_MATCH) - n_braces = gen_gimple_match_op (f, opname); + n_braces = gen_match_op (f, opname); else gcc_unreachable ();