Commit 53a19317 by Richard Biener Committed by Richard Biener

genmatch.c (verbose): New global.

2015-07-30  Richard Biener  <rguenther@suse.de>

	* genmatch.c (verbose): New global.
	(warning_at): Add overload with source_location.
	(capture_info::capture_info): Add bool whether generating gimple
	or generic.  Add gimple member.
	(capture_info::cinfo): Add capture member.
	(capture_info::walk_match): Record capture.  Warn on
	non-captured leafs.
	(capture_info::walk_c_expr): Add more fragments captures cannot
	escape through.  Warn on escaped captures.
	(dt_simplify::gen_1): Warn on operands we force to have no
	side-effects.
	(main): Initialize verbose.
	* match.pd: Add integer_nonzerop and HONOR_NANS predicates.

From-SVN: r226386
parent f501d5cd
2015-07-30 Richard Biener <rguenther@suse.de> 2015-07-30 Richard Biener <rguenther@suse.de>
* genmatch.c (verbose): New global.
(warning_at): Add overload with source_location.
(capture_info::capture_info): Add bool whether generating gimple
or generic. Add gimple member.
(capture_info::cinfo): Add capture member.
(capture_info::walk_match): Record capture. Warn on
non-captured leafs.
(capture_info::walk_c_expr): Add more fragments captures cannot
escape through. Warn on escaped captures.
(dt_simplify::gen_1): Warn on operands we force to have no
side-effects.
(main): Initialize verbose.
* match.pd: Add integer_nonzerop and HONOR_NANS predicates.
2015-07-30 Richard Biener <rguenther@suse.de>
PR middle-end/67053 PR middle-end/67053
* match.pd: Allow both operands to independently have conversion * match.pd: Allow both operands to independently have conversion
when simplifying compares of addresses. when simplifying compares of addresses.
......
...@@ -43,6 +43,12 @@ void ggc_free (void *) ...@@ -43,6 +43,12 @@ void ggc_free (void *)
} }
/* Global state. */
/* Verboseness. 0 is quiet, 1 adds some warnings, 2 is for debugging. */
unsigned verbose;
/* libccp helpers. */ /* libccp helpers. */
static struct line_maps *line_table; static struct line_maps *line_table;
...@@ -126,6 +132,18 @@ warning_at (const cpp_token *tk, const char *msg, ...) ...@@ -126,6 +132,18 @@ warning_at (const cpp_token *tk, const char *msg, ...)
va_end (ap); va_end (ap);
} }
static void
#if GCC_VERSION >= 4001
__attribute__((format (printf, 2, 3)))
#endif
warning_at (source_location loc, const char *msg, ...)
{
va_list ap;
va_start (ap, msg);
error_cb (NULL, CPP_DL_WARNING, 0, loc, 0, msg, &ap);
va_end (ap);
}
/* Like fprintf, but print INDENT spaces at the beginning. */ /* Like fprintf, but print INDENT spaces at the beginning. */
static void static void
...@@ -1599,7 +1617,7 @@ decision_tree::print (FILE *f) ...@@ -1599,7 +1617,7 @@ decision_tree::print (FILE *f)
struct capture_info struct capture_info
{ {
capture_info (simplify *s, operand *); capture_info (simplify *s, operand *, bool);
void walk_match (operand *o, unsigned toplevel_arg, bool, bool); void walk_match (operand *o, unsigned toplevel_arg, bool, bool);
bool walk_result (operand *o, bool, operand *); bool walk_result (operand *o, bool, operand *);
void walk_c_expr (c_expr *); void walk_c_expr (c_expr *);
...@@ -1614,16 +1632,20 @@ struct capture_info ...@@ -1614,16 +1632,20 @@ struct capture_info
unsigned long toplevel_msk; unsigned long toplevel_msk;
int result_use_count; int result_use_count;
unsigned same_as; unsigned same_as;
capture *c;
}; };
auto_vec<cinfo> info; auto_vec<cinfo> info;
unsigned long force_no_side_effects; unsigned long force_no_side_effects;
bool gimple;
}; };
/* Analyze captures in S. */ /* Analyze captures in S. */
capture_info::capture_info (simplify *s, operand *result) capture_info::capture_info (simplify *s, operand *result, bool gimple_)
{ {
gimple = gimple_;
expr *e; expr *e;
if (s->kind == simplify::MATCH) if (s->kind == simplify::MATCH)
{ {
...@@ -1661,6 +1683,8 @@ capture_info::walk_match (operand *o, unsigned toplevel_arg, ...@@ -1661,6 +1683,8 @@ capture_info::walk_match (operand *o, unsigned toplevel_arg,
info[where].toplevel_msk |= 1 << toplevel_arg; info[where].toplevel_msk |= 1 << toplevel_arg;
info[where].force_no_side_effects_p |= conditional_p; info[where].force_no_side_effects_p |= conditional_p;
info[where].cond_expr_cond_p |= cond_expr_cond_p; info[where].cond_expr_cond_p |= cond_expr_cond_p;
if (!info[where].c)
info[where].c = c;
if (!c->what) if (!c->what)
return; return;
/* Recurse to exprs and captures. */ /* Recurse to exprs and captures. */
...@@ -1710,6 +1734,10 @@ capture_info::walk_match (operand *o, unsigned toplevel_arg, ...@@ -1710,6 +1734,10 @@ capture_info::walk_match (operand *o, unsigned toplevel_arg,
{ {
/* Mark non-captured leafs toplevel arg for checking. */ /* Mark non-captured leafs toplevel arg for checking. */
force_no_side_effects |= 1 << toplevel_arg; force_no_side_effects |= 1 << toplevel_arg;
if (verbose >= 1
&& !gimple)
warning_at (o->location,
"forcing no side-effects on possibly lost leaf");
} }
else else
gcc_unreachable (); gcc_unreachable ();
...@@ -1801,15 +1829,25 @@ capture_info::walk_result (operand *o, bool conditional_p, operand *result) ...@@ -1801,15 +1829,25 @@ capture_info::walk_result (operand *o, bool conditional_p, operand *result)
void void
capture_info::walk_c_expr (c_expr *e) capture_info::walk_c_expr (c_expr *e)
{ {
/* Give up for C exprs mentioning captures not inside TREE_TYPE (). */ /* Give up for C exprs mentioning captures not inside TREE_TYPE,
TREE_REAL_CST, TREE_CODE or a predicate where they cannot
really escape through. */
unsigned p_depth = 0; unsigned p_depth = 0;
for (unsigned i = 0; i < e->code.length (); ++i) for (unsigned i = 0; i < e->code.length (); ++i)
{ {
const cpp_token *t = &e->code[i]; const cpp_token *t = &e->code[i];
const cpp_token *n = i < e->code.length () - 1 ? &e->code[i+1] : NULL; const cpp_token *n = i < e->code.length () - 1 ? &e->code[i+1] : NULL;
id_base *id;
if (t->type == CPP_NAME if (t->type == CPP_NAME
&& strcmp ((const char *)CPP_HASHNODE && (strcmp ((const char *)CPP_HASHNODE
(t->val.node.node)->ident.str, "TREE_TYPE") == 0 (t->val.node.node)->ident.str, "TREE_TYPE") == 0
|| strcmp ((const char *)CPP_HASHNODE
(t->val.node.node)->ident.str, "TREE_CODE") == 0
|| strcmp ((const char *)CPP_HASHNODE
(t->val.node.node)->ident.str, "TREE_REAL_CST") == 0
|| ((id = get_operator ((const char *)CPP_HASHNODE
(t->val.node.node)->ident.str))
&& is_a <predicate_id *> (id)))
&& n->type == CPP_OPEN_PAREN) && n->type == CPP_OPEN_PAREN)
p_depth++; p_depth++;
else if (t->type == CPP_CLOSE_PAREN else if (t->type == CPP_CLOSE_PAREN
...@@ -1828,6 +1866,9 @@ capture_info::walk_c_expr (c_expr *e) ...@@ -1828,6 +1866,9 @@ capture_info::walk_c_expr (c_expr *e)
id = (const char *)CPP_HASHNODE (n->val.node.node)->ident.str; id = (const char *)CPP_HASHNODE (n->val.node.node)->ident.str;
unsigned where = *e->capture_ids->get(id); unsigned where = *e->capture_ids->get(id);
info[info[where].same_as].force_no_side_effects_p = true; info[info[where].same_as].force_no_side_effects_p = true;
if (verbose >= 1
&& !gimple)
warning_at (t, "capture escapes");
} }
} }
} }
...@@ -2662,25 +2703,37 @@ dt_simplify::gen_1 (FILE *f, int indent, bool gimple, operand *result) ...@@ -2662,25 +2703,37 @@ dt_simplify::gen_1 (FILE *f, int indent, bool gimple, operand *result)
/* Analyze captures and perform early-outs on the incoming arguments /* Analyze captures and perform early-outs on the incoming arguments
that cover cases we cannot handle. */ that cover cases we cannot handle. */
capture_info cinfo (s, result); capture_info cinfo (s, result, gimple);
if (s->kind == simplify::SIMPLIFY) if (s->kind == simplify::SIMPLIFY)
{ {
if (!gimple) if (!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_indent (f, indent, {
"if (TREE_SIDE_EFFECTS (op%d)) return NULL_TREE;\n", fprintf_indent (f, indent,
i); "if (TREE_SIDE_EFFECTS (op%d)) return NULL_TREE;\n",
i);
if (verbose >= 1)
warning_at (as_a <expr *> (s->match)->ops[i]->location,
"forcing toplevel operand to have no "
"side-effects");
}
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_indent (f, indent, {
"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);
if (verbose >= 1)
warning_at (cinfo.info[i].c->location,
"forcing captured operand to have no "
"side-effects");
}
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
...@@ -4165,7 +4218,6 @@ main (int argc, char **argv) ...@@ -4165,7 +4218,6 @@ main (int argc, char **argv)
return 1; return 1;
bool gimple = true; bool gimple = true;
bool verbose = false;
char *input = argv[argc-1]; char *input = argv[argc-1];
for (int i = 1; i < argc - 1; ++i) for (int i = 1; i < argc - 1; ++i)
{ {
...@@ -4174,11 +4226,13 @@ main (int argc, char **argv) ...@@ -4174,11 +4226,13 @@ main (int argc, char **argv)
else if (strcmp (argv[i], "--generic") == 0) else if (strcmp (argv[i], "--generic") == 0)
gimple = false; gimple = false;
else if (strcmp (argv[i], "-v") == 0) else if (strcmp (argv[i], "-v") == 0)
verbose = true; verbose = 1;
else if (strcmp (argv[i], "-vv") == 0)
verbose = 2;
else else
{ {
fprintf (stderr, "Usage: genmatch " fprintf (stderr, "Usage: genmatch "
"[--gimple] [--generic] [-v] input\n"); "[--gimple] [--generic] [-v[v]] input\n");
return 1; return 1;
} }
} }
...@@ -4235,7 +4289,7 @@ add_operator (VIEW_CONVERT2, "VIEW_CONVERT2", "tcc_unary", 1); ...@@ -4235,7 +4289,7 @@ add_operator (VIEW_CONVERT2, "VIEW_CONVERT2", "tcc_unary", 1);
predicate_id *pred = p.user_predicates[i]; predicate_id *pred = p.user_predicates[i];
lower (pred->matchers, gimple); lower (pred->matchers, gimple);
if (verbose) if (verbose == 2)
for (unsigned i = 0; i < pred->matchers.length (); ++i) for (unsigned i = 0; i < pred->matchers.length (); ++i)
print_matches (pred->matchers[i]); print_matches (pred->matchers[i]);
...@@ -4243,7 +4297,7 @@ add_operator (VIEW_CONVERT2, "VIEW_CONVERT2", "tcc_unary", 1); ...@@ -4243,7 +4297,7 @@ add_operator (VIEW_CONVERT2, "VIEW_CONVERT2", "tcc_unary", 1);
for (unsigned i = 0; i < pred->matchers.length (); ++i) for (unsigned i = 0; i < pred->matchers.length (); ++i)
dt.insert (pred->matchers[i], i); dt.insert (pred->matchers[i], i);
if (verbose) if (verbose == 2)
dt.print (stderr); dt.print (stderr);
write_predicate (stdout, pred, dt, gimple); write_predicate (stdout, pred, dt, gimple);
...@@ -4252,7 +4306,7 @@ add_operator (VIEW_CONVERT2, "VIEW_CONVERT2", "tcc_unary", 1); ...@@ -4252,7 +4306,7 @@ add_operator (VIEW_CONVERT2, "VIEW_CONVERT2", "tcc_unary", 1);
/* Lower the main simplifiers and generate code for them. */ /* Lower the main simplifiers and generate code for them. */
lower (p.simplifiers, gimple); lower (p.simplifiers, gimple);
if (verbose) if (verbose == 2)
for (unsigned i = 0; i < p.simplifiers.length (); ++i) for (unsigned i = 0; i < p.simplifiers.length (); ++i)
print_matches (p.simplifiers[i]); print_matches (p.simplifiers[i]);
...@@ -4260,7 +4314,7 @@ add_operator (VIEW_CONVERT2, "VIEW_CONVERT2", "tcc_unary", 1); ...@@ -4260,7 +4314,7 @@ add_operator (VIEW_CONVERT2, "VIEW_CONVERT2", "tcc_unary", 1);
for (unsigned i = 0; i < p.simplifiers.length (); ++i) for (unsigned i = 0; i < p.simplifiers.length (); ++i)
dt.insert (p.simplifiers[i], i); dt.insert (p.simplifiers[i], i);
if (verbose) if (verbose == 2)
dt.print (stderr); dt.print (stderr);
if (gimple) if (gimple)
......
...@@ -26,11 +26,12 @@ along with GCC; see the file COPYING3. If not see ...@@ -26,11 +26,12 @@ along with GCC; see the file COPYING3. If not see
/* Generic tree predicates we inherit. */ /* Generic tree predicates we inherit. */
(define_predicates (define_predicates
integer_onep integer_zerop integer_all_onesp integer_minus_onep integer_onep integer_zerop integer_all_onesp integer_minus_onep
integer_each_onep integer_truep integer_each_onep integer_truep integer_nonzerop
real_zerop real_onep real_minus_onep real_zerop real_onep real_minus_onep
CONSTANT_CLASS_P CONSTANT_CLASS_P
tree_expr_nonnegative_p tree_expr_nonnegative_p
integer_pow2p) integer_pow2p
HONOR_NANS)
/* Operator lists. */ /* Operator lists. */
(define_operator_list tcc_comparison (define_operator_list tcc_comparison
......
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