@@ -114,43 +114,41 @@ module Make<LocationSig Location, InputSig<Location> Input> {
114114 }
115115
116116 /**
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 .
119119 */
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"
143132 }
144133
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
150137 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
152143 }
144+ }
153145
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> {
154152 private newtype OrderedRefIndex =
155153 MkOrderedRefIndex ( int i , int tag ) {
156154 exists ( RefKind rk | ref ( _, i , _, rk ) | tag = rk .getOrder ( ) )
@@ -168,7 +166,7 @@ module Make<LocationSig Location, InputSig<Location> Input> {
168166 *
169167 * Reads are considered before writes when they happen at the same index.
170168 */
171- private int refRank ( BasicBlock bb , int i , SourceVariable v , RefKind k ) {
169+ int refRank ( BasicBlock bb , int i , SourceVariable v , RefKind k ) {
172170 refOrd ( bb , i , v , k , _) =
173171 rank [ result ] ( int j , int ord , OrderedRefIndex res |
174172 res = refOrd ( bb , j , v , _, ord )
@@ -177,10 +175,27 @@ module Make<LocationSig Location, InputSig<Location> Input> {
177175 )
178176 }
179177
180- private int maxRefRank ( BasicBlock bb , SourceVariable v ) {
178+ int maxRefRank ( BasicBlock bb , SourceVariable v ) {
181179 result = refRank ( bb , _, v , _) and
182180 not result + 1 = refRank ( bb , _, v , _)
183181 }
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 >
184199
185200 /**
186201 * 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> {
295310 not variableWrite ( readbb , _, v , _)
296311 or
297312 synthPhiRead ( readbb , v ) and
298- not ref ( readbb , _, v , _)
313+ not varRef ( readbb , _, v , _)
299314 )
300315 }
301316
@@ -329,103 +344,40 @@ module Make<LocationSig Location, InputSig<Location> Input> {
329344 private class TDefinition = TWriteDef or TPhiNode ;
330345
331346 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-
357347 /**
358348 * 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 ()`).
361351 *
362- * Unlike `Liveness::ref `, this includes `phi` nodes and pseudo-reads
352+ * Unlike `Liveness::varRef `, this includes `phi` nodes and pseudo-reads
363353 * associated with uncertain writes.
364354 */
365355 pragma [ nomagic]
366- predicate ssaRef ( BasicBlock bb , int i , SourceVariable v , SsaRefKind k ) {
356+ predicate ssaRef ( BasicBlock bb , int i , SourceVariable v , RefKind k ) {
367357 variableRead ( bb , i , v , _) and
368- k = SsaActualRead ( )
358+ k = Read ( )
369359 or
370360 variableWrite ( bb , i , v , false ) and
371- k = SsaActualRead ( )
361+ k = Read ( )
372362 or
373363 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 ( )
410365 }
411366
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 >
416368
417369 /**
418370 * Holds if the SSA definition `def` reaches rank index `rnk` in its own
419371 * basic block `bb`.
420372 */
421373 predicate ssaDefReachesRank ( BasicBlock bb , Definition def , int rnk , SourceVariable v ) {
422374 exists ( int i |
423- rnk = ssaRefRank ( bb , i , v , SsaDef ( ) ) and
375+ rnk = refRank ( bb , i , v , Def ( ) ) and
424376 def .definesAt ( v , bb , i )
425377 )
426378 or
427379 ssaDefReachesRank ( bb , def , rnk - 1 , v ) and
428- rnk = ssaRefRank ( bb , _, v , SsaActualRead ( ) )
380+ rnk = refRank ( bb , _, v , Read ( ) )
429381 }
430382
431383 /**
@@ -436,7 +388,7 @@ module Make<LocationSig Location, InputSig<Location> Input> {
436388 private predicate liveThrough ( BasicBlock idom , BasicBlock bb , SourceVariable v ) {
437389 idom = getImmediateBasicBlockDominator ( bb ) and
438390 liveAtExit ( bb , v ) and
439- not ssaRef ( bb , _, v , SsaDef ( ) )
391+ not ssaRef ( bb , _, v , Def ( ) )
440392 }
441393
442394 /**
@@ -447,7 +399,7 @@ module Make<LocationSig Location, InputSig<Location> Input> {
447399 pragma [ nomagic]
448400 predicate ssaDefReachesEndOfBlock ( BasicBlock bb , Definition def , SourceVariable v ) {
449401 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
451403 ssaDefReachesRank ( bb , def , last , v ) and
452404 liveAtExit ( bb , v )
453405 )
@@ -471,7 +423,7 @@ module Make<LocationSig Location, InputSig<Location> Input> {
471423 predicate ssaDefReachesReadWithinBlock ( SourceVariable v , Definition def , BasicBlock bb , int i ) {
472424 exists ( int rnk |
473425 ssaDefReachesRank ( bb , def , rnk , v ) and
474- rnk = ssaRefRank ( bb , i , v , SsaActualRead ( ) )
426+ rnk = refRank ( bb , i , v , Read ( ) )
475427 )
476428 }
477429
@@ -483,7 +435,7 @@ module Make<LocationSig Location, InputSig<Location> Input> {
483435 predicate ssaDefReachesRead ( SourceVariable v , Definition def , BasicBlock bb , int i ) {
484436 ssaDefReachesReadWithinBlock ( v , def , bb , i )
485437 or
486- ssaRef ( bb , i , v , SsaActualRead ( ) ) and
438+ ssaRef ( bb , i , v , Read ( ) ) and
487439 ssaDefReachesEndOfBlock ( getImmediateBasicBlockDominator ( bb ) , def , v ) and
488440 not ssaDefReachesReadWithinBlock ( v , _, bb , i )
489441 }
@@ -537,7 +489,7 @@ module Make<LocationSig Location, InputSig<Location> Input> {
537489 * either a read (when `k` is `SsaActualRead()`), an SSA definition (when `k`
538490 * is `SsaDef()`), or a phi-read (when `k` is `SsaPhiRead()`).
539491 *
540- * Unlike `Liveness::ref `, this includes `phi` (read) nodes.
492+ * Unlike `Liveness::varRef `, this includes `phi` (read) nodes.
541493 */
542494 pragma [ nomagic]
543495 predicate ssaRef ( BasicBlock bb , int i , SourceVariable v , SsaRefKind k ) {
@@ -697,7 +649,7 @@ module Make<LocationSig Location, InputSig<Location> Input> {
697649 exists ( SourceVariable v |
698650 varBlockReachesExt ( pragma [ only_bind_into ] ( def ) , v , bb1 , pragma [ only_bind_into ] ( bb2 ) ) and
699651 phi .definesAt ( v , bb2 , _, _) and
700- not ref ( bb2 , _, v , _)
652+ not varRef ( bb2 , _, v , _)
701653 )
702654 }
703655
0 commit comments