From 343fcb75b1331fd070f6ff6dbbc133b9bce5954a Mon Sep 17 00:00:00 2001 From: linma Date: Sun, 15 May 2022 13:41:16 -0700 Subject: [PATCH 1/3] pgo: put profileUse in IPASCCPM, update stmtFreqs in lower/emit/inline/lfounroll/lfovectorize phases --- src/mapleall/maple_ipa/BUILD.gn | 1 - .../maple_ipa/include/ipa_gcovprofile.h | 44 ---------- .../maple_ipa/src/ipa_gcovprofile.cpp | 87 ------------------- .../maple_ipa/src/ipa_phase_manager.cpp | 15 +++- src/mapleall/maple_ir/include/mir_function.h | 8 +- src/mapleall/maple_ir/include/mir_lower.h | 8 ++ src/mapleall/maple_ir/include/mir_nodes.h | 81 +++++++++++++++++ src/mapleall/maple_ir/src/mir_lower.cpp | 72 +++++++++++++++ src/mapleall/maple_ir/src/mir_nodes.cpp | 73 ++++++++++++++++ src/mapleall/maple_me/include/lfo_loop_vec.h | 2 + src/mapleall/maple_me/include/pme_emit.h | 1 + src/mapleall/maple_me/src/bb.cpp | 11 +++ src/mapleall/maple_me/src/func_emit.cpp | 4 + src/mapleall/maple_me/src/irmap_emit.cpp | 21 +++++ src/mapleall/maple_me/src/lfo_loop_vec.cpp | 38 ++++++++ src/mapleall/maple_me/src/lfo_unroll.cpp | 76 ++++++++++++++-- src/mapleall/maple_me/src/me_cfg.cpp | 60 ++++++++++++- .../maple_me/src/me_critical_edge.cpp | 12 ++- src/mapleall/maple_me/src/me_emit.cpp | 8 ++ src/mapleall/maple_me/src/me_profile_use.cpp | 4 +- src/mapleall/maple_me/src/pme_emit.cpp | 64 +++++++++++++- src/mapleall/maple_me/src/pme_mir_lower.cpp | 59 ++++++++++++- src/mapleall/maple_phase/include/phases.def | 5 +- .../maple_util/include/gcov_profile.h | 48 +++++++--- src/mapleall/mpl2mpl/include/call_graph.h | 4 +- src/mapleall/mpl2mpl/src/call_graph.cpp | 25 ++++++ src/mapleall/mpl2mpl/src/gcov_parser.cpp | 15 ++-- src/mapleall/mpl2mpl/src/inline.cpp | 66 ++++++++++++-- .../mpl2mpl/src/module_phase_manager.cpp | 3 +- 29 files changed, 729 insertions(+), 186 deletions(-) delete mode 100644 src/mapleall/maple_ipa/include/ipa_gcovprofile.h delete mode 100644 src/mapleall/maple_ipa/src/ipa_gcovprofile.cpp diff --git a/src/mapleall/maple_ipa/BUILD.gn b/src/mapleall/maple_ipa/BUILD.gn index 909eaf1bfc..c4b8682172 100755 --- a/src/mapleall/maple_ipa/BUILD.gn +++ b/src/mapleall/maple_ipa/BUILD.gn @@ -36,7 +36,6 @@ src_libmplipa = [ "src/prop_parameter_type.cpp", "src/ipa_collect.cpp", "src/ipa_clone.cpp", - "src/ipa_gcovprofile.cpp", ] configs = [ "${MAPLEALL_ROOT}:mapleallcompilecfg" ] diff --git a/src/mapleall/maple_ipa/include/ipa_gcovprofile.h b/src/mapleall/maple_ipa/include/ipa_gcovprofile.h deleted file mode 100644 index 9ad1658f6b..0000000000 --- a/src/mapleall/maple_ipa/include/ipa_gcovprofile.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) [2021] Huawei Technologies Co.,Ltd.All rights reserved. - * - * OpenArkCompiler is licensed under Mulan PSL v2. - * You can use this software according to the terms and conditions of the Mulan PSL v2. - * You may obtain a copy of Mulan PSL v2 at: - * - * http://license.coscl.org.cn/MulanPSL2 - * - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR - * FIT FOR A PARTICULAR PURPOSE. - * See the Mulan PSL v2 for more details. - */ -#ifndef MAPLE_IPA_INCLUDE_IPA_GCOVPROFILE_H -#define MAPLE_IPA_INCLUDE_IPA_GCOVPROFILE_H -#include -#include -#include "mempool.h" -#include "mempool_allocator.h" -#include "mir_module.h" -#include "mir_function.h" -#include "me_phase_manager.h" -#include "gcov_parser.h" - -namespace maple { - -class IpaProfile : public MapleModulePhase, public MaplePhaseManager { - public: - explicit IpaProfile(MemPool *mp) : MapleModulePhase(&id, mp), MaplePhaseManager(*mp) {} - ~IpaProfile() override = default; - std::string PhaseName() const override; - PHASECONSTRUCTOR(IpaProfile); - bool PhaseRun(MIRModule &m) override; - AnalysisDataManager *GetResult() { - return result; - } - private: - void GetAnalysisDependence(maple::AnalysisDep &aDep) const override; - AnalysisDataManager *result = nullptr; -}; - -} // namespace maple -#endif // MAPLE_IPA_INCLUDE_IPA_GCOVPROFILE_H diff --git a/src/mapleall/maple_ipa/src/ipa_gcovprofile.cpp b/src/mapleall/maple_ipa/src/ipa_gcovprofile.cpp deleted file mode 100644 index a0bd27d9b5..0000000000 --- a/src/mapleall/maple_ipa/src/ipa_gcovprofile.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) [2021-2022] Huawei Technologies Co.,Ltd.All rights reserved. - * - * OpenArkCompiler is licensed under Mulan PSL v2. - * You can use this software according to the terms and conditions of the Mulan PSL v2. - * You may obtain a copy of Mulan PSL v2 at: - * - * http://license.coscl.org.cn/MulanPSL2 - * - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR - * FIT FOR A PARTICULAR PURPOSE. - * See the Mulan PSL v2 for more details. - */ -#include "ipa_phase_manager.h" -#include "pme_emit.h" -#include "ipa_gcovprofile.h" - -namespace maple { - -void IpaProfile::GetAnalysisDependence(maple::AnalysisDep &aDep) const { - if (Options::profileUse) { - aDep.AddRequired(); - aDep.AddPreserved(); - } -} - -bool IpaProfile::PhaseRun(MIRModule &m) { - SetQuiet(true); - // keep original options value - bool oldProp = MeOption::propDuringBuild; - bool oldMerge = MeOption::mergeStmts; - uint8 oldOptLevel = MeOption::optLevel; - bool oldLayout = MeOption::layoutWithPredict; - MeOption::mergeStmts = false; - MeOption::propDuringBuild = false; - MeOption::layoutWithPredict = false; - MeOption::optLevel = 3; - - AddPhase("mecfgbuild", true); - AddPhase("profileUse", true); - AddPhase("emitforipa", true); - // Not like other phasemanager which use temp mempool to hold analysis results generated from the sub phases. - // Here we use GetManagerMemPool which lives longer than this phase(manager) itself to hold all the analysis result. - // So the following phase can access the result in this phase. - result = GetManagerMemPool()->New(*GetPhaseMemPool()); - auto iter = m.GetFunctionList().begin(); - for (; iter != m.GetFunctionList().end(); iter++) { - MIRFunction *func = *iter; - if (func == nullptr || func->GetFuncSymbol()->GetStorageClass() == kScUnused || - func->IsEmpty()) { - continue; - } - m.SetCurFunction(func); - auto meFuncMP = std::make_unique(memPoolCtrler, "ipa gcovprofile mempool"); - auto meFuncStackMP = std::make_unique(memPoolCtrler, ""); - MemPool *versMP = new ThreadLocalMemPool(memPoolCtrler, "first verst mempool"); - MeFunction &meFunc = *(meFuncMP->New(&m, func, meFuncMP.get(), *meFuncStackMP, versMP, "unknown")); - func->SetMeFunc(&meFunc); - meFunc.PartialInit(); - if (!IsQuiet()) { - LogInfo::MapleLogger() << "---Preparing Function for scc phase < " << func->GetName() << " > ---\n"; - } - meFunc.Prepare(); - - for (size_t i = 0; i < phasesSequence.size(); ++i) { - const MaplePhaseInfo *phase = MaplePhaseRegister::GetMaplePhaseRegister()->GetPhaseByID(phasesSequence[i]); - if (!IsQuiet()) { - LogInfo::MapleLogger() << " >> Prepare " << (phase->IsAnalysis() ? "analysis" : "transform") - << " Phase [ " << phase->PhaseName() << " ] <<\n"; - } - if (phase->IsAnalysis()) { - (void)RunAnalysisPhase(*phase, *result, meFunc, 1); - } else { - (void)RunTransformPhase(*phase, *result, meFunc, 1); - } - } - } - - // restore option value - MeOption::mergeStmts = oldMerge; - MeOption::propDuringBuild = oldProp; - MeOption::optLevel = oldOptLevel; - MeOption::layoutWithPredict = oldLayout; - return false; -} -} // namespace maple diff --git a/src/mapleall/maple_ipa/src/ipa_phase_manager.cpp b/src/mapleall/maple_ipa/src/ipa_phase_manager.cpp index 05bc4b00fa..c6845fda78 100644 --- a/src/mapleall/maple_ipa/src/ipa_phase_manager.cpp +++ b/src/mapleall/maple_ipa/src/ipa_phase_manager.cpp @@ -14,6 +14,7 @@ */ #include "ipa_phase_manager.h" #include "pme_emit.h" +#include "gcov_parser.h" #define JAVALANG (mirModule.IsJavaModule()) #define CLANG (mirModule.IsCModule()) @@ -83,7 +84,7 @@ bool IpaSccPM::PhaseRun(MIRModule &m) { void IpaSccPM::DoPhasesPopulate(const MIRModule &mirModule) { (void)mirModule; - if (Options::profileGen || Options::profileUse) { + if (Options::profileGen) { AddPhase("sccprofile", true); } else { AddPhase("sccprepare", true); @@ -100,6 +101,10 @@ void IpaSccPM::GetAnalysisDependence(maple::AnalysisDep &aDep) const { aDep.AddRequired(); aDep.AddPreserved(); aDep.AddPreserved(); + if (Options::profileUse) { + aDep.AddRequired(); + aDep.AddPreserved(); + } } void SCCPrepare::Dump(MeFunction &f, const std::string phaseName) { @@ -113,6 +118,10 @@ void SCCPrepare::Dump(MeFunction &f, const std::string phaseName) { bool SCCPrepare::PhaseRun(SCCNode &scc) { SetQuiet(true); AddPhase("mecfgbuild", true); + if (Options::profileUse) { + AddPhase("splitcriticaledge", true); + AddPhase("profileUse", true); + } AddPhase("ssatab", true); AddPhase("aliasclass", true); AddPhase("ssa", true); @@ -174,7 +183,7 @@ bool SCCEmit::PhaseRun(SCCNode &scc) { m.SetCurFunction(func); const MaplePhaseInfo *phase = MaplePhaseRegister::GetMaplePhaseRegister()->GetPhaseByID(&MEPreMeEmission::id); if (!IsQuiet()) { - LogInfo::MapleLogger() << "---Run " << (phase->IsAnalysis() ? "analysis" : "transform") + LogInfo::MapleLogger() << " ---call " << (phase->IsAnalysis() ? "analysis" : "transform") << " Phase [ " << phase->PhaseName() << " ]---\n"; } (void)RunAnalysisPhase(*phase, *serialADM, *func->GetMeFunc()); @@ -196,8 +205,6 @@ bool SCCProfile::PhaseRun(SCCNode &scc) { if (Options::profileGen) { AddPhase("splitcriticaledge", true); AddPhase("profileGen", true); - } else { - AddPhase("profileUse", true); } AddPhase("emitforipa", true); // Not like other phasemanager which use temp mempool to hold analysis results generated from the sub phases. diff --git a/src/mapleall/maple_ir/include/mir_function.h b/src/mapleall/maple_ir/include/mir_function.h index f805ff824f..4f51ceaeca 100644 --- a/src/mapleall/maple_ir/include/mir_function.h +++ b/src/mapleall/maple_ir/include/mir_function.h @@ -1250,7 +1250,13 @@ class MIRFunction { GcovFuncInfo* GetFuncProfData() { return funcProfData; } - + GcovFuncInfo* GetFuncProfData() const { + return funcProfData; + } + void SetStmtFreq(uint32_t stmtID, uint64_t freq) { + ASSERT((funcProfData != nullptr && freq > 0), "nullptr check"); + funcProfData->SetStmtFreq(stmtID, freq); + } private: MIRModule *module; // the module that owns this function PUIdx puIdx = 0; // the PU index of this function diff --git a/src/mapleall/maple_ir/include/mir_lower.h b/src/mapleall/maple_ir/include/mir_lower.h index 4fdd43f277..332a6de89f 100644 --- a/src/mapleall/maple_ir/include/mir_lower.h +++ b/src/mapleall/maple_ir/include/mir_lower.h @@ -138,6 +138,14 @@ class MIRLower { virtual bool InLFO() const { return false; } + GcovFuncInfo *GetFuncProfData() { return mirFunc->GetFuncProfData(); } + void CopyStmtFrequency(StmtNode *newStmt, StmtNode *oldStmt) { + ASSERT(GetFuncProfData() != nullptr, "nullptr check"); + if (newStmt == oldStmt) return; + int64_t freq = GetFuncProfData()->GetStmtFreq(oldStmt->GetStmtID()); + GetFuncProfData()->SetStmtFreq(newStmt->GetStmtID(), freq); +} + protected: MIRModule &mirModule; private: diff --git a/src/mapleall/maple_ir/include/mir_nodes.h b/src/mapleall/maple_ir/include/mir_nodes.h index d3aa5dab35..f782bdc03b 100755 --- a/src/mapleall/maple_ir/include/mir_nodes.h +++ b/src/mapleall/maple_ir/include/mir_nodes.h @@ -2391,6 +2391,11 @@ class BlockNode : public StmtNode { return blk; } + BlockNode *CloneTreeWithFreqs(MapleAllocator &allocator, + std::unordered_map& toFreqs, + std::unordered_map& fromFreqs, + uint64_t numer, uint64_t denom, uint32_t updateOp); + bool IsEmpty() const { return stmtNodeList.empty(); } @@ -2458,6 +2463,30 @@ class IfStmtNode : public UnaryStmtNode { return node; } + IfStmtNode *CloneTreeWithFreqs(MapleAllocator &allocator, + std::unordered_map& toFreqs, + std::unordered_map& fromFreqs, + uint64_t numer, uint64_t denom, uint32_t updateOp) { + auto *node = allocator.GetMemPool()->New(*this); + node->SetStmtID(stmtIDNext++); + node->SetOpnd(Opnd()->CloneTree(allocator), 0); + if (fromFreqs.count(GetStmtID()) > 0) { + int64_t oldFreq = fromFreqs[GetStmtID()]; + int64_t newFreq = denom > 0 ? (oldFreq * numer / denom) : oldFreq; + toFreqs[node->GetStmtID()] = newFreq > 0 ? newFreq : 1; + if (updateOp & kUpdateOrigFreq) { + int64_t left = (oldFreq - newFreq) > 0 ? (oldFreq - newFreq) : 1; + fromFreqs[GetStmtID()] = left; + } + } + node->thenPart = thenPart->CloneTreeWithFreqs(allocator, toFreqs, fromFreqs, numer, denom, updateOp); + if (elsePart != nullptr) { + node->elsePart = elsePart->CloneTreeWithFreqs(allocator, toFreqs, fromFreqs, numer, denom, updateOp); + } + node->SetMeStmtID(GetMeStmtID()); + return node; + } + BaseNode *Opnd(size_t i = 0) const override { if (i == 0) { return UnaryStmtNode::Opnd(0); @@ -2520,6 +2549,26 @@ class WhileStmtNode : public UnaryStmtNode { return node; } + WhileStmtNode *CloneTreeWithFreqs(MapleAllocator &allocator, + std::unordered_map& toFreqs, + std::unordered_map& fromFreqs, + uint64_t numer, uint64_t denom, uint32_t updateOp) { + auto *node = allocator.GetMemPool()->New(*this); + node->SetStmtID(stmtIDNext++); + if (fromFreqs.count(GetStmtID()) > 0) { + int64_t oldFreq = fromFreqs[GetStmtID()]; + int64_t newFreq = denom > 0 ? (oldFreq * numer / denom) : oldFreq; + toFreqs[node->GetStmtID()] = newFreq > 0 ? newFreq : 1; + if (updateOp & kUpdateOrigFreq) { + int64_t left = (oldFreq - newFreq) > 0 ? (oldFreq - newFreq) : 1; + fromFreqs[GetStmtID()] = left; + } + } + node->SetOpnd(Opnd(0)->CloneTree(allocator), 0); + node->body = body->CloneTreeWithFreqs(allocator, toFreqs, fromFreqs, numer, denom, updateOp); + return node; + } + void SetBody(BlockNode *node) { body = node; } @@ -2571,6 +2620,38 @@ class DoloopNode : public StmtNode { return node; } + DoloopNode *CloneTreeWithFreqs(MapleAllocator &allocator, + std::unordered_map& toFreqs, + std::unordered_map& fromFreqs, + uint64_t numer, uint64_t denom, uint32_t updateOp) { + auto *node = allocator.GetMemPool()->New(*this); + node->SetStmtID(stmtIDNext++); + if (fromFreqs.count(GetStmtID()) > 0) { + int64_t oldFreq = fromFreqs[GetStmtID()]; + int64_t newFreq = oldFreq; + if (updateOp & kUpdateInlinedFreq) { // used in inline + newFreq = denom > 0 ? (oldFreq * numer / denom) : oldFreq; + } else if (updateOp & kUpdateUnrolledFreq) { // used in unrolled part + int64_t bodyFreq = fromFreqs[GetDoBody()->GetStmtID()]; + newFreq = denom > 0 ? (bodyFreq * numer / denom + (oldFreq - bodyFreq)) : oldFreq; + } else if (updateOp & kUpdateUnrollRemainderFreq) { // used in unrolled remainder + int64_t bodyFreq = fromFreqs[GetDoBody()->GetStmtID()]; + newFreq = denom > 0 ? (((bodyFreq * numer) % denom) + (oldFreq - bodyFreq)) : oldFreq; + } + toFreqs[node->GetStmtID()] = newFreq; + ASSERT(oldFreq >= newFreq, "sanity check"); + if (updateOp & kUpdateOrigFreq) { + int64_t left = oldFreq - newFreq; + fromFreqs[GetStmtID()] = left; + } + } + node->SetStartExpr(startExpr->CloneTree(allocator)); + node->SetContExpr(GetCondExpr()->CloneTree(allocator)); + node->SetIncrExpr(GetIncrExpr()->CloneTree(allocator)); + node->SetDoBody(GetDoBody()->CloneTreeWithFreqs(allocator, toFreqs, fromFreqs, numer, denom, updateOp)); + return node; + } + void SetDoVarStIdx(StIdx idx) { doVarStIdx = idx; } diff --git a/src/mapleall/maple_ir/src/mir_lower.cpp b/src/mapleall/maple_ir/src/mir_lower.cpp index 5456385a55..99dbd04c3f 100644 --- a/src/mapleall/maple_ir/src/mir_lower.cpp +++ b/src/mapleall/maple_ir/src/mir_lower.cpp @@ -137,6 +137,9 @@ LabelIdx MIRLower::CreateCondGotoStmt(Opcode op, BlockNode &blk, const IfStmtNod mirModule.CurFunction()->GetLabelTab()->AddToStringLabelMap(lableIdx); brStmt->SetOffset(lableIdx); blk.AddStatement(brStmt); + if (GetFuncProfData()) { + GetFuncProfData()->CopyStmtFreq(brStmt->GetStmtID(), ifStmt.GetStmtID()); + } bool thenEmpty = (ifStmt.GetThenPart() == nullptr) || (ifStmt.GetThenPart()->GetFirst() == nullptr); if (thenEmpty) { blk.AppendStatementsFromBlock(*ifStmt.GetElsePart()); @@ -151,6 +154,13 @@ void MIRLower::CreateBrFalseStmt(BlockNode &blk, const IfStmtNode &ifStmt) { auto *lableStmt = mirModule.CurFuncCodeMemPool()->New(); lableStmt->SetLabelIdx(labelIdx); blk.AddStatement(lableStmt); + // set stmtfreqs + if (GetFuncProfData()) { + ASSERT(GetFuncProfData()->GetStmtFreq(ifStmt.GetThenPart()->GetStmtID()) >= 0, "sanity check"); + int64_t freq = GetFuncProfData()->GetStmtFreq(ifStmt.GetStmtID()) - + GetFuncProfData()->GetStmtFreq(ifStmt.GetThenPart()->GetStmtID()); + GetFuncProfData()->SetStmtFreq(lableStmt->GetStmtID(), freq); + } } void MIRLower::CreateBrTrueStmt(BlockNode &blk, const IfStmtNode &ifStmt) { @@ -158,6 +168,13 @@ void MIRLower::CreateBrTrueStmt(BlockNode &blk, const IfStmtNode &ifStmt) { auto *lableStmt = mirModule.CurFuncCodeMemPool()->New(); lableStmt->SetLabelIdx(labelIdx); blk.AddStatement(lableStmt); + // set stmtfreqs + if (GetFuncProfData()) { + ASSERT(GetFuncProfData()->GetStmtFreq(ifStmt.GetElsePart()->GetStmtID()) >= 0, "sanity check"); + int64_t freq = GetFuncProfData()->GetStmtFreq(ifStmt.GetStmtID()) - + GetFuncProfData()->GetStmtFreq(ifStmt.GetElsePart()->GetStmtID()); + GetFuncProfData()->SetStmtFreq(lableStmt->GetStmtID(), freq); + } } @@ -171,15 +188,27 @@ void MIRLower::CreateBrFalseAndGotoStmt(BlockNode &blk, const IfStmtNode &ifStmt mirModule.CurFunction()->GetLabelTab()->AddToStringLabelMap(gotoLableIdx); gotoStmt->SetOffset(gotoLableIdx); blk.AddStatement(gotoStmt); + // set stmtfreqs + if (GetFuncProfData()) { + GetFuncProfData()->CopyStmtFreq(gotoStmt->GetStmtID(), ifStmt.GetThenPart()->GetStmtID()); + } } auto *lableStmt = mirModule.CurFuncCodeMemPool()->New(); lableStmt->SetLabelIdx(labelIdx); blk.AddStatement(lableStmt); blk.AppendStatementsFromBlock(*ifStmt.GetElsePart()); + // set stmtfreqs + if (GetFuncProfData()) { + GetFuncProfData()->CopyStmtFreq(lableStmt->GetStmtID(), ifStmt.GetElsePart()->GetStmtID()); + } if (fallThroughFromThen) { lableStmt = mirModule.CurFuncCodeMemPool()->New(); lableStmt->SetLabelIdx(gotoLableIdx); blk.AddStatement(lableStmt); + // set endlabel stmtfreqs + if (GetFuncProfData()) { + GetFuncProfData()->CopyStmtFreq(lableStmt->GetStmtID(), ifStmt.GetStmtID()); + } } } @@ -201,6 +230,9 @@ BlockNode *MIRLower::LowerIfStmt(IfStmtNode &ifStmt, bool recursive) { evalStmt->SetOpnd(ifStmt.Opnd(), 0); evalStmt->SetSrcPos(ifStmt.GetSrcPos()); blk->AddStatement(evalStmt); + if (GetFuncProfData()) { + GetFuncProfData()->CopyStmtFreq(evalStmt->GetStmtID(), ifStmt.GetStmtID()); + } } else if (elseEmpty) { // brfalse // @@ -313,14 +345,28 @@ BlockNode *MIRLower::LowerWhileStmt(WhileStmtNode &whileStmt) { auto *lableStmt = mirModule.CurFuncCodeMemPool()->New(); lableStmt->SetLabelIdx(bodyLableIdx); blk->AddStatement(lableStmt); + // update frequency + if (GetFuncProfData()) { + GetFuncProfData()->CopyStmtFreq(lableStmt->GetStmtID(), whileStmt.GetStmtID()); + GetFuncProfData()->CopyStmtFreq(brFalseStmt->GetStmtID(), whileStmt.GetStmtID()); + } blk->AppendStatementsFromBlock(*whileStmt.GetBody()); auto *brTrueStmt = mirModule.CurFuncCodeMemPool()->New(OP_brtrue); brTrueStmt->SetOpnd(whileStmt.Opnd(0)->CloneTree(mirModule.GetCurFuncCodeMPAllocator()), 0); brTrueStmt->SetOffset(bodyLableIdx); + if (GetFuncProfData() && blk->GetLast()) { + GetFuncProfData()->CopyStmtFreq(brTrueStmt->GetStmtID(), whileStmt.GetBody()->GetStmtID()); + } blk->AddStatement(brTrueStmt); lableStmt = mirModule.CurFuncCodeMemPool()->New(); lableStmt->SetLabelIdx(lalbeIdx); blk->AddStatement(lableStmt); + if (GetFuncProfData()) { + int64_t freq = GetFuncProfData()->GetStmtFreq(whileStmt.GetStmtID()) - + GetFuncProfData()->GetStmtFreq(brTrueStmt->GetStmtID()); + ASSERT(freq >= 0, "sanity check"); + GetFuncProfData()->SetStmtFreq(lableStmt->GetStmtID(), freq); + } return blk; } @@ -336,6 +382,11 @@ BlockNode *MIRLower::LowerWhileStmt(WhileStmtNode &whileStmt) { BlockNode *MIRLower::LowerDoloopStmt(DoloopNode &doloop) { ASSERT(doloop.GetDoBody() != nullptr, "nullptr check"); doloop.SetDoBody(LowerBlock(*doloop.GetDoBody())); + int64_t doloopnodeFreq = 0, bodynodeFreq = 0; + if (GetFuncProfData()) { + doloopnodeFreq = GetFuncProfData()->GetStmtFreq(doloop.GetStmtID()); + bodynodeFreq= GetFuncProfData()->GetStmtFreq(doloop.GetDoBody()->GetStmtID()); + } auto *blk = mirModule.CurFuncCodeMemPool()->New(); if (doloop.IsPreg()) { PregIdx regIdx = (PregIdx)doloop.GetDoVarStIdx().FullIdx(); @@ -355,17 +406,28 @@ BlockNode *MIRLower::LowerDoloopStmt(DoloopNode &doloop) { startDassign->SetSrcPos(doloop.GetSrcPos()); blk->AddStatement(startDassign); } + if (GetFuncProfData()) { + GetFuncProfData()->SetStmtFreq(blk->GetLast()->GetStmtID(), doloopnodeFreq - bodynodeFreq); + } auto *brFalseStmt = mirModule.CurFuncCodeMemPool()->New(OP_brfalse); brFalseStmt->SetOpnd(doloop.GetCondExpr(), 0); LabelIdx lIdx = mirModule.CurFunction()->GetLabelTab()->CreateLabel(); mirModule.CurFunction()->GetLabelTab()->AddToStringLabelMap(lIdx); brFalseStmt->SetOffset(lIdx); blk->AddStatement(brFalseStmt); + // udpate stmtFreq + if (GetFuncProfData()) { + GetFuncProfData()->SetStmtFreq(brFalseStmt->GetStmtID(), (doloopnodeFreq - bodynodeFreq)); + } LabelIdx bodyLabelIdx = mirModule.CurFunction()->GetLabelTab()->CreateLabel(); mirModule.CurFunction()->GetLabelTab()->AddToStringLabelMap(bodyLabelIdx); auto *labelStmt = mirModule.CurFuncCodeMemPool()->New(); labelStmt->SetLabelIdx(bodyLabelIdx); blk->AddStatement(labelStmt); + // udpate stmtFreq + if (GetFuncProfData()) { + GetFuncProfData()->SetStmtFreq(labelStmt->GetStmtID(), bodynodeFreq); + } blk->AppendStatementsFromBlock(*doloop.GetDoBody()); if (doloop.IsPreg()) { PregIdx regIdx = (PregIdx)doloop.GetDoVarStIdx().FullIdx(); @@ -398,9 +460,17 @@ BlockNode *MIRLower::LowerDoloopStmt(DoloopNode &doloop) { brTrueStmt->SetOpnd(doloop.GetCondExpr()->CloneTree(mirModule.GetCurFuncCodeMPAllocator()), 0); brTrueStmt->SetOffset(bodyLabelIdx); blk->AddStatement(brTrueStmt); + // udpate stmtFreq + if (GetFuncProfData()) { + GetFuncProfData()->SetStmtFreq(brTrueStmt->GetStmtID(), bodynodeFreq); + } labelStmt = mirModule.CurFuncCodeMemPool()->New(); labelStmt->SetLabelIdx(lIdx); blk->AddStatement(labelStmt); + // udpate stmtFreq + if (GetFuncProfData()) { + GetFuncProfData()->SetStmtFreq(labelStmt->GetStmtID(), (doloopnodeFreq - bodynodeFreq)); + } return blk; } @@ -430,6 +500,7 @@ BlockNode *MIRLower::LowerBlock(BlockNode &block) { auto *newBlock = mirModule.CurFuncCodeMemPool()->New(); BlockNode *tmp = nullptr; if (block.GetFirst() == nullptr) { + newBlock->SetStmtID(block.GetStmtID()); // keep original block stmtid return newBlock; } StmtNode *nextStmt = block.GetFirst(); @@ -468,6 +539,7 @@ BlockNode *MIRLower::LowerBlock(BlockNode &block) { break; } } while (nextStmt != nullptr); + newBlock->SetStmtID(block.GetStmtID()); // keep original block stmtid return newBlock; } diff --git a/src/mapleall/maple_ir/src/mir_nodes.cpp b/src/mapleall/maple_ir/src/mir_nodes.cpp index d0fde66285..991853f007 100755 --- a/src/mapleall/maple_ir/src/mir_nodes.cpp +++ b/src/mapleall/maple_ir/src/mir_nodes.cpp @@ -243,6 +243,66 @@ void BlockNode::InsertBlockAfter(BlockNode &inblock, const StmtNode *stmt1) { stmtNodeList.splice(stmt1, inblock.GetStmtNodes()); } +BlockNode *BlockNode::CloneTreeWithFreqs(MapleAllocator &allocator, + std::unordered_map& toFreqs, + std::unordered_map& fromFreqs, + uint64_t numer, uint64_t denom, uint32_t updateOp) { + auto *nnode = allocator.GetMemPool()->New(); + nnode->SetStmtID(stmtIDNext++); + if (fromFreqs.count(GetStmtID()) > 0) { + int64_t oldFreq = fromFreqs[GetStmtID()]; + int64_t newFreq; + if (updateOp & kUpdateUnrollRemainderFreq) { + newFreq = denom > 0 ? (oldFreq * numer % denom) : oldFreq; + } else { + newFreq = denom > 0 ? (oldFreq * numer / denom) : oldFreq; + } + toFreqs[nnode->GetStmtID()] = (newFreq > 0 || (oldFreq == 0)) ? newFreq : 1; + if (updateOp & kUpdateOrigFreq) { // upateOp & 1 : update from + int64_t left = ((oldFreq - newFreq) > 0 || (oldFreq == 0)) ? (oldFreq - newFreq) : 1; + fromFreqs[GetStmtID()] = left; + } + } + for (auto &stmt : stmtNodeList) { + StmtNode *newStmt; + if (stmt.GetOpCode() == OP_block) { + newStmt = static_cast((static_cast(&stmt))->CloneTreeWithFreqs(allocator, toFreqs, + fromFreqs, numer, denom, updateOp)); + } else if (stmt.GetOpCode() == OP_if) { + newStmt = static_cast((static_cast(&stmt))->CloneTreeWithFreqs(allocator, toFreqs, + fromFreqs, numer, denom, updateOp)); + } else if (stmt.GetOpCode() == OP_while) { + newStmt = static_cast((static_cast(&stmt))->CloneTreeWithFreqs(allocator, toFreqs, + fromFreqs, numer, denom, updateOp)); + } else if (stmt.GetOpCode() == OP_doloop) { + newStmt = static_cast((static_cast(&stmt))->CloneTreeWithFreqs(allocator, toFreqs, + fromFreqs, numer, denom, updateOp)); + } else { + newStmt = static_cast(stmt.CloneTree(allocator)); + if (fromFreqs.count(stmt.GetStmtID()) > 0) { + int64_t oldFreq = fromFreqs[stmt.GetStmtID()]; + int64_t newFreq; + if (updateOp & kUpdateUnrollRemainderFreq) { + newFreq = denom > 0 ? (oldFreq * numer % denom) : oldFreq; + } else { + newFreq = denom > 0 ? (oldFreq * numer / denom) : oldFreq; + } + toFreqs[newStmt->GetStmtID()] = (newFreq > 0 || oldFreq == 0) ? newFreq : 1; + if (updateOp & kUpdateOrigFreq) { + int64_t left = ((oldFreq - newFreq) > 0 || oldFreq == 0) ? (oldFreq - newFreq) : 1; + fromFreqs[stmt.GetStmtID()] = left; + } + } + } + ASSERT(newStmt != nullptr, "null ptr check"); + newStmt->SetSrcPos(stmt.GetSrcPos()); + newStmt->SetPrev(nullptr); + newStmt->SetNext(nullptr); + nnode->AddStatement(newStmt); + } + return nnode; +} + void BaseNode::DumpBase(int32 indent) const { PrintIndentation(indent); LogInfo::MapleLogger() << kOpcodeInfo.GetTableItemAt(GetOpCode()).name << " " << GetPrimTypeName(GetPrimType()); @@ -622,6 +682,11 @@ void StmtNode::DumpBase(int32 indent) const { LogInfo::MapleLogger() << "LOC " << srcPosition.FileNum() << " " << srcPosition.LineNum() << '\n'; lastPrintedLineNum = srcPosition.LineNum(); } + // dump stmtFreqs + if (Options::profileUse && theMIRModule->CurFunction()->GetFuncProfData() && + theMIRModule->CurFunction()->GetFuncProfData()->GetStmtFreq(GetStmtID()) >= 0) { + LogInfo::MapleLogger() << "stmtID " << GetStmtID() << " freq " << theMIRModule->CurFunction()->GetFuncProfData()->GetStmtFreq(GetStmtID()) << "\n"; + } PrintIndentation(indent); LogInfo::MapleLogger() << kOpcodeInfo.GetTableItemAt(GetOpCode()).name; } @@ -1261,6 +1326,10 @@ void BlockNode::Dump(int32 indent, const MIRSymbolTable *theSymTab, MIRPregTable LogInfo::MapleLogger() << "LOC " << srcPosition.FileNum() << " " << srcPosition.LineNum() << '\n'; lastPrintedLineNum = srcPosition.LineNum(); } + // dump stmtFreqs + if (Options::profileUse && theMIRModule->CurFunction()->GetFuncProfData()) { + LogInfo::MapleLogger() << "stmtID " << GetStmtID() << " freq " << theMIRModule->CurFunction()->GetFuncProfData()->GetStmtFreq(GetStmtID()) << "\n"; + } for (auto &stmt : GetStmtNodes()) { stmt.Dump(indent + 1); } @@ -1274,6 +1343,10 @@ void LabelNode::Dump(int32) const { LogInfo::MapleLogger() << "LOC " << srcPosition.FileNum() << " " << srcPosition.LineNum() << '\n'; lastPrintedLineNum = srcPosition.LineNum(); } + // dump stmtFreqs + if (Options::profileUse && theMIRModule->CurFunction()->GetFuncProfData()) { + LogInfo::MapleLogger() << "stmtID " << GetStmtID() << " freq " << theMIRModule->CurFunction()->GetFuncProfData()->GetStmtFreq(GetStmtID()) << "\n"; + } LogInfo::MapleLogger() << "@" << theMIRModule->CurFunction()->GetLabelName(labelIdx) << " "; } diff --git a/src/mapleall/maple_me/include/lfo_loop_vec.h b/src/mapleall/maple_me/include/lfo_loop_vec.h index 64cb44da33..b9e36ee298 100644 --- a/src/mapleall/maple_me/include/lfo_loop_vec.h +++ b/src/mapleall/maple_me/include/lfo_loop_vec.h @@ -58,6 +58,8 @@ class LoopVecInfo { void UpdateWidestTypeSize(uint32_t); void ResetStmtRHSTypeSize() { currentRHSTypeSize = 0; } bool UpdateRHSTypeSize(PrimType); // record rhs node typesize + // used when profileUse is true + void UpdateDoloopProfData(MIRFunction *, DoloopNode *, int32_t, bool isRemainder = false); uint32_t largestTypeSize; // largest size type in vectorizable stmtnodes uint32_t smallestTypeSize; // smallest size type in vectorizable stmtnodes uint32_t currentRHSTypeSize; // largest size of current stmt's RHS, this is temp value and update for each stmt diff --git a/src/mapleall/maple_me/include/pme_emit.h b/src/mapleall/maple_me/include/pme_emit.h index b54ce40558..fa791d3fba 100644 --- a/src/mapleall/maple_me/include/pme_emit.h +++ b/src/mapleall/maple_me/include/pme_emit.h @@ -78,6 +78,7 @@ class PreMeEmitter : public AnalysisResult { MapleAllocator* GetCodeMPAlloc() { return codeMPAlloc; } MapleMap *GetPreMeStmtExtensionMap() { return &PreMeStmtExtensionMap; } MapleMap *GetPreMeExprExtensionMap() { return &PreMeExprExtensionMap; } + GcovFuncInfo *GetFuncProfData() { return mirFunc->GetFuncProfData(); } private: ArrayNode *ConvertToArray(BaseNode *x, TyIdx ptrTyIdx); diff --git a/src/mapleall/maple_me/src/bb.cpp b/src/mapleall/maple_me/src/bb.cpp index 2cc46f4d86..1be0bb1bbc 100644 --- a/src/mapleall/maple_me/src/bb.cpp +++ b/src/mapleall/maple_me/src/bb.cpp @@ -80,6 +80,9 @@ void BB::DumpBBAttribute(const MIRModule *mod) const { void BB::DumpHeader(const MIRModule *mod) const { mod->GetOut() << "============BB id:" << GetBBId() << " " << StrAttribute() << " ["; DumpBBAttribute(mod); + if (Options::profileUse && frequency >= 0) { + mod->GetOut() << " freq: " << frequency << " "; + } mod->GetOut() << "]===============\n"; mod->GetOut() << "preds: "; for (const auto &predElement : pred) { @@ -89,6 +92,14 @@ void BB::DumpHeader(const MIRModule *mod) const { for (const auto &succElement : succ) { mod->GetOut() << succElement->GetBBId() << " "; } + // dump edge frequency + if (Options::profileUse && succFreq.size() > 0) { + mod->GetOut() << " succFreq [ "; + for (const auto &succFreq : succFreq) { + mod->GetOut() << succFreq << " "; + } + mod->GetOut() << " ]"; + } mod->GetOut() << '\n'; if (bbLabel != 0) { LabelNode lblNode; diff --git a/src/mapleall/maple_me/src/func_emit.cpp b/src/mapleall/maple_me/src/func_emit.cpp index f94edba275..61f3c49c29 100644 --- a/src/mapleall/maple_me/src/func_emit.cpp +++ b/src/mapleall/maple_me/src/func_emit.cpp @@ -21,6 +21,10 @@ void FuncEmit::EmitLabelForBB(MIRFunction &func, BB &bb) const { ASSERT(bb.GetBBLabel() != 0, "Should have a label"); // create labelnode LabelNode *label = func.GetCodeMempool()->New(); + // add freq for new added stmt node + if (Options::profileUse) { + func.SetStmtFreq(label->GetStmtID(), bb.GetFrequency()); + } label->SetLabelIdx(bb.GetBBLabel()); if (bb.IsEmpty()) { bb.SetFirst(label); diff --git a/src/mapleall/maple_me/src/irmap_emit.cpp b/src/mapleall/maple_me/src/irmap_emit.cpp index 42041f51db..824e7c7e53 100755 --- a/src/mapleall/maple_me/src/irmap_emit.cpp +++ b/src/mapleall/maple_me/src/irmap_emit.cpp @@ -714,6 +714,10 @@ void BB::EmitBB(SSATab &ssaTab, BlockNode &curblk, bool needAnotherPass) { bbFirstStmt = stmt; } bbLastStmt = stmt; + if (Options::profileUse && ssaTab.GetModule().CurFunction()->GetFuncProfData() && + (IsCallAssigned(stmt->GetOpCode()) || stmt->GetOpCode() == OP_call)) { + ssaTab.GetModule().CurFunction()->GetFuncProfData()->SetStmtFreq(stmt->GetStmtID(), frequency); + } } if (GetAttributes(kBBAttrIsTryEnd)) { // generate op_endtry @@ -726,5 +730,22 @@ void BB::EmitBB(SSATab &ssaTab, BlockNode &curblk, bool needAnotherPass) { } stmtNodeList.set_first(bbFirstStmt); stmtNodeList.set_last(bbLastStmt); + // set stmt freq + if (Options::profileUse && ssaTab.GetModule().CurFunction()->GetFuncProfData()) { + if (bbFirstStmt) { + ssaTab.GetModule().CurFunction()->GetFuncProfData()->SetStmtFreq(bbFirstStmt->GetStmtID(), frequency); + } + if (bbLastStmt && (bbFirstStmt != bbLastStmt)) { + ssaTab.GetModule().CurFunction()->GetFuncProfData()->SetStmtFreq(bbLastStmt->GetStmtID(), frequency); + } + if (stmtNodeList.empty()) { + auto *commentNode = ssaTab.GetModule().CurFunction()->GetCodeMempool()->New(ssaTab.GetModule()); + commentNode->SetComment("profileStmt"); + ssaTab.GetModule().CurFunction()->GetFuncProfData()->SetStmtFreq(commentNode->GetStmtID(), frequency); + curblk.AddStatement(commentNode); + stmtNodeList.set_first(commentNode); + stmtNodeList.set_last(commentNode); + } + } } } // namespace maple diff --git a/src/mapleall/maple_me/src/lfo_loop_vec.cpp b/src/mapleall/maple_me/src/lfo_loop_vec.cpp index c26e2eb02c..73186c4999 100644 --- a/src/mapleall/maple_me/src/lfo_loop_vec.cpp +++ b/src/mapleall/maple_me/src/lfo_loop_vec.cpp @@ -23,6 +23,44 @@ #define MAX_VECTOR_LENGTH_SIZE 128 namespace maple { + +void LoopVecInfo::UpdateDoloopProfData(MIRFunction *mirFunc, + DoloopNode *doloop, int32_t vecLanes, bool isRemainder) { + auto *profData = mirFunc->GetFuncProfData(); + if (!profData) return; + int64_t doloopFreq = profData->GetStmtFreq(doloop->GetStmtID()); + int64_t tempFreq; + BlockNode *body = doloop->GetDoBody(); + int64_t bodyFreq = profData->GetStmtFreq(body->GetStmtID()); + if (isRemainder) { + // update doloop node in remainder + tempFreq = (bodyFreq % vecLanes) + (doloopFreq - bodyFreq); + profData->SetStmtFreq(doloop->GetStmtID(), tempFreq); + // update doloop body freq in remainder + profData->SetStmtFreq(body->GetStmtID(), (bodyFreq % vecLanes)); + // update stmtlist in doloopbody + if (body->GetFirst()) { + profData->SetStmtFreq(body->GetFirst()->GetStmtID(), (bodyFreq % vecLanes)); + } + if (body->GetLast() && (body->GetFirst() != body->GetLast())) { + profData->SetStmtFreq(body->GetLast()->GetStmtID(), (bodyFreq % vecLanes)); + } + } else { + // vectorized doloop + tempFreq = (bodyFreq / vecLanes) + (doloopFreq - bodyFreq); + profData->SetStmtFreq(doloop->GetStmtID(), tempFreq); + // update doloop body freq + profData->SetStmtFreq(body->GetStmtID(), (bodyFreq / vecLanes)); + // update stmtlist in doloopbody + if (body->GetFirst()) { + profData->SetStmtFreq(body->GetFirst()->GetStmtID(), (tempFreq / vecLanes)); + } + if (body->GetLast() && (body->GetFirst() != body->GetLast())) { + profData->SetStmtFreq(body->GetLast()->GetStmtID(), (tempFreq / vecLanes)); + } + } +} + uint32_t LoopVectorization::vectorizedLoop = 0; void LoopVecInfo::UpdateWidestTypeSize(uint32_t newtypesize) { diff --git a/src/mapleall/maple_me/src/lfo_unroll.cpp b/src/mapleall/maple_me/src/lfo_unroll.cpp index 2fb44b0bc7..7cd7f5ed67 100644 --- a/src/mapleall/maple_me/src/lfo_unroll.cpp +++ b/src/mapleall/maple_me/src/lfo_unroll.cpp @@ -51,14 +51,33 @@ void LfoUnrollOneLoop::ReplaceIV(BaseNode *x, BaseNode *repNode) { } BlockNode *LfoUnrollOneLoop::DoFullUnroll(size_t tripCount) { - BlockNode *unrolledBlk = doloop->GetDoBody()->CloneTreeWithSrcPosition(*mirModule); + BlockNode *unrolledBlk; + size_t unrollTimes = tripCount; + if (Options::profileUse && preMeFunc->meFunc && preMeFunc->meFunc->GetMirFunc() && + preMeFunc->meFunc->GetMirFunc()->GetFuncProfData()) { + auto *profData = preMeFunc->meFunc->GetMirFunc()->GetFuncProfData(); + auto &stmtFreqs = profData->GetStmtFreqs(); + uint32 updateOp = (kKeepOrigFreq | kUpdateUnrolledFreq); + unrolledBlk = doloop->GetDoBody()->CloneTreeWithFreqs(mirModule->GetCurFuncCodeMPAllocator(), + stmtFreqs, stmtFreqs, 1 /*numor*/, unrollTimes/*denom*/, updateOp); + } else { + unrolledBlk = doloop->GetDoBody()->CloneTreeWithSrcPosition(*mirModule); + } ReplaceIV(unrolledBlk, doloop->GetStartExpr()); BlockNode *nextIterBlk = nullptr; tripCount--; uint32 i = 0; while (tripCount > 0) { i++; - nextIterBlk = doloop->GetDoBody()->CloneTreeWithSrcPosition(*mirModule); + if (Options::profileUse && preMeFunc->meFunc && preMeFunc->meFunc->GetMirFunc() && + preMeFunc->meFunc->GetMirFunc()->GetFuncProfData()) { + auto &stmtFreqs = preMeFunc->meFunc->GetMirFunc()->GetFuncProfData()->GetStmtFreqs(); + nextIterBlk = doloop->GetDoBody()->CloneTreeWithFreqs(mirModule->GetCurFuncCodeMPAllocator(), + stmtFreqs, stmtFreqs, 1 /*numor*/, unrollTimes/*denom*/, + (kKeepOrigFreq | kUpdateUnrolledFreq)); + } else { + nextIterBlk = doloop->GetDoBody()->CloneTreeWithSrcPosition(*mirModule); + } BaseNode *adjExpr = mirBuilder->CreateIntConst(stepAmount * i, ivPrimType); BaseNode *repExpr = codeMP->New(OP_add, ivPrimType, doloop->GetStartExpr(), adjExpr); ReplaceIV(nextIterBlk, repExpr); @@ -78,10 +97,27 @@ BlockNode *LfoUnrollOneLoop::DoUnroll(size_t times, size_t tripCount) { if (remainderTripCount == 0) { unrolledBlk = codeMP->New(); } else if (remainderTripCount == 1) { - unrolledBlk = doloop->GetDoBody()->CloneTreeWithSrcPosition(*mirModule); + if (Options::profileUse && preMeFunc->meFunc && preMeFunc->meFunc->GetMirFunc() && + preMeFunc->meFunc->GetMirFunc()->GetFuncProfData()) { + auto &stmtFreqs = preMeFunc->meFunc->GetMirFunc()->GetFuncProfData()->GetStmtFreqs(); + unrolledBlk = doloop->GetDoBody()->CloneTreeWithFreqs(mirModule->GetCurFuncCodeMPAllocator(), + stmtFreqs, stmtFreqs, 1/*numor*/, times/*denom*/, + (kKeepOrigFreq | kUpdateUnrollRemainderFreq)) ; + } else { + unrolledBlk = doloop->GetDoBody()->CloneTreeWithSrcPosition(*mirModule); + } ReplaceIV(unrolledBlk, doloop->GetStartExpr()); } else { - DoloopNode *remDoloop = doloop->CloneTree(*preEmit->GetCodeMPAlloc()); + DoloopNode *remDoloop; + if (Options::profileUse && preMeFunc->meFunc && preMeFunc->meFunc->GetMirFunc() && + preMeFunc->meFunc->GetMirFunc()->GetFuncProfData()) { + auto &stmtFreqs = preMeFunc->meFunc->GetMirFunc()->GetFuncProfData()->GetStmtFreqs(); + remDoloop = doloop->CloneTreeWithFreqs(mirModule->GetCurFuncCodeMPAllocator(), + stmtFreqs, stmtFreqs, 1/*numor*/, times/*denom*/, + (kKeepOrigFreq | kUpdateUnrollRemainderFreq)); + } else { + remDoloop = doloop->CloneTree(*preEmit->GetCodeMPAlloc()); + } // generate remDoloop's termination BaseNode *terminationRHS = codeMP->New(OP_add, ivPrimType, doloop->GetStartExpr()->CloneTree(*preEmit->GetCodeMPAlloc()), @@ -112,8 +148,15 @@ BlockNode *LfoUnrollOneLoop::DoUnroll(size_t times, size_t tripCount) { RegassignNode *rass = mirBuilder->CreateStmtRegassign(ivPrimType, regIdx, remLoopEndExpr); unrolledBlk = codeMP->New(); unrolledBlk->AddStatement(rass); - - DoloopNode *remDoloop = doloop->CloneTree(*preEmit->GetCodeMPAlloc()); + DoloopNode *remDoloop; + if (Options::profileUse && preMeFunc->meFunc && preMeFunc->meFunc->GetMirFunc() && + preMeFunc->meFunc->GetMirFunc()->GetFuncProfData()) { + auto &stmtFreqs = preMeFunc->meFunc->GetMirFunc()->GetFuncProfData()->GetStmtFreqs(); + remDoloop = doloop->CloneTreeWithFreqs(mirModule->GetCurFuncCodeMPAllocator(), + stmtFreqs, stmtFreqs, 1/*numor*/, times/*denom*/, (kUpdateUnrollRemainderFreq)); + } else { + remDoloop = doloop->CloneTree(*preEmit->GetCodeMPAlloc()); + } // generate remDoloop's termination BaseNode *terminationRHS = mirBuilder->CreateExprRegread(ivPrimType, regIdx); remDoloop->SetContExpr(codeMP->New(OP_lt, PTY_i32, ivPrimType, CloneIVNode(), terminationRHS)); @@ -121,11 +164,26 @@ BlockNode *LfoUnrollOneLoop::DoUnroll(size_t times, size_t tripCount) { } // form the unrolled loop - DoloopNode *unrolledDoloop = doloop->CloneTree(*preEmit->GetCodeMPAlloc()); + DoloopNode *unrolledDoloop; + if (Options::profileUse && preMeFunc->meFunc && preMeFunc->meFunc->GetMirFunc() && + preMeFunc->meFunc->GetMirFunc()->GetFuncProfData()) { + auto &stmtFreqs = preMeFunc->meFunc->GetMirFunc()->GetFuncProfData()->GetStmtFreqs(); + unrolledDoloop = doloop->CloneTreeWithFreqs(mirModule->GetCurFuncCodeMPAllocator(), + stmtFreqs, stmtFreqs, 1/*numor*/, times/*denom*/,(kKeepOrigFreq | kUpdateUnrolledFreq)); + } else { + unrolledDoloop = doloop->CloneTree(*preEmit->GetCodeMPAlloc()); + } uint32 i = 1; BlockNode *nextIterBlk = nullptr; do { - nextIterBlk = doloop->GetDoBody()->CloneTreeWithSrcPosition(*mirModule); + if (Options::profileUse && preMeFunc->meFunc && preMeFunc->meFunc->GetMirFunc() && + preMeFunc->meFunc->GetMirFunc()->GetFuncProfData()) { + auto &stmtFreqs = preMeFunc->meFunc->GetMirFunc()->GetFuncProfData()->GetStmtFreqs(); + nextIterBlk = doloop->GetDoBody()->CloneTreeWithFreqs(mirModule->GetCurFuncCodeMPAllocator(), + stmtFreqs, stmtFreqs, 1/*numor*/, times/*denom*/, (kKeepOrigFreq | kUpdateUnrolledFreq)); + } else { + nextIterBlk = doloop->GetDoBody()->CloneTreeWithSrcPosition(*mirModule); + } BaseNode *adjExpr = mirBuilder->CreateIntConst(stepAmount * i, ivPrimType); BaseNode *repExpr = codeMP->New(OP_add, ivPrimType, CloneIVNode(), adjExpr); ReplaceIV(nextIterBlk, repExpr); @@ -237,7 +295,7 @@ void LfoUnrollOneLoop::Process() { if (fullUnroll) { unrolledBlk = DoFullUnroll(tripCount); } else { - if (MeOption::optLevel <= 2 || unrollTimes == 1) { + if (MeOption::optLevel < 2 || unrollTimes == 1) { // changeback linma return; } unrolledBlk = DoUnroll(unrollTimes, tripCount); diff --git a/src/mapleall/maple_me/src/me_cfg.cpp b/src/mapleall/maple_me/src/me_cfg.cpp index 0f6b7fef3f..3f65ff3c98 100644 --- a/src/mapleall/maple_me/src/me_cfg.cpp +++ b/src/mapleall/maple_me/src/me_cfg.cpp @@ -1812,19 +1812,71 @@ void MeCFG::ConstructBBFreqFromStmtFreq() { if (!gcovData) return; GcovFuncInfo* funcData = gcovData->GetFuncProfile(func.GetUniqueID()); if (!funcData) return; + if (funcData->stmtFreqs.size() == 0) return; auto eIt = valid_end(); for (auto bIt = valid_begin(); bIt != eIt; ++bIt) { if ((*bIt)->IsEmpty()) continue; - StmtNode first = (*bIt)->GetFirst(); + StmtNode& first = (*bIt)->GetFirst(); if (funcData->stmtFreqs.count(first.GetStmtID()) > 0) { (*bIt)->SetFrequency(funcData->stmtFreqs[first.GetStmtID()]); + } else if (funcData->stmtFreqs.count((*bIt)->GetLast().GetStmtID()) > 0) { + (*bIt)->SetFrequency(funcData->stmtFreqs[(*bIt)->GetLast().GetStmtID()]); } else { - StmtNode last = (*bIt)->GetLast(); - if (funcData->stmtFreqs.count(last.GetStmtID()) > 0) { - (*bIt)->SetFrequency(funcData->stmtFreqs[last.GetStmtID()]); + LogInfo::MapleLogger() << "ERROR:: bb " << (*bIt)->GetBBId() << "frequency is not set" << "\n"; + ASSERT(0, "no freq set"); + } + } + // add common entry and common exit + auto *bb = *common_entry(); + uint64_t freq = 0; + for (int i = 0; i < bb->GetSucc().size(); i++) { + freq += bb->GetSucc(i)->GetFrequency(); + } + bb->SetFrequency(freq); + bb = *common_exit(); + freq = 0; + for (int i = 0; i < bb->GetPred().size(); i++) { + freq += bb->GetPred(i)->GetFrequency(); + } + bb->SetFrequency(freq); + // set succfreqs + for (auto bIt = valid_begin(); bIt != eIt; ++bIt) { + auto *bb = *bIt; + if (!bb) continue; + int64_t succSum = 0; // verify only + if (bb->GetSucc().size() == 1) { + bb->PushBackSuccFreq(bb->GetFrequency()); + } else if (bb->GetSucc().size() == 2) { + auto *fallthru = bb->GetSucc(0); + auto *targetBB = bb->GetSucc(1); + if (targetBB->GetFrequency() >= bb->GetFrequency()) { + // fixup frequency of target bb + uint32_t fallthruFreq = fallthru->GetFrequency(); + for (int i = 0; i < fallthru->GetPred().size(); i++) { + auto *pred = fallthru->GetPred(i); + if (pred->GetSucc().size() == 1 && (pred != bb)) { + fallthruFreq -= pred->GetFrequency(); + } + } + bb->PushBackSuccFreq(fallthruFreq); + bb->PushBackSuccFreq(bb->GetFrequency() - fallthruFreq); + } else { + bb->PushBackSuccFreq(fallthru->GetFrequency()); + bb->PushBackSuccFreq(targetBB->GetFrequency()); + } + } else if (bb->GetSucc().size() > 2) { + // switch case + for (int i = 0; i < bb->GetSucc().size(); i++) { + bb->PushBackSuccFreq(bb->GetSucc(i)->GetFrequency()); + succSum += bb->GetSucc(i)->GetFrequency(); + } + if (succSum != bb->GetFrequency()) { + LogInfo::MapleLogger() << "ERROR:: bb " << bb->GetBBId() << "frequency inconsistent with sum of succs" << "\n"; } } } + // clear stmtFreqs since cfg frequency is create + funcData->stmtFreqs.clear(); } void MeCFG::ConstructStmtFreq() { diff --git a/src/mapleall/maple_me/src/me_critical_edge.cpp b/src/mapleall/maple_me/src/me_critical_edge.cpp index b04a72496f..0d2f2046fa 100644 --- a/src/mapleall/maple_me/src/me_critical_edge.cpp +++ b/src/mapleall/maple_me/src/me_critical_edge.cpp @@ -178,7 +178,8 @@ void MeSplitCEdge::BreakCriticalEdge(MeFunction &func, BB &pred, BB &succ) const } // profileGen invokes MESplitCEdge to remove critical edges without going through ME completely // newBB needs to be materialized - if (Options::profileGen) { + if (Options::profileGen || + (Options::profileUse && (func.IsPme() || func.IsLfo()))) { LabelIdx succLabel = succ.GetBBLabel(); ASSERT(succLabel != 0, "succ's label missed"); if (func.GetIRMap() != nullptr) { @@ -291,7 +292,14 @@ void MESplitCEdge::GetAnalysisDependence(maple::AnalysisDep &aDep) const { bool MESplitCEdge::PhaseRun(maple::MeFunction &f) { bool enableDebug = DEBUGFUNC_NEWPM(f); MeSplitCEdge mscedge = MeSplitCEdge(enableDebug); - (void)mscedge.SplitCriticalEdgeForMeFunc(f); + bool split = mscedge.SplitCriticalEdgeForMeFunc(f); + if (split && Options::profileUse && (f.IsPme() || f.IsLfo()) && f.GetPreMeFunc()) { + // new inserted BB will break while/if label information and IR layout + f.GetPreMeFunc()->label2IfInfo.clear(); + f.GetPreMeFunc()->label2WhileInfo.clear(); + f.GetPreMeFunc()->pmeCreatedIfLabelSet.clear(); + f.GetPreMeFunc()->pmeCreatedWhileLabelSet.clear(); + } return false; } } // namespace maple diff --git a/src/mapleall/maple_me/src/me_emit.cpp b/src/mapleall/maple_me/src/me_emit.cpp index a9ea2a21a4..ebb2b45889 100644 --- a/src/mapleall/maple_me/src/me_emit.cpp +++ b/src/mapleall/maple_me/src/me_emit.cpp @@ -78,6 +78,10 @@ bool MEEmit::PhaseRun(maple::MeFunction &f) { mirFunction->ReleaseCodeMemory(); mirFunction->SetMemPool(new ThreadLocalMemPool(memPoolCtrler, "IR from IRMap::Emit()")); mirFunction->SetBody(mirFunction->GetCodeMempool()->New()); + if (Options::profileUse && mirFunction->GetFuncProfData()) { + mirFunction->GetFuncProfData()->SetStmtFreq(mirFunction->GetBody()->GetStmtID(), + mirFunction->GetFuncProfData()->entry_freq); + } // initialize is_deleted field to true; will reset when emitting Maple IR for (size_t k = 1; k < mirFunction->GetSymTab()->GetSymbolTableSize(); ++k) { MIRSymbol *sym = mirFunction->GetSymTab()->GetSymbolFromStIdx(k); @@ -137,6 +141,10 @@ bool MEEmit::PhaseRun(maple::MeFunction &f) { f.GetCfg()->DumpToFile("meemit", true); } } + // TODO:: set funcProfData null, enable only after cglower could update stmtFreqs + if (Options::profileUse && f.GetMirFunc()->GetFuncProfData()) { + f.GetMirFunc()->SetFuncProfData(nullptr); + } return false; } diff --git a/src/mapleall/maple_me/src/me_profile_use.cpp b/src/mapleall/maple_me/src/me_profile_use.cpp index 6c23f958dc..7c6eb2fda9 100644 --- a/src/mapleall/maple_me/src/me_profile_use.cpp +++ b/src/mapleall/maple_me/src/me_profile_use.cpp @@ -298,8 +298,8 @@ bool MeProfUse::GcovRun() { GcovProfileData* gcovData = func->GetMIRModule().GetGcovProfile(); if (!gcovData) return false; GcovFuncInfo* funcData = gcovData->GetFuncProfile(func->GetUniqueID()); - func->GetMirFunc()->SetFuncProfData(funcData); if (!funcData) return false; + func->GetMirFunc()->SetFuncProfData(funcData); // early return if lineno fail uint64 linenohash = ComputeLinenoHash(); uint32 lineNoChkSum = static_cast((linenohash >> 32) ^ (linenohash & 0xffffffff)); @@ -308,6 +308,7 @@ bool MeProfUse::GcovRun() { LogInfo::MapleLogger() << func->GetName() << " lineno checksum doesn't match gcda value " << funcData->lineno_checksum << " lineno real hash " << lineNoChkSum << '\n'; } + func->GetMirFunc()->SetFuncProfData(nullptr); // clear func profile data return false; } FindInstrumentEdges(); @@ -331,6 +332,7 @@ bool MeProfUse::GcovRun() { LogInfo::MapleLogger() << func->GetName() << " counter doesn't match profile counter " << funcData->num_counts << " func real counter " << instrumentBBs.size() << '\n'; } + func->GetMirFunc()->SetFuncProfData(nullptr); // clear func profile data return false; } size_t i = 0; diff --git a/src/mapleall/maple_me/src/pme_emit.cpp b/src/mapleall/maple_me/src/pme_emit.cpp index 0c980bc7dd..4e6c7b2ab9 100755 --- a/src/mapleall/maple_me/src/pme_emit.cpp +++ b/src/mapleall/maple_me/src/pme_emit.cpp @@ -738,6 +738,8 @@ StmtNode* PreMeEmitter::EmitPreMeStmt(MeStmt *mestmt, BaseNode *parent) { void PreMeEmitter::EmitBB(BB *bb, BlockNode *curblk) { CHECK_FATAL(curblk != nullptr, "null ptr check"); + bool setFirstFreq = (GetFuncProfData() != nullptr); + bool setLastFreq = false; // emit head. label LabelIdx labidx = bb->GetBBLabel(); if (labidx != 0 && !preMeFunc->WhileLabelCreatedByPreMe(labidx) && !preMeFunc->IfLabelCreatedByPreMe(labidx)) { @@ -747,12 +749,24 @@ void PreMeEmitter::EmitBB(BB *bb, BlockNode *curblk) { curblk->AddStatement(lbnode); PreMeMIRExtension *pmeExt = preMeMP->New(curblk); PreMeStmtExtensionMap[lbnode->GetStmtID()] = pmeExt; + if (GetFuncProfData()) { + GetFuncProfData()->SetStmtFreq(lbnode->GetStmtID(), bb->GetFrequency()); + } } for (auto& mestmt : bb->GetMeStmts()) { StmtNode *stmt = EmitPreMeStmt(&mestmt, curblk); if (!stmt) // can be null i.e, a goto to a label that was created by lno lower continue; curblk->AddStatement(stmt); + // add for first stmt in bb in curblk + if (GetFuncProfData() != nullptr) { + if (setFirstFreq || (stmt->GetOpCode() == OP_call) || (stmt->GetOpCode() == OP_callassigned)) { + GetFuncProfData()->SetStmtFreq(stmt->GetStmtID(), bb->GetFrequency()); + setFirstFreq = false; + } else { + setLastFreq = true; + } + } } if (bb->GetAttributes(kBBAttrIsTryEnd)) { /* generate op_endtry */ @@ -760,6 +774,15 @@ void PreMeEmitter::EmitBB(BB *bb, BlockNode *curblk) { curblk->AddStatement(endtry); PreMeMIRExtension *pmeExt = preMeMP->New(curblk); PreMeStmtExtensionMap[endtry->GetStmtID()] = pmeExt; + setLastFreq = true; + } + // add stmtnode to last + if (GetFuncProfData()) { + if (setLastFreq) { + GetFuncProfData()->SetStmtFreq(curblk->GetLast()->GetStmtID(), bb->GetFrequency()); + } else { + LogInfo::MapleLogger() << " bb " << bb->GetBBId() << "no stmt used to add frequency\n"; + } } } @@ -796,6 +819,10 @@ DoloopNode *PreMeEmitter::EmitPreMeDoloop(BB *mewhilebb, BlockNode *curblk, PreM Doloopnode->SetIncrExpr(constnode); Doloopnode->SetIsPreg(false); curblk->AddStatement(Doloopnode); + // add stmtfreq + if (GetFuncProfData()) { + GetFuncProfData()->SetStmtFreq(Doloopnode->GetStmtID(), mewhilebb->GetFrequency()); + } return Doloopnode; } @@ -812,6 +839,10 @@ WhileStmtNode *PreMeEmitter::EmitPreMeWhile(BB *meWhilebb, BlockNode *curblk) { PreMeMIRExtension *whilenodeExt = preMeMP->New(Whilestmt); PreMeStmtExtensionMap[whilebodyNode->GetStmtID()] = whilenodeExt; Whilestmt->SetBody(whilebodyNode); + // add stmtfreq + if (GetFuncProfData()) { + GetFuncProfData()->SetStmtFreq(Whilestmt->GetStmtID(), meWhilebb->GetFrequency()); + } curblk->AddStatement(Whilestmt); return Whilestmt; } @@ -854,12 +885,18 @@ uint32 PreMeEmitter::Raise2PreMeWhile(uint32 curj, BlockNode *curblk) { "Raise2PreMeWhile: cannot find IV increment"); dobody->RemoveStmt(dassnode); } + // set dobody freq + if (GetFuncProfData()) { + int64_t freq = (endlblbb == suc0) ? suc1->GetFrequency() : suc0->GetFrequency(); + GetFuncProfData()->SetStmtFreq(dobody->GetStmtID(), freq); + } return curj; } uint32 PreMeEmitter::Raise2PreMeIf(uint32 curj, BlockNode *curblk) { MapleVector &bbvec = cfg->GetAllBBs(); BB *curbb = bbvec[curj]; + bool setFirstFreq = (GetFuncProfData() != nullptr); // emit BB contents before the if statement LabelIdx labidx = curbb->GetBBLabel(); if (labidx != 0 && !preMeFunc->IfLabelCreatedByPreMe(labidx)) { @@ -873,6 +910,11 @@ uint32 PreMeEmitter::Raise2PreMeIf(uint32 curj, BlockNode *curblk) { while (mestmt->GetOp() != OP_brfalse && mestmt->GetOp() != OP_brtrue) { StmtNode *stmt = EmitPreMeStmt(mestmt, curblk); curblk->AddStatement(stmt); + if (setFirstFreq) { + // add frequency of first stmt of curbb + GetFuncProfData()->SetStmtFreq(stmt->GetStmtID(), curbb->GetFrequency()); + setFirstFreq = false; + } mestmt = mestmt->GetNext(); } // emit the if statement @@ -906,6 +948,10 @@ uint32 PreMeEmitter::Raise2PreMeIf(uint32 curj, BlockNode *curblk) { IfstmtNode->SetOpnd(condnode, 0); IfstmtNode->SetMeStmtID(condgoto->GetMeStmtId()); curblk->AddStatement(IfstmtNode); + if (GetFuncProfData()) { + // set ifstmt freq + GetFuncProfData()->SetStmtFreq(IfstmtNode->GetStmtID(), curbb->GetFrequency()); + } PreMeMIRExtension *ifpmeExt = preMeMP->New(IfstmtNode); if (ifInfo->elseLabel != 0) { // both else and then are not empty; BlockNode *elseBlk = codeMP->New(); @@ -927,6 +973,11 @@ uint32 PreMeEmitter::Raise2PreMeIf(uint32 curj, BlockNode *curblk) { while (j != endmebb->GetBBId()) { j = EmitPreMeBB(j, elseBlk); } + if (GetFuncProfData()) { + // set then part/else part frequency + GetFuncProfData()->SetStmtFreq(thenBlk->GetStmtID(), bbvec[curj+1]->GetFrequency()); + GetFuncProfData()->SetStmtFreq(elseBlk->GetStmtID(), elsemebb->GetFrequency()); + } CHECK_FATAL(j < bbvec.size(), ""); return j; } else { // there is only then or else part in this if stmt @@ -947,6 +998,13 @@ uint32 PreMeEmitter::Raise2PreMeIf(uint32 curj, BlockNode *curblk) { j = EmitPreMeBB(j, branchBlock); } CHECK_FATAL(j < bbvec.size(), ""); + if (GetFuncProfData()) { + // set then part/else part frequency + int64_t ifFreq = GetFuncProfData()->GetStmtFreq(IfstmtNode->GetStmtID()); + int64_t branchFreq = bbvec[curj+1]->GetFrequency(); + GetFuncProfData()->SetStmtFreq(branchBlock->GetStmtID(), branchFreq); + GetFuncProfData()->SetStmtFreq(emptyBlock->GetStmtID(), (ifFreq - branchFreq)); + } return j; } } @@ -954,7 +1012,7 @@ uint32 PreMeEmitter::Raise2PreMeIf(uint32 curj, BlockNode *curblk) { uint32 PreMeEmitter::EmitPreMeBB(uint32 curj, BlockNode *curblk) { MapleVector &bbvec = cfg->GetAllBBs(); BB *mebb = bbvec[curj]; - if (!mebb || mebb == cfg->GetCommonEntryBB() || mebb == cfg->GetCommonEntryBB()) { + if (!mebb || mebb == cfg->GetCommonEntryBB() || mebb == cfg->GetCommonExitBB()) { return curj + 1; } if (mebb->GetBBLabel() != 0) { @@ -1000,6 +1058,10 @@ bool MEPreMeEmission::PhaseRun(MeFunction &f) { emitter = preMeMP->New(hmap, f.GetPreMeFunc(), preMeMP); BlockNode *curblk = mirfunction->GetCodeMempool()->New(); mirfunction->SetBody(curblk); + // restore bb frequency to stmt + if (Options::profileUse && emitter->GetFuncProfData()) { + emitter->GetFuncProfData()->SetStmtFreq(curblk->GetStmtID(), emitter->GetFuncProfData()->entry_freq); + } uint32 i = 0; while (i < f.GetCfg()->GetAllBBs().size()) { i = emitter->EmitPreMeBB(i, curblk); diff --git a/src/mapleall/maple_me/src/pme_mir_lower.cpp b/src/mapleall/maple_me/src/pme_mir_lower.cpp index 7c5f870f64..ca281bfbe6 100644 --- a/src/mapleall/maple_me/src/pme_mir_lower.cpp +++ b/src/mapleall/maple_me/src/pme_mir_lower.cpp @@ -41,11 +41,20 @@ BlockNode *PreMeMIRLower::LowerWhileStmt(WhileStmtNode &whilestmt) { brfalsestmt->SetSrcPos(whilestmt.GetSrcPos()); // add jump label target later blk->AddStatement(brfalsestmt); - + // update frequency + if (GetFuncProfData()) { + ASSERT(GetFuncProfData()->GetStmtFreq(whilestmt.GetStmtID()) >= 0, "while stmt should has freq"); + GetFuncProfData()->CopyStmtFreq(whilelblstmt->GetStmtID(), whilestmt.GetStmtID()); + GetFuncProfData()->CopyStmtFreq(brfalsestmt->GetStmtID(), whilestmt.GetStmtID()); + } // create body CHECK_FATAL(whilestmt.GetBody(), "null ptr check"); blk->AppendStatementsFromBlock(*whilestmt.GetBody()); GotoNode *whilegotonode = mirbuilder->CreateStmtGoto(OP_goto, whilelblidx); + if (GetFuncProfData() && blk->GetLast()) { + ASSERT(GetFuncProfData()->GetStmtFreq(blk->GetLast()->GetStmtID()) >= 0, "last stmt of while body should has freq"); + GetFuncProfData()->CopyStmtFreq(whilegotonode->GetStmtID(), blk->GetLast()->GetStmtID()); + } blk->AddStatement(whilegotonode); // create endlabel LabelIdx endlblidx = mirModule.CurFunction()->GetLabelTab()->CreateLabelWithPrefix('w'); @@ -55,6 +64,12 @@ BlockNode *PreMeMIRLower::LowerWhileStmt(WhileStmtNode &whilestmt) { endlblstmt->SetLabelIdx(endlblidx); brfalsestmt->SetOffset(endlblidx); blk->AddStatement(endlblstmt); + if (GetFuncProfData()) { + int64_t freq = GetFuncProfData()->GetStmtFreq(whilestmt.GetStmtID()) - + GetFuncProfData()->GetStmtFreq(whilegotonode->GetStmtID()); + ASSERT(freq >= 0, "sanity check"); + GetFuncProfData()->SetStmtFreq(endlblstmt->GetStmtID(), freq); + } return blk; } @@ -97,6 +112,9 @@ BlockNode *PreMeMIRLower::LowerIfStmt(IfStmtNode &ifstmt, bool recursive) { evalstmt->SetOpnd(ifstmt.Opnd(), 0); evalstmt->SetSrcPos(ifstmt.GetSrcPos()); blk->AddStatement(evalstmt); + if (GetFuncProfData()) { + GetFuncProfData()->CopyStmtFreq(evalstmt->GetStmtID(), ifstmt.GetStmtID()); + } } else if (elseempty) { // brfalse // @@ -112,7 +130,10 @@ BlockNode *PreMeMIRLower::LowerIfStmt(IfStmtNode &ifstmt, bool recursive) { PreMeIfInfo *ifInfo = preMeFunc->pmemp->New(); brfalsestmt->SetOffset(endlabelidx); blk->AddStatement(brfalsestmt); - + // set stmtfreqs + if (GetFuncProfData()) { + GetFuncProfData()->CopyStmtFreq(brfalsestmt->GetStmtID(), ifstmt.GetStmtID()); + } blk->AppendStatementsFromBlock(*ifstmt.GetThenPart()); LabelNode *labstmt = mirModule.CurFuncCodeMemPool()->New(); @@ -122,6 +143,13 @@ BlockNode *PreMeMIRLower::LowerIfStmt(IfStmtNode &ifstmt, bool recursive) { preMeFunc->label2IfInfo.insert(std::make_pair(endlabelidx, ifInfo)); } blk->AddStatement(labstmt); + // set stmtfreqs + if (GetFuncProfData()) { + ASSERT(GetFuncProfData()->GetStmtFreq(ifstmt.GetThenPart()->GetStmtID()) >= 0, "sanity check"); + int64_t freq = GetFuncProfData()->GetStmtFreq(ifstmt.GetStmtID()) - + GetFuncProfData()->GetStmtFreq(ifstmt.GetThenPart()->GetStmtID()); + GetFuncProfData()->SetStmtFreq(labstmt->GetStmtID(), freq); + } } else if (thenempty) { // brtrue // @@ -138,6 +166,10 @@ BlockNode *PreMeMIRLower::LowerIfStmt(IfStmtNode &ifstmt, bool recursive) { brtruestmt->SetOffset(endlabelidx); blk->AddStatement(brtruestmt); + // set stmtfreqs + if (GetFuncProfData()) { + GetFuncProfData()->CopyStmtFreq(brtruestmt->GetStmtID(), ifstmt.GetStmtID()); + } blk->AppendStatementsFromBlock(*ifstmt.GetElsePart()); LabelNode *labstmt = mirModule.CurFuncCodeMemPool()->New(); labstmt->SetLabelIdx(endlabelidx); @@ -146,6 +178,13 @@ BlockNode *PreMeMIRLower::LowerIfStmt(IfStmtNode &ifstmt, bool recursive) { preMeFunc->label2IfInfo.insert(std::make_pair(endlabelidx, ifInfo)); } blk->AddStatement(labstmt); + // set stmtfreqs + if (GetFuncProfData()) { + ASSERT(GetFuncProfData()->GetStmtFreq(ifstmt.GetElsePart()->GetStmtID()) > 0, "sanity check"); + int64_t freq = GetFuncProfData()->GetStmtFreq(ifstmt.GetStmtID()) - + GetFuncProfData()->GetStmtFreq(ifstmt.GetElsePart()->GetStmtID()); + GetFuncProfData()->SetStmtFreq(labstmt->GetStmtID(), freq); + } } else { // brfalse // @@ -156,6 +195,10 @@ BlockNode *PreMeMIRLower::LowerIfStmt(IfStmtNode &ifstmt, bool recursive) { CondGotoNode *brfalsestmt = mirModule.CurFuncCodeMemPool()->New(OP_brfalse); brfalsestmt->SetOpnd(ifstmt.Opnd(), 0); brfalsestmt->SetSrcPos(ifstmt.GetSrcPos()); + // set stmtfreqs + if (GetFuncProfData()) { + GetFuncProfData()->CopyStmtFreq(brfalsestmt->GetStmtID(), ifstmt.GetStmtID()); + } LabelIdx elselabelidx = mirFunc->GetLabelTab()->CreateLabelWithPrefix('s'); mirFunc->GetLabelTab()->AddToStringLabelMap(elselabelidx); if (canRaiseBack) { @@ -182,6 +225,10 @@ BlockNode *PreMeMIRLower::LowerIfStmt(IfStmtNode &ifstmt, bool recursive) { } gotostmt->SetOffset(endlabelidx); blk->AddStatement(gotostmt); + // set stmtfreqs + if (GetFuncProfData()) { + GetFuncProfData()->CopyStmtFreq(gotostmt->GetStmtID(), ifstmt.GetThenPart()->GetStmtID()); + } } LabelNode *labstmt = mirModule.CurFuncCodeMemPool()->New(); @@ -194,6 +241,10 @@ BlockNode *PreMeMIRLower::LowerIfStmt(IfStmtNode &ifstmt, bool recursive) { labstmt = mirModule.CurFuncCodeMemPool()->New(); labstmt->SetLabelIdx(endlabelidx); blk->AddStatement(labstmt); + // set stmtfreqs + if (GetFuncProfData()) { + GetFuncProfData()->CopyStmtFreq(labstmt->GetStmtID(), ifstmt.GetElsePart()->GetStmtID()); + } } if (endlabelidx == 0) { // create end label endlabelidx = mirFunc->GetLabelTab()->CreateLabelWithPrefix('e'); @@ -202,6 +253,10 @@ BlockNode *PreMeMIRLower::LowerIfStmt(IfStmtNode &ifstmt, bool recursive) { } LabelNode *endlabelnode = mirbuilder->CreateStmtLabel(endlabelidx); blk->AddStatement(endlabelnode); + // set stmtfreqs + if (GetFuncProfData()) { + GetFuncProfData()->CopyStmtFreq(endlabelnode->GetStmtID(), ifstmt.GetStmtID()); + } } ifInfo->endLabel = endlabelidx; } diff --git a/src/mapleall/maple_phase/include/phases.def b/src/mapleall/maple_phase/include/phases.def index d8705b4270..13f6f39ad1 100644 --- a/src/mapleall/maple_phase/include/phases.def +++ b/src/mapleall/maple_phase/include/phases.def @@ -14,9 +14,8 @@ ADDMODULEPHASE("callgraph", Options::O2 && Options::useInline && !Options::profi ADDMODULEPHASE("simplify", Options::O2 && !Options::genLMBC) ADDMODULEPHASE("ConstantFold", Options::O2) // ipa phase manager -ADDMODULEPHASE("ipaprofile", CLANG && Options::profileUse) -ADDMODULEPHASE("IpaSccPM", CLANG && (Options::O2 || Options::profileGen)) -ADDMODULEPHASE("inline", CLANG && (Options::O2 && Options::profileUse)) +ADDMODULEPHASE("IpaSccPM", CLANG && (Options::O2 || Options::profileGen || Options::profileUse)) +ADDMODULEPHASE("inline", CLANG && (Options::O2 && Options::useInline && Options::profileUse)) ADDMODULEPHASE("ipaclone", CLANG && Options::O2 && Options::enableIPAClone) ADDMODULEPHASE("ProfileGenPM", CLANG && Options::profileGen) // me phase manager is also a phase itself. diff --git a/src/mapleall/maple_util/include/gcov_profile.h b/src/mapleall/maple_util/include/gcov_profile.h index 0ff02f8154..3c30e62428 100644 --- a/src/mapleall/maple_util/include/gcov_profile.h +++ b/src/mapleall/maple_util/include/gcov_profile.h @@ -10,32 +10,60 @@ typedef unsigned gcov_unsigned_t; typedef int64_t gcov_type; typedef uint64_t gcov_type_unsigned; typedef unsigned location_t; +#define HOTCALLSITEFREQ 100 + +enum UpdateFreqOp { + kKeepOrigFreq = 0, + kUpdateOrigFreq = 0x1, + kUpdateInlinedFreq = 0x2, + kUpdateUnrolledFreq = 0x4, + kUpdateUnrollRemainderFreq = 0x8, +}; class GcovFuncInfo { public: GcovFuncInfo(MapleAllocator* alloc, unsigned funcIdent, unsigned lineno_cs, unsigned cfg_cs) : ident(funcIdent), lineno_checksum(lineno_cs), cfg_checksum(cfg_cs), counts(alloc->Adapter()) {}; + ~GcovFuncInfo() = default; + int64_t GetFuncFrequency() const { return entry_freq; } - void SetStmtFreq(uint32_t stmtID, int64_t freq) { - stmtFreqs[stmtID] = freq; + void SetFuncFrequency(int64_t freq) { entry_freq = freq; } + + std::unordered_map& GetStmtFreqs() { + return stmtFreqs; } int64_t GetStmtFreq(uint32_t stmtID) { if (stmtFreqs.count(stmtID) > 0) { return stmtFreqs[stmtID]; } - return 0; + return -1; // unstored + } + void SetStmtFreq(uint32_t stmtID, int64_t freq) { + stmtFreqs[stmtID] = freq; + } + void EraseStmtFreq(uint32_t stmtID) { + stmtFreqs.erase(stmtID); + } + void CopyStmtFreq(uint32_t newStmtID, uint32_t origStmtId, bool deleteOld = false) { + ASSERT(GetStmtFreq(origStmtId) >= 0, "origStmtId no freq record"); + SetStmtFreq(newStmtID, GetStmtFreq(origStmtId)); + if (deleteOld) { + EraseStmtFreq(origStmtId); + } + } + bool IsHotCallSite(uint32_t stmtID) { + if (stmtFreqs.count(stmtID) > 0) { + uint64 freq = stmtFreqs[stmtID]; + return (freq >= HOTCALLSITEFREQ); + } + ASSERT(0, "should not be here"); + return false; } - - /* Name of function. */ - char *name; unsigned ident; unsigned lineno_checksum; unsigned cfg_checksum; - /* Array of basic blocks. Like in GCC, the entry block is - at blocks[0] and the exit block is at blocks[1]. */ - - /* Raw arc coverage counts. */ + // Raw arc coverage counts. unsigned num_counts; MapleVector counts; int64_t entry_freq; // record entry bb frequence diff --git a/src/mapleall/mpl2mpl/include/call_graph.h b/src/mapleall/mpl2mpl/include/call_graph.h index fef62f0501..f7e313e7fc 100644 --- a/src/mapleall/mpl2mpl/include/call_graph.h +++ b/src/mapleall/mpl2mpl/include/call_graph.h @@ -337,7 +337,9 @@ class CGNode : public BaseGraphNode { } return sccIdentity; } - + // check frequency + int64_t GetFuncFrequency() const; + int64_t GetCallsiteFrequency(const StmtNode *callstmt) const; private: // mirFunc is generated from callStmt's puIdx from mpl instruction // mirFunc will be nullptr if CGNode represents an external/intrinsic call diff --git a/src/mapleall/mpl2mpl/src/call_graph.cpp b/src/mapleall/mpl2mpl/src/call_graph.cpp index d760cfafea..0ac862dce6 100644 --- a/src/mapleall/mpl2mpl/src/call_graph.cpp +++ b/src/mapleall/mpl2mpl/src/call_graph.cpp @@ -92,6 +92,9 @@ const std::string CallInfo::GetCalleeName() const { void CGNode::DumpDetail() const { LogInfo::MapleLogger() << "---CGNode @" << this << ": " << mirFunc->GetName() << "\t"; + if (Options::profileUse && mirFunc->GetFuncProfData()) { + LogInfo::MapleLogger() << " Ffreq " << GetFuncFrequency() << "\t"; + } if (HasOneCandidate() != nullptr) { LogInfo::MapleLogger() << "@One Candidate\n"; } else { @@ -112,6 +115,10 @@ void CGNode::DumpDetail() const { } else { LogInfo::MapleLogger() << "\tcallee external: " << ci->GetCalleeName(); } + if (Options::profileUse) { + LogInfo::MapleLogger() << " callsite freq" << GetCallsiteFrequency(ci->GetCallStmt()); + } + LogInfo::MapleLogger() << "\n"; } } // dump caller @@ -186,6 +193,24 @@ bool CGNode::IsCalleeOf(CGNode *func) const { return callers.find(func) != callers.end(); } +int64_t CGNode::GetCallsiteFrequency(const StmtNode *callstmt) const { + GcovFuncInfo *funcInfo = mirFunc->GetFuncProfData(); + if (funcInfo->stmtFreqs.count(callstmt->GetStmtID()) > 0) { + return funcInfo->stmtFreqs[callstmt->GetStmtID()]; + } + ASSERT(0, "should not be here"); + return -1; +} + +int64_t CGNode::GetFuncFrequency() const { + GcovFuncInfo *funcInfo = mirFunc->GetFuncProfData(); + if (funcInfo) { + return funcInfo->GetFuncFrequency(); + } + ASSERT(0, "should not be here"); + return 0; +} + void CallGraph::ClearFunctionList() { for (auto iter = mirModule->GetFunctionList().begin(); iter != mirModule->GetFunctionList().end();) { if (GlobalTables::GetFunctionTable().GetFunctionFromPuidx((*iter)->GetPuidx()) == nullptr) { diff --git a/src/mapleall/mpl2mpl/src/gcov_parser.cpp b/src/mapleall/mpl2mpl/src/gcov_parser.cpp index 8256011d07..c1d26e2fd3 100644 --- a/src/mapleall/mpl2mpl/src/gcov_parser.cpp +++ b/src/mapleall/mpl2mpl/src/gcov_parser.cpp @@ -95,21 +95,18 @@ static unsigned program_count; int MGcovParser::read_count_file() { std::string gcovDataFile = Options::profile; if (gcovDataFile.empty()) { - const std::string& fileName = m.GetFileName(); - std::string::size_type lastDot = fileName.find_last_of('.'); - ASSERT(lastDot != std::string::npos, "sanity check"); - // search default directory if (const char* env_p = std::getenv("GCOV_PREFIX")) { gcovDataFile.append(env_p); } else { gcovDataFile.append("."); } gcovDataFile.append("/"); - gcovDataFile.append(fileName.substr(0, lastDot)); - gcovDataFile.append(".gcda"); + gcovDataFile.append(m.GetProfileDataFileName()); } + ASSERT(!gcovDataFile.empty(), "null check"); if (!gcov_open(gcovDataFile.c_str(), 1)) { LogInfo::MapleLogger() << "no data file " << gcovDataFile << " \n"; + Options::profileUse = false; // reset profileUse return 0; } @@ -125,7 +122,11 @@ int MGcovParser::read_count_file() { GCOV_UNSIGNED2STRING (e, GCOV_VERSION); LogInfo::MapleLogger() << gcovDataFile << " version " << v << " prefer version " << e << "\n"; } + // read stam value, stamp is generated by time function + // the value should be same in .gcno file but skip compare here + // bbg_stamp unsigned tag = gcov_read_unsigned (); + gcovData = localMP->New(&alloc); GcovFuncInfo *funcInfo = nullptr; while ((tag = gcov_read_unsigned ())) { @@ -181,7 +182,7 @@ void M2MGcovParser::GetAnalysisDependence(AnalysisDep &aDep) const { } bool M2MGcovParser::PhaseRun(maple::MIRModule &m) { - MemPool *memPool = GetPhaseMemPool(); + MemPool *memPool = m.GetMemPool(); // use global pool to store gcov data MGcovParser gcovParser(m, memPool, true); int res = gcovParser.read_count_file(); diff --git a/src/mapleall/mpl2mpl/src/inline.cpp b/src/mapleall/mpl2mpl/src/inline.cpp index 8d0d2ed688..2349977e18 100644 --- a/src/mapleall/mpl2mpl/src/inline.cpp +++ b/src/mapleall/mpl2mpl/src/inline.cpp @@ -87,6 +87,10 @@ void MInline::InitParams() { } void MInline::InitProfile() const { + // gcov use different profile data, return + if (Options::profileUse) { + return; + } uint32 dexNameIdx = module.GetFileinfo(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName("INFO_filename")); const std::string &dexName = GlobalTables::GetStrTable().GetStringFromStrIdx(GStrIdx(dexNameIdx)); bool deCompressSucc = module.GetProfile().DeCompress(Options::profile, dexName); @@ -546,9 +550,18 @@ GotoNode *MInline::UpdateReturnStmts(const MIRFunction &caller, BlockNode &newBo dStmt = builder.CreateStmtRegassign(mirPreg->GetPrimType(), pregIdx, currBaseNode); } dStmt->SetSrcPos(stmt.GetSrcPos()); + if (Options::profileUse) { + caller.GetFuncProfData()->CopyStmtFreq(dStmt->GetStmtID(), stmt.GetStmtID()); + caller.GetFuncProfData()->CopyStmtFreq(gotoNode->GetStmtID(), stmt.GetStmtID()); + caller.GetFuncProfData()->EraseStmtFreq(stmt.GetStmtID()); + } newBody.ReplaceStmt1WithStmt2(&stmt, dStmt); newBody.InsertAfter(dStmt, gotoNode); } else { + if (Options::profileUse) { + caller.GetFuncProfData()->CopyStmtFreq(gotoNode->GetStmtID(), stmt.GetStmtID()); + caller.GetFuncProfData()->EraseStmtFreq(stmt.GetStmtID()); + } newBody.ReplaceStmt1WithStmt2(&stmt, gotoNode); } break; @@ -716,11 +729,26 @@ bool MInline::PerformInline(MIRFunction &caller, BlockNode &enclosingBlk, CallNo // multiple definition for these static symbols ConvertPStaticToFStatic(callee); // Step 1: Clone CALLEE's body. - auto getBody = [callee, this] (BlockNode* funcBody) { + auto getBody = [caller, callee, this] (BlockNode* funcBody, CallNode &callStmt) { if (callee.IsFromMpltInline()) { return funcBody->CloneTree(module.GetCurFuncCodeMPAllocator()); } - return funcBody->CloneTreeWithSrcPosition(module); + if (Options::profileUse) { + auto *callerProfData = caller.GetFuncProfData(); + auto *calleeProfData = callee.GetFuncProfData(); + ASSERT(callerProfData && calleeProfData, "nullptr check"); + int64_t callsiteFreq = callerProfData->GetStmtFreq(callStmt.GetStmtID()); + int64_t calleeEntryFreq = calleeProfData->GetFuncFrequency(); + auto *blockNode = funcBody->CloneTreeWithFreqs(module.GetCurFuncCodeMPAllocator(), + callerProfData->GetStmtFreqs(), + calleeProfData->GetStmtFreqs(), + callsiteFreq, calleeEntryFreq, (kUpdateOrigFreq | kUpdateInlinedFreq)); + // update func Frequency + calleeProfData->SetFuncFrequency(calleeEntryFreq - callsiteFreq); + return blockNode; + } else { + return funcBody->CloneTreeWithSrcPosition(module); + } }; BlockNode *newBody = nullptr; @@ -736,7 +764,7 @@ bool MInline::PerformInline(MIRFunction &caller, BlockNode &enclosingBlk, CallNo } if (currFuncBody == nullptr) { // For Inline recursive, we save the original function body before first inline. - currFuncBody = getBody(callee.GetBody()); + currFuncBody = getBody(callee.GetBody(), callStmt); // update inlining levels if (recursiveFuncToInlineLevel.find(&callee) != recursiveFuncToInlineLevel.end()) { recursiveFuncToInlineLevel[&callee]++; @@ -744,10 +772,11 @@ bool MInline::PerformInline(MIRFunction &caller, BlockNode &enclosingBlk, CallNo recursiveFuncToInlineLevel[&callee] = 1; } } - newBody = getBody(currFuncBody); + newBody = getBody(currFuncBody, callStmt); } else { - newBody = getBody(callee.GetBody()); + newBody = getBody(callee.GetBody(), callStmt); } + // Step 2: Rename symbols, labels, pregs uint32 stIdxOff = RenameSymbols(caller, callee, inlinedTimes); uint32 labIdxOff = RenameLabels(caller, callee, inlinedTimes); @@ -804,6 +833,9 @@ bool MInline::PerformInline(MIRFunction &caller, BlockNode &enclosingBlk, CallNo DassignNode *stmt = builder.CreateStmtDassign(*newFormal, 0, currBaseNode); newBody->InsertBefore(newBody->GetFirst(), stmt); } + if (Options::profileUse) { + caller.GetFuncProfData()->CopyStmtFreq(newBody->GetFirst()->GetStmtID(), callStmt.GetStmtID()); + } } // Step 5: Insert the callee'return jump dest label. // For caller: a = foo() ==> @@ -819,6 +851,9 @@ bool MInline::PerformInline(MIRFunction &caller, BlockNode &enclosingBlk, CallNo retLabIdx = CreateReturnLabel(caller, callee, inlinedTimes); labelStmt = builder.CreateStmtLabel(retLabIdx); newBody->AddStatement(labelStmt); + if (Options::profileUse) { + caller.GetFuncProfData()->CopyStmtFreq(labelStmt->GetStmtID(), callStmt.GetStmtID()); + } } // Step 6: Handle return values. // Find the rval of call-stmt @@ -860,6 +895,11 @@ bool MInline::PerformInline(MIRFunction &caller, BlockNode &enclosingBlk, CallNo } } } + if (Options::profileUse && (labelStmt != nullptr) && + (newBody->GetLast() == labelStmt)) { + caller.GetFuncProfData()->CopyStmtFreq(labelStmt->GetStmtID(), callStmt.GetStmtID()); + } + // Step 7: Replace the call-stmt with new CALLEE'body. // begin inlining function if (!Options::noComment) { @@ -870,7 +910,11 @@ bool MInline::PerformInline(MIRFunction &caller, BlockNode &enclosingBlk, CallNo (void)beginCmt.append(kSecondInlineBeginComment); } beginCmt.append(callee.GetName()); - enclosingBlk.InsertBefore(&callStmt, builder.CreateStmtComment(beginCmt.c_str())); + StmtNode *commNode = builder.CreateStmtComment(beginCmt.c_str()); + enclosingBlk.InsertBefore(&callStmt, commNode); + if (Options::profileUse) { + caller.GetFuncProfData()->CopyStmtFreq(commNode->GetStmtID(), callStmt.GetStmtID()); + } // end inlining function MapleString endCmt(module.CurFuncCodeMemPool()); if (module.firstInline) { @@ -882,7 +926,11 @@ bool MInline::PerformInline(MIRFunction &caller, BlockNode &enclosingBlk, CallNo if (enclosingBlk.GetLast() != nullptr && &callStmt != enclosingBlk.GetLast()) { CHECK_FATAL(callStmt.GetNext() != nullptr, "null ptr check"); } - enclosingBlk.InsertAfter(&callStmt, builder.CreateStmtComment(endCmt.c_str())); + commNode = builder.CreateStmtComment(endCmt.c_str()); + enclosingBlk.InsertAfter(&callStmt, commNode); + if (Options::profileUse) { + caller.GetFuncProfData()->CopyStmtFreq(commNode->GetStmtID(), callStmt.GetStmtID()); + } CHECK_FATAL(callStmt.GetNext() != nullptr, "null ptr check"); } if (newBody->IsEmpty()) { @@ -1195,6 +1243,10 @@ bool MInline::IsHotCallSite(const MIRFunction &caller, const MIRFunction &callee LogInfo::MapleLogger() << "[CHECK_HOT] " << callee.GetName() << " to " << caller.GetName() << " op " << callStmt.GetOpCode() << '\n'; } + // use gcov profile + if (Options::profileUse) { + return caller.GetFuncProfData()->IsHotCallSite(callStmt.GetStmtID()); + } return module.GetProfile().CheckFuncHot(caller.GetName()); } diff --git a/src/mapleall/mpl2mpl/src/module_phase_manager.cpp b/src/mapleall/mpl2mpl/src/module_phase_manager.cpp index f1a99cd1bf..18cace5950 100644 --- a/src/mapleall/mpl2mpl/src/module_phase_manager.cpp +++ b/src/mapleall/mpl2mpl/src/module_phase_manager.cpp @@ -16,7 +16,7 @@ #include "me_phase_manager.h" #include "ipa_phase_manager.h" #include "ipa_side_effect.h" -#include "ipa_gcovprofile.h" +#include "gcov_parser.h" #define JAVALANG (mirModule.IsJavaModule()) #define CLANG (mirModule.IsCModule()) @@ -110,7 +110,6 @@ MAPLE_ANALYSIS_PHASE_REGISTER(M2MKlassHierarchy, classhierarchy) MAPLE_ANALYSIS_PHASE_REGISTER(M2MAnnotationAnalysis, annotationanalysis) MAPLE_ANALYSIS_PHASE_REGISTER(ProfileGenPM, ProfileGenPM) MAPLE_ANALYSIS_PHASE_REGISTER(M2MGcovParser, gcovparser) -MAPLE_ANALYSIS_PHASE_REGISTER(IpaProfile, ipaprofile) MAPLE_TRANSFORM_PHASE_REGISTER(M2MInline, inline) MAPLE_TRANSFORM_PHASE_REGISTER(M2MIPODevirtualize, ipodevirtulize) -- Gitee From 5e681cbd8375f2b9c4cbeb9da43d606bcb10eb1f Mon Sep 17 00:00:00 2001 From: linma Date: Mon, 16 May 2022 21:28:40 -0700 Subject: [PATCH 2/3] change lfo fullunroll condition same as trunk --- src/mapleall/maple_me/src/lfo_unroll.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mapleall/maple_me/src/lfo_unroll.cpp b/src/mapleall/maple_me/src/lfo_unroll.cpp index 7cd7f5ed67..40a328c37c 100644 --- a/src/mapleall/maple_me/src/lfo_unroll.cpp +++ b/src/mapleall/maple_me/src/lfo_unroll.cpp @@ -295,7 +295,7 @@ void LfoUnrollOneLoop::Process() { if (fullUnroll) { unrolledBlk = DoFullUnroll(tripCount); } else { - if (MeOption::optLevel < 2 || unrollTimes == 1) { // changeback linma + if (MeOption::optLevel <= 2 || unrollTimes == 1) { // changeback linma return; } unrolledBlk = DoUnroll(unrollTimes, tripCount); -- Gitee From 22890107afbc4453ab9287dd35ff58c92d188bb4 Mon Sep 17 00:00:00 2001 From: linma Date: Mon, 16 May 2022 22:35:50 -0700 Subject: [PATCH 3/3] delete useless comment --- src/mapleall/maple_me/src/lfo_unroll.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mapleall/maple_me/src/lfo_unroll.cpp b/src/mapleall/maple_me/src/lfo_unroll.cpp index 40a328c37c..95a6fb71cd 100644 --- a/src/mapleall/maple_me/src/lfo_unroll.cpp +++ b/src/mapleall/maple_me/src/lfo_unroll.cpp @@ -295,7 +295,7 @@ void LfoUnrollOneLoop::Process() { if (fullUnroll) { unrolledBlk = DoFullUnroll(tripCount); } else { - if (MeOption::optLevel <= 2 || unrollTimes == 1) { // changeback linma + if (MeOption::optLevel <= 2 || unrollTimes == 1) { return; } unrolledBlk = DoUnroll(unrollTimes, tripCount); -- Gitee