Skip to content

Commit fc0144a

Browse files
authored
[Serialization] Read the initializer for interesting static variables before consuming it (#92353)
Close #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.
1 parent 89d0937 commit fc0144a

File tree

3 files changed

+214
-126
lines changed

3 files changed

+214
-126
lines changed

clang/lib/Serialization/ASTReaderDecl.cpp

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4186,12 +4186,35 @@ void ASTReader::PassInterestingDeclsToConsumer() {
41864186
GetDecl(ID);
41874187
EagerlyDeserializedDecls.clear();
41884188

4189-
while (!PotentiallyInterestingDecls.empty()) {
4190-
Decl *D = PotentiallyInterestingDecls.front();
4191-
PotentiallyInterestingDecls.pop_front();
4189+
auto ConsumingPotentialInterestingDecls = [this]() {
4190+
while (!PotentiallyInterestingDecls.empty()) {
4191+
Decl *D = PotentiallyInterestingDecls.front();
4192+
PotentiallyInterestingDecls.pop_front();
4193+
if (isConsumerInterestedIn(D))
4194+
PassInterestingDeclToConsumer(D);
4195+
}
4196+
};
4197+
std::deque<Decl *> MaybeInterestingDecls =
4198+
std::move(PotentiallyInterestingDecls);
4199+
assert(PotentiallyInterestingDecls.empty());
4200+
while (!MaybeInterestingDecls.empty()) {
4201+
Decl *D = MaybeInterestingDecls.front();
4202+
MaybeInterestingDecls.pop_front();
4203+
// Since we load the variable's initializers lazily, it'd be problematic
4204+
// if the initializers dependent on each other. So here we try to load the
4205+
// initializers of static variables to make sure they are passed to code
4206+
// generator by order. If we read anything interesting, we would consume
4207+
// that before emitting the current declaration.
4208+
if (auto *VD = dyn_cast<VarDecl>(D);
4209+
VD && VD->isFileVarDecl() && !VD->isExternallyVisible())
4210+
VD->getInit();
4211+
ConsumingPotentialInterestingDecls();
41924212
if (isConsumerInterestedIn(D))
41934213
PassInterestingDeclToConsumer(D);
41944214
}
4215+
4216+
// If we add any new potential interesting decl in the last call, consume it.
4217+
ConsumingPotentialInterestingDecls();
41954218
}
41964219

41974220
void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) {

clang/test/Modules/pr91418.cppm

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// RUN: rm -rf %t
2+
// RUN: mkdir -p %t
3+
// RUN: split-file %s %t
4+
//
5+
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 -x c++-header %t/foo.h \
6+
// RUN: -emit-pch -o %t/foo.pch
7+
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 %t/use.cpp -include-pch \
8+
// RUN: %t/foo.pch -emit-llvm -o - | FileCheck %t/use.cpp
9+
10+
//--- foo.h
11+
#ifndef FOO_H
12+
#define FOO_H
13+
typedef float __m128 __attribute__((__vector_size__(16), __aligned__(16)));
14+
15+
static __inline__ __m128 __attribute__((__always_inline__, __min_vector_width__(128)))
16+
_mm_setr_ps(float __z, float __y, float __x, float __w)
17+
{
18+
return __extension__ (__m128){ __z, __y, __x, __w };
19+
}
20+
21+
typedef __m128 VR;
22+
23+
inline VR MakeVR( float X, float Y, float Z, float W )
24+
{
25+
return _mm_setr_ps( X, Y, Z, W );
26+
}
27+
28+
extern "C" float sqrtf(float);
29+
30+
namespace VectorSinConstantsSSE
31+
{
32+
float a = (16 * sqrtf(0.225f));
33+
VR A = MakeVR(a, a, a, a);
34+
static const float b = (16 * sqrtf(0.225f));
35+
static const VR B = MakeVR(b, b, b, b);
36+
}
37+
38+
#endif // FOO_H
39+
40+
//--- use.cpp
41+
#include "foo.h"
42+
float use() {
43+
return VectorSinConstantsSSE::A[0] + VectorSinConstantsSSE::A[1] +
44+
VectorSinConstantsSSE::A[2] + VectorSinConstantsSSE::A[3] +
45+
VectorSinConstantsSSE::B[0] + VectorSinConstantsSSE::B[1] +
46+
VectorSinConstantsSSE::B[2] + VectorSinConstantsSSE::B[3];
47+
}
48+
49+
// CHECK: define{{.*}}@__cxx_global_var_init(
50+
// CHECK: store{{.*}}, ptr @_ZN21VectorSinConstantsSSE1aE
51+
52+
// CHECK: define{{.*}}@__cxx_global_var_init.1(
53+
// CHECK: store{{.*}}, ptr @_ZN21VectorSinConstantsSSE1AE
54+
55+
// CHECK: define{{.*}}@__cxx_global_var_init.2(
56+
// CHECK: store{{.*}}, ptr @_ZN21VectorSinConstantsSSEL1BE
57+
58+
// CHECK: define{{.*}}@__cxx_global_var_init.3(
59+
// CHECK: store{{.*}}, ptr @_ZN21VectorSinConstantsSSEL1bE
60+
61+
// CHECK: @_GLOBAL__sub_I_use.cpp
62+
// CHECK: call{{.*}}@__cxx_global_var_init(
63+
// CHECK: call{{.*}}@__cxx_global_var_init.1(
64+
// CHECK: call{{.*}}@__cxx_global_var_init.3(
65+
// CHECK: call{{.*}}@__cxx_global_var_init.2(

0 commit comments

Comments
 (0)