diff --git a/xls/codegen_v_1_5/pipeline_register_insertion_pass_test.cc b/xls/codegen_v_1_5/pipeline_register_insertion_pass_test.cc index 38b3038462..326798e685 100644 --- a/xls/codegen_v_1_5/pipeline_register_insertion_pass_test.cc +++ b/xls/codegen_v_1_5/pipeline_register_insertion_pass_test.cc @@ -434,7 +434,6 @@ TEST_F(PipelineRegisterInsertionPassTest, TestCombinedRegisters) { XLS_ASSERT_OK_AND_ASSIGN(Node * source_acc, source->AppendStateElement( "acc", Value(UBits(0, 32)))); BValue acc = sbb.SourceNode(source_acc); - sbb.AddStateReadToCurrentStage(acc); BValue v0 = sbb.Add(x, acc, SourceInfo(), "v0"); sbb.EndStage(sbb.Literal(UBits(1, 1)), sbb.Literal(UBits(1, 1))); @@ -474,7 +473,6 @@ TEST_F(PipelineRegisterInsertionPassTest, TestRegistersDontCombine) { XLS_ASSERT_OK_AND_ASSIGN(Node * source_acc, source->AppendStateElement( "acc", Value(UBits(0, 32)))); BValue acc = sbb.SourceNode(source_acc); - sbb.AddStateReadToCurrentStage(acc); BValue v0 = sbb.Add(x, acc, SourceInfo(), "v0"); sbb.EndStage(sbb.Literal(UBits(1, 1)), sbb.Literal(UBits(1, 1))); @@ -516,7 +514,6 @@ TEST_F(PipelineRegisterInsertionPassTest, TestCombinedRegistersWithState) { XLS_ASSERT_OK_AND_ASSIGN(Node * source_acc, source->AppendStateElement( "acc", Value(UBits(0, 32)))); BValue acc = sbb.SourceNode(source_acc); - sbb.AddStateReadToCurrentStage(acc); sbb.EndStage(sbb.Literal(UBits(1, 1)), sbb.Literal(UBits(1, 1))); // Stage 1 @@ -573,7 +570,6 @@ TEST_F(PipelineRegisterInsertionPassTest, XLS_ASSERT_OK_AND_ASSIGN(Node * source_acc, source->AppendStateElement( "acc", Value(UBits(0, 32)))); BValue acc = sbb.SourceNode(source_acc); - sbb.AddStateReadToCurrentStage(acc); BValue v0 = sbb.Add(x, acc, SourceInfo(), "v0"); sbb.EndStage(sbb.Literal(UBits(1, 1)), sbb.Literal(UBits(1, 1))); @@ -633,7 +629,6 @@ TEST_F(PipelineRegisterInsertionPassTest, XLS_ASSERT_OK_AND_ASSIGN(Node * source_acc, source->AppendStateElement( "acc", Value(UBits(0, 32)))); BValue acc = sbb.SourceNode(source_acc); - sbb.AddStateReadToCurrentStage(acc); BValue v0 = sbb.Add(x, acc, SourceInfo(), "v0"); sbb.EndStage(sbb.Literal(UBits(1, 1)), sbb.Literal(UBits(1, 1))); @@ -642,7 +637,6 @@ TEST_F(PipelineRegisterInsertionPassTest, XLS_ASSERT_OK_AND_ASSIGN( Node * source_z, source->AppendStateElement("z", Value(UBits(0, 32)))); BValue z = sbb.SourceNode(source_z); - sbb.AddStateReadToCurrentStage(z); sbb.EndStage(sbb.Literal(UBits(1, 1)), sbb.Literal(UBits(1, 1))); // Stage 2 - ends mutex region 1 @@ -700,7 +694,6 @@ TEST_F(PipelineRegisterInsertionPassTest, XLS_ASSERT_OK_AND_ASSIGN(Node * source_acc, source->AppendStateElement( "acc", Value(UBits(0, 32)))); BValue acc = sbb.SourceNode(source_acc); - sbb.AddStateReadToCurrentStage(acc); BValue v0 = sbb.Add(x, acc, SourceInfo(), "v0"); sbb.EndStage(sbb.Literal(UBits(1, 1)), sbb.Literal(UBits(1, 1))); @@ -713,7 +706,6 @@ TEST_F(PipelineRegisterInsertionPassTest, XLS_ASSERT_OK_AND_ASSIGN( Node * source_z, source->AppendStateElement("z", Value(UBits(0, 32)))); BValue z = sbb.SourceNode(source_z); - sbb.AddStateReadToCurrentStage(z); sbb.Next(acc, v0); sbb.EndStage(sbb.Literal(UBits(1, 1)), sbb.Literal(UBits(1, 1))); @@ -767,7 +759,6 @@ TEST_F(PipelineRegisterInsertionPassTest, XLS_ASSERT_OK_AND_ASSIGN(Node * source_acc, source->AppendStateElement( "acc", Value(UBits(0, 32)))); BValue acc = sbb.SourceNode(source_acc); - sbb.AddStateReadToCurrentStage(acc); BValue v0 = sbb.Add(x, acc, SourceInfo(), "v0"); sbb.EndStage(sbb.Literal(UBits(1, 1)), sbb.Literal(UBits(1, 1))); @@ -785,7 +776,6 @@ TEST_F(PipelineRegisterInsertionPassTest, XLS_ASSERT_OK_AND_ASSIGN( Node * source_z, source->AppendStateElement("z", Value(UBits(0, 32)))); BValue z = sbb.SourceNode(source_z); - sbb.AddStateReadToCurrentStage(z); sbb.EndStage(sbb.Literal(UBits(1, 1)), sbb.Literal(UBits(1, 1))); // Stage 4 @@ -838,8 +828,6 @@ TEST_F(PipelineRegisterInsertionPassTest, Node * source_z, source->AppendStateElement("z", Value(UBits(0, 32)))); BValue acc = sbb.SourceNode(source_acc); BValue z = sbb.SourceNode(source_z); - sbb.AddStateReadToCurrentStage(acc); - sbb.AddStateReadToCurrentStage(z); BValue next_acc = sbb.Add(x, acc, SourceInfo(), "next_acc"); sbb.Next(acc, next_acc); sbb.EndStage(sbb.Literal(UBits(1, 1)), sbb.Literal(UBits(1, 1))); @@ -894,7 +882,6 @@ TEST_F(PipelineRegisterInsertionPassTest, XLS_ASSERT_OK_AND_ASSIGN(StateRead * source_read, source->AddStateRead(source_se)); BValue acc = sbb.SourceNode(source_read); - sbb.AddStateReadToCurrentStage(acc); BValue v0 = sbb.Add(x, acc, SourceInfo(), "v0"); sbb.EndStage(sbb.Literal(UBits(1, 1)), sbb.Literal(UBits(1, 1))); diff --git a/xls/codegen_v_1_5/state_to_register_io_lowering_pass.cc b/xls/codegen_v_1_5/state_to_register_io_lowering_pass.cc index 3cdef65ab9..436086d79e 100644 --- a/xls/codegen_v_1_5/state_to_register_io_lowering_pass.cc +++ b/xls/codegen_v_1_5/state_to_register_io_lowering_pass.cc @@ -73,6 +73,7 @@ absl::StatusOr ReplaceNode(Block* block, Node* old_node, Node* new_node, if (old_node->Is()) { XLS_RETURN_IF_ERROR(block->RemoveNodeFromStage(old_node).status()); + XLS_RETURN_IF_ERROR(old_node->function_base()->RemoveNode(old_node)); return false; } if (old_node->IsDead()) { diff --git a/xls/codegen_v_1_5/testdata/scheduled_block_conversion_pass_test_SimpleProcWithGlobalChannels.ir b/xls/codegen_v_1_5/testdata/scheduled_block_conversion_pass_test_SimpleProcWithGlobalChannels.ir index e692c6c2fe..e16ae395db 100644 --- a/xls/codegen_v_1_5/testdata/scheduled_block_conversion_pass_test_SimpleProcWithGlobalChannels.ir +++ b/xls/codegen_v_1_5/testdata/scheduled_block_conversion_pass_test_SimpleProcWithGlobalChannels.ir @@ -9,10 +9,10 @@ top scheduled_block __test__P_0_next(clk: clock, rst: bits[1]) { source proc __test__P_0_next__src(__state: bits[32], init={0}) { } literal.3: bits[1] = literal(value=1, id=3) - stage_inputs_valid_0: bits[1] = literal(value=1, id=19) - stage_outputs_ready_0: bits[1] = literal(value=1, id=20) + stage_inputs_valid_0: bits[1] = literal(value=1, id=20) + stage_outputs_ready_0: bits[1] = literal(value=1, id=21) controlled_stage(stage_inputs_valid_0, stage_outputs_ready_0) { - active_inputs_valid active_inputs_valid_0: bits[1] = literal(value=1, id=21) + active_inputs_valid active_inputs_valid_0: bits[1] = literal(value=1, id=22) after_all.4: token = after_all(id=4) receive.5: (token, bits[32]) = receive(after_all.4, predicate=literal.3, channel=test__a, id=5) tok: token = tuple_index(receive.5, index=0, id=7) @@ -21,17 +21,17 @@ top scheduled_block __test__P_0_next(clk: clock, rst: bits[1]) { tok__1: token = tuple_index(receive.9, index=0, id=11) b_value: bits[32] = tuple_index(receive.9, index=1, id=12) umul.13: bits[32] = umul(a_value, b_value, id=13) - ret stage_outputs_valid_0: bits[1] = and(stage_inputs_valid_0, active_inputs_valid_0, id=22) + ret stage_outputs_valid_0: bits[1] = and(stage_inputs_valid_0, active_inputs_valid_0, id=23) } - stage_inputs_valid_1: bits[1] = literal(value=1, id=23) - stage_outputs_ready_1: bits[1] = literal(value=1, id=24) + stage_inputs_valid_1: bits[1] = literal(value=1, id=24) + stage_outputs_ready_1: bits[1] = literal(value=1, id=25) controlled_stage(stage_inputs_valid_1, stage_outputs_ready_1) { - active_inputs_valid active_inputs_valid_1: bits[1] = literal(value=1, id=25) - __state: bits[32] = state_read(state_element=__state, id=2) - result_value: bits[32] = add(umul.13, __state, id=14) + active_inputs_valid active_inputs_valid_1: bits[1] = literal(value=1, id=26) + __state__1: bits[32] = state_read(state_element=__state, id=2) + result_value: bits[32] = add(umul.13, __state__1, id=14) send.15: token = send(tok__1, result_value, predicate=literal.3, channel=test__result, id=15) next_value.16: () = next_value(state_element=__state, value=result_value, id=16) - ret stage_outputs_valid_1: bits[1] = and(stage_inputs_valid_1, active_inputs_valid_1, id=26) + ret stage_outputs_valid_1: bits[1] = and(stage_inputs_valid_1, active_inputs_valid_1, id=27) } - rst: bits[1] = input_port(name=rst, id=18) + rst: bits[1] = input_port(name=rst, id=19) } diff --git a/xls/codegen_v_1_5/testdata/scheduled_block_conversion_pass_test_SimpleProcWithProcScopedChannels.ir b/xls/codegen_v_1_5/testdata/scheduled_block_conversion_pass_test_SimpleProcWithProcScopedChannels.ir index 4d539c6f46..338c2ab54e 100644 --- a/xls/codegen_v_1_5/testdata/scheduled_block_conversion_pass_test_SimpleProcWithProcScopedChannels.ir +++ b/xls/codegen_v_1_5/testdata/scheduled_block_conversion_pass_test_SimpleProcWithProcScopedChannels.ir @@ -8,10 +8,10 @@ top scheduled_block __test__P_0_next(clk: clock, rst: bits[1]) { chan_interface result(direction=send, kind=streaming, strictness=proven_mutually_exclusive, flow_control=ready_valid, flop_kind=none) } literal.3: bits[1] = literal(value=1, id=3) - stage_inputs_valid_0: bits[1] = literal(value=1, id=20) - stage_outputs_ready_0: bits[1] = literal(value=1, id=21) + stage_inputs_valid_0: bits[1] = literal(value=1, id=21) + stage_outputs_ready_0: bits[1] = literal(value=1, id=22) controlled_stage(stage_inputs_valid_0, stage_outputs_ready_0) { - active_inputs_valid active_inputs_valid_0: bits[1] = literal(value=1, id=22) + active_inputs_valid active_inputs_valid_0: bits[1] = literal(value=1, id=23) after_all.5: token = after_all(id=5) receive.6: (token, bits[32]) = receive(after_all.5, predicate=literal.3, channel=a, id=6) tok: token = tuple_index(receive.6, index=0, id=8) @@ -20,17 +20,17 @@ top scheduled_block __test__P_0_next(clk: clock, rst: bits[1]) { tok__1: token = tuple_index(receive.10, index=0, id=12) b_value: bits[32] = tuple_index(receive.10, index=1, id=13) umul.14: bits[32] = umul(a_value, b_value, id=14) - ret stage_outputs_valid_0: bits[1] = and(stage_inputs_valid_0, active_inputs_valid_0, id=23) + ret stage_outputs_valid_0: bits[1] = and(stage_inputs_valid_0, active_inputs_valid_0, id=24) } - stage_inputs_valid_1: bits[1] = literal(value=1, id=24) - stage_outputs_ready_1: bits[1] = literal(value=1, id=25) + stage_inputs_valid_1: bits[1] = literal(value=1, id=25) + stage_outputs_ready_1: bits[1] = literal(value=1, id=26) controlled_stage(stage_inputs_valid_1, stage_outputs_ready_1) { - active_inputs_valid active_inputs_valid_1: bits[1] = literal(value=1, id=26) - __state: bits[32] = state_read(state_element=__state, id=2) - result_value: bits[32] = add(umul.14, __state, id=15) + active_inputs_valid active_inputs_valid_1: bits[1] = literal(value=1, id=27) + __state__1: bits[32] = state_read(state_element=__state, id=2) + result_value: bits[32] = add(umul.14, __state__1, id=15) send.16: token = send(tok__1, result_value, predicate=literal.3, channel=result, id=16) next_value.17: () = next_value(state_element=__state, value=result_value, id=17) - ret stage_outputs_valid_1: bits[1] = and(stage_inputs_valid_1, active_inputs_valid_1, id=27) + ret stage_outputs_valid_1: bits[1] = and(stage_inputs_valid_1, active_inputs_valid_1, id=28) } - rst: bits[1] = input_port(name=rst, id=19) + rst: bits[1] = input_port(name=rst, id=20) } diff --git a/xls/codegen_v_1_5/testdata/scheduled_block_conversion_pass_test_SimpleProcWithoutReset.ir b/xls/codegen_v_1_5/testdata/scheduled_block_conversion_pass_test_SimpleProcWithoutReset.ir index b13c9ceab9..8b84dad4bc 100644 --- a/xls/codegen_v_1_5/testdata/scheduled_block_conversion_pass_test_SimpleProcWithoutReset.ir +++ b/xls/codegen_v_1_5/testdata/scheduled_block_conversion_pass_test_SimpleProcWithoutReset.ir @@ -7,10 +7,10 @@ top scheduled_block __test__P_0_next(clk: clock) { chan_interface result(direction=send, kind=streaming, strictness=proven_mutually_exclusive, flow_control=ready_valid, flop_kind=none) } literal.3: bits[1] = literal(value=1, id=3) - stage_inputs_valid_0: bits[1] = literal(value=1, id=19) - stage_outputs_ready_0: bits[1] = literal(value=1, id=20) + stage_inputs_valid_0: bits[1] = literal(value=1, id=20) + stage_outputs_ready_0: bits[1] = literal(value=1, id=21) controlled_stage(stage_inputs_valid_0, stage_outputs_ready_0) { - active_inputs_valid active_inputs_valid_0: bits[1] = literal(value=1, id=21) + active_inputs_valid active_inputs_valid_0: bits[1] = literal(value=1, id=22) after_all.5: token = after_all(id=5) receive.6: (token, bits[32]) = receive(after_all.5, predicate=literal.3, channel=a, id=6) tok: token = tuple_index(receive.6, index=0, id=8) @@ -19,16 +19,16 @@ top scheduled_block __test__P_0_next(clk: clock) { tok__1: token = tuple_index(receive.10, index=0, id=12) b_value: bits[32] = tuple_index(receive.10, index=1, id=13) umul.14: bits[32] = umul(a_value, b_value, id=14) - ret stage_outputs_valid_0: bits[1] = and(stage_inputs_valid_0, active_inputs_valid_0, id=22) + ret stage_outputs_valid_0: bits[1] = and(stage_inputs_valid_0, active_inputs_valid_0, id=23) } - stage_inputs_valid_1: bits[1] = literal(value=1, id=23) - stage_outputs_ready_1: bits[1] = literal(value=1, id=24) + stage_inputs_valid_1: bits[1] = literal(value=1, id=24) + stage_outputs_ready_1: bits[1] = literal(value=1, id=25) controlled_stage(stage_inputs_valid_1, stage_outputs_ready_1) { - active_inputs_valid active_inputs_valid_1: bits[1] = literal(value=1, id=25) - __state: bits[32] = state_read(state_element=__state, id=2) - result_value: bits[32] = add(umul.14, __state, id=15) + active_inputs_valid active_inputs_valid_1: bits[1] = literal(value=1, id=26) + __state__1: bits[32] = state_read(state_element=__state, id=2) + result_value: bits[32] = add(umul.14, __state__1, id=15) send.16: token = send(tok__1, result_value, predicate=literal.3, channel=result, id=16) next_value.17: () = next_value(state_element=__state, value=result_value, id=17) - ret stage_outputs_valid_1: bits[1] = and(stage_inputs_valid_1, active_inputs_valid_1, id=26) + ret stage_outputs_valid_1: bits[1] = and(stage_inputs_valid_1, active_inputs_valid_1, id=27) } } diff --git a/xls/codegen_v_1_5/testdata/scheduling_pass_test_MultiProcWithOneProcScheduled.ir b/xls/codegen_v_1_5/testdata/scheduling_pass_test_MultiProcWithOneProcScheduled.ir index af67e04869..69ec2541f5 100644 --- a/xls/codegen_v_1_5/testdata/scheduling_pass_test_MultiProcWithOneProcScheduled.ir +++ b/xls/codegen_v_1_5/testdata/scheduling_pass_test_MultiProcWithOneProcScheduled.ir @@ -17,8 +17,8 @@ top scheduled_proc __test__P_0_next(__state: bits[32], init={0}) { umul.13: bits[32] = umul(a_value, b_value, id=13) } stage { - __state: bits[32] = state_read(state_element=__state, id=2) - result_value: bits[32] = add(umul.13, __state, id=14) + __state__1: bits[32] = state_read(state_element=__state, id=2) + result_value: bits[32] = add(umul.13, __state__1, id=14) send.15: token = send(tok__1, result_value, predicate=literal.3, channel=test__result, id=15) next_value.16: () = next_value(state_element=__state, value=result_value, id=16) } diff --git a/xls/codegen_v_1_5/testdata/scheduling_pass_test_SimpleProcWithGlobalChannels.ir b/xls/codegen_v_1_5/testdata/scheduling_pass_test_SimpleProcWithGlobalChannels.ir index af67e04869..69ec2541f5 100644 --- a/xls/codegen_v_1_5/testdata/scheduling_pass_test_SimpleProcWithGlobalChannels.ir +++ b/xls/codegen_v_1_5/testdata/scheduling_pass_test_SimpleProcWithGlobalChannels.ir @@ -17,8 +17,8 @@ top scheduled_proc __test__P_0_next(__state: bits[32], init={0}) { umul.13: bits[32] = umul(a_value, b_value, id=13) } stage { - __state: bits[32] = state_read(state_element=__state, id=2) - result_value: bits[32] = add(umul.13, __state, id=14) + __state__1: bits[32] = state_read(state_element=__state, id=2) + result_value: bits[32] = add(umul.13, __state__1, id=14) send.15: token = send(tok__1, result_value, predicate=literal.3, channel=test__result, id=15) next_value.16: () = next_value(state_element=__state, value=result_value, id=16) } diff --git a/xls/codegen_v_1_5/testdata/scheduling_pass_test_SimpleProcWithProcScopedChannels.ir b/xls/codegen_v_1_5/testdata/scheduling_pass_test_SimpleProcWithProcScopedChannels.ir index 9c74f9b385..9a2fb6ed76 100644 --- a/xls/codegen_v_1_5/testdata/scheduling_pass_test_SimpleProcWithProcScopedChannels.ir +++ b/xls/codegen_v_1_5/testdata/scheduling_pass_test_SimpleProcWithProcScopedChannels.ir @@ -16,8 +16,8 @@ top scheduled_proc __test__P_0_next RemoveDeadParameters(FunctionBase* f) { if (f->IsProc()) { Proc* p = f->AsProcOrDie(); absl::flat_hash_set dead_state_elements; - absl::flat_hash_set invariant_state_elements( - p->StateElements().begin(), p->StateElements().end()); + absl::flat_hash_set invariant_state_elements; + for (StateElement* se : p->StateElements()) { + if (p->GetStateReadsByStateElement(se).empty()) { + dead_state_elements.insert(se); + } else { + invariant_state_elements.insert(se); + } + } + for (Next* next : p->next_values()) { - if (next->value() != - p->GetStateReadByStateElement(next->state_element())) { - // This state param is not actually invariant. + if (dead_state_elements.contains(next->state_element())) { + continue; + } + absl::Span reads = + p->GetStateReadsByStateElement(next->state_element()); + if (!absl::c_linear_search(reads, next->value())) { invariant_state_elements.erase(next->state_element()); } } + + // 1. Remove next values for all dead and invariant state elements. + std::vector next_values(p->next_values().begin(), + p->next_values().end()); + for (Next* next : next_values) { + if (dead_state_elements.contains(next->state_element()) || + invariant_state_elements.contains(next->state_element())) { + XLS_RETURN_IF_ERROR(p->RemoveNode(next)); + } + } + + // 2. Replace uses of reads for invariant state elements. for (StateElement* invariant : invariant_state_elements) { - // Replace all uses of invariant state elements (i.e.: ones where - // next[i] == param[i]) with a literal of the initial value. Value init_value = invariant->initial_value(); - Node* state_read = p->GetStateReadByStateElement(invariant); - absl::btree_set next_values = - p->next_values(invariant); - for (Next* next : next_values) { - XLS_RETURN_IF_ERROR(p->RemoveNode(next)); + for (StateRead* read : p->GetStateReadsByStateElement(invariant)) { + XLS_RETURN_IF_ERROR( + read->ReplaceUsesWithNew(init_value).status()); } - XLS_RETURN_IF_ERROR( - state_read->ReplaceUsesWithNew(init_value).status()); dead_state_elements.insert(invariant); } + // 3. Remove the state elements themselves. bool changed = false; for (StateElement* dead : dead_state_elements) { XLS_ASSIGN_OR_RETURN(int64_t index, p->GetStateElementIndex(dead)); diff --git a/xls/dev_tools/ir_minimizer_main_test.py b/xls/dev_tools/ir_minimizer_main_test.py index c45adaa8bf..fe573c20ef 100644 --- a/xls/dev_tools/ir_minimizer_main_test.py +++ b/xls/dev_tools/ir_minimizer_main_test.py @@ -732,6 +732,36 @@ def test_new_style_proc(self): encoding='utf-8', ) + def test_proc_multiple_reads(self): + input_ir = """package foo + +top proc foo(x: bits[32], init={42}) { + chan_interface input(direction=receive, kind=streaming, strictness=proven_mutually_exclusive) + chan_interface output(direction=send, kind=streaming, strictness=proven_mutually_exclusive) + tkn: token = literal(value=token, id=1000) + read1: bits[32] = state_read(state_element=x) + read2: bits[32] = state_read(state_element=x) + receive.1: (token, bits[32]) = receive(tkn, channel=input) + tuple_index.2: bits[32] = tuple_index(receive.1, index=1) + add: bits[32] = add(read1, read2) + send.3: token = send(tkn, add, channel=output) + next_value.4: () = next_value(state_element=x, value=tuple_index.2) +} +""" + ir_file = self.create_tempfile(content=input_ir) + test_sh_file = self.create_tempfile() + self._write_sh_script(test_sh_file.full_path, [r'/usr/bin/env']) # = true + # The minimizer should not crash. + subprocess.check_output( + [ + IR_MINIMIZER_MAIN_PATH, + '--test_executable=' + test_sh_file.full_path, + '--can_remove_params', + ir_file.full_path, + ], + encoding='utf-8', + ) + def test_verify_return_code(self): # If the test script never successfully runs, then ir_minimizer_main should # return nonzero. diff --git a/xls/interpreter/testdata/serial_proc_runtime_test_ExplicitStateAccessMultipleBranchingLabeledReads.ir b/xls/interpreter/testdata/serial_proc_runtime_test_ExplicitStateAccessMultipleBranchingLabeledReads.ir index b03953f7c9..3e0c8dd724 100644 --- a/xls/interpreter/testdata/serial_proc_runtime_test_ExplicitStateAccessMultipleBranchingLabeledReads.ir +++ b/xls/interpreter/testdata/serial_proc_runtime_test_ExplicitStateAccessMultipleBranchingLabeledReads.ir @@ -21,15 +21,15 @@ top proc __test_module__main_0_next<>(__val: bits[32], __switch: bits[1], init={ or.22: bits[1] = or(not.20, not.21, id=22) not.31: bits[1] = not(and.30, id=31) or.26: bits[1] = or(and.6, and.19, id=26) - __val: bits[32] = state_read(state_element=__val, predicate=and.6, label="EvenRead", id=7) - __val__1: bits[32] = state_read(state_element=__val, predicate=and.19, label="OddRead", id=24) + __val__1: bits[32] = state_read(state_element=__val, predicate=and.6, label="EvenRead", id=7) + __val__2: bits[32] = state_read(state_element=__val, predicate=and.19, label="OddRead", id=24) assert.23: token = assert(assert.14, or.22, message="State element read after read in same activation.", id=23) or.32: bits[1] = or(not.31, or.26, id=32) not.34: bits[1] = not(and.30, id=34) not.35: bits[1] = not(and.11, id=35) - even: bits[32] = identity(__val, id=8) + even: bits[32] = identity(__val__1, id=8) literal.9: bits[32] = literal(value=1, id=9) - odd: bits[32] = identity(__val__1, id=25) + odd: bits[32] = identity(__val__2, id=25) literal.27: bits[32] = literal(value=1, id=27) assert.33: token = assert(assert.23, or.32, message="State element written before read in same activation.", id=33) or.36: bits[1] = or(not.34, not.35, id=36) diff --git a/xls/interpreter/testdata/serial_proc_runtime_test_ExplicitStateAccessMultipleReads.ir b/xls/interpreter/testdata/serial_proc_runtime_test_ExplicitStateAccessMultipleReads.ir index b795e7659b..b286faaf73 100644 --- a/xls/interpreter/testdata/serial_proc_runtime_test_ExplicitStateAccessMultipleReads.ir +++ b/xls/interpreter/testdata/serial_proc_runtime_test_ExplicitStateAccessMultipleReads.ir @@ -6,14 +6,14 @@ top proc __test_module__main_0_next<>(__state: bits[32], init={0}) { literal.2: bits[1] = literal(value=1, id=2) not.6: bits[1] = not(literal.2, id=6) not.7: bits[1] = not(literal.2, id=7) - __state: bits[32] = state_read(state_element=__state, predicate=literal.2, id=4) + __state__1: bits[32] = state_read(state_element=__state, predicate=literal.2, id=4) __token: token = literal(value=token, id=1) or.8: bits[1] = or(not.6, not.7, id=8) - __state__1: bits[32] = state_read(state_element=__state, predicate=literal.2, id=10) + __state__2: bits[32] = state_read(state_element=__state, predicate=literal.2, id=10) tuple.3: () = tuple(id=3) - first: bits[32] = identity(__state, id=5) + first: bits[32] = identity(__state__1, id=5) assert.9: token = assert(__token, or.8, message="State element read after read in same activation.", id=9) - second: bits[32] = identity(__state__1, id=11) + second: bits[32] = identity(__state__2, id=11) or.12: bits[1] = or(literal.2, literal.2, id=12) tuple.13: () = tuple(id=13) } diff --git a/xls/interpreter/testdata/serial_proc_runtime_test_ExplicitStateAccessMultipleStatesMultipleReads.ir b/xls/interpreter/testdata/serial_proc_runtime_test_ExplicitStateAccessMultipleStatesMultipleReads.ir index 71d30c116a..692a7d53cf 100644 --- a/xls/interpreter/testdata/serial_proc_runtime_test_ExplicitStateAccessMultipleStatesMultipleReads.ir +++ b/xls/interpreter/testdata/serial_proc_runtime_test_ExplicitStateAccessMultipleStatesMultipleReads.ir @@ -6,14 +6,14 @@ top proc __test_module__main_0_next<>(__state_0: bits[32], __state_1: bits[32], literal.2: bits[1] = literal(value=1, id=2) not.6: bits[1] = not(literal.2, id=6) not.7: bits[1] = not(literal.2, id=7) - __state_1: bits[32] = state_read(state_element=__state_1, predicate=literal.2, id=4) + __state_1__1: bits[32] = state_read(state_element=__state_1, predicate=literal.2, id=4) __token: token = literal(value=token, id=1) or.8: bits[1] = or(not.6, not.7, id=8) - __state_1__1: bits[32] = state_read(state_element=__state_1, predicate=literal.2, id=10) + __state_1__2: bits[32] = state_read(state_element=__state_1, predicate=literal.2, id=10) tuple.3: () = tuple(id=3) - b_0: bits[32] = identity(__state_1, id=5) + b_0: bits[32] = identity(__state_1__1, id=5) assert.9: token = assert(__token, or.8, message="State element read after read in same activation.", id=9) - b_1: bits[32] = identity(__state_1__1, id=11) + b_1: bits[32] = identity(__state_1__2, id=11) or.12: bits[1] = or(literal.2, literal.2, id=12) tuple.13: () = tuple(id=13) } diff --git a/xls/ir/ir_parser.cc b/xls/ir/ir_parser.cc index 49df0a8278..3f4605d6b7 100644 --- a/xls/ir/ir_parser.cc +++ b/xls/ir/ir_parser.cc @@ -829,27 +829,50 @@ absl::StatusOr Parser::ParseNode( break; } case Op::kStateRead: { - IdentifierString* state_name = + IdentifierString* state_element_name = arg_parser.AddKeywordArg("state_element"); std::optional* predicate = arg_parser.AddOptionalKeywordArg("predicate"); std::optional* label = arg_parser.AddOptionalKeywordArg("label"); XLS_ASSIGN_OR_RETURN(operands, arg_parser.Run(/*arity=*/0)); - auto it = name_to_value->find(state_name->value); - if (it == name_to_value->end()) { - return absl::InvalidArgumentError( - absl::StrFormat("Referred to state name that hadn't yet been " - "defined: %s @ %s", - state_name->value, op_token.pos().ToHumanString())); + XLS_ASSIGN_OR_RETURN( + Proc * proc, GetEffectiveProcOrError( + fb, "state_read operations only supported in procs", + op_token.pos())); + std::optional state_element = + proc->MaybeGetStateElementByName(state_element_name->value); + if (!state_element.has_value()) { + return absl::InvalidArgumentError(absl::StrFormat( + "Referred to state_element name that hadn't yet been " + "defined: %s @ %s", + state_element_name->value, op_token.pos().ToHumanString())); } - bvalue = it->second; - if (predicate->has_value()) { - XLS_RETURN_IF_ERROR( - bvalue.node()->As()->SetPredicate((*predicate)->node())); + + // If an implicit state read already exists, delete it. + auto it = name_to_value->find(state_element_name->value); + if (it != name_to_value->end()) { + Node* old_read = it->second.node(); + name_to_value->erase(it); + XLS_RETURN_IF_ERROR(old_read->function_base()->RemoveNode(old_read)); } - if (label->has_value()) { - bvalue.node()->As()->set_label(label->value().value); + + if (auto* pb = dynamic_cast(fb)) { + bvalue = pb->StateRead(BStateElement(*state_element, pb), *predicate, + label->has_value() + ? std::make_optional(label->value().value) + : std::nullopt, + *loc); + } else if (auto* sbb = dynamic_cast(fb)) { + bvalue = sbb->StateRead(BStateElement(*state_element), *predicate, + label->has_value() + ? std::make_optional(label->value().value) + : std::nullopt, + *loc); + } + + if (!node_name.empty()) { + bvalue.SetName(node_name); } break; } @@ -1934,16 +1957,13 @@ absl::StatusOr Parser::ParseBody( XLS_ASSIGN_OR_RETURN( Proc * source_proc, ParseProc(package, /*outer_attributes=*/{}, &source)); - for (StateElement* element : source_proc->StateElements()) { - absl::Span reads = - source_proc->GetStateReadsByStateElement(element); - // TODO: (nelsonliang) Make this work for multiple reads of the same - // state element. This will require populating `name_to_value` with - // entries for each `StateRead` node (keyed by node name) rather than - // one entry per state element (keyed by state element name). - XLS_RET_CHECK_EQ(reads.size(), 1); - name_to_value->emplace(element->name(), - bb->SourceNode(reads.front())); + // TODO: Clean this up once we require explicit StateRead + // nodes, since they'll added to name_to_value when the IR is parsed. + for (Node* node : source_proc->nodes()) { + if (node->Is()) { + StateRead* read = node->As(); + name_to_value->emplace(read->GetName(), bb->SourceNode(read)); + } } } else { return absl::InvalidArgumentError(absl::StrFormat( @@ -3545,11 +3565,7 @@ absl::Status Parser::ParseControlledStage( } XLS_ASSIGN_OR_RETURN(BValue result, ParseNode(builder, name_to_value)); (*name_to_value)[result.node()->GetName()] = result; - if (result.node()->Is()) { - // State reads are not created the way normal nodes are, so we need to - // force this. - builder->AddStateReadToCurrentStage(result); - } + if (is_active_inputs_valid) { if (active_inputs_valid.has_value()) { return absl::InvalidArgumentError(absl::StrFormat( diff --git a/xls/ir/ir_parser.h b/xls/ir/ir_parser.h index 8416ec7f2c..109973efdc 100644 --- a/xls/ir/ir_parser.h +++ b/xls/ir/ir_parser.h @@ -33,6 +33,7 @@ #include #include "absl/container/flat_hash_map.h" +#include "absl/container/flat_hash_set.h" #include "absl/status/status.h" #include "absl/status/statusor.h" #include "absl/strings/str_format.h" diff --git a/xls/ir/ir_parser_test.cc b/xls/ir/ir_parser_test.cc index 0da72e07b4..bbf3b47efc 100644 --- a/xls/ir/ir_parser_test.cc +++ b/xls/ir/ir_parser_test.cc @@ -176,6 +176,30 @@ TEST(IrParserTest, ParseSingleEmptyPackageNamedKeywords) { } } +TEST(IrParserTest, ProcWithMultipleReadsOfSameStateElement) { + std::string program = R"( +package test_module + +proc foo(__state: bits[32], __cond: bits[1], init={0, 1}) { + cond: bits[1] = state_read(state_element=__cond) + not_cond: bits[1] = not(cond) + __state_1: bits[32] = state_read(state_element=__state, predicate=cond) + __state_2: bits[32] = state_read(state_element=__state, predicate=not_cond) + next_value.1: () = next_value(state_element=__state, value=__state_1, predicate=cond) + next_value.2: () = next_value(state_element=__state, value=__state_2, predicate=not_cond) + next_value.3: () = next_value(state_element=__cond, value=not_cond) +} + +)"; + XLS_ASSERT_OK_AND_ASSIGN(auto package, Parser::ParsePackage(program)); + XLS_ASSERT_OK_AND_ASSIGN(Proc * proc, package->GetProc("foo")); + EXPECT_EQ(proc->GetStateElementCount(), 2); + XLS_ASSERT_OK_AND_ASSIGN(StateElement * state, + proc->GetStateElementByName("__state")); + absl::Span reads = proc->GetStateReadsByStateElement(state); + EXPECT_EQ(reads.size(), 2); +} + TEST(IrParserTest, ParseSingleFunctionPackage) { std::string input = R"(package SingleFunctionPackage @@ -1232,6 +1256,28 @@ scheduled_block b() { EXPECT_EQ(block->stages().size(), 0); } +TEST(IrParserTest, ScheduledBlockWithMultipleStateReads) { + const std::string input = R"(package test +scheduled_block b() { + source proc foo(__state: bits[32], init={0}) { + } + iv0: bits[1] = literal(value=1, id=1) + or0: bits[1] = literal(value=1, id=2) + controlled_stage(iv0, or0) { + active_inputs_valid aiv0: bits[1] = literal(value=1, id=3) + __state_1: bits[32] = state_read(state_element=__state, id=4) + __state_2: bits[32] = state_read(state_element=__state, id=5) + sum: bits[32] = add(__state_1, __state_2, id=6) + ret ov0: bits[1] = identity(aiv0, id=7) + } +} +)"; + XLS_ASSERT_OK_AND_ASSIGN(std::unique_ptr pkg, + Parser::ParsePackage(input)); + XLS_ASSERT_OK_AND_ASSIGN(Block * block, pkg->GetBlock("b")); + EXPECT_TRUE(block->IsScheduled()); +} + TEST(IrParserTest, ScheduledBlockWithEmptyStage) { const std::string input = R"(package test scheduled_block b() { diff --git a/xls/ir/proc.cc b/xls/ir/proc.cc index c18cd5324d..7194dc368f 100644 --- a/xls/ir/proc.cc +++ b/xls/ir/proc.cc @@ -214,18 +214,19 @@ absl::Status Proc::RemoveStateElement(int64_t index) { StateElement* old_state_element = GetStateElement(index); auto old_state_read_it = state_reads_.find(old_state_element); - XLS_RET_CHECK(old_state_read_it != state_reads_.end()); - for (StateRead* read : old_state_read_it->second) { - if (!read->users().empty()) { - return absl::InvalidArgumentError( - absl::StrFormat("Cannot remove state element %d of proc %s, existing " - "state read %s has uses", - index, name(), read->GetNameView())); + if (old_state_read_it != state_reads_.end()) { + for (StateRead* read : old_state_read_it->second) { + if (!read->users().empty()) { + return absl::InvalidArgumentError(absl::StrFormat( + "Cannot remove state element %d of proc %s, existing " + "state read %s has uses", + index, name(), read->GetNameView())); + } + XLS_RETURN_IF_ERROR(FunctionBase::RemoveNode(read)); } - XLS_RETURN_IF_ERROR(RemoveNode(read)); + // TODO(allight): This should ideally not need to be done manually. + state_reads_.erase(old_state_read_it); } - // TODO(allight): This should ideally not need to be done manually. - state_reads_.erase(old_state_read_it); state_elements_.erase(old_state_element->name()); state_vec_.erase(state_vec_.begin() + index); @@ -238,7 +239,7 @@ absl::Status Proc::RemoveAllStateElements() { for (const auto& [elem, reads] : state_reads_) { for (StateRead* read : reads) { if (read != nullptr) { - XLS_RETURN_IF_ERROR(RemoveNode(read)) + XLS_RETURN_IF_ERROR(FunctionBase::RemoveNode(read)) << "Cannot remove " << elem->ToString() << " of proc " << name() << " because read '" << read->ToString() << "' could not be removed."; @@ -1094,4 +1095,22 @@ void Proc::MoveNonLogicFrom(Proc& other) { channel_vec_ = std::move(other.channel_vec_); } +absl::Status Proc::RemoveNode(Node* n) { + if (n->Is()) { + StateRead* read = n->As(); + auto it = state_reads_.find(read->state_element()); + if (it != state_reads_.end()) { + std::vector& reads = it->second; + auto read_it = std::find(reads.begin(), reads.end(), read); + if (read_it != reads.end()) { + reads.erase(read_it); + } + if (reads.empty()) { + state_reads_.erase(it); + } + } + } + return FunctionBase::RemoveNode(n); +} + } // namespace xls diff --git a/xls/ir/proc.h b/xls/ir/proc.h index c47a25b77b..33036c1d8d 100644 --- a/xls/ir/proc.h +++ b/xls/ir/proc.h @@ -270,6 +270,8 @@ class Proc : public FunctionBase { bool HasImplicitUse(Node* node) const override; + absl::Status RemoveNode(Node* n) override; + // Creates a clone of the proc with the new name `new_name`. Proc is // owned by `target_package`. `channel_remapping` dictates how to map channel // names to new channel names in the cloned version; if a key is unavailable diff --git a/xls/ir/scheduled_builder.cc b/xls/ir/scheduled_builder.cc index 7659f8e2f7..fb79e4232b 100644 --- a/xls/ir/scheduled_builder.cc +++ b/xls/ir/scheduled_builder.cc @@ -15,6 +15,8 @@ #include "xls/ir/scheduled_builder.h" #include +#include +#include #include #include "absl/algorithm/container.h" @@ -35,6 +37,7 @@ #include "xls/ir/nodes.h" #include "xls/ir/package.h" #include "xls/ir/proc.h" +#include "xls/ir/source_location.h" #include "xls/ir/verifier.h" namespace xls { @@ -231,4 +234,42 @@ void ScheduledBlockBuilder::SetSourceReturnValue(Node* return_value) { source_fn->set_return_type(return_value->GetType()); } +BValue ScheduledBlockBuilder::StateRead(BStateElement state_element, + std::optional predicate, + std::optional label, + const SourceInfo& loc) { + if (ErrorPending()) { + return BValue(); + } + if (!state_element.valid()) { + return BValue(); + } + ScheduledBlock* sb = block(); + if (sb->source() == nullptr || !sb->source()->IsProc()) { + return SetError("Block has no proc source for StateRead", loc); + } + Proc* proc = absl::down_cast(sb->source()); + absl::StatusOr se_or_status = + proc->GetStateElementByName(state_element.state_element()->name()); + if (!se_or_status.ok() || + se_or_status.value() != state_element.state_element()) { + return SetError( + absl::StrFormat("State element %s does not belong to the source proc", + state_element.state_element()->name()), + loc); + } + absl::StatusOr state_read = + function()->MakeNodeWithName( + loc, state_element.state_element(), + predicate.has_value() ? std::make_optional(predicate->node()) + : std::nullopt, + label, state_element.state_element()->name()); + if (!state_read.ok()) { + return SetError(absl::StrFormat("Unable to add state read: %s", + state_read.status().message()), + loc); + } + return CreateBValue(*state_read, loc); +} + } // namespace xls diff --git a/xls/ir/scheduled_builder.h b/xls/ir/scheduled_builder.h index 749c2641aa..ffc159f31d 100644 --- a/xls/ir/scheduled_builder.h +++ b/xls/ir/scheduled_builder.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -31,6 +32,7 @@ #include "xls/ir/function_builder.h" #include "xls/ir/package.h" #include "xls/ir/proc.h" +#include "xls/ir/source_location.h" namespace xls { @@ -175,11 +177,10 @@ class ScheduledBlockBuilder : public BlockBuilder { // avoid forward referencing in IR text. void SetSourceReturnValue(Node* return_value); - // Indicates that the given state read should be considered part of the - // current stage. State reads are created stageless by default. - void AddStateReadToCurrentStage(BValue state_read) { - current_stage_nodes_.push_back(state_read.node()); - } + BValue StateRead(BStateElement state_element, + std::optional predicate = std::nullopt, + std::optional label = std::nullopt, + const SourceInfo& loc = SourceInfo()); protected: void OnNodeAdded(Node* node) override; diff --git a/xls/ir/testdata/ir_parser_round_trip_test_ParseIIProc.ir b/xls/ir/testdata/ir_parser_round_trip_test_ParseIIProc.ir index f6e67655d5..bba9c48ce3 100644 --- a/xls/ir/testdata/ir_parser_round_trip_test_ParseIIProc.ir +++ b/xls/ir/testdata/ir_parser_round_trip_test_ParseIIProc.ir @@ -2,6 +2,6 @@ package test #[initiation_interval(12)] top proc example(tkn: token, init={token}) { - tkn: token = state_read(state_element=tkn, id=2) - next_value.3: () = next_value(state_element=tkn, value=tkn, id=3) + tkn__1: token = state_read(state_element=tkn, id=2) + next_value.3: () = next_value(state_element=tkn, value=tkn__1, id=3) } diff --git a/xls/ir/testdata/ir_parser_round_trip_test_ParseInstantiatedProc.ir b/xls/ir/testdata/ir_parser_round_trip_test_ParseInstantiatedProc.ir index 5cf051db14..230411e888 100644 --- a/xls/ir/testdata/ir_parser_round_trip_test_ParseInstantiatedProc.ir +++ b/xls/ir/testdata/ir_parser_round_trip_test_ParseInstantiatedProc.ir @@ -3,14 +3,14 @@ package test proc my_proc(my_token: token, my_state: bits[32], init={token, 42}) { chan_interface in_ch(direction=receive, kind=single_value, strictness=proven_mutually_exclusive, flow_control=none, flop_kind=none) chan_interface out_ch(direction=send, kind=streaming, flow_control=ready_valid, flop_kind=skid) - my_token: token = state_read(state_element=my_token, id=9) - my_state: bits[32] = state_read(state_element=my_state, id=10) - send.1: token = send(my_token, my_state, channel=out_ch, id=1) + my_token__1: token = state_read(state_element=my_token, id=9) + my_state__1: bits[32] = state_read(state_element=my_state, id=10) + send.1: token = send(my_token__1, my_state__1, channel=out_ch, id=1) literal.2: bits[1] = literal(value=1, id=2) receive.3: (token, bits[32]) = receive(send.1, predicate=literal.2, channel=in_ch, id=3) tuple_index.4: token = tuple_index(receive.3, index=0, id=4) next_value.15: () = next_value(state_element=my_token, value=tuple_index.4, id=15) - next_value.16: () = next_value(state_element=my_state, value=my_state, id=16) + next_value.16: () = next_value(state_element=my_state, value=my_state__1, id=16) } proc other_proc<>(my_token: token, my_state: bits[32], init={token, 42}) { @@ -21,8 +21,8 @@ proc other_proc<>(my_token: token, my_state: bits[32], init={token, 42}) { chan_interface ch_b(direction=send, kind=streaming, flow_control=ready_valid, flop_kind=none) chan_interface ch_b(direction=receive, kind=streaming, flow_control=ready_valid, flop_kind=skid) proc_instantiation foo(ch_a, ch_b, proc=my_proc) - my_token: token = state_read(state_element=my_token, id=11) - my_state: bits[32] = state_read(state_element=my_state, id=12) - next_value.19: () = next_value(state_element=my_token, value=my_token, id=19) - next_value.20: () = next_value(state_element=my_state, value=my_state, id=20) + my_token__1: token = state_read(state_element=my_token, id=11) + my_state__1: bits[32] = state_read(state_element=my_state, id=12) + next_value.19: () = next_value(state_element=my_token, value=my_token__1, id=19) + next_value.20: () = next_value(state_element=my_state, value=my_state__1, id=20) } diff --git a/xls/ir/testdata/ir_parser_round_trip_test_ParseInstantiatedProcWithZeroArgs.ir b/xls/ir/testdata/ir_parser_round_trip_test_ParseInstantiatedProcWithZeroArgs.ir index 877d4fab9f..0a6a8751c9 100644 --- a/xls/ir/testdata/ir_parser_round_trip_test_ParseInstantiatedProcWithZeroArgs.ir +++ b/xls/ir/testdata/ir_parser_round_trip_test_ParseInstantiatedProcWithZeroArgs.ir @@ -1,16 +1,16 @@ package test proc my_proc<>(my_token: token, my_state: bits[32], init={token, 42}) { - my_token: token = state_read(state_element=my_token, id=5) - my_state: bits[32] = state_read(state_element=my_state, id=6) - next_value.7: () = next_value(state_element=my_token, value=my_token, id=7) - next_value.8: () = next_value(state_element=my_state, value=my_state, id=8) + my_token__1: token = state_read(state_element=my_token, id=5) + my_state__1: bits[32] = state_read(state_element=my_state, id=6) + next_value.7: () = next_value(state_element=my_token, value=my_token__1, id=7) + next_value.8: () = next_value(state_element=my_state, value=my_state__1, id=8) } proc other_proc<>(my_token: token, my_state: bits[32], init={token, 42}) { proc_instantiation foo(proc=my_proc) - my_token: token = state_read(state_element=my_token, id=9) - my_state: bits[32] = state_read(state_element=my_state, id=10) - next_value.11: () = next_value(state_element=my_token, value=my_token, id=11) - next_value.12: () = next_value(state_element=my_state, value=my_state, id=12) + my_token__1: token = state_read(state_element=my_token, id=9) + my_state__1: bits[32] = state_read(state_element=my_state, id=10) + next_value.11: () = next_value(state_element=my_token, value=my_token__1, id=11) + next_value.12: () = next_value(state_element=my_state, value=my_state__1, id=12) } diff --git a/xls/ir/testdata/ir_parser_round_trip_test_ParseInstantiationWithChannel.ir b/xls/ir/testdata/ir_parser_round_trip_test_ParseInstantiationWithChannel.ir index 91f1857427..27e8c856af 100644 --- a/xls/ir/testdata/ir_parser_round_trip_test_ParseInstantiationWithChannel.ir +++ b/xls/ir/testdata/ir_parser_round_trip_test_ParseInstantiationWithChannel.ir @@ -3,8 +3,8 @@ package test chan foo(bits[32], id=42, kind=streaming, ops=send_receive, flow_control=none, strictness=proven_mutually_exclusive, fifo_depth=0, bypass=true, register_push_outputs=false, register_pop_outputs=false) proc placeholder_channel_user(tok: token, init={token}) { - tok: token = state_read(state_element=tok, id=13) - recv_out: (token, bits[32]) = receive(tok, channel=foo, id=1) + tok__1: token = state_read(state_element=tok, id=13) + recv_out: (token, bits[32]) = receive(tok__1, channel=foo, id=1) recv_tok: token = tuple_index(recv_out, index=0, id=2) recv_data: bits[32] = tuple_index(recv_out, index=1, id=3) send_out: token = send(recv_tok, recv_data, channel=foo, id=4) diff --git a/xls/ir/testdata/ir_parser_round_trip_test_ParseInstantiationWithNoBypassChannel.ir b/xls/ir/testdata/ir_parser_round_trip_test_ParseInstantiationWithNoBypassChannel.ir index d16e2b7753..1f0c515b19 100644 --- a/xls/ir/testdata/ir_parser_round_trip_test_ParseInstantiationWithNoBypassChannel.ir +++ b/xls/ir/testdata/ir_parser_round_trip_test_ParseInstantiationWithNoBypassChannel.ir @@ -3,8 +3,8 @@ package test chan foo(bits[32], id=42, kind=streaming, ops=send_receive, flow_control=none, strictness=proven_mutually_exclusive, fifo_depth=1, bypass=false, register_push_outputs=true, register_pop_outputs=true) proc placeholder_channel_user(tok: token, init={token}) { - tok: token = state_read(state_element=tok, id=13) - recv_out: (token, bits[32]) = receive(tok, channel=foo, id=1) + tok__1: token = state_read(state_element=tok, id=13) + recv_out: (token, bits[32]) = receive(tok__1, channel=foo, id=1) recv_tok: token = tuple_index(recv_out, index=0, id=2) recv_data: bits[32] = tuple_index(recv_out, index=1, id=3) send_out: token = send(recv_tok, recv_data, channel=foo, id=4) diff --git a/xls/ir/testdata/ir_parser_round_trip_test_ParseNewStyleProc.ir b/xls/ir/testdata/ir_parser_round_trip_test_ParseNewStyleProc.ir index 10ff27e000..4d118f27a8 100644 --- a/xls/ir/testdata/ir_parser_round_trip_test_ParseNewStyleProc.ir +++ b/xls/ir/testdata/ir_parser_round_trip_test_ParseNewStyleProc.ir @@ -3,12 +3,12 @@ package test proc my_proc(my_token: token, my_state: bits[32], init={token, 42}) { chan_interface in_ch(direction=receive, kind=streaming, strictness=proven_mutually_exclusive, flow_control=none, flop_kind=none) chan_interface out_ch(direction=send, kind=streaming, flow_control=ready_valid, flop_kind=skid) - my_token: token = state_read(state_element=my_token, id=7) - my_state: bits[32] = state_read(state_element=my_state, id=8) - send.1: token = send(my_token, my_state, channel=out_ch, id=1) + my_token__1: token = state_read(state_element=my_token, id=7) + my_state__1: bits[32] = state_read(state_element=my_state, id=8) + send.1: token = send(my_token__1, my_state__1, channel=out_ch, id=1) literal.2: bits[1] = literal(value=1, id=2) receive.3: (token, bits[32]) = receive(send.1, predicate=literal.2, channel=in_ch, id=3) tuple_index.4: token = tuple_index(receive.3, index=0, id=4) next_value.13: () = next_value(state_element=my_token, value=tuple_index.4, id=13) - next_value.14: () = next_value(state_element=my_state, value=my_state, id=14) + next_value.14: () = next_value(state_element=my_state, value=my_state__1, id=14) } diff --git a/xls/ir/testdata/ir_parser_round_trip_test_ParseNewStyleProcNoInterfaceChannels.ir b/xls/ir/testdata/ir_parser_round_trip_test_ParseNewStyleProcNoInterfaceChannels.ir index 73f77436f2..2efcf7d0c4 100644 --- a/xls/ir/testdata/ir_parser_round_trip_test_ParseNewStyleProcNoInterfaceChannels.ir +++ b/xls/ir/testdata/ir_parser_round_trip_test_ParseNewStyleProcNoInterfaceChannels.ir @@ -1,8 +1,8 @@ package test proc my_proc<>(my_token: token, my_state: bits[32], init={token, 42}) { - my_token: token = state_read(state_element=my_token, id=3) - my_state: bits[32] = state_read(state_element=my_state, id=4) - next_value.5: () = next_value(state_element=my_token, value=my_token, id=5) - next_value.6: () = next_value(state_element=my_state, value=my_state, id=6) + my_token__1: token = state_read(state_element=my_token, id=3) + my_state__1: bits[32] = state_read(state_element=my_state, id=4) + next_value.5: () = next_value(state_element=my_token, value=my_token__1, id=5) + next_value.6: () = next_value(state_element=my_state, value=my_state__1, id=6) } diff --git a/xls/ir/testdata/ir_parser_round_trip_test_ParseNewStyleProcWithChannelDefinitions.ir b/xls/ir/testdata/ir_parser_round_trip_test_ParseNewStyleProcWithChannelDefinitions.ir index ef29124896..e017add27c 100644 --- a/xls/ir/testdata/ir_parser_round_trip_test_ParseNewStyleProcWithChannelDefinitions.ir +++ b/xls/ir/testdata/ir_parser_round_trip_test_ParseNewStyleProcWithChannelDefinitions.ir @@ -4,11 +4,11 @@ proc my_proc<>(my_token: token, my_state: bits[32], init={token, 42}) { chan ch(bits[32], id=0, kind=streaming, ops=send_receive, flow_control=none, strictness=proven_mutually_exclusive) chan_interface ch(direction=send, kind=streaming, flow_control=ready_valid, flop_kind=none) chan_interface ch(direction=receive, kind=streaming, flow_control=ready_valid, flop_kind=none) - my_token: token = state_read(state_element=my_token, id=6) - my_state: bits[32] = state_read(state_element=my_state, id=7) - send.1: token = send(my_token, my_state, channel=ch, id=1) + my_token__1: token = state_read(state_element=my_token, id=6) + my_state__1: bits[32] = state_read(state_element=my_state, id=7) + send.1: token = send(my_token__1, my_state__1, channel=ch, id=1) receive.2: (token, bits[32]) = receive(send.1, channel=ch, id=2) tuple_index.3: token = tuple_index(receive.2, index=0, id=3) next_value.11: () = next_value(state_element=my_token, value=tuple_index.3, id=11) - next_value.12: () = next_value(state_element=my_state, value=my_state, id=12) + next_value.12: () = next_value(state_element=my_state, value=my_state__1, id=12) } diff --git a/xls/ir/testdata/ir_parser_round_trip_test_ParseNewStyleProcWithComplexChannelTypes.ir b/xls/ir/testdata/ir_parser_round_trip_test_ParseNewStyleProcWithComplexChannelTypes.ir index 632c26c443..2f46bf9761 100644 --- a/xls/ir/testdata/ir_parser_round_trip_test_ParseNewStyleProcWithComplexChannelTypes.ir +++ b/xls/ir/testdata/ir_parser_round_trip_test_ParseNewStyleProcWithComplexChannelTypes.ir @@ -3,12 +3,12 @@ package test proc my_proc(my_token: token, my_state: ((), bits[32][1]), init={token, ((), [42])}) { chan_interface in_ch(direction=receive, kind=single_value, strictness=proven_mutually_exclusive, flow_control=none, flop_kind=none) chan_interface out_ch(direction=send, kind=streaming, flow_control=ready_valid, flop_kind=skid) - my_token: token = state_read(state_element=my_token, id=7) - my_state: ((), bits[32][1]) = state_read(state_element=my_state, id=8) - send.1: token = send(my_token, my_state, channel=out_ch, id=1) + my_token__1: token = state_read(state_element=my_token, id=7) + my_state__1: ((), bits[32][1]) = state_read(state_element=my_state, id=8) + send.1: token = send(my_token__1, my_state__1, channel=out_ch, id=1) literal.2: bits[1] = literal(value=1, id=2) receive.3: (token, ()) = receive(send.1, predicate=literal.2, channel=in_ch, id=3) tuple_index.4: token = tuple_index(receive.3, index=0, id=4) next_value.13: () = next_value(state_element=my_token, value=tuple_index.4, id=13) - next_value.14: () = next_value(state_element=my_state, value=my_state, id=14) + next_value.14: () = next_value(state_element=my_state, value=my_state__1, id=14) } diff --git a/xls/ir/testdata/ir_parser_round_trip_test_ParseProcWithExplicitNext.ir b/xls/ir/testdata/ir_parser_round_trip_test_ParseProcWithExplicitNext.ir index df5b47b9e7..8b4383f3a7 100644 --- a/xls/ir/testdata/ir_parser_round_trip_test_ParseProcWithExplicitNext.ir +++ b/xls/ir/testdata/ir_parser_round_trip_test_ParseProcWithExplicitNext.ir @@ -3,12 +3,12 @@ package test chan ch(bits[32], id=0, kind=streaming, ops=send_receive, flow_control=none, strictness=proven_mutually_exclusive) proc my_proc(my_token: token, my_state: bits[32], init={token, 42}) { - my_token: token = state_read(state_element=my_token, id=9) - my_state: bits[32] = state_read(state_element=my_state, id=10) - send.1: token = send(my_token, my_state, channel=ch, id=1) + my_token__1: token = state_read(state_element=my_token, id=9) + my_state__1: bits[32] = state_read(state_element=my_state, id=10) + send.1: token = send(my_token__1, my_state__1, channel=ch, id=1) literal.2: bits[1] = literal(value=1, id=2) receive.3: (token, bits[32]) = receive(send.1, predicate=literal.2, channel=ch, id=3) tuple_index.4: token = tuple_index(receive.3, index=0, id=4) next_value.5: () = next_value(state_element=my_token, value=tuple_index.4, id=5) - next_value.6: () = next_value(state_element=my_state, value=my_state, id=6) + next_value.6: () = next_value(state_element=my_state, value=my_state__1, id=6) } diff --git a/xls/ir/testdata/ir_parser_round_trip_test_ParseProcWithPredicatedStateRead.ir b/xls/ir/testdata/ir_parser_round_trip_test_ParseProcWithPredicatedStateRead.ir index 0583e15d06..5d305d6eef 100644 --- a/xls/ir/testdata/ir_parser_round_trip_test_ParseProcWithPredicatedStateRead.ir +++ b/xls/ir/testdata/ir_parser_round_trip_test_ParseProcWithPredicatedStateRead.ir @@ -3,14 +3,14 @@ package test chan ch(bits[32], id=0, kind=streaming, ops=send_receive, flow_control=none, strictness=proven_mutually_exclusive) proc my_proc(my_token: token, my_state: bits[32], my_predicate: bits[1], init={token, 42, 1}) { - my_predicate: bits[1] = state_read(state_element=my_predicate, id=18) - my_token: token = state_read(state_element=my_token, id=9) - my_state: bits[32] = state_read(state_element=my_state, predicate=my_predicate, id=10) - send.1: token = send(my_token, my_state, channel=ch, id=1) + my_predicate__1: bits[1] = state_read(state_element=my_predicate, id=18) + my_token__1: token = state_read(state_element=my_token, id=9) + my_state__1: bits[32] = state_read(state_element=my_state, predicate=my_predicate__1, id=10) + send.1: token = send(my_token__1, my_state__1, channel=ch, id=1) literal.2: bits[1] = literal(value=1, id=2) receive.3: (token, bits[32]) = receive(send.1, predicate=literal.2, channel=ch, id=3) tuple_index.4: token = tuple_index(receive.3, index=0, id=4) next_value.5: () = next_value(state_element=my_token, value=tuple_index.4, id=5) - next_value.6: () = next_value(state_element=my_state, value=my_state, id=6) - next_value.7: () = next_value(state_element=my_predicate, value=my_predicate, id=7) + next_value.6: () = next_value(state_element=my_state, value=my_state__1, id=6) + next_value.7: () = next_value(state_element=my_predicate, value=my_predicate__1, id=7) } diff --git a/xls/ir/testdata/ir_parser_round_trip_test_ParseScheduledProc.ir b/xls/ir/testdata/ir_parser_round_trip_test_ParseScheduledProc.ir index b43b4fe690..9cad7b39cc 100644 --- a/xls/ir/testdata/ir_parser_round_trip_test_ParseScheduledProc.ir +++ b/xls/ir/testdata/ir_parser_round_trip_test_ParseScheduledProc.ir @@ -2,9 +2,9 @@ package my_package scheduled_proc my_proc(st: bits[32], init={42}) { stage { - st: bits[32] = state_read(state_element=st, id=1) + st__1: bits[32] = state_read(state_element=st, id=1) literal.2: bits[32] = literal(value=1, id=2) - add.3: bits[32] = add(literal.2, st, id=3) + add.3: bits[32] = add(literal.2, st__1, id=3) next_value.4: () = next_value(state_element=st, value=add.3, id=4) } } diff --git a/xls/ir/testdata/ir_parser_round_trip_test_ParseSimpleProc.ir b/xls/ir/testdata/ir_parser_round_trip_test_ParseSimpleProc.ir index ff6bc50b7c..73470e7eab 100644 --- a/xls/ir/testdata/ir_parser_round_trip_test_ParseSimpleProc.ir +++ b/xls/ir/testdata/ir_parser_round_trip_test_ParseSimpleProc.ir @@ -3,12 +3,12 @@ package test chan ch(bits[32], id=0, kind=streaming, ops=send_receive, flow_control=none, strictness=proven_mutually_exclusive) proc my_proc(my_token: token, my_state: bits[32], init={token, 42}) { - my_token: token = state_read(state_element=my_token, id=7) - my_state: bits[32] = state_read(state_element=my_state, id=8) - send.1: token = send(my_token, my_state, channel=ch, id=1) + my_token__1: token = state_read(state_element=my_token, id=7) + my_state__1: bits[32] = state_read(state_element=my_state, id=8) + send.1: token = send(my_token__1, my_state__1, channel=ch, id=1) literal.2: bits[1] = literal(value=1, id=2) receive.3: (token, bits[32]) = receive(send.1, predicate=literal.2, channel=ch, id=3) tuple_index.4: token = tuple_index(receive.3, index=0, id=4) next_value.13: () = next_value(state_element=my_token, value=tuple_index.4, id=13) - next_value.14: () = next_value(state_element=my_state, value=my_state, id=14) + next_value.14: () = next_value(state_element=my_state, value=my_state__1, id=14) } diff --git a/xls/tools/delay_info_main_test.py b/xls/tools/delay_info_main_test.py index 717ad46c9b..dff4e0164b 100644 --- a/xls/tools/delay_info_main_test.py +++ b/xls/tools/delay_info_main_test.py @@ -144,14 +144,9 @@ def test_decoupled_next_proc(self): '--pipeline_stages=1', ir_file.full_path, ]).decode('utf-8') - print(output) self.assertIn('# Critical path for state element __state', output) - self.assertIn( - '__state: bits[32] = state_read(state_element=__state,', output - ) - self.assertIn( - 'add: bits[32] = add(__state: bits[32], one: bits[32],', output - ) + self.assertIn('sr: bits[32] = state_read(state_element=__state,', output) + self.assertIn('add: bits[32] = add(sr: bits[32], one: bits[32],', output) self.assertIn('next_state: () = next_value(state_element=__state,', output) diff --git a/xls/tools/eval_proc_main_proc_scoped_test.py b/xls/tools/eval_proc_main_proc_scoped_test.py index 1583cc179f..7c78f2a3e7 100644 --- a/xls/tools/eval_proc_main_proc_scoped_test.py +++ b/xls/tools/eval_proc_main_proc_scoped_test.py @@ -1332,13 +1332,15 @@ def test_observe_proc(self, backend): node_stats( node_id=4, node_text=( - "send.4: token = send(literal.2, st, channel=out, id=4)" + "send.4: token = send(literal.2, st__1, channel=out, id=4)" ), set_bits=TOKEN, ), node_stats( node_id=78, - node_text="st: bits[32] = state_read(state_element=st, id=78)", + node_text=( + "st__1: bits[32] = state_read(state_element=st, id=78)" + ), set_bits=_value_32_bits(0b11), total_bit_count=32, unset_bit_count=30,