Files
scriptc/tests/corpus/speculative-loop-view-headers.ts
T
Chris Tate eaa8a44cdf Read typed-array header fields once at a speculative loop's entry
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.
2026-10-26 02:02:46 -05:00

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(","));