Re: r311857 - Emit static constexpr member as available_externally definition

2017-09-04 Thread Mehdi AMINI via cfe-commits
Hey Hans,

Just a heads up that I fixed the issue and reapplies the commit in r312512.
Let me know if any new issues occur! (and feel free to revert of course).

Thanks,

-- 
Mehdi

2017-08-28 14:18 GMT-07:00 Mehdi AMINI :

> Sorry for the inconvenience!
>
> I will follow-up in the PR.
>
> --
> Mehdi
>
>
> 2017-08-28 12:42 GMT-07:00 Hans Wennborg :
>
>> I reverted this in r311898 as it caused Chromium builds to fail with
>> an assertion; see PR34348.
>>
>> On Sun, Aug 27, 2017 at 1:24 PM, Mehdi Amini via cfe-commits
>>  wrote:
>> > Author: mehdi_amini
>> > Date: Sun Aug 27 13:24:09 2017
>> > New Revision: 311857
>> >
>> > URL: http://llvm.org/viewvc/llvm-project?rev=311857=rev
>> > Log:
>> > Emit static constexpr member as available_externally definition
>> >
>> > By exposing the constant initializer, the optimizer can fold many
>> > of these constructs.
>> >
>> > Differential Revision: https://reviews.llvm.org/D34992
>> >
>> > Added:
>> > cfe/trunk/test/CodeGenCXX/cxx11-extern-constexpr.cpp
>> > Modified:
>> > cfe/trunk/lib/CodeGen/CodeGenModule.cpp
>> >
>> > Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
>> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/Co
>> deGenModule.cpp?rev=311857=311856=311857=diff
>> > 
>> ==
>> > --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
>> > +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Sun Aug 27 13:24:09 2017
>> > @@ -2437,6 +2437,28 @@ CodeGenModule::GetOrCreateLLVMGlobal(Str
>> >  D->getType().isConstant(Context) &&
>> >  isExternallyVisible(D->getLinkageAndVisibility().getLinkage(
>> )))
>> >GV->setSection(".cp.rodata");
>> > +
>> > +// Check if we a have a const declaration with an initializer, we
>> may be
>> > +// able to emit it as available_externally to expose it's value to
>> the
>> > +// optimizer.
>> > +if (Context.getLangOpts().CPlusPlus && GV->hasExternalLinkage() &&
>> > +D->getType().isConstQualified() && !GV->hasInitializer() &&
>> > +!D->hasDefinition() && D->hasInit() &&
>> !D->hasAttr()) {
>> > +  const auto *Record =
>> > +  Context.getBaseElementType(D->getType())->getAsCXXRecordDecl
>> ();
>> > +  bool HasMutableFields = Record && Record->hasMutableFields();
>> > +  if (!HasMutableFields) {
>> > +const VarDecl *InitDecl;
>> > +const Expr *InitExpr = D->getAnyInitializer(InitDecl);
>> > +if (InitExpr) {
>> > +  GV->setConstant(true);
>> > +  GV->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage
>> );
>> > +  ConstantEmitter emitter(*this);
>> > +  GV->setInitializer(emitter.tryEmitForInitializer(*InitDecl))
>> ;
>> > +  emitter.finalize(GV);
>> > +}
>> > +  }
>> > +}
>> >}
>> >
>> >auto ExpectedAS =
>> >
>> > Added: cfe/trunk/test/CodeGenCXX/cxx11-extern-constexpr.cpp
>> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCX
>> X/cxx11-extern-constexpr.cpp?rev=311857=auto
>> > 
>> ==
>> > --- cfe/trunk/test/CodeGenCXX/cxx11-extern-constexpr.cpp (added)
>> > +++ cfe/trunk/test/CodeGenCXX/cxx11-extern-constexpr.cpp Sun Aug 27
>> 13:24:09 2017
>> > @@ -0,0 +1,55 @@
>> > +// RUN: %clang_cc1 -std=c++11 %s -emit-llvm -o - -triple
>> x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK --check-prefix=CXX11
>> > +// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple
>> x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK --check-prefix=CXX17
>> > +
>> > +struct A {
>> > +  static const int Foo = 123;
>> > +};
>> > +// CHECK: @_ZN1A3FooE = constant i32 123, align 4
>> > +const int *p = ::Foo; // emit available_externally
>> > +const int A::Foo;   // convert to full definition
>> > +
>> > +struct Bar {
>> > +  int b;
>> > +};
>> > +
>> > +struct MutableBar {
>> > +  mutable int b;
>> > +};
>> > +
>> > +struct Foo {
>> > +  // CXX11: @_ZN3Foo21ConstexprStaticMemberE = available_externally
>> constant i32 42,
>> > +  // CXX17: @_ZN3Foo21ConstexprStaticMemberE = linkonce_odr constant
>> i32 42,
>> > +  static constexpr int ConstexprStaticMember = 42;
>> > +  // CHECK: @_ZN3Foo17ConstStaticMemberE = available_externally
>> constant i32 43,
>> > +  static const int ConstStaticMember = 43;
>> > +
>> > +  // CXX11: @_ZN3Foo23ConstStaticStructMemberE = available_externally
>> constant %struct.Bar { i32 44 },
>> > +  // CXX17: @_ZN3Foo23ConstStaticStructMemberE = linkonce_odr
>> constant %struct.Bar { i32 44 },
>> > +  static constexpr Bar ConstStaticStructMember = {44};
>> > +
>> > +  // CXX11: @_ZN3Foo34ConstexprStaticMutableStructMemberE = external
>> global %struct.MutableBar,
>> > +  // CXX17: @_ZN3Foo34ConstexprStaticMutableStructMemberE =
>> linkonce_odr global %struct.MutableBar { i32 45 },
>> > +  static constexpr 

Re: r311857 - Emit static constexpr member as available_externally definition

2017-08-28 Thread Mehdi AMINI via cfe-commits
Sorry for the inconvenience!

I will follow-up in the PR.

-- 
Mehdi


2017-08-28 12:42 GMT-07:00 Hans Wennborg :

> I reverted this in r311898 as it caused Chromium builds to fail with
> an assertion; see PR34348.
>
> On Sun, Aug 27, 2017 at 1:24 PM, Mehdi Amini via cfe-commits
>  wrote:
> > Author: mehdi_amini
> > Date: Sun Aug 27 13:24:09 2017
> > New Revision: 311857
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=311857=rev
> > Log:
> > Emit static constexpr member as available_externally definition
> >
> > By exposing the constant initializer, the optimizer can fold many
> > of these constructs.
> >
> > Differential Revision: https://reviews.llvm.org/D34992
> >
> > Added:
> > cfe/trunk/test/CodeGenCXX/cxx11-extern-constexpr.cpp
> > Modified:
> > cfe/trunk/lib/CodeGen/CodeGenModule.cpp
> >
> > Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/
> CodeGenModule.cpp?rev=311857=311856=311857=diff
> > 
> ==
> > --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
> > +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Sun Aug 27 13:24:09 2017
> > @@ -2437,6 +2437,28 @@ CodeGenModule::GetOrCreateLLVMGlobal(Str
> >  D->getType().isConstant(Context) &&
> >  isExternallyVisible(D->getLinkageAndVisibility().getLinkage()))
> >GV->setSection(".cp.rodata");
> > +
> > +// Check if we a have a const declaration with an initializer, we
> may be
> > +// able to emit it as available_externally to expose it's value to
> the
> > +// optimizer.
> > +if (Context.getLangOpts().CPlusPlus && GV->hasExternalLinkage() &&
> > +D->getType().isConstQualified() && !GV->hasInitializer() &&
> > +!D->hasDefinition() && D->hasInit() &&
> !D->hasAttr()) {
> > +  const auto *Record =
> > +  Context.getBaseElementType(D->getType())->
> getAsCXXRecordDecl();
> > +  bool HasMutableFields = Record && Record->hasMutableFields();
> > +  if (!HasMutableFields) {
> > +const VarDecl *InitDecl;
> > +const Expr *InitExpr = D->getAnyInitializer(InitDecl);
> > +if (InitExpr) {
> > +  GV->setConstant(true);
> > +  GV->setLinkage(llvm::GlobalValue::
> AvailableExternallyLinkage);
> > +  ConstantEmitter emitter(*this);
> > +  GV->setInitializer(emitter.tryEmitForInitializer(*InitDecl));
> > +  emitter.finalize(GV);
> > +}
> > +  }
> > +}
> >}
> >
> >auto ExpectedAS =
> >
> > Added: cfe/trunk/test/CodeGenCXX/cxx11-extern-constexpr.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/
> CodeGenCXX/cxx11-extern-constexpr.cpp?rev=311857=auto
> > 
> ==
> > --- cfe/trunk/test/CodeGenCXX/cxx11-extern-constexpr.cpp (added)
> > +++ cfe/trunk/test/CodeGenCXX/cxx11-extern-constexpr.cpp Sun Aug 27
> 13:24:09 2017
> > @@ -0,0 +1,55 @@
> > +// RUN: %clang_cc1 -std=c++11 %s -emit-llvm -o - -triple
> x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK --check-prefix=CXX11
> > +// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple
> x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK --check-prefix=CXX17
> > +
> > +struct A {
> > +  static const int Foo = 123;
> > +};
> > +// CHECK: @_ZN1A3FooE = constant i32 123, align 4
> > +const int *p = ::Foo; // emit available_externally
> > +const int A::Foo;   // convert to full definition
> > +
> > +struct Bar {
> > +  int b;
> > +};
> > +
> > +struct MutableBar {
> > +  mutable int b;
> > +};
> > +
> > +struct Foo {
> > +  // CXX11: @_ZN3Foo21ConstexprStaticMemberE = available_externally
> constant i32 42,
> > +  // CXX17: @_ZN3Foo21ConstexprStaticMemberE = linkonce_odr constant
> i32 42,
> > +  static constexpr int ConstexprStaticMember = 42;
> > +  // CHECK: @_ZN3Foo17ConstStaticMemberE = available_externally
> constant i32 43,
> > +  static const int ConstStaticMember = 43;
> > +
> > +  // CXX11: @_ZN3Foo23ConstStaticStructMemberE = available_externally
> constant %struct.Bar { i32 44 },
> > +  // CXX17: @_ZN3Foo23ConstStaticStructMemberE = linkonce_odr constant
> %struct.Bar { i32 44 },
> > +  static constexpr Bar ConstStaticStructMember = {44};
> > +
> > +  // CXX11: @_ZN3Foo34ConstexprStaticMutableStructMemberE = external
> global %struct.MutableBar,
> > +  // CXX17: @_ZN3Foo34ConstexprStaticMutableStructMemberE =
> linkonce_odr global %struct.MutableBar { i32 45 },
> > +  static constexpr MutableBar ConstexprStaticMutableStructMember =
> {45};
> > +};
> > +// CHECK: @_ZL15ConstStaticexpr = internal constant i32 46,
> > +static constexpr int ConstStaticexpr = 46;
> > +// CHECK: @_ZL9ConstExpr = internal constant i32 46, align 4
> > +static const int ConstExpr = 46;
> > +
> > +// CHECK: @_ZL21ConstexprStaticStruct = internal constant %struct.Bar {
> i32 47 },
> > +static 

