24 ImportedFunctionsInliningStatistics::InlineGraphNode &
25 ImportedFunctionsInliningStatistics::createInlineGraphNode(
const Function &
F) {
27 auto &ValueLookup = NodesMap[F.
getName()];
29 ValueLookup = llvm::make_unique<InlineGraphNode>();
30 ValueLookup->Imported = F.
getMetadata(
"thinlto_src_module") !=
nullptr;
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) {
55 assert(It != NodesMap.
end() &&
"The node should be already there.");
58 NonImportedCallers.push_back(It->first());
66 ImportedFunctions += int(F.
getMetadata(
"thinlto_src_module") !=
nullptr);
69 static std::string
getStatString(
const char *Msg, int32_t Fraction, int32_t All,
70 const char *PercentageOfMsg,
71 bool LineEnd =
true) {
74 Result = 100 *
static_cast<double>(Fraction) / All;
76 std::stringstream Str;
77 Str << std::setprecision(4) << Msg <<
": " << Fraction <<
" [" << Result
78 <<
"% of " << PercentageOfMsg <<
"]";
85 calculateRealInlines();
86 NonImportedCallers.clear();
88 int32_t InlinedImportedFunctionsCount = 0;
89 int32_t InlinedNotImportedFunctionsCount = 0;
91 int32_t InlinedImportedFunctionsToImportingModuleCount = 0;
92 int32_t InlinedNotImportedFunctionsToImportingModuleCount = 0;
94 const auto SortedNodes = getSortedNodes();
99 Ostream <<
"------- Dumping inliner stats for [" << ModuleName
103 Ostream <<
"-- List of inlined functions:\n";
105 for (
const auto &Node : SortedNodes) {
106 assert(Node->second->NumberOfInlines >= Node->second->NumberOfRealInlines);
107 if (Node->second->NumberOfInlines == 0)
110 if (Node->second->Imported) {
111 InlinedImportedFunctionsCount++;
112 InlinedImportedFunctionsToImportingModuleCount +=
113 int(Node->second->NumberOfRealInlines > 0);
115 InlinedNotImportedFunctionsCount++;
116 InlinedNotImportedFunctionsToImportingModuleCount +=
117 int(Node->second->NumberOfRealInlines > 0);
121 Ostream <<
"Inlined "
122 << (Node->second->Imported ?
"imported " :
"not imported ")
123 <<
"function [" << Node->first() <<
"]"
124 <<
": #inlines = " << Node->second->NumberOfInlines
125 <<
", #inlines_to_importing_module = "
126 << Node->second->NumberOfRealInlines <<
"\n";
129 auto InlinedFunctionsCount =
130 InlinedImportedFunctionsCount + InlinedNotImportedFunctionsCount;
131 auto NotImportedFuncCount = AllFunctions - ImportedFunctions;
132 auto ImportedNotInlinedIntoModule =
133 ImportedFunctions - InlinedImportedFunctionsToImportingModuleCount;
135 Ostream <<
"-- Summary:\n"
136 <<
"All functions: " << AllFunctions
137 <<
", imported functions: " << ImportedFunctions <<
"\n"
139 AllFunctions,
"all functions")
141 InlinedImportedFunctionsCount, ImportedFunctions,
142 "imported functions")
143 <<
getStatString(
"imported functions inlined into importing module",
144 InlinedImportedFunctionsToImportingModuleCount,
145 ImportedFunctions,
"imported functions",
147 <<
getStatString(
", remaining", ImportedNotInlinedIntoModule,
148 ImportedFunctions,
"imported functions")
150 InlinedNotImportedFunctionsCount,
151 NotImportedFuncCount,
"non-imported functions")
153 "non-imported functions inlined into importing module",
154 InlinedNotImportedFunctionsToImportingModuleCount,
155 NotImportedFuncCount,
"non-imported functions");
160 void ImportedFunctionsInliningStatistics::calculateRealInlines() {
162 std::sort(NonImportedCallers.begin(), NonImportedCallers.end());
163 NonImportedCallers.erase(
164 std::unique(NonImportedCallers.begin(), NonImportedCallers.end()),
165 NonImportedCallers.end());
167 for (
const auto &
Name : NonImportedCallers) {
168 auto &Node = *NodesMap[
Name];
174 void 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);
184 ImportedFunctionsInliningStatistics::SortedNodesTy
185 ImportedFunctionsInliningStatistics::getSortedNodes() {
186 SortedNodesTy SortedNodes;
187 SortedNodes.reserve(NodesMap.
size());
189 SortedNodes.push_back(&Node);
192 SortedNodes.begin(), SortedNodes.end(),
193 [&](
const SortedNodesTy::value_type &Lhs,
194 const SortedNodesTy::value_type &Rhs) {
195 if (Lhs->second->NumberOfInlines != Rhs->second->NumberOfInlines)
196 return Lhs->second->NumberOfInlines > Rhs->second->NumberOfInlines;
197 if (Lhs->second->NumberOfRealInlines != Rhs->second->NumberOfRealInlines)
198 return Lhs->second->NumberOfRealInlines >
199 Rhs->second->NumberOfRealInlines;
200 return Lhs->first() < Rhs->first();
void setModuleInfo(const Module &M)
Set information like AllFunctions, ImportedFunctions, ModuleName.
A Module instance is used to store all the information related to an LLVM module. ...
void recordInline(const Function &Caller, const Function &Callee)
Record inline of.
iterator find(StringRef Key)
StringRef getName() const
Return a constant reference to the value's name.
StringRef getName() const
Get a short "name" for the module.
iterator_range< iterator > functions()
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)
StringMapEntry< ValueTy > value_type
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void dump(bool Verbose)
Dump stats computed with InlinerStatistics class.
MDNode * getMetadata(unsigned KindID) const
Get the current metadata attachments for the given kind, if any.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A raw_ostream that writes to an std::string.