[llvm] r243750 - [CaptureTracker] Provide an ordered basic block to PointerMayBeCapturedBefore

Kostya Serebryany via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 18 11:33:03 PDT 2015


On Fri, Sep 18, 2015 at 7:12 AM, Bruno Cardoso Lopes <
bruno.cardoso at gmail.com> wrote:

> Hi Kostya,
>
> Sorry for the delay, just got back from vacations.
> This is interesting. Did you measure compile time before the
> introduction of this functionality?
>

The compile time was horrible even before this change due to
https://llvm.org/bugs/show_bug.cgi?id=17409
It became worse and new hot functions have appeared, but now they are gone
again (17409 is still there)

Thanks!

--kcc

>
> Hard to tell offhand, but I would be happy to help if you can
> synthesise a testcase!
>




>
> On Mon, Aug 31, 2015 at 10:11 PM, Kostya Serebryany <kcc at google.com>
> wrote:
> > +llvm-commits at lists.llvm.org
> >
> > On Mon, Aug 31, 2015 at 6:08 PM, Kostya Serebryany <kcc at google.com>
> wrote:
> >>
> >> Hi Bruno,
> >>
> >> I have an input source file where this new functionality consumes
> >> almost half of compile time (~ 500 seconds out of total ~1000, which
> leads
> >> to compilation timeout)
> >> when compiled with -O2 -fsanitize=address.
> >>
> >> The profile looks like this:
> >> +  25.41%            clang  clang               [.]
> >> llvm::OrderedBasicBlock::comesBefore(llvm::Instruction const*,
> >> llvm::Instruction const*)
> >> +  12.13%            clang  clang               [.]
> >> llvm::DenseMapBase<llvm::SmallDenseMap<llvm::Instruction const*,
> unsigned
> >> int, 32u, llvm::DenseMapInfo<llvm::Instruction const*>, ll
> >> +   3.79%            clang  clang               [.]
> >> llvm::DenseMapBase<llvm::SmallDenseMap<llvm::Instruction const*,
> unsigned
> >> int, 32u, llvm::DenseMapInfo<llvm::Instruction const*>, llvm::detail:▒
> >>
> >> Is a substantially non-linear behavior expected here?
> >> Can the code be tuned to avoid it?
> >>
> >> Unfortunately, I can't provide the reproducer (at least, not easy),
> >> but I'd be happy to make experiments if you suggest any.
> >>
> >> Thanks,
> >>
> >> --kcc
> >>
> >>
> >> On Fri, Jul 31, 2015 at 7:31 AM, Bruno Cardoso Lopes
> >> <bruno.cardoso at gmail.com> wrote:
> >>>
> >>> Author: bruno
> >>> Date: Fri Jul 31 09:31:35 2015
> >>> New Revision: 243750
> >>>
> >>> URL: http://llvm.org/viewvc/llvm-project?rev=243750&view=rev
> >>> Log:
> >>> [CaptureTracker] Provide an ordered basic block to
> >>> PointerMayBeCapturedBefore
> >>>
> >>> This patch is a follow up from r240560 and is a step further into
> >>> mitigating the compile time performance issues in CaptureTracker.
> >>>
> >>> By providing the CaptureTracker with a "cached ordered basic block"
> >>> instead of computing it every time, MemDepAnalysis can use this cache
> >>> throughout its calls to AA->callCapturesBefore, avoiding to recompute
> it
> >>> for every scanned instruction. In the same testcase used in r240560,
> >>> compile time is reduced from 2min to 30s.
> >>>
> >>> This also fixes PR22348.
> >>>
> >>> rdar://problem/19230319
> >>> Differential Revision: http://reviews.llvm.org/D11364
> >>>
> >>> Added:
> >>>     llvm/trunk/include/llvm/Analysis/OrderedBasicBlock.h
> >>>     llvm/trunk/lib/Analysis/OrderedBasicBlock.cpp
> >>> Modified:
> >>>     llvm/trunk/include/llvm/Analysis/AliasAnalysis.h
> >>>     llvm/trunk/include/llvm/Analysis/CaptureTracking.h
> >>>     llvm/trunk/lib/Analysis/AliasAnalysis.cpp
> >>>     llvm/trunk/lib/Analysis/CMakeLists.txt
> >>>     llvm/trunk/lib/Analysis/CaptureTracking.cpp
> >>>     llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp
> >>>
> >>> Modified: llvm/trunk/include/llvm/Analysis/AliasAnalysis.h
> >>> URL:
> >>>
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/AliasAnalysis.h?rev=243750&r1=243749&r2=243750&view=diff
> >>>
> >>>
> ==============================================================================
> >>> --- llvm/trunk/include/llvm/Analysis/AliasAnalysis.h (original)
> >>> +++ llvm/trunk/include/llvm/Analysis/AliasAnalysis.h Fri Jul 31
> 09:31:35
> >>> 2015
> >>> @@ -55,6 +55,7 @@ class AnalysisUsage;
> >>>  class MemTransferInst;
> >>>  class MemIntrinsic;
> >>>  class DominatorTree;
> >>> +class OrderedBasicBlock;
> >>>
> >>>  /// The possible results of an alias query.
> >>>  ///
> >>> @@ -501,16 +502,19 @@ public:
> >>>    virtual ModRefInfo getModRefInfo(ImmutableCallSite CS1,
> >>>                                     ImmutableCallSite CS2);
> >>>
> >>> -  /// Return information about whether a particular call site modifies
> >>> or reads
> >>> -  /// the specified memory location.
> >>> +  /// \brief Return information about whether a particular call site
> >>> modifies
> >>> +  /// or reads the specified memory location \p MemLoc before
> >>> instruction \p I
> >>> +  /// in a BasicBlock. A ordered basic block \p OBB can be used to
> speed
> >>> up
> >>> +  /// instruction ordering queries inside the BasicBlock containing \p
> >>> I.
> >>>    ModRefInfo callCapturesBefore(const Instruction *I,
> >>> -                                const MemoryLocation &MemLoc,
> >>> -                                DominatorTree *DT);
> >>> +                                const MemoryLocation &MemLoc,
> >>> DominatorTree *DT,
> >>> +                                OrderedBasicBlock *OBB = nullptr);
> >>>
> >>> -  /// A convenience wrapper to synthesize a memory location.
> >>> +  /// \brief A convenience wrapper to synthesize a memory location.
> >>>    ModRefInfo callCapturesBefore(const Instruction *I, const Value *P,
> >>> -                                uint64_t Size, DominatorTree *DT) {
> >>> -    return callCapturesBefore(I, MemoryLocation(P, Size), DT);
> >>> +                                uint64_t Size, DominatorTree *DT,
> >>> +                                OrderedBasicBlock *OBB = nullptr) {
> >>> +    return callCapturesBefore(I, MemoryLocation(P, Size), DT, OBB);
> >>>    }
> >>>
> >>>    /// @}
> >>>
> >>> Modified: llvm/trunk/include/llvm/Analysis/CaptureTracking.h
> >>> URL:
> >>>
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/CaptureTracking.h?rev=243750&r1=243749&r2=243750&view=diff
> >>>
> >>>
> ==============================================================================
> >>> --- llvm/trunk/include/llvm/Analysis/CaptureTracking.h (original)
> >>> +++ llvm/trunk/include/llvm/Analysis/CaptureTracking.h Fri Jul 31
> >>> 09:31:35 2015
> >>> @@ -20,6 +20,7 @@ namespace llvm {
> >>>    class Use;
> >>>    class Instruction;
> >>>    class DominatorTree;
> >>> +  class OrderedBasicBlock;
> >>>
> >>>    /// PointerMayBeCaptured - Return true if this pointer value may be
> >>> captured
> >>>    /// by the enclosing function (which is required to exist).  This
> >>> routine can
> >>> @@ -41,10 +42,12 @@ namespace llvm {
> >>>    /// it or not.  The boolean StoreCaptures specified whether storing
> >>> the value
> >>>    /// (or part of it) into memory anywhere automatically counts as
> >>> capturing it
> >>>    /// or not. Captures by the provided instruction are considered if
> the
> >>> -  /// final parameter is true.
> >>> +  /// final parameter is true. An ordered basic block in \p OBB could
> be
> >>> used
> >>> +  /// to speed up capture-tracker queries.
> >>>    bool PointerMayBeCapturedBefore(const Value *V, bool ReturnCaptures,
> >>>                                    bool StoreCaptures, const
> Instruction
> >>> *I,
> >>> -                                  DominatorTree *DT, bool IncludeI =
> >>> false);
> >>> +                                  DominatorTree *DT, bool IncludeI =
> >>> false,
> >>> +                                  OrderedBasicBlock *OBB = nullptr);
> >>>
> >>>    /// This callback is used in conjunction with PointerMayBeCaptured.
> In
> >>>    /// addition to the interface here, you'll need to provide your own
> >>> getters
> >>>
> >>> Added: llvm/trunk/include/llvm/Analysis/OrderedBasicBlock.h
> >>> URL:
> >>>
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/OrderedBasicBlock.h?rev=243750&view=auto
> >>>
> >>>
> ==============================================================================
> >>> --- llvm/trunk/include/llvm/Analysis/OrderedBasicBlock.h (added)
> >>> +++ llvm/trunk/include/llvm/Analysis/OrderedBasicBlock.h Fri Jul 31
> >>> 09:31:35 2015
> >>> @@ -0,0 +1,66 @@
> >>> +//===- llvm/Analysis/OrderedBasicBlock.h --------------------- -*- C++
> >>> -*-===//
> >>> +//
> >>> +//                     The LLVM Compiler Infrastructure
> >>> +//
> >>> +// This file is distributed under the University of Illinois Open
> Source
> >>> +// License. See LICENSE.TXT for details.
> >>> +//
> >>>
> >>>
> +//===----------------------------------------------------------------------===//
> >>> +//
> >>> +// This file defines the OrderedBasicBlock class. OrderedBasicBlock
> >>> maintains
> >>> +// an interface where clients can query if one instruction comes
> before
> >>> another
> >>> +// in a BasicBlock. Since BasicBlock currently lacks a reliable way to
> >>> query
> >>> +// relative position between instructions one can use
> OrderedBasicBlock
> >>> to do
> >>> +// such queries. OrderedBasicBlock is lazily built on a source
> >>> BasicBlock and
> >>> +// maintains an internal Instruction -> Position map. A
> >>> OrderedBasicBlock
> >>> +// instance should be discarded whenever the source BasicBlock
> changes.
> >>> +//
> >>> +// It's currently used by the CaptureTracker in order to find relative
> >>> +// positions of a pair of instructions inside a BasicBlock.
> >>> +//
> >>>
> >>>
> +//===----------------------------------------------------------------------===//
> >>> +
> >>> +#ifndef LLVM_ANALYSIS_ORDEREDBASICBLOCK_H
> >>> +#define LLVM_ANALYSIS_ORDEREDBASICBLOCK_H
> >>> +
> >>> +#include "llvm/ADT/DenseMap.h"
> >>> +#include "llvm/IR/BasicBlock.h"
> >>> +
> >>> +namespace llvm {
> >>> +
> >>> +class Instruction;
> >>> +class BasicBlock;
> >>> +
> >>> +class OrderedBasicBlock {
> >>> +private:
> >>> +  /// \brief Map a instruction to its position in a BasicBlock.
> >>> +  SmallDenseMap<const Instruction *, unsigned, 32> NumberedInsts;
> >>> +
> >>> +  /// \brief Keep track of last instruction inserted into \p
> >>> NumberedInsts.
> >>> +  /// It speeds up queries for uncached instructions by providing a
> >>> start point
> >>> +  /// for new queries in OrderedBasicBlock::comesBefore.
> >>> +  BasicBlock::const_iterator LastInstFound;
> >>> +
> >>> +  /// \brief The position/number to tag the next instruction to be
> >>> found.
> >>> +  unsigned NextInstPos;
> >>> +
> >>> +  /// \brief The source BasicBlock to map.
> >>> +  const BasicBlock *BB;
> >>> +
> >>> +  /// \brief Given no cached results, find if \p A comes before \p B
> in
> >>> \p BB.
> >>> +  /// Cache and number out instruction while walking \p BB.
> >>> +  bool comesBefore(const Instruction *A, const Instruction *B);
> >>> +
> >>> +public:
> >>> +  OrderedBasicBlock(const BasicBlock *BasicB);
> >>> +
> >>> +  /// \brief Find out whether \p A dominates \p B, meaning whether \p
> A
> >>> +  /// comes before \p B in \p BB. This is a simplification that
> >>> considers
> >>> +  /// cached instruction positions and ignores other basic blocks,
> being
> >>> +  /// only relevant to compare relative instructions positions inside
> \p
> >>> BB.
> >>> +  bool dominates(const Instruction *A, const Instruction *B);
> >>> +};
> >>> +
> >>> +} // End llvm namespace
> >>> +
> >>> +#endif
> >>>
> >>> Modified: llvm/trunk/lib/Analysis/AliasAnalysis.cpp
> >>> URL:
> >>>
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/AliasAnalysis.cpp?rev=243750&r1=243749&r2=243750&view=diff
> >>>
> >>>
> ==============================================================================
> >>> --- llvm/trunk/lib/Analysis/AliasAnalysis.cpp (original)
> >>> +++ llvm/trunk/lib/Analysis/AliasAnalysis.cpp Fri Jul 31 09:31:35 2015
> >>> @@ -335,13 +335,18 @@ ModRefInfo AliasAnalysis::getModRefInfo(
> >>>    return MRI_ModRef;
> >>>  }
> >>>
> >>> -// FIXME: this is really just shoring-up a deficiency in alias
> analysis.
> >>> -// BasicAA isn't willing to spend linear time determining whether an
> >>> alloca
> >>> -// was captured before or after this particular call, while we are.
> >>> However,
> >>> -// with a smarter AA in place, this test is just wasting compile time.
> >>> +/// \brief Return information about whether a particular call site
> >>> modifies
> >>> +/// or reads the specified memory location \p MemLoc before
> instruction
> >>> \p I
> >>> +/// in a BasicBlock. A ordered basic block \p OBB can be used to speed
> >>> up
> >>> +/// instruction-ordering queries inside the BasicBlock containing \p
> I.
> >>> +/// FIXME: this is really just shoring-up a deficiency in alias
> >>> analysis.
> >>> +/// BasicAA isn't willing to spend linear time determining whether an
> >>> alloca
> >>> +/// was captured before or after this particular call, while we are.
> >>> However,
> >>> +/// with a smarter AA in place, this test is just wasting compile
> time.
> >>>  ModRefInfo AliasAnalysis::callCapturesBefore(const Instruction *I,
> >>>                                               const MemoryLocation
> >>> &MemLoc,
> >>> -                                             DominatorTree *DT) {
> >>> +                                             DominatorTree *DT,
> >>> +                                             OrderedBasicBlock *OBB) {
> >>>    if (!DT)
> >>>      return MRI_ModRef;
> >>>
> >>> @@ -356,7 +361,8 @@ ModRefInfo AliasAnalysis::callCapturesBe
> >>>
> >>>    if (llvm::PointerMayBeCapturedBefore(Object, /* ReturnCaptures */
> >>> true,
> >>>                                         /* StoreCaptures */ true, I,
> DT,
> >>> -                                       /* include Object */ true))
> >>> +                                       /* include Object */ true,
> >>> +                                       /* OrderedBasicBlock */ OBB))
> >>>      return MRI_ModRef;
> >>>
> >>>    unsigned ArgNo = 0;
> >>>
> >>> Modified: llvm/trunk/lib/Analysis/CMakeLists.txt
> >>> URL:
> >>>
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CMakeLists.txt?rev=243750&r1=243749&r2=243750&view=diff
> >>>
> >>>
> ==============================================================================
> >>> --- llvm/trunk/lib/Analysis/CMakeLists.txt (original)
> >>> +++ llvm/trunk/lib/Analysis/CMakeLists.txt Fri Jul 31 09:31:35 2015
> >>> @@ -45,6 +45,7 @@ add_llvm_library(LLVMAnalysis
> >>>    MemoryLocation.cpp
> >>>    ModuleDebugInfoPrinter.cpp
> >>>    NoAliasAnalysis.cpp
> >>> +  OrderedBasicBlock.cpp
> >>>    PHITransAddr.cpp
> >>>    PostDominators.cpp
> >>>    PtrUseVisitor.cpp
> >>>
> >>> Modified: llvm/trunk/lib/Analysis/CaptureTracking.cpp
> >>> URL:
> >>>
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CaptureTracking.cpp?rev=243750&r1=243749&r2=243750&view=diff
> >>>
> >>>
> ==============================================================================
> >>> --- llvm/trunk/lib/Analysis/CaptureTracking.cpp (original)
> >>> +++ llvm/trunk/lib/Analysis/CaptureTracking.cpp Fri Jul 31 09:31:35
> 2015
> >>> @@ -21,6 +21,7 @@
> >>>  #include "llvm/Analysis/AliasAnalysis.h"
> >>>  #include "llvm/Analysis/CFG.h"
> >>>  #include "llvm/Analysis/CaptureTracking.h"
> >>> +#include "llvm/Analysis/OrderedBasicBlock.h"
> >>>  #include "llvm/IR/CallSite.h"
> >>>  #include "llvm/IR/Constants.h"
> >>>  #include "llvm/IR/Dominators.h"
> >>> @@ -52,63 +53,6 @@ namespace {
> >>>      bool Captured;
> >>>    };
> >>>
> >>> -  struct NumberedInstCache {
> >>> -    SmallDenseMap<const Instruction *, unsigned, 32> NumberedInsts;
> >>> -    BasicBlock::const_iterator LastInstFound;
> >>> -    unsigned LastInstPos;
> >>> -    const BasicBlock *BB;
> >>> -
> >>> -    NumberedInstCache(const BasicBlock *BasicB) : LastInstPos(0),
> >>> BB(BasicB) {
> >>> -      LastInstFound = BB->end();
> >>> -    }
> >>> -
> >>> -    /// \brief Find the first instruction 'A' or 'B' in 'BB'. Number
> out
> >>> -    /// instruction while walking 'BB'.
> >>> -    const Instruction *find(const Instruction *A, const Instruction
> *B)
> >>> {
> >>> -      const Instruction *Inst = nullptr;
> >>> -      assert(!(LastInstFound == BB->end() && LastInstPos != 0) &&
> >>> -             "Instruction supposed to be in NumberedInsts");
> >>> -
> >>> -      // Start the search with the instruction found in the last
> lookup
> >>> round.
> >>> -      auto II = BB->begin();
> >>> -      auto IE = BB->end();
> >>> -      if (LastInstFound != IE)
> >>> -        II = std::next(LastInstFound);
> >>> -
> >>> -      // Number all instructions up to the point where we find 'A' or
> >>> 'B'.
> >>> -      for (++LastInstPos; II != IE; ++II, ++LastInstPos) {
> >>> -        Inst = cast<Instruction>(II);
> >>> -        NumberedInsts[Inst] = LastInstPos;
> >>> -        if (Inst == A || Inst == B)
> >>> -          break;
> >>> -      }
> >>> -
> >>> -      assert(II != IE && "Instruction not found?");
> >>> -      LastInstFound = II;
> >>> -      return Inst;
> >>> -    }
> >>> -
> >>> -    /// \brief Find out whether 'A' dominates 'B', meaning whether 'A'
> >>> -    /// comes before 'B' in 'BB'. This is a simplification that
> >>> considers
> >>> -    /// cached instruction positions and ignores other basic blocks,
> >>> being
> >>> -    /// only relevant to compare relative instructions positions
> inside
> >>> 'BB'.
> >>> -    bool dominates(const Instruction *A, const Instruction *B) {
> >>> -      assert(A->getParent() == B->getParent() &&
> >>> -             "Instructions must be in the same basic block!");
> >>> -
> >>> -      unsigned NA = NumberedInsts.lookup(A);
> >>> -      unsigned NB = NumberedInsts.lookup(B);
> >>> -      if (NA && NB)
> >>> -        return NA < NB;
> >>> -      if (NA)
> >>> -        return true;
> >>> -      if (NB)
> >>> -        return false;
> >>> -
> >>> -      return A == find(A, B);
> >>> -    }
> >>> -  };
> >>> -
> >>>    /// Only find pointer captures which happen before the given
> >>> instruction. Uses
> >>>    /// the dominator tree to determine whether one instruction is
> before
> >>> another.
> >>>    /// Only support the case where the Value is defined in the same
> basic
> >>> block
> >>> @@ -116,8 +60,8 @@ namespace {
> >>>    struct CapturesBefore : public CaptureTracker {
> >>>
> >>>      CapturesBefore(bool ReturnCaptures, const Instruction *I,
> >>> DominatorTree *DT,
> >>> -                   bool IncludeI)
> >>> -      : LocalInstCache(I->getParent()), BeforeHere(I), DT(DT),
> >>> +                   bool IncludeI, OrderedBasicBlock *IC)
> >>> +      : OrderedBB(IC), BeforeHere(I), DT(DT),
> >>>          ReturnCaptures(ReturnCaptures), IncludeI(IncludeI),
> >>> Captured(false) {}
> >>>
> >>>      void tooManyUses() override { Captured = true; }
> >>> @@ -131,7 +75,7 @@ namespace {
> >>>
> >>>        // Compute the case where both instructions are inside the same
> >>> basic
> >>>        // block. Since instructions in the same BB as BeforeHere are
> >>> numbered in
> >>> -      // 'LocalInstCache', avoid using 'dominates' and
> >>> 'isPotentiallyReachable'
> >>> +      // 'OrderedBB', avoid using 'dominates' and
> >>> 'isPotentiallyReachable'
> >>>        // which are very expensive for large basic blocks.
> >>>        if (BB == BeforeHere->getParent()) {
> >>>          // 'I' dominates 'BeforeHere' => not safe to prune.
> >>> @@ -142,7 +86,7 @@ namespace {
> >>>          // UseBB == BB, avoid pruning.
> >>>          if (isa<InvokeInst>(BeforeHere) || isa<PHINode>(I) || I ==
> >>> BeforeHere)
> >>>            return false;
> >>> -        if (!LocalInstCache.dominates(BeforeHere, I))
> >>> +        if (!OrderedBB->dominates(BeforeHere, I))
> >>>            return false;
> >>>
> >>>          // 'BeforeHere' comes before 'I', it's safe to prune if we
> also
> >>> @@ -196,7 +140,7 @@ namespace {
> >>>        return true;
> >>>      }
> >>>
> >>> -    NumberedInstCache LocalInstCache;
> >>> +    OrderedBasicBlock *OrderedBB;
> >>>      const Instruction *BeforeHere;
> >>>      DominatorTree *DT;
> >>>
> >>> @@ -238,21 +182,29 @@ bool llvm::PointerMayBeCaptured(const Va
> >>>  /// returning the value (or part of it) from the function counts as
> >>> capturing
> >>>  /// it or not.  The boolean StoreCaptures specified whether storing
> the
> >>> value
> >>>  /// (or part of it) into memory anywhere automatically counts as
> >>> capturing it
> >>> -/// or not.
> >>> +/// or not. A ordered basic block \p OBB can be used in order to speed
> >>> up
> >>> +/// queries about relative order among instructions in the same basic
> >>> block.
> >>>  bool llvm::PointerMayBeCapturedBefore(const Value *V, bool
> >>> ReturnCaptures,
> >>>                                        bool StoreCaptures, const
> >>> Instruction *I,
> >>> -                                      DominatorTree *DT, bool
> IncludeI)
> >>> {
> >>> +                                      DominatorTree *DT, bool
> IncludeI,
> >>> +                                      OrderedBasicBlock *OBB) {
> >>>    assert(!isa<GlobalValue>(V) &&
> >>>           "It doesn't make sense to ask whether a global is
> captured.");
> >>> +  bool UseNewOBB = OBB == nullptr;
> >>>
> >>>    if (!DT)
> >>>      return PointerMayBeCaptured(V, ReturnCaptures, StoreCaptures);
> >>> +  if (UseNewOBB)
> >>> +    OBB = new OrderedBasicBlock(I->getParent());
> >>>
> >>>    // TODO: See comment in PointerMayBeCaptured regarding what could be
> >>> done
> >>>    // with StoreCaptures.
> >>>
> >>> -  CapturesBefore CB(ReturnCaptures, I, DT, IncludeI);
> >>> +  CapturesBefore CB(ReturnCaptures, I, DT, IncludeI, OBB);
> >>>    PointerMayBeCaptured(V, &CB);
> >>> +
> >>> +  if (UseNewOBB)
> >>> +    delete OBB;
> >>>    return CB.Captured;
> >>>  }
> >>>
> >>>
> >>> Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp
> >>> URL:
> >>>
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=243750&r1=243749&r2=243750&view=diff
> >>>
> >>>
> ==============================================================================
> >>> --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original)
> >>> +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Fri Jul 31
> >>> 09:31:35 2015
> >>> @@ -22,6 +22,7 @@
> >>>  #include "llvm/Analysis/InstructionSimplify.h"
> >>>  #include "llvm/Analysis/MemoryBuiltins.h"
> >>>  #include "llvm/Analysis/PHITransAddr.h"
> >>> +#include "llvm/Analysis/OrderedBasicBlock.h"
> >>>  #include "llvm/Analysis/ValueTracking.h"
> >>>  #include "llvm/IR/DataLayout.h"
> >>>  #include "llvm/IR/Dominators.h"
> >>> @@ -420,6 +421,12 @@ MemDepResult MemoryDependenceAnalysis::g
> >>>
> >>>    const DataLayout &DL = BB->getModule()->getDataLayout();
> >>>
> >>> +  // Create a numbered basic block to lazily compute and cache
> >>> instruction
> >>> +  // positions inside a BB. This is used to provide fast queries for
> >>> relative
> >>> +  // position between two instructions in a BB and can be used by
> >>> +  // AliasAnalysis::callCapturesBefore.
> >>> +  OrderedBasicBlock OBB(BB);
> >>> +
> >>>    // Walk backwards through the basic block, looking for dependencies.
> >>>    while (ScanIt != BB->begin()) {
> >>>      Instruction *Inst = --ScanIt;
> >>> @@ -623,7 +630,7 @@ MemDepResult MemoryDependenceAnalysis::g
> >>>      ModRefInfo MR = AA->getModRefInfo(Inst, MemLoc);
> >>>      // If necessary, perform additional analysis.
> >>>      if (MR == MRI_ModRef)
> >>> -      MR = AA->callCapturesBefore(Inst, MemLoc, DT);
> >>> +      MR = AA->callCapturesBefore(Inst, MemLoc, DT, &OBB);
> >>>      switch (MR) {
> >>>      case MRI_NoModRef:
> >>>        // If the call has no effect on the queried pointer, just ignore
> >>> it.
> >>>
> >>> Added: llvm/trunk/lib/Analysis/OrderedBasicBlock.cpp
> >>> URL:
> >>>
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/OrderedBasicBlock.cpp?rev=243750&view=auto
> >>>
> >>>
> ==============================================================================
> >>> --- llvm/trunk/lib/Analysis/OrderedBasicBlock.cpp (added)
> >>> +++ llvm/trunk/lib/Analysis/OrderedBasicBlock.cpp Fri Jul 31 09:31:35
> >>> 2015
> >>> @@ -0,0 +1,85 @@
> >>> +//===- OrderedBasicBlock.cpp --------------------------------- -*- C++
> >>> -*-===//
> >>> +//
> >>> +//                     The LLVM Compiler Infrastructure
> >>> +//
> >>> +// This file is distributed under the University of Illinois Open
> Source
> >>> +// License. See LICENSE.TXT for details.
> >>> +//
> >>>
> >>>
> +//===----------------------------------------------------------------------===//
> >>> +//
> >>> +// This file implements the OrderedBasicBlock class. OrderedBasicBlock
> >>> +// maintains an interface where clients can query if one instruction
> >>> comes
> >>> +// before another in a BasicBlock. Since BasicBlock currently lacks a
> >>> reliable
> >>> +// way to query relative position between instructions one can use
> >>> +// OrderedBasicBlock to do such queries. OrderedBasicBlock is lazily
> >>> built on a
> >>> +// source BasicBlock and maintains an internal Instruction -> Position
> >>> map. A
> >>> +// OrderedBasicBlock instance should be discarded whenever the source
> >>> +// BasicBlock changes.
> >>> +//
> >>> +// It's currently used by the CaptureTracker in order to find relative
> >>> +// positions of a pair of instructions inside a BasicBlock.
> >>> +//
> >>>
> >>>
> +//===----------------------------------------------------------------------===//
> >>> +
> >>> +#include "llvm/Analysis/OrderedBasicBlock.h"
> >>> +#include "llvm/IR/Instruction.h"
> >>> +using namespace llvm;
> >>> +
> >>> +OrderedBasicBlock::OrderedBasicBlock(const BasicBlock *BasicB)
> >>> +    : NextInstPos(0), BB(BasicB) {
> >>> +  LastInstFound = BB->end();
> >>> +}
> >>> +
> >>> +/// \brief Given no cached results, find if \p A comes before \p B in
> \p
> >>> BB.
> >>> +/// Cache and number out instruction while walking \p BB.
> >>> +bool OrderedBasicBlock::comesBefore(const Instruction *A,
> >>> +                                    const Instruction *B) {
> >>> +  const Instruction *Inst = nullptr;
> >>> +  assert(!(LastInstFound == BB->end() && NextInstPos != 0) &&
> >>> +         "Instruction supposed to be in NumberedInsts");
> >>> +
> >>> +  // Start the search with the instruction found in the last lookup
> >>> round.
> >>> +  auto II = BB->begin();
> >>> +  auto IE = BB->end();
> >>> +  if (LastInstFound != IE)
> >>> +    II = std::next(LastInstFound);
> >>> +
> >>> +  // Number all instructions up to the point where we find 'A' or 'B'.
> >>> +  for (; II != IE; ++II) {
> >>> +    Inst = cast<Instruction>(II);
> >>> +    NumberedInsts[Inst] = NextInstPos++;
> >>> +    if (Inst == A || Inst == B)
> >>> +      break;
> >>> +  }
> >>> +
> >>> +  assert(II != IE && "Instruction not found?");
> >>> +  assert((Inst == A || Inst == B) && "Should find A or B");
> >>> +  LastInstFound = II;
> >>> +  return Inst == A;
> >>> +}
> >>> +
> >>> +/// \brief Find out whether \p A dominates \p B, meaning whether \p A
> >>> +/// comes before \p B in \p BB. This is a simplification that
> considers
> >>> +/// cached instruction positions and ignores other basic blocks, being
> >>> +/// only relevant to compare relative instructions positions inside \p
> >>> BB.
> >>> +bool OrderedBasicBlock::dominates(const Instruction *A, const
> >>> Instruction *B) {
> >>> +  assert(A->getParent() == B->getParent() &&
> >>> +         "Instructions must be in the same basic block!");
> >>> +
> >>> +  // First we lookup the instructions. If they don't exist, lookup
> will
> >>> give us
> >>> +  // back ::end(). If they both exist, we compare the numbers.
> >>> Otherwise, if NA
> >>> +  // exists and NB doesn't, it means NA must come before NB because we
> >>> would
> >>> +  // have numbered NB as well if it didn't. The same is true for NB.
> If
> >>> it
> >>> +  // exists, but NA does not, NA must come after it. If neither exist,
> >>> we need
> >>> +  // to number the block and cache the results (by calling
> comesBefore).
> >>> +  auto NAI = NumberedInsts.find(A);
> >>> +  auto NBI = NumberedInsts.find(B);
> >>> +  if (NAI != NumberedInsts.end() && NBI != NumberedInsts.end())
> >>> +    return NAI->second < NBI->second;
> >>> +  if (NAI != NumberedInsts.end())
> >>> +    return true;
> >>> +  if (NBI != NumberedInsts.end())
> >>> +    return false;
> >>> +
> >>> +  return comesBefore(A, B);
> >>> +}
> >>>
> >>>
> >>> _______________________________________________
> >>> llvm-commits mailing list
> >>> llvm-commits at cs.uiuc.edu
> >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
> >>
> >>
> >
>
>
>
> --
> Bruno Cardoso Lopes
> http://www.brunocardoso.cc
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150918/bd958cde/attachment.html>


More information about the llvm-commits mailing list