From dcd4c0f49b086a704a3252f5facc918326a2c1fa Mon Sep 17 00:00:00 2001 From: hufeng Date: Tue, 1 Nov 2022 21:25:32 +0800 Subject: [PATCH 1/2] 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 9143ac1ca2..3769926906 100644 --- a/es2panda/compiler/core/function.cpp +++ b/es2panda/compiler/core/function.cpp @@ -205,6 +205,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