On Tue, 24 Jun 2014, Prathamesh Kulkarni wrote: > 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, applied. Richard. > 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; > -- Richard Biener <rguent...@suse.de> SUSE / SUSE Labs SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746 GF: Jeff Hawn, Jennifer Guild, Felix Imend"orffer