[llvm] [HWASAN] Implement selective instrumentation based on profiling information (PR #83503)
Kirill Stoimenov via llvm-commits
llvm-commits at lists.llvm.org
Thu Feb 29 15:36:38 PST 2024
https://github.com/kstoimenov created https://github.com/llvm/llvm-project/pull/83503
None
>From 6fff46376325201823391dc9702d8aab1fd8b1c7 Mon Sep 17 00:00:00 2001
From: Kirill Stoimenov <kstoimenov at google.com>
Date: Fri, 23 Feb 2024 17:33:02 +0000
Subject: [PATCH 1/3] [HWASAN] Implement selective instumentation based on
profiling information.
---
.../Instrumentation/HWAddressSanitizer.cpp | 65 ++++++++++++++++++-
1 file changed, 63 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
index 33add6d4cd767b..ba79c221ea5490 100644
--- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -15,11 +15,14 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/DomTreeUpdater.h"
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/PostDominators.h"
+#include "llvm/Analysis/BlockFrequencyInfo.h"
+#include "llvm/Analysis/ProfileSummaryInfo.h"
#include "llvm/Analysis/StackSafetyAnalysis.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/ValueTracking.h"
@@ -177,6 +180,25 @@ static cl::opt<bool> ClWithTls(
"platforms that support this"),
cl::Hidden, cl::init(true));
+static cl::opt<bool>
+ CSkipHotCode("hwasan-skip-hot-code",
+ cl::desc("Do not instument hot functions based on FDO."),
+ cl::Hidden, cl::init(false));
+
+static cl::opt<int> HotPercentileCutoff("opt-hwasan-percentile-cutoff-hot",
+ cl::init(0));
+static cl::opt<int> ColdPercentileCutoff("opt-hwasan-percentile-cutoff-cold",
+ cl::init(0));
+
+STATISTIC(NumTotalFuncs, "Number of funcs seen by HWASAN");
+STATISTIC(NumHwasanCtors, "Number of HWASAN ctors");
+STATISTIC(NumNoSanitizeFuncs, "Number of no-sanitize HWASAN funcs");
+STATISTIC(NumConsideredFuncs, "Number of funcs considered for HWASAN");
+STATISTIC(NumInstrumentedFuncs, "Number of HWASAN instrumented funcs");
+STATISTIC(NumNoProfileSummaryFuncs, "Number of HWASAN funcs without PS");
+STATISTIC(NumSkippedHotFuncs, "Number of skipped hot HWASAN funcs");
+STATISTIC(NumSkippedNotColdFuncs, "Number of skipped not cold HWASAN funcs");
+
// Mode for selecting how to insert frame record info into the stack ring
// buffer.
enum RecordStackHistoryMode {
@@ -1501,11 +1523,50 @@ bool HWAddressSanitizer::instrumentStack(memtag::StackInfo &SInfo,
void HWAddressSanitizer::sanitizeFunction(Function &F,
FunctionAnalysisManager &FAM) {
- if (&F == HwasanCtorFunction)
+ NumTotalFuncs++;
+ if (&F == HwasanCtorFunction) {
+ NumHwasanCtors++;
return;
+ }
- if (!F.hasFnAttribute(Attribute::SanitizeHWAddress))
+ if (!F.hasFnAttribute(Attribute::SanitizeHWAddress)) {
+ NumNoSanitizeFuncs++;
return;
+ }
+
+ NumConsideredFuncs++;
+ if (CSkipHotCode) {
+ auto &MAMProxy = FAM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
+ ProfileSummaryInfo *PSI =
+ MAMProxy.getCachedResult<ProfileSummaryAnalysis>(*F.getParent());
+ if (PSI != nullptr && PSI->hasProfileSummary()) {
+ auto &BFI = FAM.getResult<BlockFrequencyAnalysis>(F);
+
+ const bool is_hot =
+ (HotPercentileCutoff.getNumOccurrences() && HotPercentileCutoff >= 0)
+ ? PSI->isFunctionHotInCallGraphNthPercentile(HotPercentileCutoff,
+ &F, BFI)
+ : PSI->isFunctionEntryHot(&F);
+
+ const auto is_cold = (ColdPercentileCutoff.getNumOccurrences() &&
+ ColdPercentileCutoff >= 0)
+ ? PSI->isFunctionColdInCallGraphNthPercentile(
+ ColdPercentileCutoff, &F, BFI)
+ : PSI->isFunctionEntryCold(&F);
+
+ if (is_hot) {
+ ++NumSkippedHotFuncs;
+ return;
+ }
+ if (!is_cold) {
+ ++NumSkippedNotColdFuncs;
+ return;
+ }
+ } else {
+ ++NumNoProfileSummaryFuncs;
+ }
+ }
+ NumInstrumentedFuncs++;
LLVM_DEBUG(dbgs() << "Function: " << F.getName() << "\n");
>From fc36ab787a98c38f3c19d8b8bd3318d48bb777bb Mon Sep 17 00:00:00 2001
From: Kirill Stoimenov <kstoimenov at google.com>
Date: Thu, 29 Feb 2024 21:33:40 +0000
Subject: [PATCH 2/3] Removed cold code.
---
.../Instrumentation/HWAddressSanitizer.cpp | 14 --------------
1 file changed, 14 deletions(-)
diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
index ba79c221ea5490..99b92731a3b9ac 100644
--- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -187,8 +187,6 @@ static cl::opt<bool>
static cl::opt<int> HotPercentileCutoff("opt-hwasan-percentile-cutoff-hot",
cl::init(0));
-static cl::opt<int> ColdPercentileCutoff("opt-hwasan-percentile-cutoff-cold",
- cl::init(0));
STATISTIC(NumTotalFuncs, "Number of funcs seen by HWASAN");
STATISTIC(NumHwasanCtors, "Number of HWASAN ctors");
@@ -197,7 +195,6 @@ STATISTIC(NumConsideredFuncs, "Number of funcs considered for HWASAN");
STATISTIC(NumInstrumentedFuncs, "Number of HWASAN instrumented funcs");
STATISTIC(NumNoProfileSummaryFuncs, "Number of HWASAN funcs without PS");
STATISTIC(NumSkippedHotFuncs, "Number of skipped hot HWASAN funcs");
-STATISTIC(NumSkippedNotColdFuncs, "Number of skipped not cold HWASAN funcs");
// Mode for selecting how to insert frame record info into the stack ring
// buffer.
@@ -1541,27 +1538,16 @@ void HWAddressSanitizer::sanitizeFunction(Function &F,
MAMProxy.getCachedResult<ProfileSummaryAnalysis>(*F.getParent());
if (PSI != nullptr && PSI->hasProfileSummary()) {
auto &BFI = FAM.getResult<BlockFrequencyAnalysis>(F);
-
const bool is_hot =
(HotPercentileCutoff.getNumOccurrences() && HotPercentileCutoff >= 0)
? PSI->isFunctionHotInCallGraphNthPercentile(HotPercentileCutoff,
&F, BFI)
: PSI->isFunctionEntryHot(&F);
- const auto is_cold = (ColdPercentileCutoff.getNumOccurrences() &&
- ColdPercentileCutoff >= 0)
- ? PSI->isFunctionColdInCallGraphNthPercentile(
- ColdPercentileCutoff, &F, BFI)
- : PSI->isFunctionEntryCold(&F);
-
if (is_hot) {
++NumSkippedHotFuncs;
return;
}
- if (!is_cold) {
- ++NumSkippedNotColdFuncs;
- return;
- }
} else {
++NumNoProfileSummaryFuncs;
}
>From 269c6c879fba684e5f0ced9b7b2f4b6cab21e3ba Mon Sep 17 00:00:00 2001
From: Kirill Stoimenov <kstoimenov at google.com>
Date: Thu, 29 Feb 2024 23:34:56 +0000
Subject: [PATCH 3/3] Added tests.
---
llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
index 99b92731a3b9ac..bf59f10723c2db 100644
--- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -185,7 +185,7 @@ static cl::opt<bool>
cl::desc("Do not instument hot functions based on FDO."),
cl::Hidden, cl::init(false));
-static cl::opt<int> HotPercentileCutoff("opt-hwasan-percentile-cutoff-hot",
+static cl::opt<int> HotPercentileCutoff("hwasan-percentile-cutoff-hot",
cl::init(0));
STATISTIC(NumTotalFuncs, "Number of funcs seen by HWASAN");
More information about the llvm-commits
mailing list