LLVM: lib/Analysis/ImportedFunctionsInliningStatistics.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

19#include

20#include

21#include

22

23using namespace llvm;

24

25namespace llvm {

27 "inliner-function-import-stats",

30 "basic statistics"),

32 "printing of statistics for each inlined function")),

34}

35

36ImportedFunctionsInliningStatistics::InlineGraphNode &

37ImportedFunctionsInliningStatistics::createInlineGraphNode(const Function &F) {

38

39 auto &ValueLookup = NodesMap[F.getName()];

40 if (!ValueLookup) {

41 ValueLookup = std::make_unique();

42 ValueLookup->Imported = F.hasMetadata("thinlto_src_module");

43 }

44 return *ValueLookup;

45}

46

49

50 InlineGraphNode &CallerNode = createInlineGraphNode(Caller);

51 InlineGraphNode &CalleeNode = createInlineGraphNode(Callee);

52 CalleeNode.NumberOfInlines++;

53

54 if (!CallerNode.Imported && !CalleeNode.Imported) {

55

56

57

58

59 CalleeNode.NumberOfRealInlines++;

60 return;

61 }

62

63 CallerNode.InlinedCallees.push_back(&CalleeNode);

64 if (!CallerNode.Imported) {

65

66 auto It = NodesMap.find(Caller.getName());

67 assert(It != NodesMap.end() && "The node should be already there.");

68

69

70 NonImportedCallers.push_back(It->first());

71 }

72}

73

75 ModuleName = M.getName();

76 for (const auto &F : M.functions()) {

77 if (F.isDeclaration())

78 continue;

79 AllFunctions++;

80 ImportedFunctions += int(F.hasMetadata("thinlto_src_module"));

81 }

82}

83static std::string getStatString(const char *Msg, int32_t Fraction, int32_t All,

84 const char *PercentageOfMsg,

85 bool LineEnd = true) {

86 double Result = 0;

87 if (All != 0)

88 Result = 100 * static_cast<double>(Fraction) / All;

89

90 std::stringstream Str;

91 Str << std::setprecision(4) << Msg << ": " << Fraction << " [" << Result

92 << "% of " << PercentageOfMsg << "]";

93 if (LineEnd)

94 Str << "\n";

95 return Str.str();

96}

97

99 calculateRealInlines();

100 NonImportedCallers.clear();

101

102 int32_t InlinedImportedFunctionsCount = 0;

103 int32_t InlinedNotImportedFunctionsCount = 0;

104

105 int32_t InlinedImportedFunctionsToImportingModuleCount = 0;

106 int32_t InlinedNotImportedFunctionsToImportingModuleCount = 0;

107

108 const auto SortedNodes = getSortedNodes();

109 std::string Out;

110 Out.reserve(5000);

112

113 Ostream << "------- Dumping inliner stats for [" << ModuleName

114 << "] -------\n";

115

117 Ostream << "-- List of inlined functions:\n";

118

119 for (const auto &Node : SortedNodes) {

120 assert(Node->second->NumberOfInlines >= Node->second->NumberOfRealInlines);

121 if (Node->second->NumberOfInlines == 0)

122 continue;

123

124 if (Node->second->Imported) {

125 InlinedImportedFunctionsCount++;

126 InlinedImportedFunctionsToImportingModuleCount +=

127 int(Node->second->NumberOfRealInlines > 0);

128 } else {

129 InlinedNotImportedFunctionsCount++;

130 InlinedNotImportedFunctionsToImportingModuleCount +=

131 int(Node->second->NumberOfRealInlines > 0);

132 }

133

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";

141 }

142

143 auto InlinedFunctionsCount =

144 InlinedImportedFunctionsCount + InlinedNotImportedFunctionsCount;

145 auto NotImportedFuncCount = AllFunctions - ImportedFunctions;

146 auto ImportedNotInlinedIntoModule =

147 ImportedFunctions - InlinedImportedFunctionsToImportingModuleCount;

148

149 Ostream << "-- Summary:\n"

150 << "All functions: " << AllFunctions

151 << ", imported functions: " << ImportedFunctions << "\n"

152 << getStatString("inlined functions", InlinedFunctionsCount,

153 AllFunctions, "all functions")

154 << getStatString("imported functions inlined anywhere",

155 InlinedImportedFunctionsCount, ImportedFunctions,

156 "imported functions")

157 << getStatString("imported functions inlined into importing module",

158 InlinedImportedFunctionsToImportingModuleCount,

159 ImportedFunctions, "imported functions",

160 false)

161 << getStatString(", remaining", ImportedNotInlinedIntoModule,

162 ImportedFunctions, "imported functions")

163 << getStatString("non-imported functions inlined anywhere",

164 InlinedNotImportedFunctionsCount,

165 NotImportedFuncCount, "non-imported functions")

167 "non-imported functions inlined into importing module",

168 InlinedNotImportedFunctionsToImportingModuleCount,

169 NotImportedFuncCount, "non-imported functions");

171 dbgs() << Out;

172}

173

174void ImportedFunctionsInliningStatistics::calculateRealInlines() {

175

177 NonImportedCallers.erase(llvm::unique(NonImportedCallers),

178 NonImportedCallers.end());

179

180 for (const auto &Name : NonImportedCallers) {

181 auto &Node = *NodesMap[Name];

182 if (Node.Visited)

184 }

185}

186

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);

194 }

195}

196

197ImportedFunctionsInliningStatistics::SortedNodesTy

198ImportedFunctionsInliningStatistics::getSortedNodes() {

199 SortedNodesTy SortedNodes;

200 SortedNodes.reserve(NodesMap.size());

202 SortedNodes.push_back(&Node);

203

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();

212 });

213 return SortedNodes;

214}

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)

Definition ImportedFunctionsInliningStatistics.cpp:83

LLVM_ABI void setModuleInfo(const Module &M)

Set information like AllFunctions, ImportedFunctions, ModuleName.

Definition ImportedFunctionsInliningStatistics.cpp:74

LLVM_ABI void dump(bool Verbose)

Dump stats computed with InlinerStatistics class.

Definition ImportedFunctionsInliningStatistics.cpp:98

LLVM_ABI void recordInline(const Function &Caller, const Function &Callee)

Record inline of.

Definition ImportedFunctionsInliningStatistics.cpp:47

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"))