<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Sep 18, 2015 at 7:12 AM, Bruno Cardoso Lopes <span dir="ltr"><<a href="mailto:bruno.cardoso@gmail.com" target="_blank" onclick="window.open('https://mail.google.com/mail/?view=cm&tf=1&to=bruno.cardoso@gmail.com&cc=&bcc=&su=&body=','_blank');return false;">bruno.cardoso@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Hi Kostya,<br>
<br>
Sorry for the delay, just got back from vacations.<br>
This is interesting. Did you measure compile time before the<br>
introduction of this functionality?<br></blockquote><div><br></div><div>The compile time was horrible even before this change due to <a href="https://llvm.org/bugs/show_bug.cgi?id=17409">https://llvm.org/bugs/show_bug.cgi?id=17409</a></div><div>It became worse and new hot functions have appeared, but now they are gone again (17409 is still there) </div><div><br></div><div>Thanks! </div><div><br></div><div>--kcc </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<br>
Hard to tell offhand, but I would be happy to help if you can<br>
synthesise a testcase!<br></blockquote><div><br></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div><div><br>
On Mon, Aug 31, 2015 at 10:11 PM, Kostya Serebryany <<a href="mailto:kcc@google.com" target="_blank" onclick="window.open('https://mail.google.com/mail/?view=cm&tf=1&to=kcc@google.com&cc=&bcc=&su=&body=','_blank');return false;">kcc@google.com</a>> wrote:<br>
> +<a href="mailto:llvm-commits@lists.llvm.org" target="_blank" onclick="window.open('https://mail.google.com/mail/?view=cm&tf=1&to=llvm-commits@lists.llvm.org&cc=&bcc=&su=&body=','_blank');return false;">llvm-commits@lists.llvm.org</a><br>
><br>
> On Mon, Aug 31, 2015 at 6:08 PM, Kostya Serebryany <<a href="mailto:kcc@google.com" target="_blank" onclick="window.open('https://mail.google.com/mail/?view=cm&tf=1&to=kcc@google.com&cc=&bcc=&su=&body=','_blank');return false;">kcc@google.com</a>> wrote:<br>
>><br>
>> Hi Bruno,<br>
>><br>
>> I have an input source file where this new functionality consumes<br>
>> almost half of compile time (~ 500 seconds out of total ~1000, which leads<br>
>> to compilation timeout)<br>
>> when compiled with -O2 -fsanitize=address.<br>
>><br>
>> The profile looks like this:<br>
>> +  25.41%  Â  Â  Â  Â  Â  clang  clang  Â  Â  Â  Â  Â  Â  Â [.]<br>
>> llvm::OrderedBasicBlock::comesBefore(llvm::Instruction const*,<br>
>> llvm::Instruction const*)<br>
>> +  12.13%  Â  Â  Â  Â  Â  clang  clang  Â  Â  Â  Â  Â  Â  Â [.]<br>
>> llvm::DenseMapBase<llvm::SmallDenseMap<llvm::Instruction const*, unsigned<br>
>> int, 32u, llvm::DenseMapInfo<llvm::Instruction const*>, ll<br>
>> +  Â 3.79%  Â  Â  Â  Â  Â  clang  clang  Â  Â  Â  Â  Â  Â  Â [.]<br>
>> llvm::DenseMapBase<llvm::SmallDenseMap<llvm::Instruction const*, unsigned<br>
>> int, 32u, llvm::DenseMapInfo<llvm::Instruction const*>, llvm::detail:â–’<br>
>><br>
>> Is a substantially non-linear behavior expected here?<br>
>> Can the code be tuned to avoid it?<br>
>><br>
>> Unfortunately, I can't provide the reproducer (at least, not easy),<br>
>> but I'd be happy to make experiments if you suggest any.<br>
>><br>
>> Thanks,<br>
>><br>
>> --kcc<br>
>><br>
>><br>
>> On Fri, Jul 31, 2015 at 7:31 AM, Bruno Cardoso Lopes<br>
>> <<a href="mailto:bruno.cardoso@gmail.com" target="_blank" onclick="window.open('https://mail.google.com/mail/?view=cm&tf=1&to=bruno.cardoso@gmail.com&cc=&bcc=&su=&body=','_blank');return false;">bruno.cardoso@gmail.com</a>> wrote:<br>
>>><br>
>>> 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<br>
>>> 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:<br>
>>> <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>
>>> ==============================================================================<br>
>>> --- llvm/trunk/include/llvm/Analysis/AliasAnalysis.h (original)<br>
>>> +++ llvm/trunk/include/llvm/Analysis/AliasAnalysis.h Fri Jul 31 09:31:35<br>
>>> 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<br>
>>> or reads<br>
>>> -  /// the specified memory location.<br>
>>> +  /// \brief Return information about whether a particular call site<br>
>>> modifies<br>
>>> +  /// or reads the specified memory location \p MemLoc before<br>
>>> instruction \p I<br>
>>> +  /// in a BasicBlock. A ordered basic block \p OBB can be used to speed<br>
>>> up<br>
>>> +  /// instruction ordering queries inside the BasicBlock containing \p<br>
>>> I.<br>
>>>  Â  ModRefInfo callCapturesBefore(const Instruction *I,<br>
>>> -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  const MemoryLocation &MemLoc,<br>
>>> -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  DominatorTree *DT);<br>
>>> +  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  const MemoryLocation &MemLoc,<br>
>>> 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:<br>
>>> <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>
>>> ==============================================================================<br>
>>> --- llvm/trunk/include/llvm/Analysis/CaptureTracking.h (original)<br>
>>> +++ llvm/trunk/include/llvm/Analysis/CaptureTracking.h Fri Jul 31<br>
>>> 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<br>
>>> captured<br>
>>>  Â  /// by the enclosing function (which is required to exist).  This<br>
>>> routine can<br>
>>> @@ -41,10 +42,12 @@ namespace llvm {<br>
>>>  Â  /// it or not.  The boolean StoreCaptures specified whether storing<br>
>>> the value<br>
>>>  Â  /// (or part of it) into memory anywhere automatically counts as<br>
>>> 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<br>
>>> used<br>
>>> +  /// to speed up capture-tracker queries.<br>
>>>  Â  bool PointerMayBeCapturedBefore(const Value *V, bool ReturnCaptures,<br>
>>>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  bool StoreCaptures, const Instruction<br>
>>> *I,<br>
>>> -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  DominatorTree *DT, bool IncludeI =<br>
>>> false);<br>
>>> +  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  DominatorTree *DT, bool IncludeI =<br>
>>> 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<br>
>>> getters<br>
>>><br>
>>> Added: llvm/trunk/include/llvm/Analysis/OrderedBasicBlock.h<br>
>>> URL:<br>
>>> <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>
>>> ==============================================================================<br>
>>> --- llvm/trunk/include/llvm/Analysis/OrderedBasicBlock.h (added)<br>
>>> +++ llvm/trunk/include/llvm/Analysis/OrderedBasicBlock.h Fri Jul 31<br>
>>> 09:31:35 2015<br>
>>> @@ -0,0 +1,66 @@<br>
>>> +//===- llvm/Analysis/OrderedBasicBlock.h --------------------- -*- C++<br>
>>> -*-===//<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>
>>> +//<br>
>>> +// This file defines the OrderedBasicBlock class. OrderedBasicBlock<br>
>>> maintains<br>
>>> +// an interface where clients can query if one instruction comes before<br>
>>> another<br>
>>> +// in a BasicBlock. Since BasicBlock currently lacks a reliable way to<br>
>>> query<br>
>>> +// relative position between instructions one can use OrderedBasicBlock<br>
>>> to do<br>
>>> +// such queries. OrderedBasicBlock is lazily built on a source<br>
>>> BasicBlock and<br>
>>> +// maintains an internal Instruction -> Position map. A<br>
>>> 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>
>>> +<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<br>
>>> NumberedInsts.<br>
>>> +  /// It speeds up queries for uncached instructions by providing a<br>
>>> 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<br>
>>> 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<br>
>>> \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<br>
>>> considers<br>
>>> +  /// cached instruction positions and ignores other basic blocks, being<br>
>>> +  /// only relevant to compare relative instructions positions inside \p<br>
>>> 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:<br>
>>> <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>
>>> ==============================================================================<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<br>
>>> alloca<br>
>>> -// was captured before or after this particular call, while we are.<br>
>>> 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<br>
>>> modifies<br>
>>> +/// or reads the specified memory location \p MemLoc before instruction<br>
>>> \p I<br>
>>> +/// in a BasicBlock. A ordered basic block \p OBB can be used to speed<br>
>>> up<br>
>>> +/// instruction-ordering queries inside the BasicBlock containing \p I.<br>
>>> +/// FIXME: this is really just shoring-up a deficiency in alias<br>
>>> analysis.<br>
>>> +/// BasicAA isn't willing to spend linear time determining whether an<br>
>>> alloca<br>
>>> +/// was captured before or after this particular call, while we are.<br>
>>> 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<br>
>>> &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 */<br>
>>> 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:<br>
>>> <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>
>>> ==============================================================================<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:<br>
>>> <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>
>>> ==============================================================================<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),<br>
>>> 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>
>>> {<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<br>
>>> 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<br>
>>> '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<br>
>>> considers<br>
>>> -  Â  /// cached instruction positions and ignores other basic blocks,<br>
>>> being<br>
>>> -  Â  /// only relevant to compare relative instructions positions inside<br>
>>> '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<br>
>>> instruction. Uses<br>
>>>  Â  /// the dominator tree to determine whether one instruction is before<br>
>>> another.<br>
>>>  Â  /// Only support the case where the Value is defined in the same basic<br>
>>> block<br>
>>> @@ -116,8 +60,8 @@ namespace {<br>
>>>  Â  struct CapturesBefore : public CaptureTracker {<br>
>>><br>
>>>  Â  Â  CapturesBefore(bool ReturnCaptures, const Instruction *I,<br>
>>> 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),<br>
>>> 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<br>
>>> basic<br>
>>>  Â  Â  Â  // block. Since instructions in the same BB as BeforeHere are<br>
>>> numbered in<br>
>>> -  Â  Â  // 'LocalInstCache', avoid using 'dominates' and<br>
>>> 'isPotentiallyReachable'<br>
>>> +  Â  Â  // 'OrderedBB', avoid using 'dominates' and<br>
>>> '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 ==<br>
>>> 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<br>
>>> capturing<br>
>>>  /// it or not.  The boolean StoreCaptures specified whether storing the<br>
>>> value<br>
>>>  /// (or part of it) into memory anywhere automatically counts as<br>
>>> capturing it<br>
>>> -/// or not.<br>
>>> +/// or not. A ordered basic block \p OBB can be used in order to speed<br>
>>> up<br>
>>> +/// queries about relative order among instructions in the same basic<br>
>>> block.<br>
>>>  bool llvm::PointerMayBeCapturedBefore(const Value *V, bool<br>
>>> ReturnCaptures,<br>
>>>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  bool StoreCaptures, const<br>
>>> Instruction *I,<br>
>>> -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  DominatorTree *DT, bool IncludeI)<br>
>>> {<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<br>
>>> 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:<br>
>>> <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>
>>> ==============================================================================<br>
>>> --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original)<br>
>>> +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Fri Jul 31<br>
>>> 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<br>
>>> instruction<br>
>>> +  // positions inside a BB. This is used to provide fast queries for<br>
>>> 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<br>
>>> it.<br>
>>><br>
>>> Added: llvm/trunk/lib/Analysis/OrderedBasicBlock.cpp<br>
>>> URL:<br>
>>> <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>
>>> ==============================================================================<br>
>>> --- llvm/trunk/lib/Analysis/OrderedBasicBlock.cpp (added)<br>
>>> +++ llvm/trunk/lib/Analysis/OrderedBasicBlock.cpp Fri Jul 31 09:31:35<br>
>>> 2015<br>
>>> @@ -0,0 +1,85 @@<br>
>>> +//===- OrderedBasicBlock.cpp --------------------------------- -*- C++<br>
>>> -*-===//<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>
>>> +//<br>
>>> +// This file implements the OrderedBasicBlock class. OrderedBasicBlock<br>
>>> +// maintains an interface where clients can query if one instruction<br>
>>> comes<br>
>>> +// before another in a BasicBlock. Since BasicBlock currently lacks a<br>
>>> reliable<br>
>>> +// way to query relative position between instructions one can use<br>
>>> +// OrderedBasicBlock to do such queries. OrderedBasicBlock is lazily<br>
>>> built on a<br>
>>> +// source BasicBlock and maintains an internal Instruction -> Position<br>
>>> 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>
>>> +<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<br>
>>> 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<br>
>>> 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<br>
>>> BB.<br>
>>> +bool OrderedBasicBlock::dominates(const Instruction *A, const<br>
>>> 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<br>
>>> give us<br>
>>> +  // back ::end(). If they both exist, we compare the numbers.<br>
>>> Otherwise, if NA<br>
>>> +  // exists and NB doesn't, it means NA must come before NB because we<br>
>>> would<br>
>>> +  // have numbered NB as well if it didn't. The same is true for NB. If<br>
>>> it<br>
>>> +  // exists, but NA does not, NA must come after it. If neither exist,<br>
>>> 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" onclick="window.open('https://mail.google.com/mail/?view=cm&tf=1&to=llvm-commits@cs.uiuc.edu&cc=&bcc=&su=&body=','_blank');return false;">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>
>><br>
>><br>
><br>
<br>
<br>
<br>
</div></div><span><font color="#888888">--<br>
Bruno Cardoso Lopes<br>
<a href="http://www.brunocardoso.cc" rel="noreferrer" target="_blank">http://www.brunocardoso.cc</a><br>
</font></span></blockquote></div><br></div></div>