This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Test distilled from -gdwarf-2 -O3 bootstrap failure


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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]