From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jim Wilson To: Mark Mitchell Cc: schwab@suse.de, gcc@gcc.gnu.org, wilson@redhat.com Subject: Re: Bootstrap failure of gcc-ss-20010409 in ia64 Date: Fri, 13 Apr 2001 19:13:00 -0000 Message-id: <200104140213.TAA32124@wilson.cygnus.com> References: <20010411174320Q.mitchell@codesourcery.com> X-SW-Source: 2001-04/msg00647.html 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 struct char_traits; template class allocator; template, typename _Alloc = allocator<_CharT> > class basic_string; template class allocator { public: ~allocator() throw() {} }; static inline void __attribute__ ((__unused__)) __atomic_add (int* __mem, int __val) { __sync_fetch_and_add_si (__mem, __val); } template 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 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;