Skip to content

Conversation

mingmingl-llvm
Copy link
Contributor

@mingmingl-llvm mingmingl-llvm commented Oct 7, 2025

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

@mingmingl-llvm mingmingl-llvm requested review from snehasish and teresajohnson and removed request for snehasish October 7, 2025 19:21
@mingmingl-llvm mingmingl-llvm marked this pull request as ready for review October 7, 2025 19:21
@llvmbot llvmbot added llvm:codegen llvm:analysis Includes value tracking, cost tables and constant folding llvm:transforms labels Oct 7, 2025
@llvmbot
Copy link
Member

llvmbot commented Oct 7, 2025

@llvm/pr-subscribers-pgo
@llvm/pr-subscribers-backend-x86
@llvm/pr-subscribers-llvm-analysis

@llvm/pr-subscribers-llvm-transforms

Author: Mingming Liu (mingmingl-llvm)

Changes

This 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:

  • (modified) llvm/include/llvm/Analysis/StaticDataProfileInfo.h (+18)
  • (modified) llvm/lib/Analysis/StaticDataProfileInfo.cpp (+37)
  • (modified) llvm/lib/CodeGen/StaticDataAnnotator.cpp (+1-1)
  • (modified) llvm/lib/Transforms/Instrumentation/MemProfUse.cpp (+8-22)
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))
Copy link
Contributor

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?

Copy link
Contributor Author

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..

Copy link
Contributor

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?

Copy link
Contributor Author

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]

; 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."))
Copy link
Contributor

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?

Copy link
Contributor Author

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]

// 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))

@mingmingl-llvm mingmingl-llvm changed the title [nfc][StaticDataLayout] Factor out helper functions for section prefix eligibility [StaticDataLayout] Factor out a helper function for section prefix eligibility and use it in both optimizer and codegen Oct 7, 2025
Copy link
Contributor Author

@mingmingl-llvm mingmingl-llvm left a 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."))
Copy link
Contributor Author

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]

// 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))
Copy link
Contributor Author

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..

@llvmbot llvmbot added backend:X86 PGO Profile Guided Optimizations labels Oct 8, 2025
@mingmingl-llvm
Copy link
Contributor Author

Hi folks, this PR is ready for review (again, after llvm/test/CodeGen/X86/global-variable-partition-with-dap.ll is added for subsequent PRs to expand on), thanks!

Copy link
Contributor

@teresajohnson teresajohnson left a 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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/reconcillation/reconciliation/

Copy link
Contributor Author

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
Copy link
Contributor

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.

Copy link
Contributor Author

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) {
Copy link
Contributor

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;
}

Copy link
Contributor Author

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in 34b47c9

mingmingl-llvm added a commit that referenced this pull request Oct 10, 2025
Copy link
Contributor Author

@mingmingl-llvm mingmingl-llvm left a 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
Copy link
Contributor Author

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.
Copy link
Contributor Author

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.

mingmingl-llvm added a commit that referenced this pull request Oct 10, 2025
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Oct 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend:X86 llvm:analysis Includes value tracking, cost tables and constant folding llvm:codegen llvm:transforms PGO Profile Guided Optimizations

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants