Author: rsmith Date: Thu Jul 19 14:38:56 2018 New Revision: 337498 URL: http://llvm.org/viewvc/llvm-project?rev=337498&view=rev Log: 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. Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp cfe/trunk/test/CodeGen/init.c Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=337498&r1=337497&r2=337498&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Thu Jul 19 14:38:56 2018 @@ -659,7 +659,19 @@ EmitArrayConstant(CodeGenModule &CGM, co 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 Modified: cfe/trunk/test/CodeGen/init.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/init.c?rev=337498&r1=337497&r2=337498&view=diff ============================================================================== --- cfe/trunk/test/CodeGen/init.c (original) +++ cfe/trunk/test/CodeGen/init.c Thu Jul 19 14:38:56 2018 @@ -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) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits