https://github.com/ahatanak created https://github.com/llvm/llvm-project/pull/96944
Users who don't need the signature string to be emitted can use the flag to reduce code size. rdar://121933818 >From 5f71f113b27482114904eae8234c6ebc17eef5a4 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka <ahata...@gmail.com> Date: Tue, 25 Jun 2024 19:37:46 -0700 Subject: [PATCH] [CodeGen] Add a flag to disable emitting block signature strings Users who don't need the signature string to be emitted can use the flag to reduce code size. rdar://121933818 --- clang/docs/ReleaseNotes.rst | 5 ++++ clang/include/clang/Basic/CodeGenOptions.def | 1 + clang/include/clang/Driver/Options.td | 5 ++++ clang/lib/CodeGen/CGBlocks.cpp | 24 +++++++++++++------- clang/lib/Driver/ToolChains/Clang.cpp | 3 +++ clang/test/CodeGen/blocks.c | 12 ++++++---- clang/test/CodeGenObjC/blocks.m | 8 +++++-- 7 files changed, 44 insertions(+), 14 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index df579ae398c5e..f1fe826edc0ab 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -419,6 +419,11 @@ New Compiler Flags Matches MSVC behaviour by defining ``__STDC__`` to ``1`` when MSVC compatibility mode is used. It has no effect for C++ code. +- ``-fdisable-block-signature-string`` instructs clang not to emit the signature + string for blocks. Disabling the string can potentially break existing code + that relies on it. Users should carefully consider this possibiilty when using + the flag. + Deprecated Compiler Flags ------------------------- diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index e3f6da4a84f69..d8738541266d5 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -187,6 +187,7 @@ CODEGENOPT(NoImplicitFloat , 1, 0) ///< Set when -mno-implicit-float is enable CODEGENOPT(NullPointerIsValid , 1, 0) ///< Assume Null pointer deference is defined. CODEGENOPT(OpenCLCorrectlyRoundedDivSqrt, 1, 0) ///< -cl-fp32-correctly-rounded-divide-sqrt CODEGENOPT(HIPCorrectlyRoundedDivSqrt, 1, 1) ///< -fno-hip-fp32-correctly-rounded-divide-sqrt +CODEGENOPT(DisableBlockSignatureString, 1, 0) ///< Set when -fdisable-block-signature-string is enabled. CODEGENOPT(HIPSaveKernelArgName, 1, 0) ///< Set when -fhip-kernel-arg-name is enabled. CODEGENOPT(UniqueInternalLinkageNames, 1, 0) ///< Internal Linkage symbols get unique names. CODEGENOPT(SplitMachineFunctions, 1, 0) ///< Split machine functions using profile information. diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index dd55838dcf384..53a5a918cf52d 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3477,6 +3477,11 @@ defm objc_avoid_heapify_local_blocks : BoolFOption<"objc-avoid-heapify-local-blo PosFlag<SetTrue, [], [ClangOption], "Try">, NegFlag<SetFalse, [], [ClangOption], "Don't try">, BothFlags<[], [CC1Option], " to avoid heapifying local blocks">>; +defm disable_block_signature_string : BoolFOption<"disable-block-signature-string", + CodeGenOpts<"DisableBlockSignatureString">, DefaultFalse, + PosFlag<SetTrue, [], [ClangOption], "Disable">, + NegFlag<SetFalse, [], [ClangOption], "Don't disable">, + BothFlags<[], [CC1Option], " block signature string)">>; def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group<f_Group>, Visibility<[ClangOption, FlangOption]>, diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp index 5dac1cd425bf6..241d6fc2a0c95 100644 --- a/clang/lib/CodeGen/CGBlocks.cpp +++ b/clang/lib/CodeGen/CGBlocks.cpp @@ -121,11 +121,15 @@ static std::string getBlockDescriptorName(const CGBlockInfo &BlockInfo, Name += "_"; } - std::string TypeAtEncoding = - CGM.getContext().getObjCEncodingForBlock(BlockInfo.getBlockExpr()); - /// Replace occurrences of '@' with '\1'. '@' is reserved on ELF platforms as - /// a separator between symbol name and symbol version. - std::replace(TypeAtEncoding.begin(), TypeAtEncoding.end(), '@', '\1'); + std::string TypeAtEncoding; + + if (!CGM.getCodeGenOpts().DisableBlockSignatureString) { + TypeAtEncoding = + CGM.getContext().getObjCEncodingForBlock(BlockInfo.getBlockExpr()); + /// Replace occurrences of '@' with '\1'. '@' is reserved on ELF platforms + /// as a separator between symbol name and symbol version. + std::replace(TypeAtEncoding.begin(), TypeAtEncoding.end(), '@', '\1'); + } Name += "e" + llvm::to_string(TypeAtEncoding.size()) + "_" + TypeAtEncoding; Name += "l" + CGM.getObjCRuntime().getRCBlockLayoutStr(CGM, BlockInfo); return Name; @@ -201,9 +205,13 @@ static llvm::Constant *buildBlockDescriptor(CodeGenModule &CGM, } // Signature. Mandatory ObjC-style method descriptor @encode sequence. - std::string typeAtEncoding = - CGM.getContext().getObjCEncodingForBlock(blockInfo.getBlockExpr()); - elements.add(CGM.GetAddrOfConstantCString(typeAtEncoding).getPointer()); + if (CGM.getCodeGenOpts().DisableBlockSignatureString) { + elements.addNullPointer(i8p); + } else { + std::string typeAtEncoding = + CGM.getContext().getObjCEncodingForBlock(blockInfo.getBlockExpr()); + elements.add(CGM.GetAddrOfConstantCString(typeAtEncoding).getPointer()); + } // GC layout. if (C.getLangOpts().ObjC) { diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index c0f6bc0c2e45a..38d510be85b14 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -5734,6 +5734,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_fexperimental_omit_vtable_rtti, options::OPT_fno_experimental_omit_vtable_rtti); + Args.AddLastArg(CmdArgs, options::OPT_fdisable_block_signature_string, + options::OPT_fno_disable_block_signature_string); + // Handle segmented stacks. Args.addOptInFlag(CmdArgs, options::OPT_fsplit_stack, options::OPT_fno_split_stack); diff --git a/clang/test/CodeGen/blocks.c b/clang/test/CodeGen/blocks.c index 8f947fcdfccb2..09efee257766e 100644 --- a/clang/test/CodeGen/blocks.c +++ b/clang/test/CodeGen/blocks.c @@ -1,7 +1,11 @@ -// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -Wno-strict-prototypes -o - -fblocks | FileCheck %s - -// CHECK: @{{.*}} = internal constant { i32, i32, ptr, ptr, ptr, ptr } { i32 0, i32 24, ptr @__copy_helper_block_4_20r, ptr @__destroy_helper_block_4_20r, ptr @{{.*}}, ptr null }, align 4 -// CHECK: @[[BLOCK_DESCRIPTOR_TMP21:.*]] = internal constant { i32, i32, ptr, ptr, ptr, ptr } { i32 0, i32 24, ptr @__copy_helper_block_4_20r, ptr @__destroy_helper_block_4_20r, ptr @{{.*}}, ptr null }, align 4 +// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -Wno-strict-prototypes -o - -fblocks | FileCheck --check-prefix=CHECK --check-prefix=SIG_STR %s +// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -Wno-strict-prototypes -o - -fblocks -fdisable-block-signature-string | FileCheck --check-prefix=CHECK --check-prefix=NO_SIG_STR %s + +// SIG_STR: @[[STR:.*]] = private unnamed_addr constant [6 x i8] c"v4@?0\00", align 1 +// SIG_STR: @{{.*}} = internal constant { i32, i32, ptr, ptr, ptr, ptr } { i32 0, i32 24, ptr @__copy_helper_block_4_20r, ptr @__destroy_helper_block_4_20r, ptr @[[STR]], ptr null }, align 4 +// SIG_STR: @[[BLOCK_DESCRIPTOR_TMP21:.*]] = internal constant { i32, i32, ptr, ptr, ptr, ptr } { i32 0, i32 24, ptr @__copy_helper_block_4_20r, ptr @__destroy_helper_block_4_20r, ptr @[[STR]], ptr null }, align 4 +// NO_SIG_STR: @{{.*}} = internal constant { i32, i32, ptr, ptr, ptr, ptr } { i32 0, i32 24, ptr @__copy_helper_block_4_20r, ptr @__destroy_helper_block_4_20r, ptr null, ptr null }, align 4 +// NO_SIG_STR: @[[BLOCK_DESCRIPTOR_TMP21:.*]] = internal constant { i32, i32, ptr, ptr, ptr, ptr } { i32 0, i32 24, ptr @__copy_helper_block_4_20r, ptr @__destroy_helper_block_4_20r, ptr null, ptr null }, align 4 void (^f)(void) = ^{}; diff --git a/clang/test/CodeGenObjC/blocks.m b/clang/test/CodeGenObjC/blocks.m index f82801239ad36..cd767b4cea191 100644 --- a/clang/test/CodeGenObjC/blocks.m +++ b/clang/test/CodeGenObjC/blocks.m @@ -1,9 +1,13 @@ -// RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -fblocks -Wno-strict-prototypes -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -fblocks -Wno-strict-prototypes -o - %s | FileCheck --check-prefix=CHECK --check-prefix=SIG_STR %s +// RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -fblocks -Wno-strict-prototypes -fdisable-block-signature-string -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NO_SIG_STR %s // Check that there is only one capture (20o) in the copy/dispose function // names. -// CHECK: @[[BLOCK_DESCRIPTOR0:.*]] = linkonce_odr hidden unnamed_addr constant { i32, i32, ptr, ptr, ptr, i32 } { i32 0, i32 28, ptr @__copy_helper_block_4_20o, ptr @__destroy_helper_block_4_20o, ptr @{{.*}}, i32 512 }, +// SIG_STR: @[[STR3:.*]] = private unnamed_addr constant [6 x i8] c"v4@?0\00", align 1 +// SIG_STR: @[[BLOCK_DESCRIPTOR0:"__block_descriptor_28_4_20o_e5_v4\\01\?0l"]] = linkonce_odr hidden unnamed_addr constant { i32, i32, ptr, ptr, ptr, i32 } { i32 0, i32 28, ptr @__copy_helper_block_4_20o, ptr @__destroy_helper_block_4_20o, ptr @[[STR3]], i32 512 }, +// NO_SIG_STR: @[[BLOCK_DESCRIPTOR0:__block_descriptor_28_4_20o_e0_l]] = linkonce_odr hidden unnamed_addr constant { i32, i32, ptr, ptr, ptr, i32 } { i32 0, i32 28, ptr @__copy_helper_block_4_20o, ptr @__destroy_helper_block_4_20o, ptr null, i32 512 }, + void (^gb0)(void); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits