[llvm-commits] [llvm] r103686 - in /llvm/trunk: lib/CodeGen/RegAllocFast.cpp test/CodeGen/PowerPC/2007-04-30-InlineAsmEarlyClobber.ll test/CodeGen/X86/2008-09-18-inline-asm-2.ll
Jakob Stoklund Olesen
stoklund at 2pi.dk
Wed May 12 17:19:43 PDT 2010
Author: stoklund
Date: Wed May 12 19:19:43 2010
New Revision: 103686
URL: http://llvm.org/viewvc/llvm-project?rev=103686&view=rev
Log:
Take allocation hints from copy instructions to/from physregs.
This causes way more identity copies to be generated, ripe for coalescing.
Modified:
llvm/trunk/lib/CodeGen/RegAllocFast.cpp
llvm/trunk/test/CodeGen/PowerPC/2007-04-30-InlineAsmEarlyClobber.ll
llvm/trunk/test/CodeGen/X86/2008-09-18-inline-asm-2.ll
Modified: llvm/trunk/lib/CodeGen/RegAllocFast.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocFast.cpp?rev=103686&r1=103685&r2=103686&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/RegAllocFast.cpp (original)
+++ llvm/trunk/lib/CodeGen/RegAllocFast.cpp Wed May 12 19:19:43 2010
@@ -49,6 +49,7 @@
private:
const TargetMachine *TM;
MachineFunction *MF;
+ MachineRegisterInfo *MRI;
const TargetRegisterInfo *TRI;
const TargetInstrInfo *TII;
@@ -132,11 +133,11 @@
LiveRegMap::iterator assignVirtToPhysReg(unsigned VirtReg,
unsigned PhysReg);
LiveRegMap::iterator allocVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
- unsigned VirtReg);
+ unsigned VirtReg, unsigned Hint);
unsigned defineVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
- unsigned OpNum, unsigned VirtReg);
+ unsigned OpNum, unsigned VirtReg, unsigned Hint);
unsigned reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
- unsigned OpNum, unsigned VirtReg);
+ unsigned OpNum, unsigned VirtReg, unsigned Hint);
void reservePhysReg(MachineBasicBlock &MBB, MachineInstr *MI,
unsigned PhysReg);
void spillAll(MachineBasicBlock &MBB, MachineInstr *MI);
@@ -216,7 +217,7 @@
LR.Dirty = false;
DEBUG(dbgs() << " Spilling register " << TRI->getName(LR.PhysReg)
<< " containing %reg" << VirtReg);
- const TargetRegisterClass *RC = MF->getRegInfo().getRegClass(VirtReg);
+ const TargetRegisterClass *RC = MRI->getRegClass(VirtReg);
int FrameIndex = getStackSpaceFor(VirtReg, RC);
DEBUG(dbgs() << " to stack slot #" << FrameIndex << "\n");
TII->storeRegToStackSlot(MBB, MI, LR.PhysReg, spillKill,
@@ -331,15 +332,52 @@
/// allocVirtReg - Allocate a physical register for VirtReg.
RAFast::LiveRegMap::iterator RAFast::allocVirtReg(MachineBasicBlock &MBB,
MachineInstr *MI,
- unsigned VirtReg) {
+ unsigned VirtReg,
+ unsigned Hint) {
const unsigned spillCost = 100;
assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
"Can only allocate virtual registers");
- const TargetRegisterClass *RC = MF->getRegInfo().getRegClass(VirtReg);
+ const TargetRegisterClass *RC = MRI->getRegClass(VirtReg);
TargetRegisterClass::iterator AOB = RC->allocation_order_begin(*MF);
TargetRegisterClass::iterator AOE = RC->allocation_order_end(*MF);
+ // Ignore invalid hints.
+ if (Hint && (!TargetRegisterInfo::isPhysicalRegister(Hint) ||
+ !RC->contains(Hint) || UsedInInstr.test(Hint)))
+ Hint = 0;
+
+ // If there is no hint, peek at the first use of this register.
+ if (!Hint && !MRI->use_nodbg_empty(VirtReg)) {
+ MachineInstr &MI = *MRI->use_nodbg_begin(VirtReg);
+ unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
+ // Copy to physreg -> use physreg as hint.
+ if (TII->isMoveInstr(MI, SrcReg, DstReg, SrcSubReg, DstSubReg) &&
+ SrcReg == VirtReg && TargetRegisterInfo::isPhysicalRegister(DstReg) &&
+ RC->contains(DstReg) && !UsedInInstr.test(DstReg)) {
+ Hint = DstReg;
+ DEBUG(dbgs() << " %reg" << VirtReg << " gets hint from " << MI);
+ }
+ }
+
+ // Take hint when possible.
+ if (Hint) {
+ assert(RC->contains(Hint) && !UsedInInstr.test(Hint) &&
+ "Invalid hint should have been cleared");
+ switch(PhysRegState[Hint]) {
+ case regDisabled:
+ case regReserved:
+ break;
+ default:
+ DEBUG(dbgs() << " %reg" << VirtReg << " really wants "
+ << TRI->getName(Hint) << "\n");
+ spillVirtReg(MBB, MI, PhysRegState[Hint], true);
+ // Fall through.
+ case regFree:
+ return assignVirtToPhysReg(VirtReg, Hint);
+ }
+ }
+
// First try to find a completely free register.
unsigned BestCost = 0, BestReg = 0;
bool hasDisabled = false;
@@ -447,12 +485,12 @@
/// defineVirtReg - Allocate a register for VirtReg and mark it as dirty.
unsigned RAFast::defineVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
- unsigned OpNum, unsigned VirtReg) {
+ unsigned OpNum, unsigned VirtReg, unsigned Hint) {
assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
"Not a virtual register");
LiveRegMap::iterator lri = LiveVirtRegs.find(VirtReg);
if (lri == LiveVirtRegs.end())
- lri = allocVirtReg(MBB, MI, VirtReg);
+ lri = allocVirtReg(MBB, MI, VirtReg, Hint);
else
addKillFlag(lri); // Kill before redefine.
LiveReg &LR = lri->second;
@@ -465,13 +503,13 @@
/// reloadVirtReg - Make sure VirtReg is available in a physreg and return it.
unsigned RAFast::reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
- unsigned OpNum, unsigned VirtReg) {
+ unsigned OpNum, unsigned VirtReg, unsigned Hint) {
assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
"Not a virtual register");
LiveRegMap::iterator lri = LiveVirtRegs.find(VirtReg);
if (lri == LiveVirtRegs.end()) {
- lri = allocVirtReg(MBB, MI, VirtReg);
- const TargetRegisterClass *RC = MF->getRegInfo().getRegClass(VirtReg);
+ lri = allocVirtReg(MBB, MI, VirtReg, Hint);
+ const TargetRegisterClass *RC = MRI->getRegClass(VirtReg);
int FrameIndex = getStackSpaceFor(VirtReg, RC);
DEBUG(dbgs() << " Reloading %reg" << VirtReg << " into "
<< TRI->getName(lri->second.PhysReg) << "\n");
@@ -605,6 +643,11 @@
continue;
}
+ // If this is a copy, we may be able to coalesce.
+ unsigned CopySrc, CopyDst, CopySrcSub, CopyDstSub;
+ if (!TII->isMoveInstr(*MI, CopySrc, CopyDst, CopySrcSub, CopyDstSub))
+ CopySrc = CopyDst = 0;
+
// Track registers used by instruction.
UsedInInstr.reset();
PhysDefs.clear();
@@ -651,11 +694,14 @@
unsigned Reg = MO.getReg();
if (!Reg || TargetRegisterInfo::isPhysicalRegister(Reg)) continue;
if (MO.isUse()) {
- setPhysReg(MO, reloadVirtReg(MBB, MI, i, Reg));
+ unsigned PhysReg = reloadVirtReg(MBB, MI, i, Reg, CopyDst);
+ if (CopySrc == Reg)
+ CopySrc = PhysReg;
+ setPhysReg(MO, PhysReg);
if (MO.isKill())
VirtKills.push_back(Reg);
} else if (MO.isEarlyClobber()) {
- unsigned PhysReg = defineVirtReg(MBB, MI, i, Reg);
+ unsigned PhysReg = defineVirtReg(MBB, MI, i, Reg, 0);
setPhysReg(MO, PhysReg);
PhysDefs.push_back(PhysReg);
}
@@ -671,7 +717,7 @@
killPhysReg(PhysKills[i]);
PhysKills.clear();
- MF->getRegInfo().addPhysRegsUsed(UsedInInstr);
+ MRI->addPhysRegsUsed(UsedInInstr);
// Track registers defined by instruction - early clobbers at this point.
UsedInInstr.reset();
@@ -702,7 +748,10 @@
}
if (MO.isDead())
VirtKills.push_back(Reg);
- setPhysReg(MO, defineVirtReg(MBB, MI, i, Reg));
+ unsigned PhysReg = defineVirtReg(MBB, MI, i, Reg, CopySrc);
+ if (CopyDst == Reg)
+ CopyDst = PhysReg;
+ setPhysReg(MO, PhysReg);
}
// Spill all dirty virtregs before a call, in case of an exception.
@@ -721,7 +770,7 @@
killPhysReg(PhysKills[i]);
PhysKills.clear();
- MF->getRegInfo().addPhysRegsUsed(UsedInInstr);
+ MRI->addPhysRegsUsed(UsedInInstr);
}
// Spill all physical registers holding virtual registers now.
@@ -739,6 +788,7 @@
DEBUG(dbgs() << "Machine Function\n");
DEBUG(Fn.dump());
MF = &Fn;
+ MRI = &MF->getRegInfo();
TM = &Fn.getTarget();
TRI = TM->getRegisterInfo();
TII = TM->getInstrInfo();
@@ -748,7 +798,7 @@
// initialize the virtual->physical register map to have a 'null'
// mapping for all virtual registers
- unsigned LastVirtReg = MF->getRegInfo().getLastVirtReg();
+ unsigned LastVirtReg = MRI->getLastVirtReg();
StackSlotForVirtReg.grow(LastVirtReg);
// Loop over all of the basic blocks, eliminating virtual register references
@@ -757,7 +807,7 @@
AllocateBasicBlock(*MBB);
// Make sure the set of used physregs is closed under subreg operations.
- MF->getRegInfo().closePhysRegsUsed(*TRI);
+ MRI->closePhysRegsUsed(*TRI);
StackSlotForVirtReg.clear();
return true;
Modified: llvm/trunk/test/CodeGen/PowerPC/2007-04-30-InlineAsmEarlyClobber.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/2007-04-30-InlineAsmEarlyClobber.ll?rev=103686&r1=103685&r2=103686&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/2007-04-30-InlineAsmEarlyClobber.ll (original)
+++ llvm/trunk/test/CodeGen/PowerPC/2007-04-30-InlineAsmEarlyClobber.ll Wed May 12 19:19:43 2010
@@ -7,8 +7,8 @@
; CHECK: subfze r4,r6
; LOCAL: subfc r6,r5,r4
; LOCAL: subfze r3,r3
-; FAST: subfc r9,r8,r7
-; FAST: subfze r10,r6
+; FAST: subfc r3,r5,r4
+; FAST: subfze r4,r6
; PR1357
Modified: llvm/trunk/test/CodeGen/X86/2008-09-18-inline-asm-2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2008-09-18-inline-asm-2.ll?rev=103686&r1=103685&r2=103686&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/2008-09-18-inline-asm-2.ll (original)
+++ llvm/trunk/test/CodeGen/X86/2008-09-18-inline-asm-2.ll Wed May 12 19:19:43 2010
@@ -1,6 +1,6 @@
; RUN: llc < %s -march=x86 | grep "#%ebp %esi %edi 8(%edx) %eax (%ebx)"
; RUN: llc < %s -march=x86 -regalloc=local | grep "#%edi %ebp %edx 8(%ebx) %eax (%esi)"
-; RUN: llc < %s -march=x86 -regalloc=fast | grep "#%ecx %ebx %edi 8(%ebp) %eax (%esi)"
+; RUN: llc < %s -march=x86 -regalloc=fast | grep "#%ecx %ebx %edx 8(%edi) %eax (%esi)"
; The 1st, 2nd, 3rd and 5th registers above must all be different. The registers
; referenced in the 4th and 6th operands must not be the same as the 1st or 5th
More information about the llvm-commits
mailing list