OSDN Git Service

* var-tracking.c (vt_find_locations): Set the in_pending bitmap at
[pf3gnuchains/gcc-fork.git] / gcc / var-tracking.c
index be66392..6e95e50 100644 (file)
@@ -267,6 +267,9 @@ static bool emit_notes;
 /* Fake variable for stack pointer.  */
 tree frame_base_decl;
 
+/* Stack adjust caused by function prologue.  */
+static HOST_WIDE_INT frame_stack_adjust;
+
 /* Local function prototypes.  */
 static void stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *,
                                          HOST_WIDE_INT *);
@@ -304,7 +307,7 @@ static int variable_union_info_cmp_pos (const void *, const void *);
 static int variable_union (void **, void *);
 static void dataflow_set_union (dataflow_set *, dataflow_set *);
 static bool variable_part_different_p (variable_part *, variable_part *);
-static bool variable_different_p (variable, variable);
+static bool variable_different_p (variable, variable, bool);
 static int dataflow_set_different_1 (void **, void *);
 static int dataflow_set_different_2 (void **, void *);
 static bool dataflow_set_different (dataflow_set *, dataflow_set *);
@@ -370,7 +373,7 @@ stack_adjust_offset_pre_post (rtx pattern, HOST_WIDE_INT *pre,
       else
        *post -= INTVAL (XEXP (src, 1));
     }
