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 {