[LLVMbugs] [Bug 1916] New: LLVM stack unwinding is slow

bugzilla-daemon at cs.uiuc.edu bugzilla-daemon at cs.uiuc.edu
Mon Jan 14 10:46:58 PST 2008


           Summary: LLVM stack unwinding is slow
           Product: new-bugs
           Version: unspecified
          Platform: Other
        OS/Version: Linux
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: new bugs
        AssignedTo: unassignedbugs at nondot.org
        ReportedBy: baldrick at free.fr
                CC: llvmbugs at cs.uiuc.edu

When unwinding code generated by LLVM, every invoke encountered causes
a branch to the corresponding landing pad, even if all the handler is
going to do for that exception is reraise it (in extreme cases you get
PR1913).  This is because we add a catch-all to the dwarf unwind tables
in order to enforce the semantics of invoke (an invoke always branches to
the landing pad whenever an exception unwinds through it).  If we don't
enforce them then things can break!  [Here's an example: compile at -O0
then use opt -std-compile-opts to cause inlining.

#include <cstdio>
class A {
  A() {}
  ~A() {}
void f() {
  A a;
  throw 5.0;
main() {
  try {
   } catch(...) { printf("caught\n"); }

You don't get "caught" unless a catch-all was pushed in the original IR].

The result is slower unwinding.  When unwinding an exception using code
compiled with mainline gcc, you only get a branch to the final landing pad
that actually handles the exception, and not to every landing pad encountered
as the stack is unwound.

I think this can be fixed at codegen time (no inlining is done by codegen):
we can drop the semantics of invoke and no longer require all exceptions that
unwind through an invoke to branch to the landing pad.  I think we can do this
without needing to know how to recognise the catch-all for the language: the
eh.selector has an array of type infos and returns what amounts to an index
into that array.  For each possible index value we can analyse the control
flow, and determine those for which only trivial code is executed followed by
a rewind.  It would be nice to say that we could remove all those indices from
the eh.selector call, but we can't (see later example) but we can remove
such an index if it is the last one, which is the most important case anyway
since that is almost always the "catch-all" we added.  Here's the example:  
suppose an exception E matches typeinfo A and also typeinfo B (this is possible
with C++).  If, in the selector, A occurs before B, and we do
something trivial if A matches but something non-trivial if B matches, then
removing the A typeinfo would change the behaviour if an E is thrown.

Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.

More information about the llvm-bugs mailing list