[clang] f9969a3 - [CodeGen] Sort llvm.global_ctors by lexing order before emission

Yuanfang Chen via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 22 16:00:55 PDT 2022


Author: Yuanfang Chen
Date: 2022-08-22T16:00:14-07:00
New Revision: f9969a3d28e738e9427e371aac06d71269220123

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

LOG: [CodeGen] Sort llvm.global_ctors by lexing order before emission

Fixes https://github.com/llvm/llvm-project/issues/55804

The lexing order is already bookkept in DelayedCXXInitPosition but we
were not using it based on the wrong assumption that inline variable is
unordered. This patch fixes it by ordering entries in llvm.global_ctors
by orders in DelayedCXXInitPosition.

for llvm.global_ctors entries without a lexing order, ordering them by
the insertion order.

(This *mostly* orders the template instantiation in
https://reviews.llvm.org/D126341 intuitively, minus one tweak for which I'll
submit a separate patch.)

Reviewed By: efriedma

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

Added: 
    clang/test/CodeGenCXX/static-init-inline-variable.cpp

Modified: 
    clang/lib/CodeGen/CGDeclCXX.cpp
    clang/lib/CodeGen/CodeGenModule.cpp
    clang/lib/CodeGen/CodeGenModule.h
    clang/lib/CodeGen/ItaniumCXXABI.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp
index 8ceb4863d6ead..2075857848656 100644
--- a/clang/lib/CodeGen/CGDeclCXX.cpp
+++ b/clang/lib/CodeGen/CGDeclCXX.cpp
@@ -562,7 +562,7 @@ CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D,
       Priority = 400;
 
     if (Priority != -1)
