[clang] Enable direct methods and fast alloc calls for libobjc2. (PR #78030)

Saleem Abdulrasool via cfe-commits cfe-commits at lists.llvm.org
Sun Jan 14 11:08:52 PST 2024


================
@@ -3906,14 +4028,50 @@ llvm::Function *CGObjCGNU::GenerateMethod(const ObjCMethodDecl *OMD,
   CodeGenTypes &Types = CGM.getTypes();
   llvm::FunctionType *MethodTy =
     Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));
-  std::string FunctionName = getSymbolNameForMethod(OMD);
-
-  llvm::Function *Method
-    = llvm::Function::Create(MethodTy,
-                             llvm::GlobalValue::InternalLinkage,
-                             FunctionName,
-                             &TheModule);
-  return Method;
+
+  bool isDirect = OMD->isDirectMethod();
+  std::string FunctionName =
+      getSymbolNameForMethod(OMD, /*include category*/ !isDirect);
+
+  if (!isDirect)
+    return llvm::Function::Create(MethodTy,
+                                  llvm::GlobalVariable::InternalLinkage,
+                                  FunctionName, &TheModule);
+
+  auto *COMD = OMD->getCanonicalDecl();
+  auto I = DirectMethodDefinitions.find(COMD);
+  llvm::Function *OldFn = nullptr, *Fn = nullptr;
+
+  if (I != DirectMethodDefinitions.end()) {
+    // Objective-C allows for the declaration and implementation types
+    // to differ slightly.
+    //
+    // If we're being asked for the Function associated for a method
+    // implementation, a previous value might have been cached
+    // based on the type of the canonical declaration.
+    //
+    // If these do not match, then we'll replace this function with
+    // a new one that has the proper type below.
+    if (!OMD->getBody() || COMD->getReturnType() == OMD->getReturnType())
+      return I->second;
+    OldFn = I->second;
+  }
+
+  if (OldFn) {
+    Fn = llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage,
+                                "", &CGM.getModule());
+    Fn->takeName(OldFn);
+    OldFn->replaceAllUsesWith(Fn);
+    OldFn->eraseFromParent();
+
+    // Replace the cached function in the map.
+    I->second = Fn;
+  } else {
+    Fn = llvm::Function::Create(MethodTy, llvm::GlobalVariable::ExternalLinkage,
+                                FunctionName, &TheModule);
+    DirectMethodDefinitions.insert(std::make_pair(COMD, Fn));
+  }
+  return Fn;
----------------
compnerd wrote:

Feels like this would be clearer as:

```c++
if (I == DirectMethodDefinitions.end()) {
  auto *F = llvm::Function::Create(MethodTy, llvm::GlobalVariable::ExternalLinkage,
                                   FunctionName, &TheModule);
  DirectMethodDefinitions.insert(std::make_pair(COMD, F));
  return F;
}

// Objective-C allows for ...
```

That will merge the block on L4061-4068, with L4046-4057.

https://github.com/llvm/llvm-project/pull/78030


More information about the cfe-commits mailing list