You've already forked linux-packaging-mono
Imported Upstream version 5.18.0.207
Former-commit-id: 3b152f462918d427ce18620a2cbe4f8b79650449
This commit is contained in:
parent
8e12397d70
commit
eb85e2fc17
36
external/llvm/lib/ExecutionEngine/CMakeLists.txt
vendored
36
external/llvm/lib/ExecutionEngine/CMakeLists.txt
vendored
@ -1,36 +0,0 @@
|
||||
if(NOT LLVM_BUILD_EXECUTION_ENGINE)
|
||||
set(EXCLUDE_FROM_ALL ON)
|
||||
endif()
|
||||
|
||||
add_llvm_library(LLVMExecutionEngine
|
||||
ExecutionEngine.cpp
|
||||
ExecutionEngineBindings.cpp
|
||||
GDBRegistrationListener.cpp
|
||||
SectionMemoryManager.cpp
|
||||
TargetSelect.cpp
|
||||
|
||||
ADDITIONAL_HEADER_DIRS
|
||||
${LLVM_MAIN_INCLUDE_DIR}/llvm/ExecutionEngine
|
||||
|
||||
DEPENDS
|
||||
intrinsics_gen
|
||||
)
|
||||
|
||||
if(BUILD_SHARED_LIBS)
|
||||
target_link_libraries(LLVMExecutionEngine PUBLIC LLVMRuntimeDyld)
|
||||
endif()
|
||||
|
||||
if(LLVM_BUILD_EXECUTION_ENGINE)
|
||||
add_subdirectory(Interpreter)
|
||||
add_subdirectory(MCJIT)
|
||||
add_subdirectory(Orc)
|
||||
add_subdirectory(RuntimeDyld)
|
||||
endif()
|
||||
|
||||
if( LLVM_USE_OPROFILE )
|
||||
add_subdirectory(OProfileJIT)
|
||||
endif( LLVM_USE_OPROFILE )
|
||||
|
||||
if( LLVM_USE_INTEL_JITEVENTS )
|
||||
add_subdirectory(IntelJITEvents)
|
||||
endif( LLVM_USE_INTEL_JITEVENTS )
|
1361
external/llvm/lib/ExecutionEngine/ExecutionEngine.cpp
vendored
1361
external/llvm/lib/ExecutionEngine/ExecutionEngine.cpp
vendored
File diff suppressed because it is too large
Load Diff
@ -1,413 +0,0 @@
|
||||
//===-- ExecutionEngineBindings.cpp - C bindings for EEs ------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the C bindings for the ExecutionEngine library.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm-c/ExecutionEngine.h"
|
||||
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||||
#include "llvm/ExecutionEngine/GenericValue.h"
|
||||
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/Support/CodeGenCWrappers.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
#include <cstring>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "jit"
|
||||
|
||||
// Wrapping the C bindings types.
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(GenericValue, LLVMGenericValueRef)
|
||||
|
||||
|
||||
static LLVMTargetMachineRef wrap(const TargetMachine *P) {
|
||||
return
|
||||
reinterpret_cast<LLVMTargetMachineRef>(const_cast<TargetMachine*>(P));
|
||||
}
|
||||
|
||||
/*===-- Operations on generic values --------------------------------------===*/
|
||||
|
||||
LLVMGenericValueRef LLVMCreateGenericValueOfInt(LLVMTypeRef Ty,
|
||||
unsigned long long N,
|
||||
LLVMBool IsSigned) {
|
||||
GenericValue *GenVal = new GenericValue();
|
||||
GenVal->IntVal = APInt(unwrap<IntegerType>(Ty)->getBitWidth(), N, IsSigned);
|
||||
return wrap(GenVal);
|
||||
}
|
||||
|
||||
LLVMGenericValueRef LLVMCreateGenericValueOfPointer(void *P) {
|
||||
GenericValue *GenVal = new GenericValue();
|
||||
GenVal->PointerVal = P;
|
||||
return wrap(GenVal);
|
||||
}
|
||||
|
||||
LLVMGenericValueRef LLVMCreateGenericValueOfFloat(LLVMTypeRef TyRef, double N) {
|
||||
GenericValue *GenVal = new GenericValue();
|
||||
switch (unwrap(TyRef)->getTypeID()) {
|
||||
case Type::FloatTyID:
|
||||
GenVal->FloatVal = N;
|
||||
break;
|
||||
case Type::DoubleTyID:
|
||||
GenVal->DoubleVal = N;
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("LLVMGenericValueToFloat supports only float and double.");
|
||||
}
|
||||
return wrap(GenVal);
|
||||
}
|
||||
|
||||
unsigned LLVMGenericValueIntWidth(LLVMGenericValueRef GenValRef) {
|
||||
return unwrap(GenValRef)->IntVal.getBitWidth();
|
||||
}
|
||||
|
||||
unsigned long long LLVMGenericValueToInt(LLVMGenericValueRef GenValRef,
|
||||
LLVMBool IsSigned) {
|
||||
GenericValue *GenVal = unwrap(GenValRef);
|
||||
if (IsSigned)
|
||||
return GenVal->IntVal.getSExtValue();
|
||||
else
|
||||
return GenVal->IntVal.getZExtValue();
|
||||
}
|
||||
|
||||
void *LLVMGenericValueToPointer(LLVMGenericValueRef GenVal) {
|
||||
return unwrap(GenVal)->PointerVal;
|
||||
}
|
||||
|
||||
double LLVMGenericValueToFloat(LLVMTypeRef TyRef, LLVMGenericValueRef GenVal) {
|
||||
switch (unwrap(TyRef)->getTypeID()) {
|
||||
case Type::FloatTyID:
|
||||
return unwrap(GenVal)->FloatVal;
|
||||
case Type::DoubleTyID:
|
||||
return unwrap(GenVal)->DoubleVal;
|
||||
default:
|
||||
llvm_unreachable("LLVMGenericValueToFloat supports only float and double.");
|
||||
}
|
||||
}
|
||||
|
||||
void LLVMDisposeGenericValue(LLVMGenericValueRef GenVal) {
|
||||
delete unwrap(GenVal);
|
||||
}
|
||||
|
||||
/*===-- Operations on execution engines -----------------------------------===*/
|
||||
|
||||
LLVMBool LLVMCreateExecutionEngineForModule(LLVMExecutionEngineRef *OutEE,
|
||||
LLVMModuleRef M,
|
||||
char **OutError) {
|
||||
std::string Error;
|
||||
EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
|
||||
builder.setEngineKind(EngineKind::Either)
|
||||
.setErrorStr(&Error);
|
||||
if (ExecutionEngine *EE = builder.create()){
|
||||
*OutEE = wrap(EE);
|
||||
return 0;
|
||||
}
|
||||
*OutError = strdup(Error.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
LLVMBool LLVMCreateInterpreterForModule(LLVMExecutionEngineRef *OutInterp,
|
||||
LLVMModuleRef M,
|
||||
char **OutError) {
|
||||
std::string Error;
|
||||
EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
|
||||
builder.setEngineKind(EngineKind::Interpreter)
|
||||
.setErrorStr(&Error);
|
||||
if (ExecutionEngine *Interp = builder.create()) {
|
||||
*OutInterp = wrap(Interp);
|
||||
return 0;
|
||||
}
|
||||
*OutError = strdup(Error.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
LLVMBool LLVMCreateJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
|
||||
LLVMModuleRef M,
|
||||
unsigned OptLevel,
|
||||
char **OutError) {
|
||||
std::string Error;
|
||||
EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
|
||||
builder.setEngineKind(EngineKind::JIT)
|
||||
.setErrorStr(&Error)
|
||||
.setOptLevel((CodeGenOpt::Level)OptLevel);
|
||||
if (ExecutionEngine *JIT = builder.create()) {
|
||||
*OutJIT = wrap(JIT);
|
||||
return 0;
|
||||
}
|
||||
*OutError = strdup(Error.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
void LLVMInitializeMCJITCompilerOptions(LLVMMCJITCompilerOptions *PassedOptions,
|
||||
size_t SizeOfPassedOptions) {
|
||||
LLVMMCJITCompilerOptions options;
|
||||
memset(&options, 0, sizeof(options)); // Most fields are zero by default.
|
||||
options.CodeModel = LLVMCodeModelJITDefault;
|
||||
|
||||
memcpy(PassedOptions, &options,
|
||||
std::min(sizeof(options), SizeOfPassedOptions));
|
||||
}
|
||||
|
||||
LLVMBool LLVMCreateMCJITCompilerForModule(
|
||||
LLVMExecutionEngineRef *OutJIT, LLVMModuleRef M,
|
||||
LLVMMCJITCompilerOptions *PassedOptions, size_t SizeOfPassedOptions,
|
||||
char **OutError) {
|
||||
LLVMMCJITCompilerOptions options;
|
||||
// If the user passed a larger sized options struct, then they were compiled
|
||||
// against a newer LLVM. Tell them that something is wrong.
|
||||
if (SizeOfPassedOptions > sizeof(options)) {
|
||||
*OutError = strdup(
|
||||
"Refusing to use options struct that is larger than my own; assuming "
|
||||
"LLVM library mismatch.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Defend against the user having an old version of the API by ensuring that
|
||||
// any fields they didn't see are cleared. We must defend against fields being
|
||||
// set to the bitwise equivalent of zero, and assume that this means "do the
|
||||
// default" as if that option hadn't been available.
|
||||
LLVMInitializeMCJITCompilerOptions(&options, sizeof(options));
|
||||
memcpy(&options, PassedOptions, SizeOfPassedOptions);
|
||||
|
||||
TargetOptions targetOptions;
|
||||
targetOptions.EnableFastISel = options.EnableFastISel;
|
||||
std::unique_ptr<Module> Mod(unwrap(M));
|
||||
|
||||
if (Mod)
|
||||
// Set function attribute "no-frame-pointer-elim" based on
|
||||
// NoFramePointerElim.
|
||||
for (auto &F : *Mod) {
|
||||
auto Attrs = F.getAttributes();
|
||||
StringRef Value(options.NoFramePointerElim ? "true" : "false");
|
||||
Attrs = Attrs.addAttribute(F.getContext(), AttributeList::FunctionIndex,
|
||||
"no-frame-pointer-elim", Value);
|
||||
F.setAttributes(Attrs);
|
||||
}
|
||||
|
||||
std::string Error;
|
||||
EngineBuilder builder(std::move(Mod));
|
||||
builder.setEngineKind(EngineKind::JIT)
|
||||
.setErrorStr(&Error)
|
||||
.setOptLevel((CodeGenOpt::Level)options.OptLevel)
|
||||
.setTargetOptions(targetOptions);
|
||||
bool JIT;
|
||||
if (Optional<CodeModel::Model> CM = unwrap(options.CodeModel, JIT))
|
||||
builder.setCodeModel(*CM);
|
||||
if (options.MCJMM)
|
||||
builder.setMCJITMemoryManager(
|
||||
std::unique_ptr<RTDyldMemoryManager>(unwrap(options.MCJMM)));
|
||||
if (ExecutionEngine *JIT = builder.create()) {
|
||||
*OutJIT = wrap(JIT);
|
||||
return 0;
|
||||
}
|
||||
*OutError = strdup(Error.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
void LLVMDisposeExecutionEngine(LLVMExecutionEngineRef EE) {
|
||||
delete unwrap(EE);
|
||||
}
|
||||
|
||||
void LLVMRunStaticConstructors(LLVMExecutionEngineRef EE) {
|
||||
unwrap(EE)->finalizeObject();
|
||||
unwrap(EE)->runStaticConstructorsDestructors(false);
|
||||
}
|
||||
|
||||
void LLVMRunStaticDestructors(LLVMExecutionEngineRef EE) {
|
||||
unwrap(EE)->finalizeObject();
|
||||
unwrap(EE)->runStaticConstructorsDestructors(true);
|
||||
}
|
||||
|
||||
int LLVMRunFunctionAsMain(LLVMExecutionEngineRef EE, LLVMValueRef F,
|
||||
unsigned ArgC, const char * const *ArgV,
|
||||
const char * const *EnvP) {
|
||||
unwrap(EE)->finalizeObject();
|
||||
|
||||
std::vector<std::string> ArgVec(ArgV, ArgV + ArgC);
|
||||
return unwrap(EE)->runFunctionAsMain(unwrap<Function>(F), ArgVec, EnvP);
|
||||
}
|
||||
|
||||
LLVMGenericValueRef LLVMRunFunction(LLVMExecutionEngineRef EE, LLVMValueRef F,
|
||||
unsigned NumArgs,
|
||||
LLVMGenericValueRef *Args) {
|
||||
unwrap(EE)->finalizeObject();
|
||||
|
||||
std::vector<GenericValue> ArgVec;
|
||||
ArgVec.reserve(NumArgs);
|
||||
for (unsigned I = 0; I != NumArgs; ++I)
|
||||
ArgVec.push_back(*unwrap(Args[I]));
|
||||
|
||||
GenericValue *Result = new GenericValue();
|
||||
*Result = unwrap(EE)->runFunction(unwrap<Function>(F), ArgVec);
|
||||
return wrap(Result);
|
||||
}
|
||||
|
||||
void LLVMFreeMachineCodeForFunction(LLVMExecutionEngineRef EE, LLVMValueRef F) {
|
||||
}
|
||||
|
||||
void LLVMAddModule(LLVMExecutionEngineRef EE, LLVMModuleRef M){
|
||||
unwrap(EE)->addModule(std::unique_ptr<Module>(unwrap(M)));
|
||||
}
|
||||
|
||||
LLVMBool LLVMRemoveModule(LLVMExecutionEngineRef EE, LLVMModuleRef M,
|
||||
LLVMModuleRef *OutMod, char **OutError) {
|
||||
Module *Mod = unwrap(M);
|
||||
unwrap(EE)->removeModule(Mod);
|
||||
*OutMod = wrap(Mod);
|
||||
return 0;
|
||||
}
|
||||
|
||||
LLVMBool LLVMFindFunction(LLVMExecutionEngineRef EE, const char *Name,
|
||||
LLVMValueRef *OutFn) {
|
||||
if (Function *F = unwrap(EE)->FindFunctionNamed(Name)) {
|
||||
*OutFn = wrap(F);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void *LLVMRecompileAndRelinkFunction(LLVMExecutionEngineRef EE,
|
||||
LLVMValueRef Fn) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LLVMTargetDataRef LLVMGetExecutionEngineTargetData(LLVMExecutionEngineRef EE) {
|
||||
return wrap(&unwrap(EE)->getDataLayout());
|
||||
}
|
||||
|
||||
LLVMTargetMachineRef
|
||||
LLVMGetExecutionEngineTargetMachine(LLVMExecutionEngineRef EE) {
|
||||
return wrap(unwrap(EE)->getTargetMachine());
|
||||
}
|
||||
|
||||
void LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global,
|
||||
void* Addr) {
|
||||
unwrap(EE)->addGlobalMapping(unwrap<GlobalValue>(Global), Addr);
|
||||
}
|
||||
|
||||
void *LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global) {
|
||||
unwrap(EE)->finalizeObject();
|
||||
|
||||
return unwrap(EE)->getPointerToGlobal(unwrap<GlobalValue>(Global));
|
||||
}
|
||||
|
||||
uint64_t LLVMGetGlobalValueAddress(LLVMExecutionEngineRef EE, const char *Name) {
|
||||
return unwrap(EE)->getGlobalValueAddress(Name);
|
||||
}
|
||||
|
||||
uint64_t LLVMGetFunctionAddress(LLVMExecutionEngineRef EE, const char *Name) {
|
||||
return unwrap(EE)->getFunctionAddress(Name);
|
||||
}
|
||||
|
||||
/*===-- Operations on memory managers -------------------------------------===*/
|
||||
|
||||
namespace {
|
||||
|
||||
struct SimpleBindingMMFunctions {
|
||||
LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection;
|
||||
LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection;
|
||||
LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory;
|
||||
LLVMMemoryManagerDestroyCallback Destroy;
|
||||
};
|
||||
|
||||
class SimpleBindingMemoryManager : public RTDyldMemoryManager {
|
||||
public:
|
||||
SimpleBindingMemoryManager(const SimpleBindingMMFunctions& Functions,
|
||||
void *Opaque);
|
||||
~SimpleBindingMemoryManager() override;
|
||||
|
||||
uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
|
||||
unsigned SectionID,
|
||||
StringRef SectionName) override;
|
||||
|
||||
uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
|
||||
unsigned SectionID, StringRef SectionName,
|
||||
bool isReadOnly) override;
|
||||
|
||||
bool finalizeMemory(std::string *ErrMsg) override;
|
||||
|
||||
private:
|
||||
SimpleBindingMMFunctions Functions;
|
||||
void *Opaque;
|
||||
};
|
||||
|
||||
SimpleBindingMemoryManager::SimpleBindingMemoryManager(
|
||||
const SimpleBindingMMFunctions& Functions,
|
||||
void *Opaque)
|
||||
: Functions(Functions), Opaque(Opaque) {
|
||||
assert(Functions.AllocateCodeSection &&
|
||||
"No AllocateCodeSection function provided!");
|
||||
assert(Functions.AllocateDataSection &&
|
||||
"No AllocateDataSection function provided!");
|
||||
assert(Functions.FinalizeMemory &&
|
||||
"No FinalizeMemory function provided!");
|
||||
assert(Functions.Destroy &&
|
||||
"No Destroy function provided!");
|
||||
}
|
||||
|
||||
SimpleBindingMemoryManager::~SimpleBindingMemoryManager() {
|
||||
Functions.Destroy(Opaque);
|
||||
}
|
||||
|
||||
uint8_t *SimpleBindingMemoryManager::allocateCodeSection(
|
||||
uintptr_t Size, unsigned Alignment, unsigned SectionID,
|
||||
StringRef SectionName) {
|
||||
return Functions.AllocateCodeSection(Opaque, Size, Alignment, SectionID,
|
||||
SectionName.str().c_str());
|
||||
}
|
||||
|
||||
uint8_t *SimpleBindingMemoryManager::allocateDataSection(
|
||||
uintptr_t Size, unsigned Alignment, unsigned SectionID,
|
||||
StringRef SectionName, bool isReadOnly) {
|
||||
return Functions.AllocateDataSection(Opaque, Size, Alignment, SectionID,
|
||||
SectionName.str().c_str(),
|
||||
isReadOnly);
|
||||
}
|
||||
|
||||
bool SimpleBindingMemoryManager::finalizeMemory(std::string *ErrMsg) {
|
||||
char *errMsgCString = nullptr;
|
||||
bool result = Functions.FinalizeMemory(Opaque, &errMsgCString);
|
||||
assert((result || !errMsgCString) &&
|
||||
"Did not expect an error message if FinalizeMemory succeeded");
|
||||
if (errMsgCString) {
|
||||
if (ErrMsg)
|
||||
*ErrMsg = errMsgCString;
|
||||
free(errMsgCString);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
LLVMMCJITMemoryManagerRef LLVMCreateSimpleMCJITMemoryManager(
|
||||
void *Opaque,
|
||||
LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection,
|
||||
LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection,
|
||||
LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory,
|
||||
LLVMMemoryManagerDestroyCallback Destroy) {
|
||||
|
||||
if (!AllocateCodeSection || !AllocateDataSection || !FinalizeMemory ||
|
||||
!Destroy)
|
||||
return nullptr;
|
||||
|
||||
SimpleBindingMMFunctions functions;
|
||||
functions.AllocateCodeSection = AllocateCodeSection;
|
||||
functions.AllocateDataSection = AllocateDataSection;
|
||||
functions.FinalizeMemory = FinalizeMemory;
|
||||
functions.Destroy = Destroy;
|
||||
return wrap(new SimpleBindingMemoryManager(functions, Opaque));
|
||||
}
|
||||
|
||||
void LLVMDisposeMCJITMemoryManager(LLVMMCJITMemoryManagerRef MM) {
|
||||
delete unwrap(MM);
|
||||
}
|
||||
|
@ -1,237 +0,0 @@
|
||||
//===----- GDBRegistrationListener.cpp - Registers objects with GDB -------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ExecutionEngine/JITEventListener.h"
|
||||
#include "llvm/Object/ObjectFile.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/ManagedStatic.h"
|
||||
#include "llvm/Support/Mutex.h"
|
||||
#include "llvm/Support/MutexGuard.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace llvm::object;
|
||||
|
||||
// This must be kept in sync with gdb/gdb/jit.h .
|
||||
extern "C" {
|
||||
|
||||
typedef enum {
|
||||
JIT_NOACTION = 0,
|
||||
JIT_REGISTER_FN,
|
||||
JIT_UNREGISTER_FN
|
||||
} jit_actions_t;
|
||||
|
||||
struct jit_code_entry {
|
||||
struct jit_code_entry *next_entry;
|
||||
struct jit_code_entry *prev_entry;
|
||||
const char *symfile_addr;
|
||||
uint64_t symfile_size;
|
||||
};
|
||||
|
||||
struct jit_descriptor {
|
||||
uint32_t version;
|
||||
// This should be jit_actions_t, but we want to be specific about the
|
||||
// bit-width.
|
||||
uint32_t action_flag;
|
||||
struct jit_code_entry *relevant_entry;
|
||||
struct jit_code_entry *first_entry;
|
||||
};
|
||||
|
||||
// We put information about the JITed function in this global, which the
|
||||
// debugger reads. Make sure to specify the version statically, because the
|
||||
// debugger checks the version before we can set it during runtime.
|
||||
struct jit_descriptor __jit_debug_descriptor = { 1, 0, nullptr, nullptr };
|
||||
|
||||
// Debuggers puts a breakpoint in this function.
|
||||
LLVM_ATTRIBUTE_NOINLINE void __jit_debug_register_code() {
|
||||
// The noinline and the asm prevent calls to this function from being
|
||||
// optimized out.
|
||||
#if !defined(_MSC_VER)
|
||||
asm volatile("":::"memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
struct RegisteredObjectInfo {
|
||||
RegisteredObjectInfo() {}
|
||||
|
||||
RegisteredObjectInfo(std::size_t Size, jit_code_entry *Entry,
|
||||
OwningBinary<ObjectFile> Obj)
|
||||
: Size(Size), Entry(Entry), Obj(std::move(Obj)) {}
|
||||
|
||||
std::size_t Size;
|
||||
jit_code_entry *Entry;
|
||||
OwningBinary<ObjectFile> Obj;
|
||||
};
|
||||
|
||||
// Buffer for an in-memory object file in executable memory
|
||||
typedef llvm::DenseMap< const char*, RegisteredObjectInfo>
|
||||
RegisteredObjectBufferMap;
|
||||
|
||||
/// Global access point for the JIT debugging interface designed for use with a
|
||||
/// singleton toolbox. Handles thread-safe registration and deregistration of
|
||||
/// object files that are in executable memory managed by the client of this
|
||||
/// class.
|
||||
class GDBJITRegistrationListener : public JITEventListener {
|
||||
/// A map of in-memory object files that have been registered with the
|
||||
/// JIT interface.
|
||||
RegisteredObjectBufferMap ObjectBufferMap;
|
||||
|
||||
public:
|
||||
/// Instantiates the JIT service.
|
||||
GDBJITRegistrationListener() : ObjectBufferMap() {}
|
||||
|
||||
/// Unregisters each object that was previously registered and releases all
|
||||
/// internal resources.
|
||||
~GDBJITRegistrationListener() override;
|
||||
|
||||
/// Creates an entry in the JIT registry for the buffer @p Object,
|
||||
/// which must contain an object file in executable memory with any
|
||||
/// debug information for the debugger.
|
||||
void NotifyObjectEmitted(const ObjectFile &Object,
|
||||
const RuntimeDyld::LoadedObjectInfo &L) override;
|
||||
|
||||
/// Removes the internal registration of @p Object, and
|
||||
/// frees associated resources.
|
||||
/// Returns true if @p Object was found in ObjectBufferMap.
|
||||
void NotifyFreeingObject(const ObjectFile &Object) override;
|
||||
|
||||
private:
|
||||
/// Deregister the debug info for the given object file from the debugger
|
||||
/// and delete any temporary copies. This private method does not remove
|
||||
/// the function from Map so that it can be called while iterating over Map.
|
||||
void deregisterObjectInternal(RegisteredObjectBufferMap::iterator I);
|
||||
};
|
||||
|
||||
/// Lock used to serialize all jit registration events, since they
|
||||
/// modify global variables.
|
||||
ManagedStatic<sys::Mutex> JITDebugLock;
|
||||
|
||||
/// Do the registration.
|
||||
void NotifyDebugger(jit_code_entry* JITCodeEntry) {
|
||||
__jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
|
||||
|
||||
// Insert this entry at the head of the list.
|
||||
JITCodeEntry->prev_entry = nullptr;
|
||||
jit_code_entry* NextEntry = __jit_debug_descriptor.first_entry;
|
||||
JITCodeEntry->next_entry = NextEntry;
|
||||
if (NextEntry) {
|
||||
NextEntry->prev_entry = JITCodeEntry;
|
||||
}
|
||||
__jit_debug_descriptor.first_entry = JITCodeEntry;
|
||||
__jit_debug_descriptor.relevant_entry = JITCodeEntry;
|
||||
__jit_debug_register_code();
|
||||
}
|
||||
|
||||
GDBJITRegistrationListener::~GDBJITRegistrationListener() {
|
||||
// Free all registered object files.
|
||||
llvm::MutexGuard locked(*JITDebugLock);
|
||||
for (RegisteredObjectBufferMap::iterator I = ObjectBufferMap.begin(),
|
||||
E = ObjectBufferMap.end();
|
||||
I != E; ++I) {
|
||||
// Call the private method that doesn't update the map so our iterator
|
||||
// doesn't break.
|
||||
deregisterObjectInternal(I);
|
||||
}
|
||||
ObjectBufferMap.clear();
|
||||
}
|
||||
|
||||
void GDBJITRegistrationListener::NotifyObjectEmitted(
|
||||
const ObjectFile &Object,
|
||||
const RuntimeDyld::LoadedObjectInfo &L) {
|
||||
|
||||
OwningBinary<ObjectFile> DebugObj = L.getObjectForDebug(Object);
|
||||
|
||||
// Bail out if debug objects aren't supported.
|
||||
if (!DebugObj.getBinary())
|
||||
return;
|
||||
|
||||
const char *Buffer = DebugObj.getBinary()->getMemoryBufferRef().getBufferStart();
|
||||
size_t Size = DebugObj.getBinary()->getMemoryBufferRef().getBufferSize();
|
||||
|
||||
const char *Key = Object.getMemoryBufferRef().getBufferStart();
|
||||
|
||||
assert(Key && "Attempt to register a null object with a debugger.");
|
||||
llvm::MutexGuard locked(*JITDebugLock);
|
||||
assert(ObjectBufferMap.find(Key) == ObjectBufferMap.end() &&
|
||||
"Second attempt to perform debug registration.");
|
||||
jit_code_entry* JITCodeEntry = new jit_code_entry();
|
||||
|
||||
if (!JITCodeEntry) {
|
||||
llvm::report_fatal_error(
|
||||
"Allocation failed when registering a JIT entry!\n");
|
||||
} else {
|
||||
JITCodeEntry->symfile_addr = Buffer;
|
||||
JITCodeEntry->symfile_size = Size;
|
||||
|
||||
ObjectBufferMap[Key] = RegisteredObjectInfo(Size, JITCodeEntry,
|
||||
std::move(DebugObj));
|
||||
NotifyDebugger(JITCodeEntry);
|
||||
}
|
||||
}
|
||||
|
||||
void GDBJITRegistrationListener::NotifyFreeingObject(const ObjectFile& Object) {
|
||||
const char *Key = Object.getMemoryBufferRef().getBufferStart();
|
||||
llvm::MutexGuard locked(*JITDebugLock);
|
||||
RegisteredObjectBufferMap::iterator I = ObjectBufferMap.find(Key);
|
||||
|
||||
if (I != ObjectBufferMap.end()) {
|
||||
deregisterObjectInternal(I);
|
||||
ObjectBufferMap.erase(I);
|
||||
}
|
||||
}
|
||||
|
||||
void GDBJITRegistrationListener::deregisterObjectInternal(
|
||||
RegisteredObjectBufferMap::iterator I) {
|
||||
|
||||
jit_code_entry*& JITCodeEntry = I->second.Entry;
|
||||
|
||||
// Do the unregistration.
|
||||
{
|
||||
__jit_debug_descriptor.action_flag = JIT_UNREGISTER_FN;
|
||||
|
||||
// Remove the jit_code_entry from the linked list.
|
||||
jit_code_entry* PrevEntry = JITCodeEntry->prev_entry;
|
||||
jit_code_entry* NextEntry = JITCodeEntry->next_entry;
|
||||
|
||||
if (NextEntry) {
|
||||
NextEntry->prev_entry = PrevEntry;
|
||||
}
|
||||
if (PrevEntry) {
|
||||
PrevEntry->next_entry = NextEntry;
|
||||
}
|
||||
else {
|
||||
assert(__jit_debug_descriptor.first_entry == JITCodeEntry);
|
||||
__jit_debug_descriptor.first_entry = NextEntry;
|
||||
}
|
||||
|
||||
// Tell the debugger which entry we removed, and unregister the code.
|
||||
__jit_debug_descriptor.relevant_entry = JITCodeEntry;
|
||||
__jit_debug_register_code();
|
||||
}
|
||||
|
||||
delete JITCodeEntry;
|
||||
JITCodeEntry = nullptr;
|
||||
}
|
||||
|
||||
llvm::ManagedStatic<GDBJITRegistrationListener> GDBRegListener;
|
||||
|
||||
} // end namespace
|
||||
|
||||
namespace llvm {
|
||||
|
||||
JITEventListener* JITEventListener::createGDBRegistrationListener() {
|
||||
return &*GDBRegListener;
|
||||
}
|
||||
|
||||
} // namespace llvm
|
@ -1,17 +0,0 @@
|
||||
include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. )
|
||||
|
||||
if( HAVE_LIBDL )
|
||||
set(LLVM_INTEL_JIT_LIBS ${CMAKE_DL_LIBS})
|
||||
endif()
|
||||
|
||||
set(LLVM_INTEL_JIT_LIBS ${LLVM_PTHREAD_LIB} ${LLVM_INTEL_JIT_LIBS})
|
||||
|
||||
|
||||
add_llvm_library(LLVMIntelJITEvents
|
||||
IntelJITEventListener.cpp
|
||||
jitprofiling.c
|
||||
|
||||
LINK_LIBS ${LLVM_INTEL_JIT_LIBS}
|
||||
)
|
||||
|
||||
add_dependencies(LLVMIntelJITEvents LLVMCodeGen)
|
@ -1,240 +0,0 @@
|
||||
//===-- IntelJITEventListener.cpp - Tell Intel profiler about JITed code --===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines a JITEventListener object to tell Intel(R) VTune(TM)
|
||||
// Amplifier XE 2011 about JITted functions.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "IntelJITEventsWrapper.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/Config/config.h"
|
||||
#include "llvm/DebugInfo/DIContext.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
||||
#include "llvm/ExecutionEngine/JITEventListener.h"
|
||||
#include "llvm/IR/DebugInfo.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/Metadata.h"
|
||||
#include "llvm/IR/ValueHandle.h"
|
||||
#include "llvm/Object/ObjectFile.h"
|
||||
#include "llvm/Object/SymbolSize.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/Errno.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace llvm::object;
|
||||
|
||||
#define DEBUG_TYPE "amplifier-jit-event-listener"
|
||||
|
||||
namespace {
|
||||
|
||||
class IntelJITEventListener : public JITEventListener {
|
||||
typedef DenseMap<void*, unsigned int> MethodIDMap;
|
||||
|
||||
std::unique_ptr<IntelJITEventsWrapper> Wrapper;
|
||||
MethodIDMap MethodIDs;
|
||||
|
||||
typedef SmallVector<const void *, 64> MethodAddressVector;
|
||||
typedef DenseMap<const void *, MethodAddressVector> ObjectMap;
|
||||
|
||||
ObjectMap LoadedObjectMap;
|
||||
std::map<const char*, OwningBinary<ObjectFile>> DebugObjects;
|
||||
|
||||
public:
|
||||
IntelJITEventListener(IntelJITEventsWrapper* libraryWrapper) {
|
||||
Wrapper.reset(libraryWrapper);
|
||||
}
|
||||
|
||||
~IntelJITEventListener() {
|
||||
}
|
||||
|
||||
void NotifyObjectEmitted(const ObjectFile &Obj,
|
||||
const RuntimeDyld::LoadedObjectInfo &L) override;
|
||||
|
||||
void NotifyFreeingObject(const ObjectFile &Obj) override;
|
||||
};
|
||||
|
||||
static LineNumberInfo DILineInfoToIntelJITFormat(uintptr_t StartAddress,
|
||||
uintptr_t Address,
|
||||
DILineInfo Line) {
|
||||
LineNumberInfo Result;
|
||||
|
||||
Result.Offset = Address - StartAddress;
|
||||
Result.LineNumber = Line.Line;
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
static iJIT_Method_Load FunctionDescToIntelJITFormat(
|
||||
IntelJITEventsWrapper& Wrapper,
|
||||
const char* FnName,
|
||||
uintptr_t FnStart,
|
||||
size_t FnSize) {
|
||||
iJIT_Method_Load Result;
|
||||
memset(&Result, 0, sizeof(iJIT_Method_Load));
|
||||
|
||||
Result.method_id = Wrapper.iJIT_GetNewMethodID();
|
||||
Result.method_name = const_cast<char*>(FnName);
|
||||
Result.method_load_address = reinterpret_cast<void*>(FnStart);
|
||||
Result.method_size = FnSize;
|
||||
|
||||
Result.class_id = 0;
|
||||
Result.class_file_name = NULL;
|
||||
Result.user_data = NULL;
|
||||
Result.user_data_size = 0;
|
||||
Result.env = iJDE_JittingAPI;
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
void IntelJITEventListener::NotifyObjectEmitted(
|
||||
const ObjectFile &Obj,
|
||||
const RuntimeDyld::LoadedObjectInfo &L) {
|
||||
|
||||
OwningBinary<ObjectFile> DebugObjOwner = L.getObjectForDebug(Obj);
|
||||
const ObjectFile &DebugObj = *DebugObjOwner.getBinary();
|
||||
|
||||
// Get the address of the object image for use as a unique identifier
|
||||
const void* ObjData = DebugObj.getData().data();
|
||||
std::unique_ptr<DIContext> Context = DWARFContext::create(DebugObj);
|
||||
MethodAddressVector Functions;
|
||||
|
||||
// Use symbol info to iterate functions in the object.
|
||||
for (const std::pair<SymbolRef, uint64_t> &P : computeSymbolSizes(DebugObj)) {
|
||||
SymbolRef Sym = P.first;
|
||||
std::vector<LineNumberInfo> LineInfo;
|
||||
std::string SourceFileName;
|
||||
|
||||
Expected<SymbolRef::Type> SymTypeOrErr = Sym.getType();
|
||||
if (!SymTypeOrErr) {
|
||||
// TODO: Actually report errors helpfully.
|
||||
consumeError(SymTypeOrErr.takeError());
|
||||
continue;
|
||||
}
|
||||
SymbolRef::Type SymType = *SymTypeOrErr;
|
||||
if (SymType != SymbolRef::ST_Function)
|
||||
continue;
|
||||
|
||||
Expected<StringRef> Name = Sym.getName();
|
||||
if (!Name) {
|
||||
// TODO: Actually report errors helpfully.
|
||||
consumeError(Name.takeError());
|
||||
continue;
|
||||
}
|
||||
|
||||
Expected<uint64_t> AddrOrErr = Sym.getAddress();
|
||||
if (!AddrOrErr) {
|
||||
// TODO: Actually report errors helpfully.
|
||||
consumeError(AddrOrErr.takeError());
|
||||
continue;
|
||||
}
|
||||
uint64_t Addr = *AddrOrErr;
|
||||
uint64_t Size = P.second;
|
||||
|
||||
// Record this address in a local vector
|
||||
Functions.push_back((void*)Addr);
|
||||
|
||||
// Build the function loaded notification message
|
||||
iJIT_Method_Load FunctionMessage =
|
||||
FunctionDescToIntelJITFormat(*Wrapper, Name->data(), Addr, Size);
|
||||
DILineInfoTable Lines = Context->getLineInfoForAddressRange(Addr, Size);
|
||||
DILineInfoTable::iterator Begin = Lines.begin();
|
||||
DILineInfoTable::iterator End = Lines.end();
|
||||
for (DILineInfoTable::iterator It = Begin; It != End; ++It) {
|
||||
LineInfo.push_back(
|
||||
DILineInfoToIntelJITFormat((uintptr_t)Addr, It->first, It->second));
|
||||
}
|
||||
if (LineInfo.size() == 0) {
|
||||
FunctionMessage.source_file_name = 0;
|
||||
FunctionMessage.line_number_size = 0;
|
||||
FunctionMessage.line_number_table = 0;
|
||||
} else {
|
||||
// Source line information for the address range is provided as
|
||||
// a code offset for the start of the corresponding sub-range and
|
||||
// a source line. JIT API treats offsets in LineNumberInfo structures
|
||||
// as the end of the corresponding code region. The start of the code
|
||||
// is taken from the previous element. Need to shift the elements.
|
||||
|
||||
LineNumberInfo last = LineInfo.back();
|
||||
last.Offset = FunctionMessage.method_size;
|
||||
LineInfo.push_back(last);
|
||||
for (size_t i = LineInfo.size() - 2; i > 0; --i)
|
||||
LineInfo[i].LineNumber = LineInfo[i - 1].LineNumber;
|
||||
|
||||
SourceFileName = Lines.front().second.FileName;
|
||||
FunctionMessage.source_file_name =
|
||||
const_cast<char *>(SourceFileName.c_str());
|
||||
FunctionMessage.line_number_size = LineInfo.size();
|
||||
FunctionMessage.line_number_table = &*LineInfo.begin();
|
||||
}
|
||||
|
||||
Wrapper->iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED,
|
||||
&FunctionMessage);
|
||||
MethodIDs[(void*)Addr] = FunctionMessage.method_id;
|
||||
}
|
||||
|
||||
// To support object unload notification, we need to keep a list of
|
||||
// registered function addresses for each loaded object. We will
|
||||
// use the MethodIDs map to get the registered ID for each function.
|
||||
LoadedObjectMap[ObjData] = Functions;
|
||||
DebugObjects[Obj.getData().data()] = std::move(DebugObjOwner);
|
||||
}
|
||||
|
||||
void IntelJITEventListener::NotifyFreeingObject(const ObjectFile &Obj) {
|
||||
// This object may not have been registered with the listener. If it wasn't,
|
||||
// bail out.
|
||||
if (DebugObjects.find(Obj.getData().data()) == DebugObjects.end())
|
||||
return;
|
||||
|
||||
// Get the address of the object image for use as a unique identifier
|
||||
const ObjectFile &DebugObj = *DebugObjects[Obj.getData().data()].getBinary();
|
||||
const void* ObjData = DebugObj.getData().data();
|
||||
|
||||
// Get the object's function list from LoadedObjectMap
|
||||
ObjectMap::iterator OI = LoadedObjectMap.find(ObjData);
|
||||
if (OI == LoadedObjectMap.end())
|
||||
return;
|
||||
MethodAddressVector& Functions = OI->second;
|
||||
|
||||
// Walk the function list, unregistering each function
|
||||
for (MethodAddressVector::iterator FI = Functions.begin(),
|
||||
FE = Functions.end();
|
||||
FI != FE;
|
||||
++FI) {
|
||||
void* FnStart = const_cast<void*>(*FI);
|
||||
MethodIDMap::iterator MI = MethodIDs.find(FnStart);
|
||||
if (MI != MethodIDs.end()) {
|
||||
Wrapper->iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_UNLOAD_START,
|
||||
&MI->second);
|
||||
MethodIDs.erase(MI);
|
||||
}
|
||||
}
|
||||
|
||||
// Erase the object from LoadedObjectMap
|
||||
LoadedObjectMap.erase(OI);
|
||||
DebugObjects.erase(Obj.getData().data());
|
||||
}
|
||||
|
||||
} // anonymous namespace.
|
||||
|
||||
namespace llvm {
|
||||
JITEventListener *JITEventListener::createIntelJITEventListener() {
|
||||
return new IntelJITEventListener(new IntelJITEventsWrapper);
|
||||
}
|
||||
|
||||
// for testing
|
||||
JITEventListener *JITEventListener::createIntelJITEventListener(
|
||||
IntelJITEventsWrapper* TestImpl) {
|
||||
return new IntelJITEventListener(TestImpl);
|
||||
}
|
||||
|
||||
} // namespace llvm
|
||||
|
@ -1,96 +0,0 @@
|
||||
//===-- IntelJITEventsWrapper.h - Intel JIT Events API Wrapper --*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines a wrapper for the Intel JIT Events API. It allows for the
|
||||
// implementation of the jitprofiling library to be swapped with an alternative
|
||||
// implementation (for testing). To include this file, you must have the
|
||||
// jitprofiling.h header available; it is available in Intel(R) VTune(TM)
|
||||
// Amplifier XE 2011.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef INTEL_JIT_EVENTS_WRAPPER_H
|
||||
#define INTEL_JIT_EVENTS_WRAPPER_H
|
||||
|
||||
#include "jitprofiling.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class IntelJITEventsWrapper {
|
||||
// Function pointer types for testing implementation of Intel jitprofiling
|
||||
// library
|
||||
typedef int (*NotifyEventPtr)(iJIT_JVM_EVENT, void*);
|
||||
typedef void (*RegisterCallbackExPtr)(void *, iJIT_ModeChangedEx );
|
||||
typedef iJIT_IsProfilingActiveFlags (*IsProfilingActivePtr)(void);
|
||||
typedef void (*FinalizeThreadPtr)(void);
|
||||
typedef void (*FinalizeProcessPtr)(void);
|
||||
typedef unsigned int (*GetNewMethodIDPtr)(void);
|
||||
|
||||
NotifyEventPtr NotifyEventFunc;
|
||||
RegisterCallbackExPtr RegisterCallbackExFunc;
|
||||
IsProfilingActivePtr IsProfilingActiveFunc;
|
||||
GetNewMethodIDPtr GetNewMethodIDFunc;
|
||||
|
||||
public:
|
||||
bool isAmplifierRunning() {
|
||||
return iJIT_IsProfilingActive() == iJIT_SAMPLING_ON;
|
||||
}
|
||||
|
||||
IntelJITEventsWrapper()
|
||||
: NotifyEventFunc(::iJIT_NotifyEvent),
|
||||
RegisterCallbackExFunc(::iJIT_RegisterCallbackEx),
|
||||
IsProfilingActiveFunc(::iJIT_IsProfilingActive),
|
||||
GetNewMethodIDFunc(::iJIT_GetNewMethodID) {
|
||||
}
|
||||
|
||||
IntelJITEventsWrapper(NotifyEventPtr NotifyEventImpl,
|
||||
RegisterCallbackExPtr RegisterCallbackExImpl,
|
||||
IsProfilingActivePtr IsProfilingActiveImpl,
|
||||
FinalizeThreadPtr FinalizeThreadImpl,
|
||||
FinalizeProcessPtr FinalizeProcessImpl,
|
||||
GetNewMethodIDPtr GetNewMethodIDImpl)
|
||||
: NotifyEventFunc(NotifyEventImpl),
|
||||
RegisterCallbackExFunc(RegisterCallbackExImpl),
|
||||
IsProfilingActiveFunc(IsProfilingActiveImpl),
|
||||
GetNewMethodIDFunc(GetNewMethodIDImpl) {
|
||||
}
|
||||
|
||||
// Sends an event announcing that a function has been emitted
|
||||
// return values are event-specific. See Intel documentation for details.
|
||||
int iJIT_NotifyEvent(iJIT_JVM_EVENT EventType, void *EventSpecificData) {
|
||||
if (!NotifyEventFunc)
|
||||
return -1;
|
||||
return NotifyEventFunc(EventType, EventSpecificData);
|
||||
}
|
||||
|
||||
// Registers a callback function to receive notice of profiling state changes
|
||||
void iJIT_RegisterCallbackEx(void *UserData,
|
||||
iJIT_ModeChangedEx NewModeCallBackFuncEx) {
|
||||
if (RegisterCallbackExFunc)
|
||||
RegisterCallbackExFunc(UserData, NewModeCallBackFuncEx);
|
||||
}
|
||||
|
||||
// Returns the current profiler mode
|
||||
iJIT_IsProfilingActiveFlags iJIT_IsProfilingActive(void) {
|
||||
if (!IsProfilingActiveFunc)
|
||||
return iJIT_NOTHING_RUNNING;
|
||||
return IsProfilingActiveFunc();
|
||||
}
|
||||
|
||||
// Generates a locally unique method ID for use in code registration
|
||||
unsigned int iJIT_GetNewMethodID(void) {
|
||||
if (!GetNewMethodIDFunc)
|
||||
return -1;
|
||||
return GetNewMethodIDFunc();
|
||||
}
|
||||
};
|
||||
|
||||
} //namespace llvm
|
||||
|
||||
#endif //INTEL_JIT_EVENTS_WRAPPER_H
|
@ -1,24 +0,0 @@
|
||||
;===- ./lib/ExecutionEngine/JITProfileAmplifier/LLVMBuild.txt --*- Conf -*--===;
|
||||
;
|
||||
; The LLVM Compiler Infrastructure
|
||||
;
|
||||
; This file is distributed under the University of Illinois Open Source
|
||||
; License. See LICENSE.TXT for details.
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
;
|
||||
; This is an LLVMBuild description file for the components in this subdirectory.
|
||||
;
|
||||
; For more information on the LLVMBuild system, please see:
|
||||
;
|
||||
; http://llvm.org/docs/LLVMBuild.html
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
|
||||
[common]
|
||||
|
||||
[component_0]
|
||||
type = OptionalLibrary
|
||||
name = IntelJITEvents
|
||||
parent = ExecutionEngine
|
||||
required_libraries = CodeGen Core DebugInfoDWARF Support Object ExecutionEngine
|
@ -1,454 +0,0 @@
|
||||
/*===-- ittnotify_config.h - JIT Profiling API internal config-----*- C -*-===*
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
* This file is distributed under the University of Illinois Open Source
|
||||
* License. See LICENSE.TXT for details.
|
||||
*
|
||||
*===----------------------------------------------------------------------===*
|
||||
*
|
||||
* This file provides Intel(R) Performance Analyzer JIT (Just-In-Time)
|
||||
* Profiling API internal config.
|
||||
*
|
||||
* NOTE: This file comes in a style different from the rest of LLVM
|
||||
* source base since this is a piece of code shared from Intel(R)
|
||||
* products. Please do not reformat / re-style this code to make
|
||||
* subsequent merges and contributions from the original source base eaiser.
|
||||
*
|
||||
*===----------------------------------------------------------------------===*/
|
||||
#ifndef _ITTNOTIFY_CONFIG_H_
|
||||
#define _ITTNOTIFY_CONFIG_H_
|
||||
|
||||
/** @cond exclude_from_documentation */
|
||||
#ifndef ITT_OS_WIN
|
||||
# define ITT_OS_WIN 1
|
||||
#endif /* ITT_OS_WIN */
|
||||
|
||||
#ifndef ITT_OS_LINUX
|
||||
# define ITT_OS_LINUX 2
|
||||
#endif /* ITT_OS_LINUX */
|
||||
|
||||
#ifndef ITT_OS_MAC
|
||||
# define ITT_OS_MAC 3
|
||||
#endif /* ITT_OS_MAC */
|
||||
|
||||
#ifndef ITT_OS
|
||||
# if defined WIN32 || defined _WIN32
|
||||
# define ITT_OS ITT_OS_WIN
|
||||
# elif defined( __APPLE__ ) && defined( __MACH__ )
|
||||
# define ITT_OS ITT_OS_MAC
|
||||
# else
|
||||
# define ITT_OS ITT_OS_LINUX
|
||||
# endif
|
||||
#endif /* ITT_OS */
|
||||
|
||||
#ifndef ITT_PLATFORM_WIN
|
||||
# define ITT_PLATFORM_WIN 1
|
||||
#endif /* ITT_PLATFORM_WIN */
|
||||
|
||||
#ifndef ITT_PLATFORM_POSIX
|
||||
# define ITT_PLATFORM_POSIX 2
|
||||
#endif /* ITT_PLATFORM_POSIX */
|
||||
|
||||
#ifndef ITT_PLATFORM
|
||||
# if ITT_OS==ITT_OS_WIN
|
||||
# define ITT_PLATFORM ITT_PLATFORM_WIN
|
||||
# else
|
||||
# define ITT_PLATFORM ITT_PLATFORM_POSIX
|
||||
# endif /* _WIN32 */
|
||||
#endif /* ITT_PLATFORM */
|
||||
|
||||
#if defined(_UNICODE) && !defined(UNICODE)
|
||||
#define UNICODE
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||
#include <tchar.h>
|
||||
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
#include <stdint.h>
|
||||
#if defined(UNICODE) || defined(_UNICODE)
|
||||
#include <wchar.h>
|
||||
#endif /* UNICODE || _UNICODE */
|
||||
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
|
||||
#ifndef CDECL
|
||||
# if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||
# define CDECL __cdecl
|
||||
# else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
# if defined _M_X64 || defined _M_AMD64 || defined __x86_64__
|
||||
# define CDECL /* not actual on x86_64 platform */
|
||||
# else /* _M_X64 || _M_AMD64 || __x86_64__ */
|
||||
# define CDECL __attribute__ ((cdecl))
|
||||
# endif /* _M_X64 || _M_AMD64 || __x86_64__ */
|
||||
# endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
#endif /* CDECL */
|
||||
|
||||
#ifndef STDCALL
|
||||
# if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||
# define STDCALL __stdcall
|
||||
# else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
# if defined _M_X64 || defined _M_AMD64 || defined __x86_64__
|
||||
# define STDCALL /* not supported on x86_64 platform */
|
||||
# else /* _M_X64 || _M_AMD64 || __x86_64__ */
|
||||
# define STDCALL __attribute__ ((stdcall))
|
||||
# endif /* _M_X64 || _M_AMD64 || __x86_64__ */
|
||||
# endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
#endif /* STDCALL */
|
||||
|
||||
#define ITTAPI CDECL
|
||||
#define LIBITTAPI CDECL
|
||||
|
||||
/* TODO: Temporary for compatibility! */
|
||||
#define ITTAPI_CALL CDECL
|
||||
#define LIBITTAPI_CALL CDECL
|
||||
|
||||
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||
/* use __forceinline (VC++ specific) */
|
||||
#define ITT_INLINE __forceinline
|
||||
#define ITT_INLINE_ATTRIBUTE /* nothing */
|
||||
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
/*
|
||||
* Generally, functions are not inlined unless optimization is specified.
|
||||
* For functions declared inline, this attribute inlines the function even
|
||||
* if no optimization level was specified.
|
||||
*/
|
||||
#ifdef __STRICT_ANSI__
|
||||
#define ITT_INLINE static
|
||||
#else /* __STRICT_ANSI__ */
|
||||
#define ITT_INLINE static inline
|
||||
#endif /* __STRICT_ANSI__ */
|
||||
#define ITT_INLINE_ATTRIBUTE __attribute__ ((always_inline))
|
||||
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
/** @endcond */
|
||||
|
||||
#ifndef ITT_ARCH_IA32
|
||||
# define ITT_ARCH_IA32 1
|
||||
#endif /* ITT_ARCH_IA32 */
|
||||
|
||||
#ifndef ITT_ARCH_IA32E
|
||||
# define ITT_ARCH_IA32E 2
|
||||
#endif /* ITT_ARCH_IA32E */
|
||||
|
||||
#ifndef ITT_ARCH_IA64
|
||||
# define ITT_ARCH_IA64 3
|
||||
#endif /* ITT_ARCH_IA64 */
|
||||
|
||||
#ifndef ITT_ARCH
|
||||
# if defined _M_X64 || defined _M_AMD64 || defined __x86_64__
|
||||
# define ITT_ARCH ITT_ARCH_IA32E
|
||||
# elif defined _M_IA64 || defined __ia64
|
||||
# define ITT_ARCH ITT_ARCH_IA64
|
||||
# else
|
||||
# define ITT_ARCH ITT_ARCH_IA32
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
# define ITT_EXTERN_C extern "C"
|
||||
#else
|
||||
# define ITT_EXTERN_C /* nothing */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define ITT_TO_STR_AUX(x) #x
|
||||
#define ITT_TO_STR(x) ITT_TO_STR_AUX(x)
|
||||
|
||||
#define __ITT_BUILD_ASSERT(expr, suffix) do { \
|
||||
static char __itt_build_check_##suffix[(expr) ? 1 : -1]; \
|
||||
__itt_build_check_##suffix[0] = 0; \
|
||||
} while(0)
|
||||
#define _ITT_BUILD_ASSERT(expr, suffix) __ITT_BUILD_ASSERT((expr), suffix)
|
||||
#define ITT_BUILD_ASSERT(expr) _ITT_BUILD_ASSERT((expr), __LINE__)
|
||||
|
||||
#define ITT_MAGIC { 0xED, 0xAB, 0xAB, 0xEC, 0x0D, 0xEE, 0xDA, 0x30 }
|
||||
|
||||
/* Replace with snapshot date YYYYMMDD for promotion build. */
|
||||
#define API_VERSION_BUILD 20111111
|
||||
|
||||
#ifndef API_VERSION_NUM
|
||||
#define API_VERSION_NUM 0.0.0
|
||||
#endif /* API_VERSION_NUM */
|
||||
|
||||
#define API_VERSION "ITT-API-Version " ITT_TO_STR(API_VERSION_NUM) \
|
||||
" (" ITT_TO_STR(API_VERSION_BUILD) ")"
|
||||
|
||||
/* OS communication functions */
|
||||
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||
#include <windows.h>
|
||||
typedef HMODULE lib_t;
|
||||
typedef DWORD TIDT;
|
||||
typedef CRITICAL_SECTION mutex_t;
|
||||
#define MUTEX_INITIALIZER { 0 }
|
||||
#define strong_alias(name, aliasname) /* empty for Windows */
|
||||
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
#include <dlfcn.h>
|
||||
#if defined(UNICODE) || defined(_UNICODE)
|
||||
#include <wchar.h>
|
||||
#endif /* UNICODE */
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE 1 /* need for PTHREAD_MUTEX_RECURSIVE */
|
||||
#endif /* _GNU_SOURCE */
|
||||
#include <pthread.h>
|
||||
typedef void* lib_t;
|
||||
typedef pthread_t TIDT;
|
||||
typedef pthread_mutex_t mutex_t;
|
||||
#define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
||||
#define _strong_alias(name, aliasname) \
|
||||
extern __typeof (name) aliasname __attribute__ ((alias (#name)));
|
||||
#define strong_alias(name, aliasname) _strong_alias(name, aliasname)
|
||||
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
|
||||
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||
#define __itt_get_proc(lib, name) GetProcAddress(lib, name)
|
||||
#define __itt_mutex_init(mutex) InitializeCriticalSection(mutex)
|
||||
#define __itt_mutex_lock(mutex) EnterCriticalSection(mutex)
|
||||
#define __itt_mutex_unlock(mutex) LeaveCriticalSection(mutex)
|
||||
#define __itt_load_lib(name) LoadLibraryA(name)
|
||||
#define __itt_unload_lib(handle) FreeLibrary(handle)
|
||||
#define __itt_system_error() (int)GetLastError()
|
||||
#define __itt_fstrcmp(s1, s2) lstrcmpA(s1, s2)
|
||||
#define __itt_fstrlen(s) lstrlenA(s)
|
||||
#define __itt_fstrcpyn(s1, s2, l) lstrcpynA(s1, s2, l)
|
||||
#define __itt_fstrdup(s) _strdup(s)
|
||||
#define __itt_thread_id() GetCurrentThreadId()
|
||||
#define __itt_thread_yield() SwitchToThread()
|
||||
#ifndef ITT_SIMPLE_INIT
|
||||
ITT_INLINE long
|
||||
__itt_interlocked_increment(volatile long* ptr) ITT_INLINE_ATTRIBUTE;
|
||||
ITT_INLINE long __itt_interlocked_increment(volatile long* ptr)
|
||||
{
|
||||
return InterlockedIncrement(ptr);
|
||||
}
|
||||
#endif /* ITT_SIMPLE_INIT */
|
||||
#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */
|
||||
#define __itt_get_proc(lib, name) dlsym(lib, name)
|
||||
#define __itt_mutex_init(mutex) {\
|
||||
pthread_mutexattr_t mutex_attr; \
|
||||
int error_code = pthread_mutexattr_init(&mutex_attr); \
|
||||
if (error_code) \
|
||||
__itt_report_error(__itt_error_system, "pthread_mutexattr_init", \
|
||||
error_code); \
|
||||
error_code = pthread_mutexattr_settype(&mutex_attr, \
|
||||
PTHREAD_MUTEX_RECURSIVE); \
|
||||
if (error_code) \
|
||||
__itt_report_error(__itt_error_system, "pthread_mutexattr_settype", \
|
||||
error_code); \
|
||||
error_code = pthread_mutex_init(mutex, &mutex_attr); \
|
||||
if (error_code) \
|
||||
__itt_report_error(__itt_error_system, "pthread_mutex_init", \
|
||||
error_code); \
|
||||
error_code = pthread_mutexattr_destroy(&mutex_attr); \
|
||||
if (error_code) \
|
||||
__itt_report_error(__itt_error_system, "pthread_mutexattr_destroy", \
|
||||
error_code); \
|
||||
}
|
||||
#define __itt_mutex_lock(mutex) pthread_mutex_lock(mutex)
|
||||
#define __itt_mutex_unlock(mutex) pthread_mutex_unlock(mutex)
|
||||
#define __itt_load_lib(name) dlopen(name, RTLD_LAZY)
|
||||
#define __itt_unload_lib(handle) dlclose(handle)
|
||||
#define __itt_system_error() errno
|
||||
#define __itt_fstrcmp(s1, s2) strcmp(s1, s2)
|
||||
#define __itt_fstrlen(s) strlen(s)
|
||||
#define __itt_fstrcpyn(s1, s2, l) strncpy(s1, s2, l)
|
||||
#define __itt_fstrdup(s) strdup(s)
|
||||
#define __itt_thread_id() pthread_self()
|
||||
#define __itt_thread_yield() sched_yield()
|
||||
#if ITT_ARCH==ITT_ARCH_IA64
|
||||
#ifdef __INTEL_COMPILER
|
||||
#define __TBB_machine_fetchadd4(addr, val) __fetchadd4_acq((void *)addr, val)
|
||||
#else /* __INTEL_COMPILER */
|
||||
/* TODO: Add Support for not Intel compilers for IA64 */
|
||||
#endif /* __INTEL_COMPILER */
|
||||
#else /* ITT_ARCH!=ITT_ARCH_IA64 */
|
||||
ITT_INLINE long
|
||||
__TBB_machine_fetchadd4(volatile void* ptr, long addend) ITT_INLINE_ATTRIBUTE;
|
||||
ITT_INLINE long __TBB_machine_fetchadd4(volatile void* ptr, long addend)
|
||||
{
|
||||
long result;
|
||||
__asm__ __volatile__("lock\nxadd %0,%1"
|
||||
: "=r"(result),"=m"(*(long*)ptr)
|
||||
: "0"(addend), "m"(*(long*)ptr)
|
||||
: "memory");
|
||||
return result;
|
||||
}
|
||||
#endif /* ITT_ARCH==ITT_ARCH_IA64 */
|
||||
#ifndef ITT_SIMPLE_INIT
|
||||
ITT_INLINE long
|
||||
__itt_interlocked_increment(volatile long* ptr) ITT_INLINE_ATTRIBUTE;
|
||||
ITT_INLINE long __itt_interlocked_increment(volatile long* ptr)
|
||||
{
|
||||
return __TBB_machine_fetchadd4(ptr, 1) + 1L;
|
||||
}
|
||||
#endif /* ITT_SIMPLE_INIT */
|
||||
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
|
||||
typedef enum {
|
||||
__itt_collection_normal = 0,
|
||||
__itt_collection_paused = 1
|
||||
} __itt_collection_state;
|
||||
|
||||
typedef enum {
|
||||
__itt_thread_normal = 0,
|
||||
__itt_thread_ignored = 1
|
||||
} __itt_thread_state;
|
||||
|
||||
#pragma pack(push, 8)
|
||||
|
||||
typedef struct ___itt_thread_info
|
||||
{
|
||||
const char* nameA; /*!< Copy of original name in ASCII. */
|
||||
#if defined(UNICODE) || defined(_UNICODE)
|
||||
const wchar_t* nameW; /*!< Copy of original name in UNICODE. */
|
||||
#else /* UNICODE || _UNICODE */
|
||||
void* nameW;
|
||||
#endif /* UNICODE || _UNICODE */
|
||||
TIDT tid;
|
||||
__itt_thread_state state; /*!< Thread state (paused or normal) */
|
||||
int extra1; /*!< Reserved to the runtime */
|
||||
void* extra2; /*!< Reserved to the runtime */
|
||||
struct ___itt_thread_info* next;
|
||||
} __itt_thread_info;
|
||||
|
||||
#include "ittnotify_types.h" /* For __itt_group_id definition */
|
||||
|
||||
typedef struct ___itt_api_info_20101001
|
||||
{
|
||||
const char* name;
|
||||
void** func_ptr;
|
||||
void* init_func;
|
||||
__itt_group_id group;
|
||||
} __itt_api_info_20101001;
|
||||
|
||||
typedef struct ___itt_api_info
|
||||
{
|
||||
const char* name;
|
||||
void** func_ptr;
|
||||
void* init_func;
|
||||
void* null_func;
|
||||
__itt_group_id group;
|
||||
} __itt_api_info;
|
||||
|
||||
struct ___itt_domain;
|
||||
struct ___itt_string_handle;
|
||||
|
||||
typedef struct ___itt_global
|
||||
{
|
||||
unsigned char magic[8];
|
||||
unsigned long version_major;
|
||||
unsigned long version_minor;
|
||||
unsigned long version_build;
|
||||
volatile long api_initialized;
|
||||
volatile long mutex_initialized;
|
||||
volatile long atomic_counter;
|
||||
mutex_t mutex;
|
||||
lib_t lib;
|
||||
void* error_handler;
|
||||
const char** dll_path_ptr;
|
||||
__itt_api_info* api_list_ptr;
|
||||
struct ___itt_global* next;
|
||||
/* Joinable structures below */
|
||||
__itt_thread_info* thread_list;
|
||||
struct ___itt_domain* domain_list;
|
||||
struct ___itt_string_handle* string_list;
|
||||
__itt_collection_state state;
|
||||
} __itt_global;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#define NEW_THREAD_INFO_W(gptr,h,h_tail,t,s,n) { \
|
||||
h = (__itt_thread_info*)malloc(sizeof(__itt_thread_info)); \
|
||||
if (h != NULL) { \
|
||||
h->tid = t; \
|
||||
h->nameA = NULL; \
|
||||
h->nameW = n ? _wcsdup(n) : NULL; \
|
||||
h->state = s; \
|
||||
h->extra1 = 0; /* reserved */ \
|
||||
h->extra2 = NULL; /* reserved */ \
|
||||
h->next = NULL; \
|
||||
if (h_tail == NULL) \
|
||||
(gptr)->thread_list = h; \
|
||||
else \
|
||||
h_tail->next = h; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define NEW_THREAD_INFO_A(gptr,h,h_tail,t,s,n) { \
|
||||
h = (__itt_thread_info*)malloc(sizeof(__itt_thread_info)); \
|
||||
if (h != NULL) { \
|
||||
h->tid = t; \
|
||||
h->nameA = n ? __itt_fstrdup(n) : NULL; \
|
||||
h->nameW = NULL; \
|
||||
h->state = s; \
|
||||
h->extra1 = 0; /* reserved */ \
|
||||
h->extra2 = NULL; /* reserved */ \
|
||||
h->next = NULL; \
|
||||
if (h_tail == NULL) \
|
||||
(gptr)->thread_list = h; \
|
||||
else \
|
||||
h_tail->next = h; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define NEW_DOMAIN_W(gptr,h,h_tail,name) { \
|
||||
h = (__itt_domain*)malloc(sizeof(__itt_domain)); \
|
||||
if (h != NULL) { \
|
||||
h->flags = 0; /* domain is disabled by default */ \
|
||||
h->nameA = NULL; \
|
||||
h->nameW = name ? _wcsdup(name) : NULL; \
|
||||
h->extra1 = 0; /* reserved */ \
|
||||
h->extra2 = NULL; /* reserved */ \
|
||||
h->next = NULL; \
|
||||
if (h_tail == NULL) \
|
||||
(gptr)->domain_list = h; \
|
||||
else \
|
||||
h_tail->next = h; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define NEW_DOMAIN_A(gptr,h,h_tail,name) { \
|
||||
h = (__itt_domain*)malloc(sizeof(__itt_domain)); \
|
||||
if (h != NULL) { \
|
||||
h->flags = 0; /* domain is disabled by default */ \
|
||||
h->nameA = name ? __itt_fstrdup(name) : NULL; \
|
||||
h->nameW = NULL; \
|
||||
h->extra1 = 0; /* reserved */ \
|
||||
h->extra2 = NULL; /* reserved */ \
|
||||
h->next = NULL; \
|
||||
if (h_tail == NULL) \
|
||||
(gptr)->domain_list = h; \
|
||||
else \
|
||||
h_tail->next = h; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define NEW_STRING_HANDLE_W(gptr,h,h_tail,name) { \
|
||||
h = (__itt_string_handle*)malloc(sizeof(__itt_string_handle)); \
|
||||
if (h != NULL) { \
|
||||
h->strA = NULL; \
|
||||
h->strW = name ? _wcsdup(name) : NULL; \
|
||||
h->extra1 = 0; /* reserved */ \
|
||||
h->extra2 = NULL; /* reserved */ \
|
||||
h->next = NULL; \
|
||||
if (h_tail == NULL) \
|
||||
(gptr)->string_list = h; \
|
||||
else \
|
||||
h_tail->next = h; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define NEW_STRING_HANDLE_A(gptr,h,h_tail,name) { \
|
||||
h = (__itt_string_handle*)malloc(sizeof(__itt_string_handle)); \
|
||||
if (h != NULL) { \
|
||||
h->strA = name ? __itt_fstrdup(name) : NULL; \
|
||||
h->strW = NULL; \
|
||||
h->extra1 = 0; /* reserved */ \
|
||||
h->extra2 = NULL; /* reserved */ \
|
||||
h->next = NULL; \
|
||||
if (h_tail == NULL) \
|
||||
(gptr)->string_list = h; \
|
||||
else \
|
||||
h_tail->next = h; \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif /* _ITTNOTIFY_CONFIG_H_ */
|
@ -1,70 +0,0 @@
|
||||
/*===-- ittnotify_types.h - JIT Profiling API internal types--------*- C -*-===*
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
* This file is distributed under the University of Illinois Open Source
|
||||
* License. See LICENSE.TXT for details.
|
||||
*
|
||||
*===----------------------------------------------------------------------===*
|
||||
*
|
||||
* NOTE: This file comes in a style different from the rest of LLVM
|
||||
* source base since this is a piece of code shared from Intel(R)
|
||||
* products. Please do not reformat / re-style this code to make
|
||||
* subsequent merges and contributions from the original source base eaiser.
|
||||
*
|
||||
*===----------------------------------------------------------------------===*/
|
||||
#ifndef _ITTNOTIFY_TYPES_H_
|
||||
#define _ITTNOTIFY_TYPES_H_
|
||||
|
||||
typedef enum ___itt_group_id
|
||||
{
|
||||
__itt_group_none = 0,
|
||||
__itt_group_legacy = 1<<0,
|
||||
__itt_group_control = 1<<1,
|
||||
__itt_group_thread = 1<<2,
|
||||
__itt_group_mark = 1<<3,
|
||||
__itt_group_sync = 1<<4,
|
||||
__itt_group_fsync = 1<<5,
|
||||
__itt_group_jit = 1<<6,
|
||||
__itt_group_model = 1<<7,
|
||||
__itt_group_splitter_min = 1<<7,
|
||||
__itt_group_counter = 1<<8,
|
||||
__itt_group_frame = 1<<9,
|
||||
__itt_group_stitch = 1<<10,
|
||||
__itt_group_heap = 1<<11,
|
||||
__itt_group_splitter_max = 1<<12,
|
||||
__itt_group_structure = 1<<12,
|
||||
__itt_group_suppress = 1<<13,
|
||||
__itt_group_all = -1
|
||||
} __itt_group_id;
|
||||
|
||||
#pragma pack(push, 8)
|
||||
|
||||
typedef struct ___itt_group_list
|
||||
{
|
||||
__itt_group_id id;
|
||||
const char* name;
|
||||
} __itt_group_list;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#define ITT_GROUP_LIST(varname) \
|
||||
static __itt_group_list varname[] = { \
|
||||
{ __itt_group_all, "all" }, \
|
||||
{ __itt_group_control, "control" }, \
|
||||
{ __itt_group_thread, "thread" }, \
|
||||
{ __itt_group_mark, "mark" }, \
|
||||
{ __itt_group_sync, "sync" }, \
|
||||
{ __itt_group_fsync, "fsync" }, \
|
||||
{ __itt_group_jit, "jit" }, \
|
||||
{ __itt_group_model, "model" }, \
|
||||
{ __itt_group_counter, "counter" }, \
|
||||
{ __itt_group_frame, "frame" }, \
|
||||
{ __itt_group_stitch, "stitch" }, \
|
||||
{ __itt_group_heap, "heap" }, \
|
||||
{ __itt_group_structure, "structure" }, \
|
||||
{ __itt_group_suppress, "suppress" }, \
|
||||
{ __itt_group_none, NULL } \
|
||||
}
|
||||
|
||||
#endif /* _ITTNOTIFY_TYPES_H_ */
|
@ -1,482 +0,0 @@
|
||||
/*===-- jitprofiling.c - JIT (Just-In-Time) Profiling API----------*- C -*-===*
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
* This file is distributed under the University of Illinois Open Source
|
||||
* License. See LICENSE.TXT for details.
|
||||
*
|
||||
*===----------------------------------------------------------------------===*
|
||||
*
|
||||
* This file provides Intel(R) Performance Analyzer JIT (Just-In-Time)
|
||||
* Profiling API implementation.
|
||||
*
|
||||
* NOTE: This file comes in a style different from the rest of LLVM
|
||||
* source base since this is a piece of code shared from Intel(R)
|
||||
* products. Please do not reformat / re-style this code to make
|
||||
* subsequent merges and contributions from the original source base eaiser.
|
||||
*
|
||||
*===----------------------------------------------------------------------===*/
|
||||
#include "ittnotify_config.h"
|
||||
|
||||
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||
#include <windows.h>
|
||||
#pragma optimize("", off)
|
||||
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
#include <dlfcn.h>
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
#include <malloc.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "jitprofiling.h"
|
||||
|
||||
static const char rcsid[] = "\n@(#) $Revision: 243501 $\n";
|
||||
|
||||
#define DLL_ENVIRONMENT_VAR "VS_PROFILER"
|
||||
|
||||
#ifndef NEW_DLL_ENVIRONMENT_VAR
|
||||
#if ITT_ARCH==ITT_ARCH_IA32
|
||||
#define NEW_DLL_ENVIRONMENT_VAR "INTEL_JIT_PROFILER32"
|
||||
#else
|
||||
#define NEW_DLL_ENVIRONMENT_VAR "INTEL_JIT_PROFILER64"
|
||||
#endif
|
||||
#endif /* NEW_DLL_ENVIRONMENT_VAR */
|
||||
|
||||
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||
#define DEFAULT_DLLNAME "JitPI.dll"
|
||||
HINSTANCE m_libHandle = NULL;
|
||||
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
#define DEFAULT_DLLNAME "libJitPI.so"
|
||||
void* m_libHandle = NULL;
|
||||
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
|
||||
/* default location of JIT profiling agent on Android */
|
||||
#define ANDROID_JIT_AGENT_PATH "/data/intel/libittnotify.so"
|
||||
|
||||
/* the function pointers */
|
||||
typedef unsigned int(*TPInitialize)(void);
|
||||
static TPInitialize FUNC_Initialize=NULL;
|
||||
|
||||
typedef unsigned int(*TPNotify)(unsigned int, void*);
|
||||
static TPNotify FUNC_NotifyEvent=NULL;
|
||||
|
||||
static iJIT_IsProfilingActiveFlags executionMode = iJIT_NOTHING_RUNNING;
|
||||
|
||||
/* end collector dll part. */
|
||||
|
||||
/* loadiJIT_Funcs() : this function is called just in the beginning
|
||||
* and is responsible to load the functions from BistroJavaCollector.dll
|
||||
* result:
|
||||
* on success: the functions loads, iJIT_DLL_is_missing=0, return value = 1
|
||||
* on failure: the functions are NULL, iJIT_DLL_is_missing=1, return value = 0
|
||||
*/
|
||||
static int loadiJIT_Funcs(void);
|
||||
|
||||
/* global representing whether the BistroJavaCollector can't be loaded */
|
||||
static int iJIT_DLL_is_missing = 0;
|
||||
|
||||
/* Virtual stack - the struct is used as a virtual stack for each thread.
|
||||
* Every thread initializes with a stack of size INIT_TOP_STACK.
|
||||
* Every method entry decreases from the current stack point,
|
||||
* and when a thread stack reaches its top of stack (return from the global
|
||||
* function), the top of stack and the current stack increase. Notice that
|
||||
* when returning from a function the stack pointer is the address of
|
||||
* the function return.
|
||||
*/
|
||||
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||
static DWORD threadLocalStorageHandle = 0;
|
||||
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
static pthread_key_t threadLocalStorageHandle = (pthread_key_t)0;
|
||||
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
|
||||
#define INIT_TOP_Stack 10000
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int TopStack;
|
||||
unsigned int CurrentStack;
|
||||
} ThreadStack, *pThreadStack;
|
||||
|
||||
/* end of virtual stack. */
|
||||
|
||||
/*
|
||||
* The function for reporting virtual-machine related events to VTune.
|
||||
* Note: when reporting iJVM_EVENT_TYPE_ENTER_NIDS, there is no need to fill
|
||||
* in the stack_id field in the iJIT_Method_NIDS structure, as VTune fills it.
|
||||
* The return value in iJVM_EVENT_TYPE_ENTER_NIDS &&
|
||||
* iJVM_EVENT_TYPE_LEAVE_NIDS events will be 0 in case of failure.
|
||||
* in iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED event
|
||||
* it will be -1 if EventSpecificData == 0 otherwise it will be 0.
|
||||
*/
|
||||
|
||||
ITT_EXTERN_C int JITAPI
|
||||
iJIT_NotifyEvent(iJIT_JVM_EVENT event_type, void *EventSpecificData)
|
||||
{
|
||||
int ReturnValue;
|
||||
|
||||
/*
|
||||
* This section is for debugging outside of VTune.
|
||||
* It creates the environment variables that indicates call graph mode.
|
||||
* If running outside of VTune remove the remark.
|
||||
*
|
||||
*
|
||||
* static int firstTime = 1;
|
||||
* char DoCallGraph[12] = "DoCallGraph";
|
||||
* if (firstTime)
|
||||
* {
|
||||
* firstTime = 0;
|
||||
* SetEnvironmentVariable( "BISTRO_COLLECTORS_DO_CALLGRAPH", DoCallGraph);
|
||||
* }
|
||||
*
|
||||
* end of section.
|
||||
*/
|
||||
|
||||
/* initialization part - the functions have not been loaded yet. This part
|
||||
* will load the functions, and check if we are in Call Graph mode.
|
||||
* (for special treatment).
|
||||
*/
|
||||
if (!FUNC_NotifyEvent)
|
||||
{
|
||||
if (iJIT_DLL_is_missing)
|
||||
return 0;
|
||||
|
||||
/* load the Function from the DLL */
|
||||
if (!loadiJIT_Funcs())
|
||||
return 0;
|
||||
|
||||
/* Call Graph initialization. */
|
||||
}
|
||||
|
||||
/* If the event is method entry/exit, check that in the current mode
|
||||
* VTune is allowed to receive it
|
||||
*/
|
||||
if ((event_type == iJVM_EVENT_TYPE_ENTER_NIDS ||
|
||||
event_type == iJVM_EVENT_TYPE_LEAVE_NIDS) &&
|
||||
(executionMode != iJIT_CALLGRAPH_ON))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/* This section is performed when method enter event occurs.
|
||||
* It updates the virtual stack, or creates it if this is the first
|
||||
* method entry in the thread. The stack pointer is decreased.
|
||||
*/
|
||||
if (event_type == iJVM_EVENT_TYPE_ENTER_NIDS)
|
||||
{
|
||||
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||
pThreadStack threadStack =
|
||||
(pThreadStack)TlsGetValue (threadLocalStorageHandle);
|
||||
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
pThreadStack threadStack =
|
||||
(pThreadStack)pthread_getspecific(threadLocalStorageHandle);
|
||||
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
|
||||
/* check for use of reserved method IDs */
|
||||
if ( ((piJIT_Method_NIDS) EventSpecificData)->method_id <= 999 )
|
||||
return 0;
|
||||
|
||||
if (!threadStack)
|
||||
{
|
||||
/* initialize the stack. */
|
||||
threadStack = (pThreadStack) calloc (sizeof(ThreadStack), 1);
|
||||
threadStack->TopStack = INIT_TOP_Stack;
|
||||
threadStack->CurrentStack = INIT_TOP_Stack;
|
||||
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||
TlsSetValue(threadLocalStorageHandle,(void*)threadStack);
|
||||
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
pthread_setspecific(threadLocalStorageHandle,(void*)threadStack);
|
||||
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
}
|
||||
|
||||
/* decrease the stack. */
|
||||
((piJIT_Method_NIDS) EventSpecificData)->stack_id =
|
||||
(threadStack->CurrentStack)--;
|
||||
}
|
||||
|
||||
/* This section is performed when method leave event occurs
|
||||
* It updates the virtual stack.
|
||||
* Increases the stack pointer.
|
||||
* If the stack pointer reached the top (left the global function)
|
||||
* increase the pointer and the top pointer.
|
||||
*/
|
||||
if (event_type == iJVM_EVENT_TYPE_LEAVE_NIDS)
|
||||
{
|
||||
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||
pThreadStack threadStack =
|
||||
(pThreadStack)TlsGetValue (threadLocalStorageHandle);
|
||||
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
pThreadStack threadStack =
|
||||
(pThreadStack)pthread_getspecific(threadLocalStorageHandle);
|
||||
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
|
||||
/* check for use of reserved method IDs */
|
||||
if ( ((piJIT_Method_NIDS) EventSpecificData)->method_id <= 999 )
|
||||
return 0;
|
||||
|
||||
if (!threadStack)
|
||||
{
|
||||
/* Error: first report in this thread is method exit */
|
||||
exit (1);
|
||||
}
|
||||
|
||||
((piJIT_Method_NIDS) EventSpecificData)->stack_id =
|
||||
++(threadStack->CurrentStack) + 1;
|
||||
|
||||
if (((piJIT_Method_NIDS) EventSpecificData)->stack_id
|
||||
> threadStack->TopStack)
|
||||
((piJIT_Method_NIDS) EventSpecificData)->stack_id =
|
||||
(unsigned int)-1;
|
||||
}
|
||||
|
||||
if (event_type == iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED)
|
||||
{
|
||||
/* check for use of reserved method IDs */
|
||||
if ( ((piJIT_Method_Load) EventSpecificData)->method_id <= 999 )
|
||||
return 0;
|
||||
}
|
||||
|
||||
ReturnValue = (int)FUNC_NotifyEvent(event_type, EventSpecificData);
|
||||
|
||||
return ReturnValue;
|
||||
}
|
||||
|
||||
/* The new mode call back routine */
|
||||
ITT_EXTERN_C void JITAPI
|
||||
iJIT_RegisterCallbackEx(void *userdata, iJIT_ModeChangedEx
|
||||
NewModeCallBackFuncEx)
|
||||
{
|
||||
/* is it already missing... or the load of functions from the DLL failed */
|
||||
if (iJIT_DLL_is_missing || !loadiJIT_Funcs())
|
||||
{
|
||||
/* then do not bother with notifications */
|
||||
NewModeCallBackFuncEx(userdata, iJIT_NO_NOTIFICATIONS);
|
||||
/* Error: could not load JIT functions. */
|
||||
return;
|
||||
}
|
||||
/* nothing to do with the callback */
|
||||
}
|
||||
|
||||
/*
|
||||
* This function allows the user to query in which mode, if at all,
|
||||
*VTune is running
|
||||
*/
|
||||
ITT_EXTERN_C iJIT_IsProfilingActiveFlags JITAPI iJIT_IsProfilingActive()
|
||||
{
|
||||
if (!iJIT_DLL_is_missing)
|
||||
{
|
||||
loadiJIT_Funcs();
|
||||
}
|
||||
|
||||
return executionMode;
|
||||
}
|
||||
|
||||
/* this function loads the collector dll (BistroJavaCollector)
|
||||
* and the relevant functions.
|
||||
* on success: all functions load, iJIT_DLL_is_missing = 0, return value = 1
|
||||
* on failure: all functions are NULL, iJIT_DLL_is_missing = 1, return value = 0
|
||||
*/
|
||||
static int loadiJIT_Funcs()
|
||||
{
|
||||
static int bDllWasLoaded = 0;
|
||||
char *dllName = (char*)rcsid; /* !! Just to avoid unused code elimination */
|
||||
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||
DWORD dNameLength = 0;
|
||||
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
|
||||
if(bDllWasLoaded)
|
||||
{
|
||||
/* dll was already loaded, no need to do it for the second time */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Assumes that the DLL will not be found */
|
||||
iJIT_DLL_is_missing = 1;
|
||||
FUNC_NotifyEvent = NULL;
|
||||
|
||||
if (m_libHandle)
|
||||
{
|
||||
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||
FreeLibrary(m_libHandle);
|
||||
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
dlclose(m_libHandle);
|
||||
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
m_libHandle = NULL;
|
||||
}
|
||||
|
||||
/* Try to get the dll name from the environment */
|
||||
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||
dNameLength = GetEnvironmentVariableA(NEW_DLL_ENVIRONMENT_VAR, NULL, 0);
|
||||
if (dNameLength)
|
||||
{
|
||||
DWORD envret = 0;
|
||||
dllName = (char*)malloc(sizeof(char) * (dNameLength + 1));
|
||||
envret = GetEnvironmentVariableA(NEW_DLL_ENVIRONMENT_VAR,
|
||||
dllName, dNameLength);
|
||||
if (envret)
|
||||
{
|
||||
/* Try to load the dll from the PATH... */
|
||||
m_libHandle = LoadLibraryExA(dllName,
|
||||
NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
|
||||
}
|
||||
free(dllName);
|
||||
} else {
|
||||
/* Try to use old VS_PROFILER variable */
|
||||
dNameLength = GetEnvironmentVariableA(DLL_ENVIRONMENT_VAR, NULL, 0);
|
||||
if (dNameLength)
|
||||
{
|
||||
DWORD envret = 0;
|
||||
dllName = (char*)malloc(sizeof(char) * (dNameLength + 1));
|
||||
envret = GetEnvironmentVariableA(DLL_ENVIRONMENT_VAR,
|
||||
dllName, dNameLength);
|
||||
if (envret)
|
||||
{
|
||||
/* Try to load the dll from the PATH... */
|
||||
m_libHandle = LoadLibraryA(dllName);
|
||||
}
|
||||
free(dllName);
|
||||
}
|
||||
}
|
||||
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
dllName = getenv(NEW_DLL_ENVIRONMENT_VAR);
|
||||
if (!dllName)
|
||||
dllName = getenv(DLL_ENVIRONMENT_VAR);
|
||||
#ifdef ANDROID
|
||||
if (!dllName)
|
||||
dllName = ANDROID_JIT_AGENT_PATH;
|
||||
#endif
|
||||
if (dllName)
|
||||
{
|
||||
/* Try to load the dll from the PATH... */
|
||||
m_libHandle = dlopen(dllName, RTLD_LAZY);
|
||||
}
|
||||
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
|
||||
if (!m_libHandle)
|
||||
{
|
||||
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||
m_libHandle = LoadLibraryA(DEFAULT_DLLNAME);
|
||||
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
m_libHandle = dlopen(DEFAULT_DLLNAME, RTLD_LAZY);
|
||||
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
}
|
||||
|
||||
/* if the dll wasn't loaded - exit. */
|
||||
if (!m_libHandle)
|
||||
{
|
||||
iJIT_DLL_is_missing = 1; /* don't try to initialize
|
||||
* JIT agent the second time
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||
FUNC_NotifyEvent = (TPNotify)GetProcAddress(m_libHandle, "NotifyEvent");
|
||||
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
FUNC_NotifyEvent = (TPNotify)(intptr_t)dlsym(m_libHandle, "NotifyEvent");
|
||||
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
if (!FUNC_NotifyEvent)
|
||||
{
|
||||
FUNC_Initialize = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||
FUNC_Initialize = (TPInitialize)GetProcAddress(m_libHandle, "Initialize");
|
||||
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
FUNC_Initialize = (TPInitialize)(intptr_t)dlsym(m_libHandle, "Initialize");
|
||||
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
if (!FUNC_Initialize)
|
||||
{
|
||||
FUNC_NotifyEvent = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
executionMode = (iJIT_IsProfilingActiveFlags)FUNC_Initialize();
|
||||
|
||||
bDllWasLoaded = 1;
|
||||
iJIT_DLL_is_missing = 0; /* DLL is ok. */
|
||||
|
||||
/*
|
||||
* Call Graph mode: init the thread local storage
|
||||
* (need to store the virtual stack there).
|
||||
*/
|
||||
if ( executionMode == iJIT_CALLGRAPH_ON )
|
||||
{
|
||||
/* Allocate a thread local storage slot for the thread "stack" */
|
||||
if (!threadLocalStorageHandle)
|
||||
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||
threadLocalStorageHandle = TlsAlloc();
|
||||
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
pthread_key_create(&threadLocalStorageHandle, NULL);
|
||||
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function should be called by the user whenever a thread ends,
|
||||
* to free the thread "virtual stack" storage
|
||||
*/
|
||||
ITT_EXTERN_C void JITAPI FinalizeThread()
|
||||
{
|
||||
if (threadLocalStorageHandle)
|
||||
{
|
||||
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||
pThreadStack threadStack =
|
||||
(pThreadStack)TlsGetValue (threadLocalStorageHandle);
|
||||
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
pThreadStack threadStack =
|
||||
(pThreadStack)pthread_getspecific(threadLocalStorageHandle);
|
||||
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
if (threadStack)
|
||||
{
|
||||
free (threadStack);
|
||||
threadStack = NULL;
|
||||
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||
TlsSetValue (threadLocalStorageHandle, threadStack);
|
||||
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
pthread_setspecific(threadLocalStorageHandle, threadStack);
|
||||
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function should be called by the user when the process ends,
|
||||
* to free the local storage index
|
||||
*/
|
||||
ITT_EXTERN_C void JITAPI FinalizeProcess()
|
||||
{
|
||||
if (m_libHandle)
|
||||
{
|
||||
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||
FreeLibrary(m_libHandle);
|
||||
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
dlclose(m_libHandle);
|
||||
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
m_libHandle = NULL;
|
||||
}
|
||||
|
||||
if (threadLocalStorageHandle)
|
||||
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||
TlsFree (threadLocalStorageHandle);
|
||||
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
pthread_key_delete(threadLocalStorageHandle);
|
||||
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||
}
|
||||
|
||||
/*
|
||||
* This function should be called by the user for any method once.
|
||||
* The function will return a unique method ID, the user should maintain
|
||||
* the ID for each method
|
||||
*/
|
||||
ITT_EXTERN_C unsigned int JITAPI iJIT_GetNewMethodID()
|
||||
{
|
||||
static unsigned int methodID = 0x100000;
|
||||
|
||||
if (methodID == 0)
|
||||
return 0; /* ERROR : this is not a valid value */
|
||||
|
||||
return methodID++;
|
||||
}
|
@ -1,259 +0,0 @@
|
||||
/*===-- jitprofiling.h - JIT Profiling API-------------------------*- C -*-===*
|
||||
*
|
||||
* The LLVM Compiler Infrastructure
|
||||
*
|
||||
* This file is distributed under the University of Illinois Open Source
|
||||
* License. See LICENSE.TXT for details.
|
||||
*
|
||||
*===----------------------------------------------------------------------===*
|
||||
*
|
||||
* This file provides Intel(R) Performance Analyzer JIT (Just-In-Time)
|
||||
* Profiling API declaration.
|
||||
*
|
||||
* NOTE: This file comes in a style different from the rest of LLVM
|
||||
* source base since this is a piece of code shared from Intel(R)
|
||||
* products. Please do not reformat / re-style this code to make
|
||||
* subsequent merges and contributions from the original source base eaiser.
|
||||
*
|
||||
*===----------------------------------------------------------------------===*/
|
||||
#ifndef __JITPROFILING_H__
|
||||
#define __JITPROFILING_H__
|
||||
|
||||
/*
|
||||
* Various constants used by functions
|
||||
*/
|
||||
|
||||
/* event notification */
|
||||
typedef enum iJIT_jvm_event
|
||||
{
|
||||
|
||||
/* shutdown */
|
||||
|
||||
/*
|
||||
* Program exiting EventSpecificData NA
|
||||
*/
|
||||
iJVM_EVENT_TYPE_SHUTDOWN = 2,
|
||||
|
||||
/* JIT profiling */
|
||||
|
||||
/*
|
||||
* issued after method code jitted into memory but before code is executed
|
||||
* EventSpecificData is an iJIT_Method_Load
|
||||
*/
|
||||
iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED=13,
|
||||
|
||||
/* issued before unload. Method code will no longer be executed, but code
|
||||
* and info are still in memory. The VTune profiler may capture method
|
||||
* code only at this point EventSpecificData is iJIT_Method_Id
|
||||
*/
|
||||
iJVM_EVENT_TYPE_METHOD_UNLOAD_START,
|
||||
|
||||
/* Method Profiling */
|
||||
|
||||
/* method name, Id and stack is supplied
|
||||
* issued when a method is about to be entered EventSpecificData is
|
||||
* iJIT_Method_NIDS
|
||||
*/
|
||||
iJVM_EVENT_TYPE_ENTER_NIDS = 19,
|
||||
|
||||
/* method name, Id and stack is supplied
|
||||
* issued when a method is about to be left EventSpecificData is
|
||||
* iJIT_Method_NIDS
|
||||
*/
|
||||
iJVM_EVENT_TYPE_LEAVE_NIDS
|
||||
} iJIT_JVM_EVENT;
|
||||
|
||||
typedef enum _iJIT_ModeFlags
|
||||
{
|
||||
/* No need to Notify VTune, since VTune is not running */
|
||||
iJIT_NO_NOTIFICATIONS = 0x0000,
|
||||
|
||||
/* when turned on the jit must call
|
||||
* iJIT_NotifyEvent
|
||||
* (
|
||||
* iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED,
|
||||
* )
|
||||
* for all the method already jitted
|
||||
*/
|
||||
iJIT_BE_NOTIFY_ON_LOAD = 0x0001,
|
||||
|
||||
/* when turned on the jit must call
|
||||
* iJIT_NotifyEvent
|
||||
* (
|
||||
* iJVM_EVENT_TYPE_METHOD_UNLOAD_FINISHED,
|
||||
* ) for all the method that are unloaded
|
||||
*/
|
||||
iJIT_BE_NOTIFY_ON_UNLOAD = 0x0002,
|
||||
|
||||
/* when turned on the jit must instrument all
|
||||
* the currently jited code with calls on
|
||||
* method entries
|
||||
*/
|
||||
iJIT_BE_NOTIFY_ON_METHOD_ENTRY = 0x0004,
|
||||
|
||||
/* when turned on the jit must instrument all
|
||||
* the currently jited code with calls
|
||||
* on method exit
|
||||
*/
|
||||
iJIT_BE_NOTIFY_ON_METHOD_EXIT = 0x0008
|
||||
|
||||
} iJIT_ModeFlags;
|
||||
|
||||
|
||||
/* Flags used by iJIT_IsProfilingActive() */
|
||||
typedef enum _iJIT_IsProfilingActiveFlags
|
||||
{
|
||||
/* No profiler is running. Currently not used */
|
||||
iJIT_NOTHING_RUNNING = 0x0000,
|
||||
|
||||
/* Sampling is running. This is the default value
|
||||
* returned by iJIT_IsProfilingActive()
|
||||
*/
|
||||
iJIT_SAMPLING_ON = 0x0001,
|
||||
|
||||
/* Call Graph is running */
|
||||
iJIT_CALLGRAPH_ON = 0x0002
|
||||
|
||||
} iJIT_IsProfilingActiveFlags;
|
||||
|
||||
/* Enumerator for the environment of methods*/
|
||||
typedef enum _iJDEnvironmentType
|
||||
{
|
||||
iJDE_JittingAPI = 2
|
||||
} iJDEnvironmentType;
|
||||
|
||||
/**********************************
|
||||
* Data structures for the events *
|
||||
**********************************/
|
||||
|
||||
/* structure for the events:
|
||||
* iJVM_EVENT_TYPE_METHOD_UNLOAD_START
|
||||
*/
|
||||
|
||||
typedef struct _iJIT_Method_Id
|
||||
{
|
||||
/* Id of the method (same as the one passed in
|
||||
* the iJIT_Method_Load struct
|
||||
*/
|
||||
unsigned int method_id;
|
||||
|
||||
} *piJIT_Method_Id, iJIT_Method_Id;
|
||||
|
||||
|
||||
/* structure for the events:
|
||||
* iJVM_EVENT_TYPE_ENTER_NIDS,
|
||||
* iJVM_EVENT_TYPE_LEAVE_NIDS,
|
||||
* iJVM_EVENT_TYPE_EXCEPTION_OCCURRED_NIDS
|
||||
*/
|
||||
|
||||
typedef struct _iJIT_Method_NIDS
|
||||
{
|
||||
/* unique method ID */
|
||||
unsigned int method_id;
|
||||
|
||||
/* NOTE: no need to fill this field, it's filled by VTune */
|
||||
unsigned int stack_id;
|
||||
|
||||
/* method name (just the method, without the class) */
|
||||
char* method_name;
|
||||
} *piJIT_Method_NIDS, iJIT_Method_NIDS;
|
||||
|
||||
/* structures for the events:
|
||||
* iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED
|
||||
*/
|
||||
|
||||
typedef struct _LineNumberInfo
|
||||
{
|
||||
/* x86 Offset from the beginning of the method*/
|
||||
unsigned int Offset;
|
||||
|
||||
/* source line number from the beginning of the source file */
|
||||
unsigned int LineNumber;
|
||||
|
||||
} *pLineNumberInfo, LineNumberInfo;
|
||||
|
||||
typedef struct _iJIT_Method_Load
|
||||
{
|
||||
/* unique method ID - can be any unique value, (except 0 - 999) */
|
||||
unsigned int method_id;
|
||||
|
||||
/* method name (can be with or without the class and signature, in any case
|
||||
* the class name will be added to it)
|
||||
*/
|
||||
char* method_name;
|
||||
|
||||
/* virtual address of that method - This determines the method range for the
|
||||
* iJVM_EVENT_TYPE_ENTER/LEAVE_METHOD_ADDR events
|
||||
*/
|
||||
void* method_load_address;
|
||||
|
||||
/* Size in memory - Must be exact */
|
||||
unsigned int method_size;
|
||||
|
||||
/* Line Table size in number of entries - Zero if none */
|
||||
unsigned int line_number_size;
|
||||
|
||||
/* Pointer to the beginning of the line numbers info array */
|
||||
pLineNumberInfo line_number_table;
|
||||
|
||||
/* unique class ID */
|
||||
unsigned int class_id;
|
||||
|
||||
/* class file name */
|
||||
char* class_file_name;
|
||||
|
||||
/* source file name */
|
||||
char* source_file_name;
|
||||
|
||||
/* bits supplied by the user for saving in the JIT file */
|
||||
void* user_data;
|
||||
|
||||
/* the size of the user data buffer */
|
||||
unsigned int user_data_size;
|
||||
|
||||
/* NOTE: no need to fill this field, it's filled by VTune */
|
||||
iJDEnvironmentType env;
|
||||
|
||||
} *piJIT_Method_Load, iJIT_Method_Load;
|
||||
|
||||
/* API Functions */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef CDECL
|
||||
# if defined WIN32 || defined _WIN32
|
||||
# define CDECL __cdecl
|
||||
# else /* defined WIN32 || defined _WIN32 */
|
||||
# if defined _M_X64 || defined _M_AMD64 || defined __x86_64__
|
||||
# define CDECL /* not actual on x86_64 platform */
|
||||
# else /* _M_X64 || _M_AMD64 || __x86_64__ */
|
||||
# define CDECL __attribute__ ((cdecl))
|
||||
# endif /* _M_X64 || _M_AMD64 || __x86_64__ */
|
||||
# endif /* defined WIN32 || defined _WIN32 */
|
||||
#endif /* CDECL */
|
||||
|
||||
#define JITAPI CDECL
|
||||
|
||||
/* called when the settings are changed with new settings */
|
||||
typedef void (*iJIT_ModeChangedEx)(void *UserData, iJIT_ModeFlags Flags);
|
||||
|
||||
int JITAPI iJIT_NotifyEvent(iJIT_JVM_EVENT event_type, void *EventSpecificData);
|
||||
|
||||
/* The new mode call back routine */
|
||||
void JITAPI iJIT_RegisterCallbackEx(void *userdata,
|
||||
iJIT_ModeChangedEx NewModeCallBackFuncEx);
|
||||
|
||||
iJIT_IsProfilingActiveFlags JITAPI iJIT_IsProfilingActive(void);
|
||||
|
||||
void JITAPI FinalizeThread(void);
|
||||
|
||||
void JITAPI FinalizeProcess(void);
|
||||
|
||||
unsigned int JITAPI iJIT_GetNewMethodID(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __JITPROFILING_H__ */
|
@ -1,20 +0,0 @@
|
||||
# Make sure that the path to libffi headers is on the command
|
||||
# line. That path can be a compiler's non-default path even when
|
||||
# FFI_INCLUDE_DIR was not used, because cmake has its own paths for
|
||||
# searching for headers (CMAKE_SYSTEM_INCLUDE_PATH, for instance):
|
||||
if( FFI_INCLUDE_PATH )
|
||||
include_directories( ${FFI_INCLUDE_PATH} )
|
||||
endif()
|
||||
|
||||
add_llvm_library(LLVMInterpreter
|
||||
Execution.cpp
|
||||
ExternalFunctions.cpp
|
||||
Interpreter.cpp
|
||||
|
||||
DEPENDS
|
||||
intrinsics_gen
|
||||
)
|
||||
|
||||
if( LLVM_ENABLE_FFI )
|
||||
target_link_libraries( LLVMInterpreter PRIVATE ${FFI_LIBRARY_PATH} )
|
||||
endif()
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,103 +0,0 @@
|
||||
//===- Interpreter.cpp - Top-Level LLVM Interpreter Implementation --------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements the top-level functionality for the LLVM interpreter.
|
||||
// This interpreter is designed to be a very simple, portable, inefficient
|
||||
// interpreter.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Interpreter.h"
|
||||
#include "llvm/CodeGen/IntrinsicLowering.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include <cstring>
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
static struct RegisterInterp {
|
||||
RegisterInterp() { Interpreter::Register(); }
|
||||
} InterpRegistrator;
|
||||
|
||||
}
|
||||
|
||||
extern "C" void LLVMLinkInInterpreter() { }
|
||||
|
||||
/// Create a new interpreter object.
|
||||
///
|
||||
ExecutionEngine *Interpreter::create(std::unique_ptr<Module> M,
|
||||
std::string *ErrStr) {
|
||||
// Tell this Module to materialize everything and release the GVMaterializer.
|
||||
if (Error Err = M->materializeAll()) {
|
||||
std::string Msg;
|
||||
handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) {
|
||||
Msg = EIB.message();
|
||||
});
|
||||
if (ErrStr)
|
||||
*ErrStr = Msg;
|
||||
// We got an error, just return 0
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new Interpreter(std::move(M));
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Interpreter ctor - Initialize stuff
|
||||
//
|
||||
Interpreter::Interpreter(std::unique_ptr<Module> M)
|
||||
: ExecutionEngine(std::move(M)) {
|
||||
|
||||
memset(&ExitValue.Untyped, 0, sizeof(ExitValue.Untyped));
|
||||
// Initialize the "backend"
|
||||
initializeExecutionEngine();
|
||||
initializeExternalFunctions();
|
||||
emitGlobals();
|
||||
|
||||
IL = new IntrinsicLowering(getDataLayout());
|
||||
}
|
||||
|
||||
Interpreter::~Interpreter() {
|
||||
delete IL;
|
||||
}
|
||||
|
||||
void Interpreter::runAtExitHandlers () {
|
||||
while (!AtExitHandlers.empty()) {
|
||||
callFunction(AtExitHandlers.back(), None);
|
||||
AtExitHandlers.pop_back();
|
||||
run();
|
||||
}
|
||||
}
|
||||
|
||||
/// run - Start execution with the specified function and arguments.
|
||||
///
|
||||
GenericValue Interpreter::runFunction(Function *F,
|
||||
ArrayRef<GenericValue> ArgValues) {
|
||||
assert (F && "Function *F was null at entry to run()");
|
||||
|
||||
// Try extra hard not to pass extra args to a function that isn't
|
||||
// expecting them. C programmers frequently bend the rules and
|
||||
// declare main() with fewer parameters than it actually gets
|
||||
// passed, and the interpreter barfs if you pass a function more
|
||||
// parameters than it is declared to take. This does not attempt to
|
||||
// take into account gratuitous differences in declared types,
|
||||
// though.
|
||||
const size_t ArgCount = F->getFunctionType()->getNumParams();
|
||||
ArrayRef<GenericValue> ActualArgs =
|
||||
ArgValues.slice(0, std::min(ArgValues.size(), ArgCount));
|
||||
|
||||
// Set up the function call.
|
||||
callFunction(F, ActualArgs);
|
||||
|
||||
// Start executing the function.
|
||||
run();
|
||||
|
||||
return ExitValue;
|
||||
}
|
@ -1,235 +0,0 @@
|
||||
//===-- Interpreter.h ------------------------------------------*- C++ -*--===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This header file defines the interpreter structure
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIB_EXECUTIONENGINE_INTERPRETER_INTERPRETER_H
|
||||
#define LLVM_LIB_EXECUTIONENGINE_INTERPRETER_INTERPRETER_H
|
||||
|
||||
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||||
#include "llvm/ExecutionEngine/GenericValue.h"
|
||||
#include "llvm/IR/CallSite.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/InstVisitor.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
namespace llvm {
|
||||
|
||||
class IntrinsicLowering;
|
||||
template<typename T> class generic_gep_type_iterator;
|
||||
class ConstantExpr;
|
||||
typedef generic_gep_type_iterator<User::const_op_iterator> gep_type_iterator;
|
||||
|
||||
|
||||
// AllocaHolder - Object to track all of the blocks of memory allocated by
|
||||
// alloca. When the function returns, this object is popped off the execution
|
||||
// stack, which causes the dtor to be run, which frees all the alloca'd memory.
|
||||
//
|
||||
class AllocaHolder {
|
||||
std::vector<void *> Allocations;
|
||||
|
||||
public:
|
||||
AllocaHolder() {}
|
||||
|
||||
// Make this type move-only.
|
||||
AllocaHolder(AllocaHolder &&) = default;
|
||||
AllocaHolder &operator=(AllocaHolder &&RHS) = default;
|
||||
|
||||
~AllocaHolder() {
|
||||
for (void *Allocation : Allocations)
|
||||
free(Allocation);
|
||||
}
|
||||
|
||||
void add(void *Mem) { Allocations.push_back(Mem); }
|
||||
};
|
||||
|
||||
typedef std::vector<GenericValue> ValuePlaneTy;
|
||||
|
||||
// ExecutionContext struct - This struct represents one stack frame currently
|
||||
// executing.
|
||||
//
|
||||
struct ExecutionContext {
|
||||
Function *CurFunction;// The currently executing function
|
||||
BasicBlock *CurBB; // The currently executing BB
|
||||
BasicBlock::iterator CurInst; // The next instruction to execute
|
||||
CallSite Caller; // Holds the call that called subframes.
|
||||
// NULL if main func or debugger invoked fn
|
||||
std::map<Value *, GenericValue> Values; // LLVM values used in this invocation
|
||||
std::vector<GenericValue> VarArgs; // Values passed through an ellipsis
|
||||
AllocaHolder Allocas; // Track memory allocated by alloca
|
||||
|
||||
ExecutionContext() : CurFunction(nullptr), CurBB(nullptr), CurInst(nullptr) {}
|
||||
};
|
||||
|
||||
// Interpreter - This class represents the entirety of the interpreter.
|
||||
//
|
||||
class Interpreter : public ExecutionEngine, public InstVisitor<Interpreter> {
|
||||
GenericValue ExitValue; // The return value of the called function
|
||||
IntrinsicLowering *IL;
|
||||
|
||||
// The runtime stack of executing code. The top of the stack is the current
|
||||
// function record.
|
||||
std::vector<ExecutionContext> ECStack;
|
||||
|
||||
// AtExitHandlers - List of functions to call when the program exits,
|
||||
// registered with the atexit() library function.
|
||||
std::vector<Function*> AtExitHandlers;
|
||||
|
||||
public:
|
||||
explicit Interpreter(std::unique_ptr<Module> M);
|
||||
~Interpreter() override;
|
||||
|
||||
/// runAtExitHandlers - Run any functions registered by the program's calls to
|
||||
/// atexit(3), which we intercept and store in AtExitHandlers.
|
||||
///
|
||||
void runAtExitHandlers();
|
||||
|
||||
static void Register() {
|
||||
InterpCtor = create;
|
||||
}
|
||||
|
||||
/// Create an interpreter ExecutionEngine.
|
||||
///
|
||||
static ExecutionEngine *create(std::unique_ptr<Module> M,
|
||||
std::string *ErrorStr = nullptr);
|
||||
|
||||
/// run - Start execution with the specified function and arguments.
|
||||
///
|
||||
GenericValue runFunction(Function *F,
|
||||
ArrayRef<GenericValue> ArgValues) override;
|
||||
|
||||
void *getPointerToNamedFunction(StringRef Name,
|
||||
bool AbortOnFailure = true) override {
|
||||
// FIXME: not implemented.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Methods used to execute code:
|
||||
// Place a call on the stack
|
||||
void callFunction(Function *F, ArrayRef<GenericValue> ArgVals);
|
||||
void run(); // Execute instructions until nothing left to do
|
||||
|
||||
// Opcode Implementations
|
||||
void visitReturnInst(ReturnInst &I);
|
||||
void visitBranchInst(BranchInst &I);
|
||||
void visitSwitchInst(SwitchInst &I);
|
||||
void visitIndirectBrInst(IndirectBrInst &I);
|
||||
|
||||
void visitBinaryOperator(BinaryOperator &I);
|
||||
void visitICmpInst(ICmpInst &I);
|
||||
void visitFCmpInst(FCmpInst &I);
|
||||
void visitAllocaInst(AllocaInst &I);
|
||||
void visitLoadInst(LoadInst &I);
|
||||
void visitStoreInst(StoreInst &I);
|
||||
void visitGetElementPtrInst(GetElementPtrInst &I);
|
||||
void visitPHINode(PHINode &PN) {
|
||||
llvm_unreachable("PHI nodes already handled!");
|
||||
}
|
||||
void visitTruncInst(TruncInst &I);
|
||||
void visitZExtInst(ZExtInst &I);
|
||||
void visitSExtInst(SExtInst &I);
|
||||
void visitFPTruncInst(FPTruncInst &I);
|
||||
void visitFPExtInst(FPExtInst &I);
|
||||
void visitUIToFPInst(UIToFPInst &I);
|
||||
void visitSIToFPInst(SIToFPInst &I);
|
||||
void visitFPToUIInst(FPToUIInst &I);
|
||||
void visitFPToSIInst(FPToSIInst &I);
|
||||
void visitPtrToIntInst(PtrToIntInst &I);
|
||||
void visitIntToPtrInst(IntToPtrInst &I);
|
||||
void visitBitCastInst(BitCastInst &I);
|
||||
void visitSelectInst(SelectInst &I);
|
||||
|
||||
|
||||
void visitCallSite(CallSite CS);
|
||||
void visitCallInst(CallInst &I) { visitCallSite (CallSite (&I)); }
|
||||
void visitInvokeInst(InvokeInst &I) { visitCallSite (CallSite (&I)); }
|
||||
void visitUnreachableInst(UnreachableInst &I);
|
||||
|
||||
void visitShl(BinaryOperator &I);
|
||||
void visitLShr(BinaryOperator &I);
|
||||
void visitAShr(BinaryOperator &I);
|
||||
|
||||
void visitVAArgInst(VAArgInst &I);
|
||||
void visitExtractElementInst(ExtractElementInst &I);
|
||||
void visitInsertElementInst(InsertElementInst &I);
|
||||
void visitShuffleVectorInst(ShuffleVectorInst &I);
|
||||
|
||||
void visitExtractValueInst(ExtractValueInst &I);
|
||||
void visitInsertValueInst(InsertValueInst &I);
|
||||
|
||||
void visitInstruction(Instruction &I) {
|
||||
errs() << I << "\n";
|
||||
llvm_unreachable("Instruction not interpretable yet!");
|
||||
}
|
||||
|
||||
GenericValue callExternalFunction(Function *F,
|
||||
ArrayRef<GenericValue> ArgVals);
|
||||
void exitCalled(GenericValue GV);
|
||||
|
||||
void addAtExitHandler(Function *F) {
|
||||
AtExitHandlers.push_back(F);
|
||||
}
|
||||
|
||||
GenericValue *getFirstVarArg () {
|
||||
return &(ECStack.back ().VarArgs[0]);
|
||||
}
|
||||
|
||||
private: // Helper functions
|
||||
GenericValue executeGEPOperation(Value *Ptr, gep_type_iterator I,
|
||||
gep_type_iterator E, ExecutionContext &SF);
|
||||
|
||||
// SwitchToNewBasicBlock - Start execution in a new basic block and run any
|
||||
// PHI nodes in the top of the block. This is used for intraprocedural
|
||||
// control flow.
|
||||
//
|
||||
void SwitchToNewBasicBlock(BasicBlock *Dest, ExecutionContext &SF);
|
||||
|
||||
void *getPointerToFunction(Function *F) override { return (void*)F; }
|
||||
|
||||
void initializeExecutionEngine() { }
|
||||
void initializeExternalFunctions();
|
||||
GenericValue getConstantExprValue(ConstantExpr *CE, ExecutionContext &SF);
|
||||
GenericValue getOperandValue(Value *V, ExecutionContext &SF);
|
||||
GenericValue executeTruncInst(Value *SrcVal, Type *DstTy,
|
||||
ExecutionContext &SF);
|
||||
GenericValue executeSExtInst(Value *SrcVal, Type *DstTy,
|
||||
ExecutionContext &SF);
|
||||
GenericValue executeZExtInst(Value *SrcVal, Type *DstTy,
|
||||
ExecutionContext &SF);
|
||||
GenericValue executeFPTruncInst(Value *SrcVal, Type *DstTy,
|
||||
ExecutionContext &SF);
|
||||
GenericValue executeFPExtInst(Value *SrcVal, Type *DstTy,
|
||||
ExecutionContext &SF);
|
||||
GenericValue executeFPToUIInst(Value *SrcVal, Type *DstTy,
|
||||
ExecutionContext &SF);
|
||||
GenericValue executeFPToSIInst(Value *SrcVal, Type *DstTy,
|
||||
ExecutionContext &SF);
|
||||
GenericValue executeUIToFPInst(Value *SrcVal, Type *DstTy,
|
||||
ExecutionContext &SF);
|
||||
GenericValue executeSIToFPInst(Value *SrcVal, Type *DstTy,
|
||||
ExecutionContext &SF);
|
||||
GenericValue executePtrToIntInst(Value *SrcVal, Type *DstTy,
|
||||
ExecutionContext &SF);
|
||||
GenericValue executeIntToPtrInst(Value *SrcVal, Type *DstTy,
|
||||
ExecutionContext &SF);
|
||||
GenericValue executeBitCastInst(Value *SrcVal, Type *DstTy,
|
||||
ExecutionContext &SF);
|
||||
GenericValue executeCastOperation(Instruction::CastOps opcode, Value *SrcVal,
|
||||
Type *Ty, ExecutionContext &SF);
|
||||
void popStackAndReturnValueToCaller(Type *RetTy, GenericValue Result);
|
||||
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
@ -1,22 +0,0 @@
|
||||
;===- ./lib/ExecutionEngine/Interpreter/LLVMBuild.txt ----------*- Conf -*--===;
|
||||
;
|
||||
; The LLVM Compiler Infrastructure
|
||||
;
|
||||
; This file is distributed under the University of Illinois Open Source
|
||||
; License. See LICENSE.TXT for details.
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
;
|
||||
; This is an LLVMBuild description file for the components in this subdirectory.
|
||||
;
|
||||
; For more information on the LLVMBuild system, please see:
|
||||
;
|
||||
; http://llvm.org/docs/LLVMBuild.html
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
|
||||
[component_0]
|
||||
type = Library
|
||||
name = Interpreter
|
||||
parent = ExecutionEngine
|
||||
required_libraries = CodeGen Core ExecutionEngine Support
|
25
external/llvm/lib/ExecutionEngine/LLVMBuild.txt
vendored
25
external/llvm/lib/ExecutionEngine/LLVMBuild.txt
vendored
@ -1,25 +0,0 @@
|
||||
;===- ./lib/ExecutionEngine/LLVMBuild.txt ----------------------*- Conf -*--===;
|
||||
;
|
||||
; The LLVM Compiler Infrastructure
|
||||
;
|
||||
; This file is distributed under the University of Illinois Open Source
|
||||
; License. See LICENSE.TXT for details.
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
;
|
||||
; This is an LLVMBuild description file for the components in this subdirectory.
|
||||
;
|
||||
; For more information on the LLVMBuild system, please see:
|
||||
;
|
||||
; http://llvm.org/docs/LLVMBuild.html
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
|
||||
[common]
|
||||
subdirectories = Interpreter MCJIT RuntimeDyld IntelJITEvents OProfileJIT Orc
|
||||
|
||||
[component_0]
|
||||
type = Library
|
||||
name = ExecutionEngine
|
||||
parent = Libraries
|
||||
required_libraries = Core MC Object RuntimeDyld Support Target
|
@ -1,6 +0,0 @@
|
||||
add_llvm_library(LLVMMCJIT
|
||||
MCJIT.cpp
|
||||
|
||||
DEPENDS
|
||||
intrinsics_gen
|
||||
)
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user