mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-02 07:43:42 +08:00
A speculative integer loop's fast copy exits to a copy that resumes the failed iteration, and both read the header fields of the views they access. GVN's load PRE moved the fast copy's read of a view's data pointer ahead of the exit branch, to make the resume copy's read redundant, and put a copy on the exit edge. The loop then kept its first iteration in the loop, so the overflow checks of a value whose range is known after one iteration stayed in every iteration, with a reload of the data pointer. A view held by a const local or a parameter that the loop does not rebind is the same view in every iteration, and its length, data pointer and shared storage never change. The loop's entry now reads them once, and the element accesses of every copy use those values.
37 lines
1.2 KiB
TypeScript
37 lines
1.2 KiB
TypeScript
// Speculative integer loops over typed-array views held by a const local
|
|
// and by a parameter. The fast copy, the copy a failed check resumes in and
|
|
// the ordinary copy all read and write the same views: a product that
|
|
// leaves the safe integers fails the fast copy's check partway through,
|
|
// and writes past the end are ignored.
|
|
function fill(buffer: ArrayBuffer, count: number, seed: number): number {
|
|
const view = new Float64Array(buffer);
|
|
let l = seed;
|
|
for (let i = 0; i < count; i++) {
|
|
l = (l * 3877 + 29573) % 139968;
|
|
view[i] = l;
|
|
}
|
|
return l;
|
|
}
|
|
|
|
function grow(out: Int32Array, count: number, start: number): number {
|
|
let x = start;
|
|
for (let i = 0; i < count; i++) {
|
|
x = x * 3 + 1;
|
|
out[i] = x % 1000;
|
|
}
|
|
return x;
|
|
}
|
|
|
|
function sum(view: Float64Array | Int32Array): number {
|
|
let s = 0;
|
|
for (const v of view) s += v;
|
|
return s;
|
|
}
|
|
|
|
const buffer = new ArrayBuffer(8 * 64);
|
|
console.log(fill(buffer, 64, 42), sum(new Float64Array(buffer)));
|
|
console.log(fill(buffer, 100, 7), new Float64Array(buffer)[63]);
|
|
const out = new Int32Array(40);
|
|
console.log(grow(out, 60, 1), sum(out), out[0], out[39]);
|
|
console.log(grow(out, 10, 5), out.join(","));
|