Merge pull request #19044 from aschackmull/ssa/useuse-trim

Ssa: Trim the use-use relation to skip irrelevant nodes
This commit is contained in:
Anders Schack-Mulligen
2025-03-28 11:55:34 +01:00
committed by GitHub
22 changed files with 1577 additions and 3115 deletions

View File

@@ -1007,9 +1007,11 @@ private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationI
}
}
predicate guardControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
guard.(IRGuards::IRGuardCondition).controls(bb, branch)
}
predicate keepAllPhiInputBackEdges() { any() }
}
private module DataFlowIntegrationImpl = SsaImpl::DataFlowIntegration<DataFlowIntegrationInput>;

View File

@@ -68,31 +68,23 @@
| test.cpp:10:8:10:9 | t2 | test.cpp:11:7:11:8 | [input] SSA phi read(t2) |
| test.cpp:10:8:10:9 | t2 | test.cpp:11:7:11:8 | [input] SSA phi(*t2) |
| test.cpp:10:8:10:9 | t2 | test.cpp:13:10:13:11 | t2 |
| test.cpp:11:7:11:8 | [input] SSA phi read(t2) | test.cpp:15:3:15:6 | SSA phi read(t2) |
| test.cpp:11:7:11:8 | [input] SSA phi(*t2) | test.cpp:15:3:15:6 | SSA phi(*t2) |
| test.cpp:11:7:11:8 | [input] SSA phi read(t2) | test.cpp:15:8:15:9 | t2 |
| test.cpp:11:7:11:8 | [input] SSA phi(*t2) | test.cpp:15:8:15:9 | t2 |
| test.cpp:11:7:11:8 | t1 | test.cpp:21:8:21:9 | t1 |
| test.cpp:12:5:12:10 | ... = ... | test.cpp:13:10:13:11 | t2 |
| test.cpp:12:10:12:10 | 0 | test.cpp:12:5:12:10 | ... = ... |
| test.cpp:13:5:13:8 | [input] SSA phi read(t2) | test.cpp:15:3:15:6 | SSA phi read(t2) |
| test.cpp:13:5:13:8 | [input] SSA phi(*t2) | test.cpp:15:3:15:6 | SSA phi(*t2) |
| test.cpp:13:10:13:11 | t2 | test.cpp:13:5:13:8 | [input] SSA phi read(t2) |
| test.cpp:13:10:13:11 | t2 | test.cpp:13:5:13:8 | [input] SSA phi(*t2) |
| test.cpp:15:3:15:6 | SSA phi read(t2) | test.cpp:15:8:15:9 | t2 |
| test.cpp:15:3:15:6 | SSA phi(*t2) | test.cpp:15:8:15:9 | t2 |
| test.cpp:13:10:13:11 | t2 | test.cpp:15:8:15:9 | t2 |
| test.cpp:13:10:13:11 | t2 | test.cpp:15:8:15:9 | t2 |
| test.cpp:15:8:15:9 | t2 | test.cpp:23:15:23:16 | [input] SSA phi read(*t2) |
| test.cpp:15:8:15:9 | t2 | test.cpp:23:15:23:16 | [input] SSA phi read(t2) |
| test.cpp:17:3:17:8 | ... = ... | test.cpp:21:8:21:9 | t1 |
| test.cpp:17:8:17:8 | 0 | test.cpp:17:3:17:8 | ... = ... |
| test.cpp:21:8:21:9 | t1 | test.cpp:23:15:23:16 | [input] SSA phi read(t1) |
| test.cpp:21:8:21:9 | t1 | test.cpp:23:15:23:16 | [input] SSA phi(*t1) |
| test.cpp:21:8:21:9 | t1 | test.cpp:23:19:23:19 | SSA phi read(t1) |
| test.cpp:21:8:21:9 | t1 | test.cpp:23:19:23:19 | SSA phi(*t1) |
| test.cpp:23:15:23:16 | 0 | test.cpp:23:15:23:16 | 0 |
| test.cpp:23:15:23:16 | 0 | test.cpp:23:15:23:16 | [input] SSA phi(*i) |
| test.cpp:23:15:23:16 | 0 | test.cpp:23:19:23:19 | SSA phi(*i) |
| test.cpp:23:15:23:16 | [input] SSA phi read(*t2) | test.cpp:23:19:23:19 | SSA phi read(*t2) |
| test.cpp:23:15:23:16 | [input] SSA phi read(i) | test.cpp:23:19:23:19 | SSA phi read(i) |
| test.cpp:23:15:23:16 | [input] SSA phi read(t1) | test.cpp:23:19:23:19 | SSA phi read(t1) |
| test.cpp:23:15:23:16 | [input] SSA phi read(t2) | test.cpp:23:19:23:19 | SSA phi read(t2) |
| test.cpp:23:15:23:16 | [input] SSA phi(*i) | test.cpp:23:19:23:19 | SSA phi(*i) |
| test.cpp:23:15:23:16 | [input] SSA phi(*t1) | test.cpp:23:19:23:19 | SSA phi(*t1) |
| test.cpp:23:19:23:19 | SSA phi read(*t2) | test.cpp:24:10:24:11 | t2 |
| test.cpp:23:19:23:19 | SSA phi read(i) | test.cpp:23:19:23:19 | i |
| test.cpp:23:19:23:19 | SSA phi read(t1) | test.cpp:23:23:23:24 | t1 |

View File

