Skip to content

Commit

Permalink
Move FCalls and runtime exports to the managed callling convetion
Browse files Browse the repository at this point in the history
There are two benefits:
1) CQ - no need to 'save' the shadow stack explicitly.
2) Uniformity - this is the same scheme as upstream uses.

Additionally, this will allows us to implement the shadow stack
saving via the transition frames, if we so choose.
  • Loading branch information
SingleAccretion committed May 17, 2024
1 parent 87b8674 commit 3c13211
Show file tree
Hide file tree
Showing 28 changed files with 441 additions and 357 deletions.
104 changes: 43 additions & 61 deletions src/coreclr/jit/llvm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ enum class EEApiId
GetMangledFilterFuncletName,
GetSignatureForMethodSymbol,
AddCodeReloc,
IsRuntimeImport,
GetPrimitiveTypeForTrivialWasmStruct,
GetTypeDescriptor,
GetAlternativeFunctionName,
Expand Down Expand Up @@ -174,31 +173,6 @@ GCInfo* Llvm::getGCInfo()
return _gcInfo;
}

bool Llvm::callRequiresShadowStackSave(const GenTreeCall* call) const
{
// In general, if the call is itself not managed (does not have a shadow stack argument) **and** may call
// back into managed code, we need to save the shadow stack pointer, so that the RPI frame can pick it up.
// Another case where the save/restore is required is when calling into native runtime code that can trigger
// a GC (canonical example: allocators), to communicate shadow stack bounds to the roots scan.
//
if (call->IsHelperCall())
{
return helperCallRequiresShadowStackSave(call->GetHelperNum());
}

// SPGCT calls are assumed to never RPI by contract.
return !callHasShadowStackArg(call) && !call->IsSuppressGCTransition();
}

bool Llvm::helperCallRequiresShadowStackSave(CorInfoHelpFunc helperFunc) const
{
// Save/restore is needed if the helper doesn't have a shadow stack argument, unless we know it won't call
// back into managed code or has special semantics. TODO-LLVM-CQ: mark (make, if required) more helpers
// "HFIF_NO_RPI_OR_GC".
unsigned helperFlags = getHelperFuncInfo(helperFunc).Flags;
return (helperFlags & (HFIF_SS_ARG | HFIF_NO_RPI_OR_GC)) == HFIF_NONE;
}

bool Llvm::callHasShadowStackArg(const GenTreeCall* call) const
{
return callHasManagedCallingConvention(call);
Expand All @@ -216,12 +190,6 @@ bool Llvm::callHasManagedCallingConvention(const GenTreeCall* call) const
return helperCallHasManagedCallingConvention(call->GetHelperNum());
}

// Runtime imports are effectively unmanaged but are not tracked as such.
if ((call->gtCallType == CT_USER_FUNC) && IsRuntimeImport(call->gtCallMethHnd))
{
return false;
}

return !call->IsUnmanaged();
}

Expand Down Expand Up @@ -275,10 +243,10 @@ bool Llvm::helperCallMayPhysicallyThrow(CorInfoHelpFunc helperFunc) const
{ FUNC(CORINFO_HELP_UMOD) CORINFO_TYPE_UINT, { CORINFO_TYPE_UINT, CORINFO_TYPE_UINT }, HFIF_SS_ARG },

// Implemented in "Runtime\MathHelpers.cpp".
{ FUNC(CORINFO_HELP_LLSH) CORINFO_TYPE_LONG, { CORINFO_TYPE_LONG, CORINFO_TYPE_INT } },
{ FUNC(CORINFO_HELP_LRSH) CORINFO_TYPE_LONG, { CORINFO_TYPE_LONG, CORINFO_TYPE_INT } },
{ FUNC(CORINFO_HELP_LRSZ) CORINFO_TYPE_LONG, { CORINFO_TYPE_LONG, CORINFO_TYPE_INT } },
{ FUNC(CORINFO_HELP_LMUL) CORINFO_TYPE_LONG, { CORINFO_TYPE_LONG, CORINFO_TYPE_LONG } },
{ FUNC(CORINFO_HELP_LLSH) CORINFO_TYPE_LONG, { CORINFO_TYPE_LONG, CORINFO_TYPE_INT }, HFIF_SS_ARG },
{ FUNC(CORINFO_HELP_LRSH) CORINFO_TYPE_LONG, { CORINFO_TYPE_LONG, CORINFO_TYPE_INT }, HFIF_SS_ARG },
{ FUNC(CORINFO_HELP_LRSZ) CORINFO_TYPE_LONG, { CORINFO_TYPE_LONG, CORINFO_TYPE_INT }, HFIF_SS_ARG },
{ FUNC(CORINFO_HELP_LMUL) CORINFO_TYPE_LONG, { CORINFO_TYPE_LONG, CORINFO_TYPE_LONG }, HFIF_SS_ARG },

