LLVM  10.0.0svn
ProfileSummary.cpp
Go to the documentation of this file.
1 //=-- Profilesummary.cpp - Profile summary support --------------------------=//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains support for converting profile summary data from/to
10 // metadata.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/IR/ProfileSummary.h"
15 #include "llvm/IR/Attributes.h"
16 #include "llvm/IR/Constants.h"
17 #include "llvm/IR/Function.h"
18 #include "llvm/IR/Metadata.h"
19 #include "llvm/IR/Type.h"
20 #include "llvm/Support/Casting.h"
21 
22 using namespace llvm;
23 
24 // Return an MDTuple with two elements. The first element is a string Key and
25 // the second is a uint64_t Value.
26 static Metadata *getKeyValMD(LLVMContext &Context, const char *Key,
27  uint64_t Val) {
28  Type *Int64Ty = Type::getInt64Ty(Context);
29  Metadata *Ops[2] = {MDString::get(Context, Key),
31  return MDTuple::get(Context, Ops);
32 }
33 
34 // Return an MDTuple with two elements. The first element is a string Key and
35 // the second is a string Value.
36 static Metadata *getKeyValMD(LLVMContext &Context, const char *Key,
37  const char *Val) {
38  Metadata *Ops[2] = {MDString::get(Context, Key), MDString::get(Context, Val)};
39  return MDTuple::get(Context, Ops);
40 }
41 
42 // This returns an MDTuple representing the detiled summary. The tuple has two
43 // elements: a string "DetailedSummary" and an MDTuple representing the value
44 // of the detailed summary. Each element of this tuple is again an MDTuple whose
45 // elements are the (Cutoff, MinCount, NumCounts) triplet of the
46 // DetailedSummaryEntry.
47 Metadata *ProfileSummary::getDetailedSummaryMD(LLVMContext &Context) {
48  std::vector<Metadata *> Entries;
49  Type *Int32Ty = Type::getInt32Ty(Context);
50  Type *Int64Ty = Type::getInt64Ty(Context);
51  for (auto &Entry : DetailedSummary) {
52  Metadata *EntryMD[3] = {
55  ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Entry.NumCounts))};
56  Entries.push_back(MDTuple::get(Context, EntryMD));
57  }
58  Metadata *Ops[2] = {MDString::get(Context, "DetailedSummary"),
59  MDTuple::get(Context, Entries)};
60  return MDTuple::get(Context, Ops);
61 }
62 
63 // This returns an MDTuple representing this ProfileSummary object. The first
64 // entry of this tuple is another MDTuple of two elements: a string
65 // "ProfileFormat" and a string representing the format ("InstrProf" or
66 // "SampleProfile"). The rest of the elements of the outer MDTuple are specific
67 // to the kind of profile summary as returned by getFormatSpecificMD.
69  const char *KindStr[3] = {"InstrProf", "CSInstrProf", "SampleProfile"};
70  Metadata *Components[] = {
71  getKeyValMD(Context, "ProfileFormat", KindStr[PSK]),
72  getKeyValMD(Context, "TotalCount", getTotalCount()),
73  getKeyValMD(Context, "MaxCount", getMaxCount()),
74  getKeyValMD(Context, "MaxInternalCount", getMaxInternalCount()),
75  getKeyValMD(Context, "MaxFunctionCount", getMaxFunctionCount()),
76  getKeyValMD(Context, "NumCounts", getNumCounts()),
77  getKeyValMD(Context, "NumFunctions", getNumFunctions()),
78  getDetailedSummaryMD(Context),
79  };
80  return MDTuple::get(Context, Components);
81 }
82 
83 // Parse an MDTuple representing (Key, Val) pair.
84 static bool getVal(MDTuple *MD, const char *Key, uint64_t &Val) {
85  if (!MD)
86  return false;
87  if (MD->getNumOperands() != 2)
88  return false;
89  MDString *KeyMD = dyn_cast<MDString>(MD->getOperand(0));
91  if (!KeyMD || !ValMD)
92  return false;
93  if (!KeyMD->getString().equals(Key))
94  return false;
95  Val = cast<ConstantInt>(ValMD->getValue())->getZExtValue();
96  return true;
97 }
98 
99 // Check if an MDTuple represents a (Key, Val) pair.
100 static bool isKeyValuePair(MDTuple *MD, const char *Key, const char *Val) {
101  if (!MD || MD->getNumOperands() != 2)
102  return false;
103  MDString *KeyMD = dyn_cast<MDString>(MD->getOperand(0));
104  MDString *ValMD = dyn_cast<MDString>(MD->getOperand(1));
105  if (!KeyMD || !ValMD)
106  return false;
107  if (!KeyMD->getString().equals(Key) || !ValMD->getString().equals(Val))
108  return false;
109  return true;
110 }
111 
112 // Parse an MDTuple representing detailed summary.
113 static bool getSummaryFromMD(MDTuple *MD, SummaryEntryVector &Summary) {
114  if (!MD || MD->getNumOperands() != 2)
115  return false;
116  MDString *KeyMD = dyn_cast<MDString>(MD->getOperand(0));
117  if (!KeyMD || !KeyMD->getString().equals("DetailedSummary"))
118  return false;
119  MDTuple *EntriesMD = dyn_cast<MDTuple>(MD->getOperand(1));
120  if (!EntriesMD)
121  return false;
122  for (auto &&MDOp : EntriesMD->operands()) {
123  MDTuple *EntryMD = dyn_cast<MDTuple>(MDOp);
124  if (!EntryMD || EntryMD->getNumOperands() != 3)
125  return false;
126  ConstantAsMetadata *Op0 =
127  dyn_cast<ConstantAsMetadata>(EntryMD->getOperand(0));
128  ConstantAsMetadata *Op1 =
129  dyn_cast<ConstantAsMetadata>(EntryMD->getOperand(1));
130  ConstantAsMetadata *Op2 =
131  dyn_cast<ConstantAsMetadata>(EntryMD->getOperand(2));
132 
133  if (!Op0 || !Op1 || !Op2)
134  return false;
135  Summary.emplace_back(cast<ConstantInt>(Op0->getValue())->getZExtValue(),
136  cast<ConstantInt>(Op1->getValue())->getZExtValue(),
137  cast<ConstantInt>(Op2->getValue())->getZExtValue());
138  }
139  return true;
140 }
141 
143  MDTuple *Tuple = dyn_cast_or_null<MDTuple>(MD);
144  if (!Tuple || Tuple->getNumOperands() != 8)
145  return nullptr;
146 
147  auto &FormatMD = Tuple->getOperand(0);
148  ProfileSummary::Kind SummaryKind;
149  if (isKeyValuePair(dyn_cast_or_null<MDTuple>(FormatMD), "ProfileFormat",
150  "SampleProfile"))
151  SummaryKind = PSK_Sample;
152  else if (isKeyValuePair(dyn_cast_or_null<MDTuple>(FormatMD), "ProfileFormat",
153  "InstrProf"))
154  SummaryKind = PSK_Instr;
155  else if (isKeyValuePair(dyn_cast_or_null<MDTuple>(FormatMD), "ProfileFormat",
156  "CSInstrProf"))
157  SummaryKind = PSK_CSInstr;
158  else
159  return nullptr;
160 
161  uint64_t NumCounts, TotalCount, NumFunctions, MaxFunctionCount, MaxCount,
162  MaxInternalCount;
163  if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(1)), "TotalCount",
164  TotalCount))
165  return nullptr;
166  if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(2)), "MaxCount", MaxCount))
167  return nullptr;
168  if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(3)), "MaxInternalCount",
169  MaxInternalCount))
170  return nullptr;
171  if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(4)), "MaxFunctionCount",
172  MaxFunctionCount))
173  return nullptr;
174  if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(5)), "NumCounts", NumCounts))
175  return nullptr;
176  if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(6)), "NumFunctions",
177  NumFunctions))
178  return nullptr;
179 
180  SummaryEntryVector Summary;
181  if (!getSummaryFromMD(dyn_cast<MDTuple>(Tuple->getOperand(7)), Summary))
182  return nullptr;
183  return new ProfileSummary(SummaryKind, std::move(Summary), TotalCount,
184  MaxCount, MaxInternalCount, MaxFunctionCount,
185  NumCounts, NumFunctions);
186 }
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata *> MDs)
Definition: Metadata.h:1132
LLVMContext & Context
This class represents lattice values for constants.
Definition: AllocatorList.h:23
static MDString * get(LLVMContext &Context, StringRef Str)
Definition: Metadata.cpp:453
This file contains the declarations for metadata subclasses.
static bool isKeyValuePair(MDTuple *MD, const char *Key, const char *Val)
const MDOperand & getOperand(unsigned I) const
Definition: Metadata.h:1068
static IntegerType * getInt64Ty(LLVMContext &C)
Definition: Type.cpp:176
uint64_t getMaxInternalCount()
Tuple of metadata.
Definition: Metadata.h:1105
static bool getVal(MDTuple *MD, const char *Key, uint64_t &Val)
Metadata * getMD(LLVMContext &Context)
Return summary information as metadata.
ProfileSummary(Kind K, SummaryEntryVector DetailedSummary, uint64_t TotalCount, uint64_t MaxCount, uint64_t MaxInternalCount, uint64_t MaxFunctionCount, uint32_t NumCounts, uint32_t NumFunctions)
This file contains the simple types necessary to represent the attributes associated with functions a...
Key
PAL metadata keys.
static Metadata * getKeyValMD(LLVMContext &Context, const char *Key, uint64_t Val)
op_range operands() const
Definition: Metadata.h:1066
uint64_t getMaxFunctionCount()
static ConstantAsMetadata * get(Constant *C)
Definition: Metadata.h:409
StringRef getString() const
Definition: Metadata.cpp:463
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:64
This file contains the declarations for the subclasses of Constant, which represent the different fla...
uint64_t getTotalCount()
Constant * getValue() const
Definition: Metadata.h:417
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
Definition: Constants.cpp:640
static bool getSummaryFromMD(MDTuple *MD, SummaryEntryVector &Summary)
static ProfileSummary * getFromMD(Metadata *MD)
Construct profile summary from metdata.
LLVM_NODISCARD bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
Definition: StringRef.h:160
uint32_t getNumFunctions()
static IntegerType * getInt32Ty(LLVMContext &C)
Definition: Type.cpp:175
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:332
A single uniqued string.
Definition: Metadata.h:603
std::vector< ProfileSummaryEntry > SummaryEntryVector
unsigned getNumOperands() const
Return number of MDNode operands.
Definition: Metadata.h:1074
Root of the metadata hierarchy.
Definition: Metadata.h:57
IntegerType * Int32Ty