Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NativeAOT-LLVM]: Initial support for IsVirtualVtable calls #1768

Merged
merged 9 commits into from
Feb 10, 2022
7 changes: 7 additions & 0 deletions src/coreclr/jit/indirectcalltransformer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,14 @@ class IndirectCallTransformer
}

private:
// Wasm stores function pointers as indices in a function table
#if defined(TARGET_WASM32)
const int FAT_POINTER_MASK = 0x80000000;
#elif defined(TARGET_WASM64)
const int FAT_POINTER_MASK = 0x8000000000000000;
#else
const int FAT_POINTER_MASK = 0x2;
#endif // TARGET_WASM

GenTree* fptrAddress;
var_types pointerType;
Expand Down
156 changes: 100 additions & 56 deletions src/coreclr/jit/llvm.cpp

Large diffs are not rendered by default.

14 changes: 8 additions & 6 deletions src/coreclr/jit/llvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ extern "C" void registerLlvmCallbacks(void* thisPtr,
const char* dataLayout,
const char* (*getMangledMethodNamePtr)(void*, CORINFO_METHOD_STRUCT_*),
const char* (*getMangledSymbolNamePtr)(void*, void*),
const char* (*getMangledSymbolNameFromHelperTargetPtr)(void*, void*),
const char* (*getTypeName)(void*, CORINFO_CLASS_HANDLE),
const char* (*addCodeReloc)(void*, void*),
const uint32_t (*isRuntimeImport)(void*, CORINFO_METHOD_STRUCT_*),
Expand Down Expand Up @@ -153,15 +154,15 @@ class Llvm
void emitDoNothingCall();
void endImportingBasicBlock(BasicBlock* block);
[[noreturn]] void failFunctionCompilation();
void failUnsupportedCalls(GenTreeCall* callNode, CORINFO_SIG_INFO &calleeSigInfo);
void failUnsupportedCalls(GenTreeCall* callNode, CORINFO_SIG_INFO* calleeSigInfo);
void fillPhis();
llvm::Instruction* getCast(llvm::Value* source, Type* targetType);
void generateProlog();
CorInfoType getCorInfoTypeForArg(CORINFO_SIG_INFO& sigInfo, CORINFO_ARG_LIST_HANDLE& arg, CORINFO_CLASS_HANDLE* clsHnd);
CorInfoType getCorInfoTypeForArg(CORINFO_SIG_INFO* sigInfo, CORINFO_ARG_LIST_HANDLE& arg, CORINFO_CLASS_HANDLE* clsHnd);
llvm::FunctionType* getFunctionType();
llvm::FunctionType* getFunctionTypeForCall(GenTreeCall* callNode);
llvm::FunctionType* createFunctionTypeForCall(GenTreeCall* call);
Value* getGenTreeValue(GenTree* node);
LlvmArgInfo getLlvmArgInfoForArgIx(CORINFO_SIG_INFO& sigInfo, unsigned int lclNum);
LlvmArgInfo getLlvmArgInfoForArgIx(unsigned int lclNum);
llvm::BasicBlock* getLLVMBasicBlockForBlock(BasicBlock* block);
Type* getLlvmTypeForCorInfoType(CorInfoType corInfoType, CORINFO_CLASS_HANDLE classHnd);
Type* getLlvmTypeForParameterType(CORINFO_CLASS_HANDLE classHnd);
Expand All @@ -170,6 +171,7 @@ class Llvm
int getLocalOffsetAtIndex(GenTreeLclVar* lclVar);
Value* getLocalVarAddress(GenTreeLclVar* lclVar);
struct DebugMetadata getOrCreateDebugMetadata(const char* documentFileName);
llvm::Function* getOrCreateLlvmFunction(const char* symbolName, GenTreeCall* call);
Value* getShadowStackForCallee();
unsigned int getSpillOffsetAtIndex(unsigned int index, unsigned int offset);
Value* getSsaLocalForPhi(unsigned lclNum, unsigned ssaNum);
Expand All @@ -181,8 +183,8 @@ class Llvm
void importStoreInd(GenTreeStoreInd* storeIndOp);
Value* localVar(GenTreeLclVar* lclVar);

GenTreeCall::Use* lowerCallReturn(GenTreeCall* callNode, CORINFO_SIG_INFO& calleeSigInfo, GenTreeCall::Use* lastArg);
void lowerCallToShadowStack(GenTreeCall* callNode, CORINFO_SIG_INFO& calleeSigInfo);
GenTreeCall::Use* lowerCallReturn(GenTreeCall* callNode, CORINFO_SIG_INFO* calleeSigInfo, GenTreeCall::Use* lastArg);
void lowerCallToShadowStack(GenTreeCall* callNode, CORINFO_SIG_INFO* calleeSigInfo);
void lowerToShadowStack();

Value* mapGenTreeToValue(GenTree* genTree, Value* valueRef);
Expand Down
23 changes: 21 additions & 2 deletions src/coreclr/jit/ssabuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -598,9 +598,28 @@ void SsaBuilder::InsertPhiToRationalIRForm(BasicBlock* block, unsigned lclNum)
GenTree* storeLcl = m_pCompiler->gtNewStoreLclVar(lclNum, phi);

LIR::Range& lirRange = LIR::AsRange(block);
GenTree* firstNode = lirRange.FirstNode();
GenTree* firstNode = lirRange.FirstNode();

// cant insert the storeLcl bewteen phis so find first non-phi node
GenTree* nonPhiNode = nullptr;
for (GenTree* node : lirRange)
{
if (!node->IsPhiNode())
{
nonPhiNode = node;
break;
}
}

lirRange.InsertBefore(firstNode, phi);
lirRange.InsertAfter(phi, storeLcl);
if (nonPhiNode == nullptr)
{
lirRange.InsertAfter(phi, storeLcl);
}
else
{
lirRange.InsertBefore(nonPhiNode, storeLcl);
}

JITDUMP("Added PHI definition for V%02u at start of " FMT_BB ".\n", lclNum, block->bbNum);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,8 @@ private unsafe void CompileSingleMethod(CorInfoImpl corInfo, LLVMMethodCodeNode
{
if (GetMethodIL(method).GetExceptionRegions().Length == 0)
{
var sig = method.Signature;
// this could be inlined, by the local makes debugging easier
var mangledName = NodeFactory.NameMangler.GetMangledMethodName(method).ToString();
var sig = method.Signature;
corInfo.RegisterLlvmCallbacks((IntPtr)Unsafe.AsPointer(ref corInfo), _outputFile,
Module.Target,
Module.DataLayout);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Internal.IL;
using Internal.Text;
using Internal.TypeSystem;
using Internal.TypeSystem.Ecma;

namespace Internal.JitInterface
{
Expand All @@ -25,6 +26,15 @@ public static void addCodeReloc(IntPtr thisHandle, void* handle)
var helperNode = node as ReadyToRunHelperNode;
if (helperNode != null)
{
if (helperNode.Id == ReadyToRunHelperId.VirtualCall)
{
MethodDesc virtualCallTarget = (MethodDesc)helperNode.Target;
_this._codeRelocs.Add(new Relocation(RelocType.IMAGE_REL_BASED_REL32, 0,
_this._compilation.NodeFactory.MethodEntrypoint(virtualCallTarget)));

return;
}

MetadataType target = (MetadataType)helperNode.Target;
switch (helperNode.Id)
{
Expand Down Expand Up @@ -105,6 +115,21 @@ private static byte[] AppendNullByte(byte[] inputArray)
return (byte*)_this.GetPin(sb.UnderlyingArray);
}

[UnmanagedCallersOnly]
public static byte* getSymbolMangledNameFromHelperTarget(IntPtr thisHandle, void* handle)
{
var _this = GetThis(thisHandle);

var node = (ReadyToRunHelperNode)_this.HandleToObject((IntPtr)handle);
var method = node.Target as MethodDesc;

// Abstract methods must require a lookup so no point passing the abstract name back
if (method.IsAbstract || method.IsVirtual) return null;

Utf8StringBuilder sb = new Utf8StringBuilder();
return (byte*)_this.GetPin(AppendNullByte(_this._compilation.NameMangler.GetMangledMethodName(method).UnderlyingArray));
}

// IL backend does not use the mangled name. The unmangled name is easier to read.
[UnmanagedCallersOnly]
public static byte* getTypeName(IntPtr thisHandle, CORINFO_CLASS_STRUCT_* structHnd)
Expand All @@ -120,7 +145,6 @@ private static byte[] AppendNullByte(byte[] inputArray)
return (byte*)_this.GetPin(sb.UnderlyingArray);
}


[UnmanagedCallersOnly]
public static uint isRuntimeImport(IntPtr thisHandle, CORINFO_METHOD_STRUCT_* ftn)
{
Expand Down Expand Up @@ -267,6 +291,7 @@ public static CorInfoTypeWithMod getParameterType(IntPtr thisHandle, CORINFO_CLA
private extern static void registerLlvmCallbacks(IntPtr thisHandle, byte* outputFileName, byte* triple, byte* dataLayout,
delegate* unmanaged<IntPtr, CORINFO_METHOD_STRUCT_*, byte*> getMangedMethodNamePtr,
delegate* unmanaged<IntPtr, void*, byte*> getSymbolMangledName,
delegate* unmanaged<IntPtr, void*, byte*> getSymbolMangledNameFromHelperTarget,
delegate* unmanaged<IntPtr, CORINFO_CLASS_STRUCT_*, byte*> getTypeName,
delegate* unmanaged<IntPtr, void*, void> addCodeReloc,
delegate* unmanaged<IntPtr, CORINFO_METHOD_STRUCT_*, uint> isRuntimeImport,
Expand All @@ -286,6 +311,7 @@ public void RegisterLlvmCallbacks(IntPtr corInfoPtr, string outputFileName, stri
(byte*)GetPin(StringToUTF8(dataLayout)),
&getMangledMethodName,
&getSymbolMangledName,
&getSymbolMangledNameFromHelperTarget,
&getTypeName,
&addCodeReloc,
&isRuntimeImport,
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/tools/aot/ILCompiler/ILCompiler.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AssemblyName>ilc</AssemblyName>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
Expand Down