diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 26bb1a95871..037138ad02e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2011-10-30 David S. Miller + + * dwarf2out.c (dwarf2out_var_location): When processing several + consecutive location notes, cache the result of next_real_insn(). + 2011-10-30 Uros Bizjak * config/i386/i386.md (avx2_vec_dup): Macroize insn from diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 8d5a9f0fc81..478952f7211 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -20127,10 +20127,12 @@ dwarf2out_var_location (rtx loc_note) { char loclabel[MAX_ARTIFICIAL_LABEL_BYTES + 2]; struct var_loc_node *newloc; - rtx next_real; + rtx next_real, next_note; static const char *last_label; static const char *last_postcall_label; static bool last_in_cold_section_p; + static rtx expected_next_loc_note; + static rtx cached_next_real_insn; tree decl; bool var_loc_p; @@ -20149,7 +20151,35 @@ dwarf2out_var_location (rtx loc_note) if (var_loc_p && !DECL_P (NOTE_VAR_LOCATION_DECL (loc_note))) return; - next_real = next_real_insn (loc_note); + /* Optimize processing a large consecutive sequence of location + notes so we don't spend too much time in next_real_insn. If the + next insn is another location note, remember the next_real_insn + calculation for next time. */ + next_real = cached_next_real_insn; + if (next_real) + { + if (expected_next_loc_note != loc_note) + next_real = NULL_RTX; + } + + next_note = NEXT_INSN (loc_note); + if (! next_note + || INSN_DELETED_P (next_note) + || GET_CODE (next_note) != NOTE + || (NOTE_KIND (next_note) != NOTE_INSN_VAR_LOCATION + && NOTE_KIND (next_note) != NOTE_INSN_CALL_ARG_LOCATION)) + next_note = NULL_RTX; + + if (! next_real) + next_real = next_real_insn (loc_note); + + if (next_note) + { + expected_next_loc_note = next_note; + cached_next_real_insn = next_real; + } + else + cached_next_real_insn = NULL_RTX; /* If there are no instructions which would be affected by this note, don't do anything. */