The the .tailc dump for the function combine.c:cant_combine_insn_p looks like this: [snip] <L23>:; T.150_24 = dest_5->u.fld[0].rtuint; if (T.150_24 > 52) goto <L35>; else goto <L24>; <L24>:; T.151_26 = fixed_regs[T.150_24]; if (T.151_26 != 0) goto <L35>; else goto <L25>; <L25>:; T.152_29 = regclass_map[T.150_24]; T.153_30 = T.152_29 - 1; if (T.153_30 <= 3) goto <L35>; else goto <L26>; <L26>:; if (T.152_29 == 7) goto <L35>; else goto <L27>; <L27>:; if (T.152_29 == 5) goto <L35>; else goto <L28>; <L28>:; if (T.152_29 == 6) goto <L35>; else goto <L29>; <L29>:; if (T.152_29 == 13) goto <L35>; else goto <L30>; <L30>:; if (T.152_29 == 14) goto <L31>; else goto <L35>; <L31>:; # T.139_1 = PHI <0(7), 1(25), 0(2), 1(0), 0(24), 0(8), 1(23), 1(22), 1(21), 1(20), 1(19), 0(18), 0(17), 1(16), 1(15), 1(14), 1(13), 1(12), 1(11)>; <L35>:; return T.139_1; Note the return value T.139_1 The .optimized dump looks like: [snip] <L75>:; T.139 = 1; goto <bb 26> (<L35>); <L27>:; if (T.152 == 5) goto <L76>; else goto <L28>; <L76>:; T.139 = 1; goto <bb 26> (<L35>); <L28>:; if (T.152 == 6) goto <L77>; else goto <L29>; <L77>:; T.139 = 1; goto <bb 26> (<L35>); <L29>:; if (T.152 == 13) goto <L78>; else goto <L30>; <L78>:; T.139 = 1; goto <bb 26> (<L35>); <L30>:; if (T.152 == 14) goto <L31>; else goto <L79>; <L79>:; T.139 = 0; goto <bb 26> (<L35>); <L31>:; T.139 = 1; <L35>:; return T.139; Not that T.139 is assigned 1 in a lot of BBs, followed by a jumb to the return statement. The code would be much smaller if there was a only 1 assignment that all the ifs jump to.
Created attachment 6716 [details] compilable file containing the function this PR talks about.
Confirmed, here is a simple example: int f(int i, int b, int c) { if (i) return 1; if (b) return 1; if (c) return 1; return 0; }
I have a semi fix (well one [or is two less] less BB), the fix for that part was in PHI-OPT but the rest would need to be in outof-ssa.
I think the best way to do this is to add a short analysis pass in the out of ssa pass, immediately before we commit the final edge insertions. Take a look at the predecessors of each basic block, and find any edges which have the same set of stmts on it. Commit one of these edges, if it generates a new basic block, simply redirect all the other matching edges to that block, and remove the PENDING_STMTS list for those edges. I've started a basic implementation.
Subject: Bug 16447 CVSROOT: /cvs/gcc Module name: gcc Branch: tree-cleanup-branch Changes by: amacleod@gcc.gnu.org 2004-10-06 12:46:04 Modified files: gcc : ChangeLog tree-cfg.c tree-flow.h tree-optimize.c tree-outof-ssa.c Log message: 2004-10-06 Andrew MacLeod <amacleod@redhat.com> PR tree-optimization/16447 * tree-cfg.c (bsi_commit_one_edge_insert): Rename from bsi_commit_edge_inserts_1, and make funtion external. Return new block. (bsi_commit_edge_inserts): Use renamed bsi_commit_one_edge_insert. * tree-optimize.c (pass_cleanup_cfg_post_optimizing): Enable listing. * tree-flow.h (bsi_commit_one_edge_insert): Extern decl. * tree-outof-ssa.c (rewrite_trees): Don't commit edges here. (same_stmt_list_p): New. Return TRUE if edge is to be forwarded. (identical_copies_p): New. Return true is two copies are the same. (identical_stmt_lists_p): New. Return true if stmt lists are the same. (analyze_edges_for_bb): New. Determine how best to insert edge stmts for a basic block. (perform_edge_inserts): New. Determine what to do with all stmts that have been inserted on edges. (remove_ssa_form): Analyze and commit edges from here. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=tree-cleanup-branch&r1=2.5512.2.2&r2=2.5512.2.3 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree-cfg.c.diff?cvsroot=gcc&only_with_tag=tree-cleanup-branch&r1=2.55.2.3&r2=2.55.2.4 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree-flow.h.diff?cvsroot=gcc&only_with_tag=tree-cleanup-branch&r1=2.46.2.2&r2=2.46.2.3 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree-optimize.c.diff?cvsroot=gcc&only_with_tag=tree-cleanup-branch&r1=2.47.2.3&r2=2.47.2.4 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree-outof-ssa.c.diff?cvsroot=gcc&only_with_tag=tree-cleanup-branch&r1=2.22.2.1&r2=2.22.2.2
Created attachment 7294 [details] patch for the problem This has been added to the tcb cleanup branch, so it will be integrated into the next release. THe resulting code from the example in the PR: D.16577 = dest->u.fld[0].rtuint; if (D.16577 > 52) goto <L35>; else goto <L24>; <L24>:; if (fixed_regs[D.16577] != 0) goto <L35>; else goto <L25>; <L25>:; D.16579 = regclass_map[D.16577]; if (D.16579 - 1 <= 3) goto <L61>; else goto <L26>; <L26>:; if (D.16579 == 7) goto <L61>; else goto <L27>; <L27>:; if (D.16579 == 5) goto <L61>; else goto <L28>; <L28>:; if (D.16579 == 6) goto <L61>; else goto <L29>; <L29>:; if (D.16579 == 13) goto <L61>; else goto <L30>; <L30>:; if (D.16579 == 14) goto <L61>; else goto <L35>; <L35>:; D.16562 = 0; goto <bb 27> (<L62>); <L61>:; D.16562 = 1; <L62>:; return D.16562;
Patch here: <http://gcc.gnu.org/ml/gcc-patches/2004-10/msg00488.html>, applied to tcb already.
Subject: Bug 16447 CVSROOT: /cvs/gcc Module name: gcc Changes by: amacleod@gcc.gnu.org 2004-11-02 00:23:05 Modified files: gcc : ChangeLog tree-cfg.c tree-flow.h tree-optimize.c tree-outof-ssa.c Log message: 2004-11-01 Andrew MacLeod <amacleod@redhat.com> PR tree-optimization/16447 * tree-cfg.c (bsi_commit_one_edge_insert): Rename from bsi_commit_edge_inserts_1, and make funtion external. Return new block. (bsi_commit_edge_inserts): Use renamed bsi_commit_one_edge_insert. * tree-optimize.c (pass_cleanup_cfg_post_optimizing): Enable listing. * tree-flow.h (bsi_commit_one_edge_insert): Extern decl. * tree-outof-ssa.c (rewrite_trees): Don't commit edges here. (same_stmt_list_p): New. Return TRUE if edge is to be forwarded. (identical_copies_p): New. Return true is two copies are the same. (identical_stmt_lists_p): New. Return true if stmt lists are the same. (analyze_edges_for_bb): New. Determine how best to insert edge stmts for a basic block. (perform_edge_inserts): New. Determine what to do with all stmts that have been inserted on edges. (remove_ssa_form): Analyze and commit edges from here. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.6125&r2=2.6126 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree-cfg.c.diff?cvsroot=gcc&r1=2.96&r2=2.97 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree-flow.h.diff?cvsroot=gcc&r1=2.57&r2=2.58 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree-optimize.c.diff?cvsroot=gcc&r1=2.60&r2=2.61 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree-outof-ssa.c.diff?cvsroot=gcc&r1=2.27&r2=2.28
Fixed on the mainline now.