Commit c551c21d by Michael Matz Committed by Michael Matz

genmatch.c (fprintf_indent): New function.

	* genmatch.c (fprintf_indent): New function.
	(operand::gen_transform): Add indent parameter.
	(expr::gen_transform, c_expr::gen_transform,
	capture::gen_transform): Ditto and use fprintf_indent.
	(dt_node::gen, dt_node::gen_kids, dt_node::gen_kids_1): Ditto.
	(dt_operand::gen, dt_operand::gen_predicate,
	dt_operand::gen_match_op, dt_operand::gen_gimple_expr,
	dt_operand::gen_generic_expr, dt_simplify::gen): Ditto.
	(decision_tree::gen_gimple): Adjust calls and indent generated
	code.
	(decision_tree::gen_generic): Ditto.
	(write_predicate): Ditto.

From-SVN: r225617
parent cb1fd5b4
2015-07-09 Michael Matz <matz@suse.de>
* genmatch.c (fprintf_indent): New function.
(operand::gen_transform): Add indent parameter.
(expr::gen_transform, c_expr::gen_transform,
capture::gen_transform): Ditto and use fprintf_indent.
(dt_node::gen, dt_node::gen_kids, dt_node::gen_kids_1): Ditto.
(dt_operand::gen, dt_operand::gen_predicate,
dt_operand::gen_match_op, dt_operand::gen_gimple_expr,
dt_operand::gen_generic_expr, dt_simplify::gen): Ditto.
(decision_tree::gen_gimple): Adjust calls and indent generated
code.
(decision_tree::gen_generic): Ditto.
(write_predicate): Ditto.
2015-07-08 Uros Bizjak <ubizjak@gmail.com> 2015-07-08 Uros Bizjak <ubizjak@gmail.com>
PR target/66814 PR target/66814
......
...@@ -126,6 +126,23 @@ warning_at (const cpp_token *tk, const char *msg, ...) ...@@ -126,6 +126,23 @@ warning_at (const cpp_token *tk, const char *msg, ...)
va_end (ap); va_end (ap);
} }
/* Like fprintf, but print INDENT spaces at the beginning. */
static void
#if GCC_VERSION >= 4001
__attribute__((format (printf, 3, 4)))
#endif
fprintf_indent (FILE *f, unsigned int indent, const char *format, ...)
{
va_list ap;
for (; indent >= 8; indent -= 8)
fputc ('\t', f);
fprintf (f, "%*s", indent, "");
va_start (ap, format);
vfprintf (f, format, ap);
va_end (ap);
}
static void static void
output_line_directive (FILE *f, source_location location, output_line_directive (FILE *f, source_location location,
bool dumpfile = false) bool dumpfile = false)
...@@ -468,7 +485,7 @@ struct operand { ...@@ -468,7 +485,7 @@ struct operand {
enum op_type { OP_PREDICATE, OP_EXPR, OP_CAPTURE, OP_C_EXPR }; enum op_type { OP_PREDICATE, OP_EXPR, OP_CAPTURE, OP_C_EXPR };
operand (enum op_type type_) : type (type_) {} operand (enum op_type type_) : type (type_) {}
enum op_type type; enum op_type type;
virtual void gen_transform (FILE *, const char *, bool, int, virtual void gen_transform (FILE *, int, const char *, bool, int,
const char *, capture_info *, const char *, capture_info *,
dt_operand ** = 0, dt_operand ** = 0,
bool = true) bool = true)
...@@ -510,7 +527,7 @@ struct expr : public operand ...@@ -510,7 +527,7 @@ struct expr : public operand
/* Whether pushing any stmt to the sequence should be conditional /* Whether pushing any stmt to the sequence should be conditional
on this expression having a single-use. */ on this expression having a single-use. */
bool force_single_use; bool force_single_use;
virtual void gen_transform (FILE *f, const char *, bool, int, virtual void gen_transform (FILE *f, int, const char *, bool, int,
const char *, capture_info *, const char *, capture_info *,
dt_operand ** = 0, bool = true); dt_operand ** = 0, bool = true);
}; };
...@@ -541,7 +558,7 @@ struct c_expr : public operand ...@@ -541,7 +558,7 @@ struct c_expr : public operand
unsigned nr_stmts; unsigned nr_stmts;
/* The identifier replacement vector. */ /* The identifier replacement vector. */
vec<id_tab> ids; vec<id_tab> ids;
virtual void gen_transform (FILE *f, const char *, bool, int, virtual void gen_transform (FILE *f, int, const char *, bool, int,
const char *, capture_info *, const char *, capture_info *,
dt_operand ** = 0, bool = true); dt_operand ** = 0, bool = true);
}; };
...@@ -556,7 +573,7 @@ struct capture : public operand ...@@ -556,7 +573,7 @@ struct capture : public operand
unsigned where; unsigned where;
/* The captured value. */ /* The captured value. */
operand *what; operand *what;
virtual void gen_transform (FILE *f, const char *, bool, int, virtual void gen_transform (FILE *f, int, const char *, bool, int,
const char *, capture_info *, const char *, capture_info *,
dt_operand ** = 0, bool = true); dt_operand ** = 0, bool = true);
}; };
...@@ -1166,10 +1183,10 @@ struct dt_node ...@@ -1166,10 +1183,10 @@ struct dt_node
dt_node *append_match_op (dt_operand *, dt_node *parent = 0, unsigned pos = 0); dt_node *append_match_op (dt_operand *, dt_node *parent = 0, unsigned pos = 0);
dt_node *append_simplify (simplify *, unsigned, dt_operand **); dt_node *append_simplify (simplify *, unsigned, dt_operand **);
virtual void gen (FILE *, bool) {} virtual void gen (FILE *, int, bool) {}
void gen_kids (FILE *, bool); void gen_kids (FILE *, int, bool);
void gen_kids_1 (FILE *, bool, void gen_kids_1 (FILE *, int, bool,
vec<dt_operand *>, vec<dt_operand *>, vec<dt_operand *>, vec<dt_operand *>, vec<dt_operand *>, vec<dt_operand *>,
vec<dt_operand *>, vec<dt_operand *>, vec<dt_node *>); vec<dt_operand *>, vec<dt_operand *>, vec<dt_node *>);
}; };
...@@ -1188,12 +1205,12 @@ struct dt_operand : public dt_node ...@@ -1188,12 +1205,12 @@ struct dt_operand : public dt_node
: dt_node (type), op (op_), match_dop (match_dop_), : dt_node (type), op (op_), match_dop (match_dop_),
parent (parent_), pos (pos_) {} parent (parent_), pos (pos_) {}
void gen (FILE *, bool); void gen (FILE *, int, bool);
unsigned gen_predicate (FILE *, const char *, bool); unsigned gen_predicate (FILE *, int, const char *, bool);
unsigned gen_match_op (FILE *, const char *); unsigned gen_match_op (FILE *, int, const char *);
unsigned gen_gimple_expr (FILE *); unsigned gen_gimple_expr (FILE *, int);
unsigned gen_generic_expr (FILE *, const char *); unsigned gen_generic_expr (FILE *, int, const char *);
char *get_name (char *); char *get_name (char *);
void gen_opname (char *, unsigned); void gen_opname (char *, unsigned);
...@@ -1211,7 +1228,7 @@ struct dt_simplify : public dt_node ...@@ -1211,7 +1228,7 @@ struct dt_simplify : public dt_node
: dt_node (DT_SIMPLIFY), s (s_), pattern_no (pattern_no_), : dt_node (DT_SIMPLIFY), s (s_), pattern_no (pattern_no_),
indexes (indexes_) {} indexes (indexes_) {}
void gen (FILE *f, bool); void gen (FILE *f, int, bool);
}; };
template<> template<>
...@@ -1739,8 +1756,8 @@ get_operand_type (id_base *op, const char *in_type, ...@@ -1739,8 +1756,8 @@ get_operand_type (id_base *op, const char *in_type,
/* Generate transform code for an expression. */ /* Generate transform code for an expression. */
void void
expr::gen_transform (FILE *f, const char *dest, bool gimple, int depth, expr::gen_transform (FILE *f, int indent, const char *dest, bool gimple,
const char *in_type, capture_info *cinfo, int depth, const char *in_type, capture_info *cinfo,
dt_operand **indexes, bool) dt_operand **indexes, bool)
{ {
bool conversion_p = is_conversion (operation); bool conversion_p = is_conversion (operation);
...@@ -1784,18 +1801,20 @@ expr::gen_transform (FILE *f, const char *dest, bool gimple, int depth, ...@@ -1784,18 +1801,20 @@ expr::gen_transform (FILE *f, const char *dest, bool gimple, int depth,
if (!type) if (!type)
fatal ("two conversions in a row"); fatal ("two conversions in a row");
fprintf (f, "{\n"); fprintf_indent (f, indent, "{\n");
fprintf (f, " tree ops%d[%u], res;\n", depth, ops.length ()); indent += 2;
fprintf_indent (f, indent, "tree ops%d[%u], res;\n", depth, ops.length ());
char op0type[64]; char op0type[64];
snprintf (op0type, 64, "TREE_TYPE (ops%d[0])", depth); snprintf (op0type, 64, "TREE_TYPE (ops%d[0])", depth);
for (unsigned i = 0; i < ops.length (); ++i) for (unsigned i = 0; i < ops.length (); ++i)
{ {
char dest[32]; char dest[32];
snprintf (dest, 32, " ops%d[%u]", depth, i); snprintf (dest, 32, "ops%d[%u]", depth, i);
const char *optype const char *optype
= get_operand_type (operation, in_type, expr_type, = get_operand_type (operation, in_type, expr_type,
i == 0 ? NULL : op0type); i == 0 ? NULL : op0type);
ops[i]->gen_transform (f, dest, gimple, depth + 1, optype, cinfo, indexes, ops[i]->gen_transform (f, indent, dest, gimple, depth + 1, optype,
cinfo, indexes,
((!(*operation == COND_EXPR) ((!(*operation == COND_EXPR)
&& !(*operation == VEC_COND_EXPR)) && !(*operation == VEC_COND_EXPR))
|| i != 0)); || i != 0));
...@@ -1810,45 +1829,67 @@ expr::gen_transform (FILE *f, const char *dest, bool gimple, int depth, ...@@ -1810,45 +1829,67 @@ expr::gen_transform (FILE *f, const char *dest, bool gimple, int depth,
if (gimple) if (gimple)
{ {
if (*operation == CONVERT_EXPR) if (*operation == CONVERT_EXPR)
fprintf (f, " if (%s != TREE_TYPE (ops%d[0])\n" {
" && !useless_type_conversion_p (%s, TREE_TYPE (ops%d[0])))\n" fprintf_indent (f, indent,
" {\n", type, depth, type, depth); "if (%s != TREE_TYPE (ops%d[0])\n",
type, depth);
fprintf_indent (f, indent,
" && !useless_type_conversion_p (%s, TREE_TYPE (ops%d[0])))\n",
type, depth);
fprintf_indent (f, indent + 2, "{\n");
indent += 4;
}
/* ??? Building a stmt can fail for various reasons here, seq being /* ??? Building a stmt can fail for various reasons here, seq being
NULL or the stmt referencing SSA names occuring in abnormal PHIs. NULL or the stmt referencing SSA names occuring in abnormal PHIs.
So if we fail here we should continue matching other patterns. */ So if we fail here we should continue matching other patterns. */
fprintf (f, " code_helper tem_code = %s;\n" fprintf_indent (f, indent, "code_helper tem_code = %s;\n", opr);
" tree tem_ops[3] = { ", opr); fprintf_indent (f, indent, "tree tem_ops[3] = { ");
for (unsigned i = 0; i < ops.length (); ++i) for (unsigned i = 0; i < ops.length (); ++i)
fprintf (f, "ops%d[%u]%s", depth, i, fprintf (f, "ops%d[%u]%s", depth, i,
i == ops.length () - 1 ? " };\n" : ", "); i == ops.length () - 1 ? " };\n" : ", ");
fprintf (f, " gimple_resimplify%d (lseq, &tem_code, %s, tem_ops, valueize);\n", fprintf_indent (f, indent,
ops.length (), type); "gimple_resimplify%d (lseq, &tem_code, %s, tem_ops, valueize);\n",
fprintf (f, " res = maybe_push_res_to_seq (tem_code, %s, tem_ops, lseq);\n" ops.length (), type);
" if (!res) return false;\n", type); fprintf_indent (f, indent,
"res = maybe_push_res_to_seq (tem_code, %s, tem_ops, lseq);\n",
type);
fprintf_indent (f, indent,
"if (!res) return false;\n");
if (*operation == CONVERT_EXPR) if (*operation == CONVERT_EXPR)
fprintf (f, " }\n" {
" else\n" indent -= 4;
" res = ops%d[0];\n", depth); fprintf_indent (f, indent, " }\n");
fprintf_indent (f, indent, "else\n");
fprintf_indent (f, indent, " res = ops%d[0];\n", depth);
}
} }
else else
{ {
if (*operation == CONVERT_EXPR) if (*operation == CONVERT_EXPR)
fprintf (f, " if (TREE_TYPE (ops%d[0]) != %s)\n", depth, type); {
fprintf_indent (f, indent, "if (TREE_TYPE (ops%d[0]) != %s)\n",
depth, type);
indent += 2;
}
if (operation->kind == id_base::CODE) if (operation->kind == id_base::CODE)
fprintf (f, " res = fold_build%d_loc (loc, %s, %s", fprintf_indent (f, indent, "res = fold_build%d_loc (loc, %s, %s",
ops.length(), opr, type); ops.length(), opr, type);
else else
fprintf (f, " res = build_call_expr_loc (loc, " fprintf_indent (f, indent, "res = build_call_expr_loc (loc, "
"builtin_decl_implicit (%s), %d", opr, ops.length()); "builtin_decl_implicit (%s), %d", opr, ops.length());
for (unsigned i = 0; i < ops.length (); ++i) for (unsigned i = 0; i < ops.length (); ++i)
fprintf (f, ", ops%d[%u]", depth, i); fprintf (f, ", ops%d[%u]", depth, i);
fprintf (f, ");\n"); fprintf (f, ");\n");
if (*operation == CONVERT_EXPR) if (*operation == CONVERT_EXPR)
fprintf (f, " else\n" {
" res = ops%d[0];\n", depth); indent -= 2;
fprintf_indent (f, indent, "else\n");
fprintf_indent (f, indent, " res = ops%d[0];\n", depth);
}
} }
fprintf (f, "%s = res;\n", dest); fprintf_indent (f, indent, "%s = res;\n", dest);
fprintf (f, "}\n"); indent -= 2;
fprintf_indent (f, indent, "}\n");
} }
/* Generate code for a c_expr which is either the expression inside /* Generate code for a c_expr which is either the expression inside
...@@ -1856,12 +1897,12 @@ expr::gen_transform (FILE *f, const char *dest, bool gimple, int depth, ...@@ -1856,12 +1897,12 @@ expr::gen_transform (FILE *f, const char *dest, bool gimple, int depth,
result to be stored to DEST. */ result to be stored to DEST. */
void void
c_expr::gen_transform (FILE *f, const char *dest, c_expr::gen_transform (FILE *f, int indent, const char *dest,
bool, int, const char *, capture_info *, bool, int, const char *, capture_info *,
dt_operand **, bool) dt_operand **, bool)
{ {
if (dest && nr_stmts == 1) if (dest && nr_stmts == 1)
fprintf (f, "%s = ", dest); fprintf_indent (f, indent, "%s = ", dest);
unsigned stmt_nr = 1; unsigned stmt_nr = 1;
for (unsigned i = 0; i < code.length (); ++i) for (unsigned i = 0; i < code.length (); ++i)
...@@ -1915,10 +1956,9 @@ c_expr::gen_transform (FILE *f, const char *dest, ...@@ -1915,10 +1956,9 @@ c_expr::gen_transform (FILE *f, const char *dest,
if (token->type == CPP_SEMICOLON) if (token->type == CPP_SEMICOLON)
{ {
stmt_nr++; stmt_nr++;
fputc ('\n', f);
if (dest && stmt_nr == nr_stmts) if (dest && stmt_nr == nr_stmts)
fprintf (f, "\n %s = ", dest); fprintf_indent (f, indent, "%s = ", dest);
else
fputc ('\n', f);
} }
} }
} }
...@@ -1926,8 +1966,8 @@ c_expr::gen_transform (FILE *f, const char *dest, ...@@ -1926,8 +1966,8 @@ c_expr::gen_transform (FILE *f, const char *dest,
/* Generate transform code for a capture. */ /* Generate transform code for a capture. */
void void
capture::gen_transform (FILE *f, const char *dest, bool gimple, int depth, capture::gen_transform (FILE *f, int indent, const char *dest, bool gimple,
const char *in_type, capture_info *cinfo, int depth, const char *in_type, capture_info *cinfo,
dt_operand **indexes, bool expand_compares) dt_operand **indexes, bool expand_compares)
{ {
if (what && is_a<expr *> (what)) if (what && is_a<expr *> (what))
...@@ -1936,11 +1976,12 @@ capture::gen_transform (FILE *f, const char *dest, bool gimple, int depth, ...@@ -1936,11 +1976,12 @@ capture::gen_transform (FILE *f, const char *dest, bool gimple, int depth,
{ {
char buf[20]; char buf[20];
sprintf (buf, "captures[%u]", where); sprintf (buf, "captures[%u]", where);
what->gen_transform (f, buf, gimple, depth, in_type, cinfo, NULL); what->gen_transform (f, indent, buf, gimple, depth, in_type,
cinfo, NULL);
} }
} }
fprintf (f, "%s = captures[%u];\n", dest, where); fprintf_indent (f, indent, "%s = captures[%u];\n", dest, where);
/* ??? Stupid tcc_comparison GENERIC trees in COND_EXPRs. Deal /* ??? Stupid tcc_comparison GENERIC trees in COND_EXPRs. Deal
with substituting a capture of that. with substituting a capture of that.
...@@ -1948,13 +1989,16 @@ capture::gen_transform (FILE *f, const char *dest, bool gimple, int depth, ...@@ -1948,13 +1989,16 @@ capture::gen_transform (FILE *f, const char *dest, bool gimple, int depth,
to match. */ to match. */
if (gimple && expand_compares if (gimple && expand_compares
&& cinfo->info[where].cond_expr_cond_p) && cinfo->info[where].cond_expr_cond_p)
fprintf (f, "if (COMPARISON_CLASS_P (%s))\n" {
" {\n" fprintf_indent (f, indent, "if (COMPARISON_CLASS_P (%s))\n", dest);
" if (!seq) return false;\n" fprintf_indent (f, indent, " {\n");
" %s = gimple_build (seq, TREE_CODE (%s)," fprintf_indent (f, indent, " if (!seq) return false;\n");
" TREE_TYPE (%s), TREE_OPERAND (%s, 0)," fprintf_indent (f, indent, " %s = gimple_build (seq, TREE_CODE (%s),"
" TREE_OPERAND (%s, 1));\n" " TREE_TYPE (%s), TREE_OPERAND (%s, 0),"
" }\n", dest, dest, dest, dest, dest, dest); " TREE_OPERAND (%s, 1));\n",
dest, dest, dest, dest, dest);
fprintf_indent (f, indent, " }\n");
}
} }
/* Return the name of the operand representing the decision tree node. /* Return the name of the operand representing the decision tree node.
...@@ -1989,7 +2033,7 @@ dt_operand::gen_opname (char *name, unsigned pos) ...@@ -1989,7 +2033,7 @@ dt_operand::gen_opname (char *name, unsigned pos)
a predicate. */ a predicate. */
unsigned unsigned
dt_operand::gen_predicate (FILE *f, const char *opname, bool gimple) dt_operand::gen_predicate (FILE *f, int indent, const char *opname, bool gimple)
{ {
predicate *p = as_a <predicate *> (op); predicate *p = as_a <predicate *> (op);
...@@ -1998,13 +2042,14 @@ dt_operand::gen_predicate (FILE *f, const char *opname, bool gimple) ...@@ -1998,13 +2042,14 @@ dt_operand::gen_predicate (FILE *f, const char *opname, bool gimple)
/* If this is a predicate generated from a pattern mangle its /* If this is a predicate generated from a pattern mangle its
name and pass on the valueize hook. */ name and pass on the valueize hook. */
if (gimple) if (gimple)
fprintf (f, "if (gimple_%s (%s, valueize))\n", p->p->id, opname); fprintf_indent (f, indent, "if (gimple_%s (%s, valueize))\n",
p->p->id, opname);
else else
fprintf (f, "if (tree_%s (%s))\n", p->p->id, opname); fprintf_indent (f, indent, "if (tree_%s (%s))\n", p->p->id, opname);
} }
else else
fprintf (f, "if (%s (%s))\n", p->p->id, opname); fprintf_indent (f, indent, "if (%s (%s))\n", p->p->id, opname);
fprintf (f, "{\n"); fprintf_indent (f, indent + 2, "{\n");
return 1; return 1;
} }
...@@ -2012,20 +2057,20 @@ dt_operand::gen_predicate (FILE *f, const char *opname, bool gimple) ...@@ -2012,20 +2057,20 @@ dt_operand::gen_predicate (FILE *f, const char *opname, bool gimple)
a capture-match. */ a capture-match. */
unsigned unsigned
dt_operand::gen_match_op (FILE *f, const char *opname) dt_operand::gen_match_op (FILE *f, int indent, const char *opname)
{ {
char match_opname[20]; char match_opname[20];
match_dop->get_name (match_opname); match_dop->get_name (match_opname);
fprintf (f, "if (%s == %s || operand_equal_p (%s, %s, 0))\n", fprintf_indent (f, indent, "if (%s == %s || operand_equal_p (%s, %s, 0))\n",
opname, match_opname, opname, match_opname); opname, match_opname, opname, match_opname);
fprintf (f, "{\n"); fprintf_indent (f, indent + 2, "{\n");
return 1; return 1;
} }
/* Generate GIMPLE matching code for the decision tree operand. */ /* Generate GIMPLE matching code for the decision tree operand. */
unsigned unsigned
dt_operand::gen_gimple_expr (FILE *f) dt_operand::gen_gimple_expr (FILE *f, int indent)
{ {
expr *e = static_cast<expr *> (op); expr *e = static_cast<expr *> (op);
id_base *id = e->operation; id_base *id = e->operation;
...@@ -2045,25 +2090,37 @@ dt_operand::gen_gimple_expr (FILE *f) ...@@ -2045,25 +2090,37 @@ dt_operand::gen_gimple_expr (FILE *f)
/* ??? If this is a memory operation we can't (and should not) /* ??? If this is a memory operation we can't (and should not)
match this. The only sensible operand types are match this. The only sensible operand types are
SSA names and invariants. */ SSA names and invariants. */
fprintf (f, "tree %s = TREE_OPERAND (gimple_assign_rhs1 (def_stmt), %i);\n", fprintf_indent (f, indent,
child_opname, i); "tree %s = TREE_OPERAND (gimple_assign_rhs1 (def_stmt), %i);\n",
fprintf (f, "if ((TREE_CODE (%s) == SSA_NAME\n" child_opname, i);
"|| is_gimple_min_invariant (%s))\n" fprintf_indent (f, indent,
"&& (%s = do_valueize (valueize, %s)))\n" "if ((TREE_CODE (%s) == SSA_NAME\n",
"{\n", child_opname, child_opname, child_opname, child_opname);
child_opname); fprintf_indent (f, indent,
" || is_gimple_min_invariant (%s))\n",
child_opname);
fprintf_indent (f, indent,
" && (%s = do_valueize (valueize, %s)))\n",
child_opname, child_opname);
fprintf_indent (f, indent,
" {\n");
indent += 4;
continue; continue;
} }
else else
fprintf (f, "tree %s = gimple_assign_rhs%u (def_stmt);\n", fprintf_indent (f, indent,
child_opname, i + 1); "tree %s = gimple_assign_rhs%u (def_stmt);\n",
child_opname, i + 1);
} }
else else
fprintf (f, "tree %s = gimple_call_arg (def_stmt, %u);\n", fprintf_indent (f, indent,
child_opname, i); "tree %s = gimple_call_arg (def_stmt, %u);\n",
fprintf (f, "if ((%s = do_valueize (valueize, %s)))\n", child_opname, i);
child_opname, child_opname); fprintf_indent (f, indent,
fprintf (f, "{\n"); "if ((%s = do_valueize (valueize, %s)))\n",
child_opname, child_opname);
fprintf_indent (f, indent, " {\n");
indent += 4;
} }
/* While the toplevel operands are canonicalized by the caller /* While the toplevel operands are canonicalized by the caller
after valueizing operands of sub-expressions we have to after valueizing operands of sub-expressions we have to
...@@ -2079,9 +2136,12 @@ dt_operand::gen_gimple_expr (FILE *f) ...@@ -2079,9 +2136,12 @@ dt_operand::gen_gimple_expr (FILE *f)
char child_opname0[20], child_opname1[20]; char child_opname0[20], child_opname1[20];
gen_opname (child_opname0, 0); gen_opname (child_opname0, 0);
gen_opname (child_opname1, 1); gen_opname (child_opname1, 1);
fprintf (f, "if (tree_swap_operands_p (%s, %s, false))\n" fprintf_indent (f, indent,
" std::swap (%s, %s);\n", child_opname0, child_opname1, "if (tree_swap_operands_p (%s, %s, false))\n",
child_opname0, child_opname1); child_opname0, child_opname1);
fprintf_indent (f, indent,
" std::swap (%s, %s);\n",
child_opname0, child_opname1);
} }
} }
...@@ -2091,7 +2151,7 @@ dt_operand::gen_gimple_expr (FILE *f) ...@@ -2091,7 +2151,7 @@ dt_operand::gen_gimple_expr (FILE *f)
/* Generate GENERIC matching code for the decision tree operand. */ /* Generate GENERIC matching code for the decision tree operand. */
unsigned unsigned
dt_operand::gen_generic_expr (FILE *f, const char *opname) dt_operand::gen_generic_expr (FILE *f, int indent, const char *opname)
{ {
expr *e = static_cast<expr *> (op); expr *e = static_cast<expr *> (op);
unsigned n_ops = e->ops.length (); unsigned n_ops = e->ops.length ();
...@@ -2102,11 +2162,11 @@ dt_operand::gen_generic_expr (FILE *f, const char *opname) ...@@ -2102,11 +2162,11 @@ dt_operand::gen_generic_expr (FILE *f, const char *opname)
gen_opname (child_opname, i); gen_opname (child_opname, i);
if (e->operation->kind == id_base::CODE) if (e->operation->kind == id_base::CODE)
fprintf (f, "tree %s = TREE_OPERAND (%s, %u);\n", fprintf_indent (f, indent, "tree %s = TREE_OPERAND (%s, %u);\n",
child_opname, opname, i); child_opname, opname, i);
else else
fprintf (f, "tree %s = CALL_EXPR_ARG (%s, %u);\n", fprintf_indent (f, indent, "tree %s = CALL_EXPR_ARG (%s, %u);\n",
child_opname, opname, i); child_opname, opname, i);
} }
return 0; return 0;
...@@ -2115,7 +2175,7 @@ dt_operand::gen_generic_expr (FILE *f, const char *opname) ...@@ -2115,7 +2175,7 @@ dt_operand::gen_generic_expr (FILE *f, const char *opname)
/* Generate matching code for the children of the decision tree node. */ /* Generate matching code for the children of the decision tree node. */
void void
dt_node::gen_kids (FILE *f, bool gimple) dt_node::gen_kids (FILE *f, int indent, bool gimple)
{ {
auto_vec<dt_operand *> gimple_exprs; auto_vec<dt_operand *> gimple_exprs;
auto_vec<dt_operand *> generic_exprs; auto_vec<dt_operand *> generic_exprs;
...@@ -2163,10 +2223,10 @@ dt_node::gen_kids (FILE *f, bool gimple) ...@@ -2163,10 +2223,10 @@ dt_node::gen_kids (FILE *f, bool gimple)
{ {
/* A DT_TRUE operand serves as a barrier - generate code now /* A DT_TRUE operand serves as a barrier - generate code now
for what we have collected sofar. */ for what we have collected sofar. */
gen_kids_1 (f, gimple, gimple_exprs, generic_exprs, gen_kids_1 (f, indent, gimple, gimple_exprs, generic_exprs,
fns, generic_fns, preds, others); fns, generic_fns, preds, others);
/* And output the true operand itself. */ /* And output the true operand itself. */
kids[i]->gen (f, gimple); kids[i]->gen (f, indent, gimple);
gimple_exprs.truncate (0); gimple_exprs.truncate (0);
generic_exprs.truncate (0); generic_exprs.truncate (0);
fns.truncate (0); fns.truncate (0);
...@@ -2179,14 +2239,14 @@ dt_node::gen_kids (FILE *f, bool gimple) ...@@ -2179,14 +2239,14 @@ dt_node::gen_kids (FILE *f, bool gimple)
} }
/* Generate code for the remains. */ /* Generate code for the remains. */
gen_kids_1 (f, gimple, gimple_exprs, generic_exprs, gen_kids_1 (f, indent, gimple, gimple_exprs, generic_exprs,
fns, generic_fns, preds, others); fns, generic_fns, preds, others);
} }
/* Generate matching code for the children of the decision tree node. */ /* Generate matching code for the children of the decision tree node. */
void void
dt_node::gen_kids_1 (FILE *f, bool gimple, dt_node::gen_kids_1 (FILE *f, int indent, bool gimple,
vec<dt_operand *> gimple_exprs, vec<dt_operand *> gimple_exprs,
vec<dt_operand *> generic_exprs, vec<dt_operand *> generic_exprs,
vec<dt_operand *> fns, vec<dt_operand *> fns,
...@@ -2213,67 +2273,88 @@ dt_node::gen_kids_1 (FILE *f, bool gimple, ...@@ -2213,67 +2273,88 @@ dt_node::gen_kids_1 (FILE *f, bool gimple,
else else
generic_exprs[0]->get_name (kid_opname); generic_exprs[0]->get_name (kid_opname);
fprintf (f, "switch (TREE_CODE (%s))\n" fprintf_indent (f, indent, "switch (TREE_CODE (%s))\n", kid_opname);
"{\n", kid_opname); fprintf_indent (f, indent, " {\n");
indent += 4;
} }
if (exprs_len || fns_len) if (exprs_len || fns_len)
{ {
fprintf (f, "case SSA_NAME:\n"); fprintf_indent (f, indent,
fprintf (f, "if (do_valueize (valueize, %s) != NULL_TREE)\n", kid_opname); "case SSA_NAME:\n");
fprintf (f, "{\n"); fprintf_indent (f, indent,
fprintf (f, "gimple def_stmt = SSA_NAME_DEF_STMT (%s);\n", kid_opname); " if (do_valueize (valueize, %s) != NULL_TREE)\n",
kid_opname);
fprintf_indent (f, indent,
" {\n");
fprintf_indent (f, indent,
" gimple def_stmt = SSA_NAME_DEF_STMT (%s);\n",
kid_opname);
indent += 6;
if (exprs_len) if (exprs_len)
{ {
fprintf (f, "if (is_gimple_assign (def_stmt))\n"); fprintf_indent (f, indent,
fprintf (f, "switch (gimple_assign_rhs_code (def_stmt))\n" "if (is_gimple_assign (def_stmt))\n");
"{\n"); fprintf_indent (f, indent,
" switch (gimple_assign_rhs_code (def_stmt))\n");
indent += 4;
fprintf_indent (f, indent, "{\n");
for (unsigned i = 0; i < exprs_len; ++i) for (unsigned i = 0; i < exprs_len; ++i)
{ {
expr *e = as_a <expr *> (gimple_exprs[i]->op); expr *e = as_a <expr *> (gimple_exprs[i]->op);
id_base *op = e->operation; id_base *op = e->operation;
if (*op == CONVERT_EXPR || *op == NOP_EXPR) if (*op == CONVERT_EXPR || *op == NOP_EXPR)
fprintf (f, "CASE_CONVERT:\n"); fprintf_indent (f, indent, " CASE_CONVERT:\n");
else else
fprintf (f, "case %s:\n", op->id); fprintf_indent (f, indent, " case %s:\n", op->id);
fprintf (f, "{\n"); fprintf_indent (f, indent, " {\n");
gimple_exprs[i]->gen (f, true); gimple_exprs[i]->gen (f, indent + 6, true);
fprintf (f, "break;\n" fprintf_indent (f, indent, " break;\n");
"}\n"); fprintf_indent (f, indent, " }\n");
} }
fprintf (f, "default:;\n" fprintf_indent (f, indent, " default:;\n");
"}\n"); indent -= 4;
fprintf_indent (f, indent, "}\n");
} }
if (fns_len) if (fns_len)
{ {
if (exprs_len) if (exprs_len)
fprintf (f, "else "); fprintf_indent (f, indent, "else ");
else
fprintf (f, "if (gimple_call_builtin_p (def_stmt, BUILT_IN_NORMAL))\n" fprintf_indent (f, indent, " ");
"{\n"
"tree fndecl = gimple_call_fndecl (def_stmt);\n" fprintf (f, "if (gimple_call_builtin_p (def_stmt, BUILT_IN_NORMAL))\n");
"switch (DECL_FUNCTION_CODE (fndecl))\n" fprintf_indent (f, indent,
"{\n"); " {\n");
fprintf_indent (f, indent,
" tree fndecl = gimple_call_fndecl (def_stmt);\n");
fprintf_indent (f, indent,
" switch (DECL_FUNCTION_CODE (fndecl))\n");
fprintf_indent (f, indent,
" {\n");
indent += 8;
for (unsigned i = 0; i < fns_len; ++i) for (unsigned i = 0; i < fns_len; ++i)
{ {
expr *e = as_a <expr *>(fns[i]->op); expr *e = as_a <expr *>(fns[i]->op);
fprintf (f, "case %s:\n" fprintf_indent (f, indent, "case %s:\n", e->operation->id);
"{\n", e->operation->id); fprintf_indent (f, indent, " {\n");
fns[i]->gen (f, true); fns[i]->gen (f, indent + 4, true);
fprintf (f, "break;\n" fprintf_indent (f, indent, " break;\n");
"}\n"); fprintf_indent (f, indent, " }\n");
} }
fprintf (f, "default:;\n" fprintf_indent (f, indent, "default:;\n");
"}\n" indent -= 8;
"}\n"); fprintf_indent (f, indent, " }\n");
fprintf_indent (f, indent, " }\n");
} }
fprintf (f, "}\n" indent -= 6;
"break;\n"); fprintf_indent (f, indent, " }\n");
fprintf_indent (f, indent, " break;\n");
} }
for (unsigned i = 0; i < generic_exprs.length (); ++i) for (unsigned i = 0; i < generic_exprs.length (); ++i)
...@@ -2281,76 +2362,89 @@ dt_node::gen_kids_1 (FILE *f, bool gimple, ...@@ -2281,76 +2362,89 @@ dt_node::gen_kids_1 (FILE *f, bool gimple,
expr *e = as_a <expr *>(generic_exprs[i]->op); expr *e = as_a <expr *>(generic_exprs[i]->op);
id_base *op = e->operation; id_base *op = e->operation;
if (*op == CONVERT_EXPR || *op == NOP_EXPR) if (*op == CONVERT_EXPR || *op == NOP_EXPR)
fprintf (f, "CASE_CONVERT:\n"); fprintf_indent (f, indent, "CASE_CONVERT:\n");
else else
fprintf (f, "case %s:\n", op->id); fprintf_indent (f, indent, "case %s:\n", op->id);
fprintf (f, "{\n"); fprintf_indent (f, indent, " {\n");
generic_exprs[i]->gen (f, gimple); generic_exprs[i]->gen (f, indent + 4, gimple);
fprintf (f, "break;\n" fprintf_indent (f, indent, " break;\n");
"}\n"); fprintf_indent (f, indent, " }\n");
} }
if (gfns_len) if (gfns_len)
{ {
fprintf (f, "case CALL_EXPR:\n" fprintf_indent (f, indent,
"{\n" "case CALL_EXPR:\n");
"tree fndecl = get_callee_fndecl (%s);\n" fprintf_indent (f, indent,
"if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)\n" " {\n");
"switch (DECL_FUNCTION_CODE (fndecl))\n" fprintf_indent (f, indent,
"{\n", kid_opname); " tree fndecl = get_callee_fndecl (%s);\n",
kid_opname);
fprintf_indent (f, indent,
" if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)\n");
fprintf_indent (f, indent,
" switch (DECL_FUNCTION_CODE (fndecl))\n");
fprintf_indent (f, indent,
" {\n");
indent += 10;
for (unsigned j = 0; j < generic_fns.length (); ++j) for (unsigned j = 0; j < generic_fns.length (); ++j)
{ {
expr *e = as_a <expr *>(generic_fns[j]->op); expr *e = as_a <expr *>(generic_fns[j]->op);
gcc_assert (e->operation->kind == id_base::FN); gcc_assert (e->operation->kind == id_base::FN);
fprintf (f, "case %s:\n" fprintf_indent (f, indent, "case %s:\n", e->operation->id);
"{\n", e->operation->id); fprintf_indent (f, indent, " {\n");
generic_fns[j]->gen (f, false); generic_fns[j]->gen (f, indent + 4, false);
fprintf (f, "break;\n" fprintf_indent (f, indent, " break;\n");
"}\n"); fprintf_indent (f, indent, " }\n");
} }
fprintf (f, "default:;\n" indent -= 10;
"}\n" fprintf_indent (f, indent, " default:;\n");
"break;\n" fprintf_indent (f, indent, " }\n");
"}\n"); fprintf_indent (f, indent, " break;\n");
fprintf_indent (f, indent, " }\n");
} }
/* Close switch (TREE_CODE ()). */ /* Close switch (TREE_CODE ()). */
if (exprs_len || fns_len || gexprs_len || gfns_len) if (exprs_len || fns_len || gexprs_len || gfns_len)
fprintf (f, "default:;\n" {
"}\n"); indent -= 4;
fprintf_indent (f, indent, " default:;\n");
fprintf_indent (f, indent, " }\n");
}
for (unsigned i = 0; i < preds.length (); ++i) for (unsigned i = 0; i < preds.length (); ++i)
{ {
expr *e = as_a <expr *> (preds[i]->op); expr *e = as_a <expr *> (preds[i]->op);
predicate_id *p = as_a <predicate_id *> (e->operation); predicate_id *p = as_a <predicate_id *> (e->operation);
preds[i]->get_name (kid_opname); preds[i]->get_name (kid_opname);
fprintf (f, "tree %s_pops[%d];\n", kid_opname, p->nargs); fprintf_indent (f, indent, "tree %s_pops[%d];\n", kid_opname, p->nargs);
fprintf (f, "if (%s_%s (%s, %s_pops%s))\n", fprintf_indent (f, indent, "if (%s_%s (%s, %s_pops%s))\n",
gimple ? "gimple" : "tree", gimple ? "gimple" : "tree",
p->id, kid_opname, kid_opname, p->id, kid_opname, kid_opname,
gimple ? ", valueize" : ""); gimple ? ", valueize" : "");
fprintf (f, "{\n"); fprintf_indent (f, indent, " {\n");
for (int j = 0; j < p->nargs; ++j) for (int j = 0; j < p->nargs; ++j)
{ {
char child_opname[20]; char child_opname[20];
preds[i]->gen_opname (child_opname, j); preds[i]->gen_opname (child_opname, j);
fprintf (f, "tree %s = %s_pops[%d];\n", child_opname, kid_opname, j); fprintf_indent (f, indent + 4, "tree %s = %s_pops[%d];\n",
child_opname, kid_opname, j);
} }
preds[i]->gen_kids (f, gimple); preds[i]->gen_kids (f, indent + 4, gimple);
fprintf (f, "}\n"); fprintf (f, "}\n");
} }
for (unsigned i = 0; i < others.length (); ++i) for (unsigned i = 0; i < others.length (); ++i)
others[i]->gen (f, gimple); others[i]->gen (f, indent, gimple);
} }
/* Generate matching code for the decision tree operand. */ /* Generate matching code for the decision tree operand. */
void void
dt_operand::gen (FILE *f, bool gimple) dt_operand::gen (FILE *f, int indent, bool gimple)
{ {
char opname[20]; char opname[20];
get_name (opname); get_name (opname);
...@@ -2361,14 +2455,14 @@ dt_operand::gen (FILE *f, bool gimple) ...@@ -2361,14 +2455,14 @@ dt_operand::gen (FILE *f, bool gimple)
switch (op->type) switch (op->type)
{ {
case operand::OP_PREDICATE: case operand::OP_PREDICATE:
n_braces = gen_predicate (f, opname, gimple); n_braces = gen_predicate (f, indent, opname, gimple);
break; break;
case operand::OP_EXPR: case operand::OP_EXPR:
if (gimple) if (gimple)
n_braces = gen_gimple_expr (f); n_braces = gen_gimple_expr (f, indent);
else else
n_braces = gen_generic_expr (f, opname); n_braces = gen_generic_expr (f, indent, opname);
break; break;
default: default:
...@@ -2377,14 +2471,20 @@ dt_operand::gen (FILE *f, bool gimple) ...@@ -2377,14 +2471,20 @@ dt_operand::gen (FILE *f, bool gimple)
else if (type == DT_TRUE) else if (type == DT_TRUE)
; ;
else if (type == DT_MATCH) else if (type == DT_MATCH)
n_braces = gen_match_op (f, opname); n_braces = gen_match_op (f, indent, opname);
else else
gcc_unreachable (); gcc_unreachable ();
gen_kids (f, gimple); indent += 4 * n_braces;
gen_kids (f, indent, gimple);
for (unsigned i = 0; i < n_braces; ++i) for (unsigned i = 0; i < n_braces; ++i)
fprintf (f, "}\n"); {
indent -= 4;
if (indent < 0)
indent = 0;
fprintf_indent (f, indent, " }\n");
}
} }
...@@ -2394,19 +2494,21 @@ dt_operand::gen (FILE *f, bool gimple) ...@@ -2394,19 +2494,21 @@ dt_operand::gen (FILE *f, bool gimple)
that is not part of the decision tree (simplify->match). */ that is not part of the decision tree (simplify->match). */
void void
dt_simplify::gen (FILE *f, bool gimple) dt_simplify::gen (FILE *f, int indent, bool gimple)
{ {
fprintf (f, "{\n"); fprintf_indent (f, indent, "{\n");
indent += 2;
output_line_directive (f, s->result_location); output_line_directive (f, s->result_location);
if (s->capture_max >= 0) if (s->capture_max >= 0)
fprintf (f, "tree captures[%u] ATTRIBUTE_UNUSED = {};\n", fprintf_indent (f, indent, "tree captures[%u] ATTRIBUTE_UNUSED = {};\n",
s->capture_max + 1); s->capture_max + 1);
for (int i = 0; i <= s->capture_max; ++i) for (int i = 0; i <= s->capture_max; ++i)
if (indexes[i]) if (indexes[i])
{ {
char opname[20]; char opname[20];
fprintf (f, "captures[%u] = %s;\n", i, indexes[i]->get_name (opname)); fprintf_indent (f, indent, "captures[%u] = %s;\n",
i, indexes[i]->get_name (opname));
} }
unsigned n_braces = 0; unsigned n_braces = 0;
...@@ -2417,18 +2519,19 @@ dt_simplify::gen (FILE *f, bool gimple) ...@@ -2417,18 +2519,19 @@ dt_simplify::gen (FILE *f, bool gimple)
if_or_with &w = s->ifexpr_vec[i]; if_or_with &w = s->ifexpr_vec[i];
if (w.is_with) if (w.is_with)
{ {
fprintf (f, "{\n"); fprintf_indent (f, indent, "{\n");
indent += 4;
output_line_directive (f, w.location); output_line_directive (f, w.location);
w.cexpr->gen_transform (f, NULL, true, 1, "type", NULL); w.cexpr->gen_transform (f, indent, NULL, true, 1, "type", NULL);
n_braces++; n_braces++;
} }
else else
{ {
output_line_directive (f, w.location); output_line_directive (f, w.location);
fprintf (f, "if ("); fprintf_indent (f, indent, "if (");
if (i == s->ifexpr_vec.length () - 1 if (i == s->ifexpr_vec.length () - 1
|| s->ifexpr_vec[i+1].is_with) || s->ifexpr_vec[i+1].is_with)
w.cexpr->gen_transform (f, NULL, true, 1, "type", NULL); w.cexpr->gen_transform (f, indent, NULL, true, 1, "type", NULL);
else else
{ {
unsigned j = i; unsigned j = i;
...@@ -2438,10 +2541,10 @@ dt_simplify::gen (FILE *f, bool gimple) ...@@ -2438,10 +2541,10 @@ dt_simplify::gen (FILE *f, bool gimple)
{ {
fprintf (f, "\n"); fprintf (f, "\n");
output_line_directive (f, s->ifexpr_vec[j].location); output_line_directive (f, s->ifexpr_vec[j].location);
fprintf (f, "&& "); fprintf_indent (f, indent + 4, "&& ");
} }
fprintf (f, "("); fprintf (f, "(");
s->ifexpr_vec[j].cexpr->gen_transform (f, NULL, s->ifexpr_vec[j].cexpr->gen_transform (f, 0, NULL,
true, 1, "type", true, 1, "type",
NULL); NULL);
fprintf (f, ")"); fprintf (f, ")");
...@@ -2454,7 +2557,8 @@ dt_simplify::gen (FILE *f, bool gimple) ...@@ -2454,7 +2557,8 @@ dt_simplify::gen (FILE *f, bool gimple)
fprintf (f, ")\n"); fprintf (f, ")\n");
} }
} }
fprintf (f, "{\n"); fprintf_indent (f, indent + 2, "{\n");
indent += 4;
n_braces++; n_braces++;
} }
...@@ -2470,15 +2574,18 @@ dt_simplify::gen (FILE *f, bool gimple) ...@@ -2470,15 +2574,18 @@ dt_simplify::gen (FILE *f, bool gimple)
{ {
for (unsigned i = 0; i < as_a <expr *> (s->match)->ops.length (); ++i) for (unsigned i = 0; i < as_a <expr *> (s->match)->ops.length (); ++i)
if (cinfo.force_no_side_effects & (1 << i)) if (cinfo.force_no_side_effects & (1 << i))
fprintf (f, "if (TREE_SIDE_EFFECTS (op%d)) return NULL_TREE;\n", i); fprintf_indent (f, indent,
"if (TREE_SIDE_EFFECTS (op%d)) return NULL_TREE;\n",
i);
for (int i = 0; i <= s->capture_max; ++i) for (int i = 0; i <= s->capture_max; ++i)
if (cinfo.info[i].cse_p) if (cinfo.info[i].cse_p)
; ;
else if (cinfo.info[i].force_no_side_effects_p else if (cinfo.info[i].force_no_side_effects_p
&& (cinfo.info[i].toplevel_msk && (cinfo.info[i].toplevel_msk
& cinfo.force_no_side_effects) == 0) & cinfo.force_no_side_effects) == 0)
fprintf (f, "if (TREE_SIDE_EFFECTS (captures[%d])) " fprintf_indent (f, indent,
"return NULL_TREE;\n", i); "if (TREE_SIDE_EFFECTS (captures[%d])) "
"return NULL_TREE;\n", i);
else if ((cinfo.info[i].toplevel_msk else if ((cinfo.info[i].toplevel_msk
& cinfo.force_no_side_effects) != 0) & cinfo.force_no_side_effects) != 0)
/* Mark capture as having no side-effects if we had to verify /* Mark capture as having no side-effects if we had to verify
...@@ -2489,28 +2596,33 @@ dt_simplify::gen (FILE *f, bool gimple) ...@@ -2489,28 +2596,33 @@ dt_simplify::gen (FILE *f, bool gimple)
{ {
/* Force single-use restriction by only allowing simple /* Force single-use restriction by only allowing simple
results via setting seq to NULL. */ results via setting seq to NULL. */
fprintf (f, "gimple_seq *lseq = seq;\n"); fprintf_indent (f, indent, "gimple_seq *lseq = seq;\n");
bool first_p = true; bool first_p = true;
for (int i = 0; i <= s->capture_max; ++i) for (int i = 0; i <= s->capture_max; ++i)
if (cinfo.info[i].force_single_use) if (cinfo.info[i].force_single_use)
{ {
if (first_p) if (first_p)
{ {
fprintf (f, "if (lseq\n" fprintf_indent (f, indent, "if (lseq\n");
"&& ("); fprintf_indent (f, indent, " && (");
first_p = false; first_p = false;
} }
else else
fprintf (f, "\n|| "); {
fprintf (f, "\n");
fprintf_indent (f, indent, " || ");
}
fprintf (f, "!single_use (captures[%d])", i); fprintf (f, "!single_use (captures[%d])", i);
} }
if (!first_p) if (!first_p)
fprintf (f, "))\n" {
"lseq = NULL;\n"); fprintf (f, "))\n");
fprintf_indent (f, indent, " lseq = NULL;\n");
}
} }
} }
fprintf (f, "if (dump_file && (dump_flags & TDF_DETAILS)) " fprintf_indent (f, indent, "if (dump_file && (dump_flags & TDF_DETAILS)) "
"fprintf (dump_file, \"Applying pattern "); "fprintf (dump_file, \"Applying pattern ");
output_line_directive (f, s->result_location, true); output_line_directive (f, s->result_location, true);
fprintf (f, ", %%s:%%d\\n\", __FILE__, __LINE__);\n"); fprintf (f, ", %%s:%%d\\n\", __FILE__, __LINE__);\n");
...@@ -2519,7 +2631,7 @@ dt_simplify::gen (FILE *f, bool gimple) ...@@ -2519,7 +2631,7 @@ dt_simplify::gen (FILE *f, bool gimple)
if (!result) if (!result)
{ {
/* If there is no result then this is a predicate implementation. */ /* If there is no result then this is a predicate implementation. */
fprintf (f, "return true;\n"); fprintf_indent (f, indent, "return true;\n");
} }
else if (gimple) else if (gimple)
{ {
...@@ -2533,18 +2645,17 @@ dt_simplify::gen (FILE *f, bool gimple) ...@@ -2533,18 +2645,17 @@ dt_simplify::gen (FILE *f, bool gimple)
expr *e = as_a <expr *> (result); expr *e = as_a <expr *> (result);
bool is_predicate = is_a <predicate_id *> (e->operation); bool is_predicate = is_a <predicate_id *> (e->operation);
if (!is_predicate) if (!is_predicate)
fprintf (f, "*res_code = %s;\n", fprintf_indent (f, indent, "*res_code = %s;\n",
*e->operation == CONVERT_EXPR *e->operation == CONVERT_EXPR
? "NOP_EXPR" : e->operation->id); ? "NOP_EXPR" : e->operation->id);
for (unsigned j = 0; j < e->ops.length (); ++j) for (unsigned j = 0; j < e->ops.length (); ++j)
{ {
char dest[32]; char dest[32];
snprintf (dest, 32, " res_ops[%d]", j); snprintf (dest, 32, "res_ops[%d]", j);
const char *optype const char *optype
= get_operand_type (e->operation, = get_operand_type (e->operation,
"type", e->expr_type, "type", e->expr_type,
j == 0 j == 0 ? NULL : "TREE_TYPE (res_ops[0])");
? NULL : "TREE_TYPE (res_ops[0])");
/* We need to expand GENERIC conditions we captured from /* We need to expand GENERIC conditions we captured from
COND_EXPRs. */ COND_EXPRs. */
bool expand_generic_cond_exprs_p bool expand_generic_cond_exprs_p
...@@ -2555,38 +2666,46 @@ dt_simplify::gen (FILE *f, bool gimple) ...@@ -2555,38 +2666,46 @@ dt_simplify::gen (FILE *f, bool gimple)
&& ((!(*e->operation == COND_EXPR) && ((!(*e->operation == COND_EXPR)
&& !(*e->operation == VEC_COND_EXPR)) && !(*e->operation == VEC_COND_EXPR))
|| j != 0)); || j != 0));
e->ops[j]->gen_transform (f, dest, true, 1, optype, &cinfo, e->ops[j]->gen_transform (f, indent, dest, true, 1, optype,
&cinfo,
indexes, expand_generic_cond_exprs_p); indexes, expand_generic_cond_exprs_p);
} }
/* Re-fold the toplevel result. It's basically an embedded /* Re-fold the toplevel result. It's basically an embedded
gimple_build w/o actually building the stmt. */ gimple_build w/o actually building the stmt. */
if (!is_predicate) if (!is_predicate)
fprintf (f, "gimple_resimplify%d (lseq, res_code, type, " fprintf_indent (f, indent,
"res_ops, valueize);\n", e->ops.length ()); "gimple_resimplify%d (lseq, res_code, type, "
"res_ops, valueize);\n", e->ops.length ());
} }
else if (result->type == operand::OP_CAPTURE else if (result->type == operand::OP_CAPTURE
|| result->type == operand::OP_C_EXPR) || result->type == operand::OP_C_EXPR)
{ {
result->gen_transform (f, "res_ops[0]", true, 1, "type", result->gen_transform (f, indent, "res_ops[0]", true, 1, "type",
&cinfo, indexes, false); &cinfo, indexes, false);
fprintf (f, "*res_code = TREE_CODE (res_ops[0]);\n"); fprintf_indent (f, indent, "*res_code = TREE_CODE (res_ops[0]);\n");
if (is_a <capture *> (result) if (is_a <capture *> (result)
&& cinfo.info[as_a <capture *> (result)->where].cond_expr_cond_p) && cinfo.info[as_a <capture *> (result)->where].cond_expr_cond_p)
{ {
/* ??? Stupid tcc_comparison GENERIC trees in COND_EXPRs. Deal /* ??? Stupid tcc_comparison GENERIC trees in COND_EXPRs. Deal
with substituting a capture of that. */ with substituting a capture of that. */
fprintf (f, "if (COMPARISON_CLASS_P (res_ops[0]))\n" fprintf_indent (f, indent,
" {\n" "if (COMPARISON_CLASS_P (res_ops[0]))\n");
" tree tem = res_ops[0];\n" fprintf_indent (f, indent,
" res_ops[0] = TREE_OPERAND (tem, 0);\n" " {\n");
" res_ops[1] = TREE_OPERAND (tem, 1);\n" fprintf_indent (f, indent,
" }\n"); " tree tem = res_ops[0];\n");
fprintf_indent (f, indent,
" res_ops[0] = TREE_OPERAND (tem, 0);\n");
fprintf_indent (f, indent,
" res_ops[1] = TREE_OPERAND (tem, 1);\n");
fprintf_indent (f, indent,
" }\n");
} }
} }
else else
gcc_unreachable (); gcc_unreachable ();
fprintf (f, "return true;\n"); fprintf_indent (f, indent, "return true;\n");
} }
else /* GENERIC */ else /* GENERIC */
{ {
...@@ -2602,9 +2721,14 @@ dt_simplify::gen (FILE *f, bool gimple) ...@@ -2602,9 +2721,14 @@ dt_simplify::gen (FILE *f, bool gimple)
{ {
if (!cinfo.info[i].force_no_side_effects_p if (!cinfo.info[i].force_no_side_effects_p
&& cinfo.info[i].result_use_count > 1) && cinfo.info[i].result_use_count > 1)
fprintf (f, " if (TREE_SIDE_EFFECTS (captures[%d]))\n" {
" captures[%d] = save_expr (captures[%d]);\n", fprintf_indent (f, indent,
i, i, i); "if (TREE_SIDE_EFFECTS (captures[%d]))\n",
i);
fprintf_indent (f, indent,
" captures[%d] = save_expr (captures[%d]);\n",
i, i);
}
} }
for (unsigned j = 0; j < e->ops.length (); ++j) for (unsigned j = 0; j < e->ops.length (); ++j)
{ {
...@@ -2613,38 +2737,41 @@ dt_simplify::gen (FILE *f, bool gimple) ...@@ -2613,38 +2737,41 @@ dt_simplify::gen (FILE *f, bool gimple)
snprintf (dest, 32, "res_ops[%d]", j); snprintf (dest, 32, "res_ops[%d]", j);
else else
{ {
fprintf (f, " tree res_op%d;\n", j); fprintf_indent (f, indent, "tree res_op%d;\n", j);
snprintf (dest, 32, " res_op%d", j); snprintf (dest, 32, "res_op%d", j);
} }
const char *optype const char *optype
= get_operand_type (e->operation, = get_operand_type (e->operation,
"type", e->expr_type, "type", e->expr_type,
j == 0 j == 0
? NULL : "TREE_TYPE (res_op0)"); ? NULL : "TREE_TYPE (res_op0)");
e->ops[j]->gen_transform (f, dest, false, 1, optype, e->ops[j]->gen_transform (f, indent, dest, false, 1, optype,
&cinfo, indexes); &cinfo, indexes);
} }
if (is_predicate) if (is_predicate)
fprintf (f, "return true;\n"); fprintf_indent (f, indent, "return true;\n");
else else
{ {
fprintf (f, " tree res;\n"); fprintf_indent (f, indent, "tree res;\n");
/* Re-fold the toplevel result. Use non_lvalue to /* Re-fold the toplevel result. Use non_lvalue to
build NON_LVALUE_EXPRs so they get properly build NON_LVALUE_EXPRs so they get properly
ignored when in GIMPLE form. */ ignored when in GIMPLE form. */
if (*e->operation == NON_LVALUE_EXPR) if (*e->operation == NON_LVALUE_EXPR)
fprintf (f, " res = non_lvalue_loc (loc, res_op0);\n"); fprintf_indent (f, indent,
"res = non_lvalue_loc (loc, res_op0);\n");
else else
{ {
if (e->operation->kind == id_base::CODE) if (e->operation->kind == id_base::CODE)
fprintf (f, " res = fold_build%d_loc (loc, %s, type", fprintf_indent (f, indent,
e->ops.length (), "res = fold_build%d_loc (loc, %s, type",
*e->operation == CONVERT_EXPR e->ops.length (),
? "NOP_EXPR" : e->operation->id); *e->operation == CONVERT_EXPR
? "NOP_EXPR" : e->operation->id);
else else
fprintf (f, " res = build_call_expr_loc " fprintf_indent (f, indent,
"(loc, builtin_decl_implicit (%s), %d", "res = build_call_expr_loc "
e->operation->id, e->ops.length()); "(loc, builtin_decl_implicit (%s), %d",
e->operation->id, e->ops.length());
for (unsigned j = 0; j < e->ops.length (); ++j) for (unsigned j = 0; j < e->ops.length (); ++j)
fprintf (f, ", res_op%d", j); fprintf (f, ", res_op%d", j);
fprintf (f, ");\n"); fprintf (f, ");\n");
...@@ -2655,8 +2782,8 @@ dt_simplify::gen (FILE *f, bool gimple) ...@@ -2655,8 +2782,8 @@ dt_simplify::gen (FILE *f, bool gimple)
|| result->type == operand::OP_C_EXPR) || result->type == operand::OP_C_EXPR)
{ {
fprintf (f, " tree res;\n"); fprintf_indent (f, indent, "tree res;\n");
s->result->gen_transform (f, " res", false, 1, "type", s->result->gen_transform (f, indent, "res", false, 1, "type",
&cinfo, indexes); &cinfo, indexes);
} }
else else
...@@ -2670,19 +2797,28 @@ dt_simplify::gen (FILE *f, bool gimple) ...@@ -2670,19 +2797,28 @@ dt_simplify::gen (FILE *f, bool gimple)
if (!cinfo.info[i].force_no_side_effects_p if (!cinfo.info[i].force_no_side_effects_p
&& !cinfo.info[i].expr_p && !cinfo.info[i].expr_p
&& cinfo.info[i].result_use_count == 0) && cinfo.info[i].result_use_count == 0)
fprintf (f, " if (TREE_SIDE_EFFECTS (captures[%d]))\n" {
" res = build2_loc (loc, COMPOUND_EXPR, type," fprintf_indent (f, indent,
" fold_ignored_result (captures[%d]), res);\n", "if (TREE_SIDE_EFFECTS (captures[%d]))\n",
i, i); i);
fprintf_indent (f, indent + 2,
"res = build2_loc (loc, COMPOUND_EXPR, type, "
"fold_ignored_result (captures[%d]), res);\n",
i);
}
} }
fprintf (f, " return res;\n"); fprintf_indent (f, indent, "return res;\n");
} }
} }
for (unsigned i = 0; i < n_braces; ++i) for (unsigned i = 0; i < n_braces; ++i)
fprintf (f, "}\n"); {
fprintf_indent (f, indent - 2, "}\n");
indent -= 4;
}
fprintf (f, "}\n"); indent -= 2;
fprintf_indent (f, indent, "}\n");
} }
/* Main entry to generate code for matching GIMPLE IL off the decision /* Main entry to generate code for matching GIMPLE IL off the decision
...@@ -2702,8 +2838,8 @@ decision_tree::gen_gimple (FILE *f) ...@@ -2702,8 +2838,8 @@ decision_tree::gen_gimple (FILE *f)
fprintf (f, ")\n"); fprintf (f, ")\n");
fprintf (f, "{\n"); fprintf (f, "{\n");
fprintf (f, "switch (code.get_rep())\n" fprintf (f, " switch (code.get_rep())\n"
"{\n"); " {\n");
for (unsigned i = 0; i < root->kids.length (); i++) for (unsigned i = 0; i < root->kids.length (); i++)
{ {
dt_operand *dop = static_cast<dt_operand *>(root->kids[i]); dt_operand *dop = static_cast<dt_operand *>(root->kids[i]);
...@@ -2713,20 +2849,20 @@ decision_tree::gen_gimple (FILE *f) ...@@ -2713,20 +2849,20 @@ decision_tree::gen_gimple (FILE *f)
if (*e->operation == CONVERT_EXPR if (*e->operation == CONVERT_EXPR
|| *e->operation == NOP_EXPR) || *e->operation == NOP_EXPR)
fprintf (f, "CASE_CONVERT:\n"); fprintf (f, " CASE_CONVERT:\n");
else else
fprintf (f, "case %s%s:\n", fprintf (f, " case %s%s:\n",
is_a <fn_id *> (e->operation) ? "-" : "", is_a <fn_id *> (e->operation) ? "-" : "",
e->operation->id); e->operation->id);
fprintf (f, "{\n"); fprintf (f, " {\n");
dop->gen_kids (f, true); dop->gen_kids (f, 10, true);
fprintf (f, "break;\n"); fprintf (f, " break;\n");
fprintf (f, "}\n"); fprintf (f, " }\n");
} }
fprintf (f, "default:;\n" fprintf (f, " default:;\n"
"}\n"); " }\n");
fprintf (f, "return false;\n"); fprintf (f, " return false;\n");
fprintf (f, "}\n"); fprintf (f, "}\n");
} }
} }
...@@ -2747,8 +2883,8 @@ decision_tree::gen_generic (FILE *f) ...@@ -2747,8 +2883,8 @@ decision_tree::gen_generic (FILE *f)
fprintf (f, ")\n"); fprintf (f, ")\n");
fprintf (f, "{\n"); fprintf (f, "{\n");
fprintf (f, "switch (code)\n" fprintf (f, " switch (code)\n"
"{\n"); " {\n");
for (unsigned i = 0; i < root->kids.length (); i++) for (unsigned i = 0; i < root->kids.length (); i++)
{ {
dt_operand *dop = static_cast<dt_operand *>(root->kids[i]); dt_operand *dop = static_cast<dt_operand *>(root->kids[i]);
...@@ -2763,18 +2899,18 @@ decision_tree::gen_generic (FILE *f) ...@@ -2763,18 +2899,18 @@ decision_tree::gen_generic (FILE *f)
operator_id *op_id = static_cast <operator_id *> (e->operation); operator_id *op_id = static_cast <operator_id *> (e->operation);
if (op_id->code == NOP_EXPR || op_id->code == CONVERT_EXPR) if (op_id->code == NOP_EXPR || op_id->code == CONVERT_EXPR)
fprintf (f, "CASE_CONVERT:\n"); fprintf (f, " CASE_CONVERT:\n");
else else
fprintf (f, "case %s:\n", e->operation->id); fprintf (f, " case %s:\n", e->operation->id);
fprintf (f, "{\n"); fprintf (f, " {\n");
dop->gen_kids (f, false); dop->gen_kids (f, 10, false);
fprintf (f, "break;\n" fprintf (f, " break;\n"
"}\n"); " }\n");
} }
fprintf (f, "default:;\n" fprintf (f, " default:;\n"
"}\n"); " }\n");
fprintf (f, "return NULL_TREE;\n"); fprintf (f, " return NULL_TREE;\n");
fprintf (f, "}\n"); fprintf (f, "}\n");
} }
} }
...@@ -2790,13 +2926,13 @@ write_predicate (FILE *f, predicate_id *p, decision_tree &dt, bool gimple) ...@@ -2790,13 +2926,13 @@ write_predicate (FILE *f, predicate_id *p, decision_tree &dt, bool gimple)
p->nargs > 0 ? ", tree *res_ops" : "", p->nargs > 0 ? ", tree *res_ops" : "",
gimple ? ", tree (*valueize)(tree)" : ""); gimple ? ", tree (*valueize)(tree)" : "");
/* Conveniently make 'type' available. */ /* Conveniently make 'type' available. */
fprintf (f, "tree type = TREE_TYPE (t);\n"); fprintf_indent (f, 2, "tree type = TREE_TYPE (t);\n");
if (!gimple) if (!gimple)
fprintf (f, "if (TREE_SIDE_EFFECTS (t)) return false;\n"); fprintf_indent (f, 2, "if (TREE_SIDE_EFFECTS (t)) return false;\n");
dt.root->gen_kids (f, gimple); dt.root->gen_kids (f, 2, gimple);
fprintf (f, "return false;\n" fprintf_indent (f, 2, "return false;\n"
"}\n"); "}\n");
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment