optimize: dedup consts
This commit is contained in:
40
src/ir.rs
40
src/ir.rs
@@ -112,7 +112,7 @@ ir! {
|
||||
With => { namespace: Box<Ir>, expr: Box<Ir> },
|
||||
Assert => { assertion: Box<Ir>, expr: Box<Ir> },
|
||||
ConcatStrings => { parts: Vec<Ir> },
|
||||
Const => { value: i::Const },
|
||||
Const => { idx: usize },
|
||||
Var => { sym: usize },
|
||||
#[derive(Copy)]
|
||||
Thunk => { idx: usize },
|
||||
@@ -127,6 +127,7 @@ pub struct DowngradeContext {
|
||||
thunks: Vec<Ir>,
|
||||
funcs: Vec<Func>,
|
||||
consts: Vec<i::Const>,
|
||||
constmap: HashMap<i::Const, usize>,
|
||||
symbols: Vec<EcoString>,
|
||||
symmap: HashMap<EcoString, usize>,
|
||||
}
|
||||
@@ -157,6 +158,16 @@ impl DowngradeContext {
|
||||
LoadFunc { idx }
|
||||
}
|
||||
|
||||
fn new_const(&mut self, cnst: i::Const) -> Const {
|
||||
if let Some(&idx) = self.constmap.get(&cnst) {
|
||||
Const { idx }
|
||||
} else {
|
||||
self.constmap.insert(cnst.clone(), self.consts.len());
|
||||
self.consts.push(cnst);
|
||||
Const { idx: self.consts.len() - 1 }
|
||||
}
|
||||
}
|
||||
|
||||
fn new_sym(&mut self, sym: impl Into<EcoString>) -> usize {
|
||||
let sym = sym.into();
|
||||
if let Some(&idx) = self.symmap.get(&sym) {
|
||||
@@ -414,9 +425,7 @@ impl Downgrade for ast::Path {
|
||||
let parts = self
|
||||
.parts()
|
||||
.map(|part| match part {
|
||||
ast::InterpolPart::Literal(lit) => Const {
|
||||
value: lit.to_string().into(),
|
||||
}
|
||||
ast::InterpolPart::Literal(lit) => ctx.new_const(lit.to_string().into())
|
||||
.ir()
|
||||
.ok(),
|
||||
ast::InterpolPart::Interpolation(interpol) => {
|
||||
@@ -444,7 +453,7 @@ impl Downgrade for ast::Str {
|
||||
.normalized_parts()
|
||||
.into_iter()
|
||||
.map(|part| match part {
|
||||
ast::InterpolPart::Literal(lit) => Const { value: lit.into() }.ir().ok(),
|
||||
ast::InterpolPart::Literal(lit) => ctx.new_const(lit.into()).ir().ok(),
|
||||
ast::InterpolPart::Interpolation(interpol) => {
|
||||
interpol.expr().unwrap().downgrade(ctx)
|
||||
}
|
||||
@@ -459,17 +468,11 @@ impl Downgrade for ast::Str {
|
||||
}
|
||||
|
||||
impl Downgrade for ast::Literal {
|
||||
fn downgrade(self, _ctx: &mut DowngradeContext) -> Result<Ir> {
|
||||
fn downgrade(self, ctx: &mut DowngradeContext) -> Result<Ir> {
|
||||
match self.kind() {
|
||||
ast::LiteralKind::Integer(int) => Const {
|
||||
value: int.value().unwrap().into(),
|
||||
},
|
||||
ast::LiteralKind::Float(float) => Const {
|
||||
value: float.value().unwrap().into(),
|
||||
},
|
||||
ast::LiteralKind::Uri(uri) => Const {
|
||||
value: uri.to_string().into(),
|
||||
},
|
||||
ast::LiteralKind::Integer(int) => ctx.new_const(int.value().unwrap().into()),
|
||||
ast::LiteralKind::Float(float) => ctx.new_const(float.value().unwrap().into()),
|
||||
ast::LiteralKind::Uri(uri) => ctx.new_const(uri.to_string().into())
|
||||
}
|
||||
.ir()
|
||||
.ok()
|
||||
@@ -519,11 +522,6 @@ impl Downgrade for ast::HasAttr {
|
||||
fn downgrade(self, ctx: &mut DowngradeContext) -> Result<Ir> {
|
||||
let attrs = self.expr().unwrap().downgrade(ctx)?;
|
||||
let path = downgrade_attrpath(self.attrpath().unwrap(), ctx)?;
|
||||
if let Some(attrs) = Downcast::<Attrs>::downcast_ref(&attrs) {
|
||||
if let Some(res) = attrs.has_attr(&path) {
|
||||
return Const { value: res.into() }.ir().ok();
|
||||
}
|
||||
}
|
||||
HasAttr {
|
||||
lhs: attrs.boxed(),
|
||||
rhs: path,
|
||||
@@ -730,7 +728,7 @@ fn downgrade_attr(attr: ast::Attr, ctx: &mut DowngradeContext) -> Result<Attr> {
|
||||
let parts = parts
|
||||
.into_iter()
|
||||
.map(|part| match part {
|
||||
Literal(lit) => Const { value: lit.into() }.ir().ok(),
|
||||
Literal(lit) => ctx.new_const(lit.into()).ir().ok(),
|
||||
Interpolation(interpol) => interpol.expr().unwrap().downgrade(ctx),
|
||||
})
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
|
||||
Reference in New Issue
Block a user