<div dir="ltr">Thanks for doing this one. The name changing thing made this one a bit strange to port.<div><br></div><div>This is also the last non-loop-related pass needed for the per-TU O3 pipeline!</div><div>(ignoring CGSCC stuff which you can grab from <a href="http://reviews.llvm.org/D21921">http://reviews.llvm.org/D21921</a>)</div><div><br></div><div>Only LoopLoadElimination and LoopUnswitch are left I think. (LoopUnswitch requires an API (addLoop) which the new PM LoopPassManager doesn't have).<br><div><br></div><div>-- Sean Silva</div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Aug 1, 2016 at 2:48 PM, Michael Kuperstein 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: mkuper<br>
Date: Mon Aug  1 16:48:33 2016<br>
New Revision: 277393<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=277393&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=277393&view=rev</a><br>
Log:<br>
[PM] Port SpeculativeExecution to the new PM<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D23033" rel="noreferrer" target="_blank">https://reviews.llvm.org/D23033</a><br>
<br>
Added:<br>
    llvm/trunk/include/llvm/Transforms/Scalar/SpeculativeExecution.h<br>
Modified:<br>
    llvm/trunk/include/llvm/InitializePasses.h<br>
    llvm/trunk/lib/Passes/PassBuilder.cpp<br>
    llvm/trunk/lib/Passes/PassRegistry.def<br>
    llvm/trunk/lib/Transforms/Scalar/Scalar.cpp<br>
    llvm/trunk/lib/Transforms/Scalar/SpeculativeExecution.cpp<br>
    llvm/trunk/test/Transforms/SpeculativeExecution/spec.ll<br>
<br>
Modified: llvm/trunk/include/llvm/InitializePasses.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=277393&r1=277392&r2=277393&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=277393&r1=277392&r2=277393&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/InitializePasses.h (original)<br>
+++ llvm/trunk/include/llvm/InitializePasses.h Mon Aug  1 16:48:33 2016<br>
@@ -313,7 +313,7 @@ void initializeSingleLoopExtractorPass(P<br>
 void initializeSinkingLegacyPassPass(PassRegistry&);<br>
 void initializeSjLjEHPreparePass(PassRegistry&);<br>
 void initializeSlotIndexesPass(PassRegistry&);<br>
-void initializeSpeculativeExecutionPass(PassRegistry&);<br>
+void initializeSpeculativeExecutionLegacyPassPass(PassRegistry&);<br>
 void initializeSpillPlacementPass(PassRegistry&);<br>
 void initializeStackColoringPass(PassRegistry&);<br>
 void initializeStackMapLivenessPass(PassRegistry&);<br>
<br>
Added: llvm/trunk/include/llvm/Transforms/Scalar/SpeculativeExecution.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar/SpeculativeExecution.h?rev=277393&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar/SpeculativeExecution.h?rev=277393&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/Transforms/Scalar/SpeculativeExecution.h (added)<br>
+++ llvm/trunk/include/llvm/Transforms/Scalar/SpeculativeExecution.h Mon Aug  1 16:48:33 2016<br>
@@ -0,0 +1,92 @@<br>
+//===- SpeculativeExecution.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 pass hoists instructions to enable speculative execution on<br>
+// targets where branches are expensive. This is aimed at GPUs. It<br>
+// currently works on simple if-then and if-then-else<br>
+// patterns.<br>
+//<br>
+// Removing branches is not the only motivation for this<br>
+// pass. E.g. consider this code and assume that there is no<br>
+// addressing mode for multiplying by sizeof(*a):<br>
+//<br>
+//   if (b > 0)<br>
+//     c = a[i + 1]<br>
+//   if (d > 0)<br>
+//     e = a[i + 2]<br>
+//<br>
+// turns into<br>
+//<br>
+//   p = &a[i + 1];<br>
+//   if (b > 0)<br>
+//     c = *p;<br>
+//   q = &a[i + 2];<br>
+//   if (d > 0)<br>
+//     e = *q;<br>
+//<br>
+// which could later be optimized to<br>
+//<br>
+//   r = &a[i];<br>
+//   if (b > 0)<br>
+//     c = r[1];<br>
+//   if (d > 0)<br>
+//     e = r[2];<br>
+//<br>
+// Later passes sink back much of the speculated code that did not enable<br>
+// further optimization.<br>
+//<br>
+// This pass is more aggressive than the function SpeculativeyExecuteBB in<br>
+// SimplifyCFG. SimplifyCFG will not speculate if no selects are introduced and<br>
+// it will speculate at most one instruction. It also will not speculate if<br>
+// there is a value defined in the if-block that is only used in the then-block.<br>
+// These restrictions make sense since the speculation in SimplifyCFG seems<br>
+// aimed at introducing cheap selects, while this pass is intended to do more<br>
+// aggressive speculation while counting on later passes to either capitalize on<br>
+// that or clean it up.<br>
+//<br>
+// If the pass was created by calling<br>
+// createSpeculativeExecutionIfHasBranchDivergencePass or the<br>
+// -spec-exec-only-if-divergent-target option is present, this pass only has an<br>
+// effect on targets where TargetTransformInfo::hasBranchDivergence() is true;<br>
+// on other targets, it is a nop.<br>
+//<br>
+// This lets you include this pass unconditionally in the IR pass pipeline, but<br>
+// only enable it for relevant targets.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+#ifndef LLVM_TRANSFORMS_SCALAR_SPECULATIVEEXECUTION_H<br>
+#define LLVM_TRANSFORMS_SCALAR_SPECULATIVEEXECUTION_H<br>
+<br>
+#include "llvm/Analysis/TargetTransformInfo.h"<br>
+#include "llvm/IR/PassManager.h"<br>
+<br>
+namespace llvm {<br>
+class SpeculativeExecutionPass<br>
+    : public PassInfoMixin<SpeculativeExecutionPass> {<br>
+public:<br>
+  SpeculativeExecutionPass(bool OnlyIfDivergentTarget = false);<br>
+<br>
+  PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);<br>
+<br>
+  // Glue for old PM<br>
+  bool runImpl(Function &F, TargetTransformInfo *TTI);<br>
+<br>
+private:<br>
+  bool runOnBasicBlock(BasicBlock &B);<br>
+  bool considerHoistingFromTo(BasicBlock &FromBlock, BasicBlock &ToBlock);<br>
+<br>
+  // If true, this pass is a nop unless the target architecture has branch<br>
+  // divergence.<br>
+  const bool OnlyIfDivergentTarget = false;<br>
+<br>
+  TargetTransformInfo *TTI = nullptr;<br>
+};<br>
+}<br>
+<br>
+#endif //LLVM_TRANSFORMS_SCALAR_SPECULATIVEEXECUTION_H<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=277393&r1=277392&r2=277393&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Passes/PassBuilder.cpp?rev=277393&r1=277392&r2=277393&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Passes/PassBuilder.cpp (original)<br>
+++ llvm/trunk/lib/Passes/PassBuilder.cpp Mon Aug  1 16:48:33 2016<br>
@@ -112,6 +112,7 @@<br>
 #include "llvm/Transforms/Scalar/SROA.h"<br>
 #include "llvm/Transforms/Scalar/SimplifyCFG.h"<br>
 #include "llvm/Transforms/Scalar/Sink.h"<br>
+#include "llvm/Transforms/Scalar/SpeculativeExecution.h"<br>
 #include "llvm/Transforms/Scalar/TailRecursionElimination.h"<br>
 #include "llvm/Transforms/Utils/AddDiscriminators.h"<br>
 #include "llvm/Transforms/Utils/BreakCriticalEdges.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=277393&r1=277392&r2=277393&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Passes/PassRegistry.def?rev=277393&r1=277392&r2=277393&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Passes/PassRegistry.def (original)<br>
+++ llvm/trunk/lib/Passes/PassRegistry.def Mon Aug  1 16:48:33 2016<br>
@@ -175,6 +175,7 @@ FUNCTION_PASS("sccp", SCCPPass())<br>
 FUNCTION_PASS("simplify-cfg", SimplifyCFGPass())<br>
 FUNCTION_PASS("sink", SinkingPass())<br>
 FUNCTION_PASS("slp-vectorizer", SLPVectorizerPass())<br>
+FUNCTION_PASS("speculative-execution", SpeculativeExecutionPass())<br>
 FUNCTION_PASS("sroa", SROA())<br>
 FUNCTION_PASS("tailcallelim", TailCallElimPass())<br>
 FUNCTION_PASS("unreachableblockelim", UnreachableBlockElimPass())<br>
<br>
Modified: llvm/trunk/lib/Transforms/Scalar/Scalar.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/Scalar.cpp?rev=277393&r1=277392&r2=277393&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/Scalar.cpp?rev=277393&r1=277392&r2=277393&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Transforms/Scalar/Scalar.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/Scalar/Scalar.cpp Mon Aug  1 16:48:33 2016<br>
@@ -80,7 +80,7 @@ void llvm::initializeScalarOpts(PassRegi<br>
   initializeSinkingLegacyPassPass(Registry);<br>
   initializeTailCallElimPass(Registry);<br>
   initializeSeparateConstOffsetFromGEPPass(Registry);<br>
-  initializeSpeculativeExecutionPass(Registry);<br>
+  initializeSpeculativeExecutionLegacyPassPass(Registry);<br>
   initializeStraightLineStrengthReducePass(Registry);<br>
   initializeLoadCombinePass(Registry);<br>
   initializePlaceBackedgeSafepointsImplPass(Registry);<br>
<br>
Modified: llvm/trunk/lib/Transforms/Scalar/SpeculativeExecution.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SpeculativeExecution.cpp?rev=277393&r1=277392&r2=277393&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SpeculativeExecution.cpp?rev=277393&r1=277392&r2=277393&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Transforms/Scalar/SpeculativeExecution.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/Scalar/SpeculativeExecution.cpp Mon Aug  1 16:48:33 2016<br>
@@ -61,9 +61,9 @@<br>
 //<br>
 //===----------------------------------------------------------------------===//<br>
<br>
+#include "llvm/Transforms/Scalar/SpeculativeExecution.h"<br>
 #include "llvm/ADT/SmallSet.h"<br>
 #include "llvm/Analysis/GlobalsModRef.h"<br>
-#include "llvm/Analysis/TargetTransformInfo.h"<br>
 #include "llvm/Analysis/ValueTracking.h"<br>
 #include "llvm/IR/Instructions.h"<br>
 #include "llvm/IR/Module.h"<br>
@@ -101,58 +101,62 @@ static cl::opt<bool> SpecExecOnlyIfDiver<br>
<br>
 namespace {<br>
<br>
-class SpeculativeExecution : public FunctionPass {<br>
- public:<br>
-   static char ID;<br>
-   explicit SpeculativeExecution(bool OnlyIfDivergentTarget = false)<br>
-       : FunctionPass(ID),<br>
-         OnlyIfDivergentTarget(OnlyIfDivergentTarget ||<br>
-                               SpecExecOnlyIfDivergentTarget) {}<br>
-<br>
-   void getAnalysisUsage(AnalysisUsage &AU) const override;<br>
-   bool runOnFunction(Function &F) override;<br>
-<br>
-   const char *getPassName() const override {<br>
-     if (OnlyIfDivergentTarget)<br>
-       return "Speculatively execute instructions if target has divergent "<br>
-              "branches";<br>
-     return "Speculatively execute instructions";<br>
-   }<br>
-<br>
- private:<br>
-  bool runOnBasicBlock(BasicBlock &B);<br>
-  bool considerHoistingFromTo(BasicBlock &FromBlock, BasicBlock &ToBlock);<br>
+class SpeculativeExecutionLegacyPass : public FunctionPass {<br>
+public:<br>
+  static char ID;<br>
+  explicit SpeculativeExecutionLegacyPass(bool OnlyIfDivergentTarget = false)<br>
+      : FunctionPass(ID), OnlyIfDivergentTarget(OnlyIfDivergentTarget ||<br>
+                                                SpecExecOnlyIfDivergentTarget),<br>
+        Impl(OnlyIfDivergentTarget) {}<br>
+<br>
+  void getAnalysisUsage(AnalysisUsage &AU) const override;<br>
+  bool runOnFunction(Function &F) override;<br>
+<br>
+  const char *getPassName() const override {<br>
+    if (OnlyIfDivergentTarget)<br>
+      return "Speculatively execute instructions if target has divergent "<br>
+             "branches";<br>
+    return "Speculatively execute instructions";<br>
+  }<br>
<br>
-  // If true, this pass is a nop unless the target architecture has branch<br>
-  // divergence.<br>
+private:<br>
+  // Variable preserved purely for correct name printing.<br>
   const bool OnlyIfDivergentTarget;<br>
-  const TargetTransformInfo *TTI = nullptr;<br>
+<br>
+  SpeculativeExecutionPass Impl;<br>
 };<br>
 } // namespace<br>
<br>
-char SpeculativeExecution::ID = 0;<br>
-INITIALIZE_PASS_BEGIN(SpeculativeExecution, "speculative-execution",<br>
+char SpeculativeExecutionLegacyPass::ID = 0;<br>
+INITIALIZE_PASS_BEGIN(SpeculativeExecutionLegacyPass, "speculative-execution",<br>
                       "Speculatively execute instructions", false, false)<br>
 INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)<br>
-INITIALIZE_PASS_END(SpeculativeExecution, "speculative-execution",<br>
+INITIALIZE_PASS_END(SpeculativeExecutionLegacyPass, "speculative-execution",<br>
                     "Speculatively execute instructions", false, false)<br>
<br>
-void SpeculativeExecution::getAnalysisUsage(AnalysisUsage &AU) const {<br>
+void SpeculativeExecutionLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const {<br>
   AU.addRequired<TargetTransformInfoWrapperPass>();<br>
   AU.addPreserved<GlobalsAAWrapperPass>();<br>
 }<br>
<br>
-bool SpeculativeExecution::runOnFunction(Function &F) {<br>
+bool SpeculativeExecutionLegacyPass::runOnFunction(Function &F) {<br>
   if (skipFunction(F))<br>
     return false;<br>
<br>
-  TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);<br>
+  auto *TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);<br>
+  return Impl.runImpl(F, TTI);<br>
+}<br>
+<br>
+namespace llvm {<br>
+<br>
+bool SpeculativeExecutionPass::runImpl(Function &F, TargetTransformInfo *TTI) {<br>
   if (OnlyIfDivergentTarget && !TTI->hasBranchDivergence()) {<br>
     DEBUG(dbgs() << "Not running SpeculativeExecution because "<br>
                     "TTI->hasBranchDivergence() is false.\n");<br>
     return false;<br>
   }<br>
<br>
+  this->TTI = TTI;<br>
   bool Changed = false;<br>
   for (auto& B : F) {<br>
     Changed |= runOnBasicBlock(B);<br>
@@ -160,7 +164,7 @@ bool SpeculativeExecution::runOnFunction<br>
   return Changed;<br>
 }<br>
<br>
-bool SpeculativeExecution::runOnBasicBlock(BasicBlock &B) {<br>
+bool SpeculativeExecutionPass::runOnBasicBlock(BasicBlock &B) {<br>
   BranchInst *BI = dyn_cast<BranchInst>(B.getTerminator());<br>
   if (BI == nullptr)<br>
     return false;<br>
@@ -227,8 +231,8 @@ static unsigned ComputeSpeculationCost(c<br>
   }<br>
 }<br>
<br>
-bool SpeculativeExecution::considerHoistingFromTo(BasicBlock &FromBlock,<br>
-                                                  BasicBlock &ToBlock) {<br>
+bool SpeculativeExecutionPass::considerHoistingFromTo(<br>
+    BasicBlock &FromBlock, BasicBlock &ToBlock) {<br>
   SmallSet<const Instruction *, 8> NotHoisted;<br>
   const auto AllPrecedingUsesFromBlockHoisted = [&NotHoisted](User *U) {<br>
     for (Value* V : U->operand_values()) {<br>
@@ -270,14 +274,28 @@ bool SpeculativeExecution::considerHoist<br>
   return true;<br>
 }<br>
<br>
-namespace llvm {<br>
-<br>
 FunctionPass *createSpeculativeExecutionPass() {<br>
-  return new SpeculativeExecution();<br>
+  return new SpeculativeExecutionLegacyPass();<br>
 }<br>
<br>
 FunctionPass *createSpeculativeExecutionIfHasBranchDivergencePass() {<br>
-  return new SpeculativeExecution(/* OnlyIfDivergentTarget = */ true);<br>
+  return new SpeculativeExecutionLegacyPass(/* OnlyIfDivergentTarget = */ true);<br>
 }<br>
<br>
+SpeculativeExecutionPass::SpeculativeExecutionPass(bool OnlyIfDivergentTarget)<br>
+    : OnlyIfDivergentTarget(OnlyIfDivergentTarget ||<br>
+                            SpecExecOnlyIfDivergentTarget) {}<br>
+<br>
+PreservedAnalyses SpeculativeExecutionPass::run(Function &F,<br>
+                                                FunctionAnalysisManager &AM) {<br>
+  auto *TTI = &AM.getResult<TargetIRAnalysis>(F);<br>
+<br>
+  bool Changed = runImpl(F, TTI);<br>
+<br>
+  if (!Changed)<br>
+    return PreservedAnalyses::all();<br>
+  PreservedAnalyses PA;<br>
+  PA.preserve<GlobalsAA>();<br>
+  return PA;<br>
+}<br>
 }  // namespace llvm<br>
<br>
Modified: llvm/trunk/test/Transforms/SpeculativeExecution/spec.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SpeculativeExecution/spec.ll?rev=277393&r1=277392&r2=277393&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SpeculativeExecution/spec.ll?rev=277393&r1=277392&r2=277393&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/Transforms/SpeculativeExecution/spec.ll (original)<br>
+++ llvm/trunk/test/Transforms/SpeculativeExecution/spec.ll Mon Aug  1 16:48:33 2016<br>
@@ -1,6 +1,9 @@<br>
 ; RUN: opt < %s -S -speculative-execution \<br>
 ; RUN:   -spec-exec-max-speculation-cost 4 -spec-exec-max-not-hoisted 3 \<br>
 ; RUN:   | FileCheck %s<br>
+; RUN: opt < %s -S -passes='speculative-execution' \<br>
+; RUN:   -spec-exec-max-speculation-cost 4 -spec-exec-max-not-hoisted 3 \<br>
+; RUN:   | FileCheck %s<br>
<br>
 target datalayout = "e-i64:64-v16:16-v32:32-n16:32:64"<br>
<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">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>