@@ -1954,4 +1954,85 @@ module Make<LocationSig Location, InputSig<Location> Input> {
19541954 }
19551955 }
19561956 }
1957+
1958+ /**
1959+ * Provides query predicates for testing adjacent SSA references and
1960+ * insertion of phi reads.
1961+ */
1962+ module TestAdjacentRefs {
1963+ private newtype TRef =
1964+ TRefRead ( BasicBlock bb , int i , SourceVariable v ) { variableRead ( bb , i , v , true ) } or
1965+ TRefDef ( Definition def ) or
1966+ TRefPhiRead ( BasicBlock bb , SourceVariable v ) { synthPhiRead ( bb , v ) }
1967+
1968+ /**
1969+ * An SSA reference. This is either a certain read, a definition, or a
1970+ * synthesized phi read.
1971+ */
1972+ class Ref extends TRef {
1973+ /** Gets the source variable referenced by this reference. */
1974+ SourceVariable getSourceVariable ( ) {
1975+ this = TRefRead ( _, _, result )
1976+ or
1977+ exists ( Definition def | this = TRefDef ( def ) and def .getSourceVariable ( ) = result )
1978+ or
1979+ this = TRefPhiRead ( _, result )
1980+ }
1981+
1982+ predicate isPhiRead ( ) { this = TRefPhiRead ( _, _) }
1983+
1984+ /** Gets a textual representation of this SSA reference. */
1985+ string toString ( ) {
1986+ this = TRefRead ( _, _, _) and result = "SSA read(" + this .getSourceVariable ( ) + ")"
1987+ or
1988+ exists ( Definition def | this = TRefDef ( def ) and result = def .toString ( ) )
1989+ or
1990+ this = TRefPhiRead ( _, _) and result = "SSA phi read(" + this .getSourceVariable ( ) + ")"
1991+ }
1992+
1993+ /** Gets the location of this SSA reference. */
1994+ Location getLocation ( ) {
1995+ exists ( BasicBlock bb , int i |
1996+ this = TRefRead ( bb , i , _) and bb .getNode ( i ) .getLocation ( ) = result
1997+ )
1998+ or
1999+ exists ( Definition def | this = TRefDef ( def ) and def .getLocation ( ) = result )
2000+ or
2001+ exists ( BasicBlock bb | this = TRefPhiRead ( bb , _) and bb .getLocation ( ) = result )
2002+ }
2003+
2004+ /** Holds if this reference of `v` occurs in `bb` at index `i`. */
2005+ predicate accessAt ( BasicBlock bb , int i , SourceVariable v ) {
2006+ this = TRefRead ( bb , i , v )
2007+ or
2008+ exists ( Definition def | this = TRefDef ( def ) and def .definesAt ( v , bb , i ) )
2009+ or
2010+ this = TRefPhiRead ( bb , v ) and i = - 1
2011+ }
2012+ }
2013+
2014+ /**
2015+ * Holds if `r2` is a certain read or uncertain write, and `r1` is the
2016+ * unique prior reference.
2017+ */
2018+ query predicate adjacentRefRead ( Ref r1 , Ref r2 ) {
2019+ exists ( BasicBlock bb1 , int i1 , BasicBlock bb2 , int i2 , SourceVariable v |
2020+ r1 .accessAt ( bb1 , i1 , v ) and
2021+ r2 .accessAt ( bb2 , i2 , v ) and
2022+ AdjacentSsaRefs:: adjacentRefRead ( bb1 , i1 , bb2 , i2 , v )
2023+ )
2024+ }
2025+
2026+ /**
2027+ * Holds if `phi` is a phi definition or phi read and `input` is one its
2028+ * inputs without any other reference in-between.
2029+ */
2030+ query predicate adjacentRefPhi ( Ref input , Ref phi ) {
2031+ exists ( BasicBlock bb , int i , BasicBlock bbPhi , SourceVariable v |
2032+ input .accessAt ( bb , i , v ) and
2033+ phi .accessAt ( bbPhi , - 1 , v ) and
2034+ AdjacentSsaRefs:: adjacentRefPhi ( bb , i , _, bbPhi , v )
2035+ )
2036+ }
2037+ }
19572038}
0 commit comments