ProfileSummary.cpp 7.5 KB

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