File indexing completed on 2026-05-10 08:44:41
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #ifndef LLVM_TRANSFORMS_SCALAR_CONSTANTHOISTING_H
0037 #define LLVM_TRANSFORMS_SCALAR_CONSTANTHOISTING_H
0038
0039 #include "llvm/ADT/ArrayRef.h"
0040 #include "llvm/ADT/DenseMap.h"
0041 #include "llvm/ADT/MapVector.h"
0042 #include "llvm/ADT/PointerUnion.h"
0043 #include "llvm/ADT/SetVector.h"
0044 #include "llvm/ADT/SmallVector.h"
0045 #include "llvm/IR/BasicBlock.h"
0046 #include "llvm/IR/PassManager.h"
0047 #include <algorithm>
0048 #include <vector>
0049
0050 namespace llvm {
0051
0052 class BasicBlock;
0053 class BlockFrequencyInfo;
0054 class Constant;
0055 class ConstantInt;
0056 class ConstantExpr;
0057 class DominatorTree;
0058 class Function;
0059 class GlobalVariable;
0060 class Instruction;
0061 class ProfileSummaryInfo;
0062 class TargetTransformInfo;
0063 class TargetTransformInfo;
0064
0065
0066
0067
0068 namespace consthoist {
0069
0070
0071
0072 struct ConstantUser {
0073 Instruction *Inst;
0074 unsigned OpndIdx;
0075
0076 ConstantUser(Instruction *Inst, unsigned Idx) : Inst(Inst), OpndIdx(Idx) {}
0077 };
0078
0079 using ConstantUseListType = SmallVector<ConstantUser, 8>;
0080
0081
0082 struct ConstantCandidate {
0083 ConstantUseListType Uses;
0084
0085
0086
0087 ConstantInt *ConstInt;
0088 ConstantExpr *ConstExpr;
0089 unsigned CumulativeCost = 0;
0090
0091 ConstantCandidate(ConstantInt *ConstInt, ConstantExpr *ConstExpr=nullptr) :
0092 ConstInt(ConstInt), ConstExpr(ConstExpr) {}
0093
0094
0095 void addUser(Instruction *Inst, unsigned Idx, unsigned Cost) {
0096 CumulativeCost += Cost;
0097 Uses.push_back(ConstantUser(Inst, Idx));
0098 }
0099 };
0100
0101
0102
0103 struct RebasedConstantInfo {
0104 ConstantUseListType Uses;
0105 Constant *Offset;
0106 Type *Ty;
0107
0108 RebasedConstantInfo(ConstantUseListType &&Uses, Constant *Offset,
0109 Type *Ty=nullptr) : Uses(std::move(Uses)), Offset(Offset), Ty(Ty) {}
0110 };
0111
0112 using RebasedConstantListType = SmallVector<RebasedConstantInfo, 4>;
0113
0114
0115 struct ConstantInfo {
0116
0117
0118
0119 ConstantInt *BaseInt;
0120 ConstantExpr *BaseExpr;
0121 RebasedConstantListType RebasedConstants;
0122 };
0123
0124 }
0125
0126 class ConstantHoistingPass : public PassInfoMixin<ConstantHoistingPass> {
0127 public:
0128 PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
0129
0130
0131 bool runImpl(Function &F, TargetTransformInfo &TTI, DominatorTree &DT,
0132 BlockFrequencyInfo *BFI, BasicBlock &Entry,
0133 ProfileSummaryInfo *PSI);
0134
0135 void cleanup() {
0136 ClonedCastMap.clear();
0137 ConstIntCandVec.clear();
0138 for (auto MapEntry : ConstGEPCandMap)
0139 MapEntry.second.clear();
0140 ConstGEPCandMap.clear();
0141 ConstIntInfoVec.clear();
0142 for (auto MapEntry : ConstGEPInfoMap)
0143 MapEntry.second.clear();
0144 ConstGEPInfoMap.clear();
0145 }
0146
0147 private:
0148 using ConstPtrUnionType = PointerUnion<ConstantInt *, ConstantExpr *>;
0149 using ConstCandMapType = DenseMap<ConstPtrUnionType, unsigned>;
0150
0151 const TargetTransformInfo *TTI;
0152 DominatorTree *DT;
0153 BlockFrequencyInfo *BFI;
0154 LLVMContext *Ctx;
0155 const DataLayout *DL;
0156 BasicBlock *Entry;
0157 ProfileSummaryInfo *PSI;
0158 bool OptForSize;
0159
0160
0161 using ConstCandVecType = std::vector<consthoist::ConstantCandidate>;
0162 using GVCandVecMapType = MapVector<GlobalVariable *, ConstCandVecType>;
0163 ConstCandVecType ConstIntCandVec;
0164 GVCandVecMapType ConstGEPCandMap;
0165
0166
0167 using ConstInfoVecType = SmallVector<consthoist::ConstantInfo, 8>;
0168 using GVInfoVecMapType = MapVector<GlobalVariable *, ConstInfoVecType>;
0169 ConstInfoVecType ConstIntInfoVec;
0170 GVInfoVecMapType ConstGEPInfoMap;
0171
0172
0173 MapVector<Instruction *, Instruction *> ClonedCastMap;
0174
0175 void collectMatInsertPts(
0176 const consthoist::RebasedConstantListType &RebasedConstants,
0177 SmallVectorImpl<BasicBlock::iterator> &MatInsertPts) const;
0178 BasicBlock::iterator findMatInsertPt(Instruction *Inst,
0179 unsigned Idx = ~0U) const;
0180 SetVector<BasicBlock::iterator> findConstantInsertionPoint(
0181 const consthoist::ConstantInfo &ConstInfo,
0182 const ArrayRef<BasicBlock::iterator> MatInsertPts) const;
0183 void collectConstantCandidates(ConstCandMapType &ConstCandMap,
0184 Instruction *Inst, unsigned Idx,
0185 ConstantInt *ConstInt);
0186 void collectConstantCandidates(ConstCandMapType &ConstCandMap,
0187 Instruction *Inst, unsigned Idx,
0188 ConstantExpr *ConstExpr);
0189 void collectConstantCandidates(ConstCandMapType &ConstCandMap,
0190 Instruction *Inst, unsigned Idx);
0191 void collectConstantCandidates(ConstCandMapType &ConstCandMap,
0192 Instruction *Inst);
0193 void collectConstantCandidates(Function &Fn);
0194 void findAndMakeBaseConstant(ConstCandVecType::iterator S,
0195 ConstCandVecType::iterator E,
0196 SmallVectorImpl<consthoist::ConstantInfo> &ConstInfoVec);
0197 unsigned maximizeConstantsInRange(ConstCandVecType::iterator S,
0198 ConstCandVecType::iterator E,
0199 ConstCandVecType::iterator &MaxCostItr);
0200
0201
0202 void findBaseConstants(GlobalVariable *BaseGV);
0203
0204
0205
0206 struct UserAdjustment {
0207 Constant *Offset;
0208 Type *Ty;
0209 BasicBlock::iterator MatInsertPt;
0210 const consthoist::ConstantUser User;
0211 UserAdjustment(Constant *O, Type *T, BasicBlock::iterator I,
0212 consthoist::ConstantUser U)
0213 : Offset(O), Ty(T), MatInsertPt(I), User(U) {}
0214 };
0215 void emitBaseConstants(Instruction *Base, UserAdjustment *Adj);
0216
0217
0218 bool emitBaseConstants(GlobalVariable *BaseGV);
0219 void deleteDeadCastInst() const;
0220 };
0221
0222 }
0223
0224 #endif