5
5
6
6
import csharp
7
7
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
-
17
8
abstract private class GvnKind extends TGvnKind {
18
9
abstract string toString ( ) ;
19
10
}
@@ -71,16 +62,6 @@ private GvnKind getKind(ControlFlowElement cfe) {
71
62
)
72
63
}
73
64
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
-
84
65
/** The global value number of a control flow element. */
85
66
abstract class Gvn extends TGvn {
86
67
/** Gets the string representation of this global value number. */
@@ -99,14 +80,6 @@ private class ListGvn extends Gvn, TListGvn {
99
80
override string toString ( ) { result = "[" + l .toString ( ) + "]" }
100
81
}
101
82
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
-
110
83
abstract private class GvnList extends TGvnList {
111
84
abstract string toString ( ) ;
112
85
}
@@ -176,14 +149,56 @@ private ControlFlowElement getRankedChild(ControlFlowElement cfe, int rnk) {
176
149
)
177
150
}
178
151
152
+ pragma [ noinline]
153
+ private Gvn gvnChild ( ControlFlowElement cfe , int index ) {
154
+ result = toGvn ( getRankedChild ( cfe , index ) )
155
+ }
156
+
157
+ pragma [ noinline]
179
158
private predicate gvnConstructedCons (
180
- ControlFlowElement e , GvnKind kind , int index , Gvn head , GvnList tail
159
+ ControlFlowElement cfe , GvnKind kind , int index , Gvn head , GvnList tail
181
160
) {
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 )
184
163
}
185
164
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
+
186
200
/** Gets the global value number of the element `cfe` */
201
+ cached
187
202
Gvn toGvn ( ControlFlowElement cfe ) {
188
203
result = TConstantGvn ( cfe .( Expr ) .getValue ( ) )
189
204
or
0 commit comments