This patch factors expression checking for GIMPLE.

Generates code as:
if (TREE_CODE (opname) == SSA_NAME)
{
  gimple def_stmt = SSA_NAME_DEF_STMT (opname);
  if (is_gimple_assign (def_stmt))
  {
    if (gimple_assign_rhs_code (def_stmt) == <expr-code1>)
      {
         ....
      }
    if (gimple_assign_rhs_code (def_stmt) == <expr-code2>)
      {
         ....
      }
   }
}

We cannot use switch-case, for convert/nop since
we use CONVERT_EXPR_CODE_P, so i used if stmt.

Unfortunately, back-tracking is still done. I shall look into that.

* genmatch.c (dt_node::get_expr_code): New member function.
     (dt_node::is_gimple_expr): Likewise.
     (dt_node::is_gimple_fn): Likewise.
     (dt_operand::kids_type): New struct.
     (dt_operand::gen_gimple_expr): Remove.
     (dt_operand::gen_gimple_expr_expr): Remove 2nd argument and
change return        type to unsigned. Adjust code-gen for
expressions.
     (dt_operand::gen_gimple_expr_fn): Remove 2nd argument and change
return type to unsigned.
     (dt_operand::grok_kids): New member function.
     (dt_operand::gen_gimple_kids): Likewise.
     (dt_operand::gen_gimple): Adjust code-gen for gimple expressions.
Call dt_operand::gen_gimple_kids.
     (decision_tree::gen_gimple): Call dt_operand::gen_gimple_kids.

Thanks and Regards,
Prathamesh
Index: gcc/genmatch.c
===================================================================
--- gcc/genmatch.c	(revision 211973)
+++ gcc/genmatch.c	(working copy)
@@ -325,6 +325,10 @@ struct dt_node
 
   virtual void gen_gimple (FILE *) {}
   virtual void gen_generic (FILE *) {}
+  
+  bool get_expr_code (enum tree_code&);
+  bool is_gimple_expr ();
+  bool is_gimple_fn ();
 };
 
 struct dt_operand: public dt_node
@@ -333,6 +337,15 @@ struct dt_operand: public dt_node
   dt_operand *match_dop;
   dt_operand *parent;
   unsigned pos;
+
+  struct kids_type {
+    vec<dt_node *> gimple_exprs;
+    vec<dt_node *> fns;
+    vec<dt_node *> others;
+    dt_node *true_operand;
+  
+    kids_type (): gimple_exprs (vNULL), fns (vNULL), others (vNULL), true_operand (0) {}
+  };
  
   dt_operand (enum dt_type type, operand *op_, dt_operand *match_dop_, dt_operand *parent_ = 0, unsigned pos_ = 0)
 	: dt_node (type), op (op_), match_dop (match_dop_), parent (parent_), pos (pos_) {} 
@@ -342,9 +355,8 @@ struct dt_operand: public dt_node
   unsigned gen_predicate (FILE *, const char *);
   unsigned gen_match_op (FILE *, const char *);
 
-  unsigned gen_gimple_expr (FILE *, const char *);
-  void gen_gimple_expr_expr (FILE *, expr *);
-  void gen_gimple_expr_fn (FILE *, expr *);
+  unsigned gen_gimple_expr_expr (FILE *); 
+  unsigned gen_gimple_expr_fn (FILE *);
 
   unsigned gen_generic_expr (FILE *, const char *, bool);
   void gen_generic_expr_expr (FILE *, expr *, const char *, bool);
@@ -352,6 +364,9 @@ struct dt_operand: public dt_node
 
   char *get_name (char *);
   void gen_opname (char *, unsigned);
+
+  void grok_kids(kids_type&);
+  void gen_gimple_kids (FILE *);
 };
 
 
@@ -906,9 +921,10 @@ dt_operand::gen_match_op (FILE *f, const
   return 1;
 }
 
-void
-dt_operand::gen_gimple_expr_fn (FILE *f, expr *e)
+unsigned
+dt_operand::gen_gimple_expr_fn (FILE *f) 
 {
+  expr *e = static_cast<expr *> (op);
   unsigned n_ops = e->ops.length ();
 
   fn_id *op = static_cast <fn_id *> (e->operation->op);
@@ -924,20 +940,22 @@ dt_operand::gen_gimple_expr_fn (FILE *f,
       fprintf (f, "if ((%s = do_valueize (valueize, %s)) != 0)\n", child_opname, child_opname);
       fprintf (f, "{\n");
     } 
+
+  return n_ops + 1;
 }
 
