Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  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/IR/PassManager.h"
  66.  
  67. namespace llvm {
  68. class TargetTransformInfo;
  69. class SpeculativeExecutionPass
  70.     : public PassInfoMixin<SpeculativeExecutionPass> {
  71. public:
  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.  
  79. private:
  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.