annotate gcc/tree-ssa-propagate.c @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 /* Generic SSA value propagation engine.
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2 Copyright (C) 2004-2020 Free Software Foundation, Inc.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 Contributed by Diego Novillo <dnovillo@redhat.com>
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
4
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 This file is part of GCC.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
6
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 GCC is free software; you can redistribute it and/or modify it
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 under the terms of the GNU General Public License as published by the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 Free Software Foundation; either version 3, or (at your option) any
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 later version.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
11
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 GCC is distributed in the hope that it will be useful, but WITHOUT
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 for more details.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
16
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 You should have received a copy of the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 along with GCC; see the file COPYING3. If not see
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
19 <http://www.gnu.org/licenses/>. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
20
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 #include "config.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 #include "system.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 #include "coretypes.h"
111
kono
parents: 67
diff changeset
24 #include "backend.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 #include "tree.h"
111
kono
parents: 67
diff changeset
26 #include "gimple.h"
kono
parents: 67
diff changeset
27 #include "ssa.h"
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
28 #include "gimple-pretty-print.h"
111
kono
parents: 67
diff changeset
29 #include "dumpfile.h"
kono
parents: 67
diff changeset
30 #include "gimple-fold.h"
kono
parents: 67
diff changeset
31 #include "tree-eh.h"
kono
parents: 67
diff changeset
32 #include "gimplify.h"
kono
parents: 67
diff changeset
33 #include "gimple-iterator.h"
kono
parents: 67
diff changeset
34 #include "tree-cfg.h"
kono
parents: 67
diff changeset
35 #include "tree-ssa.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 #include "tree-ssa-propagate.h"
111
kono
parents: 67
diff changeset
37 #include "domwalk.h"
kono
parents: 67
diff changeset
38 #include "cfgloop.h"
kono
parents: 67
diff changeset
39 #include "tree-cfgcleanup.h"
kono
parents: 67
diff changeset
40 #include "cfganal.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
41
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
42 /* This file implements a generic value propagation engine based on
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
43 the same propagation used by the SSA-CCP algorithm [1].
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
44
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
45 Propagation is performed by simulating the execution of every
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
46 statement that produces the value being propagated. Simulation
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
47 proceeds as follows:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
48
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
49 1- Initially, all edges of the CFG are marked not executable and
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 the CFG worklist is seeded with all the statements in the entry
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
51 basic block (block 0).
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
52
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
53 2- Every statement S is simulated with a call to the call-back
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
54 function SSA_PROP_VISIT_STMT. This evaluation may produce 3
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
55 results:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
56
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
57 SSA_PROP_NOT_INTERESTING: Statement S produces nothing of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
58 interest and does not affect any of the work lists.
111
kono
parents: 67
diff changeset
59 The statement may be simulated again if any of its input
kono
parents: 67
diff changeset
60 operands change in future iterations of the simulator.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
61
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
62 SSA_PROP_VARYING: The value produced by S cannot be determined
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
63 at compile time. Further simulation of S is not required.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
64 If S is a conditional jump, all the outgoing edges for the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
65 block are considered executable and added to the work
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
66 list.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
67
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
68 SSA_PROP_INTERESTING: S produces a value that can be computed
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
69 at compile time. Its result can be propagated into the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
70 statements that feed from S. Furthermore, if S is a
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
71 conditional jump, only the edge known to be taken is added
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
72 to the work list. Edges that are known not to execute are
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
73 never simulated.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
74
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
75 3- PHI nodes are simulated with a call to SSA_PROP_VISIT_PHI. The
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
76 return value from SSA_PROP_VISIT_PHI has the same semantics as
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
77 described in #2.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
78
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
79 4- Three work lists are kept. Statements are only added to these
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
80 lists if they produce one of SSA_PROP_INTERESTING or
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
81 SSA_PROP_VARYING.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
82
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
83 CFG_BLOCKS contains the list of blocks to be simulated.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
84 Blocks are added to this list if their incoming edges are
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
85 found executable.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
86
111
kono
parents: 67
diff changeset
87 SSA_EDGE_WORKLIST contains the list of statements that we
kono
parents: 67
diff changeset
88 need to revisit.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
89
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
90 5- Simulation terminates when all three work lists are drained.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
91
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
92 Before calling ssa_propagate, it is important to clear
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
93 prop_simulate_again_p for all the statements in the program that
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
94 should be simulated. This initialization allows an implementation
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
95 to specify which statements should never be simulated.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
96
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
97 It is also important to compute def-use information before calling
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
98 ssa_propagate.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
99
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
100 References:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
101
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
102 [1] Constant propagation with conditional branches,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
103 Wegman and Zadeck, ACM TOPLAS 13(2):181-210.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
104
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
105 [2] Building an Optimizing Compiler,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
106 Robert Morgan, Butterworth-Heinemann, 1998, Section 8.9.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
107
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
108 [3] Advanced Compiler Design and Implementation,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
109 Steven Muchnick, Morgan Kaufmann, 1997, Section 12.6 */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
110
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
111 /* Worklists of control flow edge destinations. This contains
111
kono
parents: 67
diff changeset
112 the CFG order number of the blocks so we can iterate in CFG
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
113 order by visiting in bit-order. We use two worklists to
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
114 first make forward progress before iterating. */
111
kono
parents: 67
diff changeset
115 static bitmap cfg_blocks;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
116 static bitmap cfg_blocks_back;
111
kono
parents: 67
diff changeset
117 static int *bb_to_cfg_order;
kono
parents: 67
diff changeset
118 static int *cfg_order_to_bb;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
119
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
120 /* Worklists of SSA edges which will need reexamination as their
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
121 definition has changed. SSA edges are def-use edges in the SSA
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
122 web. For each D-U edge, we store the target statement or PHI node
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
123 UID in a bitmap. UIDs order stmts in execution order. We use
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
124 two worklists to first make forward progress before iterating. */
111
kono
parents: 67
diff changeset
125 static bitmap ssa_edge_worklist;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
126 static bitmap ssa_edge_worklist_back;
111
kono
parents: 67
diff changeset
127 static vec<gimple *> uid_to_stmt;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
128
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
129 /* Current RPO index in the iteration. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
130 static int curr_order;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
131
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
132
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
133 /* We have just defined a new value for VAR. If IS_VARYING is true,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
134 add all immediate uses of VAR to VARYING_SSA_EDGES, otherwise add
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
135 them to INTERESTING_SSA_EDGES. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
136
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
137 static void
111
kono
parents: 67
diff changeset
138 add_ssa_edge (tree var)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
139 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
140 imm_use_iterator iter;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
141 use_operand_p use_p;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
142
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
143 FOR_EACH_IMM_USE_FAST (use_p, iter, var)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
144 {
111
kono
parents: 67
diff changeset
145 gimple *use_stmt = USE_STMT (use_p);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
146 if (!prop_simulate_again_p (use_stmt))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
147 continue;
111
kono
parents: 67
diff changeset
148
kono
parents: 67
diff changeset
149 /* If we did not yet simulate the block wait for this to happen
kono
parents: 67
diff changeset
150 and do not add the stmt to the SSA edge worklist. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
151 basic_block use_bb = gimple_bb (use_stmt);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
152 if (! (use_bb->flags & BB_VISITED))
111
kono
parents: 67
diff changeset
153 continue;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
154
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
155 /* If this is a use on a not yet executable edge do not bother to
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
156 queue it. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
157 if (gimple_code (use_stmt) == GIMPLE_PHI
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
158 && !(EDGE_PRED (use_bb, PHI_ARG_INDEX_FROM_USE (use_p))->flags
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
159 & EDGE_EXECUTABLE))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
160 continue;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
161
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
162 bitmap worklist;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
163 if (bb_to_cfg_order[gimple_bb (use_stmt)->index] < curr_order)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
164 worklist = ssa_edge_worklist_back;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
165 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
166 worklist = ssa_edge_worklist;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
167 if (bitmap_set_bit (worklist, gimple_uid (use_stmt)))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
168 {
111
kono
parents: 67
diff changeset
169 uid_to_stmt[gimple_uid (use_stmt)] = use_stmt;
kono
parents: 67
diff changeset
170 if (dump_file && (dump_flags & TDF_DETAILS))
kono
parents: 67
diff changeset
171 {
kono
parents: 67
diff changeset
172 fprintf (dump_file, "ssa_edge_worklist: adding SSA use in ");
kono
parents: 67
diff changeset
173 print_gimple_stmt (dump_file, use_stmt, 0, TDF_SLIM);
kono
parents: 67
diff changeset
174 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
175 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
176 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
177 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
178
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
179
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
180 /* Add edge E to the control flow worklist. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
181
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
182 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
183 add_control_edge (edge e)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
184 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
185 basic_block bb = e->dest;
111
kono
parents: 67
diff changeset
186 if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
187 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
188
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
189 /* If the edge had already been executed, skip it. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
190 if (e->flags & EDGE_EXECUTABLE)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
191 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
192
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
193 e->flags |= EDGE_EXECUTABLE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
194
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
195 int bb_order = bb_to_cfg_order[bb->index];
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
196 if (bb_order < curr_order)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
197 bitmap_set_bit (cfg_blocks_back, bb_order);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
198 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
199 bitmap_set_bit (cfg_blocks, bb_order);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
200
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
201 if (dump_file && (dump_flags & TDF_DETAILS))
111
kono
parents: 67
diff changeset
202 fprintf (dump_file, "Adding destination of edge (%d -> %d) to worklist\n",
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
203 e->src->index, e->dest->index);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
204 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
205
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
206
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
207 /* Simulate the execution of STMT and update the work lists accordingly. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
208
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
209 void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
210 ssa_propagation_engine::simulate_stmt (gimple *stmt)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
211 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
212 enum ssa_prop_result val = SSA_PROP_NOT_INTERESTING;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
213 edge taken_edge = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
214 tree output_name = NULL_TREE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
215
111
kono
parents: 67
diff changeset
216 /* Pull the stmt off the SSA edge worklist. */
kono
parents: 67
diff changeset
217 bitmap_clear_bit (ssa_edge_worklist, gimple_uid (stmt));
kono
parents: 67
diff changeset
218
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
219 /* Don't bother visiting statements that are already
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
220 considered varying by the propagator. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
221 if (!prop_simulate_again_p (stmt))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
222 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
223
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
224 if (gimple_code (stmt) == GIMPLE_PHI)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
225 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
226 val = visit_phi (as_a <gphi *> (stmt));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
227 output_name = gimple_phi_result (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
228 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
229 else
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
230 val = visit_stmt (stmt, &taken_edge, &output_name);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
231
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
232 if (val == SSA_PROP_VARYING)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
233 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
234 prop_set_simulate_again (stmt, false);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
235
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
236 /* If the statement produced a new varying value, add the SSA
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
237 edges coming out of OUTPUT_NAME. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
238 if (output_name)
111
kono
parents: 67
diff changeset
239 add_ssa_edge (output_name);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
240
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
241 /* If STMT transfers control out of its basic block, add
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
242 all outgoing edges to the work list. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
243 if (stmt_ends_bb_p (stmt))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
244 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
245 edge e;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
246 edge_iterator ei;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
247 basic_block bb = gimple_bb (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
248 FOR_EACH_EDGE (e, ei, bb->succs)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
249 add_control_edge (e);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
250 }
111
kono
parents: 67
diff changeset
251 return;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
252 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
253 else if (val == SSA_PROP_INTERESTING)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
254 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
255 /* If the statement produced new value, add the SSA edges coming
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
256 out of OUTPUT_NAME. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
257 if (output_name)
111
kono
parents: 67
diff changeset
258 add_ssa_edge (output_name);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
259
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
260 /* If we know which edge is going to be taken out of this block,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
261 add it to the CFG work list. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
262 if (taken_edge)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
263 add_control_edge (taken_edge);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
264 }
111
kono
parents: 67
diff changeset
265
kono
parents: 67
diff changeset
266 /* If there are no SSA uses on the stmt whose defs are simulated
kono
parents: 67
diff changeset
267 again then this stmt will be never visited again. */
kono
parents: 67
diff changeset
268 bool has_simulate_again_uses = false;
kono
parents: 67
diff changeset
269 use_operand_p use_p;
kono
parents: 67
diff changeset
270 ssa_op_iter iter;
kono
parents: 67
diff changeset
271 if (gimple_code (stmt) == GIMPLE_PHI)
kono
parents: 67
diff changeset
272 {
kono
parents: 67
diff changeset
273 edge_iterator ei;
kono
parents: 67
diff changeset
274 edge e;
kono
parents: 67
diff changeset
275 tree arg;
kono
parents: 67
diff changeset
276 FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->preds)
kono
parents: 67
diff changeset
277 if (!(e->flags & EDGE_EXECUTABLE)
kono
parents: 67
diff changeset
278 || ((arg = PHI_ARG_DEF_FROM_EDGE (stmt, e))
kono
parents: 67
diff changeset
279 && TREE_CODE (arg) == SSA_NAME
kono
parents: 67
diff changeset
280 && !SSA_NAME_IS_DEFAULT_DEF (arg)
kono
parents: 67
diff changeset
281 && prop_simulate_again_p (SSA_NAME_DEF_STMT (arg))))
kono
parents: 67
diff changeset
282 {
kono
parents: 67
diff changeset
283 has_simulate_again_uses = true;
kono
parents: 67
diff changeset
284 break;
kono
parents: 67
diff changeset
285 }
kono
parents: 67
diff changeset
286 }
kono
parents: 67
diff changeset
287 else
kono
parents: 67
diff changeset
288 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
kono
parents: 67
diff changeset
289 {
kono
parents: 67
diff changeset
290 gimple *def_stmt = SSA_NAME_DEF_STMT (USE_FROM_PTR (use_p));
kono
parents: 67
diff changeset
291 if (!gimple_nop_p (def_stmt)
kono
parents: 67
diff changeset
292 && prop_simulate_again_p (def_stmt))
kono
parents: 67
diff changeset
293 {
kono
parents: 67
diff changeset
294 has_simulate_again_uses = true;
kono
parents: 67
diff changeset
295 break;
kono
parents: 67
diff changeset
296 }
kono
parents: 67
diff changeset
297 }
kono
parents: 67
diff changeset
298 if (!has_simulate_again_uses)
kono
parents: 67
diff changeset
299 {
kono
parents: 67
diff changeset
300 if (dump_file && (dump_flags & TDF_DETAILS))
kono
parents: 67
diff changeset
301 fprintf (dump_file, "marking stmt to be not simulated again\n");
kono
parents: 67
diff changeset
302 prop_set_simulate_again (stmt, false);
kono
parents: 67
diff changeset
303 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
304 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
305
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
306
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
307 /* Simulate the execution of BLOCK. Evaluate the statement associated
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
308 with each variable reference inside the block. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
309
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
310 void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
311 ssa_propagation_engine::simulate_block (basic_block block)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
312 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
313 gimple_stmt_iterator gsi;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
314
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
315 /* There is nothing to do for the exit block. */
111
kono
parents: 67
diff changeset
316 if (block == EXIT_BLOCK_PTR_FOR_FN (cfun))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
317 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
318
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
319 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
320 fprintf (dump_file, "\nSimulating block %d\n", block->index);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
321
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
322 /* Always simulate PHI nodes, even if we have simulated this block
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
323 before. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
324 for (gsi = gsi_start_phis (block); !gsi_end_p (gsi); gsi_next (&gsi))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
325 simulate_stmt (gsi_stmt (gsi));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
326
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
327 /* If this is the first time we've simulated this block, then we
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
328 must simulate each of its statements. */
111
kono
parents: 67
diff changeset
329 if (! (block->flags & BB_VISITED))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
330 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
331 gimple_stmt_iterator j;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
332 unsigned int normal_edge_count;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
333 edge e, normal_edge;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
334 edge_iterator ei;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
335
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
336 for (j = gsi_start_bb (block); !gsi_end_p (j); gsi_next (&j))
111
kono
parents: 67
diff changeset
337 simulate_stmt (gsi_stmt (j));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
338
111
kono
parents: 67
diff changeset
339 /* Note that we have simulated this block. */
kono
parents: 67
diff changeset
340 block->flags |= BB_VISITED;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
341
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
342 /* We cannot predict when abnormal and EH edges will be executed, so
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
343 once a block is considered executable, we consider any
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
344 outgoing abnormal edges as executable.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
345
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
346 TODO: This is not exactly true. Simplifying statement might
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
347 prove it non-throwing and also computed goto can be handled
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
348 when destination is known.
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
349
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
350 At the same time, if this block has only one successor that is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
351 reached by non-abnormal edges, then add that successor to the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
352 worklist. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
353 normal_edge_count = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
354 normal_edge = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
355 FOR_EACH_EDGE (e, ei, block->succs)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
356 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
357 if (e->flags & (EDGE_ABNORMAL | EDGE_EH))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
358 add_control_edge (e);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
359 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
360 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
361 normal_edge_count++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
362 normal_edge = e;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
363 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
364 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
365
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
366 if (normal_edge_count == 1)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
367 add_control_edge (normal_edge);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
368 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
369 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
370
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
371
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
372 /* Initialize local data structures and work lists. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
373
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
374 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
375 ssa_prop_init (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
376 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
377 edge e;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
378 edge_iterator ei;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
379 basic_block bb;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
380
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
381 /* Worklists of SSA edges. */
111
kono
parents: 67
diff changeset
382 ssa_edge_worklist = BITMAP_ALLOC (NULL);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
383 ssa_edge_worklist_back = BITMAP_ALLOC (NULL);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
384 bitmap_tree_view (ssa_edge_worklist);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
385 bitmap_tree_view (ssa_edge_worklist_back);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
386
111
kono
parents: 67
diff changeset
387 /* Worklist of basic-blocks. */
kono
parents: 67
diff changeset
388 bb_to_cfg_order = XNEWVEC (int, last_basic_block_for_fn (cfun) + 1);
kono
parents: 67
diff changeset
389 cfg_order_to_bb = XNEWVEC (int, n_basic_blocks_for_fn (cfun));
kono
parents: 67
diff changeset
390 int n = pre_and_rev_post_order_compute_fn (cfun, NULL,
kono
parents: 67
diff changeset
391 cfg_order_to_bb, false);
kono
parents: 67
diff changeset
392 for (int i = 0; i < n; ++i)
kono
parents: 67
diff changeset
393 bb_to_cfg_order[cfg_order_to_bb[i]] = i;
kono
parents: 67
diff changeset
394 cfg_blocks = BITMAP_ALLOC (NULL);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
395 cfg_blocks_back = BITMAP_ALLOC (NULL);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
396
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
397 /* Initially assume that every edge in the CFG is not executable.
111
kono
parents: 67
diff changeset
398 (including the edges coming out of the entry block). Mark blocks
kono
parents: 67
diff changeset
399 as not visited, blocks not yet visited will have all their statements
kono
parents: 67
diff changeset
400 simulated once an incoming edge gets executable. */
kono
parents: 67
diff changeset
401 set_gimple_stmt_max_uid (cfun, 0);
kono
parents: 67
diff changeset
402 for (int i = 0; i < n; ++i)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
403 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
404 gimple_stmt_iterator si;
111
kono
parents: 67
diff changeset
405 bb = BASIC_BLOCK_FOR_FN (cfun, cfg_order_to_bb[i]);
kono
parents: 67
diff changeset
406
kono
parents: 67
diff changeset
407 for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
kono
parents: 67
diff changeset
408 {
kono
parents: 67
diff changeset
409 gimple *stmt = gsi_stmt (si);
kono
parents: 67
diff changeset
410 gimple_set_uid (stmt, inc_gimple_stmt_max_uid (cfun));
kono
parents: 67
diff changeset
411 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
412
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
413 for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
111
kono
parents: 67
diff changeset
414 {
kono
parents: 67
diff changeset
415 gimple *stmt = gsi_stmt (si);
kono
parents: 67
diff changeset
416 gimple_set_uid (stmt, inc_gimple_stmt_max_uid (cfun));
kono
parents: 67
diff changeset
417 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
418
111
kono
parents: 67
diff changeset
419 bb->flags &= ~BB_VISITED;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
420 FOR_EACH_EDGE (e, ei, bb->succs)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
421 e->flags &= ~EDGE_EXECUTABLE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
422 }
111
kono
parents: 67
diff changeset
423 uid_to_stmt.safe_grow (gimple_stmt_max_uid (cfun));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
424
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
425 /* Seed the algorithm by adding the successors of the entry block to the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
426 edge worklist. */
111
kono
parents: 67
diff changeset
427 FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR_FOR_FN (cfun)->succs)
kono
parents: 67
diff changeset
428 {
kono
parents: 67
diff changeset
429 e->flags &= ~EDGE_EXECUTABLE;
kono
parents: 67
diff changeset
430 add_control_edge (e);
kono
parents: 67
diff changeset
431 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
432 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
433
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
434
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
435 /* Free allocated storage. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
436
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
437 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
438 ssa_prop_fini (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
439 {
111
kono
parents: 67
diff changeset
440 BITMAP_FREE (cfg_blocks);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
441 BITMAP_FREE (cfg_blocks_back);
111
kono
parents: 67
diff changeset
442 free (bb_to_cfg_order);
kono
parents: 67
diff changeset
443 free (cfg_order_to_bb);
kono
parents: 67
diff changeset
444 BITMAP_FREE (ssa_edge_worklist);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
445 BITMAP_FREE (ssa_edge_worklist_back);
111
kono
parents: 67
diff changeset
446 uid_to_stmt.release ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
447 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
448
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
449
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
450 /* Return true if EXPR is an acceptable right-hand-side for a
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
451 GIMPLE assignment. We validate the entire tree, not just
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
452 the root node, thus catching expressions that embed complex
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
453 operands that are not permitted in GIMPLE. This function
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
454 is needed because the folding routines in fold-const.c
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
455 may return such expressions in some cases, e.g., an array
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
456 access with an embedded index addition. It may make more
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
457 sense to have folding routines that are sensitive to the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
458 constraints on GIMPLE operands, rather than abandoning any
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
459 any attempt to fold if the usual folding turns out to be too
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
460 aggressive. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
461
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
462 bool
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
463 valid_gimple_rhs_p (tree expr)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
464 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
465 enum tree_code code = TREE_CODE (expr);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
466
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
467 switch (TREE_CODE_CLASS (code))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
468 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
469 case tcc_declaration:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
470 if (!is_gimple_variable (expr))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
471 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
472 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
473
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
474 case tcc_constant:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
475 /* All constants are ok. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
476 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
477
111
kono
parents: 67
diff changeset
478 case tcc_comparison:
kono
parents: 67
diff changeset
479 /* GENERIC allows comparisons with non-boolean types, reject
kono
parents: 67
diff changeset
480 those for GIMPLE. Let vector-typed comparisons pass - rules
kono
parents: 67
diff changeset
481 for GENERIC and GIMPLE are the same here. */
kono
parents: 67
diff changeset
482 if (!(INTEGRAL_TYPE_P (TREE_TYPE (expr))
kono
parents: 67
diff changeset
483 && (TREE_CODE (TREE_TYPE (expr)) == BOOLEAN_TYPE
kono
parents: 67
diff changeset
484 || TYPE_PRECISION (TREE_TYPE (expr)) == 1))
kono
parents: 67
diff changeset
485 && ! VECTOR_TYPE_P (TREE_TYPE (expr)))
kono
parents: 67
diff changeset
486 return false;
kono
parents: 67
diff changeset
487
kono
parents: 67
diff changeset
488 /* Fallthru. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
489 case tcc_binary:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
490 if (!is_gimple_val (TREE_OPERAND (expr, 0))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
491 || !is_gimple_val (TREE_OPERAND (expr, 1)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
492 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
493 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
494
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
495 case tcc_unary:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
496 if (!is_gimple_val (TREE_OPERAND (expr, 0)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
497 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
498 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
499
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
500 case tcc_expression:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
501 switch (code)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
502 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
503 case ADDR_EXPR:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
504 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
505 tree t;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
506 if (is_gimple_min_invariant (expr))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
507 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
508 t = TREE_OPERAND (expr, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
509 while (handled_component_p (t))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
510 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
511 /* ??? More checks needed, see the GIMPLE verifier. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
512 if ((TREE_CODE (t) == ARRAY_REF
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
513 || TREE_CODE (t) == ARRAY_RANGE_REF)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
514 && !is_gimple_val (TREE_OPERAND (t, 1)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
515 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
516 t = TREE_OPERAND (t, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
517 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
518 if (!is_gimple_id (t))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
519 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
520 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
521 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
522
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
523 default:
111
kono
parents: 67
diff changeset
524 if (get_gimple_rhs_class (code) == GIMPLE_TERNARY_RHS)
kono
parents: 67
diff changeset
525 {
kono
parents: 67
diff changeset
526 if (((code == VEC_COND_EXPR || code == COND_EXPR)
kono
parents: 67
diff changeset
527 ? !is_gimple_condexpr (TREE_OPERAND (expr, 0))
kono
parents: 67
diff changeset
528 : !is_gimple_val (TREE_OPERAND (expr, 0)))
kono
parents: 67
diff changeset
529 || !is_gimple_val (TREE_OPERAND (expr, 1))
kono
parents: 67
diff changeset
530 || !is_gimple_val (TREE_OPERAND (expr, 2)))
kono
parents: 67
diff changeset
531 return false;
kono
parents: 67
diff changeset
532 break;
kono
parents: 67
diff changeset
533 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
534 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
535 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
536 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
537
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
538 case tcc_vl_exp:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
539 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
540
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
541 case tcc_exceptional:
111
kono
parents: 67
diff changeset
542 if (code == CONSTRUCTOR)
kono
parents: 67
diff changeset
543 {
kono
parents: 67
diff changeset
544 unsigned i;
kono
parents: 67
diff changeset
545 tree elt;
kono
parents: 67
diff changeset
546 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expr), i, elt)
kono
parents: 67
diff changeset
547 if (!is_gimple_val (elt))
kono
parents: 67
diff changeset
548 return false;
kono
parents: 67
diff changeset
549 return true;
kono
parents: 67
diff changeset
550 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
551 if (code != SSA_NAME)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
552 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
553 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
554
111
kono
parents: 67
diff changeset
555 case tcc_reference:
kono
parents: 67
diff changeset
556 if (code == BIT_FIELD_REF)
kono
parents: 67
diff changeset
557 return is_gimple_val (TREE_OPERAND (expr, 0));
kono
parents: 67
diff changeset
558 return false;
kono
parents: 67
diff changeset
559
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
560 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
561 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
562 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
563
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
564 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
565 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
566
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
567
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
568 /* Return true if EXPR is a CALL_EXPR suitable for representation
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
569 as a single GIMPLE_CALL statement. If the arguments require
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
570 further gimplification, return false. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
571
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
572 static bool
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
573 valid_gimple_call_p (tree expr)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
574 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
575 unsigned i, nargs;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
576
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
577 if (TREE_CODE (expr) != CALL_EXPR)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
578 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
579
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
580 nargs = call_expr_nargs (expr);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
581 for (i = 0; i < nargs; i++)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
582 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
583 tree arg = CALL_EXPR_ARG (expr, i);
111
kono
parents: 67
diff changeset
584 if (is_gimple_reg_type (TREE_TYPE (arg)))
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
585 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
586 if (!is_gimple_val (arg))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
587 return false;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
588 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
589 else
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
590 if (!is_gimple_lvalue (arg))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
591 return false;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
592 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
593
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
594 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
595 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
596
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
597
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
598 /* Make SSA names defined by OLD_STMT point to NEW_STMT
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
599 as their defining statement. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
600
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
601 void
111
kono
parents: 67
diff changeset
602 move_ssa_defining_stmt_for_defs (gimple *new_stmt, gimple *old_stmt)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
603 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
604 tree var;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
605 ssa_op_iter iter;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
606
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
607 if (gimple_in_ssa_p (cfun))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
608 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
609 /* Make defined SSA_NAMEs point to the new
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
610 statement as their definition. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
611 FOR_EACH_SSA_TREE_OPERAND (var, old_stmt, iter, SSA_OP_ALL_DEFS)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
612 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
613 if (TREE_CODE (var) == SSA_NAME)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
614 SSA_NAME_DEF_STMT (var) = new_stmt;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
615 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
616 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
617 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
618
111
kono
parents: 67
diff changeset
619 /* Helper function for update_gimple_call and update_call_from_tree.
kono
parents: 67
diff changeset
620 A GIMPLE_CALL STMT is being replaced with GIMPLE_CALL NEW_STMT. */
kono
parents: 67
diff changeset
621
kono
parents: 67
diff changeset
622 static void
kono
parents: 67
diff changeset
623 finish_update_gimple_call (gimple_stmt_iterator *si_p, gimple *new_stmt,
kono
parents: 67
diff changeset
624 gimple *stmt)
kono
parents: 67
diff changeset
625 {
kono
parents: 67
diff changeset
626 gimple_call_set_lhs (new_stmt, gimple_call_lhs (stmt));
kono
parents: 67
diff changeset
627 move_ssa_defining_stmt_for_defs (new_stmt, stmt);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
628 gimple_move_vops (new_stmt, stmt);
111
kono
parents: 67
diff changeset
629 gimple_set_location (new_stmt, gimple_location (stmt));
kono
parents: 67
diff changeset
630 if (gimple_block (new_stmt) == NULL_TREE)
kono
parents: 67
diff changeset
631 gimple_set_block (new_stmt, gimple_block (stmt));
kono
parents: 67
diff changeset
632 gsi_replace (si_p, new_stmt, false);
kono
parents: 67
diff changeset
633 }
kono
parents: 67
diff changeset
634
kono
parents: 67
diff changeset
635 /* Update a GIMPLE_CALL statement at iterator *SI_P to call to FN
kono
parents: 67
diff changeset
636 with number of arguments NARGS, where the arguments in GIMPLE form
kono
parents: 67
diff changeset
637 follow NARGS argument. */
kono
parents: 67
diff changeset
638
kono
parents: 67
diff changeset
639 bool
kono
parents: 67
diff changeset
640 update_gimple_call (gimple_stmt_iterator *si_p, tree fn, int nargs, ...)
kono
parents: 67
diff changeset
641 {
kono
parents: 67
diff changeset
642 va_list ap;
kono
parents: 67
diff changeset
643 gcall *new_stmt, *stmt = as_a <gcall *> (gsi_stmt (*si_p));
kono
parents: 67
diff changeset
644
kono
parents: 67
diff changeset
645 gcc_assert (is_gimple_call (stmt));
kono
parents: 67
diff changeset
646 va_start (ap, nargs);
kono
parents: 67
diff changeset
647 new_stmt = gimple_build_call_valist (fn, nargs, ap);
kono
parents: 67
diff changeset
648 finish_update_gimple_call (si_p, new_stmt, stmt);
kono
parents: 67
diff changeset
649 va_end (ap);
kono
parents: 67
diff changeset
650 return true;
kono
parents: 67
diff changeset
651 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
652
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
653 /* Update a GIMPLE_CALL statement at iterator *SI_P to reflect the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
654 value of EXPR, which is expected to be the result of folding the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
655 call. This can only be done if EXPR is a CALL_EXPR with valid
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
656 GIMPLE operands as arguments, or if it is a suitable RHS expression
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
657 for a GIMPLE_ASSIGN. More complex expressions will require
111
kono
parents: 67
diff changeset
658 gimplification, which will introduce additional statements. In this
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
659 event, no update is performed, and the function returns false.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
660 Note that we cannot mutate a GIMPLE_CALL in-place, so we always
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
661 replace the statement at *SI_P with an entirely new statement.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
662 The new statement need not be a call, e.g., if the original call
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
663 folded to a constant. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
664
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
665 bool
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
666 update_call_from_tree (gimple_stmt_iterator *si_p, tree expr)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
667 {
111
kono
parents: 67
diff changeset
668 gimple *stmt = gsi_stmt (*si_p);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
669
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
670 if (valid_gimple_call_p (expr))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
671 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
672 /* The call has simplified to another call. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
673 tree fn = CALL_EXPR_FN (expr);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
674 unsigned i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
675 unsigned nargs = call_expr_nargs (expr);
111
kono
parents: 67
diff changeset
676 vec<tree> args = vNULL;
kono
parents: 67
diff changeset
677 gcall *new_stmt;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
678
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
679 if (nargs > 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
680 {
111
kono
parents: 67
diff changeset
681 args.create (nargs);
kono
parents: 67
diff changeset
682 args.safe_grow_cleared (nargs);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
683
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
684 for (i = 0; i < nargs; i++)
111
kono
parents: 67
diff changeset
685 args[i] = CALL_EXPR_ARG (expr, i);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
686 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
687
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
688 new_stmt = gimple_build_call_vec (fn, args);
111
kono
parents: 67
diff changeset
689 finish_update_gimple_call (si_p, new_stmt, stmt);
kono
parents: 67
diff changeset
690 args.release ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
691
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
692 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
693 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
694 else if (valid_gimple_rhs_p (expr))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
695 {
111
kono
parents: 67
diff changeset
696 tree lhs = gimple_call_lhs (stmt);
kono
parents: 67
diff changeset
697 gimple *new_stmt;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
698
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
699 /* The call has simplified to an expression
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
700 that cannot be represented as a GIMPLE_CALL. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
701 if (lhs)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
702 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
703 /* A value is expected.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
704 Introduce a new GIMPLE_ASSIGN statement. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
705 STRIP_USELESS_TYPE_CONVERSION (expr);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
706 new_stmt = gimple_build_assign (lhs, expr);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
707 move_ssa_defining_stmt_for_defs (new_stmt, stmt);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
708 gimple_move_vops (new_stmt, stmt);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
709 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
710 else if (!TREE_SIDE_EFFECTS (expr))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
711 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
712 /* No value is expected, and EXPR has no effect.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
713 Replace it with an empty statement. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
714 new_stmt = gimple_build_nop ();
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
715 if (gimple_in_ssa_p (cfun))
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
716 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
717 unlink_stmt_vdef (stmt);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
718 release_defs (stmt);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
719 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
720 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
721 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
722 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
723 /* No value is expected, but EXPR has an effect,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
724 e.g., it could be a reference to a volatile
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
725 variable. Create an assignment statement
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
726 with a dummy (unused) lhs variable. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
727 STRIP_USELESS_TYPE_CONVERSION (expr);
111
kono
parents: 67
diff changeset
728 if (gimple_in_ssa_p (cfun))
kono
parents: 67
diff changeset
729 lhs = make_ssa_name (TREE_TYPE (expr));
kono
parents: 67
diff changeset
730 else
kono
parents: 67
diff changeset
731 lhs = create_tmp_var (TREE_TYPE (expr));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
732 new_stmt = gimple_build_assign (lhs, expr);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
733 gimple_move_vops (new_stmt, stmt);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
734 move_ssa_defining_stmt_for_defs (new_stmt, stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
735 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
736 gimple_set_location (new_stmt, gimple_location (stmt));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
737 gsi_replace (si_p, new_stmt, false);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
738 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
739 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
740 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
741 /* The call simplified to an expression that is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
742 not a valid GIMPLE RHS. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
743 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
744 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
745
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
746 /* Entry point to the propagation engine.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
747
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
748 The VISIT_STMT virtual function is called for every statement
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
749 visited and the VISIT_PHI virtual function is called for every PHI
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
750 node visited. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
751
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
752 void
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
753 ssa_propagation_engine::ssa_propagate (void)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
754 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
755 ssa_prop_init ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
756
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
757 curr_order = 0;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
758
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
759 /* Iterate until the worklists are empty. We iterate both blocks
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
760 and stmts in RPO order, using sets of two worklists to first
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
761 complete the current iteration before iterating over backedges. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
762 while (1)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
763 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
764 int next_block_order = (bitmap_empty_p (cfg_blocks)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
765 ? -1 : bitmap_first_set_bit (cfg_blocks));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
766 int next_stmt_uid = (bitmap_empty_p (ssa_edge_worklist)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
767 ? -1 : bitmap_first_set_bit (ssa_edge_worklist));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
768 if (next_block_order == -1 && next_stmt_uid == -1)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
769 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
770 if (bitmap_empty_p (cfg_blocks_back)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
771 && bitmap_empty_p (ssa_edge_worklist_back))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
772 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
773
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
774 if (dump_file && (dump_flags & TDF_DETAILS))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
775 fprintf (dump_file, "Regular worklists empty, now processing "
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
776 "backedge destinations\n");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
777 std::swap (cfg_blocks, cfg_blocks_back);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
778 std::swap (ssa_edge_worklist, ssa_edge_worklist_back);
111
kono
parents: 67
diff changeset
779 continue;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
780 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
781
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
782 int next_stmt_bb_order = -1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
783 gimple *next_stmt = NULL;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
784 if (next_stmt_uid != -1)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
785 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
786 next_stmt = uid_to_stmt[next_stmt_uid];
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
787 next_stmt_bb_order = bb_to_cfg_order[gimple_bb (next_stmt)->index];
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
788 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
789
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
790 /* Pull the next block to simulate off the worklist if it comes first. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
791 if (next_block_order != -1
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
792 && (next_stmt_bb_order == -1
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
793 || next_block_order <= next_stmt_bb_order))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
794 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
795 curr_order = next_block_order;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
796 bitmap_clear_bit (cfg_blocks, next_block_order);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
797 basic_block bb
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
798 = BASIC_BLOCK_FOR_FN (cfun, cfg_order_to_bb [next_block_order]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
799 simulate_block (bb);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
800 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
801 /* Else simulate from the SSA edge worklist. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
802 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
803 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
804 curr_order = next_stmt_bb_order;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
805 if (dump_file && (dump_flags & TDF_DETAILS))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
806 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
807 fprintf (dump_file, "\nSimulating statement: ");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
808 print_gimple_stmt (dump_file, next_stmt, 0, dump_flags);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
809 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
810 simulate_stmt (next_stmt);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
811 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
812 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
813
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
814 ssa_prop_fini ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
815 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
816
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
817 /* Return true if STMT is of the form 'mem_ref = RHS', where 'mem_ref'
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
818 is a non-volatile pointer dereference, a structure reference or a
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
819 reference to a single _DECL. Ignore volatile memory references
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
820 because they are not interesting for the optimizers. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
821
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
822 bool
111
kono
parents: 67
diff changeset
823 stmt_makes_single_store (gimple *stmt)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
824 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
825 tree lhs;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
826
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
827 if (gimple_code (stmt) != GIMPLE_ASSIGN
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
828 && gimple_code (stmt) != GIMPLE_CALL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
829 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
830
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
831 if (!gimple_vdef (stmt))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
832 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
833
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
834 lhs = gimple_get_lhs (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
835
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
836 /* A call statement may have a null LHS. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
837 if (!lhs)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
838 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
839
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
840 return (!TREE_THIS_VOLATILE (lhs)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
841 && (DECL_P (lhs)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
842 || REFERENCE_CLASS_P (lhs)));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
843 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
844
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
845
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
846 /* Propagation statistics. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
847 struct prop_stats_d
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
848 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
849 long num_const_prop;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
850 long num_copy_prop;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
851 long num_stmts_folded;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
852 long num_dce;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
853 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
854
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
855 static struct prop_stats_d prop_stats;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
856
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
857 /* Replace USE references in statement STMT with the values stored in
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
858 PROP_VALUE. Return true if at least one reference was replaced. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
859
111
kono
parents: 67
diff changeset
860 bool
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
861 substitute_and_fold_engine::replace_uses_in (gimple *stmt)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
862 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
863 bool replaced = false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
864 use_operand_p use;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
865 ssa_op_iter iter;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
866
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
867 FOR_EACH_SSA_USE_OPERAND (use, stmt, iter, SSA_OP_USE)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
868 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
869 tree tuse = USE_FROM_PTR (use);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
870 tree val = get_value (tuse);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
871
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
872 if (val == tuse || val == NULL_TREE)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
873 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
874
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
875 if (gimple_code (stmt) == GIMPLE_ASM
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
876 && !may_propagate_copy_into_asm (tuse))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
877 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
878
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
879 if (!may_propagate_copy (tuse, val))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
880 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
881
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
882 if (TREE_CODE (val) != SSA_NAME)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
883 prop_stats.num_const_prop++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
884 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
885 prop_stats.num_copy_prop++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
886
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
887 propagate_value (use, val);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
888
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
889 replaced = true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
890 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
891
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
892 return replaced;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
893 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
894
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
895
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
896 /* Replace propagated values into all the arguments for PHI using the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
897 values from PROP_VALUE. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
898
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
899 bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
900 substitute_and_fold_engine::replace_phi_args_in (gphi *phi)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
901 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
902 size_t i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
903 bool replaced = false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
904
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
905 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
906 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
907 fprintf (dump_file, "Folding PHI node: ");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
908 print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
909 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
910
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
911 for (i = 0; i < gimple_phi_num_args (phi); i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
912 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
913 tree arg = gimple_phi_arg_def (phi, i);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
914
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
915 if (TREE_CODE (arg) == SSA_NAME)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
916 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
917 tree val = get_value (arg);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
918
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
919 if (val && val != arg && may_propagate_copy (arg, val))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
920 {
111
kono
parents: 67
diff changeset
921 edge e = gimple_phi_arg_edge (phi, i);
kono
parents: 67
diff changeset
922
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
923 if (TREE_CODE (val) != SSA_NAME)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
924 prop_stats.num_const_prop++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
925 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
926 prop_stats.num_copy_prop++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
927
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
928 propagate_value (PHI_ARG_DEF_PTR (phi, i), val);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
929 replaced = true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
930
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
931 /* If we propagated a copy and this argument flows
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
932 through an abnormal edge, update the replacement
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
933 accordingly. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
934 if (TREE_CODE (val) == SSA_NAME
111
kono
parents: 67
diff changeset
935 && e->flags & EDGE_ABNORMAL
kono
parents: 67
diff changeset
936 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val))
kono
parents: 67
diff changeset
937 {
kono
parents: 67
diff changeset
938 /* This can only occur for virtual operands, since
kono
parents: 67
diff changeset
939 for the real ones SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val))
kono
parents: 67
diff changeset
940 would prevent replacement. */
kono
parents: 67
diff changeset
941 gcc_checking_assert (virtual_operand_p (val));
kono
parents: 67
diff changeset
942 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val) = 1;
kono
parents: 67
diff changeset
943 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
944 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
945 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
946 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
947
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
948 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
949 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
950 if (!replaced)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
951 fprintf (dump_file, "No folding possible\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
952 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
953 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
954 fprintf (dump_file, "Folded into: ");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
955 print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
956 fprintf (dump_file, "\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
957 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
958 }
111
kono
parents: 67
diff changeset
959
kono
parents: 67
diff changeset
960 return replaced;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
961 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
962
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
963
111
kono
parents: 67
diff changeset
964 class substitute_and_fold_dom_walker : public dom_walker
kono
parents: 67
diff changeset
965 {
kono
parents: 67
diff changeset
966 public:
kono
parents: 67
diff changeset
967 substitute_and_fold_dom_walker (cdi_direction direction,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
968 class substitute_and_fold_engine *engine)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
969 : dom_walker (direction),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
970 something_changed (false),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
971 substitute_and_fold_engine (engine)
111
kono
parents: 67
diff changeset
972 {
kono
parents: 67
diff changeset
973 stmts_to_remove.create (0);
kono
parents: 67
diff changeset
974 stmts_to_fixup.create (0);
kono
parents: 67
diff changeset
975 need_eh_cleanup = BITMAP_ALLOC (NULL);
kono
parents: 67
diff changeset
976 }
kono
parents: 67
diff changeset
977 ~substitute_and_fold_dom_walker ()
kono
parents: 67
diff changeset
978 {
kono
parents: 67
diff changeset
979 stmts_to_remove.release ();
kono
parents: 67
diff changeset
980 stmts_to_fixup.release ();
kono
parents: 67
diff changeset
981 BITMAP_FREE (need_eh_cleanup);
kono
parents: 67
diff changeset
982 }
kono
parents: 67
diff changeset
983
kono
parents: 67
diff changeset
984 virtual edge before_dom_children (basic_block);
kono
parents: 67
diff changeset
985 virtual void after_dom_children (basic_block) {}
kono
parents: 67
diff changeset
986
kono
parents: 67
diff changeset
987 bool something_changed;
kono
parents: 67
diff changeset
988 vec<gimple *> stmts_to_remove;
kono
parents: 67
diff changeset
989 vec<gimple *> stmts_to_fixup;
kono
parents: 67
diff changeset
990 bitmap need_eh_cleanup;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
991
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
992 class substitute_and_fold_engine *substitute_and_fold_engine;
111
kono
parents: 67
diff changeset
993 };
kono
parents: 67
diff changeset
994
kono
parents: 67
diff changeset
995 edge
kono
parents: 67
diff changeset
996 substitute_and_fold_dom_walker::before_dom_children (basic_block bb)
kono
parents: 67
diff changeset
997 {
kono
parents: 67
diff changeset
998 /* Propagate known values into PHI nodes. */
kono
parents: 67
diff changeset
999 for (gphi_iterator i = gsi_start_phis (bb);
kono
parents: 67
diff changeset
1000 !gsi_end_p (i);
kono
parents: 67
diff changeset
1001 gsi_next (&i))
kono
parents: 67
diff changeset
1002 {
kono
parents: 67
diff changeset
1003 gphi *phi = i.phi ();
kono
parents: 67
diff changeset
1004 tree res = gimple_phi_result (phi);
kono
parents: 67
diff changeset
1005 if (virtual_operand_p (res))
kono
parents: 67
diff changeset
1006 continue;
kono
parents: 67
diff changeset
1007 if (res && TREE_CODE (res) == SSA_NAME)
kono
parents: 67
diff changeset
1008 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1009 tree sprime = substitute_and_fold_engine->get_value (res);
111
kono
parents: 67
diff changeset
1010 if (sprime
kono
parents: 67
diff changeset
1011 && sprime != res
kono
parents: 67
diff changeset
1012 && may_propagate_copy (res, sprime))
kono
parents: 67
diff changeset
1013 {
kono
parents: 67
diff changeset
1014 stmts_to_remove.safe_push (phi);
kono
parents: 67
diff changeset
1015 continue;
kono
parents: 67
diff changeset
1016 }
kono
parents: 67
diff changeset
1017 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1018 something_changed |= substitute_and_fold_engine->replace_phi_args_in (phi);
111
kono
parents: 67
diff changeset
1019 }
kono
parents: 67
diff changeset
1020
kono
parents: 67
diff changeset
1021 /* Propagate known values into stmts. In some case it exposes
kono
parents: 67
diff changeset
1022 more trivially deletable stmts to walk backward. */
kono
parents: 67
diff changeset
1023 for (gimple_stmt_iterator i = gsi_start_bb (bb);
kono
parents: 67
diff changeset
1024 !gsi_end_p (i);
kono
parents: 67
diff changeset
1025 gsi_next (&i))
kono
parents: 67
diff changeset
1026 {
kono
parents: 67
diff changeset
1027 bool did_replace;
kono
parents: 67
diff changeset
1028 gimple *stmt = gsi_stmt (i);
kono
parents: 67
diff changeset
1029
kono
parents: 67
diff changeset
1030 /* No point propagating into a stmt we have a value for we
kono
parents: 67
diff changeset
1031 can propagate into all uses. Mark it for removal instead. */
kono
parents: 67
diff changeset
1032 tree lhs = gimple_get_lhs (stmt);
kono
parents: 67
diff changeset
1033 if (lhs && TREE_CODE (lhs) == SSA_NAME)
kono
parents: 67
diff changeset
1034 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1035 tree sprime = substitute_and_fold_engine->get_value (lhs);
111
kono
parents: 67
diff changeset
1036 if (sprime
kono
parents: 67
diff changeset
1037 && sprime != lhs
kono
parents: 67
diff changeset
1038 && may_propagate_copy (lhs, sprime)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1039 && !stmt_could_throw_p (cfun, stmt)
111
kono
parents: 67
diff changeset
1040 && !gimple_has_side_effects (stmt)
kono
parents: 67
diff changeset
1041 /* We have to leave ASSERT_EXPRs around for jump-threading. */
kono
parents: 67
diff changeset
1042 && (!is_gimple_assign (stmt)
kono
parents: 67
diff changeset
1043 || gimple_assign_rhs_code (stmt) != ASSERT_EXPR))
kono
parents: 67
diff changeset
1044 {
kono
parents: 67
diff changeset
1045 stmts_to_remove.safe_push (stmt);
kono
parents: 67
diff changeset
1046 continue;
kono
parents: 67
diff changeset
1047 }
kono
parents: 67
diff changeset
1048 }
kono
parents: 67
diff changeset
1049
kono
parents: 67
diff changeset
1050 /* Replace the statement with its folded version and mark it
kono
parents: 67
diff changeset
1051 folded. */
kono
parents: 67
diff changeset
1052 did_replace = false;
kono
parents: 67
diff changeset
1053 if (dump_file && (dump_flags & TDF_DETAILS))
kono
parents: 67
diff changeset
1054 {
kono
parents: 67
diff changeset
1055 fprintf (dump_file, "Folding statement: ");
kono
parents: 67
diff changeset
1056 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
kono
parents: 67
diff changeset
1057 }
kono
parents: 67
diff changeset
1058
kono
parents: 67
diff changeset
1059 gimple *old_stmt = stmt;
kono
parents: 67
diff changeset
1060 bool was_noreturn = (is_gimple_call (stmt)
kono
parents: 67
diff changeset
1061 && gimple_call_noreturn_p (stmt));
kono
parents: 67
diff changeset
1062
kono
parents: 67
diff changeset
1063 /* Replace real uses in the statement. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1064 did_replace |= substitute_and_fold_engine->replace_uses_in (stmt);
111
kono
parents: 67
diff changeset
1065
kono
parents: 67
diff changeset
1066 /* If we made a replacement, fold the statement. */
kono
parents: 67
diff changeset
1067 if (did_replace)
kono
parents: 67
diff changeset
1068 {
kono
parents: 67
diff changeset
1069 fold_stmt (&i, follow_single_use_edges);
kono
parents: 67
diff changeset
1070 stmt = gsi_stmt (i);
kono
parents: 67
diff changeset
1071 gimple_set_modified (stmt, true);
kono
parents: 67
diff changeset
1072 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1073 /* Also fold if we want to fold all statements. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1074 else if (substitute_and_fold_engine->fold_all_stmts
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1075 && fold_stmt (&i, follow_single_use_edges))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1076 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1077 did_replace = true;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1078 stmt = gsi_stmt (i);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1079 gimple_set_modified (stmt, true);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1080 }
111
kono
parents: 67
diff changeset
1081
kono
parents: 67
diff changeset
1082 /* Some statements may be simplified using propagator
kono
parents: 67
diff changeset
1083 specific information. Do this before propagating
kono
parents: 67
diff changeset
1084 into the stmt to not disturb pass specific information. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1085 update_stmt_if_modified (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1086 if (substitute_and_fold_engine->fold_stmt(&i))
111
kono
parents: 67
diff changeset
1087 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1088 did_replace = true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1089 prop_stats.num_stmts_folded++;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1090 stmt = gsi_stmt (i);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1091 gimple_set_modified (stmt, true);
111
kono
parents: 67
diff changeset
1092 }
kono
parents: 67
diff changeset
1093
kono
parents: 67
diff changeset
1094 /* If this is a control statement the propagator left edges
kono
parents: 67
diff changeset
1095 unexecuted on force the condition in a way consistent with
kono
parents: 67
diff changeset
1096 that. See PR66945 for cases where the propagator can end
kono
parents: 67
diff changeset
1097 up with a different idea of a taken edge than folding
kono
parents: 67
diff changeset
1098 (once undefined behavior is involved). */
kono
parents: 67
diff changeset
1099 if (gimple_code (stmt) == GIMPLE_COND)
kono
parents: 67
diff changeset
1100 {
kono
parents: 67
diff changeset
1101 if ((EDGE_SUCC (bb, 0)->flags & EDGE_EXECUTABLE)
kono
parents: 67
diff changeset
1102 ^ (EDGE_SUCC (bb, 1)->flags & EDGE_EXECUTABLE))
kono
parents: 67
diff changeset
1103 {
kono
parents: 67
diff changeset
1104 if (((EDGE_SUCC (bb, 0)->flags & EDGE_TRUE_VALUE) != 0)
kono
parents: 67
diff changeset
1105 == ((EDGE_SUCC (bb, 0)->flags & EDGE_EXECUTABLE) != 0))
kono
parents: 67
diff changeset
1106 gimple_cond_make_true (as_a <gcond *> (stmt));
kono
parents: 67
diff changeset
1107 else
kono
parents: 67
diff changeset
1108 gimple_cond_make_false (as_a <gcond *> (stmt));
kono
parents: 67
diff changeset
1109 gimple_set_modified (stmt, true);
kono
parents: 67
diff changeset
1110 did_replace = true;
kono
parents: 67
diff changeset
1111 }
kono
parents: 67
diff changeset
1112 }
kono
parents: 67
diff changeset
1113
kono
parents: 67
diff changeset
1114 /* Now cleanup. */
kono
parents: 67
diff changeset
1115 if (did_replace)
kono
parents: 67
diff changeset
1116 {
kono
parents: 67
diff changeset
1117 /* If we cleaned up EH information from the statement,
kono
parents: 67
diff changeset
1118 remove EH edges. */
kono
parents: 67
diff changeset
1119 if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt))
kono
parents: 67
diff changeset
1120 bitmap_set_bit (need_eh_cleanup, bb->index);
kono
parents: 67
diff changeset
1121
kono
parents: 67
diff changeset
1122 /* If we turned a not noreturn call into a noreturn one
kono
parents: 67
diff changeset
1123 schedule it for fixup. */
kono
parents: 67
diff changeset
1124 if (!was_noreturn
kono
parents: 67
diff changeset
1125 && is_gimple_call (stmt)
kono
parents: 67
diff changeset
1126 && gimple_call_noreturn_p (stmt))
kono
parents: 67
diff changeset
1127 stmts_to_fixup.safe_push (stmt);
kono
parents: 67
diff changeset
1128
kono
parents: 67
diff changeset
1129 if (gimple_assign_single_p (stmt))
kono
parents: 67
diff changeset
1130 {
kono
parents: 67
diff changeset
1131 tree rhs = gimple_assign_rhs1 (stmt);
kono
parents: 67
diff changeset
1132
kono
parents: 67
diff changeset
1133 if (TREE_CODE (rhs) == ADDR_EXPR)
kono
parents: 67
diff changeset
1134 recompute_tree_invariant_for_addr_expr (rhs);
kono
parents: 67
diff changeset
1135 }
kono
parents: 67
diff changeset
1136
kono
parents: 67
diff changeset
1137 /* Determine what needs to be done to update the SSA form. */
kono
parents: 67
diff changeset
1138 update_stmt_if_modified (stmt);
kono
parents: 67
diff changeset
1139 if (!is_gimple_debug (stmt))
kono
parents: 67
diff changeset
1140 something_changed = true;
kono
parents: 67
diff changeset
1141 }
kono
parents: 67
diff changeset
1142
kono
parents: 67
diff changeset
1143 if (dump_file && (dump_flags & TDF_DETAILS))
kono
parents: 67
diff changeset
1144 {
kono
parents: 67
diff changeset
1145 if (did_replace)
kono
parents: 67
diff changeset
1146 {
kono
parents: 67
diff changeset
1147 fprintf (dump_file, "Folded into: ");
kono
parents: 67
diff changeset
1148 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
kono
parents: 67
diff changeset
1149 fprintf (dump_file, "\n");
kono
parents: 67
diff changeset
1150 }
kono
parents: 67
diff changeset
1151 else
kono
parents: 67
diff changeset
1152 fprintf (dump_file, "Not folded\n");
kono
parents: 67
diff changeset
1153 }
kono
parents: 67
diff changeset
1154 }
kono
parents: 67
diff changeset
1155 return NULL;
kono
parents: 67
diff changeset
1156 }
kono
parents: 67
diff changeset
1157
kono
parents: 67
diff changeset
1158
kono
parents: 67
diff changeset
1159
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1160 /* Perform final substitution and folding of propagated values.
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1161 Process the whole function if BLOCK is null, otherwise only
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1162 process the blocks that BLOCK dominates. In the latter case,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1163 it is the caller's responsibility to ensure that dominator
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1164 information is available and up-to-date.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1165
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1166 PROP_VALUE[I] contains the single value that should be substituted
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1167 at every use of SSA name N_I. If PROP_VALUE is NULL, no values are
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1168 substituted.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1169
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1170 If FOLD_FN is non-NULL the function will be invoked on all statements
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1171 before propagating values for pass specific simplification.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1172
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1173 DO_DCE is true if trivially dead stmts can be removed.
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1174
111
kono
parents: 67
diff changeset
1175 If DO_DCE is true, the statements within a BB are walked from
kono
parents: 67
diff changeset
1176 last to first element. Otherwise we scan from first to last element.
kono
parents: 67
diff changeset
1177
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1178 Return TRUE when something changed. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1179
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1180 bool
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1181 substitute_and_fold_engine::substitute_and_fold (basic_block block)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1182 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1183 if (dump_file && (dump_flags & TDF_DETAILS))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1184 fprintf (dump_file, "\nSubstituting values and folding statements\n\n");
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1185
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1186 memset (&prop_stats, 0, sizeof (prop_stats));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1187
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1188 /* Don't call calculate_dominance_info when iterating over a subgraph.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1189 Callers that are using the interface this way are likely to want to
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1190 iterate over several disjoint subgraphs, and it would be expensive
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1191 in enable-checking builds to revalidate the whole dominance tree
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1192 each time. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1193 if (block)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1194 gcc_assert (dom_info_state (CDI_DOMINATORS));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1195 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1196 calculate_dominance_info (CDI_DOMINATORS);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1197 substitute_and_fold_dom_walker walker (CDI_DOMINATORS, this);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1198 walker.walk (block ? block : ENTRY_BLOCK_PTR_FOR_FN (cfun));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1199
111
kono
parents: 67
diff changeset
1200 /* We cannot remove stmts during the BB walk, especially not release
kono
parents: 67
diff changeset
1201 SSA names there as that destroys the lattice of our callers.
kono
parents: 67
diff changeset
1202 Remove stmts in reverse order to make debug stmt creation possible. */
kono
parents: 67
diff changeset
1203 while (!walker.stmts_to_remove.is_empty ())
kono
parents: 67
diff changeset
1204 {
kono
parents: 67
diff changeset
1205 gimple *stmt = walker.stmts_to_remove.pop ();
kono
parents: 67
diff changeset
1206 if (dump_file && dump_flags & TDF_DETAILS)
kono
parents: 67
diff changeset
1207 {
kono
parents: 67
diff changeset
1208 fprintf (dump_file, "Removing dead stmt ");
kono
parents: 67
diff changeset
1209 print_gimple_stmt (dump_file, stmt, 0);
kono
parents: 67
diff changeset
1210 fprintf (dump_file, "\n");
kono
parents: 67
diff changeset
1211 }
kono
parents: 67
diff changeset
1212 prop_stats.num_dce++;
kono
parents: 67
diff changeset
1213 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
kono
parents: 67
diff changeset
1214 if (gimple_code (stmt) == GIMPLE_PHI)
kono
parents: 67
diff changeset
1215 remove_phi_node (&gsi, true);
kono
parents: 67
diff changeset
1216 else
kono
parents: 67
diff changeset
1217 {
kono
parents: 67
diff changeset
1218 unlink_stmt_vdef (stmt);
kono
parents: 67
diff changeset
1219 gsi_remove (&gsi, true);
kono
parents: 67
diff changeset
1220 release_defs (stmt);
kono
parents: 67
diff changeset
1221 }
kono
parents: 67
diff changeset
1222 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1223
111
kono
parents: 67
diff changeset
1224 if (!bitmap_empty_p (walker.need_eh_cleanup))
kono
parents: 67
diff changeset
1225 gimple_purge_all_dead_eh_edges (walker.need_eh_cleanup);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1226
111
kono
parents: 67
diff changeset
1227 /* Fixup stmts that became noreturn calls. This may require splitting
kono
parents: 67
diff changeset
1228 blocks and thus isn't possible during the dominator walk. Do this
kono
parents: 67
diff changeset
1229 in reverse order so we don't inadvertedly remove a stmt we want to
kono
parents: 67
diff changeset
1230 fixup by visiting a dominating now noreturn call first. */
kono
parents: 67
diff changeset
1231 while (!walker.stmts_to_fixup.is_empty ())
kono
parents: 67
diff changeset
1232 {
kono
parents: 67
diff changeset
1233 gimple *stmt = walker.stmts_to_fixup.pop ();
kono
parents: 67
diff changeset
1234 if (dump_file && dump_flags & TDF_DETAILS)
kono
parents: 67
diff changeset
1235 {
kono
parents: 67
diff changeset
1236 fprintf (dump_file, "Fixing up noreturn call ");
kono
parents: 67
diff changeset
1237 print_gimple_stmt (dump_file, stmt, 0);
kono
parents: 67
diff changeset
1238 fprintf (dump_file, "\n");
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1239 }
111
kono
parents: 67
diff changeset
1240 fixup_noreturn_call (stmt);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1241 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1242
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1243 statistics_counter_event (cfun, "Constants propagated",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1244 prop_stats.num_const_prop);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1245 statistics_counter_event (cfun, "Copies propagated",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1246 prop_stats.num_copy_prop);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1247 statistics_counter_event (cfun, "Statements folded",
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1248 prop_stats.num_stmts_folded);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1249 statistics_counter_event (cfun, "Statements deleted",
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1250 prop_stats.num_dce);
111
kono
parents: 67
diff changeset
1251
kono
parents: 67
diff changeset
1252 return walker.something_changed;
kono
parents: 67
diff changeset
1253 }
kono
parents: 67
diff changeset
1254
kono
parents: 67
diff changeset
1255
kono
parents: 67
diff changeset
1256 /* Return true if we may propagate ORIG into DEST, false otherwise. */
kono
parents: 67
diff changeset
1257
kono
parents: 67
diff changeset
1258 bool
kono
parents: 67
diff changeset
1259 may_propagate_copy (tree dest, tree orig)
kono
parents: 67
diff changeset
1260 {
kono
parents: 67
diff changeset
1261 tree type_d = TREE_TYPE (dest);
kono
parents: 67
diff changeset
1262 tree type_o = TREE_TYPE (orig);
kono
parents: 67
diff changeset
1263
kono
parents: 67
diff changeset
1264 /* If ORIG is a default definition which flows in from an abnormal edge
kono
parents: 67
diff changeset
1265 then the copy can be propagated. It is important that we do so to avoid
kono
parents: 67
diff changeset
1266 uninitialized copies. */
kono
parents: 67
diff changeset
1267 if (TREE_CODE (orig) == SSA_NAME
kono
parents: 67
diff changeset
1268 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig)
kono
parents: 67
diff changeset
1269 && SSA_NAME_IS_DEFAULT_DEF (orig)
kono
parents: 67
diff changeset
1270 && (SSA_NAME_VAR (orig) == NULL_TREE
kono
parents: 67
diff changeset
1271 || TREE_CODE (SSA_NAME_VAR (orig)) == VAR_DECL))
kono
parents: 67
diff changeset
1272 ;
kono
parents: 67
diff changeset
1273 /* Otherwise if ORIG just flows in from an abnormal edge then the copy cannot
kono
parents: 67
diff changeset
1274 be propagated. */
kono
parents: 67
diff changeset
1275 else if (TREE_CODE (orig) == SSA_NAME
kono
parents: 67
diff changeset
1276 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig))
kono
parents: 67
diff changeset
1277 return false;
kono
parents: 67
diff changeset
1278 /* Similarly if DEST flows in from an abnormal edge then the copy cannot be
kono
parents: 67
diff changeset
1279 propagated. */
kono
parents: 67
diff changeset
1280 else if (TREE_CODE (dest) == SSA_NAME
kono
parents: 67
diff changeset
1281 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (dest))
kono
parents: 67
diff changeset
1282 return false;
kono
parents: 67
diff changeset
1283
kono
parents: 67
diff changeset
1284 /* Do not copy between types for which we *do* need a conversion. */
kono
parents: 67
diff changeset
1285 if (!useless_type_conversion_p (type_d, type_o))
kono
parents: 67
diff changeset
1286 return false;
kono
parents: 67
diff changeset
1287
kono
parents: 67
diff changeset
1288 /* Generally propagating virtual operands is not ok as that may
kono
parents: 67
diff changeset
1289 create overlapping life-ranges. */
kono
parents: 67
diff changeset
1290 if (TREE_CODE (dest) == SSA_NAME && virtual_operand_p (dest))
kono
parents: 67
diff changeset
1291 return false;
kono
parents: 67
diff changeset
1292
kono
parents: 67
diff changeset
1293 /* Anything else is OK. */
kono
parents: 67
diff changeset
1294 return true;
kono
parents: 67
diff changeset
1295 }
kono
parents: 67
diff changeset
1296
kono
parents: 67
diff changeset
1297 /* Like may_propagate_copy, but use as the destination expression
kono
parents: 67
diff changeset
1298 the principal expression (typically, the RHS) contained in
kono
parents: 67
diff changeset
1299 statement DEST. This is more efficient when working with the
kono
parents: 67
diff changeset
1300 gimple tuples representation. */
kono
parents: 67
diff changeset
1301
kono
parents: 67
diff changeset
1302 bool
kono
parents: 67
diff changeset
1303 may_propagate_copy_into_stmt (gimple *dest, tree orig)
kono
parents: 67
diff changeset
1304 {
kono
parents: 67
diff changeset
1305 tree type_d;
kono
parents: 67
diff changeset
1306 tree type_o;
kono
parents: 67
diff changeset
1307
kono
parents: 67
diff changeset
1308 /* If the statement is a switch or a single-rhs assignment,
kono
parents: 67
diff changeset
1309 then the expression to be replaced by the propagation may
kono
parents: 67
diff changeset
1310 be an SSA_NAME. Fortunately, there is an explicit tree
kono
parents: 67
diff changeset
1311 for the expression, so we delegate to may_propagate_copy. */
kono
parents: 67
diff changeset
1312
kono
parents: 67
diff changeset
1313 if (gimple_assign_single_p (dest))
kono
parents: 67
diff changeset
1314 return may_propagate_copy (gimple_assign_rhs1 (dest), orig);
kono
parents: 67
diff changeset
1315 else if (gswitch *dest_swtch = dyn_cast <gswitch *> (dest))
kono
parents: 67
diff changeset
1316 return may_propagate_copy (gimple_switch_index (dest_swtch), orig);
kono
parents: 67
diff changeset
1317
kono
parents: 67
diff changeset
1318 /* In other cases, the expression is not materialized, so there
kono
parents: 67
diff changeset
1319 is no destination to pass to may_propagate_copy. On the other
kono
parents: 67
diff changeset
1320 hand, the expression cannot be an SSA_NAME, so the analysis
kono
parents: 67
diff changeset
1321 is much simpler. */
kono
parents: 67
diff changeset
1322
kono
parents: 67
diff changeset
1323 if (TREE_CODE (orig) == SSA_NAME
kono
parents: 67
diff changeset
1324 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig))
kono
parents: 67
diff changeset
1325 return false;
kono
parents: 67
diff changeset
1326
kono
parents: 67
diff changeset
1327 if (is_gimple_assign (dest))
kono
parents: 67
diff changeset
1328 type_d = TREE_TYPE (gimple_assign_lhs (dest));
kono
parents: 67
diff changeset
1329 else if (gimple_code (dest) == GIMPLE_COND)
kono
parents: 67
diff changeset
1330 type_d = boolean_type_node;
kono
parents: 67
diff changeset
1331 else if (is_gimple_call (dest)
kono
parents: 67
diff changeset
1332 && gimple_call_lhs (dest) != NULL_TREE)
kono
parents: 67
diff changeset
1333 type_d = TREE_TYPE (gimple_call_lhs (dest));
kono
parents: 67
diff changeset
1334 else
kono
parents: 67
diff changeset
1335 gcc_unreachable ();
kono
parents: 67
diff changeset
1336
kono
parents: 67
diff changeset
1337 type_o = TREE_TYPE (orig);
kono
parents: 67
diff changeset
1338
kono
parents: 67
diff changeset
1339 if (!useless_type_conversion_p (type_d, type_o))
kono
parents: 67
diff changeset
1340 return false;
kono
parents: 67
diff changeset
1341
kono
parents: 67
diff changeset
1342 return true;
kono
parents: 67
diff changeset
1343 }
kono
parents: 67
diff changeset
1344
kono
parents: 67
diff changeset
1345 /* Similarly, but we know that we're propagating into an ASM_EXPR. */
kono
parents: 67
diff changeset
1346
kono
parents: 67
diff changeset
1347 bool
kono
parents: 67
diff changeset
1348 may_propagate_copy_into_asm (tree dest ATTRIBUTE_UNUSED)
kono
parents: 67
diff changeset
1349 {
kono
parents: 67
diff changeset
1350 return true;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1351 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1352
111
kono
parents: 67
diff changeset
1353
kono
parents: 67
diff changeset
1354 /* Common code for propagate_value and replace_exp.
kono
parents: 67
diff changeset
1355
kono
parents: 67
diff changeset
1356 Replace use operand OP_P with VAL. FOR_PROPAGATION indicates if the
kono
parents: 67
diff changeset
1357 replacement is done to propagate a value or not. */
kono
parents: 67
diff changeset
1358
kono
parents: 67
diff changeset
1359 static void
kono
parents: 67
diff changeset
1360 replace_exp_1 (use_operand_p op_p, tree val,
kono
parents: 67
diff changeset
1361 bool for_propagation ATTRIBUTE_UNUSED)
kono
parents: 67
diff changeset
1362 {
kono
parents: 67
diff changeset
1363 if (flag_checking)
kono
parents: 67
diff changeset
1364 {
kono
parents: 67
diff changeset
1365 tree op = USE_FROM_PTR (op_p);
kono
parents: 67
diff changeset
1366 gcc_assert (!(for_propagation
kono
parents: 67
diff changeset
1367 && TREE_CODE (op) == SSA_NAME
kono
parents: 67
diff changeset
1368 && TREE_CODE (val) == SSA_NAME
kono
parents: 67
diff changeset
1369 && !may_propagate_copy (op, val)));
kono
parents: 67
diff changeset
1370 }
kono
parents: 67
diff changeset
1371
kono
parents: 67
diff changeset
1372 if (TREE_CODE (val) == SSA_NAME)
kono
parents: 67
diff changeset
1373 SET_USE (op_p, val);
kono
parents: 67
diff changeset
1374 else
kono
parents: 67
diff changeset
1375 SET_USE (op_p, unshare_expr (val));
kono
parents: 67
diff changeset
1376 }
kono
parents: 67
diff changeset
1377
kono
parents: 67
diff changeset
1378
kono
parents: 67
diff changeset
1379 /* Propagate the value VAL (assumed to be a constant or another SSA_NAME)
kono
parents: 67
diff changeset
1380 into the operand pointed to by OP_P.
kono
parents: 67
diff changeset
1381
kono
parents: 67
diff changeset
1382 Use this version for const/copy propagation as it will perform additional
kono
parents: 67
diff changeset
1383 checks to ensure validity of the const/copy propagation. */
kono
parents: 67
diff changeset
1384
kono
parents: 67
diff changeset
1385 void
kono
parents: 67
diff changeset
1386 propagate_value (use_operand_p op_p, tree val)
kono
parents: 67
diff changeset
1387 {
kono
parents: 67
diff changeset
1388 replace_exp_1 (op_p, val, true);
kono
parents: 67
diff changeset
1389 }
kono
parents: 67
diff changeset
1390
kono
parents: 67
diff changeset
1391 /* Replace *OP_P with value VAL (assumed to be a constant or another SSA_NAME).
kono
parents: 67
diff changeset
1392
kono
parents: 67
diff changeset
1393 Use this version when not const/copy propagating values. For example,
kono
parents: 67
diff changeset
1394 PRE uses this version when building expressions as they would appear
kono
parents: 67
diff changeset
1395 in specific blocks taking into account actions of PHI nodes.
kono
parents: 67
diff changeset
1396
kono
parents: 67
diff changeset
1397 The statement in which an expression has been replaced should be
kono
parents: 67
diff changeset
1398 folded using fold_stmt_inplace. */
kono
parents: 67
diff changeset
1399
kono
parents: 67
diff changeset
1400 void
kono
parents: 67
diff changeset
1401 replace_exp (use_operand_p op_p, tree val)
kono
parents: 67
diff changeset
1402 {
kono
parents: 67
diff changeset
1403 replace_exp_1 (op_p, val, false);
kono
parents: 67
diff changeset
1404 }
kono
parents: 67
diff changeset
1405
kono
parents: 67
diff changeset
1406
kono
parents: 67
diff changeset
1407 /* Propagate the value VAL (assumed to be a constant or another SSA_NAME)
kono
parents: 67
diff changeset
1408 into the tree pointed to by OP_P.
kono
parents: 67
diff changeset
1409
kono
parents: 67
diff changeset
1410 Use this version for const/copy propagation when SSA operands are not
kono
parents: 67
diff changeset
1411 available. It will perform the additional checks to ensure validity of
kono
parents: 67
diff changeset
1412 the const/copy propagation, but will not update any operand information.
kono
parents: 67
diff changeset
1413 Be sure to mark the stmt as modified. */
kono
parents: 67
diff changeset
1414
kono
parents: 67
diff changeset
1415 void
kono
parents: 67
diff changeset
1416 propagate_tree_value (tree *op_p, tree val)
kono
parents: 67
diff changeset
1417 {
kono
parents: 67
diff changeset
1418 if (TREE_CODE (val) == SSA_NAME)
kono
parents: 67
diff changeset
1419 *op_p = val;
kono
parents: 67
diff changeset
1420 else
kono
parents: 67
diff changeset
1421 *op_p = unshare_expr (val);
kono
parents: 67
diff changeset
1422 }
kono
parents: 67
diff changeset
1423
kono
parents: 67
diff changeset
1424
kono
parents: 67
diff changeset
1425 /* Like propagate_tree_value, but use as the operand to replace
kono
parents: 67
diff changeset
1426 the principal expression (typically, the RHS) contained in the
kono
parents: 67
diff changeset
1427 statement referenced by iterator GSI. Note that it is not
kono
parents: 67
diff changeset
1428 always possible to update the statement in-place, so a new
kono
parents: 67
diff changeset
1429 statement may be created to replace the original. */
kono
parents: 67
diff changeset
1430
kono
parents: 67
diff changeset
1431 void
kono
parents: 67
diff changeset
1432 propagate_tree_value_into_stmt (gimple_stmt_iterator *gsi, tree val)
kono
parents: 67
diff changeset
1433 {
kono
parents: 67
diff changeset
1434 gimple *stmt = gsi_stmt (*gsi);
kono
parents: 67
diff changeset
1435
kono
parents: 67
diff changeset
1436 if (is_gimple_assign (stmt))
kono
parents: 67
diff changeset
1437 {
kono
parents: 67
diff changeset
1438 tree expr = NULL_TREE;
kono
parents: 67
diff changeset
1439 if (gimple_assign_single_p (stmt))
kono
parents: 67
diff changeset
1440 expr = gimple_assign_rhs1 (stmt);
kono
parents: 67
diff changeset
1441 propagate_tree_value (&expr, val);
kono
parents: 67
diff changeset
1442 gimple_assign_set_rhs_from_tree (gsi, expr);
kono
parents: 67
diff changeset
1443 }
kono
parents: 67
diff changeset
1444 else if (gcond *cond_stmt = dyn_cast <gcond *> (stmt))
kono
parents: 67
diff changeset
1445 {
kono
parents: 67
diff changeset
1446 tree lhs = NULL_TREE;
kono
parents: 67
diff changeset
1447 tree rhs = build_zero_cst (TREE_TYPE (val));
kono
parents: 67
diff changeset
1448 propagate_tree_value (&lhs, val);
kono
parents: 67
diff changeset
1449 gimple_cond_set_code (cond_stmt, NE_EXPR);
kono
parents: 67
diff changeset
1450 gimple_cond_set_lhs (cond_stmt, lhs);
kono
parents: 67
diff changeset
1451 gimple_cond_set_rhs (cond_stmt, rhs);
kono
parents: 67
diff changeset
1452 }
kono
parents: 67
diff changeset
1453 else if (is_gimple_call (stmt)
kono
parents: 67
diff changeset
1454 && gimple_call_lhs (stmt) != NULL_TREE)
kono
parents: 67
diff changeset
1455 {
kono
parents: 67
diff changeset
1456 tree expr = NULL_TREE;
kono
parents: 67
diff changeset
1457 bool res;
kono
parents: 67
diff changeset
1458 propagate_tree_value (&expr, val);
kono
parents: 67
diff changeset
1459 res = update_call_from_tree (gsi, expr);
kono
parents: 67
diff changeset
1460 gcc_assert (res);
kono
parents: 67
diff changeset
1461 }
kono
parents: 67
diff changeset
1462 else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt))
kono
parents: 67
diff changeset
1463 propagate_tree_value (gimple_switch_index_ptr (swtch_stmt), val);
kono
parents: 67
diff changeset
1464 else
kono
parents: 67
diff changeset
1465 gcc_unreachable ();
kono
parents: 67
diff changeset
1466 }