summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorDale Johannesen <dalej@apple.com>2010-02-02 02:08:02 +0000
committerDale Johannesen <dalej@apple.com>2010-02-02 02:08:02 +0000
commitc84816a62ee9b373d4b171204b0b089e0974b19a (patch)
tree2c183c268790d0d53a98c92bf9c37bc8c82c6093 /llvm/lib/CodeGen
parent545168268b398b448e922118cfea38cdab535b85 (diff)
downloadbcm5719-llvm-c84816a62ee9b373d4b171204b0b089e0974b19a.tar.gz
bcm5719-llvm-c84816a62ee9b373d4b171204b0b089e0974b19a.zip
Make local RA smarter about reusing input register of a copy
as output. Needed for (functional) correctness in inline asm, and should be generally beneficial. 7361612. llvm-svn: 95050
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/RegAllocLocal.cpp14
1 files changed, 14 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/RegAllocLocal.cpp b/llvm/lib/CodeGen/RegAllocLocal.cpp
index 6a09bd98166..6a698dec863 100644
--- a/llvm/lib/CodeGen/RegAllocLocal.cpp
+++ b/llvm/lib/CodeGen/RegAllocLocal.cpp
@@ -764,8 +764,11 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
// Determine whether this is a copy instruction. The cases where the
// source or destination are phys regs are handled specially.
unsigned SrcCopyReg, DstCopyReg, SrcCopySubReg, DstCopySubReg;
+ unsigned SrcCopyPhysReg = 0U;
bool isCopy = TII->isMoveInstr(*MI, SrcCopyReg, DstCopyReg,
SrcCopySubReg, DstCopySubReg);
+ if (isCopy && TargetRegisterInfo::isVirtualRegister(SrcCopyReg))
+ SrcCopyPhysReg = getVirt2PhysRegMapSlot(SrcCopyReg);
// Loop over the implicit uses, making sure that they are at the head of the
// use order list, so they don't get reallocated.
@@ -977,13 +980,24 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
// If DestVirtReg already has a value, use it.
if (!(DestPhysReg = getVirt2PhysRegMapSlot(DestVirtReg))) {
+ // If this is a copy try to reuse the input as the output;
+ // that will make the copy go away.
// If this is a copy, the source reg is a phys reg, and
// that reg is available, use that phys reg for DestPhysReg.
+ // If this is a copy, the source reg is a virtual reg, and
+ // the phys reg that was assigned to that virtual reg is now
+ // available, use that phys reg for DestPhysReg. (If it's now
+ // available that means this was the last use of the source.)
if (isCopy &&
TargetRegisterInfo::isPhysicalRegister(SrcCopyReg) &&
isPhysRegAvailable(SrcCopyReg)) {
DestPhysReg = SrcCopyReg;
assignVirtToPhysReg(DestVirtReg, DestPhysReg);
+ } else if (isCopy &&
+ TargetRegisterInfo::isVirtualRegister(SrcCopyReg) &&
+ SrcCopyPhysReg && isPhysRegAvailable(SrcCopyPhysReg)) {
+ DestPhysReg = SrcCopyPhysReg;
+ assignVirtToPhysReg(DestVirtReg, DestPhysReg);
} else
DestPhysReg = getReg(MBB, MI, DestVirtReg);
}
OpenPOWER on IntegriCloud