diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Analysis/AssumptionTracker.cpp | 113 | ||||
-rw-r--r-- | llvm/lib/Analysis/CMakeLists.txt | 1 | ||||
-rw-r--r-- | llvm/lib/Transforms/IPO/InlineAlways.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Transforms/IPO/InlineSimple.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Transforms/IPO/Inliner.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombine.h | 13 | ||||
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstructionCombining.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/Transforms/Scalar/LoopUnswitch.cpp | 9 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/InlineFunction.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/LoopUnroll.cpp | 8 |
12 files changed, 173 insertions, 7 deletions
diff --git a/llvm/lib/Analysis/AssumptionTracker.cpp b/llvm/lib/Analysis/AssumptionTracker.cpp new file mode 100644 index 00000000000..3441030e49e --- /dev/null +++ b/llvm/lib/Analysis/AssumptionTracker.cpp @@ -0,0 +1,113 @@ +//===- AssumptionTracker.cpp - Track @llvm.assume -------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains a pass that keeps track of @llvm.assume intrinsics in +// the functions of a module. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Analysis/AssumptionTracker.h" +#include "llvm/IR/CallSite.h" +#include "llvm/IR/Dominators.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/PatternMatch.h" +#include "llvm/Support/Debug.h" +using namespace llvm; +using namespace llvm::PatternMatch; + +void AssumptionTracker::FunctionCallbackVH::deleted() { + AT->forgetCachedAssumptions(cast<Function>(getValPtr())); + // 'this' now dangles! +} + +void AssumptionTracker::forgetCachedAssumptions(Function *F) { + CachedAssumeCalls.erase(F); +} + +void AssumptionTracker::CallCallbackVH::deleted() { + assert(F && "delete callback called on dummy handle"); + FunctionCallsMap::iterator I = AT->CachedAssumeCalls.find(F); + assert(I != AT->CachedAssumeCalls.end() && + "Function cleared from the map without removing the values?"); + + I->second->erase(*this); + // 'this' now dangles! +} + +AssumptionTracker::FunctionCallsMap::iterator +AssumptionTracker::scanFunction(Function *F) { + auto IP = + CachedAssumeCalls.insert(std::make_pair(FunctionCallbackVH(F, this), + std::unique_ptr<CallHandleSet>( + new CallHandleSet()))); + assert(IP.second && "Scanning function already in the map?"); + + FunctionCallsMap::iterator I = IP.first; + + // Go through all instructions in all blocks, add all calls to @llvm.assume + // to our cache. + for (BasicBlock &B : *F) + for (Instruction &II : B) + if (match(cast<Value>(&II), m_Intrinsic<Intrinsic::assume>(m_Value()))) + I->second->insert(CallCallbackVH(&II, this)); + + return I; +} + +void AssumptionTracker::verifyAnalysis() const { +#ifndef NDEBUG + for (const auto &I : CachedAssumeCalls) { + for (const BasicBlock &B : cast<Function>(*I.first)) + for (const Instruction &II : B) { + Instruction *C = const_cast<Instruction*>(&II); + if (match(C, m_Intrinsic<Intrinsic::assume>(m_Value()))) { + assert(I.second->count(CallCallbackVH(C, + const_cast<AssumptionTracker*>(this))) && + "Assumption in scanned function not in cache"); + } + } + } +#endif +} + +void AssumptionTracker::registerAssumption(CallInst *CI) { + assert(match(cast<Value>(CI), + m_Intrinsic<Intrinsic::assume>(m_Value())) && + "Registered call does not call @llvm.assume"); + assert(CI->getParent() && + "Cannot register @llvm.assume call not in a basic block"); + + Function *F = CI->getParent()->getParent(); + assert(F && "Cannot register @llvm.assume call not in a function"); + + FunctionCallsMap::iterator I = CachedAssumeCalls.find(F); + if (I == CachedAssumeCalls.end()) { + // If this function has not already been scanned, then don't do anything + // here. This intrinsic will be found, if it still exists, if the list of + // assumptions in this function is requested at some later point. This + // maintains the following invariant: if a function is present in the + // cache, then its list of assumption intrinsic calls is complete. + return; + } + + I->second->insert(CallCallbackVH(CI, this)); +} + +AssumptionTracker::AssumptionTracker() : ImmutablePass(ID) { + initializeAssumptionTrackerPass(*PassRegistry::getPassRegistry()); +} + +AssumptionTracker::~AssumptionTracker() {} + +INITIALIZE_PASS(AssumptionTracker, "assumption-tracker", "Assumption Tracker", + false, true) +char AssumptionTracker::ID = 0; + diff --git a/llvm/lib/Analysis/CMakeLists.txt b/llvm/lib/Analysis/CMakeLists.txt index 792fadd119b..6dbd486ba7b 100644 --- a/llvm/lib/Analysis/CMakeLists.txt +++ b/llvm/lib/Analysis/CMakeLists.txt @@ -5,6 +5,7 @@ add_llvm_library(LLVMAnalysis AliasDebugger.cpp AliasSetTracker.cpp Analysis.cpp + AssumptionTracker.cpp BasicAliasAnalysis.cpp BlockFrequencyInfo.cpp BlockFrequencyInfoImpl.cpp diff --git a/llvm/lib/Transforms/IPO/InlineAlways.cpp b/llvm/lib/Transforms/IPO/InlineAlways.cpp index 18c2540910f..819b2e08e0a 100644 --- a/llvm/lib/Transforms/IPO/InlineAlways.cpp +++ b/llvm/lib/Transforms/IPO/InlineAlways.cpp @@ -15,6 +15,7 @@ #include "llvm/Transforms/IPO.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/AssumptionTracker.h" #include "llvm/Analysis/CallGraph.h" #include "llvm/Analysis/InlineCost.h" #include "llvm/IR/CallSite.h" @@ -67,6 +68,7 @@ char AlwaysInliner::ID = 0; INITIALIZE_PASS_BEGIN(AlwaysInliner, "always-inline", "Inliner for always_inline functions", false, false) INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(AssumptionTracker) INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass) INITIALIZE_PASS_DEPENDENCY(InlineCostAnalysis) INITIALIZE_PASS_END(AlwaysInliner, "always-inline", diff --git a/llvm/lib/Transforms/IPO/InlineSimple.cpp b/llvm/lib/Transforms/IPO/InlineSimple.cpp index b9b4895eaa8..d9a2b9e6b67 100644 --- a/llvm/lib/Transforms/IPO/InlineSimple.cpp +++ b/llvm/lib/Transforms/IPO/InlineSimple.cpp @@ -13,6 +13,7 @@ #include "llvm/Transforms/IPO.h" #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/AssumptionTracker.h" #include "llvm/Analysis/CallGraph.h" #include "llvm/Analysis/InlineCost.h" #include "llvm/IR/CallSite.h" @@ -75,6 +76,7 @@ char SimpleInliner::ID = 0; INITIALIZE_PASS_BEGIN(SimpleInliner, "inline", "Function Integration/Inlining", false, false) INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(AssumptionTracker) INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass) INITIALIZE_PASS_DEPENDENCY(InlineCostAnalysis) INITIALIZE_PASS_END(SimpleInliner, "inline", diff --git a/llvm/lib/Transforms/IPO/Inliner.cpp b/llvm/lib/Transforms/IPO/Inliner.cpp index 3cb6479a10c..de979504742 100644 --- a/llvm/lib/Transforms/IPO/Inliner.cpp +++ b/llvm/lib/Transforms/IPO/Inliner.cpp @@ -17,6 +17,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/AssumptionTracker.h" #include "llvm/Analysis/CallGraph.h" #include "llvm/Analysis/InlineCost.h" #include "llvm/IR/CallSite.h" @@ -76,6 +77,7 @@ Inliner::Inliner(char &ID, int Threshold, bool InsertLifetime) /// always explicitly call the implementation here. void Inliner::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired<AliasAnalysis>(); + AU.addRequired<AssumptionTracker>(); CallGraphSCCPass::getAnalysisUsage(AU); } @@ -441,6 +443,7 @@ static bool InlineHistoryIncludes(Function *F, int InlineHistoryID, bool Inliner::runOnSCC(CallGraphSCC &SCC) { CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph(); + AssumptionTracker *AT = &getAnalysis<AssumptionTracker>(); DataLayoutPass *DLP = getAnalysisIfAvailable<DataLayoutPass>(); const DataLayout *DL = DLP ? &DLP->getDataLayout() : nullptr; const TargetLibraryInfo *TLI = getAnalysisIfAvailable<TargetLibraryInfo>(); @@ -503,7 +506,7 @@ bool Inliner::runOnSCC(CallGraphSCC &SCC) { InlinedArrayAllocasTy InlinedArrayAllocas; - InlineFunctionInfo InlineInfo(&CG, DL, AA); + InlineFunctionInfo InlineInfo(&CG, DL, AA, AT); // Now that we have all of the call sites, loop over them and inline them if // it looks profitable to do so. diff --git a/llvm/lib/Transforms/InstCombine/InstCombine.h b/llvm/lib/Transforms/InstCombine/InstCombine.h index c8ed7c2b5a6..c56dc3c8684 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombine.h +++ b/llvm/lib/Transforms/InstCombine/InstCombine.h @@ -11,12 +11,14 @@ #define LLVM_LIB_TRANSFORMS_INSTCOMBINE_INSTCOMBINE_H #include "InstCombineWorklist.h" +#include "llvm/Analysis/AssumptionTracker.h" #include "llvm/Analysis/TargetFolder.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/InstVisitor.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Operator.h" +#include "llvm/IR/PatternMatch.h" #include "llvm/Pass.h" #include "llvm/Transforms/Utils/SimplifyLibCalls.h" @@ -71,14 +73,20 @@ static inline Constant *SubOne(Constant *C) { class LLVM_LIBRARY_VISIBILITY InstCombineIRInserter : public IRBuilderDefaultInserter<true> { InstCombineWorklist &Worklist; + AssumptionTracker *AT; public: - InstCombineIRInserter(InstCombineWorklist &WL) : Worklist(WL) {} + InstCombineIRInserter(InstCombineWorklist &WL, AssumptionTracker *AT) + : Worklist(WL), AT(AT) {} void InsertHelper(Instruction *I, const Twine &Name, BasicBlock *BB, BasicBlock::iterator InsertPt) const { IRBuilderDefaultInserter<true>::InsertHelper(I, Name, BB, InsertPt); Worklist.Add(I); + + using namespace llvm::PatternMatch; + if ((match(I, m_Intrinsic<Intrinsic::assume>(m_Value())))) + AT->registerAssumption(cast<CallInst>(I)); } }; @@ -86,6 +94,7 @@ public: class LLVM_LIBRARY_VISIBILITY InstCombiner : public FunctionPass, public InstVisitor<InstCombiner, Instruction *> { + AssumptionTracker *AT; const DataLayout *DL; TargetLibraryInfo *TLI; bool MadeIRChange; @@ -114,6 +123,8 @@ public: void getAnalysisUsage(AnalysisUsage &AU) const override; + AssumptionTracker *getAssumptionTracker() const { return AT; } + const DataLayout *getDataLayout() const { return DL; } TargetLibraryInfo *getTargetLibraryInfo() const { return TLI; } diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index 331df3a9648..92f38fc19c8 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -996,6 +996,8 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { } case Intrinsic::assume: { // Canonicalize assume(a && b) -> assume(a); assume(b); + // Note: New assumption intrinsics created here are registered by + // the InstCombineIRInserter object. Value *IIOperand = II->getArgOperand(0), *A, *B, *AssumeIntrinsic = II->getCalledValue(); if (match(IIOperand, m_And(m_Value(A), m_Value(B)))) { @@ -1005,8 +1007,10 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { } // assume(!(a || b)) -> assume(!a); assume(!b); if (match(IIOperand, m_Not(m_Or(m_Value(A), m_Value(B))))) { - Builder->CreateCall(AssumeIntrinsic, Builder->CreateNot(A), II->getName()); - Builder->CreateCall(AssumeIntrinsic, Builder->CreateNot(B), II->getName()); + Builder->CreateCall(AssumeIntrinsic, Builder->CreateNot(A), + II->getName()); + Builder->CreateCall(AssumeIntrinsic, Builder->CreateNot(B), + II->getName()); return EraseInstFromFunction(*II); } break; diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index a95f5784fa5..3ae9f0ddce8 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -39,6 +39,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/Analysis/AssumptionTracker.h" #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/MemoryBuiltins.h" @@ -85,12 +86,14 @@ void LLVMInitializeInstCombine(LLVMPassRegistryRef R) { char InstCombiner::ID = 0; INITIALIZE_PASS_BEGIN(InstCombiner, "instcombine", "Combine redundant instructions", false, false) +INITIALIZE_PASS_DEPENDENCY(AssumptionTracker) INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfo) INITIALIZE_PASS_END(InstCombiner, "instcombine", "Combine redundant instructions", false, false) void InstCombiner::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); + AU.addRequired<AssumptionTracker>(); AU.addRequired<TargetLibraryInfo>(); } @@ -2907,6 +2910,7 @@ bool InstCombiner::runOnFunction(Function &F) { if (skipOptnoneFunction(F)) return false; + AT = &getAnalysis<AssumptionTracker>(); DataLayoutPass *DLP = getAnalysisIfAvailable<DataLayoutPass>(); DL = DLP ? &DLP->getDataLayout() : nullptr; TLI = &getAnalysis<TargetLibraryInfo>(); @@ -2918,7 +2922,7 @@ bool InstCombiner::runOnFunction(Function &F) { /// instructions into the worklist when they are created. IRBuilder<true, TargetFolder, InstCombineIRInserter> TheBuilder(F.getContext(), TargetFolder(DL), - InstCombineIRInserter(Worklist)); + InstCombineIRInserter(Worklist, AT)); Builder = &TheBuilder; InstCombinerLibCallSimplifier TheSimplifier(DL, TLI, this); diff --git a/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp b/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp index 22dd65c7cf6..198a3b385ae 100644 --- a/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp +++ b/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Transforms/Scalar.h" +#include "llvm/Analysis/AssumptionTracker.h" #include "llvm/Analysis/CodeMetrics.h" #include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/ScalarEvolution.h" @@ -102,6 +103,7 @@ namespace { /// loop preheaders be inserted into the CFG... /// void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequired<AssumptionTracker>(); AU.addRequired<LoopInfo>(); AU.addPreserved<LoopInfo>(); AU.addRequiredID(LoopSimplifyID); @@ -182,6 +184,7 @@ namespace { char LoopUnroll::ID = 0; INITIALIZE_PASS_BEGIN(LoopUnroll, "loop-unroll", "Unroll loops", false, false) INITIALIZE_AG_DEPENDENCY(TargetTransformInfo) +INITIALIZE_PASS_DEPENDENCY(AssumptionTracker) INITIALIZE_PASS_DEPENDENCY(LoopInfo) INITIALIZE_PASS_DEPENDENCY(LoopSimplify) INITIALIZE_PASS_DEPENDENCY(LCSSA) @@ -351,6 +354,7 @@ bool LoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) { LoopInfo *LI = &getAnalysis<LoopInfo>(); ScalarEvolution *SE = &getAnalysis<ScalarEvolution>(); const TargetTransformInfo &TTI = getAnalysis<TargetTransformInfo>(); + AssumptionTracker *AT = &getAnalysis<AssumptionTracker>(); BasicBlock *Header = L->getHeader(); DEBUG(dbgs() << "Loop Unroll: F[" << Header->getParent()->getName() @@ -493,7 +497,8 @@ bool LoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) { } // Unroll the loop. - if (!UnrollLoop(L, Count, TripCount, AllowRuntime, TripMultiple, LI, this, &LPM)) + if (!UnrollLoop(L, Count, TripCount, AllowRuntime, TripMultiple, LI, this, + &LPM, AT)) return false; return true; diff --git a/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp b/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp index 977c53a3bc6..d3140f9a76d 100644 --- a/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp +++ b/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp @@ -30,6 +30,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" +#include "llvm/Analysis/AssumptionTracker.h" #include "llvm/Analysis/CodeMetrics.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/LoopInfo.h" @@ -126,6 +127,7 @@ namespace { class LoopUnswitch : public LoopPass { LoopInfo *LI; // Loop information LPPassManager *LPM; + AssumptionTracker *AT; // LoopProcessWorklist - Used to check if second loop needs processing // after RewriteLoopBodyWithConditionConstant rewrites first loop. @@ -164,6 +166,7 @@ namespace { /// loop preheaders be inserted into the CFG. /// void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequired<AssumptionTracker>(); AU.addRequiredID(LoopSimplifyID); AU.addPreservedID(LoopSimplifyID); AU.addRequired<LoopInfo>(); @@ -326,6 +329,7 @@ char LoopUnswitch::ID = 0; INITIALIZE_PASS_BEGIN(LoopUnswitch, "loop-unswitch", "Unswitch loops", false, false) INITIALIZE_AG_DEPENDENCY(TargetTransformInfo) +INITIALIZE_PASS_DEPENDENCY(AssumptionTracker) INITIALIZE_PASS_DEPENDENCY(LoopSimplify) INITIALIZE_PASS_DEPENDENCY(LoopInfo) INITIALIZE_PASS_DEPENDENCY(LCSSA) @@ -376,6 +380,7 @@ bool LoopUnswitch::runOnLoop(Loop *L, LPPassManager &LPM_Ref) { if (skipOptnoneFunction(L)) return false; + AT = &getAnalysis<AssumptionTracker>(); LI = &getAnalysis<LoopInfo>(); LPM = &LPM_Ref; DominatorTreeWrapperPass *DTWP = @@ -823,6 +828,10 @@ void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val, F->getBasicBlockList().splice(NewPreheader, F->getBasicBlockList(), NewBlocks[0], F->end()); + // FIXME: We could register any cloned assumptions instead of clearing the + // whole function's cache. + AT->forgetCachedAssumptions(F); + // Now we create the new Loop object for the versioned loop. Loop *NewLoop = CloneLoop(L, L->getParentLoop(), VMap, LI, LPM); diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp index 935d6b813e6..8aaeacf10c2 100644 --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -18,6 +18,7 @@ #include "llvm/ADT/SetVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/AssumptionTracker.h" #include "llvm/Analysis/CallGraph.h" #include "llvm/Analysis/CaptureTracking.h" #include "llvm/Analysis/InstructionSimplify.h" @@ -982,6 +983,11 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, // Add noalias metadata if necessary. AddAliasScopeMetadata(CS, VMap, IFI.DL, IFI.AA); + + // FIXME: We could register any cloned assumptions instead of clearing the + // whole function's cache. + if (IFI.AT) + IFI.AT->forgetCachedAssumptions(Caller); } // If there are any alloca instructions in the block that used to be the entry diff --git a/llvm/lib/Transforms/Utils/LoopUnroll.cpp b/llvm/lib/Transforms/Utils/LoopUnroll.cpp index ab1c25a75e2..576298892f4 100644 --- a/llvm/lib/Transforms/Utils/LoopUnroll.cpp +++ b/llvm/lib/Transforms/Utils/LoopUnroll.cpp @@ -19,6 +19,7 @@ #include "llvm/Transforms/Utils/UnrollLoop.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" +#include "llvm/Analysis/AssumptionTracker.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/LoopIterator.h" #include "llvm/Analysis/LoopPass.h" @@ -154,7 +155,8 @@ FoldBlockIntoPredecessor(BasicBlock *BB, LoopInfo* LI, LPPassManager *LPM, /// available from the Pass it must also preserve those analyses. bool llvm::UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool AllowRuntime, unsigned TripMultiple, - LoopInfo *LI, Pass *PP, LPPassManager *LPM) { + LoopInfo *LI, Pass *PP, LPPassManager *LPM, + AssumptionTracker *AT) { BasicBlock *Preheader = L->getLoopPreheader(); if (!Preheader) { DEBUG(dbgs() << " Can't unroll; loop preheader-insertion failed.\n"); @@ -442,6 +444,10 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, } } + // FIXME: We could register any cloned assumptions instead of clearing the + // whole function's cache. + AT->forgetCachedAssumptions(F); + DominatorTree *DT = nullptr; if (PP) { // FIXME: Reconstruct dom info, because it is not preserved properly. |