<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>