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