On Mon, Aug 4, 2014 at 2:13 PM, Richard Biener <richard.guent...@gmail.com> wrote: > On Sun, Aug 3, 2014 at 6:58 PM, Prathamesh Kulkarni > <bilbotheelffri...@gmail.com> wrote: >> On Tue, Jul 29, 2014 at 4:29 PM, Richard Biener >> <richard.guent...@gmail.com> wrote: >>> On Mon, Jul 28, 2014 at 10:02 PM, Prathamesh Kulkarni >>> <bilbotheelffri...@gmail.com> wrote: >>>> I am having few issues replacing op in c_expr. >>>> I thought of following possibilities: >>>> >>>> a) create a new vec<cpp_token> vector new_code. >>>> for each token in code >>>> { >>>> if token.type is not CPP_NAME >>>> new_code.safe_push (token); >>>> else >>>> { >>>> cpp_token new_token = >>>> ??? create new token of type CPP_NAME >>>> with contents as name of operator ??? >>>> } >>>> } >>>> >>>> I tried to go this way, but am stuck with creating a new token type. >>>> i started by: >>>> cpp_token new_token = token; // get same attrs as token. >>>> CPP_HASHNODE (new_token.val.node.node)->ident.str = name of operator. >>>> CPP_HASHNODE (new_token.val.node.node)->ident.len = len of operator name. >>>> name of operator is obtained from opers[i] in parse_for. >>>> >>>> however this does not work because I guess >>>> new_token = token, shallow copies >>>> the token (default assignment operator, i didn't find an overloaded >>>> version). >>>> >>>> b) create new struct c_expr_elem and use >>>> vec<c_expr_elem> code, instead of vec<cpp_token> code; >>>> >>>> sth like: >>>> struct c_expr_elem >>>> { >>>> enum c_expr_elem_type { ID, TOKEN }; >>>> enum c_expr_elem_type type; >>>> >>>> union { >>>> cpp_token token; >>>> const char *id; >>>> }; >>>> }; >>>> >>>> while replacing op, compare token with op, and if it matches, >>>> create a new c_expr_elem with type = ID, and id = name of operator. >>>> This shall probably work, but shall require many changes to other parts >>>> since we change c_expr::code. >>>> >>>> I would like to hear any other suggestions. >>> >>> Together with the vector of tokens recorded at parse_c_expr time >>> record a vector of token mappings (op -> plus, op2 -> ...) and do >>> the replacement at code-generation time where we also special-case >>> captures. >>> >>> Yeah, it's a but unfortunate that c_expr parsing is done the way it >>> is done.... >> Thanks. I guess we would require a multi-map for this since there can >> be many operators >> (op -> [plus, minus], op2 -> [negate]) ? > > Well, it would be enough to attach the mapping to c_expr()s after the > AST lowering when there is at most one? Because obviously > code-generation cannot know which to replace. > >> Unfortunately, I somehow seem to have missed your response and ended up with >> a >> hackish way of doing it, although it works. I will soon change that to >> use token mappings. >> >> I mostly followed b), except i made it sub-class of cpp_token, so the >> other code using c_expr::code >> (outline_c_expr, c_expr::gen_transform) did not require changes except >> for special-casing op. > > Indeed not too ugly. Still at the point where you replace in the for() > processing > > - operand *result_op = replace_id (s->result, user_id, opers[i]); > + > + operand *result_op; > + if (is_a<c_expr *> (s->result)) > + result_op = replace_op_in_c_expr (s->result, user_id, > opers[i]); > + else > + result_op = replace_id (s->result, user_id, opers[i]); > + > + > > it should be "easy" to attach a replacemet vector/map to the c_expr > and use that duing code-generation. > > Note that sub-expressions can also be c_exprs, thus > > (match-and-simplify > (....) > (plus { ... } @2)) > > I don't think your patch covers that. That is, you should add > c_expr handing to replace_id instead. Thanks, this patch covers that case. For now, I have still kept the old way, since the change was one-liner. I will change it after I am done with conditional convert
* genmatch.c (c_expr::elem): New struct. (c_expr::code): Change type to vec<c_expr::elem>. (replace_op_in_c_expr): New function. (replace_id): Call replace_op_in_c_expr. (c_expr::gen_transform): Adjust to changes in c_expr. (outline_c_expr): Likewise. (parse_c_expr): Likewise. (parse_for): Call replace_op_in_c_expr. Thanks, Prathamesh > > Richard. > >> * genmatch.c (c_expr::elem): New struct. >> (c_expr::code): Change type to vec<c_expr::elem>. >> (replace_op_in_c_expr): New function. >> (c_expr::gen_transform): Adjust to changes in c_expr. >> (outline_c_expr): Likewise. >> (parse_c_expr): Likewise. >> (parse_for): Call replace_op_in_c_expr. >> >> Thanks, >> Prathamesh >> >>> >>> Richard. >>> >>>> Thanks, >>>> Prathamesh.
Index: genmatch.c =================================================================== --- genmatch.c (revision 213756) +++ genmatch.c (working copy) @@ -239,11 +239,20 @@ struct expr : public operand struct c_expr : public operand { - c_expr (cpp_reader *r_, vec<cpp_token> code_, unsigned nr_stmts_) + struct elem: public cpp_token + { + enum elem_type { TOKEN, ID }; + enum elem_type type; + const char *id; + + elem (enum elem_type type_ = TOKEN, const char *id_ = 0): type (type_), id (id_) {} + }; + + c_expr (cpp_reader *r_, vec<elem> code_, unsigned nr_stmts_) : operand (OP_C_EXPR), r (r_), code (code_), nr_stmts (nr_stmts_), fname (NULL) {} cpp_reader *r; - vec<cpp_token> code; + vec<elem> code; unsigned nr_stmts; char *fname; virtual void gen_transform (FILE *f, const char *, bool, int); @@ -620,6 +629,31 @@ check_operator (id_base *op, unsigned n_ } operand * +replace_op_in_c_expr (operand *o, const char *user_id, const char *oper) +{ + gcc_assert (is_a<c_expr *> (o)); + c_expr *ce = as_a<c_expr *> (o); + + vec<c_expr::elem> code = vNULL; + + for (unsigned i = 0; i < ce->code.length (); ++i) + { + cpp_token token = ce->code[i]; + if (token.type == CPP_NAME + && strcmp ((const char *) NODE_NAME (token.val.node.node), user_id) == 0) + { + e_operation operation (oper); + c_expr::elem elm (c_expr::elem::ID, operation.op->id); + code.safe_push (elm); + } + else + code.safe_push (ce->code[i]); + } + + return new c_expr (ce->r, code, ce->nr_stmts); +} + +operand * replace_id (operand *o, const char *user_id, const char *oper) { if (o->type == operand::OP_CAPTURE) @@ -631,10 +665,13 @@ replace_id (operand *o, const char *user return nc; } - if (o->type != operand::OP_EXPR) + if (is_a<c_expr *> (o)) + return replace_op_in_c_expr (o, user_id, oper); + + if (!is_a<expr *> (o)) return o; - expr *e = static_cast<expr *> (o); + expr *e = as_a<expr *> (o); expr *ne; if (e->operation->op->kind == id_base::USER_DEFINED && strcmp (e->operation->op->id, user_id) == 0) @@ -651,6 +688,7 @@ replace_id (operand *o, const char *user return ne; } + void check_no_user_id (operand *o) @@ -752,6 +790,11 @@ c_expr::gen_transform (FILE *f, const ch for (unsigned i = 0; i < code.length (); ++i) { + if (code[i].type == elem::ID) + { + fputs (code[i].id, f); + continue; + } const cpp_token *token = &code[i]; /* Replace captures for code-gen. */ @@ -1727,6 +1770,11 @@ outline_c_exprs (FILE *f, struct operand unsigned stmt_nr = 1; for (unsigned i = 0; i < e->code.length (); ++i) { + if (e->code[i].type == c_expr::elem::ID) + { + fputs (e->code[i].id, f); + continue; + } const cpp_token *token = &e->code[i]; /* Replace captures for code-gen. */ @@ -1982,7 +2030,7 @@ parse_c_expr (cpp_reader *r, cpp_ttype s const cpp_token *token; cpp_ttype end; unsigned opencnt; - vec<cpp_token> code = vNULL; + vec<c_expr::elem> code = vNULL; unsigned nr_stmts = 0; eat_token (r, start); if (start == CPP_OPEN_PAREN) @@ -2007,7 +2055,7 @@ parse_c_expr (cpp_reader *r, cpp_ttype s nr_stmts++; /* Record the token. */ - code.safe_push (*token); + code.safe_push (*(c_expr::elem *) token); } while (1); return new c_expr (r, code, nr_stmts); @@ -2147,10 +2195,20 @@ parse_for (cpp_reader *r, source_locatio { simplify *s = for_simplifiers[j]; operand *match_op = replace_id (s->match, user_id, opers[i]); - operand *result_op = replace_id (s->result, user_id, opers[i]); + + operand *result_op; + if (is_a<c_expr *> (s->result)) + result_op = replace_op_in_c_expr (s->result, user_id, opers[i]); + else + result_op = replace_id (s->result, user_id, opers[i]); + + + vec<operand *> ifexpr_vec = vNULL; + for (unsigned k = 0; k < s->ifexpr_vec.length (); ++k) + ifexpr_vec.safe_push (replace_op_in_c_expr (s->ifexpr_vec[k], user_id, opers[i])); simplify *ns = new simplify (s->name, match_op, s->match_location, - result_op, s->result_location, s->ifexpr_vec); + result_op, s->result_location, ifexpr_vec); simplifiers.safe_push (ns); }