forked from libre-chip/fayalite
simplify_enums: cache folded expressions
This commit is contained in:
parent
6902aea3a6
commit
b1116c4a1a
1 changed files with 27 additions and 10 deletions
|
|
@ -96,6 +96,7 @@ enum EnumTypeState {
|
||||||
|
|
||||||
struct ModuleState {
|
struct ModuleState {
|
||||||
module_name: NameId,
|
module_name: NameId,
|
||||||
|
expr_cache: HashMap<ExprEnum, ExprEnum>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModuleState {
|
impl ModuleState {
|
||||||
|
|
@ -675,6 +676,7 @@ impl Folder for State {
|
||||||
fn fold_module<T: BundleType>(&mut self, v: Module<T>) -> Result<Module<T>, Self::Error> {
|
fn fold_module<T: BundleType>(&mut self, v: Module<T>) -> Result<Module<T>, Self::Error> {
|
||||||
self.module_state_stack.push(ModuleState {
|
self.module_state_stack.push(ModuleState {
|
||||||
module_name: v.name_id(),
|
module_name: v.name_id(),
|
||||||
|
expr_cache: HashMap::default(),
|
||||||
});
|
});
|
||||||
let retval = Fold::default_fold(v, self);
|
let retval = Fold::default_fold(v, self);
|
||||||
self.module_state_stack.pop();
|
self.module_state_stack.pop();
|
||||||
|
|
@ -682,30 +684,39 @@ impl Folder for State {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_expr_enum(&mut self, op: ExprEnum) -> Result<ExprEnum, Self::Error> {
|
fn fold_expr_enum(&mut self, op: ExprEnum) -> Result<ExprEnum, Self::Error> {
|
||||||
match op {
|
if let Some(folded_op) = self
|
||||||
|
.module_state_stack
|
||||||
|
.last()
|
||||||
|
.expect("known to be in module")
|
||||||
|
.expr_cache
|
||||||
|
.get(&op)
|
||||||
|
{
|
||||||
|
return Ok(*folded_op);
|
||||||
|
}
|
||||||
|
let folded_op = match op {
|
||||||
ExprEnum::EnumLiteral(op) => {
|
ExprEnum::EnumLiteral(op) => {
|
||||||
let folded_variant_value = op.variant_value().map(|v| v.fold(self)).transpose()?;
|
let folded_variant_value = op.variant_value().map(|v| v.fold(self)).transpose()?;
|
||||||
Ok(*Expr::expr_enum(self.handle_enum_literal(
|
*Expr::expr_enum(self.handle_enum_literal(
|
||||||
op.ty(),
|
op.ty(),
|
||||||
op.variant_index(),
|
op.variant_index(),
|
||||||
folded_variant_value,
|
folded_variant_value,
|
||||||
)?))
|
)?)
|
||||||
}
|
}
|
||||||
ExprEnum::VariantAccess(op) => {
|
ExprEnum::VariantAccess(op) => {
|
||||||
let folded_base_expr = Expr::canonical(op.base()).fold(self)?;
|
let folded_base_expr = Expr::canonical(op.base()).fold(self)?;
|
||||||
Ok(*Expr::expr_enum(self.handle_variant_access(
|
*Expr::expr_enum(self.handle_variant_access(
|
||||||
op.base().ty(),
|
op.base().ty(),
|
||||||
folded_base_expr,
|
folded_base_expr,
|
||||||
op.variant_index(),
|
op.variant_index(),
|
||||||
)?))
|
)?)
|
||||||
}
|
}
|
||||||
ExprEnum::MemPort(mem_port) => Ok(
|
ExprEnum::MemPort(mem_port) => {
|
||||||
if let Some(&wire) = self.replacement_mem_ports.get(&mem_port) {
|
if let Some(&wire) = self.replacement_mem_ports.get(&mem_port) {
|
||||||
ExprEnum::Wire(wire)
|
ExprEnum::Wire(wire)
|
||||||
} else {
|
} else {
|
||||||
ExprEnum::MemPort(mem_port.fold(self)?)
|
ExprEnum::MemPort(mem_port.fold(self)?)
|
||||||
},
|
}
|
||||||
),
|
}
|
||||||
ExprEnum::UIntLiteral(_)
|
ExprEnum::UIntLiteral(_)
|
||||||
| ExprEnum::SIntLiteral(_)
|
| ExprEnum::SIntLiteral(_)
|
||||||
| ExprEnum::BoolLiteral(_)
|
| ExprEnum::BoolLiteral(_)
|
||||||
|
|
@ -813,8 +824,14 @@ impl Folder for State {
|
||||||
| ExprEnum::Wire(_)
|
| ExprEnum::Wire(_)
|
||||||
| ExprEnum::Reg(_)
|
| ExprEnum::Reg(_)
|
||||||
| ExprEnum::RegSync(_)
|
| ExprEnum::RegSync(_)
|
||||||
| ExprEnum::RegAsync(_) => op.default_fold(self),
|
| ExprEnum::RegAsync(_) => op.default_fold(self)?,
|
||||||
}
|
};
|
||||||
|
self.module_state_stack
|
||||||
|
.last_mut()
|
||||||
|
.expect("known to be in module")
|
||||||
|
.expr_cache
|
||||||
|
.insert(op, folded_op);
|
||||||
|
Ok(folded_op)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_block(&mut self, block: Block) -> Result<Block, Self::Error> {
|
fn fold_block(&mut self, block: Block) -> Result<Block, Self::Error> {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue