Skip to content

Commit bdd7cf8

Browse files
librust-pnacl-trans: New argument, --raw, to automatically run the minimum set
of PNaCl passes need for translation.
1 parent c468aff commit bdd7cf8

File tree

1 file changed

+47
-13
lines changed

1 file changed

+47
-13
lines changed

src/librust-pnacl-trans/lib.rs

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@ extern crate libc;
2626
extern crate log;
2727
extern crate llvm = "rustc_llvm";
2828

29-
use getopts::{optopt, optflag, getopts, reqopt, OptGroup, Matches};
29+
use getopts::{optopt, optflag, getopts, reqopt, optmulti, OptGroup, Matches};
3030
use std::c_str::CString;
31+
use std::collections::{HashSet, HashMap};
3132
use std::fmt::Show;
3233
use std::io::fs::File;
3334
use std::io::process::{Command, InheritFd, ExitStatus};
@@ -62,7 +63,9 @@ fn optgroups() -> Vec<OptGroup> {
6263
optopt("", "opt-level", "Optimize with possible levels 0-3", "LEVEL"),
6364
optflag("", "save-temps", "Save temp files"),
6465
optopt("", "target", "The target triple to codegen for", ""),
65-
reqopt("", "cross-path", "The path to the Pepper SDK", ""))
66+
reqopt("", "cross-path", "The path to the Pepper SDK", ""),
67+
optmulti("", "raw", "The specified bitcodes have had none of the usual PNaCl IR \
68+
legalization passes run on them", ""))
6669

6770
}
6871
fn fatal<T: Str + Show>(msg: T) -> ! {
@@ -137,17 +140,36 @@ pub fn main() {
137140
let cross_path = matches.opt_str("cross-path").unwrap();
138141
let cross_path = os::make_absolute(&Path::new(cross_path));
139142

140-
let input = if !matches.free.is_empty() {
141-
matches.free.clone()
142-
} else {
143-
fatal("missing input file(s)");
144-
};
143+
let mut input: Vec<(String, bool)> = matches.free
144+
.iter()
145+
.map(|i| (i.clone(), false) )
146+
.collect();
147+
145148
let output = matches.opt_str("o").unwrap();
146149
let ctxt = unsafe { llvm::LLVMContextCreate() };
147150

148-
let mut bc_input = Vec::new();
151+
unsafe {
152+
llvm::LLVMInitializePasses();
153+
}
154+
155+
{
156+
let raw_bitcodes_vec = matches.opt_strs("raw");
157+
let mut raw_bitcodes = HashSet::new();
158+
for i in raw_bitcodes_vec.move_iter() {
159+
if !raw_bitcodes.insert(i.clone()) {
160+
warn(format!("file specified two or more times in --raw: `{}`", i));
161+
}
162+
input.push((i, true));
163+
}
164+
}
165+
166+
if input.is_empty() {
167+
fatal("missing input file(s)");
168+
}
169+
170+
let mut bc_input = HashMap::new();
149171
let mut obj_input: Vec<String> = Vec::new();
150-
for i in input.move_iter() {
172+
for (i, is_raw) in input.move_iter() {
151173
let bc = match File::open(&Path::new(i.clone())).read_to_end() {
152174
Ok(buf) => buf,
153175
Err(e) => {
@@ -165,9 +187,23 @@ pub fn main() {
165187
}
166188
});
167189
if llmod == ptr::mut_null() {
190+
if is_raw {
191+
warn(format!("raw bitcode isn't bitcode: `{}`", i));
192+
}
168193
obj_input.push(i);
169194
} else {
170-
bc_input.push((llmod, i));
195+
if is_raw {
196+
unsafe {
197+
let pm = llvm::LLVMCreatePassManager();
198+
"pnacl-sjlj-eh".with_c_str(|s| assert!(llvm::LLVMRustAddPass(pm, s)) );
199+
"expand-varargs".with_c_str(|s| assert!(llvm::LLVMRustAddPass(pm, s)) );
200+
llvm::LLVMRunPassManager(pm, llmod);
201+
llvm::LLVMDisposePassManager(pm);
202+
}
203+
}
204+
if !bc_input.insert(i.clone(), llmod) {
205+
warn(format!("file specified two or more times: `{}`", i));
206+
}
171207
}
172208
}
173209

@@ -191,8 +227,6 @@ pub fn main() {
191227
}
192228
}
193229

194-
llvm::LLVMInitializePasses();
195-
196230
// Only initialize the platforms supported by Rust here, because
197231
// using --llvm-root will have multiple platforms that rustllvm
198232
// doesn't actually link to and it's pointless to put target info
@@ -239,7 +273,7 @@ pub fn main() {
239273

240274
let obj_input: Vec<String> = bc_input
241275
.move_iter()
242-
.filter_map(|(llmod, i)| {
276+
.filter_map(|(i, llmod)| {
243277
debug!("translating `{}`", i);
244278
unsafe {
245279
let pm = llvm::LLVMCreatePassManager();

0 commit comments

Comments
 (0)