<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jun 14, 2016 at 12:47 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</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">It looks like the problem is specifically the call to the BlockFrequencyInfo destructor...<br><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="h5">On Mon, Jun 13, 2016 at 6:45 PM, Sean Silva <span dir="ltr"><<a href="mailto:chisophugis@gmail.com" target="_blank">chisophugis@gmail.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">Thanks. My gut is that this would affect any user of BlockFrequencyInfo.h and so I would suggest to move the include there instead.</div><div><div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jun 13, 2016 at 6:38 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</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">Fixed in r272612, can you take a look and see if that's the right fix?<br></div><div><div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jun 13, 2016 at 6:27 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</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">This breaks the modules bot (as did the previous commit of this). Looks like BlockFrequencyInfo.h triggers an instantiation that requires a definition of BlockFrequencyInfoImpl.</div><div><div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jun 13, 2016 at 5:51 PM, Sean Silva via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: silvas<br>
Date: Mon Jun 13 19:51:09 2016<br>
New Revision: 272607<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=272607&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=272607&view=rev</a><br>
Log:<br>
Bring back "[PM] Port JumpThreading to the new PM" with a fix<br>
<br>
This reverts commit r272603 and adds a fix.<br>
<br>
Big thanks to Davide for pointing me at r216244 which gives some insight<br>
into how to fix this VS2013 issue. VS2013 can't synthesize a move<br>
constructor. So the fix here is to add one explicitly to the<br>
JumpThreadingPass class.<br>
<br>
Added:<br>
    llvm/trunk/include/llvm/Transforms/Scalar/JumpThreading.h<br>
Modified:<br>
    llvm/trunk/lib/Passes/PassBuilder.cpp<br>
    llvm/trunk/lib/Passes/PassRegistry.def<br>
    llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp<br>
    llvm/trunk/test/Transforms/JumpThreading/thread-loads.ll<br>
