diff options
author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2017-04-24 18:25:07 +0000 |
---|---|---|
committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2017-04-24 18:25:07 +0000 |
commit | 58ccc0949a8c766fa729c04149cbffbc32096f59 (patch) | |
tree | 8e4a7b1c7e1f6dd4817cd2854c520ef2cb7a362f /llvm/lib/Transforms | |
parent | 0889225f51791cb4e8219a9dd96c3144122348ec (diff) | |
download | llvm-58ccc0949a8c766fa729c04149cbffbc32096f59.zip llvm-58ccc0949a8c766fa729c04149cbffbc32096f59.tar.gz llvm-58ccc0949a8c766fa729c04149cbffbc32096f59.tar.bz2 |
Revert "Compute safety information in a much finer granularity."
Use-after-free in llvm::isGuaranteedToExecute.
llvm-svn: 301214
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/Scalar/LICM.cpp | 32 | ||||
-rw-r--r-- | llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/LoopUtils.cpp | 24 |
3 files changed, 38 insertions, 20 deletions
diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp index 2b84150..340c81f 100644 --- a/llvm/lib/Transforms/Scalar/LICM.cpp +++ b/llvm/lib/Transforms/Scalar/LICM.cpp @@ -478,17 +478,27 @@ bool llvm::hoistRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI, /// void llvm::computeLoopSafetyInfo(LoopSafetyInfo *SafetyInfo, Loop *CurLoop) { assert(CurLoop != nullptr && "CurLoop cant be null"); - // Iterate over loop instructions and compute early exit points. - for (Loop::block_iterator BB = CurLoop->block_begin(), + BasicBlock *Header = CurLoop->getHeader(); + // Setting default safety values. + SafetyInfo->MayThrow = false; + SafetyInfo->HeaderMayThrow = false; + // Iterate over header and compute safety info. + for (BasicBlock::iterator I = Header->begin(), E = Header->end(); + (I != E) && !SafetyInfo->HeaderMayThrow; ++I) + SafetyInfo->HeaderMayThrow |= + !isGuaranteedToTransferExecutionToSuccessor(&*I); + + SafetyInfo->MayThrow = SafetyInfo->HeaderMayThrow; + // Iterate over loop instructions and compute safety info. + // Skip header as it has been computed and stored in HeaderMayThrow. + // The first block in loopinfo.Blocks is guaranteed to be the header. + assert(Header == *CurLoop->getBlocks().begin() && "First block must be header"); + for (Loop::block_iterator BB = std::next(CurLoop->block_begin()), BBE = CurLoop->block_end(); - BB != BBE; ++BB) { - for (BasicBlock::iterator I = (*BB)->begin(), E = (*BB)->end(); I != E; - ++I) { - if (isGuaranteedToTransferExecutionToSuccessor(&*I)) - continue; - SafetyInfo->EarlyExits.push_back(&*I); - } - } + (BB != BBE) && !SafetyInfo->MayThrow; ++BB) + for (BasicBlock::iterator I = (*BB)->begin(), E = (*BB)->end(); + (I != E) && !SafetyInfo->MayThrow; ++I) + SafetyInfo->MayThrow |= !isGuaranteedToTransferExecutionToSuccessor(&*I); // Compute funclet colors if we might sink/hoist in a function with a funclet // personality routine. @@ -1084,7 +1094,7 @@ bool llvm::promoteLoopAccessesToScalars( // Do we know this object does not escape ? bool IsKnownNonEscapingObject = false; - if (!SafetyInfo->EarlyExits.empty()) { + if (SafetyInfo->MayThrow) { // If a loop can throw, we have to insert a store along each unwind edge. // That said, we can't actually make the unwind edge explicit. Therefore, // we have to prove that the store is dead along the unwind edge. diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp index a6c1669..946d85d 100644 --- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp +++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp @@ -272,7 +272,7 @@ bool LoopIdiomRecognize::runOnCountableLoop() { // Give up if the loop has instructions may throw. LoopSafetyInfo SafetyInfo; computeLoopSafetyInfo(&SafetyInfo, CurLoop); - if (!SafetyInfo.EarlyExits.empty()) + if (SafetyInfo.MayThrow) return MadeChange; // Scan all the blocks in the loop that are not in subloops. diff --git a/llvm/lib/Transforms/Utils/LoopUtils.cpp b/llvm/lib/Transforms/Utils/LoopUtils.cpp index 062432f..175d013a 100644 --- a/llvm/lib/Transforms/Utils/LoopUtils.cpp +++ b/llvm/lib/Transforms/Utils/LoopUtils.cpp @@ -1044,11 +1044,21 @@ bool llvm::isGuaranteedToExecute(const Instruction &Inst, const DominatorTree *DT, const Loop *CurLoop, const LoopSafetyInfo *SafetyInfo) { // We have to check to make sure that the instruction dominates all - // of the exit points. If it doesn't, then there is a path out of the loop - // which does not execute this instruction and its not guaranteed to execute. - for (Instruction *ExitInst : SafetyInfo->EarlyExits) - if (!DT->dominates(&Inst, ExitInst)) - return false; + // of the exit blocks. If it doesn't, then there is a path out of the loop + // which does not execute this instruction, so we can't hoist it. + + // If the instruction is in the header block for the loop (which is very + // common), it is always guaranteed to dominate the exit blocks. Since this + // is a common case, and can save some work, check it now. + if (Inst.getParent() == CurLoop->getHeader()) + // If there's a throw in the header block, we can't guarantee we'll reach + // Inst. + return !SafetyInfo->HeaderMayThrow; + + // Somewhere in this loop there is an instruction which may throw and make us + // exit the loop. + if (SafetyInfo->MayThrow) + return false; // Get the exit blocks for the current loop. SmallVector<BasicBlock *, 8> ExitBlocks; @@ -1061,9 +1071,7 @@ bool llvm::isGuaranteedToExecute(const Instruction &Inst, // As a degenerate case, if the loop is statically infinite then we haven't // proven anything since there are no exit blocks. - // However, we also special case instruction from the header as the header - // is always guaranteed to execute. - if (ExitBlocks.empty() && Inst.getParent() != CurLoop->getHeader()) + if (ExitBlocks.empty()) return false; // FIXME: In general, we have to prove that the loop isn't an infinite loop. |