mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-03-13 08:35:46 +00:00
Fix for PR929. The PHI nodes were being gone through for each instruction
in a successor block for every block...resulting in some O(N^k) algorithm which wasn't very good for performance. Calculating this information up front and keeping it in a map made it much faster. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30697 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
86f7b2100c
commit
f7da4e939f
@ -39,7 +39,7 @@ class MRegisterInfo;
|
|||||||
class LiveVariables : public MachineFunctionPass {
|
class LiveVariables : public MachineFunctionPass {
|
||||||
public:
|
public:
|
||||||
/// VarInfo - This represents the regions where a virtual register is live in
|
/// VarInfo - This represents the regions where a virtual register is live in
|
||||||
/// the program. We represent this with three difference pieces of
|
/// the program. We represent this with three different pieces of
|
||||||
/// information: the instruction that uniquely defines the value, the set of
|
/// information: the instruction that uniquely defines the value, the set of
|
||||||
/// blocks the instruction is live into and live out of, and the set of
|
/// blocks the instruction is live into and live out of, and the set of
|
||||||
/// non-phi instructions that are the last users of the value.
|
/// non-phi instructions that are the last users of the value.
|
||||||
@ -136,9 +136,19 @@ private: // Intermediate data structures
|
|||||||
MachineInstr **PhysRegInfo;
|
MachineInstr **PhysRegInfo;
|
||||||
bool *PhysRegUsed;
|
bool *PhysRegUsed;
|
||||||
|
|
||||||
|
typedef std::map<const MachineBasicBlock*,
|
||||||
|
std::vector<unsigned> > PHIVarInfoMap;
|
||||||
|
|
||||||
|
PHIVarInfoMap PHIVarInfo;
|
||||||
|
|
||||||
void HandlePhysRegUse(unsigned Reg, MachineInstr *MI);
|
void HandlePhysRegUse(unsigned Reg, MachineInstr *MI);
|
||||||
void HandlePhysRegDef(unsigned Reg, MachineInstr *MI);
|
void HandlePhysRegDef(unsigned Reg, MachineInstr *MI);
|
||||||
|
|
||||||
|
/// analyzePHINodes - Gather information about the PHI nodes in here. In
|
||||||
|
/// particular, we want to map the variable information of a virtual
|
||||||
|
/// register which is used in a PHI node. We map that to the BB the vreg
|
||||||
|
/// is coming from.
|
||||||
|
void analyzePHINodes(const MachineFunction& Fn);
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual bool runOnMachineFunction(MachineFunction &MF);
|
virtual bool runOnMachineFunction(MachineFunction &MF);
|
||||||
|
@ -92,7 +92,6 @@ bool LiveVariables::RegisterDefIsDead(MachineInstr *MI, unsigned Reg) const {
|
|||||||
return std::binary_search(I->second.begin(), I->second.end(), Reg);
|
return std::binary_search(I->second.begin(), I->second.end(), Reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LiveVariables::MarkVirtRegAliveInBlock(VarInfo &VRInfo,
|
void LiveVariables::MarkVirtRegAliveInBlock(VarInfo &VRInfo,
|
||||||
MachineBasicBlock *MBB) {
|
MachineBasicBlock *MBB) {
|
||||||
unsigned BBNum = MBB->getNumber();
|
unsigned BBNum = MBB->getNumber();
|
||||||
@ -212,6 +211,8 @@ bool LiveVariables::runOnMachineFunction(MachineFunction &MF) {
|
|||||||
HandlePhysRegDef(I->first, 0);
|
HandlePhysRegDef(I->first, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
analyzePHINodes(MF);
|
||||||
|
|
||||||
// Calculate live variable information in depth first order on the CFG of the
|
// Calculate live variable information in depth first order on the CFG of the
|
||||||
// function. This guarantees that we will see the definition of a virtual
|
// function. This guarantees that we will see the definition of a virtual
|
||||||
// register before its uses due to dominance properties of SSA (except for PHI
|
// register before its uses due to dominance properties of SSA (except for PHI
|
||||||
@ -288,26 +289,16 @@ bool LiveVariables::runOnMachineFunction(MachineFunction &MF) {
|
|||||||
// bottom of this basic block. We check all of our successor blocks to see
|
// 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
|
// if they have PHI nodes, and if so, we simulate an assignment at the end
|
||||||
// of the current block.
|
// of the current block.
|
||||||
for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(),
|
if (!PHIVarInfo[MBB].empty()) {
|
||||||
E = MBB->succ_end(); SI != E; ++SI) {
|
std::vector<unsigned>& VarInfoVec = PHIVarInfo[MBB];
|
||||||
MachineBasicBlock *Succ = *SI;
|
|
||||||
|
|
||||||
// PHI nodes are guaranteed to be at the top of the block...
|
for (std::vector<unsigned>::iterator I = VarInfoVec.begin(),
|
||||||
for (MachineBasicBlock::iterator MI = Succ->begin(), ME = Succ->end();
|
E = VarInfoVec.end(); I != E; ++I) {
|
||||||
MI != ME && MI->getOpcode() == TargetInstrInfo::PHI; ++MI) {
|
VarInfo& VRInfo = getVarInfo(*I);
|
||||||
for (unsigned i = 1; ; i += 2) {
|
assert(VRInfo.DefInst && "Register use before def (or no def)!");
|
||||||
assert(MI->getNumOperands() > i+1 &&
|
|
||||||
"Didn't find an entry for our predecessor??");
|
|
||||||
if (MI->getOperand(i+1).getMachineBasicBlock() == MBB) {
|
|
||||||
MachineOperand &MO = MI->getOperand(i);
|
|
||||||
VarInfo &VRInfo = getVarInfo(MO.getReg());
|
|
||||||
assert(VRInfo.DefInst && "Register use before def (or no def)!");
|
|
||||||
|
|
||||||
// Only mark it alive only in the block we are representing.
|
// Only mark it alive only in the block we are representing.
|
||||||
MarkVirtRegAliveInBlock(VRInfo, MBB);
|
MarkVirtRegAliveInBlock(VRInfo, MBB);
|
||||||
break; // Found the PHI entry for this block.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,6 +353,7 @@ bool LiveVariables::runOnMachineFunction(MachineFunction &MF) {
|
|||||||
assert(Visited.count(&*i) != 0 && "unreachable basic block found");
|
assert(Visited.count(&*i) != 0 && "unreachable basic block found");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
PHIVarInfo.clear();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -450,4 +442,17 @@ void LiveVariables::removeVirtualRegistersDead(MachineInstr *MI) {
|
|||||||
RegistersDead.erase(I);
|
RegistersDead.erase(I);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// analyzePHINodes - Gather information about the PHI nodes in here. In
|
||||||
|
/// particular, we want to map the variable information of a virtual
|
||||||
|
/// register which is used in a PHI node. We map that to the BB the vreg is
|
||||||
|
/// coming from.
|
||||||
|
///
|
||||||
|
void LiveVariables::analyzePHINodes(const MachineFunction& Fn) {
|
||||||
|
for (MachineFunction::const_iterator I = Fn.begin(), E = Fn.end();
|
||||||
|
I != E; ++I)
|
||||||
|
for (MachineBasicBlock::const_iterator BBI = I->begin(), BBE = I->end();
|
||||||
|
BBI != BBE && BBI->getOpcode() == TargetInstrInfo::PHI; ++BBI)
|
||||||
|
for (unsigned i = 1, e = BBI->getNumOperands(); i != e; i += 2)
|
||||||
|
PHIVarInfo[BBI->getOperand(i + 1).getMachineBasicBlock()].
|
||||||
|
push_back(BBI->getOperand(i).getReg());
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user