/* Utilities for ipa analysis.
- Copyright (C) 2004, 2005, 2007, 2011, 2012 Free Software Foundation, Inc.
+ Copyright (C) 2004-2015 Free Software Foundation, Inc.
Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
This file is part of GCC.
#ifndef GCC_IPA_UTILS_H
#define GCC_IPA_UTILS_H
-#include "tree.h"
-#include "cgraph.h"
struct ipa_dfs_info {
int dfn_number;
};
-
/* In ipa-utils.c */
void ipa_print_order (FILE*, const char *, struct cgraph_node**, int);
int ipa_reduced_postorder (struct cgraph_node **, bool, bool,
bool (*ignore_edge) (struct cgraph_edge *));
void ipa_free_postorder_info (void);
-vec<cgraph_node_ptr> ipa_get_nodes_in_cycle (struct cgraph_node *);
+vec<cgraph_node *> ipa_get_nodes_in_cycle (struct cgraph_node *);
+bool ipa_edge_within_scc (struct cgraph_edge *);
int ipa_reverse_postorder (struct cgraph_node **);
tree get_base_var (tree);
+void ipa_merge_profiles (struct cgraph_node *dst,
+ struct cgraph_node *src, bool preserve_body = false);
+bool recursive_call_p (tree, tree);
+
+/* In ipa-profile.c */
+bool ipa_propagate_frequency (struct cgraph_node *node);
+
+/* In ipa-devirt.c */
+
+struct odr_type_d;
+typedef odr_type_d *odr_type;
+void build_type_inheritance_graph (void);
+void update_type_inheritance_graph (void);
+vec <cgraph_node *>
+possible_polymorphic_call_targets (tree, HOST_WIDE_INT,
+ ipa_polymorphic_call_context,
+ bool *copletep = NULL,
+ void **cache_token = NULL,
+ bool speuclative = false);
+odr_type get_odr_type (tree, bool insert = false);
+bool type_in_anonymous_namespace_p (const_tree);
+bool type_with_linkage_p (const_tree);
+bool odr_type_p (const_tree);
+bool possible_polymorphic_call_target_p (tree ref, gimple stmt, struct cgraph_node *n);
+void dump_possible_polymorphic_call_targets (FILE *, tree, HOST_WIDE_INT,
+ const ipa_polymorphic_call_context &);
+bool possible_polymorphic_call_target_p (tree, HOST_WIDE_INT,
+ const ipa_polymorphic_call_context &,
+ struct cgraph_node *);
+tree inlined_polymorphic_ctor_dtor_block_p (tree, bool);
+bool decl_maybe_in_construction_p (tree, tree, gimple, tree);
+tree vtable_pointer_value_to_binfo (const_tree);
+bool vtable_pointer_value_to_vtable (const_tree, tree *, unsigned HOST_WIDE_INT *);
+tree subbinfo_with_vtable_at_offset (tree, unsigned HOST_WIDE_INT, tree);
+void compare_virtual_tables (varpool_node *, varpool_node *);
+bool type_all_derivations_known_p (const_tree);
+bool type_known_to_have_no_derivations_p (tree);
+bool contains_polymorphic_type_p (const_tree);
+void register_odr_type (tree);
+bool types_must_be_same_for_odr (tree, tree);
+bool types_odr_comparable (tree, tree, bool strict = false);
+cgraph_node *try_speculative_devirtualization (tree, HOST_WIDE_INT,
+ ipa_polymorphic_call_context);
+void warn_types_mismatch (tree t1, tree t2, location_t loc1 = UNKNOWN_LOCATION,
+ location_t loc2 = UNKNOWN_LOCATION);
+bool odr_or_derived_type_p (const_tree t);
+bool odr_types_equivalent_p (tree type1, tree type2);
+
+/* Return vector containing possible targets of polymorphic call E.
+ If COMPLETEP is non-NULL, store true if the list is complete.
+ CACHE_TOKEN (if non-NULL) will get stored to an unique ID of entry
+ in the target cache. If user needs to visit every target list
+ just once, it can memoize them.
+
+ Returned vector is placed into cache. It is NOT caller's responsibility
+ to free it. The vector can be freed on cgraph_remove_node call if
+ the particular node is a virtual function present in the cache. */
+
+inline vec <cgraph_node *>
+possible_polymorphic_call_targets (struct cgraph_edge *e,
+ bool *completep = NULL,
+ void **cache_token = NULL,
+ bool speculative = false)
+{
+ ipa_polymorphic_call_context context(e);
+
+ return possible_polymorphic_call_targets (e->indirect_info->otr_type,
+ e->indirect_info->otr_token,
+ context,
+ completep, cache_token,
+ speculative);
+}
+
+/* Same as above but taking OBJ_TYPE_REF as an parameter. */
+
+inline vec <cgraph_node *>
+possible_polymorphic_call_targets (tree ref,
+ gimple call,
+ bool *completep = NULL,
+ void **cache_token = NULL)
+{
+ ipa_polymorphic_call_context context (current_function_decl, ref, call);
+
+ return possible_polymorphic_call_targets (obj_type_ref_class (ref),
+ tree_to_uhwi
+ (OBJ_TYPE_REF_TOKEN (ref)),
+ context,
+ completep, cache_token);
+}
+
+/* Dump possible targets of a polymorphic call E into F. */
+
+inline void
+dump_possible_polymorphic_call_targets (FILE *f, struct cgraph_edge *e)
+{
+ ipa_polymorphic_call_context context(e);
+
+ dump_possible_polymorphic_call_targets (f, e->indirect_info->otr_type,
+ e->indirect_info->otr_token,
+ context);
+}
+
+/* Return true if N can be possibly target of a polymorphic call of
+ E. */
+
+inline bool
+possible_polymorphic_call_target_p (struct cgraph_edge *e,
+ struct cgraph_node *n)
+{
+ ipa_polymorphic_call_context context(e);
+
+ return possible_polymorphic_call_target_p (e->indirect_info->otr_type,
+ e->indirect_info->otr_token,
+ context, n);
+}
+
+/* Return true if BINFO corresponds to a type with virtual methods.
+ Every type has several BINFOs. One is the BINFO associated by the type
+ while other represents bases of derived types. The BINFOs representing
+ bases do not have BINFO_VTABLE pointer set when this is the single
+ inheritance (because vtables are shared). Look up the BINFO of type
+ and check presence of its vtable. */
+inline bool
+polymorphic_type_binfo_p (const_tree binfo)
+{
+ /* See if BINFO's type has an virtual table associtated with it.
+ Check is defensive because of Java FE produces BINFOs
+ without BINFO_TYPE set. */
+ return (BINFO_TYPE (binfo) && TYPE_BINFO (BINFO_TYPE (binfo))
+ && BINFO_VTABLE (TYPE_BINFO (BINFO_TYPE (binfo))));
+}
#endif /* GCC_IPA_UTILS_H */