diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h index b4f478147b084a1f8c66b837447c8d73966cda94..ffdf0ed1f6e967331b109ec01e3ee976ce102833 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h @@ -1121,6 +1121,11 @@ class GraphColorRegAllocator : public AArch64RegAllocator { return "regalloc"; } + enum SpillMemCheck : uint8 { + kSpillMemPre, + kSpillMemPost, + }; + private: struct SetLiveRangeCmpFunc { bool operator()(const LiveRange *lhs, const LiveRange *rhs) const { @@ -1183,7 +1188,7 @@ class GraphColorRegAllocator : public AArch64RegAllocator { void ComputeLiveRangesUpdateIfInsnIsCall(const Insn &insn); void ComputeLiveRangesUpdateLiveUnitInsnRange(BB &bb, uint32 currPoint); void ComputeLiveRanges(); - MemOperand *CreateSpillMem(uint32 spillIdx); + MemOperand *CreateSpillMem(uint32 spillIdx, SpillMemCheck check); bool CheckOverlap(uint64 val, uint32 &lastBitSet, uint32 &overlapNum, uint32 i) const; void CheckInterference(LiveRange &lr1, LiveRange &lr2) const; void BuildInterferenceGraphSeparateIntFp(std::vector &intLrVec, std::vector &fpLrVec); @@ -1314,6 +1319,7 @@ class GraphColorRegAllocator : public AArch64RegAllocator { std::array spillMemOpnds = { nullptr }; regno_t intSpillFillRegs[kSpillMemOpndNum]; regno_t fpSpillFillRegs[kSpillMemOpndNum]; + bool operandSpilled[kSpillMemOpndNum]; bool needExtraSpillReg = false; #ifdef USE_LRA bool doLRA = true; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp index 479d7332520b872ddd87da1ec40b266114722f26..71224dd97308e3d59922a62f46db58be7f247aaf 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp @@ -941,11 +941,26 @@ void GraphColorRegAllocator::ComputeLiveRanges() { } /* Create a common stack space for spilling with need_spill */ -MemOperand *GraphColorRegAllocator::CreateSpillMem(uint32 spillIdx) { +MemOperand *GraphColorRegAllocator::CreateSpillMem(uint32 spillIdx, SpillMemCheck check) { if (spillIdx >= spillMemOpnds.size()) { return nullptr; } + if (operandSpilled[spillIdx]) { + // For this insn, spill slot already used, need to find next available slot. + uint32 i; + for (i = spillIdx + 1; i < kSpillMemOpndNum; ++i) { + if (operandSpilled[i] == false) { + break; + } + } + CHECK_FATAL(i < kSpillMemOpndNum, "no more available spill mem slot"); + spillIdx = i; + } + if (check == kSpillMemPost) { + operandSpilled[spillIdx] = true; + } + if (spillMemOpnds[spillIdx] == nullptr) { regno_t reg = cgFunc->NewVReg(kRegTyInt, sizeof(int64)); auto *a64CGFunc = static_cast(cgFunc); @@ -2459,7 +2474,7 @@ void GraphColorRegAllocator::SpillOperandForSpillPre(Insn &insn, const Operand & if (!needSpill) { return; } - MemOperand *spillMem = CreateSpillMem(spillIdx); + MemOperand *spillMem = CreateSpillMem(spillIdx, kSpillMemPre); ASSERT(spillMem != nullptr, "spillMem nullptr check"); auto *a64CGFunc = static_cast(cgFunc); CG *cg = a64CGFunc->GetCG(); @@ -2493,7 +2508,7 @@ void GraphColorRegAllocator::SpillOperandForSpillPost(Insn &insn, const Operand return; } - MemOperand *spillMem = CreateSpillMem(spillIdx); + MemOperand *spillMem = CreateSpillMem(spillIdx, kSpillMemPost); ASSERT(spillMem != nullptr, "spillMem nullptr check"); auto *a64CGFunc = static_cast(cgFunc); CG *cg = a64CGFunc->GetCG(); @@ -3211,6 +3226,9 @@ void GraphColorRegAllocator::FinalizeRegisters() { if (insn->GetId() == 0) { continue; } + for (uint32 i = 0; i < kSpillMemOpndNum; ++i) { + operandSpilled[i] = false; + } FinalizeRegisterInfo *fInfo = memPool->New(alloc); uint64 usedRegMask = FinalizeRegisterPreprocess(*fInfo, *insn);