Skip to content

Commit

Permalink
Fix box issue with normalized fields
Browse files Browse the repository at this point in the history
  • Loading branch information
btwj committed Feb 6, 2024
1 parent 2a275b2 commit 1311d61
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 50 deletions.
2 changes: 1 addition & 1 deletion aeneas/src/ir/Normalization.v3
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}
}
Expand Down
34 changes: 23 additions & 11 deletions aeneas/src/ir/Reachability.v3
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<SsaInstr>.new(), fields1 = Vector<SsaInstr>.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()]);

Expand Down
53 changes: 17 additions & 36 deletions aeneas/src/ir/VariantSolver.v3
Original file line number Diff line number Diff line change
Expand Up @@ -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<int, void>, vecT: Vector<Type>, 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<Type>.new();
var cases = Vector<VariantCase>.new();
Expand All @@ -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<int, void>.new(int.!<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;
Expand All @@ -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<VariantField>.new(of.length);
var indexesUsed = HashMap<int, void>.new(int.!<int>, int.==);

var vecO = Vector<Type>.new();

for (i < of.length) {
var rf = c.fields[i];

var nf = Vector<Type>.new();

if (rf != null) {
Expand All @@ -278,25 +277,7 @@ class VariantSolver(nc: NormalizerConfig, rn: ReachabilityNormalizer, verbose: b
var indexes = Array<int>.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;
}
Expand Down
1 change: 0 additions & 1 deletion apps/TypeRep/TypeSystem.v3
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion test/gc/variants.gc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 1311d61

Please sign in to comment.