diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2011-02-18 22:03:18 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2011-02-18 22:03:18 +0000 |
commit | ba05c01dabc40373760a20c874103fc58d4377f0 (patch) | |
tree | 487731548cc0b61e10b46c9f2c2120148658f9fc | |
parent | d8c87888a71c4433d76b48bca6c3e03a17890648 (diff) |
Add VirtRegMap::rewrite() and use it in the new register allocators.
The rewriter works almost identically to -rewriter=trivial, except it also
eliminates any identity copies.
This makes the new register allocators independent of VirtRegRewriter.cpp which
will be going away at the same time as RegAllocLinearScan.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@125967 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/RegAllocBasic.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/RegAllocGreedy.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/VirtRegMap.cpp | 71 | ||||
-rw-r--r-- | lib/CodeGen/VirtRegMap.h | 8 |
4 files changed, 81 insertions, 6 deletions
diff --git a/lib/CodeGen/RegAllocBasic.cpp b/lib/CodeGen/RegAllocBasic.cpp index 18a5a45452..045c8db9da 100644 --- a/lib/CodeGen/RegAllocBasic.cpp +++ b/lib/CodeGen/RegAllocBasic.cpp @@ -18,7 +18,6 @@ #include "RenderMachineFunction.h" #include "Spiller.h" #include "VirtRegMap.h" -#include "VirtRegRewriter.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AliasAnalysis.h" @@ -510,8 +509,7 @@ bool RABasic::runOnMachineFunction(MachineFunction &mf) { #endif // !NDEBUG // Run rewriter - std::auto_ptr<VirtRegRewriter> rewriter(createVirtRegRewriter()); - rewriter->runOnMachineFunction(*MF, *VRM, LIS); + VRM->rewrite(LIS->getSlotIndexes()); // The pass output is in VirtRegMap. Release all the transient data. releaseMemory(); diff --git a/lib/CodeGen/RegAllocGreedy.cpp b/lib/CodeGen/RegAllocGreedy.cpp index 7c35ceb1f5..c4080aef86 100644 --- a/lib/CodeGen/RegAllocGreedy.cpp +++ b/lib/CodeGen/RegAllocGreedy.cpp @@ -21,7 +21,6 @@ #include "SpillPlacement.h" #include "SplitKit.h" #include "VirtRegMap.h" -#include "VirtRegRewriter.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Function.h" @@ -1273,8 +1272,7 @@ bool RAGreedy::runOnMachineFunction(MachineFunction &mf) { // Run rewriter { NamedRegionTimer T("Rewriter", TimerGroupName, TimePassesIsEnabled); - std::auto_ptr<VirtRegRewriter> rewriter(createVirtRegRewriter()); - rewriter->runOnMachineFunction(*MF, *VRM, LIS); + VRM->rewrite(Indexes); } // The pass output is in VirtRegMap. Release all the transient data. diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp index 82c64f36d5..734b87e62f 100644 --- a/lib/CodeGen/VirtRegMap.cpp +++ b/lib/CodeGen/VirtRegMap.cpp @@ -24,6 +24,7 @@ #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/SlotIndexes.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetRegisterInfo.h" @@ -254,6 +255,76 @@ bool VirtRegMap::FindUnusedRegisters(LiveIntervals* LIs) { return AnyUnused; } +void VirtRegMap::rewrite(SlotIndexes *Indexes) { + DEBUG(dbgs() << "********** REWRITE VIRTUAL REGISTERS **********\n" + << "********** Function: " + << MF->getFunction()->getName() << '\n'); + + SmallVector<unsigned, 8> SuperKills; + + for (MachineFunction::iterator MBBI = MF->begin(), MBBE = MF->end(); + MBBI != MBBE; ++MBBI) { + DEBUG(MBBI->print(dbgs(), Indexes)); + for (MachineBasicBlock::iterator MII = MBBI->begin(), MIE = MBBI->end(); + MII != MIE;) { + MachineInstr *MI = MII; + ++MII; + + for (MachineInstr::mop_iterator MOI = MI->operands_begin(), + MOE = MI->operands_end(); MOI != MOE; ++MOI) { + MachineOperand &MO = *MOI; + if (!MO.isReg() || !TargetRegisterInfo::isVirtualRegister(MO.getReg())) + continue; + unsigned VirtReg = MO.getReg(); + unsigned PhysReg = getPhys(VirtReg); + assert(PhysReg != NO_PHYS_REG && "Instruction uses unmapped VirtReg"); + + // Preserve semantics of sub-register operands. + if (MO.getSubReg()) { + // A virtual register kill refers to the whole register, so we may + // have to add <imp-use,kill> operands for the super-register. + if (MO.isUse() && MO.isKill() && !MO.isUndef()) + SuperKills.push_back(PhysReg); + + // We don't have to deal with sub-register defs because + // LiveIntervalAnalysis already added the necessary <imp-def> + // operands. + + // PhysReg operands cannot have subregister indexes. + PhysReg = TRI->getSubReg(PhysReg, MO.getSubReg()); + assert(PhysReg && "Invalid SubReg for physical register"); + MO.setSubReg(0); + } + // Rewrite. Note we could have used MachineOperand::substPhysReg(), but + // we need the inlining here. + MO.setReg(PhysReg); + } + + // Add any missing super-register kills after rewriting the whole + // instruction. + while (!SuperKills.empty()) + MI->addRegisterKilled(SuperKills.pop_back_val(), TRI, true); + + DEBUG(dbgs() << "> " << *MI); + + // Finally, remove any identity copies. + if (MI->isIdentityCopy()) { + DEBUG(dbgs() << "Deleting identity copy.\n"); + RemoveMachineInstrFromMaps(MI); + if (Indexes) + Indexes->removeMachineInstrFromMaps(MI); + // It's safe to erase MI because MII has already been incremented. + MI->eraseFromParent(); + } + } + } + + // Tell MRI about physical registers in use. + for (unsigned Reg = 1, RegE = TRI->getNumRegs(); Reg != RegE; ++Reg) + if (!MRI->reg_nodbg_empty(Reg)) + MRI->setPhysRegUsed(Reg); +} + void VirtRegMap::print(raw_ostream &OS, const Module* M) const { const TargetRegisterInfo* TRI = MF->getTarget().getRegisterInfo(); const MachineRegisterInfo &MRI = MF->getRegInfo(); diff --git a/lib/CodeGen/VirtRegMap.h b/lib/CodeGen/VirtRegMap.h index cbc96bbd4f..a43ac5fc82 100644 --- a/lib/CodeGen/VirtRegMap.h +++ b/lib/CodeGen/VirtRegMap.h @@ -35,6 +35,7 @@ namespace llvm { class TargetInstrInfo; class TargetRegisterInfo; class raw_ostream; + class SlotIndexes; class VirtRegMap : public MachineFunctionPass { public: @@ -493,6 +494,13 @@ namespace llvm { return 0; } + /// rewrite - Rewrite all instructions in MF to use only physical registers + /// by mapping all virtual register operands to their assigned physical + /// registers. + /// + /// @param Indexes Optionally remove deleted instructions from indexes. + void rewrite(SlotIndexes *Indexes); + void print(raw_ostream &OS, const Module* M = 0) const; void dump() const; }; |