mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Add experimental JIT compiler
This commit is contained in:
parent
97bb812238
commit
d7aa9918ef
@ -216,7 +216,8 @@ RUSTC_INPUTS := $(S)src/rustc/driver/rustc.rs
|
||||
######################################################################
|
||||
|
||||
# FIXME: x86-ism
|
||||
LLVM_COMPONENTS=x86 ipo bitreader bitwriter linker asmparser
|
||||
LLVM_COMPONENTS=x86 ipo bitreader bitwriter linker asmparser jit mcjit \
|
||||
interpreter
|
||||
|
||||
define DEF_LLVM_VARS
|
||||
# The configure script defines these variables with the target triples
|
||||
|
2
configure
vendored
2
configure
vendored
@ -595,7 +595,7 @@ do
|
||||
LLVM_TARGET="--target=$t"
|
||||
|
||||
# Disable unused LLVM features
|
||||
LLVM_OPTS="$LLVM_DBG_OPTS --disable-docs --disable-jit \
|
||||
LLVM_OPTS="$LLVM_DBG_OPTS --disable-docs \
|
||||
--enable-bindings=none --disable-threads \
|
||||
--disable-pthreads"
|
||||
|
||||
|
@ -76,6 +76,7 @@ mod write {
|
||||
// Generate a pre-optimization intermediate file if -save-temps was
|
||||
// specified.
|
||||
|
||||
|
||||
if opts.save_temps {
|
||||
match opts.output_type {
|
||||
output_type_bitcode => {
|
||||
@ -135,7 +136,7 @@ mod write {
|
||||
llvm::LLVMPassManagerBuilderDispose(MPMB);
|
||||
}
|
||||
if !sess.no_verify() { llvm::LLVMAddVerifierPass(pm.llpm); }
|
||||
if is_object_or_assembly_or_exe(opts.output_type) {
|
||||
if is_object_or_assembly_or_exe(opts.output_type) || opts.jit {
|
||||
let LLVMOptNone = 0 as c_int; // -O0
|
||||
let LLVMOptLess = 1 as c_int; // -O1
|
||||
let LLVMOptDefault = 2 as c_int; // -O2, -Os
|
||||
@ -148,6 +149,29 @@ mod write {
|
||||
session::Aggressive => LLVMOptAggressive
|
||||
};
|
||||
|
||||
if opts.jit {
|
||||
// If we are using JIT, go ahead and create and
|
||||
// execute the engine now.
|
||||
|
||||
/*llvm::LLVMAddBasicAliasAnalysisPass(pm.llpm);
|
||||
llvm::LLVMAddInstructionCombiningPass(pm.llpm);
|
||||
llvm::LLVMAddReassociatePass(pm.llpm);
|
||||
llvm::LLVMAddGVNPass(pm.llpm);
|
||||
llvm::LLVMAddCFGSimplificationPass(pm.llpm);*/
|
||||
|
||||
// JIT execution takes ownership of the module,
|
||||
// so don't dispose and return.
|
||||
|
||||
if !llvm::LLVMRustJIT(pm.llpm,
|
||||
llmod,
|
||||
CodeGenOptLevel,
|
||||
true) {
|
||||
llvm_err(sess, ~"Could not JIT");
|
||||
}
|
||||
if sess.time_llvm_passes() { llvm::LLVMRustPrintPassTimings(); }
|
||||
return;
|
||||
}
|
||||
|
||||
let mut FileType;
|
||||
if opts.output_type == output_type_object ||
|
||||
opts.output_type == output_type_exe {
|
||||
|
@ -259,7 +259,8 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
|
||||
|
||||
let stop_after_codegen =
|
||||
sess.opts.output_type != link::output_type_exe ||
|
||||
sess.opts.static && sess.building_library;
|
||||
(sess.opts.static && sess.building_library) ||
|
||||
sess.opts.jit;
|
||||
|
||||
if stop_after_codegen { return {crate: crate, tcx: Some(ty_cx)}; }
|
||||
|
||||
@ -483,6 +484,7 @@ fn build_session_options(matches: getopts::Matches,
|
||||
llvm::LLVMSetDebug(1);
|
||||
}
|
||||
|
||||
let jit = opt_present(matches, ~"jit");
|
||||
let output_type =
|
||||
if parse_only || no_trans {
|
||||
link::output_type_none
|
||||
@ -545,6 +547,7 @@ fn build_session_options(matches: getopts::Matches,
|
||||
extra_debuginfo: extra_debuginfo,
|
||||
lint_opts: lint_opts,
|
||||
save_temps: save_temps,
|
||||
jit: jit,
|
||||
output_type: output_type,
|
||||
addl_lib_search_paths: addl_lib_search_paths,
|
||||
maybe_sysroot: sysroot_opt,
|
||||
@ -620,6 +623,7 @@ fn opts() -> ~[getopts::Opt] {
|
||||
optopt(~"o"), optopt(~"out-dir"), optflag(~"xg"),
|
||||
optflag(~"c"), optflag(~"g"), optflag(~"save-temps"),
|
||||
optopt(~"sysroot"), optopt(~"target"),
|
||||
optflag(~"jit"),
|
||||
|
||||
optmulti(~"W"), optmulti(~"warn"),
|
||||
optmulti(~"A"), optmulti(~"allow"),
|
||||
|
@ -42,6 +42,7 @@ Options:
|
||||
-L <path> Add a directory to the library search path
|
||||
--lib Compile a library crate
|
||||
--ls List the symbols defined by a compiled library crate
|
||||
--jit Execute using JIT (experimental)
|
||||
--no-trans Run all passes except translation; no output
|
||||
-O Equivalent to --opt-level=2
|
||||
-o <filename> Write output to <filename>
|
||||
|
@ -108,6 +108,7 @@ type options =
|
||||
extra_debuginfo: bool,
|
||||
lint_opts: ~[(lint::lint, lint::level)],
|
||||
save_temps: bool,
|
||||
jit: bool,
|
||||
output_type: back::link::output_type,
|
||||
addl_lib_search_paths: ~[Path],
|
||||
maybe_sysroot: Option<Path>,
|
||||
@ -249,6 +250,7 @@ fn basic_options() -> @options {
|
||||
extra_debuginfo: false,
|
||||
lint_opts: ~[],
|
||||
save_temps: false,
|
||||
jit: false,
|
||||
output_type: link::output_type_exe,
|
||||
addl_lib_search_paths: ~[],
|
||||
maybe_sysroot: None,
|
||||
|
@ -986,6 +986,12 @@ extern mod llvm {
|
||||
call. */
|
||||
fn LLVMRustGetLastError() -> *c_char;
|
||||
|
||||
/** JIT the module. **/
|
||||
fn LLVMRustJIT(PM: PassManagerRef,
|
||||
M: ModuleRef,
|
||||
OptLevel: c_int,
|
||||
EnableSegmentedStacks: bool) -> bool;
|
||||
|
||||
/** Parses the bitcode in the given memory buffer. */
|
||||
fn LLVMRustParseBitcode(MemBuf: MemoryBufferRef) -> ModuleRef;
|
||||
|
||||
|
@ -28,6 +28,11 @@
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
#include "llvm/Support/Host.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/DynamicLibrary.h"
|
||||
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||||
#include "llvm/ExecutionEngine/JIT.h"
|
||||
#include "llvm/ExecutionEngine/Interpreter.h"
|
||||
#include "llvm/ExecutionEngine/GenericValue.h"
|
||||
#include "llvm-c/Core.h"
|
||||
#include "llvm-c/BitReader.h"
|
||||
#include "llvm-c/Object.h"
|
||||
@ -68,6 +73,61 @@ void LLVMInitializeX86TargetMC();
|
||||
void LLVMInitializeX86AsmPrinter();
|
||||
void LLVMInitializeX86AsmParser();
|
||||
|
||||
// Only initialize the platforms supported by Rust here,
|
||||
// because using --llvm-root will have multiple platforms
|
||||
// that rustllvm doesn't actually link to and it's pointless to put target info
|
||||
// into the registry that Rust can not generate machine code for.
|
||||
|
||||
#define INITIALIZE_TARGETS() LLVMInitializeX86TargetInfo(); \
|
||||
LLVMInitializeX86Target(); \
|
||||
LLVMInitializeX86TargetMC(); \
|
||||
LLVMInitializeX86AsmPrinter(); \
|
||||
LLVMInitializeX86AsmParser();
|
||||
|
||||
extern "C" bool
|
||||
LLVMRustJIT(LLVMPassManagerRef PMR,
|
||||
LLVMModuleRef M,
|
||||
CodeGenOpt::Level OptLevel,
|
||||
bool EnableSegmentedStacks) {
|
||||
|
||||
INITIALIZE_TARGETS();
|
||||
InitializeNativeTarget();
|
||||
InitializeNativeTargetAsmPrinter();
|
||||
|
||||
std::string Err;
|
||||
TargetOptions Options;
|
||||
Options.NoFramePointerElim = true;
|
||||
Options.EnableSegmentedStacks = EnableSegmentedStacks;
|
||||
|
||||
PassManager *PM = unwrap<PassManager>(PMR);
|
||||
|
||||
PM->run(*unwrap(M));
|
||||
|
||||
ExecutionEngine* EE = EngineBuilder(unwrap(M))
|
||||
.setTargetOptions(Options)
|
||||
.setOptLevel(OptLevel)
|
||||
.setUseMCJIT(true)
|
||||
.create();
|
||||
|
||||
if(!EE || Err != "") {
|
||||
LLVMRustError = Err.c_str();
|
||||
return false;
|
||||
}
|
||||
|
||||
Function* func = EE->FindFunctionNamed("main");
|
||||
|
||||
if(!func || Err != "") {
|
||||
LLVMRustError = Err.c_str();
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<GenericValue> args;
|
||||
|
||||
EE->runFunction(func, args);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
extern "C" bool
|
||||
LLVMRustWriteOutputFile(LLVMPassManagerRef PMR,
|
||||
LLVMModuleRef M,
|
||||
@ -77,16 +137,7 @@ LLVMRustWriteOutputFile(LLVMPassManagerRef PMR,
|
||||
CodeGenOpt::Level OptLevel,
|
||||
bool EnableSegmentedStacks) {
|
||||
|
||||
// Only initialize the platforms supported by Rust here,
|
||||
// because using --llvm-root will have multiple platforms
|
||||
// that rustllvm doesn't actually link to and it's pointless to put target info
|
||||
// into the registry that Rust can not generate machine code for.
|
||||
|
||||
LLVMInitializeX86TargetInfo();
|
||||
LLVMInitializeX86Target();
|
||||
LLVMInitializeX86TargetMC();
|
||||
LLVMInitializeX86AsmPrinter();
|
||||
LLVMInitializeX86AsmParser();
|
||||
INITIALIZE_TARGETS();
|
||||
|
||||
TargetOptions Options;
|
||||
Options.NoFramePointerElim = true;
|
||||
|
@ -4,6 +4,7 @@ LLVMRustWriteOutputFile
|
||||
LLVMRustGetLastError
|
||||
LLVMRustConstSmallInt
|
||||
LLVMRustConstInt
|
||||
LLVMRustJIT
|
||||
LLVMRustParseBitcode
|
||||
LLVMRustParseAssemblyFile
|
||||
LLVMRustPrintPassTimings
|
||||
@ -485,6 +486,7 @@ LLVMIsThreadLocal
|
||||
LLVMIsUndef
|
||||
LLVMLabelType
|
||||
LLVMLabelTypeInContext
|
||||
LLVMLinkInInterpreter
|
||||
LLVMMDNode
|
||||
LLVMMDNodeInContext
|
||||
LLVMMDString
|
||||
|
Loading…
Reference in New Issue
Block a user