Re: r311857 - Emit static constexpr member as available_externally definition

2017-08-28 Thread Hans Wennborg via cfe-commits
I reverted this in r311898 as it caused Chromium builds to fail with
an assertion; see PR34348.

On Sun, Aug 27, 2017 at 1:24 PM, Mehdi Amini via cfe-commits
 wrote:
> Author: mehdi_amini
> Date: Sun Aug 27 13:24:09 2017
> New Revision: 311857
>
> URL: http://llvm.org/viewvc/llvm-project?rev=311857=rev
> Log:
> Emit static constexpr member as available_externally definition
>
> By exposing the constant initializer, the optimizer can fold many
> of these constructs.
>
> Differential Revision: https://reviews.llvm.org/D34992
>
> Added:
> cfe/trunk/test/CodeGenCXX/cxx11-extern-constexpr.cpp
> Modified:
> cfe/trunk/lib/CodeGen/CodeGenModule.cpp
>
> Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=311857=311856=311857=diff
> ==
> --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Sun Aug 27 13:24:09 2017
> @@ -2437,6 +2437,28 @@ CodeGenModule::GetOrCreateLLVMGlobal(Str
>  D->getType().isConstant(Context) &&
>  isExternallyVisible(D->getLinkageAndVisibility().getLinkage()))
>GV->setSection(".cp.rodata");
> +
> +// Check if we a have a const declaration with an initializer, we may be
> +// able to emit it as available_externally to expose it's value to the
> +// optimizer.
> +if (Context.getLangOpts().CPlusPlus && GV->hasExternalLinkage() &&
> +D->getType().isConstQualified() && !GV->hasInitializer() &&
> +!D->hasDefinition() && D->hasInit() && !D->hasAttr()) 
> {
> +  const auto *Record =
> +  Context.getBaseElementType(D->getType())->getAsCXXRecordDecl();
> +  bool HasMutableFields = Record && Record->hasMutableFields();
> +  if (!HasMutableFields) {
> +const VarDecl *InitDecl;
> +const Expr *InitExpr = D->getAnyInitializer(InitDecl);
> +if (InitExpr) {
> +  GV->setConstant(true);
> +  GV->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage);
> +  ConstantEmitter emitter(*this);
> +  GV->setInitializer(emitter.tryEmitForInitializer(*InitDecl));
> +  emitter.finalize(GV);
> +}
> +  }
> +}
>}
>
>auto ExpectedAS =
>
> Added: cfe/trunk/test/CodeGenCXX/cxx11-extern-constexpr.cpp
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx11-extern-constexpr.cpp?rev=311857=auto
> ==
> --- cfe/trunk/test/CodeGenCXX/cxx11-extern-constexpr.cpp (added)
> +++ cfe/trunk/test/CodeGenCXX/cxx11-extern-constexpr.cpp Sun Aug 27 13:24:09 
> 2017
> @@ -0,0 +1,55 @@
> +// RUN: %clang_cc1 -std=c++11 %s -emit-llvm -o - -triple x86_64-linux-gnu | 
> FileCheck %s --check-prefix=CHECK --check-prefix=CXX11
> +// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple x86_64-linux-gnu | 
> FileCheck %s --check-prefix=CHECK --check-prefix=CXX17
> +
> +struct A {
> +  static const int Foo = 123;
> +};
> +// CHECK: @_ZN1A3FooE = constant i32 123, align 4
> +const int *p = ::Foo; // emit available_externally
> +const int A::Foo;   // convert to full definition
> +
> +struct Bar {
> +  int b;
> +};
> +
> +struct MutableBar {
> +  mutable int b;
> +};
> +
> +struct Foo {
> +  // CXX11: @_ZN3Foo21ConstexprStaticMemberE = available_externally constant 
> i32 42,
> +  // CXX17: @_ZN3Foo21ConstexprStaticMemberE = linkonce_odr constant i32 42,
> +  static constexpr int ConstexprStaticMember = 42;
> +  // CHECK: @_ZN3Foo17ConstStaticMemberE = available_externally constant i32 
> 43,
> +  static const int ConstStaticMember = 43;
> +
> +  // CXX11: @_ZN3Foo23ConstStaticStructMemberE = available_externally 
> constant %struct.Bar { i32 44 },
> +  // CXX17: @_ZN3Foo23ConstStaticStructMemberE = linkonce_odr constant 
> %struct.Bar { i32 44 },
> +  static constexpr Bar ConstStaticStructMember = {44};
> +
> +  // CXX11: @_ZN3Foo34ConstexprStaticMutableStructMemberE = external global 
> %struct.MutableBar,
> +  // CXX17: @_ZN3Foo34ConstexprStaticMutableStructMemberE = linkonce_odr 
> global %struct.MutableBar { i32 45 },
> +  static constexpr MutableBar ConstexprStaticMutableStructMember = {45};
> +};
> +// CHECK: @_ZL15ConstStaticexpr = internal constant i32 46,
> +static constexpr int ConstStaticexpr = 46;
> +// CHECK: @_ZL9ConstExpr = internal constant i32 46, align 4
> +static const int ConstExpr = 46;
> +
> +// CHECK: @_ZL21ConstexprStaticStruct = internal constant %struct.Bar { i32 
> 47 },
> +static constexpr Bar ConstexprStaticStruct = {47};
> +
> +// CHECK: @_ZL28ConstexprStaticMutableStruct = internal global 
> %struct.MutableBar { i32 48 },
> +static constexpr MutableBar ConstexprStaticMutableStruct = {48};
> +
> +void use(const int &);
> +void foo() {
> +  use(Foo::ConstexprStaticMember);
> +  use(Foo::ConstStaticMember);
> +  

r311898 - Revert r311857 "Emit static constexpr member as available_externally definition"

2017-08-28 Thread Hans Wennborg via cfe-commits
Author: hans
Date: Mon Aug 28 10:53:00 2017
New Revision: 311898

URL: http://llvm.org/viewvc/llvm-project?rev=311898=rev
Log:
Revert r311857 "Emit static constexpr member as available_externally definition"

It caused PR759744.

> Emit static constexpr member as available_externally definition
>
> By exposing the constant initializer, the optimizer can fold many
> of these constructs.
>
> Differential Revision: https://reviews.llvm.org/D34992

Removed:
cfe/trunk/test/CodeGenCXX/cxx11-extern-constexpr.cpp
Modified:
cfe/trunk/lib/CodeGen/CodeGenModule.cpp

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=311898=311897=311898=diff
==
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Mon Aug 28 10:53:00 2017
@@ -2437,28 +2437,6 @@ CodeGenModule::GetOrCreateLLVMGlobal(Str
 D->getType().isConstant(Context) &&
 isExternallyVisible(D->getLinkageAndVisibility().getLinkage()))
   GV->setSection(".cp.rodata");
-
-// Check if we a have a const declaration with an initializer, we may be
-// able to emit it as available_externally to expose it's value to the
-// optimizer.
-if (Context.getLangOpts().CPlusPlus && GV->hasExternalLinkage() &&
-D->getType().isConstQualified() && !GV->hasInitializer() &&
-!D->hasDefinition() && D->hasInit() && !D->hasAttr()) {
-  const auto *Record =
-  Context.getBaseElementType(D->getType())->getAsCXXRecordDecl();
-  bool HasMutableFields = Record && Record->hasMutableFields();
-  if (!HasMutableFields) {
-const VarDecl *InitDecl;
-const Expr *InitExpr = D->getAnyInitializer(InitDecl);
-if (InitExpr) {
-  GV->setConstant(true);
-  GV->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage);
-  ConstantEmitter emitter(*this);
-  GV->setInitializer(emitter.tryEmitForInitializer(*InitDecl));
-  emitter.finalize(GV);
-}
-  }
-}
   }
 
   auto ExpectedAS =

