Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Transforms/Utils/CallGraphUpdater.cpp
35271 views
1
//===- CallGraphUpdater.cpp - A (lazy) call graph update helper -----------===//
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
/// \file
9
///
10
/// This file provides interfaces used to manipulate a call graph, regardless
11
/// if it is a "old style" CallGraph or an "new style" LazyCallGraph.
12
///
13
//===----------------------------------------------------------------------===//
14
15
#include "llvm/Transforms/Utils/CallGraphUpdater.h"
16
#include "llvm/IR/Constants.h"
17
#include "llvm/Transforms/Utils/ModuleUtils.h"
18
19
using namespace llvm;
20
21
bool CallGraphUpdater::finalize() {
22
if (!DeadFunctionsInComdats.empty()) {
23
filterDeadComdatFunctions(DeadFunctionsInComdats);
24
DeadFunctions.append(DeadFunctionsInComdats.begin(),
25
DeadFunctionsInComdats.end());
26
}
27
28
// This is the code path for the new lazy call graph and for the case were
29
// no call graph was provided.
30
for (Function *DeadFn : DeadFunctions) {
31
DeadFn->removeDeadConstantUsers();
32
DeadFn->replaceAllUsesWith(PoisonValue::get(DeadFn->getType()));
33
34
if (LCG && !ReplacedFunctions.count(DeadFn)) {
35
// Taken mostly from the inliner:
36
LazyCallGraph::Node &N = LCG->get(*DeadFn);
37
auto *DeadSCC = LCG->lookupSCC(N);
38
assert(DeadSCC && DeadSCC->size() == 1 &&
39
&DeadSCC->begin()->getFunction() == DeadFn);
40
41
FAM->clear(*DeadFn, DeadFn->getName());
42
AM->clear(*DeadSCC, DeadSCC->getName());
43
LCG->markDeadFunction(*DeadFn);
44
45
// Mark the relevant parts of the call graph as invalid so we don't
46
// visit them.
47
UR->InvalidatedSCCs.insert(LCG->lookupSCC(N));
48
UR->DeadFunctions.push_back(DeadFn);
49
} else {
50
// The CGSCC infrastructure batch deletes functions at the end of the
51
// call graph walk, so only erase the function if we're not using that
52
// infrastructure.
53
// The function is now really dead and de-attached from everything.
54
DeadFn->eraseFromParent();
55
}
56
}
57
58
bool Changed = !DeadFunctions.empty();
59
DeadFunctionsInComdats.clear();
60
DeadFunctions.clear();
61
return Changed;
62
}
63
64
void CallGraphUpdater::reanalyzeFunction(Function &Fn) {
65
if (LCG) {
66
LazyCallGraph::Node &N = LCG->get(Fn);
67
LazyCallGraph::SCC *C = LCG->lookupSCC(N);
68
updateCGAndAnalysisManagerForCGSCCPass(*LCG, *C, N, *AM, *UR, *FAM);
69
}
70
}
71
72
void CallGraphUpdater::registerOutlinedFunction(Function &OriginalFn,
73
Function &NewFn) {
74
if (LCG)
75
LCG->addSplitFunction(OriginalFn, NewFn);
76
}
77
78
void CallGraphUpdater::removeFunction(Function &DeadFn) {
79
DeadFn.deleteBody();
80
DeadFn.setLinkage(GlobalValue::ExternalLinkage);
81
if (DeadFn.hasComdat())
82
DeadFunctionsInComdats.push_back(&DeadFn);
83
else
84
DeadFunctions.push_back(&DeadFn);
85
86
if (FAM)
87
FAM->clear(DeadFn, DeadFn.getName());
88
}
89
90
void CallGraphUpdater::replaceFunctionWith(Function &OldFn, Function &NewFn) {
91
OldFn.removeDeadConstantUsers();
92
ReplacedFunctions.insert(&OldFn);
93
if (LCG) {
94
// Directly substitute the functions in the call graph.
95
LazyCallGraph::Node &OldLCGN = LCG->get(OldFn);
96
SCC->getOuterRefSCC().replaceNodeFunction(OldLCGN, NewFn);
97
}
98
removeFunction(OldFn);
99
}
100
101