Call JIT_GCPoll() runtime helper from gc.safepoint_poll()

gc.safepoint_poll() helper required by Safepoint placement pass was an
empty function. This change fixes this to call the correct runtime helper
to perform the CLR GC Poll.

The current strategy is to use an unconditional call to the GCPoll helper.
Inlining the GCPoll helper is future work.

Issue #32
This commit is contained in:
Swaroop Sridhar 2015-04-07 20:40:33 -07:00
Родитель a2ce25f986
Коммит 4058c27ed9
4 изменённых файлов: 51 добавлений и 46 удалений

Просмотреть файл

@ -230,13 +230,6 @@ private:
/// \returns \p true if GC info was successfully reported.
bool outputGCInfo(LLILCJitContext *JitContext);
/// Create the @gc.safepoint_poll() method
/// Creates the @gc.safepoint_poll() method and insertes it into the
/// current module. This helper is required by the LLVM GC-Statepoint
/// insertion phase.
/// \param Context JitContext Context record for the current jit request.
void createSafepointPoll(LLILCJitContext *Context);
public:
/// A pointer to the singleton jit instance.
static LLILCJit *TheJit;

Просмотреть файл

@ -1187,6 +1187,12 @@ private:
/// \brief Insert IR to setup the security object
void insertIRForSecurityObject();
/// \brief Create the @gc.safepoint_poll() method
/// Creates the @gc.safepoint_poll() method and insertes it into the
/// current module. This helper is required by the LLVM GC-Statepoint
/// insertion phase.
void createSafepointPoll();
private:
LLILCJitContext *JitContext;

Просмотреть файл

@ -179,10 +179,6 @@ CorJitResult LLILCJit::compileMethod(ICorJitInfo *JitInfo,
std::unique_ptr<Module> M = Context.getModuleForMethod(MethodInfo);
Context.CurrentModule = M.get();
if (!ShouldUseConservativeGC) {
createSafepointPoll(&Context);
}
EngineBuilder Builder(std::move(M));
std::string ErrStr;
Builder.setErrorStr(&ErrStr);
@ -269,41 +265,6 @@ CorJitResult LLILCJit::compileMethod(ICorJitInfo *JitInfo,
return Result;
}
// Insert the special @gc.safepoint_poll function
//
// This helper is required by the LLVM GC-Statepoint insertion phase.
// Statepoint lowering inlines the body of @gc.safepoint_poll function
// at function entry and at loop-back-edges.
//
// The following code is inserted into the module:
//
// define void @gc.safepoint_poll()
// {
// entry:
// ret void
// }
//
// TODO: Replace this empty safepoint_poll function with a CLR-specific
// sequence that checks if a GC is pending, and calls/branches
// to a runtime helper when necessary.
void LLILCJit::createSafepointPoll(LLILCJitContext *Context) {
Module *M = Context->CurrentModule;
FunctionType *VoidFnType =
FunctionType::get(Type::getVoidTy(M->getContext()), false);
Function *SafepointPoll = dyn_cast<Function>(
M->getOrInsertFunction("gc.safepoint_poll", VoidFnType));
assert(SafepointPoll->empty());
BasicBlock *EntryBlock =
BasicBlock::Create(*Context->LLVMContext, "entry", SafepointPoll);
ReturnInst::Create(*Context->LLVMContext, EntryBlock);
}
std::unique_ptr<Module>
LLILCJitContext::getModuleForMethod(CORINFO_METHOD_INFO *MethodInfo) {
// Grab name info from the EE.

Просмотреть файл

@ -269,6 +269,10 @@ void GenIR::readerPrePass(uint8_t *Buffer, uint32_t NumBytes) {
ASSERTNR(UNREACHED);
}
if (!LLILCJit::TheJit->ShouldUseConservativeGC) {
createSafepointPoll();
}
CORINFO_METHOD_HANDLE MethodHandle = JitContext->MethodInfo->ftn;
// Capture low-level info about the return type for use in Return.
@ -662,6 +666,47 @@ uint32_t GenIR::convertReaderAlignment(ReaderAlignType ReaderAlignment) {
return Result;
}
// Create the special @gc.safepoint_poll function
//
// This helper is required by the LLVM GC-Statepoint insertion phase.
// Statepoint lowering inlines the body of @gc.safepoint_poll function
// at function entry and at loop-back-edges.
//
// The current strategy is to use an unconditional call to the GCPoll helper.
// TODO: Inline calls to GCPoll helper when CORJIT_FLG_GCPOLL_INLINE is set.
//
// The following code is inserted into the module:
//
// define void @gc.safepoint_poll()
// {
// entry:
// call void inttoptr(i64 <JIT_GCPoll> to void()*)()
// ret void
// }
void GenIR::createSafepointPoll() {
Module *M = JitContext->CurrentModule;
llvm::LLVMContext *LLVMContext = JitContext->LLVMContext;
Type *VoidType = Type::getVoidTy(*LLVMContext);
FunctionType *VoidFnType = FunctionType::get(VoidType, false);
llvm::Function *SafepointPoll = dyn_cast<llvm::Function>(
M->getOrInsertFunction("gc.safepoint_poll", VoidFnType));
assert(SafepointPoll->empty());
BasicBlock *EntryBlock =
BasicBlock::Create(*LLVMContext, "entry", SafepointPoll);
IRNode *Address = getHelperCallAddress(CORINFO_HELP_POLL_GC);
Value *Target =
LLVMBuilder->CreateIntToPtr(Address, getUnmanagedPointerType(VoidFnType));
CallInst::Create(Target, "", EntryBlock);
ReturnInst::Create(*LLVMContext, EntryBlock);
}
#pragma endregion
#pragma region DIAGNOSTICS