|
3 | 3 | */
|
4 | 4 |
|
5 | 5 | import csharp
|
6 |
| -import SsaImplCommon |
| 6 | +private import SsaImplCommon as SsaImplCommon |
| 7 | +private import AssignableDefinitions |
| 8 | + |
| 9 | +private module SsaInput implements SsaImplCommon::InputSig { |
| 10 | + class BasicBlock = ControlFlow::BasicBlock; |
| 11 | + |
| 12 | + BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result = bb.getImmediateDominator() } |
| 13 | + |
| 14 | + BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() } |
| 15 | + |
| 16 | + class ExitBasicBlock = ControlFlow::BasicBlocks::ExitBlock; |
| 17 | + |
| 18 | + class SourceVariable = Ssa::SourceVariable; |
| 19 | + |
| 20 | + /** |
| 21 | + * Holds if the `i`th node of basic block `bb` is a (potential) write to source |
| 22 | + * variable `v`. The Boolean `certain` indicates whether the write is certain. |
| 23 | + * |
| 24 | + * This includes implicit writes via calls. |
| 25 | + */ |
| 26 | + predicate variableWrite(ControlFlow::BasicBlock bb, int i, Ssa::SourceVariable v, boolean certain) { |
| 27 | + variableWriteDirect(bb, i, v, certain) |
| 28 | + or |
| 29 | + variableWriteQualifier(bb, i, v, certain) |
| 30 | + or |
| 31 | + updatesNamedFieldOrProp(bb, i, _, v, _) and |
| 32 | + certain = false |
| 33 | + or |
| 34 | + updatesCapturedVariable(bb, i, _, v, _, _) and |
| 35 | + certain = false |
| 36 | + } |
| 37 | + |
| 38 | + /** |
| 39 | + * Holds if the `i`th of basic block `bb` reads source variable `v`. |
| 40 | + * |
| 41 | + * This includes implicit reads via calls. |
| 42 | + */ |
| 43 | + predicate variableRead(ControlFlow::BasicBlock bb, int i, Ssa::SourceVariable v, boolean certain) { |
| 44 | + variableReadActual(bb, i, v) and |
| 45 | + certain = true |
| 46 | + or |
| 47 | + variableReadPseudo(bb, i, v) and |
| 48 | + certain = false |
| 49 | + } |
| 50 | +} |
| 51 | + |
| 52 | +import SsaImplCommon::Make<SsaInput> |
7 | 53 |
|
8 | 54 | /**
|
9 | 55 | * Holds if the `i`th node of basic block `bb` reads source variable `v`.
|
@@ -805,24 +851,6 @@ private module CapturedVariableImpl {
|
805 | 851 | }
|
806 | 852 | }
|
807 | 853 |
|
808 |
| -/** |
809 |
| - * Holds if the `i`th node of basic block `bb` is a (potential) write to source |
810 |
| - * variable `v`. The Boolean `certain` indicates whether the write is certain. |
811 |
| - * |
812 |
| - * This includes implicit writes via calls. |
813 |
| - */ |
814 |
| -predicate variableWrite(ControlFlow::BasicBlock bb, int i, Ssa::SourceVariable v, boolean certain) { |
815 |
| - variableWriteDirect(bb, i, v, certain) |
816 |
| - or |
817 |
| - variableWriteQualifier(bb, i, v, certain) |
818 |
| - or |
819 |
| - updatesNamedFieldOrProp(bb, i, _, v, _) and |
820 |
| - certain = false |
821 |
| - or |
822 |
| - updatesCapturedVariable(bb, i, _, v, _, _) and |
823 |
| - certain = false |
824 |
| -} |
825 |
| - |
826 | 854 | /**
|
827 | 855 | * Liveness analysis to restrict the size of the SSA representation for
|
828 | 856 | * captured variables.
|
@@ -1039,19 +1067,6 @@ private predicate variableReadPseudo(ControlFlow::BasicBlock bb, int i, Ssa::Sou
|
1039 | 1067 | capturedReadIn(bb, i, v, _, _, _)
|
1040 | 1068 | }
|
1041 | 1069 |
|
1042 |
| -/** |
1043 |
| - * Holds if the `i`th of basic block `bb` reads source variable `v`. |
1044 |
| - * |
1045 |
| - * This includes implicit reads via calls. |
1046 |
| - */ |
1047 |
| -predicate variableRead(ControlFlow::BasicBlock bb, int i, Ssa::SourceVariable v, boolean certain) { |
1048 |
| - variableReadActual(bb, i, v) and |
1049 |
| - certain = true |
1050 |
| - or |
1051 |
| - variableReadPseudo(bb, i, v) and |
1052 |
| - certain = false |
1053 |
| -} |
1054 |
| - |
1055 | 1070 | cached
|
1056 | 1071 | private module Cached {
|
1057 | 1072 | cached
|
@@ -1151,7 +1166,7 @@ private module Cached {
|
1151 | 1166 | predicate variableWriteQualifier(
|
1152 | 1167 | ControlFlow::BasicBlock bb, int i, QualifiedFieldOrPropSourceVariable v, boolean certain
|
1153 | 1168 | ) {
|
1154 |
| - variableWrite(bb, i, v.getQualifier(), certain) and |
| 1169 | + SsaInput::variableWrite(bb, i, v.getQualifier(), certain) and |
1155 | 1170 | // Eliminate corner case where a call definition can overlap with a
|
1156 | 1171 | // qualifier definition: if method `M` updates field `F`, then a call
|
1157 | 1172 | // to `M` is both an update of `x.M` and `x.M.M`, so the former call
|
|
0 commit comments