-  else if (GET_CODE (dest) == MEM)
+  else if (MEM_P (dest))
     {
       /* (set (mem (pre_dec (reg sp))) (foo)) */
       src = XEXP (dest, 0);
@@ -474,7 +477,7 @@ bb_stack_adjust_offset (basic_block bb)
        offset += VTI (bb)->mos[i].u.adjust;
       else if (VTI (bb)->mos[i].type != MO_CALL)
        {
-         if (GET_CODE (VTI (bb)->mos[i].u.loc) == MEM)
+         if (MEM_P (VTI (bb)->mos[i].u.loc))
            {
              VTI (bb)->mos[i].u.loc
                = adjust_stack_reference (VTI (bb)->mos[i].u.loc, -offset);
@@ -484,7 +487,7 @@ bb_stack_adjust_offset (basic_block bb)
   VTI (bb)->out.stack_adjust = offset;
 }
 
-/* Compute stack adjustment caused by function prolog.  */
+/* Compute stack adjustment caused by function prologue.  */
 
 static HOST_WIDE_INT
 prologue_stack_adjust (void)
@@ -500,7 +503,7 @@ prologue_stack_adjust (void)
   end = NEXT_INSN (BB_END (bb));
   for (insn = BB_HEAD (bb); insn != end; insn = NEXT_INSN (insn))
     {
-      if (GET_CODE (insn) == NOTE
+      if (NOTE_P (insn)
          && NOTE_LINE_NUMBER (insn) == NOTE_INSN_PROLOGUE_END)
        break;
 
@@ -528,7 +531,7 @@ vt_stack_adjustments (void)
 
   /* Initialize entry block.  */
   VTI (ENTRY_BLOCK_PTR)->visited = true;
-  VTI (ENTRY_BLOCK_PTR)->out.stack_adjust = 0;
+  VTI (ENTRY_BLOCK_PTR)->out.stack_adjust = frame_stack_adjust;
 
   /* Allocate stack for back-tracking up CFG.  */
   stack = xmalloc ((n_basic_blocks + 1) * sizeof (edge));
@@ -590,6 +593,9 @@ adjust_stack_reference (rtx mem, HOST_WIDE_INT adjustment)
   rtx adjusted_mem;
   rtx tmp;
 
+  if (adjustment == 0)
+    return mem;
+
   adjusted_mem = copy_rtx (mem);
   XEXP (adjusted_mem, 0) = replace_rtx (XEXP (adjusted_mem, 0),
                                        stack_pointer_rtx,
@@ -1099,8 +1105,8 @@ variable_union (void **slot, void *data)
                   node2 = dst->var_part[j].loc_chain; node && node2;
                   node = node->next, node2 = node2->next)
                {
-                 if (!((GET_CODE (node2->loc) == REG
-                        && GET_CODE (node->loc) == REG
+                 if (!((REG_P (node2->loc)
+                        && REG_P (node->loc)
                         && REGNO (node2->loc) == REGNO (node->loc))
                        || rtx_equal_p (node2->loc, node->loc)))
                    break;
@@ -1136,8 +1142,8 @@ variable_union (void **slot, void *data)
              /* Find location from NODE.  */
              for (jj = 0; jj < dst_l; jj++)
                {
-                 if ((GET_CODE (vui[jj].lc->loc) == REG
-                      && GET_CODE (node->loc) == REG
+                 if ((REG_P (vui[jj].lc->loc)
+                      && REG_P (node->loc)
                       && REGNO (vui[jj].lc->loc) == REGNO (node->loc))
                      || rtx_equal_p (vui[jj].lc->loc, node->loc))
                    {
@@ -1246,7 +1252,7 @@ variable_part_different_p (variable_part *vp1, variable_part *vp2)
     {
       for (lc2 = vp2->loc_chain; lc2; lc2 = lc2->next)
        {
-         if (GET_CODE (lc1->loc) == REG && GET_CODE (lc2->loc) == REG)
+         if (REG_P (lc1->loc) && REG_P (lc2->loc))
            {
              if (REGNO (lc1->loc) == REGNO (lc2->loc))
                break;
@@ -1260,12 +1266,13 @@ variable_part_different_p (variable_part *vp1, variable_part *vp2)
   return false;
 }
 
-/* Return true if variables VAR1 and VAR2 are different (only the first
-   location in the list of locations is checked for each offset,
-   i.e. when true is returned a note should be emitted).  */
+/* Return true if variables VAR1 and VAR2 are different.
+   If COMPARE_CURRENT_LOCATION is true compare also the cur_loc of each
+   variable part.  */
 
 static bool
-variable_different_p (variable var1, variable var2)
+variable_different_p (variable var1, variable var2,
+                     bool compare_current_location)
 {
   int i;
 
@@ -1279,6 +1286,16 @@ variable_different_p (variable var1, variable var2)
     {
       if (var1->var_part[i].offset != var2->var_part[i].offset)
        return true;
+      if (compare_current_location)
+       {
+         if (!((REG_P (var1->var_part[i].cur_loc)
+                && REG_P (var2->var_part[i].cur_loc)
+                && (REGNO (var1->var_part[i].cur_loc)
+                    == REGNO (var2->var_part[i].cur_loc)))
+               || rtx_equal_p (var1->var_part[i].cur_loc,
+                               var2->var_part[i].cur_loc)))
+           return true;
+       }
       if (variable_part_different_p (&var1->var_part[i], &var2->var_part[i]))
        return true;
       if (variable_part_different_p (&var2->var_part[i], &var1->var_part[i]))
@@ -1307,7 +1324,7 @@ dataflow_set_different_1 (void **slot, void *data)
       return 0;
     }
 
-  if (variable_different_p (var1, var2))
+  if (variable_different_p (var1, var2, false))
     {
       dataflow_set_different_value = true;
 
@@ -1342,7 +1359,7 @@ dataflow_set_different_2 (void **slot, void *data)
 #ifdef ENABLE_CHECKING
   /* If both variables are defined they have been already checked for
      equivalence.  */
-  if (variable_different_p (var1, var2))
+  if (variable_different_p (var1, var2, false))
     abort ();
 #endif
 
@@ -1455,13 +1472,13 @@ track_expr_p (tree expr)
      extern char **_dl_argv_internal __attribute__ ((alias ("_dl_argv")));
      char **_dl_argv;
   */
-  if (GET_CODE (decl_rtl) == MEM
+  if (MEM_P (decl_rtl)
       && contains_symbol_ref (XEXP (decl_rtl, 0)))
     return 0;
 
   /* If RTX is a memory it should not be very large (because it would be
      an array or struct).  */
-  if (GET_CODE (decl_rtl) == MEM)
+  if (MEM_P (decl_rtl))
     {
       /* Do not track structures and arrays.  */
       if (GET_MODE (decl_rtl) == BLKmode)
@@ -1482,7 +1499,7 @@ count_uses (rtx *loc, void *insn)
 {
   basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
 
-  if (GET_CODE (*loc) == REG)
+  if (REG_P (*loc))
     {
 #ifdef ENABLE_CHECKING
        if (REGNO (*loc) >= FIRST_PSEUDO_REGISTER)
@@ -1490,7 +1507,7 @@ count_uses (rtx *loc, void *insn)
 #endif
        VTI (bb)->n_mos++;
     }
-  else if (GET_CODE (*loc) == MEM
+  else if (MEM_P (*loc)
           && MEM_EXPR (*loc)
           && track_expr_p (MEM_EXPR (*loc)))
     {
@@ -1523,7 +1540,7 @@ count_stores (rtx loc, rtx expr ATTRIBUTE_UNUSED, void *insn)
 static int
 add_uses (rtx *loc, void *insn)
 {
-  if (GET_CODE (*loc) == REG)
+  if (REG_P (*loc))
     {
       basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
       micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
@@ -1533,7 +1550,7 @@ add_uses (rtx *loc, void *insn)
       mo->u.loc = *loc;
       mo->insn = (rtx) insn;
     }
-  else if (GET_CODE (*loc) == MEM
+  else if (MEM_P (*loc)
           && MEM_EXPR (*loc)
           && track_expr_p (MEM_EXPR (*loc)))
     {
@@ -1563,7 +1580,7 @@ add_uses_1 (rtx *x, void *insn)
 static void
 add_stores (rtx loc, rtx expr, void *insn)
 {
-  if (GET_CODE (loc) == REG)
+  if (REG_P (loc))
     {
       basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
       micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
@@ -1574,7 +1591,7 @@ add_stores (rtx loc, rtx expr, void *insn)
       mo->u.loc = loc;
       mo->insn = (rtx) insn;
     }
-  else if (GET_CODE (loc) == MEM
+  else if (MEM_P (loc)
           && MEM_EXPR (loc)
           && track_expr_p (MEM_EXPR (loc)))
     {
@@ -1618,9 +1635,9 @@ compute_bb_dataflow (basic_block bb)
            {
              rtx loc = VTI (bb)->mos[i].u.loc;
 
-             if (GET_CODE (loc) == REG)
+             if (REG_P (loc))
                var_reg_delete_and_set (out, loc);
-             else if (GET_CODE (loc) == MEM)
+             else if (MEM_P (loc))
                var_mem_delete_and_set (out, loc);
            }
            break;
@@ -1630,9 +1647,9 @@ compute_bb_dataflow (basic_block bb)
            {
              rtx loc = VTI (bb)->mos[i].u.loc;
 
-             if (GET_CODE (loc) == REG)
+             if (REG_P (loc))
                var_reg_delete (out, loc);
-             else if (GET_CODE (loc) == MEM)
+             else if (MEM_P (loc))
                var_mem_delete (out, loc);
            }
            break;
@@ -1642,9 +1659,8 @@ compute_bb_dataflow (basic_block bb)
              rtx base;
 
              out->stack_adjust += VTI (bb)->mos[i].u.adjust;
-             base = gen_rtx_MEM (Pmode,
-                                 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
-                                               GEN_INT (out->stack_adjust)));
+             base = gen_rtx_MEM (Pmode, plus_constant (stack_pointer_rtx,
+                                                       out->stack_adjust));
              set_frame_base_location (out, base);
            }
            break;
@@ -1684,13 +1700,10 @@ vt_find_locations (void)
   in_worklist = sbitmap_alloc (last_basic_block);
   in_pending = sbitmap_alloc (last_basic_block);
   sbitmap_zero (in_worklist);
-  sbitmap_zero (in_pending);
 
   FOR_EACH_BB (bb)
-    {
-      fibheap_insert (pending, bb_order[bb->index], bb);
-      SET_BIT (in_pending, bb->index);
-    }
+    fibheap_insert (pending, bb_order[bb->index], bb);
+  sbitmap_ones (in_pending);
 
   while (!fibheap_empty (pending))
     {
@@ -1907,9 +1920,8 @@ variable_was_changed (variable var, htab_t htab)
 }
 
 /* Set the location of frame_base_decl to LOC in dataflow set SET.  This
-   function expects that
-   frame_base_decl has already one location for offset 0 in the variable table.
- */
+   function expects that frame_base_decl has already one location for offset 0
+   in the variable table.  */
 
 static void
 set_frame_base_location (dataflow_set *set, rtx loc)
@@ -1988,7 +2000,7 @@ set_variable_part (dataflow_set *set, rtx loc, tree decl, HOST_WIDE_INT offset)
          node = var->var_part[pos].loc_chain;
 
          if (node
-             && ((GET_CODE (node->loc) == REG && GET_CODE (loc) == REG
+             && ((REG_P (node->loc) && REG_P (loc)
                   && REGNO (node->loc) == REGNO (loc))
                  || rtx_equal_p (node->loc, loc)))
            {
@@ -2035,7 +2047,7 @@ set_variable_part (dataflow_set *set, rtx loc, tree decl, HOST_WIDE_INT offset)
   for (node = var->var_part[pos].loc_chain; node; node = next)
     {
       next = node->next;
-      if ((GET_CODE (node->loc) == REG && GET_CODE (loc) == REG
+      if ((REG_P (node->loc) && REG_P (loc)
           && REGNO (node->loc) == REGNO (loc))
          || rtx_equal_p (node->loc, loc))
        {
@@ -2104,7 +2116,7 @@ delete_variable_part (dataflow_set *set, rtx loc, tree decl,
              for (node = var->var_part[pos].loc_chain; node;
                   node = node->next)
                {
-                 if ((GET_CODE (node->loc) == REG && GET_CODE (loc) == REG
+                 if ((REG_P (node->loc) && REG_P (loc)
                       && REGNO (node->loc) == REGNO (loc))
                      || rtx_equal_p (node->loc, loc))
                    {
@@ -2119,7 +2131,7 @@ delete_variable_part (dataflow_set *set, rtx loc, tree decl,
          for (node = *nextp; node; node = next)
            {
              next = node->next;
-             if ((GET_CODE (node->loc) == REG && GET_CODE (loc) == REG
+             if ((REG_P (node->loc) && REG_P (loc)
                   && REGNO (node->loc) == REGNO (loc))
                  || rtx_equal_p (node->loc, loc))
                {
@@ -2135,8 +2147,8 @@ delete_variable_part (dataflow_set *set, rtx loc, tree decl,
             we have to emit new location so add the variable to set
             of changed variables.  */
          if (var->var_part[pos].cur_loc
-             && ((GET_CODE (loc) == REG
-                  && GET_CODE (var->var_part[pos].cur_loc) == REG
+             && ((REG_P (loc)
+                  && REG_P (var->var_part[pos].cur_loc)
                   && REGNO (loc) == REGNO (var->var_part[pos].cur_loc))
                  || rtx_equal_p (loc, var->var_part[pos].cur_loc)))
            {
@@ -2286,7 +2298,7 @@ emit_notes_for_differences_1 (void **slot, void *data)
       empty_var->n_var_parts = 0;
       variable_was_changed (empty_var, NULL);
     }
-  else if (variable_different_p (old_var, new_var))
+  else if (variable_different_p (old_var, new_var, true))
     {
       variable_was_changed (new_var, NULL);
     }
@@ -2364,7 +2376,7 @@ emit_notes_in_bb (basic_block bb)
            {
              rtx loc = VTI (bb)->mos[i].u.loc;
 
-             if (GET_CODE (loc) == REG)
+             if (REG_P (loc))
                var_reg_delete_and_set (&set, loc);
              else
                var_mem_delete_and_set (&set, loc);
@@ -2381,7 +2393,7 @@ emit_notes_in_bb (basic_block bb)
            {
              rtx loc = VTI (bb)->mos[i].u.loc;
 
-             if (GET_CODE (loc) == REG)
+             if (REG_P (loc))
                var_reg_delete (&set, loc);
              else
                var_mem_delete (&set, loc);
@@ -2398,9 +2410,8 @@ emit_notes_in_bb (basic_block bb)
              rtx base;
 
              set.stack_adjust += VTI (bb)->mos[i].u.adjust;
-             base = gen_rtx_MEM (Pmode,
-                                 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
-                                               GEN_INT (set.stack_adjust)));
+             base = gen_rtx_MEM (Pmode, plus_constant (stack_pointer_rtx,
+                                                       set.stack_adjust));
              set_frame_base_location (&set, base);
              emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN);
            }
@@ -2452,7 +2463,7 @@ vt_emit_notes (void)
 static bool
 vt_get_decl_and_offset (rtx rtl, tree *declp, HOST_WIDE_INT *offsetp)
 {
-  if (GET_CODE (rtl) == REG)
+  if (REG_P (rtl))
     {
       if (REG_ATTRS (rtl))
        {
@@ -2461,7 +2472,7 @@ vt_get_decl_and_offset (rtx rtl, tree *declp, HOST_WIDE_INT *offsetp)
          return true;
        }
     }
-  else if (GET_CODE (rtl) == MEM)
+  else if (MEM_P (rtl))
     {
       if (MEM_ATTRS (rtl))
        {
@@ -2479,11 +2490,7 @@ static void
 vt_add_function_parameters (void)
 {
   tree parm;
-  HOST_WIDE_INT stack_adjust = 0;
   
-  if (!frame_pointer_needed)
-    stack_adjust = prologue_stack_adjust ();
-
   for (parm = DECL_ARGUMENTS (current_function_decl);
        parm; parm = TREE_CHAIN (parm))
     {
@@ -2518,11 +2525,9 @@ vt_add_function_parameters (void)
 #endif
 
       incoming = eliminate_regs (incoming, 0, NULL_RTX);
-      if (!frame_pointer_needed && GET_CODE (incoming) == MEM)
-       incoming = adjust_stack_reference (incoming, -stack_adjust);
       out = &VTI (ENTRY_BLOCK_PTR)->out;
 
-      if (GET_CODE (incoming) == REG)
+      if (REG_P (incoming))
        {
 #ifdef ENABLE_CHECKING
          if (REGNO (incoming) >= FIRST_PSEUDO_REGISTER)
@@ -2532,7 +2537,7 @@ vt_add_function_parameters (void)
                             parm, offset, incoming);
          set_variable_part (out, incoming, parm, offset);
        }
-      else if (GET_CODE (incoming) == MEM)
+      else if (MEM_P (incoming))
        {
          set_variable_part (out, incoming, parm, offset);
        }
@@ -2571,7 +2576,7 @@ vt_initialize (void)
                }
              note_uses (&PATTERN (insn), count_uses_1, insn);
              note_stores (PATTERN (insn), count_stores, insn);
-             if (GET_CODE (insn) == CALL_INSN)
+             if (CALL_P (insn))
                VTI (bb)->n_mos++;
            }
        }
@@ -2621,7 +2626,7 @@ vt_initialize (void)
                    }
                }
 
-             if (GET_CODE (insn) == CALL_INSN)
+             if (CALL_P (insn))
                {
                  micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
 
@@ -2692,7 +2697,9 @@ vt_initialize (void)
       DECL_ARTIFICIAL (frame_base_decl) = 1;
 
       /* Set its initial "location".  */
-      base = gen_rtx_MEM (Pmode, stack_pointer_rtx);
+      frame_stack_adjust = -prologue_stack_adjust ();
+      base = gen_rtx_MEM (Pmode, plus_constant (stack_pointer_rtx,
+                                               frame_stack_adjust));
       set_variable_part (&VTI (ENTRY_BLOCK_PTR)->out, base, frame_base_decl, 0);
     }
   else