27    "inliner-function-import-stats",
 
   32                          "printing of statistics for each inlined function")),
 
   36ImportedFunctionsInliningStatistics::InlineGraphNode &
 
   37ImportedFunctionsInliningStatistics::createInlineGraphNode(
const Function &
F) {
 
   39  auto &ValueLookup = NodesMap[
F.getName()];
 
   41    ValueLookup = std::make_unique<InlineGraphNode>();
 
   42    ValueLookup->Imported = 
F.hasMetadata(
"thinlto_src_module");
 
   50  InlineGraphNode &CallerNode = createInlineGraphNode(Caller);
 
   51  InlineGraphNode &CalleeNode = createInlineGraphNode(Callee);
 
   52  CalleeNode.NumberOfInlines++;
 
   54  if (!CallerNode.Imported && !CalleeNode.Imported) {
 
   59    CalleeNode.NumberOfRealInlines++;
 
   63  CallerNode.InlinedCallees.
push_back(&CalleeNode);
 
   64  if (!CallerNode.Imported) {
 
   66    auto It = NodesMap.find(Caller.getName());
 
   67    assert(It != NodesMap.end() && 
"The node should be already there.");
 
   70    NonImportedCallers.push_back(It->first());
 
 
   75  ModuleName = M.getName();
 
   76  for (
const auto &
F : M.functions()) {
 
   77    if (
F.isDeclaration())
 
   80    ImportedFunctions += int(
F.hasMetadata(
"thinlto_src_module"));
 
 
   84                                 const char *PercentageOfMsg,
 
   85                                 bool LineEnd = 
true) {
 
   88    Result = 100 * 
static_cast<double>(Fraction) / 
All;
 
   90  std::stringstream Str;
 
   91  Str << std::setprecision(4) << Msg << 
": " << Fraction << 
" [" << Result
 
   92      << 
"% of " << PercentageOfMsg << 
"]";
 
 
   99  calculateRealInlines();
 
  100  NonImportedCallers.clear();
 
  102  int32_t InlinedImportedFunctionsCount = 0;
 
  103  int32_t InlinedNotImportedFunctionsCount = 0;
 
  105  int32_t InlinedImportedFunctionsToImportingModuleCount = 0;
 
  106  int32_t InlinedNotImportedFunctionsToImportingModuleCount = 0;
 
  108  const auto SortedNodes = getSortedNodes();
 
  113  Ostream << 
"------- Dumping inliner stats for [" << ModuleName
 
  117    Ostream << 
"-- List of inlined functions:\n";
 
  119  for (
const auto &
Node : SortedNodes) {
 
  120    assert(
Node->second->NumberOfInlines >= 
Node->second->NumberOfRealInlines);
 
  121    if (
Node->second->NumberOfInlines == 0)
 
  124    if (
Node->second->Imported) {
 
  125      InlinedImportedFunctionsCount++;
 
  126      InlinedImportedFunctionsToImportingModuleCount +=
 
  127          int(
Node->second->NumberOfRealInlines > 0);
 
  129      InlinedNotImportedFunctionsCount++;
 
  130      InlinedNotImportedFunctionsToImportingModuleCount +=
 
  131          int(
Node->second->NumberOfRealInlines > 0);
 
  135      Ostream << 
"Inlined " 
  136              << (
Node->second->Imported ? 
"imported " : 
"not imported ")
 
  137              << 
"function [" << 
Node->first() << 
"]" 
  138              << 
": #inlines = " << 
Node->second->NumberOfInlines
 
  139              << 
", #inlines_to_importing_module = " 
  140              << 
Node->second->NumberOfRealInlines << 
"\n";
 
  143  auto InlinedFunctionsCount =
 
  144      InlinedImportedFunctionsCount + InlinedNotImportedFunctionsCount;
 
  145  auto NotImportedFuncCount = AllFunctions - ImportedFunctions;
 
  146  auto ImportedNotInlinedIntoModule =
 
  147      ImportedFunctions - InlinedImportedFunctionsToImportingModuleCount;
 
  149  Ostream << 
"-- Summary:\n" 
  150          << 
"All functions: " << AllFunctions
 
  151          << 
", imported functions: " << ImportedFunctions << 
"\n" 
  153                           AllFunctions, 
"all functions")
 
  155                           InlinedImportedFunctionsCount, ImportedFunctions,
 
  156                           "imported functions")
 
  157          << 
getStatString(
"imported functions inlined into importing module",
 
  158                           InlinedImportedFunctionsToImportingModuleCount,
 
  159                           ImportedFunctions, 
"imported functions",
 
  161          << 
getStatString(
", remaining", ImportedNotInlinedIntoModule,
 
  162                           ImportedFunctions, 
"imported functions")
 
  164                           InlinedNotImportedFunctionsCount,
 
  165                           NotImportedFuncCount, 
"non-imported functions")
 
  167                 "non-imported functions inlined into importing module",
 
  168                 InlinedNotImportedFunctionsToImportingModuleCount,
 
  169                 NotImportedFuncCount, 
"non-imported functions");
 
 
  174void ImportedFunctionsInliningStatistics::calculateRealInlines() {
 
  177  NonImportedCallers.erase(
llvm::unique(NonImportedCallers),
 
  178                           NonImportedCallers.end());
 
  180  for (
const auto &Name : NonImportedCallers) {
 
  181    auto &
Node = *NodesMap[Name];
 
  187void ImportedFunctionsInliningStatistics::dfs(InlineGraphNode &GraphNode) {
 
  188  assert(!GraphNode.Visited);
 
  189  GraphNode.Visited = 
true;
 
  190  for (
auto *
const InlinedFunctionNode : GraphNode.InlinedCallees) {
 
  191    InlinedFunctionNode->NumberOfRealInlines++;
 
  192    if (!InlinedFunctionNode->Visited)
 
  193      dfs(*InlinedFunctionNode);
 
  197ImportedFunctionsInliningStatistics::SortedNodesTy
 
  198ImportedFunctionsInliningStatistics::getSortedNodes() {
 
  199  SortedNodesTy SortedNodes;
 
  200  SortedNodes.reserve(NodesMap.size());
 
  202    SortedNodes.push_back(&Node);
 
  204  llvm::sort(SortedNodes, [&](
const SortedNodesTy::value_type &Lhs,
 
  205                              const SortedNodesTy::value_type &Rhs) {
 
  206    if (Lhs->second->NumberOfInlines != Rhs->second->NumberOfInlines)
 
  207      return Lhs->second->NumberOfInlines > Rhs->second->NumberOfInlines;
 
  208    if (Lhs->second->NumberOfRealInlines != Rhs->second->NumberOfRealInlines)
 
  209      return Lhs->second->NumberOfRealInlines >
 
  210             Rhs->second->NumberOfRealInlines;
 
  211    return Lhs->first() < Rhs->first();
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
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.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
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.
cl::opt< InlinerFunctionImportStatsOpts > InlinerFunctionImportStats("inliner-function-import-stats", cl::init(InlinerFunctionImportStatsOpts::No), cl::values(clEnumValN(InlinerFunctionImportStatsOpts::Basic, "basic", "basic statistics"), clEnumValN(InlinerFunctionImportStatsOpts::Verbose, "verbose", "printing of statistics for each inlined function")), cl::Hidden, cl::desc("Enable inliner stats for imported functions"))