summaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CodeGenPGO.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CodeGenPGO.cpp')
-rw-r--r--clang/lib/CodeGen/CodeGenPGO.cpp30
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);