Skip to content

Commit 0e646d9

Browse files
ahatanakahatanaka
authored andcommitted
[CodeGen] Add a flag to disable emitting block signature strings (llvm#96944)
Users who don't need the signature string to be emitted can use the flag to reduce code size. rdar://121933818
1 parent 04733f8 commit 0e646d9

File tree

8 files changed

+61
-16
lines changed

8 files changed

+61
-16
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,11 @@ New Compiler Flags
318318
similarly to ``-pg`` by writing profile information, but targets the ``prof``
319319
tool as opposed to the ``gprof`` tool.
320320

321+
- ``-fdisable-block-signature-string`` instructs clang not to emit the signature
322+
string for blocks. Disabling the string can potentially break existing code
323+
that relies on it. Users should carefully consider this possibiilty when using
324+
the flag.
325+
321326
Deprecated Compiler Flags
322327
-------------------------
323328

clang/docs/UsersManual.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -913,6 +913,12 @@ Clang options that don't fit neatly into other categories.
913913
binary compatibility issues on older x86_64 targets, however, so use it with
914914
caution.
915915

916+
.. option:: -fdisable-block-signature-string
917+
918+
Instruct clang not to emit the signature string for blocks. Disabling the
919+
string can potentially break existing code that relies on it. Users should
920+
carefully consider this possibiilty when using the flag.
921+
916922
.. _configuration-files:
917923

918924
Configuration files

clang/include/clang/Basic/CodeGenOptions.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ CODEGENOPT(NoImplicitFloat , 1, 0) ///< Set when -mno-implicit-float is enable
183183
CODEGENOPT(NullPointerIsValid , 1, 0) ///< Assume Null pointer deference is defined.
184184
CODEGENOPT(OpenCLCorrectlyRoundedDivSqrt, 1, 0) ///< -cl-fp32-correctly-rounded-divide-sqrt
185185
CODEGENOPT(HIPCorrectlyRoundedDivSqrt, 1, 1) ///< -fno-hip-fp32-correctly-rounded-divide-sqrt
186+
CODEGENOPT(DisableBlockSignatureString, 1, 0) ///< Set when -fdisable-block-signature-string is enabled.
186187
CODEGENOPT(HIPSaveKernelArgName, 1, 0) ///< Set when -fhip-kernel-arg-name is enabled.
187188
CODEGENOPT(UniqueInternalLinkageNames, 1, 0) ///< Internal Linkage symbols get unique names.
188189
CODEGENOPT(SplitMachineFunctions, 1, 0) ///< Split machine functions using profile information.

clang/include/clang/Driver/Options.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2844,6 +2844,11 @@ defm objc_avoid_heapify_local_blocks : BoolFOption<"objc-avoid-heapify-local-blo
28442844
PosFlag<SetTrue, [], "Try">,
28452845
NegFlag<SetFalse, [], "Don't try">,
28462846
BothFlags<[CC1Option, NoDriverOption], " to avoid heapifying local blocks">>;
2847+
defm disable_block_signature_string : BoolFOption<"disable-block-signature-string",
2848+
CodeGenOpts<"DisableBlockSignatureString">, DefaultFalse,
2849+
PosFlag<SetTrue, [], "Disable">,
2850+
NegFlag<SetFalse, [], "Don't disable">,
2851+
BothFlags<[CC1Option], " block signature string)">>;
28472852

28482853
def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group<f_Group>,
28492854
HelpText<"Omit the frame pointer from functions that don't need it. "

clang/lib/CodeGen/CGBlocks.cpp

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -142,11 +142,15 @@ static std::string getBlockDescriptorName(const CGBlockInfo &BlockInfo,
142142
Name += "_";
143143
}
144144

145-
std::string TypeAtEncoding =
146-
CGM.getContext().getObjCEncodingForBlock(BlockInfo.getBlockExpr());
147-
/// Replace occurrences of '@' with '\1'. '@' is reserved on ELF platforms as
148-
/// a separator between symbol name and symbol version.
149-
std::replace(TypeAtEncoding.begin(), TypeAtEncoding.end(), '@', '\1');
145+
std::string TypeAtEncoding;
146+
147+
if (!CGM.getCodeGenOpts().DisableBlockSignatureString) {
148+
TypeAtEncoding =
149+
CGM.getContext().getObjCEncodingForBlock(BlockInfo.getBlockExpr());
150+
/// Replace occurrences of '@' with '\1'. '@' is reserved on ELF platforms
151+
/// as a separator between symbol name and symbol version.
152+
std::replace(TypeAtEncoding.begin(), TypeAtEncoding.end(), '@', '\1');
153+
}
150154
Name += "e" + llvm::to_string(TypeAtEncoding.size()) + "_" + TypeAtEncoding;
151155
Name += "l" + CGM.getObjCRuntime().getRCBlockLayoutStr(CGM, BlockInfo);
152156
return Name;
@@ -227,10 +231,14 @@ static llvm::Constant *buildBlockDescriptor(CodeGenModule &CGM,
227231
}
228232

229233
// Signature. Mandatory ObjC-style method descriptor @encode sequence.
230-
std::string typeAtEncoding =
231-
CGM.getContext().getObjCEncodingForBlock(blockInfo.getBlockExpr());
232-
elements.add(llvm::ConstantExpr::getBitCast(
233-
CGM.GetAddrOfConstantCString(typeAtEncoding).getPointer(), i8p));
234+
if (CGM.getCodeGenOpts().DisableBlockSignatureString) {
235+
elements.addNullPointer(i8p);
236+
} else {
237+
std::string typeAtEncoding =
238+
CGM.getContext().getObjCEncodingForBlock(blockInfo.getBlockExpr());
239+
elements.add(llvm::ConstantExpr::getBitCast(
240+
CGM.GetAddrOfConstantCString(typeAtEncoding).getPointer(), i8p));
241+
}
234242

235243
// GC layout.
236244
if (C.getLangOpts().ObjC) {
@@ -841,7 +849,8 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
841849
descriptor = buildBlockDescriptor(CGM, blockInfo);
842850

843851
// Compute the initial on-stack block flags.
844-
flags = BLOCK_HAS_SIGNATURE;
852+
if (!CGM.getCodeGenOpts().DisableBlockSignatureString)
853+
flags = BLOCK_HAS_SIGNATURE;
845854
if (blockInfo.HasCapturedVariableLayout)
846855
flags |= BLOCK_HAS_EXTENDED_LAYOUT;
847856
if (blockInfo.NeedsCopyDispose)
@@ -1358,7 +1367,9 @@ static llvm::Constant *buildGlobalBlock(CodeGenModule &CGM,
13581367
fields.add(CGM.getNSConcreteGlobalBlock());
13591368

13601369
// __flags
1361-
BlockFlags flags = BLOCK_IS_GLOBAL | BLOCK_HAS_SIGNATURE;
1370+
BlockFlags flags = BLOCK_IS_GLOBAL;
1371+
if (!CGM.getCodeGenOpts().DisableBlockSignatureString)
1372+
flags |= BLOCK_HAS_SIGNATURE;
13621373
if (blockInfo.UsesStret)
13631374
flags |= BLOCK_USE_STRET;
13641375

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5657,6 +5657,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &Job,
56575657
Args.AddLastArg(CmdArgs, options::OPT_fexperimental_relative_cxx_abi_vtables,
56585658
options::OPT_fno_experimental_relative_cxx_abi_vtables);
56595659

5660+
Args.AddLastArg(CmdArgs, options::OPT_fdisable_block_signature_string,
5661+
options::OPT_fno_disable_block_signature_string);
5662+
56605663
// Handle segmented stacks.
56615664
Args.addOptInFlag(CmdArgs, options::OPT_fsplit_stack,
56625665
options::OPT_fno_split_stack);

clang/test/CodeGen/blocks.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
1-
// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -Wno-strict-prototypes -o - -fblocks | FileCheck %s
1+
// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -Wno-strict-prototypes -o - -fblocks | FileCheck --check-prefix=CHECK --check-prefix=SIG_STR %s
2+
// 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
23

3-
// 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
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
4+
// SIG_STR: @[[STR:.*]] = private unnamed_addr constant [6 x i8] c"v4@?0\00", align 1
5+
// SIG_STR: @{{.*}} = internal constant { ptr, i32, i32, ptr, ptr } { ptr @_NSConcreteGlobalBlock, i32 1342177280, i32 0, ptr @f_block_invoke, ptr @{{.*}} }, align 4
6+
// NO_SIG_STR: @{{.*}} = internal constant { ptr, i32, i32, ptr, ptr } { ptr @_NSConcreteGlobalBlock, i32 268435456, i32 0, ptr @f_block_invoke, ptr @{{.*}} }, align 4
7+
8+
// 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
9+
// 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
10+
// 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
11+
// 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
512

613
void (^f)(void) = ^{};
714

clang/test/CodeGenObjC/blocks.m

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1-
// RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -fblocks -Wno-strict-prototypes -o - %s | FileCheck %s
1+
// 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
2+
// 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
23

34
// Check that there is only one capture (20o) in the copy/dispose function
45
// names.
56

6-
// 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 },
7+
// SIG_STR: @[[STR3:.*]] = private unnamed_addr constant [6 x i8] c"v4@?0\00", align 1
8+
// 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 },
9+
// 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 },
10+
711

812
void (^gb0)(void);
913

@@ -136,6 +140,9 @@ void test5(A *a) {
136140
}
137141

138142
// CHECK-LABEL: define void @test5(
143+
// CHECK: %[[FLAGS:.*]] = getelementptr inbounds <{ ptr, i32, i32, ptr, ptr, ptr, ptr }>, ptr %{{.*}}, i32 0, i32 1
144+
// SIG_STR: store i32 -1040187392, ptr %[[FLAGS]], align 4
145+
// NO_SIG_STR: store i32 -2113929216, ptr %[[FLAGS]], align 4
139146
// CHECK: %[[V0:.*]] = getelementptr inbounds <{ ptr, i32, i32, ptr, ptr, ptr, ptr }>, ptr %{{.*}}, i32 0, i32 4
140147
// CHECK: store ptr @[[BLOCK_DESCRIPTOR0]], ptr %[[V0]],
141148

0 commit comments

Comments
 (0)