Skip to content

Commit 4a0b3a9

Browse files
committed
Refactored core datastructures to be compatible with the changes
1 parent 877fb0a commit 4a0b3a9

File tree

5 files changed

+79
-136
lines changed

5 files changed

+79
-136
lines changed

numba_rvsdg/core/datastructures/byte_flow.py

Lines changed: 23 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import dis
2-
from copy import deepcopy
32
from dataclasses import dataclass
43
from typing import Generator, Callable
54

@@ -61,90 +60,51 @@ def from_bytecode(code: Callable) -> "ByteFlow": # type: ignore
6160
scfg = flowinfo.build_basicblocks()
6261
return ByteFlow(bc=bc, scfg=scfg)
6362

64-
def _join_returns(self) -> "ByteFlow":
63+
def _join_returns(self) -> None:
6564
"""Joins the return blocks within the corresponding SCFG.
6665
67-
This method creates a deep copy of the SCFG and performs
68-
operation to join return blocks within the control flow.
69-
It returns a new ByteFlow object with the updated SCFG.
70-
71-
Returns
72-
-------
73-
byteflow: ByteFlow
74-
The new ByteFlow object with updated SCFG.
66+
This method performs operation to join return blocks within
67+
the control flow.
7568
"""
76-
scfg = deepcopy(self.scfg)
77-
scfg.join_returns()
78-
return ByteFlow(bc=self.bc, scfg=scfg)
69+
self.scfg.join_returns()
7970

80-
def _restructure_loop(self) -> "ByteFlow":
71+
def _restructure_loop(self) -> None:
8172
"""Restructures the loops within the corresponding SCFG.
8273
83-
Creates a deep copy of the SCFG and performs the operation to
84-
restructure loop constructs within the control flow using
85-
the algorithm LOOP RESTRUCTURING from section 4.1 of Bahmann2015.
74+
Performs the operation to restructure loop constructs within
75+
the control flow using the algorithm LOOP RESTRUCTURING from
76+
section 4.1 of Bahmann2015.
8677
It applies the restructuring operation to both the main SCFG
87-
and any subregions within it. It returns a new ByteFlow object
88-
with the updated SCFG.
89-
90-
Returns
91-
-------
92-
byteflow: ByteFlow
93-
The new ByteFlow object with updated SCFG.
78+
and any subregions within it.
9479
"""
95-
scfg = deepcopy(self.scfg)
96-
restructure_loop(scfg.region)
97-
for region in _iter_subregions(scfg):
80+
restructure_loop(self.scfg.region)
81+
for region in _iter_subregions(self.scfg):
9882
restructure_loop(region)
99-
return ByteFlow(bc=self.bc, scfg=scfg)
10083

101-
def _restructure_branch(self) -> "ByteFlow":
84+
def _restructure_branch(self) -> None:
10285
"""Restructures the branches within the corresponding SCFG.
10386
104-
Creates a deep copy of the SCFG and performs the operation to
105-
restructure branch constructs within the control flow. It applies
106-
the restructuring operation to both the main SCFG and any
107-
subregions within it. It returns a new ByteFlow object with
108-
the updated SCFG.
109-
110-
Returns
111-
-------
112-
byteflow: ByteFlow
113-
The new ByteFlow object with updated SCFG.
87+
This method applies restructuring branch operation to both
88+
the main SCFG and any subregions within it.
11489
"""
115-
scfg = deepcopy(self.scfg)
116-
restructure_branch(scfg.region)
117-
for region in _iter_subregions(scfg):
90+
restructure_branch(self.scfg.region)
91+
for region in _iter_subregions(self.scfg):
11892
restructure_branch(region)
119-
return ByteFlow(bc=self.bc, scfg=scfg)
12093

121-
def restructure(self) -> "ByteFlow":
94+
def restructure(self) -> None:
12295
"""Applies join_returns, restructure_loop and restructure_branch
12396
in the respective order on the SCFG.
12497
125-
Creates a deep copy of the SCFG and applies a series of
126-
restructuring operations to it. The operations include
127-
joining return blocks, restructuring loop constructs, and
128-
restructuring branch constructs. It returns a new ByteFlow
129-
object with the updated SCFG.
130-
131-
Returns
132-
-------
133-
byteflow: ByteFlow
134-
The new ByteFlow object with updated SCFG.
98+
Applies a series of restructuring operations to given SCFG.
99+
The operations include joining return blocks, restructuring
100+
loop constructs, and restructuring branch constructs.
135101
"""
136-
scfg = deepcopy(self.scfg)
137102
# close
138-
scfg.join_returns()
103+
self._join_returns()
139104
# handle loop
140-
restructure_loop(scfg.region)
141-
for region in _iter_subregions(scfg):
142-
restructure_loop(region)
105+
self._restructure_loop()
143106
# handle branch
144-
restructure_branch(scfg.region)
145-
for region in _iter_subregions(scfg):
146-
restructure_branch(region)
147-
return ByteFlow(bc=self.bc, scfg=scfg)
107+
self._restructure_branch()
148108

149109

150110
def _iter_subregions(scfg: SCFG) -> Generator[RegionBlock, SCFG, None]:

