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