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