1 //===- InstrProf.cpp - Instrumented profiling format 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 clang's instrumentation based PGO and 10 // coverage. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/ProfileData/InstrProf.h" 15 #include "llvm/ADT/ArrayRef.h" 16 #include "llvm/ADT/SmallString.h" 17 #include "llvm/ADT/SmallVector.h" 18 #include "llvm/ADT/StringExtras.h" 19 #include "llvm/ADT/StringRef.h" 20 #include "llvm/ADT/Triple.h" 21 #include "llvm/Config/config.h" 22 #include "llvm/IR/Constant.h" 23 #include "llvm/IR/Constants.h" 24 #include "llvm/IR/Function.h" 25 #include "llvm/IR/GlobalValue.h" 26 #include "llvm/IR/GlobalVariable.h" 27 #include "llvm/IR/Instruction.h" 28 #include "llvm/IR/LLVMContext.h" 29 #include "llvm/IR/MDBuilder.h" 30 #include "llvm/IR/Metadata.h" 31 #include "llvm/IR/Module.h" 32 #include "llvm/IR/Type.h" 33 #include "llvm/ProfileData/InstrProfReader.h" 34 #include "llvm/Support/Casting.h" 35 #include "llvm/Support/CommandLine.h" 36 #include "llvm/Support/Compiler.h" 37 #include "llvm/Support/Compression.h" 38 #include "llvm/Support/Endian.h" 39 #include "llvm/Support/Error.h" 40 #include "llvm/Support/ErrorHandling.h" 41 #include "llvm/Support/LEB128.h" 42 #include "llvm/Support/ManagedStatic.h" 43 #include "llvm/Support/MathExtras.h" 44 #include "llvm/Support/Path.h" 45 #include "llvm/Support/SwapByteOrder.h" 46 #include <algorithm> 47 #include <cassert> 48 #include <cstddef> 49 #include <cstdint> 50 #include <cstring> 51 #include <memory> 52 #include <string> 53 #include <system_error> 54 #include <utility> 55 #include <vector> 56 57 using namespace llvm; 58 59 static cl::opt<bool> StaticFuncFullModulePrefix( 60 "static-func-full-module-prefix", cl::init(true), cl::Hidden, 61 cl::desc("Use full module build paths in the profile counter names for " 62 "static functions.")); 63 64 // This option is tailored to users that have different top-level directory in 65 // profile-gen and profile-use compilation. Users need to specific the number 66 // of levels to strip. A value larger than the number of directories in the 67 // source file will strip all the directory names and only leave the basename. 68 // 69 // Note current ThinLTO module importing for the indirect-calls assumes 70 // the source directory name not being stripped. A non-zero option value here 71 // can potentially prevent some inter-module indirect-call-promotions. 72 static cl::opt<unsigned> StaticFuncStripDirNamePrefix( 73 "static-func-strip-dirname-prefix", cl::init(0), cl::Hidden, 74 cl::desc("Strip specified level of directory name from source path in " 75 "the profile counter name for static functions.")); 76 77 static std::string getInstrProfErrString(instrprof_error Err, 78 const std::string &ErrMsg = "") { 79 std::string Msg; 80 raw_string_ostream OS(Msg); 81 82 switch (Err) { 83 case instrprof_error::success: 84 OS << "success"; 85 break; 86 case instrprof_error::eof: 87 OS << "end of File"; 88 break; 89 case instrprof_error::unrecognized_format: 90 OS << "unrecognized instrumentation profile encoding format"; 91 break; 92 case instrprof_error::bad_magic: 93 OS << "invalid instrumentation profile data (bad magic)"; 94 break; 95 case instrprof_error::bad_header: 96 OS << "invalid instrumentation profile data (file header is corrupt)"; 97 break; 98 case instrprof_error::unsupported_version: 99 OS << "unsupported instrumentation profile format version"; 100 break; 101 case instrprof_error::unsupported_hash_type: 102 OS << "unsupported instrumentation profile hash type"; 103 break; 104 case instrprof_error::too_large: 105 OS << "too much profile data"; 106 break; 107 case instrprof_error::truncated: 108 OS << "truncated profile data"; 109 break; 110 case instrprof_error::malformed: 111 OS << "malformed instrumentation profile data"; 112 break; 113 case instrprof_error::missing_debug_info_for_correlation: 114 OS << "debug info for correlation is required"; 115 break; 116 case instrprof_error::unexpected_debug_info_for_correlation: 117 OS << "debug info for correlation is not necessary"; 118 break; 119 case instrprof_error::unable_to_correlate_profile: 120 OS << "unable to correlate profile"; 121 break; 122 case instrprof_error::unsupported_debug_format: 123 OS << "unsupported debug info format (only DWARF is supported)"; 124 break; 125 case instrprof_error::invalid_prof: 126 OS << "invalid profile created. Please file a bug " 127 "at: " BUG_REPORT_URL 128 " and include the profraw files that caused this error."; 129 break; 130 case instrprof_error::unknown_function: 131 OS << "no profile data available for function"; 132 break; 133 case instrprof_error::hash_mismatch: 134 OS << "function control flow change detected (hash mismatch)"; 135 break; 136 case instrprof_error::count_mismatch: 137 OS << "function basic block count change detected (counter mismatch)"; 138 break; 139 case instrprof_error::counter_overflow: 140 OS << "counter overflow"; 141 break; 142 case instrprof_error::value_site_count_mismatch: 143 OS << "function value site count change detected (counter mismatch)"; 144 break; 145 case instrprof_error::compress_failed: 146 OS << "failed to compress data (zlib)"; 147 break; 148 case instrprof_error::uncompress_failed: 149 OS << "failed to uncompress data (zlib)"; 150 break; 151 case instrprof_error::empty_raw_profile: 152 OS << "empty raw profile file"; 153 break; 154 case instrprof_error::zlib_unavailable: 155 OS << "profile uses zlib compression but the profile reader was built " 156 "without zlib support"; 157 break; 158 } 159 160 // If optional error message is not empty, append it to the message. 161 if (!ErrMsg.empty()) 162 OS << ": " << ErrMsg; 163 164 return OS.str(); 165 } 166 167 namespace { 168 169 // FIXME: This class is only here to support the transition to llvm::Error. It 170 // will be removed once this transition is complete. Clients should prefer to 171 // deal with the Error value directly, rather than converting to error_code. 172 class InstrProfErrorCategoryType : public std::error_category { 173 const char *name() const noexcept override { return "llvm.instrprof"; } 174 175 std::string message(int IE) const override { 176 return getInstrProfErrString(static_cast<instrprof_error>(IE)); 177 } 178 }; 179 180 } // end anonymous namespace 181 182 static ManagedStatic<InstrProfErrorCategoryType> ErrorCategory; 183 184 const std::error_category &llvm::instrprof_category() { 185 return *ErrorCategory; 186 } 187 188 namespace { 189 190 const char *InstrProfSectNameCommon[] = { 191 #define INSTR_PROF_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix) \ 192 SectNameCommon, 193 #include "llvm/ProfileData/InstrProfData.inc" 194 }; 195 196 const char *InstrProfSectNameCoff[] = { 197 #define INSTR_PROF_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix) \ 198 SectNameCoff, 199 #include "llvm/ProfileData/InstrProfData.inc" 200 }; 201 202 const char *InstrProfSectNamePrefix[] = { 203 #define INSTR_PROF_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix) \ 204 Prefix, 205 #include "llvm/ProfileData/InstrProfData.inc" 206 }; 207 208 } // namespace 209 210 namespace llvm { 211 212 cl::opt<bool> DoInstrProfNameCompression( 213 "enable-name-compression", 214 cl::desc("Enable name/filename string compression"), cl::init(true)); 215 216 std::string getInstrProfSectionName(InstrProfSectKind IPSK, 217 Triple::ObjectFormatType OF, 218 bool AddSegmentInfo) { 219 std::string SectName; 220 221 if (OF == Triple::MachO && AddSegmentInfo) 222 SectName = InstrProfSectNamePrefix[IPSK]; 223 224 if (OF == Triple::COFF) 225 SectName += InstrProfSectNameCoff[IPSK]; 226 else 227 SectName += InstrProfSectNameCommon[IPSK]; 228 229 if (OF == Triple::MachO && IPSK == IPSK_data && AddSegmentInfo) 230 SectName += ",regular,live_support"; 231 232 return SectName; 233 } 234 235 void SoftInstrProfErrors::addError(instrprof_error IE) { 236 if (IE == instrprof_error::success) 237 return; 238 239 if (FirstError == instrprof_error::success) 240 FirstError = IE; 241 242 switch (IE) { 243 case instrprof_error::hash_mismatch: 244 ++NumHashMismatches; 245 break; 246 case instrprof_error::count_mismatch: 247 ++NumCountMismatches; 248 break; 249 case instrprof_error::counter_overflow: 250 ++NumCounterOverflows; 251 break; 252 case instrprof_error::value_site_count_mismatch: 253 ++NumValueSiteCountMismatches; 254 break; 255 default: 256 llvm_unreachable("Not a soft error"); 257 } 258 } 259 260 std::string InstrProfError::message() const { 261 return getInstrProfErrString(Err, Msg); 262 } 263 264 char InstrProfError::ID = 0; 265 266 std::string getPGOFuncName(StringRef RawFuncName, 267 GlobalValue::LinkageTypes Linkage, 268 StringRef FileName, 269 uint64_t Version LLVM_ATTRIBUTE_UNUSED) { 270 return GlobalValue::getGlobalIdentifier(RawFuncName, Linkage, FileName); 271 } 272 273 // Strip NumPrefix level of directory name from PathNameStr. If the number of 274 // directory separators is less than NumPrefix, strip all the directories and 275 // leave base file name only. 276 static StringRef stripDirPrefix(StringRef PathNameStr, uint32_t NumPrefix) { 277 uint32_t Count = NumPrefix; 278 uint32_t Pos = 0, LastPos = 0; 279 for (auto & CI : PathNameStr) { 280 ++Pos; 281 if (llvm::sys::path::is_separator(CI)) { 282 LastPos = Pos; 283 --Count; 284 } 285 if (Count == 0) 286 break; 287 } 288 return PathNameStr.substr(LastPos); 289 } 290 291 // Return the PGOFuncName. This function has some special handling when called 292 // in LTO optimization. The following only applies when calling in LTO passes 293 // (when \c InLTO is true): LTO's internalization privatizes many global linkage 294 // symbols. This happens after value profile annotation, but those internal 295 // linkage functions should not have a source prefix. 296 // Additionally, for ThinLTO mode, exported internal functions are promoted 297 // and renamed. We need to ensure that the original internal PGO name is 298 // used when computing the GUID that is compared against the profiled GUIDs. 299 // To differentiate compiler generated internal symbols from original ones, 300 // PGOFuncName meta data are created and attached to the original internal 301 // symbols in the value profile annotation step 302 // (PGOUseFunc::annotateIndirectCallSites). If a symbol does not have the meta 303 // data, its original linkage must be non-internal. 304 std::string getPGOFuncName(const Function &F, bool InLTO, uint64_t Version) { 305 if (!InLTO) { 306 StringRef FileName(F.getParent()->getSourceFileName()); 307 uint32_t StripLevel = StaticFuncFullModulePrefix ? 0 : (uint32_t)-1; 308 if (StripLevel < StaticFuncStripDirNamePrefix) 309 StripLevel = StaticFuncStripDirNamePrefix; 310 if (StripLevel) 311 FileName = stripDirPrefix(FileName, StripLevel); 312 return getPGOFuncName(F.getName(), F.getLinkage(), FileName, Version); 313 } 314 315 // In LTO mode (when InLTO is true), first check if there is a meta data. 316 if (MDNode *MD = getPGOFuncNameMetadata(F)) { 317 StringRef S = cast<MDString>(MD->getOperand(0))->getString(); 318 return S.str(); 319 } 320 321 // If there is no meta data, the function must be a global before the value 322 // profile annotation pass. Its current linkage may be internal if it is 323 // internalized in LTO mode. 324 return getPGOFuncName(F.getName(), GlobalValue::ExternalLinkage, ""); 325 } 326 327 StringRef getFuncNameWithoutPrefix(StringRef PGOFuncName, StringRef FileName) { 328 if (FileName.empty()) 329 return PGOFuncName; 330 // Drop the file name including ':'. See also getPGOFuncName. 331 if (PGOFuncName.startswith(FileName)) 332 PGOFuncName = PGOFuncName.drop_front(FileName.size() + 1); 333 return PGOFuncName; 334 } 335 336 // \p FuncName is the string used as profile lookup key for the function. A 337 // symbol is created to hold the name. Return the legalized symbol name. 338 std::string getPGOFuncNameVarName(StringRef FuncName, 339 GlobalValue::LinkageTypes Linkage) { 340 std::string VarName = std::string(getInstrProfNameVarPrefix()); 341 VarName += FuncName; 342 343 if (!GlobalValue::isLocalLinkage(Linkage)) 344 return VarName; 345 346 // Now fix up illegal chars in local VarName that may upset the assembler. 347 const char *InvalidChars = "-:<>/\"'"; 348 size_t found = VarName.find_first_of(InvalidChars); 349 while (found != std::string::npos) { 350 VarName[found] = '_'; 351 found = VarName.find_first_of(InvalidChars, found + 1); 352 } 353 return VarName; 354 } 355 356 GlobalVariable *createPGOFuncNameVar(Module &M, 357 GlobalValue::LinkageTypes Linkage, 358 StringRef PGOFuncName) { 359 // We generally want to match the function's linkage, but available_externally 360 // and extern_weak both have the wrong semantics, and anything that doesn't 361 // need to link across compilation units doesn't need to be visible at all. 362 if (Linkage == GlobalValue::ExternalWeakLinkage) 363 Linkage = GlobalValue::LinkOnceAnyLinkage; 364 else if (Linkage == GlobalValue::AvailableExternallyLinkage) 365 Linkage = GlobalValue::LinkOnceODRLinkage; 366 else if (Linkage == GlobalValue::InternalLinkage || 367 Linkage == GlobalValue::ExternalLinkage) 368 Linkage = GlobalValue::PrivateLinkage; 369 370 auto *Value = 371 ConstantDataArray::getString(M.getContext(), PGOFuncName, false); 372 auto FuncNameVar = 373 new GlobalVariable(M, Value->getType(), true, Linkage, Value, 374 getPGOFuncNameVarName(PGOFuncName, Linkage)); 375 376 // Hide the symbol so that we correctly get a copy for each executable. 377 if (!GlobalValue::isLocalLinkage(FuncNameVar->getLinkage())) 378 FuncNameVar->setVisibility(GlobalValue::HiddenVisibility); 379 380 return FuncNameVar; 381 } 382 383 GlobalVariable *createPGOFuncNameVar(Function &F, StringRef PGOFuncName) { 384 return createPGOFuncNameVar(*F.getParent(), F.getLinkage(), PGOFuncName); 385 } 386 387 Error InstrProfSymtab::create(Module &M, bool InLTO) { 388 for (Function &F : M) { 389 // Function may not have a name: like using asm("") to overwrite the name. 390 // Ignore in this case. 391 if (!F.hasName()) 392 continue; 393 const std::string &PGOFuncName = getPGOFuncName(F, InLTO); 394 if (Error E = addFuncName(PGOFuncName)) 395 return E; 396 MD5FuncMap.emplace_back(Function::getGUID(PGOFuncName), &F); 397 // In ThinLTO, local function may have been promoted to global and have 398 // suffix ".llvm." added to the function name. We need to add the 399 // stripped function name to the symbol table so that we can find a match 400 // from profile. 401 // 402 // We may have other suffixes similar as ".llvm." which are needed to 403 // be stripped before the matching, but ".__uniq." suffix which is used 404 // to differentiate internal linkage functions in different modules 405 // should be kept. Now this is the only suffix with the pattern ".xxx" 406 // which is kept before matching. 407 const std::string UniqSuffix = ".__uniq."; 408 auto pos = PGOFuncName.find(UniqSuffix); 409 // Search '.' after ".__uniq." if ".__uniq." exists, otherwise 410 // search '.' from the beginning. 411 if (pos != std::string::npos) 412 pos += UniqSuffix.length(); 413 else 414 pos = 0; 415 pos = PGOFuncName.find('.', pos); 416 if (pos != std::string::npos && pos != 0) { 417 const std::string &OtherFuncName = PGOFuncName.substr(0, pos); 418 if (Error E = addFuncName(OtherFuncName)) 419 return E; 420 MD5FuncMap.emplace_back(Function::getGUID(OtherFuncName), &F); 421 } 422 } 423 Sorted = false; 424 finalizeSymtab(); 425 return Error::success(); 426 } 427 428 uint64_t InstrProfSymtab::getFunctionHashFromAddress(uint64_t Address) { 429 finalizeSymtab(); 430 auto It = partition_point(AddrToMD5Map, [=](std::pair<uint64_t, uint64_t> A) { 431 return A.first < Address; 432 }); 433 // Raw function pointer collected by value profiler may be from 434 // external functions that are not instrumented. They won't have 435 // mapping data to be used by the deserializer. Force the value to 436 // be 0 in this case. 437 if (It != AddrToMD5Map.end() && It->first == Address) 438 return (uint64_t)It->second; 439 return 0; 440 } 441 442 Error collectPGOFuncNameStrings(ArrayRef<std::string> NameStrs, 443 bool doCompression, std::string &Result) { 444 assert(!NameStrs.empty() && "No name data to emit"); 445 446 uint8_t Header[16], *P = Header; 447 std::string UncompressedNameStrings = 448 join(NameStrs.begin(), NameStrs.end(), getInstrProfNameSeparator()); 449 450 assert(StringRef(UncompressedNameStrings) 451 .count(getInstrProfNameSeparator()) == (NameStrs.size() - 1) && 452 "PGO name is invalid (contains separator token)"); 453 454 unsigned EncLen = encodeULEB128(UncompressedNameStrings.length(), P); 455 P += EncLen; 456 457 auto WriteStringToResult = [&](size_t CompressedLen, StringRef InputStr) { 458 EncLen = encodeULEB128(CompressedLen, P); 459 P += EncLen; 460 char *HeaderStr = reinterpret_cast<char *>(&Header[0]); 461 unsigned HeaderLen = P - &Header[0]; 462 Result.append(HeaderStr, HeaderLen); 463 Result += InputStr; 464 return Error::success(); 465 }; 466 467 if (!doCompression) { 468 return WriteStringToResult(0, UncompressedNameStrings); 469 } 470 471 SmallString<128> CompressedNameStrings; 472 Error E = zlib::compress(StringRef(UncompressedNameStrings), 473 CompressedNameStrings, zlib::BestSizeCompression); 474 if (E) { 475 consumeError(std::move(E)); 476 return make_error<InstrProfError>(instrprof_error::compress_failed); 477 } 478 479 return WriteStringToResult(CompressedNameStrings.size(), 480 CompressedNameStrings); 481 } 482 483 StringRef getPGOFuncNameVarInitializer(GlobalVariable *NameVar) { 484 auto *Arr = cast<ConstantDataArray>(NameVar->getInitializer()); 485 StringRef NameStr = 486 Arr->isCString() ? Arr->getAsCString() : Arr->getAsString(); 487 return NameStr; 488 } 489 490 Error collectPGOFuncNameStrings(ArrayRef<GlobalVariable *> NameVars, 491 std::string &Result, bool doCompression) { 492 std::vector<std::string> NameStrs; 493 for (auto *NameVar : NameVars) { 494 NameStrs.push_back(std::string(getPGOFuncNameVarInitializer(NameVar))); 495 } 496 return collectPGOFuncNameStrings( 497 NameStrs, zlib::isAvailable() && doCompression, Result); 498 } 499 500 Error readPGOFuncNameStrings(StringRef NameStrings, InstrProfSymtab &Symtab) { 501 const uint8_t *P = NameStrings.bytes_begin(); 502 const uint8_t *EndP = NameStrings.bytes_end(); 503 while (P < EndP) { 504 uint32_t N; 505 uint64_t UncompressedSize = decodeULEB128(P, &N); 506 P += N; 507 uint64_t CompressedSize = decodeULEB128(P, &N); 508 P += N; 509 bool isCompressed = (CompressedSize != 0); 510 SmallString<128> UncompressedNameStrings; 511 StringRef NameStrings; 512 if (isCompressed) { 513 if (!llvm::zlib::isAvailable()) 514 return make_error<InstrProfError>(instrprof_error::zlib_unavailable); 515 516 StringRef CompressedNameStrings(reinterpret_cast<const char *>(P), 517 CompressedSize); 518 if (Error E = 519 zlib::uncompress(CompressedNameStrings, UncompressedNameStrings, 520 UncompressedSize)) { 521 consumeError(std::move(E)); 522 return make_error<InstrProfError>(instrprof_error::uncompress_failed); 523 } 524 P += CompressedSize; 525 NameStrings = StringRef(UncompressedNameStrings.data(), 526 UncompressedNameStrings.size()); 527 } else { 528 NameStrings = 529 StringRef(reinterpret_cast<const char *>(P), UncompressedSize); 530 P += UncompressedSize; 531 } 532 // Now parse the name strings. 533 SmallVector<StringRef, 0> Names; 534 NameStrings.split(Names, getInstrProfNameSeparator()); 535 for (StringRef &Name : Names) 536 if (Error E = Symtab.addFuncName(Name)) 537 return E; 538 539 while (P < EndP && *P == 0) 540 P++; 541 } 542 return Error::success(); 543 } 544 545 void InstrProfRecord::accumulateCounts(CountSumOrPercent &Sum) const { 546 uint64_t FuncSum = 0; 547 Sum.NumEntries += Counts.size(); 548 for (uint64_t Count : Counts) 549 FuncSum += Count; 550 Sum.CountSum += FuncSum; 551 552 for (uint32_t VK = IPVK_First; VK <= IPVK_Last; ++VK) { 553 uint64_t KindSum = 0; 554 uint32_t NumValueSites = getNumValueSites(VK); 555 for (size_t I = 0; I < NumValueSites; ++I) { 556 uint32_t NV = getNumValueDataForSite(VK, I); 557 std::unique_ptr<InstrProfValueData[]> VD = getValueForSite(VK, I); 558 for (uint32_t V = 0; V < NV; V++) 559 KindSum += VD[V].Count; 560 } 561 Sum.ValueCounts[VK] += KindSum; 562 } 563 } 564 565 void InstrProfValueSiteRecord::overlap(InstrProfValueSiteRecord &Input, 566 uint32_t ValueKind, 567 OverlapStats &Overlap, 568 OverlapStats &FuncLevelOverlap) { 569 this->sortByTargetValues(); 570 Input.sortByTargetValues(); 571 double Score = 0.0f, FuncLevelScore = 0.0f; 572 auto I = ValueData.begin(); 573 auto IE = ValueData.end(); 574 auto J = Input.ValueData.begin(); 575 auto JE = Input.ValueData.end(); 576 while (I != IE && J != JE) { 577 if (I->Value == J->Value) { 578 Score += OverlapStats::score(I->Count, J->Count, 579 Overlap.Base.ValueCounts[ValueKind], 580 Overlap.Test.ValueCounts[ValueKind]); 581 FuncLevelScore += OverlapStats::score( 582 I->Count, J->Count, FuncLevelOverlap.Base.ValueCounts[ValueKind], 583 FuncLevelOverlap.Test.ValueCounts[ValueKind]); 584 ++I; 585 } else if (I->Value < J->Value) { 586 ++I; 587 continue; 588 } 589 ++J; 590 } 591 Overlap.Overlap.ValueCounts[ValueKind] += Score; 592 FuncLevelOverlap.Overlap.ValueCounts[ValueKind] += FuncLevelScore; 593 } 594 595 // Return false on mismatch. 596 void InstrProfRecord::overlapValueProfData(uint32_t ValueKind, 597 InstrProfRecord &Other, 598 OverlapStats &Overlap, 599 OverlapStats &FuncLevelOverlap) { 600 uint32_t ThisNumValueSites = getNumValueSites(ValueKind); 601 assert(ThisNumValueSites == Other.getNumValueSites(ValueKind)); 602 if (!ThisNumValueSites) 603 return; 604 605 std::vector<InstrProfValueSiteRecord> &ThisSiteRecords = 606 getOrCreateValueSitesForKind(ValueKind); 607 MutableArrayRef<InstrProfValueSiteRecord> OtherSiteRecords = 608 Other.getValueSitesForKind(ValueKind); 609 for (uint32_t I = 0; I < ThisNumValueSites; I++) 610 ThisSiteRecords[I].overlap(OtherSiteRecords[I], ValueKind, Overlap, 611 FuncLevelOverlap); 612 } 613 614 void InstrProfRecord::overlap(InstrProfRecord &Other, OverlapStats &Overlap, 615 OverlapStats &FuncLevelOverlap, 616 uint64_t ValueCutoff) { 617 // FuncLevel CountSum for other should already computed and nonzero. 618 assert(FuncLevelOverlap.Test.CountSum >= 1.0f); 619 accumulateCounts(FuncLevelOverlap.Base); 620 bool Mismatch = (Counts.size() != Other.Counts.size()); 621 622 // Check if the value profiles mismatch. 623 if (!Mismatch) { 624 for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) { 625 uint32_t ThisNumValueSites = getNumValueSites(Kind); 626 uint32_t OtherNumValueSites = Other.getNumValueSites(Kind); 627 if (ThisNumValueSites != OtherNumValueSites) { 628 Mismatch = true; 629 break; 630 } 631 } 632 } 633 if (Mismatch) { 634 Overlap.addOneMismatch(FuncLevelOverlap.Test); 635 return; 636 } 637 638 // Compute overlap for value counts. 639 for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) 640 overlapValueProfData(Kind, Other, Overlap, FuncLevelOverlap); 641 642 double Score = 0.0; 643 uint64_t MaxCount = 0; 644 // Compute overlap for edge counts. 645 for (size_t I = 0, E = Other.Counts.size(); I < E; ++I) { 646 Score += OverlapStats::score(Counts[I], Other.Counts[I], 647 Overlap.Base.CountSum, Overlap.Test.CountSum); 648 MaxCount = std::max(Other.Counts[I], MaxCount); 649 } 650 Overlap.Overlap.CountSum += Score; 651 Overlap.Overlap.NumEntries += 1; 652 653 if (MaxCount >= ValueCutoff) { 654 double FuncScore = 0.0; 655 for (size_t I = 0, E = Other.Counts.size(); I < E; ++I) 656 FuncScore += OverlapStats::score(Counts[I], Other.Counts[I], 657 FuncLevelOverlap.Base.CountSum, 658 FuncLevelOverlap.Test.CountSum); 659 FuncLevelOverlap.Overlap.CountSum = FuncScore; 660 FuncLevelOverlap.Overlap.NumEntries = Other.Counts.size(); 661 FuncLevelOverlap.Valid = true; 662 } 663 } 664 665 void InstrProfValueSiteRecord::merge(InstrProfValueSiteRecord &Input, 666 uint64_t Weight, 667 function_ref<void(instrprof_error)> Warn) { 668 this->sortByTargetValues(); 669 Input.sortByTargetValues(); 670 auto I = ValueData.begin(); 671 auto IE = ValueData.end(); 672 for (const InstrProfValueData &J : Input.ValueData) { 673 while (I != IE && I->Value < J.Value) 674 ++I; 675 if (I != IE && I->Value == J.Value) { 676 bool Overflowed; 677 I->Count = SaturatingMultiplyAdd(J.Count, Weight, I->Count, &Overflowed); 678 if (Overflowed) 679 Warn(instrprof_error::counter_overflow); 680 ++I; 681 continue; 682 } 683 ValueData.insert(I, J); 684 } 685 } 686 687 void InstrProfValueSiteRecord::scale(uint64_t N, uint64_t D, 688 function_ref<void(instrprof_error)> Warn) { 689 for (InstrProfValueData &I : ValueData) { 690 bool Overflowed; 691 I.Count = SaturatingMultiply(I.Count, N, &Overflowed) / D; 692 if (Overflowed) 693 Warn(instrprof_error::counter_overflow); 694 } 695 } 696 697 // Merge Value Profile data from Src record to this record for ValueKind. 698 // Scale merged value counts by \p Weight. 699 void InstrProfRecord::mergeValueProfData( 700 uint32_t ValueKind, InstrProfRecord &Src, uint64_t Weight, 701 function_ref<void(instrprof_error)> Warn) { 702 uint32_t ThisNumValueSites = getNumValueSites(ValueKind); 703 uint32_t OtherNumValueSites = Src.getNumValueSites(ValueKind); 704 if (ThisNumValueSites != OtherNumValueSites) { 705 Warn(instrprof_error::value_site_count_mismatch); 706 return; 707 } 708 if (!ThisNumValueSites) 709 return; 710 std::vector<InstrProfValueSiteRecord> &ThisSiteRecords = 711 getOrCreateValueSitesForKind(ValueKind); 712 MutableArrayRef<InstrProfValueSiteRecord> OtherSiteRecords = 713 Src.getValueSitesForKind(ValueKind); 714 for (uint32_t I = 0; I < ThisNumValueSites; I++) 715 ThisSiteRecords[I].merge(OtherSiteRecords[I], Weight, Warn); 716 } 717 718 void InstrProfRecord::merge(InstrProfRecord &Other, uint64_t Weight, 719 function_ref<void(instrprof_error)> Warn) { 720 // If the number of counters doesn't match we either have bad data 721 // or a hash collision. 722 if (Counts.size() != Other.Counts.size()) { 723 Warn(instrprof_error::count_mismatch); 724 return; 725 } 726 727 for (size_t I = 0, E = Other.Counts.size(); I < E; ++I) { 728 bool Overflowed; 729 Counts[I] = 730 SaturatingMultiplyAdd(Other.Counts[I], Weight, Counts[I], &Overflowed); 731 if (Overflowed) 732 Warn(instrprof_error::counter_overflow); 733 } 734 735 for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) 736 mergeValueProfData(Kind, Other, Weight, Warn); 737 } 738 739 void InstrProfRecord::scaleValueProfData( 740 uint32_t ValueKind, uint64_t N, uint64_t D, 741 function_ref<void(instrprof_error)> Warn) { 742 for (auto &R : getValueSitesForKind(ValueKind)) 743 R.scale(N, D, Warn); 744 } 745 746 void InstrProfRecord::scale(uint64_t N, uint64_t D, 747 function_ref<void(instrprof_error)> Warn) { 748 assert(D != 0 && "D cannot be 0"); 749 for (auto &Count : this->Counts) { 750 bool Overflowed; 751 Count = SaturatingMultiply(Count, N, &Overflowed) / D; 752 if (Overflowed) 753 Warn(instrprof_error::counter_overflow); 754 } 755 for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) 756 scaleValueProfData(Kind, N, D, Warn); 757 } 758 759 // Map indirect call target name hash to name string. 760 uint64_t InstrProfRecord::remapValue(uint64_t Value, uint32_t ValueKind, 761 InstrProfSymtab *SymTab) { 762 if (!SymTab) 763 return Value; 764 765 if (ValueKind == IPVK_IndirectCallTarget) 766 return SymTab->getFunctionHashFromAddress(Value); 767 768 return Value; 769 } 770 771 void InstrProfRecord::addValueData(uint32_t ValueKind, uint32_t Site, 772 InstrProfValueData *VData, uint32_t N, 773 InstrProfSymtab *ValueMap) { 774 for (uint32_t I = 0; I < N; I++) { 775 VData[I].Value = remapValue(VData[I].Value, ValueKind, ValueMap); 776 } 777 std::vector<InstrProfValueSiteRecord> &ValueSites = 778 getOrCreateValueSitesForKind(ValueKind); 779 if (N == 0) 780 ValueSites.emplace_back(); 781 else 782 ValueSites.emplace_back(VData, VData + N); 783 } 784 785 #define INSTR_PROF_COMMON_API_IMPL 786 #include "llvm/ProfileData/InstrProfData.inc" 787 788 /*! 789 * ValueProfRecordClosure Interface implementation for InstrProfRecord 790 * class. These C wrappers are used as adaptors so that C++ code can be 791 * invoked as callbacks. 792 */ 793 uint32_t getNumValueKindsInstrProf(const void *Record) { 794 return reinterpret_cast<const InstrProfRecord *>(Record)->getNumValueKinds(); 795 } 796 797 uint32_t getNumValueSitesInstrProf(const void *Record, uint32_t VKind) { 798 return reinterpret_cast<const InstrProfRecord *>(Record) 799 ->getNumValueSites(VKind); 800 } 801 802 uint32_t getNumValueDataInstrProf(const void *Record, uint32_t VKind) { 803 return reinterpret_cast<const InstrProfRecord *>(Record) 804 ->getNumValueData(VKind); 805 } 806 807 uint32_t getNumValueDataForSiteInstrProf(const void *R, uint32_t VK, 808 uint32_t S) { 809 return reinterpret_cast<const InstrProfRecord *>(R) 810 ->getNumValueDataForSite(VK, S); 811 } 812 813 void getValueForSiteInstrProf(const void *R, InstrProfValueData *Dst, 814 uint32_t K, uint32_t S) { 815 reinterpret_cast<const InstrProfRecord *>(R)->getValueForSite(Dst, K, S); 816 } 817 818 ValueProfData *allocValueProfDataInstrProf(size_t TotalSizeInBytes) { 819 ValueProfData *VD = 820 (ValueProfData *)(new (::operator new(TotalSizeInBytes)) ValueProfData()); 821 memset(VD, 0, TotalSizeInBytes); 822 return VD; 823 } 824 825 static ValueProfRecordClosure InstrProfRecordClosure = { 826 nullptr, 827 getNumValueKindsInstrProf, 828 getNumValueSitesInstrProf, 829 getNumValueDataInstrProf, 830 getNumValueDataForSiteInstrProf, 831 nullptr, 832 getValueForSiteInstrProf, 833 allocValueProfDataInstrProf}; 834 835 // Wrapper implementation using the closure mechanism. 836 uint32_t ValueProfData::getSize(const InstrProfRecord &Record) { 837 auto Closure = InstrProfRecordClosure; 838 Closure.Record = &Record; 839 return getValueProfDataSize(&Closure); 840 } 841 842 // Wrapper implementation using the closure mechanism. 843 std::unique_ptr<ValueProfData> 844 ValueProfData::serializeFrom(const InstrProfRecord &Record) { 845 InstrProfRecordClosure.Record = &Record; 846 847 std::unique_ptr<ValueProfData> VPD( 848 serializeValueProfDataFrom(&InstrProfRecordClosure, nullptr)); 849 return VPD; 850 } 851 852 void ValueProfRecord::deserializeTo(InstrProfRecord &Record, 853 InstrProfSymtab *SymTab) { 854 Record.reserveSites(Kind, NumValueSites); 855 856 InstrProfValueData *ValueData = getValueProfRecordValueData(this); 857 for (uint64_t VSite = 0; VSite < NumValueSites; ++VSite) { 858 uint8_t ValueDataCount = this->SiteCountArray[VSite]; 859 Record.addValueData(Kind, VSite, ValueData, ValueDataCount, SymTab); 860 ValueData += ValueDataCount; 861 } 862 } 863 864 // For writing/serializing, Old is the host endianness, and New is 865 // byte order intended on disk. For Reading/deserialization, Old 866 // is the on-disk source endianness, and New is the host endianness. 867 void ValueProfRecord::swapBytes(support::endianness Old, 868 support::endianness New) { 869 using namespace support; 870 871 if (Old == New) 872 return; 873 874 if (getHostEndianness() != Old) { 875 sys::swapByteOrder<uint32_t>(NumValueSites); 876 sys::swapByteOrder<uint32_t>(Kind); 877 } 878 uint32_t ND = getValueProfRecordNumValueData(this); 879 InstrProfValueData *VD = getValueProfRecordValueData(this); 880 881 // No need to swap byte array: SiteCountArrray. 882 for (uint32_t I = 0; I < ND; I++) { 883 sys::swapByteOrder<uint64_t>(VD[I].Value); 884 sys::swapByteOrder<uint64_t>(VD[I].Count); 885 } 886 if (getHostEndianness() == Old) { 887 sys::swapByteOrder<uint32_t>(NumValueSites); 888 sys::swapByteOrder<uint32_t>(Kind); 889 } 890 } 891 892 void ValueProfData::deserializeTo(InstrProfRecord &Record, 893 InstrProfSymtab *SymTab) { 894 if (NumValueKinds == 0) 895 return; 896 897 ValueProfRecord *VR = getFirstValueProfRecord(this); 898 for (uint32_t K = 0; K < NumValueKinds; K++) { 899 VR->deserializeTo(Record, SymTab); 900 VR = getValueProfRecordNext(VR); 901 } 902 } 903 904 template <class T> 905 static T swapToHostOrder(const unsigned char *&D, support::endianness Orig) { 906 using namespace support; 907 908 if (Orig == little) 909 return endian::readNext<T, little, unaligned>(D); 910 else 911 return endian::readNext<T, big, unaligned>(D); 912 } 913 914 static std::unique_ptr<ValueProfData> allocValueProfData(uint32_t TotalSize) { 915 return std::unique_ptr<ValueProfData>(new (::operator new(TotalSize)) 916 ValueProfData()); 917 } 918 919 Error ValueProfData::checkIntegrity() { 920 if (NumValueKinds > IPVK_Last + 1) 921 return make_error<InstrProfError>( 922 instrprof_error::malformed, "number of value profile kinds is invalid"); 923 // Total size needs to be multiple of quadword size. 924 if (TotalSize % sizeof(uint64_t)) 925 return make_error<InstrProfError>( 926 instrprof_error::malformed, "total size is not multiples of quardword"); 927 928 ValueProfRecord *VR = getFirstValueProfRecord(this); 929 for (uint32_t K = 0; K < this->NumValueKinds; K++) { 930 if (VR->Kind > IPVK_Last) 931 return make_error<InstrProfError>(instrprof_error::malformed, 932 "value kind is invalid"); 933 VR = getValueProfRecordNext(VR); 934 if ((char *)VR - (char *)this > (ptrdiff_t)TotalSize) 935 return make_error<InstrProfError>( 936 instrprof_error::malformed, 937 "value profile address is greater than total size"); 938 } 939 return Error::success(); 940 } 941 942 Expected<std::unique_ptr<ValueProfData>> 943 ValueProfData::getValueProfData(const unsigned char *D, 944 const unsigned char *const BufferEnd, 945 support::endianness Endianness) { 946 using namespace support; 947 948 if (D + sizeof(ValueProfData) > BufferEnd) 949 return make_error<InstrProfError>(instrprof_error::truncated); 950 951 const unsigned char *Header = D; 952 uint32_t TotalSize = swapToHostOrder<uint32_t>(Header, Endianness); 953 if (D + TotalSize > BufferEnd) 954 return make_error<InstrProfError>(instrprof_error::too_large); 955 956 std::unique_ptr<ValueProfData> VPD = allocValueProfData(TotalSize); 957 memcpy(VPD.get(), D, TotalSize); 958 // Byte swap. 959 VPD->swapBytesToHost(Endianness); 960 961 Error E = VPD->checkIntegrity(); 962 if (E) 963 return std::move(E); 964 965 return std::move(VPD); 966 } 967 968 void ValueProfData::swapBytesToHost(support::endianness Endianness) { 969 using namespace support; 970 971 if (Endianness == getHostEndianness()) 972 return; 973 974 sys::swapByteOrder<uint32_t>(TotalSize); 975 sys::swapByteOrder<uint32_t>(NumValueKinds); 976 977 ValueProfRecord *VR = getFirstValueProfRecord(this); 978 for (uint32_t K = 0; K < NumValueKinds; K++) { 979 VR->swapBytes(Endianness, getHostEndianness()); 980 VR = getValueProfRecordNext(VR); 981 } 982 } 983 984 void ValueProfData::swapBytesFromHost(support::endianness Endianness) { 985 using namespace support; 986 987 if (Endianness == getHostEndianness()) 988 return; 989 990 ValueProfRecord *VR = getFirstValueProfRecord(this); 991 for (uint32_t K = 0; K < NumValueKinds; K++) { 992 ValueProfRecord *NVR = getValueProfRecordNext(VR); 993 VR->swapBytes(getHostEndianness(), Endianness); 994 VR = NVR; 995 } 996 sys::swapByteOrder<uint32_t>(TotalSize); 997 sys::swapByteOrder<uint32_t>(NumValueKinds); 998 } 999 1000 void annotateValueSite(Module &M, Instruction &Inst, 1001 const InstrProfRecord &InstrProfR, 1002 InstrProfValueKind ValueKind, uint32_t SiteIdx, 1003 uint32_t MaxMDCount) { 1004 uint32_t NV = InstrProfR.getNumValueDataForSite(ValueKind, SiteIdx); 1005 if (!NV) 1006 return; 1007 1008 uint64_t Sum = 0; 1009 std::unique_ptr<InstrProfValueData[]> VD = 1010 InstrProfR.getValueForSite(ValueKind, SiteIdx, &Sum); 1011 1012 ArrayRef<InstrProfValueData> VDs(VD.get(), NV); 1013 annotateValueSite(M, Inst, VDs, Sum, ValueKind, MaxMDCount); 1014 } 1015 1016 void annotateValueSite(Module &M, Instruction &Inst, 1017 ArrayRef<InstrProfValueData> VDs, 1018 uint64_t Sum, InstrProfValueKind ValueKind, 1019 uint32_t MaxMDCount) { 1020 LLVMContext &Ctx = M.getContext(); 1021 MDBuilder MDHelper(Ctx); 1022 SmallVector<Metadata *, 3> Vals; 1023 // Tag 1024 Vals.push_back(MDHelper.createString("VP")); 1025 // Value Kind 1026 Vals.push_back(MDHelper.createConstant( 1027 ConstantInt::get(Type::getInt32Ty(Ctx), ValueKind))); 1028 // Total Count 1029 Vals.push_back( 1030 MDHelper.createConstant(ConstantInt::get(Type::getInt64Ty(Ctx), Sum))); 1031 1032 // Value Profile Data 1033 uint32_t MDCount = MaxMDCount; 1034 for (auto &VD : VDs) { 1035 Vals.push_back(MDHelper.createConstant( 1036 ConstantInt::get(Type::getInt64Ty(Ctx), VD.Value))); 1037 Vals.push_back(MDHelper.createConstant( 1038 ConstantInt::get(Type::getInt64Ty(Ctx), VD.Count))); 1039 if (--MDCount == 0) 1040 break; 1041 } 1042 Inst.setMetadata(LLVMContext::MD_prof, MDNode::get(Ctx, Vals)); 1043 } 1044 1045 bool getValueProfDataFromInst(const Instruction &Inst, 1046 InstrProfValueKind ValueKind, 1047 uint32_t MaxNumValueData, 1048 InstrProfValueData ValueData[], 1049 uint32_t &ActualNumValueData, uint64_t &TotalC, 1050 bool GetNoICPValue) { 1051 MDNode *MD = Inst.getMetadata(LLVMContext::MD_prof); 1052 if (!MD) 1053 return false; 1054 1055 unsigned NOps = MD->getNumOperands(); 1056 1057 if (NOps < 5) 1058 return false; 1059 1060 // Operand 0 is a string tag "VP": 1061 MDString *Tag = cast<MDString>(MD->getOperand(0)); 1062 if (!Tag) 1063 return false; 1064 1065 if (!Tag->getString().equals("VP")) 1066 return false; 1067 1068 // Now check kind: 1069 ConstantInt *KindInt = mdconst::dyn_extract<ConstantInt>(MD->getOperand(1)); 1070 if (!KindInt) 1071 return false; 1072 if (KindInt->getZExtValue() != ValueKind) 1073 return false; 1074 1075 // Get total count 1076 ConstantInt *TotalCInt = mdconst::dyn_extract<ConstantInt>(MD->getOperand(2)); 1077 if (!TotalCInt) 1078 return false; 1079 TotalC = TotalCInt->getZExtValue(); 1080 1081 ActualNumValueData = 0; 1082 1083 for (unsigned I = 3; I < NOps; I += 2) { 1084 if (ActualNumValueData >= MaxNumValueData) 1085 break; 1086 ConstantInt *Value = mdconst::dyn_extract<ConstantInt>(MD->getOperand(I)); 1087 ConstantInt *Count = 1088 mdconst::dyn_extract<ConstantInt>(MD->getOperand(I + 1)); 1089 if (!Value || !Count) 1090 return false; 1091 uint64_t CntValue = Count->getZExtValue(); 1092 if (!GetNoICPValue && (CntValue == NOMORE_ICP_MAGICNUM)) 1093 continue; 1094 ValueData[ActualNumValueData].Value = Value->getZExtValue(); 1095 ValueData[ActualNumValueData].Count = CntValue; 1096 ActualNumValueData++; 1097 } 1098 return true; 1099 } 1100 1101 MDNode *getPGOFuncNameMetadata(const Function &F) { 1102 return F.getMetadata(getPGOFuncNameMetadataName()); 1103 } 1104 1105 void createPGOFuncNameMetadata(Function &F, StringRef PGOFuncName) { 1106 // Only for internal linkage functions. 1107 if (PGOFuncName == F.getName()) 1108 return; 1109 // Don't create duplicated meta-data. 1110 if (getPGOFuncNameMetadata(F)) 1111 return; 1112 LLVMContext &C = F.getContext(); 1113 MDNode *N = MDNode::get(C, MDString::get(C, PGOFuncName)); 1114 F.setMetadata(getPGOFuncNameMetadataName(), N); 1115 } 1116 1117 bool needsComdatForCounter(const Function &F, const Module &M) { 1118 if (F.hasComdat()) 1119 return true; 1120 1121 if (!Triple(M.getTargetTriple()).supportsCOMDAT()) 1122 return false; 1123 1124 // See createPGOFuncNameVar for more details. To avoid link errors, profile 1125 // counters for function with available_externally linkage needs to be changed 1126 // to linkonce linkage. On ELF based systems, this leads to weak symbols to be 1127 // created. Without using comdat, duplicate entries won't be removed by the 1128 // linker leading to increased data segement size and raw profile size. Even 1129 // worse, since the referenced counter from profile per-function data object 1130 // will be resolved to the common strong definition, the profile counts for 1131 // available_externally functions will end up being duplicated in raw profile 1132 // data. This can result in distorted profile as the counts of those dups 1133 // will be accumulated by the profile merger. 1134 GlobalValue::LinkageTypes Linkage = F.getLinkage(); 1135 if (Linkage != GlobalValue::ExternalWeakLinkage && 1136 Linkage != GlobalValue::AvailableExternallyLinkage) 1137 return false; 1138 1139 return true; 1140 } 1141 1142 // Check if INSTR_PROF_RAW_VERSION_VAR is defined. 1143 bool isIRPGOFlagSet(const Module *M) { 1144 auto IRInstrVar = 1145 M->getNamedGlobal(INSTR_PROF_QUOTE(INSTR_PROF_RAW_VERSION_VAR)); 1146 if (!IRInstrVar || IRInstrVar->hasLocalLinkage()) 1147 return false; 1148 1149 // For CSPGO+LTO, this variable might be marked as non-prevailing and we only 1150 // have the decl. 1151 if (IRInstrVar->isDeclaration()) 1152 return true; 1153 1154 // Check if the flag is set. 1155 if (!IRInstrVar->hasInitializer()) 1156 return false; 1157 1158 auto *InitVal = dyn_cast_or_null<ConstantInt>(IRInstrVar->getInitializer()); 1159 if (!InitVal) 1160 return false; 1161 return (InitVal->getZExtValue() & VARIANT_MASK_IR_PROF) != 0; 1162 } 1163 1164 // Check if we can safely rename this Comdat function. 1165 bool canRenameComdatFunc(const Function &F, bool CheckAddressTaken) { 1166 if (F.getName().empty()) 1167 return false; 1168 if (!needsComdatForCounter(F, *(F.getParent()))) 1169 return false; 1170 // Unsafe to rename the address-taken function (which can be used in 1171 // function comparison). 1172 if (CheckAddressTaken && F.hasAddressTaken()) 1173 return false; 1174 // Only safe to do if this function may be discarded if it is not used 1175 // in the compilation unit. 1176 if (!GlobalValue::isDiscardableIfUnused(F.getLinkage())) 1177 return false; 1178 1179 // For AvailableExternallyLinkage functions. 1180 if (!F.hasComdat()) { 1181 assert(F.getLinkage() == GlobalValue::AvailableExternallyLinkage); 1182 return true; 1183 } 1184 return true; 1185 } 1186 1187 // Create a COMDAT variable INSTR_PROF_RAW_VERSION_VAR to make the runtime 1188 // aware this is an ir_level profile so it can set the version flag. 1189 GlobalVariable *createIRLevelProfileFlagVar(Module &M, bool IsCS, 1190 bool InstrEntryBBEnabled, 1191 bool DebugInfoCorrelate) { 1192 const StringRef VarName(INSTR_PROF_QUOTE(INSTR_PROF_RAW_VERSION_VAR)); 1193 Type *IntTy64 = Type::getInt64Ty(M.getContext()); 1194 uint64_t ProfileVersion = (INSTR_PROF_RAW_VERSION | VARIANT_MASK_IR_PROF); 1195 if (IsCS) 1196 ProfileVersion |= VARIANT_MASK_CSIR_PROF; 1197 if (InstrEntryBBEnabled) 1198 ProfileVersion |= VARIANT_MASK_INSTR_ENTRY; 1199 if (DebugInfoCorrelate) 1200 ProfileVersion |= VARIANT_MASK_DBG_CORRELATE; 1201 auto IRLevelVersionVariable = new GlobalVariable( 1202 M, IntTy64, true, GlobalValue::WeakAnyLinkage, 1203 Constant::getIntegerValue(IntTy64, APInt(64, ProfileVersion)), VarName); 1204 IRLevelVersionVariable->setVisibility(GlobalValue::DefaultVisibility); 1205 Triple TT(M.getTargetTriple()); 1206 if (TT.supportsCOMDAT()) { 1207 IRLevelVersionVariable->setLinkage(GlobalValue::ExternalLinkage); 1208 IRLevelVersionVariable->setComdat(M.getOrInsertComdat(VarName)); 1209 } 1210 return IRLevelVersionVariable; 1211 } 1212 1213 // Create the variable for the profile file name. 1214 void createProfileFileNameVar(Module &M, StringRef InstrProfileOutput) { 1215 if (InstrProfileOutput.empty()) 1216 return; 1217 Constant *ProfileNameConst = 1218 ConstantDataArray::getString(M.getContext(), InstrProfileOutput, true); 1219 GlobalVariable *ProfileNameVar = new GlobalVariable( 1220 M, ProfileNameConst->getType(), true, GlobalValue::WeakAnyLinkage, 1221 ProfileNameConst, INSTR_PROF_QUOTE(INSTR_PROF_PROFILE_NAME_VAR)); 1222 Triple TT(M.getTargetTriple()); 1223 if (TT.supportsCOMDAT()) { 1224 ProfileNameVar->setLinkage(GlobalValue::ExternalLinkage); 1225 ProfileNameVar->setComdat(M.getOrInsertComdat( 1226 StringRef(INSTR_PROF_QUOTE(INSTR_PROF_PROFILE_NAME_VAR)))); 1227 } 1228 } 1229 1230 Error OverlapStats::accumulateCounts(const std::string &BaseFilename, 1231 const std::string &TestFilename, 1232 bool IsCS) { 1233 auto getProfileSum = [IsCS](const std::string &Filename, 1234 CountSumOrPercent &Sum) -> Error { 1235 auto ReaderOrErr = InstrProfReader::create(Filename); 1236 if (Error E = ReaderOrErr.takeError()) { 1237 return E; 1238 } 1239 auto Reader = std::move(ReaderOrErr.get()); 1240 Reader->accumulateCounts(Sum, IsCS); 1241 return Error::success(); 1242 }; 1243 auto Ret = getProfileSum(BaseFilename, Base); 1244 if (Ret) 1245 return Ret; 1246 Ret = getProfileSum(TestFilename, Test); 1247 if (Ret) 1248 return Ret; 1249 this->BaseFilename = &BaseFilename; 1250 this->TestFilename = &TestFilename; 1251 Valid = true; 1252 return Error::success(); 1253 } 1254 1255 void OverlapStats::addOneMismatch(const CountSumOrPercent &MismatchFunc) { 1256 Mismatch.NumEntries += 1; 1257 Mismatch.CountSum += MismatchFunc.CountSum / Test.CountSum; 1258 for (unsigned I = 0; I < IPVK_Last - IPVK_First + 1; I++) { 1259 if (Test.ValueCounts[I] >= 1.0f) 1260 Mismatch.ValueCounts[I] += 1261 MismatchFunc.ValueCounts[I] / Test.ValueCounts[I]; 1262 } 1263 } 1264 1265 void OverlapStats::addOneUnique(const CountSumOrPercent &UniqueFunc) { 1266 Unique.NumEntries += 1; 1267 Unique.CountSum += UniqueFunc.CountSum / Test.CountSum; 1268 for (unsigned I = 0; I < IPVK_Last - IPVK_First + 1; I++) { 1269 if (Test.ValueCounts[I] >= 1.0f) 1270 Unique.ValueCounts[I] += UniqueFunc.ValueCounts[I] / Test.ValueCounts[I]; 1271 } 1272 } 1273 1274 void OverlapStats::dump(raw_fd_ostream &OS) const { 1275 if (!Valid) 1276 return; 1277 1278 const char *EntryName = 1279 (Level == ProgramLevel ? "functions" : "edge counters"); 1280 if (Level == ProgramLevel) { 1281 OS << "Profile overlap infomation for base_profile: " << *BaseFilename 1282 << " and test_profile: " << *TestFilename << "\nProgram level:\n"; 1283 } else { 1284 OS << "Function level:\n" 1285 << " Function: " << FuncName << " (Hash=" << FuncHash << ")\n"; 1286 } 1287 1288 OS << " # of " << EntryName << " overlap: " << Overlap.NumEntries << "\n"; 1289 if (Mismatch.NumEntries) 1290 OS << " # of " << EntryName << " mismatch: " << Mismatch.NumEntries 1291 << "\n"; 1292 if (Unique.NumEntries) 1293 OS << " # of " << EntryName 1294 << " only in test_profile: " << Unique.NumEntries << "\n"; 1295 1296 OS << " Edge profile overlap: " << format("%.3f%%", Overlap.CountSum * 100) 1297 << "\n"; 1298 if (Mismatch.NumEntries) 1299 OS << " Mismatched count percentage (Edge): " 1300 << format("%.3f%%", Mismatch.CountSum * 100) << "\n"; 1301 if (Unique.NumEntries) 1302 OS << " Percentage of Edge profile only in test_profile: " 1303 << format("%.3f%%", Unique.CountSum * 100) << "\n"; 1304 OS << " Edge profile base count sum: " << format("%.0f", Base.CountSum) 1305 << "\n" 1306 << " Edge profile test count sum: " << format("%.0f", Test.CountSum) 1307 << "\n"; 1308 1309 for (unsigned I = 0; I < IPVK_Last - IPVK_First + 1; I++) { 1310 if (Base.ValueCounts[I] < 1.0f && Test.ValueCounts[I] < 1.0f) 1311 continue; 1312 char ProfileKindName[20]; 1313 switch (I) { 1314 case IPVK_IndirectCallTarget: 1315 strncpy(ProfileKindName, "IndirectCall", 19); 1316 break; 1317 case IPVK_MemOPSize: 1318 strncpy(ProfileKindName, "MemOP", 19); 1319 break; 1320 default: 1321 snprintf(ProfileKindName, 19, "VP[%d]", I); 1322 break; 1323 } 1324 OS << " " << ProfileKindName 1325 << " profile overlap: " << format("%.3f%%", Overlap.ValueCounts[I] * 100) 1326 << "\n"; 1327 if (Mismatch.NumEntries) 1328 OS << " Mismatched count percentage (" << ProfileKindName 1329 << "): " << format("%.3f%%", Mismatch.ValueCounts[I] * 100) << "\n"; 1330 if (Unique.NumEntries) 1331 OS << " Percentage of " << ProfileKindName 1332 << " profile only in test_profile: " 1333 << format("%.3f%%", Unique.ValueCounts[I] * 100) << "\n"; 1334 OS << " " << ProfileKindName 1335 << " profile base count sum: " << format("%.0f", Base.ValueCounts[I]) 1336 << "\n" 1337 << " " << ProfileKindName 1338 << " profile test count sum: " << format("%.0f", Test.ValueCounts[I]) 1339 << "\n"; 1340 } 1341 } 1342 1343 } // end namespace llvm 1344