Set GC-strategy on LLVM function based on JitContext

Set the GC strategy on the generated function to "statepoint-example"
only if the JitContext specifies using precise GC.

Also fixed format-spacing
Rename safepoint_poll creation method to createSafepointPoll()
This commit is contained in:
Swaroop Sridhar 2015-04-03 17:09:12 -07:00
Родитель e71f0eb6f5
Коммит 59f4982919
4 изменённых файлов: 26 добавлений и 53 удалений

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

@ -80,11 +80,6 @@ public:
std::string MethodName; ///< Name of the method (for diagnostics).
//@}
/// \name CoreCLR GC information
//@{
bool ShouldUseConservativeGC; ///< Whether the GC is conservative/precise
//@}
/// \name LLVM information
//@{
llvm::LLVMContext *LLVMContext; ///< LLVM context for types and similar.
@ -235,16 +230,22 @@ private:
/// \returns \p true if GC info was successfully reported.
bool outputGCInfo(LLILCJitContext *JitContext);
/// Insert the @gc.safepoint_poll() method
/// Inserts the @gc.safepoint_poll() method into the current module.
/// This helper is required by the LLVM GC-Statepoint insertion phase.
/// 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 insertSafepointPoll(LLILCJitContext *Context);
void createSafepointPoll(LLILCJitContext *Context);
public:
/// A pointer to the singleton jit instance.
static LLILCJit *TheJit;
/// \name CoreCLR GC information
//@{
bool ShouldUseConservativeGC; ///< Whether the GC is conservative/precise
//@}
private:
/// Thread local storage for the jit's per-thread state.
llvm::sys::ThreadLocal<LLILCJitPerThreadState> State;

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

@ -1185,6 +1185,7 @@ private:
private:
LLILCJitContext *JitContext;
ReaderMethodSignature MethodSignature;
llvm::Function *Function;
// The LLVMBuilder has a notion of a current insertion point. During the

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

@ -66,13 +66,7 @@ LLVMDumpLevel dumpLevel() {
// When CLR config support is included, update it here.
bool shouldUseConservativeGC() {
const char *LevelCStr = getenv("COMPLUS_GCCONSERVATIVE");
if (LevelCStr) {
std::string Level = LevelCStr;
if (Level.compare("1") == 0) {
return true;
}
}
return false;
return (LevelCStr != nullptr) && (strcmp(LevelCStr, "1") == 0);
}
// The one and only Jit Object.
@ -105,6 +99,8 @@ LLILCJit::LLILCJit() {
InitializeNativeTargetAsmPrinter();
InitializeNativeTargetAsmParser();
llvm::linkStatepointExampleGC();
ShouldUseConservativeGC = shouldUseConservativeGC();
}
#ifdef LLVM_ON_WIN32
@ -182,10 +178,9 @@ CorJitResult LLILCJit::compileMethod(ICorJitInfo *JitInfo,
Context.LLVMContext = &PerThreadState->LLVMContext;
std::unique_ptr<Module> M = Context.getModuleForMethod(MethodInfo);
Context.CurrentModule = M.get();
Context.ShouldUseConservativeGC = shouldUseConservativeGC();
if (!Context.ShouldUseConservativeGC) {
insertSafepointPoll(&Context);
if (!ShouldUseConservativeGC) {
createSafepointPoll(&Context);
}
EngineBuilder Builder(std::move(M));
@ -198,7 +193,7 @@ CorJitResult LLILCJit::compileMethod(ICorJitInfo *JitInfo,
TargetOptions Options;
// Statepoint GC does not support FastIsel yet.
Options.EnableFastISel = Context.ShouldUseConservativeGC;
Options.EnableFastISel = false;
if ((Flags & CORJIT_FLG_DEBUG_CODE) == 0) {
Builder.setOptLevel(CodeGenOpt::Level::Default);
@ -227,7 +222,7 @@ CorJitResult LLILCJit::compileMethod(ICorJitInfo *JitInfo,
if (HasMethod) {
if (!Context.ShouldUseConservativeGC) {
if (!ShouldUseConservativeGC) {
// If using Precise GC, run the GC-Safepoint insertion
// and lowering passes before generating code.
legacy::PassManager Passes;
@ -274,7 +269,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.
@ -283,55 +277,30 @@ CorJitResult LLILCJit::compileMethod(ICorJitInfo *JitInfo,
//
// The following code is inserted into the module:
//
// An empty dummy function
// define void @__llilc_statepoint() {
// entry:
// ret void
// }
//
// gc.safepoint_poll() function containing a call to an empty function
// The call instruction causes a safepoint placement.
// define void @gc.safepoint_poll()
// {
// entry:
// call void @__llilc_statepoint()
// ret void
// }
//
// TODO: Rather than introduce a Call at every poll-site, use a
// CLR-specific sequence that checks if a GC is pending, and calls/branches
// 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::insertSafepointPoll(LLILCJitContext *Context) {
void LLILCJit::createSafepointPoll(LLILCJitContext *Context) {
Module *M = Context->CurrentModule;
FunctionType *VoidFnType =
FunctionType::get(Type::getVoidTy(M->getContext()), false);
// Create a dummy empty function
Function *EmptyFunction = dyn_cast<Function>(
M->getOrInsertFunction("__llilcGcPoll", VoidFnType));
assert(EmptyFunction->empty());
llvm::BasicBlock *EmptyEntryBlock =
BasicBlock::Create(*Context->LLVMContext, "entry", EmptyFunction);
ReturnInst::Create(*Context->LLVMContext, EmptyEntryBlock);
// Create the gc.safepoint_poll() function containing a call to the
// above dummy function, so that the call is converted into
// a gc.statepoint()
FunctionType::get(Type::getVoidTy(M->getContext()), false);
Function *SafepointPoll = dyn_cast<Function>(
M->getOrInsertFunction("gc.safepoint_poll", VoidFnType));
assert(SafepointPoll->empty());
llvm::BasicBlock *EntryBlock =
BasicBlock *EntryBlock =
BasicBlock::Create(*Context->LLVMContext, "entry", SafepointPoll);
CallInst::Create(EmptyFunction, "", EntryBlock);
ReturnInst::Create(*Context->LLVMContext, EntryBlock);
}

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

@ -529,7 +529,9 @@ Function *GenIR::getFunction(const ReaderMethodSignature &Signature) {
F->setCallingConv(CallingConv::CLR_SecretParameter);
}
F->setGC("statepoint-example");
if (!LLILCJit::TheJit->ShouldUseConservativeGC) {
F->setGC("statepoint-example");
}
return F;
}