1 //===-- PPCMergeStringPool.cpp -------------------------------------------===// 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 transformation tries to merge the strings in the module into one pool 10 // of strings. The idea is to reduce the number of TOC entries in the module so 11 // that instead of having one TOC entry for each string there is only one global 12 // TOC entry and all of the strings are referenced off of that one entry plus 13 // an offset. 14 // 15 //===----------------------------------------------------------------------===// 16 17 #include "PPC.h" 18 #include "llvm/ADT/Statistic.h" 19 #include "llvm/Analysis/DomTreeUpdater.h" 20 #include "llvm/Analysis/LoopInfo.h" 21 #include "llvm/Analysis/LoopIterator.h" 22 #include "llvm/Analysis/ScalarEvolution.h" 23 #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" 24 #include "llvm/IR/Constants.h" 25 #include "llvm/IR/Instructions.h" 26 #include "llvm/IR/Module.h" 27 #include "llvm/IR/ValueSymbolTable.h" 28 #include "llvm/Pass.h" 29 #include "llvm/Support/CommandLine.h" 30 31 #define DEBUG_TYPE "ppc-merge-strings" 32 33 STATISTIC(NumPooledStrings, "Number of Strings Pooled"); 34 35 using namespace llvm; 36 37 static cl::opt<unsigned> 38 MaxStringsPooled("ppc-max-strings-pooled", cl::Hidden, cl::init(-1), 39 cl::desc("Maximum Number of Strings to Pool.")); 40 41 static cl::opt<unsigned> 42 MinStringsBeforePool("ppc-min-strings-before-pool", cl::Hidden, cl::init(2), 43 cl::desc("Minimum number of string candidates before " 44 "pooling is considered.")); 45 46 namespace { 47 struct { 48 bool operator()(const GlobalVariable *LHS, const GlobalVariable *RHS) const { 49 // First priority is alignment. 50 // If elements are sorted in terms of alignment then there won't be an 51 // issue with incorrect alignment that would require padding. 52 Align LHSAlign = LHS->getAlign().valueOrOne(); 53 Align RHSAlign = RHS->getAlign().valueOrOne(); 54 if (LHSAlign > RHSAlign) 55 return true; 56 else if (LHSAlign < RHSAlign) 57 return false; 58 59 // Next priority is the number of uses. 60 // Smaller offsets are easier to materialize because materializing a large 61 // offset may require more than one instruction. (ie addis, addi). 62 if (LHS->getNumUses() > RHS->getNumUses()) 63 return true; 64 else if (LHS->getNumUses() < RHS->getNumUses()) 65 return false; 66 67 const Constant *ConstLHS = LHS->getInitializer(); 68 const ConstantDataSequential *ConstDataLHS = 69 dyn_cast<ConstantDataSequential>(ConstLHS); 70 unsigned LHSSize = 71 ConstDataLHS->getNumElements() * ConstDataLHS->getElementByteSize(); 72 const Constant *ConstRHS = RHS->getInitializer(); 73 const ConstantDataSequential *ConstDataRHS = 74 dyn_cast<ConstantDataSequential>(ConstRHS); 75 unsigned RHSSize = 76 ConstDataRHS->getNumElements() * ConstDataRHS->getElementByteSize(); 77 78 // Finally smaller constants should go first. This is, again, trying to 79 // minimize the offsets into the final struct. 80 return LHSSize < RHSSize; 81 } 82 } CompareConstants; 83 84 class PPCMergeStringPool : public ModulePass { 85 public: 86 static char ID; 87 PPCMergeStringPool() : ModulePass(ID) {} 88 89 bool runOnModule(Module &M) override { return mergeModuleStringPool(M); } 90 91 StringRef getPassName() const override { return "PPC Merge String Pool"; } 92 93 void getAnalysisUsage(AnalysisUsage &AU) const override { 94 AU.addPreserved<DominatorTreeWrapperPass>(); 95 AU.addPreserved<LoopInfoWrapperPass>(); 96 AU.addPreserved<ScalarEvolutionWrapperPass>(); 97 AU.addPreserved<SCEVAAWrapperPass>(); 98 } 99 100 private: 101 // Globals in a Module are already unique so a set is not required and a 102 // vector will do. 103 std::vector<GlobalVariable *> MergeableStrings; 104 Align MaxAlignment; 105 Type *PooledStructType; 106 LLVMContext *Context; 107 void collectCandidateConstants(Module &M); 108 bool mergeModuleStringPool(Module &M); 109 void replaceUsesWithGEP(GlobalVariable *GlobalToReplace, GlobalVariable *GPool, 110 unsigned ElementIndex); 111 }; 112 113 114 // In order for a constant to be pooled we need to be able to replace all of 115 // the uses for that constant. This function checks all of the uses to make 116 // sure that they can be replaced. 117 static bool hasReplaceableUsers(GlobalVariable &GV) { 118 for (User *CurrentUser : GV.users()) { 119 // Instruction users are always valid. 120 if (isa<Instruction>(CurrentUser)) 121 continue; 122 123 // We cannot replace GlobalValue users because they are not just nodes 124 // in IR. To replace a user like this we would need to create a new 125 // GlobalValue with the replacement and then try to delete the original 126 // GlobalValue. Deleting the original would only happen if it has no other 127 // uses. 128 if (isa<GlobalValue>(CurrentUser)) 129 return false; 130 131 // We only support Instruction and Constant users. 132 if (!isa<Constant>(CurrentUser)) 133 return false; 134 } 135 136 return true; 137 } 138 139 // Run through all of the constants in the module and determine if they are 140 // valid candidates to be merged into the string pool. Valid candidates will 141 // be added to MergeableStrings. 142 void PPCMergeStringPool::collectCandidateConstants(Module &M) { 143 SmallVector<GlobalValue *, 4> UsedV; 144 collectUsedGlobalVariables(M, UsedV, /*CompilerUsed=*/false); 145 SmallVector<GlobalValue *, 4> UsedVCompiler; 146 collectUsedGlobalVariables(M, UsedVCompiler, /*CompilerUsed=*/true); 147 // Combine all of the Global Variables marked as used into a SmallPtrSet for 148 // faster lookup inside the loop. 149 SmallPtrSet<GlobalValue *, 8> AllUsedGlobals; 150 AllUsedGlobals.insert(UsedV.begin(), UsedV.end()); 151 AllUsedGlobals.insert(UsedVCompiler.begin(), UsedVCompiler.end()); 152 153 for (GlobalVariable &Global : M.globals()) { 154 LLVM_DEBUG(dbgs() << "Looking at global:"); 155 LLVM_DEBUG(Global.dump()); 156 LLVM_DEBUG(dbgs() << "isConstant() " << Global.isConstant() << "\n"); 157 LLVM_DEBUG(dbgs() << "hasInitializer() " << Global.hasInitializer() 158 << "\n"); 159 160 // We can only pool constants. 161 if (!Global.isConstant() || !Global.hasInitializer()) 162 continue; 163 164 // If a global constant has a section we do not try to pool it because 165 // there is no guarantee that other constants will also be in the same 166 // section. Trying to pool constants from different sections (or no 167 // section) means that the pool has to be in multiple sections at the same 168 // time. 169 if (Global.hasSection()) 170 continue; 171 172 // Do not pool constants with metadata because we should not add metadata 173 // to the pool when that metadata refers to a single constant in the pool. 174 if (Global.hasMetadata()) 175 continue; 176 177 ConstantDataSequential *ConstData = 178 dyn_cast<ConstantDataSequential>(Global.getInitializer()); 179 180 // If the constant is undef then ConstData will be null. 181 if (!ConstData) 182 continue; 183 184 // Do not pool globals that are part of llvm.used or llvm.compiler.end. 185 if (AllUsedGlobals.contains(&Global)) 186 continue; 187 188 if (!hasReplaceableUsers(Global)) 189 continue; 190 191 Align AlignOfGlobal = Global.getAlign().valueOrOne(); 192 193 // TODO: At this point do not allow over-aligned types. Adding a type 194 // with larger alignment may lose the larger alignment once it is 195 // added to the struct. 196 // Fix this in a future patch. 197 if (AlignOfGlobal.value() > ConstData->getElementByteSize()) 198 continue; 199 200 // Make sure that the global is only visible inside the compilation unit. 201 if (Global.getLinkage() != GlobalValue::PrivateLinkage && 202 Global.getLinkage() != GlobalValue::InternalLinkage) 203 continue; 204 205 LLVM_DEBUG(dbgs() << "Constant data of Global: "); 206 LLVM_DEBUG(ConstData->dump()); 207 LLVM_DEBUG(dbgs() << "\n\n"); 208 209 MergeableStrings.push_back(&Global); 210 if (MaxAlignment < AlignOfGlobal) 211 MaxAlignment = AlignOfGlobal; 212 213 // If we have already reached the maximum number of pooled strings then 214 // there is no point in looking for more. 215 if (MergeableStrings.size() >= MaxStringsPooled) 216 break; 217 } 218 } 219 220 bool PPCMergeStringPool::mergeModuleStringPool(Module &M) { 221 222 LLVM_DEBUG(dbgs() << "Merging string pool for module: " << M.getName() 223 << "\n"); 224 LLVM_DEBUG(dbgs() << "Number of globals is: " << M.global_size() << "\n"); 225 226 collectCandidateConstants(M); 227 228 // If we have too few constants in the module that are merge candidates we 229 // will skip doing the merging. 230 if (MergeableStrings.size() < MinStringsBeforePool) 231 return false; 232 233 // Sort the global constants to make access more efficient. 234 std::sort(MergeableStrings.begin(), MergeableStrings.end(), CompareConstants); 235 236 SmallVector<Constant *> ConstantsInStruct; 237 for (GlobalVariable *GV : MergeableStrings) 238 ConstantsInStruct.push_back(GV->getInitializer()); 239 240 // Use an anonymous struct to pool the strings. 241 // TODO: This pass uses a single anonymous struct for all of the pooled 242 // entries. This may cause a performance issue in the situation where 243 // computing the offset requires two instructions (addis, addi). For the 244 // future we may want to split this into multiple structs. 245 Constant *ConstantPool = ConstantStruct::getAnon(ConstantsInStruct); 246 PooledStructType = ConstantPool->getType(); 247 248 // The GlobalVariable constructor calls 249 // MM->insertGlobalVariable(PooledGlobal). 250 GlobalVariable *PooledGlobal = 251 new GlobalVariable(M, PooledStructType, 252 /* isConstant */ true, GlobalValue::PrivateLinkage, 253 ConstantPool, "__ModuleStringPool"); 254 PooledGlobal->setAlignment(MaxAlignment); 255 256 LLVM_DEBUG(dbgs() << "Constructing global variable for string pool: "); 257 LLVM_DEBUG(PooledGlobal->dump()); 258 259 Context = &M.getContext(); 260 size_t ElementIndex = 0; 261 for (GlobalVariable *GV : MergeableStrings) { 262 263 LLVM_DEBUG(dbgs() << "The global:\n"); 264 LLVM_DEBUG(GV->dump()); 265 LLVM_DEBUG(dbgs() << "Has " << GV->getNumUses() << " uses.\n"); 266 267 // Access to the pooled constant strings require an offset. Add a GEP 268 // before every use in order to compute this offset. 269 replaceUsesWithGEP(GV, PooledGlobal, ElementIndex); 270 271 // This GV has no more uses so we can erase it. 272 if (GV->use_empty()) 273 GV->eraseFromParent(); 274 275 NumPooledStrings++; 276 ElementIndex++; 277 } 278 return true; 279 } 280 281 static bool userHasOperand(User *TheUser, GlobalVariable *GVOperand) { 282 for (Value *Op : TheUser->operands()) 283 if (Op == GVOperand) 284 return true; 285 return false; 286 } 287 288 // For pooled strings we need to add the offset into the pool for each string. 289 // This is done by adding a Get Element Pointer (GEP) before each user. This 290 // function adds the GEP. 291 void PPCMergeStringPool::replaceUsesWithGEP(GlobalVariable *GlobalToReplace, 292 GlobalVariable *GPool, 293 unsigned ElementIndex) { 294 SmallVector<Value *, 2> Indices; 295 Indices.push_back(ConstantInt::get(Type::getInt32Ty(*Context), 0)); 296 Indices.push_back(ConstantInt::get(Type::getInt32Ty(*Context), ElementIndex)); 297 298 // Need to save a temporary copy of each user list because we remove uses 299 // as we replace them. 300 SmallVector<User *> Users; 301 for (User *CurrentUser : GlobalToReplace->users()) 302 Users.push_back(CurrentUser); 303 304 for (User *CurrentUser : Users) { 305 Instruction *UserInstruction = dyn_cast<Instruction>(CurrentUser); 306 Constant *UserConstant = dyn_cast<Constant>(CurrentUser); 307 308 // At this point we expect that the user is either an instruction or a 309 // constant. 310 assert((UserConstant || UserInstruction) && 311 "Expected the user to be an instruction or a constant."); 312 313 // The user was not found so it must have been replaced earlier. 314 if (!userHasOperand(CurrentUser, GlobalToReplace)) 315 continue; 316 317 // We cannot replace operands in globals so we ignore those. 318 if (isa<GlobalValue>(CurrentUser)) 319 continue; 320 321 if (!UserInstruction) { 322 // User is a constant type. 323 Constant *ConstGEP = ConstantExpr::getInBoundsGetElementPtr( 324 PooledStructType, GPool, Indices); 325 UserConstant->handleOperandChange(GlobalToReplace, ConstGEP); 326 continue; 327 } 328 329 if (PHINode *UserPHI = dyn_cast<PHINode>(UserInstruction)) { 330 // GEP instructions cannot be added before PHI nodes. 331 // With getInBoundsGetElementPtr we create the GEP and then replace it 332 // inline into the PHI. 333 Constant *ConstGEP = ConstantExpr::getInBoundsGetElementPtr( 334 PooledStructType, GPool, Indices); 335 UserPHI->replaceUsesOfWith(GlobalToReplace, ConstGEP); 336 continue; 337 } 338 // The user is a valid instruction that is not a PHINode. 339 GetElementPtrInst *GEPInst = 340 GetElementPtrInst::Create(PooledStructType, GPool, Indices); 341 GEPInst->insertBefore(UserInstruction); 342 343 LLVM_DEBUG(dbgs() << "Inserting GEP before:\n"); 344 LLVM_DEBUG(UserInstruction->dump()); 345 346 LLVM_DEBUG(dbgs() << "Replacing this global:\n"); 347 LLVM_DEBUG(GlobalToReplace->dump()); 348 LLVM_DEBUG(dbgs() << "with this:\n"); 349 LLVM_DEBUG(GEPInst->dump()); 350 351 // After the GEP is inserted the GV can be replaced. 352 CurrentUser->replaceUsesOfWith(GlobalToReplace, GEPInst); 353 } 354 } 355 356 } // namespace 357 358 char PPCMergeStringPool::ID = 0; 359 360 INITIALIZE_PASS(PPCMergeStringPool, DEBUG_TYPE, "PPC Merge String Pool", false, 361 false) 362 363 ModulePass *llvm::createPPCMergeStringPoolPass() { 364 return new PPCMergeStringPool(); 365 } 366