// Implemented in "CoreLib\src\Internal\Runtime\CompilerHelpers\MathHelpers.cs".
{ FUNC(CORINFO_HELP_LMUL_OVF) CORINFO_TYPE_LONG, { CORINFO_TYPE_LONG, CORINFO_TYPE_LONG }, HFIF_SS_ARG },
Expand All @@ -289,36 +257,36 @@ bool Llvm::helperCallMayPhysicallyThrow(CorInfoHelpFunc helperFunc) const
{ FUNC(CORINFO_HELP_ULMOD) CORINFO_TYPE_ULONG, { CORINFO_TYPE_ULONG, CORINFO_TYPE_ULONG }, HFIF_SS_ARG },

// Implemented in "Runtime\MathHelpers.cpp".
{ FUNC(CORINFO_HELP_LNG2DBL) CORINFO_TYPE_DOUBLE, { CORINFO_TYPE_LONG } },
{ FUNC(CORINFO_HELP_ULNG2DBL) CORINFO_TYPE_DOUBLE, { CORINFO_TYPE_ULONG } },
{ FUNC(CORINFO_HELP_DBL2INT) CORINFO_TYPE_INT, { CORINFO_TYPE_DOUBLE } },
{ FUNC(CORINFO_HELP_LNG2DBL) CORINFO_TYPE_DOUBLE, { CORINFO_TYPE_LONG }, HFIF_SS_ARG },
{ FUNC(CORINFO_HELP_ULNG2DBL) CORINFO_TYPE_DOUBLE, { CORINFO_TYPE_ULONG }, HFIF_SS_ARG },
{ FUNC(CORINFO_HELP_DBL2INT) CORINFO_TYPE_INT, { CORINFO_TYPE_DOUBLE }, HFIF_SS_ARG },

// Implemented in "CoreLib\src\Internal\Runtime\CompilerHelpers\MathHelpers.cs".
{ FUNC(CORINFO_HELP_DBL2INT_OVF) CORINFO_TYPE_INT, { CORINFO_TYPE_DOUBLE }, HFIF_SS_ARG },

// Implemented in "Runtime\MathHelpers.cpp".
{ FUNC(CORINFO_HELP_DBL2LNG) CORINFO_TYPE_LONG, { CORINFO_TYPE_DOUBLE } },
{ FUNC(CORINFO_HELP_DBL2LNG) CORINFO_TYPE_LONG, { CORINFO_TYPE_DOUBLE }, HFIF_SS_ARG },

// Implemented in "CoreLib\src\Internal\Runtime\CompilerHelpers\MathHelpers.cs".
{ FUNC(CORINFO_HELP_DBL2LNG_OVF) CORINFO_TYPE_LONG, { CORINFO_TYPE_DOUBLE }, HFIF_SS_ARG },

// Implemented in "Runtime\MathHelpers.cpp".
{ FUNC(CORINFO_HELP_DBL2UINT) CORINFO_TYPE_UINT, { CORINFO_TYPE_DOUBLE } },
{ FUNC(CORINFO_HELP_DBL2UINT) CORINFO_TYPE_UINT, { CORINFO_TYPE_DOUBLE }, HFIF_SS_ARG },

// Implemented in "CoreLib\src\Internal\Runtime\CompilerHelpers\MathHelpers.cs".
{ FUNC(CORINFO_HELP_DBL2UINT_OVF) CORINFO_TYPE_UINT, { CORINFO_TYPE_DOUBLE }, HFIF_SS_ARG },

