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 reg notes after store motion


This is an update to Zdenek's patch originally written to resolve the
problems noted in this thread.

http://gcc.gnu.org/ml/gcc-patches/2003-04/msg00086.html

It turns out the problem Zdenek was fixing is triggered with the existing
store-motion implementation on the tree-ssa branch.

Anyway, all I've done is updated some of the comments and dealt with
minor changes in function signatures in gcse.c


Bootstrapped and regression tested.

	* gcse.c (remove_reachable_equiv_notes): New.
	(replace_store_insn): Call it.  Update antic list.
	(store_killed_in_insn): Take REG_EQUAL notes into account.
	(build_store_vectors, delete_store): Add parameter to
	replace_store_insn call.

Index: gcse.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gcse.c,v
retrieving revision 1.273
diff -c -3 -p -r1.273 gcse.c
*** gcse.c	15 Sep 2003 01:55:49 -0000	1.273
--- gcse.c	15 Sep 2003 22:58:43 -0000
*************** static bool store_killed_before (rtx, rt
*** 692,698 ****
  static void build_store_vectors (void);
  static void insert_insn_start_bb (rtx, basic_block);
  static int insert_store (struct ls_expr *, edge);
! static void replace_store_insn (rtx, rtx, basic_block);
  static void delete_store (struct ls_expr *, basic_block);
  static void free_store_memory (void);
  static void store_motion (void);
--- 692,699 ----
  static void build_store_vectors (void);
  static void insert_insn_start_bb (rtx, basic_block);
  static int insert_store (struct ls_expr *, edge);
! static void remove_reachable_equiv_notes (basic_block, struct ls_expr *);
! static void replace_store_insn (rtx, rtx, basic_block, struct ls_expr *);
  static void delete_store (struct ls_expr *, basic_block);
  static void free_store_memory (void);
  static void store_motion (void);
*************** find_loads (rtx x, rtx store_pattern, in
*** 7254,7260 ****
  static bool
  store_killed_in_insn (rtx x, rtx x_regs, rtx insn, int after)
  {
!   rtx reg, base;
  
    if (!INSN_P (insn))
      return false;
--- 7255,7261 ----
  static bool
  store_killed_in_insn (rtx x, rtx x_regs, rtx insn, int after)
  {
!   rtx reg, base, note;
  
    if (!INSN_P (insn))
      return false;
*************** store_killed_in_insn (rtx x, rtx x_regs,
*** 7305,7314 ****
  		return true;
  	    }
  	}
!       return find_loads (SET_SRC (pat), x, after);
      }
!   else
!     return find_loads (PATTERN (insn), x, after);
  }
  
  /* Returns true if the expression X is loaded or clobbered on or after INSN
--- 7306,7331 ----
  		return true;
  	    }
  	}
!       if (find_loads (SET_SRC (pat), x, after))
! 	return true;
      }
!   else if (find_loads (PATTERN (insn), x, after))
!     return true;
! 
!   /* If this insn has a REG_EQUAL or REG_EQUIV note referencing a memory
!      location aliased with X, then this insn kills X.  */
!   note = find_reg_equal_equiv_note (insn);
!   if (! note)
!     return false;
!   note = XEXP (note, 0);
! 
!   /* However, if the note represents a must alias rather than a may
!      alias relationship, then it does not kill X.  */
!   if (expr_equiv_p (note, x))
!     return false;
! 
!   /* See if there are any aliased loads in the note.  */
!   return find_loads (note, x, after);
  }
  
  /* Returns true if the expression X is loaded or clobbered on or after INSN
*************** build_store_vectors (void)
*** 7396,7402 ****
  	      rtx r = gen_reg_rtx (GET_MODE (ptr->pattern));
  	      if (gcse_file)
  		fprintf (gcse_file, "Removing redundant store:\n");
! 	      replace_store_insn (r, XEXP (st, 0), bb);
  	      continue;
  	    }
  	  SET_BIT (ae_gen[bb->index], ptr->index);
--- 7413,7419 ----
  	      rtx r = gen_reg_rtx (GET_MODE (ptr->pattern));
  	      if (gcse_file)
  		fprintf (gcse_file, "Removing redundant store:\n");
! 	      replace_store_insn (r, XEXP (st, 0), bb, ptr);
  	      continue;
  	    }
  	  SET_BIT (ae_gen[bb->index], ptr->index);
*************** insert_store (struct ls_expr * expr, edg
*** 7551,7563 ****
    return 1;
  }
  
  /* This routine will replace a store with a SET to a specified register.  */
  
  static void
! replace_store_insn (rtx reg, rtx del, basic_block bb)
  {
!   rtx insn;
  
    insn = gen_move_insn (reg, SET_SRC (single_set (del)));
    insn = emit_insn_after (insn, del);
  
--- 7568,7654 ----
    return 1;
  }
  
