[PATCH] D35851: [Dominators] Include infinite loops in PostDominatorTree

Hal Finkel via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 11 19:22:26 PDT 2017

hfinkel added a comment.

I think that we should go ahead with this approach.

I agree with Tobias that this has some unfortunate properties. For example, if we have:

  br cond, blocka, blockb
  br blocka
  br blockc

Can we use post-dominance to verify that the `lifetime_end(a)` is correctly placed and sufficient (i.e. do the set of `lifetime_end(a)` post-dominate the `lifetime_start(a)`? If we connect infinite loops to the exit node, then the answer is no (because, as in this example, it isn't true that the set of `lifetime_end(a)` post-dominates `lifetime_start(a)`, even though the set is correctly placed and sufficient). What's frustrating about this is that the definition of post-dominance seems perfect for this task: we want to ensure that all paths from the `lifetime_start(a)` to the exit pass through one of the `lifetime_end(a)s`.

There is also a small wrinkle in the above argument in that it also ignores functions that may throw (which don't induce any extra edges in the PDT to the exit). In the particular case of lifetime management of stack locations, this is okay (because the unwind edge implicitly includes a lifetime_end of everything on the stack). I'm not sure how well this generalizes, however, to other use cases. There's also no good way to change this (because functions that might unwind aren't terminators -- which I think that we should change, but that's perhaps another story).

Nevertheless, given that we have infinite loops, it is unclear that we'd ever be able to use post-dominance to verify the lifetime intrinsics. To do so would imply that, among other things, we could use post-dominance within infinite loops as well. Given that, within the loop there are no paths to the exit node, or if you add one you must do it arbitrarily, it is not obvious to me that you can construct a definition that makes sense there.

These issues are discussed in the literature. For example, see:

A new foundation for control-dependence and slicing for modern program structures
VP Ranganath, et al. - ESOP, 2005 

There seems to be an active effort, to the present day, to understand how to analyze non-terminating programs, especially in the program-slicing literature - search for "non-termination sensitive control dependence" (on Google scholar or similar) and you'll find a significant amount of discussion. However, I don't see a clear answer in the literature for what to do here, and quickly scanning a few of the papers, it seems that the relevant algorithms are all less efficient than the ones based on traditional post-dominance (i.e. which connect everything to a virtual exit node). When Tobias and I discussed this in June, I don't recall settling on an obviously-better scheme. We discussed various ways for adding virtual edges to other places in the graph, instead of to the exit node, but no heuristic seemed ideal. I don't recall discussing removing edges as has been discussed here (and whereas with adding edges it still seems possible to generate a conservatively-correct graph, removing edges seems prone to doing otherwise - and that makes me a bit nervous). As a result, I'm in favor of moving forward with the current patch. I'd like to think that we can do better, but I'm convinced that we know how yet.

Another thing that Tobias and I discussed in June was a desire to handle unreachable and infinite loops in a consistent way. I agree with this, and while unfortunate, this does have that consistency property.


More information about the llvm-commits mailing list