This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [GSoC] replacing op in c_expr


On Tue, Jul 29, 2014 at 4:29 PM, Richard Biener
<richard.guenther@gmail.com> wrote:
> On Mon, Jul 28, 2014 at 10:02 PM, Prathamesh Kulkarni
> <bilbotheelffriend@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]) ?
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.

* 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 213343)
+++ genmatch.c	(working copy)
@@ -238,11 +238,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);
@@ -641,6 +650,31 @@ replace_id (operand *o, const char *user
 
   return ne;
 }
+
+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);
+}
   
 void
 check_no_user_id (operand *o)
@@ -742,6 +776,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.  */
@@ -1717,6 +1756,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.  */
@@ -1972,7 +2016,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)
@@ -1997,7 +2041,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);
@@ -2134,10 +2178,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);
 	    }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]