138fd1498Szrj /* Interprocedural semantic function equality pass 238fd1498Szrj Copyright (C) 2014-2018 Free Software Foundation, Inc. 338fd1498Szrj 438fd1498Szrj Contributed by Jan Hubicka <hubicka@ucw.cz> and Martin Liska <mliska@suse.cz> 538fd1498Szrj 638fd1498Szrj This file is part of GCC. 738fd1498Szrj 838fd1498Szrj GCC is free software; you can redistribute it and/or modify it under 938fd1498Szrj the terms of the GNU General Public License as published by the Free 1038fd1498Szrj Software Foundation; either version 3, or (at your option) any later 1138fd1498Szrj version. 1238fd1498Szrj 1338fd1498Szrj GCC is distributed in the hope that it will be useful, but WITHOUT ANY 1438fd1498Szrj WARRANTY; without even the implied warranty of MERCHANTABILITY or 1538fd1498Szrj FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1638fd1498Szrj for more details. 1738fd1498Szrj 1838fd1498Szrj You should have received a copy of the GNU General Public License 1938fd1498Szrj along with GCC; see the file COPYING3. If not see 2038fd1498Szrj <http://www.gnu.org/licenses/>. */ 2138fd1498Szrj 2238fd1498Szrj namespace ipa_icf { 2338fd1498Szrj class sem_item; 2438fd1498Szrj 2538fd1498Szrj /* Congruence class encompasses a collection of either functions or 2638fd1498Szrj read-only variables. These items are considered to be equivalent 2738fd1498Szrj if not proved the oposite. */ 2838fd1498Szrj class congruence_class 2938fd1498Szrj { 3038fd1498Szrj public: 3138fd1498Szrj /* Congruence class constructor for a new class with _ID. */ congruence_class(unsigned int _id)3238fd1498Szrj congruence_class (unsigned int _id): in_worklist (false), id(_id) 3338fd1498Szrj { 3438fd1498Szrj } 3538fd1498Szrj 3638fd1498Szrj /* Destructor. */ ~congruence_class()3738fd1498Szrj ~congruence_class () 3838fd1498Szrj { 3938fd1498Szrj } 4038fd1498Szrj 4138fd1498Szrj /* Dump function prints all class members to a FILE with an INDENT. */ 4238fd1498Szrj void dump (FILE *file, unsigned int indent = 0) const; 4338fd1498Szrj 4438fd1498Szrj /* Returns true if there's a member that is used from another group. */ 4538fd1498Szrj bool is_class_used (void); 4638fd1498Szrj 4738fd1498Szrj /* Flag is used in case we want to remove a class from worklist and 4838fd1498Szrj delete operation is quite expensive for 4938fd1498Szrj the data structure (linked list). */ 5038fd1498Szrj bool in_worklist; 5138fd1498Szrj 5238fd1498Szrj /* Vector of all group members. */ 5338fd1498Szrj auto_vec <sem_item *> members; 5438fd1498Szrj 5538fd1498Szrj /* Global unique class identifier. */ 5638fd1498Szrj unsigned int id; 5738fd1498Szrj }; 5838fd1498Szrj 5938fd1498Szrj /* Semantic item type enum. */ 6038fd1498Szrj enum sem_item_type 6138fd1498Szrj { 6238fd1498Szrj FUNC, 6338fd1498Szrj VAR 6438fd1498Szrj }; 6538fd1498Szrj 6638fd1498Szrj /* Class is container for address references for a symtab_node. */ 6738fd1498Szrj 6838fd1498Szrj class symbol_compare_collection 6938fd1498Szrj { 7038fd1498Szrj public: 7138fd1498Szrj /* Constructor. */ 7238fd1498Szrj symbol_compare_collection (symtab_node *node); 7338fd1498Szrj 7438fd1498Szrj /* Destructor. */ ~symbol_compare_collection()7538fd1498Szrj ~symbol_compare_collection () 7638fd1498Szrj { 7738fd1498Szrj m_references.release (); 7838fd1498Szrj m_interposables.release (); 7938fd1498Szrj } 8038fd1498Szrj 8138fd1498Szrj /* Vector of address references. */ 8238fd1498Szrj vec<symtab_node *> m_references; 8338fd1498Szrj 8438fd1498Szrj /* Vector of interposable references. */ 8538fd1498Szrj vec<symtab_node *> m_interposables; 8638fd1498Szrj }; 8738fd1498Szrj 8838fd1498Szrj /* Hash traits for symbol_compare_collection map. */ 8938fd1498Szrj 9038fd1498Szrj struct symbol_compare_hash : nofree_ptr_hash <symbol_compare_collection> 9138fd1498Szrj { 9238fd1498Szrj static hashval_t hashsymbol_compare_hash9338fd1498Szrj hash (value_type v) 9438fd1498Szrj { 9538fd1498Szrj inchash::hash hstate; 9638fd1498Szrj hstate.add_int (v->m_references.length ()); 9738fd1498Szrj 9838fd1498Szrj for (unsigned i = 0; i < v->m_references.length (); i++) 9938fd1498Szrj hstate.add_int (v->m_references[i]->ultimate_alias_target ()->order); 10038fd1498Szrj 10138fd1498Szrj hstate.add_int (v->m_interposables.length ()); 10238fd1498Szrj 10338fd1498Szrj for (unsigned i = 0; i < v->m_interposables.length (); i++) 10438fd1498Szrj hstate.add_int (v->m_interposables[i]->ultimate_alias_target ()->order); 10538fd1498Szrj 10638fd1498Szrj return hstate.end (); 10738fd1498Szrj } 10838fd1498Szrj 10938fd1498Szrj static bool equalsymbol_compare_hash11038fd1498Szrj equal (value_type a, value_type b) 11138fd1498Szrj { 11238fd1498Szrj if (a->m_references.length () != b->m_references.length () 11338fd1498Szrj || a->m_interposables.length () != b->m_interposables.length ()) 11438fd1498Szrj return false; 11538fd1498Szrj 11638fd1498Szrj for (unsigned i = 0; i < a->m_references.length (); i++) 11738fd1498Szrj if (a->m_references[i]->equal_address_to (b->m_references[i]) != 1) 11838fd1498Szrj return false; 11938fd1498Szrj 12038fd1498Szrj for (unsigned i = 0; i < a->m_interposables.length (); i++) 12138fd1498Szrj if (!a->m_interposables[i]->semantically_equivalent_p 12238fd1498Szrj (b->m_interposables[i])) 12338fd1498Szrj return false; 12438fd1498Szrj 12538fd1498Szrj return true; 12638fd1498Szrj } 12738fd1498Szrj }; 12838fd1498Szrj 12938fd1498Szrj 13038fd1498Szrj /* Semantic item usage pair. */ 13138fd1498Szrj class sem_usage_pair 13238fd1498Szrj { 13338fd1498Szrj public: 13438fd1498Szrj /* Constructor for key value pair, where _ITEM is key and _INDEX is a target. */ 13538fd1498Szrj sem_usage_pair (sem_item *_item, unsigned int _index); 13638fd1498Szrj 13738fd1498Szrj /* Target semantic item where an item is used. */ 13838fd1498Szrj sem_item *item; 13938fd1498Szrj 14038fd1498Szrj /* Index of usage of such an item. */ 14138fd1498Szrj unsigned int index; 14238fd1498Szrj }; 14338fd1498Szrj 14438fd1498Szrj typedef std::pair<symtab_node *, symtab_node *> symtab_pair; 14538fd1498Szrj 14638fd1498Szrj /* Semantic item is a base class that encapsulates all shared functionality 14738fd1498Szrj for both semantic function and variable items. */ 14838fd1498Szrj class sem_item 14938fd1498Szrj { 15038fd1498Szrj public: 15138fd1498Szrj /* Semantic item constructor for a node of _TYPE, where STACK is used 15238fd1498Szrj for bitmap memory allocation. */ 15338fd1498Szrj sem_item (sem_item_type _type, bitmap_obstack *stack); 15438fd1498Szrj 15538fd1498Szrj /* Semantic item constructor for a node of _TYPE, where STACK is used 15638fd1498Szrj for bitmap memory allocation. The item is based on symtab node _NODE. */ 15738fd1498Szrj sem_item (sem_item_type _type, symtab_node *_node, bitmap_obstack *stack); 15838fd1498Szrj 15938fd1498Szrj virtual ~sem_item (); 16038fd1498Szrj 16138fd1498Szrj /* Dump function for debugging purpose. */ 16238fd1498Szrj DEBUG_FUNCTION void dump (void); 16338fd1498Szrj 16438fd1498Szrj /* Initialize semantic item by info reachable during LTO WPA phase. */ 16538fd1498Szrj virtual void init_wpa (void) = 0; 16638fd1498Szrj 16738fd1498Szrj /* Semantic item initialization function. */ 16838fd1498Szrj virtual void init (void) = 0; 16938fd1498Szrj 17038fd1498Szrj /* Add reference to a semantic TARGET. */ 17138fd1498Szrj void add_reference (sem_item *target); 17238fd1498Szrj 17338fd1498Szrj /* Fast equality function based on knowledge known in WPA. */ 17438fd1498Szrj virtual bool equals_wpa (sem_item *item, 17538fd1498Szrj hash_map <symtab_node *, sem_item *> &ignored_nodes) = 0; 17638fd1498Szrj 17738fd1498Szrj /* Returns true if the item equals to ITEM given as arguemnt. */ 17838fd1498Szrj virtual bool equals (sem_item *item, 17938fd1498Szrj hash_map <symtab_node *, sem_item *> &ignored_nodes) = 0; 18038fd1498Szrj 18138fd1498Szrj /* References independent hash function. */ 18238fd1498Szrj virtual hashval_t get_hash (void) = 0; 18338fd1498Szrj 18438fd1498Szrj /* Set new hash value of the item. */ 18538fd1498Szrj void set_hash (hashval_t hash); 18638fd1498Szrj 18738fd1498Szrj /* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can 18838fd1498Szrj be applied. */ 18938fd1498Szrj virtual bool merge (sem_item *alias_item) = 0; 19038fd1498Szrj 19138fd1498Szrj /* Dump symbol to FILE. */ 19238fd1498Szrj virtual void dump_to_file (FILE *file) = 0; 19338fd1498Szrj 19438fd1498Szrj /* Update hash by address sensitive references. */ 19538fd1498Szrj void update_hash_by_addr_refs (hash_map <symtab_node *, 19638fd1498Szrj sem_item *> &m_symtab_node_map); 19738fd1498Szrj 19838fd1498Szrj /* Update hash by computed local hash values taken from different 19938fd1498Szrj semantic items. */ 20038fd1498Szrj void update_hash_by_local_refs (hash_map <symtab_node *, 20138fd1498Szrj sem_item *> &m_symtab_node_map); 20238fd1498Szrj 20338fd1498Szrj /* Return base tree that can be used for compatible_types_p and 20438fd1498Szrj contains_polymorphic_type_p comparison. */ 20538fd1498Szrj static bool get_base_types (tree *t1, tree *t2); 20638fd1498Szrj 20738fd1498Szrj /* Return true if target supports alias symbols. */ 20838fd1498Szrj bool target_supports_symbol_aliases_p (void); 20938fd1498Szrj 21038fd1498Szrj /* Item type. */ 21138fd1498Szrj sem_item_type type; 21238fd1498Szrj 21338fd1498Szrj /* Symtab node. */ 21438fd1498Szrj symtab_node *node; 21538fd1498Szrj 21638fd1498Szrj /* Declaration tree node. */ 21738fd1498Szrj tree decl; 21838fd1498Szrj 21938fd1498Szrj /* Semantic references used that generate congruence groups. */ 22038fd1498Szrj vec <sem_item *> refs; 22138fd1498Szrj 22238fd1498Szrj /* Pointer to a congruence class the item belongs to. */ 22338fd1498Szrj congruence_class *cls; 22438fd1498Szrj 22538fd1498Szrj /* Index of the item in a class belonging to. */ 22638fd1498Szrj unsigned int index_in_class; 22738fd1498Szrj 22838fd1498Szrj /* List of semantic items where the instance is used. */ 22938fd1498Szrj vec <sem_usage_pair *> usages; 23038fd1498Szrj 23138fd1498Szrj /* A bitmap with indices of all classes referencing this item. */ 23238fd1498Szrj bitmap usage_index_bitmap; 23338fd1498Szrj 23438fd1498Szrj /* List of tree references (either FUNC_DECL or VAR_DECL). */ 23538fd1498Szrj vec <tree> tree_refs; 23638fd1498Szrj 23738fd1498Szrj /* A set with symbol table references. */ 23838fd1498Szrj hash_set <symtab_node *> refs_set; 23938fd1498Szrj 24038fd1498Szrj /* Temporary hash used where hash values of references are added. */ 24138fd1498Szrj hashval_t global_hash; 24238fd1498Szrj protected: 24338fd1498Szrj /* Cached, once calculated hash for the item. */ 24438fd1498Szrj 24538fd1498Szrj /* Accumulate to HSTATE a hash of expression EXP. */ 24638fd1498Szrj static void add_expr (const_tree exp, inchash::hash &hstate); 24738fd1498Szrj /* Accumulate to HSTATE a hash of type T. */ 24838fd1498Szrj static void add_type (const_tree t, inchash::hash &hstate); 24938fd1498Szrj 25038fd1498Szrj /* Compare properties of symbol that does not affect semantics of symbol 25138fd1498Szrj itself but affects semantics of its references. 25238fd1498Szrj If ADDRESS is true, do extra checking needed for IPA_REF_ADDR. */ 25338fd1498Szrj static bool compare_referenced_symbol_properties (symtab_node *used_by, 25438fd1498Szrj symtab_node *n1, 25538fd1498Szrj symtab_node *n2, 25638fd1498Szrj bool address); 25738fd1498Szrj 25838fd1498Szrj /* Compare two attribute lists. */ 25938fd1498Szrj static bool compare_attributes (const_tree list1, const_tree list2); 26038fd1498Szrj 26138fd1498Szrj /* Hash properties compared by compare_referenced_symbol_properties. */ 26238fd1498Szrj void hash_referenced_symbol_properties (symtab_node *ref, 26338fd1498Szrj inchash::hash &hstate, 26438fd1498Szrj bool address); 26538fd1498Szrj 26638fd1498Szrj /* For a given symbol table nodes N1 and N2, we check that FUNCTION_DECLs 26738fd1498Szrj point to a same function. Comparison can be skipped if IGNORED_NODES 26838fd1498Szrj contains these nodes. ADDRESS indicate if address is taken. */ 26938fd1498Szrj bool compare_symbol_references (hash_map <symtab_node *, sem_item *> 27038fd1498Szrj &ignored_nodes, 27138fd1498Szrj symtab_node *n1, symtab_node *n2, 27238fd1498Szrj bool address); 27338fd1498Szrj protected: 27438fd1498Szrj /* Hash of item. */ 27538fd1498Szrj hashval_t m_hash; 27638fd1498Szrj 27738fd1498Szrj /* Indicated whether a hash value has been set or not. */ 27838fd1498Szrj bool m_hash_set; 27938fd1498Szrj 28038fd1498Szrj private: 28138fd1498Szrj /* Initialize internal data structures. Bitmap STACK is used for 28238fd1498Szrj bitmap memory allocation process. */ 28338fd1498Szrj void setup (bitmap_obstack *stack); 28438fd1498Szrj }; // class sem_item 28538fd1498Szrj 28638fd1498Szrj class sem_function: public sem_item 28738fd1498Szrj { 28838fd1498Szrj public: 28938fd1498Szrj /* Semantic function constructor that uses STACK as bitmap memory stack. */ 29038fd1498Szrj sem_function (bitmap_obstack *stack); 29138fd1498Szrj 29238fd1498Szrj /* Constructor based on callgraph node _NODE. 29338fd1498Szrj Bitmap STACK is used for memory allocation. */ 29438fd1498Szrj sem_function (cgraph_node *_node, bitmap_obstack *stack); 29538fd1498Szrj 29638fd1498Szrj ~sem_function (); 29738fd1498Szrj init_wpa(void)29838fd1498Szrj inline virtual void init_wpa (void) 29938fd1498Szrj { 30038fd1498Szrj } 30138fd1498Szrj 30238fd1498Szrj virtual void init (void); 30338fd1498Szrj virtual bool equals_wpa (sem_item *item, 30438fd1498Szrj hash_map <symtab_node *, sem_item *> &ignored_nodes); 30538fd1498Szrj virtual hashval_t get_hash (void); 30638fd1498Szrj virtual bool equals (sem_item *item, 30738fd1498Szrj hash_map <symtab_node *, sem_item *> &ignored_nodes); 30838fd1498Szrj virtual bool merge (sem_item *alias_item); 30938fd1498Szrj 31038fd1498Szrj /* Dump symbol to FILE. */ dump_to_file(FILE * file)31138fd1498Szrj virtual void dump_to_file (FILE *file) 31238fd1498Szrj { 31338fd1498Szrj gcc_assert (file); 31438fd1498Szrj dump_function_to_file (decl, file, TDF_DETAILS); 31538fd1498Szrj } 31638fd1498Szrj 31738fd1498Szrj /* Returns cgraph_node. */ get_node(void)31838fd1498Szrj inline cgraph_node *get_node (void) 31938fd1498Szrj { 32038fd1498Szrj return dyn_cast <cgraph_node *> (node); 32138fd1498Szrj } 32238fd1498Szrj 32338fd1498Szrj /* Improve accumulated hash for HSTATE based on a gimple statement STMT. */ 32438fd1498Szrj void hash_stmt (gimple *stmt, inchash::hash &inchash); 32538fd1498Szrj 32638fd1498Szrj /* Return true if polymorphic comparison must be processed. */ 32738fd1498Szrj bool compare_polymorphic_p (void); 32838fd1498Szrj 32938fd1498Szrj /* For a given call graph NODE, the function constructs new 33038fd1498Szrj semantic function item. */ 33138fd1498Szrj static sem_function *parse (cgraph_node *node, bitmap_obstack *stack); 33238fd1498Szrj 33338fd1498Szrj /* Perform additional checks needed to match types of used function 33438fd1498Szrj paramters. */ 33538fd1498Szrj bool compatible_parm_types_p (tree, tree); 33638fd1498Szrj 33738fd1498Szrj /* Exception handling region tree. */ 33838fd1498Szrj eh_region region_tree; 33938fd1498Szrj 34038fd1498Szrj /* Number of function arguments. */ 34138fd1498Szrj unsigned int arg_count; 34238fd1498Szrj 34338fd1498Szrj /* Total amount of edges in the function. */ 34438fd1498Szrj unsigned int edge_count; 34538fd1498Szrj 34638fd1498Szrj /* Vector of sizes of all basic blocks. */ 34738fd1498Szrj vec <unsigned int> bb_sizes; 34838fd1498Szrj 34938fd1498Szrj /* Control flow graph checksum. */ 35038fd1498Szrj hashval_t cfg_checksum; 35138fd1498Szrj 35238fd1498Szrj /* GIMPLE codes hash value. */ 35338fd1498Szrj hashval_t gcode_hash; 35438fd1498Szrj 35538fd1498Szrj /* Total number of SSA names used in the function. */ 35638fd1498Szrj unsigned ssa_names_size; 35738fd1498Szrj 35838fd1498Szrj /* Array of structures for all basic blocks. */ 35938fd1498Szrj vec <ipa_icf_gimple::sem_bb *> bb_sorted; 36038fd1498Szrj 36138fd1498Szrj /* Return true if parameter I may be used. */ 36238fd1498Szrj bool param_used_p (unsigned int i); 36338fd1498Szrj 36438fd1498Szrj private: 36538fd1498Szrj /* Calculates hash value based on a BASIC_BLOCK. */ 36638fd1498Szrj hashval_t get_bb_hash (const ipa_icf_gimple::sem_bb *basic_block); 36738fd1498Szrj 36838fd1498Szrj /* For given basic blocks BB1 and BB2 (from functions FUNC1 and FUNC), 36938fd1498Szrj true value is returned if phi nodes are semantically 37038fd1498Szrj equivalent in these blocks . */ 37138fd1498Szrj bool compare_phi_node (basic_block bb1, basic_block bb2); 37238fd1498Szrj 37338fd1498Szrj /* Basic blocks dictionary BB_DICT returns true if SOURCE index BB 37438fd1498Szrj corresponds to TARGET. */ 37538fd1498Szrj bool bb_dict_test (vec<int> *bb_dict, int source, int target); 37638fd1498Szrj 37738fd1498Szrj /* If cgraph edges E1 and E2 are indirect calls, verify that 37838fd1498Szrj ICF flags are the same. */ 37938fd1498Szrj bool compare_edge_flags (cgraph_edge *e1, cgraph_edge *e2); 38038fd1498Szrj 38138fd1498Szrj /* Processes function equality comparison. */ 38238fd1498Szrj bool equals_private (sem_item *item); 38338fd1498Szrj 38438fd1498Szrj /* Returns true if tree T can be compared as a handled component. */ 38538fd1498Szrj static bool icf_handled_component_p (tree t); 38638fd1498Szrj 38738fd1498Szrj /* Function checker stores binding between functions. */ 38838fd1498Szrj ipa_icf_gimple::func_checker *m_checker; 38938fd1498Szrj 39038fd1498Szrj /* COMPARED_FUNC is a function that we compare to. */ 39138fd1498Szrj sem_function *m_compared_func; 39238fd1498Szrj }; // class sem_function 39338fd1498Szrj 39438fd1498Szrj class sem_variable: public sem_item 39538fd1498Szrj { 39638fd1498Szrj public: 39738fd1498Szrj /* Semantic variable constructor that uses STACK as bitmap memory stack. */ 39838fd1498Szrj sem_variable (bitmap_obstack *stack); 39938fd1498Szrj 40038fd1498Szrj /* Constructor based on callgraph node _NODE. 40138fd1498Szrj Bitmap STACK is used for memory allocation. */ 40238fd1498Szrj 40338fd1498Szrj sem_variable (varpool_node *_node, bitmap_obstack *stack); 40438fd1498Szrj init_wpa(void)40538fd1498Szrj inline virtual void init_wpa (void) {} 40638fd1498Szrj 40738fd1498Szrj /* Semantic variable initialization function. */ init(void)40838fd1498Szrj inline virtual void init (void) 40938fd1498Szrj { 41038fd1498Szrj decl = get_node ()->decl; 41138fd1498Szrj } 41238fd1498Szrj 41338fd1498Szrj virtual hashval_t get_hash (void); 41438fd1498Szrj virtual bool merge (sem_item *alias_item); 41538fd1498Szrj virtual void dump_to_file (FILE *file); 41638fd1498Szrj virtual bool equals (sem_item *item, 41738fd1498Szrj hash_map <symtab_node *, sem_item *> &ignored_nodes); 41838fd1498Szrj 41938fd1498Szrj /* Fast equality variable based on knowledge known in WPA. */ 42038fd1498Szrj virtual bool equals_wpa (sem_item *item, 42138fd1498Szrj hash_map <symtab_node *, sem_item *> &ignored_nodes); 42238fd1498Szrj 42338fd1498Szrj /* Returns varpool_node. */ get_node(void)42438fd1498Szrj inline varpool_node *get_node (void) 42538fd1498Szrj { 42638fd1498Szrj return dyn_cast <varpool_node *> (node); 42738fd1498Szrj } 42838fd1498Szrj 42938fd1498Szrj /* Parser function that visits a varpool NODE. */ 43038fd1498Szrj static sem_variable *parse (varpool_node *node, bitmap_obstack *stack); 43138fd1498Szrj 43238fd1498Szrj private: 43338fd1498Szrj /* Compares trees T1 and T2 for semantic equality. */ 43438fd1498Szrj static bool equals (tree t1, tree t2); 43538fd1498Szrj }; // class sem_variable 43638fd1498Szrj 43738fd1498Szrj class sem_item_optimizer; 43838fd1498Szrj 43938fd1498Szrj struct congruence_class_group 44038fd1498Szrj { 44138fd1498Szrj hashval_t hash; 44238fd1498Szrj sem_item_type type; 44338fd1498Szrj vec <congruence_class *> classes; 44438fd1498Szrj }; 44538fd1498Szrj 44638fd1498Szrj /* Congruence class set structure. */ 44738fd1498Szrj struct congruence_class_hash : nofree_ptr_hash <congruence_class_group> 44838fd1498Szrj { hashcongruence_class_hash44938fd1498Szrj static inline hashval_t hash (const congruence_class_group *item) 45038fd1498Szrj { 45138fd1498Szrj return item->hash; 45238fd1498Szrj } 45338fd1498Szrj equalcongruence_class_hash45438fd1498Szrj static inline int equal (const congruence_class_group *item1, 45538fd1498Szrj const congruence_class_group *item2) 45638fd1498Szrj { 45738fd1498Szrj return item1->hash == item2->hash && item1->type == item2->type; 45838fd1498Szrj } 45938fd1498Szrj }; 46038fd1498Szrj 46138fd1498Szrj struct traverse_split_pair 46238fd1498Szrj { 46338fd1498Szrj sem_item_optimizer *optimizer; 46438fd1498Szrj class congruence_class *cls; 46538fd1498Szrj }; 46638fd1498Szrj 46738fd1498Szrj /* Semantic item optimizer includes all top-level logic 46838fd1498Szrj related to semantic equality comparison. */ 46938fd1498Szrj class sem_item_optimizer 47038fd1498Szrj { 47138fd1498Szrj public: 47238fd1498Szrj sem_item_optimizer (); 47338fd1498Szrj ~sem_item_optimizer (); 47438fd1498Szrj 47538fd1498Szrj /* Function responsible for visiting all potential functions and 47638fd1498Szrj read-only variables that can be merged. */ 47738fd1498Szrj void parse_funcs_and_vars (void); 47838fd1498Szrj 47938fd1498Szrj /* Optimizer entry point which returns true in case it processes 48038fd1498Szrj a merge operation. True is returned if there's a merge operation 48138fd1498Szrj processed. */ 48238fd1498Szrj bool execute (void); 48338fd1498Szrj 48438fd1498Szrj /* Dump function. */ 48538fd1498Szrj void dump (void); 48638fd1498Szrj 48738fd1498Szrj /* Verify congruence classes if checking is enabled. */ 48838fd1498Szrj void checking_verify_classes (void); 48938fd1498Szrj 49038fd1498Szrj /* Verify congruence classes. */ 49138fd1498Szrj void verify_classes (void); 49238fd1498Szrj 49338fd1498Szrj /* Write IPA ICF summary for symbols. */ 49438fd1498Szrj void write_summary (void); 49538fd1498Szrj 49638fd1498Szrj /* Read IPA ICF summary for symbols. */ 49738fd1498Szrj void read_summary (void); 49838fd1498Szrj 49938fd1498Szrj /* Callgraph removal hook called for a NODE with a custom DATA. */ 50038fd1498Szrj static void cgraph_removal_hook (cgraph_node *node, void *data); 50138fd1498Szrj 50238fd1498Szrj /* Varpool removal hook called for a NODE with a custom DATA. */ 50338fd1498Szrj static void varpool_removal_hook (varpool_node *node, void *data); 50438fd1498Szrj 50538fd1498Szrj /* Worklist of congruence classes that can potentially 50638fd1498Szrj refine classes of congruence. */ 50738fd1498Szrj std::list<congruence_class *> worklist; 50838fd1498Szrj 50938fd1498Szrj /* Remove semantic ITEM and release memory. */ 51038fd1498Szrj void remove_item (sem_item *item); 51138fd1498Szrj 51238fd1498Szrj /* Remove symtab NODE triggered by symtab removal hooks. */ 51338fd1498Szrj void remove_symtab_node (symtab_node *node); 51438fd1498Szrj 51538fd1498Szrj /* Register callgraph and varpool hooks. */ 51638fd1498Szrj void register_hooks (void); 51738fd1498Szrj 51838fd1498Szrj /* Unregister callgraph and varpool hooks. */ 51938fd1498Szrj void unregister_hooks (void); 52038fd1498Szrj 52138fd1498Szrj /* Adds a CLS to hashtable associated by hash value. */ 52238fd1498Szrj void add_class (congruence_class *cls); 52338fd1498Szrj 52438fd1498Szrj /* Gets a congruence class group based on given HASH value and TYPE. */ 52538fd1498Szrj congruence_class_group *get_group_by_hash (hashval_t hash, 52638fd1498Szrj sem_item_type type); 52738fd1498Szrj 52838fd1498Szrj /* Because types can be arbitrarily large, avoid quadratic bottleneck. */ 52938fd1498Szrj hash_map<const_tree, hashval_t> m_type_hash_cache; 53038fd1498Szrj private: 53138fd1498Szrj 53238fd1498Szrj /* For each semantic item, append hash values of references. */ 53338fd1498Szrj void update_hash_by_addr_refs (); 53438fd1498Szrj 53538fd1498Szrj /* Congruence classes are built by hash value. */ 53638fd1498Szrj void build_hash_based_classes (void); 53738fd1498Szrj 53838fd1498Szrj /* Semantic items in classes having more than one element and initialized. 53938fd1498Szrj In case of WPA, we load function body. */ 54038fd1498Szrj void parse_nonsingleton_classes (void); 54138fd1498Szrj 54238fd1498Szrj /* Equality function for semantic items is used to subdivide existing 54338fd1498Szrj classes. If IN_WPA, fast equality function is invoked. */ 54438fd1498Szrj void subdivide_classes_by_equality (bool in_wpa = false); 54538fd1498Szrj 54638fd1498Szrj /* Subdivide classes by address and interposable references 54738fd1498Szrj that members of the class reference. 54838fd1498Szrj Example can be a pair of functions that have an address 54938fd1498Szrj taken from a function. If these addresses are different the class 55038fd1498Szrj is split. */ 55138fd1498Szrj unsigned subdivide_classes_by_sensitive_refs(); 55238fd1498Szrj 55338fd1498Szrj /* Debug function prints all informations about congruence classes. */ 55438fd1498Szrj void dump_cong_classes (void); 55538fd1498Szrj 55638fd1498Szrj /* Build references according to call graph. */ 55738fd1498Szrj void build_graph (void); 55838fd1498Szrj 55938fd1498Szrj /* Iterative congruence reduction function. */ 56038fd1498Szrj void process_cong_reduction (void); 56138fd1498Szrj 56238fd1498Szrj /* After reduction is done, we can declare all items in a group 56338fd1498Szrj to be equal. PREV_CLASS_COUNT is start number of classes 56438fd1498Szrj before reduction. True is returned if there's a merge operation 56538fd1498Szrj processed. */ 56638fd1498Szrj bool merge_classes (unsigned int prev_class_count); 56738fd1498Szrj 56838fd1498Szrj /* Fixup points to analysis info. */ 56938fd1498Szrj void fixup_points_to_sets (void); 57038fd1498Szrj 57138fd1498Szrj /* Fixup points to set PT. */ 57238fd1498Szrj void fixup_pt_set (struct pt_solution *pt); 57338fd1498Szrj 57438fd1498Szrj /* Adds a newly created congruence class CLS to worklist. */ 57538fd1498Szrj void worklist_push (congruence_class *cls); 57638fd1498Szrj 57738fd1498Szrj /* Pops a class from worklist. */ 57838fd1498Szrj congruence_class *worklist_pop (); 57938fd1498Szrj 58038fd1498Szrj /* Every usage of a congruence class CLS is a candidate that can split the 58138fd1498Szrj collection of classes. Bitmap stack BMSTACK is used for bitmap 58238fd1498Szrj allocation. */ 58338fd1498Szrj void do_congruence_step (congruence_class *cls); 58438fd1498Szrj 58538fd1498Szrj /* Tests if a class CLS used as INDEXth splits any congruence classes. 58638fd1498Szrj Bitmap stack BMSTACK is used for bitmap allocation. */ 58738fd1498Szrj void do_congruence_step_for_index (congruence_class *cls, unsigned int index); 58838fd1498Szrj 58938fd1498Szrj /* Makes pairing between a congruence class CLS and semantic ITEM. */ 59038fd1498Szrj static void add_item_to_class (congruence_class *cls, sem_item *item); 59138fd1498Szrj 59238fd1498Szrj /* Disposes split map traverse function. CLS is congruence 59338fd1498Szrj class, BSLOT is bitmap slot we want to release. DATA is mandatory, 59438fd1498Szrj but unused argument. */ 59538fd1498Szrj static bool release_split_map (congruence_class * const &cls, bitmap const &b, 59638fd1498Szrj traverse_split_pair *pair); 59738fd1498Szrj 59838fd1498Szrj /* Process split operation for a cognruence class CLS, 59938fd1498Szrj where bitmap B splits congruence class members. DATA is used 60038fd1498Szrj as argument of split pair. */ 60138fd1498Szrj static bool traverse_congruence_split (congruence_class * const &cls, 60238fd1498Szrj bitmap const &b, 60338fd1498Szrj traverse_split_pair *pair); 60438fd1498Szrj 605*58e805e6Szrj /* Compare function for sorting pairs in do_congruence_step_f. */ 606*58e805e6Szrj static int sort_congruence_split (const void *, const void *); 607*58e805e6Szrj 60838fd1498Szrj /* Reads a section from LTO stream file FILE_DATA. Input block for DATA 60938fd1498Szrj contains LEN bytes. */ 61038fd1498Szrj void read_section (lto_file_decl_data *file_data, const char *data, 61138fd1498Szrj size_t len); 61238fd1498Szrj 61338fd1498Szrj /* Removes all callgraph and varpool nodes that are marked by symtab 61438fd1498Szrj as deleted. */ 61538fd1498Szrj void filter_removed_items (void); 61638fd1498Szrj 61738fd1498Szrj /* Vector of semantic items. */ 61838fd1498Szrj vec <sem_item *> m_items; 61938fd1498Szrj 62038fd1498Szrj /* A set containing all items removed by hooks. */ 62138fd1498Szrj hash_set <symtab_node *> m_removed_items_set; 62238fd1498Szrj 62338fd1498Szrj /* Hashtable of congruence classes. */ 62438fd1498Szrj hash_table <congruence_class_hash> m_classes; 62538fd1498Szrj 62638fd1498Szrj /* Count of congruence classes. */ 62738fd1498Szrj unsigned int m_classes_count; 62838fd1498Szrj 62938fd1498Szrj /* Map data structure maps symtab nodes to semantic items. */ 63038fd1498Szrj hash_map <symtab_node *, sem_item *> m_symtab_node_map; 63138fd1498Szrj 63238fd1498Szrj /* Set to true if a splitter class is removed. */ 63338fd1498Szrj bool splitter_class_removed; 63438fd1498Szrj 63538fd1498Szrj /* Global unique class id counter. */ 63638fd1498Szrj static unsigned int class_id; 63738fd1498Szrj 63838fd1498Szrj /* Callgraph node removal hook holder. */ 63938fd1498Szrj cgraph_node_hook_list *m_cgraph_node_hooks; 64038fd1498Szrj 64138fd1498Szrj /* Varpool node removal hook holder. */ 64238fd1498Szrj varpool_node_hook_list *m_varpool_node_hooks; 64338fd1498Szrj 64438fd1498Szrj /* Bitmap stack. */ 64538fd1498Szrj bitmap_obstack m_bmstack; 64638fd1498Szrj 64738fd1498Szrj /* Vector of merged variables. Needed for fixup of points-to-analysis 64838fd1498Szrj info. */ 64938fd1498Szrj vec <symtab_pair> m_merged_variables; 65038fd1498Szrj }; // class sem_item_optimizer 65138fd1498Szrj 65238fd1498Szrj } // ipa_icf namespace 653