Bootstrap failure of gcc-ss-20010409 in ia64
Jim Wilson
wilson@cygnus.com
Fri Apr 13 19:13:00 GMT 2001
My work on the IA-64 port has been hampered lately because I've been running
into too many different regressions all at the same time. I found four
serious regressions all at about the same time. Disentagling all of the
problems has been hard.
1) The trunk was broken by Richard's large C++ EH/Unwind API patch which went
in without any IA-64 support. This caused builds to break early, during
the stage1 gcc build. This patch did not go on the branch. This was fixed
by hacking the trunk to use setjmp/longjmp EH for IA-64, which is something
that still needs to be fixed. Hopefully the same breakage won't go on the
branch when this patch gets moved to the branch. If so, that will make
use of the gcc3 branch undesirable for IA-64 C++ code.
2) The branch was broken by your patch to throttle C++ inlining. This patch
went on both the trunk and the branch. This caused builds to fail late,
during the target libstdc++ build. At the time, I assumed both the branch
and trunk were broken because of this patch, but that I couldn't see the
problem on the trunk because of the large C++ EH patch. That seems to be
mistaken as I haven't been able to reproduce the problem on the trunk.
3) I discovered that debugging binaries built by gcc no longer worked right.
If I use the assembler that comes with my OS release, gdb reports the right
line number but the wrong filename when debugging a stage2 cc1plus on the
trunk. This makes debugging difficult, but still possible. If I try the
binutils 2.11 assembler, I get gdb segfaults debugging a stage2 cc1plus on
the trunk. This make debugging impossible. This has forced me to build
stage1 cc1plus binaries to be able to debug C++ testcases. I suspect this
is related to the dwarf2out.c file table changes in gcc and binutils by
Richard et al. I also see similar problems on the gcc3 branch.
4) An IA-64 backend patch I wrote to fix a linux kernel miscompilation problem
triggered a latent assembler problem. This was discovered after binutils
2.11. has been released. This forces me to use an up-to-date assembler for
gcc builds now. Unfortunately, using an up-to-date assembler exacerbates
the above problem #3.
It will take some time for me to get all of these problems resolved.
For the moment, just concentrating on the one problem that you are asking
about, problem #2...
The problem is easy to reproduce on the branch. We get the dwarf2out.c
abort when compiling libstdc++. I can reproduce this with a native ia64-linux
compiler, and with a cross from x86-linux to ia64-linux. I haven't been able
to reproduce the problem on the trunk. I checked out a copy of the trunk
using -D"March 27, 2001", which includes your C++ throttling patch, but none
of Richard's C++ EH/Unwind API patch. The problem does not show up there.
So my earlier comment about Dan's patch working on the trunk should be
disregarded.
Curiously, the testcase does not fail with a native x86-linux compiler.
That may be because of the IA-64 built-in function used by the testcase, or
it may be because an optimization pass (like reorder-blocks) is changing
the decls in a machine dependent way that only causes the problem to show
up for some targets.
The testcase fails on the branch because of the __exception_info symbol.
This disappears with Richard's patch, thus there is a chance that the problem
will go away when Richard's patch goes on the branch. Interestingly, this
symbol is still present on the trunk in the March 27 tree I checked out, but
the problem does not show up there. Hence I suspect that it is just an
accident that the problem is showing up with this symbol on the branch, and
that Richard's patch won't actually make the problem go away, but rather will
just make it a latent problem. The real problem is probably elsewhere, though
it could be in any of the C++ front end, the dwarf2out.c file, the IA-64
back-end, or in the optimizer.
At the moment, I haven't spent any significant time debugging dwarf2out
to see if I can identify the problem. I'm very close to finishing problem
#4, the linux kernel miscompilation and latent assembler bug. After I resolve
these problems, I will spend some more time looking into the dwarf2out.c
abort. I will also have to look at the dwarf2 file table problem sometime
soon. Not being able to debug stage2/stage3 gcc binaries makes it hard to
work on build failures, so this is also a serious problem even though it
doesn't cause an obvious build failure.
I did spend some time creating a smaller testcase to make the problem easier
to debug. The following testcase is 86 lines, and aborts in dwarf2out.c
for an ia64-linux target when compiled with -O2 -S -g. This testcase can
probably be reduced even further, but I was at the point of diminishing
returns, plus I have limited C++ knowledge and wasn't sure how to simplify
some parts of the testcase.
template<class _CharT>
struct char_traits;
template<typename _Alloc>
class allocator;
template<typename _CharT, typename _Traits = char_traits<_CharT>,
typename _Alloc = allocator<_CharT> >
class basic_string;
template <class _Tp>
class allocator {
public:
~allocator() throw() {}
};
static inline void
__attribute__ ((__unused__))
__atomic_add (int* __mem, int __val)
{
__sync_fetch_and_add_si (__mem, __val);
}
template<typename _CharT, typename _Traits, typename _Alloc>
class basic_string
{
public:
typedef _Alloc allocator_type;
private:
struct _Rep
{
int _M_references;
bool
_M_is_leaked() const
{ return _M_references < 0; }
_CharT*
_M_refdata() throw()
{ return reinterpret_cast<_CharT*> (this + 1); }
_CharT*
_M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2)
{ return (!_M_is_leaked()) ? _M_refcopy() : _M_clone(__alloc1); }
_CharT*
_M_refcopy() throw()
{
__atomic_add(&_M_references, 1);
return _M_refdata();
}
_CharT*
_M_clone(const _Alloc&);
};
struct _Alloc_hider : _Alloc
{
_Alloc_hider(_CharT* __dat, const _Alloc& __a)
: _Alloc(__a), _M_p(__dat) { }
_CharT* _M_p;
};
mutable _Alloc_hider _M_dataplus;
_CharT*
_M_data() const
{ return _M_dataplus._M_p; }
_Rep*
_M_rep() const
{ return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); }
public:
basic_string(const basic_string& __str);
};
template<typename _CharT, typename _Traits, typename _Alloc>
basic_string<_CharT, _Traits, _Alloc>::
basic_string(const basic_string& __str)
: _M_dataplus(__str._M_rep()->_M_grab(_Alloc(), _Alloc ()), _Alloc ())
{ }
template class basic_string<char>;
More information about the Gcc
mailing list