Mercurial > hg > CbC > CbC_gcc
comparison gcc/alias.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
comparison
equal
deleted
inserted
replaced
65:65488c3d617d | 67:f6334be47118 |
---|---|
32 #include "regs.h" | 32 #include "regs.h" |
33 #include "hard-reg-set.h" | 33 #include "hard-reg-set.h" |
34 #include "basic-block.h" | 34 #include "basic-block.h" |
35 #include "flags.h" | 35 #include "flags.h" |
36 #include "output.h" | 36 #include "output.h" |
37 #include "toplev.h" | 37 #include "diagnostic-core.h" |
38 #include "cselib.h" | 38 #include "cselib.h" |
39 #include "splay-tree.h" | 39 #include "splay-tree.h" |
40 #include "ggc.h" | 40 #include "ggc.h" |
41 #include "langhooks.h" | 41 #include "langhooks.h" |
42 #include "timevar.h" | 42 #include "timevar.h" |
209 /* We preserve the copy of old array around to avoid amount of garbage | 209 /* We preserve the copy of old array around to avoid amount of garbage |
210 produced. About 8% of garbage produced were attributed to this | 210 produced. About 8% of garbage produced were attributed to this |
211 array. */ | 211 array. */ |
212 static GTY((deletable)) VEC(rtx,gc) *old_reg_base_value; | 212 static GTY((deletable)) VEC(rtx,gc) *old_reg_base_value; |
213 | 213 |
214 /* Static hunks of RTL used by the aliasing code; these are initialized | 214 #define static_reg_base_value \ |
215 once per function to avoid unnecessary RTL allocations. */ | 215 (this_target_rtl->x_static_reg_base_value) |
216 static GTY (()) rtx static_reg_base_value[FIRST_PSEUDO_REGISTER]; | |
217 | 216 |
218 #define REG_BASE_VALUE(X) \ | 217 #define REG_BASE_VALUE(X) \ |
219 (REGNO (X) < VEC_length (rtx, reg_base_value) \ | 218 (REGNO (X) < VEC_length (rtx, reg_base_value) \ |
220 ? VEC_index (rtx, reg_base_value, REGNO (X)) : 0) | 219 ? VEC_index (rtx, reg_base_value, REGNO (X)) : 0) |
221 | 220 |
277 || TREE_CODE (base) == LABEL_DECL) | 276 || TREE_CODE (base) == LABEL_DECL) |
278 return false; | 277 return false; |
279 | 278 |
280 /* If this is a pointer dereference of a non-SSA_NAME punt. | 279 /* If this is a pointer dereference of a non-SSA_NAME punt. |
281 ??? We could replace it with a pointer to anything. */ | 280 ??? We could replace it with a pointer to anything. */ |
282 if (INDIRECT_REF_P (base) | 281 if ((INDIRECT_REF_P (base) |
282 || TREE_CODE (base) == MEM_REF) | |
283 && TREE_CODE (TREE_OPERAND (base, 0)) != SSA_NAME) | 283 && TREE_CODE (TREE_OPERAND (base, 0)) != SSA_NAME) |
284 return false; | |
285 if (TREE_CODE (base) == TARGET_MEM_REF | |
286 && TMR_BASE (base) | |
287 && TREE_CODE (TMR_BASE (base)) != SSA_NAME) | |
284 return false; | 288 return false; |
285 | 289 |
286 /* If this is a reference based on a partitioned decl replace the | 290 /* If this is a reference based on a partitioned decl replace the |
287 base with an INDIRECT_REF of the pointer representative we | 291 base with an INDIRECT_REF of the pointer representative we |
288 created during stack slot partitioning. */ | 292 created during stack slot partitioning. */ |
291 && cfun->gimple_df->decls_to_pointers != NULL) | 295 && cfun->gimple_df->decls_to_pointers != NULL) |
292 { | 296 { |
293 void *namep; | 297 void *namep; |
294 namep = pointer_map_contains (cfun->gimple_df->decls_to_pointers, base); | 298 namep = pointer_map_contains (cfun->gimple_df->decls_to_pointers, base); |
295 if (namep) | 299 if (namep) |
296 { | 300 ref->base = build_simple_mem_ref (*(tree *)namep); |
297 ref->base_alias_set = get_alias_set (base); | 301 } |
298 ref->base = build1 (INDIRECT_REF, TREE_TYPE (base), *(tree *)namep); | 302 else if (TREE_CODE (base) == TARGET_MEM_REF |
299 } | 303 && TREE_CODE (TMR_BASE (base)) == ADDR_EXPR |
304 && TREE_CODE (TREE_OPERAND (TMR_BASE (base), 0)) == VAR_DECL | |
305 && ! TREE_STATIC (TREE_OPERAND (TMR_BASE (base), 0)) | |
306 && cfun->gimple_df->decls_to_pointers != NULL) | |
307 { | |
308 void *namep; | |
309 namep = pointer_map_contains (cfun->gimple_df->decls_to_pointers, | |
310 TREE_OPERAND (TMR_BASE (base), 0)); | |
311 if (namep) | |
312 ref->base = build_simple_mem_ref (*(tree *)namep); | |
300 } | 313 } |
301 | 314 |
302 ref->ref_alias_set = MEM_ALIAS_SET (mem); | 315 ref->ref_alias_set = MEM_ALIAS_SET (mem); |
303 | 316 |
304 /* If MEM_OFFSET or MEM_SIZE are NULL we have to punt. | 317 /* If MEM_OFFSET or MEM_SIZE are NULL we have to punt. |
354 | 367 |
355 if (!ao_ref_from_mem (&ref1, x) | 368 if (!ao_ref_from_mem (&ref1, x) |
356 || !ao_ref_from_mem (&ref2, mem)) | 369 || !ao_ref_from_mem (&ref2, mem)) |
357 return true; | 370 return true; |
358 | 371 |
359 return refs_may_alias_p_1 (&ref1, &ref2, tbaa_p); | 372 return refs_may_alias_p_1 (&ref1, &ref2, |
373 tbaa_p | |
374 && MEM_ALIAS_SET (x) != 0 | |
375 && MEM_ALIAS_SET (mem) != 0); | |
360 } | 376 } |
361 | 377 |
362 /* Returns a pointer to the alias set entry for ALIAS_SET, if there is | 378 /* Returns a pointer to the alias set entry for ALIAS_SET, if there is |
363 such an entry, or NULL otherwise. */ | 379 such an entry, or NULL otherwise. */ |
364 | 380 |
449 /* The two alias sets are distinct and neither one is the | 465 /* The two alias sets are distinct and neither one is the |
450 child of the other. Therefore, they cannot conflict. */ | 466 child of the other. Therefore, they cannot conflict. */ |
451 return 0; | 467 return 0; |
452 } | 468 } |
453 | 469 |
454 static int | |
455 walk_mems_2 (rtx *x, rtx mem) | |
456 { | |
457 if (MEM_P (*x)) | |
458 { | |
459 if (alias_sets_conflict_p (MEM_ALIAS_SET(*x), MEM_ALIAS_SET(mem))) | |
460 return 1; | |
461 | |
462 return -1; | |
463 } | |
464 return 0; | |
465 } | |
466 | |
467 static int | |
468 walk_mems_1 (rtx *x, rtx *pat) | |
469 { | |
470 if (MEM_P (*x)) | |
471 { | |
472 /* Visit all MEMs in *PAT and check indepedence. */ | |
473 if (for_each_rtx (pat, (rtx_function) walk_mems_2, *x)) | |
474 /* Indicate that dependence was determined and stop traversal. */ | |
475 return 1; | |
476 | |
477 return -1; | |
478 } | |
479 return 0; | |
480 } | |
481 | |
482 /* Return 1 if two specified instructions have mem expr with conflict alias sets*/ | |
483 bool | |
484 insn_alias_sets_conflict_p (rtx insn1, rtx insn2) | |
485 { | |
486 /* For each pair of MEMs in INSN1 and INSN2 check their independence. */ | |
487 return for_each_rtx (&PATTERN (insn1), (rtx_function) walk_mems_1, | |
488 &PATTERN (insn2)); | |
489 } | |
490 | |
491 /* Return 1 if the two specified alias sets will always conflict. */ | 470 /* Return 1 if the two specified alias sets will always conflict. */ |
492 | 471 |
493 int | 472 int |
494 alias_sets_must_conflict_p (alias_set_type set1, alias_set_type set2) | 473 alias_sets_must_conflict_p (alias_set_type set1, alias_set_type set2) |
495 { | 474 { |
646 aren't types. */ | 625 aren't types. */ |
647 if (! TYPE_P (t)) | 626 if (! TYPE_P (t)) |
648 { | 627 { |
649 tree inner; | 628 tree inner; |
650 | 629 |
651 /* Remove any nops, then give the language a chance to do | 630 /* Give the language a chance to do something with this tree |
652 something with this tree before we look at it. */ | 631 before we look at it. */ |
653 STRIP_NOPS (t); | 632 STRIP_NOPS (t); |
654 set = lang_hooks.get_alias_set (t); | 633 set = lang_hooks.get_alias_set (t); |
655 if (set != -1) | 634 if (set != -1) |
656 return set; | 635 return set; |
657 | 636 |
658 /* Retrieve the original memory reference if needed. */ | 637 /* Get the base object of the reference. */ |
659 if (TREE_CODE (t) == TARGET_MEM_REF) | |
660 t = TMR_ORIGINAL (t); | |
661 | |
662 /* First see if the actual object referenced is an INDIRECT_REF from a | |
663 restrict-qualified pointer or a "void *". */ | |
664 inner = t; | 638 inner = t; |
665 while (handled_component_p (inner)) | 639 while (handled_component_p (inner)) |
666 { | 640 { |
641 /* If there is a VIEW_CONVERT_EXPR in the chain we cannot use | |
642 the type of any component references that wrap it to | |
643 determine the alias-set. */ | |
644 if (TREE_CODE (inner) == VIEW_CONVERT_EXPR) | |
645 t = TREE_OPERAND (inner, 0); | |
667 inner = TREE_OPERAND (inner, 0); | 646 inner = TREE_OPERAND (inner, 0); |
668 STRIP_NOPS (inner); | |
669 } | 647 } |
670 | 648 |
649 /* Handle pointer dereferences here, they can override the | |
650 alias-set. */ | |
671 if (INDIRECT_REF_P (inner)) | 651 if (INDIRECT_REF_P (inner)) |
672 { | 652 { |
673 set = get_deref_alias_set_1 (TREE_OPERAND (inner, 0)); | 653 set = get_deref_alias_set_1 (TREE_OPERAND (inner, 0)); |
674 if (set != -1) | 654 if (set != -1) |
675 return set; | 655 return set; |
676 } | 656 } |
657 else if (TREE_CODE (inner) == TARGET_MEM_REF) | |
658 return get_deref_alias_set (TMR_OFFSET (inner)); | |
659 else if (TREE_CODE (inner) == MEM_REF) | |
660 { | |
661 set = get_deref_alias_set_1 (TREE_OPERAND (inner, 1)); | |
662 if (set != -1) | |
663 return set; | |
664 } | |
665 | |
666 /* If the innermost reference is a MEM_REF that has a | |
667 conversion embedded treat it like a VIEW_CONVERT_EXPR above, | |
668 using the memory access type for determining the alias-set. */ | |
669 if (TREE_CODE (inner) == MEM_REF | |
670 && TYPE_MAIN_VARIANT (TREE_TYPE (inner)) | |
671 != TYPE_MAIN_VARIANT | |
672 (TREE_TYPE (TREE_TYPE (TREE_OPERAND (inner, 1))))) | |
673 return get_deref_alias_set (TREE_OPERAND (inner, 1)); | |
677 | 674 |
678 /* Otherwise, pick up the outermost object that we could have a pointer | 675 /* Otherwise, pick up the outermost object that we could have a pointer |
679 to, processing conversions as above. */ | 676 to, processing conversions as above. */ |
680 while (component_uses_parent_alias_set (t)) | 677 while (component_uses_parent_alias_set (t)) |
681 { | 678 { |
708 set = lang_hooks.get_alias_set (t); | 705 set = lang_hooks.get_alias_set (t); |
709 if (set != -1) | 706 if (set != -1) |
710 return set; | 707 return set; |
711 return 0; | 708 return 0; |
712 } | 709 } |
710 | |
713 t = TYPE_CANONICAL (t); | 711 t = TYPE_CANONICAL (t); |
712 | |
714 /* Canonical types shouldn't form a tree nor should the canonical | 713 /* Canonical types shouldn't form a tree nor should the canonical |
715 type require structural equality checks. */ | 714 type require structural equality checks. */ |
716 gcc_assert (!TYPE_STRUCTURAL_EQUALITY_P (t) && TYPE_CANONICAL (t) == t); | 715 gcc_checking_assert (TYPE_CANONICAL (t) == t |
716 && !TYPE_STRUCTURAL_EQUALITY_P (t)); | |
717 | 717 |
718 /* If this is a type with a known alias set, return it. */ | 718 /* If this is a type with a known alias set, return it. */ |
719 if (TYPE_ALIAS_SET_KNOWN_P (t)) | 719 if (TYPE_ALIAS_SET_KNOWN_P (t)) |
720 return TYPE_ALIAS_SET (t); | 720 return TYPE_ALIAS_SET (t); |
721 | 721 |
737 return set; | 737 return set; |
738 | 738 |
739 /* There are no objects of FUNCTION_TYPE, so there's no point in | 739 /* There are no objects of FUNCTION_TYPE, so there's no point in |
740 using up an alias set for them. (There are, of course, pointers | 740 using up an alias set for them. (There are, of course, pointers |
741 and references to functions, but that's different.) */ | 741 and references to functions, but that's different.) */ |
742 else if (TREE_CODE (t) == FUNCTION_TYPE | 742 else if (TREE_CODE (t) == FUNCTION_TYPE || TREE_CODE (t) == METHOD_TYPE) |
743 || TREE_CODE (t) == METHOD_TYPE) | |
744 set = 0; | 743 set = 0; |
745 | 744 |
746 /* Unless the language specifies otherwise, let vector types alias | 745 /* Unless the language specifies otherwise, let vector types alias |
747 their components. This avoids some nasty type punning issues in | 746 their components. This avoids some nasty type punning issues in |
748 normal usage. And indeed lets vectors be treated more like an | 747 normal usage. And indeed lets vectors be treated more like an |
756 character(kind=1) through a reference to a character(kind=1)[1:1]. | 755 character(kind=1) through a reference to a character(kind=1)[1:1]. |
757 Or consider if we want to assign integer(kind=4)[0:D.1387] and | 756 Or consider if we want to assign integer(kind=4)[0:D.1387] and |
758 integer(kind=4)[4] the same alias set or not. | 757 integer(kind=4)[4] the same alias set or not. |
759 Just be pragmatic here and make sure the array and its element | 758 Just be pragmatic here and make sure the array and its element |
760 type get the same alias set assigned. */ | 759 type get the same alias set assigned. */ |
761 else if (TREE_CODE (t) == ARRAY_TYPE | 760 else if (TREE_CODE (t) == ARRAY_TYPE && !TYPE_NONALIASED_COMPONENT (t)) |
762 && !TYPE_NONALIASED_COMPONENT (t)) | |
763 set = get_alias_set (TREE_TYPE (t)); | 761 set = get_alias_set (TREE_TYPE (t)); |
764 | 762 |
763 /* From the former common C and C++ langhook implementation: | |
764 | |
765 Unfortunately, there is no canonical form of a pointer type. | |
766 In particular, if we have `typedef int I', then `int *', and | |
767 `I *' are different types. So, we have to pick a canonical | |
768 representative. We do this below. | |
769 | |
770 Technically, this approach is actually more conservative that | |
771 it needs to be. In particular, `const int *' and `int *' | |
772 should be in different alias sets, according to the C and C++ | |
773 standard, since their types are not the same, and so, | |
774 technically, an `int **' and `const int **' cannot point at | |
775 the same thing. | |
776 | |
777 But, the standard is wrong. In particular, this code is | |
778 legal C++: | |
779 | |
780 int *ip; | |
781 int **ipp = &ip; | |
782 const int* const* cipp = ipp; | |
783 And, it doesn't make sense for that to be legal unless you | |
784 can dereference IPP and CIPP. So, we ignore cv-qualifiers on | |
785 the pointed-to types. This issue has been reported to the | |
786 C++ committee. | |
787 | |
788 In addition to the above canonicalization issue, with LTO | |
789 we should also canonicalize `T (*)[]' to `T *' avoiding | |
790 alias issues with pointer-to element types and pointer-to | |
791 array types. | |
792 | |
793 Likewise we need to deal with the situation of incomplete | |
794 pointed-to types and make `*(struct X **)&a' and | |
795 `*(struct X {} **)&a' alias. Otherwise we will have to | |
796 guarantee that all pointer-to incomplete type variants | |
797 will be replaced by pointer-to complete type variants if | |
798 they are available. | |
799 | |
800 With LTO the convenient situation of using `void *' to | |
801 access and store any pointer type will also become | |
802 more apparent (and `void *' is just another pointer-to | |
803 incomplete type). Assigning alias-set zero to `void *' | |
804 and all pointer-to incomplete types is a not appealing | |
805 solution. Assigning an effective alias-set zero only | |
806 affecting pointers might be - by recording proper subset | |
807 relationships of all pointer alias-sets. | |
808 | |
809 Pointer-to function types are another grey area which | |
810 needs caution. Globbing them all into one alias-set | |
811 or the above effective zero set would work. | |
812 | |
813 For now just assign the same alias-set to all pointers. | |
814 That's simple and avoids all the above problems. */ | |
815 else if (POINTER_TYPE_P (t) | |
816 && t != ptr_type_node) | |
817 return get_alias_set (ptr_type_node); | |
818 | |
819 /* Otherwise make a new alias set for this type. */ | |
765 else | 820 else |
766 /* Otherwise make a new alias set for this type. */ | |
767 set = new_alias_set (); | 821 set = new_alias_set (); |
768 | 822 |
769 TYPE_ALIAS_SET (t) = set; | 823 TYPE_ALIAS_SET (t) = set; |
770 | 824 |
771 /* If this is an aggregate type, we must record any component aliasing | 825 /* If this is an aggregate type or a complex type, we must record any |
772 information. */ | 826 component aliasing information. */ |
773 if (AGGREGATE_TYPE_P (t) || TREE_CODE (t) == COMPLEX_TYPE) | 827 if (AGGREGATE_TYPE_P (t) || TREE_CODE (t) == COMPLEX_TYPE) |
774 record_component_aliases (t); | 828 record_component_aliases (t); |
775 | 829 |
776 return set; | 830 return set; |
777 } | 831 } |
821 superset_entry = get_alias_set_entry (superset); | 875 superset_entry = get_alias_set_entry (superset); |
822 if (superset_entry == 0) | 876 if (superset_entry == 0) |
823 { | 877 { |
824 /* Create an entry for the SUPERSET, so that we have a place to | 878 /* Create an entry for the SUPERSET, so that we have a place to |
825 attach the SUBSET. */ | 879 attach the SUBSET. */ |
826 superset_entry = GGC_NEW (struct alias_set_entry_d); | 880 superset_entry = ggc_alloc_cleared_alias_set_entry_d (); |
827 superset_entry->alias_set = superset; | 881 superset_entry->alias_set = superset; |
828 superset_entry->children | 882 superset_entry->children |
829 = splay_tree_new_ggc (splay_tree_compare_ints); | 883 = splay_tree_new_ggc (splay_tree_compare_ints, |
884 ggc_alloc_splay_tree_scalar_scalar_splay_tree_s, | |
885 ggc_alloc_splay_tree_scalar_scalar_splay_tree_node_s); | |
830 superset_entry->has_zero_child = 0; | 886 superset_entry->has_zero_child = 0; |
831 VEC_replace (alias_set_entry, alias_sets, superset, superset_entry); | 887 VEC_replace (alias_set_entry, alias_sets, superset, superset_entry); |
832 } | 888 } |
833 | 889 |
834 if (subset == 0) | 890 if (subset == 0) |
881 for (binfo = TYPE_BINFO (type), i = 0; | 937 for (binfo = TYPE_BINFO (type), i = 0; |
882 BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) | 938 BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) |
883 record_alias_subset (superset, | 939 record_alias_subset (superset, |
884 get_alias_set (BINFO_TYPE (base_binfo))); | 940 get_alias_set (BINFO_TYPE (base_binfo))); |
885 } | 941 } |
886 for (field = TYPE_FIELDS (type); field != 0; field = TREE_CHAIN (field)) | 942 for (field = TYPE_FIELDS (type); field != 0; field = DECL_CHAIN (field)) |
887 if (TREE_CODE (field) == FIELD_DECL && !DECL_NONADDRESSABLE_P (field)) | 943 if (TREE_CODE (field) == FIELD_DECL && !DECL_NONADDRESSABLE_P (field)) |
888 record_alias_subset (superset, get_alias_set (TREE_TYPE (field))); | 944 record_alias_subset (superset, get_alias_set (TREE_TYPE (field))); |
889 break; | 945 break; |
890 | 946 |
891 case COMPLEX_TYPE: | 947 case COMPLEX_TYPE: |
1132 if (!REG_P (dest)) | 1188 if (!REG_P (dest)) |
1133 return; | 1189 return; |
1134 | 1190 |
1135 regno = REGNO (dest); | 1191 regno = REGNO (dest); |
1136 | 1192 |
1137 gcc_assert (regno < VEC_length (rtx, reg_base_value)); | 1193 gcc_checking_assert (regno < VEC_length (rtx, reg_base_value)); |
1138 | 1194 |
1139 /* If this spans multiple hard registers, then we must indicate that every | 1195 /* If this spans multiple hard registers, then we must indicate that every |
1140 register has an unusable value. */ | 1196 register has an unusable value. */ |
1141 if (regno < FIRST_PSEUDO_REGISTER) | 1197 if (regno < FIRST_PSEUDO_REGISTER) |
1142 n = hard_regno_nregs[regno][GET_MODE (dest)]; | 1198 n = hard_regno_nregs[regno][GET_MODE (dest)]; |
1230 else if ((regno >= FIRST_PSEUDO_REGISTER || ! fixed_regs[regno]) | 1286 else if ((regno >= FIRST_PSEUDO_REGISTER || ! fixed_regs[regno]) |
1231 && ! reg_seen[regno] && new_reg_base_value[regno] == 0) | 1287 && ! reg_seen[regno] && new_reg_base_value[regno] == 0) |
1232 new_reg_base_value[regno] = find_base_value (src); | 1288 new_reg_base_value[regno] = find_base_value (src); |
1233 | 1289 |
1234 reg_seen[regno] = 1; | 1290 reg_seen[regno] = 1; |
1291 } | |
1292 | |
1293 /* Return REG_BASE_VALUE for REGNO. Selective scheduler uses this to avoid | |
1294 using hard registers with non-null REG_BASE_VALUE for renaming. */ | |
1295 rtx | |
1296 get_reg_base_value (unsigned int regno) | |
1297 { | |
1298 return VEC_index (rtx, reg_base_value, regno); | |
1235 } | 1299 } |
1236 | 1300 |
1237 /* If a value is known for REGNO, return it. */ | 1301 /* If a value is known for REGNO, return it. */ |
1238 | 1302 |
1239 rtx | 1303 rtx |
2161 | 2225 |
2162 return GEN_INT (ioffset); | 2226 return GEN_INT (ioffset); |
2163 } | 2227 } |
2164 | 2228 |
2165 /* Return nonzero if we can determine the exprs corresponding to memrefs | 2229 /* Return nonzero if we can determine the exprs corresponding to memrefs |
2166 X and Y and they do not overlap. */ | 2230 X and Y and they do not overlap. |
2231 If LOOP_VARIANT is set, skip offset-based disambiguation */ | |
2167 | 2232 |
2168 int | 2233 int |
2169 nonoverlapping_memrefs_p (const_rtx x, const_rtx y) | 2234 nonoverlapping_memrefs_p (const_rtx x, const_rtx y, bool loop_invariant) |
2170 { | 2235 { |
2171 tree exprx = MEM_EXPR (x), expry = MEM_EXPR (y); | 2236 tree exprx = MEM_EXPR (x), expry = MEM_EXPR (y); |
2172 rtx rtlx, rtly; | 2237 rtx rtlx, rtly; |
2173 rtx basex, basey; | 2238 rtx basex, basey; |
2174 rtx moffsetx, moffsety; | 2239 rtx moffsetx, moffsety; |
2261 || (CONSTANT_P (basex) && REG_P (basey) | 2326 || (CONSTANT_P (basex) && REG_P (basey) |
2262 && REGNO_PTR_FRAME_P (REGNO (basey))) | 2327 && REGNO_PTR_FRAME_P (REGNO (basey))) |
2263 || (CONSTANT_P (basey) && REG_P (basex) | 2328 || (CONSTANT_P (basey) && REG_P (basex) |
2264 && REGNO_PTR_FRAME_P (REGNO (basex)))); | 2329 && REGNO_PTR_FRAME_P (REGNO (basex)))); |
2265 | 2330 |
2331 /* Offset based disambiguation not appropriate for loop invariant */ | |
2332 if (loop_invariant) | |
2333 return 0; | |
2334 | |
2266 sizex = (!MEM_P (rtlx) ? (int) GET_MODE_SIZE (GET_MODE (rtlx)) | 2335 sizex = (!MEM_P (rtlx) ? (int) GET_MODE_SIZE (GET_MODE (rtlx)) |
2267 : MEM_SIZE (rtlx) ? INTVAL (MEM_SIZE (rtlx)) | 2336 : MEM_SIZE (rtlx) ? INTVAL (MEM_SIZE (rtlx)) |
2268 : -1); | 2337 : -1); |
2269 sizey = (!MEM_P (rtly) ? (int) GET_MODE_SIZE (GET_MODE (rtly)) | 2338 sizey = (!MEM_P (rtly) ? (int) GET_MODE_SIZE (GET_MODE (rtly)) |
2270 : MEM_SIZE (rtly) ? INTVAL (MEM_SIZE (rtly)) : | 2339 : MEM_SIZE (rtly) ? INTVAL (MEM_SIZE (rtly)) : |
2295 /* If we don't know the size of the lower-offset value, we can't tell | 2364 /* If we don't know the size of the lower-offset value, we can't tell |
2296 if they conflict. Otherwise, we do the test. */ | 2365 if they conflict. Otherwise, we do the test. */ |
2297 return sizex >= 0 && offsety >= offsetx + sizex; | 2366 return sizex >= 0 && offsety >= offsetx + sizex; |
2298 } | 2367 } |
2299 | 2368 |
2300 /* True dependence: X is read after store in MEM takes place. */ | 2369 /* Helper for true_dependence and canon_true_dependence. |
2301 | 2370 Checks for true dependence: X is read after store in MEM takes place. |
2302 int | 2371 |
2303 true_dependence (const_rtx mem, enum machine_mode mem_mode, const_rtx x, | 2372 VARIES is the function that should be used as rtx_varies function. |
2304 bool (*varies) (const_rtx, bool)) | 2373 |
2305 { | 2374 If MEM_CANONICALIZED is FALSE, then X_ADDR and MEM_ADDR should be |
2306 rtx x_addr, mem_addr; | 2375 NULL_RTX, and the canonical addresses of MEM and X are both computed |
2376 here. If MEM_CANONICALIZED, then MEM must be already canonicalized. | |
2377 | |
2378 If X_ADDR is non-NULL, it is used in preference of XEXP (x, 0). | |
2379 | |
2380 Returns 1 if there is a true dependence, 0 otherwise. */ | |
2381 | |
2382 static int | |
2383 true_dependence_1 (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr, | |
2384 const_rtx x, rtx x_addr, bool (*varies) (const_rtx, bool), | |
2385 bool mem_canonicalized) | |
2386 { | |
2307 rtx base; | 2387 rtx base; |
2308 int ret; | 2388 int ret; |
2389 | |
2390 gcc_checking_assert (mem_canonicalized ? (mem_addr != NULL_RTX) | |
2391 : (mem_addr == NULL_RTX && x_addr == NULL_RTX)); | |
2309 | 2392 |
2310 if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) | 2393 if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) |
2311 return 1; | 2394 return 1; |
2312 | 2395 |
2313 /* (mem:BLK (scratch)) is a special mechanism to conflict with everything. | 2396 /* (mem:BLK (scratch)) is a special mechanism to conflict with everything. |
2330 potentially overlap), we cannot easily tell from the addresses | 2413 potentially overlap), we cannot easily tell from the addresses |
2331 whether the references overlap. */ | 2414 whether the references overlap. */ |
2332 if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x)) | 2415 if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x)) |
2333 return 1; | 2416 return 1; |
2334 | 2417 |
2335 if (mem_mode == VOIDmode) | 2418 if (! mem_addr) |
2336 mem_mode = GET_MODE (mem); | 2419 { |
2420 mem_addr = XEXP (mem, 0); | |
2421 if (mem_mode == VOIDmode) | |
2422 mem_mode = GET_MODE (mem); | |
2423 } | |
2424 | |
2425 if (! x_addr) | |
2426 { | |
2427 x_addr = XEXP (x, 0); | |
2428 if (!((GET_CODE (x_addr) == VALUE | |
2429 && GET_CODE (mem_addr) != VALUE | |
2430 && reg_mentioned_p (x_addr, mem_addr)) | |
2431 || (GET_CODE (x_addr) != VALUE | |
2432 && GET_CODE (mem_addr) == VALUE | |
2433 && reg_mentioned_p (mem_addr, x_addr)))) | |
2434 { | |
2435 x_addr = get_addr (x_addr); | |
2436 if (! mem_canonicalized) | |
2437 mem_addr = get_addr (mem_addr); | |
2438 } | |
2439 } | |
2440 | |
2441 base = find_base_term (x_addr); | |
2442 if (base && (GET_CODE (base) == LABEL_REF | |
2443 || (GET_CODE (base) == SYMBOL_REF | |
2444 && CONSTANT_POOL_ADDRESS_P (base)))) | |
2445 return 0; | |
2446 | |
2447 if (! base_alias_check (x_addr, mem_addr, GET_MODE (x), mem_mode)) | |
2448 return 0; | |
2449 | |
2450 x_addr = canon_rtx (x_addr); | |
2451 if (!mem_canonicalized) | |
2452 mem_addr = canon_rtx (mem_addr); | |
2453 | |
2454 if ((ret = memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr, | |
2455 SIZE_FOR_MODE (x), x_addr, 0)) != -1) | |
2456 return ret; | |
2457 | |
2458 if (DIFFERENT_ALIAS_SETS_P (x, mem)) | |
2459 return 0; | |
2460 | |
2461 if (nonoverlapping_memrefs_p (mem, x, false)) | |
2462 return 0; | |
2463 | |
2464 if (aliases_everything_p (x)) | |
2465 return 1; | |
2466 | |
2467 /* We cannot use aliases_everything_p to test MEM, since we must look | |
2468 at MEM_ADDR, rather than XEXP (mem, 0). */ | |
2469 if (GET_CODE (mem_addr) == AND) | |
2470 return 1; | |
2471 | |
2472 /* ??? In true_dependence we also allow BLKmode to alias anything. Why | |
2473 don't we do this in anti_dependence and output_dependence? */ | |
2474 if (mem_mode == BLKmode || GET_MODE (x) == BLKmode) | |
2475 return 1; | |
2476 | |
2477 if (fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr, varies)) | |
2478 return 0; | |
2479 | |
2480 return rtx_refs_may_alias_p (x, mem, true); | |
2481 } | |
2482 | |
2483 /* True dependence: X is read after store in MEM takes place. */ | |
2484 | |
2485 int | |
2486 true_dependence (const_rtx mem, enum machine_mode mem_mode, const_rtx x, | |
2487 bool (*varies) (const_rtx, bool)) | |
2488 { | |
2489 return true_dependence_1 (mem, mem_mode, NULL_RTX, | |
2490 x, NULL_RTX, varies, | |
2491 /*mem_canonicalized=*/false); | |
2492 } | |
2493 | |
2494 /* Canonical true dependence: X is read after store in MEM takes place. | |
2495 Variant of true_dependence which assumes MEM has already been | |
2496 canonicalized (hence we no longer do that here). | |
2497 The mem_addr argument has been added, since true_dependence_1 computed | |
2498 this value prior to canonicalizing. */ | |
2499 | |
2500 int | |
2501 canon_true_dependence (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr, | |
2502 const_rtx x, rtx x_addr, bool (*varies) (const_rtx, bool)) | |
2503 { | |
2504 return true_dependence_1 (mem, mem_mode, mem_addr, | |
2505 x, x_addr, varies, | |
2506 /*mem_canonicalized=*/true); | |
2507 } | |
2508 | |
2509 /* Returns nonzero if a write to X might alias a previous read from | |
2510 (or, if WRITEP is nonzero, a write to) MEM. */ | |
2511 | |
2512 static int | |
2513 write_dependence_p (const_rtx mem, const_rtx x, int writep) | |
2514 { | |
2515 rtx x_addr, mem_addr; | |
2516 const_rtx fixed_scalar; | |
2517 rtx base; | |
2518 int ret; | |
2519 | |
2520 if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) | |
2521 return 1; | |
2522 | |
2523 /* (mem:BLK (scratch)) is a special mechanism to conflict with everything. | |
2524 This is used in epilogue deallocation functions. */ | |
2525 if (GET_MODE (x) == BLKmode && GET_CODE (XEXP (x, 0)) == SCRATCH) | |
2526 return 1; | |
2527 if (GET_MODE (mem) == BLKmode && GET_CODE (XEXP (mem, 0)) == SCRATCH) | |
2528 return 1; | |
2529 if (MEM_ALIAS_SET (x) == ALIAS_SET_MEMORY_BARRIER | |
2530 || MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER) | |
2531 return 1; | |
2532 | |
2533 /* A read from read-only memory can't conflict with read-write memory. */ | |
2534 if (!writep && MEM_READONLY_P (mem)) | |
2535 return 0; | |
2536 | |
2537 /* If we have MEMs refering to different address spaces (which can | |
2538 potentially overlap), we cannot easily tell from the addresses | |
2539 whether the references overlap. */ | |
2540 if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x)) | |
2541 return 1; | |
2337 | 2542 |
2338 x_addr = XEXP (x, 0); | 2543 x_addr = XEXP (x, 0); |
2339 mem_addr = XEXP (mem, 0); | 2544 mem_addr = XEXP (mem, 0); |
2340 if (!((GET_CODE (x_addr) == VALUE | 2545 if (!((GET_CODE (x_addr) == VALUE |
2341 && GET_CODE (mem_addr) != VALUE | 2546 && GET_CODE (mem_addr) != VALUE |
2346 { | 2551 { |
2347 x_addr = get_addr (x_addr); | 2552 x_addr = get_addr (x_addr); |
2348 mem_addr = get_addr (mem_addr); | 2553 mem_addr = get_addr (mem_addr); |
2349 } | 2554 } |
2350 | 2555 |
2351 base = find_base_term (x_addr); | 2556 if (! writep) |
2352 if (base && (GET_CODE (base) == LABEL_REF | 2557 { |
2353 || (GET_CODE (base) == SYMBOL_REF | 2558 base = find_base_term (mem_addr); |
2354 && CONSTANT_POOL_ADDRESS_P (base)))) | 2559 if (base && (GET_CODE (base) == LABEL_REF |
2355 return 0; | 2560 || (GET_CODE (base) == SYMBOL_REF |
2356 | 2561 && CONSTANT_POOL_ADDRESS_P (base)))) |
2357 if (! base_alias_check (x_addr, mem_addr, GET_MODE (x), mem_mode)) | 2562 return 0; |
2563 } | |
2564 | |
2565 if (! base_alias_check (x_addr, mem_addr, GET_MODE (x), | |
2566 GET_MODE (mem))) | |
2358 return 0; | 2567 return 0; |
2359 | 2568 |
2360 x_addr = canon_rtx (x_addr); | 2569 x_addr = canon_rtx (x_addr); |
2361 mem_addr = canon_rtx (mem_addr); | 2570 mem_addr = canon_rtx (mem_addr); |
2362 | 2571 |
2363 if ((ret = memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr, | 2572 if ((ret = memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr, |
2364 SIZE_FOR_MODE (x), x_addr, 0)) != -1) | 2573 SIZE_FOR_MODE (x), x_addr, 0)) != -1) |
2365 return ret; | 2574 return ret; |
2366 | 2575 |
2367 if (DIFFERENT_ALIAS_SETS_P (x, mem)) | 2576 if (nonoverlapping_memrefs_p (x, mem, false)) |
2368 return 0; | 2577 return 0; |
2369 | 2578 |
2370 if (nonoverlapping_memrefs_p (mem, x)) | 2579 fixed_scalar |
2580 = fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr, | |
2581 rtx_addr_varies_p); | |
2582 | |
2583 if ((fixed_scalar == mem && !aliases_everything_p (x)) | |
2584 || (fixed_scalar == x && !aliases_everything_p (mem))) | |
2371 return 0; | 2585 return 0; |
2372 | 2586 |
2373 if (aliases_everything_p (x)) | 2587 return rtx_refs_may_alias_p (x, mem, false); |
2374 return 1; | 2588 } |
2375 | 2589 |
2376 /* We cannot use aliases_everything_p to test MEM, since we must look | 2590 /* Anti dependence: X is written after read in MEM takes place. */ |
2377 at MEM_MODE, rather than GET_MODE (MEM). */ | |
2378 if (mem_mode == QImode || GET_CODE (mem_addr) == AND) | |
2379 return 1; | |
2380 | |
2381 /* In true_dependence we also allow BLKmode to alias anything. Why | |
2382 don't we do this in anti_dependence and output_dependence? */ | |
2383 if (mem_mode == BLKmode || GET_MODE (x) == BLKmode) | |
2384 return 1; | |
2385 | |
2386 if (fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr, varies)) | |
2387 return 0; | |
2388 | |
2389 return rtx_refs_may_alias_p (x, mem, true); | |
2390 } | |
2391 | |
2392 /* Canonical true dependence: X is read after store in MEM takes place. | |
2393 Variant of true_dependence which assumes MEM has already been | |
2394 canonicalized (hence we no longer do that here). | |
2395 The mem_addr argument has been added, since true_dependence computed | |
2396 this value prior to canonicalizing. | |
2397 If x_addr is non-NULL, it is used in preference of XEXP (x, 0). */ | |
2398 | 2591 |
2399 int | 2592 int |
2400 canon_true_dependence (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr, | 2593 anti_dependence (const_rtx mem, const_rtx x) |
2401 const_rtx x, rtx x_addr, bool (*varies) (const_rtx, bool)) | 2594 { |
2402 { | 2595 return write_dependence_p (mem, x, /*writep=*/0); |
2403 int ret; | 2596 } |
2597 | |
2598 /* Output dependence: X is written after store in MEM takes place. */ | |
2599 | |
2600 int | |
2601 output_dependence (const_rtx mem, const_rtx x) | |
2602 { | |
2603 return write_dependence_p (mem, x, /*writep=*/1); | |
2604 } | |
2605 | |
2606 | |
2607 | |
2608 /* Check whether X may be aliased with MEM. Don't do offset-based | |
2609 memory disambiguation & TBAA. */ | |
2610 int | |
2611 may_alias_p (const_rtx mem, const_rtx x) | |
2612 { | |
2613 rtx x_addr, mem_addr; | |
2404 | 2614 |
2405 if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) | 2615 if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) |
2406 return 1; | 2616 return 1; |
2407 | 2617 |
2408 /* (mem:BLK (scratch)) is a special mechanism to conflict with everything. | 2618 /* ??? In true_dependence we also allow BLKmode to alias anything. */ |
2409 This is used in epilogue deallocation functions. */ | 2619 if (GET_MODE (mem) == BLKmode || GET_MODE (x) == BLKmode) |
2410 if (GET_MODE (x) == BLKmode && GET_CODE (XEXP (x, 0)) == SCRATCH) | 2620 return 1; |
2411 return 1; | 2621 |
2412 if (GET_MODE (mem) == BLKmode && GET_CODE (XEXP (mem, 0)) == SCRATCH) | |
2413 return 1; | |
2414 if (MEM_ALIAS_SET (x) == ALIAS_SET_MEMORY_BARRIER | 2622 if (MEM_ALIAS_SET (x) == ALIAS_SET_MEMORY_BARRIER |
2415 || MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER) | 2623 || MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER) |
2416 return 1; | 2624 return 1; |
2417 | 2625 |
2418 /* Read-only memory is by definition never modified, and therefore can't | 2626 /* Read-only memory is by definition never modified, and therefore can't |
2419 conflict with anything. We don't expect to find read-only set on MEM, | 2627 conflict with anything. We don't expect to find read-only set on MEM, |
2420 but stupid user tricks can produce them, so don't die. */ | 2628 but stupid user tricks can produce them, so don't die. */ |
2421 if (MEM_READONLY_P (x)) | 2629 if (MEM_READONLY_P (x)) |
2422 return 0; | |
2423 | |
2424 /* If we have MEMs refering to different address spaces (which can | |
2425 potentially overlap), we cannot easily tell from the addresses | |
2426 whether the references overlap. */ | |
2427 if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x)) | |
2428 return 1; | |
2429 | |
2430 if (! x_addr) | |
2431 { | |
2432 x_addr = XEXP (x, 0); | |
2433 if (!((GET_CODE (x_addr) == VALUE | |
2434 && GET_CODE (mem_addr) != VALUE | |
2435 && reg_mentioned_p (x_addr, mem_addr)) | |
2436 || (GET_CODE (x_addr) != VALUE | |
2437 && GET_CODE (mem_addr) == VALUE | |
2438 && reg_mentioned_p (mem_addr, x_addr)))) | |
2439 x_addr = get_addr (x_addr); | |
2440 } | |
2441 | |
2442 if (! base_alias_check (x_addr, mem_addr, GET_MODE (x), mem_mode)) | |
2443 return 0; | |
2444 | |
2445 x_addr = canon_rtx (x_addr); | |
2446 if ((ret = memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr, | |
2447 SIZE_FOR_MODE (x), x_addr, 0)) != -1) | |
2448 return ret; | |
2449 | |
2450 if (DIFFERENT_ALIAS_SETS_P (x, mem)) | |
2451 return 0; | |
2452 | |
2453 if (nonoverlapping_memrefs_p (x, mem)) | |
2454 return 0; | |
2455 | |
2456 if (aliases_everything_p (x)) | |
2457 return 1; | |
2458 | |
2459 /* We cannot use aliases_everything_p to test MEM, since we must look | |
2460 at MEM_MODE, rather than GET_MODE (MEM). */ | |
2461 if (mem_mode == QImode || GET_CODE (mem_addr) == AND) | |
2462 return 1; | |
2463 | |
2464 /* In true_dependence we also allow BLKmode to alias anything. Why | |
2465 don't we do this in anti_dependence and output_dependence? */ | |
2466 if (mem_mode == BLKmode || GET_MODE (x) == BLKmode) | |
2467 return 1; | |
2468 | |
2469 if (fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr, varies)) | |
2470 return 0; | |
2471 | |
2472 return rtx_refs_may_alias_p (x, mem, true); | |
2473 } | |
2474 | |
2475 /* Returns nonzero if a write to X might alias a previous read from | |
2476 (or, if WRITEP is nonzero, a write to) MEM. */ | |
2477 | |
2478 static int | |
2479 write_dependence_p (const_rtx mem, const_rtx x, int writep) | |
2480 { | |
2481 rtx x_addr, mem_addr; | |
2482 const_rtx fixed_scalar; | |
2483 rtx base; | |
2484 int ret; | |
2485 | |
2486 if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) | |
2487 return 1; | |
2488 | |
2489 /* (mem:BLK (scratch)) is a special mechanism to conflict with everything. | |
2490 This is used in epilogue deallocation functions. */ | |
2491 if (GET_MODE (x) == BLKmode && GET_CODE (XEXP (x, 0)) == SCRATCH) | |
2492 return 1; | |
2493 if (GET_MODE (mem) == BLKmode && GET_CODE (XEXP (mem, 0)) == SCRATCH) | |
2494 return 1; | |
2495 if (MEM_ALIAS_SET (x) == ALIAS_SET_MEMORY_BARRIER | |
2496 || MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER) | |
2497 return 1; | |
2498 | |
2499 /* A read from read-only memory can't conflict with read-write memory. */ | |
2500 if (!writep && MEM_READONLY_P (mem)) | |
2501 return 0; | 2630 return 0; |
2502 | 2631 |
2503 /* If we have MEMs refering to different address spaces (which can | 2632 /* If we have MEMs refering to different address spaces (which can |
2504 potentially overlap), we cannot easily tell from the addresses | 2633 potentially overlap), we cannot easily tell from the addresses |
2505 whether the references overlap. */ | 2634 whether the references overlap. */ |
2517 { | 2646 { |
2518 x_addr = get_addr (x_addr); | 2647 x_addr = get_addr (x_addr); |
2519 mem_addr = get_addr (mem_addr); | 2648 mem_addr = get_addr (mem_addr); |
2520 } | 2649 } |
2521 | 2650 |
2522 if (! writep) | 2651 if (! base_alias_check (x_addr, mem_addr, GET_MODE (x), GET_MODE (mem_addr))) |
2523 { | |
2524 base = find_base_term (mem_addr); | |
2525 if (base && (GET_CODE (base) == LABEL_REF | |
2526 || (GET_CODE (base) == SYMBOL_REF | |
2527 && CONSTANT_POOL_ADDRESS_P (base)))) | |
2528 return 0; | |
2529 } | |
2530 | |
2531 if (! base_alias_check (x_addr, mem_addr, GET_MODE (x), | |
2532 GET_MODE (mem))) | |
2533 return 0; | 2652 return 0; |
2534 | 2653 |
2535 x_addr = canon_rtx (x_addr); | 2654 x_addr = canon_rtx (x_addr); |
2536 mem_addr = canon_rtx (mem_addr); | 2655 mem_addr = canon_rtx (mem_addr); |
2537 | 2656 |
2538 if ((ret = memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr, | 2657 if (nonoverlapping_memrefs_p (mem, x, true)) |
2539 SIZE_FOR_MODE (x), x_addr, 0)) != -1) | |
2540 return ret; | |
2541 | |
2542 if (nonoverlapping_memrefs_p (x, mem)) | |
2543 return 0; | 2658 return 0; |
2544 | 2659 |
2545 fixed_scalar | 2660 if (aliases_everything_p (x)) |
2546 = fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr, | 2661 return 1; |
2547 rtx_addr_varies_p); | 2662 |
2548 | 2663 /* We cannot use aliases_everything_p to test MEM, since we must look |
2549 if ((fixed_scalar == mem && !aliases_everything_p (x)) | 2664 at MEM_ADDR, rather than XEXP (mem, 0). */ |
2550 || (fixed_scalar == x && !aliases_everything_p (mem))) | 2665 if (GET_CODE (mem_addr) == AND) |
2666 return 1; | |
2667 | |
2668 if (fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr, | |
2669 rtx_addr_varies_p)) | |
2551 return 0; | 2670 return 0; |
2552 | 2671 |
2672 /* TBAA not valid for loop_invarint */ | |
2553 return rtx_refs_may_alias_p (x, mem, false); | 2673 return rtx_refs_may_alias_p (x, mem, false); |
2554 } | 2674 } |
2555 | |
2556 /* Anti dependence: X is written after read in MEM takes place. */ | |
2557 | |
2558 int | |
2559 anti_dependence (const_rtx mem, const_rtx x) | |
2560 { | |
2561 return write_dependence_p (mem, x, /*writep=*/0); | |
2562 } | |
2563 | |
2564 /* Output dependence: X is written after store in MEM takes place. */ | |
2565 | |
2566 int | |
2567 output_dependence (const_rtx mem, const_rtx x) | |
2568 { | |
2569 return write_dependence_p (mem, x, /*writep=*/1); | |
2570 } | |
2571 | |
2572 | 2675 |
2573 void | 2676 void |
2574 init_alias_target (void) | 2677 init_alias_target (void) |
2575 { | 2678 { |
2576 int i; | 2679 int i; |
2590 = gen_rtx_ADDRESS (Pmode, stack_pointer_rtx); | 2693 = gen_rtx_ADDRESS (Pmode, stack_pointer_rtx); |
2591 static_reg_base_value[ARG_POINTER_REGNUM] | 2694 static_reg_base_value[ARG_POINTER_REGNUM] |
2592 = gen_rtx_ADDRESS (Pmode, arg_pointer_rtx); | 2695 = gen_rtx_ADDRESS (Pmode, arg_pointer_rtx); |
2593 static_reg_base_value[FRAME_POINTER_REGNUM] | 2696 static_reg_base_value[FRAME_POINTER_REGNUM] |
2594 = gen_rtx_ADDRESS (Pmode, frame_pointer_rtx); | 2697 = gen_rtx_ADDRESS (Pmode, frame_pointer_rtx); |
2595 #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM | 2698 #if !HARD_FRAME_POINTER_IS_FRAME_POINTER |
2596 static_reg_base_value[HARD_FRAME_POINTER_REGNUM] | 2699 static_reg_base_value[HARD_FRAME_POINTER_REGNUM] |
2597 = gen_rtx_ADDRESS (Pmode, hard_frame_pointer_rtx); | 2700 = gen_rtx_ADDRESS (Pmode, hard_frame_pointer_rtx); |
2598 #endif | 2701 #endif |
2599 } | 2702 } |
2600 | 2703 |
2637 rtx insn; | 2740 rtx insn; |
2638 | 2741 |
2639 timevar_push (TV_ALIAS_ANALYSIS); | 2742 timevar_push (TV_ALIAS_ANALYSIS); |
2640 | 2743 |
2641 reg_known_value_size = maxreg - FIRST_PSEUDO_REGISTER; | 2744 reg_known_value_size = maxreg - FIRST_PSEUDO_REGISTER; |
2642 reg_known_value = GGC_CNEWVEC (rtx, reg_known_value_size); | 2745 reg_known_value = ggc_alloc_cleared_vec_rtx (reg_known_value_size); |
2643 reg_known_equiv_p = XCNEWVEC (bool, reg_known_value_size); | 2746 reg_known_equiv_p = XCNEWVEC (bool, reg_known_value_size); |
2644 | 2747 |
2645 /* If we have memory allocated from the previous run, use it. */ | 2748 /* If we have memory allocated from the previous run, use it. */ |
2646 if (old_reg_base_value) | 2749 if (old_reg_base_value) |
2647 reg_base_value = old_reg_base_value; | 2750 reg_base_value = old_reg_base_value; |
2808 free (reg_seen); | 2911 free (reg_seen); |
2809 reg_seen = 0; | 2912 reg_seen = 0; |
2810 timevar_pop (TV_ALIAS_ANALYSIS); | 2913 timevar_pop (TV_ALIAS_ANALYSIS); |
2811 } | 2914 } |
2812 | 2915 |
2916 /* Equate REG_BASE_VALUE (reg1) to REG_BASE_VALUE (reg2). | |
2917 Special API for var-tracking pass purposes. */ | |
2918 | |
2919 void | |
2920 vt_equate_reg_base_value (const_rtx reg1, const_rtx reg2) | |
2921 { | |
2922 VEC_replace (rtx, reg_base_value, REGNO (reg1), REG_BASE_VALUE (reg2)); | |
2923 } | |
2924 | |
2813 void | 2925 void |
2814 end_alias_analysis (void) | 2926 end_alias_analysis (void) |
2815 { | 2927 { |
2816 old_reg_base_value = reg_base_value; | 2928 old_reg_base_value = reg_base_value; |
2817 ggc_free (reg_known_value); | 2929 ggc_free (reg_known_value); |