https://github.com/zsrkmyn updated https://github.com/llvm/llvm-project/pull/165358
>From 0fc8d8d02fdf11e2a42b1c8015347ee7ab0a78e0 Mon Sep 17 00:00:00 2001 From: Senran Zhang <[email protected]> Date: Tue, 28 Oct 2025 16:15:07 +0800 Subject: [PATCH 1/4] [InstrProf] Fix frontend generated function hash The most significant 4 bits in function hash are reserved bits, and are now used as context-sensitive flag, so they must be masked out. This tries to fix #160248. --- clang/lib/CodeGen/CodeGenPGO.cpp | 9 +++++++-- .../Profile/Inputs/c-counter-overflows.proftext | 2 +- clang/test/Profile/Inputs/c-general.profdata.v12 | Bin 0 -> 2616 bytes clang/test/Profile/Inputs/c-general.proftext | 12 ++++++------ .../Profile/Inputs/c-unprofiled-blocks.proftext | 4 ++-- clang/test/Profile/Inputs/cxx-rangefor.proftext | 2 +- .../Inputs/misexpect-switch-default.proftext | 2 +- .../Inputs/misexpect-switch-nonconst.proftext | 2 +- clang/test/Profile/c-collision.c | 4 ++-- clang/test/Profile/c-general.c | 1 + llvm/include/llvm/ProfileData/InstrProf.h | 7 +++++-- llvm/include/llvm/ProfileData/InstrProfData.inc | 2 +- llvm/lib/ProfileData/InstrProf.cpp | 5 +++-- llvm/lib/ProfileData/InstrProfWriter.cpp | 2 +- .../Instrumentation/PGOInstrumentation.cpp | 2 +- .../tools/llvm-profdata/profile-version.test | 2 +- 16 files changed, 34 insertions(+), 24 deletions(-) create mode 100644 clang/test/Profile/Inputs/c-general.profdata.v12 diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp index 8f095649f87ce..06d7380b4e37c 100644 --- a/clang/lib/CodeGen/CodeGenPGO.cpp +++ b/clang/lib/CodeGen/CodeGenPGO.cpp @@ -58,9 +58,10 @@ enum PGOHashVersion : unsigned { PGO_HASH_V1, PGO_HASH_V2, PGO_HASH_V3, + PGO_HASH_V4, // Keep this set to the latest hash version. - PGO_HASH_LATEST = PGO_HASH_V3 + PGO_HASH_LATEST = PGO_HASH_V4 }; namespace { @@ -152,7 +153,9 @@ static PGOHashVersion getPGOHashVersion(llvm::IndexedInstrProfReader *PGOReader, return PGO_HASH_V1; if (PGOReader->getVersion() <= 5) return PGO_HASH_V2; - return PGO_HASH_V3; + if (PGOReader->getVersion() <= 12) + return PGO_HASH_V3; + return PGO_HASH_V4; } /// A RecursiveASTVisitor that fills a map of statements to PGO counters. @@ -1099,6 +1102,8 @@ void CodeGenPGO::mapRegionCounters(const Decl *D) { assert(Walker.NextCounter > 0 && "no entry counter mapped for decl"); NumRegionCounters = Walker.NextCounter; FunctionHash = Walker.Hash.finalize(); + if (HashVersion >= PGO_HASH_V4) + FunctionHash &= llvm::NamedInstrProfRecord::FUNC_HASH_MASK; } bool CodeGenPGO::skipRegionMappingForDecl(const Decl *D) { diff --git a/clang/test/Profile/Inputs/c-counter-overflows.proftext b/clang/test/Profile/Inputs/c-counter-overflows.proftext index 4d0287c787051..8633060507014 100644 --- a/clang/test/Profile/Inputs/c-counter-overflows.proftext +++ b/clang/test/Profile/Inputs/c-counter-overflows.proftext @@ -1,5 +1,5 @@ main -7779561829442898616 +862032801801816760 8 1 68719476720 diff --git a/clang/test/Profile/Inputs/c-general.profdata.v12 b/clang/test/Profile/Inputs/c-general.profdata.v12 new file mode 100644 index 0000000000000000000000000000000000000000..57a72faaecc85f567936cec900704e0fb531946b GIT binary patch literal 2616 zcmb_eTSydP6#jQx(@ITI%v3}LQy(m`lnAezRANa4iHSC@v#UEXJG1SKq(qTzXa?OZ zql?f=1qRh)2oVJpQN1XUJ=8-{VV4&rdZ-@E_CMb){;SwS`|{2C{&V}!Idf)bRIg8O zS9)UE{J+#?bNT$`bLAqEmlB;o2(x;UErd=1dtx||kjD|{@E7RimLgvjw<KsF^6$>s zg1pS#G30S1je8XNtl{XOrk(UrhlhFGvY7Z(!qz+d!XnQ~xMdFMr4a`1#RZ=rXA?hl zI6nB4NOCS=QToc@la*w|X{_Kp>bQ;0-&W7hm)hs&D;MA`EbG%F<^FVYcQSe2NGR)? zQ!y1?bEuN;b@?2o?i-unhr9=jAuBS8kg3VDy#IF8jp@y&+^F;M$SB6HmnDrUWr;Ps za$)c2HEIGxO@Wv}^cr@Mf#AjL!`a$upW5=D7|IID(oN`c_|$I6)uot5d2?ZWUD8h) zmvFKu#d>-`kkyOGumgsZ*<bLyY|YVu2Vh1?#W<jtvfE`;xc&ZTflDk&h=9mIJ{XMg z!H>)sqX$Hjf&2wy42Vo21EYjIpa;Y~tn9~Nxvg$zOOiMgZMv@NUP;w;uOW>WH>{h? zyd@3=h5&Vj48)6v+k^jCeKFhJ=er7`uIBE=?Z!x9U#G`wqz~1$Y>?lNr4WgrKsXcS zg?Q+Rt$++Wv<5QlL==`cgN!W+d$h*FUibAU|Ne3%8m*}!6+`iORTpo~cxla0g2xsb z2t;*~F0c;n3BytLTt6|=fB9M?w&5Al_&WeDhZfp9#@P>Lr@yN<#+PS!b`c_n43UDJ zWFP|I9Qxq1Ngs%5flS8?sax5vS0^V+or7;M_4%aYaVQ!-8i)oIy)?auwQn7+H&@X? z5usez;nHR|uDVv<WS9<9k)`%dO&;IE&#j~ex9BF(p(HKr(C5j=-V5LCC|eb&ICZJr zp{l0ar+0R^2fj{SZ0noq!c|1Sh=<EZ#;M$qp|$o^A4Dc2q|&BzNPJCA%ruPlHYs;e zaKy+WO(1xpLthl|*vLTeKrA^Rcp&ZqL>$}=d0_5iL`5>th|dsTK{))+cyp0Bel(Bb YX5x<&$;U{p#P%2R`zY|+Q4m4z4;UZ1fdBvi literal 0 HcmV?d00001 diff --git a/clang/test/Profile/Inputs/c-general.proftext b/clang/test/Profile/Inputs/c-general.proftext index 08280ef39a89d..72e1be6e8846f 100644 --- a/clang/test/Profile/Inputs/c-general.proftext +++ b/clang/test/Profile/Inputs/c-general.proftext @@ -7,7 +7,7 @@ simple_loops 75 conditionals -4904767535850050386 +293081517422662482 13 1 100 @@ -24,7 +24,7 @@ conditionals 1 early_exits -2880354649761471549 +574511640547777597 9 1 0 @@ -37,7 +37,7 @@ early_exits 0 jumps -15051420506203462683 +63440946314451995 22 1 1 @@ -86,7 +86,7 @@ switches 0 big_switch -13144136522122330070 +461999971447013334 17 1 32 @@ -125,7 +125,7 @@ boolean_operators 33 boolop_loops -12402604614320574815 +873389568252105055 13 1 50 @@ -149,7 +149,7 @@ conditional_operator 1 do_fallthrough -8714614136504380050 +644163604256451218 4 1 10 diff --git a/clang/test/Profile/Inputs/c-unprofiled-blocks.proftext b/clang/test/Profile/Inputs/c-unprofiled-blocks.proftext index d880663fed32d..7af509715f8f7 100644 --- a/clang/test/Profile/Inputs/c-unprofiled-blocks.proftext +++ b/clang/test/Profile/Inputs/c-unprofiled-blocks.proftext @@ -1,5 +1,5 @@ never_called -6820425066224770721 +1055817543190535841 9 0 0 @@ -17,7 +17,7 @@ main 1 dead_code -5254464978620792806 +642778960193404902 10 1 0 diff --git a/clang/test/Profile/Inputs/cxx-rangefor.proftext b/clang/test/Profile/Inputs/cxx-rangefor.proftext index d41205bbde147..cfc88da8f9726 100644 --- a/clang/test/Profile/Inputs/cxx-rangefor.proftext +++ b/clang/test/Profile/Inputs/cxx-rangefor.proftext @@ -1,5 +1,5 @@ _Z9range_forv -8789831523895825398 +719380991647896566 5 1 4 diff --git a/clang/test/Profile/Inputs/misexpect-switch-default.proftext b/clang/test/Profile/Inputs/misexpect-switch-default.proftext index 533da91765234..112426e0c7b57 100644 --- a/clang/test/Profile/Inputs/misexpect-switch-default.proftext +++ b/clang/test/Profile/Inputs/misexpect-switch-default.proftext @@ -1,6 +1,6 @@ main # Func Hash: -8734802134600123338 +664351602352194506 # Num Counters: 9 # Counter Values: diff --git a/clang/test/Profile/Inputs/misexpect-switch-nonconst.proftext b/clang/test/Profile/Inputs/misexpect-switch-nonconst.proftext index 0da9379357ae7..99d067c57f16f 100644 --- a/clang/test/Profile/Inputs/misexpect-switch-nonconst.proftext +++ b/clang/test/Profile/Inputs/misexpect-switch-nonconst.proftext @@ -1,6 +1,6 @@ main # Func Hash: -3721743393642630379 +262978879822089451 # Num Counters: 10 # Counter Values: diff --git a/clang/test/Profile/c-collision.c b/clang/test/Profile/c-collision.c index 6c779c6facaa2..f35ba1bfb7627 100644 --- a/clang/test/Profile/c-collision.c +++ b/clang/test/Profile/c-collision.c @@ -2,8 +2,8 @@ // RUN: %clang_cc1 -UEXTRA -triple x86_64-unknown-linux-gnu -main-file-name c-collision.c %s -o - -emit-llvm -fprofile-instrument=clang | FileCheck %s --check-prefix=CHECK-NOEXTRA // RUN: %clang_cc1 -DEXTRA -triple x86_64-unknown-linux-gnu -main-file-name c-collision.c %s -o - -emit-llvm -fprofile-instrument=clang | FileCheck %s --check-prefix=CHECK-EXTRA -// CHECK-NOEXTRA: @__profd_foo = private global { {{.*}} } { i64 6699318081062747564, i64 7156072912471487002, -// CHECK-EXTRA: @__profd_foo = private global { {{.*}} } { i64 6699318081062747564, i64 -4383447408116050035, +// CHECK-NOEXTRA: @__profd_foo = private global { {{.*}} } { i64 6699318081062747564, i64 238543884830405146, +// CHECK-EXTRA: @__profd_foo = private global { {{.*}} } { i64 6699318081062747564, i64 228238610311337869, extern int bar; void foo(void) { diff --git a/clang/test/Profile/c-general.c b/clang/test/Profile/c-general.c index ee36a43dac081..6c865e608a037 100644 --- a/clang/test/Profile/c-general.c +++ b/clang/test/Profile/c-general.c @@ -4,6 +4,7 @@ // RUN: llvm-profdata merge %S/Inputs/c-general.proftext -o %t.profdata // RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-general.c %s -o - -emit-llvm -fprofile-instrument-use=clang -fprofile-instrument-use-path=%t.profdata | FileCheck -allow-deprecated-dag-overlap -check-prefix=PGOUSE %s +// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-general.c %s -o - -emit-llvm -fprofile-instrument-use=clang -fprofile-instrument-use-path=%S/Inputs/c-general.profdata.v12 | FileCheck -allow-deprecated-dag-overlap -check-prefix=PGOUSE %s // RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-general.c %s -o - -emit-llvm -fprofile-instrument-use=clang -fprofile-instrument-use-path=%S/Inputs/c-general.profdata.v5 | FileCheck -allow-deprecated-dag-overlap -check-prefix=PGOUSE %s // RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-general.c %s -o - -emit-llvm -fprofile-instrument-use=clang -fprofile-instrument-use-path=%S/Inputs/c-general.profdata.v3 | FileCheck -allow-deprecated-dag-overlap -check-prefix=PGOUSE %s // Also check compatibility with older profiles. diff --git a/llvm/include/llvm/ProfileData/InstrProf.h b/llvm/include/llvm/ProfileData/InstrProf.h index 85a9efe73855b..0532500e68db3 100644 --- a/llvm/include/llvm/ProfileData/InstrProf.h +++ b/llvm/include/llvm/ProfileData/InstrProf.h @@ -1059,7 +1059,8 @@ struct NamedInstrProfRecord : InstrProfRecord { uint64_t Hash; // We reserve this bit as the flag for context sensitive profile record. - static const int CS_FLAG_IN_FUNC_HASH = 60; + static constexpr unsigned CS_FLAG_IN_FUNC_HASH = 60; + static constexpr uint64_t FUNC_HASH_MASK = 0x0FFF'FFFF'FFFF'FFFF; NamedInstrProfRecord() = default; NamedInstrProfRecord(StringRef Name, uint64_t Hash, @@ -1174,7 +1175,9 @@ enum ProfVersion { Version11 = 11, // VTable profiling, decision record and bitmap are modified for mcdc. Version12 = 12, - // The current version is 12. + // In this version, the frontend PGO stable hash algorithm defaults to V4. + Version13 = 13, + // The current version is 13. CurrentVersion = INSTR_PROF_INDEX_VERSION }; const uint64_t Version = ProfVersion::CurrentVersion; diff --git a/llvm/include/llvm/ProfileData/InstrProfData.inc b/llvm/include/llvm/ProfileData/InstrProfData.inc index 0496f240dc823..46d6bb5bd8896 100644 --- a/llvm/include/llvm/ProfileData/InstrProfData.inc +++ b/llvm/include/llvm/ProfileData/InstrProfData.inc @@ -722,7 +722,7 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure, /* Raw profile format version (start from 1). */ #define INSTR_PROF_RAW_VERSION 10 /* Indexed profile format version (start from 1). */ -#define INSTR_PROF_INDEX_VERSION 12 +#define INSTR_PROF_INDEX_VERSION 13 /* Coverage mapping format version (start from 0). */ #define INSTR_PROF_COVMAP_VERSION 6 diff --git a/llvm/lib/ProfileData/InstrProf.cpp b/llvm/lib/ProfileData/InstrProf.cpp index 02087355ab318..54987872f2d8b 100644 --- a/llvm/lib/ProfileData/InstrProf.cpp +++ b/llvm/lib/ProfileData/InstrProf.cpp @@ -1690,7 +1690,7 @@ Expected<Header> Header::readFromBuffer(const unsigned char *Buffer) { IndexedInstrProf::ProfVersion::CurrentVersion) return make_error<InstrProfError>(instrprof_error::unsupported_version); - static_assert(IndexedInstrProf::ProfVersion::CurrentVersion == Version12, + static_assert(IndexedInstrProf::ProfVersion::CurrentVersion == Version13, "Please update the reader as needed when a new field is added " "or when indexed profile version gets bumped."); @@ -1723,10 +1723,11 @@ size_t Header::size() const { // of the header, and byte offset of existing fields shouldn't change when // indexed profile version gets incremented. static_assert( - IndexedInstrProf::ProfVersion::CurrentVersion == Version12, + IndexedInstrProf::ProfVersion::CurrentVersion == Version13, "Please update the size computation below if a new field has " "been added to the header; for a version bump without new " "fields, add a case statement to fall through to the latest version."); + case 13ull: case 12ull: return 72; case 11ull: diff --git a/llvm/lib/ProfileData/InstrProfWriter.cpp b/llvm/lib/ProfileData/InstrProfWriter.cpp index a3473514d4637..0f15ca8ff6df7 100644 --- a/llvm/lib/ProfileData/InstrProfWriter.cpp +++ b/llvm/lib/ProfileData/InstrProfWriter.cpp @@ -542,7 +542,7 @@ Error InstrProfWriter::writeImpl(ProfOStream &OS) { // The WritePrevVersion handling will either need to be removed or updated // if the version is advanced beyond 12. static_assert(IndexedInstrProf::ProfVersion::CurrentVersion == - IndexedInstrProf::ProfVersion::Version12); + IndexedInstrProf::ProfVersion::Version13); if (static_cast<bool>(ProfileKind & InstrProfKind::IRInstrumentation)) Header.Version |= VARIANT_MASK_IR_PROF; if (static_cast<bool>(ProfileKind & InstrProfKind::ContextSensitive)) diff --git a/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp b/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp index 120c4f65a7292..9981ec8220ff7 100644 --- a/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp +++ b/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp @@ -734,7 +734,7 @@ void FuncPGOInstrumentation<Edge, BBInfo>::computeCFGHash() { FunctionHash = (((uint64_t)JCH.getCRC()) << 28) + JC.getCRC(); // Reserve bit 60-63 for other information purpose. - FunctionHash &= 0x0FFFFFFFFFFFFFFF; + FunctionHash &= NamedInstrProfRecord::FUNC_HASH_MASK; if (IsCS) NamedInstrProfRecord::setCSFlagInHash(FunctionHash); LLVM_DEBUG(dbgs() << "Function Hash Computation for " << F.getName() << ":\n" diff --git a/llvm/test/tools/llvm-profdata/profile-version.test b/llvm/test/tools/llvm-profdata/profile-version.test index cb68a648d5e5a..e811699ac63ed 100644 --- a/llvm/test/tools/llvm-profdata/profile-version.test +++ b/llvm/test/tools/llvm-profdata/profile-version.test @@ -2,7 +2,7 @@ Test the profile version. RUN: llvm-profdata merge -o %t.profdata %p/Inputs/basic.proftext RUN: llvm-profdata show --profile-version %t.profdata | FileCheck %s -CHECK: Profile version: 12 +CHECK: Profile version: 13 RUN: llvm-profdata merge -o %t.prev.profdata %p/Inputs/basic.proftext --write-prev-version RUN: llvm-profdata show --profile-version %t.prev.profdata | FileCheck %s --check-prefix=PREV >From 395f1ccfe671a676e86a343aca24419aa464ca2d Mon Sep 17 00:00:00 2001 From: Senran Zhang <[email protected]> Date: Tue, 28 Oct 2025 19:15:41 +0800 Subject: [PATCH 2/4] Update clang test --- clang/test/Profile/Inputs/cxx-throws.proftext | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/Profile/Inputs/cxx-throws.proftext b/clang/test/Profile/Inputs/cxx-throws.proftext index 043dea08c728f..92b0eab396844 100644 --- a/clang/test/Profile/Inputs/cxx-throws.proftext +++ b/clang/test/Profile/Inputs/cxx-throws.proftext @@ -1,5 +1,5 @@ _Z6throwsv -18172607911962830854 +878785342860126214 9 1 100 >From 98d0cbc9dcbfded7b1f1b1f4a3e987825a631010 Mon Sep 17 00:00:00 2001 From: Senran Zhang <[email protected]> Date: Thu, 30 Oct 2025 09:56:08 +0800 Subject: [PATCH 3/4] Restruct comment string --- llvm/include/llvm/ProfileData/InstrProf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/include/llvm/ProfileData/InstrProf.h b/llvm/include/llvm/ProfileData/InstrProf.h index 0532500e68db3..9f52b6aba0f52 100644 --- a/llvm/include/llvm/ProfileData/InstrProf.h +++ b/llvm/include/llvm/ProfileData/InstrProf.h @@ -1059,8 +1059,8 @@ struct NamedInstrProfRecord : InstrProfRecord { uint64_t Hash; // We reserve this bit as the flag for context sensitive profile record. - static constexpr unsigned CS_FLAG_IN_FUNC_HASH = 60; static constexpr uint64_t FUNC_HASH_MASK = 0x0FFF'FFFF'FFFF'FFFF; + static constexpr unsigned CS_FLAG_IN_FUNC_HASH = 60; NamedInstrProfRecord() = default; NamedInstrProfRecord(StringRef Name, uint64_t Hash, >From 5b6288e608aabd4c9f61acd29c9ecd9dde6c9e7c Mon Sep 17 00:00:00 2001 From: Senran Zhang <[email protected]> Date: Thu, 30 Oct 2025 09:58:23 +0800 Subject: [PATCH 4/4] Update comment string --- llvm/include/llvm/ProfileData/InstrProf.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/llvm/include/llvm/ProfileData/InstrProf.h b/llvm/include/llvm/ProfileData/InstrProf.h index 9f52b6aba0f52..7886478158c3c 100644 --- a/llvm/include/llvm/ProfileData/InstrProf.h +++ b/llvm/include/llvm/ProfileData/InstrProf.h @@ -1058,8 +1058,9 @@ struct NamedInstrProfRecord : InstrProfRecord { StringRef Name; uint64_t Hash; - // We reserve this bit as the flag for context sensitive profile record. + // We reserve the highest 4 bits as flags. static constexpr uint64_t FUNC_HASH_MASK = 0x0FFF'FFFF'FFFF'FFFF; + // The 60th bit is for context sensitive profile record. static constexpr unsigned CS_FLAG_IN_FUNC_HASH = 60; NamedInstrProfRecord() = default; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
