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