diff options
| author | Devang Patel <dpatel@apple.com> | 2007-08-24 06:17:19 +0000 | 
|---|---|---|
| committer | Devang Patel <dpatel@apple.com> | 2007-08-24 06:17:19 +0000 | 
| commit | 4bc9298f2a6ad6fbf6823cb706cdcd8cb41cdd21 (patch) | |
| tree | 3e02e3a6c1b3c10ba16120c89265e080a10e6d86 | |
| parent | 4be56a5d12730de3d88ed707dff57a11f64cbe7d (diff) | |
| download | bcm5719-llvm-4bc9298f2a6ad6fbf6823cb706cdcd8cb41cdd21.tar.gz bcm5719-llvm-4bc9298f2a6ad6fbf6823cb706cdcd8cb41cdd21.zip | |
It is not safe to execute split condition's true branch first all the time. If split
condition predicate is GT or GE then execute false branch first.
llvm-svn: 41358
| -rw-r--r-- | llvm/lib/Transforms/Scalar/LoopIndexSplit.cpp | 40 | 
1 files changed, 35 insertions, 5 deletions
| diff --git a/llvm/lib/Transforms/Scalar/LoopIndexSplit.cpp b/llvm/lib/Transforms/Scalar/LoopIndexSplit.cpp index 93d6309c484..23ffc3a4d25 100644 --- a/llvm/lib/Transforms/Scalar/LoopIndexSplit.cpp +++ b/llvm/lib/Transforms/Scalar/LoopIndexSplit.cpp @@ -57,7 +57,8 @@ namespace {      class SplitInfo {      public: -      SplitInfo() : SplitValue(NULL), SplitCondition(NULL) {} +      SplitInfo() : SplitValue(NULL), SplitCondition(NULL),  +                    UseTrueBranchFirst(true) {}        // Induction variable's range is split at this value.        Value *SplitValue; @@ -65,10 +66,14 @@ namespace {        // This compare instruction compares IndVar against SplitValue.        ICmpInst *SplitCondition; +      // True if after loop index split, first loop will execute split condition's +      // true branch. +      bool UseTrueBranchFirst;        // Clear split info.        void clear() {          SplitValue = NULL;          SplitCondition = NULL; +        UseTrueBranchFirst = true;        }      }; @@ -199,6 +204,9 @@ bool LoopIndexSplit::runOnLoop(Loop *IncomingLoop, LPPassManager &LPM_Ref) {        ++SI;    } +  if (SplitData.empty()) +    return false; +    // Split most profitiable condition.    // FIXME : Implement cost analysis.    unsigned MostProfitableSDIndex = 0; @@ -341,6 +349,14 @@ void LoopIndexSplit::findSplitCondition() {      if (CI->getPredicate() == ICmpInst::ICMP_NE)        return; +    // If split condition predicate is GT or GE then first execute +    // false branch of split condition. +    if (CI->getPredicate() != ICmpInst::ICMP_ULT +        && CI->getPredicate() != ICmpInst::ICMP_SLT +        && CI->getPredicate() != ICmpInst::ICMP_ULE +        && CI->getPredicate() != ICmpInst::ICMP_SLE) +      SD.UseTrueBranchFirst = false; +      // If one operand is loop invariant and second operand is SCEVAddRecExpr      // based on induction variable then CI is a candidate split condition.      Value *V0 = CI->getOperand(0); @@ -878,16 +894,30 @@ bool LoopIndexSplit::splitLoop(SplitInfo &SD) {    //[*] Eliminate split condition's inactive branch from ALoop.    BasicBlock *A_SplitCondBlock = SD.SplitCondition->getParent();    BranchInst *A_BR = cast<BranchInst>(A_SplitCondBlock->getTerminator()); -  BasicBlock *A_InactiveBranch = A_BR->getSuccessor(1); -  BasicBlock *A_ActiveBranch = A_BR->getSuccessor(0); +  BasicBlock *A_InactiveBranch = NULL; +  BasicBlock *A_ActiveBranch = NULL; +  if (SD.UseTrueBranchFirst) { +    A_ActiveBranch = A_BR->getSuccessor(0); +    A_InactiveBranch = A_BR->getSuccessor(1); +  } else { +    A_ActiveBranch = A_BR->getSuccessor(1); +    A_InactiveBranch = A_BR->getSuccessor(0); +  }    A_BR->setUnconditionalDest(A_BR->getSuccessor(0));    removeBlocks(A_InactiveBranch, L, A_ActiveBranch);    //[*] Eliminate split condition's inactive branch in from BLoop.    BasicBlock *B_SplitCondBlock = cast<BasicBlock>(ValueMap[A_SplitCondBlock]);    BranchInst *B_BR = cast<BranchInst>(B_SplitCondBlock->getTerminator()); -  BasicBlock *B_InactiveBranch = B_BR->getSuccessor(0); -  BasicBlock *B_ActiveBranch = B_BR->getSuccessor(1); +  BasicBlock *B_InactiveBranch = NULL; +  BasicBlock *B_ActiveBranch = NULL; +  if (SD.UseTrueBranchFirst) { +    B_ActiveBranch = B_BR->getSuccessor(1); +    B_InactiveBranch = B_BR->getSuccessor(0); +  } else { +    B_ActiveBranch = B_BR->getSuccessor(0); +    B_InactiveBranch = B_BR->getSuccessor(1); +  }    B_BR->setUnconditionalDest(B_BR->getSuccessor(1));    removeBlocks(B_InactiveBranch, BLoop, B_ActiveBranch); | 

