xref: /netbsd-src/external/apache2/llvm/dist/llvm/tools/llvm-reduce/deltas/ReduceGlobalVars.cpp (revision 82d56013d7b633d116a93943de88e08335357a7c)
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 "llvm/IR/Constants.h"
16 #include <set>
17 
18 using namespace llvm;
19 
20 /// Removes all the 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 (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 (!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 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     outs() << "\t" << ++GVCount << ": " << GV.getName() << "\n";
66   outs() << "----------------------------\n";
67   return GVCount;
68 }
69 
reduceGlobalsDeltaPass(TestRunner & Test)70 void llvm::reduceGlobalsDeltaPass(TestRunner &Test) {
71   outs() << "*** Reducing GVs...\n";
72   int GVCount = countGVs(Test.getProgram());
73   runDeltaPass(Test, GVCount, extractGVsFromModule);
74 }
75