Skip to content
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
1 change: 1 addition & 0 deletions conformance/runner/script-metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export function tsSourcePath(fixture: string, testsDir: string = TESTS_DIR): str
export const VARIANTS: Record<string, CompileOptions> = {
current: {},
'ec-pool': { ecConstantPool: true },
'ec-sink': { ecConstantPool: true, ecReductionSinking: true },
liveness: { schedulerMode: 'liveness' },
both: { ecConstantPool: true, schedulerMode: 'liveness' },
};
Expand Down
6 changes: 6 additions & 0 deletions packages/runar-cli/src/__tests__/experimental-flags.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,10 @@ describe('experimental size-optimizer flags', () => {
const pooled = await hexWith({ ecConstantPool: true }, 'pool');
expect(pooled).toBe(bare);
});

it('--ec-reduction-sinking is inert on a contract with no EC operations', async () => {
const bare = await hexWith({}, 'nosink');
const sunk = await hexWith({ ecConstantPool: true, ecReductionSinking: true }, 'sink');
expect(sunk).toBe(bare);
});
});
1 change: 1 addition & 0 deletions packages/runar-cli/src/bin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ program
.option('--asm', 'print ASM to stdout')
.option('--disable-constant-folding', 'disable ANF constant folding pass')
.option('--ec-constant-pool', 'EXPERIMENTAL: pool repeated EC curve constants (changes emitted bytes)')
.option('--ec-reduction-sinking', 'EXPERIMENTAL: drop provably-dead sign fix-ups from EC modular reductions')
.option('--stack-scheduler <mode>', 'EXPERIMENTAL: operand scheduling — current|liveness', 'current')
.option('--from-ir <path>', 'compile from an ANF IR JSON file (skips parse/validate/typecheck/anf-lower)')
.option('--hex', 'print only the script hex to stdout (no artifact JSON)')
Expand Down
7 changes: 5 additions & 2 deletions packages/runar-cli/src/commands/compile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ interface CompileOptions {
asm?: boolean;
disableConstantFolding?: boolean;
ecConstantPool?: boolean;
ecReductionSinking?: boolean;
stackScheduler?: string;
fromIr?: string;
hex?: boolean;
Expand Down Expand Up @@ -96,10 +97,10 @@ export async function compileCommand(

// Dynamically import the compiler to avoid hard failures if it's not
// yet fully built (the compiler package may still be under development).
type CompileFn = (source: string, options?: { fileName?: string; disableConstantFolding?: boolean; ecConstantPool?: boolean; schedulerMode?: 'current' | 'liveness'; parseOnly?: boolean }) => unknown;
type CompileFn = (source: string, options?: { fileName?: string; disableConstantFolding?: boolean; ecConstantPool?: boolean; ecReductionSinking?: boolean; schedulerMode?: 'current' | 'liveness'; parseOnly?: boolean }) => unknown;
type CompileFromANFFn = (
program: unknown,
options?: { disableConstantFolding?: boolean; ecConstantPool?: boolean; schedulerMode?: 'current' | 'liveness' },
options?: { disableConstantFolding?: boolean; ecConstantPool?: boolean; ecReductionSinking?: boolean; schedulerMode?: 'current' | 'liveness' },
) => { scriptHex: string; scriptAsm: string };
type LoadANFFn = (json: string) => unknown;

Expand Down Expand Up @@ -192,6 +193,7 @@ export async function compileCommand(
result = compileFromANF(program, {
disableConstantFolding: options.disableConstantFolding,
ecConstantPool: options.ecConstantPool,
ecReductionSinking: options.ecReductionSinking,
schedulerMode: schedulerMode(options),
});
} catch (err) {
Expand Down Expand Up @@ -270,6 +272,7 @@ export async function compileCommand(
fileName: resolvedPath,
disableConstantFolding: options.disableConstantFolding,
ecConstantPool: options.ecConstantPool,
ecReductionSinking: options.ecReductionSinking,
schedulerMode: schedulerMode(options),
parseOnly: options.parseOnly,
}) as CompileResultLike;
Expand Down
15 changes: 15 additions & 0 deletions packages/runar-compiler/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,17 @@ export interface CompileOptions {
*/
ecConstantPool?: boolean;

/**
* EXPERIMENTAL. Drop the sign fix-up from EC modular reductions wherever a
* sign lattice proves the dividend non-negative, and use the cheap
* `a - b + p` form where the subtrahend is proved reduced.
*
* Only pays alongside `ecConstantPool` — the cheap subtraction references the
* prime twice — and the codegen compares emitted bytes before choosing it.
* Measured: `verifyECDSA_P256` 304,463 -> ~180,000 bytes with both on.
*/
ecReductionSinking?: boolean;

/**
* EXPERIMENTAL. Operand scheduling strategy for the ANF -> Stack pass.
*
Expand Down Expand Up @@ -500,6 +511,7 @@ export function compile(source: string, options?: CompileOptions): CompileResult
onProgress?.('Stack lowering', 60);
const stackProgram = lowerToStack(optimizedAnf, {
ecConstantPool: opts.ecConstantPool === true,
ecReductionSinking: opts.ecReductionSinking === true,
schedulerMode: opts.schedulerMode,
});

Expand Down Expand Up @@ -592,6 +604,8 @@ export interface CompileFromANFOptions {
disablePeephole?: boolean;
/** EXPERIMENTAL. Pool repeated EC curve constants. See CompileOptions. */
ecConstantPool?: boolean;
/** EXPERIMENTAL. Sink EC modular reductions. See CompileOptions. */
ecReductionSinking?: boolean;
/** EXPERIMENTAL. Operand scheduling strategy. See CompileOptions. */
schedulerMode?: 'current' | 'liveness';
}
Expand Down Expand Up @@ -665,6 +679,7 @@ export function compileFromANF(

const stackProgram = lowerToStack(optimizedAnf, {
ecConstantPool: opts.ecConstantPool === true,
ecReductionSinking: opts.ecReductionSinking === true,
schedulerMode: opts.schedulerMode,
});
if (!opts.disablePeephole) {
Expand Down
13 changes: 12 additions & 1 deletion packages/runar-compiler/src/passes/05-stack-lower.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,13 @@ export interface LoweringOptions {
*/
ecConstantPool?: boolean;

/**
* Drop the sign fix-up from EC modular reductions wherever a sign lattice
* proves the dividend non-negative. Only pays alongside `ecConstantPool`;
* the codegen compares emitted bytes before choosing the cheap subtraction.
*/
ecReductionSinking?: boolean;

/**
* Operand scheduling strategy.
*
Expand Down Expand Up @@ -1284,7 +1291,11 @@ class LoweringContext {
* identical to the shipping ones.
*/
private ecCodegenOptions(): EcCodegenOptions | undefined {
return this.opts.ecConstantPool ? { constantPool: true } : undefined;
if (!this.opts.ecConstantPool && !this.opts.ecReductionSinking) return undefined;
return {
constantPool: this.opts.ecConstantPool === true,
reductionSinking: this.opts.ecReductionSinking === true,
};
}

bringToTop(name: string, consume: boolean): void {
Expand Down
Loading
Loading