-void
-dt_operand::gen_gimple_expr_expr (FILE *f, expr *e)
+unsigned
+dt_operand::gen_gimple_expr_expr (FILE *f)
 {
+  expr *e = static_cast<expr *> (op);
   unsigned n_ops = e->ops.length (); 
 
   operator_id *op_id = static_cast <operator_id *> (e->operation->op);
   
   if (op_id->code == NOP_EXPR || op_id->code == CONVERT_EXPR)
-    fprintf (f, "if (is_gimple_assign (def_stmt)\n"
-	        "    && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))");
+    fprintf (f, " if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))");
   else
-    fprintf (f, "if (is_gimple_assign (def_stmt) && gimple_assign_rhs_code (def_stmt) == %s)\n", op_id->id);
+    fprintf (f, "if (gimple_assign_rhs_code (def_stmt) == %s)\n", op_id->id);
 
   fprintf (f, "{\n");
   
@@ -950,22 +968,9 @@ dt_operand::gen_gimple_expr_expr (FILE *
       fprintf (f, "if ((%s = do_valueize (valueize, %s)) != 0)\n", child_opname, child_opname);
       fprintf (f, "{\n");
     }      
-} 
-
-unsigned
-dt_operand::gen_gimple_expr (FILE *f, const char *opname)
-{
-  expr *e = static_cast<expr *> (op);
-
-  fprintf (f, "if (TREE_CODE (%s) == SSA_NAME)\n", opname);
-  fprintf (f, "{\n");
-  
-  fprintf (f, "gimple def_stmt = SSA_NAME_DEF_STMT (%s);\n", opname);
-  (e->operation->op->kind == id_base::CODE) ? gen_gimple_expr_expr (f, e) : gen_gimple_expr_fn (f, e);
-
-  return e->ops.length () + 2;
-}
 
