mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-10 02:36:06 +00:00
CodeGen/LiveVariables: hoist out code in nested loops
This makes runOnMachineFunction vastly more readable. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216368 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
20d7da5b79
commit
9fdcfdd601
@ -175,6 +175,10 @@ private: // Intermediate data structures
|
||||
/// register which is used in a PHI node. We map that to the BB the vreg
|
||||
/// is coming from.
|
||||
void analyzePHINodes(const MachineFunction& Fn);
|
||||
|
||||
void runOnInstr(MachineInstr *MI, SmallVectorImpl<unsigned> &Defs);
|
||||
|
||||
void runOnBlock(MachineBasicBlock *MBB, unsigned NumRegs);
|
||||
public:
|
||||
|
||||
bool runOnMachineFunction(MachineFunction &MF) override;
|
||||
|
@ -497,6 +497,126 @@ void LiveVariables::UpdatePhysRegDefs(MachineInstr *MI,
|
||||
}
|
||||
}
|
||||
|
||||
void LiveVariables::runOnInstr(MachineInstr *MI,
|
||||
SmallVectorImpl<unsigned> &Defs) {
|
||||
assert(!MI->isDebugValue());
|
||||
// Process all of the operands of the instruction...
|
||||
unsigned NumOperandsToProcess = MI->getNumOperands();
|
||||
|
||||
// Unless it is a PHI node. In this case, ONLY process the DEF, not any
|
||||
// of the uses. They will be handled in other basic blocks.
|
||||
if (MI->isPHI())
|
||||
NumOperandsToProcess = 1;
|
||||
|
||||
// Clear kill and dead markers. LV will recompute them.
|
||||
SmallVector<unsigned, 4> UseRegs;
|
||||
SmallVector<unsigned, 4> DefRegs;
|
||||
SmallVector<unsigned, 1> RegMasks;
|
||||
for (unsigned i = 0; i != NumOperandsToProcess; ++i) {
|
||||
MachineOperand &MO = MI->getOperand(i);
|
||||
if (MO.isRegMask()) {
|
||||
RegMasks.push_back(i);
|
||||
continue;
|
||||
}
|
||||
if (!MO.isReg() || MO.getReg() == 0)
|
||||
continue;
|
||||
unsigned MOReg = MO.getReg();
|
||||
if (MO.isUse()) {
|
||||
MO.setIsKill(false);
|
||||
if (MO.readsReg())
|
||||
UseRegs.push_back(MOReg);
|
||||
} else /*MO.isDef()*/ {
|
||||
MO.setIsDead(false);
|
||||
DefRegs.push_back(MOReg);
|
||||
}
|
||||
}
|
||||
|
||||
MachineBasicBlock *MBB = MI->getParent();
|
||||
// Process all uses.
|
||||
for (unsigned i = 0, e = UseRegs.size(); i != e; ++i) {
|
||||
unsigned MOReg = UseRegs[i];
|
||||
if (TargetRegisterInfo::isVirtualRegister(MOReg))
|
||||
HandleVirtRegUse(MOReg, MBB, MI);
|
||||
else if (!MRI->isReserved(MOReg))
|
||||
HandlePhysRegUse(MOReg, MI);
|
||||
}
|
||||
|
||||
// Process all masked registers. (Call clobbers).
|
||||
for (unsigned i = 0, e = RegMasks.size(); i != e; ++i)
|
||||
HandleRegMask(MI->getOperand(RegMasks[i]));
|
||||
|
||||
// Process all defs.
|
||||
for (unsigned i = 0, e = DefRegs.size(); i != e; ++i) {
|
||||
unsigned MOReg = DefRegs[i];
|
||||
if (TargetRegisterInfo::isVirtualRegister(MOReg))
|
||||
HandleVirtRegDef(MOReg, MI);
|
||||
else if (!MRI->isReserved(MOReg))
|
||||
HandlePhysRegDef(MOReg, MI, Defs);
|
||||
}
|
||||
UpdatePhysRegDefs(MI, Defs);
|
||||
}
|
||||
|
||||
void LiveVariables::runOnBlock(MachineBasicBlock *MBB, const unsigned NumRegs) {
|
||||
// Mark live-in registers as live-in.
|
||||
SmallVector<unsigned, 4> Defs;
|
||||
for (MachineBasicBlock::livein_iterator II = MBB->livein_begin(),
|
||||
EE = MBB->livein_end(); II != EE; ++II) {
|
||||
assert(TargetRegisterInfo::isPhysicalRegister(*II) &&
|
||||
"Cannot have a live-in virtual register!");
|
||||
HandlePhysRegDef(*II, nullptr, Defs);
|
||||
}
|
||||
|
||||
// Loop over all of the instructions, processing them.
|
||||
DistanceMap.clear();
|
||||
unsigned Dist = 0;
|
||||
for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end();
|
||||
I != E; ++I) {
|
||||
MachineInstr *MI = I;
|
||||
if (MI->isDebugValue())
|
||||
continue;
|
||||
DistanceMap.insert(std::make_pair(MI, Dist++));
|
||||
|
||||
runOnInstr(MI, Defs);
|
||||
}
|
||||
|
||||
// Handle any virtual assignments from PHI nodes which might be at the
|
||||
// bottom of this basic block. We check all of our successor blocks to see
|
||||
// if they have PHI nodes, and if so, we simulate an assignment at the end
|
||||
// of the current block.
|
||||
if (!PHIVarInfo[MBB->getNumber()].empty()) {
|
||||
SmallVectorImpl<unsigned> &VarInfoVec = PHIVarInfo[MBB->getNumber()];
|
||||
|
||||
for (SmallVectorImpl<unsigned>::iterator I = VarInfoVec.begin(),
|
||||
E = VarInfoVec.end(); I != E; ++I)
|
||||
// Mark it alive only in the block we are representing.
|
||||
MarkVirtRegAliveInBlock(getVarInfo(*I),MRI->getVRegDef(*I)->getParent(),
|
||||
MBB);
|
||||
}
|
||||
|
||||
// MachineCSE may CSE instructions which write to non-allocatable physical
|
||||
// registers across MBBs. Remember if any reserved register is liveout.
|
||||
SmallSet<unsigned, 4> LiveOuts;
|
||||
for (MachineBasicBlock::const_succ_iterator SI = MBB->succ_begin(),
|
||||
SE = MBB->succ_end(); SI != SE; ++SI) {
|
||||
MachineBasicBlock *SuccMBB = *SI;
|
||||
if (SuccMBB->isLandingPad())
|
||||
continue;
|
||||
for (MachineBasicBlock::livein_iterator LI = SuccMBB->livein_begin(),
|
||||
LE = SuccMBB->livein_end(); LI != LE; ++LI) {
|
||||
unsigned LReg = *LI;
|
||||
if (!TRI->isInAllocatableClass(LReg))
|
||||
// Ignore other live-ins, e.g. those that are live into landing pads.
|
||||
LiveOuts.insert(LReg);
|
||||
}
|
||||
}
|
||||
|
||||
// Loop over PhysRegDef / PhysRegUse, killing any registers that are
|
||||
// available at the end of the basic block.
|
||||
for (unsigned i = 0; i != NumRegs; ++i)
|
||||
if ((PhysRegDef[i] || PhysRegUse[i]) && !LiveOuts.count(i))
|
||||
HandlePhysRegDef(i, nullptr, Defs);
|
||||
}
|
||||
|
||||
bool LiveVariables::runOnMachineFunction(MachineFunction &mf) {
|
||||
MF = &mf;
|
||||
MRI = &mf.getRegInfo();
|
||||
@ -526,116 +646,7 @@ bool LiveVariables::runOnMachineFunction(MachineFunction &mf) {
|
||||
SmallPtrSet<MachineBasicBlock*,16> Visited;
|
||||
|
||||
for (MachineBasicBlock *MBB : depth_first_ext(Entry, Visited)) {
|
||||
// Mark live-in registers as live-in.
|
||||
SmallVector<unsigned, 4> Defs;
|
||||
for (MachineBasicBlock::livein_iterator II = MBB->livein_begin(),
|
||||
EE = MBB->livein_end(); II != EE; ++II) {
|
||||
assert(TargetRegisterInfo::isPhysicalRegister(*II) &&
|
||||
"Cannot have a live-in virtual register!");
|
||||
HandlePhysRegDef(*II, nullptr, Defs);
|
||||
}
|
||||
|
||||
// Loop over all of the instructions, processing them.
|
||||
DistanceMap.clear();
|
||||
unsigned Dist = 0;
|
||||
for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end();
|
||||
I != E; ++I) {
|
||||
MachineInstr *MI = I;
|
||||
if (MI->isDebugValue())
|
||||
continue;
|
||||
DistanceMap.insert(std::make_pair(MI, Dist++));
|
||||
|
||||
// Process all of the operands of the instruction...
|
||||
unsigned NumOperandsToProcess = MI->getNumOperands();
|
||||
|
||||
// Unless it is a PHI node. In this case, ONLY process the DEF, not any
|
||||
// of the uses. They will be handled in other basic blocks.
|
||||
if (MI->isPHI())
|
||||
NumOperandsToProcess = 1;
|
||||
|
||||
// Clear kill and dead markers. LV will recompute them.
|
||||
SmallVector<unsigned, 4> UseRegs;
|
||||
SmallVector<unsigned, 4> DefRegs;
|
||||
SmallVector<unsigned, 1> RegMasks;
|
||||
for (unsigned i = 0; i != NumOperandsToProcess; ++i) {
|
||||
MachineOperand &MO = MI->getOperand(i);
|
||||
if (MO.isRegMask()) {
|
||||
RegMasks.push_back(i);
|
||||
continue;
|
||||
}
|
||||
if (!MO.isReg() || MO.getReg() == 0)
|
||||
continue;
|
||||
unsigned MOReg = MO.getReg();
|
||||
if (MO.isUse()) {
|
||||
MO.setIsKill(false);
|
||||
if (MO.readsReg())
|
||||
UseRegs.push_back(MOReg);
|
||||
} else /*MO.isDef()*/ {
|
||||
MO.setIsDead(false);
|
||||
DefRegs.push_back(MOReg);
|
||||
}
|
||||
}
|
||||
|
||||
// Process all uses.
|
||||
for (unsigned i = 0, e = UseRegs.size(); i != e; ++i) {
|
||||
unsigned MOReg = UseRegs[i];
|
||||
if (TargetRegisterInfo::isVirtualRegister(MOReg))
|
||||
HandleVirtRegUse(MOReg, MBB, MI);
|
||||
else if (!MRI->isReserved(MOReg))
|
||||
HandlePhysRegUse(MOReg, MI);
|
||||
}
|
||||
|
||||
// Process all masked registers. (Call clobbers).
|
||||
for (unsigned i = 0, e = RegMasks.size(); i != e; ++i)
|
||||
HandleRegMask(MI->getOperand(RegMasks[i]));
|
||||
|
||||
// Process all defs.
|
||||
for (unsigned i = 0, e = DefRegs.size(); i != e; ++i) {
|
||||
unsigned MOReg = DefRegs[i];
|
||||
if (TargetRegisterInfo::isVirtualRegister(MOReg))
|
||||
HandleVirtRegDef(MOReg, MI);
|
||||
else if (!MRI->isReserved(MOReg))
|
||||
HandlePhysRegDef(MOReg, MI, Defs);
|
||||
}
|
||||
UpdatePhysRegDefs(MI, Defs);
|
||||
}
|
||||
|
||||
// Handle any virtual assignments from PHI nodes which might be at the
|
||||
// bottom of this basic block. We check all of our successor blocks to see
|
||||
// if they have PHI nodes, and if so, we simulate an assignment at the end
|
||||
// of the current block.
|
||||
if (!PHIVarInfo[MBB->getNumber()].empty()) {
|
||||
SmallVectorImpl<unsigned> &VarInfoVec = PHIVarInfo[MBB->getNumber()];
|
||||
|
||||
for (SmallVectorImpl<unsigned>::iterator I = VarInfoVec.begin(),
|
||||
E = VarInfoVec.end(); I != E; ++I)
|
||||
// Mark it alive only in the block we are representing.
|
||||
MarkVirtRegAliveInBlock(getVarInfo(*I),MRI->getVRegDef(*I)->getParent(),
|
||||
MBB);
|
||||
}
|
||||
|
||||
// MachineCSE may CSE instructions which write to non-allocatable physical
|
||||
// registers across MBBs. Remember if any reserved register is liveout.
|
||||
SmallSet<unsigned, 4> LiveOuts;
|
||||
for (MachineBasicBlock::const_succ_iterator SI = MBB->succ_begin(),
|
||||
SE = MBB->succ_end(); SI != SE; ++SI) {
|
||||
MachineBasicBlock *SuccMBB = *SI;
|
||||
if (SuccMBB->isLandingPad())
|
||||
continue;
|
||||
for (MachineBasicBlock::livein_iterator LI = SuccMBB->livein_begin(),
|
||||
LE = SuccMBB->livein_end(); LI != LE; ++LI) {
|
||||
unsigned LReg = *LI;
|
||||
if (!TRI->isInAllocatableClass(LReg))
|
||||
// Ignore other live-ins, e.g. those that are live into landing pads.
|
||||
LiveOuts.insert(LReg);
|
||||
}
|
||||
}
|
||||
|
||||
// Loop over PhysRegDef / PhysRegUse, killing any registers that are
|
||||
// available at the end of the basic block.
|
||||
for (unsigned i = 0; i != NumRegs; ++i)
|
||||
if ((PhysRegDef[i] || PhysRegUse[i]) && !LiveOuts.count(i))
|
||||
HandlePhysRegDef(i, nullptr, Defs);
|
||||
runOnBlock(MBB, NumRegs);
|
||||
|
||||
PhysRegDef.clear();
|
||||
PhysRegUse.clear();
|
||||
|
Loading…
x
Reference in New Issue
Block a user