1//===- SpeculativeExecution.h -----------------------------------*- C++ -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// This pass hoists instructions to enable speculative execution on 10// targets where branches are expensive. This is aimed at GPUs. It 11// currently works on simple if-then and if-then-else 12// patterns. 13// 14// Removing branches is not the only motivation for this 15// pass. E.g. consider this code and assume that there is no 16// addressing mode for multiplying by sizeof(*a): 17// 18// if (b > 0) 19// c = a[i + 1] 20// if (d > 0) 21// e = a[i + 2] 22// 23// turns into 24// 25// p = &a[i + 1]; 26// if (b > 0) 27// c = *p; 28// q = &a[i + 2]; 29// if (d > 0) 30// e = *q; 31// 32// which could later be optimized to 33// 34// r = &a[i]; 35// if (b > 0) 36// c = r[1]; 37// if (d > 0) 38// e = r[2]; 39// 40// Later passes sink back much of the speculated code that did not enable 41// further optimization. 42// 43// This pass is more aggressive than the function SpeculativeyExecuteBB in 44// SimplifyCFG. SimplifyCFG will not speculate if no selects are introduced and 45// it will speculate at most one instruction. It also will not speculate if 46// there is a value defined in the if-block that is only used in the then-block. 47// These restrictions make sense since the speculation in SimplifyCFG seems 48// aimed at introducing cheap selects, while this pass is intended to do more 49// aggressive speculation while counting on later passes to either capitalize on 50// that or clean it up. 51// 52// If the pass was created by calling 53// createSpeculativeExecutionIfHasBranchDivergencePass or the 54// -spec-exec-only-if-divergent-target option is present, this pass only has an 55// effect on targets where TargetTransformInfo::hasBranchDivergence() is true; 56// on other targets, it is a nop. 57// 58// This lets you include this pass unconditionally in the IR pass pipeline, but 59// only enable it for relevant targets. 60// 61//===----------------------------------------------------------------------===// 62#ifndef LLVM_TRANSFORMS_SCALAR_SPECULATIVEEXECUTION_H 63#define LLVM_TRANSFORMS_SCALAR_SPECULATIVEEXECUTION_H 64 65#include "llvm/Analysis/TargetTransformInfo.h" 66#include "llvm/IR/PassManager.h" 67 68namespace llvm { 69class SpeculativeExecutionPass 70 : public PassInfoMixin<SpeculativeExecutionPass> { 71public: 72 SpeculativeExecutionPass(bool OnlyIfDivergentTarget = false); 73 74 PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); 75 76 // Glue for old PM 77 bool runImpl(Function &F, TargetTransformInfo *TTI); 78 79private: 80 bool runOnBasicBlock(BasicBlock &B); 81 bool considerHoistingFromTo(BasicBlock &FromBlock, BasicBlock &ToBlock); 82 83 // If true, this pass is a nop unless the target architecture has branch 84 // divergence. 85 const bool OnlyIfDivergentTarget = false; 86 87 TargetTransformInfo *TTI = nullptr; 88}; 89} 90 91#endif //LLVM_TRANSFORMS_SCALAR_SPECULATIVEEXECUTION_H 92