Index: gcc/genmatch.c =================================================================== --- gcc/genmatch.c (revision 215271) +++ gcc/genmatch.c (working copy) @@ -250,7 +250,7 @@ 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_transform (FILE *f, const char *, bool, int, const char *) = 0; + virtual void gen_transform (FILE *f, const char *, bool, int, const char *, dt_operand ** = 0) = 0; }; struct predicate : public operand @@ -257,7 +257,7 @@ { predicate (const char *ident_) : operand (OP_PREDICATE), ident (ident_) {} const char *ident; - virtual void gen_transform (FILE *, const char *, bool, int, const char *) + virtual void gen_transform (FILE *, const char *, bool, int, const char *, dt_operand ** = 0) { gcc_unreachable (); } }; @@ -277,7 +277,7 @@ e_operation *operation; vec ops; const char *expr_type; - virtual void gen_transform (FILE *f, const char *, bool, int, const char *); + virtual void gen_transform (FILE *f, const char *, bool, int, const char *, dt_operand ** = 0); }; struct c_expr : public operand @@ -300,7 +300,7 @@ char *fname; vec ids; - virtual void gen_transform (FILE *f, const char *, bool, int, const char *); + virtual void gen_transform (FILE *f, const char *, bool, int, const char *, dt_operand **); void output_code (FILE *f, bool); }; @@ -310,7 +310,7 @@ : operand (OP_CAPTURE), where (where_), what (what_) {} const char *where; operand *what; - virtual void gen_transform (FILE *f, const char *, bool, int, const char *); + virtual void gen_transform (FILE *f, const char *, bool, int, const char *, dt_operand ** = 0); }; template<> @@ -894,7 +894,7 @@ void expr::gen_transform (FILE *f, const char *dest, bool gimple, int depth, - const char *in_type) + const char *in_type, dt_operand **indexes) { bool conversion_p = is_conversion (operation->op); const char *type = expr_type; @@ -945,7 +945,7 @@ is not unless we somehow discover what operand we can generate first and do it in the appropriate order. */ - : (i == 0 ? in_type : type)); + : (i == 0 ? in_type : type), indexes); } if (gimple) @@ -1043,7 +1043,7 @@ void -c_expr::gen_transform (FILE *f, const char *dest, bool, int, const char *) +c_expr::gen_transform (FILE *f, const char *dest, bool, int, const char *, dt_operand **) { /* If this expression has an outlined function variant, call it. */ if (fname) @@ -1063,8 +1063,19 @@ } void -capture::gen_transform (FILE *f, const char *dest, bool, int, const char *) +capture::gen_transform (FILE *f, const char *dest, bool gimple, int depth, const char *in_type, dt_operand **indexes) { + if (what && is_a (what)) + { + int index = atoi (where); + if (indexes[index] == 0) + { + char buf[20]; + sprintf (buf, "captures[%s]", where); + what->gen_transform (f, buf, gimple, depth, in_type, 0); + } + } + fprintf (f, "%s = captures[%s];\n", dest, where); } @@ -1806,7 +1817,7 @@ snprintf (dest, 32, " res_ops[%d]", j); e->ops[j]->gen_transform (f, dest, true, 1, is_conversion (e->operation->op) - ? NULL : "type"); + ? NULL : "type", indexes); } /* Re-fold the toplevel result. It's basically an embedded gimple_build w/o actually building the stmt. */ @@ -1816,7 +1827,7 @@ else if (s->result->type == operand::OP_CAPTURE || s->result->type == operand::OP_C_EXPR) { - s->result->gen_transform (f, "res_ops[0]", true, 1, "type"); + s->result->gen_transform (f, "res_ops[0]", true, 1, "type", indexes); fprintf (f, "*res_code = TREE_CODE (res_ops[0]);\n"); } else @@ -1835,7 +1846,7 @@ snprintf (dest, 32, " res_op%d", j); e->ops[j]->gen_transform (f, dest, false, 1, is_conversion (e->operation->op) - ? NULL : "type"); + ? NULL : "type", indexes); } /* Re-fold the toplevel result. */ if (e->operation->op->kind == id_base::CODE) @@ -1852,7 +1863,7 @@ || s->result->type == operand::OP_C_EXPR) { fprintf (f, " tree res;\n"); - s->result->gen_transform (f, " res", false, 1, "type"); + s->result->gen_transform (f, " res", false, 1, "type", indexes); fprintf (f, " return res;\n"); } else Index: gcc/match-builtin.pd =================================================================== --- gcc/match-builtin.pd (revision 215271) +++ gcc/match-builtin.pd (working copy) @@ -41,11 +41,8 @@ (simplify (CABS @0) (SQRT (plus - /* ??? There is no way to CSE here. We'd need to support - expression captures here, like with - (mult (realpart@1 @0) @1) */ - (mult (realpart @0) (realpart @0)) - (mult (imagpart @0) (imagpart @0))))))) + (mult (realpart@1 @0) @1) + (mult (imagpart@2 @0) @2)))))) /* From fold_binary. */ /* Optimize x*pow(x,c) as pow(x,c+1). */