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]

Fix problem with store motion in gcse.c


This was discussed a while ago, with no real resolution.

This is a fix for ACATS test c95072a.  What's going on is that gcse
is trying to move a store onto an abnormal edge by moving it to the block
that is the destination of that edge. But that's not valid because it's
moving the store to a block where it wasn't previously.

Dan and I spent time trying to modify the data structures to avoid the
attempt to move the store if it would be placed on an abnormal edge, but
couldn't find any way to do it.  So I did this, which is a bit of a kludge,
but direct in the sense that it simply doesn't move such a store.

Does this seem a reasonable approach?

Tested on x86_64-linux-gnu.

2004-11-24  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>

	* gcse.c (insert_store): Error if try to insert store on abnormal edge.
	(store_motion): Don't move store if any edge we'd want to move it
	to is abnormal.

*** gcse.c	23 Nov 2004 19:55:15 -0000	1.323
--- gcse.c	24 Nov 2004 22:59:25 -0000
*************** pre_edge_insert (struct edge_list *edge_
*** 4220,4224 ****
  			   now.  */
  
! 			if ((eg->flags & EDGE_ABNORMAL) == EDGE_ABNORMAL)
  			  insert_insn_end_bb (index_map[j], bb, 0);
  			else
--- 4220,4224 ----
  			   now.  */
  
! 			if (eg->flags & EDGE_ABNORMAL)
  			  insert_insn_end_bb (index_map[j], bb, 0);
  			else
*************** insert_store (struct ls_expr * expr, edg
*** 6221,6231 ****
      }
  
!   /* We can't insert on this edge, so we'll insert at the head of the
!      successors block.  See Morgan, sec 10.5.  */
!   if ((e->flags & EDGE_ABNORMAL) == EDGE_ABNORMAL)
!     {
!       insert_insn_start_bb (insn, bb);
!       return 0;
!     }
  
    insert_insn_on_edge (insn, e);
--- 6221,6227 ----
      }
  
!   /* We can't put stores in the front of blocks pointed to by abnormal
!      edges since that may put a store where one didn't used to be.  */
!   gcc_assert (!(e->flags & EDGE_ABNORMAL));
  
    insert_insn_on_edge (insn, e);
*************** store_motion (void)
*** 6491,6494 ****
--- 6487,6509 ----
    for (ptr = first_ls_expr (); ptr != NULL; ptr = next_ls_expr (ptr))
      {
+       /* If any of the edges we have above are abnormal, we can't move this
+ 	 store.  */
+       for (x = NUM_EDGES (edge_list) - 1; x >= 0; x--)
+ 	if (TEST_BIT (pre_insert_map[x], ptr->index)
+ 	    && (INDEX_EDGE (edge_list, x)->flags & EDGE_ABNORMAL))
+ 	  break;
+ 
+       if (x >= 0)
+ 	{
+ 	  if (gcse_file != NULL)
+ 	    fprintf (gcse_file,
+ 		     "Can't replace store %d: abnormal edge from %d to %d\n",
+ 		     ptr->index, INDEX_EDGE (edge_list, x)->src->index,
+ 		     INDEX_EDGE (edge_list, x)->dest->index);
+ 	  continue;
+ 	}
+ 		      
+       /* Now we want to insert the new stores which are going to be needed.  */
+ 
        FOR_EACH_BB (bb)
  	if (TEST_BIT (pre_delete_map[bb->index], ptr->index))


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