JumpThreading.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- JumpThreading.h - thread control through conditional BBs -*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. /// \file
  15. /// See the comments on JumpThreadingPass.
  16. //
  17. //===----------------------------------------------------------------------===//
  18. #ifndef LLVM_TRANSFORMS_SCALAR_JUMPTHREADING_H
  19. #define LLVM_TRANSFORMS_SCALAR_JUMPTHREADING_H
  20. #include "llvm/ADT/ArrayRef.h"
  21. #include "llvm/ADT/DenseSet.h"
  22. #include "llvm/ADT/SmallPtrSet.h"
  23. #include "llvm/ADT/SmallSet.h"
  24. #include "llvm/ADT/SmallVector.h"
  25. #include "llvm/Analysis/BlockFrequencyInfo.h"
  26. #include "llvm/Analysis/BranchProbabilityInfo.h"
  27. #include "llvm/Analysis/DomTreeUpdater.h"
  28. #include "llvm/IR/ValueHandle.h"
  29. #include <memory>
  30. #include <utility>
  31. namespace llvm {
  32. class AAResults;
  33. class BasicBlock;
  34. class BinaryOperator;
  35. class BranchInst;
  36. class CmpInst;
  37. class Constant;
  38. class DomTreeUpdater;
  39. class Function;
  40. class Instruction;
  41. class IntrinsicInst;
  42. class LazyValueInfo;
  43. class LoadInst;
  44. class PHINode;
  45. class SelectInst;
  46. class SwitchInst;
  47. class TargetLibraryInfo;
  48. class TargetTransformInfo;
  49. class Value;
  50. /// A private "module" namespace for types and utilities used by
  51. /// JumpThreading.
  52. /// These are implementation details and should not be used by clients.
  53. namespace jumpthreading {
  54. // These are at global scope so static functions can use them too.
  55. using PredValueInfo = SmallVectorImpl<std::pair<Constant *, BasicBlock *>>;
  56. using PredValueInfoTy = SmallVector<std::pair<Constant *, BasicBlock *>, 8>;
  57. // This is used to keep track of what kind of constant we're currently hoping
  58. // to find.
  59. enum ConstantPreference { WantInteger, WantBlockAddress };
  60. } // end namespace jumpthreading
  61. /// This pass performs 'jump threading', which looks at blocks that have
  62. /// multiple predecessors and multiple successors. If one or more of the
  63. /// predecessors of the block can be proven to always jump to one of the
  64. /// successors, we forward the edge from the predecessor to the successor by
  65. /// duplicating the contents of this block.
  66. ///
  67. /// An example of when this can occur is code like this:
  68. ///
  69. /// if () { ...
  70. /// X = 4;
  71. /// }
  72. /// if (X < 3) {
  73. ///
  74. /// In this case, the unconditional branch at the end of the first if can be
  75. /// revectored to the false side of the second if.
  76. class JumpThreadingPass : public PassInfoMixin<JumpThreadingPass> {
  77. TargetLibraryInfo *TLI;
  78. TargetTransformInfo *TTI;
  79. LazyValueInfo *LVI;
  80. AAResults *AA;
  81. DomTreeUpdater *DTU;
  82. std::unique_ptr<BlockFrequencyInfo> BFI;
  83. std::unique_ptr<BranchProbabilityInfo> BPI;
  84. bool HasProfileData = false;
  85. bool HasGuards = false;
  86. #ifndef LLVM_ENABLE_ABI_BREAKING_CHECKS
  87. SmallPtrSet<const BasicBlock *, 16> LoopHeaders;
  88. #else
  89. SmallSet<AssertingVH<const BasicBlock>, 16> LoopHeaders;
  90. #endif
  91. unsigned BBDupThreshold;
  92. unsigned DefaultBBDupThreshold;
  93. bool InsertFreezeWhenUnfoldingSelect;
  94. public:
  95. JumpThreadingPass(bool InsertFreezeWhenUnfoldingSelect = false, int T = -1);
  96. // Glue for old PM.
  97. bool runImpl(Function &F, TargetLibraryInfo *TLI, TargetTransformInfo *TTI,
  98. LazyValueInfo *LVI, AAResults *AA, DomTreeUpdater *DTU,
  99. bool HasProfileData, std::unique_ptr<BlockFrequencyInfo> BFI,
  100. std::unique_ptr<BranchProbabilityInfo> BPI);
  101. PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
  102. void releaseMemory() {
  103. BFI.reset();
  104. BPI.reset();
  105. }
  106. void findLoopHeaders(Function &F);
  107. bool processBlock(BasicBlock *BB);
  108. bool maybeMergeBasicBlockIntoOnlyPred(BasicBlock *BB);
  109. void updateSSA(BasicBlock *BB, BasicBlock *NewBB,
  110. DenseMap<Instruction *, Value *> &ValueMapping);
  111. DenseMap<Instruction *, Value *> cloneInstructions(BasicBlock::iterator BI,
  112. BasicBlock::iterator BE,
  113. BasicBlock *NewBB,
  114. BasicBlock *PredBB);
  115. bool tryThreadEdge(BasicBlock *BB,
  116. const SmallVectorImpl<BasicBlock *> &PredBBs,
  117. BasicBlock *SuccBB);
  118. void threadEdge(BasicBlock *BB, const SmallVectorImpl<BasicBlock *> &PredBBs,
  119. BasicBlock *SuccBB);
  120. bool duplicateCondBranchOnPHIIntoPred(
  121. BasicBlock *BB, const SmallVectorImpl<BasicBlock *> &PredBBs);
  122. bool computeValueKnownInPredecessorsImpl(
  123. Value *V, BasicBlock *BB, jumpthreading::PredValueInfo &Result,
  124. jumpthreading::ConstantPreference Preference,
  125. DenseSet<Value *> &RecursionSet, Instruction *CxtI = nullptr);
  126. bool
  127. computeValueKnownInPredecessors(Value *V, BasicBlock *BB,
  128. jumpthreading::PredValueInfo &Result,
  129. jumpthreading::ConstantPreference Preference,
  130. Instruction *CxtI = nullptr) {
  131. DenseSet<Value *> RecursionSet;
  132. return computeValueKnownInPredecessorsImpl(V, BB, Result, Preference,
  133. RecursionSet, CxtI);
  134. }
  135. Constant *evaluateOnPredecessorEdge(BasicBlock *BB, BasicBlock *PredPredBB,
  136. Value *cond);
  137. bool maybethreadThroughTwoBasicBlocks(BasicBlock *BB, Value *Cond);
  138. void threadThroughTwoBasicBlocks(BasicBlock *PredPredBB, BasicBlock *PredBB,
  139. BasicBlock *BB, BasicBlock *SuccBB);
  140. bool processThreadableEdges(Value *Cond, BasicBlock *BB,
  141. jumpthreading::ConstantPreference Preference,
  142. Instruction *CxtI = nullptr);
  143. bool processBranchOnPHI(PHINode *PN);
  144. bool processBranchOnXOR(BinaryOperator *BO);
  145. bool processImpliedCondition(BasicBlock *BB);
  146. bool simplifyPartiallyRedundantLoad(LoadInst *LI);
  147. void unfoldSelectInstr(BasicBlock *Pred, BasicBlock *BB, SelectInst *SI,
  148. PHINode *SIUse, unsigned Idx);
  149. bool tryToUnfoldSelect(CmpInst *CondCmp, BasicBlock *BB);
  150. bool tryToUnfoldSelect(SwitchInst *SI, BasicBlock *BB);
  151. bool tryToUnfoldSelectInCurrBB(BasicBlock *BB);
  152. bool processGuards(BasicBlock *BB);
  153. bool threadGuard(BasicBlock *BB, IntrinsicInst *Guard, BranchInst *BI);
  154. private:
  155. BasicBlock *splitBlockPreds(BasicBlock *BB, ArrayRef<BasicBlock *> Preds,
  156. const char *Suffix);
  157. void updateBlockFreqAndEdgeWeight(BasicBlock *PredBB, BasicBlock *BB,
  158. BasicBlock *NewBB, BasicBlock *SuccBB);
  159. /// Check if the block has profile metadata for its outgoing edges.
  160. bool doesBlockHaveProfileData(BasicBlock *BB);
  161. };
  162. } // end namespace llvm
  163. #endif // LLVM_TRANSFORMS_SCALAR_JUMPTHREADING_H
  164. #ifdef __GNUC__
  165. #pragma GCC diagnostic pop
  166. #endif