On 05/07/12 15:30, Michael Matz wrote: > Hi, > > On Thu, 5 Jul 2012, Tom de Vries wrote: > >> The asserts allow the return result to be optimized, but not the cfg >> conditions. >> >> AFAIU, we can insert the asserts earlier. F.i., we can insert >> aD.1711_6 = ASSERT_EXPR <aD.1711_1(D), aD.1711_1(D) > 0> >> before the GIMPLE_COND in bb2. > > Nope. That would require some more checks, in particular that the BB > containing builtin_unreachable doesn't contain any other side-effects. > Given this: > > if (i < 0) > { do_something_interesting(); > __builtin_unreachable(); > } > > moving the assert before the if would remove the if condition, hence > the call to do_something_interesting. You need to retain side-effects if > there are any. >
Michael, Thanks for pointing that out. I tried a first stab at your suggestion of implementing the optimization in pass_fold_builtins, it works for the test-case. Thanks, - Tom > > Ciao, > Michael. >
Index: gcc/tree-ssa-ccp.c =================================================================== --- gcc/tree-ssa-ccp.c (revision 189007) +++ gcc/tree-ssa-ccp.c (working copy) @@ -2318,6 +2318,44 @@ optimize_stdarg_builtin (gimple call) } } +/* Return false if there are staments with side-effects before I. Otherwise, + return true and make the block of I unreachable. */ + +static bool +optimize_unreachable (gimple_stmt_iterator i) +{ + gimple stmt; + basic_block bb; + edge_iterator ei; + edge e; + + for (gsi_prev (&i); !gsi_end_p (i); gsi_prev (&i)) + { + stmt = gsi_stmt (i); + if (gimple_has_side_effects (stmt)) + return false; + } + + bb = gsi_bb (i); + + FOR_EACH_EDGE (e, ei, bb->preds) + { + basic_block src = e->src; + gimple stmt; + i = gsi_last_bb (src); + stmt = gsi_stmt (i); + gcc_assert (gimple_code (stmt) == GIMPLE_COND); + if (e->flags & EDGE_TRUE_VALUE) + gimple_cond_make_false (stmt); + else if (e->flags & EDGE_FALSE_VALUE) + gimple_cond_make_true (stmt); + else + gcc_unreachable (); + } + + return true; +} + /* A simple pass that attempts to fold all builtin functions. This pass is run after we've propagated as many constants as we can. */ @@ -2379,6 +2417,11 @@ execute_fold_all_builtins (void) gsi_next (&i); continue; + case BUILT_IN_UNREACHABLE: + if (optimize_unreachable (i)) + cfg_changed = true; + break; + case BUILT_IN_VA_START: case BUILT_IN_VA_END: case BUILT_IN_VA_COPY: @@ -2393,6 +2436,9 @@ execute_fold_all_builtins (void) continue; } + if (result == NULL_TREE) + break; + if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Simplified\n ");