From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23962 invoked by alias); 21 Dec 2002 12:46:05 -0000 Mailing-List: contact gcc-prs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-prs-owner@gcc.gnu.org Received: (qmail 23948 invoked by uid 71); 21 Dec 2002 12:46:04 -0000 Date: Sat, 21 Dec 2002 04:46:00 -0000 Message-ID: <20021221124604.23947.qmail@sources.redhat.com> To: nobody@gcc.gnu.org Cc: gcc-prs@gcc.gnu.org, From: Eric Botcazou Subject: Re: optimization/8492: [3.3 regression] GCC spins forever compiling loop Reply-To: Eric Botcazou X-SW-Source: 2002-12/txt/msg01169.txt.bz2 List-Id: The following reply was made to PR optimization/8492; it has been noted by GNATS. From: Eric Botcazou To: Jan Hubicka Cc: janis187@us.ibm.com, gcc-gnats@gcc.gnu.org, gcc-prs@gcc.gnu.org, gcc-bugs@gcc.gnu.org, nobody@gcc.gnu.org, thorpej@shagadelic.org, jh@suse.cz Subject: Re: optimization/8492: [3.3 regression] GCC spins forever compiling loop Date: Sat, 21 Dec 2002 13:37:21 +0100 --------------Boundary-00=_92ZGJYYMSGCW3CHM5E1P Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable > I think deleting unreachable blocks is cheap enought to do in the case > conditional jump was eliminated. Ok. But then the GCSE code needs to be (at least partially) re-initialize= d=20 because the number of basic blocks may change. I've attached a naive patc= h I=20 wrote some time ago: while fixing the PR (and doing some housekeeping wor= k),=20 it introduces many regressions because of this problem. > Alternatively we may prevent first local cprop pass from modifying CFG. I don't know enough of the global organization of optimization passes to=20 comment. Will the optimizations missed at that point be caught elsewhere = ? --=20 Eric Botcazou --------------Boundary-00=_92ZGJYYMSGCW3CHM5E1P Content-Type: text/x-diff; charset="iso-8859-1"; name="pr8492-2.diff" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="pr8492-2.diff" --- gcse.c.orig=09Sun Dec 1 09:28:09 2002 +++ gcse.c=09Sun Dec 1 11:00:05 2002 @@ -606,13 +606,13 @@ static void find_used_regs=09PARAMS ((rtx *, void *)); static int try_replace_reg=09PARAMS ((rtx, rtx, rtx)); static struct expr *find_avail_set PARAMS ((int, rtx)); -static int cprop_jump=09=09PARAMS ((basic_block, rtx, rtx, rtx, rtx)); static void mems_conflict_for_gcse_p PARAMS ((rtx, rtx, void *)); static int load_killed_in_block_p PARAMS ((basic_block, int, rtx, int= )); static void canon_list_insert PARAMS ((rtx, rtx, void *)); static int cprop_insn=09=09PARAMS ((rtx, int)); static int cprop=09=09PARAMS ((int)); static int one_cprop_pass=09PARAMS ((int, int)); +static bool constprop_jump=09PARAMS ((basic_block, rtx, rtx, rtx, rtx)); static bool constprop_register=09PARAMS ((rtx, rtx, rtx, int)); static struct expr *find_bypass_set PARAMS ((int, int)); static int bypass_block=09=09 PARAMS ((basic_block, rtx, rtx)); @@ -701,7 +701,7 @@ static rtx gcse_emit_move_after=09=09PARAMS ((rtx, rtx, rtx)); static bool do_local_cprop=09=09PARAMS ((rtx, rtx, int, rtx*)); static bool adjust_libcall_notes=09PARAMS ((rtx, rtx, rtx, rtx*)); -static void local_cprop_pass=09=09PARAMS ((int)); +static bool local_cprop_pass=09=09PARAMS ((int)); =0C /* Entry point for global common subexpression elimination. F is the first instruction in the function. */ @@ -3674,6 +3674,11 @@ static sbitmap *cprop_avin; static sbitmap *cprop_avout; =20 +/* Note whether or not the CFG was modified between two points. This ma= y + happen during the local cprop pass if we changed any jumps. */ + +static bool cfg_was_modified; + /* Allocate vars used for copy/const propagation. N_BLOCKS is the numbe= r of basic blocks. N_SETS is the number of sets. */ =20 @@ -3964,7 +3969,7 @@ return success; } =20 -/* Find a set of REGNOs that are available on entry to INSN's block. Re= turns +/* Find a SET of REGNO that is available on entry to INSN's block. Retu= rns NULL no such set is found. */ =20 static struct expr * @@ -4034,15 +4039,15 @@ return set1; } =20 -/* Subroutine of cprop_insn that tries to propagate constants into +/* Subroutine of constprop_register that tries to propagate constants in= to JUMP_INSNS. JUMP must be a conditional jump. If SETCC is non-NULL it is the instruction that immediately preceeds JUMP, and must be a single SET of a register. FROM is what we will try to replace, - SRC is the constant we will try to substitute for it. Returns nonzer= o + SRC is the constant we will try to substitute for it. Returns TRUE if a change was made. */ =20 -static int -cprop_jump (bb, setcc, jump, from, src) +static bool +constprop_jump (bb, setcc, jump, from, src) basic_block bb; rtx setcc; rtx jump; @@ -4071,7 +4076,7 @@ /* If no simplification can be made, then try the next register. */ if (rtx_equal_p (new, new_set) || rtx_equal_p (new, SET_SRC (set))) - return 0; + return false; =20 /* If this is now a no-op delete it, otherwise this must be a valid in= sn. */ if (new =3D=3D pc_rtx) @@ -4082,9 +4087,9 @@ to one computed by setcc. */ if (setcc=20 =09 && modified_in_p (new, setcc)) -=09return 0; +=09return false; if (! validate_change (jump, &SET_SRC (set), new, 0)) -=09return 0; +=09return false; =20 /* If this has turned into an unconditional jump, =09 then put a barrier after it so that the unreachable @@ -4110,11 +4115,17 @@ print_rtl (gcse_file, src); fprintf (gcse_file, "\n"); } - purge_dead_edges (bb); =20 - return 1; + cfg_was_modified |=3D purge_dead_edges (bb); + + return true; } =20 +/* Perform constant propagation on INSN. FROM is what we will try to + replace, TO is the constant we will try to substitute for it. If + ALTER_JUMPS is non-zero, propagate constants into JUMP_INSNS too. + Returns TRUE if a change was made. */ + static bool constprop_register (insn, from, to, alter_jumps) rtx insn; @@ -4132,14 +4143,14 @@ { rtx dest =3D SET_DEST (sset); if ((REG_P (dest) || CC0_P (dest)) -=09 && cprop_jump (BLOCK_FOR_INSN (insn), insn, NEXT_INSN (insn), from,= to)) -=09return 1; +=09 && constprop_jump (BLOCK_FOR_INSN (insn), insn, NEXT_INSN (insn), f= rom, to)) +=09return true; } =20 /* Handle normal insns next. */ if (GET_CODE (insn) =3D=3D INSN && try_replace_reg (from, to, insn)) - return 1; + return true; =20 /* Try to propagate a CONST_INT into a conditional jump. We're pretty specific about what we will handle in this @@ -4148,8 +4159,9 @@ Right now the insn in question must look like (set (pc) (if_then_else ...)) */ else if (alter_jumps && any_condjump_p (insn) && onlyjump_p (insn)) - return cprop_jump (BLOCK_FOR_INSN (insn), NULL, insn, from, to); - return 0; + return constprop_jump (BLOCK_FOR_INSN (insn), NULL, insn, from, to); + + return false; } =20 /* Perform constant and copy propagation on INSN. @@ -4332,6 +4344,7 @@ their REG_EQUAL notes need updating to reflect that OLDREG has been replaced with NEWVAL in INSN. Return true if all substitutions could be made. */ + static bool adjust_libcall_notes (oldreg, newval, insn, libcall_sp) rtx oldreg, newval, insn, *libcall_sp; @@ -4369,7 +4382,11 @@ =20 #define MAX_NESTED_LIBCALLS 9 =20 -static void +/* Perform one local copy/constant propagation pass. ALTER_JUMPS is + non-zero if we are allowed to modify JUMP_INSNS. Return TRUE if + the CFG was modified. */ + +static bool local_cprop_pass (alter_jumps) int alter_jumps; { @@ -4377,6 +4394,8 @@ struct reg_use *reg_used; rtx libcall_stack[MAX_NESTED_LIBCALLS + 1], *libcall_sp; =20 + cfg_was_modified =3D false; + cselib_init (); libcall_sp =3D &libcall_stack[MAX_NESTED_LIBCALLS]; *libcall_sp =3D 0; @@ -4414,6 +4433,8 @@ cselib_process_insn (insn); } cselib_finish (); +=20 + return cfg_was_modified; } =20 /* Forward propagate copies. This includes copies and constants. Retur= n @@ -4463,22 +4484,25 @@ return changed; } =20 -/* Perform one copy/constant propagation pass. - F is the first insn in the function. - PASS is the pass count. */ +/* Perform one copy/constant propagation pass. PASS is the + pass count, ALTER_JUMPS is non-zero if we are allowed to + modify JUMP_INSNS. Return nonzero if a change was made. */ =20 static int one_cprop_pass (pass, alter_jumps) int pass; int alter_jumps; { + bool do_cleanup_cfg; int changed =3D 0; =20 const_prop_count =3D 0; copy_prop_count =3D 0; =20 - local_cprop_pass (alter_jumps); - + do_cleanup_cfg =3D local_cprop_pass (alter_jumps); + if (do_cleanup_cfg) + cleanup_cfg (0); + =20 alloc_hash_table (max_cuid, &set_hash_table, 1); compute_hash_table (&set_hash_table); if (gcse_file) --------------Boundary-00=_92ZGJYYMSGCW3CHM5E1P--