summaryrefslogtreecommitdiff
path: root/lib/CodeGen/RegAllocFast.cpp
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2010-07-29 00:52:19 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2010-07-29 00:52:19 +0000
commit4bd94f7bbe2ed6e0d83d03b06c0d20bb346abeca (patch)
tree2e7b1d2d3e39392c15dc534820086f4b2d3a724d /lib/CodeGen/RegAllocFast.cpp
parent887b703d226fe913bf4b5c23935ba5b784eb993c (diff)
downloadllvm-4bd94f7bbe2ed6e0d83d03b06c0d20bb346abeca.tar.gz
llvm-4bd94f7bbe2ed6e0d83d03b06c0d20bb346abeca.tar.bz2
llvm-4bd94f7bbe2ed6e0d83d03b06c0d20bb346abeca.tar.xz
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@109715 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/RegAllocFast.cpp')
-rw-r--r--lib/CodeGen/RegAllocFast.cpp14
1 files changed, 11 insertions, 3 deletions
diff --git a/lib/CodeGen/RegAllocFast.cpp b/lib/CodeGen/RegAllocFast.cpp
index e34fcdbebb..66f83d823e 100644
--- a/lib/CodeGen/RegAllocFast.cpp
+++ b/lib/CodeGen/RegAllocFast.cpp
@@ -847,13 +847,18 @@ void RAFast::AllocateBasicBlock() {
// operands. If there are also physical defs, these registers must avoid
// both physical defs and uses, making them more constrained than normal
// 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
// pass for all inline asm.
if (MI->isInlineAsm() || hasEarlyClobbers || hasPartialRedefs ||
- (hasTiedOps && hasPhysDefs)) {
+ (hasTiedOps && (hasPhysDefs || TID.getNumDefs() > 1))) {
handleThroughOperands(MI, VirtDead);
// Don't attempt coalescing when we have funny stuff going on.
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.
@@ -874,14 +879,17 @@ void RAFast::AllocateBasicBlock() {
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();
if (hasEarlyClobbers) {
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i);
- if (!MO.isReg() || !MO.isDef()) continue;
+ if (!MO.isReg()) continue;
unsigned Reg = MO.getReg();
if (!Reg || !TargetRegisterInfo::isPhysicalRegister(Reg)) continue;
+ // Look for physreg defs and tied uses.
+ if (!MO.isDef() && !MI->isRegTiedToDefOperand(i)) continue;
UsedInInstr.set(Reg);
for (const unsigned *AS = TRI->getAliasSet(Reg); *AS; ++AS)
UsedInInstr.set(*AS);