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