private BasicBlock current_block;
private bool unreachable_reported;
private List<JumpTarget> jump_stack = new ArrayList<JumpTarget> ();
+ private Set<BasicBlock> all_basic_blocks;
// check_variables
Map<Symbol, List<Variable>> var_map;
*/
public void analyze (CodeContext context) {
this.context = context;
+ all_basic_blocks = new HashSet<BasicBlock> ();
/* we're only interested in non-pkg source files */
var source_files = context.get_source_files ();
}
}
+ all_basic_blocks = null;
this.context = null;
}
}
m.entry_block = new BasicBlock.entry ();
+ all_basic_blocks.add (m.entry_block);
m.return_block = new BasicBlock ();
+ all_basic_blocks.add (m.return_block);
m.exit_block = new BasicBlock.exit ();
+ all_basic_blocks.add (m.exit_block);
m.return_block.connect (m.exit_block);
}
current_block = new BasicBlock ();
+ all_basic_blocks.add (current_block);
+
m.entry_block.connect (current_block);
current_block.add_node (m);
return;
}
current.postorder_visited = true;
- foreach (BasicBlock succ in current.get_successors ()) {
+ foreach (weak BasicBlock succ in current.get_successors ()) {
depth_first_traverse (succ, list);
}
current.postorder_number = list.size;
// new immediate dominator
BasicBlock new_idom = null;
bool first = true;
- foreach (BasicBlock pred in block.get_predecessors ()) {
+ foreach (weak BasicBlock pred in block.get_predecessors ()) {
if (idoms[pred.postorder_number] != null) {
if (first) {
new_idom = pred;
for (int i = block_list.size - 1; i >= 0; i--) {
var block = block_list[i];
- foreach (BasicBlock succ in block.get_successors ()) {
+ foreach (weak BasicBlock succ in block.get_successors ()) {
// if idom(succ) != block
if (succ.parent != block) {
block.add_dominator_frontier (succ);
}
}
- foreach (BasicBlock child in block.get_children ()) {
- foreach (BasicBlock child_frontier in child.get_dominator_frontier ()) {
+ foreach (weak BasicBlock child in block.get_children ()) {
+ foreach (weak BasicBlock child_frontier in child.get_dominator_frontier ()) {
// if idom(child_frontier) != block
if (child_frontier.parent != block) {
block.add_dominator_frontier (child_frontier);
}
}
- foreach (BasicBlock succ in block.get_successors ()) {
+ foreach (weak BasicBlock succ in block.get_successors ()) {
int j = 0;
- foreach (BasicBlock pred in succ.get_predecessors ()) {
+ foreach (weak BasicBlock pred in succ.get_predecessors ()) {
if (pred == block) {
break;
}
}
}
- foreach (BasicBlock child in block.get_children ()) {
+ foreach (weak BasicBlock child in block.get_children ()) {
check_block_variables (child);
}
mark_unreachable ();
} else {
current_block = new BasicBlock ();
+ all_basic_blocks.add (current_block);
last_block.connect (current_block);
}
stmt.true_statement.accept (this);
mark_unreachable ();
} else {
current_block = new BasicBlock ();
+ all_basic_blocks.add (current_block);
last_block.connect (current_block);
}
if (stmt.false_statement != null) {
// reachable?
if (last_true_block != null || last_false_block != null) {
current_block = new BasicBlock ();
+ all_basic_blocks.add (current_block);
if (last_true_block != null) {
last_true_block.connect (current_block);
}
}
var after_switch_block = new BasicBlock ();
+ all_basic_blocks.add (after_switch_block);
jump_stack.add (new JumpTarget.break_target (after_switch_block));
// condition
foreach (SwitchSection section in stmt.get_sections ()) {
current_block = new BasicBlock ();
+ all_basic_blocks.add (current_block);
condition_block.connect (current_block);
foreach (Statement section_stmt in section.get_statements ()) {
section_stmt.accept (this);
}
var loop_block = new BasicBlock ();
+ all_basic_blocks.add (loop_block);
jump_stack.add (new JumpTarget.continue_target (loop_block));
var after_loop_block = new BasicBlock ();
+ all_basic_blocks.add (after_loop_block);
jump_stack.add (new JumpTarget.break_target (after_loop_block));
// loop block
handle_errors (stmt.collection);
var loop_block = new BasicBlock ();
+ all_basic_blocks.add (loop_block);
jump_stack.add (new JumpTarget.continue_target (loop_block));
var after_loop_block = new BasicBlock ();
+ all_basic_blocks.add (after_loop_block);
jump_stack.add (new JumpTarget.break_target (after_loop_block));
// loop block
// normal control flow
if (!always_fail) {
current_block = new BasicBlock ();
+ all_basic_blocks.add (current_block);
last_block.connect (current_block);
}
}
var before_try_block = current_block;
var after_try_block = new BasicBlock ();
+ all_basic_blocks.add (after_try_block);
BasicBlock finally_block = null;
if (stmt.finally_body != null) {
finally_block = new BasicBlock ();
+ all_basic_blocks.add (finally_block);
current_block = finally_block;
// trap all forbidden jumps
var invalid_block = new BasicBlock ();
+ all_basic_blocks.add (invalid_block);
jump_stack.add (new JumpTarget.any_target (invalid_block));
stmt.finally_body.accept (this);
var catch_clauses = stmt.get_catch_clauses ();
for (int i = catch_clauses.size - 1; i >= 0; i--) {
var catch_clause = catch_clauses[i];
+ var error_block = new BasicBlock ();
+ all_basic_blocks.add (error_block);
+
if (catch_clause.error_type != null) {
var error_type = (ErrorType) catch_clause.error_type;
- jump_stack.add (new JumpTarget.error_target (new BasicBlock (), catch_clause, catch_clause.error_type.data_type as ErrorDomain, error_type.error_code, null));
+ jump_stack.add (new JumpTarget.error_target (error_block, catch_clause, catch_clause.error_type.data_type as ErrorDomain, error_type.error_code, null));
} else {
- jump_stack.add (new JumpTarget.error_target (new BasicBlock (), catch_clause, null, null, null));
+ jump_stack.add (new JumpTarget.error_target (error_block, catch_clause, null, null, null));
}
}