This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Infinite loop in init_alias_analysis



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:




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]