This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Test distilled from -gdwarf-2 -O3 bootstrap failure
- From: Alexandre Oliva <aoliva at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: gcc at gcc dot gnu dot org
- Date: 25 Feb 2002 00:35:06 -0300
- Subject: Re: Test distilled from -gdwarf-2 -O3 bootstrap failure
- Organization: GCC Team, Red Hat
- References: <orwux2byts.fsf@free.redhat.lsd.ic.unicamp.br><or664m75r4.fsf@free.redhat.lsd.ic.unicamp.br>
On Feb 24, 2002, Alexandre Oliva <aoliva@redhat.com> wrote:
> Ok, I've figured out what's going on. In the first round of expanding
> C bodies, f3() is deemed too big to be tree-inlined, so generation of
> RTL is not deferred for it, but generation of assembly is. f4() is
> compiled to RTL and then assembly is generated for it, because it's
> referenced (by itself :-(, so f3() has to be emitted out-of-line
> because it couldn't be inlined.
> In the second round(), we generate RTL for f1() and f2(), but they are
> never emitted because they are inlined. After generating assembly for
> f3(), however, we get in trouble because:
> - the inlined block from f1() contains the statement expression passed
> as an argument from f2
> - the block copied from f1() was marked as ABSTRACT when we started
> generating debugging info for the inlined f2:
> dwarf2out_abstract_function() set the abstract flag in all blocks
> within f2, irregardless of whether they came from other functions.
> I tried to skip blocks from f1(), but then we'd try to expand the
> initializer of its argument and lose. It appears to me that we should
> be emitting debugging info for f1() just like for f2(), but the test
> for the block abstractness prevents that: blocks of inlined functions
> into inlined functions will always be marked as abstract.
> I'm now testing two different patches for the problem. The first
> removes the test for abstractness of the block; the second simply
> arranges for us to generate declarations of the block. The latter is
> enough to prevent the crash, and it seems reasonable under the
> principle that, if we don't generate debugging info for the whole
> block, we must at least generate it for the initializers of the
> parameters, as we'd have done had we not chosen to generate debugging
> info for the function.
> However, it appears to me that the former should be the right
> approach, since I don't see why handling f1 should be any different
> from f2. We might emit more debugging info than necessary, though
> (but I'm not really sure about it). Anyhow, it actually fails to
> bootstrap, as some labels referenced in the debugging info don't
> make it to the output. So I'm leaning towards the second patch, but
> if others agree the former would be better, I'll dig deeper :-)
> For reference, here's the testcase I'm going to install in
> gcc.dg/debug (thanks Jakub!) as soon as a patch for the bug is
> approved, and the two candidate patches I'm testing (the first one
> actually fails to bootstrap, while the second is doing well, but I
> have doubts as to the correctness of the generated info). ChangeLog
> entries missing because this is not a patch submission, just a RFC.
> So... any comments?
Here's another alternative I'm trying right now. It appears to be the
better than both I posted earlier, and it has just completed bootstrap
on athlon-pc-linux-gnu with BOOT_CFLAGS='-O3 -g'. Ok to install if no
regressions are introduced in the testsuite?
Index: gcc/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* dwarf2out.c (gen_inlined_subroutine_die): If block is abstract,
generate a die for the lexical block.
Index: gcc/dwarf2out.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/dwarf2out.c,v
retrieving revision 1.356
diff -u -p -r1.356 dwarf2out.c
--- gcc/dwarf2out.c 2002/02/21 23:03:14 1.356
+++ gcc/dwarf2out.c 2002/02/25 02:57:09
@@ -10574,6 +10574,20 @@ gen_inlined_subroutine_die (stmt, contex
decls_for_scope (stmt, subr_die, depth);
current_function_has_inlines = 1;
}
+ else
+ /* We may get here if we're the outer block of function A that was
+ inlined into function B that was inlined into function C. When
+ generating debugging info for C, dwarf2out_abstract_function(B)
+ would mark all inlined blocks as abstract, including this one.
+ So, we wouldn't (and shouldn't) expect labels to be generated
+ for this one. Instead, just emit debugging info for
+ declarations within the block. This is particularly important
+ in the case of initializers of arguments passed from B to us:
+ if they're statement expressions containing declarations, we
+ wouldn't generate dies for their abstract variables, and then,
+ when generating dies for the real variables, we'd die (pun
+ intended :-) */
+ gen_lexical_block_die (stmt, context_die, depth);
}
/* Generate a DIE for a field in a record, or structure. */
Index: gcc/testsuite/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* gcc.dg/debug/20020224-1.c: New.
Index: gcc/testsuite/gcc.dg/debug/20020224-1.c
===================================================================
RCS file: 20020224-1.c
diff -N 20020224-1.c
--- /dev/null Tue May 5 13:32:27 1998
+++ gcc/testsuite/gcc.dg/debug/20020224-1.c Sun Feb 24 18:57:15 2002
@@ -0,0 +1,60 @@
+/* { dg-do compile } */
+
+/* Here's the deal: f3 is not inlined because it's too big, but f2 and
+ f1 are inlined into it. We used to fail to emit debugging info for
+ t1, because it was moved inside the (inlined) block of f1, marked
+ as abstract, then we'd crash. */
+
+#define UNUSED __attribute__((unused))
+#define EXT __extension__
+
+int undef(void);
+
+inline static void
+f1 (int i UNUSED)
+{
+}
+
+inline static void
+f2 (void)
+{
+ f1 (EXT ({ int t1 UNUSED; undef (); }));
+}
+
+inline static void
+f3 (void)
+{
+ int v1 UNUSED;
+ int v2 UNUSED;
+
+ EXT ({ int t2 UNUSED; if (0) undef (); 0; })
+ && EXT ({ int t3 UNUSED; if (0) undef (); 0; });
+
+ if (1)
+ {
+ undef ();
+ if (1)
+ f2 ();
+ }
+
+ {
+ undef ();
+ }
+}
+
+inline static void
+f4 (void)
+{
+ EXT ({ undef (); 1; }) && EXT ({ int t4 UNUSED = ({ 1; }); 1; });
+
+ { }
+
+ EXT ({ int t5 UNUSED; if (0) undef (); 0; });
+
+ f4 ();
+
+ undef ();
+ f3 ();
+
+ return;
+}
--
Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist Professional serial bug killer