Skip to content

Commit f6848dc

Browse files
committed
---
yaml --- r: 92127 b: refs/heads/auto c: 0b1bbc5 h: refs/heads/master i: 92125: 3249b6c 92123: 82ee965 92119: 8c74e3b 92111: 8b39fc4 92095: ba007ea v: v3
1 parent fc84a10 commit f6848dc

File tree

23 files changed

+670
-386
lines changed

23 files changed

+670
-386
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ refs/heads/try3: 9387340aab40a73e8424c48fd42f0c521a4875c0
1313
refs/tags/release-0.3.1: 495bae036dfe5ec6ceafd3312b4dca48741e845b
1414
refs/tags/release-0.4: e828ea2080499553b97dfe33b3f4d472b4562ad7
1515
refs/tags/release-0.5: 7e3bcfbf21278251ee936ad53e92e9b719702d73
16-
refs/heads/auto: 2eb22ae2b400c99966dad07145a541ce8c2586fb
16+
refs/heads/auto: 0b1bbc5fd6cf477011f5a56ca0d978658a527db9
1717
refs/heads/servo: af82457af293e2a842ba6b7759b70288da276167
1818
refs/tags/release-0.6: b4ebcfa1812664df5e142f0134a5faea3918544c
1919
refs/tags/0.1: b19db808c2793fe2976759b85a355c3ad8c8b336

branches/auto/mk/llvm.mk

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,7 @@ endif
3737
# dependencies. In these cases, commit a change that touches
3838
# the stamp in the source dir.
3939
$$(LLVM_STAMP_$(1)): $(S)src/rustllvm/llvm-auto-clean-trigger
40-
@$$(call E, make: cleaning llvm)
4140
$(Q)$(MAKE) clean-llvm
42-
@$$(call E, make: done cleaning llvm)
4341
touch $$@
4442

4543
endef

branches/auto/src/librustc/back/link.rs

Lines changed: 143 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,111 @@ pub fn WriteOutputFile(
8282
}
8383
}
8484

