]> gcc.gnu.org Git - gcc.git/commitdiff
df.h (df_insn_delete): Adjust prototype.
authorSteven Bosscher <steven@gcc.gnu.org>
Fri, 22 Mar 2013 16:37:00 +0000 (16:37 +0000)
committerSteven Bosscher <steven@gcc.gnu.org>
Fri, 22 Mar 2013 16:37:00 +0000 (16:37 +0000)
* df.h (df_insn_delete): Adjust prototype.
* emit-rtl.c (remove_insn): Pass a basic block to df_insn_delete
and let it decide whether mark the basic block dirty.
(set_insn_deleted): Only pass INSN_P insns to df_insn_delete.
* df-scan.c (df_insn_info_delete): New helper function, split
off from df_insn_delete.
(df_scan_free_bb_info): Use it.
(df_insn_rescan, df_insn_rescan_all, df_process_deferred_rescans):
Likewise.
(df_insn_delete): Likewise.  Take insn rtx as argument.  Verify
that the insn is actually an insn and it has a non-NULL basic block.
Do not mark basic block dirty if only deleting a DEBUG_INSN.

From-SVN: r196977

gcc/df-scan.c
gcc/df.h
gcc/emit-rtl.c

index 931fa2c7e4800e0c92fc8bc60e95d06f9872448a..fdfa93190ce0c77f1a858fab83725f81b4cddb59 100644 (file)
@@ -142,6 +142,8 @@ static void df_install_ref (df_ref, struct df_reg_info *,
 static int df_ref_compare (const void *, const void *);
 static int df_mw_compare (const void *, const void *);
 
+static void df_insn_info_delete (unsigned int);
+
 /* Indexed by hardware reg number, is true if that register is ever
    used in the current function.
 
@@ -277,8 +279,7 @@ df_scan_free_bb_info (basic_block bb, void *vbb_info)
       FOR_BB_INSNS (bb, insn)
        {
          if (INSN_P (insn))
-           /* Record defs within INSN.  */
-           df_insn_delete (bb, INSN_UID (insn));
+           df_insn_info_delete (INSN_UID (insn));
        }
 
       if (bb_index < df_scan->block_info_size)
@@ -1087,44 +1088,15 @@ df_mw_hardreg_chain_delete (struct df_mw_hardreg **hardregs)
 }
 
 
-/* Delete all of the refs information from INSN.  BB must be passed in
-   except when called from df_process_deferred_rescans to mark the block
-   as dirty.  */
+/* Delete all of the refs information from the insn with UID.
+   Internal helper for df_insn_delete, df_insn_rescan, and other
+   df-scan routines that don't have to work in deferred mode
+   and do not have to mark basic blocks for re-processing.  */
 
-void
-df_insn_delete (basic_block bb, unsigned int uid)
+static void
+df_insn_info_delete (unsigned int uid)
 {
-  struct df_insn_info *insn_info = NULL;
-  if (!df)
-    return;
-
-  df_grow_bb_info (df_scan);
-  df_grow_reg_info ();
-
-  /* The block must be marked as dirty now, rather than later as in
-     df_insn_rescan and df_notes_rescan because it may not be there at
-     rescanning time and the mark would blow up.  */
-  if (bb)
-    df_set_bb_dirty (bb);
-
-  insn_info = DF_INSN_UID_SAFE_GET (uid);
-
-  /* The client has deferred rescanning.  */
-  if (df->changeable_flags & DF_DEFER_INSN_RESCAN)
-    {
-      if (insn_info)
-       {
-         bitmap_clear_bit (&df->insns_to_rescan, uid);
-         bitmap_clear_bit (&df->insns_to_notes_rescan, uid);
-         bitmap_set_bit (&df->insns_to_delete, uid);
-       }
-      if (dump_file)
-       fprintf (dump_file, "deferring deletion of insn with uid = %d.\n", uid);
-      return;
-    }
-
-  if (dump_file)
-    fprintf (dump_file, "deleting insn with uid = %d.\n", uid);
+  struct df_insn_info *insn_info = DF_INSN_UID_SAFE_GET (uid);
 
   bitmap_clear_bit (&df->insns_to_delete, uid);
   bitmap_clear_bit (&df->insns_to_rescan, uid);
@@ -1160,6 +1132,67 @@ df_insn_delete (basic_block bb, unsigned int uid)
     }
 }
 
