@@ -49,7 +49,23 @@ private module SsaInput implements SsaImplCommon::InputSig {
4949 }
5050}
5151
52- import SsaImplCommon:: Make< SsaInput >
52+ private import SsaImplCommon:: Make< SsaInput > as Impl
53+
54+ class Definition = Impl:: Definition ;
55+
56+ class WriteDefinition = Impl:: WriteDefinition ;
57+
58+ class UncertainWriteDefinition = Impl:: UncertainWriteDefinition ;
59+
60+ class PhiNode = Impl:: PhiNode ;
61+
62+ module Consistency = Impl:: Consistency;
63+
64+ module ExposedForTestingOnly {
65+ predicate ssaDefReachesReadExt = Impl:: ssaDefReachesReadExt / 4 ;
66+
67+ predicate phiHasInputFromBlockExt = Impl:: phiHasInputFromBlockExt / 3 ;
68+ }
5369
5470/**
5571 * Holds if the `i`th node of basic block `bb` reads source variable `v`.
@@ -1072,7 +1088,7 @@ private predicate adjacentDefRead(
10721088 Definition def , SsaInput:: BasicBlock bb1 , int i1 , SsaInput:: BasicBlock bb2 , int i2 ,
10731089 SsaInput:: SourceVariable v
10741090) {
1075- adjacentDefRead ( def , bb1 , i1 , bb2 , i2 ) and
1091+ Impl :: adjacentDefRead ( def , bb1 , i1 , bb2 , i2 ) and
10761092 v = def .getSourceVariable ( )
10771093}
10781094
@@ -1088,7 +1104,7 @@ private predicate adjacentDefReachesRead(
10881104 exists ( SsaInput:: BasicBlock bb3 , int i3 |
10891105 adjacentDefReachesRead ( def , bb1 , i1 , bb3 , i3 ) and
10901106 SsaInput:: variableRead ( bb3 , i3 , _, false ) and
1091- adjacentDefRead ( def , bb3 , i3 , bb2 , i2 )
1107+ Impl :: adjacentDefRead ( def , bb3 , i3 , bb2 , i2 )
10921108 )
10931109}
10941110
@@ -1111,11 +1127,11 @@ private predicate adjacentDefReachesUncertainRead(
11111127/** Same as `lastRefRedef`, but skips uncertain reads. */
11121128pragma [ nomagic]
11131129private predicate lastRefSkipUncertainReads ( Definition def , SsaInput:: BasicBlock bb , int i ) {
1114- lastRef ( def , bb , i ) and
1130+ Impl :: lastRef ( def , bb , i ) and
11151131 not SsaInput:: variableRead ( bb , i , def .getSourceVariable ( ) , false )
11161132 or
11171133 exists ( SsaInput:: BasicBlock bb0 , int i0 |
1118- lastRef ( def , bb0 , i0 ) and
1134+ Impl :: lastRef ( def , bb0 , i0 ) and
11191135 adjacentDefReachesUncertainRead ( def , bb , i , bb0 , i0 )
11201136 )
11211137}
@@ -1237,7 +1253,7 @@ private module Cached {
12371253 v = def .getSourceVariable ( ) and
12381254 capturedReadIn ( _, _, v , edef .getSourceVariable ( ) , c , additionalCalls ) and
12391255 def = def0 .getAnUltimateDefinition ( ) and
1240- ssaDefReachesRead ( _, def0 , bb , i ) and
1256+ Impl :: ssaDefReachesRead ( _, def0 , bb , i ) and
12411257 capturedReadIn ( bb , i , v , _, _, _) and
12421258 c = bb .getNode ( i )
12431259 )
@@ -1264,18 +1280,18 @@ private module Cached {
12641280
12651281 cached
12661282 predicate isLiveAtEndOfBlock ( Definition def , ControlFlow:: BasicBlock bb ) {
1267- ssaDefReachesEndOfBlock ( bb , def , _)
1283+ Impl :: ssaDefReachesEndOfBlock ( bb , def , _)
12681284 }
12691285
12701286 cached
1271- Definition phiHasInputFromBlock ( PhiNode phi , ControlFlow:: BasicBlock bb ) {
1272- phiHasInputFromBlock ( phi , result , bb )
1287+ Definition phiHasInputFromBlock ( Ssa :: PhiNode phi , ControlFlow:: BasicBlock bb ) {
1288+ Impl :: phiHasInputFromBlock ( phi , result , bb )
12731289 }
12741290
12751291 cached
12761292 AssignableRead getAReadAtNode ( Definition def , ControlFlow:: Node cfn ) {
12771293 exists ( Ssa:: SourceVariable v , ControlFlow:: BasicBlock bb , int i |
1278- ssaDefReachesRead ( v , def , bb , i ) and
1294+ Impl :: ssaDefReachesRead ( v , def , bb , i ) and
12791295 variableReadActual ( bb , i , v ) and
12801296 cfn = bb .getNode ( i ) and
12811297 result .getAControlFlowNode ( ) = cfn
@@ -1313,11 +1329,11 @@ private module Cached {
13131329 /** Same as `lastRefRedef`, but skips uncertain reads. */
13141330 cached
13151331 predicate lastRefBeforeRedef ( Definition def , ControlFlow:: BasicBlock bb , int i , Definition next ) {
1316- lastRefRedef ( def , bb , i , next ) and
1332+ Impl :: lastRefRedef ( def , bb , i , next ) and
13171333 not SsaInput:: variableRead ( bb , i , def .getSourceVariable ( ) , false )
13181334 or
13191335 exists ( SsaInput:: BasicBlock bb0 , int i0 |
1320- lastRefRedef ( def , bb0 , i0 , next ) and
1336+ Impl :: lastRefRedef ( def , bb0 , i0 , next ) and
13211337 adjacentDefReachesUncertainRead ( def , bb , i , bb0 , i0 )
13221338 )
13231339 }
@@ -1333,7 +1349,7 @@ private module Cached {
13331349
13341350 cached
13351351 Definition uncertainWriteDefinitionInput ( UncertainWriteDefinition def ) {
1336- uncertainWriteDefinitionInput ( def , result )
1352+ Impl :: uncertainWriteDefinitionInput ( def , result )
13371353 }
13381354
13391355 cached
@@ -1343,10 +1359,57 @@ private module Cached {
13431359 v = def .getSourceVariable ( ) and
13441360 p = v .getAssignable ( ) and
13451361 def = def0 .getAnUltimateDefinition ( ) and
1346- ssaDefReachesRead ( _, def0 , bb , i ) and
1362+ Impl :: ssaDefReachesRead ( _, def0 , bb , i ) and
13471363 outRefExitRead ( bb , i , v )
13481364 )
13491365 }
13501366}
13511367
13521368import Cached
1369+
1370+ private string getSplitString ( DefinitionExt def ) {
1371+ exists ( ControlFlow:: BasicBlock bb , int i , ControlFlow:: Node cfn |
1372+ def .definesAt ( _, bb , i , _) and
1373+ result = cfn .( ControlFlow:: Nodes:: ElementNode ) .getSplitsString ( )
1374+ |
1375+ cfn = bb .getNode ( i )
1376+ or
1377+ not exists ( bb .getNode ( i ) ) and
1378+ cfn = bb .getFirstNode ( )
1379+ )
1380+ }
1381+
1382+ string getToStringPrefix ( DefinitionExt def ) {
1383+ result = "[" + getSplitString ( def ) + "] "
1384+ or
1385+ not exists ( getSplitString ( def ) ) and
1386+ result = ""
1387+ }
1388+
1389+ /**
1390+ * An extended static single assignment (SSA) definition.
1391+ *
1392+ * This is either a normal SSA definition (`Definition`) or a
1393+ * phi-read node (`PhiReadNode`).
1394+ *
1395+ * Only intended for internal use.
1396+ */
1397+ class DefinitionExt extends Impl:: DefinitionExt {
1398+ override string toString ( ) { result = this .( Ssa:: Definition ) .toString ( ) }
1399+
1400+ /** Gets the location of this definition. */
1401+ Location getLocation ( ) { result = this .( Ssa:: Definition ) .getLocation ( ) }
1402+ }
1403+
1404+ /**
1405+ * A phi-read node.
1406+ *
1407+ * Only intended for internal use.
1408+ */
1409+ class PhiReadNode extends DefinitionExt , Impl:: PhiReadNode {
1410+ override string toString ( ) {
1411+ result = getToStringPrefix ( this ) + "SSA phi read(" + this .getSourceVariable ( ) + ")"
1412+ }
1413+
1414+ override Location getLocation ( ) { result = this .getBasicBlock ( ) .getLocation ( ) }
1415+ }
0 commit comments