weird code generation differences without optimization [was Re: purify 4.1 and egcs still appear to be incompatible.]
Ian Haggard
ian@shellus.com
Tue Feb 17 11:20:00 GMT 1998
Brad M. Garcia wrote:
>
> On Mon, 16 Feb 1998, Ian Haggard wrote:
>
> > Actually, the problem is that gcc's default copy constructors for "empty" types
> > somehow are making purify think that the one byte being copied is actually
> > being used.
>
> So... why does gcc copy a random byte unnecessarily? I would think that
> we could at least change it to copy something that _has_ been initialized.
> Or make it do something other than a copy. I'm assuming that this "null"
> instruction has been added to assist debugging in some way.
The reason for the "unnecessary" copy is that the default copy ctor/assignment
op are defined simply to do bitwise copy. And the standard, unfortunately,
also requires that even "empty" structs take up space.
Hmmm...the more I look at this, the weirder it gets. My example program in my
previous message suddenly started giving me purify errors all the time, not
just when I was defining NO_PURIFY_ERROR. But now check this out:
triton:tests% cat truetype3.cc
struct __true_type {
};
template <class T>
inline void tifoo(T) {}
template<class T>
void tfoo(T) {}
inline void ifoo(__true_type) {}
void foo(__true_type) {}
main() {
tifoo(__true_type());
tfoo(__true_type());
ifoo(__true_type());
foo(__true_type());
return 0;
}
triton:tests% g++ -v
Reading specs from
/////////////////////home/discovery4/ian/pkg/egcs-1.0/sparc-sun-solaris2.5.1/lib/gcc-lib/sparc-sun-solaris2.5.1/egcs-2.90.21/specs
gcc version egcs-2.90.21 971202 (egcs-1.00 release)
triton:tests% purify g++ truetype3.cc -o truetype3
Purify 4.1 Solaris 2, Copyright (C) 1992-1997 Rational Software Corp. All
rights reserved.
Instrumenting: cca003ib1.o libgcc.a.....
Purify engine: While processing file
/home/triton2/ian/pkg/gcc-2.8.0/sparc-sun-solaris2.5.1/lib/gcc-lib/sparc-sun-solaris2.5.1/2.8.0/libgcc.a(_bb.o):
Warning: Found untested reloc type R_SPARC_GOT10 at location 0x1480 (section
2),
apparently pointing to offset 0x28.
[SNIP more R_SPARC_GOT10 warnings]
Purify engine: Warning: Found untested reloc type R_SPARC_GOT10 at location
0x1b80 (section 2),
apparently pointing to offset 0xc0.
................................................ Linking
triton:tests% ./truetype3
**** Purify instrumented ./truetype3 (pid 15292 at Tue Feb 17 12:30:55 1998)
* Purify 4.1 Solaris 2, Copyright (C) 1992-1997 Rational Software Corp. All
rights reserved.
* For contact information type: "purify -help"
* For Purify Viewer output, set the DISPLAY environment variable.
* Command-line: ./truetype3
* Options settings: -cache-dir=/home/enterprise4/casper/cache \
-always-use-cache-dir \
-purify_home=/home/brclib7/software/pure/purify-4.1-solaris2 \
-recursion-depth-limit=20000 \
-cache-dir=/home/discovery4/ian/homes/localdisk/purelibcache -g++=yes \
-purify -purify-home=/home/brclib7/software/pure/purify-4.1-solaris2
* Purify licensed to Shell Development Co. or Shell Development Company or
SHELL E&P TECHNOLOGY
* Purify checking enabled.
**** Purify instrumented ./truetype3 (pid 15292) ****
UMR: Uninitialized memory read:
* This is occurring while in:
tifoo__H1Z11__true_type_X01_v [cca003ib1.o]
main [cca003ib1.o]
_start [crt1.o]
* Reading 1 byte from 0xeffff4c7 on the stack.
* Address 0xeffff4c7 is 17 bytes below frame pointer in function main.
**** Purify instrumented ./truetype3 (pid 15292) ****
UMR: Uninitialized memory read:
* This is occurring while in:
ifoo(__true_type) [cca003ib1.o]
main [cca003ib1.o]
_start [crt1.o]
* Reading 1 byte from 0xeffff4c7 on the stack.
* Address 0xeffff4c7 is 17 bytes below frame pointer in function main.
**** Purify instrumented ./truetype3 (pid 15292) ****
Current file descriptors in use: 6
FIU: file descriptor 0: <stdin>
FIU: file descriptor 1: <stdout>
FIU: file descriptor 2: <stderr>
FIU: file descriptor 3: <inherited from parent>
FIU: file descriptor 26: <reserved for Purify internal use>
FIU: file descriptor 27: <reserved for Purify internal use>
No dynamic memory is in use. No leaks are possible.
**** Purify instrumented ./truetype3 (pid 15292) ****
* Program exited with status code 0.
* 2 access errors, 2 total occurrences.
* Basic memory usage (including Purify overhead):
292988 code
79284 data/bss
0 heap (peak use)
2856 stack
* Shared library memory usage (including Purify overhead):
135713 libm.so.1_pure_p3_c0_410_551 (shared code)
5872 libm.so.1_pure_p3_c0_410_551 (private data)
803345 libc.so.1_pure_p3_c0_410_551 (shared code)
34868 libc.so.1_pure_p3_c0_410_551 (private data)
1216 libdl.so.1_pure_p3_c0_410_551 (shared code)
0 libdl.so.1_pure_p3_c0_410_551 (private data)
9576 libinternal_stubs.so.1 (shared code)
324 libinternal_stubs.so.1 (private data)
triton:tests%
So only the inline versions of the function produce the purify errors. And
when I took a look at the assembly code, I understood why. The out-of-line
versions only did some register moves, but the inline versions actually loaded
the value of their argument into a register. Moreover, the non-template
versions contained two useless unconditional branch instructions at the end of
the function. I'm attaching the .s-file generated by egcs-1.0 from the above
source code. Could someone please explain to me the reason why each version of
this empty function generates different assembly? BTW, in when I compiled my
test file with gcc 2.7.0, all of the functions generated the same code, which
was of the form:
foo__FG11__true_type:
!#PROLOGUE# 0
save %sp,-112,%sp
!#PROLOGUE# 1
mov %i0,%o0
b .LL4
nop
b .LL3
nop
.LL4:
.LL3:
ret
restore
I still don't understand why the unconditional branches are necessary, but the
code generation is consistent, anyway.
--
Ian Haggard || ian@shellus.com (work) || IanHaggard@juno.com (home)
GNU/Linux -- "Oh, no, Mr Bill!" || #define employer_opinion !my_opinion
.file "truetype3.cc"
! GNU C++ version egcs-2.90.21 971202 (egcs-1.00 release) (sparc-sun-solaris2.5.1) compiled by GNU C version 2.7.0.
! options passed:
! options enabled: -fpeephole -ffunction-cse -fkeep-static-consts
! -fpcc-struct-return -fexceptions -fcommon -fverbose-asm -fgnu-linker
! -fargument-alias -mepilogue -mapp-regs
gcc2_compiled.:
.section ".text"
.align 4
.global foo__FG11__true_type
.type foo__FG11__true_type,#function
.proc 020
foo__FG11__true_type:
.LLFB1:
!#PROLOGUE# 0
save %sp,-112,%sp
.LLCFI0:
!#PROLOGUE# 1
mov %i0,%o0
b .LL4
nop
b .LL3
nop
.LL4:
.LL3:
ret
restore
.LLFE1:
.LLfe1:
.size foo__FG11__true_type,.LLfe1-foo__FG11__true_type
.align 4
.global main
.type main,#function
.proc 04
main:
.LLFB2:
!#PROLOGUE# 0
save %sp,-120,%sp
.LLCFI1:
!#PROLOGUE# 1
add %fp,-17,%o1
mov %o1,%o0
call __11__true_type,0
nop
add %fp,-17,%o1
mov %o1,%o0
call tifoo__H1Z11__true_type_X01_v,0
nop
add %fp,-17,%o1
mov %o1,%o0
call __11__true_type,0
nop
add %fp,-17,%o1
mov %o1,%o0
call tfoo__H1Z11__true_type_X01_v,0
nop
add %fp,-17,%o1
mov %o1,%o0
call __11__true_type,0
nop
add %fp,-17,%o1
mov %o1,%o0
call ifoo__FG11__true_type,0
nop
add %fp,-17,%o1
mov %o1,%o0
call __11__true_type,0
nop
add %fp,-17,%o1
mov %o1,%o0
call foo__FG11__true_type,0
nop
mov 0,%i0
b .LL5
nop
mov 0,%i0
b .LL5
nop
.LL5:
ret
restore
.LLFE2:
.LLfe2:
.size main,.LLfe2-main
.section ".gnu.linkonce.t.tfoo__H1Z11__true_type_X01_v",#alloc,#execinstr
.align 4
.weak tfoo__H1Z11__true_type_X01_v
.type tfoo__H1Z11__true_type_X01_v,#function
.proc 020
tfoo__H1Z11__true_type_X01_v:
.LLFB3:
!#PROLOGUE# 0
save %sp,-112,%sp
.LLCFI2:
!#PROLOGUE# 1
mov %i0,%o0
.LL9:
ret
restore
.LLFE3:
.LLfe3:
.size tfoo__H1Z11__true_type_X01_v,.LLfe3-tfoo__H1Z11__true_type_X01_v
.section ".gnu.linkonce.t.tifoo__H1Z11__true_type_X01_v",#alloc,#execinstr
.align 4
.weak tifoo__H1Z11__true_type_X01_v
.type tifoo__H1Z11__true_type_X01_v,#function
.proc 020
tifoo__H1Z11__true_type_X01_v:
.LLFB4:
!#PROLOGUE# 0
save %sp,-112,%sp
.LLCFI3:
!#PROLOGUE# 1
mov %i0,%o1
ldub [%o1],%o0
.LL8:
ret
restore
.LLFE4:
.LLfe4:
.size tifoo__H1Z11__true_type_X01_v,.LLfe4-tifoo__H1Z11__true_type_X01_v
.section ".gnu.linkonce.t.ifoo__FG11__true_type",#alloc,#execinstr
.align 4
.weak ifoo__FG11__true_type
.type ifoo__FG11__true_type,#function
.proc 020
ifoo__FG11__true_type:
.LLFB5:
!#PROLOGUE# 0
save %sp,-112,%sp
.LLCFI4:
!#PROLOGUE# 1
mov %i0,%o1
ldub [%o1],%o0
b .LL2
nop
b .LL1
nop
.LL2:
.LL1:
ret
restore
.LLFE5:
.LLfe5:
.size ifoo__FG11__true_type,.LLfe5-ifoo__FG11__true_type
.section ".gnu.linkonce.t.__11__true_type",#alloc,#execinstr
.align 4
.weak __11__true_type
.type __11__true_type,#function
.proc 0110
__11__true_type:
.LLFB6:
!#PROLOGUE# 0
save %sp,-112,%sp
.LLCFI5:
!#PROLOGUE# 1
mov %i0,%o0
.LL7:
mov %o0,%i0
b .LL6
nop
.LL6:
ret
restore
.LLFE6:
.LLfe6:
.size __11__true_type,.LLfe6-__11__true_type
.section ".eh_frame",#alloc,#write
__FRAME_BEGIN__:
.uaword .LLECIE1-.LLSCIE1
.LLSCIE1:
.uaword 0x0
.byte 0x1
.byte 0x0
.byte 0x1
.byte 0x7c
.byte 0x65
.byte 0xc
.byte 0xe
.byte 0x0
.byte 0x9
.byte 0x65
.byte 0xf
.align 4
.LLECIE1:
.uaword .LLEFDE1-.LLSFDE1
.LLSFDE1:
.uaword .LLSFDE1-__FRAME_BEGIN__
.uaword .LLFB1
.uaword .LLFE1-.LLFB1
.byte 0x4
.uaword .LLCFI0-.LLFB1
.byte 0xd
.byte 0x1e
.byte 0x2d
.byte 0x9
.byte 0x65
.byte 0x1f
.align 4
.LLEFDE1:
.uaword .LLEFDE3-.LLSFDE3
.LLSFDE3:
.uaword .LLSFDE3-__FRAME_BEGIN__
.uaword .LLFB2
.uaword .LLFE2-.LLFB2
.byte 0x4
.uaword .LLCFI1-.LLFB2
.byte 0xd
.byte 0x1e
.byte 0x2d
.byte 0x9
.byte 0x65
.byte 0x1f
.align 4
.LLEFDE3:
.uaword .LLEFDE5-.LLSFDE5
.LLSFDE5:
.uaword .LLSFDE5-__FRAME_BEGIN__
.uaword .LLFB3
.uaword .LLFE3-.LLFB3
.byte 0x4
.uaword .LLCFI2-.LLFB3
.byte 0xd
.byte 0x1e
.byte 0x2d
.byte 0x9
.byte 0x65
.byte 0x1f
.align 4
.LLEFDE5:
.uaword .LLEFDE7-.LLSFDE7
.LLSFDE7:
.uaword .LLSFDE7-__FRAME_BEGIN__
.uaword .LLFB4
.uaword .LLFE4-.LLFB4
.byte 0x4
.uaword .LLCFI3-.LLFB4
.byte 0xd
.byte 0x1e
.byte 0x2d
.byte 0x9
.byte 0x65
.byte 0x1f
.align 4
.LLEFDE7:
.uaword .LLEFDE9-.LLSFDE9
.LLSFDE9:
.uaword .LLSFDE9-__FRAME_BEGIN__
.uaword .LLFB5
.uaword .LLFE5-.LLFB5
.byte 0x4
.uaword .LLCFI4-.LLFB5
.byte 0xd
.byte 0x1e
.byte 0x2d
.byte 0x9
.byte 0x65
.byte 0x1f
.align 4
.LLEFDE9:
.uaword .LLEFDE11-.LLSFDE11
.LLSFDE11:
.uaword .LLSFDE11-__FRAME_BEGIN__
.uaword .LLFB6
.uaword .LLFE6-.LLFB6
.byte 0x4
.uaword .LLCFI5-.LLFB6
.byte 0xd
.byte 0x1e
.byte 0x2d
.byte 0x9
.byte 0x65
.byte 0x1f
.align 4
.LLEFDE11:
.ident "GCC: (GNU) egcs-2.90.21 971202 (egcs-1.00 release)"
More information about the Gcc-bugs
mailing list