From ea64ef271db6b01cdd74463d84662fe054be6e7d Mon Sep 17 00:00:00 2001 From: Jeffrey A Law Date: Mon, 10 Nov 1997 07:12:10 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 5 +++++ gcc/alias.c | 32 +++++++++++++++++++++++++++----- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7c7f88ea6d5..5a1e4f13eb6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +Mon Nov 10 00:05:56 1997 Jeffrey A Law (law@cygnus.com) + + * alias.c (MAX_ALIAS_LOOP_PASSES): Define. + (init_alias_analysis): Break out of loops after MAX_ALIAS_LOOP_PASSES. + Sun Nov 9 02:07:16 1997 Jeffrey A Law (law@cygnus.com) * fixinc.svr4 (__STDC__): Add another case. diff --git a/gcc/alias.c b/gcc/alias.c index 025da501a42..333aa5c754e 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; -- 2.30.2