diff options
Diffstat (limited to 'gcc')
| -rw-r--r-- | gcc/ChangeLog | 10 | ||||
| -rw-r--r-- | gcc/cfgrtl.c | 11 | ||||
| -rw-r--r-- | gcc/value-prof.c | 24 |
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++) { |

