diff --git a/aeneas/src/core/Eval.v3 b/aeneas/src/core/Eval.v3 index f534cd262..4eb1fc674 100644 --- a/aeneas/src/core/Eval.v3 +++ b/aeneas/src/core/Eval.v3 @@ -743,9 +743,6 @@ def evalOp(op: Operator, args: Arguments) -> Result { var object = args.r(0); return if(object != null, object.values[field.index]); } - VariantReplaceNull => { - return args.vals[0]; - } VariantGetMethod(method) => { var object = args.r(0); var spec = getIrSpec(method, args); diff --git a/aeneas/src/core/Opcode.v3 b/aeneas/src/core/Opcode.v3 index bfaf0f3ab..c77dd495c 100644 --- a/aeneas/src/core/Opcode.v3 +++ b/aeneas/src/core/Opcode.v3 @@ -104,7 +104,6 @@ type Opcode { case VariantEq; case VariantGetTag; case VariantGetField(field: IrField); - case VariantReplaceNull; case VariantGetMethod(method: IrMethod); case VariantGetVirtual(method: IrMethod); case VariantGetSelector(selector: IrSelector); @@ -290,7 +289,6 @@ component Opcodes { t[Opcode.VariantEq.tag] = P |C; t[Opcode.VariantGetTag.tag] = P|NNEG; t[Opcode.VariantGetField.tag] = P; - t[Opcode.VariantReplaceNull.tag] = P|NZ; t[Opcode.VariantGetMethod.tag] = NZ|P; t[Opcode.VariantGetVirtual.tag] = NZ|P; t[Opcode.VariantGetSelector.tag] = NZ|P; diff --git a/aeneas/src/core/Operator.v3 b/aeneas/src/core/Operator.v3 index 26c402d6e..91da214e2 100644 --- a/aeneas/src/core/Operator.v3 +++ b/aeneas/src/core/Operator.v3 @@ -337,11 +337,6 @@ component V3Op { return newOp0(Opcode.VariantGetSelector(selector), typeArgs, [methodRef.receiver], methodRef.getFuncType()); } -//---------------------------------------------------------------------------- - def newVariantReplaceNull(vtype: Type) -> Operator { - var tt = [vtype]; - return newOp0(Opcode.VariantReplaceNull, tt, tt, vtype); - } //---------------------------------------------------------------------------- def newNullCheck(rtype: Type) -> Operator { var tt = [rtype]; diff --git a/aeneas/src/ir/SsaNormalizer.v3 b/aeneas/src/ir/SsaNormalizer.v3 index e618de2ba..fd92991f5 100644 --- a/aeneas/src/ir/SsaNormalizer.v3 +++ b/aeneas/src/ir/SsaNormalizer.v3 @@ -255,13 +255,6 @@ class SsaRaNormalizer extends SsaRebuilder { if (rc.isUnboxed()) { // flattened data type becomes component call and needs new receiver ai_new = Arrays.prepend(newGraph.nullReceiver(), ai_new); - } else { - var obj = ai_new[0]; - if (V3Op.needsNullCheck(i_old, obj)) { - // XXX: make CallVariantMethod operator for null replacement? - ai_new[0] = curBlock.add(V3Op.newVariantReplaceNull(m.receiver), [obj], Facts.NONE); - norm.newIr.getIrClass(m.receiver).facts |= Fact.C_HEAP; - } } } normCall(i_old, funcNorm, newOp, ai_new); @@ -315,13 +308,6 @@ class SsaRaNormalizer extends SsaRebuilder { if (rc.isUnboxed()) { // flattened data type becomes component call and needs new receiver ai_new = Arrays.prepend(newGraph.nullReceiver(), ai_new); - } else { - // for variant calls, replace null receiver with record - var obj = normVariantGetTag(rc.variantNorm, ai_new); - if (!obj.facts.V_NON_ZERO) { - ai_new[0] = curBlock.add(V3Op.newVariantReplaceNull(m.receiver), [obj], Facts.NONE); - norm.newIr.makeIrClass(m.receiver).facts |= Fact.C_HEAP; - } } normCall(i_old, funcNorm, V3Op.newCallMethod(m), ai_new); } @@ -744,12 +730,6 @@ class SsaRaNormalizer extends SsaRebuilder { if (t.1) { newOp = V3Op.newCallVariantSelector(m); } else { - var obj = x; - if (!obj.facts.V_NON_ZERO) { - // XXX: make CallVariantMethod operator for null replacement? - x = curBlock.add(V3Op.newVariantReplaceNull(m.receiver), [obj], Facts.NONE); - norm.newIr.getIrClass(m.receiver).facts |= Fact.C_HEAP; - } newOp = V3Op.newCallMethod(m); facts |= Fact.O_NO_NULL_CHECK; } diff --git a/aeneas/src/jvm/JvmGen.v3 b/aeneas/src/jvm/JvmGen.v3 index 96cd13694..fd4941831 100644 --- a/aeneas/src/jvm/JvmGen.v3 +++ b/aeneas/src/jvm/JvmGen.v3 @@ -630,14 +630,6 @@ class JvmV3ClosureGen extends JvmClassGen { // emit the invocation method var invoke_code = builder.newCodeBuilder(); invoke_code.locals(invoke_sig.localsSize(true)); - if (isVariant) { - // substitute default variant record for null - invoke_code.load(JvmTypes.KIND_OBJECT, 1); - var b = invoke_code.branch_fw(JvmBytecode.IFNONNULL); - builder.jprog.jrep.emitDefaultVariantRecord(memberRef.receiver, invoke_code); - invoke_code.store(JvmTypes.KIND_OBJECT, 1); - invoke_code.patchBranch(b); - } builder.emitLoadArguments(invoke_code, funcType, memberRef.getUnboundType(), 1); builder.jprog.jrep.emitInvokeVirtual(invoke_code, memberRef, true); invoke_code.ret(jvmKind(Function.getReturnType(funcType))); diff --git a/aeneas/src/jvm/JvmRep.v3 b/aeneas/src/jvm/JvmRep.v3 index d5a40bc6f..cbb412b2d 100644 --- a/aeneas/src/jvm/JvmRep.v3 +++ b/aeneas/src/jvm/JvmRep.v3 @@ -222,17 +222,6 @@ class JvmTypeReps(jprog: JvmProgram) { code.newempty(jclass); code.athrow(); } - def emitDefaultVariantRecord(t: Type, code: JvmCodeBuilder) { - var jclass = getJvmClass(t); - if (jclass.defaultRecord == null) { - // XXX: canonicalize this default record with the one from reachability - var ct = ClassType.!(t); - jclass.defaultRecord = if(ct.classDecl.variantTag >= 0, - jprog.prog.newRecord(t, jprog.prog.ir.getIrClass(t).fields.length), - V3.makeDefaultVariantRecord(jprog.prog, t)); - } - jprog.jheap.emitRecordValue(code, jclass.defaultRecord); - } def emitInvokeVirtual(code: JvmCodeBuilder, spec: IrSpec, nonnull: bool) { var jclass = jprog.jvmClass(spec.receiver); var nsig = jprog.jvmSig(spec.getMethodType()); diff --git a/aeneas/src/jvm/SsaJvmGen.v3 b/aeneas/src/jvm/SsaJvmGen.v3 index 9a81445fb..32490b490 100644 --- a/aeneas/src/jvm/SsaJvmGen.v3 +++ b/aeneas/src/jvm/SsaJvmGen.v3 @@ -514,14 +514,6 @@ class SsaJvmGen(jprog: JvmProgram, context: SsaContext, jsig: JvmSig, code: JvmC var dclass = jprog.newClosure(methodRef); code.invokestatic(dclass.name, "$get", JvmSig.new([jclass], dclass)); } - VariantReplaceNull => { - var t = op.typeArgs[0]; - code.dup(); - var b = code.branch_fw(JvmBytecode.IFNONNULL); - code.pop(); - code.builder.jprog.jrep.emitDefaultVariantRecord(t, code); - code.patchBranch(b); - } Init => ; // do nothing ComponentGetField(field) => jprog.jrep.emitGetField(V3Op.extractIrSpec(op, field), code); ComponentSetField(field) => { diff --git a/aeneas/src/mach/MachLowering.v3 b/aeneas/src/mach/MachLowering.v3 index cfe5def8e..96f4c3a16 100644 --- a/aeneas/src/mach/MachLowering.v3 +++ b/aeneas/src/mach/MachLowering.v3 @@ -514,7 +514,6 @@ class MachLowering(mach: MachProgram, compiler: Compiler, config: MachLoweringCo VariantGetField(field) => return genClassGetField(true, i_old, field); VariantGetMethod(method) => i_new = genVariantGetMethod(i_old, method); VariantGetSelector(selector) => i_new = genVariantGetSelector(i_old, selector); - VariantReplaceNull => i_new = genVariantReplaceNull(i_old); ComponentGetField(field) => return genComponentGetField(i_old, field); ComponentSetField(field) => return genComponentSetField(i_old, field); TupleGetElem(index) => return genTupleGetElem(i_old, index); @@ -1720,20 +1719,6 @@ class MachLowering(mach: MachProgram, compiler: Compiler, config: MachLoweringCo var mtbl = context.graph.valConst(mach.data.ptrType, mach.methodTable(methodRef)); return ptrLoad(funcRep.machType, ptrAdd(mtbl, tid), 0); } - def genVariantReplaceNull(i_old: SsaApplyOp) -> SsaInstr { - var vt = i_old.op.typeArgs[0]; - var val = i_old.input0(); - if (V3.getVariantTag(vt) == 0) return val; // tag == 0 should be prepared for null - var t = addIfNull(val); - var tblock = t.0, fblock = t.1, merge = t.2; - curBlock = fblock; - fblock.addGoto(merge.block); - tblock.addGoto(merge.block); - curBlock = merge; - var record = V3.makeDefaultVariantRecord(context.prog, vt); - var addr = mach.machVal(record); - return curBlock.addPhi(vt, [val, context.graph.valConst(mach.machType(vt), addr)]); - } def genComponentGetField(i_old: SsaApplyOp, field: IrField) { if (config.ObjectSystem) return void(normId(i_old)); var fieldRef = V3Op.extractIrSpec(i_old.op, field); diff --git a/doc/aeneas-issues.txt b/doc/aeneas-issues.txt index 106e29ace..d6793d982 100644 --- a/doc/aeneas-issues.txt +++ b/doc/aeneas-issues.txt @@ -47,6 +47,7 @@ ______ ______ __ _ ______ ______ ______ _____ ______ ______ _ _ ______ _ encoding of struct, array, func types -- aeneas sucks ----- + Enum.set.view(int) and int.view(Enum.set) names for synthesized functions (e.g. Class.==, byte.!) Do in-place specialization and normalization move IntNormalizer into reachability/norm phase instead of mach lowering