1ddc64eb9SDiego Trevino Ferrer //===- ReduceFunctions.cpp - Specialized Delta Pass -----------------------===//
2ddc64eb9SDiego Trevino Ferrer //
3ddc64eb9SDiego Trevino Ferrer // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4ddc64eb9SDiego Trevino Ferrer // See https://llvm.org/LICENSE.txt for license information.
5ddc64eb9SDiego Trevino Ferrer // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ddc64eb9SDiego Trevino Ferrer //
7ddc64eb9SDiego Trevino Ferrer //===----------------------------------------------------------------------===//
8ddc64eb9SDiego Trevino Ferrer //
9ddc64eb9SDiego Trevino Ferrer // This file implements a function which calls the Generic Delta pass in order
10ddc64eb9SDiego Trevino Ferrer // to reduce functions (and any instruction that calls it) in the provided
11ddc64eb9SDiego Trevino Ferrer // Module.
12ddc64eb9SDiego Trevino Ferrer //
13ddc64eb9SDiego Trevino Ferrer //===----------------------------------------------------------------------===//
14ddc64eb9SDiego Trevino Ferrer
15ddc64eb9SDiego Trevino Ferrer #include "ReduceFunctions.h"
16345fbfd7SDavid Blaikie #include "Delta.h"
172962f9dfSJohn Regehr #include "Utils.h"
18d4c3f202SRoman Lebedev #include "llvm/ADT/STLExtras.h"
19aa9bdd50SMatt Arsenault #include "llvm/Transforms/Utils/ModuleUtils.h"
20d4c3f202SRoman Lebedev #include <iterator>
21345fbfd7SDavid Blaikie
22345fbfd7SDavid Blaikie using namespace llvm;
23ddc64eb9SDiego Trevino Ferrer
24d4c3f202SRoman Lebedev /// Removes all the Defined Functions
25ddc64eb9SDiego Trevino Ferrer /// that aren't inside any of the desired Chunks.
extractFunctionsFromModule(Oracle & O,ReducerWorkItem & WorkItem)26*23cc36e4SMatt Arsenault static void extractFunctionsFromModule(Oracle &O, ReducerWorkItem &WorkItem) {
27*23cc36e4SMatt Arsenault Module &Program = WorkItem.getModule();
28*23cc36e4SMatt Arsenault
29d4c3f202SRoman Lebedev // Record all out-of-chunk functions.
30aa9bdd50SMatt Arsenault SmallPtrSet<Constant *, 8> FuncsToRemove;
31aa9bdd50SMatt Arsenault for (Function &F : Program.functions()) {
32ee6e25e4SMatt Arsenault // Intrinsics don't have function bodies that are useful to
33ee6e25e4SMatt Arsenault // reduce. Additionally, intrinsics may have additional operand
3419ab1817SRoman Lebedev // constraints. But, do drop intrinsics that are not referenced.
35ae6a5c1dSMatt Arsenault if ((!F.isIntrinsic() || F.use_empty()) && !hasAliasOrBlockAddressUse(F) &&
36aa9bdd50SMatt Arsenault !O.shouldKeep())
37aa9bdd50SMatt Arsenault FuncsToRemove.insert(&F);
38aa9bdd50SMatt Arsenault }
39aa9bdd50SMatt Arsenault
40aa9bdd50SMatt Arsenault removeFromUsedLists(Program, [&FuncsToRemove](Constant *C) {
41aa9bdd50SMatt Arsenault return FuncsToRemove.count(C);
42ee6e25e4SMatt Arsenault });
43ddc64eb9SDiego Trevino Ferrer
44d4c3f202SRoman Lebedev // Then, drop body of each of them. We want to batch this and do nothing else
45d4c3f202SRoman Lebedev // here so that minimal number of remaining exteranal uses will remain.
46aa9bdd50SMatt Arsenault for (Constant *F : FuncsToRemove)
47aa9bdd50SMatt Arsenault F->dropAllReferences();
48d4c3f202SRoman Lebedev
49d4c3f202SRoman Lebedev // And finally, we can actually delete them.
50aa9bdd50SMatt Arsenault for (Constant *F : FuncsToRemove) {
512962f9dfSJohn Regehr // Replace all *still* remaining uses with the default value.
52aa9bdd50SMatt Arsenault F->replaceAllUsesWith(getDefaultValue(F->getType()));
53d4c3f202SRoman Lebedev // And finally, fully drop it.
54aa9bdd50SMatt Arsenault cast<Function>(F)->eraseFromParent();
553755579fSDiego Trevino Ferrer }
56ddc64eb9SDiego Trevino Ferrer }
57ddc64eb9SDiego Trevino Ferrer
reduceFunctionsDeltaPass(TestRunner & Test)58ddc64eb9SDiego Trevino Ferrer void llvm::reduceFunctionsDeltaPass(TestRunner &Test) {
592592ccdeSArthur Eubanks runDeltaPass(Test, extractFunctionsFromModule, "Reducing Functions");
60ddc64eb9SDiego Trevino Ferrer }
61