summaryrefslogtreecommitdiffstats
path: root/meta-oe/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99491.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-oe/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99491.patch')
-rw-r--r--meta-oe/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99491.patch309
1 files changed, 309 insertions, 0 deletions
diff --git a/meta-oe/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99491.patch b/meta-oe/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99491.patch
new file mode 100644
index 0000000000..a2d6c6a69a
--- /dev/null
+++ b/meta-oe/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99491.patch
@@ -0,0 +1,309 @@
12011-04-08 Richard Sandiford <richard.sandiford@linaro.org>
2
3 Backport from mainline:
4 gcc/
5 * dwarf2out.c (dw_loc_list_node): Add resolved_addr and replaced.
6 (cached_dw_loc_list_def): New structure.
7 (cached_dw_loc_list): New typedef.
8 (cached_dw_loc_list_table): New variable.
9 (cached_dw_loc_list_table_hash): New function.
10 (cached_dw_loc_list_table_eq): Likewise.
11 (add_location_or_const_value_attribute): Take a bool cache_p.
12 Cache the list when the parameter is true.
13 (gen_formal_parameter_die): Update caller.
14 (gen_variable_die): Likewise.
15 (dwarf2out_finish): Likewise.
16 (dwarf2out_abstract_function): Nullify cached_dw_loc_list_table
17 while generating debug info for the decl.
18 (dwarf2out_function_decl): Clear cached_dw_loc_list_table.
19 (dwarf2out_init): Initialize cached_dw_loc_list_table.
20 (resolve_addr): Cache the result of resolving a chain of
21 location lists.
22
23 From: 2010-10-12 Jakub Jelinek <jakub@redhat.com>
24 * dwarf2out.c (dw_loc_list_node): Add emitted field.
25 (output_loc_list): Return immediately if emitted is set, set it.
26
27=== modified file 'gcc/dwarf2out.c'
28--- old/gcc/dwarf2out.c 2011-03-10 14:55:10 +0000
29+++ new/gcc/dwarf2out.c 2011-03-28 09:43:50 +0000
30@@ -4256,6 +4256,12 @@
31 Only on head of list */
32 const char *section; /* Section this loclist is relative to */
33 dw_loc_descr_ref expr;
34+ /* True if all addresses in this and subsequent lists are known to be
35+ resolved. */
36+ bool resolved_addr;
37+ /* True if this list has been replaced by dw_loc_next. */
38+ bool replaced;
39+ bool emitted;
40 } dw_loc_list_node;
41
42 #if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO)
43@@ -5759,6 +5765,19 @@
44 /* Table of decl location linked lists. */
45 static GTY ((param_is (var_loc_list))) htab_t decl_loc_table;
46
47+/* A cached location list. */
48+struct GTY (()) cached_dw_loc_list_def {
49+ /* The DECL_UID of the decl that this entry describes. */
50+ unsigned int decl_id;
51+
52+ /* The cached location list. */
53+ dw_loc_list_ref loc_list;
54+};
55+typedef struct cached_dw_loc_list_def cached_dw_loc_list;
56+
57+/* Table of cached location lists. */
58+static GTY ((param_is (cached_dw_loc_list))) htab_t cached_dw_loc_list_table;
59+
60 /* A pointer to the base of a list of references to DIE's that
61 are uniquely identified by their tag, presence/absence of
62 children DIE's, and list of attribute/value pairs. */
63@@ -6112,7 +6131,7 @@
64 static void insert_int (HOST_WIDE_INT, unsigned, unsigned char *);
65 static void insert_float (const_rtx, unsigned char *);
66 static rtx rtl_for_decl_location (tree);
67-static bool add_location_or_const_value_attribute (dw_die_ref, tree,
68+static bool add_location_or_const_value_attribute (dw_die_ref, tree, bool,
69 enum dwarf_attribute);
70 static bool tree_add_const_value_attribute (dw_die_ref, tree);
71 static bool tree_add_const_value_attribute_for_decl (dw_die_ref, tree);
72@@ -7731,6 +7750,24 @@
73 htab_find_with_hash (decl_loc_table, decl, DECL_UID (decl));
74 }
75
76+/* Returns a hash value for X (which really is a cached_dw_loc_list_list). */
77+
78+static hashval_t
79+cached_dw_loc_list_table_hash (const void *x)
80+{
81+ return (hashval_t) ((const cached_dw_loc_list *) x)->decl_id;
82+}
83+
84+/* Return nonzero if decl_id of cached_dw_loc_list X is the same as
85+ UID of decl *Y. */
86+
87+static int
88+cached_dw_loc_list_table_eq (const void *x, const void *y)
89+{
90+ return (((const cached_dw_loc_list *) x)->decl_id
91+ == DECL_UID ((const_tree) y));
92+}
93+
94 /* Equate a DIE to a particular declaration. */
95
96 static void
97@@ -10355,6 +10392,10 @@
98 {
99 dw_loc_list_ref curr = list_head;
100
101+ if (list_head->emitted)
102+ return;
103+ list_head->emitted = true;
104+
105 ASM_OUTPUT_LABEL (asm_out_file, list_head->ll_symbol);
106
107 /* Walk the location list, and output each range + expression. */
108@@ -15920,15 +15961,22 @@
109 these things can crop up in other ways also.) Note that one type of
110 constant value which can be passed into an inlined function is a constant
111 pointer. This can happen for example if an actual argument in an inlined
112- function call evaluates to a compile-time constant address. */
113+ function call evaluates to a compile-time constant address.
114+
115+ CACHE_P is true if it is worth caching the location list for DECL,
116+ so that future calls can reuse it rather than regenerate it from scratch.
117+ This is true for BLOCK_NONLOCALIZED_VARS in inlined subroutines,
118+ since we will need to refer to them each time the function is inlined. */
119
120 static bool
121-add_location_or_const_value_attribute (dw_die_ref die, tree decl,
122+add_location_or_const_value_attribute (dw_die_ref die, tree decl, bool cache_p,
123 enum dwarf_attribute attr)
124 {
125 rtx rtl;
126 dw_loc_list_ref list;
127 var_loc_list *loc_list;
128+ cached_dw_loc_list *cache;
129+ void **slot;
130
131 if (TREE_CODE (decl) == ERROR_MARK)
132 return false;
133@@ -15964,7 +16012,34 @@
134 && add_const_value_attribute (die, rtl))
135 return true;
136 }
137- list = loc_list_from_tree (decl, decl_by_reference_p (decl) ? 0 : 2);
138+ /* If this decl is from BLOCK_NONLOCALIZED_VARS, we might need its
139+ list several times. See if we've already cached the contents. */
140+ list = NULL;
141+ if (loc_list == NULL || cached_dw_loc_list_table == NULL)
142+ cache_p = false;
143+ if (cache_p)
144+ {
145+ cache = (cached_dw_loc_list *)
146+ htab_find_with_hash (cached_dw_loc_list_table, decl, DECL_UID (decl));
147+ if (cache)
148+ list = cache->loc_list;
149+ }
150+ if (list == NULL)
151+ {
152+ list = loc_list_from_tree (decl, decl_by_reference_p (decl) ? 0 : 2);
153+ /* It is usually worth caching this result if the decl is from
154+ BLOCK_NONLOCALIZED_VARS and if the list has at least two elements. */
155+ if (cache_p && list && list->dw_loc_next)
156+ {
157+ slot = htab_find_slot_with_hash (cached_dw_loc_list_table, decl,
158+ DECL_UID (decl), INSERT);
159+ cache = (cached_dw_loc_list *)
160+ ggc_alloc_cleared (sizeof (cached_dw_loc_list));
161+ cache->decl_id = DECL_UID (decl);
162+ cache->loc_list = list;
163+ *slot = cache;
164+ }
165+ }
166 if (list)
167 {
168 add_AT_location_description (die, attr, list);
169@@ -17532,7 +17607,7 @@
170 equate_decl_number_to_die (node, parm_die);
171 if (! DECL_ABSTRACT (node_or_origin))
172 add_location_or_const_value_attribute (parm_die, node_or_origin,
173- DW_AT_location);
174+ node == NULL, DW_AT_location);
175
176 break;
177
178@@ -17712,6 +17787,7 @@
179 tree context;
180 int was_abstract;
181 htab_t old_decl_loc_table;
182+ htab_t old_cached_dw_loc_list_table;
183
184 /* Make sure we have the actual abstract inline, not a clone. */
185 decl = DECL_ORIGIN (decl);
186@@ -17725,7 +17801,9 @@
187 DIE. Be sure to not clobber the outer location table nor use it or we would
188 get locations in abstract instantces. */
189 old_decl_loc_table = decl_loc_table;
190+ old_cached_dw_loc_list_table = cached_dw_loc_list_table;
191 decl_loc_table = NULL;
192+ cached_dw_loc_list_table = NULL;
193
194 /* Be sure we've emitted the in-class declaration DIE (if any) first, so
195 we don't get confused by DECL_ABSTRACT. */
196@@ -17750,6 +17828,7 @@
197
198 current_function_decl = save_fn;
199 decl_loc_table = old_decl_loc_table;
200+ cached_dw_loc_list_table = old_cached_dw_loc_list_table;
201 pop_cfun ();
202 }
203
204@@ -18431,9 +18510,8 @@
205 && !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl_or_origin)))
206 defer_location (decl_or_origin, var_die);
207 else
208- add_location_or_const_value_attribute (var_die,
209- decl_or_origin,
210- DW_AT_location);
211+ add_location_or_const_value_attribute (var_die, decl_or_origin,
212+ decl == NULL, DW_AT_location);
213 add_pubname (decl_or_origin, var_die);
214 }
215 else
216@@ -20049,6 +20127,7 @@
217 dwarf2out_decl (decl);
218
219 htab_empty (decl_loc_table);
220+ htab_empty (cached_dw_loc_list_table);
221 }
222
223 /* Output a marker (i.e. a label) for the beginning of the generated code for
224@@ -20649,6 +20728,11 @@
225 decl_loc_table = htab_create_ggc (10, decl_loc_table_hash,
226 decl_loc_table_eq, NULL);
227
228+ /* Allocate the cached_dw_loc_list_table. */
229+ cached_dw_loc_list_table
230+ = htab_create_ggc (10, cached_dw_loc_list_table_hash,
231+ cached_dw_loc_list_table_eq, NULL);
232+
233 /* Allocate the initial hunk of the decl_scope_table. */
234 decl_scope_table = VEC_alloc (tree, gc, 256);
235
236@@ -21278,30 +21362,53 @@
237 {
238 dw_die_ref c;
239 dw_attr_ref a;
240- dw_loc_list_ref *curr;
241+ dw_loc_list_ref *curr, *start, loc;
242 unsigned ix;
243
244 for (ix = 0; VEC_iterate (dw_attr_node, die->die_attr, ix, a); ix++)
245 switch (AT_class (a))
246 {
247 case dw_val_class_loc_list:
248- curr = AT_loc_list_ptr (a);
249- while (*curr)
250+ start = curr = AT_loc_list_ptr (a);
251+ loc = *curr;
252+ gcc_assert (loc);
253+ /* The same list can be referenced more than once. See if we have
254+ already recorded the result from a previous pass. */
255+ if (loc->replaced)
256+ *curr = loc->dw_loc_next;
257+ else if (!loc->resolved_addr)
258 {
259- if (!resolve_addr_in_expr ((*curr)->expr))
260+ /* As things stand, we do not expect or allow one die to
261+ reference a suffix of another die's location list chain.
262+ References must be identical or completely separate.
263+ There is therefore no need to cache the result of this
264+ pass on any list other than the first; doing so
265+ would lead to unnecessary writes. */
266+ while (*curr)
267 {
268- dw_loc_list_ref next = (*curr)->dw_loc_next;
269- if (next && (*curr)->ll_symbol)
270+ gcc_assert (!(*curr)->replaced && !(*curr)->resolved_addr);
271+ if (!resolve_addr_in_expr ((*curr)->expr))
272 {
273- gcc_assert (!next->ll_symbol);
274- next->ll_symbol = (*curr)->ll_symbol;
275+ dw_loc_list_ref next = (*curr)->dw_loc_next;
276+ if (next && (*curr)->ll_symbol)
277+ {
278+ gcc_assert (!next->ll_symbol);
279+ next->ll_symbol = (*curr)->ll_symbol;
280+ }
281+ *curr = next;
282 }
283- *curr = next;
284+ else
285+ curr = &(*curr)->dw_loc_next;
286 }
287+ if (loc == *start)
288+ loc->resolved_addr = 1;
289 else
290- curr = &(*curr)->dw_loc_next;
291+ {
292+ loc->replaced = 1;
293+ loc->dw_loc_next = *start;
294+ }
295 }
296- if (!AT_loc_list (a))
297+ if (!*start)
298 {
299 remove_AT (die, a->dw_attr);
300 ix--;
301@@ -21361,6 +21468,7 @@
302 add_location_or_const_value_attribute (
303 VEC_index (deferred_locations, deferred_locations_list, i)->die,
304 VEC_index (deferred_locations, deferred_locations_list, i)->variable,
305+ false,
306 DW_AT_location);
307 }
308
309