diff options
Diffstat (limited to 'gcc/ipa-icf.h')
-rw-r--r-- | gcc/ipa-icf.h | 553 |
1 files changed, 553 insertions, 0 deletions
diff --git a/gcc/ipa-icf.h b/gcc/ipa-icf.h new file mode 100644 index 00000000000..d8e7b163a16 --- /dev/null +++ b/gcc/ipa-icf.h @@ -0,0 +1,553 @@ +/* Interprocedural semantic function equality pass + Copyright (C) 2014 Free Software Foundation, Inc. + + Contributed by Jan Hubicka <hubicka@ucw.cz> and Martin Liska <mliska@suse.cz> + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +namespace ipa_icf { +class sem_item; + +/* Congruence class encompasses a collection of either functions or + read-only variables. These items are considered to be equivalent + if not proved the oposite. */ +class congruence_class +{ +public: + /* Congruence class constructor for a new class with _ID. */ + congruence_class (unsigned int _id): in_worklist (false), id(_id) + { + } + + /* Destructor. */ + ~congruence_class () + { + } + + /* Dump function prints all class members to a FILE with an INDENT. */ + void dump (FILE *file, unsigned int indent = 0) const; + + /* Returns true if there's a member that is used from another group. */ + bool is_class_used (void); + + /* Flag is used in case we want to remove a class from worklist and + delete operation is quite expensive for + the data structure (linked list). */ + bool in_worklist; + + /* Vector of all group members. */ + auto_vec <sem_item *> members; + + /* Global unique class identifier. */ + unsigned int id; +}; + +/* Semantic item type enum. */ +enum sem_item_type +{ + FUNC, + VAR +}; + +/* Semantic item usage pair. */ +class sem_usage_pair +{ +public: + /* Constructor for key value pair, where _ITEM is key and _INDEX is a target. */ + sem_usage_pair (sem_item *_item, unsigned int _index); + + /* Target semantic item where an item is used. */ + sem_item *item; + + /* Index of usage of such an item. */ + unsigned int index; +}; + +/* Semantic item is a base class that encapsulates all shared functionality + for both semantic function and variable items. */ +class sem_item +{ +public: + /* Semantic item constructor for a node of _TYPE, where STACK is used + for bitmap memory allocation. */ + sem_item (sem_item_type _type, bitmap_obstack *stack); + + /* Semantic item constructor for a node of _TYPE, where STACK is used + for bitmap memory allocation. The item is based on symtab node _NODE + with computed _HASH. */ + sem_item (sem_item_type _type, symtab_node *_node, hashval_t _hash, + bitmap_obstack *stack); + + virtual ~sem_item (); + + /* Dump function for debugging purpose. */ + DEBUG_FUNCTION void dump (void); + + /* Initialize semantic item by info reachable during LTO WPA phase. */ + virtual void init_wpa (void) = 0; + + /* Semantic item initialization function. */ + virtual void init (void) = 0; + + /* 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; + + /* Returns true if the item equals to ITEM given as arguemnt. */ + virtual bool equals (sem_item *item, + hash_map <symtab_node *, sem_item *> &ignored_nodes) = 0; + + /* References independent hash function. */ + virtual hashval_t get_hash (void) = 0; + + /* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can + be applied. */ + virtual bool merge (sem_item *alias_item) = 0; + + /* Dump symbol to FILE. */ + virtual void dump_to_file (FILE *file) = 0; + + /* 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); + + /* Item type. */ + sem_item_type type; + + /* Symtab node. */ + symtab_node *node; + + /* Declaration tree node. */ + tree decl; + + /* Semantic references used that generate congruence groups. */ + vec <sem_item *> refs; + + /* Pointer to a congruence class the item belongs to. */ + congruence_class *cls; + + /* Index of the item in a class belonging to. */ + unsigned int index_in_class; + + /* List of semantic items where the instance is used. */ + vec <sem_usage_pair *> usages; + + /* A bitmap with indices of all classes referencing this item. */ + bitmap usage_index_bitmap; + + /* List of tree references (either FUNC_DECL or VAR_DECL). */ + vec <tree> tree_refs; + + /* A set with symbol table references. */ + hash_set <symtab_node *> refs_set; + +protected: + /* Cached, once calculated hash for the item. */ + hashval_t hash; + +private: + /* Initialize internal data structures. Bitmap STACK is used for + bitmap memory allocation process. */ + void setup (bitmap_obstack *stack); +}; // class sem_item + +class sem_function: public sem_item +{ +public: + /* Semantic function constructor that uses STACK as bitmap memory stack. */ + sem_function (bitmap_obstack *stack); + + /* Constructor based on callgraph node _NODE with computed hash _HASH. + Bitmap STACK is used for memory allocation. */ + sem_function (cgraph_node *_node, hashval_t _hash, bitmap_obstack *stack); + + ~sem_function (); + + inline virtual void init_wpa (void) + { + parse_tree_args (); + } + + virtual void init (void); + virtual bool equals_wpa (sem_item *item, + hash_map <symtab_node *, sem_item *> &ignored_nodes); + virtual hashval_t get_hash (void); + virtual bool equals (sem_item *item, + hash_map <symtab_node *, sem_item *> &ignored_nodes); + virtual bool merge (sem_item *alias_item); + + /* Dump symbol to FILE. */ + virtual void dump_to_file (FILE *file) + { + gcc_assert (file); + 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) + { + return dyn_cast <cgraph_node *> (node); + } + + /* Improve accumulated hash for HSTATE based on a gimple statement STMT. */ + void hash_stmt (inchash::hash *inchash, gimple stmt); + + /* Return true if polymorphic comparison must be processed. */ + bool compare_polymorphic_p (void); + + /* For a given call graph NODE, the function constructs new + semantic function item. */ + static sem_function *parse (cgraph_node *node, bitmap_obstack *stack); + + /* 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; + + /* Total amount of edges in the function. */ + unsigned int edge_count; + + /* Vector of sizes of all basic blocks. */ + vec <unsigned int> bb_sizes; + + /* Control flow graph checksum. */ + hashval_t cfg_checksum; + + /* GIMPLE codes hash value. */ + hashval_t gcode_hash; + + /* Total number of SSA names used in the function. */ + unsigned ssa_names_size; + + /* Array of structures for all basic blocks. */ + vec <ipa_icf_gimple::sem_bb *> bb_sorted; + +private: + /* Calculates hash value based on a BASIC_BLOCK. */ + hashval_t get_bb_hash (const ipa_icf_gimple::sem_bb *basic_block); + + /* For given basic blocks BB1 and BB2 (from functions FUNC1 and FUNC), + true value is returned if phi nodes are semantically + equivalent in these blocks . */ + bool compare_phi_node (basic_block bb1, basic_block bb2); + + /* Basic blocks dictionary BB_DICT returns true if SOURCE index BB + corresponds to TARGET. */ + bool bb_dict_test (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); + + /* 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. */ + bool compare_cgraph_references (hash_map <symtab_node *, sem_item *> + &ignored_nodes, + symtab_node *n1, symtab_node *n2); + + /* Processes function equality comparison. */ + bool equals_private (sem_item *item, + hash_map <symtab_node *, sem_item *> &ignored_nodes); + + /* Returns true if tree T can be compared as a handled component. */ + static bool icf_handled_component_p (tree t); + + /* Function checker stores binding between functions. */ + ipa_icf_gimple::func_checker *m_checker; + + /* COMPARED_FUNC is a function that we compare to. */ + sem_function *m_compared_func; +}; // class sem_function + +class sem_variable: public sem_item +{ +public: + /* Semantic variable constructor that uses STACK as bitmap memory stack. */ + sem_variable (bitmap_obstack *stack); + + /* Constructor based on callgraph node _NODE with computed hash _HASH. + Bitmap STACK is used for memory allocation. */ + + sem_variable (varpool_node *_node, hashval_t _hash, bitmap_obstack *stack); + + inline virtual void init_wpa (void) {} + + /* Semantic variable initialization function. */ + inline virtual void init (void) + { + decl = get_node ()->decl; + ctor = ctor_for_folding (decl); + } + + virtual hashval_t get_hash (void); + virtual bool merge (sem_item *alias_item); + virtual void dump_to_file (FILE *file); + virtual bool equals (sem_item *item, + hash_map <symtab_node *, sem_item *> &ignored_nodes); + + /* Fast equality variable based on knowledge known in WPA. */ + inline virtual bool equals_wpa (sem_item *item, + hash_map <symtab_node *, sem_item *> & ARG_UNUSED(ignored_nodes)) + { + gcc_assert (item->type == VAR); + return true; + } + + /* Returns varpool_node. */ + inline varpool_node *get_node (void) + { + return dyn_cast <varpool_node *> (node); + } + + /* Parser function that visits a varpool NODE. */ + static sem_variable *parse (varpool_node *node, bitmap_obstack *stack); + + /* Variable constructor. */ + tree ctor; + +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; + +struct congruence_class_group +{ + hashval_t hash; + sem_item_type type; + vec <congruence_class *> classes; +}; + +/* Congruence class set structure. */ +struct congruence_class_group_hash: typed_noop_remove <congruence_class_group> +{ + typedef congruence_class_group value_type; + typedef congruence_class_group compare_type; + + static inline hashval_t hash (const value_type *item) + { + return item->hash; + } + + static inline int equal (const value_type *item1, const compare_type *item2) + { + return item1->hash == item2->hash && item1->type == item2->type; + } +}; + +struct traverse_split_pair +{ + sem_item_optimizer *optimizer; + class congruence_class *cls; +}; + +/* Semantic item optimizer includes all top-level logic + related to semantic equality comparison. */ +class sem_item_optimizer +{ +public: + sem_item_optimizer (); + ~sem_item_optimizer (); + + /* Function responsible for visiting all potential functions and + read-only variables that can be merged. */ + void parse_funcs_and_vars (void); + + /* Optimizer entry point. */ + void execute (void); + + /* Dump function. */ + void dump (void); + + /* Verify congruence classes if checking is enabled. */ + void verify_classes (void); + + /* Write IPA ICF summary for symbols. */ + void write_summary (void); + + /* Read IPA IPA ICF summary for symbols. */ + void read_summary (void); + + /* Callgraph removal hook called for a NODE with a custom DATA. */ + static void cgraph_removal_hook (cgraph_node *node, void *data); + + /* Varpool removal hook called for a NODE with a custom DATA. */ + static void varpool_removal_hook (varpool_node *node, void *data); + + /* Worklist of congruence classes that can potentially + refine classes of congruence. */ + std::list<congruence_class *> worklist; + + /* Remove semantic ITEM and release memory. */ + void remove_item (sem_item *item); + + /* Remove symtab NODE triggered by symtab removal hooks. */ + void remove_symtab_node (symtab_node *node); + + /* Register callgraph and varpool hooks. */ + void register_hooks (void); + + /* Unregister callgraph and varpool hooks. */ + void unregister_hooks (void); + + /* Adds a CLS to hashtable associated by hash value. */ + void add_class (congruence_class *cls); + + /* Gets a congruence class group based on given HASH value and TYPE. */ + congruence_class_group *get_group_by_hash (hashval_t hash, + sem_item_type type); + +private: + + /* Congruence classes are built by hash value. */ + void build_hash_based_classes (void); + + /* Semantic items in classes having more than one element and initialized. + In case of WPA, we load function body. */ + void parse_nonsingleton_classes (void); + + /* Equality function for semantic items is used to subdivide existing + classes. If IN_WPA, fast equality function is invoked. */ + void subdivide_classes_by_equality (bool in_wpa = false); + + /* Debug function prints all informations about congruence classes. */ + void dump_cong_classes (void); + + /* Build references according to call graph. */ + void build_graph (void); + + /* Iterative congruence reduction function. */ + void process_cong_reduction (void); + + /* After reduction is done, we can declare all items in a group + to be equal. PREV_CLASS_COUNT is start number of classes + before reduction. */ + void merge_classes (unsigned int prev_class_count); + + /* Adds a newly created congruence class CLS to worklist. */ + void worklist_push (congruence_class *cls); + + /* Pops a class from worklist. */ + congruence_class *worklist_pop (); + + /* Every usage of a congruence class CLS is a candidate that can split the + collection of classes. Bitmap stack BMSTACK is used for bitmap + allocation. */ + void do_congruence_step (congruence_class *cls); + + /* Tests if a class CLS used as INDEXth splits any congruence classes. + Bitmap stack BMSTACK is used for bitmap allocation. */ + void do_congruence_step_for_index (congruence_class *cls, unsigned int index); + + /* Makes pairing between a congruence class CLS and semantic ITEM. */ + static void add_item_to_class (congruence_class *cls, sem_item *item); + + /* Disposes split map traverse function. CLS is congruence + class, BSLOT is bitmap slot we want to release. DATA is mandatory, + but unused argument. */ + static bool release_split_map (congruence_class * const &cls, bitmap const &b, + traverse_split_pair *pair); + + /* Process split operation for a cognruence class CLS, + where bitmap B splits congruence class members. DATA is used + as argument of split pair. */ + static bool traverse_congruence_split (congruence_class * const &cls, + bitmap const &b, + traverse_split_pair *pair); + + /* Reads a section from LTO stream file FILE_DATA. Input block for DATA + contains LEN bytes. */ + void read_section (lto_file_decl_data *file_data, const char *data, + size_t len); + + /* Removes all callgraph and varpool nodes that are marked by symtab + as deleted. */ + void filter_removed_items (void); + + /* Vector of semantic items. */ + vec <sem_item *> m_items; + + /* A set containing all items removed by hooks. */ + hash_set <symtab_node *> m_removed_items_set; + + /* Hashtable of congruence classes */ + hash_table <congruence_class_group_hash> m_classes; + + /* Count of congruence classes. */ + unsigned int m_classes_count; + + /* Map data structure maps symtab nodes to semantic items. */ + hash_map <symtab_node *, sem_item *> m_symtab_node_map; + + /* Set to true if a splitter class is removed. */ + bool splitter_class_removed; + + /* Global unique class id counter. */ + static unsigned int class_id; + + /* Callgraph node removal hook holder. */ + cgraph_node_hook_list *m_cgraph_node_hooks; + + /* Varpool node removal hook holder. */ + varpool_node_hook_list *m_varpool_node_hooks; + + /* Bitmap stack. */ + bitmap_obstack m_bmstack; +}; // class sem_item_optimizer + +} // ipa_icf namespace |