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] Fix a problem in lim store motion


Hello,

we were supplying a wrong loop to the set_level function if it was
called from store motion (when it needed to hoist invariants on that address
of a memory reference is dependent) -- instead of the loop to that the
reference belongs we were supplying a loop to that the hoisted statement
belongs.  This caused the ICE during compilation of Ada rts observed by
Richard Kenner.

Bootstrapped & regtested on i686.

Zdenek

	* tree-ssa-loop-im.c (force_move_till_expr, force_move_till):
	Take orig_loop argument and pass it to set_level.
	(schedule_sm): Pass the correct orig_loop to force_move_till.

Index: tree-ssa-loop-im.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-loop-im.c,v
retrieving revision 2.2
diff -c -3 -p -r2.2 tree-ssa-loop-im.c
*** tree-ssa-loop-im.c	28 Jul 2004 01:17:00 -0000	2.2
--- tree-ssa-loop-im.c	29 Jul 2004 08:43:59 -0000
*************** may_move_till (tree ref, tree *index, vo
*** 710,719 ****
  }
  
  /* Forces statements definining (invariant) SSA names in expression EXPR to be
!    moved out of the LOOP.  */
  
  static void
! force_move_till_expr (tree expr, struct loop *loop)
  {
    char class = TREE_CODE_CLASS (TREE_CODE (expr));
    unsigned i, nops;
--- 710,719 ----
  }
  
  /* Forces statements definining (invariant) SSA names in expression EXPR to be
!    moved out of the LOOP.  ORIG_LOOP is the loop in that EXPR is used.  */
  
  static void
! force_move_till_expr (tree expr, struct loop *orig_loop, struct loop *loop)
  {
    char class = TREE_CODE_CLASS (TREE_CODE (expr));
    unsigned i, nops;
*************** force_move_till_expr (tree expr, struct 
*** 724,730 ****
        if (IS_EMPTY_STMT (stmt))
  	return;
  
!       set_level (stmt, bb_for_stmt (stmt)->loop_father, loop);
        return;
      }
  
--- 724,730 ----
        if (IS_EMPTY_STMT (stmt))
  	return;
  
!       set_level (stmt, orig_loop, loop);
        return;
      }
  
*************** force_move_till_expr (tree expr, struct 
*** 736,759 ****
  
    nops = first_rtl_op (TREE_CODE (expr));
    for (i = 0; i < nops; i++)
!     force_move_till_expr (TREE_OPERAND (expr, i), loop);
  }
  
  /* Forces statement defining invariants in REF (and *INDEX) to be moved out of
!    the loop passed in DATA.  Callback for for_each_index.  */
  
  static bool
  force_move_till (tree ref, tree *index, void *data)
  {
    tree stmt;
  
    if (TREE_CODE (ref) == ARRAY_REF)
      {
        tree step = array_ref_element_size (ref);
        tree lbound = array_ref_low_bound (ref);
  
!       force_move_till_expr (step, data);
!       force_move_till_expr (lbound, data);
      }
  
    if (TREE_CODE (*index) != SSA_NAME)
--- 736,767 ----
  
    nops = first_rtl_op (TREE_CODE (expr));
    for (i = 0; i < nops; i++)
!     force_move_till_expr (TREE_OPERAND (expr, i), orig_loop, loop);
  }
  
  /* Forces statement defining invariants in REF (and *INDEX) to be moved out of
!    the LOOP.  The reference REF is used in the loop ORIG_LOOP.  Callback for
!    for_each_index.  */
! 
! struct fmt_data
! {
!   struct loop *loop;
!   struct loop *orig_loop;
! };
  
  static bool
  force_move_till (tree ref, tree *index, void *data)
  {
    tree stmt;
+   struct fmt_data *fmt_data = data;
  
    if (TREE_CODE (ref) == ARRAY_REF)
      {
        tree step = array_ref_element_size (ref);
        tree lbound = array_ref_low_bound (ref);
  
!       force_move_till_expr (step, fmt_data->orig_loop, fmt_data->loop);
!       force_move_till_expr (lbound, fmt_data->orig_loop, fmt_data->loop);
      }
  
    if (TREE_CODE (*index) != SSA_NAME)
*************** force_move_till (tree ref, tree *index, 
*** 763,769 ****
    if (IS_EMPTY_STMT (stmt))
      return true;
  
!   set_level (stmt, bb_for_stmt (stmt)->loop_father, data);
  
    return true;
  }
--- 771,777 ----
    if (IS_EMPTY_STMT (stmt))
      return true;
  
!   set_level (stmt, fmt_data->orig_loop, fmt_data->loop);
  
    return true;
  }
*************** schedule_sm (struct loop *loop, edge *ex
*** 977,986 ****
    tree tmp_var;
    unsigned i;
    tree load, store;
  
    tmp_var = make_rename_temp (TREE_TYPE (ref), "lsm_tmp");
  
!   for_each_index (&ref, force_move_till, loop);
  
    rewrite_mem_refs (tmp_var, mem_refs);
    for (aref = mem_refs; aref; aref = aref->next)
--- 985,997 ----
    tree tmp_var;
    unsigned i;
    tree load, store;
+   struct fmt_data fmt_data;
  
    tmp_var = make_rename_temp (TREE_TYPE (ref), "lsm_tmp");
  
!   fmt_data.loop = loop;
!   fmt_data.orig_loop = loop;
!   for_each_index (&ref, force_move_till, &fmt_data);
  
    rewrite_mem_refs (tmp_var, mem_refs);
    for (aref = mem_refs; aref; aref = aref->next)


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