On Thu, Jan 22, 2026 at 09:55:42AM -0700, Jeffrey Law wrote:
> 
> 
> On 1/16/2026 7:29 AM, Stefan Schulze Frielinghaus wrote:
> > > 
> > > The likely-spilled classes machinery can't be used as-is since the 
> > > decision
> > > for your case is dependent upon context (ie, the insn itself and its
> > > constraints).  So perhaps what we want is your code to peek at the
> > > constraints, but bolted onto the code that's checking for the 
> > > likely-spilled
> > > classes?
> > My knowledge about cse is very thin and so far I don't see how to
> > implement this in hash_rtx() or tight this with likely-spilled classes.
> > For example, having
> > 
> > 1: r100=%1
> > 2: r101=...
> > 3: r102=exp_a(r100)
> > 4: r103=exp_b(r101)
> > 5: r104=exp_c(r100)
> > 
> > Assume that insn 3 has no hard register constraint, but insn 4 does
> > which is referring to hard register %1.  Then I would still like to keep
> > track that r100 and %1 hold the same value, while analyzing insn 1,
> > which enables me to substitute r100 by %1 in insn 3.  For insn 4,
> > however, I would like to invalidate this relation, since operand r101 is
> > potentially loaded into %1 and would clobber the register.  Explicitly
> > clobbering/invalidating register %1 while analyzing insn 4 ensures that
> > r100 is not substituted by %1 in insn 5.
> > 
> > Thus, at first encounter I still want to hash a hard register and at
> > some later point once I encounter a hard register constraint referring to
> > the same hard register, I want to invalidate it.  To be conservative
> > here, I do this irrespective whether an alternative is likely, unlikely,
> > or whatsoever.  Basically I'm treating a hard register constraint as a
> > possible load.
> > 
> > In that regard hard register constraints may not be as restrictive as
> > single register classes, since for the latter even a substitution into
> > insn 3 wouldn't be done if I read the current implementation correctly.
> The basic idea is that by setting "record" to false, the value won't be kept
> in the hash table and it won't be subject to CSE going forward.   For your
> scenario I think we still have a problem; but I don't see a great solution. 
> Essentially at 1, you don't know if %1 is safe to have its lifetime
> extended.   That's the key difference -- more context is needed for the
> single register constraint issues.

Yes, there is basically one contract which has to be fulfilled at the
moment: A hard register N must not be live at an insn which constraints
an operand to hard register N via a hard register constraint or a
constraint referring to a single register class.  That would be a bug
coming either from an optimization or if the target emits a sequence of
instructions where we have assignments to hard registers and usages of
hard register constraints referring to the same hard register.

Assume that in the following r100 is constraint to hard register %1 in
insn 1 and 3.  Furthermore, assume that hard register %1 becomes dead
between insn 2 and 3.

1: r101=exp_a(r100)
   ...
2: %r1=...
   ...
3: r102=exp_b(r100)

Then r100 would be assigned %r1 for insn 1 and spilled prior insn 2 and
reloaded just after insn 2 as soon as %1 becomes dead.  Thus, between
insn 2 and 3 the lifetime of %1 may be extended assuming that no other
insn has a single register constraint referring to %1.  The important
part is that %1 becomes dead somewhere before insn 3, i.e., I have to
prevent CSE to extend the lifetime of register %1 across insn 3.

> 
> ISTM that you have to invalidate the relevant hash table entries at 4.  Not
> sure the best way to do that, most of CSE has fallen out of my brain through
> the years.

Isn't this what is happening by this patch during
invalidate_from_sets_and_clobbers() where we have the context in form of
the insn?  I'm basically removing all hash table entries which are
related to a register which is referred by any hard register constraint.
That should prevent CSE to propagate a hard register any further.

Cheers,
Stefan

Reply via email to