Mercurial > hg > CbC > CbC_gcc
annotate gcc/tree-outof-ssa.c @ 157:dafe684d005c
...
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 25 May 2020 18:08:54 +0900 |
parents | 1830386684a0 |
children |
rev | line source |
---|---|
0 | 1 /* Convert a program in SSA form into Normal form. |
145 | 2 Copyright (C) 2004-2020 Free Software Foundation, Inc. |
0 | 3 Contributed by Andrew Macleod <amacleod@redhat.com> |
4 | |
5 This file is part of GCC. | |
6 | |
7 GCC is free software; you can redistribute it and/or modify | |
8 it under the terms of the GNU General Public License as published by | |
9 the Free Software Foundation; either version 3, or (at your option) | |
10 any later version. | |
11 | |
12 GCC is distributed in the hope that it will be useful, | |
13 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 GNU General Public License for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
18 along with GCC; see the file COPYING3. If not see | |
19 <http://www.gnu.org/licenses/>. */ | |
20 | |
21 #include "config.h" | |
22 #include "system.h" | |
23 #include "coretypes.h" | |
111 | 24 #include "backend.h" |
25 #include "rtl.h" | |
0 | 26 #include "tree.h" |
111 | 27 #include "gimple.h" |
28 #include "cfghooks.h" | |
29 #include "ssa.h" | |
131 | 30 #include "tree-ssa.h" |
111 | 31 #include "memmodel.h" |
32 #include "emit-rtl.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
|
33 #include "gimple-pretty-print.h" |
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
|
34 #include "diagnostic-core.h" |
131 | 35 #include "tree-dfa.h" |
111 | 36 #include "stor-layout.h" |
37 #include "cfgrtl.h" | |
38 #include "cfganal.h" | |
39 #include "tree-eh.h" | |
40 #include "gimple-iterator.h" | |
41 #include "tree-cfg.h" | |
42 #include "dumpfile.h" | |
43 #include "tree-ssa-live.h" | |
44 #include "tree-ssa-ter.h" | |
45 #include "tree-ssa-coalesce.h" | |
46 #include "tree-outof-ssa.h" | |
47 #include "dojump.h" | |
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
|
48 |
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
|
49 /* FIXME: A lot of code here deals with expanding to RTL. All that code |
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
|
50 should be in cfgexpand.c. */ |
111 | 51 #include "explow.h" |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
52 #include "expr.h" |
0 | 53 |
111 | 54 /* Return TRUE if expression STMT is suitable for replacement. */ |
0 | 55 |
111 | 56 bool |
57 ssa_is_replaceable_p (gimple *stmt) | |
58 { | |
59 use_operand_p use_p; | |
60 tree def; | |
61 gimple *use_stmt; | |
62 | |
63 /* Only consider modify stmts. */ | |
64 if (!is_gimple_assign (stmt)) | |
65 return false; | |
66 | |
67 /* If the statement may throw an exception, it cannot be replaced. */ | |
131 | 68 if (stmt_could_throw_p (cfun, stmt)) |
111 | 69 return false; |
70 | |
71 /* Punt if there is more than 1 def. */ | |
72 def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF); | |
73 if (!def) | |
74 return false; | |
75 | |
76 /* Only consider definitions which have a single use. */ | |
77 if (!single_imm_use (def, &use_p, &use_stmt)) | |
78 return false; | |
79 | |
80 /* Used in this block, but at the TOP of the block, not the end. */ | |
81 if (gimple_code (use_stmt) == GIMPLE_PHI) | |
82 return false; | |
83 | |
84 /* There must be no VDEFs. */ | |
85 if (gimple_vdef (stmt)) | |
86 return false; | |
87 | |
88 /* Float expressions must go through memory if float-store is on. */ | |
89 if (flag_float_store | |
90 && FLOAT_TYPE_P (gimple_expr_type (stmt))) | |
91 return false; | |
92 | |
93 /* An assignment with a register variable on the RHS is not | |
94 replaceable. */ | |
95 if (gimple_assign_rhs_code (stmt) == VAR_DECL | |
96 && DECL_HARD_REGISTER (gimple_assign_rhs1 (stmt))) | |
97 return false; | |
98 | |
99 /* No function calls can be replaced. */ | |
100 if (is_gimple_call (stmt)) | |
101 return false; | |
102 | |
103 /* Leave any stmt with volatile operands alone as well. */ | |
104 if (gimple_has_volatile_ops (stmt)) | |
105 return false; | |
106 | |
107 return true; | |
108 } | |
109 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
110 |
0 | 111 /* Used to hold all the components required to do SSA PHI elimination. |
112 The node and pred/succ list is a simple linear list of nodes and | |
113 edges represented as pairs of nodes. | |
114 | |
115 The predecessor and successor list: Nodes are entered in pairs, where | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
116 [0] ->PRED, [1]->SUCC. All the even indexes in the array represent |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
117 predecessors, all the odd elements are successors. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
118 |
0 | 119 Rationale: |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
120 When implemented as bitmaps, very large programs SSA->Normal times were |
0 | 121 being dominated by clearing the interference graph. |
122 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
123 Typically this list of edges is extremely small since it only includes |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
124 PHI results and uses from a single edge which have not coalesced with |
0 | 125 each other. This means that no virtual PHI nodes are included, and |
126 empirical evidence suggests that the number of edges rarely exceed | |
127 3, and in a bootstrap of GCC, the maximum size encountered was 7. | |
128 This also limits the number of possible nodes that are involved to | |
129 rarely more than 6, and in the bootstrap of gcc, the maximum number | |
130 of nodes encountered was 12. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
131 |
145 | 132 class elim_graph |
111 | 133 { |
145 | 134 public: |
111 | 135 elim_graph (var_map map); |
136 | |
0 | 137 /* Size of the elimination vectors. */ |
138 int size; | |
139 | |
140 /* List of nodes in the elimination graph. */ | |
111 | 141 auto_vec<int> nodes; |
0 | 142 |
143 /* The predecessor and successor edge list. */ | |
111 | 144 auto_vec<int> edge_list; |
0 | 145 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
146 /* Source locus on each edge */ |
145 | 147 auto_vec<location_t> edge_locus; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
148 |
0 | 149 /* Visited vector. */ |
111 | 150 auto_sbitmap visited; |
0 | 151 |
152 /* Stack for visited nodes. */ | |
111 | 153 auto_vec<int> stack; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
154 |
0 | 155 /* The variable partition map. */ |
156 var_map map; | |
157 | |
158 /* Edge being eliminated by this graph. */ | |
159 edge e; | |
160 | |
161 /* List of constant copies to emit. These are pushed on in pairs. */ | |
111 | 162 auto_vec<int> const_dests; |
163 auto_vec<tree> const_copies; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
164 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
165 /* Source locations for any constant copies. */ |
145 | 166 auto_vec<location_t> copy_locus; |
111 | 167 }; |
0 | 168 |
169 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
170 /* For an edge E find out a good source location to associate with |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
171 instructions inserted on edge E. If E has an implicit goto set, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
172 use its location. Otherwise search instructions in predecessors |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
173 of E for a location, and use that one. That makes sense because |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
174 we insert on edges for PHI nodes, and effects of PHIs happen on |
145 | 175 the end of the predecessor conceptually. An exception is made |
176 for EH edges because we don't want to drag the source location | |
177 of unrelated statements at the beginning of handlers; they would | |
178 be further reused for various EH constructs, which would damage | |
179 the coverage information. */ | |
0 | 180 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
181 static void |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
182 set_location_for_edge (edge e) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
183 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
184 if (e->goto_locus) |
145 | 185 set_curr_insn_location (e->goto_locus); |
186 else if (e->flags & EDGE_EH) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
187 { |
145 | 188 basic_block bb = e->dest; |
189 gimple_stmt_iterator gsi; | |
190 | |
191 do | |
192 { | |
193 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) | |
194 { | |
195 gimple *stmt = gsi_stmt (gsi); | |
196 if (is_gimple_debug (stmt)) | |
197 continue; | |
198 if (gimple_has_location (stmt) || gimple_block (stmt)) | |
199 { | |
200 set_curr_insn_location (gimple_location (stmt)); | |
201 return; | |
202 } | |
203 } | |
204 /* Nothing found in this basic block. Make a half-assed attempt | |
205 to continue with another block. */ | |
206 if (single_succ_p (bb)) | |
207 bb = single_succ (bb); | |
208 else | |
209 bb = e->dest; | |
210 } | |
211 while (bb != e->dest); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
212 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
213 else |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
214 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
215 basic_block bb = e->src; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
216 gimple_stmt_iterator gsi; |
0 | 217 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
218 do |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
219 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
220 for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
221 { |
111 | 222 gimple *stmt = gsi_stmt (gsi); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
223 if (is_gimple_debug (stmt)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
224 continue; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
225 if (gimple_has_location (stmt) || gimple_block (stmt)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
226 { |
111 | 227 set_curr_insn_location (gimple_location (stmt)); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
228 return; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
229 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
230 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
231 /* Nothing found in this basic block. Make a half-assed attempt |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
232 to continue with another block. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
233 if (single_pred_p (bb)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
234 bb = single_pred (bb); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
235 else |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
236 bb = e->src; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
237 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
238 while (bb != e->src); |
0 | 239 } |
240 } | |
241 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
242 /* Emit insns to copy SRC into DEST converting SRC if necessary. As |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
243 SRC/DEST might be BLKmode memory locations SIZEEXP is a tree from |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
244 which we deduce the size to copy in that case. */ |
0 | 245 |
111 | 246 static inline rtx_insn * |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
247 emit_partition_copy (rtx dest, rtx src, int unsignedsrcp, tree sizeexp) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
248 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
249 start_sequence (); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
250 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
251 if (GET_MODE (src) != VOIDmode && GET_MODE (src) != GET_MODE (dest)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
252 src = convert_to_mode (GET_MODE (dest), src, unsignedsrcp); |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
253 if (GET_MODE (src) == BLKmode) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
254 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
255 gcc_assert (GET_MODE (dest) == BLKmode); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
256 emit_block_move (dest, src, expr_size (sizeexp), BLOCK_OP_NORMAL); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
257 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
258 else |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
259 emit_move_insn (dest, src); |
111 | 260 do_pending_stack_adjust (); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
261 |
111 | 262 rtx_insn *seq = get_insns (); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
263 end_sequence (); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
264 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
265 return seq; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
266 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
267 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
268 /* Insert a copy instruction from partition SRC to DEST onto edge E. */ |
0 | 269 |
270 static void | |
145 | 271 insert_partition_copy_on_edge (edge e, int dest, int src, location_t locus) |
0 | 272 { |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
273 tree var; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
274 if (dump_file && (dump_flags & TDF_DETAILS)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
275 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
276 fprintf (dump_file, |
111 | 277 "Inserting a partition copy on edge BB%d->BB%d : " |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
278 "PART.%d = PART.%d", |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
279 e->src->index, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
280 e->dest->index, dest, src); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
281 fprintf (dump_file, "\n"); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
282 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
283 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
284 gcc_assert (SA.partition_to_pseudo[dest]); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
285 gcc_assert (SA.partition_to_pseudo[src]); |
0 | 286 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
287 set_location_for_edge (e); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
288 /* If a locus is provided, override the default. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
289 if (locus) |
111 | 290 set_curr_insn_location (locus); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
291 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
292 var = partition_to_var (SA.map, src); |
111 | 293 rtx_insn *seq = emit_partition_copy (copy_rtx (SA.partition_to_pseudo[dest]), |
294 copy_rtx (SA.partition_to_pseudo[src]), | |
295 TYPE_UNSIGNED (TREE_TYPE (var)), | |
296 var); | |
0 | 297 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
298 insert_insn_on_edge (seq, e); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
299 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
300 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
301 /* Insert a copy instruction from expression SRC to partition DEST |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
302 onto edge E. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
303 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
304 static void |
145 | 305 insert_value_copy_on_edge (edge e, int dest, tree src, location_t locus) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
306 { |
111 | 307 rtx dest_rtx, seq, x; |
308 machine_mode dest_mode, src_mode; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
309 int unsignedp; |
0 | 310 |
311 if (dump_file && (dump_flags & TDF_DETAILS)) | |
312 { | |
313 fprintf (dump_file, | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
314 "Inserting a value copy on edge BB%d->BB%d : PART.%d = ", |
0 | 315 e->src->index, |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
316 e->dest->index, dest); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
317 print_generic_expr (dump_file, src, TDF_SLIM); |
0 | 318 fprintf (dump_file, "\n"); |
319 } | |
320 | |
111 | 321 dest_rtx = copy_rtx (SA.partition_to_pseudo[dest]); |
322 gcc_assert (dest_rtx); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
323 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
324 set_location_for_edge (e); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
325 /* If a locus is provided, override the default. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
326 if (locus) |
111 | 327 set_curr_insn_location (locus); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
328 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
329 start_sequence (); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
330 |
111 | 331 tree name = partition_to_var (SA.map, dest); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
332 src_mode = TYPE_MODE (TREE_TYPE (src)); |
111 | 333 dest_mode = GET_MODE (dest_rtx); |
334 gcc_assert (src_mode == TYPE_MODE (TREE_TYPE (name))); | |
335 gcc_assert (!REG_P (dest_rtx) | |
336 || dest_mode == promote_ssa_mode (name, &unsignedp)); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
337 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
338 if (src_mode != dest_mode) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
339 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
340 x = expand_expr (src, NULL, src_mode, EXPAND_NORMAL); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
341 x = convert_modes (dest_mode, src_mode, x, unsignedp); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
342 } |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
343 else if (src_mode == BLKmode) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
344 { |
111 | 345 x = dest_rtx; |
346 store_expr (src, x, 0, false, false); | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
347 } |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
348 else |
111 | 349 x = expand_expr (src, dest_rtx, dest_mode, EXPAND_NORMAL); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
350 |
111 | 351 if (x != dest_rtx) |
352 emit_move_insn (dest_rtx, x); | |
353 do_pending_stack_adjust (); | |
354 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
355 seq = get_insns (); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
356 end_sequence (); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
357 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
358 insert_insn_on_edge (seq, e); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
359 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
360 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
361 /* Insert a copy instruction from RTL expression SRC to partition DEST |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
362 onto edge E. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
363 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
364 static void |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
365 insert_rtx_to_part_on_edge (edge e, int dest, rtx src, int unsignedsrcp, |
145 | 366 location_t locus) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
367 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
368 if (dump_file && (dump_flags & TDF_DETAILS)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
369 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
370 fprintf (dump_file, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
371 "Inserting a temp copy on edge BB%d->BB%d : PART.%d = ", |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
372 e->src->index, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
373 e->dest->index, dest); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
374 print_simple_rtl (dump_file, src); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
375 fprintf (dump_file, "\n"); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
376 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
377 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
378 gcc_assert (SA.partition_to_pseudo[dest]); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
379 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
380 set_location_for_edge (e); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
381 /* If a locus is provided, override the default. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
382 if (locus) |
111 | 383 set_curr_insn_location (locus); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
384 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
385 /* We give the destination as sizeexp in case src/dest are BLKmode |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
386 mems. Usually we give the source. As we result from SSA names |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
387 the left and right size should be the same (and no WITH_SIZE_EXPR |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
388 involved), so it doesn't matter. */ |
111 | 389 rtx_insn *seq = emit_partition_copy (copy_rtx (SA.partition_to_pseudo[dest]), |
390 src, unsignedsrcp, | |
391 partition_to_var (SA.map, dest)); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
392 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
393 insert_insn_on_edge (seq, e); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
394 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
395 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
396 /* Insert a copy instruction from partition SRC to RTL lvalue DEST |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
397 onto edge E. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
398 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
399 static void |
145 | 400 insert_part_to_rtx_on_edge (edge e, rtx dest, int src, location_t locus) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
401 { |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
402 tree var; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
403 if (dump_file && (dump_flags & TDF_DETAILS)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
404 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
405 fprintf (dump_file, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
406 "Inserting a temp copy on edge BB%d->BB%d : ", |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
407 e->src->index, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
408 e->dest->index); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
409 print_simple_rtl (dump_file, dest); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
410 fprintf (dump_file, "= PART.%d\n", src); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
411 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
412 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
413 gcc_assert (SA.partition_to_pseudo[src]); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
414 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
415 set_location_for_edge (e); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
416 /* If a locus is provided, override the default. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
417 if (locus) |
111 | 418 set_curr_insn_location (locus); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
419 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
420 var = partition_to_var (SA.map, src); |
111 | 421 rtx_insn *seq = emit_partition_copy (dest, |
422 copy_rtx (SA.partition_to_pseudo[src]), | |
423 TYPE_UNSIGNED (TREE_TYPE (var)), | |
424 var); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
425 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
426 insert_insn_on_edge (seq, e); |
0 | 427 } |
428 | |
429 | |
111 | 430 /* Create an elimination graph for map. */ |
0 | 431 |
111 | 432 elim_graph::elim_graph (var_map map) : |
433 nodes (30), edge_list (20), edge_locus (10), visited (map->num_partitions), | |
434 stack (30), map (map), const_dests (20), const_copies (20), copy_locus (10) | |
435 { | |
0 | 436 } |
437 | |
438 | |
439 /* Empty elimination graph G. */ | |
440 | |
441 static inline void | |
111 | 442 clear_elim_graph (elim_graph *g) |
0 | 443 { |
111 | 444 g->nodes.truncate (0); |
445 g->edge_list.truncate (0); | |
446 g->edge_locus.truncate (0); | |
0 | 447 } |
448 | |
449 | |
450 /* Return the number of nodes in graph G. */ | |
451 | |
452 static inline int | |
111 | 453 elim_graph_size (elim_graph *g) |
0 | 454 { |
111 | 455 return g->nodes.length (); |
0 | 456 } |
457 | |
458 | |
459 /* Add NODE to graph G, if it doesn't exist already. */ | |
460 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
461 static inline void |
111 | 462 elim_graph_add_node (elim_graph *g, int node) |
0 | 463 { |
464 int x; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
465 int t; |
0 | 466 |
111 | 467 FOR_EACH_VEC_ELT (g->nodes, x, t) |
0 | 468 if (t == node) |
469 return; | |
111 | 470 g->nodes.safe_push (node); |
0 | 471 } |
472 | |
473 | |
474 /* Add the edge PRED->SUCC to graph G. */ | |
475 | |
476 static inline void | |
145 | 477 elim_graph_add_edge (elim_graph *g, int pred, int succ, location_t locus) |
0 | 478 { |
111 | 479 g->edge_list.safe_push (pred); |
480 g->edge_list.safe_push (succ); | |
481 g->edge_locus.safe_push (locus); | |
0 | 482 } |
483 | |
484 | |
485 /* Remove an edge from graph G for which NODE is the predecessor, and | |
486 return the successor node. -1 is returned if there is no such edge. */ | |
487 | |
488 static inline int | |
145 | 489 elim_graph_remove_succ_edge (elim_graph *g, int node, location_t *locus) |
0 | 490 { |
491 int y; | |
492 unsigned x; | |
111 | 493 for (x = 0; x < g->edge_list.length (); x += 2) |
494 if (g->edge_list[x] == node) | |
0 | 495 { |
111 | 496 g->edge_list[x] = -1; |
497 y = g->edge_list[x + 1]; | |
498 g->edge_list[x + 1] = -1; | |
499 *locus = g->edge_locus[x / 2]; | |
500 g->edge_locus[x / 2] = UNKNOWN_LOCATION; | |
0 | 501 return y; |
502 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
503 *locus = UNKNOWN_LOCATION; |
0 | 504 return -1; |
505 } | |
506 | |
507 | |
508 /* Find all the nodes in GRAPH which are successors to NODE in the | |
509 edge list. VAR will hold the partition number found. CODE is the | |
510 code fragment executed for every node found. */ | |
511 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
512 #define FOR_EACH_ELIM_GRAPH_SUCC(GRAPH, NODE, VAR, LOCUS, CODE) \ |
0 | 513 do { \ |
514 unsigned x_; \ | |
515 int y_; \ | |
111 | 516 for (x_ = 0; x_ < (GRAPH)->edge_list.length (); x_ += 2) \ |
0 | 517 { \ |
111 | 518 y_ = (GRAPH)->edge_list[x_]; \ |
0 | 519 if (y_ != (NODE)) \ |
520 continue; \ | |
111 | 521 (void) ((VAR) = (GRAPH)->edge_list[x_ + 1]); \ |
522 (void) ((LOCUS) = (GRAPH)->edge_locus[x_ / 2]); \ | |
0 | 523 CODE; \ |
524 } \ | |
525 } while (0) | |
526 | |
527 | |
528 /* Find all the nodes which are predecessors of NODE in the edge list for | |
529 GRAPH. VAR will hold the partition number found. CODE is the | |
530 code fragment executed for every node found. */ | |
531 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
532 #define FOR_EACH_ELIM_GRAPH_PRED(GRAPH, NODE, VAR, LOCUS, CODE) \ |
0 | 533 do { \ |
534 unsigned x_; \ | |
535 int y_; \ | |
111 | 536 for (x_ = 0; x_ < (GRAPH)->edge_list.length (); x_ += 2) \ |
0 | 537 { \ |
111 | 538 y_ = (GRAPH)->edge_list[x_ + 1]; \ |
0 | 539 if (y_ != (NODE)) \ |
540 continue; \ | |
111 | 541 (void) ((VAR) = (GRAPH)->edge_list[x_]); \ |
542 (void) ((LOCUS) = (GRAPH)->edge_locus[x_ / 2]); \ | |
0 | 543 CODE; \ |
544 } \ | |
545 } while (0) | |
546 | |
547 | |
548 /* Add T to elimination graph G. */ | |
549 | |
550 static inline void | |
111 | 551 eliminate_name (elim_graph *g, int T) |
0 | 552 { |
553 elim_graph_add_node (g, T); | |
554 } | |
555 | |
111 | 556 /* Return true if this phi argument T should have a copy queued when using |
557 var_map MAP. PHI nodes should contain only ssa_names and invariants. A | |
558 test for ssa_name is definitely simpler, but don't let invalid contents | |
559 slip through in the meantime. */ | |
560 | |
561 static inline bool | |
562 queue_phi_copy_p (var_map map, tree t) | |
563 { | |
564 if (TREE_CODE (t) == SSA_NAME) | |
565 { | |
566 if (var_to_partition (map, t) == NO_PARTITION) | |
567 return true; | |
568 return false; | |
569 } | |
570 gcc_checking_assert (is_gimple_min_invariant (t)); | |
571 return true; | |
572 } | |
0 | 573 |
574 /* Build elimination graph G for basic block BB on incoming PHI edge | |
575 G->e. */ | |
576 | |
577 static void | |
111 | 578 eliminate_build (elim_graph *g) |
0 | 579 { |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
580 tree Ti; |
0 | 581 int p0, pi; |
111 | 582 gphi_iterator gsi; |
0 | 583 |
584 clear_elim_graph (g); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
585 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
586 for (gsi = gsi_start_phis (g->e->dest); !gsi_end_p (gsi); gsi_next (&gsi)) |
0 | 587 { |
111 | 588 gphi *phi = gsi.phi (); |
145 | 589 location_t locus; |
0 | 590 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
591 p0 = var_to_partition (g->map, gimple_phi_result (phi)); |
0 | 592 /* Ignore results which are not in partitions. */ |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
593 if (p0 == NO_PARTITION) |
0 | 594 continue; |
595 | |
596 Ti = PHI_ARG_DEF (phi, g->e->dest_idx); | |
145 | 597 /* See set_location_for_edge for the rationale. */ |
598 if (g->e->flags & EDGE_EH) | |
599 locus = UNKNOWN_LOCATION; | |
600 else | |
601 locus = gimple_phi_arg_location_from_edge (phi, g->e); | |
0 | 602 |
603 /* If this argument is a constant, or a SSA_NAME which is being | |
604 left in SSA form, just queue a copy to be emitted on this | |
605 edge. */ | |
111 | 606 if (queue_phi_copy_p (g->map, Ti)) |
0 | 607 { |
608 /* Save constant copies until all other copies have been emitted | |
609 on this edge. */ | |
111 | 610 g->const_dests.safe_push (p0); |
611 g->const_copies.safe_push (Ti); | |
612 g->copy_locus.safe_push (locus); | |
0 | 613 } |
614 else | |
615 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
616 pi = var_to_partition (g->map, Ti); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
617 if (p0 != pi) |
0 | 618 { |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
619 eliminate_name (g, p0); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
620 eliminate_name (g, pi); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
621 elim_graph_add_edge (g, p0, pi, locus); |
0 | 622 } |
623 } | |
624 } | |
625 } | |
626 | |
627 | |
628 /* Push successors of T onto the elimination stack for G. */ | |
629 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
630 static void |
111 | 631 elim_forward (elim_graph *g, int T) |
0 | 632 { |
633 int S; | |
145 | 634 location_t locus; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
635 |
111 | 636 bitmap_set_bit (g->visited, T); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
637 FOR_EACH_ELIM_GRAPH_SUCC (g, T, S, locus, |
0 | 638 { |
111 | 639 if (!bitmap_bit_p (g->visited, S)) |
0 | 640 elim_forward (g, S); |
641 }); | |
111 | 642 g->stack.safe_push (T); |
0 | 643 } |
644 | |
645 | |
646 /* Return 1 if there unvisited predecessors of T in graph G. */ | |
647 | |
648 static int | |
111 | 649 elim_unvisited_predecessor (elim_graph *g, int T) |
0 | 650 { |
651 int P; | |
145 | 652 location_t locus; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
653 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
654 FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus, |
0 | 655 { |
111 | 656 if (!bitmap_bit_p (g->visited, P)) |
0 | 657 return 1; |
658 }); | |
659 return 0; | |
660 } | |
661 | |
662 /* Process predecessors first, and insert a copy. */ | |
663 | |
664 static void | |
111 | 665 elim_backward (elim_graph *g, int T) |
0 | 666 { |
667 int P; | |
145 | 668 location_t locus; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
669 |
111 | 670 bitmap_set_bit (g->visited, T); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
671 FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus, |
0 | 672 { |
111 | 673 if (!bitmap_bit_p (g->visited, P)) |
0 | 674 { |
675 elim_backward (g, P); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
676 insert_partition_copy_on_edge (g->e, P, T, locus); |
0 | 677 } |
678 }); | |
679 } | |
680 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
681 /* Allocate a new pseudo register usable for storing values sitting |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
682 in NAME (a decl or SSA name), i.e. with matching mode and attributes. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
683 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
684 static rtx |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
685 get_temp_reg (tree name) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
686 { |
111 | 687 tree type = TREE_TYPE (name); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
688 int unsignedp; |
111 | 689 machine_mode reg_mode = promote_ssa_mode (name, &unsignedp); |
145 | 690 if (reg_mode == BLKmode) |
691 return assign_temp (type, 0, 0); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
692 rtx x = gen_reg_rtx (reg_mode); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
693 if (POINTER_TYPE_P (type)) |
111 | 694 mark_reg_pointer (x, TYPE_ALIGN (TREE_TYPE (type))); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
695 return x; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
696 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
697 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
698 /* Insert required copies for T in graph G. Check for a strongly connected |
0 | 699 region, and create a temporary to break the cycle if one is found. */ |
700 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
701 static void |
111 | 702 elim_create (elim_graph *g, int T) |
0 | 703 { |
704 int P, S; | |
145 | 705 location_t locus; |
0 | 706 |
707 if (elim_unvisited_predecessor (g, T)) | |
708 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
709 tree var = partition_to_var (g->map, T); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
710 rtx U = get_temp_reg (var); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
711 int unsignedsrcp = TYPE_UNSIGNED (TREE_TYPE (var)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
712 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
713 insert_part_to_rtx_on_edge (g->e, U, T, UNKNOWN_LOCATION); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
714 FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus, |
0 | 715 { |
111 | 716 if (!bitmap_bit_p (g->visited, P)) |
0 | 717 { |
718 elim_backward (g, P); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
719 insert_rtx_to_part_on_edge (g->e, P, U, unsignedsrcp, locus); |
0 | 720 } |
721 }); | |
722 } | |
723 else | |
724 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
725 S = elim_graph_remove_succ_edge (g, T, &locus); |
0 | 726 if (S != -1) |
727 { | |
111 | 728 bitmap_set_bit (g->visited, T); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
729 insert_partition_copy_on_edge (g->e, T, S, locus); |
0 | 730 } |
731 } | |
732 } | |
733 | |
734 | |
735 /* Eliminate all the phi nodes on edge E in graph G. */ | |
736 | |
737 static void | |
111 | 738 eliminate_phi (edge e, elim_graph *g) |
0 | 739 { |
740 int x; | |
741 | |
111 | 742 gcc_assert (g->const_copies.length () == 0); |
743 gcc_assert (g->copy_locus.length () == 0); | |
0 | 744 |
745 /* Abnormal edges already have everything coalesced. */ | |
746 if (e->flags & EDGE_ABNORMAL) | |
747 return; | |
748 | |
749 g->e = e; | |
750 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
751 eliminate_build (g); |
0 | 752 |
753 if (elim_graph_size (g) != 0) | |
754 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
755 int part; |
0 | 756 |
111 | 757 bitmap_clear (g->visited); |
758 g->stack.truncate (0); | |
0 | 759 |
111 | 760 FOR_EACH_VEC_ELT (g->nodes, x, part) |
0 | 761 { |
111 | 762 if (!bitmap_bit_p (g->visited, part)) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
763 elim_forward (g, part); |
0 | 764 } |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
765 |
111 | 766 bitmap_clear (g->visited); |
767 while (g->stack.length () > 0) | |
0 | 768 { |
111 | 769 x = g->stack.pop (); |
770 if (!bitmap_bit_p (g->visited, x)) | |
0 | 771 elim_create (g, x); |
772 } | |
773 } | |
774 | |
775 /* If there are any pending constant copies, issue them now. */ | |
111 | 776 while (g->const_copies.length () > 0) |
0 | 777 { |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
778 int dest; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
779 tree src; |
145 | 780 location_t locus; |
0 | 781 |
111 | 782 src = g->const_copies.pop (); |
783 dest = g->const_dests.pop (); | |
784 locus = g->copy_locus.pop (); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
785 insert_value_copy_on_edge (e, dest, src, locus); |
0 | 786 } |
787 } | |
788 | |
789 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
790 /* Remove each argument from PHI. If an arg was the last use of an SSA_NAME, |
0 | 791 check to see if this allows another PHI node to be removed. */ |
792 | |
793 static void | |
111 | 794 remove_gimple_phi_args (gphi *phi) |
0 | 795 { |
796 use_operand_p arg_p; | |
797 ssa_op_iter iter; | |
798 | |
799 if (dump_file && (dump_flags & TDF_DETAILS)) | |
800 { | |
801 fprintf (dump_file, "Removing Dead PHI definition: "); | |
802 print_gimple_stmt (dump_file, phi, 0, TDF_SLIM); | |
803 } | |
804 | |
805 FOR_EACH_PHI_ARG (arg_p, phi, iter, SSA_OP_USE) | |
806 { | |
807 tree arg = USE_FROM_PTR (arg_p); | |
808 if (TREE_CODE (arg) == SSA_NAME) | |
809 { | |
810 /* Remove the reference to the existing argument. */ | |
811 SET_USE (arg_p, NULL_TREE); | |
812 if (has_zero_uses (arg)) | |
813 { | |
111 | 814 gimple *stmt; |
0 | 815 gimple_stmt_iterator gsi; |
816 | |
817 stmt = SSA_NAME_DEF_STMT (arg); | |
818 | |
819 /* Also remove the def if it is a PHI node. */ | |
820 if (gimple_code (stmt) == GIMPLE_PHI) | |
821 { | |
111 | 822 remove_gimple_phi_args (as_a <gphi *> (stmt)); |
0 | 823 gsi = gsi_for_stmt (stmt); |
824 remove_phi_node (&gsi, true); | |
825 } | |
826 | |
827 } | |
828 } | |
829 } | |
830 } | |
831 | |
832 /* Remove any PHI node which is a virtual PHI, or a PHI with no uses. */ | |
833 | |
834 static void | |
835 eliminate_useless_phis (void) | |
836 { | |
837 basic_block bb; | |
111 | 838 gphi_iterator gsi; |
0 | 839 tree result; |
840 | |
111 | 841 FOR_EACH_BB_FN (bb, cfun) |
0 | 842 { |
843 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); ) | |
844 { | |
111 | 845 gphi *phi = gsi.phi (); |
0 | 846 result = gimple_phi_result (phi); |
111 | 847 if (virtual_operand_p (result)) |
145 | 848 remove_phi_node (&gsi, true); |
0 | 849 else |
850 { | |
851 /* Also remove real PHIs with no uses. */ | |
852 if (has_zero_uses (result)) | |
853 { | |
854 remove_gimple_phi_args (phi); | |
855 remove_phi_node (&gsi, true); | |
856 } | |
857 else | |
858 gsi_next (&gsi); | |
859 } | |
860 } | |
861 } | |
862 } | |
863 | |
864 | |
865 /* This function will rewrite the current program using the variable mapping | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
866 found in MAP. If the replacement vector VALUES is provided, any |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
867 occurrences of partitions with non-null entries in the vector will be |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
868 replaced with the expression in the vector instead of its mapped |
0 | 869 variable. */ |
870 | |
871 static void | |
111 | 872 rewrite_trees (var_map map) |
0 | 873 { |
111 | 874 if (!flag_checking) |
875 return; | |
876 | |
0 | 877 basic_block bb; |
878 /* Search for PHIs where the destination has no partition, but one | |
879 or more arguments has a partition. This should not happen and can | |
880 create incorrect code. */ | |
111 | 881 FOR_EACH_BB_FN (bb, cfun) |
0 | 882 { |
111 | 883 gphi_iterator gsi; |
0 | 884 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) |
885 { | |
111 | 886 gphi *phi = gsi.phi (); |
0 | 887 tree T0 = var_to_partition_to_var (map, gimple_phi_result (phi)); |
888 if (T0 == NULL_TREE) | |
889 { | |
890 size_t i; | |
891 for (i = 0; i < gimple_phi_num_args (phi); i++) | |
892 { | |
893 tree arg = PHI_ARG_DEF (phi, i); | |
894 | |
895 if (TREE_CODE (arg) == SSA_NAME | |
896 && var_to_partition (map, arg) != NO_PARTITION) | |
897 { | |
898 fprintf (stderr, "Argument of PHI is in a partition :("); | |
899 print_generic_expr (stderr, arg, TDF_SLIM); | |
900 fprintf (stderr, "), but the result is not :"); | |
901 print_gimple_stmt (stderr, phi, 0, TDF_SLIM); | |
902 internal_error ("SSA corruption"); | |
903 } | |
904 } | |
905 } | |
906 } | |
907 } | |
908 } | |
909 | |
131 | 910 /* Create a default def for VAR. */ |
911 | |
912 static void | |
913 create_default_def (tree var, void *arg ATTRIBUTE_UNUSED) | |
914 { | |
915 if (!is_gimple_reg (var)) | |
916 return; | |
917 | |
918 tree ssa = get_or_create_ssa_default_def (cfun, var); | |
919 gcc_assert (ssa); | |
920 } | |
921 | |
922 /* Call CALLBACK for all PARM_DECLs and RESULT_DECLs for which | |
923 assign_parms may ask for a default partition. */ | |
924 | |
925 static void | |
926 for_all_parms (void (*callback)(tree var, void *arg), void *arg) | |
927 { | |
928 for (tree var = DECL_ARGUMENTS (current_function_decl); var; | |
929 var = DECL_CHAIN (var)) | |
930 callback (var, arg); | |
931 if (!VOID_TYPE_P (TREE_TYPE (DECL_RESULT (current_function_decl)))) | |
932 callback (DECL_RESULT (current_function_decl), arg); | |
933 if (cfun->static_chain_decl) | |
934 callback (cfun->static_chain_decl, arg); | |
935 } | |
936 | |
937 /* We need to pass two arguments to set_parm_default_def_partition, | |
938 but for_all_parms only supports one. Use a pair. */ | |
939 | |
940 typedef std::pair<var_map, bitmap> parm_default_def_partition_arg; | |
941 | |
942 /* Set in ARG's PARTS bitmap the bit corresponding to the partition in | |
943 ARG's MAP containing VAR's default def. */ | |
944 | |
945 static void | |
946 set_parm_default_def_partition (tree var, void *arg_) | |
947 { | |
948 parm_default_def_partition_arg *arg = (parm_default_def_partition_arg *)arg_; | |
949 var_map map = arg->first; | |
950 bitmap parts = arg->second; | |
951 | |
952 if (!is_gimple_reg (var)) | |
953 return; | |
954 | |
955 tree ssa = ssa_default_def (cfun, var); | |
956 gcc_assert (ssa); | |
957 | |
958 int version = var_to_partition (map, ssa); | |
959 gcc_assert (version != NO_PARTITION); | |
960 | |
961 bool changed = bitmap_set_bit (parts, version); | |
962 gcc_assert (changed); | |
963 } | |
964 | |
965 /* Allocate and return a bitmap that has a bit set for each partition | |
966 that contains a default def for a parameter. */ | |
967 | |
968 static bitmap | |
969 get_parm_default_def_partitions (var_map map) | |
970 { | |
971 bitmap parm_default_def_parts = BITMAP_ALLOC (NULL); | |
972 | |
973 parm_default_def_partition_arg | |
974 arg = std::make_pair (map, parm_default_def_parts); | |
975 | |
976 for_all_parms (set_parm_default_def_partition, &arg); | |
977 | |
978 return parm_default_def_parts; | |
979 } | |
980 | |
981 /* Allocate and return a bitmap that has a bit set for each partition | |
982 that contains an undefined value. */ | |
983 | |
984 static bitmap | |
985 get_undefined_value_partitions (var_map map) | |
986 { | |
987 bitmap undefined_value_parts = BITMAP_ALLOC (NULL); | |
988 | |
989 for (unsigned int i = 1; i < num_ssa_names; i++) | |
990 { | |
991 tree var = ssa_name (i); | |
992 if (var | |
993 && !virtual_operand_p (var) | |
994 && !has_zero_uses (var) | |
995 && ssa_undefined_value_p (var)) | |
996 { | |
997 const int p = var_to_partition (map, var); | |
998 if (p != NO_PARTITION) | |
999 bitmap_set_bit (undefined_value_parts, p); | |
1000 } | |
1001 } | |
1002 | |
1003 return undefined_value_parts; | |
1004 } | |
1005 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1006 /* Given the out-of-ssa info object SA (with prepared partitions) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1007 eliminate all phi nodes in all basic blocks. Afterwards no |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1008 basic block will have phi nodes anymore and there are possibly |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1009 some RTL instructions inserted on edges. */ |
0 | 1010 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1011 void |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1012 expand_phi_nodes (struct ssaexpand *sa) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1013 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1014 basic_block bb; |
111 | 1015 elim_graph g (sa->map); |
0 | 1016 |
111 | 1017 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb, |
1018 EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1019 if (!gimple_seq_empty_p (phi_nodes (bb))) |
0 | 1020 { |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1021 edge e; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1022 edge_iterator ei; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1023 FOR_EACH_EDGE (e, ei, bb->preds) |
111 | 1024 eliminate_phi (e, &g); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1025 set_phi_nodes (bb, NULL); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1026 /* We can't redirect EH edges in RTL land, so we need to do this |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1027 here. Redirection happens only when splitting is necessary, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1028 which it is only for critical edges, normally. For EH edges |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1029 it might also be necessary when the successor has more than |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1030 one predecessor. In that case the edge is either required to |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1031 be fallthru (which EH edges aren't), or the predecessor needs |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1032 to end with a jump (which again, isn't the case with EH edges). |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1033 Hence, split all EH edges on which we inserted instructions |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1034 and whose successor has multiple predecessors. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1035 for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei)); ) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1036 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1037 if (e->insns.r && (e->flags & EDGE_EH) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1038 && !single_pred_p (e->dest)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1039 { |
111 | 1040 rtx_insn *insns = e->insns.r; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1041 basic_block bb; |
111 | 1042 e->insns.r = NULL; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1043 bb = split_edge (e); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1044 single_pred_edge (bb)->insns.r = insns; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1045 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1046 else |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1047 ei_next (&ei); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1048 } |
0 | 1049 } |
1050 } | |
1051 | |
1052 | |
1053 /* Remove the ssa-names in the current function and translate them into normal | |
1054 compiler variables. PERFORM_TER is true if Temporary Expression Replacement | |
1055 should also be used. */ | |
1056 | |
1057 static void | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1058 remove_ssa_form (bool perform_ter, struct ssaexpand *sa) |
0 | 1059 { |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1060 bitmap values = NULL; |
0 | 1061 var_map map; |
1062 | |
131 | 1063 for_all_parms (create_default_def, NULL); |
1064 map = init_var_map (num_ssa_names); | |
1065 coalesce_ssa_name (map); | |
0 | 1066 |
1067 /* Return to viewing the variable list as just all reference variables after | |
1068 coalescing has been performed. */ | |
111 | 1069 partition_view_normal (map); |
0 | 1070 |
1071 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1072 { | |
1073 fprintf (dump_file, "After Coalescing:\n"); | |
1074 dump_var_map (dump_file, map); | |
1075 } | |
1076 | |
1077 if (perform_ter) | |
1078 { | |
1079 values = find_replaceable_exprs (map); | |
1080 if (values && dump_file && (dump_flags & TDF_DETAILS)) | |
1081 dump_replaceable_exprs (dump_file, values); | |
1082 } | |
1083 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1084 rewrite_trees (map); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1085 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1086 sa->map = map; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1087 sa->values = values; |
111 | 1088 sa->partitions_for_parm_default_defs = get_parm_default_def_partitions (map); |
1089 sa->partitions_for_undefined_values = get_undefined_value_partitions (map); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1090 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1091 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1092 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1093 /* If not already done so for basic block BB, assign increasing uids |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1094 to each of its instructions. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1095 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1096 static void |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1097 maybe_renumber_stmts_bb (basic_block bb) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1098 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1099 unsigned i = 0; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1100 gimple_stmt_iterator gsi; |
0 | 1101 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1102 if (!bb->aux) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1103 return; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1104 bb->aux = NULL; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1105 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) |
0 | 1106 { |
111 | 1107 gimple *stmt = gsi_stmt (gsi); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1108 gimple_set_uid (stmt, i); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1109 i++; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1110 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1111 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1112 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1113 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1114 /* Return true if we can determine that the SSA_NAMEs RESULT (a result |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1115 of a PHI node) and ARG (one of its arguments) conflict. Return false |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1116 otherwise, also when we simply aren't sure. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1117 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1118 static bool |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1119 trivially_conflicts_p (basic_block bb, tree result, tree arg) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1120 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1121 use_operand_p use; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1122 imm_use_iterator imm_iter; |
111 | 1123 gimple *defa = SSA_NAME_DEF_STMT (arg); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1124 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1125 /* If ARG isn't defined in the same block it's too complicated for |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1126 our little mind. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1127 if (gimple_bb (defa) != bb) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1128 return false; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1129 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1130 FOR_EACH_IMM_USE_FAST (use, imm_iter, result) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1131 { |
111 | 1132 gimple *use_stmt = USE_STMT (use); |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1133 if (is_gimple_debug (use_stmt)) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1134 continue; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1135 /* Now, if there's a use of RESULT that lies outside this basic block, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1136 then there surely is a conflict with ARG. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1137 if (gimple_bb (use_stmt) != bb) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1138 return true; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1139 if (gimple_code (use_stmt) == GIMPLE_PHI) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1140 continue; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1141 /* The use now is in a real stmt of BB, so if ARG was defined |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1142 in a PHI node (like RESULT) both conflict. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1143 if (gimple_code (defa) == GIMPLE_PHI) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1144 return true; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1145 maybe_renumber_stmts_bb (bb); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1146 /* If the use of RESULT occurs after the definition of ARG, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1147 the two conflict too. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1148 if (gimple_uid (defa) < gimple_uid (use_stmt)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1149 return true; |
0 | 1150 } |
1151 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1152 return false; |
0 | 1153 } |
1154 | |
1155 | |
1156 /* Search every PHI node for arguments associated with backedges which | |
1157 we can trivially determine will need a copy (the argument is either | |
1158 not an SSA_NAME or the argument has a different underlying variable | |
1159 than the PHI result). | |
1160 | |
1161 Insert a copy from the PHI argument to a new destination at the | |
1162 end of the block with the backedge to the top of the loop. Update | |
1163 the PHI argument to reference this new destination. */ | |
1164 | |
1165 static void | |
1166 insert_backedge_copies (void) | |
1167 { | |
1168 basic_block bb; | |
111 | 1169 gphi_iterator gsi; |
0 | 1170 |
111 | 1171 mark_dfs_back_edges (); |
1172 | |
1173 FOR_EACH_BB_FN (bb, cfun) | |
0 | 1174 { |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1175 /* Mark block as possibly needing calculation of UIDs. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1176 bb->aux = &bb->aux; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1177 |
0 | 1178 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) |
1179 { | |
111 | 1180 gphi *phi = gsi.phi (); |
0 | 1181 tree result = gimple_phi_result (phi); |
1182 size_t i; | |
1183 | |
111 | 1184 if (virtual_operand_p (result)) |
0 | 1185 continue; |
1186 | |
1187 for (i = 0; i < gimple_phi_num_args (phi); i++) | |
1188 { | |
1189 tree arg = gimple_phi_arg_def (phi, i); | |
1190 edge e = gimple_phi_arg_edge (phi, i); | |
145 | 1191 /* We are only interested in copies emitted on critical |
1192 backedges. */ | |
1193 if (!(e->flags & EDGE_DFS_BACK) | |
1194 || !EDGE_CRITICAL_P (e)) | |
1195 continue; | |
0 | 1196 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1197 /* If the argument is not an SSA_NAME, then we will need a |
145 | 1198 constant initialization. If the argument is an SSA_NAME then |
1199 a copy statement may be needed. First handle the case | |
1200 where we cannot insert before the argument definition. */ | |
1201 if (TREE_CODE (arg) != SSA_NAME | |
1202 || (gimple_code (SSA_NAME_DEF_STMT (arg)) == GIMPLE_PHI | |
1203 && trivially_conflicts_p (bb, result, arg))) | |
0 | 1204 { |
1205 tree name; | |
111 | 1206 gassign *stmt; |
1207 gimple *last = NULL; | |
0 | 1208 gimple_stmt_iterator gsi2; |
1209 | |
1210 gsi2 = gsi_last_bb (gimple_phi_arg_edge (phi, i)->src); | |
1211 if (!gsi_end_p (gsi2)) | |
1212 last = gsi_stmt (gsi2); | |
1213 | |
1214 /* In theory the only way we ought to get back to the | |
1215 start of a loop should be with a COND_EXPR or GOTO_EXPR. | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1216 However, better safe than sorry. |
0 | 1217 If the block ends with a control statement or |
1218 something that might throw, then we have to | |
1219 insert this assignment before the last | |
1220 statement. Else insert it after the last statement. */ | |
1221 if (last && stmt_ends_bb_p (last)) | |
1222 { | |
1223 /* If the last statement in the block is the definition | |
1224 site of the PHI argument, then we can't insert | |
1225 anything after it. */ | |
1226 if (TREE_CODE (arg) == SSA_NAME | |
1227 && SSA_NAME_DEF_STMT (arg) == last) | |
1228 continue; | |
1229 } | |
1230 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1231 /* Create a new instance of the underlying variable of the |
0 | 1232 PHI result. */ |
111 | 1233 name = copy_ssa_name (result); |
1234 stmt = gimple_build_assign (name, | |
0 | 1235 gimple_phi_arg_def (phi, i)); |
1236 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1237 /* copy location if present. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1238 if (gimple_phi_arg_has_location (phi, i)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1239 gimple_set_location (stmt, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1240 gimple_phi_arg_location (phi, i)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1241 |
0 | 1242 /* Insert the new statement into the block and update |
1243 the PHI node. */ | |
1244 if (last && stmt_ends_bb_p (last)) | |
1245 gsi_insert_before (&gsi2, stmt, GSI_NEW_STMT); | |
1246 else | |
1247 gsi_insert_after (&gsi2, stmt, GSI_NEW_STMT); | |
1248 SET_PHI_ARG_DEF (phi, i, name); | |
1249 } | |
145 | 1250 /* Insert a copy before the definition of the backedge value |
1251 and adjust all conflicting uses. */ | |
1252 else if (trivially_conflicts_p (bb, result, arg)) | |
1253 { | |
1254 gimple *def = SSA_NAME_DEF_STMT (arg); | |
1255 if (gimple_nop_p (def) | |
1256 || gimple_code (def) == GIMPLE_PHI) | |
1257 continue; | |
1258 tree name = copy_ssa_name (result); | |
1259 gimple *stmt = gimple_build_assign (name, result); | |
1260 imm_use_iterator imm_iter; | |
1261 gimple *use_stmt; | |
1262 /* The following matches trivially_conflicts_p. */ | |
1263 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, result) | |
1264 { | |
1265 if (gimple_bb (use_stmt) != bb | |
1266 || (gimple_code (use_stmt) != GIMPLE_PHI | |
1267 && (maybe_renumber_stmts_bb (bb), true) | |
1268 && gimple_uid (use_stmt) > gimple_uid (def))) | |
1269 { | |
1270 use_operand_p use; | |
1271 FOR_EACH_IMM_USE_ON_STMT (use, imm_iter) | |
1272 SET_USE (use, name); | |
1273 } | |
1274 } | |
1275 gimple_stmt_iterator gsi = gsi_for_stmt (def); | |
1276 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT); | |
1277 } | |
0 | 1278 } |
1279 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1280 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1281 /* Unmark this block again. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1282 bb->aux = NULL; |
0 | 1283 } |
1284 } | |
1285 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1286 /* Free all memory associated with going out of SSA form. SA is |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1287 the outof-SSA info object. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1288 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1289 void |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1290 finish_out_of_ssa (struct ssaexpand *sa) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1291 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1292 free (sa->partition_to_pseudo); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1293 if (sa->values) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1294 BITMAP_FREE (sa->values); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1295 delete_var_map (sa->map); |
111 | 1296 BITMAP_FREE (sa->partitions_for_parm_default_defs); |
1297 BITMAP_FREE (sa->partitions_for_undefined_values); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1298 memset (sa, 0, sizeof *sa); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1299 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1300 |
0 | 1301 /* Take the current function out of SSA form, translating PHIs as described in |
1302 R. Morgan, ``Building an Optimizing Compiler'', | |
1303 Butterworth-Heinemann, Boston, MA, 1998. pp 176-186. */ | |
1304 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1305 unsigned int |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1306 rewrite_out_of_ssa (struct ssaexpand *sa) |
0 | 1307 { |
1308 /* If elimination of a PHI requires inserting a copy on a backedge, | |
1309 then we will have to split the backedge which has numerous | |
1310 undesirable performance effects. | |
1311 | |
1312 A significant number of such cases can be handled here by inserting | |
1313 copies into the loop itself. */ | |
1314 insert_backedge_copies (); | |
1315 | |
1316 | |
1317 /* Eliminate PHIs which are of no use, such as virtual or dead phis. */ | |
1318 eliminate_useless_phis (); | |
1319 | |
1320 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1321 gimple_dump_cfg (dump_file, dump_flags & ~TDF_DETAILS); | |
1322 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1323 remove_ssa_form (flag_tree_ter, sa); |
0 | 1324 |
1325 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1326 gimple_dump_cfg (dump_file, dump_flags & ~TDF_DETAILS); | |
1327 | |
1328 return 0; | |
1329 } |