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]
Other format: [Raw text]

Re: Reload reloading outdated values ?


On 2 October 2012 20:25, Frederic Riss <frederic.riss@gmail.com> wrote:
> Something must be wrong, as I don't see how reload can safely move
> memory expressions other than constant addresses around like this.

I dug a bit more, and I'm still confused about this reload behavior.
Let's take this pseudo-RTL code as example:

r229 = mem(r6835, r6823)
... (other insns not touching r229, r6835 or r6823)
r3357 = xor(r219, r229)

At one point at the start of IRA, update_equiv_regs() adds the
REG_EQUIV note after checking that no insn between the r229 def and
it's use break the equivalence:

r229 = mem(r6835, r6823)  => REG_EQUIV mem(r6835, r6823)
... (other insns not touching r229, r6835 or r6823)
r3357 = xor(r219, r229)

Register allocation runs. All register mentioned above _except_ r229
get allocated. r229 is marked for spill by IRA.

Then reload kicks in. It records the equivalence in its reg_equiv
arrays. We end up with a situation like this:

r229 = mem(r8, r21)  => REG_EQUIV mem(r8, r21)
... (other insns not touching r229, r6835 or r6823, _but using r8_)
r54 = xor(r54, r229)

The second insn is reloaded using the recorded equivalence, and the
initial def of r229 is deleted as it was only setting up the
equivalence:

... (other insns not touching r229, r6835 or r6823, _but using r8_)
r44 = mem(r8, r21)
r54 = xor(r54, r44)

Obviously, the code is wrong, and I don't see what can prevent such a
scenario from happening.

I'm even more confused when reading validate_equiv_mem() that is used
to check the equivalence in update_equiv_regs(). It contains that
comment and code in the scan of the insns between the def and the
death of the analyzed register:

      /* This used to ignore readonly memory and const/pure calls.  The problem
	 is the equivalent form may reference a pseudo which gets assigned a
	 call clobbered hard reg.  When we later replace REG with its
	 equivalent form, the value in the call-clobbered reg has been
	 changed and all hell breaks loose.  */
      if (CALL_P (insn))
	return 0;

I understand the comment and the issue, but I don't see what make an
ordinary instruction different from a call. Every pseudo used in any
insn can get allocated to a hard register that would break  the
equivalence, depending of the pseudo interference.

Any clue of what I'm missing?

Fred


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