Implement basic support for localloc.

Getting the LLVM IR right here is not too hard. We're zeroing via the JIT helper since using LLVM's memset might lead to calls into the CRT.

Most of the challenge here is getting this IR properly lowered to machine code. I have some preliminary changes checked into LLVM for this already, and this change depends upon them.

To enable those changes we now use the CoreCLR environment when targeting windows. Thus the LLVM triple we use on windows is now actually a quad.

The LLVM work is incomplete so this only works at runtime if the localloc is small enough to stay within the guard page, but it handles all our simple test cases.
This commit is contained in:
Andy Ayers 2015-03-24 15:49:38 -07:00
Родитель 44f164ca2e
Коммит 089a03b09e
4 изменённых файлов: 34 добавлений и 4 удалений

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

@ -368,9 +368,7 @@ public:
ReaderAlignType Alignment, bool IsVolatile) override;
IRNode *loadNull() override;
IRNode *localAlloc(IRNode *Arg, bool ZeroInit) override {
throw NotYetImplementedException("localAlloc");
};
IRNode *localAlloc(IRNode *Arg, bool ZeroInit) override;
IRNode *loadFieldAddress(CORINFO_RESOLVED_TOKEN *ResolvedToken,
IRNode *Obj) override;

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

@ -38,14 +38,23 @@ if (WIN32)
${LLILCJIT_EXPORTS_DEF_TEMP} ${LLILCJIT_EXPORTS_DEF})
set(SHARED_LIB_SOURCES ${SOURCES} ${LLILCJIT_EXPORTS_DEF})
# For windows we need to specify the CoreCLR environment
set(LLILC_TARGET_TRIPLE "${LLVM_DEFAULT_TARGET_TRIPLE}-coreclr")
else()
if (UNIX)
set(LLILCJIT_LINK_LIBRARIES ${LLILCJIT_LINK_LIBRARIES} coreclrpal)
endif()
set(SHARED_LIB_SOURCES ${SOURCES})
# For non-windows we can use the default triple for now
set(LLILC_TARGET_TRIPLE "${LLVM_DEFAULT_TARGET_TRIPLE}")
endif()
message(STATUS "LLILC_TARGET_TRIPLE is ${LLILC_TARGET_TRIPLE}")
add_definitions(-DLLILC_TARGET_TRIPLE="${LLILC_TARGET_TRIPLE}")
set(LLVM_EXPORTED_SYMBOL_FILE ${LLILCJIT_EXPORTS_DEF})
add_llilcjit_library(

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

@ -170,7 +170,7 @@ CorJitResult LLILCJit::compileMethod(ICorJitInfo *JitInfo,
Context.LLVMContext = &PerThreadState->LLVMContext;
std::unique_ptr<Module> M = Context.getModuleForMethod(MethodInfo);
Context.CurrentModule = M.get();
Context.CurrentModule->setTargetTriple(LLVM_DEFAULT_TARGET_TRIPLE);
Context.CurrentModule->setTargetTriple(LLILC_TARGET_TRIPLE);
Context.TheABIInfo = ABIInfo::get(*Context.CurrentModule);
// Initialize per invocation JIT options. This should be done after the

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

@ -5381,6 +5381,29 @@ bool GenIR::abs(IRNode *Argument, IRNode **Result) {
return false;
}
IRNode *GenIR::localAlloc(IRNode *Arg, bool ZeroInit) {
// Note that we've seen a localloc in this method, since it has repercussions
// on other aspects of code generation.
this->HasLocAlloc = true;
// Arg is the number of bytes to allocate. Result must be pointer-aligned.
const unsigned int Alignment = TargetPointerSizeInBits / 8;
LLVMContext &Context = *JitContext->LLVMContext;
Type *Ty = Type::getInt8Ty(Context);
AllocaInst *LocAlloc = LLVMBuilder->CreateAlloca(Ty, Arg, "LocAlloc");
LocAlloc->setAlignment(Alignment);
// Zero the allocated region if so requested.
if (ZeroInit) {
Value *ZeroByte = ConstantInt::get(Context, APInt(8, 0, true));
Type *VoidTy = Type::getVoidTy(Context);
callHelperImpl(CORINFO_HELP_MEMSET, VoidTy, (IRNode *)LocAlloc,
(IRNode *)ZeroByte, Arg);
}
return (IRNode *)LocAlloc;
}
#pragma endregion
#pragma region STACK MAINTENANCE