<br>
Added: llvm/trunk/include/llvm/Transforms/Scalar/JumpThreading.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar/JumpThreading.h?rev=272607&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar/JumpThreading.h?rev=272607&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/Transforms/Scalar/JumpThreading.h (added)<br>
+++ llvm/trunk/include/llvm/Transforms/Scalar/JumpThreading.h Mon Jun 13 19:51:09 2016<br>
@@ -0,0 +1,140 @@<br>
+//===- JumpThreading.h - thread control through conditional BBs -*- 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>
+/// \file<br>
+/// See the comments on JumpThreadingPass.<br>
+///<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#ifndef LLVM_TRANSFORMS_SCALAR_JUMPTHREADING_H<br>
+#define LLVM_TRANSFORMS_SCALAR_JUMPTHREADING_H<br>
+<br>
+#include "llvm/ADT/DenseSet.h"<br>
+#include "llvm/ADT/SmallPtrSet.h"<br>
+#include "llvm/ADT/SmallSet.h"<br>
+#include "llvm/Analysis/BlockFrequencyInfo.h"<br>
+#include "llvm/Analysis/BranchProbabilityInfo.h"<br>
+#include "llvm/Analysis/LazyValueInfo.h"<br>
+#include "llvm/Analysis/TargetLibraryInfo.h"<br>
+#include "llvm/IR/Instructions.h"<br>
+#include "llvm/IR/ValueHandle.h"<br>
+<br>
+namespace llvm {<br>
+<br>
+/// A private "module" namespace for types and utilities used by<br>
+/// JumpThreading.<br>
+/// These are implementation details and should not be used by clients.<br>
+namespace jumpthreading {<br>
+// These are at global scope so static functions can use them too.<br>
+typedef SmallVectorImpl<std::pair<Constant *, BasicBlock *>> PredValueInfo;<br>
+typedef SmallVector<std::pair<Constant *, BasicBlock *>, 8> PredValueInfoTy;<br>
+<br>
+// This is used to keep track of what kind of constant we're currently hoping<br>
+// to find.<br>
+enum ConstantPreference { WantInteger, WantBlockAddress };<br>
+}<br>
+<br>
+/// This pass performs 'jump threading', which looks at blocks that have<br>
+/// multiple predecessors and multiple successors.  If one or more of the<br>
+/// predecessors of the block can be proven to always jump to one of the<br>
+/// successors, we forward the edge from the predecessor to the successor by<br>
+/// duplicating the contents of this block.<br>
+///<br>
+/// An example of when this can occur is code like this:<br>
+///<br>
+///   if () { ...<br>
+///     X = 4;<br>
+///   }<br>
+///   if (X < 3) {<br>
+///<br>
+/// In this case, the unconditional branch at the end of the first if can be<br>
+/// revectored to the false side of the second if.<br>
+///<br>
+class JumpThreadingPass : public PassInfoMixin<JumpThreadingPass> {<br>
+  TargetLibraryInfo *TLI;<br>
+  LazyValueInfo *LVI;<br>
+  std::unique_ptr<BlockFrequencyInfo> BFI;<br>
+  std::unique_ptr<BranchProbabilityInfo> BPI;<br>
+  bool HasProfileData;<br>
+#ifdef NDEBUG<br>
+  SmallPtrSet<const BasicBlock *, 16> LoopHeaders;<br>
+#else<br>
+  SmallSet<AssertingVH<const BasicBlock>, 16> LoopHeaders;<br>
+#endif<br>
+  DenseSet<std::pair<Value *, BasicBlock *>> RecursionSet;<br>
+<br>
+  unsigned BBDupThreshold;<br>
+<br>
+  // RAII helper for updating the recursion stack.<br>
+  struct RecursionSetRemover {<br>
+    DenseSet<std::pair<Value *, BasicBlock *>> &TheSet;<br>
+    std::pair<Value *, BasicBlock *> ThePair;<br>
+<br>
+    RecursionSetRemover(DenseSet<std::pair<Value *, BasicBlock *>> &S,<br>
+                        std::pair<Value *, BasicBlock *> P)<br>
+        : TheSet(S), ThePair(P) {}<br>
+<br>
+    ~RecursionSetRemover() { TheSet.erase(ThePair); }<br>
+  };<br>
+<br>
+public:<br>
+  JumpThreadingPass(int T = -1);<br>
+  // Hack for MSVC 2013 which seems like it can't synthesize this.<br>
+  JumpThreadingPass(JumpThreadingPass &&Other)<br>
+      : TLI(Other.TLI), LVI(Other.LVI), BFI(std::move(Other.BFI)),<br>
+        BPI(std::move(Other.BPI)), HasProfileData(Other.HasProfileData),<br>
+        LoopHeaders(std::move(Other.LoopHeaders)),<br>
+        RecursionSet(std::move(Other.RecursionSet)),<br>
+        BBDupThreshold(Other.BBDupThreshold) {}<br>
+<br>
+  // Glue for old PM.<br>
+  bool runImpl(Function &F, TargetLibraryInfo *TLI_, LazyValueInfo *LVI_,<br>
+               bool HasProfileData_, std::unique_ptr<BlockFrequencyInfo> BFI_,<br>
+               std::unique_ptr<BranchProbabilityInfo> BPI_);<br>
+<br>
+  PreservedAnalyses run(Function &F, AnalysisManager<Function> &AM);<br>
+<br>
+  void releaseMemory() {<br>
+    BFI.reset();<br></blockquote></div></div></div></div></blockquote></div></div></div></div></blockquote></div></div></div></div></blockquote><div><br></div></div></div><div>... here. Is there a good reason for this function to be inline?</div></div></div></div></blockquote><div><br></div><div>No good reason. I think this was an artifact of how I refactored things.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><br></div><div>(I'm not confident that fixing that will allow the include to be removed; you still need the relevant definition when creating or destroying a JumpThreadingPass.)</div></div></div></div></blockquote><div><br></div><div>My bigger concern is that BlockFrequencyInfo.h is non-modular (we have an existence proof that the modular include is not equivalent to the textual include for it).</div><div><br></div><div>-- Sean Silva</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div class="h5"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+    BPI.reset();<br>
+  }<br>
+<br>
+  void FindLoopHeaders(Function &F);<br>
+  bool ProcessBlock(BasicBlock *BB);<br>
+  bool ThreadEdge(BasicBlock *BB, const SmallVectorImpl<BasicBlock *> &PredBBs,<br>
+                  BasicBlock *SuccBB);<br>
+  bool DuplicateCondBranchOnPHIIntoPred(<br>
+      BasicBlock *BB, const SmallVectorImpl<BasicBlock *> &PredBBs);<br>
+<br>
+  bool<br>
+  ComputeValueKnownInPredecessors(Value *V, BasicBlock *BB,<br>
+                                  jumpthreading::PredValueInfo &Result,<br>
+                                  jumpthreading::ConstantPreference Preference,<br>
+                                  Instruction *CxtI = nullptr);<br>
+  bool ProcessThreadableEdges(Value *Cond, BasicBlock *BB,<br>
+                              jumpthreading::ConstantPreference Preference,<br>
+                              Instruction *CxtI = nullptr);<br>
+<br>
+  bool ProcessBranchOnPHI(PHINode *PN);<br>
+  bool ProcessBranchOnXOR(BinaryOperator *BO);<br>
+  bool ProcessImpliedCondition(BasicBlock *BB);<br>
+<br>
+  bool SimplifyPartiallyRedundantLoad(LoadInst *LI);<br>
+  bool TryToUnfoldSelect(CmpInst *CondCmp, BasicBlock *BB);<br>
+  bool TryToUnfoldSelectInCurrBB(BasicBlock *BB);<br>
+<br>
+private:<br>
+  BasicBlock *SplitBlockPreds(BasicBlock *BB, ArrayRef<BasicBlock *> Preds,<br>
+                              const char *Suffix);<br>
+  void UpdateBlockFreqAndEdgeWeight(BasicBlock *PredBB, BasicBlock *BB,<br>
+                                    BasicBlock *NewBB, BasicBlock *SuccBB);<br>
+};<br>
+<br>
+} // end namespace llvm<br>
+<br>
+#endif<br>
<br>
Modified: llvm/trunk/lib/Passes/PassBuilder.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Passes/PassBuilder.cpp?rev=272607&r1=272606&r2=272607&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Passes/PassBuilder.cpp?rev=272607&r1=272606&r2=272607&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Passes/PassBuilder.cpp (original)<br>
+++ llvm/trunk/lib/Passes/PassBuilder.cpp Mon Jun 13 19:51:09 2016<br>
@@ -75,6 +75,7 @@<br>
 #include "llvm/Transforms/Scalar/GVN.h"<br>
 #include "llvm/Transforms/Scalar/GuardWidening.h"<br>
 #include "llvm/Transforms/Scalar/IndVarSimplify.h"<br>
+#include "llvm/Transforms/Scalar/JumpThreading.h"<br>
 #include "llvm/Transforms/Scalar/LoopRotation.h"<br>
 #include "llvm/Transforms/Scalar/LoopSimplifyCFG.h"<br>
 #include "llvm/Transforms/Scalar/LowerAtomic.h"<br>
<br>
Modified: llvm/trunk/lib/Passes/PassRegistry.def<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Passes/PassRegistry.def?rev=272607&r1=272606&r2=272607&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Passes/PassRegistry.def?rev=272607&r1=272606&r2=272607&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Passes/PassRegistry.def (original)<br>
+++ llvm/trunk/lib/Passes/PassRegistry.def Mon Jun 13 19:51:09 2016<br>
@@ -130,6 +130,7 @@ FUNCTION_PASS("lower-expect", LowerExpec<br>
 FUNCTION_PASS("guard-widening", GuardWideningPass())<br>
 FUNCTION_PASS("gvn", GVN())<br>
 FUNCTION_PASS("mldst-motion", MergedLoadStoreMotionPass())<br>
+FUNCTION_PASS("jump-threading", JumpThreadingPass())<br>
 FUNCTION_PASS("partially-inline-libcalls", PartiallyInlineLibCallsPass())<br>
 FUNCTION_PASS("lcssa", LCSSAPass())<br>
 FUNCTION_PASS("print", PrintFunctionPass(dbgs()))<br>
<br>
Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=272607&r1=272606&r2=272607&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=272607&r1=272606&r2=272607&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Mon Jun 13 19:51:09 2016<br>
@@ -11,31 +11,25 @@<br>
 //<br>
 //===----------------------------------------------------------------------===//<br>
<br>
+#include "llvm/Transforms/Scalar/JumpThreading.h"<br>
 #include "llvm/Transforms/Scalar.h"<br>
 #include "llvm/ADT/DenseMap.h"<br>
 #include "llvm/ADT/DenseSet.h"<br>
 #include "llvm/ADT/STLExtras.h"<br>
-#include "llvm/ADT/SmallPtrSet.h"<br>
-#include "llvm/ADT/SmallSet.h"<br>
 #include "llvm/ADT/Statistic.h"<br>
 #include "llvm/Analysis/GlobalsModRef.h"<br>
 #include "llvm/Analysis/CFG.h"<br>
-#include "llvm/Analysis/BlockFrequencyInfo.h"<br>
 #include "llvm/Analysis/BlockFrequencyInfoImpl.h"<br>
-#include "llvm/Analysis/BranchProbabilityInfo.h"<br>
 #include "llvm/Analysis/ConstantFolding.h"<br>
 #include "llvm/Analysis/InstructionSimplify.h"<br>
-#include "llvm/Analysis/LazyValueInfo.h"<br>
 #include "llvm/Analysis/Loads.h"<br>
 #include "llvm/Analysis/LoopInfo.h"<br>
-#include "llvm/Analysis/TargetLibraryInfo.h"<br>
 #include "llvm/Analysis/ValueTracking.h"<br>
 #include "llvm/IR/DataLayout.h"<br>
 #include "llvm/IR/IntrinsicInst.h"<br>
 #include "llvm/IR/LLVMContext.h"<br>
 #include "llvm/IR/MDBuilder.h"<br>
 #include "llvm/IR/Metadata.h"<br>
-#include "llvm/IR/ValueHandle.h"<br>
 #include "llvm/Pass.h"<br>
 #include "llvm/Support/CommandLine.h"<br>
 #include "llvm/Support/Debug.h"<br>
@@ -46,6 +40,7 @@<br>
 #include <algorithm><br>
 #include <memory><br>
 using namespace llvm;<br>
+using namespace jumpthreading;<br>
<br>
 #define DEBUG_TYPE "jump-threading"<br>
<br>
@@ -66,17 +61,6 @@ ImplicationSearchThreshold(<br>
   cl::init(3), cl::Hidden);<br>
<br>
 namespace {<br>
-  // These are at global scope so static functions can use them too.<br>
-  typedef SmallVectorImpl<std::pair<Constant*, BasicBlock*> > PredValueInfo;<br>
-  typedef SmallVector<std::pair<Constant*, BasicBlock*>, 8> PredValueInfoTy;<br>
-<br>
-  // This is used to keep track of what kind of constant we're currently hoping<br>
-  // to find.<br>
-  enum ConstantPreference {<br>
-    WantInteger,<br>
-    WantBlockAddress<br>
-  };<br>
-<br>
   /// This pass performs 'jump threading', which looks at blocks that have<br>
   /// multiple predecessors and multiple successors.  If one or more of the<br>
   /// predecessors of the block can be proven to always jump to one of the<br>
@@ -94,37 +78,11 @@ namespace {<br>
   /// revectored to the false side of the second if.<br>
   ///<br>
   class JumpThreading : public FunctionPass {<br>
-    TargetLibraryInfo *TLI;<br>
-    LazyValueInfo *LVI;<br>
-    std::unique_ptr<BlockFrequencyInfo> BFI;<br>
-    std::unique_ptr<BranchProbabilityInfo> BPI;<br>
-    bool HasProfileData;<br>
-#ifdef NDEBUG<br>
-    SmallPtrSet<const BasicBlock *, 16> LoopHeaders;<br>
-#else<br>
-    SmallSet<AssertingVH<const BasicBlock>, 16> LoopHeaders;<br>
-#endif<br>
-    DenseSet<std::pair<Value*, BasicBlock*> > RecursionSet;<br>
-<br>
-    unsigned BBDupThreshold;<br>
-<br>
-    // RAII helper for updating the recursion stack.<br>
-    struct RecursionSetRemover {<br>
-      DenseSet<std::pair<Value*, BasicBlock*> > &TheSet;<br>
-      std::pair<Value*, BasicBlock*> ThePair;<br>
-<br>
-      RecursionSetRemover(DenseSet<std::pair<Value*, BasicBlock*> > &S,<br>
-                          std::pair<Value*, BasicBlock*> P)<br>
-        : TheSet(S), ThePair(P) { }<br>
+    JumpThreadingPass Impl;<br>
<br>
-      ~RecursionSetRemover() {<br>
-        TheSet.erase(ThePair);<br>
-      }<br>
-    };<br>
   public:<br>
     static char ID; // Pass identification<br>
-    JumpThreading(int T = -1) : FunctionPass(ID) {<br>
-      BBDupThreshold = (T == -1) ? BBDuplicateThreshold : unsigned(T);<br>
+    JumpThreading(int T = -1) : FunctionPass(ID), Impl(T) {<br>
       initializeJumpThreadingPass(*PassRegistry::getPassRegistry());<br>
     }<br>
<br>
@@ -137,39 +95,7 @@ namespace {<br>
       AU.addRequired<TargetLibraryInfoWrapperPass>();<br>
     }<br>
<br>
-    void releaseMemory() override {<br>
-      BFI.reset();</blockquote></div></div></div></div></blockquote></div></div></div></div></blockquote></div></div></div></div></blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
-      BPI.reset();<br>
-    }<br>
-<br>
-    void FindLoopHeaders(Function &F);<br>
-    bool ProcessBlock(BasicBlock *BB);<br>
-    bool ThreadEdge(BasicBlock *BB, const SmallVectorImpl<BasicBlock*> &PredBBs,<br>
-                    BasicBlock *SuccBB);<br>
-    bool DuplicateCondBranchOnPHIIntoPred(BasicBlock *BB,<br>
-                                  const SmallVectorImpl<BasicBlock *> &PredBBs);<br>
-<br>
-    bool ComputeValueKnownInPredecessors(Value *V, BasicBlock *BB,<br>
-                                         PredValueInfo &Result,<br>
-                                         ConstantPreference Preference,<br>
-                                         Instruction *CxtI = nullptr);<br>
-    bool ProcessThreadableEdges(Value *Cond, BasicBlock *BB,<br>
-                                ConstantPreference Preference,<br>
-                                Instruction *CxtI = nullptr);<br>
-<br>
-    bool ProcessBranchOnPHI(PHINode *PN);<br>
-    bool ProcessBranchOnXOR(BinaryOperator *BO);<br>
-    bool ProcessImpliedCondition(BasicBlock *BB);<br>
-<br>
-    bool SimplifyPartiallyRedundantLoad(LoadInst *LI);<br>
-    bool TryToUnfoldSelect(CmpInst *CondCmp, BasicBlock *BB);<br>
-    bool TryToUnfoldSelectInCurrBB(BasicBlock *BB);<br>
-<br>
-  private:<br>
-    BasicBlock *SplitBlockPreds(BasicBlock *BB, ArrayRef<BasicBlock *> Preds,<br>
-                                const char *Suffix);<br>
-    void UpdateBlockFreqAndEdgeWeight(BasicBlock *PredBB, BasicBlock *BB,<br>
-                                      BasicBlock *NewBB, BasicBlock *SuccBB);<br>
+    void releaseMemory() override { Impl.releaseMemory(); }<br>
   };<br>
 }<br>
<br>
@@ -184,24 +110,68 @@ INITIALIZE_PASS_END(JumpThreading, "jump<br>
 // Public interface to the Jump Threading pass<br>
 FunctionPass *llvm::createJumpThreadingPass(int Threshold) { return new JumpThreading(Threshold); }<br>
<br>
+JumpThreadingPass::JumpThreadingPass(int T) {<br>
+  BBDupThreshold = (T == -1) ? BBDuplicateThreshold : unsigned(T);<br>
+}<br>
+<br>
 /// runOnFunction - Top level algorithm.<br>
 ///<br>
 bool JumpThreading::runOnFunction(Function &F) {<br>
   if (skipFunction(F))<br>
     return false;<br>
+  auto TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();<br>
+  auto LVI = &getAnalysis<LazyValueInfoWrapperPass>().getLVI();<br>
+  std::unique_ptr<BlockFrequencyInfo> BFI;<br>
+  std::unique_ptr<BranchProbabilityInfo> BPI;<br>
+  bool HasProfileData = F.getEntryCount().hasValue();<br>
+  if (HasProfileData) {<br>
+    LoopInfo LI{DominatorTree(F)};<br>
+    BPI.reset(new BranchProbabilityInfo(F, LI));<br>
+    BFI.reset(new BlockFrequencyInfo(F, *BPI, LI));<br>
+  }<br>
+  return Impl.runImpl(F, TLI, LVI, HasProfileData, std::move(BFI),<br>
+                      std::move(BPI));<br>
+}<br>
+<br>
+PreservedAnalyses JumpThreadingPass::run(Function &F,<br>
+                                         AnalysisManager<Function> &AM) {<br>
+<br>
+  auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);<br>
+  auto &LVI = AM.getResult<LazyValueAnalysis>(F);<br>
+  std::unique_ptr<BlockFrequencyInfo> BFI;<br>
+  std::unique_ptr<BranchProbabilityInfo> BPI;<br>
+  bool HasProfileData = F.getEntryCount().hasValue();<br>
+  if (HasProfileData) {<br>
+    LoopInfo LI{DominatorTree(F)};<br>
+    BPI.reset(new BranchProbabilityInfo(F, LI));<br>
+    BFI.reset(new BlockFrequencyInfo(F, *BPI, LI));<br>
+  }<br>
+  bool Changed =<br>
+      runImpl(F, &TLI, &LVI, HasProfileData, std::move(BFI), std::move(BPI));<br>
+  if (!Changed)<br>
+    return PreservedAnalyses::all();<br>
+  PreservedAnalyses PA;<br>
+  PA.preserve<LazyValueAnalysis>();<br>
+  PA.preserve<GlobalsAA>();<br>
+  return PreservedAnalyses::none();<br>
+}<br>
+<br>
+bool JumpThreadingPass::runImpl(Function &F, TargetLibraryInfo *TLI_,<br>
+                                LazyValueInfo *LVI_, bool HasProfileData_,<br>
+                                std::unique_ptr<BlockFrequencyInfo> BFI_,<br>
+                                std::unique_ptr<BranchProbabilityInfo> BPI_) {<br>
<br>
   DEBUG(dbgs() << "Jump threading on function '" << F.getName() << "'\n");<br>
-  TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();<br>
-  LVI = &getAnalysis<LazyValueInfoWrapperPass>().getLVI();<br>
+  TLI = TLI_;<br>
+  LVI = LVI_;<br>
   BFI.reset();<br>
   BPI.reset();<br>
   // When profile data is available, we need to update edge weights after<br>
   // successful jump threading, which requires both BPI and BFI being available.<br>
-  HasProfileData = F.getEntryCount().hasValue();<br>
+  HasProfileData = HasProfileData_;<br>
   if (HasProfileData) {<br>
-    LoopInfo LI{DominatorTree(F)};<br>
-    BPI.reset(new BranchProbabilityInfo(F, LI));<br>
-    BFI.reset(new BlockFrequencyInfo(F, *BPI, LI));<br>
+    BPI = std::move(BPI_);<br>
+    BFI = std::move(BFI_);<br>
   }<br>
<br>
   // Remove unreachable blocks from function as they may result in infinite<br>
@@ -364,7 +334,7 @@ static unsigned getJumpThreadDuplication<br>
 /// enough to track all of these properties and keep it up-to-date as the CFG<br>
 /// mutates, so we don't allow any of these transformations.<br>
 ///<br>
-void JumpThreading::FindLoopHeaders(Function &F) {<br>
+void JumpThreadingPass::FindLoopHeaders(Function &F) {<br>
   SmallVector<std::pair<const BasicBlock*,const BasicBlock*>, 32> Edges;<br>
   FindFunctionBackedges(F, Edges);<br>
<br>
@@ -398,10 +368,9 @@ static Constant *getKnownConstant(Value<br>
 ///<br>
 /// This returns true if there were any known values.<br>
 ///<br>
-bool JumpThreading::<br>
-ComputeValueKnownInPredecessors(Value *V, BasicBlock *BB, PredValueInfo &Result,<br>
-                                ConstantPreference Preference,<br>
-                                Instruction *CxtI) {<br>
+bool JumpThreadingPass::ComputeValueKnownInPredecessors(<br>
+    Value *V, BasicBlock *BB, PredValueInfo &Result,<br>
+    ConstantPreference Preference, Instruction *CxtI) {<br>
   // This method walks up use-def chains recursively.  Because of this, we could<br>
   // get into an infinite loop going around loops in the use-def chain.  To<br>
   // prevent this, keep track of what (value, block) pairs we've already visited<br>
@@ -727,7 +696,7 @@ static bool hasAddressTakenAndUsed(Basic<br>
<br>
 /// ProcessBlock - If there are any predecessors whose control can be threaded<br>
 /// through to a successor, transform them now.<br>
-bool JumpThreading::ProcessBlock(BasicBlock *BB) {<br>
+bool JumpThreadingPass::ProcessBlock(BasicBlock *BB) {<br>
   // If the block is trivially dead, just return and let the caller nuke it.<br>
   // This simplifies other transformations.<br>
   if (pred_empty(BB) &&<br>
@@ -911,7 +880,7 @@ bool JumpThreading::ProcessBlock(BasicBl<br>
   return false;<br>
 }<br>
<br>
-bool JumpThreading::ProcessImpliedCondition(BasicBlock *BB) {<br>
+bool JumpThreadingPass::ProcessImpliedCondition(BasicBlock *BB) {<br>
   auto *BI = dyn_cast<BranchInst>(BB->getTerminator());<br>
   if (!BI || !BI->isConditional())<br>
     return false;<br>
@@ -950,7 +919,7 @@ bool JumpThreading::ProcessImpliedCondit<br>
 /// load instruction, eliminate it by replacing it with a PHI node.  This is an<br>
 /// important optimization that encourages jump threading, and needs to be run<br>
 /// interlaced with other jump threading tasks.<br>
-bool JumpThreading::SimplifyPartiallyRedundantLoad(LoadInst *LI) {<br>
+bool JumpThreadingPass::SimplifyPartiallyRedundantLoad(LoadInst *LI) {<br>
   // Don't hack volatile/atomic loads.<br>
   if (!LI->isSimple()) return false;<br>
<br>
@@ -1198,9 +1167,9 @@ FindMostPopularDest(BasicBlock *BB,<br>
   return MostPopularDest;<br>
 }<br>
<br>
-bool JumpThreading::ProcessThreadableEdges(Value *Cond, BasicBlock *BB,<br>
-                                           ConstantPreference Preference,<br>
-                                           Instruction *CxtI) {<br>
+bool JumpThreadingPass::ProcessThreadableEdges(Value *Cond, BasicBlock *BB,<br>
+                                               ConstantPreference Preference,<br>
+                                               Instruction *CxtI) {<br>
   // If threading this would thread across a loop header, don't even try to<br>
   // thread the edge.<br>
   if (LoopHeaders.count(BB))<br>
@@ -1306,7 +1275,7 @@ bool JumpThreading::ProcessThreadableEdg<br>
 /// a PHI node in the current block.  See if there are any simplifications we<br>
 /// can do based on inputs to the phi node.<br>
 ///<br>
-bool JumpThreading::ProcessBranchOnPHI(PHINode *PN) {<br>
+bool JumpThreadingPass::ProcessBranchOnPHI(PHINode *PN) {<br>
   BasicBlock *BB = PN->getParent();<br>
<br>
   // TODO: We could make use of this to do it once for blocks with common PHI<br>
@@ -1336,7 +1305,7 @@ bool JumpThreading::ProcessBranchOnPHI(P<br>
 /// a xor instruction in the current block.  See if there are any<br>
 /// simplifications we can do based on inputs to the xor.<br>
 ///<br>
-bool JumpThreading::ProcessBranchOnXOR(BinaryOperator *BO) {<br>
+bool JumpThreadingPass::ProcessBranchOnXOR(BinaryOperator *BO) {<br>
   BasicBlock *BB = BO->getParent();<br>
<br>
   // If either the LHS or RHS of the xor is a constant, don't do this<br>
@@ -1464,9 +1433,9 @@ static void AddPHINodeEntriesForMappedBl<br>
 /// ThreadEdge - We have decided that it is safe and profitable to factor the<br>
 /// blocks in PredBBs to one predecessor, then thread an edge from it to SuccBB<br>
 /// across BB.  Transform the IR to reflect this change.<br>
-bool JumpThreading::ThreadEdge(BasicBlock *BB,<br>
-                               const SmallVectorImpl<BasicBlock*> &PredBBs,<br>
-                               BasicBlock *SuccBB) {<br>
+bool JumpThreadingPass::ThreadEdge(BasicBlock *BB,<br>
+                                   const SmallVectorImpl<BasicBlock *> &PredBBs,<br>
+                                   BasicBlock *SuccBB) {<br>
   // If threading to the same block as we come from, we would infinite loop.<br>
   if (SuccBB == BB) {<br>
     DEBUG(dbgs() << "  Not threading across BB '" << BB->getName()<br>
@@ -1620,9 +1589,9 @@ bool JumpThreading::ThreadEdge(BasicBloc<br>
 /// Create a new basic block that will be the predecessor of BB and successor of<br>
 /// all blocks in Preds. When profile data is availble, update the frequency of<br>
 /// this new block.<br>
-BasicBlock *JumpThreading::SplitBlockPreds(BasicBlock *BB,<br>
-                                           ArrayRef<BasicBlock *> Preds,<br>
-                                           const char *Suffix) {<br>
+BasicBlock *JumpThreadingPass::SplitBlockPreds(BasicBlock *BB,<br>
+                                               ArrayRef<BasicBlock *> Preds,<br>
+                                               const char *Suffix) {<br>
   // Collect the frequencies of all predecessors of BB, which will be used to<br>
   // update the edge weight on BB->SuccBB.<br>
   BlockFrequency PredBBFreq(0);<br>
@@ -1642,10 +1611,10 @@ BasicBlock *JumpThreading::SplitBlockPre<br>
 /// Update the block frequency of BB and branch weight and the metadata on the<br>
 /// edge BB->SuccBB. This is done by scaling the weight of BB->SuccBB by 1 -<br>
 /// Freq(PredBB->BB) / Freq(BB->SuccBB).<br>
-void JumpThreading::UpdateBlockFreqAndEdgeWeight(BasicBlock *PredBB,<br>
-                                                 BasicBlock *BB,<br>
-                                                 BasicBlock *NewBB,<br>
-                                                 BasicBlock *SuccBB) {<br>
+void JumpThreadingPass::UpdateBlockFreqAndEdgeWeight(BasicBlock *PredBB,<br>
+                                                     BasicBlock *BB,<br>
+                                                     BasicBlock *NewBB,<br>
+                                                     BasicBlock *SuccBB) {<br>
   if (!HasProfileData)<br>
     return;<br>
<br>
@@ -1706,8 +1675,8 @@ void JumpThreading::UpdateBlockFreqAndEd<br>
 /// If we can duplicate the contents of BB up into PredBB do so now, this<br>
 /// improves the odds that the branch will be on an analyzable instruction like<br>
 /// a compare.<br>
-bool JumpThreading::DuplicateCondBranchOnPHIIntoPred(BasicBlock *BB,<br>
-                                 const SmallVectorImpl<BasicBlock *> &PredBBs) {<br>
+bool JumpThreadingPass::DuplicateCondBranchOnPHIIntoPred(<br>
+    BasicBlock *BB, const SmallVectorImpl<BasicBlock *> &PredBBs) {<br>
   assert(!PredBBs.empty() && "Can't handle an empty set");<br>
<br>
   // If BB is a loop header, then duplicating this block outside the loop would<br>
@@ -1856,7 +1825,7 @@ bool JumpThreading::DuplicateCondBranchO<br>
 ///<br>
 /// And expand the select into a branch structure if one of its arms allows %c<br>
 /// to be folded. This later enables threading from bb1 over bb2.<br>
-bool JumpThreading::TryToUnfoldSelect(CmpInst *CondCmp, BasicBlock *BB) {<br>
+bool JumpThreadingPass::TryToUnfoldSelect(CmpInst *CondCmp, BasicBlock *BB) {<br>
   BranchInst *CondBr = dyn_cast<BranchInst>(BB->getTerminator());<br>
   PHINode *CondLHS = dyn_cast<PHINode>(CondCmp->getOperand(0));<br>
   Constant *CondRHS = cast<Constant>(CondCmp->getOperand(1));<br>
@@ -1934,7 +1903,7 @@ bool JumpThreading::TryToUnfoldSelect(Cm<br>
 /// select if the associated PHI has at least one constant.  If the unfolded<br>
 /// select is not jump-threaded, it will be folded again in the later<br>
 /// optimizations.<br>
-bool JumpThreading::TryToUnfoldSelectInCurrBB(BasicBlock *BB) {<br>
+bool JumpThreadingPass::TryToUnfoldSelectInCurrBB(BasicBlock *BB) {<br>
   // If threading this would thread across a loop header, don't thread the edge.<br>
   // See the comments above FindLoopHeaders for justifications and caveats.<br>
   if (LoopHeaders.count(BB))<br>
<br>
Modified: llvm/trunk/test/Transforms/JumpThreading/thread-loads.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/JumpThreading/thread-loads.ll?rev=272607&r1=272606&r2=272607&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/JumpThreading/thread-loads.ll?rev=272607&r1=272606&r2=272607&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/Transforms/JumpThreading/thread-loads.ll (original)<br>
+++ llvm/trunk/test/Transforms/JumpThreading/thread-loads.ll Mon Jun 13 19:51:09 2016<br>
@@ -1,4 +1,5 @@<br>
 ; RUN: opt < %s -jump-threading -S | FileCheck %s<br>
+; RUN: opt < %s -passes=jump-threading -S | FileCheck %s<br>
<br>
 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"<br>
 target triple = "i386-apple-darwin7"<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div></div></div><br></div></div>
</blockquote></div><br></div></div>