Rust · 1900 bytes Raw Blame History
1 use std::collections::BTreeSet;
2 use std::path::PathBuf;
3
4 use armfortas::driver::OptLevel;
5 use armfortas::testing::{capture_from_path, CaptureRequest, CapturedStage, Stage};
6
7 fn fixture(path: &str) -> PathBuf {
8 let path = PathBuf::from(path);
9 assert!(path.exists(), "missing test fixture {}", path.display());
10 path
11 }
12
13 fn capture_text(request: CaptureRequest, stage: Stage) -> String {
14 let result = capture_from_path(&request).expect("capture should succeed");
15 match result.get(stage) {
16 Some(CapturedStage::Text(text)) => text.clone(),
17 Some(CapturedStage::Run(_)) => panic!("expected text stage for {}", stage.as_str()),
18 None => panic!("missing requested stage {}", stage.as_str()),
19 }
20 }
21
22 fn count(haystack: &str, needle: &str) -> usize {
23 haystack.matches(needle).count()
24 }
25
26 #[test]
27 fn gvn_reduces_cross_block_recomputation_for_value_args() {
28 let source = fixture("tests/fixtures/gvn_cross_block.f90");
29
30 let ir_o0 = capture_text(
31 CaptureRequest {
32 input: source.clone(),
33 requested: BTreeSet::from([Stage::Ir]),
34 opt_level: OptLevel::O0,
35 },
36 Stage::Ir,
37 );
38 let opt_ir_o2 = capture_text(
39 CaptureRequest {
40 input: source,
41 requested: BTreeSet::from([Stage::OptIr]),
42 opt_level: OptLevel::O2,
43 },
44 Stage::OptIr,
45 );
46
47 assert_eq!(
48 count(&ir_o0, " = iadd "),
49 4,
50 "lowered IR should contain four adds before optimization rewrites:\n{}",
51 ir_o0
52 );
53 assert_eq!(
54 count(&opt_ir_o2, " = iadd "),
55 2,
56 "O2 optimized IR should reuse the dominating a+b value across blocks:\n{}",
57 opt_ir_o2
58 );
59 assert_eq!(
60 count(&opt_ir_o2, "iadd %0, %1"),
61 1,
62 "optimized IR should materialize the source add only once:\n{}",
63 opt_ir_o2
64 );
65 }
66