Skip to content

Commit

Permalink
Remove ConstArrayAccess variant on InstantiatedWireReference
Browse files Browse the repository at this point in the history
  • Loading branch information
VonTum committed Jun 2, 2024
1 parent d6527f2 commit 073b634
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 44 deletions.
10 changes: 2 additions & 8 deletions src/codegen_fallback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,10 @@ impl<'g, 'out, Stream : std::fmt::Write> CodeGenerationContext<'g, 'out, Stream>
let mut result = String::new();
for path_elem in path {
result.push_str(&match path_elem {
RealWirePathElem::MuxArrayWrite{span:_, idx_wire} => {
RealWirePathElem::ArrayAccess{span:_, idx_wire} => {
let idx_wire_name = self.wire_name(*idx_wire, absolute_latency);
format!("[{idx_wire_name}]")
}
RealWirePathElem::ConstArrayWrite{span:_, idx} => {
format!("[{}]", idx)
}
});
}
result
Expand Down Expand Up @@ -131,12 +128,9 @@ impl<'g, 'out, Stream : std::fmt::Write> CodeGenerationContext<'g, 'out, Stream>
write!(self.program_text, " = {}", self.wire_name(*root, w.absolute_latency))?;
for pe in path {
match pe {
RealWirePathElem::MuxArrayWrite { span:_, idx_wire } => {
RealWirePathElem::ArrayAccess { span:_, idx_wire } => {
write!(self.program_text, "[{}]", self.wire_name(*idx_wire, w.absolute_latency))?;
}
RealWirePathElem::ConstArrayWrite { span:_, idx } => {
write!(self.program_text, "[{}]", idx)?;
}
}
}
writeln!(self.program_text, ";")?;
Expand Down
49 changes: 18 additions & 31 deletions src/instantiation/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,18 @@ macro_rules! caught_by_typecheck {

pub type ExecutionResult<T> = Result<T, (Span, String)>;

fn write_gen_variable<'t, 'p>(mut target : &'t mut Value, conn_path : &'p [RealWirePathElem], to_write : Value) -> ExecutionResult<()> {
fn write_gen_variable<'t, 'p>(mut target : &'t mut Value, conn_path : &'p [RealWirePathElem], to_write : Value, wires : &FlatAlloc<RealWire, WireIDMarker>) -> ExecutionResult<()> {
for elem in conn_path {
match elem {
RealWirePathElem::ConstArrayWrite{span, idx} => {
RealWirePathElem::ArrayAccess{span, idx_wire} => {
let idx = wires[*idx_wire].source.unwrap_constant_integer(); // Caught by typecheck
let Value::Array(a_box) = target else {caught_by_typecheck!("Non-array")};
let array_len = a_box.len();
let Some(tt) = usize::try_from(idx).ok().and_then(|pos| a_box.get_mut(pos)) else {
return Err((span.inner_span(), format!("Index {idx} is out of bounds for this array of size {}", array_len)))
};
target = tt
}
RealWirePathElem::MuxArrayWrite {span:_, idx_wire:_ } => {
caught_by_typecheck!("Non-generative array access");
}
}
}
*target = to_write;
Expand All @@ -56,7 +54,6 @@ struct InstantiatedWireRef {
root : RealWireRefRoot,
path : Vec<RealWirePathElem>
}

impl<'fl, 'l> InstantiationContext<'fl, 'l> {
fn span_of(&self, v : FlatID) -> Span {
self.md.instructions[v].unwrap_wire().span
Expand Down Expand Up @@ -131,28 +128,16 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
InstantiatedWireRef{root, path : Vec::new()}
}

fn instantiate_wire_ref(&self, wire_ref : &WireReference) -> InstantiatedWireRef {
fn instantiate_wire_ref(&mut self, wire_ref : &WireReference) -> InstantiatedWireRef {
// Later on, potentially allow module arrays
let mut result = self.realize_wire_ref_root(&wire_ref.root);

for v in &wire_ref.path {
match v {
&WireReferencePathElement::ArrayIdx{idx, bracket_span} => {
match &self.generation_state[idx] {
SubModuleOrWire::SubModule(_) => unreachable!(),
SubModuleOrWire::Unnasigned => unreachable!(),
&SubModuleOrWire::Wire(idx_wire) => {
assert!(self.wires[idx_wire].typ == INT_CONCRETE_TYPE);

result.path.push(RealWirePathElem::MuxArrayWrite{ span:bracket_span, idx_wire});
}
SubModuleOrWire::CompileTimeValue(cv) => {
result.path.push(RealWirePathElem::ConstArrayWrite{
idx : cv.value.unwrap_integer().clone(),
span : bracket_span
});
}
}
let idx_wire = self.get_wire_or_constant_as_wire(idx);
assert_eq!(self.wires[idx_wire].typ, INT_CONCRETE_TYPE, "Caught by typecheck");
result.path.push(RealWirePathElem::ArrayAccess{ span:bracket_span, idx_wire});
}
}
}
Expand Down Expand Up @@ -185,7 +170,7 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
let found_v = self.generation_state[conn_from].unwrap_generation_value().clone();

let SubModuleOrWire::CompileTimeValue(v_writable) = &mut self.generation_state[*decl_id] else {caught_by_typecheck!()};
write_gen_variable(&mut v_writable.value, &wire_ref_inst.path, found_v.value)?;
write_gen_variable(&mut v_writable.value, &wire_ref_inst.path, found_v.value, &self.wires)?;
}
RealWireRefRoot::Constant(_) => {
caught_by_typecheck!("Cannot assign to constants!")
Expand All @@ -195,8 +180,12 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
WriteModifiers::Initial{initial_kw_span : _} => {
let found_v = self.get_generation_value(conn_from)?.clone();

let RealWireDataSource::Multiplexer{is_state : Some(initial_value), sources : _} = &mut self.wires[wire_ref_inst.root.unwrap_wire()].source else {caught_by_typecheck!()};
write_gen_variable(initial_value, &wire_ref_inst.path, found_v.value)?;
let root_wire = wire_ref_inst.root.unwrap_wire();
let RealWireDataSource::Multiplexer{is_state : Some(initial_value), sources : _} = &mut self.wires[root_wire].source else {caught_by_typecheck!()};
let mut new_init_val = std::mem::replace(initial_value, Value::Error);
write_gen_variable(&mut new_init_val, &wire_ref_inst.path, found_v.value, &self.wires)?;
let RealWireDataSource::Multiplexer{is_state : Some(initial_value), sources : _} = &mut self.wires[root_wire].source else {caught_by_typecheck!()};
*initial_value = new_init_val;
}
}
Ok(())
Expand All @@ -216,19 +205,17 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {

for path_elem in &wire_ref_inst.path {
work_on_value = match path_elem {
RealWirePathElem::ConstArrayWrite { span, idx } => {
RealWirePathElem::ArrayAccess { span, idx_wire } => {
let idx = self.wires[*idx_wire].source.unwrap_constant_integer();

array_access(&work_on_value, &idx, *span)?
}
RealWirePathElem::MuxArrayWrite { span, idx_wire:_ } => {
span.outer_span().debug();
caught_by_typecheck!("Write to a non-generative wire at compiletime.")
}
}
}

Ok(work_on_value)
}
fn compute_compile_time(&self, wire_inst : &WireInstance) -> ExecutionResult<TypedValue> {
fn compute_compile_time(&mut self, wire_inst : &WireInstance) -> ExecutionResult<TypedValue> {
Ok(match &wire_inst.source {
WireSource::WireRef(wire_ref) => {
let wire_ref_instance = self.instantiate_wire_ref(wire_ref);
Expand Down
19 changes: 15 additions & 4 deletions src/instantiation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,16 @@ pub struct ConnectFrom {

#[derive(Debug)]
pub enum RealWirePathElem {
MuxArrayWrite{span : BracketSpan, idx_wire : WireID},
ConstArrayWrite{span : BracketSpan, idx : BigInt}
ArrayAccess{span : BracketSpan, idx_wire : WireID},
}

impl RealWirePathElem {
fn for_each_wire_in_path<F : FnMut(WireID)>(path : &[RealWirePathElem], mut f : F) {
for v in path {
match v {
RealWirePathElem::MuxArrayWrite { span:_, idx_wire } => {
RealWirePathElem::ArrayAccess { span:_, idx_wire } => {
f(*idx_wire);
}
RealWirePathElem::ConstArrayWrite { span:_, idx:_ } => {}
}
}
}
Expand All @@ -71,6 +69,19 @@ pub enum RealWireDataSource {
Constant{value : Value}
}

impl RealWireDataSource {
#[track_caller]
pub fn unwrap_constant(&self) -> &Value {
let Self::Constant { value } = self else {unreachable!()};
value
}
#[track_caller]
pub fn unwrap_constant_integer(&self) -> &BigInt {
let Self::Constant { value : Value::Integer(v)} = self else {unreachable!()};
v
}
}

#[derive(Debug)]
pub struct RealWire {
pub source : RealWireDataSource,
Expand Down
2 changes: 1 addition & 1 deletion src/instantiation/typecheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
fn walk_type_along_path(&self, mut cur_typ : ConcreteType, path : &[RealWirePathElem]) -> ConcreteType {
for p in path {
match p {
RealWirePathElem::MuxArrayWrite { span:_, idx_wire:_ } | RealWirePathElem::ConstArrayWrite { span:_, idx:_ } => {
RealWirePathElem::ArrayAccess { span:_, idx_wire:_ } => {
cur_typ = cur_typ.down_array().clone();
}
}
Expand Down

0 comments on commit 073b634

Please sign in to comment.