@@ -114,43 +114,41 @@ module Make<LocationSig Location, InputSig<Location> Input> {
114
114
}
115
115
116
116
/**
117
- * Liveness analysis (based on source variables) to restrict the size of the
118
- * SSA representation .
117
+ * A classification of variable references into reads and
118
+ * (certain or uncertain) writes / definitions .
119
119
*/
120
- private module Liveness {
121
- /**
122
- * A classification of variable references into reads (of a given kind) and
123
- * (certain or uncertain) writes.
124
- */
125
- private newtype TRefKind =
126
- Read ( ) or
127
- Write ( boolean certain ) { certain in [ false , true ] }
128
-
129
- private class RefKind extends TRefKind {
130
- string toString ( ) {
131
- this = Read ( ) and result = "read"
132
- or
133
- exists ( boolean certain | this = Write ( certain ) and result = "write (" + certain + ")" )
134
- }
135
-
136
- int getOrder ( ) {
137
- this = Read ( ) and
138
- result = 0
139
- or
140
- this = Write ( _) and
141
- result = 1
142
- }
120
+ private newtype TRefKind =
121
+ Read ( ) or
122
+ Write ( boolean certain ) { certain in [ false , true ] } or
123
+ Def ( )
124
+
125
+ private class RefKind extends TRefKind {
126
+ string toString ( ) {
127
+ this = Read ( ) and result = "read"
128
+ or
129
+ exists ( boolean certain | this = Write ( certain ) and result = "write (" + certain + ")" )
130
+ or
131
+ this = Def ( ) and result = "def"
143
132
}
144
133
145
- /**
146
- * Holds if the `i`th node of basic block `bb` is a reference to `v` of kind `k`.
147
- */
148
- predicate ref ( BasicBlock bb , int i , SourceVariable v , RefKind k ) {
149
- variableRead ( bb , i , v , _) and k = Read ( )
134
+ int getOrder ( ) {
135
+ this = Read ( ) and
136
+ result = 0
150
137
or
151
- exists ( boolean certain | variableWrite ( bb , i , v , certain ) | k = Write ( certain ) )
138
+ this = Write ( _) and
139
+ result = 1
140
+ or
141
+ this = Def ( ) and
142
+ result = 1
152
143
}
144
+ }
153
145
146
+ /**
147
+ * Holds if the `i`th node of basic block `bb` is a reference to `v` of kind `k`.
148
+ */
149
+ private signature predicate refSig ( BasicBlock bb , int i , SourceVariable v , RefKind k ) ;
150
+
151
+ private module RankRefs< refSig / 4 ref> {
154
152
private newtype OrderedRefIndex =
155
153
MkOrderedRefIndex ( int i , int tag ) {
156
154
exists ( RefKind rk | ref ( _, i , _, rk ) | tag = rk .getOrder ( ) )
@@ -168,7 +166,7 @@ module Make<LocationSig Location, InputSig<Location> Input> {
168
166
*
169
167
* Reads are considered before writes when they happen at the same index.
170
168
*/
171
- private int refRank ( BasicBlock bb , int i , SourceVariable v , RefKind k ) {
169
+ int refRank ( BasicBlock bb , int i , SourceVariable v , RefKind k ) {
172
170
refOrd ( bb , i , v , k , _) =
173
171
rank [ result ] ( int j , int ord , OrderedRefIndex res |
174
172
res = refOrd ( bb , j , v , _, ord )
@@ -177,10 +175,27 @@ module Make<LocationSig Location, InputSig<Location> Input> {
177
175
)
178
176
}
179
177
180
- private int maxRefRank ( BasicBlock bb , SourceVariable v ) {
178
+ int maxRefRank ( BasicBlock bb , SourceVariable v ) {
181
179
result = refRank ( bb , _, v , _) and
182
180
not result + 1 = refRank ( bb , _, v , _)
183
181
}
182
+ }
183
+
184
+ /**
185
+ * Liveness analysis (based on source variables) to restrict the size of the
186
+ * SSA representation.
187
+ */
188
+ private module Liveness {
189
+ /**
190
+ * Holds if the `i`th node of basic block `bb` is a reference to `v` of kind `k`.
191
+ */
192
+ predicate varRef ( BasicBlock bb , int i , SourceVariable v , RefKind k ) {
193
+ variableRead ( bb , i , v , _) and k = Read ( )
194
+ or
195
+ exists ( boolean certain | variableWrite ( bb , i , v , certain ) | k = Write ( certain ) )
196
+ }
197
+
198
+ private import RankRefs< varRef / 4 >
184
199
185
200
/**
186
201
* Gets the (1-based) rank of the first reference to `v` inside basic block `bb`
@@ -295,7 +310,7 @@ module Make<LocationSig Location, InputSig<Location> Input> {
295
310
not variableWrite ( readbb , _, v , _)
296
311
or
297
312
synthPhiRead ( readbb , v ) and
298
- not ref ( readbb , _, v , _)
313
+ not varRef ( readbb , _, v , _)
299
314
)
300
315
}
301
316
@@ -329,103 +344,40 @@ module Make<LocationSig Location, InputSig<Location> Input> {
329
344
private class TDefinition = TWriteDef or TPhiNode ;
330
345
331
346
private module SsaDefReachesNew {
332
- newtype TSsaRefKind =
333
- SsaActualRead ( ) or
334
- SsaDef ( )
335
-
336
- /**
337
- * A classification of SSA variable references into reads and definitions.
338
- */
339
- class SsaRefKind extends TSsaRefKind {
340
- string toString ( ) {
341
- this = SsaActualRead ( ) and
342
- result = "SsaActualRead"
343
- or
344
- this = SsaDef ( ) and
345
- result = "SsaDef"
346
- }
347
-
348
- int getOrder ( ) {
349
- this = SsaActualRead ( ) and
350
- result = 0
351
- or
352
- this = SsaDef ( ) and
353
- result = 1
354
- }
355
- }
356
-
357
347
/**
358
348
* Holds if the `i`th node of basic block `bb` is a reference to `v`,
359
- * either a read (when `k` is `SsaActualRead ()`) or an SSA definition (when
360
- * `k` is `SsaDef ()`).
349
+ * either a read (when `k` is `Read ()`) or an SSA definition (when
350
+ * `k` is `Def ()`).
361
351
*
362
- * Unlike `Liveness::ref `, this includes `phi` nodes and pseudo-reads
352
+ * Unlike `Liveness::varRef `, this includes `phi` nodes and pseudo-reads
363
353
* associated with uncertain writes.
364
354
*/
365
355
pragma [ nomagic]
366
- predicate ssaRef ( BasicBlock bb , int i , SourceVariable v , SsaRefKind k ) {
356
+ predicate ssaRef ( BasicBlock bb , int i , SourceVariable v , RefKind k ) {
367
357
variableRead ( bb , i , v , _) and
368
- k = SsaActualRead ( )
358
+ k = Read ( )
369
359
or
370
360
variableWrite ( bb , i , v , false ) and
371
- k = SsaActualRead ( )
361
+ k = Read ( )
372
362
or
373
363
any ( Definition def ) .definesAt ( v , bb , i ) and
374
- k = SsaDef ( )
375
- }
376
-
377
- private newtype OrderedSsaRefIndex =
378
- MkOrderedSsaRefIndex ( int i , SsaRefKind k ) { ssaRef ( _, i , _, k ) }
379
-
380
- private OrderedSsaRefIndex ssaRefOrd (
381
- BasicBlock bb , int i , SourceVariable v , SsaRefKind k , int ord
382
- ) {
383
- ssaRef ( bb , i , v , k ) and
384
- result = MkOrderedSsaRefIndex ( i , k ) and
385
- ord = k .getOrder ( )
386
- }
387
-
388
- /**
389
- * Gets the (1-based) rank of the reference to `v` at the `i`th node of basic
390
- * block `bb`, which has the given reference kind `k`.
391
- *
392
- * For example, if `bb` is a basic block with a phi node for `v` (considered
393
- * to be at index -1), reads `v` at node 2, and defines it at node 5, we have:
394
- *
395
- * ```ql
396
- * ssaRefRank(bb, -1, v, SsaDef()) = 1 // phi node
397
- * ssaRefRank(bb, 2, v, Read()) = 2 // read at node 2
398
- * ssaRefRank(bb, 5, v, SsaDef()) = 3 // definition at node 5
399
- * ```
400
- *
401
- * Reads are considered before writes when they happen at the same index.
402
- */
403
- int ssaRefRank ( BasicBlock bb , int i , SourceVariable v , SsaRefKind k ) {
404
- ssaRefOrd ( bb , i , v , k , _) =
405
- rank [ result ] ( int j , int ord , OrderedSsaRefIndex res |
406
- res = ssaRefOrd ( bb , j , v , _, ord )
407
- |
408
- res order by j , ord
409
- )
364
+ k = Def ( )
410
365
}
411
366
412
- int maxSsaRefRank ( BasicBlock bb , SourceVariable v ) {
413
- result = ssaRefRank ( bb , _, v , _) and
414
- not result + 1 = ssaRefRank ( bb , _, v , _)
415
- }
367
+ private import RankRefs< ssaRef / 4 >
416
368
417
369
/**
418
370
* Holds if the SSA definition `def` reaches rank index `rnk` in its own
419
371
* basic block `bb`.
420
372
*/
421
373
predicate ssaDefReachesRank ( BasicBlock bb , Definition def , int rnk , SourceVariable v ) {
422
374
exists ( int i |
423
- rnk = ssaRefRank ( bb , i , v , SsaDef ( ) ) and
375
+ rnk = refRank ( bb , i , v , Def ( ) ) and
424
376
def .definesAt ( v , bb , i )
425
377
)
426
378
or
427
379
ssaDefReachesRank ( bb , def , rnk - 1 , v ) and
428
- rnk = ssaRefRank ( bb , _, v , SsaActualRead ( ) )
380
+ rnk = refRank ( bb , _, v , Read ( ) )
429
381
}
430
382
431
383
/**
@@ -436,7 +388,7 @@ module Make<LocationSig Location, InputSig<Location> Input> {
436
388
private predicate liveThrough ( BasicBlock idom , BasicBlock bb , SourceVariable v ) {
437
389
idom = getImmediateBasicBlockDominator ( bb ) and
438
390
liveAtExit ( bb , v ) and
439
- not ssaRef ( bb , _, v , SsaDef ( ) )
391
+ not ssaRef ( bb , _, v , Def ( ) )
440
392
}
441
393
442
394
/**
@@ -447,7 +399,7 @@ module Make<LocationSig Location, InputSig<Location> Input> {
447
399
pragma [ nomagic]
448
400
predicate ssaDefReachesEndOfBlock ( BasicBlock bb , Definition def , SourceVariable v ) {
449
401
exists ( int last |
450
- last = maxSsaRefRank ( pragma [ only_bind_into ] ( bb ) , pragma [ only_bind_into ] ( v ) ) and
402
+ last = maxRefRank ( pragma [ only_bind_into ] ( bb ) , pragma [ only_bind_into ] ( v ) ) and
451
403
ssaDefReachesRank ( bb , def , last , v ) and
452
404
liveAtExit ( bb , v )
453
405
)
@@ -471,7 +423,7 @@ module Make<LocationSig Location, InputSig<Location> Input> {
471
423
predicate ssaDefReachesReadWithinBlock ( SourceVariable v , Definition def , BasicBlock bb , int i ) {
472
424
exists ( int rnk |
473
425
ssaDefReachesRank ( bb , def , rnk , v ) and
474
- rnk = ssaRefRank ( bb , i , v , SsaActualRead ( ) )
426
+ rnk = refRank ( bb , i , v , Read ( ) )
475
427
)
476
428
}
477
429
@@ -483,7 +435,7 @@ module Make<LocationSig Location, InputSig<Location> Input> {
483
435
predicate ssaDefReachesRead ( SourceVariable v , Definition def , BasicBlock bb , int i ) {
484
436
ssaDefReachesReadWithinBlock ( v , def , bb , i )
485
437
or
486
- ssaRef ( bb , i , v , SsaActualRead ( ) ) and
438
+ ssaRef ( bb , i , v , Read ( ) ) and
487
439
ssaDefReachesEndOfBlock ( getImmediateBasicBlockDominator ( bb ) , def , v ) and
488
440
not ssaDefReachesReadWithinBlock ( v , _, bb , i )
489
441
}
@@ -537,7 +489,7 @@ module Make<LocationSig Location, InputSig<Location> Input> {
537
489
* either a read (when `k` is `SsaActualRead()`), an SSA definition (when `k`
538
490
* is `SsaDef()`), or a phi-read (when `k` is `SsaPhiRead()`).
539
491
*
540
- * Unlike `Liveness::ref `, this includes `phi` (read) nodes.
492
+ * Unlike `Liveness::varRef `, this includes `phi` (read) nodes.
541
493
*/
542
494
pragma [ nomagic]
543
495
predicate ssaRef ( BasicBlock bb , int i , SourceVariable v , SsaRefKind k ) {
@@ -697,7 +649,7 @@ module Make<LocationSig Location, InputSig<Location> Input> {
697
649
exists ( SourceVariable v |
698
650
varBlockReachesExt ( pragma [ only_bind_into ] ( def ) , v , bb1 , pragma [ only_bind_into ] ( bb2 ) ) and
699
651
phi .definesAt ( v , bb2 , _, _) and
700
- not ref ( bb2 , _, v , _)
652
+ not varRef ( bb2 , _, v , _)
701
653
)
702
654
}
703
655
0 commit comments