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