|
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