1//===- ReduceFunctions.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 functions (and any instruction that calls it) in the provided
11// Module.
12//
13//===----------------------------------------------------------------------===//
14
15#include "ReduceFunctions.h"
16#include "Delta.h"
17#include "Utils.h"
18#include "llvm/ADT/STLExtras.h"
19#include "llvm/Transforms/Utils/ModuleUtils.h"
20#include <iterator>
21
22using namespace llvm;
23
24/// Removes all the Defined Functions
25/// that aren't inside any of the desired Chunks.
26static void extractFunctionsFromModule(Oracle &O, ReducerWorkItem &WorkItem) {
27 Module &Program = WorkItem.getModule();
28
29 // Record all out-of-chunk functions.
30 SmallPtrSet<Constant *, 8> FuncsToRemove;
31 for (Function &F : Program.functions()) {
32 // Intrinsics don't have function bodies that are useful to
33 // reduce. Additionally, intrinsics may have additional operand
34 // constraints. But, do drop intrinsics that are not referenced.
35 if ((!F.isIntrinsic() || F.use_empty()) && !hasAliasOrBlockAddressUse(F) &&
36 !O.shouldKeep())
37 FuncsToRemove.insert(Ptr: &F);
38 }
39
40 removeFromUsedLists(M&: Program, ShouldRemove: [&FuncsToRemove](Constant *C) {
41 return FuncsToRemove.count(Ptr: C);
42 });
43
44 // Then, drop body of each of them. We want to batch this and do nothing else
45 // here so that minimal number of remaining exteranal uses will remain.
46 for (Constant *F : FuncsToRemove)
47 F->dropAllReferences();
48
49 // And finally, we can actually delete them.
50 for (Constant *F : FuncsToRemove) {
51 // Replace all *still* remaining uses with the default value.
52 F->replaceAllUsesWith(V: getDefaultValue(T: F->getType()));
53 // And finally, fully drop it.
54 cast<Function>(Val: F)->eraseFromParent();
55 }
56}
57
58void llvm::reduceFunctionsDeltaPass(TestRunner &Test) {
59 runDeltaPass(Test, ExtractChunksFromModule: extractFunctionsFromModule, Message: "Reducing Functions");
60}
61