On 10/19/10 14:42, Ian Lance Taylor wrote:
Jeff Law<l...@redhat.com> writes:
Reload has the ability to replace a pseudo with its equivalent memory
location. This is fine and good.
Imagine:
1. We have a pseudo (call is pseudo A) with a read-only memory
equivalent. Pseudo A does not get a hard reg
2. Pseudo A crosses a call (because the memory is readonly, we will
not invalidate the equivalency)
3. The equivalent memory address references another pseudo (call it
pseudo B)
4. Pseudo B does not cross calls and is assigned a call-clobbered
hard reg.
5. reload replaces pseudo A with its equivalent memory form and in
doing so lengthens the lifetime of pseudo B and causes pseudo B to be
live across a call.
Obviously this is bad. The question is where/how do we want to catch it.
The easy solution is to go ahead and invalidate the equivalency once
we notice that pseudo A crosses a call, even though the memory
equivalent is readonly. Seems a little harsh, but it's a one line
change.
If you can spot this before reload, then you can load the memory address
into a new pseudo C, and let the register allocator decide whether to
save C on the stack or rematerialize it as needed.
That's the problem -- we don't know until reload has completed whether
or not the pseudo with the equivalent memory location will get a hard
register or not.
Otherwise, if you don't invalidate the equivalency, you are effectively
extending the lifetime of pseudo B so that it lives across a call.
Right.
If
there is any register pressure, B is going to go onto the stack or is
going to force something else onto the stack.
Not today, which is the problem. Pseudo B continues to live in the
call-clobbered register which can have its value clobbered by the call
if we replace A with its memory equivalent. ie, we generate incorrect code.
The same problem can occur when we ignore the call because it is marked
as pure/const as well.
At that point, you would
have been better off just putting the memory address on the stack
instead of pseudo B. So I think that invalidating the equivalency
across a function call is probably the right thing to do.
Agreed. I'll prepare a patch.
Jeff