From 5bbe7e13f7f1a2823ead0b63e6e49b953f8aa444 Mon Sep 17 00:00:00 2001 From: hufeng Date: Tue, 25 Oct 2022 14:48:11 +0800 Subject: [PATCH 1/4] Fix not restoring before CFG Signed-off-by: hufeng Change-Id: I45f2e5249176b924a123b377deb6415e2d0bd233 --- ts2panda/src/assemblyDumper.ts | 3 +- ts2panda/src/regAllocator.ts | 177 ++++++++++++---------------- ts2panda/tests/regAllocator.test.ts | 163 +++++++++++++++++++------ 3 files changed, 202 insertions(+), 141 deletions(-) diff --git a/ts2panda/src/assemblyDumper.ts b/ts2panda/src/assemblyDumper.ts index a11bc0b750..6b2fc9d793 100644 --- a/ts2panda/src/assemblyDumper.ts +++ b/ts2panda/src/assemblyDumper.ts @@ -82,7 +82,8 @@ export class AssemblyDumper { for (let i = 0; i < parametersCount; ++i) { let node = irNodes[i]; this.output += "\t"; - this.output += node.getMnemonic() + " v" + (node.operands[0]).num + ", a" + ((node.operands[0]).num) + "\n"; + let paramIdx = parametersCount - i - 1; + this.output += node.getMnemonic() + " v" + (node.operands[0]).num + ", a" + paramIdx + "\n"; } for (let i = parametersCount; i < irNodes.length; ++i) { diff --git a/ts2panda/src/regAllocator.ts b/ts2panda/src/regAllocator.ts index 9d5ac4f11f..790745246c 100644 --- a/ts2panda/src/regAllocator.ts +++ b/ts2panda/src/regAllocator.ts @@ -16,7 +16,7 @@ import { getRangeStartVregPos, isRangeInst } from "./base/util"; -import { CacheList } from "./base/vregisterCache"; +import { CacheList, VregisterCache } from "./base/vregisterCache"; import { DebugInfo } from "./debuginfo"; import { Format, @@ -28,21 +28,14 @@ import { } from "./irnodes"; import { PandaGen } from "./pandagen"; -const MAX_VREGA = 16; -const MAX_VREGB = 256; const MAX_VREGC = 65536; -interface VRegWithFlag { - vreg: VReg; - flag: boolean; // indicate whether it is used as a temporary register for spill -} - class RegAllocator { private newInsns: IRNode[] = []; private spills: VReg[] = []; + private spillId: number = 0; private vRegsId: number = 0; - private usedVreg: VRegWithFlag[] = []; - private tmpVreg: VRegWithFlag[] = []; + private needAdjust: boolean = false; constructor() { this.vRegsId = 0; @@ -51,42 +44,14 @@ class RegAllocator { allocIndexForVreg(vreg: VReg) { let num = this.getFreeVreg(); vreg.num = num; - this.usedVreg[num] = {vreg: vreg, flag: false}; } - findTmpVreg(level: number): VReg { - let iterCnts = Math.min(MAX_VREGB, this.usedVreg.length); - for (let i = 0; i < iterCnts; ++i) { - let value = this.usedVreg[i]; - if (value === undefined || value.flag) { - continue; - } - if (level === MAX_VREGA && value.vreg.num >= MAX_VREGA) { - throw new Error("no available tmp vReg from A"); - } - value.flag = true; - this.tmpVreg.push(value); - return value.vreg; - } - throw new Error("no available tmp vReg from B"); + getSpill(): VReg { + return this.spills[this.spillId++]; } - clearVregFlags(): void { - for (let v of this.tmpVreg) { - v.flag = false; - } - this.tmpVreg = []; - } - allocSpill(): VReg { - if (this.spills.length > 0) { - return this.spills.pop()!; - } - let v = new VReg(); - this.allocIndexForVreg(v); - return v; - } - freeSpill(v: VReg): void { - this.spills.push(v); + freeSpill(): void { + this.spillId = 0; } getFreeVreg(): number { @@ -112,48 +77,26 @@ class RegAllocator { return num; } - markVregNotAvailableAsTmp(vreg: VReg): void { - let num = vreg.num; - this.usedVreg[num].flag = true; - this.tmpVreg.push(this.usedVreg[num]); - } - doRealAdjustment(operands: OperandType[], format: Format, index: number, irNodes: IRNode[]) { let head: IRNode[] = []; let tail: IRNode[] = []; - let spills: VReg[] = []; - // mark all vreg used in the current insn as not valid for tmp register - for (let i = 0; i < operands.length; ++i) { - if (operands[i] instanceof VReg) { - this.markVregNotAvailableAsTmp(operands[i]); - } - } for (let j = 0; j < operands.length; ++j) { if (operands[j] instanceof VReg) { let vOrigin = operands[j]; if (vOrigin.num >= (1 << format[j][1])) { - let spill = this.allocSpill(); - spills.push(spill); - let vTmp; - try { - vTmp = this.findTmpVreg(1 << format[j][1]); - } catch { - throw Error("no available tmp vReg"); - } - head.push(new Mov(spill, vTmp)); - operands[j] = vTmp; + let spill = this.getSpill(); + operands[j] = spill; if (format[j][0] == OperandKind.SrcVReg) { - head.push(new Mov(vTmp, vOrigin)); + head.push(new Mov(spill, vOrigin)); } else if (format[j][0] == OperandKind.DstVReg) { - tail.push(new Mov(vOrigin, vTmp)) + tail.push(new Mov(vOrigin, spill)) } else if (format[j][0] == OperandKind.SrcDstVReg) { - head.push(new Mov(vTmp, vOrigin)); - tail.push(new Mov(vOrigin, vTmp)) + head.push(new Mov(spill, vOrigin)); + tail.push(new Mov(vOrigin, spill)) } else { // here we do nothing } - tail.push(new Mov(vTmp, spill)); } } } @@ -163,11 +106,7 @@ class RegAllocator { DebugInfo.copyDebugInfo(irNodes[index], tail); this.newInsns.push(...head, irNodes[index], ...tail); - - for (let j = spills.length - 1; j >= 0; --j) { - this.freeSpill(spills[j]); - } - this.clearVregFlags(); + this.freeSpill(); } checkDynRangeInstruction(irNodes: IRNode[], index: number): boolean { @@ -179,8 +118,6 @@ class RegAllocator { 1. "CalliDynRange 4, v255" is a valid insn, there is no need for all 4 registers numbers to be less than 255, it is also similar for NewobjDyn 2. we do not need to mark any register to be invalid for tmp register, since no other register is used in calli.dyn.range - 3. if v.num is bigger than 255, it means all register less than 255 has been already used, they should have been pushed - into usedVreg */ if ((operands[rangeRegOffset]).num >= level) { // needs to be adjusted. @@ -208,37 +145,23 @@ class RegAllocator { adjustDynRangeInstruction(irNodes: IRNode[], index: number) { let head: IRNode[] = []; - let tail: IRNode[] = []; - let spills: VReg[] = []; let operands = irNodes[index].operands; /* exclude operands that are not require consecutive */ let rangeRegOffset = getRangeStartVregPos(irNodes[index]); let regNums = operands.length - getRangeStartVregPos(irNodes[index]); - let level = 1 << (irNodes[index].getFormats())[0][rangeRegOffset][1]; - let tmp = this.findTmpVreg(level); - for (let i = 0; i < regNums; i++) { - let spill = this.allocSpill(); - spills.push(spill); - - /* We need to make sure that the register input in the .range instruction is continuous(small to big). */ - head.push(new Mov(spill, this.usedVreg[tmp.num + i].vreg)); - head.push(new Mov(this.usedVreg[tmp.num + i].vreg, operands[i + rangeRegOffset])); - operands[i + rangeRegOffset] = this.usedVreg[tmp.num + i].vreg; - tail.push(new Mov(this.usedVreg[tmp.num + i].vreg, spill)); + let spill = this.getSpill(); + head.push(new Mov(spill, operands[i + rangeRegOffset])); + operands[i + rangeRegOffset] = spill; } // for debuginfo DebugInfo.copyDebugInfo(irNodes[index], head); - DebugInfo.copyDebugInfo(irNodes[index], tail); - this.newInsns.push(...head, irNodes[index], ...tail); - for (let i = spills.length - 1; i >= 0; --i) { - this.freeSpill(spills[i]); - } - this.clearVregFlags(); + this.newInsns.push(...head, irNodes[index]); + this.freeSpill(); } adjustInstructionsIfNeeded(irNodes: IRNode[]): void { @@ -275,13 +198,7 @@ class RegAllocator { return this.vRegsId; } - run(pandaGen: PandaGen): void { - let irNodes = pandaGen.getInsns(); - let locals = pandaGen.getLocals(); - let temps = pandaGen.getTemps(); - let cache = pandaGen.getVregisterCache(); - let parametersCount = pandaGen.getParametersCount(); - // don't mess up allocation order + allocIndexForVregs(locals: VReg[], temps: VReg[], cache: VregisterCache): void { for (let i = 0; i < locals.length; ++i) { this.allocIndexForVreg(locals[i]); } @@ -294,6 +211,60 @@ class RegAllocator { this.allocIndexForVreg(cacheItem.getCache()); } } + } + + allocSpillPool(irNodes: IRNode[]): void { + let spillCount: number = 0; + for (let i = 0; i < irNodes.length; ++i) { + let operands = irNodes[i].operands; + let formats = irNodes[i].getFormats(); + if (isRangeInst(irNodes[i])) { + let rangeRegOffset = getRangeStartVregPos(irNodes[i]); + spillCount = Math.max(spillCount, operands.length - rangeRegOffset); + + let level = 1 << (irNodes[i].getFormats())[0][rangeRegOffset][1]; + if ((operands[rangeRegOffset]).num >= level) { + this.needAdjust = true; + } + continue; + } + + let min = operands.length; + spillCount = Math.max(spillCount, min); + for (let j = 0; j < formats.length; ++j) { + let num = this.getNumOfInvalidVregs(operands, formats[j]); + if (num < min) { + min = num; + } + } + if (min > 0) { + this.needAdjust = true; + } + } + + if (this.needAdjust) { + this.vRegsId = 0; + while (spillCount--) { + let spill = new VReg(); + this.allocIndexForVreg(spill); + this.spills.push(spill); + } + } + } + + run(pandaGen: PandaGen): void { + let irNodes = pandaGen.getInsns(); + let locals = pandaGen.getLocals(); + let temps = pandaGen.getTemps(); + let cache = pandaGen.getVregisterCache(); + let parametersCount = pandaGen.getParametersCount(); + + this.allocIndexForVregs(locals, temps, cache); + this.allocSpillPool(irNodes); + if (this.needAdjust) { + // assign index to Vregs again + this.allocIndexForVregs(locals, temps, cache); + } this.adjustInstructionsIfNeeded(irNodes); for (let i = 0; i < parametersCount; ++i) { let v = new VReg(); diff --git a/ts2panda/tests/regAllocator.test.ts b/ts2panda/tests/regAllocator.test.ts index b20940b14b..185ebd3594 100644 --- a/ts2panda/tests/regAllocator.test.ts +++ b/ts2panda/tests/regAllocator.test.ts @@ -19,19 +19,22 @@ import * as ts from "typescript"; import { Callrange, Returnundefined, - Sttoglobalrecord, - Tryldglobalbyname, Imm, IRNode, + Jmp, + Label, Ldai, Lda, + Ldglobalvar, + Mov, Sta, + Throw, VReg } from "../src/irnodes"; import { PandaGen } from "../src/pandagen"; import { CacheExpander } from "../src/pass/cacheExpander"; import { RegAlloc } from "../src/regAllocator"; -import { basicChecker, checkInstructions, compileAllSnippet } from "./utils/base"; +import { basicChecker, checkInstructions, compileAllSnippet, SnippetCompiler } from "./utils/base"; import { creatAstFromSnippet } from "./utils/asthelper"; function checkRegisterNumber(left: IRNode, right: IRNode): boolean { @@ -55,32 +58,46 @@ function checkRegisterNumber(left: IRNode, right: IRNode): boolean { return true; } describe("RegAllocator", function () { - it("make spill for Src register", function () { - let string: string = ""; + it("make spill for Dst register & Src register", function () { + let string = "function test() {"; for (let i = 0; i < 256; ++i) { string += "let a" + i + " = " + i + ";"; } - string += "a255;"; + string += "a255;}"; + + let snippetCompiler = new SnippetCompiler(); + snippetCompiler.compile(string, [new CacheExpander(), new RegAlloc()]); + let insns = snippetCompiler.getPandaGenByName("UnitTest.test").getInsns(); - let pgs = compileAllSnippet(string, [new CacheExpander(), new RegAlloc()]); - let insns = pgs[0].getInsns(); IRNode.pg = new PandaGen("", creatAstFromSnippet(""), 0, undefined); - IRNode.pg.updateIcSize(252); + IRNode.pg.updateIcSize(0); + + let v = []; + for (let i = 0; i < 260; ++i) { + v[i] = new VReg(); + v[i].num = i; + } let expected: IRNode[] = [ new Ldai(new Imm(252)), - new Sttoglobalrecord(new Imm(0), 'a252'), + new Sta(v[0]), + new Mov(v[256], v[0]), new Ldai(new Imm(253)), - new Sttoglobalrecord(new Imm(1), 'a253'), + new Sta(v[0]), + new Mov(v[257], v[0]), new Ldai(new Imm(254)), - new Sttoglobalrecord(new Imm(2), 'a254'), + new Sta(v[0]), + new Mov(v[258], v[0]), new Ldai(new Imm(255)), - new Sttoglobalrecord(new Imm(3), 'a255'), - new Tryldglobalbyname(new Imm(4), 'a255'), + new Sta(v[0]), + new Mov(v[259], v[0]), + // load a255 + new Mov(v[0], v[259]), + new Lda(v[0]), new Returnundefined() ] - expect(checkInstructions(insns.slice(insns.length - 10), expected, checkRegisterNumber)).to.be.true; + expect(checkInstructions(insns.slice(insns.length - 15), expected, checkRegisterNumber)).to.be.true; }); it("make spill for SrcDst register", function () { @@ -95,41 +112,113 @@ describe("RegAllocator", function () { but in case later 16 might be changed to 8, then spill operation will be needed in some cases. this testcase is designed for 8bits constraints. */ - let string = ""; + let string = "function test() {"; for (let i = 0; i < 256; ++i) { string += "let a" + i + " = " + i + ";"; } - string += "call(a252, a253, a254, a255);"; - let pgs = compileAllSnippet(string, [new CacheExpander(), new RegAlloc()]); - let insns = pgs[0].getInsns(); + string += "test(a252, a253, a254, a255);}"; + + let snippetCompiler = new SnippetCompiler(); + snippetCompiler.compile(string, [new CacheExpander(), new RegAlloc()]); + let insns = snippetCompiler.getPandaGenByName("UnitTest.test").getInsns(); + IRNode.pg = new PandaGen("", creatAstFromSnippet(""), 0, undefined); - IRNode.pg.updateIcSize(252); + IRNode.pg.updateIcSize(0); let v = []; - for (let i = 0; i < 8; ++i) { + for (let i = 0; i < 268; ++i) { v[i] = new VReg(); v[i].num = i; } let expected = [ new Ldai(new Imm(252)), - new Sttoglobalrecord(new Imm(252), 'a252'), + new Sta(v[0]), + new Mov(v[259], v[0]), + new Ldai(new Imm(253)), + new Sta(v[0]), + new Mov(v[260], v[0]), + new Ldai(new Imm(254)), + new Sta(v[0]), + new Mov(v[261], v[0]), + new Ldai(new Imm(255)), + new Sta(v[0]), + new Mov(v[262], v[0]), + new Ldglobalvar(new Imm(0), "test"), + new Sta(v[0]), + new Mov(v[263], v[0]), + // call test with [a252, a253, a254, a255] + new Mov(v[0], v[259]), + new Lda(v[0]), + new Sta(v[0]), + new Mov(v[264], v[0]), + new Mov(v[0], v[260]), + new Lda(v[0]), + new Sta(v[0]), + new Mov(v[265], v[0]), + new Mov(v[0], v[261]), + new Lda(v[0]), + new Sta(v[0]), + new Mov(v[266], v[0]), + new Mov(v[0], v[262]), + new Lda(v[0]), + new Sta(v[0]), + new Mov(v[267], v[0]), + new Mov(v[0], v[263]), + new Lda(v[0]), + new Mov(v[0], v[264]), + new Mov(v[1], v[265]), + new Mov(v[2], v[266]), + new Mov(v[3], v[267]), + new Callrange(new Imm(1), new Imm(4), [v[0], v[1], v[2], v[3]]), + new Returnundefined(), + ]; + + expect(checkInstructions(insns.slice(insns.length - 39), expected, checkRegisterNumber)).to.be.true; + }); + + it("make spill for control-flow change", function () { + let string = "function test() {"; + for (let i = 0; i < 256; ++i) { + string += "let a" + i + " = " + i + ";"; + } + string += `try { throw a0; } catch { a0 }};`; + + let snippetCompiler = new SnippetCompiler(); + snippetCompiler.compile(string, [new CacheExpander(), new RegAlloc()]); + let insns = snippetCompiler.getPandaGenByName("UnitTest.test").getInsns(); + + IRNode.pg = new PandaGen("", creatAstFromSnippet(""), 0, undefined); + IRNode.pg.updateIcSize(0); + let v = []; + for (let i = 0; i < 261; ++i) { + v[i] = new VReg(); + v[i].num = i; + } + let tryBeginLabel = new Label(); + let tryEndLabel = new Label(); + let catchBeginLabel = new Label(); + let catchEndLabel = new Label(); + + let expected = [ + new Ldai(new Imm(252)), + new Sta(v[0]), + new Mov(v[256], v[0]), new Ldai(new Imm(253)), - new Sttoglobalrecord(new Imm(253), 'a253'), + new Sta(v[0]), + new Mov(v[257], v[0]), new Ldai(new Imm(254)), - new Sttoglobalrecord(new Imm(254), 'a254'), + new Sta(v[0]), + new Mov(v[258], v[0]), new Ldai(new Imm(255)), - new Sttoglobalrecord(new Imm(256), 'a255'), - new Tryldglobalbyname(new Imm(257), 'call'), - new Sta(v[3]), - new Tryldglobalbyname(new Imm(258), 'a252'), - new Sta(v[4]), - new Tryldglobalbyname(new Imm(259), 'a253'), - new Sta(v[5]), - new Tryldglobalbyname(new Imm(260), 'a254'), - new Sta(v[6]), - new Tryldglobalbyname(new Imm(261), 'a255'), - new Sta(v[7]), - new Lda(v[3]), - new Callrange(new Imm(255), new Imm(4), [v[4], v[5], v[6], v[7]]), + new Sta(v[0]), + new Mov(v[259], v[0]), + tryBeginLabel, + new Lda(v[4]), + new Throw(), + tryEndLabel, + new Jmp(catchEndLabel), + catchBeginLabel, + new Lda(v[4]), + catchEndLabel, new Returnundefined(), ]; -- Gitee From dd5557f756d115b950e411695a8f6b0e3f1ce0b1 Mon Sep 17 00:00:00 2001 From: hufeng Date: Tue, 1 Nov 2022 21:25:32 +0800 Subject: [PATCH 2/4] Fix no restoring before CFG on ES2ABC Signed-off-by: hufeng Change-Id: Ia668f7977628c6b6689506b468cff6a7764fbd5e --- es2panda/compiler/core/function.cpp | 1 + es2panda/compiler/core/pandagen.cpp | 198 ++++++------- es2panda/compiler/core/pandagen.h | 18 +- es2panda/compiler/core/regAllocator.cpp | 215 +++++++------- es2panda/compiler/core/regAllocator.h | 152 ++++------ es2panda/compiler/templates/isa.h.erb | 40 ++- es2panda/ir/irnode.h | 10 + .../test-spill-fill-with-CFG-expected.txt | 1 + .../regAllocator/test-spill-fill-with-CFG.js | 274 ++++++++++++++++++ 9 files changed, 608 insertions(+), 301 deletions(-) create mode 100644 es2panda/test/compiler/js/regAllocator/test-spill-fill-with-CFG-expected.txt create mode 100644 es2panda/test/compiler/js/regAllocator/test-spill-fill-with-CFG.js diff --git a/es2panda/compiler/core/function.cpp b/es2panda/compiler/core/function.cpp index 5fb0ba8c80..1325518b13 100644 --- a/es2panda/compiler/core/function.cpp +++ b/es2panda/compiler/core/function.cpp @@ -199,6 +199,7 @@ static void CompileFunctionOrProgram(PandaGen *pg) void Function::Compile(PandaGen *pg) { CompileFunctionOrProgram(pg); + pg->AdjustSpillInsns(); pg->SetFunctionKind(); pg->SetSourceLocationFlag(lexer::SourceLocationFlag::INVALID_SOURCE_LOCATION); pg->CopyFunctionArguments(pg->RootNode()); diff --git a/es2panda/compiler/core/pandagen.cpp b/es2panda/compiler/core/pandagen.cpp index ed81f39bda..a7c61bf5f4 100644 --- a/es2panda/compiler/core/pandagen.cpp +++ b/es2panda/compiler/core/pandagen.cpp @@ -91,7 +91,7 @@ void PandaGen::SetFunctionKind() Label *PandaGen::AllocLabel() { std::string id = std::string {Label::PREFIX} + std::to_string(labelId_++); - return sa_.AllocLabel(std::move(id)); + return ra_.AllocLabel(std::move(id)); } bool PandaGen::IsDebug() const @@ -210,6 +210,8 @@ void PandaGen::InitializeLexEnv(const ir::AstNode *node) void PandaGen::CopyFunctionArguments(const ir::AstNode *node) { FrontAllocator fa(this); + auto spillRegsCount = ra_.GetSpillRegsCount(); + totalRegs_ += spillRegsCount; VReg targetReg = totalRegs_; for (const auto *param : topScope_->ParamScope()->Params()) { @@ -221,11 +223,11 @@ void PandaGen::CopyFunctionArguments(const ir::AstNode *node) auto typeIndex = context_->TypeRecorder()->GetVariableTypeIndex(param); if (typeIndex != extractor::TypeRecorder::PRIMITIVETYPE_ANY) { // Simply encode type index for params - MoveVregWithType(node, -(typeIndex + 1), param->Vreg(), targetReg++); + MoveVregWithType(node, -(typeIndex + 1), param->Vreg() + spillRegsCount, targetReg++); continue; } } - MoveVreg(node, param->Vreg(), targetReg++); + MoveVreg(node, param->Vreg() + spillRegsCount, targetReg++); } } @@ -462,9 +464,9 @@ void PandaGen::TryLoadGlobalByName(const ir::AstNode *node, const util::StringVi } else { int64_t typeIndex = extractor::TypeExtractor::GetBuiltinTypeIndex(name); if (context_->IsTypeExtractorEnabled() && typeIndex != extractor::TypeRecorder::PRIMITIVETYPE_ANY) { - sa_.EmitWithType(node, typeIndex, 0, name); + ra_.EmitWithType(node, typeIndex, 0, name); } else { - sa_.Emit(node, 0, name); + ra_.Emit(node, 0, name); } } strings_.insert(name); @@ -493,7 +495,7 @@ void PandaGen::TryStoreGlobalByName(const ir::AstNode *node, const util::StringV if (isDebuggerEvaluateExpressionMode()) { StoreObjByNameViaDebugger(node, name); } else { - sa_.Emit(node, 0, name); + ra_.Emit(node, 0, name); } strings_.insert(name); } @@ -501,7 +503,7 @@ void PandaGen::TryStoreGlobalByName(const ir::AstNode *node, const util::StringV void PandaGen::LoadObjByName(const ir::AstNode *node, VReg obj, const util::StringView &prop) { LoadAccumulator(node, obj); // object is load to acc - sa_.Emit(node, 0, prop); + ra_.Emit(node, 0, prop); strings_.insert(prop); } @@ -515,11 +517,11 @@ void PandaGen::LoadObjByIndex(const ir::AstNode *node, VReg obj, int64_t index) { LoadAccumulator(node, obj); // object is load to acc if (index <= util::Helpers::MAX_INT16) { - sa_.Emit(node, 0, index); + ra_.Emit(node, 0, index); return; } - sa_.Emit(node, index); + ra_.Emit(node, index); } void PandaGen::LoadObjByValue(const ir::AstNode *node, VReg obj) @@ -586,13 +588,13 @@ void PandaGen::LoadAccumulator(const ir::AstNode *node, VReg reg) void PandaGen::LoadGlobalVar(const ir::AstNode *node, const util::StringView &name) { - sa_.Emit(node, 0, name); + ra_.Emit(node, 0, name); strings_.insert(name); } void PandaGen::StoreGlobalVar(const ir::AstNode *node, const util::StringView &name) { - sa_.Emit(node, 0, name); + ra_.Emit(node, 0, name); strings_.insert(name); } @@ -608,28 +610,28 @@ void PandaGen::StoreAccToLexEnv(const ir::AstNode *node, const binder::ScopeFind void PandaGen::LoadAccumulatorString(const ir::AstNode *node, const util::StringView &str) { - sa_.Emit(node, str); + ra_.Emit(node, str); strings_.insert(str); } void PandaGen::LoadAccumulatorFloat(const ir::AstNode *node, double num) { - sa_.Emit(node, num); + ra_.Emit(node, num); } void PandaGen::LoadAccumulatorInt(const ir::AstNode *node, int32_t num) { - sa_.Emit(node, num); + ra_.Emit(node, num); } void PandaGen::LoadAccumulatorInt(const ir::AstNode *node, size_t num) { - sa_.Emit(node, static_cast(num)); + ra_.Emit(node, static_cast(num)); } void PandaGen::LoadAccumulatorBigInt(const ir::AstNode *node, const util::StringView &num) { - sa_.Emit(node, num); + ra_.Emit(node, num); strings_.insert(num); } @@ -643,39 +645,39 @@ void PandaGen::LoadConst(const ir::AstNode *node, Constant id) { switch (id) { case Constant::JS_HOLE: { - sa_.Emit(node); + ra_.Emit(node); break; } case Constant::JS_NAN: { - sa_.Emit(node); + ra_.Emit(node); break; } case Constant::JS_INFINITY: { - sa_.Emit(node); + ra_.Emit(node); break; } case Constant::JS_GLOBAL: { - sa_.Emit(node); + ra_.Emit(node); break; } case Constant::JS_UNDEFINED: { - sa_.Emit(node); + ra_.Emit(node); break; } case Constant::JS_SYMBOL: { - sa_.Emit(node); + ra_.Emit(node); break; } case Constant::JS_NULL: { - sa_.Emit(node); + ra_.Emit(node); break; } case Constant::JS_TRUE: { - sa_.Emit(node); + ra_.Emit(node); break; } case Constant::JS_FALSE: { - sa_.Emit(node); + ra_.Emit(node); break; } default: { @@ -696,12 +698,12 @@ void PandaGen::MoveVregWithType(const ir::AstNode *node, int64_t typeIndex, VReg void PandaGen::SetLabel([[maybe_unused]] const ir::AstNode *node, Label *label) { - sa_.AddLabel(label); + ra_.AddLabel(label); } void PandaGen::Branch(const ir::AstNode *node, Label *label) { - sa_.Emit(node, label); + ra_.Emit(node, label); } bool PandaGen::CheckControlFlowChange() const @@ -831,12 +833,12 @@ void PandaGen::Unary(const ir::AstNode *node, lexer::TokenType op, VReg operand) } case lexer::TokenType::PUNCTUATOR_MINUS: { LoadAccumulator(node, operand); - sa_.Emit(node, 0); + ra_.Emit(node, 0); break; } case lexer::TokenType::PUNCTUATOR_TILDE: { LoadAccumulator(node, operand); - sa_.Emit(node, 0); + ra_.Emit(node, 0); break; } case lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK: { @@ -845,12 +847,12 @@ void PandaGen::Unary(const ir::AstNode *node, lexer::TokenType op, VReg operand) } case lexer::TokenType::PUNCTUATOR_PLUS_PLUS: { LoadAccumulator(node, operand); - sa_.Emit(node, 0); + ra_.Emit(node, 0); break; } case lexer::TokenType::PUNCTUATOR_MINUS_MINUS: { LoadAccumulator(node, operand); - sa_.Emit(node, 0); + ra_.Emit(node, 0); break; } case lexer::TokenType::KEYW_VOID: @@ -1020,7 +1022,7 @@ void PandaGen::GreaterEqual(const ir::AstNode *node, VReg lhs) void PandaGen::IsTrue(const ir::AstNode *node) { - sa_.Emit(node); + ra_.Emit(node); } void PandaGen::BranchIfUndefined(const ir::AstNode *node, Label *target) @@ -1030,7 +1032,7 @@ void PandaGen::BranchIfUndefined(const ir::AstNode *node, Label *target) StoreAccumulator(node, tmp); LoadConst(node, Constant::JS_UNDEFINED); Equal(node, tmp); - sa_.Emit(node, target); + ra_.Emit(node, target); } void PandaGen::BranchIfNotUndefined(const ir::AstNode *node, Label *target) @@ -1040,7 +1042,7 @@ void PandaGen::BranchIfNotUndefined(const ir::AstNode *node, Label *target) StoreAccumulator(node, tmp); LoadConst(node, Constant::JS_UNDEFINED); Equal(node, tmp); - sa_.Emit(node, target); + ra_.Emit(node, target); } void PandaGen::BranchIfStrictNotUndefined(const ir::AstNode *node, class Label *target) @@ -1050,13 +1052,13 @@ void PandaGen::BranchIfStrictNotUndefined(const ir::AstNode *node, class Label * StoreAccumulator(node, tmp); LoadConst(node, Constant::JS_UNDEFINED); StrictEqual(node, tmp); - sa_.Emit(node, target); + ra_.Emit(node, target); } void PandaGen::BranchIfTrue(const ir::AstNode *node, Label *target) { IsTrue(node); - sa_.Emit(node, target); + ra_.Emit(node, target); } void PandaGen::BranchIfNotTrue(const ir::AstNode *node, Label *target) @@ -1067,8 +1069,8 @@ void PandaGen::BranchIfNotTrue(const ir::AstNode *node, Label *target) void PandaGen::BranchIfFalse(const ir::AstNode *node, Label *target) { - sa_.Emit(node); - sa_.Emit(node, target); + ra_.Emit(node); + ra_.Emit(node, target); } void PandaGen::BranchIfStrictNull(const ir::AstNode *node, class Label *target) @@ -1078,12 +1080,12 @@ void PandaGen::BranchIfStrictNull(const ir::AstNode *node, class Label *target) StoreAccumulator(node, tmp); LoadConst(node, Constant::JS_NULL); ra_.Emit(node, 0, tmp); - sa_.Emit(node, target); + ra_.Emit(node, target); } void PandaGen::EmitThrow(const ir::AstNode *node) { - sa_.Emit(node); + ra_.Emit(node); } void PandaGen::EmitRethrow(const ir::AstNode *node) @@ -1100,7 +1102,7 @@ void PandaGen::EmitRethrow(const ir::AstNode *node) LoadAccumulator(node, exception); NotEqual(node, hole); - sa_.Emit(node, skipThrow); + ra_.Emit(node, skipThrow); SetLabel(node, doThrow); LoadAccumulator(node, exception); @@ -1111,12 +1113,12 @@ void PandaGen::EmitRethrow(const ir::AstNode *node) void PandaGen::EmitReturn(const ir::AstNode *node) { - sa_.Emit(node); + ra_.Emit(node); } void PandaGen::EmitReturnUndefined(const ir::AstNode *node) { - sa_.Emit(node); + ra_.Emit(node); } void PandaGen::ImplicitReturn(const ir::AstNode *node) @@ -1190,11 +1192,11 @@ void PandaGen::CallThis(const ir::AstNode *node, VReg startReg, size_t argCount) default: { int64_t actualArgs = argCount - 1; if (actualArgs <= util::Helpers::MAX_INT8) { - rra_.Emit(node, thisReg, argCount, 0, actualArgs, thisReg); + ra_.EmitRange(node, argCount, 0, actualArgs, thisReg); break; } - rra_.Emit(node, thisReg, argCount, actualArgs, thisReg); + ra_.EmitRange(node, argCount, actualArgs, thisReg); break; } } @@ -1205,7 +1207,7 @@ void PandaGen::Call(const ir::AstNode *node, VReg startReg, size_t argCount) LoadAccumulator(node, startReg); // callee is load to acc switch (argCount) { case 0: { // 0 args - sa_.Emit(node, 0); + ra_.Emit(node, 0); break; } case 1: { // 1 arg @@ -1229,11 +1231,11 @@ void PandaGen::Call(const ir::AstNode *node, VReg startReg, size_t argCount) default: { VReg arg0 = startReg + 1; if (argCount <= util::Helpers::MAX_INT8) { - rra_.Emit(node, arg0, argCount, 0, argCount, arg0); + ra_.EmitRange(node, argCount, 0, argCount, arg0); break; } - rra_.Emit(node, arg0, argCount, argCount, arg0); + ra_.EmitRange(node, argCount, argCount, arg0); break; } } @@ -1244,20 +1246,20 @@ void PandaGen::SuperCall(const ir::AstNode *node, VReg startReg, size_t argCount if (RootNode()->AsScriptFunction()->IsArrow()) { GetFunctionObject(node); // load funcobj to acc for super call in arrow function if (argCount <= util::Helpers::MAX_INT8) { - rra_.Emit(node, startReg, argCount, 0, static_cast(argCount), startReg); + ra_.EmitRange(node, argCount, 0, static_cast(argCount), startReg); } else { - rra_.Emit(node, startReg, argCount, static_cast(argCount), startReg); + ra_.EmitRange(node, argCount, static_cast(argCount), startReg); } return; } if (argCount <= util::Helpers::MAX_INT8) { // no need to load funcobj to acc for super call in other kinds of functions - rra_.Emit(node, startReg, argCount, 0, static_cast(argCount), startReg); + ra_.EmitRange(node, argCount, 0, static_cast(argCount), startReg); return; } - rra_.Emit(node, startReg, argCount, static_cast(argCount), startReg); + ra_.EmitRange(node, argCount, static_cast(argCount), startReg); } void PandaGen::SuperCallSpread(const ir::AstNode *node, VReg vs) @@ -1268,11 +1270,11 @@ void PandaGen::SuperCallSpread(const ir::AstNode *node, VReg vs) void PandaGen::NewObject(const ir::AstNode *node, VReg startReg, size_t argCount) { if (argCount <= util::Helpers::MAX_INT8) { - rra_.Emit(node, startReg, argCount, 0, static_cast(argCount), startReg); + ra_.EmitRange(node, argCount, 0, static_cast(argCount), startReg); return; } - rra_.Emit(node, startReg, argCount, static_cast(argCount), startReg); + ra_.EmitRange(node, argCount, static_cast(argCount), startReg); } void PandaGen::DefineFunction(const ir::AstNode *node, const ir::ScriptFunction *realNode, const util::StringView &name) @@ -1293,7 +1295,7 @@ void PandaGen::DefineFunction(const ir::AstNode *node, const ir::ScriptFunction void PandaGen::TypeOf(const ir::AstNode *node) { - sa_.Emit(node, 0); + ra_.Emit(node, 0); } void PandaGen::CallSpread(const ir::AstNode *node, VReg func, VReg thisReg, VReg args) @@ -1309,7 +1311,7 @@ void PandaGen::NewObjSpread(const ir::AstNode *node, VReg obj) void PandaGen::GetUnmappedArgs(const ir::AstNode *node) { - sa_.Emit(node); + ra_.Emit(node); } void PandaGen::Negate(const ir::AstNode *node) @@ -1327,13 +1329,13 @@ void PandaGen::Negate(const ir::AstNode *node) void PandaGen::ToNumber(const ir::AstNode *node, VReg arg) { LoadAccumulator(node, arg); - sa_.Emit(node, 0); + ra_.Emit(node, 0); } void PandaGen::ToNumeric(const ir::AstNode *node, VReg arg) { LoadAccumulator(node, arg); - sa_.Emit(node, 0); + ra_.Emit(node, 0); } void PandaGen::CreateGeneratorObj(const ir::AstNode *node, VReg funcObj) @@ -1383,18 +1385,18 @@ void PandaGen::GeneratorComplete(const ir::AstNode *node, VReg genObj) void PandaGen::ResumeGenerator(const ir::AstNode *node, VReg genObj) { LoadAccumulator(node, genObj); - sa_.Emit(node); + ra_.Emit(node); } void PandaGen::GetResumeMode(const ir::AstNode *node, VReg genObj) { LoadAccumulator(node, genObj); - sa_.Emit(node); + ra_.Emit(node); } void PandaGen::AsyncFunctionEnter(const ir::AstNode *node) { - sa_.Emit(node); + ra_.Emit(node); } void PandaGen::AsyncFunctionAwait(const ir::AstNode *node, VReg asyncFuncObj) @@ -1425,17 +1427,17 @@ void PandaGen::AsyncGeneratorReject(const ir::AstNode *node, VReg asyncGenObj) void PandaGen::GetTemplateObject(const ir::AstNode *node, VReg value) { LoadAccumulator(node, value); - sa_.Emit(node, 0); + ra_.Emit(node, 0); } void PandaGen::CopyRestArgs(const ir::AstNode *node, uint32_t index) { - index <= util::Helpers::MAX_INT8 ? sa_.Emit(node, index) : sa_.Emit(node, index); + index <= util::Helpers::MAX_INT8 ? ra_.Emit(node, index) : ra_.Emit(node, index); } void PandaGen::GetPropIterator(const ir::AstNode *node) { - sa_.Emit(node); + ra_.Emit(node); } void PandaGen::GetNextPropName(const ir::AstNode *node, VReg iter) @@ -1445,7 +1447,7 @@ void PandaGen::GetNextPropName(const ir::AstNode *node, VReg iter) void PandaGen::CreateEmptyObject(const ir::AstNode *node) { - sa_.Emit(node); + ra_.Emit(node); } void PandaGen::CreateObjectWithBuffer(const ir::AstNode *node, uint32_t idx) @@ -1453,7 +1455,7 @@ void PandaGen::CreateObjectWithBuffer(const ir::AstNode *node, uint32_t idx) ASSERT(util::Helpers::IsInteger(idx)); std::string idxStr = std::string(context_->Binder()->Program()->RecordName()) + "_" + std::to_string(idx); util::UString litId(idxStr, allocator_); - sa_.Emit(node, 0, litId.View()); + ra_.Emit(node, 0, litId.View()); } void PandaGen::SetObjectWithProto(const ir::AstNode *node, VReg proto, VReg obj) @@ -1476,7 +1478,7 @@ void PandaGen::DefineGetterSetterByValue(const ir::AstNode *node, VReg obj, VReg void PandaGen::CreateEmptyArray(const ir::AstNode *node) { - sa_.Emit(node, 0); + ra_.Emit(node, 0); } void PandaGen::CreateArrayWithBuffer(const ir::AstNode *node, uint32_t idx) @@ -1484,7 +1486,7 @@ void PandaGen::CreateArrayWithBuffer(const ir::AstNode *node, uint32_t idx) ASSERT(util::Helpers::IsInteger(idx)); std::string idxStr = std::string(context_->Binder()->Program()->RecordName()) + "_" + std::to_string(idx); util::UString litId(idxStr, allocator_); - sa_.Emit(node, 0, litId.View()); + ra_.Emit(node, 0, litId.View()); } void PandaGen::CreateArray(const ir::AstNode *node, const ArenaVector &elements, VReg obj) @@ -1595,19 +1597,19 @@ void PandaGen::ThrowIfNotObject(const ir::AstNode *node, VReg obj) void PandaGen::ThrowThrowNotExist(const ir::AstNode *node) { - sa_.Emit(node); + ra_.Emit(node); } void PandaGen::GetIterator(const ir::AstNode *node) { - sa_.Emit(node, 0); + ra_.Emit(node, 0); } void PandaGen::GetAsyncIterator(const ir::AstNode *node) { /* * TODO: async iterator - * sa_.Emit(node); + * ra_.Emit(node); */ } @@ -1622,18 +1624,16 @@ void PandaGen::CreateObjectWithExcludedKeys(const ir::AstNode *node, VReg obj, V size_t argRegCnt = (argCount == 0 ? argCount : argCount - 1); if (argRegCnt <= util::Helpers::MAX_INT8) { - rra_.Emit(node, argStart, argCount, static_cast(argRegCnt), - obj, argStart); + ra_.EmitRange(node, argCount, static_cast(argRegCnt), obj, argStart); return; } - rra_.Emit(node, argStart, argCount, static_cast(argRegCnt), - obj, argStart); + ra_.EmitRange(node, argCount, static_cast(argRegCnt), obj, argStart); } void PandaGen::ThrowObjectNonCoercible(const ir::AstNode *node) { - sa_.Emit(node); + ra_.Emit(node); } void PandaGen::CloseIterator(const ir::AstNode *node, VReg iter) @@ -1653,28 +1653,28 @@ void PandaGen::DefineClassWithBuffer(const ir::AstNode *node, const util::String void PandaGen::LoadLocalModuleVariable(const ir::AstNode *node, const binder::ModuleVariable *variable) { auto index = variable->Index(); - index <= util::Helpers::MAX_INT8 ? sa_.Emit(node, index) : - sa_.Emit(node, index); + index <= util::Helpers::MAX_INT8 ? ra_.Emit(node, index) : + ra_.Emit(node, index); } void PandaGen::LoadExternalModuleVariable(const ir::AstNode *node, const binder::ModuleVariable *variable) { auto index = variable->Index(); - index <= util::Helpers::MAX_INT8 ? sa_.Emit(node, index) : - sa_.Emit(node, index); + index <= util::Helpers::MAX_INT8 ? ra_.Emit(node, index) : + ra_.Emit(node, index); } void PandaGen::StoreModuleVariable(const ir::AstNode *node, const binder::ModuleVariable *variable) { auto index = variable->Index(); - index <= util::Helpers::MAX_INT8 ? sa_.Emit(node, index) : - sa_.Emit(node, index); + index <= util::Helpers::MAX_INT8 ? ra_.Emit(node, index) : + ra_.Emit(node, index); } void PandaGen::GetModuleNamespace(const ir::AstNode *node, uint32_t index) { - index <= util::Helpers::MAX_INT8 ? sa_.Emit(node, index) : - sa_.Emit(node, index); + index <= util::Helpers::MAX_INT8 ? ra_.Emit(node, index) : + ra_.Emit(node, index); } void PandaGen::DynamicImportCall(const ir::AstNode *node) @@ -1691,7 +1691,7 @@ void PandaGen::StSuperByName(const ir::AstNode *node, VReg obj, const util::Stri void PandaGen::LdSuperByName(const ir::AstNode *node, VReg obj, const util::StringView &key) { LoadAccumulator(node, obj); // object is load to acc - sa_.Emit(node, 0, key); + ra_.Emit(node, 0, key); strings_.insert(key); } @@ -1751,27 +1751,27 @@ void PandaGen::LoadSuperProperty(const ir::AstNode *node, VReg obj, const Operan void PandaGen::LoadLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot) { if ((level > util::Helpers::MAX_INT8) || (slot > util::Helpers::MAX_INT8)) { - sa_.Emit(node, level, slot); + ra_.Emit(node, level, slot); return; } - sa_.Emit(node, level, slot); + ra_.Emit(node, level, slot); } void PandaGen::LoadLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot, const util::StringView &name) { if (context_->HotfixHelper() && context_->HotfixHelper()->IsPatchVar(slot)) { uint32_t patchSlot = context_->HotfixHelper()->GetPatchLexicalIdx(std::string(name)); - sa_.Emit(node, patchSlot); + ra_.Emit(node, patchSlot); return; } if ((level > util::Helpers::MAX_INT8) || (slot > util::Helpers::MAX_INT8)) { - sa_.Emit(node, level, slot); + ra_.Emit(node, level, slot); return; } - sa_.Emit(node, level, slot); + ra_.Emit(node, level, slot); } void PandaGen::StoreLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t slot) @@ -1799,7 +1799,7 @@ void PandaGen::StoreLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t { if (context_->HotfixHelper() && context_->HotfixHelper()->IsPatchVar(slot)) { uint32_t patchSlot = context_->HotfixHelper()->GetPatchLexicalIdx(std::string(name)); - sa_.Emit(node, patchSlot); + ra_.Emit(node, patchSlot); return; } RegScope rs(this); @@ -1810,7 +1810,7 @@ void PandaGen::StoreLexicalVar(const ir::AstNode *node, uint32_t level, uint32_t void PandaGen::ThrowIfSuperNotCorrectCall(const ir::AstNode *node, int64_t num) { - sa_.Emit(node, num); + ra_.Emit(node, num); } void PandaGen::ThrowUndefinedIfHole(const ir::AstNode *node, const util::StringView &name) @@ -1838,14 +1838,14 @@ void PandaGen::ThrowConstAssignment(const ir::AstNode *node, const util::StringV void PandaGen::PopLexEnv(const ir::AstNode *node) { - sa_.Emit(node); + ra_.Emit(node); } void PandaGen::CopyLexEnv(const ir::AstNode *node) { /* * TODO: add copy lexenv to optimize the loop env creation - * sa_.Emit(node); + * ra_.Emit(node); */ } @@ -1862,15 +1862,15 @@ void PandaGen::NewLexicalEnv(const ir::AstNode *node, uint32_t num, binder::Vari void PandaGen::NewLexEnv(const ir::AstNode *node, uint32_t num) { - num <= util::Helpers::MAX_INT8 ? sa_.Emit(node, num) : sa_.Emit(node, num); + num <= util::Helpers::MAX_INT8 ? ra_.Emit(node, num) : ra_.Emit(node, num); } void PandaGen::NewLexEnvWithScopeInfo(const ir::AstNode *node, uint32_t num, int32_t scopeInfoIdx) { std::string idxStr = std::string(context_->Binder()->Program()->RecordName()) + "_" + std::to_string(scopeInfoIdx); util::UString litId(idxStr, allocator_); - num <= util::Helpers::MAX_INT8 ? sa_.Emit(node, num, litId.View()) : - sa_.Emit(node, num, litId.View()); + num <= util::Helpers::MAX_INT8 ? ra_.Emit(node, num, litId.View()) : + ra_.Emit(node, num, litId.View()); } uint32_t PandaGen::TryDepth() const @@ -1990,13 +1990,13 @@ VReg PandaGen::LoadPropertyKey(const ir::Expression *prop, bool isComputed) void PandaGen::StLetOrClassToGlobalRecord(const ir::AstNode *node, const util::StringView &name) { - sa_.Emit(node, 0, name); + ra_.Emit(node, 0, name); strings_.insert(name); } void PandaGen::StConstToGlobalRecord(const ir::AstNode *node, const util::StringView &name) { - sa_.Emit(node, 0, name); + ra_.Emit(node, 0, name); strings_.insert(name); } diff --git a/es2panda/compiler/core/pandagen.h b/es2panda/compiler/core/pandagen.h index 02f17f126c..4e85174c87 100644 --- a/es2panda/compiler/core/pandagen.h +++ b/es2panda/compiler/core/pandagen.h @@ -89,9 +89,7 @@ public: catchList_(allocator_->Adapter()), strings_(allocator_->Adapter()), buffStorage_(allocator_->Adapter()), - sa_(this), - ra_(this), - rra_(this) + ra_(this) { } ~PandaGen() = default; @@ -143,6 +141,11 @@ public: return insns_; } + void SetInsns(ArenaList newInsns) + { + insns_ = newInsns; + } + ArenaMap &TypedInsns() { return typedInsns_; @@ -205,9 +208,12 @@ public: void SetSourceLocationFlag(lexer::SourceLocationFlag flag) { - sa_.SetSourceLocationFlag(flag); ra_.SetSourceLocationFlag(flag); - rra_.SetSourceLocationFlag(flag); + } + + void AdjustSpillInsns() + { + ra_.AdjustInsRegWhenHasSpill(); } panda::panda_file::FunctionKind GetFunctionKind() const @@ -480,9 +486,7 @@ private: DynamicContext *dynamicContext_ {}; OptionalChain *optionalChain_ {}; InlineCache ic_; - SimpleAllocator sa_; RegAllocator ra_; - RangeRegAllocator rra_; IcSizeType currentSlot_ {0}; uint32_t usedRegs_ {0}; diff --git a/es2panda/compiler/core/regAllocator.cpp b/es2panda/compiler/core/regAllocator.cpp index 88613e85bd..79410e310c 100644 --- a/es2panda/compiler/core/regAllocator.cpp +++ b/es2panda/compiler/core/regAllocator.cpp @@ -21,168 +21,187 @@ namespace panda::es2panda::compiler { -// AllocatorBase +// FrontAllocator -void AllocatorBase::PushBack(IRNode *ins) +FrontAllocator::FrontAllocator(PandaGen *pg) + : pg_(pg), insn_(std::move(pg_->Insns()), pg_->Allocator()->Adapter()) { - pg_->Insns().push_back(ins); } -ArenaAllocator *AllocatorBase::Allocator() const +FrontAllocator::~FrontAllocator() { - return pg_->Allocator(); + pg_->Insns().splice(pg_->Insns().end(), std::move(insn_)); } -void AllocatorBase::UpdateIcSlot(IRNode *node) +// RegAllocator + +void RegAllocator::PushBack(IRNode *ins) { - auto inc = node->SetIcSlot(pg_->GetCurrentSlot()); - pg_->IncreaseCurrentSlot(inc); + pg_->Insns().push_back(ins); } -void SimpleAllocator::Run(IRNode *ins, int64_t typeIndex) +ArenaAllocator *RegAllocator::Allocator() const { - PushBack(ins); - pg_->TypedInsns()[ins] = typeIndex; + return pg_->Allocator(); } -// FrontAllocator - -FrontAllocator::FrontAllocator(PandaGen *pg) - : AllocatorBase(pg), insn_(std::move(pg_->Insns()), pg_->Allocator()->Adapter()) +uint16_t RegAllocator::GetSpillRegsCount() const { + return spillRegs_; } -FrontAllocator::~FrontAllocator() +void RegAllocator::UpdateIcSlot(IRNode *node) { - pg_->Insns().splice(pg_->Insns().end(), std::move(insn_)); + auto inc = node->SetIcSlot(pg_->GetCurrentSlot()); + pg_->IncreaseCurrentSlot(inc); } -// SimpleAllocator -Label *SimpleAllocator::AllocLabel(std::string &&id) +Label *RegAllocator::AllocLabel(std::string &&id) { const auto *lastInsNode = pg_->Insns().empty() ? FIRST_NODE_OF_FUNCTION : pg_->Insns().back()->Node(); return Alloc