diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_regsaves.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_regsaves.h index f2d8cb448251aa9a7c5d8074b4377919e8e0e1bc..f14cee004b92c59adb146a4f475553a62f4fc09e 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_regsaves.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_regsaves.h @@ -59,10 +59,6 @@ class SavedRegInfo { saveSet.insert(r); } - void RemoveSaveReg(regno_t r) { - saveSet.erase(r); - } - void InsertEntryReg(regno_t r) { restoreEntrySet.insert(r); } @@ -83,6 +79,10 @@ class SavedRegInfo { return restoreExitSet; } + void RemoveSaveReg(regno_t r) { + saveSet.erase(r); + } + private: MapleSet saveSet; MapleSet restoreEntrySet; @@ -117,7 +117,8 @@ class AArch64RegSavesOpt : public RegSavesOpt { pDomInfo(&pdom), bbSavedRegs(alloc.Adapter()), regSavedBBs(alloc.Adapter()), - regOffset(alloc.Adapter()) { + regOffset(alloc.Adapter()), + id2bb(alloc.Adapter()) { bbSavedRegs.resize(func.NumBBs()); regSavedBBs.resize(sizeof(CalleeBitsType)<<3); for (int i = 0; i < bbSavedRegs.size(); ++i) { @@ -145,7 +146,7 @@ class AArch64RegSavesOpt : public RegSavesOpt { bool AlreadySavedInDominatorList(BB *bb, regno_t reg) const; void DetermineCalleeSaveLocationsDoms(); void DetermineCalleeSaveLocationsPre(); - void DetermineCalleeRestoreLocations(); + bool DetermineCalleeRestoreLocations(); int32 FindNextOffsetForCalleeSave(); void InsertCalleeSaveCode(); void InsertCalleeRestoreCode(); @@ -221,6 +222,14 @@ class AArch64RegSavesOpt : public RegSavesOpt { return bbSavedRegs[bid]; } + void SetId2bb(BB *bb) { + id2bb[bb->GetId()] = bb; + } + + BB *GetId2bb(uint32 bid) { + return id2bb[bid]; + } + private: DomAnalysis *domInfo; PostDomAnalysis *pDomInfo; @@ -230,6 +239,7 @@ class AArch64RegSavesOpt : public RegSavesOpt { MapleVector bbSavedRegs; /* set of regs to be saved in a BB */ MapleVector regSavedBBs; /* set of BBs to be saved for a reg */ MapleMap regOffset; /* save offset of each register */ + MapleMap id2bb; /* bbid to bb* mapping */ bool oneAtaTime = false; regno_t oneAtaTimeReg = 0; }; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp index b70edf4edea06a8a9361e3a8cb42ce302b429339..3d6f553417c14bfd72831dd06e199daecfde939e 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp @@ -104,6 +104,18 @@ bool AArch64GenProEpilog::OptimizeTailBB(BB &bb, std::set &callInsns, con } MOperator insnMop = insn->GetMachineOpcode(); switch (insnMop) { + case MOP_xldr: + case MOP_xldp: + case MOP_dldr: + case MOP_dldp: { + if (bb.GetKind() == BB::kBBReturn) { + RegOperand ® = static_cast(insn->GetOperand(0)); + if (AArch64Abi::IsCalleeSavedReg(static_cast(reg.GetRegisterNumber()))) { + break; /* inserted restore from calleeregs-placement, ignore */ + } + } + return false; + } case MOP_wmovrr: case MOP_xmovrr: { CHECK_FATAL(insn->GetOperand(0).IsRegister(), "operand0 is not register"); diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_regsaves.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_regsaves.cpp index 8348ada6aee5c040183aca60ad2b42d426270f83..bea6923abbbe87f2f64cf301fdca80753f4e22e6 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_regsaves.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_regsaves.cpp @@ -49,6 +49,10 @@ void AArch64RegSavesOpt::InitData() { aarchCGFunc->GetProEpilogSavedRegs().push_back(RLR); } } + + for (auto bb : bfs->sortedBBs) { + SetId2bb(bb); + } } @@ -405,7 +409,7 @@ void AArch64RegSavesOpt::DetermineCalleeSaveLocationsPre() { /* Determine calleesave regs restore locations by calling ssu-pre, previous bbSavedRegs memory is cleared and restore locs recorded in it */ -void AArch64RegSavesOpt::DetermineCalleeRestoreLocations() { +bool AArch64RegSavesOpt::DetermineCalleeRestoreLocations() { AArch64CGFunc *aarchCGFunc = static_cast(cgFunc); MapleAllocator sprealloc(memPool); if (RS_DUMP) { @@ -444,8 +448,24 @@ void AArch64RegSavesOpt::DetermineCalleeRestoreLocations() { /* something gone wrong, skip this reg */ wkCand.restoreAtEpilog = true; } + /* splitted empty block for critical edge present, skip function */ + MapleSet rset = wkCand.restoreAtEntryBBs; + for (auto bbid : wkCand.restoreAtExitBBs) { + rset.insert(bbid); + } + for (auto bbid : rset) { + BB *bb = GetId2bb(bbid); + if (bb->GetKind() == BB::kBBGoto && bb->NumInsn() == 1) { + aarchCGFunc->GetProEpilogSavedRegs().clear(); + const MapleVector &callees = aarchCGFunc->GetCalleeSavedRegs(); + for (auto areg : callees) { + aarchCGFunc->GetProEpilogSavedRegs().push_back(areg); + } + return false; + } + } if (wkCand.restoreAtEpilog) { - /* Restore cannot be applied, skip this reg and place save/restore + /* Restore cannot b3 applied, skip this reg and place save/restore in prolog/epilog */ for (int bid = 1; bid < bbSavedRegs.size(); bid++) { SavedRegInfo *sp = bbSavedRegs[bid]; @@ -473,36 +493,31 @@ void AArch64RegSavesOpt::DetermineCalleeRestoreLocations() { GetbbSavedRegsEntry(entBB)->InsertEntryReg(reg); } for (uint32 exitBB : wkCand.restoreAtExitBBs) { - for (BB *bb : bfs->sortedBBs) { - if (bb->GetId() == exitBB) { - if (bb->GetKind() == BB::kBBIgoto) { - CHECK_FATAL(false, "igoto detected"); - } - Insn *lastInsn = bb->GetLastInsn(); - if (lastInsn != nullptr && lastInsn->IsBranch() && - (!lastInsn->GetOperand(0).IsRegister() || /* not a reg OR */ - (!AArch64Abi::IsCalleeSavedReg( /* reg but not cs */ - static_cast(static_cast( - lastInsn->GetOperand(0)).GetRegisterNumber()))))) { - /* To insert in this block - 1 instr */ - SavedRegInfo *sp = GetbbSavedRegsEntry(exitBB); - sp->InsertExitReg(reg); - sp->insertAtLastMinusOne = true; - } else if (bb->GetSuccs().size() > 1) { - for (BB *sbb : bb->GetSuccs()) { - if (sbb->GetPreds().size() > 1) { - CHECK_FATAL(false, "critical edge detected"); - } - } - for (BB *sbb : bb->GetSuccs()) { - /* To insert at all succs */ - GetbbSavedRegsEntry(sbb->GetId())->InsertEntryReg(reg); - } - } else { - /* otherwise, BB_FT etc */ - GetbbSavedRegsEntry(exitBB)->InsertExitReg(reg); + BB *bb = GetId2bb(exitBB); + if (bb->GetKind() == BB::kBBIgoto) { + CHECK_FATAL(false, "igoto detected"); + } + Insn *lastInsn = bb->GetLastInsn(); + if (lastInsn != nullptr && lastInsn->IsBranch() && + (!lastInsn->GetOperand(0).IsRegister() || /* not a reg OR */ + (!AArch64Abi::IsCalleeSavedReg( /* reg but not cs */ + static_cast(static_cast( + lastInsn->GetOperand(0)).GetRegisterNumber()))))) { + /* To insert in this block - 1 instr */ + SavedRegInfo *sp = GetbbSavedRegsEntry(exitBB); + sp->InsertExitReg(reg); + sp->insertAtLastMinusOne = true; + } else if (bb->GetSuccs().size() > 1) { + for (BB *sbb : bb->GetSuccs()) { + if (sbb->GetPreds().size() > 1) { + CHECK_FATAL(false, "critical edge detected"); } + /* To insert at all succs */ + GetbbSavedRegsEntry(sbb->GetId())->InsertEntryReg(reg); } + } else { + /* otherwise, BB_FT etc */ + GetbbSavedRegsEntry(exitBB)->InsertExitReg(reg); } if (RS_DUMP) { std::string r = reg <= R28 ? "R" : "V"; @@ -511,6 +526,7 @@ void AArch64RegSavesOpt::DetermineCalleeRestoreLocations() { } } } + return true; } int32 AArch64RegSavesOpt::FindNextOffsetForCalleeSave() { @@ -806,8 +822,11 @@ void AArch64RegSavesOpt::Run() { } /* Determine restore sites */ - DetermineCalleeRestoreLocations(); + if (!DetermineCalleeRestoreLocations()) { + return; + } +#ifdef VERIFY /* Verify saves/restores are in pair */ if (RS_DUMP) { std::vector rlist = { R19, R20, R21, R22, R23, R24, R25, R26, R27, R28 }; @@ -820,6 +839,7 @@ void AArch64RegSavesOpt::Run() { mLog << "\nVerify Done\n"; } } +#endif /* Generate callee save instrs at found sites */ InsertCalleeSaveCode();