Rust · 3444 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(name: &str) -> PathBuf {
8 let path = PathBuf::from("test_programs").join(name);
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 #[test]
23 fn optir_respects_requested_optimization_level() {
24 let source = fixture("sroa_small_array.f90");
25
26 let o0_request = CaptureRequest {
27 input: source.clone(),
28 requested: BTreeSet::from([Stage::Ir, Stage::OptIr]),
29 opt_level: OptLevel::O0,
30 };
31 let o2_request = CaptureRequest {
32 input: source,
33 requested: BTreeSet::from([Stage::Ir, Stage::OptIr]),
34 opt_level: OptLevel::O2,
35 };
36
37 let ir_o0 = capture_text(o0_request.clone(), Stage::Ir);
38 let opt_ir_o0 = capture_text(o0_request, Stage::OptIr);
39 assert_eq!(
40 ir_o0, opt_ir_o0,
41 "O0 optimized IR capture should match the lowered IR exactly"
42 );
43 assert!(
44 ir_o0.contains("alloca [i32 x 3]"),
45 "baseline lowered IR should still show the aggregate alloca"
46 );
47
48 let ir_o2 = capture_text(o2_request.clone(), Stage::Ir);
49 let opt_ir_o2 = capture_text(o2_request, Stage::OptIr);
50 assert_eq!(
51 ir_o2, ir_o0,
52 "requested optimization level must not change the raw lowered IR capture"
53 );
54 assert_ne!(
55 opt_ir_o2, ir_o2,
56 "O2 optimized IR capture should differ from the raw lowered IR"
57 );
58 assert!(
59 !opt_ir_o2.contains("alloca [i32 x 3]"),
60 "SROA+mem2reg should remove the aggregate alloca from optimized IR"
61 );
62 assert!(
63 opt_ir_o2.contains("const_int 60"),
64 "optimized IR should expose the folded result for the test program"
65 );
66 }
67
68 #[test]
69 fn backend_capture_stages_use_optimized_ir() {
70 let source = fixture("inline_pure.f90");
71 let outlined_helper = "_afs_internal___prog_inline_pure_1";
72
73 let asm_o0 = capture_text(
74 CaptureRequest {
75 input: source.clone(),
76 requested: BTreeSet::from([Stage::Asm]),
77 opt_level: OptLevel::O0,
78 },
79 Stage::Asm,
80 );
81 let asm_o2 = capture_text(
82 CaptureRequest {
83 input: source,
84 requested: BTreeSet::from([Stage::Asm]),
85 opt_level: OptLevel::O2,
86 },
87 Stage::Asm,
88 );
89
90 assert!(
91 asm_o0.contains(&format!("bl {}", outlined_helper)),
92 "O0 assembly should still contain the out-of-line helper call"
93 );
94 assert!(
95 asm_o0.contains(&format!("{}:", outlined_helper)),
96 "O0 assembly should still emit the contained helper function"
97 );
98 assert!(
99 !asm_o2.contains(&format!("bl {}", outlined_helper)),
100 "O2 assembly capture should reflect inlining and remove helper calls"
101 );
102 assert!(
103 !asm_o2.contains(&format!("{}:", outlined_helper)),
104 "O2 assembly capture should not emit a now-dead outlined helper"
105 );
106 }
107