[clang] aa4bcaa - Remove the unused/undefined `_cmd` parameter in `objc_direct` methods.
Michael Wyman via cfe-commits
cfe-commits at lists.llvm.org
Wed Sep 21 15:45:28 PDT 2022
Author: Michael Wyman
Date: 2022-09-21T15:37:48-07:00
New Revision: aa4bcaab9600b42165587ec6f135399ff933bd14
URL: https://github.com/llvm/llvm-project/commit/aa4bcaab9600b42165587ec6f135399ff933bd14
DIFF: https://github.com/llvm/llvm-project/commit/aa4bcaab9600b42165587ec6f135399ff933bd14.diff
LOG: Remove the unused/undefined `_cmd` parameter in `objc_direct` methods.
When `objc_direct` methods were implemented, the implicit `_cmd` parameter was left as an argument to the method implementation function, but was unset by callers; if the method body referenced the `_cmd` variable, a selector load would be emitted inside the body. However, this leaves an unused argument in the ABI, and is unnecessary.
This change removes the empty/unset argument, and if `_cmd` is referenced inside an `objc_direct` method it will emit local storage for the implicit variable. From the ABI perspective, `objc_direct` methods will have the implicit `self` parameter, immediately followed by whatever explicit arguments are defined on the method, rather than having one unset/undefined register in the middle.
Differential Revision: https://reviews.llvm.org/D131424
Added:
Modified:
clang/lib/CodeGen/CGCall.cpp
clang/lib/CodeGen/CGObjC.cpp
clang/lib/CodeGen/CGObjCMac.cpp
clang/test/CodeGenObjC/direct-method.m
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index ff39289d68b30..1df9c6b23cf8b 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -484,9 +484,11 @@ const CGFunctionInfo &
CodeGenTypes::arrangeObjCMessageSendSignature(const ObjCMethodDecl *MD,
QualType receiverType) {
SmallVector<CanQualType, 16> argTys;
- SmallVector<FunctionProtoType::ExtParameterInfo, 4> extParamInfos(2);
+ SmallVector<FunctionProtoType::ExtParameterInfo, 4> extParamInfos(
+ MD->isDirectMethod() ? 1 : 2);
argTys.push_back(Context.getCanonicalParamType(receiverType));
- argTys.push_back(Context.getCanonicalParamType(Context.getObjCSelType()));
+ if (!MD->isDirectMethod())
+ argTys.push_back(Context.getCanonicalParamType(Context.getObjCSelType()));
// FIXME: Kill copy?
for (const auto *I : MD->parameters()) {
argTys.push_back(Context.getCanonicalParamType(I->getType()));
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp
index d2959deae24f8..bbd300ed530a5 100644
--- a/clang/lib/CodeGen/CGObjC.cpp
+++ b/clang/lib/CodeGen/CGObjC.cpp
@@ -768,7 +768,8 @@ void CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD,
}
args.push_back(OMD->getSelfDecl());
- args.push_back(OMD->getCmdDecl());
+ if (!OMD->isDirectMethod())
+ args.push_back(OMD->getCmdDecl());
args.append(OMD->param_begin(), OMD->param_end());
diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 7a972152e1144..c3b8e6e8afa91 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -2145,7 +2145,8 @@ CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
if (!IsSuper)
Arg0 = CGF.Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy);
ActualArgs.add(RValue::get(Arg0), Arg0Ty);
- ActualArgs.add(RValue::get(SelValue), selTy);
+ if (!Method || !Method->isDirectMethod())
+ ActualArgs.add(RValue::get(SelValue), selTy);
ActualArgs.addFrom(CallArgs);
// If we're calling a method, use the formal signature.
@@ -4103,6 +4104,9 @@ void CGObjCCommonMac::GenerateDirectMethodPrologue(
// only synthesize _cmd if it's referenced
if (OMD->getCmdDecl()->isUsed()) {
+ // `_cmd` is not a parameter to direct methods, so storage must be
+ // explicitly declared for it.
+ CGF.EmitVarDecl(*OMD->getCmdDecl());
Builder.CreateStore(GetSelector(CGF, OMD),
CGF.GetAddrOfLocalVar(OMD->getCmdDecl()));
}
diff --git a/clang/test/CodeGenObjC/direct-method.m b/clang/test/CodeGenObjC/direct-method.m
index 2301c84a71a2b..2583de1378bdb 100644
--- a/clang/test/CodeGenObjC/direct-method.m
+++ b/clang/test/CodeGenObjC/direct-method.m
@@ -28,9 +28,7 @@ - (int)getInt __attribute__((objc_direct)) {
// CHECK-LABEL: entry:
// CHECK-NEXT: [[RETVAL:%.*]] = alloca
// CHECK-NEXT: [[SELFADDR:%.*]] = alloca %0*,
- // CHECK-NEXT: [[_CMDADDR:%.*]] = alloca i8*,
// CHECK-NEXT: store %0* %{{.*}}, %0** [[SELFADDR]],
- // CHECK-NEXT: store i8* %{{.*}}, i8** [[_CMDADDR]],
// self nil-check
// CHECK-NEXT: [[SELF:%.*]] = load %0*, %0** [[SELFADDR]],
@@ -60,9 +58,7 @@ + (int)classGetInt __attribute__((objc_direct)) {
// loading parameters
// CHECK-LABEL: entry:
// CHECK-NEXT: [[SELFADDR:%.*]] = alloca i8*,
- // CHECK-NEXT: [[_CMDADDR:%.*]] = alloca i8*,
// CHECK-NEXT: store i8* %{{.*}}, i8** [[SELFADDR]],
- // CHECK-NEXT: store i8* %{{.*}}, i8** [[_CMDADDR]],
// [self self]
// CHECK-NEXT: [[SELF:%.*]] = load i8*, i8** [[SELFADDR]],
@@ -81,9 +77,7 @@ - (struct my_complex_struct)getComplex __attribute__((objc_direct)) {
// CHECK-LABEL: entry:
// CHECK-NEXT: [[RETVAL:%.*]] = alloca
// CHECK-NEXT: [[SELFADDR:%.*]] = alloca %0*,
- // CHECK-NEXT: [[_CMDADDR:%.*]] = alloca i8*,
// CHECK-NEXT: store %0* %{{.*}}, %0** [[SELFADDR]],
- // CHECK-NEXT: store i8* %{{.*}}, i8** [[_CMDADDR]],
// self nil-check
// CHECK-NEXT: [[SELF:%.*]] = load %0*, %0** [[SELFADDR]],
@@ -125,9 +119,7 @@ - (struct my_aggregate_struct)getAggregate __attribute__((objc_direct)) {
// loading parameters
// CHECK-LABEL: entry:
// CHECK-NEXT: [[SELFADDR:%.*]] = alloca %0*,
- // CHECK-NEXT: [[_CMDADDR:%.*]] = alloca i8*,
// CHECK-NEXT: store %0* %{{.*}}, %0** [[SELFADDR]],
- // CHECK-NEXT: store i8* %{{.*}}, i8** [[_CMDADDR]],
// self nil-check
// CHECK-NEXT: [[SELF:%.*]] = load %0*, %0** [[SELFADDR]],
@@ -159,6 +151,19 @@ + (struct my_aggregate_struct)classGetAggregate __attribute__((objc_direct)) {
// CHECK: ret void
}
+// CHECK-LABEL: define hidden void @"\01-[Root accessCmd]"(
+- (void)accessCmd __attribute__((objc_direct)) {
+ // CHECK-LABEL: entry:
+ // CHECK-NEXT: [[SELFADDR:%.*]] = alloca %0*,
+ // CHECK-NEXT: [[CMDVAL:%_cmd]] = alloca i8*,
+
+ // loading the _cmd selector
+ // CHECK-LABEL: objc_direct_method.cont:
+ // CHECK-NEXT: [[CMD1:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
+ // CHECK-NEXT: store i8* [[CMD1]], i8** [[CMDVAL]],
+ SEL sel = _cmd;
+}
+
@end
// CHECK-LABEL: define hidden i32 @"\01-[Root intProperty]"
@@ -205,19 +210,19 @@ - (int)directMethodInCategoryNoDecl __attribute__((objc_direct)) {
int useRoot(Root *r) {
// CHECK-LABEL: define{{.*}} i32 @useRoot
- // CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Root getInt]"
- // CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Root intProperty]"
- // CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Root intProperty2]"
+ // CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Root getInt]" to i32 (i8*)
+ // CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Root intProperty]" to i32 (i8*)
+ // CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Root intProperty2]" to i32 (i8*)
return [r getInt] + [r intProperty] + [r intProperty2];
}
int useFoo(Foo *f) {
// CHECK-LABEL: define{{.*}} i32 @useFoo
- // CHECK: call void bitcast {{.*}} @"\01-[Foo setGetDynamic_setDirect:]"
- // CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Foo getDirect_setDynamic]"
- // CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Foo directMethodInExtension]"
- // CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Foo directMethodInCategory]"
- // CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Foo directMethodInCategoryNoDecl]"
+ // CHECK: call void bitcast {{.*}} @"\01-[Foo setGetDynamic_setDirect:]" to void (i8*, i32)
+ // CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Foo getDirect_setDynamic]" to i32 (i8*)
+ // CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Foo directMethodInExtension]" to i32 (i8*)
+ // CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Foo directMethodInCategory]" to i32 (i8*)
+ // CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Foo directMethodInCategoryNoDecl]" to i32 (i8*)
[f setGetDynamic_setDirect:1];
return [f getDirect_setDynamic] +
[f directMethodInExtension] +
More information about the cfe-commits
mailing list