aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPranil Dey <mkdeyp@gmail.com>2024-10-25 00:56:59 +0530
committerPranil Dey <mkdeyp@gmail.com>2024-10-25 00:57:07 +0530
commitc756ee328c82211698ddcaf9e3475c763884d7bb (patch)
tree3ba9410c973bc8ee51d51929d267036cda1e32dc
parentc4ab1c57107003e55287df06cf9b552830cb9d3c (diff)
downloadgcc-devel/nothrow-detection.zip
gcc-devel/nothrow-detection.tar.gz
gcc-devel/nothrow-detection.tar.bz2
Fixed extract_types_for_resx functiondevel/nothrow-detection
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
-rw-r--r--gcc/tree-eh.cc89
1 files changed, 44 insertions, 45 deletions
diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc
index df90d1b..e62fed9 100644
--- a/gcc/tree-eh.cc
+++ b/gcc/tree-eh.cc
@@ -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)
+// 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