r231564 - Reapply r231508 "CodeGen: Emit constant temporaries into read-only globals."

Richard Smith richard at metafoo.co.uk
Wed Apr 8 20:09:44 PDT 2015


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)) {
> +        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/baedc543/attachment.html>


More information about the cfe-commits mailing list