Skip to content

Improve typed array sort #1040

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 30 additions & 12 deletions src/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6652,28 +6652,46 @@ export class Compiler extends DiagnosticEmitter {
): void {
// Differs from `performAutoreleases` in that concluding this flow also
// concludes all its parent flows, for example on a `return`.
var module = this.module;
if (flow.is(FlowFlags.INLINE_CONTEXT)) {
// Traverse to the top-most flow containing the inlined function's
// locals as scoped locals and release these instead of all the locals.
let current = flow;
let parent: Flow | null;
while (parent = flow.parent) flow = parent;
this.performAutoreleases(flow, stmts, /* finalize */ false);
while (parent = current.parent) current = parent;
let scopedLocals = current.scopedLocals;
if (scopedLocals) {
for (let local of scopedLocals.values()) {
this.maybeFinishAutorelease(local, flow, stmts);
}
}
} else {
for (let local of flow.parentFunction.localsByIndex) {
let localIndex = local.index;
if (flow.isAnyLocalFlag(localIndex, LocalFlags.ANY_RETAINED)) {
flow.unsetLocalFlag(localIndex, LocalFlags.ANY_RETAINED);
stmts.push(
this.makeRelease(
module.local_get(localIndex, local.type.toNativeType())
)
);
}
this.maybeFinishAutorelease(local, flow, stmts);
}
}
}

/** Finishes a single autorelease of the specified local. */
private maybeFinishAutorelease(
/** Local to finish autoreleasing. */
local: Local,
/** Flow releasing its queued autoreleases. */
flow: Flow,
/** Array of statements to append the releases to. */
stmts: ExpressionRef[]
): void {
var localIndex = local.index;
var module = this.module;
if (~localIndex && flow.isAnyLocalFlag(localIndex, LocalFlags.ANY_RETAINED)) {
flow.unsetLocalFlag(localIndex, LocalFlags.ANY_RETAINED);
stmts.push(
this.makeRelease(
module.local_get(localIndex, local.type.toNativeType())
)
);
}
}

// </reference-counting>

/** Creates a direct call to the specified function. */
Expand Down
42 changes: 26 additions & 16 deletions std/assembly/typedarray.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ export class Int8Array extends ArrayBufferView {
}

sort(comparator: (a: i8, b: i8) => i32 = COMPARATOR<i8>()): Int8Array {
return SORT<Int8Array, i8>(this, comparator);
SORT<Int8Array, i8>(this, comparator);
return this;
}

slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Int8Array {
Expand Down Expand Up @@ -186,7 +187,8 @@ export class Uint8Array extends ArrayBufferView {
}

sort(comparator: (a: u8, b: u8) => i32 = COMPARATOR<u8>()): Uint8Array {
return SORT<Uint8Array, u8>(this, comparator);
SORT<Uint8Array, u8>(this, comparator);
return this;
}

slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Uint8Array {
Expand Down Expand Up @@ -314,7 +316,8 @@ export class Uint8ClampedArray extends ArrayBufferView {
}

sort(fn: (a: u8, b: u8) => i32 = COMPARATOR<u8>()): Uint8ClampedArray {
return SORT<Uint8ClampedArray, u8>(this, fn);
SORT<Uint8ClampedArray, u8>(this, fn);
return this;
}

slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Uint8ClampedArray {
Expand Down Expand Up @@ -442,7 +445,8 @@ export class Int16Array extends ArrayBufferView {
}

sort(comparator: (a: i16, b: i16) => i32 = COMPARATOR<i16>()): Int16Array {
return SORT<Int16Array, i16>(this, comparator);
SORT<Int16Array, i16>(this, comparator);
return this;
}

slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Int16Array {
Expand Down Expand Up @@ -570,7 +574,8 @@ export class Uint16Array extends ArrayBufferView {
}

sort(comparator: (a: u16, b: u16) => i32 = COMPARATOR<u16>()): Uint16Array {
return SORT<Uint16Array, u16>(this, comparator);
SORT<Uint16Array, u16>(this, comparator);
return this;
}

slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Uint16Array {
Expand Down Expand Up @@ -698,7 +703,8 @@ export class Int32Array extends ArrayBufferView {
}

sort(comparator: (a: i32, b: i32) => i32 = COMPARATOR<i32>()): Int32Array {
return SORT<Int32Array, i32>(this, comparator);
SORT<Int32Array, i32>(this, comparator);
return this;
}

slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Int32Array {
Expand Down Expand Up @@ -826,7 +832,8 @@ export class Uint32Array extends ArrayBufferView {
}

sort(comparator: (a: u32, b: u32) => i32 = COMPARATOR<u32>()): Uint32Array {
return SORT<Uint32Array, u32>(this, comparator);
SORT<Uint32Array, u32>(this, comparator);
return this;
}

slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Uint32Array {
Expand Down Expand Up @@ -954,7 +961,8 @@ export class Int64Array extends ArrayBufferView {
}

sort(comparator: (a: i64, b: i64) => i32 = COMPARATOR<i64>()): Int64Array {
return SORT<Int64Array, i64>(this, comparator);
SORT<Int64Array, i64>(this, comparator);
return this;
}

slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Int64Array {
Expand Down Expand Up @@ -1082,7 +1090,8 @@ export class Uint64Array extends ArrayBufferView {
}

sort(comparator: (a: u64, b: u64) => i32 = COMPARATOR<u64>()): Uint64Array {
return SORT<Uint64Array, u64>(this, comparator);
SORT<Uint64Array, u64>(this, comparator);
return this;
}

slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Uint64Array {
Expand Down Expand Up @@ -1210,7 +1219,8 @@ export class Float32Array extends ArrayBufferView {
}

sort(comparator: (a: f32, b: f32) => i32 = COMPARATOR<f32>()): Float32Array {
return SORT<Float32Array, f32>(this, comparator);
SORT<Float32Array, f32>(this, comparator);
return this;
}

slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Float32Array {
Expand Down Expand Up @@ -1338,7 +1348,8 @@ export class Float64Array extends ArrayBufferView {
}

sort(comparator: (a: f64, b: f64) => i32 = COMPARATOR<f64>()): Float64Array {
return SORT<Float64Array, f64>(this, comparator);
SORT<Float64Array, f64>(this, comparator);
return this;
}

slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Float64Array {
Expand Down Expand Up @@ -1439,9 +1450,9 @@ function FILL<TArray extends ArrayBufferView, T extends number>(
function SORT<TArray extends ArrayBufferView, T>(
array: TArray,
comparator: (a: T, b: T) => i32
): TArray {
): void {
var len = array.length;
if (len <= 1) return array;
if (len <= 1) return;
var base = array.dataStart;
if (len == 2) {
let a: T = load<T>(base, sizeof<T>()); // a = arr[1]
Expand All @@ -1450,10 +1461,9 @@ function SORT<TArray extends ArrayBufferView, T>(
store<T>(base, b, sizeof<T>()); // arr[1] = b
store<T>(base, a); // arr[0] = a
}
return array;
} else {
SORT_IMPL<T>(base, len, comparator);
}
SORT_IMPL<T>(base, len, comparator);
return array;
}

// @ts-ignore: decorator
Expand Down
4 changes: 2 additions & 2 deletions tests/compiler/resolve-elementaccess.optimized.wat
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@
if
i32.const 144
i32.const 208
i32.const 1187
i32.const 1196
i32.const 63
call $~lib/builtins/abort
unreachable
Expand All @@ -248,7 +248,7 @@
if
i32.const 144
i32.const 208
i32.const 1176
i32.const 1185
i32.const 63
call $~lib/builtins/abort
unreachable
Expand Down
4 changes: 2 additions & 2 deletions tests/compiler/resolve-elementaccess.untouched.wat
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@
if
i32.const 144
i32.const 208
i32.const 1187
i32.const 1196
i32.const 63
call $~lib/builtins/abort
unreachable
Expand All @@ -551,7 +551,7 @@
if
i32.const 144
i32.const 208
i32.const 1176
i32.const 1185
i32.const 63
call $~lib/builtins/abort
unreachable
Expand Down
2 changes: 1 addition & 1 deletion tests/compiler/std/dataview.optimized.wat
Original file line number Diff line number Diff line change
Expand Up @@ -1870,7 +1870,7 @@
if
i32.const 304
i32.const 416
i32.const 163
i32.const 164
i32.const 44
call $~lib/builtins/abort
unreachable
Expand Down
2 changes: 1 addition & 1 deletion tests/compiler/std/dataview.untouched.wat
Original file line number Diff line number Diff line change
Expand Up @@ -3622,7 +3622,7 @@
if
i32.const 304
i32.const 416
i32.const 163
i32.const 164
i32.const 44
call $~lib/builtins/abort
unreachable
Expand Down
804 changes: 654 additions & 150 deletions tests/compiler/std/typedarray.optimized.wat

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions tests/compiler/std/typedarray.ts
Original file line number Diff line number Diff line change
Expand Up @@ -807,4 +807,19 @@ testTypedArraySet<Float64Array>();
targetClampedArray.set(d, 0);
targetClampedArray.set(e, 5);
valuesEqual<Uint8ClampedArray>(targetClampedArray, [1, 255, 100, 255, 0, 0, 100, 10, 255, 0]);
}

{
let arr2 = new Int32Array(2);
arr2[0] = 2;
arr2[1] = 1;
arr2.sort();
assert(arr2[0] == 1 && arr2[1] == 2);

let arr3 = new Int32Array(3);
arr3[0] = 3;
arr3[1] = 2;
arr3[2] = 1;
arr3.sort();
assert(arr3[0] == 1 && arr3[1] == 2 && arr3[2] == 3);
}
1,108 changes: 844 additions & 264 deletions tests/compiler/std/typedarray.untouched.wat

Large diffs are not rendered by default.