mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-14 14:24:05 +00:00
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
This commit is contained in:
@ -18,7 +18,6 @@
|
|||||||
#include "RenderMachineFunction.h"
|
#include "RenderMachineFunction.h"
|
||||||
#include "Spiller.h"
|
#include "Spiller.h"
|
||||||
#include "VirtRegMap.h"
|
#include "VirtRegMap.h"
|
||||||
#include "VirtRegRewriter.h"
|
|
||||||
#include "llvm/ADT/OwningPtr.h"
|
#include "llvm/ADT/OwningPtr.h"
|
||||||
#include "llvm/ADT/Statistic.h"
|
#include "llvm/ADT/Statistic.h"
|
||||||
#include "llvm/Analysis/AliasAnalysis.h"
|
#include "llvm/Analysis/AliasAnalysis.h"
|
||||||
@ -510,8 +509,7 @@ bool RABasic::runOnMachineFunction(MachineFunction &mf) {
|
|||||||
#endif // !NDEBUG
|
#endif // !NDEBUG
|
||||||
|
|
||||||
// Run rewriter
|
// Run rewriter
|
||||||
std::auto_ptr<VirtRegRewriter> rewriter(createVirtRegRewriter());
|
VRM->rewrite(LIS->getSlotIndexes());
|
||||||
rewriter->runOnMachineFunction(*MF, *VRM, LIS);
|
|
||||||
|
|
||||||
// The pass output is in VirtRegMap. Release all the transient data.
|
// The pass output is in VirtRegMap. Release all the transient data.
|
||||||
releaseMemory();
|
releaseMemory();
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
#include "SpillPlacement.h"
|
#include "SpillPlacement.h"
|
||||||
#include "SplitKit.h"
|
#include "SplitKit.h"
|
||||||
#include "VirtRegMap.h"
|
#include "VirtRegMap.h"
|
||||||
#include "VirtRegRewriter.h"
|
|
||||||
#include "llvm/ADT/Statistic.h"
|
#include "llvm/ADT/Statistic.h"
|
||||||
#include "llvm/Analysis/AliasAnalysis.h"
|
#include "llvm/Analysis/AliasAnalysis.h"
|
||||||
#include "llvm/Function.h"
|
#include "llvm/Function.h"
|
||||||
@ -1273,8 +1272,7 @@ bool RAGreedy::runOnMachineFunction(MachineFunction &mf) {
|
|||||||
// Run rewriter
|
// Run rewriter
|
||||||
{
|
{
|
||||||
NamedRegionTimer T("Rewriter", TimerGroupName, TimePassesIsEnabled);
|
NamedRegionTimer T("Rewriter", TimerGroupName, TimePassesIsEnabled);
|
||||||
std::auto_ptr<VirtRegRewriter> rewriter(createVirtRegRewriter());
|
VRM->rewrite(Indexes);
|
||||||
rewriter->runOnMachineFunction(*MF, *VRM, LIS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The pass output is in VirtRegMap. Release all the transient data.
|
// The pass output is in VirtRegMap. Release all the transient data.
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "llvm/CodeGen/MachineFunction.h"
|
#include "llvm/CodeGen/MachineFunction.h"
|
||||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||||
|
#include "llvm/CodeGen/SlotIndexes.h"
|
||||||
#include "llvm/Target/TargetMachine.h"
|
#include "llvm/Target/TargetMachine.h"
|
||||||
#include "llvm/Target/TargetInstrInfo.h"
|
#include "llvm/Target/TargetInstrInfo.h"
|
||||||
#include "llvm/Target/TargetRegisterInfo.h"
|
#include "llvm/Target/TargetRegisterInfo.h"
|
||||||
@ -254,6 +255,76 @@ bool VirtRegMap::FindUnusedRegisters(LiveIntervals* LIs) {
|
|||||||
return AnyUnused;
|
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 {
|
void VirtRegMap::print(raw_ostream &OS, const Module* M) const {
|
||||||
const TargetRegisterInfo* TRI = MF->getTarget().getRegisterInfo();
|
const TargetRegisterInfo* TRI = MF->getTarget().getRegisterInfo();
|
||||||
const MachineRegisterInfo &MRI = MF->getRegInfo();
|
const MachineRegisterInfo &MRI = MF->getRegInfo();
|
||||||
|
@ -35,6 +35,7 @@ namespace llvm {
|
|||||||
class TargetInstrInfo;
|
class TargetInstrInfo;
|
||||||
class TargetRegisterInfo;
|
class TargetRegisterInfo;
|
||||||
class raw_ostream;
|
class raw_ostream;
|
||||||
|
class SlotIndexes;
|
||||||
|
|
||||||
class VirtRegMap : public MachineFunctionPass {
|
class VirtRegMap : public MachineFunctionPass {
|
||||||
public:
|
public:
|
||||||
@ -493,6 +494,13 @@ namespace llvm {
|
|||||||
return 0;
|
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 print(raw_ostream &OS, const Module* M = 0) const;
|
||||||
void dump() const;
|
void dump() const;
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user