Commit 28fabd43 by Richard Biener Committed by Richard Biener

genmatch.c (enum tree_code): Remove CONVERT{0,1,2} and VIEW_CONVERT{0,1,2}.

2019-12-06  Richard Biener  <rguenther@suse.de>

	* genmatch.c (enum tree_code): Remove CONVERT{0,1,2} and
	VIEW_CONVERT{0,1,2}.
	(expr::opt_grp): Add and initialize.
	(lower_opt_convert): Rename to ...
	(lower_opt): ... and work on opt_grp, simply switching operations
	from being optional to being present or not.
	(has_opt_convert): Rename to ...
	(has_opt): ... and adjust.
	(parser::parse_operation): Return the optional opt_grp,
	remove special-casing of conditional operations and more generally
	parse [digit]'?'.
	(parser::parse_expr): Stick on the parsed opt_grp and perform
	rough verification.
	(parser::parse_for): Remove now unnecessary code.
	(main): Likewise.
	* doc/match-and-simplify.texi: Mention ? now works on all
	unary operations and also match predicates.

From-SVN: r279037
parent f7f6be76
2019-12-06 Richard Biener <rguenther@suse.de>
* genmatch.c (enum tree_code): Remove CONVERT{0,1,2} and
VIEW_CONVERT{0,1,2}.
(expr::opt_grp): Add and initialize.
(lower_opt_convert): Rename to ...
(lower_opt): ... and work on opt_grp, simply switching operations
from being optional to being present or not.
(has_opt_convert): Rename to ...
(has_opt): ... and adjust.
(parser::parse_operation): Return the optional opt_grp,
remove special-casing of conditional operations and more generally
parse [digit]'?'.
(parser::parse_expr): Stick on the parsed opt_grp and perform
rough verification.
(parser::parse_for): Remove now unnecessary code.
(main): Likewise.
* doc/match-and-simplify.texi: Mention ? now works on all
unary operations and also match predicates.
2019-12-06 Jan Hubicka <hubicka@ucw.cz> 2019-12-06 Jan Hubicka <hubicka@ucw.cz>
* cgraphclones.c (cgraph_node::create_clone): Only localize toplevel * cgraphclones.c (cgraph_node::create_clone): Only localize toplevel
...@@ -380,6 +380,9 @@ patterns only. If you want to match all four combinations you ...@@ -380,6 +380,9 @@ patterns only. If you want to match all four combinations you
have access to two additional conditional converts as in have access to two additional conditional converts as in
@code{(eq (convert1@? @@1) (convert2@? @@2))}. @code{(eq (convert1@? @@1) (convert2@? @@2))}.
The support for @code{?} marking extends to all unary operations
including predicates you declare yourself with @code{match}.
Predicates available from the GCC middle-end need to be made Predicates available from the GCC middle-end need to be made
available explicitely via @code{define_predicates}: available explicitely via @code{define_predicates}:
......
...@@ -224,12 +224,6 @@ output_line_directive (FILE *f, location_t location, ...@@ -224,12 +224,6 @@ output_line_directive (FILE *f, location_t location,
#define DEFTREECODE(SYM, STRING, TYPE, NARGS) SYM, #define DEFTREECODE(SYM, STRING, TYPE, NARGS) SYM,
enum tree_code { enum tree_code {
#include "tree.def" #include "tree.def"
CONVERT0,
CONVERT1,
CONVERT2,
VIEW_CONVERT0,
VIEW_CONVERT1,
VIEW_CONVERT2,
MAX_TREE_CODES MAX_TREE_CODES
}; };
#undef DEFTREECODE #undef DEFTREECODE
...@@ -703,11 +697,12 @@ public: ...@@ -703,11 +697,12 @@ public:
expr (id_base *operation_, location_t loc, bool is_commutative_ = false) expr (id_base *operation_, location_t loc, bool is_commutative_ = false)
: operand (OP_EXPR, loc), operation (operation_), : operand (OP_EXPR, loc), operation (operation_),
ops (vNULL), expr_type (NULL), is_commutative (is_commutative_), ops (vNULL), expr_type (NULL), is_commutative (is_commutative_),
is_generic (false), force_single_use (false) {} is_generic (false), force_single_use (false), opt_grp (0) {}
expr (expr *e) expr (expr *e)
: operand (OP_EXPR, e->location), operation (e->operation), : operand (OP_EXPR, e->location), operation (e->operation),
ops (vNULL), expr_type (e->expr_type), is_commutative (e->is_commutative), ops (vNULL), expr_type (e->expr_type), is_commutative (e->is_commutative),
is_generic (e->is_generic), force_single_use (e->force_single_use) {} is_generic (e->is_generic), force_single_use (e->force_single_use),
opt_grp (e->opt_grp) {}
void append_op (operand *op) { ops.safe_push (op); } void append_op (operand *op) { ops.safe_push (op); }
/* The operator and its operands. */ /* The operator and its operands. */
id_base *operation; id_base *operation;
...@@ -722,6 +717,8 @@ public: ...@@ -722,6 +717,8 @@ public:
/* 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;
/* If non-zero, the group for optional handling. */
unsigned char opt_grp;
virtual void gen_transform (FILE *f, int, 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, int = 0); dt_operand ** = 0, int = 0);
...@@ -1093,18 +1090,17 @@ lower_commutative (simplify *s, vec<simplify *>& simplifiers) ...@@ -1093,18 +1090,17 @@ lower_commutative (simplify *s, vec<simplify *>& simplifiers)
} }
} }
/* Strip conditional conversios using operator OPER from O and its /* Strip conditional operations using group GRP from O and its
children if STRIP, else replace them with an unconditional convert. */ children if STRIP, else replace them with an unconditional operation. */
operand * operand *
lower_opt_convert (operand *o, enum tree_code oper, lower_opt (operand *o, unsigned char grp, bool strip)
enum tree_code to_oper, bool strip)
{ {
if (capture *c = dyn_cast<capture *> (o)) if (capture *c = dyn_cast<capture *> (o))
{ {
if (c->what) if (c->what)
return new capture (c->location, c->where, return new capture (c->location, c->where,
lower_opt_convert (c->what, oper, to_oper, strip), lower_opt (c->what, grp, strip),
c->value_match); c->value_match);
else else
return c; return c;
...@@ -1114,36 +1110,34 @@ lower_opt_convert (operand *o, enum tree_code oper, ...@@ -1114,36 +1110,34 @@ lower_opt_convert (operand *o, enum tree_code oper,
if (!e) if (!e)
return o; return o;
if (*e->operation == oper) if (e->opt_grp == grp)
{ {
if (strip) if (strip)
return lower_opt_convert (e->ops[0], oper, to_oper, strip); return lower_opt (e->ops[0], grp, strip);
expr *ne = new expr (e); expr *ne = new expr (e);
ne->operation = (to_oper == CONVERT_EXPR ne->opt_grp = 0;
? get_operator ("CONVERT_EXPR") ne->append_op (lower_opt (e->ops[0], grp, strip));
: get_operator ("VIEW_CONVERT_EXPR"));
ne->append_op (lower_opt_convert (e->ops[0], oper, to_oper, strip));
return ne; return ne;
} }
expr *ne = new expr (e); expr *ne = new expr (e);
for (unsigned i = 0; i < e->ops.length (); ++i) for (unsigned i = 0; i < e->ops.length (); ++i)
ne->append_op (lower_opt_convert (e->ops[i], oper, to_oper, strip)); ne->append_op (lower_opt (e->ops[i], grp, strip));
return ne; return ne;
} }
/* Determine whether O or its children uses the conditional conversion /* Determine whether O or its children uses the conditional operation
operator OPER. */ group GRP. */
static bool static bool
has_opt_convert (operand *o, enum tree_code oper) has_opt (operand *o, unsigned char grp)
{ {
if (capture *c = dyn_cast<capture *> (o)) if (capture *c = dyn_cast<capture *> (o))
{ {
if (c->what) if (c->what)
return has_opt_convert (c->what, oper); return has_opt (c->what, grp);
else else
return false; return false;
} }
...@@ -1152,11 +1146,11 @@ has_opt_convert (operand *o, enum tree_code oper) ...@@ -1152,11 +1146,11 @@ has_opt_convert (operand *o, enum tree_code oper)
if (!e) if (!e)
return false; return false;
if (*e->operation == oper) if (e->opt_grp == grp)
return true; return true;
for (unsigned i = 0; i < e->ops.length (); ++i) for (unsigned i = 0; i < e->ops.length (); ++i)
if (has_opt_convert (e->ops[i], oper)) if (has_opt (e->ops[i], grp))
return true; return true;
return false; return false;
...@@ -1166,34 +1160,24 @@ has_opt_convert (operand *o, enum tree_code oper) ...@@ -1166,34 +1160,24 @@ has_opt_convert (operand *o, enum tree_code oper)
if required. */ if required. */
static vec<operand *> static vec<operand *>
lower_opt_convert (operand *o) lower_opt (operand *o)
{ {
vec<operand *> v1 = vNULL, v2; vec<operand *> v1 = vNULL, v2;
v1.safe_push (o); v1.safe_push (o);
enum tree_code opers[] /* Conditional operations are lowered to a pattern with the
= { CONVERT0, CONVERT_EXPR, operation and one without. All different conditional operation
CONVERT1, CONVERT_EXPR, groups are lowered separately. */
CONVERT2, CONVERT_EXPR,
VIEW_CONVERT0, VIEW_CONVERT_EXPR,
VIEW_CONVERT1, VIEW_CONVERT_EXPR,
VIEW_CONVERT2, VIEW_CONVERT_EXPR };
/* Conditional converts are lowered to a pattern with the for (unsigned i = 1; i <= 10; ++i)
conversion and one without. The three different conditional
convert codes are lowered separately. */
for (unsigned i = 0; i < sizeof (opers) / sizeof (enum tree_code); i += 2)
{ {
v2 = vNULL; v2 = vNULL;
for (unsigned j = 0; j < v1.length (); ++j) for (unsigned j = 0; j < v1.length (); ++j)
if (has_opt_convert (v1[j], opers[i])) if (has_opt (v1[j], i))
{ {
v2.safe_push (lower_opt_convert (v1[j], v2.safe_push (lower_opt (v1[j], i, false));
opers[i], opers[i+1], false)); v2.safe_push (lower_opt (v1[j], i, true));
v2.safe_push (lower_opt_convert (v1[j],
opers[i], opers[i+1], true));
} }
if (v2 != vNULL) if (v2 != vNULL)
...@@ -1211,9 +1195,9 @@ lower_opt_convert (operand *o) ...@@ -1211,9 +1195,9 @@ lower_opt_convert (operand *o)
the resulting multiple patterns to SIMPLIFIERS. */ the resulting multiple patterns to SIMPLIFIERS. */
static void static void
lower_opt_convert (simplify *s, vec<simplify *>& simplifiers) lower_opt (simplify *s, vec<simplify *>& simplifiers)
{ {
vec<operand *> matchers = lower_opt_convert (s->match); vec<operand *> matchers = lower_opt (s->match);
for (unsigned i = 0; i < matchers.length (); ++i) for (unsigned i = 0; i < matchers.length (); ++i)
{ {
simplify *ns = new simplify (s->kind, s->id, matchers[i], s->result, simplify *ns = new simplify (s->kind, s->id, matchers[i], s->result,
...@@ -1557,7 +1541,7 @@ lower (vec<simplify *>& simplifiers, bool gimple) ...@@ -1557,7 +1541,7 @@ lower (vec<simplify *>& simplifiers, bool gimple)
{ {
auto_vec<simplify *> out_simplifiers; auto_vec<simplify *> out_simplifiers;
for (unsigned i = 0; i < simplifiers.length (); ++i) for (unsigned i = 0; i < simplifiers.length (); ++i)
lower_opt_convert (simplifiers[i], out_simplifiers); lower_opt (simplifiers[i], out_simplifiers);
simplifiers.truncate (0); simplifiers.truncate (0);
for (unsigned i = 0; i < out_simplifiers.length (); ++i) for (unsigned i = 0; i < out_simplifiers.length (); ++i)
...@@ -3966,7 +3950,7 @@ private: ...@@ -3966,7 +3950,7 @@ private:
unsigned get_internal_capture_id (); unsigned get_internal_capture_id ();
id_base *parse_operation (); id_base *parse_operation (unsigned char &);
operand *parse_capture (operand *, bool); operand *parse_capture (operand *, bool);
operand *parse_expr (); operand *parse_expr ();
c_expr *parse_c_expr (cpp_ttype); c_expr *parse_c_expr (cpp_ttype);
...@@ -4157,47 +4141,36 @@ parser::record_operlist (location_t loc, user_id *p) ...@@ -4157,47 +4141,36 @@ parser::record_operlist (location_t loc, user_id *p)
convert2? */ convert2? */
id_base * id_base *
parser::parse_operation () parser::parse_operation (unsigned char &opt_grp)
{ {
const cpp_token *id_tok = peek (); const cpp_token *id_tok = peek ();
char *alt_id = NULL;
const char *id = get_ident (); const char *id = get_ident ();
const cpp_token *token = peek (); const cpp_token *token = peek ();
if (strcmp (id, "convert0") == 0) opt_grp = 0;
fatal_at (id_tok, "use 'convert?' here");
else if (strcmp (id, "view_convert0") == 0)
fatal_at (id_tok, "use 'view_convert?' here");
if (token->type == CPP_QUERY if (token->type == CPP_QUERY
&& !(token->flags & PREV_WHITE)) && !(token->flags & PREV_WHITE))
{ {
if (strcmp (id, "convert") == 0)
id = "convert0";
else if (strcmp (id, "convert1") == 0)
;
else if (strcmp (id, "convert2") == 0)
;
else if (strcmp (id, "view_convert") == 0)
id = "view_convert0";
else if (strcmp (id, "view_convert1") == 0)
;
else if (strcmp (id, "view_convert2") == 0)
;
else
fatal_at (id_tok, "non-convert operator conditionalized");
if (!parsing_match_operand) if (!parsing_match_operand)
fatal_at (id_tok, "conditional convert can only be used in " fatal_at (id_tok, "conditional convert can only be used in "
"match expression"); "match expression");
if (ISDIGIT (id[strlen (id) - 1]))
{
opt_grp = id[strlen (id) - 1] - '0' + 1;
alt_id = xstrdup (id);
alt_id[strlen (id) - 1] = '\0';
if (opt_grp == 1)
fatal_at (id_tok, "use '%s?' here", alt_id);
}
else
opt_grp = 1;
eat_token (CPP_QUERY); eat_token (CPP_QUERY);
} }
else if (strcmp (id, "convert1") == 0 id_base *op = get_operator (alt_id ? alt_id : id);
|| strcmp (id, "convert2") == 0
|| strcmp (id, "view_convert1") == 0
|| strcmp (id, "view_convert2") == 0)
fatal_at (id_tok, "expected '?' after conditional operator");
id_base *op = get_operator (id);
if (!op) if (!op)
fatal_at (id_tok, "unknown operator %s", id); fatal_at (id_tok, "unknown operator %s", alt_id ? alt_id : id);
if (alt_id)
free (alt_id);
user_id *p = dyn_cast<user_id *> (op); user_id *p = dyn_cast<user_id *> (op);
if (p && p->is_oper_list) if (p && p->is_oper_list)
{ {
...@@ -4253,7 +4226,8 @@ class operand * ...@@ -4253,7 +4226,8 @@ class operand *
parser::parse_expr () parser::parse_expr ()
{ {
const cpp_token *token = peek (); const cpp_token *token = peek ();
expr *e = new expr (parse_operation (), token->src_loc); unsigned char opt_grp;
expr *e = new expr (parse_operation (opt_grp), token->src_loc);
token = peek (); token = peek ();
operand *op; operand *op;
bool is_commutative = false; bool is_commutative = false;
...@@ -4349,6 +4323,12 @@ parser::parse_expr () ...@@ -4349,6 +4323,12 @@ parser::parse_expr ()
"commutative"); "commutative");
} }
e->expr_type = expr_type; e->expr_type = expr_type;
if (opt_grp != 0)
{
if (e->ops.length () != 1)
fatal_at (token, "only unary operations can be conditional");
e->opt_grp = opt_grp;
}
return op; return op;
} }
else if (!(token->flags & PREV_WHITE)) else if (!(token->flags & PREV_WHITE))
...@@ -4731,10 +4711,6 @@ parser::parse_for (location_t) ...@@ -4731,10 +4711,6 @@ parser::parse_for (location_t)
id_base *idb = get_operator (oper, true); id_base *idb = get_operator (oper, true);
if (idb == NULL) if (idb == NULL)
fatal_at (token, "no such operator '%s'", oper); fatal_at (token, "no such operator '%s'", oper);
if (*idb == CONVERT0 || *idb == CONVERT1 || *idb == CONVERT2
|| *idb == VIEW_CONVERT0 || *idb == VIEW_CONVERT1
|| *idb == VIEW_CONVERT2)
fatal_at (token, "conditional operators cannot be used inside for");
if (arity == -1) if (arity == -1)
arity = idb->nargs; arity = idb->nargs;
...@@ -5141,12 +5117,6 @@ main (int argc, char **argv) ...@@ -5141,12 +5117,6 @@ main (int argc, char **argv)
add_operator (SYM, # SYM, # TYPE, NARGS); add_operator (SYM, # SYM, # TYPE, NARGS);
#define END_OF_BASE_TREE_CODES #define END_OF_BASE_TREE_CODES
#include "tree.def" #include "tree.def"
add_operator (CONVERT0, "convert0", "tcc_unary", 1);
add_operator (CONVERT1, "convert1", "tcc_unary", 1);
add_operator (CONVERT2, "convert2", "tcc_unary", 1);
add_operator (VIEW_CONVERT0, "view_convert0", "tcc_unary", 1);
add_operator (VIEW_CONVERT1, "view_convert1", "tcc_unary", 1);
add_operator (VIEW_CONVERT2, "view_convert2", "tcc_unary", 1);
#undef END_OF_BASE_TREE_CODES #undef END_OF_BASE_TREE_CODES
#undef DEFTREECODE #undef DEFTREECODE
......
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