[LLVMdev] unwinds to in the CFG

Nick Lewycky
Fri, 28 Mar 2008 06:15:41 -0000

I have a new plan for handling 'unwinds to' in the control flow graph
and dominance.

Just as a quick recap the problem I encountered is how to deal
instructions in a block being used as operands in the unwind dest. Such
as this:

bb1: unwinds to %cleanup
   call void @foo() ; might throw, might not
   %x = add i32 %y, %z
   call void @foo() ; might throw, might not
   ret void
cleanup:
   call void @use(i32 %x)

The problem is that %x might not have been executed before we enter
%cleanup.

I won't reiterate what my previous plan was. The problem with it was
that a lot of optimizations use the dominance tree to decide where it's
safe to insert new instructions and it always assumes that if A dom B
then an instruction in A is always accessible in B.

Here's the new plan. Please poke holes in it.

A. redefine the CFG a bit.
  i.   pred_iterator stays the same.
  ii.  succ_iterator only iterates over successors
  iii. outedge_iterator iterates over successors and the unwind dest

There's still some code which refers to outedges by TerminatorInst +
unsigned. I can't think of any reason not to replace all of them with
outedge_iterator.

B. redefine the dominator tree by modifying the GraphTraits
  i.  A dom B means that all instructions in A are guaranteed to execute
before any instructions in B.
  ii. the domtree may have multiple roots.

Multiple roots occurs when the entry block 'unwinds to' another block.
Domtree getRoot() should just return the root represented by the
Function entry block, and if anyone needs it would could provide
getAllRoots(). We would also need to add an "isReachable" method to
domtree and replace all users who currently test for reachability by
checking whether the block is dominated by the root.

Before I start investing time implementing these changes, does anyone
foresee any problems that I missed?

Nick