@@ -7,21 +7,39 @@ import csharp
77 */
88module BaseSsa {
99 private import ControlFlowGraph
10+ private import AssignableDefinitions
11+
12+ private class SimpleLocalScopeVariable extends LocalScopeVariable {
13+ SimpleLocalScopeVariable ( ) {
14+ not exists ( AssignableDefinition def1 , AssignableDefinition def2 |
15+ def1 .getTarget ( ) = this and
16+ def2 .getTarget ( ) = this and
17+ def1 .getEnclosingCallable ( ) != def2 .getEnclosingCallable ( )
18+ )
19+ }
20+ }
1021
1122 /**
1223 * Holds if the `i`th node of basic block `bb` is assignable definition `def`,
1324 * targeting local scope variable `v`.
1425 */
15- private predicate defAt ( BasicBlock bb , int i , AssignableDefinition def , LocalScopeVariable v ) {
26+ private predicate defAt ( BasicBlock bb , int i , AssignableDefinition def , SimpleLocalScopeVariable v ) {
1627 bb .getNode ( i ) = def .getAControlFlowNode ( ) and
17- v = def .getTarget ( )
28+ v = def .getTarget ( ) and
29+ // In cases like `(x, x) = (0, 1)`, we discard the first (dead) definition of `x`
30+ not exists ( TupleAssignmentDefinition tdef , TupleAssignmentDefinition other |
31+ tdef = def |
32+ other .getAssignment ( ) = tdef .getAssignment ( ) and
33+ other .getEvaluationOrder ( ) > tdef .getEvaluationOrder ( ) and
34+ other .getTarget ( ) = v
35+ )
1836 }
1937
2038 /**
2139 * Holds if basic block `bb` would need to start with a phi node for local scope
2240 * variable `v` in an SSA representation.
2341 */
24- private predicate needsPhiNode ( BasicBlock bb , LocalScopeVariable v ) {
42+ private predicate needsPhiNode ( BasicBlock bb , SimpleLocalScopeVariable v ) {
2543 exists ( BasicBlock def |
2644 def .inDominanceFrontier ( bb ) |
2745 defAt ( def , _, _, v ) or
@@ -36,7 +54,7 @@ module BaseSsa {
3654 * either a read (when `k` is `SsaRead()`) or a write including phi nodes
3755 * (when `k` is `SsaDef()`).
3856 */
39- private predicate ssaRef ( BasicBlock bb , int i , LocalScopeVariable v , SsaRefKind k ) {
57+ private predicate ssaRef ( BasicBlock bb , int i , SimpleLocalScopeVariable v , SsaRefKind k ) {
4058 bb .getNode ( i ) .getElement ( ) = v .getAnAccess ( ) .( VariableRead ) and
4159 k = SsaRead ( )
4260 or
@@ -52,7 +70,7 @@ module BaseSsa {
5270 * Gets the (1-based) rank of the reference to `v` at the `i`th node of basic
5371 * block `bb`, which has the given reference kind `k`.
5472 */
55- private int ssaRefRank ( BasicBlock bb , int i , LocalScopeVariable v , SsaRefKind k ) {
73+ private int ssaRefRank ( BasicBlock bb , int i , SimpleLocalScopeVariable v , SsaRefKind k ) {
5674 i = rank [ result ] ( int j | ssaRef ( bb , j , v , _) ) and
5775 ssaRef ( bb , i , v , k )
5876 }
@@ -62,7 +80,7 @@ module BaseSsa {
6280 * `bb` reaches the reference at rank `rnk`, without passing through another
6381 * definition of `v`, including phi nodes.
6482 */
65- private predicate defReachesRank ( BasicBlock bb , AssignableDefinition def , LocalScopeVariable v , int rnk ) {
83+ private predicate defReachesRank ( BasicBlock bb , AssignableDefinition def , SimpleLocalScopeVariable v , int rnk ) {
6684 exists ( int i |
6785 rnk = ssaRefRank ( bb , i , v , SsaDef ( ) ) |
6886 defAt ( bb , i , def , v )
@@ -77,7 +95,7 @@ module BaseSsa {
7795 * basic block `bb` without passing through another definition of `v`, including
7896 * phi nodes.
7997 */
80- private predicate reachesEndOf ( AssignableDefinition def , LocalScopeVariable v , BasicBlock bb ) {
98+ private predicate reachesEndOf ( AssignableDefinition def , SimpleLocalScopeVariable v , BasicBlock bb ) {
8199 exists ( int rnk |
82100 defReachesRank ( bb , def , v , rnk ) and
83101 rnk = max ( ssaRefRank ( bb , _, v , _) )
@@ -94,7 +112,7 @@ module BaseSsa {
94112 * Gets a read of the SSA definition for variable `v` at definition `def`. That is,
95113 * a read that is guaranteed to read the value assigned at definition `def`.
96114 */
97- cached AssignableRead getARead ( AssignableDefinition def , LocalScopeVariable v ) {
115+ cached AssignableRead getARead ( AssignableDefinition def , SimpleLocalScopeVariable v ) {
98116 exists ( BasicBlock bb , int i , int rnk |
99117 result .getTarget ( ) = v and
100118 result .getAControlFlowNode ( ) = bb .getNode ( i ) and
@@ -103,7 +121,7 @@ module BaseSsa {
103121 defReachesRank ( bb , def , v , rnk )
104122 or
105123 reachesEndOf ( def , v , bb .getAPredecessor ( ) ) and
106- not ssaRefRank ( bb , i , v , SsaDef ( ) ) < rnk
124+ not ssaRefRank ( bb , _ , v , SsaDef ( ) ) < rnk
107125 )
108126 }
109127}
0 commit comments