basic_block.py 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. # TODO: Get all jump commands
  2. JUMP_COMMANDS = ['j', 'jal']
  3. def is_jump(statement):
  4. '''Check if a statement is a jump command.'''
  5. return statement[0] == 'command' and statement[1] in JUMP_COMMANDS
  6. def find_leaders(statements):
  7. '''Determine the leaders, which are:
  8. 1. The first statement.
  9. 2. Any statement that is the target of a jump.
  10. 3. Any statement that follows directly follows a jump.'''
  11. leaders = [0]
  12. jump_target_labels = []
  13. # Append statements following jumps and save jump target labels
  14. for i, statement in enumerate(statements[1:]):
  15. if is_jump(statement):
  16. leaders.append(i + 2)
  17. jump_target_labels.append(statement[2]['args'][0])
  18. #print 'found jump:', i, statement
  19. #print 'target labels:', jump_target_labels
  20. # Append jump targets
  21. for i, statement in enumerate(statements[1:]):
  22. if i + 1 not in leaders \
  23. and statement[0] == 'label' \
  24. and statement[1] in jump_target_labels:
  25. leaders.append(i + 1)
  26. #print 'target:', i + 1, statements[i + 1]
  27. return leaders
  28. def find_basic_blocks(statements):
  29. '''Divide a statement list into basic blocks. Returns a list of basic
  30. blocks, which are also statement lists.'''
  31. leaders = find_leaders(statements)
  32. blocks = []
  33. for i in range(len(leaders) - 1):
  34. blocks.append(statements[leaders[i]:leaders[i + 1]])
  35. return blocks