1 //=-- InstrProf.cpp - Instrumented profiling format 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 clang's instrumentation based PGO and 11 // coverage. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "llvm/ProfileData/InstrProf.h" 16 #include "llvm/ADT/StringExtras.h" 17 #include "llvm/IR/Constants.h" 18 #include "llvm/IR/Function.h" 19 #include "llvm/IR/GlobalVariable.h" 20 #include "llvm/IR/MDBuilder.h" 21 #include "llvm/IR/Module.h" 22 #include "llvm/Support/Compression.h" 23 #include "llvm/Support/ErrorHandling.h" 24 #include "llvm/Support/LEB128.h" 25 #include "llvm/Support/ManagedStatic.h" 26 27 using namespace llvm; 28 29 namespace { 30 class InstrProfErrorCategoryType : public std::error_category { 31 const char *name() const LLVM_NOEXCEPT override { return "llvm.instrprof"; } 32 std::string message(int IE) const override { 33 instrprof_error E = static_cast<instrprof_error>(IE); 34 switch (E) { 35 case instrprof_error::success: 36 return "Success"; 37 case instrprof_error::eof: 38 return "End of File"; 39 case instrprof_error::unrecognized_format: 40 return "Unrecognized instrumentation profile encoding format"; 41 case instrprof_error::bad_magic: 42 return "Invalid instrumentation profile data (bad magic)"; 43 case instrprof_error::bad_header: 44 return "Invalid instrumentation profile data (file header is corrupt)"; 45 case instrprof_error::unsupported_version: 46 return "Unsupported instrumentation profile format version"; 47 case instrprof_error::unsupported_hash_type: 48 return "Unsupported instrumentation profile hash type"; 49 case instrprof_error::too_large: 50 return "Too much profile data"; 51 case instrprof_error::truncated: 52 return "Truncated profile data"; 53 case instrprof_error::malformed: 54 return "Malformed instrumentation profile data"; 55 case instrprof_error::unknown_function: 56 return "No profile data available for function"; 57 case instrprof_error::hash_mismatch: 58 return "Function control flow change detected (hash mismatch)"; 59 case instrprof_error::count_mismatch: 60 return "Function basic block count change detected (counter mismatch)"; 61 case instrprof_error::counter_overflow: 62 return "Counter overflow"; 63 case instrprof_error::value_site_count_mismatch: 64 return "Function value site count change detected (counter mismatch)"; 65 } 66 llvm_unreachable("A value of instrprof_error has no message."); 67 } 68 }; 69 } // end anonymous namespace 70 71 static ManagedStatic<InstrProfErrorCategoryType> ErrorCategory; 72 73 const std::error_category &llvm::instrprof_category() { 74 return *ErrorCategory; 75 } 76 77 namespace llvm { 78 79 std::string getPGOFuncName(StringRef RawFuncName, 80 GlobalValue::LinkageTypes Linkage, 81 StringRef FileName, 82 uint64_t Version LLVM_ATTRIBUTE_UNUSED) { 83 return GlobalValue::getGlobalIdentifier(RawFuncName, Linkage, FileName); 84 } 85 86 std::string getPGOFuncName(const Function &F, uint64_t Version) { 87 return getPGOFuncName(F.getName(), F.getLinkage(), F.getParent()->getName(), 88 Version); 89 } 90 91 StringRef getFuncNameWithoutPrefix(StringRef PGOFuncName, StringRef FileName) { 92 if (FileName.empty()) 93 FileName = "<unknown>"; 94 // Drop the file name including ':'. See also getPGOFuncName. 95 if (PGOFuncName.startswith(FileName)) 96 PGOFuncName = PGOFuncName.drop_front(FileName.size() + 1); 97 return PGOFuncName; 98 } 99 100 // \p FuncName is the string used as profile lookup key for the function. A 101 // symbol is created to hold the name. Return the legalized symbol name. 102 std::string getPGOFuncNameVarName(StringRef FuncName, 103 GlobalValue::LinkageTypes Linkage) { 104 std::string VarName = getInstrProfNameVarPrefix(); 105 VarName += FuncName; 106 107 if (!GlobalValue::isLocalLinkage(Linkage)) 108 return VarName; 109 110 // Now fix up illegal chars in local VarName that may upset the assembler. 111 const char *InvalidChars = "-:<>\"'"; 112 size_t found = VarName.find_first_of(InvalidChars); 113 while (found != std::string::npos) { 114 VarName[found] = '_'; 115 found = VarName.find_first_of(InvalidChars, found + 1); 116 } 117 return VarName; 118 } 119 120 GlobalVariable *createPGOFuncNameVar(Module &M, 121 GlobalValue::LinkageTypes Linkage, 122 StringRef PGOFuncName) { 123 124 // We generally want to match the function's linkage, but available_externally 125 // and extern_weak both have the wrong semantics, and anything that doesn't 126 // need to link across compilation units doesn't need to be visible at all. 127 if (Linkage == GlobalValue::ExternalWeakLinkage) 128 Linkage = GlobalValue::LinkOnceAnyLinkage; 129 else if (Linkage == GlobalValue::AvailableExternallyLinkage) 130 Linkage = GlobalValue::LinkOnceODRLinkage; 131 else if (Linkage == GlobalValue::InternalLinkage || 132 Linkage == GlobalValue::ExternalLinkage) 133 Linkage = GlobalValue::PrivateLinkage; 134 135 auto *Value = 136 ConstantDataArray::getString(M.getContext(), PGOFuncName, false); 137 auto FuncNameVar = 138 new GlobalVariable(M, Value->getType(), true, Linkage, Value, 139 getPGOFuncNameVarName(PGOFuncName, Linkage)); 140 141 // Hide the symbol so that we correctly get a copy for each executable. 142 if (!GlobalValue::isLocalLinkage(FuncNameVar->getLinkage())) 143 FuncNameVar->setVisibility(GlobalValue::HiddenVisibility); 144 145 return FuncNameVar; 146 } 147 148 GlobalVariable *createPGOFuncNameVar(Function &F, StringRef PGOFuncName) { 149 return createPGOFuncNameVar(*F.getParent(), F.getLinkage(), PGOFuncName); 150 } 151 152 void InstrProfSymtab::create(const Module &M) { 153 for (const Function &F : M) 154 addFuncName(getPGOFuncName(F)); 155 156 finalizeSymtab(); 157 } 158 159 int collectPGOFuncNameStrings(const std::vector<std::string> &NameStrs, 160 bool doCompression, std::string &Result) { 161 uint8_t Header[16], *P = Header; 162 std::string UncompressedNameStrings = 163 join(NameStrs.begin(), NameStrs.end(), StringRef(" ")); 164 165 unsigned EncLen = encodeULEB128(UncompressedNameStrings.length(), P); 166 P += EncLen; 167 168 auto WriteStringToResult = [&](size_t CompressedLen, 169 const std::string &InputStr) { 170 EncLen = encodeULEB128(CompressedLen, P); 171 P += EncLen; 172 char *HeaderStr = reinterpret_cast<char *>(&Header[0]); 173 unsigned HeaderLen = P - &Header[0]; 174 Result.append(HeaderStr, HeaderLen); 175 Result += InputStr; 176 return 0; 177 }; 178 179 if (!doCompression) 180 return WriteStringToResult(0, UncompressedNameStrings); 181 182 SmallVector<char, 128> CompressedNameStrings; 183 zlib::Status Success = 184 zlib::compress(StringRef(UncompressedNameStrings), CompressedNameStrings, 185 zlib::BestSizeCompression); 186 187 if (Success != zlib::StatusOK) 188 return 1; 189 190 return WriteStringToResult( 191 CompressedNameStrings.size(), 192 std::string(CompressedNameStrings.data(), CompressedNameStrings.size())); 193 } 194 195 StringRef getPGOFuncNameVarInitializer(GlobalVariable *NameVar) { 196 auto *Arr = cast<ConstantDataArray>(NameVar->getInitializer()); 197 StringRef NameStr = 198 Arr->isCString() ? Arr->getAsCString() : Arr->getAsString(); 199 return NameStr; 200 } 201 202 int collectPGOFuncNameStrings(const std::vector<GlobalVariable *> &NameVars, 203 std::string &Result, bool doCompression) { 204 std::vector<std::string> NameStrs; 205 for (auto *NameVar : NameVars) { 206 NameStrs.push_back(getPGOFuncNameVarInitializer(NameVar)); 207 } 208 return collectPGOFuncNameStrings( 209 NameStrs, zlib::isAvailable() && doCompression, Result); 210 } 211 212 int readPGOFuncNameStrings(StringRef NameStrings, InstrProfSymtab &Symtab) { 213 const uint8_t *P = reinterpret_cast<const uint8_t *>(NameStrings.data()); 214 const uint8_t *EndP = reinterpret_cast<const uint8_t *>(NameStrings.data() + 215 NameStrings.size()); 216 while (P < EndP) { 217 uint32_t N; 218 uint64_t UncompressedSize = decodeULEB128(P, &N); 219 P += N; 220 uint64_t CompressedSize = decodeULEB128(P, &N); 221 P += N; 222 bool isCompressed = (CompressedSize != 0); 223 SmallString<128> UncompressedNameStrings; 224 StringRef NameStrings; 225 if (isCompressed) { 226 StringRef CompressedNameStrings(reinterpret_cast<const char *>(P), 227 CompressedSize); 228 if (zlib::uncompress(CompressedNameStrings, UncompressedNameStrings, 229 UncompressedSize) != zlib::StatusOK) 230 return 1; 231 P += CompressedSize; 232 NameStrings = StringRef(UncompressedNameStrings.data(), 233 UncompressedNameStrings.size()); 234 } else { 235 NameStrings = 236 StringRef(reinterpret_cast<const char *>(P), UncompressedSize); 237 P += UncompressedSize; 238 } 239 // Now parse the name strings. 240 SmallVector<StringRef, 0> Names; 241 NameStrings.split(Names, ' '); 242 for (StringRef &Name : Names) 243 Symtab.addFuncName(Name); 244 245 while (P < EndP && *P == 0) 246 P++; 247 } 248 Symtab.finalizeSymtab(); 249 return 0; 250 } 251 252 instrprof_error InstrProfValueSiteRecord::merge(InstrProfValueSiteRecord &Input, 253 uint64_t Weight) { 254 this->sortByTargetValues(); 255 Input.sortByTargetValues(); 256 auto I = ValueData.begin(); 257 auto IE = ValueData.end(); 258 instrprof_error Result = instrprof_error::success; 259 for (auto J = Input.ValueData.begin(), JE = Input.ValueData.end(); J != JE; 260 ++J) { 261 while (I != IE && I->Value < J->Value) 262 ++I; 263 if (I != IE && I->Value == J->Value) { 264 bool Overflowed; 265 I->Count = SaturatingMultiplyAdd(J->Count, Weight, I->Count, &Overflowed); 266 if (Overflowed) 267 Result = instrprof_error::counter_overflow; 268 ++I; 269 continue; 270 } 271 ValueData.insert(I, *J); 272 } 273 return Result; 274 } 275 276 instrprof_error InstrProfValueSiteRecord::scale(uint64_t Weight) { 277 instrprof_error Result = instrprof_error::success; 278 for (auto I = ValueData.begin(), IE = ValueData.end(); I != IE; ++I) { 279 bool Overflowed; 280 I->Count = SaturatingMultiply(I->Count, Weight, &Overflowed); 281 if (Overflowed) 282 Result = instrprof_error::counter_overflow; 283 } 284 return Result; 285 } 286 287 // Merge Value Profile data from Src record to this record for ValueKind. 288 // Scale merged value counts by \p Weight. 289 instrprof_error InstrProfRecord::mergeValueProfData(uint32_t ValueKind, 290 InstrProfRecord &Src, 291 uint64_t Weight) { 292 uint32_t ThisNumValueSites = getNumValueSites(ValueKind); 293 uint32_t OtherNumValueSites = Src.getNumValueSites(ValueKind); 294 if (ThisNumValueSites != OtherNumValueSites) 295 return instrprof_error::value_site_count_mismatch; 296 std::vector<InstrProfValueSiteRecord> &ThisSiteRecords = 297 getValueSitesForKind(ValueKind); 298 std::vector<InstrProfValueSiteRecord> &OtherSiteRecords = 299 Src.getValueSitesForKind(ValueKind); 300 instrprof_error Result = instrprof_error::success; 301 for (uint32_t I = 0; I < ThisNumValueSites; I++) 302 MergeResult(Result, ThisSiteRecords[I].merge(OtherSiteRecords[I], Weight)); 303 return Result; 304 } 305 306 instrprof_error InstrProfRecord::merge(InstrProfRecord &Other, 307 uint64_t Weight) { 308 // If the number of counters doesn't match we either have bad data 309 // or a hash collision. 310 if (Counts.size() != Other.Counts.size()) 311 return instrprof_error::count_mismatch; 312 313 instrprof_error Result = instrprof_error::success; 314 315 for (size_t I = 0, E = Other.Counts.size(); I < E; ++I) { 316 bool Overflowed; 317 Counts[I] = 318 SaturatingMultiplyAdd(Other.Counts[I], Weight, Counts[I], &Overflowed); 319 if (Overflowed) 320 Result = instrprof_error::counter_overflow; 321 } 322 323 for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) 324 MergeResult(Result, mergeValueProfData(Kind, Other, Weight)); 325 326 return Result; 327 } 328 329 instrprof_error InstrProfRecord::scaleValueProfData(uint32_t ValueKind, 330 uint64_t Weight) { 331 uint32_t ThisNumValueSites = getNumValueSites(ValueKind); 332 std::vector<InstrProfValueSiteRecord> &ThisSiteRecords = 333 getValueSitesForKind(ValueKind); 334 instrprof_error Result = instrprof_error::success; 335 for (uint32_t I = 0; I < ThisNumValueSites; I++) 336 MergeResult(Result, ThisSiteRecords[I].scale(Weight)); 337 return Result; 338 } 339 340 instrprof_error InstrProfRecord::scale(uint64_t Weight) { 341 instrprof_error Result = instrprof_error::success; 342 for (auto &Count : this->Counts) { 343 bool Overflowed; 344 Count = SaturatingMultiply(Count, Weight, &Overflowed); 345 if (Overflowed && Result == instrprof_error::success) { 346 Result = instrprof_error::counter_overflow; 347 } 348 } 349 for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) 350 MergeResult(Result, scaleValueProfData(Kind, Weight)); 351 352 return Result; 353 } 354 355 // Map indirect call target name hash to name string. 356 uint64_t InstrProfRecord::remapValue(uint64_t Value, uint32_t ValueKind, 357 ValueMapType *ValueMap) { 358 if (!ValueMap) 359 return Value; 360 switch (ValueKind) { 361 case IPVK_IndirectCallTarget: { 362 auto Result = 363 std::lower_bound(ValueMap->begin(), ValueMap->end(), Value, 364 [](const std::pair<uint64_t, uint64_t> &LHS, 365 uint64_t RHS) { return LHS.first < RHS; }); 366 if (Result != ValueMap->end()) 367 Value = (uint64_t)Result->second; 368 break; 369 } 370 } 371 return Value; 372 } 373 374 void InstrProfRecord::addValueData(uint32_t ValueKind, uint32_t Site, 375 InstrProfValueData *VData, uint32_t N, 376 ValueMapType *ValueMap) { 377 for (uint32_t I = 0; I < N; I++) { 378 VData[I].Value = remapValue(VData[I].Value, ValueKind, ValueMap); 379 } 380 std::vector<InstrProfValueSiteRecord> &ValueSites = 381 getValueSitesForKind(ValueKind); 382 if (N == 0) 383 ValueSites.push_back(InstrProfValueSiteRecord()); 384 else 385 ValueSites.emplace_back(VData, VData + N); 386 } 387 388 #define INSTR_PROF_COMMON_API_IMPL 389 #include "llvm/ProfileData/InstrProfData.inc" 390 391 /*! 392 * \brief ValueProfRecordClosure Interface implementation for InstrProfRecord 393 * class. These C wrappers are used as adaptors so that C++ code can be 394 * invoked as callbacks. 395 */ 396 uint32_t getNumValueKindsInstrProf(const void *Record) { 397 return reinterpret_cast<const InstrProfRecord *>(Record)->getNumValueKinds(); 398 } 399 400 uint32_t getNumValueSitesInstrProf(const void *Record, uint32_t VKind) { 401 return reinterpret_cast<const InstrProfRecord *>(Record) 402 ->getNumValueSites(VKind); 403 } 404 405 uint32_t getNumValueDataInstrProf(const void *Record, uint32_t VKind) { 406 return reinterpret_cast<const InstrProfRecord *>(Record) 407 ->getNumValueData(VKind); 408 } 409 410 uint32_t getNumValueDataForSiteInstrProf(const void *R, uint32_t VK, 411 uint32_t S) { 412 return reinterpret_cast<const InstrProfRecord *>(R) 413 ->getNumValueDataForSite(VK, S); 414 } 415 416 void getValueForSiteInstrProf(const void *R, InstrProfValueData *Dst, 417 uint32_t K, uint32_t S) { 418 reinterpret_cast<const InstrProfRecord *>(R)->getValueForSite(Dst, K, S); 419 return; 420 } 421 422 ValueProfData *allocValueProfDataInstrProf(size_t TotalSizeInBytes) { 423 ValueProfData *VD = 424 (ValueProfData *)(new (::operator new(TotalSizeInBytes)) ValueProfData()); 425 memset(VD, 0, TotalSizeInBytes); 426 return VD; 427 } 428 429 static ValueProfRecordClosure InstrProfRecordClosure = { 430 nullptr, 431 getNumValueKindsInstrProf, 432 getNumValueSitesInstrProf, 433 getNumValueDataInstrProf, 434 getNumValueDataForSiteInstrProf, 435 nullptr, 436 getValueForSiteInstrProf, 437 allocValueProfDataInstrProf}; 438 439 // Wrapper implementation using the closure mechanism. 440 uint32_t ValueProfData::getSize(const InstrProfRecord &Record) { 441 InstrProfRecordClosure.Record = &Record; 442 return getValueProfDataSize(&InstrProfRecordClosure); 443 } 444 445 // Wrapper implementation using the closure mechanism. 446 std::unique_ptr<ValueProfData> 447 ValueProfData::serializeFrom(const InstrProfRecord &Record) { 448 InstrProfRecordClosure.Record = &Record; 449 450 std::unique_ptr<ValueProfData> VPD( 451 serializeValueProfDataFrom(&InstrProfRecordClosure, nullptr)); 452 return VPD; 453 } 454 455 void ValueProfRecord::deserializeTo(InstrProfRecord &Record, 456 InstrProfRecord::ValueMapType *VMap) { 457 Record.reserveSites(Kind, NumValueSites); 458 459 InstrProfValueData *ValueData = getValueProfRecordValueData(this); 460 for (uint64_t VSite = 0; VSite < NumValueSites; ++VSite) { 461 uint8_t ValueDataCount = this->SiteCountArray[VSite]; 462 Record.addValueData(Kind, VSite, ValueData, ValueDataCount, VMap); 463 ValueData += ValueDataCount; 464 } 465 } 466 467 // For writing/serializing, Old is the host endianness, and New is 468 // byte order intended on disk. For Reading/deserialization, Old 469 // is the on-disk source endianness, and New is the host endianness. 470 void ValueProfRecord::swapBytes(support::endianness Old, 471 support::endianness New) { 472 using namespace support; 473 if (Old == New) 474 return; 475 476 if (getHostEndianness() != Old) { 477 sys::swapByteOrder<uint32_t>(NumValueSites); 478 sys::swapByteOrder<uint32_t>(Kind); 479 } 480 uint32_t ND = getValueProfRecordNumValueData(this); 481 InstrProfValueData *VD = getValueProfRecordValueData(this); 482 483 // No need to swap byte array: SiteCountArrray. 484 for (uint32_t I = 0; I < ND; I++) { 485 sys::swapByteOrder<uint64_t>(VD[I].Value); 486 sys::swapByteOrder<uint64_t>(VD[I].Count); 487 } 488 if (getHostEndianness() == Old) { 489 sys::swapByteOrder<uint32_t>(NumValueSites); 490 sys::swapByteOrder<uint32_t>(Kind); 491 } 492 } 493 494 void ValueProfData::deserializeTo(InstrProfRecord &Record, 495 InstrProfRecord::ValueMapType *VMap) { 496 if (NumValueKinds == 0) 497 return; 498 499 ValueProfRecord *VR = getFirstValueProfRecord(this); 500 for (uint32_t K = 0; K < NumValueKinds; K++) { 501 VR->deserializeTo(Record, VMap); 502 VR = getValueProfRecordNext(VR); 503 } 504 } 505 506 template <class T> 507 static T swapToHostOrder(const unsigned char *&D, support::endianness Orig) { 508 using namespace support; 509 if (Orig == little) 510 return endian::readNext<T, little, unaligned>(D); 511 else 512 return endian::readNext<T, big, unaligned>(D); 513 } 514 515 static std::unique_ptr<ValueProfData> allocValueProfData(uint32_t TotalSize) { 516 return std::unique_ptr<ValueProfData>(new (::operator new(TotalSize)) 517 ValueProfData()); 518 } 519 520 instrprof_error ValueProfData::checkIntegrity() { 521 if (NumValueKinds > IPVK_Last + 1) 522 return instrprof_error::malformed; 523 // Total size needs to be mulltiple of quadword size. 524 if (TotalSize % sizeof(uint64_t)) 525 return instrprof_error::malformed; 526 527 ValueProfRecord *VR = getFirstValueProfRecord(this); 528 for (uint32_t K = 0; K < this->NumValueKinds; K++) { 529 if (VR->Kind > IPVK_Last) 530 return instrprof_error::malformed; 531 VR = getValueProfRecordNext(VR); 532 if ((char *)VR - (char *)this > (ptrdiff_t)TotalSize) 533 return instrprof_error::malformed; 534 } 535 return instrprof_error::success; 536 } 537 538 ErrorOr<std::unique_ptr<ValueProfData>> 539 ValueProfData::getValueProfData(const unsigned char *D, 540 const unsigned char *const BufferEnd, 541 support::endianness Endianness) { 542 using namespace support; 543 if (D + sizeof(ValueProfData) > BufferEnd) 544 return instrprof_error::truncated; 545 546 const unsigned char *Header = D; 547 uint32_t TotalSize = swapToHostOrder<uint32_t>(Header, Endianness); 548 if (D + TotalSize > BufferEnd) 549 return instrprof_error::too_large; 550 551 std::unique_ptr<ValueProfData> VPD = allocValueProfData(TotalSize); 552 memcpy(VPD.get(), D, TotalSize); 553 // Byte swap. 554 VPD->swapBytesToHost(Endianness); 555 556 instrprof_error EC = VPD->checkIntegrity(); 557 if (EC != instrprof_error::success) 558 return EC; 559 560 return std::move(VPD); 561 } 562 563 void ValueProfData::swapBytesToHost(support::endianness Endianness) { 564 using namespace support; 565 if (Endianness == getHostEndianness()) 566 return; 567 568 sys::swapByteOrder<uint32_t>(TotalSize); 569 sys::swapByteOrder<uint32_t>(NumValueKinds); 570 571 ValueProfRecord *VR = getFirstValueProfRecord(this); 572 for (uint32_t K = 0; K < NumValueKinds; K++) { 573 VR->swapBytes(Endianness, getHostEndianness()); 574 VR = getValueProfRecordNext(VR); 575 } 576 } 577 578 void ValueProfData::swapBytesFromHost(support::endianness Endianness) { 579 using namespace support; 580 if (Endianness == getHostEndianness()) 581 return; 582 583 ValueProfRecord *VR = getFirstValueProfRecord(this); 584 for (uint32_t K = 0; K < NumValueKinds; K++) { 585 ValueProfRecord *NVR = getValueProfRecordNext(VR); 586 VR->swapBytes(getHostEndianness(), Endianness); 587 VR = NVR; 588 } 589 sys::swapByteOrder<uint32_t>(TotalSize); 590 sys::swapByteOrder<uint32_t>(NumValueKinds); 591 } 592 593 void annotateValueSite(Module &M, Instruction &Inst, 594 const InstrProfRecord &InstrProfR, 595 InstrProfValueKind ValueKind, uint32_t SiteIdx, 596 uint32_t MaxMDCount) { 597 uint32_t NV = InstrProfR.getNumValueDataForSite(ValueKind, SiteIdx); 598 599 uint64_t Sum = 0; 600 std::unique_ptr<InstrProfValueData[]> VD = 601 InstrProfR.getValueForSite(ValueKind, SiteIdx, &Sum); 602 603 annotateValueSite(M, Inst, VD.get(), NV, Sum, ValueKind, MaxMDCount); 604 } 605 606 void annotateValueSite(Module &M, Instruction &Inst, 607 const InstrProfValueData VD[], uint32_t NV, 608 uint64_t Sum, InstrProfValueKind ValueKind, 609 uint32_t MaxMDCount) { 610 LLVMContext &Ctx = M.getContext(); 611 MDBuilder MDHelper(Ctx); 612 SmallVector<Metadata *, 3> Vals; 613 // Tag 614 Vals.push_back(MDHelper.createString("VP")); 615 // Value Kind 616 Vals.push_back(MDHelper.createConstant( 617 ConstantInt::get(Type::getInt32Ty(Ctx), ValueKind))); 618 // Total Count 619 Vals.push_back( 620 MDHelper.createConstant(ConstantInt::get(Type::getInt64Ty(Ctx), Sum))); 621 622 // Value Profile Data 623 uint32_t MDCount = MaxMDCount; 624 for (uint32_t I = 0; I < NV; ++I) { 625 Vals.push_back(MDHelper.createConstant( 626 ConstantInt::get(Type::getInt64Ty(Ctx), VD[I].Value))); 627 Vals.push_back(MDHelper.createConstant( 628 ConstantInt::get(Type::getInt64Ty(Ctx), VD[I].Count))); 629 if (--MDCount == 0) 630 break; 631 } 632 Inst.setMetadata(LLVMContext::MD_prof, MDNode::get(Ctx, Vals)); 633 } 634 635 bool getValueProfDataFromInst(const Instruction &Inst, 636 InstrProfValueKind ValueKind, 637 uint32_t MaxNumValueData, 638 InstrProfValueData ValueData[], 639 uint32_t &ActualNumValueData, uint64_t &TotalC) { 640 MDNode *MD = Inst.getMetadata(LLVMContext::MD_prof); 641 if (!MD) 642 return false; 643 644 unsigned NOps = MD->getNumOperands(); 645 646 if (NOps < 5) 647 return false; 648 649 // Operand 0 is a string tag "VP": 650 MDString *Tag = cast<MDString>(MD->getOperand(0)); 651 if (!Tag) 652 return false; 653 654 if (!Tag->getString().equals("VP")) 655 return false; 656 657 // Now check kind: 658 ConstantInt *KindInt = mdconst::dyn_extract<ConstantInt>(MD->getOperand(1)); 659 if (!KindInt) 660 return false; 661 if (KindInt->getZExtValue() != ValueKind) 662 return false; 663 664 // Get total count 665 ConstantInt *TotalCInt = mdconst::dyn_extract<ConstantInt>(MD->getOperand(2)); 666 if (!TotalCInt) 667 return false; 668 TotalC = TotalCInt->getZExtValue(); 669 670 ActualNumValueData = 0; 671 672 for (unsigned I = 3; I < NOps; I += 2) { 673 if (ActualNumValueData >= MaxNumValueData) 674 break; 675 ConstantInt *Value = mdconst::dyn_extract<ConstantInt>(MD->getOperand(I)); 676 ConstantInt *Count = 677 mdconst::dyn_extract<ConstantInt>(MD->getOperand(I + 1)); 678 if (!Value || !Count) 679 return false; 680 ValueData[ActualNumValueData].Value = Value->getZExtValue(); 681 ValueData[ActualNumValueData].Count = Count->getZExtValue(); 682 ActualNumValueData++; 683 } 684 return true; 685 } 686 } // end namespace llvm 687