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