// Implemented in "Runtime\MathHelpers.cpp".
{ FUNC(CORINFO_HELP_DBL2ULNG) CORINFO_TYPE_ULONG, { CORINFO_TYPE_DOUBLE } },
{ FUNC(CORINFO_HELP_DBL2ULNG) CORINFO_TYPE_ULONG, { CORINFO_TYPE_DOUBLE }, HFIF_SS_ARG },

// Implemented in "CoreLib\src\Internal\Runtime\CompilerHelpers\MathHelpers.cs".
{ FUNC(CORINFO_HELP_DBL2ULNG_OVF) CORINFO_TYPE_ULONG, { CORINFO_TYPE_DOUBLE }, HFIF_SS_ARG },

// Implemented in "Runtime\MathHelpers.cpp".
{ FUNC(CORINFO_HELP_FLTREM) CORINFO_TYPE_FLOAT, { CORINFO_TYPE_FLOAT, CORINFO_TYPE_FLOAT } },
{ FUNC(CORINFO_HELP_DBLREM) CORINFO_TYPE_DOUBLE, { CORINFO_TYPE_DOUBLE, CORINFO_TYPE_DOUBLE } },
{ FUNC(CORINFO_HELP_FLTROUND) CORINFO_TYPE_FLOAT, { CORINFO_TYPE_FLOAT } },
{ FUNC(CORINFO_HELP_DBLROUND) CORINFO_TYPE_DOUBLE, { CORINFO_TYPE_DOUBLE } },
// Implemented as "fmodf"/"fmod".
{ FUNC(CORINFO_HELP_FLTREM) CORINFO_TYPE_FLOAT, { CORINFO_TYPE_FLOAT, CORINFO_TYPE_FLOAT }, HFIF_NO_RPI_OR_GC },
{ FUNC(CORINFO_HELP_DBLREM) CORINFO_TYPE_DOUBLE, { CORINFO_TYPE_DOUBLE, CORINFO_TYPE_DOUBLE }, HFIF_NO_RPI_OR_GC },
{ FUNC(CORINFO_HELP_FLTROUND) },
{ FUNC(CORINFO_HELP_DBLROUND) },

// Runtime export, implemented in "Runtime.Base\src\System\Runtime\RuntimeExports.cs".
{ FUNC(CORINFO_HELP_NEWFAST) CORINFO_TYPE_CLASS, { CORINFO_TYPE_PTR }, HFIF_SS_ARG },
Expand Down Expand Up @@ -380,7 +348,7 @@ bool Llvm::helperCallMayPhysicallyThrow(CorInfoHelpFunc helperFunc) const
{ FUNC(CORINFO_HELP_RETHROW) CORINFO_TYPE_VOID, { CORINFO_TYPE_PTR }, HFIF_SS_ARG },

// Implemented in "Runtime\MiscHelpers.cpp".
{ FUNC(CORINFO_HELP_USER_BREAKPOINT) CORINFO_TYPE_VOID, { } },
{ FUNC(CORINFO_HELP_USER_BREAKPOINT) CORINFO_TYPE_VOID, { }, HFIF_SS_ARG},

// Implemented in "Runtime.Base\src\System\ThrowHelpers.cs".
{ FUNC(CORINFO_HELP_RNGCHKFAIL) CORINFO_TYPE_VOID, { }, HFIF_SS_ARG },
Expand All @@ -393,7 +361,7 @@ bool Llvm::helperCallMayPhysicallyThrow(CorInfoHelpFunc helperFunc) const
{ FUNC(CORINFO_HELP_VERIFICATION) },

// Implemented in "Runtime\EHHelpers.cpp".
{ FUNC(CORINFO_HELP_FAIL_FAST) CORINFO_TYPE_VOID, { }, HFIF_NO_RPI_OR_GC },
{ FUNC(CORINFO_HELP_FAIL_FAST) CORINFO_TYPE_VOID, { }, HFIF_SS_ARG | HFIF_NO_RPI_OR_GC },

