This is the mail archive of the gcc-bugs@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]

[Bug optimization/11781] New: superfluous jumps generated


PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11781

           Summary: superfluous jumps generated
           Product: gcc
           Version: 3.3
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: optimization
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: anton at mips dot complang dot tuwien dot ac dot at
                CC: bernd dot paysan at gmx dot de,gcc-bugs at gcc dot gnu
                    dot org
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu

The preprocessed source code for demonstrating this issue is at

http://www.complang.tuwien.ac.at/anton/tmp/engine-fast.i

(where has the upload button on this form gone?)

When compiled with

gcc  -I./../arch/386 -I. -Wall -O2 -fomit-frame-pointer -fforce-addr -fforce-mem
-march=pentium -DHAVE_CONFIG_H
-DDEFAULTPATH=\".:/usr/local/lib/gforth/site-forth:/usr/local/share/gforth/site-forth:/usr/local/lib/gforth/0.6.1:/usr/local/share/gforth/0.6.1\"
-fno-gcse -fno-strict-aliasing -fno-crossjumping -fno-defer-pop -fcaller-saves
-fno-inline -o engine-fast.s -S ./engine-fast.i

from this source code (reformatted for slightly improved readability):

I_question_branch:
{
  Cell * a_target;
  Bool f;
  ;
  ((a_target)=(Cell *)(((*(ip)))));
  ((f)=(Bool)(spTOS));
  ({ ip+=(1);});
  sp += 1;
  {
    if (f==0) {
      ({ip=((Xt *)a_target); ;});
      ;
      (ip++);
      spTOS = sp[0];
      ({asm("":"=X"(cfa)); goto **(ip-1);});
    }
    ;
  }
  ;
  (ip++);
  spTOS = sp[0];
  K_question_branch:
  asm("#" "question_branch");
  ({asm("":"=X"(cfa)); goto **(ip-1);});
}

gcc produces the following assembly code:

...
	.long	.L347
...
	jmp	*%edx
.L347:
#APP
	#question_branch
#NO_APP
	movl	-4(%ebp), %edx
	jmp	*%edx
...
.L26:
	movl	636(%esp), %edx
	movl	(%ebp), %eax
	addl	$4, %edi
	addl	$4, %ebp
	testl	%edx, %edx
	jne	.L979
	leal	4(%eax), %ebp
	movl	(%edi), %eax
	movl	%eax, 636(%esp)
	movl	-4(%ebp), %edx
	jmp	*%edx
.L666:
...
.L979:
	movl	(%edi), %edx
	addl	$4, %ebp
	movl	%edx, 636(%esp)
	jmp	.L347
...

This fragment includes all occurences of .L347.  The "jmp .L347" could
be easily avoided by just appending the block starting at .L347 to the
block starting at .L979.  In the source code this code is consecutive,
so the jump must have been introduced by optimization.

If you try to reproduce this with another gcc version, search for
"#question_branch" to find the appropriate label for ".L347".

As an aside: It would be very helpful for Gforth and other
interpreters using dynamic superinstructions (aka selective inlining,
PLDI'98 p. 291), and for systems like Tempo (a partial
evaluator/run-time specializer for C), if the basic blocks would stay
in source order where possible (i.e., in the example above: .L26,
.L979, .L347, and only then something else).  These systems work by
copying code between two labels (as-values) at run-time; if the code
is not consecutive, these systems will not work; in Gforth we have a
fall-back but more ambitious approaches like Tempo may be confined to
using gcc-2.x unless you give them a way to control the order of the
machine code.


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