Expose some of the internal predicates to PrintSSA.qll. We do this by publicly importing those modules in the
DebugSsa module, which is then imported by PrintSSA.
Module containing the predicates that connect uses to their reaching definition. The reaching definitions are computed separately for each unique use
MemoryLocation. An instruction is treated as a definition of a use location if the defined location overlaps the use location in any way. Thus, a single instruction may serve as a definition for multiple use locations, since a single definition location may overlap many use locations.
Module to handle insertion of
Phi instructions at the correct blocks. We insert a
Phi instruction at the beginning of a block for a given location when that block is on the dominance frontier of a definition of the location and there is a use of that location reachable from that block without an intervening definition of the location. Within the approach outlined above, we treat a location slightly differently depending on whether or not it is a virtual variable. For a virtual variable, we will insert a
Phi instruction on the dominance frontier if there is a use of any member location of that virtual variable that is reachable from the
Phi instruction. For a location that is not a virtual variable, we insert a
Phi instruction only if there is an exactly-overlapping use of the location reachable from the
Phi instruction. This ensures that we insert a
Phi instruction for a non-virtual variable only if doing so would allow dataflow analysis to get a more precise result than if we just used a
Phi instruction for the virtual variable as a whole.