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 | |
22 | using namespace llvm; |
23 | |
24 | /// Removes all the Defined Functions |
25 | /// that aren't inside any of the desired Chunks. |
26 | static void (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 | |
58 | void llvm::reduceFunctionsDeltaPass(TestRunner &Test) { |
59 | runDeltaPass(Test, ExtractChunksFromModule: extractFunctionsFromModule, Message: "Reducing Functions" ); |
60 | } |
61 | |