From 4bf4bafcced902ee6d58a90486768f08a3795d02 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Thu, 13 May 2010 00:19:43 +0000 Subject: Take allocation hints from copy instructions to/from physregs. This causes way more identity copies to be generated, ripe for coalescing. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103686 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/RegAllocFast.cpp | 86 +++++++++++++++++----- .../PowerPC/2007-04-30-InlineAsmEarlyClobber.ll | 4 +- test/CodeGen/X86/2008-09-18-inline-asm-2.ll | 2 +- 3 files changed, 71 insertions(+), 21 deletions(-) diff --git a/lib/CodeGen/RegAllocFast.cpp b/lib/CodeGen/RegAllocFast.cpp index 304162a303..110b7fc1fe 100644 --- a/lib/CodeGen/RegAllocFast.cpp +++ b/lib/CodeGen/RegAllocFast.cpp @@ -49,6 +49,7 @@ namespace { private: const TargetMachine *TM; MachineFunction *MF; + MachineRegisterInfo *MRI; const TargetRegisterInfo *TRI; const TargetInstrInfo *TII; @@ -132,11 +133,11 @@ namespace { 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 @@ void RAFast::spillVirtReg(MachineBasicBlock &MBB, 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 @@ RAFast::assignVirtToPhysReg(unsigned VirtReg, unsigned PhysReg) { /// 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 @@ RAFast::LiveRegMap::iterator RAFast::allocVirtReg(MachineBasicBlock &MBB, /// 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 @@ unsigned RAFast::defineVirtReg(MachineBasicBlock &MBB, MachineInstr *MI, /// 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 @@ void RAFast::AllocateBasicBlock(MachineBasicBlock &MBB) { 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 @@ void RAFast::AllocateBasicBlock(MachineBasicBlock &MBB) { 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 @@ void RAFast::AllocateBasicBlock(MachineBasicBlock &MBB) { 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 @@ void RAFast::AllocateBasicBlock(MachineBasicBlock &MBB) { } 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 @@ void RAFast::AllocateBasicBlock(MachineBasicBlock &MBB) { killPhysReg(PhysKills[i]); PhysKills.clear(); - MF->getRegInfo().addPhysRegsUsed(UsedInInstr); + MRI->addPhysRegsUsed(UsedInInstr); } // Spill all physical registers holding virtual registers now. @@ -739,6 +788,7 @@ bool RAFast::runOnMachineFunction(MachineFunction &Fn) { 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 @@ bool RAFast::runOnMachineFunction(MachineFunction &Fn) { // 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 @@ bool RAFast::runOnMachineFunction(MachineFunction &Fn) { 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; diff --git a/test/CodeGen/PowerPC/2007-04-30-InlineAsmEarlyClobber.ll b/test/CodeGen/PowerPC/2007-04-30-InlineAsmEarlyClobber.ll index 0a75f7a777..be74312777 100644 --- a/test/CodeGen/PowerPC/2007-04-30-InlineAsmEarlyClobber.ll +++ b/test/CodeGen/PowerPC/2007-04-30-InlineAsmEarlyClobber.ll @@ -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 diff --git a/test/CodeGen/X86/2008-09-18-inline-asm-2.ll b/test/CodeGen/X86/2008-09-18-inline-asm-2.ll index 5a1ca88498..d3a227d353 100644 --- a/test/CodeGen/X86/2008-09-18-inline-asm-2.ll +++ b/test/CodeGen/X86/2008-09-18-inline-asm-2.ll @@ -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 -- cgit v1.2.3