aboutsummaryrefslogtreecommitdiff
path: root/tools/llvm-reduce/deltas/ReduceFunctions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/llvm-reduce/deltas/ReduceFunctions.cpp')
-rw-r--r--tools/llvm-reduce/deltas/ReduceFunctions.cpp77
1 files changed, 77 insertions, 0 deletions
diff --git a/tools/llvm-reduce/deltas/ReduceFunctions.cpp b/tools/llvm-reduce/deltas/ReduceFunctions.cpp
new file mode 100644
index 000000000000..3382f35a945a
--- /dev/null
+++ b/tools/llvm-reduce/deltas/ReduceFunctions.cpp
@@ -0,0 +1,77 @@
+//===- 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";
+}