diff options
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.patch | 309 |
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 @@ | |||
1 | 2011-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 | |||