From 25b986079d61bc30a5de9270ac091598d97cb6c7 Mon Sep 17 00:00:00 2001 From: Bradley Teo Date: Tue, 6 Feb 2024 02:01:17 -0500 Subject: [PATCH] Fix box issue with normalized fields --- aeneas/src/ir/Normalization.v3 | 2 +- aeneas/src/ir/Reachability.v3 | 34 +++++++++++++++------- aeneas/src/ir/VariantSolver.v3 | 53 +++++++++++----------------------- apps/TypeRep/TypeSystem.v3 | 1 - test/gc/variants.gc | 2 +- 5 files changed, 42 insertions(+), 50 deletions(-) diff --git a/aeneas/src/ir/Normalization.v3 b/aeneas/src/ir/Normalization.v3 index 8303b5735..60e87a7d3 100644 --- a/aeneas/src/ir/Normalization.v3 +++ b/aeneas/src/ir/Normalization.v3 @@ -651,7 +651,7 @@ class ReachabilityNormalizer(config: NormalizerConfig, ra: ReachabilityAnalyzer) for (box in rc.variantNorm.boxes) { if (rc.raFacts.RC_EQUALITY) { var equality = box.ic.methods[IrUtil.EQUALS_METHOD_INDEX]; - equality.ssa = BoxComparatorGen.new(this, context, box.ic, equality).generate(); + equality.ssa = BoxComparatorGen.new(this, context, box, equality).generate(); } } } diff --git a/aeneas/src/ir/Reachability.v3 b/aeneas/src/ir/Reachability.v3 index 77a490999..a9f191261 100644 --- a/aeneas/src/ir/Reachability.v3 +++ b/aeneas/src/ir/Reachability.v3 @@ -886,8 +886,9 @@ class VariantComparatorGen(context: SsaContext, root: IrClass, receiver: IrClass } } -class BoxComparatorGen(rn: ReachabilityNormalizer, context: SsaContext, receiver: IrClass, method: IrMethod) { +class BoxComparatorGen(rn: ReachabilityNormalizer, context: SsaContext, box: VariantBox, method: IrMethod) { def generate() -> SsaGraph { + var receiver = box.ic; context.enterMethod(method); var graph: SsaGraph; @@ -905,17 +906,28 @@ class BoxComparatorGen(rn: ReachabilityNormalizer, context: SsaContext, receiver s.newGraph = graph; s.curBlock = SsaBuilder.new(context, graph, graph.startBlock); - for (f in receiver.fields) { - var spec = IrSpec.new(receiver.ctype, [receiver.ctype], f); - var f0 = s.curBlock.opGetField(spec, p0); - var f1 = s.curBlock.opGetField(spec, p1); - f0.facts |= Fact.O_NO_NULL_CHECK; - f1.facts |= Fact.O_NO_NULL_CHECK; + if (box.origRanges != null) { + for (i < box.origRanges.length) { + if (box.origFields[i] == null) continue; - var cmp = s.normSingleEqualOp(null, f.fieldType, f0, f1); - var cont = SsaBlock.new(); - s.curBlock.addIf(cmp, cont, falseBlock); - s.curBlock = SsaBuilder.new(context, graph, cont); + var or = box.origRanges[i]; + var fields0 = Vector.new(), fields1 = Vector.new(); + + for (i = or.0; i < or.1; i++) { + var spec = IrSpec.new(receiver.ctype, [receiver.ctype], receiver.fields[i]); + var f0 = s.curBlock.opGetField(spec, p0); + var f1 = s.curBlock.opGetField(spec, p1); + f0.facts |= Fact.O_NO_NULL_CHECK; + f1.facts |= Fact.O_NO_NULL_CHECK; + fields0.put(f0); + fields1.put(f1); + } + var args = fields0.putv(fields1); + var cmp = s.normEqualOp0(null, rn.norm(box.origFields[i].orig.fieldType), args.extract()); + var cont = SsaBlock.new(); + s.curBlock.addIf(cmp, cont, falseBlock); + s.curBlock = SsaBuilder.new(context, graph, cont); + } } s.curBlock.addReturn([graph.trueConst()]); diff --git a/aeneas/src/ir/VariantSolver.v3 b/aeneas/src/ir/VariantSolver.v3 index b74c07275..e00130719 100644 --- a/aeneas/src/ir/VariantSolver.v3 +++ b/aeneas/src/ir/VariantSolver.v3 @@ -203,6 +203,19 @@ class VariantSolver(nc: NormalizerConfig, rn: ReachabilityNormalizer, verbose: b if (verbose) Terminal.put1("variant norm %q\n", rc.variantNorm.render); } + private def addTypeToList(ignore: HashMap, vecT: Vector, t: Type) -> int { + for (i < vecT.length) { + if (ignore.has(i)) continue; + + var supertype = nc.UnifyRepresentations(rn.ra.compiler, rn.ra.prog, vecT[i], t); + if (supertype != null) { + vecT[i] = supertype; + return i; + } + } + vecT.put(t); + return vecT.length - 1; + } def unboxUsingUnboxedNorm(rc: RaClass) -> bool { var vecT = Vector.new(); var cases = Vector.new(); @@ -218,27 +231,15 @@ class VariantSolver(nc: NormalizerConfig, rn: ReachabilityNormalizer, verbose: b for (l = rc.children; l != null; l = l.tail) { var c = l.head; var caseUnboxed = parentUnboxed || c.orig.boxing == Boxing.UNBOXED; + var indexesUsed = HashMap.new(int.!, int.==); if (!caseUnboxed || CLOptions.UNBOX_ALL_AND_BOX.get()) { hasBoxedCase = true; - var boxedIndex = -1; var boxedName = Strings.format1("%q", c.oldType.render); var boxedType = V3Box.newType(boxedName, ClassType.!(c.oldType)); boxedType.tag = V3.getVariantTag(c.oldType); - - for (i < vecT.length) { - var supertype = nc.UnifyRepresentations(rn.ra.compiler, rn.ra.prog, vecT[i], boxedType); - if (supertype != null) { - vecT[i] = supertype; - boxedIndex = i; - break; - } - } - if (boxedIndex < 0) { - boxedIndex = vecT.length; - vecT.put(boxedType); - } + var boxedIndex = addTypeToList(indexesUsed, vecT, boxedType); var origRanges = Array<(int, int)>.new(c.fields.length); var start = 0; @@ -254,18 +255,16 @@ class VariantSolver(nc: NormalizerConfig, rn: ReachabilityNormalizer, verbose: b box.origRanges = origRanges; box.origFields = c.fields; cases.put(VariantCase([VariantField.new([boxedType], [boxedIndex], (0, 0))], [box])); - continue; } var of = c.orig.fields; var caseFields = Array.new(of.length); - var indexesUsed = HashMap.new(int.!, int.==); + var vecO = Vector.new(); for (i < of.length) { var rf = c.fields[i]; - var nf = Vector.new(); if (rf != null) { @@ -278,25 +277,7 @@ class VariantSolver(nc: NormalizerConfig, rn: ReachabilityNormalizer, verbose: b var indexes = Array.new(fieldTypes.length); for (j < fieldTypes.length) { - var assigned = -1; - - // Try to find an existing field to use - for (k < vecT.length) { - if (indexesUsed.has(k)) continue; - - var supertype = nc.UnifyRepresentations(rn.ra.compiler, rn.ra.prog, fieldTypes[j], vecT[k]); - if (supertype != null) { - // TODO: Heuristic - don't always use the supertype - vecT[k] = supertype; - assigned = k; - break; - } - } - - if (assigned < 0) { - assigned = vecT.length; - vecT.put(fieldTypes[j]); - } + var assigned = addTypeToList(indexesUsed, vecT, fieldTypes[j]); indexesUsed[assigned] = (); indexes[j] = assigned; } diff --git a/apps/TypeRep/TypeSystem.v3 b/apps/TypeRep/TypeSystem.v3 index 94387905f..7d2bf8f93 100644 --- a/apps/TypeRep/TypeSystem.v3 +++ b/apps/TypeRep/TypeSystem.v3 @@ -196,7 +196,6 @@ component TypeSystem { // Return {true} if {t} is a reference type. def isRefType(t: Type) -> bool { match (t) { - x: BoxType => return true; x: ClassType => return true; x: ArrayType => return true; x: ClosureType => return true; diff --git a/test/gc/variants.gc b/test/gc/variants.gc index 5c3ff0633..2827b163b 100644 --- a/test/gc/variants.gc +++ b/test/gc/variants.gc @@ -239,7 +239,7 @@ ../variants/unboxed01.v3 ../variants/unboxed02.v3 ../variants/unboxed03.v3 -../variants/unboxed_mixed_array00.v3 +../variants/ub_mixed_array00.v3 ../variants/v01.v3 ../variants/v13.v3 ../variants/v14.v3