Mercurial > hg > CbC > CbC_gcc
comparison gcc/tree-ssa-phiprop.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
comparison
equal
deleted
inserted
replaced
65:65488c3d617d | 67:f6334be47118 |
---|---|
24 #include "tm.h" | 24 #include "tm.h" |
25 #include "tree.h" | 25 #include "tree.h" |
26 #include "tm_p.h" | 26 #include "tm_p.h" |
27 #include "basic-block.h" | 27 #include "basic-block.h" |
28 #include "timevar.h" | 28 #include "timevar.h" |
29 #include "diagnostic.h" | |
30 #include "tree-pretty-print.h" | 29 #include "tree-pretty-print.h" |
31 #include "gimple-pretty-print.h" | 30 #include "gimple-pretty-print.h" |
32 #include "tree-flow.h" | 31 #include "tree-flow.h" |
33 #include "tree-pass.h" | 32 #include "tree-pass.h" |
34 #include "tree-dump.h" | 33 #include "tree-dump.h" |
138 gimple new_phi; | 137 gimple new_phi; |
139 edge_iterator ei; | 138 edge_iterator ei; |
140 edge e; | 139 edge e; |
141 | 140 |
142 gcc_assert (is_gimple_assign (use_stmt) | 141 gcc_assert (is_gimple_assign (use_stmt) |
143 && gimple_assign_rhs_code (use_stmt) == INDIRECT_REF); | 142 && gimple_assign_rhs_code (use_stmt) == MEM_REF); |
144 | 143 |
145 /* Build a new PHI node to replace the definition of | 144 /* Build a new PHI node to replace the definition of |
146 the indirect reference lhs. */ | 145 the indirect reference lhs. */ |
147 res = gimple_assign_lhs (use_stmt); | 146 res = gimple_assign_lhs (use_stmt); |
148 SSA_NAME_DEF_STMT (res) = new_phi = create_phi_node (res, bb); | 147 SSA_NAME_DEF_STMT (res) = new_phi = create_phi_node (res, bb); |
186 /* Reuse a formerly created dereference. */ | 185 /* Reuse a formerly created dereference. */ |
187 new_var = phivn[SSA_NAME_VERSION (old_arg)].value; | 186 new_var = phivn[SSA_NAME_VERSION (old_arg)].value; |
188 } | 187 } |
189 else | 188 else |
190 { | 189 { |
190 tree rhs = gimple_assign_rhs1 (use_stmt); | |
191 gcc_assert (TREE_CODE (old_arg) == ADDR_EXPR); | 191 gcc_assert (TREE_CODE (old_arg) == ADDR_EXPR); |
192 old_arg = TREE_OPERAND (old_arg, 0); | 192 new_var = create_tmp_reg (TREE_TYPE (rhs), NULL); |
193 new_var = create_tmp_reg (TREE_TYPE (old_arg), NULL); | 193 if (!is_gimple_min_invariant (old_arg)) |
194 tmp = gimple_build_assign (new_var, unshare_expr (old_arg)); | 194 old_arg = PHI_ARG_DEF_FROM_EDGE (phi, e); |
195 else | |
196 old_arg = unshare_expr (old_arg); | |
197 tmp = gimple_build_assign (new_var, | |
198 fold_build2 (MEM_REF, TREE_TYPE (rhs), | |
199 old_arg, | |
200 TREE_OPERAND (rhs, 1))); | |
195 gcc_assert (is_gimple_reg (new_var)); | 201 gcc_assert (is_gimple_reg (new_var)); |
196 add_referenced_var (new_var); | 202 add_referenced_var (new_var); |
197 new_var = make_ssa_name (new_var, tmp); | 203 new_var = make_ssa_name (new_var, tmp); |
198 gimple_assign_set_lhs (tmp, new_var); | 204 gimple_assign_set_lhs (tmp, new_var); |
199 gimple_set_location (tmp, locus); | 205 gimple_set_location (tmp, locus); |
245 gimple_stmt_iterator gsi; | 251 gimple_stmt_iterator gsi; |
246 imm_use_iterator ui; | 252 imm_use_iterator ui; |
247 use_operand_p arg_p, use; | 253 use_operand_p arg_p, use; |
248 ssa_op_iter i; | 254 ssa_op_iter i; |
249 bool phi_inserted; | 255 bool phi_inserted; |
256 tree type = NULL_TREE; | |
257 bool one_invariant = false; | |
250 | 258 |
251 if (!POINTER_TYPE_P (TREE_TYPE (ptr)) | 259 if (!POINTER_TYPE_P (TREE_TYPE (ptr)) |
252 || !is_gimple_reg_type (TREE_TYPE (TREE_TYPE (ptr)))) | 260 || !is_gimple_reg_type (TREE_TYPE (TREE_TYPE (ptr)))) |
253 return false; | 261 return false; |
254 | 262 |
267 gimple def_stmt = SSA_NAME_DEF_STMT (arg); | 275 gimple def_stmt = SSA_NAME_DEF_STMT (arg); |
268 if (!gimple_assign_single_p (def_stmt)) | 276 if (!gimple_assign_single_p (def_stmt)) |
269 return false; | 277 return false; |
270 arg = gimple_assign_rhs1 (def_stmt); | 278 arg = gimple_assign_rhs1 (def_stmt); |
271 } | 279 } |
272 if ((TREE_CODE (arg) != ADDR_EXPR | 280 if (TREE_CODE (arg) != ADDR_EXPR |
273 /* Avoid to have to decay *&a to a[0] later. */ | |
274 || !is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (arg, 0)))) | |
275 && !(TREE_CODE (arg) == SSA_NAME | 281 && !(TREE_CODE (arg) == SSA_NAME |
276 && SSA_NAME_VERSION (arg) < n | 282 && SSA_NAME_VERSION (arg) < n |
277 && phivn[SSA_NAME_VERSION (arg)].value != NULL_TREE | 283 && phivn[SSA_NAME_VERSION (arg)].value != NULL_TREE |
284 && (!type | |
285 || types_compatible_p | |
286 (type, TREE_TYPE (phivn[SSA_NAME_VERSION (arg)].value))) | |
278 && phivn_valid_p (phivn, arg, bb))) | 287 && phivn_valid_p (phivn, arg, bb))) |
279 return false; | 288 return false; |
289 if (!type | |
290 && TREE_CODE (arg) == SSA_NAME) | |
291 type = TREE_TYPE (phivn[SSA_NAME_VERSION (arg)].value); | |
292 if (TREE_CODE (arg) == ADDR_EXPR | |
293 && is_gimple_min_invariant (arg)) | |
294 one_invariant = true; | |
280 } | 295 } |
296 | |
297 /* If we neither have an address of a decl nor can reuse a previously | |
298 inserted load, do not hoist anything. */ | |
299 if (!one_invariant | |
300 && !type) | |
301 return false; | |
281 | 302 |
282 /* Find a dereferencing use. First follow (single use) ssa | 303 /* Find a dereferencing use. First follow (single use) ssa |
283 copy chains for ptr. */ | 304 copy chains for ptr. */ |
284 while (single_imm_use (ptr, &use, &use_stmt) | 305 while (single_imm_use (ptr, &use, &use_stmt) |
285 && gimple_assign_ssa_name_copy_p (use_stmt)) | 306 && gimple_assign_ssa_name_copy_p (use_stmt)) |
294 tree vuse; | 315 tree vuse; |
295 | 316 |
296 /* Check whether this is a load of *ptr. */ | 317 /* Check whether this is a load of *ptr. */ |
297 if (!(is_gimple_assign (use_stmt) | 318 if (!(is_gimple_assign (use_stmt) |
298 && TREE_CODE (gimple_assign_lhs (use_stmt)) == SSA_NAME | 319 && TREE_CODE (gimple_assign_lhs (use_stmt)) == SSA_NAME |
299 && gimple_assign_rhs_code (use_stmt) == INDIRECT_REF | 320 && gimple_assign_rhs_code (use_stmt) == MEM_REF |
300 && TREE_OPERAND (gimple_assign_rhs1 (use_stmt), 0) == ptr | 321 && TREE_OPERAND (gimple_assign_rhs1 (use_stmt), 0) == ptr |
322 && integer_zerop (TREE_OPERAND (gimple_assign_rhs1 (use_stmt), 1)) | |
323 && (!type | |
324 || types_compatible_p | |
325 (TREE_TYPE (gimple_assign_lhs (use_stmt)), type)) | |
301 /* We cannot replace a load that may throw or is volatile. */ | 326 /* We cannot replace a load that may throw or is volatile. */ |
302 && !stmt_can_throw_internal (use_stmt))) | 327 && !stmt_can_throw_internal (use_stmt))) |
303 continue; | 328 continue; |
304 | 329 |
305 /* Check if we can move the loads. The def stmt of the virtual use | 330 /* Check if we can move the loads. The def stmt of the virtual use |
315 /* Found a proper dereference. Insert a phi node if this | 340 /* Found a proper dereference. Insert a phi node if this |
316 is the first load transformation. */ | 341 is the first load transformation. */ |
317 if (!phi_inserted) | 342 if (!phi_inserted) |
318 { | 343 { |
319 res = phiprop_insert_phi (bb, phi, use_stmt, phivn, n); | 344 res = phiprop_insert_phi (bb, phi, use_stmt, phivn, n); |
345 type = TREE_TYPE (res); | |
320 | 346 |
321 /* Remember the value we created for *ptr. */ | 347 /* Remember the value we created for *ptr. */ |
322 phivn[SSA_NAME_VERSION (ptr)].value = res; | 348 phivn[SSA_NAME_VERSION (ptr)].value = res; |
323 phivn[SSA_NAME_VERSION (ptr)].vuse = vuse; | 349 phivn[SSA_NAME_VERSION (ptr)].vuse = vuse; |
324 | 350 |
325 /* Remove old stmt. The phi is taken care of by DCE, if we | 351 /* Remove old stmt. The phi is taken care of by DCE, if we |
326 want to delete it here we also have to delete all intermediate | 352 want to delete it here we also have to delete all intermediate |
327 copies. */ | 353 copies. */ |
328 gsi = gsi_for_stmt (use_stmt); | 354 gsi = gsi_for_stmt (use_stmt); |
329 gsi_remove (&gsi, false); | 355 gsi_remove (&gsi, true); |
330 | 356 |
331 phi_inserted = true; | 357 phi_inserted = true; |
332 } | 358 } |
333 else | 359 else |
334 { | 360 { |
364 phivn = XCNEWVEC (struct phiprop_d, n); | 390 phivn = XCNEWVEC (struct phiprop_d, n); |
365 | 391 |
366 /* Walk the dominator tree in preorder. */ | 392 /* Walk the dominator tree in preorder. */ |
367 bbs = get_all_dominated_blocks (CDI_DOMINATORS, | 393 bbs = get_all_dominated_blocks (CDI_DOMINATORS, |
368 single_succ (ENTRY_BLOCK_PTR)); | 394 single_succ (ENTRY_BLOCK_PTR)); |
369 for (i = 0; VEC_iterate (basic_block, bbs, i, bb); ++i) | 395 FOR_EACH_VEC_ELT (basic_block, bbs, i, bb) |
370 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) | 396 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) |
371 did_something |= propagate_with_phi (bb, gsi_stmt (gsi), phivn, n); | 397 did_something |= propagate_with_phi (bb, gsi_stmt (gsi), phivn, n); |
372 | 398 |
373 if (did_something) | 399 if (did_something) |
374 gsi_commit_edge_inserts (); | 400 gsi_commit_edge_inserts (); |