mirror of
https://github.com/RPCSX/llvm.git
synced 2025-03-01 17:35:38 +00:00
Reintroduce VirtRegRewriter.
OK, not really. We don't want to reintroduce the old rewriter hacks. This patch extracts virtual register rewriting as a separate pass that runs after the register allocator. This is possible now that CodeGen/Passes.cpp can configure the full optimizing register allocator pipeline. The rewriter pass uses register assignments in VirtRegMap to rewrite virtual registers to physical registers, and it inserts kill flags based on live intervals. These finalization steps are the same for the optimizing register allocators: RABasic, RAGreedy, and PBQP. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@158244 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
6660ed5f2f
commit
05ec712e7f
@ -300,6 +300,10 @@ namespace llvm {
|
||||
/// basic blocks.
|
||||
extern char &SpillPlacementID;
|
||||
|
||||
/// VirtRegRewriter pass. Rewrite virtual registers to physical registers as
|
||||
/// assigned in VirtRegMap.
|
||||
extern char &VirtRegRewriterID;
|
||||
|
||||
/// UnreachableMachineBlockElimination - This pass removes unreachable
|
||||
/// machine basic blocks.
|
||||
extern char &UnreachableMachineBlockElimID;
|
||||
|
@ -248,6 +248,7 @@ void initializeUnreachableBlockElimPass(PassRegistry&);
|
||||
void initializeUnreachableMachineBlockElimPass(PassRegistry&);
|
||||
void initializeVerifierPass(PassRegistry&);
|
||||
void initializeVirtRegMapPass(PassRegistry&);
|
||||
void initializeVirtRegRewriterPass(PassRegistry&);
|
||||
void initializeInstSimplifierPass(PassRegistry&);
|
||||
void initializeUnpackMachineBundlesPass(PassRegistry&);
|
||||
void initializeFinalizeMachineBundlesPass(PassRegistry&);
|
||||
|
@ -65,6 +65,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
|
||||
initializeUnreachableBlockElimPass(Registry);
|
||||
initializeUnreachableMachineBlockElimPass(Registry);
|
||||
initializeVirtRegMapPass(Registry);
|
||||
initializeVirtRegRewriterPass(Registry);
|
||||
initializeLowerIntrinsicsPass(Registry);
|
||||
initializeMachineFunctionPrinterPassPass(Registry);
|
||||
}
|
||||
|
@ -609,6 +609,10 @@ void TargetPassConfig::addOptimizedRegAlloc(FunctionPass *RegAllocPass) {
|
||||
PM->add(RegAllocPass);
|
||||
printAndVerify("After Register Allocation");
|
||||
|
||||
// Finally rewrite virtual registers.
|
||||
addPass(VirtRegRewriterID);
|
||||
printAndVerify("After Virtual Register Rewriter");
|
||||
|
||||
// FinalizeRegAlloc is convenient until MachineInstrBundles is more mature,
|
||||
// but eventually, all users of it should probably be moved to addPostRA and
|
||||
// it can go away. Currently, it's the intended place for targets to run
|
||||
|
@ -146,6 +146,7 @@ void RABasic::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addRequired<AliasAnalysis>();
|
||||
AU.addPreserved<AliasAnalysis>();
|
||||
AU.addRequired<LiveIntervals>();
|
||||
AU.addPreserved<LiveIntervals>();
|
||||
AU.addPreserved<SlotIndexes>();
|
||||
AU.addRequired<LiveDebugVariables>();
|
||||
AU.addPreserved<LiveDebugVariables>();
|
||||
@ -335,18 +336,7 @@ bool RABasic::runOnMachineFunction(MachineFunction &mf) {
|
||||
}
|
||||
#endif // !NDEBUG
|
||||
|
||||
// Run rewriter
|
||||
VRM->rewrite(LIS->getSlotIndexes());
|
||||
|
||||
// Write out new DBG_VALUE instructions.
|
||||
getAnalysis<LiveDebugVariables>().emitDebugValues(VRM);
|
||||
|
||||
// All machine operands and other references to virtual registers have been
|
||||
// replaced. Remove the virtual registers and release all the transient data.
|
||||
VRM->clearAllVirt();
|
||||
MRI->clearVirtRegs();
|
||||
releaseMemory();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -337,6 +337,7 @@ void RAGreedy::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addRequired<AliasAnalysis>();
|
||||
AU.addPreserved<AliasAnalysis>();
|
||||
AU.addRequired<LiveIntervals>();
|
||||
AU.addPreserved<LiveIntervals>();
|
||||
AU.addRequired<SlotIndexes>();
|
||||
AU.addPreserved<SlotIndexes>();
|
||||
AU.addRequired<LiveDebugVariables>();
|
||||
@ -1753,25 +1754,6 @@ bool RAGreedy::runOnMachineFunction(MachineFunction &mf) {
|
||||
|
||||
allocatePhysRegs();
|
||||
addMBBLiveIns(MF);
|
||||
LIS->addKillFlags();
|
||||
|
||||
// Run rewriter
|
||||
{
|
||||
NamedRegionTimer T("Rewriter", TimerGroupName, TimePassesIsEnabled);
|
||||
VRM->rewrite(Indexes);
|
||||
}
|
||||
|
||||
// Write out new DBG_VALUE instructions.
|
||||
{
|
||||
NamedRegionTimer T("Emit Debug Info", TimerGroupName, TimePassesIsEnabled);
|
||||
DebugVars->emitDebugValues(VRM);
|
||||
}
|
||||
|
||||
// All machine operands and other references to virtual registers have been
|
||||
// replaced. Remove the virtual registers and release all the transient data.
|
||||
VRM->clearAllVirt();
|
||||
MRI->clearVirtRegs();
|
||||
releaseMemory();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -724,14 +724,6 @@ bool RegAllocPBQP::runOnMachineFunction(MachineFunction &MF) {
|
||||
|
||||
DEBUG(dbgs() << "Post alloc VirtRegMap:\n" << *vrm << "\n");
|
||||
|
||||
// Run rewriter
|
||||
vrm->rewrite(lis->getSlotIndexes());
|
||||
|
||||
// All machine operands and other references to virtual registers have been
|
||||
// replaced. Remove the virtual registers.
|
||||
vrm->clearAllVirt();
|
||||
mri->clearVirtRegs();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -18,12 +18,14 @@
|
||||
|
||||
#define DEBUG_TYPE "regalloc"
|
||||
#include "VirtRegMap.h"
|
||||
#include "LiveDebugVariables.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/SlotIndexes.h"
|
||||
#include "llvm/CodeGen/Passes.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
@ -104,11 +106,117 @@ void VirtRegMap::assignVirt2StackSlot(unsigned virtReg, int SS) {
|
||||
Virt2StackSlotMap[virtReg] = SS;
|
||||
}
|
||||
|
||||
void VirtRegMap::rewrite(SlotIndexes *Indexes) {
|
||||
void VirtRegMap::print(raw_ostream &OS, const Module*) const {
|
||||
OS << "********** REGISTER MAP **********\n";
|
||||
for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) {
|
||||
unsigned Reg = TargetRegisterInfo::index2VirtReg(i);
|
||||
if (Virt2PhysMap[Reg] != (unsigned)VirtRegMap::NO_PHYS_REG) {
|
||||
OS << '[' << PrintReg(Reg, TRI) << " -> "
|
||||
<< PrintReg(Virt2PhysMap[Reg], TRI) << "] "
|
||||
<< MRI->getRegClass(Reg)->getName() << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) {
|
||||
unsigned Reg = TargetRegisterInfo::index2VirtReg(i);
|
||||
if (Virt2StackSlotMap[Reg] != VirtRegMap::NO_STACK_SLOT) {
|
||||
OS << '[' << PrintReg(Reg, TRI) << " -> fi#" << Virt2StackSlotMap[Reg]
|
||||
<< "] " << MRI->getRegClass(Reg)->getName() << "\n";
|
||||
}
|
||||
}
|
||||
OS << '\n';
|
||||
}
|
||||
|
||||
void VirtRegMap::dump() const {
|
||||
print(dbgs());
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// VirtRegRewriter
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The VirtRegRewriter is the last of the register allocator passes.
|
||||
// It rewrites virtual registers to physical registers as specified in the
|
||||
// VirtRegMap analysis. It also updates live-in information on basic blocks
|
||||
// according to LiveIntervals.
|
||||
//
|
||||
namespace {
|
||||
class VirtRegRewriter : public MachineFunctionPass {
|
||||
MachineFunction *MF;
|
||||
const TargetMachine *TM;
|
||||
const TargetRegisterInfo *TRI;
|
||||
const TargetInstrInfo *TII;
|
||||
MachineRegisterInfo *MRI;
|
||||
SlotIndexes *Indexes;
|
||||
LiveIntervals *LIS;
|
||||
VirtRegMap *VRM;
|
||||
|
||||
void rewrite();
|
||||
void addMBBLiveIns();
|
||||
public:
|
||||
static char ID;
|
||||
VirtRegRewriter() : MachineFunctionPass(ID) {}
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
|
||||
|
||||
virtual bool runOnMachineFunction(MachineFunction&);
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
char &llvm::VirtRegRewriterID = VirtRegRewriter::ID;
|
||||
|
||||
INITIALIZE_PASS_BEGIN(VirtRegRewriter, "virtregrewriter",
|
||||
"Virtual Register Rewriter", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
|
||||
INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
|
||||
INITIALIZE_PASS_DEPENDENCY(LiveDebugVariables)
|
||||
INITIALIZE_PASS_DEPENDENCY(VirtRegMap)
|
||||
INITIALIZE_PASS_END(VirtRegRewriter, "virtregrewriter",
|
||||
"Virtual Register Rewriter", false, false)
|
||||
|
||||
char VirtRegRewriter::ID = 0;
|
||||
|
||||
void VirtRegRewriter::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.setPreservesCFG();
|
||||
AU.addRequired<LiveIntervals>();
|
||||
AU.addRequired<SlotIndexes>();
|
||||
AU.addPreserved<SlotIndexes>();
|
||||
AU.addRequired<LiveDebugVariables>();
|
||||
AU.addRequired<VirtRegMap>();
|
||||
MachineFunctionPass::getAnalysisUsage(AU);
|
||||
}
|
||||
|
||||
bool VirtRegRewriter::runOnMachineFunction(MachineFunction &fn) {
|
||||
MF = &fn;
|
||||
TM = &MF->getTarget();
|
||||
TRI = TM->getRegisterInfo();
|
||||
TII = TM->getInstrInfo();
|
||||
MRI = &MF->getRegInfo();
|
||||
Indexes = &getAnalysis<SlotIndexes>();
|
||||
LIS = &getAnalysis<LiveIntervals>();
|
||||
VRM = &getAnalysis<VirtRegMap>();
|
||||
DEBUG(dbgs() << "********** REWRITE VIRTUAL REGISTERS **********\n"
|
||||
<< "********** Function: "
|
||||
<< MF->getFunction()->getName() << '\n');
|
||||
DEBUG(dump());
|
||||
DEBUG(VRM->dump());
|
||||
|
||||
// Add kill flags while we still have virtual registers.
|
||||
LIS->addKillFlags();
|
||||
|
||||
// Rewrite virtual registers.
|
||||
rewrite();
|
||||
|
||||
// Write out new DBG_VALUE instructions.
|
||||
getAnalysis<LiveDebugVariables>().emitDebugValues(VRM);
|
||||
|
||||
// All machine operands and other references to virtual registers have been
|
||||
// replaced. Remove the virtual registers and release all the transient data.
|
||||
VRM->clearAllVirt();
|
||||
MRI->clearVirtRegs();
|
||||
return true;
|
||||
}
|
||||
|
||||
void VirtRegRewriter::rewrite() {
|
||||
SmallVector<unsigned, 8> SuperDeads;
|
||||
SmallVector<unsigned, 8> SuperDefs;
|
||||
SmallVector<unsigned, 8> SuperKills;
|
||||
@ -135,8 +243,9 @@ void VirtRegMap::rewrite(SlotIndexes *Indexes) {
|
||||
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");
|
||||
unsigned PhysReg = VRM->getPhys(VirtReg);
|
||||
assert(PhysReg != VirtRegMap::NO_PHYS_REG &&
|
||||
"Instruction uses unmapped VirtReg");
|
||||
assert(!Reserved.test(PhysReg) && "Reserved register assignment");
|
||||
|
||||
// Preserve semantics of sub-register operands.
|
||||
@ -207,31 +316,3 @@ void VirtRegMap::rewrite(SlotIndexes *Indexes) {
|
||||
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();
|
||||
|
||||
OS << "********** REGISTER MAP **********\n";
|
||||
for (unsigned i = 0, e = MRI.getNumVirtRegs(); i != e; ++i) {
|
||||
unsigned Reg = TargetRegisterInfo::index2VirtReg(i);
|
||||
if (Virt2PhysMap[Reg] != (unsigned)VirtRegMap::NO_PHYS_REG) {
|
||||
OS << '[' << PrintReg(Reg, TRI) << " -> "
|
||||
<< PrintReg(Virt2PhysMap[Reg], TRI) << "] "
|
||||
<< MRI.getRegClass(Reg)->getName() << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned i = 0, e = MRI.getNumVirtRegs(); i != e; ++i) {
|
||||
unsigned Reg = TargetRegisterInfo::index2VirtReg(i);
|
||||
if (Virt2StackSlotMap[Reg] != VirtRegMap::NO_STACK_SLOT) {
|
||||
OS << '[' << PrintReg(Reg, TRI) << " -> fi#" << Virt2StackSlotMap[Reg]
|
||||
<< "] " << MRI.getRegClass(Reg)->getName() << "\n";
|
||||
}
|
||||
}
|
||||
OS << '\n';
|
||||
}
|
||||
|
||||
void VirtRegMap::dump() const {
|
||||
print(dbgs());
|
||||
}
|
||||
|
@ -177,13 +177,6 @@ namespace llvm {
|
||||
/// the specified stack slot
|
||||
void assignVirt2StackSlot(unsigned virtReg, int frameIndex);
|
||||
|
||||
/// 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;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user