This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]