123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===- SpeculativeExecution.h -----------------------------------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // 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/IR/PassManager.h"
- namespace llvm {
- class TargetTransformInfo;
- 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
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|