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::{Backtrace, 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 Backtrace::default(),
93 )
94 .unwrap();
95
96 let mut pass_manager = PassManager::default();
97 crate::register_known_passes(&mut pass_manager);
98
99 let mut group = PassGroup::default();
100 for pass in passes {
101 group.append_pass(pass);
102 }
103
104 let before = context.to_string();
105 let modified = pass_manager.run(&mut context, &group).unwrap();
106 let after = context.to_string();
107
108 if std::env::args().any(|x| x == "--nocapture") {
110 println!("{}", prettydiff::diff_lines(&before, &after));
111 }
112
113 assert_eq!(expected.is_some(), modified);
114
115 let Some(expected) = expected else {
116 return;
117 };
118
119 let actual = context
120 .to_string()
121 .lines()
122 .filter_map(|x| {
123 if x.contains(", !") {
124 Some(format!("{}\n", x.trim()))
125 } else {
126 None
127 }
128 })
129 .collect::<Vec<String>>();
130
131 assert!(!actual.is_empty());
132
133 let mut expected_matches = actual.len();
134
135 for (actual, expected) in actual.iter().zip(expected) {
136 if !actual.contains(expected) {
137 panic!("Actual: {actual:?} does not contains expected: {expected:?}. (Run with --nocapture to see a diff)");
138 } else {
139 expected_matches -= 1;
140 }
141 }
142
143 assert_eq!(expected_matches, 0);
144 }
145}