xref: /llvm-project/llvm/tools/llvm-reduce/deltas/ReduceGlobalVars.cpp (revision 23cc36e4765912a1bcdbbc3fb8b0976a06dea043)
10ffe687eSDiego Trevino Ferrer //===- ReduceGlobalVars.cpp - Specialized Delta Pass ----------------------===//
20ffe687eSDiego Trevino Ferrer //
30ffe687eSDiego Trevino Ferrer // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40ffe687eSDiego Trevino Ferrer // See https://llvm.org/LICENSE.txt for license information.
50ffe687eSDiego Trevino Ferrer // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60ffe687eSDiego Trevino Ferrer //
70ffe687eSDiego Trevino Ferrer //===----------------------------------------------------------------------===//
80ffe687eSDiego Trevino Ferrer //
90ffe687eSDiego Trevino Ferrer // This file implements a function which calls the Generic Delta pass in order
105799fc79SRoman Lebedev // to reduce Global Variables in the provided Module.
110ffe687eSDiego Trevino Ferrer //
120ffe687eSDiego Trevino Ferrer //===----------------------------------------------------------------------===//
130ffe687eSDiego Trevino Ferrer 
140ffe687eSDiego Trevino Ferrer #include "ReduceGlobalVars.h"
152962f9dfSJohn Regehr #include "Utils.h"
16457db403SSimon Pilgrim #include "llvm/IR/Constants.h"
17aa9bdd50SMatt Arsenault #include "llvm/Transforms/Utils/ModuleUtils.h"
180ffe687eSDiego Trevino Ferrer 
19345fbfd7SDavid Blaikie using namespace llvm;
20345fbfd7SDavid Blaikie 
shouldAlwaysKeep(const GlobalVariable & GV)21a50cec5bSMatt Arsenault static bool shouldAlwaysKeep(const GlobalVariable &GV) {
22a50cec5bSMatt Arsenault   return GV.getName() == "llvm.used" || GV.getName() == "llvm.compiler.used";
23a50cec5bSMatt Arsenault }
24a50cec5bSMatt Arsenault 
255799fc79SRoman Lebedev /// Removes all the GVs that aren't inside the desired Chunks.
extractGVsFromModule(Oracle & O,ReducerWorkItem & WorkItem)26*23cc36e4SMatt Arsenault static void extractGVsFromModule(Oracle &O, ReducerWorkItem &WorkItem) {
27*23cc36e4SMatt Arsenault   Module &Program = WorkItem.getModule();
28*23cc36e4SMatt Arsenault 
290ffe687eSDiego Trevino Ferrer   // Get GVs inside desired chunks
30aa9bdd50SMatt Arsenault   std::vector<Constant *> InitGVsToKeep;
31aa9bdd50SMatt Arsenault   for (auto &GV : Program.globals()) {
32a50cec5bSMatt Arsenault     if (shouldAlwaysKeep(GV) || O.shouldKeep())
332f161736SDwight Guth       InitGVsToKeep.push_back(&GV);
34aa9bdd50SMatt Arsenault   }
352f161736SDwight Guth 
362f161736SDwight Guth   // We create a vector first, then convert it to a set, so that we don't have
372f161736SDwight Guth   // to pay the cost of rebalancing the set frequently if the order we insert
382f161736SDwight Guth   // the elements doesn't match the order they should appear inside the set.
39a50cec5bSMatt Arsenault   DenseSet<Constant *> GVsToKeep(InitGVsToKeep.begin(), InitGVsToKeep.end());
400ffe687eSDiego Trevino Ferrer 
410ffe687eSDiego Trevino Ferrer   // Delete out-of-chunk GVs and their uses
42aa9bdd50SMatt Arsenault   DenseSet<Constant *> ToRemove;
43aa9bdd50SMatt Arsenault   for (auto &GV : Program.globals()) {
44a50cec5bSMatt Arsenault     if (!GVsToKeep.count(&GV))
45aa9bdd50SMatt Arsenault       ToRemove.insert(&GV);
460ffe687eSDiego Trevino Ferrer   }
47aa9bdd50SMatt Arsenault 
48aa9bdd50SMatt Arsenault   removeFromUsedLists(Program,
49aa9bdd50SMatt Arsenault                       [&ToRemove](Constant *C) { return ToRemove.count(C); });
500ffe687eSDiego Trevino Ferrer 
51aa9bdd50SMatt Arsenault   for (auto *GV : ToRemove) {
52aa9bdd50SMatt Arsenault     GV->replaceAllUsesWith(getDefaultValue(GV->getType()));
53aa9bdd50SMatt Arsenault     cast<GlobalVariable>(GV)->eraseFromParent();
54aa9bdd50SMatt Arsenault   }
550ffe687eSDiego Trevino Ferrer }
560ffe687eSDiego Trevino Ferrer 
reduceGlobalsDeltaPass(TestRunner & Test)570ffe687eSDiego Trevino Ferrer void llvm::reduceGlobalsDeltaPass(TestRunner &Test) {
582592ccdeSArthur Eubanks   runDeltaPass(Test, extractGVsFromModule, "Reducing GlobalVariables");
590ffe687eSDiego Trevino Ferrer }
60