@@ -1062,7 +1062,7 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
}
/** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
predicate guardControlsBlock(Guard guard, ControlFlow::BasicBlock bb, boolean branch) {
predicate guardDirectlyControlsBlock(Guard guard, ControlFlow::BasicBlock bb, boolean branch) {
exists(ConditionBlock conditionBlock, ControlFlow::SuccessorTypes::ConditionalSuccessor s |
guard.getAControlFlowNode() = conditionBlock.getLastNode() and
s.getValue() = branch and

View File

@@ -252,7 +252,7 @@
| CSharp7.cs:233:28:233:29 | access to local variable i1 | CSharp7.cs:235:38:235:39 | access to local variable i1 |
| CSharp7.cs:233:28:233:33 | ... > ... | CSharp7.cs:233:13:233:33 | [false] ... && ... |
| CSharp7.cs:233:28:233:33 | ... > ... | CSharp7.cs:233:13:233:33 | [true] ... && ... |
| CSharp7.cs:235:13:235:42 | [input] SSA phi read(o) | CSharp7.cs:248:9:274:9 | SSA phi read(o) |
| CSharp7.cs:235:13:235:42 | [input] SSA phi read(o) | CSharp7.cs:248:17:248:17 | access to local variable o |
| CSharp7.cs:235:33:235:36 | "int " | CSharp7.cs:235:31:235:41 | $"..." |
| CSharp7.cs:235:38:235:39 | access to local variable i1 | CSharp7.cs:235:31:235:41 | $"..." |
| CSharp7.cs:237:18:237:18 | access to local variable o | CSharp7.cs:237:23:237:31 | String s1 |
@@ -260,18 +260,17 @@
| CSharp7.cs:237:18:237:18 | access to local variable o | CSharp7.cs:241:18:241:18 | access to local variable o |
| CSharp7.cs:237:23:237:31 | SSA def(s1) | CSharp7.cs:239:41:239:42 | access to local variable s1 |
| CSharp7.cs:237:23:237:31 | String s1 | CSharp7.cs:237:23:237:31 | SSA def(s1) |
| CSharp7.cs:239:13:239:45 | [input] SSA phi read(o) | CSharp7.cs:248:9:274:9 | SSA phi read(o) |
| CSharp7.cs:239:13:239:45 | [input] SSA phi read(o) | CSharp7.cs:248:17:248:17 | access to local variable o |
| CSharp7.cs:239:33:239:39 | "string " | CSharp7.cs:239:31:239:44 | $"..." |
| CSharp7.cs:239:41:239:42 | access to local variable s1 | CSharp7.cs:239:31:239:44 | $"..." |
| CSharp7.cs:241:18:241:18 | access to local variable o | CSharp7.cs:242:9:243:9 | [input] SSA phi read(o) |
| CSharp7.cs:241:18:241:18 | access to local variable o | CSharp7.cs:244:18:244:18 | access to local variable o |
| CSharp7.cs:242:9:243:9 | [input] SSA phi read(o) | CSharp7.cs:248:9:274:9 | SSA phi read(o) |
| CSharp7.cs:242:9:243:9 | [input] SSA phi read(o) | CSharp7.cs:248:17:248:17 | access to local variable o |
| CSharp7.cs:244:18:244:18 | access to local variable o | CSharp7.cs:244:18:244:28 | [input] SSA phi read(o) |
| CSharp7.cs:244:18:244:18 | access to local variable o | CSharp7.cs:244:23:244:28 | Object v1 |
| CSharp7.cs:244:18:244:18 | access to local variable o | CSharp7.cs:245:9:246:9 | [input] SSA phi read(o) |
| CSharp7.cs:244:18:244:28 | [input] SSA phi read(o) | CSharp7.cs:248:9:274:9 | SSA phi read(o) |
| CSharp7.cs:245:9:246:9 | [input] SSA phi read(o) | CSharp7.cs:248:9:274:9 | SSA phi read(o) |
| CSharp7.cs:248:9:274:9 | SSA phi read(o) | CSharp7.cs:248:17:248:17 | access to local variable o |
| CSharp7.cs:244:18:244:28 | [input] SSA phi read(o) | CSharp7.cs:248:17:248:17 | access to local variable o |
| CSharp7.cs:245:9:246:9 | [input] SSA phi read(o) | CSharp7.cs:248:17:248:17 | access to local variable o |
| CSharp7.cs:248:17:248:17 | access to local variable o | CSharp7.cs:254:27:254:27 | access to local variable o |
| CSharp7.cs:248:17:248:17 | access to local variable o | CSharp7.cs:257:18:257:23 | Int32 i2 |
| CSharp7.cs:248:17:248:17 | access to local variable o | CSharp7.cs:260:18:260:23 | Int32 i3 |
@@ -312,10 +311,8 @@
| CSharp7.cs:285:39:285:42 | access to local variable list | CSharp7.cs:287:36:287:39 | access to local variable list |
| CSharp7.cs:287:36:287:39 | access to local variable list | CSharp7.cs:289:32:289:35 | access to local variable list |
| CSharp7.cs:297:18:297:18 | access to local variable x | CSharp7.cs:297:18:297:22 | SSA def(x) |
| CSharp7.cs:297:18:297:22 | SSA def(x) | CSharp7.cs:297:18:297:22 | [input] SSA phi(x) |
| CSharp7.cs:297:18:297:22 | [input] SSA phi(x) | CSharp7.cs:297:25:297:25 | SSA phi(x) |
| CSharp7.cs:297:18:297:22 | SSA def(x) | CSharp7.cs:297:25:297:25 | access to local variable x |
| CSharp7.cs:297:22:297:22 | 0 | CSharp7.cs:297:18:297:18 | access to local variable x |
| CSharp7.cs:297:25:297:25 | SSA phi(x) | CSharp7.cs:297:25:297:25 | access to local variable x |
| CSharp7.cs:297:25:297:25 | access to local variable x | CSharp7.cs:297:25:297:30 | ... < ... |
| CSharp7.cs:297:25:297:25 | access to local variable x | CSharp7.cs:297:35:297:35 | access to local variable x |
| CSharp7.cs:297:25:297:30 | ... < ... | CSharp7.cs:297:25:297:44 | [false] ... && ... |
@@ -326,6 +323,5 @@
| CSharp7.cs:297:35:297:44 | [true] ... is ... | CSharp7.cs:297:25:297:44 | [true] ... && ... |
| CSharp7.cs:297:40:297:44 | Int32 y | CSharp7.cs:297:40:297:44 | SSA def(y) |
| CSharp7.cs:297:40:297:44 | SSA def(y) | CSharp7.cs:299:31:299:31 | access to local variable y |
| CSharp7.cs:297:47:297:49 | SSA def(x) | CSharp7.cs:297:47:297:49 | [input] SSA phi(x) |
| CSharp7.cs:297:47:297:49 | [input] SSA phi(x) | CSharp7.cs:297:25:297:25 | SSA phi(x) |
| CSharp7.cs:297:47:297:49 | SSA def(x) | CSharp7.cs:297:25:297:25 | access to local variable x |
| CSharp7.cs:297:49:297:49 | access to local variable x | CSharp7.cs:297:47:297:49 | SSA def(x) |

View File

@@ -680,10 +680,17 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
}
}
/** Holds if the guard `guard` directly controls block `bb` upon evaluating to `branch`. */
predicate guardDirectlyControlsBlock(Guard guard, BasicBlock bb, boolean branch) {
guard.directlyControls(bb, branch)
}
/** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
predicate guardControlsBlock(Guard guard, BasicBlock bb, boolean branch) {
guard.controls(bb, branch)
}
predicate includeWriteDefsInFlowStep() { none() }
}
private module DataFlowIntegrationImpl = Impl::DataFlowIntegration<DataFlowIntegrationInput>;

View File

@@ -1,10 +1,7 @@
| A.java:14:14:14:16 | "A" : String | A.java:14:7:14:20 | SSA def(a) : new A(...) { ... } [p] |
| A.java:14:14:14:16 | "A" : String | A.java:14:11:14:20 | f2(...) : new A(...) { ... } [p] |
| A.java:14:14:14:16 | "A" : String | A.java:15:16:15:16 | a : new A(...) { ... } [p] |
| A.java:14:14:14:16 | "A" : String | A.java:15:16:15:22 | get(...) : String |
| A.java:14:14:14:16 | "A" : String | A.java:18:8:18:15 | p : String |
| A.java:14:14:14:16 | "A" : String | A.java:18:25:40:3 | SSA def(p) : String |
| A.java:14:14:14:16 | "A" : String | A.java:28:7:38:5 | SSA def(a) : new A(...) { ... } [p] |
| A.java:14:14:14:16 | "A" : String | A.java:28:11:38:5 | new (...) : new A(...) { ... } [p] |
| A.java:14:14:14:16 | "A" : String | A.java:28:11:38:5 | p : String |
| A.java:14:14:14:16 | "A" : String | A.java:30:14:30:16 | parameter this : new A(...) { ... } [p] |
@@ -16,16 +13,12 @@
| A.java:14:14:14:16 | "A" : String | A.java:35:26:35:27 | this : new A(...) { ... } [p] |
| A.java:14:14:14:16 | "A" : String | A.java:39:12:39:12 | a : new A(...) { ... } [p] |
| A.java:14:14:14:16 | "A" : String | A.java:39:12:39:12 | p : String |
| A.java:21:11:21:13 | "B" : String | A.java:14:7:14:20 | SSA def(a) : new A(...) { ... } [String s] |
| A.java:21:11:21:13 | "B" : String | A.java:14:11:14:20 | f2(...) : new A(...) { ... } [String s] |
| A.java:21:11:21:13 | "B" : String | A.java:15:16:15:16 | a : new A(...) { ... } [String s] |
| A.java:21:11:21:13 | "B" : String | A.java:15:16:15:22 | get(...) : String |
| A.java:21:11:21:13 | "B" : String | A.java:21:7:21:13 | ...=... : String |
| A.java:21:11:21:13 | "B" : String | A.java:21:7:21:13 | SSA def(s) : String |
| A.java:21:11:21:13 | "B" : String | A.java:21:7:21:13 | [input] SSA phi(s) : String |
| A.java:21:11:21:13 | "B" : String | A.java:25:5:25:26 | SSA phi(s) : String |
| A.java:21:11:21:13 | "B" : String | A.java:25:5:25:26 | phi(String s) : String |
| A.java:21:11:21:13 | "B" : String | A.java:28:7:38:5 | SSA def(a) : new A(...) { ... } [String s] |
| A.java:21:11:21:13 | "B" : String | A.java:28:11:38:5 | String s : String |
| A.java:21:11:21:13 | "B" : String | A.java:28:11:38:5 | new (...) : new A(...) { ... } [String s] |
| A.java:21:11:21:13 | "B" : String | A.java:30:14:30:16 | parameter this : new A(...) { ... } [String s] |
@@ -37,16 +30,12 @@
| A.java:21:11:21:13 | "B" : String | A.java:35:26:35:27 | this : new A(...) { ... } [String s] |
| A.java:21:11:21:13 | "B" : String | A.java:39:12:39:12 | String s : String |
| A.java:21:11:21:13 | "B" : String | A.java:39:12:39:12 | a : new A(...) { ... } [String s] |
| A.java:23:11:23:13 | "C" : String | A.java:14:7:14:20 | SSA def(a) : new A(...) { ... } [String s] |
| A.java:23:11:23:13 | "C" : String | A.java:14:11:14:20 | f2(...) : new A(...) { ... } [String s] |
| A.java:23:11:23:13 | "C" : String | A.java:15:16:15:16 | a : new A(...) { ... } [String s] |
| A.java:23:11:23:13 | "C" : String | A.java:15:16:15:22 | get(...) : String |
| A.java:23:11:23:13 | "C" : String | A.java:23:7:23:13 | ...=... : String |
| A.java:23:11:23:13 | "C" : String | A.java:23:7:23:13 | SSA def(s) : String |
| A.java:23:11:23:13 | "C" : String | A.java:23:7:23:13 | [input] SSA phi(s) : String |
| A.java:23:11:23:13 | "C" : String | A.java:25:5:25:26 | SSA phi(s) : String |
| A.java:23:11:23:13 | "C" : String | A.java:25:5:25:26 | phi(String s) : String |
| A.java:23:11:23:13 | "C" : String | A.java:28:7:38:5 | SSA def(a) : new A(...) { ... } [String s] |
| A.java:23:11:23:13 | "C" : String | A.java:28:11:38:5 | String s : String |
| A.java:23:11:23:13 | "C" : String | A.java:28:11:38:5 | new (...) : new A(...) { ... } [String s] |
| A.java:23:11:23:13 | "C" : String | A.java:30:14:30:16 | parameter this : new A(...) { ... } [String s] |
@@ -60,20 +49,16 @@
| A.java:23:11:23:13 | "C" : String | A.java:39:12:39:12 | a : new A(...) { ... } [String s] |
| A.java:25:22:25:24 | "D" : String | A.java:4:5:4:7 | parameter this [Return] : Box [elem] |
| A.java:25:22:25:24 | "D" : String | A.java:4:9:4:16 | e : String |
| A.java:25:22:25:24 | "D" : String | A.java:4:19:4:31 | SSA def(e) : String |
| A.java:25:22:25:24 | "D" : String | A.java:4:21:4:24 | this <.field> [post update] : Box [elem] |
| A.java:25:22:25:24 | "D" : String | A.java:4:21:4:28 | ...=... : String |
| A.java:25:22:25:24 | "D" : String | A.java:4:28:4:28 | e : String |
| A.java:25:22:25:24 | "D" : String | A.java:6:12:6:18 | parameter this : Box [elem] |
| A.java:25:22:25:24 | "D" : String | A.java:6:31:6:34 | elem : String |
| A.java:25:22:25:24 | "D" : String | A.java:6:31:6:34 | this <.field> : Box [elem] |
| A.java:25:22:25:24 | "D" : String | A.java:14:7:14:20 | SSA def(a) : new A(...) { ... } [Box b1, ... (2)] |
| A.java:25:22:25:24 | "D" : String | A.java:14:11:14:20 | f2(...) : new A(...) { ... } [Box b1, ... (2)] |
| A.java:25:22:25:24 | "D" : String | A.java:15:16:15:16 | a : new A(...) { ... } [Box b1, ... (2)] |
| A.java:25:22:25:24 | "D" : String | A.java:15:16:15:22 | get(...) : String |
| A.java:25:22:25:24 | "D" : String | A.java:25:9:25:25 | SSA def(b1) : Box [elem] |
| A.java:25:22:25:24 | "D" : String | A.java:25:14:25:25 | new Box(...) : Box [elem] |
| A.java:25:22:25:24 | "D" : String | A.java:28:7:38:5 | SSA def(a) : new A(...) { ... } [Box b1, ... (2)] |
| A.java:25:22:25:24 | "D" : String | A.java:28:11:38:5 | Box b1 : Box [elem] |
| A.java:25:22:25:24 | "D" : String | A.java:28:11:38:5 | new (...) : new A(...) { ... } [Box b1, ... (2)] |
| A.java:25:22:25:24 | "D" : String | A.java:30:14:30:16 | parameter this : new A(...) { ... } [Box b1, ... (2)] |
@@ -88,19 +73,16 @@
| A.java:25:22:25:24 | "D" : String | A.java:39:12:39:12 | a : new A(...) { ... } [Box b1, ... (2)] |
| A.java:27:16:27:18 | "E" : String | A.java:5:10:5:16 | parameter this [Return] : Box [elem] |
| A.java:27:16:27:18 | "E" : String | A.java:5:18:5:25 | e : String |
| A.java:27:16:27:18 | "E" : String | A.java:5:28:5:40 | SSA def(e) : String |
| A.java:27:16:27:18 | "E" : String | A.java:5:30:5:33 | this <.field> [post update] : Box [elem] |
| A.java:27:16:27:18 | "E" : String | A.java:5:30:5:37 | ...=... : String |
| A.java:27:16:27:18 | "E" : String | A.java:5:37:5:37 | e : String |
| A.java:27:16:27:18 | "E" : String | A.java:6:12:6:18 | parameter this : Box [elem] |
| A.java:27:16:27:18 | "E" : String | A.java:6:31:6:34 | elem : String |
| A.java:27:16:27:18 | "E" : String | A.java:6:31:6:34 | this <.field> : Box [elem] |
| A.java:27:16:27:18 | "E" : String | A.java:14:7:14:20 | SSA def(a) : new A(...) { ... } [Box b2, ... (2)] |
| A.java:27:16:27:18 | "E" : String | A.java:14:11:14:20 | f2(...) : new A(...) { ... } [Box b2, ... (2)] |
| A.java:27:16:27:18 | "E" : String | A.java:15:16:15:16 | a : new A(...) { ... } [Box b2, ... (2)] |
| A.java:27:16:27:18 | "E" : String | A.java:15:16:15:22 | get(...) : String |
| A.java:27:16:27:18 | "E" : String | A.java:27:5:27:6 | b2 [post update] : Box [elem] |
| A.java:27:16:27:18 | "E" : String | A.java:28:7:38:5 | SSA def(a) : new A(...) { ... } [Box b2, ... (2)] |
| A.java:27:16:27:18 | "E" : String | A.java:28:11:38:5 | Box b2 : Box [elem] |
| A.java:27:16:27:18 | "E" : String | A.java:28:11:38:5 | new (...) : new A(...) { ... } [Box b2, ... (2)] |
| A.java:27:16:27:18 | "E" : String | A.java:30:14:30:16 | parameter this : new A(...) { ... } [Box b2, ... (2)] |

View File

@@ -1,6 +1,4 @@
| A.java:5:18:5:21 | null | A.java:2:13:2:20 | o |
| A.java:5:18:5:21 | null | A.java:5:12:5:21 | SSA def(src) |
| A.java:5:18:5:21 | null | A.java:5:18:5:21 | null |
| A.java:5:18:5:21 | null | A.java:6:12:6:18 | SSA def(x) |
| A.java:5:18:5:21 | null | A.java:6:16:6:18 | src |
| A.java:5:18:5:21 | null | A.java:7:10:7:10 | x |

View File

@@ -3,14 +3,12 @@ edges
| A.java:12:14:12:18 | src(...) : Object | A.java:12:5:12:5 | b [post update] : Box [elem] |
| A.java:12:14:12:18 | src(...) : Object | A.java:12:5:12:18 | ...=... : Object |
| A.java:13:12:13:12 | b : Box [elem] | A.java:17:13:17:16 | f1(...) : Box [elem] |
| A.java:17:9:17:16 | SSA def(b) : Box [elem] | A.java:18:8:18:8 | b : Box [elem] |
| A.java:17:13:17:16 | f1(...) : Box [elem] | A.java:17:9:17:16 | SSA def(b) : Box [elem] |
| A.java:17:13:17:16 | f1(...) : Box [elem] | A.java:18:8:18:8 | b : Box [elem] |
| A.java:18:8:18:8 | b : Box [elem] | A.java:21:11:21:15 | b : Box [elem] |
#select
| 0 | A.java:12:5:12:5 | b [post update] : Box [elem] |
| 0 | A.java:12:5:12:18 | ...=... : Object |
| 0 | A.java:13:12:13:12 | b : Box [elem] |
| 1 | A.java:17:9:17:16 | SSA def(b) : Box [elem] |
| 1 | A.java:17:13:17:16 | f1(...) : Box [elem] |
| 1 | A.java:18:8:18:8 | b : Box [elem] |
| 2 | A.java:21:11:21:15 | b : Box [elem] |

View File

@@ -2,8 +2,7 @@ edges
| A.java:4:16:4:18 | parameter this [Return] [elem] | A.java:22:17:22:25 | new Box(...) [elem] |
| A.java:4:16:4:18 | this <constr(this)> [post update] [elem] | A.java:4:16:4:18 | parameter this [Return] [elem] |
| A.java:5:19:5:22 | elem | A.java:24:10:24:19 | other.elem |
| A.java:22:9:22:25 | SSA def(other) [elem] | A.java:23:13:23:17 | other [elem] |
| A.java:22:17:22:25 | new Box(...) [elem] | A.java:22:9:22:25 | SSA def(other) [elem] |
| A.java:22:17:22:25 | new Box(...) [elem] | A.java:23:13:23:17 | other [elem] |
| A.java:23:13:23:17 | other [elem] | A.java:24:10:24:14 | other [elem] |
| A.java:23:13:23:17 | other [post update] [elem] | A.java:24:10:24:14 | other [elem] |
| A.java:24:10:24:14 | other [elem] | A.java:24:10:24:19 | other.elem |
@@ -11,7 +10,6 @@ edges
| A.java:28:5:28:5 | b [post update] [elem] | A.java:27:16:27:20 | b [Return] [elem] |
| A.java:28:14:28:25 | new Object(...) | A.java:28:5:28:5 | b [post update] [elem] |
#select
| 0 | A.java:22:9:22:25 | SSA def(other) [elem] |
| 0 | A.java:22:17:22:25 | new Box(...) [elem] |
| 0 | A.java:23:13:23:17 | other [elem] |
| 0 | A.java:23:13:23:17 | other [post update] [elem] |

View File

@@ -1,13 +1,9 @@
| TestSwitchExpr.java:4:15:4:22 | o |
| TestSwitchExpr.java:7:16:7:28 | SSA def(x1) |
| TestSwitchExpr.java:7:21:7:28 | source(...) |
| TestSwitchExpr.java:8:16:8:30 | SSA def(x2) |
| TestSwitchExpr.java:8:21:8:30 | switch (...) |
| TestSwitchExpr.java:10:24:10:25 | x1 |
| TestSwitchExpr.java:12:16:12:30 | SSA def(x3) |
| TestSwitchExpr.java:12:21:12:30 | switch (...) |
| TestSwitchExpr.java:13:38:13:39 | x2 |
| TestSwitchExpr.java:16:16:16:30 | SSA def(x4) |
| TestSwitchExpr.java:16:21:16:30 | switch (...) |
| TestSwitchExpr.java:19:23:19:24 | x3 |
| TestSwitchExpr.java:23:14:23:15 | x4 |

View File

@@ -1,24 +1,19 @@
| Test.java:12:15:12:47 | SSA def(inp) |
| Test.java:12:21:12:47 | new FileInputStream(...) |
| Test.java:14:21:14:39 | buffer(...) |
| Test.java:14:36:14:38 | inp |
| Test.java:15:16:15:54 | SSA def(lines) |
| Test.java:15:24:15:54 | readLines(...) |
| Test.java:15:42:15:44 | inp |
| Test.java:16:18:16:45 | readFully(...) |
| Test.java:16:36:16:38 | inp |
| Test.java:17:22:17:55 | toBufferedInputStream(...) |
| Test.java:17:52:17:54 | inp |
| Test.java:18:10:18:71 | SSA def(bufread) |
| Test.java:18:20:18:71 | toBufferedReader(...) |
| Test.java:18:45:18:70 | new InputStreamReader(...) |
| Test.java:18:67:18:69 | inp |
| Test.java:19:19:19:48 | toByteArray(...) |
| Test.java:19:39:19:41 | inp |
| Test.java:20:10:20:50 | SSA def(chars) |
| Test.java:20:18:20:50 | toCharArray(...) |
| Test.java:20:38:20:40 | inp |
| Test.java:21:10:21:43 | SSA def(s) |
| Test.java:21:14:21:43 | toString(...) |
| Test.java:21:31:21:33 | inp |
| Test.java:22:20:22:52 | toInputStream(...) |

View File

@@ -10,13 +10,11 @@
| A.java:20:16:20:16 | this <.field> |
| A.java:21:12:21:20 | getThis(...) |
| A.java:21:12:21:20 | this <.method> |
| A.java:25:7:25:17 | SSA def(a) |
| A.java:25:11:25:17 | new A(...) |
| A.java:25:11:25:17 | new A(...) [pre constructor] |
| A.java:26:12:26:12 | a |
| A.java:26:12:26:22 | getThis(...) |
| A.java:26:12:26:36 | getThisWrap(...) |
| A.java:27:7:27:17 | SSA def(c) |
| A.java:27:11:27:17 | new C(...) |
| A.java:27:11:27:17 | new C(...) [pre constructor] |
| A.java:28:5:28:5 | c |

View File

@@ -97,7 +97,7 @@ module SsaDataflowInput implements DataFlowIntegrationInputSig {
}
pragma[inline]
predicate guardControlsBlock(Guard guard, js::BasicBlock bb, boolean branch) {
predicate guardDirectlyControlsBlock(Guard guard, js::BasicBlock bb, boolean branch) {
exists(js::ConditionGuardNode g |
g.getTest() = guard and
g.dominates(bb) and

View File

@@ -503,7 +503,7 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
}
/** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
predicate guardControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
Guards::guardControlsBlock(guard, bb, branch)
}
}

View File

@@ -1,83 +1,50 @@
testFailures
newStyleBarrierGuards
| barrier-guards.rb:3:16:4:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:4:5:4:7 | foo |
| barrier-guards.rb:9:25:10:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:10:5:10:7 | foo |
| barrier-guards.rb:17:1:18:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:18:5:18:7 | foo |
| barrier-guards.rb:23:1:24:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:24:5:24:7 | foo |
| barrier-guards.rb:27:20:28:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:28:5:28:7 | foo |
| barrier-guards.rb:37:21:38:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:38:5:38:7 | foo |
| barrier-guards.rb:45:9:45:11 | foo |
| barrier-guards.rb:70:22:71:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:71:5:71:7 | foo |
| barrier-guards.rb:82:26:83:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:83:5:83:7 | foo |
| barrier-guards.rb:90:1:91:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:91:5:91:7 | foo |
| barrier-guards.rb:125:11:126:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:126:5:126:7 | foo |
| barrier-guards.rb:132:11:133:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:133:5:133:7 | foo |
| barrier-guards.rb:134:11:135:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:135:5:135:7 | foo |
| barrier-guards.rb:139:18:140:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:140:5:140:7 | foo |
| barrier-guards.rb:141:19:142:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:142:5:142:7 | foo |
| barrier-guards.rb:148:21:149:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:149:5:149:7 | foo |
| barrier-guards.rb:153:18:154:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:154:5:154:7 | foo |
| barrier-guards.rb:158:10:159:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:159:5:159:7 | foo |
| barrier-guards.rb:163:11:164:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:164:5:164:7 | foo |
| barrier-guards.rb:191:4:191:15 | [input] SSA phi read(foo) |
| barrier-guards.rb:191:20:191:31 | [input] SSA phi read(foo) |
| barrier-guards.rb:191:32:192:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:192:5:192:7 | foo |
| barrier-guards.rb:195:4:195:15 | [input] SSA phi read(foo) |
| barrier-guards.rb:195:4:195:31 | [input] SSA phi read(foo) |
| barrier-guards.rb:195:20:195:31 | [input] SSA phi read(foo) |
| barrier-guards.rb:195:36:195:47 | [input] SSA phi read(foo) |
| barrier-guards.rb:195:48:196:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:196:5:196:7 | foo |
| barrier-guards.rb:199:4:199:15 | [input] SSA phi read(foo) |
| barrier-guards.rb:199:4:199:31 | [input] SSA phi read(foo) |
| barrier-guards.rb:199:20:199:31 | [input] SSA phi read(foo) |
| barrier-guards.rb:203:36:203:47 | [input] SSA phi read(foo) |
| barrier-guards.rb:207:22:208:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:208:5:208:7 | foo |
| barrier-guards.rb:211:22:212:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:212:5:212:7 | foo |
| barrier-guards.rb:215:28:216:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:216:5:216:7 | foo |
| barrier-guards.rb:219:21:219:23 | foo |
| barrier-guards.rb:219:21:219:32 | [input] SSA phi read(foo) |
| barrier-guards.rb:219:95:220:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:220:5:220:7 | foo |
| barrier-guards.rb:232:18:233:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:233:5:233:7 | foo |
| barrier-guards.rb:237:19:237:38 | [input] SSA phi read(foo) |
| barrier-guards.rb:237:24:237:26 | foo |
| barrier-guards.rb:243:9:244:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:244:5:244:7 | foo |
| barrier-guards.rb:259:17:260:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:260:5:260:7 | foo |
| barrier-guards.rb:264:17:265:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:265:5:265:7 | foo |
| barrier-guards.rb:272:17:272:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:272:17:272:19 | foo |
| barrier-guards.rb:275:20:276:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:276:5:276:7 | foo |
| barrier-guards.rb:281:21:282:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:282:5:282:7 | foo |
| barrier-guards.rb:291:7:292:19 | [input] SSA phi read(foo) |
| barrier-guards.rb:292:5:292:7 | foo |
| barrier_flow.rb:19:14:19:14 | x |
| barrier_flow.rb:32:10:32:10 | x |

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -387,7 +387,7 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
}
/** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
predicate guardControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
exists(ConditionBasicBlock conditionBlock, ConditionalSuccessor s |
guard = conditionBlock.getLastNode() and
s.getValue() = branch and

View File

@@ -430,13 +430,10 @@ localStep
| main.rs:318:11:318:12 | s1 | main.rs:319:9:319:45 | ... \| ... |
| main.rs:319:9:319:45 | ... \| ... | main.rs:319:9:319:25 | ...::A(...) |
| main.rs:319:9:319:45 | ... \| ... | main.rs:319:29:319:45 | ...::B(...) |
| main.rs:319:9:319:45 | [SSA] phi | main.rs:319:55:319:55 | n |
| main.rs:319:24:319:24 | [SSA] [input] phi | main.rs:319:9:319:45 | [SSA] phi |
| main.rs:319:24:319:24 | [SSA] n | main.rs:319:24:319:24 | [SSA] [input] phi |
| main.rs:319:24:319:24 | [SSA] n | main.rs:319:55:319:55 | n |
| main.rs:319:24:319:24 | n | main.rs:319:24:319:24 | [SSA] n |
| main.rs:319:24:319:24 | n | main.rs:319:24:319:24 | n |
| main.rs:319:44:319:44 | [SSA] [input] phi | main.rs:319:9:319:45 | [SSA] phi |
| main.rs:319:44:319:44 | [SSA] n | main.rs:319:44:319:44 | [SSA] [input] phi |
| main.rs:319:44:319:44 | [SSA] n | main.rs:319:55:319:55 | n |
| main.rs:319:44:319:44 | n | main.rs:319:44:319:44 | [SSA] n |
| main.rs:319:44:319:44 | n | main.rs:319:44:319:44 | n |
| main.rs:319:50:319:56 | sink(...) | main.rs:318:5:320:5 | match s1 { ... } |
@@ -473,13 +470,10 @@ localStep
| main.rs:336:11:336:12 | s1 | main.rs:337:9:337:19 | ... \| ... |
| main.rs:337:9:337:19 | ... \| ... | main.rs:337:9:337:12 | A(...) |
| main.rs:337:9:337:19 | ... \| ... | main.rs:337:16:337:19 | B(...) |
| main.rs:337:9:337:19 | [SSA] phi | main.rs:337:29:337:29 | n |
| main.rs:337:11:337:11 | [SSA] [input] phi | main.rs:337:9:337:19 | [SSA] phi |
| main.rs:337:11:337:11 | [SSA] n | main.rs:337:11:337:11 | [SSA] [input] phi |
| main.rs:337:11:337:11 | [SSA] n | main.rs:337:29:337:29 | n |
| main.rs:337:11:337:11 | n | main.rs:337:11:337:11 | [SSA] n |
| main.rs:337:11:337:11 | n | main.rs:337:11:337:11 | n |
| main.rs:337:18:337:18 | [SSA] [input] phi | main.rs:337:9:337:19 | [SSA] phi |
| main.rs:337:18:337:18 | [SSA] n | main.rs:337:18:337:18 | [SSA] [input] phi |
| main.rs:337:18:337:18 | [SSA] n | main.rs:337:29:337:29 | n |
| main.rs:337:18:337:18 | n | main.rs:337:18:337:18 | [SSA] n |
| main.rs:337:18:337:18 | n | main.rs:337:18:337:18 | n |
| main.rs:337:24:337:30 | sink(...) | main.rs:336:5:338:5 | match s1 { ... } |
@@ -516,13 +510,10 @@ localStep
| main.rs:359:11:359:12 | s1 | main.rs:360:9:360:71 | ... \| ... |
| main.rs:360:9:360:71 | ... \| ... | main.rs:360:9:360:38 | ...::C {...} |
| main.rs:360:9:360:71 | ... \| ... | main.rs:360:42:360:71 | ...::D {...} |
| main.rs:360:9:360:71 | [SSA] phi | main.rs:360:81:360:81 | n |
| main.rs:360:36:360:36 | [SSA] [input] phi | main.rs:360:9:360:71 | [SSA] phi |
| main.rs:360:36:360:36 | [SSA] n | main.rs:360:36:360:36 | [SSA] [input] phi |
| main.rs:360:36:360:36 | [SSA] n | main.rs:360:81:360:81 | n |
| main.rs:360:36:360:36 | n | main.rs:360:36:360:36 | [SSA] n |
| main.rs:360:36:360:36 | n | main.rs:360:36:360:36 | n |
| main.rs:360:69:360:69 | [SSA] [input] phi | main.rs:360:9:360:71 | [SSA] phi |
| main.rs:360:69:360:69 | [SSA] n | main.rs:360:69:360:69 | [SSA] [input] phi |
| main.rs:360:69:360:69 | [SSA] n | main.rs:360:81:360:81 | n |
| main.rs:360:69:360:69 | n | main.rs:360:69:360:69 | [SSA] n |
| main.rs:360:69:360:69 | n | main.rs:360:69:360:69 | n |
| main.rs:360:76:360:82 | sink(...) | main.rs:359:5:361:5 | match s1 { ... } |
@@ -559,13 +550,10 @@ localStep
| main.rs:379:11:379:12 | s1 | main.rs:380:9:380:43 | ... \| ... |
| main.rs:380:9:380:43 | ... \| ... | main.rs:380:9:380:24 | C {...} |
| main.rs:380:9:380:43 | ... \| ... | main.rs:380:28:380:43 | D {...} |
| main.rs:380:9:380:43 | [SSA] phi | main.rs:380:53:380:53 | n |
| main.rs:380:22:380:22 | [SSA] [input] phi | main.rs:380:9:380:43 | [SSA] phi |
| main.rs:380:22:380:22 | [SSA] n | main.rs:380:22:380:22 | [SSA] [input] phi |
| main.rs:380:22:380:22 | [SSA] n | main.rs:380:53:380:53 | n |
| main.rs:380:22:380:22 | n | main.rs:380:22:380:22 | [SSA] n |
| main.rs:380:22:380:22 | n | main.rs:380:22:380:22 | n |
| main.rs:380:41:380:41 | [SSA] [input] phi | main.rs:380:9:380:43 | [SSA] phi |
| main.rs:380:41:380:41 | [SSA] n | main.rs:380:41:380:41 | [SSA] [input] phi |
| main.rs:380:41:380:41 | [SSA] n | main.rs:380:53:380:53 | n |
| main.rs:380:41:380:41 | n | main.rs:380:41:380:41 | [SSA] n |
| main.rs:380:41:380:41 | n | main.rs:380:41:380:41 | n |
| main.rs:380:48:380:54 | sink(...) | main.rs:379:5:381:5 | match s1 { ... } |

View File

@@ -1493,8 +1493,34 @@ module Make<LocationSig Location, InputSig<Location> Input> {
predicate controlsBranchEdge(BasicBlock bb1, BasicBlock bb2, boolean branch);
}
/** Holds if `guard` directly controls block `bb` upon evaluating to `branch`. */
predicate guardDirectlyControlsBlock(Guard guard, BasicBlock bb, boolean branch);
/** Holds if `guard` controls block `bb` upon evaluating to `branch`. */
predicate guardControlsBlock(Guard guard, BasicBlock bb, boolean branch);
default predicate guardControlsBlock(Guard guard, BasicBlock bb, boolean branch) {
guardDirectlyControlsBlock(guard, bb, branch)
}
/**
* Holds if `WriteDefinition`s should be included as an intermediate node
* between the assigned `Expr` or `Parameter` and the first read of the SSA
* definition.
*/
default predicate includeWriteDefsInFlowStep() { any() }
/**
* Holds if barrier guards should be supported on input edges to phi
* nodes. Disable this only if barrier guards are not going to be used.
*/
default predicate supportBarrierGuardsOnPhiEdges() { any() }
/**
* Holds if all phi input back edges should be kept in the data flow graph.
*
* This is ordinarily not necessary and causes the retention of superfluous
* nodes.
*/
default predicate keepAllPhiInputBackEdges() { none() }
}
/**
@@ -1508,9 +1534,9 @@ module Make<LocationSig Location, InputSig<Location> Input> {
final private class DefinitionExtFinal = DefinitionExt;
/** An SSA definition into which another SSA definition may flow. */
private class SsaInputDefinitionExt extends DefinitionExtFinal {
SsaInputDefinitionExt() {
/** An SSA definition which is either a phi node or a phi read node. */
private class SsaPhiExt extends DefinitionExtFinal {
SsaPhiExt() {
this instanceof PhiNode
or
this instanceof PhiReadNode
@@ -1518,7 +1544,7 @@ module Make<LocationSig Location, InputSig<Location> Input> {
}
cached
private Definition getAPhiInputDef(SsaInputDefinitionExt phi, BasicBlock bb) {
private Definition getAPhiInputDef(SsaPhiExt phi, BasicBlock bb) {
exists(SourceVariable v, BasicBlock bbDef |
phi.definesAt(v, bbDef, _, _) and
getABasicBlockPredecessor(bbDef) = bb and
@@ -1526,6 +1552,118 @@ module Make<LocationSig Location, InputSig<Location> Input> {
)
}
/**
* Holds if the phi input edge from `input` to `phi` is a back edge and
* must be kept.
*/
private predicate relevantBackEdge(SsaPhiExt phi, BasicBlock input) {
exists(BasicBlock bbPhi |
DfInput::keepAllPhiInputBackEdges() and
exists(getAPhiInputDef(phi, input)) and
phi.getBasicBlock() = bbPhi and
getImmediateBasicBlockDominator+(input) = bbPhi
)
}
/**
* Holds if the input to `phi` from the block `input` might be relevant for
* barrier guards as a separately synthesized `TSsaInputNode`.
*
* Note that `TSsaInputNode`s have both unique predecessors and unique
* successors, both of which are given by `adjacentRefPhi`, so we can
* always skip them in the flow graph without increasing the number of flow
* edges, if they are not needed for barrier guards.
*/
private predicate relevantPhiInputNode(SsaPhiExt phi, BasicBlock input) {
relevantBackEdge(phi, input)
or
DfInput::supportBarrierGuardsOnPhiEdges() and
// If the input isn't explicitly read then a guard cannot check it.
exists(DfInput::getARead(getAPhiInputDef(phi, input))) and
(
// The input node is relevant either if it sits directly on a branch
// edge for a guard,
exists(DfInput::Guard g | g.controlsBranchEdge(input, phi.getBasicBlock(), _))
or
// or if the unique predecessor is not an equivalent substitute in
// terms of being controlled by the same guards.
// Example:
// ```
// if (g1) {
// use(x); // A
// if (g2) { .. }
// // no need for an input node here, as the set of guards controlling
// // this block is the same as the set of guards controlling the prior
// // use of `x` at A.
// }
// // phi-read node for `x`
// ```
exists(BasicBlock prev |
AdjacentSsaRefs::adjacentRefPhi(prev, _, input, phi.getBasicBlock(),
phi.getSourceVariable()) and
prev != input and
exists(DfInput::Guard g, boolean branch |
DfInput::guardDirectlyControlsBlock(g, input, branch) and
not DfInput::guardDirectlyControlsBlock(g, prev, branch)
)
)
)
}
/**
* Holds if a next adjacent use of `phi` is as input to `phi2` through
* `input`. The boolean `relevant` indicates whether the input edge might
* be relevant for barrier guards.
*/
private predicate phiStepsToPhiInput(
SsaPhiExt phi, SsaPhiExt phi2, BasicBlock input, boolean relevant
) {
exists(BasicBlock bb1, int i, SourceVariable v, BasicBlock bb2 |
phi.definesAt(pragma[only_bind_into](v), bb1, i, _) and
AdjacentSsaRefs::adjacentRefPhi(bb1, i, input, bb2, v) and
phi2.definesAt(pragma[only_bind_into](v), bb2, _, _) and
if relevantPhiInputNode(phi2, input) then relevant = true else relevant = false
)
}
/**
* Holds if a next adjacent use of `phi` occurs at index `i` in basic block
* `bb`. The boolean `isUse` indicates whether the use is a read or an
* uncertain write.
*/
private predicate phiStepsToRef(SsaPhiExt phi, BasicBlock bb, int i, boolean isUse) {
exists(SourceVariable v, BasicBlock bb1, int i1 |
phi.definesAt(v, bb1, i1, _) and
AdjacentSsaRefs::adjacentRefRead(bb1, i1, bb, i, v)
|
isUse = true and
variableRead(bb, i, v, true)
or
isUse = false and
exists(UncertainWriteDefinition def2 |
DfInput::allowFlowIntoUncertainDef(def2) and
def2.definesAt(v, bb, i)
)
)
}
/**
* Holds if the next adjacent use of `phi` is unique. In this case, we can
* skip the phi in the use-use step relation without increasing the number
* flow edges.
*/
private predicate phiHasUniqNextNode(SsaPhiExt phi) {
not relevantBackEdge(phi, _) and
exists(int nextPhiInput, int nextPhi, int nextRef |
1 = nextPhiInput + nextPhi + nextRef and
nextPhiInput =
count(SsaPhiExt phi2, BasicBlock input | phiStepsToPhiInput(phi, phi2, input, true)) and
nextPhi = count(SsaPhiExt phi2 | phiStepsToPhiInput(phi, phi2, _, false)) and
nextRef = count(BasicBlock bb, int i, boolean isUse | phiStepsToRef(phi, bb, i, isUse))
)
}
cached
private newtype TNode =
TParamNode(DfInput::Parameter p) {
exists(WriteDefinition def | DfInput::ssaDefInitializesParam(def, p))
@@ -1538,10 +1676,8 @@ module Make<LocationSig Location, InputSig<Location> Input> {
isPost = false
)
} or
TSsaDefinitionNode(DefinitionExt def) or
TSsaInputNode(SsaInputDefinitionExt phi, BasicBlock input) {
exists(getAPhiInputDef(phi, input))
}
TSsaDefinitionNode(DefinitionExt def) { not phiHasUniqNextNode(def) } or
TSsaInputNode(SsaPhiExt phi, BasicBlock input) { relevantPhiInputNode(phi, input) }
/**
* A data flow node that we need to reference in the value step relation.
@@ -1743,7 +1879,7 @@ module Make<LocationSig Location, InputSig<Location> Input> {
* both inputs into the phi read node after the outer condition are guarded.
*/
private class SsaInputNodeImpl extends SsaNodeImpl, TSsaInputNode {
private SsaInputDefinitionExt def_;
private SsaPhiExt def_;
private BasicBlock input_;
SsaInputNodeImpl() { this = TSsaInputNode(def_, input_) }
@@ -1754,9 +1890,9 @@ module Make<LocationSig Location, InputSig<Location> Input> {
input = input_
}
SsaInputDefinitionExt getPhi() { result = def_ }
SsaPhiExt getPhi() { result = def_ }
deprecated override SsaInputDefinitionExt getDefinitionExt() { result = def_ }
deprecated override SsaPhiExt getDefinitionExt() { result = def_ }
override BasicBlock getBasicBlock() { result = input_ }
@@ -1783,13 +1919,55 @@ module Make<LocationSig Location, InputSig<Location> Input> {
exists(DefinitionExt def |
nodeFrom.(SsaDefinitionExtNodeImpl).getDefExt() = def and
def.definesAt(v, bb, i, _) and
isUseStep = false
isUseStep = false and
if DfInput::includeWriteDefsInFlowStep()
then any()
else (
def instanceof PhiNode or
def instanceof PhiReadNode or
DfInput::allowFlowIntoUncertainDef(def)
)
)
or
[nodeFrom, nodeFrom.(ExprPostUpdateNode).getPreUpdateNode()].(ReadNode).readsAt(bb, i, v) and
isUseStep = true
}
private predicate flowFromRefToNode(SourceVariable v, BasicBlock bb1, int i1, Node nodeTo) {
// Flow from definition/read to next read
exists(BasicBlock bb2, int i2 |
AdjacentSsaRefs::adjacentRefRead(bb1, i1, bb2, i2, v) and
nodeTo.(ReadNode).readsAt(bb2, i2, v)
)
or
// Flow from definition/read to next uncertain write
exists(BasicBlock bb2, int i2 |
AdjacentSsaRefs::adjacentRefRead(bb1, i1, bb2, i2, v) and
exists(UncertainWriteDefinition def2 |
DfInput::allowFlowIntoUncertainDef(def2) and
nodeTo.(SsaDefinitionNode).getDefinition() = def2 and
def2.definesAt(v, bb2, i2)
)
)
or
// Flow from definition/read to phi input
exists(BasicBlock input, BasicBlock bbPhi, DefinitionExt phi |
AdjacentSsaRefs::adjacentRefPhi(bb1, i1, input, bbPhi, v) and
phi.definesAt(v, bbPhi, -1, _)
|
if relevantPhiInputNode(phi, input)
then nodeTo = TSsaInputNode(phi, input)
else flowIntoPhi(phi, v, bbPhi, nodeTo)
)
}
private predicate flowIntoPhi(DefinitionExt phi, SourceVariable v, BasicBlock bbPhi, Node nodeTo) {
phi.definesAt(v, bbPhi, -1, _) and
if phiHasUniqNextNode(phi)
then flowFromRefToNode(v, bbPhi, -1, nodeTo)
else nodeTo.(SsaDefinitionExtNodeImpl).getDefExt() = phi
}
/**
* Holds if there is a local flow step from `nodeFrom` to `nodeTo`.
*
@@ -1804,43 +1982,30 @@ module Make<LocationSig Location, InputSig<Location> Input> {
// Flow from parameter into entry definition
DfInput::ssaDefInitializesParam(def, nodeFrom.(ParameterNode).getParameter())
|
nodeTo.(SsaDefinitionNode).getDefinition() = def and
v = def.getSourceVariable() and
isUseStep = false
isUseStep = false and
if DfInput::includeWriteDefsInFlowStep()
then
nodeTo.(SsaDefinitionNode).getDefinition() = def and
v = def.getSourceVariable()
else
exists(BasicBlock bb1, int i1 |
def.definesAt(v, bb1, i1) and
flowFromRefToNode(v, bb1, i1, nodeTo)
)
)
or
// Flow from definition/read to next read
exists(BasicBlock bb1, int i1, BasicBlock bb2, int i2 |
exists(BasicBlock bb1, int i1 |
flowOutOf(nodeFrom, v, bb1, i1, isUseStep) and
AdjacentSsaRefs::adjacentRefRead(bb1, i1, bb2, i2, v) and
nodeTo.(ReadNode).readsAt(bb2, i2, v)
)
or
// Flow from definition/read to next uncertain write
exists(BasicBlock bb1, int i1, BasicBlock bb2, int i2 |
flowOutOf(nodeFrom, v, bb1, i1, isUseStep) and
AdjacentSsaRefs::adjacentRefRead(bb1, i1, bb2, i2, v) and
exists(UncertainWriteDefinition def2 |
DfInput::allowFlowIntoUncertainDef(def2) and
nodeTo.(SsaDefinitionNode).getDefinition() = def2 and
def2.definesAt(v, bb2, i2)
)
)
or
// Flow from definition/read to phi input
exists(BasicBlock bb, int i, BasicBlock input, BasicBlock bbPhi, DefinitionExt phi |
flowOutOf(nodeFrom, v, bb, i, isUseStep) and
AdjacentSsaRefs::adjacentRefPhi(bb, i, input, bbPhi, v) and
nodeTo = TSsaInputNode(phi, input) and
phi.definesAt(v, bbPhi, -1, _)
flowFromRefToNode(v, bb1, i1, nodeTo) and
nodeFrom != nodeTo
)
or
// Flow from input node to def
exists(DefinitionExt def |
nodeTo.(SsaDefinitionExtNodeImpl).getDefExt() = def and
def = nodeFrom.(SsaInputNodeImpl).getPhi() and
v = def.getSourceVariable() and
isUseStep = false
exists(DefinitionExt phi |
phi = nodeFrom.(SsaInputNodeImpl).getPhi() and
isUseStep = false and
nodeFrom != nodeTo and
flowIntoPhi(phi, v, _, nodeTo)
)
}
@@ -1853,8 +2018,10 @@ module Make<LocationSig Location, InputSig<Location> Input> {
// Flow from parameter into entry definition
DfInput::ssaDefInitializesParam(def, nodeFrom.(ParameterNode).getParameter())
|
nodeTo.(SsaDefinitionNode).getDefinition() = def and
v = def.getSourceVariable()
v = def.getSourceVariable() and
if DfInput::includeWriteDefsInFlowStep()
then nodeTo.(SsaDefinitionNode).getDefinition() = def
else nodeTo.(ExprNode).getExpr() = DfInput::getARead(def)
)
or
// Flow from SSA definition to read
@@ -1876,7 +2043,7 @@ module Make<LocationSig Location, InputSig<Location> Input> {
pragma[nomagic]
private Definition getAPhiInputDef(SsaInputNodeImpl n) {
exists(SsaInputDefinitionExt phi, BasicBlock bb |
exists(SsaPhiExt phi, BasicBlock bb |
result = getAPhiInputDef(phi, bb) and
n.isInputInto(phi, bb)
)
@@ -1970,7 +2137,7 @@ module Make<LocationSig Location, InputSig<Location> Input> {
)
or
// guard controls input block to a phi node
exists(SsaInputDefinitionExt phi |
exists(SsaPhiExt phi |
def = getAPhiInputDef(result) and
result.(SsaInputNodeImpl).isInputInto(phi, bb)
|