Make multiple defs of one vreg possible on one instruction. (#38)

Currently, if this is done, overlapping liveranges are created, and we
hit an assert that ensures our non-overlapping and
built-in-reverse-order invariants during liverange construction.

One could argue that multiple defs of a single vreg don't make a ton of
sense -- which def's value is valid after the instruction? -- but if
they all get the same alloc, then the answer is "whatever was put in
that alloc", and this is just a case of an instruction being a bit
over-eager when listing its registers.

This can arise in practice when operand lists come from combinations or
concatenations: for example, in Cranelift's s390x backend, there is a
"Loop" pseudo-instruction, and the operands of the Loop are the operands
of all the sub-instructions.

It seems more logically cohesive overall to say that one can state an
operand as many times as one likes; so this PR makes it so.
This commit is contained in:
Chris Fallin
2022-04-04 16:22:05 -07:00
committed by GitHub
parent a369150213
commit 0cb08095e6
2 changed files with 47 additions and 13 deletions

View File

@@ -1011,6 +1011,24 @@ pub trait Function {
fn multi_spillslot_named_by_last_slot(&self) -> bool {
false
}
// -----------
// Misc config
// -----------
/// Allow a single instruction to define a vreg multiple times. If
/// allowed, the semantics are as if the definition occurs only
/// once, and all defs will get the same alloc. This flexibility is
/// meant to allow the embedder to more easily aggregate operands
/// together in macro/pseudoinstructions, or e.g. add additional
/// clobbered vregs without taking care to deduplicate. This may be
/// particularly useful when referring to physical registers via
/// pinned vregs. It is optional functionality because a strict mode
/// (at most one def per vreg) is also useful for finding bugs in
/// other applications.
fn allow_multiple_vreg_defs(&self) -> bool {
false
}
}
/// A position before or after an instruction at which we can make an