public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Use a VEC for the list of conditional equivalences in DOM
@ 2010-08-17  9:56 Richard Guenther
  0 siblings, 0 replies; only message in thread
From: Richard Guenther @ 2010-08-17  9:56 UTC (permalink / raw)
  To: gcc-patches


This will make the code easier to understand and extend.  I'm touching
it because of the cond-expr predicate stuff.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

2010-08-17  Richard Guenther  <rguenther@suse.de>

	* tree-ssa-dom.c (struct edge_info): Use a VEC for the
	list of conditional equivalences.
	(free_all_edge_infos): Adjust.
	(record_equivalences_from_incoming_edge): Likewise.
	(record_cond): Likewise.
	(build_and_record_new_cond): Likewise.
	(record_conditions): Likewise.
	(dom_opt_leave_block): Likewise.

Index: gcc/tree-ssa-dom.c
===================================================================
*** gcc/tree-ssa-dom.c	(revision 163281)
--- gcc/tree-ssa-dom.c	(working copy)
*************** struct hashable_expr
*** 71,81 ****
  /* Structure for recording known values of a conditional expression
     at the exits from its block.  */
  
! struct cond_equivalence
  {
    struct hashable_expr cond;
    tree value;
! };
  
  /* Structure for recording edge equivalences as well as any pending
     edge redirections during the dominator optimizer.
--- 71,84 ----
  /* Structure for recording known values of a conditional expression
     at the exits from its block.  */
  
! typedef struct cond_equivalence_s
  {
    struct hashable_expr cond;
    tree value;
! } cond_equivalence;
! 
! DEF_VEC_O(cond_equivalence);
! DEF_VEC_ALLOC_O(cond_equivalence,heap);
  
  /* Structure for recording edge equivalences as well as any pending
     edge redirections during the dominator optimizer.
*************** struct edge_info
*** 99,109 ****
    tree rhs;
  
    /* Traversing an edge may also indicate one or more particular conditions
!      are true or false.  The number of recorded conditions can vary, but
!      can be determined by the condition's code.  So we have an array
!      and its maximum index rather than use a varray.  */
!   struct cond_equivalence *cond_equivalences;
!   unsigned int max_cond_equivalences;
  };
  
  /* Hash table with expressions made available during the renaming process.
--- 102,109 ----
    tree rhs;
  
    /* Traversing an edge may also indicate one or more particular conditions
!      are true or false.  */
!   VEC(cond_equivalence, heap) *cond_equivalences;
  };
  
  /* Hash table with expressions made available during the renaming process.
*************** static hashval_t avail_expr_hash (const
*** 179,185 ****
  static hashval_t real_avail_expr_hash (const void *);
  static int avail_expr_eq (const void *, const void *);
  static void htab_statistics (FILE *, htab_t);
! static void record_cond (struct cond_equivalence *);
  static void record_const_or_copy (tree, tree);
  static void record_equality (tree, tree);
  static void record_equivalences_from_phis (basic_block);
--- 179,185 ----
  static hashval_t real_avail_expr_hash (const void *);
  static int avail_expr_eq (const void *, const void *);
  static void htab_statistics (FILE *, htab_t);
! static void record_cond (cond_equivalence *);
  static void record_const_or_copy (tree, tree);
  static void record_equality (tree, tree);
  static void record_equivalences_from_phis (basic_block);
*************** free_all_edge_infos (void)
*** 636,642 ****
  	  if (edge_info)
  	    {
  	      if (edge_info->cond_equivalences)
! 		free (edge_info->cond_equivalences);
  	      free (edge_info);
  	      e->aux = NULL;
  	    }
--- 636,642 ----
  	  if (edge_info)
  	    {
  	      if (edge_info->cond_equivalences)
! 		VEC_free (cond_equivalence, heap, edge_info->cond_equivalences);
  	      free (edge_info);
  	      e->aux = NULL;
  	    }
*************** record_equivalences_from_incoming_edge (
*** 1059,1072 ****
  	{
  	  tree lhs = edge_info->lhs;
  	  tree rhs = edge_info->rhs;
! 	  struct cond_equivalence *cond_equivalences = edge_info->cond_equivalences;
  
  	  if (lhs)
  	    record_equality (lhs, rhs);
  
! 	  if (cond_equivalences)
!             for (i = 0; i < edge_info->max_cond_equivalences; i++)
!               record_cond (&cond_equivalences[i]);
  	}
      }
  }
--- 1059,1072 ----
  	{
  	  tree lhs = edge_info->lhs;
  	  tree rhs = edge_info->rhs;
! 	  cond_equivalence *eq;
  
  	  if (lhs)
  	    record_equality (lhs, rhs);
  
! 	  for (i = 0; VEC_iterate (cond_equivalence,
! 				   edge_info->cond_equivalences, i, eq); ++i)
! 	    record_cond (eq);
  	}
      }
  }
*************** htab_statistics (FILE *file, htab_t htab
*** 1114,1120 ****
     boolean value.  */
  
  static void