// NYI in NativeAOT.
{ FUNC(CORINFO_HELP_METHOD_ACCESS_EXCEPTION) },
Expand All @@ -415,10 +383,10 @@ bool Llvm::helperCallMayPhysicallyThrow(CorInfoHelpFunc helperFunc) const
{ FUNC(CORINFO_HELP_STOP_FOR_GC) },

// (Not) implemented in "Runtime\portable.cpp".
{ FUNC(CORINFO_HELP_POLL_GC) CORINFO_TYPE_VOID, { } },
{ FUNC(CORINFO_HELP_POLL_GC) CORINFO_TYPE_VOID, { }, HFIF_SS_ARG},

// Debug-only helpers, implemented in "Runtime\wasm\GcStress.cpp".
{ FUNC(CORINFO_HELP_STRESS_GC) CORINFO_TYPE_BYREF, { CORINFO_TYPE_BYREF, CORINFO_TYPE_PTR } },
{ FUNC(CORINFO_HELP_STRESS_GC) CORINFO_TYPE_BYREF, { CORINFO_TYPE_BYREF, CORINFO_TYPE_PTR }, HFIF_SS_ARG },
{ FUNC(CORINFO_HELP_CHECK_OBJ) CORINFO_TYPE_CLASS, { CORINFO_TYPE_CLASS }, HFIF_NO_RPI_OR_GC },

// Write barriers, implemented in "Runtime\portable.cpp".
Expand Down Expand Up @@ -493,7 +461,7 @@ bool Llvm::helperCallMayPhysicallyThrow(CorInfoHelpFunc helperFunc) const
{ FUNC(CORINFO_HELP_MEMCPY) CORINFO_TYPE_VOID, { CORINFO_TYPE_PTR, CORINFO_TYPE_PTR, CORINFO_TYPE_NATIVEUINT }, HFIF_SS_ARG },

// Implemented as plain "memset".
{ FUNC(CORINFO_HELP_NATIVE_MEMSET) CORINFO_TYPE_VOID, { CORINFO_TYPE_PTR, CORINFO_TYPE_INT, CORINFO_TYPE_NATIVEUINT } },
{ FUNC(CORINFO_HELP_NATIVE_MEMSET) CORINFO_TYPE_VOID, { CORINFO_TYPE_PTR, CORINFO_TYPE_INT, CORINFO_TYPE_NATIVEUINT }, HFIF_NO_RPI_OR_GC },