85+
pub mod jit {
86+
87+
use back::link::llvm_err;
88+
use driver::session::Session;
89+
use lib::llvm::llvm;
90+
use lib::llvm::{ModuleRef, ContextRef, ExecutionEngineRef};
91+
92+
use std::c_str::ToCStr;
93+
use std::cast;
94+
use std::local_data;
95+
use std::unstable::intrinsics;
96+
97+
struct LLVMJITData {
98+
ee: ExecutionEngineRef,
99+
llcx: ContextRef
100+
}
101+
102+
pub trait Engine {}
103+
impl Engine for LLVMJITData {}
104+
105+
impl Drop for LLVMJITData {
106+
fn drop(&mut self) {
107+
unsafe {
108+
llvm::LLVMDisposeExecutionEngine(self.ee);
109+
llvm::LLVMContextDispose(self.llcx);
110+
}
111+
}
112+
}
113+
114+
pub fn exec(sess: Session,
115+
c: ContextRef,
116+
m: ModuleRef,
117+
stacks: bool) {
118+
unsafe {
119+
let manager = llvm::LLVMRustPrepareJIT(intrinsics::morestack_addr());
120+
121+
// We need to tell JIT where to resolve all linked
122+
// symbols from. The equivalent of -lstd, -lcore, etc.
123+
// By default the JIT will resolve symbols from the extra and
124+
// core linked into rustc. We don't want that,
125+
// incase the user wants to use an older extra library.
126+
127+
// We custom-build a JIT execution engine via some rust wrappers
128+
// first. This wrappers takes ownership of the module passed in.
129+
let ee = llvm::LLVMRustBuildJIT(manager, m, stacks);
130+
if ee.is_null() {
131+
llvm::LLVMContextDispose(c);
132+
llvm_err(sess, ~"Could not create the JIT");
133+
}
134+
135+
// Next, we need to get a handle on the _rust_main function by
136+
// looking up it's corresponding ValueRef and then requesting that
137+
// the execution engine compiles the function.
138+
let fun = "_rust_main".with_c_str(|entry| {
139+
llvm::LLVMGetNamedFunction(m, entry)
140+
});
141+
if fun.is_null() {
142+
llvm::LLVMDisposeExecutionEngine(ee);
143+
llvm::LLVMContextDispose(c);
144+
llvm_err(sess, ~"Could not find _rust_main in the JIT");
145+
}
146+
147+
// Finally, once we have the pointer to the code, we can do some
148+
// closure magic here to turn it straight into a callable rust
149+
// closure
150+
let code = llvm::LLVMGetPointerToGlobal(ee, fun);
151+
assert!(!code.is_null());
152+
let func: extern "Rust" fn() = cast::transmute(code);
153+
func();
154+
155+
// Currently there is no method of re-using the executing engine
156+
// from LLVM in another call to the JIT. While this kinda defeats
157+
// the purpose of having a JIT in the first place, there isn't
158+
// actually much code currently which would re-use data between
159+
// different invocations of this. Additionally, the compilation
160+
// model currently isn't designed to support this scenario.
161+
//
162+
// We can't destroy the engine/context immediately here, however,
163+
// because of annihilation. The JIT code contains drop glue for any
164+
// types defined in the crate we just ran, and if any of those boxes
165+
// are going to be dropped during annihilation, the drop glue must
166+
// be run. Hence, we need to transfer ownership of this jit engine
167+
// to the caller of this function. To be convenient for now, we
168+
// shove it into TLS and have someone else remove it later on.
169+
let data = ~LLVMJITData { ee: ee, llcx: c };
170+
set_engine(data as ~Engine);
171+
}
172+
}
173+
174+
// The stage1 compiler won't work, but that doesn't really matter. TLS
175+
// changed only very recently to allow storage of owned values.
176+
local_data_key!(engine_key: ~Engine)
177+
178+
fn set_engine(engine: ~Engine) {
179+
local_data::set(engine_key, engine)
180+
}
181+
182+
pub fn consume_engine() -> Option<~Engine> {
183+
local_data::pop(engine_key)
184+
}
185+
}
186+
85187
pub mod write {
86188

189+
use back::link::jit;
87190
use back::link::{WriteOutputFile, output_type};
88191
use back::link::{output_type_assembly, output_type_bitcode};
89192
use back::link::{output_type_exe, output_type_llvm_assembly};
@@ -204,38 +307,48 @@ pub mod write {
204307
})
205308
}
206309

