Update comment

http://reviews.llvm.org/D8034

Files:
  lib/CodeGen/CGExpr.cpp
  test/CodeGenCXX/compound-literals.cpp
  test/CodeGenCXX/cxx0x-initializer-array.cpp
  test/CodeGenCXX/cxx0x-initializer-references.cpp
  test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
Index: lib/CodeGen/CGExpr.cpp
===================================================================
--- lib/CodeGen/CGExpr.cpp
+++ lib/CodeGen/CGExpr.cpp
@@ -301,6 +301,23 @@
   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, ".reftmp");
+        GV->setAlignment(
+            CGF.getContext().getTypeAlignInChars(M->getType()).getQuantity());
+        GV->setComdat(CGF.CurFn->getComdat());
+        return GV;
+      }
     return CGF.CreateMemTemp(Inner->getType(), "ref.tmp");
 
   case SD_Thread:
@@ -370,8 +387,9 @@
   // 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);
Index: test/CodeGenCXX/compound-literals.cpp
===================================================================
--- test/CodeGenCXX/compound-literals.cpp
+++ test/CodeGenCXX/compound-literals.cpp
@@ -28,7 +28,7 @@
 
 // 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]* @.reftmp, [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]]
Index: test/CodeGenCXX/cxx0x-initializer-array.cpp
===================================================================
--- test/CodeGenCXX/cxx0x-initializer-array.cpp
+++ test/CodeGenCXX/cxx0x-initializer-array.cpp
@@ -44,7 +44,7 @@
 
   // CHECK-LABEL: define void @_ZN22ValueInitArrayOfMemPtr1gEv
   void g() {
-    // CHECK: store i32 -1,
+    // CHECK: call void @_ZN22ValueInitArrayOfMemPtr1fERA3_KMNS_1SEi([3 x i32]* dereferenceable(12) @.reftmp)
     f(a{});
   }
 }
Index: test/CodeGenCXX/cxx0x-initializer-references.cpp
===================================================================
--- test/CodeGenCXX/cxx0x-initializer-references.cpp
+++ test/CodeGenCXX/cxx0x-initializer-references.cpp
@@ -36,20 +36,10 @@
   }
 
   void reference_to_aggregate() {
-    // 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: store %{{.*}}* %{{.*}}, %{{.*}}** %{{.*}}, align
+    // CHECK: store %"struct.reference::A"* @.reftmp, %"struct.reference::A"** %{{.*}}, align
     const A &ra1{1, 2};
 
-    // 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: store [3 x i32]* %{{.*}}, [3 x i32]** %{{.*}}, align
+    // CHECK-NEXT: store [3 x i32]* @.reftmp1, [3 x i32]** %{{.*}}, align
     const int (&arrayRef)[] = {1, 2, 3};
 
     // CHECK-NEXT: ret
Index: test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
===================================================================
--- test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
+++ test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
@@ -64,14 +64,20 @@
 // CHECK: @globalInitList2 = global %{{[^ ]+}} zeroinitializer
 // CHECK: @_ZGR15globalInitList2_ = internal global [2 x %[[WITHARG:[^ ]*]]] zeroinitializer
 
+// CHECK: @.reftmp = private constant [3 x i32] [i32 1, i32 2, i32 3], align 4
+// CHECK: @.reftmp2 = private constant [3 x i32] [i32 1, i32 2, i32 3], align 4
+
 // CHECK: @_ZN15partly_constant1kE = global i32 0, align 4
 // CHECK: @_ZN15partly_constant2ilE = global {{.*}} null, align 8
 // CHECK: @[[PARTLY_CONSTANT_OUTER:_ZGRN15partly_constant2ilE.*]] = internal global {{.*}} zeroinitializer, align 8
 // CHECK: @[[PARTLY_CONSTANT_INNER:_ZGRN15partly_constant2ilE.*]] = internal global [3 x {{.*}}] zeroinitializer, align 8
 // CHECK: @[[PARTLY_CONSTANT_FIRST:_ZGRN15partly_constant2ilE.*]] = internal constant [3 x i32] [i32 1, i32 2, i32 3], align 4
 // 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: @.reftmp8 = private constant [2 x i32] [i32 42, i32 43], comdat($_ZN7PR204451fILi0EEEvv), align 4
+// CHECK: @.reftmp9 = private constant [3 x %"class.ConstExpr::C"] [%"class.ConstExpr::C" { i32 1 }, %"class.ConstExpr::C" { i32 2 }, %"class.ConstExpr::C" { i32 3 }], align 4
+
 // CHECK: appending global
 
 
@@ -220,10 +226,8 @@
 
 // CHECK-LABEL: define void @_ZN8haslist1C2Ev
 haslist1::haslist1()
-// CHECK: alloca [3 x i32]
-// CHECK: store i32 1
-// CHECK: store i32 2
-// CHECK: store i32 3
+// CHECK-NOT: alloca [3 x i32]
+// CHECK: store i32* getelementptr inbounds ([3 x i32]* @.reftmp, i64 0, i64 0)
 // CHECK: store i{{32|64}} 3
   : il{1, 2, 3}
 {
@@ -246,12 +250,8 @@
 
 void fn10() {
   // CHECK-LABEL: define void @_Z4fn10v
-  // CHECK: alloca [3 x i32]
   // CHECK: call noalias i8* @_Znw{{[jm]}}
-  // CHECK: store i32 1
-  // CHECK: store i32 2
-  // CHECK: store i32 3
-  // CHECK: store i32*
+  // CHECK: store i32* getelementptr inbounds ([3 x i32]* @.reftmp2, i64 0, i64 0)
   // CHECK: store i{{32|64}} 3
   (void) new std::initializer_list<int> {1, 2, 3};
 }
@@ -462,6 +462,22 @@
   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]* @.reftmp8, 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"]* @.reftmp9, i64 0, i64 0)
+// CHECK: call void @_ZN9ConstExpr1fESt16initializer_listINS_1CEE
+    f({C(1), C(2), C(3)});
+  }
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to