55
66import csharp
77
8- private newtype TGvnKind =
9- TGvnKindExpr ( int kind ) { expressions ( _, kind , _) } or
10- TGvnKindStmt ( int kind ) { statements ( _, kind ) } or
11- TGvnKindDeclaration ( GvnKindExpr kind , boolean thisTarget , Declaration d ) {
12- exists ( Expr e |
13- d = referenceAttribute ( e ) and thisTarget = isTargetThis ( e ) and kind = getKind ( e )
14- )
15- }
16-
178abstract private class GvnKind extends TGvnKind {
189 abstract string toString ( ) ;
1910}
@@ -71,16 +62,6 @@ private GvnKind getKind(ControlFlowElement cfe) {
7162 )
7263}
7364
74- /**
75- * Type for containing the global value number of a control flow element.
76- * A global value number, can either be a constant or a list of global value numbers,
77- * where the list also carries a `kind`, which is used to distinguish between general expressions,
78- * declarations and statements.
79- */
80- private newtype TGvn =
81- TConstantGvn ( string s ) { s = any ( Expr e ) .getValue ( ) } or
82- TListGvn ( GvnList l )
83-
8465/** The global value number of a control flow element. */
8566abstract class Gvn extends TGvn {
8667 /** Gets the string representation of this global value number. */
@@ -99,14 +80,6 @@ private class ListGvn extends Gvn, TListGvn {
9980 override string toString ( ) { result = "[" + l .toString ( ) + "]" }
10081}
10182
102- /**
103- * Type for containing a list of global value numbers with a kind.
104- * The empty list carries the kind of the controlflowelement.
105- */
106- private newtype TGvnList =
107- TGvnNil ( GvnKind gkind ) or
108- TGvnCons ( Gvn head , GvnList tail ) { gvnConstructedCons ( _, _, _, head , tail ) }
109-
11083abstract private class GvnList extends TGvnList {
11184 abstract string toString ( ) ;
11285}
@@ -176,14 +149,56 @@ private ControlFlowElement getRankedChild(ControlFlowElement cfe, int rnk) {
176149 )
177150}
178151
152+ pragma [ noinline]
153+ private Gvn gvnChild ( ControlFlowElement cfe , int index ) {
154+ result = toGvn ( getRankedChild ( cfe , index ) )
155+ }
156+
157+ pragma [ noinline]
179158private predicate gvnConstructedCons (
180- ControlFlowElement e , GvnKind kind , int index , Gvn head , GvnList tail
159+ ControlFlowElement cfe , GvnKind kind , int index , Gvn head , GvnList tail
181160) {
182- tail = gvnConstructed ( e , kind , index - 1 ) and
183- head = toGvn ( getRankedChild ( e , index ) )
161+ tail = gvnConstructed ( cfe , kind , index - 1 ) and
162+ head = gvnChild ( cfe , index )
184163}
185164
165+ cached
166+ private module Cached {
167+ cached
168+ newtype TGvnKind =
169+ TGvnKindExpr ( int kind ) { expressions ( _, kind , _) } or
170+ TGvnKindStmt ( int kind ) { statements ( _, kind ) } or
171+ TGvnKindDeclaration ( GvnKindExpr kind , boolean thisTarget , Declaration d ) {
172+ exists ( Expr e |
173+ d = referenceAttribute ( e ) and thisTarget = isTargetThis ( e ) and kind = getKind ( e )
174+ )
175+ }
176+
177+ /**
178+ * Type for containing the global value number of a control flow element.
179+ * A global value number, can either be a constant or a list of global value numbers,
180+ * where the list also carries a `kind`, which is used to distinguish between general expressions,
181+ * declarations and statements.
182+ */
183+ cached
184+ newtype TGvn =
185+ TConstantGvn ( string s ) { s = any ( Expr e ) .getValue ( ) } or
186+ TListGvn ( GvnList l )
187+
188+ /**
189+ * Type for containing a list of global value numbers with a kind.
190+ * The empty list carries the kind of the controlflowelement.
191+ */
192+ cached
193+ newtype TGvnList =
194+ TGvnNil ( GvnKind gkind ) or
195+ TGvnCons ( Gvn head , GvnList tail ) { gvnConstructedCons ( _, _, _, head , tail ) }
196+ }
197+
198+ private import Cached
199+
186200/** Gets the global value number of the element `cfe` */
201+ cached
187202Gvn toGvn ( ControlFlowElement cfe ) {
188203 result = TConstantGvn ( cfe .( Expr ) .getValue ( ) )
189204 or
0 commit comments