================ @@ -1994,6 +2004,106 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { { PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty }); } + void GenerateDirectMethodPrologue(CodeGenFunction &CGF, llvm::Function *Fn, + const ObjCMethodDecl *OMD, + const ObjCContainerDecl *CD) override { + auto &Builder = CGF.Builder; + bool ReceiverCanBeNull = true; + auto selfAddr = CGF.GetAddrOfLocalVar(OMD->getSelfDecl()); + auto selfValue = Builder.CreateLoad(selfAddr); + + // Generate: + // + // /* unless the receiver is never NULL */ + // if (self == nil) { + // return (ReturnType){ }; + // } + // + // /* for class methods only to force class lazy initialization */ + // if (!__objc_{class}_initialized) + // { + // objc_send_initialize(class); + // __objc_{class}_initialized = 1; + // } + // + // _cmd = @selector(...) + // ... + + if (OMD->isClassMethod()) { + const ObjCInterfaceDecl *OID = cast<ObjCInterfaceDecl>(CD); + + // Nullable `Class` expressions cannot be messaged with a direct method + // so the only reason why the receive can be null would be because + // of weak linking. + ReceiverCanBeNull = isWeakLinkedClass(OID); + } + + if (ReceiverCanBeNull) { + llvm::BasicBlock *SelfIsNilBlock = + CGF.createBasicBlock("objc_direct_method.self_is_nil"); + llvm::BasicBlock *ContBlock = + CGF.createBasicBlock("objc_direct_method.cont"); + + // if (self == nil) { + auto selfTy = cast<llvm::PointerType>(selfValue->getType()); + auto Zero = llvm::ConstantPointerNull::get(selfTy); + + llvm::MDBuilder MDHelper(CGM.getLLVMContext()); + Builder.CreateCondBr(Builder.CreateICmpEQ(selfValue, Zero), + SelfIsNilBlock, ContBlock, + MDHelper.createBranchWeights(1, 1 << 20)); + + CGF.EmitBlock(SelfIsNilBlock); + + // return (ReturnType){ }; + auto retTy = OMD->getReturnType(); + Builder.SetInsertPoint(SelfIsNilBlock); + if (!retTy->isVoidType()) { + CGF.EmitNullInitialization(CGF.ReturnValue, retTy); + } + CGF.EmitBranchThroughCleanup(CGF.ReturnBlock); + // } + + // rest of the body + CGF.EmitBlock(ContBlock); + Builder.SetInsertPoint(ContBlock); + } + + if (OMD->isClassMethod()) { + // Prefix of the class type. + auto *classStart = + llvm::StructType::get(PtrTy, PtrTy, PtrTy, LongTy, LongTy); + auto &astContext = CGM.getContext(); + auto flags = Builder.CreateLoad( + Address{Builder.CreateStructGEP(classStart, selfValue, 4), LongTy, + CharUnits::fromQuantity( + astContext.getTypeAlign(astContext.UnsignedLongTy))}); + auto isInitialized = Builder.CreateAnd(flags, (1 << 8)); + llvm::BasicBlock *notInitializedBlock = + CGF.createBasicBlock("objc_direct_method.send_initialize"); + llvm::BasicBlock *initializedBlock = + CGF.createBasicBlock("objc_direct_method.class_initialized"); + llvm::MDBuilder MDHelper(CGM.getLLVMContext()); ---------------- compnerd wrote:
Perhaps hoist the MDBuilder as you need it previously as well. https://github.com/llvm/llvm-project/pull/78030 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits