LLVM  9.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 const char *ProfileSummary::KindStr[2] = {"InstrProf", "SampleProfile"};
25 
26 // Return an MDTuple with two elements. The first element is a string Key and
27 // the second is a uint64_t Value.
28 static Metadata *getKeyValMD(LLVMContext &Context, const char *Key,
29  uint64_t Val) {
30  Type *Int64Ty = Type::getInt64Ty(Context);
31  Metadata *Ops[2] = {MDString::get(Context, Key),
33  return MDTuple::get(Context, Ops);
34 }
35 
36 // Return an MDTuple with two elements. The first element is a string Key and
37 // the second is a string Value.
38 static Metadata *getKeyValMD(LLVMContext &Context, const char *Key,
39  const char *Val) {
40  Metadata *Ops[2] = {MDString::get(Context, Key), MDString::get(Context, Val)};
41  return MDTuple::get(Context, Ops);
42 }
43 
44 // This returns an MDTuple representing the detiled summary. The tuple has two
45 // elements: a string "DetailedSummary" and an MDTuple representing the value
46 // of the detailed summary. Each element of this tuple is again an MDTuple whose
47 // elements are the (Cutoff, MinCount, NumCounts) triplet of the
48 // DetailedSummaryEntry.
49 Metadata *ProfileSummary::getDetailedSummaryMD(LLVMContext &Context) {
50  std::vector<Metadata *> Entries;
51  Type *Int32Ty = Type::getInt32Ty(Context);
52  Type *Int64Ty = Type::getInt64Ty(Context);
53  for (auto &Entry : DetailedSummary) {
54  Metadata *EntryMD[3] = {
55  ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Entry.Cutoff)),
56  ConstantAsMetadata::get(ConstantInt::get(Int64Ty, Entry.MinCount)),
57  ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Entry.NumCounts))};
58  Entries.push_back(MDTuple::get(Context, EntryMD));
59  }
60  Metadata *Ops[2] = {MDString::get(Context, "DetailedSummary"),
61  MDTuple::get(Context, Entries)};
62  return MDTuple::get(Context, Ops);
63 }
64 
65 // This returns an MDTuple representing this ProfileSummary object. The first
66 // entry of this tuple is another MDTuple of two elements: a string
67 // "ProfileFormat" and a string representing the format ("InstrProf" or
68 // "SampleProfile"). The rest of the elements of the outer MDTuple are specific
69 // to the kind of profile summary as returned by getFormatSpecificMD.
71  Metadata *Components[] = {
72  getKeyValMD(Context, "ProfileFormat", KindStr[PSK]),
73  getKeyValMD(Context, "TotalCount", getTotalCount()),
74  getKeyValMD(Context, "MaxCount", getMaxCount()),
75  getKeyValMD(Context, "MaxInternalCount", getMaxInternalCount()),
76  getKeyValMD(Context, "MaxFunctionCount", getMaxFunctionCount()),
77  getKeyValMD(Context, "NumCounts", getNumCounts()),
78  getKeyValMD(Context, "NumFunctions", getNumFunctions()),
79  getDetailedSummaryMD(Context),
80  };
81  return MDTuple::get(Context, Components);
82 }
83 
84 // Parse an MDTuple representing (Key, Val) pair.
85 static bool getVal(MDTuple *MD, const char *Key, uint64_t &Val) {
86  if (!MD)
87  return false;
88  if (MD->getNumOperands() != 2)
89  return false;
90  MDString *KeyMD = dyn_cast<MDString>(MD->getOperand(0));
92  if (!KeyMD || !ValMD)
93  return false;
94  if (!KeyMD->getString().equals(Key))
95  return false;
96  Val = cast<ConstantInt>(ValMD->getValue())->getZExtValue();
97  return true;
98 }
99 
100 // Check if an MDTuple represents a (Key, Val) pair.
101 static bool isKeyValuePair(MDTuple *MD, const char *Key, const char *Val) {
102  if (!MD || MD->getNumOperands() != 2)
103  return false;
104  MDString *KeyMD = dyn_cast<MDString>(MD->getOperand(0));
105  MDString *ValMD = dyn_cast<MDString>(MD->getOperand(1));
106  if (!KeyMD || !ValMD)
107  return false;
108  if (!KeyMD->getString().equals(Key) || !ValMD->getString().equals(Val))
109  return false;
110  return true;
111 }
112 
113 // Parse an MDTuple representing detailed summary.
114 static bool getSummaryFromMD(MDTuple *MD, SummaryEntryVector &Summary) {
115  if (!MD || MD->getNumOperands() != 2)
116  return false;
117  MDString *KeyMD = dyn_cast<MDString>(MD->getOperand(0));
118  if (!KeyMD || !KeyMD->getString().equals("DetailedSummary"))
119  return false;
120  MDTuple *EntriesMD = dyn_cast<MDTuple>(MD->getOperand(1));
121  if (!EntriesMD)
122  return false;
123  for (auto &&MDOp : EntriesMD->operands()) {
124  MDTuple *EntryMD = dyn_cast<MDTuple>(MDOp);
125  if (!EntryMD || EntryMD->getNumOperands() != 3)
126  return false;
127  ConstantAsMetadata *Op0 =
128  dyn_cast<ConstantAsMetadata>(EntryMD->getOperand(0));
129  ConstantAsMetadata *Op1 =
130  dyn_cast<ConstantAsMetadata>(EntryMD->getOperand(1));
131  ConstantAsMetadata *Op2 =
132  dyn_cast<ConstantAsMetadata>(EntryMD->getOperand(2));
133 
134  if (!Op0 || !Op1 || !Op2)
135  return false;
136  Summary.emplace_back(cast<ConstantInt>(Op0->getValue())->getZExtValue(),
137  cast<ConstantInt>(Op1->getValue())->getZExtValue(),
138  cast<ConstantInt>(Op2->getValue())->getZExtValue());
139  }
140  return true;
141 }
142 
144  MDTuple *Tuple = dyn_cast_or_null<MDTuple>(MD);
145  if (!Tuple || Tuple->getNumOperands() != 8)
146  return nullptr;
147 
148  auto &FormatMD = Tuple->getOperand(0);
149  ProfileSummary::Kind SummaryKind;
150  if (isKeyValuePair(dyn_cast_or_null<MDTuple>(FormatMD), "ProfileFormat",
151  "SampleProfile"))
152  SummaryKind = PSK_Sample;
153  else if (isKeyValuePair(dyn_cast_or_null<MDTuple>(FormatMD), "ProfileFormat",
154  "InstrProf"))
155  SummaryKind = PSK_Instr;
156  else
157  return nullptr;
158 
159  uint64_t NumCounts, TotalCount, NumFunctions, MaxFunctionCount, MaxCount,
160  MaxInternalCount;
161  if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(1)), "TotalCount",
162  TotalCount))
163  return nullptr;
164  if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(2)), "MaxCount", MaxCount))
165  return nullptr;
166  if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(3)), "MaxInternalCount",
167  MaxInternalCount))
168  return nullptr;
169  if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(4)), "MaxFunctionCount",
170  MaxFunctionCount))
171  return nullptr;
172  if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(5)), "NumCounts", NumCounts))
173  return nullptr;
174  if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(6)), "NumFunctions",
175  NumFunctions))
176  return nullptr;
177 
178  SummaryEntryVector Summary;
179  if (!getSummaryFromMD(dyn_cast<MDTuple>(Tuple->getOperand(7)), Summary))
180  return nullptr;
181  return new ProfileSummary(SummaryKind, std::move(Summary), TotalCount,
182  MaxCount, MaxInternalCount, MaxFunctionCount,
183  NumCounts, NumFunctions);
184 }
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:68
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:621
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:322
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