[LLVMdev] How to handle divide-by-zero exception?

Marc B. Reynolds marc.reynolds at orange.fr
Sat May 10 07:16:30 PDT 2008


DISCLAIMER:  I am SSA, LLVM and compiler ignorant, so take the following for
what it is worth.

What about logically breaking a (complex) SEH method into two logical
methods, as per this pseudo-code as an example:

-----------------------

foo(parameter-list)
{
  leading-statements;

  try {
    try-statements;
  }
  catch(Execption0 ex0) {
    catch-0-statements;
  }
  .
  catch(ExceptionN exN) {
    catch-n-statements;
  }
  finally {
    final-statemements
  }

  tail-statements;
} 


foo$n(parameter-list)
{
  leading-statements.

  PushTheExceptionHandler(foo$x);

  try-statements

  PopTheExceptionHandler();
     
  final-statements;
  tail-statements;
} 

foo$x(ExceptionInformation info)
{
  // here the stack-pointer and frame-base-pointer
  // should be the same as at the beginning of the
  // try-block. Local variables from 'foo$n' are
  // at the same offsets.

  if (isExeception0) {
   catch-0-statements;
  }
  .
  else if (isExecptionN) {
    catch-n-statements;
  }
  else {
     unwind-to-next-handler();
  }

  final-statements;
  tail-statements;
} 

-------------------------

The rough idea is:

1) Make lists of the global & local variables modified in 'try-statements'
and accessed
   in 'foo$x', per catch-?-statements.  Those that are access in
'final-statements' and
   'tail-statements' are added to a separate list.
2) Add memory-stores for each modified global & local variable in
'leading-statements',
   which is also accessed in 'foo$x'
3) The local variables from the previous two points need slots in the
stack-frame of
   foo$n, so that foo$x can access them if executed.
4) Flag all potentially excepting instructions (PEI).  Note that a given
instruction
   might match more that one catch block.
5) For each possible exception that an instruction may throw, trace backward
and find
   the first occurrence of any value updated that is in either that
'catch-?-statements'
   list or the list of the final-parts.  This instruction should be marked
with an
   additional 'serializing' flag, which indicates that it needs to be stored
to memory
   prior to the PEI in question and cannot be moved past it.

Then optimize the two methods as if they were otherwise independent.
Various optimizations would obviously be able to 'unflag' an op previous
marked PEI and the serialize flags would need adjustment.

The back-end compiler pass could attempt to 'merge' the two functions.






More information about the llvm-dev mailing list