diff options
author | Owen Anderson <resistor@mac.com> | 2007-12-11 20:12:11 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2007-12-11 20:12:11 +0000 |
commit | d525f664c92bc285c80484015f7aaa8fc17c4cb3 (patch) | |
tree | bc4b45b1423b7369f9f15598f69870500c92a037 /lib/CodeGen/StrongPHIElimination.cpp | |
parent | 12ebf14048f4a6489033f8468ba36424442140ac (diff) |
More progress on StrongPHIElimination. Now we actually USE the DomForest!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44877 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/StrongPHIElimination.cpp')
-rw-r--r-- | lib/CodeGen/StrongPHIElimination.cpp | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/lib/CodeGen/StrongPHIElimination.cpp b/lib/CodeGen/StrongPHIElimination.cpp index fa7c10cf60..4762cf37f6 100644 --- a/lib/CodeGen/StrongPHIElimination.cpp +++ b/lib/CodeGen/StrongPHIElimination.cpp @@ -97,6 +97,9 @@ namespace { void processBlock(MachineBasicBlock* MBB); std::vector<DomForestNode*> computeDomForest(std::set<unsigned>& instrs); + void processPHIUnion(MachineInstr* Inst, + std::set<unsigned>& PHIUnion, + std::vector<StrongPHIElimination::DomForestNode*>& DF); void breakCriticalEdges(MachineFunction &Fn); }; @@ -303,6 +306,92 @@ void StrongPHIElimination::processBlock(MachineBasicBlock* MBB) { } } +void StrongPHIElimination::processPHIUnion(MachineInstr* Inst, + std::set<unsigned>& PHIUnion, + std::vector<StrongPHIElimination::DomForestNode*>& DF) { + + std::vector<DomForestNode*> worklist(DF.begin(), DF.end()); + SmallPtrSet<DomForestNode*, 4> visited; + + LiveVariables& LV = getAnalysis<LiveVariables>(); + unsigned DestReg = Inst->getOperand(0).getReg(); + + while (!worklist.empty()) { + DomForestNode* DFNode = worklist.back(); + + LiveVariables::VarInfo& Info = LV.getVarInfo(DFNode->getReg()); + visited.insert(DFNode); + + bool inserted = false; + SmallPtrSet<DomForestNode*, 4> interferences; + for (DomForestNode::iterator CI = DFNode->begin(), CE = DFNode->end(); + CI != CE; ++CI) { + DomForestNode* child = *CI; + LiveVariables::VarInfo& CInfo = LV.getVarInfo(child->getReg()); + + if (isLiveOut(Info, CInfo.DefInst->getParent())) { + interferences.insert(child); + } else if (isLiveIn(Info, CInfo.DefInst->getParent()) || + Info.DefInst->getParent() == CInfo.DefInst->getParent()) { + // FIXME: Add (p, c) to possible local interferences + } + + if (!visited.count(child)) { + worklist.push_back(child); + inserted = true; + } + } + + if (interferences.size() == 1) { + DomForestNode* child = *interferences.begin(); + + unsigned numParentCopies = 0; + unsigned numChildCopies = 0; + for (int i = Inst->getNumOperands() - 1; i >= 2; i-=2) { + unsigned SrcReg = Inst->getOperand(i-1).getReg(); + if (SrcReg == DFNode->getReg()) numParentCopies++; + else if (SrcReg == child->getReg()) numChildCopies++; + } + + if (numParentCopies < numChildCopies) { + // Insert copies for child + for (int i = Inst->getNumOperands() - 1; i >= 2; i-=2) { + if (Inst->getOperand(i-1).getReg() == child->getReg()) { + unsigned SrcReg = Inst->getOperand(i-1).getReg(); + MachineBasicBlock* From = Inst->getOperand(i).getMBB(); + + Waiting[From].push_back(std::make_pair(SrcReg, DestReg)); + } + } + + // FIXME: Make child's children parent's children + } else { + // Insert copies for parent + for (int i = Inst->getNumOperands() - 1; i >= 2; i-=2) { + if (Inst->getOperand(i-1).getReg() == DFNode->getReg()) { + unsigned SrcReg = Inst->getOperand(i-1).getReg(); + MachineBasicBlock* From = Inst->getOperand(i).getMBB(); + + Waiting[From].push_back(std::make_pair(SrcReg, DestReg)); + } + } + } + } else if (interferences.size() > 1) { + // Insert copies for parent + for (int i = Inst->getNumOperands() - 1; i >= 2; i-=2) { + if (Inst->getOperand(i-1).getReg() == DFNode->getReg()) { + unsigned SrcReg = Inst->getOperand(i-1).getReg(); + MachineBasicBlock* From = Inst->getOperand(i).getMBB(); + + Waiting[From].push_back(std::make_pair(SrcReg, DestReg)); + } + } + } + + if (!inserted) worklist.pop_back(); + } +} + /// breakCriticalEdges - Break critical edges coming into blocks with PHI /// nodes, preserving dominator and livevariable info. void StrongPHIElimination::breakCriticalEdges(MachineFunction &Fn) { |