| //===- ReduceFunctions.cpp - Specialized Delta Pass -----------------------===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file implements a function which calls the Generic Delta pass in order |
| // to reduce functions (and any instruction that calls it) in the provided |
| // Module. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "ReduceFunctions.h" |
| #include "Delta.h" |
| #include "llvm/ADT/SetVector.h" |
| #include <set> |
| |
| using namespace llvm; |
| |
| /// Removes all the Defined Functions (as well as their calls) |
| /// that aren't inside any of the desired Chunks. |
| static void extractFunctionsFromModule(const std::vector<Chunk> &ChunksToKeep, |
| Module *Program) { |
| // Get functions inside desired chunks |
| std::set<Function *> FuncsToKeep; |
| int I = 0, FunctionCount = 0; |
| for (auto &F : *Program) |
| if (I < (int)ChunksToKeep.size()) { |
| if (ChunksToKeep[I].contains(++FunctionCount)) |
| FuncsToKeep.insert(&F); |
| if (FunctionCount == ChunksToKeep[I].end) |
| ++I; |
| } |
| |
| // Delete out-of-chunk functions, and replace their calls with undef |
| std::vector<Function *> FuncsToRemove; |
| SetVector<CallInst *> CallsToRemove; |
| for (auto &F : *Program) |
| if (!FuncsToKeep.count(&F)) { |
| for (auto U : F.users()) |
| if (auto *Call = dyn_cast<CallInst>(U)) { |
| Call->replaceAllUsesWith(UndefValue::get(Call->getType())); |
| CallsToRemove.insert(Call); |
| } |
| F.replaceAllUsesWith(UndefValue::get(F.getType())); |
| FuncsToRemove.push_back(&F); |
| } |
| |
| for (auto *C : CallsToRemove) |
| C->eraseFromParent(); |
| |
| for (auto *F : FuncsToRemove) |
| F->eraseFromParent(); |
| } |
| |
| /// Counts the amount of non-declaration functions and prints their |
| /// respective name & index |
| static int countFunctions(Module *Program) { |
| // TODO: Silence index with --quiet flag |
| errs() << "----------------------------\n"; |
| errs() << "Function Index Reference:\n"; |
| int FunctionCount = 0; |
| for (auto &F : *Program) |
| errs() << "\t" << ++FunctionCount << ": " << F.getName() << "\n"; |
| |
| errs() << "----------------------------\n"; |
| return FunctionCount; |
| } |
| |
| void llvm::reduceFunctionsDeltaPass(TestRunner &Test) { |
| errs() << "*** Reducing Functions...\n"; |
| int Functions = countFunctions(Test.getProgram()); |
| runDeltaPass(Test, Functions, extractFunctionsFromModule); |
| errs() << "----------------------------\n"; |
| } |