Emit initial value saves in the proper place
Bernd Schmidt
bernds_cb1@t-online.de
Fri Sep 15 12:42:00 GMT 2006
The testcase testsuite/g++.old-deja/g++.other/singleton.C was failing in
our 4.1-based Blackfin compiler with -mfdpic.
This is the assembly we generated for the main function:
_main:
L$LFB$7:
LINK 20;
L$LCFI$3:
L$L$18:
[FP+-8] = P3;
P3 = [FP+-8];
L$LEHB$2:
call __ZN9singleton8instanceEv;
L$LEHE$2:
P3 = [FP+-8];
call __ZN9singleton5checkEv;
R0 += -2;
[FP+-4] = R0;
jump.s L$L$17;
L$L$22:
L$L$19:
P3 = [FP+-8];
call ___cxa_begin_catch;
P3 = [FP+-8];
L$LEHB$3:
call ___cxa_end_catch;
L$LEHE$3:
jump.s L$L$18;
L$L$17:
R0 = [FP+-4];
UNLINK;
rts;
We jump to L$LEHE$3 when catching an exception, and it jumps back to the
start of the loop. The problem is that calling a function and returning
through an exception may clobber P3. The code tries to save P3 to the
stack and reload it from there, but the save happens in the wrong place
- it's inside the loop. P3 is the PIC register, and having it clobbered
causes everything to go downhill rather quickly.
This is a bug in the initial_values pass, which tries to emit
instructions at the start of the function, but what it actually does is
emit them at the start of the first basic block. In this case, the
first basic block is part of a loop, so we may execute the save
instruction multiple times.
Fixed by emitting insns on the edge between the dummy entry block and
the first basic block instead. This is a regression from 3.4, which
emitted the insns right at the start of the function in all cases.
Bootstrapped on i686-linux, regression tested against bfin-elf.
Committed on mainline as 116968.
Bernd
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: correct-entry.diff
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20060915/0f0b9465/attachment.ksh>
More information about the Gcc-patches
mailing list