blob: 8ee1804b7f513fbe2769213c37a54ea3c37230b0 [file] [log] [blame]
//===---------------- JIT.cc - Initialize the JIT -------------------------===//
//
// The Micro Virtual Machine
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <llvm/Type.h>
#include <llvm/Support/CFG.h>
#include <llvm/Module.h>
#include <llvm/Constants.h>
#include <llvm/Type.h>
#include <llvm/DerivedTypes.h>
#include <llvm/Function.h>
#include <llvm/Instructions.h>
#include <llvm/ModuleProvider.h>
#include <llvm/ExecutionEngine/JIT.h>
#include <llvm/ExecutionEngine/GenericValue.h>
#include <llvm/PassManager.h>
#include <llvm/Analysis/Verifier.h>
#include <llvm/Transforms/Scalar.h>
#include <llvm/Target/TargetData.h>
#include <llvm/Assembly/PrintModulePass.h>
#include <llvm/Target/TargetOptions.h>
#include <llvm/CodeGen/MachineCodeEmitter.h>
#include <llvm/CodeGen/MachineBasicBlock.h>
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/ModuleProvider.h"
#include "llvm/PassManager.h"
#include "llvm/ValueSymbolTable.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/CodeGen/RegAllocRegistry.h"
#include "llvm/CodeGen/SchedulerRegistry.h"
#include "llvm/CodeGen/ScheduleDAG.h"
#include "llvm/Target/SubtargetFeature.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetMachineRegistry.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/Streams.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/MutexGuard.h"
#include <llvm/Transforms/IPO.h>
#include <stdio.h>
#include "mvm/JIT.h"
#include "mvm/Method.h"
#include "mvm/VMLet.h"
#include "MvmMemoryManager.h"
using namespace mvm;
using namespace mvm::jit;
using namespace llvm;
extern "C" void printFloat(float f) {
printf("%f\n", f);
}
extern "C" void printDouble(double d) {
printf("%f\n", d);
}
extern "C" void printLong(sint64 l) {
printf("%lld\n", l);
}
extern "C" void printInt(sint32 i) {
printf("%d\n", i);
}
extern "C" void printObject(mvm::Object* obj) {
printf("%s\n", obj->printString());
}
static void addPass(FunctionPassManager *PM, Pass *P) {
// Add the pass to the pass manager...
PM->add(P);
}
void jit::AddStandardCompilePasses(FunctionPassManager *PM) {
llvm::MutexGuard locked(mvm::jit::executionEngine->lock);
// LLVM does not allow calling functions from other modules in verifier
//PM->add(createVerifierPass()); // Verify that input is correct
addPass(PM, createCFGSimplificationPass()); // Clean up disgusting code
addPass(PM, createScalarReplAggregatesPass());// Kill useless allocas
addPass(PM, createInstructionCombiningPass()); // Clean up after IPCP & DAE
addPass(PM, createCFGSimplificationPass()); // Clean up after IPCP & DAE
addPass(PM, createPromoteMemoryToRegisterPass());// Kill useless allocas
addPass(PM, createInstructionCombiningPass()); // Clean up after IPCP & DAE
addPass(PM, createCFGSimplificationPass()); // Clean up after IPCP & DAE
addPass(PM, createTailDuplicationPass()); // Simplify cfg by copying code
addPass(PM, createInstructionCombiningPass()); // Cleanup for scalarrepl.
addPass(PM, createCFGSimplificationPass()); // Merge & remove BBs
addPass(PM, createScalarReplAggregatesPass()); // Break up aggregate allocas
addPass(PM, createInstructionCombiningPass()); // Combine silly seq's
addPass(PM, createCondPropagationPass()); // Propagate conditionals
addPass(PM, createTailCallEliminationPass()); // Eliminate tail calls
addPass(PM, createCFGSimplificationPass()); // Merge & remove BBs
addPass(PM, createReassociatePass()); // Reassociate expressions
addPass(PM, createLoopRotatePass());
addPass(PM, createLICMPass()); // Hoist loop invariants
addPass(PM, createLoopUnswitchPass()); // Unswitch loops.
addPass(PM, createInstructionCombiningPass()); // Clean up after LICM/reassoc
addPass(PM, createIndVarSimplifyPass()); // Canonicalize indvars
addPass(PM, createLoopUnrollPass()); // Unroll small loops
addPass(PM, createInstructionCombiningPass()); // Clean up after the unroller
addPass(PM, createGVNPass()); // GVN for load instructions
addPass(PM, createGCSEPass()); // Remove common subexprs
addPass(PM, createSCCPPass()); // Constant prop with SCCP
// Run instcombine after redundancy elimination to exploit opportunities
// opened up by them.
addPass(PM, createInstructionCombiningPass());
addPass(PM, createCondPropagationPass()); // Propagate conditionals
addPass(PM, createDeadStoreEliminationPass()); // Delete dead stores
addPass(PM, createAggressiveDCEPass()); // SSA based 'Aggressive DCE'
addPass(PM, createCFGSimplificationPass()); // Merge & remove BBs
}
static void initialiseTypes(llvm::Module* mod) {
{
// llvm::Type Definitions
std::vector<const llvm::Type*>StructTy_struct_NativeString_fields;
StructTy_struct_NativeString_fields.push_back(IntegerType::get(8));
StructType* StructTy_struct_NativeString =
StructType::get(StructTy_struct_NativeString_fields, /*isPacked=*/true);
mod->addTypeName("struct.mvm::NativeString", StructTy_struct_NativeString);
mod->addTypeName("struct.mvm::Object", StructTy_struct_NativeString);
mod->addTypeName("struct.mvm::Thread", StructTy_struct_NativeString);
std::vector<const llvm::Type*>StructTy_struct_PrintBuffer_fields;
StructTy_struct_PrintBuffer_fields.push_back(IntegerType::get(32));
StructTy_struct_PrintBuffer_fields.push_back(IntegerType::get(32));
PointerType* PointerTy_0 = PointerType::getUnqual(StructTy_struct_NativeString);
StructTy_struct_PrintBuffer_fields.push_back(PointerTy_0);
StructType* StructTy_struct_PrintBuffer =
StructType::get(StructTy_struct_PrintBuffer_fields, /*isPacked=*/false);
mod->addTypeName("struct.mvm::PrintBuffer", StructTy_struct_PrintBuffer);
std::vector<const llvm::Type*>StructTy_struct_VirtualTable_fields;
std::vector<const llvm::Type*>StructTy_struct_gc_vt_fields;
std::vector<const llvm::Type*>FuncTy_2_args;
FuncTy_2_args.push_back(PointerTy_0);
FuncTy_2_args.push_back(IntegerType::get(32));
FunctionType* FuncTy_2 = FunctionType::get(
/*Result=*/llvm::Type::VoidTy,
/*Params=*/FuncTy_2_args,
/*isVarArg=*/false);
PointerType* PointerTy_1 = PointerType::getUnqual(FuncTy_2);
StructTy_struct_gc_vt_fields.push_back(PointerTy_1);
StructTy_struct_gc_vt_fields.push_back(PointerTy_1);
StructType* StructTy_struct_gc_vt =
StructType::get(StructTy_struct_gc_vt_fields, /*isPacked=*/false);
mod->addTypeName("struct.mvm::gc_vt", StructTy_struct_gc_vt);
StructTy_struct_VirtualTable_fields.push_back(PointerTy_1);
StructTy_struct_VirtualTable_fields.push_back(PointerTy_1);
std::vector<const llvm::Type*>FuncTy_4_args;
FuncTy_4_args.push_back(PointerTy_0);
PointerType* PointerTy_5 = PointerType::getUnqual(StructTy_struct_PrintBuffer);
FuncTy_4_args.push_back(PointerTy_5);
FunctionType* FuncTy_4 = FunctionType::get(
/*Result=*/llvm::Type::VoidTy,
/*Params=*/FuncTy_4_args,
/*isVarArg=*/false);
PointerType* PointerTy_3 = PointerType::getUnqual(FuncTy_4);
StructTy_struct_VirtualTable_fields.push_back(PointerTy_3);
std::vector<const llvm::Type*>FuncTy_7_args;
FuncTy_7_args.push_back(PointerTy_0);
FunctionType* FuncTy_7 = FunctionType::get(
/*Result=*/IntegerType::get(32),
/*Params=*/FuncTy_7_args,
/*isVarArg=*/false);
PointerType* PointerTy_6 = PointerType::getUnqual(FuncTy_7);
StructTy_struct_VirtualTable_fields.push_back(PointerTy_6);
StructTy_struct_VirtualTable_fields.push_back(IntegerType::get(32));
OpaqueType* OpaqueTy_struct_llvm__Type = OpaqueType::get();
mod->addTypeName("struct.llvm::Type", OpaqueTy_struct_llvm__Type);
PointerType* PointerTy_8 = PointerType::getUnqual(OpaqueTy_struct_llvm__Type);
StructTy_struct_VirtualTable_fields.push_back(PointerTy_8);
StructType* StructTy_struct_VirtualTable =
StructType::get(StructTy_struct_VirtualTable_fields, /*isPacked=*/false);
mod->addTypeName("struct.mvm::VirtualTable", StructTy_struct_VirtualTable);
mod->addTypeName("struct.mvm::gc_vt", StructTy_struct_gc_vt);
mod->addTypeName("struct.llvm::Type", OpaqueTy_struct_llvm__Type);
}
{
// Lock llvm::Type Definitions
std::vector<const llvm::Type*>StructTy_struct_mvm__Lock_fields;
std::vector<const llvm::Type*>StructTy_struct_mvm__SpinLock_fields;
StructTy_struct_mvm__SpinLock_fields.push_back(IntegerType::get(32));
StructType* StructTy_struct_mvm__SpinLock =
StructType::get(StructTy_struct_mvm__SpinLock_fields, /*isPacked=*/false);
mod->addTypeName("struct.mvm::SpinLock", StructTy_struct_mvm__SpinLock);
StructTy_struct_mvm__Lock_fields.push_back(StructTy_struct_mvm__SpinLock);
std::vector<const llvm::Type*>FuncTy_1_args;
PATypeHolder StructTy_struct_mvm__Lock_fwd = OpaqueType::get();
PointerType* PointerTy_2 = PointerType::getUnqual(StructTy_struct_mvm__Lock_fwd);
FuncTy_1_args.push_back(PointerTy_2);
FunctionType* FuncTy_1 = FunctionType::get(
/*Result=*/llvm::Type::VoidTy,
/*Params=*/FuncTy_1_args,
/*isVarArg=*/false);
PointerType* PointerTy_0 = PointerType::getUnqual(FuncTy_1);
StructTy_struct_mvm__Lock_fields.push_back(PointerTy_0);
StructTy_struct_mvm__Lock_fields.push_back(PointerTy_0);
std::vector<const llvm::Type*>FuncTy_4_args;
FuncTy_4_args.push_back(PointerTy_2);
FunctionType* FuncTy_4 = FunctionType::get(
/*Result=*/IntegerType::get(32),
/*Params=*/FuncTy_4_args,
/*isVarArg=*/false);
PointerType* PointerTy_3 = PointerType::getUnqual(FuncTy_4);
StructTy_struct_mvm__Lock_fields.push_back(PointerTy_3);
StructTy_struct_mvm__Lock_fields.push_back(IntegerType::get(32));
StructType* StructTy_struct_mvm__Lock =
StructType::get(StructTy_struct_mvm__Lock_fields, /*isPacked=*/false);
mod->addTypeName("struct.mvm::Lock", StructTy_struct_mvm__Lock);
mod->addTypeName("struct.mvm::LockNormal", StructTy_struct_mvm__Lock);
cast<OpaqueType>(StructTy_struct_mvm__Lock_fwd.get())->
refineAbstractTypeTo(StructTy_struct_mvm__Lock);
StructTy_struct_mvm__Lock =
cast<StructType>(StructTy_struct_mvm__Lock_fwd.get());
std::vector<const llvm::Type*>StructTy_struct_mvm__LockRecursive_fields;
StructTy_struct_mvm__LockRecursive_fields.push_back(StructTy_struct_mvm__Lock);
StructTy_struct_mvm__LockRecursive_fields.push_back(IntegerType::get(32));
StructType* StructTy_struct_mvm__LockRecursive =
StructType::get(StructTy_struct_mvm__LockRecursive_fields,
/*isPacked=*/false);
mod->addTypeName("struct.mvm::LockRecursive",
StructTy_struct_mvm__LockRecursive);
std::vector<const llvm::Type*>StructTy_struct_mvm__Object_fields;
StructTy_struct_mvm__Object_fields.push_back(IntegerType::get(8));
StructType* StructTy_struct_mvm__Object =
StructType::get(StructTy_struct_mvm__Object_fields, /*isPacked=*/true);
mod->addTypeName("struct.mvm::Object", StructTy_struct_mvm__Object);
mod->addTypeName("struct.mvm::SpinLock", StructTy_struct_mvm__SpinLock);
// llvm::Type definition of Cond and CollectableArea
std::vector<const llvm::Type*>StructTy_struct_collectablearea_fields;
StructTy_struct_collectablearea_fields.push_back(IntegerType::get(32));
StructTy_struct_collectablearea_fields.push_back(IntegerType::get(32));
StructTy_struct_collectablearea_fields.push_back(IntegerType::get(32));
StructType* StructTy_struct_collectablearea =
StructType::get(StructTy_struct_collectablearea_fields, /*isPacked=*/false);
mod->addTypeName("struct.mvm::Cond", StructTy_struct_collectablearea);
mod->addTypeName("struct.mvm::CollectableArea", StructTy_struct_collectablearea);
}
// llvm::Type Definitions of Key
std::vector<const llvm::Type*>StructTy_struct_Key_fields;
PointerType* PointerTy_0 = PointerType::getUnqual(IntegerType::get(8));
StructTy_struct_Key_fields.push_back(PointerTy_0);
StructType* StructTy_struct_Key =
StructType::get(StructTy_struct_Key_fields, /*isPacked=*/false);
mod->addTypeName("struct.mvm::ThreadKey", StructTy_struct_Key);
// TODO
mod->addTypeName("struct.mvm::Method", StructTy_struct_Key);
mod->addTypeName("struct.mvm::Code", StructTy_struct_Key);
}
extern "C" void __register_frame(void*);
void VMLet::initialise() {
llvm::SizedMemoryCode = true;
llvm::NoFramePointerElim = true;
llvm::ExceptionHandling = true;
llvm::Module *module = jit::globalModule = new llvm::Module ("microvm");
jit::globalModuleProvider = new llvm::ExistingModuleProvider (jit::globalModule);
jit::memoryManager = new MvmMemoryManager();
initialiseTypes(globalModule);
executionEngine = llvm::ExecutionEngine::createJIT(jit::globalModuleProvider, 0, jit::memoryManager);
executionEngine->InstallExceptionTableRegister(__register_frame);
ptrType = PointerType::getUnqual(Type::Int8Ty);
{
std::vector<const llvm::Type *> arg_types;
arg_types.insert (arg_types.begin (), llvm::PointerType::getUnqual(ptrType));
llvm::FunctionType *mtype = llvm::FunctionType::get (llvm::Type::VoidTy, arg_types, false);
new llvm::Function(mtype, llvm::GlobalValue::ExternalLinkage, "llvm.va_start", module);
}
{
std::vector<const llvm::Type *> arg_types;
arg_types.insert (arg_types.begin (), llvm::Type::Int32Ty);
llvm::FunctionType *mtype = llvm::FunctionType::get (ptrType, arg_types, false);
new llvm::Function(mtype, llvm::GlobalValue::ExternalLinkage, "llvm.frameaddress", module);
}
{
const llvm::Type *BPTy = ptrType;
// Prototype malloc as "char* malloc(...)", because we don't know in
// doInitialization whether size_t is int or long.
FunctionType *FT = FunctionType::get(BPTy, std::vector<const llvm::Type*>(), true);
new llvm::Function(FT, llvm::GlobalValue::ExternalLinkage, "_ZN2gcnwEjP5gc_vt", module);
}
// Create printFloatLLVM
{
std::vector<const Type*> args;
args.push_back(Type::FloatTy);
const FunctionType* type = FunctionType::get(Type::VoidTy, args, false);
printFloatLLVM = new Function(type, GlobalValue::ExternalLinkage,
"printFloat",
module);
}
// Create printDoubleLLVM
{
std::vector<const Type*> args;
args.push_back(Type::DoubleTy);
const FunctionType* type = FunctionType::get(Type::VoidTy, args, false);
printDoubleLLVM = new Function(type, GlobalValue::ExternalLinkage,
"printDouble",
module);
}
// Create printLongLLVM
{
std::vector<const Type*> args;
args.push_back(Type::Int64Ty);
const FunctionType* type = FunctionType::get(Type::VoidTy, args, false);
printLongLLVM = new Function(type, GlobalValue::ExternalLinkage,
"printLong",
module);
}
// Create printIntLLVM
{
std::vector<const Type*> args;
args.push_back(Type::Int32Ty);
const FunctionType* type = FunctionType::get(Type::VoidTy, args, false);
printIntLLVM = new Function(type, GlobalValue::ExternalLinkage,
"printInt",
module);
}
// Create printObjectLLVM
{
std::vector<const Type*> args;
args.push_back(ptrType);
const FunctionType* type = FunctionType::get(Type::VoidTy, args, false);
printObjectLLVM = new Function(type, GlobalValue::ExternalLinkage,
"printObject",
module);
}
{
const PointerType* PointerTy_0 = ptrType;
std::vector<const Type*>FuncTy_4_args;
FuncTy_4_args.push_back(IntegerType::get(32));
std::vector<const Type*>FuncTy_7_args;
FuncTy_7_args.push_back(PointerTy_0);
FuncTy_7_args.push_back(PointerTy_0);
std::vector<const Type*>FuncTy_9_args;
FuncTy_9_args.push_back(PointerTy_0);
FunctionType* FuncTy_9 = FunctionType::get(
/*Result=*/Type::VoidTy,
/*Params=*/FuncTy_9_args,
/*isVarArg=*/false);
PointerType* PointerTy_8 = PointerType::getUnqual(FuncTy_9);
FuncTy_7_args.push_back(PointerTy_8);
std::vector<const Type*>FuncTy_11_args;
FunctionType* FuncTy_11 = FunctionType::get(
/*Result=*/PointerTy_0,
/*Params=*/FuncTy_11_args,
/*isVarArg=*/false);
llvmGetException = new Function(
/*Type=*/FuncTy_11,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"llvm.eh.exception", module); // (external, no body)
std::vector<const Type*>FuncTy_13_args;
FuncTy_13_args.push_back(PointerTy_0);
FuncTy_13_args.push_back(PointerTy_0);
FunctionType* FuncTy_13 = FunctionType::get(
/*Result=*/IntegerType::get(32),
/*Params=*/FuncTy_13_args,
/*isVarArg=*/true);
if (sizeof(void*) == 4) {
exceptionSelector = new Function(
/*Type=*/FuncTy_13,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"llvm.eh.selector.i32", module); // (external, no body)
} else {
exceptionSelector = new Function(
/*Type=*/FuncTy_13,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"llvm.eh.selector.i64", module); // (external, no body)
}
std::vector<const Type*>FuncTy_19_args;
FunctionType* FuncTy_19 = FunctionType::get(
/*Result=*/Type::VoidTy,
/*Params=*/FuncTy_19_args,
/*isVarArg=*/false);
personality = new Function(
/*Type=*/FuncTy_19,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"__gxx_personality_v0", module); // (external, no body)
unwindResume = new Function(
/*Type=*/FuncTy_9,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"_Unwind_Resume_or_Rethrow", module); // (external, no body)
std::vector<const Type*>FuncTy_17_args;
FuncTy_17_args.push_back(PointerTy_0);
FunctionType* FuncTy_17 = FunctionType::get(
/*Result=*/PointerTy_0,
/*Params=*/FuncTy_17_args,
/*isVarArg=*/false);
exceptionBeginCatch = new Function(
/*Type=*/FuncTy_17,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"__cxa_begin_catch", module); // (external, no body)
exceptionEndCatch = new Function(
/*Type=*/FuncTy_19,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"__cxa_end_catch", module); // (external, no body)
}
// Math function
{
std::vector<const Type*>args1;
args1.push_back(Type::DoubleTy);
FunctionType* FuncTy = FunctionType::get(
/*Result=*/Type::DoubleTy,
/*Params=*/args1,
/*isVarArg=*/false);
func_llvm_sqrt_f64 = new Function(FuncTy, GlobalValue::ExternalLinkage, "llvm.sqrt.f64", module);
func_llvm_sin_f64 = new Function(FuncTy, GlobalValue::ExternalLinkage, "llvm.sin.f64", module);
func_llvm_cos_f64 = new Function(FuncTy, GlobalValue::ExternalLinkage, "llvm.cos.f64", module);
func_llvm_tan_f64 = new Function(FuncTy, GlobalValue::ExternalLinkage, "tan", module);
func_llvm_asin_f64 = new Function(FuncTy, GlobalValue::ExternalLinkage, "asin", module);
func_llvm_acos_f64 = new Function(FuncTy, GlobalValue::ExternalLinkage, "acos", module);
func_llvm_atan_f64 = new Function(FuncTy, GlobalValue::ExternalLinkage, "atan", module);
func_llvm_exp_f64 = new Function(FuncTy, GlobalValue::ExternalLinkage, "exp", module);
func_llvm_log_f64 = new Function(FuncTy, GlobalValue::ExternalLinkage, "log", module);
func_llvm_ceil_f64 = new Function(FuncTy, GlobalValue::ExternalLinkage, "ceil", module);
func_llvm_floor_f64 = new Function(FuncTy, GlobalValue::ExternalLinkage, "floor", module);
func_llvm_cbrt_f64 = new Function(FuncTy, GlobalValue::ExternalLinkage, "cbrt", module);
func_llvm_cosh_f64 = new Function(FuncTy, GlobalValue::ExternalLinkage, "cosh", module);
func_llvm_expm1_f64 = new Function(FuncTy, GlobalValue::ExternalLinkage, "expm1", module);
func_llvm_log10_f64 = new Function(FuncTy, GlobalValue::ExternalLinkage, "log10", module);
func_llvm_log1p_f64 = new Function(FuncTy, GlobalValue::ExternalLinkage, "log1p", module);
func_llvm_sinh_f64 = new Function(FuncTy, GlobalValue::ExternalLinkage, "sinh", module);
func_llvm_tanh_f64 = new Function(FuncTy, GlobalValue::ExternalLinkage, "tanh", module);
func_llvm_fabs_f64 = new Function(FuncTy, GlobalValue::ExternalLinkage, "fabs", module);
std::vector<const Type*>args2;
args2.push_back(Type::DoubleTy);
args2.push_back(Type::DoubleTy);
FunctionType* FuncTy2 = FunctionType::get(
/*Result=*/Type::DoubleTy,
/*Params=*/args2,
/*isVarArg=*/false);
func_llvm_hypot_f64 = new Function(FuncTy2, GlobalValue::ExternalLinkage, "hypot", module);
//func_llvm_pow_f64 = new Function(FuncTy2, GlobalValue::ExternalLinkage, "llvm.pow.f64", module);
func_llvm_pow_f64 = new Function(FuncTy2, GlobalValue::ExternalLinkage, "pow", module);
func_llvm_atan2_f64 = new Function(FuncTy2, GlobalValue::ExternalLinkage, "atan2", module);
std::vector<const Type*>args3;
args3.push_back(Type::DoubleTy);
FunctionType* FuncTy3 = FunctionType::get(
/*Result=*/Type::DoubleTy,
/*Params=*/args3,
/*isVarArg=*/false);
func_llvm_rint_f64 = new Function(FuncTy3, GlobalValue::ExternalLinkage, "rint", module);
std::vector<const Type*>args4;
args4.push_back(Type::FloatTy);
FunctionType* FuncTyF = FunctionType::get(
/*Result=*/Type::FloatTy,
/*Params=*/args4,
/*isVarArg=*/false);
func_llvm_fabs_f32 = new Function(FuncTyF, GlobalValue::ExternalLinkage, "fabsf", module);
}
// Create setjmp
{
std::vector<const Type*> args;
args.push_back(ptrType);
const FunctionType* type = FunctionType::get(Type::Int32Ty, args,
false);
setjmpLLVM = new Function(type, GlobalValue::ExternalLinkage,
"setjmp",
module);
}
/* Create memcpy */
{
PointerType* PointerTy_2 = PointerType::getUnqual(IntegerType::get(8));
std::vector<const Type*>FuncTy_4_args;
FuncTy_4_args.push_back(PointerTy_2);
FuncTy_4_args.push_back(PointerTy_2);
FuncTy_4_args.push_back(IntegerType::get(32));
FuncTy_4_args.push_back(IntegerType::get(32));
FunctionType* FuncTy_4 = FunctionType::get(
/*Result=*/Type::VoidTy,
/*Params=*/FuncTy_4_args,
/*isVarArg=*/false);
llvm_memcpy_i32 = new Function(
/*Type=*/FuncTy_4,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"llvm.memcpy.i32", module); // (external, no body)
}
/* Create memset */
{
PointerType* PointerTy_2 = PointerType::getUnqual(IntegerType::get(8));
std::vector<const Type*>FuncTy_4_args;
FuncTy_4_args.push_back(PointerTy_2);
FuncTy_4_args.push_back(IntegerType::get(8));
FuncTy_4_args.push_back(IntegerType::get(32));
FuncTy_4_args.push_back(IntegerType::get(32));
FunctionType* FuncTy_4 = FunctionType::get(
/*Result=*/Type::VoidTy,
/*Params=*/FuncTy_4_args,
/*isVarArg=*/false);
llvm_memset_i32 = new Function(
/*Type=*/FuncTy_4,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"llvm.memset.i32", module); // (external, no body)
}
// Constant declaration
constantLongMinusOne = ConstantInt::get(Type::Int64Ty, -1);
constantLongZero = ConstantInt::get(Type::Int64Ty, 0);
constantLongOne = ConstantInt::get(Type::Int64Ty, 1);
constantZero = ConstantInt::get(Type::Int32Ty, 0);
constantInt8Zero = ConstantInt::get(Type::Int8Ty, 0);
constantOne = ConstantInt::get(Type::Int32Ty, 1);
constantTwo = ConstantInt::get(Type::Int32Ty, 2);
constantThree = ConstantInt::get(Type::Int32Ty, 3);
constantFour = ConstantInt::get(Type::Int32Ty, 4);
constantFive = ConstantInt::get(Type::Int32Ty, 5);
constantSix = ConstantInt::get(Type::Int32Ty, 6);
constantSeven = ConstantInt::get(Type::Int32Ty, 7);
constantEight = ConstantInt::get(Type::Int32Ty, 8);
constantMinusOne = ConstantInt::get(Type::Int32Ty, -1);
constantMinInt = ConstantInt::get(Type::Int32Ty, MinInt);
constantMaxInt = ConstantInt::get(Type::Int32Ty, MaxInt);
constantMinLong = ConstantInt::get(Type::Int64Ty, MinLong);
constantMaxLong = ConstantInt::get(Type::Int64Ty, MaxLong);
constantFloatZero = ConstantFP::get(Type::FloatTy, APFloat(0.0f));
constantFloatOne = ConstantFP::get(Type::FloatTy, APFloat(1.0f));
constantFloatTwo = ConstantFP::get(Type::FloatTy, APFloat(2.0f));
constantDoubleZero = ConstantFP::get(Type::DoubleTy, APFloat(0.0));
constantDoubleOne = ConstantFP::get(Type::DoubleTy, APFloat(1.0));
constantMaxIntFloat = ConstantFP::get(Type::FloatTy, APFloat(MaxIntFloat));
constantMinIntFloat = ConstantFP::get(Type::FloatTy, APFloat(MinIntFloat));
constantMinLongFloat = ConstantFP::get(Type::FloatTy, APFloat(MinLongFloat));
constantMinLongDouble = ConstantFP::get(Type::DoubleTy, APFloat(MinLongDouble));
constantMaxLongFloat = ConstantFP::get(Type::FloatTy, APFloat(MaxLongFloat));
constantMaxIntDouble = ConstantFP::get(Type::DoubleTy, APFloat(MaxIntDouble));
constantMinIntDouble = ConstantFP::get(Type::DoubleTy, APFloat(MinIntDouble));
constantMaxLongDouble = ConstantFP::get(Type::DoubleTy, APFloat(MaxLongDouble));
constantMaxLongDouble = ConstantFP::get(Type::DoubleTy, APFloat(MaxLongDouble));
constantFloatInfinity = ConstantFP::get(Type::FloatTy, APFloat(MaxFloat));
constantFloatMinusInfinity = ConstantFP::get(Type::FloatTy, APFloat(MinFloat));
constantDoubleInfinity = ConstantFP::get(Type::DoubleTy, APFloat(MaxDouble));
constantDoubleMinusInfinity = ConstantFP::get(Type::DoubleTy, APFloat(MinDouble));
constantDoubleMinusZero = ConstantFP::get(Type::DoubleTy, APFloat(-0.0));
constantFloatMinusZero = ConstantFP::get(Type::FloatTy, APFloat(-0.0f));
constantPtrNull = Constant::getNullValue(ptrType);
arrayPtrType = PointerType::getUnqual(ArrayType::get(Type::Int8Ty, 0));
//mvm::jit::protectTypes = mvm::Lock::allocNormal();
//mvm::Object::pushRoot((mvm::Object*)mvm::jit::protectTypes);
//mvm::jit::protectConstants = mvm::Lock::allocNormal();
//mvm::Object::pushRoot((mvm::Object*)mvm::jit::protectConstants);
mvm::jit::protectEngine = mvm::Lock::allocNormal();
mvm::Object::pushRoot((mvm::Object*)mvm::jit::protectEngine);
}
llvm::Function* mvm::jit::llvm_memcpy_i32;
llvm::Function* mvm::jit::llvm_memset_i32;
llvm::Function* mvm::jit::exceptionEndCatch;
llvm::Function* mvm::jit::exceptionBeginCatch;
llvm::Function* mvm::jit::unwindResume;
llvm::Function* mvm::jit::exceptionSelector;
llvm::Function* mvm::jit::personality;
llvm::Function* mvm::jit::llvmGetException;
llvm::Function* mvm::jit::printFloatLLVM;
llvm::Function* mvm::jit::printDoubleLLVM;
llvm::Function* mvm::jit::printLongLLVM;
llvm::Function* mvm::jit::printIntLLVM;
llvm::Function* mvm::jit::printObjectLLVM;
llvm::Function* mvm::jit::setjmpLLVM;
llvm::Function* mvm::jit::func_llvm_fabs_f32;
llvm::Function* mvm::jit::func_llvm_fabs_f64;
llvm::Function* mvm::jit::func_llvm_sqrt_f64;
llvm::Function* mvm::jit::func_llvm_sin_f64;
llvm::Function* mvm::jit::func_llvm_cos_f64;
llvm::Function* mvm::jit::func_llvm_tan_f64;
llvm::Function* mvm::jit::func_llvm_asin_f64;
llvm::Function* mvm::jit::func_llvm_acos_f64;
llvm::Function* mvm::jit::func_llvm_atan_f64;
llvm::Function* mvm::jit::func_llvm_atan2_f64;
llvm::Function* mvm::jit::func_llvm_exp_f64;
llvm::Function* mvm::jit::func_llvm_log_f64;
llvm::Function* mvm::jit::func_llvm_pow_f64;
llvm::Function* mvm::jit::func_llvm_ceil_f64;
llvm::Function* mvm::jit::func_llvm_floor_f64;
llvm::Function* mvm::jit::func_llvm_rint_f64;
llvm::Function* mvm::jit::func_llvm_cbrt_f64;
llvm::Function* mvm::jit::func_llvm_cosh_f64;
llvm::Function* mvm::jit::func_llvm_expm1_f64;
llvm::Function* mvm::jit::func_llvm_hypot_f64;
llvm::Function* mvm::jit::func_llvm_log10_f64;
llvm::Function* mvm::jit::func_llvm_log1p_f64;
llvm::Function* mvm::jit::func_llvm_sinh_f64;
llvm::Function* mvm::jit::func_llvm_tanh_f64;
llvm::ExecutionEngine* mvm::jit::executionEngine;
//mvm::Lock* mvm::jit::protectTypes;
//mvm::Lock* mvm::jit::protectConstants;
mvm::Lock* mvm::jit::protectEngine;
llvm::ConstantInt* mvm::jit::constantInt8Zero;
llvm::ConstantInt* mvm::jit::constantZero;
llvm::ConstantInt* mvm::jit::constantOne;
llvm::ConstantInt* mvm::jit::constantTwo;
llvm::ConstantInt* mvm::jit::constantThree;
llvm::ConstantInt* mvm::jit::constantFour;
llvm::ConstantInt* mvm::jit::constantFive;
llvm::ConstantInt* mvm::jit::constantSix;
llvm::ConstantInt* mvm::jit::constantSeven;
llvm::ConstantInt* mvm::jit::constantEight;
llvm::ConstantInt* mvm::jit::constantMinusOne;
llvm::ConstantInt* mvm::jit::constantLongMinusOne;
llvm::ConstantInt* mvm::jit::constantLongZero;
llvm::ConstantInt* mvm::jit::constantLongOne;
llvm::ConstantInt* mvm::jit::constantMinInt;
llvm::ConstantInt* mvm::jit::constantMaxInt;
llvm::ConstantInt* mvm::jit::constantMinLong;
llvm::ConstantInt* mvm::jit::constantMaxLong;
llvm::ConstantFP* mvm::jit::constantFloatZero;
llvm::ConstantFP* mvm::jit::constantFloatOne;
llvm::ConstantFP* mvm::jit::constantFloatTwo;
llvm::ConstantFP* mvm::jit::constantDoubleZero;
llvm::ConstantFP* mvm::jit::constantDoubleOne;
llvm::ConstantFP* mvm::jit::constantMaxIntFloat;
llvm::ConstantFP* mvm::jit::constantMinIntFloat;
llvm::ConstantFP* mvm::jit::constantMinLongFloat;
llvm::ConstantFP* mvm::jit::constantMinLongDouble;
llvm::ConstantFP* mvm::jit::constantMaxLongFloat;
llvm::ConstantFP* mvm::jit::constantMaxIntDouble;
llvm::ConstantFP* mvm::jit::constantMinIntDouble;
llvm::ConstantFP* mvm::jit::constantMaxLongDouble;
llvm::ConstantFP* mvm::jit::constantDoubleInfinity;
llvm::ConstantFP* mvm::jit::constantDoubleMinusInfinity;
llvm::ConstantFP* mvm::jit::constantFloatInfinity;
llvm::ConstantFP* mvm::jit::constantFloatMinusInfinity;
llvm::ConstantFP* mvm::jit::constantFloatMinusZero;
llvm::ConstantFP* mvm::jit::constantDoubleMinusZero;
llvm::Constant* mvm::jit::constantPtrNull;
const llvm::PointerType* mvm::jit::ptrType;
const llvm::Type* mvm::jit::arrayPtrType;
llvm::Module *mvm::jit::globalModule;
llvm::ExistingModuleProvider *mvm::jit::globalModuleProvider;
llvm::JITMemoryManager *mvm::jit::memoryManager;
uint64 mvm::jit::getTypeSize(const llvm::Type* type) {
return executionEngine->getTargetData()->getABITypeSize(type);
}
extern "C" void __deregister_frame(void*);
void ExceptionTable::destroyer(size_t sz) {
__deregister_frame(this->frameRegister());
}
void mvm::jit::runPasses(llvm::Function* func, llvm::FunctionPassManager* pm) {
llvm::MutexGuard locked(mvm::jit::executionEngine->lock);
pm->run(*func);
}
void mvm::jit::protectConstants() {
mvm::jit::executionEngine->lock.acquire();
}
void mvm::jit::unprotectConstants() {
mvm::jit::executionEngine->lock.release();
}
void mvm::jit::protectTypes() {
mvm::jit::executionEngine->lock.acquire();
}
void mvm::jit::unprotectTypes() {
mvm::jit::executionEngine->lock.release();
}