summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2018-07-19 21:38:56 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2018-07-19 21:38:56 +0000
commit83497d9eadd04a0ee57e4858a8f3b7b3cb99a22b (patch)
treee42ee23d708d2dea9a8e2d1b08c314fa927930a4
parent0b75dc5fa2e0552e7c9f3250e3487cf73dacd32b (diff)
downloadbcm5719-llvm-83497d9eadd04a0ee57e4858a8f3b7b3cb99a22b.tar.gz
bcm5719-llvm-83497d9eadd04a0ee57e4858a8f3b7b3cb99a22b.zip
When we choose to use zeroinitializer for a trailing portion of an array
constant, don't convert the rest into a packed struct. If an array constant has a large non-zero portion and a large zero portion, we want to emit the first part as an array and the rest as a zeroinitializer if possible. This fixes a memory usage regression from r333141 when compiling PHP. llvm-svn: 337498
-rw-r--r--clang/lib/CodeGen/CGExprConstant.cpp14
-rw-r--r--clang/test/CodeGen/init.c4
2 files changed, 17 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
index b26ff3d20e4..afe2bfe8e9b 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -659,7 +659,19 @@ EmitArrayConstant(CodeGenModule &CGM, const ConstantArrayType *DestType,
if (TrailingZeroes >= 8) {
assert(Elements.size() >= NonzeroLength &&
"missing initializer for non-zero element");
- Elements.resize(NonzeroLength + 1);
+
+ // If all the elements had the same type up to the trailing zeroes, emit a
+ // struct of two arrays (the nonzero data and the zeroinitializer).
+ if (CommonElementType && NonzeroLength >= 8) {
+ llvm::Constant *Initial = llvm::ConstantArray::get(
+ llvm::ArrayType::get(CommonElementType, ArrayBound),
+ makeArrayRef(Elements).take_front(NonzeroLength));
+ Elements.resize(2);
+ Elements[0] = Initial;
+ } else {
+ Elements.resize(NonzeroLength + 1);
+ }
+
auto *FillerType =
CommonElementType
? CommonElementType
diff --git a/clang/test/CodeGen/init.c b/clang/test/CodeGen/init.c
index b5396810103..770995f93f3 100644
--- a/clang/test/CodeGen/init.c
+++ b/clang/test/CodeGen/init.c
@@ -81,6 +81,10 @@ struct Huge {
int arr[1000 * 1000 * 1000];
} huge_struct = {1, {2, 0, 0, 0}};
+// CHECK-DAG: @large_array_with_zeroes = constant <{ [21 x i8], [979 x i8] }> <{ [21 x i8] c"abc\01\02\03xyzzy\00\00\00\00\00\00\00\00\00q", [979 x i8] zeroinitializer }>
+const char large_array_with_zeroes[1000] = {
+ 'a', 'b', 'c', 1, 2, 3, 'x', 'y', 'z', 'z', 'y', [20] = 'q'
+};
// PR279 comment #3
char test8(int X) {
OpenPOWER on IntegriCloud