RuntimeLibcalls: Add entries for objc runtime calls (#147920)

Stop emitting these calls by name in PreISelIntrinsicLowering. This
is still kind of a hack. We should be going through the abstract
RTLIB:Libcall, and then checking if the call is really supported in
this module. Do this as a placeholder until RuntimeLibcalls is a
module analysis.
This commit is contained in:
Matt Arsenault 2025-07-11 07:45:12 +09:00 committed by GitHub
parent 545b075a87
commit 14b2d2cc3a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 94 additions and 28 deletions

View File

@ -387,6 +387,34 @@ def HEXAGON_MEMCPY_LIKELY_ALIGNED_MIN32BYTES_MULT8BYTES : RuntimeLibcall;
// XCore calls
def MEMCPY_ALIGN_4 : RuntimeLibcall;
// Objective-C calls
def OBJC_AUTORELEASE : RuntimeLibcall;
def OBJC_AUTORELEASEPOOLPOP : RuntimeLibcall;
def OBJC_AUTORELEASEPOOLPUSH : RuntimeLibcall;
def OBJC_AUTORELEASERETURNVALUE : RuntimeLibcall;
def OBJC_COPYWEAK : RuntimeLibcall;
def OBJC_DESTROYWEAK : RuntimeLibcall;
def OBJC_INITWEAK : RuntimeLibcall;
def OBJC_LOADWEAK : RuntimeLibcall;
def OBJC_LOADWEAKRETAINED : RuntimeLibcall;
def OBJC_MOVEWEAK : RuntimeLibcall;
def OBJC_RELEASE : RuntimeLibcall;
def OBJC_RETAIN : RuntimeLibcall;
def OBJC_RETAINAUTORELEASE : RuntimeLibcall;
def OBJC_RETAINAUTORELEASERETURNVALUE : RuntimeLibcall;
def OBJC_RETAINAUTORELEASEDRETURNVALUE : RuntimeLibcall;
def OBJC_CLAIMAUTORELEASEDRETURNVALUE : RuntimeLibcall;
def OBJC_RETAINBLOCK : RuntimeLibcall;
def OBJC_STORESTRONG : RuntimeLibcall;
def OBJC_STOREWEAK : RuntimeLibcall;
def OBJC_UNSAFECLAIMAUTORELEASEDRETURNVALUE : RuntimeLibcall;
def OBJC_RETAINEDOBJECT : RuntimeLibcall;
def OBJC_UNRETAINEDOBJECT : RuntimeLibcall;
def OBJC_UNRETAINEDPOINTER : RuntimeLibcall;
def OBJC_RETAIN_AUTORELEASE : RuntimeLibcall;
def OBJC_SYNC_ENTER : RuntimeLibcall;
def OBJC_SYNC_EXIT : RuntimeLibcall;
//--------------------------------------------------------------------
// Define implementation default libcalls
//--------------------------------------------------------------------
@ -1032,6 +1060,37 @@ defvar LibmHasSinCosF80 = LibcallImpls<(add sincos_f80), hasSinCos>;
defvar LibmHasSinCosF128 = LibcallImpls<(add sincos_f128), hasSinCos>;
defvar LibmHasSinCosPPCF128 = LibcallImpls<(add sincos_ppcf128), hasSinCos>;
//===----------------------------------------------------------------------===//
// Objective-C Runtime Libcalls
//===----------------------------------------------------------------------===//
def objc_autorelease : RuntimeLibcallImpl<OBJC_AUTORELEASE>;
def objc_autoreleasePoolPop : RuntimeLibcallImpl<OBJC_AUTORELEASEPOOLPOP>;
def objc_autoreleasePoolPush : RuntimeLibcallImpl<OBJC_AUTORELEASEPOOLPUSH>;
def objc_autoreleaseReturnValue : RuntimeLibcallImpl<OBJC_AUTORELEASERETURNVALUE>;
def objc_copyWeak : RuntimeLibcallImpl<OBJC_COPYWEAK>;
def objc_destroyWeak : RuntimeLibcallImpl<OBJC_DESTROYWEAK>;
def objc_initWeak : RuntimeLibcallImpl<OBJC_INITWEAK>;
def objc_loadWeak : RuntimeLibcallImpl<OBJC_LOADWEAK>;
def objc_loadWeakRetained : RuntimeLibcallImpl<OBJC_LOADWEAKRETAINED>;
def objc_moveWeak : RuntimeLibcallImpl<OBJC_MOVEWEAK>;
def objc_release : RuntimeLibcallImpl<OBJC_RELEASE>;
def objc_retain : RuntimeLibcallImpl<OBJC_RETAIN>;
def objc_retainAutorelease : RuntimeLibcallImpl<OBJC_RETAINAUTORELEASE>;
def objc_retainAutoreleaseReturnValue : RuntimeLibcallImpl<OBJC_RETAINAUTORELEASERETURNVALUE>;
def objc_retainAutoreleasedReturnValue : RuntimeLibcallImpl<OBJC_RETAINAUTORELEASEDRETURNVALUE>;
def objc_claimAutoreleasedReturnValue : RuntimeLibcallImpl<OBJC_CLAIMAUTORELEASEDRETURNVALUE>;
def objc_retainBlock : RuntimeLibcallImpl<OBJC_RETAINBLOCK>;
def objc_storeStrong : RuntimeLibcallImpl<OBJC_STORESTRONG>;
def objc_storeWeak : RuntimeLibcallImpl<OBJC_STOREWEAK>;
def objc_unsafeClaimAutoreleasedReturnValue : RuntimeLibcallImpl<OBJC_UNSAFECLAIMAUTORELEASEDRETURNVALUE>;
def objc_retainedObject : RuntimeLibcallImpl<OBJC_RETAINEDOBJECT>;
def objc_unretainedObject : RuntimeLibcallImpl<OBJC_UNRETAINEDOBJECT>;
def objc_unretainedPointer : RuntimeLibcallImpl<OBJC_UNRETAINEDPOINTER>;
def objc_retain_autorelease : RuntimeLibcallImpl<OBJC_RETAIN_AUTORELEASE>;
def objc_sync_enter : RuntimeLibcallImpl<OBJC_SYNC_ENTER>;
def objc_sync_exit : RuntimeLibcallImpl<OBJC_SYNC_EXIT>;
//===----------------------------------------------------------------------===//
// AArch64 Runtime Libcalls
//===----------------------------------------------------------------------===//

View File

@ -25,6 +25,7 @@
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/RuntimeLibcalls.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Use.h"
#include "llvm/InitializePasses.h"
@ -135,17 +136,22 @@ static CallInst::TailCallKind getOverridingTailCallKind(const Function &F) {
return CallInst::TCK_None;
}
static bool lowerObjCCall(Function &F, const char *NewFn,
static bool lowerObjCCall(Function &F, RTLIB::LibcallImpl NewFn,
bool setNonLazyBind = false) {
assert(IntrinsicInst::mayLowerToFunctionCall(F.getIntrinsicID()) &&
"Pre-ISel intrinsics do lower into regular function calls");
if (F.use_empty())
return false;
// FIXME: When RuntimeLibcalls is an analysis, check if the function is really
// supported, and go through RTLIB::Libcall.
const char *NewFnName = RTLIB::RuntimeLibcallsInfo::getLibcallImplName(NewFn);
// If we haven't already looked up this function, check to see if the
// program already contains a function with this name.
Module *M = F.getParent();
FunctionCallee FCache = M->getOrInsertFunction(NewFn, F.getFunctionType());
FunctionCallee FCache =
M->getOrInsertFunction(NewFnName, F.getFunctionType());
if (Function *Fn = dyn_cast<Function>(FCache.getCallee())) {
Fn->setLinkage(F.getLinkage());
@ -501,82 +507,83 @@ bool PreISelIntrinsicLowering::lowerIntrinsics(Module &M) const {
});
break;
case Intrinsic::objc_autorelease:
Changed |= lowerObjCCall(F, "objc_autorelease");
Changed |= lowerObjCCall(F, RTLIB::objc_autorelease);
break;
case Intrinsic::objc_autoreleasePoolPop:
Changed |= lowerObjCCall(F, "objc_autoreleasePoolPop");
Changed |= lowerObjCCall(F, RTLIB::objc_autoreleasePoolPop);
break;
case Intrinsic::objc_autoreleasePoolPush:
Changed |= lowerObjCCall(F, "objc_autoreleasePoolPush");
Changed |= lowerObjCCall(F, RTLIB::objc_autoreleasePoolPush);
break;
case Intrinsic::objc_autoreleaseReturnValue:
Changed |= lowerObjCCall(F, "objc_autoreleaseReturnValue");
Changed |= lowerObjCCall(F, RTLIB::objc_autoreleaseReturnValue);
break;
case Intrinsic::objc_copyWeak:
Changed |= lowerObjCCall(F, "objc_copyWeak");
Changed |= lowerObjCCall(F, RTLIB::objc_copyWeak);
break;
case Intrinsic::objc_destroyWeak:
Changed |= lowerObjCCall(F, "objc_destroyWeak");
Changed |= lowerObjCCall(F, RTLIB::objc_destroyWeak);
break;
case Intrinsic::objc_initWeak:
Changed |= lowerObjCCall(F, "objc_initWeak");
Changed |= lowerObjCCall(F, RTLIB::objc_initWeak);
break;
case Intrinsic::objc_loadWeak:
Changed |= lowerObjCCall(F, "objc_loadWeak");
Changed |= lowerObjCCall(F, RTLIB::objc_loadWeak);
break;
case Intrinsic::objc_loadWeakRetained:
Changed |= lowerObjCCall(F, "objc_loadWeakRetained");
Changed |= lowerObjCCall(F, RTLIB::objc_loadWeakRetained);
break;
case Intrinsic::objc_moveWeak:
Changed |= lowerObjCCall(F, "objc_moveWeak");
Changed |= lowerObjCCall(F, RTLIB::objc_moveWeak);
break;
case Intrinsic::objc_release:
Changed |= lowerObjCCall(F, "objc_release", true);
Changed |= lowerObjCCall(F, RTLIB::objc_release, true);
break;
case Intrinsic::objc_retain:
Changed |= lowerObjCCall(F, "objc_retain", true);
Changed |= lowerObjCCall(F, RTLIB::objc_retain, true);
break;
case Intrinsic::objc_retainAutorelease:
Changed |= lowerObjCCall(F, "objc_retainAutorelease");
Changed |= lowerObjCCall(F, RTLIB::objc_retainAutorelease);
break;
case Intrinsic::objc_retainAutoreleaseReturnValue:
Changed |= lowerObjCCall(F, "objc_retainAutoreleaseReturnValue");
Changed |= lowerObjCCall(F, RTLIB::objc_retainAutoreleaseReturnValue);
break;
case Intrinsic::objc_retainAutoreleasedReturnValue:
Changed |= lowerObjCCall(F, "objc_retainAutoreleasedReturnValue");
Changed |= lowerObjCCall(F, RTLIB::objc_retainAutoreleasedReturnValue);
break;
case Intrinsic::objc_claimAutoreleasedReturnValue:
Changed |= lowerObjCCall(F, "objc_claimAutoreleasedReturnValue");
Changed |= lowerObjCCall(F, RTLIB::objc_claimAutoreleasedReturnValue);
break;
case Intrinsic::objc_retainBlock:
Changed |= lowerObjCCall(F, "objc_retainBlock");
Changed |= lowerObjCCall(F, RTLIB::objc_retainBlock);
break;
case Intrinsic::objc_storeStrong:
Changed |= lowerObjCCall(F, "objc_storeStrong");
Changed |= lowerObjCCall(F, RTLIB::objc_storeStrong);
break;
case Intrinsic::objc_storeWeak:
Changed |= lowerObjCCall(F, "objc_storeWeak");
Changed |= lowerObjCCall(F, RTLIB::objc_storeWeak);
break;
case Intrinsic::objc_unsafeClaimAutoreleasedReturnValue:
Changed |= lowerObjCCall(F, "objc_unsafeClaimAutoreleasedReturnValue");
Changed |=
lowerObjCCall(F, RTLIB::objc_unsafeClaimAutoreleasedReturnValue);
break;
case Intrinsic::objc_retainedObject:
Changed |= lowerObjCCall(F, "objc_retainedObject");
Changed |= lowerObjCCall(F, RTLIB::objc_retainedObject);
break;
case Intrinsic::objc_unretainedObject:
Changed |= lowerObjCCall(F, "objc_unretainedObject");
Changed |= lowerObjCCall(F, RTLIB::objc_unretainedObject);
break;
case Intrinsic::objc_unretainedPointer:
Changed |= lowerObjCCall(F, "objc_unretainedPointer");
Changed |= lowerObjCCall(F, RTLIB::objc_unretainedPointer);
break;
case Intrinsic::objc_retain_autorelease:
Changed |= lowerObjCCall(F, "objc_retain_autorelease");
Changed |= lowerObjCCall(F, RTLIB::objc_retain_autorelease);
break;
case Intrinsic::objc_sync_enter:
Changed |= lowerObjCCall(F, "objc_sync_enter");
Changed |= lowerObjCCall(F, RTLIB::objc_sync_enter);
break;
case Intrinsic::objc_sync_exit:
Changed |= lowerObjCCall(F, "objc_sync_exit");
Changed |= lowerObjCCall(F, RTLIB::objc_sync_exit);
break;
case Intrinsic::exp:
case Intrinsic::exp2: