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