Mercurial > hg > CbC > CbC_gcc
comparison gcc/tree-outof-ssa.c @ 63:b7f97abdc517 gcc-4.6-20100522
update gcc from gcc-4.5.0 to gcc-4.6
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 24 May 2010 12:47:05 +0900 |
parents | 77e2b8dfacca |
children | f6334be47118 |
comparison
equal
deleted
inserted
replaced
56:3c8a44c06a95 | 63:b7f97abdc517 |
---|---|
1 /* Convert a program in SSA form into Normal form. | 1 /* Convert a program in SSA form into Normal form. |
2 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 | 2 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 |
3 Free Software Foundation, Inc. | 3 Free Software Foundation, Inc. |
4 Contributed by Andrew Macleod <amacleod@redhat.com> | 4 Contributed by Andrew Macleod <amacleod@redhat.com> |
5 | 5 |
6 This file is part of GCC. | 6 This file is part of GCC. |
7 | 7 |
25 #include "tm.h" | 25 #include "tm.h" |
26 #include "tree.h" | 26 #include "tree.h" |
27 #include "ggc.h" | 27 #include "ggc.h" |
28 #include "basic-block.h" | 28 #include "basic-block.h" |
29 #include "diagnostic.h" | 29 #include "diagnostic.h" |
30 #include "tree-pretty-print.h" | |
31 #include "gimple-pretty-print.h" | |
30 #include "bitmap.h" | 32 #include "bitmap.h" |
31 #include "tree-flow.h" | 33 #include "tree-flow.h" |
32 #include "timevar.h" | 34 #include "timevar.h" |
33 #include "tree-dump.h" | 35 #include "tree-dump.h" |
34 #include "tree-pass.h" | 36 #include "tree-pass.h" |
138 } | 140 } |
139 while (bb != e->src); | 141 while (bb != e->src); |
140 } | 142 } |
141 } | 143 } |
142 | 144 |
143 /* Emit insns to copy SRC into DEST converting SRC if necessary. */ | 145 /* Emit insns to copy SRC into DEST converting SRC if necessary. As |
146 SRC/DEST might be BLKmode memory locations SIZEEXP is a tree from | |
147 which we deduce the size to copy in that case. */ | |
144 | 148 |
145 static inline rtx | 149 static inline rtx |
146 emit_partition_copy (rtx dest, rtx src, int unsignedsrcp) | 150 emit_partition_copy (rtx dest, rtx src, int unsignedsrcp, tree sizeexp) |
147 { | 151 { |
148 rtx seq; | 152 rtx seq; |
149 | 153 |
150 start_sequence (); | 154 start_sequence (); |
151 | 155 |
152 if (GET_MODE (src) != VOIDmode && GET_MODE (src) != GET_MODE (dest)) | 156 if (GET_MODE (src) != VOIDmode && GET_MODE (src) != GET_MODE (dest)) |
153 src = convert_to_mode (GET_MODE (dest), src, unsignedsrcp); | 157 src = convert_to_mode (GET_MODE (dest), src, unsignedsrcp); |
154 emit_move_insn (dest, src); | 158 if (GET_MODE (src) == BLKmode) |
159 { | |
160 gcc_assert (GET_MODE (dest) == BLKmode); | |
161 emit_block_move (dest, src, expr_size (sizeexp), BLOCK_OP_NORMAL); | |
162 } | |
163 else | |
164 emit_move_insn (dest, src); | |
155 | 165 |
156 seq = get_insns (); | 166 seq = get_insns (); |
157 end_sequence (); | 167 end_sequence (); |
158 | 168 |
159 return seq; | 169 return seq; |
162 /* Insert a copy instruction from partition SRC to DEST onto edge E. */ | 172 /* Insert a copy instruction from partition SRC to DEST onto edge E. */ |
163 | 173 |
164 static void | 174 static void |
165 insert_partition_copy_on_edge (edge e, int dest, int src, source_location locus) | 175 insert_partition_copy_on_edge (edge e, int dest, int src, source_location locus) |
166 { | 176 { |
177 tree var; | |
167 rtx seq; | 178 rtx seq; |
168 if (dump_file && (dump_flags & TDF_DETAILS)) | 179 if (dump_file && (dump_flags & TDF_DETAILS)) |
169 { | 180 { |
170 fprintf (dump_file, | 181 fprintf (dump_file, |
171 "Inserting a partition copy on edge BB%d->BB%d :" | 182 "Inserting a partition copy on edge BB%d->BB%d :" |
181 set_location_for_edge (e); | 192 set_location_for_edge (e); |
182 /* If a locus is provided, override the default. */ | 193 /* If a locus is provided, override the default. */ |
183 if (locus) | 194 if (locus) |
184 set_curr_insn_source_location (locus); | 195 set_curr_insn_source_location (locus); |
185 | 196 |
197 var = partition_to_var (SA.map, src); | |
186 seq = emit_partition_copy (SA.partition_to_pseudo[dest], | 198 seq = emit_partition_copy (SA.partition_to_pseudo[dest], |
187 SA.partition_to_pseudo[src], | 199 SA.partition_to_pseudo[src], |
188 TYPE_UNSIGNED (TREE_TYPE ( | 200 TYPE_UNSIGNED (TREE_TYPE (var)), |
189 partition_to_var (SA.map, src)))); | 201 var); |
190 | 202 |
191 insert_insn_on_edge (seq, e); | 203 insert_insn_on_edge (seq, e); |
192 } | 204 } |
193 | 205 |
194 /* Insert a copy instruction from expression SRC to partition DEST | 206 /* Insert a copy instruction from expression SRC to partition DEST |
230 if (src_mode != dest_mode) | 242 if (src_mode != dest_mode) |
231 { | 243 { |
232 x = expand_expr (src, NULL, src_mode, EXPAND_NORMAL); | 244 x = expand_expr (src, NULL, src_mode, EXPAND_NORMAL); |
233 x = convert_modes (dest_mode, src_mode, x, unsignedp); | 245 x = convert_modes (dest_mode, src_mode, x, unsignedp); |
234 } | 246 } |
247 else if (src_mode == BLKmode) | |
248 { | |
249 x = SA.partition_to_pseudo[dest]; | |
250 store_expr (src, x, 0, false); | |
251 } | |
235 else | 252 else |
236 x = expand_expr (src, SA.partition_to_pseudo[dest], | 253 x = expand_expr (src, SA.partition_to_pseudo[dest], |
237 dest_mode, EXPAND_NORMAL); | 254 dest_mode, EXPAND_NORMAL); |
238 | 255 |
239 if (x != SA.partition_to_pseudo[dest]) | 256 if (x != SA.partition_to_pseudo[dest]) |
267 set_location_for_edge (e); | 284 set_location_for_edge (e); |
268 /* If a locus is provided, override the default. */ | 285 /* If a locus is provided, override the default. */ |
269 if (locus) | 286 if (locus) |
270 set_curr_insn_source_location (locus); | 287 set_curr_insn_source_location (locus); |
271 | 288 |
289 /* We give the destination as sizeexp in case src/dest are BLKmode | |
290 mems. Usually we give the source. As we result from SSA names | |
291 the left and right size should be the same (and no WITH_SIZE_EXPR | |
292 involved), so it doesn't matter. */ | |
272 seq = emit_partition_copy (SA.partition_to_pseudo[dest], | 293 seq = emit_partition_copy (SA.partition_to_pseudo[dest], |
273 src, | 294 src, unsignedsrcp, |
274 unsignedsrcp); | 295 partition_to_var (SA.map, dest)); |
275 | 296 |
276 insert_insn_on_edge (seq, e); | 297 insert_insn_on_edge (seq, e); |
277 } | 298 } |
278 | 299 |
279 /* Insert a copy instruction from partition SRC to RTL lvalue DEST | 300 /* Insert a copy instruction from partition SRC to RTL lvalue DEST |
280 onto edge E. */ | 301 onto edge E. */ |
281 | 302 |
282 static void | 303 static void |
283 insert_part_to_rtx_on_edge (edge e, rtx dest, int src, source_location locus) | 304 insert_part_to_rtx_on_edge (edge e, rtx dest, int src, source_location locus) |
284 { | 305 { |
306 tree var; | |
285 rtx seq; | 307 rtx seq; |
286 if (dump_file && (dump_flags & TDF_DETAILS)) | 308 if (dump_file && (dump_flags & TDF_DETAILS)) |
287 { | 309 { |
288 fprintf (dump_file, | 310 fprintf (dump_file, |
289 "Inserting a temp copy on edge BB%d->BB%d : ", | 311 "Inserting a temp copy on edge BB%d->BB%d : ", |
298 set_location_for_edge (e); | 320 set_location_for_edge (e); |
299 /* If a locus is provided, override the default. */ | 321 /* If a locus is provided, override the default. */ |
300 if (locus) | 322 if (locus) |
301 set_curr_insn_source_location (locus); | 323 set_curr_insn_source_location (locus); |
302 | 324 |
325 var = partition_to_var (SA.map, src); | |
303 seq = emit_partition_copy (dest, | 326 seq = emit_partition_copy (dest, |
304 SA.partition_to_pseudo[src], | 327 SA.partition_to_pseudo[src], |
305 TYPE_UNSIGNED (TREE_TYPE ( | 328 TYPE_UNSIGNED (TREE_TYPE (var)), |
306 partition_to_var (SA.map, src)))); | 329 var); |
307 | 330 |
308 insert_insn_on_edge (seq, e); | 331 insert_insn_on_edge (seq, e); |
309 } | 332 } |
310 | 333 |
311 | 334 |
429 for (x_ = 0; x_ < VEC_length (int, (GRAPH)->edge_list); x_ += 2) \ | 452 for (x_ = 0; x_ < VEC_length (int, (GRAPH)->edge_list); x_ += 2) \ |
430 { \ | 453 { \ |
431 y_ = VEC_index (int, (GRAPH)->edge_list, x_); \ | 454 y_ = VEC_index (int, (GRAPH)->edge_list, x_); \ |
432 if (y_ != (NODE)) \ | 455 if (y_ != (NODE)) \ |
433 continue; \ | 456 continue; \ |
434 (VAR) = VEC_index (int, (GRAPH)->edge_list, x_ + 1); \ | 457 (void) ((VAR) = VEC_index (int, (GRAPH)->edge_list, x_ + 1)); \ |
435 (LOCUS) = VEC_index (source_location, (GRAPH)->edge_locus, x_ / 2); \ | 458 (void) ((LOCUS) = VEC_index (source_location, \ |
459 (GRAPH)->edge_locus, x_ / 2)); \ | |
436 CODE; \ | 460 CODE; \ |
437 } \ | 461 } \ |
438 } while (0) | 462 } while (0) |
439 | 463 |
440 | 464 |
449 for (x_ = 0; x_ < VEC_length (int, (GRAPH)->edge_list); x_ += 2) \ | 473 for (x_ = 0; x_ < VEC_length (int, (GRAPH)->edge_list); x_ += 2) \ |
450 { \ | 474 { \ |
451 y_ = VEC_index (int, (GRAPH)->edge_list, x_ + 1); \ | 475 y_ = VEC_index (int, (GRAPH)->edge_list, x_ + 1); \ |
452 if (y_ != (NODE)) \ | 476 if (y_ != (NODE)) \ |
453 continue; \ | 477 continue; \ |
454 (VAR) = VEC_index (int, (GRAPH)->edge_list, x_); \ | 478 (void) ((VAR) = VEC_index (int, (GRAPH)->edge_list, x_)); \ |
455 (LOCUS) = VEC_index (source_location, (GRAPH)->edge_locus, x_ / 2); \ | 479 (void) ((LOCUS) = VEC_index (source_location, \ |
480 (GRAPH)->edge_locus, x_ / 2)); \ | |
456 CODE; \ | 481 CODE; \ |
457 } \ | 482 } \ |
458 } while (0) | 483 } while (0) |
459 | 484 |
460 | 485 |
954 return false; | 979 return false; |
955 | 980 |
956 FOR_EACH_IMM_USE_FAST (use, imm_iter, result) | 981 FOR_EACH_IMM_USE_FAST (use, imm_iter, result) |
957 { | 982 { |
958 gimple use_stmt = USE_STMT (use); | 983 gimple use_stmt = USE_STMT (use); |
984 if (is_gimple_debug (use_stmt)) | |
985 continue; | |
959 /* Now, if there's a use of RESULT that lies outside this basic block, | 986 /* Now, if there's a use of RESULT that lies outside this basic block, |
960 then there surely is a conflict with ARG. */ | 987 then there surely is a conflict with ARG. */ |
961 if (gimple_bb (use_stmt) != bb) | 988 if (gimple_bb (use_stmt) != bb) |
962 return true; | 989 return true; |
963 if (gimple_code (use_stmt) == GIMPLE_PHI) | 990 if (gimple_code (use_stmt) == GIMPLE_PHI) |