aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>2003-12-01 10:05:16 -0700
committerJeff Law <law@gcc.gnu.org>2003-12-01 10:05:16 -0700
commit095c3bbdbb5402b86d078a57e3c5f62abdba7d8b (patch)
treeaeb2801dd9b947d89f976847d77b7ded7fd6e8c0 /gcc
parent8325a4ec9c0d79b68856e355323052ad8fbdd21c (diff)
downloadgcc-095c3bbdbb5402b86d078a57e3c5f62abdba7d8b.zip
gcc-095c3bbdbb5402b86d078a57e3c5f62abdba7d8b.tar.gz
gcc-095c3bbdbb5402b86d078a57e3c5f62abdba7d8b.tar.bz2
flow.c (count_or_remove_death_notes_bb): New.
* flow.c (count_or_remove_death_notes_bb): New. Extracted from count_or_remove_death_notes. (count_or_remove_death_notes): Use EXECUTE_IF_SET_IN_SBITMAP. From-SVN: r74111
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/flow.c113
2 files changed, 78 insertions, 41 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 989c689..00e4063 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2003-12-01 Jeff Law <law@redhat.com>
+
+ * flow.c (count_or_remove_death_notes_bb): New. Extracted from
+ count_or_remove_death_notes.
+ (count_or_remove_death_notes): Use EXECUTE_IF_SET_IN_SBITMAP.
+
2003-12-01 Andreas Krebbel <krebbel1@de.ibm.com>
* builtins.c (expand_builtin_longjmp): Added two memory clobbers.
diff --git a/gcc/flow.c b/gcc/flow.c
index 0dffb46..d131fab 100644
--- a/gcc/flow.c
+++ b/gcc/flow.c
@@ -326,6 +326,7 @@ static void add_to_mem_set_list (struct propagate_block_info *, rtx);
static int invalidate_mems_from_autoinc (rtx *, void *);
static void invalidate_mems_from_set (struct propagate_block_info *, rtx);
static void clear_log_links (sbitmap);
+static int count_or_remove_death_notes_bb (basic_block, int);
void
@@ -4168,65 +4169,95 @@ int
count_or_remove_death_notes (sbitmap blocks, int kill)
{
int count = 0;
+ int i;
basic_block bb;
- FOR_EACH_BB_REVERSE (bb)
+
+ /* This used to be a loop over all the blocks with a membership test
+ inside the loop. That can be amazingly expensive on a large CFG
+ when only a small number of bits are set in BLOCKs (for example,
+ the calls from the scheduler typically have very few bits set).
+
+ For extra credit, someone should convert BLOCKS to a bitmap rather
+ than an sbitmap. */
+ if (blocks)
+ {
+ EXECUTE_IF_SET_IN_SBITMAP (blocks, 0, i,
+ {
+ count += count_or_remove_death_notes_bb (BASIC_BLOCK (i), kill);
+ });
+ }
+ else
{
- rtx insn;
+ FOR_EACH_BB (bb)
+ {
+ count += count_or_remove_death_notes_bb (bb, kill);
+ }
+ }
- if (blocks && ! TEST_BIT (blocks, bb->index))
- continue;
+ return count;
+}
+
+/* Optionally removes all the REG_DEAD and REG_UNUSED notes from basic
+ block BB. Returns a count of the number of registers that died. */
+
+static int
+count_or_remove_death_notes_bb (basic_block bb, int kill)
+{
+ int count = 0;
+ rtx insn;
- for (insn = bb->head;; insn = NEXT_INSN (insn))
+ for (insn = bb->head;; insn = NEXT_INSN (insn))
+ {
+ if (INSN_P (insn))
{
- if (INSN_P (insn))
- {
- rtx *pprev = &REG_NOTES (insn);
- rtx link = *pprev;
+ rtx *pprev = &REG_NOTES (insn);
+ rtx link = *pprev;
- while (link)
+ while (link)
+ {
+ switch (REG_NOTE_KIND (link))
{
- switch (REG_NOTE_KIND (link))
+ case REG_DEAD:
+ if (GET_CODE (XEXP (link, 0)) == REG)
{
- case REG_DEAD:
- if (GET_CODE (XEXP (link, 0)) == REG)
- {
- rtx reg = XEXP (link, 0);
- int n;
-
- if (REGNO (reg) >= FIRST_PSEUDO_REGISTER)
- n = 1;
- else
- n = HARD_REGNO_NREGS (REGNO (reg), GET_MODE (reg));
- count += n;
- }
- /* Fall through. */
-
- case REG_UNUSED:
- if (kill)
- {
- rtx next = XEXP (link, 1);
- free_EXPR_LIST_node (link);
- *pprev = link = next;
- break;
- }
- /* Fall through. */
-
- default:
- pprev = &XEXP (link, 1);
- link = *pprev;
+ rtx reg = XEXP (link, 0);
+ int n;
+
+ if (REGNO (reg) >= FIRST_PSEUDO_REGISTER)
+ n = 1;
+ else
+ n = HARD_REGNO_NREGS (REGNO (reg), GET_MODE (reg));
+ count += n;
+ }
+
+ /* Fall through. */
+
+ case REG_UNUSED:
+ if (kill)
+ {
+ rtx next = XEXP (link, 1);
+ free_EXPR_LIST_node (link);
+ *pprev = link = next;
break;
}
+ /* Fall through. */
+
+ default:
+ pprev = &XEXP (link, 1);
+ link = *pprev;
+ break;
}
}
-
- if (insn == bb->end)
- break;
}
+
+ if (insn == bb->end)
+ break;
}
return count;
}
+
/* Clear LOG_LINKS fields of insns in a selected blocks or whole chain
if blocks is NULL. */