aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-09-28 06:17:10 +0000
committerChris Lattner <sabre@nondot.org>2006-09-28 06:17:10 +0000
commit57f9a43c64e8c5c8b2566fb6649754c11b59b98a (patch)
tree0a6b75f1e7cc114ea807580fa56c9d3c75bfae27
parentf308ea01d5e805ec07f479a79c753fa04541ec96 (diff)
refactor critical edge breaking out into the SplitCritEdgesForPHIConstants method.
This is a baby step towards fixing PR925. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30643 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/CodeGen/SelectionDAGISel.h1
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp29
2 files changed, 21 insertions, 9 deletions
diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h
index f439f21d6f..504319def6 100644
--- a/include/llvm/CodeGen/SelectionDAGISel.h
+++ b/include/llvm/CodeGen/SelectionDAGISel.h
@@ -124,6 +124,7 @@ protected:
SelectionDAG &DAG);
private:
+ void SplitCritEdgesForPHIConstants(BasicBlock *BB);
SDOperand CopyValueToVirtualRegister(SelectionDAGLowering &SDL,
Value *V, unsigned Reg);
void SelectBasicBlock(BasicBlock *BB, MachineFunction &MF,
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index e9fd888ead..d6dcf482ab 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -845,8 +845,6 @@ void SelectionDAGLowering::visitSwitchCase(SelectionDAGISel::CaseBlock &CB) {
CurMBB->addSuccessor(CB.RHSBB);
}
-/// visitSwitchCase - Emits the necessary code to represent a single node in
-/// the binary search tree resulting from lowering a switch instruction.
void SelectionDAGLowering::visitJumpTable(SelectionDAGISel::JumpTable &JT) {
// FIXME: Need to emit different code for PIC vs. Non-PIC, specifically,
// we need to add the address of the jump table to the value loaded, since
@@ -3207,6 +3205,21 @@ static bool OptimizeGEPExpression(GetElementPtrInst *GEPI,
return true;
}
+/// SplitCritEdgesForPHIConstants - If this block has any PHI nodes with
+/// constant operands, and if any of the edges feeding the PHI node are
+/// critical, split them so that the assignments of a constant to a register
+/// will not be executed on a path that isn't relevant.
+void SelectionDAGISel::SplitCritEdgesForPHIConstants(BasicBlock *BB) {
+ PHINode *PN;
+ BasicBlock::iterator BBI = BB->begin();
+ while ((PN = dyn_cast<PHINode>(BBI++))) {
+ for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
+ if (isa<Constant>(PN->getIncomingValue(i)))
+ SplitCriticalEdge(PN->getIncomingBlock(i), BB);
+ }
+}
+
+
bool SelectionDAGISel::runOnFunction(Function &Fn) {
MachineFunction &MF = MachineFunction::construct(&Fn, TLI.getTargetMachine());
RegMap = MF.getSSARegMap();
@@ -3225,14 +3238,12 @@ bool SelectionDAGISel::runOnFunction(Function &Fn) {
while (MadeChange) {
MadeChange = false;
for (Function::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) {
- PHINode *PN;
- BasicBlock::iterator BBI;
- for (BBI = BB->begin(); (PN = dyn_cast<PHINode>(BBI)); ++BBI)
- for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
- if (isa<Constant>(PN->getIncomingValue(i)))
- SplitCriticalEdge(PN->getIncomingBlock(i), BB);
+ // If this block has any PHI nodes with constant operands, and if any of the
+ // edges feeding the PHI node are critical, split them.
+ if (isa<PHINode>(BB->begin()))
+ SplitCritEdgesForPHIConstants(BB);
- for (BasicBlock::iterator E = BB->end(); BBI != E; ) {
+ for (BasicBlock::iterator BBI = BB->begin(), E = BB->end(); BBI != E; ) {
Instruction *I = BBI++;
if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(I)) {
MadeChange |= OptimizeGEPExpression(GEPI, TLI.getTargetData());