-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathopt.rs
78 lines (69 loc) · 2.3 KB
/
opt.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
use crate::ir;
use crate::ir::traverse::{Folder, RunFolder};
use crate::swc_globals;
use crate::utils::default_hash;
mod constant;
mod dce;
mod forward;
mod inline;
mod mut2ssa;
mod redundant;
mod redundant_obj;
mod sroa;
mod unroll;
mod writeonly;
#[cfg(test)]
mod tests;
pub fn run_passes(_: &swc_globals::Initialized, ir: ir::Block) -> ir::Block {
OptCx::new(ir)
.converge_with("main-opt-loop", |cx| {
cx.converge::<dce::Dce>("dce")
.run::<redundant::LoadStore>("redundant-load-store")
.run::<mut2ssa::Mut2Ssa>("mut2ssa")
.run::<forward::Reads>("forward-reads-redundancy")
.converge::<dce::Dce>("dce-forwarded-reads")
.run::<unroll::Loops>("unroll-loops")
.run::<sroa::Replace>("scalar-replace")
.run::<redundant_obj::LoadStore>("redundant-obj")
.run::<writeonly::Objects>("writeonly-objects")
.run::<constant::ConstProp>("const-prop")
.run::<inline::Inline>("inline")
})
.into_inner()
}
struct OptCx(ir::Block);
impl OptCx {
fn new(block: ir::Block) -> Self {
Self(block)
}
fn into_inner(self) -> ir::Block {
self.0
}
#[inline(never)] // for better profiling
fn run<F: Folder + Default>(self, name: &str) -> Self {
log::debug!("{}: running single pass", name);
Self(F::default().run_folder(self.0))
}
#[inline(never)] // for better profiling
fn converge<F: Folder + Default>(self, name: &str) -> Self {
self.converge_with(name, |cx| cx.run::<F>(name))
}
fn converge_with(self, name: &str, mut f: impl FnMut(Self) -> Self) -> Self {
let mut this = self;
let mut last_hash = default_hash(&this.0);
log::debug!("{}: starting opt-to-convergence, hash {}", name, last_hash);
let mut iter = 0u64;
loop {
iter += 1;
this = f(this);
let hash = default_hash(&this.0);
if hash == last_hash {
log::debug!("{}: stopping opt-to-convergence, iteration {}", name, iter);
return this;
} else {
log::debug!("{}: continuing opt-to-convergence, hash {}", name, hash);
}
last_hash = hash;
}
}
}