r355660 - Variable auto-init: split out small arrays
JF Bastien via cfe-commits
cfe-commits at lists.llvm.org
Thu Mar 7 17:26:49 PST 2019
Author: jfb
Date: Thu Mar 7 17:26:49 2019
New Revision: 355660
URL: http://llvm.org/viewvc/llvm-project?rev=355660&view=rev
Log:
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
Modified:
cfe/trunk/lib/CodeGen/CGDecl.cpp
cfe/trunk/test/CodeGenCXX/auto-var-init.cpp
Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=355660&r1=355659&r2=355660&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Thu Mar 7 17:26:49 2019
@@ -970,12 +970,12 @@ static llvm::Value *shouldUseMemSetToIni
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(CodeGe
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(CodeGe
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(CodeGe
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(CodeGe
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()),
Modified: cfe/trunk/test/CodeGenCXX/auto-var-init.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/auto-var-init.cpp?rev=355660&r1=355659&r2=355660&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/auto-var-init.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/auto-var-init.cpp Thu Mar 7 17:26:49 2019
@@ -129,7 +129,6 @@ struct arraytail { int i; int arr[]; };
// PATTERN-O1-NOT: @__const.test_bool4_custom.custom
// ZERO-O1-NOT: @__const.test_bool4_custom.custom
-// PATTERN: @__const.test_intptr4_uninit.uninit = private unnamed_addr constant [4 x i32*] [i32* inttoptr (i64 -6148914691236517206 to i32*), i32* inttoptr (i64 -6148914691236517206 to i32*), i32* inttoptr (i64 -6148914691236517206 to i32*), i32* inttoptr (i64 -6148914691236517206 to i32*)], align 16
// PATTERN: @__const.test_intptr4_custom.custom = private unnamed_addr constant [4 x i32*] [i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*)], align 16
// ZERO: @__const.test_intptr4_custom.custom = private unnamed_addr constant [4 x i32*] [i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*)], align 16
// PATTERN-O0: @__const.test_tailpad4_uninit.uninit = private unnamed_addr constant [4 x { i16, i8, [1 x i8] }] [{ i16, i8, [1 x i8] } { i16 -21846, i8 -86, [1 x i8] c"\AA" }, { i16, i8, [1 x i8] } { i16 -21846, i8 -86, [1 x i8] c"\AA" }, { i16, i8, [1 x i8] } { i16 -21846, i8 -86, [1 x i8] c"\AA" }, { i16, i8, [1 x i8] } { i16 -21846, i8 -86, [1 x i8] c"\AA" }], align 16
@@ -1019,13 +1018,20 @@ TEST_CUSTOM(bool4, bool[4], { true, true
// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
TEST_UNINIT(intptr4, int*[4]);
-// CHECK-LABEL: @test_intptr4_uninit()
-// CHECK: %uninit = alloca [4 x i32*], align
-// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
-// PATTERN-LABEL: @test_intptr4_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_intptr4_uninit.uninit
-// ZERO-LABEL: @test_intptr4_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// CHECK-LABEL: @test_intptr4_uninit()
+// CHECK: %uninit = alloca [4 x i32*], align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-O1-LABEL: @test_intptr4_uninit()
+// PATTERN-O1: %1 = getelementptr inbounds [4 x i32*], [4 x i32*]* %uninit, i64 0, i64 0
+// PATTERN-O1-NEXT: store i32* inttoptr (i64 -6148914691236517206 to i32*), i32** %1, align 16
+// PATTERN-O1-NEXT: %2 = getelementptr inbounds [4 x i32*], [4 x i32*]* %uninit, i64 0, i64 1
+// PATTERN-O1-NEXT: store i32* inttoptr (i64 -6148914691236517206 to i32*), i32** %2, align 8
+// PATTERN-O1-NEXT: %3 = getelementptr inbounds [4 x i32*], [4 x i32*]* %uninit, i64 0, i64 2
+// PATTERN-O1-NEXT: store i32* inttoptr (i64 -6148914691236517206 to i32*), i32** %3, align 16
+// PATTERN-O1-NEXT: %4 = getelementptr inbounds [4 x i32*], [4 x i32*]* %uninit, i64 0, i64 3
+// PATTERN-O1-NEXT: store i32* inttoptr (i64 -6148914691236517206 to i32*), i32** %4, align 8
+// ZERO-LABEL: @test_intptr4_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
TEST_BRACES(intptr4, int*[4]);
// CHECK-LABEL: @test_intptr4_braces()
@@ -1124,7 +1130,7 @@ TEST_UNINIT(atomicnotlockfree, _Atomic(n
// PATTERN-LABEL: @test_atomicnotlockfree_uninit()
// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_atomicnotlockfree_uninit.uninit
// PATTERN-O1: bitcast
-// PATTERN-O1: call void @llvm.memset{{.*}}({{.*}}0, i8 -86, i64 32
+// PATTERN-O1: call void @llvm.memset{{.*}}({{.*}}, i8 -86, i64 32
// ZERO-LABEL: @test_atomicnotlockfree_uninit()
// ZERO: call void @llvm.memset{{.*}}, i8 0,
More information about the cfe-commits
mailing list