[llvm] r217334 - Add an Assumption-Tracking Pass

Alexey Samsonov vonosmas at gmail.com
Mon Sep 8 10:57:52 PDT 2014


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?



> +
> +        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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140908/6d5df9c4/attachment.html>


More information about the llvm-commits mailing list