+ /* Remove any REG_EQUAL or REG_EQUIV notes containing a reference to the
+    memory location in SMEXPR set in basic block BB.
+ 
+    This could be rather expensive.  */
+ 
+ static void
+ remove_reachable_equiv_notes (basic_block bb, struct ls_expr *smexpr)
+ {
+   edge *stack = xmalloc (sizeof (edge) * n_basic_blocks), act;
+   sbitmap visited = sbitmap_alloc (last_basic_block);
+   int stack_top = 0;
+   rtx last, insn, note;
+   rtx mem = smexpr->pattern;
+ 
+   sbitmap_zero (visited);
+   act = bb->succ;
+ 
+   while (1)
+     {
+       if (!act)
+ 	{
+ 	  if (!stack_top)
+ 	    {
+ 	      free (stack);
+ 	      sbitmap_free (visited);
+ 	      return;
+ 	    }
+ 	  act = stack[--stack_top];
+ 	}
+       bb = act->dest;
+       
+       if (bb == EXIT_BLOCK_PTR
+ 	  || TEST_BIT (visited, bb->index)
+ 	  || TEST_BIT (ae_kill[bb->index], smexpr->index))
+ 	{
+ 	  act = act->succ_next;
+ 	  continue;
+ 	}
+       SET_BIT (visited, bb->index);
+ 
+       if (TEST_BIT (st_antloc[bb->index], smexpr->index))
+ 	{
+ 	  for (last = ANTIC_STORE_LIST (smexpr);
+ 	       BLOCK_FOR_INSN (XEXP (last, 0)) != bb;
+ 	       last = XEXP (last, 1))
+ 	    continue;
+ 	  last = XEXP (last, 0);
+ 	}
+       else
+ 	last = NEXT_INSN (bb->end);
+   
+       for (insn = bb->head; insn != last; insn = NEXT_INSN (insn))
+ 	if (INSN_P (insn))
+ 	  {
+ 	    note = find_reg_equal_equiv_note (insn);
+ 	    if (!note || !expr_equiv_p (XEXP (note, 0), mem))
+ 	      continue;
+ 
+ 	    if (gcse_file)
+ 	      fprintf (gcse_file, "STORE_MOTION  drop REG_EQUAL note at insn %d:\n",
+ 		       INSN_UID (insn));
+ 	    remove_note (insn, note);
+ 	  }
+       act = act->succ_next;
+       if (bb->succ)
+ 	{
+ 	  if (act)
+ 	    stack[stack_top++] = act;
+ 	  act = bb->succ;
+ 	}
+     }
+ }
+ 
  /* This routine will replace a store with a SET to a specified register.  */
  
  static void
! replace_store_insn (rtx reg, rtx del, basic_block bb, struct ls_expr *smexpr)
  {
!   rtx insn, mem, note, set, ptr;
  
+   mem = smexpr->pattern;
    insn = gen_move_insn (reg, SET_SRC (single_set (del)));
    insn = emit_insn_after (insn, del);
  
*************** replace_store_insn (rtx reg, rtx del, ba
*** 7571,7577 ****
--- 7662,7696 ----
        fprintf (gcse_file, "\n");
      }
  
+   for (ptr = ANTIC_STORE_LIST (smexpr); ptr; ptr = XEXP (ptr, 1))
+     if (XEXP (ptr, 0) == del)
+       {
+ 	XEXP (ptr, 0) = insn;
+ 	break;
+       }
    delete_insn (del);
+ 
+   /* Now we must handle REG_EQUAL notes whose contents is equal to the mem;
+      they are no longer accurate provided that they are reached by this
+      definition, so drop them.  */
+   for (; insn != NEXT_INSN (bb->end); insn = NEXT_INSN (insn))
+     if (INSN_P (insn))
+       {
+ 	set = single_set (insn);
+ 	if (!set)
+ 	  continue;
+ 	if (expr_equiv_p (SET_DEST (set), mem))
+ 	  return;
+ 	note = find_reg_equal_equiv_note (insn);
+ 	if (!note || !expr_equiv_p (XEXP (note, 0), mem))
+ 	  continue;
+ 
+ 	if (gcse_file)
+ 	  fprintf (gcse_file, "STORE_MOTION  drop REG_EQUAL note at insn %d:\n",
+ 		   INSN_UID (insn));
+ 	remove_note (insn, note);
+       }
+   remove_reachable_equiv_notes (bb, smexpr);
  }
  
  
*************** delete_store (struct ls_expr * expr, bas
*** 7595,7601 ****
  	{
  	  /* We know there is only one since we deleted redundant
  	     ones during the available computation.  */
! 	  replace_store_insn (reg, del, bb);
  	  break;
  	}
      }
--- 7714,7720 ----
  	{
  	  /* We know there is only one since we deleted redundant
  	     ones during the available computation.  */
! 	  replace_store_insn (reg, del, bb, expr);
  	  break;
  	}
      }





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