[clang] 11b0591 - [Serialization] Read the initializer for interesting static variables before consuming it
Chuanqi Xu via cfe-commits
cfe-commits at lists.llvm.org
Tue May 14 19:30:44 PDT 2024
Author: Chuanqi Xu
Date: 2024-05-15T10:29:49+08:00
New Revision: 11b059145d177ee287c7ada9864addf8d083c160
URL: https://github.com/llvm/llvm-project/commit/11b059145d177ee287c7ada9864addf8d083c160
DIFF: https://github.com/llvm/llvm-project/commit/11b059145d177ee287c7ada9864addf8d083c160.diff
LOG: [Serialization] Read the initializer for interesting static variables before consuming it
Close https://github.com/llvm/llvm-project/issues/91418
Since we load the variable's initializers lazily, it'd be problematic
if the initializers dependent on each other. So here we try to load the
initializers of static variables to make sure they are passed to code
generator by order. If we read any thing interesting, we would consume
that before emitting the current declaration.
Added:
clang/test/Modules/pr91418.cppm
Modified:
clang/lib/Serialization/ASTReaderDecl.cpp
Removed:
################################################################################
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 0c647086e304a..a6254b70560c3 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -4186,12 +4186,35 @@ void ASTReader::PassInterestingDeclsToConsumer() {
GetDecl(ID);
EagerlyDeserializedDecls.clear();
- while (!PotentiallyInterestingDecls.empty()) {
- Decl *D = PotentiallyInterestingDecls.front();
- PotentiallyInterestingDecls.pop_front();
+ auto ConsumingPotentialInterestingDecls = [this]() {
+ while (!PotentiallyInterestingDecls.empty()) {
+ Decl *D = PotentiallyInterestingDecls.front();
+ PotentiallyInterestingDecls.pop_front();
+ if (isConsumerInterestedIn(D))
+ PassInterestingDeclToConsumer(D);
+ }
+ };
+ std::deque<Decl *> MaybeInterestingDecls =
+ std::move(PotentiallyInterestingDecls);
+ assert(PotentiallyInterestingDecls.empty());
+ while (!MaybeInterestingDecls.empty()) {
+ Decl *D = MaybeInterestingDecls.front();
+ MaybeInterestingDecls.pop_front();
+ // Since we load the variable's initializers lazily, it'd be problematic
+ // if the initializers dependent on each other. So here we try to load the
+ // initializers of static variables to make sure they are passed to code
+ // generator by order. If we read anything interesting, we would consume
+ // that before emitting the current declaration.
+ if (auto *VD = dyn_cast<VarDecl>(D);
+ VD && VD->isFileVarDecl() && !VD->isExternallyVisible())
+ VD->getInit();
+ ConsumingPotentialInterestingDecls();
if (isConsumerInterestedIn(D))
PassInterestingDeclToConsumer(D);
}
+
+ // If we add any new potential interesting decl in the last call, consume it.
+ ConsumingPotentialInterestingDecls();
}
void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) {
diff --git a/clang/test/Modules/pr91418.cppm b/clang/test/Modules/pr91418.cppm
new file mode 100644
index 0000000000000..33fec992439d6
--- /dev/null
+++ b/clang/test/Modules/pr91418.cppm
@@ -0,0 +1,67 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+//
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 -x c++-header %t/foo.h \
+// RUN: -emit-pch -o %t/foo.pch
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 %t/use.cpp -include-pch \
+// RUN: %t/foo.pch -emit-llvm -o - | FileCheck %t/use.cpp
+
+//--- foo.h
+#ifndef FOO_H
+#define FOO_H
+typedef float __m128 __attribute__((__vector_size__(16), __aligned__(16)));
+
+static __inline__ __m128 __attribute__((__always_inline__, __min_vector_width__(128)))
+_mm_setr_ps(float __z, float __y, float __x, float __w)
+{
+ return __extension__ (__m128){ __z, __y, __x, __w };
+}
+
+typedef __m128 VR;
+
+inline VR MakeVR( float X, float Y, float Z, float W )
+{
+ return _mm_setr_ps( X, Y, Z, W );
+}
+
+extern "C" float sqrtf(float);
+
+namespace VectorSinConstantsSSE
+{
+ float a = (16 * sqrtf(0.225f));
+ VR A = MakeVR(a, a, a, a);
+ static const float b = (16 * sqrtf(0.225f));
+ static const VR B = MakeVR(b, b, b, b);
+}
+
+#endif // FOO_H
+
+//--- use.cpp
+#include "foo.h"
+float use() {
+ return VectorSinConstantsSSE::A[0] + VectorSinConstantsSSE::A[1] +
+ VectorSinConstantsSSE::A[2] + VectorSinConstantsSSE::A[3] +
+ VectorSinConstantsSSE::B[0] + VectorSinConstantsSSE::B[1] +
+ VectorSinConstantsSSE::B[2] + VectorSinConstantsSSE::B[3];
+}
+
+// CHECK: define{{.*}}@__cxx_global_var_init(
+// CHECK: store{{.*}}[[a_RESULT:%[a-zA-Z0-9]+]], ptr @_ZN21VectorSinConstantsSSE1aE
+
+// CHECK: define{{.*}}@__cxx_global_var_init.1(
+// CHECK: [[A_CALL:%[a-zA-Z0-9]+]] = call{{.*}}@_Z6MakeVRffff(
+// CHECK: store{{.*}}[[A_CALL]], ptr @_ZN21VectorSinConstantsSSE1AE
+
+// CHECK: define{{.*}}@__cxx_global_var_init.2(
+// CHECK: [[B_CALL:%[a-zA-Z0-9]+]] = call{{.*}}@_Z6MakeVRffff(
+// CHECK: store{{.*}}[[B_CALL]], ptr @_ZN21VectorSinConstantsSSEL1BE
+
+// CHECK: define{{.*}}@__cxx_global_var_init.3(
+// CHECK: store{{.*}}[[b_RESULT:%[a-zA-Z0-9]+]], ptr @_ZN21VectorSinConstantsSSEL1bE
+
+// CHECK: @_GLOBAL__sub_I_use.cpp
+// CHECK: call{{.*}}@__cxx_global_var_init(
+// CHECK: call{{.*}}@__cxx_global_var_init.1(
+// CHECK: call{{.*}}@__cxx_global_var_init.3(
+// CHECK: call{{.*}}@__cxx_global_var_init.2(
More information about the cfe-commits
mailing list