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 Arsenaultstatic 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 Arsenaultstatic 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 Ferrervoid llvm::reduceGlobalsDeltaPass(TestRunner &Test) { 582592ccdeSArthur Eubanks runDeltaPass(Test, extractGVsFromModule, "Reducing GlobalVariables"); 590ffe687eSDiego Trevino Ferrer } 60