+/* Delete all of the refs information from INSN, either right now
+   or marked for later in deferred mode.  */
+
+void
+df_insn_delete (rtx insn)
+{
+  unsigned int uid;
+  basic_block bb;
+
+  gcc_checking_assert (INSN_P (insn));
+
+  if (!df)
+    return;
+
+  uid = INSN_UID (insn);
+  bb = BLOCK_FOR_INSN (insn);
+
+  /* ??? bb can be NULL after pass_free_cfg.  At that point, DF should
+     not exist anymore (as mentioned in df-core.c: "The only requirement
+     [for DF] is that there be a correct control flow graph."  Clearly
+     that isn't the case after pass_free_cfg.  But DF is freed much later
+     because some back-ends want to use DF info even though the CFG is
+     already gone.  It's not clear to me whether that is safe, actually.
+     In any case, we expect BB to be non-NULL at least up to register
+     allocation, so disallow a non-NULL BB up to there.  Not perfect
+     but better than nothing...  */
+
+  gcc_checking_assert (bb != NULL || reload_completed);
+
+  df_grow_bb_info (df_scan);
+  df_grow_reg_info ();
+
+  /* The block must be marked as dirty now, rather than later as in
+     df_insn_rescan and df_notes_rescan because it may not be there at
+     rescanning time and the mark would blow up.
+     DEBUG_INSNs do not make a block's data flow solution dirty (at
+     worst the LUIDs are no longer contiguous).  */
+  if (bb != NULL && NONDEBUG_INSN_P (insn))
+    df_set_bb_dirty (bb);
+
+  /* The client has deferred rescanning.  */
+  if (df->changeable_flags & DF_DEFER_INSN_RESCAN)
+    {
+      struct df_insn_info *insn_info = DF_INSN_UID_SAFE_GET (uid);
+      if (insn_info)
+       {
+         bitmap_clear_bit (&df->insns_to_rescan, uid);
+         bitmap_clear_bit (&df->insns_to_notes_rescan, uid);
+         bitmap_set_bit (&df->insns_to_delete, uid);
+       }
+      if (dump_file)
+       fprintf (dump_file, "deferring deletion of insn with uid = %d.\n", uid);
+      return;
+    }
+
+  if (dump_file)
+    fprintf (dump_file, "deleting insn with uid = %d.\n", uid);
+
+  df_insn_info_delete (uid);
+}
+
 
 /* Free all of the refs and the mw_hardregs in COLLECTION_REC.  */
 
@@ -1262,7 +1295,7 @@ df_insn_rescan (rtx insn)
       /* There's change - we need to delete the existing info.
         Since the insn isn't moved, we can salvage its LUID.  */
       luid = DF_INSN_LUID (insn);
-      df_insn_delete (NULL, uid);
+      df_insn_info_delete (uid);
       df_insn_create_insn_record (insn);
       DF_INSN_LUID (insn) = luid;
     }
@@ -1345,7 +1378,7 @@ df_insn_rescan_debug_internal (rtx insn)
 
 
 /* Rescan all of the insns in the function.  Note that the artificial
-   uses and defs are not touched.  This function will destroy def-se
+   uses and defs are not touched.  This function will destroy def-use
    or use-def chains.  */
 
 void
@@ -1377,7 +1410,7 @@ df_insn_rescan_all (void)
     {
       struct df_insn_info *insn_info = DF_INSN_UID_SAFE_GET (uid);
       if (insn_info)
-       df_insn_delete (NULL, uid);
+       df_insn_info_delete (uid);
     }
 
   bitmap_clear (&tmp);
@@ -1434,7 +1467,7 @@ df_process_deferred_rescans (void)
     {
       struct df_insn_info *insn_info = DF_INSN_UID_SAFE_GET (uid);
       if (insn_info)
-       df_insn_delete (NULL, uid);
+       df_insn_info_delete (uid);
     }
 
   bitmap_copy (&tmp, &df->insns_to_rescan);
index c2bb826a4aea67d7dbbc3d19f81cbc4cfff0bd58..716ce0c8d72eec7504b9e690237e94e2ae659b4f 100644 (file)
--- a/gcc/df.h
+++ b/gcc/df.h
@@ -996,7 +996,7 @@ extern df_ref df_ref_create (rtx, rtx *, rtx,basic_block,
 extern void df_uses_create (rtx *, rtx, int);
 extern void df_ref_remove (df_ref);
 extern struct df_insn_info * df_insn_create_insn_record (rtx);
-extern void df_insn_delete (basic_block, unsigned int);
+extern void df_insn_delete (rtx);
 extern void df_bb_refs_record (int, bool);
 extern bool df_insn_rescan (rtx);
 extern bool df_insn_rescan_debug_internal (rtx);
index 59cd38d40f4c296087bb8af9b657aef63c18e689..31c1e638d7c503cf965d188c587a1d1df4f7ac0f 100644 (file)
@@ -3964,7 +3964,8 @@ add_insn_before (rtx insn, rtx before, basic_block bb)
 void
 set_insn_deleted (rtx insn)
 {
-  df_insn_delete (BLOCK_FOR_INSN (insn), INSN_UID (insn));
+  if (INSN_P (insn) && !JUMP_TABLE_DATA_P (insn))
+    df_insn_delete (insn);
   PUT_CODE (insn, NOTE);
   NOTE_KIND (insn) = NOTE_INSN_DELETED;
 }
@@ -3979,9 +3980,6 @@ remove_insn (rtx insn)
   rtx prev = PREV_INSN (insn);
   basic_block bb;
 
-  /* Later in the code, the block will be marked dirty.  */
-  df_insn_delete (NULL, INSN_UID (insn));
-
   if (prev)
     {
       NEXT_INSN (prev) = next;
@@ -4032,11 +4030,15 @@ remove_insn (rtx insn)
 
       gcc_assert (stack);
     }
+
+  /* Invalidate data flow information associated with INSN.  */
+  if (INSN_P (insn) && !JUMP_TABLE_DATA_P (insn))
+    df_insn_delete (insn);
+
+  /* Fix up basic block boundaries, if necessary.  */
   if (!BARRIER_P (insn)
       && (bb = BLOCK_FOR_INSN (insn)))
     {
-      if (NONDEBUG_INSN_P (insn))
-       df_set_bb_dirty (bb);
       if (BB_HEAD (bb) == insn)
        {
          /* Never ever delete the basic block note without deleting whole
This page took 0.07508 seconds and 5 git commands to generate.