ConstantHoisting.h 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. //==- ConstantHoisting.h - Prepare code for expensive constants --*- 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 identifies expensive constants to hoist and coalesces them to
  10. // better prepare it for SelectionDAG-based code generation. This works around
  11. // the limitations of the basic-block-at-a-time approach.
  12. //
  13. // First it scans all instructions for integer constants and calculates its
  14. // cost. If the constant can be folded into the instruction (the cost is
  15. // TCC_Free) or the cost is just a simple operation (TCC_BASIC), then we don't
  16. // consider it expensive and leave it alone. This is the default behavior and
  17. // the default implementation of getIntImmCostInst will always return TCC_Free.
  18. //
  19. // If the cost is more than TCC_BASIC, then the integer constant can't be folded
  20. // into the instruction and it might be beneficial to hoist the constant.
  21. // Similar constants are coalesced to reduce register pressure and
  22. // materialization code.
  23. //
  24. // When a constant is hoisted, it is also hidden behind a bitcast to force it to
  25. // be live-out of the basic block. Otherwise the constant would be just
  26. // duplicated and each basic block would have its own copy in the SelectionDAG.
  27. // The SelectionDAG recognizes such constants as opaque and doesn't perform
  28. // certain transformations on them, which would create a new expensive constant.
  29. //
  30. // This optimization is only applied to integer constants in instructions and
  31. // simple (this means not nested) constant cast expressions. For example:
  32. // %0 = load i64* inttoptr (i64 big_constant to i64*)
  33. //
  34. //===----------------------------------------------------------------------===//
  35. #ifndef LLVM_TRANSFORMS_SCALAR_CONSTANTHOISTING_H
  36. #define LLVM_TRANSFORMS_SCALAR_CONSTANTHOISTING_H
  37. #include "llvm/ADT/DenseMap.h"
  38. #include "llvm/ADT/MapVector.h"
  39. #include "llvm/ADT/PointerUnion.h"
  40. #include "llvm/ADT/SetVector.h"
  41. #include "llvm/ADT/SmallPtrSet.h"
  42. #include "llvm/ADT/SmallVector.h"
  43. #include "llvm/IR/PassManager.h"
  44. #include <algorithm>
  45. #include <vector>
  46. namespace llvm {
  47. class BasicBlock;
  48. class BlockFrequencyInfo;
  49. class Constant;
  50. class ConstantInt;
  51. class ConstantExpr;
  52. class DominatorTree;
  53. class Function;
  54. class GlobalVariable;
  55. class Instruction;
  56. class ProfileSummaryInfo;
  57. class TargetTransformInfo;
  58. /// A private "module" namespace for types and utilities used by
  59. /// ConstantHoisting. These are implementation details and should not be used by
  60. /// clients.
  61. namespace consthoist {
  62. /// Keeps track of the user of a constant and the operand index where the
  63. /// constant is used.
  64. struct ConstantUser {
  65. Instruction *Inst;
  66. unsigned OpndIdx;
  67. ConstantUser(Instruction *Inst, unsigned Idx) : Inst(Inst), OpndIdx(Idx) {}
  68. };
  69. using ConstantUseListType = SmallVector<ConstantUser, 8>;
  70. /// Keeps track of a constant candidate and its uses.
  71. struct ConstantCandidate {
  72. ConstantUseListType Uses;
  73. // If the candidate is a ConstantExpr (currely only constant GEP expressions
  74. // whose base pointers are GlobalVariables are supported), ConstInt records
  75. // its offset from the base GV, ConstExpr tracks the candidate GEP expr.
  76. ConstantInt *ConstInt;
  77. ConstantExpr *ConstExpr;
  78. unsigned CumulativeCost = 0;
  79. ConstantCandidate(ConstantInt *ConstInt, ConstantExpr *ConstExpr=nullptr) :
  80. ConstInt(ConstInt), ConstExpr(ConstExpr) {}
  81. /// Add the user to the use list and update the cost.
  82. void addUser(Instruction *Inst, unsigned Idx, unsigned Cost) {
  83. CumulativeCost += Cost;
  84. Uses.push_back(ConstantUser(Inst, Idx));
  85. }
  86. };
  87. /// This represents a constant that has been rebased with respect to a
  88. /// base constant. The difference to the base constant is recorded in Offset.
  89. struct RebasedConstantInfo {
  90. ConstantUseListType Uses;
  91. Constant *Offset;
  92. Type *Ty;
  93. RebasedConstantInfo(ConstantUseListType &&Uses, Constant *Offset,
  94. Type *Ty=nullptr) : Uses(std::move(Uses)), Offset(Offset), Ty(Ty) {}
  95. };
  96. using RebasedConstantListType = SmallVector<RebasedConstantInfo, 4>;
  97. /// A base constant and all its rebased constants.
  98. struct ConstantInfo {
  99. // If the candidate is a ConstantExpr (currely only constant GEP expressions
  100. // whose base pointers are GlobalVariables are supported), ConstInt records
  101. // its offset from the base GV, ConstExpr tracks the candidate GEP expr.
  102. ConstantInt *BaseInt;
  103. ConstantExpr *BaseExpr;
  104. RebasedConstantListType RebasedConstants;
  105. };
  106. } // end namespace consthoist
  107. class ConstantHoistingPass : public PassInfoMixin<ConstantHoistingPass> {
  108. public:
  109. PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
  110. // Glue for old PM.
  111. bool runImpl(Function &F, TargetTransformInfo &TTI, DominatorTree &DT,
  112. BlockFrequencyInfo *BFI, BasicBlock &Entry,
  113. ProfileSummaryInfo *PSI);
  114. void cleanup() {
  115. ClonedCastMap.clear();
  116. ConstIntCandVec.clear();
  117. for (auto MapEntry : ConstGEPCandMap)
  118. MapEntry.second.clear();
  119. ConstGEPCandMap.clear();
  120. ConstIntInfoVec.clear();
  121. for (auto MapEntry : ConstGEPInfoMap)
  122. MapEntry.second.clear();
  123. ConstGEPInfoMap.clear();
  124. }
  125. private:
  126. using ConstPtrUnionType = PointerUnion<ConstantInt *, ConstantExpr *>;
  127. using ConstCandMapType = DenseMap<ConstPtrUnionType, unsigned>;
  128. const TargetTransformInfo *TTI;
  129. DominatorTree *DT;
  130. BlockFrequencyInfo *BFI;
  131. LLVMContext *Ctx;
  132. const DataLayout *DL;
  133. BasicBlock *Entry;
  134. ProfileSummaryInfo *PSI;
  135. /// Keeps track of constant candidates found in the function.
  136. using ConstCandVecType = std::vector<consthoist::ConstantCandidate>;
  137. using GVCandVecMapType = MapVector<GlobalVariable *, ConstCandVecType>;
  138. ConstCandVecType ConstIntCandVec;
  139. GVCandVecMapType ConstGEPCandMap;
  140. /// These are the final constants we decided to hoist.
  141. using ConstInfoVecType = SmallVector<consthoist::ConstantInfo, 8>;
  142. using GVInfoVecMapType = MapVector<GlobalVariable *, ConstInfoVecType>;
  143. ConstInfoVecType ConstIntInfoVec;
  144. GVInfoVecMapType ConstGEPInfoMap;
  145. /// Keep track of cast instructions we already cloned.
  146. MapVector<Instruction *, Instruction *> ClonedCastMap;
  147. Instruction *findMatInsertPt(Instruction *Inst, unsigned Idx = ~0U) const;
  148. SetVector<Instruction *>
  149. findConstantInsertionPoint(const consthoist::ConstantInfo &ConstInfo) const;
  150. void collectConstantCandidates(ConstCandMapType &ConstCandMap,
  151. Instruction *Inst, unsigned Idx,
  152. ConstantInt *ConstInt);
  153. void collectConstantCandidates(ConstCandMapType &ConstCandMap,
  154. Instruction *Inst, unsigned Idx,
  155. ConstantExpr *ConstExpr);
  156. void collectConstantCandidates(ConstCandMapType &ConstCandMap,
  157. Instruction *Inst, unsigned Idx);
  158. void collectConstantCandidates(ConstCandMapType &ConstCandMap,
  159. Instruction *Inst);
  160. void collectConstantCandidates(Function &Fn);
  161. void findAndMakeBaseConstant(ConstCandVecType::iterator S,
  162. ConstCandVecType::iterator E,
  163. SmallVectorImpl<consthoist::ConstantInfo> &ConstInfoVec);
  164. unsigned maximizeConstantsInRange(ConstCandVecType::iterator S,
  165. ConstCandVecType::iterator E,
  166. ConstCandVecType::iterator &MaxCostItr);
  167. // If BaseGV is nullptr, find base among Constant Integer candidates;
  168. // otherwise find base among constant GEPs sharing BaseGV as base pointer.
  169. void findBaseConstants(GlobalVariable *BaseGV);
  170. void emitBaseConstants(Instruction *Base, Constant *Offset, Type *Ty,
  171. const consthoist::ConstantUser &ConstUser);
  172. // If BaseGV is nullptr, emit Constant Integer base; otherwise emit
  173. // constant GEP base.
  174. bool emitBaseConstants(GlobalVariable *BaseGV);
  175. void deleteDeadCastInst() const;
  176. };
  177. } // end namespace llvm
  178. #endif // LLVM_TRANSFORMS_SCALAR_CONSTANTHOISTING_H