Support bounds widening for conditionals with while loops #803
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Added support for widenening bounds for nt_array_ptr dereferences in while
loops. For example, "while (*p) {}" would widen the bounds of p upon
entry to the loop.
To compute In[B] we compute the intersection of Out[B*->B], where B* are all
preds of B. When there is a back edge from block B' to B (for example in
loops), the Out set for block B' will be empty when we first enter B. As a
result, the intersection operation would always result in an empty In set for
B.
So to handle this, we consider the In and Out sets for all blocks to have a
default value of "Top" which indicates a set of all members of the Gen set. In
this way we ensure that the intersection does not result in an empty set even
if the Out set for a block is actually empty.
But we also need to handle the case where there is an unconditional jump into a
block (for example, as a result of a goto). In this case, we cannot widen the
bounds because we would not have checked for the ptr dereference. So in this
case we want the intersection to result in an empty set.
So we initialize the In and Out sets of all blocks, except the Entry block, as
"Top".
Top represents the union of the Gen sets of all edges. We have chosen the
offsets of ptr variables in Top to be the max unsigned int. The reason behind
this is that in order to compute the actual In sets for blocks we are going to
intersect the Out sets on all the incoming edges of the block. And in that case
we would always pick the ptr with the smaller offset. Chosing max unsigned int
also makes handling Top much easier as we do not need to explicitly store edge
info.