mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
Fix a bug in the -regalloc=fast handling of exotic two-address instruction with
multiple defs, like t2LDRSB_POST. The first def could accidentally steal the physreg that the second, tied def was required to be allocated to. Now, the tied use-def is treated more like an early clobber, and the physreg is reserved before allocating the other defs. This would never be a problem when the tied def was the only def which is the usual case. This fixes MallocBench/gs for thumb2 -O0. llvm-svn: 109715
This commit is contained in:
parent
6a7ab2405c
commit
7f337a8e64
@ -847,13 +847,18 @@ void RAFast::AllocateBasicBlock() {
|
|||||||
// operands. If there are also physical defs, these registers must avoid
|
// operands. If there are also physical defs, these registers must avoid
|
||||||
// both physical defs and uses, making them more constrained than normal
|
// both physical defs and uses, making them more constrained than normal
|
||||||
// operands.
|
// operands.
|
||||||
|
// Similarly, if there are multiple defs and tied operands, we must make sure
|
||||||
|
// the same register is allocated to uses and defs.
|
||||||
// We didn't detect inline asm tied operands above, so just make this extra
|
// We didn't detect inline asm tied operands above, so just make this extra
|
||||||
// pass for all inline asm.
|
// pass for all inline asm.
|
||||||
if (MI->isInlineAsm() || hasEarlyClobbers || hasPartialRedefs ||
|
if (MI->isInlineAsm() || hasEarlyClobbers || hasPartialRedefs ||
|
||||||
(hasTiedOps && hasPhysDefs)) {
|
(hasTiedOps && (hasPhysDefs || TID.getNumDefs() > 1))) {
|
||||||
handleThroughOperands(MI, VirtDead);
|
handleThroughOperands(MI, VirtDead);
|
||||||
// Don't attempt coalescing when we have funny stuff going on.
|
// Don't attempt coalescing when we have funny stuff going on.
|
||||||
CopyDst = 0;
|
CopyDst = 0;
|
||||||
|
// Pretend we have early clobbers so the use operands get marked below.
|
||||||
|
// This is not necessary for the common case of a single tied use.
|
||||||
|
hasEarlyClobbers = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Second scan.
|
// Second scan.
|
||||||
@ -874,14 +879,17 @@ void RAFast::AllocateBasicBlock() {
|
|||||||
|
|
||||||
MRI->addPhysRegsUsed(UsedInInstr);
|
MRI->addPhysRegsUsed(UsedInInstr);
|
||||||
|
|
||||||
// Track registers defined by instruction - early clobbers at this point.
|
// Track registers defined by instruction - early clobbers and tied uses at
|
||||||
|
// this point.
|
||||||
UsedInInstr.reset();
|
UsedInInstr.reset();
|
||||||
if (hasEarlyClobbers) {
|
if (hasEarlyClobbers) {
|
||||||
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
||||||
MachineOperand &MO = MI->getOperand(i);
|
MachineOperand &MO = MI->getOperand(i);
|
||||||
if (!MO.isReg() || !MO.isDef()) continue;
|
if (!MO.isReg()) continue;
|
||||||
unsigned Reg = MO.getReg();
|
unsigned Reg = MO.getReg();
|
||||||
if (!Reg || !TargetRegisterInfo::isPhysicalRegister(Reg)) continue;
|
if (!Reg || !TargetRegisterInfo::isPhysicalRegister(Reg)) continue;
|
||||||
|
// Look for physreg defs and tied uses.
|
||||||
|
if (!MO.isDef() && !MI->isRegTiedToDefOperand(i)) continue;
|
||||||
UsedInInstr.set(Reg);
|
UsedInInstr.set(Reg);
|
||||||
for (const unsigned *AS = TRI->getAliasSet(Reg); *AS; ++AS)
|
for (const unsigned *AS = TRI->getAliasSet(Reg); *AS; ++AS)
|
||||||
UsedInInstr.set(*AS);
|
UsedInInstr.set(*AS);
|
||||||
|
Loading…
Reference in New Issue
Block a user