+  return n_ops + 1;
+} 
 
 void
 dt_operand::gen_generic_expr_expr (FILE *f, expr *e, const char *opname,
@@ -1026,6 +1031,128 @@ dt_operand::gen_generic_expr (FILE *f, c
   return valueize ? e->ops.length () + 1 : 1;
 }
 
+bool
+dt_node::get_expr_code (enum tree_code& code)
+{
+
+  if (type != dt_node::DT_OPERAND)
+    return false;
+
+  dt_operand *dop = static_cast<dt_operand *> (this);
+  
+  if (dop->op->type != operand::OP_EXPR)
+    return false;
+
+  expr *e = static_cast<expr *> (dop->op);
+  if (e->operation->op->kind != id_base::CODE)
+    return false;
+
+  operator_id *opr = static_cast<operator_id *> (e->operation->op);
+  code = opr->code;
+  return true;
+}
+
+bool
+dt_node::is_gimple_expr ()
+{
+  enum tree_code code;
+
+  if (!get_expr_code (code))
+    return false;
+
+  if (code == REALPART_EXPR || code == IMAGPART_EXPR
+      || code == BIT_FIELD_REF || code == VIEW_CONVERT_EXPR)
+    return false;
+
+  dt_operand *dop = static_cast<dt_operand *> (this);
+
+  if (dop->parent->type != dt_operand::DT_OPERAND)
+    return true;
+
+  if (dop->parent->get_expr_code (code) && code == COND_EXPR && dop->pos == 0)
+    return false;
+
+  return true;
+}
+
+bool
+dt_node::is_gimple_fn ()
+{
+  if (type != dt_node::DT_OPERAND)
+    return false;
+  
+  dt_operand *dop = static_cast<dt_operand *> (this);
+  if (dop->op->type != operand::OP_EXPR)
+    return false;
+
+  expr *e = static_cast<expr *> (dop->op);
+  return e->operation->op->kind == id_base::FN;
+}
+
+void
+dt_operand::grok_kids (kids_type& ktype)
+{
+
+  for (unsigned i = 0; i < kids.length (); ++i)
+    {
+      if (kids[i]->is_gimple_expr ())
+	ktype.gimple_exprs.safe_push (kids[i]);
+      else if (kids[i]->is_gimple_fn ())
+	ktype.fns.safe_push (kids[i]);
+      else if (kids[i]->type == dt_node::DT_TRUE)
+	ktype.true_operand = kids[i];
+      else
+	ktype.others.safe_push (kids[i]);
+    }
+}
+
+void
+dt_operand::gen_gimple_kids (FILE *f)
+{
+  kids_type ktype;
+  grok_kids (ktype);
+
+  char buf[128];
+  char *kid_opname = buf;
+ 
+  unsigned exprs_len = ktype.gimple_exprs.length ();
+  unsigned fns_len = ktype.fns.length ();
+
+  if (exprs_len || fns_len)
+    {
+      if (exprs_len)
+	(static_cast<dt_operand *>(ktype.gimple_exprs[0]))->get_name (kid_opname);
+      else
+	(static_cast<dt_operand *>(ktype.fns[0]))->get_name (kid_opname);
+
+      fprintf (f, "if (TREE_CODE (%s) == SSA_NAME)\n", kid_opname);
+      fprintf (f, "{\n");
+      fprintf (f, "gimple def_stmt = SSA_NAME_DEF_STMT (%s);\n", kid_opname);
+
+      if (exprs_len)
+	{
+	  fprintf (f, "if (is_gimple_assign (def_stmt))\n");
+	  fprintf (f, "{\n");
+	  for (unsigned i = 0; i < exprs_len; ++i)
+	    {
+	      ktype.gimple_exprs[i]->gen_gimple (f);
+	    }
+	  fprintf (f, "}\n");
+	}
+  
+      for (unsigned i = 0; i < fns_len; ++i) 
+	ktype.fns[i]->gen_gimple (f);
+
+      fprintf (f, "}\n");
+    }
+  
+  for (unsigned i = 0; i < ktype.others.length (); ++i)
+    ktype.others[i]->gen_gimple (f);
+
+  if (ktype.true_operand)
+    ktype.true_operand->gen_gimple (f);
+}
+
 void
 dt_operand::gen_gimple (FILE *f)
 {
@@ -1044,24 +1171,12 @@ dt_operand::gen_gimple (FILE *f)
 	  break;
 
 	case operand::OP_EXPR:
-	{
-	  expr *e = static_cast<expr *> (op);
-  	  operator_id *op_id = static_cast <operator_id *> (e->operation->op);
-	  enum tree_code code = op_id->code;
-
-	  if (code == REALPART_EXPR || code == IMAGPART_EXPR || code == VIEW_CONVERT_EXPR || code == BIT_FIELD_REF)
-	    n_braces = gen_generic_expr (f, opname, true);
-
-	  // check for cond_expr, 0th operand -> generic
-	  else if (parent->type == dt_node::DT_OPERAND && parent->op->type == operand::OP_EXPR)
-	    {
-	      e = static_cast<expr *> (parent->op);
-	      op_id = static_cast <operator_id *> (e->operation->op);
-	      n_braces = (op_id->code == COND_EXPR && pos == 0) ? gen_generic_expr (f, opname, true) : gen_gimple_expr (f, opname);
-	    }
+	  if (is_gimple_expr ())
+	    n_braces = gen_gimple_expr_expr (f);
+	  else if (is_gimple_fn ())
+	    n_braces = gen_gimple_expr_fn (f);
 	  else
-	    n_braces = gen_gimple_expr (f, opname);
-	}
+	    n_braces = gen_generic_expr (f, opname, true);
 	  break;
 
 	default:
@@ -1074,14 +1189,11 @@ dt_operand::gen_gimple (FILE *f)
   else
     gcc_unreachable ();
 
-  unsigned i;
-
-  for (i = 0; i < kids.length (); ++i)
-    kids[i]->gen_gimple (f);
+  gen_gimple_kids (f);
 
-  for (i = 0; i < n_braces; ++i)
+  for (unsigned i = 0; i < n_braces; ++i)
     fprintf (f, "}\n");
-  
+
   fprintf (f, "}\n");
 }
 
@@ -1276,10 +1388,7 @@ decision_tree::gen_gimple (FILE *f)
 	    fprintf (f, "else ");
 	  fprintf (f, "if (code == %s)\n", e->operation->op->id);
 	  fprintf (f, "{\n");
-
-	  for (unsigned j = 0; j < dop->kids.length (); ++j)
-	    dop->kids[j]->gen_gimple (f);
-
+	  dop->gen_gimple_kids (f); 
 	  fprintf (f, "}\n");
 
 	  first = false;

Reply via email to