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