First this adds a controlling option to the phiopt pass (-fssa-phiopt). Second, this moves the first phiopt pass from the main optimization pipeline into early opts (before merge-phi which confuses phiopt but after dce which will help it).
ISTR that adding an early phiopt pass was wanted to perform CFG cleanups on the weird CFG that the gimplifier produces from C++ code (but I fail to recollect the details nor remember a bug number). Generally doing a phiopt before merge-phi gets the chance to screw things up is good. Also phiopt is a kind of cleanup that is always beneficial as it decreases code-size. Bootstrap and regtest running on x86_64-unknown-linux-gnu. I felt that -ftree-XXX is bad naming so I went for -fssa-XXX even if that is now inconsistent. Any optinion here? For RTL we simply have unsuffixed names so shall we instead go for -fphiopt? PHI implies SSA anyway and 'SSA' or 'RTL' is an implementation detail that the user should not be interested in (applies to tree- as well, of course). Now, 'phiopt' is a bad name when thinking of users (but they shouldn't play with those options anyway). So - comments on the pass move? Comments on the flag naming? Thanks, Richard. 2014-06-17 Richard Biener <rguent...@suse.de> * passes.def (pass_all_early_optimizations): Add phi-opt after dce and before merge-phi. (pass_all_optimizations): Remove first phi-opt pass. * common.opt (fssa-phiopt): New option. * opts.c (default_options_table): Enable -fssa-phiopt with -O1+ but not with -Og. * tree-ssa-phiopt.c (pass_phiopt): Add gate method. * doc/invoke.texi (-fssa-phiopt): Document. Index: gcc/passes.def =================================================================== --- gcc/passes.def (revision 211736) +++ gcc/passes.def (working copy) @@ -73,8 +73,12 @@ along with GCC; see the file COPYING3. execute TODO_rebuild_alias at this point. */ NEXT_PASS (pass_build_ealias); NEXT_PASS (pass_fre); - NEXT_PASS (pass_merge_phi); NEXT_PASS (pass_cd_dce); + NEXT_PASS (pass_phiopt); + /* Do this after phiopt runs as phiopt is confused by + PHIs with more than two arguments. Switch conversion + looks for a single PHI block though. */ + NEXT_PASS (pass_merge_phi); NEXT_PASS (pass_early_ipa_sra); NEXT_PASS (pass_tail_recursion); NEXT_PASS (pass_convert_switch); @@ -155,7 +159,6 @@ along with GCC; see the file COPYING3. NEXT_PASS (pass_cselim); NEXT_PASS (pass_copy_prop); NEXT_PASS (pass_tree_ifcombine); - NEXT_PASS (pass_phiopt); NEXT_PASS (pass_tail_recursion); NEXT_PASS (pass_ch); NEXT_PASS (pass_stdarg); Index: gcc/common.opt =================================================================== --- gcc/common.opt (revision 211736) +++ gcc/common.opt (working copy) @@ -1950,6 +1950,10 @@ fsplit-wide-types Common Report Var(flag_split_wide_types) Optimization Split wide types into independent registers +fssa-phiopt +Common Report Var(flag_ssa_phiopt) Optimization +Optimize conditional patterns using SSA PHI nodes + fvariable-expansion-in-unroller Common Report Var(flag_variable_expansion_in_unroller) Optimization Apply variable expansion when loops are unrolled Index: gcc/opts.c =================================================================== --- gcc/opts.c (revision 211736) +++ gcc/opts.c (working copy) @@ -457,6 +457,7 @@ static const struct default_options defa { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fbranch_count_reg, NULL, 1 }, { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fmove_loop_invariants, NULL, 1 }, { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_pta, NULL, 1 }, + { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fssa_phiopt, NULL, 1 }, /* -O2 optimizations. */ { OPT_LEVELS_2_PLUS, OPT_finline_small_functions, NULL, 1 }, Index: gcc/tree-ssa-phiopt.c =================================================================== --- gcc/tree-ssa-phiopt.c (revision 211736) +++ gcc/tree-ssa-phiopt.c (working copy) @@ -2332,6 +2332,7 @@ public: /* opt_pass methods: */ opt_pass * clone () { return new pass_phiopt (m_ctxt); } + virtual bool gate (function *) { return flag_ssa_phiopt; } virtual unsigned int execute (function *) { return tree_ssa_phiopt_worker (false, gate_hoist_loads ()); Index: gcc/doc/invoke.texi =================================================================== --- gcc/doc/invoke.texi (revision 211736) +++ gcc/doc/invoke.texi (working copy) @@ -412,7 +412,7 @@ Objective-C and Objective-C++ Dialects}. -fselective-scheduling -fselective-scheduling2 @gol -fsel-sched-pipelining -fsel-sched-pipelining-outer-loops @gol -fshrink-wrap -fsignaling-nans -fsingle-precision-constant @gol --fsplit-ivs-in-unroller -fsplit-wide-types -fstack-protector @gol +-fsplit-ivs-in-unroller -fsplit-wide-types -fssa-phiopt -fstack-protector @gol -fstack-protector-all -fstack-protector-strong -fstrict-aliasing @gol -fstrict-overflow -fthread-jumps -ftracer -ftree-bit-ccp @gol -ftree-builtin-call-dce -ftree-ccp -ftree-ch @gol @@ -6907,6 +6907,7 @@ compilation time. -ftree-bit-ccp @gol -ftree-builtin-call-dce @gol -ftree-ccp @gol +-fssa-phiopt @gol -ftree-ch @gol -ftree-copyrename @gol -ftree-dce @gol @@ -7892,6 +7893,11 @@ Perform sparse conditional constant prop pass only operates on local scalar variables and is enabled by default at @option{-O} and higher. +@item -fssa-phiopt +@opindex fssa-phiopt +Perform pattern matching on SSA PHI nodes to optimize conditional +code. This pass is enabled by default at @option{-O} and higher. + @item -ftree-switch-conversion Perform conversion of simple initializations in a switch to initializations from a scalar array. This flag is enabled by default