<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Sep 8, 2014 at 11:52 AM, Hal Finkel <span dir="ltr"><<a href="mailto:hfinkel@anl.gov" target="_blank">hfinkel@anl.gov</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">----- Original Message -----<br>
> From: "Alexey Samsonov" <<a href="mailto:vonosmas@gmail.com">vonosmas@gmail.com</a>><br>
> To: "Hal Finkel" <<a href="mailto:hfinkel@anl.gov">hfinkel@anl.gov</a>><br>
> Cc: "llvm-commits" <<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a>><br>
</span><div><div class="h5">> Sent: Monday, September 8, 2014 1:27:46 PM<br>
> Subject: Re: [llvm] r217334 - Add an Assumption-Tracking Pass<br>
><br>
><br>
><br>
><br>
> On Mon, Sep 8, 2014 at 11:07 AM, Hal Finkel < <a href="mailto:hfinkel@anl.gov">hfinkel@anl.gov</a> ><br>
> wrote:<br>
><br>
><br>
><br>
><br>
> ----- Original Message -----<br>
> > From: "Alexey Samsonov" < <a href="mailto:vonosmas@gmail.com">vonosmas@gmail.com</a> ><br>
> > To: "Hal Finkel" < <a href="mailto:hfinkel@anl.gov">hfinkel@anl.gov</a> ><br>
> > Cc: "llvm-commits" < <a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a> ><br>
> > Sent: Monday, September 8, 2014 12:57:52 PM<br>
> > Subject: Re: [llvm] r217334 - Add an Assumption-Tracking Pass<br>
> ><br>
> ><br>
> > Hi Hal,<br>
> ><br>
> ><br>
> > On Sun, Sep 7, 2014 at 5:44 AM, Hal Finkel < <a href="mailto:hfinkel@anl.gov">hfinkel@anl.gov</a> ><br>
> > wrote:<br>
> ><br>
> ><br>
> > Author: hfinkel<br>
> > Date: Sun Sep 7 07:44:26 2014<br>
> > New Revision: 217334<br>
> ><br>
> > URL: <a href="http://llvm.org/viewvc/llvm-project?rev=217334&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=217334&view=rev</a><br>
> > Log:<br>
> > Add an Assumption-Tracking Pass<br>
> ><br>
> > This adds an immutable pass, AssumptionTracker, which keeps a cache<br>
> > of<br>
> > @llvm.assume call instructions within a module. It uses callback<br>
> > value handles<br>
> > to keep stale functions and intrinsics out of the map, and it<br>
> > relies<br>
> > on any<br>
> > code that creates new @llvm.assume calls to notify it of the new<br>
> > instructions.<br>
> > The benefit is that code needing to find @llvm.assume intrinsics<br>
> > can<br>
> > do so<br>
> > directly, without scanning the function, thus allowing the cost of<br>
> > @llvm.assume<br>
> > handling to be negligible when none are present.<br>
> ><br>
> > The current design is intended to be lightweight. We don't keep<br>
> > track<br>
> > of<br>
> > anything until we need a list of assumptions in some function. The<br>
> > first time<br>
> > this happens, we scan the function. After that, we add/remove<br>
> > @llvm.assume<br>
> > calls from the cache in response to registration calls and<br>
> > ValueHandle<br>
> > callbacks.<br>
> ><br>
> > There are no new direct test cases for this pass, but because it<br>
> > calls it<br>
> > validation function upon module finalization, we'll pick up<br>
> > detectable<br>
> > inconsistencies from the other tests that touch @llvm.assume calls.<br>
> ><br>
> > This pass will be used by follow-up commits that make use of<br>
> > @llvm.assume.<br>
> ><br>
> > Added:<br>
> > llvm/trunk/include/llvm/Analysis/AssumptionTracker.h<br>
> > llvm/trunk/lib/Analysis/AssumptionTracker.cpp<br>
> > Modified:<br>
> > llvm/trunk/include/llvm/InitializePasses.h<br>
> > llvm/trunk/include/llvm/Transforms/Utils/Cloning.h<br>
> > llvm/trunk/include/llvm/Transforms/Utils/UnrollLoop.h<br>
> > llvm/trunk/lib/Analysis/CMakeLists.txt<br>
> > llvm/trunk/lib/Transforms/IPO/InlineAlways.cpp<br>
> > llvm/trunk/lib/Transforms/IPO/InlineSimple.cpp<br>
> > llvm/trunk/lib/Transforms/IPO/Inliner.cpp<br>
> > llvm/trunk/lib/Transforms/InstCombine/InstCombine.h<br>
> > llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp<br>
> > llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp<br>
> > llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp<br>
> > llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp<br>
> > llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp<br>
> > llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp<br>
> ><br>
> > Added: llvm/trunk/include/llvm/Analysis/AssumptionTracker.h<br>
> > URL:<br>
> > <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/AssumptionTracker.h?rev=217334&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/AssumptionTracker.h?rev=217334&view=auto</a><br>
> > ==============================================================================<br>
> > --- llvm/trunk/include/llvm/Analysis/AssumptionTracker.h (added)<br>
> > +++ llvm/trunk/include/llvm/Analysis/AssumptionTracker.h Sun Sep 7<br>
> > 07:44:26 2014<br>
> > @@ -0,0 +1,128 @@<br>
> > +//===- llvm/Analysis/AssumptionTracker.h - Track @llvm.assume<br>
> > ---*-<br>
> > C++ -*-===//<br>
> > +//<br>
> > +// The LLVM Compiler Infrastructure<br>
> > +//<br>
> > +// This file is distributed under the University of Illinois Open<br>
> > Source<br>
> > +// License. See LICENSE.TXT for details.<br>
> > +//<br>
> > +//===----------------------------------------------------------------------===//<br>
> > +//<br>
> > +// This file contains a pass that keeps track of @llvm.assume<br>
> > intrinsics in<br>
> > +// the functions of a module (allowing assumptions within any<br>
> > function to be<br>
> > +// found cheaply by other parts of the optimizer).<br>
> > +//<br>
> > +//===----------------------------------------------------------------------===//<br>
> > +<br>
> > +#ifndef LLVM_ANALYSIS_ASSUMPTIONTRACKER_H<br>
> > +#define LLVM_ANALYSIS_ASSUMPTIONTRACKER_H<br>
> > +<br>
> > +#include "llvm/ADT/DenseMap.h"<br>
> > +#include "llvm/ADT/DenseSet.h"<br>
> > +#include "llvm/ADT/SmallSet.h"<br>
> > +#include "llvm/IR/Function.h"<br>
> > +#include "llvm/IR/Instructions.h"<br>
> > +#include "llvm/IR/ValueHandle.h"<br>
> > +#include "llvm/Pass.h"<br>
> > +#include <memory><br>
> > +<br>
> > +namespace llvm {<br>
> > +<br>
> > +/// An immutable pass that tracks @llvm.assume intrinsics in a<br>
> > module.<br>
> > +class AssumptionTracker : public ImmutablePass {<br>
> > + /// A callback value handle applied to function objects, which we<br>
> > use to<br>
> > + /// delete our cache of intrinsics for a function when it is<br>
> > deleted.<br>
> > + class FunctionCallbackVH : public CallbackVH {<br>
> > + AssumptionTracker *AT;<br>
> > + void deleted() override;<br>
> > +<br>
> > + public:<br>
> > + typedef DenseMapInfo<Value *> DMI;<br>
> > +<br>
> > + FunctionCallbackVH(Value *V, AssumptionTracker *AT = nullptr)<br>
> > + : CallbackVH(V), AT(AT) {}<br>
> > + };<br>
> > +<br>
> > + /// A callback value handle applied to call instructions, which<br>
> > keeps<br>
> > + /// track of the call's parent function so that we can remove a<br>
> > + /// assumption intrinsic call from our cache when the instruction<br>
> > is<br>
> > + /// deleted.<br>
> > + class CallCallbackVH : public CallbackVH {<br>
> > + AssumptionTracker *AT;<br>
> > + void deleted() override;<br>
> > +<br>
> > + // We store the function here because we need it to lookup the<br>
> > set<br>
> > + // containing this handle when the underlying CallInst is being<br>
> > deleted.<br>
> > + Function *F;<br>
> > +<br>
> > + public:<br>
> > + typedef DenseMapInfo<Instruction *> DMI;<br>
> > +<br>
> > + CallCallbackVH(Instruction *I, AssumptionTracker *AT = nullptr)<br>
> > + : CallbackVH(I), AT(AT), F(nullptr) {<br>
> > + if (I != DMI::getEmptyKey() && I != DMI::getTombstoneKey())<br>
> > + F = I->getParent()->getParent();<br>
> > + }<br>
> > +<br>
> > + operator CallInst*() const {<br>
> > + Value *V = getValPtr();<br>
> > + if (V == DMI::getEmptyKey() || V == DMI::getTombstoneKey())<br>
> > + return static_cast<CallInst*>(V);<br>
> ><br>
> ><br>
> ><br>
> > ^^ UBSan bootstrap bot reports undefined behavior here:<br>
> ><br>
> > /home/dtoolsbot/build/sanitizer-x86_64-linux-bootstrap/build/llvm/include/llvm/Analysis/AssumptionTracker.h:69:18:<br>
> > runtime error: downcast of misaligned address 0xfffffffffffffffc<br>
> > for<br>
> > type 'llvm::CallInst', which requires 8 byte alignment<br>
> ><br>
> > (full log:<br>
> > <a href="http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-bootstrap/builds/4491/steps/check-llvm%20ubsan/logs/stdio" target="_blank">http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-bootstrap/builds/4491/steps/check-llvm%20ubsan/logs/stdio</a><br>
> > )<br>
> ><br>
> ><br>
> > The real problem is probably the fact that we don't enforce correct<br>
> > alignment on EmptyKey and TombstoneKey in DenseMap<T*, foo>, but<br>
> > it's not clear how to do this in the general case:<br>
> > correct alignment of "fake pointers" of type T* depends on the<br>
> > natural alignment of T, while the definition of T might not be<br>
> > available.<br>
> ><br>
> ><br>
> > Can you work around this problem somehow, and avoid bogus cast of<br>
> > fake pointer here?<br>
><br>
> Interesting. Would using a reinterpret_cast fix the problem?<br>
><br>
><br>
><br>
> reinterpret_cast<> will make the tool silent (at least, in its<br>
> current implementation). 5.2.10 [expr.reinterpret.cast], p. 7<br>
> makes me think that the result of this reinterpret_cast<> is<br>
> unspecified.<br>
<br>
</div></div>Sounds good. If you look in include/llvm/ADT/DenseMapInfo.h, you'll see that the original pointer values were formed via a reinterpret_cast, so I'd not be making anything depend more on unspecified if I make this a reinterpret_cast too.<br></blockquote><div><br></div><div>I agree.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span class="HOEnZb"><font color="#888888"><br>
 -Hal<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
><br>
><br>
><br>
> -Hal<br>
><br>
><br>
><br>
> ><br>
> ><br>
> ><br>
> ><br>
> > +<br>
> > + return cast<CallInst>(V);<br>
> > + }<br>
> > +<br>
> > + CallInst *operator->() const { return<br>
> > cast<CallInst>(getValPtr());<br>
> > }<br>
> > + CallInst &operator*() const { return<br>
> > *cast<CallInst>(getValPtr());<br>
> > }<br>
> > + };<br>
> > +<br>
> > + friend FunctionCallbackVH;<br>
> > + friend CallCallbackVH;<br>
> > +<br>
> > + // FIXME: SmallSet might be better here, but it currently has no<br>
> > iterators.<br>
> > + typedef DenseSet<CallCallbackVH, CallCallbackVH::DMI><br>
> > CallHandleSet;<br>
> > + typedef DenseMap<FunctionCallbackVH,<br>
> > std::unique_ptr<CallHandleSet>,<br>
> > + FunctionCallbackVH::DMI> FunctionCallsMap;<br>
> > + FunctionCallsMap CachedAssumeCalls;<br>
> > +<br>
> > + /// Scan the provided function for @llvm.assume intrinsic calls.<br>
> > Returns an<br>
> > + /// iterator to the set for this function in the<br>
> > CachedAssumeCalls<br>
> > map.<br>
> > + FunctionCallsMap::iterator scanFunction(Function *F);<br>
> > +<br>
> > +public:<br>
> > + /// Remove the cache of @llvm.assume intrinsics for the given<br>
> > function.<br>
> > + void forgetCachedAssumptions(Function *F);<br>
> > +<br>
> > + /// Add an @llvm.assume intrinsic to the cache for its parent<br>
> > function.<br>
> > + void registerAssumption(CallInst *CI);<br>
> > +<br>
> > + typedef CallHandleSet::iterator assumption_iterator;<br>
> > + typedef iterator_range<assumption_iterator> assumption_range;<br>
> > +<br>
> > + inline assumption_range assumptions(Function *F) {<br>
> > + FunctionCallsMap::iterator I = CachedAssumeCalls.find(F);<br>
> > + if (I == CachedAssumeCalls.end()) {<br>
> > + I = scanFunction(F);<br>
> > + }<br>
> > +<br>
> > + return assumption_range(I->second->begin(), I->second->end());<br>
> > + }<br>
> > +<br>
> > + AssumptionTracker();<br>
> > + ~AssumptionTracker();<br>
> > +<br>
> > + void releaseMemory() override {<br>
> > + CachedAssumeCalls.shrink_and_clear();<br>
> > + }<br>
> > +<br>
> > + void verifyAnalysis() const override;<br>
> > + bool doFinalization(Module &) override {<br>
> > + verifyAnalysis();<br>
> > + return false;<br>
> > + }<br>
> > +<br>
> > + static char ID; // Pass identification, replacement for typeid<br>
> > +};<br>
> > +<br>
> > +} // end namespace llvm<br>
> > +<br>
> > +#endif<br>
> ><br>
> > Modified: llvm/trunk/include/llvm/InitializePasses.h<br>
> > URL:<br>
> > <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=217334&r1=217333&r2=217334&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=217334&r1=217333&r2=217334&view=diff</a><br>
> > ==============================================================================<br>
> > --- llvm/trunk/include/llvm/InitializePasses.h (original)<br>
> > +++ llvm/trunk/include/llvm/InitializePasses.h Sun Sep 7 07:44:26<br>
> > 2014<br>
> > @@ -262,6 +262,7 @@ void initializeDataLayoutPassPass(PassRe<br>
> > void initializeTargetTransformInfoAnalysisGroup(PassRegistry&);<br>
> > void initializeNoTTIPass(PassRegistry&);<br>
> > void initializeTargetLibraryInfoPass(PassRegistry&);<br>
> > +void initializeAssumptionTrackerPass(PassRegistry &);<br>
> > void initializeTwoAddressInstructionPassPass(PassRegistry&);<br>
> > void initializeTypeBasedAliasAnalysisPass(PassRegistry&);<br>
> > void initializeScopedNoAliasAAPass(PassRegistry&);<br>
> ><br>
> > Modified: llvm/trunk/include/llvm/Transforms/Utils/Cloning.h<br>
> > URL:<br>
> > <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Cloning.h?rev=217334&r1=217333&r2=217334&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Cloning.h?rev=217334&r1=217333&r2=217334&view=diff</a><br>
> > ==============================================================================<br>
> > --- llvm/trunk/include/llvm/Transforms/Utils/Cloning.h (original)<br>
> > +++ llvm/trunk/include/llvm/Transforms/Utils/Cloning.h Sun Sep 7<br>
> > 07:44:26 2014<br>
> > @@ -44,6 +44,7 @@ class Loop;<br>
> > class LoopInfo;<br>
> > class AllocaInst;<br>
> > class AliasAnalysis;<br>
> > +class AssumptionTracker;<br>
> ><br>
> > /// CloneModule - Return an exact copy of the specified module<br>
> > ///<br>
> > @@ -160,14 +161,16 @@ class InlineFunctionInfo {<br>
> > public:<br>
> > explicit InlineFunctionInfo(CallGraph *cg = nullptr,<br>
> > const DataLayout *DL = nullptr,<br>
> > - AliasAnalysis *AA = nullptr)<br>
> > - : CG(cg), DL(DL), AA(AA) {}<br>
> > + AliasAnalysis *AA = nullptr,<br>
> > + AssumptionTracker *AT = nullptr)<br>
> > + : CG(cg), DL(DL), AA(AA), AT(AT) {}<br>
> ><br>
> > /// CG - If non-null, InlineFunction will update the callgraph to<br>
> > reflect the<br>
> > /// changes it makes.<br>
> > CallGraph *CG;<br>
> > const DataLayout *DL;<br>
> > AliasAnalysis *AA;<br>
> > + AssumptionTracker *AT;<br>
> ><br>
> > /// StaticAllocas - InlineFunction fills this in with all static<br>
> > allocas that<br>
> > /// get copied into the caller.<br>
> ><br>
> > Modified: llvm/trunk/include/llvm/Transforms/Utils/UnrollLoop.h<br>
> > URL:<br>
> > <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/UnrollLoop.h?rev=217334&r1=217333&r2=217334&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/UnrollLoop.h?rev=217334&r1=217333&r2=217334&view=diff</a><br>
> > ==============================================================================<br>
> > --- llvm/trunk/include/llvm/Transforms/Utils/UnrollLoop.h<br>
> > (original)<br>
> > +++ llvm/trunk/include/llvm/Transforms/Utils/UnrollLoop.h Sun Sep 7<br>
> > 07:44:26 2014<br>
> > @@ -18,6 +18,7 @@<br>
> ><br>
> > namespace llvm {<br>
> ><br>
> > +class AssumptionTracker;<br>
> > class Loop;<br>
> > class LoopInfo;<br>
> > class LPPassManager;<br>
> > @@ -25,7 +26,7 @@ class Pass;<br>
> ><br>
> > bool UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool<br>
> > AllowRuntime,<br>
> > unsigned TripMultiple, LoopInfo *LI, Pass *PP,<br>
> > - LPPassManager *LPM);<br>
> > + LPPassManager *LPM, AssumptionTracker *AT);<br>
> ><br>
> > bool UnrollRuntimeLoopProlog(Loop *L, unsigned Count, LoopInfo *LI,<br>
> > LPPassManager* LPM);<br>
> ><br>
> > Added: llvm/trunk/lib/Analysis/AssumptionTracker.cpp<br>
> > URL:<br>
> > <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/AssumptionTracker.cpp?rev=217334&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/AssumptionTracker.cpp?rev=217334&view=auto</a><br>
> > ==============================================================================<br>
> > --- llvm/trunk/lib/Analysis/AssumptionTracker.cpp (added)<br>
> > +++ llvm/trunk/lib/Analysis/AssumptionTracker.cpp Sun Sep 7<br>
> > 07:44:26<br>
> > 2014<br>
> > @@ -0,0 +1,113 @@<br>
> > +//===- AssumptionTracker.cpp - Track @llvm.assume<br>
> > -------------------------===//<br>
> > +//<br>
> > +// The LLVM Compiler Infrastructure<br>
> > +//<br>
> > +// This file is distributed under the University of Illinois Open<br>
> > Source<br>
> > +// License. See LICENSE.TXT for details.<br>
> > +//<br>
> > +//===----------------------------------------------------------------------===//<br>
> > +//<br>
> > +// This file contains a pass that keeps track of @llvm.assume<br>
> > intrinsics in<br>
> > +// the functions of a module.<br>
> > +//<br>
> > +//===----------------------------------------------------------------------===//<br>
> > +<br>
> > +#include "llvm/Analysis/AssumptionTracker.h"<br>
> > +#include "llvm/IR/CallSite.h"<br>
> > +#include "llvm/IR/Dominators.h"<br>
> > +#include "llvm/IR/Function.h"<br>
> > +#include "llvm/IR/Instructions.h"<br>
> > +#include "llvm/IR/IntrinsicInst.h"<br>
> > +#include "llvm/IR/PatternMatch.h"<br>
> > +#include "llvm/Support/Debug.h"<br>
> > +using namespace llvm;<br>
> > +using namespace llvm::PatternMatch;<br>
> > +<br>
> > +void AssumptionTracker::FunctionCallbackVH::deleted() {<br>
> > + AT->forgetCachedAssumptions(cast<Function>(getValPtr()));<br>
> > + // 'this' now dangles!<br>
> > +}<br>
> > +<br>
> > +void AssumptionTracker::forgetCachedAssumptions(Function *F) {<br>
> > + CachedAssumeCalls.erase(F);<br>
> > +}<br>
> > +<br>
> > +void AssumptionTracker::CallCallbackVH::deleted() {<br>
> > + assert(F && "delete callback called on dummy handle");<br>
> > + FunctionCallsMap::iterator I = AT->CachedAssumeCalls.find(F);<br>
> > + assert(I != AT->CachedAssumeCalls.end() &&<br>
> > + "Function cleared from the map without removing the values?");<br>
> > +<br>
> > + I->second->erase(*this);<br>
> > + // 'this' now dangles!<br>
> > +}<br>
> > +<br>
> > +AssumptionTracker::FunctionCallsMap::iterator<br>
> > +AssumptionTracker::scanFunction(Function *F) {<br>
> > + auto IP =<br>
> > + CachedAssumeCalls.insert(std::make_pair(FunctionCallbackVH(F,<br>
> > this),<br>
> > + std::unique_ptr<CallHandleSet>(<br>
> > + new CallHandleSet())));<br>
> > + assert(IP.second && "Scanning function already in the map?");<br>
> > +<br>
> > + FunctionCallsMap::iterator I = IP.first;<br>
> > +<br>
> > + // Go through all instructions in all blocks, add all calls to<br>
> > @llvm.assume<br>
> > + // to our cache.<br>
> > + for (BasicBlock &B : *F)<br>
> > + for (Instruction &II : B)<br>
> > + if (match(cast<Value>(&II),<br>
> > m_Intrinsic<Intrinsic::assume>(m_Value())))<br>
> > + I->second->insert(CallCallbackVH(&II, this));<br>
> > +<br>
> > + return I;<br>
> > +}<br>
> > +<br>
> > +void AssumptionTracker::verifyAnalysis() const {<br>
> > +#ifndef NDEBUG<br>
> > + for (const auto &I : CachedAssumeCalls) {<br>
> > + for (const BasicBlock &B : cast<Function>(*I.first))<br>
> > + for (const Instruction &II : B) {<br>
> > + Instruction *C = const_cast<Instruction*>(&II);<br>
> > + if (match(C, m_Intrinsic<Intrinsic::assume>(m_Value()))) {<br>
> > + assert(I.second->count(CallCallbackVH(C,<br>
> > + const_cast<AssumptionTracker*>(this))) &&<br>
> > + "Assumption in scanned function not in cache");<br>
> > + }<br>
> > + }<br>
> > + }<br>
> > +#endif<br>
> > +}<br>
> > +<br>
> > +void AssumptionTracker::registerAssumption(CallInst *CI) {<br>
> > + assert(match(cast<Value>(CI),<br>
> > + m_Intrinsic<Intrinsic::assume>(m_Value())) &&<br>
> > + "Registered call does not call @llvm.assume");<br>
> > + assert(CI->getParent() &&<br>
> > + "Cannot register @llvm.assume call not in a basic block");<br>
> > +<br>
> > + Function *F = CI->getParent()->getParent();<br>
> > + assert(F && "Cannot register @llvm.assume call not in a<br>
> > function");<br>
> > +<br>
> > + FunctionCallsMap::iterator I = CachedAssumeCalls.find(F);<br>
> > + if (I == CachedAssumeCalls.end()) {<br>
> > + // If this function has not already been scanned, then don't do<br>
> > anything<br>
> > + // here. This intrinsic will be found, if it still exists, if the<br>
> > list of<br>
> > + // assumptions in this function is requested at some later point.<br>
> > This<br>
> > + // maintains the following invariant: if a function is present in<br>
> > the<br>
> > + // cache, then its list of assumption intrinsic calls is<br>
> > complete.<br>
> > + return;<br>
> > + }<br>
> > +<br>
> > + I->second->insert(CallCallbackVH(CI, this));<br>
> > +}<br>
> > +<br>
> > +AssumptionTracker::AssumptionTracker() : ImmutablePass(ID) {<br>
> > +<br>
> > initializeAssumptionTrackerPass(*PassRegistry::getPassRegistry());<br>
> > +}<br>
> > +<br>
> > +AssumptionTracker::~AssumptionTracker() {}<br>
> > +<br>
> > +INITIALIZE_PASS(AssumptionTracker, "assumption-tracker",<br>
> > "Assumption<br>
> > Tracker",<br>
> > + false, true)<br>
> > +char AssumptionTracker::ID = 0;<br>
> > +<br>
> ><br>
> > Modified: llvm/trunk/lib/Analysis/CMakeLists.txt<br>
> > URL:<br>
> > <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CMakeLists.txt?rev=217334&r1=217333&r2=217334&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CMakeLists.txt?rev=217334&r1=217333&r2=217334&view=diff</a><br>
> > ==============================================================================<br>
> > --- llvm/trunk/lib/Analysis/CMakeLists.txt (original)<br>
> > +++ llvm/trunk/lib/Analysis/CMakeLists.txt Sun Sep 7 07:44:26 2014<br>
> > @@ -5,6 +5,7 @@ add_llvm_library(LLVMAnalysis<br>
> > AliasDebugger.cpp<br>
> > AliasSetTracker.cpp<br>
> > Analysis.cpp<br>
> > + AssumptionTracker.cpp<br>
> > BasicAliasAnalysis.cpp<br>
> > BlockFrequencyInfo.cpp<br>
> > BlockFrequencyInfoImpl.cpp<br>
> ><br>
> > Modified: llvm/trunk/lib/Transforms/IPO/InlineAlways.cpp<br>
> > URL:<br>
> > <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/InlineAlways.cpp?rev=217334&r1=217333&r2=217334&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/InlineAlways.cpp?rev=217334&r1=217333&r2=217334&view=diff</a><br>
> > ==============================================================================<br>
> > --- llvm/trunk/lib/Transforms/IPO/InlineAlways.cpp (original)<br>
> > +++ llvm/trunk/lib/Transforms/IPO/InlineAlways.cpp Sun Sep 7<br>
> > 07:44:26<br>
> > 2014<br>
> > @@ -15,6 +15,7 @@<br>
> > #include "llvm/Transforms/IPO.h"<br>
> > #include "llvm/ADT/SmallPtrSet.h"<br>
> > #include "llvm/Analysis/AliasAnalysis.h"<br>
> > +#include "llvm/Analysis/AssumptionTracker.h"<br>
> > #include "llvm/Analysis/CallGraph.h"<br>
> > #include "llvm/Analysis/InlineCost.h"<br>
> > #include "llvm/IR/CallSite.h"<br>
> > @@ -67,6 +68,7 @@ char AlwaysInliner::ID = 0;<br>
> > INITIALIZE_PASS_BEGIN(AlwaysInliner, "always-inline",<br>
> > "Inliner for always_inline functions", false, false)<br>
> > INITIALIZE_AG_DEPENDENCY(AliasAnalysis)<br>
> > +INITIALIZE_PASS_DEPENDENCY(AssumptionTracker)<br>
> > INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass)<br>
> > INITIALIZE_PASS_DEPENDENCY(InlineCostAnalysis)<br>
> > INITIALIZE_PASS_END(AlwaysInliner, "always-inline",<br>
> ><br>
> > Modified: llvm/trunk/lib/Transforms/IPO/InlineSimple.cpp<br>
> > URL:<br>
> > <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/InlineSimple.cpp?rev=217334&r1=217333&r2=217334&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/InlineSimple.cpp?rev=217334&r1=217333&r2=217334&view=diff</a><br>
> > ==============================================================================<br>
> > --- llvm/trunk/lib/Transforms/IPO/InlineSimple.cpp (original)<br>
> > +++ llvm/trunk/lib/Transforms/IPO/InlineSimple.cpp Sun Sep 7<br>
> > 07:44:26<br>
> > 2014<br>
> > @@ -13,6 +13,7 @@<br>
> ><br>
> > #include "llvm/Transforms/IPO.h"<br>
> > #include "llvm/Analysis/AliasAnalysis.h"<br>
> > +#include "llvm/Analysis/AssumptionTracker.h"<br>
> > #include "llvm/Analysis/CallGraph.h"<br>
> > #include "llvm/Analysis/InlineCost.h"<br>
> > #include "llvm/IR/CallSite.h"<br>
> > @@ -75,6 +76,7 @@ char SimpleInliner::ID = 0;<br>
> > INITIALIZE_PASS_BEGIN(SimpleInliner, "inline",<br>
> > "Function Integration/Inlining", false, false)<br>
> > INITIALIZE_AG_DEPENDENCY(AliasAnalysis)<br>
> > +INITIALIZE_PASS_DEPENDENCY(AssumptionTracker)<br>
> > INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass)<br>
> > INITIALIZE_PASS_DEPENDENCY(InlineCostAnalysis)<br>
> > INITIALIZE_PASS_END(SimpleInliner, "inline",<br>
> ><br>
> > Modified: llvm/trunk/lib/Transforms/IPO/Inliner.cpp<br>
> > URL:<br>
> > <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/Inliner.cpp?rev=217334&r1=217333&r2=217334&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/Inliner.cpp?rev=217334&r1=217333&r2=217334&view=diff</a><br>
> > ==============================================================================<br>
> > --- llvm/trunk/lib/Transforms/IPO/Inliner.cpp (original)<br>
> > +++ llvm/trunk/lib/Transforms/IPO/Inliner.cpp Sun Sep 7 07:44:26<br>
> > 2014<br>
> > @@ -17,6 +17,7 @@<br>
> > #include "llvm/ADT/SmallPtrSet.h"<br>
> > #include "llvm/ADT/Statistic.h"<br>
> > #include "llvm/Analysis/AliasAnalysis.h"<br>
> > +#include "llvm/Analysis/AssumptionTracker.h"<br>
> > #include "llvm/Analysis/CallGraph.h"<br>
> > #include "llvm/Analysis/InlineCost.h"<br>
> > #include "llvm/IR/CallSite.h"<br>
> > @@ -76,6 +77,7 @@ Inliner::Inliner(char &ID, int Threshold<br>
> > /// always explicitly call the implementation here.<br>
> > void Inliner::getAnalysisUsage(AnalysisUsage &AU) const {<br>
> > AU.addRequired<AliasAnalysis>();<br>
> > + AU.addRequired<AssumptionTracker>();<br>
> > CallGraphSCCPass::getAnalysisUsage(AU);<br>
> > }<br>
> ><br>
> > @@ -441,6 +443,7 @@ static bool InlineHistoryIncludes(Functi<br>
> ><br>
> > bool Inliner::runOnSCC(CallGraphSCC &SCC) {<br>
> > CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph();<br>
> > + AssumptionTracker *AT = &getAnalysis<AssumptionTracker>();<br>
> > DataLayoutPass *DLP = getAnalysisIfAvailable<DataLayoutPass>();<br>
> > const DataLayout *DL = DLP ? &DLP->getDataLayout() : nullptr;<br>
> > const TargetLibraryInfo *TLI =<br>
> > getAnalysisIfAvailable<TargetLibraryInfo>();<br>
> > @@ -503,7 +506,7 @@ bool Inliner::runOnSCC(CallGraphSCC &SCC<br>
> ><br>
> ><br>
> > InlinedArrayAllocasTy InlinedArrayAllocas;<br>
> > - InlineFunctionInfo InlineInfo(&CG, DL, AA);<br>
> > + InlineFunctionInfo InlineInfo(&CG, DL, AA, AT);<br>
> ><br>
> > // Now that we have all of the call sites, loop over them and<br>
> > inline<br>
> > them if<br>
> > // it looks profitable to do so.<br>
> ><br>
> > Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombine.h<br>
> > URL:<br>
> > <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombine.h?rev=217334&r1=217333&r2=217334&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombine.h?rev=217334&r1=217333&r2=217334&view=diff</a><br>
> > ==============================================================================<br>
> > --- llvm/trunk/lib/Transforms/InstCombine/InstCombine.h (original)<br>
> > +++ llvm/trunk/lib/Transforms/InstCombine/InstCombine.h Sun Sep 7<br>
> > 07:44:26 2014<br>
> > @@ -11,12 +11,14 @@<br>
> > #define LLVM_LIB_TRANSFORMS_INSTCOMBINE_INSTCOMBINE_H<br>
> ><br>
> > #include "InstCombineWorklist.h"<br>
> > +#include "llvm/Analysis/AssumptionTracker.h"<br>
> > #include "llvm/Analysis/TargetFolder.h"<br>
> > #include "llvm/Analysis/ValueTracking.h"<br>
> > #include "llvm/IR/IRBuilder.h"<br>
> > #include "llvm/IR/InstVisitor.h"<br>
> > #include "llvm/IR/IntrinsicInst.h"<br>
> > #include "llvm/IR/Operator.h"<br>
> > +#include "llvm/IR/PatternMatch.h"<br>
> > #include "llvm/Pass.h"<br>
> > #include "llvm/Transforms/Utils/SimplifyLibCalls.h"<br>
> ><br>
> > @@ -71,14 +73,20 @@ static inline Constant *SubOne(Constant<br>
> > class LLVM_LIBRARY_VISIBILITY InstCombineIRInserter<br>
> > : public IRBuilderDefaultInserter<true> {<br>
> > InstCombineWorklist &Worklist;<br>
> > + AssumptionTracker *AT;<br>
> ><br>
> > public:<br>
> > - InstCombineIRInserter(InstCombineWorklist &WL) : Worklist(WL) {}<br>
> > + InstCombineIRInserter(InstCombineWorklist &WL, AssumptionTracker<br>
> > *AT)<br>
> > + : Worklist(WL), AT(AT) {}<br>
> ><br>
> > void InsertHelper(Instruction *I, const Twine &Name, BasicBlock<br>
> > *BB,<br>
> > BasicBlock::iterator InsertPt) const {<br>
> > IRBuilderDefaultInserter<true>::InsertHelper(I, Name, BB,<br>
> > InsertPt);<br>
> > Worklist.Add(I);<br>
> > +<br>
> > + using namespace llvm::PatternMatch;<br>
> > + if ((match(I, m_Intrinsic<Intrinsic::assume>(m_Value()))))<br>
> > + AT->registerAssumption(cast<CallInst>(I));<br>
> > }<br>
> > };<br>
> ><br>
> > @@ -86,6 +94,7 @@ public:<br>
> > class LLVM_LIBRARY_VISIBILITY InstCombiner<br>
> > : public FunctionPass,<br>
> > public InstVisitor<InstCombiner, Instruction *> {<br>
> > + AssumptionTracker *AT;<br>
> > const DataLayout *DL;<br>
> > TargetLibraryInfo *TLI;<br>
> > bool MadeIRChange;<br>
> > @@ -114,6 +123,8 @@ public:<br>
> ><br>
> > void getAnalysisUsage(AnalysisUsage &AU) const override;<br>
> ><br>
> > + AssumptionTracker *getAssumptionTracker() const { return AT; }<br>
> > +<br>
> > const DataLayout *getDataLayout() const { return DL; }<br>
> ><br>
> > TargetLibraryInfo *getTargetLibraryInfo() const { return TLI; }<br>
> ><br>
> > Modified:<br>
> > llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp<br>
> > URL:<br>
> > <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp?rev=217334&r1=217333&r2=217334&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp?rev=217334&r1=217333&r2=217334&view=diff</a><br>
> > ==============================================================================<br>
> > --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp<br>
> > (original)<br>
> > +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Sun<br>
> > Sep 7 07:44:26 2014<br>
> > @@ -996,6 +996,8 @@ Instruction *InstCombiner::visitCallInst<br>
> > }<br>
> > case Intrinsic::assume: {<br>
> > // Canonicalize assume(a && b) -> assume(a); assume(b);<br>
> > + // Note: New assumption intrinsics created here are registered by<br>
> > + // the InstCombineIRInserter object.<br>
> > Value *IIOperand = II->getArgOperand(0), *A, *B,<br>
> > *AssumeIntrinsic = II->getCalledValue();<br>
> > if (match(IIOperand, m_And(m_Value(A), m_Value(B)))) {<br>
> > @@ -1005,8 +1007,10 @@ Instruction *InstCombiner::visitCallInst<br>
> > }<br>
> > // assume(!(a || b)) -> assume(!a); assume(!b);<br>
> > if (match(IIOperand, m_Not(m_Or(m_Value(A), m_Value(B))))) {<br>
> > - Builder->CreateCall(AssumeIntrinsic, Builder->CreateNot(A),<br>
> > II->getName());<br>
> > - Builder->CreateCall(AssumeIntrinsic, Builder->CreateNot(B),<br>
> > II->getName());<br>
> > + Builder->CreateCall(AssumeIntrinsic, Builder->CreateNot(A),<br>
> > + II->getName());<br>
> > + Builder->CreateCall(AssumeIntrinsic, Builder->CreateNot(B),<br>
> > + II->getName());<br>
> > return EraseInstFromFunction(*II);<br>
> > }<br>
> > break;<br>
> ><br>
> > Modified:<br>
> > llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp<br>
> > URL:<br>
> > <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp?rev=217334&r1=217333&r2=217334&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp?rev=217334&r1=217333&r2=217334&view=diff</a><br>
> > ==============================================================================<br>
> > --- llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp<br>
> > (original)<br>
> > +++ llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp<br>
> > Sun Sep 7 07:44:26 2014<br>
> > @@ -39,6 +39,7 @@<br>
> > #include "llvm/ADT/SmallPtrSet.h"<br>
> > #include "llvm/ADT/Statistic.h"<br>
> > #include "llvm/ADT/StringSwitch.h"<br>
> > +#include "llvm/Analysis/AssumptionTracker.h"<br>
> > #include "llvm/Analysis/ConstantFolding.h"<br>
> > #include "llvm/Analysis/InstructionSimplify.h"<br>
> > #include "llvm/Analysis/MemoryBuiltins.h"<br>
> > @@ -85,12 +86,14 @@ void LLVMInitializeInstCombine(LLVMPassR<br>
> > char InstCombiner::ID = 0;<br>
> > INITIALIZE_PASS_BEGIN(InstCombiner, "instcombine",<br>
> > "Combine redundant instructions", false, false)<br>
> > +INITIALIZE_PASS_DEPENDENCY(AssumptionTracker)<br>
> > INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfo)<br>
> > INITIALIZE_PASS_END(InstCombiner, "instcombine",<br>
> > "Combine redundant instructions", false, false)<br>
> ><br>
> > void InstCombiner::getAnalysisUsage(AnalysisUsage &AU) const {<br>
> > AU.setPreservesCFG();<br>
> > + AU.addRequired<AssumptionTracker>();<br>
> > AU.addRequired<TargetLibraryInfo>();<br>
> > }<br>
> ><br>
> > @@ -2907,6 +2910,7 @@ bool InstCombiner::runOnFunction(Functio<br>
> > if (skipOptnoneFunction(F))<br>
> > return false;<br>
> ><br>
> > + AT = &getAnalysis<AssumptionTracker>();<br>
> > DataLayoutPass *DLP = getAnalysisIfAvailable<DataLayoutPass>();<br>
> > DL = DLP ? &DLP->getDataLayout() : nullptr;<br>
> > TLI = &getAnalysis<TargetLibraryInfo>();<br>
> > @@ -2918,7 +2922,7 @@ bool InstCombiner::runOnFunction(Functio<br>
> > /// instructions into the worklist when they are created.<br>
> > IRBuilder<true, TargetFolder, InstCombineIRInserter><br>
> > TheBuilder(F.getContext(), TargetFolder(DL),<br>
> > - InstCombineIRInserter(Worklist));<br>
> > + InstCombineIRInserter(Worklist, AT));<br>
> > Builder = &TheBuilder;<br>
> ><br>
> > InstCombinerLibCallSimplifier TheSimplifier(DL, TLI, this);<br>
> ><br>
> > Modified: llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp<br>
> > URL:<br>
> > <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp?rev=217334&r1=217333&r2=217334&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp?rev=217334&r1=217333&r2=217334&view=diff</a><br>
> > ==============================================================================<br>
> > --- llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp (original)<br>
> > +++ llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp Sun Sep 7<br>
> > 07:44:26 2014<br>
> > @@ -13,6 +13,7 @@<br>
> > //===----------------------------------------------------------------------===//<br>
> ><br>
> > #include "llvm/Transforms/Scalar.h"<br>
> > +#include "llvm/Analysis/AssumptionTracker.h"<br>
> > #include "llvm/Analysis/CodeMetrics.h"<br>
> > #include "llvm/Analysis/LoopPass.h"<br>
> > #include "llvm/Analysis/ScalarEvolution.h"<br>
> > @@ -102,6 +103,7 @@ namespace {<br>
> > /// loop preheaders be inserted into the CFG...<br>
> > ///<br>
> > void getAnalysisUsage(AnalysisUsage &AU) const override {<br>
> > + AU.addRequired<AssumptionTracker>();<br>
> > AU.addRequired<LoopInfo>();<br>
> > AU.addPreserved<LoopInfo>();<br>
> > AU.addRequiredID(LoopSimplifyID);<br>
> > @@ -182,6 +184,7 @@ namespace {<br>
> > char LoopUnroll::ID = 0;<br>
> > INITIALIZE_PASS_BEGIN(LoopUnroll, "loop-unroll", "Unroll loops",<br>
> > false, false)<br>
> > INITIALIZE_AG_DEPENDENCY(TargetTransformInfo)<br>
> > +INITIALIZE_PASS_DEPENDENCY(AssumptionTracker)<br>
> > INITIALIZE_PASS_DEPENDENCY(LoopInfo)<br>
> > INITIALIZE_PASS_DEPENDENCY(LoopSimplify)<br>
> > INITIALIZE_PASS_DEPENDENCY(LCSSA)<br>
> > @@ -351,6 +354,7 @@ bool LoopUnroll::runOnLoop(Loop *L, LPPa<br>
> > LoopInfo *LI = &getAnalysis<LoopInfo>();<br>
> > ScalarEvolution *SE = &getAnalysis<ScalarEvolution>();<br>
> > const TargetTransformInfo &TTI =<br>
> > getAnalysis<TargetTransformInfo>();<br>
> > + AssumptionTracker *AT = &getAnalysis<AssumptionTracker>();<br>
> ><br>
> > BasicBlock *Header = L->getHeader();<br>
> > DEBUG(dbgs() << "Loop Unroll: F[" << Header->getParent()->getName()<br>
> > @@ -493,7 +497,8 @@ bool LoopUnroll::runOnLoop(Loop *L, LPPa<br>
> > }<br>
> ><br>
> > // Unroll the loop.<br>
> > - if (!UnrollLoop(L, Count, TripCount, AllowRuntime, TripMultiple,<br>
> > LI, this, &LPM))<br>
> > + if (!UnrollLoop(L, Count, TripCount, AllowRuntime, TripMultiple,<br>
> > LI, this,<br>
> > + &LPM, AT))<br>
> > return false;<br>
> ><br>
> > return true;<br>
> ><br>
> > Modified: llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp<br>
> > URL:<br>
> > <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp?rev=217334&r1=217333&r2=217334&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp?rev=217334&r1=217333&r2=217334&view=diff</a><br>
> > ==============================================================================<br>
> > --- llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp (original)<br>
> > +++ llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp Sun Sep 7<br>
> > 07:44:26 2014<br>
> > @@ -30,6 +30,7 @@<br>
> > #include "llvm/ADT/STLExtras.h"<br>
> > #include "llvm/ADT/SmallPtrSet.h"<br>
> > #include "llvm/ADT/Statistic.h"<br>
> > +#include "llvm/Analysis/AssumptionTracker.h"<br>
> > #include "llvm/Analysis/CodeMetrics.h"<br>
> > #include "llvm/Analysis/InstructionSimplify.h"<br>
> > #include "llvm/Analysis/LoopInfo.h"<br>
> > @@ -126,6 +127,7 @@ namespace {<br>
> > class LoopUnswitch : public LoopPass {<br>
> > LoopInfo *LI; // Loop information<br>
> > LPPassManager *LPM;<br>
> > + AssumptionTracker *AT;<br>
> ><br>
> > // LoopProcessWorklist - Used to check if second loop needs<br>
> > processing<br>
> > // after RewriteLoopBodyWithConditionConstant rewrites first loop.<br>
> > @@ -164,6 +166,7 @@ namespace {<br>
> > /// loop preheaders be inserted into the CFG.<br>
> > ///<br>
> > void getAnalysisUsage(AnalysisUsage &AU) const override {<br>
> > + AU.addRequired<AssumptionTracker>();<br>
> > AU.addRequiredID(LoopSimplifyID);<br>
> > AU.addPreservedID(LoopSimplifyID);<br>
> > AU.addRequired<LoopInfo>();<br>
> > @@ -326,6 +329,7 @@ char LoopUnswitch::ID = 0;<br>
> > INITIALIZE_PASS_BEGIN(LoopUnswitch, "loop-unswitch", "Unswitch<br>
> > loops",<br>
> > false, false)<br>
> > INITIALIZE_AG_DEPENDENCY(TargetTransformInfo)<br>
> > +INITIALIZE_PASS_DEPENDENCY(AssumptionTracker)<br>
> > INITIALIZE_PASS_DEPENDENCY(LoopSimplify)<br>
> > INITIALIZE_PASS_DEPENDENCY(LoopInfo)<br>
> > INITIALIZE_PASS_DEPENDENCY(LCSSA)<br>
> > @@ -376,6 +380,7 @@ bool LoopUnswitch::runOnLoop(Loop *L, LP<br>
> > if (skipOptnoneFunction(L))<br>
> > return false;<br>
> ><br>
> > + AT = &getAnalysis<AssumptionTracker>();<br>
> > LI = &getAnalysis<LoopInfo>();<br>
> > LPM = &LPM_Ref;<br>
> > DominatorTreeWrapperPass *DTWP =<br>
> > @@ -823,6 +828,10 @@ void LoopUnswitch::UnswitchNontrivialCon<br>
> > F->getBasicBlockList().splice(NewPreheader, F->getBasicBlockList(),<br>
> > NewBlocks[0], F->end());<br>
> ><br>
> > + // FIXME: We could register any cloned assumptions instead of<br>
> > clearing the<br>
> > + // whole function's cache.<br>
> > + AT->forgetCachedAssumptions(F);<br>
> > +<br>
> > // Now we create the new Loop object for the versioned loop.<br>
> > Loop *NewLoop = CloneLoop(L, L->getParentLoop(), VMap, LI, LPM);<br>
> ><br>
> ><br>
> > Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp<br>
> > URL:<br>
> > <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp?rev=217334&r1=217333&r2=217334&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp?rev=217334&r1=217333&r2=217334&view=diff</a><br>
> > ==============================================================================<br>
> > --- llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp (original)<br>
> > +++ llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Sun Sep 7<br>
> > 07:44:26 2014<br>
> > @@ -18,6 +18,7 @@<br>
> > #include "llvm/ADT/SetVector.h"<br>
> > #include "llvm/ADT/StringExtras.h"<br>
> > #include "llvm/Analysis/AliasAnalysis.h"<br>
> > +#include "llvm/Analysis/AssumptionTracker.h"<br>
> > #include "llvm/Analysis/CallGraph.h"<br>
> > #include "llvm/Analysis/CaptureTracking.h"<br>
> > #include "llvm/Analysis/InstructionSimplify.h"<br>
> > @@ -982,6 +983,11 @@ bool llvm::InlineFunction(CallSite CS, I<br>
> ><br>
> > // Add noalias metadata if necessary.<br>
> > AddAliasScopeMetadata(CS, VMap, IFI.DL, IFI.AA);<br>
> > +<br>
> > + // FIXME: We could register any cloned assumptions instead of<br>
> > clearing the<br>
> > + // whole function's cache.<br>
> > + if ( <a href="http://IFI.AT" target="_blank">IFI.AT</a> )<br>
> > + IFI.AT->forgetCachedAssumptions(Caller);<br>
> > }<br>
> ><br>
> > // If there are any alloca instructions in the block that used to<br>
> > be<br>
> > the entry<br>
> ><br>
> > Modified: llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp<br>
> > URL:<br>
> > <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp?rev=217334&r1=217333&r2=217334&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp?rev=217334&r1=217333&r2=217334&view=diff</a><br>
> > ==============================================================================<br>
> > --- llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp (original)<br>
> > +++ llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp Sun Sep 7<br>
> > 07:44:26<br>
> > 2014<br>
> > @@ -19,6 +19,7 @@<br>
> > #include "llvm/Transforms/Utils/UnrollLoop.h"<br>
> > #include "llvm/ADT/SmallPtrSet.h"<br>
> > #include "llvm/ADT/Statistic.h"<br>
> > +#include "llvm/Analysis/AssumptionTracker.h"<br>
> > #include "llvm/Analysis/InstructionSimplify.h"<br>
> > #include "llvm/Analysis/LoopIterator.h"<br>
> > #include "llvm/Analysis/LoopPass.h"<br>
> > @@ -154,7 +155,8 @@ FoldBlockIntoPredecessor(BasicBlock *BB,<br>
> > /// available from the Pass it must also preserve those analyses.<br>
> > bool llvm::UnrollLoop(Loop *L, unsigned Count, unsigned TripCount,<br>
> > bool AllowRuntime, unsigned TripMultiple,<br>
> > - LoopInfo *LI, Pass *PP, LPPassManager *LPM) {<br>
> > + LoopInfo *LI, Pass *PP, LPPassManager *LPM,<br>
> > + AssumptionTracker *AT) {<br>
> > BasicBlock *Preheader = L->getLoopPreheader();<br>
> > if (!Preheader) {<br>
> > DEBUG(dbgs() << " Can't unroll; loop preheader-insertion<br>
> > failed.\n");<br>
> > @@ -442,6 +444,10 @@ bool llvm::UnrollLoop(Loop *L, unsigned<br>
> > }<br>
> > }<br>
> ><br>
> > + // FIXME: We could register any cloned assumptions instead of<br>
> > clearing the<br>
> > + // whole function's cache.<br>
> > + AT->forgetCachedAssumptions(F);<br>
> > +<br>
> > DominatorTree *DT = nullptr;<br>
> > if (PP) {<br>
> > // FIXME: Reconstruct dom info, because it is not preserved<br>
> > properly.<br>
> ><br>
> ><br>
> > _______________________________________________<br>
> > llvm-commits mailing list<br>
> > <a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
> > <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
> ><br>
> ><br>
> ><br>
> ><br>
> > --<br>
> ><br>
> > Alexey Samsonov<br>
> > <a href="mailto:vonosmas@gmail.com">vonosmas@gmail.com</a><br>
><br>
> --<br>
> Hal Finkel<br>
> Assistant Computational Scientist<br>
> Leadership Computing Facility<br>
> Argonne National Laboratory<br>
><br>
><br>
><br>
><br>
> --<br>
><br>
> Alexey Samsonov<br>
> <a href="mailto:vonosmas@gmail.com">vonosmas@gmail.com</a><br>
<br>
--<br>
Hal Finkel<br>
Assistant Computational Scientist<br>
Leadership Computing Facility<br>
Argonne National Laboratory<br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div dir="ltr">Alexey Samsonov<br><a href="mailto:vonosmas@gmail.com" target="_blank">vonosmas@gmail.com</a></div>
</div></div>