[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