aboutsummaryrefslogtreecommitdiff
path: root/gcc/alias.c
diff options
context:
space:
mode:
authorJeffrey A Law <law@cygnus.com>1997-11-10 07:12:10 +0000
committerJeff Law <law@gcc.gnu.org>1997-11-10 00:12:10 -0700
commitea64ef271db6b01cdd74463d84662fe054be6e7d (patch)
treeddff8d78b2a13cab1df70004e71c53922b7f54d9 /gcc/alias.c
parent0ff27f584bf0b28a6922de4374cd95b714e5a0c3 (diff)
downloadgcc-ea64ef271db6b01cdd74463d84662fe054be6e7d.zip
gcc-ea64ef271db6b01cdd74463d84662fe054be6e7d.tar.gz
gcc-ea64ef271db6b01cdd74463d84662fe054be6e7d.tar.bz2
alias.c (MAX_ALIAS_LOOP_PASSES): Define.
* alias.c (MAX_ALIAS_LOOP_PASSES): Define. (init_alias_analysis): Break out of loops after MAX_ALIAS_LOOP_PASSES. From-SVN: r16415
Diffstat (limited to 'gcc/alias.c')
-rw-r--r--gcc/alias.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/gcc/alias.c b/gcc/alias.c
index 025da50..333aa5c 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -36,6 +36,12 @@ static int memrefs_conflict_p PROTO((int, rtx, int, rtx,
#define SIZE_FOR_MODE(X) (GET_MODE_SIZE (GET_MODE (X)))
+/* Cap the number of passes we make over the insns propagating alias
+ information through set chains.
+
+ 10 is a completely arbitrary choice. */
+#define MAX_ALIAS_LOOP_PASSES 10
+
/* reg_base_value[N] gives an address to which register N is related.
If all sets after the first add or subtract to the current value
or otherwise modify it so it does not point to a different top level
@@ -962,7 +968,7 @@ void
init_alias_analysis ()
{
int maxreg = max_reg_num ();
- int changed;
+ int changed, pass;
register int i;
register rtx insn;
rtx note;
@@ -1002,10 +1008,21 @@ init_alias_analysis ()
We could propagate more information in the first pass by making use
of REG_N_SETS to determine immediately that the alias information
- for a pseudo is "constant". */
+ for a pseudo is "constant".
+
+ A program with an uninitialized variable can cause an infinite loop
+ here. Instead of doing a full dataflow analysis to detect such problems
+ we just cap the number of iterations for the loop.
+
+ The state of the arrays for the set chain in question does not matter
+ since the program has undefined behavior. */
changed = 1;
- while (changed)
+ pass = 0;
+ while (changed && pass < MAX_ALIAS_LOOP_PASSES)
{
+ /* Keep track of the pass number so we can break out of the loop. */
+ pass++;
+
/* Assume nothing will change this iteration of the loop. */
changed = 0;
@@ -1130,10 +1147,15 @@ init_alias_analysis ()
In theory this loop can take as long as O(registers^2), but unless
there are very long dependency chains it will run in close to linear
- time. */
+ time.
+
+ This loop may not be needed any longer now that the main loop does
+ a better job at propagating alias information. */
+ pass = 0;
do
{
changed = 0;
+ pass++;
for (i = 0; i < reg_base_value_size; i++)
{
rtx base = reg_base_value[i];
@@ -1148,7 +1170,7 @@ init_alias_analysis ()
}
}
}
- while (changed);
+ while (changed && pass < MAX_ALIAS_LOOP_PASSES);
new_reg_base_value = 0;
reg_seen = 0;