r231564 - Reapply r231508 "CodeGen: Emit constant temporaries into read-only globals."
Richard Smith
richard at metafoo.co.uk
Wed Apr 8 20:24:26 PDT 2015
On Wed, Apr 8, 2015 at 8:09 PM, Richard Smith <richard at metafoo.co.uk> wrote:
> I suspect this caused PR23165, can you investigate? Looks like the global
> constant we emit for the temporary in that case has the wrong vptr!
>
> On Sat, Mar 7, 2015 at 5:37 AM, Benjamin Kramer <benny.kra at googlemail.com>
> wrote:
>
>> Author: d0k
>> Date: Sat Mar 7 07:37:13 2015
>> New Revision: 231564
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=231564&view=rev
>> Log:
>> Reapply r231508 "CodeGen: Emit constant temporaries into read-only
>> globals."
>>
>> I disabled putting the new global into the same COMDAT as the function
>> for now.
>> There's a fundamental problem when we inline references to the global but
>> still
>> have the global in a COMDAT linked to the inlined function. Since this is
>> only
>> an optimization there may be other versions of the COMDAT around that are
>> missing the new global and hell breaks loose at link time.
>>
>> I hope the chromium build doesn't break this time :)
>>
>> Modified:
>> cfe/trunk/lib/CodeGen/CGExpr.cpp
>> cfe/trunk/test/CodeGenCXX/compound-literals.cpp
>> cfe/trunk/test/CodeGenCXX/cxx0x-initializer-array.cpp
>> cfe/trunk/test/CodeGenCXX/cxx0x-initializer-references.cpp
>> cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
>>
>> Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=231564&r1=231563&r2=231564&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
>> +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Sat Mar 7 07:37:13 2015
>> @@ -301,6 +301,23 @@ createReferenceTemporary(CodeGenFunction
>> switch (M->getStorageDuration()) {
>> case SD_FullExpression:
>> case SD_Automatic:
>> + // If we have a constant temporary array or record try to promote it
>> into a
>> + // constant global under the same rules a normal constant would've
>> been
>> + // promoted. This is easier on the optimizer and generally emits
>> fewer
>> + // instructions.
>> + if (CGF.CGM.getCodeGenOpts().MergeAllConstants &&
>> + (M->getType()->isArrayType() || M->getType()->isRecordType()) &&
>> + CGF.CGM.isTypeConstant(M->getType(), true))
>> + if (llvm::Constant *Init =
>> + CGF.CGM.EmitConstantExpr(Inner, M->getType(), &CGF)) {
>>
>
This is using the wrong type; you're assuming that M's type and Inner's
type are the same, and they're not in general (M can refer to a subobject
of the object initialized by Inner). You shouldn't be looking at M at all
in this code; it's passed in so that the static / thread storage cases can
work out the linkage and mangled name for their global.
> + auto *GV = new llvm::GlobalVariable(
>> + CGF.CGM.getModule(), Init->getType(), /*isConstant=*/true,
>> + llvm::GlobalValue::PrivateLinkage, Init, ".ref.tmp");
>> + GV->setAlignment(
>> +
>> CGF.getContext().getTypeAlignInChars(M->getType()).getQuantity());
>> + // FIXME: Should we put the new global into a COMDAT?
>> + return GV;
>> + }
>> return CGF.CreateMemTemp(Inner->getType(), "ref.tmp");
>>
>> case SD_Thread:
>> @@ -370,8 +387,9 @@ EmitMaterializeTemporaryExpr(const Mater
>> // Create and initialize the reference temporary.
>> llvm::Value *Object = createReferenceTemporary(*this, M, E);
>> if (auto *Var = dyn_cast<llvm::GlobalVariable>(Object)) {
>> - // If the temporary is a global and has a constant initializer, we
>> may
>> - // have already initialized it.
>> + // If the temporary is a global and has a constant initializer or is
>> a
>> + // constant temporary that we promoted to a global, we may have
>> already
>> + // initialized it.
>> if (!Var->hasInitializer()) {
>> Var->setInitializer(CGM.EmitNullConstant(E->getType()));
>> EmitAnyExprToMem(E, Object, Qualifiers(), /*IsInit*/true);
>>
>> Modified: cfe/trunk/test/CodeGenCXX/compound-literals.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/compound-literals.cpp?rev=231564&r1=231563&r2=231564&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/test/CodeGenCXX/compound-literals.cpp (original)
>> +++ cfe/trunk/test/CodeGenCXX/compound-literals.cpp Sat Mar 7 07:37:13
>> 2015
>> @@ -28,7 +28,7 @@ int f() {
>>
>> // CHECK-LABEL: define i32 @_Z1gv()
>> int g() {
>> - // CHECK: store [2 x i32]* %{{[a-z0-9.]+}}, [2 x i32]**
>> [[V:%[a-z0-9.]+]]
>> + // CHECK: store [2 x i32]* @{{.*}}, [2 x i32]** [[V:%[a-z0-9.]+]]
>> const int (&v)[2] = (int [2]) {1,2};
>>
>> // CHECK: [[A:%[a-z0-9.]+]] = load [2 x i32]*, [2 x i32]** [[V]]
>>
>> Modified: cfe/trunk/test/CodeGenCXX/cxx0x-initializer-array.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx0x-initializer-array.cpp?rev=231564&r1=231563&r2=231564&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/test/CodeGenCXX/cxx0x-initializer-array.cpp (original)
>> +++ cfe/trunk/test/CodeGenCXX/cxx0x-initializer-array.cpp Sat Mar 7
>> 07:37:13 2015
>> @@ -42,10 +42,11 @@ namespace ValueInitArrayOfMemPtr {
>> // CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %{{.*}}, i8*
>> bitcast ([3 x i32]* @[[THREE_NULL_MEMPTRS]] to i8*), i32 12, i32 4, i1
>> false)
>> }
>>
>> - // CHECK-LABEL: define void @_ZN22ValueInitArrayOfMemPtr1gEv
>> - void g() {
>> + // Test dynamic initialization.
>> + // CHECK-LABEL: define void @_ZN22ValueInitArrayOfMemPtr1gEMNS_1SEi
>> + void g(p ptr) {
>> // CHECK: store i32 -1,
>> - f(a{});
>> + f(a{ptr});
>> }
>> }
>>
>>
>> Modified: cfe/trunk/test/CodeGenCXX/cxx0x-initializer-references.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx0x-initializer-references.cpp?rev=231564&r1=231563&r2=231564&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/test/CodeGenCXX/cxx0x-initializer-references.cpp (original)
>> +++ cfe/trunk/test/CodeGenCXX/cxx0x-initializer-references.cpp Sat Mar 7
>> 07:37:13 2015
>> @@ -35,22 +35,30 @@ namespace reference {
>> // CHECK-NEXT: ret
>> }
>>
>> - void reference_to_aggregate() {
>> + void reference_to_aggregate(int i) {
>> // CHECK: getelementptr {{.*}}, i32 0, i32 0
>> // CHECK-NEXT: store i32 1
>> // CHECK-NEXT: getelementptr {{.*}}, i32 0, i32 1
>> - // CHECK-NEXT: store i32 2
>> + // CHECK-NEXT: %[[I1:.*]] = load i32, i32*
>> + // CHECK-NEXT: store i32 %[[I1]]
>> // CHECK-NEXT: store %{{.*}}* %{{.*}}, %{{.*}}** %{{.*}}, align
>> - const A &ra1{1, 2};
>> + const A &ra1{1, i};
>>
>> // CHECK-NEXT: getelementptr inbounds [3 x i32], [3 x i32]* %{{.*}},
>> i{{32|64}} 0, i{{32|64}} 0
>> // CHECK-NEXT: store i32 1
>> // CHECK-NEXT: getelementptr inbounds i32, i32* %{{.*}}, i{{32|64}} 1
>> // CHECK-NEXT: store i32 2
>> // CHECK-NEXT: getelementptr inbounds i32, i32* %{{.*}}, i{{32|64}} 1
>> - // CHECK-NEXT: store i32 3
>> + // CHECK-NEXT: %[[I2:.*]] = load i32, i32*
>> + // CHECK-NEXT: store i32 %[[I2]]
>> // CHECK-NEXT: store [3 x i32]* %{{.*}}, [3 x i32]** %{{.*}}, align
>> - const int (&arrayRef)[] = {1, 2, 3};
>> + const int (&arrayRef)[] = {1, 2, i};
>> +
>> + // CHECK: store %{{.*}}* @{{.*}}, %{{.*}}** %{{.*}}, align
>> + const A &constra1{1, 2};
>> +
>> + // CHECK-NEXT: store [3 x i32]* @{{.*}}, [3 x i32]** %{{.*}}, align
>> + const int (&constarrayRef)[] = {1, 2, 3};
>>
>> // CHECK-NEXT: ret
>> }
>>
>> Modified:
>> cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp?rev=231564&r1=231563&r2=231564&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
>> (original)
>> +++ cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
>> Sat Mar 7 07:37:13 2015
>> @@ -72,6 +72,9 @@ namespace thread_local_global_array {
>> // CHECK: @[[PARTLY_CONSTANT_SECOND:_ZGRN15partly_constant2ilE.*]] =
>> internal global [2 x i32] zeroinitializer, align 4
>> // CHECK: @[[PARTLY_CONSTANT_THIRD:_ZGRN15partly_constant2ilE.*]] =
>> internal constant [4 x i32] [i32 5, i32 6, i32 7, i32 8], align 4
>>
>> +// CHECK: @[[REFTMP1:.*]] = private constant [2 x i32] [i32 42, i32 43],
>> align 4
>> +// CHECK: @[[REFTMP2:.*]] = private constant [3 x %{{.*}}] [%{{.*}} {
>> i32 1 }, %{{.*}} { i32 2 }, %{{.*}} { i32 3 }], align 4
>> +
>> // CHECK: appending global
>>
>>
>> @@ -215,17 +218,16 @@ void fn9() {
>>
>> struct haslist1 {
>> std::initializer_list<int> il;
>> - haslist1();
>> + haslist1(int i);
>> };
>>
>> -// CHECK-LABEL: define void @_ZN8haslist1C2Ev
>> -haslist1::haslist1()
>> +// CHECK-LABEL: define void @_ZN8haslist1C2Ei
>> +haslist1::haslist1(int i)
>> // CHECK: alloca [3 x i32]
>> -// CHECK: store i32 1
>> +// CHECK: store i32 %
>> // CHECK: store i32 2
>> // CHECK: store i32 3
>> -// CHECK: store i{{32|64}} 3
>> - : il{1, 2, 3}
>> + : il{i, 2, 3}
>> {
>> destroyme2 dm2;
>> }
>> @@ -244,16 +246,15 @@ haslist2::haslist2()
>> // CHECK: call void @_ZN10destroyme1D1Ev
>> }
>>
>> -void fn10() {
>> - // CHECK-LABEL: define void @_Z4fn10v
>> +void fn10(int i) {
>> + // CHECK-LABEL: define void @_Z4fn10i
>> // CHECK: alloca [3 x i32]
>> // CHECK: call noalias i8* @_Znw{{[jm]}}
>> - // CHECK: store i32 1
>> + // CHECK: store i32 %
>> // CHECK: store i32 2
>> // CHECK: store i32 3
>> // CHECK: store i32*
>> - // CHECK: store i{{32|64}} 3
>> - (void) new std::initializer_list<int> {1, 2, 3};
>> + (void) new std::initializer_list<int> {i, 2, 3};
>> }
>>
>> void fn11() {
>> @@ -462,6 +463,22 @@ namespace PR20445 {
>> template<int x> void f() { new MyClass({42, 43}); }
>> template void f<0>();
>> // CHECK-LABEL: define {{.*}} @_ZN7PR204451fILi0EEEvv(
>> + // CHECK: store i32* getelementptr inbounds ([2 x i32]* @[[REFTMP1]],
>> i64 0, i64 0)
>> // CHECK: call void @_ZN7PR204456vectorC1ESt16initializer_listIiE(
>> // CHECK: call void @_ZN7PR204457MyClassC1ERKNS_6vectorE(
>> }
>> +
>> +namespace ConstExpr {
>> + class C {
>> + int x;
>> + public:
>> + constexpr C(int x) : x(x) {}
>> + };
>> + void f(std::initializer_list<C>);
>> + void g() {
>> +// CHECK-LABEL: _ZN9ConstExpr1gEv
>> +// CHECK: store %"class.ConstExpr::C"* getelementptr inbounds ([3 x
>> %"class.ConstExpr::C"]* @[[REFTMP2]], i64 0, i64 0)
>> +// CHECK: call void @_ZN9ConstExpr1fESt16initializer_listINS_1CEE
>> + f({C(1), C(2), C(3)});
>> + }
>> +}
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150408/d9635333/attachment.html>
More information about the cfe-commits
mailing list