OSDN Git Service

gcc/
[pf3gnuchains/gcc-fork.git] / gcc / df-problems.c
index 5e56025..cdbc8a1 100644 (file)
@@ -157,27 +157,6 @@ df_print_bb_index (basic_block bb, FILE *file)
   fprintf (file, ")\n");
 }
 
-
-
-/* Make sure that the seen_in_insn and seen_in_block sbitmaps are set
-   up correctly. */
-
-static void
-df_set_seen (void)
-{
-  seen_in_block = BITMAP_ALLOC (&df_bitmap_obstack);
-  seen_in_insn = BITMAP_ALLOC (&df_bitmap_obstack);
-}
-
-
-static void
-df_unset_seen (void)
-{
-  BITMAP_FREE (seen_in_block);
-  BITMAP_FREE (seen_in_insn);
-}
-
-
 \f
 /*----------------------------------------------------------------------------
    REACHING DEFINITIONS
@@ -487,7 +466,8 @@ df_rd_local_compute (bitmap all_blocks)
   bitmap sparse_invalidated = problem_data->sparse_invalidated_by_call;
   bitmap dense_invalidated = problem_data->dense_invalidated_by_call;
 
-  df_set_seen ();
+  seen_in_block = BITMAP_ALLOC (&df_bitmap_obstack);
+  seen_in_insn = BITMAP_ALLOC (&df_bitmap_obstack);
 
   df_maybe_reorganize_def_refs (DF_REF_ORDER_BY_REG);
 
@@ -506,7 +486,9 @@ df_rd_local_compute (bitmap all_blocks)
                          DF_DEFS_BEGIN (regno), 
                          DF_DEFS_COUNT (regno));
     }
-  df_unset_seen ();
+
+  BITMAP_FREE (seen_in_block);
+  BITMAP_FREE (seen_in_insn);
 }
 
 
@@ -876,7 +858,7 @@ df_lr_bb_local_compute (unsigned int bb_index)
     {
       unsigned int uid = INSN_UID (insn);
 
-      if (!INSN_P (insn))
+      if (!NONDEBUG_INSN_P (insn))
        continue;       
 
       for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
@@ -3200,6 +3182,8 @@ df_set_note (enum reg_note note_type, rtx insn, rtx old, rtx reg)
   rtx curr = old;
   rtx prev = NULL;
 
+  gcc_assert (!DEBUG_INSN_P (insn));
+
   while (curr)
     if (XEXP (curr, 0) == reg)
       {
@@ -3332,9 +3316,12 @@ df_whole_mw_reg_dead_p (struct df_mw_hardreg *mws,
 static rtx
 df_set_dead_notes_for_mw (rtx insn, rtx old, struct df_mw_hardreg *mws,
                          bitmap live, bitmap do_not_gen,
-                         bitmap artificial_uses)
+                         bitmap artificial_uses, bool *added_notes_p)
 {
   unsigned int r;
+  bool is_debug = *added_notes_p;
+
+  *added_notes_p = false;
   
 #ifdef REG_DEAD_DEBUGGING
   if (dump_file)
@@ -3352,6 +3339,11 @@ df_set_dead_notes_for_mw (rtx insn, rtx old, struct df_mw_hardreg *mws,
   if (df_whole_mw_reg_dead_p (mws, live, artificial_uses, do_not_gen))
     {
       /* Add a dead note for the entire multi word register.  */
+      if (is_debug)
+       {
+         *added_notes_p = true;
+         return old;
+       }
       old = df_set_note (REG_DEAD, insn, old, mws->mw_reg);
 #ifdef REG_DEAD_DEBUGGING
       df_print_note ("adding 1: ", insn, REG_NOTES (insn));
