diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-07-19 21:38:56 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-07-19 21:38:56 +0000 |
commit | 83497d9eadd04a0ee57e4858a8f3b7b3cb99a22b (patch) | |
tree | e42ee23d708d2dea9a8e2d1b08c314fa927930a4 /clang/lib/CodeGen | |
parent | 0b75dc5fa2e0552e7c9f3250e3487cf73dacd32b (diff) | |
download | bcm5719-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
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGExprConstant.cpp | 14 |
1 files changed, 13 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 |