Mercurial > hg > CbC > CbC_gcc
comparison gcc/tree-ssa-sccvn.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
111:04ced10e8804 | 131:84e7813d76e9 |
---|---|
1 /* SCC value numbering for trees | 1 /* SCC value numbering for trees |
2 Copyright (C) 2006-2017 Free Software Foundation, Inc. | 2 Copyright (C) 2006-2018 Free Software Foundation, Inc. |
3 Contributed by Daniel Berlin <dan@dberlin.org> | 3 Contributed by Daniel Berlin <dan@dberlin.org> |
4 | 4 |
5 This file is part of GCC. | 5 This file is part of GCC. |
6 | 6 |
7 GCC is free software; you can redistribute it and/or modify | 7 GCC is free software; you can redistribute it and/or modify |
23 #include "coretypes.h" | 23 #include "coretypes.h" |
24 #include "backend.h" | 24 #include "backend.h" |
25 #include "rtl.h" | 25 #include "rtl.h" |
26 #include "tree.h" | 26 #include "tree.h" |
27 #include "gimple.h" | 27 #include "gimple.h" |
28 #include "alloc-pool.h" | |
29 #include "ssa.h" | 28 #include "ssa.h" |
30 #include "expmed.h" | 29 #include "expmed.h" |
31 #include "insn-config.h" | 30 #include "insn-config.h" |
32 #include "memmodel.h" | 31 #include "memmodel.h" |
33 #include "emit-rtl.h" | 32 #include "emit-rtl.h" |
126 blocks for equivalence. | 125 blocks for equivalence. |
127 3. We could value number vuses in more cases, particularly, whole | 126 3. We could value number vuses in more cases, particularly, whole |
128 structure copies. | 127 structure copies. |
129 */ | 128 */ |
130 | 129 |
130 /* There's no BB_EXECUTABLE but we can use BB_VISITED. */ | |
131 #define BB_EXECUTABLE BB_VISITED | |
131 | 132 |
132 static tree *last_vuse_ptr; | 133 static tree *last_vuse_ptr; |
133 static vn_lookup_kind vn_walk_kind; | 134 static vn_lookup_kind vn_walk_kind; |
134 static vn_lookup_kind default_vn_walk_kind; | 135 static vn_lookup_kind default_vn_walk_kind; |
135 bitmap const_parms; | |
136 | 136 |
137 /* vn_nary_op hashtable helpers. */ | 137 /* vn_nary_op hashtable helpers. */ |
138 | 138 |
139 struct vn_nary_op_hasher : nofree_ptr_hash <vn_nary_op_s> | 139 struct vn_nary_op_hasher : nofree_ptr_hash <vn_nary_op_s> |
140 { | 140 { |
155 equivalent. */ | 155 equivalent. */ |
156 | 156 |
157 inline bool | 157 inline bool |
158 vn_nary_op_hasher::equal (const vn_nary_op_s *vno1, const vn_nary_op_s *vno2) | 158 vn_nary_op_hasher::equal (const vn_nary_op_s *vno1, const vn_nary_op_s *vno2) |
159 { | 159 { |
160 return vn_nary_op_eq (vno1, vno2); | 160 return vno1 == vno2 || vn_nary_op_eq (vno1, vno2); |
161 } | 161 } |
162 | 162 |
163 typedef hash_table<vn_nary_op_hasher> vn_nary_op_table_type; | 163 typedef hash_table<vn_nary_op_hasher> vn_nary_op_table_type; |
164 typedef vn_nary_op_table_type::iterator vn_nary_op_iterator_type; | 164 typedef vn_nary_op_table_type::iterator vn_nary_op_iterator_type; |
165 | 165 |
167 /* vn_phi hashtable helpers. */ | 167 /* vn_phi hashtable helpers. */ |
168 | 168 |
169 static int | 169 static int |
170 vn_phi_eq (const_vn_phi_t const vp1, const_vn_phi_t const vp2); | 170 vn_phi_eq (const_vn_phi_t const vp1, const_vn_phi_t const vp2); |
171 | 171 |
172 struct vn_phi_hasher : pointer_hash <vn_phi_s> | 172 struct vn_phi_hasher : nofree_ptr_hash <vn_phi_s> |
173 { | 173 { |
174 static inline hashval_t hash (const vn_phi_s *); | 174 static inline hashval_t hash (const vn_phi_s *); |
175 static inline bool equal (const vn_phi_s *, const vn_phi_s *); | 175 static inline bool equal (const vn_phi_s *, const vn_phi_s *); |
176 static inline void remove (vn_phi_s *); | |
177 }; | 176 }; |
178 | 177 |
179 /* Return the computed hashcode for phi operation P1. */ | 178 /* Return the computed hashcode for phi operation P1. */ |
180 | 179 |
181 inline hashval_t | 180 inline hashval_t |
187 /* Compare two phi entries for equality, ignoring VN_TOP arguments. */ | 186 /* Compare two phi entries for equality, ignoring VN_TOP arguments. */ |
188 | 187 |
189 inline bool | 188 inline bool |
190 vn_phi_hasher::equal (const vn_phi_s *vp1, const vn_phi_s *vp2) | 189 vn_phi_hasher::equal (const vn_phi_s *vp1, const vn_phi_s *vp2) |
191 { | 190 { |
192 return vn_phi_eq (vp1, vp2); | 191 return vp1 == vp2 || vn_phi_eq (vp1, vp2); |
193 } | |
194 | |
195 /* Free a phi operation structure VP. */ | |
196 | |
197 inline void | |
198 vn_phi_hasher::remove (vn_phi_s *phi) | |
199 { | |
200 phi->phiargs.release (); | |
201 } | 192 } |
202 | 193 |
203 typedef hash_table<vn_phi_hasher> vn_phi_table_type; | 194 typedef hash_table<vn_phi_hasher> vn_phi_table_type; |
204 typedef vn_phi_table_type::iterator vn_phi_iterator_type; | 195 typedef vn_phi_table_type::iterator vn_phi_iterator_type; |
205 | 196 |
233 } | 224 } |
234 | 225 |
235 | 226 |
236 /* vn_reference hashtable helpers. */ | 227 /* vn_reference hashtable helpers. */ |
237 | 228 |
238 struct vn_reference_hasher : pointer_hash <vn_reference_s> | 229 struct vn_reference_hasher : nofree_ptr_hash <vn_reference_s> |
239 { | 230 { |
240 static inline hashval_t hash (const vn_reference_s *); | 231 static inline hashval_t hash (const vn_reference_s *); |
241 static inline bool equal (const vn_reference_s *, const vn_reference_s *); | 232 static inline bool equal (const vn_reference_s *, const vn_reference_s *); |
242 static inline void remove (vn_reference_s *); | |
243 }; | 233 }; |
244 | 234 |
245 /* Return the hashcode for a given reference operation P1. */ | 235 /* Return the hashcode for a given reference operation P1. */ |
246 | 236 |
247 inline hashval_t | 237 inline hashval_t |
251 } | 241 } |
252 | 242 |
253 inline bool | 243 inline bool |
254 vn_reference_hasher::equal (const vn_reference_s *v, const vn_reference_s *c) | 244 vn_reference_hasher::equal (const vn_reference_s *v, const vn_reference_s *c) |
255 { | 245 { |
256 return vn_reference_eq (v, c); | 246 return v == c || vn_reference_eq (v, c); |
257 } | |
258 | |
259 inline void | |
260 vn_reference_hasher::remove (vn_reference_s *v) | |
261 { | |
262 free_reference (v); | |
263 } | 247 } |
264 | 248 |
265 typedef hash_table<vn_reference_hasher> vn_reference_table_type; | 249 typedef hash_table<vn_reference_hasher> vn_reference_table_type; |
266 typedef vn_reference_table_type::iterator vn_reference_iterator_type; | 250 typedef vn_reference_table_type::iterator vn_reference_iterator_type; |
267 | 251 |
268 | 252 |
269 /* The set of hashtables and alloc_pool's for their items. */ | 253 /* The set of VN hashtables. */ |
270 | 254 |
271 typedef struct vn_tables_s | 255 typedef struct vn_tables_s |
272 { | 256 { |
273 vn_nary_op_table_type *nary; | 257 vn_nary_op_table_type *nary; |
274 vn_phi_table_type *phis; | 258 vn_phi_table_type *phis; |
275 vn_reference_table_type *references; | 259 vn_reference_table_type *references; |
276 struct obstack nary_obstack; | |
277 object_allocator<vn_phi_s> *phis_pool; | |
278 object_allocator<vn_reference_s> *references_pool; | |
279 } *vn_tables_t; | 260 } *vn_tables_t; |
280 | 261 |
281 | 262 |
282 /* vn_constant hashtable helpers. */ | 263 /* vn_constant hashtable helpers. */ |
283 | 264 |
308 | 289 |
309 static hash_table<vn_constant_hasher> *constant_to_value_id; | 290 static hash_table<vn_constant_hasher> *constant_to_value_id; |
310 static bitmap constant_value_ids; | 291 static bitmap constant_value_ids; |
311 | 292 |
312 | 293 |
294 /* Obstack we allocate the vn-tables elements from. */ | |
295 static obstack vn_tables_obstack; | |
296 /* Special obstack we never unwind. */ | |
297 static obstack vn_tables_insert_obstack; | |
298 | |
299 static vn_reference_t last_inserted_ref; | |
300 static vn_phi_t last_inserted_phi; | |
301 static vn_nary_op_t last_inserted_nary; | |
302 | |
313 /* Valid hashtables storing information we have proven to be | 303 /* Valid hashtables storing information we have proven to be |
314 correct. */ | 304 correct. */ |
315 | |
316 static vn_tables_t valid_info; | 305 static vn_tables_t valid_info; |
317 | 306 |
318 /* Optimistic hashtables storing information we are making assumptions about | 307 |
319 during iterations. */ | 308 /* Valueization hook. Valueize NAME if it is an SSA name, otherwise |
320 | 309 just return it. */ |
321 static vn_tables_t optimistic_info; | 310 tree (*vn_valueize) (tree); |
322 | 311 |
323 /* Pointer to the set of hashtables that is currently being used. | 312 |
324 Should always point to either the optimistic_info, or the | 313 /* This represents the top of the VN lattice, which is the universal |
325 valid_info. */ | 314 value. */ |
326 | 315 |
327 static vn_tables_t current_info; | 316 tree VN_TOP; |
328 | 317 |
329 | 318 /* Unique counter for our value ids. */ |
330 /* Reverse post order index for each basic block. */ | 319 |
331 | 320 static unsigned int next_value_id; |
332 static int *rpo_numbers; | 321 |
333 | 322 |
334 #define SSA_VAL(x) (VN_INFO ((x))->valnum) | 323 /* Table of vn_ssa_aux_t's, one per ssa_name. The vn_ssa_aux_t objects |
324 are allocated on an obstack for locality reasons, and to free them | |
325 without looping over the vec. */ | |
326 | |
327 struct vn_ssa_aux_hasher : typed_noop_remove <vn_ssa_aux_t> | |
328 { | |
329 typedef vn_ssa_aux_t value_type; | |
330 typedef tree compare_type; | |
331 static inline hashval_t hash (const value_type &); | |
332 static inline bool equal (const value_type &, const compare_type &); | |
333 static inline void mark_deleted (value_type &) {} | |
334 static inline void mark_empty (value_type &e) { e = NULL; } | |
335 static inline bool is_deleted (value_type &) { return false; } | |
336 static inline bool is_empty (value_type &e) { return e == NULL; } | |
337 }; | |
338 | |
339 hashval_t | |
340 vn_ssa_aux_hasher::hash (const value_type &entry) | |
341 { | |
342 return SSA_NAME_VERSION (entry->name); | |
343 } | |
344 | |
345 bool | |
346 vn_ssa_aux_hasher::equal (const value_type &entry, const compare_type &name) | |
347 { | |
348 return name == entry->name; | |
349 } | |
350 | |
351 static hash_table<vn_ssa_aux_hasher> *vn_ssa_aux_hash; | |
352 typedef hash_table<vn_ssa_aux_hasher>::iterator vn_ssa_aux_iterator_type; | |
353 static struct obstack vn_ssa_aux_obstack; | |
354 | |
355 static vn_nary_op_t vn_nary_op_insert_stmt (gimple *, tree); | |
356 static unsigned int vn_nary_length_from_stmt (gimple *); | |
357 static vn_nary_op_t alloc_vn_nary_op_noinit (unsigned int, obstack *); | |
358 static vn_nary_op_t vn_nary_op_insert_into (vn_nary_op_t, | |
359 vn_nary_op_table_type *, bool); | |
360 static void init_vn_nary_op_from_stmt (vn_nary_op_t, gimple *); | |
361 static void init_vn_nary_op_from_pieces (vn_nary_op_t, unsigned int, | |
362 enum tree_code, tree, tree *); | |
363 static tree vn_lookup_simplify_result (gimple_match_op *); | |
364 | |
365 /* Return whether there is value numbering information for a given SSA name. */ | |
366 | |
367 bool | |
368 has_VN_INFO (tree name) | |
369 { | |
370 return vn_ssa_aux_hash->find_with_hash (name, SSA_NAME_VERSION (name)); | |
371 } | |
372 | |
373 vn_ssa_aux_t | |
374 VN_INFO (tree name) | |
375 { | |
376 vn_ssa_aux_t *res | |
377 = vn_ssa_aux_hash->find_slot_with_hash (name, SSA_NAME_VERSION (name), | |
378 INSERT); | |
379 if (*res != NULL) | |
380 return *res; | |
381 | |
382 vn_ssa_aux_t newinfo = *res = XOBNEW (&vn_ssa_aux_obstack, struct vn_ssa_aux); | |
383 memset (newinfo, 0, sizeof (struct vn_ssa_aux)); | |
384 newinfo->name = name; | |
385 newinfo->valnum = VN_TOP; | |
386 /* We are using the visited flag to handle uses with defs not within the | |
387 region being value-numbered. */ | |
388 newinfo->visited = false; | |
389 | |
390 /* Given we create the VN_INFOs on-demand now we have to do initialization | |
391 different than VN_TOP here. */ | |
392 if (SSA_NAME_IS_DEFAULT_DEF (name)) | |
393 switch (TREE_CODE (SSA_NAME_VAR (name))) | |
394 { | |
395 case VAR_DECL: | |
396 /* All undefined vars are VARYING. */ | |
397 newinfo->valnum = name; | |
398 newinfo->visited = true; | |
399 break; | |
400 | |
401 case PARM_DECL: | |
402 /* Parameters are VARYING but we can record a condition | |
403 if we know it is a non-NULL pointer. */ | |
404 newinfo->visited = true; | |
405 newinfo->valnum = name; | |
406 if (POINTER_TYPE_P (TREE_TYPE (name)) | |
407 && nonnull_arg_p (SSA_NAME_VAR (name))) | |
408 { | |
409 tree ops[2]; | |
410 ops[0] = name; | |
411 ops[1] = build_int_cst (TREE_TYPE (name), 0); | |
412 vn_nary_op_t nary; | |
413 /* Allocate from non-unwinding stack. */ | |
414 nary = alloc_vn_nary_op_noinit (2, &vn_tables_insert_obstack); | |
415 init_vn_nary_op_from_pieces (nary, 2, NE_EXPR, | |
416 boolean_type_node, ops); | |
417 nary->predicated_values = 0; | |
418 nary->u.result = boolean_true_node; | |
419 vn_nary_op_insert_into (nary, valid_info->nary, true); | |
420 gcc_assert (nary->unwind_to == NULL); | |
421 /* Also do not link it into the undo chain. */ | |
422 last_inserted_nary = nary->next; | |
423 nary->next = (vn_nary_op_t)(void *)-1; | |
424 nary = alloc_vn_nary_op_noinit (2, &vn_tables_insert_obstack); | |
425 init_vn_nary_op_from_pieces (nary, 2, EQ_EXPR, | |
426 boolean_type_node, ops); | |
427 nary->predicated_values = 0; | |
428 nary->u.result = boolean_false_node; | |
429 vn_nary_op_insert_into (nary, valid_info->nary, true); | |
430 gcc_assert (nary->unwind_to == NULL); | |
431 last_inserted_nary = nary->next; | |
432 nary->next = (vn_nary_op_t)(void *)-1; | |
433 if (dump_file && (dump_flags & TDF_DETAILS)) | |
434 { | |
435 fprintf (dump_file, "Recording "); | |
436 print_generic_expr (dump_file, name, TDF_SLIM); | |
437 fprintf (dump_file, " != 0\n"); | |
438 } | |
439 } | |
440 break; | |
441 | |
442 case RESULT_DECL: | |
443 /* If the result is passed by invisible reference the default | |
444 def is initialized, otherwise it's uninitialized. Still | |
445 undefined is varying. */ | |
446 newinfo->visited = true; | |
447 newinfo->valnum = name; | |
448 break; | |
449 | |
450 default: | |
451 gcc_unreachable (); | |
452 } | |
453 return newinfo; | |
454 } | |
455 | |
456 /* Return the SSA value of X. */ | |
457 | |
458 inline tree | |
459 SSA_VAL (tree x, bool *visited = NULL) | |
460 { | |
461 vn_ssa_aux_t tem = vn_ssa_aux_hash->find_with_hash (x, SSA_NAME_VERSION (x)); | |
462 if (visited) | |
463 *visited = tem && tem->visited; | |
464 return tem && tem->visited ? tem->valnum : x; | |
465 } | |
335 | 466 |
336 /* Return the SSA value of the VUSE x, supporting released VDEFs | 467 /* Return the SSA value of the VUSE x, supporting released VDEFs |
337 during elimination which will value-number the VDEF to the | 468 during elimination which will value-number the VDEF to the |
338 associated VUSE (but not substitute in the whole lattice). */ | 469 associated VUSE (but not substitute in the whole lattice). */ |
339 | 470 |
344 return NULL_TREE; | 475 return NULL_TREE; |
345 | 476 |
346 do | 477 do |
347 { | 478 { |
348 x = SSA_VAL (x); | 479 x = SSA_VAL (x); |
480 gcc_assert (x != VN_TOP); | |
349 } | 481 } |
350 while (SSA_NAME_IN_FREE_LIST (x)); | 482 while (SSA_NAME_IN_FREE_LIST (x)); |
351 | 483 |
352 return x; | 484 return x; |
353 } | 485 } |
354 | 486 |
355 /* This represents the top of the VN lattice, which is the universal | 487 /* Similar to the above but used as callback for walk_non_aliases_vuses |
356 value. */ | 488 and thus should stop at unvisited VUSE to not walk across region |
357 | 489 boundaries. */ |
358 tree VN_TOP; | 490 |
359 | 491 static tree |
360 /* Unique counter for our value ids. */ | 492 vuse_valueize (tree vuse) |
361 | 493 { |
362 static unsigned int next_value_id; | 494 do |
363 | 495 { |
364 /* Next DFS number and the stack for strongly connected component | 496 bool visited; |
365 detection. */ | 497 vuse = SSA_VAL (vuse, &visited); |
366 | 498 if (!visited) |
367 static unsigned int next_dfs_num; | 499 return NULL_TREE; |
368 static vec<tree> sccstack; | 500 gcc_assert (vuse != VN_TOP); |
369 | 501 } |
370 | 502 while (SSA_NAME_IN_FREE_LIST (vuse)); |
371 | 503 return vuse; |
372 /* Table of vn_ssa_aux_t's, one per ssa_name. The vn_ssa_aux_t objects | |
373 are allocated on an obstack for locality reasons, and to free them | |
374 without looping over the vec. */ | |
375 | |
376 static vec<vn_ssa_aux_t> vn_ssa_aux_table; | |
377 static struct obstack vn_ssa_aux_obstack; | |
378 | |
379 /* Return whether there is value numbering information for a given SSA name. */ | |
380 | |
381 bool | |
382 has_VN_INFO (tree name) | |
383 { | |
384 if (SSA_NAME_VERSION (name) < vn_ssa_aux_table.length ()) | |
385 return vn_ssa_aux_table[SSA_NAME_VERSION (name)] != NULL; | |
386 return false; | |
387 } | |
388 | |
389 /* Return the value numbering information for a given SSA name. */ | |
390 | |
391 vn_ssa_aux_t | |
392 VN_INFO (tree name) | |
393 { | |
394 vn_ssa_aux_t res = vn_ssa_aux_table[SSA_NAME_VERSION (name)]; | |
395 gcc_checking_assert (res); | |
396 return res; | |
397 } | |
398 | |
399 /* Set the value numbering info for a given SSA name to a given | |
400 value. */ | |
401 | |
402 static inline void | |
403 VN_INFO_SET (tree name, vn_ssa_aux_t value) | |
404 { | |
405 vn_ssa_aux_table[SSA_NAME_VERSION (name)] = value; | |
406 } | |
407 | |
408 /* Initialize the value numbering info for a given SSA name. | |
409 This should be called just once for every SSA name. */ | |
410 | |
411 vn_ssa_aux_t | |
412 VN_INFO_GET (tree name) | |
413 { | |
414 vn_ssa_aux_t newinfo; | |
415 | |
416 gcc_assert (SSA_NAME_VERSION (name) >= vn_ssa_aux_table.length () | |
417 || vn_ssa_aux_table[SSA_NAME_VERSION (name)] == NULL); | |
418 newinfo = XOBNEW (&vn_ssa_aux_obstack, struct vn_ssa_aux); | |
419 memset (newinfo, 0, sizeof (struct vn_ssa_aux)); | |
420 if (SSA_NAME_VERSION (name) >= vn_ssa_aux_table.length ()) | |
421 vn_ssa_aux_table.safe_grow_cleared (SSA_NAME_VERSION (name) + 1); | |
422 vn_ssa_aux_table[SSA_NAME_VERSION (name)] = newinfo; | |
423 return newinfo; | |
424 } | 504 } |
425 | 505 |
426 | 506 |
427 /* Return the vn_kind the expression computed by the stmt should be | 507 /* Return the vn_kind the expression computed by the stmt should be |
428 associated with. */ | 508 associated with. */ |
507 { | 587 { |
508 vn_constant_s **slot; | 588 vn_constant_s **slot; |
509 struct vn_constant_s vc; | 589 struct vn_constant_s vc; |
510 vn_constant_t vcp; | 590 vn_constant_t vcp; |
511 | 591 |
592 /* If the hashtable isn't initialized we're not running from PRE and thus | |
593 do not need value-ids. */ | |
594 if (!constant_to_value_id) | |
595 return 0; | |
596 | |
512 vc.hashcode = vn_hash_constant_with_type (constant); | 597 vc.hashcode = vn_hash_constant_with_type (constant); |
513 vc.constant = constant; | 598 vc.constant = constant; |
514 slot = constant_to_value_id->find_slot (&vc, INSERT); | 599 slot = constant_to_value_id->find_slot (&vc, INSERT); |
515 if (*slot) | 600 if (*slot) |
516 return (*slot)->value_id; | 601 return (*slot)->value_id; |
553 { | 638 { |
554 inchash::hash hstate; | 639 inchash::hash hstate; |
555 hashval_t result; | 640 hashval_t result; |
556 int i; | 641 int i; |
557 vn_reference_op_t vro; | 642 vn_reference_op_t vro; |
558 HOST_WIDE_INT off = -1; | 643 poly_int64 off = -1; |
559 bool deref = false; | 644 bool deref = false; |
560 | 645 |
561 FOR_EACH_VEC_ELT (vr1->operands, i, vro) | 646 FOR_EACH_VEC_ELT (vr1->operands, i, vro) |
562 { | 647 { |
563 if (vro->opcode == MEM_REF) | 648 if (vro->opcode == MEM_REF) |
564 deref = true; | 649 deref = true; |
565 else if (vro->opcode != ADDR_EXPR) | 650 else if (vro->opcode != ADDR_EXPR) |
566 deref = false; | 651 deref = false; |
567 if (vro->off != -1) | 652 if (maybe_ne (vro->off, -1)) |
568 { | 653 { |
569 if (off == -1) | 654 if (known_eq (off, -1)) |
570 off = 0; | 655 off = 0; |
571 off += vro->off; | 656 off += vro->off; |
572 } | 657 } |
573 else | 658 else |
574 { | 659 { |
575 if (off != -1 | 660 if (maybe_ne (off, -1) |
576 && off != 0) | 661 && maybe_ne (off, 0)) |
577 hstate.add_int (off); | 662 hstate.add_poly_int (off); |
578 off = -1; | 663 off = -1; |
579 if (deref | 664 if (deref |
580 && vro->opcode == ADDR_EXPR) | 665 && vro->opcode == ADDR_EXPR) |
581 { | 666 { |
582 if (vro->op0) | 667 if (vro->op0) |
638 | 723 |
639 i = 0; | 724 i = 0; |
640 j = 0; | 725 j = 0; |
641 do | 726 do |
642 { | 727 { |
643 HOST_WIDE_INT off1 = 0, off2 = 0; | 728 poly_int64 off1 = 0, off2 = 0; |
644 vn_reference_op_t vro1, vro2; | 729 vn_reference_op_t vro1, vro2; |
645 vn_reference_op_s tem1, tem2; | 730 vn_reference_op_s tem1, tem2; |
646 bool deref1 = false, deref2 = false; | 731 bool deref1 = false, deref2 = false; |
647 for (; vr1->operands.iterate (i, &vro1); i++) | 732 for (; vr1->operands.iterate (i, &vro1); i++) |
648 { | 733 { |
649 if (vro1->opcode == MEM_REF) | 734 if (vro1->opcode == MEM_REF) |
650 deref1 = true; | 735 deref1 = true; |
651 /* Do not look through a storage order barrier. */ | 736 /* Do not look through a storage order barrier. */ |
652 else if (vro1->opcode == VIEW_CONVERT_EXPR && vro1->reverse) | 737 else if (vro1->opcode == VIEW_CONVERT_EXPR && vro1->reverse) |
653 return false; | 738 return false; |
654 if (vro1->off == -1) | 739 if (known_eq (vro1->off, -1)) |
655 break; | 740 break; |
656 off1 += vro1->off; | 741 off1 += vro1->off; |
657 } | 742 } |
658 for (; vr2->operands.iterate (j, &vro2); j++) | 743 for (; vr2->operands.iterate (j, &vro2); j++) |
659 { | 744 { |
660 if (vro2->opcode == MEM_REF) | 745 if (vro2->opcode == MEM_REF) |
661 deref2 = true; | 746 deref2 = true; |
662 /* Do not look through a storage order barrier. */ | 747 /* Do not look through a storage order barrier. */ |
663 else if (vro2->opcode == VIEW_CONVERT_EXPR && vro2->reverse) | 748 else if (vro2->opcode == VIEW_CONVERT_EXPR && vro2->reverse) |
664 return false; | 749 return false; |
665 if (vro2->off == -1) | 750 if (known_eq (vro2->off, -1)) |
666 break; | 751 break; |
667 off2 += vro2->off; | 752 off2 += vro2->off; |
668 } | 753 } |
669 if (off1 != off2) | 754 if (maybe_ne (off1, off2)) |
670 return false; | 755 return false; |
671 if (deref1 && vro1->opcode == ADDR_EXPR) | 756 if (deref1 && vro1->opcode == ADDR_EXPR) |
672 { | 757 { |
673 memset (&tem1, 0, sizeof (tem1)); | 758 memset (&tem1, 0, sizeof (tem1)); |
674 tem1.op0 = TREE_OPERAND (vro1->op0, 0); | 759 tem1.op0 = TREE_OPERAND (vro1->op0, 0); |
759 temp.off = 0; | 844 temp.off = 0; |
760 break; | 845 break; |
761 case MEM_REF: | 846 case MEM_REF: |
762 /* The base address gets its own vn_reference_op_s structure. */ | 847 /* The base address gets its own vn_reference_op_s structure. */ |
763 temp.op0 = TREE_OPERAND (ref, 1); | 848 temp.op0 = TREE_OPERAND (ref, 1); |
764 { | 849 if (!mem_ref_offset (ref).to_shwi (&temp.off)) |
765 offset_int off = mem_ref_offset (ref); | 850 temp.off = -1; |
766 if (wi::fits_shwi_p (off)) | |
767 temp.off = off.to_shwi (); | |
768 } | |
769 temp.clique = MR_DEPENDENCE_CLIQUE (ref); | 851 temp.clique = MR_DEPENDENCE_CLIQUE (ref); |
770 temp.base = MR_DEPENDENCE_BASE (ref); | 852 temp.base = MR_DEPENDENCE_BASE (ref); |
771 temp.reverse = REF_REVERSE_STORAGE_ORDER (ref); | 853 temp.reverse = REF_REVERSE_STORAGE_ORDER (ref); |
772 break; | 854 break; |
773 case BIT_FIELD_REF: | 855 case BIT_FIELD_REF: |
774 /* Record bits, position and storage order. */ | 856 /* Record bits, position and storage order. */ |
775 temp.op0 = TREE_OPERAND (ref, 1); | 857 temp.op0 = TREE_OPERAND (ref, 1); |
776 temp.op1 = TREE_OPERAND (ref, 2); | 858 temp.op1 = TREE_OPERAND (ref, 2); |
777 if (tree_fits_shwi_p (TREE_OPERAND (ref, 2))) | 859 if (!multiple_p (bit_field_offset (ref), BITS_PER_UNIT, &temp.off)) |
778 { | 860 temp.off = -1; |
779 HOST_WIDE_INT off = tree_to_shwi (TREE_OPERAND (ref, 2)); | |
780 if (off % BITS_PER_UNIT == 0) | |
781 temp.off = off / BITS_PER_UNIT; | |
782 } | |
783 temp.reverse = REF_REVERSE_STORAGE_ORDER (ref); | 861 temp.reverse = REF_REVERSE_STORAGE_ORDER (ref); |
784 break; | 862 break; |
785 case COMPONENT_REF: | 863 case COMPONENT_REF: |
786 /* The field decl is enough to unambiguously specify the field, | 864 /* The field decl is enough to unambiguously specify the field, |
787 a matching type is not necessary and a mismatching type | 865 a matching type is not necessary and a mismatching type |
790 temp.op0 = TREE_OPERAND (ref, 1); | 868 temp.op0 = TREE_OPERAND (ref, 1); |
791 temp.op1 = TREE_OPERAND (ref, 2); | 869 temp.op1 = TREE_OPERAND (ref, 2); |
792 { | 870 { |
793 tree this_offset = component_ref_field_offset (ref); | 871 tree this_offset = component_ref_field_offset (ref); |
794 if (this_offset | 872 if (this_offset |
795 && TREE_CODE (this_offset) == INTEGER_CST) | 873 && poly_int_tree_p (this_offset)) |
796 { | 874 { |
797 tree bit_offset = DECL_FIELD_BIT_OFFSET (TREE_OPERAND (ref, 1)); | 875 tree bit_offset = DECL_FIELD_BIT_OFFSET (TREE_OPERAND (ref, 1)); |
798 if (TREE_INT_CST_LOW (bit_offset) % BITS_PER_UNIT == 0) | 876 if (TREE_INT_CST_LOW (bit_offset) % BITS_PER_UNIT == 0) |
799 { | 877 { |
800 offset_int off | 878 poly_offset_int off |
801 = (wi::to_offset (this_offset) | 879 = (wi::to_poly_offset (this_offset) |
802 + (wi::to_offset (bit_offset) >> LOG2_BITS_PER_UNIT)); | 880 + (wi::to_offset (bit_offset) >> LOG2_BITS_PER_UNIT)); |
803 if (wi::fits_shwi_p (off) | 881 /* Probibit value-numbering zero offset components |
804 /* Probibit value-numbering zero offset components | 882 of addresses the same before the pass folding |
805 of addresses the same before the pass folding | 883 __builtin_object_size had a chance to run |
806 __builtin_object_size had a chance to run | 884 (checking cfun->after_inlining does the |
807 (checking cfun->after_inlining does the | 885 trick here). */ |
808 trick here). */ | 886 if (TREE_CODE (orig) != ADDR_EXPR |
809 && (TREE_CODE (orig) != ADDR_EXPR | 887 || maybe_ne (off, 0) |
810 || off != 0 | 888 || cfun->after_inlining) |
811 || cfun->after_inlining)) | 889 off.to_shwi (&temp.off); |
812 temp.off = off.to_shwi (); | |
813 } | 890 } |
814 } | 891 } |
815 } | 892 } |
816 break; | 893 break; |
817 case ARRAY_RANGE_REF: | 894 case ARRAY_RANGE_REF: |
826 temp.op2 = TREE_OPERAND (ref, 3); | 903 temp.op2 = TREE_OPERAND (ref, 3); |
827 temp.align = eltype->type_common.align; | 904 temp.align = eltype->type_common.align; |
828 if (! temp.op2) | 905 if (! temp.op2) |
829 temp.op2 = size_binop (EXACT_DIV_EXPR, TYPE_SIZE_UNIT (eltype), | 906 temp.op2 = size_binop (EXACT_DIV_EXPR, TYPE_SIZE_UNIT (eltype), |
830 size_int (TYPE_ALIGN_UNIT (eltype))); | 907 size_int (TYPE_ALIGN_UNIT (eltype))); |
831 if (TREE_CODE (temp.op0) == INTEGER_CST | 908 if (poly_int_tree_p (temp.op0) |
832 && TREE_CODE (temp.op1) == INTEGER_CST | 909 && poly_int_tree_p (temp.op1) |
833 && TREE_CODE (temp.op2) == INTEGER_CST) | 910 && TREE_CODE (temp.op2) == INTEGER_CST) |
834 { | 911 { |
835 offset_int off = ((wi::to_offset (temp.op0) | 912 poly_offset_int off = ((wi::to_poly_offset (temp.op0) |
836 - wi::to_offset (temp.op1)) | 913 - wi::to_poly_offset (temp.op1)) |
837 * wi::to_offset (temp.op2) | 914 * wi::to_offset (temp.op2) |
838 * vn_ref_op_align_unit (&temp)); | 915 * vn_ref_op_align_unit (&temp)); |
839 if (wi::fits_shwi_p (off)) | 916 off.to_shwi (&temp.off); |
840 temp.off = off.to_shwi(); | |
841 } | 917 } |
842 } | 918 } |
843 break; | 919 break; |
844 case VAR_DECL: | 920 case VAR_DECL: |
845 if (DECL_HARD_REGISTER (ref)) | 921 if (DECL_HARD_REGISTER (ref)) |
922 { | 998 { |
923 vn_reference_op_t op; | 999 vn_reference_op_t op; |
924 unsigned i; | 1000 unsigned i; |
925 tree base = NULL_TREE; | 1001 tree base = NULL_TREE; |
926 tree *op0_p = &base; | 1002 tree *op0_p = &base; |
927 offset_int offset = 0; | 1003 poly_offset_int offset = 0; |
928 offset_int max_size; | 1004 poly_offset_int max_size; |
929 offset_int size = -1; | 1005 poly_offset_int size = -1; |
930 tree size_tree = NULL_TREE; | 1006 tree size_tree = NULL_TREE; |
931 alias_set_type base_alias_set = -1; | 1007 alias_set_type base_alias_set = -1; |
932 | 1008 |
933 /* First get the final access size from just the outermost expression. */ | 1009 /* First get the final access size from just the outermost expression. */ |
934 op = &ops[0]; | 1010 op = &ops[0]; |
940 { | 1016 { |
941 machine_mode mode = TYPE_MODE (type); | 1017 machine_mode mode = TYPE_MODE (type); |
942 if (mode == BLKmode) | 1018 if (mode == BLKmode) |
943 size_tree = TYPE_SIZE (type); | 1019 size_tree = TYPE_SIZE (type); |
944 else | 1020 else |
945 size = int (GET_MODE_BITSIZE (mode)); | 1021 size = GET_MODE_BITSIZE (mode); |
946 } | 1022 } |
947 if (size_tree != NULL_TREE | 1023 if (size_tree != NULL_TREE |
948 && TREE_CODE (size_tree) == INTEGER_CST) | 1024 && poly_int_tree_p (size_tree)) |
949 size = wi::to_offset (size_tree); | 1025 size = wi::to_poly_offset (size_tree); |
950 | 1026 |
951 /* Initially, maxsize is the same as the accessed element size. | 1027 /* Initially, maxsize is the same as the accessed element size. |
952 In the following it will only grow (or become -1). */ | 1028 In the following it will only grow (or become -1). */ |
953 max_size = size; | 1029 max_size = size; |
954 | 1030 |
967 && op->op0 | 1043 && op->op0 |
968 && DECL_P (TREE_OPERAND (op->op0, 0))) | 1044 && DECL_P (TREE_OPERAND (op->op0, 0))) |
969 { | 1045 { |
970 vn_reference_op_t pop = &ops[i-1]; | 1046 vn_reference_op_t pop = &ops[i-1]; |
971 base = TREE_OPERAND (op->op0, 0); | 1047 base = TREE_OPERAND (op->op0, 0); |
972 if (pop->off == -1) | 1048 if (known_eq (pop->off, -1)) |
973 { | 1049 { |
974 max_size = -1; | 1050 max_size = -1; |
975 offset = 0; | 1051 offset = 0; |
976 } | 1052 } |
977 else | 1053 else |
1001 op0_p = NULL; | 1077 op0_p = NULL; |
1002 break; | 1078 break; |
1003 | 1079 |
1004 /* And now the usual component-reference style ops. */ | 1080 /* And now the usual component-reference style ops. */ |
1005 case BIT_FIELD_REF: | 1081 case BIT_FIELD_REF: |
1006 offset += wi::to_offset (op->op1); | 1082 offset += wi::to_poly_offset (op->op1); |
1007 break; | 1083 break; |
1008 | 1084 |
1009 case COMPONENT_REF: | 1085 case COMPONENT_REF: |
1010 { | 1086 { |
1011 tree field = op->op0; | 1087 tree field = op->op0; |
1012 /* We do not have a complete COMPONENT_REF tree here so we | 1088 /* We do not have a complete COMPONENT_REF tree here so we |
1013 cannot use component_ref_field_offset. Do the interesting | 1089 cannot use component_ref_field_offset. Do the interesting |
1014 parts manually. */ | 1090 parts manually. */ |
1015 tree this_offset = DECL_FIELD_OFFSET (field); | 1091 tree this_offset = DECL_FIELD_OFFSET (field); |
1016 | 1092 |
1017 if (op->op1 || TREE_CODE (this_offset) != INTEGER_CST) | 1093 if (op->op1 || !poly_int_tree_p (this_offset)) |
1018 max_size = -1; | 1094 max_size = -1; |
1019 else | 1095 else |
1020 { | 1096 { |
1021 offset_int woffset = (wi::to_offset (this_offset) | 1097 poly_offset_int woffset = (wi::to_poly_offset (this_offset) |
1022 << LOG2_BITS_PER_UNIT); | 1098 << LOG2_BITS_PER_UNIT); |
1023 woffset += wi::to_offset (DECL_FIELD_BIT_OFFSET (field)); | 1099 woffset += wi::to_offset (DECL_FIELD_BIT_OFFSET (field)); |
1024 offset += woffset; | 1100 offset += woffset; |
1025 } | 1101 } |
1026 break; | 1102 break; |
1027 } | 1103 } |
1028 | 1104 |
1029 case ARRAY_RANGE_REF: | 1105 case ARRAY_RANGE_REF: |
1030 case ARRAY_REF: | 1106 case ARRAY_REF: |
1031 /* We recorded the lower bound and the element size. */ | 1107 /* We recorded the lower bound and the element size. */ |
1032 if (TREE_CODE (op->op0) != INTEGER_CST | 1108 if (!poly_int_tree_p (op->op0) |
1033 || TREE_CODE (op->op1) != INTEGER_CST | 1109 || !poly_int_tree_p (op->op1) |
1034 || TREE_CODE (op->op2) != INTEGER_CST) | 1110 || TREE_CODE (op->op2) != INTEGER_CST) |
1035 max_size = -1; | 1111 max_size = -1; |
1036 else | 1112 else |
1037 { | 1113 { |
1038 offset_int woffset | 1114 poly_offset_int woffset |
1039 = wi::sext (wi::to_offset (op->op0) - wi::to_offset (op->op1), | 1115 = wi::sext (wi::to_poly_offset (op->op0) |
1116 - wi::to_poly_offset (op->op1), | |
1040 TYPE_PRECISION (TREE_TYPE (op->op0))); | 1117 TYPE_PRECISION (TREE_TYPE (op->op0))); |
1041 woffset *= wi::to_offset (op->op2) * vn_ref_op_align_unit (op); | 1118 woffset *= wi::to_offset (op->op2) * vn_ref_op_align_unit (op); |
1042 woffset <<= LOG2_BITS_PER_UNIT; | 1119 woffset <<= LOG2_BITS_PER_UNIT; |
1043 offset += woffset; | 1120 offset += woffset; |
1044 } | 1121 } |
1079 else | 1156 else |
1080 ref->base_alias_set = get_alias_set (base); | 1157 ref->base_alias_set = get_alias_set (base); |
1081 /* We discount volatiles from value-numbering elsewhere. */ | 1158 /* We discount volatiles from value-numbering elsewhere. */ |
1082 ref->volatile_p = false; | 1159 ref->volatile_p = false; |
1083 | 1160 |
1084 if (!wi::fits_shwi_p (size) || wi::neg_p (size)) | 1161 if (!size.to_shwi (&ref->size) || maybe_lt (ref->size, 0)) |
1085 { | 1162 { |
1086 ref->offset = 0; | 1163 ref->offset = 0; |
1087 ref->size = -1; | 1164 ref->size = -1; |
1088 ref->max_size = -1; | 1165 ref->max_size = -1; |
1089 return true; | 1166 return true; |
1090 } | 1167 } |
1091 | 1168 |
1092 ref->size = size.to_shwi (); | 1169 if (!offset.to_shwi (&ref->offset)) |
1093 | |
1094 if (!wi::fits_shwi_p (offset)) | |
1095 { | 1170 { |
1096 ref->offset = 0; | 1171 ref->offset = 0; |
1097 ref->max_size = -1; | 1172 ref->max_size = -1; |
1098 return true; | 1173 return true; |
1099 } | 1174 } |
1100 | 1175 |
1101 ref->offset = offset.to_shwi (); | 1176 if (!max_size.to_shwi (&ref->max_size) || maybe_lt (ref->max_size, 0)) |
1102 | |
1103 if (!wi::fits_shwi_p (max_size) || wi::neg_p (max_size)) | |
1104 ref->max_size = -1; | 1177 ref->max_size = -1; |
1105 else | |
1106 ref->max_size = max_size.to_shwi (); | |
1107 | 1178 |
1108 return true; | 1179 return true; |
1109 } | 1180 } |
1110 | 1181 |
1111 /* Copy the operations present in load/store/call REF into RESULT, a vector of | 1182 /* Copy the operations present in load/store/call REF into RESULT, a vector of |
1137 memset (&temp, 0, sizeof (temp)); | 1208 memset (&temp, 0, sizeof (temp)); |
1138 temp.type = gimple_call_return_type (call); | 1209 temp.type = gimple_call_return_type (call); |
1139 temp.opcode = CALL_EXPR; | 1210 temp.opcode = CALL_EXPR; |
1140 temp.op0 = gimple_call_fn (call); | 1211 temp.op0 = gimple_call_fn (call); |
1141 temp.op1 = gimple_call_chain (call); | 1212 temp.op1 = gimple_call_chain (call); |
1142 if (stmt_could_throw_p (call) && (lr = lookup_stmt_eh_lp (call)) > 0) | 1213 if (stmt_could_throw_p (cfun, call) && (lr = lookup_stmt_eh_lp (call)) > 0) |
1143 temp.op2 = size_int (lr); | 1214 temp.op2 = size_int (lr); |
1144 temp.off = -1; | 1215 temp.off = -1; |
1145 if (gimple_call_with_bounds_p (call)) | |
1146 temp.with_bounds = 1; | |
1147 result->safe_push (temp); | 1216 result->safe_push (temp); |
1148 | 1217 |
1149 /* Copy the call arguments. As they can be references as well, | 1218 /* Copy the call arguments. As they can be references as well, |
1150 just chain them together. */ | 1219 just chain them together. */ |
1151 for (i = 0; i < gimple_call_num_args (call); ++i) | 1220 for (i = 0; i < gimple_call_num_args (call); ++i) |
1163 { | 1232 { |
1164 unsigned int i = *i_p; | 1233 unsigned int i = *i_p; |
1165 vn_reference_op_t op = &(*ops)[i]; | 1234 vn_reference_op_t op = &(*ops)[i]; |
1166 vn_reference_op_t mem_op = &(*ops)[i - 1]; | 1235 vn_reference_op_t mem_op = &(*ops)[i - 1]; |
1167 tree addr_base; | 1236 tree addr_base; |
1168 HOST_WIDE_INT addr_offset = 0; | 1237 poly_int64 addr_offset = 0; |
1169 | 1238 |
1170 /* The only thing we have to do is from &OBJ.foo.bar add the offset | 1239 /* The only thing we have to do is from &OBJ.foo.bar add the offset |
1171 from .foo.bar to the preceding MEM_REF offset and replace the | 1240 from .foo.bar to the preceding MEM_REF offset and replace the |
1172 address with &OBJ. */ | 1241 address with &OBJ. */ |
1173 addr_base = get_addr_base_and_unit_offset (TREE_OPERAND (op->op0, 0), | 1242 addr_base = get_addr_base_and_unit_offset (TREE_OPERAND (op->op0, 0), |
1174 &addr_offset); | 1243 &addr_offset); |
1175 gcc_checking_assert (addr_base && TREE_CODE (addr_base) != MEM_REF); | 1244 gcc_checking_assert (addr_base && TREE_CODE (addr_base) != MEM_REF); |
1176 if (addr_base != TREE_OPERAND (op->op0, 0)) | 1245 if (addr_base != TREE_OPERAND (op->op0, 0)) |
1177 { | 1246 { |
1178 offset_int off = offset_int::from (wi::to_wide (mem_op->op0), SIGNED); | 1247 poly_offset_int off |
1179 off += addr_offset; | 1248 = (poly_offset_int::from (wi::to_poly_wide (mem_op->op0), |
1249 SIGNED) | |
1250 + addr_offset); | |
1180 mem_op->op0 = wide_int_to_tree (TREE_TYPE (mem_op->op0), off); | 1251 mem_op->op0 = wide_int_to_tree (TREE_TYPE (mem_op->op0), off); |
1181 op->op0 = build_fold_addr_expr (addr_base); | 1252 op->op0 = build_fold_addr_expr (addr_base); |
1182 if (tree_fits_shwi_p (mem_op->op0)) | 1253 if (tree_fits_shwi_p (mem_op->op0)) |
1183 mem_op->off = tree_to_shwi (mem_op->op0); | 1254 mem_op->off = tree_to_shwi (mem_op->op0); |
1184 else | 1255 else |
1197 unsigned int i = *i_p; | 1268 unsigned int i = *i_p; |
1198 vn_reference_op_t op = &(*ops)[i]; | 1269 vn_reference_op_t op = &(*ops)[i]; |
1199 vn_reference_op_t mem_op = &(*ops)[i - 1]; | 1270 vn_reference_op_t mem_op = &(*ops)[i - 1]; |
1200 gimple *def_stmt; | 1271 gimple *def_stmt; |
1201 enum tree_code code; | 1272 enum tree_code code; |
1202 offset_int off; | 1273 poly_offset_int off; |
1203 | 1274 |
1204 def_stmt = SSA_NAME_DEF_STMT (op->op0); | 1275 def_stmt = SSA_NAME_DEF_STMT (op->op0); |
1205 if (!is_gimple_assign (def_stmt)) | 1276 if (!is_gimple_assign (def_stmt)) |
1206 return false; | 1277 return false; |
1207 | 1278 |
1208 code = gimple_assign_rhs_code (def_stmt); | 1279 code = gimple_assign_rhs_code (def_stmt); |
1209 if (code != ADDR_EXPR | 1280 if (code != ADDR_EXPR |
1210 && code != POINTER_PLUS_EXPR) | 1281 && code != POINTER_PLUS_EXPR) |
1211 return false; | 1282 return false; |
1212 | 1283 |
1213 off = offset_int::from (wi::to_wide (mem_op->op0), SIGNED); | 1284 off = poly_offset_int::from (wi::to_poly_wide (mem_op->op0), SIGNED); |
1214 | 1285 |
1215 /* The only thing we have to do is from &OBJ.foo.bar add the offset | 1286 /* The only thing we have to do is from &OBJ.foo.bar add the offset |
1216 from .foo.bar to the preceding MEM_REF offset and replace the | 1287 from .foo.bar to the preceding MEM_REF offset and replace the |
1217 address with &OBJ. */ | 1288 address with &OBJ. */ |
1218 if (code == ADDR_EXPR) | 1289 if (code == ADDR_EXPR) |
1219 { | 1290 { |
1220 tree addr, addr_base; | 1291 tree addr, addr_base; |
1221 HOST_WIDE_INT addr_offset; | 1292 poly_int64 addr_offset; |
1222 | 1293 |
1223 addr = gimple_assign_rhs1 (def_stmt); | 1294 addr = gimple_assign_rhs1 (def_stmt); |
1224 addr_base = get_addr_base_and_unit_offset (TREE_OPERAND (addr, 0), | 1295 addr_base = get_addr_base_and_unit_offset (TREE_OPERAND (addr, 0), |
1225 &addr_offset); | 1296 &addr_offset); |
1226 /* If that didn't work because the address isn't invariant propagate | 1297 /* If that didn't work because the address isn't invariant propagate |
1227 the reference tree from the address operation in case the current | 1298 the reference tree from the address operation in case the current |
1228 dereference isn't offsetted. */ | 1299 dereference isn't offsetted. */ |
1229 if (!addr_base | 1300 if (!addr_base |
1230 && *i_p == ops->length () - 1 | 1301 && *i_p == ops->length () - 1 |
1231 && off == 0 | 1302 && known_eq (off, 0) |
1232 /* This makes us disable this transform for PRE where the | 1303 /* This makes us disable this transform for PRE where the |
1233 reference ops might be also used for code insertion which | 1304 reference ops might be also used for code insertion which |
1234 is invalid. */ | 1305 is invalid. */ |
1235 && default_vn_walk_kind == VN_WALKREWRITE) | 1306 && default_vn_walk_kind == VN_WALKREWRITE) |
1236 { | 1307 { |
1243 && tem[tem.length () - 2].opcode == MEM_REF) | 1314 && tem[tem.length () - 2].opcode == MEM_REF) |
1244 { | 1315 { |
1245 vn_reference_op_t new_mem_op = &tem[tem.length () - 2]; | 1316 vn_reference_op_t new_mem_op = &tem[tem.length () - 2]; |
1246 new_mem_op->op0 | 1317 new_mem_op->op0 |
1247 = wide_int_to_tree (TREE_TYPE (mem_op->op0), | 1318 = wide_int_to_tree (TREE_TYPE (mem_op->op0), |
1248 wi::to_wide (new_mem_op->op0)); | 1319 wi::to_poly_wide (new_mem_op->op0)); |
1249 } | 1320 } |
1250 else | 1321 else |
1251 gcc_assert (tem.last ().opcode == STRING_CST); | 1322 gcc_assert (tem.last ().opcode == STRING_CST); |
1252 ops->pop (); | 1323 ops->pop (); |
1253 ops->pop (); | 1324 ops->pop (); |
1254 ops->safe_splice (tem); | 1325 ops->safe_splice (tem); |
1255 --*i_p; | 1326 --*i_p; |
1256 return true; | 1327 return true; |
1257 } | 1328 } |
1258 if (!addr_base | 1329 if (!addr_base |
1259 || TREE_CODE (addr_base) != MEM_REF) | 1330 || TREE_CODE (addr_base) != MEM_REF |
1331 || (TREE_CODE (TREE_OPERAND (addr_base, 0)) == SSA_NAME | |
1332 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (addr_base, 0)))) | |
1260 return false; | 1333 return false; |
1261 | 1334 |
1262 off += addr_offset; | 1335 off += addr_offset; |
1263 off += mem_ref_offset (addr_base); | 1336 off += mem_ref_offset (addr_base); |
1264 op->op0 = TREE_OPERAND (addr_base, 0); | 1337 op->op0 = TREE_OPERAND (addr_base, 0); |
1267 { | 1340 { |
1268 tree ptr, ptroff; | 1341 tree ptr, ptroff; |
1269 ptr = gimple_assign_rhs1 (def_stmt); | 1342 ptr = gimple_assign_rhs1 (def_stmt); |
1270 ptroff = gimple_assign_rhs2 (def_stmt); | 1343 ptroff = gimple_assign_rhs2 (def_stmt); |
1271 if (TREE_CODE (ptr) != SSA_NAME | 1344 if (TREE_CODE (ptr) != SSA_NAME |
1272 || TREE_CODE (ptroff) != INTEGER_CST) | 1345 || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr) |
1346 /* Make sure to not endlessly recurse. | |
1347 See gcc.dg/tree-ssa/20040408-1.c for an example. Can easily | |
1348 happen when we value-number a PHI to its backedge value. */ | |
1349 || SSA_VAL (ptr) == op->op0 | |
1350 || !poly_int_tree_p (ptroff)) | |
1273 return false; | 1351 return false; |
1274 | 1352 |
1275 off += wi::to_offset (ptroff); | 1353 off += wi::to_poly_offset (ptroff); |
1276 op->op0 = ptr; | 1354 op->op0 = ptr; |
1277 } | 1355 } |
1278 | 1356 |
1279 mem_op->op0 = wide_int_to_tree (TREE_TYPE (mem_op->op0), off); | 1357 mem_op->op0 = wide_int_to_tree (TREE_TYPE (mem_op->op0), off); |
1280 if (tree_fits_shwi_p (mem_op->op0)) | 1358 if (tree_fits_shwi_p (mem_op->op0)) |
1281 mem_op->off = tree_to_shwi (mem_op->op0); | 1359 mem_op->off = tree_to_shwi (mem_op->op0); |
1282 else | 1360 else |
1283 mem_op->off = -1; | 1361 mem_op->off = -1; |
1362 /* ??? Can end up with endless recursion here!? | |
1363 gcc.c-torture/execute/strcmp-1.c */ | |
1284 if (TREE_CODE (op->op0) == SSA_NAME) | 1364 if (TREE_CODE (op->op0) == SSA_NAME) |
1285 op->op0 = SSA_VAL (op->op0); | 1365 op->op0 = SSA_VAL (op->op0); |
1286 if (TREE_CODE (op->op0) != SSA_NAME) | 1366 if (TREE_CODE (op->op0) != SSA_NAME) |
1287 op->opcode = TREE_CODE (op->op0); | 1367 op->opcode = TREE_CODE (op->op0); |
1288 | 1368 |
1307 a call to a builtin function with at most two arguments. */ | 1387 a call to a builtin function with at most two arguments. */ |
1308 op = &operands[0]; | 1388 op = &operands[0]; |
1309 if (op->opcode == CALL_EXPR | 1389 if (op->opcode == CALL_EXPR |
1310 && TREE_CODE (op->op0) == ADDR_EXPR | 1390 && TREE_CODE (op->op0) == ADDR_EXPR |
1311 && TREE_CODE (TREE_OPERAND (op->op0, 0)) == FUNCTION_DECL | 1391 && TREE_CODE (TREE_OPERAND (op->op0, 0)) == FUNCTION_DECL |
1312 && DECL_BUILT_IN (TREE_OPERAND (op->op0, 0)) | 1392 && fndecl_built_in_p (TREE_OPERAND (op->op0, 0)) |
1313 && operands.length () >= 2 | 1393 && operands.length () >= 2 |
1314 && operands.length () <= 3) | 1394 && operands.length () <= 3) |
1315 { | 1395 { |
1316 vn_reference_op_t arg0, arg1 = NULL; | 1396 vn_reference_op_t arg0, arg1 = NULL; |
1317 bool anyconst = false; | 1397 bool anyconst = false; |
1342 } | 1422 } |
1343 } | 1423 } |
1344 | 1424 |
1345 /* Simplify reads from constants or constant initializers. */ | 1425 /* Simplify reads from constants or constant initializers. */ |
1346 else if (BITS_PER_UNIT == 8 | 1426 else if (BITS_PER_UNIT == 8 |
1347 && is_gimple_reg_type (ref->type) | 1427 && COMPLETE_TYPE_P (ref->type) |
1348 && (!INTEGRAL_TYPE_P (ref->type) | 1428 && is_gimple_reg_type (ref->type)) |
1349 || TYPE_PRECISION (ref->type) % BITS_PER_UNIT == 0)) | 1429 { |
1350 { | 1430 poly_int64 off = 0; |
1351 HOST_WIDE_INT off = 0; | |
1352 HOST_WIDE_INT size; | 1431 HOST_WIDE_INT size; |
1353 if (INTEGRAL_TYPE_P (ref->type)) | 1432 if (INTEGRAL_TYPE_P (ref->type)) |
1354 size = TYPE_PRECISION (ref->type); | 1433 size = TYPE_PRECISION (ref->type); |
1434 else if (tree_fits_shwi_p (TYPE_SIZE (ref->type))) | |
1435 size = tree_to_shwi (TYPE_SIZE (ref->type)); | |
1355 else | 1436 else |
1356 size = tree_to_shwi (TYPE_SIZE (ref->type)); | 1437 return NULL_TREE; |
1357 if (size % BITS_PER_UNIT != 0 | 1438 if (size % BITS_PER_UNIT != 0 |
1358 || size > MAX_BITSIZE_MODE_ANY_MODE) | 1439 || size > MAX_BITSIZE_MODE_ANY_MODE) |
1359 return NULL_TREE; | 1440 return NULL_TREE; |
1360 size /= BITS_PER_UNIT; | 1441 size /= BITS_PER_UNIT; |
1361 unsigned i; | 1442 unsigned i; |
1364 if (TREE_CODE_CLASS (operands[i].opcode) == tcc_constant) | 1445 if (TREE_CODE_CLASS (operands[i].opcode) == tcc_constant) |
1365 { | 1446 { |
1366 ++i; | 1447 ++i; |
1367 break; | 1448 break; |
1368 } | 1449 } |
1369 if (operands[i].off == -1) | 1450 if (known_eq (operands[i].off, -1)) |
1370 return NULL_TREE; | 1451 return NULL_TREE; |
1371 off += operands[i].off; | 1452 off += operands[i].off; |
1372 if (operands[i].opcode == MEM_REF) | 1453 if (operands[i].opcode == MEM_REF) |
1373 { | 1454 { |
1374 ++i; | 1455 ++i; |
1381 if (TREE_CODE_CLASS (base->opcode) == tcc_constant) | 1462 if (TREE_CODE_CLASS (base->opcode) == tcc_constant) |
1382 ctor = base->op0; | 1463 ctor = base->op0; |
1383 else if (base->opcode == MEM_REF | 1464 else if (base->opcode == MEM_REF |
1384 && base[1].opcode == ADDR_EXPR | 1465 && base[1].opcode == ADDR_EXPR |
1385 && (TREE_CODE (TREE_OPERAND (base[1].op0, 0)) == VAR_DECL | 1466 && (TREE_CODE (TREE_OPERAND (base[1].op0, 0)) == VAR_DECL |
1386 || TREE_CODE (TREE_OPERAND (base[1].op0, 0)) == CONST_DECL)) | 1467 || TREE_CODE (TREE_OPERAND (base[1].op0, 0)) == CONST_DECL |
1468 || TREE_CODE (TREE_OPERAND (base[1].op0, 0)) == STRING_CST)) | |
1387 { | 1469 { |
1388 decl = TREE_OPERAND (base[1].op0, 0); | 1470 decl = TREE_OPERAND (base[1].op0, 0); |
1389 ctor = ctor_for_folding (decl); | 1471 if (TREE_CODE (decl) == STRING_CST) |
1472 ctor = decl; | |
1473 else | |
1474 ctor = ctor_for_folding (decl); | |
1390 } | 1475 } |
1391 if (ctor == NULL_TREE) | 1476 if (ctor == NULL_TREE) |
1392 return build_zero_cst (ref->type); | 1477 return build_zero_cst (ref->type); |
1393 else if (ctor != error_mark_node) | 1478 else if (ctor != error_mark_node) |
1394 { | 1479 { |
1480 HOST_WIDE_INT const_off; | |
1395 if (decl) | 1481 if (decl) |
1396 { | 1482 { |
1397 tree res = fold_ctor_reference (ref->type, ctor, | 1483 tree res = fold_ctor_reference (ref->type, ctor, |
1398 off * BITS_PER_UNIT, | 1484 off * BITS_PER_UNIT, |
1399 size * BITS_PER_UNIT, decl); | 1485 size * BITS_PER_UNIT, decl); |
1402 STRIP_USELESS_TYPE_CONVERSION (res); | 1488 STRIP_USELESS_TYPE_CONVERSION (res); |
1403 if (is_gimple_min_invariant (res)) | 1489 if (is_gimple_min_invariant (res)) |
1404 return res; | 1490 return res; |
1405 } | 1491 } |
1406 } | 1492 } |
1407 else | 1493 else if (off.is_constant (&const_off)) |
1408 { | 1494 { |
1409 unsigned char buf[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT]; | 1495 unsigned char buf[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT]; |
1410 int len = native_encode_expr (ctor, buf, size, off); | 1496 int len = native_encode_expr (ctor, buf, size, const_off); |
1411 if (len > 0) | 1497 if (len > 0) |
1412 return native_interpret_expr (ref->type, buf, len); | 1498 return native_interpret_expr (ref->type, buf, len); |
1413 } | 1499 } |
1414 } | 1500 } |
1415 } | 1501 } |
1436 structures into their value numbers. This is done in-place, and | 1522 structures into their value numbers. This is done in-place, and |
1437 the vector passed in is returned. *VALUEIZED_ANYTHING will specify | 1523 the vector passed in is returned. *VALUEIZED_ANYTHING will specify |
1438 whether any operands were valueized. */ | 1524 whether any operands were valueized. */ |
1439 | 1525 |
1440 static vec<vn_reference_op_s> | 1526 static vec<vn_reference_op_s> |
1441 valueize_refs_1 (vec<vn_reference_op_s> orig, bool *valueized_anything) | 1527 valueize_refs_1 (vec<vn_reference_op_s> orig, bool *valueized_anything, |
1528 bool with_avail = false) | |
1442 { | 1529 { |
1443 vn_reference_op_t vro; | 1530 vn_reference_op_t vro; |
1444 unsigned int i; | 1531 unsigned int i; |
1445 | 1532 |
1446 *valueized_anything = false; | 1533 *valueized_anything = false; |
1448 FOR_EACH_VEC_ELT (orig, i, vro) | 1535 FOR_EACH_VEC_ELT (orig, i, vro) |
1449 { | 1536 { |
1450 if (vro->opcode == SSA_NAME | 1537 if (vro->opcode == SSA_NAME |
1451 || (vro->op0 && TREE_CODE (vro->op0) == SSA_NAME)) | 1538 || (vro->op0 && TREE_CODE (vro->op0) == SSA_NAME)) |
1452 { | 1539 { |
1453 tree tem = SSA_VAL (vro->op0); | 1540 tree tem = with_avail ? vn_valueize (vro->op0) : SSA_VAL (vro->op0); |
1454 if (tem != vro->op0) | 1541 if (tem != vro->op0) |
1455 { | 1542 { |
1456 *valueized_anything = true; | 1543 *valueized_anything = true; |
1457 vro->op0 = tem; | 1544 vro->op0 = tem; |
1458 } | 1545 } |
1461 if (TREE_CODE (vro->op0) != SSA_NAME && vro->opcode == SSA_NAME) | 1548 if (TREE_CODE (vro->op0) != SSA_NAME && vro->opcode == SSA_NAME) |
1462 vro->opcode = TREE_CODE (vro->op0); | 1549 vro->opcode = TREE_CODE (vro->op0); |
1463 } | 1550 } |
1464 if (vro->op1 && TREE_CODE (vro->op1) == SSA_NAME) | 1551 if (vro->op1 && TREE_CODE (vro->op1) == SSA_NAME) |
1465 { | 1552 { |
1466 tree tem = SSA_VAL (vro->op1); | 1553 tree tem = with_avail ? vn_valueize (vro->op1) : SSA_VAL (vro->op1); |
1467 if (tem != vro->op1) | 1554 if (tem != vro->op1) |
1468 { | 1555 { |
1469 *valueized_anything = true; | 1556 *valueized_anything = true; |
1470 vro->op1 = tem; | 1557 vro->op1 = tem; |
1471 } | 1558 } |
1472 } | 1559 } |
1473 if (vro->op2 && TREE_CODE (vro->op2) == SSA_NAME) | 1560 if (vro->op2 && TREE_CODE (vro->op2) == SSA_NAME) |
1474 { | 1561 { |
1475 tree tem = SSA_VAL (vro->op2); | 1562 tree tem = with_avail ? vn_valueize (vro->op2) : SSA_VAL (vro->op2); |
1476 if (tem != vro->op2) | 1563 if (tem != vro->op2) |
1477 { | 1564 { |
1478 *valueized_anything = true; | 1565 *valueized_anything = true; |
1479 vro->op2 = tem; | 1566 vro->op2 = tem; |
1480 } | 1567 } |
1497 *valueized_anything = true; | 1584 *valueized_anything = true; |
1498 } | 1585 } |
1499 /* If it transforms a non-constant ARRAY_REF into a constant | 1586 /* If it transforms a non-constant ARRAY_REF into a constant |
1500 one, adjust the constant offset. */ | 1587 one, adjust the constant offset. */ |
1501 else if (vro->opcode == ARRAY_REF | 1588 else if (vro->opcode == ARRAY_REF |
1502 && vro->off == -1 | 1589 && known_eq (vro->off, -1) |
1503 && TREE_CODE (vro->op0) == INTEGER_CST | 1590 && poly_int_tree_p (vro->op0) |
1504 && TREE_CODE (vro->op1) == INTEGER_CST | 1591 && poly_int_tree_p (vro->op1) |
1505 && TREE_CODE (vro->op2) == INTEGER_CST) | 1592 && TREE_CODE (vro->op2) == INTEGER_CST) |
1506 { | 1593 { |
1507 offset_int off = ((wi::to_offset (vro->op0) | 1594 poly_offset_int off = ((wi::to_poly_offset (vro->op0) |
1508 - wi::to_offset (vro->op1)) | 1595 - wi::to_poly_offset (vro->op1)) |
1509 * wi::to_offset (vro->op2) | 1596 * wi::to_offset (vro->op2) |
1510 * vn_ref_op_align_unit (vro)); | 1597 * vn_ref_op_align_unit (vro)); |
1511 if (wi::fits_shwi_p (off)) | 1598 off.to_shwi (&vro->off); |
1512 vro->off = off.to_shwi (); | |
1513 } | 1599 } |
1514 } | 1600 } |
1515 | 1601 |
1516 return orig; | 1602 return orig; |
1517 } | 1603 } |
1567 { | 1653 { |
1568 vn_reference_s **slot; | 1654 vn_reference_s **slot; |
1569 hashval_t hash; | 1655 hashval_t hash; |
1570 | 1656 |
1571 hash = vr->hashcode; | 1657 hash = vr->hashcode; |
1572 slot = current_info->references->find_slot_with_hash (vr, hash, NO_INSERT); | 1658 slot = valid_info->references->find_slot_with_hash (vr, hash, NO_INSERT); |
1573 if (!slot && current_info == optimistic_info) | |
1574 slot = valid_info->references->find_slot_with_hash (vr, hash, NO_INSERT); | |
1575 if (slot) | 1659 if (slot) |
1576 { | 1660 { |
1577 if (vnresult) | 1661 if (vnresult) |
1578 *vnresult = (vn_reference_t)*slot; | 1662 *vnresult = (vn_reference_t)*slot; |
1579 return ((vn_reference_t)*slot)->result; | 1663 return ((vn_reference_t)*slot)->result; |
1608 vr->vuse = vuse_ssa_val (vuse); | 1692 vr->vuse = vuse_ssa_val (vuse); |
1609 if (vr->vuse) | 1693 if (vr->vuse) |
1610 vr->hashcode = vr->hashcode + SSA_NAME_VERSION (vr->vuse); | 1694 vr->hashcode = vr->hashcode + SSA_NAME_VERSION (vr->vuse); |
1611 | 1695 |
1612 hash = vr->hashcode; | 1696 hash = vr->hashcode; |
1613 slot = current_info->references->find_slot_with_hash (vr, hash, NO_INSERT); | 1697 slot = valid_info->references->find_slot_with_hash (vr, hash, NO_INSERT); |
1614 if (!slot && current_info == optimistic_info) | |
1615 slot = valid_info->references->find_slot_with_hash (vr, hash, NO_INSERT); | |
1616 if (slot) | 1698 if (slot) |
1617 return *slot; | 1699 return *slot; |
1618 | 1700 |
1619 return NULL; | 1701 return NULL; |
1620 } | 1702 } |
1632 tree value) | 1714 tree value) |
1633 { | 1715 { |
1634 vn_reference_s vr1; | 1716 vn_reference_s vr1; |
1635 vn_reference_t result; | 1717 vn_reference_t result; |
1636 unsigned value_id; | 1718 unsigned value_id; |
1637 vr1.vuse = vuse; | 1719 vr1.vuse = vuse ? SSA_VAL (vuse) : NULL_TREE; |
1638 vr1.operands = operands; | 1720 vr1.operands = operands; |
1639 vr1.type = type; | 1721 vr1.type = type; |
1640 vr1.set = set; | 1722 vr1.set = set; |
1641 vr1.hashcode = vn_reference_compute_hash (&vr1); | 1723 vr1.hashcode = vn_reference_compute_hash (&vr1); |
1642 if (vn_reference_lookup_1 (&vr1, &result)) | 1724 if (vn_reference_lookup_1 (&vr1, &result)) |
1647 value_id = get_or_alloc_constant_value_id (value); | 1729 value_id = get_or_alloc_constant_value_id (value); |
1648 return vn_reference_insert_pieces (vuse, set, type, | 1730 return vn_reference_insert_pieces (vuse, set, type, |
1649 operands.copy (), value, value_id); | 1731 operands.copy (), value, value_id); |
1650 } | 1732 } |
1651 | 1733 |
1652 static vn_nary_op_t vn_nary_op_insert_stmt (gimple *stmt, tree result); | |
1653 static unsigned mprts_hook_cnt; | |
1654 | |
1655 /* Hook for maybe_push_res_to_seq, lookup the expression in the VN tables. */ | |
1656 | |
1657 static tree | |
1658 vn_lookup_simplify_result (code_helper rcode, tree type, tree *ops_) | |
1659 { | |
1660 if (!rcode.is_tree_code ()) | |
1661 return NULL_TREE; | |
1662 tree *ops = ops_; | |
1663 unsigned int length = TREE_CODE_LENGTH ((tree_code) rcode); | |
1664 if (rcode == CONSTRUCTOR | |
1665 /* ??? We're arriving here with SCCVNs view, decomposed CONSTRUCTOR | |
1666 and GIMPLEs / match-and-simplifies, CONSTRUCTOR as GENERIC tree. */ | |
1667 && TREE_CODE (ops_[0]) == CONSTRUCTOR) | |
1668 { | |
1669 length = CONSTRUCTOR_NELTS (ops_[0]); | |
1670 ops = XALLOCAVEC (tree, length); | |
1671 for (unsigned i = 0; i < length; ++i) | |
1672 ops[i] = CONSTRUCTOR_ELT (ops_[0], i)->value; | |
1673 } | |
1674 vn_nary_op_t vnresult = NULL; | |
1675 tree res = vn_nary_op_lookup_pieces (length, (tree_code) rcode, | |
1676 type, ops, &vnresult); | |
1677 /* We can end up endlessly recursing simplifications if the lookup above | |
1678 presents us with a def-use chain that mirrors the original simplification. | |
1679 See PR80887 for an example. Limit successful lookup artificially | |
1680 to 10 times if we are called as mprts_hook. */ | |
1681 if (res | |
1682 && mprts_hook | |
1683 && --mprts_hook_cnt == 0) | |
1684 { | |
1685 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1686 fprintf (dump_file, "Resetting mprts_hook after too many " | |
1687 "invocations.\n"); | |
1688 mprts_hook = NULL; | |
1689 } | |
1690 return res; | |
1691 } | |
1692 | |
1693 /* Return a value-number for RCODE OPS... either by looking up an existing | 1734 /* Return a value-number for RCODE OPS... either by looking up an existing |
1694 value-number for the simplified result or by inserting the operation if | 1735 value-number for the simplified result or by inserting the operation if |
1695 INSERT is true. */ | 1736 INSERT is true. */ |
1696 | 1737 |
1697 static tree | 1738 static tree |
1698 vn_nary_build_or_lookup_1 (code_helper rcode, tree type, tree *ops, | 1739 vn_nary_build_or_lookup_1 (gimple_match_op *res_op, bool insert) |
1699 bool insert) | |
1700 { | 1740 { |
1701 tree result = NULL_TREE; | 1741 tree result = NULL_TREE; |
1702 /* We will be creating a value number for | 1742 /* We will be creating a value number for |
1703 RCODE (OPS...). | 1743 RCODE (OPS...). |
1704 So first simplify and lookup this expression to see if it | 1744 So first simplify and lookup this expression to see if it |
1705 is already available. */ | 1745 is already available. */ |
1706 mprts_hook = vn_lookup_simplify_result; | 1746 mprts_hook = vn_lookup_simplify_result; |
1707 mprts_hook_cnt = 9; | |
1708 bool res = false; | 1747 bool res = false; |
1709 switch (TREE_CODE_LENGTH ((tree_code) rcode)) | 1748 switch (TREE_CODE_LENGTH ((tree_code) res_op->code)) |
1710 { | 1749 { |
1711 case 1: | 1750 case 1: |
1712 res = gimple_resimplify1 (NULL, &rcode, type, ops, vn_valueize); | 1751 res = gimple_resimplify1 (NULL, res_op, vn_valueize); |
1713 break; | 1752 break; |
1714 case 2: | 1753 case 2: |
1715 res = gimple_resimplify2 (NULL, &rcode, type, ops, vn_valueize); | 1754 res = gimple_resimplify2 (NULL, res_op, vn_valueize); |
1716 break; | 1755 break; |
1717 case 3: | 1756 case 3: |
1718 res = gimple_resimplify3 (NULL, &rcode, type, ops, vn_valueize); | 1757 res = gimple_resimplify3 (NULL, res_op, vn_valueize); |
1719 break; | 1758 break; |
1720 } | 1759 } |
1721 mprts_hook = NULL; | 1760 mprts_hook = NULL; |
1722 gimple *new_stmt = NULL; | 1761 gimple *new_stmt = NULL; |
1723 if (res | 1762 if (res |
1724 && gimple_simplified_result_is_gimple_val (rcode, ops)) | 1763 && gimple_simplified_result_is_gimple_val (res_op)) |
1725 /* The expression is already available. */ | 1764 { |
1726 result = ops[0]; | 1765 /* The expression is already available. */ |
1766 result = res_op->ops[0]; | |
1767 /* Valueize it, simplification returns sth in AVAIL only. */ | |
1768 if (TREE_CODE (result) == SSA_NAME) | |
1769 result = SSA_VAL (result); | |
1770 } | |
1727 else | 1771 else |
1728 { | 1772 { |
1729 tree val = vn_lookup_simplify_result (rcode, type, ops); | 1773 tree val = vn_lookup_simplify_result (res_op); |
1730 if (!val && insert) | 1774 if (!val && insert) |
1731 { | 1775 { |
1732 gimple_seq stmts = NULL; | 1776 gimple_seq stmts = NULL; |
1733 result = maybe_push_res_to_seq (rcode, type, ops, &stmts); | 1777 result = maybe_push_res_to_seq (res_op, &stmts); |
1734 if (result) | 1778 if (result) |
1735 { | 1779 { |
1736 gcc_assert (gimple_seq_singleton_p (stmts)); | 1780 gcc_assert (gimple_seq_singleton_p (stmts)); |
1737 new_stmt = gimple_seq_first_stmt (stmts); | 1781 new_stmt = gimple_seq_first_stmt (stmts); |
1738 } | 1782 } |
1744 if (new_stmt) | 1788 if (new_stmt) |
1745 { | 1789 { |
1746 /* The expression is not yet available, value-number lhs to | 1790 /* The expression is not yet available, value-number lhs to |
1747 the new SSA_NAME we created. */ | 1791 the new SSA_NAME we created. */ |
1748 /* Initialize value-number information properly. */ | 1792 /* Initialize value-number information properly. */ |
1749 VN_INFO_GET (result)->valnum = result; | 1793 vn_ssa_aux_t result_info = VN_INFO (result); |
1750 VN_INFO (result)->value_id = get_next_value_id (); | 1794 result_info->valnum = result; |
1795 result_info->value_id = get_next_value_id (); | |
1796 result_info->visited = 1; | |
1751 gimple_seq_add_stmt_without_update (&VN_INFO (result)->expr, | 1797 gimple_seq_add_stmt_without_update (&VN_INFO (result)->expr, |
1752 new_stmt); | 1798 new_stmt); |
1753 VN_INFO (result)->needs_insertion = true; | 1799 result_info->needs_insertion = true; |
1754 /* ??? PRE phi-translation inserts NARYs without corresponding | 1800 /* ??? PRE phi-translation inserts NARYs without corresponding |
1755 SSA name result. Re-use those but set their result according | 1801 SSA name result. Re-use those but set their result according |
1756 to the stmt we just built. */ | 1802 to the stmt we just built. */ |
1757 vn_nary_op_t nary = NULL; | 1803 vn_nary_op_t nary = NULL; |
1758 vn_nary_op_lookup_stmt (new_stmt, &nary); | 1804 vn_nary_op_lookup_stmt (new_stmt, &nary); |
1759 if (nary) | 1805 if (nary) |
1760 { | 1806 { |
1761 gcc_assert (nary->result == NULL_TREE); | 1807 gcc_assert (! nary->predicated_values && nary->u.result == NULL_TREE); |
1762 nary->result = gimple_assign_lhs (new_stmt); | 1808 nary->u.result = gimple_assign_lhs (new_stmt); |
1763 } | 1809 } |
1764 /* As all "inserted" statements are singleton SCCs, insert | 1810 /* As all "inserted" statements are singleton SCCs, insert |
1765 to the valid table. This is strictly needed to | 1811 to the valid table. This is strictly needed to |
1766 avoid re-generating new value SSA_NAMEs for the same | 1812 avoid re-generating new value SSA_NAMEs for the same |
1767 expression during SCC iteration over and over (the | 1813 expression during SCC iteration over and over (the |
1768 optimistic table gets cleared after each iteration). | 1814 optimistic table gets cleared after each iteration). |
1769 We do not need to insert into the optimistic table, as | 1815 We do not need to insert into the optimistic table, as |
1770 lookups there will fall back to the valid table. */ | 1816 lookups there will fall back to the valid table. */ |
1771 else if (current_info == optimistic_info) | |
1772 { | |
1773 current_info = valid_info; | |
1774 vn_nary_op_insert_stmt (new_stmt, result); | |
1775 current_info = optimistic_info; | |
1776 } | |
1777 else | 1817 else |
1778 vn_nary_op_insert_stmt (new_stmt, result); | 1818 { |
1819 unsigned int length = vn_nary_length_from_stmt (new_stmt); | |
1820 vn_nary_op_t vno1 | |
1821 = alloc_vn_nary_op_noinit (length, &vn_tables_insert_obstack); | |
1822 vno1->value_id = result_info->value_id; | |
1823 vno1->length = length; | |
1824 vno1->predicated_values = 0; | |
1825 vno1->u.result = result; | |
1826 init_vn_nary_op_from_stmt (vno1, new_stmt); | |
1827 vn_nary_op_insert_into (vno1, valid_info->nary, true); | |
1828 /* Also do not link it into the undo chain. */ | |
1829 last_inserted_nary = vno1->next; | |
1830 vno1->next = (vn_nary_op_t)(void *)-1; | |
1831 } | |
1779 if (dump_file && (dump_flags & TDF_DETAILS)) | 1832 if (dump_file && (dump_flags & TDF_DETAILS)) |
1780 { | 1833 { |
1781 fprintf (dump_file, "Inserting name "); | 1834 fprintf (dump_file, "Inserting name "); |
1782 print_generic_expr (dump_file, result); | 1835 print_generic_expr (dump_file, result); |
1783 fprintf (dump_file, " for expression "); | 1836 fprintf (dump_file, " for expression "); |
1790 | 1843 |
1791 /* Return a value-number for RCODE OPS... either by looking up an existing | 1844 /* Return a value-number for RCODE OPS... either by looking up an existing |
1792 value-number for the simplified result or by inserting the operation. */ | 1845 value-number for the simplified result or by inserting the operation. */ |
1793 | 1846 |
1794 static tree | 1847 static tree |
1795 vn_nary_build_or_lookup (code_helper rcode, tree type, tree *ops) | 1848 vn_nary_build_or_lookup (gimple_match_op *res_op) |
1796 { | 1849 { |
1797 return vn_nary_build_or_lookup_1 (rcode, type, ops, true); | 1850 return vn_nary_build_or_lookup_1 (res_op, true); |
1798 } | 1851 } |
1799 | 1852 |
1800 /* Try to simplify the expression RCODE OPS... of type TYPE and return | 1853 /* Try to simplify the expression RCODE OPS... of type TYPE and return |
1801 its value if present. */ | 1854 its value if present. */ |
1802 | 1855 |
1803 tree | 1856 tree |
1804 vn_nary_simplify (vn_nary_op_t nary) | 1857 vn_nary_simplify (vn_nary_op_t nary) |
1805 { | 1858 { |
1806 if (nary->length > 3) | 1859 if (nary->length > gimple_match_op::MAX_NUM_OPS) |
1807 return NULL_TREE; | 1860 return NULL_TREE; |
1808 tree ops[3]; | 1861 gimple_match_op op (gimple_match_cond::UNCOND, nary->opcode, |
1809 memcpy (ops, nary->op, sizeof (tree) * nary->length); | 1862 nary->type, nary->length); |
1810 return vn_nary_build_or_lookup_1 (nary->opcode, nary->type, ops, false); | 1863 memcpy (op.ops, nary->op, sizeof (tree) * nary->length); |
1811 } | 1864 return vn_nary_build_or_lookup_1 (&op, false); |
1812 | 1865 } |
1866 | |
1867 basic_block vn_context_bb; | |
1813 | 1868 |
1814 /* Callback for walk_non_aliased_vuses. Tries to perform a lookup | 1869 /* Callback for walk_non_aliased_vuses. Tries to perform a lookup |
1815 from the statement defining VUSE and if not successful tries to | 1870 from the statement defining VUSE and if not successful tries to |
1816 translate *REFP and VR_ through an aggregate copy at the definition | 1871 translate *REFP and VR_ through an aggregate copy at the definition |
1817 of VUSE. If *DISAMBIGUATE_ONLY is true then do not perform translation | 1872 of VUSE. If *DISAMBIGUATE_ONLY is true then do not perform translation |
1823 bool *disambiguate_only) | 1878 bool *disambiguate_only) |
1824 { | 1879 { |
1825 vn_reference_t vr = (vn_reference_t)vr_; | 1880 vn_reference_t vr = (vn_reference_t)vr_; |
1826 gimple *def_stmt = SSA_NAME_DEF_STMT (vuse); | 1881 gimple *def_stmt = SSA_NAME_DEF_STMT (vuse); |
1827 tree base = ao_ref_base (ref); | 1882 tree base = ao_ref_base (ref); |
1828 HOST_WIDE_INT offset, maxsize; | 1883 HOST_WIDE_INT offseti, maxsizei; |
1829 static vec<vn_reference_op_s> lhs_ops; | 1884 static vec<vn_reference_op_s> lhs_ops; |
1830 ao_ref lhs_ref; | 1885 ao_ref lhs_ref; |
1831 bool lhs_ref_ok = false; | 1886 bool lhs_ref_ok = false; |
1832 | 1887 poly_int64 copy_size; |
1833 /* If the reference is based on a parameter that was determined as | |
1834 pointing to readonly memory it doesn't change. */ | |
1835 if (TREE_CODE (base) == MEM_REF | |
1836 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME | |
1837 && SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (base, 0)) | |
1838 && bitmap_bit_p (const_parms, | |
1839 SSA_NAME_VERSION (TREE_OPERAND (base, 0)))) | |
1840 { | |
1841 *disambiguate_only = true; | |
1842 return NULL; | |
1843 } | |
1844 | 1888 |
1845 /* First try to disambiguate after value-replacing in the definitions LHS. */ | 1889 /* First try to disambiguate after value-replacing in the definitions LHS. */ |
1846 if (is_gimple_assign (def_stmt)) | 1890 if (is_gimple_assign (def_stmt)) |
1847 { | 1891 { |
1848 tree lhs = gimple_assign_lhs (def_stmt); | 1892 tree lhs = gimple_assign_lhs (def_stmt); |
1849 bool valueized_anything = false; | 1893 bool valueized_anything = false; |
1850 /* Avoid re-allocation overhead. */ | 1894 /* Avoid re-allocation overhead. */ |
1851 lhs_ops.truncate (0); | 1895 lhs_ops.truncate (0); |
1896 basic_block saved_rpo_bb = vn_context_bb; | |
1897 vn_context_bb = gimple_bb (def_stmt); | |
1852 copy_reference_ops_from_ref (lhs, &lhs_ops); | 1898 copy_reference_ops_from_ref (lhs, &lhs_ops); |
1853 lhs_ops = valueize_refs_1 (lhs_ops, &valueized_anything); | 1899 lhs_ops = valueize_refs_1 (lhs_ops, &valueized_anything, true); |
1900 vn_context_bb = saved_rpo_bb; | |
1854 if (valueized_anything) | 1901 if (valueized_anything) |
1855 { | 1902 { |
1856 lhs_ref_ok = ao_ref_init_from_vn_reference (&lhs_ref, | 1903 lhs_ref_ok = ao_ref_init_from_vn_reference (&lhs_ref, |
1857 get_alias_set (lhs), | 1904 get_alias_set (lhs), |
1858 TREE_TYPE (lhs), lhs_ops); | 1905 TREE_TYPE (lhs), lhs_ops); |
1865 } | 1912 } |
1866 else | 1913 else |
1867 { | 1914 { |
1868 ao_ref_init (&lhs_ref, lhs); | 1915 ao_ref_init (&lhs_ref, lhs); |
1869 lhs_ref_ok = true; | 1916 lhs_ref_ok = true; |
1917 } | |
1918 | |
1919 /* If we reach a clobbering statement try to skip it and see if | |
1920 we find a VN result with exactly the same value as the | |
1921 possible clobber. In this case we can ignore the clobber | |
1922 and return the found value. | |
1923 Note that we don't need to worry about partial overlapping | |
1924 accesses as we then can use TBAA to disambiguate against the | |
1925 clobbering statement when looking up a load (thus the | |
1926 VN_WALKREWRITE guard). */ | |
1927 if (vn_walk_kind == VN_WALKREWRITE | |
1928 && is_gimple_reg_type (TREE_TYPE (lhs)) | |
1929 && types_compatible_p (TREE_TYPE (lhs), vr->type)) | |
1930 { | |
1931 tree *saved_last_vuse_ptr = last_vuse_ptr; | |
1932 /* Do not update last_vuse_ptr in vn_reference_lookup_2. */ | |
1933 last_vuse_ptr = NULL; | |
1934 tree saved_vuse = vr->vuse; | |
1935 hashval_t saved_hashcode = vr->hashcode; | |
1936 void *res = vn_reference_lookup_2 (ref, | |
1937 gimple_vuse (def_stmt), 0, vr); | |
1938 /* Need to restore vr->vuse and vr->hashcode. */ | |
1939 vr->vuse = saved_vuse; | |
1940 vr->hashcode = saved_hashcode; | |
1941 last_vuse_ptr = saved_last_vuse_ptr; | |
1942 if (res && res != (void *)-1) | |
1943 { | |
1944 vn_reference_t vnresult = (vn_reference_t) res; | |
1945 if (vnresult->result | |
1946 && operand_equal_p (vnresult->result, | |
1947 gimple_assign_rhs1 (def_stmt), 0)) | |
1948 return res; | |
1949 } | |
1870 } | 1950 } |
1871 } | 1951 } |
1872 else if (gimple_call_builtin_p (def_stmt, BUILT_IN_NORMAL) | 1952 else if (gimple_call_builtin_p (def_stmt, BUILT_IN_NORMAL) |
1873 && gimple_call_num_args (def_stmt) <= 4) | 1953 && gimple_call_num_args (def_stmt) <= 4) |
1874 { | 1954 { |
1905 } | 1985 } |
1906 | 1986 |
1907 if (*disambiguate_only) | 1987 if (*disambiguate_only) |
1908 return (void *)-1; | 1988 return (void *)-1; |
1909 | 1989 |
1910 offset = ref->offset; | |
1911 maxsize = ref->max_size; | |
1912 | |
1913 /* If we cannot constrain the size of the reference we cannot | 1990 /* If we cannot constrain the size of the reference we cannot |
1914 test if anything kills it. */ | 1991 test if anything kills it. */ |
1915 if (maxsize == -1) | 1992 if (!ref->max_size_known_p ()) |
1916 return (void *)-1; | 1993 return (void *)-1; |
1994 | |
1995 poly_int64 offset = ref->offset; | |
1996 poly_int64 maxsize = ref->max_size; | |
1917 | 1997 |
1918 /* We can't deduce anything useful from clobbers. */ | 1998 /* We can't deduce anything useful from clobbers. */ |
1919 if (gimple_clobber_p (def_stmt)) | 1999 if (gimple_clobber_p (def_stmt)) |
1920 return (void *)-1; | 2000 return (void *)-1; |
1921 | 2001 |
1922 /* def_stmt may-defs *ref. See if we can derive a value for *ref | 2002 /* def_stmt may-defs *ref. See if we can derive a value for *ref |
1923 from that definition. | 2003 from that definition. |
1924 1) Memset. */ | 2004 1) Memset. */ |
1925 if (is_gimple_reg_type (vr->type) | 2005 if (is_gimple_reg_type (vr->type) |
1926 && gimple_call_builtin_p (def_stmt, BUILT_IN_MEMSET) | 2006 && gimple_call_builtin_p (def_stmt, BUILT_IN_MEMSET) |
1927 && integer_zerop (gimple_call_arg (def_stmt, 1)) | 2007 && (integer_zerop (gimple_call_arg (def_stmt, 1)) |
1928 && tree_fits_uhwi_p (gimple_call_arg (def_stmt, 2)) | 2008 || ((TREE_CODE (gimple_call_arg (def_stmt, 1)) == INTEGER_CST |
1929 && TREE_CODE (gimple_call_arg (def_stmt, 0)) == ADDR_EXPR) | 2009 || (INTEGRAL_TYPE_P (vr->type) && known_eq (ref->size, 8))) |
1930 { | 2010 && CHAR_BIT == 8 && BITS_PER_UNIT == 8 |
1931 tree ref2 = TREE_OPERAND (gimple_call_arg (def_stmt, 0), 0); | 2011 && offset.is_constant (&offseti) |
2012 && offseti % BITS_PER_UNIT == 0)) | |
2013 && poly_int_tree_p (gimple_call_arg (def_stmt, 2)) | |
2014 && (TREE_CODE (gimple_call_arg (def_stmt, 0)) == ADDR_EXPR | |
2015 || TREE_CODE (gimple_call_arg (def_stmt, 0)) == SSA_NAME)) | |
2016 { | |
1932 tree base2; | 2017 tree base2; |
1933 HOST_WIDE_INT offset2, size2, maxsize2; | 2018 poly_int64 offset2, size2, maxsize2; |
1934 bool reverse; | 2019 bool reverse; |
1935 base2 = get_ref_base_and_extent (ref2, &offset2, &size2, &maxsize2, | 2020 tree ref2 = gimple_call_arg (def_stmt, 0); |
1936 &reverse); | 2021 if (TREE_CODE (ref2) == SSA_NAME) |
1937 size2 = tree_to_uhwi (gimple_call_arg (def_stmt, 2)) * 8; | 2022 { |
1938 if ((unsigned HOST_WIDE_INT)size2 / 8 | 2023 ref2 = SSA_VAL (ref2); |
1939 == tree_to_uhwi (gimple_call_arg (def_stmt, 2)) | 2024 if (TREE_CODE (ref2) == SSA_NAME |
1940 && maxsize2 != -1 | 2025 && (TREE_CODE (base) != MEM_REF |
1941 && operand_equal_p (base, base2, 0) | 2026 || TREE_OPERAND (base, 0) != ref2)) |
1942 && offset2 <= offset | 2027 { |
1943 && offset2 + size2 >= offset + maxsize) | 2028 gimple *def_stmt = SSA_NAME_DEF_STMT (ref2); |
1944 { | 2029 if (gimple_assign_single_p (def_stmt) |
1945 tree val = build_zero_cst (vr->type); | 2030 && gimple_assign_rhs_code (def_stmt) == ADDR_EXPR) |
2031 ref2 = gimple_assign_rhs1 (def_stmt); | |
2032 } | |
2033 } | |
2034 if (TREE_CODE (ref2) == ADDR_EXPR) | |
2035 { | |
2036 ref2 = TREE_OPERAND (ref2, 0); | |
2037 base2 = get_ref_base_and_extent (ref2, &offset2, &size2, &maxsize2, | |
2038 &reverse); | |
2039 if (!known_size_p (maxsize2) | |
2040 || !known_eq (maxsize2, size2) | |
2041 || !operand_equal_p (base, base2, OEP_ADDRESS_OF)) | |
2042 return (void *)-1; | |
2043 } | |
2044 else if (TREE_CODE (ref2) == SSA_NAME) | |
2045 { | |
2046 poly_int64 soff; | |
2047 if (TREE_CODE (base) != MEM_REF | |
2048 || !(mem_ref_offset (base) << LOG2_BITS_PER_UNIT).to_shwi (&soff)) | |
2049 return (void *)-1; | |
2050 offset += soff; | |
2051 offset2 = 0; | |
2052 if (TREE_OPERAND (base, 0) != ref2) | |
2053 { | |
2054 gimple *def = SSA_NAME_DEF_STMT (ref2); | |
2055 if (is_gimple_assign (def) | |
2056 && gimple_assign_rhs_code (def) == POINTER_PLUS_EXPR | |
2057 && gimple_assign_rhs1 (def) == TREE_OPERAND (base, 0) | |
2058 && poly_int_tree_p (gimple_assign_rhs2 (def)) | |
2059 && (wi::to_poly_offset (gimple_assign_rhs2 (def)) | |
2060 << LOG2_BITS_PER_UNIT).to_shwi (&offset2)) | |
2061 { | |
2062 ref2 = gimple_assign_rhs1 (def); | |
2063 if (TREE_CODE (ref2) == SSA_NAME) | |
2064 ref2 = SSA_VAL (ref2); | |
2065 } | |
2066 else | |
2067 return (void *)-1; | |
2068 } | |
2069 } | |
2070 else | |
2071 return (void *)-1; | |
2072 tree len = gimple_call_arg (def_stmt, 2); | |
2073 if (known_subrange_p (offset, maxsize, offset2, | |
2074 wi::to_poly_offset (len) << LOG2_BITS_PER_UNIT)) | |
2075 { | |
2076 tree val; | |
2077 if (integer_zerop (gimple_call_arg (def_stmt, 1))) | |
2078 val = build_zero_cst (vr->type); | |
2079 else if (INTEGRAL_TYPE_P (vr->type) | |
2080 && known_eq (ref->size, 8)) | |
2081 { | |
2082 gimple_match_op res_op (gimple_match_cond::UNCOND, NOP_EXPR, | |
2083 vr->type, gimple_call_arg (def_stmt, 1)); | |
2084 val = vn_nary_build_or_lookup (&res_op); | |
2085 if (!val | |
2086 || (TREE_CODE (val) == SSA_NAME | |
2087 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val))) | |
2088 return (void *)-1; | |
2089 } | |
2090 else | |
2091 { | |
2092 unsigned len = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (vr->type)); | |
2093 unsigned char *buf = XALLOCAVEC (unsigned char, len); | |
2094 memset (buf, TREE_INT_CST_LOW (gimple_call_arg (def_stmt, 1)), | |
2095 len); | |
2096 val = native_interpret_expr (vr->type, buf, len); | |
2097 if (!val) | |
2098 return (void *)-1; | |
2099 } | |
1946 return vn_reference_lookup_or_insert_for_pieces | 2100 return vn_reference_lookup_or_insert_for_pieces |
1947 (vuse, vr->set, vr->type, vr->operands, val); | 2101 (vuse, vr->set, vr->type, vr->operands, val); |
1948 } | 2102 } |
1949 } | 2103 } |
1950 | 2104 |
1953 && gimple_assign_single_p (def_stmt) | 2107 && gimple_assign_single_p (def_stmt) |
1954 && gimple_assign_rhs_code (def_stmt) == CONSTRUCTOR | 2108 && gimple_assign_rhs_code (def_stmt) == CONSTRUCTOR |
1955 && CONSTRUCTOR_NELTS (gimple_assign_rhs1 (def_stmt)) == 0) | 2109 && CONSTRUCTOR_NELTS (gimple_assign_rhs1 (def_stmt)) == 0) |
1956 { | 2110 { |
1957 tree base2; | 2111 tree base2; |
1958 HOST_WIDE_INT offset2, size2, maxsize2; | 2112 poly_int64 offset2, size2, maxsize2; |
1959 bool reverse; | 2113 bool reverse; |
1960 base2 = get_ref_base_and_extent (gimple_assign_lhs (def_stmt), | 2114 base2 = get_ref_base_and_extent (gimple_assign_lhs (def_stmt), |
1961 &offset2, &size2, &maxsize2, &reverse); | 2115 &offset2, &size2, &maxsize2, &reverse); |
1962 if (maxsize2 != -1 | 2116 if (known_size_p (maxsize2) |
1963 && operand_equal_p (base, base2, 0) | 2117 && operand_equal_p (base, base2, 0) |
1964 && offset2 <= offset | 2118 && known_subrange_p (offset, maxsize, offset2, size2)) |
1965 && offset2 + size2 >= offset + maxsize) | |
1966 { | 2119 { |
1967 tree val = build_zero_cst (vr->type); | 2120 tree val = build_zero_cst (vr->type); |
1968 return vn_reference_lookup_or_insert_for_pieces | 2121 return vn_reference_lookup_or_insert_for_pieces |
1969 (vuse, vr->set, vr->type, vr->operands, val); | 2122 (vuse, vr->set, vr->type, vr->operands, val); |
1970 } | 2123 } |
1971 } | 2124 } |
1972 | 2125 |
1973 /* 3) Assignment from a constant. We can use folds native encode/interpret | 2126 /* 3) Assignment from a constant. We can use folds native encode/interpret |
1974 routines to extract the assigned bits. */ | 2127 routines to extract the assigned bits. */ |
1975 else if (ref->size == maxsize | 2128 else if (known_eq (ref->size, maxsize) |
1976 && is_gimple_reg_type (vr->type) | 2129 && is_gimple_reg_type (vr->type) |
1977 && !contains_storage_order_barrier_p (vr->operands) | 2130 && !contains_storage_order_barrier_p (vr->operands) |
1978 && gimple_assign_single_p (def_stmt) | 2131 && gimple_assign_single_p (def_stmt) |
1979 && CHAR_BIT == 8 && BITS_PER_UNIT == 8 | 2132 && CHAR_BIT == 8 && BITS_PER_UNIT == 8 |
1980 && maxsize % BITS_PER_UNIT == 0 | 2133 /* native_encode and native_decode operate on arrays of bytes |
1981 && offset % BITS_PER_UNIT == 0 | 2134 and so fundamentally need a compile-time size and offset. */ |
2135 && maxsize.is_constant (&maxsizei) | |
2136 && maxsizei % BITS_PER_UNIT == 0 | |
2137 && offset.is_constant (&offseti) | |
2138 && offseti % BITS_PER_UNIT == 0 | |
1982 && (is_gimple_min_invariant (gimple_assign_rhs1 (def_stmt)) | 2139 && (is_gimple_min_invariant (gimple_assign_rhs1 (def_stmt)) |
1983 || (TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME | 2140 || (TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME |
1984 && is_gimple_min_invariant (SSA_VAL (gimple_assign_rhs1 (def_stmt)))))) | 2141 && is_gimple_min_invariant (SSA_VAL (gimple_assign_rhs1 (def_stmt)))))) |
1985 { | 2142 { |
1986 tree base2; | 2143 tree base2; |
1987 HOST_WIDE_INT offset2, size2, maxsize2; | 2144 HOST_WIDE_INT offset2, size2; |
1988 bool reverse; | 2145 bool reverse; |
1989 base2 = get_ref_base_and_extent (gimple_assign_lhs (def_stmt), | 2146 base2 = get_ref_base_and_extent_hwi (gimple_assign_lhs (def_stmt), |
1990 &offset2, &size2, &maxsize2, &reverse); | 2147 &offset2, &size2, &reverse); |
1991 if (!reverse | 2148 if (base2 |
1992 && maxsize2 != -1 | 2149 && !reverse |
1993 && maxsize2 == size2 | |
1994 && size2 % BITS_PER_UNIT == 0 | 2150 && size2 % BITS_PER_UNIT == 0 |
1995 && offset2 % BITS_PER_UNIT == 0 | 2151 && offset2 % BITS_PER_UNIT == 0 |
1996 && operand_equal_p (base, base2, 0) | 2152 && operand_equal_p (base, base2, 0) |
1997 && offset2 <= offset | 2153 && known_subrange_p (offseti, maxsizei, offset2, size2)) |
1998 && offset2 + size2 >= offset + maxsize) | |
1999 { | 2154 { |
2000 /* We support up to 512-bit values (for V8DFmode). */ | 2155 /* We support up to 512-bit values (for V8DFmode). */ |
2001 unsigned char buffer[64]; | 2156 unsigned char buffer[64]; |
2002 int len; | 2157 int len; |
2003 | 2158 |
2004 tree rhs = gimple_assign_rhs1 (def_stmt); | 2159 tree rhs = gimple_assign_rhs1 (def_stmt); |
2005 if (TREE_CODE (rhs) == SSA_NAME) | 2160 if (TREE_CODE (rhs) == SSA_NAME) |
2006 rhs = SSA_VAL (rhs); | 2161 rhs = SSA_VAL (rhs); |
2007 len = native_encode_expr (gimple_assign_rhs1 (def_stmt), | 2162 len = native_encode_expr (gimple_assign_rhs1 (def_stmt), |
2008 buffer, sizeof (buffer)); | 2163 buffer, sizeof (buffer), |
2009 if (len > 0) | 2164 (offseti - offset2) / BITS_PER_UNIT); |
2165 if (len > 0 && len * BITS_PER_UNIT >= maxsizei) | |
2010 { | 2166 { |
2011 tree type = vr->type; | 2167 tree type = vr->type; |
2012 /* Make sure to interpret in a type that has a range | 2168 /* Make sure to interpret in a type that has a range |
2013 covering the whole access size. */ | 2169 covering the whole access size. */ |
2014 if (INTEGRAL_TYPE_P (vr->type) | 2170 if (INTEGRAL_TYPE_P (vr->type) |
2015 && ref->size != TYPE_PRECISION (vr->type)) | 2171 && maxsizei != TYPE_PRECISION (vr->type)) |
2016 type = build_nonstandard_integer_type (ref->size, | 2172 type = build_nonstandard_integer_type (maxsizei, |
2017 TYPE_UNSIGNED (type)); | 2173 TYPE_UNSIGNED (type)); |
2018 tree val = native_interpret_expr (type, | 2174 tree val = native_interpret_expr (type, buffer, |
2019 buffer | 2175 maxsizei / BITS_PER_UNIT); |
2020 + ((offset - offset2) | |
2021 / BITS_PER_UNIT), | |
2022 ref->size / BITS_PER_UNIT); | |
2023 /* If we chop off bits because the types precision doesn't | 2176 /* If we chop off bits because the types precision doesn't |
2024 match the memory access size this is ok when optimizing | 2177 match the memory access size this is ok when optimizing |
2025 reads but not when called from the DSE code during | 2178 reads but not when called from the DSE code during |
2026 elimination. */ | 2179 elimination. */ |
2027 if (val | 2180 if (val |
2040 } | 2193 } |
2041 } | 2194 } |
2042 | 2195 |
2043 /* 4) Assignment from an SSA name which definition we may be able | 2196 /* 4) Assignment from an SSA name which definition we may be able |
2044 to access pieces from. */ | 2197 to access pieces from. */ |
2045 else if (ref->size == maxsize | 2198 else if (known_eq (ref->size, maxsize) |
2046 && is_gimple_reg_type (vr->type) | 2199 && is_gimple_reg_type (vr->type) |
2047 && !contains_storage_order_barrier_p (vr->operands) | 2200 && !contains_storage_order_barrier_p (vr->operands) |
2048 && gimple_assign_single_p (def_stmt) | 2201 && gimple_assign_single_p (def_stmt) |
2049 && TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME) | 2202 && TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME) |
2050 { | 2203 { |
2051 tree base2; | 2204 tree base2; |
2052 HOST_WIDE_INT offset2, size2, maxsize2; | 2205 poly_int64 offset2, size2, maxsize2; |
2053 bool reverse; | 2206 bool reverse; |
2054 base2 = get_ref_base_and_extent (gimple_assign_lhs (def_stmt), | 2207 base2 = get_ref_base_and_extent (gimple_assign_lhs (def_stmt), |
2055 &offset2, &size2, &maxsize2, | 2208 &offset2, &size2, &maxsize2, |
2056 &reverse); | 2209 &reverse); |
2057 if (!reverse | 2210 if (!reverse |
2058 && maxsize2 != -1 | 2211 && known_size_p (maxsize2) |
2059 && maxsize2 == size2 | 2212 && known_eq (maxsize2, size2) |
2060 && operand_equal_p (base, base2, 0) | 2213 && operand_equal_p (base, base2, 0) |
2061 && offset2 <= offset | 2214 && known_subrange_p (offset, maxsize, offset2, size2) |
2062 && offset2 + size2 >= offset + maxsize | |
2063 /* ??? We can't handle bitfield precision extracts without | 2215 /* ??? We can't handle bitfield precision extracts without |
2064 either using an alternate type for the BIT_FIELD_REF and | 2216 either using an alternate type for the BIT_FIELD_REF and |
2065 then doing a conversion or possibly adjusting the offset | 2217 then doing a conversion or possibly adjusting the offset |
2066 according to endianness. */ | 2218 according to endianness. */ |
2067 && (! INTEGRAL_TYPE_P (vr->type) | 2219 && (! INTEGRAL_TYPE_P (vr->type) |
2068 || ref->size == TYPE_PRECISION (vr->type)) | 2220 || known_eq (ref->size, TYPE_PRECISION (vr->type))) |
2069 && ref->size % BITS_PER_UNIT == 0) | 2221 && multiple_p (ref->size, BITS_PER_UNIT)) |
2070 { | 2222 { |
2071 code_helper rcode = BIT_FIELD_REF; | 2223 gimple_match_op op (gimple_match_cond::UNCOND, |
2072 tree ops[3]; | 2224 BIT_FIELD_REF, vr->type, |
2073 ops[0] = SSA_VAL (gimple_assign_rhs1 (def_stmt)); | 2225 vn_valueize (gimple_assign_rhs1 (def_stmt)), |
2074 ops[1] = bitsize_int (ref->size); | 2226 bitsize_int (ref->size), |
2075 ops[2] = bitsize_int (offset - offset2); | 2227 bitsize_int (offset - offset2)); |
2076 tree val = vn_nary_build_or_lookup (rcode, vr->type, ops); | 2228 tree val = vn_nary_build_or_lookup (&op); |
2077 if (val | 2229 if (val |
2078 && (TREE_CODE (val) != SSA_NAME | 2230 && (TREE_CODE (val) != SSA_NAME |
2079 || ! SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val))) | 2231 || ! SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val))) |
2080 { | 2232 { |
2081 vn_reference_t res = vn_reference_lookup_or_insert_for_pieces | 2233 vn_reference_t res = vn_reference_lookup_or_insert_for_pieces |
2092 && (DECL_P (gimple_assign_rhs1 (def_stmt)) | 2244 && (DECL_P (gimple_assign_rhs1 (def_stmt)) |
2093 || TREE_CODE (gimple_assign_rhs1 (def_stmt)) == MEM_REF | 2245 || TREE_CODE (gimple_assign_rhs1 (def_stmt)) == MEM_REF |
2094 || handled_component_p (gimple_assign_rhs1 (def_stmt)))) | 2246 || handled_component_p (gimple_assign_rhs1 (def_stmt)))) |
2095 { | 2247 { |
2096 tree base2; | 2248 tree base2; |
2097 HOST_WIDE_INT maxsize2; | |
2098 int i, j, k; | 2249 int i, j, k; |
2099 auto_vec<vn_reference_op_s> rhs; | 2250 auto_vec<vn_reference_op_s> rhs; |
2100 vn_reference_op_t vro; | 2251 vn_reference_op_t vro; |
2101 ao_ref r; | 2252 ao_ref r; |
2102 | 2253 |
2103 if (!lhs_ref_ok) | 2254 if (!lhs_ref_ok) |
2104 return (void *)-1; | 2255 return (void *)-1; |
2105 | 2256 |
2106 /* See if the assignment kills REF. */ | 2257 /* See if the assignment kills REF. */ |
2107 base2 = ao_ref_base (&lhs_ref); | 2258 base2 = ao_ref_base (&lhs_ref); |
2108 maxsize2 = lhs_ref.max_size; | 2259 if (!lhs_ref.max_size_known_p () |
2109 if (maxsize2 == -1 | |
2110 || (base != base2 | 2260 || (base != base2 |
2111 && (TREE_CODE (base) != MEM_REF | 2261 && (TREE_CODE (base) != MEM_REF |
2112 || TREE_CODE (base2) != MEM_REF | 2262 || TREE_CODE (base2) != MEM_REF |
2113 || TREE_OPERAND (base, 0) != TREE_OPERAND (base2, 0) | 2263 || TREE_OPERAND (base, 0) != TREE_OPERAND (base2, 0) |
2114 || !tree_int_cst_equal (TREE_OPERAND (base, 1), | 2264 || !tree_int_cst_equal (TREE_OPERAND (base, 1), |
2131 checked that the assignment to the lhs kills vr. Thus for | 2281 checked that the assignment to the lhs kills vr. Thus for |
2132 aggregate copies using char[] types the vn_reference_op_eq | 2282 aggregate copies using char[] types the vn_reference_op_eq |
2133 may fail when comparing types for compatibility. But we really | 2283 may fail when comparing types for compatibility. But we really |
2134 don't care here - further lookups with the rewritten operands | 2284 don't care here - further lookups with the rewritten operands |
2135 will simply fail if we messed up types too badly. */ | 2285 will simply fail if we messed up types too badly. */ |
2136 HOST_WIDE_INT extra_off = 0; | 2286 poly_int64 extra_off = 0; |
2137 if (j == 0 && i >= 0 | 2287 if (j == 0 && i >= 0 |
2138 && lhs_ops[0].opcode == MEM_REF | 2288 && lhs_ops[0].opcode == MEM_REF |
2139 && lhs_ops[0].off != -1) | 2289 && maybe_ne (lhs_ops[0].off, -1)) |
2140 { | 2290 { |
2141 if (lhs_ops[0].off == vr->operands[i].off) | 2291 if (known_eq (lhs_ops[0].off, vr->operands[i].off)) |
2142 i--, j--; | 2292 i--, j--; |
2143 else if (vr->operands[i].opcode == MEM_REF | 2293 else if (vr->operands[i].opcode == MEM_REF |
2144 && vr->operands[i].off != -1) | 2294 && maybe_ne (vr->operands[i].off, -1)) |
2145 { | 2295 { |
2146 extra_off = vr->operands[i].off - lhs_ops[0].off; | 2296 extra_off = vr->operands[i].off - lhs_ops[0].off; |
2147 i--, j--; | 2297 i--, j--; |
2148 } | 2298 } |
2149 } | 2299 } |
2165 | 2315 |
2166 /* Now re-write REF to be based on the rhs of the assignment. */ | 2316 /* Now re-write REF to be based on the rhs of the assignment. */ |
2167 copy_reference_ops_from_ref (gimple_assign_rhs1 (def_stmt), &rhs); | 2317 copy_reference_ops_from_ref (gimple_assign_rhs1 (def_stmt), &rhs); |
2168 | 2318 |
2169 /* Apply an extra offset to the inner MEM_REF of the RHS. */ | 2319 /* Apply an extra offset to the inner MEM_REF of the RHS. */ |
2170 if (extra_off != 0) | 2320 if (maybe_ne (extra_off, 0)) |
2171 { | 2321 { |
2172 if (rhs.length () < 2 | 2322 if (rhs.length () < 2) |
2173 || rhs[0].opcode != MEM_REF | |
2174 || rhs[0].off == -1) | |
2175 return (void *)-1; | 2323 return (void *)-1; |
2176 rhs[0].off += extra_off; | 2324 int ix = rhs.length () - 2; |
2177 rhs[0].op0 = int_const_binop (PLUS_EXPR, rhs[0].op0, | 2325 if (rhs[ix].opcode != MEM_REF |
2178 build_int_cst (TREE_TYPE (rhs[0].op0), | 2326 || known_eq (rhs[ix].off, -1)) |
2179 extra_off)); | 2327 return (void *)-1; |
2328 rhs[ix].off += extra_off; | |
2329 rhs[ix].op0 = int_const_binop (PLUS_EXPR, rhs[ix].op0, | |
2330 build_int_cst (TREE_TYPE (rhs[ix].op0), | |
2331 extra_off)); | |
2180 } | 2332 } |
2181 | 2333 |
2182 /* We need to pre-pend vr->operands[0..i] to rhs. */ | 2334 /* We need to pre-pend vr->operands[0..i] to rhs. */ |
2183 vec<vn_reference_op_s> old = vr->operands; | 2335 vec<vn_reference_op_s> old = vr->operands; |
2184 if (i + 1 + rhs.length () > vr->operands.length ()) | 2336 if (i + 1 + rhs.length () > vr->operands.length ()) |
2200 | 2352 |
2201 /* Adjust *ref from the new operands. */ | 2353 /* Adjust *ref from the new operands. */ |
2202 if (!ao_ref_init_from_vn_reference (&r, vr->set, vr->type, vr->operands)) | 2354 if (!ao_ref_init_from_vn_reference (&r, vr->set, vr->type, vr->operands)) |
2203 return (void *)-1; | 2355 return (void *)-1; |
2204 /* This can happen with bitfields. */ | 2356 /* This can happen with bitfields. */ |
2205 if (ref->size != r.size) | 2357 if (maybe_ne (ref->size, r.size)) |
2206 return (void *)-1; | 2358 return (void *)-1; |
2207 *ref = r; | 2359 *ref = r; |
2208 | 2360 |
2209 /* Do not update last seen VUSE after translating. */ | 2361 /* Do not update last seen VUSE after translating. */ |
2210 last_vuse_ptr = NULL; | 2362 last_vuse_ptr = NULL; |
2223 || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMMOVE)) | 2375 || gimple_call_builtin_p (def_stmt, BUILT_IN_MEMMOVE)) |
2224 && (TREE_CODE (gimple_call_arg (def_stmt, 0)) == ADDR_EXPR | 2376 && (TREE_CODE (gimple_call_arg (def_stmt, 0)) == ADDR_EXPR |
2225 || TREE_CODE (gimple_call_arg (def_stmt, 0)) == SSA_NAME) | 2377 || TREE_CODE (gimple_call_arg (def_stmt, 0)) == SSA_NAME) |
2226 && (TREE_CODE (gimple_call_arg (def_stmt, 1)) == ADDR_EXPR | 2378 && (TREE_CODE (gimple_call_arg (def_stmt, 1)) == ADDR_EXPR |
2227 || TREE_CODE (gimple_call_arg (def_stmt, 1)) == SSA_NAME) | 2379 || TREE_CODE (gimple_call_arg (def_stmt, 1)) == SSA_NAME) |
2228 && tree_fits_uhwi_p (gimple_call_arg (def_stmt, 2))) | 2380 && poly_int_tree_p (gimple_call_arg (def_stmt, 2), ©_size)) |
2229 { | 2381 { |
2230 tree lhs, rhs; | 2382 tree lhs, rhs; |
2231 ao_ref r; | 2383 ao_ref r; |
2232 HOST_WIDE_INT rhs_offset, copy_size, lhs_offset; | 2384 poly_int64 rhs_offset, lhs_offset; |
2233 vn_reference_op_s op; | 2385 vn_reference_op_s op; |
2234 HOST_WIDE_INT at; | 2386 poly_uint64 mem_offset; |
2387 poly_int64 at, byte_maxsize; | |
2235 | 2388 |
2236 /* Only handle non-variable, addressable refs. */ | 2389 /* Only handle non-variable, addressable refs. */ |
2237 if (ref->size != maxsize | 2390 if (maybe_ne (ref->size, maxsize) |
2238 || offset % BITS_PER_UNIT != 0 | 2391 || !multiple_p (offset, BITS_PER_UNIT, &at) |
2239 || ref->size % BITS_PER_UNIT != 0) | 2392 || !multiple_p (maxsize, BITS_PER_UNIT, &byte_maxsize)) |
2240 return (void *)-1; | 2393 return (void *)-1; |
2241 | 2394 |
2242 /* Extract a pointer base and an offset for the destination. */ | 2395 /* Extract a pointer base and an offset for the destination. */ |
2243 lhs = gimple_call_arg (def_stmt, 0); | 2396 lhs = gimple_call_arg (def_stmt, 0); |
2244 lhs_offset = 0; | 2397 lhs_offset = 0; |
2245 if (TREE_CODE (lhs) == SSA_NAME) | 2398 if (TREE_CODE (lhs) == SSA_NAME) |
2246 { | 2399 { |
2247 lhs = SSA_VAL (lhs); | 2400 lhs = vn_valueize (lhs); |
2248 if (TREE_CODE (lhs) == SSA_NAME) | 2401 if (TREE_CODE (lhs) == SSA_NAME) |
2249 { | 2402 { |
2250 gimple *def_stmt = SSA_NAME_DEF_STMT (lhs); | 2403 gimple *def_stmt = SSA_NAME_DEF_STMT (lhs); |
2251 if (gimple_assign_single_p (def_stmt) | 2404 if (gimple_assign_single_p (def_stmt) |
2252 && gimple_assign_rhs_code (def_stmt) == ADDR_EXPR) | 2405 && gimple_assign_rhs_code (def_stmt) == ADDR_EXPR) |
2258 tree tem = get_addr_base_and_unit_offset (TREE_OPERAND (lhs, 0), | 2411 tree tem = get_addr_base_and_unit_offset (TREE_OPERAND (lhs, 0), |
2259 &lhs_offset); | 2412 &lhs_offset); |
2260 if (!tem) | 2413 if (!tem) |
2261 return (void *)-1; | 2414 return (void *)-1; |
2262 if (TREE_CODE (tem) == MEM_REF | 2415 if (TREE_CODE (tem) == MEM_REF |
2263 && tree_fits_uhwi_p (TREE_OPERAND (tem, 1))) | 2416 && poly_int_tree_p (TREE_OPERAND (tem, 1), &mem_offset)) |
2264 { | 2417 { |
2265 lhs = TREE_OPERAND (tem, 0); | 2418 lhs = TREE_OPERAND (tem, 0); |
2266 if (TREE_CODE (lhs) == SSA_NAME) | 2419 if (TREE_CODE (lhs) == SSA_NAME) |
2267 lhs = SSA_VAL (lhs); | 2420 lhs = vn_valueize (lhs); |
2268 lhs_offset += tree_to_uhwi (TREE_OPERAND (tem, 1)); | 2421 lhs_offset += mem_offset; |
2269 } | 2422 } |
2270 else if (DECL_P (tem)) | 2423 else if (DECL_P (tem)) |
2271 lhs = build_fold_addr_expr (tem); | 2424 lhs = build_fold_addr_expr (tem); |
2272 else | 2425 else |
2273 return (void *)-1; | 2426 return (void *)-1; |
2278 | 2431 |
2279 /* Extract a pointer base and an offset for the source. */ | 2432 /* Extract a pointer base and an offset for the source. */ |
2280 rhs = gimple_call_arg (def_stmt, 1); | 2433 rhs = gimple_call_arg (def_stmt, 1); |
2281 rhs_offset = 0; | 2434 rhs_offset = 0; |
2282 if (TREE_CODE (rhs) == SSA_NAME) | 2435 if (TREE_CODE (rhs) == SSA_NAME) |
2283 rhs = SSA_VAL (rhs); | 2436 rhs = vn_valueize (rhs); |
2284 if (TREE_CODE (rhs) == ADDR_EXPR) | 2437 if (TREE_CODE (rhs) == ADDR_EXPR) |
2285 { | 2438 { |
2286 tree tem = get_addr_base_and_unit_offset (TREE_OPERAND (rhs, 0), | 2439 tree tem = get_addr_base_and_unit_offset (TREE_OPERAND (rhs, 0), |
2287 &rhs_offset); | 2440 &rhs_offset); |
2288 if (!tem) | 2441 if (!tem) |
2289 return (void *)-1; | 2442 return (void *)-1; |
2290 if (TREE_CODE (tem) == MEM_REF | 2443 if (TREE_CODE (tem) == MEM_REF |
2291 && tree_fits_uhwi_p (TREE_OPERAND (tem, 1))) | 2444 && poly_int_tree_p (TREE_OPERAND (tem, 1), &mem_offset)) |
2292 { | 2445 { |
2293 rhs = TREE_OPERAND (tem, 0); | 2446 rhs = TREE_OPERAND (tem, 0); |
2294 rhs_offset += tree_to_uhwi (TREE_OPERAND (tem, 1)); | 2447 rhs_offset += mem_offset; |
2295 } | 2448 } |
2296 else if (DECL_P (tem)) | 2449 else if (DECL_P (tem) |
2450 || TREE_CODE (tem) == STRING_CST) | |
2297 rhs = build_fold_addr_expr (tem); | 2451 rhs = build_fold_addr_expr (tem); |
2298 else | 2452 else |
2299 return (void *)-1; | 2453 return (void *)-1; |
2300 } | 2454 } |
2301 if (TREE_CODE (rhs) != SSA_NAME | 2455 if (TREE_CODE (rhs) != SSA_NAME |
2302 && TREE_CODE (rhs) != ADDR_EXPR) | 2456 && TREE_CODE (rhs) != ADDR_EXPR) |
2303 return (void *)-1; | 2457 return (void *)-1; |
2304 | 2458 |
2305 copy_size = tree_to_uhwi (gimple_call_arg (def_stmt, 2)); | |
2306 | |
2307 /* The bases of the destination and the references have to agree. */ | 2459 /* The bases of the destination and the references have to agree. */ |
2308 if ((TREE_CODE (base) != MEM_REF | 2460 if (TREE_CODE (base) == MEM_REF) |
2309 && !DECL_P (base)) | 2461 { |
2310 || (TREE_CODE (base) == MEM_REF | 2462 if (TREE_OPERAND (base, 0) != lhs |
2311 && (TREE_OPERAND (base, 0) != lhs | 2463 || !poly_int_tree_p (TREE_OPERAND (base, 1), &mem_offset)) |
2312 || !tree_fits_uhwi_p (TREE_OPERAND (base, 1)))) | 2464 return (void *) -1; |
2313 || (DECL_P (base) | 2465 at += mem_offset; |
2314 && (TREE_CODE (lhs) != ADDR_EXPR | 2466 } |
2315 || TREE_OPERAND (lhs, 0) != base))) | 2467 else if (!DECL_P (base) |
2468 || TREE_CODE (lhs) != ADDR_EXPR | |
2469 || TREE_OPERAND (lhs, 0) != base) | |
2316 return (void *)-1; | 2470 return (void *)-1; |
2317 | 2471 |
2318 at = offset / BITS_PER_UNIT; | |
2319 if (TREE_CODE (base) == MEM_REF) | |
2320 at += tree_to_uhwi (TREE_OPERAND (base, 1)); | |
2321 /* If the access is completely outside of the memcpy destination | 2472 /* If the access is completely outside of the memcpy destination |
2322 area there is no aliasing. */ | 2473 area there is no aliasing. */ |
2323 if (lhs_offset >= at + maxsize / BITS_PER_UNIT | 2474 if (!ranges_maybe_overlap_p (lhs_offset, copy_size, at, byte_maxsize)) |
2324 || lhs_offset + copy_size <= at) | |
2325 return NULL; | 2475 return NULL; |
2326 /* And the access has to be contained within the memcpy destination. */ | 2476 /* And the access has to be contained within the memcpy destination. */ |
2327 if (lhs_offset > at | 2477 if (!known_subrange_p (at, byte_maxsize, lhs_offset, copy_size)) |
2328 || lhs_offset + copy_size < at + maxsize / BITS_PER_UNIT) | |
2329 return (void *)-1; | 2478 return (void *)-1; |
2330 | 2479 |
2331 /* Make room for 2 operands in the new reference. */ | 2480 /* Make room for 2 operands in the new reference. */ |
2332 if (vr->operands.length () < 2) | 2481 if (vr->operands.length () < 2) |
2333 { | 2482 { |
2361 | 2510 |
2362 /* Adjust *ref from the new operands. */ | 2511 /* Adjust *ref from the new operands. */ |
2363 if (!ao_ref_init_from_vn_reference (&r, vr->set, vr->type, vr->operands)) | 2512 if (!ao_ref_init_from_vn_reference (&r, vr->set, vr->type, vr->operands)) |
2364 return (void *)-1; | 2513 return (void *)-1; |
2365 /* This can happen with bitfields. */ | 2514 /* This can happen with bitfields. */ |
2366 if (ref->size != r.size) | 2515 if (maybe_ne (ref->size, r.size)) |
2367 return (void *)-1; | 2516 return (void *)-1; |
2368 *ref = r; | 2517 *ref = r; |
2369 | 2518 |
2370 /* Do not update last seen VUSE after translating. */ | 2519 /* Do not update last seen VUSE after translating. */ |
2371 last_vuse_ptr = NULL; | 2520 last_vuse_ptr = NULL; |
2432 if (ao_ref_init_from_vn_reference (&r, set, type, vr1.operands)) | 2581 if (ao_ref_init_from_vn_reference (&r, set, type, vr1.operands)) |
2433 *vnresult = | 2582 *vnresult = |
2434 (vn_reference_t)walk_non_aliased_vuses (&r, vr1.vuse, | 2583 (vn_reference_t)walk_non_aliased_vuses (&r, vr1.vuse, |
2435 vn_reference_lookup_2, | 2584 vn_reference_lookup_2, |
2436 vn_reference_lookup_3, | 2585 vn_reference_lookup_3, |
2437 vuse_ssa_val, &vr1); | 2586 vuse_valueize, &vr1); |
2438 gcc_checking_assert (vr1.operands == shared_lookup_references); | 2587 gcc_checking_assert (vr1.operands == shared_lookup_references); |
2439 } | 2588 } |
2440 | 2589 |
2441 if (*vnresult) | 2590 if (*vnresult) |
2442 return (*vnresult)->result; | 2591 return (*vnresult)->result; |
2488 vn_walk_kind = kind; | 2637 vn_walk_kind = kind; |
2489 wvnresult = | 2638 wvnresult = |
2490 (vn_reference_t)walk_non_aliased_vuses (&r, vr1.vuse, | 2639 (vn_reference_t)walk_non_aliased_vuses (&r, vr1.vuse, |
2491 vn_reference_lookup_2, | 2640 vn_reference_lookup_2, |
2492 vn_reference_lookup_3, | 2641 vn_reference_lookup_3, |
2493 vuse_ssa_val, &vr1); | 2642 vuse_valueize, &vr1); |
2494 gcc_checking_assert (vr1.operands == shared_lookup_references); | 2643 gcc_checking_assert (vr1.operands == shared_lookup_references); |
2495 if (wvnresult) | 2644 if (wvnresult) |
2496 { | 2645 { |
2497 if (vnresult) | 2646 if (vnresult) |
2498 *vnresult = wvnresult; | 2647 *vnresult = wvnresult; |
2523 vr->set = 0; | 2672 vr->set = 0; |
2524 vr->hashcode = vn_reference_compute_hash (vr); | 2673 vr->hashcode = vn_reference_compute_hash (vr); |
2525 vn_reference_lookup_1 (vr, vnresult); | 2674 vn_reference_lookup_1 (vr, vnresult); |
2526 } | 2675 } |
2527 | 2676 |
2528 /* Insert OP into the current hash table with a value number of | 2677 /* Insert OP into the current hash table with a value number of RESULT. */ |
2529 RESULT, and return the resulting reference structure we created. */ | 2678 |
2530 | 2679 static void |
2531 static vn_reference_t | |
2532 vn_reference_insert (tree op, tree result, tree vuse, tree vdef) | 2680 vn_reference_insert (tree op, tree result, tree vuse, tree vdef) |
2533 { | 2681 { |
2534 vn_reference_s **slot; | 2682 vn_reference_s **slot; |
2535 vn_reference_t vr1; | 2683 vn_reference_t vr1; |
2536 bool tem; | 2684 bool tem; |
2537 | 2685 |
2538 vr1 = current_info->references_pool->allocate (); | 2686 vr1 = XOBNEW (&vn_tables_obstack, vn_reference_s); |
2539 if (TREE_CODE (result) == SSA_NAME) | 2687 if (TREE_CODE (result) == SSA_NAME) |
2540 vr1->value_id = VN_INFO (result)->value_id; | 2688 vr1->value_id = VN_INFO (result)->value_id; |
2541 else | 2689 else |
2542 vr1->value_id = get_or_alloc_constant_value_id (result); | 2690 vr1->value_id = get_or_alloc_constant_value_id (result); |
2543 vr1->vuse = vuse ? SSA_VAL (vuse) : NULL_TREE; | 2691 vr1->vuse = vuse_ssa_val (vuse); |
2544 vr1->operands = valueize_shared_reference_ops_from_ref (op, &tem).copy (); | 2692 vr1->operands = valueize_shared_reference_ops_from_ref (op, &tem).copy (); |
2545 vr1->type = TREE_TYPE (op); | 2693 vr1->type = TREE_TYPE (op); |
2546 vr1->set = get_alias_set (op); | 2694 vr1->set = get_alias_set (op); |
2547 vr1->hashcode = vn_reference_compute_hash (vr1); | 2695 vr1->hashcode = vn_reference_compute_hash (vr1); |
2548 vr1->result = TREE_CODE (result) == SSA_NAME ? SSA_VAL (result) : result; | 2696 vr1->result = TREE_CODE (result) == SSA_NAME ? SSA_VAL (result) : result; |
2549 vr1->result_vdef = vdef; | 2697 vr1->result_vdef = vdef; |
2550 | 2698 |
2551 slot = current_info->references->find_slot_with_hash (vr1, vr1->hashcode, | 2699 slot = valid_info->references->find_slot_with_hash (vr1, vr1->hashcode, |
2552 INSERT); | 2700 INSERT); |
2553 | 2701 |
2554 /* Because we lookup stores using vuses, and value number failures | 2702 /* Because IL walking on reference lookup can end up visiting |
2555 using the vdefs (see visit_reference_op_store for how and why), | 2703 a def that is only to be visited later in iteration order |
2556 it's possible that on failure we may try to insert an already | 2704 when we are about to make an irreducible region reducible |
2557 inserted store. This is not wrong, there is no ssa name for a | 2705 the def can be effectively processed and its ref being inserted |
2558 store that we could use as a differentiator anyway. Thus, unlike | 2706 by vn_reference_lookup_3 already. So we cannot assert (!*slot) |
2559 the other lookup functions, you cannot gcc_assert (!*slot) | 2707 but save a lookup if we deal with already inserted refs here. */ |
2560 here. */ | |
2561 | |
2562 /* But free the old slot in case of a collision. */ | |
2563 if (*slot) | 2708 if (*slot) |
2564 free_reference (*slot); | 2709 { |
2710 /* We cannot assert that we have the same value either because | |
2711 when disentangling an irreducible region we may end up visiting | |
2712 a use before the corresponding def. That's a missed optimization | |
2713 only though. See gcc.dg/tree-ssa/pr87126.c for example. */ | |
2714 if (dump_file && (dump_flags & TDF_DETAILS) | |
2715 && !operand_equal_p ((*slot)->result, vr1->result, 0)) | |
2716 { | |
2717 fprintf (dump_file, "Keeping old value "); | |
2718 print_generic_expr (dump_file, (*slot)->result); | |
2719 fprintf (dump_file, " because of collision\n"); | |
2720 } | |
2721 free_reference (vr1); | |
2722 obstack_free (&vn_tables_obstack, vr1); | |
2723 return; | |
2724 } | |
2565 | 2725 |
2566 *slot = vr1; | 2726 *slot = vr1; |
2567 return vr1; | 2727 vr1->next = last_inserted_ref; |
2728 last_inserted_ref = vr1; | |
2568 } | 2729 } |
2569 | 2730 |
2570 /* Insert a reference by it's pieces into the current hash table with | 2731 /* Insert a reference by it's pieces into the current hash table with |
2571 a value number of RESULT. Return the resulting reference | 2732 a value number of RESULT. Return the resulting reference |
2572 structure we created. */ | 2733 structure we created. */ |
2578 | 2739 |
2579 { | 2740 { |
2580 vn_reference_s **slot; | 2741 vn_reference_s **slot; |
2581 vn_reference_t vr1; | 2742 vn_reference_t vr1; |
2582 | 2743 |
2583 vr1 = current_info->references_pool->allocate (); | 2744 vr1 = XOBNEW (&vn_tables_obstack, vn_reference_s); |
2584 vr1->value_id = value_id; | 2745 vr1->value_id = value_id; |
2585 vr1->vuse = vuse ? SSA_VAL (vuse) : NULL_TREE; | 2746 vr1->vuse = vuse_ssa_val (vuse); |
2586 vr1->operands = valueize_refs (operands); | 2747 vr1->operands = valueize_refs (operands); |
2587 vr1->type = type; | 2748 vr1->type = type; |
2588 vr1->set = set; | 2749 vr1->set = set; |
2589 vr1->hashcode = vn_reference_compute_hash (vr1); | 2750 vr1->hashcode = vn_reference_compute_hash (vr1); |
2590 if (result && TREE_CODE (result) == SSA_NAME) | 2751 if (result && TREE_CODE (result) == SSA_NAME) |
2591 result = SSA_VAL (result); | 2752 result = SSA_VAL (result); |
2592 vr1->result = result; | 2753 vr1->result = result; |
2593 | 2754 |
2594 slot = current_info->references->find_slot_with_hash (vr1, vr1->hashcode, | 2755 slot = valid_info->references->find_slot_with_hash (vr1, vr1->hashcode, |
2595 INSERT); | 2756 INSERT); |
2596 | 2757 |
2597 /* At this point we should have all the things inserted that we have | 2758 /* At this point we should have all the things inserted that we have |
2598 seen before, and we should never try inserting something that | 2759 seen before, and we should never try inserting something that |
2599 already exists. */ | 2760 already exists. */ |
2600 gcc_assert (!*slot); | 2761 gcc_assert (!*slot); |
2601 if (*slot) | |
2602 free_reference (*slot); | |
2603 | 2762 |
2604 *slot = vr1; | 2763 *slot = vr1; |
2764 vr1->next = last_inserted_ref; | |
2765 last_inserted_ref = vr1; | |
2605 return vr1; | 2766 return vr1; |
2606 } | 2767 } |
2607 | 2768 |
2608 /* Compute and return the hash value for nary operation VBO1. */ | 2769 /* Compute and return the hash value for nary operation VBO1. */ |
2609 | 2770 |
2771 | 2932 |
2772 if (vnresult) | 2933 if (vnresult) |
2773 *vnresult = NULL; | 2934 *vnresult = NULL; |
2774 | 2935 |
2775 vno->hashcode = vn_nary_op_compute_hash (vno); | 2936 vno->hashcode = vn_nary_op_compute_hash (vno); |
2776 slot = current_info->nary->find_slot_with_hash (vno, vno->hashcode, | 2937 slot = valid_info->nary->find_slot_with_hash (vno, vno->hashcode, NO_INSERT); |
2777 NO_INSERT); | |
2778 if (!slot && current_info == optimistic_info) | |
2779 slot = valid_info->nary->find_slot_with_hash (vno, vno->hashcode, | |
2780 NO_INSERT); | |
2781 if (!slot) | 2938 if (!slot) |
2782 return NULL_TREE; | 2939 return NULL_TREE; |
2783 if (vnresult) | 2940 if (vnresult) |
2784 *vnresult = *slot; | 2941 *vnresult = *slot; |
2785 return (*slot)->result; | 2942 return (*slot)->predicated_values ? NULL_TREE : (*slot)->u.result; |
2786 } | 2943 } |
2787 | 2944 |
2788 /* Lookup a n-ary operation by its pieces and return the resulting value | 2945 /* Lookup a n-ary operation by its pieces and return the resulting value |
2789 number if it exists in the hash table. Return NULL_TREE if it does | 2946 number if it exists in the hash table. Return NULL_TREE if it does |
2790 not exist in the hash table or if the result field of the operation | 2947 not exist in the hash table or if the result field of the operation |
2844 obstack. */ | 3001 obstack. */ |
2845 | 3002 |
2846 static vn_nary_op_t | 3003 static vn_nary_op_t |
2847 alloc_vn_nary_op (unsigned int length, tree result, unsigned int value_id) | 3004 alloc_vn_nary_op (unsigned int length, tree result, unsigned int value_id) |
2848 { | 3005 { |
2849 vn_nary_op_t vno1 = alloc_vn_nary_op_noinit (length, | 3006 vn_nary_op_t vno1 = alloc_vn_nary_op_noinit (length, &vn_tables_obstack); |
2850 ¤t_info->nary_obstack); | |
2851 | 3007 |
2852 vno1->value_id = value_id; | 3008 vno1->value_id = value_id; |
2853 vno1->length = length; | 3009 vno1->length = length; |
2854 vno1->result = result; | 3010 vno1->predicated_values = 0; |
3011 vno1->u.result = result; | |
2855 | 3012 |
2856 return vno1; | 3013 return vno1; |
2857 } | 3014 } |
2858 | 3015 |
2859 /* Insert VNO into TABLE. If COMPUTE_HASH is true, then compute | 3016 /* Insert VNO into TABLE. If COMPUTE_HASH is true, then compute |
2864 bool compute_hash) | 3021 bool compute_hash) |
2865 { | 3022 { |
2866 vn_nary_op_s **slot; | 3023 vn_nary_op_s **slot; |
2867 | 3024 |
2868 if (compute_hash) | 3025 if (compute_hash) |
2869 vno->hashcode = vn_nary_op_compute_hash (vno); | 3026 { |
3027 vno->hashcode = vn_nary_op_compute_hash (vno); | |
3028 gcc_assert (! vno->predicated_values | |
3029 || (! vno->u.values->next | |
3030 && vno->u.values->n == 1)); | |
3031 } | |
2870 | 3032 |
2871 slot = table->find_slot_with_hash (vno, vno->hashcode, INSERT); | 3033 slot = table->find_slot_with_hash (vno, vno->hashcode, INSERT); |
2872 /* While we do not want to insert things twice it's awkward to | 3034 vno->unwind_to = *slot; |
2873 avoid it in the case where visit_nary_op pattern-matches stuff | 3035 if (*slot) |
2874 and ends up simplifying the replacement to itself. We then | 3036 { |
2875 get two inserts, one from visit_nary_op and one from | 3037 /* Prefer non-predicated values. |
2876 vn_nary_build_or_lookup. | 3038 ??? Only if those are constant, otherwise, with constant predicated |
2877 So allow inserts with the same value number. */ | 3039 value, turn them into predicated values with entry-block validity |
2878 if (*slot && (*slot)->result == vno->result) | 3040 (??? but we always find the first valid result currently). */ |
2879 return *slot; | 3041 if ((*slot)->predicated_values |
2880 | 3042 && ! vno->predicated_values) |
3043 { | |
3044 /* ??? We cannot remove *slot from the unwind stack list. | |
3045 For the moment we deal with this by skipping not found | |
3046 entries but this isn't ideal ... */ | |
3047 *slot = vno; | |
3048 /* ??? Maintain a stack of states we can unwind in | |
3049 vn_nary_op_s? But how far do we unwind? In reality | |
3050 we need to push change records somewhere... Or not | |
3051 unwind vn_nary_op_s and linking them but instead | |
3052 unwind the results "list", linking that, which also | |
3053 doesn't move on hashtable resize. */ | |
3054 /* We can also have a ->unwind_to recording *slot there. | |
3055 That way we can make u.values a fixed size array with | |
3056 recording the number of entries but of course we then | |
3057 have always N copies for each unwind_to-state. Or we | |
3058 make sure to only ever append and each unwinding will | |
3059 pop off one entry (but how to deal with predicated | |
3060 replaced with non-predicated here?) */ | |
3061 vno->next = last_inserted_nary; | |
3062 last_inserted_nary = vno; | |
3063 return vno; | |
3064 } | |
3065 else if (vno->predicated_values | |
3066 && ! (*slot)->predicated_values) | |
3067 return *slot; | |
3068 else if (vno->predicated_values | |
3069 && (*slot)->predicated_values) | |
3070 { | |
3071 /* ??? Factor this all into a insert_single_predicated_value | |
3072 routine. */ | |
3073 gcc_assert (!vno->u.values->next && vno->u.values->n == 1); | |
3074 basic_block vno_bb | |
3075 = BASIC_BLOCK_FOR_FN (cfun, vno->u.values->valid_dominated_by_p[0]); | |
3076 vn_pval *nval = vno->u.values; | |
3077 vn_pval **next = &vno->u.values; | |
3078 bool found = false; | |
3079 for (vn_pval *val = (*slot)->u.values; val; val = val->next) | |
3080 { | |
3081 if (expressions_equal_p (val->result, vno->u.values->result)) | |
3082 { | |
3083 found = true; | |
3084 for (unsigned i = 0; i < val->n; ++i) | |
3085 { | |
3086 basic_block val_bb | |
3087 = BASIC_BLOCK_FOR_FN (cfun, | |
3088 val->valid_dominated_by_p[i]); | |
3089 if (dominated_by_p (CDI_DOMINATORS, vno_bb, val_bb)) | |
3090 /* Value registered with more generic predicate. */ | |
3091 return *slot; | |
3092 else if (dominated_by_p (CDI_DOMINATORS, val_bb, vno_bb)) | |
3093 /* Shouldn't happen, we insert in RPO order. */ | |
3094 gcc_unreachable (); | |
3095 } | |
3096 /* Append value. */ | |
3097 *next = (vn_pval *) obstack_alloc (&vn_tables_obstack, | |
3098 sizeof (vn_pval) | |
3099 + val->n * sizeof (int)); | |
3100 (*next)->next = NULL; | |
3101 (*next)->result = val->result; | |
3102 (*next)->n = val->n + 1; | |
3103 memcpy ((*next)->valid_dominated_by_p, | |
3104 val->valid_dominated_by_p, | |
3105 val->n * sizeof (int)); | |
3106 (*next)->valid_dominated_by_p[val->n] = vno_bb->index; | |
3107 next = &(*next)->next; | |
3108 if (dump_file && (dump_flags & TDF_DETAILS)) | |
3109 fprintf (dump_file, "Appending predicate to value.\n"); | |
3110 continue; | |
3111 } | |
3112 /* Copy other predicated values. */ | |
3113 *next = (vn_pval *) obstack_alloc (&vn_tables_obstack, | |
3114 sizeof (vn_pval) | |
3115 + (val->n-1) * sizeof (int)); | |
3116 memcpy (*next, val, sizeof (vn_pval) + (val->n-1) * sizeof (int)); | |
3117 (*next)->next = NULL; | |
3118 next = &(*next)->next; | |
3119 } | |
3120 if (!found) | |
3121 *next = nval; | |
3122 | |
3123 *slot = vno; | |
3124 vno->next = last_inserted_nary; | |
3125 last_inserted_nary = vno; | |
3126 return vno; | |
3127 } | |
3128 | |
3129 /* While we do not want to insert things twice it's awkward to | |
3130 avoid it in the case where visit_nary_op pattern-matches stuff | |
3131 and ends up simplifying the replacement to itself. We then | |
3132 get two inserts, one from visit_nary_op and one from | |
3133 vn_nary_build_or_lookup. | |
3134 So allow inserts with the same value number. */ | |
3135 if ((*slot)->u.result == vno->u.result) | |
3136 return *slot; | |
3137 } | |
3138 | |
3139 /* ??? There's also optimistic vs. previous commited state merging | |
3140 that is problematic for the case of unwinding. */ | |
3141 | |
3142 /* ??? We should return NULL if we do not use 'vno' and have the | |
3143 caller release it. */ | |
2881 gcc_assert (!*slot); | 3144 gcc_assert (!*slot); |
2882 | 3145 |
2883 *slot = vno; | 3146 *slot = vno; |
3147 vno->next = last_inserted_nary; | |
3148 last_inserted_nary = vno; | |
2884 return vno; | 3149 return vno; |
2885 } | 3150 } |
2886 | 3151 |
2887 /* Insert a n-ary operation into the current hash table using it's | 3152 /* Insert a n-ary operation into the current hash table using it's |
2888 pieces. Return the vn_nary_op_t structure we created and put in | 3153 pieces. Return the vn_nary_op_t structure we created and put in |
2893 tree type, tree *ops, | 3158 tree type, tree *ops, |
2894 tree result, unsigned int value_id) | 3159 tree result, unsigned int value_id) |
2895 { | 3160 { |
2896 vn_nary_op_t vno1 = alloc_vn_nary_op (length, result, value_id); | 3161 vn_nary_op_t vno1 = alloc_vn_nary_op (length, result, value_id); |
2897 init_vn_nary_op_from_pieces (vno1, length, code, type, ops); | 3162 init_vn_nary_op_from_pieces (vno1, length, code, type, ops); |
2898 return vn_nary_op_insert_into (vno1, current_info->nary, true); | 3163 return vn_nary_op_insert_into (vno1, valid_info->nary, true); |
3164 } | |
3165 | |
3166 static vn_nary_op_t | |
3167 vn_nary_op_insert_pieces_predicated (unsigned int length, enum tree_code code, | |
3168 tree type, tree *ops, | |
3169 tree result, unsigned int value_id, | |
3170 edge pred_e) | |
3171 { | |
3172 /* ??? Currently tracking BBs. */ | |
3173 if (! single_pred_p (pred_e->dest)) | |
3174 { | |
3175 /* Never record for backedges. */ | |
3176 if (pred_e->flags & EDGE_DFS_BACK) | |
3177 return NULL; | |
3178 edge_iterator ei; | |
3179 edge e; | |
3180 int cnt = 0; | |
3181 /* Ignore backedges. */ | |
3182 FOR_EACH_EDGE (e, ei, pred_e->dest->preds) | |
3183 if (! dominated_by_p (CDI_DOMINATORS, e->src, e->dest)) | |
3184 cnt++; | |
3185 if (cnt != 1) | |
3186 return NULL; | |
3187 } | |
3188 if (dump_file && (dump_flags & TDF_DETAILS) | |
3189 /* ??? Fix dumping, but currently we only get comparisons. */ | |
3190 && TREE_CODE_CLASS (code) == tcc_comparison) | |
3191 { | |
3192 fprintf (dump_file, "Recording on edge %d->%d ", pred_e->src->index, | |
3193 pred_e->dest->index); | |
3194 print_generic_expr (dump_file, ops[0], TDF_SLIM); | |
3195 fprintf (dump_file, " %s ", get_tree_code_name (code)); | |
3196 print_generic_expr (dump_file, ops[1], TDF_SLIM); | |
3197 fprintf (dump_file, " == %s\n", | |
3198 integer_zerop (result) ? "false" : "true"); | |
3199 } | |
3200 vn_nary_op_t vno1 = alloc_vn_nary_op (length, NULL_TREE, value_id); | |
3201 init_vn_nary_op_from_pieces (vno1, length, code, type, ops); | |
3202 vno1->predicated_values = 1; | |
3203 vno1->u.values = (vn_pval *) obstack_alloc (&vn_tables_obstack, | |
3204 sizeof (vn_pval)); | |
3205 vno1->u.values->next = NULL; | |
3206 vno1->u.values->result = result; | |
3207 vno1->u.values->n = 1; | |
3208 vno1->u.values->valid_dominated_by_p[0] = pred_e->dest->index; | |
3209 return vn_nary_op_insert_into (vno1, valid_info->nary, true); | |
3210 } | |
3211 | |
3212 static bool | |
3213 dominated_by_p_w_unex (basic_block bb1, basic_block bb2); | |
3214 | |
3215 static tree | |
3216 vn_nary_op_get_predicated_value (vn_nary_op_t vno, basic_block bb) | |
3217 { | |
3218 if (! vno->predicated_values) | |
3219 return vno->u.result; | |
3220 for (vn_pval *val = vno->u.values; val; val = val->next) | |
3221 for (unsigned i = 0; i < val->n; ++i) | |
3222 if (dominated_by_p_w_unex (bb, | |
3223 BASIC_BLOCK_FOR_FN | |
3224 (cfun, val->valid_dominated_by_p[i]))) | |
3225 return val->result; | |
3226 return NULL_TREE; | |
2899 } | 3227 } |
2900 | 3228 |
2901 /* Insert OP into the current hash table with a value number of | 3229 /* Insert OP into the current hash table with a value number of |
2902 RESULT. Return the vn_nary_op_t structure we created and put in | 3230 RESULT. Return the vn_nary_op_t structure we created and put in |
2903 the hashtable. */ | 3231 the hashtable. */ |
2908 unsigned length = TREE_CODE_LENGTH (TREE_CODE (op)); | 3236 unsigned length = TREE_CODE_LENGTH (TREE_CODE (op)); |
2909 vn_nary_op_t vno1; | 3237 vn_nary_op_t vno1; |
2910 | 3238 |
2911 vno1 = alloc_vn_nary_op (length, result, VN_INFO (result)->value_id); | 3239 vno1 = alloc_vn_nary_op (length, result, VN_INFO (result)->value_id); |
2912 init_vn_nary_op_from_op (vno1, op); | 3240 init_vn_nary_op_from_op (vno1, op); |
2913 return vn_nary_op_insert_into (vno1, current_info->nary, true); | 3241 return vn_nary_op_insert_into (vno1, valid_info->nary, true); |
2914 } | 3242 } |
2915 | 3243 |
2916 /* Insert the rhs of STMT into the current hash table with a value number of | 3244 /* Insert the rhs of STMT into the current hash table with a value number of |
2917 RESULT. */ | 3245 RESULT. */ |
2918 | 3246 |
2921 { | 3249 { |
2922 vn_nary_op_t vno1 | 3250 vn_nary_op_t vno1 |
2923 = alloc_vn_nary_op (vn_nary_length_from_stmt (stmt), | 3251 = alloc_vn_nary_op (vn_nary_length_from_stmt (stmt), |
2924 result, VN_INFO (result)->value_id); | 3252 result, VN_INFO (result)->value_id); |
2925 init_vn_nary_op_from_stmt (vno1, stmt); | 3253 init_vn_nary_op_from_stmt (vno1, stmt); |
2926 return vn_nary_op_insert_into (vno1, current_info->nary, true); | 3254 return vn_nary_op_insert_into (vno1, valid_info->nary, true); |
2927 } | 3255 } |
2928 | 3256 |
2929 /* Compute a hashcode for PHI operation VP1 and return it. */ | 3257 /* Compute a hashcode for PHI operation VP1 and return it. */ |
2930 | 3258 |
2931 static inline hashval_t | 3259 static inline hashval_t |
2932 vn_phi_compute_hash (vn_phi_t vp1) | 3260 vn_phi_compute_hash (vn_phi_t vp1) |
2933 { | 3261 { |
2934 inchash::hash hstate (vp1->phiargs.length () > 2 | 3262 inchash::hash hstate (EDGE_COUNT (vp1->block->preds) > 2 |
2935 ? vp1->block->index : vp1->phiargs.length ()); | 3263 ? vp1->block->index : EDGE_COUNT (vp1->block->preds)); |
2936 tree phi1op; | 3264 tree phi1op; |
2937 tree type; | 3265 tree type; |
2938 edge e; | 3266 edge e; |
2939 edge_iterator ei; | 3267 edge_iterator ei; |
2940 | 3268 |
3002 if (vp1->hashcode != vp2->hashcode) | 3330 if (vp1->hashcode != vp2->hashcode) |
3003 return false; | 3331 return false; |
3004 | 3332 |
3005 if (vp1->block != vp2->block) | 3333 if (vp1->block != vp2->block) |
3006 { | 3334 { |
3007 if (vp1->phiargs.length () != vp2->phiargs.length ()) | 3335 if (EDGE_COUNT (vp1->block->preds) != EDGE_COUNT (vp2->block->preds)) |
3008 return false; | 3336 return false; |
3009 | 3337 |
3010 switch (vp1->phiargs.length ()) | 3338 switch (EDGE_COUNT (vp1->block->preds)) |
3011 { | 3339 { |
3012 case 1: | 3340 case 1: |
3013 /* Single-arg PHIs are just copies. */ | 3341 /* Single-arg PHIs are just copies. */ |
3014 break; | 3342 break; |
3015 | 3343 |
3080 if (!types_compatible_p (vp1->type, vp2->type)) | 3408 if (!types_compatible_p (vp1->type, vp2->type)) |
3081 return false; | 3409 return false; |
3082 | 3410 |
3083 /* Any phi in the same block will have it's arguments in the | 3411 /* Any phi in the same block will have it's arguments in the |
3084 same edge order, because of how we store phi nodes. */ | 3412 same edge order, because of how we store phi nodes. */ |
3085 int i; | 3413 for (unsigned i = 0; i < EDGE_COUNT (vp1->block->preds); ++i) |
3086 tree phi1op; | 3414 { |
3087 FOR_EACH_VEC_ELT (vp1->phiargs, i, phi1op) | 3415 tree phi1op = vp1->phiargs[i]; |
3088 { | |
3089 tree phi2op = vp2->phiargs[i]; | 3416 tree phi2op = vp2->phiargs[i]; |
3090 if (phi1op == VN_TOP || phi2op == VN_TOP) | 3417 if (phi1op == VN_TOP || phi2op == VN_TOP) |
3091 continue; | 3418 continue; |
3092 if (!expressions_equal_p (phi1op, phi2op)) | 3419 if (!expressions_equal_p (phi1op, phi2op)) |
3093 return false; | 3420 return false; |
3094 } | 3421 } |
3095 | 3422 |
3096 return true; | 3423 return true; |
3097 } | 3424 } |
3098 | 3425 |
3099 static vec<tree> shared_lookup_phiargs; | |
3100 | |
3101 /* Lookup PHI in the current hash table, and return the resulting | 3426 /* Lookup PHI in the current hash table, and return the resulting |
3102 value number if it exists in the hash table. Return NULL_TREE if | 3427 value number if it exists in the hash table. Return NULL_TREE if |
3103 it does not exist in the hash table. */ | 3428 it does not exist in the hash table. */ |
3104 | 3429 |
3105 static tree | 3430 static tree |
3106 vn_phi_lookup (gimple *phi) | 3431 vn_phi_lookup (gimple *phi, bool backedges_varying_p) |
3107 { | 3432 { |
3108 vn_phi_s **slot; | 3433 vn_phi_s **slot; |
3109 struct vn_phi_s vp1; | 3434 struct vn_phi_s *vp1; |
3110 edge e; | 3435 edge e; |
3111 edge_iterator ei; | 3436 edge_iterator ei; |
3112 | 3437 |
3113 shared_lookup_phiargs.truncate (0); | 3438 vp1 = XALLOCAVAR (struct vn_phi_s, |
3114 shared_lookup_phiargs.safe_grow (gimple_phi_num_args (phi)); | 3439 sizeof (struct vn_phi_s) |
3440 + (gimple_phi_num_args (phi) - 1) * sizeof (tree)); | |
3115 | 3441 |
3116 /* Canonicalize the SSA_NAME's to their value number. */ | 3442 /* Canonicalize the SSA_NAME's to their value number. */ |
3117 FOR_EACH_EDGE (e, ei, gimple_bb (phi)->preds) | 3443 FOR_EACH_EDGE (e, ei, gimple_bb (phi)->preds) |
3118 { | 3444 { |
3119 tree def = PHI_ARG_DEF_FROM_EDGE (phi, e); | 3445 tree def = PHI_ARG_DEF_FROM_EDGE (phi, e); |
3120 def = TREE_CODE (def) == SSA_NAME ? SSA_VAL (def) : def; | 3446 if (TREE_CODE (def) == SSA_NAME |
3121 shared_lookup_phiargs[e->dest_idx] = def; | 3447 && (!backedges_varying_p || !(e->flags & EDGE_DFS_BACK))) |
3122 } | 3448 def = SSA_VAL (def); |
3123 vp1.type = TREE_TYPE (gimple_phi_result (phi)); | 3449 vp1->phiargs[e->dest_idx] = def; |
3124 vp1.phiargs = shared_lookup_phiargs; | 3450 } |
3125 vp1.block = gimple_bb (phi); | |
3126 /* Extract values of the controlling condition. */ | |
3127 vp1.cclhs = NULL_TREE; | |
3128 vp1.ccrhs = NULL_TREE; | |
3129 basic_block idom1 = get_immediate_dominator (CDI_DOMINATORS, vp1.block); | |
3130 if (EDGE_COUNT (idom1->succs) == 2) | |
3131 if (gcond *last1 = safe_dyn_cast <gcond *> (last_stmt (idom1))) | |
3132 { | |
3133 vp1.cclhs = vn_valueize (gimple_cond_lhs (last1)); | |
3134 vp1.ccrhs = vn_valueize (gimple_cond_rhs (last1)); | |
3135 } | |
3136 vp1.hashcode = vn_phi_compute_hash (&vp1); | |
3137 slot = current_info->phis->find_slot_with_hash (&vp1, vp1.hashcode, | |
3138 NO_INSERT); | |
3139 if (!slot && current_info == optimistic_info) | |
3140 slot = valid_info->phis->find_slot_with_hash (&vp1, vp1.hashcode, | |
3141 NO_INSERT); | |
3142 if (!slot) | |
3143 return NULL_TREE; | |
3144 return (*slot)->result; | |
3145 } | |
3146 | |
3147 /* Insert PHI into the current hash table with a value number of | |
3148 RESULT. */ | |
3149 | |
3150 static vn_phi_t | |
3151 vn_phi_insert (gimple *phi, tree result) | |
3152 { | |
3153 vn_phi_s **slot; | |
3154 vn_phi_t vp1 = current_info->phis_pool->allocate (); | |
3155 vec<tree> args = vNULL; | |
3156 edge e; | |
3157 edge_iterator ei; | |
3158 | |
3159 args.safe_grow (gimple_phi_num_args (phi)); | |
3160 | |
3161 /* Canonicalize the SSA_NAME's to their value number. */ | |
3162 FOR_EACH_EDGE (e, ei, gimple_bb (phi)->preds) | |
3163 { | |
3164 tree def = PHI_ARG_DEF_FROM_EDGE (phi, e); | |
3165 def = TREE_CODE (def) == SSA_NAME ? SSA_VAL (def) : def; | |
3166 args[e->dest_idx] = def; | |
3167 } | |
3168 vp1->value_id = VN_INFO (result)->value_id; | |
3169 vp1->type = TREE_TYPE (gimple_phi_result (phi)); | 3451 vp1->type = TREE_TYPE (gimple_phi_result (phi)); |
3170 vp1->phiargs = args; | |
3171 vp1->block = gimple_bb (phi); | 3452 vp1->block = gimple_bb (phi); |
3172 /* Extract values of the controlling condition. */ | 3453 /* Extract values of the controlling condition. */ |
3173 vp1->cclhs = NULL_TREE; | 3454 vp1->cclhs = NULL_TREE; |
3174 vp1->ccrhs = NULL_TREE; | 3455 vp1->ccrhs = NULL_TREE; |
3175 basic_block idom1 = get_immediate_dominator (CDI_DOMINATORS, vp1->block); | 3456 basic_block idom1 = get_immediate_dominator (CDI_DOMINATORS, vp1->block); |
3176 if (EDGE_COUNT (idom1->succs) == 2) | 3457 if (EDGE_COUNT (idom1->succs) == 2) |
3177 if (gcond *last1 = safe_dyn_cast <gcond *> (last_stmt (idom1))) | 3458 if (gcond *last1 = safe_dyn_cast <gcond *> (last_stmt (idom1))) |
3178 { | 3459 { |
3460 /* ??? We want to use SSA_VAL here. But possibly not | |
3461 allow VN_TOP. */ | |
3462 vp1->cclhs = vn_valueize (gimple_cond_lhs (last1)); | |
3463 vp1->ccrhs = vn_valueize (gimple_cond_rhs (last1)); | |
3464 } | |
3465 vp1->hashcode = vn_phi_compute_hash (vp1); | |
3466 slot = valid_info->phis->find_slot_with_hash (vp1, vp1->hashcode, NO_INSERT); | |
3467 if (!slot) | |
3468 return NULL_TREE; | |
3469 return (*slot)->result; | |
3470 } | |
3471 | |
3472 /* Insert PHI into the current hash table with a value number of | |
3473 RESULT. */ | |
3474 | |
3475 static vn_phi_t | |
3476 vn_phi_insert (gimple *phi, tree result, bool backedges_varying_p) | |
3477 { | |
3478 vn_phi_s **slot; | |
3479 vn_phi_t vp1 = (vn_phi_t) obstack_alloc (&vn_tables_obstack, | |
3480 sizeof (vn_phi_s) | |
3481 + ((gimple_phi_num_args (phi) - 1) | |
3482 * sizeof (tree))); | |
3483 edge e; | |
3484 edge_iterator ei; | |
3485 | |
3486 /* Canonicalize the SSA_NAME's to their value number. */ | |
3487 FOR_EACH_EDGE (e, ei, gimple_bb (phi)->preds) | |
3488 { | |
3489 tree def = PHI_ARG_DEF_FROM_EDGE (phi, e); | |
3490 if (TREE_CODE (def) == SSA_NAME | |
3491 && (!backedges_varying_p || !(e->flags & EDGE_DFS_BACK))) | |
3492 def = SSA_VAL (def); | |
3493 vp1->phiargs[e->dest_idx] = def; | |
3494 } | |
3495 vp1->value_id = VN_INFO (result)->value_id; | |
3496 vp1->type = TREE_TYPE (gimple_phi_result (phi)); | |
3497 vp1->block = gimple_bb (phi); | |
3498 /* Extract values of the controlling condition. */ | |
3499 vp1->cclhs = NULL_TREE; | |
3500 vp1->ccrhs = NULL_TREE; | |
3501 basic_block idom1 = get_immediate_dominator (CDI_DOMINATORS, vp1->block); | |
3502 if (EDGE_COUNT (idom1->succs) == 2) | |
3503 if (gcond *last1 = safe_dyn_cast <gcond *> (last_stmt (idom1))) | |
3504 { | |
3505 /* ??? We want to use SSA_VAL here. But possibly not | |
3506 allow VN_TOP. */ | |
3179 vp1->cclhs = vn_valueize (gimple_cond_lhs (last1)); | 3507 vp1->cclhs = vn_valueize (gimple_cond_lhs (last1)); |
3180 vp1->ccrhs = vn_valueize (gimple_cond_rhs (last1)); | 3508 vp1->ccrhs = vn_valueize (gimple_cond_rhs (last1)); |
3181 } | 3509 } |
3182 vp1->result = result; | 3510 vp1->result = result; |
3183 vp1->hashcode = vn_phi_compute_hash (vp1); | 3511 vp1->hashcode = vn_phi_compute_hash (vp1); |
3184 | 3512 |
3185 slot = current_info->phis->find_slot_with_hash (vp1, vp1->hashcode, INSERT); | 3513 slot = valid_info->phis->find_slot_with_hash (vp1, vp1->hashcode, INSERT); |
3186 | 3514 gcc_assert (!*slot); |
3187 /* Because we iterate over phi operations more than once, it's | 3515 |
3188 possible the slot might already exist here, hence no assert.*/ | |
3189 *slot = vp1; | 3516 *slot = vp1; |
3517 vp1->next = last_inserted_phi; | |
3518 last_inserted_phi = vp1; | |
3190 return vp1; | 3519 return vp1; |
3191 } | 3520 } |
3192 | 3521 |
3193 | |
3194 /* Print set of components in strongly connected component SCC to OUT. */ | |
3195 | |
3196 static void | |
3197 print_scc (FILE *out, vec<tree> scc) | |
3198 { | |
3199 tree var; | |
3200 unsigned int i; | |
3201 | |
3202 fprintf (out, "SCC consists of %u:", scc.length ()); | |
3203 FOR_EACH_VEC_ELT (scc, i, var) | |
3204 { | |
3205 fprintf (out, " "); | |
3206 print_generic_expr (out, var); | |
3207 } | |
3208 fprintf (out, "\n"); | |
3209 } | |
3210 | 3522 |
3211 /* Return true if BB1 is dominated by BB2 taking into account edges | 3523 /* Return true if BB1 is dominated by BB2 taking into account edges |
3212 that are not executable. */ | 3524 that are not executable. */ |
3213 | 3525 |
3214 static bool | 3526 static bool |
3293 as a result. */ | 3605 as a result. */ |
3294 | 3606 |
3295 static inline bool | 3607 static inline bool |
3296 set_ssa_val_to (tree from, tree to) | 3608 set_ssa_val_to (tree from, tree to) |
3297 { | 3609 { |
3298 tree currval = SSA_VAL (from); | 3610 vn_ssa_aux_t from_info = VN_INFO (from); |
3299 HOST_WIDE_INT toff, coff; | 3611 tree currval = from_info->valnum; // SSA_VAL (from) |
3612 poly_int64 toff, coff; | |
3300 | 3613 |
3301 /* The only thing we allow as value numbers are ssa_names | 3614 /* The only thing we allow as value numbers are ssa_names |
3302 and invariants. So assert that here. We don't allow VN_TOP | 3615 and invariants. So assert that here. We don't allow VN_TOP |
3303 as visiting a stmt should produce a value-number other than | 3616 as visiting a stmt should produce a value-number other than |
3304 that. | 3617 that. |
3305 ??? Still VN_TOP can happen for unreachable code, so force | 3618 ??? Still VN_TOP can happen for unreachable code, so force |
3306 it to varying in that case. Not all code is prepared to | 3619 it to varying in that case. Not all code is prepared to |
3307 get VN_TOP on valueization. */ | 3620 get VN_TOP on valueization. */ |
3308 if (to == VN_TOP) | 3621 if (to == VN_TOP) |
3309 { | 3622 { |
3623 /* ??? When iterating and visiting PHI <undef, backedge-value> | |
3624 for the first time we rightfully get VN_TOP and we need to | |
3625 preserve that to optimize for example gcc.dg/tree-ssa/ssa-sccvn-2.c. | |
3626 With SCCVN we were simply lucky we iterated the other PHI | |
3627 cycles first and thus visited the backedge-value DEF. */ | |
3628 if (currval == VN_TOP) | |
3629 goto set_and_exit; | |
3310 if (dump_file && (dump_flags & TDF_DETAILS)) | 3630 if (dump_file && (dump_flags & TDF_DETAILS)) |
3311 fprintf (dump_file, "Forcing value number to varying on " | 3631 fprintf (dump_file, "Forcing value number to varying on " |
3312 "receiving VN_TOP\n"); | 3632 "receiving VN_TOP\n"); |
3313 to = from; | 3633 to = from; |
3314 } | 3634 } |
3315 | 3635 |
3316 gcc_assert (to != NULL_TREE | 3636 gcc_checking_assert (to != NULL_TREE |
3317 && ((TREE_CODE (to) == SSA_NAME | 3637 && ((TREE_CODE (to) == SSA_NAME |
3318 && (to == from || SSA_VAL (to) == to)) | 3638 && (to == from || SSA_VAL (to) == to)) |
3319 || is_gimple_min_invariant (to))); | 3639 || is_gimple_min_invariant (to))); |
3320 | 3640 |
3321 if (from != to) | 3641 if (from != to) |
3322 { | 3642 { |
3323 if (currval == from) | 3643 if (currval == from) |
3324 { | 3644 { |
3332 } | 3652 } |
3333 return false; | 3653 return false; |
3334 } | 3654 } |
3335 else if (currval != VN_TOP | 3655 else if (currval != VN_TOP |
3336 && ! is_gimple_min_invariant (currval) | 3656 && ! is_gimple_min_invariant (currval) |
3657 && ! ssa_undefined_value_p (currval, false) | |
3337 && is_gimple_min_invariant (to)) | 3658 && is_gimple_min_invariant (to)) |
3338 { | 3659 { |
3339 if (dump_file && (dump_flags & TDF_DETAILS)) | 3660 if (dump_file && (dump_flags & TDF_DETAILS)) |
3340 { | 3661 { |
3341 fprintf (dump_file, "Forcing VARYING instead of changing " | 3662 fprintf (dump_file, "Forcing VARYING instead of changing " |
3352 else if (TREE_CODE (to) == SSA_NAME | 3673 else if (TREE_CODE (to) == SSA_NAME |
3353 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (to)) | 3674 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (to)) |
3354 to = from; | 3675 to = from; |
3355 } | 3676 } |
3356 | 3677 |
3678 set_and_exit: | |
3357 if (dump_file && (dump_flags & TDF_DETAILS)) | 3679 if (dump_file && (dump_flags & TDF_DETAILS)) |
3358 { | 3680 { |
3359 fprintf (dump_file, "Setting value number of "); | 3681 fprintf (dump_file, "Setting value number of "); |
3360 print_generic_expr (dump_file, from); | 3682 print_generic_expr (dump_file, from); |
3361 fprintf (dump_file, " to "); | 3683 fprintf (dump_file, " to "); |
3376 get_addr_base_and_unit_offset to do this comparison. */ | 3698 get_addr_base_and_unit_offset to do this comparison. */ |
3377 && !(TREE_CODE (currval) == ADDR_EXPR | 3699 && !(TREE_CODE (currval) == ADDR_EXPR |
3378 && TREE_CODE (to) == ADDR_EXPR | 3700 && TREE_CODE (to) == ADDR_EXPR |
3379 && (get_addr_base_and_unit_offset (TREE_OPERAND (currval, 0), &coff) | 3701 && (get_addr_base_and_unit_offset (TREE_OPERAND (currval, 0), &coff) |
3380 == get_addr_base_and_unit_offset (TREE_OPERAND (to, 0), &toff)) | 3702 == get_addr_base_and_unit_offset (TREE_OPERAND (to, 0), &toff)) |
3381 && coff == toff)) | 3703 && known_eq (coff, toff))) |
3382 { | 3704 { |
3383 if (dump_file && (dump_flags & TDF_DETAILS)) | 3705 if (dump_file && (dump_flags & TDF_DETAILS)) |
3384 fprintf (dump_file, " (changed)\n"); | 3706 fprintf (dump_file, " (changed)\n"); |
3385 | 3707 from_info->valnum = to; |
3386 /* If we equate two SSA names we have to make the side-band info | |
3387 of the leader conservative (and remember whatever original value | |
3388 was present). */ | |
3389 if (TREE_CODE (to) == SSA_NAME) | |
3390 { | |
3391 if (INTEGRAL_TYPE_P (TREE_TYPE (to)) | |
3392 && SSA_NAME_RANGE_INFO (to)) | |
3393 { | |
3394 if (SSA_NAME_IS_DEFAULT_DEF (to) | |
3395 || dominated_by_p_w_unex | |
3396 (gimple_bb (SSA_NAME_DEF_STMT (from)), | |
3397 gimple_bb (SSA_NAME_DEF_STMT (to)))) | |
3398 /* Keep the info from the dominator. */ | |
3399 ; | |
3400 else | |
3401 { | |
3402 /* Save old info. */ | |
3403 if (! VN_INFO (to)->info.range_info) | |
3404 { | |
3405 VN_INFO (to)->info.range_info = SSA_NAME_RANGE_INFO (to); | |
3406 VN_INFO (to)->range_info_anti_range_p | |
3407 = SSA_NAME_ANTI_RANGE_P (to); | |
3408 } | |
3409 /* Rather than allocating memory and unioning the info | |
3410 just clear it. */ | |
3411 if (dump_file && (dump_flags & TDF_DETAILS)) | |
3412 { | |
3413 fprintf (dump_file, "clearing range info of "); | |
3414 print_generic_expr (dump_file, to); | |
3415 fprintf (dump_file, "\n"); | |
3416 } | |
3417 SSA_NAME_RANGE_INFO (to) = NULL; | |
3418 } | |
3419 } | |
3420 else if (POINTER_TYPE_P (TREE_TYPE (to)) | |
3421 && SSA_NAME_PTR_INFO (to)) | |
3422 { | |
3423 if (SSA_NAME_IS_DEFAULT_DEF (to) | |
3424 || dominated_by_p_w_unex | |
3425 (gimple_bb (SSA_NAME_DEF_STMT (from)), | |
3426 gimple_bb (SSA_NAME_DEF_STMT (to)))) | |
3427 /* Keep the info from the dominator. */ | |
3428 ; | |
3429 else if (! SSA_NAME_PTR_INFO (from) | |
3430 /* Handle the case of trivially equivalent info. */ | |
3431 || memcmp (SSA_NAME_PTR_INFO (to), | |
3432 SSA_NAME_PTR_INFO (from), | |
3433 sizeof (ptr_info_def)) != 0) | |
3434 { | |
3435 /* Save old info. */ | |
3436 if (! VN_INFO (to)->info.ptr_info) | |
3437 VN_INFO (to)->info.ptr_info = SSA_NAME_PTR_INFO (to); | |
3438 /* Rather than allocating memory and unioning the info | |
3439 just clear it. */ | |
3440 if (dump_file && (dump_flags & TDF_DETAILS)) | |
3441 { | |
3442 fprintf (dump_file, "clearing points-to info of "); | |
3443 print_generic_expr (dump_file, to); | |
3444 fprintf (dump_file, "\n"); | |
3445 } | |
3446 SSA_NAME_PTR_INFO (to) = NULL; | |
3447 } | |
3448 } | |
3449 } | |
3450 | |
3451 VN_INFO (from)->valnum = to; | |
3452 return true; | 3708 return true; |
3453 } | 3709 } |
3454 if (dump_file && (dump_flags & TDF_DETAILS)) | 3710 if (dump_file && (dump_flags & TDF_DETAILS)) |
3455 fprintf (dump_file, "\n"); | 3711 fprintf (dump_file, "\n"); |
3456 return false; | 3712 return false; |
3457 } | 3713 } |
3458 | 3714 |
3459 /* Mark as processed all the definitions in the defining stmt of USE, or | |
3460 the USE itself. */ | |
3461 | |
3462 static void | |
3463 mark_use_processed (tree use) | |
3464 { | |
3465 ssa_op_iter iter; | |
3466 def_operand_p defp; | |
3467 gimple *stmt = SSA_NAME_DEF_STMT (use); | |
3468 | |
3469 if (SSA_NAME_IS_DEFAULT_DEF (use) || gimple_code (stmt) == GIMPLE_PHI) | |
3470 { | |
3471 VN_INFO (use)->use_processed = true; | |
3472 return; | |
3473 } | |
3474 | |
3475 FOR_EACH_SSA_DEF_OPERAND (defp, stmt, iter, SSA_OP_ALL_DEFS) | |
3476 { | |
3477 tree def = DEF_FROM_PTR (defp); | |
3478 | |
3479 VN_INFO (def)->use_processed = true; | |
3480 } | |
3481 } | |
3482 | |
3483 /* Set all definitions in STMT to value number to themselves. | 3715 /* Set all definitions in STMT to value number to themselves. |
3484 Return true if a value number changed. */ | 3716 Return true if a value number changed. */ |
3485 | 3717 |
3486 static bool | 3718 static bool |
3487 defs_to_varying (gimple *stmt) | 3719 defs_to_varying (gimple *stmt) |
3515 | 3747 |
3516 static tree | 3748 static tree |
3517 valueized_wider_op (tree wide_type, tree op) | 3749 valueized_wider_op (tree wide_type, tree op) |
3518 { | 3750 { |
3519 if (TREE_CODE (op) == SSA_NAME) | 3751 if (TREE_CODE (op) == SSA_NAME) |
3520 op = SSA_VAL (op); | 3752 op = vn_valueize (op); |
3521 | 3753 |
3522 /* Either we have the op widened available. */ | 3754 /* Either we have the op widened available. */ |
3523 tree ops[3] = {}; | 3755 tree ops[3] = {}; |
3524 ops[0] = op; | 3756 ops[0] = op; |
3525 tree tem = vn_nary_op_lookup_pieces (1, NOP_EXPR, | 3757 tree tem = vn_nary_op_lookup_pieces (1, NOP_EXPR, |
3536 { | 3768 { |
3537 tem = gimple_assign_rhs1 (def); | 3769 tem = gimple_assign_rhs1 (def); |
3538 if (useless_type_conversion_p (wide_type, TREE_TYPE (tem))) | 3770 if (useless_type_conversion_p (wide_type, TREE_TYPE (tem))) |
3539 { | 3771 { |
3540 if (TREE_CODE (tem) == SSA_NAME) | 3772 if (TREE_CODE (tem) == SSA_NAME) |
3541 tem = SSA_VAL (tem); | 3773 tem = vn_valueize (tem); |
3542 return tem; | 3774 return tem; |
3543 } | 3775 } |
3544 } | 3776 } |
3545 } | 3777 } |
3546 | 3778 |
3555 value number of LHS has changed as a result. */ | 3787 value number of LHS has changed as a result. */ |
3556 | 3788 |
3557 static bool | 3789 static bool |
3558 visit_nary_op (tree lhs, gassign *stmt) | 3790 visit_nary_op (tree lhs, gassign *stmt) |
3559 { | 3791 { |
3560 tree result = vn_nary_op_lookup_stmt (stmt, NULL); | 3792 vn_nary_op_t vnresult; |
3793 tree result = vn_nary_op_lookup_stmt (stmt, &vnresult); | |
3794 if (! result && vnresult) | |
3795 result = vn_nary_op_get_predicated_value (vnresult, gimple_bb (stmt)); | |
3561 if (result) | 3796 if (result) |
3562 return set_ssa_val_to (lhs, result); | 3797 return set_ssa_val_to (lhs, result); |
3563 | 3798 |
3564 /* Do some special pattern matching for redundancies of operations | 3799 /* Do some special pattern matching for redundancies of operations |
3565 in different types. */ | 3800 in different types. */ |
3601 { | 3836 { |
3602 unsigned lhs_prec = TYPE_PRECISION (type); | 3837 unsigned lhs_prec = TYPE_PRECISION (type); |
3603 unsigned rhs_prec = TYPE_PRECISION (TREE_TYPE (rhs1)); | 3838 unsigned rhs_prec = TYPE_PRECISION (TREE_TYPE (rhs1)); |
3604 if (lhs_prec == rhs_prec) | 3839 if (lhs_prec == rhs_prec) |
3605 { | 3840 { |
3606 ops[1] = NULL_TREE; | 3841 gimple_match_op match_op (gimple_match_cond::UNCOND, |
3607 result = vn_nary_build_or_lookup (NOP_EXPR, | 3842 NOP_EXPR, type, ops[0]); |
3608 type, ops); | 3843 result = vn_nary_build_or_lookup (&match_op); |
3609 if (result) | 3844 if (result) |
3610 { | 3845 { |
3611 bool changed = set_ssa_val_to (lhs, result); | 3846 bool changed = set_ssa_val_to (lhs, result); |
3612 vn_nary_op_insert_stmt (stmt, result); | 3847 vn_nary_op_insert_stmt (stmt, result); |
3613 return changed; | 3848 return changed; |
3614 } | 3849 } |
3615 } | 3850 } |
3616 else | 3851 else |
3617 { | 3852 { |
3618 ops[1] = wide_int_to_tree (type, | 3853 tree mask = wide_int_to_tree |
3619 wi::mask (rhs_prec, false, | 3854 (type, wi::mask (rhs_prec, false, lhs_prec)); |
3620 lhs_prec)); | 3855 gimple_match_op match_op (gimple_match_cond::UNCOND, |
3621 result = vn_nary_build_or_lookup (BIT_AND_EXPR, | 3856 BIT_AND_EXPR, |
3622 TREE_TYPE (lhs), | 3857 TREE_TYPE (lhs), |
3623 ops); | 3858 ops[0], mask); |
3859 result = vn_nary_build_or_lookup (&match_op); | |
3624 if (result) | 3860 if (result) |
3625 { | 3861 { |
3626 bool changed = set_ssa_val_to (lhs, result); | 3862 bool changed = set_ssa_val_to (lhs, result); |
3627 vn_nary_op_insert_stmt (stmt, result); | 3863 vn_nary_op_insert_stmt (stmt, result); |
3628 return changed; | 3864 return changed; |
3693 } | 3929 } |
3694 changed |= set_ssa_val_to (vdef, vdef_val); | 3930 changed |= set_ssa_val_to (vdef, vdef_val); |
3695 } | 3931 } |
3696 if (lhs) | 3932 if (lhs) |
3697 changed |= set_ssa_val_to (lhs, lhs); | 3933 changed |= set_ssa_val_to (lhs, lhs); |
3698 vr2 = current_info->references_pool->allocate (); | 3934 vr2 = XOBNEW (&vn_tables_obstack, vn_reference_s); |
3699 vr2->vuse = vr1.vuse; | 3935 vr2->vuse = vr1.vuse; |
3700 /* As we are not walking the virtual operand chain we know the | 3936 /* As we are not walking the virtual operand chain we know the |
3701 shared_lookup_references are still original so we can re-use | 3937 shared_lookup_references are still original so we can re-use |
3702 them here. */ | 3938 them here. */ |
3703 vr2->operands = vr1.operands.copy (); | 3939 vr2->operands = vr1.operands.copy (); |
3704 vr2->type = vr1.type; | 3940 vr2->type = vr1.type; |
3705 vr2->set = vr1.set; | 3941 vr2->set = vr1.set; |
3706 vr2->hashcode = vr1.hashcode; | 3942 vr2->hashcode = vr1.hashcode; |
3707 vr2->result = lhs; | 3943 vr2->result = lhs; |
3708 vr2->result_vdef = vdef_val; | 3944 vr2->result_vdef = vdef_val; |
3709 slot = current_info->references->find_slot_with_hash (vr2, vr2->hashcode, | 3945 slot = valid_info->references->find_slot_with_hash (vr2, vr2->hashcode, |
3710 INSERT); | 3946 INSERT); |
3711 gcc_assert (!*slot); | 3947 gcc_assert (!*slot); |
3712 *slot = vr2; | 3948 *slot = vr2; |
3949 vr2->next = last_inserted_ref; | |
3950 last_inserted_ref = vr2; | |
3713 } | 3951 } |
3714 | 3952 |
3715 return changed; | 3953 return changed; |
3716 } | 3954 } |
3717 | 3955 |
3739 { | 3977 { |
3740 /* We will be setting the value number of lhs to the value number | 3978 /* We will be setting the value number of lhs to the value number |
3741 of VIEW_CONVERT_EXPR <TREE_TYPE (result)> (result). | 3979 of VIEW_CONVERT_EXPR <TREE_TYPE (result)> (result). |
3742 So first simplify and lookup this expression to see if it | 3980 So first simplify and lookup this expression to see if it |
3743 is already available. */ | 3981 is already available. */ |
3744 code_helper rcode = VIEW_CONVERT_EXPR; | 3982 gimple_match_op res_op (gimple_match_cond::UNCOND, |
3745 tree ops[3] = { result }; | 3983 VIEW_CONVERT_EXPR, TREE_TYPE (op), result); |
3746 result = vn_nary_build_or_lookup (rcode, TREE_TYPE (op), ops); | 3984 result = vn_nary_build_or_lookup (&res_op); |
3985 /* When building the conversion fails avoid inserting the reference | |
3986 again. */ | |
3987 if (!result) | |
3988 return set_ssa_val_to (lhs, lhs); | |
3747 } | 3989 } |
3748 | 3990 |
3749 if (result) | 3991 if (result) |
3750 changed = set_ssa_val_to (lhs, result); | 3992 changed = set_ssa_val_to (lhs, result); |
3751 else | 3993 else |
3793 vn_reference_lookup (lhs, vuse, VN_NOWALK, &vnresult, false); | 4035 vn_reference_lookup (lhs, vuse, VN_NOWALK, &vnresult, false); |
3794 if (vnresult | 4036 if (vnresult |
3795 && vnresult->result) | 4037 && vnresult->result) |
3796 { | 4038 { |
3797 tree result = vnresult->result; | 4039 tree result = vnresult->result; |
3798 if (TREE_CODE (result) == SSA_NAME) | 4040 gcc_checking_assert (TREE_CODE (result) != SSA_NAME |
3799 result = SSA_VAL (result); | 4041 || result == SSA_VAL (result)); |
3800 resultsame = expressions_equal_p (result, op); | 4042 resultsame = expressions_equal_p (result, op); |
3801 if (resultsame) | 4043 if (resultsame) |
3802 { | 4044 { |
3803 /* If the TBAA state isn't compatible for downstream reads | 4045 /* If the TBAA state isn't compatible for downstream reads |
3804 we cannot value-number the VDEFs the same. */ | 4046 we cannot value-number the VDEFs the same. */ |
3817 { | 4059 { |
3818 assign = build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, op); | 4060 assign = build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, op); |
3819 vn_reference_lookup (assign, vuse, VN_NOWALK, &vnresult, false); | 4061 vn_reference_lookup (assign, vuse, VN_NOWALK, &vnresult, false); |
3820 if (vnresult) | 4062 if (vnresult) |
3821 { | 4063 { |
3822 VN_INFO (vdef)->use_processed = true; | 4064 VN_INFO (vdef)->visited = true; |
3823 return set_ssa_val_to (vdef, vnresult->result_vdef); | 4065 return set_ssa_val_to (vdef, vnresult->result_vdef); |
3824 } | 4066 } |
3825 } | 4067 } |
3826 | 4068 |
3827 if (dump_file && (dump_flags & TDF_DETAILS)) | 4069 if (dump_file && (dump_flags & TDF_DETAILS)) |
3865 | 4107 |
3866 return changed; | 4108 return changed; |
3867 } | 4109 } |
3868 | 4110 |
3869 /* Visit and value number PHI, return true if the value number | 4111 /* Visit and value number PHI, return true if the value number |
3870 changed. */ | 4112 changed. When BACKEDGES_VARYING_P is true then assume all |
4113 backedge values are varying. When INSERTED is not NULL then | |
4114 this is just a ahead query for a possible iteration, set INSERTED | |
4115 to true if we'd insert into the hashtable. */ | |
3871 | 4116 |
3872 static bool | 4117 static bool |
3873 visit_phi (gimple *phi) | 4118 visit_phi (gimple *phi, bool *inserted, bool backedges_varying_p) |
3874 { | 4119 { |
3875 tree result, sameval = VN_TOP, seen_undef = NULL_TREE; | 4120 tree result, sameval = VN_TOP, seen_undef = NULL_TREE; |
4121 tree backedge_val = NULL_TREE; | |
4122 bool seen_non_backedge = false; | |
4123 tree sameval_base = NULL_TREE; | |
4124 poly_int64 soff, doff; | |
3876 unsigned n_executable = 0; | 4125 unsigned n_executable = 0; |
3877 bool allsame = true; | |
3878 edge_iterator ei; | 4126 edge_iterator ei; |
3879 edge e; | 4127 edge e; |
3880 | 4128 |
3881 /* TODO: We could check for this in init_sccvn, and replace this | 4129 /* TODO: We could check for this in initialization, and replace this |
3882 with a gcc_assert. */ | 4130 with a gcc_assert. */ |
3883 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (phi))) | 4131 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (phi))) |
3884 return set_ssa_val_to (PHI_RESULT (phi), PHI_RESULT (phi)); | 4132 return set_ssa_val_to (PHI_RESULT (phi), PHI_RESULT (phi)); |
4133 | |
4134 /* We track whether a PHI was CSEd to to avoid excessive iterations | |
4135 that would be necessary only because the PHI changed arguments | |
4136 but not value. */ | |
4137 if (!inserted) | |
4138 gimple_set_plf (phi, GF_PLF_1, false); | |
3885 | 4139 |
3886 /* See if all non-TOP arguments have the same value. TOP is | 4140 /* See if all non-TOP arguments have the same value. TOP is |
3887 equivalent to everything, so we can ignore it. */ | 4141 equivalent to everything, so we can ignore it. */ |
3888 FOR_EACH_EDGE (e, ei, gimple_bb (phi)->preds) | 4142 FOR_EACH_EDGE (e, ei, gimple_bb (phi)->preds) |
3889 if (e->flags & EDGE_EXECUTABLE) | 4143 if (e->flags & EDGE_EXECUTABLE) |
3890 { | 4144 { |
3891 tree def = PHI_ARG_DEF_FROM_EDGE (phi, e); | 4145 tree def = PHI_ARG_DEF_FROM_EDGE (phi, e); |
3892 | 4146 |
3893 ++n_executable; | 4147 ++n_executable; |
3894 if (TREE_CODE (def) == SSA_NAME) | 4148 if (TREE_CODE (def) == SSA_NAME) |
3895 def = SSA_VAL (def); | 4149 { |
4150 if (!backedges_varying_p || !(e->flags & EDGE_DFS_BACK)) | |
4151 def = SSA_VAL (def); | |
4152 if (e->flags & EDGE_DFS_BACK) | |
4153 backedge_val = def; | |
4154 } | |
4155 if (!(e->flags & EDGE_DFS_BACK)) | |
4156 seen_non_backedge = true; | |
3896 if (def == VN_TOP) | 4157 if (def == VN_TOP) |
3897 ; | 4158 ; |
3898 /* Ignore undefined defs for sameval but record one. */ | 4159 /* Ignore undefined defs for sameval but record one. */ |
3899 else if (TREE_CODE (def) == SSA_NAME | 4160 else if (TREE_CODE (def) == SSA_NAME |
4161 && ! virtual_operand_p (def) | |
3900 && ssa_undefined_value_p (def, false)) | 4162 && ssa_undefined_value_p (def, false)) |
3901 seen_undef = def; | 4163 seen_undef = def; |
3902 else if (sameval == VN_TOP) | 4164 else if (sameval == VN_TOP) |
3903 sameval = def; | 4165 sameval = def; |
3904 else if (!expressions_equal_p (def, sameval)) | 4166 else if (!expressions_equal_p (def, sameval)) |
3905 { | 4167 { |
3906 allsame = false; | 4168 /* We know we're arriving only with invariant addresses here, |
4169 try harder comparing them. We can do some caching here | |
4170 which we cannot do in expressions_equal_p. */ | |
4171 if (TREE_CODE (def) == ADDR_EXPR | |
4172 && TREE_CODE (sameval) == ADDR_EXPR | |
4173 && sameval_base != (void *)-1) | |
4174 { | |
4175 if (!sameval_base) | |
4176 sameval_base = get_addr_base_and_unit_offset | |
4177 (TREE_OPERAND (sameval, 0), &soff); | |
4178 if (!sameval_base) | |
4179 sameval_base = (tree)(void *)-1; | |
4180 else if ((get_addr_base_and_unit_offset | |
4181 (TREE_OPERAND (def, 0), &doff) == sameval_base) | |
4182 && known_eq (soff, doff)) | |
4183 continue; | |
4184 } | |
4185 sameval = NULL_TREE; | |
3907 break; | 4186 break; |
3908 } | 4187 } |
3909 } | 4188 } |
3910 | 4189 |
3911 | 4190 /* If the value we want to use is flowing over the backedge and we |
4191 should take it as VARYING but it has a non-VARYING value drop to | |
4192 VARYING. | |
4193 If we value-number a virtual operand never value-number to the | |
4194 value from the backedge as that confuses the alias-walking code. | |
4195 See gcc.dg/torture/pr87176.c. If the value is the same on a | |
4196 non-backedge everything is OK though. */ | |
4197 if (backedge_val | |
4198 && !seen_non_backedge | |
4199 && TREE_CODE (backedge_val) == SSA_NAME | |
4200 && sameval == backedge_val | |
4201 && (SSA_NAME_IS_VIRTUAL_OPERAND (backedge_val) | |
4202 || SSA_VAL (backedge_val) != backedge_val)) | |
4203 /* Note this just drops to VARYING without inserting the PHI into | |
4204 the hashes. */ | |
4205 result = PHI_RESULT (phi); | |
3912 /* If none of the edges was executable keep the value-number at VN_TOP, | 4206 /* If none of the edges was executable keep the value-number at VN_TOP, |
3913 if only a single edge is exectuable use its value. */ | 4207 if only a single edge is exectuable use its value. */ |
3914 if (n_executable <= 1) | 4208 else if (n_executable <= 1) |
3915 result = seen_undef ? seen_undef : sameval; | 4209 result = seen_undef ? seen_undef : sameval; |
3916 /* If we saw only undefined values and VN_TOP use one of the | 4210 /* If we saw only undefined values and VN_TOP use one of the |
3917 undefined values. */ | 4211 undefined values. */ |
3918 else if (sameval == VN_TOP) | 4212 else if (sameval == VN_TOP) |
3919 result = seen_undef ? seen_undef : sameval; | 4213 result = seen_undef ? seen_undef : sameval; |
3920 /* First see if it is equivalent to a phi node in this block. We prefer | 4214 /* First see if it is equivalent to a phi node in this block. We prefer |
3921 this as it allows IV elimination - see PRs 66502 and 67167. */ | 4215 this as it allows IV elimination - see PRs 66502 and 67167. */ |
3922 else if ((result = vn_phi_lookup (phi))) | 4216 else if ((result = vn_phi_lookup (phi, backedges_varying_p))) |
3923 ; | 4217 { |
4218 if (!inserted | |
4219 && TREE_CODE (result) == SSA_NAME | |
4220 && gimple_code (SSA_NAME_DEF_STMT (result)) == GIMPLE_PHI) | |
4221 { | |
4222 gimple_set_plf (SSA_NAME_DEF_STMT (result), GF_PLF_1, true); | |
4223 if (dump_file && (dump_flags & TDF_DETAILS)) | |
4224 { | |
4225 fprintf (dump_file, "Marking CSEd to PHI node "); | |
4226 print_gimple_expr (dump_file, SSA_NAME_DEF_STMT (result), | |
4227 0, TDF_SLIM); | |
4228 fprintf (dump_file, "\n"); | |
4229 } | |
4230 } | |
4231 } | |
3924 /* If all values are the same use that, unless we've seen undefined | 4232 /* If all values are the same use that, unless we've seen undefined |
3925 values as well and the value isn't constant. | 4233 values as well and the value isn't constant. |
3926 CCP/copyprop have the same restriction to not remove uninit warnings. */ | 4234 CCP/copyprop have the same restriction to not remove uninit warnings. */ |
3927 else if (allsame | 4235 else if (sameval |
3928 && (! seen_undef || is_gimple_min_invariant (sameval))) | 4236 && (! seen_undef || is_gimple_min_invariant (sameval))) |
3929 result = sameval; | 4237 result = sameval; |
3930 else | 4238 else |
3931 { | 4239 { |
3932 result = PHI_RESULT (phi); | 4240 result = PHI_RESULT (phi); |
3933 /* Only insert PHIs that are varying, for constant value numbers | 4241 /* Only insert PHIs that are varying, for constant value numbers |
3934 we mess up equivalences otherwise as we are only comparing | 4242 we mess up equivalences otherwise as we are only comparing |
3935 the immediate controlling predicates. */ | 4243 the immediate controlling predicates. */ |
3936 vn_phi_insert (phi, result); | 4244 vn_phi_insert (phi, result, backedges_varying_p); |
4245 if (inserted) | |
4246 *inserted = true; | |
3937 } | 4247 } |
3938 | 4248 |
3939 return set_ssa_val_to (PHI_RESULT (phi), result); | 4249 return set_ssa_val_to (PHI_RESULT (phi), result); |
3940 } | 4250 } |
3941 | 4251 |
3952 if (code == SSA_NAME) | 4262 if (code == SSA_NAME) |
3953 return NULL_TREE; | 4263 return NULL_TREE; |
3954 | 4264 |
3955 /* First try constant folding based on our current lattice. */ | 4265 /* First try constant folding based on our current lattice. */ |
3956 mprts_hook = vn_lookup_simplify_result; | 4266 mprts_hook = vn_lookup_simplify_result; |
3957 mprts_hook_cnt = 9; | |
3958 tem = gimple_fold_stmt_to_constant_1 (stmt, vn_valueize, vn_valueize); | 4267 tem = gimple_fold_stmt_to_constant_1 (stmt, vn_valueize, vn_valueize); |
3959 mprts_hook = NULL; | 4268 mprts_hook = NULL; |
3960 if (tem | 4269 if (tem |
3961 && (TREE_CODE (tem) == SSA_NAME | 4270 && (TREE_CODE (tem) == SSA_NAME |
3962 || is_gimple_min_invariant (tem))) | 4271 || is_gimple_min_invariant (tem))) |
3963 return tem; | 4272 return tem; |
3964 | 4273 |
3965 return NULL_TREE; | 4274 return NULL_TREE; |
3966 } | 4275 } |
3967 | 4276 |
3968 /* Visit and value number USE, return true if the value number | 4277 /* Visit and value number STMT, return true if the value number |
3969 changed. */ | 4278 changed. */ |
3970 | 4279 |
3971 static bool | 4280 static bool |
3972 visit_use (tree use) | 4281 visit_stmt (gimple *stmt, bool backedges_varying_p = false) |
3973 { | 4282 { |
3974 bool changed = false; | 4283 bool changed = false; |
3975 gimple *stmt = SSA_NAME_DEF_STMT (use); | |
3976 | |
3977 mark_use_processed (use); | |
3978 | |
3979 gcc_assert (!SSA_NAME_IN_FREE_LIST (use) | |
3980 && !SSA_NAME_IS_DEFAULT_DEF (use)); | |
3981 | 4284 |
3982 if (dump_file && (dump_flags & TDF_DETAILS)) | 4285 if (dump_file && (dump_flags & TDF_DETAILS)) |
3983 { | 4286 { |
3984 fprintf (dump_file, "Value numbering "); | 4287 fprintf (dump_file, "Value numbering stmt = "); |
3985 print_generic_expr (dump_file, use); | |
3986 fprintf (dump_file, " stmt = "); | |
3987 print_gimple_stmt (dump_file, stmt, 0); | 4288 print_gimple_stmt (dump_file, stmt, 0); |
3988 } | 4289 } |
3989 | 4290 |
3990 if (gimple_code (stmt) == GIMPLE_PHI) | 4291 if (gimple_code (stmt) == GIMPLE_PHI) |
3991 changed = visit_phi (stmt); | 4292 changed = visit_phi (stmt, NULL, backedges_varying_p); |
3992 else if (gimple_has_volatile_ops (stmt)) | 4293 else if (gimple_has_volatile_ops (stmt)) |
3993 changed = defs_to_varying (stmt); | 4294 changed = defs_to_varying (stmt); |
3994 else if (gassign *ass = dyn_cast <gassign *> (stmt)) | 4295 else if (gassign *ass = dyn_cast <gassign *> (stmt)) |
3995 { | 4296 { |
3996 enum tree_code code = gimple_assign_rhs_code (ass); | 4297 enum tree_code code = gimple_assign_rhs_code (ass); |
4173 changed = defs_to_varying (stmt); | 4474 changed = defs_to_varying (stmt); |
4174 done: | 4475 done: |
4175 return changed; | 4476 return changed; |
4176 } | 4477 } |
4177 | 4478 |
4178 /* Compare two operands by reverse postorder index */ | 4479 |
4179 | 4480 /* Allocate a value number table. */ |
4180 static int | |
4181 compare_ops (const void *pa, const void *pb) | |
4182 { | |
4183 const tree opa = *((const tree *)pa); | |
4184 const tree opb = *((const tree *)pb); | |
4185 gimple *opstmta = SSA_NAME_DEF_STMT (opa); | |
4186 gimple *opstmtb = SSA_NAME_DEF_STMT (opb); | |
4187 basic_block bba; | |
4188 basic_block bbb; | |
4189 | |
4190 if (gimple_nop_p (opstmta) && gimple_nop_p (opstmtb)) | |
4191 return SSA_NAME_VERSION (opa) - SSA_NAME_VERSION (opb); | |
4192 else if (gimple_nop_p (opstmta)) | |
4193 return -1; | |
4194 else if (gimple_nop_p (opstmtb)) | |
4195 return 1; | |
4196 | |
4197 bba = gimple_bb (opstmta); | |
4198 bbb = gimple_bb (opstmtb); | |
4199 | |
4200 if (!bba && !bbb) | |
4201 return SSA_NAME_VERSION (opa) - SSA_NAME_VERSION (opb); | |
4202 else if (!bba) | |
4203 return -1; | |
4204 else if (!bbb) | |
4205 return 1; | |
4206 | |
4207 if (bba == bbb) | |
4208 { | |
4209 if (gimple_code (opstmta) == GIMPLE_PHI | |
4210 && gimple_code (opstmtb) == GIMPLE_PHI) | |
4211 return SSA_NAME_VERSION (opa) - SSA_NAME_VERSION (opb); | |
4212 else if (gimple_code (opstmta) == GIMPLE_PHI) | |
4213 return -1; | |
4214 else if (gimple_code (opstmtb) == GIMPLE_PHI) | |
4215 return 1; | |
4216 else if (gimple_uid (opstmta) != gimple_uid (opstmtb)) | |
4217 return gimple_uid (opstmta) - gimple_uid (opstmtb); | |
4218 else | |
4219 return SSA_NAME_VERSION (opa) - SSA_NAME_VERSION (opb); | |
4220 } | |
4221 return rpo_numbers[bba->index] - rpo_numbers[bbb->index]; | |
4222 } | |
4223 | |
4224 /* Sort an array containing members of a strongly connected component | |
4225 SCC so that the members are ordered by RPO number. | |
4226 This means that when the sort is complete, iterating through the | |
4227 array will give you the members in RPO order. */ | |
4228 | 4481 |
4229 static void | 4482 static void |
4230 sort_scc (vec<tree> scc) | 4483 allocate_vn_table (vn_tables_t table, unsigned size) |
4231 { | 4484 { |
4232 scc.qsort (compare_ops); | 4485 table->phis = new vn_phi_table_type (size); |
4233 } | 4486 table->nary = new vn_nary_op_table_type (size); |
4234 | 4487 table->references = new vn_reference_table_type (size); |
4235 /* Insert the no longer used nary ONARY to the hash INFO. */ | |
4236 | |
4237 static void | |
4238 copy_nary (vn_nary_op_t onary, vn_tables_t info) | |
4239 { | |
4240 size_t size = sizeof_vn_nary_op (onary->length); | |
4241 vn_nary_op_t nary = alloc_vn_nary_op_noinit (onary->length, | |
4242 &info->nary_obstack); | |
4243 memcpy (nary, onary, size); | |
4244 vn_nary_op_insert_into (nary, info->nary, false); | |
4245 } | |
4246 | |
4247 /* Insert the no longer used phi OPHI to the hash INFO. */ | |
4248 | |
4249 static void | |
4250 copy_phi (vn_phi_t ophi, vn_tables_t info) | |
4251 { | |
4252 vn_phi_t phi = info->phis_pool->allocate (); | |
4253 vn_phi_s **slot; | |
4254 memcpy (phi, ophi, sizeof (*phi)); | |
4255 ophi->phiargs.create (0); | |
4256 slot = info->phis->find_slot_with_hash (phi, phi->hashcode, INSERT); | |
4257 gcc_assert (!*slot); | |
4258 *slot = phi; | |
4259 } | |
4260 | |
4261 /* Insert the no longer used reference OREF to the hash INFO. */ | |
4262 | |
4263 static void | |
4264 copy_reference (vn_reference_t oref, vn_tables_t info) | |
4265 { | |
4266 vn_reference_t ref; | |
4267 vn_reference_s **slot; | |
4268 ref = info->references_pool->allocate (); | |
4269 memcpy (ref, oref, sizeof (*ref)); | |
4270 oref->operands.create (0); | |
4271 slot = info->references->find_slot_with_hash (ref, ref->hashcode, INSERT); | |
4272 if (*slot) | |
4273 free_reference (*slot); | |
4274 *slot = ref; | |
4275 } | |
4276 | |
4277 /* Process a strongly connected component in the SSA graph. */ | |
4278 | |
4279 static void | |
4280 process_scc (vec<tree> scc) | |
4281 { | |
4282 tree var; | |
4283 unsigned int i; | |
4284 unsigned int iterations = 0; | |
4285 bool changed = true; | |
4286 vn_nary_op_iterator_type hin; | |
4287 vn_phi_iterator_type hip; | |
4288 vn_reference_iterator_type hir; | |
4289 vn_nary_op_t nary; | |
4290 vn_phi_t phi; | |
4291 vn_reference_t ref; | |
4292 | |
4293 /* If the SCC has a single member, just visit it. */ | |
4294 if (scc.length () == 1) | |
4295 { | |
4296 tree use = scc[0]; | |
4297 if (VN_INFO (use)->use_processed) | |
4298 return; | |
4299 /* We need to make sure it doesn't form a cycle itself, which can | |
4300 happen for self-referential PHI nodes. In that case we would | |
4301 end up inserting an expression with VN_TOP operands into the | |
4302 valid table which makes us derive bogus equivalences later. | |
4303 The cheapest way to check this is to assume it for all PHI nodes. */ | |
4304 if (gimple_code (SSA_NAME_DEF_STMT (use)) == GIMPLE_PHI) | |
4305 /* Fallthru to iteration. */ ; | |
4306 else | |
4307 { | |
4308 visit_use (use); | |
4309 return; | |
4310 } | |
4311 } | |
4312 | |
4313 if (dump_file && (dump_flags & TDF_DETAILS)) | |
4314 print_scc (dump_file, scc); | |
4315 | |
4316 /* Iterate over the SCC with the optimistic table until it stops | |
4317 changing. */ | |
4318 current_info = optimistic_info; | |
4319 while (changed) | |
4320 { | |
4321 changed = false; | |
4322 iterations++; | |
4323 if (dump_file && (dump_flags & TDF_DETAILS)) | |
4324 fprintf (dump_file, "Starting iteration %d\n", iterations); | |
4325 /* As we are value-numbering optimistically we have to | |
4326 clear the expression tables and the simplified expressions | |
4327 in each iteration until we converge. */ | |
4328 optimistic_info->nary->empty (); | |
4329 optimistic_info->phis->empty (); | |
4330 optimistic_info->references->empty (); | |
4331 obstack_free (&optimistic_info->nary_obstack, NULL); | |
4332 gcc_obstack_init (&optimistic_info->nary_obstack); | |
4333 optimistic_info->phis_pool->release (); | |
4334 optimistic_info->references_pool->release (); | |
4335 FOR_EACH_VEC_ELT (scc, i, var) | |
4336 gcc_assert (!VN_INFO (var)->needs_insertion | |
4337 && VN_INFO (var)->expr == NULL); | |
4338 FOR_EACH_VEC_ELT (scc, i, var) | |
4339 changed |= visit_use (var); | |
4340 } | |
4341 | |
4342 if (dump_file && (dump_flags & TDF_DETAILS)) | |
4343 fprintf (dump_file, "Processing SCC needed %d iterations\n", iterations); | |
4344 statistics_histogram_event (cfun, "SCC iterations", iterations); | |
4345 | |
4346 /* Finally, copy the contents of the no longer used optimistic | |
4347 table to the valid table. */ | |
4348 FOR_EACH_HASH_TABLE_ELEMENT (*optimistic_info->nary, nary, vn_nary_op_t, hin) | |
4349 copy_nary (nary, valid_info); | |
4350 FOR_EACH_HASH_TABLE_ELEMENT (*optimistic_info->phis, phi, vn_phi_t, hip) | |
4351 copy_phi (phi, valid_info); | |
4352 FOR_EACH_HASH_TABLE_ELEMENT (*optimistic_info->references, | |
4353 ref, vn_reference_t, hir) | |
4354 copy_reference (ref, valid_info); | |
4355 | |
4356 current_info = valid_info; | |
4357 } | |
4358 | |
4359 | |
4360 /* Pop the components of the found SCC for NAME off the SCC stack | |
4361 and process them. Returns true if all went well, false if | |
4362 we run into resource limits. */ | |
4363 | |
4364 static void | |
4365 extract_and_process_scc_for_name (tree name) | |
4366 { | |
4367 auto_vec<tree> scc; | |
4368 tree x; | |
4369 | |
4370 /* Found an SCC, pop the components off the SCC stack and | |
4371 process them. */ | |
4372 do | |
4373 { | |
4374 x = sccstack.pop (); | |
4375 | |
4376 VN_INFO (x)->on_sccstack = false; | |
4377 scc.safe_push (x); | |
4378 } while (x != name); | |
4379 | |
4380 /* Drop all defs in the SCC to varying in case a SCC turns out to be | |
4381 incredibly large. | |
4382 ??? Just switch to a non-optimistic mode that avoids any iteration. */ | |
4383 if (scc.length () > (unsigned)PARAM_VALUE (PARAM_SCCVN_MAX_SCC_SIZE)) | |
4384 { | |
4385 if (dump_file) | |
4386 { | |
4387 print_scc (dump_file, scc); | |
4388 fprintf (dump_file, "WARNING: Giving up value-numbering SCC due to " | |
4389 "size %u exceeding %u\n", scc.length (), | |
4390 (unsigned)PARAM_VALUE (PARAM_SCCVN_MAX_SCC_SIZE)); | |
4391 } | |
4392 tree var; | |
4393 unsigned i; | |
4394 FOR_EACH_VEC_ELT (scc, i, var) | |
4395 { | |
4396 gimple *def = SSA_NAME_DEF_STMT (var); | |
4397 mark_use_processed (var); | |
4398 if (SSA_NAME_IS_DEFAULT_DEF (var) | |
4399 || gimple_code (def) == GIMPLE_PHI) | |
4400 set_ssa_val_to (var, var); | |
4401 else | |
4402 defs_to_varying (def); | |
4403 } | |
4404 return; | |
4405 } | |
4406 | |
4407 if (scc.length () > 1) | |
4408 sort_scc (scc); | |
4409 | |
4410 process_scc (scc); | |
4411 } | |
4412 | |
4413 /* Depth first search on NAME to discover and process SCC's in the SSA | |
4414 graph. | |
4415 Execution of this algorithm relies on the fact that the SCC's are | |
4416 popped off the stack in topological order. | |
4417 Returns true if successful, false if we stopped processing SCC's due | |
4418 to resource constraints. */ | |
4419 | |
4420 static void | |
4421 DFS (tree name) | |
4422 { | |
4423 auto_vec<ssa_op_iter> itervec; | |
4424 auto_vec<tree> namevec; | |
4425 use_operand_p usep = NULL; | |
4426 gimple *defstmt; | |
4427 tree use; | |
4428 ssa_op_iter iter; | |
4429 | |
4430 start_over: | |
4431 /* SCC info */ | |
4432 VN_INFO (name)->dfsnum = next_dfs_num++; | |
4433 VN_INFO (name)->visited = true; | |
4434 VN_INFO (name)->low = VN_INFO (name)->dfsnum; | |
4435 | |
4436 sccstack.safe_push (name); | |
4437 VN_INFO (name)->on_sccstack = true; | |
4438 defstmt = SSA_NAME_DEF_STMT (name); | |
4439 | |
4440 /* Recursively DFS on our operands, looking for SCC's. */ | |
4441 if (!gimple_nop_p (defstmt)) | |
4442 { | |
4443 /* Push a new iterator. */ | |
4444 if (gphi *phi = dyn_cast <gphi *> (defstmt)) | |
4445 usep = op_iter_init_phiuse (&iter, phi, SSA_OP_ALL_USES); | |
4446 else | |
4447 usep = op_iter_init_use (&iter, defstmt, SSA_OP_ALL_USES); | |
4448 } | |
4449 else | |
4450 clear_and_done_ssa_iter (&iter); | |
4451 | |
4452 while (1) | |
4453 { | |
4454 /* If we are done processing uses of a name, go up the stack | |
4455 of iterators and process SCCs as we found them. */ | |
4456 if (op_iter_done (&iter)) | |
4457 { | |
4458 /* See if we found an SCC. */ | |
4459 if (VN_INFO (name)->low == VN_INFO (name)->dfsnum) | |
4460 extract_and_process_scc_for_name (name); | |
4461 | |
4462 /* Check if we are done. */ | |
4463 if (namevec.is_empty ()) | |
4464 return; | |
4465 | |
4466 /* Restore the last use walker and continue walking there. */ | |
4467 use = name; | |
4468 name = namevec.pop (); | |
4469 memcpy (&iter, &itervec.last (), | |
4470 sizeof (ssa_op_iter)); | |
4471 itervec.pop (); | |
4472 goto continue_walking; | |
4473 } | |
4474 | |
4475 use = USE_FROM_PTR (usep); | |
4476 | |
4477 /* Since we handle phi nodes, we will sometimes get | |
4478 invariants in the use expression. */ | |
4479 if (TREE_CODE (use) == SSA_NAME) | |
4480 { | |
4481 if (! (VN_INFO (use)->visited)) | |
4482 { | |
4483 /* Recurse by pushing the current use walking state on | |
4484 the stack and starting over. */ | |
4485 itervec.safe_push (iter); | |
4486 namevec.safe_push (name); | |
4487 name = use; | |
4488 goto start_over; | |
4489 | |
4490 continue_walking: | |
4491 VN_INFO (name)->low = MIN (VN_INFO (name)->low, | |
4492 VN_INFO (use)->low); | |
4493 } | |
4494 if (VN_INFO (use)->dfsnum < VN_INFO (name)->dfsnum | |
4495 && VN_INFO (use)->on_sccstack) | |
4496 { | |
4497 VN_INFO (name)->low = MIN (VN_INFO (use)->dfsnum, | |
4498 VN_INFO (name)->low); | |
4499 } | |
4500 } | |
4501 | |
4502 usep = op_iter_next_use (&iter); | |
4503 } | |
4504 } | |
4505 | |
4506 /* Allocate a value number table. */ | |
4507 | |
4508 static void | |
4509 allocate_vn_table (vn_tables_t table) | |
4510 { | |
4511 table->phis = new vn_phi_table_type (23); | |
4512 table->nary = new vn_nary_op_table_type (23); | |
4513 table->references = new vn_reference_table_type (23); | |
4514 | |
4515 gcc_obstack_init (&table->nary_obstack); | |
4516 table->phis_pool = new object_allocator<vn_phi_s> ("VN phis"); | |
4517 table->references_pool = new object_allocator<vn_reference_s> | |
4518 ("VN references"); | |
4519 } | 4488 } |
4520 | 4489 |
4521 /* Free a value number table. */ | 4490 /* Free a value number table. */ |
4522 | 4491 |
4523 static void | 4492 static void |
4524 free_vn_table (vn_tables_t table) | 4493 free_vn_table (vn_tables_t table) |
4525 { | 4494 { |
4495 /* Walk over elements and release vectors. */ | |
4496 vn_reference_iterator_type hir; | |
4497 vn_reference_t vr; | |
4498 FOR_EACH_HASH_TABLE_ELEMENT (*table->references, vr, vn_reference_t, hir) | |
4499 vr->operands.release (); | |
4526 delete table->phis; | 4500 delete table->phis; |
4527 table->phis = NULL; | 4501 table->phis = NULL; |
4528 delete table->nary; | 4502 delete table->nary; |
4529 table->nary = NULL; | 4503 table->nary = NULL; |
4530 delete table->references; | 4504 delete table->references; |
4531 table->references = NULL; | 4505 table->references = NULL; |
4532 obstack_free (&table->nary_obstack, NULL); | |
4533 delete table->phis_pool; | |
4534 delete table->references_pool; | |
4535 } | |
4536 | |
4537 static void | |
4538 init_scc_vn (void) | |
4539 { | |
4540 int j; | |
4541 int *rpo_numbers_temp; | |
4542 | |
4543 calculate_dominance_info (CDI_DOMINATORS); | |
4544 mark_dfs_back_edges (); | |
4545 | |
4546 sccstack.create (0); | |
4547 constant_to_value_id = new hash_table<vn_constant_hasher> (23); | |
4548 | |
4549 constant_value_ids = BITMAP_ALLOC (NULL); | |
4550 | |
4551 next_dfs_num = 1; | |
4552 next_value_id = 1; | |
4553 | |
4554 vn_ssa_aux_table.create (num_ssa_names + 1); | |
4555 /* VEC_alloc doesn't actually grow it to the right size, it just | |
4556 preallocates the space to do so. */ | |
4557 vn_ssa_aux_table.safe_grow_cleared (num_ssa_names + 1); | |
4558 gcc_obstack_init (&vn_ssa_aux_obstack); | |
4559 | |
4560 shared_lookup_phiargs.create (0); | |
4561 shared_lookup_references.create (0); | |
4562 rpo_numbers = XNEWVEC (int, last_basic_block_for_fn (cfun)); | |
4563 rpo_numbers_temp = | |
4564 XNEWVEC (int, n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS); | |
4565 pre_and_rev_post_order_compute (NULL, rpo_numbers_temp, false); | |
4566 | |
4567 /* RPO numbers is an array of rpo ordering, rpo[i] = bb means that | |
4568 the i'th block in RPO order is bb. We want to map bb's to RPO | |
4569 numbers, so we need to rearrange this array. */ | |
4570 for (j = 0; j < n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS; j++) | |
4571 rpo_numbers[rpo_numbers_temp[j]] = j; | |
4572 | |
4573 XDELETE (rpo_numbers_temp); | |
4574 | |
4575 VN_TOP = build_decl (UNKNOWN_LOCATION, VAR_DECL, | |
4576 get_identifier ("VN_TOP"), error_mark_node); | |
4577 | |
4578 renumber_gimple_stmt_uids (); | |
4579 | |
4580 /* Create the valid and optimistic value numbering tables. */ | |
4581 valid_info = XCNEW (struct vn_tables_s); | |
4582 allocate_vn_table (valid_info); | |
4583 optimistic_info = XCNEW (struct vn_tables_s); | |
4584 allocate_vn_table (optimistic_info); | |
4585 current_info = valid_info; | |
4586 | |
4587 /* Create the VN_INFO structures, and initialize value numbers to | |
4588 TOP or VARYING for parameters. */ | |
4589 size_t i; | |
4590 tree name; | |
4591 | |
4592 FOR_EACH_SSA_NAME (i, name, cfun) | |
4593 { | |
4594 VN_INFO_GET (name)->valnum = VN_TOP; | |
4595 VN_INFO (name)->needs_insertion = false; | |
4596 VN_INFO (name)->expr = NULL; | |
4597 VN_INFO (name)->value_id = 0; | |
4598 | |
4599 if (!SSA_NAME_IS_DEFAULT_DEF (name)) | |
4600 continue; | |
4601 | |
4602 switch (TREE_CODE (SSA_NAME_VAR (name))) | |
4603 { | |
4604 case VAR_DECL: | |
4605 /* All undefined vars are VARYING. */ | |
4606 VN_INFO (name)->valnum = name; | |
4607 VN_INFO (name)->visited = true; | |
4608 break; | |
4609 | |
4610 case PARM_DECL: | |
4611 /* Parameters are VARYING but we can record a condition | |
4612 if we know it is a non-NULL pointer. */ | |
4613 VN_INFO (name)->visited = true; | |
4614 VN_INFO (name)->valnum = name; | |
4615 if (POINTER_TYPE_P (TREE_TYPE (name)) | |
4616 && nonnull_arg_p (SSA_NAME_VAR (name))) | |
4617 { | |
4618 tree ops[2]; | |
4619 ops[0] = name; | |
4620 ops[1] = build_int_cst (TREE_TYPE (name), 0); | |
4621 vn_nary_op_insert_pieces (2, NE_EXPR, boolean_type_node, ops, | |
4622 boolean_true_node, 0); | |
4623 if (dump_file && (dump_flags & TDF_DETAILS)) | |
4624 { | |
4625 fprintf (dump_file, "Recording "); | |
4626 print_generic_expr (dump_file, name, TDF_SLIM); | |
4627 fprintf (dump_file, " != 0\n"); | |
4628 } | |
4629 } | |
4630 break; | |
4631 | |
4632 case RESULT_DECL: | |
4633 /* If the result is passed by invisible reference the default | |
4634 def is initialized, otherwise it's uninitialized. Still | |
4635 undefined is varying. */ | |
4636 VN_INFO (name)->visited = true; | |
4637 VN_INFO (name)->valnum = name; | |
4638 break; | |
4639 | |
4640 default: | |
4641 gcc_unreachable (); | |
4642 } | |
4643 } | |
4644 } | |
4645 | |
4646 /* Restore SSA info that has been reset on value leaders. */ | |
4647 | |
4648 void | |
4649 scc_vn_restore_ssa_info (void) | |
4650 { | |
4651 unsigned i; | |
4652 tree name; | |
4653 | |
4654 FOR_EACH_SSA_NAME (i, name, cfun) | |
4655 { | |
4656 if (has_VN_INFO (name)) | |
4657 { | |
4658 if (VN_INFO (name)->needs_insertion) | |
4659 ; | |
4660 else if (POINTER_TYPE_P (TREE_TYPE (name)) | |
4661 && VN_INFO (name)->info.ptr_info) | |
4662 SSA_NAME_PTR_INFO (name) = VN_INFO (name)->info.ptr_info; | |
4663 else if (INTEGRAL_TYPE_P (TREE_TYPE (name)) | |
4664 && VN_INFO (name)->info.range_info) | |
4665 { | |
4666 SSA_NAME_RANGE_INFO (name) = VN_INFO (name)->info.range_info; | |
4667 SSA_NAME_ANTI_RANGE_P (name) | |
4668 = VN_INFO (name)->range_info_anti_range_p; | |
4669 } | |
4670 } | |
4671 } | |
4672 } | |
4673 | |
4674 void | |
4675 free_scc_vn (void) | |
4676 { | |
4677 size_t i; | |
4678 tree name; | |
4679 | |
4680 delete constant_to_value_id; | |
4681 constant_to_value_id = NULL; | |
4682 BITMAP_FREE (constant_value_ids); | |
4683 shared_lookup_phiargs.release (); | |
4684 shared_lookup_references.release (); | |
4685 XDELETEVEC (rpo_numbers); | |
4686 | |
4687 FOR_EACH_SSA_NAME (i, name, cfun) | |
4688 { | |
4689 if (has_VN_INFO (name) | |
4690 && VN_INFO (name)->needs_insertion) | |
4691 release_ssa_name (name); | |
4692 } | |
4693 obstack_free (&vn_ssa_aux_obstack, NULL); | |
4694 vn_ssa_aux_table.release (); | |
4695 | |
4696 sccstack.release (); | |
4697 free_vn_table (valid_info); | |
4698 XDELETE (valid_info); | |
4699 free_vn_table (optimistic_info); | |
4700 XDELETE (optimistic_info); | |
4701 | |
4702 BITMAP_FREE (const_parms); | |
4703 } | 4506 } |
4704 | 4507 |
4705 /* Set *ID according to RESULT. */ | 4508 /* Set *ID according to RESULT. */ |
4706 | 4509 |
4707 static void | 4510 static void |
4729 | 4532 |
4730 /* Now set the value ids of the things we had put in the hash | 4533 /* Now set the value ids of the things we had put in the hash |
4731 table. */ | 4534 table. */ |
4732 | 4535 |
4733 FOR_EACH_HASH_TABLE_ELEMENT (*valid_info->nary, vno, vn_nary_op_t, hin) | 4536 FOR_EACH_HASH_TABLE_ELEMENT (*valid_info->nary, vno, vn_nary_op_t, hin) |
4734 set_value_id_for_result (vno->result, &vno->value_id); | 4537 if (! vno->predicated_values) |
4538 set_value_id_for_result (vno->u.result, &vno->value_id); | |
4735 | 4539 |
4736 FOR_EACH_HASH_TABLE_ELEMENT (*valid_info->phis, vp, vn_phi_t, hip) | 4540 FOR_EACH_HASH_TABLE_ELEMENT (*valid_info->phis, vp, vn_phi_t, hip) |
4737 set_value_id_for_result (vp->result, &vp->value_id); | 4541 set_value_id_for_result (vp->result, &vp->value_id); |
4738 | 4542 |
4739 FOR_EACH_HASH_TABLE_ELEMENT (*valid_info->references, vr, vn_reference_t, | 4543 FOR_EACH_HASH_TABLE_ELEMENT (*valid_info->references, vr, vn_reference_t, |
4740 hir) | 4544 hir) |
4741 set_value_id_for_result (vr->result, &vr->value_id); | 4545 set_value_id_for_result (vr->result, &vr->value_id); |
4742 } | |
4743 | |
4744 class sccvn_dom_walker : public dom_walker | |
4745 { | |
4746 public: | |
4747 sccvn_dom_walker () | |
4748 : dom_walker (CDI_DOMINATORS, true), cond_stack (0) {} | |
4749 | |
4750 virtual edge before_dom_children (basic_block); | |
4751 virtual void after_dom_children (basic_block); | |
4752 | |
4753 void record_cond (basic_block, | |
4754 enum tree_code code, tree lhs, tree rhs, bool value); | |
4755 void record_conds (basic_block, | |
4756 enum tree_code code, tree lhs, tree rhs, bool value); | |
4757 | |
4758 auto_vec<std::pair <basic_block, std::pair <vn_nary_op_t, vn_nary_op_t> > > | |
4759 cond_stack; | |
4760 }; | |
4761 | |
4762 /* Record a temporary condition for the BB and its dominated blocks. */ | |
4763 | |
4764 void | |
4765 sccvn_dom_walker::record_cond (basic_block bb, | |
4766 enum tree_code code, tree lhs, tree rhs, | |
4767 bool value) | |
4768 { | |
4769 tree ops[2] = { lhs, rhs }; | |
4770 vn_nary_op_t old = NULL; | |
4771 if (vn_nary_op_lookup_pieces (2, code, boolean_type_node, ops, &old)) | |
4772 current_info->nary->remove_elt_with_hash (old, old->hashcode); | |
4773 vn_nary_op_t cond | |
4774 = vn_nary_op_insert_pieces (2, code, boolean_type_node, ops, | |
4775 value | |
4776 ? boolean_true_node | |
4777 : boolean_false_node, 0); | |
4778 if (dump_file && (dump_flags & TDF_DETAILS)) | |
4779 { | |
4780 fprintf (dump_file, "Recording temporarily "); | |
4781 print_generic_expr (dump_file, ops[0], TDF_SLIM); | |
4782 fprintf (dump_file, " %s ", get_tree_code_name (code)); | |
4783 print_generic_expr (dump_file, ops[1], TDF_SLIM); | |
4784 fprintf (dump_file, " == %s%s\n", | |
4785 value ? "true" : "false", | |
4786 old ? " (old entry saved)" : ""); | |
4787 } | |
4788 cond_stack.safe_push (std::make_pair (bb, std::make_pair (cond, old))); | |
4789 } | |
4790 | |
4791 /* Record temporary conditions for the BB and its dominated blocks | |
4792 according to LHS CODE RHS == VALUE and its dominated conditions. */ | |
4793 | |
4794 void | |
4795 sccvn_dom_walker::record_conds (basic_block bb, | |
4796 enum tree_code code, tree lhs, tree rhs, | |
4797 bool value) | |
4798 { | |
4799 /* Record the original condition. */ | |
4800 record_cond (bb, code, lhs, rhs, value); | |
4801 | |
4802 if (!value) | |
4803 return; | |
4804 | |
4805 /* Record dominated conditions if the condition is true. Note that | |
4806 the inversion is already recorded. */ | |
4807 switch (code) | |
4808 { | |
4809 case LT_EXPR: | |
4810 case GT_EXPR: | |
4811 record_cond (bb, code == LT_EXPR ? LE_EXPR : GE_EXPR, lhs, rhs, true); | |
4812 record_cond (bb, NE_EXPR, lhs, rhs, true); | |
4813 record_cond (bb, EQ_EXPR, lhs, rhs, false); | |
4814 break; | |
4815 | |
4816 case EQ_EXPR: | |
4817 record_cond (bb, LE_EXPR, lhs, rhs, true); | |
4818 record_cond (bb, GE_EXPR, lhs, rhs, true); | |
4819 record_cond (bb, LT_EXPR, lhs, rhs, false); | |
4820 record_cond (bb, GT_EXPR, lhs, rhs, false); | |
4821 break; | |
4822 | |
4823 default: | |
4824 break; | |
4825 } | |
4826 } | |
4827 | |
4828 /* Restore expressions and values derived from conditionals. */ | |
4829 | |
4830 void | |
4831 sccvn_dom_walker::after_dom_children (basic_block bb) | |
4832 { | |
4833 while (!cond_stack.is_empty () | |
4834 && cond_stack.last ().first == bb) | |
4835 { | |
4836 vn_nary_op_t cond = cond_stack.last ().second.first; | |
4837 vn_nary_op_t old = cond_stack.last ().second.second; | |
4838 current_info->nary->remove_elt_with_hash (cond, cond->hashcode); | |
4839 if (old) | |
4840 vn_nary_op_insert_into (old, current_info->nary, false); | |
4841 cond_stack.pop (); | |
4842 } | |
4843 } | |
4844 | |
4845 /* Value number all statements in BB. */ | |
4846 | |
4847 edge | |
4848 sccvn_dom_walker::before_dom_children (basic_block bb) | |
4849 { | |
4850 edge e; | |
4851 edge_iterator ei; | |
4852 | |
4853 if (dump_file && (dump_flags & TDF_DETAILS)) | |
4854 fprintf (dump_file, "Visiting BB %d\n", bb->index); | |
4855 | |
4856 /* If we have a single predecessor record the equivalence from a | |
4857 possible condition on the predecessor edge. */ | |
4858 edge pred_e = NULL; | |
4859 FOR_EACH_EDGE (e, ei, bb->preds) | |
4860 { | |
4861 /* Ignore simple backedges from this to allow recording conditions | |
4862 in loop headers. */ | |
4863 if (dominated_by_p (CDI_DOMINATORS, e->src, e->dest)) | |
4864 continue; | |
4865 if (! pred_e) | |
4866 pred_e = e; | |
4867 else | |
4868 { | |
4869 pred_e = NULL; | |
4870 break; | |
4871 } | |
4872 } | |
4873 if (pred_e) | |
4874 { | |
4875 /* Check if there are multiple executable successor edges in | |
4876 the source block. Otherwise there is no additional info | |
4877 to be recorded. */ | |
4878 edge e2; | |
4879 FOR_EACH_EDGE (e2, ei, pred_e->src->succs) | |
4880 if (e2 != pred_e | |
4881 && e2->flags & EDGE_EXECUTABLE) | |
4882 break; | |
4883 if (e2 && (e2->flags & EDGE_EXECUTABLE)) | |
4884 { | |
4885 gimple *stmt = last_stmt (pred_e->src); | |
4886 if (stmt | |
4887 && gimple_code (stmt) == GIMPLE_COND) | |
4888 { | |
4889 enum tree_code code = gimple_cond_code (stmt); | |
4890 tree lhs = gimple_cond_lhs (stmt); | |
4891 tree rhs = gimple_cond_rhs (stmt); | |
4892 record_conds (bb, code, lhs, rhs, | |
4893 (pred_e->flags & EDGE_TRUE_VALUE) != 0); | |
4894 code = invert_tree_comparison (code, HONOR_NANS (lhs)); | |
4895 if (code != ERROR_MARK) | |
4896 record_conds (bb, code, lhs, rhs, | |
4897 (pred_e->flags & EDGE_TRUE_VALUE) == 0); | |
4898 } | |
4899 } | |
4900 } | |
4901 | |
4902 /* Value-number all defs in the basic-block. */ | |
4903 for (gphi_iterator gsi = gsi_start_phis (bb); | |
4904 !gsi_end_p (gsi); gsi_next (&gsi)) | |
4905 { | |
4906 gphi *phi = gsi.phi (); | |
4907 tree res = PHI_RESULT (phi); | |
4908 if (!VN_INFO (res)->visited) | |
4909 DFS (res); | |
4910 } | |
4911 for (gimple_stmt_iterator gsi = gsi_start_bb (bb); | |
4912 !gsi_end_p (gsi); gsi_next (&gsi)) | |
4913 { | |
4914 ssa_op_iter i; | |
4915 tree op; | |
4916 FOR_EACH_SSA_TREE_OPERAND (op, gsi_stmt (gsi), i, SSA_OP_ALL_DEFS) | |
4917 if (!VN_INFO (op)->visited) | |
4918 DFS (op); | |
4919 } | |
4920 | |
4921 /* Finally look at the last stmt. */ | |
4922 gimple *stmt = last_stmt (bb); | |
4923 if (!stmt) | |
4924 return NULL; | |
4925 | |
4926 enum gimple_code code = gimple_code (stmt); | |
4927 if (code != GIMPLE_COND | |
4928 && code != GIMPLE_SWITCH | |
4929 && code != GIMPLE_GOTO) | |
4930 return NULL; | |
4931 | |
4932 if (dump_file && (dump_flags & TDF_DETAILS)) | |
4933 { | |
4934 fprintf (dump_file, "Visiting control stmt ending BB %d: ", bb->index); | |
4935 print_gimple_stmt (dump_file, stmt, 0); | |
4936 } | |
4937 | |
4938 /* ??? We can even handle stmts with outgoing EH or ABNORMAL edges | |
4939 if value-numbering can prove they are not reachable. Handling | |
4940 computed gotos is also possible. */ | |
4941 tree val; | |
4942 switch (code) | |
4943 { | |
4944 case GIMPLE_COND: | |
4945 { | |
4946 tree lhs = vn_valueize (gimple_cond_lhs (stmt)); | |
4947 tree rhs = vn_valueize (gimple_cond_rhs (stmt)); | |
4948 val = gimple_simplify (gimple_cond_code (stmt), | |
4949 boolean_type_node, lhs, rhs, | |
4950 NULL, vn_valueize); | |
4951 /* If that didn't simplify to a constant see if we have recorded | |
4952 temporary expressions from taken edges. */ | |
4953 if (!val || TREE_CODE (val) != INTEGER_CST) | |
4954 { | |
4955 tree ops[2]; | |
4956 ops[0] = lhs; | |
4957 ops[1] = rhs; | |
4958 val = vn_nary_op_lookup_pieces (2, gimple_cond_code (stmt), | |
4959 boolean_type_node, ops, NULL); | |
4960 } | |
4961 break; | |
4962 } | |
4963 case GIMPLE_SWITCH: | |
4964 val = gimple_switch_index (as_a <gswitch *> (stmt)); | |
4965 break; | |
4966 case GIMPLE_GOTO: | |
4967 val = gimple_goto_dest (stmt); | |
4968 break; | |
4969 default: | |
4970 gcc_unreachable (); | |
4971 } | |
4972 if (!val) | |
4973 return NULL; | |
4974 | |
4975 edge taken = find_taken_edge (bb, vn_valueize (val)); | |
4976 if (!taken) | |
4977 return NULL; | |
4978 | |
4979 if (dump_file && (dump_flags & TDF_DETAILS)) | |
4980 fprintf (dump_file, "Marking all edges out of BB %d but (%d -> %d) as " | |
4981 "not executable\n", bb->index, bb->index, taken->dest->index); | |
4982 | |
4983 return taken; | |
4984 } | |
4985 | |
4986 /* Do SCCVN. Returns true if it finished, false if we bailed out | |
4987 due to resource constraints. DEFAULT_VN_WALK_KIND_ specifies | |
4988 how we use the alias oracle walking during the VN process. */ | |
4989 | |
4990 void | |
4991 run_scc_vn (vn_lookup_kind default_vn_walk_kind_) | |
4992 { | |
4993 size_t i; | |
4994 | |
4995 default_vn_walk_kind = default_vn_walk_kind_; | |
4996 | |
4997 init_scc_vn (); | |
4998 | |
4999 /* Collect pointers we know point to readonly memory. */ | |
5000 const_parms = BITMAP_ALLOC (NULL); | |
5001 tree fnspec = lookup_attribute ("fn spec", | |
5002 TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl))); | |
5003 if (fnspec) | |
5004 { | |
5005 fnspec = TREE_VALUE (TREE_VALUE (fnspec)); | |
5006 i = 1; | |
5007 for (tree arg = DECL_ARGUMENTS (cfun->decl); | |
5008 arg; arg = DECL_CHAIN (arg), ++i) | |
5009 { | |
5010 if (i >= (unsigned) TREE_STRING_LENGTH (fnspec)) | |
5011 break; | |
5012 if (TREE_STRING_POINTER (fnspec)[i] == 'R' | |
5013 || TREE_STRING_POINTER (fnspec)[i] == 'r') | |
5014 { | |
5015 tree name = ssa_default_def (cfun, arg); | |
5016 if (name) | |
5017 bitmap_set_bit (const_parms, SSA_NAME_VERSION (name)); | |
5018 } | |
5019 } | |
5020 } | |
5021 | |
5022 /* Walk all blocks in dominator order, value-numbering stmts | |
5023 SSA defs and decide whether outgoing edges are not executable. */ | |
5024 sccvn_dom_walker walker; | |
5025 walker.walk (ENTRY_BLOCK_PTR_FOR_FN (cfun)); | |
5026 | |
5027 /* Initialize the value ids and prune out remaining VN_TOPs | |
5028 from dead code. */ | |
5029 tree name; | |
5030 FOR_EACH_SSA_NAME (i, name, cfun) | |
5031 { | |
5032 vn_ssa_aux_t info = VN_INFO (name); | |
5033 if (!info->visited | |
5034 || info->valnum == VN_TOP) | |
5035 info->valnum = name; | |
5036 if (info->valnum == name) | |
5037 info->value_id = get_next_value_id (); | |
5038 else if (is_gimple_min_invariant (info->valnum)) | |
5039 info->value_id = get_or_alloc_constant_value_id (info->valnum); | |
5040 } | |
5041 | |
5042 /* Propagate. */ | |
5043 FOR_EACH_SSA_NAME (i, name, cfun) | |
5044 { | |
5045 vn_ssa_aux_t info = VN_INFO (name); | |
5046 if (TREE_CODE (info->valnum) == SSA_NAME | |
5047 && info->valnum != name | |
5048 && info->value_id != VN_INFO (info->valnum)->value_id) | |
5049 info->value_id = VN_INFO (info->valnum)->value_id; | |
5050 } | |
5051 | |
5052 set_hashtable_value_ids (); | |
5053 | |
5054 if (dump_file && (dump_flags & TDF_DETAILS)) | |
5055 { | |
5056 fprintf (dump_file, "Value numbers:\n"); | |
5057 FOR_EACH_SSA_NAME (i, name, cfun) | |
5058 { | |
5059 if (VN_INFO (name)->visited | |
5060 && SSA_VAL (name) != name) | |
5061 { | |
5062 print_generic_expr (dump_file, name); | |
5063 fprintf (dump_file, " = "); | |
5064 print_generic_expr (dump_file, SSA_VAL (name)); | |
5065 fprintf (dump_file, "\n"); | |
5066 } | |
5067 } | |
5068 } | |
5069 } | 4546 } |
5070 | 4547 |
5071 /* Return the maximum value id we have ever seen. */ | 4548 /* Return the maximum value id we have ever seen. */ |
5072 | 4549 |
5073 unsigned int | 4550 unsigned int |
5166 ~eliminate_dom_walker (); | 4643 ~eliminate_dom_walker (); |
5167 | 4644 |
5168 virtual edge before_dom_children (basic_block); | 4645 virtual edge before_dom_children (basic_block); |
5169 virtual void after_dom_children (basic_block); | 4646 virtual void after_dom_children (basic_block); |
5170 | 4647 |
5171 tree eliminate_avail (tree op); | 4648 virtual tree eliminate_avail (basic_block, tree op); |
5172 void eliminate_push_avail (tree op); | 4649 virtual void eliminate_push_avail (basic_block, tree op); |
5173 tree eliminate_insert (gimple_stmt_iterator *gsi, tree val); | 4650 tree eliminate_insert (basic_block, gimple_stmt_iterator *gsi, tree val); |
4651 | |
4652 void eliminate_stmt (basic_block, gimple_stmt_iterator *); | |
4653 | |
4654 unsigned eliminate_cleanup (bool region_p = false); | |
5174 | 4655 |
5175 bool do_pre; | 4656 bool do_pre; |
5176 unsigned int el_todo; | 4657 unsigned int el_todo; |
5177 unsigned int eliminations; | 4658 unsigned int eliminations; |
5178 unsigned int insertions; | 4659 unsigned int insertions; |
5184 bitmap need_eh_cleanup; | 4665 bitmap need_eh_cleanup; |
5185 | 4666 |
5186 /* Blocks with statements that have had their AB properties changed. */ | 4667 /* Blocks with statements that have had their AB properties changed. */ |
5187 bitmap need_ab_cleanup; | 4668 bitmap need_ab_cleanup; |
5188 | 4669 |
4670 /* Local state for the eliminate domwalk. */ | |
5189 auto_vec<gimple *> to_remove; | 4671 auto_vec<gimple *> to_remove; |
5190 auto_vec<gimple *> to_fixup; | 4672 auto_vec<gimple *> to_fixup; |
5191 auto_vec<tree> avail; | 4673 auto_vec<tree> avail; |
5192 auto_vec<tree> avail_stack; | 4674 auto_vec<tree> avail_stack; |
5193 }; | 4675 }; |
5210 | 4692 |
5211 /* Return a leader for OP that is available at the current point of the | 4693 /* Return a leader for OP that is available at the current point of the |
5212 eliminate domwalk. */ | 4694 eliminate domwalk. */ |
5213 | 4695 |
5214 tree | 4696 tree |
5215 eliminate_dom_walker::eliminate_avail (tree op) | 4697 eliminate_dom_walker::eliminate_avail (basic_block, tree op) |
5216 { | 4698 { |
5217 tree valnum = VN_INFO (op)->valnum; | 4699 tree valnum = VN_INFO (op)->valnum; |
5218 if (TREE_CODE (valnum) == SSA_NAME) | 4700 if (TREE_CODE (valnum) == SSA_NAME) |
5219 { | 4701 { |
5220 if (SSA_NAME_IS_DEFAULT_DEF (valnum)) | 4702 if (SSA_NAME_IS_DEFAULT_DEF (valnum)) |
5228 } | 4710 } |
5229 | 4711 |
5230 /* At the current point of the eliminate domwalk make OP available. */ | 4712 /* At the current point of the eliminate domwalk make OP available. */ |
5231 | 4713 |
5232 void | 4714 void |
5233 eliminate_dom_walker::eliminate_push_avail (tree op) | 4715 eliminate_dom_walker::eliminate_push_avail (basic_block, tree op) |
5234 { | 4716 { |
5235 tree valnum = VN_INFO (op)->valnum; | 4717 tree valnum = VN_INFO (op)->valnum; |
5236 if (TREE_CODE (valnum) == SSA_NAME) | 4718 if (TREE_CODE (valnum) == SSA_NAME) |
5237 { | 4719 { |
5238 if (avail.length () <= SSA_NAME_VERSION (valnum)) | 4720 if (avail.length () <= SSA_NAME_VERSION (valnum)) |
5247 | 4729 |
5248 /* Insert the expression recorded by SCCVN for VAL at *GSI. Returns | 4730 /* Insert the expression recorded by SCCVN for VAL at *GSI. Returns |
5249 the leader for the expression if insertion was successful. */ | 4731 the leader for the expression if insertion was successful. */ |
5250 | 4732 |
5251 tree | 4733 tree |
5252 eliminate_dom_walker::eliminate_insert (gimple_stmt_iterator *gsi, tree val) | 4734 eliminate_dom_walker::eliminate_insert (basic_block bb, |
4735 gimple_stmt_iterator *gsi, tree val) | |
5253 { | 4736 { |
5254 /* We can insert a sequence with a single assignment only. */ | 4737 /* We can insert a sequence with a single assignment only. */ |
5255 gimple_seq stmts = VN_INFO (val)->expr; | 4738 gimple_seq stmts = VN_INFO (val)->expr; |
5256 if (!gimple_seq_singleton_p (stmts)) | 4739 if (!gimple_seq_singleton_p (stmts)) |
5257 return NULL_TREE; | 4740 return NULL_TREE; |
5266 | 4749 |
5267 tree op = gimple_assign_rhs1 (stmt); | 4750 tree op = gimple_assign_rhs1 (stmt); |
5268 if (gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR | 4751 if (gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR |
5269 || gimple_assign_rhs_code (stmt) == BIT_FIELD_REF) | 4752 || gimple_assign_rhs_code (stmt) == BIT_FIELD_REF) |
5270 op = TREE_OPERAND (op, 0); | 4753 op = TREE_OPERAND (op, 0); |
5271 tree leader = TREE_CODE (op) == SSA_NAME ? eliminate_avail (op) : op; | 4754 tree leader = TREE_CODE (op) == SSA_NAME ? eliminate_avail (bb, op) : op; |
5272 if (!leader) | 4755 if (!leader) |
5273 return NULL_TREE; | 4756 return NULL_TREE; |
5274 | 4757 |
5275 tree res; | 4758 tree res; |
5276 stmts = NULL; | 4759 stmts = NULL; |
5298 res now has two values. That doesn't play well with how | 4781 res now has two values. That doesn't play well with how |
5299 we track availability here, so give up. */ | 4782 we track availability here, so give up. */ |
5300 if (dump_file && (dump_flags & TDF_DETAILS)) | 4783 if (dump_file && (dump_flags & TDF_DETAILS)) |
5301 { | 4784 { |
5302 if (TREE_CODE (res) == SSA_NAME) | 4785 if (TREE_CODE (res) == SSA_NAME) |
5303 res = eliminate_avail (res); | 4786 res = eliminate_avail (bb, res); |
5304 if (res) | 4787 if (res) |
5305 { | 4788 { |
5306 fprintf (dump_file, "Failed to insert expression for value "); | 4789 fprintf (dump_file, "Failed to insert expression for value "); |
5307 print_generic_expr (dump_file, val); | 4790 print_generic_expr (dump_file, val); |
5308 fprintf (dump_file, " which is really fully redundant to "); | 4791 fprintf (dump_file, " which is really fully redundant to "); |
5314 return NULL_TREE; | 4797 return NULL_TREE; |
5315 } | 4798 } |
5316 else | 4799 else |
5317 { | 4800 { |
5318 gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT); | 4801 gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT); |
5319 VN_INFO_GET (res)->valnum = val; | 4802 VN_INFO (res)->valnum = val; |
4803 VN_INFO (res)->visited = true; | |
5320 } | 4804 } |
5321 | 4805 |
5322 insertions++; | 4806 insertions++; |
5323 if (dump_file && (dump_flags & TDF_DETAILS)) | 4807 if (dump_file && (dump_flags & TDF_DETAILS)) |
5324 { | 4808 { |
5327 } | 4811 } |
5328 | 4812 |
5329 return res; | 4813 return res; |
5330 } | 4814 } |
5331 | 4815 |
5332 | 4816 void |
4817 eliminate_dom_walker::eliminate_stmt (basic_block b, gimple_stmt_iterator *gsi) | |
4818 { | |
4819 tree sprime = NULL_TREE; | |
4820 gimple *stmt = gsi_stmt (*gsi); | |
4821 tree lhs = gimple_get_lhs (stmt); | |
4822 if (lhs && TREE_CODE (lhs) == SSA_NAME | |
4823 && !gimple_has_volatile_ops (stmt) | |
4824 /* See PR43491. Do not replace a global register variable when | |
4825 it is a the RHS of an assignment. Do replace local register | |
4826 variables since gcc does not guarantee a local variable will | |
4827 be allocated in register. | |
4828 ??? The fix isn't effective here. This should instead | |
4829 be ensured by not value-numbering them the same but treating | |
4830 them like volatiles? */ | |
4831 && !(gimple_assign_single_p (stmt) | |
4832 && (TREE_CODE (gimple_assign_rhs1 (stmt)) == VAR_DECL | |
4833 && DECL_HARD_REGISTER (gimple_assign_rhs1 (stmt)) | |
4834 && is_global_var (gimple_assign_rhs1 (stmt))))) | |
4835 { | |
4836 sprime = eliminate_avail (b, lhs); | |
4837 if (!sprime) | |
4838 { | |
4839 /* If there is no existing usable leader but SCCVN thinks | |
4840 it has an expression it wants to use as replacement, | |
4841 insert that. */ | |
4842 tree val = VN_INFO (lhs)->valnum; | |
4843 if (val != VN_TOP | |
4844 && TREE_CODE (val) == SSA_NAME | |
4845 && VN_INFO (val)->needs_insertion | |
4846 && VN_INFO (val)->expr != NULL | |
4847 && (sprime = eliminate_insert (b, gsi, val)) != NULL_TREE) | |
4848 eliminate_push_avail (b, sprime); | |
4849 } | |
4850 | |
4851 /* If this now constitutes a copy duplicate points-to | |
4852 and range info appropriately. This is especially | |
4853 important for inserted code. See tree-ssa-copy.c | |
4854 for similar code. */ | |
4855 if (sprime | |
4856 && TREE_CODE (sprime) == SSA_NAME) | |
4857 { | |
4858 basic_block sprime_b = gimple_bb (SSA_NAME_DEF_STMT (sprime)); | |
4859 if (POINTER_TYPE_P (TREE_TYPE (lhs)) | |
4860 && SSA_NAME_PTR_INFO (lhs) | |
4861 && ! SSA_NAME_PTR_INFO (sprime)) | |
4862 { | |
4863 duplicate_ssa_name_ptr_info (sprime, | |
4864 SSA_NAME_PTR_INFO (lhs)); | |
4865 if (b != sprime_b) | |
4866 mark_ptr_info_alignment_unknown | |
4867 (SSA_NAME_PTR_INFO (sprime)); | |
4868 } | |
4869 else if (INTEGRAL_TYPE_P (TREE_TYPE (lhs)) | |
4870 && SSA_NAME_RANGE_INFO (lhs) | |
4871 && ! SSA_NAME_RANGE_INFO (sprime) | |
4872 && b == sprime_b) | |
4873 duplicate_ssa_name_range_info (sprime, | |
4874 SSA_NAME_RANGE_TYPE (lhs), | |
4875 SSA_NAME_RANGE_INFO (lhs)); | |
4876 } | |
4877 | |
4878 /* Inhibit the use of an inserted PHI on a loop header when | |
4879 the address of the memory reference is a simple induction | |
4880 variable. In other cases the vectorizer won't do anything | |
4881 anyway (either it's loop invariant or a complicated | |
4882 expression). */ | |
4883 if (sprime | |
4884 && TREE_CODE (sprime) == SSA_NAME | |
4885 && do_pre | |
4886 && (flag_tree_loop_vectorize || flag_tree_parallelize_loops > 1) | |
4887 && loop_outer (b->loop_father) | |
4888 && has_zero_uses (sprime) | |
4889 && bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (sprime)) | |
4890 && gimple_assign_load_p (stmt)) | |
4891 { | |
4892 gimple *def_stmt = SSA_NAME_DEF_STMT (sprime); | |
4893 basic_block def_bb = gimple_bb (def_stmt); | |
4894 if (gimple_code (def_stmt) == GIMPLE_PHI | |
4895 && def_bb->loop_father->header == def_bb) | |
4896 { | |
4897 loop_p loop = def_bb->loop_father; | |
4898 ssa_op_iter iter; | |
4899 tree op; | |
4900 bool found = false; | |
4901 FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE) | |
4902 { | |
4903 affine_iv iv; | |
4904 def_bb = gimple_bb (SSA_NAME_DEF_STMT (op)); | |
4905 if (def_bb | |
4906 && flow_bb_inside_loop_p (loop, def_bb) | |
4907 && simple_iv (loop, loop, op, &iv, true)) | |
4908 { | |
4909 found = true; | |
4910 break; | |
4911 } | |
4912 } | |
4913 if (found) | |
4914 { | |
4915 if (dump_file && (dump_flags & TDF_DETAILS)) | |
4916 { | |
4917 fprintf (dump_file, "Not replacing "); | |
4918 print_gimple_expr (dump_file, stmt, 0); | |
4919 fprintf (dump_file, " with "); | |
4920 print_generic_expr (dump_file, sprime); | |
4921 fprintf (dump_file, " which would add a loop" | |
4922 " carried dependence to loop %d\n", | |
4923 loop->num); | |
4924 } | |
4925 /* Don't keep sprime available. */ | |
4926 sprime = NULL_TREE; | |
4927 } | |
4928 } | |
4929 } | |
4930 | |
4931 if (sprime) | |
4932 { | |
4933 /* If we can propagate the value computed for LHS into | |
4934 all uses don't bother doing anything with this stmt. */ | |
4935 if (may_propagate_copy (lhs, sprime)) | |
4936 { | |
4937 /* Mark it for removal. */ | |
4938 to_remove.safe_push (stmt); | |
4939 | |
4940 /* ??? Don't count copy/constant propagations. */ | |
4941 if (gimple_assign_single_p (stmt) | |
4942 && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME | |
4943 || gimple_assign_rhs1 (stmt) == sprime)) | |
4944 return; | |
4945 | |
4946 if (dump_file && (dump_flags & TDF_DETAILS)) | |
4947 { | |
4948 fprintf (dump_file, "Replaced "); | |
4949 print_gimple_expr (dump_file, stmt, 0); | |
4950 fprintf (dump_file, " with "); | |
4951 print_generic_expr (dump_file, sprime); | |
4952 fprintf (dump_file, " in all uses of "); | |
4953 print_gimple_stmt (dump_file, stmt, 0); | |
4954 } | |
4955 | |
4956 eliminations++; | |
4957 return; | |
4958 } | |
4959 | |
4960 /* If this is an assignment from our leader (which | |
4961 happens in the case the value-number is a constant) | |
4962 then there is nothing to do. */ | |
4963 if (gimple_assign_single_p (stmt) | |
4964 && sprime == gimple_assign_rhs1 (stmt)) | |
4965 return; | |
4966 | |
4967 /* Else replace its RHS. */ | |
4968 bool can_make_abnormal_goto | |
4969 = is_gimple_call (stmt) | |
4970 && stmt_can_make_abnormal_goto (stmt); | |
4971 | |
4972 if (dump_file && (dump_flags & TDF_DETAILS)) | |
4973 { | |
4974 fprintf (dump_file, "Replaced "); | |
4975 print_gimple_expr (dump_file, stmt, 0); | |
4976 fprintf (dump_file, " with "); | |
4977 print_generic_expr (dump_file, sprime); | |
4978 fprintf (dump_file, " in "); | |
4979 print_gimple_stmt (dump_file, stmt, 0); | |
4980 } | |
4981 | |
4982 eliminations++; | |
4983 gimple *orig_stmt = stmt; | |
4984 if (!useless_type_conversion_p (TREE_TYPE (lhs), | |
4985 TREE_TYPE (sprime))) | |
4986 sprime = fold_convert (TREE_TYPE (lhs), sprime); | |
4987 tree vdef = gimple_vdef (stmt); | |
4988 tree vuse = gimple_vuse (stmt); | |
4989 propagate_tree_value_into_stmt (gsi, sprime); | |
4990 stmt = gsi_stmt (*gsi); | |
4991 update_stmt (stmt); | |
4992 /* In case the VDEF on the original stmt was released, value-number | |
4993 it to the VUSE. This is to make vuse_ssa_val able to skip | |
4994 released virtual operands. */ | |
4995 if (vdef != gimple_vdef (stmt)) | |
4996 { | |
4997 gcc_assert (SSA_NAME_IN_FREE_LIST (vdef)); | |
4998 VN_INFO (vdef)->valnum = vuse; | |
4999 } | |
5000 | |
5001 /* If we removed EH side-effects from the statement, clean | |
5002 its EH information. */ | |
5003 if (maybe_clean_or_replace_eh_stmt (orig_stmt, stmt)) | |
5004 { | |
5005 bitmap_set_bit (need_eh_cleanup, | |
5006 gimple_bb (stmt)->index); | |
5007 if (dump_file && (dump_flags & TDF_DETAILS)) | |
5008 fprintf (dump_file, " Removed EH side-effects.\n"); | |
5009 } | |
5010 | |
5011 /* Likewise for AB side-effects. */ | |
5012 if (can_make_abnormal_goto | |
5013 && !stmt_can_make_abnormal_goto (stmt)) | |
5014 { | |
5015 bitmap_set_bit (need_ab_cleanup, | |
5016 gimple_bb (stmt)->index); | |
5017 if (dump_file && (dump_flags & TDF_DETAILS)) | |
5018 fprintf (dump_file, " Removed AB side-effects.\n"); | |
5019 } | |
5020 | |
5021 return; | |
5022 } | |
5023 } | |
5024 | |
5025 /* If the statement is a scalar store, see if the expression | |
5026 has the same value number as its rhs. If so, the store is | |
5027 dead. */ | |
5028 if (gimple_assign_single_p (stmt) | |
5029 && !gimple_has_volatile_ops (stmt) | |
5030 && !is_gimple_reg (gimple_assign_lhs (stmt)) | |
5031 && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME | |
5032 || is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))) | |
5033 { | |
5034 tree val; | |
5035 tree rhs = gimple_assign_rhs1 (stmt); | |
5036 vn_reference_t vnresult; | |
5037 val = vn_reference_lookup (lhs, gimple_vuse (stmt), VN_WALKREWRITE, | |
5038 &vnresult, false); | |
5039 if (TREE_CODE (rhs) == SSA_NAME) | |
5040 rhs = VN_INFO (rhs)->valnum; | |
5041 if (val | |
5042 && operand_equal_p (val, rhs, 0)) | |
5043 { | |
5044 /* We can only remove the later store if the former aliases | |
5045 at least all accesses the later one does or if the store | |
5046 was to readonly memory storing the same value. */ | |
5047 alias_set_type set = get_alias_set (lhs); | |
5048 if (! vnresult | |
5049 || vnresult->set == set | |
5050 || alias_set_subset_of (set, vnresult->set)) | |
5051 { | |
5052 if (dump_file && (dump_flags & TDF_DETAILS)) | |
5053 { | |
5054 fprintf (dump_file, "Deleted redundant store "); | |
5055 print_gimple_stmt (dump_file, stmt, 0); | |
5056 } | |
5057 | |
5058 /* Queue stmt for removal. */ | |
5059 to_remove.safe_push (stmt); | |
5060 return; | |
5061 } | |
5062 } | |
5063 } | |
5064 | |
5065 /* If this is a control statement value numbering left edges | |
5066 unexecuted on force the condition in a way consistent with | |
5067 that. */ | |
5068 if (gcond *cond = dyn_cast <gcond *> (stmt)) | |
5069 { | |
5070 if ((EDGE_SUCC (b, 0)->flags & EDGE_EXECUTABLE) | |
5071 ^ (EDGE_SUCC (b, 1)->flags & EDGE_EXECUTABLE)) | |
5072 { | |
5073 if (dump_file && (dump_flags & TDF_DETAILS)) | |
5074 { | |
5075 fprintf (dump_file, "Removing unexecutable edge from "); | |
5076 print_gimple_stmt (dump_file, stmt, 0); | |
5077 } | |
5078 if (((EDGE_SUCC (b, 0)->flags & EDGE_TRUE_VALUE) != 0) | |
5079 == ((EDGE_SUCC (b, 0)->flags & EDGE_EXECUTABLE) != 0)) | |
5080 gimple_cond_make_true (cond); | |
5081 else | |
5082 gimple_cond_make_false (cond); | |
5083 update_stmt (cond); | |
5084 el_todo |= TODO_cleanup_cfg; | |
5085 return; | |
5086 } | |
5087 } | |
5088 | |
5089 bool can_make_abnormal_goto = stmt_can_make_abnormal_goto (stmt); | |
5090 bool was_noreturn = (is_gimple_call (stmt) | |
5091 && gimple_call_noreturn_p (stmt)); | |
5092 tree vdef = gimple_vdef (stmt); | |
5093 tree vuse = gimple_vuse (stmt); | |
5094 | |
5095 /* If we didn't replace the whole stmt (or propagate the result | |
5096 into all uses), replace all uses on this stmt with their | |
5097 leaders. */ | |
5098 bool modified = false; | |
5099 use_operand_p use_p; | |
5100 ssa_op_iter iter; | |
5101 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE) | |
5102 { | |
5103 tree use = USE_FROM_PTR (use_p); | |
5104 /* ??? The call code above leaves stmt operands un-updated. */ | |
5105 if (TREE_CODE (use) != SSA_NAME) | |
5106 continue; | |
5107 tree sprime; | |
5108 if (SSA_NAME_IS_DEFAULT_DEF (use)) | |
5109 /* ??? For default defs BB shouldn't matter, but we have to | |
5110 solve the inconsistency between rpo eliminate and | |
5111 dom eliminate avail valueization first. */ | |
5112 sprime = eliminate_avail (b, use); | |
5113 else | |
5114 /* Look for sth available at the definition block of the argument. | |
5115 This avoids inconsistencies between availability there which | |
5116 decides if the stmt can be removed and availability at the | |
5117 use site. The SSA property ensures that things available | |
5118 at the definition are also available at uses. */ | |
5119 sprime = eliminate_avail (gimple_bb (SSA_NAME_DEF_STMT (use)), use); | |
5120 if (sprime && sprime != use | |
5121 && may_propagate_copy (use, sprime) | |
5122 /* We substitute into debug stmts to avoid excessive | |
5123 debug temporaries created by removed stmts, but we need | |
5124 to avoid doing so for inserted sprimes as we never want | |
5125 to create debug temporaries for them. */ | |
5126 && (!inserted_exprs | |
5127 || TREE_CODE (sprime) != SSA_NAME | |
5128 || !is_gimple_debug (stmt) | |
5129 || !bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (sprime)))) | |
5130 { | |
5131 propagate_value (use_p, sprime); | |
5132 modified = true; | |
5133 } | |
5134 } | |
5135 | |
5136 /* Fold the stmt if modified, this canonicalizes MEM_REFs we propagated | |
5137 into which is a requirement for the IPA devirt machinery. */ | |
5138 gimple *old_stmt = stmt; | |
5139 if (modified) | |
5140 { | |
5141 /* If a formerly non-invariant ADDR_EXPR is turned into an | |
5142 invariant one it was on a separate stmt. */ | |
5143 if (gimple_assign_single_p (stmt) | |
5144 && TREE_CODE (gimple_assign_rhs1 (stmt)) == ADDR_EXPR) | |
5145 recompute_tree_invariant_for_addr_expr (gimple_assign_rhs1 (stmt)); | |
5146 gimple_stmt_iterator prev = *gsi; | |
5147 gsi_prev (&prev); | |
5148 if (fold_stmt (gsi)) | |
5149 { | |
5150 /* fold_stmt may have created new stmts inbetween | |
5151 the previous stmt and the folded stmt. Mark | |
5152 all defs created there as varying to not confuse | |
5153 the SCCVN machinery as we're using that even during | |
5154 elimination. */ | |
5155 if (gsi_end_p (prev)) | |
5156 prev = gsi_start_bb (b); | |
5157 else | |
5158 gsi_next (&prev); | |
5159 if (gsi_stmt (prev) != gsi_stmt (*gsi)) | |
5160 do | |
5161 { | |
5162 tree def; | |
5163 ssa_op_iter dit; | |
5164 FOR_EACH_SSA_TREE_OPERAND (def, gsi_stmt (prev), | |
5165 dit, SSA_OP_ALL_DEFS) | |
5166 /* As existing DEFs may move between stmts | |
5167 only process new ones. */ | |
5168 if (! has_VN_INFO (def)) | |
5169 { | |
5170 VN_INFO (def)->valnum = def; | |
5171 VN_INFO (def)->visited = true; | |
5172 } | |
5173 if (gsi_stmt (prev) == gsi_stmt (*gsi)) | |
5174 break; | |
5175 gsi_next (&prev); | |
5176 } | |
5177 while (1); | |
5178 } | |
5179 stmt = gsi_stmt (*gsi); | |
5180 /* In case we folded the stmt away schedule the NOP for removal. */ | |
5181 if (gimple_nop_p (stmt)) | |
5182 to_remove.safe_push (stmt); | |
5183 } | |
5184 | |
5185 /* Visit indirect calls and turn them into direct calls if | |
5186 possible using the devirtualization machinery. Do this before | |
5187 checking for required EH/abnormal/noreturn cleanup as devird | |
5188 may expose more of those. */ | |
5189 if (gcall *call_stmt = dyn_cast <gcall *> (stmt)) | |
5190 { | |
5191 tree fn = gimple_call_fn (call_stmt); | |
5192 if (fn | |
5193 && flag_devirtualize | |
5194 && virtual_method_call_p (fn)) | |
5195 { | |
5196 tree otr_type = obj_type_ref_class (fn); | |
5197 unsigned HOST_WIDE_INT otr_tok | |
5198 = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (fn)); | |
5199 tree instance; | |
5200 ipa_polymorphic_call_context context (current_function_decl, | |
5201 fn, stmt, &instance); | |
5202 context.get_dynamic_type (instance, OBJ_TYPE_REF_OBJECT (fn), | |
5203 otr_type, stmt); | |
5204 bool final; | |
5205 vec <cgraph_node *> targets | |
5206 = possible_polymorphic_call_targets (obj_type_ref_class (fn), | |
5207 otr_tok, context, &final); | |
5208 if (dump_file) | |
5209 dump_possible_polymorphic_call_targets (dump_file, | |
5210 obj_type_ref_class (fn), | |
5211 otr_tok, context); | |
5212 if (final && targets.length () <= 1 && dbg_cnt (devirt)) | |
5213 { | |
5214 tree fn; | |
5215 if (targets.length () == 1) | |
5216 fn = targets[0]->decl; | |
5217 else | |
5218 fn = builtin_decl_implicit (BUILT_IN_UNREACHABLE); | |
5219 if (dump_enabled_p ()) | |
5220 { | |
5221 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, stmt, | |
5222 "converting indirect call to " | |
5223 "function %s\n", | |
5224 lang_hooks.decl_printable_name (fn, 2)); | |
5225 } | |
5226 gimple_call_set_fndecl (call_stmt, fn); | |
5227 /* If changing the call to __builtin_unreachable | |
5228 or similar noreturn function, adjust gimple_call_fntype | |
5229 too. */ | |
5230 if (gimple_call_noreturn_p (call_stmt) | |
5231 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fn))) | |
5232 && TYPE_ARG_TYPES (TREE_TYPE (fn)) | |
5233 && (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fn))) | |
5234 == void_type_node)) | |
5235 gimple_call_set_fntype (call_stmt, TREE_TYPE (fn)); | |
5236 maybe_remove_unused_call_args (cfun, call_stmt); | |
5237 modified = true; | |
5238 } | |
5239 } | |
5240 } | |
5241 | |
5242 if (modified) | |
5243 { | |
5244 /* When changing a call into a noreturn call, cfg cleanup | |
5245 is needed to fix up the noreturn call. */ | |
5246 if (!was_noreturn | |
5247 && is_gimple_call (stmt) && gimple_call_noreturn_p (stmt)) | |
5248 to_fixup.safe_push (stmt); | |
5249 /* When changing a condition or switch into one we know what | |
5250 edge will be executed, schedule a cfg cleanup. */ | |
5251 if ((gimple_code (stmt) == GIMPLE_COND | |
5252 && (gimple_cond_true_p (as_a <gcond *> (stmt)) | |
5253 || gimple_cond_false_p (as_a <gcond *> (stmt)))) | |
5254 || (gimple_code (stmt) == GIMPLE_SWITCH | |
5255 && TREE_CODE (gimple_switch_index | |
5256 (as_a <gswitch *> (stmt))) == INTEGER_CST)) | |
5257 el_todo |= TODO_cleanup_cfg; | |
5258 /* If we removed EH side-effects from the statement, clean | |
5259 its EH information. */ | |
5260 if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt)) | |
5261 { | |
5262 bitmap_set_bit (need_eh_cleanup, | |
5263 gimple_bb (stmt)->index); | |
5264 if (dump_file && (dump_flags & TDF_DETAILS)) | |
5265 fprintf (dump_file, " Removed EH side-effects.\n"); | |
5266 } | |
5267 /* Likewise for AB side-effects. */ | |
5268 if (can_make_abnormal_goto | |
5269 && !stmt_can_make_abnormal_goto (stmt)) | |
5270 { | |
5271 bitmap_set_bit (need_ab_cleanup, | |
5272 gimple_bb (stmt)->index); | |
5273 if (dump_file && (dump_flags & TDF_DETAILS)) | |
5274 fprintf (dump_file, " Removed AB side-effects.\n"); | |
5275 } | |
5276 update_stmt (stmt); | |
5277 /* In case the VDEF on the original stmt was released, value-number | |
5278 it to the VUSE. This is to make vuse_ssa_val able to skip | |
5279 released virtual operands. */ | |
5280 if (vdef && SSA_NAME_IN_FREE_LIST (vdef)) | |
5281 VN_INFO (vdef)->valnum = vuse; | |
5282 } | |
5283 | |
5284 /* Make new values available - for fully redundant LHS we | |
5285 continue with the next stmt above and skip this. */ | |
5286 def_operand_p defp; | |
5287 FOR_EACH_SSA_DEF_OPERAND (defp, stmt, iter, SSA_OP_DEF) | |
5288 eliminate_push_avail (b, DEF_FROM_PTR (defp)); | |
5289 } | |
5333 | 5290 |
5334 /* Perform elimination for the basic-block B during the domwalk. */ | 5291 /* Perform elimination for the basic-block B during the domwalk. */ |
5335 | 5292 |
5336 edge | 5293 edge |
5337 eliminate_dom_walker::before_dom_children (basic_block b) | 5294 eliminate_dom_walker::before_dom_children (basic_block b) |
5338 { | 5295 { |
5339 /* Mark new bb. */ | 5296 /* Mark new bb. */ |
5340 avail_stack.safe_push (NULL_TREE); | 5297 avail_stack.safe_push (NULL_TREE); |
5341 | 5298 |
5342 /* Skip unreachable blocks marked unreachable during the SCCVN domwalk. */ | 5299 /* Skip unreachable blocks marked unreachable during the SCCVN domwalk. */ |
5343 edge_iterator ei; | 5300 if (!(b->flags & BB_EXECUTABLE)) |
5344 edge e; | |
5345 FOR_EACH_EDGE (e, ei, b->preds) | |
5346 if (e->flags & EDGE_EXECUTABLE) | |
5347 break; | |
5348 if (! e) | |
5349 return NULL; | 5301 return NULL; |
5302 | |
5303 vn_context_bb = b; | |
5350 | 5304 |
5351 for (gphi_iterator gsi = gsi_start_phis (b); !gsi_end_p (gsi);) | 5305 for (gphi_iterator gsi = gsi_start_phis (b); !gsi_end_p (gsi);) |
5352 { | 5306 { |
5353 gphi *phi = gsi.phi (); | 5307 gphi *phi = gsi.phi (); |
5354 tree res = PHI_RESULT (phi); | 5308 tree res = PHI_RESULT (phi); |
5357 { | 5311 { |
5358 gsi_next (&gsi); | 5312 gsi_next (&gsi); |
5359 continue; | 5313 continue; |
5360 } | 5314 } |
5361 | 5315 |
5362 tree sprime = eliminate_avail (res); | 5316 tree sprime = eliminate_avail (b, res); |
5363 if (sprime | 5317 if (sprime |
5364 && sprime != res) | 5318 && sprime != res) |
5365 { | 5319 { |
5366 if (dump_file && (dump_flags & TDF_DETAILS)) | 5320 if (dump_file && (dump_flags & TDF_DETAILS)) |
5367 { | 5321 { |
5395 gimple_stmt_iterator gsi2 = gsi_after_labels (b); | 5349 gimple_stmt_iterator gsi2 = gsi_after_labels (b); |
5396 gsi_insert_before (&gsi2, stmt, GSI_NEW_STMT); | 5350 gsi_insert_before (&gsi2, stmt, GSI_NEW_STMT); |
5397 continue; | 5351 continue; |
5398 } | 5352 } |
5399 | 5353 |
5400 eliminate_push_avail (res); | 5354 eliminate_push_avail (b, res); |
5401 gsi_next (&gsi); | 5355 gsi_next (&gsi); |
5402 } | 5356 } |
5403 | 5357 |
5404 for (gimple_stmt_iterator gsi = gsi_start_bb (b); | 5358 for (gimple_stmt_iterator gsi = gsi_start_bb (b); |
5405 !gsi_end_p (gsi); | 5359 !gsi_end_p (gsi); |
5406 gsi_next (&gsi)) | 5360 gsi_next (&gsi)) |
5407 { | 5361 eliminate_stmt (b, &gsi); |
5408 tree sprime = NULL_TREE; | |
5409 gimple *stmt = gsi_stmt (gsi); | |
5410 tree lhs = gimple_get_lhs (stmt); | |
5411 if (lhs && TREE_CODE (lhs) == SSA_NAME | |
5412 && !gimple_has_volatile_ops (stmt) | |
5413 /* See PR43491. Do not replace a global register variable when | |
5414 it is a the RHS of an assignment. Do replace local register | |
5415 variables since gcc does not guarantee a local variable will | |
5416 be allocated in register. | |
5417 ??? The fix isn't effective here. This should instead | |
5418 be ensured by not value-numbering them the same but treating | |
5419 them like volatiles? */ | |
5420 && !(gimple_assign_single_p (stmt) | |
5421 && (TREE_CODE (gimple_assign_rhs1 (stmt)) == VAR_DECL | |
5422 && DECL_HARD_REGISTER (gimple_assign_rhs1 (stmt)) | |
5423 && is_global_var (gimple_assign_rhs1 (stmt))))) | |
5424 { | |
5425 sprime = eliminate_avail (lhs); | |
5426 if (!sprime) | |
5427 { | |
5428 /* If there is no existing usable leader but SCCVN thinks | |
5429 it has an expression it wants to use as replacement, | |
5430 insert that. */ | |
5431 tree val = VN_INFO (lhs)->valnum; | |
5432 if (val != VN_TOP | |
5433 && TREE_CODE (val) == SSA_NAME | |
5434 && VN_INFO (val)->needs_insertion | |
5435 && VN_INFO (val)->expr != NULL | |
5436 && (sprime = eliminate_insert (&gsi, val)) != NULL_TREE) | |
5437 eliminate_push_avail (sprime); | |
5438 } | |
5439 | |
5440 /* If this now constitutes a copy duplicate points-to | |
5441 and range info appropriately. This is especially | |
5442 important for inserted code. See tree-ssa-copy.c | |
5443 for similar code. */ | |
5444 if (sprime | |
5445 && TREE_CODE (sprime) == SSA_NAME) | |
5446 { | |
5447 basic_block sprime_b = gimple_bb (SSA_NAME_DEF_STMT (sprime)); | |
5448 if (POINTER_TYPE_P (TREE_TYPE (lhs)) | |
5449 && VN_INFO_PTR_INFO (lhs) | |
5450 && ! VN_INFO_PTR_INFO (sprime)) | |
5451 { | |
5452 duplicate_ssa_name_ptr_info (sprime, | |
5453 VN_INFO_PTR_INFO (lhs)); | |
5454 if (b != sprime_b) | |
5455 mark_ptr_info_alignment_unknown | |
5456 (SSA_NAME_PTR_INFO (sprime)); | |
5457 } | |
5458 else if (INTEGRAL_TYPE_P (TREE_TYPE (lhs)) | |
5459 && VN_INFO_RANGE_INFO (lhs) | |
5460 && ! VN_INFO_RANGE_INFO (sprime) | |
5461 && b == sprime_b) | |
5462 duplicate_ssa_name_range_info (sprime, | |
5463 VN_INFO_RANGE_TYPE (lhs), | |
5464 VN_INFO_RANGE_INFO (lhs)); | |
5465 } | |
5466 | |
5467 /* Inhibit the use of an inserted PHI on a loop header when | |
5468 the address of the memory reference is a simple induction | |
5469 variable. In other cases the vectorizer won't do anything | |
5470 anyway (either it's loop invariant or a complicated | |
5471 expression). */ | |
5472 if (sprime | |
5473 && TREE_CODE (sprime) == SSA_NAME | |
5474 && do_pre | |
5475 && (flag_tree_loop_vectorize || flag_tree_parallelize_loops > 1) | |
5476 && loop_outer (b->loop_father) | |
5477 && has_zero_uses (sprime) | |
5478 && bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (sprime)) | |
5479 && gimple_assign_load_p (stmt)) | |
5480 { | |
5481 gimple *def_stmt = SSA_NAME_DEF_STMT (sprime); | |
5482 basic_block def_bb = gimple_bb (def_stmt); | |
5483 if (gimple_code (def_stmt) == GIMPLE_PHI | |
5484 && def_bb->loop_father->header == def_bb) | |
5485 { | |
5486 loop_p loop = def_bb->loop_father; | |
5487 ssa_op_iter iter; | |
5488 tree op; | |
5489 bool found = false; | |
5490 FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE) | |
5491 { | |
5492 affine_iv iv; | |
5493 def_bb = gimple_bb (SSA_NAME_DEF_STMT (op)); | |
5494 if (def_bb | |
5495 && flow_bb_inside_loop_p (loop, def_bb) | |
5496 && simple_iv (loop, loop, op, &iv, true)) | |
5497 { | |
5498 found = true; | |
5499 break; | |
5500 } | |
5501 } | |
5502 if (found) | |
5503 { | |
5504 if (dump_file && (dump_flags & TDF_DETAILS)) | |
5505 { | |
5506 fprintf (dump_file, "Not replacing "); | |
5507 print_gimple_expr (dump_file, stmt, 0); | |
5508 fprintf (dump_file, " with "); | |
5509 print_generic_expr (dump_file, sprime); | |
5510 fprintf (dump_file, " which would add a loop" | |
5511 " carried dependence to loop %d\n", | |
5512 loop->num); | |
5513 } | |
5514 /* Don't keep sprime available. */ | |
5515 sprime = NULL_TREE; | |
5516 } | |
5517 } | |
5518 } | |
5519 | |
5520 if (sprime) | |
5521 { | |
5522 /* If we can propagate the value computed for LHS into | |
5523 all uses don't bother doing anything with this stmt. */ | |
5524 if (may_propagate_copy (lhs, sprime)) | |
5525 { | |
5526 /* Mark it for removal. */ | |
5527 to_remove.safe_push (stmt); | |
5528 | |
5529 /* ??? Don't count copy/constant propagations. */ | |
5530 if (gimple_assign_single_p (stmt) | |
5531 && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME | |
5532 || gimple_assign_rhs1 (stmt) == sprime)) | |
5533 continue; | |
5534 | |
5535 if (dump_file && (dump_flags & TDF_DETAILS)) | |
5536 { | |
5537 fprintf (dump_file, "Replaced "); | |
5538 print_gimple_expr (dump_file, stmt, 0); | |
5539 fprintf (dump_file, " with "); | |
5540 print_generic_expr (dump_file, sprime); | |
5541 fprintf (dump_file, " in all uses of "); | |
5542 print_gimple_stmt (dump_file, stmt, 0); | |
5543 } | |
5544 | |
5545 eliminations++; | |
5546 continue; | |
5547 } | |
5548 | |
5549 /* If this is an assignment from our leader (which | |
5550 happens in the case the value-number is a constant) | |
5551 then there is nothing to do. */ | |
5552 if (gimple_assign_single_p (stmt) | |
5553 && sprime == gimple_assign_rhs1 (stmt)) | |
5554 continue; | |
5555 | |
5556 /* Else replace its RHS. */ | |
5557 bool can_make_abnormal_goto | |
5558 = is_gimple_call (stmt) | |
5559 && stmt_can_make_abnormal_goto (stmt); | |
5560 | |
5561 if (dump_file && (dump_flags & TDF_DETAILS)) | |
5562 { | |
5563 fprintf (dump_file, "Replaced "); | |
5564 print_gimple_expr (dump_file, stmt, 0); | |
5565 fprintf (dump_file, " with "); | |
5566 print_generic_expr (dump_file, sprime); | |
5567 fprintf (dump_file, " in "); | |
5568 print_gimple_stmt (dump_file, stmt, 0); | |
5569 } | |
5570 | |
5571 eliminations++; | |
5572 gimple *orig_stmt = stmt; | |
5573 if (!useless_type_conversion_p (TREE_TYPE (lhs), | |
5574 TREE_TYPE (sprime))) | |
5575 sprime = fold_convert (TREE_TYPE (lhs), sprime); | |
5576 tree vdef = gimple_vdef (stmt); | |
5577 tree vuse = gimple_vuse (stmt); | |
5578 propagate_tree_value_into_stmt (&gsi, sprime); | |
5579 stmt = gsi_stmt (gsi); | |
5580 update_stmt (stmt); | |
5581 if (vdef != gimple_vdef (stmt)) | |
5582 VN_INFO (vdef)->valnum = vuse; | |
5583 | |
5584 /* If we removed EH side-effects from the statement, clean | |
5585 its EH information. */ | |
5586 if (maybe_clean_or_replace_eh_stmt (orig_stmt, stmt)) | |
5587 { | |
5588 bitmap_set_bit (need_eh_cleanup, | |
5589 gimple_bb (stmt)->index); | |
5590 if (dump_file && (dump_flags & TDF_DETAILS)) | |
5591 fprintf (dump_file, " Removed EH side-effects.\n"); | |
5592 } | |
5593 | |
5594 /* Likewise for AB side-effects. */ | |
5595 if (can_make_abnormal_goto | |
5596 && !stmt_can_make_abnormal_goto (stmt)) | |
5597 { | |
5598 bitmap_set_bit (need_ab_cleanup, | |
5599 gimple_bb (stmt)->index); | |
5600 if (dump_file && (dump_flags & TDF_DETAILS)) | |
5601 fprintf (dump_file, " Removed AB side-effects.\n"); | |
5602 } | |
5603 | |
5604 continue; | |
5605 } | |
5606 } | |
5607 | |
5608 /* If the statement is a scalar store, see if the expression | |
5609 has the same value number as its rhs. If so, the store is | |
5610 dead. */ | |
5611 if (gimple_assign_single_p (stmt) | |
5612 && !gimple_has_volatile_ops (stmt) | |
5613 && !is_gimple_reg (gimple_assign_lhs (stmt)) | |
5614 && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME | |
5615 || is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))) | |
5616 { | |
5617 tree val; | |
5618 tree rhs = gimple_assign_rhs1 (stmt); | |
5619 vn_reference_t vnresult; | |
5620 val = vn_reference_lookup (lhs, gimple_vuse (stmt), VN_WALKREWRITE, | |
5621 &vnresult, false); | |
5622 if (TREE_CODE (rhs) == SSA_NAME) | |
5623 rhs = VN_INFO (rhs)->valnum; | |
5624 if (val | |
5625 && operand_equal_p (val, rhs, 0)) | |
5626 { | |
5627 /* We can only remove the later store if the former aliases | |
5628 at least all accesses the later one does or if the store | |
5629 was to readonly memory storing the same value. */ | |
5630 alias_set_type set = get_alias_set (lhs); | |
5631 if (! vnresult | |
5632 || vnresult->set == set | |
5633 || alias_set_subset_of (set, vnresult->set)) | |
5634 { | |
5635 if (dump_file && (dump_flags & TDF_DETAILS)) | |
5636 { | |
5637 fprintf (dump_file, "Deleted redundant store "); | |
5638 print_gimple_stmt (dump_file, stmt, 0); | |
5639 } | |
5640 | |
5641 /* Queue stmt for removal. */ | |
5642 to_remove.safe_push (stmt); | |
5643 continue; | |
5644 } | |
5645 } | |
5646 } | |
5647 | |
5648 /* If this is a control statement value numbering left edges | |
5649 unexecuted on force the condition in a way consistent with | |
5650 that. */ | |
5651 if (gcond *cond = dyn_cast <gcond *> (stmt)) | |
5652 { | |
5653 if ((EDGE_SUCC (b, 0)->flags & EDGE_EXECUTABLE) | |
5654 ^ (EDGE_SUCC (b, 1)->flags & EDGE_EXECUTABLE)) | |
5655 { | |
5656 if (dump_file && (dump_flags & TDF_DETAILS)) | |
5657 { | |
5658 fprintf (dump_file, "Removing unexecutable edge from "); | |
5659 print_gimple_stmt (dump_file, stmt, 0); | |
5660 } | |
5661 if (((EDGE_SUCC (b, 0)->flags & EDGE_TRUE_VALUE) != 0) | |
5662 == ((EDGE_SUCC (b, 0)->flags & EDGE_EXECUTABLE) != 0)) | |
5663 gimple_cond_make_true (cond); | |
5664 else | |
5665 gimple_cond_make_false (cond); | |
5666 update_stmt (cond); | |
5667 el_todo |= TODO_cleanup_cfg; | |
5668 continue; | |
5669 } | |
5670 } | |
5671 | |
5672 bool can_make_abnormal_goto = stmt_can_make_abnormal_goto (stmt); | |
5673 bool was_noreturn = (is_gimple_call (stmt) | |
5674 && gimple_call_noreturn_p (stmt)); | |
5675 tree vdef = gimple_vdef (stmt); | |
5676 tree vuse = gimple_vuse (stmt); | |
5677 | |
5678 /* If we didn't replace the whole stmt (or propagate the result | |
5679 into all uses), replace all uses on this stmt with their | |
5680 leaders. */ | |
5681 bool modified = false; | |
5682 use_operand_p use_p; | |
5683 ssa_op_iter iter; | |
5684 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE) | |
5685 { | |
5686 tree use = USE_FROM_PTR (use_p); | |
5687 /* ??? The call code above leaves stmt operands un-updated. */ | |
5688 if (TREE_CODE (use) != SSA_NAME) | |
5689 continue; | |
5690 tree sprime = eliminate_avail (use); | |
5691 if (sprime && sprime != use | |
5692 && may_propagate_copy (use, sprime) | |
5693 /* We substitute into debug stmts to avoid excessive | |
5694 debug temporaries created by removed stmts, but we need | |
5695 to avoid doing so for inserted sprimes as we never want | |
5696 to create debug temporaries for them. */ | |
5697 && (!inserted_exprs | |
5698 || TREE_CODE (sprime) != SSA_NAME | |
5699 || !is_gimple_debug (stmt) | |
5700 || !bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (sprime)))) | |
5701 { | |
5702 propagate_value (use_p, sprime); | |
5703 modified = true; | |
5704 } | |
5705 } | |
5706 | |
5707 /* Fold the stmt if modified, this canonicalizes MEM_REFs we propagated | |
5708 into which is a requirement for the IPA devirt machinery. */ | |
5709 gimple *old_stmt = stmt; | |
5710 if (modified) | |
5711 { | |
5712 /* If a formerly non-invariant ADDR_EXPR is turned into an | |
5713 invariant one it was on a separate stmt. */ | |
5714 if (gimple_assign_single_p (stmt) | |
5715 && TREE_CODE (gimple_assign_rhs1 (stmt)) == ADDR_EXPR) | |
5716 recompute_tree_invariant_for_addr_expr (gimple_assign_rhs1 (stmt)); | |
5717 gimple_stmt_iterator prev = gsi; | |
5718 gsi_prev (&prev); | |
5719 if (fold_stmt (&gsi)) | |
5720 { | |
5721 /* fold_stmt may have created new stmts inbetween | |
5722 the previous stmt and the folded stmt. Mark | |
5723 all defs created there as varying to not confuse | |
5724 the SCCVN machinery as we're using that even during | |
5725 elimination. */ | |
5726 if (gsi_end_p (prev)) | |
5727 prev = gsi_start_bb (b); | |
5728 else | |
5729 gsi_next (&prev); | |
5730 if (gsi_stmt (prev) != gsi_stmt (gsi)) | |
5731 do | |
5732 { | |
5733 tree def; | |
5734 ssa_op_iter dit; | |
5735 FOR_EACH_SSA_TREE_OPERAND (def, gsi_stmt (prev), | |
5736 dit, SSA_OP_ALL_DEFS) | |
5737 /* As existing DEFs may move between stmts | |
5738 we have to guard VN_INFO_GET. */ | |
5739 if (! has_VN_INFO (def)) | |
5740 VN_INFO_GET (def)->valnum = def; | |
5741 if (gsi_stmt (prev) == gsi_stmt (gsi)) | |
5742 break; | |
5743 gsi_next (&prev); | |
5744 } | |
5745 while (1); | |
5746 } | |
5747 stmt = gsi_stmt (gsi); | |
5748 /* In case we folded the stmt away schedule the NOP for removal. */ | |
5749 if (gimple_nop_p (stmt)) | |
5750 to_remove.safe_push (stmt); | |
5751 } | |
5752 | |
5753 /* Visit indirect calls and turn them into direct calls if | |
5754 possible using the devirtualization machinery. Do this before | |
5755 checking for required EH/abnormal/noreturn cleanup as devird | |
5756 may expose more of those. */ | |
5757 if (gcall *call_stmt = dyn_cast <gcall *> (stmt)) | |
5758 { | |
5759 tree fn = gimple_call_fn (call_stmt); | |
5760 if (fn | |
5761 && flag_devirtualize | |
5762 && virtual_method_call_p (fn)) | |
5763 { | |
5764 tree otr_type = obj_type_ref_class (fn); | |
5765 unsigned HOST_WIDE_INT otr_tok | |
5766 = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (fn)); | |
5767 tree instance; | |
5768 ipa_polymorphic_call_context context (current_function_decl, | |
5769 fn, stmt, &instance); | |
5770 context.get_dynamic_type (instance, OBJ_TYPE_REF_OBJECT (fn), | |
5771 otr_type, stmt); | |
5772 bool final; | |
5773 vec <cgraph_node *> targets | |
5774 = possible_polymorphic_call_targets (obj_type_ref_class (fn), | |
5775 otr_tok, context, &final); | |
5776 if (dump_file) | |
5777 dump_possible_polymorphic_call_targets (dump_file, | |
5778 obj_type_ref_class (fn), | |
5779 otr_tok, context); | |
5780 if (final && targets.length () <= 1 && dbg_cnt (devirt)) | |
5781 { | |
5782 tree fn; | |
5783 if (targets.length () == 1) | |
5784 fn = targets[0]->decl; | |
5785 else | |
5786 fn = builtin_decl_implicit (BUILT_IN_UNREACHABLE); | |
5787 if (dump_enabled_p ()) | |
5788 { | |
5789 location_t loc = gimple_location (stmt); | |
5790 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc, | |
5791 "converting indirect call to " | |
5792 "function %s\n", | |
5793 lang_hooks.decl_printable_name (fn, 2)); | |
5794 } | |
5795 gimple_call_set_fndecl (call_stmt, fn); | |
5796 /* If changing the call to __builtin_unreachable | |
5797 or similar noreturn function, adjust gimple_call_fntype | |
5798 too. */ | |
5799 if (gimple_call_noreturn_p (call_stmt) | |
5800 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fn))) | |
5801 && TYPE_ARG_TYPES (TREE_TYPE (fn)) | |
5802 && (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fn))) | |
5803 == void_type_node)) | |
5804 gimple_call_set_fntype (call_stmt, TREE_TYPE (fn)); | |
5805 maybe_remove_unused_call_args (cfun, call_stmt); | |
5806 modified = true; | |
5807 } | |
5808 } | |
5809 } | |
5810 | |
5811 if (modified) | |
5812 { | |
5813 /* When changing a call into a noreturn call, cfg cleanup | |
5814 is needed to fix up the noreturn call. */ | |
5815 if (!was_noreturn | |
5816 && is_gimple_call (stmt) && gimple_call_noreturn_p (stmt)) | |
5817 to_fixup.safe_push (stmt); | |
5818 /* When changing a condition or switch into one we know what | |
5819 edge will be executed, schedule a cfg cleanup. */ | |
5820 if ((gimple_code (stmt) == GIMPLE_COND | |
5821 && (gimple_cond_true_p (as_a <gcond *> (stmt)) | |
5822 || gimple_cond_false_p (as_a <gcond *> (stmt)))) | |
5823 || (gimple_code (stmt) == GIMPLE_SWITCH | |
5824 && TREE_CODE (gimple_switch_index | |
5825 (as_a <gswitch *> (stmt))) == INTEGER_CST)) | |
5826 el_todo |= TODO_cleanup_cfg; | |
5827 /* If we removed EH side-effects from the statement, clean | |
5828 its EH information. */ | |
5829 if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt)) | |
5830 { | |
5831 bitmap_set_bit (need_eh_cleanup, | |
5832 gimple_bb (stmt)->index); | |
5833 if (dump_file && (dump_flags & TDF_DETAILS)) | |
5834 fprintf (dump_file, " Removed EH side-effects.\n"); | |
5835 } | |
5836 /* Likewise for AB side-effects. */ | |
5837 if (can_make_abnormal_goto | |
5838 && !stmt_can_make_abnormal_goto (stmt)) | |
5839 { | |
5840 bitmap_set_bit (need_ab_cleanup, | |
5841 gimple_bb (stmt)->index); | |
5842 if (dump_file && (dump_flags & TDF_DETAILS)) | |
5843 fprintf (dump_file, " Removed AB side-effects.\n"); | |
5844 } | |
5845 update_stmt (stmt); | |
5846 if (vdef != gimple_vdef (stmt)) | |
5847 VN_INFO (vdef)->valnum = vuse; | |
5848 } | |
5849 | |
5850 /* Make new values available - for fully redundant LHS we | |
5851 continue with the next stmt above and skip this. */ | |
5852 def_operand_p defp; | |
5853 FOR_EACH_SSA_DEF_OPERAND (defp, stmt, iter, SSA_OP_DEF) | |
5854 eliminate_push_avail (DEF_FROM_PTR (defp)); | |
5855 } | |
5856 | 5362 |
5857 /* Replace destination PHI arguments. */ | 5363 /* Replace destination PHI arguments. */ |
5364 edge_iterator ei; | |
5365 edge e; | |
5858 FOR_EACH_EDGE (e, ei, b->succs) | 5366 FOR_EACH_EDGE (e, ei, b->succs) |
5859 if (e->flags & EDGE_EXECUTABLE) | 5367 if (e->flags & EDGE_EXECUTABLE) |
5860 for (gphi_iterator gsi = gsi_start_phis (e->dest); | 5368 for (gphi_iterator gsi = gsi_start_phis (e->dest); |
5861 !gsi_end_p (gsi); | 5369 !gsi_end_p (gsi); |
5862 gsi_next (&gsi)) | 5370 gsi_next (&gsi)) |
5865 use_operand_p use_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, e); | 5373 use_operand_p use_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, e); |
5866 tree arg = USE_FROM_PTR (use_p); | 5374 tree arg = USE_FROM_PTR (use_p); |
5867 if (TREE_CODE (arg) != SSA_NAME | 5375 if (TREE_CODE (arg) != SSA_NAME |
5868 || virtual_operand_p (arg)) | 5376 || virtual_operand_p (arg)) |
5869 continue; | 5377 continue; |
5870 tree sprime = eliminate_avail (arg); | 5378 tree sprime = eliminate_avail (b, arg); |
5871 if (sprime && may_propagate_copy (arg, sprime)) | 5379 if (sprime && may_propagate_copy (arg, sprime)) |
5872 propagate_value (use_p, sprime); | 5380 propagate_value (use_p, sprime); |
5873 } | 5381 } |
5382 | |
5383 vn_context_bb = NULL; | |
5384 | |
5874 return NULL; | 5385 return NULL; |
5875 } | 5386 } |
5876 | 5387 |
5877 /* Make no longer available leaders no longer available. */ | 5388 /* Make no longer available leaders no longer available. */ |
5878 | 5389 |
5889 else | 5400 else |
5890 avail[SSA_NAME_VERSION (valnum)] = entry; | 5401 avail[SSA_NAME_VERSION (valnum)] = entry; |
5891 } | 5402 } |
5892 } | 5403 } |
5893 | 5404 |
5894 /* Eliminate fully redundant computations. */ | 5405 /* Remove queued stmts and perform delayed cleanups. */ |
5895 | 5406 |
5896 unsigned int | 5407 unsigned |
5897 vn_eliminate (bitmap inserted_exprs) | 5408 eliminate_dom_walker::eliminate_cleanup (bool region_p) |
5898 { | 5409 { |
5899 eliminate_dom_walker el (CDI_DOMINATORS, inserted_exprs); | 5410 statistics_counter_event (cfun, "Eliminated", eliminations); |
5900 el.avail.reserve (num_ssa_names); | 5411 statistics_counter_event (cfun, "Insertions", insertions); |
5901 | |
5902 el.walk (cfun->cfg->x_entry_block_ptr); | |
5903 | 5412 |
5904 /* We cannot remove stmts during BB walk, especially not release SSA | 5413 /* We cannot remove stmts during BB walk, especially not release SSA |
5905 names there as this confuses the VN machinery. The stmts ending | 5414 names there as this confuses the VN machinery. The stmts ending |
5906 up in to_remove are either stores or simple copies. | 5415 up in to_remove are either stores or simple copies. |
5907 Remove stmts in reverse order to make debug stmt creation possible. */ | 5416 Remove stmts in reverse order to make debug stmt creation possible. */ |
5908 while (!el.to_remove.is_empty ()) | 5417 while (!to_remove.is_empty ()) |
5909 { | 5418 { |
5910 gimple *stmt = el.to_remove.pop (); | 5419 bool do_release_defs = true; |
5420 gimple *stmt = to_remove.pop (); | |
5421 | |
5422 /* When we are value-numbering a region we do not require exit PHIs to | |
5423 be present so we have to make sure to deal with uses outside of the | |
5424 region of stmts that we thought are eliminated. | |
5425 ??? Note we may be confused by uses in dead regions we didn't run | |
5426 elimination on. Rather than checking individual uses we accept | |
5427 dead copies to be generated here (gcc.c-torture/execute/20060905-1.c | |
5428 contains such example). */ | |
5429 if (region_p) | |
5430 { | |
5431 if (gphi *phi = dyn_cast <gphi *> (stmt)) | |
5432 { | |
5433 tree lhs = gimple_phi_result (phi); | |
5434 if (!has_zero_uses (lhs)) | |
5435 { | |
5436 if (dump_file && (dump_flags & TDF_DETAILS)) | |
5437 fprintf (dump_file, "Keeping eliminated stmt live " | |
5438 "as copy because of out-of-region uses\n"); | |
5439 tree sprime = eliminate_avail (gimple_bb (stmt), lhs); | |
5440 gimple *copy = gimple_build_assign (lhs, sprime); | |
5441 gimple_stmt_iterator gsi | |
5442 = gsi_after_labels (gimple_bb (stmt)); | |
5443 gsi_insert_before (&gsi, copy, GSI_SAME_STMT); | |
5444 do_release_defs = false; | |
5445 } | |
5446 } | |
5447 else if (tree lhs = gimple_get_lhs (stmt)) | |
5448 if (TREE_CODE (lhs) == SSA_NAME | |
5449 && !has_zero_uses (lhs)) | |
5450 { | |
5451 if (dump_file && (dump_flags & TDF_DETAILS)) | |
5452 fprintf (dump_file, "Keeping eliminated stmt live " | |
5453 "as copy because of out-of-region uses\n"); | |
5454 tree sprime = eliminate_avail (gimple_bb (stmt), lhs); | |
5455 gimple_stmt_iterator gsi = gsi_for_stmt (stmt); | |
5456 if (is_gimple_assign (stmt)) | |
5457 { | |
5458 gimple_assign_set_rhs_from_tree (&gsi, sprime); | |
5459 stmt = gsi_stmt (gsi); | |
5460 update_stmt (stmt); | |
5461 if (maybe_clean_or_replace_eh_stmt (stmt, stmt)) | |
5462 bitmap_set_bit (need_eh_cleanup, gimple_bb (stmt)->index); | |
5463 continue; | |
5464 } | |
5465 else | |
5466 { | |
5467 gimple *copy = gimple_build_assign (lhs, sprime); | |
5468 gsi_insert_before (&gsi, copy, GSI_SAME_STMT); | |
5469 do_release_defs = false; | |
5470 } | |
5471 } | |
5472 } | |
5911 | 5473 |
5912 if (dump_file && (dump_flags & TDF_DETAILS)) | 5474 if (dump_file && (dump_flags & TDF_DETAILS)) |
5913 { | 5475 { |
5914 fprintf (dump_file, "Removing dead stmt "); | 5476 fprintf (dump_file, "Removing dead stmt "); |
5915 print_gimple_stmt (dump_file, stmt, 0, 0); | 5477 print_gimple_stmt (dump_file, stmt, 0, TDF_NONE); |
5916 } | 5478 } |
5917 | 5479 |
5918 gimple_stmt_iterator gsi = gsi_for_stmt (stmt); | 5480 gimple_stmt_iterator gsi = gsi_for_stmt (stmt); |
5919 if (gimple_code (stmt) == GIMPLE_PHI) | 5481 if (gimple_code (stmt) == GIMPLE_PHI) |
5920 remove_phi_node (&gsi, true); | 5482 remove_phi_node (&gsi, do_release_defs); |
5921 else | 5483 else |
5922 { | 5484 { |
5923 basic_block bb = gimple_bb (stmt); | 5485 basic_block bb = gimple_bb (stmt); |
5924 unlink_stmt_vdef (stmt); | 5486 unlink_stmt_vdef (stmt); |
5925 if (gsi_remove (&gsi, true)) | 5487 if (gsi_remove (&gsi, true)) |
5926 bitmap_set_bit (el.need_eh_cleanup, bb->index); | 5488 bitmap_set_bit (need_eh_cleanup, bb->index); |
5927 if (is_gimple_call (stmt) && stmt_can_make_abnormal_goto (stmt)) | 5489 if (is_gimple_call (stmt) && stmt_can_make_abnormal_goto (stmt)) |
5928 bitmap_set_bit (el.need_ab_cleanup, bb->index); | 5490 bitmap_set_bit (need_ab_cleanup, bb->index); |
5929 release_defs (stmt); | 5491 if (do_release_defs) |
5492 release_defs (stmt); | |
5930 } | 5493 } |
5931 | 5494 |
5932 /* Removing a stmt may expose a forwarder block. */ | 5495 /* Removing a stmt may expose a forwarder block. */ |
5933 el.el_todo |= TODO_cleanup_cfg; | 5496 el_todo |= TODO_cleanup_cfg; |
5934 } | 5497 } |
5935 | 5498 |
5936 /* Fixup stmts that became noreturn calls. This may require splitting | 5499 /* Fixup stmts that became noreturn calls. This may require splitting |
5937 blocks and thus isn't possible during the dominator walk. Do this | 5500 blocks and thus isn't possible during the dominator walk. Do this |
5938 in reverse order so we don't inadvertedly remove a stmt we want to | 5501 in reverse order so we don't inadvertedly remove a stmt we want to |
5939 fixup by visiting a dominating now noreturn call first. */ | 5502 fixup by visiting a dominating now noreturn call first. */ |
5940 while (!el.to_fixup.is_empty ()) | 5503 while (!to_fixup.is_empty ()) |
5941 { | 5504 { |
5942 gimple *stmt = el.to_fixup.pop (); | 5505 gimple *stmt = to_fixup.pop (); |
5943 | 5506 |
5944 if (dump_file && (dump_flags & TDF_DETAILS)) | 5507 if (dump_file && (dump_flags & TDF_DETAILS)) |
5945 { | 5508 { |
5946 fprintf (dump_file, "Fixing up noreturn call "); | 5509 fprintf (dump_file, "Fixing up noreturn call "); |
5947 print_gimple_stmt (dump_file, stmt, 0); | 5510 print_gimple_stmt (dump_file, stmt, 0); |
5948 } | 5511 } |
5949 | 5512 |
5950 if (fixup_noreturn_call (stmt)) | 5513 if (fixup_noreturn_call (stmt)) |
5951 el.el_todo |= TODO_cleanup_cfg; | 5514 el_todo |= TODO_cleanup_cfg; |
5952 } | 5515 } |
5953 | 5516 |
5954 bool do_eh_cleanup = !bitmap_empty_p (el.need_eh_cleanup); | 5517 bool do_eh_cleanup = !bitmap_empty_p (need_eh_cleanup); |
5955 bool do_ab_cleanup = !bitmap_empty_p (el.need_ab_cleanup); | 5518 bool do_ab_cleanup = !bitmap_empty_p (need_ab_cleanup); |
5956 | 5519 |
5957 if (do_eh_cleanup) | 5520 if (do_eh_cleanup) |
5958 gimple_purge_all_dead_eh_edges (el.need_eh_cleanup); | 5521 gimple_purge_all_dead_eh_edges (need_eh_cleanup); |
5959 | 5522 |
5960 if (do_ab_cleanup) | 5523 if (do_ab_cleanup) |
5961 gimple_purge_all_dead_abnormal_call_edges (el.need_ab_cleanup); | 5524 gimple_purge_all_dead_abnormal_call_edges (need_ab_cleanup); |
5962 | 5525 |
5963 if (do_eh_cleanup || do_ab_cleanup) | 5526 if (do_eh_cleanup || do_ab_cleanup) |
5964 el.el_todo |= TODO_cleanup_cfg; | 5527 el_todo |= TODO_cleanup_cfg; |
5965 | 5528 |
5966 statistics_counter_event (cfun, "Eliminated", el.eliminations); | 5529 return el_todo; |
5967 statistics_counter_event (cfun, "Insertions", el.insertions); | 5530 } |
5968 | 5531 |
5969 return el.el_todo; | 5532 /* Eliminate fully redundant computations. */ |
5533 | |
5534 unsigned | |
5535 eliminate_with_rpo_vn (bitmap inserted_exprs) | |
5536 { | |
5537 eliminate_dom_walker walker (CDI_DOMINATORS, inserted_exprs); | |
5538 | |
5539 walker.walk (cfun->cfg->x_entry_block_ptr); | |
5540 return walker.eliminate_cleanup (); | |
5541 } | |
5542 | |
5543 static unsigned | |
5544 do_rpo_vn (function *fn, edge entry, bitmap exit_bbs, | |
5545 bool iterate, bool eliminate); | |
5546 | |
5547 void | |
5548 run_rpo_vn (vn_lookup_kind kind) | |
5549 { | |
5550 default_vn_walk_kind = kind; | |
5551 do_rpo_vn (cfun, NULL, NULL, true, false); | |
5552 | |
5553 /* ??? Prune requirement of these. */ | |
5554 constant_to_value_id = new hash_table<vn_constant_hasher> (23); | |
5555 constant_value_ids = BITMAP_ALLOC (NULL); | |
5556 | |
5557 /* Initialize the value ids and prune out remaining VN_TOPs | |
5558 from dead code. */ | |
5559 tree name; | |
5560 unsigned i; | |
5561 FOR_EACH_SSA_NAME (i, name, cfun) | |
5562 { | |
5563 vn_ssa_aux_t info = VN_INFO (name); | |
5564 if (!info->visited | |
5565 || info->valnum == VN_TOP) | |
5566 info->valnum = name; | |
5567 if (info->valnum == name) | |
5568 info->value_id = get_next_value_id (); | |
5569 else if (is_gimple_min_invariant (info->valnum)) | |
5570 info->value_id = get_or_alloc_constant_value_id (info->valnum); | |
5571 } | |
5572 | |
5573 /* Propagate. */ | |
5574 FOR_EACH_SSA_NAME (i, name, cfun) | |
5575 { | |
5576 vn_ssa_aux_t info = VN_INFO (name); | |
5577 if (TREE_CODE (info->valnum) == SSA_NAME | |
5578 && info->valnum != name | |
5579 && info->value_id != VN_INFO (info->valnum)->value_id) | |
5580 info->value_id = VN_INFO (info->valnum)->value_id; | |
5581 } | |
5582 | |
5583 set_hashtable_value_ids (); | |
5584 | |
5585 if (dump_file && (dump_flags & TDF_DETAILS)) | |
5586 { | |
5587 fprintf (dump_file, "Value numbers:\n"); | |
5588 FOR_EACH_SSA_NAME (i, name, cfun) | |
5589 { | |
5590 if (VN_INFO (name)->visited | |
5591 && SSA_VAL (name) != name) | |
5592 { | |
5593 print_generic_expr (dump_file, name); | |
5594 fprintf (dump_file, " = "); | |
5595 print_generic_expr (dump_file, SSA_VAL (name)); | |
5596 fprintf (dump_file, " (%04d)\n", VN_INFO (name)->value_id); | |
5597 } | |
5598 } | |
5599 } | |
5600 } | |
5601 | |
5602 /* Free VN associated data structures. */ | |
5603 | |
5604 void | |
5605 free_rpo_vn (void) | |
5606 { | |
5607 free_vn_table (valid_info); | |
5608 XDELETE (valid_info); | |
5609 obstack_free (&vn_tables_obstack, NULL); | |
5610 obstack_free (&vn_tables_insert_obstack, NULL); | |
5611 | |
5612 vn_ssa_aux_iterator_type it; | |
5613 vn_ssa_aux_t info; | |
5614 FOR_EACH_HASH_TABLE_ELEMENT (*vn_ssa_aux_hash, info, vn_ssa_aux_t, it) | |
5615 if (info->needs_insertion) | |
5616 release_ssa_name (info->name); | |
5617 obstack_free (&vn_ssa_aux_obstack, NULL); | |
5618 delete vn_ssa_aux_hash; | |
5619 | |
5620 delete constant_to_value_id; | |
5621 constant_to_value_id = NULL; | |
5622 BITMAP_FREE (constant_value_ids); | |
5623 } | |
5624 | |
5625 /* Adaptor to the elimination engine using RPO availability. */ | |
5626 | |
5627 class rpo_elim : public eliminate_dom_walker | |
5628 { | |
5629 public: | |
5630 rpo_elim(basic_block entry_) | |
5631 : eliminate_dom_walker (CDI_DOMINATORS, NULL), entry (entry_) {} | |
5632 ~rpo_elim(); | |
5633 | |
5634 virtual tree eliminate_avail (basic_block, tree op); | |
5635 | |
5636 virtual void eliminate_push_avail (basic_block, tree); | |
5637 | |
5638 basic_block entry; | |
5639 /* Instead of having a local availability lattice for each | |
5640 basic-block and availability at X defined as union of | |
5641 the local availabilities at X and its dominators we're | |
5642 turning this upside down and track availability per | |
5643 value given values are usually made available at very | |
5644 few points (at least one). | |
5645 So we have a value -> vec<location, leader> map where | |
5646 LOCATION is specifying the basic-block LEADER is made | |
5647 available for VALUE. We push to this vector in RPO | |
5648 order thus for iteration we can simply pop the last | |
5649 entries. | |
5650 LOCATION is the basic-block index and LEADER is its | |
5651 SSA name version. */ | |
5652 /* ??? We'd like to use auto_vec here with embedded storage | |
5653 but that doesn't play well until we can provide move | |
5654 constructors and use std::move on hash-table expansion. | |
5655 So for now this is a bit more expensive than necessary. | |
5656 We eventually want to switch to a chaining scheme like | |
5657 for hashtable entries for unwinding which would make | |
5658 making the vector part of the vn_ssa_aux structure possible. */ | |
5659 typedef hash_map<tree, vec<std::pair<int, int> > > rpo_avail_t; | |
5660 rpo_avail_t m_rpo_avail; | |
5661 }; | |
5662 | |
5663 /* Global RPO state for access from hooks. */ | |
5664 static rpo_elim *rpo_avail; | |
5665 | |
5666 /* Hook for maybe_push_res_to_seq, lookup the expression in the VN tables. */ | |
5667 | |
5668 static tree | |
5669 vn_lookup_simplify_result (gimple_match_op *res_op) | |
5670 { | |
5671 if (!res_op->code.is_tree_code ()) | |
5672 return NULL_TREE; | |
5673 tree *ops = res_op->ops; | |
5674 unsigned int length = res_op->num_ops; | |
5675 if (res_op->code == CONSTRUCTOR | |
5676 /* ??? We're arriving here with SCCVNs view, decomposed CONSTRUCTOR | |
5677 and GIMPLEs / match-and-simplifies, CONSTRUCTOR as GENERIC tree. */ | |
5678 && TREE_CODE (res_op->ops[0]) == CONSTRUCTOR) | |
5679 { | |
5680 length = CONSTRUCTOR_NELTS (res_op->ops[0]); | |
5681 ops = XALLOCAVEC (tree, length); | |
5682 for (unsigned i = 0; i < length; ++i) | |
5683 ops[i] = CONSTRUCTOR_ELT (res_op->ops[0], i)->value; | |
5684 } | |
5685 vn_nary_op_t vnresult = NULL; | |
5686 tree res = vn_nary_op_lookup_pieces (length, (tree_code) res_op->code, | |
5687 res_op->type, ops, &vnresult); | |
5688 /* If this is used from expression simplification make sure to | |
5689 return an available expression. */ | |
5690 if (res && TREE_CODE (res) == SSA_NAME && mprts_hook && rpo_avail) | |
5691 res = rpo_avail->eliminate_avail (vn_context_bb, res); | |
5692 return res; | |
5693 } | |
5694 | |
5695 rpo_elim::~rpo_elim () | |
5696 { | |
5697 /* Release the avail vectors. */ | |
5698 for (rpo_avail_t::iterator i = m_rpo_avail.begin (); | |
5699 i != m_rpo_avail.end (); ++i) | |
5700 (*i).second.release (); | |
5701 } | |
5702 | |
5703 /* Return a leader for OPs value that is valid at BB. */ | |
5704 | |
5705 tree | |
5706 rpo_elim::eliminate_avail (basic_block bb, tree op) | |
5707 { | |
5708 bool visited; | |
5709 tree valnum = SSA_VAL (op, &visited); | |
5710 /* If we didn't visit OP then it must be defined outside of the | |
5711 region we process and also dominate it. So it is available. */ | |
5712 if (!visited) | |
5713 return op; | |
5714 if (TREE_CODE (valnum) == SSA_NAME) | |
5715 { | |
5716 if (SSA_NAME_IS_DEFAULT_DEF (valnum)) | |
5717 return valnum; | |
5718 vec<std::pair<int, int> > *av = m_rpo_avail.get (valnum); | |
5719 if (!av || av->is_empty ()) | |
5720 return NULL_TREE; | |
5721 int i = av->length () - 1; | |
5722 if ((*av)[i].first == bb->index) | |
5723 /* On tramp3d 90% of the cases are here. */ | |
5724 return ssa_name ((*av)[i].second); | |
5725 do | |
5726 { | |
5727 basic_block abb = BASIC_BLOCK_FOR_FN (cfun, (*av)[i].first); | |
5728 /* ??? During elimination we have to use availability at the | |
5729 definition site of a use we try to replace. This | |
5730 is required to not run into inconsistencies because | |
5731 of dominated_by_p_w_unex behavior and removing a definition | |
5732 while not replacing all uses. | |
5733 ??? We could try to consistently walk dominators | |
5734 ignoring non-executable regions. The nearest common | |
5735 dominator of bb and abb is where we can stop walking. We | |
5736 may also be able to "pre-compute" (bits of) the next immediate | |
5737 (non-)dominator during the RPO walk when marking edges as | |
5738 executable. */ | |
5739 if (dominated_by_p_w_unex (bb, abb)) | |
5740 { | |
5741 tree leader = ssa_name ((*av)[i].second); | |
5742 /* Prevent eliminations that break loop-closed SSA. */ | |
5743 if (loops_state_satisfies_p (LOOP_CLOSED_SSA) | |
5744 && ! SSA_NAME_IS_DEFAULT_DEF (leader) | |
5745 && ! flow_bb_inside_loop_p (gimple_bb (SSA_NAME_DEF_STMT | |
5746 (leader))->loop_father, | |
5747 bb)) | |
5748 return NULL_TREE; | |
5749 if (dump_file && (dump_flags & TDF_DETAILS)) | |
5750 { | |
5751 print_generic_expr (dump_file, leader); | |
5752 fprintf (dump_file, " is available for "); | |
5753 print_generic_expr (dump_file, valnum); | |
5754 fprintf (dump_file, "\n"); | |
5755 } | |
5756 /* On tramp3d 99% of the _remaining_ cases succeed at | |
5757 the first enty. */ | |
5758 return leader; | |
5759 } | |
5760 /* ??? Can we somehow skip to the immediate dominator | |
5761 RPO index (bb_to_rpo)? Again, maybe not worth, on | |
5762 tramp3d the worst number of elements in the vector is 9. */ | |
5763 } | |
5764 while (--i >= 0); | |
5765 } | |
5766 else if (valnum != VN_TOP) | |
5767 /* valnum is is_gimple_min_invariant. */ | |
5768 return valnum; | |
5769 return NULL_TREE; | |
5770 } | |
5771 | |
5772 /* Make LEADER a leader for its value at BB. */ | |
5773 | |
5774 void | |
5775 rpo_elim::eliminate_push_avail (basic_block bb, tree leader) | |
5776 { | |
5777 tree valnum = VN_INFO (leader)->valnum; | |
5778 if (valnum == VN_TOP) | |
5779 return; | |
5780 if (dump_file && (dump_flags & TDF_DETAILS)) | |
5781 { | |
5782 fprintf (dump_file, "Making available beyond BB%d ", bb->index); | |
5783 print_generic_expr (dump_file, leader); | |
5784 fprintf (dump_file, " for value "); | |
5785 print_generic_expr (dump_file, valnum); | |
5786 fprintf (dump_file, "\n"); | |
5787 } | |
5788 bool existed; | |
5789 vec<std::pair<int, int> > &av = m_rpo_avail.get_or_insert (valnum, &existed); | |
5790 if (!existed) | |
5791 { | |
5792 new (&av) vec<std::pair<int, int> >; | |
5793 av = vNULL; | |
5794 av.reserve_exact (2); | |
5795 } | |
5796 av.safe_push (std::make_pair (bb->index, SSA_NAME_VERSION (leader))); | |
5797 } | |
5798 | |
5799 /* Valueization hook for RPO VN plus required state. */ | |
5800 | |
5801 tree | |
5802 rpo_vn_valueize (tree name) | |
5803 { | |
5804 if (TREE_CODE (name) == SSA_NAME) | |
5805 { | |
5806 vn_ssa_aux_t val = VN_INFO (name); | |
5807 if (val) | |
5808 { | |
5809 tree tem = val->valnum; | |
5810 if (tem != VN_TOP && tem != name) | |
5811 { | |
5812 if (TREE_CODE (tem) != SSA_NAME) | |
5813 return tem; | |
5814 /* For all values we only valueize to an available leader | |
5815 which means we can use SSA name info without restriction. */ | |
5816 tem = rpo_avail->eliminate_avail (vn_context_bb, tem); | |
5817 if (tem) | |
5818 return tem; | |
5819 } | |
5820 } | |
5821 } | |
5822 return name; | |
5823 } | |
5824 | |
5825 /* Insert on PRED_E predicates derived from CODE OPS being true besides the | |
5826 inverted condition. */ | |
5827 | |
5828 static void | |
5829 insert_related_predicates_on_edge (enum tree_code code, tree *ops, edge pred_e) | |
5830 { | |
5831 switch (code) | |
5832 { | |
5833 case LT_EXPR: | |
5834 /* a < b -> a {!,<}= b */ | |
5835 vn_nary_op_insert_pieces_predicated (2, NE_EXPR, boolean_type_node, | |
5836 ops, boolean_true_node, 0, pred_e); | |
5837 vn_nary_op_insert_pieces_predicated (2, LE_EXPR, boolean_type_node, | |
5838 ops, boolean_true_node, 0, pred_e); | |
5839 /* a < b -> ! a {>,=} b */ | |
5840 vn_nary_op_insert_pieces_predicated (2, GT_EXPR, boolean_type_node, | |
5841 ops, boolean_false_node, 0, pred_e); | |
5842 vn_nary_op_insert_pieces_predicated (2, EQ_EXPR, boolean_type_node, | |
5843 ops, boolean_false_node, 0, pred_e); | |
5844 break; | |
5845 case GT_EXPR: | |
5846 /* a > b -> a {!,>}= b */ | |
5847 vn_nary_op_insert_pieces_predicated (2, NE_EXPR, boolean_type_node, | |
5848 ops, boolean_true_node, 0, pred_e); | |
5849 vn_nary_op_insert_pieces_predicated (2, GE_EXPR, boolean_type_node, | |
5850 ops, boolean_true_node, 0, pred_e); | |
5851 /* a > b -> ! a {<,=} b */ | |
5852 vn_nary_op_insert_pieces_predicated (2, LT_EXPR, boolean_type_node, | |
5853 ops, boolean_false_node, 0, pred_e); | |
5854 vn_nary_op_insert_pieces_predicated (2, EQ_EXPR, boolean_type_node, | |
5855 ops, boolean_false_node, 0, pred_e); | |
5856 break; | |
5857 case EQ_EXPR: | |
5858 /* a == b -> ! a {<,>} b */ | |
5859 vn_nary_op_insert_pieces_predicated (2, LT_EXPR, boolean_type_node, | |
5860 ops, boolean_false_node, 0, pred_e); | |
5861 vn_nary_op_insert_pieces_predicated (2, GT_EXPR, boolean_type_node, | |
5862 ops, boolean_false_node, 0, pred_e); | |
5863 break; | |
5864 case LE_EXPR: | |
5865 case GE_EXPR: | |
5866 case NE_EXPR: | |
5867 /* Nothing besides inverted condition. */ | |
5868 break; | |
5869 default:; | |
5870 } | |
5871 } | |
5872 | |
5873 /* Main stmt worker for RPO VN, process BB. */ | |
5874 | |
5875 static unsigned | |
5876 process_bb (rpo_elim &avail, basic_block bb, | |
5877 bool bb_visited, bool iterate_phis, bool iterate, bool eliminate, | |
5878 bool do_region, bitmap exit_bbs) | |
5879 { | |
5880 unsigned todo = 0; | |
5881 edge_iterator ei; | |
5882 edge e; | |
5883 | |
5884 vn_context_bb = bb; | |
5885 | |
5886 /* If we are in loop-closed SSA preserve this state. This is | |
5887 relevant when called on regions from outside of FRE/PRE. */ | |
5888 bool lc_phi_nodes = false; | |
5889 if (loops_state_satisfies_p (LOOP_CLOSED_SSA)) | |
5890 FOR_EACH_EDGE (e, ei, bb->preds) | |
5891 if (e->src->loop_father != e->dest->loop_father | |
5892 && flow_loop_nested_p (e->dest->loop_father, | |
5893 e->src->loop_father)) | |
5894 { | |
5895 lc_phi_nodes = true; | |
5896 break; | |
5897 } | |
5898 | |
5899 /* Value-number all defs in the basic-block. */ | |
5900 for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi); | |
5901 gsi_next (&gsi)) | |
5902 { | |
5903 gphi *phi = gsi.phi (); | |
5904 tree res = PHI_RESULT (phi); | |
5905 vn_ssa_aux_t res_info = VN_INFO (res); | |
5906 if (!bb_visited) | |
5907 { | |
5908 gcc_assert (!res_info->visited); | |
5909 res_info->valnum = VN_TOP; | |
5910 res_info->visited = true; | |
5911 } | |
5912 | |
5913 /* When not iterating force backedge values to varying. */ | |
5914 visit_stmt (phi, !iterate_phis); | |
5915 if (virtual_operand_p (res)) | |
5916 continue; | |
5917 | |
5918 /* Eliminate */ | |
5919 /* The interesting case is gcc.dg/tree-ssa/pr22230.c for correctness | |
5920 how we handle backedges and availability. | |
5921 And gcc.dg/tree-ssa/ssa-sccvn-2.c for optimization. */ | |
5922 tree val = res_info->valnum; | |
5923 if (res != val && !iterate && eliminate) | |
5924 { | |
5925 if (tree leader = avail.eliminate_avail (bb, res)) | |
5926 { | |
5927 if (leader != res | |
5928 /* Preserve loop-closed SSA form. */ | |
5929 && (! lc_phi_nodes | |
5930 || is_gimple_min_invariant (leader))) | |
5931 { | |
5932 if (dump_file && (dump_flags & TDF_DETAILS)) | |
5933 { | |
5934 fprintf (dump_file, "Replaced redundant PHI node " | |
5935 "defining "); | |
5936 print_generic_expr (dump_file, res); | |
5937 fprintf (dump_file, " with "); | |
5938 print_generic_expr (dump_file, leader); | |
5939 fprintf (dump_file, "\n"); | |
5940 } | |
5941 avail.eliminations++; | |
5942 | |
5943 if (may_propagate_copy (res, leader)) | |
5944 { | |
5945 /* Schedule for removal. */ | |
5946 avail.to_remove.safe_push (phi); | |
5947 continue; | |
5948 } | |
5949 /* ??? Else generate a copy stmt. */ | |
5950 } | |
5951 } | |
5952 } | |
5953 /* Only make defs available that not already are. But make | |
5954 sure loop-closed SSA PHI node defs are picked up for | |
5955 downstream uses. */ | |
5956 if (lc_phi_nodes | |
5957 || res == val | |
5958 || ! avail.eliminate_avail (bb, res)) | |
5959 avail.eliminate_push_avail (bb, res); | |
5960 } | |
5961 | |
5962 /* For empty BBs mark outgoing edges executable. For non-empty BBs | |
5963 we do this when processing the last stmt as we have to do this | |
5964 before elimination which otherwise forces GIMPLE_CONDs to | |
5965 if (1 != 0) style when seeing non-executable edges. */ | |
5966 if (gsi_end_p (gsi_start_bb (bb))) | |
5967 { | |
5968 FOR_EACH_EDGE (e, ei, bb->succs) | |
5969 { | |
5970 if (!(e->flags & EDGE_EXECUTABLE)) | |
5971 { | |
5972 if (dump_file && (dump_flags & TDF_DETAILS)) | |
5973 fprintf (dump_file, | |
5974 "marking outgoing edge %d -> %d executable\n", | |
5975 e->src->index, e->dest->index); | |
5976 e->flags |= EDGE_EXECUTABLE; | |
5977 e->dest->flags |= BB_EXECUTABLE; | |
5978 } | |
5979 else if (!(e->dest->flags & BB_EXECUTABLE)) | |
5980 { | |
5981 if (dump_file && (dump_flags & TDF_DETAILS)) | |
5982 fprintf (dump_file, | |
5983 "marking destination block %d reachable\n", | |
5984 e->dest->index); | |
5985 e->dest->flags |= BB_EXECUTABLE; | |
5986 } | |
5987 } | |
5988 } | |
5989 for (gimple_stmt_iterator gsi = gsi_start_bb (bb); | |
5990 !gsi_end_p (gsi); gsi_next (&gsi)) | |
5991 { | |
5992 ssa_op_iter i; | |
5993 tree op; | |
5994 if (!bb_visited) | |
5995 { | |
5996 FOR_EACH_SSA_TREE_OPERAND (op, gsi_stmt (gsi), i, SSA_OP_ALL_DEFS) | |
5997 { | |
5998 vn_ssa_aux_t op_info = VN_INFO (op); | |
5999 gcc_assert (!op_info->visited); | |
6000 op_info->valnum = VN_TOP; | |
6001 op_info->visited = true; | |
6002 } | |
6003 | |
6004 /* We somehow have to deal with uses that are not defined | |
6005 in the processed region. Forcing unvisited uses to | |
6006 varying here doesn't play well with def-use following during | |
6007 expression simplification, so we deal with this by checking | |
6008 the visited flag in SSA_VAL. */ | |
6009 } | |
6010 | |
6011 visit_stmt (gsi_stmt (gsi)); | |
6012 | |
6013 gimple *last = gsi_stmt (gsi); | |
6014 e = NULL; | |
6015 switch (gimple_code (last)) | |
6016 { | |
6017 case GIMPLE_SWITCH: | |
6018 e = find_taken_edge (bb, vn_valueize (gimple_switch_index | |
6019 (as_a <gswitch *> (last)))); | |
6020 break; | |
6021 case GIMPLE_COND: | |
6022 { | |
6023 tree lhs = vn_valueize (gimple_cond_lhs (last)); | |
6024 tree rhs = vn_valueize (gimple_cond_rhs (last)); | |
6025 tree val = gimple_simplify (gimple_cond_code (last), | |
6026 boolean_type_node, lhs, rhs, | |
6027 NULL, vn_valueize); | |
6028 /* If the condition didn't simplfy see if we have recorded | |
6029 an expression from sofar taken edges. */ | |
6030 if (! val || TREE_CODE (val) != INTEGER_CST) | |
6031 { | |
6032 vn_nary_op_t vnresult; | |
6033 tree ops[2]; | |
6034 ops[0] = lhs; | |
6035 ops[1] = rhs; | |
6036 val = vn_nary_op_lookup_pieces (2, gimple_cond_code (last), | |
6037 boolean_type_node, ops, | |
6038 &vnresult); | |
6039 /* Did we get a predicated value? */ | |
6040 if (! val && vnresult && vnresult->predicated_values) | |
6041 { | |
6042 val = vn_nary_op_get_predicated_value (vnresult, bb); | |
6043 if (val && dump_file && (dump_flags & TDF_DETAILS)) | |
6044 { | |
6045 fprintf (dump_file, "Got predicated value "); | |
6046 print_generic_expr (dump_file, val, TDF_NONE); | |
6047 fprintf (dump_file, " for "); | |
6048 print_gimple_stmt (dump_file, last, TDF_SLIM); | |
6049 } | |
6050 } | |
6051 } | |
6052 if (val) | |
6053 e = find_taken_edge (bb, val); | |
6054 if (! e) | |
6055 { | |
6056 /* If we didn't manage to compute the taken edge then | |
6057 push predicated expressions for the condition itself | |
6058 and related conditions to the hashtables. This allows | |
6059 simplification of redundant conditions which is | |
6060 important as early cleanup. */ | |
6061 edge true_e, false_e; | |
6062 extract_true_false_edges_from_block (bb, &true_e, &false_e); | |
6063 enum tree_code code = gimple_cond_code (last); | |
6064 enum tree_code icode | |
6065 = invert_tree_comparison (code, HONOR_NANS (lhs)); | |
6066 tree ops[2]; | |
6067 ops[0] = lhs; | |
6068 ops[1] = rhs; | |
6069 if (do_region | |
6070 && bitmap_bit_p (exit_bbs, true_e->dest->index)) | |
6071 true_e = NULL; | |
6072 if (do_region | |
6073 && bitmap_bit_p (exit_bbs, false_e->dest->index)) | |
6074 false_e = NULL; | |
6075 if (true_e) | |
6076 vn_nary_op_insert_pieces_predicated | |
6077 (2, code, boolean_type_node, ops, | |
6078 boolean_true_node, 0, true_e); | |
6079 if (false_e) | |
6080 vn_nary_op_insert_pieces_predicated | |
6081 (2, code, boolean_type_node, ops, | |
6082 boolean_false_node, 0, false_e); | |
6083 if (icode != ERROR_MARK) | |
6084 { | |
6085 if (true_e) | |
6086 vn_nary_op_insert_pieces_predicated | |
6087 (2, icode, boolean_type_node, ops, | |
6088 boolean_false_node, 0, true_e); | |
6089 if (false_e) | |
6090 vn_nary_op_insert_pieces_predicated | |
6091 (2, icode, boolean_type_node, ops, | |
6092 boolean_true_node, 0, false_e); | |
6093 } | |
6094 /* Relax for non-integers, inverted condition handled | |
6095 above. */ | |
6096 if (INTEGRAL_TYPE_P (TREE_TYPE (lhs))) | |
6097 { | |
6098 if (true_e) | |
6099 insert_related_predicates_on_edge (code, ops, true_e); | |
6100 if (false_e) | |
6101 insert_related_predicates_on_edge (icode, ops, false_e); | |
6102 } | |
6103 } | |
6104 break; | |
6105 } | |
6106 case GIMPLE_GOTO: | |
6107 e = find_taken_edge (bb, vn_valueize (gimple_goto_dest (last))); | |
6108 break; | |
6109 default: | |
6110 e = NULL; | |
6111 } | |
6112 if (e) | |
6113 { | |
6114 todo = TODO_cleanup_cfg; | |
6115 if (!(e->flags & EDGE_EXECUTABLE)) | |
6116 { | |
6117 if (dump_file && (dump_flags & TDF_DETAILS)) | |
6118 fprintf (dump_file, | |
6119 "marking known outgoing %sedge %d -> %d executable\n", | |
6120 e->flags & EDGE_DFS_BACK ? "back-" : "", | |
6121 e->src->index, e->dest->index); | |
6122 e->flags |= EDGE_EXECUTABLE; | |
6123 e->dest->flags |= BB_EXECUTABLE; | |
6124 } | |
6125 else if (!(e->dest->flags & BB_EXECUTABLE)) | |
6126 { | |
6127 if (dump_file && (dump_flags & TDF_DETAILS)) | |
6128 fprintf (dump_file, | |
6129 "marking destination block %d reachable\n", | |
6130 e->dest->index); | |
6131 e->dest->flags |= BB_EXECUTABLE; | |
6132 } | |
6133 } | |
6134 else if (gsi_one_before_end_p (gsi)) | |
6135 { | |
6136 FOR_EACH_EDGE (e, ei, bb->succs) | |
6137 { | |
6138 if (!(e->flags & EDGE_EXECUTABLE)) | |
6139 { | |
6140 if (dump_file && (dump_flags & TDF_DETAILS)) | |
6141 fprintf (dump_file, | |
6142 "marking outgoing edge %d -> %d executable\n", | |
6143 e->src->index, e->dest->index); | |
6144 e->flags |= EDGE_EXECUTABLE; | |
6145 e->dest->flags |= BB_EXECUTABLE; | |
6146 } | |
6147 else if (!(e->dest->flags & BB_EXECUTABLE)) | |
6148 { | |
6149 if (dump_file && (dump_flags & TDF_DETAILS)) | |
6150 fprintf (dump_file, | |
6151 "marking destination block %d reachable\n", | |
6152 e->dest->index); | |
6153 e->dest->flags |= BB_EXECUTABLE; | |
6154 } | |
6155 } | |
6156 } | |
6157 | |
6158 /* Eliminate. That also pushes to avail. */ | |
6159 if (eliminate && ! iterate) | |
6160 avail.eliminate_stmt (bb, &gsi); | |
6161 else | |
6162 /* If not eliminating, make all not already available defs | |
6163 available. */ | |
6164 FOR_EACH_SSA_TREE_OPERAND (op, gsi_stmt (gsi), i, SSA_OP_DEF) | |
6165 if (! avail.eliminate_avail (bb, op)) | |
6166 avail.eliminate_push_avail (bb, op); | |
6167 } | |
6168 | |
6169 /* Eliminate in destination PHI arguments. Always substitute in dest | |
6170 PHIs, even for non-executable edges. This handles region | |
6171 exits PHIs. */ | |
6172 if (!iterate && eliminate) | |
6173 FOR_EACH_EDGE (e, ei, bb->succs) | |
6174 for (gphi_iterator gsi = gsi_start_phis (e->dest); | |
6175 !gsi_end_p (gsi); gsi_next (&gsi)) | |
6176 { | |
6177 gphi *phi = gsi.phi (); | |
6178 use_operand_p use_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, e); | |
6179 tree arg = USE_FROM_PTR (use_p); | |
6180 if (TREE_CODE (arg) != SSA_NAME | |
6181 || virtual_operand_p (arg)) | |
6182 continue; | |
6183 tree sprime; | |
6184 if (SSA_NAME_IS_DEFAULT_DEF (arg)) | |
6185 { | |
6186 sprime = SSA_VAL (arg); | |
6187 gcc_assert (TREE_CODE (sprime) != SSA_NAME | |
6188 || SSA_NAME_IS_DEFAULT_DEF (sprime)); | |
6189 } | |
6190 else | |
6191 /* Look for sth available at the definition block of the argument. | |
6192 This avoids inconsistencies between availability there which | |
6193 decides if the stmt can be removed and availability at the | |
6194 use site. The SSA property ensures that things available | |
6195 at the definition are also available at uses. */ | |
6196 sprime = avail.eliminate_avail (gimple_bb (SSA_NAME_DEF_STMT (arg)), | |
6197 arg); | |
6198 if (sprime | |
6199 && sprime != arg | |
6200 && may_propagate_copy (arg, sprime)) | |
6201 propagate_value (use_p, sprime); | |
6202 } | |
6203 | |
6204 vn_context_bb = NULL; | |
6205 return todo; | |
6206 } | |
6207 | |
6208 /* Unwind state per basic-block. */ | |
6209 | |
6210 struct unwind_state | |
6211 { | |
6212 /* Times this block has been visited. */ | |
6213 unsigned visited; | |
6214 /* Whether to handle this as iteration point or whether to treat | |
6215 incoming backedge PHI values as varying. */ | |
6216 bool iterate; | |
6217 /* Maximum RPO index this block is reachable from. */ | |
6218 int max_rpo; | |
6219 /* Unwind state. */ | |
6220 void *ob_top; | |
6221 vn_reference_t ref_top; | |
6222 vn_phi_t phi_top; | |
6223 vn_nary_op_t nary_top; | |
6224 }; | |
6225 | |
6226 /* Unwind the RPO VN state for iteration. */ | |
6227 | |
6228 static void | |
6229 do_unwind (unwind_state *to, int rpo_idx, rpo_elim &avail, int *bb_to_rpo) | |
6230 { | |
6231 gcc_assert (to->iterate); | |
6232 for (; last_inserted_nary != to->nary_top; | |
6233 last_inserted_nary = last_inserted_nary->next) | |
6234 { | |
6235 vn_nary_op_t *slot; | |
6236 slot = valid_info->nary->find_slot_with_hash | |
6237 (last_inserted_nary, last_inserted_nary->hashcode, NO_INSERT); | |
6238 /* Predication causes the need to restore previous state. */ | |
6239 if ((*slot)->unwind_to) | |
6240 *slot = (*slot)->unwind_to; | |
6241 else | |
6242 valid_info->nary->clear_slot (slot); | |
6243 } | |
6244 for (; last_inserted_phi != to->phi_top; | |
6245 last_inserted_phi = last_inserted_phi->next) | |
6246 { | |
6247 vn_phi_t *slot; | |
6248 slot = valid_info->phis->find_slot_with_hash | |
6249 (last_inserted_phi, last_inserted_phi->hashcode, NO_INSERT); | |
6250 valid_info->phis->clear_slot (slot); | |
6251 } | |
6252 for (; last_inserted_ref != to->ref_top; | |
6253 last_inserted_ref = last_inserted_ref->next) | |
6254 { | |
6255 vn_reference_t *slot; | |
6256 slot = valid_info->references->find_slot_with_hash | |
6257 (last_inserted_ref, last_inserted_ref->hashcode, NO_INSERT); | |
6258 (*slot)->operands.release (); | |
6259 valid_info->references->clear_slot (slot); | |
6260 } | |
6261 obstack_free (&vn_tables_obstack, to->ob_top); | |
6262 | |
6263 /* Prune [rpo_idx, ] from avail. */ | |
6264 /* ??? This is O(number-of-values-in-region) which is | |
6265 O(region-size) rather than O(iteration-piece). */ | |
6266 for (rpo_elim::rpo_avail_t::iterator i | |
6267 = avail.m_rpo_avail.begin (); | |
6268 i != avail.m_rpo_avail.end (); ++i) | |
6269 { | |
6270 while (! (*i).second.is_empty ()) | |
6271 { | |
6272 if (bb_to_rpo[(*i).second.last ().first] < rpo_idx) | |
6273 break; | |
6274 (*i).second.pop (); | |
6275 } | |
6276 } | |
6277 } | |
6278 | |
6279 /* Do VN on a SEME region specified by ENTRY and EXIT_BBS in FN. | |
6280 If ITERATE is true then treat backedges optimistically as not | |
6281 executed and iterate. If ELIMINATE is true then perform | |
6282 elimination, otherwise leave that to the caller. */ | |
6283 | |
6284 static unsigned | |
6285 do_rpo_vn (function *fn, edge entry, bitmap exit_bbs, | |
6286 bool iterate, bool eliminate) | |
6287 { | |
6288 unsigned todo = 0; | |
6289 | |
6290 /* We currently do not support region-based iteration when | |
6291 elimination is requested. */ | |
6292 gcc_assert (!entry || !iterate || !eliminate); | |
6293 /* When iterating we need loop info up-to-date. */ | |
6294 gcc_assert (!iterate || !loops_state_satisfies_p (LOOPS_NEED_FIXUP)); | |
6295 | |
6296 bool do_region = entry != NULL; | |
6297 if (!do_region) | |
6298 { | |
6299 entry = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (fn)); | |
6300 exit_bbs = BITMAP_ALLOC (NULL); | |
6301 bitmap_set_bit (exit_bbs, EXIT_BLOCK); | |
6302 } | |
6303 | |
6304 int *rpo = XNEWVEC (int, n_basic_blocks_for_fn (fn) - NUM_FIXED_BLOCKS); | |
6305 int n = rev_post_order_and_mark_dfs_back_seme | |
6306 (fn, entry, exit_bbs, !loops_state_satisfies_p (LOOPS_NEED_FIXUP), rpo); | |
6307 /* rev_post_order_and_mark_dfs_back_seme fills RPO in reverse order. */ | |
6308 for (int i = 0; i < n / 2; ++i) | |
6309 std::swap (rpo[i], rpo[n-i-1]); | |
6310 | |
6311 if (!do_region) | |
6312 BITMAP_FREE (exit_bbs); | |
6313 | |
6314 int *bb_to_rpo = XNEWVEC (int, last_basic_block_for_fn (fn)); | |
6315 for (int i = 0; i < n; ++i) | |
6316 bb_to_rpo[rpo[i]] = i; | |
6317 | |
6318 unwind_state *rpo_state = XNEWVEC (unwind_state, n); | |
6319 | |
6320 rpo_elim avail (entry->dest); | |
6321 rpo_avail = &avail; | |
6322 | |
6323 /* Verify we have no extra entries into the region. */ | |
6324 if (flag_checking && do_region) | |
6325 { | |
6326 auto_bb_flag bb_in_region (fn); | |
6327 for (int i = 0; i < n; ++i) | |
6328 { | |
6329 basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]); | |
6330 bb->flags |= bb_in_region; | |
6331 } | |
6332 /* We can't merge the first two loops because we cannot rely | |
6333 on EDGE_DFS_BACK for edges not within the region. But if | |
6334 we decide to always have the bb_in_region flag we can | |
6335 do the checking during the RPO walk itself (but then it's | |
6336 also easy to handle MEME conservatively). */ | |
6337 for (int i = 0; i < n; ++i) | |
6338 { | |
6339 basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]); | |
6340 edge e; | |
6341 edge_iterator ei; | |
6342 FOR_EACH_EDGE (e, ei, bb->preds) | |
6343 gcc_assert (e == entry || (e->src->flags & bb_in_region)); | |
6344 } | |
6345 for (int i = 0; i < n; ++i) | |
6346 { | |
6347 basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]); | |
6348 bb->flags &= ~bb_in_region; | |
6349 } | |
6350 } | |
6351 | |
6352 /* Create the VN state. For the initial size of the various hashtables | |
6353 use a heuristic based on region size and number of SSA names. */ | |
6354 unsigned region_size = (((unsigned HOST_WIDE_INT)n * num_ssa_names) | |
6355 / (n_basic_blocks_for_fn (fn) - NUM_FIXED_BLOCKS)); | |
6356 VN_TOP = create_tmp_var_raw (void_type_node, "vn_top"); | |
6357 | |
6358 vn_ssa_aux_hash = new hash_table <vn_ssa_aux_hasher> (region_size * 2); | |
6359 gcc_obstack_init (&vn_ssa_aux_obstack); | |
6360 | |
6361 gcc_obstack_init (&vn_tables_obstack); | |
6362 gcc_obstack_init (&vn_tables_insert_obstack); | |
6363 valid_info = XCNEW (struct vn_tables_s); | |
6364 allocate_vn_table (valid_info, region_size); | |
6365 last_inserted_ref = NULL; | |
6366 last_inserted_phi = NULL; | |
6367 last_inserted_nary = NULL; | |
6368 | |
6369 vn_valueize = rpo_vn_valueize; | |
6370 | |
6371 /* Initialize the unwind state and edge/BB executable state. */ | |
6372 bool need_max_rpo_iterate = false; | |
6373 for (int i = 0; i < n; ++i) | |
6374 { | |
6375 basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]); | |
6376 rpo_state[i].visited = 0; | |
6377 rpo_state[i].max_rpo = i; | |
6378 bb->flags &= ~BB_EXECUTABLE; | |
6379 bool has_backedges = false; | |
6380 edge e; | |
6381 edge_iterator ei; | |
6382 FOR_EACH_EDGE (e, ei, bb->preds) | |
6383 { | |
6384 if (e->flags & EDGE_DFS_BACK) | |
6385 has_backedges = true; | |
6386 e->flags &= ~EDGE_EXECUTABLE; | |
6387 if (iterate || e == entry) | |
6388 continue; | |
6389 if (bb_to_rpo[e->src->index] > i) | |
6390 { | |
6391 rpo_state[i].max_rpo = MAX (rpo_state[i].max_rpo, | |
6392 bb_to_rpo[e->src->index]); | |
6393 need_max_rpo_iterate = true; | |
6394 } | |
6395 else | |
6396 rpo_state[i].max_rpo | |
6397 = MAX (rpo_state[i].max_rpo, | |
6398 rpo_state[bb_to_rpo[e->src->index]].max_rpo); | |
6399 } | |
6400 rpo_state[i].iterate = iterate && has_backedges; | |
6401 } | |
6402 entry->flags |= EDGE_EXECUTABLE; | |
6403 entry->dest->flags |= BB_EXECUTABLE; | |
6404 | |
6405 /* When there are irreducible regions the simplistic max_rpo computation | |
6406 above for the case of backedges doesn't work and we need to iterate | |
6407 until there are no more changes. */ | |
6408 unsigned nit = 0; | |
6409 while (need_max_rpo_iterate) | |
6410 { | |
6411 nit++; | |
6412 need_max_rpo_iterate = false; | |
6413 for (int i = 0; i < n; ++i) | |
6414 { | |
6415 basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]); | |
6416 edge e; | |
6417 edge_iterator ei; | |
6418 FOR_EACH_EDGE (e, ei, bb->preds) | |
6419 { | |
6420 if (e == entry) | |
6421 continue; | |
6422 int max_rpo = MAX (rpo_state[i].max_rpo, | |
6423 rpo_state[bb_to_rpo[e->src->index]].max_rpo); | |
6424 if (rpo_state[i].max_rpo != max_rpo) | |
6425 { | |
6426 rpo_state[i].max_rpo = max_rpo; | |
6427 need_max_rpo_iterate = true; | |
6428 } | |
6429 } | |
6430 } | |
6431 } | |
6432 statistics_histogram_event (cfun, "RPO max_rpo iterations", nit); | |
6433 | |
6434 /* As heuristic to improve compile-time we handle only the N innermost | |
6435 loops and the outermost one optimistically. */ | |
6436 if (iterate) | |
6437 { | |
6438 loop_p loop; | |
6439 unsigned max_depth = PARAM_VALUE (PARAM_RPO_VN_MAX_LOOP_DEPTH); | |
6440 FOR_EACH_LOOP (loop, LI_ONLY_INNERMOST) | |
6441 if (loop_depth (loop) > max_depth) | |
6442 for (unsigned i = 2; | |
6443 i < loop_depth (loop) - max_depth; ++i) | |
6444 { | |
6445 basic_block header = superloop_at_depth (loop, i)->header; | |
6446 bool non_latch_backedge = false; | |
6447 edge e; | |
6448 edge_iterator ei; | |
6449 FOR_EACH_EDGE (e, ei, header->preds) | |
6450 if (e->flags & EDGE_DFS_BACK) | |
6451 { | |
6452 e->flags |= EDGE_EXECUTABLE; | |
6453 /* There can be a non-latch backedge into the header | |
6454 which is part of an outer irreducible region. We | |
6455 cannot avoid iterating this block then. */ | |
6456 if (!dominated_by_p (CDI_DOMINATORS, | |
6457 e->src, e->dest)) | |
6458 { | |
6459 if (dump_file && (dump_flags & TDF_DETAILS)) | |
6460 fprintf (dump_file, "non-latch backedge %d -> %d " | |
6461 "forces iteration of loop %d\n", | |
6462 e->src->index, e->dest->index, loop->num); | |
6463 non_latch_backedge = true; | |
6464 } | |
6465 } | |
6466 rpo_state[bb_to_rpo[header->index]].iterate = non_latch_backedge; | |
6467 } | |
6468 } | |
6469 | |
6470 uint64_t nblk = 0; | |
6471 int idx = 0; | |
6472 if (iterate) | |
6473 /* Go and process all blocks, iterating as necessary. */ | |
6474 do | |
6475 { | |
6476 basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[idx]); | |
6477 | |
6478 /* If the block has incoming backedges remember unwind state. This | |
6479 is required even for non-executable blocks since in irreducible | |
6480 regions we might reach them via the backedge and re-start iterating | |
6481 from there. | |
6482 Note we can individually mark blocks with incoming backedges to | |
6483 not iterate where we then handle PHIs conservatively. We do that | |
6484 heuristically to reduce compile-time for degenerate cases. */ | |
6485 if (rpo_state[idx].iterate) | |
6486 { | |
6487 rpo_state[idx].ob_top = obstack_alloc (&vn_tables_obstack, 0); | |
6488 rpo_state[idx].ref_top = last_inserted_ref; | |
6489 rpo_state[idx].phi_top = last_inserted_phi; | |
6490 rpo_state[idx].nary_top = last_inserted_nary; | |
6491 } | |
6492 | |
6493 if (!(bb->flags & BB_EXECUTABLE)) | |
6494 { | |
6495 if (dump_file && (dump_flags & TDF_DETAILS)) | |
6496 fprintf (dump_file, "Block %d: BB%d found not executable\n", | |
6497 idx, bb->index); | |
6498 idx++; | |
6499 continue; | |
6500 } | |
6501 | |
6502 if (dump_file && (dump_flags & TDF_DETAILS)) | |
6503 fprintf (dump_file, "Processing block %d: BB%d\n", idx, bb->index); | |
6504 nblk++; | |
6505 todo |= process_bb (avail, bb, | |
6506 rpo_state[idx].visited != 0, | |
6507 rpo_state[idx].iterate, | |
6508 iterate, eliminate, do_region, exit_bbs); | |
6509 rpo_state[idx].visited++; | |
6510 | |
6511 /* Verify if changed values flow over executable outgoing backedges | |
6512 and those change destination PHI values (that's the thing we | |
6513 can easily verify). Reduce over all such edges to the farthest | |
6514 away PHI. */ | |
6515 int iterate_to = -1; | |
6516 edge_iterator ei; | |
6517 edge e; | |
6518 FOR_EACH_EDGE (e, ei, bb->succs) | |
6519 if ((e->flags & (EDGE_DFS_BACK|EDGE_EXECUTABLE)) | |
6520 == (EDGE_DFS_BACK|EDGE_EXECUTABLE) | |
6521 && rpo_state[bb_to_rpo[e->dest->index]].iterate) | |
6522 { | |
6523 int destidx = bb_to_rpo[e->dest->index]; | |
6524 if (!rpo_state[destidx].visited) | |
6525 { | |
6526 if (dump_file && (dump_flags & TDF_DETAILS)) | |
6527 fprintf (dump_file, "Unvisited destination %d\n", | |
6528 e->dest->index); | |
6529 if (iterate_to == -1 || destidx < iterate_to) | |
6530 iterate_to = destidx; | |
6531 continue; | |
6532 } | |
6533 if (dump_file && (dump_flags & TDF_DETAILS)) | |
6534 fprintf (dump_file, "Looking for changed values of backedge" | |
6535 " %d->%d destination PHIs\n", | |
6536 e->src->index, e->dest->index); | |
6537 vn_context_bb = e->dest; | |
6538 gphi_iterator gsi; | |
6539 for (gsi = gsi_start_phis (e->dest); | |
6540 !gsi_end_p (gsi); gsi_next (&gsi)) | |
6541 { | |
6542 bool inserted = false; | |
6543 /* While we'd ideally just iterate on value changes | |
6544 we CSE PHIs and do that even across basic-block | |
6545 boundaries. So even hashtable state changes can | |
6546 be important (which is roughly equivalent to | |
6547 PHI argument value changes). To not excessively | |
6548 iterate because of that we track whether a PHI | |
6549 was CSEd to with GF_PLF_1. */ | |
6550 bool phival_changed; | |
6551 if ((phival_changed = visit_phi (gsi.phi (), | |
6552 &inserted, false)) | |
6553 || (inserted && gimple_plf (gsi.phi (), GF_PLF_1))) | |
6554 { | |
6555 if (!phival_changed | |
6556 && dump_file && (dump_flags & TDF_DETAILS)) | |
6557 fprintf (dump_file, "PHI was CSEd and hashtable " | |
6558 "state (changed)\n"); | |
6559 if (iterate_to == -1 || destidx < iterate_to) | |
6560 iterate_to = destidx; | |
6561 break; | |
6562 } | |
6563 } | |
6564 vn_context_bb = NULL; | |
6565 } | |
6566 if (iterate_to != -1) | |
6567 { | |
6568 do_unwind (&rpo_state[iterate_to], iterate_to, avail, bb_to_rpo); | |
6569 idx = iterate_to; | |
6570 if (dump_file && (dump_flags & TDF_DETAILS)) | |
6571 fprintf (dump_file, "Iterating to %d BB%d\n", | |
6572 iterate_to, rpo[iterate_to]); | |
6573 continue; | |
6574 } | |
6575 | |
6576 idx++; | |
6577 } | |
6578 while (idx < n); | |
6579 | |
6580 else /* !iterate */ | |
6581 { | |
6582 /* Process all blocks greedily with a worklist that enforces RPO | |
6583 processing of reachable blocks. */ | |
6584 auto_bitmap worklist; | |
6585 bitmap_set_bit (worklist, 0); | |
6586 while (!bitmap_empty_p (worklist)) | |
6587 { | |
6588 int idx = bitmap_first_set_bit (worklist); | |
6589 bitmap_clear_bit (worklist, idx); | |
6590 basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[idx]); | |
6591 gcc_assert ((bb->flags & BB_EXECUTABLE) | |
6592 && !rpo_state[idx].visited); | |
6593 | |
6594 if (dump_file && (dump_flags & TDF_DETAILS)) | |
6595 fprintf (dump_file, "Processing block %d: BB%d\n", idx, bb->index); | |
6596 | |
6597 /* When we run into predecessor edges where we cannot trust its | |
6598 executable state mark them executable so PHI processing will | |
6599 be conservative. | |
6600 ??? Do we need to force arguments flowing over that edge | |
6601 to be varying or will they even always be? */ | |
6602 edge_iterator ei; | |
6603 edge e; | |
6604 FOR_EACH_EDGE (e, ei, bb->preds) | |
6605 if (!(e->flags & EDGE_EXECUTABLE) | |
6606 && !rpo_state[bb_to_rpo[e->src->index]].visited | |
6607 && rpo_state[bb_to_rpo[e->src->index]].max_rpo >= (int)idx) | |
6608 { | |
6609 if (dump_file && (dump_flags & TDF_DETAILS)) | |
6610 fprintf (dump_file, "Cannot trust state of predecessor " | |
6611 "edge %d -> %d, marking executable\n", | |
6612 e->src->index, e->dest->index); | |
6613 e->flags |= EDGE_EXECUTABLE; | |
6614 } | |
6615 | |
6616 nblk++; | |
6617 todo |= process_bb (avail, bb, false, false, false, eliminate, | |
6618 do_region, exit_bbs); | |
6619 rpo_state[idx].visited++; | |
6620 | |
6621 FOR_EACH_EDGE (e, ei, bb->succs) | |
6622 if ((e->flags & EDGE_EXECUTABLE) | |
6623 && e->dest->index != EXIT_BLOCK | |
6624 && (!do_region || !bitmap_bit_p (exit_bbs, e->dest->index)) | |
6625 && !rpo_state[bb_to_rpo[e->dest->index]].visited) | |
6626 bitmap_set_bit (worklist, bb_to_rpo[e->dest->index]); | |
6627 } | |
6628 } | |
6629 | |
6630 /* If statistics or dump file active. */ | |
6631 int nex = 0; | |
6632 unsigned max_visited = 1; | |
6633 for (int i = 0; i < n; ++i) | |
6634 { | |
6635 basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]); | |
6636 if (bb->flags & BB_EXECUTABLE) | |
6637 nex++; | |
6638 statistics_histogram_event (cfun, "RPO block visited times", | |
6639 rpo_state[i].visited); | |
6640 if (rpo_state[i].visited > max_visited) | |
6641 max_visited = rpo_state[i].visited; | |
6642 } | |
6643 unsigned nvalues = 0, navail = 0; | |
6644 for (rpo_elim::rpo_avail_t::iterator i = avail.m_rpo_avail.begin (); | |
6645 i != avail.m_rpo_avail.end (); ++i) | |
6646 { | |
6647 nvalues++; | |
6648 navail += (*i).second.length (); | |
6649 } | |
6650 statistics_counter_event (cfun, "RPO blocks", n); | |
6651 statistics_counter_event (cfun, "RPO blocks visited", nblk); | |
6652 statistics_counter_event (cfun, "RPO blocks executable", nex); | |
6653 statistics_histogram_event (cfun, "RPO iterations", 10*nblk / nex); | |
6654 statistics_histogram_event (cfun, "RPO num values", nvalues); | |
6655 statistics_histogram_event (cfun, "RPO num avail", navail); | |
6656 statistics_histogram_event (cfun, "RPO num lattice", | |
6657 vn_ssa_aux_hash->elements ()); | |
6658 if (dump_file && (dump_flags & (TDF_DETAILS|TDF_STATS))) | |
6659 { | |
6660 fprintf (dump_file, "RPO iteration over %d blocks visited %" PRIu64 | |
6661 " blocks in total discovering %d executable blocks iterating " | |
6662 "%d.%d times, a block was visited max. %u times\n", | |
6663 n, nblk, nex, | |
6664 (int)((10*nblk / nex)/10), (int)((10*nblk / nex)%10), | |
6665 max_visited); | |
6666 fprintf (dump_file, "RPO tracked %d values available at %d locations " | |
6667 "and %" PRIu64 " lattice elements\n", | |
6668 nvalues, navail, (uint64_t) vn_ssa_aux_hash->elements ()); | |
6669 } | |
6670 | |
6671 if (eliminate) | |
6672 { | |
6673 /* When !iterate we already performed elimination during the RPO | |
6674 walk. */ | |
6675 if (iterate) | |
6676 { | |
6677 /* Elimination for region-based VN needs to be done within the | |
6678 RPO walk. */ | |
6679 gcc_assert (! do_region); | |
6680 /* Note we can't use avail.walk here because that gets confused | |
6681 by the existing availability and it will be less efficient | |
6682 as well. */ | |
6683 todo |= eliminate_with_rpo_vn (NULL); | |
6684 } | |
6685 else | |
6686 todo |= avail.eliminate_cleanup (do_region); | |
6687 } | |
6688 | |
6689 vn_valueize = NULL; | |
6690 rpo_avail = NULL; | |
6691 | |
6692 XDELETEVEC (bb_to_rpo); | |
6693 XDELETEVEC (rpo); | |
6694 XDELETEVEC (rpo_state); | |
6695 | |
6696 return todo; | |
6697 } | |
6698 | |
6699 /* Region-based entry for RPO VN. Performs value-numbering and elimination | |
6700 on the SEME region specified by ENTRY and EXIT_BBS. */ | |
6701 | |
6702 unsigned | |
6703 do_rpo_vn (function *fn, edge entry, bitmap exit_bbs) | |
6704 { | |
6705 default_vn_walk_kind = VN_WALKREWRITE; | |
6706 unsigned todo = do_rpo_vn (fn, entry, exit_bbs, false, true); | |
6707 free_rpo_vn (); | |
6708 return todo; | |
5970 } | 6709 } |
5971 | 6710 |
5972 | 6711 |
5973 namespace { | 6712 namespace { |
5974 | 6713 |
5998 virtual unsigned int execute (function *); | 6737 virtual unsigned int execute (function *); |
5999 | 6738 |
6000 }; // class pass_fre | 6739 }; // class pass_fre |
6001 | 6740 |
6002 unsigned int | 6741 unsigned int |
6003 pass_fre::execute (function *) | 6742 pass_fre::execute (function *fun) |
6004 { | 6743 { |
6005 unsigned int todo = 0; | 6744 unsigned todo = 0; |
6006 | 6745 |
6007 run_scc_vn (VN_WALKREWRITE); | 6746 /* At -O[1g] use the cheap non-iterating mode. */ |
6008 | 6747 calculate_dominance_info (CDI_DOMINATORS); |
6009 /* Remove all the redundant expressions. */ | 6748 if (optimize > 1) |
6010 todo |= vn_eliminate (NULL); | 6749 loop_optimizer_init (AVOID_CFG_MODIFICATIONS); |
6011 | 6750 |
6012 scc_vn_restore_ssa_info (); | 6751 default_vn_walk_kind = VN_WALKREWRITE; |
6013 free_scc_vn (); | 6752 todo = do_rpo_vn (fun, NULL, NULL, optimize > 1, true); |
6753 free_rpo_vn (); | |
6754 | |
6755 if (optimize > 1) | |
6756 loop_optimizer_finalize (); | |
6014 | 6757 |
6015 return todo; | 6758 return todo; |
6016 } | 6759 } |
6017 | 6760 |
6018 } // anon namespace | 6761 } // anon namespace |
6020 gimple_opt_pass * | 6763 gimple_opt_pass * |
6021 make_pass_fre (gcc::context *ctxt) | 6764 make_pass_fre (gcc::context *ctxt) |
6022 { | 6765 { |
6023 return new pass_fre (ctxt); | 6766 return new pass_fre (ctxt); |
6024 } | 6767 } |
6768 | |
6769 #undef BB_EXECUTABLE |