2007-12-23 17:59:28 +01:00
|
|
|
/*===-- llvm-c/ExecutionEngine.h - ExecutionEngine Lib C Iface --*- C++ -*-===*\
|
|
|
|
|* *|
|
2019-01-19 09:50:56 +01:00
|
|
|
|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
|
|
|
|
|* Exceptions. *|
|
|
|
|
|* See https://llvm.org/LICENSE.txt for license information. *|
|
|
|
|
|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
|
2007-12-23 17:59:28 +01:00
|
|
|
|* *|
|
|
|
|
|*===----------------------------------------------------------------------===*|
|
|
|
|
|* *|
|
|
|
|
|* This header declares the C interface to libLLVMExecutionEngine.o, which *|
|
|
|
|
|* implements various analyses of the LLVM IR. *|
|
|
|
|
|* *|
|
|
|
|
|* Many exotic languages can interoperate with C code but have a harder time *|
|
|
|
|
|* with C++ due to name mangling. So in addition to C, this interface enables *|
|
|
|
|
|* tools written in such languages. *|
|
|
|
|
|* *|
|
|
|
|
\*===----------------------------------------------------------------------===*/
|
|
|
|
|
|
|
|
#ifndef LLVM_C_EXECUTIONENGINE_H
|
|
|
|
#define LLVM_C_EXECUTIONENGINE_H
|
|
|
|
|
2019-11-14 22:57:57 +01:00
|
|
|
#include "llvm-c/ExternC.h"
|
2008-03-27 01:27:14 +01:00
|
|
|
#include "llvm-c/Target.h"
|
2013-05-02 00:58:00 +02:00
|
|
|
#include "llvm-c/TargetMachine.h"
|
2017-06-06 13:49:48 +02:00
|
|
|
#include "llvm-c/Types.h"
|
2007-12-23 17:59:28 +01:00
|
|
|
|
2019-11-14 22:57:57 +01:00
|
|
|
LLVM_C_EXTERN_C_BEGIN
|
2007-12-23 17:59:28 +01:00
|
|
|
|
2012-03-21 04:54:29 +01:00
|
|
|
/**
|
|
|
|
* @defgroup LLVMCExecutionEngine Execution Engine
|
|
|
|
* @ingroup LLVMC
|
|
|
|
*
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
2013-04-29 19:49:40 +02:00
|
|
|
void LLVMLinkInMCJIT(void);
|
2009-06-24 23:09:18 +02:00
|
|
|
void LLVMLinkInInterpreter(void);
|
|
|
|
|
2007-12-23 17:59:28 +01:00
|
|
|
typedef struct LLVMOpaqueGenericValue *LLVMGenericValueRef;
|
|
|
|
typedef struct LLVMOpaqueExecutionEngine *LLVMExecutionEngineRef;
|
2013-05-22 04:46:43 +02:00
|
|
|
typedef struct LLVMOpaqueMCJITMemoryManager *LLVMMCJITMemoryManagerRef;
|
2007-12-23 17:59:28 +01:00
|
|
|
|
2013-04-29 19:49:40 +02:00
|
|
|
struct LLVMMCJITCompilerOptions {
|
|
|
|
unsigned OptLevel;
|
2013-05-02 00:58:00 +02:00
|
|
|
LLVMCodeModel CodeModel;
|
2013-04-29 19:49:40 +02:00
|
|
|
LLVMBool NoFramePointerElim;
|
2013-05-02 00:58:00 +02:00
|
|
|
LLVMBool EnableFastISel;
|
2013-05-22 04:46:43 +02:00
|
|
|
LLVMMCJITMemoryManagerRef MCJMM;
|
2013-04-29 19:49:40 +02:00
|
|
|
};
|
|
|
|
|
2007-12-23 17:59:28 +01:00
|
|
|
/*===-- Operations on generic values --------------------------------------===*/
|
|
|
|
|
|
|
|
LLVMGenericValueRef LLVMCreateGenericValueOfInt(LLVMTypeRef Ty,
|
|
|
|
unsigned long long N,
|
2010-01-09 23:27:07 +01:00
|
|
|
LLVMBool IsSigned);
|
2007-12-23 17:59:28 +01:00
|
|
|
|
|
|
|
LLVMGenericValueRef LLVMCreateGenericValueOfPointer(void *P);
|
|
|
|
|
|
|
|
LLVMGenericValueRef LLVMCreateGenericValueOfFloat(LLVMTypeRef Ty, double N);
|
|
|
|
|
|
|
|
unsigned LLVMGenericValueIntWidth(LLVMGenericValueRef GenValRef);
|
|
|
|
|
|
|
|
unsigned long long LLVMGenericValueToInt(LLVMGenericValueRef GenVal,
|
2010-01-09 23:27:07 +01:00
|
|
|
LLVMBool IsSigned);
|
2007-12-23 17:59:28 +01:00
|
|
|
|
|
|
|
void *LLVMGenericValueToPointer(LLVMGenericValueRef GenVal);
|
|
|
|
|
|
|
|
double LLVMGenericValueToFloat(LLVMTypeRef TyRef, LLVMGenericValueRef GenVal);
|
|
|
|
|
|
|
|
void LLVMDisposeGenericValue(LLVMGenericValueRef GenVal);
|
|
|
|
|
|
|
|
/*===-- Operations on execution engines -----------------------------------===*/
|
|
|
|
|
2010-03-03 00:58:54 +01:00
|
|
|
LLVMBool LLVMCreateExecutionEngineForModule(LLVMExecutionEngineRef *OutEE,
|
|
|
|
LLVMModuleRef M,
|
|
|
|
char **OutError);
|
|
|
|
|
|
|
|
LLVMBool LLVMCreateInterpreterForModule(LLVMExecutionEngineRef *OutInterp,
|
|
|
|
LLVMModuleRef M,
|
|
|
|
char **OutError);
|
|
|
|
|
|
|
|
LLVMBool LLVMCreateJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
|
|
|
|
LLVMModuleRef M,
|
|
|
|
unsigned OptLevel,
|
|
|
|
char **OutError);
|
|
|
|
|
2013-05-02 00:58:00 +02:00
|
|
|
void LLVMInitializeMCJITCompilerOptions(
|
|
|
|
struct LLVMMCJITCompilerOptions *Options, size_t SizeOfOptions);
|
|
|
|
|
2013-04-29 19:49:40 +02:00
|
|
|
/**
|
|
|
|
* Create an MCJIT execution engine for a module, with the given options. It is
|
|
|
|
* the responsibility of the caller to ensure that all fields in Options up to
|
2013-05-02 00:58:00 +02:00
|
|
|
* the given SizeOfOptions are initialized. It is correct to pass a smaller
|
|
|
|
* value of SizeOfOptions that omits some fields. The canonical way of using
|
|
|
|
* this is:
|
2013-04-29 19:49:40 +02:00
|
|
|
*
|
|
|
|
* LLVMMCJITCompilerOptions options;
|
2013-05-02 00:58:00 +02:00
|
|
|
* LLVMInitializeMCJITCompilerOptions(&options, sizeof(options));
|
2013-04-29 19:49:40 +02:00
|
|
|
* ... fill in those options you care about
|
2013-05-02 00:58:00 +02:00
|
|
|
* LLVMCreateMCJITCompilerForModule(&jit, mod, &options, sizeof(options),
|
|
|
|
* &error);
|
2013-04-29 19:49:40 +02:00
|
|
|
*
|
|
|
|
* Note that this is also correct, though possibly suboptimal:
|
|
|
|
*
|
|
|
|
* LLVMCreateMCJITCompilerForModule(&jit, mod, 0, 0, &error);
|
|
|
|
*/
|
2013-05-02 00:58:00 +02:00
|
|
|
LLVMBool LLVMCreateMCJITCompilerForModule(
|
|
|
|
LLVMExecutionEngineRef *OutJIT, LLVMModuleRef M,
|
|
|
|
struct LLVMMCJITCompilerOptions *Options, size_t SizeOfOptions,
|
|
|
|
char **OutError);
|
2013-04-29 19:49:40 +02:00
|
|
|
|
2007-12-23 17:59:28 +01:00
|
|
|
void LLVMDisposeExecutionEngine(LLVMExecutionEngineRef EE);
|
|
|
|
|
|
|
|
void LLVMRunStaticConstructors(LLVMExecutionEngineRef EE);
|
|
|
|
|
|
|
|
void LLVMRunStaticDestructors(LLVMExecutionEngineRef EE);
|
|
|
|
|
|
|
|
int LLVMRunFunctionAsMain(LLVMExecutionEngineRef EE, LLVMValueRef F,
|
|
|
|
unsigned ArgC, const char * const *ArgV,
|
|
|
|
const char * const *EnvP);
|
|
|
|
|
|
|
|
LLVMGenericValueRef LLVMRunFunction(LLVMExecutionEngineRef EE, LLVMValueRef F,
|
|
|
|
unsigned NumArgs,
|
|
|
|
LLVMGenericValueRef *Args);
|
|
|
|
|
|
|
|
void LLVMFreeMachineCodeForFunction(LLVMExecutionEngineRef EE, LLVMValueRef F);
|
|
|
|
|
2010-03-03 00:58:54 +01:00
|
|
|
void LLVMAddModule(LLVMExecutionEngineRef EE, LLVMModuleRef M);
|
|
|
|
|
|
|
|
LLVMBool LLVMRemoveModule(LLVMExecutionEngineRef EE, LLVMModuleRef M,
|
|
|
|
LLVMModuleRef *OutMod, char **OutError);
|
|
|
|
|
2010-01-09 23:27:07 +01:00
|
|
|
LLVMBool LLVMFindFunction(LLVMExecutionEngineRef EE, const char *Name,
|
|
|
|
LLVMValueRef *OutFn);
|
2007-12-23 17:59:28 +01:00
|
|
|
|
2013-05-02 00:58:00 +02:00
|
|
|
void *LLVMRecompileAndRelinkFunction(LLVMExecutionEngineRef EE,
|
|
|
|
LLVMValueRef Fn);
|
2010-07-19 11:33:13 +02:00
|
|
|
|
2008-03-27 01:27:14 +01:00
|
|
|
LLVMTargetDataRef LLVMGetExecutionEngineTargetData(LLVMExecutionEngineRef EE);
|
2014-01-23 20:23:28 +01:00
|
|
|
LLVMTargetMachineRef
|
|
|
|
LLVMGetExecutionEngineTargetMachine(LLVMExecutionEngineRef EE);
|
2008-03-27 01:27:14 +01:00
|
|
|
|
2008-06-20 04:16:11 +02:00
|
|
|
void LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global,
|
|
|
|
void* Addr);
|
|
|
|
|
2009-01-21 19:11:10 +01:00
|
|
|
void *LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global);
|
|
|
|
|
2014-12-22 19:53:11 +01:00
|
|
|
uint64_t LLVMGetGlobalValueAddress(LLVMExecutionEngineRef EE, const char *Name);
|
|
|
|
|
|
|
|
uint64_t LLVMGetFunctionAddress(LLVMExecutionEngineRef EE, const char *Name);
|
|
|
|
|
2020-03-13 17:24:09 +01:00
|
|
|
/// Returns true on error, false on success. If true is returned then the error
|
|
|
|
/// message is copied to OutStr and cleared in the ExecutionEngine instance.
|
|
|
|
LLVMBool LLVMExecutionEngineGetErrMsg(LLVMExecutionEngineRef EE,
|
|
|
|
char **OutError);
|
|
|
|
|
2013-05-22 04:46:43 +02:00
|
|
|
/*===-- Operations on memory managers -------------------------------------===*/
|
|
|
|
|
2013-10-02 02:59:25 +02:00
|
|
|
typedef uint8_t *(*LLVMMemoryManagerAllocateCodeSectionCallback)(
|
|
|
|
void *Opaque, uintptr_t Size, unsigned Alignment, unsigned SectionID,
|
|
|
|
const char *SectionName);
|
|
|
|
typedef uint8_t *(*LLVMMemoryManagerAllocateDataSectionCallback)(
|
|
|
|
void *Opaque, uintptr_t Size, unsigned Alignment, unsigned SectionID,
|
|
|
|
const char *SectionName, LLVMBool IsReadOnly);
|
|
|
|
typedef LLVMBool (*LLVMMemoryManagerFinalizeMemoryCallback)(
|
|
|
|
void *Opaque, char **ErrMsg);
|
2013-09-30 21:11:32 +02:00
|
|
|
typedef void (*LLVMMemoryManagerDestroyCallback)(void *Opaque);
|
|
|
|
|
2013-05-22 04:46:43 +02:00
|
|
|
/**
|
|
|
|
* Create a simple custom MCJIT memory manager. This memory manager can
|
|
|
|
* intercept allocations in a module-oblivious way. This will return NULL
|
|
|
|
* if any of the passed functions are NULL.
|
|
|
|
*
|
|
|
|
* @param Opaque An opaque client object to pass back to the callbacks.
|
|
|
|
* @param AllocateCodeSection Allocate a block of memory for executable code.
|
|
|
|
* @param AllocateDataSection Allocate a block of memory for data.
|
|
|
|
* @param FinalizeMemory Set page permissions and flush cache. Return 0 on
|
|
|
|
* success, 1 on error.
|
|
|
|
*/
|
|
|
|
LLVMMCJITMemoryManagerRef LLVMCreateSimpleMCJITMemoryManager(
|
|
|
|
void *Opaque,
|
2013-09-30 21:11:32 +02:00
|
|
|
LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection,
|
|
|
|
LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection,
|
|
|
|
LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory,
|
2013-10-22 17:18:03 +02:00
|
|
|
LLVMMemoryManagerDestroyCallback Destroy);
|
2013-05-22 04:46:43 +02:00
|
|
|
|
|
|
|
void LLVMDisposeMCJITMemoryManager(LLVMMCJITMemoryManagerRef MM);
|
|
|
|
|
2018-05-24 23:32:54 +02:00
|
|
|
/*===-- JIT Event Listener functions -------------------------------------===*/
|
|
|
|
|
|
|
|
LLVMJITEventListenerRef LLVMCreateGDBRegistrationListener(void);
|
|
|
|
LLVMJITEventListenerRef LLVMCreateIntelJITEventListener(void);
|
2018-11-02 10:57:24 +01:00
|
|
|
LLVMJITEventListenerRef LLVMCreateOProfileJITEventListener(void);
|
Add PerfJITEventListener for perf profiling support.
This new JIT event listener supports generating profiling data for
the linux 'perf' profiling tool, allowing it to generate function and
instruction level profiles.
Currently this functionality is not enabled by default, but must be
enabled with LLVM_USE_PERF=yes. Given that the listener has no
dependencies, it might be sensible to enable by default once the
initial issues have been shaken out.
I followed existing precedent in registering the listener by default
in lli. Should there be a decision to enable this by default on linux,
that should probably be changed.
Please note that until https://reviews.llvm.org/D47343 is resolved,
using this functionality with mcjit rather than orcjit will not
reliably work.
Disregarding the previous comment, here's an example:
$ cat /tmp/expensive_loop.c
bool stupid_isprime(uint64_t num)
{
if (num == 2)
return true;
if (num < 1 || num % 2 == 0)
return false;
for(uint64_t i = 3; i < num / 2; i+= 2) {
if (num % i == 0)
return false;
}
return true;
}
int main(int argc, char **argv)
{
int numprimes = 0;
for (uint64_t num = argc; num < 100000; num++)
{
if (stupid_isprime(num))
numprimes++;
}
return numprimes;
}
$ clang -ggdb -S -c -emit-llvm /tmp/expensive_loop.c -o
/tmp/expensive_loop.ll
$ perf record -o perf.data -g -k 1 ./bin/lli -jit-kind=mcjit /tmp/expensive_loop.ll 1
$ perf inject --jit -i perf.data -o perf.jit.data
$ perf report -i perf.jit.data
- 92.59% lli jitted-5881-2.so [.] stupid_isprime
stupid_isprime
main
llvm::MCJIT::runFunction
llvm::ExecutionEngine::runFunctionAsMain
main
__libc_start_main
0x4bf6258d4c544155
+ 0.85% lli ld-2.27.so [.] do_lookup_x
And line-level annotations also work:
│ for(uint64_t i = 3; i < num / 2; i+= 2) {
│1 30: movq $0x3,-0x18(%rbp)
0.03 │1 38: mov -0x18(%rbp),%rax
0.03 │ mov -0x10(%rbp),%rcx
│ shr $0x1,%rcx
3.63 │ ┌──cmp %rcx,%rax
│ ├──jae 6f
│ │ if (num % i == 0)
0.03 │ │ mov -0x10(%rbp),%rax
│ │ xor %edx,%edx
89.00 │ │ divq -0x18(%rbp)
│ │ cmp $0x0,%rdx
0.22 │ │↓ jne 5f
│ │ return false;
│ │ movb $0x0,-0x1(%rbp)
│ │↓ jmp 73
│ │ }
3.22 │1 5f:│↓ jmp 61
│ │ for(uint64_t i = 3; i < num / 2; i+= 2) {
Subscribers: mgorny, llvm-commits
Differential Revision: https://reviews.llvm.org/D44892
llvm-svn: 337789
2018-07-24 02:54:06 +02:00
|
|
|
LLVMJITEventListenerRef LLVMCreatePerfJITEventListener(void);
|
2018-05-24 23:32:54 +02:00
|
|
|
|
2012-03-21 04:54:29 +01:00
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
*/
|
|
|
|
|
2019-11-14 22:57:57 +01:00
|
|
|
LLVM_C_EXTERN_C_END
|
2007-12-23 17:59:28 +01:00
|
|
|
|
|
|
|
#endif
|