From 302ca4416c9ebc23e230381917867f5040eb9297 Mon Sep 17 00:00:00 2001 From: Ajani Bilby <11359344+AjaniBilby@users.noreply.github.com> Date: Sat, 16 Mar 2024 17:14:13 +1100 Subject: [PATCH] streamlined global reg allocation --- source/compiler/codegen/context.ts | 4 ++-- source/compiler/codegen/expression/container.ts | 2 +- source/compiler/codegen/expression/helper.ts | 8 ++++---- source/compiler/codegen/expression/postfix.ts | 2 +- source/compiler/codegen/expression/type.ts | 12 ++++++++---- source/compiler/codegen/scope.ts | 4 ++-- source/compiler/project.ts | 3 +-- source/wasm/funcRef.ts | 1 - source/wasm/section/global.ts | 13 ++++++------- 9 files changed, 25 insertions(+), 24 deletions(-) diff --git a/source/compiler/codegen/context.ts b/source/compiler/codegen/context.ts index 1fe7f75..1f3ba87 100644 --- a/source/compiler/codegen/context.ts +++ b/source/compiler/codegen/context.ts @@ -215,8 +215,8 @@ function CompileAssign(ctx: Context, syntax: Syntax.Term_Assign) { if (target.type instanceof IntrinsicValue) { switch (target.base.locality) { - case BasePointerType.global: ctx.block.push(Instruction.global.get(target.base)); break; - case BasePointerType.local: ctx.block.push(Instruction.local.get(target.base)); break; + case BasePointerType.global: ctx.block.push(Instruction.global.get(target.base.ref)); break; + case BasePointerType.local: ctx.block.push(Instruction.local.get(target.base.ref)); break; default: AssertUnreachable(target.base.locality); } } diff --git a/source/compiler/codegen/expression/container.ts b/source/compiler/codegen/expression/container.ts index c18a6cc..16358c4 100644 --- a/source/compiler/codegen/expression/container.ts +++ b/source/compiler/codegen/expression/container.ts @@ -56,7 +56,7 @@ export function StructBuilder(ctx: Context, syntax: Syntax.Term_Container, expec }); seen.push(name); - ctx.block.push(Instruction.global.get(ctx.file.owner.project.stackBase)); + ctx.block.push(Instruction.global.get(ctx.file.owner.project.stackBase.ref)); const expr = CompileExpr(ctx, elm.value[1], attr.type); if (expr instanceof IntrinsicValue) { Store(ctx, expr.type, new LatentOffset(alloc.getOffset(), attr.offset) ); diff --git a/source/compiler/codegen/expression/helper.ts b/source/compiler/codegen/expression/helper.ts index 162e2ec..bf48525 100644 --- a/source/compiler/codegen/expression/helper.ts +++ b/source/compiler/codegen/expression/helper.ts @@ -28,8 +28,8 @@ export function Load(ctx: Context, type: SolidType, base: BasePointer, offset: n if (!(type instanceof IntrinsicType)) Panic("Unimplemented"); switch (base.locality) { - case BasePointerType.global: ctx.block.push(Instruction.global.get(base)); break; - case BasePointerType.local: ctx.block.push(Instruction.local.get(base)); break; + case BasePointerType.global: ctx.block.push(Instruction.global.get(base.ref)); break; + case BasePointerType.local: ctx.block.push(Instruction.local.get(base.ref)); break; default: AssertUnreachable(base.locality); } @@ -64,8 +64,8 @@ export function ResolveLinearType(ctx: Context, type: LinearType, ref: Reference Load(ctx, base.type, ctx.file.owner.project.stackBase, type.offset); } else { switch (type.base.locality) { - case BasePointerType.global: ctx.block.push(Instruction.global.get(type.base)); break; - case BasePointerType.local: ctx.block.push(Instruction.local.get(type.base)); break; + case BasePointerType.global: ctx.block.push(Instruction.global.get(type.base.ref)); break; + case BasePointerType.local: ctx.block.push(Instruction.local.get(type.base.ref)); break; default: AssertUnreachable(type.base.locality); } diff --git a/source/compiler/codegen/expression/postfix.ts b/source/compiler/codegen/expression/postfix.ts index 148e4a3..6482528 100644 --- a/source/compiler/codegen/expression/postfix.ts +++ b/source/compiler/codegen/expression/postfix.ts @@ -59,7 +59,7 @@ function CompileCall(ctx: Context, syntax: Syntax.Term_Expr_call, operand: Opera const alloc = ctx.scope.stack.allocate(primary.size, primary.align); returnType = LinearType.make(primary, alloc, ctx.file.owner.project.stackBase); - ctx.block.push(Instruction.global.get(ctx.file.owner.project.stackReg.idx)) + ctx.block.push(Instruction.global.get(ctx.file.owner.project.stackReg.ref)) ctx.block.push(Instruction.const.i32(alloc.getOffset())); } } else Panic( diff --git a/source/compiler/codegen/expression/type.ts b/source/compiler/codegen/expression/type.ts index 9038f81..5c5e3bf 100644 --- a/source/compiler/codegen/expression/type.ts +++ b/source/compiler/codegen/expression/type.ts @@ -6,7 +6,6 @@ import { StackAllocation } from "~/compiler/codegen/allocation/stack.ts"; import { ReferenceRange } from "~/parser.ts"; import { IsNamespace } from "~/compiler/file.ts"; import { Namespace } from "~/compiler/file.ts"; -import { Intrinsic } from "~/wasm/type.ts"; import { LocalRef } from "~/wasm/funcRef.ts"; @@ -41,12 +40,17 @@ export function IsContainerType(a: any): boolean { export enum BasePointerType { global, local }; -export class BasePointer extends LocalRef { +export class BasePointer { locality: BasePointerType; + ref: LocalRef; - constructor(type: Intrinsic, locality: BasePointerType) { - super(type); + constructor(locality: BasePointerType, ref: LocalRef) { this.locality = locality; + this.ref = ref; + } + + get () { + return this.ref.get(); } } diff --git a/source/compiler/codegen/scope.ts b/source/compiler/codegen/scope.ts index a88fc38..122eec7 100644 --- a/source/compiler/codegen/scope.ts +++ b/source/compiler/codegen/scope.ts @@ -7,6 +7,7 @@ import { RegisterAllocator } from "~/compiler/codegen/allocation/registers.ts"; import { StackAllocator } from "~/compiler/codegen/allocation/stack.ts"; import { ReferenceRange } from "~/parser.ts"; import { Function } from "~/wasm/function.ts"; +import { BasePointerType } from "~/compiler/codegen/expression/type.ts"; export class Scope { _parent: Scope | null; @@ -44,8 +45,7 @@ export class Scope { } else if (type instanceof Structure) { const reg = this.register.allocate(type.getBitcode(), true); - // TODO(@ajanibilby): fix immediately, don't bypass the reg allocator like this - const linear = LinearType.make(type, null, new BasePointer(type.getBitcode(), this._localRegs)); + const linear = LinearType.make(type, null, new BasePointer(BasePointerType.local, reg.ref)); this.vars[name] = new StructVariable(name, linear); this.vars[name].markDefined(); } else AssertUnreachable(type); diff --git a/source/compiler/project.ts b/source/compiler/project.ts index bedd600..3656120 100644 --- a/source/compiler/project.ts +++ b/source/compiler/project.ts @@ -24,8 +24,7 @@ export default class Project { true, Instruction.const.i32(0) ); - this.stackBase = new BasePointer(Intrinsic.i32, BasePointerType.global); - this.stackBase.resolve(this.stackReg.idx); + this.stackBase = new BasePointer(BasePointerType.global, this.stackReg.ref); this.module.addMemory(0, 1); } diff --git a/source/wasm/funcRef.ts b/source/wasm/funcRef.ts index 2e270e7..e107684 100644 --- a/source/wasm/funcRef.ts +++ b/source/wasm/funcRef.ts @@ -1,5 +1,4 @@ import { LatentValue, type Byte } from "~/helper.ts"; - import { EncodeU32, Intrinsic } from "~/wasm/type.ts"; export class FuncRef extends LatentValue { diff --git a/source/wasm/section/global.ts b/source/wasm/section/global.ts index 26fd3b6..0fb8165 100644 --- a/source/wasm/section/global.ts +++ b/source/wasm/section/global.ts @@ -1,25 +1,23 @@ import { Intrinsic } from "~/wasm/type.ts"; import { EncodeU32 } from "~/wasm/type.ts"; import { Constant } from "~/wasm/instruction/constant.ts"; +import { LocalRef } from "~/wasm/funcRef.ts"; import { Byte } from "~/helper.ts"; - export class GlobalRegister { - idx: number; - type: Intrinsic; mutable: boolean; expr: Constant; + ref: LocalRef; constructor(type: Intrinsic, mutable: boolean, expr: Constant, index: number) { - this.type = type; - this.idx = index; + this.ref = new LocalRef(type); this.mutable = mutable; this.expr = expr; } toBinary(): Byte[] { return [ - this.type, + this.ref.type, this.mutable ? 0x01 : 0x00, ...this.expr.toBinary(), @@ -41,8 +39,9 @@ export default class GlobalSection { const idx = this.bindings.length; const n = new GlobalRegister(type, mut, expr, idx); - this.bindings.push(n); + n.ref.resolve(idx); + this.bindings.push(n); return n; }