re PR target/65697 (__atomic memory barriers not strong enough for __sync builtins)
[gcc.git] / gcc / ipa-utils.h
index d2424f75e57c582277bee440d111d160e3ff8bbd..27b54ac44dc0852098bc469cc294ad5f4daf500d 100644 (file)
@@ -1,5 +1,5 @@
 /* Utilities for ipa analysis.
-   Copyright (C) 2004-2013 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,8 +20,6 @@ along with GCC; see the file COPYING3.  If not see
 
 #ifndef GCC_IPA_UTILS_H
 #define GCC_IPA_UTILS_H
-#include "tree-core.h"
-#include "cgraph.h"
 
 struct ipa_dfs_info {
   int dfn_number;
@@ -41,12 +39,12 @@ 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);
+                        struct cgraph_node *src, bool preserve_body = false);
 bool recursive_call_p (tree, tree);
 
 /* In ipa-profile.c  */
@@ -60,16 +58,41 @@ void build_type_inheritance_graph (void);
 void update_type_inheritance_graph (void);
 vec <cgraph_node *>
 possible_polymorphic_call_targets (tree, HOST_WIDE_INT,
-                                  bool *final = NULL,
-                                  void **cache_token = NULL);
+                                  ipa_polymorphic_call_context,
+                                  bool *copletep = NULL,
+                                  void **cache_token = NULL,
+                                  bool speuclative = false);
 odr_type get_odr_type (tree, bool insert = false);
-void dump_possible_polymorphic_call_targets (FILE *, tree, HOST_WIDE_INT);
+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,
-                                        struct cgraph_node *n);
-tree method_class_type (tree);
+                                        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 FINALP 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.
@@ -80,13 +103,34 @@ tree method_class_type (tree);
 
 inline vec <cgraph_node *>
 possible_polymorphic_call_targets (struct cgraph_edge *e,
-                                  bool *final = NULL,
-                                  void **cache_token = NULL)
+                                  bool *completep = NULL,
+                                  void **cache_token = NULL,
+                                  bool speculative = false)
 {
-  gcc_checking_assert (e->indirect_info->polymorphic);
+  ipa_polymorphic_call_context context(e);
+
   return possible_polymorphic_call_targets (e->indirect_info->otr_type,
                                            e->indirect_info->otr_token,
-                                           final, cache_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.  */
@@ -94,9 +138,11 @@ possible_polymorphic_call_targets (struct cgraph_edge *e,
 inline void
 dump_possible_polymorphic_call_targets (FILE *f, struct cgraph_edge *e)
 {
-  gcc_checking_assert (e->indirect_info->polymorphic);
+  ipa_polymorphic_call_context context(e);
+
   dump_possible_polymorphic_call_targets (f, e->indirect_info->otr_type,
-                                         e->indirect_info->otr_token);
+                                         e->indirect_info->otr_token,
+                                         context);
 }
 
 /* Return true if N can be possibly target of a polymorphic call of
@@ -106,21 +152,29 @@ 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, n);
+                                            e->indirect_info->otr_token,
+                                            context, n);
 }
 
-/* Return true if N can be possibly target of a polymorphic call of
-   OBJ_TYPE_REF expression CALL.  */
+/* 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
-possible_polymorphic_call_target_p (tree call,
-                                   struct cgraph_node *n)
+polymorphic_type_binfo_p (const_tree binfo)
 {
-  return possible_polymorphic_call_target_p (obj_type_ref_class (call),
-                                            tree_low_cst
-                                               (OBJ_TYPE_REF_TOKEN (call), 1),
-                                            n);
+  /* 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  */