diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_proepilog.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_proepilog.h index 918353e0498a018213f06799d8d4fff62724a5f9..b35fc050afda4bef2b0762b8449daa534d2022cc 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_proepilog.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_proepilog.h @@ -31,6 +31,7 @@ class AArch64GenProEpilog : public GenProEpilog { ~AArch64GenProEpilog() override = default; bool TailCallOpt() override; + bool NeedProEpilog() override; void Run() override; private: void GenStackGuard(BB&); diff --git a/src/mapleall/maple_be/include/cg/proepilog.h b/src/mapleall/maple_be/include/cg/proepilog.h index 5ceedf2d6ef321c26782890dc8262c4c0c4f5b2b..445dcb3b268918f3ee27ce99652d046c9195af75 100644 --- a/src/mapleall/maple_be/include/cg/proepilog.h +++ b/src/mapleall/maple_be/include/cg/proepilog.h @@ -35,6 +35,12 @@ class GenProEpilog { return false; } + virtual bool NeedProEpilog() { + return true; + } + + + /* CFI related routines */ int64 GetOffsetFromCFA() const { return offsetFromCfa; @@ -56,4 +62,4 @@ class GenProEpilog { CGFUNCPHASE(CgDoGenProEpiLog, "generateproepilog") } /* namespace maplebe */ -#endif /* MAPLEBE_INCLUDE_CG_PROEPILOG_H */ \ No newline at end of file +#endif /* MAPLEBE_INCLUDE_CG_PROEPILOG_H */ 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 a2c9af8ef6a0158d50ee320100b7926b0780cd2d..45bbe7ff2ee4cc39286d78b9ad63b026e120dc12 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp @@ -143,21 +143,12 @@ void AArch64GenProEpilog::TailCallBBOpt(const BB &exitBB, std::set &callI * Return value: true if function do not need Prologue/Epilogue. false otherwise. */ bool AArch64GenProEpilog::TailCallOpt() { - auto &aarchCGFunc = static_cast(cgFunc); - BB *exitBB = nullptr; - const MapleVector ®sToRestore = aarchCGFunc.GetCalleeSavedRegs(); - - size_t calleeSavedRegSize = 2; - CHECK_FATAL(regsToRestore.size() >= calleeSavedRegSize, "Forgot FP and LR ?"); - - if (regsToRestore.size() > calleeSavedRegSize || aarchCGFunc.HasStackLoadStore() || HasLoop() || - cgFunc.GetFunction().GetAttr(FUNCATTR_callersensitive) || IsFuncNeedFrame(cgFunc.GetName())) { + size_t exitBBSize = cgFunc.GetExitBBsVec().size(); + if (exitBBSize > 1) { return false; } - size_t exitBBSize = cgFunc.GetExitBBsVec().size(); - CHECK_FATAL(exitBBSize == 1, "Should not be exist multiple exits."); - + BB *exitBB = nullptr; if (exitBBSize == 0) { if (cgFunc.GetLastBB()->GetPrev()->GetFirstStmt() == cgFunc.GetCleanupLabel() && cgFunc.GetLastBB()->GetPrev()->GetPrev() != nullptr) { @@ -219,6 +210,35 @@ bool AArch64GenProEpilog::TailCallOpt() { return true; } +bool AArch64GenProEpilog::NeedProEpilog() { + if (cgFunc.GetMirModule().GetSrcLang() != kSrcLangC) { + return true; + } else if (static_cast(cgFunc.GetMemlayout())->GetSizeOfLocals() > 0 || + cgFunc.GetFunction().GetAttr(FUNCATTR_varargs) || cgFunc.HasVLAOrAlloca()) { + return true; + } + auto &aarchCGFunc = static_cast(cgFunc); + const MapleVector ®sToRestore = aarchCGFunc.GetCalleeSavedRegs(); + size_t calleeSavedRegSize = kTwoRegister; + CHECK_FATAL(regsToRestore.size() >= calleeSavedRegSize, "Forgot FP and LR ?"); + if (regsToRestore.size() > calleeSavedRegSize || aarchCGFunc.HasStackLoadStore() || HasLoop() || + cgFunc.GetFunction().GetAttr(FUNCATTR_callersensitive)) { + return true; + } + if (cgFunc.GetCG()->DoPrologueEpilogue()) { + return !TailCallOpt(); + } else { + FOR_ALL_BB(bb, &cgFunc) { + FOR_BB_INSNS_REV(insn, bb) { + if (insn->IsCall()) { + return true; + } + } + } + } + return false; +} + void AArch64GenProEpilog::GenStackGuard(BB &bb) { auto &aarchCGFunc = static_cast(cgFunc); CG *currCG = cgFunc.GetCG(); @@ -1741,7 +1761,7 @@ void AArch64GenProEpilog::GenerateEpilogForCleanup(BB &bb) { void AArch64GenProEpilog::Run() { CHECK_FATAL(cgFunc.GetFunction().GetBody()->GetFirst()->GetOpCode() == OP_label, "The first statement should be a label"); - cgFunc.SetHasProEpilogue(true); + cgFunc.SetHasProEpilogue(NeedProEpilog()); if (cgFunc.GetHasProEpilogue()) { GenStackGuard(*(cgFunc.GetFirstBB())); }