vitalybuka created this revision. vitalybuka added reviewers: pcc, eugenis, glider, jfb. Herald added subscribers: cfe-commits, dexonsmith. Herald added a project: clang.
Patch extends effect of D63967 <https://reviews.llvm.org/D63967> to 32bit platforms and improves pattern initialization there. It cuts size of 32bit binary compiled with -ftrivial-auto-var-init=pattern by 2%. Using pointer on the first page was useful but is not worth of 2% Binary size change on CTMark, (with -fuse-ld=lld -Wl,--icf=all, similar results with default linker options) master patch diff Os pattern 7.915580e+05 7.727164e+05 -0.026256 O3 pattern 9.953688e+05 9.769336e+05 -0.018545 Zero vs Pattern on master zero pattern diff Os 7.689712e+05 7.915580e+05 0.031380 O3 9.744796e+05 9.953688e+05 0.021133 Zero vs Pattern with the patch zero pattern diff Os 7.689712e+05 7.727164e+05 0.003025 O3 9.744796e+05 9.769336e+05 0.001525 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D64597 Files: clang/lib/CodeGen/PatternInit.cpp clang/test/CodeGenCXX/auto-var-init.cpp
Index: clang/test/CodeGenCXX/auto-var-init.cpp =================================================================== --- clang/test/CodeGenCXX/auto-var-init.cpp +++ clang/test/CodeGenCXX/auto-var-init.cpp @@ -65,9 +65,9 @@ // PATTERN-O1-NOT: @__const.test_nullinit_uninit.uninit // PATTERN-O1-NOT: @__const.test_nullinit_braces.braces // PATTERN-O1-NOT: @__const.test_nullinit_custom.custom -// PATTERN-I386: @__const.test_nullinit_uninit.uninit = private unnamed_addr constant %struct.nullinit { i8* inttoptr (i32 170 to i8*) }, align 4 -// PATTERN-I386: @__const.test_nullinit_braces.braces = private unnamed_addr constant %struct.nullinit { i8* inttoptr (i32 170 to i8*) }, align 4 -// PATTERN-I386: @__const.test_nullinit_custom.custom = private unnamed_addr constant %struct.nullinit { i8* inttoptr (i32 170 to i8*) }, align 4 +// PATTERN-I386: @__const.test_nullinit_uninit.uninit = private unnamed_addr constant %struct.nullinit { i8* inttoptr (i32 -1431655766 to i8*) }, align 4 +// PATTERN-I386: @__const.test_nullinit_braces.braces = private unnamed_addr constant %struct.nullinit { i8* inttoptr (i32 -1431655766 to i8*) }, align 4 +// PATTERN-I386: @__const.test_nullinit_custom.custom = private unnamed_addr constant %struct.nullinit { i8* inttoptr (i32 -1431655766 to i8*) }, align 4 struct nullinit { char* null = nullptr; }; // PATTERN-O0: @__const.test_padded_uninit.uninit = private unnamed_addr constant { i8, [3 x i8], i32 } { i8 -86, [3 x i8] c"\AA\AA\AA", i32 -1431655766 }, align 4 // PATTERN-O0: @__const.test_padded_custom.custom = private unnamed_addr constant { i8, [3 x i8], i32 } { i8 42, [3 x i8] zeroinitializer, i32 13371337 }, align 4 @@ -181,19 +181,19 @@ // PATTERN-O1-NOT: @__const.test_base_uninit.uninit // PATTERN-O0: @__const.test_base_braces.braces = private unnamed_addr constant %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) }, align 8 // PATTERN-O1-NOT: @__const.test_base_braces.braces -// PATTERN-I386: @__const.test_base_uninit.uninit = private unnamed_addr constant %struct.base { i32 (...)** inttoptr (i32 170 to i32 (...)**) }, align 4 +// PATTERN-I386: @__const.test_base_uninit.uninit = private unnamed_addr constant %struct.base { i32 (...)** inttoptr (i32 -1431655766 to i32 (...)**) }, align 4 struct base { virtual ~base(); }; // PATTERN-O0: @__const.test_derived_uninit.uninit = private unnamed_addr constant %struct.derived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) } }, align 8 // PATTERN-O1-NOT: @__const.test_derived_uninit.uninit // PATTERN-O0: @__const.test_derived_braces.braces = private unnamed_addr constant %struct.derived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) } }, align 8 // PATTERN-O1-NOT: @__const.test_derived_braces.braces -// PATTERN-I386: @__const.test_derived_uninit.uninit = private unnamed_addr constant %struct.derived { %struct.base { i32 (...)** inttoptr (i32 170 to i32 (...)**) } }, align 4 +// PATTERN-I386: @__const.test_derived_uninit.uninit = private unnamed_addr constant %struct.derived { %struct.base { i32 (...)** inttoptr (i32 -1431655766 to i32 (...)**) } }, align 4 struct derived : public base {}; // PATTERN-O0: @__const.test_virtualderived_uninit.uninit = private unnamed_addr constant %struct.virtualderived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) }, %struct.derived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) } } }, align 8 // PATTERN-O1-NOT: @__const.test_virtualderived_uninit.uninit // PATTERN-O0: @__const.test_virtualderived_braces.braces = private unnamed_addr constant %struct.virtualderived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) }, %struct.derived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) } } }, align 8 // PATTERN-O1-NOT: @__const.test_virtualderived_braces.braces -// PATTERN-I386: @__const.test_virtualderived_uninit.uninit = private unnamed_addr constant %struct.virtualderived { %struct.base { i32 (...)** inttoptr (i32 170 to i32 (...)**) }, %struct.derived { %struct.base { i32 (...)** inttoptr (i32 170 to i32 (...)**) } } }, align 4 +// PATTERN-I386: @__const.test_virtualderived_uninit.uninit = private unnamed_addr constant %struct.virtualderived { %struct.base { i32 (...)** inttoptr (i32 -1431655766 to i32 (...)**) }, %struct.derived { %struct.base { i32 (...)** inttoptr (i32 -1431655766 to i32 (...)**) } } }, align 4 struct virtualderived : public virtual base, public virtual derived {}; // PATTERN-O0: @__const.test_matching_uninit.uninit = private unnamed_addr constant %union.matching { i32 -1431655766 }, align 4 // PATTERN-O1-NOT: @__const.test_matching_uninit.uninit @@ -518,7 +518,7 @@ // ZERO-LABEL: @test_intptr_uninit() // ZERO: store i32* null, i32** %uninit, align // PATTERN-I386-LABEL: @test_intptr_uninit() -// PATTERN-I386: store i32* inttoptr (i32 170 to i32*), i32** %uninit, align 4 +// PATTERN-I386: store i32* inttoptr (i32 -1431655766 to i32*), i32** %uninit, align 4 TEST_BRACES(intptr, int*); // CHECK-LABEL: @test_intptr_braces() @@ -535,7 +535,7 @@ // ZERO-LABEL: @test_intptrptr_uninit() // ZERO: store i32** null, i32*** %uninit, align // PATTERN-I386-LABEL: @test_intptrptr_uninit() -// PATTERN-I386: store i32** inttoptr (i32 170 to i32**), i32*** %uninit, align 4 +// PATTERN-I386: store i32** inttoptr (i32 -1431655766 to i32**), i32*** %uninit, align 4 TEST_BRACES(intptrptr, int**); // CHECK-LABEL: @test_intptrptr_braces() @@ -552,7 +552,7 @@ // ZERO-LABEL: @test_function_uninit() // ZERO: store void ()* null, void ()** %uninit, align // PATTERN-I386-LABEL: @test_function_uninit() -// PATTERN-I386: store void ()* inttoptr (i32 170 to void ()*), void ()** %uninit, align 4 +// PATTERN-I386: store void ()* inttoptr (i32 -1431655766 to void ()*), void ()** %uninit, align 4 TEST_BRACES(function, void(*)()); // CHECK-LABEL: @test_function_braces() Index: clang/lib/CodeGen/PatternInit.cpp =================================================================== --- clang/lib/CodeGen/PatternInit.cpp +++ clang/lib/CodeGen/PatternInit.cpp @@ -18,11 +18,6 @@ // pointers as well as integers so that aggregates are likely to be // initialized with this repeated value. constexpr uint64_t LargeValue = 0xAAAAAAAAAAAAAAAAull; - // For 32-bit platforms it's a bit trickier because, across systems, only the - // zero page can reasonably be expected to be unmapped, and even then we need - // a very low address. We use a smaller value, and that value sadly doesn't - // have a repeated byte-pattern. We don't use it for integers. - constexpr uint32_t SmallValue = 0x000000AA; // Floating-point values are initialized as NaNs because they propagate. Using // a repeated byte pattern means that it will be easier to initialize // all-floating-point aggregates and arrays with memset. Further, aggregates @@ -45,19 +40,10 @@ Ty->isVectorTy() ? Ty->getVectorElementType() : Ty); unsigned PtrWidth = CGM.getContext().getTargetInfo().getPointerWidth( PtrTy->getAddressSpace()); - llvm::Type *IntTy = llvm::IntegerType::get(CGM.getLLVMContext(), PtrWidth); - uint64_t IntValue; - switch (PtrWidth) { - default: + if (PtrWidth > 64) llvm_unreachable("pattern initialization of unsupported pointer width"); - case 64: - IntValue = LargeValue; - break; - case 32: - IntValue = SmallValue; - break; - } - auto *Int = llvm::ConstantInt::get(IntTy, IntValue); + llvm::Type *IntTy = llvm::IntegerType::get(CGM.getLLVMContext(), PtrWidth); + auto *Int = llvm::ConstantInt::get(IntTy, LargeValue); return llvm::ConstantExpr::getIntToPtr(Int, PtrTy); } if (Ty->isFPOrFPVectorTy()) {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits