Message ID | 20220114182047.6270-4-amonakov@ispras.ru |
---|---|
State | New |
Headers | show |
Series | [1/3] tree-ssa-sink: do not sink to in front of setjmp | expand |
On Fri, Jan 14, 2022 at 7:21 PM Alexander Monakov <amonakov@ispras.ru> wrote: > > When a returns_twice call has an associated abnormal edge, the edge > corresponds to the "second return" from the call. It wouldn't make sense > if any executable statements appeared between the call and the > destination of the edge (they wouldn't be re-executed upon the "second > return"), so verify that. OK for next stage1. Thanks, Richard. > gcc/ChangeLog: > > * tree-cfg.c (gimple_verify_flow_info): Check placement of > returns_twice calls. > --- > gcc/tree-cfg.c | 33 +++++++++++++++++++++++++++++++++ > 1 file changed, 33 insertions(+) > > diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c > index a99f1acb4..70bd31d3d 100644 > --- a/gcc/tree-cfg.c > +++ b/gcc/tree-cfg.c > @@ -5644,6 +5644,7 @@ gimple_verify_flow_info (void) > } > > /* Verify that body of basic block BB is free of control flow. */ > + bool seen_nondebug_stmt = false; > for (; !gsi_end_p (gsi); gsi_next (&gsi)) > { > gimple *stmt = gsi_stmt (gsi); > @@ -5664,6 +5665,38 @@ gimple_verify_flow_info (void) > gimple_label_label (label_stmt), bb->index); > err = 1; > } > + > + /* Check that no statements appear between a returns_twice call > + and its associated abnormal edge. */ > + if (gimple_code (stmt) == GIMPLE_CALL > + && gimple_call_flags (stmt) & ECF_RETURNS_TWICE) > + { > + const char *misplaced = NULL; > + /* TM is an exception: it points abnormal edges just after the > + call that starts a transaction, i.e. it must end the BB. */ > + if (gimple_call_builtin_p (stmt, BUILT_IN_TM_START)) > + { > + if (single_succ_p (bb) > + && bb_has_abnormal_pred (single_succ (bb)) > + && !gsi_one_nondebug_before_end_p (gsi)) > + misplaced = "not last"; > + } > + else > + { > + if (seen_nondebug_stmt > + && bb_has_abnormal_pred (bb)) > + misplaced = "not first"; > + } > + if (misplaced) > + { > + error ("returns_twice call is %s in basic block %d", > + misplaced, bb->index); > + print_gimple_stmt (stderr, stmt, 0, TDF_SLIM); > + err = 1; > + } > + } > + if (!is_gimple_debug (stmt)) > + seen_nondebug_stmt = true; > } > > gsi = gsi_last_nondebug_bb (bb); > -- > 2.33.1 >
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index a99f1acb4..70bd31d3d 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -5644,6 +5644,7 @@ gimple_verify_flow_info (void) } /* Verify that body of basic block BB is free of control flow. */ + bool seen_nondebug_stmt = false; for (; !gsi_end_p (gsi); gsi_next (&gsi)) { gimple *stmt = gsi_stmt (gsi); @@ -5664,6 +5665,38 @@ gimple_verify_flow_info (void) gimple_label_label (label_stmt), bb->index); err = 1; } + + /* Check that no statements appear between a returns_twice call + and its associated abnormal edge. */ + if (gimple_code (stmt) == GIMPLE_CALL + && gimple_call_flags (stmt) & ECF_RETURNS_TWICE) + { + const char *misplaced = NULL; + /* TM is an exception: it points abnormal edges just after the + call that starts a transaction, i.e. it must end the BB. */ + if (gimple_call_builtin_p (stmt, BUILT_IN_TM_START)) + { + if (single_succ_p (bb) + && bb_has_abnormal_pred (single_succ (bb)) + && !gsi_one_nondebug_before_end_p (gsi)) + misplaced = "not last"; + } + else + { + if (seen_nondebug_stmt + && bb_has_abnormal_pred (bb)) + misplaced = "not first"; + } + if (misplaced) + { + error ("returns_twice call is %s in basic block %d", + misplaced, bb->index); + print_gimple_stmt (stderr, stmt, 0, TDF_SLIM); + err = 1; + } + } + if (!is_gimple_debug (stmt)) + seen_nondebug_stmt = true; } gsi = gsi_last_nondebug_bb (bb);