ProfileSummary.cpp revision 303231
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 std::vector<Metadata *> Components; 73 Components.push_back(getKeyValMD(Context, "ProfileFormat", KindStr[PSK])); 74 75 Components.push_back(getKeyValMD(Context, "TotalCount", getTotalCount())); 76 Components.push_back(getKeyValMD(Context, "MaxCount", getMaxCount())); 77 Components.push_back( 78 getKeyValMD(Context, "MaxInternalCount", getMaxInternalCount())); 79 Components.push_back( 80 getKeyValMD(Context, "MaxFunctionCount", getMaxFunctionCount())); 81 Components.push_back(getKeyValMD(Context, "NumCounts", getNumCounts())); 82 Components.push_back(getKeyValMD(Context, "NumFunctions", getNumFunctions())); 83 Components.push_back(getDetailedSummaryMD(Context)); 84 return MDTuple::get(Context, Components); 85} 86 87// Parse an MDTuple representing (Key, Val) pair. 88static bool getVal(MDTuple *MD, const char *Key, uint64_t &Val) { 89 if (!MD) 90 return false; 91 if (MD->getNumOperands() != 2) 92 return false; 93 MDString *KeyMD = dyn_cast<MDString>(MD->getOperand(0)); 94 ConstantAsMetadata *ValMD = dyn_cast<ConstantAsMetadata>(MD->getOperand(1)); 95 if (!KeyMD || !ValMD) 96 return false; 97 if (!KeyMD->getString().equals(Key)) 98 return false; 99 Val = cast<ConstantInt>(ValMD->getValue())->getZExtValue(); 100 return true; 101} 102 103// Check if an MDTuple represents a (Key, Val) pair. 104static bool isKeyValuePair(MDTuple *MD, const char *Key, const char *Val) { 105 if (!MD || MD->getNumOperands() != 2) 106 return false; 107 MDString *KeyMD = dyn_cast<MDString>(MD->getOperand(0)); 108 MDString *ValMD = dyn_cast<MDString>(MD->getOperand(1)); 109 if (!KeyMD || !ValMD) 110 return false; 111 if (!KeyMD->getString().equals(Key) || !ValMD->getString().equals(Val)) 112 return false; 113 return true; 114} 115 116// Parse an MDTuple representing detailed summary. 117static bool getSummaryFromMD(MDTuple *MD, SummaryEntryVector &Summary) { 118 if (!MD || MD->getNumOperands() != 2) 119 return false; 120 MDString *KeyMD = dyn_cast<MDString>(MD->getOperand(0)); 121 if (!KeyMD || !KeyMD->getString().equals("DetailedSummary")) 122 return false; 123 MDTuple *EntriesMD = dyn_cast<MDTuple>(MD->getOperand(1)); 124 if (!EntriesMD) 125 return false; 126 for (auto &&MDOp : EntriesMD->operands()) { 127 MDTuple *EntryMD = dyn_cast<MDTuple>(MDOp); 128 if (!EntryMD || EntryMD->getNumOperands() != 3) 129 return false; 130 ConstantAsMetadata *Op0 = 131 dyn_cast<ConstantAsMetadata>(EntryMD->getOperand(0)); 132 ConstantAsMetadata *Op1 = 133 dyn_cast<ConstantAsMetadata>(EntryMD->getOperand(1)); 134 ConstantAsMetadata *Op2 = 135 dyn_cast<ConstantAsMetadata>(EntryMD->getOperand(2)); 136 137 if (!Op0 || !Op1 || !Op2) 138 return false; 139 Summary.emplace_back(cast<ConstantInt>(Op0->getValue())->getZExtValue(), 140 cast<ConstantInt>(Op1->getValue())->getZExtValue(), 141 cast<ConstantInt>(Op2->getValue())->getZExtValue()); 142 } 143 return true; 144} 145 146ProfileSummary *ProfileSummary::getFromMD(Metadata *MD) { 147 if (!MD) 148 return nullptr; 149 if (!isa<MDTuple>(MD)) 150 return nullptr; 151 MDTuple *Tuple = cast<MDTuple>(MD); 152 if (Tuple->getNumOperands() != 8) 153 return nullptr; 154 155 auto &FormatMD = Tuple->getOperand(0); 156 ProfileSummary::Kind SummaryKind; 157 if (isKeyValuePair(dyn_cast_or_null<MDTuple>(FormatMD), "ProfileFormat", 158 "SampleProfile")) 159 SummaryKind = PSK_Sample; 160 else if (isKeyValuePair(dyn_cast_or_null<MDTuple>(FormatMD), "ProfileFormat", 161 "InstrProf")) 162 SummaryKind = PSK_Instr; 163 else 164 return nullptr; 165 166 uint64_t NumCounts, TotalCount, NumFunctions, MaxFunctionCount, MaxCount, 167 MaxInternalCount; 168 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(1)), "TotalCount", 169 TotalCount)) 170 return nullptr; 171 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(2)), "MaxCount", MaxCount)) 172 return nullptr; 173 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(3)), "MaxInternalCount", 174 MaxInternalCount)) 175 return nullptr; 176 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(4)), "MaxFunctionCount", 177 MaxFunctionCount)) 178 return nullptr; 179 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(5)), "NumCounts", NumCounts)) 180 return nullptr; 181 if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(6)), "NumFunctions", 182 NumFunctions)) 183 return nullptr; 184 185 SummaryEntryVector Summary; 186 if (!getSummaryFromMD(dyn_cast<MDTuple>(Tuple->getOperand(7)), Summary)) 187 return nullptr; 188 return new ProfileSummary(SummaryKind, Summary, TotalCount, MaxCount, 189 MaxInternalCount, MaxFunctionCount, NumCounts, 190 NumFunctions); 191} 192