This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Infinite loop in init_alias_analysis
- To: law at cygnus dot com
- Subject: Re: Infinite loop in init_alias_analysis
- From: Christian Iseli <chris at lslsun dot epfl dot ch>
- Date: Tue, 04 Nov 1997 21:32:05 +0100
- cc: egcs at cygnus dot com
law@hurl.cygnus.com said:
> > Things happen in the following way: - During the first iteration
> > of the loop, new_reg_base_value[24] is set to (address (reg:HI 1 %r3))
> OK.
> > (reg 1 is a FUNCTION_ARG_REGNO_P) while copying_arguments is
> > true. - Later in the function, new_reg_base_value[1] is set to (reg/v:HI 24)
> OK.
> > - Now the first iteration terminates and the values from
> > new_reg_base_value
> OK.
> > are copied into reg_base_value. - In the next loop iteration,
> > find_base_value is called and promptly returns the values it finds in
> > reg_base_value, which yields to new_reg_base_value[24] => (reg/v:HI
> > 24> ) and new_reg_base_value[1] => (address (reg:HI 1 %r3)) - And
> > so on...
> Sorry, this is where you lost me. Can you describe this better?
I'll try :-)
We seem to agree on the state of things after the first iteration through the
loop;
we have:
reg_base_value[1] == (reg/v:HI 24)
...
reg_base_value[24] == (address (reg:HI 1 %r3))
which were copied from new_reg_base_value.
Now we start a new iteration. find_base_value is called (line 269 of alias.c)
with
(reg:HI 1 %r3) and, since reg_base_value[1] contains (reg/v:HI 24), returns
(reg/v:HI 24).
Thus new_reg_base_value[24] is set to (reg/v:HI 24).
Later, find_base_value is called with (reg/v:HI 24) and, since
reg_base_value[24] contains
(address (reg:HI 1 %r3)), returns (address (reg:HI 1 %r3)).
Thus new_reg_base_value[1] is set to (address (reg:HI 1 %r3)).
At the end of the while loop, things are copied from new_reg_base_value to
reg_base_value
and so, at the end of the second iteration we have:
reg_base_value[1] == (address (reg:HI 1 %r3))
...
reg_base_value[24] == (reg/v:HI 24)
i.e., 1 and 24 were swapped.
So we start the 3rd iteration. find_base_value is called with (reg:HI 1 %r3)
and, since
reg_base_value[1] contains (address (reg:HI 1 %r3)), returns (address (reg:HI
1 %r3)).
Thus new_reg_base_value[24] is set to (address (reg:HI 1 %r3)).
Later, find_base_value is called with (reg/v:HI 24) and, since
reg_base_value[24] contains
(reg/v:HI 24), returns (reg/v:HI 24).
Thus new_reg_base_value[1] is set to (reg/v:HI 24).
At the end of the while loop, things are copied from new_reg_base_value to
reg_base_value
and so, at the end of the third iteration we have:
reg_base_value[1] == (reg/v:HI 24)
...
reg_base_value[24] == (address (reg:HI 1 %r3))
i.e., 1 and 24 were swapped again.
So we have an endless loop.
The C routine that causes a problem looks like
char *foo(char *str, const char *p, int n)
{
some loop doing *str++ = something;
*str = '\0';
return str;
}
str is passed in (reg:HI 1 %r3) and copied into (reg/v:HI 24).
The first setting of (reg:HI 1 %r3) occurs for the return statement.
> > I'm not sure what's the best fix...
> > - do some clever testing of new_reg_base_value and reg_base_value ?
> Such as?
Not allowing to return reg_base_value when it is the same as the argument of
find_base_value...
At the moment, the following patch is my preferred proposition.
I hope I was more clear this time.
Let me know what you think.
Christian
*** alias.c~ Tue Nov 4 10:52:17 1997
--- alias.c Tue Nov 4 14:04:27 1997
*************** find_base_value (src)
*** 95,110 ****
return src;
case REG:
- /* If this REG is related to a known base value, return it. */
- if (reg_base_value[REGNO (src)])
- return reg_base_value[REGNO (src)];
-
/* At the start of a function argument registers have known base
values which may be lost later. Returning an ADDRESS
expression here allows optimization based on argument values
even when the argument registers are used for other purposes. */
if (REGNO (src) < FIRST_PSEUDO_REGISTER && copying_arguments)
return new_reg_base_value[REGNO (src)];
return src;
case MEM:
--- 95,110 ----
return src;
case REG:
/* At the start of a function argument registers have known base
values which may be lost later. Returning an ADDRESS
expression here allows optimization based on argument values
even when the argument registers are used for other purposes. */
if (REGNO (src) < FIRST_PSEUDO_REGISTER && copying_arguments)
return new_reg_base_value[REGNO (src)];
+
+ /* If this REG is related to a known base value, return it. */
+ if (reg_base_value[REGNO (src)])
+ return reg_base_value[REGNO (src)];
return src;
case MEM: