Skip to content
This repository was archived by the owner on Jan 7, 2022. It is now read-only.

Commit cc5cf54

Browse files
bors[bot]vext01
andcommitted
Merge #11
11: TIR test suite. r=ltratt a=vext01 This change adds a rustc flag `--emit yk-tir` which causes ykrustc to dump the TIR in a textual format and exit. Then we add a test new test suite kind which allows us to write tests against the textual TIR dumps. It works in much the same way as the existing MirOpt test suite. Note that this needs a ykpack change to go in first. Raising a draft PR for initial discussion. What do you think of the general approach? [I think `generate_tir()` can be tidied up some in light of this change, but I didn't want to do that in this PR]. Co-authored-by: Edd Barrett <vext01@gmail.com>
2 parents ee89705 + 26a4331 commit cc5cf54

File tree

12 files changed

+181
-30
lines changed

12 files changed

+181
-30
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4046,7 +4046,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
40464046
[[package]]
40474047
name = "ykpack"
40484048
version = "0.1.0"
4049-
source = "git+https://github.com/softdevteam/ykpack#358a7403a5b8c03809f5c5b07933a6850060afa4"
4049+
source = "git+https://github.com/softdevteam/ykpack#9c5542d9d556ce745f0b21983a009a1297f371e4"
40504050
dependencies = [
40514051
"fallible-iterator 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
40524052
"rmp-serde 0.14.0 (git+https://github.com/3Hren/msgpack-rust?rev=40b3d480b20961e6eeceb416b32bcd0a3383846a)",

src/bootstrap/builder.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,7 @@ impl<'a> Builder<'a> {
372372
test::RunFail,
373373
test::RunPassValgrind,
374374
test::MirOpt,
375+
test::YkTir,
375376
test::Codegen,
376377
test::CodegenUnits,
377378
test::Incremental,

src/bootstrap/test.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -812,6 +812,12 @@ default_test!(MirOpt {
812812
suite: "mir-opt"
813813
});
814814

815+
default_test!(YkTir {
816+
path: "src/test/yk-tir",
817+
mode: "yk-tir",
818+
suite: "yk-tir"
819+
});
820+
815821
default_test!(Codegen {
816822
path: "src/test/codegen",
817823
mode: "codegen",

src/librustc/session/config.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ pub enum DebugInfo {
122122

123123
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord, RustcEncodable, RustcDecodable)]
124124
pub enum OutputType {
125+
YkTir,
125126
Bitcode,
126127
Assembly,
127128
LlvmAssembly,
@@ -138,7 +139,8 @@ impl OutputType {
138139
fn is_compatible_with_codegen_units_and_single_output_file(&self) -> bool {
139140
match *self {
140141
OutputType::Exe | OutputType::DepInfo => true,
141-
OutputType::Bitcode
142+
OutputType::YkTir
143+
| OutputType::Bitcode
142144
| OutputType::Assembly
143145
| OutputType::LlvmAssembly
144146
| OutputType::Mir
@@ -149,6 +151,7 @@ impl OutputType {
149151

150152
fn shorthand(&self) -> &'static str {
151153
match *self {
154+
OutputType::YkTir => "yk-tir",
152155
OutputType::Bitcode => "llvm-bc",
153156
OutputType::Assembly => "asm",
154157
OutputType::LlvmAssembly => "llvm-ir",
@@ -162,6 +165,7 @@ impl OutputType {
162165

163166
fn from_shorthand(shorthand: &str) -> Option<Self> {
164167
Some(match shorthand {
168+
"yk-tir" => OutputType::YkTir,
165169
"asm" => OutputType::Assembly,
166170
"llvm-ir" => OutputType::LlvmAssembly,
167171
"mir" => OutputType::Mir,
@@ -176,7 +180,8 @@ impl OutputType {
176180

177181
fn shorthands_display() -> String {
178182
format!(
179-
"`{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`",
183+
"`{}` `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`",
184+
OutputType::YkTir.shorthand(),
180185
OutputType::Bitcode.shorthand(),
181186
OutputType::Assembly.shorthand(),
182187
OutputType::LlvmAssembly.shorthand(),
@@ -190,6 +195,7 @@ impl OutputType {
190195

191196
pub fn extension(&self) -> &'static str {
192197
match *self {
198+
OutputType::YkTir => "yktir",
193199
OutputType::Bitcode => "bc",
194200
OutputType::Assembly => "s",
195201
OutputType::LlvmAssembly => "ll",
@@ -253,7 +259,8 @@ impl OutputTypes {
253259
// True if any of the output types require codegen or linking.
254260
pub fn should_codegen(&self) -> bool {
255261
self.0.keys().any(|k| match *k {
256-
OutputType::Bitcode
262+
OutputType::YkTir
263+
| OutputType::Bitcode
257264
| OutputType::Assembly
258265
| OutputType::LlvmAssembly
259266
| OutputType::Mir
@@ -1696,7 +1703,7 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
16961703
"emit",
16971704
"Comma separated list of types of output for \
16981705
the compiler to emit",
1699-
"[asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir]",
1706+
"[asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir|yk-tir]",
17001707
),
17011708
opt::multi_s(
17021709
"",

src/librustc_codegen_ssa/back/write.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,7 @@ pub fn start_async_codegen<B: ExtraBackendMethods>(
425425

426426
for output_type in sess.opts.output_types.keys() {
427427
match *output_type {
428+
OutputType::YkTir => {},
428429
OutputType::Bitcode => { modules_config.emit_bc = true; }
429430
OutputType::LlvmAssembly => { modules_config.emit_ir = true; }
430431
OutputType::Assembly => {
@@ -598,6 +599,7 @@ fn produce_final_output_artifacts(sess: &Session,
598599
user_wants_objects = true;
599600
copy_if_one_unit(OutputType::Object, true);
600601
}
602+
OutputType::YkTir |
601603
OutputType::Mir |
602604
OutputType::Metadata |
603605
OutputType::Exe |

src/librustc_interface/passes.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ use syntax::symbol::Symbol;
4646
use syntax::feature_gate::AttributeType;
4747
use syntax_pos::{FileName, hygiene};
4848
use syntax_ext;
49-
use rustc_yk_sections::mir_cfg::generate_tir;
49+
use rustc_yk_sections::emit_tir::{generate_tir, TirMode};
5050
use rustc_codegen_utils::link::out_filename;
5151
use rustc::util::nodemap::DefIdSet;
5252

@@ -1040,12 +1040,20 @@ pub fn start_codegen<'tcx>(
10401040

10411041
// Output Yorick debug sections into binary targets.
10421042
if tcx.sess.crate_types.borrow().contains(&config::CrateType::Executable) {
1043-
let out_fname = out_filename(
1044-
tcx.sess, config::CrateType::Executable, &outputs,
1045-
&*tcx.crate_name(LOCAL_CRATE).as_str());
1043+
let tir_mode = if tcx.sess.opts.output_types.contains_key(&OutputType::YkTir) {
1044+
// The user passed "--emit yk-tir" so we will output textual TIR and stop.
1045+
TirMode::TextDump(outputs.path(OutputType::YkTir))
1046+
} else {
1047+
// TIR will be encoded into the compiled binary.
1048+
let out_fname = out_filename(
1049+
tcx.sess, config::CrateType::Executable, &outputs,
1050+
&*tcx.crate_name(LOCAL_CRATE).as_str());
1051+
TirMode::Default(out_fname)
1052+
};
10461053

1047-
match generate_tir(&tcx, &def_ids, out_fname) {
1048-
Ok(tir) => tcx.sess.yk_link_objects.borrow_mut().push(tir),
1054+
match generate_tir(&tcx, &def_ids, tir_mode) {
1055+
Ok(Some(obj)) => tcx.sess.yk_link_objects.borrow_mut().push(obj),
1056+
Ok(None) => (),
10491057
Err(e) => {
10501058
tcx.sess.err(&format!("could not emit TIR: {}", e));
10511059
tcx.sess.abort_if_errors();

src/librustc_yk_sections/mir_cfg.rs renamed to src/librustc_yk_sections/emit_tir.rs

Lines changed: 70 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use std::path::PathBuf;
2525
use std::fs::File;
2626
use rustc_yk_link::YkExtraLinkObject;
2727
use std::fs;
28+
use std::io::Write;
2829
use std::error::Error;
2930
use std::cell::{Cell, RefCell};
3031
use std::mem::size_of;
@@ -37,6 +38,15 @@ use ykpack::LocalIndex as TirLocal;
3738
const SECTION_NAME: &'static str = ".yk_tir";
3839
const TMP_EXT: &'static str = ".yk_tir.tmp";
3940

41+
/// Describes how to output MIR.
42+
pub enum TirMode {
43+
/// Write MIR into an object file for linkage. The inner path should be the path to the main
44+
/// executable (from this we generate a filename for the resulting object).
45+
Default(PathBuf),
46+
/// Write MIR in textual form the specified path.
47+
TextDump(PathBuf),
48+
}
49+
4050
/// A conversion context holds the state needed to perform the conversion to (pre-SSA) TIR.
4151
struct ConvCx<'a, 'tcx, 'gcx> {
4252
/// The compiler's god struct. Needed for queries etc.
@@ -111,16 +121,55 @@ impl<'a, 'tcx, 'gcx> ConvCx<'a, 'tcx, 'gcx> {
111121
}
112122
}
113123

114-
/// Converts and serialises the specified DefIds, returning an linkable ELF object.
124+
/// Writes TIR to file for the specified DefIds, possibly returning a linkable ELF object.
115125
pub fn generate_tir<'a, 'tcx, 'gcx>(
116-
tcx: &'a TyCtxt<'a, 'tcx, 'gcx>, def_ids: &DefIdSet, exe_filename: PathBuf)
117-
-> Result<YkExtraLinkObject, Box<dyn Error>> {
126+
tcx: &'a TyCtxt<'a, 'tcx, 'gcx>, def_ids: &DefIdSet, mode: TirMode)
127+
-> Result<Option<YkExtraLinkObject>, Box<dyn Error>>
128+
{
129+
let tir_path = do_generate_tir(tcx, def_ids, &mode)?;
130+
match mode {
131+
TirMode::Default(_) => {
132+
// In this case the file at `tir_path` is a raw binary file which we use to make an
133+
// object file for linkage.
134+
let obj = YkExtraLinkObject::new(&tir_path, SECTION_NAME);
135+
// Now we have our object, we can remove the temp file. It's not the end of the world
136+
// if we can't remove it, so we allow this to fail.
137+
fs::remove_file(tir_path).ok();
138+
Ok(Some(obj))
139+
},
140+
TirMode::TextDump(_) => {
141+
// In this case we have no object to link, and we keep the file at `tir_path` around,
142+
// as this is the text dump the user asked for.
143+
Ok(None)
144+
}
145+
}
146+
}
118147

119-
// The filename must be the same between builds for the reproducible build tests to pass.
120-
let mut mir_path: String = exe_filename.to_str().unwrap().to_owned();
121-
mir_path.push_str(TMP_EXT);
122-
let mut fh = File::create(&mir_path)?;
123-
let mut enc = ykpack::Encoder::from(&mut fh);
148+
fn do_generate_tir<'a, 'tcx, 'gcx>(
149+
tcx: &'a TyCtxt<'a, 'tcx, 'gcx>, def_ids: &DefIdSet, mode: &TirMode)
150+
-> Result<PathBuf, Box<dyn Error>>
151+
{
152+
let (tir_path, mut default_file, textdump_file) = match mode {
153+
TirMode::Default(exe_path) => {
154+
// The default mode of operation dumps TIR in binary format to a temporary file, which
155+
// is later converted into an ELF object. Note that the temporary file name must be the
156+
// same between builds for the reproducible build tests to pass.
157+
let mut tir_path = exe_path.clone();
158+
tir_path.set_extension(TMP_EXT);
159+
let mut file = File::create(&tir_path)?;
160+
(tir_path, Some(file), None)
161+
},
162+
TirMode::TextDump(dump_path) => {
163+
// In text dump mode we just write lines to a file and we don't need an encoder.
164+
let mut file = File::create(&dump_path)?;
165+
(dump_path.clone(), None, Some(file))
166+
},
167+
};
168+
169+
let mut enc = match default_file {
170+
Some(ref mut f) => Some(ykpack::Encoder::from(f)),
171+
_ => None,
172+
};
124173

125174
// To satisfy the reproducible build tests, the CFG must be written out in a deterministic
126175
// order, thus we sort the `DefId`s first.
@@ -141,17 +190,22 @@ pub fn generate_tir<'a, 'tcx, 'gcx>(
141190
let phied_pack = PhiInserter::new(mir, pre_ssa_pack, ccx.def_sites()).pack();
142191

143192
// FIXME - rename variables with fresh SSA names.
144-
enc.serialise(phied_pack)?;
193+
194+
if let Some(ref mut e) = enc {
195+
e.serialise(phied_pack)?;
196+
} else {
197+
write!(textdump_file.as_ref().unwrap(), "{}", phied_pack)?;
198+
}
145199
}
146200
}
147-
enc.done()?;
148201

149-
// Now graft the resulting blob file into an object file.
150-
let path = PathBuf::from(mir_path);
151-
let ret = YkExtraLinkObject::new(&path, SECTION_NAME);
152-
fs::remove_file(path)?;
202+
if let Some(e) = enc {
203+
// Now finalise the encoder and convert the resulting blob file into an object file for
204+
// linkage into the main binary. Once we've converted, we no longer need the original file.
205+
e.done()?;
206+
}
153207

154-
Ok(ret)
208+
Ok(tir_path)
155209
}
156210

157211
/// Lazy computation of dominance frontiers.
@@ -327,7 +381,7 @@ impl<'tcx> ToPack<ykpack::Pack> for (&ConvCx<'_, 'tcx, '_>, &DefId, &Mir<'tcx>)
327381
let ser_def_id = ykpack::DefId::new(
328382
ccx.tcx.crate_hash(def_id.krate).as_u64(), def_id.index.as_raw_u32());
329383

330-
ykpack::Pack::Mir(ykpack::Mir::new(ser_def_id, ser_blks))
384+
ykpack::Pack::Mir(ykpack::Mir::new(ser_def_id, ccx.tcx.item_path_str(**def_id), ser_blks))
331385
}
332386
}
333387

src/librustc_yk_sections/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ extern crate ykpack;
1616
extern crate rustc_data_structures;
1717
#[macro_use] extern crate log;
1818

19-
pub mod mir_cfg;
19+
pub mod emit_tir;

src/test/yk-tir/simple_phi.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
use std::env;
2+
3+
#[no_trace]
4+
fn main() {
5+
let x = env::args().count();
6+
let mut res = 42;
7+
8+
if x > 4 {
9+
res = 100;
10+
}
11+
12+
println!("res: {}", res);
13+
}
14+
15+
// END RUST SOURCE
16+
// [Begin TIR for main]
17+
// ...
18+
// bb2:
19+
// ...
20+
// term: SwitchInt { target_bbs: [4, 3] }
21+
// bb3:
22+
// Assign(Local(0), Unimplemented)
23+
// term: Goto { target_bb: 4 }
24+
// bb4:
25+
// Assign(Local(0), Phi([Local(0), Local(0)]))
26+
// ...
27+
// [End TIR for main]

src/tools/compiletest/src/common.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub enum Mode {
2525
RunMake,
2626
Ui,
2727
MirOpt,
28+
YkTir,
2829
}
2930

3031
impl Mode {
@@ -60,6 +61,7 @@ impl FromStr for Mode {
6061
"run-make" => Ok(RunMake),
6162
"ui" => Ok(Ui),
6263
"mir-opt" => Ok(MirOpt),
64+
"yk-tir" => Ok(YkTir),
6365
_ => Err(()),
6466
}
6567
}
@@ -83,6 +85,7 @@ impl fmt::Display for Mode {
8385
RunMake => "run-make",
8486
Ui => "ui",
8587
MirOpt => "mir-opt",
88+
YkTir => "yk-tir",
8689
};
8790
fmt::Display::fmt(s, f)
8891
}

0 commit comments

Comments
 (0)