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