This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] PR opt/12628: Call reg_scan before jump bypassing
- From: Roger Sayle <roger at eyesopen dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 30 Nov 2003 19:20:25 -0700 (MST)
- Subject: [PATCH] PR opt/12628: Call reg_scan before jump bypassing
The following patch is my proposed fix for PR optimization/12628
which is an ICE-on-valid caused by an obscure combination of compiler
flags. The jump bypassing pass calls init_alias_analysis assuming
that register information is currently correct. Unfortunately,
with the options "-O2 -fno-expensive-optimizations -fno-rerun-loop-opt"
reg_scan isn't called after either GCSE nor loop. This then leads
to the ICE in init_alias_analysis.
The proposed (and least invasive) solution is for toplev.c's
rest_of_handle_jump_bypass to call reg_scan itself as it needs
aliasing information. This is consistent with most other uses
of reg_scan in toplev.c where it's called immediately before
the pass that requires it, for example, the CSE passes. Alas
this policy is not entirely consistent, with GCSE relying on
reg_scan being called at the end of addressof. It would be
more consistent to move reg_scan from the end of addressof to
the beginning of GCSE, but this could potentially expose a
similar failure caused by another obscure set of compiler flags.
Longer term, it would be nice if, like the CFG, we maintained
a set of flags indicating whether these data structures were
valid following an optimization pass. This would save us from
recalculating information that hasn't changed.
Unfortunately, calling reg_scan performs a traversal of the
RTL insn stream, so we can expect a minor slow-down from this
change :<. It isn't clear whether GCSE or loop preserve the
"reg_scan" information, so this change is safe even when the
user hasn't specified wierd command line options. However,
to try and combat this, the patch below contains some clean-ups
to reg_scan and reg_scan_update. I've also moved reg_scan's
call to allocate_reg_info (which looks like it can do a
significant amount of work) into the TV_REG_SCAN timevar so
we can get a more accurate picture of how much reg_scan costs.
My next patch addresses PR/12322 and will speed-up RTL's GCSE
pass, so hopefully we'll still have a net performance win.
This patch has been tested on i686-pc-linux-gnu with a complete
"make bootstrap", all languages except treelang, and regression
tested with a top-level "make -k check" with no new failures.
Ok for mainline?
Many thanks in advance,
2003-11-30 Roger Sayle <roger@eyesopen.com>
PR optimization/12628
* toplev.c (rest_of_handle_jump_bypass): Call reg_scan.
* regclass.c (reg_scan): Include allocate_reg_info time in
TV_REG_SCAN. Minor clean-ups.
(reg_scan_update): Minor clean-ups.
* gcc.dg/20031130-1.c: New test case.
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.845
diff -c -3 -p -r1.845 toplev.c
*** toplev.c 21 Nov 2003 04:05:05 -0000 1.845
--- toplev.c 30 Nov 2003 22:35:19 -0000
*************** rest_of_handle_jump_bypass (tree decl, r
*** 2568,2573 ****
--- 2568,2574 ----
open_dump_file (DFI_bypass, decl);
cleanup_cfg (CLEANUP_EXPENSIVE);
+ reg_scan (insns, max_reg_num (), 1);
if (bypass_jumps (rtl_dump_file))
{
Index: regclass.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/regclass.c,v
retrieving revision 1.179
diff -c -3 -p -r1.179 regclass.c
*** regclass.c 13 Oct 2003 21:16:19 -0000 1.179
--- regclass.c 30 Nov 2003 22:35:19 -0000
*************** reg_scan (rtx f, unsigned int nregs, int
*** 2293,2313 ****
{
rtx insn;
allocate_reg_info (nregs, TRUE, FALSE);
max_parallel = 3;
max_set_parallel = 0;
- timevar_push (TV_REG_SCAN);
-
for (insn = f; insn; insn = NEXT_INSN (insn))
! if (GET_CODE (insn) == INSN
! || GET_CODE (insn) == CALL_INSN
! || GET_CODE (insn) == JUMP_INSN)
{
! if (GET_CODE (PATTERN (insn)) == PARALLEL
! && XVECLEN (PATTERN (insn), 0) > max_parallel)
! max_parallel = XVECLEN (PATTERN (insn), 0);
! reg_scan_mark_refs (PATTERN (insn), insn, 0, 0);
if (REG_NOTES (insn))
reg_scan_mark_refs (REG_NOTES (insn), insn, 1, 0);
--- 2293,2312 ----
{
rtx insn;
+ timevar_push (TV_REG_SCAN);
+
allocate_reg_info (nregs, TRUE, FALSE);
max_parallel = 3;
max_set_parallel = 0;
for (insn = f; insn; insn = NEXT_INSN (insn))
! if (INSN_P (insn))
{
! rtx pat = PATTERN (insn);
! if (GET_CODE (pat) == PARALLEL
! && XVECLEN (pat, 0) > max_parallel)
! max_parallel = XVECLEN (pat, 0);
! reg_scan_mark_refs (pat, insn, 0, 0);
if (REG_NOTES (insn))
reg_scan_mark_refs (REG_NOTES (insn), insn, 1, 0);
*************** reg_scan_update (rtx first, rtx last, un
*** 2331,2344 ****
allocate_reg_info (max_reg_num (), FALSE, FALSE);
for (insn = first; insn != last; insn = NEXT_INSN (insn))
! if (GET_CODE (insn) == INSN
! || GET_CODE (insn) == CALL_INSN
! || GET_CODE (insn) == JUMP_INSN)
{
! if (GET_CODE (PATTERN (insn)) == PARALLEL
! && XVECLEN (PATTERN (insn), 0) > max_parallel)
! max_parallel = XVECLEN (PATTERN (insn), 0);
! reg_scan_mark_refs (PATTERN (insn), insn, 0, old_max_regno);
if (REG_NOTES (insn))
reg_scan_mark_refs (REG_NOTES (insn), insn, 1, old_max_regno);
--- 2330,2342 ----
allocate_reg_info (max_reg_num (), FALSE, FALSE);
for (insn = first; insn != last; insn = NEXT_INSN (insn))
! if (INSN_P (insn))
{
! rtx pat = PATTERN (insn);
! if (GET_CODE (pat) == PARALLEL
! && XVECLEN (pat, 0) > max_parallel)
! max_parallel = XVECLEN (pat, 0);
! reg_scan_mark_refs (pat, insn, 0, old_max_regno);
if (REG_NOTES (insn))
reg_scan_mark_refs (REG_NOTES (insn), insn, 1, old_max_regno);
/* PR optimization/12628 */
/* The following test used to ICE in init_alias_analysis because the
given command line options meant that reg_scan wasn't (re)run before
the jump bypassing pass. */
/* { dg-do compile } */
/* { dg-options "-O2 -fno-expensive-optimizations -fno-rerun-loop-opt" } */
int outbuf[100];
int outcnt;
int bi_buf;
void send_bits(void)
{
bi_buf = 0;
outbuf[outcnt++] = 8;
outbuf[outcnt++] = 8;
if (outcnt)
bi_buf = 1;
}
Roger
--
Roger Sayle, E-mail: roger@eyesopen.com
OpenEye Scientific Software, WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road, Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507. Fax: (+1) 505-473-0833