aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-threadupdate.h
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2021-09-13 10:37:49 -0700
committerIan Lance Taylor <iant@golang.org>2021-09-13 10:37:49 -0700
commite252b51ccde010cbd2a146485d8045103cd99533 (patch)
treee060f101cdc32bf5e520de8e5275db9d4236b74c /gcc/tree-ssa-threadupdate.h
parentf10c7c4596dda99d2ee872c995ae4aeda65adbdf (diff)
parent104c05c5284b7822d770ee51a7d91946c7e56d50 (diff)
downloadgcc-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.h107
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