Skip to content

Commit e527320

Browse files
committed
---
yaml --- r: 63340 b: refs/heads/snap-stage3 c: 83d44f8 h: refs/heads/master v: v3
1 parent a675c41 commit e527320

File tree

19 files changed

+348
-270
lines changed

19 files changed

+348
-270
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: 2d28d645422c1617be58c8ca7ad9a457264ca850
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: 5de67f9cc9674752bb6b9db6c2db790a19ec4e9c
4+
refs/heads/snap-stage3: 83d44f87e5fe8935c1f8a5f26409a99286675650
55
refs/heads/try: 7b78b52e602bb3ea8174f9b2006bff3315f03ef9
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b

branches/snap-stage3/src/librustc/back/link.rs

Lines changed: 55 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -101,34 +101,21 @@ pub mod jit {
101101
use back::link::llvm_err;
102102
use driver::session::Session;
103103
use lib::llvm::llvm;
104-
use lib::llvm::{ModuleRef, PassManagerRef};
104+
use lib::llvm::{ModuleRef, ContextRef};
105105
use metadata::cstore;
106106

107107
use core::cast;
108-
use core::libc::c_int;
109108
use core::ptr;
110109
use core::str;
111-
112-
pub mod rusti {
113-
#[nolink]
114-
#[abi = "rust-intrinsic"]
115-
pub extern "rust-intrinsic" {
116-
pub fn morestack_addr() -> *();
117-
}
118-
}
119-
120-
pub struct Closure {
121-
code: *(),
122-
env: *(),
123-
}
110+
use core::sys;
111+
use core::unstable::intrinsics;
124112

125113
pub fn exec(sess: Session,
126-
pm: PassManagerRef,
114+
c: ContextRef,
127115
m: ModuleRef,
128-
opt: c_int,
129116
stacks: bool) {
130117
unsafe {
131-
let manager = llvm::LLVMRustPrepareJIT(rusti::morestack_addr());
118+
let manager = llvm::LLVMRustPrepareJIT(intrinsics::morestack_addr());
132119

133120
// We need to tell JIT where to resolve all linked
134121
// symbols from. The equivalent of -lstd, -lcore, etc.
@@ -152,26 +139,43 @@ pub mod jit {
152139
});
153140
}
154141

155-
// The execute function will return a void pointer
156-
// to the _rust_main function. We can do closure
157-
// magic here to turn it straight into a callable rust
158-
// closure. It will also cleanup the memory manager
159-
// for us.
160-
161-
let entry = llvm::LLVMRustExecuteJIT(manager,
162-
pm, m, opt, stacks);
163-
164-
if ptr::is_null(entry) {
165-
llvm_err(sess, ~"Could not JIT");
166-
} else {
167-
let closure = Closure {
168-
code: entry,
169-
env: ptr::null()
170-
};
171-
let func: &fn() = cast::transmute(closure);
142+
// We custom-build a JIT execution engine via some rust wrappers
143+
// first. This wrappers takes ownership of the module passed in.
144+
let ee = llvm::LLVMRustBuildJIT(manager, m, stacks);
145+
if ee.is_null() {
146+
llvm::LLVMContextDispose(c);
147+
llvm_err(sess, ~"Could not create the JIT");
148+
}
172149

173-
func();
150+
// Next, we need to get a handle on the _rust_main function by
151+
// looking up it's corresponding ValueRef and then requesting that
152+
// the execution engine compiles the function.
153+
let fun = do str::as_c_str("_rust_main") |entry| {
154+
llvm::LLVMGetNamedFunction(m, entry)
155+
};
156+
if fun.is_null() {
157+
llvm::LLVMDisposeExecutionEngine(ee);
158+
llvm::LLVMContextDispose(c);
159+
llvm_err(sess, ~"Could not find _rust_main in the JIT");
174160
}
161+
162+
// Finally, once we have the pointer to the code, we can do some
163+
// closure magic here to turn it straight into a callable rust
164+
// closure
165+
let code = llvm::LLVMGetPointerToGlobal(ee, fun);
166+
assert!(!code.is_null());
167+
let closure = sys::Closure {
168+
code: code,
169+
env: ptr::null()
170+
};
171+
let func: &fn() = cast::transmute(closure);
172+
func();
173+
174+
// Sadly, there currently is no interface to re-use this execution
175+
// engine, so it's disposed of here along with the context to
176+
// prevent leaks.
177+
llvm::LLVMDisposeExecutionEngine(ee);
178+
llvm::LLVMContextDispose(c);
175179
}
176180
}
177181
}
@@ -188,6 +192,7 @@ pub mod write {
188192
use driver::session;
189193
use lib::llvm::llvm;
190194
use lib::llvm::{ModuleRef, mk_pass_manager, mk_target_data};
195+
use lib::llvm::{ContextRef};
191196
use lib;
192197

193198
use back::passes;
@@ -206,6 +211,7 @@ pub mod write {
206211
}
207212

208213
pub fn run_passes(sess: Session,
214+
llcx: ContextRef,
209215
llmod: ModuleRef,
210216
output_type: output_type,
211217
output: &Path) {
@@ -261,7 +267,17 @@ pub mod write {
261267
debug!("Running Module Optimization Pass");
262268
mpm.run(llmod);
263269

264-
if is_object_or_assembly_or_exe(output_type) || opts.jit {
270+
if opts.jit {
271+
// If we are using JIT, go ahead and create and execute the
272+
// engine now. JIT execution takes ownership of the module and
273+
// context, so don't dispose and return.
274+
jit::exec(sess, llcx, llmod, true);
275+
276+
if sess.time_llvm_passes() {
277+
llvm::LLVMRustPrintPassTimings();
278+
}
279+
return;
280+
} else if is_object_or_assembly_or_exe(output_type) {
265281
let LLVMOptNone = 0 as c_int; // -O0
266282
let LLVMOptLess = 1 as c_int; // -O1
267283
let LLVMOptDefault = 2 as c_int; // -O2, -Os
@@ -274,20 +290,6 @@ pub mod write {
274290
session::Aggressive => LLVMOptAggressive
275291
};
276292

277-
if opts.jit {
278-
// If we are using JIT, go ahead and create and
279-
// execute the engine now.
280-
// JIT execution takes ownership of the module,
281-
// so don't dispose and return.
282-
283-
jit::exec(sess, pm.llpm, llmod, CodeGenOptLevel, true);
284-
285-
if sess.time_llvm_passes() {
286-
llvm::LLVMRustPrintPassTimings();
287-
}
288-
return;
289-
}
290-
291293
let FileType;
292294
if output_type == output_type_object ||
293295
output_type == output_type_exe {
@@ -348,6 +350,7 @@ pub mod write {
348350
// Clean up and return
349351

350352
llvm::LLVMDisposeModule(llmod);
353+
llvm::LLVMContextDispose(llcx);
351354
if sess.time_llvm_passes() {
352355
llvm::LLVMRustPrintPassTimings();
353356
}
@@ -366,6 +369,7 @@ pub mod write {
366369
}
367370

368371
llvm::LLVMDisposeModule(llmod);
372+
llvm::LLVMContextDispose(llcx);
369373
if sess.time_llvm_passes() { llvm::LLVMRustPrintPassTimings(); }
370374
}
371375
}

branches/snap-stage3/src/librustc/driver/driver.rs

Lines changed: 52 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -65,24 +65,34 @@ pub fn source_name(input: &input) -> @str {
6565
6666
pub fn default_configuration(sess: Session, argv0: @str, input: &input) ->
6767
ast::crate_cfg {
68-
let (libc, tos) = match sess.targ_cfg.os {
69-
session::os_win32 => (@"msvcrt.dll", @"win32"),
70-
session::os_macos => (@"libc.dylib", @"macos"),
71-
session::os_linux => (@"libc.so.6", @"linux"),
72-
session::os_android => (@"libc.so", @"android"),
73-
session::os_freebsd => (@"libc.so.7", @"freebsd")
68+
let libc = match sess.targ_cfg.os {
69+
session::os_win32 => @"msvcrt.dll",
70+
session::os_macos => @"libc.dylib",
71+
session::os_linux => @"libc.so.6",
72+
session::os_android => @"libc.so",
73+
session::os_freebsd => @"libc.so.7"
74+
// _ { "libc.so" }
7475
};
76+
let tos = match sess.targ_cfg.os {
77+
session::os_win32 => @"win32",
78+
session::os_macos => @"macos",
79+
session::os_linux => @"linux",
80+
session::os_android => @"android",
81+
session::os_freebsd => @"freebsd"
82+
// _ { "libc.so" }
83+
};
84+
85+
let mk = attr::mk_name_value_item_str;
7586

7687
// ARM is bi-endian, however using NDK seems to default
7788
// to little-endian unless a flag is provided.
7889
let (end,arch,wordsz) = match sess.targ_cfg.arch {
79-
abi::X86 => (@"little", @"x86", @"32"),
80-
abi::X86_64 => (@"little", @"x86_64", @"64"),
81-
abi::Arm => (@"little", @"arm", @"32"),
82-
abi::Mips => (@"big", @"mips", @"32")
90+
abi::X86 => (@"little",@"x86",@"32"),
91+
abi::X86_64 => (@"little",@"x86_64",@"64"),
92+
abi::Arm => (@"little",@"arm",@"32"),
93+
abi::Mips => (@"big",@"mips",@"32")
8394
};
8495

85-
let mk = attr::mk_name_value_item_str;
8696
return ~[ // Target bindings.
8797
attr::mk_word_item(os::FAMILY.to_managed()),
8898
mk(@"target_os", tos),
@@ -205,7 +215,7 @@ pub fn compile_rest(sess: Session,
205215

206216
let mut crate = crate_opt.unwrap();
207217

208-
let (llmod, link_meta) = {
218+
let (llcx, llmod, link_meta) = {
209219
crate = time(time_passes, ~"intrinsic injection", ||
210220
front::intrinsic_inject::inject_intrinsic(sess, crate));
211221

@@ -328,14 +338,14 @@ pub fn compile_rest(sess: Session,
328338
let obj_filename = outputs.obj_filename.with_filetype("s");
329339

330340
time(time_passes, ~"LLVM passes", ||
331-
link::write::run_passes(sess, llmod, output_type,
332-
&obj_filename));
341+
link::write::run_passes(sess, llcx, llmod, output_type,
342+
&obj_filename));
333343

334344
link::write::run_ndk(sess, &obj_filename, &outputs.obj_filename);
335345
} else {
336346
time(time_passes, ~"LLVM passes", ||
337-
link::write::run_passes(sess, llmod, sess.opts.output_type,
338-
&outputs.obj_filename));
347+
link::write::run_passes(sess, llcx, llmod, sess.opts.output_type,
348+
&outputs.obj_filename));
339349
}
340350

341351
let stop_after_codegen =
@@ -453,37 +463,36 @@ pub fn pretty_print_input(sess: Session, cfg: ast::crate_cfg, input: &input,
453463
}
454464
455465
pub fn get_os(triple: &str) -> Option<session::os> {
456-
for os_names.each |&(name, os)| {
457-
if triple.contains(name) { return Some(os) }
458-
}
459-
None
466+
if triple.contains("win32") ||
467+
triple.contains("mingw32") {
468+
Some(session::os_win32)
469+
} else if triple.contains("darwin") {
470+
Some(session::os_macos)
471+
} else if triple.contains("android") {
472+
Some(session::os_android)
473+
} else if triple.contains("linux") {
474+
Some(session::os_linux)
475+
} else if triple.contains("freebsd") {
476+
Some(session::os_freebsd)
477+
} else { None }
460478
}
461-
static os_names : &'static [(&'static str, session::os)] = &'static [
462-
("win32", session::os_win32),
463-
("darwin", session::os_macos),
464-
("android", session::os_android),
465-
("linux", session::os_linux),
466-
("freebsd", session::os_freebsd)];
467479

468480
pub fn get_arch(triple: &str) -> Option<abi::Architecture> {
469-
for architecture_abis.each |&(arch, abi)| {
470-
if triple.contains(arch) { return Some(abi) }
471-
}
472-
None
481+
if triple.contains("i386") ||
482+
triple.contains("i486") ||
483+
triple.contains("i586") ||
484+
triple.contains("i686") ||
485+
triple.contains("i786") {
486+
Some(abi::X86)
487+
} else if triple.contains("x86_64") {
488+
Some(abi::X86_64)
489+
} else if triple.contains("arm") ||
490+
triple.contains("xscale") {
491+
Some(abi::Arm)
492+
} else if triple.contains("mips") {
493+
Some(abi::Mips)
494+
} else { None }
473495
}
474-
static architecture_abis : &'static [(&'static str, abi::Architecture)] = &'static [
475-
("i386", abi::X86),
476-
("i486", abi::X86),
477-
("i586", abi::X86),
478-
("i686", abi::X86),
479-
("i786", abi::X86),
480-
481-
("x86_64", abi::X86_64),
482-
483-
("arm", abi::Arm),
484-
("xscale", abi::Arm),
485-
486-
("mips", abi::Mips)];
487496

488497
pub fn build_target_config(sopts: @session::options,
489498
demitter: diagnostic::Emitter)

0 commit comments

Comments
 (0)