re PR target/65697 (__atomic memory barriers not strong enough for __sync builtins)
[gcc.git] / gcc / ipa-icf.h
index 148135338887b48a1504af7ef6e296e6088f585a..67d5bdc90c5eb9c7f8ff344b110e5fc1234316e7 100644 (file)
@@ -87,28 +87,27 @@ public:
 
 /* Hash traits for symbol_compare_collection map.  */
 
-struct symbol_compare_hashmap_traits: default_hashmap_traits
+struct symbol_compare_hash : nofree_ptr_hash <symbol_compare_collection>
 {
   static hashval_t
-  hash (const symbol_compare_collection *v)
+  hash (value_type v)
   {
     inchash::hash hstate;
     hstate.add_int (v->m_references.length ());
 
     for (unsigned i = 0; i < v->m_references.length (); i++)
-      hstate.add_ptr (v->m_references[i]->ultimate_alias_target ());
+      hstate.add_int (v->m_references[i]->ultimate_alias_target ()->order);
 
     hstate.add_int (v->m_interposables.length ());
 
     for (unsigned i = 0; i < v->m_interposables.length (); i++)
-      hstate.add_ptr (v->m_interposables[i]->ultimate_alias_target ());
+      hstate.add_int (v->m_interposables[i]->ultimate_alias_target ()->order);
 
     return hstate.end ();
   }
 
   static bool
-  equal_keys (const symbol_compare_collection *a,
-             const symbol_compare_collection *b)
+  equal (value_type a, value_type b)
   {
     if (a->m_references.length () != b->m_references.length ()
        || a->m_interposables.length () != b->m_interposables.length ())
@@ -171,18 +170,6 @@ public:
   /* Add reference to a semantic TARGET.  */
   void add_reference (sem_item *target);
 
-  /* Gets symbol name of the item.  */
-  const char *name (void)
-  {
-    return node->name ();
-  }
-
-  /* Gets assembler name of the item.  */
-  const char *asm_name (void)
-  {
-    return node->asm_name ();
-  }
-
   /* Fast equality function based on knowledge known in WPA.  */
   virtual bool equals_wpa (sem_item *item,
                           hash_map <symtab_node *, sem_item *> &ignored_nodes) = 0;
@@ -201,6 +188,15 @@ public:
   /* Dump symbol to FILE.  */
   virtual void dump_to_file (FILE *file) = 0;
 
+  /* Update hash by address sensitive references.  */
+  void update_hash_by_addr_refs (hash_map <symtab_node *,
+                                sem_item *> &m_symtab_node_map);
+
+  /* Update hash by computed local hash values taken from different
+     semantic items.  */
+  void update_hash_by_local_refs (hash_map <symtab_node *,
+                                 sem_item *> &m_symtab_node_map);
+
   /* Return base tree that can be used for compatible_types_p and
      contains_polymorphic_type_p comparison.  */
   static bool get_base_types (tree *t1, tree *t2);
@@ -238,17 +234,39 @@ public:
   /* A set with symbol table references.  */
   hash_set <symtab_node *> refs_set;
 
+  /* Hash of item.  */
+  hashval_t hash;
+
+  /* Temporary hash used where hash values of references are added.  */
+  hashval_t global_hash;
 protected:
   /* Cached, once calculated hash for the item.  */
-  hashval_t hash;
 
-  /* Accumulate to HSTATE a hash of constructor expression EXP.  */
+  /* Accumulate to HSTATE a hash of expression EXP.  */
   static void add_expr (const_tree exp, inchash::hash &hstate);
+  /* Accumulate to HSTATE a hash of type T.  */
+  static void add_type (const_tree t, inchash::hash &hstate);
+
+  /* Compare properties of symbol that does not affect semantics of symbol
+     itself but affects semantics of its references.
+     If ADDRESS is true, do extra checking needed for IPA_REF_ADDR.  */
+  static bool compare_referenced_symbol_properties (symtab_node *used_by,
+                                                   symtab_node *n1,
+                                                   symtab_node *n2,
+                                                   bool address);
+
+  /* Compare two attribute lists.  */
+  static bool compare_attributes (const_tree list1, const_tree list2);
+
+  /* Hash properties compared by compare_referenced_symbol_properties.  */
+  void hash_referenced_symbol_properties (symtab_node *ref,
+                                         inchash::hash &hstate,
+                                         bool address);
 
   /* For a given symbol table nodes N1 and N2, we check that FUNCTION_DECLs
      point to a same function. Comparison can be skipped if IGNORED_NODES
      contains these nodes.  ADDRESS indicate if address is taken.  */
-  bool compare_cgraph_references (hash_map <symtab_node *, sem_item *>
+  bool compare_symbol_references (hash_map <symtab_node *, sem_item *>
                                  &ignored_nodes,
                                  symtab_node *n1, symtab_node *n2,
                                  bool address);
@@ -273,7 +291,6 @@ public:
 
   inline virtual void init_wpa (void)
   {
-    parse_tree_args ();
   }
 
   virtual void init (void);
@@ -291,9 +308,6 @@ public:
     dump_function_to_file (decl, file, TDF_DETAILS);
   }
 
-  /* Parses function arguments and result type.  */
-  void parse_tree_args (void);
-
   /* Returns cgraph_node.  */
   inline cgraph_node *get_node (void)
   {
@@ -310,15 +324,13 @@ public:
      semantic function item.  */
   static sem_function *parse (cgraph_node *node, bitmap_obstack *stack);
 
+  /* Perform additional checks needed to match types of used function
+     paramters.  */
+  bool compatible_parm_types_p (tree, tree);
+
   /* Exception handling region tree.  */
   eh_region region_tree;
 
-  /* Result type tree node.  */
-  tree result_type;
-
-  /* Array of argument tree types.  */
-  vec <tree> arg_types;
-
   /* Number of function arguments.  */
   unsigned int arg_count;
 
@@ -340,6 +352,9 @@ public:
   /* Array of structures for all basic blocks.  */
   vec <ipa_icf_gimple::sem_bb *> bb_sorted;
 
+  /* Return true if parameter I may be used.  */
+  bool param_used_p (unsigned int i);
+
 private:
   /* Calculates hash value based on a BASIC_BLOCK.  */
   hashval_t get_bb_hash (const ipa_icf_gimple::sem_bb *basic_block);
@@ -353,18 +368,12 @@ private:
      corresponds to TARGET.  */
   bool bb_dict_test (vec<int> *bb_dict, int source, int target);
 
-  /* Iterates all tree types in T1 and T2 and returns true if all types
-     are compatible. If COMPARE_POLYMORPHIC is set to true,
-     more strict comparison is executed.  */
-  bool compare_type_list (tree t1, tree t2, bool compare_polymorphic);
-
   /* If cgraph edges E1 and E2 are indirect calls, verify that
      ICF flags are the same.  */
   bool compare_edge_flags (cgraph_edge *e1, cgraph_edge *e2);
 
   /* Processes function equality comparison.  */
-  bool equals_private (sem_item *item,
-                      hash_map <symtab_node *, sem_item *> &ignored_nodes);
+  bool equals_private (sem_item *item);
 
   /* Returns true if tree T can be compared as a handled component.  */
   static bool icf_handled_component_p (tree t);
@@ -415,15 +424,8 @@ public:
   static sem_variable *parse (varpool_node *node, bitmap_obstack *stack);
 
 private:
-  /* Iterates though a constructor and identifies tree references
-     we are interested in semantic function equality.  */
-  void parse_tree_refs (tree t);
-
   /* Compares trees T1 and T2 for semantic equality.  */
   static bool equals (tree t1, tree t2);
-
-  /* Compare that symbol sections are either NULL or have same name.  */
-  bool compare_sections (sem_variable *alias);
 }; // class sem_variable
 
 class sem_item_optimizer;
@@ -436,17 +438,15 @@ struct congruence_class_group
 };
 
 /* Congruence class set structure.  */
-struct congruence_class_group_hash: typed_noop_remove <congruence_class_group>
+struct congruence_class_group_hash : nofree_ptr_hash <congruence_class_group>
 {
-  typedef congruence_class_group value_type;
-  typedef congruence_class_group compare_type;
-
-  static inline hashval_t hash (const value_type *item)
+  static inline hashval_t hash (const congruence_class_group *item)
   {
     return item->hash;
   }
 
-  static inline int equal (const value_type *item1, const compare_type *item2)
+  static inline int equal (const congruence_class_group *item1,
+                          const congruence_class_group *item2)
   {
     return item1->hash == item2->hash && item1->type == item2->type;
   }
@@ -516,8 +516,13 @@ public:
   congruence_class_group *get_group_by_hash (hashval_t hash,
       sem_item_type type);
 
+  /* Because types can be arbitrarily large, avoid quadratic bottleneck.  */
+  hash_map<const_tree, hashval_t> m_type_hash_cache;
 private:
 
+  /* For each semantic item, append hash values of references.  */
+  void update_hash_by_addr_refs ();
+
   /* Congruence classes are built by hash value.  */
   void build_hash_based_classes (void);