Line data Source code
1 : /* Header file for SSA jump threading.
2 : Copyright (C) 2013-2026 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 2083233 : 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 2083233 : class jt_simplifier
50 : {
51 : public:
52 2083233 : 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 2083233 : 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 */
|