207-
// Create a codegen-specific pass manager to emit the actual
208-
// assembly or object files. This may not end up getting used,
209-
// but we make it anyway for good measure.
210-
let cpm = llvm::LLVMCreatePassManager();
211-
llvm::LLVMRustAddAnalysisPasses(tm, cpm, llmod);
212-
llvm::LLVMRustAddLibraryInfo(cpm, llmod);
213-
214-
match output_type {
215-
output_type_none => {}
216-
output_type_bitcode => {
217-
output.with_c_str(|buf| {
218-
llvm::LLVMWriteBitcodeToFile(llmod, buf);
219-
})
220-
}
221-
output_type_llvm_assembly => {
222-
output.with_c_str(|output| {
223-
llvm::LLVMRustPrintModule(cpm, llmod, output)
224-
})
225-
}
226-
output_type_assembly => {
227-
WriteOutputFile(sess, tm, cpm, llmod, output, lib::llvm::AssemblyFile);
228-
}
229-
output_type_exe | output_type_object => {
230-
WriteOutputFile(sess, tm, cpm, llmod, output, lib::llvm::ObjectFile);
310+
if sess.opts.jit {
311+
// If we are using JIT, go ahead and create and execute the
312+
// engine now. JIT execution takes ownership of the module and
313+
// context, so don't dispose
314+
jit::exec(sess, llcx, llmod, true);
315+
} else {
316+
// Create a codegen-specific pass manager to emit the actual
317+
// assembly or object files. This may not end up getting used,
318+
// but we make it anyway for good measure.
319+
let cpm = llvm::LLVMCreatePassManager();
320+
llvm::LLVMRustAddAnalysisPasses(tm, cpm, llmod);
321+
llvm::LLVMRustAddLibraryInfo(cpm, llmod);
322+
323+
match output_type {
324+
output_type_none => {}
325+
output_type_bitcode => {
326+
output.with_c_str(|buf| {
327+
llvm::LLVMWriteBitcodeToFile(llmod, buf);
328+
})
329+
}
330+
output_type_llvm_assembly => {
331+
output.with_c_str(|output| {
332+
llvm::LLVMRustPrintModule(cpm, llmod, output)
333+
})
334+
}
335+
output_type_assembly => {
336+
WriteOutputFile(sess, tm, cpm, llmod, output, lib::llvm::AssemblyFile);
337+
}
338+
output_type_exe | output_type_object => {
339+
WriteOutputFile(sess, tm, cpm, llmod, output, lib::llvm::ObjectFile);
340+
}
231341
}
232-
}
233342

234-
llvm::LLVMDisposePassManager(cpm);
343+
llvm::LLVMDisposePassManager(cpm);
344+
}
235345

236346
llvm::LLVMRustDisposeTargetMachine(tm);
237-
llvm::LLVMDisposeModule(llmod);
238-
llvm::LLVMContextDispose(llcx);
347+
// the jit takes ownership of these two items
348+
if !sess.opts.jit {
349+
llvm::LLVMDisposeModule(llmod);
350+
llvm::LLVMContextDispose(llcx);
351+
}
239352
if sess.time_llvm_passes() { llvm::LLVMRustPrintPassTimings(); }
240353
}
241354
}
@@ -598,8 +711,8 @@ pub fn sanitize(s: &str) -> ~str {
598711
',' => result.push_str("$C$"),
599712

600713
// '.' doesn't occur in types and functions, so reuse it
601-
// for ':' and '-'
602-
'-' | ':' => result.push_char('.'),
714+
// for ':'
715+
':' => result.push_char('.'),
603716

604717
// These are legal symbols
605718
'a' .. 'z'

branches/auto/src/librustc/back/upcall.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,22 @@ use middle::trans::type_::Type;
1515
use lib::llvm::{ModuleRef, ValueRef};
1616

1717
pub struct Upcalls {
18+
trace: ValueRef,
1819
rust_personality: ValueRef,
20+
reset_stack_limit: ValueRef
1921
}
2022

2123
macro_rules! upcall (
24+
(fn $name:ident($($arg:expr),+) -> $ret:expr) => ({
25+
let fn_ty = Type::func([ $($arg),* ], &$ret);
26+
base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty)
27+
});
28+
(nothrow fn $name:ident($($arg:expr),+) -> $ret:expr) => ({
29+
let fn_ty = Type::func([ $($arg),* ], &$ret);
30+
let decl = base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty);
31+
base::set_no_unwind(decl);
32+
decl
33+
});
2234
(nothrow fn $name:ident -> $ret:expr) => ({
2335
let fn_ty = Type::func([], &$ret);
2436
let decl = base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty);
@@ -27,9 +39,13 @@ macro_rules! upcall (
2739
})
2840
)
2941

