[PATCH] D81682: [PGO] Extend the value profile buckets for mem op sizes.
Hiroshi Yamauchi via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 25 13:39:17 PDT 2020
yamauchi added a comment.
Here's the raw diff for the last update
diff --git a/compiler-rt/include/profile/InstrProfData.inc b/compiler-rt/include/profile/InstrProfData.inc
index f4cb2524ad7..8c6e6cffe95 100644
--- a/compiler-rt/include/profile/InstrProfData.inc
+++ b/compiler-rt/include/profile/InstrProfData.inc
@@ -830,6 +830,47 @@ typedef struct InstrProfValueData {
* metadata. For example, it's 2 for [2, 2] and 64 for [65, 127].
*/
+/*
+ * Clz and Popcount. This code was copied from
+ * compiler-rt/lib/fuzzer/{FuzzerBuiltins.h,FuzzerBuiltinsMsvc.h}.
+ */
+#if defined(_MSC_VER) && !defined(__clang__)
+
+#include <intrin.h>
+INSTR_PROF_VISIBILITY INSTR_PROF_INLINE
+uint32_t InstProfClzll(uint64_t X) {
+ unsigned long LeadZeroIdx = 0;
+#if !defined(_M_ARM) && !defined(_M_X64)
+ // Scan the high 32 bits.
+ if (_BitScanReverse(&LeadZeroIdx, static_cast<unsigned long>(X >> 32)))
+ return static_cast<int>(63 - (LeadZeroIdx + 32)); // Create a bit offset
+ // from the MSB.
+ // Scan the low 32 bits.
+ if (_BitScanReverse(&LeadZeroIdx, static_cast<unsigned long>(X)))
+ return static_cast<int>(63 - LeadZeroIdx);
+#else
+ if (_BitScanReverse64(&LeadZeroIdx, X)) return 63 - LeadZeroIdx;
+#endif
+ return 64;
+}
+INSTR_PROF_VISIBILITY INSTR_PROF_INLINE
+int InstProfPopcountll(unsigned long long X) {
+#if !defined(_M_ARM) && !defined(_M_X64)
+ return __popcnt(X) + __popcnt(X >> 32);
+#else
+ return __popcnt64(X);
+#endif
+}
+
+#else
+
+INSTR_PROF_VISIBILITY INSTR_PROF_INLINE
+uint32_t InstProfClzll(unsigned long long X) { return __builtin_clzll(X); }
+INSTR_PROF_VISIBILITY INSTR_PROF_INLINE
+int InstProfPopcountll(unsigned long long X) { return __builtin_popcountll(X); }
+
+#endif /* defined(_MSC_VER) && !defined(__clang__) */
+
/* Map an (observed) memop size value to the representative value of its range.
* For example, 5 -> 5, 22 -> 17, 99 -> 65, 256 -> 256, 1001 -> 513. */
INSTR_PROF_VISIBILITY INSTR_PROF_INLINE uint64_t
@@ -840,12 +881,12 @@ InstrProfGetRangeRepValue(uint64_t Value) {
else if (Value >= 513)
// The last range is mapped to its lowest value.
return 513;
- else if (__builtin_popcountll(Value) == 1)
+ else if (InstProfPopcountll(Value) == 1)
// If it's a power of two, use it as is.
return Value;
else
// Otherwise, take to the previous power of two + 1.
- return (1 << (64 - __builtin_clzll(Value) - 1)) + 1;
+ return (1 << (64 - InstProfClzll(Value) - 1)) + 1;
}
/* Return true if the range that an (observed) memop size value belongs to has
@@ -856,7 +897,7 @@ InstrProfIsSingleValRange(uint64_t Value) {
if (Value <= 8)
// The first ranges are individually tracked.
return 1;
- else if (__builtin_popcountll(Value) == 1)
+ else if (InstProfPopcountll(Value) == 1)
// If it's a power of two, there's only one value.
return 1;
else
diff --git a/llvm/include/llvm/ProfileData/InstrProfData.inc b/llvm/include/llvm/ProfileData/InstrProfData.inc
index f4cb2524ad7..8c6e6cffe95 100644
--- a/llvm/include/llvm/ProfileData/InstrProfData.inc
+++ b/llvm/include/llvm/ProfileData/InstrProfData.inc
@@ -830,6 +830,47 @@ typedef struct InstrProfValueData {
* metadata. For example, it's 2 for [2, 2] and 64 for [65, 127].
*/
+/*
+ * Clz and Popcount. This code was copied from
+ * compiler-rt/lib/fuzzer/{FuzzerBuiltins.h,FuzzerBuiltinsMsvc.h}.
+ */
+#if defined(_MSC_VER) && !defined(__clang__)
+
+#include <intrin.h>
+INSTR_PROF_VISIBILITY INSTR_PROF_INLINE
+uint32_t InstProfClzll(uint64_t X) {
+ unsigned long LeadZeroIdx = 0;
+#if !defined(_M_ARM) && !defined(_M_X64)
+ // Scan the high 32 bits.
+ if (_BitScanReverse(&LeadZeroIdx, static_cast<unsigned long>(X >> 32)))
+ return static_cast<int>(63 - (LeadZeroIdx + 32)); // Create a bit offset
+ // from the MSB.
+ // Scan the low 32 bits.
+ if (_BitScanReverse(&LeadZeroIdx, static_cast<unsigned long>(X)))
+ return static_cast<int>(63 - LeadZeroIdx);
+#else
+ if (_BitScanReverse64(&LeadZeroIdx, X)) return 63 - LeadZeroIdx;
+#endif
+ return 64;
+}
+INSTR_PROF_VISIBILITY INSTR_PROF_INLINE
+int InstProfPopcountll(unsigned long long X) {
+#if !defined(_M_ARM) && !defined(_M_X64)
+ return __popcnt(X) + __popcnt(X >> 32);
+#else
+ return __popcnt64(X);
+#endif
+}
+
+#else
+
+INSTR_PROF_VISIBILITY INSTR_PROF_INLINE
+uint32_t InstProfClzll(unsigned long long X) { return __builtin_clzll(X); }
+INSTR_PROF_VISIBILITY INSTR_PROF_INLINE
+int InstProfPopcountll(unsigned long long X) { return __builtin_popcountll(X); }
+
+#endif /* defined(_MSC_VER) && !defined(__clang__) */
+
/* Map an (observed) memop size value to the representative value of its range.
* For example, 5 -> 5, 22 -> 17, 99 -> 65, 256 -> 256, 1001 -> 513. */
INSTR_PROF_VISIBILITY INSTR_PROF_INLINE uint64_t
@@ -840,12 +881,12 @@ InstrProfGetRangeRepValue(uint64_t Value) {
else if (Value >= 513)
// The last range is mapped to its lowest value.
return 513;
- else if (__builtin_popcountll(Value) == 1)
+ else if (InstProfPopcountll(Value) == 1)
// If it's a power of two, use it as is.
return Value;
else
// Otherwise, take to the previous power of two + 1.
- return (1 << (64 - __builtin_clzll(Value) - 1)) + 1;
+ return (1 << (64 - InstProfClzll(Value) - 1)) + 1;
}
/* Return true if the range that an (observed) memop size value belongs to has
@@ -856,7 +897,7 @@ InstrProfIsSingleValRange(uint64_t Value) {
if (Value <= 8)
// The first ranges are individually tracked.
return 1;
- else if (__builtin_popcountll(Value) == 1)
+ else if (InstProfPopcountll(Value) == 1)
// If it's a power of two, there's only one value.
return 1;
else
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D81682/new/
https://reviews.llvm.org/D81682
More information about the llvm-commits
mailing list