summaryrefslogtreecommitdiffstats
path: root/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
diff options
context:
space:
mode:
authorBenjamin Kramer <benny.kra@googlemail.com>2015-03-06 20:00:03 +0000
committerBenjamin Kramer <benny.kra@googlemail.com>2015-03-06 20:00:03 +0000
commitfe85506967c38cad114ef2014c363b7b14ca81c8 (patch)
treec48a17ac7ba2a07248b755f7ecd77f1a6ed5652d /test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
parentf6ddf1b4f9cc7b2a5016d46fd6d0d2726946988c (diff)
CodeGen: Emit constant temporaries into read-only globals.
Instead of creating a copy on the stack just stash them in a private constant global. This saves both the copying overhead and the stack space, and gives the optimizer more room to constant fold. This tries to make array temporaries more similar to regular arrays, they can't use the same logic because a temporary has no VarDecl to be bound to so we roll our own version here. The original use case for this optimization was code like for (int i : {1, 2, 3, 4, 5, 6, 7, 8, 10}) foo(i); where without this patch (assuming that the loop is not unrolled) we would alloca an array on the stack, copy the 10 values over and iterate on that. With this patch we put the array in .text use it directly. Apart from that case this helps on virtually any passing of a constant std::initializer_list as a function argument. Differential Revision: http://reviews.llvm.org/D8034 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@231508 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp')
-rw-r--r--test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp39
1 files changed, 28 insertions, 11 deletions
diff --git a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
index d68ba7c753..f079311e7e 100644
--- a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
+++ b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
@@ -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], comdat($_ZN7PR204451fILi0EEEvv), 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)});
+ }
+}