Removed: cfe/trunk/test/CodeGenCXX/cxx11-extern-constexpr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx11-extern-constexpr.cpp?rev=311897=auto
==
--- cfe/trunk/test/CodeGenCXX/cxx11-extern-constexpr.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/cxx11-extern-constexpr.cpp (removed)
@@ -1,55 +0,0 @@
-// RUN: %clang_cc1 -std=c++11 %s -emit-llvm -o - -triple x86_64-linux-gnu | 
FileCheck %s --check-prefix=CHECK --check-prefix=CXX11
-// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple x86_64-linux-gnu | 
FileCheck %s --check-prefix=CHECK --check-prefix=CXX17
-
-struct A {
-  static const int Foo = 123;
-};
-// CHECK: @_ZN1A3FooE = constant i32 123, align 4
-const int *p = ::Foo; // emit available_externally
-const int A::Foo;   // convert to full definition
-
-struct Bar {
-  int b;
-};
-
-struct MutableBar {
-  mutable int b;
-};
-
-struct Foo {
-  // CXX11: @_ZN3Foo21ConstexprStaticMemberE = available_externally constant 
i32 42,
-  // CXX17: @_ZN3Foo21ConstexprStaticMemberE = linkonce_odr constant i32 42,
-  static constexpr int ConstexprStaticMember = 42;
-  // CHECK: @_ZN3Foo17ConstStaticMemberE = available_externally constant i32 
43,
-  static const int ConstStaticMember = 43;
-
-  // CXX11: @_ZN3Foo23ConstStaticStructMemberE = available_externally constant 
%struct.Bar { i32 44 },
-  // CXX17: @_ZN3Foo23ConstStaticStructMemberE = linkonce_odr constant 
%struct.Bar { i32 44 },
-  static constexpr Bar ConstStaticStructMember = {44};
-
-  // CXX11: @_ZN3Foo34ConstexprStaticMutableStructMemberE = external global 
%struct.MutableBar,
-  // CXX17: @_ZN3Foo34ConstexprStaticMutableStructMemberE = linkonce_odr 
global %struct.MutableBar { i32 45 },
-  static constexpr MutableBar ConstexprStaticMutableStructMember = {45};
-};
-// CHECK: @_ZL15ConstStaticexpr = internal constant i32 46,
-static constexpr int ConstStaticexpr = 46;
-// CHECK: @_ZL9ConstExpr = internal constant i32 46, align 4
-static const int ConstExpr = 46;
-
-// CHECK: @_ZL21ConstexprStaticStruct = internal constant %struct.Bar { i32 47 
},
-static constexpr Bar ConstexprStaticStruct = {47};
-
-// CHECK: @_ZL28ConstexprStaticMutableStruct = internal global 
%struct.MutableBar { i32 48 },
-static constexpr MutableBar ConstexprStaticMutableStruct = {48};
-
-void use(const int &);
-void foo() {
-  use(Foo::ConstexprStaticMember);
-  use(Foo::ConstStaticMember);
-  use(Foo::ConstStaticStructMember.b);
-  use(Foo::ConstexprStaticMutableStructMember.b);
-  use(ConstStaticexpr);
-  use(ConstExpr);
-  use(ConstexprStaticStruct.b);
-  use(ConstexprStat

r311857 - Emit static constexpr member as available_externally definition

2017-08-27 Thread Mehdi Amini via cfe-commits
Author: mehdi_amini
Date: Sun Aug 27 13:24:09 2017
New Revision: 311857

URL: http://llvm.org/viewvc/llvm-project?rev=311857=rev
Log:
Emit static constexpr member as available_externally definition

By exposing the constant initializer, the optimizer can fold many
of these constructs.

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

Added:
cfe/trunk/test/CodeGenCXX/cxx11-extern-constexpr.cpp
Modified:
cfe/trunk/lib/CodeGen/CodeGenModule.cpp

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=311857=311856=311857=diff
==
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Sun Aug 27 13:24:09 2017
@@ -2437,6 +2437,28 @@ CodeGenModule::GetOrCreateLLVMGlobal(Str
 D->getType().isConstant(Context) &&
 isExternallyVisible(D->getLinkageAndVisibility().getLinkage()))
   GV->setSection(".cp.rodata");
+
+// Check if we a have a const declaration with an initializer, we may be
+// able to emit it as available_externally to expose it's value to the
+// optimizer.
+if (Context.getLangOpts().CPlusPlus && GV->hasExternalLinkage() &&
+D->getType().isConstQualified() && !GV->hasInitializer() &&
+!D->hasDefinition() && D->hasInit() && !D->hasAttr()) {
+  const auto *Record =
+  Context.getBaseElementType(D->getType())->getAsCXXRecordDecl();
+  bool HasMutableFields = Record && Record->hasMutableFields();
+  if (!HasMutableFields) {
+const VarDecl *InitDecl;
+const Expr *InitExpr = D->getAnyInitializer(InitDecl);
+if (InitExpr) {
+  GV->setConstant(true);
+  GV->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage);
+  ConstantEmitter emitter(*this);
+  GV->setInitializer(emitter.tryEmitForInitializer(*InitDecl));
+  emitter.finalize(GV);
+}
+  }
+}
   }
 
   auto ExpectedAS =

