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());
68 ImportedFunctions += int(F.
getMetadata(
"thinlto_src_module") !=
nullptr);
71 static std::string
getStatString(
const char *Msg, int32_t Fraction, int32_t All,
72 const char *PercentageOfMsg,
73 bool LineEnd =
true) {
76 Result = 100 *
static_cast<double>(Fraction) / All;
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");
162 void ImportedFunctionsInliningStatistics::calculateRealInlines() {
165 NonImportedCallers.erase(
166 std::unique(NonImportedCallers.begin(), NonImportedCallers.end()),
167 NonImportedCallers.end());
169 for (
const auto &
Name : NonImportedCallers) {
170 auto &Node = *NodesMap[
Name];
176 void ImportedFunctionsInliningStatistics::dfs(InlineGraphNode &GraphNode) {
177 assert(!GraphNode.Visited);
178 GraphNode.Visited =
true;
179 for (
auto *
const InlinedFunctionNode : GraphNode.InlinedCallees) {
180 InlinedFunctionNode->NumberOfRealInlines++;
181 if (!InlinedFunctionNode->Visited)
182 dfs(*InlinedFunctionNode);
186 ImportedFunctionsInliningStatistics::SortedNodesTy
187 ImportedFunctionsInliningStatistics::getSortedNodes() {
188 SortedNodesTy SortedNodes;
189 SortedNodes.reserve(NodesMap.
size());
191 SortedNodes.push_back(&Node);
193 llvm::sort(SortedNodes, [&](
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.
This class represents lattice values for constants.
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
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
Get a short "name" for the module.
amdgpu Simplify well known AMD library false Value Value const Twine & Name
MDNode * getMetadata(unsigned KindID) const
Get the current metadata attachments for the given kind, if any.
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
iterator_range< iterator > functions()
void sort(IteratorTy Start, IteratorTy End)
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)
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.
StringRef getName() const
Return a constant reference to the value's name.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A raw_ostream that writes to an std::string.