+2018-06-08 Martin Liska <mliska@suse.cz>
+
+ * ipa-inline-analysis.c (inline_edge_removal_hook): Remove.
+ (initialize_growth_caches): Remove.
+ (free_growth_caches): Likewise.
+ (do_estimate_edge_time): Use edge_growth_cache.
+ (do_estimate_edge_size): Likewise.
+ (do_estimate_edge_hints): Likewise.
+ * ipa-inline.c (reset_edge_caches): Likewise.
+ (recursive_inlining): Likewise.
+ (inline_small_functions): Likewise.
+ * ipa-inline.h (initialize_growth_caches): Remove.
+ (estimate_edge_size): Likewise.
+ (estimate_edge_time): Likewise.
+ (estimate_edge_hints): Likewise.
+ (reset_edge_growth_cache): Likewise.
+ * symbol-summary.h (call_summary::remove): New method.
+
2018-06-08 Martin Liska <mliska@suse.cz>
* ipa-cp.c (class edge_clone_summary): New summary.
#include "gimplify.h"
/* Cached node/edge growths. */
-vec<edge_growth_cache_entry> edge_growth_cache;
-static struct cgraph_edge_hook_list *edge_removal_hook_holder;
-
+call_summary<edge_growth_cache_entry *> *edge_growth_cache = NULL;
/* Give initial reasons why inlining would fail on EDGE. This gets either
nullified or usually overwritten by more precise reasons later. */
}
-/* Keep edge cache consistent across edge removal. */
-
-static void
-inline_edge_removal_hook (struct cgraph_edge *edge,
- void *data ATTRIBUTE_UNUSED)
-{
- reset_edge_growth_cache (edge);
-}
-
-
-/* Initialize growth caches. */
-
-void
-initialize_growth_caches (void)
-{
- if (!edge_removal_hook_holder)
- edge_removal_hook_holder =
- symtab->add_edge_removal_hook (&inline_edge_removal_hook, NULL);
- if (symtab->edges_max_uid)
- edge_growth_cache.safe_grow_cleared (symtab->edges_max_uid);
-}
-
-
/* Free growth caches. */
void
free_growth_caches (void)
{
- if (edge_removal_hook_holder)
- {
- symtab->remove_edge_removal_hook (edge_removal_hook_holder);
- edge_removal_hook_holder = NULL;
- }
- edge_growth_cache.release ();
+ delete edge_growth_cache;
+ edge_growth_cache = NULL;
}
/* Return hints derrived from EDGE. */
gcc_checking_assert (time >= 0);
/* When caching, update the cache entry. */
- if (edge_growth_cache.exists ())
+ if (edge_growth_cache != NULL)
{
ipa_fn_summaries->get_create (edge->callee)->min_size = min_size;
- if ((int) edge_growth_cache.length () <= edge->uid)
- edge_growth_cache.safe_grow_cleared (symtab->edges_max_uid);
- edge_growth_cache[edge->uid].time = time;
- edge_growth_cache[edge->uid].nonspec_time = nonspec_time;
+ edge_growth_cache_entry *entry
+ = edge_growth_cache->get_create (edge);
+ entry->time = time;
+ entry->nonspec_time = nonspec_time;
- edge_growth_cache[edge->uid].size = size + (size >= 0);
+ entry->size = size + (size >= 0);
hints |= simple_edge_hints (edge);
- edge_growth_cache[edge->uid].hints = hints + 1;
+ entry->hints = hints + 1;
}
return time;
}
/* When we do caching, use do_estimate_edge_time to populate the entry. */
- if (edge_growth_cache.exists ())
+ if (edge_growth_cache != NULL)
{
do_estimate_edge_time (edge);
- size = edge_growth_cache[edge->uid].size;
+ size = edge_growth_cache->get (edge)->size;
gcc_checking_assert (size);
return size - (size > 0);
}
/* When we do caching, use do_estimate_edge_time to populate the entry. */
- if (edge_growth_cache.exists ())
+ if (edge_growth_cache != NULL)
{
do_estimate_edge_time (edge);
- hints = edge_growth_cache[edge->uid].hints;
+ hints = edge_growth_cache->get (edge)->hints;
gcc_checking_assert (hints);
return hints - 1;
}
if (where->global.inlined_to)
where = where->global.inlined_to;
- for (edge = where->callers; edge; edge = edge->next_caller)
- if (edge->inline_failed)
- reset_edge_growth_cache (edge);
+ if (edge_growth_cache != NULL)
+ for (edge = where->callers; edge; edge = edge->next_caller)
+ if (edge->inline_failed)
+ edge_growth_cache->remove (edge);
FOR_EACH_ALIAS (where, ref)
reset_edge_caches (dyn_cast <cgraph_node *> (ref->referring));
e = e->callee->callees;
else
{
- if (e->inline_failed)
- reset_edge_growth_cache (e);
+ if (edge_growth_cache != NULL && e->inline_failed)
+ edge_growth_cache->remove (e);
if (e->next_callee)
e = e->next_callee;
else
if (master_clone)
{
curr->redirect_callee (master_clone);
- reset_edge_growth_cache (curr);
+ if (edge_growth_cache != NULL)
+ edge_growth_cache->remove (curr);
}
if (estimate_size_after_inlining (node, curr) > limit)
{
curr->redirect_callee (dest);
- reset_edge_growth_cache (curr);
+ if (edge_growth_cache != NULL)
+ edge_growth_cache->remove (curr);
break;
}
if (!want_inline_self_recursive_call_p (curr, node, false, depth))
{
curr->redirect_callee (dest);
- reset_edge_growth_cache (curr);
+ if (edge_growth_cache != NULL)
+ edge_growth_cache->remove (curr);
continue;
}
if (!e->inline_failed)
clone_inlined_nodes (e, true, false, NULL);
curr->redirect_callee (master_clone);
- reset_edge_growth_cache (curr);
+ if (edge_growth_cache != NULL)
+ edge_growth_cache->remove (curr);
}
inline_call (curr, false, new_edges, &overall_size, true);
max_count = max_count.max (edge->count.ipa ());
}
ipa_free_postorder_info ();
- initialize_growth_caches ();
+ edge_growth_cache
+ = new call_summary<edge_growth_cache_entry *> (symtab, false);
if (dump_file)
fprintf (dump_file,
sreal old_time_est = estimate_edge_time (edge);
int old_hints_est = estimate_edge_hints (edge);
- reset_edge_growth_cache (edge);
+ if (edge_growth_cache != NULL)
+ edge_growth_cache->remove (edge);
gcc_assert (old_size_est == estimate_edge_size (edge));
gcc_assert (old_time_est == estimate_edge_time (edge));
/* FIXME:
for given invocation but that will be better done once whole
code is converted to sreals. Disable for now and revert to "wrong"
value so enable/disable checking paths agree. */
- edge_growth_cache[edge->uid].hints = old_hints_est + 1;
+ edge_growth_cache->get (edge)->hints = old_hints_est + 1;
/* When updating the edge costs, we only decrease badness in the keys.
Increases of badness are handled lazilly; when we see key with out
hints (hints) {}
};
-extern vec<edge_growth_cache_entry> edge_growth_cache;
+extern call_summary<edge_growth_cache_entry *> *edge_growth_cache;
/* In ipa-inline-analysis.c */
int estimate_size_after_inlining (struct cgraph_node *, struct cgraph_edge *);
int do_estimate_edge_size (struct cgraph_edge *edge);
sreal do_estimate_edge_time (struct cgraph_edge *edge);
ipa_hints do_estimate_edge_hints (struct cgraph_edge *edge);
-void initialize_growth_caches (void);
void free_growth_caches (void);
/* In ipa-inline.c */
static inline int
estimate_edge_size (struct cgraph_edge *edge)
{
- int ret;
- if ((int)edge_growth_cache.length () <= edge->uid
- || !(ret = edge_growth_cache[edge->uid].size))
+ edge_growth_cache_entry *entry;
+ if (edge_growth_cache == NULL
+ || (entry = edge_growth_cache->get (edge)) == NULL
+ || entry->size == 0)
return do_estimate_edge_size (edge);
- return ret - (ret > 0);
+ return entry->size - (entry->size > 0);
}
/* Return estimated callee growth after inlining EDGE. */
static inline sreal
estimate_edge_time (struct cgraph_edge *edge, sreal *nonspec_time = NULL)
{
- sreal ret;
- if ((int)edge_growth_cache.length () <= edge->uid
- || !edge_growth_cache[edge->uid].size)
+ edge_growth_cache_entry *entry;
+ if (edge_growth_cache == NULL
+ || (entry = edge_growth_cache->get (edge)) == NULL
+ || entry->time == 0)
return do_estimate_edge_time (edge);
if (nonspec_time)
- *nonspec_time = edge_growth_cache[edge->uid].nonspec_time;
- return edge_growth_cache[edge->uid].time;
+ *nonspec_time = edge_growth_cache->get (edge)->nonspec_time;
+ return entry->time;
}
static inline ipa_hints
estimate_edge_hints (struct cgraph_edge *edge)
{
- ipa_hints ret;
- if ((int)edge_growth_cache.length () <= edge->uid
- || !(ret = edge_growth_cache[edge->uid].hints))
+ edge_growth_cache_entry *entry;
+ if (edge_growth_cache == NULL
+ || (entry = edge_growth_cache->get (edge)) == NULL
+ || entry->hints == 0)
return do_estimate_edge_hints (edge);
- return ret - 1;
-}
-
-/* Reset cached value for EDGE. */
-
-static inline void
-reset_edge_growth_cache (struct cgraph_edge *edge)
-{
- if ((int)edge_growth_cache.length () > edge->uid)
- {
- struct edge_growth_cache_entry zero (0, 0, 0, 0);
- edge_growth_cache[edge->uid] = zero;
- }
+ return entry->hints - 1;
}
#endif /* GCC_IPA_INLINE_H */
return get (hashable_uid (edge), false);
}
+ /* Remove edge from summary. */
+ void remove (cgraph_edge *edge)
+ {
+ int uid = hashable_uid (edge);
+ T **v = m_map.get (uid);
+ if (v)
+ {
+ m_map.remove (uid);
+ release (*v);
+ }
+ }
+
/* Return number of elements handled by data structure. */
size_t elements ()
{