00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "config.h"
00024 #include "system.h"
00025 #include "coretypes.h"
00026 #include "tm.h"
00027 #include "rtl.h"
00028 #include "tree.h"
00029 #include "tm_p.h"
00030 #include "function.h"
00031 #include "alias.h"
00032 #include "emit-rtl.h"
00033 #include "regs.h"
00034 #include "hard-reg-set.h"
00035 #include "basic-block.h"
00036 #include "flags.h"
00037 #include "output.h"
00038 #include "toplev.h"
00039 #include "cselib.h"
00040 #include "splay-tree.h"
00041 #include "ggc.h"
00042 #include "langhooks.h"
00043 #include "timevar.h"
00044 #include "target.h"
00045 #include "cgraph.h"
00046 #include "varray.h"
00047 #include "tree-pass.h"
00048 #include "ipa-type-escape.h"
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 struct alias_set_entry GTY(())
00132 {
00133
00134 HOST_WIDE_INT alias_set;
00135
00136
00137
00138
00139
00140
00141
00142
00143 splay_tree GTY((param1_is (int), param2_is (int))) children;
00144
00145
00146
00147 int has_zero_child;
00148 };
00149 typedef struct alias_set_entry *alias_set_entry;
00150
00151 static int rtx_equal_for_memref_p (rtx, rtx);
00152 static rtx find_symbolic_term (rtx);
00153 static int memrefs_conflict_p (int, rtx, int, rtx, HOST_WIDE_INT);
00154 static void record_set (rtx, rtx, void *);
00155 static int base_alias_check (rtx, rtx, enum machine_mode,
00156 enum machine_mode);
00157 static rtx find_base_value (rtx);
00158 static int mems_in_disjoint_alias_sets_p (rtx, rtx);
00159 static int insert_subset_children (splay_tree_node, void*);
00160 static tree find_base_decl (tree);
00161 static alias_set_entry get_alias_set_entry (HOST_WIDE_INT);
00162 static rtx fixed_scalar_and_varying_struct_p (rtx, rtx, rtx, rtx,
00163 int (*) (rtx, int));
00164 static int aliases_everything_p (rtx);
00165 static bool nonoverlapping_component_refs_p (tree, tree);
00166 static tree decl_for_component_ref (tree);
00167 static rtx adjust_offset_for_component_ref (tree, rtx);
00168 static int nonoverlapping_memrefs_p (rtx, rtx);
00169 static int write_dependence_p (rtx, rtx, int);
00170
00171 static void memory_modified_1 (rtx, rtx, void *);
00172 static void record_alias_subset (HOST_WIDE_INT, HOST_WIDE_INT);
00173
00174
00175
00176
00177 #define SIZE_FOR_MODE(X) (GET_MODE_SIZE (GET_MODE (X)))
00178
00179
00180
00181
00182
00183 #define DIFFERENT_ALIAS_SETS_P(MEM1, MEM2) \
00184 mems_in_disjoint_alias_sets_p (MEM1, MEM2)
00185
00186
00187
00188 #define MAX_ALIAS_LOOP_PASSES 10
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 static GTY(()) VEC(rtx,gc) *reg_base_value;
00210 static rtx *new_reg_base_value;
00211
00212
00213
00214
00215 static GTY((deletable)) VEC(rtx,gc) *old_reg_base_value;
00216
00217
00218
00219 static GTY (()) rtx static_reg_base_value[FIRST_PSEUDO_REGISTER];
00220
00221 #define REG_BASE_VALUE(X) \
00222 (REGNO (X) < VEC_length (rtx, reg_base_value) \
00223 ? VEC_index (rtx, reg_base_value, REGNO (X)) : 0)
00224
00225
00226
00227
00228 static GTY((length("reg_known_value_size"))) rtx *reg_known_value;
00229
00230
00231 static GTY(()) unsigned int reg_known_value_size;
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 static bool *reg_known_equiv_p;
00246
00247
00248
00249 static bool copying_arguments;
00250
00251 DEF_VEC_P(alias_set_entry);
00252 DEF_VEC_ALLOC_P(alias_set_entry,gc);
00253
00254
00255 static GTY (()) VEC(alias_set_entry,gc) *alias_sets;
00256
00257
00258
00259
00260 static inline alias_set_entry
00261 get_alias_set_entry (HOST_WIDE_INT alias_set)
00262 {
00263 return VEC_index (alias_set_entry, alias_sets, alias_set);
00264 }
00265
00266
00267
00268
00269 static inline int
00270 mems_in_disjoint_alias_sets_p (rtx mem1, rtx mem2)
00271 {
00272
00273
00274
00275
00276
00277
00278
00279 gcc_assert (flag_strict_aliasing
00280 || (!MEM_ALIAS_SET (mem1) && !MEM_ALIAS_SET (mem2)));
00281
00282 return ! alias_sets_conflict_p (MEM_ALIAS_SET (mem1), MEM_ALIAS_SET (mem2));
00283 }
00284
00285
00286
00287
00288 static int
00289 insert_subset_children (splay_tree_node node, void *data)
00290 {
00291 splay_tree_insert ((splay_tree) data, node->key, node->value);
00292
00293 return 0;
00294 }
00295
00296
00297
00298 int
00299 alias_sets_conflict_p (HOST_WIDE_INT set1, HOST_WIDE_INT set2)
00300 {
00301 alias_set_entry ase;
00302
00303
00304
00305 if (set1 == 0 || set2 == 0
00306
00307 || set1 == set2)
00308 return 1;
00309
00310
00311 ase = get_alias_set_entry (set1);
00312 if (ase != 0
00313 && (ase->has_zero_child
00314 || splay_tree_lookup (ase->children,
00315 (splay_tree_key) set2)))
00316 return 1;
00317
00318
00319 ase = get_alias_set_entry (set2);
00320 if (ase != 0
00321 && (ase->has_zero_child
00322 || splay_tree_lookup (ase->children,
00323 (splay_tree_key) set1)))
00324 return 1;
00325
00326
00327
00328 return 0;
00329 }
00330
00331
00332
00333
00334 int
00335 alias_sets_might_conflict_p (HOST_WIDE_INT set1, HOST_WIDE_INT set2)
00336 {
00337 if (set1 == 0 || set2 == 0 || set1 == set2)
00338 return 1;
00339
00340 return 0;
00341 }
00342
00343
00344
00345
00346
00347
00348
00349 int
00350 objects_must_conflict_p (tree t1, tree t2)
00351 {
00352 HOST_WIDE_INT set1, set2;
00353
00354
00355
00356
00357 if (t1 == 0 && t2 == 0)
00358 return 0;
00359
00360
00361 if (t1 == t2
00362
00363 || (t1 != 0 && TYPE_VOLATILE (t1) && t2 != 0 && TYPE_VOLATILE (t2)))
00364 return 1;
00365
00366 set1 = t1 ? get_alias_set (t1) : 0;
00367 set2 = t2 ? get_alias_set (t2) : 0;
00368
00369
00370
00371
00372
00373
00374 return set1 == 0 || set2 == 0 || set1 == set2;
00375 }
00376
00377
00378
00379
00380
00381
00382 static tree
00383 find_base_decl (tree t)
00384 {
00385 tree d0, d1;
00386
00387 if (t == 0 || t == error_mark_node || ! POINTER_TYPE_P (TREE_TYPE (t)))
00388 return 0;
00389
00390
00391
00392 if (DECL_P (t))
00393 {
00394 if (TREE_CODE (t) == VAR_DECL && DECL_BASED_ON_RESTRICT_P (t))
00395 t = DECL_GET_RESTRICT_BASE (t);
00396 return t;
00397 }
00398
00399
00400
00401
00402 switch (TREE_CODE_CLASS (TREE_CODE (t)))
00403 {
00404 case tcc_unary:
00405 return find_base_decl (TREE_OPERAND (t, 0));
00406
00407 case tcc_binary:
00408
00409 d0 = find_base_decl (TREE_OPERAND (t, 0));
00410 d1 = find_base_decl (TREE_OPERAND (t, 1));
00411 if (d0 == d1)
00412 return d0;
00413 else if (d0 == 0)
00414 return d1;
00415 else if (d1 == 0)
00416 return d0;
00417 else
00418 return 0;
00419
00420 default:
00421 return 0;
00422 }
00423 }
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435 bool
00436 component_uses_parent_alias_set (tree t)
00437 {
00438 while (1)
00439 {
00440
00441 if (!handled_component_p (t))
00442 return false;
00443
00444 switch (TREE_CODE (t))
00445 {
00446 case COMPONENT_REF:
00447 if (DECL_NONADDRESSABLE_P (TREE_OPERAND (t, 1)))
00448 return true;
00449 break;
00450
00451 case ARRAY_REF:
00452 case ARRAY_RANGE_REF:
00453 if (TYPE_NONALIASED_COMPONENT (TREE_TYPE (TREE_OPERAND (t, 0))))
00454 return true;
00455 break;
00456
00457 case REALPART_EXPR:
00458 case IMAGPART_EXPR:
00459 break;
00460
00461 default:
00462
00463 return true;
00464 }
00465
00466 t = TREE_OPERAND (t, 0);
00467 if (get_alias_set (TREE_TYPE (t)) == 0)
00468 return true;
00469 }
00470 }
00471
00472
00473
00474
00475 HOST_WIDE_INT
00476 get_alias_set (tree t)
00477 {
00478 HOST_WIDE_INT set;
00479
00480
00481
00482
00483 if (! flag_strict_aliasing || t == error_mark_node
00484 || (! TYPE_P (t)
00485 && (TREE_TYPE (t) == 0 || TREE_TYPE (t) == error_mark_node)))
00486 return 0;
00487
00488
00489
00490
00491
00492
00493 if (! TYPE_P (t))
00494 {
00495 tree inner = t;
00496
00497
00498
00499 STRIP_NOPS (t);
00500 set = lang_hooks.get_alias_set (t);
00501 if (set != -1)
00502 return set;
00503
00504
00505
00506 while (handled_component_p (inner))
00507 {
00508 inner = TREE_OPERAND (inner, 0);
00509 STRIP_NOPS (inner);
00510 }
00511
00512
00513 if (INDIRECT_REF_P (inner))
00514 {
00515 tree decl = find_base_decl (TREE_OPERAND (inner, 0));
00516
00517 if (decl && DECL_POINTER_ALIAS_SET_KNOWN_P (decl))
00518 {
00519
00520 if (DECL_POINTER_ALIAS_SET (decl) == -2)
00521 {
00522 tree pointed_to_type = TREE_TYPE (TREE_TYPE (decl));
00523
00524
00525
00526
00527
00528
00529
00530
00531 HOST_WIDE_INT pointed_to_alias_set
00532 = get_alias_set (pointed_to_type);
00533
00534 if (pointed_to_alias_set == 0)
00535
00536 DECL_POINTER_ALIAS_SET (decl) = 0;
00537 else if (AGGREGATE_TYPE_P (pointed_to_type))
00538
00539
00540
00541
00542
00543
00544
00545
00546 DECL_POINTER_ALIAS_SET (decl)
00547 = pointed_to_alias_set;
00548 else
00549 {
00550 DECL_POINTER_ALIAS_SET (decl) = new_alias_set ();
00551 record_alias_subset (pointed_to_alias_set,
00552 DECL_POINTER_ALIAS_SET (decl));
00553 }
00554 }
00555
00556
00557 return DECL_POINTER_ALIAS_SET (decl);
00558 }
00559
00560
00561
00562
00563 else if (TREE_CODE (TREE_TYPE (inner)) == VOID_TYPE
00564 || (TYPE_REF_CAN_ALIAS_ALL
00565 (TREE_TYPE (TREE_OPERAND (inner, 0)))))
00566 return 0;
00567 }
00568
00569
00570
00571 while (component_uses_parent_alias_set (t))
00572 {
00573 t = TREE_OPERAND (t, 0);
00574 STRIP_NOPS (t);
00575 }
00576
00577
00578
00579
00580 if (TREE_CODE (t) == VAR_DECL
00581 && DECL_RTL_SET_P (t) && MEM_P (DECL_RTL (t)))
00582 return MEM_ALIAS_SET (DECL_RTL (t));
00583
00584
00585 t = TREE_TYPE (t);
00586 }
00587
00588
00589
00590 t = TYPE_MAIN_VARIANT (t);
00591 if (TYPE_ALIAS_SET_KNOWN_P (t))
00592 return TYPE_ALIAS_SET (t);
00593
00594
00595 set = lang_hooks.get_alias_set (t);
00596 if (set != -1)
00597 return set;
00598
00599
00600
00601
00602 else if (TREE_CODE (t) == FUNCTION_TYPE)
00603 set = 0;
00604
00605
00606
00607
00608
00609 else if (TREE_CODE (t) == VECTOR_TYPE)
00610 set = get_alias_set (TREE_TYPE (t));
00611
00612 else
00613
00614 set = new_alias_set ();
00615
00616 TYPE_ALIAS_SET (t) = set;
00617
00618
00619
00620 if (AGGREGATE_TYPE_P (t) || TREE_CODE (t) == COMPLEX_TYPE)
00621 record_component_aliases (t);
00622
00623 return set;
00624 }
00625
00626
00627
00628 HOST_WIDE_INT
00629 new_alias_set (void)
00630 {
00631 if (flag_strict_aliasing)
00632 {
00633 if (alias_sets == 0)
00634 VEC_safe_push (alias_set_entry, gc, alias_sets, 0);
00635 VEC_safe_push (alias_set_entry, gc, alias_sets, 0);
00636 return VEC_length (alias_set_entry, alias_sets) - 1;
00637 }
00638 else
00639 return 0;
00640 }
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655 static void
00656 record_alias_subset (HOST_WIDE_INT superset, HOST_WIDE_INT subset)
00657 {
00658 alias_set_entry superset_entry;
00659 alias_set_entry subset_entry;
00660
00661
00662
00663 if (superset == subset)
00664 return;
00665
00666 gcc_assert (superset);
00667
00668 superset_entry = get_alias_set_entry (superset);
00669 if (superset_entry == 0)
00670 {
00671
00672
00673 superset_entry = ggc_alloc (sizeof (struct alias_set_entry));
00674 superset_entry->alias_set = superset;
00675 superset_entry->children
00676 = splay_tree_new_ggc (splay_tree_compare_ints);
00677 superset_entry->has_zero_child = 0;
00678 VEC_replace (alias_set_entry, alias_sets, superset, superset_entry);
00679 }
00680
00681 if (subset == 0)
00682 superset_entry->has_zero_child = 1;
00683 else
00684 {
00685 subset_entry = get_alias_set_entry (subset);
00686
00687
00688 if (subset_entry)
00689 {
00690 if (subset_entry->has_zero_child)
00691 superset_entry->has_zero_child = 1;
00692
00693 splay_tree_foreach (subset_entry->children, insert_subset_children,
00694 superset_entry->children);
00695 }
00696
00697
00698 splay_tree_insert (superset_entry->children,
00699 (splay_tree_key) subset, 0);
00700 }
00701 }
00702
00703
00704
00705
00706
00707
00708
00709 void
00710 record_component_aliases (tree type)
00711 {
00712 HOST_WIDE_INT superset = get_alias_set (type);
00713 tree field;
00714
00715 if (superset == 0)
00716 return;
00717
00718 switch (TREE_CODE (type))
00719 {
00720 case ARRAY_TYPE:
00721 if (! TYPE_NONALIASED_COMPONENT (type))
00722 record_alias_subset (superset, get_alias_set (TREE_TYPE (type)));
00723 break;
00724
00725 case RECORD_TYPE:
00726 case UNION_TYPE:
00727 case QUAL_UNION_TYPE:
00728
00729 if (TYPE_BINFO (type))
00730 {
00731 int i;
00732 tree binfo, base_binfo;
00733
00734 for (binfo = TYPE_BINFO (type), i = 0;
00735 BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
00736 record_alias_subset (superset,
00737 get_alias_set (BINFO_TYPE (base_binfo)));
00738 }
00739 for (field = TYPE_FIELDS (type); field != 0; field = TREE_CHAIN (field))
00740 if (TREE_CODE (field) == FIELD_DECL && ! DECL_NONADDRESSABLE_P (field))
00741 record_alias_subset (superset, get_alias_set (TREE_TYPE (field)));
00742 break;
00743
00744 case COMPLEX_TYPE:
00745 record_alias_subset (superset, get_alias_set (TREE_TYPE (type)));
00746 break;
00747
00748 default:
00749 break;
00750 }
00751 }
00752
00753
00754
00755
00756 static GTY(()) HOST_WIDE_INT varargs_set = -1;
00757
00758 HOST_WIDE_INT
00759 get_varargs_alias_set (void)
00760 {
00761 #if 1
00762
00763
00764
00765
00766 return 0;
00767 #else
00768 if (varargs_set == -1)
00769 varargs_set = new_alias_set ();
00770
00771 return varargs_set;
00772 #endif
00773 }
00774
00775
00776
00777
00778 static GTY(()) HOST_WIDE_INT frame_set = -1;
00779
00780 HOST_WIDE_INT
00781 get_frame_alias_set (void)
00782 {
00783 if (frame_set == -1)
00784 frame_set = new_alias_set ();
00785
00786 return frame_set;
00787 }
00788
00789
00790
00791 static rtx
00792 find_base_value (rtx src)
00793 {
00794 unsigned int regno;
00795
00796 switch (GET_CODE (src))
00797 {
00798 case SYMBOL_REF:
00799 case LABEL_REF:
00800 return src;
00801
00802 case REG:
00803 regno = REGNO (src);
00804
00805
00806
00807
00808 if (regno < FIRST_PSEUDO_REGISTER && copying_arguments)
00809 return new_reg_base_value[regno];
00810
00811
00812
00813
00814
00815
00816
00817 if ((regno >= FIRST_PSEUDO_REGISTER || fixed_regs[regno])
00818 && regno < VEC_length (rtx, reg_base_value))
00819 {
00820
00821
00822 if (new_reg_base_value && new_reg_base_value[regno]
00823 && REG_N_SETS (regno) == 1)
00824 return new_reg_base_value[regno];
00825
00826 if (VEC_index (rtx, reg_base_value, regno))
00827 return VEC_index (rtx, reg_base_value, regno);
00828 }
00829
00830 return 0;
00831
00832 case MEM:
00833
00834
00835
00836 if (copying_arguments
00837 && (XEXP (src, 0) == arg_pointer_rtx
00838 || (GET_CODE (XEXP (src, 0)) == PLUS
00839 && XEXP (XEXP (src, 0), 0) == arg_pointer_rtx)))
00840 return gen_rtx_ADDRESS (VOIDmode, src);
00841 return 0;
00842
00843 case CONST:
00844 src = XEXP (src, 0);
00845 if (GET_CODE (src) != PLUS && GET_CODE (src) != MINUS)
00846 break;
00847
00848
00849
00850 case PLUS:
00851 case MINUS:
00852 {
00853 rtx temp, src_0 = XEXP (src, 0), src_1 = XEXP (src, 1);
00854
00855
00856
00857 if (REG_P (src_0) && REG_POINTER (src_0))
00858 return find_base_value (src_0);
00859 if (REG_P (src_1) && REG_POINTER (src_1))
00860 return find_base_value (src_1);
00861
00862
00863
00864 if (REG_P (src_0))
00865 {
00866 temp = find_base_value (src_0);
00867 if (temp != 0)
00868 src_0 = temp;
00869 }
00870
00871 if (REG_P (src_1))
00872 {
00873 temp = find_base_value (src_1);
00874 if (temp!= 0)
00875 src_1 = temp;
00876 }
00877
00878
00879
00880
00881 if (src_0 != 0
00882 && (GET_CODE (src_0) == SYMBOL_REF
00883 || GET_CODE (src_0) == LABEL_REF
00884 || (GET_CODE (src_0) == ADDRESS
00885 && GET_MODE (src_0) != VOIDmode)))
00886 return src_0;
00887
00888 if (src_1 != 0
00889 && (GET_CODE (src_1) == SYMBOL_REF
00890 || GET_CODE (src_1) == LABEL_REF
00891 || (GET_CODE (src_1) == ADDRESS
00892 && GET_MODE (src_1) != VOIDmode)))
00893 return src_1;
00894
00895
00896
00897
00898 if (GET_CODE (src_1) == CONST_INT || CONSTANT_P (src_0))
00899 return find_base_value (src_0);
00900 else if (GET_CODE (src_0) == CONST_INT || CONSTANT_P (src_1))
00901 return find_base_value (src_1);
00902
00903 return 0;
00904 }
00905
00906 case LO_SUM:
00907
00908
00909 return find_base_value (XEXP (src, 1));
00910
00911 case AND:
00912
00913
00914 if (GET_CODE (XEXP (src, 1)) == CONST_INT && INTVAL (XEXP (src, 1)) != 0)
00915 return find_base_value (XEXP (src, 0));
00916 return 0;
00917
00918 case TRUNCATE:
00919 if (GET_MODE_SIZE (GET_MODE (src)) < GET_MODE_SIZE (Pmode))
00920 break;
00921
00922 case HIGH:
00923 case PRE_INC:
00924 case PRE_DEC:
00925 case POST_INC:
00926 case POST_DEC:
00927 case PRE_MODIFY:
00928 case POST_MODIFY:
00929 return find_base_value (XEXP (src, 0));
00930
00931 case ZERO_EXTEND:
00932 case SIGN_EXTEND:
00933 {
00934 rtx temp = find_base_value (XEXP (src, 0));
00935
00936 if (temp != 0 && CONSTANT_P (temp))
00937 temp = convert_memory_address (Pmode, temp);
00938
00939 return temp;
00940 }
00941
00942 default:
00943 break;
00944 }
00945
00946 return 0;
00947 }
00948
00949
00950
00951
00952
00953 static char *reg_seen;
00954
00955
00956
00957 static int unique_id;
00958
00959 static void
00960 record_set (rtx dest, rtx set, void *data ATTRIBUTE_UNUSED)
00961 {
00962 unsigned regno;
00963 rtx src;
00964 int n;
00965
00966 if (!REG_P (dest))
00967 return;
00968
00969 regno = REGNO (dest);
00970
00971 gcc_assert (regno < VEC_length (rtx, reg_base_value));
00972
00973
00974
00975 if (regno < FIRST_PSEUDO_REGISTER)
00976 n = hard_regno_nregs[regno][GET_MODE (dest)];
00977 else
00978 n = 1;
00979 if (n != 1)
00980 {
00981 while (--n >= 0)
00982 {
00983 reg_seen[regno + n] = 1;
00984 new_reg_base_value[regno + n] = 0;
00985 }
00986 return;
00987 }
00988
00989 if (set)
00990 {
00991
00992
00993
00994 if (GET_CODE (set) == CLOBBER)
00995 {
00996 new_reg_base_value[regno] = 0;
00997 return;
00998 }
00999 src = SET_SRC (set);
01000 }
01001 else
01002 {
01003 if (reg_seen[regno])
01004 {
01005 new_reg_base_value[regno] = 0;
01006 return;
01007 }
01008 reg_seen[regno] = 1;
01009 new_reg_base_value[regno] = gen_rtx_ADDRESS (Pmode,
01010 GEN_INT (unique_id++));
01011 return;
01012 }
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030 if (new_reg_base_value[regno] != 0
01031 && find_base_value (src) != new_reg_base_value[regno])
01032 switch (GET_CODE (src))
01033 {
01034 case LO_SUM:
01035 case MINUS:
01036 if (XEXP (src, 0) != dest && XEXP (src, 1) != dest)
01037 new_reg_base_value[regno] = 0;
01038 break;
01039 case PLUS:
01040
01041
01042
01043 {
01044 rtx other = NULL_RTX;
01045
01046 if (XEXP (src, 0) == dest)
01047 other = XEXP (src, 1);
01048 else if (XEXP (src, 1) == dest)
01049 other = XEXP (src, 0);
01050
01051 if (! other || find_base_value (other))
01052 new_reg_base_value[regno] = 0;
01053 break;
01054 }
01055 case AND:
01056 if (XEXP (src, 0) != dest || GET_CODE (XEXP (src, 1)) != CONST_INT)
01057 new_reg_base_value[regno] = 0;
01058 break;
01059 default:
01060 new_reg_base_value[regno] = 0;
01061 break;
01062 }
01063
01064 else if ((regno >= FIRST_PSEUDO_REGISTER || ! fixed_regs[regno])
01065 && ! reg_seen[regno] && new_reg_base_value[regno] == 0)
01066 new_reg_base_value[regno] = find_base_value (src);
01067
01068 reg_seen[regno] = 1;
01069 }
01070
01071
01072
01073
01074
01075
01076 void
01077 clear_reg_alias_info (rtx reg)
01078 {
01079 unsigned int regno = REGNO (reg);
01080
01081 if (regno >= FIRST_PSEUDO_REGISTER)
01082 {
01083 regno -= FIRST_PSEUDO_REGISTER;
01084 if (regno < reg_known_value_size)
01085 {
01086 reg_known_value[regno] = reg;
01087 reg_known_equiv_p[regno] = false;
01088 }
01089 }
01090 }
01091
01092
01093
01094 rtx
01095 get_reg_known_value (unsigned int regno)
01096 {
01097 if (regno >= FIRST_PSEUDO_REGISTER)
01098 {
01099 regno -= FIRST_PSEUDO_REGISTER;
01100 if (regno < reg_known_value_size)
01101 return reg_known_value[regno];
01102 }
01103 return NULL;
01104 }
01105
01106
01107
01108 static void
01109 set_reg_known_value (unsigned int regno, rtx val)
01110 {
01111 if (regno >= FIRST_PSEUDO_REGISTER)
01112 {
01113 regno -= FIRST_PSEUDO_REGISTER;
01114 if (regno < reg_known_value_size)
01115 reg_known_value[regno] = val;
01116 }
01117 }
01118
01119
01120
01121 bool
01122 get_reg_known_equiv_p (unsigned int regno)
01123 {
01124 if (regno >= FIRST_PSEUDO_REGISTER)
01125 {
01126 regno -= FIRST_PSEUDO_REGISTER;
01127 if (regno < reg_known_value_size)
01128 return reg_known_equiv_p[regno];
01129 }
01130 return false;
01131 }
01132
01133 static void
01134 set_reg_known_equiv_p (unsigned int regno, bool val)
01135 {
01136 if (regno >= FIRST_PSEUDO_REGISTER)
01137 {
01138 regno -= FIRST_PSEUDO_REGISTER;
01139 if (regno < reg_known_value_size)
01140 reg_known_equiv_p[regno] = val;
01141 }
01142 }
01143
01144
01145
01146
01147
01148
01149
01150 rtx
01151 canon_rtx (rtx x)
01152 {
01153
01154 if (REG_P (x) && REGNO (x) >= FIRST_PSEUDO_REGISTER)
01155 {
01156 rtx t = get_reg_known_value (REGNO (x));
01157 if (t == x)
01158 return x;
01159 if (t)
01160 return canon_rtx (t);
01161 }
01162
01163 if (GET_CODE (x) == PLUS)
01164 {
01165 rtx x0 = canon_rtx (XEXP (x, 0));
01166 rtx x1 = canon_rtx (XEXP (x, 1));
01167
01168 if (x0 != XEXP (x, 0) || x1 != XEXP (x, 1))
01169 {
01170 if (GET_CODE (x0) == CONST_INT)
01171 return plus_constant (x1, INTVAL (x0));
01172 else if (GET_CODE (x1) == CONST_INT)
01173 return plus_constant (x0, INTVAL (x1));
01174 return gen_rtx_PLUS (GET_MODE (x), x0, x1);
01175 }
01176 }
01177
01178
01179
01180
01181
01182 else if (MEM_P (x))
01183 x = replace_equiv_address_nv (x, canon_rtx (XEXP (x, 0)));
01184
01185 return x;
01186 }
01187
01188
01189
01190
01191
01192
01193
01194 static int
01195 rtx_equal_for_memref_p (rtx x, rtx y)
01196 {
01197 int i;
01198 int j;
01199 enum rtx_code code;
01200 const char *fmt;
01201
01202 if (x == 0 && y == 0)
01203 return 1;
01204 if (x == 0 || y == 0)
01205 return 0;
01206
01207 if (x == y)
01208 return 1;
01209
01210 code = GET_CODE (x);
01211
01212 if (code != GET_CODE (y))
01213 return 0;
01214
01215
01216
01217
01218 if (GET_MODE (x) != GET_MODE (y))
01219 return 0;
01220
01221
01222 switch (code)
01223 {
01224 case REG:
01225 return REGNO (x) == REGNO (y);
01226
01227 case LABEL_REF:
01228 return XEXP (x, 0) == XEXP (y, 0);
01229
01230 case SYMBOL_REF:
01231 return XSTR (x, 0) == XSTR (y, 0);
01232
01233 case VALUE:
01234 case CONST_INT:
01235 case CONST_DOUBLE:
01236
01237
01238
01239 return 0;
01240
01241 default:
01242 break;
01243 }
01244
01245
01246 if (code == PLUS)
01247 return ((rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 0))
01248 && rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 1)))
01249 || (rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 1))
01250 && rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 0))));
01251
01252
01253 if (COMMUTATIVE_P (x))
01254 {
01255 rtx xop0 = canon_rtx (XEXP (x, 0));
01256 rtx yop0 = canon_rtx (XEXP (y, 0));
01257 rtx yop1 = canon_rtx (XEXP (y, 1));
01258
01259 return ((rtx_equal_for_memref_p (xop0, yop0)
01260 && rtx_equal_for_memref_p (canon_rtx (XEXP (x, 1)), yop1))
01261 || (rtx_equal_for_memref_p (xop0, yop1)
01262 && rtx_equal_for_memref_p (canon_rtx (XEXP (x, 1)), yop0)));
01263 }
01264 else if (NON_COMMUTATIVE_P (x))
01265 {
01266 return (rtx_equal_for_memref_p (canon_rtx (XEXP (x, 0)),
01267 canon_rtx (XEXP (y, 0)))
01268 && rtx_equal_for_memref_p (canon_rtx (XEXP (x, 1)),
01269 canon_rtx (XEXP (y, 1))));
01270 }
01271 else if (UNARY_P (x))
01272 return rtx_equal_for_memref_p (canon_rtx (XEXP (x, 0)),
01273 canon_rtx (XEXP (y, 0)));
01274
01275
01276
01277
01278
01279
01280 fmt = GET_RTX_FORMAT (code);
01281 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
01282 {
01283 switch (fmt[i])
01284 {
01285 case 'i':
01286 if (XINT (x, i) != XINT (y, i))
01287 return 0;
01288 break;
01289
01290 case 'E':
01291
01292 if (XVECLEN (x, i) != XVECLEN (y, i))
01293 return 0;
01294
01295
01296 for (j = 0; j < XVECLEN (x, i); j++)
01297 if (rtx_equal_for_memref_p (canon_rtx (XVECEXP (x, i, j)),
01298 canon_rtx (XVECEXP (y, i, j))) == 0)
01299 return 0;
01300 break;
01301
01302 case 'e':
01303 if (rtx_equal_for_memref_p (canon_rtx (XEXP (x, i)),
01304 canon_rtx (XEXP (y, i))) == 0)
01305 return 0;
01306 break;
01307
01308
01309 case 's':
01310 if (strcmp (XSTR (x, i), XSTR (y, i)))
01311 return 0;
01312 break;
01313
01314
01315 case '0':
01316 break;
01317
01318
01319
01320
01321 default:
01322 gcc_unreachable ();
01323 }
01324 }
01325 return 1;
01326 }
01327
01328
01329
01330
01331 static rtx
01332 find_symbolic_term (rtx x)
01333 {
01334 int i;
01335 enum rtx_code code;
01336 const char *fmt;
01337
01338 code = GET_CODE (x);
01339 if (code == SYMBOL_REF || code == LABEL_REF)
01340 return x;
01341 if (OBJECT_P (x))
01342 return 0;
01343
01344 fmt = GET_RTX_FORMAT (code);
01345 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
01346 {
01347 rtx t;
01348
01349 if (fmt[i] == 'e')
01350 {
01351 t = find_symbolic_term (XEXP (x, i));
01352 if (t != 0)
01353 return t;
01354 }
01355 else if (fmt[i] == 'E')
01356 break;
01357 }
01358 return 0;
01359 }
01360
01361 rtx
01362 find_base_term (rtx x)
01363 {
01364 cselib_val *val;
01365 struct elt_loc_list *l;
01366
01367 #if defined (FIND_BASE_TERM)
01368
01369 x = FIND_BASE_TERM (x);
01370 #endif
01371
01372 switch (GET_CODE (x))
01373 {
01374 case REG:
01375 return REG_BASE_VALUE (x);
01376
01377 case TRUNCATE:
01378 if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (Pmode))
01379 return 0;
01380
01381 case HIGH:
01382 case PRE_INC:
01383 case PRE_DEC:
01384 case POST_INC:
01385 case POST_DEC:
01386 case PRE_MODIFY:
01387 case POST_MODIFY:
01388 return find_base_term (XEXP (x, 0));
01389
01390 case ZERO_EXTEND:
01391 case SIGN_EXTEND:
01392 {
01393 rtx temp = find_base_term (XEXP (x, 0));
01394
01395 if (temp != 0 && CONSTANT_P (temp))
01396 temp = convert_memory_address (Pmode, temp);
01397
01398 return temp;
01399 }
01400
01401 case VALUE:
01402 val = CSELIB_VAL_PTR (x);
01403 if (!val)
01404 return 0;
01405 for (l = val->locs; l; l = l->next)
01406 if ((x = find_base_term (l->loc)) != 0)
01407 return x;
01408 return 0;
01409
01410 case CONST:
01411 x = XEXP (x, 0);
01412 if (GET_CODE (x) != PLUS && GET_CODE (x) != MINUS)
01413 return 0;
01414
01415 case LO_SUM:
01416 case PLUS:
01417 case MINUS:
01418 {
01419 rtx tmp1 = XEXP (x, 0);
01420 rtx tmp2 = XEXP (x, 1);
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434 if (tmp1 == pic_offset_table_rtx && CONSTANT_P (tmp2))
01435 return find_base_term (tmp2);
01436
01437
01438
01439 if (REG_P (tmp1) && REG_POINTER (tmp1))
01440 return find_base_term (tmp1);
01441
01442 if (REG_P (tmp2) && REG_POINTER (tmp2))
01443 return find_base_term (tmp2);
01444
01445
01446
01447 tmp1 = find_base_term (tmp1);
01448 tmp2 = find_base_term (tmp2);
01449
01450
01451
01452
01453 if (tmp1 != 0
01454 && (GET_CODE (tmp1) == SYMBOL_REF
01455 || GET_CODE (tmp1) == LABEL_REF
01456 || (GET_CODE (tmp1) == ADDRESS
01457 && GET_MODE (tmp1) != VOIDmode)))
01458 return tmp1;
01459
01460 if (tmp2 != 0
01461 && (GET_CODE (tmp2) == SYMBOL_REF
01462 || GET_CODE (tmp2) == LABEL_REF
01463 || (GET_CODE (tmp2) == ADDRESS
01464 && GET_MODE (tmp2) != VOIDmode)))
01465 return tmp2;
01466
01467
01468
01469
01470 return 0;
01471 }
01472
01473 case AND:
01474 if (GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) != 0)
01475 return find_base_term (XEXP (x, 0));
01476 return 0;
01477
01478 case SYMBOL_REF:
01479 case LABEL_REF:
01480 return x;
01481
01482 default:
01483 return 0;
01484 }
01485 }
01486
01487
01488
01489
01490 static int
01491 base_alias_check (rtx x, rtx y, enum machine_mode x_mode,
01492 enum machine_mode y_mode)
01493 {
01494 rtx x_base = find_base_term (x);
01495 rtx y_base = find_base_term (y);
01496
01497
01498
01499
01500 if (x_base == 0)
01501 {
01502 rtx x_c;
01503
01504 if (! flag_expensive_optimizations || (x_c = canon_rtx (x)) == x)
01505 return 1;
01506
01507 x_base = find_base_term (x_c);
01508 if (x_base == 0)
01509 return 1;
01510 }
01511
01512 if (y_base == 0)
01513 {
01514 rtx y_c;
01515 if (! flag_expensive_optimizations || (y_c = canon_rtx (y)) == y)
01516 return 1;
01517
01518 y_base = find_base_term (y_c);
01519 if (y_base == 0)
01520 return 1;
01521 }
01522
01523
01524 if (rtx_equal_p (x_base, y_base))
01525 return 1;
01526
01527
01528
01529
01530
01531
01532 if (GET_CODE (x_base) != ADDRESS && GET_CODE (y_base) != ADDRESS)
01533 {
01534 if (GET_CODE (x) == AND && GET_CODE (y) == AND)
01535 return 1;
01536 if (GET_CODE (x) == AND
01537 && (GET_CODE (XEXP (x, 1)) != CONST_INT
01538 || (int) GET_MODE_UNIT_SIZE (y_mode) < -INTVAL (XEXP (x, 1))))
01539 return 1;
01540 if (GET_CODE (y) == AND
01541 && (GET_CODE (XEXP (y, 1)) != CONST_INT
01542 || (int) GET_MODE_UNIT_SIZE (x_mode) < -INTVAL (XEXP (y, 1))))
01543 return 1;
01544
01545 return 0;
01546 }
01547
01548
01549
01550
01551
01552 if ((GET_CODE (x_base) == ADDRESS && GET_MODE (x_base) == Pmode)
01553 || (GET_CODE (y_base) == ADDRESS && GET_MODE (y_base) == Pmode))
01554 return 0;
01555
01556 if (! flag_argument_noalias)
01557 return 1;
01558
01559 if (flag_argument_noalias > 1)
01560 return 0;
01561
01562
01563 return ! (GET_MODE (x_base) == VOIDmode && GET_MODE (y_base) == VOIDmode);
01564 }
01565
01566
01567
01568
01569
01570 rtx
01571 get_addr (rtx x)
01572 {
01573 cselib_val *v;
01574 struct elt_loc_list *l;
01575
01576 if (GET_CODE (x) != VALUE)
01577 return x;
01578 v = CSELIB_VAL_PTR (x);
01579 if (v)
01580 {
01581 for (l = v->locs; l; l = l->next)
01582 if (CONSTANT_P (l->loc))
01583 return l->loc;
01584 for (l = v->locs; l; l = l->next)
01585 if (!REG_P (l->loc) && !MEM_P (l->loc))
01586 return l->loc;
01587 if (v->locs)
01588 return v->locs->loc;
01589 }
01590 return x;
01591 }
01592
01593
01594
01595
01596
01597 static rtx
01598 addr_side_effect_eval (rtx addr, int size, int n_refs)
01599 {
01600 int offset = 0;
01601
01602 switch (GET_CODE (addr))
01603 {
01604 case PRE_INC:
01605 offset = (n_refs + 1) * size;
01606 break;
01607 case PRE_DEC:
01608 offset = -(n_refs + 1) * size;
01609 break;
01610 case POST_INC:
01611 offset = n_refs * size;
01612 break;
01613 case POST_DEC:
01614 offset = -n_refs * size;
01615 break;
01616
01617 default:
01618 return addr;
01619 }
01620
01621 if (offset)
01622 addr = gen_rtx_PLUS (GET_MODE (addr), XEXP (addr, 0),
01623 GEN_INT (offset));
01624 else
01625 addr = XEXP (addr, 0);
01626 addr = canon_rtx (addr);
01627
01628 return addr;
01629 }
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649 static int
01650 memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
01651 {
01652 if (GET_CODE (x) == VALUE)
01653 x = get_addr (x);
01654 if (GET_CODE (y) == VALUE)
01655 y = get_addr (y);
01656 if (GET_CODE (x) == HIGH)
01657 x = XEXP (x, 0);
01658 else if (GET_CODE (x) == LO_SUM)
01659 x = XEXP (x, 1);
01660 else
01661 x = addr_side_effect_eval (x, xsize, 0);
01662 if (GET_CODE (y) == HIGH)
01663 y = XEXP (y, 0);
01664 else if (GET_CODE (y) == LO_SUM)
01665 y = XEXP (y, 1);
01666 else
01667 y = addr_side_effect_eval (y, ysize, 0);
01668
01669 if (rtx_equal_for_memref_p (x, y))
01670 {
01671 if (xsize <= 0 || ysize <= 0)
01672 return 1;
01673 if (c >= 0 && xsize > c)
01674 return 1;
01675 if (c < 0 && ysize+c > 0)
01676 return 1;
01677 return 0;
01678 }
01679
01680
01681
01682
01683 if (GET_CODE (x) == PLUS)
01684 {
01685
01686
01687 rtx x0 = XEXP (x, 0);
01688 rtx x1 = XEXP (x, 1);
01689
01690 if (GET_CODE (y) == PLUS)
01691 {
01692
01693
01694 rtx y0 = XEXP (y, 0);
01695 rtx y1 = XEXP (y, 1);
01696
01697 if (rtx_equal_for_memref_p (x1, y1))
01698 return memrefs_conflict_p (xsize, x0, ysize, y0, c);
01699 if (rtx_equal_for_memref_p (x0, y0))
01700 return memrefs_conflict_p (xsize, x1, ysize, y1, c);
01701 if (GET_CODE (x1) == CONST_INT)
01702 {
01703 if (GET_CODE (y1) == CONST_INT)
01704 return memrefs_conflict_p (xsize, x0, ysize, y0,
01705 c - INTVAL (x1) + INTVAL (y1));
01706 else
01707 return memrefs_conflict_p (xsize, x0, ysize, y,
01708 c - INTVAL (x1));
01709 }
01710 else if (GET_CODE (y1) == CONST_INT)
01711 return memrefs_conflict_p (xsize, x, ysize, y0, c + INTVAL (y1));
01712
01713 return 1;
01714 }
01715 else if (GET_CODE (x1) == CONST_INT)
01716 return memrefs_conflict_p (xsize, x0, ysize, y, c - INTVAL (x1));
01717 }
01718 else if (GET_CODE (y) == PLUS)
01719 {
01720
01721
01722 rtx y0 = XEXP (y, 0);
01723 rtx y1 = XEXP (y, 1);
01724
01725 if (GET_CODE (y1) == CONST_INT)
01726 return memrefs_conflict_p (xsize, x, ysize, y0, c + INTVAL (y1));
01727 else
01728 return 1;
01729 }
01730
01731 if (GET_CODE (x) == GET_CODE (y))
01732 switch (GET_CODE (x))
01733 {
01734 case MULT:
01735 {
01736
01737
01738
01739 rtx x0, y0;
01740 rtx x1 = canon_rtx (XEXP (x, 1));
01741 rtx y1 = canon_rtx (XEXP (y, 1));
01742 if (! rtx_equal_for_memref_p (x1, y1))
01743 return 1;
01744 x0 = canon_rtx (XEXP (x, 0));
01745 y0 = canon_rtx (XEXP (y, 0));
01746 if (rtx_equal_for_memref_p (x0, y0))
01747 return (xsize == 0 || ysize == 0
01748 || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0));
01749
01750
01751 if (GET_CODE (x1) != CONST_INT)
01752 return 1;
01753 xsize /= INTVAL (x1);
01754 ysize /= INTVAL (x1);
01755 c /= INTVAL (x1);
01756 return memrefs_conflict_p (xsize, x0, ysize, y0, c);
01757 }
01758
01759 default:
01760 break;
01761 }
01762
01763
01764
01765
01766
01767 if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT)
01768 {
01769 if (GET_CODE (y) == AND || ysize < -INTVAL (XEXP (x, 1)))
01770 xsize = -1;
01771 return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)), ysize, y, c);
01772 }
01773 if (GET_CODE (y) == AND && GET_CODE (XEXP (y, 1)) == CONST_INT)
01774 {
01775
01776
01777
01778
01779 if (GET_CODE (x) == AND || xsize < -INTVAL (XEXP (y, 1)))
01780 ysize = -1;
01781 return memrefs_conflict_p (xsize, x, ysize, canon_rtx (XEXP (y, 0)), c);
01782 }
01783
01784 if (CONSTANT_P (x))
01785 {
01786 if (GET_CODE (x) == CONST_INT && GET_CODE (y) == CONST_INT)
01787 {
01788 c += (INTVAL (y) - INTVAL (x));
01789 return (xsize <= 0 || ysize <= 0
01790 || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0));
01791 }
01792
01793 if (GET_CODE (x) == CONST)
01794 {
01795 if (GET_CODE (y) == CONST)
01796 return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)),
01797 ysize, canon_rtx (XEXP (y, 0)), c);
01798 else
01799 return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)),
01800 ysize, y, c);
01801 }
01802 if (GET_CODE (y) == CONST)
01803 return memrefs_conflict_p (xsize, x, ysize,
01804 canon_rtx (XEXP (y, 0)), c);
01805
01806 if (CONSTANT_P (y))
01807 return (xsize <= 0 || ysize <= 0
01808 || (rtx_equal_for_memref_p (x, y)
01809 && ((c >= 0 && xsize > c) || (c < 0 && ysize+c > 0))));
01810
01811 return 1;
01812 }
01813 return 1;
01814 }
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838 int
01839 read_dependence (rtx mem, rtx x)
01840 {
01841 return MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem);
01842 }
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852 static rtx
01853 fixed_scalar_and_varying_struct_p (rtx mem1, rtx mem2, rtx mem1_addr,
01854 rtx mem2_addr,
01855 int (*varies_p) (rtx, int))
01856 {
01857 if (! flag_strict_aliasing)
01858 return NULL_RTX;
01859
01860 if (MEM_SCALAR_P (mem1) && MEM_IN_STRUCT_P (mem2)
01861 && !varies_p (mem1_addr, 1) && varies_p (mem2_addr, 1))
01862
01863
01864 return mem1;
01865
01866 if (MEM_IN_STRUCT_P (mem1) && MEM_SCALAR_P (mem2)
01867 && varies_p (mem1_addr, 1) && !varies_p (mem2_addr, 1))
01868
01869
01870 return mem2;
01871
01872 return NULL_RTX;
01873 }
01874
01875
01876
01877
01878 static int
01879 aliases_everything_p (rtx mem)
01880 {
01881 if (GET_CODE (XEXP (mem, 0)) == AND)
01882
01883
01884 return 1;
01885
01886 return 0;
01887 }
01888
01889
01890
01891
01892 static bool
01893 nonoverlapping_component_refs_p (tree x, tree y)
01894 {
01895 tree fieldx, fieldy, typex, typey, orig_y;
01896
01897 do
01898 {
01899
01900
01901 orig_y = y;
01902 do
01903 {
01904 fieldx = TREE_OPERAND (x, 1);
01905 typex = TYPE_MAIN_VARIANT (DECL_FIELD_CONTEXT (fieldx));
01906
01907 y = orig_y;
01908 do
01909 {
01910 fieldy = TREE_OPERAND (y, 1);
01911 typey = TYPE_MAIN_VARIANT (DECL_FIELD_CONTEXT (fieldy));
01912
01913 if (typex == typey)
01914 goto found;
01915
01916 y = TREE_OPERAND (y, 0);
01917 }
01918 while (y && TREE_CODE (y) == COMPONENT_REF);
01919
01920 x = TREE_OPERAND (x, 0);
01921 }
01922 while (x && TREE_CODE (x) == COMPONENT_REF);
01923
01924 return false;
01925
01926 found:
01927
01928
01929 if (TREE_CODE (typex) == RECORD_TYPE
01930 && fieldx != fieldy)
01931 return true;
01932
01933
01934
01935 x = TREE_OPERAND (x, 0);
01936 y = TREE_OPERAND (y, 0);
01937 }
01938 while (x && y
01939 && TREE_CODE (x) == COMPONENT_REF
01940 && TREE_CODE (y) == COMPONENT_REF);
01941
01942 return false;
01943 }
01944
01945
01946
01947 static tree
01948 decl_for_component_ref (tree x)
01949 {
01950 do
01951 {
01952 x = TREE_OPERAND (x, 0);
01953 }
01954 while (x && TREE_CODE (x) == COMPONENT_REF);
01955
01956 return x && DECL_P (x) ? x : NULL_TREE;
01957 }
01958
01959
01960
01961
01962 static rtx
01963 adjust_offset_for_component_ref (tree x, rtx offset)
01964 {
01965 HOST_WIDE_INT ioffset;
01966
01967 if (! offset)
01968 return NULL_RTX;
01969
01970 ioffset = INTVAL (offset);
01971 do
01972 {
01973 tree offset = component_ref_field_offset (x);
01974 tree field = TREE_OPERAND (x, 1);
01975
01976 if (! host_integerp (offset, 1))
01977 return NULL_RTX;
01978 ioffset += (tree_low_cst (offset, 1)
01979 + (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
01980 / BITS_PER_UNIT));
01981
01982 x = TREE_OPERAND (x, 0);
01983 }
01984 while (x && TREE_CODE (x) == COMPONENT_REF);
01985
01986 return GEN_INT (ioffset);
01987 }
01988
01989
01990
01991
01992 static int
01993 nonoverlapping_memrefs_p (rtx x, rtx y)
01994 {
01995 tree exprx = MEM_EXPR (x), expry = MEM_EXPR (y);
01996 rtx rtlx, rtly;
01997 rtx basex, basey;
01998 rtx moffsetx, moffsety;
01999 HOST_WIDE_INT offsetx = 0, offsety = 0, sizex, sizey, tem;
02000
02001
02002 if (exprx == 0 || expry == 0)
02003 return 0;
02004
02005
02006 if (TREE_CODE (exprx) == COMPONENT_REF
02007 && TREE_CODE (expry) == COMPONENT_REF
02008 && nonoverlapping_component_refs_p (exprx, expry))
02009 return 1;
02010
02011
02012
02013 moffsetx = MEM_OFFSET (x);
02014 if (TREE_CODE (exprx) == COMPONENT_REF)
02015 {
02016 if (TREE_CODE (expry) == VAR_DECL
02017 && POINTER_TYPE_P (TREE_TYPE (expry)))
02018 {
02019 tree field = TREE_OPERAND (exprx, 1);
02020 tree fieldcontext = DECL_FIELD_CONTEXT (field);
02021 if (ipa_type_escape_field_does_not_clobber_p (fieldcontext,
02022 TREE_TYPE (field)))
02023 return 1;
02024 }
02025 {
02026 tree t = decl_for_component_ref (exprx);
02027 if (! t)
02028 return 0;
02029 moffsetx = adjust_offset_for_component_ref (exprx, moffsetx);
02030 exprx = t;
02031 }
02032 }
02033 else if (INDIRECT_REF_P (exprx))
02034 {
02035 exprx = TREE_OPERAND (exprx, 0);
02036 if (flag_argument_noalias < 2
02037 || TREE_CODE (exprx) != PARM_DECL)
02038 return 0;
02039 }
02040
02041 moffsety = MEM_OFFSET (y);
02042 if (TREE_CODE (expry) == COMPONENT_REF)
02043 {
02044 if (TREE_CODE (exprx) == VAR_DECL
02045 && POINTER_TYPE_P (TREE_TYPE (exprx)))
02046 {
02047 tree field = TREE_OPERAND (expry, 1);
02048 tree fieldcontext = DECL_FIELD_CONTEXT (field);
02049 if (ipa_type_escape_field_does_not_clobber_p (fieldcontext,
02050 TREE_TYPE (field)))
02051 return 1;
02052 }
02053 {
02054 tree t = decl_for_component_ref (expry);
02055 if (! t)
02056 return 0;
02057 moffsety = adjust_offset_for_component_ref (expry, moffsety);
02058 expry = t;
02059 }
02060 }
02061 else if (INDIRECT_REF_P (expry))
02062 {
02063 expry = TREE_OPERAND (expry, 0);
02064 if (flag_argument_noalias < 2
02065 || TREE_CODE (expry) != PARM_DECL)
02066 return 0;
02067 }
02068
02069 if (! DECL_P (exprx) || ! DECL_P (expry))
02070 return 0;
02071
02072 rtlx = DECL_RTL (exprx);
02073 rtly = DECL_RTL (expry);
02074
02075
02076
02077
02078 if ((!MEM_P (rtlx) || !MEM_P (rtly))
02079 && ! rtx_equal_p (rtlx, rtly))
02080 return 1;
02081
02082
02083
02084
02085
02086 basex = MEM_P (rtlx) ? XEXP (rtlx, 0) : rtlx;
02087 if (GET_CODE (basex) == PLUS && GET_CODE (XEXP (basex, 1)) == CONST_INT)
02088 offsetx = INTVAL (XEXP (basex, 1)), basex = XEXP (basex, 0);
02089
02090 basey = MEM_P (rtly) ? XEXP (rtly, 0) : rtly;
02091 if (GET_CODE (basey) == PLUS && GET_CODE (XEXP (basey, 1)) == CONST_INT)
02092 offsety = INTVAL (XEXP (basey, 1)), basey = XEXP (basey, 0);
02093
02094
02095
02096
02097
02098 if (! rtx_equal_p (basex, basey))
02099 return ((CONSTANT_P (basex) && CONSTANT_P (basey))
02100 || (CONSTANT_P (basex) && REG_P (basey)
02101 && REGNO_PTR_FRAME_P (REGNO (basey)))
02102 || (CONSTANT_P (basey) && REG_P (basex)
02103 && REGNO_PTR_FRAME_P (REGNO (basex))));
02104
02105 sizex = (!MEM_P (rtlx) ? (int) GET_MODE_SIZE (GET_MODE (rtlx))
02106 : MEM_SIZE (rtlx) ? INTVAL (MEM_SIZE (rtlx))
02107 : -1);
02108 sizey = (!MEM_P (rtly) ? (int) GET_MODE_SIZE (GET_MODE (rtly))
02109 : MEM_SIZE (rtly) ? INTVAL (MEM_SIZE (rtly)) :
02110 -1);
02111
02112
02113
02114 if (moffsetx)
02115 offsetx += INTVAL (moffsetx), sizex -= INTVAL (moffsetx);
02116 if (moffsety)
02117 offsety += INTVAL (moffsety), sizey -= INTVAL (moffsety);
02118
02119
02120
02121
02122 if (MEM_SIZE (x) && moffsetx)
02123 sizex = INTVAL (MEM_SIZE (x));
02124 if (MEM_SIZE (y) && moffsety)
02125 sizey = INTVAL (MEM_SIZE (y));
02126
02127
02128 if (offsetx > offsety)
02129 {
02130 tem = offsetx, offsetx = offsety, offsety = tem;
02131 tem = sizex, sizex = sizey, sizey = tem;
02132 }
02133
02134
02135
02136 return sizex >= 0 && offsety >= offsetx + sizex;
02137 }
02138
02139
02140
02141 int
02142 true_dependence (rtx mem, enum machine_mode mem_mode, rtx x,
02143 int (*varies) (rtx, int))
02144 {
02145 rtx x_addr, mem_addr;
02146 rtx base;
02147
02148 if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
02149 return 1;
02150
02151
02152
02153 if (GET_MODE (x) == BLKmode && GET_CODE (XEXP (x, 0)) == SCRATCH)
02154 return 1;
02155 if (GET_MODE (mem) == BLKmode && GET_CODE (XEXP (mem, 0)) == SCRATCH)
02156 return 1;
02157 if (MEM_ALIAS_SET (x) == ALIAS_SET_MEMORY_BARRIER
02158 || MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER)
02159 return 1;
02160
02161 if (DIFFERENT_ALIAS_SETS_P (x, mem))
02162 return 0;
02163
02164
02165
02166
02167 if (MEM_READONLY_P (x))
02168 return 0;
02169
02170 if (nonoverlapping_memrefs_p (mem, x))
02171 return 0;
02172
02173 if (mem_mode == VOIDmode)
02174 mem_mode = GET_MODE (mem);
02175
02176 x_addr = get_addr (XEXP (x, 0));
02177 mem_addr = get_addr (XEXP (mem, 0));
02178
02179 base = find_base_term (x_addr);
02180 if (base && (GET_CODE (base) == LABEL_REF
02181 || (GET_CODE (base) == SYMBOL_REF
02182 && CONSTANT_POOL_ADDRESS_P (base))))
02183 return 0;
02184
02185 if (! base_alias_check (x_addr, mem_addr, GET_MODE (x), mem_mode))
02186 return 0;
02187
02188 x_addr = canon_rtx (x_addr);
02189 mem_addr = canon_rtx (mem_addr);
02190
02191 if (! memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr,
02192 SIZE_FOR_MODE (x), x_addr, 0))
02193 return 0;
02194
02195 if (aliases_everything_p (x))
02196 return 1;
02197
02198
02199
02200 if (mem_mode == QImode || GET_CODE (mem_addr) == AND)
02201 return 1;
02202
02203
02204
02205 if (mem_mode == BLKmode || GET_MODE (x) == BLKmode)
02206 return 1;
02207
02208 return ! fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr,
02209 varies);
02210 }
02211
02212
02213
02214
02215
02216
02217
02218 int
02219 canon_true_dependence (rtx mem, enum machine_mode mem_mode, rtx mem_addr,
02220 rtx x, int (*varies) (rtx, int))
02221 {
02222 rtx x_addr;
02223
02224 if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
02225 return 1;
02226
02227
02228
02229 if (GET_MODE (x) == BLKmode && GET_CODE (XEXP (x, 0)) == SCRATCH)
02230 return 1;
02231 if (GET_MODE (mem) == BLKmode && GET_CODE (XEXP (mem, 0)) == SCRATCH)
02232 return 1;
02233 if (MEM_ALIAS_SET (x) == ALIAS_SET_MEMORY_BARRIER
02234 || MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER)
02235 return 1;
02236
02237 if (DIFFERENT_ALIAS_SETS_P (x, mem))
02238 return 0;
02239
02240
02241
02242
02243 if (MEM_READONLY_P (x))
02244 return 0;
02245
02246 if (nonoverlapping_memrefs_p (x, mem))
02247 return 0;
02248
02249 x_addr = get_addr (XEXP (x, 0));
02250
02251 if (! base_alias_check (x_addr, mem_addr, GET_MODE (x), mem_mode))
02252 return 0;
02253
02254 x_addr = canon_rtx (x_addr);
02255 if (! memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr,
02256 SIZE_FOR_MODE (x), x_addr, 0))
02257 return 0;
02258
02259 if (aliases_everything_p (x))
02260 return 1;
02261
02262
02263
02264 if (mem_mode == QImode || GET_CODE (mem_addr) == AND)
02265 return 1;
02266
02267
02268
02269 if (mem_mode == BLKmode || GET_MODE (x) == BLKmode)
02270 return 1;
02271
02272 return ! fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr,
02273 varies);
02274 }
02275
02276
02277
02278
02279 static int
02280 write_dependence_p (rtx mem, rtx x, int writep)
02281 {
02282 rtx x_addr, mem_addr;
02283 rtx fixed_scalar;
02284 rtx base;
02285
02286 if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
02287 return 1;
02288
02289
02290
02291 if (GET_MODE (x) == BLKmode && GET_CODE (XEXP (x, 0)) == SCRATCH)
02292 return 1;
02293 if (GET_MODE (mem) == BLKmode && GET_CODE (XEXP (mem, 0)) == SCRATCH)
02294 return 1;
02295 if (MEM_ALIAS_SET (x) == ALIAS_SET_MEMORY_BARRIER
02296 || MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER)
02297 return 1;
02298
02299 if (DIFFERENT_ALIAS_SETS_P (x, mem))
02300 return 0;
02301
02302
02303 if (!writep && MEM_READONLY_P (mem))
02304 return 0;
02305
02306 if (nonoverlapping_memrefs_p (x, mem))
02307 return 0;
02308
02309 x_addr = get_addr (XEXP (x, 0));
02310 mem_addr = get_addr (XEXP (mem, 0));
02311
02312 if (! writep)
02313 {
02314 base = find_base_term (mem_addr);
02315 if (base && (GET_CODE (base) == LABEL_REF
02316 || (GET_CODE (base) == SYMBOL_REF
02317 && CONSTANT_POOL_ADDRESS_P (base))))
02318 return 0;
02319 }
02320
02321 if (! base_alias_check (x_addr, mem_addr, GET_MODE (x),
02322 GET_MODE (mem)))
02323 return 0;
02324
02325 x_addr = canon_rtx (x_addr);
02326 mem_addr = canon_rtx (mem_addr);
02327
02328 if (!memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr,
02329 SIZE_FOR_MODE (x), x_addr, 0))
02330 return 0;
02331
02332 fixed_scalar
02333 = fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr,
02334 rtx_addr_varies_p);
02335
02336 return (!(fixed_scalar == mem && !aliases_everything_p (x))
02337 && !(fixed_scalar == x && !aliases_everything_p (mem)));
02338 }
02339
02340
02341
02342 int
02343 anti_dependence (rtx mem, rtx x)
02344 {
02345 return write_dependence_p (mem, x, 0);
02346 }
02347
02348
02349
02350 int
02351 output_dependence (rtx mem, rtx x)
02352 {
02353 return write_dependence_p (mem, x, 1);
02354 }
02355
02356
02357 void
02358 init_alias_once (void)
02359 {
02360 int i;
02361
02362 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
02363
02364
02365
02366 if (FUNCTION_ARG_REGNO_P (OUTGOING_REGNO (i))
02367 && HARD_REGNO_MODE_OK (i, Pmode))
02368 static_reg_base_value[i]
02369 = gen_rtx_ADDRESS (VOIDmode, gen_rtx_REG (Pmode, i));
02370
02371 static_reg_base_value[STACK_POINTER_REGNUM]
02372 = gen_rtx_ADDRESS (Pmode, stack_pointer_rtx);
02373 static_reg_base_value[ARG_POINTER_REGNUM]
02374 = gen_rtx_ADDRESS (Pmode, arg_pointer_rtx);
02375 static_reg_base_value[FRAME_POINTER_REGNUM]
02376 = gen_rtx_ADDRESS (Pmode, frame_pointer_rtx);
02377 #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
02378 static_reg_base_value[HARD_FRAME_POINTER_REGNUM]
02379 = gen_rtx_ADDRESS (Pmode, hard_frame_pointer_rtx);
02380 #endif
02381 }
02382
02383
02384
02385 static bool memory_modified;
02386 static void
02387 memory_modified_1 (rtx x, rtx pat ATTRIBUTE_UNUSED, void *data)
02388 {
02389 if (MEM_P (x))
02390 {
02391 if (anti_dependence (x, (rtx)data) || output_dependence (x, (rtx)data))
02392 memory_modified = true;
02393 }
02394 }
02395
02396
02397
02398
02399 bool
02400 memory_modified_in_insn_p (rtx mem, rtx insn)
02401 {
02402 if (!INSN_P (insn))
02403 return false;
02404 memory_modified = false;
02405 note_stores (PATTERN (insn), memory_modified_1, mem);
02406 return memory_modified;
02407 }
02408
02409
02410
02411
02412 void
02413 init_alias_analysis (void)
02414 {
02415 unsigned int maxreg = max_reg_num ();
02416 int changed, pass;
02417 int i;
02418 unsigned int ui;
02419 rtx insn;
02420
02421 timevar_push (TV_ALIAS_ANALYSIS);
02422
02423 reg_known_value_size = maxreg - FIRST_PSEUDO_REGISTER;
02424 reg_known_value = ggc_calloc (reg_known_value_size, sizeof (rtx));
02425 reg_known_equiv_p = xcalloc (reg_known_value_size, sizeof (bool));
02426
02427
02428 if (old_reg_base_value)
02429 reg_base_value = old_reg_base_value;
02430
02431 if (reg_base_value)
02432 VEC_truncate (rtx, reg_base_value, 0);
02433
02434 VEC_safe_grow (rtx, gc, reg_base_value, maxreg);
02435 memset (VEC_address (rtx, reg_base_value), 0,
02436 sizeof (rtx) * VEC_length (rtx, reg_base_value));
02437
02438 new_reg_base_value = XNEWVEC (rtx, maxreg);
02439 reg_seen = XNEWVEC (char, maxreg);
02440
02441
02442
02443
02444
02445
02446
02447
02448
02449
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460 pass = 0;
02461 do
02462 {
02463
02464 changed = 0;
02465
02466
02467
02468 unique_id = 0;
02469
02470
02471
02472 copying_arguments = true;
02473
02474
02475 memset (new_reg_base_value, 0, maxreg * sizeof (rtx));
02476
02477
02478 memset (reg_seen, 0, maxreg);
02479
02480
02481
02482
02483
02484
02485
02486
02487
02488 memcpy (new_reg_base_value, static_reg_base_value,
02489 FIRST_PSEUDO_REGISTER * sizeof (rtx));
02490
02491
02492 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
02493 {
02494 if (INSN_P (insn))
02495 {
02496 rtx note, set;
02497
02498 #if defined (HAVE_prologue) || defined (HAVE_epilogue)
02499
02500
02501
02502
02503 if (reload_completed
02504 && prologue_epilogue_contains (insn))
02505 continue;
02506 #endif
02507
02508
02509
02510
02511
02512 if (GET_CODE (PATTERN (insn)) == SET
02513 && REG_NOTES (insn) != 0
02514 && find_reg_note (insn, REG_NOALIAS, NULL_RTX))
02515 record_set (SET_DEST (PATTERN (insn)), NULL_RTX, NULL);
02516 else
02517 note_stores (PATTERN (insn), record_set, NULL);
02518
02519 set = single_set (insn);
02520
02521 if (set != 0
02522 && REG_P (SET_DEST (set))
02523 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
02524 {
02525 unsigned int regno = REGNO (SET_DEST (set));
02526 rtx src = SET_SRC (set);
02527 rtx t;
02528
02529 if (REG_NOTES (insn) != 0
02530 && (((note = find_reg_note (insn, REG_EQUAL, 0)) != 0
02531 && REG_N_SETS (regno) == 1)
02532 || (note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != 0)
02533 && GET_CODE (XEXP (note, 0)) != EXPR_LIST
02534 && ! rtx_varies_p (XEXP (note, 0), 1)
02535 && ! reg_overlap_mentioned_p (SET_DEST (set),
02536 XEXP (note, 0)))
02537 {
02538 set_reg_known_value (regno, XEXP (note, 0));
02539 set_reg_known_equiv_p (regno,
02540 REG_NOTE_KIND (note) == REG_EQUIV);
02541 }
02542 else if (REG_N_SETS (regno) == 1
02543 && GET_CODE (src) == PLUS
02544 && REG_P (XEXP (src, 0))
02545 && (t = get_reg_known_value (REGNO (XEXP (src, 0))))
02546 && GET_CODE (XEXP (src, 1)) == CONST_INT)
02547 {
02548 t = plus_constant (t, INTVAL (XEXP (src, 1)));
02549 set_reg_known_value (regno, t);
02550 set_reg_known_equiv_p (regno, 0);
02551 }
02552 else if (REG_N_SETS (regno) == 1
02553 && ! rtx_varies_p (src, 1))
02554 {
02555 set_reg_known_value (regno, src);
02556 set_reg_known_equiv_p (regno, 0);
02557 }
02558 }
02559 }
02560 else if (NOTE_P (insn)
02561 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG)
02562 copying_arguments = false;
02563 }
02564
02565
02566 gcc_assert (maxreg == (unsigned int) max_reg_num());
02567
02568 for (ui = 0; ui < maxreg; ui++)
02569 {
02570 if (new_reg_base_value[ui]
02571 && new_reg_base_value[ui] != VEC_index (rtx, reg_base_value, ui)
02572 && ! rtx_equal_p (new_reg_base_value[ui],
02573 VEC_index (rtx, reg_base_value, ui)))
02574 {
02575 VEC_replace (rtx, reg_base_value, ui, new_reg_base_value[ui]);
02576 changed = 1;
02577 }
02578 }
02579 }
02580 while (changed && ++pass < MAX_ALIAS_LOOP_PASSES);
02581
02582
02583 for (i = 0; i < (int)reg_known_value_size; i++)
02584 if (reg_known_value[i] == 0)
02585 reg_known_value[i] = regno_reg_rtx[i + FIRST_PSEUDO_REGISTER];
02586
02587
02588
02589
02590
02591
02592
02593
02594
02595
02596
02597 pass = 0;
02598 do
02599 {
02600 changed = 0;
02601 pass++;
02602 for (ui = 0; ui < maxreg; ui++)
02603 {
02604 rtx base = VEC_index (rtx, reg_base_value, ui);
02605 if (base && REG_P (base))
02606 {
02607 unsigned int base_regno = REGNO (base);
02608 if (base_regno == ui)
02609 VEC_replace (rtx, reg_base_value, ui, 0);
02610 else
02611 VEC_replace (rtx, reg_base_value, ui,
02612 VEC_index (rtx, reg_base_value, base_regno));
02613 changed = 1;
02614 }
02615 }
02616 }
02617 while (changed && pass < MAX_ALIAS_LOOP_PASSES);
02618
02619
02620 free (new_reg_base_value);
02621 new_reg_base_value = 0;
02622 free (reg_seen);
02623 reg_seen = 0;
02624 timevar_pop (TV_ALIAS_ANALYSIS);
02625 }
02626
02627 void
02628 end_alias_analysis (void)
02629 {
02630 old_reg_base_value = reg_base_value;
02631 ggc_free (reg_known_value);
02632 reg_known_value = 0;
02633 reg_known_value_size = 0;
02634 free (reg_known_equiv_p);
02635 reg_known_equiv_p = 0;
02636 }
02637
02638 #include "gt-alias.h"