xref: /llvm-project/llvm/tools/llvm-reduce/deltas/ReduceGlobalVars.cpp (revision 23cc36e4765912a1bcdbbc3fb8b0976a06dea043)
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 "llvm/Transforms/Utils/ModuleUtils.h"
18 
19 using namespace llvm;
20 
shouldAlwaysKeep(const GlobalVariable & GV)21 static bool shouldAlwaysKeep(const GlobalVariable &GV) {
22   return GV.getName() == "llvm.used" || GV.getName() == "llvm.compiler.used";
23 }
24 
25 /// Removes all the GVs that aren't inside the desired Chunks.
extractGVsFromModule(Oracle & O,ReducerWorkItem & WorkItem)26 static void extractGVsFromModule(Oracle &O, ReducerWorkItem &WorkItem) {
27   Module &Program = WorkItem.getModule();
28 
29   // Get GVs inside desired chunks
30   std::vector<Constant *> InitGVsToKeep;
31   for (auto &GV : Program.globals()) {
32     if (shouldAlwaysKeep(GV) || O.shouldKeep())
33       InitGVsToKeep.push_back(&GV);
34   }
35 
36   // We create a vector first, then convert it to a set, so that we don't have
37   // to pay the cost of rebalancing the set frequently if the order we insert
38   // the elements doesn't match the order they should appear inside the set.
39   DenseSet<Constant *> GVsToKeep(InitGVsToKeep.begin(), InitGVsToKeep.end());
40 
41   // Delete out-of-chunk GVs and their uses
42   DenseSet<Constant *> ToRemove;
43   for (auto &GV : Program.globals()) {
44     if (!GVsToKeep.count(&GV))
45       ToRemove.insert(&GV);
46   }
47 
48   removeFromUsedLists(Program,
49                       [&ToRemove](Constant *C) { return ToRemove.count(C); });
50 
51   for (auto *GV : ToRemove) {
52     GV->replaceAllUsesWith(getDefaultValue(GV->getType()));
53     cast<GlobalVariable>(GV)->eraseFromParent();
54   }
55 }
56 
reduceGlobalsDeltaPass(TestRunner & Test)57 void llvm::reduceGlobalsDeltaPass(TestRunner &Test) {
58   runDeltaPass(Test, extractGVsFromModule, "Reducing GlobalVariables");
59 }
60