struct operand {
enum op_type { OP_PREDICATE, OP_EXPR, OP_CAPTURE, OP_C_EXPR, OP_IF, OP_WITH };
- operand (enum op_type type_) : type (type_) {}
+ operand (enum op_type type_, source_location loc_)
+ : type (type_), location (loc_) {}
enum op_type type;
+ source_location location;
virtual void gen_transform (FILE *, int, const char *, bool, int,
const char *, capture_info *,
dt_operand ** = 0,
struct predicate : public operand
{
- predicate (predicate_id *p_) : operand (OP_PREDICATE), p (p_) {}
+ predicate (predicate_id *p_, source_location loc)
+ : operand (OP_PREDICATE, loc), p (p_) {}
predicate_id *p;
};
struct expr : public operand
{
- expr (id_base *operation_, bool is_commutative_ = false)
- : operand (OP_EXPR), operation (operation_),
+ expr (id_base *operation_, source_location loc, bool is_commutative_ = false)
+ : operand (OP_EXPR, loc), operation (operation_),
ops (vNULL), expr_type (NULL), is_commutative (is_commutative_),
is_generic (false), force_single_use (false) {}
expr (expr *e)
- : operand (OP_EXPR), operation (e->operation),
+ : operand (OP_EXPR, e->location), operation (e->operation),
ops (vNULL), expr_type (e->expr_type), is_commutative (e->is_commutative),
is_generic (e->is_generic), force_single_use (e->force_single_use) {}
void append_op (operand *op) { ops.safe_push (op); }
id_tab (const char *id_, const char *oper_): id (id_), oper (oper_) {}
};
- c_expr (cpp_reader *r_, vec<cpp_token> code_, unsigned nr_stmts_,
+ c_expr (cpp_reader *r_, source_location loc,
+ vec<cpp_token> code_, unsigned nr_stmts_,
vec<id_tab> ids_, cid_map_t *capture_ids_)
- : operand (OP_C_EXPR), r (r_), code (code_), capture_ids (capture_ids_),
- nr_stmts (nr_stmts_), ids (ids_) {}
+ : operand (OP_C_EXPR, loc), r (r_), code (code_),
+ capture_ids (capture_ids_), nr_stmts (nr_stmts_), ids (ids_) {}
/* cpplib tokens and state to transform this back to source. */
cpp_reader *r;
vec<cpp_token> code;
struct capture : public operand
{
- capture (unsigned where_, operand *what_)
- : operand (OP_CAPTURE), where (where_), what (what_) {}
+ capture (source_location loc, unsigned where_, operand *what_)
+ : operand (OP_CAPTURE, loc), where (where_), what (what_) {}
/* Identifier index for the value. */
unsigned where;
/* The captured value. */
struct if_expr : public operand
{
- if_expr () : operand (OP_IF), cond (NULL), trueexpr (NULL),
- falseexpr (NULL) {}
+ if_expr (source_location loc)
+ : operand (OP_IF, loc), cond (NULL), trueexpr (NULL), falseexpr (NULL) {}
c_expr *cond;
operand *trueexpr;
operand *falseexpr;
struct with_expr : public operand
{
- with_expr () : operand (OP_WITH), with (NULL), subexpr (NULL) {}
+ with_expr (source_location loc)
+ : operand (OP_WITH, loc), with (NULL), subexpr (NULL) {}
c_expr *with;
operand *subexpr;
};
{
enum simplify_kind { SIMPLIFY, MATCH };
- simplify (simplify_kind kind_,
- operand *match_, source_location match_location_,
- struct operand *result_, source_location result_location_,
+ simplify (simplify_kind kind_, operand *match_, operand *result_,
vec<vec<user_id *> > for_vec_, cid_map_t *capture_ids_)
- : kind (kind_), match (match_), match_location (match_location_),
- result (result_), result_location (result_location_),
+ : kind (kind_), match (match_), result (result_),
for_vec (for_vec_),
capture_ids (capture_ids_), capture_max (capture_ids_->elements () - 1) {}
simplify_kind kind;
/* The expression that is matched against the GENERIC or GIMPLE IL. */
operand *match;
- source_location match_location;
/* For a (simplify ...) an expression with ifs and withs with the expression
produced when the pattern applies in the leafs.
For a (match ...) the leafs are either empty if it is a simple predicate
or the single expression specifying the matched operands. */
struct operand *result;
- source_location result_location;
/* Collected 'for' expression operators that have to be replaced
in the lowering phase. */
vec<vec<user_id *> > for_vec;
vec<operand *> v = commutate (c->what);
for (unsigned i = 0; i < v.length (); ++i)
{
- capture *nc = new capture (c->where, v[i]);
+ capture *nc = new capture (c->location, c->where, v[i]);
ret.safe_push (nc);
}
return ret;
vec<operand *> matchers = commutate (s->match);
for (unsigned i = 0; i < matchers.length (); ++i)
{
- simplify *ns = new simplify (s->kind, matchers[i], s->match_location,
- s->result, s->result_location,
+ simplify *ns = new simplify (s->kind, matchers[i], s->result,
s->for_vec, s->capture_ids);
simplifiers.safe_push (ns);
}
if (capture *c = dyn_cast<capture *> (o))
{
if (c->what)
- return new capture (c->where,
+ return new capture (c->location, c->where,
lower_opt_convert (c->what, oper, to_oper, strip));
else
return c;
vec<operand *> matchers = lower_opt_convert (s->match);
for (unsigned i = 0; i < matchers.length (); ++i)
{
- simplify *ns = new simplify (s->kind, matchers[i], s->match_location,
- s->result, s->result_location,
+ simplify *ns = new simplify (s->kind, matchers[i], s->result,
s->for_vec, s->capture_ids);
simplifiers.safe_push (ns);
}
lop = lower_cond (c->what);
for (unsigned i = 0; i < lop.length (); ++i)
- ro.safe_push (new capture (c->where, lop[i]));
+ ro.safe_push (new capture (c->location, c->where, lop[i]));
return ro;
}
}
for (unsigned j = 0; j < ocmp->ops.length (); ++j)
cmp->append_op (ocmp->ops[j]);
cmp->is_generic = true;
- ne->ops[0] = new capture (c->where, cmp);
+ ne->ops[0] = new capture (c->location, c->where, cmp);
}
else
{
vec<operand *> matchers = lower_cond (s->match);
for (unsigned i = 0; i < matchers.length (); ++i)
{
- simplify *ns = new simplify (s->kind, matchers[i], s->match_location,
- s->result, s->result_location,
+ simplify *ns = new simplify (s->kind, matchers[i], s->result,
s->for_vec, s->capture_ids);
simplifiers.safe_push (ns);
}
{
if (!c->what)
return c;
- return new capture (c->where, replace_id (c->what, id, with));
+ return new capture (c->location, c->where,
+ replace_id (c->what, id, with));
}
else if (expr *e = dyn_cast<expr *> (o))
{
}
else if (with_expr *w = dyn_cast <with_expr *> (o))
{
- with_expr *nw = new with_expr ();
+ with_expr *nw = new with_expr (w->location);
nw->with = as_a <c_expr *> (replace_id (w->with, id, with));
nw->subexpr = replace_id (w->subexpr, id, with);
return nw;
}
else if (if_expr *ife = dyn_cast <if_expr *> (o))
{
- if_expr *nife = new if_expr ();
+ if_expr *nife = new if_expr (ife->location);
nife->cond = as_a <c_expr *> (replace_id (ife->cond, id, with));
nife->trueexpr = replace_id (ife->trueexpr, id, with);
if (ife->falseexpr)
{
vec<c_expr::id_tab> ids = ce->ids.copy ();
ids.safe_push (c_expr::id_tab (id->id, with->id));
- return new c_expr (ce->r, ce->code, ce->nr_stmts, ids, ce->capture_ids);
+ return new c_expr (ce->r, ce->location,
+ ce->code, ce->nr_stmts, ids, ce->capture_ids);
}
return o;
if (result_op)
result_op = replace_id (result_op, id, oper);
}
- simplify *ns = new simplify (s->kind, match_op, s->match_location,
- result_op, s->result_location,
+ simplify *ns = new simplify (s->kind, match_op, result_op,
vNULL, s->capture_ids);
worklist.safe_push (ns);
}
{
fprintf_indent (f, indent, "{\n");
indent += 4;
- output_line_directive (f, w->with->code[0].src_loc);
+ output_line_directive (f, w->location);
w->with->gen_transform (f, indent, NULL, true, 1, "type", NULL);
gen_1 (f, indent, gimple, w->subexpr);
indent -= 4;
}
else if (if_expr *ife = dyn_cast <if_expr *> (result))
{
- output_line_directive (f, ife->cond->code[0].src_loc);
+ output_line_directive (f, ife->location);
fprintf_indent (f, indent, "if (");
ife->cond->gen_transform (f, indent, NULL, true, 1, "type", NULL);
fprintf (f, ")\n");
fprintf_indent (f, indent, "if (dump_file && (dump_flags & TDF_DETAILS)) "
"fprintf (dump_file, \"Applying pattern ");
- output_line_directive (f, s->result_location, true);
+ output_line_directive (f,
+ result ? result->location : s->match->location, true);
fprintf (f, ", %%s:%%d\\n\", __FILE__, __LINE__);\n");
if (!result)
{
fprintf_indent (f, indent, "{\n");
indent += 2;
- output_line_directive (f, s->result_location);
+ output_line_directive (f,
+ s->result ? s->result->location : s->match->location);
if (s->capture_max >= 0)
fprintf_indent (f, indent, "tree captures[%u] ATTRIBUTE_UNUSED = {};\n",
s->capture_max + 1);
void parse_pattern ();
operand *parse_result (operand *, predicate_id *);
void push_simplify (simplify::simplify_kind,
- vec<simplify *>&, operand *, source_location,
- operand *, source_location);
+ vec<simplify *>&, operand *, operand *);
void parse_simplify (simplify::simplify_kind,
- source_location, vec<simplify *>&, predicate_id *,
- operand *);
+ vec<simplify *>&, predicate_id *, operand *);
void parse_for (source_location);
void parse_if (source_location);
void parse_predicates (source_location);
struct operand *
parser::parse_capture (operand *op)
{
- eat_token (CPP_ATSIGN);
+ source_location src_loc = eat_token (CPP_ATSIGN)->src_loc;
const cpp_token *token = peek ();
const char *id = NULL;
if (token->type == CPP_NUMBER)
unsigned &num = capture_ids->get_or_insert (id, &existed);
if (!existed)
num = next_id;
- return new capture (num, op);
+ return new capture (src_loc, num, op);
}
/* Parse an expression
struct operand *
parser::parse_expr ()
{
- expr *e = new expr (parse_operation ());
const cpp_token *token = peek ();
+ expr *e = new expr (parse_operation (), token->src_loc);
+ token = peek ();
operand *op;
bool is_commutative = false;
bool force_capture = false;
capture_ids->get_or_insert (xstrdup (id), &existed);
if (existed)
fatal_at (token, "reserved capture id '%s' already used", id);
- op = new capture (num, e);
+ op = new capture (token->src_loc, num, e);
}
else
op = e;
unsigned opencnt;
vec<cpp_token> code = vNULL;
unsigned nr_stmts = 0;
- eat_token (start);
+ source_location loc = eat_token (start)->src_loc;
if (start == CPP_OPEN_PAREN)
end = CPP_CLOSE_PAREN;
else if (start == CPP_OPEN_BRACE)
code.safe_push (*token);
}
while (1);
- return new c_expr (r, code, nr_stmts, vNULL, capture_ids);
+ return new c_expr (r, loc, code, nr_stmts, vNULL, capture_ids);
}
/* Parse an operand which is either an expression, a predicate or
fatal_at (token, "using an operator with operands as predicate");
/* Parse the zero-operand operator "predicates" as
expression. */
- op = new expr (opr);
+ op = new expr (opr, token->src_loc);
}
else if (user_id *code = dyn_cast <user_id *> (opr))
{
fatal_at (token, "using an operator with operands as predicate");
/* Parse the zero-operand operator "predicates" as
expression. */
- op = new expr (opr);
+ op = new expr (opr, token->src_loc);
}
else if (predicate_id *p = dyn_cast <predicate_id *> (opr))
- op = new predicate (p);
+ op = new predicate (p, token->src_loc);
else
fatal_at (token, "using an unsupported operator as predicate");
if (!parsing_match_operand)
void
parser::push_simplify (simplify::simplify_kind kind,
vec<simplify *>& simplifiers,
- operand *match, source_location match_loc,
- operand *result, source_location result_loc)
+ operand *match, operand *result)
{
/* Build and push a temporary for operator list uses in expressions. */
if (!oper_lists.is_empty ())
active_fors.safe_push (oper_lists);
simplifiers.safe_push
- (new simplify (kind, match, match_loc, result, result_loc,
+ (new simplify (kind, match, result,
active_fors.copy (), capture_ids));
if (!oper_lists.is_empty ())
if (peek_ident ("if"))
{
eat_ident ("if");
- if_expr *ife = new if_expr ();
+ if_expr *ife = new if_expr (token->src_loc);
ife->cond = parse_c_expr (CPP_OPEN_PAREN);
if (peek ()->type == CPP_OPEN_PAREN)
{
else if (peek_ident ("with"))
{
eat_ident ("with");
- with_expr *withe = new with_expr ();
+ with_expr *withe = new with_expr (token->src_loc);
/* Parse (with c-expr expr) as (if-with (true) expr). */
withe->with = parse_c_expr (CPP_OPEN_BRACE);
withe->with->nr_stmts = 0;
else if (peek_ident ("switch"))
{
token = eat_ident ("switch");
- eat_token (CPP_OPEN_PAREN);
+ source_location ifloc = eat_token (CPP_OPEN_PAREN)->src_loc;
eat_ident ("if");
- if_expr *ife = new if_expr ();
+ if_expr *ife = new if_expr (ifloc);
operand *res = ife;
ife->cond = parse_c_expr (CPP_OPEN_PAREN);
if (peek ()->type == CPP_OPEN_PAREN)
{
if (peek_ident ("if", 2))
{
- eat_token (CPP_OPEN_PAREN);
+ ifloc = eat_token (CPP_OPEN_PAREN)->src_loc;
eat_ident ("if");
- ife->falseexpr = new if_expr ();
+ ife->falseexpr = new if_expr (ifloc);
ife = as_a <if_expr *> (ife->falseexpr);
ife->cond = parse_c_expr (CPP_OPEN_PAREN);
if (peek ()->type == CPP_OPEN_PAREN)
void
parser::parse_simplify (simplify::simplify_kind kind,
- source_location match_location,
vec<simplify *>& simplifiers, predicate_id *matcher,
operand *result)
{
if_expr *active_if = NULL;
for (int i = active_ifs.length (); i > 0; --i)
{
- if_expr *ifc = new if_expr ();
+ if_expr *ifc = new if_expr (active_ifs[i-1]->location);
ifc->cond = active_ifs[i-1];
ifc->trueexpr = active_if;
active_if = ifc;
active_if->trueexpr = result;
result = outermost_if;
}
- push_simplify (kind, simplifiers, match, match_location,
- result, token->src_loc);
+ push_simplify (kind, simplifiers, match, result);
return;
}
else
result = tem;
- push_simplify (kind, simplifiers, match, match_location,
- result, token->src_loc);
+ push_simplify (kind, simplifiers, match, result);
}
/* Parsing of the outer control structures. */
const char *id = get_ident ();
if (strcmp (id, "simplify") == 0)
{
- parse_simplify (simplify::SIMPLIFY,
- token->src_loc, simplifiers, NULL, NULL);
+ parse_simplify (simplify::SIMPLIFY, simplifiers, NULL, NULL);
capture_ids = NULL;
}
else if (strcmp (id, "match") == 0)
{
bool with_args = false;
+ source_location e_loc = peek ()->src_loc;
if (peek ()->type == CPP_OPEN_PAREN)
{
eat_token (CPP_OPEN_PAREN);
if (with_args)
{
capture_ids = new cid_map_t;
- e = new expr (p);
+ e = new expr (p, e_loc);
while (peek ()->type == CPP_ATSIGN)
e->append_op (parse_capture (NULL));
eat_token (CPP_CLOSE_PAREN);
|| (!e && p->nargs != 0)))
fatal_at (token, "non-matching number of match operands");
p->nargs = e ? e->ops.length () : 0;
- parse_simplify (simplify::MATCH, token->src_loc, p->matchers, p, e);
+ parse_simplify (simplify::MATCH, p->matchers, p, e);
capture_ids = NULL;
}
else if (strcmp (id, "for") == 0)