diff options
Diffstat (limited to 'clang/lib/CodeGen/CodeGenPGO.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenPGO.cpp | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp index bad796bf92dc..e810f608ab78 100644 --- a/clang/lib/CodeGen/CodeGenPGO.cpp +++ b/clang/lib/CodeGen/CodeGenPGO.cpp @@ -52,9 +52,10 @@ void CodeGenPGO::setFuncName(llvm::Function *Fn) { enum PGOHashVersion : unsigned { PGO_HASH_V1, PGO_HASH_V2, + PGO_HASH_V3, // Keep this set to the latest hash version. - PGO_HASH_LATEST = PGO_HASH_V2 + PGO_HASH_LATEST = PGO_HASH_V3 }; namespace { @@ -122,7 +123,7 @@ public: BinaryOperatorGE, BinaryOperatorEQ, BinaryOperatorNE, - // The preceding values are available with PGO_HASH_V2. + // The preceding values are available since PGO_HASH_V2. // Keep this last. It's for the static assert that follows. LastHashType @@ -144,7 +145,9 @@ static PGOHashVersion getPGOHashVersion(llvm::IndexedInstrProfReader *PGOReader, CodeGenModule &CGM) { if (PGOReader->getVersion() <= 4) return PGO_HASH_V1; - return PGO_HASH_V2; + if (PGOReader->getVersion() <= 5) + return PGO_HASH_V2; + return PGO_HASH_V3; } /// A RecursiveASTVisitor that fills a map of statements to PGO counters. @@ -288,7 +291,7 @@ struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> { return PGOHash::BinaryOperatorLAnd; if (BO->getOpcode() == BO_LOr) return PGOHash::BinaryOperatorLOr; - if (HashVersion == PGO_HASH_V2) { + if (HashVersion >= PGO_HASH_V2) { switch (BO->getOpcode()) { default: break; @@ -310,7 +313,7 @@ struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> { } } - if (HashVersion == PGO_HASH_V2) { + if (HashVersion >= PGO_HASH_V2) { switch (S->getStmtClass()) { default: break; @@ -747,13 +750,21 @@ uint64_t PGOHash::finalize() { return Working; // Check for remaining work in Working. - if (Working) - MD5.update(Working); + if (Working) { + // Keep the buggy behavior from v1 and v2 for backward-compatibility. This + // is buggy because it converts a uint64_t into an array of uint8_t. + if (HashVersion < PGO_HASH_V3) { + MD5.update({(uint8_t)Working}); + } else { + using namespace llvm::support; + uint64_t Swapped = endian::byte_swap<uint64_t, little>(Working); + MD5.update(llvm::makeArrayRef((uint8_t *)&Swapped, sizeof(Swapped))); + } + } // Finalize the MD5 and return the hash. llvm::MD5::MD5Result Result; MD5.final(Result); - using namespace llvm::support; return Result.low(); } @@ -1051,8 +1062,7 @@ llvm::MDNode *CodeGenFunction::createProfileWeightsForLoop(const Stmt *Cond, if (!PGO.haveRegionCounts()) return nullptr; Optional<uint64_t> CondCount = PGO.getStmtCount(Cond); - assert(CondCount.hasValue() && "missing expected loop condition count"); - if (*CondCount == 0) + if (!CondCount || *CondCount == 0) return nullptr; return createProfileWeights(LoopCount, std::max(*CondCount, LoopCount) - LoopCount); |