[clang] bb6ab91 - Add option -fkeep-persistent-storage-variables to emit all variables that have a persistent storage duration

Hubert Tong via cfe-commits cfe-commits at lists.llvm.org
Sat Jul 15 13:13:54 PDT 2023


Author: Zheng Qian
Date: 2023-07-15T16:13:48-04:00
New Revision: bb6ab91b1dcd2fadfddffcd020439978af184862

URL: https://github.com/llvm/llvm-project/commit/bb6ab91b1dcd2fadfddffcd020439978af184862
DIFF: https://github.com/llvm/llvm-project/commit/bb6ab91b1dcd2fadfddffcd020439978af184862.diff

LOG: Add option -fkeep-persistent-storage-variables to emit all variables that have a persistent storage duration

This patch adds a new option -fkeep-persistent-storage-variables to emit
all variables that have a persistent storage duration, including global,
static and thread-local variables. This could be useful in cases where
the presence of all these variables as symbols in the object file are
required, so that they can be directly addressed.

Reviewed By: hubert.reinterpretcast

Differential Revision: https://reviews.llvm.org/D150221

Added: 
    clang/test/CodeGen/keep-persistent-storage-variables.cpp
    clang/test/Driver/fkeep-persistent-storage-variables.c

Modified: 
    clang/include/clang/Basic/CodeGenOptions.def
    clang/include/clang/Driver/Options.td
    clang/lib/CodeGen/CGDecl.cpp
    clang/lib/CodeGen/CodeGenModule.cpp
    clang/lib/Driver/ToolChains/Clang.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index a03447ca2931e2..f9903b18603b58 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -477,6 +477,10 @@ CODEGENOPT(Addrsig, 1, 0)
 /// Whether to emit unused static constants.
 CODEGENOPT(KeepStaticConsts, 1, 0)
 
+/// Whether to emit all variables that have a persistent storage duration,
+/// including global, static and thread local variables.
+CODEGENOPT(KeepPersistentStorageVariables, 1, 0)
+
 /// Whether to follow the AAPCS enforcing at least one read before storing to a volatile bitfield
 CODEGENOPT(ForceAAPCSBitfieldLoad, 1, 0)
 

diff  --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 8d061e0ca191ea..d4e3e168b4cd01 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1757,6 +1757,10 @@ defm keep_static_consts : BoolFOption<"keep-static-consts",
   CodeGenOpts<"KeepStaticConsts">, DefaultFalse,
   PosFlag<SetTrue, [CC1Option], "Keep">, NegFlag<SetFalse, [], "Don't keep">,
   BothFlags<[NoXarchOption], " static const variables even if unused">>;
+defm keep_persistent_storage_variables : BoolFOption<"keep-persistent-storage-variables",
+  CodeGenOpts<"KeepPersistentStorageVariables">, DefaultFalse,
+  PosFlag<SetTrue, [CC1Option], "Enable">, NegFlag<SetFalse, [], "Disable">,
+  BothFlags<[NoXarchOption], " keeping all variables that have a persistent storage duration, including global, static and thread-local variables, to guarantee that they can be directly addressed">>;
 defm fixed_point : BoolFOption<"fixed-point",
   LangOpts<"FixedPoint">, DefaultFalse,
   PosFlag<SetTrue, [CC1Option], "Enable">, NegFlag<SetFalse, [], "Disable">,

diff  --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index f0953eed6acde9..b0d6eb05acc22e 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -470,6 +470,9 @@ void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D,
   else if (D.hasAttr<UsedAttr>())
     CGM.addUsedOrCompilerUsedGlobal(var);
 
+  if (CGM.getCodeGenOpts().KeepPersistentStorageVariables)
+    CGM.addUsedOrCompilerUsedGlobal(var);
+
   // We may have to cast the constant because of the initializer
   // mismatch above.
   //

