summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordavem <davem@138bc75d-0d04-0410-961f-82ee72b054a4>2011-10-31 01:48:15 +0000
committerdavem <davem@138bc75d-0d04-0410-961f-82ee72b054a4>2011-10-31 01:48:15 +0000
commit4ef5ea129991d8556b68e25c8396ce0f39521a81 (patch)
treeb2c28325717289ceaa8e5cdb8f39f2e13704f39e
parent16f17f6fc95524b507b5e08e1d3156f9ff17d907 (diff)
downloadgcc-4ef5ea129991d8556b68e25c8396ce0f39521a81.tar.gz
Handle many consecutive location notes more efficiently in dwarf2.
* dwarf2out.c (dwarf2out_var_location): When processing several consecutive location notes, cache the result of next_real_insn(). git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@180695 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/dwarf2out.c34
2 files changed, 37 insertions, 2 deletions
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 <davem@davemloft.net>
+
+ * dwarf2out.c (dwarf2out_var_location): When processing several
+ consecutive location notes, cache the result of next_real_insn().
+
2011-10-30 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.md (avx2_vec_dup<mode>): 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. */