Fixed extract_types_for_resx function

The function was recursive in nature and there is a chance of runnign out of stack, so now ann iterative approach was used to get the types for resx
This commit is contained in:
Pranil Dey 2024-10-25 00:56:59 +05:30
parent c4ab1c5710
commit c756ee328c

View File

@ -3183,60 +3183,59 @@ stmt_throw_types (function *, gimple *stmt, vec<tree> *ret_vector)
}
}
// To get the all exception types from a resx stmt
static bool
extract_types_for_resx (basic_block bb, vec<tree> *ret_vector)
{
edge e;
edge_iterator ei;
// 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);
if (bb->aux)
continue;
bb->aux = (void *)1;
if (last_stmt && (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;
}
}
/* FIXME: remove recursion here, so we do not run out of stack. */
else if (!extract_types_for_resx (e->src, ret_vector))
return false;
}
return true;
}
// To get the all exception types from a resx stmt
// To get the all exception types from a resx stmt (iterative version)
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;
basic_block start_bb = gimple_bb (resx_stmt);
hash_set<basic_block> visited_blocks;
vec<basic_block> block_stack;
block_stack.safe_push(start_bb);
while (!block_stack.is_empty())
{
basic_block bb = block_stack.pop();
if (visited_blocks.contains(bb))
continue;
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)
{
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);
}
}
else
{
block_stack.safe_push(pred_bb);
}
}
}
clear_aux_for_blocks();
return true;
}
// To get the types being thrown outside of a function