@@ -26,13 +26,15 @@ private class GvnKindStmt extends GvnKind, TGvnKindStmt {
2626}
2727
2828private class GvnKindDeclaration extends GvnKind , TGvnKindDeclaration {
29- private GvnKindExpr kind ;
29+ private int kind ;
3030 private boolean isTargetThis ;
3131 private Declaration d ;
3232
3333 GvnKindDeclaration ( ) { this = TGvnKindDeclaration ( kind , isTargetThis , d ) }
3434
35- override string toString ( ) { result = kind .toString ( ) + "," + isTargetThis + "," + d .toString ( ) }
35+ override string toString ( ) {
36+ result = "Expr(" + kind .toString ( ) + ")," + isTargetThis + "," + d .toString ( )
37+ }
3638}
3739
3840/** Gets the declaration referenced by the expression `e`, if any. */
@@ -89,21 +91,28 @@ private class GvnStruct extends Gvn, TGvnStruct {
8991 override string toString ( ) { result = "(" + head .toString ( ) + " :: " + tail .toString ( ) + ")" }
9092}
9193
94+ pragma [ noinline]
95+ private predicate gvnKindDeclaration (
96+ ControlFlowElement cfe , int kind , boolean isTargetThis , Declaration d
97+ ) {
98+ isTargetThis = isTargetThis ( cfe ) and
99+ d = referenceAttribute ( cfe ) and
100+ expressions ( cfe , kind , _)
101+ }
102+
92103/**
93104 * Gets the `GvnKind` of the element `cfe`.
94105 * In case `cfe` is a reference attribute, we encode the entire declaration and whether
95106 * the target is semantically equivalent to `this`.
96107 */
97108private GvnKind getGvnKind ( ControlFlowElement cfe ) {
98- exists ( GvnKind kind |
99- kind = getKind ( cfe ) and
100- (
101- result = TGvnKindDeclaration ( kind , isTargetThis ( cfe ) , referenceAttribute ( cfe ) )
102- or
103- not exists ( referenceAttribute ( cfe ) ) and
104- result = kind
105- )
109+ exists ( int kind , boolean isTargetThis , Declaration d |
110+ gvnKindDeclaration ( cfe , kind , isTargetThis , d ) and
111+ result = TGvnKindDeclaration ( kind , isTargetThis , d )
106112 )
113+ or
114+ not exists ( referenceAttribute ( cfe ) ) and
115+ result = getKind ( cfe )
107116}
108117
109118private Gvn gvnConstructed ( ControlFlowElement cfe , GvnKind kind , int index ) {
@@ -156,9 +165,9 @@ private module Cached {
156165 newtype TGvnKind =
157166 TGvnKindExpr ( int kind ) { expressions ( _, kind , _) } or
158167 TGvnKindStmt ( int kind ) { statements ( _, kind ) } or
159- TGvnKindDeclaration ( GvnKindExpr kind , boolean thisTarget , Declaration d ) {
168+ TGvnKindDeclaration ( int kind , boolean thisTarget , Declaration d ) {
160169 exists ( Expr e |
161- d = referenceAttribute ( e ) and thisTarget = isTargetThis ( e ) and kind = getKind ( e )
170+ d = referenceAttribute ( e ) and thisTarget = isTargetThis ( e ) and expressions ( e , kind , _ )
162171 )
163172 }
164173
@@ -218,15 +227,18 @@ abstract class StructuralComparisonConfiguration extends string {
218227 */
219228 abstract predicate candidate ( ControlFlowElement x , ControlFlowElement y ) ;
220229
230+ pragma [ inline]
231+ private predicate sameGvn ( ControlFlowElement x , ControlFlowElement y ) {
232+ pragma [ only_bind_into ] ( toGvn ( pragma [ only_bind_out ] ( x ) ) ) =
233+ pragma [ only_bind_into ] ( toGvn ( pragma [ only_bind_out ] ( y ) ) )
234+ }
235+
221236 /**
222237 * Holds if elements `x` and `y` structurally equal. `x` and `y` must be
223238 * flagged as candidates for structural equality, that is,
224239 * `candidate(x, y)` must hold.
225240 */
226- predicate same ( ControlFlowElement x , ControlFlowElement y ) {
227- candidate ( x , y ) and
228- toGvn ( x ) = toGvn ( y )
229- }
241+ predicate same ( ControlFlowElement x , ControlFlowElement y ) { candidate ( x , y ) and sameGvn ( x , y ) }
230242}
231243
232244/**
@@ -272,14 +284,17 @@ module Internal {
272284 */
273285 abstract predicate candidate ( ControlFlowElement x , ControlFlowElement y ) ;
274286
287+ pragma [ inline]
288+ private predicate sameGvn ( ControlFlowElement x , ControlFlowElement y ) {
289+ pragma [ only_bind_into ] ( toGvn ( pragma [ only_bind_out ] ( x ) ) ) =
290+ pragma [ only_bind_into ] ( toGvn ( pragma [ only_bind_out ] ( y ) ) )
291+ }
292+
275293 /**
276294 * Holds if elements `x` and `y` structurally equal. `x` and `y` must be
277295 * flagged as candidates for structural equality, that is,
278296 * `candidate(x, y)` must hold.
279297 */
280- predicate same ( ControlFlowElement x , ControlFlowElement y ) {
281- candidate ( x , y ) and
282- toGvn ( x ) = toGvn ( y )
283- }
298+ predicate same ( ControlFlowElement x , ControlFlowElement y ) { candidate ( x , y ) and sameGvn ( x , y ) }
284299 }
285300}
0 commit comments