Added: cfe/trunk/test/CodeGenCXX/cxx11-extern-constexpr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx11-extern-constexpr.cpp?rev=311857=auto
==
--- cfe/trunk/test/CodeGenCXX/cxx11-extern-constexpr.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/cxx11-extern-constexpr.cpp Sun Aug 27 13:24:09 
2017
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -std=c++11 %s -emit-llvm -o - -triple x86_64-linux-gnu | 
FileCheck %s --check-prefix=CHECK --check-prefix=CXX11
+// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple x86_64-linux-gnu | 
FileCheck %s --check-prefix=CHECK --check-prefix=CXX17
+
+struct A {
+  static const int Foo = 123;
+};
+// CHECK: @_ZN1A3FooE = constant i32 123, align 4
+const int *p = ::Foo; // emit available_externally
+const int A::Foo;   // convert to full definition
+
+struct Bar {
+  int b;
+};
+
+struct MutableBar {
+  mutable int b;
+};
+
+struct Foo {
+  // CXX11: @_ZN3Foo21ConstexprStaticMemberE = available_externally constant 
i32 42,
+  // CXX17: @_ZN3Foo21ConstexprStaticMemberE = linkonce_odr constant i32 42,
+  static constexpr int ConstexprStaticMember = 42;
+  // CHECK: @_ZN3Foo17ConstStaticMemberE = available_externally constant i32 
43,
+  static const int ConstStaticMember = 43;
+
+  // CXX11: @_ZN3Foo23ConstStaticStructMemberE = available_externally constant 
%struct.Bar { i32 44 },
+  // CXX17: @_ZN3Foo23ConstStaticStructMemberE = linkonce_odr constant 
%struct.Bar { i32 44 },
+  static constexpr Bar ConstStaticStructMember = {44};
+
+  // CXX11: @_ZN3Foo34ConstexprStaticMutableStructMemberE = external global 
%struct.MutableBar,
+  // CXX17: @_ZN3Foo34ConstexprStaticMutableStructMemberE = linkonce_odr 
global %struct.MutableBar { i32 45 },
+  static constexpr MutableBar ConstexprStaticMutableStructMember = {45};
+};
+// CHECK: @_ZL15ConstStaticexpr = internal constant i32 46,
+static constexpr int ConstStaticexpr = 46;
+// CHECK: @_ZL9ConstExpr = internal constant i32 46, align 4
+static const int ConstExpr = 46;
+
+// CHECK: @_ZL21ConstexprStaticStruct = internal constant %struct.Bar { i32 47 
},
+static constexpr Bar ConstexprStaticStruct = {47};
+
+// CHECK: @_ZL28ConstexprStaticMutableStruct = internal global 
%struct.MutableBar { i32 48 },
+static constexpr MutableBar ConstexprStaticMutableStruct = {48};
+
+void use(const int &);
+void foo() {
+  use(Foo::ConstexprStaticMember);
+  use(Foo::ConstStaticMember);
+  use(Foo::ConstStaticStructMember.b);
+  use(Foo::ConstexprStaticMutableStructMember.b);
+  use(ConstStaticexpr);
+  use(ConstExpr);
+  use(ConstexprStaticStruct.b);
+  use(ConstexprStaticMutableStruct.b);
+}


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits