From: Brian Gaeke Date: Fri, 17 Oct 2003 18:27:00 +0000 (+0000) Subject: Refactor running the JIT passes on a single function into the new method, X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=cd64ddfafe314f0a76d866f9bbb9466cc6d52b03;p=oota-llvm.git Refactor running the JIT passes on a single function into the new method, runJITOnFunction(). Add new method for recompiling and patching in new versions of functions, recompileAndRelinkFunction(). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@9199 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/ExecutionEngine/JIT/VM.cpp b/lib/ExecutionEngine/JIT/VM.cpp index f2ddcf487ae..ba1ecdf31a0 100644 --- a/lib/ExecutionEngine/JIT/VM.cpp +++ b/lib/ExecutionEngine/JIT/VM.cpp @@ -37,11 +37,25 @@ void VM::setupPassManager() { } } +/// runJITOnFunction - Run the FunctionPassManager full of +/// just-in-time compilation passes on F, hopefully filling in +/// GlobalAddress[F] with the address of F's machine code. +/// +void VM::runJITOnFunction (Function *F) { + static bool isAlreadyCodeGenerating = false; + assert(!isAlreadyCodeGenerating && "ERROR: RECURSIVE COMPILATION DETECTED!"); + + // JIT the function + isAlreadyCodeGenerating = true; + PM.run(*F); + isAlreadyCodeGenerating = false; +} + /// getPointerToFunction - This method is used to get the address of the /// specified function, compiling it if neccesary. /// void *VM::getPointerToFunction(Function *F) { - void *&Addr = GlobalAddress[F]; // Function already code gen'd + void *&Addr = GlobalAddress[F]; // Check if function already code gen'd if (Addr) return Addr; // Make sure we read in the function if it exists in this Module @@ -50,14 +64,28 @@ void *VM::getPointerToFunction(Function *F) { if (F->isExternal()) return Addr = getPointerToNamedFunction(F->getName()); - static bool isAlreadyCodeGenerating = false; - assert(!isAlreadyCodeGenerating && "ERROR: RECURSIVE COMPILATION DETECTED!"); + runJITOnFunction (F); + assert(Addr && "Code generation didn't add function to GlobalAddress table!"); + return Addr; +} - // JIT the function - isAlreadyCodeGenerating = true; - PM.run(*F); - isAlreadyCodeGenerating = false; +/// recompileAndRelinkFunction - This method is used to force a function +/// which has already been compiled, to be compiled again, possibly +/// after it has been modified. Then the entry to the old copy is overwritten +/// with a branch to the new copy. If there was no old copy, this acts +/// just like VM::getPointerToFunction(). +/// +void *VM::recompileAndRelinkFunction(Function *F) { + void *&Addr = GlobalAddress[F]; // Check if function already code gen'd + + // If it's not already compiled (this is kind of weird) there is no + // reason to patch it up. + if (!Addr) { return getPointerToFunction (F); } + void *OldAddr = Addr; + Addr = 0; + runJITOnFunction (F); assert(Addr && "Code generation didn't add function to GlobalAddress table!"); + TM.replaceMachineCodeForFunction (OldAddr, Addr); return Addr; }