Mercurial > hg > CbC > CbC_gcc
comparison gcc/ipa-inline-analysis.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
111:04ced10e8804 | 131:84e7813d76e9 |
---|---|
1 /* Analysis used by inlining decision heuristics. | 1 /* Analysis used by inlining decision heuristics. |
2 Copyright (C) 2003-2017 Free Software Foundation, Inc. | 2 Copyright (C) 2003-2018 Free Software Foundation, Inc. |
3 Contributed by Jan Hubicka | 3 Contributed by Jan Hubicka |
4 | 4 |
5 This file is part of GCC. | 5 This file is part of GCC. |
6 | 6 |
7 GCC is free software; you can redistribute it and/or modify it under | 7 GCC is free software; you can redistribute it and/or modify it under |
45 #include "ipa-fnsummary.h" | 45 #include "ipa-fnsummary.h" |
46 #include "ipa-inline.h" | 46 #include "ipa-inline.h" |
47 #include "cfgloop.h" | 47 #include "cfgloop.h" |
48 #include "tree-scalar-evolution.h" | 48 #include "tree-scalar-evolution.h" |
49 #include "ipa-utils.h" | 49 #include "ipa-utils.h" |
50 #include "cilk.h" | |
51 #include "cfgexpand.h" | 50 #include "cfgexpand.h" |
52 #include "gimplify.h" | 51 #include "gimplify.h" |
53 | 52 |
54 /* Cached node/edge growths. */ | 53 /* Cached node/edge growths. */ |
55 vec<edge_growth_cache_entry> edge_growth_cache; | 54 call_summary<edge_growth_cache_entry *> *edge_growth_cache = NULL; |
56 static struct cgraph_edge_hook_list *edge_removal_hook_holder; | |
57 | |
58 | 55 |
59 /* Give initial reasons why inlining would fail on EDGE. This gets either | 56 /* Give initial reasons why inlining would fail on EDGE. This gets either |
60 nullified or usually overwritten by more precise reasons later. */ | 57 nullified or usually overwritten by more precise reasons later. */ |
61 | 58 |
62 void | 59 void |
79 || cgraph_inline_failed_type (e->inline_failed) | 76 || cgraph_inline_failed_type (e->inline_failed) |
80 == CIF_FINAL_ERROR); | 77 == CIF_FINAL_ERROR); |
81 } | 78 } |
82 | 79 |
83 | 80 |
84 /* Keep edge cache consistent across edge removal. */ | |
85 | |
86 static void | |
87 inline_edge_removal_hook (struct cgraph_edge *edge, | |
88 void *data ATTRIBUTE_UNUSED) | |
89 { | |
90 reset_edge_growth_cache (edge); | |
91 } | |
92 | |
93 | |
94 /* Initialize growth caches. */ | |
95 | |
96 void | |
97 initialize_growth_caches (void) | |
98 { | |
99 if (!edge_removal_hook_holder) | |
100 edge_removal_hook_holder = | |
101 symtab->add_edge_removal_hook (&inline_edge_removal_hook, NULL); | |
102 if (symtab->edges_max_uid) | |
103 edge_growth_cache.safe_grow_cleared (symtab->edges_max_uid); | |
104 } | |
105 | |
106 | |
107 /* Free growth caches. */ | 81 /* Free growth caches. */ |
108 | 82 |
109 void | 83 void |
110 free_growth_caches (void) | 84 free_growth_caches (void) |
111 { | 85 { |
112 if (edge_removal_hook_holder) | 86 delete edge_growth_cache; |
113 { | 87 edge_growth_cache = NULL; |
114 symtab->remove_edge_removal_hook (edge_removal_hook_holder); | |
115 edge_removal_hook_holder = NULL; | |
116 } | |
117 edge_growth_cache.release (); | |
118 } | 88 } |
119 | 89 |
120 /* Return hints derrived from EDGE. */ | 90 /* Return hints derrived from EDGE. */ |
121 | 91 |
122 int | 92 int |
124 { | 94 { |
125 int hints = 0; | 95 int hints = 0; |
126 struct cgraph_node *to = (edge->caller->global.inlined_to | 96 struct cgraph_node *to = (edge->caller->global.inlined_to |
127 ? edge->caller->global.inlined_to : edge->caller); | 97 ? edge->caller->global.inlined_to : edge->caller); |
128 struct cgraph_node *callee = edge->callee->ultimate_alias_target (); | 98 struct cgraph_node *callee = edge->callee->ultimate_alias_target (); |
129 if (ipa_fn_summaries->get (to)->scc_no | 99 int to_scc_no = ipa_fn_summaries->get (to)->scc_no; |
130 && ipa_fn_summaries->get (to)->scc_no | 100 int callee_scc_no = ipa_fn_summaries->get (callee)->scc_no; |
131 == ipa_fn_summaries->get (callee)->scc_no | 101 |
132 && !edge->recursive_p ()) | 102 if (to_scc_no && to_scc_no == callee_scc_no && !edge->recursive_p ()) |
133 hints |= INLINE_HINT_same_scc; | 103 hints |= INLINE_HINT_same_scc; |
134 | 104 |
135 if (callee->lto_file_data && edge->caller->lto_file_data | 105 if (callee->lto_file_data && edge->caller->lto_file_data |
136 && edge->caller->lto_file_data != callee->lto_file_data | 106 && edge->caller->lto_file_data != callee->lto_file_data |
137 && !callee->merged_comdat && !callee->icf_merged) | 107 && !callee->merged_comdat && !callee->icf_merged) |
173 | 143 |
174 /* When we have profile feedback, we can quite safely identify hot | 144 /* When we have profile feedback, we can quite safely identify hot |
175 edges and for those we disable size limits. Don't do that when | 145 edges and for those we disable size limits. Don't do that when |
176 probability that caller will call the callee is low however, since it | 146 probability that caller will call the callee is low however, since it |
177 may hurt optimization of the caller's hot path. */ | 147 may hurt optimization of the caller's hot path. */ |
178 if (edge->count.initialized_p () && edge->maybe_hot_p () | 148 if (edge->count.ipa ().initialized_p () && edge->maybe_hot_p () |
179 && (edge->count.apply_scale (2, 1) | 149 && (edge->count.ipa ().apply_scale (2, 1) |
180 > (edge->caller->global.inlined_to | 150 > (edge->caller->global.inlined_to |
181 ? edge->caller->global.inlined_to->count | 151 ? edge->caller->global.inlined_to->count.ipa () |
182 : edge->caller->count))) | 152 : edge->caller->count.ipa ()))) |
183 hints |= INLINE_HINT_known_hot; | 153 hints |= INLINE_HINT_known_hot; |
184 | 154 |
185 known_vals.release (); | 155 known_vals.release (); |
186 known_contexts.release (); | 156 known_contexts.release (); |
187 known_aggs.release (); | 157 known_aggs.release (); |
188 gcc_checking_assert (size >= 0); | 158 gcc_checking_assert (size >= 0); |
189 gcc_checking_assert (time >= 0); | 159 gcc_checking_assert (time >= 0); |
190 | 160 |
191 /* When caching, update the cache entry. */ | 161 /* When caching, update the cache entry. */ |
192 if (edge_growth_cache.exists ()) | 162 if (edge_growth_cache != NULL) |
193 { | 163 { |
194 ipa_fn_summaries->get (edge->callee)->min_size = min_size; | 164 ipa_fn_summaries->get_create (edge->callee)->min_size = min_size; |
195 if ((int) edge_growth_cache.length () <= edge->uid) | 165 edge_growth_cache_entry *entry |
196 edge_growth_cache.safe_grow_cleared (symtab->edges_max_uid); | 166 = edge_growth_cache->get_create (edge); |
197 edge_growth_cache[edge->uid].time = time; | 167 entry->time = time; |
198 edge_growth_cache[edge->uid].nonspec_time = nonspec_time; | 168 entry->nonspec_time = nonspec_time; |
199 | 169 |
200 edge_growth_cache[edge->uid].size = size + (size >= 0); | 170 entry->size = size + (size >= 0); |
201 hints |= simple_edge_hints (edge); | 171 hints |= simple_edge_hints (edge); |
202 edge_growth_cache[edge->uid].hints = hints + 1; | 172 entry->hints = hints + 1; |
203 } | 173 } |
204 return time; | 174 return time; |
205 } | 175 } |
206 | 176 |
207 | 177 |
218 vec<ipa_polymorphic_call_context> known_contexts; | 188 vec<ipa_polymorphic_call_context> known_contexts; |
219 vec<ipa_agg_jump_function_p> known_aggs; | 189 vec<ipa_agg_jump_function_p> known_aggs; |
220 | 190 |
221 /* When we do caching, use do_estimate_edge_time to populate the entry. */ | 191 /* When we do caching, use do_estimate_edge_time to populate the entry. */ |
222 | 192 |
223 if (edge_growth_cache.exists ()) | 193 if (edge_growth_cache != NULL) |
224 { | 194 { |
225 do_estimate_edge_time (edge); | 195 do_estimate_edge_time (edge); |
226 size = edge_growth_cache[edge->uid].size; | 196 size = edge_growth_cache->get (edge)->size; |
227 gcc_checking_assert (size); | 197 gcc_checking_assert (size); |
228 return size - (size > 0); | 198 return size - (size > 0); |
229 } | 199 } |
230 | 200 |
231 callee = edge->callee->ultimate_alias_target (); | 201 callee = edge->callee->ultimate_alias_target (); |
259 vec<ipa_polymorphic_call_context> known_contexts; | 229 vec<ipa_polymorphic_call_context> known_contexts; |
260 vec<ipa_agg_jump_function_p> known_aggs; | 230 vec<ipa_agg_jump_function_p> known_aggs; |
261 | 231 |
262 /* When we do caching, use do_estimate_edge_time to populate the entry. */ | 232 /* When we do caching, use do_estimate_edge_time to populate the entry. */ |
263 | 233 |
264 if (edge_growth_cache.exists ()) | 234 if (edge_growth_cache != NULL) |
265 { | 235 { |
266 do_estimate_edge_time (edge); | 236 do_estimate_edge_time (edge); |
267 hints = edge_growth_cache[edge->uid].hints; | 237 hints = edge_growth_cache->get (edge)->hints; |
268 gcc_checking_assert (hints); | 238 gcc_checking_assert (hints); |
269 return hints - 1; | 239 return hints - 1; |
270 } | 240 } |
271 | 241 |
272 callee = edge->callee->ultimate_alias_target (); | 242 callee = edge->callee->ultimate_alias_target (); |
293 int | 263 int |
294 estimate_size_after_inlining (struct cgraph_node *node, | 264 estimate_size_after_inlining (struct cgraph_node *node, |
295 struct cgraph_edge *edge) | 265 struct cgraph_edge *edge) |
296 { | 266 { |
297 struct ipa_call_summary *es = ipa_call_summaries->get (edge); | 267 struct ipa_call_summary *es = ipa_call_summaries->get (edge); |
268 ipa_fn_summary *s = ipa_fn_summaries->get (node); | |
298 if (!es->predicate || *es->predicate != false) | 269 if (!es->predicate || *es->predicate != false) |
299 { | 270 { |
300 int size = ipa_fn_summaries->get (node)->size + estimate_edge_growth (edge); | 271 int size = s->size + estimate_edge_growth (edge); |
301 gcc_assert (size >= 0); | 272 gcc_assert (size >= 0); |
302 return size; | 273 return size; |
303 } | 274 } |
304 return ipa_fn_summaries->get (node)->size; | 275 return s->size; |
305 } | 276 } |
306 | 277 |
307 | 278 |
308 struct growth_data | 279 struct growth_data |
309 { | 280 { |