This is the mail archive of the gcc-patches@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]

[PATCH][match-and-simplify][1/2] Delay for lowering


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


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