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 Global Variables in the provided Module.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "ReduceGlobalVars.h"
15 #include "Utils.h"
16 #include "llvm/IR/Constants.h"
17 #include <set>
18 
19 using namespace llvm;
20 
21 /// Removes all the GVs that aren't inside the desired Chunks.
extractGVsFromModule(Oracle & O,Module & Program)22 static void extractGVsFromModule(Oracle &O, Module &Program) {
23   // Get GVs inside desired chunks
24   std::vector<GlobalVariable *> InitGVsToKeep;
25   for (auto &GV : Program.globals())
26     if (O.shouldKeep())
27       InitGVsToKeep.push_back(&GV);
28 
29   // We create a vector first, then convert it to a set, so that we don't have
30   // to pay the cost of rebalancing the set frequently if the order we insert
31   // the elements doesn't match the order they should appear inside the set.
32   std::set<GlobalVariable *> GVsToKeep(InitGVsToKeep.begin(),
33                                        InitGVsToKeep.end());
34 
35   // Delete out-of-chunk GVs and their uses
36   std::vector<GlobalVariable *> ToRemove;
37   std::vector<WeakVH> InstToRemove;
38   for (auto &GV : Program.globals())
39     if (!GVsToKeep.count(&GV)) {
40       for (auto *U : GV.users())
41         if (auto *Inst = dyn_cast<Instruction>(U))
42           InstToRemove.push_back(Inst);
43 
44       GV.replaceAllUsesWith(getDefaultValue(GV.getType()));
45       ToRemove.push_back(&GV);
46     }
47 
48   // Delete (unique) Instruction uses of unwanted GVs
49   for (Value *V : InstToRemove) {
50     if (!V)
51       continue;
52     auto *Inst = cast<Instruction>(V);
53     Inst->replaceAllUsesWith(getDefaultValue(Inst->getType()));
54     Inst->eraseFromParent();
55   }
56 
57   for (auto *GV : ToRemove)
58     GV->eraseFromParent();
59 }
60 
reduceGlobalsDeltaPass(TestRunner & Test)61 void llvm::reduceGlobalsDeltaPass(TestRunner &Test) {
62   outs() << "*** Reducing GVs...\n";
63   runDeltaPass(Test, extractGVsFromModule);
64 }
65