This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: ICE in change_address at emit_rtl.c
- From: Per Bothner <per at bothner dot com>
- To: Richard Kenner <kenner at vlsi1 dot ultra dot nyu dot edu>
- Cc: gcc at gcc dot gnu dot org
- Date: Sun, 25 Nov 2001 16:12:36 -0800
- Subject: Re: ICE in change_address at emit_rtl.c
- References: <10111252255.AA28755@vlsi1.ultra.nyu.edu>
Richard Kenner wrote:
> The big difference is that the temporary used by LET_EXPR (actually
> LET_EXPR can be used to encode user-level declarations too) has a
> well-defined scope. It is clear when the temporary register needs to
> be allocated (on entrance to the BODY expression) to be allocated, and
> it is clear when it can be freed (on exit from the BODY expression).
> Neither are true for SAVE_EXPR, which is much less well defined.
>
>I disagree. The scopes of both need to be exactly the same: the scope of
>the underlying expression. It's not possible for fold to know that so it
>would have to do the same thing with the new LET_EXPR as for the present
>SAVE_EXPR. I don't see how this changes things at all.
>
Consider the code in fold that converts 2*x to x+x:
/* x*2 is x+x */
if (! wins && real_twop (arg1) && global_bindings_p () == 0
&& ! contains_placeholder_p (arg0))
{
tree arg = save_expr (arg0);
return build (PLUS_EXPR, type, arg, arg);
}
Under my proposal this might be:
/* x*2 is x+x */
if (! wins && real_twop (arg1) && global_bindings_p () == 0
&& ! contains_placeholder_p (arg0)) {
{
tree tmp = make_temp_decl (type);
return build (LET_EXPR, type, tmp, arg0,
build (PLUS_EXPR, type, tmp, tmp));
}
Using a LET_EXPR makes the scope explicit. It is clear that
the scope of the tmp lasts during the evaluation of the let-body,
which is during the evaluation of the PLUS_EXPR. Using a
SAVE_EXPR, the scope of the temporary is "from the first
time the SAVE_EXPR is evaluated until the last time the
SAVE_EXPR is evaluated". We cannot know what this is without
analyzing the entire body of the function.