diff options
| author | Owen Anderson <resistor@mac.com> | 2010-08-27 17:12:29 +0000 | 
|---|---|---|
| committer | Owen Anderson <resistor@mac.com> | 2010-08-27 17:12:29 +0000 | 
| commit | 6ebbd9238036369a11b709332ddec9a4771f5be2 (patch) | |
| tree | 7ac4ade2ed055bf7bcad4f338f716fe5e21c8164 /llvm/lib/Transforms/Scalar/JumpThreading.cpp | |
| parent | 8b4c3207785390f4a3b0478bbb65c218d49c81ae (diff) | |
| download | llvm-6ebbd9238036369a11b709332ddec9a4771f5be2.zip llvm-6ebbd9238036369a11b709332ddec9a4771f5be2.tar.gz llvm-6ebbd9238036369a11b709332ddec9a4771f5be2.tar.bz2  | |
Use LVI to eliminate conditional branches where we've tested a related condition previously.  Update tests for this change.
This fixes PR5652.
llvm-svn: 112270
Diffstat (limited to 'llvm/lib/Transforms/Scalar/JumpThreading.cpp')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/JumpThreading.cpp | 39 | 
1 files changed, 39 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp index 8abd842..3d4db28 100644 --- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp +++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp @@ -669,6 +669,45 @@ bool JumpThreading::ProcessBlock(BasicBlock *BB) {            }        }      } +     +    // For a comparison where the LHS is outside this block, it's possible +    // that we've branch on it before.  Used LVI to see if we can simplify +    // the branch based on that. +    BranchInst *CondBr = dyn_cast<BranchInst>(BB->getTerminator()); +    Constant *CondConst = dyn_cast<Constant>(CondCmp->getOperand(1)); +    if (LVI && CondBr && CondConst && CondBr->isConditional() && +        (!isa<Instruction>(CondCmp->getOperand(0)) || +         cast<Instruction>(CondCmp->getOperand(0))->getParent() != BB)) { +      // For predecessor edge, determine if the comparison is true or false +      // on that edge.  If they're all true or all false, we can simplify the +      // branch. +      // FIXME: We could handle mixed true/false by duplicating code. +      unsigned Trues = 0, Falses = 0, predcount = 0; +      for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB);PI != PE; ++PI){ +        ++predcount; +        LazyValueInfo::Tristate Ret = +          LVI->getPredicateOnEdge(CondCmp->getPredicate(),  +                                  CondCmp->getOperand(0), CondConst, *PI, BB); +        if (Ret == LazyValueInfo::True) +          ++Trues; +        else if (Ret == LazyValueInfo::False) +          ++Falses; +      } +       +      // If we can determine the branch direction statically, converted +      // the conditional branch to an unconditional one. +      if (Trues && Trues == predcount) { +        RemovePredecessorAndSimplify(CondBr->getSuccessor(1), BB, TD); +        BranchInst::Create(CondBr->getSuccessor(0), CondBr); +        CondBr->eraseFromParent(); +        return true; +      } else if (Falses && Falses == predcount) { +        RemovePredecessorAndSimplify(CondBr->getSuccessor(0), BB, TD); +        BranchInst::Create(CondBr->getSuccessor(1), CondBr); +        CondBr->eraseFromParent(); +        return true; +      } +    }    }    // Check for some cases that are worth simplifying.  Right now we want to look  | 