-      AddGlobalCtor(Fn, Priority, COMDATKey);
+      AddGlobalCtor(Fn, Priority, ~0U, COMDATKey);
     else
       EmitPointerToInitFunc(D, Addr, Fn, ISA);
   } else if (auto *IPA = D->getAttr<InitPriorityAttr>()) {
@@ -588,8 +588,16 @@ CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D,
     // SelectAny globals will be comdat-folded. Put the initializer into a
     // COMDAT group associated with the global, so the initializers get folded
     // too.
-
-    AddGlobalCtor(Fn, 65535, COMDATKey);
+    I = DelayedCXXInitPosition.find(D);
+    // CXXGlobalInits.size() is the lex order number for the next deferred
+    // VarDecl. Use it when the current VarDecl is non-deferred. Although this
+    // lex order number is shared between current VarDecl and some following
+    // VarDecls, their order of insertion into `llvm.global_ctors` is the same
+    // as the lexing order and the following stable sort would preserve such
+    // order.
+    unsigned LexOrder =
+        I == DelayedCXXInitPosition.end() ? CXXGlobalInits.size() : I->second;
+    AddGlobalCtor(Fn, 65535, LexOrder, COMDATKey);
     if (COMDATKey && (getTriple().isOSBinFormatELF() ||
                       getTarget().getCXXABI().isMicrosoft())) {
       // When COMDAT is used on ELF or in the MS C++ ABI, the key must be in

diff  --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 9b97e890c3523..74c14fed6575e 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -47,6 +47,7 @@
 #include "clang/CodeGen/BackendUtil.h"
 #include "clang/CodeGen/ConstantInitBuilder.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/Analysis/TargetLibraryInfo.h"
@@ -560,6 +561,9 @@ void CodeGenModule::Release() {
     if (PGOStats.hasDiagnostics())
       PGOStats.reportDiagnostics(getDiags(), getCodeGenOpts().MainFileName);
   }
+  llvm::stable_sort(GlobalCtors, [](const Structor &L, const Structor &R) {
+    return L.LexOrder < R.LexOrder;
+  });
   EmitCtorList(GlobalCtors, "llvm.global_ctors");
   EmitCtorList(GlobalDtors, "llvm.global_dtors");
   EmitGlobalAnnotations();
@@ -1579,9 +1583,10 @@ llvm::GlobalValue *CodeGenModule::GetGlobalValue(StringRef Name) {
 /// AddGlobalCtor - Add a function to the list that will be called before
 /// main() runs.
 void CodeGenModule::AddGlobalCtor(llvm::Function *Ctor, int Priority,
+                                  unsigned LexOrder,
                                   llvm::Constant *AssociatedData) {
   // FIXME: Type coercion of void()* types.
-  GlobalCtors.push_back(Structor(Priority, Ctor, AssociatedData));
+  GlobalCtors.push_back(Structor(Priority, LexOrder, Ctor, AssociatedData));
 }
 
 /// AddGlobalDtor - Add a function to the list that will be called
@@ -1595,7 +1600,7 @@ void CodeGenModule::AddGlobalDtor(llvm::Function *Dtor, int Priority,
   }
 
   // FIXME: Type coercion of void()* types.
-  GlobalDtors.push_back(Structor(Priority, Dtor, nullptr));
+  GlobalDtors.push_back(Structor(Priority, ~0U, Dtor, nullptr));
 }
 
 void CodeGenModule::EmitCtorList(CtorList &Fns, const char *GlobalName) {

diff  --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index 14c791f4bce57..f57afdca49429 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -282,12 +282,15 @@ class CodeGenModule : public CodeGenTypeCache {
 
 public:
   struct Structor {
-    Structor() : Priority(0), Initializer(nullptr), AssociatedData(nullptr) {}
-    Structor(int Priority, llvm::Constant *Initializer,
+    Structor()
+        : Priority(0), LexOrder(~0u), Initializer(nullptr),
+          AssociatedData(nullptr) {}
+    Structor(int Priority, unsigned LexOrder, llvm::Constant *Initializer,
              llvm::Constant *AssociatedData)
-        : Priority(Priority), Initializer(Initializer),
+        : Priority(Priority), LexOrder(LexOrder), Initializer(Initializer),
           AssociatedData(AssociatedData) {}
     int Priority;
+    unsigned LexOrder;
     llvm::Constant *Initializer;
     llvm::Constant *AssociatedData;
   };
@@ -1602,6 +1605,7 @@ class CodeGenModule : public CodeGenTypeCache {
 
   // FIXME: Hardcoding priority here is gross.
   void AddGlobalCtor(llvm::Function *Ctor, int Priority = 65535,
+                     unsigned LexOrder = ~0U,
                      llvm::Constant *AssociatedData = nullptr);
   void AddGlobalDtor(llvm::Function *Dtor, int Priority = 65535,
                      bool IsDtorAttrFunc = false);

diff  --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 002a5edabe222..2809cbe99c101 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -2687,7 +2687,7 @@ void CodeGenModule::registerGlobalDtorsWithAtExit() {
     }
 
     CGF.FinishFunction();
-    AddGlobalCtor(GlobalInitFn, Priority, nullptr);
+    AddGlobalCtor(GlobalInitFn, Priority);
   }
 
   if (getCXXABI().useSinitAndSterm())

diff  --git a/clang/test/CodeGenCXX/static-init-inline-variable.cpp b/clang/test/CodeGenCXX/static-init-inline-variable.cpp
new file mode 100644
index 0000000000000..873e32544c7e6
--- /dev/null
+++ b/clang/test/CodeGenCXX/static-init-inline-variable.cpp
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -std=c++17 -S -emit-llvm -disable-llvm-passes -o - %s -triple x86_64-linux-gnu | FileCheck %s
+
+struct A {
+  int x;
+  A(int x) : x(x) {}
+  ~A() {}
+};
+
+namespace DeferredSequence {
+inline int a = 1;
+inline int b = a + 1;
+inline int c = b + 1;
+inline int d = c + 1;
+int e = d;
+}
+
+namespace MixedSequence {
+inline A a(1);
+inline int x = a.x + 1;
+inline int y = x + 1;
+inline A b(y);
+inline int z = b.x + 1;
+inline int w = z + 1;
+inline A c(b.x);
+inline A d(c.x);
+int t = w;
+}
+
+namespace NonDeferredSequence {
+inline A a(1);
+inline A b(a.x);
+inline A c(b.x);
+inline A d(c.x);
+}
+
+// CHECK: @llvm.global_ctors = appending global [16 x { i32, ptr, ptr }] [
+// CHECK-SAME: { i32, ptr, ptr } { i32 65535, ptr @__cxx_global_var_init.12, ptr @_ZN16DeferredSequence1bE },
+// CHECK-SAME: { i32, ptr, ptr } { i32 65535, ptr @__cxx_global_var_init.11, ptr @_ZN16DeferredSequence1cE },
+// CHECK-SAME: { i32, ptr, ptr } { i32 65535, ptr @__cxx_global_var_init.10, ptr @_ZN16DeferredSequence1dE },
+// CHECK-SAME: { i32, ptr, ptr } { i32 65535, ptr @__cxx_global_var_init.1,  ptr @_ZN13MixedSequence1aE },
+// CHECK-SAME: { i32, ptr, ptr } { i32 65535, ptr @__cxx_global_var_init.14, ptr @_ZN13MixedSequence1xE },
+// CHECK-SAME: { i32, ptr, ptr } { i32 65535, ptr @__cxx_global_var_init.13, ptr @_ZN13MixedSequence1yE },
+// CHECK-SAME: { i32, ptr, ptr } { i32 65535, ptr @__cxx_global_var_init.2,  ptr @_ZN13MixedSequence1bE },
+// CHECK-SAME: { i32, ptr, ptr } { i32 65535, ptr @__cxx_global_var_init.16, ptr @_ZN13MixedSequence1zE },
+// CHECK-SAME: { i32, ptr, ptr } { i32 65535, ptr @__cxx_global_var_init.15, ptr @_ZN13MixedSequence1wE },
+// CHECK-SAME: { i32, ptr, ptr } { i32 65535, ptr @__cxx_global_var_init.3,  ptr @_ZN13MixedSequence1cE },
+// CHECK-SAME: { i32, ptr, ptr } { i32 65535, ptr @__cxx_global_var_init.4,  ptr @_ZN13MixedSequence1dE },
+// CHECK-SAME: { i32, ptr, ptr } { i32 65535, ptr @__cxx_global_var_init.6,  ptr @_ZN19NonDeferredSequence1aE },
+// CHECK-SAME: { i32, ptr, ptr } { i32 65535, ptr @__cxx_global_var_init.7,  ptr @_ZN19NonDeferredSequence1bE },
+// CHECK-SAME: { i32, ptr, ptr } { i32 65535, ptr @__cxx_global_var_init.8,  ptr @_ZN19NonDeferredSequence1cE },
+// CHECK-SAME: { i32, ptr, ptr } { i32 65535, ptr @__cxx_global_var_init.9,  ptr @_ZN19NonDeferredSequence1dE },
+// CHECK-SAME: { i32, ptr, ptr } { i32 65535, ptr @_GLOBAL__sub_I_static_init_inline_variable.cpp, ptr null }


        


More information about the cfe-commits mailing list