! record_cond (struct cond_equivalence *p)
  {
    struct expr_hash_elt *element = XCNEW (struct expr_hash_elt);
    void **slot;
--- 1114,1120 ----
     boolean value.  */
  
  static void
! record_cond (cond_equivalence *p)
  {
    struct expr_hash_elt *element = XCNEW (struct expr_hash_elt);
    void **slot;
*************** record_cond (struct cond_equivalence *p)
*** 1140,1153 ****
  }
  
  /* Build a cond_equivalence record indicating that the comparison
!    CODE holds between operands OP0 and OP1.  */
  
  static void
  build_and_record_new_cond (enum tree_code code,
                             tree op0, tree op1,
!                            struct cond_equivalence *p)
  {
!   struct hashable_expr *cond = &p->cond;
  
    gcc_assert (TREE_CODE_CLASS (code) == tcc_comparison);
  
--- 1140,1154 ----
  }
  
  /* Build a cond_equivalence record indicating that the comparison
!    CODE holds between operands OP0 and OP1 and push it to **P.  */
  
  static void
  build_and_record_new_cond (enum tree_code code,
                             tree op0, tree op1,
!                            VEC(cond_equivalence, heap) **p)
  {
!   cond_equivalence c;
!   struct hashable_expr *cond = &c.cond;
  
    gcc_assert (TREE_CODE_CLASS (code) == tcc_comparison);
  
*************** build_and_record_new_cond (enum tree_cod
*** 1157,1163 ****
    cond->ops.binary.opnd0 = op0;
    cond->ops.binary.opnd1 = op1;
  
!   p->value = boolean_true_node;
  }
  
  /* Record that COND is true and INVERTED is false into the edge information
--- 1158,1165 ----
    cond->ops.binary.opnd0 = op0;
    cond->ops.binary.opnd1 = op1;
  
!   c.value = boolean_true_node;
!   VEC_safe_push (cond_equivalence, heap, *p, &c);
  }
  
  /* Record that COND is true and INVERTED is false into the edge information
*************** static void
*** 1170,1175 ****
--- 1172,1178 ----
  record_conditions (struct edge_info *edge_info, tree cond, tree inverted)
  {
    tree op0, op1;
+   cond_equivalence c;
  
    if (!COMPARISON_CLASS_P (cond))
      return;
*************** record_conditions (struct edge_info *edg
*** 1183,1307 ****
      case GT_EXPR:
        if (FLOAT_TYPE_P (TREE_TYPE (op0)))
  	{
- 	  edge_info->max_cond_equivalences = 6;
- 	  edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 6);
  	  build_and_record_new_cond (ORDERED_EXPR, op0, op1,
! 				     &edge_info->cond_equivalences[4]);
  	  build_and_record_new_cond (LTGT_EXPR, op0, op1,
! 				     &edge_info->cond_equivalences[5]);
! 	}
!       else
!         {
!           edge_info->max_cond_equivalences = 4;
! 	  edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 4);
  	}
  
        build_and_record_new_cond ((TREE_CODE (cond) == LT_EXPR
  				  ? LE_EXPR : GE_EXPR),
! 				 op0, op1, &edge_info->cond_equivalences[2]);
        build_and_record_new_cond (NE_EXPR, op0, op1,
! 				 &edge_info->cond_equivalences[3]);
        break;
  
      case GE_EXPR:
      case LE_EXPR:
        if (FLOAT_TYPE_P (TREE_TYPE (op0)))
  	{
- 	  edge_info->max_cond_equivalences = 3;
- 	  edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 3);
  	  build_and_record_new_cond (ORDERED_EXPR, op0, op1,
! 				     &edge_info->cond_equivalences[2]);
! 	}
!       else
! 	{
! 	  edge_info->max_cond_equivalences = 2;
! 	  edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 2);
  	}
        break;
  
      case EQ_EXPR:
        if (FLOAT_TYPE_P (TREE_TYPE (op0)))
  	{
- 	  edge_info->max_cond_equivalences = 5;
- 	  edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 5);
  	  build_and_record_new_cond (ORDERED_EXPR, op0, op1,
! 				     &edge_info->cond_equivalences[4]);
! 	}
!       else
! 	{
! 	  edge_info->max_cond_equivalences = 4;
! 	  edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 4);
  	}
        build_and_record_new_cond (LE_EXPR, op0, op1,
! 				 &edge_info->cond_equivalences[2]);
        build_and_record_new_cond (GE_EXPR, op0, op1,
! 				 &edge_info->cond_equivalences[3]);
        break;
  
      case UNORDERED_EXPR:
-       edge_info->max_cond_equivalences = 8;
-       edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 8);
        build_and_record_new_cond (NE_EXPR, op0, op1,
! 				 &edge_info->cond_equivalences[2]);
        build_and_record_new_cond (UNLE_EXPR, op0, op1,
! 				 &edge_info->cond_equivalences[3]);
        build_and_record_new_cond (UNGE_EXPR, op0, op1,
! 				 &edge_info->cond_equivalences[4]);
        build_and_record_new_cond (UNEQ_EXPR, op0, op1,
! 				 &edge_info->cond_equivalences[5]);
        build_and_record_new_cond (UNLT_EXPR, op0, op1,
! 				 &edge_info->cond_equivalences[6]);
        build_and_record_new_cond (UNGT_EXPR, op0, op1,
! 				 &edge_info->cond_equivalences[7]);
        break;
  
      case UNLT_EXPR:
      case UNGT_EXPR:
-       edge_info->max_cond_equivalences = 4;
-       edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 4);
        build_and_record_new_cond ((TREE_CODE (cond) == UNLT_EXPR
  				  ? UNLE_EXPR : UNGE_EXPR),
! 				 op0, op1, &edge_info->cond_equivalences[2]);
        build_and_record_new_cond (NE_EXPR, op0, op1,
! 				 &edge_info->cond_equivalences[3]);
        break;
  
      case UNEQ_EXPR:
-       edge_info->max_cond_equivalences = 4;
-       edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 4);
        build_and_record_new_cond (UNLE_EXPR, op0, op1,
! 				 &edge_info->cond_equivalences[2]);
        build_and_record_new_cond (UNGE_EXPR, op0, op1,
! 				 &edge_info->cond_equivalences[3]);
        break;
  
      case LTGT_EXPR:
-       edge_info->max_cond_equivalences = 4;
-       edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 4);
        build_and_record_new_cond (NE_EXPR, op0, op1,
! 				 &edge_info->cond_equivalences[2]);
        build_and_record_new_cond (ORDERED_EXPR, op0, op1,
! 				 &edge_info->cond_equivalences[3]);
        break;
  
      default:
-       edge_info->max_cond_equivalences = 2;
-       edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 2);
        break;
      }
  
    /* Now store the original true and false conditions into the first
       two slots.  */
!   initialize_expr_from_cond (cond, &edge_info->cond_equivalences[0].cond);
!   edge_info->cond_equivalences[0].value = boolean_true_node;
  
    /* It is possible for INVERTED to be the negation of a comparison,
       and not a valid RHS or GIMPLE_COND condition.  This happens because
       invert_truthvalue may return such an expression when asked to invert
       a floating-point comparison.  These comparisons are not assumed to
       obey the trichotomy law.  */
!   initialize_expr_from_cond (inverted, &edge_info->cond_equivalences[1].cond);
!   edge_info->cond_equivalences[1].value = boolean_false_node;
  }
  
  /* A helper function for record_const_or_copy and record_equality.
--- 1186,1281 ----
      case GT_EXPR:
        if (FLOAT_TYPE_P (TREE_TYPE (op0)))
  	{
  	  build_and_record_new_cond (ORDERED_EXPR, op0, op1,
! 				     &edge_info->cond_equivalences);
  	  build_and_record_new_cond (LTGT_EXPR, op0, op1,
! 				     &edge_info->cond_equivalences);
  	}
  
        build_and_record_new_cond ((TREE_CODE (cond) == LT_EXPR
  				  ? LE_EXPR : GE_EXPR),
! 				 op0, op1, &edge_info->cond_equivalences);
        build_and_record_new_cond (NE_EXPR, op0, op1,
! 				 &edge_info->cond_equivalences);
        break;
  
      case GE_EXPR:
      case LE_EXPR:
        if (FLOAT_TYPE_P (TREE_TYPE (op0)))
  	{
  	  build_and_record_new_cond (ORDERED_EXPR, op0, op1,
! 				     &edge_info->cond_equivalences);
  	}
        break;
  
      case EQ_EXPR:
        if (FLOAT_TYPE_P (TREE_TYPE (op0)))
  	{
  	  build_and_record_new_cond (ORDERED_EXPR, op0, op1,
! 				     &edge_info->cond_equivalences);
  	}
        build_and_record_new_cond (LE_EXPR, op0, op1,
! 				 &edge_info->cond_equivalences);
        build_and_record_new_cond (GE_EXPR, op0, op1,
! 				 &edge_info->cond_equivalences);
        break;
  
      case UNORDERED_EXPR:
        build_and_record_new_cond (NE_EXPR, op0, op1,
! 				 &edge_info->cond_equivalences);
        build_and_record_new_cond (UNLE_EXPR, op0, op1,
! 				 &edge_info->cond_equivalences);
        build_and_record_new_cond (UNGE_EXPR, op0, op1,
! 				 &edge_info->cond_equivalences);
        build_and_record_new_cond (UNEQ_EXPR, op0, op1,
! 				 &edge_info->cond_equivalences);
        build_and_record_new_cond (UNLT_EXPR, op0, op1,
! 				 &edge_info->cond_equivalences);
        build_and_record_new_cond (UNGT_EXPR, op0, op1,
! 				 &edge_info->cond_equivalences);
        break;
  
      case UNLT_EXPR:
      case UNGT_EXPR:
        build_and_record_new_cond ((TREE_CODE (cond) == UNLT_EXPR
  				  ? UNLE_EXPR : UNGE_EXPR),
! 				 op0, op1, &edge_info->cond_equivalences);
        build_and_record_new_cond (NE_EXPR, op0, op1,
! 				 &edge_info->cond_equivalences);
        break;
  
      case UNEQ_EXPR:
        build_and_record_new_cond (UNLE_EXPR, op0, op1,
! 				 &edge_info->cond_equivalences);
        build_and_record_new_cond (UNGE_EXPR, op0, op1,
! 				 &edge_info->cond_equivalences);
        break;
  
      case LTGT_EXPR:
        build_and_record_new_cond (NE_EXPR, op0, op1,
! 				 &edge_info->cond_equivalences);
        build_and_record_new_cond (ORDERED_EXPR, op0, op1,
! 				 &edge_info->cond_equivalences);
        break;
  
      default:
        break;
      }
  
    /* Now store the original true and false conditions into the first
       two slots.  */
!   initialize_expr_from_cond (cond, &c.cond);
!   c.value = boolean_true_node;
!   VEC_safe_push (cond_equivalence, heap, edge_info->cond_equivalences, &c);
  
    /* It is possible for INVERTED to be the negation of a comparison,
       and not a valid RHS or GIMPLE_COND condition.  This happens because
       invert_truthvalue may return such an expression when asked to invert
       a floating-point comparison.  These comparisons are not assumed to
       obey the trichotomy law.  */
!   initialize_expr_from_cond (inverted, &c.cond);
!   c.value = boolean_false_node;
!   VEC_safe_push (cond_equivalence, heap, edge_info->cond_equivalences, &c);
  }
  
  /* A helper function for record_const_or_copy and record_equality.
*************** dom_opt_leave_block (struct dom_walk_dat
*** 1749,1755 ****
  	     our equivalence tables.  */
  	  if (edge_info)
  	    {
! 	      struct cond_equivalence *cond_equivalences = edge_info->cond_equivalences;
  	      tree lhs = edge_info->lhs;
  	      tree rhs = edge_info->rhs;
  
--- 1723,1729 ----
  	     our equivalence tables.  */
  	  if (edge_info)
  	    {
! 	      cond_equivalence *eq;
  	      tree lhs = edge_info->lhs;
  	      tree rhs = edge_info->rhs;
  
*************** dom_opt_leave_block (struct dom_walk_dat
*** 1759,1767 ****
  
  	      /* If we have 0 = COND or 1 = COND equivalences, record them
  		 into our expression hash tables.  */
! 	      if (cond_equivalences)
! 		for (i = 0; i < edge_info->max_cond_equivalences; i++)
!                   record_cond (&cond_equivalences[i]);
  	    }
  
  	  dom_thread_across_edge (walk_data, true_edge);
--- 1733,1741 ----
  
  	      /* If we have 0 = COND or 1 = COND equivalences, record them
  		 into our expression hash tables.  */
! 	      for (i = 0; VEC_iterate (cond_equivalence,
! 				       edge_info->cond_equivalences, i, eq); ++i)
! 		record_cond (eq);
  	    }
  
  	  dom_thread_across_edge (walk_data, true_edge);
*************** dom_opt_leave_block (struct dom_walk_dat
*** 1784,1790 ****
  	     our equivalence tables.  */
  	  if (edge_info)
  	    {
! 	      struct cond_equivalence *cond_equivalences = edge_info->cond_equivalences;
  	      tree lhs = edge_info->lhs;
  	      tree rhs = edge_info->rhs;
  
--- 1758,1764 ----
  	     our equivalence tables.  */
  	  if (edge_info)
  	    {
! 	      cond_equivalence *eq;
  	      tree lhs = edge_info->lhs;
  	      tree rhs = edge_info->rhs;
  
*************** dom_opt_leave_block (struct dom_walk_dat
*** 1794,1802 ****
  
  	      /* If we have 0 = COND or 1 = COND equivalences, record them
  		 into our expression hash tables.  */
! 	      if (cond_equivalences)
! 		for (i = 0; i < edge_info->max_cond_equivalences; i++)
!                   record_cond (&cond_equivalences[i]);
  	    }
  
  	  /* Now thread the edge.  */
--- 1768,1776 ----
  
  	      /* If we have 0 = COND or 1 = COND equivalences, record them
  		 into our expression hash tables.  */
! 	      for (i = 0; VEC_iterate (cond_equivalence,
! 				       edge_info->cond_equivalences, i, eq); ++i)
! 		record_cond (eq);
  	    }
  
  	  /* Now thread the edge.  */

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2010-08-17  9:53 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-17  9:56 [PATCH] Use a VEC for the list of conditional equivalences in DOM Richard Guenther

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).