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)21static 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)26static 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)57void llvm::reduceGlobalsDeltaPass(TestRunner &Test) { 58 runDeltaPass(Test, extractGVsFromModule, "Reducing GlobalVariables"); 59 } 60