Skip to content

Commit

Permalink
Improve optimizer (swc-project#660)
Browse files Browse the repository at this point in the history
Although it's quite naive at the moment, I added two optimization passes.

 - dead code elimination (Closes swc-project#607)
 - inlining
  • Loading branch information
kdy1 authored Feb 13, 2020
1 parent 82e73b1 commit 348052b
Show file tree
Hide file tree
Showing 38 changed files with 8,160 additions and 2,583 deletions.
2 changes: 1 addition & 1 deletion common/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "swc_common"
version = "0.5.2"
version = "0.5.3"
authors = ["강동윤 <[email protected]>"]
license = "Apache-2.0/MIT"
repository = "https://github.com/swc-project/swc.git"
Expand Down
38 changes: 37 additions & 1 deletion common/src/fold/and_then.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
use super::{Fold, FoldWith, Visit, VisitWith};
use crate::util::move_map::MoveMap;
use crate::{
pass::{CompilerPass, Repeated, RepeatedPass},
util::move_map::MoveMap,
};
use std::borrow::Cow;

#[macro_export]
macro_rules! chain {
Expand Down Expand Up @@ -90,3 +94,35 @@ where
self.second.visit(node);
}
}

impl<A, B> CompilerPass for AndThen<A, B>
where
A: CompilerPass,
B: CompilerPass,
{
fn name() -> Cow<'static, str> {
format!("{} -> {}", A::name(), B::name()).into()
}
}

impl<A, B, At> RepeatedPass<At> for AndThen<A, B>
where
A: RepeatedPass<At>,
B: RepeatedPass<At>,
{
}

impl<A, B> Repeated for AndThen<A, B>
where
A: Repeated,
B: Repeated,
{
fn changed(&self) -> bool {
self.first.changed() || self.second.changed()
}

fn reset(&mut self) {
self.first.reset();
self.second.reset();
}
}
1 change: 1 addition & 0 deletions common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pub mod fold;
pub mod input;
pub mod iter;
pub mod macros;
pub mod pass;
mod pos;
mod rustc_data_structures;
pub mod serializer;
Expand Down
85 changes: 85 additions & 0 deletions common/src/pass.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
use crate::{Fold, FoldWith};
use serde::export::PhantomData;
use std::borrow::Cow;

pub trait CompilerPass {
/// Name should follow hyphen-case
///
/// TODO: timing
fn name() -> Cow<'static, str>;
}

pub trait Repeated: CompilerPass {
/// Should run again?
fn changed(&self) -> bool;

/// Reset.
fn reset(&mut self);
}

pub trait RepeatedPass<At>: Repeated + CompilerPass {}

impl<T, P> RepeatedPass<T> for P where P: CompilerPass + Repeated {}

#[derive(Debug, Copy, Clone)]
pub struct Repeat<P, At>
where
P: RepeatedPass<At>,
{
pass: P,
at: PhantomData<At>,
}

impl<P, At> Repeat<P, At>
where
P: RepeatedPass<At>,
{
pub fn new(pass: P) -> Self {
Self {
pass,
at: PhantomData,
}
}
}

impl<P, At> CompilerPass for Repeat<P, At>
where
P: RepeatedPass<At>,
{
fn name() -> Cow<'static, str> {
format!("Repeat({})", P::name()).into()
}
}

impl<P, At> Repeated for Repeat<P, At>
where
P: RepeatedPass<At>,
{
fn changed(&self) -> bool {
self.pass.changed()
}

fn reset(&mut self) {
self.pass.reset()
}
}

#[cfg(feature = "fold")]
impl<P, At> Fold<At> for Repeat<P, At>
where
At: FoldWith<Self> + FoldWith<P>,
P: RepeatedPass<At>,
{
fn fold(&mut self, mut node: At) -> At {
loop {
self.pass.reset();
node = node.fold_with(&mut self.pass);

if !self.pass.changed() {
break;
}
}

node
}
}
2 changes: 1 addition & 1 deletion ecmascript/parser/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ swc_ecma_ast = { version = "0.17.0", path ="../ast" }
swc_ecma_parser_macros = { version = "0.4", path ="./macros" }
enum_kind = { version = "0.2", path ="../../macros/enum_kind" }
unicode-xid = "0.2"
log = { version = "0.4", features = ["release_max_level_debug"] }
log = "0.4"
either = { version = "1.4" }
serde = { version = "1", features = ["derive"] }
smallvec = "1"
Expand Down
1 change: 1 addition & 0 deletions ecmascript/transforms/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ arrayvec = "0.5.1"
serde_json = "1"
smallvec = "1"
is-macro = "0.1"
log = "0.4.8"

[dev-dependencies]
testing = { version = "0.5", path ="../../testing" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ pub(super) struct CaseHandler<'a> {
listing_len: usize,

/// A sparse array whose keys correspond to locations in this.listing
/// that have been marked as branch/jump targets.
/// that have been marked as stmt/jump targets.
marked: Vec<Loc>,

leaps: LeapManager,
Expand Down
31 changes: 31 additions & 0 deletions ecmascript/transforms/src/fixer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,24 @@ impl Fold<Stmt> for Fixer {
}
}

impl Fold<IfStmt> for Fixer {
fn fold(&mut self, node: IfStmt) -> IfStmt {
let node: IfStmt = node.fold_children(self);

match *node.cons {
Stmt::If(..) => IfStmt {
cons: box Stmt::Block(BlockStmt {
span: node.cons.span(),
stmts: vec![*node.cons],
}),
..node
},

_ => node,
}
}
}

macro_rules! context_fn_args {
($T:tt, $is_new:expr) => {
impl Fold<$T> for Fixer {
Expand Down Expand Up @@ -510,6 +528,17 @@ impl Fold<Expr> for Fixer {
}

e @ Expr::Seq(..)
| e @ Expr::Update(..)
| e
@
Expr::Unary(UnaryExpr {
op: op!("delete"), ..
})
| e
@
Expr::Unary(UnaryExpr {
op: op!("void"), ..
})
| e @ Expr::Yield(..)
| e @ Expr::Cond(..)
| e @ Expr::Assign(..)
Expand Down Expand Up @@ -1039,4 +1068,6 @@ var store = global[SHARED] || (global[SHARED] = {});
foo: 1
});"
);

test_fixer!(void_and_bin, "(void 0) * 2", "(void 0) * 2");
}
8 changes: 2 additions & 6 deletions ecmascript/transforms/src/optimization.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
pub use self::{
inline_globals::InlineGlobals,
json_parse::JsonParse,
simplify::{expr_simplifier, simplifier},
};
pub use self::{inline_globals::InlineGlobals, json_parse::JsonParse, simplify::simplifier};

mod inline_globals;
mod json_parse;
mod simplify;
pub mod simplify;
30 changes: 0 additions & 30 deletions ecmascript/transforms/src/optimization/simplify.rs

This file was deleted.

Loading

0 comments on commit 348052b

Please sign in to comment.