mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-21 20:12:56 +02:00
3948eae2ef
Differential Revision: https://reviews.llvm.org/D23033 llvm-svn: 277393
93 lines
3.0 KiB
C++
93 lines
3.0 KiB
C++
//===- SpeculativeExecution.h -----------------------------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This pass hoists instructions to enable speculative execution on
|
|
// targets where branches are expensive. This is aimed at GPUs. It
|
|
// currently works on simple if-then and if-then-else
|
|
// patterns.
|
|
//
|
|
// Removing branches is not the only motivation for this
|
|
// pass. E.g. consider this code and assume that there is no
|
|
// addressing mode for multiplying by sizeof(*a):
|
|
//
|
|
// if (b > 0)
|
|
// c = a[i + 1]
|
|
// if (d > 0)
|
|
// e = a[i + 2]
|
|
//
|
|
// turns into
|
|
//
|
|
// p = &a[i + 1];
|
|
// if (b > 0)
|
|
// c = *p;
|
|
// q = &a[i + 2];
|
|
// if (d > 0)
|
|
// e = *q;
|
|
//
|
|
// which could later be optimized to
|
|
//
|
|
// r = &a[i];
|
|
// if (b > 0)
|
|
// c = r[1];
|
|
// if (d > 0)
|
|
// e = r[2];
|
|
//
|
|
// Later passes sink back much of the speculated code that did not enable
|
|
// further optimization.
|
|
//
|
|
// This pass is more aggressive than the function SpeculativeyExecuteBB in
|
|
// SimplifyCFG. SimplifyCFG will not speculate if no selects are introduced and
|
|
// it will speculate at most one instruction. It also will not speculate if
|
|
// there is a value defined in the if-block that is only used in the then-block.
|
|
// These restrictions make sense since the speculation in SimplifyCFG seems
|
|
// aimed at introducing cheap selects, while this pass is intended to do more
|
|
// aggressive speculation while counting on later passes to either capitalize on
|
|
// that or clean it up.
|
|
//
|
|
// If the pass was created by calling
|
|
// createSpeculativeExecutionIfHasBranchDivergencePass or the
|
|
// -spec-exec-only-if-divergent-target option is present, this pass only has an
|
|
// effect on targets where TargetTransformInfo::hasBranchDivergence() is true;
|
|
// on other targets, it is a nop.
|
|
//
|
|
// This lets you include this pass unconditionally in the IR pass pipeline, but
|
|
// only enable it for relevant targets.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
#ifndef LLVM_TRANSFORMS_SCALAR_SPECULATIVEEXECUTION_H
|
|
#define LLVM_TRANSFORMS_SCALAR_SPECULATIVEEXECUTION_H
|
|
|
|
#include "llvm/Analysis/TargetTransformInfo.h"
|
|
#include "llvm/IR/PassManager.h"
|
|
|
|
namespace llvm {
|
|
class SpeculativeExecutionPass
|
|
: public PassInfoMixin<SpeculativeExecutionPass> {
|
|
public:
|
|
SpeculativeExecutionPass(bool OnlyIfDivergentTarget = false);
|
|
|
|
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
|
|
|
// Glue for old PM
|
|
bool runImpl(Function &F, TargetTransformInfo *TTI);
|
|
|
|
private:
|
|
bool runOnBasicBlock(BasicBlock &B);
|
|
bool considerHoistingFromTo(BasicBlock &FromBlock, BasicBlock &ToBlock);
|
|
|
|
// If true, this pass is a nop unless the target architecture has branch
|
|
// divergence.
|
|
const bool OnlyIfDivergentTarget = false;
|
|
|
|
TargetTransformInfo *TTI = nullptr;
|
|
};
|
|
}
|
|
|
|
#endif //LLVM_TRANSFORMS_SCALAR_SPECULATIVEEXECUTION_H
|