numba_rvsdg/core/datastructures/flow_info.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,19 +126,19 @@ def build_basicblocks(
126126

127127
for begin, end in zip(offsets, [*offsets[1:], end_offset]):
128128
name = names[begin]
129-
targets: Tuple[str, ...]
129+
targets: list[str]
130130
term_offset = _prev_inst_offset(end)
131131
if term_offset not in self.jump_insts:
132132
# implicit jump
133-
targets = (names[end],)
133+
targets = [names[end]]
134134
else:
135-
targets = tuple(names[o] for o in self.jump_insts[term_offset])
135+
targets = [names[o] for o in self.jump_insts[term_offset]]
136136
block = PythonBytecodeBlock(
137137
name=name,
138138
begin=begin,
139139
end=end,
140140
_jump_targets=targets,
141-
backedges=(),
141+
backedges=[],
142142
)
143143
scfg.add_block(block)
144144
return scfg

numba_rvsdg/core/datastructures/scfg.py

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -527,14 +527,14 @@ def insert_block(
527527
# TODO: needs a diagram and documentaion
528528
# initialize new block
529529
new_block = block_type(
530-
name=new_name, _jump_targets=tuple(successors), backedges=tuple()
530+
name=new_name, _jump_targets=list(successors), backedges=[]
531531
)
532532
# add block to self
533533
self.add_block(new_block)
534534
# Replace any arcs from any of predecessors to any of successors with
535535
# an arc through the inserted block instead.
536536
for name in predecessors:
537-
block = self.graph.pop(name)
537+
block = self.graph[name]
538538
jt = list(block.jump_targets)
539539
if successors:
540540
for s in successors:
@@ -545,7 +545,7 @@ def insert_block(
545545
jt.pop(jt.index(s))
546546
else:
547547
jt.append(new_name)
548-
self.add_block(block.replace_jump_targets(jump_targets=tuple(jt)))
548+
block.replace_jump_targets(jump_targets=jt)
549549

550550
def insert_SyntheticExit(
551551
self,
@@ -639,8 +639,8 @@ def insert_block_and_control_blocks(
639639
variable_assignment[branch_variable] = branch_variable_value
640640
synth_assign_block = SyntheticAssignment(
641641
name=synth_assign,
642-
_jump_targets=(new_name,),
643-
backedges=(),
642+
_jump_targets=[new_name],
643+
backedges=[],
644644
variable_assignment=variable_assignment,
645645
)
646646
# add block
@@ -652,16 +652,12 @@ def insert_block_and_control_blocks(
652652
# replace previous successor with synth_assign
653653
jt[jt.index(s)] = synth_assign
654654
# finally, replace the jump_targets
655-
self.add_block(
656-
self.graph.pop(name).replace_jump_targets(
657-
jump_targets=tuple(jt)
658-
)
659-
)
655+
self.graph[name].replace_jump_targets(jump_targets=jt)
660656
# initialize new block, which will hold the branching table
661657
new_block = SyntheticHead(
662658
name=new_name,
663-
_jump_targets=tuple(successors),
664-
backedges=tuple(),
659+
_jump_targets=list(successors),
660+
backedges=[],
665661
variable=branch_variable,
666662
branch_value_table=branch_value_table,
667663
)
@@ -1079,7 +1075,7 @@ def to_yaml(scfg: "SCFG") -> str:
10791075
return ys
10801076

10811077
@staticmethod
1082-
def to_dict(scfg: "SCFG") -> Dict[str, Dict[str, Any]]:
1078+
def to_dict(scfg: "SCFG") -> Dict[str, Dict[str, BasicBlock]]:
10831079
"""Helper method to convert the SCFG object to a dictionary
10841080
representation.
10851081
@@ -1109,23 +1105,25 @@ def reverse_lookup(value: type) -> str:
11091105
raise TypeError("Block type not found.")
11101106

11111107
seen = set()
1112-
q: Set[Tuple[str, BasicBlock]] = set()
1108+
q: Set[str] = set()
11131109
# Order of elements doesn't matter since they're going to
11141110
# be sorted at the end.
1115-
q.update(scfg.graph.items())
1111+
graph_dict = {}
1112+
q.update(set(scfg.graph.keys()))
1113+
graph_dict.update(scfg.graph)
11161114

11171115
while q:
1118-
key, value = q.pop()
1116+
key = q.pop()
1117+
value = scfg.graph[key]
11191118
if key in seen:
11201119
continue
11211120
seen.add(key)
11221121

11231122
block_type = reverse_lookup(type(value))
11241123
blocks[key] = {"type": block_type}
11251124
if isinstance(value, RegionBlock):
1126-
assert value.subregion is not None
1127-
assert value.parent_region is not None
1128-
q.update(value.subregion.graph.items())
1125+
q.update(value.subregion.graph.keys())
1126+
graph_dict.update(value.subregion.graph)
11291127
blocks[key]["kind"] = value.kind
11301128
blocks[key]["contains"] = sorted(
11311129
[idx.name for idx in value.subregion.graph.values()]
@@ -1211,14 +1209,14 @@ def extract_block_info(
12111209
List of backedges of the requested block.
12121210
"""
12131211
block_info = blocks[current_name].copy()
1214-
block_edges = tuple(block_ref_dict[idx] for idx in edges[current_name])
1212+
block_edges = [block_ref_dict[idx] for idx in edges[current_name]]
12151213

12161214
if backedges.get(current_name):
1217-
block_backedges = tuple(
1215+
block_backedges = [
12181216
block_ref_dict[idx] for idx in backedges[current_name]
1219-
)
1217+
]
12201218
else:
1221-
block_backedges = ()
1219+
block_backedges = []
12221220

12231221
block_type = block_info.pop("type")
12241222

0 commit comments

Comments
 (0)