@@ -3364,6 +3356,11 @@ df_set_dead_notes_for_mw (rtx insn, rtx old, struct df_mw_hardreg *mws,
            && !bitmap_bit_p (artificial_uses, r)
            && !bitmap_bit_p (do_not_gen, r))
          {
+           if (is_debug)
+             {
+               *added_notes_p = true;
+               return old;
+             }
            old = df_set_note (REG_DEAD, insn, old, regno_reg_rtx[r]);
 #ifdef REG_DEAD_DEBUGGING
            df_print_note ("adding 2: ", insn, REG_NOTES (insn));
@@ -3474,10 +3471,13 @@ df_note_bb_compute (unsigned int bb_index,
       struct df_mw_hardreg **mws_rec;
       rtx old_dead_notes;
       rtx old_unused_notes;
+      int debug_insn;
  
       if (!INSN_P (insn))
        continue;
 
+      debug_insn = DEBUG_INSN_P (insn);
+
       bitmap_clear (do_not_gen);
       df_kill_notes (insn, &old_dead_notes, &old_unused_notes);
 
@@ -3562,10 +3562,18 @@ df_note_bb_compute (unsigned int bb_index,
          struct df_mw_hardreg *mws = *mws_rec; 
          if ((DF_MWS_REG_DEF_P (mws))  
              && !df_ignore_stack_reg (mws->start_regno))
-           old_dead_notes
-             = df_set_dead_notes_for_mw (insn, old_dead_notes, 
-                                         mws, live, do_not_gen,
-                                         artificial_uses);
+           {
+             bool really_add_notes = debug_insn != 0;
+
+             old_dead_notes
+               = df_set_dead_notes_for_mw (insn, old_dead_notes,
+                                           mws, live, do_not_gen,
+                                           artificial_uses,
+                                           &really_add_notes);
+
+             if (really_add_notes)
+               debug_insn = -1;
+           }
          mws_rec++;
        }
 
@@ -3575,7 +3583,7 @@ df_note_bb_compute (unsigned int bb_index,
          unsigned int uregno = DF_REF_REGNO (use);
 
 #ifdef REG_DEAD_DEBUGGING
-         if (dump_file)
+         if (dump_file && !debug_insn)
            {
              fprintf (dump_file, "  regular looking at use ");
              df_ref_debug (use, dump_file);
@@ -3583,6 +3591,12 @@ df_note_bb_compute (unsigned int bb_index,
 #endif
          if (!bitmap_bit_p (live, uregno))
            {
+             if (debug_insn)
+               {
+                 debug_insn = -1;
+                 break;
+               }
+
              if ( (!(DF_REF_FLAGS (use) & DF_REF_MW_HARDREG))
                   && (!bitmap_bit_p (do_not_gen, uregno))
                   && (!bitmap_bit_p (artificial_uses, uregno))
@@ -3614,6 +3628,14 @@ df_note_bb_compute (unsigned int bb_index,
          free_EXPR_LIST_node (old_dead_notes);
          old_dead_notes = next;
        }
+
+      if (debug_insn == -1)
+       {
+         /* ??? We could probably do better here, replacing dead
+            registers with their definitions.  */
+         INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC ();
+         df_insn_rescan_debug_internal (insn);
+       }
     }
 }
 
@@ -3759,6 +3781,9 @@ df_simulate_uses (rtx insn, bitmap live)
   df_ref *use_rec;
   unsigned int uid = INSN_UID (insn);
 
+  if (DEBUG_INSN_P (insn))
+    return;
+
   for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++)
     {
       df_ref use = *use_rec;
@@ -3825,7 +3850,7 @@ df_simulate_initialize_backwards (basic_block bb, bitmap live)
 void 
 df_simulate_one_insn_backwards (basic_block bb, rtx insn, bitmap live)
 {
-  if (! INSN_P (insn))
+  if (!NONDEBUG_INSN_P (insn))
     return;    
   
   df_simulate_defs (insn, live);
@@ -4001,6 +4026,10 @@ df_simulate_finalize_forwards (basic_block bb, bitmap live)
     propagating the information to BB3's successors. 
    ---------------------------------------------------------------------------*/
 
+/* Scratch var used by transfer functions.  This is used to do md analysis
+   only for live registers.  */
+static bitmap df_md_scratch;
+
 /* Set basic block info.  */
 
 static void
@@ -4044,6 +4073,7 @@ df_md_alloc (bitmap all_blocks)
                                            sizeof (struct df_md_bb_info), 50);
 
   df_grow_bb_info (df_md);
+  df_md_scratch = BITMAP_ALLOC (NULL);
 
   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
     {
@@ -4198,14 +4228,14 @@ df_md_local_compute (bitmap all_blocks)
   basic_block bb;
   bitmap *frontiers;
 
-  df_set_seen ();
+  seen_in_insn = BITMAP_ALLOC (NULL);
 
   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi1)
     {
       df_md_bb_local_compute (bb_index);
     }
   
-  df_unset_seen ();
+  BITMAP_FREE (seen_in_insn);
 
   frontiers = XNEWVEC (bitmap, last_basic_block);
   FOR_ALL_BB (bb)
@@ -4219,8 +4249,10 @@ df_md_local_compute (bitmap all_blocks)
       bitmap kill = df_md_get_bb_info (bb_index)->kill;
       EXECUTE_IF_SET_IN_BITMAP (frontiers[bb_index], 0, df_bb_index, bi2)
        {
+         basic_block bb = BASIC_BLOCK (df_bb_index);
          if (bitmap_bit_p (all_blocks, df_bb_index))
-           bitmap_ior_into (df_md_get_bb_info (df_bb_index)->init, kill);
+           bitmap_ior_and_into (df_md_get_bb_info (df_bb_index)->init, kill,
+                                df_get_live_in (bb));
        }
     }
 
@@ -4250,13 +4282,24 @@ df_md_reset (bitmap all_blocks)
 static bool
 df_md_transfer_function (int bb_index)
 {
+  basic_block bb = BASIC_BLOCK (bb_index);
   struct df_md_bb_info *bb_info = df_md_get_bb_info (bb_index);
   bitmap in = bb_info->in;
   bitmap out = bb_info->out;
   bitmap gen = bb_info->gen;
   bitmap kill = bb_info->kill;
 
-  return bitmap_ior_and_compl (out, gen, in, kill);
+  /* We need to use a scratch set here so that the value returned from
+     this function invocation properly reflects if the sets changed in
+     a significant way; i.e. not just because the live set was anded
+     in.  */
+  bitmap_and (df_md_scratch, gen, df_get_live_out (bb));
+
+  /* Multiple definitions of a register are not relevant if it is not
+     used.  Thus we trim the result to the places where it is live.  */
+  bitmap_and_into (in, df_get_live_in (bb));
+
+  return bitmap_ior_and_compl (out, df_md_scratch, in, kill);
 }
 
 /* Initialize the solution bit vectors for problem.  */
@@ -4319,6 +4362,7 @@ df_md_free (void)
        }
     }
 
+  BITMAP_FREE (df_md_scratch);
   free_alloc_pool (df_md->block_pool);
 
   df_md->block_info_size = 0;