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 initialized Global Variables in the provided Module. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "ReduceGlobalVars.h" 15 #include <set> 16 17 using namespace llvm; 18 19 /// Removes all the Initialized GVs that aren't inside the desired Chunks. 20 static void extractGVsFromModule(std::vector<Chunk> ChunksToKeep, 21 Module *Program) { 22 // Get GVs inside desired chunks 23 std::set<GlobalVariable *> GVsToKeep; 24 int I = 0, GVCount = 0; 25 for (auto &GV : Program->globals()) 26 if (GV.hasInitializer() && I < (int)ChunksToKeep.size()) { 27 if (ChunksToKeep[I].contains(++GVCount)) 28 GVsToKeep.insert(&GV); 29 if (GVCount == ChunksToKeep[I].end) 30 ++I; 31 } 32 33 // Delete out-of-chunk GVs and their uses 34 std::vector<GlobalVariable *> ToRemove; 35 std::vector<Instruction *> InstToRemove; 36 for (auto &GV : Program->globals()) 37 if (GV.hasInitializer() && !GVsToKeep.count(&GV)) { 38 for (auto U : GV.users()) 39 if (auto *Inst = dyn_cast<Instruction>(U)) 40 InstToRemove.push_back(Inst); 41 42 GV.replaceAllUsesWith(UndefValue::get(GV.getType())); 43 ToRemove.push_back(&GV); 44 } 45 46 // Delete Instruction uses of unwanted GVs 47 for (auto *Inst : InstToRemove) { 48 Inst->replaceAllUsesWith(UndefValue::get(Inst->getType())); 49 Inst->eraseFromParent(); 50 } 51 52 for (auto *GV : ToRemove) 53 GV->eraseFromParent(); 54 } 55 56 /// Counts the amount of initialized GVs and displays their 57 /// respective name & index 58 static int countGVs(Module *Program) { 59 // TODO: Silence index with --quiet flag 60 outs() << "----------------------------\n"; 61 outs() << "GlobalVariable Index Reference:\n"; 62 int GVCount = 0; 63 for (auto &GV : Program->globals()) 64 if (GV.hasInitializer()) 65 outs() << "\t" << ++GVCount << ": " << GV.getName() << "\n"; 66 outs() << "----------------------------\n"; 67 return GVCount; 68 } 69 70 void llvm::reduceGlobalsDeltaPass(TestRunner &Test) { 71 outs() << "*** Reducing GVs...\n"; 72 int GVCount = countGVs(Test.getProgram()); 73 runDeltaPass(Test, GVCount, extractGVsFromModule); 74 } 75