30-
pub fn declare_upcalls(_targ_cfg: @session::config,
31-
llmod: ModuleRef) -> @Upcalls {
42+
pub fn declare_upcalls(targ_cfg: @session::config, llmod: ModuleRef) -> @Upcalls {
43+
let opaque_ptr = Type::i8().ptr_to();
44+
let int_ty = Type::int(targ_cfg.arch);
45+
3246
@Upcalls {
47+
trace: upcall!(fn trace(opaque_ptr, opaque_ptr, int_ty) -> Type::void()),
3348
rust_personality: upcall!(nothrow fn rust_personality -> Type::i32()),
49+
reset_stack_limit: upcall!(nothrow fn reset_stack_limit -> Type::void())
3450
}
3551
}

branches/auto/src/librustc/driver/driver.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,11 @@ pub fn stop_after_phase_5(sess: Session) -> bool {
419419
debug!("not building executable, returning early from compile_input");
420420
return true;
421421
}
422+
423+
if sess.opts.jit {
424+
debug!("running JIT, returning early from compile_input");
425+
return true;
426+
}
422427
return false;
423428
}
424429

@@ -746,6 +751,7 @@ pub fn build_session_options(binary: @str,
746751
} else { No }
747752
};
748753
let gc = debugging_opts & session::gc != 0;
754+
let jit = debugging_opts & session::jit != 0;
749755
let extra_debuginfo = debugging_opts & session::extra_debug_info != 0;
750756
let debuginfo = debugging_opts & session::debug_info != 0 ||
751757
extra_debuginfo;
@@ -796,6 +802,7 @@ pub fn build_session_options(binary: @str,
796802
extra_debuginfo: extra_debuginfo,
797803
lint_opts: lint_opts,
798804
save_temps: save_temps,
805+
jit: jit,
799806
output_type: output_type,
800807
addl_lib_search_paths: @mut addl_lib_search_paths,
801808
ar: ar,

branches/auto/src/librustc/driver/session.rs

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -44,28 +44,30 @@ pub static time_llvm_passes: uint = 1 << 3;
4444
pub static trans_stats: uint = 1 << 4;
4545
pub static asm_comments: uint = 1 << 5;
4646
pub static no_verify: uint = 1 << 6;
47-
pub static coherence: uint = 1 << 7;
48-
pub static borrowck_stats: uint = 1 << 8;
49-
pub static borrowck_note_pure: uint = 1 << 9;
50-
pub static borrowck_note_loan: uint = 1 << 10;
51-
pub static no_landing_pads: uint = 1 << 11;
52-
pub static debug_llvm: uint = 1 << 12;
53-
pub static count_type_sizes: uint = 1 << 13;
54-
pub static meta_stats: uint = 1 << 14;
55-
pub static no_opt: uint = 1 << 15;
56-
pub static gc: uint = 1 << 16;
57-
pub static debug_info: uint = 1 << 17;
58-
pub static extra_debug_info: uint = 1 << 18;
59-
pub static print_link_args: uint = 1 << 19;
60-
pub static no_debug_borrows: uint = 1 << 20;
61-
pub static lint_llvm: uint = 1 << 21;
62-
pub static print_llvm_passes: uint = 1 << 22;
63-
pub static no_vectorize_loops: uint = 1 << 23;
64-
pub static no_vectorize_slp: uint = 1 << 24;
65-
pub static no_prepopulate_passes: uint = 1 << 25;
66-
pub static use_softfp: uint = 1 << 26;
67-
pub static gen_crate_map: uint = 1 << 27;
68-
pub static prefer_dynamic: uint = 1 << 28;
47+
pub static trace: uint = 1 << 7;
48+
pub static coherence: uint = 1 << 8;
49+
pub static borrowck_stats: uint = 1 << 9;
50+
pub static borrowck_note_pure: uint = 1 << 10;
51+
pub static borrowck_note_loan: uint = 1 << 11;
52+
pub static no_landing_pads: uint = 1 << 12;
53+
pub static debug_llvm: uint = 1 << 13;
54+
pub static count_type_sizes: uint = 1 << 14;
55+
pub static meta_stats: uint = 1 << 15;
56+
pub static no_opt: uint = 1 << 16;
57+
pub static gc: uint = 1 << 17;
58+
pub static jit: uint = 1 << 18;
59+
pub static debug_info: uint = 1 << 19;
60+
pub static extra_debug_info: uint = 1 << 20;
61+
pub static print_link_args: uint = 1 << 21;
62+
pub static no_debug_borrows: uint = 1 << 22;
63+
pub static lint_llvm: uint = 1 << 23;
64+
pub static print_llvm_passes: uint = 1 << 24;
65+
pub static no_vectorize_loops: uint = 1 << 25;
66+
pub static no_vectorize_slp: uint = 1 << 26;
67+
pub static no_prepopulate_passes: uint = 1 << 27;
68+
pub static use_softfp: uint = 1 << 28;
69+
pub static gen_crate_map: uint = 1 << 29;
70+
pub static prefer_dynamic: uint = 1 << 30;
6971

7072
pub fn debugging_opts_map() -> ~[(&'static str, &'static str, uint)] {
7173
~[("verbose", "in general, enable more debug printouts", verbose),
@@ -77,6 +79,7 @@ pub fn debugging_opts_map() -> ~[(&'static str, &'static str, uint)] {
7779
("trans-stats", "gather trans statistics", trans_stats),
7880
("asm-comments", "generate comments into the assembly (may change behavior)", asm_comments),
7981
("no-verify", "skip LLVM verification", no_verify),
82+
("trace", "emit trace logs", trace),
8083
("coherence", "perform coherence checking", coherence),
8184
("borrowck-stats", "gather borrowck statistics", borrowck_stats),
8285
("borrowck-note-pure", "note where purity is req'd",
@@ -92,6 +95,7 @@ pub fn debugging_opts_map() -> ~[(&'static str, &'static str, uint)] {
9295
("no-opt", "do not optimize, even if -O is passed", no_opt),
9396
("print-link-args", "Print the arguments passed to the linker", print_link_args),
9497
("gc", "Garbage collect shared data (experimental)", gc),
98+
("jit", "Execute using JIT (experimental)", jit),
9599
("extra-debug-info", "Extra debugging info (experimental)",
96100
extra_debug_info),
97101
("debug-info", "Produce debug info (experimental)", debug_info),
@@ -142,6 +146,7 @@ pub struct options {
142146
extra_debuginfo: bool,
143147
lint_opts: ~[(lint::lint, lint::level)],
144148
save_temps: bool,
149+
jit: bool,
145150
output_type: back::link::output_type,
146151
addl_lib_search_paths: @mut HashSet<Path>, // This is mutable for rustpkg, which
147152
// updates search paths based on the
@@ -306,6 +311,7 @@ impl Session_ {
306311
pub fn asm_comments(&self) -> bool { self.debugging_opt(asm_comments) }
307312
pub fn no_verify(&self) -> bool { self.debugging_opt(no_verify) }
308313
pub fn lint_llvm(&self) -> bool { self.debugging_opt(lint_llvm) }
314+
pub fn trace(&self) -> bool { self.debugging_opt(trace) }
309315
pub fn coherence(&self) -> bool { self.debugging_opt(coherence) }
310316
pub fn borrowck_stats(&self) -> bool { self.debugging_opt(borrowck_stats) }
311317
pub fn borrowck_note_pure(&self) -> bool {
@@ -364,6 +370,7 @@ pub fn basic_options() -> @options {
364370
extra_debuginfo: false,
365371
lint_opts: ~[],
366372
save_temps: false,
373+
jit: false,
367374
output_type: link::output_type_exe,
368375
addl_lib_search_paths: @mut HashSet::new(),
369376
ar: None,

branches/auto/src/librustc/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,10 @@ pub fn monitor(f: proc(@diagnostic::Emitter)) {
363363
let _finally = finally { ch: ch };
364364

365365
f(demitter);
366+
367+
// Due reasons explain in #7732, if there was a jit execution context it
368+
// must be consumed and passed along to our parent task.
369+
back::link::jit::consume_engine()
366370
}) {
367371
result::Ok(_) => { /* fallthrough */ }
368372
result::Err(_) => {

0 commit comments

Comments
 (0)