Skip to content

Commit

Permalink
Split block by index instead of instruction
Browse files Browse the repository at this point in the history
  • Loading branch information
alexcere committed Oct 21, 2024
1 parent cb60011 commit 7c34a36
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 11 deletions.
17 changes: 8 additions & 9 deletions src/parser/cfg_block_actions/split_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,27 @@ class SplitBlock(BlockAction):
It needs the corresponding blocklist to update the fields correspondingly
"""

def __init__(self, cfg_instruction: CFGInstruction, cfg_block: CFGBlock, cfg_blocklist: CFGBlockList):
self._cfg_instruction: CFGInstruction = cfg_instruction
def __init__(self, instr_idx: int, cfg_block: CFGBlock, cfg_blocklist: CFGBlockList):
# We add one to the index so that it points to the initial instruction of the second half
self._instr_idx: int = instr_idx + 1
self._cfg_block: Optional[CFGBlock] = cfg_block
self._cfg_block_list: CFGBlockList = cfg_blocklist
self._initial_id = self._cfg_block.block_id
self._first_half: Optional[CFGBlock] = None
self._second_half: Optional[CFGBlock] = None

def perform_action(self):
# First we find the index of the instruction. It is included as part of the first split block
instr_idx = self._cfg_block.get_instructions().index(self._cfg_instruction) + 1

#
first_half_id = new_node_name(self._initial_id)
second_half_id = new_node_name(first_half_id)

# We reuse the block name, so we don't need to modify the previous blocks
first_half = CFGBlock(first_half_id, self._cfg_block.get_instructions()[:instr_idx], "sub_block",
first_half = CFGBlock(first_half_id, self._cfg_block.get_instructions()[:self._instr_idx], "sub_block",
self._cfg_block.assignment_dict)
self._first_half = first_half

# Then we generate the second half
second_half = CFGBlock(second_half_id, self._cfg_block.get_instructions()[instr_idx:],
second_half = CFGBlock(second_half_id, self._cfg_block.get_instructions()[self._instr_idx:],
self._cfg_block.get_jump_type(), self._cfg_block.assignment_dict)
self._second_half = second_half

Expand All @@ -69,8 +67,9 @@ def _update_first_half(self):
self._first_half.set_comes_from(self._cfg_block.get_comes_from())
self._first_half.set_falls_to(self._second_half.block_id)
self._first_half.set_jump_to(None)

# We need to force the input arguments of the instruction we have use to split
self._first_half.final_stack_elements = self._cfg_instruction.get_in_args()
self._first_half.final_stack_elements = self._cfg_block.get_instructions()[self._instr_idx].get_in_args()

# Finally, we update the information from the blocks that jumped (or fell) to the first one
for pred_block_id in self._cfg_block.get_comes_from():
Expand Down Expand Up @@ -117,4 +116,4 @@ def _modify_comes_from(self, block_id: block_id_T, new_pred_block_id: block_id_T
assert found_previous, f"Comes from list {comes_from} of {block_id} does not contain {self._initial_id}"

def __str__(self):
return f"SplitBlock {self._initial_id} at instruction {self._cfg_instruction}"
return f"SplitBlock {self._initial_id} at instruction with index {self._instr_idx}"
11 changes: 9 additions & 2 deletions tests/test_split_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ def test_split_block_simple(self, n, instructions):

# We don't want to select the last index
selected_index = (n % (len(instructions) - 1))
split_object = SplitBlock(instructions[selected_index], cfg_block, cfg_block_list)
split_object = SplitBlock(selected_index, cfg_block, cfg_block_list)
split_object.perform_action()
assert True
assert len(cfg_block_list.blocks) == 2, "There must be two sub blocks"
assert "block_1" in cfg_block_list.blocks, "Block block_1 must appear in the block list"
assert "block_2" in cfg_block_list.blocks, "Block block_2 must appear in the block list"
assert len(cfg_block_list.blocks["block_1"].get_instructions()) == selected_index + 1, \
f"First block must contain {selected_index} instructions"
n_remaining_instrs = len(cfg_block.get_instructions()) - selected_index - 1
assert len(cfg_block_list.blocks["block_2"].get_instructions()) == n_remaining_instrs, \
f"Second block must contain {n_remaining_instrs} instructions"

0 comments on commit 7c34a36

Please sign in to comment.