зеркало из https://github.com/dotnet/llilc.git
Ensure generic context is kept alive.
This gets us the next part of #40. We use `llvm.frameescape` to indicate that the context-bearing local's address has escaped. This intrinsic requires that the function have a frame poniter, so disable FPO for these methods. We're still missing the ability to report the context back to the EE via the GC info. Opened Issue #336 for this. Also fixed a bug in the static field address computation where we weren't capturing the updated helper call result.
This commit is contained in:
Родитель
95b859a749
Коммит
41ebdae168
|
@ -179,7 +179,7 @@ CorJitResult LLILCJit::compileMethod(ICorJitInfo *JitInfo,
|
|||
Builder.setOptLevel(CodeGenOpt::Level::Default);
|
||||
} else {
|
||||
Builder.setOptLevel(CodeGenOpt::Level::None);
|
||||
Options.NoFramePointerElim = 1;
|
||||
Options.NoFramePointerElim = true;
|
||||
}
|
||||
|
||||
Builder.setTargetOptions(Options);
|
||||
|
|
|
@ -4356,10 +4356,11 @@ ReaderBase::rdrGetStaticFieldAddress(CORINFO_RESOLVED_TOKEN *ResolvedToken,
|
|||
//
|
||||
// Again, we happen to know that the results of these helper calls should
|
||||
// be interpreted as interior GC pointers.
|
||||
SharedStaticsBaseNode = makePtrNode(Reader_PtrGcInterior);
|
||||
IRNode *TempNode = makePtrNode(Reader_PtrGcInterior);
|
||||
|
||||
// Now make the call and attach the arguments.
|
||||
callHelper(FieldInfo->helper, SharedStaticsBaseNode, ClassHandleNode);
|
||||
SharedStaticsBaseNode =
|
||||
callHelper(FieldInfo->helper, TempNode, ClassHandleNode);
|
||||
} else {
|
||||
CorInfoHelpFunc HelperId = FieldInfo->helper;
|
||||
CORINFO_CLASS_HANDLE Class = ResolvedToken->hClass;
|
||||
|
|
|
@ -366,21 +366,43 @@ void GenIR::readerPostPass(bool IsImportOnly) {
|
|||
|
||||
// If the generic context must be kept live,
|
||||
// insert the necessary code to make it so.
|
||||
Value *ContextAddress = nullptr;
|
||||
|
||||
if (KeepGenericContextAlive) {
|
||||
Value *ContextLocalAddress = nullptr;
|
||||
CorInfoOptions Options = JitContext->MethodInfo->options;
|
||||
|
||||
if (Options & CORINFO_GENERICS_CTXT_FROM_THIS) {
|
||||
// The this argument might be modified in the method body, so
|
||||
// make a copy of the incoming this in a scratch local.
|
||||
ASSERT(HasThis);
|
||||
ContextAddress = Arguments[0];
|
||||
throw NotYetImplementedException("keep alive generic context: this");
|
||||
Value *This = thisObj();
|
||||
ContextLocalAddress = createTemporary(This->getType());
|
||||
makeStoreNonNull(This, ContextLocalAddress, false);
|
||||
} else {
|
||||
// We know the type arg is unmodified so we can use its initial
|
||||
// spilled value location for reporting.
|
||||
ASSERT(Options & (CORINFO_GENERICS_CTXT_FROM_METHODDESC |
|
||||
CORINFO_GENERICS_CTXT_FROM_METHODTABLE));
|
||||
ASSERT(HasTypeParameter);
|
||||
ContextAddress = Arguments[HasThis ? (HasVarargsToken ? 2 : 1) : 0];
|
||||
throw NotYetImplementedException("keep alive generic context: !this");
|
||||
ContextLocalAddress = Arguments[HasThis ? (HasVarargsToken ? 2 : 1) : 0];
|
||||
}
|
||||
|
||||
// Indicate that the context location's address escapes by inserting a call
|
||||
// to llvm.frameescape at the end of the allocas in the entry block.
|
||||
IRBuilder<>::InsertPoint InsertPt = LLVMBuilder->saveIP();
|
||||
LLVMBuilder->SetInsertPoint(TempInsertionPoint->getNextNode());
|
||||
Value *FrameEscape = Intrinsic::getDeclaration(JitContext->CurrentModule,
|
||||
Intrinsic::frameescape);
|
||||
Value *Args[] = {ContextLocalAddress};
|
||||
LLVMBuilder->CreateCall(FrameEscape, Args);
|
||||
// Don't move TempInsertionPoint up since what we added was not an alloca
|
||||
LLVMBuilder->restoreIP(InsertPt);
|
||||
|
||||
// This method now requires a frame pointer.
|
||||
TargetMachine *TM = JitContext->EE->getTargetMachine();
|
||||
TM->Options.NoFramePointerElim = true;
|
||||
|
||||
// TODO: we must convey the offset of this local to the runtime
|
||||
// via the GC encoding.
|
||||
}
|
||||
|
||||
// Cleanup the memory we've been using.
|
||||
|
|
Загрузка…
Ссылка в новой задаче