[gcc] Created branch 'devel/nothrow-detection'
The branch 'devel/nothrow-detection' was created pointing to: 9b53c7f9484f... Edge redirection for exceptions.
[gcc/devel/nothrow-detection] Edge redirection for exceptions.
https://gcc.gnu.org/g:9b53c7f9484fea5fa0fd23a6444b03071debc4f2 commit 9b53c7f9484fea5fa0fd23a6444b03071debc4f2 Author: Pranil Dey Date: Tue Aug 20 22:07:57 2024 +0530 Edge redirection for exceptions. This commit is contains change in code for the tree-eh.cc, tree-eh.h, MAINTAINERS and tree-cfg.cc files. Specifically it contains four functions - 1. void extract_exception_types_for_call which extracts the exception types in a call stmt and adds them into a vector tree. 2. bool stmt_throw_types does the same as stmt_could_throw the difference being that it also gives the list of exception types as given by the extract_exception_types_for_call function. 3. bool match_lp checks if a landing pad can handle any of the exception types given as input parameters by looking into the catch handlers. 4. update_stmt_eh_region is the function that walks up the EH tree and changes the landing pad for the last statement in a basic block in the control flow graph so that when the edge by make_eh_edge is created it points to the correct handlers. Further work to be done regarding RESX stmts. Diff: --- MAINTAINERS | 1 + gcc/tree-cfg.cc | 5 ++- gcc/tree-eh.cc | 114 gcc/tree-eh.h | 5 +++ 4 files changed, 123 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 595140b6f64f..f26db19345e4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -915,6 +915,7 @@ information. Juergen Christ Robin Dapp Robin Dapp +Pranil Dey Michal Jires Matthias Kretz Prathamesh Kulkarni diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc index e6fd1294b958..bb101c865ed6 100644 --- a/gcc/tree-cfg.cc +++ b/gcc/tree-cfg.cc @@ -855,11 +855,12 @@ make_edges_bb (basic_block bb, struct omp_region **pcur_region, int *pomp_index) if (!last) return ret; - + + update_stmt_eh_region(last); switch (gimple_code (last)) { case GIMPLE_GOTO: - if (make_goto_expr_edges (bb)) + if (make_goto_expr_edges (bb)) ret = 1; fallthru = false; break; diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc index 9609bdc0d9b7..eec1e6af70d7 100644 --- a/gcc/tree-eh.cc +++ b/gcc/tree-eh.cc @@ -2271,6 +2271,84 @@ make_eh_dispatch_edges (geh_dispatch *stmt) return true; } +// Check if a landing pad can handle any of the given exception types +bool match_lp(eh_landing_pad lp, vec *exception_types) { +eh_region region = lp->region; + +// Ensure the region is of type ERT_TRY +if (region && region->type == ERT_TRY) { +eh_catch_d *catch_handler = region->u.eh_try.first_catch; + +while (catch_handler) { +tree type_list = catch_handler->type_list; + +for (tree t = type_list; t; t = TREE_CHAIN(t)) { +tree type = TREE_VALUE(t); +for (unsigned i = 0; i < exception_types->length(); ++i) { + // match found or a catch-all handler (NULL) +if (type == (*exception_types)[i] || !type) { +return true; +} +} +} +catch_handler = catch_handler->next_catch; +} +} +return false; +} + +// Function to update landing pad in throw_stmt_table for a given statement +void update_stmt_eh_region(gimple *stmt) { + auto_vec exception_types; + if (!stmt_throw_types (cfun, stmt, &exception_types)) { +return; +} + +int lp_nr = lookup_stmt_eh_lp_fn(cfun, stmt); +if (lp_nr <= 0) { +return; +} + +eh_landing_pad lp = get_eh_landing_pad_from_number(lp_nr); +if (!lp) { +return; +} + +eh_region region = lp->region; + +// Walk up the region tree +while (region) { +switch (region->type) { +case ERT_CLEANUP: +*cfun->eh->throw_stmt_table->get(const_cast(stmt)) = lp->index; +return; + +case ERT_TRY: +if (match_lp(lp, &exception_types)) { +*cfun->eh->throw_stmt_table->get(const_cast(stmt)) = lp->index; +return; +} +break; + +case ERT_MUST_NOT_THROW: +// Undefined behavior, leave edge unchanged +return; + +case ERT_ALLOWED_EXCEPTIONS: +if (!match_lp(lp, &exception_types)) { +return; +} +break; + +default: +break; +} +region = region->outer; +} + +remove_stmt_from_eh_lp_fn(cfun, stmt); +} + /* Create the single EH edge from STMT to its nearest landing pad, if there is
[gcc/devel/nothrow-detection] Formatting for all functions done according to GNU standards and fixed testsuite fail bugs
https://gcc.gnu.org/g:c4ab1c57107003e55287df06cf9b552830cb9d3c commit c4ab1c57107003e55287df06cf9b552830cb9d3c Author: Pranil Dey Date: Mon Oct 7 02:23:19 2024 +0530 Formatting for all functions done according to GNU standards and fixed testsuite fail bugs Diff: --- gcc/tree-eh.cc | 448 - 1 file changed, 256 insertions(+), 192 deletions(-) diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc index 634f33f9a8d9..df90d1bc2049 100644 --- a/gcc/tree-eh.cc +++ b/gcc/tree-eh.cc @@ -2283,14 +2283,14 @@ same_or_derived_type (tree t1, tree t2) t2 = TYPE_MAIN_VARIANT (t2); if (t1 == t2) return true; - while ( (TREE_CODE (t1) == POINTER_TYPE || TREE_CODE (t1) == REFERENCE_TYPE) -&& TREE_CODE (t1) == TREE_CODE (t2)) - { -t1 = TYPE_MAIN_VARIANT (TREE_TYPE (t1)); -t2 = TYPE_MAIN_VARIANT (TREE_TYPE (t2)); -if (TREE_CODE (t1) == VOID_TYPE) - return true; - } + while ((TREE_CODE (t1) == POINTER_TYPE || TREE_CODE (t1) == REFERENCE_TYPE) + && TREE_CODE (t1) == TREE_CODE (t2)) +{ + t1 = TYPE_MAIN_VARIANT (TREE_TYPE (t1)); + t2 = TYPE_MAIN_VARIANT (TREE_TYPE (t2)); + if (TREE_CODE (t1) == VOID_TYPE) +return true; +} if (t1 == t2) return true; if (TREE_CODE (t2) == NULLPTR_TYPE && TREE_CODE (t1) == POINTER_TYPE) @@ -2300,153 +2300,186 @@ same_or_derived_type (tree t1, tree t2) return odr_equivalent_or_derived_p (t1, t2); } -// Check if a landing pad can handle any of the given exception types -static bool match_lp (eh_region region, vec *exception_types){ -// Ensure the region is of type ERT_TRY -if (region && region->type == ERT_TRY) { -eh_catch_d *catch_handler = region->u.eh_try.first_catch; +// Check if a region can handle any of the given exception types +static bool +match_lp (eh_region region, vec *exception_types) +{ + // Ensure the region is of type ERT_TRY + if (region && region->type == ERT_TRY) +{ + eh_catch_d *catch_handler = region->u.eh_try.first_catch; -while (catch_handler) { -tree type_list = catch_handler->type_list; + while (catch_handler) +{ + tree type_list = catch_handler->type_list; -if (type_list == NULL) { -return true; + if (type_list == NULL) +{ + return true; } -for (tree t = type_list; t; t = TREE_CHAIN (t)) { -tree type = TREE_VALUE (t); -for (unsigned i = 0; i < exception_types->length (); ++i) { + for (tree t = type_list; t; t = TREE_CHAIN (t)) +{ + tree type = TREE_VALUE (t); + for (unsigned i = 0; i < exception_types->length (); ++i) +{ // match found or a catch-all handler (NULL) -if (!type || same_or_derived_type (type, (*exception_types)[i])) { -return true; + if (!type + || same_or_derived_type (type, (*exception_types)[i])) +{ + return true; } } } -catch_handler = catch_handler->next_catch; + catch_handler = catch_handler->next_catch; } } -return false; + return false; } -static void unlink_eh_region(eh_region region) { -eh_region *link; +static void +unlink_eh_region (eh_region region) +{ + eh_region *link; -// Check if region is root -if (!region->outer) { -gcc_unreachable(); -return; + // Check if region is root + if (!region->outer) +{ + gcc_unreachable (); + return; } -link = ®ion->outer->inner; + link = ®ion->outer->inner; -while (*link && *link != region) { -link = &(*link)->next_peer; + while (*link && *link != region) +{ + link = &(*link)->next_peer; } -// Ensure the region is in the peer chain -gcc_assert(*link == region); + // Ensure the region is in the peer chain + gcc_assert (*link == region); -*link = region->next_peer; + *link = region->next_peer; -region->outer = NULL; -region->next_peer = NULL; + region->outer = NULL; + region->next_peer = NULL; } -static void reinsert_eh_region (eh_region region, eh_region new_outer) { -region->outer = new_outer; - -// Insert region as the inner of new_outer, or at the top of the tree -if (new_outer) { -region->next_peer = new_outer->inner; -new_outer->inner = region; -} else { -region->next_peer = cfun->eh->region_tree; -cfun->eh->region_tree = region; -} +static void +reinsert_eh_region (eh_region region, eh_region new_outer) +{ + region->outer = new_outer; + // Insert region as the inner of new_outer, or at the top of the tree + if (new_outer) +{ + region->next_peer = new_outer->inner; + new_outer->in
[gcc/devel/nothrow-detection] Updated code for unlinking regions
https://gcc.gnu.org/g:cd716809b8bd878fd5748b26129b347ede4b81ff commit cd716809b8bd878fd5748b26129b347ede4b81ff Author: Pranil Dey Date: Fri Oct 4 13:12:12 2024 +0530 Updated code for unlinking regions Diff: --- gcc/tree-eh.cc | 55 --- 1 file changed, 36 insertions(+), 19 deletions(-) diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc index 464a033dbf20..ef7d773d8372 100644 --- a/gcc/tree-eh.cc +++ b/gcc/tree-eh.cc @@ -2326,18 +2326,32 @@ bool match_lp (eh_landing_pad lp, vec *exception_types) { return false; } -void unlink_eh_region (eh_region region, eh_region prev_region) { -if (region->outer && region->outer->inner == region) { -region->outer->inner = region->next_peer; +void unlink_eh_region(eh_region region) { +gcc_assert(!region->inner); +eh_region *link; + +// Check if region is root +if (!region->outer) { +gcc_unreachable(); +return; } -if (prev_region && prev_region->next_peer == region) { -prev_region->next_peer = region->next_peer; + +link = ®ion->outer->inner; + +while (*link && *link != region) { +link = &(*link)->next_peer; } -region->next_peer = NULL; + +// Ensure the region is in the peer chain +gcc_assert(*link == region); + +*link = region->next_peer; + region->outer = NULL; +region->next_peer = NULL; } -void reinsert_eh_region(eh_region region, eh_landing_pad lp) { +void reinsert_eh_region (eh_region region, eh_landing_pad lp) { eh_region new_outer = lp->region; region->outer = new_outer; @@ -2351,8 +2365,8 @@ void reinsert_eh_region(eh_region region, eh_landing_pad lp) { } // Set the region index in the region array -region->index = vec_safe_length(cfun->eh->region_array); -vec_safe_push(cfun->eh->region_array, region); +region->index = vec_safe_length (cfun->eh->region_array); +vec_safe_push (cfun->eh->region_array, region); } // Function to update landing pad and region in throw_stmt_table for a given statement @@ -2385,7 +2399,7 @@ void update_stmt_eh_region (gimple *stmt) { } else *cfun->eh->throw_stmt_table->get (const_cast (stmt)) = lp->index; -unlink_eh_region (region, prev_region); +unlink_eh_region (region); reinsert_eh_region (region, lp); return; @@ -2397,7 +2411,7 @@ void update_stmt_eh_region (gimple *stmt) { } else *cfun->eh->throw_stmt_table->get (const_cast (stmt)) = lp->index; - unlink_eh_region (region, prev_region); + unlink_eh_region (region); reinsert_eh_region (region, lp); return; } @@ -2422,7 +2436,7 @@ void update_stmt_eh_region (gimple *stmt) { if (gimple_code (stmt) == GIMPLE_RESX){ gresx *resx_stmt = as_a (stmt); - gimple_resx_set_region (resx_stmt, region->index); + gimple_resx_set_region (resx_stmt, 0); } else remove_stmt_from_eh_lp_fn (cfun, stmt); } @@ -3089,7 +3103,8 @@ bool extract_types_for_call (gcall *call_stmt, vec *ret_vector) { } } return true; - } +} +return true; } // Determine which types can be thrown by a GIMPLE statement and convert them to compile-time types @@ -3097,14 +3112,14 @@ bool stmt_throw_types (function *fun, gimple *stmt, vec *ret_vector) { if (!flag_exceptions) { return false; } +bool type_exists = true; switch (gimple_code (stmt)) { -case GIMPLE_RESX: -extract_fun_resx_types (fun, ret_vector); -return !ret_vector->is_empty (); +// case GIMPLE_RESX: +// extract_fun_resx_types (fun, ret_vector); +// return !ret_vector->is_empty (); case GIMPLE_CALL: -bool type_exists = false; type_exists = extract_types_for_call (as_a (stmt), ret_vector); return type_exists && !ret_vector->is_empty (); @@ -3131,7 +3146,7 @@ void extract_types_for_resx (gimple *resx_stmt, vec *ret_vector) { if (bb->aux)continue; bb->aux = (void*)1; - if (e->flags & EDGE_EH && last_stmt!= NULL){ + if (!last_stmt && (e->flags & EDGE_EH)){ if (gimple_code (last_stmt) == GIMPLE_CALL) { // check if its a throw extract_types_for_call (as_a (last_stmt), ret_vector); @@ -3154,6 +3169,8 @@ void extract_fun_resx_types (function *fun, vec *ret_vector) { gimple_stmt_iterator gsi; hash_set types; + clear_aux_for_blocks (); + FOR_EACH_BB_FN (bb, fun) { bb->aux = (void*)1; @@ -3161,7 +3178,7 @@ void extract_fun_resx_types (function *fun, vec *ret_vector) { gimple *stmt = gsi_stmt (gsi); auto_vec resx_types; - if (stmt_can
[gcc/devel/nothrow-detection] Added function bool extract_types_for_resx and fixed more functions for testcases
https://gcc.gnu.org/g:f5b29909d5dd42299bc1eafff18211425266f791 commit f5b29909d5dd42299bc1eafff18211425266f791 Author: Pranil Dey Date: Sun Oct 6 18:25:17 2024 +0530 Added function bool extract_types_for_resx and fixed more functions for testcases 1. bool extract_types_for_resx (gimple *,vec *) - This is for intiating the function static bool extract_types_for_resx (basic_block, vec *) which gets the resx stmt from a basic block and aclears the aux value for all blocks 2. update_stmt_eh_region - This is changed to unlink and reinsert the regions incase of a resx stmt properly Diff: --- gcc/tree-eh.cc | 122 + gcc/tree-eh.h | 8 +--- 2 files changed, 65 insertions(+), 65 deletions(-) diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc index 89daf32046e3..634f33f9a8d9 100644 --- a/gcc/tree-eh.cc +++ b/gcc/tree-eh.cc @@ -2276,7 +2276,7 @@ make_eh_dispatch_edges (geh_dispatch *stmt) return true; } -bool +static bool same_or_derived_type (tree t1, tree t2) { t1 = TYPE_MAIN_VARIANT (t1); @@ -2288,18 +2288,20 @@ same_or_derived_type (tree t1, tree t2) { t1 = TYPE_MAIN_VARIANT (TREE_TYPE (t1)); t2 = TYPE_MAIN_VARIANT (TREE_TYPE (t2)); +if (TREE_CODE (t1) == VOID_TYPE) + return true; } if (t1 == t2) return true; + if (TREE_CODE (t2) == NULLPTR_TYPE && TREE_CODE (t1) == POINTER_TYPE) +return true; if (!AGGREGATE_TYPE_P (t1) || !AGGREGATE_TYPE_P (t2)) return false; return odr_equivalent_or_derived_p (t1, t2); } // Check if a landing pad can handle any of the given exception types -bool match_lp (eh_landing_pad lp, vec *exception_types) { -eh_region region = lp->region; - +static bool match_lp (eh_region region, vec *exception_types){ // Ensure the region is of type ERT_TRY if (region && region->type == ERT_TRY) { eh_catch_d *catch_handler = region->u.eh_try.first_catch; @@ -2315,7 +2317,7 @@ bool match_lp (eh_landing_pad lp, vec *exception_types) { tree type = TREE_VALUE (t); for (unsigned i = 0; i < exception_types->length (); ++i) { // match found or a catch-all handler (NULL) -if (!type || same_or_derived_type ( (*exception_types)[i], type)) { +if (!type || same_or_derived_type (type, (*exception_types)[i])) { return true; } } @@ -2326,7 +2328,7 @@ bool match_lp (eh_landing_pad lp, vec *exception_types) { return false; } -void unlink_eh_region(eh_region region) { +static void unlink_eh_region(eh_region region) { eh_region *link; // Check if region is root @@ -2350,8 +2352,7 @@ void unlink_eh_region(eh_region region) { region->next_peer = NULL; } -void reinsert_eh_region (eh_region region, eh_landing_pad lp) { -eh_region new_outer = lp->region; +static void reinsert_eh_region (eh_region region, eh_region new_outer) { region->outer = new_outer; // Insert region as the inner of new_outer, or at the top of the tree @@ -2363,9 +2364,6 @@ void reinsert_eh_region (eh_region region, eh_landing_pad lp) { cfun->eh->region_tree = region; } -// Set the region index in the region array -region->index = vec_safe_length (cfun->eh->region_array); -vec_safe_push (cfun->eh->region_array, region); } // Function to update landing pad and region in throw_stmt_table for a given statement @@ -2377,7 +2375,7 @@ void update_stmt_eh_region (gimple *stmt) { int lp_nr = lookup_stmt_eh_lp_fn (cfun, stmt); if (lp_nr <= 0) { -return; + return; } eh_landing_pad lp = get_eh_landing_pad_from_number (lp_nr); @@ -2386,11 +2384,11 @@ void update_stmt_eh_region (gimple *stmt) { } eh_region region = lp->region; -eh_region prev_region = NULL; +eh_region resx_region = NULL; bool update = false; if (gimple_code (stmt) == GIMPLE_RESX) -region = region->outer; +resx_region = get_eh_region_from_number (gimple_resx_region (as_a (stmt))); // Walk up the region tree while (region) { @@ -2400,30 +2398,25 @@ void update_stmt_eh_region (gimple *stmt) { return; if (gimple_code (stmt) == GIMPLE_RESX){ - gresx *resx_stmt = as_a (stmt); - gimple_resx_set_region (resx_stmt, region->index); + unlink_eh_region (resx_region); + reinsert_eh_region (resx_region, region); } -else *cfun->eh->throw_stmt_table->get (const_cast (stmt)) = lp->index; - -unlink_eh_region (region); -reinsert_eh_region (region, lp); +remove_stmt_from_eh_lp_fn (cfun, stmt); +record_stmt_eh_region (region, stmt); return; case ERT_TRY: -if (update) -
[gcc/devel/nothrow-detection] Updated code for unlinking regions and update stmt_eh_regions as well
https://gcc.gnu.org/g:da431b3514d93d70e2894c9076fd8908af70f069 commit da431b3514d93d70e2894c9076fd8908af70f069 Author: Pranil Dey Date: Sat Oct 5 10:26:15 2024 +0530 Updated code for unlinking regions and update stmt_eh_regions as well Diff: --- gcc/tree-eh.cc | 23 +++ 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc index ef7d773d8372..89daf32046e3 100644 --- a/gcc/tree-eh.cc +++ b/gcc/tree-eh.cc @@ -2327,7 +2327,6 @@ bool match_lp (eh_landing_pad lp, vec *exception_types) { } void unlink_eh_region(eh_region region) { -gcc_assert(!region->inner); eh_region *link; // Check if region is root @@ -2389,14 +2388,22 @@ void update_stmt_eh_region (gimple *stmt) { eh_region region = lp->region; eh_region prev_region = NULL; +bool update = false; +if (gimple_code (stmt) == GIMPLE_RESX) +region = region->outer; + // Walk up the region tree while (region) { switch (region->type) { case ERT_CLEANUP: +if (!update) + return; + if (gimple_code (stmt) == GIMPLE_RESX){ gresx *resx_stmt = as_a (stmt); gimple_resx_set_region (resx_stmt, region->index); } + else *cfun->eh->throw_stmt_table->get (const_cast (stmt)) = lp->index; unlink_eh_region (region); @@ -2404,11 +2411,15 @@ void update_stmt_eh_region (gimple *stmt) { return; case ERT_TRY: +if (update) +return; + if (match_lp (lp, &exception_types)) { if (gimple_code (stmt) == GIMPLE_RESX){ gresx *resx_stmt = as_a (stmt); gimple_resx_set_region (resx_stmt, region->index); } + else *cfun->eh->throw_stmt_table->get (const_cast (stmt)) = lp->index; unlink_eh_region (region); @@ -2432,8 +2443,12 @@ void update_stmt_eh_region (gimple *stmt) { } prev_region = region; region = region->outer; +update = true; } +if (!update) +return; + if (gimple_code (stmt) == GIMPLE_RESX){ gresx *resx_stmt = as_a (stmt); gimple_resx_set_region (resx_stmt, 0); @@ -3115,9 +3130,9 @@ bool stmt_throw_types (function *fun, gimple *stmt, vec *ret_vector) { bool type_exists = true; switch (gimple_code (stmt)) { -// case GIMPLE_RESX: -// extract_fun_resx_types (fun, ret_vector); -// return !ret_vector->is_empty (); +case GIMPLE_RESX: +extract_fun_resx_types (fun, ret_vector); +return !ret_vector->is_empty (); case GIMPLE_CALL: type_exists = extract_types_for_call (as_a (stmt), ret_vector);
[gcc/devel/nothrow-detection] Fixed extract_types_for_resx function
https://gcc.gnu.org/g:c756ee328c82211698ddcaf9e3475c763884d7bb commit c756ee328c82211698ddcaf9e3475c763884d7bb Author: Pranil Dey Date: Fri Oct 25 00:56:59 2024 +0530 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 Diff: --- gcc/tree-eh.cc | 89 +- 1 file changed, 44 insertions(+), 45 deletions(-) diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc index df90d1bc2049..e62fed90c6dd 100644 --- a/gcc/tree-eh.cc +++ b/gcc/tree-eh.cc @@ -3183,60 +3183,59 @@ stmt_throw_types (function *, gimple *stmt, vec *ret_vector) } } -// To get the all exception types from a resx stmt -static bool -extract_types_for_resx (basic_block bb, vec *ret_vector) +// To get the all exception types from a resx stmt (iterative version) +bool +extract_types_for_resx (gimple *resx_stmt, vec *ret_vector) { - edge e; - edge_iterator ei; + basic_block start_bb = gimple_bb (resx_stmt); + hash_set visited_blocks; + vec 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 (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(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 *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
[gcc/devel/nothrow-detection] (1597 commits) Merge branch 'master' of git+ssh://gcc.gnu.org/git/gcc into
The branch 'devel/nothrow-detection' was updated to point to: b602de4ed9f8... Merge branch 'master' of git+ssh://gcc.gnu.org/git/gcc into It previously pointed to: c16d4a0ae162... Fix handling of types Diff: Summary of changes (added commits): --- b602de4... Merge branch 'master' of git+ssh://gcc.gnu.org/git/gcc into 87905f6... middle-end: check explicitly for external or constants when (*) bac9561... Ensure coarrays in calls use a descriptor [PR81265] (*) 71bf3da... tree-optimization/116842 - vectorizer load hosting breaks U (*) 85f5d06... tree-optimization/116785 - relax volatile handling in PTA (*) 6416365... tree-optimization/116850 - corrupt post-dom info (*) 3f8b1b2... Match: Support form 1 for scalar signed integer SAT_SUB (*) f0d0c56... Daily bump. (*) a2a78c0... RISC-V: Add testcases for form 1 of scalar signed SAT_SUB (*) b6ea98b... RISC-V: Implement scalar SAT_SUB for signed integer (*) 7372672... cselib: Discard useless locs of preserved VALUEs [PR116627] (*) f4d0c6a... testsuite: XFAIL gfortran.dg/initialization_25.f90 properly (*) 01a42a0... [PATCH] SH: Document extended asm operand modifers (*) 0cd24b0... [PATCH] [PATCH] Avoid integer overflow in gcc.dg/cpp/charco (*) a0f1f50... [PATCH v2] RISC-V: Improve code generation for select of co (*) a30a9d5... doc: Document struct-layout-1.exp for ABI checks (*) 74a0ff6... Daily bump. (*) 786773d... Implement FINDLOC for UNSIGNED. (*) 1c92800... Implement CSHIFT and EOSHIFT for unsigned. (*) 2531f01... doc: Remove i?86-*-linux* installation note from 2003 (*) 9261339... Daily bump. (*) 2196a20... c++: Implement resolution for DR 36 [PR116160] (*) b9ac51a... c++: Don't strip USING_DECLs when updating local bindings [ (*) cf9efe5... c++/modules: Propagate purview/import for templates in dupl (*) 6885407... libstdc++: Fix more pedwarns in headers for C++98 (*) 16491e1... libstdc++: Refactor experimental::filesystem::path string c (*) 7040c20... libstdc++: Fix -Wsign-compare warning in std::string::resiz (*) 96e0370... c++: ICE with structured bindings and m-d array [PR102594] (*) c580b8a... libstdc++: Fix test FAILs due to -Wreturn-local-addr (*) 500046d... libstdc++: Fix test FAIL due to -Wpointer-arith (*) 0ff49a5... aarch64: fix build failure on aarch64-none-elf (*) 64072e6... diagnostic: Save/restore diagnostic context history and pus (*) ddc72ba... diagnostic: Use vec instead of custom array reallocations f (*) a721089... i386: Modernize AMD processor types (*) cd430b1... Widening-Mul: Fix one ICE when iterate on phi node (*) 9085cc2... Fix sorting in Contributors.html (*) dd5b823... libgcc, Darwin: Don't build legacy libgcc_s.1 on macOS 14 [ (*) d888a8a... c++/coro: ignore cleanup_point_exprs while expanding awaits (*) de03ef6... c++: simplify handling implicit INDIRECT_REF and co_await i (*) 05e4f07... c++/coro: prevent ICV_STATEMENT diagnostics in temp promoti (*) 037c97e... [MAINTAINERS]: Add myself as MVE Reviewer for the AArch32 ( (*) cfdc0a3... libgomp.texi: Remove now duplicate TR13 item (*) bb01c9d... RISC-V/libgcc: Save/Restore routines for E goes with ABI. (*) 6b7eaec... libgomp.texi: fix formatting; add post-TR13 OpenMP impl. st (*) b1c7095... tree-optimization/116818 - try VMAT_GATHER_SCATTER also for (*) 3db9e99... Fix bogus SLP nvector compute in check_load_store_for_parti (*) 9c04112... unswitch: Replace manual ondemand maybe_undef with ssa_name (*) 1a0b33e... c++/modules: Allow imported references in constant expressi (*) d0762e9... c++/modules: Fix linkage checks for exported using-decls (*) ad08ef0... c++/modules: Use decl_linkage in maybe_record_mergeable_dec (*) af4471c... c++: Update decl_linkage for C++11 (*) 3471ae3... testsuite/gfortran.dg/open_errors_2.f90: Remove now-redunda (*) ff20f2b... Daily bump. (*) 48e1b89... libstdc++: Add missing 'inline' to always_inline function (*) 6a4d1c3... libgcc, libstdc++: Make declarations no longer TU-local [PR (*) 6ac4e2f... c++: tweak for -Wrange-loop-construct [PR116731] (*) e23e537... libstdc++: Fix freebsd/dragonfly build [PR116859] (*) ee9f006... libstdc++: Preserve signbit of nan when converting float to (*) 5ad6ff2... libstdc++: Fix comments in tests that mention bas (*) 240285e... libstdc++: Add [[nodiscard]] to iostream members (*) 9ec258b... libgomp.texi: Fix deprecation note for omp_{get,set}_nested (*) 819098d... testsuite: XFAIL gfortran.dg/initialization_25.f90 properly (*) e9f3414... doc: Remove index reference to removed documentation in for (*) 6f76ce8... Add virtual destructor to AbstractExpr (*) 942bbb2... tree-optimization/114855 - speed up dom_oracle::register_tr (*) e4a58b6... Fortran/OpenMP: Middle-end support for mapping of DT with a (*) d797202... libstdc++: Suppress an attribute suggestion warning [PR1168 (*) c45844e... libstdc++: Fix std::basic_stracktrace to not assume allocat (*)
[gcc/devel/nothrow-detection] Fixed some indentations and function names
https://gcc.gnu.org/g:70505f5757f09145f4465f5cf597ecc2b64069e0 commit 70505f5757f09145f4465f5cf597ecc2b64069e0 Author: Pranil Dey Date: Fri Aug 30 21:31:26 2024 +0530 Fixed some indentations and function names 1. Changed function name extract_exception_types_for_call to extract_types_for_call due to length of the name 2. Fixed space indentation in some places Diff: --- gcc/tree-eh.cc | 32 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc index 4d541b08c2fc..e7e4bd191628 100644 --- a/gcc/tree-eh.cc +++ b/gcc/tree-eh.cc @@ -2293,7 +2293,7 @@ same_or_derived_type (tree t1, tree t2) } // Check if a landing pad can handle any of the given exception types -bool match_lp(eh_landing_pad lp, vec *exception_types) { +bool match_lp (eh_landing_pad lp, vec *exception_types) { eh_region region = lp->region; // Ensure the region is of type ERT_TRY @@ -2303,15 +2303,15 @@ bool match_lp(eh_landing_pad lp, vec *exception_types) { while (catch_handler) { tree type_list = catch_handler->type_list; -if(type_list == NULL) { +if (type_list == NULL) { return true; } -for (tree t = type_list; t; t = TREE_CHAIN(t)) { -tree type = TREE_VALUE(t); -for (unsigned i = 0; i < exception_types->length(); ++i) { +for (tree t = type_list; t; t = TREE_CHAIN (t)) { +tree type = TREE_VALUE (t); +for (unsigned i = 0; i < exception_types->length (); ++i) { // match found or a catch-all handler (NULL) -if (!type || same_or_derived_type ((*exception_types)[i], type)) { +if (!type || same_or_derived_type ( (*exception_types)[i], type)) { return true; } } @@ -2323,18 +2323,18 @@ bool match_lp(eh_landing_pad lp, vec *exception_types) { } // Function to update landing pad in throw_stmt_table for a given statement -void update_stmt_eh_region(gimple *stmt) { +void update_stmt_eh_region (gimple *stmt) { auto_vec exception_types; if (!stmt_throw_types (cfun, stmt, &exception_types)) { return; } -int lp_nr = lookup_stmt_eh_lp_fn(cfun, stmt); +int lp_nr = lookup_stmt_eh_lp_fn (cfun, stmt); if (lp_nr <= 0) { return; } -eh_landing_pad lp = get_eh_landing_pad_from_number(lp_nr); +eh_landing_pad lp = get_eh_landing_pad_from_number (lp_nr); if (!lp) { return; } @@ -2345,12 +2345,12 @@ void update_stmt_eh_region(gimple *stmt) { while (region) { switch (region->type) { case ERT_CLEANUP: -*cfun->eh->throw_stmt_table->get(const_cast(stmt)) = lp->index; +*cfun->eh->throw_stmt_table->get (const_cast (stmt)) = lp->index; return; case ERT_TRY: -if (match_lp(lp, &exception_types)) { -*cfun->eh->throw_stmt_table->get(const_cast(stmt)) = lp->index; +if (match_lp (lp, &exception_types)) { +*cfun->eh->throw_stmt_table->get (const_cast (stmt)) = lp->index; return; } break; @@ -2360,7 +2360,7 @@ void update_stmt_eh_region(gimple *stmt) { return; case ERT_ALLOWED_EXCEPTIONS: -if (!match_lp(lp, &exception_types)) { +if (!match_lp (lp, &exception_types)) { return; } break; @@ -2371,7 +2371,7 @@ void update_stmt_eh_region(gimple *stmt) { region = region->outer; } -remove_stmt_from_eh_lp_fn(cfun, stmt); +remove_stmt_from_eh_lp_fn (cfun, stmt); } /* Create the single EH edge from STMT to its nearest landing pad, @@ -3016,7 +3016,7 @@ stmt_could_throw_1_p (gassign *stmt) return false; } -void extract_exception_types_for_call (gcall *call_stmt, vec *ret_vector) { +void extract_types_for_call (gcall *call_stmt, vec *ret_vector) { tree callee = gimple_call_fndecl (call_stmt); if (callee == NULL_TREE) { return; @@ -3045,7 +3045,7 @@ bool stmt_throw_types (function *fun, gimple *stmt, vec *ret_vector) { switch (gimple_code (stmt)) { case GIMPLE_CALL: -extract_exception_types_for_call (as_a (stmt), ret_vector); +extract_types_for_call (as_a (stmt), ret_vector); return !ret_vector->is_empty (); default:
[gcc/devel/nothrow-detection] RESX statement processing functions added:
https://gcc.gnu.org/g:d1a84d379d65c8d11a1f81e54f41d98cbce03cd7 commit d1a84d379d65c8d11a1f81e54f41d98cbce03cd7 Author: Pranil Dey Date: Sat Sep 21 03:06:48 2024 +0530 RESX statement processing functions added: 1. extract_types_for_resx - Used as a helper for getting the types from a resx statement to use later in the extract_fun_resx_types 2. extract_fun_resx_types - Used for getting the types thrown and propagated outside a function Diff: --- gcc/tree-eh.cc | 65 ++ 1 file changed, 65 insertions(+) diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc index e7e4bd191628..121cbed505b8 100644 --- a/gcc/tree-eh.cc +++ b/gcc/tree-eh.cc @@ -3053,6 +3053,71 @@ bool stmt_throw_types (function *fun, gimple *stmt, vec *ret_vector) { } } +// To get the all exception types from a resx stmt +void extract_types_for_resx (gimple *resx_stmt, vec *ret_vector) { + edge e; + edge_iterator ei; + + basic_block bb = gimple_bb (resx_stmt); + + // Iterate over edges to walk up the basic blocks + FOR_EACH_EDGE (e, ei, bb->pred) + { + // 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 (e->flags & EDGE_EH){ + if (gimple_code (last_stmt) == GIMPLE_CALL) { +// check if its a throw +extract_types_for_call (as_a (last_stmt), ret_vector); +continue; + } + else if (gimple_code(last_stmt) == GIMPLE_RESX){ +// Recursively processing resx +extract_types_for_resx (last_stmt, ret_vector); +continue; + } + +} + else extract_types_for_resx (last_stmt, ret_vector); + } +} + +// To get the types being thrown outside of a function +void extract_fun_resx_types (function *fun){ + basic_block bb; + gimple_stmt_iterator gsi; + vec *exception_types; + + FOR_EACH_BB_FN (bb, fun) + { + bb->aux = (void*)1; + gsi = gsi_last_bb (bb); + gimple *stmt = gsi_stmt (gsi); + vec *ret_vector; + + if (stmt_can_throw_external (stmt)){ + if (gimple_code (stmt) == GIMPLE_RESX){ + extract_types_for_resx (stmt, ret_vector); + } + + else if (gimple_code (stmt) == GIMPLE_CALL){ + extract_types_for_call (as_a (stmt), ret_vector); + } + } + + for (unsigned i = 0;ilength ();++i){ + tree type = (*ret_vector)[i]; + exception_types->safe_push (type); + } + } +} + /* Return true if statement STMT within FUN could throw an exception. */ bool
[gcc/devel/nothrow-detection] Added functions extract_fun_resx_types
https://gcc.gnu.org/g:5f1a438ba69b855103cec32eecde60fd7e4415b0 commit 5f1a438ba69b855103cec32eecde60fd7e4415b0 Author: Pranil Dey Date: Tue Oct 1 10:00:59 2024 +0530 Added functions extract_fun_resx_types Diff: --- gcc/tree-eh.cc | 138 + 1 file changed, 138 insertions(+) diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc index 8e7629164b7d..89640c0faf6d 100644 --- a/gcc/tree-eh.cc +++ b/gcc/tree-eh.cc @@ -49,6 +49,8 @@ along with GCC; see the file COPYING3. If not see #include "gimplify.h" #include "print-tree.h" #include "ipa-utils.h" +#include "print-tree.h" +#include "ipa-utils.h" #include "hash-set.h" /* In some instances a tree and a gimple need to be stored in a same table, @@ -2275,6 +2277,106 @@ make_eh_dispatch_edges (geh_dispatch *stmt) } bool same_or_derived_type (tree t1, tree t2) +{ + t1 = TYPE_MAIN_VARIANT (t1); + t2 = TYPE_MAIN_VARIANT (t2); + if (t1 == t2) +return true; + while ((TREE_CODE (t1) == POINTER_TYPE || TREE_CODE (t1) == REFERENCE_TYPE) +&& TREE_CODE (t1) == TREE_CODE (t2)) + { +t1 = TYPE_MAIN_VARIANT (TREE_TYPE (t1)); +t2 = TYPE_MAIN_VARIANT (TREE_TYPE (t2)); + } + if (t1 == t2) +return true; + if (!AGGREGATE_TYPE_P (t1) || !AGGREGATE_TYPE_P (t2)) +return false; + return odr_equivalent_or_derived_p (t1, t2); +} + +// Check if a landing pad can handle any of the given exception types +bool match_lp(eh_landing_pad lp, vec *exception_types) { +eh_region region = lp->region; + +// Ensure the region is of type ERT_TRY +if (region && region->type == ERT_TRY) { +eh_catch_d *catch_handler = region->u.eh_try.first_catch; + +while (catch_handler) { +tree type_list = catch_handler->type_list; + + if (!type_list) + return true; + +for (tree t = type_list; t; t = TREE_CHAIN(t)) { +tree type = TREE_VALUE(t); +for (unsigned i = 0; i < exception_types->length(); ++i) { + // match found or a catch-all handler (NULL) +if (!type || same_or_derived_type ((*exception_types)[i], type)) { +return true; +} +} +} +catch_handler = catch_handler->next_catch; +} +} +return false; +} + +// Function to update landing pad in throw_stmt_table for a given statement +void update_stmt_eh_region(gimple *stmt) { + auto_vec exception_types; + if (!stmt_throw_types (cfun, stmt, &exception_types)) { +return; +} + +int lp_nr = lookup_stmt_eh_lp_fn(cfun, stmt); +if (lp_nr <= 0) { +return; +} + +eh_landing_pad lp = get_eh_landing_pad_from_number(lp_nr); +if (!lp) { +return; +} + +eh_region region = lp->region; + +// Walk up the region tree +while (region) { +switch (region->type) { +case ERT_CLEANUP: +*cfun->eh->throw_stmt_table->get(const_cast(stmt)) = lp->index; +return; + +case ERT_TRY: +if (match_lp(lp, &exception_types)) { +*cfun->eh->throw_stmt_table->get(const_cast(stmt)) = lp->index; +return; +} +break; + +case ERT_MUST_NOT_THROW: +// Undefined behavior, leave edge unchanged +return; + +case ERT_ALLOWED_EXCEPTIONS: +if (!match_lp(lp, &exception_types)) { +return; +} +break; + +default: +break; +} +region = region->outer; +} + +remove_stmt_from_eh_lp_fn(cfun, stmt); +} +bool +same_or_derived_type (tree t1, tree t2) { t1 = TYPE_MAIN_VARIANT (t1); t2 = TYPE_MAIN_VARIANT (t2); @@ -3029,6 +3131,42 @@ stmt_could_throw_1_p (gassign *stmt) return false; } +void extract_exception_types_for_call (gcall *call_stmt, vec *ret_vector) { +tree callee = gimple_call_fndecl (call_stmt); +if (callee == NULL_TREE) { +return; + } + if (strcmp (IDENTIFIER_POINTER (DECL_NAME (callee)), "__cxa_throw") == 0) { + // Extracting exception type + tree exception_type_info = gimple_call_arg (call_stmt, 1); + if (exception_type_info && TREE_CODE (exception_type_info) == ADDR_EXPR) { + exception_type_info = TREE_OPERAND (exception_type_info, 0); + } + if (exception_type_info && TREE_CODE (exception_type_info) == VAR_DECL) { + // Converting the typeinfo to a compile-time type + tree exception_type = TREE_TYPE (exception_type_info); + if (exception_type) { + ret_vector->safe_push (exception_type); + } + } + } +} + +// Determine which types can be thrown by a GIMPLE statement and convert them to compile-time types +bool stmt_th
[gcc/devel/nothrow-detection] Added some functions and fixed some testcase failures
https://gcc.gnu.org/g:ba70ece43622eb4da97455fb78c42c7e9c7f8ce6 commit ba70ece43622eb4da97455fb78c42c7e9c7f8ce6 Author: Pranil Dey Date: Sun Aug 25 01:25:26 2024 +0530 Added some functions and fixed some testcase failures 1. odr_equivalent_or_derived_p in ipa-devirt.cc 2. same_or_derived_type in in tree-eh.cc 3. Fixed catch-all handling in match_lp function Diff: --- gcc/ipa-devirt.cc | 24 gcc/ipa-utils.h | 1 + gcc/tree-eh.cc| 27 ++- 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/gcc/ipa-devirt.cc b/gcc/ipa-devirt.cc index a7ce434bffb4..17271b089b74 100644 --- a/gcc/ipa-devirt.cc +++ b/gcc/ipa-devirt.cc @@ -1211,6 +1211,30 @@ skip_in_fields_list_p (tree t) return false; } +/* Return true if T2 is derived form T1. */ + +bool +odr_equivalent_or_derived_p (tree t1, tree t2) +{ + if (in_lto_p) +{ + if (odr_types_equivalent_p (t1, t2)) + return true; +} + else +{ + if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2)) + return true; +} + if (!TYPE_BINFO (t2)) +return false; + for (unsigned int i = 0; i < BINFO_N_BASE_BINFOS (TYPE_BINFO (t2)); i++) +if (odr_equivalent_or_derived_p +(t1, BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (t2), i +return true; + return false; +} + /* Compare T1 and T2, report ODR violations if WARN is true and set WARNED to true if anything is reported. Return true if types match. If true is returned, the types are also compatible in the sense of diff --git a/gcc/ipa-utils.h b/gcc/ipa-utils.h index d1da9c31e09e..908b425e98c5 100644 --- a/gcc/ipa-utils.h +++ b/gcc/ipa-utils.h @@ -106,6 +106,7 @@ cgraph_node *try_speculative_devirtualization (tree, HOST_WIDE_INT, void warn_types_mismatch (tree t1, tree t2, location_t loc1 = UNKNOWN_LOCATION, location_t loc2 = UNKNOWN_LOCATION); bool odr_or_derived_type_p (const_tree t); +bool odr_equivalent_or_derived_p (tree t1, tree t2); bool odr_types_equivalent_p (tree type1, tree type2); bool odr_type_violation_reported_p (tree type); tree prevailing_odr_type (tree type); diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc index eec1e6af70d7..4d541b08c2fc 100644 --- a/gcc/tree-eh.cc +++ b/gcc/tree-eh.cc @@ -47,6 +47,8 @@ along with GCC; see the file COPYING3. If not see #include "attribs.h" #include "asan.h" #include "gimplify.h" +#include "print-tree.h" +#include "ipa-utils.h" /* In some instances a tree and a gimple need to be stored in a same table, i.e. in hash tables. This is a structure to do this. */ @@ -2270,6 +2272,25 @@ make_eh_dispatch_edges (geh_dispatch *stmt) return true; } +bool +same_or_derived_type (tree t1, tree t2) +{ + t1 = TYPE_MAIN_VARIANT (t1); + t2 = TYPE_MAIN_VARIANT (t2); + if (t1 == t2) +return true; + while ((TREE_CODE (t1) == POINTER_TYPE || TREE_CODE (t1) == REFERENCE_TYPE) +&& TREE_CODE (t1) == TREE_CODE (t2)) + { +t1 = TYPE_MAIN_VARIANT (TREE_TYPE (t1)); +t2 = TYPE_MAIN_VARIANT (TREE_TYPE (t2)); + } + if (t1 == t2) +return true; + if (!AGGREGATE_TYPE_P (t1) || !AGGREGATE_TYPE_P (t2)) +return false; + return odr_equivalent_or_derived_p (t1, t2); +} // Check if a landing pad can handle any of the given exception types bool match_lp(eh_landing_pad lp, vec *exception_types) { @@ -2282,11 +2303,15 @@ bool match_lp(eh_landing_pad lp, vec *exception_types) { while (catch_handler) { tree type_list = catch_handler->type_list; +if(type_list == NULL) { +return true; +} + for (tree t = type_list; t; t = TREE_CHAIN(t)) { tree type = TREE_VALUE(t); for (unsigned i = 0; i < exception_types->length(); ++i) { // match found or a catch-all handler (NULL) -if (type == (*exception_types)[i] || !type) { +if (!type || same_or_derived_type ((*exception_types)[i], type)) { return true; } }
[gcc/devel/nothrow-detection] Updated parameters of functions and typecasted resx stmts
https://gcc.gnu.org/g:079ca47d41e5030c63cca7f8ee679e7323a26d45 commit 079ca47d41e5030c63cca7f8ee679e7323a26d45 Author: Pranil Dey Date: Tue Oct 1 09:46:48 2024 +0530 Updated parameters of functions and typecasted resx stmts Diff: --- gcc/tree-eh.cc | 23 +-- gcc/tree-eh.h | 2 +- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc index ea9a2ca6bb00..8e7629164b7d 100644 --- a/gcc/tree-eh.cc +++ b/gcc/tree-eh.cc @@ -2346,18 +2346,20 @@ void update_stmt_eh_region (gimple *stmt) { while (region) { switch (region->type) { case ERT_CLEANUP: -if(gimple_code (stmt) == GIMPLE_RESX){ - gimple_resx_set_region(stmt, region->index); +if (gimple_code (stmt) == GIMPLE_RESX){ + gresx *resx_stmt = as_a (stmt); + gimple_resx_set_region (resx_stmt, region->index); } -*cfun->eh->throw_stmt_table->get (const_cast (stmt)) = lp->index; +else *cfun->eh->throw_stmt_table->get (const_cast (stmt)) = lp->index; return; case ERT_TRY: if (match_lp (lp, &exception_types)) { - if(gimple_code (stmt) == GIMPLE_RESX){ -gimple_resx_set_region(stmt, region->index); + if (gimple_code (stmt) == GIMPLE_RESX){ +gresx *resx_stmt = as_a (stmt); +gimple_resx_set_region (resx_stmt, region->index); } - *cfun->eh->throw_stmt_table->get (const_cast (stmt)) = lp->index; + else *cfun->eh->throw_stmt_table->get (const_cast (stmt)) = lp->index; return; } break; @@ -2378,8 +2380,9 @@ void update_stmt_eh_region (gimple *stmt) { region = region->outer; } -if(gimple_code (stmt) == GIMPLE_RESX){ - gimple_resx_set_region(stmt, -1); +if (gimple_code (stmt) == GIMPLE_RESX){ + gresx *resx_stmt = as_a (stmt); + gimple_resx_set_region (resx_stmt, 0); } else remove_stmt_from_eh_lp_fn (cfun, stmt); } @@ -3075,7 +3078,7 @@ void extract_types_for_resx (gimple *resx_stmt, vec *ret_vector) { basic_block bb = gimple_bb (resx_stmt); // Iterate over edges to walk up the basic blocks - FOR_EACH_EDGE (e, ei, bb->pred) + FOR_EACH_EDGE (e, ei, bb->preds) { // Get the last stmt of the basic block as it is an EH stmt bb = e->src; @@ -3115,7 +3118,7 @@ void extract_fun_resx_types (function *fun, vec *ret_vector) { gimple *stmt = gsi_stmt (gsi); vec *ret_vector; - if (stmt_can_throw_external (stmt)){ + if (stmt_can_throw_external (fun, stmt)){ if (gimple_code (stmt) == GIMPLE_RESX){ extract_types_for_resx (stmt, ret_vector); } diff --git a/gcc/tree-eh.h b/gcc/tree-eh.h index ea5cefc9fd29..4d816fd93c85 100644 --- a/gcc/tree-eh.h +++ b/gcc/tree-eh.h @@ -44,7 +44,7 @@ extern tree rewrite_to_non_trapping_overflow (tree); extern void extract_exception_types_for_call (gcall *, vec *); extern bool stmt_throw_types (function *, gimple *, vec *); extern void extract_types_for_resx (gimple *, vec *); -extern void extract_fun_resx_types (function *); +extern void extract_fun_resx_types (function *, vec *); extern bool stmt_could_throw_p (function *, gimple *); extern bool stmt_unremovable_because_of_non_call_eh_p (function *, gimple *); extern bool tree_could_throw_p (tree);
[gcc/devel/nothrow-detection] Reolved some conflicts
https://gcc.gnu.org/g:97933e95963b2d91da147fb9e1639434f9a7a049 commit 97933e95963b2d91da147fb9e1639434f9a7a049 Author: Pranil Dey Date: Tue Oct 1 10:03:43 2024 +0530 Reolved some conflicts Diff: --- gcc/tree-eh.cc | 36 1 file changed, 36 deletions(-) diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc index 89640c0faf6d..6ed705d6ebe9 100644 --- a/gcc/tree-eh.cc +++ b/gcc/tree-eh.cc @@ -3131,42 +3131,6 @@ stmt_could_throw_1_p (gassign *stmt) return false; } -void extract_exception_types_for_call (gcall *call_stmt, vec *ret_vector) { -tree callee = gimple_call_fndecl (call_stmt); -if (callee == NULL_TREE) { -return; - } - if (strcmp (IDENTIFIER_POINTER (DECL_NAME (callee)), "__cxa_throw") == 0) { - // Extracting exception type - tree exception_type_info = gimple_call_arg (call_stmt, 1); - if (exception_type_info && TREE_CODE (exception_type_info) == ADDR_EXPR) { - exception_type_info = TREE_OPERAND (exception_type_info, 0); - } - if (exception_type_info && TREE_CODE (exception_type_info) == VAR_DECL) { - // Converting the typeinfo to a compile-time type - tree exception_type = TREE_TYPE (exception_type_info); - if (exception_type) { - ret_vector->safe_push (exception_type); - } - } - } -} - -// Determine which types can be thrown by a GIMPLE statement and convert them to compile-time types -bool stmt_throw_types (function *fun, gimple *stmt, vec *ret_vector) { -if (!flag_exceptions) { -return false; -} - -switch (gimple_code (stmt)) { -case GIMPLE_CALL: -extract_exception_types_for_call (as_a (stmt), ret_vector); -return !ret_vector->is_empty (); - -default: -return false; -} -} void extract_types_for_call (gcall *call_stmt, vec *ret_vector) { tree callee = gimple_call_fndecl (call_stmt); if (callee == NULL_TREE) {
[gcc/devel/nothrow-detection] Merge remote-tracking branch 'origin/devel/nothrow-detection' into devel/nothrow-detection
https://gcc.gnu.org/g:6db81730ef66c0f557b78c9a67a33b6eec2f040e commit 6db81730ef66c0f557b78c9a67a33b6eec2f040e Merge: 079ca47d41e5 b602de4ed9f8 Author: Pranil Dey Date: Tue Oct 1 10:00:26 2024 +0530 Merge remote-tracking branch 'origin/devel/nothrow-detection' into devel/nothrow-detection Diff: gcc/ipa-devirt.cc | 4 ++-- gcc/tree-eh.h | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --cc gcc/tree-eh.h index 4d816fd93c85,f3b2c16ed77e..4fa134b43ddc --- a/gcc/tree-eh.h +++ b/gcc/tree-eh.h @@@ -23,6 -23,6 +23,7 @@@ along with GCC; see the file COPYING3 typedef struct eh_region_d *eh_region; typedef struct eh_landing_pad_d *eh_landing_pad; ++typedef struct eh_landing_pad_d *eh_landing_pad; extern void using_eh_for_cleanups (void); extern void add_stmt_to_eh_lp (gimple *, int); @@@ -33,6 -33,6 +34,8 @@@ extern int lookup_stmt_eh_lp (const gim extern bool make_eh_dispatch_edges (geh_dispatch *); extern bool match_lp (eh_landing_pad, vec *); extern void update_stmt_eh_region(gimple *); ++extern bool match_lp (eh_landing_pad, vec *); ++extern void update_stmt_eh_region(gimple *); extern edge make_eh_edge (gimple *); extern edge redirect_eh_edge (edge, basic_block); extern void redirect_eh_dispatch_edge (geh_dispatch *, edge, basic_block);
[gcc/devel/nothrow-detection] Added the previous functions to the tree-eh.h file
https://gcc.gnu.org/g:47c2d0f6e02b3aed9f0cdbb27ae62bff4e707390 commit 47c2d0f6e02b3aed9f0cdbb27ae62bff4e707390 Author: Pranil Dey Date: Sat Sep 21 03:13:43 2024 +0530 Added the previous functions to the tree-eh.h file Functions added: 1. void extract_types_for_resx (gimple *, vec *); 2. void extract_fun_resx_types (function *); Diff: --- gcc/tree-eh.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gcc/tree-eh.h b/gcc/tree-eh.h index f3b2c16ed77e..ea5cefc9fd29 100644 --- a/gcc/tree-eh.h +++ b/gcc/tree-eh.h @@ -43,6 +43,8 @@ extern bool tree_could_trap_p (tree); extern tree rewrite_to_non_trapping_overflow (tree); extern void extract_exception_types_for_call (gcall *, vec *); extern bool stmt_throw_types (function *, gimple *, vec *); +extern void extract_types_for_resx (gimple *, vec *); +extern void extract_fun_resx_types (function *); extern bool stmt_could_throw_p (function *, gimple *); extern bool stmt_unremovable_because_of_non_call_eh_p (function *, gimple *); extern bool tree_could_throw_p (tree);
[gcc/devel/nothrow-detection] removed conflicts
https://gcc.gnu.org/g:5a924600ea2f5fc3aee95385117ffaf492fa9203 commit 5a924600ea2f5fc3aee95385117ffaf492fa9203 Author: Pranil Dey Date: Tue Oct 1 10:10:17 2024 +0530 removed conflicts Diff: --- gcc/tree-eh.cc | 99 -- 1 file changed, 99 deletions(-) diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc index 6ed705d6ebe9..37eb6081eca9 100644 --- a/gcc/tree-eh.cc +++ b/gcc/tree-eh.cc @@ -2275,106 +2275,7 @@ make_eh_dispatch_edges (geh_dispatch *stmt) return true; } -bool -same_or_derived_type (tree t1, tree t2) -{ - t1 = TYPE_MAIN_VARIANT (t1); - t2 = TYPE_MAIN_VARIANT (t2); - if (t1 == t2) -return true; - while ((TREE_CODE (t1) == POINTER_TYPE || TREE_CODE (t1) == REFERENCE_TYPE) -&& TREE_CODE (t1) == TREE_CODE (t2)) - { -t1 = TYPE_MAIN_VARIANT (TREE_TYPE (t1)); -t2 = TYPE_MAIN_VARIANT (TREE_TYPE (t2)); - } - if (t1 == t2) -return true; - if (!AGGREGATE_TYPE_P (t1) || !AGGREGATE_TYPE_P (t2)) -return false; - return odr_equivalent_or_derived_p (t1, t2); -} - -// Check if a landing pad can handle any of the given exception types -bool match_lp(eh_landing_pad lp, vec *exception_types) { -eh_region region = lp->region; - -// Ensure the region is of type ERT_TRY -if (region && region->type == ERT_TRY) { -eh_catch_d *catch_handler = region->u.eh_try.first_catch; - -while (catch_handler) { -tree type_list = catch_handler->type_list; - - if (!type_list) - return true; - -for (tree t = type_list; t; t = TREE_CHAIN(t)) { -tree type = TREE_VALUE(t); -for (unsigned i = 0; i < exception_types->length(); ++i) { - // match found or a catch-all handler (NULL) -if (!type || same_or_derived_type ((*exception_types)[i], type)) { -return true; -} -} -} -catch_handler = catch_handler->next_catch; -} -} -return false; -} - -// Function to update landing pad in throw_stmt_table for a given statement -void update_stmt_eh_region(gimple *stmt) { - auto_vec exception_types; - if (!stmt_throw_types (cfun, stmt, &exception_types)) { -return; -} - -int lp_nr = lookup_stmt_eh_lp_fn(cfun, stmt); -if (lp_nr <= 0) { -return; -} - -eh_landing_pad lp = get_eh_landing_pad_from_number(lp_nr); -if (!lp) { -return; -} - -eh_region region = lp->region; - -// Walk up the region tree -while (region) { -switch (region->type) { -case ERT_CLEANUP: -*cfun->eh->throw_stmt_table->get(const_cast(stmt)) = lp->index; -return; -case ERT_TRY: -if (match_lp(lp, &exception_types)) { -*cfun->eh->throw_stmt_table->get(const_cast(stmt)) = lp->index; -return; -} -break; - -case ERT_MUST_NOT_THROW: -// Undefined behavior, leave edge unchanged -return; - -case ERT_ALLOWED_EXCEPTIONS: -if (!match_lp(lp, &exception_types)) { -return; -} -break; - -default: -break; -} -region = region->outer; -} - -remove_stmt_from_eh_lp_fn(cfun, stmt); -} bool same_or_derived_type (tree t1, tree t2) {
[gcc/devel/nothrow-detection] Integrated the resx functions with stmt_throw_types
https://gcc.gnu.org/g:7ec787200301f75109c41d7c4a82891971dbd62b commit 7ec787200301f75109c41d7c4a82891971dbd62b Author: Pranil Dey Date: Mon Sep 30 18:39:14 2024 +0530 Integrated the resx functions with stmt_throw_types update_stmt_eh_region updated for resx stmt support and extract_fun_resx_types fixed Diff: --- gcc/tree-eh.cc | 34 +++--- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc index 121cbed505b8..ea9a2ca6bb00 100644 --- a/gcc/tree-eh.cc +++ b/gcc/tree-eh.cc @@ -49,6 +49,7 @@ along with GCC; see the file COPYING3. If not see #include "gimplify.h" #include "print-tree.h" #include "ipa-utils.h" +#include "hash-set.h" /* In some instances a tree and a gimple need to be stored in a same table, i.e. in hash tables. This is a structure to do this. */ @@ -2345,13 +2346,19 @@ void update_stmt_eh_region (gimple *stmt) { while (region) { switch (region->type) { case ERT_CLEANUP: +if(gimple_code (stmt) == GIMPLE_RESX){ + gimple_resx_set_region(stmt, region->index); +} *cfun->eh->throw_stmt_table->get (const_cast (stmt)) = lp->index; return; case ERT_TRY: if (match_lp (lp, &exception_types)) { -*cfun->eh->throw_stmt_table->get (const_cast (stmt)) = lp->index; -return; + if(gimple_code (stmt) == GIMPLE_RESX){ +gimple_resx_set_region(stmt, region->index); + } + *cfun->eh->throw_stmt_table->get (const_cast (stmt)) = lp->index; + return; } break; @@ -2371,7 +2378,10 @@ void update_stmt_eh_region (gimple *stmt) { region = region->outer; } -remove_stmt_from_eh_lp_fn (cfun, stmt); +if(gimple_code (stmt) == GIMPLE_RESX){ + gimple_resx_set_region(stmt, -1); +} +else remove_stmt_from_eh_lp_fn (cfun, stmt); } /* Create the single EH edge from STMT to its nearest landing pad, @@ -3044,10 +3054,14 @@ bool stmt_throw_types (function *fun, gimple *stmt, vec *ret_vector) { } switch (gimple_code (stmt)) { +case GIMPLE_RESX: +extract_fun_resx_types (fun, ret_vector); +return !ret_vector->is_empty (); + case GIMPLE_CALL: extract_types_for_call (as_a (stmt), ret_vector); return !ret_vector->is_empty (); - + default: return false; } @@ -3089,10 +3103,10 @@ void extract_types_for_resx (gimple *resx_stmt, vec *ret_vector) { } // To get the types being thrown outside of a function -void extract_fun_resx_types (function *fun){ +void extract_fun_resx_types (function *fun, vec *ret_vector) { basic_block bb; gimple_stmt_iterator gsi; - vec *exception_types; + hash_set *types; FOR_EACH_BB_FN (bb, fun) { @@ -3113,9 +3127,15 @@ void extract_fun_resx_types (function *fun){ for (unsigned i = 0;ilength ();++i){ tree type = (*ret_vector)[i]; - exception_types->safe_push (type); + types->add (type); } } + + for (auto it = types->begin(); it != types->end(); ++it) { +ret_vector->safe_push(*it); + } + + clear_aux_for_blocks (); } /* Return true if statement STMT within FUN could throw an exception. */
[gcc/devel/nothrow-detection] resolved more conflicts
https://gcc.gnu.org/g:27be11a6b2fe5c91f60460e01c30ca5c4fddf58a commit 27be11a6b2fe5c91f60460e01c30ca5c4fddf58a Author: Pranil Dey Date: Tue Oct 1 10:12:35 2024 +0530 resolved more conflicts Diff: --- gcc/tree-eh.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/gcc/tree-eh.h b/gcc/tree-eh.h index 4fa134b43ddc..978bc6228bf0 100644 --- a/gcc/tree-eh.h +++ b/gcc/tree-eh.h @@ -34,8 +34,6 @@ extern int lookup_stmt_eh_lp (const gimple *); extern bool make_eh_dispatch_edges (geh_dispatch *); extern bool match_lp (eh_landing_pad, vec *); extern void update_stmt_eh_region(gimple *); -extern bool match_lp (eh_landing_pad, vec *); -extern void update_stmt_eh_region(gimple *); extern edge make_eh_edge (gimple *); extern edge redirect_eh_edge (edge, basic_block); extern void redirect_eh_dispatch_edge (geh_dispatch *, edge, basic_block);
[gcc/devel/nothrow-detection] Edge redirection for exceptions.
https://gcc.gnu.org/g:9a70651a2126e4aceefd2ebec63c0cf15ce83695 commit 9a70651a2126e4aceefd2ebec63c0cf15ce83695 Author: Pranil Dey Date: Tue Aug 20 22:07:57 2024 +0530 Edge redirection for exceptions. This commit is contains change in code for the tree-eh.cc, tree-eh.h, MAINTAINERS and tree-cfg.cc files. Specifically it contains four functions - 1. void extract_exception_types_for_call which extracts the exception types in a call stmt and adds them into a vector tree. 2. bool stmt_throw_types does the same as stmt_could_throw the difference being that it also gives the list of exception types as given by the extract_exception_types_for_call function. 3. bool match_lp checks if a landing pad can handle any of the exception types given as input parameters by looking into the catch handlers. 4. update_stmt_eh_region is the function that walks up the EH tree and changes the landing pad for the last statement in a basic block in the control flow graph so that when the edge by make_eh_edge is created it points to the correct handlers. Further work to be done regarding RESX stmts. Diff: --- gcc/tree-cfg.cc | 5 ++- gcc/tree-eh.cc | 114 gcc/tree-eh.h | 5 +++ 3 files changed, 122 insertions(+), 2 deletions(-) diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc index fcb488d87113..964376d30dcc 100644 --- a/gcc/tree-cfg.cc +++ b/gcc/tree-cfg.cc @@ -855,11 +855,12 @@ make_edges_bb (basic_block bb, struct omp_region **pcur_region, int *pomp_index) if (!last) return ret; - + + update_stmt_eh_region(last); switch (gimple_code (last)) { case GIMPLE_GOTO: - if (make_goto_expr_edges (bb)) + if (make_goto_expr_edges (bb)) ret = 1; fallthru = false; break; diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc index 9609bdc0d9b7..eec1e6af70d7 100644 --- a/gcc/tree-eh.cc +++ b/gcc/tree-eh.cc @@ -2271,6 +2271,84 @@ make_eh_dispatch_edges (geh_dispatch *stmt) return true; } +// Check if a landing pad can handle any of the given exception types +bool match_lp(eh_landing_pad lp, vec *exception_types) { +eh_region region = lp->region; + +// Ensure the region is of type ERT_TRY +if (region && region->type == ERT_TRY) { +eh_catch_d *catch_handler = region->u.eh_try.first_catch; + +while (catch_handler) { +tree type_list = catch_handler->type_list; + +for (tree t = type_list; t; t = TREE_CHAIN(t)) { +tree type = TREE_VALUE(t); +for (unsigned i = 0; i < exception_types->length(); ++i) { + // match found or a catch-all handler (NULL) +if (type == (*exception_types)[i] || !type) { +return true; +} +} +} +catch_handler = catch_handler->next_catch; +} +} +return false; +} + +// Function to update landing pad in throw_stmt_table for a given statement +void update_stmt_eh_region(gimple *stmt) { + auto_vec exception_types; + if (!stmt_throw_types (cfun, stmt, &exception_types)) { +return; +} + +int lp_nr = lookup_stmt_eh_lp_fn(cfun, stmt); +if (lp_nr <= 0) { +return; +} + +eh_landing_pad lp = get_eh_landing_pad_from_number(lp_nr); +if (!lp) { +return; +} + +eh_region region = lp->region; + +// Walk up the region tree +while (region) { +switch (region->type) { +case ERT_CLEANUP: +*cfun->eh->throw_stmt_table->get(const_cast(stmt)) = lp->index; +return; + +case ERT_TRY: +if (match_lp(lp, &exception_types)) { +*cfun->eh->throw_stmt_table->get(const_cast(stmt)) = lp->index; +return; +} +break; + +case ERT_MUST_NOT_THROW: +// Undefined behavior, leave edge unchanged +return; + +case ERT_ALLOWED_EXCEPTIONS: +if (!match_lp(lp, &exception_types)) { +return; +} +break; + +default: +break; +} +region = region->outer; +} + +remove_stmt_from_eh_lp_fn(cfun, stmt); +} + /* Create the single EH edge from STMT to its nearest landing pad, if there is such a landing pad within the current function. */ @@ -2913,6 +2991,42 @@ stmt_could_throw_1_p (gassign *stmt) return false; } +void extract_exception_types_for_call (gcall *call_stmt, vec *ret_vector) { +tree callee = gimple_call_fndecl (call_stmt); +if (callee == NULL_TREE) { +return; + } + if (strcmp (IDENTIFIER_POINTER (DECL_NAME (callee)), "__cxa_throw") == 0) { + // Extracting exception type + tree exception_type_info = gimple_call_arg (call_stmt, 1); +
[gcc/devel/nothrow-detection] (34 commits) Reolved some conflicts
The branch 'devel/nothrow-detection' was updated to point to: 97933e95963b... Reolved some conflicts It previously pointed to: b602de4ed9f8... Merge branch 'master' of git+ssh://gcc.gnu.org/git/gcc into Diff: Summary of changes (added commits): --- 97933e9... Reolved some conflicts 5f1a438... Added functions extract_fun_resx_types 6db8173... Merge remote-tracking branch 'origin/devel/nothrow-detectio 079ca47... Updated parameters of functions and typecasted resx stmts 7ec7872... Integrated the resx functions with stmt_throw_types 47c2d0f... Added the previous functions to the tree-eh.h file d1a84d3... RESX statement processing functions added: 70505f5... Fixed some indentations and function names ba70ece... Added some functions and fixed some testcase failures 9a70651... Edge redirection for exceptions. 0939c8c... Daily bump. (*) b1696ff... libstdc++-v3: Fix signed-overflow warning for newlib/ctype_ (*) ab07db3... [testcase] Fix-absfloat16.c-testcase (*) 4bcfaae... c++: concept in default argument [PR109859] (*) 65073a5... Fix internal error during inlining after ICF pass (*) 9c14f9a... diagnostics: return text buffer from test_show_locus [PR116 (*) e7a8fbe... diagnostics: require callers of diagnostic_show_locus to be (*) be02253... diagnostics: isolate diagnostic_context with interface clas (*) cce5286... diagnostics: avoid using diagnostic_context's m_printer [PR (*) 3d3d20c... diagnostics: use "%e" to avoid intermediate strings [PR1166 (*) 4c7a58a... diagnostics: add "dump" to pretty_printer and output_buffer (*) 3286b67... diagnostics: fix typo in XHTML output [PR116792] (*) ab6c7a3... diagnostics: fix memory leak in SARIF selftests (*) 8398ef9... autovectorizer: Test autovectorization of different dot-pro (*) fd35d99... c6x: Adjust dot-product backend patterns (*) 113e31c... rs6000: Adjust altivec dot-product backend patterns (*) d33786b... mips: Adjust dot-product backend patterns (*) 85a2ed0... arc: Adjust dot-product backend patterns (*) c45ef5e... i386: Fix dot_prod backend patterns for mmx and sse targets (*) bfa44e6... arm: Fix arm backend-use of (u|s|us)dot_prod patterns (*) 0d0be1d... aarch64: Fix aarch64 backend-use of (u|s|us)dot_prod patter (*) c7fba0e... autovectorizer: Add basic support for convert optabs (*) 2f68d69... optabs: Make all `*dot_prod_optab's modeled as conversions (*) 18e905b... tree-optimization/116879 - failure to recognize non-empty l (*) (*) This commit already exists in another branch. Because the reference `refs/heads/devel/nothrow-detection' matches your hooks.email-new-commits-only configuration, no separate email is sent for this commit.
[gcc/devel/nothrow-detection] Updated tree-eh.h
https://gcc.gnu.org/g:132a0acfde7975c0b6f74b6a456ecc8ed46face4 commit 132a0acfde7975c0b6f74b6a456ecc8ed46face4 Author: Pranil Dey Date: Tue Oct 1 10:32:27 2024 +0530 Updated tree-eh.h Diff: --- gcc/tree-eh.h | 1 + 1 file changed, 1 insertion(+) diff --git a/gcc/tree-eh.h b/gcc/tree-eh.h index 978bc6228bf0..618375313ec7 100644 --- a/gcc/tree-eh.h +++ b/gcc/tree-eh.h @@ -32,6 +32,7 @@ extern bool remove_stmt_from_eh_lp (gimple *); extern int lookup_stmt_eh_lp_fn (struct function *, const gimple *); extern int lookup_stmt_eh_lp (const gimple *); extern bool make_eh_dispatch_edges (geh_dispatch *); +extern bool same_or_derived_type (tree, tree); extern bool match_lp (eh_landing_pad, vec *); extern void update_stmt_eh_region(gimple *); extern edge make_eh_edge (gimple *);
[gcc/devel/nothrow-detection] Added code for inserting regions
https://gcc.gnu.org/g:1a736e25705f0b15ee4bd1994fe587bb809c7bcb commit 1a736e25705f0b15ee4bd1994fe587bb809c7bcb Author: Pranil Dey Date: Tue Oct 1 19:50:42 2024 +0530 Added code for inserting regions Diff: --- gcc/tree-eh.cc | 51 +-- gcc/tree-eh.h | 2 ++ 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc index 37eb6081eca9..3723b6672bf2 100644 --- a/gcc/tree-eh.cc +++ b/gcc/tree-eh.cc @@ -2283,7 +2283,7 @@ same_or_derived_type (tree t1, tree t2) t2 = TYPE_MAIN_VARIANT (t2); if (t1 == t2) return true; - while ((TREE_CODE (t1) == POINTER_TYPE || TREE_CODE (t1) == REFERENCE_TYPE) + while ( (TREE_CODE (t1) == POINTER_TYPE || TREE_CODE (t1) == REFERENCE_TYPE) && TREE_CODE (t1) == TREE_CODE (t2)) { t1 = TYPE_MAIN_VARIANT (TREE_TYPE (t1)); @@ -2326,6 +2326,29 @@ bool match_lp (eh_landing_pad lp, vec *exception_types) { return false; } +void unlink_eh_region (eh_region region, eh_region prev_region) { +if (region->outer && region->outer->inner == region) { +region->outer->inner = region->next_peer; +} +if (prev_region && prev_region->next_peer == region) { +prev_region->next_peer = region->next_peer; +} +region->next_peer = NULL; +region->outer = NULL; +} + +void reinsert_eh_region (eh_region region, eh_landing_pad lp) { +eh_region new_outer = lp->region->outer; +region->outer = new_outer; +if (new_outer) { +region->next_peer = new_outer->inner; +new_outer->inner = region; +} else { +region->next_peer = cfun->eh->region_tree; +cfun->eh->region_tree = region; +} +} + // Function to update landing pad in throw_stmt_table for a given statement void update_stmt_eh_region (gimple *stmt) { auto_vec exception_types; @@ -2344,6 +2367,7 @@ void update_stmt_eh_region (gimple *stmt) { } eh_region region = lp->region; +eh_region prev_region = NULL; // Walk up the region tree while (region) { @@ -2354,6 +2378,9 @@ void update_stmt_eh_region (gimple *stmt) { gimple_resx_set_region (resx_stmt, region->index); } else *cfun->eh->throw_stmt_table->get (const_cast (stmt)) = lp->index; + +unlink_eh_region (region, prev_region); +reinsert_eh_region (region, lp); return; case ERT_TRY: @@ -2363,6 +2390,9 @@ void update_stmt_eh_region (gimple *stmt) { gimple_resx_set_region (resx_stmt, region->index); } else *cfun->eh->throw_stmt_table->get (const_cast (stmt)) = lp->index; + + unlink_eh_region (region, prev_region); + reinsert_eh_region (region, lp); return; } break; @@ -2380,12 +2410,13 @@ void update_stmt_eh_region (gimple *stmt) { default: break; } +prev_region = region; region = region->outer; } if (gimple_code (stmt) == GIMPLE_RESX){ gresx *resx_stmt = as_a (stmt); - gimple_resx_set_region (resx_stmt, 0); + gimple_resx_set_region (resx_stmt, region->index); } else remove_stmt_from_eh_lp_fn (cfun, stmt); } @@ -3097,7 +3128,7 @@ void extract_types_for_resx (gimple *resx_stmt, vec *ret_vector) { extract_types_for_call (as_a (last_stmt), ret_vector); continue; } - else if (gimple_code(last_stmt) == GIMPLE_RESX){ + else if (gimple_code (last_stmt) == GIMPLE_RESX){ // Recursively processing resx extract_types_for_resx (last_stmt, ret_vector); continue; @@ -3119,26 +3150,26 @@ void extract_fun_resx_types (function *fun, vec *ret_vector) { bb->aux = (void*)1; gsi = gsi_last_bb (bb); gimple *stmt = gsi_stmt (gsi); - vec *ret_vector; + vec *resx_types; if (stmt_can_throw_external (fun, stmt)){ if (gimple_code (stmt) == GIMPLE_RESX){ - extract_types_for_resx (stmt, ret_vector); + extract_types_for_resx (stmt, resx_types); } else if (gimple_code (stmt) == GIMPLE_CALL){ - extract_types_for_call (as_a (stmt), ret_vector); + extract_types_for_call (as_a (stmt), resx_types); } } - for (unsigned i = 0;ilength ();++i){ - tree type = (*ret_vector)[i]; + for (unsigned i = 0;ilength ();++i){ + tree type = (*resx_types)[i]; types->add (type); } } - for (auto it = types->begin(); it != types->end(); ++it) {
[gcc/devel/nothrow-detection] Updated code for inserting regions and changed the return parameters of extract_types_for call
https://gcc.gnu.org/g:0d0df5179b80e808eb46c59ee1dd69138912e6fd commit 0d0df5179b80e808eb46c59ee1dd69138912e6fd Author: Pranil Dey Date: Thu Oct 3 10:11:07 2024 +0530 Updated code for inserting regions and changed the return parameters of extract_types_for call Diff: --- gcc/tree-eh.cc | 71 +- gcc/tree-eh.h | 2 +- 2 files changed, 41 insertions(+), 32 deletions(-) diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc index 3723b6672bf2..464a033dbf20 100644 --- a/gcc/tree-eh.cc +++ b/gcc/tree-eh.cc @@ -2337,9 +2337,11 @@ void unlink_eh_region (eh_region region, eh_region prev_region) { region->outer = NULL; } -void reinsert_eh_region (eh_region region, eh_landing_pad lp) { -eh_region new_outer = lp->region->outer; +void reinsert_eh_region(eh_region region, eh_landing_pad lp) { +eh_region new_outer = lp->region; region->outer = new_outer; + +// Insert region as the inner of new_outer, or at the top of the tree if (new_outer) { region->next_peer = new_outer->inner; new_outer->inner = region; @@ -2347,9 +2349,13 @@ void reinsert_eh_region (eh_region region, eh_landing_pad lp) { region->next_peer = cfun->eh->region_tree; cfun->eh->region_tree = region; } + +// Set the region index in the region array +region->index = vec_safe_length(cfun->eh->region_array); +vec_safe_push(cfun->eh->region_array, region); } -// Function to update landing pad in throw_stmt_table for a given statement +// Function to update landing pad and region in throw_stmt_table for a given statement void update_stmt_eh_region (gimple *stmt) { auto_vec exception_types; if (!stmt_throw_types (cfun, stmt, &exception_types)) { @@ -3063,24 +3069,26 @@ stmt_could_throw_1_p (gassign *stmt) return false; } -void extract_types_for_call (gcall *call_stmt, vec *ret_vector) { +bool extract_types_for_call (gcall *call_stmt, vec *ret_vector) { tree callee = gimple_call_fndecl (call_stmt); if (callee == NULL_TREE) { -return; - } - if (strcmp (IDENTIFIER_POINTER (DECL_NAME (callee)), "__cxa_throw") == 0) { - // Extracting exception type - tree exception_type_info = gimple_call_arg (call_stmt, 1); - if (exception_type_info && TREE_CODE (exception_type_info) == ADDR_EXPR) { - exception_type_info = TREE_OPERAND (exception_type_info, 0); - } - if (exception_type_info && TREE_CODE (exception_type_info) == VAR_DECL) { - // Converting the typeinfo to a compile-time type - tree exception_type = TREE_TYPE (exception_type_info); - if (exception_type) { - ret_vector->safe_push (exception_type); - } - } +return false; +} + +if (strcmp (IDENTIFIER_POINTER (DECL_NAME (callee)), "__cxa_throw") == 0) { +// Extracting exception type +tree exception_type_info = gimple_call_arg (call_stmt, 1); +if (exception_type_info && TREE_CODE (exception_type_info) == ADDR_EXPR) { +exception_type_info = TREE_OPERAND (exception_type_info, 0); +} +if (exception_type_info && TREE_CODE (exception_type_info) == VAR_DECL) { +// Converting the typeinfo to a compile-time type +tree exception_type = TREE_TYPE (exception_type_info); +if (exception_type) { + ret_vector->safe_push (exception_type); +} +} +return true; } } @@ -3096,8 +3104,9 @@ bool stmt_throw_types (function *fun, gimple *stmt, vec *ret_vector) { return !ret_vector->is_empty (); case GIMPLE_CALL: -extract_types_for_call (as_a (stmt), ret_vector); -return !ret_vector->is_empty (); +bool type_exists = false; +type_exists = extract_types_for_call (as_a (stmt), ret_vector); +return type_exists && !ret_vector->is_empty (); default: return false; @@ -3122,7 +3131,7 @@ void extract_types_for_resx (gimple *resx_stmt, vec *ret_vector) { if (bb->aux)continue; bb->aux = (void*)1; - if (e->flags & EDGE_EH){ + if (e->flags & EDGE_EH && last_stmt!= NULL){ if (gimple_code (last_stmt) == GIMPLE_CALL) { // check if its a throw extract_types_for_call (as_a (last_stmt), ret_vector); @@ -3143,32 +3152,32 @@ void extract_types_for_resx (gimple *resx_stmt, vec *ret_vector) { void extract_fun_resx_types (function *fun, vec *ret_vector) { basic_block bb; gimple_stmt_iterator gsi; - hash_set *types; + hash_set types; FOR_EACH_BB_FN (bb, fun) { bb->aux = (void*)1; gsi = gsi_last_bb (bb); gimple *stmt = gsi_stmt (gsi); - vec *resx_types; + auto_vec resx_types; -