diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_reg_alloc.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_reg_alloc.h index 66985759278dcd9c915f4cf4f6d55bff263f7116..18542b7a42d4ace1428a877409df836c37f2344a 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_reg_alloc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_reg_alloc.h @@ -28,6 +28,7 @@ class AArch64RegAllocator : public RegAllocator { regMap(std::less(), alloc.Adapter()), liveReg(std::less(), alloc.Adapter()), allocatedSet(std::less(), alloc.Adapter()), + regLiveness(std::less(), alloc.Adapter()), visitedBBs(alloc.Adapter()), sortedBBs(alloc.Adapter()), rememberRegs(alloc.Adapter()) { @@ -66,11 +67,15 @@ class AArch64RegAllocator : public RegAllocator { Operand *AllocSrcOpnd(Operand &opnd, OpndProp *opndProp = nullptr); Operand *AllocDestOpnd(Operand &opnd, const Insn &insn); + uint32 GetRegLivenessId(Operand *opnd); + void SetupRegLiveness(BB *bb); + MapleAllocator alloc; bool availRegSet[kAllRegNum]; MapleMap regMap; /* virtual-register-to-physical-register map */ MapleSet liveReg; /* a set of currently live physical registers */ MapleSet allocatedSet; /* already allocated */ + MapleMap regLiveness; MapleVector visitedBBs; MapleVector sortedBBs; MapleVector rememberRegs; @@ -87,4 +92,4 @@ class DefaultO0RegAllocator : public AArch64RegAllocator { ; } /* namespace maplebe */ -#endif /* MAPLEBE_INCLUDE_CG_AARCH64_AARCH64_REG_ALLOC_H */ \ No newline at end of file +#endif /* MAPLEBE_INCLUDE_CG_AARCH64_AARCH64_REG_ALLOC_H */ diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_reg_alloc.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_reg_alloc.cpp index 1a67313d279f82106348e5a03459265172f43f74..cc6318912f3a00e082d8851c86f1bfc370811e62 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_reg_alloc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_reg_alloc.cpp @@ -123,7 +123,10 @@ Operand *AArch64RegAllocator::AllocDestOpnd(Operand &opnd, const Insn &insn) { if (!regOpnd.IsVirtualRegister()) { auto reg = static_cast(regOpnd.GetRegisterNumber()); availRegSet[reg] = true; - ReleaseReg(reg); + uint32 id = GetRegLivenessId(®Opnd); + if (id && (id <= insn.GetId())) { + ReleaseReg(reg); + } return &opnd; } @@ -132,14 +135,20 @@ Operand *AArch64RegAllocator::AllocDestOpnd(Operand &opnd, const Insn &insn) { if (regMapIt != regMap.end()) { AArch64reg reg = regMapIt->second; if (!insn.IsCondDef()) { - ReleaseReg(reg); + uint32 id = GetRegLivenessId(®Opnd); + if (id && (id <= insn.GetId())) { + ReleaseReg(reg); + } } } else { /* AllocatePhysicalRegister insert a mapping from vreg no to phy reg no into regMap */ if (AllocatePhysicalRegister(regOpnd)) { regMapIt = regMap.find(regOpnd.GetRegisterNumber()); if (!insn.IsCondDef()) { - ReleaseReg(regMapIt->second); + uint32 id = GetRegLivenessId(®Opnd); + if (id && (id <= insn.GetId())) { + ReleaseReg(regMapIt->second); + } } } else { /* For register spill. use 0 register as spill register */ @@ -519,9 +528,40 @@ void AArch64RegAllocator::ComputeBlockOrder() { } } +uint32 AArch64RegAllocator::GetRegLivenessId(Operand *opnd) { + auto regIt = regLiveness.find(opnd); + return ((regIt == regLiveness.end()) ? 0 : regIt->second); +} + +void AArch64RegAllocator::SetupRegLiveness(BB *bb) { + regLiveness.clear(); + + uint32 id = 1; + FOR_BB_INSNS_REV(insn, bb) { + if (!insn->IsMachineInstruction()) { + continue; + } + insn->SetId(id); + id++; + const AArch64MD *md = &AArch64CG::kMd[static_cast(insn)->GetMachineOpcode()]; + uint32 opndNum = insn->GetOperandSize(); + for (uint32 i = 0; i < opndNum; i++) { + Operand &opnd = insn->GetOperand(i); + AArch64OpndProp *aarch64Opndprop = static_cast(md->operand[i]); + if (!aarch64Opndprop->IsRegDef()) { + continue; + } + if (opnd.IsRegister()) { + regLiveness[&opnd] = insn->GetId(); + } + } + } +} + bool DefaultO0RegAllocator::AllocateRegisters() { InitAvailReg(); PreAllocate(); + cgFunc->SetIsAfterRegAlloc(); auto *a64CGFunc = static_cast(cgFunc); /* @@ -537,6 +577,7 @@ bool DefaultO0RegAllocator::AllocateRegisters() { continue; } + SetupRegLiveness(bb); FOR_BB_INSNS_REV(insn, bb) { if (!insn->IsMachineInstruction()) { continue; @@ -564,7 +605,10 @@ bool DefaultO0RegAllocator::AllocateRegisters() { regno_t regNO = regOpnd.GetRegisterNumber(); rememberRegs.push_back(static_cast(regOpnd.IsVirtualRegister() ? regMap[regNO] : regNO)); } else if (!insn->IsCondDef()) { - ReleaseReg(regOpnd); + uint32 id = GetRegLivenessId(®Opnd); + if (id && (id <= insn->GetId())) { + ReleaseReg(regOpnd); + } } insn->SetOperand(i, a64CGFunc->GetOrCreatePhysicalRegisterOperand( regMap[regOpnd.GetRegisterNumber()], regOpnd.GetSize(), regOpnd.GetRegisterType()));