@@ -868,86 +868,46 @@ impl<'a> Context<'a> {
868
868
self . region_scope = region;
869
869
}
870
870
871
- let [ region_source , region_targets] = self . get_func_type (
871
+ let [ _ , region_targets] = self . get_func_type (
872
872
region_data
873
873
. signature
874
874
. ok_or_else ( || error_uninferred ! ( "region signature" ) ) ?,
875
875
) ?;
876
876
877
- let region_source_types = self . import_closed_list ( region_source) ?;
878
877
let region_target_types = self . import_closed_list ( region_targets) ?;
879
878
880
- // Create the entry node for the control flow region.
881
- // Since the core hugr does not have explicit entry blocks yet, we create a dataflow block
882
- // that simply forwards its inputs to its outputs.
883
- {
884
- let types = {
885
- let [ ctrl_type] = region_source_types. as_slice ( ) else {
886
- return Err ( table:: ModelError :: TypeError ( region_source) . into ( ) ) ;
887
- } ;
888
-
889
- let [ types] = self . expect_symbol ( * ctrl_type, model:: CORE_CTRL ) ?;
890
- self . import_type_row ( types) ?
879
+ // Identify the entry node of the control flow region by looking for
880
+ // a block whose input is linked to the sole source port of the CFG region.
881
+ let entry_node = ' find_entry: {
882
+ let [ entry_link] = region_data. sources else {
883
+ return Err ( table:: ModelError :: InvalidRegions ( node_id) . into ( ) ) ;
891
884
} ;
892
885
893
- let entry = self . hugr . add_node_with_parent (
894
- node,
895
- OpType :: DataflowBlock ( DataflowBlock {
896
- inputs : types. clone ( ) ,
897
- other_outputs : TypeRow :: default ( ) ,
898
- sum_rows : vec ! [ types. clone( ) ] ,
899
- } ) ,
900
- ) ;
901
-
902
- self . record_links ( entry, Direction :: Outgoing , region_data. sources ) ;
903
-
904
- let node_input = self . hugr . add_node_with_parent (
905
- entry,
906
- OpType :: Input ( Input {
907
- types : types. clone ( ) ,
908
- } ) ,
909
- ) ;
910
-
911
- let node_output = self . hugr . add_node_with_parent (
912
- entry,
913
- OpType :: Output ( Output {
914
- types : vec ! [ Type :: new_sum( [ types. clone( ) ] ) ] . into ( ) ,
915
- } ) ,
916
- ) ;
917
-
918
- let node_tag = self . hugr . add_node_with_parent (
919
- entry,
920
- OpType :: Tag ( Tag {
921
- tag : 0 ,
922
- variants : vec ! [ types] ,
923
- } ) ,
924
- ) ;
925
-
926
- // Connect the input node to the tag node
927
- let input_outputs = self . hugr . node_outputs ( node_input) ;
928
- let tag_inputs = self . hugr . node_inputs ( node_tag) ;
929
- let mut connections =
930
- Vec :: with_capacity ( input_outputs. size_hint ( ) . 0 + tag_inputs. size_hint ( ) . 0 ) ;
931
-
932
- for ( a, b) in input_outputs. zip ( tag_inputs) {
933
- connections. push ( ( node_input, a, node_tag, b) ) ;
934
- }
935
-
936
- // Connect the tag node to the output node
937
- let tag_outputs = self . hugr . node_outputs ( node_tag) ;
938
- let output_inputs = self . hugr . node_inputs ( node_output) ;
886
+ for child in region_data. children {
887
+ let child_data = self . get_node ( * child) ?;
888
+ let is_entry = child_data. inputs . iter ( ) . any ( |link| link == entry_link) ;
939
889
940
- for ( a, b) in tag_outputs. zip ( output_inputs) {
941
- connections. push ( ( node_tag, a, node_output, b) ) ;
890
+ if is_entry {
891
+ break ' find_entry * child;
892
+ }
942
893
}
943
894
944
- for ( src, src_port, dst, dst_port) in connections {
945
- self . hugr . connect ( src, src_port, dst, dst_port) ;
946
- }
947
- }
895
+ // TODO: We should allow for the case in which control flows
896
+ // directly from the source to the target of the region. This is
897
+ // currently not allowed in hugr core directly, but may be simulated
898
+ // by constructing an empty entry block.
899
+ return Err ( table:: ModelError :: InvalidRegions ( node_id) . into ( ) ) ;
900
+ } ;
901
+
902
+ // The entry node in core control flow regions is identified by being
903
+ // the first child node of the CFG node. We therefore import the entry
904
+ // node first and follow it up by every other node.
905
+ self . import_node ( entry_node, node) ?;
948
906
949
907
for child in region_data. children {
950
- self . import_node ( * child, node) ?;
908
+ if * child != entry_node {
909
+ self . import_node ( * child, node) ?;
910
+ }
951
911
}
952
912
953
913
// Create the exit node for the control flow region.
0 commit comments