// Not used in NativeAOT.
{ FUNC(CORINFO_HELP_RUNTIMEHANDLE_METHOD) },
Expand Down Expand Up @@ -528,7 +496,7 @@ bool Llvm::helperCallMayPhysicallyThrow(CorInfoHelpFunc helperFunc) const
{ FUNC(CORINFO_HELP_READYTORUN_THREADSTATIC_BASE) CORINFO_TYPE_PTR, { }, HFIF_SS_ARG },
{ FUNC(CORINFO_HELP_READYTORUN_THREADSTATIC_BASE_NOCTOR) CORINFO_TYPE_PTR, { }, HFIF_SS_ARG },
{ FUNC(CORINFO_HELP_READYTORUN_NONGCTHREADSTATIC_BASE) CORINFO_TYPE_PTR, { }, HFIF_SS_ARG },
{ FUNC(CORINFO_HELP_READYTORUN_VIRTUAL_FUNC_PTR) CORINFO_TYPE_PTR, { CORINFO_TYPE_CLASS } },
{ FUNC(CORINFO_HELP_READYTORUN_VIRTUAL_FUNC_PTR) CORINFO_TYPE_PTR, { CORINFO_TYPE_CLASS }, HFIF_SS_ARG },
{ FUNC(CORINFO_HELP_READYTORUN_GENERIC_HANDLE) CORINFO_TYPE_PTR, { CORINFO_TYPE_PTR }, HFIF_SS_ARG | HFIF_THROW_OR_NO_RPI_OR_GC },
{ FUNC(CORINFO_HELP_READYTORUN_DELEGATE_CTOR) CORINFO_TYPE_VOID, { CORINFO_TYPE_CLASS, CORINFO_TYPE_CLASS, CORINFO_TYPE_PTR }, HFIF_SS_ARG | HFIF_VAR_ARG },
{ FUNC(CORINFO_HELP_READYTORUN_GENERIC_STATIC_BASE) CORINFO_TYPE_PTR, { CORINFO_TYPE_PTR }, HFIF_SS_ARG },
Expand Down Expand Up @@ -571,10 +539,10 @@ bool Llvm::helperCallMayPhysicallyThrow(CorInfoHelpFunc helperFunc) const
// [R]PI helpers, implemented in "Runtime\thread.cpp".
{ FUNC(CORINFO_HELP_JIT_PINVOKE_BEGIN) CORINFO_TYPE_VOID, { CORINFO_TYPE_PTR }, HFIF_SS_ARG | HFIF_NO_RPI_OR_GC },
{ FUNC(CORINFO_HELP_JIT_PINVOKE_END) CORINFO_TYPE_VOID, { CORINFO_TYPE_PTR }, HFIF_NO_RPI_OR_GC },
{ FUNC(CORINFO_HELP_JIT_REVERSE_PINVOKE_ENTER) CORINFO_TYPE_VOID, { CORINFO_TYPE_PTR } },
{ FUNC(CORINFO_HELP_JIT_REVERSE_PINVOKE_ENTER_TRACK_TRANSITIONS) CORINFO_TYPE_VOID, { CORINFO_TYPE_PTR } },
{ FUNC(CORINFO_HELP_JIT_REVERSE_PINVOKE_ENTER) CORINFO_TYPE_VOID, { CORINFO_TYPE_PTR }, HFIF_SS_ARG },
{ FUNC(CORINFO_HELP_JIT_REVERSE_PINVOKE_ENTER_TRACK_TRANSITIONS) },
{ FUNC(CORINFO_HELP_JIT_REVERSE_PINVOKE_EXIT) CORINFO_TYPE_VOID, { CORINFO_TYPE_PTR }, HFIF_NO_RPI_OR_GC },
{ FUNC(CORINFO_HELP_JIT_REVERSE_PINVOKE_EXIT_TRACK_TRANSITIONS) CORINFO_TYPE_VOID, { CORINFO_TYPE_PTR } },
{ FUNC(CORINFO_HELP_JIT_REVERSE_PINVOKE_EXIT_TRACK_TRANSITIONS) },

// Implemented in "CoreLib\src\System\Runtime\TypeLoaderExports.cs".
{ FUNC(CORINFO_HELP_GVMLOOKUP_FOR_SLOT) CORINFO_TYPE_NATIVEINT, { CORINFO_TYPE_CLASS, CORINFO_TYPE_RT_HANDLE }, HFIF_SS_ARG }, // Oddity: IntPtr used for a pointer.
Expand Down Expand Up @@ -611,6 +579,25 @@ bool Llvm::helperCallMayPhysicallyThrow(CorInfoHelpFunc helperFunc) const
// Make sure our array is up-to-date.
static_assert_no_msg(ArrLen(s_infos) == CORINFO_HELP_COUNT);

#ifdef DEBUG
static bool s_infosVerified = false;
if (!s_infosVerified)
{
for (const HelperFuncInfo& info : s_infos)
{
if (info.IsInitialized())
{
unsigned flags = info.Flags;

// Only helpers that will never call managed code are allowed to not have the shadow stack argument.
assert(((flags & HFIF_SS_ARG) != 0) || ((flags & HFIF_NO_RPI_OR_GC) != 0));
}
}

s_infosVerified = true;
}
#endif // DEBUG

assert(helperFunc < CORINFO_HELP_COUNT);
const HelperFuncInfo& info = s_infos[helperFunc];

Expand Down Expand Up @@ -812,11 +799,6 @@ void Llvm::AddCodeReloc(void* handle)
CallEEApi<EEApiId::AddCodeReloc, void>(m_pEECorInfo, handle);
}

bool Llvm::IsRuntimeImport(CORINFO_METHOD_HANDLE methodHandle) const
{
return CallEEApi<EEApiId::IsRuntimeImport, uint32_t>(m_pEECorInfo, methodHandle) != 0;
}

