1pub mod arg_demotion;
17pub use arg_demotion::*;
18pub mod const_demotion;
19pub use const_demotion::*;
20pub mod constants;
21pub use constants::*;
22pub mod conditional_constprop;
23pub use conditional_constprop::*;
24pub mod cse;
25pub use cse::*;
26pub mod dce;
27pub use dce::*;
28pub mod inline;
29pub use inline::*;
30pub mod mem2reg;
31pub use mem2reg::*;
32pub mod memcpyopt;
33pub use memcpyopt::*;
34pub mod misc_demotion;
35pub use misc_demotion::*;
36pub mod ret_demotion;
37pub use ret_demotion::*;
38pub mod simplify_cfg;
39pub use simplify_cfg::*;
40pub mod sroa;
41pub use sroa::*;
42pub mod fn_dedup;
43pub use fn_dedup::*;
44
45mod target_fuel;
46
47#[cfg(test)]
48pub mod tests {
49 use crate::{PassGroup, PassManager};
50 use sway_features::ExperimentalFeatures;
51 use sway_types::SourceEngine;
52
53 pub(crate) fn assert_optimization<'a>(
74 passes: &[&'static str],
75 body: &str,
76 expected: Option<impl IntoIterator<Item = &'a str>>,
77 ) {
78 let source_engine = SourceEngine::default();
79 let mut context = crate::parse(
80 &format!(
81 "script {{
82 {body}
83 }}
84
85 !0 = \"a.sw\"
86 "
87 ),
88 &source_engine,
89 ExperimentalFeatures::default(),
90 )
91 .unwrap();
92
93 let mut pass_manager = PassManager::default();
94 crate::register_known_passes(&mut pass_manager);
95
96 let mut group = PassGroup::default();
97 for pass in passes {
98 group.append_pass(pass);
99 }
100
101 let before = context.to_string();
102 let modified = pass_manager.run(&mut context, &group).unwrap();
103 let after = context.to_string();
104
105 if std::env::args().any(|x| x == "--nocapture") {
107 println!("{}", prettydiff::diff_lines(&before, &after));
108 }
109
110 assert_eq!(expected.is_some(), modified);
111
112 let Some(expected) = expected else {
113 return;
114 };
115
116 let actual = context
117 .to_string()
118 .lines()
119 .filter_map(|x| {
120 if x.contains(", !") {
121 Some(format!("{}\n", x.trim()))
122 } else {
123 None
124 }
125 })
126 .collect::<Vec<String>>();
127
128 assert!(!actual.is_empty());
129
130 let mut expected_matches = actual.len();
131
132 for (actual, expected) in actual.iter().zip(expected) {
133 if !actual.contains(expected) {
134 panic!("Actual: {actual:?} does not contains expected: {expected:?}. (Run with --nocapture to see a diff)");
135 } else {
136 expected_matches -= 1;
137 }
138 }
139
140 assert_eq!(expected_matches, 0);
141 }
142}