@@ -352,6 +352,10 @@ module Make<
352352 }
353353 }
354354
355+ private predicate postUpdate ( BasicBlock bb , int i , SourceVariable v ) {
356+ variableReadWithPostUpdate ( _, _, v , bb , i )
357+ }
358+
355359 /**
356360 * Liveness analysis (based on source variables) to restrict the size of the
357361 * SSA representation.
@@ -456,7 +460,7 @@ module Make<
456460 pragma [ nomagic]
457461 private predicate inReadDominanceFrontier ( BasicBlock bb , SourceVariable v ) {
458462 exists ( BasicBlock readbb | readbb .inDominanceFrontier ( bb ) |
459- variableRead ( readbb , _, v , true ) and
463+ ( variableRead ( readbb , _, v , true ) or postUpdate ( readbb , _ , v ) ) and
460464 not variableWrite ( readbb , _, v , _)
461465 or
462466 synthPhiRead ( readbb , v ) and
@@ -613,6 +617,9 @@ module Make<
613617 variableRead ( bb , i , v , true ) and
614618 k = Read ( )
615619 or
620+ postUpdate ( bb , i , v ) and
621+ k = Read ( )
622+ or
616623 variableWrite ( bb , i , v , false ) and
617624 k = Read ( )
618625 or
@@ -647,6 +654,12 @@ module Make<
647654 )
648655 }
649656
657+ private predicate justPostUpdate ( BasicBlock bb , int i , SourceVariable v ) {
658+ postUpdate ( bb , i , v ) and
659+ not variableRead ( bb , i , v , true ) and
660+ not variableWrite ( bb , i , v , false )
661+ }
662+
650663 /**
651664 * Holds if `v` has adjacent references at index `i1` in basic block `bb1`
652665 * and index `i2` in basic block `bb2`, that is, there is a path between
@@ -668,6 +681,33 @@ module Make<
668681 1 = refRank ( bb2 , i2 , v , Read ( ) )
669682 }
670683
684+ private predicate closestPriorNonPostUpdateRef (
685+ BasicBlock bb1 , int i1 , BasicBlock bb2 , int i2 , SourceVariable v
686+ ) {
687+ exists ( RefKind k |
688+ ssaRef ( bb1 , i1 , v , k ) and
689+ bb1 = bb2 and
690+ i1 = i2
691+ |
692+ k = Def ( ) or not justPostUpdate ( bb1 , i1 , v )
693+ )
694+ or
695+ exists ( BasicBlock bb0 , int i0 |
696+ closestPriorNonPostUpdateRef ( bb1 , i1 , bb0 , i0 , v ) and
697+ justPostUpdate ( bb2 , i2 , v ) and
698+ adjacentRefRead ( bb0 , i0 , bb2 , i2 , v )
699+ )
700+ }
701+
702+ predicate adjacentRefReadSkipPostUpd (
703+ BasicBlock bb1 , int i1 , BasicBlock bb2 , int i2 , SourceVariable v
704+ ) {
705+ exists ( BasicBlock bb0 , int i0 |
706+ adjacentRefRead ( bb0 , i0 , bb2 , i2 , v ) and
707+ closestPriorNonPostUpdateRef ( bb1 , i1 , bb0 , i0 , v )
708+ )
709+ }
710+
671711 /**
672712 * Holds if the phi node or phi-read for `v` in basic block `bbPhi` takes
673713 * input from basic block `input`, and that the reference to `v` at index
@@ -682,10 +722,19 @@ module Make<
682722 1 = refRank ( bbPhi , - 1 , v , _)
683723 }
684724
725+ predicate adjacentRefPhiSkipPostUpd (
726+ BasicBlock bb , int i , BasicBlock input , BasicBlock bbPhi , SourceVariable v
727+ ) {
728+ exists ( BasicBlock bb0 , int i0 |
729+ adjacentRefPhi ( bb0 , i0 , input , bbPhi , v ) and
730+ closestPriorNonPostUpdateRef ( bb , i , bb0 , i0 , v )
731+ )
732+ }
733+
685734 private predicate adjacentRefs ( BasicBlock bb1 , int i1 , BasicBlock bb2 , int i2 , SourceVariable v ) {
686- adjacentRefRead ( bb1 , i1 , bb2 , i2 , v )
735+ adjacentRefReadSkipPostUpd ( bb1 , i1 , bb2 , i2 , v )
687736 or
688- adjacentRefPhi ( bb1 , i1 , _, bb2 , v ) and i2 = - 1
737+ adjacentRefPhiSkipPostUpd ( bb1 , i1 , _, bb2 , v ) and i2 = - 1
689738 }
690739
691740 /**
@@ -1309,7 +1358,7 @@ module Make<
13091358 /** Holds if a certain read does not have a prior reference. */
13101359 query predicate readWithoutPriorRef ( SourceVariable v , BasicBlock bb , int i ) {
13111360 variableRead ( bb , i , v , true ) and
1312- not AdjacentSsaRefs:: adjacentRefRead ( _, _, bb , i , v )
1361+ not AdjacentSsaRefs:: adjacentRefReadSkipPostUpd ( _, _, bb , i , v )
13131362 }
13141363
13151364 /**
@@ -1329,7 +1378,8 @@ module Make<
13291378 PhiNode phi , BasicBlock bbPhi , SourceVariable v , int inputRefs
13301379 ) {
13311380 phi .definesAt ( v , bbPhi , _) and
1332- inputRefs = count ( BasicBlock bb , int i | AdjacentSsaRefs:: adjacentRefPhi ( bb , i , _, bbPhi , v ) ) and
1381+ inputRefs =
1382+ count ( BasicBlock bb , int i | AdjacentSsaRefs:: adjacentRefPhiSkipPostUpd ( bb , i , _, bbPhi , v ) ) and
13331383 inputRefs < 2
13341384 }
13351385
@@ -2213,6 +2263,7 @@ module Make<
22132263 module TestAdjacentRefs {
22142264 private newtype TRef =
22152265 TRefRead ( BasicBlock bb , int i , SourceVariable v ) { variableRead ( bb , i , v , true ) } or
2266+ TRefPostUpdate ( BasicBlock bb , int i , SourceVariable v ) { postUpdate ( bb , i , v ) } or
22162267 TRefDef ( Definition def ) or
22172268 TRefPhiRead ( BasicBlock bb , SourceVariable v ) { synthPhiRead ( bb , v ) }
22182269
@@ -2225,6 +2276,8 @@ module Make<
22252276 SourceVariable getSourceVariable ( ) {
22262277 this = TRefRead ( _, _, result )
22272278 or
2279+ this = TRefPostUpdate ( _, _, result )
2280+ or
22282281 exists ( Definition def | this = TRefDef ( def ) and def .getSourceVariable ( ) = result )
22292282 or
22302283 this = TRefPhiRead ( _, result )
@@ -2237,15 +2290,18 @@ module Make<
22372290 string toString ( ) {
22382291 this = TRefRead ( _, _, _) and result = "SSA read(" + this .getSourceVariable ( ) + ")"
22392292 or
2293+ this = TRefPostUpdate ( _, _, _) and
2294+ result = "SSA post update(" + this .getSourceVariable ( ) + ")"
2295+ or
22402296 exists ( Definition def | this = TRefDef ( def ) and result = def .toString ( ) )
22412297 or
22422298 this = TRefPhiRead ( _, _) and result = "SSA phi read(" + this .getSourceVariable ( ) + ")"
22432299 }
22442300
22452301 /** Gets the location of this SSA reference. */
22462302 Location getLocation ( ) {
2247- exists ( BasicBlock bb , int i |
2248- this = TRefRead ( bb , i , _ ) and bb .getNode ( i ) .getLocation ( ) = result
2303+ exists ( BasicBlock bb , int i | this = TRefRead ( bb , i , _ ) or this = TRefPostUpdate ( bb , i , _ ) |
2304+ bb .getNode ( i ) .getLocation ( ) = result
22492305 )
22502306 or
22512307 exists ( Definition def | this = TRefDef ( def ) and def .getLocation ( ) = result )
@@ -2257,6 +2313,8 @@ module Make<
22572313 predicate accessAt ( BasicBlock bb , int i , SourceVariable v ) {
22582314 this = TRefRead ( bb , i , v )
22592315 or
2316+ this = TRefPostUpdate ( bb , i , v )
2317+ or
22602318 exists ( Definition def | this = TRefDef ( def ) and def .definesAt ( v , bb , i ) )
22612319 or
22622320 this = TRefPhiRead ( bb , v ) and i = - 1
0 commit comments