• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- ReduceGlobalVars.cpp - Specialized Delta Pass ----------------------===//
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 file implements a function which calls the Generic Delta pass in order
10 // to reduce initialized Global Variables in the provided Module.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "ReduceGlobalVars.h"
15 #include "llvm/IR/Constants.h"
16 #include <set>
17 
18 using namespace llvm;
19 
20 /// Removes all the Initialized GVs that aren't inside the desired Chunks.
extractGVsFromModule(std::vector<Chunk> ChunksToKeep,Module * Program)21 static void extractGVsFromModule(std::vector<Chunk> ChunksToKeep,
22                                  Module *Program) {
23   Oracle O(ChunksToKeep);
24 
25   // Get GVs inside desired chunks
26   std::set<GlobalVariable *> GVsToKeep;
27   for (auto &GV : Program->globals())
28     if (GV.hasInitializer() && O.shouldKeep())
29       GVsToKeep.insert(&GV);
30 
31   // Delete out-of-chunk GVs and their uses
32   std::vector<GlobalVariable *> ToRemove;
33   std::vector<WeakVH> InstToRemove;
34   for (auto &GV : Program->globals())
35     if (GV.hasInitializer() && !GVsToKeep.count(&GV)) {
36       for (auto U : GV.users())
37         if (auto *Inst = dyn_cast<Instruction>(U))
38           InstToRemove.push_back(Inst);
39 
40       GV.replaceAllUsesWith(UndefValue::get(GV.getType()));
41       ToRemove.push_back(&GV);
42     }
43 
44   // Delete (unique) Instruction uses of unwanted GVs
45   for (Value *V : InstToRemove) {
46     if (!V)
47       continue;
48     auto *Inst = cast<Instruction>(V);
49     Inst->replaceAllUsesWith(UndefValue::get(Inst->getType()));
50     Inst->eraseFromParent();
51   }
52 
53   for (auto *GV : ToRemove)
54     GV->eraseFromParent();
55 }
56 
57 /// Counts the amount of initialized GVs and displays their
58 /// respective name & index
countGVs(Module * Program)59 static int countGVs(Module *Program) {
60   // TODO: Silence index with --quiet flag
61   outs() << "----------------------------\n";
62   outs() << "GlobalVariable Index Reference:\n";
63   int GVCount = 0;
64   for (auto &GV : Program->globals())
65     if (GV.hasInitializer())
66       outs() << "\t" << ++GVCount << ": " << GV.getName() << "\n";
67   outs() << "----------------------------\n";
68   return GVCount;
69 }
70 
reduceGlobalsDeltaPass(TestRunner & Test)71 void llvm::reduceGlobalsDeltaPass(TestRunner &Test) {
72   outs() << "*** Reducing GVs...\n";
73   int GVCount = countGVs(Test.getProgram());
74   runDeltaPass(Test, GVCount, extractGVsFromModule);
75 }
76