From 864cf585ffcbe7ac02d1ecd93bdbe1b01e1dbd18 Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Sat, 9 Sep 2017 00:52:46 +0000 Subject: [PATCH] RegAllocFast: Cleanup; NFC - Use range based for - Variable names should start with upper case - Add `const` - Change class name to match filename - Fix doxygen comments - Use MCPhysReg instead of unsigned - Use references instead of pointers where things cannot be nullptr - Misc coding style improvements llvm-svn: 312846 --- llvm/include/llvm/InitializePasses.h | 2 +- llvm/lib/CodeGen/CodeGen.cpp | 2 +- llvm/lib/CodeGen/RegAllocFast.cpp | 595 +++++++++++++-------------- 3 files changed, 298 insertions(+), 301 deletions(-) diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index ba4915ac438e..2a0871f020f2 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -304,7 +304,7 @@ void initializeProfileSummaryInfoWrapperPassPass(PassRegistry&); void initializePromoteLegacyPassPass(PassRegistry&); void initializePruneEHPass(PassRegistry&); void initializeRABasicPass(PassRegistry&); -void initializeRAFastPass(PassRegistry&); +void initializeRegAllocFastPass(PassRegistry&); void initializeRAGreedyPass(PassRegistry&); void initializeReassociateLegacyPassPass(PassRegistry&); void initializeRegBankSelectPass(PassRegistry&); diff --git a/llvm/lib/CodeGen/CodeGen.cpp b/llvm/lib/CodeGen/CodeGen.cpp index b7fd45a3f6a6..75f62ba4719e 100644 --- a/llvm/lib/CodeGen/CodeGen.cpp +++ b/llvm/lib/CodeGen/CodeGen.cpp @@ -78,7 +78,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) { initializePreISelIntrinsicLoweringLegacyPassPass(Registry); initializeProcessImplicitDefsPass(Registry); initializeRABasicPass(Registry); - initializeRAFastPass(Registry); + initializeRegAllocFastPass(Registry); initializeRAGreedyPass(Registry); initializeRegisterCoalescerPass(Registry); initializeRenameIndependentSubregsPass(Registry); diff --git a/llvm/lib/CodeGen/RegAllocFast.cpp b/llvm/lib/CodeGen/RegAllocFast.cpp index ef3cc16cd053..92f653945b55 100644 --- a/llvm/lib/CodeGen/RegAllocFast.cpp +++ b/llvm/lib/CodeGen/RegAllocFast.cpp @@ -7,8 +7,9 @@ // //===----------------------------------------------------------------------===// // -// This register allocator allocates registers to a basic block at a time, -// attempting to keep values in registers and reusing registers as appropriate. +/// \file This register allocator allocates registers to a basic block at a +/// time, attempting to keep values in registers and reusing registers as +/// appropriate. // //===----------------------------------------------------------------------===// @@ -45,33 +46,31 @@ static RegisterRegAlloc fastRegAlloc("fast", "fast register allocator", createFastRegisterAllocator); namespace { - class RAFast : public MachineFunctionPass { + class RegAllocFast : public MachineFunctionPass { public: static char ID; - RAFast() : MachineFunctionPass(ID), StackSlotForVirtReg(-1), - isBulkSpilling(false) {} + RegAllocFast() : MachineFunctionPass(ID), StackSlotForVirtReg(-1) {} private: - MachineFunction *MF; + MachineFrameInfo *MFI; MachineRegisterInfo *MRI; const TargetRegisterInfo *TRI; const TargetInstrInfo *TII; RegisterClassInfo RegClassInfo; - // Basic block currently being allocated. + /// Basic block currently being allocated. MachineBasicBlock *MBB; - // StackSlotForVirtReg - Maps virtual regs to the frame index where these - // values are spilled. + /// Maps virtual regs to the frame index where these values are spilled. IndexedMap StackSlotForVirtReg; - // Everything we know about a live virtual register. + /// Everything we know about a live virtual register. struct LiveReg { - MachineInstr *LastUse; // Last instr to use reg. - unsigned VirtReg; // Virtual register number. - unsigned PhysReg; // Currently held here. - unsigned short LastOpNum; // OpNum on LastUse. - bool Dirty; // Register needs spill. + MachineInstr *LastUse; ///< Last instr to use reg. + unsigned VirtReg; ///< Virtual register number. + MCPhysReg PhysReg; ///< Currently held here. + unsigned short LastOpNum; ///< OpNum on LastUse. + bool Dirty; ///< Register needs spill. explicit LiveReg(unsigned v) : LastUse(nullptr), VirtReg(v), PhysReg(0), LastOpNum(0), Dirty(false){} @@ -83,63 +82,62 @@ namespace { typedef SparseSet LiveRegMap; - // LiveVirtRegs - This map contains entries for each virtual register - // that is currently available in a physical register. + /// This map contains entries for each virtual register that is currently + /// available in a physical register. LiveRegMap LiveVirtRegs; DenseMap > LiveDbgValueMap; - // RegState - Track the state of a physical register. + /// Track the state of a physical register. enum RegState { - // A disabled register is not available for allocation, but an alias may - // be in use. A register can only be moved out of the disabled state if - // all aliases are disabled. + /// A disabled register is not available for allocation, but an alias may + /// be in use. A register can only be moved out of the disabled state if + /// all aliases are disabled. regDisabled, - // A free register is not currently in use and can be allocated - // immediately without checking aliases. + /// A free register is not currently in use and can be allocated + /// immediately without checking aliases. regFree, - // A reserved register has been assigned explicitly (e.g., setting up a - // call parameter), and it remains reserved until it is used. + /// A reserved register has been assigned explicitly (e.g., setting up a + /// call parameter), and it remains reserved until it is used. regReserved - // A register state may also be a virtual register number, indication that - // the physical register is currently allocated to a virtual register. In - // that case, LiveVirtRegs contains the inverse mapping. + /// A register state may also be a virtual register number, indication + /// that the physical register is currently allocated to a virtual + /// register. In that case, LiveVirtRegs contains the inverse mapping. }; - // PhysRegState - One of the RegState enums, or a virtreg. + /// One of the RegState enums, or a virtreg. std::vector PhysRegState; SmallVector VirtDead; SmallVector Coalesced; - // Set of register units. + /// Set of register units. typedef SparseSet UsedInInstrSet; - // Set of register units that are used in the current instruction, and so - // cannot be allocated. + /// Set of register units that are used in the current instruction, and so + /// cannot be allocated. UsedInInstrSet UsedInInstr; - // Mark a physreg as used in this instruction. - void markRegUsedInInstr(unsigned PhysReg) { + /// Mark a physreg as used in this instruction. + void markRegUsedInInstr(MCPhysReg PhysReg) { for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) UsedInInstr.insert(*Units); } - // Check if a physreg or any of its aliases are used in this instruction. - bool isRegUsedInInstr(unsigned PhysReg) const { + /// Check if a physreg or any of its aliases are used in this instruction. + bool isRegUsedInInstr(MCPhysReg PhysReg) const { for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) if (UsedInInstr.count(*Units)) return true; return false; } - // isBulkSpilling - This flag is set when LiveRegMap will be cleared - // completely after spilling all live registers. LiveRegMap entries should - // not be erased. - bool isBulkSpilling; + /// This flag is set when LiveRegMap will be cleared completely after + /// spilling all live registers. LiveRegMap entries should not be erased. + bool isBulkSpilling = false; enum : unsigned { spillClean = 1, @@ -166,29 +164,29 @@ namespace { private: bool runOnMachineFunction(MachineFunction &Fn) override; - void AllocateBasicBlock(); - void handleThroughOperands(MachineInstr *MI, + void allocateBasicBlock(MachineBasicBlock &MBB); + void handleThroughOperands(MachineInstr &MI, SmallVectorImpl &VirtDead); - int getStackSpaceFor(unsigned VirtReg, const TargetRegisterClass *RC); - bool isLastUseOfLocalReg(MachineOperand&); + int getStackSpaceFor(unsigned VirtReg, const TargetRegisterClass &RC); + bool isLastUseOfLocalReg(const MachineOperand &MO) const; - void addKillFlag(const LiveReg&); - void killVirtReg(LiveRegMap::iterator); + void addKillFlag(const LiveReg &LRI); + void killVirtReg(LiveRegMap::iterator LRI); void killVirtReg(unsigned VirtReg); void spillVirtReg(MachineBasicBlock::iterator MI, LiveRegMap::iterator); void spillVirtReg(MachineBasicBlock::iterator MI, unsigned VirtReg); - void usePhysReg(MachineOperand&); - void definePhysReg(MachineInstr &MI, unsigned PhysReg, RegState NewState); - unsigned calcSpillCost(unsigned PhysReg) const; - void assignVirtToPhysReg(LiveReg&, unsigned PhysReg); + void usePhysReg(MachineOperand &MO); + void definePhysReg(MachineInstr &MI, MCPhysReg PhysReg, RegState NewState); + unsigned calcSpillCost(MCPhysReg PhysReg) const; + void assignVirtToPhysReg(LiveReg&, MCPhysReg PhysReg); LiveRegMap::iterator findLiveVirtReg(unsigned VirtReg) { return LiveVirtRegs.find(TargetRegisterInfo::virtReg2Index(VirtReg)); } LiveRegMap::const_iterator findLiveVirtReg(unsigned VirtReg) const { return LiveVirtRegs.find(TargetRegisterInfo::virtReg2Index(VirtReg)); } - LiveRegMap::iterator assignVirtToPhysReg(unsigned VReg, unsigned PhysReg); + LiveRegMap::iterator assignVirtToPhysReg(unsigned VReg, MCPhysReg PhysReg); LiveRegMap::iterator allocVirtReg(MachineInstr &MI, LiveRegMap::iterator, unsigned Hint); LiveRegMap::iterator defineVirtReg(MachineInstr &MI, unsigned OpNum, @@ -196,35 +194,39 @@ namespace { LiveRegMap::iterator reloadVirtReg(MachineInstr &MI, unsigned OpNum, unsigned VirtReg, unsigned Hint); void spillAll(MachineBasicBlock::iterator MI); - bool setPhysReg(MachineInstr *MI, unsigned OpNum, unsigned PhysReg); + bool setPhysReg(MachineInstr &MI, unsigned OpNum, MCPhysReg PhysReg); + + void dumpState(); }; - char RAFast::ID = 0; + char RegAllocFast::ID = 0; } -INITIALIZE_PASS(RAFast, "regallocfast", "Fast Register Allocator", false, false) +INITIALIZE_PASS(RegAllocFast, "regallocfast", "Fast Register Allocator", false, + false) -/// getStackSpaceFor - This allocates space for the specified virtual register -/// to be held on the stack. -int RAFast::getStackSpaceFor(unsigned VirtReg, const TargetRegisterClass *RC) { +/// This allocates space for the specified virtual register to be held on the +/// stack. +int RegAllocFast::getStackSpaceFor(unsigned VirtReg, + const TargetRegisterClass &RC) { // Find the location Reg would belong... int SS = StackSlotForVirtReg[VirtReg]; + // Already has space allocated? if (SS != -1) - return SS; // Already has space allocated? + return SS; // Allocate a new stack object for this spill location... - unsigned Size = TRI->getSpillSize(*RC); - unsigned Align = TRI->getSpillAlignment(*RC); - int FrameIdx = MF->getFrameInfo().CreateSpillStackObject(Size, Align); + unsigned Size = TRI->getSpillSize(RC); + unsigned Align = TRI->getSpillAlignment(RC); + int FrameIdx = MFI->CreateSpillStackObject(Size, Align); // Assign the slot. StackSlotForVirtReg[VirtReg] = FrameIdx; return FrameIdx; } -/// isLastUseOfLocalReg - Return true if MO is the only remaining reference to -/// its virtual register, and it is guaranteed to be a block-local register. -/// -bool RAFast::isLastUseOfLocalReg(MachineOperand &MO) { +/// Return true if MO is the only remaining reference to its virtual register, +/// and it is guaranteed to be a block-local register. +bool RegAllocFast::isLastUseOfLocalReg(const MachineOperand &MO) const { // If the register has ever been spilled or reloaded, we conservatively assume // it is a global register used in multiple blocks. if (StackSlotForVirtReg[MO.getReg()] != -1) @@ -237,8 +239,8 @@ bool RAFast::isLastUseOfLocalReg(MachineOperand &MO) { return ++I == MRI->reg_nodbg_end(); } -/// addKillFlag - Set kill flags on last use of a virtual register. -void RAFast::addKillFlag(const LiveReg &LR) { +/// Set kill flags on last use of a virtual register. +void RegAllocFast::addKillFlag(const LiveReg &LR) { if (!LR.LastUse) return; MachineOperand &MO = LR.LastUse->getOperand(LR.LastOpNum); if (MO.isUse() && !LR.LastUse->isRegTiedToDefOperand(LR.LastOpNum)) { @@ -256,8 +258,8 @@ void RAFast::addKillFlag(const LiveReg &LR) { } } -/// killVirtReg - Mark virtreg as no longer available. -void RAFast::killVirtReg(LiveRegMap::iterator LRI) { +/// Mark virtreg as no longer available. +void RegAllocFast::killVirtReg(LiveRegMap::iterator LRI) { addKillFlag(*LRI); assert(PhysRegState[LRI->PhysReg] == LRI->VirtReg && "Broken RegState mapping"); @@ -267,8 +269,8 @@ void RAFast::killVirtReg(LiveRegMap::iterator LRI) { LiveVirtRegs.erase(LRI); } -/// killVirtReg - Mark virtreg as no longer available. -void RAFast::killVirtReg(unsigned VirtReg) { +/// Mark virtreg as no longer available. +void RegAllocFast::killVirtReg(unsigned VirtReg) { assert(TargetRegisterInfo::isVirtualRegister(VirtReg) && "killVirtReg needs a virtual register"); LiveRegMap::iterator LRI = findLiveVirtReg(VirtReg); @@ -276,9 +278,10 @@ void RAFast::killVirtReg(unsigned VirtReg) { killVirtReg(LRI); } -/// spillVirtReg - This method spills the value specified by VirtReg into the -/// corresponding stack slot if needed. -void RAFast::spillVirtReg(MachineBasicBlock::iterator MI, unsigned VirtReg) { +/// This method spills the value specified by VirtReg into the corresponding +/// stack slot if needed. +void RegAllocFast::spillVirtReg(MachineBasicBlock::iterator MI, + unsigned VirtReg) { assert(TargetRegisterInfo::isVirtualRegister(VirtReg) && "Spilling a physical register is illegal!"); LiveRegMap::iterator LRI = findLiveVirtReg(VirtReg); @@ -286,9 +289,9 @@ void RAFast::spillVirtReg(MachineBasicBlock::iterator MI, unsigned VirtReg) { spillVirtReg(MI, LRI); } -/// spillVirtReg - Do the actual work of spilling. -void RAFast::spillVirtReg(MachineBasicBlock::iterator MI, - LiveRegMap::iterator LRI) { +/// Do the actual work of spilling. +void RegAllocFast::spillVirtReg(MachineBasicBlock::iterator MI, + LiveRegMap::iterator LRI) { LiveReg &LR = *LRI; assert(PhysRegState[LR.PhysReg] == LRI->VirtReg && "Broken RegState mapping"); @@ -299,10 +302,10 @@ void RAFast::spillVirtReg(MachineBasicBlock::iterator MI, LR.Dirty = false; DEBUG(dbgs() << "Spilling " << PrintReg(LRI->VirtReg, TRI) << " in " << PrintReg(LR.PhysReg, TRI)); - const TargetRegisterClass *RC = MRI->getRegClass(LRI->VirtReg); + const TargetRegisterClass &RC = *MRI->getRegClass(LRI->VirtReg); int FI = getStackSpaceFor(LRI->VirtReg, RC); DEBUG(dbgs() << " to stack slot #" << FI << "\n"); - TII->storeRegToStackSlot(*MBB, MI, LR.PhysReg, SpillKill, FI, RC, TRI); + TII->storeRegToStackSlot(*MBB, MI, LR.PhysReg, SpillKill, FI, &RC, TRI); ++NumStores; // Update statistics // If this register is used by DBG_VALUE then insert new DBG_VALUE to @@ -310,8 +313,7 @@ void RAFast::spillVirtReg(MachineBasicBlock::iterator MI, // value. SmallVectorImpl &LRIDbgValues = LiveDbgValueMap[LRI->VirtReg]; - for (unsigned li = 0, le = LRIDbgValues.size(); li != le; ++li) { - MachineInstr *DBG = LRIDbgValues[li]; + for (MachineInstr *DBG : LRIDbgValues) { MachineInstr *NewDV = buildDbgValueForSpill(*MBB, MI, *DBG, FI); assert(NewDV->getParent() == MBB && "dangling parent pointer"); (void)NewDV; @@ -327,32 +329,31 @@ void RAFast::spillVirtReg(MachineBasicBlock::iterator MI, killVirtReg(LRI); } -/// spillAll - Spill all dirty virtregs without killing them. -void RAFast::spillAll(MachineBasicBlock::iterator MI) { +/// Spill all dirty virtregs without killing them. +void RegAllocFast::spillAll(MachineBasicBlock::iterator MI) { if (LiveVirtRegs.empty()) return; isBulkSpilling = true; // The LiveRegMap is keyed by an unsigned (the virtreg number), so the order // of spilling here is deterministic, if arbitrary. - for (LiveRegMap::iterator i = LiveVirtRegs.begin(), e = LiveVirtRegs.end(); - i != e; ++i) - spillVirtReg(MI, i); + for (LiveRegMap::iterator I = LiveVirtRegs.begin(), E = LiveVirtRegs.end(); + I != E; ++I) + spillVirtReg(MI, I); LiveVirtRegs.clear(); isBulkSpilling = false; } -/// usePhysReg - Handle the direct use of a physical register. -/// Check that the register is not used by a virtreg. -/// Kill the physreg, marking it free. -/// This may add implicit kills to MO->getParent() and invalidate MO. -void RAFast::usePhysReg(MachineOperand &MO) { - unsigned PhysReg = MO.getReg(); - assert(TargetRegisterInfo::isPhysicalRegister(PhysReg) && - "Bad usePhysReg operand"); - +/// Handle the direct use of a physical register. Check that the register is +/// not used by a virtreg. Kill the physreg, marking it free. This may add +/// implicit kills to MO->getParent() and invalidate MO. +void RegAllocFast::usePhysReg(MachineOperand &MO) { // Ignore undef uses. if (MO.isUndef()) return; + unsigned PhysReg = MO.getReg(); + assert(TargetRegisterInfo::isPhysicalRegister(PhysReg) && + "Bad usePhysReg operand"); + markRegUsedInInstr(PhysReg); switch (PhysRegState[PhysReg]) { case regDisabled: @@ -371,7 +372,7 @@ void RAFast::usePhysReg(MachineOperand &MO) { // Maybe a superregister is reserved? for (MCRegAliasIterator AI(PhysReg, TRI, false); AI.isValid(); ++AI) { - unsigned Alias = *AI; + MCPhysReg Alias = *AI; switch (PhysRegState[Alias]) { case regDisabled: break; @@ -409,11 +410,11 @@ void RAFast::usePhysReg(MachineOperand &MO) { MO.setIsKill(); } -/// definePhysReg - Mark PhysReg as reserved or free after spilling any -/// virtregs. This is very similar to defineVirtReg except the physreg is -/// reserved instead of allocated. -void RAFast::definePhysReg(MachineInstr &MI, unsigned PhysReg, - RegState NewState) { +/// Mark PhysReg as reserved or free after spilling any virtregs. This is very +/// similar to defineVirtReg except the physreg is reserved instead of +/// allocated. +void RegAllocFast::definePhysReg(MachineInstr &MI, MCPhysReg PhysReg, + RegState NewState) { markRegUsedInInstr(PhysReg); switch (unsigned VirtReg = PhysRegState[PhysReg]) { case regDisabled: @@ -430,7 +431,7 @@ void RAFast::definePhysReg(MachineInstr &MI, unsigned PhysReg, // This is a disabled register, disable all aliases. PhysRegState[PhysReg] = NewState; for (MCRegAliasIterator AI(PhysReg, TRI, false); AI.isValid(); ++AI) { - unsigned Alias = *AI; + MCPhysReg Alias = *AI; switch (unsigned VirtReg = PhysRegState[Alias]) { case regDisabled: break; @@ -448,12 +449,11 @@ void RAFast::definePhysReg(MachineInstr &MI, unsigned PhysReg, } -// calcSpillCost - Return the cost of spilling clearing out PhysReg and -// aliases so it is free for allocation. -// Returns 0 when PhysReg is free or disabled with all aliases disabled - it -// can be allocated directly. -// Returns spillImpossible when PhysReg or an alias can't be spilled. -unsigned RAFast::calcSpillCost(unsigned PhysReg) const { +/// \brief Return the cost of spilling clearing out PhysReg and aliases so it is +/// free for allocation. Returns 0 when PhysReg is free or disabled with all +/// aliases disabled - it can be allocated directly. +/// \returns spillImpossible when PhysReg or an alias can't be spilled. +unsigned RegAllocFast::calcSpillCost(MCPhysReg PhysReg) const { if (isRegUsedInInstr(PhysReg)) { DEBUG(dbgs() << PrintReg(PhysReg, TRI) << " is already used in instr.\n"); return spillImpossible; @@ -478,7 +478,7 @@ unsigned RAFast::calcSpillCost(unsigned PhysReg) const { DEBUG(dbgs() << PrintReg(PhysReg, TRI) << " is disabled.\n"); unsigned Cost = 0; for (MCRegAliasIterator AI(PhysReg, TRI, false); AI.isValid(); ++AI) { - unsigned Alias = *AI; + MCPhysReg Alias = *AI; switch (unsigned VirtReg = PhysRegState[Alias]) { case regDisabled: break; @@ -499,11 +499,10 @@ unsigned RAFast::calcSpillCost(unsigned PhysReg) const { } -/// assignVirtToPhysReg - This method updates local state so that we know -/// that PhysReg is the proper container for VirtReg now. The physical -/// register must not be used for anything else when this is called. -/// -void RAFast::assignVirtToPhysReg(LiveReg &LR, unsigned PhysReg) { +/// \brief This method updates local state so that we know that PhysReg is the +/// proper container for VirtReg now. The physical register must not be used +/// for anything else when this is called. +void RegAllocFast::assignVirtToPhysReg(LiveReg &LR, MCPhysReg PhysReg) { DEBUG(dbgs() << "Assigning " << PrintReg(LR.VirtReg, TRI) << " to " << PrintReg(PhysReg, TRI) << "\n"); PhysRegState[PhysReg] = LR.VirtReg; @@ -511,32 +510,26 @@ void RAFast::assignVirtToPhysReg(LiveReg &LR, unsigned PhysReg) { LR.PhysReg = PhysReg; } -RAFast::LiveRegMap::iterator -RAFast::assignVirtToPhysReg(unsigned VirtReg, unsigned PhysReg) { +RegAllocFast::LiveRegMap::iterator +RegAllocFast::assignVirtToPhysReg(unsigned VirtReg, MCPhysReg PhysReg) { LiveRegMap::iterator LRI = findLiveVirtReg(VirtReg); assert(LRI != LiveVirtRegs.end() && "VirtReg disappeared"); assignVirtToPhysReg(*LRI, PhysReg); return LRI; } -/// allocVirtReg - Allocate a physical register for VirtReg. -RAFast::LiveRegMap::iterator RAFast::allocVirtReg(MachineInstr &MI, - LiveRegMap::iterator LRI, - unsigned Hint) { +/// Allocates a physical register for VirtReg. +RegAllocFast::LiveRegMap::iterator RegAllocFast::allocVirtReg(MachineInstr &MI, + LiveRegMap::iterator LRI, unsigned Hint) { const unsigned VirtReg = LRI->VirtReg; assert(TargetRegisterInfo::isVirtualRegister(VirtReg) && "Can only allocate virtual registers"); - const TargetRegisterClass *RC = MRI->getRegClass(VirtReg); - - // Ignore invalid hints. - if (Hint && (!TargetRegisterInfo::isPhysicalRegister(Hint) || - !RC->contains(Hint) || !MRI->isAllocatable(Hint))) - Hint = 0; - // Take hint when possible. - if (Hint) { + const TargetRegisterClass &RC = *MRI->getRegClass(VirtReg); + if (TargetRegisterInfo::isPhysicalRegister(Hint) && + MRI->isAllocatable(Hint) && RC.contains(Hint)) { // Ignore the hint if we would have to spill a dirty register. unsigned Cost = calcSpillCost(Hint); if (Cost < spillDirty) { @@ -548,11 +541,9 @@ RAFast::LiveRegMap::iterator RAFast::allocVirtReg(MachineInstr &MI, } } - ArrayRef AO = RegClassInfo.getOrder(RC); - // First try to find a completely free register. - for (ArrayRef::iterator I = AO.begin(), E = AO.end(); I != E; ++I){ - unsigned PhysReg = *I; + ArrayRef AO = RegClassInfo.getOrder(&RC); + for (MCPhysReg PhysReg : AO) { if (PhysRegState[PhysReg] == regFree && !isRegUsedInInstr(PhysReg)) { assignVirtToPhysReg(*LRI, PhysReg); return LRI; @@ -560,21 +551,22 @@ RAFast::LiveRegMap::iterator RAFast::allocVirtReg(MachineInstr &MI, } DEBUG(dbgs() << "Allocating " << PrintReg(VirtReg) << " from " - << TRI->getRegClassName(RC) << "\n"); + << TRI->getRegClassName(&RC) << "\n"); - unsigned BestReg = 0, BestCost = spillImpossible; - for (ArrayRef::iterator I = AO.begin(), E = AO.end(); I != E; ++I){ - unsigned Cost = calcSpillCost(*I); - DEBUG(dbgs() << "\tRegister: " << PrintReg(*I, TRI) << "\n"); + unsigned BestReg = 0; + unsigned BestCost = spillImpossible; + for (MCPhysReg PhysReg : AO) { + unsigned Cost = calcSpillCost(PhysReg); + DEBUG(dbgs() << "\tRegister: " << PrintReg(PhysReg, TRI) << "\n"); DEBUG(dbgs() << "\tCost: " << Cost << "\n"); DEBUG(dbgs() << "\tBestCost: " << BestCost << "\n"); // Cost is 0 when all aliases are already disabled. if (Cost == 0) { - assignVirtToPhysReg(*LRI, *I); + assignVirtToPhysReg(*LRI, PhysReg); return LRI; } if (Cost < BestCost) - BestReg = *I, BestCost = Cost; + BestReg = PhysReg, BestCost = Cost; } if (BestReg) { @@ -593,11 +585,11 @@ RAFast::LiveRegMap::iterator RAFast::allocVirtReg(MachineInstr &MI, return assignVirtToPhysReg(VirtReg, *AO.begin()); } -/// defineVirtReg - Allocate a register for VirtReg and mark it as dirty. -RAFast::LiveRegMap::iterator RAFast::defineVirtReg(MachineInstr &MI, - unsigned OpNum, - unsigned VirtReg, - unsigned Hint) { +/// Allocates a register for VirtReg and mark it as dirty. +RegAllocFast::LiveRegMap::iterator RegAllocFast::defineVirtReg(MachineInstr &MI, + unsigned OpNum, + unsigned VirtReg, + unsigned Hint) { assert(TargetRegisterInfo::isVirtualRegister(VirtReg) && "Not a virtual register"); LiveRegMap::iterator LRI; @@ -627,11 +619,11 @@ RAFast::LiveRegMap::iterator RAFast::defineVirtReg(MachineInstr &MI, return LRI; } -/// reloadVirtReg - Make sure VirtReg is available in a physreg and return it. -RAFast::LiveRegMap::iterator RAFast::reloadVirtReg(MachineInstr &MI, - unsigned OpNum, - unsigned VirtReg, - unsigned Hint) { +/// Make sure VirtReg is available in a physreg and return it. +RegAllocFast::LiveRegMap::iterator RegAllocFast::reloadVirtReg(MachineInstr &MI, + unsigned OpNum, + unsigned VirtReg, + unsigned Hint) { assert(TargetRegisterInfo::isVirtualRegister(VirtReg) && "Not a virtual register"); LiveRegMap::iterator LRI; @@ -640,11 +632,11 @@ RAFast::LiveRegMap::iterator RAFast::reloadVirtReg(MachineInstr &MI, MachineOperand &MO = MI.getOperand(OpNum); if (New) { LRI = allocVirtReg(MI, LRI, Hint); - const TargetRegisterClass *RC = MRI->getRegClass(VirtReg); + const TargetRegisterClass &RC = *MRI->getRegClass(VirtReg); int FrameIndex = getStackSpaceFor(VirtReg, RC); DEBUG(dbgs() << "Reloading " << PrintReg(VirtReg, TRI) << " into " << PrintReg(LRI->PhysReg, TRI) << "\n"); - TII->loadRegFromStackSlot(*MBB, MI, LRI->PhysReg, FrameIndex, RC, TRI); + TII->loadRegFromStackSlot(*MBB, MI, LRI->PhysReg, FrameIndex, &RC, TRI); ++NumLoads; } else if (LRI->Dirty) { if (isLastUseOfLocalReg(MO)) { @@ -678,11 +670,12 @@ RAFast::LiveRegMap::iterator RAFast::reloadVirtReg(MachineInstr &MI, return LRI; } -// setPhysReg - Change operand OpNum in MI the refer the PhysReg, considering -// subregs. This may invalidate any operand pointers. -// Return true if the operand kills its register. -bool RAFast::setPhysReg(MachineInstr *MI, unsigned OpNum, unsigned PhysReg) { - MachineOperand &MO = MI->getOperand(OpNum); +/// Changes operand OpNum in MI the refer the PhysReg, considering subregs. This +/// may invalidate any operand pointers. Return true if the operand kills its +/// register. +bool RegAllocFast::setPhysReg(MachineInstr &MI, unsigned OpNum, + MCPhysReg PhysReg) { + MachineOperand &MO = MI.getOperand(OpNum); bool Dead = MO.isDead(); if (!MO.getSubReg()) { MO.setReg(PhysReg); @@ -696,32 +689,31 @@ bool RAFast::setPhysReg(MachineInstr *MI, unsigned OpNum, unsigned PhysReg) { // A kill flag implies killing the full register. Add corresponding super // register kill. if (MO.isKill()) { - MI->addRegisterKilled(PhysReg, TRI, true); + MI.addRegisterKilled(PhysReg, TRI, true); return true; } // A of a sub-register requires an implicit def of the full // register. if (MO.isDef() && MO.isUndef()) - MI->addRegisterDefined(PhysReg, TRI); + MI.addRegisterDefined(PhysReg, TRI); return Dead; } -// Handle special instruction operand like early clobbers and tied ops when +// Handles special instruction operand like early clobbers and tied ops when // there are additional physreg defines. -void RAFast::handleThroughOperands(MachineInstr *MI, - SmallVectorImpl &VirtDead) { +void RegAllocFast::handleThroughOperands(MachineInstr &MI, + SmallVectorImpl &VirtDead) { DEBUG(dbgs() << "Scanning for through registers:"); SmallSet ThroughRegs; - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - MachineOperand &MO = MI->getOperand(i); + for (const MachineOperand &MO : MI.operands()) { if (!MO.isReg()) continue; unsigned Reg = MO.getReg(); if (!TargetRegisterInfo::isVirtualRegister(Reg)) continue; - if (MO.isEarlyClobber() || MI->isRegTiedToDefOperand(i) || - (MO.getSubReg() && MI->readsVirtualRegister(Reg))) { + if (MO.isEarlyClobber() || (MO.isUse() && MO.isTied()) || + (MO.getSubReg() && MI.readsVirtualRegister(Reg))) { if (ThroughRegs.insert(Reg).second) DEBUG(dbgs() << ' ' << PrintReg(Reg)); } @@ -730,63 +722,61 @@ void RAFast::handleThroughOperands(MachineInstr *MI, // If any physreg defines collide with preallocated through registers, // we must spill and reallocate. DEBUG(dbgs() << "\nChecking for physdef collisions.\n"); - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - MachineOperand &MO = MI->getOperand(i); + for (const MachineOperand &MO : MI.operands()) { if (!MO.isReg() || !MO.isDef()) continue; unsigned Reg = MO.getReg(); if (!Reg || !TargetRegisterInfo::isPhysicalRegister(Reg)) continue; markRegUsedInInstr(Reg); for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) { if (ThroughRegs.count(PhysRegState[*AI])) - definePhysReg(*MI, *AI, regFree); + definePhysReg(MI, *AI, regFree); } } SmallVector PartialDefs; DEBUG(dbgs() << "Allocating tied uses.\n"); - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - MachineOperand &MO = MI->getOperand(i); + for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) { + const MachineOperand &MO = MI.getOperand(I); if (!MO.isReg()) continue; unsigned Reg = MO.getReg(); if (!TargetRegisterInfo::isVirtualRegister(Reg)) continue; if (MO.isUse()) { - unsigned DefIdx = 0; - if (!MI->isRegTiedToDefOperand(i, &DefIdx)) continue; - DEBUG(dbgs() << "Operand " << i << "("<< MO << ") is tied to operand " + if (!MO.isTied()) continue; + unsigned DefIdx = MI.findTiedOperandIdx(I); + DEBUG(dbgs() << "Operand " << I << "("<< MO << ") is tied to operand " << DefIdx << ".\n"); - LiveRegMap::iterator LRI = reloadVirtReg(*MI, i, Reg, 0); - unsigned PhysReg = LRI->PhysReg; - setPhysReg(MI, i, PhysReg); + LiveRegMap::iterator LRI = reloadVirtReg(MI, I, Reg, 0); + MCPhysReg PhysReg = LRI->PhysReg; + setPhysReg(MI, I, PhysReg); // Note: we don't update the def operand yet. That would cause the normal // def-scan to attempt spilling. - } else if (MO.getSubReg() && MI->readsVirtualRegister(Reg)) { + } else if (MO.getSubReg() && MI.readsVirtualRegister(Reg)) { DEBUG(dbgs() << "Partial redefine: " << MO << "\n"); // Reload the register, but don't assign to the operand just yet. // That would confuse the later phys-def processing pass. - LiveRegMap::iterator LRI = reloadVirtReg(*MI, i, Reg, 0); + LiveRegMap::iterator LRI = reloadVirtReg(MI, I, Reg, 0); PartialDefs.push_back(LRI->PhysReg); } } DEBUG(dbgs() << "Allocating early clobbers.\n"); - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - MachineOperand &MO = MI->getOperand(i); + for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) { + const MachineOperand &MO = MI.getOperand(I); if (!MO.isReg()) continue; unsigned Reg = MO.getReg(); if (!TargetRegisterInfo::isVirtualRegister(Reg)) continue; if (!MO.isEarlyClobber()) continue; // Note: defineVirtReg may invalidate MO. - LiveRegMap::iterator LRI = defineVirtReg(*MI, i, Reg, 0); - unsigned PhysReg = LRI->PhysReg; - if (setPhysReg(MI, i, PhysReg)) + LiveRegMap::iterator LRI = defineVirtReg(MI, I, Reg, 0); + MCPhysReg PhysReg = LRI->PhysReg; + if (setPhysReg(MI, I, PhysReg)) VirtDead.push_back(Reg); } // Restore UsedInInstr to a state usable for allocating normal virtual uses. UsedInInstr.clear(); - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - MachineOperand &MO = MI->getOperand(i); + for (const MachineOperand &MO : MI.operands()) { if (!MO.isReg() || (MO.isDef() && !MO.isEarlyClobber())) continue; unsigned Reg = MO.getReg(); if (!Reg || !TargetRegisterInfo::isPhysicalRegister(Reg)) continue; @@ -796,20 +786,56 @@ void RAFast::handleThroughOperands(MachineInstr *MI, } // Also mark PartialDefs as used to avoid reallocation. - for (unsigned i = 0, e = PartialDefs.size(); i != e; ++i) - markRegUsedInInstr(PartialDefs[i]); + for (unsigned PartialDef : PartialDefs) + markRegUsedInInstr(PartialDef); } -void RAFast::AllocateBasicBlock() { - DEBUG(dbgs() << "\nAllocating " << *MBB); +#ifndef NDEBUG +void RegAllocFast::dumpState() { + for (unsigned Reg = 1, E = TRI->getNumRegs(); Reg != E; ++Reg) { + if (PhysRegState[Reg] == regDisabled) continue; + dbgs() << " " << TRI->getName(Reg); + switch(PhysRegState[Reg]) { + case regFree: + break; + case regReserved: + dbgs() << "*"; + break; + default: { + dbgs() << '=' << PrintReg(PhysRegState[Reg]); + LiveRegMap::iterator I = findLiveVirtReg(PhysRegState[Reg]); + assert(I != LiveVirtRegs.end() && "Missing VirtReg entry"); + if (I->Dirty) + dbgs() << "*"; + assert(I->PhysReg == Reg && "Bad inverse map"); + break; + } + } + } + dbgs() << '\n'; + // Check that LiveVirtRegs is the inverse. + for (LiveRegMap::iterator i = LiveVirtRegs.begin(), + e = LiveVirtRegs.end(); i != e; ++i) { + assert(TargetRegisterInfo::isVirtualRegister(i->VirtReg) && + "Bad map key"); + assert(TargetRegisterInfo::isPhysicalRegister(i->PhysReg) && + "Bad map value"); + assert(PhysRegState[i->PhysReg] == i->VirtReg && "Bad inverse map"); + } +} +#endif + +void RegAllocFast::allocateBasicBlock(MachineBasicBlock &MBB) { + this->MBB = &MBB; + DEBUG(dbgs() << "\nAllocating " << MBB); PhysRegState.assign(TRI->getNumRegs(), regDisabled); assert(LiveVirtRegs.empty() && "Mapping not cleared from last block?"); - MachineBasicBlock::iterator MII = MBB->begin(); + MachineBasicBlock::iterator MII = MBB.begin(); // Add live-in registers as live. - for (const auto &LI : MBB->liveins()) + for (const MachineBasicBlock::RegisterMaskPair LI : MBB.liveins()) if (MRI->isAllocatable(LI.PhysReg)) definePhysReg(*MII, LI.PhysReg, regReserved); @@ -817,56 +843,27 @@ void RAFast::AllocateBasicBlock() { Coalesced.clear(); // Otherwise, sequentially allocate each instruction in the MBB. - while (MII != MBB->end()) { - MachineInstr *MI = &*MII++; - const MCInstrDesc &MCID = MI->getDesc(); - DEBUG({ - dbgs() << "\n>> " << *MI << "Regs:"; - for (unsigned Reg = 1, E = TRI->getNumRegs(); Reg != E; ++Reg) { - if (PhysRegState[Reg] == regDisabled) continue; - dbgs() << " " << TRI->getName(Reg); - switch(PhysRegState[Reg]) { - case regFree: - break; - case regReserved: - dbgs() << "*"; - break; - default: { - dbgs() << '=' << PrintReg(PhysRegState[Reg]); - LiveRegMap::iterator I = findLiveVirtReg(PhysRegState[Reg]); - assert(I != LiveVirtRegs.end() && "Missing VirtReg entry"); - if (I->Dirty) - dbgs() << "*"; - assert(I->PhysReg == Reg && "Bad inverse map"); - break; - } - } - } - dbgs() << '\n'; - // Check that LiveVirtRegs is the inverse. - for (LiveRegMap::iterator i = LiveVirtRegs.begin(), - e = LiveVirtRegs.end(); i != e; ++i) { - assert(TargetRegisterInfo::isVirtualRegister(i->VirtReg) && - "Bad map key"); - assert(TargetRegisterInfo::isPhysicalRegister(i->PhysReg) && - "Bad map value"); - assert(PhysRegState[i->PhysReg] == i->VirtReg && "Bad inverse map"); - } - }); + for (MachineInstr &MI : MBB) { + const MCInstrDesc &MCID = MI.getDesc(); + DEBUG( + dbgs() << "\n>> " << MI << "Regs:"; + dumpState() + ); // Debug values are not allowed to change codegen in any way. - if (MI->isDebugValue()) { + if (MI.isDebugValue()) { bool ScanDbgValue = true; + MachineInstr *DebugMI = &MI; while (ScanDbgValue) { ScanDbgValue = false; - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - MachineOperand &MO = MI->getOperand(i); + for (unsigned I = 0, E = DebugMI->getNumOperands(); I != E; ++I) { + MachineOperand &MO = DebugMI->getOperand(I); if (!MO.isReg()) continue; unsigned Reg = MO.getReg(); if (!TargetRegisterInfo::isVirtualRegister(Reg)) continue; LiveRegMap::iterator LRI = findLiveVirtReg(Reg); if (LRI != LiveVirtRegs.end()) - setPhysReg(MI, i, LRI->PhysReg); + setPhysReg(*DebugMI, I, LRI->PhysReg); else { int SS = StackSlotForVirtReg[Reg]; if (SS == -1) { @@ -876,18 +873,18 @@ void RAFast::AllocateBasicBlock() { } else { // Modify DBG_VALUE now that the value is in a spill slot. - bool IsIndirect = MI->isIndirectDebugValue(); + bool IsIndirect = DebugMI->isIndirectDebugValue(); if (IsIndirect) - assert(MI->getOperand(1).getImm() == 0 && + assert(DebugMI->getOperand(1).getImm() == 0 && "DBG_VALUE with nonzero offset"); - const MDNode *Var = MI->getDebugVariable(); - const MDNode *Expr = MI->getDebugExpression(); - DebugLoc DL = MI->getDebugLoc(); - MachineBasicBlock *MBB = MI->getParent(); + const MDNode *Var = DebugMI->getDebugVariable(); + const MDNode *Expr = DebugMI->getDebugExpression(); + DebugLoc DL = DebugMI->getDebugLoc(); + MachineBasicBlock *MBB = DebugMI->getParent(); assert( cast(Var)->isValidLocationForIntrinsic(DL) && "Expected inlined-at fields to agree"); - MachineInstr *NewDV = BuildMI(*MBB, MBB->erase(MI), DL, + MachineInstr *NewDV = BuildMI(*MBB, MBB->erase(DebugMI), DL, TII->get(TargetOpcode::DBG_VALUE)) .addFrameIndex(SS) .addImm(0U) @@ -896,12 +893,12 @@ void RAFast::AllocateBasicBlock() { DEBUG(dbgs() << "Modifying debug info due to spill:" << "\t" << *NewDV); // Scan NewDV operands from the beginning. - MI = NewDV; + DebugMI = NewDV; ScanDbgValue = true; break; } } - LiveDbgValueMap[Reg].push_back(MI); + LiveDbgValueMap[Reg].push_back(DebugMI); } } // Next instruction. @@ -909,12 +906,15 @@ void RAFast::AllocateBasicBlock() { } // If this is a copy, we may be able to coalesce. - unsigned CopySrc = 0, CopyDst = 0, CopySrcSub = 0, CopyDstSub = 0; - if (MI->isCopy()) { - CopyDst = MI->getOperand(0).getReg(); - CopySrc = MI->getOperand(1).getReg(); - CopyDstSub = MI->getOperand(0).getSubReg(); - CopySrcSub = MI->getOperand(1).getSubReg(); + unsigned CopySrcReg = 0; + unsigned CopyDstReg = 0; + unsigned CopySrcSub = 0; + unsigned CopyDstSub = 0; + if (MI.isCopy()) { + CopyDstReg = MI.getOperand(0).getReg(); + CopySrcReg = MI.getOperand(1).getReg(); + CopyDstSub = MI.getOperand(0).getSubReg(); + CopySrcSub = MI.getOperand(1).getSubReg(); } // Track registers used by instruction. @@ -928,8 +928,8 @@ void RAFast::AllocateBasicBlock() { bool hasEarlyClobbers = false; bool hasPartialRedefs = false; bool hasPhysDefs = false; - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - MachineOperand &MO = MI->getOperand(i); + for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { + MachineOperand &MO = MI.getOperand(i); // Make sure MRI knows about registers clobbered by regmasks. if (MO.isRegMask()) { MRI->addPhysRegsUsedFromRegMask(MO.getRegMask()); @@ -946,7 +946,7 @@ void RAFast::AllocateBasicBlock() { } else { if (MO.isEarlyClobber()) hasEarlyClobbers = true; - if (MO.getSubReg() && MI->readsVirtualRegister(Reg)) + if (MO.getSubReg() && MI.readsVirtualRegister(Reg)) hasPartialRedefs = true; } continue; @@ -955,7 +955,7 @@ void RAFast::AllocateBasicBlock() { if (MO.isUse()) { usePhysReg(MO); } else if (MO.isEarlyClobber()) { - definePhysReg(*MI, Reg, + definePhysReg(MI, Reg, (MO.isImplicit() || MO.isDead()) ? regFree : regReserved); hasEarlyClobbers = true; } else @@ -971,11 +971,11 @@ void RAFast::AllocateBasicBlock() { // 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 || + if (MI.isInlineAsm() || hasEarlyClobbers || hasPartialRedefs || (hasTiedOps && (hasPhysDefs || MCID.getNumDefs() > 1))) { handleThroughOperands(MI, VirtDead); // Don't attempt coalescing when we have funny stuff going on. - CopyDst = 0; + CopyDstReg = 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; @@ -983,16 +983,16 @@ void RAFast::AllocateBasicBlock() { // Second scan. // Allocate virtreg uses. - for (unsigned i = 0; i != VirtOpEnd; ++i) { - MachineOperand &MO = MI->getOperand(i); + for (unsigned I = 0; I != VirtOpEnd; ++I) { + const MachineOperand &MO = MI.getOperand(I); if (!MO.isReg()) continue; unsigned Reg = MO.getReg(); if (!TargetRegisterInfo::isVirtualRegister(Reg)) continue; if (MO.isUse()) { - LiveRegMap::iterator LRI = reloadVirtReg(*MI, i, Reg, CopyDst); - unsigned PhysReg = LRI->PhysReg; - CopySrc = (CopySrc == Reg || CopySrc == PhysReg) ? PhysReg : 0; - if (setPhysReg(MI, i, PhysReg)) + LiveRegMap::iterator LRI = reloadVirtReg(MI, I, Reg, CopyDstReg); + MCPhysReg PhysReg = LRI->PhysReg; + CopySrcReg = (CopySrcReg == Reg || CopySrcReg == PhysReg) ? PhysReg : 0; + if (setPhysReg(MI, I, PhysReg)) killVirtReg(LRI); } } @@ -1001,19 +1001,18 @@ void RAFast::AllocateBasicBlock() { // this point. UsedInInstr.clear(); if (hasEarlyClobbers) { - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - MachineOperand &MO = MI->getOperand(i); + for (const MachineOperand &MO : MI.operands()) { 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; + if (!MO.isDef() && !MO.isTied()) continue; markRegUsedInInstr(Reg); } } - unsigned DefOpEnd = MI->getNumOperands(); - if (MI->isCall()) { + unsigned DefOpEnd = MI.getNumOperands(); + if (MI.isCall()) { // Spill all virtregs before a call. This serves one purpose: If an // exception is thrown, the landing pad is going to expect to find // registers in their spill slots. @@ -1027,80 +1026,78 @@ void RAFast::AllocateBasicBlock() { // Third scan. // Allocate defs and collect dead defs. - for (unsigned i = 0; i != DefOpEnd; ++i) { - MachineOperand &MO = MI->getOperand(i); + for (unsigned I = 0; I != DefOpEnd; ++I) { + const MachineOperand &MO = MI.getOperand(I); if (!MO.isReg() || !MO.isDef() || !MO.getReg() || MO.isEarlyClobber()) continue; unsigned Reg = MO.getReg(); if (TargetRegisterInfo::isPhysicalRegister(Reg)) { if (!MRI->isAllocatable(Reg)) continue; - definePhysReg(*MI, Reg, MO.isDead() ? regFree : regReserved); + definePhysReg(MI, Reg, MO.isDead() ? regFree : regReserved); continue; } - LiveRegMap::iterator LRI = defineVirtReg(*MI, i, Reg, CopySrc); - unsigned PhysReg = LRI->PhysReg; - if (setPhysReg(MI, i, PhysReg)) { + LiveRegMap::iterator LRI = defineVirtReg(MI, I, Reg, CopySrcReg); + MCPhysReg PhysReg = LRI->PhysReg; + if (setPhysReg(MI, I, PhysReg)) { VirtDead.push_back(Reg); - CopyDst = 0; // cancel coalescing; + CopyDstReg = 0; // cancel coalescing; } else - CopyDst = (CopyDst == Reg || CopyDst == PhysReg) ? PhysReg : 0; + CopyDstReg = (CopyDstReg == Reg || CopyDstReg == PhysReg) ? PhysReg : 0; } // Kill dead defs after the scan to ensure that multiple defs of the same // register are allocated identically. We didn't need to do this for uses // because we are crerating our own kill flags, and they are always at the // last use. - for (unsigned i = 0, e = VirtDead.size(); i != e; ++i) - killVirtReg(VirtDead[i]); + for (unsigned VirtReg : VirtDead) + killVirtReg(VirtReg); VirtDead.clear(); - if (CopyDst && CopyDst == CopySrc && CopyDstSub == CopySrcSub) { - DEBUG(dbgs() << "-- coalescing: " << *MI); - Coalesced.push_back(MI); + if (CopyDstReg && CopyDstReg == CopySrcReg && CopyDstSub == CopySrcSub) { + DEBUG(dbgs() << "-- coalescing: " << MI); + Coalesced.push_back(&MI); } else { - DEBUG(dbgs() << "<< " << *MI); + DEBUG(dbgs() << "<< " << MI); } } // Spill all physical registers holding virtual registers now. DEBUG(dbgs() << "Spilling live registers at end of block.\n"); - spillAll(MBB->getFirstTerminator()); + spillAll(MBB.getFirstTerminator()); // Erase all the coalesced copies. We are delaying it until now because // LiveVirtRegs might refer to the instrs. - for (unsigned i = 0, e = Coalesced.size(); i != e; ++i) - MBB->erase(Coalesced[i]); + for (MachineInstr *MI : Coalesced) + MBB.erase(MI); NumCopies += Coalesced.size(); - DEBUG(MBB->dump()); + DEBUG(MBB.dump()); } -/// runOnMachineFunction - Register allocate the whole function -/// -bool RAFast::runOnMachineFunction(MachineFunction &Fn) { +/// Allocates registers for a function. +bool RegAllocFast::runOnMachineFunction(MachineFunction &MF) { DEBUG(dbgs() << "********** FAST REGISTER ALLOCATION **********\n" - << "********** Function: " << Fn.getName() << '\n'); - MF = &Fn; - MRI = &MF->getRegInfo(); - TRI = MF->getSubtarget().getRegisterInfo(); - TII = MF->getSubtarget().getInstrInfo(); - MRI->freezeReservedRegs(Fn); - RegClassInfo.runOnMachineFunction(Fn); + << "********** Function: " << MF.getName() << '\n'); + MRI = &MF.getRegInfo(); + const TargetSubtargetInfo &STI = MF.getSubtarget(); + TRI = STI.getRegisterInfo(); + TII = STI.getInstrInfo(); + MFI = &MF.getFrameInfo(); + MRI->freezeReservedRegs(MF); + RegClassInfo.runOnMachineFunction(MF); UsedInInstr.clear(); UsedInInstr.setUniverse(TRI->getNumRegUnits()); // initialize the virtual->physical register map to have a 'null' // mapping for all virtual registers - StackSlotForVirtReg.resize(MRI->getNumVirtRegs()); - LiveVirtRegs.setUniverse(MRI->getNumVirtRegs()); + unsigned NumVirtRegs = MRI->getNumVirtRegs(); + StackSlotForVirtReg.resize(NumVirtRegs); + LiveVirtRegs.setUniverse(NumVirtRegs); // Loop over all of the basic blocks, eliminating virtual register references - for (MachineFunction::iterator MBBi = Fn.begin(), MBBe = Fn.end(); - MBBi != MBBe; ++MBBi) { - MBB = &*MBBi; - AllocateBasicBlock(); - } + for (MachineBasicBlock &MBB : MF) + allocateBasicBlock(MBB); // All machine operands and other references to virtual registers have been // replaced. Remove the virtual registers. @@ -1112,5 +1109,5 @@ bool RAFast::runOnMachineFunction(MachineFunction &Fn) { } FunctionPass *llvm::createFastRegisterAllocator() { - return new RAFast(); + return new RegAllocFast(); }