[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:34:48 GMT 2022
https://gcc.gnu.org/g:4a10a36a038842f0c932130c7c1b3dcd5eb13d47
commit 4a10a36a038842f0c932130c7c1b3dcd5eb13d47
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 | 121 ++++++++++++++++++++++----------------
1 file changed, 71 insertions(+), 50 deletions(-)
diff --git a/gcc/gimple-harden-control-flow.cc b/gcc/gimple-harden-control-flow.cc
index 5066a43fe6c..00b60da0030 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,6 +770,11 @@ 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)
{
@@ -791,14 +798,24 @@ 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
+ else if (dom_info_available_p (CDI_DOMINATORS))
{
- // Update immedite dominator and loop?
+ basic_block immdom;
+ immdom = get_immediate_dominator (CDI_DOMINATORS,
+ bb_eh_cleanup);
+ if (!dominated_by_p (CDI_DOMINATORS, immdom, bb))
+ {
+ immdom = nearest_common_dominator (CDI_DOMINATORS,
+ immdom, bb);
+ set_immediate_dominator (CDI_DOMINATORS,
+ bb_eh_cleanup, immdom);
+ }
}
add_stmt_to_eh_lp (stmt, lp_eh_cleanup);
/* Finally, wire the EH cleanup block into the CFG. */
- make_eh_edges (stmt); }
+ make_eh_edges (stmt);
+ }
}
}
@@ -809,57 +826,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