}
}
-// To get the all exception types from a resx stmt
-static bool
-extract_types_for_resx (basic_block bb, vec<tree> *ret_vector)
+// To get the all exception types from a resx stmt (iterative version)
+bool
+extract_types_for_resx (gimple *resx_stmt, vec<tree> *ret_vector)
{
- edge e;
- edge_iterator ei;
+ basic_block start_bb = gimple_bb (resx_stmt);
+ hash_set<basic_block> visited_blocks;
+ vec<basic_block> block_stack;
- // Iterate over edges to walk up the basic blocks
- FOR_EACH_EDGE (e, ei, bb->preds)
- {
- // Get the last stmt of the basic block as it is an EH stmt
- bb = e->src;
- gimple_stmt_iterator gsi = gsi_last_bb (bb);
- gimple *last_stmt = gsi_stmt (gsi);
+ block_stack.safe_push(start_bb);
- if (bb->aux)
+ while (!block_stack.is_empty())
+ {
+ basic_block bb = block_stack.pop();
+ if (visited_blocks.contains(bb))
continue;
- bb->aux = (void *)1;
- if (last_stmt && (e->flags & EDGE_EH))
+ visited_blocks.add(bb);
+
+ edge e;
+ edge_iterator ei;
+ gimple_stmt_iterator gsi = gsi_last_bb(bb);
+ gimple *last_stmt = gsi_stmt(gsi);
+
+
+ FOR_EACH_EDGE(e, ei, bb->preds)
+ {
+ basic_block pred_bb = e->src;
+
+ if (e->flags & EDGE_EH)
{
- if (gimple_code (last_stmt) == GIMPLE_CALL)
- {
- // check if its a throw
- if (!extract_types_for_call (as_a<gcall *> (last_stmt),
- ret_vector))
- return false;
- continue;
- }
- else if (gimple_code (last_stmt) == GIMPLE_RESX)
- {
- // Recursively processing resx
- // FIXME: to get this linear, we should cache results.
- if (!extract_types_for_resx (last_stmt, ret_vector))
- return false;
- continue;
- }
+ gimple_stmt_iterator pred_gsi = gsi_last_bb(pred_bb);
+ gimple *pred_last_stmt = gsi_stmt(pred_gsi);
+
+ if (gimple_code(pred_last_stmt) == GIMPLE_CALL)
+ {
+ if (!extract_types_for_call(as_a<gcall*>(pred_last_stmt), ret_vector))
+ return false;
+ }
+ else if (gimple_code(pred_last_stmt) == GIMPLE_RESX)
+ {
+ // Add the predecessor block to the stack for further exploration
+ block_stack.safe_push(pred_bb);
+ }
}
- /* FIXME: remove recursion here, so we do not run out of stack. */
- else if (!extract_types_for_resx (e->src, ret_vector))
- return false;
+ else
+ {
+ block_stack.safe_push(pred_bb);
+ }
+ }
}
- return true;
-}
-// To get the all exception types from a resx stmt
-bool
-extract_types_for_resx (gimple *resx_stmt, vec<tree> *ret_vector)
-{
- basic_block bb = gimple_bb (resx_stmt);
- bool ret = extract_types_for_resx (bb, ret_vector);
- /* FIXME: this is non-linear. */
- clear_aux_for_blocks ();
- return ret;
+ clear_aux_for_blocks();
+ return true;
}
// To get the types being thrown outside of a function