[llvm] r217334 - Add an Assumption-Tracking Pass

Hal Finkel hfinkel at anl.gov
Mon Sep 8 11:52:31 PDT 2014


----- Original Message -----
> From: "Alexey Samsonov" <vonosmas at gmail.com>
> To: "Hal Finkel" <hfinkel at anl.gov>
> Cc: "llvm-commits" <llvm-commits at cs.uiuc.edu>
> Sent: Monday, September 8, 2014 1:27:46 PM
> Subject: Re: [llvm] r217334 - Add an Assumption-Tracking Pass
> 
> 
> 
> 
> On Mon, Sep 8, 2014 at 11:07 AM, Hal Finkel < hfinkel at anl.gov >
> wrote:
> 
> 
> 
> 
> ----- Original Message -----
> > From: "Alexey Samsonov" < vonosmas at gmail.com >
> > To: "Hal Finkel" < hfinkel at anl.gov >
> > Cc: "llvm-commits" < llvm-commits at cs.uiuc.edu >
> > Sent: Monday, September 8, 2014 12:57:52 PM
> > Subject: Re: [llvm] r217334 - Add an Assumption-Tracking Pass
> > 
> > 
> > Hi Hal,
> > 
> > 
> > On Sun, Sep 7, 2014 at 5:44 AM, Hal Finkel < hfinkel at anl.gov >
> > wrote:
> > 
> > 
> > Author: hfinkel
> > Date: Sun Sep 7 07:44:26 2014
> > New Revision: 217334
> > 
> > URL: http://llvm.org/viewvc/llvm-project?rev=217334&view=rev
> > Log:
> > Add an Assumption-Tracking Pass
> > 
> > This adds an immutable pass, AssumptionTracker, which keeps a cache
> > of
> > @llvm.assume call instructions within a module. It uses callback
> > value handles
> > to keep stale functions and intrinsics out of the map, and it
> > relies
> > on any
> > code that creates new @llvm.assume calls to notify it of the new
> > instructions.
> > The benefit is that code needing to find @llvm.assume intrinsics
> > can
> > do so
> > directly, without scanning the function, thus allowing the cost of
> > @llvm.assume
> > handling to be negligible when none are present.
> > 
> > The current design is intended to be lightweight. We don't keep
> > track
> > of
> > anything until we need a list of assumptions in some function. The
> > first time
> > this happens, we scan the function. After that, we add/remove
> > @llvm.assume
> > calls from the cache in response to registration calls and
> > ValueHandle
> > callbacks.
> > 
> > There are no new direct test cases for this pass, but because it
> > calls it
> > validation function upon module finalization, we'll pick up
> > detectable
> > inconsistencies from the other tests that touch @llvm.assume calls.
> > 
> > This pass will be used by follow-up commits that make use of
> > @llvm.assume.
> > 
> > Added:
> > llvm/trunk/include/llvm/Analysis/AssumptionTracker.h
> > llvm/trunk/lib/Analysis/AssumptionTracker.cpp
> > Modified:
> > llvm/trunk/include/llvm/InitializePasses.h
> > llvm/trunk/include/llvm/Transforms/Utils/Cloning.h
> > llvm/trunk/include/llvm/Transforms/Utils/UnrollLoop.h
> > llvm/trunk/lib/Analysis/CMakeLists.txt
> > llvm/trunk/lib/Transforms/IPO/InlineAlways.cpp
> > llvm/trunk/lib/Transforms/IPO/InlineSimple.cpp
> > llvm/trunk/lib/Transforms/IPO/Inliner.cpp
> > llvm/trunk/lib/Transforms/InstCombine/InstCombine.h
> > llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
> > llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp
> > llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp
> > llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp
> > llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp
> > llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp
> > 
> > Added: llvm/trunk/include/llvm/Analysis/AssumptionTracker.h
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/AssumptionTracker.h?rev=217334&view=auto
> > ==============================================================================
> > --- llvm/trunk/include/llvm/Analysis/AssumptionTracker.h (added)
> > +++ llvm/trunk/include/llvm/Analysis/AssumptionTracker.h Sun Sep 7
> > 07:44:26 2014
> > @@ -0,0 +1,128 @@
> > +//===- llvm/Analysis/AssumptionTracker.h - Track @llvm.assume
> > ---*-
> > C++ -*-===//
> > +//
> > +// 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 (allowing assumptions within any
> > function to be
> > +// found cheaply by other parts of the optimizer).
> > +//
> > +//===----------------------------------------------------------------------===//
> > +
> > +#ifndef LLVM_ANALYSIS_ASSUMPTIONTRACKER_H
> > +#define LLVM_ANALYSIS_ASSUMPTIONTRACKER_H
> > +
> > +#include "llvm/ADT/DenseMap.h"
> > +#include "llvm/ADT/DenseSet.h"
> > +#include "llvm/ADT/SmallSet.h"
> > +#include "llvm/IR/Function.h"
> > +#include "llvm/IR/Instructions.h"
> > +#include "llvm/IR/ValueHandle.h"
> > +#include "llvm/Pass.h"
> > +#include <memory>
> > +
> > +namespace llvm {
> > +
> > +/// An immutable pass that tracks @llvm.assume intrinsics in a
> > module.
> > +class AssumptionTracker : public ImmutablePass {
> > + /// A callback value handle applied to function objects, which we
> > use to
> > + /// delete our cache of intrinsics for a function when it is
> > deleted.
> > + class FunctionCallbackVH : public CallbackVH {
> > + AssumptionTracker *AT;
> > + void deleted() override;
> > +
> > + public:
> > + typedef DenseMapInfo<Value *> DMI;
> > +
> > + FunctionCallbackVH(Value *V, AssumptionTracker *AT = nullptr)
> > + : CallbackVH(V), AT(AT) {}
> > + };
> > +
> > + /// A callback value handle applied to call instructions, which
> > keeps
> > + /// track of the call's parent function so that we can remove a
> > + /// assumption intrinsic call from our cache when the instruction
> > is
> > + /// deleted.
> > + class CallCallbackVH : public CallbackVH {
> > + AssumptionTracker *AT;
> > + void deleted() override;
> > +
> > + // We store the function here because we need it to lookup the
> > set
> > + // containing this handle when the underlying CallInst is being
> > deleted.
> > + Function *F;
> > +
> > + public:
> > + typedef DenseMapInfo<Instruction *> DMI;
> > +
> > + CallCallbackVH(Instruction *I, AssumptionTracker *AT = nullptr)
> > + : CallbackVH(I), AT(AT), F(nullptr) {
> > + if (I != DMI::getEmptyKey() && I != DMI::getTombstoneKey())
> > + F = I->getParent()->getParent();
> > + }
> > +
> > + operator CallInst*() const {
> > + Value *V = getValPtr();
> > + if (V == DMI::getEmptyKey() || V == DMI::getTombstoneKey())
> > + return static_cast<CallInst*>(V);
> > 
> > 
> > 
> > ^^ UBSan bootstrap bot reports undefined behavior here:
> > 
> > /home/dtoolsbot/build/sanitizer-x86_64-linux-bootstrap/build/llvm/include/llvm/Analysis/AssumptionTracker.h:69:18:
> > runtime error: downcast of misaligned address 0xfffffffffffffffc
> > for
> > type 'llvm::CallInst', which requires 8 byte alignment
> > 
> > (full log:
> > http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-bootstrap/builds/4491/steps/check-llvm%20ubsan/logs/stdio
> > )
> > 
> > 
> > The real problem is probably the fact that we don't enforce correct
> > alignment on EmptyKey and TombstoneKey in DenseMap<T*, foo>, but
> > it's not clear how to do this in the general case:
> > correct alignment of "fake pointers" of type T* depends on the
> > natural alignment of T, while the definition of T might not be
> > available.
> > 
> > 
> > Can you work around this problem somehow, and avoid bogus cast of
> > fake pointer here?
> 
> Interesting. Would using a reinterpret_cast fix the problem?
> 
> 
> 
> reinterpret_cast<> will make the tool silent (at least, in its
> current implementation). 5.2.10 [expr.reinterpret.cast], p. 7
> makes me think that the result of this reinterpret_cast<> is
> unspecified.

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.

 -Hal

> 
> 
> 
> -Hal
> 
> 
> 
> > 
> > 
> > 
> > 
> > +
> > + return cast<CallInst>(V);
> > + }
> > +
> > + CallInst *operator->() const { return
> > cast<CallInst>(getValPtr());
> > }
> > + CallInst &operator*() const { return
> > *cast<CallInst>(getValPtr());
> > }
> > + };
> > +
> > + friend FunctionCallbackVH;
> > + friend CallCallbackVH;
> > +
> > + // FIXME: SmallSet might be better here, but it currently has no
> > iterators.
> > + typedef DenseSet<CallCallbackVH, CallCallbackVH::DMI>
> > CallHandleSet;
> > + typedef DenseMap<FunctionCallbackVH,
> > std::unique_ptr<CallHandleSet>,
> > + FunctionCallbackVH::DMI> FunctionCallsMap;
> > + FunctionCallsMap CachedAssumeCalls;
> > +
> > + /// Scan the provided function for @llvm.assume intrinsic calls.
> > Returns an
> > + /// iterator to the set for this function in the
> > CachedAssumeCalls
> > map.
> > + FunctionCallsMap::iterator scanFunction(Function *F);
> > +
> > +public:
> > + /// Remove the cache of @llvm.assume intrinsics for the given
> > function.
> > + void forgetCachedAssumptions(Function *F);
> > +
> > + /// Add an @llvm.assume intrinsic to the cache for its parent
> > function.
> > + void registerAssumption(CallInst *CI);
> > +
> > + typedef CallHandleSet::iterator assumption_iterator;
> > + typedef iterator_range<assumption_iterator> assumption_range;
> > +
> > + inline assumption_range assumptions(Function *F) {
> > + FunctionCallsMap::iterator I = CachedAssumeCalls.find(F);
> > + if (I == CachedAssumeCalls.end()) {
> > + I = scanFunction(F);
> > + }
> > +
> > + return assumption_range(I->second->begin(), I->second->end());
> > + }
> > +
> > + AssumptionTracker();
> > + ~AssumptionTracker();
> > +
> > + void releaseMemory() override {
> > + CachedAssumeCalls.shrink_and_clear();
> > + }
> > +
> > + void verifyAnalysis() const override;
> > + bool doFinalization(Module &) override {
> > + verifyAnalysis();
> > + return false;
> > + }
> > +
> > + static char ID; // Pass identification, replacement for typeid
> > +};
> > +
> > +} // end namespace llvm
> > +
> > +#endif
> > 
> > Modified: llvm/trunk/include/llvm/InitializePasses.h
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=217334&r1=217333&r2=217334&view=diff
> > ==============================================================================
> > --- llvm/trunk/include/llvm/InitializePasses.h (original)
> > +++ llvm/trunk/include/llvm/InitializePasses.h Sun Sep 7 07:44:26
> > 2014
> > @@ -262,6 +262,7 @@ void initializeDataLayoutPassPass(PassRe
> > void initializeTargetTransformInfoAnalysisGroup(PassRegistry&);
> > void initializeNoTTIPass(PassRegistry&);
> > void initializeTargetLibraryInfoPass(PassRegistry&);
> > +void initializeAssumptionTrackerPass(PassRegistry &);
> > void initializeTwoAddressInstructionPassPass(PassRegistry&);
> > void initializeTypeBasedAliasAnalysisPass(PassRegistry&);
> > void initializeScopedNoAliasAAPass(PassRegistry&);
> > 
> > Modified: llvm/trunk/include/llvm/Transforms/Utils/Cloning.h
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Cloning.h?rev=217334&r1=217333&r2=217334&view=diff
> > ==============================================================================
> > --- llvm/trunk/include/llvm/Transforms/Utils/Cloning.h (original)
> > +++ llvm/trunk/include/llvm/Transforms/Utils/Cloning.h Sun Sep 7
> > 07:44:26 2014
> > @@ -44,6 +44,7 @@ class Loop;
> > class LoopInfo;
> > class AllocaInst;
> > class AliasAnalysis;
> > +class AssumptionTracker;
> > 
> > /// CloneModule - Return an exact copy of the specified module
> > ///
> > @@ -160,14 +161,16 @@ class InlineFunctionInfo {
> > public:
> > explicit InlineFunctionInfo(CallGraph *cg = nullptr,
> > const DataLayout *DL = nullptr,
> > - AliasAnalysis *AA = nullptr)
> > - : CG(cg), DL(DL), AA(AA) {}
> > + AliasAnalysis *AA = nullptr,
> > + AssumptionTracker *AT = nullptr)
> > + : CG(cg), DL(DL), AA(AA), AT(AT) {}
> > 
> > /// CG - If non-null, InlineFunction will update the callgraph to
> > reflect the
> > /// changes it makes.
> > CallGraph *CG;
> > const DataLayout *DL;
> > AliasAnalysis *AA;
> > + AssumptionTracker *AT;
> > 
> > /// StaticAllocas - InlineFunction fills this in with all static
> > allocas that
> > /// get copied into the caller.
> > 
> > Modified: llvm/trunk/include/llvm/Transforms/Utils/UnrollLoop.h
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/UnrollLoop.h?rev=217334&r1=217333&r2=217334&view=diff
> > ==============================================================================
> > --- llvm/trunk/include/llvm/Transforms/Utils/UnrollLoop.h
> > (original)
> > +++ llvm/trunk/include/llvm/Transforms/Utils/UnrollLoop.h Sun Sep 7
> > 07:44:26 2014
> > @@ -18,6 +18,7 @@
> > 
> > namespace llvm {
> > 
> > +class AssumptionTracker;
> > class Loop;
> > class LoopInfo;
> > class LPPassManager;
> > @@ -25,7 +26,7 @@ class Pass;
> > 
> > bool UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool
> > AllowRuntime,
> > unsigned TripMultiple, LoopInfo *LI, Pass *PP,
> > - LPPassManager *LPM);
> > + LPPassManager *LPM, AssumptionTracker *AT);
> > 
> > bool UnrollRuntimeLoopProlog(Loop *L, unsigned Count, LoopInfo *LI,
> > LPPassManager* LPM);
> > 
> > Added: llvm/trunk/lib/Analysis/AssumptionTracker.cpp
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/AssumptionTracker.cpp?rev=217334&view=auto
> > ==============================================================================
> > --- llvm/trunk/lib/Analysis/AssumptionTracker.cpp (added)
> > +++ llvm/trunk/lib/Analysis/AssumptionTracker.cpp Sun Sep 7
> > 07:44:26
> > 2014
> > @@ -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;
> > +
> > 
> > Modified: llvm/trunk/lib/Analysis/CMakeLists.txt
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CMakeLists.txt?rev=217334&r1=217333&r2=217334&view=diff
> > ==============================================================================
> > --- llvm/trunk/lib/Analysis/CMakeLists.txt (original)
> > +++ llvm/trunk/lib/Analysis/CMakeLists.txt Sun Sep 7 07:44:26 2014
> > @@ -5,6 +5,7 @@ add_llvm_library(LLVMAnalysis
> > AliasDebugger.cpp
> > AliasSetTracker.cpp
> > Analysis.cpp
> > + AssumptionTracker.cpp
> > BasicAliasAnalysis.cpp
> > BlockFrequencyInfo.cpp
> > BlockFrequencyInfoImpl.cpp
> > 
> > Modified: llvm/trunk/lib/Transforms/IPO/InlineAlways.cpp
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/InlineAlways.cpp?rev=217334&r1=217333&r2=217334&view=diff
> > ==============================================================================
> > --- llvm/trunk/lib/Transforms/IPO/InlineAlways.cpp (original)
> > +++ llvm/trunk/lib/Transforms/IPO/InlineAlways.cpp Sun Sep 7
> > 07:44:26
> > 2014
> > @@ -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",
> > 
> > Modified: llvm/trunk/lib/Transforms/IPO/InlineSimple.cpp
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/InlineSimple.cpp?rev=217334&r1=217333&r2=217334&view=diff
> > ==============================================================================
> > --- llvm/trunk/lib/Transforms/IPO/InlineSimple.cpp (original)
> > +++ llvm/trunk/lib/Transforms/IPO/InlineSimple.cpp Sun Sep 7
> > 07:44:26
> > 2014
> > @@ -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",
> > 
> > Modified: llvm/trunk/lib/Transforms/IPO/Inliner.cpp
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/Inliner.cpp?rev=217334&r1=217333&r2=217334&view=diff
> > ==============================================================================
> > --- llvm/trunk/lib/Transforms/IPO/Inliner.cpp (original)
> > +++ llvm/trunk/lib/Transforms/IPO/Inliner.cpp Sun Sep 7 07:44:26
> > 2014
> > @@ -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
> > /// 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(Functi
> > 
> > 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.
> > 
> > Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombine.h
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombine.h?rev=217334&r1=217333&r2=217334&view=diff
> > ==============================================================================
> > --- llvm/trunk/lib/Transforms/InstCombine/InstCombine.h (original)
> > +++ llvm/trunk/lib/Transforms/InstCombine/InstCombine.h Sun Sep 7
> > 07:44:26 2014
> > @@ -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
> > 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; }
> > 
> > Modified:
> > llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp?rev=217334&r1=217333&r2=217334&view=diff
> > ==============================================================================
> > --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
> > (original)
> > +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Sun
> > Sep 7 07:44:26 2014
> > @@ -996,6 +996,8 @@ Instruction *InstCombiner::visitCallInst
> > }
> > 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
> > }
> > // 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;
> > 
> > Modified:
> > llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp?rev=217334&r1=217333&r2=217334&view=diff
> > ==============================================================================
> > --- llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp
> > (original)
> > +++ llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp
> > Sun Sep 7 07:44:26 2014
> > @@ -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(LLVMPassR
> > 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(Functio
> > 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(Functio
> > /// 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);
> > 
> > Modified: llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp?rev=217334&r1=217333&r2=217334&view=diff
> > ==============================================================================
> > --- llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp (original)
> > +++ llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp Sun Sep 7
> > 07:44:26 2014
> > @@ -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, LPPa
> > 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, LPPa
> > }
> > 
> > // 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;
> > 
> > Modified: llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp?rev=217334&r1=217333&r2=217334&view=diff
> > ==============================================================================
> > --- llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp (original)
> > +++ llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp Sun Sep 7
> > 07:44:26 2014
> > @@ -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, LP
> > if (skipOptnoneFunction(L))
> > return false;
> > 
> > + AT = &getAnalysis<AssumptionTracker>();
> > LI = &getAnalysis<LoopInfo>();
> > LPM = &LPM_Ref;
> > DominatorTreeWrapperPass *DTWP =
> > @@ -823,6 +828,10 @@ void LoopUnswitch::UnswitchNontrivialCon
> > 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);
> > 
> > 
> > Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp?rev=217334&r1=217333&r2=217334&view=diff
> > ==============================================================================
> > --- llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp (original)
> > +++ llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Sun Sep 7
> > 07:44:26 2014
> > @@ -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, I
> > 
> > // 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
> > 
> > Modified: llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp?rev=217334&r1=217333&r2=217334&view=diff
> > ==============================================================================
> > --- llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp (original)
> > +++ llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp Sun Sep 7
> > 07:44:26
> > 2014
> > @@ -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,
> > /// 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
> > }
> > }
> > 
> > + // 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.
> > 
> > 
> > _______________________________________________
> > llvm-commits mailing list
> > llvm-commits at cs.uiuc.edu
> > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
> > 
> > 
> > 
> > 
> > --
> > 
> > Alexey Samsonov
> > vonosmas at gmail.com
> 
> --
> Hal Finkel
> Assistant Computational Scientist
> Leadership Computing Facility
> Argonne National Laboratory
> 
> 
> 
> 
> --
> 
> Alexey Samsonov
> vonosmas at gmail.com

-- 
Hal Finkel
Assistant Computational Scientist
Leadership Computing Facility
Argonne National Laboratory



More information about the llvm-commits mailing list