mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-29 07:04:09 +08:00
Merge pull request #839 from vercel-labs/perf/length-to-double-nneg
Convert lengths and in-range indices to doubles as non-negative
This commit is contained in:
@@ -213,7 +213,7 @@ test("length assignments skip the runtime when the length is unchanged", () => {
|
||||
module("reset", VOID, [{ kind: "arraySetLength", arr: ref("s", words), length: index, loc }]),
|
||||
);
|
||||
const fn = body(llvm, "reset");
|
||||
expect(fn).toMatch(/uitofp i64 .* to double/);
|
||||
expect(fn).toMatch(/uitofp nneg i64 .* to double/);
|
||||
expect(fn).toMatch(/fcmp oeq double %p?\S*, %t\d+/);
|
||||
expect(fn.match(/call void @scr_arr_set_len\(/g)).toHaveLength(1);
|
||||
expect(fn).toMatch(/br i1 %t\d+, label %arr\.len\.done\d*, label %arr\.len\.set\d*/);
|
||||
|
||||
@@ -411,7 +411,7 @@ export function emitDenseArrayPush(
|
||||
fastValue = B.tmp();
|
||||
B.line(`${next} = add nuw ${size} ${len}, 1`);
|
||||
B.line(`store ${size} ${next}, ptr ${lenPtr}${host.fieldAliasAttachment(lenPtr)}`);
|
||||
B.line(`${fastValue} = uitofp ${size} ${next} to double`);
|
||||
B.line(`${fastValue} = uitofp nneg ${size} ${next} to double`);
|
||||
B.br(join);
|
||||
B.startBlock(slow);
|
||||
const slowValue = B.tmp();
|
||||
|
||||
@@ -1668,7 +1668,7 @@ export class LlDyn {
|
||||
host.declare(`declare void @scr_arr_set_len(ptr, double)`);
|
||||
const index = B.tmp();
|
||||
const length = B.tmp();
|
||||
B.line(`${index} = uitofp ${this.S} ${i} to double`);
|
||||
B.line(`${index} = uitofp nneg ${this.S} ${i} to double`);
|
||||
B.line(`${length} = fadd double ${index}, 1.0`);
|
||||
B.line(`call void @scr_arr_set_len(ptr ${a}, double ${length})`);
|
||||
B.br(doneLabel);
|
||||
@@ -3409,7 +3409,7 @@ export class LlDyn {
|
||||
const n = this.lenOf(B, "%d");
|
||||
const nd = B.tmp();
|
||||
const r = B.tmp();
|
||||
B.line(`${nd} = uitofp ${host.sizeType} ${n} to double`);
|
||||
B.line(`${nd} = uitofp nneg ${host.sizeType} ${n} to double`);
|
||||
B.line(`${r} = call ptr @scr_dyn_new_num(double ${nd})`);
|
||||
B.terminate(`ret ptr ${r}`);
|
||||
B.startBlock(lStr);
|
||||
@@ -3448,7 +3448,7 @@ export class LlDyn {
|
||||
const n2 = B.tmp();
|
||||
B.line(`${n2} = call double @scr_str_utf16_len(ptr ${s})`);
|
||||
const idxD = B.tmp();
|
||||
B.line(`${idxD} = uitofp ${host.sizeType} ${idx} to double`);
|
||||
B.line(`${idxD} = uitofp nneg ${host.sizeType} ${idx} to double`);
|
||||
const inR2 = B.tmp();
|
||||
B.line(`${inR2} = fcmp olt double ${idxD}, ${n2}`);
|
||||
const lHit2 = B.newLabel("kg.ash");
|
||||
@@ -3599,7 +3599,7 @@ export class LlDyn {
|
||||
host.declare(`declare ptr @scr_dyn_jsval_iter_n(ptr, double)`);
|
||||
const count = B.tmp();
|
||||
const out = B.tmp();
|
||||
B.line(`${count} = uitofp ${host.sizeType} %n to double`);
|
||||
B.line(`${count} = uitofp nneg ${host.sizeType} %n to double`);
|
||||
B.line(`${out} = call ptr @scr_dyn_jsval_iter_n(ptr %d, double ${count})`);
|
||||
B.terminate(`ret ptr ${out}`);
|
||||
B.startBlock(lNotJv);
|
||||
@@ -3737,7 +3737,7 @@ export class LlDyn {
|
||||
const index = B.tmp();
|
||||
const bd = B.tmp();
|
||||
const r = B.tmp();
|
||||
B.line(`${index} = uitofp ${host.sizeType} ${i} to double`);
|
||||
B.line(`${index} = uitofp nneg ${host.sizeType} ${i} to double`);
|
||||
B.line(`${bd} = call double @scr_bytes_get(ptr ${bts}, double ${index})`);
|
||||
B.line(`${r} = call ptr @scr_dyn_new_num(double ${bd})`);
|
||||
B.line(`store ptr ${r}, ptr ${itemSlot}`);
|
||||
|
||||
@@ -1925,7 +1925,7 @@ export class LlEmitter {
|
||||
// The branch must dominate fptoui: NaN/out-of-range conversion
|
||||
// would produce poison. Fractional indices also need a fallback.
|
||||
` %index = fptoui double %i to ${this.sizeType}`,
|
||||
` %roundtrip = uitofp ${this.sizeType} %index to double`,
|
||||
` %roundtrip = uitofp nneg ${this.sizeType} %index to double`,
|
||||
` %integer = fcmp oeq double %roundtrip, %i`,
|
||||
` br i1 %integer, label %read, label %fallback`,
|
||||
`read:`,
|
||||
@@ -2759,14 +2759,14 @@ export class LlEmitter {
|
||||
`entry:`,
|
||||
` %ndp = getelementptr inbounds %ScrMapIx, ptr %m, i32 0, i32 19`,
|
||||
` %nd = load ${sz}, ptr %ndp`,
|
||||
` %ndf = uitofp ${sz} %nd to double`,
|
||||
` %ndf = uitofp nneg ${sz} %nd to double`,
|
||||
` %lo = fcmp oge double %k, 0.0`,
|
||||
` %hi = fcmp olt double %k, %ndf`,
|
||||
` %in = and i1 %lo, %hi`,
|
||||
` br i1 %in, label %direct, label %outside`,
|
||||
`direct:`,
|
||||
` %i = fptoui double %k to ${sz}`,
|
||||
` %back = uitofp ${sz} %i to double`,
|
||||
` %back = uitofp nneg ${sz} %i to double`,
|
||||
` %int = fcmp oeq double %back, %k`,
|
||||
` br i1 %int, label %slot, label %miss`,
|
||||
`slot:`,
|
||||
@@ -5626,7 +5626,7 @@ export class LlEmitter {
|
||||
B.line(`${lenPtr} = getelementptr inbounds %ScrArr, ptr ${arr.name}, i32 0, i32 1`);
|
||||
this.markMemoryPointer(lenPtr, "array:header");
|
||||
B.line(`${len} = load ${this.sizeType}, ptr ${lenPtr}${this.fieldAliasAttachment(lenPtr)}`);
|
||||
B.line(`${lenNumber} = uitofp ${this.sizeType} ${len} to double`);
|
||||
B.line(`${lenNumber} = uitofp nneg ${this.sizeType} ${len} to double`);
|
||||
B.line(`${same} = fcmp oeq double ${length.name}, ${lenNumber}`);
|
||||
B.condBr(same, done, resize);
|
||||
B.startBlock(resize);
|
||||
@@ -6255,7 +6255,7 @@ export class LlEmitter {
|
||||
B.line(
|
||||
`${rawLen} = load ${this.sizeType}, ptr ${lenPtr}${this.fieldAliasAttachment(lenPtr)}`,
|
||||
);
|
||||
B.line(`${len} = uitofp ${this.sizeType} ${rawLen} to double`);
|
||||
B.line(`${len} = uitofp nneg ${this.sizeType} ${rawLen} to double`);
|
||||
B.line(`${inBounds} = fcmp olt double ${i}, ${len}`);
|
||||
cur = i;
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ export function emitBytesIndex(
|
||||
const nonnegative = B.tmp();
|
||||
const belowLen = B.tmp();
|
||||
const inRange = B.tmp();
|
||||
B.line(`${lenF64} = uitofp ${host.sizeType} ${len} to double`);
|
||||
B.line(`${lenF64} = uitofp nneg ${host.sizeType} ${len} to double`);
|
||||
B.line(`${nonnegative} = fcmp oge double ${index}, ${f64Lit(0)}`);
|
||||
B.line(`${belowLen} = fcmp olt double ${index}, ${lenF64}`);
|
||||
B.line(`${inRange} = and i1 ${nonnegative}, ${belowLen}`);
|
||||
@@ -137,7 +137,7 @@ export function emitBytesIndex(
|
||||
const roundTrip = B.tmp();
|
||||
const integral = B.tmp();
|
||||
B.line(`${idx} = fptoui double ${index} to ${host.sizeType}`);
|
||||
B.line(`${roundTrip} = uitofp ${host.sizeType} ${idx} to double`);
|
||||
B.line(`${roundTrip} = uitofp nneg ${host.sizeType} ${idx} to double`);
|
||||
B.line(`${integral} = fcmp oeq double ${roundTrip}, ${index}`);
|
||||
B.condBr(integral, valid, invalid);
|
||||
|
||||
@@ -177,7 +177,7 @@ export function emitBytesLength(
|
||||
const count = bytes && size !== 1 ? B.tmp() : len;
|
||||
if (count !== len) B.line(`${count} = shl ${host.sizeType} ${len}, ${Math.log2(size)}`);
|
||||
const out = B.tmp();
|
||||
B.line(`${out} = uitofp ${host.sizeType} ${count} to double`);
|
||||
B.line(`${out} = uitofp nneg ${host.sizeType} ${count} to double`);
|
||||
return { name: out, type: F64 };
|
||||
}
|
||||
|
||||
|
||||
@@ -520,7 +520,7 @@ export function emitArrIntrinsic(
|
||||
B.line(`${p} = getelementptr inbounds %ScrArr, ptr ${r.name}, i32 0, i32 1`);
|
||||
host.markMemoryPointer(p, "array:header");
|
||||
B.line(`${len} = load ${host.sizeType}, ptr ${p}${host.fieldAliasAttachment(p)}`);
|
||||
B.line(`${t} = uitofp ${host.sizeType} ${len} to double`);
|
||||
B.line(`${t} = uitofp nneg ${host.sizeType} ${len} to double`);
|
||||
return { name: t, type: e.type };
|
||||
}
|
||||
case "getNumber": {
|
||||
|
||||
@@ -348,7 +348,7 @@ function emitDenseReferenceArrayRead(
|
||||
B.line(`${cap} = load ${host.sizeType}, ptr ${capPtr}${host.fieldAliasAttachment(capPtr)}`);
|
||||
if (integerIndex) B.line(`${inRange} = icmp ult ${host.sizeType} ${integerIndex}, ${cap}`);
|
||||
else {
|
||||
B.line(`${capNumber} = uitofp ${host.sizeType} ${cap} to double`);
|
||||
B.line(`${capNumber} = uitofp nneg ${host.sizeType} ${cap} to double`);
|
||||
B.line(`${nonnegative} = fcmp oge double ${index.name}, 0.0`);
|
||||
B.line(`${belowCap} = fcmp olt double ${index.name}, ${capNumber}`);
|
||||
B.line(`${inRange} = and i1 ${nonnegative}, ${belowCap}`);
|
||||
@@ -361,7 +361,7 @@ function emitDenseReferenceArrayRead(
|
||||
if (integerIndex) B.br(dense);
|
||||
else {
|
||||
B.line(`${offset} = fptoui double ${index.name} to ${host.sizeType}`);
|
||||
B.line(`${roundTrip} = uitofp ${host.sizeType} ${offset} to double`);
|
||||
B.line(`${roundTrip} = uitofp nneg ${host.sizeType} ${offset} to double`);
|
||||
B.line(`${integral} = fcmp oeq double ${index.name}, ${roundTrip}`);
|
||||
B.condBr(integral, dense, slow);
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ export const STRING_READ_HELPERS: readonly StringReadHelper[] = [
|
||||
` br i1 %ascii, label %fast, label %slow`,
|
||||
`fast:`,
|
||||
...loadLength(sz),
|
||||
` %n = uitofp ${sz} %len to double`,
|
||||
` %n = uitofp nneg ${sz} %len to double`,
|
||||
` ret double %n`,
|
||||
`slow:`,
|
||||
` %r = call double @scr_str_utf16_len(ptr %s)`,
|
||||
@@ -62,7 +62,7 @@ export const STRING_READ_HELPERS: readonly StringReadHelper[] = [
|
||||
` br i1 %ascii, label %bounds, label %slow`,
|
||||
`bounds:`,
|
||||
...loadLength(sz),
|
||||
` %lenf = uitofp ${sz} %len to double`,
|
||||
` %lenf = uitofp nneg ${sz} %len to double`,
|
||||
// NaN fails both ordered comparisons; -0 passes and truncates to 0.
|
||||
` %lo = fcmp oge double %i, 0.0`,
|
||||
` %hi = fcmp olt double %i, %lenf`,
|
||||
|
||||
@@ -97,7 +97,7 @@ export function emitStringSliceRead(host: LlvmEmitterContext, value: Slice): LlV
|
||||
`${pointer} = getelementptr inbounds { ${host.sizeType}, ${host.sizeType}, i32 }, ptr ${snapshot.range}, i32 0, i32 1`,
|
||||
);
|
||||
B.line(`${length} = load ${host.sizeType}, ptr ${pointer}`);
|
||||
B.line(`${number} = uitofp ${host.sizeType} ${length} to double`);
|
||||
B.line(`${number} = uitofp nneg ${host.sizeType} ${length} to double`);
|
||||
return { name: number, type: value.type };
|
||||
}
|
||||
if (value.method !== "charCodeAt") return null;
|
||||
|
||||
Reference in New Issue
Block a user