summaryrefslogtreecommitdiffstats
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/cfgrtl.c11
-rw-r--r--gcc/value-prof.c24
3 files changed, 42 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c0a0e34fe82..6cf49a96d08 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2005-02-13 Zdenek Dvorak <dvorakz@suse.cz>
+
+ PR target/17428
+ * cfgrtl.c (safe_insert_insn_on_edge): Avoid extending life range of hard
+ registers.
+ * value-prof.c (insn_prefetch_values_to_profile): Only scan normal insns.
+
+ * value-prof.c (rtl_find_values_to_profile): Do not look for values to
+ profile in libcalls.
+
2005-02-13 Nathan Sidwell <nathan@codesourcery.com>
* bitmap.h (bitmap_and_compl_into): Return bool.
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index fa0af4ba654..8de76449941 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -1470,6 +1470,16 @@ safe_insert_insn_on_edge (rtx insn, edge e)
for (x = insn; x; x = NEXT_INSN (x))
if (INSN_P (x))
note_stores (PATTERN (x), mark_killed_regs, killed);
+
+ /* Mark all hard registers as killed. Register allocator/reload cannot
+ cope with the situation when life range of hard register spans operation
+ for that the appropriate register is needed, i.e. it would be unsafe to
+ extend the life ranges of hard registers. */
+ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+ if (!fixed_regs[regno]
+ && !REGNO_PTR_FRAME_P (regno))
+ SET_REGNO_REG_SET (killed, regno);
+
bitmap_and_into (killed, e->dest->global_live_at_start);
EXECUTE_IF_SET_IN_REG_SET (killed, 0, regno, rsi)
@@ -1515,6 +1525,7 @@ safe_insert_insn_on_edge (rtx insn, edge e)
insert_insn_on_edge (insn, e);
FREE_REG_SET (killed);
+
return true;
}
diff --git a/gcc/value-prof.c b/gcc/value-prof.c
index 1663e64800d..e5e43206b40 100644
--- a/gcc/value-prof.c
+++ b/gcc/value-prof.c
@@ -245,7 +245,8 @@ insn_prefetch_values_to_profile (rtx insn, histogram_values *values)
int write;
histogram_value hist;
- if (!INSN_P (insn))
+ /* It only makes sense to look for memory references in ordinary insns. */
+ if (GET_CODE (insn) != INSN)
return false;
if (!find_mem_reference (insn, &mem, &write))
@@ -288,13 +289,30 @@ static void
rtl_find_values_to_profile (histogram_values *values)
{
rtx insn;
- unsigned i;
+ unsigned i, libcall_level;
life_analysis (NULL, PROP_DEATH_NOTES);
*values = VEC_alloc (histogram_value, 0);
+ libcall_level = 0;
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
- insn_values_to_profile (insn, values);
+ {
+ if (find_reg_note (insn, REG_LIBCALL, NULL_RTX))
+ libcall_level++;
+
+ /* Do not instrument values inside libcalls (we are going to split block
+ due to instrumentation, and libcall blocks should be local to a single
+ basic block). */
+ if (!libcall_level)
+ insn_values_to_profile (insn, values);
+
+ if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
+ {
+ gcc_assert (libcall_level > 0);
+ libcall_level--;
+ }
+ }
+ gcc_assert (libcall_level == 0);
for (i = 0; i < VEC_length (histogram_value, *values); i++)
{
OpenPOWER on IntegriCloud