Skip to content

Commit

Permalink
Normalize Ranges using RangeStart (#206)
Browse files Browse the repository at this point in the history
* Add CiRuntime.forgeRange
* Add -nr flag
* Update arguments to Range
* Change Ref's to use RangeStart's
* Change to V3.unboxI32
* New tests
  • Loading branch information
btwj authored Oct 22, 2023
1 parent 2d42a51 commit 4868eae
Show file tree
Hide file tree
Showing 31 changed files with 796 additions and 126 deletions.
43 changes: 41 additions & 2 deletions aeneas/src/core/Eval.v3
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,45 @@ def evalOp(op: Operator, args: Arguments) -> Result {
if (val == null) return Int.ZERO;
return Int.box(ArrayRangeVal.!(val).length);
}
RangeStartPlusIndex => {
var index = args.i(1);
match (args.vals[0]) {
null => return PointerRangeStart.new(NULL_PTR.add(index));
x: ArrayRangeStart => return ArrayRangeStart.new(index + x.start, x.arrayType);
x: PointerRangeStart => return PointerRangeStart.new(x.start.add(index));
}
}
NormRangeGetElem => {
var array = args.r(0), start = args.vals[1], index = args.i(2);
if (array == null) return args.throw(V3Exception.NullCheck, null);
if (start != null) index += ArrayRangeStart.!(start).start;
return array.values[index];
}
NormRangeGetElemElem(elem) => {
var array = args.r(0), start = args.vals[1], index = args.i(2);
if (array == null) return args.throw(V3Exception.NullCheck, null);
if (start != null) index += ArrayRangeStart.!(start).start;
var tval = TupleVal.!(array.values[index]);
if (tval == null) return null;
return tval.values[elem];
}
NormRangeSetElem => {
var array = args.r(0), start = args.vals[1], index = args.i(2);
if (array == null) return args.throw(V3Exception.NullCheck, null);
if (start != null) index += ArrayRangeStart.!(start).start;
return array.values[index] = args.vals[3];
}
NormRangeSetElemElem(elem) => {
var array = args.r(0), start = args.vals[1], index = args.i(2);
if (array == null) return args.throw(V3Exception.NullCheck, null);
if (start != null) index += ArrayRangeStart.!(start).start;
var tval = TupleVal.!(array.values[index]);
if (tval == null) {
var len = Tuple.length(V3Array.elementType(args.getTypeArg(0)));
array.values[index] = tval = TupleVal.new(Array<Val>.new(len));
}
return tval.values[elem] = args.vals[3]; // TODO: in-place mutation of tuple element
}
//----------------------------------------------------------------------------
Init(method) => {
var index = VstNew.!(method.source).initIndex;
Expand Down Expand Up @@ -848,13 +887,13 @@ def evalOp(op: Operator, args: Arguments) -> Result {
}
ByteArrayGetField(offset) => {
var array = args.r(0);
var i_offset = args.i(1);
var i_offset = if(ArrayRangeStart.?(args.vals[1]), ArrayRangeStart.!(args.vals[1]).start, args.i(1));
// XXX: Refactor so no intermediate ByteArrayOffset object needed
return doRefLayoutGetField(args, args.getTypeArg(0), ByteArrayOffset.new(array, offset), i_offset);
}
ByteArraySetField(offset) => {
var array = args.r(0);
var i_offset = args.i(1);
var i_offset = if(ArrayRangeStart.?(args.vals[1]), ArrayRangeStart.!(args.vals[1]).start, args.i(1));
// XXX: Refactor so no intermediate ByteArrayOffset object needed
return doRefLayoutSetField(args, args.getTypeArg(0), ByteArrayOffset.new(array, offset), i_offset, args.vals[2]);
}
Expand Down
18 changes: 18 additions & 0 deletions aeneas/src/core/Opcode.v3
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ type Opcode {
case RangeGetElem;
case RangeSetElem;
case RangeGetLength;
case RangeStartPlusIndex;
case RangeStartFromPointer;
// Normalized Range operations
case NormRangeGetElem;
case NormRangeGetElemElem(index: int);
case NormRangeSetElem;
case NormRangeSetElemElem(index: int);
// Component operations
case Init(method: IrMethod);
case ComponentGetField(field: IrField);
Expand Down Expand Up @@ -127,6 +134,7 @@ type Opcode {
case RefLayoutSetRepeatedField(offset: int, scale: int, max: int);
case ByteArrayGetField(offset: int);
case ByteArraySetField(offset: int);
case ForgeRange;
// System operations
case SystemCall(syscall: SystemCall);
// Container for VST operations
Expand All @@ -150,6 +158,7 @@ type Opcode {
case PtrCmpSwp;
case PtrLoad;
case PtrStore;
case PtrAddRangeStart;
// Get caller instruction pointer or stack pointer
case CallerIp;
case CallerSp;
Expand Down Expand Up @@ -244,6 +253,15 @@ component Opcodes {
t[Opcode.RangeFromPlus.tag] = F;
t[Opcode.RangeGetLength.tag] = P;

t[Opcode.RangeStartPlusIndex.tag] = P;
t[Opcode.RangeStartFromPointer.tag] = P;
t[Opcode.NormRangeGetElem.tag] = F;
t[Opcode.NormRangeGetElemElem.tag] = F;
t[Opcode.NormRangeSetElem.tag] = NONE;
t[Opcode.NormRangeSetElemElem.tag] = NONE;
t[Opcode.PtrAddRangeStart.tag] = P;
t[Opcode.ForgeRange.tag] = P;

t[Opcode.Init.tag] = NONE;
t[Opcode.ComponentGetField.tag] = NNC;
t[Opcode.ComponentSetField.tag] = NNC;
Expand Down
43 changes: 38 additions & 5 deletions aeneas/src/core/Operator.v3
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ component V3Op {
def type_v = Void.TYPE;
def type_f: Type = Float.FLOAT32;
def type_d: Type = Float.FLOAT64;
def type_rs = V3Range.START_TYPE;

def arr_z = Bool.ARRAY_T;
def arr_i = Int.ARRAY_T;
Expand Down Expand Up @@ -219,6 +220,28 @@ component V3Op {
var tt = [rangeType];
return newOp0(Opcode.RangeGetLength, tt, tt, type_i);
}
def newRangeStartPlusIndex(rangeType: Type, indexType: IntType) -> Operator {
return newOp0(Opcode.RangeStartPlusIndex, [rangeType, indexType], [type_rs, indexType], type_rs);
}
def newRangeStartFromPointer(rangeType: Type, ptrType: PointerType) -> Operator {
return newOp0(Opcode.RangeStartFromPointer, [rangeType, ptrType], [ptrType], type_rs);
}
def newNormRangeGetElem(arrayType: Type, indexType: Type) -> Operator {
var etype = V3Array.elementType(arrayType);
return newOp0(Opcode.NormRangeGetElem, [arrayType, indexType], [arrayType, type_rs, indexType], etype);
}
def newNormRangeGetElemElem(arrayType: Type, indexType: IntType, index: int) -> Operator {
var etype = Tuple.elementType(V3Array.elementType(arrayType), index);
return newOp0(Opcode.NormRangeGetElemElem(index), [arrayType, indexType], [arrayType, type_rs, indexType], etype);
}
def newNormRangeSetElem(arrayType: Type, indexType: Type) -> Operator {
var etype = V3Array.elementType(arrayType);
return newOp0(Opcode.NormRangeSetElem, [arrayType, indexType], [arrayType, type_rs, indexType, etype], type_v);
}
def newNormRangeSetElemElem(arrayType: Type, indexType: IntType, index: int) -> Operator {
var etype = Tuple.elementType(V3Array.elementType(arrayType), index);
return newOp0(Opcode.NormRangeSetElemElem(index), [arrayType, indexType], [arrayType, type_rs, indexType, etype], type_v);
}
//----------------------------------------------------------------------------
def newInit(meth: IrMethod) -> Operator {
return newOp0(Opcode.Init(meth), TypeUtil.NO_TYPES, TypeUtil.NO_TYPES, meth.receiver);
Expand Down Expand Up @@ -328,7 +351,8 @@ component V3Op {
V3Kind.POINTER,
V3Kind.ARRAY,
V3Kind.CLASS,
V3Kind.FUNCREF => opcode = Opcode.RefEq;
V3Kind.FUNCREF,
V3Kind.RANGE_START => opcode = Opcode.RefEq;
V3Kind.VARIANT => opcode = Opcode.VariantEq;
}
return newOp0(opcode, [t], [t, t], type_z);
Expand Down Expand Up @@ -401,6 +425,10 @@ component V3Op {
var funcType = Function.newType(param, result);
return newOp0(Opcode.UnpackClosure, [receiver, param, result], [funcType], Tuple.newType(Lists.cons2(ptrType, receiver)));
}
def newForgeRange(elementType: Type, ptrType: Type) -> Operator {
var rangeType = V3Range.newType(elementType);
return newOp0(Opcode.ForgeRange, [elementType, ptrType], [ptrType, Int.TYPE], rangeType);
}
//----------------------------------------------------------------------------
def newSystemCall(syscall: SystemCall, paramTypes: Array<Type>, returnType: Type) -> Operator {
return newOp0(Opcode.SystemCall(syscall), arr_v, paramTypes, returnType);
Expand Down Expand Up @@ -466,6 +494,9 @@ component V3Op {
var tt = [ptrType, valueType];
return newOp0(Opcode.PtrStore, tt, tt, type_v);
}
def newPtrAddRangeStart(ptrType: Type) -> Operator {
return newOp0(Opcode.PtrAddRangeStart, [ptrType], [ptrType, type_rs], ptrType);
}
//----------------------------------------------------------------------------
def newCallerIp(ptrType: Type) -> Operator {
return newOp0(Opcode.CallerIp, TypeUtil.NO_TYPES, arr_v, ptrType);
Expand Down Expand Up @@ -517,13 +548,13 @@ component V3Op {
var opcode = Opcode.RefLayoutSetRepeatedField(offset, scale, max);
return newOp0(opcode, [refType, fieldType], [refType, Int.TYPE, fieldType], Void.TYPE);
}
def newByteArrayGetField(offset: int, fieldType: Type) -> Operator {
def newByteArrayGetField(offset: int, fieldType: Type, startType: Type) -> Operator {
var opcode = Opcode.ByteArrayGetField(offset);
return newOp0(opcode, [fieldType], [V3.arrayByteType, Int.TYPE], fieldType);
return newOp0(opcode, [fieldType, startType], [V3.arrayByteType, startType], fieldType);
}
def newByteArraySetField(offset: int, fieldType: Type) -> Operator {
def newByteArraySetField(offset: int, fieldType: Type, startType: Type) -> Operator {
var opcode = Opcode.ByteArraySetField(offset);
return newOp0(opcode, [fieldType], [V3.arrayByteType, Int.TYPE, fieldType], Void.TYPE);
return newOp0(opcode, [fieldType, startType], [V3.arrayByteType, startType, fieldType], Void.TYPE);
}
//----------------------------------------------------------------------------
def bestCallVirtual(spec: IrSpec) -> Operator {
Expand Down Expand Up @@ -579,6 +610,8 @@ def renderOp(op: Operator, buf: StringBuilder) -> StringBuilder {
ArrayTupleInit(elems, length) => rfunc = StringBuilder.put2(_, "%d,%d", elems, length);
ArrayGetElemElem(index) => rfunc = StringBuilder.putd(_, index);
ArraySetElemElem(index) => rfunc = StringBuilder.putd(_, index);
NormRangeGetElemElem(index) => rfunc = StringBuilder.putd(_, index);
NormRangeSetElemElem(index) => rfunc = StringBuilder.putd(_, index);
ComponentGetField(field) => rfunc = field.render;
ComponentSetField(field) => rfunc = field.render;
ClassGetField(field) => rfunc = field.render;
Expand Down
13 changes: 9 additions & 4 deletions aeneas/src/ir/Normalization.v3
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class NormalizerConfig {
var RangeStartType: IntType;
var NonRefClosureReceiver: bool;
var AnyRefOverflow: bool;
var NormalizeRange: bool;

def setSignatureLimits(maxp: int, maxr: int) {
if (maxp < MaxParams) MaxParams = maxp;
Expand Down Expand Up @@ -173,7 +174,8 @@ class ReachabilityNormalizer(config: NormalizerConfig, ra: ReachabilityAnalyzer)
var an = ArrayNorm.!(norm(V3Array.newType(et)));
var vec = Vector<Type>.new().grow(an.size + 2);
an.addTo(vec);
vec.putn(Int.getType(false, 32), 2);
vec.put(if(config.NormalizeRange && an.size <= 1, V3Range.START_TYPE, config.RangeStartType));
vec.put(Int.getType(false, 32));
var sub = vec.extract();
var newType = Tuple.fromTypeArray(sub);
tn = RangeNorm.new(t, newType, sub, an);
Expand Down Expand Up @@ -210,7 +212,10 @@ class ReachabilityNormalizer(config: NormalizerConfig, ra: ReachabilityAnalyzer)
tn = TypeNorm.new(t, V3.getVariantTagType(t), null);
}
V3Kind.REF => {
var sub = [V3.arrayByteType, Int.TYPE];
var sub = [
V3.arrayByteType,
if(config.NormalizeRange, V3Range.START_TYPE, Int.TYPE)
];
tn = TypeNorm.new(t, Tuple.newType(Lists.cons2(V3.arrayByteType, Int.TYPE)), sub);
}
_ => {
Expand Down Expand Up @@ -582,13 +587,13 @@ class ReachabilityNormalizer(config: NormalizerConfig, ra: ReachabilityAnalyzer)
x: ArrayRangeVal => {
var rn = RangeNorm.!(tn);
normValIntoArray(x.array, rn.arrayNorm, array, index);
array[index + rn.startIndex()] = Int.box(x.start);
array[index + rn.startIndex()] = if(config.NormalizeRange && rn.arrayNorm.size <= 1, ArrayRangeStart.new(x.start, rn.arrayNorm.newType), Int.box(x.start));
array[index + rn.lengthIndex()] = Int.box(x.length);
}
x: ByteArrayOffset => {
var an = ArrayNorm.!(norm(V3.arrayByteType));
normValIntoArray(x.array, an, array, index);
array[index + an.size] = Int.box(x.offset);
array[index + an.size] = ArrayRangeStart.new(x.offset, V3.arrayByteType);
}
_ => if (index < array.length) array[index] = v;
}
Expand Down
Loading

0 comments on commit 4868eae

Please sign in to comment.