forked from OSchip/llvm-project
[CodeGen] Use the zero initializer instead of storing an all zero representation.
Summary: This change avoids the overhead of storing, and later crawling, an initializer list of all zeros for arrays. When LLVM visits this (llvm/IR/Constants.cpp) ConstantArray::getImpl() it will scan the list looking for an array of all zero. We can avoid the store, and short-cut the scan, by detecting all zeros when clang builds-up the initialization representation. This was brought to my attention when investigating PR36030 Reviewers: majnemer, rjmccall Reviewed By: rjmccall Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D42549 llvm-svn: 324776
This commit is contained in:
parent
95a0f39e35
commit
2930d7662e
|
@ -859,9 +859,10 @@ public:
|
||||||
|
|
||||||
// Copy initializer elements.
|
// Copy initializer elements.
|
||||||
SmallVector<llvm::Constant*, 16> Elts;
|
SmallVector<llvm::Constant*, 16> Elts;
|
||||||
Elts.reserve(NumInitableElts + NumElements);
|
Elts.reserve(std::max(NumInitableElts, NumElements));
|
||||||
|
|
||||||
bool RewriteType = false;
|
bool RewriteType = false;
|
||||||
|
bool AllNullValues = true;
|
||||||
for (unsigned i = 0; i < NumInitableElts; ++i) {
|
for (unsigned i = 0; i < NumInitableElts; ++i) {
|
||||||
Expr *Init = ILE->getInit(i);
|
Expr *Init = ILE->getInit(i);
|
||||||
llvm::Constant *C = Emitter.tryEmitPrivateForMemory(Init, EltType);
|
llvm::Constant *C = Emitter.tryEmitPrivateForMemory(Init, EltType);
|
||||||
|
@ -869,15 +870,22 @@ public:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
RewriteType |= (C->getType() != ElemTy);
|
RewriteType |= (C->getType() != ElemTy);
|
||||||
Elts.push_back(C);
|
Elts.push_back(C);
|
||||||
|
if (AllNullValues && !C->isNullValue())
|
||||||
|
AllNullValues = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If all initializer elements are "zero," then avoid storing NumElements
|
||||||
|
// instances of the zero representation.
|
||||||
|
if (AllNullValues)
|
||||||
|
return llvm::ConstantAggregateZero::get(AType);
|
||||||
|
|
||||||
RewriteType |= (fillC->getType() != ElemTy);
|
RewriteType |= (fillC->getType() != ElemTy);
|
||||||
Elts.resize(NumElements, fillC);
|
Elts.resize(NumElements, fillC);
|
||||||
|
|
||||||
if (RewriteType) {
|
if (RewriteType) {
|
||||||
// FIXME: Try to avoid packing the array
|
// FIXME: Try to avoid packing the array
|
||||||
std::vector<llvm::Type*> Types;
|
std::vector<llvm::Type*> Types;
|
||||||
Types.reserve(NumInitableElts + NumElements);
|
Types.reserve(Elts.size());
|
||||||
for (unsigned i = 0, e = Elts.size(); i < e; ++i)
|
for (unsigned i = 0, e = Elts.size(); i < e; ++i)
|
||||||
Types.push_back(Elts[i]->getType());
|
Types.push_back(Elts[i]->getType());
|
||||||
llvm::StructType *SType = llvm::StructType::get(AType->getContext(),
|
llvm::StructType *SType = llvm::StructType::get(AType->getContext(),
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
// RUN: %clang_cc1 %s -O0 -triple x86_64-unknown-linux-gnu -emit-llvm -o - | FileCheck %s
|
||||||
|
|
||||||
|
// CHECK: @{{.*}}.a1 = internal constant [5 x i32] [i32 0, i32 1, i32 2, i32 0, i32 0]
|
||||||
|
// CHECK: @{{.*}}.a2 = internal constant [5 x i32] zeroinitializer
|
||||||
|
// CHECK: @{{.*}}.a3 = internal constant [5 x i32] zeroinitializer
|
||||||
|
|
||||||
|
void testConstArrayInits(void)
|
||||||
|
{
|
||||||
|
const int a1[5] = {0,1,2};
|
||||||
|
const int a2[5] = {0,0,0};
|
||||||
|
const int a3[5] = {0};
|
||||||
|
}
|
Loading…
Reference in New Issue