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