24ImportedFunctionsInliningStatistics::InlineGraphNode &
25ImportedFunctionsInliningStatistics::createInlineGraphNode(
const Function &
F) {
27 auto &ValueLookup = NodesMap[
F.getName()];
29 ValueLookup = std::make_unique<InlineGraphNode>();
30 ValueLookup->Imported =
F.hasMetadata(
"thinlto_src_module");
38 InlineGraphNode &CallerNode = createInlineGraphNode(Caller);
39 InlineGraphNode &CalleeNode = createInlineGraphNode(Callee);
40 CalleeNode.NumberOfInlines++;
42 if (!CallerNode.Imported && !CalleeNode.Imported) {
47 CalleeNode.NumberOfRealInlines++;
51 CallerNode.InlinedCallees.
push_back(&CalleeNode);
52 if (!CallerNode.Imported) {
54 auto It = NodesMap.find(Caller.getName());
55 assert(It != NodesMap.end() &&
"The node should be already there.");
58 NonImportedCallers.push_back(It->first());
63 ModuleName = M.getName();
64 for (
const auto &
F : M.functions()) {
65 if (
F.isDeclaration())
68 ImportedFunctions += int(
F.hasMetadata(
"thinlto_src_module"));
72 const char *PercentageOfMsg,
73 bool LineEnd =
true) {
78 std::stringstream Str;
79 Str << std::setprecision(4) <<
Msg <<
": " <<
Fraction <<
" [" << Result
80 <<
"% of " << PercentageOfMsg <<
"]";
87 calculateRealInlines();
88 NonImportedCallers.clear();
90 int32_t InlinedImportedFunctionsCount = 0;
91 int32_t InlinedNotImportedFunctionsCount = 0;
93 int32_t InlinedImportedFunctionsToImportingModuleCount = 0;
94 int32_t InlinedNotImportedFunctionsToImportingModuleCount = 0;
96 const auto SortedNodes = getSortedNodes();
101 Ostream <<
"------- Dumping inliner stats for [" << ModuleName
105 Ostream <<
"-- List of inlined functions:\n";
107 for (
const auto &
Node : SortedNodes) {
108 assert(
Node->second->NumberOfInlines >=
Node->second->NumberOfRealInlines);
109 if (
Node->second->NumberOfInlines == 0)
112 if (
Node->second->Imported) {
113 InlinedImportedFunctionsCount++;
114 InlinedImportedFunctionsToImportingModuleCount +=
115 int(
Node->second->NumberOfRealInlines > 0);
117 InlinedNotImportedFunctionsCount++;
118 InlinedNotImportedFunctionsToImportingModuleCount +=
119 int(
Node->second->NumberOfRealInlines > 0);
123 Ostream <<
"Inlined "
124 << (
Node->second->Imported ?
"imported " :
"not imported ")
125 <<
"function [" <<
Node->first() <<
"]"
126 <<
": #inlines = " <<
Node->second->NumberOfInlines
127 <<
", #inlines_to_importing_module = "
128 <<
Node->second->NumberOfRealInlines <<
"\n";
131 auto InlinedFunctionsCount =
132 InlinedImportedFunctionsCount + InlinedNotImportedFunctionsCount;
133 auto NotImportedFuncCount = AllFunctions - ImportedFunctions;
134 auto ImportedNotInlinedIntoModule =
135 ImportedFunctions - InlinedImportedFunctionsToImportingModuleCount;
137 Ostream <<
"-- Summary:\n"
138 <<
"All functions: " << AllFunctions
139 <<
", imported functions: " << ImportedFunctions <<
"\n"
141 AllFunctions,
"all functions")
143 InlinedImportedFunctionsCount, ImportedFunctions,
144 "imported functions")
145 <<
getStatString(
"imported functions inlined into importing module",
146 InlinedImportedFunctionsToImportingModuleCount,
147 ImportedFunctions,
"imported functions",
149 <<
getStatString(
", remaining", ImportedNotInlinedIntoModule,
150 ImportedFunctions,
"imported functions")
152 InlinedNotImportedFunctionsCount,
153 NotImportedFuncCount,
"non-imported functions")
155 "non-imported functions inlined into importing module",
156 InlinedNotImportedFunctionsToImportingModuleCount,
157 NotImportedFuncCount,
"non-imported functions");
161void ImportedFunctionsInliningStatistics::calculateRealInlines() {
164 NonImportedCallers.erase(
llvm::unique(NonImportedCallers),
165 NonImportedCallers.end());
167 for (
const auto &Name : NonImportedCallers) {
168 auto &
Node = *NodesMap[Name];
174void ImportedFunctionsInliningStatistics::dfs(InlineGraphNode &GraphNode) {
175 assert(!GraphNode.Visited);
176 GraphNode.Visited =
true;
177 for (
auto *
const InlinedFunctionNode : GraphNode.InlinedCallees) {
178 InlinedFunctionNode->NumberOfRealInlines++;
179 if (!InlinedFunctionNode->Visited)
180 dfs(*InlinedFunctionNode);
184ImportedFunctionsInliningStatistics::SortedNodesTy
185ImportedFunctionsInliningStatistics::getSortedNodes() {
186 SortedNodesTy SortedNodes;
187 SortedNodes.reserve(NodesMap.size());
189 SortedNodes.push_back(&Node);
191 llvm::sort(SortedNodes, [&](
const SortedNodesTy::value_type &Lhs,
192 const SortedNodesTy::value_type &Rhs) {
193 if (Lhs->second->NumberOfInlines != Rhs->second->NumberOfInlines)
194 return Lhs->second->NumberOfInlines > Rhs->second->NumberOfInlines;
195 if (Lhs->second->NumberOfRealInlines != Rhs->second->NumberOfRealInlines)
196 return Lhs->second->NumberOfRealInlines >
197 Rhs->second->NumberOfRealInlines;
198 return Lhs->first() < Rhs->first();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Module.h This file contains the declarations for the Module class.
static std::string getStatString(const char *Msg, int32_t Fraction, int32_t All, const char *PercentageOfMsg, bool LineEnd=true)
LLVM_ABI void setModuleInfo(const Module &M)
Set information like AllFunctions, ImportedFunctions, ModuleName.
LLVM_ABI void dump(bool Verbose)
Dump stats computed with InlinerStatistics class.
LLVM_ABI void recordInline(const Function &Caller, const Function &Callee)
Record inline of.
A Module instance is used to store all the information related to an LLVM module.
void push_back(const T &Elt)
StringMapEntry< std::unique_ptr< InlineGraphNode > > value_type
A raw_ostream that writes to an std::string.
This is an optimization pass for GlobalISel generic memory operations.
auto unique(Range &&R, Predicate P)
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.