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 23 using namespace llvm; 24 25 const 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. 29 static 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. 39 static 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. 50 Metadata *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. 71 Metadata *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. 86 static 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. 102 static 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. 115 static 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 144 ProfileSummary *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