diff options
author | Ian Lance Taylor <iant@golang.org> | 2021-09-13 10:37:49 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2021-09-13 10:37:49 -0700 |
commit | e252b51ccde010cbd2a146485d8045103cd99533 (patch) | |
tree | e060f101cdc32bf5e520de8e5275db9d4236b74c /gcc/tree-ssa-threadupdate.h | |
parent | f10c7c4596dda99d2ee872c995ae4aeda65adbdf (diff) | |
parent | 104c05c5284b7822d770ee51a7d91946c7e56d50 (diff) | |
download | gcc-e252b51ccde010cbd2a146485d8045103cd99533.zip gcc-e252b51ccde010cbd2a146485d8045103cd99533.tar.gz gcc-e252b51ccde010cbd2a146485d8045103cd99533.tar.bz2 |
Merge from trunk revision 104c05c5284b7822d770ee51a7d91946c7e56d50.
Diffstat (limited to 'gcc/tree-ssa-threadupdate.h')
-rw-r--r-- | gcc/tree-ssa-threadupdate.h | 107 |
1 files changed, 96 insertions, 11 deletions
diff --git a/gcc/tree-ssa-threadupdate.h b/gcc/tree-ssa-threadupdate.h index 5f49b1a..94c9bc8 100644 --- a/gcc/tree-ssa-threadupdate.h +++ b/gcc/tree-ssa-threadupdate.h @@ -21,32 +21,114 @@ along with GCC; see the file COPYING3. If not see #ifndef _TREE_SSA_THREADUPDATE_H #define _TREE_SSA_THREADUPDATE_H 1 -/* In tree-ssa-threadupdate.c. */ -extern bool thread_through_all_blocks (bool); enum jump_thread_edge_type { EDGE_START_JUMP_THREAD, - EDGE_FSM_THREAD, EDGE_COPY_SRC_BLOCK, EDGE_COPY_SRC_JOINER_BLOCK, EDGE_NO_COPY_SRC_BLOCK }; +// We keep the registered jump threading opportunities in this +// vector as edge pairs (original_edge, target_edge). + class jump_thread_edge { public: - jump_thread_edge (edge e, enum jump_thread_edge_type type) - : e (e), type (type) {} + jump_thread_edge (edge e, jump_thread_edge_type t) : e (e), type (t) {} edge e; - enum jump_thread_edge_type type; + jump_thread_edge_type type; +}; + +class jump_thread_path_allocator +{ +public: + jump_thread_path_allocator (); + ~jump_thread_path_allocator (); + jump_thread_edge *allocate_thread_edge (edge, jump_thread_edge_type); + vec<jump_thread_edge *> *allocate_thread_path (); +private: + DISABLE_COPY_AND_ASSIGN (jump_thread_path_allocator); + obstack m_obstack; +}; + +// Abstract class for the jump thread registry. +// +// When all candidates have been registered with +// register_jump_thread(), thread_through_all_blocks() is called to +// update the CFG. + +class jt_path_registry +{ +public: + jt_path_registry (bool backedge_threads); + virtual ~jt_path_registry (); + bool register_jump_thread (vec<jump_thread_edge *> *); + bool thread_through_all_blocks (bool peel_loop_headers); + jump_thread_edge *allocate_thread_edge (edge e, jump_thread_edge_type t); + vec<jump_thread_edge *> *allocate_thread_path (); + void debug (); +protected: + void debug_path (FILE *, int pathno); + vec<vec<jump_thread_edge *> *> m_paths; + unsigned long m_num_threaded_edges; +private: + virtual bool update_cfg (bool peel_loop_headers) = 0; + jump_thread_path_allocator m_allocator; + // True if threading through back edges is allowed. This is only + // allowed in the generic copier in the backward threader. + bool m_backedge_threads; + DISABLE_COPY_AND_ASSIGN (jt_path_registry); +}; + +// Forward threader path registry using a custom BB copier. + +class fwd_jt_path_registry : public jt_path_registry +{ +public: + fwd_jt_path_registry (); + ~fwd_jt_path_registry (); + void remove_jump_threads_including (edge); +private: + bool update_cfg (bool peel_loop_headers) override; + void mark_threaded_blocks (bitmap threaded_blocks); + bool thread_block_1 (basic_block, bool noloop_only, bool joiners); + bool thread_block (basic_block, bool noloop_only); + bool thread_through_loop_header (class loop *loop, + bool may_peel_loop_headers); + class redirection_data *lookup_redirection_data (edge e, enum insert_option); + + hash_table<struct removed_edges> *m_removed_edges; + + // Main data structure to hold information for duplicates of BB. + hash_table<redirection_data> *m_redirection_data; +}; + +// Backward threader path registry using a generic BB copier. + +class back_jt_path_registry : public jt_path_registry +{ +public: + back_jt_path_registry (); +private: + bool update_cfg (bool peel_loop_headers) override; + void adjust_paths_after_duplication (unsigned curr_path_num); + bool duplicate_thread_path (edge entry, edge exit, basic_block *region, + unsigned n_region, unsigned current_path_no); + bool rewire_first_differing_edge (unsigned path_num, unsigned edge_num); +}; + +// Rather than search all the edges in jump thread paths each time DOM +// is able to simply if control statement, we build a hash table with +// the deleted edges. We only care about the address of the edge, not +// its contents. +struct removed_edges : nofree_ptr_hash<edge_def> +{ + static hashval_t hash (edge e) { return htab_hash_pointer (e); } + static bool equal (edge e1, edge e2) { return e1 == e2; } }; -extern void register_jump_thread (vec <class jump_thread_edge *> *); -extern void remove_jump_threads_including (edge); -extern void delete_jump_thread_path (vec <class jump_thread_edge *> *); -extern void remove_ctrl_stmt_and_useless_edges (basic_block, basic_block); -extern void free_dom_edge_info (edge); extern unsigned int estimate_threading_killed_stmts (basic_block); enum bb_dom_status @@ -61,4 +143,7 @@ enum bb_dom_status enum bb_dom_status determine_bb_domination_status (class loop *, basic_block); +// In tree-ssa-dom.c. +extern void free_dom_edge_info (edge); + #endif |