Mercurial > hg > CbC > CbC_gcc
annotate gcc/tree-outof-ssa.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
rev | line source |
---|---|
0 | 1 /* Convert a program in SSA form into Normal form. |
131 | 2 Copyright (C) 2004-2018 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 |
111 | 132 struct elim_graph |
133 { | |
134 elim_graph (var_map map); | |
135 | |
0 | 136 /* Size of the elimination vectors. */ |
137 int size; | |
138 | |
139 /* List of nodes in the elimination graph. */ | |
111 | 140 auto_vec<int> nodes; |
0 | 141 |
142 /* The predecessor and successor edge list. */ | |
111 | 143 auto_vec<int> edge_list; |
0 | 144 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
145 /* Source locus on each edge */ |
111 | 146 auto_vec<source_location> 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
|
147 |
0 | 148 /* Visited vector. */ |
111 | 149 auto_sbitmap visited; |
0 | 150 |
151 /* Stack for visited nodes. */ | |
111 | 152 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
|
153 |
0 | 154 /* The variable partition map. */ |
155 var_map map; | |
156 | |
157 /* Edge being eliminated by this graph. */ | |
158 edge e; | |
159 | |
160 /* List of constant copies to emit. These are pushed on in pairs. */ | |
111 | 161 auto_vec<int> const_dests; |
162 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
|
163 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
164 /* Source locations for any constant copies. */ |
111 | 165 auto_vec<source_location> copy_locus; |
166 }; | |
0 | 167 |
168 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
169 /* 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
|
170 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
|
171 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
|
172 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
|
173 we insert on edges for PHI nodes, and effects of PHIs happen on |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
174 the end of the predecessor conceptually. */ |
0 | 175 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
176 static void |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
177 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
|
178 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
179 if (e->goto_locus) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
180 { |
111 | 181 set_curr_insn_location (e->goto_locus); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
182 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
183 else |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
184 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
185 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
|
186 gimple_stmt_iterator gsi; |
0 | 187 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
188 do |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
189 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
190 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
|
191 { |
111 | 192 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
|
193 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
|
194 continue; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
195 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
|
196 { |
111 | 197 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
|
198 return; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
199 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
200 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
201 /* 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
|
202 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
|
203 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
|
204 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
|
205 else |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
206 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
|
207 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
208 while (bb != e->src); |
0 | 209 } |
210 } | |
211 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
212 /* 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
|
213 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
|
214 which we deduce the size to copy in that case. */ |
0 | 215 |
111 | 216 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
|
217 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
|
218 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
219 start_sequence (); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
220 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
221 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
|
222 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
|
223 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
|
224 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
225 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
|
226 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
|
227 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
228 else |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
229 emit_move_insn (dest, src); |
111 | 230 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
|
231 |
111 | 232 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
|
233 end_sequence (); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
234 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
235 return seq; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
236 } |
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 /* Insert a copy instruction from partition SRC to DEST onto edge E. */ |
0 | 239 |
240 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
|
241 insert_partition_copy_on_edge (edge e, int dest, int src, source_location locus) |
0 | 242 { |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
243 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
|
244 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
|
245 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
246 fprintf (dump_file, |
111 | 247 "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
|
248 "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
|
249 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
|
250 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
|
251 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
|
252 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
253 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
254 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
|
255 gcc_assert (SA.partition_to_pseudo[src]); |
0 | 256 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
257 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
|
258 /* 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
|
259 if (locus) |
111 | 260 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
|
261 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
262 var = partition_to_var (SA.map, src); |
111 | 263 rtx_insn *seq = emit_partition_copy (copy_rtx (SA.partition_to_pseudo[dest]), |
264 copy_rtx (SA.partition_to_pseudo[src]), | |
265 TYPE_UNSIGNED (TREE_TYPE (var)), | |
266 var); | |
0 | 267 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
268 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
|
269 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
270 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
271 /* 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
|
272 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
|
273 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
274 static void |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
275 insert_value_copy_on_edge (edge e, int dest, tree src, source_location locus) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
276 { |
111 | 277 rtx dest_rtx, seq, x; |
278 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
|
279 int unsignedp; |
0 | 280 |
281 if (dump_file && (dump_flags & TDF_DETAILS)) | |
282 { | |
283 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
|
284 "Inserting a value copy on edge BB%d->BB%d : PART.%d = ", |
0 | 285 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
|
286 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
|
287 print_generic_expr (dump_file, src, TDF_SLIM); |
0 | 288 fprintf (dump_file, "\n"); |
289 } | |
290 | |
111 | 291 dest_rtx = copy_rtx (SA.partition_to_pseudo[dest]); |
292 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
|
293 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
294 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
|
295 /* 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
|
296 if (locus) |
111 | 297 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
|
298 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
299 start_sequence (); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
300 |
111 | 301 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
|
302 src_mode = TYPE_MODE (TREE_TYPE (src)); |
111 | 303 dest_mode = GET_MODE (dest_rtx); |
304 gcc_assert (src_mode == TYPE_MODE (TREE_TYPE (name))); | |
305 gcc_assert (!REG_P (dest_rtx) | |
306 || 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
|
307 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
308 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
|
309 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
310 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
|
311 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
|
312 } |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
313 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
|
314 { |
111 | 315 x = dest_rtx; |
316 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
|
317 } |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
318 else |
111 | 319 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
|
320 |
111 | 321 if (x != dest_rtx) |
322 emit_move_insn (dest_rtx, x); | |
323 do_pending_stack_adjust (); | |
324 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
325 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
|
326 end_sequence (); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
327 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
328 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
|
329 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
330 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
331 /* 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
|
332 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
|
333 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
334 static void |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
335 insert_rtx_to_part_on_edge (edge e, int dest, rtx src, int unsignedsrcp, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
336 source_location locus) |
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 (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
|
339 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
340 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
|
341 "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
|
342 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
|
343 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
|
344 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
|
345 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
|
346 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
347 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
348 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
|
349 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
350 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
|
351 /* 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
|
352 if (locus) |
111 | 353 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
|
354 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
355 /* 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
|
356 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
|
357 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
|
358 involved), so it doesn't matter. */ |
111 | 359 rtx_insn *seq = emit_partition_copy (copy_rtx (SA.partition_to_pseudo[dest]), |
360 src, unsignedsrcp, | |
361 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
|
362 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
363 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
|
364 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
365 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
366 /* 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
|
367 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
|
368 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
369 static void |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
370 insert_part_to_rtx_on_edge (edge e, rtx dest, int src, source_location locus) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
371 { |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
372 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
|
373 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
|
374 { |
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, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
376 "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
|
377 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
|
378 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
|
379 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
|
380 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
|
381 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
382 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
383 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
|
384 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
385 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
|
386 /* 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
|
387 if (locus) |
111 | 388 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
|
389 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
390 var = partition_to_var (SA.map, src); |
111 | 391 rtx_insn *seq = emit_partition_copy (dest, |
392 copy_rtx (SA.partition_to_pseudo[src]), | |
393 TYPE_UNSIGNED (TREE_TYPE (var)), | |
394 var); | |
55
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_insn_on_edge (seq, e); |
0 | 397 } |
398 | |
399 | |
111 | 400 /* Create an elimination graph for map. */ |
0 | 401 |
111 | 402 elim_graph::elim_graph (var_map map) : |
403 nodes (30), edge_list (20), edge_locus (10), visited (map->num_partitions), | |
404 stack (30), map (map), const_dests (20), const_copies (20), copy_locus (10) | |
405 { | |
0 | 406 } |
407 | |
408 | |
409 /* Empty elimination graph G. */ | |
410 | |
411 static inline void | |
111 | 412 clear_elim_graph (elim_graph *g) |
0 | 413 { |
111 | 414 g->nodes.truncate (0); |
415 g->edge_list.truncate (0); | |
416 g->edge_locus.truncate (0); | |
0 | 417 } |
418 | |
419 | |
420 /* Return the number of nodes in graph G. */ | |
421 | |
422 static inline int | |
111 | 423 elim_graph_size (elim_graph *g) |
0 | 424 { |
111 | 425 return g->nodes.length (); |
0 | 426 } |
427 | |
428 | |
429 /* Add NODE to graph G, if it doesn't exist already. */ | |
430 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
431 static inline void |
111 | 432 elim_graph_add_node (elim_graph *g, int node) |
0 | 433 { |
434 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
|
435 int t; |
0 | 436 |
111 | 437 FOR_EACH_VEC_ELT (g->nodes, x, t) |
0 | 438 if (t == node) |
439 return; | |
111 | 440 g->nodes.safe_push (node); |
0 | 441 } |
442 | |
443 | |
444 /* Add the edge PRED->SUCC to graph G. */ | |
445 | |
446 static inline void | |
111 | 447 elim_graph_add_edge (elim_graph *g, int pred, int succ, source_location locus) |
0 | 448 { |
111 | 449 g->edge_list.safe_push (pred); |
450 g->edge_list.safe_push (succ); | |
451 g->edge_locus.safe_push (locus); | |
0 | 452 } |
453 | |
454 | |
455 /* Remove an edge from graph G for which NODE is the predecessor, and | |
456 return the successor node. -1 is returned if there is no such edge. */ | |
457 | |
458 static inline int | |
111 | 459 elim_graph_remove_succ_edge (elim_graph *g, int node, source_location *locus) |
0 | 460 { |
461 int y; | |
462 unsigned x; | |
111 | 463 for (x = 0; x < g->edge_list.length (); x += 2) |
464 if (g->edge_list[x] == node) | |
0 | 465 { |
111 | 466 g->edge_list[x] = -1; |
467 y = g->edge_list[x + 1]; | |
468 g->edge_list[x + 1] = -1; | |
469 *locus = g->edge_locus[x / 2]; | |
470 g->edge_locus[x / 2] = UNKNOWN_LOCATION; | |
0 | 471 return y; |
472 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
473 *locus = UNKNOWN_LOCATION; |
0 | 474 return -1; |
475 } | |
476 | |
477 | |
478 /* Find all the nodes in GRAPH which are successors to NODE in the | |
479 edge list. VAR will hold the partition number found. CODE is the | |
480 code fragment executed for every node found. */ | |
481 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
482 #define FOR_EACH_ELIM_GRAPH_SUCC(GRAPH, NODE, VAR, LOCUS, CODE) \ |
0 | 483 do { \ |
484 unsigned x_; \ | |
485 int y_; \ | |
111 | 486 for (x_ = 0; x_ < (GRAPH)->edge_list.length (); x_ += 2) \ |
0 | 487 { \ |
111 | 488 y_ = (GRAPH)->edge_list[x_]; \ |
0 | 489 if (y_ != (NODE)) \ |
490 continue; \ | |
111 | 491 (void) ((VAR) = (GRAPH)->edge_list[x_ + 1]); \ |
492 (void) ((LOCUS) = (GRAPH)->edge_locus[x_ / 2]); \ | |
0 | 493 CODE; \ |
494 } \ | |
495 } while (0) | |
496 | |
497 | |
498 /* Find all the nodes which are predecessors of NODE in the edge list for | |
499 GRAPH. VAR will hold the partition number found. CODE is the | |
500 code fragment executed for every node found. */ | |
501 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
502 #define FOR_EACH_ELIM_GRAPH_PRED(GRAPH, NODE, VAR, LOCUS, CODE) \ |
0 | 503 do { \ |
504 unsigned x_; \ | |
505 int y_; \ | |
111 | 506 for (x_ = 0; x_ < (GRAPH)->edge_list.length (); x_ += 2) \ |
0 | 507 { \ |
111 | 508 y_ = (GRAPH)->edge_list[x_ + 1]; \ |
0 | 509 if (y_ != (NODE)) \ |
510 continue; \ | |
111 | 511 (void) ((VAR) = (GRAPH)->edge_list[x_]); \ |
512 (void) ((LOCUS) = (GRAPH)->edge_locus[x_ / 2]); \ | |
0 | 513 CODE; \ |
514 } \ | |
515 } while (0) | |
516 | |
517 | |
518 /* Add T to elimination graph G. */ | |
519 | |
520 static inline void | |
111 | 521 eliminate_name (elim_graph *g, int T) |
0 | 522 { |
523 elim_graph_add_node (g, T); | |
524 } | |
525 | |
111 | 526 /* Return true if this phi argument T should have a copy queued when using |
527 var_map MAP. PHI nodes should contain only ssa_names and invariants. A | |
528 test for ssa_name is definitely simpler, but don't let invalid contents | |
529 slip through in the meantime. */ | |
530 | |
531 static inline bool | |
532 queue_phi_copy_p (var_map map, tree t) | |
533 { | |
534 if (TREE_CODE (t) == SSA_NAME) | |
535 { | |
536 if (var_to_partition (map, t) == NO_PARTITION) | |
537 return true; | |
538 return false; | |
539 } | |
540 gcc_checking_assert (is_gimple_min_invariant (t)); | |
541 return true; | |
542 } | |
0 | 543 |
544 /* Build elimination graph G for basic block BB on incoming PHI edge | |
545 G->e. */ | |
546 | |
547 static void | |
111 | 548 eliminate_build (elim_graph *g) |
0 | 549 { |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
550 tree Ti; |
0 | 551 int p0, pi; |
111 | 552 gphi_iterator gsi; |
0 | 553 |
554 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
|
555 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
556 for (gsi = gsi_start_phis (g->e->dest); !gsi_end_p (gsi); gsi_next (&gsi)) |
0 | 557 { |
111 | 558 gphi *phi = gsi.phi (); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
559 source_location locus; |
0 | 560 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
561 p0 = var_to_partition (g->map, gimple_phi_result (phi)); |
0 | 562 /* 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
|
563 if (p0 == NO_PARTITION) |
0 | 564 continue; |
565 | |
566 Ti = PHI_ARG_DEF (phi, g->e->dest_idx); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
567 locus = gimple_phi_arg_location_from_edge (phi, g->e); |
0 | 568 |
569 /* If this argument is a constant, or a SSA_NAME which is being | |
570 left in SSA form, just queue a copy to be emitted on this | |
571 edge. */ | |
111 | 572 if (queue_phi_copy_p (g->map, Ti)) |
0 | 573 { |
574 /* Save constant copies until all other copies have been emitted | |
575 on this edge. */ | |
111 | 576 g->const_dests.safe_push (p0); |
577 g->const_copies.safe_push (Ti); | |
578 g->copy_locus.safe_push (locus); | |
0 | 579 } |
580 else | |
581 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
582 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
|
583 if (p0 != pi) |
0 | 584 { |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
585 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
|
586 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
|
587 elim_graph_add_edge (g, p0, pi, locus); |
0 | 588 } |
589 } | |
590 } | |
591 } | |
592 | |
593 | |
594 /* Push successors of T onto the elimination stack for G. */ | |
595 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
596 static void |
111 | 597 elim_forward (elim_graph *g, int T) |
0 | 598 { |
599 int S; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
600 source_location locus; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
601 |
111 | 602 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
|
603 FOR_EACH_ELIM_GRAPH_SUCC (g, T, S, locus, |
0 | 604 { |
111 | 605 if (!bitmap_bit_p (g->visited, S)) |
0 | 606 elim_forward (g, S); |
607 }); | |
111 | 608 g->stack.safe_push (T); |
0 | 609 } |
610 | |
611 | |
612 /* Return 1 if there unvisited predecessors of T in graph G. */ | |
613 | |
614 static int | |
111 | 615 elim_unvisited_predecessor (elim_graph *g, int T) |
0 | 616 { |
617 int P; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
618 source_location locus; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
619 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
620 FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus, |
0 | 621 { |
111 | 622 if (!bitmap_bit_p (g->visited, P)) |
0 | 623 return 1; |
624 }); | |
625 return 0; | |
626 } | |
627 | |
628 /* Process predecessors first, and insert a copy. */ | |
629 | |
630 static void | |
111 | 631 elim_backward (elim_graph *g, int T) |
0 | 632 { |
633 int P; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
634 source_location locus; |
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_PRED (g, T, P, locus, |
0 | 638 { |
111 | 639 if (!bitmap_bit_p (g->visited, P)) |
0 | 640 { |
641 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
|
642 insert_partition_copy_on_edge (g->e, P, T, locus); |
0 | 643 } |
644 }); | |
645 } | |
646 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
647 /* 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
|
648 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
|
649 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
650 static rtx |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
651 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
|
652 { |
111 | 653 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
|
654 int unsignedp; |
111 | 655 machine_mode reg_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
|
656 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
|
657 if (POINTER_TYPE_P (type)) |
111 | 658 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
|
659 return x; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
660 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
661 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
662 /* Insert required copies for T in graph G. Check for a strongly connected |
0 | 663 region, and create a temporary to break the cycle if one is found. */ |
664 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
665 static void |
111 | 666 elim_create (elim_graph *g, int T) |
0 | 667 { |
668 int P, S; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
669 source_location locus; |
0 | 670 |
671 if (elim_unvisited_predecessor (g, T)) | |
672 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
673 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
|
674 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
|
675 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
|
676 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
677 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
|
678 FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus, |
0 | 679 { |
111 | 680 if (!bitmap_bit_p (g->visited, P)) |
0 | 681 { |
682 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
|
683 insert_rtx_to_part_on_edge (g->e, P, U, unsignedsrcp, locus); |
0 | 684 } |
685 }); | |
686 } | |
687 else | |
688 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
689 S = elim_graph_remove_succ_edge (g, T, &locus); |
0 | 690 if (S != -1) |
691 { | |
111 | 692 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
|
693 insert_partition_copy_on_edge (g->e, T, S, locus); |
0 | 694 } |
695 } | |
696 } | |
697 | |
698 | |
699 /* Eliminate all the phi nodes on edge E in graph G. */ | |
700 | |
701 static void | |
111 | 702 eliminate_phi (edge e, elim_graph *g) |
0 | 703 { |
704 int x; | |
705 | |
111 | 706 gcc_assert (g->const_copies.length () == 0); |
707 gcc_assert (g->copy_locus.length () == 0); | |
0 | 708 |
709 /* Abnormal edges already have everything coalesced. */ | |
710 if (e->flags & EDGE_ABNORMAL) | |
711 return; | |
712 | |
713 g->e = e; | |
714 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
715 eliminate_build (g); |
0 | 716 |
717 if (elim_graph_size (g) != 0) | |
718 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
719 int part; |
0 | 720 |
111 | 721 bitmap_clear (g->visited); |
722 g->stack.truncate (0); | |
0 | 723 |
111 | 724 FOR_EACH_VEC_ELT (g->nodes, x, part) |
0 | 725 { |
111 | 726 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
|
727 elim_forward (g, part); |
0 | 728 } |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
729 |
111 | 730 bitmap_clear (g->visited); |
731 while (g->stack.length () > 0) | |
0 | 732 { |
111 | 733 x = g->stack.pop (); |
734 if (!bitmap_bit_p (g->visited, x)) | |
0 | 735 elim_create (g, x); |
736 } | |
737 } | |
738 | |
739 /* If there are any pending constant copies, issue them now. */ | |
111 | 740 while (g->const_copies.length () > 0) |
0 | 741 { |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
742 int dest; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
743 tree src; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
744 source_location locus; |
0 | 745 |
111 | 746 src = g->const_copies.pop (); |
747 dest = g->const_dests.pop (); | |
748 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
|
749 insert_value_copy_on_edge (e, dest, src, locus); |
0 | 750 } |
751 } | |
752 | |
753 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
754 /* Remove each argument from PHI. If an arg was the last use of an SSA_NAME, |
0 | 755 check to see if this allows another PHI node to be removed. */ |
756 | |
757 static void | |
111 | 758 remove_gimple_phi_args (gphi *phi) |
0 | 759 { |
760 use_operand_p arg_p; | |
761 ssa_op_iter iter; | |
762 | |
763 if (dump_file && (dump_flags & TDF_DETAILS)) | |
764 { | |
765 fprintf (dump_file, "Removing Dead PHI definition: "); | |
766 print_gimple_stmt (dump_file, phi, 0, TDF_SLIM); | |
767 } | |
768 | |
769 FOR_EACH_PHI_ARG (arg_p, phi, iter, SSA_OP_USE) | |
770 { | |
771 tree arg = USE_FROM_PTR (arg_p); | |
772 if (TREE_CODE (arg) == SSA_NAME) | |
773 { | |
774 /* Remove the reference to the existing argument. */ | |
775 SET_USE (arg_p, NULL_TREE); | |
776 if (has_zero_uses (arg)) | |
777 { | |
111 | 778 gimple *stmt; |
0 | 779 gimple_stmt_iterator gsi; |
780 | |
781 stmt = SSA_NAME_DEF_STMT (arg); | |
782 | |
783 /* Also remove the def if it is a PHI node. */ | |
784 if (gimple_code (stmt) == GIMPLE_PHI) | |
785 { | |
111 | 786 remove_gimple_phi_args (as_a <gphi *> (stmt)); |
0 | 787 gsi = gsi_for_stmt (stmt); |
788 remove_phi_node (&gsi, true); | |
789 } | |
790 | |
791 } | |
792 } | |
793 } | |
794 } | |
795 | |
796 /* Remove any PHI node which is a virtual PHI, or a PHI with no uses. */ | |
797 | |
798 static void | |
799 eliminate_useless_phis (void) | |
800 { | |
801 basic_block bb; | |
111 | 802 gphi_iterator gsi; |
0 | 803 tree result; |
804 | |
111 | 805 FOR_EACH_BB_FN (bb, cfun) |
0 | 806 { |
807 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); ) | |
808 { | |
111 | 809 gphi *phi = gsi.phi (); |
0 | 810 result = gimple_phi_result (phi); |
111 | 811 if (virtual_operand_p (result)) |
0 | 812 { |
813 /* There should be no arguments which are not virtual, or the | |
814 results will be incorrect. */ | |
111 | 815 if (flag_checking) |
816 for (size_t i = 0; i < gimple_phi_num_args (phi); i++) | |
817 { | |
818 tree arg = PHI_ARG_DEF (phi, i); | |
819 if (TREE_CODE (arg) == SSA_NAME | |
820 && !virtual_operand_p (arg)) | |
821 { | |
822 fprintf (stderr, "Argument of PHI is not virtual ("); | |
823 print_generic_expr (stderr, arg, TDF_SLIM); | |
824 fprintf (stderr, "), but the result is :"); | |
825 print_gimple_stmt (stderr, phi, 0, TDF_SLIM); | |
826 internal_error ("SSA corruption"); | |
827 } | |
828 } | |
829 | |
0 | 830 remove_phi_node (&gsi, true); |
831 } | |
832 else | |
833 { | |
834 /* Also remove real PHIs with no uses. */ | |
835 if (has_zero_uses (result)) | |
836 { | |
837 remove_gimple_phi_args (phi); | |
838 remove_phi_node (&gsi, true); | |
839 } | |
840 else | |
841 gsi_next (&gsi); | |
842 } | |
843 } | |
844 } | |
845 } | |
846 | |
847 | |
848 /* 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
|
849 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
|
850 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
|
851 replaced with the expression in the vector instead of its mapped |
0 | 852 variable. */ |
853 | |
854 static void | |
111 | 855 rewrite_trees (var_map map) |
0 | 856 { |
111 | 857 if (!flag_checking) |
858 return; | |
859 | |
0 | 860 basic_block bb; |
861 /* Search for PHIs where the destination has no partition, but one | |
862 or more arguments has a partition. This should not happen and can | |
863 create incorrect code. */ | |
111 | 864 FOR_EACH_BB_FN (bb, cfun) |
0 | 865 { |
111 | 866 gphi_iterator gsi; |
0 | 867 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) |
868 { | |
111 | 869 gphi *phi = gsi.phi (); |
0 | 870 tree T0 = var_to_partition_to_var (map, gimple_phi_result (phi)); |
871 if (T0 == NULL_TREE) | |
872 { | |
873 size_t i; | |
874 for (i = 0; i < gimple_phi_num_args (phi); i++) | |
875 { | |
876 tree arg = PHI_ARG_DEF (phi, i); | |
877 | |
878 if (TREE_CODE (arg) == SSA_NAME | |
879 && var_to_partition (map, arg) != NO_PARTITION) | |
880 { | |
881 fprintf (stderr, "Argument of PHI is in a partition :("); | |
882 print_generic_expr (stderr, arg, TDF_SLIM); | |
883 fprintf (stderr, "), but the result is not :"); | |
884 print_gimple_stmt (stderr, phi, 0, TDF_SLIM); | |
885 internal_error ("SSA corruption"); | |
886 } | |
887 } | |
888 } | |
889 } | |
890 } | |
891 } | |
892 | |
131 | 893 /* Create a default def for VAR. */ |
894 | |
895 static void | |
896 create_default_def (tree var, void *arg ATTRIBUTE_UNUSED) | |
897 { | |
898 if (!is_gimple_reg (var)) | |
899 return; | |
900 | |
901 tree ssa = get_or_create_ssa_default_def (cfun, var); | |
902 gcc_assert (ssa); | |
903 } | |
904 | |
905 /* Call CALLBACK for all PARM_DECLs and RESULT_DECLs for which | |
906 assign_parms may ask for a default partition. */ | |
907 | |
908 static void | |
909 for_all_parms (void (*callback)(tree var, void *arg), void *arg) | |
910 { | |
911 for (tree var = DECL_ARGUMENTS (current_function_decl); var; | |
912 var = DECL_CHAIN (var)) | |
913 callback (var, arg); | |
914 if (!VOID_TYPE_P (TREE_TYPE (DECL_RESULT (current_function_decl)))) | |
915 callback (DECL_RESULT (current_function_decl), arg); | |
916 if (cfun->static_chain_decl) | |
917 callback (cfun->static_chain_decl, arg); | |
918 } | |
919 | |
920 /* We need to pass two arguments to set_parm_default_def_partition, | |
921 but for_all_parms only supports one. Use a pair. */ | |
922 | |
923 typedef std::pair<var_map, bitmap> parm_default_def_partition_arg; | |
924 | |
925 /* Set in ARG's PARTS bitmap the bit corresponding to the partition in | |
926 ARG's MAP containing VAR's default def. */ | |
927 | |
928 static void | |
929 set_parm_default_def_partition (tree var, void *arg_) | |
930 { | |
931 parm_default_def_partition_arg *arg = (parm_default_def_partition_arg *)arg_; | |
932 var_map map = arg->first; | |
933 bitmap parts = arg->second; | |
934 | |
935 if (!is_gimple_reg (var)) | |
936 return; | |
937 | |
938 tree ssa = ssa_default_def (cfun, var); | |
939 gcc_assert (ssa); | |
940 | |
941 int version = var_to_partition (map, ssa); | |
942 gcc_assert (version != NO_PARTITION); | |
943 | |
944 bool changed = bitmap_set_bit (parts, version); | |
945 gcc_assert (changed); | |
946 } | |
947 | |
948 /* Allocate and return a bitmap that has a bit set for each partition | |
949 that contains a default def for a parameter. */ | |
950 | |
951 static bitmap | |
952 get_parm_default_def_partitions (var_map map) | |
953 { | |
954 bitmap parm_default_def_parts = BITMAP_ALLOC (NULL); | |
955 | |
956 parm_default_def_partition_arg | |
957 arg = std::make_pair (map, parm_default_def_parts); | |
958 | |
959 for_all_parms (set_parm_default_def_partition, &arg); | |
960 | |
961 return parm_default_def_parts; | |
962 } | |
963 | |
964 /* Allocate and return a bitmap that has a bit set for each partition | |
965 that contains an undefined value. */ | |
966 | |
967 static bitmap | |
968 get_undefined_value_partitions (var_map map) | |
969 { | |
970 bitmap undefined_value_parts = BITMAP_ALLOC (NULL); | |
971 | |
972 for (unsigned int i = 1; i < num_ssa_names; i++) | |
973 { | |
974 tree var = ssa_name (i); | |
975 if (var | |
976 && !virtual_operand_p (var) | |
977 && !has_zero_uses (var) | |
978 && ssa_undefined_value_p (var)) | |
979 { | |
980 const int p = var_to_partition (map, var); | |
981 if (p != NO_PARTITION) | |
982 bitmap_set_bit (undefined_value_parts, p); | |
983 } | |
984 } | |
985 | |
986 return undefined_value_parts; | |
987 } | |
988 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
989 /* 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
|
990 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
|
991 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
|
992 some RTL instructions inserted on edges. */ |
0 | 993 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
994 void |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
995 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
|
996 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
997 basic_block bb; |
111 | 998 elim_graph g (sa->map); |
0 | 999 |
111 | 1000 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb, |
1001 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
|
1002 if (!gimple_seq_empty_p (phi_nodes (bb))) |
0 | 1003 { |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1004 edge e; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1005 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
|
1006 FOR_EACH_EDGE (e, ei, bb->preds) |
111 | 1007 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
|
1008 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
|
1009 /* 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
|
1010 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
|
1011 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
|
1012 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
|
1013 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
|
1014 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
|
1015 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
|
1016 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
|
1017 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
|
1018 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
|
1019 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1020 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
|
1021 && !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
|
1022 { |
111 | 1023 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
|
1024 basic_block bb; |
111 | 1025 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
|
1026 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
|
1027 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
|
1028 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1029 else |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1030 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
|
1031 } |
0 | 1032 } |
1033 } | |
1034 | |
1035 | |
1036 /* Remove the ssa-names in the current function and translate them into normal | |
1037 compiler variables. PERFORM_TER is true if Temporary Expression Replacement | |
1038 should also be used. */ | |
1039 | |
1040 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
|
1041 remove_ssa_form (bool perform_ter, struct ssaexpand *sa) |
0 | 1042 { |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1043 bitmap values = NULL; |
0 | 1044 var_map map; |
1045 | |
131 | 1046 for_all_parms (create_default_def, NULL); |
1047 map = init_var_map (num_ssa_names); | |
1048 coalesce_ssa_name (map); | |
0 | 1049 |
1050 /* Return to viewing the variable list as just all reference variables after | |
1051 coalescing has been performed. */ | |
111 | 1052 partition_view_normal (map); |
0 | 1053 |
1054 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1055 { | |
1056 fprintf (dump_file, "After Coalescing:\n"); | |
1057 dump_var_map (dump_file, map); | |
1058 } | |
1059 | |
1060 if (perform_ter) | |
1061 { | |
1062 values = find_replaceable_exprs (map); | |
1063 if (values && dump_file && (dump_flags & TDF_DETAILS)) | |
1064 dump_replaceable_exprs (dump_file, values); | |
1065 } | |
1066 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1067 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
|
1068 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1069 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
|
1070 sa->values = values; |
111 | 1071 sa->partitions_for_parm_default_defs = get_parm_default_def_partitions (map); |
1072 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
|
1073 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1074 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1075 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1076 /* 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
|
1077 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
|
1078 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1079 static void |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1080 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
|
1081 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1082 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
|
1083 gimple_stmt_iterator gsi; |
0 | 1084 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1085 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
|
1086 return; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1087 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
|
1088 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) |
0 | 1089 { |
111 | 1090 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
|
1091 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
|
1092 i++; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1093 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1094 } |
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 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1097 /* 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
|
1098 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
|
1099 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
|
1100 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1101 static bool |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1102 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
|
1103 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1104 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
|
1105 imm_use_iterator imm_iter; |
111 | 1106 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
|
1107 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1108 /* 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
|
1109 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
|
1110 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
|
1111 return false; |
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 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
|
1114 { |
111 | 1115 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
|
1116 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
|
1117 continue; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1118 /* 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
|
1119 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
|
1120 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
|
1121 return true; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1122 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
|
1123 continue; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1124 /* 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
|
1125 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
|
1126 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
|
1127 return true; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1128 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
|
1129 /* 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
|
1130 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
|
1131 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
|
1132 return true; |
0 | 1133 } |
1134 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1135 return false; |
0 | 1136 } |
1137 | |
1138 | |
1139 /* Search every PHI node for arguments associated with backedges which | |
1140 we can trivially determine will need a copy (the argument is either | |
1141 not an SSA_NAME or the argument has a different underlying variable | |
1142 than the PHI result). | |
1143 | |
1144 Insert a copy from the PHI argument to a new destination at the | |
1145 end of the block with the backedge to the top of the loop. Update | |
1146 the PHI argument to reference this new destination. */ | |
1147 | |
1148 static void | |
1149 insert_backedge_copies (void) | |
1150 { | |
1151 basic_block bb; | |
111 | 1152 gphi_iterator gsi; |
0 | 1153 |
111 | 1154 mark_dfs_back_edges (); |
1155 | |
1156 FOR_EACH_BB_FN (bb, cfun) | |
0 | 1157 { |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1158 /* 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
|
1159 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
|
1160 |
0 | 1161 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) |
1162 { | |
111 | 1163 gphi *phi = gsi.phi (); |
0 | 1164 tree result = gimple_phi_result (phi); |
1165 size_t i; | |
1166 | |
111 | 1167 if (virtual_operand_p (result)) |
0 | 1168 continue; |
1169 | |
1170 for (i = 0; i < gimple_phi_num_args (phi); i++) | |
1171 { | |
1172 tree arg = gimple_phi_arg_def (phi, i); | |
1173 edge e = gimple_phi_arg_edge (phi, i); | |
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 /* If the argument is not an SSA_NAME, then we will need a |
0 | 1176 constant initialization. If the argument is an SSA_NAME with |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1177 a different underlying variable then a copy statement will be |
0 | 1178 needed. */ |
1179 if ((e->flags & EDGE_DFS_BACK) | |
1180 && (TREE_CODE (arg) != SSA_NAME | |
111 | 1181 || SSA_NAME_VAR (arg) != SSA_NAME_VAR (result) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1182 || trivially_conflicts_p (bb, result, arg))) |
0 | 1183 { |
1184 tree name; | |
111 | 1185 gassign *stmt; |
1186 gimple *last = NULL; | |
0 | 1187 gimple_stmt_iterator gsi2; |
1188 | |
1189 gsi2 = gsi_last_bb (gimple_phi_arg_edge (phi, i)->src); | |
1190 if (!gsi_end_p (gsi2)) | |
1191 last = gsi_stmt (gsi2); | |
1192 | |
1193 /* In theory the only way we ought to get back to the | |
1194 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
|
1195 However, better safe than sorry. |
0 | 1196 If the block ends with a control statement or |
1197 something that might throw, then we have to | |
1198 insert this assignment before the last | |
1199 statement. Else insert it after the last statement. */ | |
1200 if (last && stmt_ends_bb_p (last)) | |
1201 { | |
1202 /* If the last statement in the block is the definition | |
1203 site of the PHI argument, then we can't insert | |
1204 anything after it. */ | |
1205 if (TREE_CODE (arg) == SSA_NAME | |
1206 && SSA_NAME_DEF_STMT (arg) == last) | |
1207 continue; | |
1208 } | |
1209 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1210 /* Create a new instance of the underlying variable of the |
0 | 1211 PHI result. */ |
111 | 1212 name = copy_ssa_name (result); |
1213 stmt = gimple_build_assign (name, | |
0 | 1214 gimple_phi_arg_def (phi, i)); |
1215 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1216 /* 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
|
1217 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
|
1218 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
|
1219 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
|
1220 |
0 | 1221 /* Insert the new statement into the block and update |
1222 the PHI node. */ | |
1223 if (last && stmt_ends_bb_p (last)) | |
1224 gsi_insert_before (&gsi2, stmt, GSI_NEW_STMT); | |
1225 else | |
1226 gsi_insert_after (&gsi2, stmt, GSI_NEW_STMT); | |
1227 SET_PHI_ARG_DEF (phi, i, name); | |
1228 } | |
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 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1232 /* 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
|
1233 bb->aux = NULL; |
0 | 1234 } |
1235 } | |
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 /* 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
|
1238 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
|
1239 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1240 void |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1241 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
|
1242 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1243 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
|
1244 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
|
1245 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
|
1246 delete_var_map (sa->map); |
111 | 1247 BITMAP_FREE (sa->partitions_for_parm_default_defs); |
1248 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
|
1249 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
|
1250 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1251 |
0 | 1252 /* Take the current function out of SSA form, translating PHIs as described in |
1253 R. Morgan, ``Building an Optimizing Compiler'', | |
1254 Butterworth-Heinemann, Boston, MA, 1998. pp 176-186. */ | |
1255 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1256 unsigned int |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1257 rewrite_out_of_ssa (struct ssaexpand *sa) |
0 | 1258 { |
1259 /* If elimination of a PHI requires inserting a copy on a backedge, | |
1260 then we will have to split the backedge which has numerous | |
1261 undesirable performance effects. | |
1262 | |
1263 A significant number of such cases can be handled here by inserting | |
1264 copies into the loop itself. */ | |
1265 insert_backedge_copies (); | |
1266 | |
1267 | |
1268 /* Eliminate PHIs which are of no use, such as virtual or dead phis. */ | |
1269 eliminate_useless_phis (); | |
1270 | |
1271 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1272 gimple_dump_cfg (dump_file, dump_flags & ~TDF_DETAILS); | |
1273 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1274 remove_ssa_form (flag_tree_ter, sa); |
0 | 1275 |
1276 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1277 gimple_dump_cfg (dump_file, dump_flags & ~TDF_DETAILS); | |
1278 | |
1279 return 0; | |
1280 } |