diff  --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index d8a45e4dcb3064..1a9cfc21ba71db 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2426,12 +2426,14 @@ void CodeGenModule::SetCommonAttributes(GlobalDecl GD, llvm::GlobalValue *GV) {
   if (D && D->hasAttr<UsedAttr>())
     addUsedOrCompilerUsedGlobal(GV);
 
-  if (CodeGenOpts.KeepStaticConsts && D && isa<VarDecl>(D)) {
-    const auto *VD = cast<VarDecl>(D);
-    if (VD->getType().isConstQualified() &&
-        VD->getStorageDuration() == SD_Static)
-      addUsedOrCompilerUsedGlobal(GV);
-  }
+  if (const auto *VD = dyn_cast_if_present<VarDecl>(D);
+      VD &&
+      ((CodeGenOpts.KeepPersistentStorageVariables &&
+        (VD->getStorageDuration() == SD_Static ||
+         VD->getStorageDuration() == SD_Thread)) ||
+       (CodeGenOpts.KeepStaticConsts && VD->getStorageDuration() == SD_Static &&
+        VD->getType().isConstQualified())))
+    addUsedOrCompilerUsedGlobal(GV);
 }
 
 bool CodeGenModule::GetCPUAndFeaturesAttributes(GlobalDecl GD,
@@ -3312,12 +3314,14 @@ bool CodeGenModule::MustBeEmitted(const ValueDecl *Global) {
   if (LangOpts.EmitAllDecls)
     return true;
 
-  if (CodeGenOpts.KeepStaticConsts) {
-    const auto *VD = dyn_cast<VarDecl>(Global);
-    if (VD && VD->getType().isConstQualified() &&
-        VD->getStorageDuration() == SD_Static)
-      return true;
-  }
+  const auto *VD = dyn_cast<VarDecl>(Global);
+  if (VD &&
+      ((CodeGenOpts.KeepPersistentStorageVariables &&
+        (VD->getStorageDuration() == SD_Static ||
+         VD->getStorageDuration() == SD_Thread)) ||
+       (CodeGenOpts.KeepStaticConsts && VD->getStorageDuration() == SD_Static &&
+        VD->getType().isConstQualified())))
+    return true;
 
   return getContext().DeclMustBeEmitted(Global);
 }

diff  --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index ce0e3aa2b3d325..ecd739e5f770bb 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -7404,6 +7404,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
 
   Args.addOptInFlag(CmdArgs, options::OPT_fkeep_static_consts,
                     options::OPT_fno_keep_static_consts);
+  Args.addOptInFlag(CmdArgs, options::OPT_fkeep_persistent_storage_variables,
+                    options::OPT_fno_keep_persistent_storage_variables);
   Args.addOptInFlag(CmdArgs, options::OPT_fcomplete_member_pointers,
                     options::OPT_fno_complete_member_pointers);
   Args.addOptOutFlag(CmdArgs, options::OPT_fcxx_static_destructors,

diff  --git a/clang/test/CodeGen/keep-persistent-storage-variables.cpp b/clang/test/CodeGen/keep-persistent-storage-variables.cpp
new file mode 100644
index 00000000000000..76ebf2921fb6a2
--- /dev/null
+++ b/clang/test/CodeGen/keep-persistent-storage-variables.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -fkeep-persistent-storage-variables -emit-llvm %s -o - -triple=x86_64-unknown-linux-gnu | FileCheck %s
+// RUN: %clang_cc1 -fkeep-persistent-storage-variables -emit-llvm %s -o - -triple=powerpc64-ibm-aix-xcoff | FileCheck %s
+
+// CHECK: @_ZL2g1 = internal global i32 0, align 4
+// CHECK: @_ZL2g2 = internal global i32 1, align 4
+// CHECK: @tl1 = thread_local global i32 0, align 4
+// CHECK: @tl2 = thread_local global i32 3, align 4
+// CHECK: @_ZL3tl3 = internal thread_local global i32 0, align 4
+// CHECK: @_ZL3tl4 = internal thread_local global i32 4, align 4
+// CHECK: @g5 = global i32 0, align 4
+// CHECK: @g6 = global i32 6, align 4
+// CHECK: @_ZZ5test3vE2s3 = internal global i32 0, align 4
+// CHECK: @_ZN12_GLOBAL__N_12s4E = internal global i32 42, align 4
+// CHECK: @_ZZ5test5vE3tl5 = internal thread_local global i32 1, align 4
+// CHECK: @_ZN2ST2s6E = global i32 7, align 4
+// CHECK: @_Z2v7 = internal global %union.anon zeroinitializer, align 4
+// CHECK: @_ZDC2v8E = global %struct.ST8 zeroinitializer, align 4
+// CHECK: @llvm{{(\.compiler)?}}.used = appending global [14 x ptr] [ptr @_ZL2g1, ptr @_ZL2g2, ptr @tl1, ptr @tl2, ptr @_ZL3tl3, ptr @_ZL3tl4, ptr @g5, ptr @g6, ptr @_ZZ5test3vE2s3, ptr @_ZN12_GLOBAL__N_12s4E, ptr @_ZZ5test5vE3tl5, ptr @_ZN2ST2s6E, ptr @_Z2v7, ptr @_ZDC2v8E], section "llvm.metadata"
+
+static int g1;
+static int g2 = 1;
+__thread int tl1;
+__thread int tl2 = 3;
+static __thread int tl3;
+static __thread int tl4 = 4;
+int g5;
+int g6 = 6;
+
+int test3() {
+  static int s3 = 0;
+  ++s3;
+  return s3;
+}
+
+namespace {
+  int s4 = 42;
+}
+
+int test5() {
+  static __thread int tl5 = 1;
+  ++tl5;
+  return tl5;
+}
+
+struct ST {
+  static int s6;
+};
+int ST::s6 = 7;
+
+static union { int v7; };
+
+struct ST8 { int v8; };
+auto [v8] = ST8{0};

diff  --git a/clang/test/Driver/fkeep-persistent-storage-variables.c b/clang/test/Driver/fkeep-persistent-storage-variables.c
new file mode 100644
index 00000000000000..25ec12a023e104
--- /dev/null
+++ b/clang/test/Driver/fkeep-persistent-storage-variables.c
@@ -0,0 +1,5 @@
+// RUN: %clang -fkeep-persistent-storage-variables -c %s -### 2>&1 | FileCheck %s
+// RUN: %clang -fkeep-persistent-storage-variables -fno-keep-persistent-storage-variables -c %s -### 2>&1 | FileCheck %s -check-prefix=CHECK-NOKEEP
+
+// CHECK: "-fkeep-persistent-storage-variables"
+// CHECK-NOKEEP-NOT: "-fkeep-persistent-storage-variables"


        


More information about the cfe-commits mailing list