CorInfoType Llvm::GetPrimitiveTypeForTrivialWasmStruct(CORINFO_CLASS_HANDLE structHandle)
{
return CallEEApi<EEApiId::GetPrimitiveTypeForTrivialWasmStruct, CorInfoType>(m_pEECorInfo, structHandle);
Expand Down
3 changes: 0 additions & 3 deletions src/coreclr/jit/llvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -342,8 +342,6 @@ class Llvm

GCInfo* getGCInfo();

bool callRequiresShadowStackSave(const GenTreeCall* call) const;
bool helperCallRequiresShadowStackSave(CorInfoHelpFunc helperFunc) const;
bool callHasShadowStackArg(const GenTreeCall* call) const;
bool helperCallHasShadowStackArg(CorInfoHelpFunc helperFunc) const;
bool callHasManagedCallingConvention(const GenTreeCall* call) const;
Expand All @@ -369,7 +367,6 @@ class Llvm
const char* GetMangledFilterFuncletName(unsigned index);
bool GetSignatureForMethodSymbol(CORINFO_GENERIC_HANDLE symbolHandle, CORINFO_SIG_INFO* pSig);
void AddCodeReloc(void* handle);
bool IsRuntimeImport(CORINFO_METHOD_HANDLE methodHandle) const;
CorInfoType GetPrimitiveTypeForTrivialWasmStruct(CORINFO_CLASS_HANDLE structHandle);
void GetTypeDescriptor(CORINFO_CLASS_HANDLE typeHandle, TypeDescriptor* pTypeDescriptor);
const char* GetAlternativeFunctionName();
Expand Down
66 changes: 38 additions & 28 deletions src/coreclr/jit/llvmcodegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,7 @@ void Llvm::initializeFunctions()
{
const char* mangledName = GetMangledMethodName(m_info->compMethodHnd);
Function* rootLlvmFunction = getOrCreateKnownLlvmFunction(mangledName, [=]() { return createFunctionType(); });
if (!rootLlvmFunction->isDeclaration())
{
BADCODE("Duplicate definition");
}
assert(rootLlvmFunction->isDeclaration());

// First function is always the root.
m_functions = new (_compiler->getAllocator(CMK_Codegen)) FunctionInfo[_compiler->compFuncCount()]();
Expand Down Expand Up @@ -794,10 +791,31 @@ void Llvm::fillPhis()
void Llvm::generateAuxiliaryArtifacts()
{
// Currently, the only auxiliary artifact we may need is an alternative exported name for the compiled function.
const char* alternativeName = GetAlternativeFunctionName();
if (alternativeName != nullptr)
{
llvm::GlobalAlias::create(alternativeName, getRootLlvmFunction());
StringRef alternativeName = GetAlternativeFunctionName();
if (!alternativeName.empty())
{
Function* llvmFuncDef = getRootLlvmFunction();
llvm::GlobalValue* existingDecl = m_context->Module.getNamedValue(alternativeName);
if (existingDecl != nullptr)
{
// We already have something under this name. Currenly, this can only be a function declaration, e. g.
// if something referenced a helper using this alternative name, which is usually the unmangled one,
// so it's pretty common. We need to replace the declaration with the defined function to avoid double
// definition problems.
assert(llvm::isa<Function>(existingDecl));
if (!existingDecl->isDeclaration())
{
// E. g. two different UCOs exported under the same name. This BADCODE is not very deterministic,
// since it depends on whether we happen to have the two offending functions in the same module
// or not. Ideally, we would devise a more robust scheme for dealing with this error.
BADCODE("Double definition");
}

existingDecl->replaceAllUsesWith(llvmFuncDef);
existingDecl->eraseFromParent();
}

llvm::GlobalAlias::create(alternativeName, llvmFuncDef);
}
}

Expand Down Expand Up @@ -1752,14 +1770,6 @@ void Llvm::buildCall(GenTreeCall* call)
argVec.Push(argValue);
}

// We may come back into managed from the unmanaged call so store the shadow stack. Note that for regular unmanaged
// calls, we fold the shadow stack save into the transition helper call, and so don't need to do anything here.
if (!call->IsUnmanaged() && callRequiresShadowStackSave(call))
{
// TODO-LLVM: set the correct shadow stack for shadow tail calls here.
emitHelperCall(CORINFO_HELP_LLVM_SET_SHADOW_STACK_TOP, getShadowStackForCallee());
}

llvm::FunctionCallee llvmFuncCallee = consumeCallTarget(call);
llvm::CallBase* callValue = emitCallOrInvoke(llvmFuncCallee, AsRef(argVec), mayPhysicallyThrow(call));

Expand Down Expand Up @@ -2541,12 +2551,6 @@ llvm::CallBase* Llvm::emitHelperCall(CorInfoHelpFunc helperFunc, ArrayRef<Value*
annotateHelperFunction(helperFunc, llvmFunc);
});

if (helperCallRequiresShadowStackSave(helperFunc))
{
// TODO-LLVM: set the correct shadow stack for shadow tail calls here.
emitHelperCall(CORINFO_HELP_LLVM_SET_SHADOW_STACK_TOP, getShadowStackForCallee());
}

llvm::CallBase* call;
if (helperCallHasShadowStackArg(helperFunc))
{
Expand Down Expand Up @@ -2757,7 +2761,6 @@ FunctionType* Llvm::createFunctionTypeForCall(GenTreeCall* call)

FunctionType* Llvm::createFunctionTypeForHelper(CorInfoHelpFunc helperFunc)
{
const bool isManagedHelper = helperCallHasManagedCallingConvention(helperFunc);
const HelperFuncInfo& helperInfo = getHelperFuncInfo(helperFunc);

ArrayStack<Type*> argVec(_compiler->getAllocator(CMK_Codegen));
Expand Down Expand Up @@ -2841,14 +2844,21 @@ void Llvm::annotateHelperFunction(CorInfoHelpFunc helperFunc, Function* llvmFunc
Function* Llvm::getOrCreateKnownLlvmFunction(
StringRef name, std::function<FunctionType*()> createFunctionType, std::function<void(Function*)> annotateFunction)
{
Function* llvmFunc = m_context->Module.getFunction(name);
if (llvmFunc == nullptr)
llvm::Constant* llvmFuncOrAlias = m_context->Module.getNamedValue(name);
if (llvmFuncOrAlias != nullptr)
{
assert(m_context->Module.getNamedValue(name) == nullptr); // No duplicate symbols!
llvmFunc = Function::Create(createFunctionType(), Function::ExternalLinkage, name, m_context->Module);
annotateFunction(llvmFunc);
// TODO-LLVM: we will miss annotating helpers that come through this path.
if (llvm::isa<llvm::GlobalAlias>(llvmFuncOrAlias))
{
// This must be the alias created by "generateAuxiliaryArtifacts".
llvmFuncOrAlias = llvm::cast<llvm::GlobalAlias>(llvmFuncOrAlias)->getAliasee();
}

return llvm::cast<Function>(llvmFuncOrAlias);
}

Function* llvmFunc = Function::Create(createFunctionType(), Function::ExternalLinkage, name, m_context->Module);
annotateFunction(llvmFunc);
return llvmFunc;
}

Expand Down
9 changes: 0 additions & 9 deletions src/coreclr/nativeaot/Bootstrap/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,18 +112,9 @@ extern "C" void* PalGetModuleHandleFromPointer(void* pointer);
#define MANAGED_RUNTIME_EXPORT_NAME(_name) _name
#define CDECL __cdecl
#else
// The runtime assumes classlib exports have a managed calling convention.
// For WASM, however, they are exported with the native calling convention
// by default so we must explicitly use the managed entrypoint here.
#ifdef HOST_WASM
#define MANAGED_RUNTIME_EXPORT(_name) \
extern "C" void _name##_Managed();
#define MANAGED_RUNTIME_EXPORT_NAME(_name) _name##_Managed
#else // !HOST_WASM
#define MANAGED_RUNTIME_EXPORT(_name) \
extern "C" void _name();
#define MANAGED_RUNTIME_EXPORT_NAME(_name) _name
#endif // !HOST_WASM
#define CDECL
#endif

Expand Down
Loading

0 comments on commit 3c13211

Please sign in to comment.