This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug optimization/11781] New: superfluous jumps generated
- From: "anton at mips dot complang dot tuwien dot ac dot at" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 3 Aug 2003 09:46:04 -0000
- Subject: [Bug optimization/11781] New: superfluous jumps generated
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
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.