Branch data Line data Source code
1 : : /* Header file for SSA jump threading.
2 : : Copyright (C) 2013-2025 Free Software Foundation, Inc.
3 : :
4 : : This file is part of GCC.
5 : :
6 : : GCC is free software; you can redistribute it and/or modify it under
7 : : the terms of the GNU General Public License as published by the Free
8 : : Software Foundation; either version 3, or (at your option) any later
9 : : version.
10 : :
11 : : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 : : WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : : for more details.
15 : :
16 : : You should have received a copy of the GNU General Public License
17 : : along with GCC; see the file COPYING3. If not see
18 : : <http://www.gnu.org/licenses/>. */
19 : :
20 : : #ifndef GCC_TREE_SSA_THREADEDGE_H
21 : : #define GCC_TREE_SSA_THREADEDGE_H
22 : :
23 : : // Class used to maintain path state in the jump threader and pass it
24 : : // to the jump threader simplifier.
25 : :
26 : 2001910 : class jt_state
27 : : {
28 : : public:
29 : 0 : virtual ~jt_state () { }
30 : : virtual void push (edge);
31 : : virtual void pop ();
32 : : virtual void register_equiv (tree dest, tree src, bool update_range);
33 : : virtual void register_equivs_edge (edge e);
34 : : virtual void register_equivs_stmt (gimple *, basic_block,
35 : : class jt_simplifier *);
36 : : virtual void record_ranges_from_stmt (gimple *stmt, bool temporary);
37 : : void get_path (vec<basic_block> &);
38 : : void append_path (basic_block);
39 : : void dump (FILE *);
40 : : void debug ();
41 : :
42 : : private:
43 : : auto_vec<basic_block> m_blocks;
44 : : static const basic_block BB_MARKER;
45 : : };
46 : :
47 : : // Statement simplifier callback for the jump threader.
48 : :
49 : 2001910 : class jt_simplifier
50 : : {
51 : : public:
52 : 2001910 : virtual ~jt_simplifier () { }
53 : : virtual tree simplify (gimple *, gimple *, basic_block, jt_state *) = 0;
54 : : };
55 : :
56 : : class hybrid_jt_state : public jt_state
57 : : {
58 : : private:
59 : 0 : void register_equivs_stmt (gimple *, basic_block, jt_simplifier *) override
60 : : {
61 : : // Ranger has no need to simplify anything.
62 : 0 : }
63 : : };
64 : :
65 : 2001910 : class hybrid_jt_simplifier : public jt_simplifier
66 : : {
67 : : public:
68 : : hybrid_jt_simplifier (class gimple_ranger *r, class path_range_query *q);
69 : : tree simplify (gimple *stmt, gimple *, basic_block, jt_state *) override;
70 : :
71 : : private:
72 : : void compute_exit_dependencies (bitmap dependencies,
73 : : const vec<basic_block> &path,
74 : : gimple *stmt);
75 : :
76 : : gimple_ranger *m_ranger;
77 : : path_range_query *m_query;
78 : : };
79 : :
80 : : // This is the high level threader. The entry point is
81 : : // thread_outgoing_edges(), which calculates and registers paths to be
82 : : // threaded. When all candidates have been registered,
83 : : // thread_through_all_blocks() is called to actually change the CFG.
84 : :
85 : : class jump_threader
86 : : {
87 : : public:
88 : : jump_threader (jt_simplifier *, class jt_state *);
89 : : ~jump_threader ();
90 : : void thread_outgoing_edges (basic_block);
91 : : void remove_jump_threads_including (edge_def *);
92 : : bool thread_through_all_blocks (bool may_peel_loop_headers);
93 : :
94 : : private:
95 : : tree simplify_control_stmt_condition (edge, gimple *);
96 : : tree simplify_control_stmt_condition_1 (edge,
97 : : gimple *,
98 : : tree op0,
99 : : tree_code cond_code,
100 : : tree op1,
101 : : unsigned limit);
102 : :
103 : : bool thread_around_empty_blocks (vec<class jump_thread_edge *> *path,
104 : : edge, bitmap visited, unsigned &limit);
105 : : int thread_through_normal_block (vec<jump_thread_edge *> *path,
106 : : edge, bitmap visited, unsigned &limit);
107 : : void thread_across_edge (edge);
108 : : bool record_temporary_equivalences_from_phis (edge);
109 : : gimple *record_temporary_equivalences_from_stmts_at_dest (edge);
110 : :
111 : : // Dummy condition to avoid creating lots of throw away statements.
112 : : gcond *dummy_cond;
113 : :
114 : : class fwd_jt_path_registry *m_registry;
115 : : jt_simplifier *m_simplifier;
116 : : jt_state *m_state;
117 : : };
118 : :
119 : : extern void propagate_threaded_block_debug_into (basic_block, basic_block);
120 : : extern bool single_succ_to_potentially_threadable_block (basic_block);
121 : :
122 : : // ?? All this ssa_name_values stuff is the store of values for
123 : : // avail_exprs_stack and const_and_copies, so it really belongs in the
124 : : // jump_threader class. However, it's probably not worth touching
125 : : // this, since all this windable state is slated to go with the
126 : : // ranger.
127 : : extern vec<tree> ssa_name_values;
128 : : #define SSA_NAME_VALUE(x) \
129 : : (SSA_NAME_VERSION (x) < ssa_name_values.length () \
130 : : ? ssa_name_values[SSA_NAME_VERSION (x)] \
131 : : : NULL_TREE)
132 : : extern void set_ssa_name_value (tree, tree);
133 : :
134 : : #endif /* GCC_TREE_SSA_THREADEDGE_H */
|