[gcc(refs/users/aoliva/heads/testme)] hardcfr: add checking at exceptions and noreturn calls: tweaks
Alexandre Oliva
aoliva@gcc.gnu.org
Thu Aug 11 02:24:38 GMT 2022
https://gcc.gnu.org/g:c7e2b43a43de1c27ab9e797b87b7fc9c0499c28b
commit c7e2b43a43de1c27ab9e797b87b7fc9c0499c28b
Author: Alexandre Oliva <oliva@gnu.org>
Date: Wed Aug 10 22:56:28 2022 -0300
hardcfr: add checking at exceptions and noreturn calls: tweaks
Diff:
---
gcc/gimple-harden-control-flow.cc | 122 +++++++++++++++++++++-----------------
1 file changed, 67 insertions(+), 55 deletions(-)
diff --git a/gcc/gimple-harden-control-flow.cc b/gcc/gimple-harden-control-flow.cc
index 5066a43fe6c..235f19c6548 100644
--- a/gcc/gimple-harden-control-flow.cc
+++ b/gcc/gimple-harden-control-flow.cc
@@ -729,10 +729,12 @@ public:
unsigned int
pass_harden_control_flow_redundancy::execute (function *fun)
{
+ bool param_check_at_escaping_exceptions = true;
+ bool param_check_before_noreturn_calls = true;
basic_block bb_eh_cleanup = NULL;
basic_block bb;
- if (flag_exceptions)
+ if (param_check_at_escaping_exceptions && flag_exceptions)
{
int lp_eh_cleanup = -1;
@@ -768,14 +770,15 @@ pass_harden_control_flow_redundancy::execute (function *fun)
if (!stmt_ends_bb_p (stmt))
split_block (bb, stmt);
+ /* A noreturn call needs not be associated with the
+ cleanup handler, because we'll add checking before
+ the call. */
+ else if (EDGE_COUNT (bb->succs) == 0)
+ continue;
if (!bb_eh_cleanup)
{
bb_eh_cleanup = create_empty_bb (bb);
- if (dom_info_available_p (CDI_DOMINATORS))
- set_immediate_dominator (CDI_DOMINATORS, bb_eh_cleanup, bb);
- if (current_loops)
- add_bb_to_loop (bb_eh_cleanup, current_loops->tree_root);
/* Make the new block an EH cleanup for the call. */
eh_region new_r = gen_eh_region_cleanup (NULL);
@@ -791,15 +794,20 @@ pass_harden_control_flow_redundancy::execute (function *fun)
gresx *resx = gimple_build_resx (new_r->index);
gsi_insert_before (&ehgsi, resx, GSI_SAME_STMT);
}
- else
- {
- // Update immedite dominator and loop?
- }
add_stmt_to_eh_lp (stmt, lp_eh_cleanup);
/* Finally, wire the EH cleanup block into the CFG. */
make_eh_edges (stmt); }
}
+
+ if (bb_eh_cleanup && dom_info_available_p (CDI_DOMINATORS))
+ {
+ basic_block immdom;
+ immdom = recompute_dominator (CDI_DOMINATORS, bb_eh_cleanup);
+ set_immediate_dominator (CDI_DOMINATORS, bb_eh_cleanup, immdom);
+ }
+ if (bb_eh_cleanup && current_loops)
+ add_bb_to_loop (bb_eh_cleanup, current_loops->tree_root);
}
/* We wish to add verification at blocks without successors, such as
@@ -809,57 +817,61 @@ pass_harden_control_flow_redundancy::execute (function *fun)
int count_noreturn = 0;
auto_sbitmap noreturn_blocks (last_basic_block_for_fn (fun));
bitmap_clear (noreturn_blocks);
- FOR_EACH_BB_FN (bb, fun)
- {
- if (EDGE_COUNT (bb->succs) == 0)
- {
- if (bitmap_set_bit (noreturn_blocks, bb->index))
- count_noreturn++;
+ if (!param_check_before_noreturn_calls)
+ FOR_EACH_BB_FN (bb, fun)
+ {
+ if (EDGE_COUNT (bb->succs) == 0)
+ {
+ if (bitmap_set_bit (noreturn_blocks, bb->index))
+ count_noreturn++;
+ continue;
+ }
+
+ /* If there are no exceptions, then any noreturn call must have
+ zero successor edges. Otherwise, check for blocks without
+ non-EH successors, but skip those with resx stmts and edges
+ (i.e., those other than that in bb_eh_cleanup), since those
+ will go through bb_eh_cleanup, that will have been counted as
+ noreturn above because it has no successors. */
+ gcc_checking_assert (bb != bb_eh_cleanup);
+ if (!flag_exceptions)
continue;
- }
- /* If there are no exceptions, then any noreturn call must have
- zero successor edges. Otherwise, check for blocks without
- non-EH successors, but skip those with resx stmts and edges
- (i.e., those other than that in bb_eh_cleanup), since those
- will go through bb_eh_cleanup, that will have been counted as
- noreturn above because it has no successors. */
- gcc_checking_assert (bb != bb_eh_cleanup);
- if (!flag_exceptions)
- continue;
-
- bool found_non_eh_edge = false;
- bool found_eh_edge = false;
- edge e;
- edge_iterator ei;
- FOR_EACH_EDGE (e, ei, bb->succs)
- {
- if ((e->flags & EDGE_EH))
- found_eh_edge = true;
- else
- found_non_eh_edge = true;
- if (found_non_eh_edge && found_eh_edge)
- break;
- }
+ bool found_non_eh_edge = false;
+ bool found_eh_edge = false;
+ edge e;
+ edge_iterator ei;
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ {
+ if ((e->flags & EDGE_EH))
+ found_eh_edge = true;
+ else
+ found_non_eh_edge = true;
+ if (found_non_eh_edge && found_eh_edge)
+ break;
+ }
- if (found_non_eh_edge)
- continue;
+ if (found_non_eh_edge)
+ continue;
- if (found_eh_edge)
- {
- /* We don't wish to check before (re?)raises, those will
- have checking performed at bb_eh_cleanup. The one
- exception is bb_eh_cleanup itself. */
- gimple_stmt_iterator gsi = gsi_last_bb (bb);
- gcc_checking_assert (!gsi_end_p (gsi));
- gimple *stmt = gsi_stmt (gsi);
- if (is_a <gresx *> (stmt))
- continue;
- }
+ if (found_eh_edge)
+ {
+ /* We don't wish to check before (re?)raises, those will
+ have checking performed at bb_eh_cleanup. The one
+ exception is bb_eh_cleanup itself. */
+ gimple_stmt_iterator gsi = gsi_last_bb (bb);
+ gcc_checking_assert (!gsi_end_p (gsi));
+ gimple *stmt = gsi_stmt (gsi);
+ if (is_a <gresx *> (stmt))
+ continue;
+ }
- if (bitmap_set_bit (noreturn_blocks, bb->index))
- count_noreturn++;
- }
+ if (bitmap_set_bit (noreturn_blocks, bb->index))
+ count_noreturn++;
+ }
+ else if (bb_eh_cleanup
+ && bitmap_set_bit (noreturn_blocks, bb_eh_cleanup->index))
+ count_noreturn++;
gcc_checking_assert (!bb_eh_cleanup
|| bitmap_bit_p (noreturn_blocks, bb_eh_cleanup->index));
More information about the Gcc-cvs
mailing list