mehdi_amini created this revision.

This enables better optimization, I don't if it is legal c++11 though.


https://reviews.llvm.org/D34992

Files:
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/test/CodeGenCXX/cxx11-extern-constexpr.cpp


Index: clang/test/CodeGenCXX/cxx11-extern-constexpr.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/cxx11-extern-constexpr.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -std=c++11 %s -emit-llvm -o - -triple x86_64-linux-gnu | 
FileCheck %s
+
+template<typename T>
+int min(const T &a, const T &b) {
+       return a > b ? b : a;
+}
+
+struct Foo {
+// CHECK: @_ZN3Foo3BARE = available_externally constant i32 42,
+  static constexpr int BAR = 42; 
+// CHECK: @_ZN3Foo4BAR2E = external constant i32,
+  static const int BAR2 = 43; 
+};
+// CHECK: @_ZL4BAR3 = available_externally constant i32 44,
+static constexpr int BAR3 = 44;
+
+int foo(int v) {
+       return min(min(Foo::BAR, Foo::BAR2), BAR3);
+}
+
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -2368,11 +2368,22 @@
       return llvm::ConstantExpr::getBitCast(Entry, Ty);
   }
 
+  auto Linkage = llvm::GlobalValue::ExternalLinkage;
+
+  llvm::Constant *Init = nullptr;
+  if (D && D->isConstexpr() && !D->isInline() && !D->hasAttr<DLLImportAttr>()) 
{
+    const VarDecl *InitDecl;
+    const Expr *InitExpr = D->getAnyInitializer(InitDecl);
+    if (InitExpr) {
+      Init = EmitConstantInit(*InitDecl);
+      Linkage = llvm::GlobalValue::AvailableExternallyLinkage;
+    }
+  }
+
   unsigned AddrSpace = GetGlobalVarAddressSpace(D, Ty->getAddressSpace());
   auto *GV = new llvm::GlobalVariable(
-      getModule(), Ty->getElementType(), false,
-      llvm::GlobalValue::ExternalLinkage, nullptr, MangledName, nullptr,
-      llvm::GlobalVariable::NotThreadLocal, AddrSpace);
+      getModule(), Ty->getElementType(), false, Linkage, Init, MangledName,
+      nullptr, llvm::GlobalVariable::NotThreadLocal, AddrSpace);
 
   // If we already created a global with the same mangled name (but different
   // type) before, take its name and remove it from its parent.


Index: clang/test/CodeGenCXX/cxx11-extern-constexpr.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/cxx11-extern-constexpr.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -std=c++11 %s -emit-llvm -o - -triple x86_64-linux-gnu | FileCheck %s
+
+template<typename T>
+int min(const T &a, const T &b) {
+	return a > b ? b : a;
+}
+
+struct Foo {
+// CHECK: @_ZN3Foo3BARE = available_externally constant i32 42,
+  static constexpr int BAR = 42; 
+// CHECK: @_ZN3Foo4BAR2E = external constant i32,
+  static const int BAR2 = 43; 
+};
+// CHECK: @_ZL4BAR3 = available_externally constant i32 44,
+static constexpr int BAR3 = 44;
+
+int foo(int v) {
+	return min(min(Foo::BAR, Foo::BAR2), BAR3);
+}
+
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -2368,11 +2368,22 @@
       return llvm::ConstantExpr::getBitCast(Entry, Ty);
   }
 
+  auto Linkage = llvm::GlobalValue::ExternalLinkage;
+
+  llvm::Constant *Init = nullptr;
+  if (D && D->isConstexpr() && !D->isInline() && !D->hasAttr<DLLImportAttr>()) {
+    const VarDecl *InitDecl;
+    const Expr *InitExpr = D->getAnyInitializer(InitDecl);
+    if (InitExpr) {
+      Init = EmitConstantInit(*InitDecl);
+      Linkage = llvm::GlobalValue::AvailableExternallyLinkage;
+    }
+  }
+
   unsigned AddrSpace = GetGlobalVarAddressSpace(D, Ty->getAddressSpace());
   auto *GV = new llvm::GlobalVariable(
-      getModule(), Ty->getElementType(), false,
-      llvm::GlobalValue::ExternalLinkage, nullptr, MangledName, nullptr,
-      llvm::GlobalVariable::NotThreadLocal, AddrSpace);
+      getModule(), Ty->getElementType(), false, Linkage, Init, MangledName,
+      nullptr, llvm::GlobalVariable::NotThreadLocal, AddrSpace);
 
   // If we already created a global with the same mangled name (but different
   // type) before, take its name and remove it from its parent.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to