diff options
| author | JF Bastien <jfbastien@apple.com> | 2019-03-08 01:26:49 +0000 |
|---|---|---|
| committer | JF Bastien <jfbastien@apple.com> | 2019-03-08 01:26:49 +0000 |
| commit | b5e5bc760e73d613c109519f962a2e62bfc53430 (patch) | |
| tree | 8368dbd97544b048533690cd115e10466d4a7cbf /clang/lib/CodeGen | |
| parent | 382ede4544a8902f38cea5680f1625ec3ac684dc (diff) | |
| download | bcm5719-llvm-b5e5bc760e73d613c109519f962a2e62bfc53430.tar.gz bcm5719-llvm-b5e5bc760e73d613c109519f962a2e62bfc53430.zip | |
Variable auto-init: split out small arrays
Summary: Following up with r355181, initialize small arrays as well.
LLVM stage2 shows a tiny size gain.
<rdar://48523005>
Reviewers: glider, pcc, kcc, rjmccall
Subscribers: jkorous, dexonsmith, jdoerfert, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D58885
llvm-svn: 355660
Diffstat (limited to 'clang/lib/CodeGen')
| -rw-r--r-- | clang/lib/CodeGen/CGDecl.cpp | 60 |
1 files changed, 38 insertions, 22 deletions
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 4acfb15c07f..c09077bb8a5 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -970,12 +970,12 @@ static llvm::Value *shouldUseMemSetToInitialize(llvm::Constant *Init, return llvm::isBytewiseValue(Init); } -/// Decide whether we want to split a constant structure store into a sequence -/// of its fields' stores. This may cost us code size and compilation speed, -/// but plays better with store optimizations. -static bool shouldSplitStructStore(CodeGenModule &CGM, - uint64_t GlobalByteSize) { - // Don't break structures that occupy more than one cacheline. +/// Decide whether we want to split a constant structure or array store into a +/// sequence of its fields' stores. This may cost us code size and compilation +/// speed, but plays better with store optimizations. +static bool shouldSplitConstantStore(CodeGenModule &CGM, + uint64_t GlobalByteSize) { + // Don't break things that occupy more than one cacheline. uint64_t ByteSizeLimit = 64; if (CGM.getCodeGenOpts().OptimizationLevel == 0) return false; @@ -1203,9 +1203,9 @@ static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D, CGBuilderTy &Builder, llvm::Constant *constant) { auto *Ty = constant->getType(); - bool isScalar = Ty->isIntOrIntVectorTy() || Ty->isPtrOrPtrVectorTy() || - Ty->isFPOrFPVectorTy(); - if (isScalar) { + bool canDoSingleStore = Ty->isIntOrIntVectorTy() || + Ty->isPtrOrPtrVectorTy() || Ty->isFPOrFPVectorTy(); + if (canDoSingleStore) { Builder.CreateStore(constant, Loc, isVolatile); return; } @@ -1213,12 +1213,13 @@ static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D, auto *Int8Ty = llvm::IntegerType::getInt8Ty(CGM.getLLVMContext()); auto *IntPtrTy = CGM.getDataLayout().getIntPtrType(CGM.getLLVMContext()); - // If the initializer is all or mostly the same, codegen with bzero / memset - // then do a few stores afterward. uint64_t ConstantSize = CGM.getDataLayout().getTypeAllocSize(Ty); if (!ConstantSize) return; auto *SizeVal = llvm::ConstantInt::get(IntPtrTy, ConstantSize); + + // If the initializer is all or mostly the same, codegen with bzero / memset + // then do a few stores afterward. if (shouldUseBZeroPlusStoresToInitialize(constant, ConstantSize)) { Builder.CreateMemSet(Loc, llvm::ConstantInt::get(Int8Ty, 0), SizeVal, isVolatile); @@ -1232,6 +1233,7 @@ static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D, return; } + // If the initializer is a repeated byte pattern, use memset. llvm::Value *Pattern = shouldUseMemSetToInitialize(constant, ConstantSize); if (Pattern) { uint64_t Value = 0x00; @@ -1245,20 +1247,34 @@ static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D, return; } - llvm::StructType *STy = dyn_cast<llvm::StructType>(Ty); - // FIXME: handle the case when STy != Loc.getElementType(). - // FIXME: handle non-struct aggregate types. - if (STy && (STy == Loc.getElementType()) && - shouldSplitStructStore(CGM, ConstantSize)) { - for (unsigned i = 0; i != constant->getNumOperands(); i++) { - Address EltPtr = Builder.CreateStructGEP(Loc, i); - emitStoresForConstant( - CGM, D, EltPtr, isVolatile, Builder, - cast<llvm::Constant>(Builder.CreateExtractValue(constant, i))); + // If the initializer is small, use a handful of stores. + if (shouldSplitConstantStore(CGM, ConstantSize)) { + if (auto *STy = dyn_cast<llvm::StructType>(Ty)) { + // FIXME: handle the case when STy != Loc.getElementType(). + if (STy == Loc.getElementType()) { + for (unsigned i = 0; i != constant->getNumOperands(); i++) { + Address EltPtr = Builder.CreateStructGEP(Loc, i); + emitStoresForConstant( + CGM, D, EltPtr, isVolatile, Builder, + cast<llvm::Constant>(Builder.CreateExtractValue(constant, i))); + } + return; + } + } else if (auto *ATy = dyn_cast<llvm::ArrayType>(Ty)) { + // FIXME: handle the case when ATy != Loc.getElementType(). + if (ATy == Loc.getElementType()) { + for (unsigned i = 0; i != ATy->getNumElements(); i++) { + Address EltPtr = Builder.CreateConstArrayGEP(Loc, i); + emitStoresForConstant( + CGM, D, EltPtr, isVolatile, Builder, + cast<llvm::Constant>(Builder.CreateExtractValue(constant, i))); + } + return; + } } - return; } + // Copy from a global. Builder.CreateMemCpy( Loc, createUnnamedGlobalFrom(CGM, D, Builder, constant, Loc.getAlignment()), |

