This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][match-and-simplify][1/2] Delay for lowering
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 23 Sep 2014 15:41:00 +0200 (CEST)
- Subject: [PATCH][match-and-simplify][1/2] Delay for lowering
- Authentication-results: sourceware.org; auth=none
This is a first cleanup step towards lowering for late, not during
parsing.
This intermediate step removes the e_operation indirection and
makes parse_for temporarily insert operators it defines so we
can avoid lazily accepting anything as user-defined and thus
report proper error locations.
Bootstrap scheduled (gimple-match.c/generic-match.c is
unchanged - always a good test)
Richard.
2014-09-23 Richard Biener <rguenther@suse.de>
* genmatch.c (struct e_operation): Remove.
(struct expr): Replace e_operation operation with id_base. Add
is_commutative member.
(<everywhere>): Remove indirections through e_operation, move
is_commutative handling to expr objects.
(parse_for): Temporarily insert user-defined operators into the
operator identifier hash.
Index: match-and-simplify/gcc/genmatch.c
===================================================================
*** match-and-simplify.orig/gcc/genmatch.c 2014-09-23 15:08:06.634446450 +0200
--- match-and-simplify/gcc/genmatch.c 2014-09-23 15:34:48.805336143 +0200
*************** struct predicate : public operand
*** 292,313 ****
{ gcc_unreachable (); }
};
- struct e_operation {
- e_operation (const char *id, bool is_commutative_ = false, bool add_new_id = true);
- id_base *op;
- bool is_commutative;
- };
-
struct expr : public operand
{
! expr (e_operation *operation_)
: operand (OP_EXPR), operation (operation_),
! ops (vNULL), expr_type (NULL) {}
void append_op (operand *op) { ops.safe_push (op); }
! e_operation *operation;
vec<operand *> ops;
const char *expr_type;
virtual void gen_transform (FILE *f, const char *, bool, int, const char *, dt_operand ** = 0);
};
--- 292,308 ----
{ gcc_unreachable (); }
};
struct expr : public operand
{
! expr (id_base *operation_, bool is_commutative_ = false)
: operand (OP_EXPR), operation (operation_),
! ops (vNULL), expr_type (NULL), is_commutative (is_commutative_) {}
void append_op (operand *op) { ops.safe_push (op); }
! id_base *operation;
vec<operand *> ops;
const char *expr_type;
+ bool is_commutative;
virtual void gen_transform (FILE *f, const char *, bool, int, const char *, dt_operand ** = 0);
};
*************** get_operator (const char *id)
*** 411,430 ****
return 0;
}
- e_operation::e_operation (const char *id, bool is_commutative_, bool add_new_id)
- {
- is_commutative = is_commutative_;
- op = get_operator (id);
- if (op)
- return;
-
- if (add_new_id == false)
- fatal ("%s is not an operator/built-in function", id);
-
- op = new id_base (id_base::USER_DEFINED, id);
- operators->find_slot_with_hash (op, op->hashval, INSERT);
- }
-
struct if_or_with {
if_or_with (operand *cexpr_, source_location location_, bool is_with_)
: location (location_), cexpr (cexpr_), is_with (is_with_) {}
--- 406,411 ----
*************** print_operand (operand *o, FILE *f = std
*** 559,565 ****
else if (expr *e = dyn_cast<expr *> (o))
{
! fprintf (f, "(%s", e->operation->op->id);
if (flattened == false)
{
--- 540,546 ----
else if (expr *e = dyn_cast<expr *> (o))
{
! fprintf (f, "(%s", e->operation->id);
if (flattened == false)
{
*************** commutate (operand *op)
*** 660,666 ****
ret.safe_push (ne);
}
! if (!e->operation->is_commutative)
return ret;
for (unsigned i = 0; i < result.length (); ++i)
--- 641,647 ----
ret.safe_push (ne);
}
! if (!e->is_commutative)
return ret;
for (unsigned i = 0; i < result.length (); ++i)
*************** lower_opt_convert (operand *o, enum tree
*** 702,715 ****
return o;
expr *e = as_a<expr *> (o);
! if (*e->operation->op == oper)
{
! expr *ne = new expr (new e_operation ("CONVERT_EXPR"));
ne->append_op (lower_opt_convert (e->ops[0], oper));
return ne;
}
! expr *ne = new expr (e->operation);
for (unsigned i = 0; i < e->ops.length (); ++i)
ne->append_op (lower_opt_convert (e->ops[i], oper));
--- 683,696 ----
return o;
expr *e = as_a<expr *> (o);
! if (*e->operation == oper)
{
! expr *ne = new expr (get_operator ("CONVERT_EXPR"));
ne->append_op (lower_opt_convert (e->ops[0], oper));
return ne;
}
! expr *ne = new expr (e->operation, e->is_commutative);
for (unsigned i = 0; i < e->ops.length (); ++i)
ne->append_op (lower_opt_convert (e->ops[i], oper));
*************** remove_opt_convert (operand *o, enum tre
*** 731,740 ****
return o;
expr *e = as_a<expr *> (o);
! if (*e->operation->op == oper)
return remove_opt_convert (e->ops[0], oper);
! expr *ne = new expr (e->operation);
for (unsigned i = 0; i < e->ops.length (); ++i)
ne->append_op (remove_opt_convert (e->ops[i], oper));
--- 712,721 ----
return o;
expr *e = as_a<expr *> (o);
! if (*e->operation == oper)
return remove_opt_convert (e->ops[0], oper);
! expr *ne = new expr (e->operation, e->is_commutative);
for (unsigned i = 0; i < e->ops.length (); ++i)
ne->append_op (remove_opt_convert (e->ops[i], oper));
*************** has_opt_convert (operand *o, enum tree_c
*** 757,763 ****
expr *e = as_a<expr *> (o);
! if (*e->operation->op == oper)
return true;
for (unsigned i = 0; i < e->ops.length (); ++i)
--- 738,744 ----
expr *e = as_a<expr *> (o);
! if (*e->operation == oper)
return true;
for (unsigned i = 0; i < e->ops.length (); ++i)
*************** replace_id (operand *o, const char *user
*** 860,873 ****
expr *e = static_cast<expr *> (o);
expr *ne;
! if (e->operation->op->kind == id_base::USER_DEFINED && strcmp (e->operation->op->id, user_id) == 0)
{
! struct e_operation *operation = new e_operation (oper, e->operation->is_commutative, false);
! check_operator (operation->op, e->ops.length ());
! ne = new expr (operation);
}
else
! ne = new expr (e->operation);
for (unsigned i = 0; i < e->ops.length (); ++i)
ne->append_op (replace_id (e->ops[i], user_id, oper));
--- 841,854 ----
expr *e = static_cast<expr *> (o);
expr *ne;
! if (e->operation->kind == id_base::USER_DEFINED
! && strcmp (e->operation->id, user_id) == 0)
{
! ne = new expr (get_operator (oper), e->is_commutative);
! check_operator (ne->operation, e->ops.length ());
}
else
! ne = new expr (e->operation, e->is_commutative);
for (unsigned i = 0; i < e->ops.length (); ++i)
ne->append_op (replace_id (e->ops[i], user_id, oper));
*************** check_no_user_id (operand *o)
*** 894,901 ****
check_expr:
expr *e = static_cast<expr *> (o);
! if (e->operation->op->kind == id_base::USER_DEFINED)
! fatal ("%s is not defined in for", e->operation->op->id);
for (unsigned i = 0; i < e->ops.length (); ++i)
check_no_user_id (e->ops[i]);
--- 875,882 ----
check_expr:
expr *e = static_cast<expr *> (o);
! if (e->operation->kind == id_base::USER_DEFINED)
! fatal ("%s is not defined in for", e->operation->id);
for (unsigned i = 0; i < e->ops.length (); ++i)
check_no_user_id (e->ops[i]);
*************** void
*** 957,963 ****
expr::gen_transform (FILE *f, const char *dest, bool gimple, int depth,
const char *in_type, dt_operand **indexes)
{
! bool conversion_p = is_conversion (operation->op);
const char *type = expr_type;
char optype[64];
if (type)
--- 938,944 ----
expr::gen_transform (FILE *f, const char *dest, bool gimple, int depth,
const char *in_type, dt_operand **indexes)
{
! bool conversion_p = is_conversion (operation);
const char *type = expr_type;
char optype[64];
if (type)
*************** expr::gen_transform (FILE *f, const char
*** 967,981 ****
/* For conversions we need to build the expression using the
outer type passed in. */
type = in_type;
! else if (*operation->op == REALPART_EXPR
! || *operation->op == IMAGPART_EXPR)
{
/* __real and __imag use the component type of its operand. */
sprintf (optype, "TREE_TYPE (TREE_TYPE (ops%d[0]))", depth);
type = optype;
}
! else if (is_a <operator_id *> (operation->op)
! && strcmp (as_a <operator_id *> (operation->op)->tcc, "tcc_comparison") == 0)
{
/* comparisons use boolean_type_node (or what gets in), but
their operands need to figure out the types themselves. */
--- 948,962 ----
/* For conversions we need to build the expression using the
outer type passed in. */
type = in_type;
! else if (*operation == REALPART_EXPR
! || *operation == IMAGPART_EXPR)
{
/* __real and __imag use the component type of its operand. */
sprintf (optype, "TREE_TYPE (TREE_TYPE (ops%d[0]))", depth);
type = optype;
}
! else if (is_a <operator_id *> (operation)
! && strcmp (as_a <operator_id *> (operation)->tcc, "tcc_comparison") == 0)
{
/* comparisons use boolean_type_node (or what gets in), but
their operands need to figure out the types themselves. */
*************** expr::gen_transform (FILE *f, const char
*** 1000,1006 ****
char dest[32];
snprintf (dest, 32, " ops%d[%u]", depth, i);
const char *optype
! = get_operand_type (operation->op, in_type, expr_type,
i == 0 ? NULL : op0type);
ops[i]->gen_transform (f, dest, gimple, depth + 1, optype, indexes);
}
--- 981,987 ----
char dest[32];
snprintf (dest, 32, " ops%d[%u]", depth, i);
const char *optype
! = get_operand_type (operation, in_type, expr_type,
i == 0 ? NULL : op0type);
ops[i]->gen_transform (f, dest, gimple, depth + 1, optype, indexes);
}
*************** expr::gen_transform (FILE *f, const char
*** 1012,1018 ****
fprintf (f, " if (!seq)\n"
" {\n"
" res = gimple_simplify (%s, %s",
! operation->op->id, type);
for (unsigned i = 0; i < ops.length (); ++i)
fprintf (f, ", ops%d[%u]", depth, i);
fprintf (f, ", seq, valueize);\n");
--- 993,999 ----
fprintf (f, " if (!seq)\n"
" {\n"
" res = gimple_simplify (%s, %s",
! operation->id, type);
for (unsigned i = 0; i < ops.length (); ++i)
fprintf (f, ", ops%d[%u]", depth, i);
fprintf (f, ", seq, valueize);\n");
*************** expr::gen_transform (FILE *f, const char
*** 1020,1038 ****
fprintf (f, " }\n");
fprintf (f, " else\n");
fprintf (f, " res = gimple_build (seq, UNKNOWN_LOCATION, %s, %s",
! operation->op->id, type);
for (unsigned i = 0; i < ops.length (); ++i)
fprintf (f, ", ops%d[%u]", depth, i);
fprintf (f, ", valueize);\n");
}
else
{
! if (operation->op->kind == id_base::CODE)
fprintf (f, " res = fold_build%d (%s, %s",
! ops.length(), operation->op->id, type);
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%d[%u]", depth, i);
fprintf (f, ");\n");
--- 1001,1019 ----
fprintf (f, " }\n");
fprintf (f, " else\n");
fprintf (f, " res = gimple_build (seq, UNKNOWN_LOCATION, %s, %s",
! operation->id, type);
for (unsigned i = 0; i < ops.length (); ++i)
fprintf (f, ", ops%d[%u]", depth, i);
fprintf (f, ", valueize);\n");
}
else
{
! if (operation->kind == id_base::CODE)
fprintf (f, " res = fold_build%d (%s, %s",
! ops.length(), operation->id, type);
else
fprintf (f, " res = build_call_expr (builtin_decl_implicit (%s), %d",
! operation->id, ops.length());
for (unsigned i = 0; i < ops.length (); ++i)
fprintf (f, ", ops%d[%u]", depth, i);
fprintf (f, ");\n");
*************** cmp_operand (operand *o1, operand *o2)
*** 1152,1158 ****
{
expr *e1 = static_cast<expr *>(o1);
expr *e2 = static_cast<expr *>(o2);
! return strcmp (e1->operation->op->id, e2->operation->op->id) == 0;
}
else
return false;
--- 1133,1139 ----
{
expr *e1 = static_cast<expr *>(o1);
expr *e2 = static_cast<expr *>(o2);
! return strcmp (e1->operation->id, e2->operation->id) == 0;
}
else
return false;
*************** unsigned
*** 1446,1452 ****
dt_operand::gen_gimple_expr (FILE *f)
{
expr *e = static_cast<expr *> (op);
! id_base *id = e->operation->op;
unsigned n_ops = e->ops.length ();
for (unsigned i = 0; i < n_ops; ++i)
--- 1427,1433 ----
dt_operand::gen_gimple_expr (FILE *f)
{
expr *e = static_cast<expr *> (op);
! id_base *id = e->operation;
unsigned n_ops = e->ops.length ();
for (unsigned i = 0; i < n_ops; ++i)
*************** dt_operand::gen_generic_expr (FILE *f, c
*** 1497,1503 ****
char child_opname[20];
gen_opname (child_opname, i);
! if (e->operation->op->kind == id_base::CODE)
fprintf (f, "tree %s = TREE_OPERAND (%s, %u);\n",
child_opname, opname, i);
else
--- 1478,1484 ----
char child_opname[20];
gen_opname (child_opname, i);
! if (e->operation->kind == id_base::CODE)
fprintf (f, "tree %s = TREE_OPERAND (%s, %u);\n",
child_opname, opname, i);
else
*************** dt_node::gen_gimple_kids (FILE *f)
*** 1525,1533 ****
{
if (e->ops.length () == 0)
generic_exprs.safe_push (op);
! else if (e->operation->op->kind == id_base::FN)
fns.safe_push (op);
! else if (e->operation->op->kind == id_base::PREDICATE)
preds.safe_push (op);
else
gimple_exprs.safe_push (op);
--- 1506,1514 ----
{
if (e->ops.length () == 0)
generic_exprs.safe_push (op);
! else if (e->operation->kind == id_base::FN)
fns.safe_push (op);
! else if (e->operation->kind == id_base::PREDICATE)
preds.safe_push (op);
else
gimple_exprs.safe_push (op);
*************** dt_node::gen_gimple_kids (FILE *f)
*** 1580,1586 ****
for (unsigned i = 0; i < exprs_len; ++i)
{
expr *e = as_a <expr *> (gimple_exprs[i]->op);
! id_base *op = e->operation->op;
if (*op == CONVERT_EXPR || *op == NOP_EXPR)
fprintf (f, "CASE_CONVERT:\n");
else
--- 1561,1567 ----
for (unsigned i = 0; i < exprs_len; ++i)
{
expr *e = as_a <expr *> (gimple_exprs[i]->op);
! id_base *op = e->operation;
if (*op == CONVERT_EXPR || *op == NOP_EXPR)
fprintf (f, "CASE_CONVERT:\n");
else
*************** dt_node::gen_gimple_kids (FILE *f)
*** 1609,1615 ****
{
expr *e = as_a <expr *>(fns[i]->op);
fprintf (f, "case %s:\n"
! "{\n", e->operation->op->id);
fns[i]->gen_gimple (f);
fprintf (f, "break;\n"
"}\n");
--- 1590,1596 ----
{
expr *e = as_a <expr *>(fns[i]->op);
fprintf (f, "case %s:\n"
! "{\n", e->operation->id);
fns[i]->gen_gimple (f);
fprintf (f, "break;\n"
"}\n");
*************** dt_node::gen_gimple_kids (FILE *f)
*** 1628,1634 ****
{
expr *e = as_a <expr *>(generic_exprs[i]->op);
fprintf (f, "case %s:\n"
! "{\n", e->operation->op->id);
generic_exprs[i]->gen_gimple (f);
fprintf (f, "break;\n"
--- 1609,1615 ----
{
expr *e = as_a <expr *>(generic_exprs[i]->op);
fprintf (f, "case %s:\n"
! "{\n", e->operation->id);
generic_exprs[i]->gen_gimple (f);
fprintf (f, "break;\n"
*************** dt_node::gen_gimple_kids (FILE *f)
*** 1643,1649 ****
for (unsigned i = 0; i < preds.length (); ++i)
{
expr *e = as_a <expr *> (preds[i]->op);
! predicate_id *p = as_a <predicate_id *> (e->operation->op);
preds[i]->get_name (kid_opname);
fprintf (f, "tree %s_pops[%d];\n", kid_opname, p->nargs);
fprintf (f, "if (gimple_%s (%s, %s_pops, valueize))\n", p->id,
--- 1624,1630 ----
for (unsigned i = 0; i < preds.length (); ++i)
{
expr *e = as_a <expr *> (preds[i]->op);
! predicate_id *p = as_a <predicate_id *> (e->operation);
preds[i]->get_name (kid_opname);
fprintf (f, "tree %s_pops[%d];\n", kid_opname, p->nargs);
fprintf (f, "if (gimple_%s (%s, %s_pops, valueize))\n", p->id,
*************** dt_node::gen_generic_kids (FILE *f)
*** 1756,1772 ****
if (kid->op->type == operand::OP_EXPR)
{
expr *e = as_a <expr *> (kid->op);
! if (e->operation->op->kind == id_base::CODE)
{
generic_exprs.safe_push (kid);
any = true;
}
! else if (e->operation->op->kind == id_base::FN)
{
fns.safe_push (kid);
any = true;
}
! else if (e->operation->op->kind == id_base::PREDICATE)
preds.safe_push (kid);
else
gcc_unreachable ();
--- 1737,1753 ----
if (kid->op->type == operand::OP_EXPR)
{
expr *e = as_a <expr *> (kid->op);
! if (e->operation->kind == id_base::CODE)
{
generic_exprs.safe_push (kid);
any = true;
}
! else if (e->operation->kind == id_base::FN)
{
fns.safe_push (kid);
any = true;
}
! else if (e->operation->kind == id_base::PREDICATE)
preds.safe_push (kid);
else
gcc_unreachable ();
*************** dt_node::gen_generic_kids (FILE *f)
*** 1784,1794 ****
{
dt_operand *kid = generic_exprs[j];
expr *e = as_a <expr *>(kid->op);
! gcc_assert (e->operation->op->kind == id_base::CODE);
/* ??? CONVERT */
fprintf (f, "case %s:\n"
! "{\n", e->operation->op->id);
kid->gen_generic (f);
fprintf (f, "break;\n"
"}\n");
--- 1765,1775 ----
{
dt_operand *kid = generic_exprs[j];
expr *e = as_a <expr *>(kid->op);
! gcc_assert (e->operation->kind == id_base::CODE);
/* ??? CONVERT */
fprintf (f, "case %s:\n"
! "{\n", e->operation->id);
kid->gen_generic (f);
fprintf (f, "break;\n"
"}\n");
*************** dt_node::gen_generic_kids (FILE *f)
*** 1799,1805 ****
{
dt_operand *kid = fns[j];
expr *e = as_a <expr *>(kid->op);
! gcc_assert (e->operation->op->kind == id_base::FN);
if (first)
fprintf (f, "case CALL_EXPR:\n"
--- 1780,1786 ----
{
dt_operand *kid = fns[j];
expr *e = as_a <expr *>(kid->op);
! gcc_assert (e->operation->kind == id_base::FN);
if (first)
fprintf (f, "case CALL_EXPR:\n"
*************** dt_node::gen_generic_kids (FILE *f)
*** 1811,1817 ****
first = false;
fprintf (f, "case %s:\n"
! "{\n", e->operation->op->id);
kid->gen_generic (f);
fprintf (f, "break;\n"
"}\n");
--- 1792,1798 ----
first = false;
fprintf (f, "case %s:\n"
! "{\n", e->operation->id);
kid->gen_generic (f);
fprintf (f, "break;\n"
"}\n");
*************** dt_node::gen_generic_kids (FILE *f)
*** 1829,1835 ****
for (unsigned i = 0; i < preds.length (); ++i)
{
expr *e = as_a <expr *> (preds[i]->op);
! predicate_id *p = as_a <predicate_id *> (e->operation->op);
char kid_opname[128];
preds[i]->get_name (kid_opname);
fprintf (f, "tree %s_pops[%d];\n", kid_opname, p->nargs);
--- 1810,1816 ----
for (unsigned i = 0; i < preds.length (); ++i)
{
expr *e = as_a <expr *> (preds[i]->op);
! predicate_id *p = as_a <predicate_id *> (e->operation);
char kid_opname[128];
preds[i]->get_name (kid_opname);
fprintf (f, "tree %s_pops[%d];\n", kid_opname, p->nargs);
*************** dt_simplify::gen (FILE *f, bool gimple)
*** 1938,1952 ****
if (s->result->type == operand::OP_EXPR)
{
expr *e = as_a <expr *> (s->result);
! bool is_predicate = is_a <predicate_id *> (e->operation->op);
if (!is_predicate)
! fprintf (f, "*res_code = %s;\n", e->operation->op->id);
for (unsigned j = 0; j < e->ops.length (); ++j)
{
char dest[32];
snprintf (dest, 32, " res_ops[%d]", j);
const char *optype
! = get_operand_type (e->operation->op,
"type", e->expr_type,
j == 0
? NULL : "TREE_TYPE (res_ops[0])");
--- 1919,1933 ----
if (s->result->type == operand::OP_EXPR)
{
expr *e = as_a <expr *> (s->result);
! bool is_predicate = is_a <predicate_id *> (e->operation);
if (!is_predicate)
! fprintf (f, "*res_code = %s;\n", e->operation->id);
for (unsigned j = 0; j < e->ops.length (); ++j)
{
char dest[32];
snprintf (dest, 32, " res_ops[%d]", j);
const char *optype
! = get_operand_type (e->operation,
"type", e->expr_type,
j == 0
? NULL : "TREE_TYPE (res_ops[0])");
*************** dt_simplify::gen (FILE *f, bool gimple)
*** 1974,1980 ****
if (s->result->type == operand::OP_EXPR)
{
expr *e = as_a <expr *> (s->result);
! bool is_predicate = is_a <predicate_id *> (e->operation->op);
for (unsigned j = 0; j < e->ops.length (); ++j)
{
char dest[32];
--- 1955,1961 ----
if (s->result->type == operand::OP_EXPR)
{
expr *e = as_a <expr *> (s->result);
! bool is_predicate = is_a <predicate_id *> (e->operation);
for (unsigned j = 0; j < e->ops.length (); ++j)
{
char dest[32];
*************** dt_simplify::gen (FILE *f, bool gimple)
*** 1986,2008 ****
snprintf (dest, 32, " res_op%d", j);
}
const char *optype
! = get_operand_type (e->operation->op,
"type", e->expr_type,
j == 0
? NULL : "TREE_TYPE (res_op0)");
e->ops[j]->gen_transform (f, dest, false, 1, optype, indexes);
}
! if (is_a <predicate_id *> (e->operation->op))
fprintf (f, "return true;\n");
else
{
/* Re-fold the toplevel result. */
! if (e->operation->op->kind == id_base::CODE)
fprintf (f, " return fold_build%d (%s, type",
! 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");
--- 1967,1989 ----
snprintf (dest, 32, " res_op%d", j);
}
const char *optype
! = get_operand_type (e->operation,
"type", e->expr_type,
j == 0
? NULL : "TREE_TYPE (res_op0)");
e->ops[j]->gen_transform (f, dest, false, 1, optype, indexes);
}
! if (is_a <predicate_id *> (e->operation))
fprintf (f, "return true;\n");
else
{
/* Re-fold the toplevel result. */
! if (e->operation->kind == id_base::CODE)
fprintf (f, " return fold_build%d (%s, type",
! e->ops.length (), e->operation->id);
else
fprintf (f, " return build_call_expr (builtin_decl_implicit (%s), %d",
! e->operation->id, e->ops.length());
for (unsigned j = 0; j < e->ops.length (); ++j)
fprintf (f, ", res_op%d", j);
fprintf (f, ");\n");
*************** decision_tree::gen_gimple (FILE *f)
*** 2049,2061 ****
if (e->ops.length () != n)
continue;
! if (*e->operation->op == CONVERT_EXPR
! || *e->operation->op == NOP_EXPR)
fprintf (f, "CASE_CONVERT:\n");
else
fprintf (f, "case %s%s:\n",
! is_a <fn_id *> (e->operation->op) ? "-" : "",
! e->operation->op->id);
fprintf (f, "{\n");
dop->gen_gimple_kids (f);
fprintf (f, "break;\n");
--- 2030,2042 ----
if (e->ops.length () != n)
continue;
! if (*e->operation == CONVERT_EXPR
! || *e->operation == NOP_EXPR)
fprintf (f, "CASE_CONVERT:\n");
else
fprintf (f, "case %s%s:\n",
! is_a <fn_id *> (e->operation) ? "-" : "",
! e->operation->id);
fprintf (f, "{\n");
dop->gen_gimple_kids (f);
fprintf (f, "break;\n");
*************** decision_tree::gen_generic (FILE *f)
*** 2105,2118 ****
GENERIC. The following drops patterns with outermost
calls. It's easy to emit overloads for function code
though if necessary. */
! || e->operation->op->kind != id_base::CODE)
continue;
! operator_id *op_id = static_cast <operator_id *> (e->operation->op);
if (op_id->code == NOP_EXPR || op_id->code == CONVERT_EXPR)
fprintf (f, "CASE_CONVERT:\n");
else
! fprintf (f, "case %s:\n", e->operation->op->id);
fprintf (f, "{\n");
dop->gen_generic_kids (f);
fprintf (f, "break;\n"
--- 2086,2099 ----
GENERIC. The following drops patterns with outermost
calls. It's easy to emit overloads for function code
though if necessary. */
! || e->operation->kind != id_base::CODE)
continue;
! operator_id *op_id = static_cast <operator_id *> (e->operation);
if (op_id->code == NOP_EXPR || op_id->code == CONVERT_EXPR)
fprintf (f, "CASE_CONVERT:\n");
else
! fprintf (f, "case %s:\n", e->operation->id);
fprintf (f, "{\n");
dop->gen_generic_kids (f);
fprintf (f, "break;\n"
*************** get_number (cpp_reader *r)
*** 2323,2329 ****
/* Parsing. */
! static e_operation *
parse_operation (cpp_reader *r)
{
const char *id = get_ident (r);
--- 2304,2310 ----
/* Parsing. */
! static id_base *
parse_operation (cpp_reader *r)
{
const char *id = get_ident (r);
*************** parse_operation (cpp_reader *r)
*** 2344,2350 ****
else if (strcmp (id, "convert0") == 0
|| strcmp (id, "convert1") == 0)
fatal_at (token, "expected '?' after conditional operator");
! return new e_operation (id);
}
static struct operand * parse_op (cpp_reader *r);
--- 2325,2334 ----
else if (strcmp (id, "convert0") == 0
|| strcmp (id, "convert1") == 0)
fatal_at (token, "expected '?' after conditional operator");
! id_base *op = get_operator (id);
! if (!op)
! fatal_at (token, "unknown operator %s", id);
! return op;
}
static struct operand * parse_op (cpp_reader *r);
*************** parse_expr (cpp_reader *r)
*** 2399,2409 ****
const cpp_token *token = peek (r);
if (token->type == CPP_CLOSE_PAREN)
{
! check_operator (e->operation->op, e->ops.length (), token);
if (is_commutative)
{
if (e->ops.length () == 2)
! e->operation->is_commutative = true;
else
fatal_at (token, "only binary operators or function with two arguments can be marked commutative");
}
--- 2383,2393 ----
const cpp_token *token = peek (r);
if (token->type == CPP_CLOSE_PAREN)
{
! check_operator (e->operation, e->ops.length (), token);
if (is_commutative)
{
if (e->ops.length () == 2)
! e->is_commutative = true;
else
fatal_at (token, "only binary operators or function with two arguments can be marked commutative");
}
*************** parse_op (cpp_reader *r)
*** 2489,2495 ****
fatal_at (token, "using an operator with operands as predicate");
/* Parse the zero-operand operator "predicates" as
expression. */
! op = new expr (new e_operation (id));
}
else if (predicate_id *p = dyn_cast <predicate_id *> (opr))
op = new predicate (p);
--- 2473,2479 ----
fatal_at (token, "using an operator with operands as predicate");
/* Parse the zero-operand operator "predicates" as
expression. */
! op = new expr (opr);
}
else if (predicate_id *p = dyn_cast <predicate_id *> (opr))
op = new predicate (p);
*************** parse_simplify (cpp_reader *r, source_lo
*** 2530,2536 ****
if (match->type == operand::OP_CAPTURE && !matcher)
fatal_at (loc, "outermost expression cannot be captured");
if (match->type == operand::OP_EXPR
! && is_a <predicate_id *> (as_a <expr *> (match)->operation->op))
fatal_at (loc, "outermost expression cannot be a predicate");
const cpp_token *token = peek (r);
--- 2514,2520 ----
if (match->type == operand::OP_CAPTURE && !matcher)
fatal_at (loc, "outermost expression cannot be captured");
if (match->type == operand::OP_EXPR
! && is_a <predicate_id *> (as_a <expr *> (match)->operation))
fatal_at (loc, "outermost expression cannot be a predicate");
const cpp_token *token = peek (r);
*************** void
*** 2653,2659 ****
parse_for (cpp_reader *r, source_location, vec<simplify *>& simplifiers,
vec<if_or_with>& active_ifs)
{
! vec<const char *> user_ids = vNULL;
vec< vec<const char *> > opers_vec = vNULL;
const cpp_token *token;
unsigned min_n_opers = 0, max_n_opers = 0;
--- 2637,2643 ----
parse_for (cpp_reader *r, source_location, vec<simplify *>& simplifiers,
vec<if_or_with>& active_ifs)
{
! vec<id_base *> user_ids = vNULL;
vec< vec<const char *> > opers_vec = vNULL;
const cpp_token *token;
unsigned min_n_opers = 0, max_n_opers = 0;
*************** parse_for (cpp_reader *r, source_locatio
*** 2664,2675 ****
if (token == 0)
break;
! const char *id = (const char *) NODE_NAME (token->val.node.node);
! if (get_operator (id))
! fatal_at (token, "built-in operators cannot be user defined identifiers in for");
!
! user_ids.safe_push (id);
! eat_token (r, CPP_NAME);
eat_token (r, CPP_OPEN_PAREN);
--- 2648,2661 ----
if (token == 0)
break;
! /* Insert the user defined operators into the operator hash. */
! const char *id = get_ident (r);
! id_base *op = new id_base (id_base::USER_DEFINED, id);
! id_base **slot = operators->find_slot_with_hash (op, op->hashval, INSERT);
! if (*slot)
! fatal_at (token, "operator already defined");
! *slot = op;
! user_ids.safe_push (op);
eat_token (r, CPP_OPEN_PAREN);
*************** parse_for (cpp_reader *r, source_locatio
*** 2677,2686 ****
while ((token = peek_ident (r)) != 0)
{
! eat_token (r, CPP_NAME);
! const char *oper = (const char *) NODE_NAME (token->val.node.node);
id_base *idb = get_operator (oper);
! if (idb == 0)
fatal_at (token, "no such operator %s", oper);
if (*idb == CONVERT0 || *idb == CONVERT1 || *idb == CONVERT2)
fatal_at (token, "conditional operators cannot be used inside for");
--- 2663,2671 ----
while ((token = peek_ident (r)) != 0)
{
! const char *oper = get_ident (r);
id_base *idb = get_operator (oper);
! if (idb == NULL)
fatal_at (token, "no such operator %s", oper);
if (*idb == CONVERT0 || *idb == CONVERT1 || *idb == CONVERT2)
fatal_at (token, "conditional operators cannot be used inside for");
*************** parse_for (cpp_reader *r, source_locatio
*** 2689,2695 ****
}
token = expect (r, CPP_CLOSE_PAREN);
if (opers.length () == 0)
! fatal_at (token, "A user-defined identifier must have at least one substitution");
if (opers_vec.length () == 0)
{
min_n_opers = opers.length ();
--- 2674,2680 ----
}
token = expect (r, CPP_CLOSE_PAREN);
if (opers.length () == 0)
! fatal_at (token, "A user-defined operator must have at least one substitution");
if (opers_vec.length () == 0)
{
min_n_opers = opers.length ();
*************** parse_for (cpp_reader *r, source_locatio
*** 2740,2757 ****
for (unsigned i = 0; i < n_ids; ++i)
{
const char *oper = opers_vec[i][j % opers_vec[i].length ()];
! match_op = replace_id (match_op, user_ids[i], oper);
! result_op = replace_id (result_op, user_ids[i], oper);
for (unsigned k = 0; k < s->ifexpr_vec.length (); ++k)
! ifexpr_vec[k].cexpr = replace_id (ifexpr_vec[k].cexpr, user_ids[i], oper);
}
simplify *ns = new simplify (match_op, s->match_location,
result_op, s->result_location, ifexpr_vec);
simplifiers.safe_push (ns);
}
}
}
void
--- 2725,2747 ----
for (unsigned i = 0; i < n_ids; ++i)
{
+ const char *op = user_ids[i]->id;
const char *oper = opers_vec[i][j % opers_vec[i].length ()];
! match_op = replace_id (match_op, op, oper);
! result_op = replace_id (result_op, op, oper);
for (unsigned k = 0; k < s->ifexpr_vec.length (); ++k)
! ifexpr_vec[k].cexpr = replace_id (ifexpr_vec[k].cexpr, op, oper);
}
simplify *ns = new simplify (match_op, s->match_location,
result_op, s->result_location, ifexpr_vec);
simplifiers.safe_push (ns);
}
}
+
+ /* Remove user-defined operators from the hash again. */
+ for (unsigned i = 0; i < user_ids.length (); ++i)
+ operators->remove_elt (user_ids[i]);
}
void