Revision | 3a35856fd36599e4a0d52f265ecc1aabaf2009d6 (tree) |
---|---|
Zeit | 2023-01-26 01:58:23 |
Autor | miyakawataku |
Commiter | miyakawataku |
remove AllocationSet interface
@@ -1,29 +1,125 @@ | ||
1 | 1 | package org.kink_lang.kink.internal.compile.javaclassir; |
2 | 2 | |
3 | +import java.util.Comparator; | |
4 | +import java.util.HashMap; | |
5 | +import java.util.HashSet; | |
3 | 6 | import java.util.List; |
7 | +import java.util.Map; | |
8 | +import java.util.Set; | |
9 | +import java.util.SortedSet; | |
10 | +import java.util.TreeSet; | |
11 | +import java.util.function.Predicate; | |
12 | +import java.util.stream.Collectors; | |
4 | 13 | |
14 | +import org.kink_lang.kink.internal.intrinsicsupport.CoreFuns; | |
5 | 15 | import org.kink_lang.kink.internal.program.itree.LocalVar; |
16 | +import org.kink_lang.kink.internal.program.itree.LocalVarContent; | |
17 | +import org.kink_lang.kink.internal.program.itree.UsedDefinedVars; | |
6 | 18 | |
7 | 19 | /** |
8 | - * Analysis of allocation of local vars in a fun. | |
20 | + * Allocation analysis of localvars in a fast fun. | |
21 | + * | |
22 | + * @param recv the set of local vars containing recv. | |
23 | + * @param args the mapping from local vars to arg indexes. | |
24 | + * @param control the local vars of CORE control funs. | |
25 | + * @param field vars stored in fields of the fun val. | |
26 | + * @param stackBound vars stored in stack. | |
9 | 27 | */ |
10 | -public interface AllocationSet { | |
28 | +public record AllocationSet( | |
29 | + Set<LocalVar> recv, | |
30 | + Map<LocalVar, Integer> args, | |
31 | + Set<LocalVar> control, | |
32 | + List<LocalVar> field, | |
33 | + List<LocalVar> stack) { | |
34 | + | |
35 | + public Allocation get(LocalVar lvar) { | |
36 | + if (recv().contains(lvar)) { | |
37 | + return new Allocation.Recv(); | |
38 | + } | |
39 | + | |
40 | + if (args().containsKey(lvar)) { | |
41 | + int argInd = args().get(lvar); | |
42 | + return new Allocation.Arg(argInd); | |
43 | + } | |
44 | + | |
45 | + if (control().contains(lvar)) { | |
46 | + return new Allocation.CoreMod(); | |
47 | + } | |
48 | + | |
49 | + int fieldInd = field().indexOf(lvar); | |
50 | + if (fieldInd >= 0) { | |
51 | + return new Allocation.Field(fieldInd, isNonNull(lvar)); | |
52 | + } | |
53 | + | |
54 | + int stackInd = stack().indexOf(lvar); | |
55 | + if (stackInd >= 0) { | |
56 | + return new Allocation.Stack(stackInd, isNonNull(lvar)); | |
57 | + } | |
58 | + | |
59 | + return new Allocation.Unused(); | |
60 | + } | |
11 | 61 | |
12 | 62 | /** |
13 | - * Returns the storage for the local var in the fun. | |
14 | - * | |
15 | - * @param lvar the local var. | |
16 | - * @return the storage for the local var in the fun. | |
63 | + * Whether the local var is nonnull. | |
17 | 64 | */ |
18 | - Allocation get(LocalVar lvar); | |
65 | + private boolean isNonNull(LocalVar lvar) { | |
66 | + return lvar instanceof LocalVar.Generated | |
67 | + || CONTROL_LVARS.contains(lvar); | |
68 | + } | |
19 | 69 | |
20 | 70 | /** |
21 | - * Returns a list of the free vars, | |
22 | - * in the order by they are read in the preamble. | |
71 | + * Analyzes the vars as of the val-capture fast fun for the case a local var | |
72 | + * of a control fun is overridden on the top level. | |
23 | 73 | * |
24 | - * @return a list of the free vars. | |
74 | + * @param vars of the val-capture fast fun. | |
75 | + * @return the analysis. | |
25 | 76 | */ |
26 | - List<LocalVar> free(); | |
77 | + public static AllocationSet valCaptureControlOverridden(UsedDefinedVars vars) { | |
78 | + return valCapture(Set.of(), vars); | |
79 | + } | |
80 | + | |
81 | + /** Lvars of CORE control funs. */ | |
82 | + private static final Set<LocalVar> CONTROL_LVARS = CoreFuns.controlSyms().stream() | |
83 | + .map(LocalVar.Original::new) | |
84 | + .collect(Collectors.toUnmodifiableSet()); | |
85 | + | |
86 | + /** | |
87 | + * Analyzes the vars as of the val-capture fast fun for the case that no local var | |
88 | + * of a control fun is overridden on the top level. | |
89 | + * | |
90 | + * @param vars of the val-capture fast fun. | |
91 | + * @return the analysis. | |
92 | + */ | |
93 | + public static AllocationSet valCaptureControlUnchanged(UsedDefinedVars vars) { | |
94 | + return valCapture(CONTROL_LVARS, vars); | |
95 | + } | |
96 | + | |
97 | + /** | |
98 | + * Makes analysis for a val-capture fast fun. | |
99 | + */ | |
100 | + private static AllocationSet valCapture(Set<LocalVar> control, UsedDefinedVars vars) { | |
101 | + Set<LocalVar> recv = new HashSet<>(); | |
102 | + Map<LocalVar, Integer> args = new HashMap<>(); | |
103 | + SortedSet<LocalVar> bound = new TreeSet<>(Comparator.comparing(LocalVar::name)); | |
104 | + for (LocalVar lvar : vars.definedLvars()) { | |
105 | + LocalVarContent content = vars.getContent(lvar); | |
106 | + if (content instanceof LocalVarContent.Recv) { | |
107 | + recv.add(lvar); | |
108 | + } else if (content instanceof LocalVarContent.Arg arg) { | |
109 | + args.put(lvar, arg.index()); | |
110 | + } else if (vars.isUsed(lvar)) { | |
111 | + bound.add(lvar); | |
112 | + } | |
113 | + } | |
114 | + | |
115 | + List<LocalVar> field = vars.freeLvars() | |
116 | + .stream() | |
117 | + .filter(Predicate.not(control::contains)) | |
118 | + .sorted(Comparator.comparing(LocalVar::name)) | |
119 | + .toList(); | |
120 | + | |
121 | + return new AllocationSet(recv, args, control, field, bound.stream().toList()); | |
122 | + } | |
27 | 123 | |
28 | 124 | } |
29 | 125 |
@@ -21,7 +21,7 @@ | ||
21 | 21 | */ |
22 | 22 | public class FastLvarAccessGenerator implements LvarAccessGenerator { |
23 | 23 | |
24 | - /** The analysis of local vars. */ | |
24 | + /** The allocation analysis of local vars. */ | |
25 | 25 | private final AllocationSet allocationSet; |
26 | 26 | |
27 | 27 | /** The supplier of key strs. */ |
@@ -33,7 +33,7 @@ | ||
33 | 33 | /** |
34 | 34 | * Constructs a generator. |
35 | 35 | * |
36 | - * @param allocationSet the analysis of local vars. | |
36 | + * @param allocationSet the allocation analysis of local vars. | |
37 | 37 | * @param keySup the supplier of key strs. |
38 | 38 | * @param traceAccum trace accumulator. |
39 | 39 | */ |
@@ -27,7 +27,7 @@ | ||
27 | 27 | private final Function<FastFunItree, JavaClassIr> compile; |
28 | 28 | |
29 | 29 | /** Analyzes the storage of funs. */ |
30 | - private final Function<FastFunItree, ValCaptureAllocationSet> analyzeStorage; | |
30 | + private final Function<FastFunItree, AllocationSet> analyzeAllocation; | |
31 | 31 | |
32 | 32 | /** The accumulator of child JavaClassIr instances. */ |
33 | 33 | private final ChildJcirAccumulator jcirAccum; |
@@ -37,23 +37,23 @@ | ||
37 | 37 | * |
38 | 38 | * @param lvarAccGen generator of lvars access insns of the enclosing context. |
39 | 39 | * @param compile compiles funs. |
40 | - * @param analyzeStorage analyzes the storage of funs. | |
40 | + * @param analyzeAllocation analyzes the storage of funs. | |
41 | 41 | * @param jcirAccum the accumulator of child JavaClassIr instances. |
42 | 42 | */ |
43 | 43 | public MakeValCaptureFastFunGenerator( |
44 | 44 | LvarAccessGenerator lvarAccGen, |
45 | 45 | Function<FastFunItree, JavaClassIr> compile, |
46 | - Function<FastFunItree, ValCaptureAllocationSet> analyzeStorage, | |
46 | + Function<FastFunItree, AllocationSet> analyzeAllocation, | |
47 | 47 | ChildJcirAccumulator jcirAccum) { |
48 | 48 | this.lvarAccGen = lvarAccGen; |
49 | 49 | this.compile = compile; |
50 | - this.analyzeStorage = analyzeStorage; | |
50 | + this.analyzeAllocation = analyzeAllocation; | |
51 | 51 | this.jcirAccum = jcirAccum; |
52 | 52 | } |
53 | 53 | |
54 | 54 | @Override |
55 | 55 | public List<Insn> makeFun(FastFunItree fun) { |
56 | - List<LocalVar> free = analyzeStorage.apply(fun).free(); | |
56 | + List<LocalVar> free = analyzeAllocation.apply(fun).field(); | |
57 | 57 | JavaClassIr jcir = compile.apply(fun); |
58 | 58 | int jcirInd = jcirAccum.add(jcir); |
59 | 59 | return free.isEmpty() |
@@ -1,127 +0,0 @@ | ||
1 | -package org.kink_lang.kink.internal.compile.javaclassir; | |
2 | - | |
3 | -import java.util.Comparator; | |
4 | -import java.util.HashMap; | |
5 | -import java.util.HashSet; | |
6 | -import java.util.List; | |
7 | -import java.util.Map; | |
8 | -import java.util.Set; | |
9 | -import java.util.SortedSet; | |
10 | -import java.util.TreeSet; | |
11 | -import java.util.function.Predicate; | |
12 | -import java.util.stream.Collectors; | |
13 | - | |
14 | -import org.kink_lang.kink.internal.intrinsicsupport.CoreFuns; | |
15 | -import org.kink_lang.kink.internal.program.itree.LocalVar; | |
16 | -import org.kink_lang.kink.internal.program.itree.LocalVarContent; | |
17 | -import org.kink_lang.kink.internal.program.itree.UsedDefinedVars; | |
18 | - | |
19 | -/** | |
20 | - * Analysis of an val-capturing fast fun. | |
21 | - * | |
22 | - * @param recv the set of local vars containing recv. | |
23 | - * @param args the mapping from local vars to arg indexes. | |
24 | - * @param control the local vars of CORE control funs. | |
25 | - * @param free free vars. | |
26 | - * @param stackBound bound vars stored in stack. | |
27 | - */ | |
28 | -public record ValCaptureAllocationSet( | |
29 | - Set<LocalVar> recv, | |
30 | - Map<LocalVar, Integer> args, | |
31 | - Set<LocalVar> control, | |
32 | - List<LocalVar> free, | |
33 | - List<LocalVar> stackBound) implements AllocationSet { | |
34 | - | |
35 | - @Override | |
36 | - public Allocation get(LocalVar lvar) { | |
37 | - if (recv().contains(lvar)) { | |
38 | - return new Allocation.Recv(); | |
39 | - } | |
40 | - | |
41 | - if (args().containsKey(lvar)) { | |
42 | - int argInd = args().get(lvar); | |
43 | - return new Allocation.Arg(argInd); | |
44 | - } | |
45 | - | |
46 | - if (control().contains(lvar)) { | |
47 | - return new Allocation.CoreMod(); | |
48 | - } | |
49 | - | |
50 | - int freeInd = free().indexOf(lvar); | |
51 | - if (freeInd >= 0) { | |
52 | - return new Allocation.Field(freeInd, isNonNull(lvar)); | |
53 | - } | |
54 | - | |
55 | - int stackInd = stackBound().indexOf(lvar); | |
56 | - if (stackInd >= 0) { | |
57 | - return new Allocation.Stack(stackInd, isNonNull(lvar)); | |
58 | - } | |
59 | - | |
60 | - return new Allocation.Unused(); | |
61 | - } | |
62 | - | |
63 | - /** | |
64 | - * Whether the local var is nonnull. | |
65 | - */ | |
66 | - private boolean isNonNull(LocalVar lvar) { | |
67 | - return lvar instanceof LocalVar.Generated | |
68 | - || CONTROL_LVARS.contains(lvar); | |
69 | - } | |
70 | - | |
71 | - /** | |
72 | - * Analyzes the vars as of the inner SSA fun for the case a local var | |
73 | - * of a control fun is overridden on the top level. | |
74 | - * | |
75 | - * @param vars of the inner SSA fun. | |
76 | - * @return the analysis. | |
77 | - */ | |
78 | - public static ValCaptureAllocationSet analyzeControlOverridden(UsedDefinedVars vars) { | |
79 | - return analyze(Set.of(), vars); | |
80 | - } | |
81 | - | |
82 | - /** Lvars of CORE control funs. */ | |
83 | - private static final Set<LocalVar> CONTROL_LVARS = CoreFuns.controlSyms().stream() | |
84 | - .map(LocalVar.Original::new) | |
85 | - .collect(Collectors.toUnmodifiableSet()); | |
86 | - | |
87 | - /** | |
88 | - * Analyzes the vars as of the inner SSA fun for the case that no local var | |
89 | - * of a control fun is overridden on the top level. | |
90 | - * | |
91 | - * @param vars of the inner SSA fun. | |
92 | - * @return the analysis. | |
93 | - */ | |
94 | - public static ValCaptureAllocationSet analyzeControlUnchanged(UsedDefinedVars vars) { | |
95 | - return analyze(CONTROL_LVARS, vars); | |
96 | - } | |
97 | - | |
98 | - /** | |
99 | - * Makes analysis. | |
100 | - */ | |
101 | - private static ValCaptureAllocationSet analyze(Set<LocalVar> control, UsedDefinedVars vars) { | |
102 | - Set<LocalVar> recv = new HashSet<>(); | |
103 | - Map<LocalVar, Integer> args = new HashMap<>(); | |
104 | - SortedSet<LocalVar> bound = new TreeSet<>(Comparator.comparing(LocalVar::name)); | |
105 | - for (LocalVar lvar : vars.definedLvars()) { | |
106 | - LocalVarContent content = vars.getContent(lvar); | |
107 | - if (content instanceof LocalVarContent.Recv) { | |
108 | - recv.add(lvar); | |
109 | - } else if (content instanceof LocalVarContent.Arg arg) { | |
110 | - args.put(lvar, arg.index()); | |
111 | - } else if (vars.isUsed(lvar)) { | |
112 | - bound.add(lvar); | |
113 | - } | |
114 | - } | |
115 | - | |
116 | - List<LocalVar> free = vars.freeLvars() | |
117 | - .stream() | |
118 | - .filter(Predicate.not(control::contains)) | |
119 | - .sorted(Comparator.comparing(LocalVar::name)) | |
120 | - .toList(); | |
121 | - | |
122 | - return new ValCaptureAllocationSet(recv, args, control, free, bound.stream().toList()); | |
123 | - } | |
124 | - | |
125 | -} | |
126 | - | |
127 | -// vim: et sw=4 sts=4 fdm=marker |
@@ -56,21 +56,21 @@ | ||
56 | 56 | * @return the compiled IR. |
57 | 57 | */ |
58 | 58 | public JavaClassIr compileControlUnchanged(FastFunItree fun) { |
59 | - var storageAnalysis = ValCaptureAllocationSet.analyzeControlUnchanged(fun); | |
59 | + var allocationSet = AllocationSet.valCaptureControlUnchanged(fun); | |
60 | 60 | var keySup = new KeyStrSupplier(); |
61 | 61 | var traceAccum = new TraceAccumulator(); |
62 | - var lvarAccGen = new FastLvarAccessGenerator(storageAnalysis, keySup, traceAccum); | |
62 | + var lvarAccGen = new FastLvarAccessGenerator(allocationSet, keySup, traceAccum); | |
63 | 63 | var jcirAccum = new ChildJcirAccumulator(); |
64 | 64 | var controlGen = new UnchangedControlGenerator( |
65 | 65 | vm, programName, programText, keySup, traceAccum); |
66 | 66 | var makeFunGen = new MakeValCaptureFastFunGenerator( |
67 | 67 | lvarAccGen, |
68 | 68 | this::compileControlUnchanged, |
69 | - ValCaptureAllocationSet::analyzeControlUnchanged, | |
69 | + AllocationSet::valCaptureControlUnchanged, | |
70 | 70 | jcirAccum); |
71 | 71 | return compile( |
72 | 72 | fun, |
73 | - storageAnalysis, | |
73 | + allocationSet, | |
74 | 74 | keySup, |
75 | 75 | traceAccum, |
76 | 76 | lvarAccGen, |
@@ -88,21 +88,21 @@ | ||
88 | 88 | * @return the compiled IR. |
89 | 89 | */ |
90 | 90 | public JavaClassIr compileControlOverridden(FastFunItree fun) { |
91 | - var storageAnalysis = ValCaptureAllocationSet.analyzeControlOverridden(fun); | |
91 | + var allocationSet = AllocationSet.valCaptureControlOverridden(fun); | |
92 | 92 | var keySup = new KeyStrSupplier(); |
93 | 93 | var traceAccum = new TraceAccumulator(); |
94 | - var lvarAccGen = new FastLvarAccessGenerator(storageAnalysis, keySup, traceAccum); | |
94 | + var lvarAccGen = new FastLvarAccessGenerator(allocationSet, keySup, traceAccum); | |
95 | 95 | var jcirAccum = new ChildJcirAccumulator(); |
96 | 96 | var controlGen = new OverriddenControlGenerator( |
97 | 97 | vm, programName, programText, keySup, traceAccum); |
98 | 98 | var makeFunGen = new MakeValCaptureFastFunGenerator( |
99 | 99 | lvarAccGen, |
100 | 100 | this::compileControlOverridden, |
101 | - ValCaptureAllocationSet::analyzeControlOverridden, | |
101 | + AllocationSet::valCaptureControlOverridden, | |
102 | 102 | jcirAccum); |
103 | 103 | return compile( |
104 | 104 | fun, |
105 | - storageAnalysis, | |
105 | + allocationSet, | |
106 | 106 | keySup, |
107 | 107 | traceAccum, |
108 | 108 | lvarAccGen, |
@@ -117,7 +117,7 @@ | ||
117 | 117 | */ |
118 | 118 | private JavaClassIr compile( |
119 | 119 | FastFunItree fun, |
120 | - ValCaptureAllocationSet storageAnalysis, | |
120 | + AllocationSet allocationSet, | |
121 | 121 | KeyStrSupplier keySup, |
122 | 122 | TraceAccumulator traceAccum, |
123 | 123 | LvarAccessGenerator lvarAccGen, |
@@ -141,11 +141,11 @@ | ||
141 | 141 | insns.add(new Insn.Case(InsnsGenerator.PROGRAMCOUNTER_KEY, 0)); |
142 | 142 | |
143 | 143 | // allocate lvars |
144 | - int stackBoundLvars = storageAnalysis.stackBound().size(); | |
145 | - if (stackBoundLvars >= 1) { | |
144 | + int stackLvars = allocationSet.stack().size(); | |
145 | + if (stackLvars >= 1) { | |
146 | 146 | // dataStack.increaseSp(number of stack bound lvars) |
147 | 147 | insns.add(InsnsGenerator.LOAD_DATASTACK); |
148 | - insns.add(new Insn.PushInt(stackBoundLvars)); | |
148 | + insns.add(new Insn.PushInt(stackLvars)); | |
149 | 149 | insns.add(INVOKE_INCREASE_SP); |
150 | 150 | } |
151 | 151 |
@@ -161,7 +161,7 @@ | ||
161 | 161 | vm.loc.of(programName, programText, fun.pos()).getDesc(), controlDesc); |
162 | 162 | return new JavaClassIr( |
163 | 163 | BASE_CLASS_NAME, |
164 | - storageAnalysis.free().size(), | |
164 | + allocationSet.field().size(), | |
165 | 165 | insns, |
166 | 166 | traceAccum.traces(), |
167 | 167 | desc, |
@@ -0,0 +1,195 @@ | ||
1 | +package org.kink_lang.kink.internal.compile.javaclassir; | |
2 | + | |
3 | +import java.util.List; | |
4 | +import java.util.Map; | |
5 | +import java.util.Set; | |
6 | +import java.util.stream.Collectors; | |
7 | + | |
8 | +import org.junit.jupiter.api.Test; | |
9 | + | |
10 | +import static org.assertj.core.api.Assertions.assertThat; | |
11 | + | |
12 | +import org.kink_lang.kink.internal.intrinsicsupport.CoreFuns; | |
13 | +import org.kink_lang.kink.internal.program.itree.LocalVar; | |
14 | +import org.kink_lang.kink.internal.program.itree.LocalVarContent; | |
15 | +import org.kink_lang.kink.internal.program.itree.UsedDefinedVars; | |
16 | + | |
17 | +public class AllocationSetTest { | |
18 | + | |
19 | + private final AllocationSet analysis = new AllocationSet( | |
20 | + Set.of(new LocalVar.Generated("R", "r")), | |
21 | + Map.of( | |
22 | + new LocalVar.Generated("A0", "0"), 0, | |
23 | + new LocalVar.Generated("A1", "1"), 1, | |
24 | + new LocalVar.Generated("A1dup", "1"), 1, | |
25 | + new LocalVar.Generated("A3", "3"), 3), | |
26 | + Set.of(new LocalVar.Original("if"), new LocalVar.Original("branch")), | |
27 | + List.of( | |
28 | + new LocalVar.Original("new"), | |
29 | + new LocalVar.Generated("Result", "0"), | |
30 | + new LocalVar.Original("true")), | |
31 | + List.of( | |
32 | + new LocalVar.Generated("X", "x"), | |
33 | + new LocalVar.Generated("Y", "y"), | |
34 | + new LocalVar.Generated("Z", "z"), | |
35 | + new LocalVar.Original("W"), | |
36 | + new LocalVar.Original("raise"))); | |
37 | + | |
38 | + @Test | |
39 | + public void get_recv() { | |
40 | + assertThat(analysis.get(new LocalVar.Generated("R", "r"))) | |
41 | + .isEqualTo(new Allocation.Recv()); | |
42 | + } | |
43 | + | |
44 | + @Test | |
45 | + public void get_arg() { | |
46 | + assertThat(analysis.get(new LocalVar.Generated("A1", "1"))) | |
47 | + .isEqualTo(new Allocation.Arg(1)); | |
48 | + } | |
49 | + | |
50 | + @Test | |
51 | + public void get_control() { | |
52 | + assertThat(analysis.get(new LocalVar.Original("if"))) | |
53 | + .isEqualTo(new Allocation.CoreMod()); | |
54 | + } | |
55 | + | |
56 | + @Test | |
57 | + public void get_field_from_toplevel() { | |
58 | + assertThat(analysis.get(new LocalVar.Original("new"))) | |
59 | + .isEqualTo(new Allocation.Field(0, false)); | |
60 | + } | |
61 | + | |
62 | + @Test | |
63 | + public void get_field_from_toplevel_which_overrides_control() { | |
64 | + assertThat(analysis.get(new LocalVar.Original("true"))) | |
65 | + .isEqualTo(new Allocation.Field(2, true)); | |
66 | + } | |
67 | + | |
68 | + @Test | |
69 | + public void get_field_from_bound() { | |
70 | + assertThat(analysis.get(new LocalVar.Generated("Result", "0"))) | |
71 | + .isEqualTo(new Allocation.Field(1, true)); | |
72 | + } | |
73 | + | |
74 | + @Test | |
75 | + public void get_stacked() { | |
76 | + assertThat(analysis.get(new LocalVar.Generated("Y", "y"))) | |
77 | + .isEqualTo(new Allocation.Stack(1, true)); | |
78 | + } | |
79 | + | |
80 | + @Test | |
81 | + public void get_stacked_nullable() { | |
82 | + assertThat(analysis.get(new LocalVar.Original("W"))) | |
83 | + .isEqualTo(new Allocation.Stack(3, false)); | |
84 | + } | |
85 | + | |
86 | + @Test | |
87 | + public void get_stacked_control_sym() { | |
88 | + assertThat(analysis.get(new LocalVar.Original("raise"))) | |
89 | + .isEqualTo(new Allocation.Stack(4, true)); | |
90 | + } | |
91 | + | |
92 | + @Test | |
93 | + public void get_unused() { | |
94 | + assertThat(analysis.get(new LocalVar.Original("unused"))) | |
95 | + .isEqualTo(new Allocation.Unused()); | |
96 | + } | |
97 | + | |
98 | + @Test | |
99 | + public void analyze_control_overridden() { | |
100 | + assertThat(AllocationSet.valCaptureControlOverridden(new StubVars())) | |
101 | + .isEqualTo(new AllocationSet( | |
102 | + Set.of( | |
103 | + new LocalVar.Generated("Ra", "a"), | |
104 | + new LocalVar.Generated("Rb", "b")), | |
105 | + Map.of( | |
106 | + new LocalVar.Generated("A0", "0"), 0, | |
107 | + new LocalVar.Generated("A1dup", "1"), 1, | |
108 | + new LocalVar.Generated("A1", "1"), 1, | |
109 | + new LocalVar.Generated("A3", "3"), 3), | |
110 | + Set.of(), | |
111 | + List.of( | |
112 | + new LocalVar.Generated("F2", "2"), | |
113 | + new LocalVar.Generated("F3", "3"), | |
114 | + new LocalVar.Original("branch"), | |
115 | + new LocalVar.Original("f0"), | |
116 | + new LocalVar.Original("f1")), | |
117 | + List.of( | |
118 | + new LocalVar.Generated("Va", "used"), | |
119 | + new LocalVar.Generated("Vc", "used")))); | |
120 | + } | |
121 | + | |
122 | + @Test | |
123 | + public void analyze_control_unchanged() { | |
124 | + assertThat(AllocationSet.valCaptureControlUnchanged(new StubVars())) | |
125 | + .isEqualTo(new AllocationSet( | |
126 | + Set.of( | |
127 | + new LocalVar.Generated("Ra", "a"), | |
128 | + new LocalVar.Generated("Rb", "b")), | |
129 | + Map.of( | |
130 | + new LocalVar.Generated("A0", "0"), 0, | |
131 | + new LocalVar.Generated("A1dup", "1"), 1, | |
132 | + new LocalVar.Generated("A1", "1"), 1, | |
133 | + new LocalVar.Generated("A3", "3"), 3), | |
134 | + CoreFuns.controlSyms().stream() | |
135 | + .map(LocalVar.Original::new) | |
136 | + .collect(Collectors.toUnmodifiableSet()), | |
137 | + List.of( | |
138 | + new LocalVar.Generated("F2", "2"), | |
139 | + new LocalVar.Generated("F3", "3"), | |
140 | + new LocalVar.Original("f0"), | |
141 | + new LocalVar.Original("f1")), | |
142 | + List.of( | |
143 | + new LocalVar.Generated("Va", "used"), | |
144 | + new LocalVar.Generated("Vc", "used")))); | |
145 | + } | |
146 | + | |
147 | + private static class StubVars implements UsedDefinedVars { | |
148 | + | |
149 | + @Override | |
150 | + public Set<LocalVar> usedLvars() { | |
151 | + return Set.of( | |
152 | + new LocalVar.Generated("Va", "used"), | |
153 | + new LocalVar.Generated("Vc", "used")); | |
154 | + } | |
155 | + | |
156 | + @Override | |
157 | + public Set<LocalVar> definedLvars() { | |
158 | + return Set.of( | |
159 | + new LocalVar.Generated("Ra", "a"), | |
160 | + new LocalVar.Generated("Rb", "b"), | |
161 | + new LocalVar.Generated("A0", "0"), | |
162 | + new LocalVar.Generated("A1", "1"), | |
163 | + new LocalVar.Generated("A1dup", "1"), | |
164 | + new LocalVar.Generated("A3", "3"), | |
165 | + new LocalVar.Generated("Va", "used"), | |
166 | + new LocalVar.Generated("Vbnotused", "notused"), | |
167 | + new LocalVar.Generated("Vc", "used")); | |
168 | + } | |
169 | + | |
170 | + @Override | |
171 | + public Set<LocalVar> freeLvars() { | |
172 | + return Set.of( | |
173 | + new LocalVar.Original("f0"), | |
174 | + new LocalVar.Original("f1"), | |
175 | + new LocalVar.Original("branch"), | |
176 | + new LocalVar.Generated("F2", "2"), | |
177 | + new LocalVar.Generated("F3", "3")); | |
178 | + } | |
179 | + | |
180 | + @Override | |
181 | + public LocalVarContent getContent(LocalVar lvar) { | |
182 | + if (lvar.name().startsWith("R")) { | |
183 | + return new LocalVarContent.Recv(); | |
184 | + } else if (lvar instanceof LocalVar.Generated glv && lvar.name().startsWith("A")) { | |
185 | + return new LocalVarContent.Arg(Integer.parseInt(glv.unique())); | |
186 | + } else { | |
187 | + return new LocalVarContent.Unknown(); | |
188 | + } | |
189 | + } | |
190 | + | |
191 | + } | |
192 | + | |
193 | +} | |
194 | + | |
195 | +// vim: et sw=4 sts=4 fdm=marker |
@@ -23,7 +23,7 @@ | ||
23 | 23 | |
24 | 24 | public class FastLvarAccessGeneratorTest { |
25 | 25 | |
26 | - private final AllocationSet allocationSet = new ValCaptureAllocationSet( | |
26 | + private final AllocationSet allocationSet = new AllocationSet( | |
27 | 27 | Set.of(new LocalVar.Generated("R", "r")), |
28 | 28 | Map.of( |
29 | 29 | new LocalVar.Generated("A0", "0"), 0, |
@@ -100,7 +100,7 @@ | ||
100 | 100 | |
101 | 101 | @Test |
102 | 102 | public void load_nullable_stack_lvar() { |
103 | - ValCaptureAllocationSet allocationSet = new ValCaptureAllocationSet( | |
103 | + AllocationSet allocationSet = new AllocationSet( | |
104 | 104 | Set.of(), |
105 | 105 | Map.of(), |
106 | 106 | Set.of(), |
@@ -52,7 +52,7 @@ | ||
52 | 52 | private final MakeValCaptureFastFunGenerator funGen = new MakeValCaptureFastFunGenerator( |
53 | 53 | this.lvarAccGen, |
54 | 54 | this.compile, |
55 | - fun -> ValCaptureAllocationSet.analyzeControlOverridden(fun), | |
55 | + fun -> AllocationSet.valCaptureControlOverridden(fun), | |
56 | 56 | this.jcirAccum); |
57 | 57 | |
58 | 58 | @Test |
@@ -1,195 +0,0 @@ | ||
1 | -package org.kink_lang.kink.internal.compile.javaclassir; | |
2 | - | |
3 | -import java.util.List; | |
4 | -import java.util.Map; | |
5 | -import java.util.Set; | |
6 | -import java.util.stream.Collectors; | |
7 | - | |
8 | -import org.junit.jupiter.api.Test; | |
9 | - | |
10 | -import static org.assertj.core.api.Assertions.assertThat; | |
11 | - | |
12 | -import org.kink_lang.kink.internal.intrinsicsupport.CoreFuns; | |
13 | -import org.kink_lang.kink.internal.program.itree.LocalVar; | |
14 | -import org.kink_lang.kink.internal.program.itree.LocalVarContent; | |
15 | -import org.kink_lang.kink.internal.program.itree.UsedDefinedVars; | |
16 | - | |
17 | -public class ValCaptureAllocationSetTest { | |
18 | - | |
19 | - private final ValCaptureAllocationSet analysis = new ValCaptureAllocationSet( | |
20 | - Set.of(new LocalVar.Generated("R", "r")), | |
21 | - Map.of( | |
22 | - new LocalVar.Generated("A0", "0"), 0, | |
23 | - new LocalVar.Generated("A1", "1"), 1, | |
24 | - new LocalVar.Generated("A1dup", "1"), 1, | |
25 | - new LocalVar.Generated("A3", "3"), 3), | |
26 | - Set.of(new LocalVar.Original("if"), new LocalVar.Original("branch")), | |
27 | - List.of( | |
28 | - new LocalVar.Original("new"), | |
29 | - new LocalVar.Generated("Result", "0"), | |
30 | - new LocalVar.Original("true")), | |
31 | - List.of( | |
32 | - new LocalVar.Generated("X", "x"), | |
33 | - new LocalVar.Generated("Y", "y"), | |
34 | - new LocalVar.Generated("Z", "z"), | |
35 | - new LocalVar.Original("W"), | |
36 | - new LocalVar.Original("raise"))); | |
37 | - | |
38 | - @Test | |
39 | - public void get_recv() { | |
40 | - assertThat(analysis.get(new LocalVar.Generated("R", "r"))) | |
41 | - .isEqualTo(new Allocation.Recv()); | |
42 | - } | |
43 | - | |
44 | - @Test | |
45 | - public void get_arg() { | |
46 | - assertThat(analysis.get(new LocalVar.Generated("A1", "1"))) | |
47 | - .isEqualTo(new Allocation.Arg(1)); | |
48 | - } | |
49 | - | |
50 | - @Test | |
51 | - public void get_control() { | |
52 | - assertThat(analysis.get(new LocalVar.Original("if"))) | |
53 | - .isEqualTo(new Allocation.CoreMod()); | |
54 | - } | |
55 | - | |
56 | - @Test | |
57 | - public void get_field_from_toplevel() { | |
58 | - assertThat(analysis.get(new LocalVar.Original("new"))) | |
59 | - .isEqualTo(new Allocation.Field(0, false)); | |
60 | - } | |
61 | - | |
62 | - @Test | |
63 | - public void get_field_from_toplevel_which_overrides_control() { | |
64 | - assertThat(analysis.get(new LocalVar.Original("true"))) | |
65 | - .isEqualTo(new Allocation.Field(2, true)); | |
66 | - } | |
67 | - | |
68 | - @Test | |
69 | - public void get_field_from_bound() { | |
70 | - assertThat(analysis.get(new LocalVar.Generated("Result", "0"))) | |
71 | - .isEqualTo(new Allocation.Field(1, true)); | |
72 | - } | |
73 | - | |
74 | - @Test | |
75 | - public void get_stacked() { | |
76 | - assertThat(analysis.get(new LocalVar.Generated("Y", "y"))) | |
77 | - .isEqualTo(new Allocation.Stack(1, true)); | |
78 | - } | |
79 | - | |
80 | - @Test | |
81 | - public void get_stacked_nullable() { | |
82 | - assertThat(analysis.get(new LocalVar.Original("W"))) | |
83 | - .isEqualTo(new Allocation.Stack(3, false)); | |
84 | - } | |
85 | - | |
86 | - @Test | |
87 | - public void get_stacked_control_sym() { | |
88 | - assertThat(analysis.get(new LocalVar.Original("raise"))) | |
89 | - .isEqualTo(new Allocation.Stack(4, true)); | |
90 | - } | |
91 | - | |
92 | - @Test | |
93 | - public void get_unused() { | |
94 | - assertThat(analysis.get(new LocalVar.Original("unused"))) | |
95 | - .isEqualTo(new Allocation.Unused()); | |
96 | - } | |
97 | - | |
98 | - @Test | |
99 | - public void analyze_control_overridden() { | |
100 | - assertThat(ValCaptureAllocationSet.analyzeControlOverridden(new StubVars())) | |
101 | - .isEqualTo(new ValCaptureAllocationSet( | |
102 | - Set.of( | |
103 | - new LocalVar.Generated("Ra", "a"), | |
104 | - new LocalVar.Generated("Rb", "b")), | |
105 | - Map.of( | |
106 | - new LocalVar.Generated("A0", "0"), 0, | |
107 | - new LocalVar.Generated("A1dup", "1"), 1, | |
108 | - new LocalVar.Generated("A1", "1"), 1, | |
109 | - new LocalVar.Generated("A3", "3"), 3), | |
110 | - Set.of(), | |
111 | - List.of( | |
112 | - new LocalVar.Generated("F2", "2"), | |
113 | - new LocalVar.Generated("F3", "3"), | |
114 | - new LocalVar.Original("branch"), | |
115 | - new LocalVar.Original("f0"), | |
116 | - new LocalVar.Original("f1")), | |
117 | - List.of( | |
118 | - new LocalVar.Generated("Va", "used"), | |
119 | - new LocalVar.Generated("Vc", "used")))); | |
120 | - } | |
121 | - | |
122 | - @Test | |
123 | - public void analyze_control_unchanged() { | |
124 | - assertThat(ValCaptureAllocationSet.analyzeControlUnchanged(new StubVars())) | |
125 | - .isEqualTo(new ValCaptureAllocationSet( | |
126 | - Set.of( | |
127 | - new LocalVar.Generated("Ra", "a"), | |
128 | - new LocalVar.Generated("Rb", "b")), | |
129 | - Map.of( | |
130 | - new LocalVar.Generated("A0", "0"), 0, | |
131 | - new LocalVar.Generated("A1dup", "1"), 1, | |
132 | - new LocalVar.Generated("A1", "1"), 1, | |
133 | - new LocalVar.Generated("A3", "3"), 3), | |
134 | - CoreFuns.controlSyms().stream() | |
135 | - .map(LocalVar.Original::new) | |
136 | - .collect(Collectors.toUnmodifiableSet()), | |
137 | - List.of( | |
138 | - new LocalVar.Generated("F2", "2"), | |
139 | - new LocalVar.Generated("F3", "3"), | |
140 | - new LocalVar.Original("f0"), | |
141 | - new LocalVar.Original("f1")), | |
142 | - List.of( | |
143 | - new LocalVar.Generated("Va", "used"), | |
144 | - new LocalVar.Generated("Vc", "used")))); | |
145 | - } | |
146 | - | |
147 | - private static class StubVars implements UsedDefinedVars { | |
148 | - | |
149 | - @Override | |
150 | - public Set<LocalVar> usedLvars() { | |
151 | - return Set.of( | |
152 | - new LocalVar.Generated("Va", "used"), | |
153 | - new LocalVar.Generated("Vc", "used")); | |
154 | - } | |
155 | - | |
156 | - @Override | |
157 | - public Set<LocalVar> definedLvars() { | |
158 | - return Set.of( | |
159 | - new LocalVar.Generated("Ra", "a"), | |
160 | - new LocalVar.Generated("Rb", "b"), | |
161 | - new LocalVar.Generated("A0", "0"), | |
162 | - new LocalVar.Generated("A1", "1"), | |
163 | - new LocalVar.Generated("A1dup", "1"), | |
164 | - new LocalVar.Generated("A3", "3"), | |
165 | - new LocalVar.Generated("Va", "used"), | |
166 | - new LocalVar.Generated("Vbnotused", "notused"), | |
167 | - new LocalVar.Generated("Vc", "used")); | |
168 | - } | |
169 | - | |
170 | - @Override | |
171 | - public Set<LocalVar> freeLvars() { | |
172 | - return Set.of( | |
173 | - new LocalVar.Original("f0"), | |
174 | - new LocalVar.Original("f1"), | |
175 | - new LocalVar.Original("branch"), | |
176 | - new LocalVar.Generated("F2", "2"), | |
177 | - new LocalVar.Generated("F3", "3")); | |
178 | - } | |
179 | - | |
180 | - @Override | |
181 | - public LocalVarContent getContent(LocalVar lvar) { | |
182 | - if (lvar.name().startsWith("R")) { | |
183 | - return new LocalVarContent.Recv(); | |
184 | - } else if (lvar instanceof LocalVar.Generated glv && lvar.name().startsWith("A")) { | |
185 | - return new LocalVarContent.Arg(Integer.parseInt(glv.unique())); | |
186 | - } else { | |
187 | - return new LocalVarContent.Unknown(); | |
188 | - } | |
189 | - } | |
190 | - | |
191 | - } | |
192 | - | |
193 | -} | |
194 | - | |
195 | -// vim: et sw=4 sts=4 fdm=marker |