From 089a03b09e30c7f4200583d5a77e06eb5ed75a29 Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Tue, 24 Mar 2015 15:49:38 -0700 Subject: [PATCH] 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. --- include/Reader/readerir.h | 4 +--- lib/Jit/CMakeLists.txt | 9 +++++++++ lib/Jit/LLILCJit.cpp | 2 +- lib/Reader/readerir.cpp | 23 +++++++++++++++++++++++ 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/include/Reader/readerir.h b/include/Reader/readerir.h index 99c3ee756ea..69eef23fef1 100644 --- a/include/Reader/readerir.h +++ b/include/Reader/readerir.h @@ -368,9 +368,7 @@ class GenIR : public ReaderBase { 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; diff --git a/lib/Jit/CMakeLists.txt b/lib/Jit/CMakeLists.txt index e33f5d2d445..b0cf2856914 100644 --- a/lib/Jit/CMakeLists.txt +++ b/lib/Jit/CMakeLists.txt @@ -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( diff --git a/lib/Jit/LLILCJit.cpp b/lib/Jit/LLILCJit.cpp index c81f77338d7..3ec6ea2dcf2 100644 --- a/lib/Jit/LLILCJit.cpp +++ b/lib/Jit/LLILCJit.cpp @@ -170,7 +170,7 @@ CorJitResult LLILCJit::compileMethod(ICorJitInfo *JitInfo, Context.LLVMContext = &PerThreadState->LLVMContext; std::unique_ptr 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 diff --git a/lib/Reader/readerir.cpp b/lib/Reader/readerir.cpp index 4e7d9696a39..409750ab6c4 100644 --- a/lib/Reader/readerir.cpp +++ b/lib/Reader/readerir.cpp @@ -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