re PR target/65697 (__atomic memory barriers not strong enough for __sync builtins)
[gcc.git] / gcc / ipa-utils.h
index c81232cfccee994e72114365de5931d2ff7d64e2..27b54ac44dc0852098bc469cc294ad5f4daf500d 100644 (file)
@@ -1,5 +1,5 @@
 /* Utilities for ipa analysis.
-   Copyright (C) 2004-2014 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.
@@ -20,7 +20,6 @@ along with GCC; see the file COPYING3.  If not see
 
 #ifndef GCC_IPA_UTILS_H
 #define GCC_IPA_UTILS_H
-#include "cgraph.h"
 
 struct ipa_dfs_info {
   int dfn_number;
@@ -34,101 +33,6 @@ struct ipa_dfs_info {
   PTR aux;
 };
 
-/* Context of polymorphic call.  This is used by ipa-devirt walkers of the
-   type inheritance graph.  */
-
-class ipa_polymorphic_call_context {
-public:
-  /* The called object appears in an object of type OUTER_TYPE
-     at offset OFFSET.  When information is not 100% reliable, we
-     use SPECULATIVE_OUTER_TYPE and SPECULATIVE_OFFSET. */
-  HOST_WIDE_INT offset;
-  HOST_WIDE_INT speculative_offset;
-  tree outer_type;
-  tree speculative_outer_type;
-  /* True if outer object may be in construction or destruction.  */
-  bool maybe_in_construction;
-  /* True if outer object may be of derived type.  */
-  bool maybe_derived_type;
-  /* True if speculative outer object may be of derived type.  We always
-     speculate that construction does not happen.  */
-  bool speculative_maybe_derived_type;
-  /* True if the context is invalid and all calls should be redirected
-     to BUILTIN_UNREACHABLE.  */
-  bool invalid;
-
-  /* Build empty "I know nothing" context.  */
-  ipa_polymorphic_call_context ();
-  /* Build polymorphic call context for indirect call E.  */
-  ipa_polymorphic_call_context (cgraph_edge *e);
-  /* Build polymorphic call context for IP invariant CST.
-     If specified, OTR_TYPE specify the type of polymorphic call
-     that takes CST+OFFSET as a prameter.  */
-  ipa_polymorphic_call_context (tree cst, tree otr_type = NULL,
-                               HOST_WIDE_INT offset = 0);
-  /* Build context for pointer REF contained in FNDECL at statement STMT.
-     if INSTANCE is non-NULL, return pointer to the object described by
-     the context.  */
-  ipa_polymorphic_call_context (tree fndecl, tree ref, gimple stmt,
-                               tree *instance = NULL);
-
-  /* Look for vtable stores or constructor calls to work out dynamic type
-     of memory location.  */
-  bool get_dynamic_type (tree, tree, tree, gimple);
-
-  /* Make context non-speculative.  */
-  void clear_speculation ();
-
-  /* Walk container types and modify context to point to actual class
-     containing EXPECTED_TYPE as base class.  */
-  bool restrict_to_inner_class (tree expected_type);
-
-private:
-  void set_by_decl (tree, HOST_WIDE_INT);
-  bool set_by_invariant (tree, tree, HOST_WIDE_INT);
-};
-
-/* Build polymorphic call context for indirect call E.  */
-
-inline
-ipa_polymorphic_call_context::ipa_polymorphic_call_context (cgraph_edge *e)
-{
-  gcc_checking_assert (e->indirect_info->polymorphic);
-
-  offset = e->indirect_info->offset;
-  speculative_offset = e->indirect_info->speculative_offset;
-  outer_type = e->indirect_info->outer_type;
-  speculative_outer_type = e->indirect_info->speculative_outer_type;
-  maybe_in_construction = e->indirect_info->maybe_in_construction;
-  maybe_derived_type = e->indirect_info->maybe_derived_type;
-  speculative_maybe_derived_type = e->indirect_info->speculative_maybe_derived_type;
-  invalid = false;
-}
-
-/* Build empty "I know nothing" context.  */
-
-inline
-ipa_polymorphic_call_context::ipa_polymorphic_call_context ()
-{
-  offset = 0;
-  speculative_offset = 0;
-  outer_type = NULL;
-  speculative_outer_type = NULL;
-  maybe_in_construction = true;
-  maybe_derived_type = true;
-  speculative_maybe_derived_type = false;
-  invalid = false;
-}
-
-/* Make context non-speculative.  */
-
-inline void
-ipa_polymorphic_call_context::clear_speculation ()
-{
-  speculative_outer_type = NULL;
-  speculative_offset = 0;
-  speculative_maybe_derived_type = false;
-}
 
 /* In ipa-utils.c  */
 void ipa_print_order (FILE*, const char *, struct cgraph_node**, int);
@@ -140,7 +44,7 @@ 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);
+                        struct cgraph_node *src, bool preserve_body = false);
 bool recursive_call_p (tree, tree);
 
 /* In ipa-profile.c  */
@@ -157,24 +61,38 @@ possible_polymorphic_call_targets (tree, HOST_WIDE_INT,
                                   ipa_polymorphic_call_context,
                                   bool *copletep = NULL,
                                   void **cache_token = NULL,
-                                  int *nonconstruction_targets = 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 method_class_type (const_tree);
+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 complette. 
+   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.
@@ -187,7 +105,7 @@ inline vec <cgraph_node *>
 possible_polymorphic_call_targets (struct cgraph_edge *e,
                                   bool *completep = NULL,
                                   void **cache_token = NULL,
-                                  int *nonconstruction_targets = NULL)
+                                  bool speculative = false)
 {
   ipa_polymorphic_call_context context(e);
 
@@ -195,7 +113,7 @@ possible_polymorphic_call_targets (struct cgraph_edge *e,
                                            e->indirect_info->otr_token,
                                            context,
                                            completep, cache_token,
-                                           nonconstruction_targets);
+                                           speculative);
 }
 
 /* Same as above but taking OBJ_TYPE_REF as an parameter.  */
@@ -241,21 +159,22 @@ possible_polymorphic_call_target_p (struct cgraph_edge *e,
                                             context, n);
 }
 
-/* Return true of T is type with One Definition Rule info attached. 
-   It means that either it is anonymous type or it has assembler name
-   set.  */
+/* Return true if BINFO corresponds to a type with virtual methods. 
 
-static inline bool
-odr_type_p (const_tree t)
-{
-  if (type_in_anonymous_namespace_p (t))
-    return true;
-  /* We do not have this information when not in LTO, but we do not need
-     to care, since it is used only for type merging.  */
-  gcc_assert (in_lto_p || flag_lto);
+   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.  */
 
-  return (TYPE_NAME (t)
-          && (DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (t))));
+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  */