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