-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[StaticDataLayout] Factor out a helper function for section prefix eligibility and use it in both optimizer and codegen #162348
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: users/mingmingl-llvm/module
Are you sure you want to change the base?
[StaticDataLayout] Factor out a helper function for section prefix eligibility and use it in both optimizer and codegen #162348
Conversation
…tatus of a global variable for section prefix annotation
@llvm/pr-subscribers-pgo @llvm/pr-subscribers-llvm-transforms Author: Mingming Liu (mingmingl-llvm) ChangesThis change introduces new helper functions to check if a global variable is eligible for section prefix annotation. This shared logic will be used by both MemProfUse and StaticDataSplitter to avoid annotating ineligible variables. Full diff: https://github.com/llvm/llvm-project/pull/162348.diff 4 Files Affected:
diff --git a/llvm/include/llvm/Analysis/StaticDataProfileInfo.h b/llvm/include/llvm/Analysis/StaticDataProfileInfo.h
index fa21eba1377df..f06e7ceaa74ce 100644
--- a/llvm/include/llvm/Analysis/StaticDataProfileInfo.h
+++ b/llvm/include/llvm/Analysis/StaticDataProfileInfo.h
@@ -10,6 +10,24 @@
namespace llvm {
+namespace memprof {
+// Represents the eligibility status of a global variable for section prefix
+// annotation. Other than AnnotationOk, each enum value indicates a specific
+// reason for ineligibility.
+enum class AnnotationKind : uint8_t {
+ AnnotationOK,
+ DeclForLinker,
+ ExplicitSection,
+ ReservedName,
+};
+/// Returns the annotation kind of the global variable \p GV.
+AnnotationKind getAnnotationKind(const GlobalVariable &GV);
+
+/// Returns true if the annotation kind of the global variable \p GV is
+/// AnnotationOK.
+bool IsAnnotationOK(const GlobalVariable &GV);
+} // namespace memprof
+
/// A class that holds the constants that represent static data and their
/// profile information and provides methods to operate on them.
class StaticDataProfileInfo {
diff --git a/llvm/lib/Analysis/StaticDataProfileInfo.cpp b/llvm/lib/Analysis/StaticDataProfileInfo.cpp
index b036b2dde770e..ff4582ca7eeb1 100644
--- a/llvm/lib/Analysis/StaticDataProfileInfo.cpp
+++ b/llvm/lib/Analysis/StaticDataProfileInfo.cpp
@@ -6,6 +6,43 @@
#include "llvm/ProfileData/InstrProf.h"
using namespace llvm;
+
+namespace llvm {
+namespace memprof {
+// Returns true iff the global variable has custom section either by
+// __attribute__((section("name")))
+// (https://clang.llvm.org/docs/AttributeReference.html#section-declspec-allocate)
+// or #pragma clang section directives
+// (https://clang.llvm.org/docs/LanguageExtensions.html#specifying-section-names-for-global-objects-pragma-clang-section).
+static bool hasExplicitSectionName(const GlobalVariable &GVar) {
+ if (GVar.hasSection())
+ return true;
+
+ auto Attrs = GVar.getAttributes();
+ if (Attrs.hasAttribute("bss-section") || Attrs.hasAttribute("data-section") ||
+ Attrs.hasAttribute("relro-section") ||
+ Attrs.hasAttribute("rodata-section"))
+ return true;
+ return false;
+}
+
+AnnotationKind getAnnotationKind(const GlobalVariable &GV) {
+ if (GV.isDeclarationForLinker())
+ return AnnotationKind::DeclForLinker;
+ StringRef Name = GV.getName();
+ if (Name.starts_with("llvm."))
+ return AnnotationKind::ReservedName;
+ if (hasExplicitSectionName(GV))
+ return AnnotationKind::ExplicitSection;
+ return AnnotationKind::AnnotationOK;
+}
+
+bool IsAnnotationOK(const GlobalVariable &GV) {
+ return getAnnotationKind(GV) == AnnotationKind::AnnotationOK;
+}
+} // namespace memprof
+} // namespace llvm
+
void StaticDataProfileInfo::addConstantProfileCount(
const Constant *C, std::optional<uint64_t> Count) {
if (!Count) {
diff --git a/llvm/lib/CodeGen/StaticDataAnnotator.cpp b/llvm/lib/CodeGen/StaticDataAnnotator.cpp
index 53a9ab4dbda02..9b737751c4a98 100644
--- a/llvm/lib/CodeGen/StaticDataAnnotator.cpp
+++ b/llvm/lib/CodeGen/StaticDataAnnotator.cpp
@@ -75,7 +75,7 @@ bool StaticDataAnnotator::runOnModule(Module &M) {
bool Changed = false;
for (auto &GV : M.globals()) {
- if (GV.isDeclarationForLinker())
+ if (!llvm::memprof::IsAnnotationOK(GV))
continue;
// The implementation below assumes prior passes don't set section prefixes,
diff --git a/llvm/lib/Transforms/Instrumentation/MemProfUse.cpp b/llvm/lib/Transforms/Instrumentation/MemProfUse.cpp
index d86fcf268ce4f..ca2af1a9534d3 100644
--- a/llvm/lib/Transforms/Instrumentation/MemProfUse.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemProfUse.cpp
@@ -17,6 +17,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/MemoryProfileInfo.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
+#include "llvm/Analysis/StaticDataProfileInfo.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/Function.h"
@@ -775,23 +776,6 @@ PreservedAnalyses MemProfUsePass::run(Module &M, ModuleAnalysisManager &AM) {
return PreservedAnalyses::none();
}
-// Returns true iff the global variable has custom section either by
-// __attribute__((section("name")))
-// (https://clang.llvm.org/docs/AttributeReference.html#section-declspec-allocate)
-// or #pragma clang section directives
-// (https://clang.llvm.org/docs/LanguageExtensions.html#specifying-section-names-for-global-objects-pragma-clang-section).
-static bool hasExplicitSectionName(const GlobalVariable &GVar) {
- if (GVar.hasSection())
- return true;
-
- auto Attrs = GVar.getAttributes();
- if (Attrs.hasAttribute("bss-section") || Attrs.hasAttribute("data-section") ||
- Attrs.hasAttribute("relro-section") ||
- Attrs.hasAttribute("rodata-section"))
- return true;
- return false;
-}
-
bool MemProfUsePass::annotateGlobalVariables(
Module &M, const memprof::DataAccessProfData *DataAccessProf) {
if (!AnnotateStaticDataSectionPrefix || M.globals().empty())
@@ -817,13 +801,16 @@ bool MemProfUsePass::annotateGlobalVariables(
for (GlobalVariable &GVar : M.globals()) {
assert(!GVar.getSectionPrefix().has_value() &&
"GVar shouldn't have section prefix yet");
- if (GVar.isDeclarationForLinker())
- continue;
-
- if (hasExplicitSectionName(GVar)) {
+ auto Kind = llvm::memprof::getAnnotationKind(GVar);
+ switch (Kind) {
+ case llvm::memprof::AnnotationKind::AnnotationOK:
+ break;
+ case llvm::memprof::AnnotationKind::ExplicitSection:
++NumOfMemProfExplicitSectionGlobalVars;
LLVM_DEBUG(dbgs() << "Global variable " << GVar.getName()
<< " has explicit section name. Skip annotating.\n");
+ [[fallthrough]];
+ default:
continue;
}
@@ -833,7 +820,6 @@ bool MemProfUsePass::annotateGlobalVariables(
// TODO: Track string content hash in the profiles and compute it inside the
// compiler to categeorize the hotness string literals.
if (Name.starts_with(".str")) {
-
LLVM_DEBUG(dbgs() << "Skip annotating string literal " << Name << "\n");
continue;
}
|
bool Changed = false; | ||
for (auto &GV : M.globals()) { | ||
if (GV.isDeclarationForLinker()) | ||
if (!llvm::memprof::IsAnnotationOK(GV)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This helper function includes more checks than just isDeclarationForLinker - so is this change really NFC?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah I agree.
I think this PR is more of 'NFCI' (non functional change intended) or no user-visible change intended. I removed the 'NFC' tag so (unfamiliar) readers won't get (unintentionally) fooled..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But are the effects of this change and the other one I mentioned earlier not observable by tests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But are the effects of this change and the other one I mentioned earlier not observable by tests?
Yeah, the test coverage is limited to [1] before. Improved the test coverage now, PTAL, thanks!
[1]
llvm-project/llvm/test/Transforms/PGOProfile/data-access-profile.ll
Lines 28 to 29 in 139a6bf
; LOG: Global variable var3 has explicit section name. Skip annotating. | |
; LOG: Global variable var4 has explicit section name. Skip annotating. |
if (GV.isDeclarationForLinker()) | ||
return AnnotationKind::DeclForLinker; | ||
StringRef Name = GV.getName(); | ||
if (Name.starts_with("llvm.")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check is new afaict - so is this NFC?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah sorry, you are correct.
This is from another similar call site [1] and this PR means to cover that one. Updated the PR.
[1]
llvm-project/llvm/lib/CodeGen/StaticDataSplitter.cpp
Lines 133 to 137 in 30b9ef8
// Skip 'llvm.'-prefixed global variables conservatively because they are | |
// often handled specially, and skip those not in static data | |
// sections. | |
if (!GV || GV->getName().starts_with("llvm.") || | |
!inStaticDataSection(*GV, TM)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for reviews! PTAL.
if (GV.isDeclarationForLinker()) | ||
return AnnotationKind::DeclForLinker; | ||
StringRef Name = GV.getName(); | ||
if (Name.starts_with("llvm.")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah sorry, you are correct.
This is from another similar call site [1] and this PR means to cover that one. Updated the PR.
[1]
llvm-project/llvm/lib/CodeGen/StaticDataSplitter.cpp
Lines 133 to 137 in 30b9ef8
// Skip 'llvm.'-prefixed global variables conservatively because they are | |
// often handled specially, and skip those not in static data | |
// sections. | |
if (!GV || GV->getName().starts_with("llvm.") || | |
!inStaticDataSection(*GV, TM)) |
bool Changed = false; | ||
for (auto &GV : M.globals()) { | ||
if (GV.isDeclarationForLinker()) | ||
if (!llvm::memprof::IsAnnotationOK(GV)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah I agree.
I think this PR is more of 'NFCI' (non functional change intended) or no user-visible change intended. I removed the 'NFC' tag so (unfamiliar) readers won't get (unintentionally) fooled..
Hi folks, this PR is ready for review (again, after |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm with a few small fixes below
|
||
;; A minimal test case. llc will crash if global variables already has a section | ||
;; prefix. Subsequent PRs will expand on this test case to test the hotness | ||
;; reconcillation implementation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/reconcillation/reconciliation/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed in #162938 and will rebase the PR that depends on the test.
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" | ||
target triple = "x86_64-unknown-linux-gnu" | ||
|
||
;; A minimal test case. llc will crash if global variables already has a section |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the behavior of this test affected by this PR? If not, commit it separately as a standalone change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done in #162938 to pre-commit the test case.
LLVM_DEBUG(dbgs() << "Global variable " << GVar.getName() | ||
<< " has explicit section name. Skip annotating.\n"); | ||
auto Kind = llvm::memprof::getAnnotationKind(GVar); | ||
switch (Kind) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the switch now only handles 2 cases, this would be clearer written as an if condition like:
if (Kind != llvm::memprof::AnnotationKind::AnnotationOK) {
HandleUnsupportedAnnotationKinds(GVar, Kind);
continue;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll resolve this one shortly after.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done in 34b47c9
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for reviews!
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" | ||
target triple = "x86_64-unknown-linux-gnu" | ||
|
||
;; A minimal test case. llc will crash if global variables already has a section |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done in #162938 to pre-commit the test case.
|
||
;; A minimal test case. llc will crash if global variables already has a section | ||
;; prefix. Subsequent PRs will expand on this test case to test the hotness | ||
;; reconcillation implementation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed in #162938 and will rebase the PR that depends on the test.
This change introduces new helper functions to check if a global variable is eligible for section prefix annotation.
This shared logic is used by both MemProfUse and StaticDataSplitter to avoid annotating ineligible variables.
This is the 2nd patch as a split of #155337