1311116Sdim//===- SpeculativeExecution.h -----------------------------------*- C++ -*-===// 2311116Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6311116Sdim// 7311116Sdim//===----------------------------------------------------------------------===// 8311116Sdim// 9311116Sdim// This pass hoists instructions to enable speculative execution on 10311116Sdim// targets where branches are expensive. This is aimed at GPUs. It 11311116Sdim// currently works on simple if-then and if-then-else 12311116Sdim// patterns. 13311116Sdim// 14311116Sdim// Removing branches is not the only motivation for this 15311116Sdim// pass. E.g. consider this code and assume that there is no 16311116Sdim// addressing mode for multiplying by sizeof(*a): 17311116Sdim// 18311116Sdim// if (b > 0) 19311116Sdim// c = a[i + 1] 20311116Sdim// if (d > 0) 21311116Sdim// e = a[i + 2] 22311116Sdim// 23311116Sdim// turns into 24311116Sdim// 25311116Sdim// p = &a[i + 1]; 26311116Sdim// if (b > 0) 27311116Sdim// c = *p; 28311116Sdim// q = &a[i + 2]; 29311116Sdim// if (d > 0) 30311116Sdim// e = *q; 31311116Sdim// 32311116Sdim// which could later be optimized to 33311116Sdim// 34311116Sdim// r = &a[i]; 35311116Sdim// if (b > 0) 36311116Sdim// c = r[1]; 37311116Sdim// if (d > 0) 38311116Sdim// e = r[2]; 39311116Sdim// 40311116Sdim// Later passes sink back much of the speculated code that did not enable 41311116Sdim// further optimization. 42311116Sdim// 43311116Sdim// This pass is more aggressive than the function SpeculativeyExecuteBB in 44311116Sdim// SimplifyCFG. SimplifyCFG will not speculate if no selects are introduced and 45311116Sdim// it will speculate at most one instruction. It also will not speculate if 46311116Sdim// there is a value defined in the if-block that is only used in the then-block. 47311116Sdim// These restrictions make sense since the speculation in SimplifyCFG seems 48311116Sdim// aimed at introducing cheap selects, while this pass is intended to do more 49311116Sdim// aggressive speculation while counting on later passes to either capitalize on 50311116Sdim// that or clean it up. 51311116Sdim// 52311116Sdim// If the pass was created by calling 53311116Sdim// createSpeculativeExecutionIfHasBranchDivergencePass or the 54311116Sdim// -spec-exec-only-if-divergent-target option is present, this pass only has an 55311116Sdim// effect on targets where TargetTransformInfo::hasBranchDivergence() is true; 56311116Sdim// on other targets, it is a nop. 57311116Sdim// 58311116Sdim// This lets you include this pass unconditionally in the IR pass pipeline, but 59311116Sdim// only enable it for relevant targets. 60311116Sdim// 61311116Sdim//===----------------------------------------------------------------------===// 62311116Sdim#ifndef LLVM_TRANSFORMS_SCALAR_SPECULATIVEEXECUTION_H 63311116Sdim#define LLVM_TRANSFORMS_SCALAR_SPECULATIVEEXECUTION_H 64311116Sdim 65311116Sdim#include "llvm/Analysis/TargetTransformInfo.h" 66311116Sdim#include "llvm/IR/PassManager.h" 67311116Sdim 68311116Sdimnamespace llvm { 69311116Sdimclass SpeculativeExecutionPass 70311116Sdim : public PassInfoMixin<SpeculativeExecutionPass> { 71311116Sdimpublic: 72311116Sdim SpeculativeExecutionPass(bool OnlyIfDivergentTarget = false); 73311116Sdim 74311116Sdim PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); 75311116Sdim 76311116Sdim // Glue for old PM 77311116Sdim bool runImpl(Function &F, TargetTransformInfo *TTI); 78311116Sdim 79311116Sdimprivate: 80311116Sdim bool runOnBasicBlock(BasicBlock &B); 81311116Sdim bool considerHoistingFromTo(BasicBlock &FromBlock, BasicBlock &ToBlock); 82311116Sdim 83311116Sdim // If true, this pass is a nop unless the target architecture has branch 84341825Sdim // divergence. 85311116Sdim const bool OnlyIfDivergentTarget = false; 86311116Sdim 87311116Sdim TargetTransformInfo *TTI = nullptr; 88311116Sdim}; 89311116Sdim} 90311116Sdim 91311116Sdim#endif //LLVM_TRANSFORMS_SCALAR_SPECULATIVEEXECUTION_H 92