@@ -1954,4 +1954,85 @@ module Make<LocationSig Location, InputSig<Location> Input> {
1954
1954
}
1955
1955
}
1956
1956
}
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
+ }
1957
2038
}
0 commit comments