######################################################################
# 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
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"
// Generate a pre-optimization intermediate file if -save-temps was
// specified.
+
if opts.save_temps {
match opts.output_type {
output_type_bitcode => {
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
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 {
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)}; }
llvm::LLVMSetDebug(1);
}
+ let jit = opt_present(matches, ~"jit");
let output_type =
if parse_only || no_trans {
link::output_type_none
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,
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"),
-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>
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>,
extra_debuginfo: false,
lint_opts: ~[],
save_temps: false,
+ jit: false,
output_type: link::output_type_exe,
addl_lib_search_paths: ~[],
maybe_sysroot: None,
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;
#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"
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,
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;
LLVMRustGetLastError
LLVMRustConstSmallInt
LLVMRustConstInt
+LLVMRustJIT
LLVMRustParseBitcode
LLVMRustParseAssemblyFile
LLVMRustPrintPassTimings
LLVMIsUndef
LLVMLabelType
LLVMLabelTypeInContext
+LLVMLinkInInterpreter
LLVMMDNode
LLVMMDNodeInContext
LLVMMDString