From 6a38c8916fad91371e166c831eb35898c3b6e21a Mon Sep 17 00:00:00 2001 From: linma Date: Thu, 21 Jul 2022 13:19:17 -0700 Subject: [PATCH 01/16] pgo: rewrite profile data parser to accept maple profile data format --- src/mapleall/maple_ipa/src/ipa_clone.cpp | 4 +- .../maple_ipa/src/ipa_phase_manager.cpp | 6 +- src/mapleall/maple_ir/include/mir_function.h | 8 +- src/mapleall/maple_ir/include/mir_lower.h | 2 +- src/mapleall/maple_ir/include/mir_module.h | 13 +- .../maple_me/include/me_profile_use.h | 5 +- src/mapleall/maple_me/include/pme_emit.h | 2 +- src/mapleall/maple_me/src/me_cfg.cpp | 4 +- src/mapleall/maple_me/src/me_profile_use.cpp | 26 +- src/mapleall/maple_util/BUILD.gn | 1 + .../{gcov_profile.h => mpl_profdata.h} | 115 ++++-- src/mapleall/maple_util/include/namemangler.h | 5 + src/mapleall/maple_util/src/mpl_profdata.cpp | 53 +++ src/mapleall/maple_util/src/namemangler.cpp | 92 +++++ src/mapleall/mpl2mpl/BUILD.gn | 2 +- src/mapleall/mpl2mpl/include/gcov_parser.h | 117 ------ .../mpl2mpl/include/inline_transformer.h | 6 +- .../mpl2mpl/include/mpl_profdata_parser.h | 111 ++++++ src/mapleall/mpl2mpl/src/call_graph.cpp | 4 +- src/mapleall/mpl2mpl/src/gcov_parser.cpp | 359 ------------------ src/mapleall/mpl2mpl/src/gen_profile.cpp | 2 +- src/mapleall/mpl2mpl/src/inline.cpp | 4 +- .../mpl2mpl/src/inline_transformer.cpp | 17 +- .../mpl2mpl/src/module_phase_manager.cpp | 4 +- .../mpl2mpl/src/mpl_profdata_parser.cpp | 162 ++++++++ 25 files changed, 567 insertions(+), 557 deletions(-) rename src/mapleall/maple_util/include/{gcov_profile.h => mpl_profdata.h} (37%) create mode 100644 src/mapleall/maple_util/src/mpl_profdata.cpp delete mode 100644 src/mapleall/mpl2mpl/include/gcov_parser.h create mode 100644 src/mapleall/mpl2mpl/include/mpl_profdata_parser.h delete mode 100644 src/mapleall/mpl2mpl/src/gcov_parser.cpp create mode 100644 src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp diff --git a/src/mapleall/maple_ipa/src/ipa_clone.cpp b/src/mapleall/maple_ipa/src/ipa_clone.cpp index b439e6fe0f..86cb99ee51 100644 --- a/src/mapleall/maple_ipa/src/ipa_clone.cpp +++ b/src/mapleall/maple_ipa/src/ipa_clone.cpp @@ -140,9 +140,9 @@ MIRFunction *IpaClone::IpaCloneFunctionWithFreq(MIRFunction &originalFunction, newFunc->SetBaseClassFuncNames(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fullName)); newFunc->GetFuncSymbol()->SetAppearsInCode(true); newFunc->SetPuidxOrigin(newFunc->GetPuidx()); - GcovFuncInfo *origProfData = originalFunction.GetFuncProfData(); + FuncProfInfo *origProfData = originalFunction.GetFuncProfData(); auto *moduleMp = mirBuilder.GetMirModule().GetMemPool(); - GcovFuncInfo *newProfData = moduleMp->New(&mirBuilder.GetMirModule().GetMPAllocator(), + FuncProfInfo *newProfData = moduleMp->New(&mirBuilder.GetMirModule().GetMPAllocator(), newFunc->GetPuidx(), 0, 0); // skip checksum information newFunc->SetFuncProfData(newProfData); newProfData->SetFuncFrequency(callSiteFreq); diff --git a/src/mapleall/maple_ipa/src/ipa_phase_manager.cpp b/src/mapleall/maple_ipa/src/ipa_phase_manager.cpp index e2271b3f5f..d473d76cb5 100644 --- a/src/mapleall/maple_ipa/src/ipa_phase_manager.cpp +++ b/src/mapleall/maple_ipa/src/ipa_phase_manager.cpp @@ -14,7 +14,7 @@ */ #include "ipa_phase_manager.h" #include "pme_emit.h" -#include "gcov_parser.h" +#include "mpl_profdata_parser.h" #define JAVALANG (mirModule.IsJavaModule()) #define CLANG (mirModule.IsCModule()) @@ -102,8 +102,8 @@ void IpaSccPM::GetAnalysisDependence(maple::AnalysisDep &aDep) const { aDep.AddPreserved(); aDep.AddPreserved(); if (Options::profileUse) { - aDep.AddRequired(); - aDep.AddPreserved(); + aDep.AddRequired(); + aDep.AddPreserved(); } } diff --git a/src/mapleall/maple_ir/include/mir_function.h b/src/mapleall/maple_ir/include/mir_function.h index f6122d2ee4..51073f76f9 100644 --- a/src/mapleall/maple_ir/include/mir_function.h +++ b/src/mapleall/maple_ir/include/mir_function.h @@ -1258,13 +1258,13 @@ class MIRFunction { InlineSummary *GetOrCreateInlineSummary(); - void SetFuncProfData(GcovFuncInfo *data) { + void SetFuncProfData(FuncProfInfo *data) { funcProfData = data; } - GcovFuncInfo* GetFuncProfData() { + FuncProfInfo* GetFuncProfData() { return funcProfData; } - GcovFuncInfo* GetFuncProfData() const { + FuncProfInfo* GetFuncProfData() const { return funcProfData; } void SetStmtFreq(uint32_t stmtID, uint64_t freq) { @@ -1371,7 +1371,7 @@ class MIRFunction { uint32 nCtrs = 0; // number of counters uint64 fileLinenoChksum = 0; uint64 cfgChksum = 0; - GcovFuncInfo *funcProfData = nullptr; + FuncProfInfo *funcProfData = nullptr; InlineSummary *inlineSummary = nullptr; void DumpFlavorLoweredThanMmpl() const; MIRFuncType *ReconstructFormals(const std::vector &symbols, bool clearOldArgs); diff --git a/src/mapleall/maple_ir/include/mir_lower.h b/src/mapleall/maple_ir/include/mir_lower.h index c2261326d1..e4229aa853 100644 --- a/src/mapleall/maple_ir/include/mir_lower.h +++ b/src/mapleall/maple_ir/include/mir_lower.h @@ -142,7 +142,7 @@ class MIRLower { virtual bool InLFO() const { return false; } - GcovFuncInfo *GetFuncProfData() const { + FuncProfInfo *GetFuncProfData() const { return mirFunc->GetFuncProfData(); } void CopyStmtFrequency(StmtNode *newStmt, StmtNode *oldStmt) { diff --git a/src/mapleall/maple_ir/include/mir_module.h b/src/mapleall/maple_ir/include/mir_module.h index 37c54a99b3..be748df3f5 100644 --- a/src/mapleall/maple_ir/include/mir_module.h +++ b/src/mapleall/maple_ir/include/mir_module.h @@ -22,7 +22,7 @@ #include "muid.h" #include "profile.h" #include "namemangler.h" -#include "gcov_profile.h" +#include "mpl_profdata.h" #if MIR_FEATURE_FULL #include #include @@ -268,11 +268,11 @@ class MIRModule { return profile; } - GcovProfileData* GetGcovProfile() { - return gcovProfile; + MplProfileData* GetMapleProfile() { + return mplProfile; } - void SetGcovProfile(GcovProfileData* info) { - gcovProfile = info; + void SetMapleProfile(MplProfileData* info) { + mplProfile = info; } void SetSomeSymbolNeedForDecl(bool s) { @@ -345,7 +345,6 @@ class MIRModule { std::replace(profileDataFileName.begin(), profileDataFileName.end(), '.', '_'); std::replace(profileDataFileName.begin(), profileDataFileName.end(), '-', '_'); std::replace(profileDataFileName.begin(), profileDataFileName.end(), '/', '_'); - profileDataFileName = profileDataFileName + namemangler::kProfFileNameExt; return profileDataFileName; } @@ -710,7 +709,7 @@ class MIRModule { MapleSet symbolSet; MapleVector symbolDefOrder; Profile profile; - GcovProfileData* gcovProfile; + MplProfileData* mplProfile; bool someSymbolNeedForwDecl = false; // some symbols' addressses used in initialization std::ostream &out; diff --git a/src/mapleall/maple_me/include/me_profile_use.h b/src/mapleall/maple_me/include/me_profile_use.h index a6a0be8df7..2014e80026 100644 --- a/src/mapleall/maple_me/include/me_profile_use.h +++ b/src/mapleall/maple_me/include/me_profile_use.h @@ -137,8 +137,7 @@ class MeProfUse : public PGOInstrument { bool IsSuccUseProf() const { return succCalcuAllEdgeFreq; } - bool GcovRun(); - GcovFuncInfo *GetFuncData(); + bool MapleProfRun(); bool CheckSumFail(const uint64 hash, const uint32 expectedCheckSum, const std::string &tag); private: bool IsAllZero(Profile::BBInfo &result) const; @@ -147,6 +146,8 @@ class MeProfUse : public PGOInstrument { void ComputeEdgeFreq(); void InitBBEdgeInfo(); void ComputeBBFreq(BBUseInfo &bbInfo, bool &changed); + FuncProfInfo *GetFuncData(); + uint64 SumEdgesCount(const MapleVector &edges) const; BBUseInfo *GetBBUseInfo(const BB &bb) const; BBUseInfo *GetOrCreateBBUseInfo(const BB &bb) ; diff --git a/src/mapleall/maple_me/include/pme_emit.h b/src/mapleall/maple_me/include/pme_emit.h index 1a192138e6..19424dd4d1 100644 --- a/src/mapleall/maple_me/include/pme_emit.h +++ b/src/mapleall/maple_me/include/pme_emit.h @@ -79,7 +79,7 @@ class PreMeEmitter : public AnalysisResult { MapleAllocator* GetCodeMPAlloc() { return codeMPAlloc; } MapleMap *GetPreMeStmtExtensionMap() { return &PreMeStmtExtensionMap; } MapleMap *GetPreMeExprExtensionMap() { return &PreMeExprExtensionMap; } - GcovFuncInfo *GetFuncProfData() { return mirFunc->GetFuncProfData(); } + FuncProfInfo *GetFuncProfData() { return mirFunc->GetFuncProfData(); } private: ArrayNode *ConvertToArray(BaseNode *x, TyIdx ptrTyIdx); diff --git a/src/mapleall/maple_me/src/me_cfg.cpp b/src/mapleall/maple_me/src/me_cfg.cpp index bad79a8d57..a46f55b1da 100644 --- a/src/mapleall/maple_me/src/me_cfg.cpp +++ b/src/mapleall/maple_me/src/me_cfg.cpp @@ -1874,7 +1874,7 @@ void MeCFG::ConstructEdgeFreqFromBBFreq() { // set bb frequency from stmt record void MeCFG::ConstructBBFreqFromStmtFreq() { - GcovFuncInfo* funcData = func.GetMirFunc()->GetFuncProfData(); + FuncProfInfo* funcData = func.GetMirFunc()->GetFuncProfData(); if (!funcData) { return; } @@ -1914,7 +1914,7 @@ void MeCFG::ConstructBBFreqFromStmtFreq() { } void MeCFG::ConstructStmtFreq() { - GcovFuncInfo* funcData = func.GetMirFunc()->GetFuncProfData(); + FuncProfInfo* funcData = func.GetMirFunc()->GetFuncProfData(); if (!funcData) { return; } diff --git a/src/mapleall/maple_me/src/me_profile_use.cpp b/src/mapleall/maple_me/src/me_profile_use.cpp index 0a4d1ea0f7..4d9c62b6ad 100644 --- a/src/mapleall/maple_me/src/me_profile_use.cpp +++ b/src/mapleall/maple_me/src/me_profile_use.cpp @@ -294,12 +294,12 @@ bool MeProfUse::Run() { return true; } -GcovFuncInfo *MeProfUse::GetFuncData() { - GcovProfileData *gcovData = func->GetMIRModule().GetGcovProfile(); - if (!gcovData) { +FuncProfInfo *MeProfUse::GetFuncData() { + MplProfileData* profData = func->GetMIRModule().GetMapleProfile(); + if (!profData) { return nullptr; } - GcovFuncInfo *funcData = gcovData->GetFuncProfile(func->GetUniqueID()); + FuncProfInfo *funcData = profData->GetFuncProfile(func->GetUniqueID()); return funcData; } @@ -315,20 +315,20 @@ bool MeProfUse::CheckSumFail(const uint64 hash, const uint32 expectedCheckSum, c return false; } -bool MeProfUse::GcovRun() { - GcovFuncInfo *funcData = GetFuncData(); +bool MeProfUse::MapleProfRun() { + FuncProfInfo* funcData = GetFuncData(); if (!funcData) { return false; } func->GetMirFunc()->SetFuncProfData(funcData); // early return if lineno fail - if (CheckSumFail(ComputeLinenoHash(), funcData->lineno_checksum, "lineno")) { + if (CheckSumFail(ComputeLinenoHash(), funcData->linenoChecksum, "lineno")) { func->GetMirFunc()->SetFuncProfData(nullptr); // clear func profile data return false; } FindInstrumentEdges(); // early return if cfgchecksum fail - if (CheckSumFail(ComputeFuncHash(), funcData->cfg_checksum, "func")) { + if (CheckSumFail(ComputeFuncHash(), funcData->cfgChecksum, "func")) { return false; } std::vector instrumentBBs; @@ -336,10 +336,10 @@ bool MeProfUse::GcovRun() { if (dump) { DumpEdgeInfo(); } - if (instrumentBBs.size() != funcData->num_counts) { + if (instrumentBBs.size() != funcData->edgeCounts) { if (dump) { LogInfo::MapleLogger() << func->GetName() << " counter doesn't match profile counter " - << funcData->num_counts << " func real counter " << instrumentBBs.size() << '\n'; + << funcData->edgeCounts << " func real counter " << instrumentBBs.size() << '\n'; } func->GetMirFunc()->SetFuncProfData(nullptr); // clear func profile data return false; @@ -368,8 +368,10 @@ bool MEProfUse::PhaseRun(maple::MeFunction &f) { MeProfUse profUse(f, *GetPhaseMemPool(), DEBUGFUNC_NEWPM(f)); bool result = true; if (Options::profileUse) { - result = profUse.GcovRun(); - f.GetCfg()->VerifyBBFreq(); + result = profUse.MapleProfRun(); + if (result) { + f.GetCfg()->VerifyBBFreq(); + } } else { profUse.Run(); } diff --git a/src/mapleall/maple_util/BUILD.gn b/src/mapleall/maple_util/BUILD.gn index a7341eae06..09f912369e 100755 --- a/src/mapleall/maple_util/BUILD.gn +++ b/src/mapleall/maple_util/BUILD.gn @@ -27,6 +27,7 @@ src_libmplutil = [ "src/error_code.cpp", "src/thread_env.cpp", "src/mpl_int_val.cpp", + "src/mpl_profdata.cpp" ] src_libcommandline = [ diff --git a/src/mapleall/maple_util/include/gcov_profile.h b/src/mapleall/maple_util/include/mpl_profdata.h similarity index 37% rename from src/mapleall/maple_util/include/gcov_profile.h rename to src/mapleall/maple_util/include/mpl_profdata.h index baf50aa973..6aa8c1520f 100644 --- a/src/mapleall/maple_util/include/gcov_profile.h +++ b/src/mapleall/maple_util/include/mpl_profdata.h @@ -1,32 +1,26 @@ /* - * Copyright (c) [2022] Futurewei Technologies Co., Ltd. All rights reserved. + * Copyright (c) [2022] Futurewei Technologies, Inc. All rights reserved. * - * OpenArkCompiler is licensed under the Mulan Permissive Software License v2. - * You can use this software according to the terms and conditions of the MulanPSL - 2.0. - * You may obtain a copy of MulanPSL - 2.0 at: + * 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: * - * https://opensource.org/licenses/MulanPSL-2.0 + * 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 MulanPSL - 2.0 for more details. + * See the Mulan PSL v2 for more details. */ -#ifndef MAPLE_UTIL_INCLUDE_GCOV_PROFILE_H -#define MAPLE_UTIL_INCLUDE_GCOV_PROFILE_H - +#ifndef MAPLE_UTIL_INCLUDE_MPL_PROFDATA_H +#define MAPLE_UTIL_INCLUDE_MPL_PROFDATA_H #include "mempool_allocator.h" #include #include namespace maple { -using gcov_unsigned_t = unsigned; -using gcov_type = int64_t; -using gcov_type_unsigned = uint64_t; -using location_t = unsigned; #define HOTCALLSITEFREQ 100 - enum UpdateFreqOp { kKeepOrigFreq = 0, kUpdateOrigFreq = 0x1, @@ -35,11 +29,60 @@ enum UpdateFreqOp { kUpdateUnrollRemainderFreq = 0x8, }; -class GcovFuncInfo { +// used for record cumulative datas +struct ProfileSummaryHistogram { + uint32_t startValue; // count value range in [startValue, nextHistogramStart) + uint32_t countNums; // Number of counters whose profile count falls in countValue range. + uint64_t countMinVal; // Smallest profile count included in this range. + uint64_t countCumValue; // Cumulative value of the profile counts + + ProfileSummaryHistogram(uint32_t s, uint32_t num, uint64_t mincount, uint64_t cumcounts) : + startValue(s), countNums(num), countMinVal(mincount), countCumValue(cumcounts) { + } +}; + +class ProfileSummary { +public: + ProfileSummary(MapleAllocator* alloc) : histogram(alloc->Adapter()) {} + ProfileSummary(MapleAllocator *alloc, uint64_t checksum, uint32_t runtimes, + uint32_t totalcount, uint64_t maxcount, uint64_t sumcount) : + checkSum(checksum), run(runtimes), totalCount(totalcount), maxCount(maxcount), sumCount(sumcount), + histogram(alloc->Adapter()) {} + + void SetSummary(uint64_t checksum, uint32_t runtimes, uint32_t totalcount, uint64_t maxcount, uint64_t sumcount) { + checkSum = checksum; + run = runtimes; + totalCount = totalcount; + maxCount = maxcount; + sumCount = sumcount; + } + void AddHistogramRecord(uint32_t s, uint32_t num, uint64_t mincount, uint64_t cumcounts) { + histogram.push_back(ProfileSummaryHistogram(s, num, mincount, cumcounts)); + } + void DumpSummary(); + uint64_t GetCheckSum() { return checkSum; } + uint32_t GetRun() { return run; } + uint32_t GetTotalCount() { return totalCount; } + uint64_t GetMaxCount() { return maxCount; } + uint64_t GetSumCount() { return sumCount; } + uint32_t GetHistogramLength() { return histogram.size(); } + MapleVector& GetHistogram() { return histogram; } + +private: + uint64_t checkSum; // checksum value of module + uint32_t run; // run times + uint32_t totalCount; // number of counters + uint64_t maxCount; // max counter value in single run + uint64_t sumCount; // sum of all counters accumulated. + MapleVector histogram; // record gcov_bucket_type histogram[GCOV_HISTOGRAM_SIZE]; +}; + +class FuncProfInfo { 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; + FuncProfInfo(MapleAllocator* alloc, unsigned funcIdent, unsigned lineno_cs, + unsigned cfg_cs, unsigned countnum = 0) : ident(funcIdent), linenoChecksum(lineno_cs), + cfgChecksum(cfg_cs), edgeCounts(countnum), counts(alloc->Adapter()) {}; + ~FuncProfInfo() = default; uint64_t GetFuncFrequency() const { return entry_freq; } void SetFuncFrequency(uint64_t freq) { entry_freq = freq; } @@ -77,34 +120,48 @@ class GcovFuncInfo { ASSERT(0, "should not be here"); return false; } + void DumpFunctionProfile(); + unsigned ident; - unsigned lineno_checksum; - unsigned cfg_checksum; + unsigned linenoChecksum; + unsigned cfgChecksum; // Raw arc coverage counts. - unsigned num_counts; - MapleVector counts; + unsigned edgeCounts; + MapleVector counts; uint64_t entry_freq; // record entry bb frequence std::unordered_map stmtFreqs; // stmt_id is key, counter value uint64_t real_entryfreq; // function prof data may be modified after clone/inline }; -class GcovProfileData { +class MplProfileData { public: - GcovProfileData(MapleAllocator *alloc) : funcsCounter(alloc->Adapter()) {} + MplProfileData(MemPool *m, MapleAllocator *a) : funcsCounter(a->Adapter()), summary(a), mp(m), alloc(a) {} - GcovFuncInfo *GetFuncProfile(unsigned puidx) { + FuncProfInfo *GetFuncProfile(unsigned puidx) { if (funcsCounter.count(puidx) > 0) { return funcsCounter[puidx]; } return nullptr; } - void AddFuncProfile(unsigned puidx, GcovFuncInfo *funcData) { + FuncProfInfo *AddNewFuncProfile(unsigned puidx, unsigned lino_cs, unsigned cfg_cs, unsigned countnum) { + FuncProfInfo *funcProf = mp->New(alloc, puidx, lino_cs, cfg_cs, countnum); + ASSERT(funcsCounter.count(puidx) == 0, "sanity check"); + funcsCounter[puidx] = funcProf; + return funcProf; + } + void AddFuncProfile(unsigned puidx, FuncProfInfo *funcData) { ASSERT(funcsCounter.count(puidx) == 0, "sanity check"); funcsCounter[puidx] = funcData; } - MapleUnorderedMap funcsCounter; // use puidx as key + void DumpProfileData(); + void DumpFunctionsProfile(); + MapleUnorderedMap funcsCounter; // use puidx as key + // record module profile information and statistics of count information + ProfileSummary summary; +private: + MemPool *mp; + MapleAllocator *alloc; }; - } // end namespace -#endif // MAPLE_UTIL_INCLUDE_GCOV_PROFILE_H +#endif // MAPLE_UTIL_INCLUDE_MPL_PROFDATA_H diff --git a/src/mapleall/maple_util/include/namemangler.h b/src/mapleall/maple_util/include/namemangler.h index 250e9ef8ba..c1b21573fe 100644 --- a/src/mapleall/maple_util/include/namemangler.h +++ b/src/mapleall/maple_util/include/namemangler.h @@ -190,6 +190,7 @@ static constexpr const char kBindingProtectedRegionStr[] = "__BindingProtectRegi static constexpr const char kClassNamePrefixStr[] = "L"; static constexpr const char kClassMethodSplitterStr[] = "_3B"; static constexpr const char kFuncGetCurrentCl[] = "MCC_GetCurrentClassLoader"; +static constexpr const char kMplProfFileNameExt[] = ".mprofdata"; // Serve as a global flag to indicate whether frequent strings have been compressed extern bool doCompression; @@ -212,6 +213,10 @@ uint32_t GetUnsignedLeb128Decode(const uint8_t **data); size_t GetUleb128Size(uint64_t val); size_t GetSleb128Size(int32_t val); bool NeedConvertUTF16(const std::string &str8); +uint32_t EncodeSLEB128(int64_t Value, std::ofstream &out); +uint32_t EncodeULEB128(uint64_t Value, std::ofstream &out); +uint64_t DecodeULEB128(const uint8_t *p, unsigned *n = nullptr, const uint8_t *end = nullptr); +int64_t DecodeSLEB128(const uint8_t *p, unsigned *n = nullptr, const uint8_t *end = nullptr); } // namespace namemangler #endif diff --git a/src/mapleall/maple_util/src/mpl_profdata.cpp b/src/mapleall/maple_util/src/mpl_profdata.cpp new file mode 100644 index 0000000000..64e37ed9c0 --- /dev/null +++ b/src/mapleall/maple_util/src/mpl_profdata.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) [2022] Futurewei Technologies, Inc. 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 "mpl_profdata.h" +#include "mpl_logging.h" +namespace maple { +void ProfileSummary::DumpSummary() { + LogInfo::MapleLogger() << "---------ProfileSummary-------------- \n"; + LogInfo::MapleLogger() << " checkSum: " << std::hex << "0x" << checkSum << "\n"; + LogInfo::MapleLogger() << " runtimes: " << std::dec << run << "\n"; + LogInfo::MapleLogger() << " totalCounts: " << std::dec << totalCount << "\n"; + LogInfo::MapleLogger() << " maxCount: " << std::dec << maxCount << "\n"; + LogInfo::MapleLogger() << " count histogram: countRange countNum minCount cumCount \n"; + for (auto &it : histogram) { + LogInfo::MapleLogger() <<" " << std::dec << it.startValue << "\t"; + LogInfo::MapleLogger() << std::dec << it. countNums<< "\t" << it.countMinVal << "\t" << it.countCumValue << "\n"; + } +} + +void FuncProfInfo::DumpFunctionProfile() { + LogInfo::MapleLogger() << "function ident " << std::dec << ident; + LogInfo::MapleLogger() << " lino_checksum 0x" << std::hex << linenoChecksum << ", "; + LogInfo::MapleLogger() << " cfg_checksum 0x" << std::hex << cfgChecksum << "\n"; + LogInfo::MapleLogger() << " num_counts " << std::dec << edgeCounts << " : "; + for (int i = 0; i < edgeCounts; i++) { + LogInfo::MapleLogger() << std::dec << " " << counts[i]; + } + LogInfo::MapleLogger() << "\n"; +} + +void MplProfileData::DumpFunctionsProfile() { + LogInfo::MapleLogger() << "---------FunctionProfile-------------- \n"; + for (auto &it : funcsCounter) { + it.second->DumpFunctionProfile(); + } +} + +void MplProfileData::DumpProfileData() { + summary.DumpSummary(); + DumpFunctionsProfile(); +} +} // endof namespace diff --git a/src/mapleall/maple_util/src/namemangler.cpp b/src/mapleall/maple_util/src/namemangler.cpp index b2dbd0ca91..151a97f371 100644 --- a/src/mapleall/maple_util/src/namemangler.cpp +++ b/src/mapleall/maple_util/src/namemangler.cpp @@ -16,6 +16,7 @@ #include #include #include +#include namespace namemangler { #ifdef __MRT_DEBUG @@ -593,4 +594,95 @@ size_t GetSleb128Size(int32_t v) { } return size; } + +// encode signed to output stream +uint32_t EncodeSLEB128(int64_t Value, std::ofstream &out) { + bool More; + uint32_t Count = 0; + do { + uint8_t Byte = Value & 0x7f; + // NOTE: this assumes that this signed shift is an arithmetic right shift. + Value >>= 7; + More = !((((Value == 0 ) && ((Byte & 0x40) == 0)) || + ((Value == -1) && ((Byte & 0x40) != 0)))); + Count++; + if (More) { + Byte |= 0x80; // Mark this byte to show that more bytes will follow. + } + out << (char)(Byte); + } while (More); + return Count; +} + +uint32_t EncodeULEB128(uint64_t Value, std::ofstream &out) { + uint32_t Count = 0; + do { + uint8_t Byte = Value & 0x7f; + Value >>= 7; + Count++; + if (Value != 0) { + Byte |= 0x80; // Mark this byte to show that more bytes will follow. + } + out << char(Byte); + } while (Value != 0); + return Count; +} + +// decode a ULEB128 value. +uint64_t DecodeULEB128(const uint8_t *p, unsigned *n, const uint8_t *end) { + const uint8_t *orig_p = p; + uint64_t Value = 0; + unsigned Shift = 0; + do { + if (p == end) { + if (n) + *n = (unsigned)(p - orig_p); + return 0; + } + uint64_t Slice = *p & 0x7f; + if ((Shift >= 64 && Slice != 0) || Slice << Shift >> Shift != Slice) { + if (n) + *n = (unsigned)(p - orig_p); + return 0; + } + Value += Slice << Shift; + Shift += 7; + } while (*p++ >= 128); + if (n) + *n = (unsigned)(p - orig_p); + return Value; +} + +//decode a SLEB128 value. +int64_t DecodeSLEB128(const uint8_t *p, unsigned *n, const uint8_t *end) { + const uint8_t *orig_p = p; + int64_t Value = 0; + unsigned Shift = 0; + uint8_t Byte; + do { + if (p == end) { + if (n) + *n = (unsigned)(p - orig_p); + return 0; + } + Byte = *p; + uint64_t Slice = Byte & 0x7f; + if ((Shift >= 64 && Slice != (Value < 0 ? 0x7f : 0x00)) || + (Shift == 63 && Slice != 0 && Slice != 0x7f)) { + if (n) + *n = (unsigned)(p - orig_p); + return 0; + } + Value |= Slice << Shift; + Shift += 7; + ++p; + } while (Byte >= 128); + // Sign extend negative numbers if needed. + if (Shift < 64 && (Byte & 0x40)) + Value |= (-1ULL) << Shift; + if (n) + *n = (unsigned)(p - orig_p); + return Value; +} + } // namespace namemangler diff --git a/src/mapleall/mpl2mpl/BUILD.gn b/src/mapleall/mpl2mpl/BUILD.gn index c41431ec49..63ba35bebe 100755 --- a/src/mapleall/mpl2mpl/BUILD.gn +++ b/src/mapleall/mpl2mpl/BUILD.gn @@ -57,7 +57,7 @@ src_libmpl2mpl = [ "src/inline_analyzer.cpp", "src/inline_transformer.cpp", "src/method_replace.cpp", - "src/gcov_parser.cpp", + "src/mpl_profdata_parser.cpp", ] configs = [ "${MAPLEALL_ROOT}:mapleallcompilecfg" ] diff --git a/src/mapleall/mpl2mpl/include/gcov_parser.h b/src/mapleall/mpl2mpl/include/gcov_parser.h deleted file mode 100644 index 85dcb3566d..0000000000 --- a/src/mapleall/mpl2mpl/include/gcov_parser.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) [2022] Futurewei Technologies Co., Ltd. All rights reserved. - * - * OpenArkCompiler is licensed under the Mulan Permissive Software License v2. - * You can use this software according to the terms and conditions of the MulanPSL - 2.0. - * You may obtain a copy of MulanPSL - 2.0 at: - * - * https://opensource.org/licenses/MulanPSL-2.0 - * - * 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 MulanPSL - 2.0 for more details. - */ - -#ifndef MAPLE_MPL2MPL_INCLUDE_GCOVPROFUSE_H -#define MAPLE_MPL2MPL_INCLUDE_GCOVPROFUSE_H -#include "mempool.h" -#include "mempool_allocator.h" -#include "bb.h" -#include "maple_phase_manager.h" -#include "gcov_profile.h" - -namespace maple { -using gcov_position_t = unsigned; -// counter defined in gcov-counter.def -enum { - GCOV_COUNTER_ARCS, - GCOV_COUNTER_V_INTERVAL, - GCOV_COUNTER_V_POW2, - GCOV_COUNTER_V_SINGLE, - GCOV_COUNTER_V_INDIR, - GCOV_COUNTER_AVERAGE, - GCOV_COUNTER_IOR, - GCOV_TIME_PROFILER, - GCOV_COUNTER_ICALL_TOPNV, - GCOV_COUNTERS -}; - -class GcovVar { - public: - GcovVar() { - file = nullptr; - buffer = nullptr; - } - FILE *file = nullptr; - gcov_position_t start = 0; - unsigned offset = 0; - unsigned length = 0; - unsigned overread = 0; - int error = 0; - int mode = 0; - int endian = 0; - size_t alloc = 0; - gcov_unsigned_t* buffer = nullptr; -}; - -class MGcovParser : public AnalysisResult { - public: - MGcovParser(MIRModule &mirmod, MemPool *memPool, bool debug) : AnalysisResult(memPool), m(mirmod), - alloc(memPool), localMP(memPool), gcovData(nullptr), dumpDetail(debug) { - gcovVar = localMP->New(); - } - ~MGcovParser() override { - localMP = nullptr; - gcovData = nullptr; - gcovVar = nullptr; - } - int ReadGcdaFile(); - void DumpFuncInfo(); - GcovProfileData *GetGcovData() { return gcovData; } - - private: - using gcov_bucket_type = struct { - gcov_unsigned_t num_counters; - gcov_type min_value; - gcov_type cum_value; - }; - - struct gcov_ctr_summary { - gcov_unsigned_t num; - gcov_unsigned_t runs; - gcov_type sum_all; - gcov_type run_max; - gcov_type sum_max; - gcov_bucket_type histogram[252]; - }; - struct gcov_summary { - gcov_unsigned_t checksum; - struct gcov_ctr_summary ctrs[GCOV_COUNTER_V_INTERVAL]; - }; - - int GcovReadMagic(gcov_unsigned_t magic, gcov_unsigned_t expected); - int GcovOpenFile(const char *name, int mode); - gcov_unsigned_t from_file(gcov_unsigned_t value); - const gcov_unsigned_t *GcovReadWords(unsigned words); - void GcovSync(gcov_position_t base, gcov_unsigned_t length); - int GcovCloseFile(void); - void GcovAllocate(unsigned length); - gcov_unsigned_t GcovReadUnsigned(void); - gcov_position_t GcovGetPosition(void); - gcov_type GcovReadCounter(void); - void GcovReadSummary(struct gcov_summary *summary); - - MIRModule &m; - MapleAllocator alloc; - MemPool *localMP; - GcovProfileData *gcovData; - GcovVar *gcovVar = nullptr; - bool dumpDetail; -}; - -MAPLE_MODULE_PHASE_DECLARE(M2MGcovParser) - -} // end of namespace maple - -#endif // MAPLE_MPL2MPL_INCLUDE_GCOVPROFUSE_H diff --git a/src/mapleall/mpl2mpl/include/inline_transformer.h b/src/mapleall/mpl2mpl/include/inline_transformer.h index 8d95a97381..1569f9b900 100644 --- a/src/mapleall/mpl2mpl/include/inline_transformer.h +++ b/src/mapleall/mpl2mpl/include/inline_transformer.h @@ -55,7 +55,10 @@ class InlineTransformer { callee(callee), callStmt(callStmt), dumpDetail(dumpDetail), - cg(cg) {} + cg(cg) { + updateFreq = (Options::profileUse && caller.GetFuncProfData() && callee.GetFuncProfData()); + }; + bool PerformInline(BlockNode &enclosingBlk); static void ReplaceSymbols(BaseNode*, uint32, const std::vector*); static void ConvertPStaticToFStatic(MIRFunction &func); @@ -91,6 +94,7 @@ class InlineTransformer { LabelIdx returnLabelIdx = 0; // The lableidx where the code will jump when the callee returns. StmtNode *labelStmt = nullptr; // The LabelNode we created for the callee, if needed. CallGraph *cg = nullptr; + bool updateFreq = false; }; } // namespace maple #endif // MPL2MPL_INCLUDE_INLINE_TRANSFORMER_H diff --git a/src/mapleall/mpl2mpl/include/mpl_profdata_parser.h b/src/mapleall/mpl2mpl/include/mpl_profdata_parser.h new file mode 100644 index 0000000000..95513fd835 --- /dev/null +++ b/src/mapleall/mpl2mpl/include/mpl_profdata_parser.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) [2022] Futurewei Technologies, Inc. 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_MPL2MPL_INCLUDE_GCOVPROFUSE_H +#define MAPLE_MPL2MPL_INCLUDE_GCOVPROFUSE_H +#include "mempool.h" +#include "mempool_allocator.h" +#include "bb.h" +#include "maple_phase_manager.h" +#include "mpl_profdata.h" + +namespace maple { +//maple profile data format +// Summary layout +// MagicNumber +// chesum +// run times +// counts number +// count Maxium value +// accumulated count sum +// cout histogram size (count statistic information used for hot function check) +// count lower bound <-- begin of histogram details +// countNum in current range +// minium value in count range +// accumulated count sum +// count range <-- another histogram element +// countNum +// minium value in cout range +// accumulated count sum +// Function profile layout (now only including edge profiling counts) +// function numbers +// function Ident (key number to identify each function(now use mirfunction->puidx) +// function line number checksum +// function cfg checksum +// counts number in function 0 +// count <-- begin of count value +// count +// counts number in function 1 +// count +// ... +// now only unsigned number in profile data, use ULEB128 to encode/decode value for file size + +const uint32_t kMapleProfDataMagicNumber = 0xA0EFEF; + +class ProfDataBinaryImportBase { +public: + ProfDataBinaryImportBase(std::string &filename, std::ifstream &input) : fileName(filename), + inputStream(input) {} + template T ReadNum(); + std::ifstream& GetInputStream() { return inputStream; } + std::string& GetProfDataFileName() { return fileName; } + void SetPosition(uint8_t *p) { pos = p; } + uint8_t *GetPosition() { return pos; } +private: + std::string &fileName; + std::ifstream &inputStream; + uint8_t *pos = nullptr; +}; + +class ProfileSummaryImport : public ProfDataBinaryImportBase { +public: + ProfileSummaryImport(std::string& outputFile, std::ifstream &input): + ProfDataBinaryImportBase(outputFile, input) {} + int ReadSummary(MplProfileData *); +private: + void ReadMProfMagic(); +}; + +class FunctionProfileImport : public ProfDataBinaryImportBase { +public: + FunctionProfileImport(std::string& inputFile, std::ifstream &input) : + ProfDataBinaryImportBase(inputFile, input) {} + int ReadFuncProfile(MplProfileData *profData); +}; + + +class MplProfDataParser : public AnalysisResult { + public: + MplProfDataParser(MIRModule &mirmod, MemPool *mp, bool debug) : AnalysisResult(mp), + m(mirmod), alloc(memPool), mempool(mp), dumpDetail(debug) { + } + virtual ~MplProfDataParser() { + } + MplProfileData *GetProfData() { return profData; } + int ReadMapleProfileData(); + private: + + MIRModule &m; + MapleAllocator alloc; + MemPool *mempool; + MplProfileData *profData = nullptr; + bool dumpDetail = false; +}; + +MAPLE_MODULE_PHASE_DECLARE(MMplProfDataParser) + +} // end of namespace maple + +#endif // MAPLE_MPL2MPL_INCLUDE_GCOVPROFUSE_H diff --git a/src/mapleall/mpl2mpl/src/call_graph.cpp b/src/mapleall/mpl2mpl/src/call_graph.cpp index 12e8664a26..ba629b6b56 100644 --- a/src/mapleall/mpl2mpl/src/call_graph.cpp +++ b/src/mapleall/mpl2mpl/src/call_graph.cpp @@ -190,7 +190,7 @@ bool CGNode::IsCalleeOf(CGNode *func) const { } uint64_t CGNode::GetCallsiteFrequency(const StmtNode *callstmt) const { - GcovFuncInfo *funcInfo = mirFunc->GetFuncProfData(); + FuncProfInfo *funcInfo = mirFunc->GetFuncProfData(); if (funcInfo->stmtFreqs.count(callstmt->GetStmtID()) > 0) { return funcInfo->stmtFreqs[callstmt->GetStmtID()]; } @@ -199,7 +199,7 @@ uint64_t CGNode::GetCallsiteFrequency(const StmtNode *callstmt) const { } uint64_t CGNode::GetFuncFrequency() const { - GcovFuncInfo *funcInfo = mirFunc->GetFuncProfData(); + FuncProfInfo *funcInfo = mirFunc->GetFuncProfData(); if (funcInfo) { return funcInfo->GetFuncFrequency(); } diff --git a/src/mapleall/mpl2mpl/src/gcov_parser.cpp b/src/mapleall/mpl2mpl/src/gcov_parser.cpp deleted file mode 100644 index f0f1373e90..0000000000 --- a/src/mapleall/mpl2mpl/src/gcov_parser.cpp +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Copyright (c) [2022] Futurewei Technologies Co., Ltd. All rights reserved. - * - * OpenArkCompiler is licensed under the Mulan Permissive Software License v2. - * You can use this software according to the terms and conditions of the MulanPSL - 2.0. - * You may obtain a copy of MulanPSL - 2.0 at: - * - * https://opensource.org/licenses/MulanPSL-2.0 - * - * 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 MulanPSL - 2.0 for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "option.h" -#include "mpl_logging.h" -#include "gcov_parser.h" - -namespace maple { -#define GCOV_DATA_MAGIC ((gcov_unsigned_t)0x67636461) /* "gcda" */ -#define GCOV_VERSION ((gcov_unsigned_t)0x4137352a) - -#ifndef ATTRIBUTE_UNUSED -#define ATTRIBUTE_UNUSED __attribute__((unused)) -#endif - -/* Convert a magic or version number to a 4 character string. */ -#define GCOV_UNSIGNED2STRING(ARRAY,VALUE) \ - ((ARRAY)[0] = (char)((VALUE) >> 24), \ - (ARRAY)[1] = (char)((VALUE) >> 16), \ - (ARRAY)[2] = (char)((VALUE) >> 8), \ - (ARRAY)[3] = (char)((VALUE) >> 0)) - -#define GCOV_TAG_FUNCTION ((gcov_unsigned_t)0x01000000) -#define GCOV_TAG_FUNCTION_LENGTH (3) -#define GCOV_TAG_BLOCKS ((gcov_unsigned_t)0x01410000) -#define GCOV_TAG_BLOCKS_LENGTH(NUM) (NUM) -#define GCOV_TAG_BLOCKS_NUM(LENGTH) (LENGTH) -#define GCOV_TAG_ARCS ((gcov_unsigned_t)0x01430000) -#define GCOV_TAG_ARCS_LENGTH(NUM) (1 + (NUM) * 2) -#define GCOV_TAG_ARCS_NUM(LENGTH) (((LENGTH) - 1) / 2) -#define GCOV_TAG_LINES ((gcov_unsigned_t)0x01450000) -#define GCOV_TAG_COUNTER_BASE ((gcov_unsigned_t)0x01a10000) -#define GCOV_TAG_COUNTER_LENGTH(NUM) ((NUM) * 2) -#define GCOV_TAG_COUNTER_NUM(LENGTH) ((LENGTH) / 2) -#define GCOV_TAG_OBJECT_SUMMARY ((gcov_unsigned_t)0xa1000000) /* Obsolete */ -#define GCOV_TAG_PROGRAM_SUMMARY ((gcov_unsigned_t)0xa3000000) -#define GCOV_TAG_SUMMARY_LENGTH(NUM) \ - (1 + GCOV_COUNTERS_SUMMABLE * (10 + 3 * 2) + (NUM) * 5) -#define GCOV_TAG_AFDO_FILE_NAMES ((gcov_unsigned_t)0xaa000000) -#define GCOV_TAG_AFDO_FUNCTION ((gcov_unsigned_t)0xac000000) -#define GCOV_TAG_AFDO_WORKING_SET ((gcov_unsigned_t)0xaf000000) - -// Convert a counter index to a tag -#define GCOV_TAG_FOR_COUNTER(COUNT) \ - (GCOV_TAG_COUNTER_BASE + ((gcov_unsigned_t)(COUNT) << 17)) - -// Return the number of set bits in X -static int popcount_hwi (unsigned long long x) { - int i, ret = 0; - size_t bits = sizeof (x) * CHAR_BIT; - for (i = 0; i < bits; i += 1) { - ret += x & 1; - x >>= 1; - } - return ret; -} - -gcov_position_t MGcovParser::GcovGetPosition (void) { - ((void)(0 && (gcovVar->mode > 0))); - return gcovVar->start + gcovVar->offset; -} - -int MGcovParser::GcovOpenFile(const char *name, int mode) { - ((void)(0 && (!gcovVar->file))); - gcovVar->start = 0; - gcovVar->offset = gcovVar->length = 0; - gcovVar->overread = -1u; - gcovVar->error = 0; - gcovVar->endian = 0; - gcovVar->alloc = 0; - if (mode >= 0) { - gcovVar->file = fopen(name, (mode > 0) ? "rb" : "r+b"); - } - if (gcovVar->file) { - mode = 1; - } else if (mode <= 0) { - gcovVar->file = fopen(name, "w+b"); - } - if (!gcovVar->file) return 0; - gcovVar->mode = mode ? mode : 1; - setbuf(gcovVar->file, (char *)0); - return 1; -} - -void MGcovParser::GcovAllocate (unsigned length) { - size_t new_size = gcovVar->alloc; - if (!new_size) { - new_size = (1 << 10); - } - new_size += length; - new_size *= 2; - gcovVar->alloc = new_size; - gcovVar->buffer= ((gcov_unsigned_t *) realloc ((gcovVar->buffer), (new_size << 2))); -} - -int MGcovParser::GcovReadMagic(gcov_unsigned_t magic, gcov_unsigned_t expected) { - if (magic == expected) return 1; - magic = (magic >> 16) | (magic << 16); - magic = ((magic & 0xff00ff) << 8) | ((magic >> 8) & 0xff00ff); - if (magic == expected) { - gcovVar->endian = 1; - return -1; - } - return 0; -} - -void MGcovParser::GcovSync(gcov_position_t base, gcov_unsigned_t length) { - ((void)(0 && (gcovVar->mode > 0))); - base += length; - if (base - gcovVar->start <= gcovVar->length) { - gcovVar->offset = base - gcovVar->start; - } else { - gcovVar->offset = gcovVar->length = 0; - fseek (gcovVar->file, base << 2, 0); - gcovVar->start = ftell (gcovVar->file) >> 2; - } -} - -const gcov_unsigned_t * MGcovParser::GcovReadWords (unsigned words) { - const gcov_unsigned_t *result; - unsigned excess = gcovVar->length - gcovVar->offset; - if (gcovVar->mode <= 0) - return nullptr; - if (excess < words) { - gcovVar->start += gcovVar->offset; - if (excess) { - memmove_s(gcovVar->buffer, excess * 4, gcovVar->buffer + gcovVar->offset, excess * 4); - } - gcovVar->offset = 0; - gcovVar->length = excess; - if (gcovVar->length + words > gcovVar->alloc) { - GcovAllocate(gcovVar->length + words); - } - excess = gcovVar->alloc - gcovVar->length; - excess = fread (gcovVar->buffer + gcovVar->length, 1, excess << 2, gcovVar->file) >> 2; - gcovVar->length += excess; - if (gcovVar->length < words) { - gcovVar->overread += words - gcovVar->length; - gcovVar->length = 0; - return 0; - } - } - result = &gcovVar->buffer[gcovVar->offset]; - gcovVar->offset += words; - return result; -} - -gcov_unsigned_t MGcovParser::from_file(gcov_unsigned_t value) { - if (gcovVar->endian) { - value = (value >> 16) | (value << 16); - value = ((value & 0xff00ff) << 8) | ((value >> 8) & 0xff00ff); - } - return value; -} - -gcov_unsigned_t MGcovParser::GcovReadUnsigned(void) { - gcov_unsigned_t value; - const gcov_unsigned_t *buffer = GcovReadWords(1); - if (!buffer) return 0; - value = from_file(buffer[0]); - return value; -} - -int MGcovParser::GcovCloseFile (void) { - if (gcovVar->file) { - fclose (gcovVar->file); - gcovVar->file = 0; - gcovVar->length = 0; - } - free (gcovVar->buffer); - gcovVar->alloc = 0; - gcovVar->buffer = nullptr; - gcovVar->mode = 0; - return gcovVar->error; -} - -gcov_type MGcovParser::GcovReadCounter (void) { - gcov_type value; - const gcov_unsigned_t *buffer = GcovReadWords(2); - if (!buffer) return 0; - value = from_file (buffer[0]); - if (sizeof (value) > sizeof (gcov_unsigned_t)) { - value |= ((gcov_type) from_file (buffer[1])) << 32; - } else if (buffer[1]) { - gcovVar->error = -1; - } - return value; -} - -void MGcovParser::GcovReadSummary (struct gcov_summary *summary) { - unsigned ix, h_ix, bv_ix, h_cnt = 0; - struct gcov_ctr_summary *csum; - unsigned histo_bitvector[(252 + 31) / 32]; - unsigned cur_bitvector; - summary->checksum = GcovReadUnsigned(); - for (csum = summary->ctrs, ix = (GCOV_COUNTER_ARCS + 1); ix--; csum++) { - csum->num = GcovReadUnsigned(); - csum->runs = GcovReadUnsigned(); - csum->sum_all = GcovReadCounter(); - csum->run_max = GcovReadCounter(); - csum->sum_max = GcovReadCounter(); - memset_s(csum->histogram, sizeof (gcov_bucket_type) * 252, 0, sizeof (gcov_bucket_type) * 252); - for (bv_ix = 0; bv_ix < (252 + 31) / 32; bv_ix++) { - histo_bitvector[bv_ix] = GcovReadUnsigned(); - h_cnt += popcount_hwi (histo_bitvector[bv_ix]); - } - bv_ix = 0; - h_ix = 0; - cur_bitvector = 0; - while (h_cnt--) { - while (!cur_bitvector) { - h_ix = bv_ix * 32; - if (bv_ix >= (252 + 31) / 32) { - CHECK_FATAL(false, "corrupted profile info: summary histogram " "bitvector is corrupt"); - } - cur_bitvector = histo_bitvector[bv_ix++]; - } - while (!(cur_bitvector & 0x1)) { - h_ix++; - cur_bitvector >>= 1; - } - if (h_ix >= 252) { - CHECK_FATAL(0, "corrupted profile info: summary histogram " "index is corrupt"); - } - csum->histogram[h_ix].num_counters = GcovReadUnsigned(); - csum->histogram[h_ix].min_value = GcovReadCounter(); - csum->histogram[h_ix].cum_value = GcovReadCounter(); - cur_bitvector >>= 1; - h_ix++; - } - } -} - -static unsigned object_runs; -static unsigned program_count; -// reference -int MGcovParser::ReadGcdaFile() { - std::string gcovDataFile = Options::profile; - if (gcovDataFile.empty()) { - if (const char* env_p = std::getenv("GCOV_PREFIX")) { - gcovDataFile.append(env_p); - } else { - gcovDataFile.append("."); - } - gcovDataFile.append("/"); - gcovDataFile.append(m.GetProfileDataFileName()); - } - ASSERT(!gcovDataFile.empty(), "null check"); - if (!GcovOpenFile(gcovDataFile.c_str(), 1)) { - LogInfo::MapleLogger() << "no data file " << gcovDataFile << " \n"; - Options::profileUse = false; // reset profileUse - return 0; - } - - if (!GcovReadMagic(GcovReadUnsigned(), GCOV_DATA_MAGIC)) { - LogInfo::MapleLogger() << gcovDataFile << " not a gcov data file\n"; - GcovCloseFile (); - return 1; - } - unsigned version = GcovReadUnsigned(); - if (version != GCOV_VERSION) { - char v[4], e[4]; - GCOV_UNSIGNED2STRING (v, version); - 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 = GcovReadUnsigned(); - - gcovData = localMP->New(&alloc); - GcovFuncInfo *funcInfo = nullptr; - while ((tag = GcovReadUnsigned())) { - unsigned length = GcovReadUnsigned(); - unsigned long base = GcovGetPosition(); - - if (tag == GCOV_TAG_PROGRAM_SUMMARY) { - struct gcov_summary summary; - GcovReadSummary(&summary); - object_runs += summary.ctrs[GCOV_COUNTER_ARCS].runs; - program_count++; - } else if (tag == GCOV_TAG_FUNCTION && length == GCOV_TAG_FUNCTION_LENGTH) { - unsigned ident; - /* Try to find the function in the list. To speed up the - search, first start from the last function found. */ - ident = GcovReadUnsigned(); - unsigned lineno_checksum = GcovReadUnsigned(); - unsigned cfg_checksum = GcovReadUnsigned(); - funcInfo = localMP->New(&alloc, ident, lineno_checksum, cfg_checksum); - (gcovData->funcsCounter)[ident] = funcInfo; - } else if (tag == GCOV_TAG_FOR_COUNTER (GCOV_COUNTER_ARCS)) { - funcInfo->num_counts = GCOV_TAG_COUNTER_NUM(length); - for (int ix = 0; ix != funcInfo->num_counts; ix++) { - funcInfo->counts.push_back(GcovReadCounter()); - } - } - GcovSync(base, length); - } - GcovCloseFile(); - - if (dumpDetail) { - DumpFuncInfo(); - } - return 0; -} - -void MGcovParser::DumpFuncInfo() { - for (auto &it : gcovData->funcsCounter) { - GcovFuncInfo *funcInfo = it.second; - LogInfo::MapleLogger() << "\nfunction ident " << std::dec << funcInfo->ident; - LogInfo::MapleLogger() << " lino_checksum 0x" << std::hex << funcInfo->lineno_checksum; - LogInfo::MapleLogger() << " cfg_checksum 0x" << std::hex << funcInfo->cfg_checksum << "\n"; - LogInfo::MapleLogger() << " num_counts " << std::dec << funcInfo->num_counts << " : "; - for (int i = 0; i < funcInfo->num_counts; i++) { - LogInfo::MapleLogger() << std::dec << " " << funcInfo->counts[i]; - } - } - LogInfo::MapleLogger() << "\n" ; -} - -void M2MGcovParser::GetAnalysisDependence(AnalysisDep &aDep) const { - aDep.SetPreservedAll(); -} - -bool M2MGcovParser::PhaseRun(maple::MIRModule &m) { - MemPool *memPool = m.GetMemPool(); // use global pool to store gcov data - MGcovParser gcovParser(m, memPool, true); - int res = gcovParser.ReadGcdaFile(); - if (res) { - // something wrong - return false; - } - m.SetGcovProfile(gcovParser.GetGcovData()); - return true; -} - - -} // end namespace maple diff --git a/src/mapleall/mpl2mpl/src/gen_profile.cpp b/src/mapleall/mpl2mpl/src/gen_profile.cpp index 2f1a0bdb0e..b586d91474 100644 --- a/src/mapleall/mpl2mpl/src/gen_profile.cpp +++ b/src/mapleall/mpl2mpl/src/gen_profile.cpp @@ -104,7 +104,7 @@ void ProfileGen::CreateModProfDesc() { modProfDescSymMirConst->AddItem(checksumMirConst, 5); // Make the profile file name as fileName.gcda - std::string profFileName = mod.GetProfileDataFileName(); + std::string profFileName = mod.GetProfileDataFileName() + namemangler::kProfFileNameExt; auto *profileFNMirConst = modMP->New("./" + profFileName, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(PTY_a64))); modProfDescSymMirConst->AddItem(profileFNMirConst, 6); diff --git a/src/mapleall/mpl2mpl/src/inline.cpp b/src/mapleall/mpl2mpl/src/inline.cpp index 4b1c4ca460..4b7543ee76 100644 --- a/src/mapleall/mpl2mpl/src/inline.cpp +++ b/src/mapleall/mpl2mpl/src/inline.cpp @@ -92,7 +92,7 @@ void MInline::InitParams() { } void MInline::InitProfile() const { - // gcov use different profile data, return + // maple profile use different profile data, return if (Options::profileUse) { return; } @@ -421,7 +421,7 @@ 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 + // use maple instrument profile if (Options::profileUse) { return caller.GetFuncProfData()->IsHotCallSite(callStmt.GetStmtID()); } diff --git a/src/mapleall/mpl2mpl/src/inline_transformer.cpp b/src/mapleall/mpl2mpl/src/inline_transformer.cpp index 87d79fab1a..030b077931 100644 --- a/src/mapleall/mpl2mpl/src/inline_transformer.cpp +++ b/src/mapleall/mpl2mpl/src/inline_transformer.cpp @@ -307,7 +307,7 @@ GotoNode *InlineTransformer::DoUpdateReturnStmts(BlockNode &newBody, StmtNode &s dStmt = builder.CreateStmtRegassign(mirPreg->GetPrimType(), pregIdx, currBaseNode); } dStmt->SetSrcPos(stmt.GetSrcPos()); - if (Options::profileUse) { + if (updateFreq) { caller.GetFuncProfData()->CopyStmtFreq(dStmt->GetStmtID(), stmt.GetStmtID()); caller.GetFuncProfData()->CopyStmtFreq(gotoNode->GetStmtID(), stmt.GetStmtID()); caller.GetFuncProfData()->EraseStmtFreq(stmt.GetStmtID()); @@ -315,7 +315,7 @@ GotoNode *InlineTransformer::DoUpdateReturnStmts(BlockNode &newBody, StmtNode &s newBody.ReplaceStmt1WithStmt2(&stmt, dStmt); newBody.InsertAfter(dStmt, gotoNode); } else { - if (Options::profileUse) { + if (updateFreq) { caller.GetFuncProfData()->CopyStmtFreq(gotoNode->GetStmtID(), stmt.GetStmtID()); caller.GetFuncProfData()->EraseStmtFreq(stmt.GetStmtID()); } @@ -458,10 +458,9 @@ BlockNode *InlineTransformer::CloneFuncBody(BlockNode &funcBody, bool recursiveF if (callee.IsFromMpltInline()) { return funcBody.CloneTree(theMIRModule->GetCurFuncCodeMPAllocator()); } - if (Options::profileUse) { + if (updateFreq) { auto *callerProfData = caller.GetFuncProfData(); auto *calleeProfData = callee.GetFuncProfData(); - ASSERT(callerProfData && calleeProfData, "nullptr check"); uint64_t callsiteFreq = callerProfData->GetStmtFreq(callStmt.GetStmtID()); uint64_t calleeEntryFreq = calleeProfData->GetFuncFrequency(); uint32_t updateOp = (kKeepOrigFreq | kUpdateFreqbyScale); @@ -560,7 +559,7 @@ void InlineTransformer::AssignActualsToFormals(BlockNode &newBody, uint32 stIdxO CHECK_NULL_FATAL(currBaseNode); CHECK_NULL_FATAL(formal); AssignActualToFormal(newBody, stIdxOff, regIdxOff, *currBaseNode, *formal); - if (Options::profileUse) { + if (updateFreq) { caller.GetFuncProfData()->CopyStmtFreq(newBody.GetFirst()->GetStmtID(), callStmt.GetStmtID()); } } @@ -604,7 +603,7 @@ void InlineTransformer::HandleReturn(BlockNode &newBody) { } } } - if (Options::profileUse && (labelStmt != nullptr) && (newBody.GetLast() == labelStmt)) { + if (updateFreq && (labelStmt != nullptr) && (newBody.GetLast() == labelStmt)) { caller.GetFuncProfData()->CopyStmtFreq(labelStmt->GetStmtID(), callStmt.GetStmtID()); } } @@ -621,7 +620,7 @@ void InlineTransformer::ReplaceCalleeBody(BlockNode &enclosingBlk, BlockNode &ne beginCmt += callee.GetName(); StmtNode *commNode = builder.CreateStmtComment(beginCmt.c_str()); enclosingBlk.InsertBefore(&callStmt, commNode); - if (Options::profileUse) { + if (updateFreq) { caller.GetFuncProfData()->CopyStmtFreq(commNode->GetStmtID(), callStmt.GetStmtID()); } // end inlining function @@ -637,7 +636,7 @@ void InlineTransformer::ReplaceCalleeBody(BlockNode &enclosingBlk, BlockNode &ne } commNode = builder.CreateStmtComment(endCmt.c_str()); enclosingBlk.InsertAfter(&callStmt, commNode); - if (Options::profileUse) { + if (updateFreq) { caller.GetFuncProfData()->CopyStmtFreq(commNode->GetStmtID(), callStmt.GetStmtID()); } CHECK_FATAL(callStmt.GetNext() != nullptr, "null ptr check"); @@ -661,7 +660,7 @@ void InlineTransformer::GenReturnLabel(BlockNode &newBody, uint32 inlinedTimes) // record the created label labelStmt = builder.CreateStmtLabel(returnLabelIdx); newBody.AddStatement(labelStmt); - if (Options::profileUse) { + if (updateFreq) { caller.GetFuncProfData()->CopyStmtFreq(labelStmt->GetStmtID(), callStmt.GetStmtID()); } } diff --git a/src/mapleall/mpl2mpl/src/module_phase_manager.cpp b/src/mapleall/mpl2mpl/src/module_phase_manager.cpp index 375fba0b8d..ff39484443 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 "gcov_parser.h" +#include "mpl_profdata_parser.h" #define JAVALANG (mirModule.IsJavaModule()) #define CLANG (mirModule.IsCModule()) @@ -109,7 +109,7 @@ MAPLE_ANALYSIS_PHASE_REGISTER(M2MCallGraph, callgraph) 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(MMplProfDataParser, grofDataParser) MAPLE_TRANSFORM_PHASE_REGISTER(M2MInline, inline) MAPLE_TRANSFORM_PHASE_REGISTER(M2MIPODevirtualize, ipodevirtulize) diff --git a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp new file mode 100644 index 0000000000..de5c758b74 --- /dev/null +++ b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp @@ -0,0 +1,162 @@ +/* + * Copyright (c) [2022] Futurewei Technologies, Inc. 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include "option.h" +#include "mpl_logging.h" +#include "mpl_profdata_parser.h" + +namespace maple { + +template T ProfDataBinaryImportBase::ReadNum() { + unsigned NumBytesRead = 0; + uint64_t Val = namemangler::DecodeULEB128(pos, &NumBytesRead); + + pos += NumBytesRead; + return static_cast(Val); +} + +int ProfileSummaryImport::ReadSummary(MplProfileData *profData) { + CHECK_FATAL(profData != nullptr, "sanity check"); + uint64_t magicNum = ReadNum(); + if (magicNum != kMapleProfDataMagicNumber) { + LogInfo::MapleLogger() << "magic number error, quit\n"; + return 1; + } + uint64_t checksum = ReadNum(); + uint32_t runtimes = ReadNum(); + uint32_t numofCounts = ReadNum(); + uint64_t maxCount = ReadNum(); + uint64_t sumCount = ReadNum(); + profData->summary.SetSummary(checksum, runtimes, numofCounts, maxCount, sumCount); + uint32_t veclen = ReadNum(); + + for (int i = 0; i < veclen; i++) { + uint32_t r1 = ReadNum(); + uint32_t r2 = ReadNum(); + uint64_t r3 = ReadNum(); + uint64_t r4 = ReadNum(); + profData->summary.AddHistogramRecord(r1, r2, r3, r4); + } + + return 0; +} + +int FunctionProfileImport::ReadFuncProfile(MplProfileData *profData) { + CHECK_FATAL(profData != nullptr, "sanity check"); + uint32_t funcNums = ReadNum(); + if (funcNums == 0) return 1; + + for (int i = 0; i < funcNums; i++) { + uint32_t funcIdent = ReadNum(); + uint32_t linocheckSum = ReadNum(); + uint32_t cfgcheckSum = ReadNum(); + uint32_t countNum = ReadNum(); + FuncProfInfo *funcProf = profData->AddNewFuncProfile(funcIdent, linocheckSum, cfgcheckSum, countNum); + CHECK_FATAL(funcProf != nullptr, "nullptr check"); + funcProf->counts.resize(countNum); + for (int j = 0; j < countNum; j++) { + funcProf->counts[j] = ReadNum(); + } + } + return 0; +} + +int MplProfDataParser::ReadMapleProfileData() { + std::string mprofDataFile = Options::profile; + if (mprofDataFile.empty()) { + if (const char* env_p = std::getenv("GCOV_PREFIX")) { + mprofDataFile.append(env_p); + } else { + mprofDataFile.append("."); + } + mprofDataFile.append("/"); + mprofDataFile.append(m.GetProfileDataFileName()); + mprofDataFile.append(namemangler::kMplProfFileNameExt); + } + ASSERT(!mprofDataFile.empty(), "null check"); + + // create mpl profdata + profData = mempool->New(mempool, &alloc); + // read .mprofdata + std::ifstream inputStream(mprofDataFile, (std::ios::in | std::ios::binary)); + if (!inputStream) { + LogInfo::MapleLogger() << "Could not open the file " << mprofDataFile << "\n"; + return 1; + } + // get length of file + inputStream.seekg (0, inputStream.end); + int length = inputStream.tellg(); + inputStream.seekg (0, inputStream.beg); + const uint32_t sizeThreshold = 1024*10; + CHECK_FATAL(length <= sizeThreshold, "NYI::large .mprofdata file size is larger than threashold, do chunk memory\n"); + + std::unique_ptr buffer(new char[sizeof(char) * length]()); + inputStream.read (buffer.get(), length); + inputStream.close(); + // read 1st part summary + ProfileSummaryImport summaryImport(mprofDataFile, inputStream); + summaryImport.SetPosition((uint8_t *)buffer.get()); + int res = summaryImport.ReadSummary(profData); + if (res) { + LogInfo::MapleLogger() << "no summary part\n"; + return 1; + } + if (dumpDetail) { + profData->summary.DumpSummary(); + } + // read 2nd part function profile data + FunctionProfileImport funcImport(mprofDataFile, inputStream); + funcImport.SetPosition(summaryImport.GetPosition()); + res = funcImport.ReadFuncProfile(profData); + if (res) { + LogInfo::MapleLogger() << "no function profile part\n"; + return 1; + } + if (dumpDetail) { + profData->DumpFunctionsProfile(); + } + return 0; +} + +void MMplProfDataParser::GetAnalysisDependence(AnalysisDep &aDep) const { + aDep.SetPreservedAll(); +} + +bool MMplProfDataParser::PhaseRun(maple::MIRModule &m) { + + MemPool *memPool = m.GetMemPool(); // use global pool to store profile data + MplProfDataParser parser(m, memPool, true/*debug*/); + int res = parser.ReadMapleProfileData(); + if (res) { + // something wrong + LogInfo::MapleLogger() << " parse .mprofdata error\n"; + return false; + } + m.SetMapleProfile(parser.GetProfData()); + + return true; +} + + +} // end namespace maple -- Gitee From f5daea66429e3c180092b341464e7f99bb534dca Mon Sep 17 00:00:00 2001 From: linma Date: Wed, 27 Jul 2022 13:43:28 -0700 Subject: [PATCH 02/16] pgo use: maintain frequency in valuerangeprop and optimizeCFg, fix frequency issue in loopinversion generate cfg dot file for profileuse debug --- src/mapleall/maple_me/include/bb.h | 33 +- src/mapleall/maple_me/include/hdse.h | 21 +- src/mapleall/maple_me/include/me_cfg.h | 39 +- src/mapleall/maple_me/include/me_loop_canon.h | 5 +- .../maple_me/include/me_loop_unrolling.h | 52 +- src/mapleall/maple_me/src/bb.cpp | 43 +- src/mapleall/maple_me/src/hdse.cpp | 59 +- src/mapleall/maple_me/src/me_bb_layout.cpp | 84 +- src/mapleall/maple_me/src/me_cfg.cpp | 249 ++-- .../maple_me/src/me_critical_edge.cpp | 22 +- src/mapleall/maple_me/src/me_dse.cpp | 10 +- src/mapleall/maple_me/src/me_hdse.cpp | 23 +- src/mapleall/maple_me/src/me_loop_canon.cpp | 60 +- .../maple_me/src/me_loop_inversion.cpp | 101 +- .../maple_me/src/me_loop_unrolling.cpp | 165 +-- src/mapleall/maple_me/src/me_profile_use.cpp | 35 +- .../maple_me/src/me_value_range_prop.cpp | 1171 +++++++++-------- src/mapleall/maple_me/src/optimizeCFG.cpp | 354 ++--- .../maple_util/include/mpl_profdata.h | 121 +- src/mapleall/maple_util/src/mpl_profdata.cpp | 61 +- .../mpl2mpl/include/inline_transformer.h | 5 +- src/mapleall/mpl2mpl/src/call_graph.cpp | 30 +- src/mapleall/mpl2mpl/src/inline.cpp | 57 +- .../mpl2mpl/src/mpl_profdata_parser.cpp | 41 +- 24 files changed, 1673 insertions(+), 1168 deletions(-) diff --git a/src/mapleall/maple_me/include/bb.h b/src/mapleall/maple_me/include/bb.h index 24d5327261..e0c01e71e8 100644 --- a/src/mapleall/maple_me/include/bb.h +++ b/src/mapleall/maple_me/include/bb.h @@ -14,18 +14,18 @@ */ #ifndef MAPLE_ME_INCLUDE_BB_H #define MAPLE_ME_INCLUDE_BB_H -#include "utils.h" #include "mpl_number.h" -#include "ptr_list_ref.h" #include "orig_symbol.h" -#include "ver_symbol.h" +#include "ptr_list_ref.h" #include "ssa.h" +#include "utils.h" +#include "ver_symbol.h" namespace maple { -class MeStmt; // circular dependency exists, no other choice -class MePhiNode; // circular dependency exists, no other choice +class MeStmt; // circular dependency exists, no other choice +class MePhiNode; // circular dependency exists, no other choice class PiassignMeStmt; // circular dependency exists, no other choice -class IRMap; // circular dependency exists, no other choice +class IRMap; // circular dependency exists, no other choice enum BBKind { kBBUnknown, // uninitialized kBBCondGoto, @@ -406,8 +406,17 @@ class BB { ASSERT(idx >= 0 && idx <= succFreq.size(), "sanity check"); succFreq[static_cast(idx)] = freq; } + void AddSuccFreq(uint64 freq, size_t pos = UINT32_MAX) { + ASSERT((pos <= succFreq.size() || pos == UINT32_MAX), "Invalid position."); + if (pos == UINT32_MAX) { + succFreq.push_back(freq); + } else { + succFreq.insert(succFreq.begin() + pos, freq); + } + } + // update edge frequency - void UpdateEdgeFreqs(); + void UpdateEdgeFreqs(bool updateSuccFreq = true); const MapleVector &GetSucc() const { return succ; @@ -487,7 +496,7 @@ class BB { auto iter = std::find(succ.begin(), succ.end(), bb); CHECK_FATAL(iter != std::end(succ), "%d is not the successor of %d", bb->UintID(), this->UintID()); CHECK_FATAL(succ.size() == succFreq.size(), "succfreq size %d doesn't match succ size %d", succFreq.size(), - succ.size()); + succ.size()); const size_t idx = static_cast(std::distance(succ.begin(), iter)); succFreq[idx] = freq; } @@ -496,7 +505,7 @@ class BB { succFreq.resize(succ.size()); } - BB* GetGroup() const { + BB *GetGroup() const { return group; } @@ -524,12 +533,13 @@ class BB { int GetPredIndex(const BB &predBB) const; int GetSuccIndex(const BB &succBB) const; void RemovePhiOpnd(int index); + private: bool IsInList(const MapleVector &bbList) const; int RemoveBBFromVector(MapleVector &bbVec) const; BBId id; - LabelIdx bbLabel = 0; // the BB's label + LabelIdx bbLabel = 0; // the BB's label MapleVector pred; // predecessor list MapleVector succ; // successor list // record the edge freq from curBB to succ BB @@ -540,8 +550,10 @@ class BB { uint32 frequency = 0; BBKind kind = kBBUnknown; uint32 attributes = 0; + public: StmtNodes stmtNodeList; + private: MeStmts meStmtList; BB *group; @@ -586,6 +598,7 @@ class SCCOfBBs { BB *GetEntry() { return entry; } + private: uint32 id; BB *entry; diff --git a/src/mapleall/maple_me/include/hdse.h b/src/mapleall/maple_me/include/hdse.h index c5a637c314..a00188d9c5 100644 --- a/src/mapleall/maple_me/include/hdse.h +++ b/src/mapleall/maple_me/include/hdse.h @@ -14,17 +14,17 @@ */ #ifndef MAPLE_ME_INCLUDE_HDSE_H #define MAPLE_ME_INCLUDE_HDSE_H +#include "alias_class.h" #include "bb.h" -#include "irmap.h" #include "dominance.h" -#include "alias_class.h" +#include "irmap.h" namespace maple { class MeIRMap; class HDSE { public: - HDSE(MIRModule &mod, const MapleVector &bbVec, BB &commonEntryBB, BB &commonExitBB, - Dominance &pDom, IRMap &map, const AliasClass *aliasClass, bool enabledDebug = false, bool decouple = false) + HDSE(MIRModule &mod, const MapleVector &bbVec, BB &commonEntryBB, BB &commonExitBB, Dominance &pDom, IRMap &map, + const AliasClass *aliasClass, bool enabledDebug = false, bool decouple = false) : hdseDebug(enabledDebug), mirModule(mod), bbVec(bbVec), @@ -48,6 +48,12 @@ class HDSE { void SetRemoveRedefine(bool val) { removeRedefine = val; } + void SetUpdateFreq(bool update) { + updateFreq = update; + } + bool UpdateFreq() { + return updateFreq; + } bool hdseDebug; bool hdseKeepRef = false; @@ -73,10 +79,11 @@ class HDSE { // Or the meExpr is opnd of a same type meExpr static const uint8 kExprTypeNotNull = 2; bool decoupleStatic = false; - bool needUNClean = false; // used to record if there's unreachable BB + bool needUNClean = false; // used to record if there's unreachable BB bool removeRedefine = false; // used to control if run ResolveContinuousRedefine() - MapleVector verstUseCounts; // index is vstIdx - std::forward_list backSubsCands; // backward substitution candidates + bool updateFreq = false; + MapleVector verstUseCounts; // index is vstIdx + std::forward_list backSubsCands; // backward substitution candidates private: void DseInit(); diff --git a/src/mapleall/maple_me/include/me_cfg.h b/src/mapleall/maple_me/include/me_cfg.h index d04e9addb1..8465e37e75 100644 --- a/src/mapleall/maple_me/include/me_cfg.h +++ b/src/mapleall/maple_me/include/me_cfg.h @@ -14,12 +14,13 @@ */ #ifndef MAPLE_ME_INCLUDE_ME_CFG_H #define MAPLE_ME_INCLUDE_ME_CFG_H -#include "me_function.h" #include "maple_phase.h" +#include "me_function.h" namespace maple { class MeCFG : public AnalysisResult { using BBPtrHolder = MapleVector; + public: using value_type = BBPtrHolder::value_type; using size_type = BBPtrHolder::size_type; @@ -86,7 +87,9 @@ class MeCFG : public AnalysisResult { hasDoWhile = hdw; } - MapleAllocator &GetAlloc() { return mecfgAlloc; } + MapleAllocator &GetAlloc() { + return mecfgAlloc; + } void SetNextBBId(uint32 currNextBBId) { nextBBId = currNextBBId; @@ -98,7 +101,9 @@ class MeCFG : public AnalysisResult { --nextBBId; } - MapleVector &GetAllBBs() { return bbVec; } + MapleVector &GetAllBBs() { + return bbVec; + } iterator begin() { return bbVec.begin(); @@ -296,8 +301,19 @@ class MeCFG : public AnalysisResult { void ConstructBBFreqFromStmtFreq(); void ConstructStmtFreq(); void ConstructEdgeFreqFromBBFreq(); - void UpdateEdgeFreqWithNewBBFreq(); - void VerifyBBFreq(); + void UpdateEdgeFreqWithBBFreq(); + int VerifyBBFreq(bool checkFatal = false); + void SetUpdateCFGFreq(bool b) { + updateFreq = b; + } + bool UpdateCFGFreq() const { + return updateFreq; + } + bool DumpIRProfileFile() const { + return dumpIRProfileFile; + } + void ClearFuncFreqInfo(); + private: void AddCatchHandlerForTryBB(BB &bb, MapleVector &exitBlocks); std::string ConstructFileNameToDump(const std::string &prefix) const; @@ -316,11 +332,14 @@ class MeCFG : public AnalysisResult { MapleAllocator mecfgAlloc; MeFunction &func; MapleSet patternSet; - BBPtrHolder bbVec; + BBPtrHolder bbVec; MapleUnorderedMap labelBBIdMap; MapleUnorderedMap bbTryNodeMap; // maps isTry bb to its try stmt MapleUnorderedMap endTryBB2TryBB; // maps endtry bb to its try bb bool hasDoWhile = false; + // following 2 variable are used in profileUse + bool updateFreq = false; // true to maintain cfg frequency in transform phase + bool dumpIRProfileFile = false; // true to dump cfg to files uint32 nextBBId = 0; // BB SCC @@ -331,10 +350,10 @@ class MeCFG : public AnalysisResult { }; MAPLE_FUNC_PHASE_DECLARE_BEGIN(MEMeCfg, MeFunction) - MeCFG *GetResult() { - return theCFG; - } - MeCFG *theCFG = nullptr; +MeCFG *GetResult() { + return theCFG; +} +MeCFG *theCFG = nullptr; MAPLE_MODULE_PHASE_DECLARE_END MAPLE_FUNC_PHASE_DECLARE_BEGIN(MECfgVerifyFrequency, MeFunction) MAPLE_FUNC_PHASE_DECLARE_END diff --git a/src/mapleall/maple_me/include/me_loop_canon.h b/src/mapleall/maple_me/include/me_loop_canon.h index 248a185127..cd76626574 100644 --- a/src/mapleall/maple_me/include/me_loop_canon.h +++ b/src/mapleall/maple_me/include/me_loop_canon.h @@ -21,7 +21,8 @@ namespace maple { // convert loop to do-while format class MeLoopCanon { public: - MeLoopCanon(MeFunction &f, bool enableDebugFunc) : func(f), isDebugFunc(enableDebugFunc) {} + MeLoopCanon(MeFunction &f, bool enableDebugFunc, bool updateFreq) + : func(f), isDebugFunc(enableDebugFunc), updateFreqs(updateFreq) {} virtual ~MeLoopCanon() = default; void NormalizationExitOfLoop(IdentifyLoops &meLoop); void NormalizationHeadAndPreHeaderOfLoop(Dominance &dom); @@ -33,6 +34,7 @@ class MeLoopCanon { void ResetIsCFGChange() { isCFGChange = false; } + private: void FindHeadBBs(Dominance &dom, const BB *bb, std::map> &heads) const; void SplitPreds(const std::vector &splitList, BB *splittedBB, BB *mergedBB); @@ -44,6 +46,7 @@ class MeLoopCanon { MeFunction &func; bool isDebugFunc; bool isCFGChange = false; + bool updateFreqs = false; }; MAPLE_FUNC_PHASE_DECLARE(MELoopCanon, MeFunction) diff --git a/src/mapleall/maple_me/include/me_loop_unrolling.h b/src/mapleall/maple_me/include/me_loop_unrolling.h index 4b0c81c075..1e5f57be8f 100644 --- a/src/mapleall/maple_me/include/me_loop_unrolling.h +++ b/src/mapleall/maple_me/include/me_loop_unrolling.h @@ -14,22 +14,23 @@ */ #ifndef MAPLE_ME_INCLUDE_LOOP_UNROLLING_H #define MAPLE_ME_INCLUDE_LOOP_UNROLLING_H -#include "me_scalar_analysis.h" +#include "me_cfg.h" +#include "me_dominance.h" #include "me_function.h" -#include "me_irmap_build.h" #include "me_ir.h" -#include "me_ssa_update.h" -#include "me_dominance.h" +#include "me_irmap_build.h" #include "me_loop_analysis.h" +#include "me_scalar_analysis.h" +#include "me_ssa_update.h" #include "profile.h" -#include "me_cfg.h" namespace maple { constexpr uint32 kMaxCost = 100; -constexpr uint8 unrollTimes[3] = { 8, 4, 2 }; // unrollTimes +constexpr uint8 unrollTimes[3] = {8, 4, 2}; // unrollTimes class LoopUnrolling { public: - enum ReturnKindOfFullyUnroll { + enum ReturnKindOfFullyUnroll + { kCanFullyUnroll, kCanNotSplitCondGoto, kCanNotFullyUnroll, @@ -37,14 +38,26 @@ class LoopUnrolling { LoopUnrolling(MeFunction &f, LoopDesc &l, MeIRMap &map, const MapleAllocator &alloc, std::map>> &candsTemp) - : func(&f), cfg(f.GetCfg()), loop(&l), irMap(&map), mpAllocator(alloc), - cands(candsTemp), lastNew2OldBB(mpAllocator.Adapter()), + : func(&f), + cfg(f.GetCfg()), + loop(&l), + irMap(&map), + mpAllocator(alloc), + cands(candsTemp), + lastNew2OldBB(mpAllocator.Adapter()), profValid(func->IsIRProfValid()) {} ~LoopUnrolling() = default; ReturnKindOfFullyUnroll LoopFullyUnroll(int64 tripCount); bool LoopPartialUnrollWithConst(uint64 tripCount); bool LoopPartialUnrollWithVar(CR &cr, CRNode &varNode, uint32 j); bool LoopUnrollingWithConst(uint64 tripCount, bool onlyFully = false); + void SetInstrumentProf(bool useInstrument) { + instrumentProf = useInstrument; + profValid = useInstrument; + } + bool GetInstrumentProf() const { + return instrumentProf; + } private: bool SplitCondGotoBB(); @@ -53,14 +66,12 @@ class LoopUnrolling { void SetLabelWithCondGotoOrGotoBB(BB &bb, std::unordered_map &old2NewBB, const BB &exitBB, LabelIdx oldlabIdx); - void ResetOldLabel2NewLabel(std::unordered_map &old2NewBB, BB &bb, - const BB &exitBB, BB &newHeadBB); - void ResetOldLabel2NewLabel2(std::unordered_map &old2NewBB, BB &bb, - const BB &exitBB, BB &newHeadBB); - void CopyLoopBody(BB &newHeadBB, std::unordered_map &old2NewBB, - std::set &labelBBs, const BB &exitBB, bool copyAllLoop); - void CopyLoopBodyForProfile(BB &newHeadBB, std::unordered_map &old2NewBB, - std::set &labelBBs, const BB &exitBB, bool copyAllLoop); + void ResetOldLabel2NewLabel(std::unordered_map &old2NewBB, BB &bb, const BB &exitBB, BB &newHeadBB); + void ResetOldLabel2NewLabel2(std::unordered_map &old2NewBB, BB &bb, const BB &exitBB, BB &newHeadBB); + void CopyLoopBody(BB &newHeadBB, std::unordered_map &old2NewBB, std::set &labelBBs, + const BB &exitBB, bool copyAllLoop); + void CopyLoopBodyForProfile(BB &newHeadBB, std::unordered_map &old2NewBB, std::set &labelBBs, + const BB &exitBB, bool copyAllLoop); void UpdateCondGotoBB(BB &bb, VarMeExpr &indVar, MeExpr &tripCount, MeExpr &unrollTimeExpr); void UpdateCondGotoStmt(BB &bb, VarMeExpr &indVar, MeExpr &tripCount, MeExpr &unrollTimeExpr, uint32 offset); void CreateIndVarAndCondGotoStmt(CR &cr, CRNode &varNode, BB &preCondGoto, uint32 unrollTime, uint32 i); @@ -85,7 +96,7 @@ class LoopUnrolling { bool canUnroll = true; MeFunction *func; - MeCFG *cfg; + MeCFG *cfg; LoopDesc *loop; MeIRMap *irMap; MapleAllocator mpAllocator; @@ -100,6 +111,7 @@ class LoopUnrolling { bool firstResetForAfterInsertGoto = true; bool resetFreqForUnrollWithVar = false; bool isUnrollWithVar = false; + bool instrumentProf = false; // use instrumented profiling }; class LoopUnrollingExecutor { @@ -109,8 +121,8 @@ class LoopUnrollingExecutor { static bool enableDebug; static bool enableDump; - void ExecuteLoopUnrolling(MeFunction &func, MeIRMap &irMap, - std::map>> &cands, IdentifyLoops &meLoop, const MapleAllocator &alloc); + void ExecuteLoopUnrolling(MeFunction &func, MeIRMap &irMap, std::map>> &cands, + IdentifyLoops &meLoop, const MapleAllocator &alloc); bool IsCFGChange() const { return isCFGChange; } diff --git a/src/mapleall/maple_me/src/bb.cpp b/src/mapleall/maple_me/src/bb.cpp index 7e7e7e5490..290a3c6caa 100644 --- a/src/mapleall/maple_me/src/bb.cpp +++ b/src/mapleall/maple_me/src/bb.cpp @@ -13,10 +13,13 @@ * See the Mulan PSL v2 for more details. */ #include "bb.h" + +#include + +#include "me_ir.h" +#include "me_ssa.h" #include "mempool_allocator.h" #include "ver_symbol.h" -#include "me_ssa.h" -#include "me_ir.h" namespace maple { std::string BB::StrAttribute() const { @@ -80,8 +83,8 @@ 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) { - mod->GetOut() << " freq: " << frequency << " "; + if (Options::profileUse && frequency >= 0) { + mod->GetOut() << " freq: " << frequency << " "; } mod->GetOut() << "]===============\n"; mod->GetOut() << "preds: "; @@ -299,8 +302,8 @@ void BB::MoveAllPredToSucc(BB *newSucc, BB *commonEntry) { } else { while (!GetPred().empty()) { BB *firstPred = GetPred(0); - if (IsSuccBB(*firstPred)) { // avoid replacing twice - firstPred->ReplaceSucc(this, newSucc, true); // firstPred will be removed from this->pred + if (IsSuccBB(*firstPred)) { // avoid replacing twice + firstPred->ReplaceSucc(this, newSucc, true); // firstPred will be removed from this->pred } } } @@ -336,8 +339,8 @@ void BB::MoveAllSuccToPred(BB *newPred, BB *commonExit) { } else { while (!GetSucc().empty()) { BB *firstSucc = GetSucc(0); - if (IsPredBB(*firstSucc)) { // avoid replacing twice - firstSucc->ReplacePred(this, newPred); // firstSucc will be removed from this->succ + if (IsPredBB(*firstSucc)) { // avoid replacing twice + firstSucc->ReplacePred(this, newPred); // firstSucc will be removed from this->succ } } } @@ -476,23 +479,31 @@ void BB::DumpMePhiList(const IRMap *irMap) { } } -// bb frequency is changed in tranform phase -// update its succ frequency by scaled value -void BB::UpdateEdgeFreqs() { +// update edge frequency by scaled value when bb frequency is changed +void BB::UpdateEdgeFreqs(bool updateBBFreqOfSucc) { int len = GetSucc().size(); ASSERT(len == GetSuccFreq().size(), "sanity check"); int64_t succFreqs = 0; for (int i = 0; i < len; i++) { succFreqs += GetSuccFreq()[i]; } - // early return if frequency is consistent - if (len == 0 || succFreqs == GetFrequency()) { - return; - } - for (size_t i = 0; i < len; ++i) { + int diff = abs(succFreqs - GetFrequency()); + if (len == 0 || diff <= 1) return; + int64_t scaledSum = 0; + for (int i = 0; i < len; i++) { int64_t sfreq = GetSuccFreq()[i]; int64_t scalefreq = (succFreqs == 0 ? (frequency / len) : (sfreq * frequency / succFreqs)); + scaledSum += scalefreq; SetSuccFreq(i, scalefreq); + // update succ frequency with new difference if needed + if (updateBBFreqOfSucc) { + auto *succ = GetSucc(i); + int64_t diff = scalefreq - sfreq; + int64_t succBBnewFreq = succ->GetFrequency() + diff; + if (succBBnewFreq >= 0) { + succ->SetFrequency(succBBnewFreq); + } + } } } diff --git a/src/mapleall/maple_me/src/hdse.cpp b/src/mapleall/maple_me/src/hdse.cpp index 9258b060e5..edf2096414 100644 --- a/src/mapleall/maple_me/src/hdse.cpp +++ b/src/mapleall/maple_me/src/hdse.cpp @@ -13,20 +13,22 @@ * See the Mulan PSL v2 for more details. */ #include "hdse.h" + #include -#include "ssa_mir_nodes.h" -#include "ver_symbol.h" + #include "irmap.h" -#include "opcode_info.h" #include "mir_preg.h" +#include "opcode_info.h" +#include "ssa_mir_nodes.h" #include "utils.h" +#include "ver_symbol.h" namespace maple { using namespace utils; void HDSE::DetermineUseCounts(MeExpr *x) { if (x->GetMeOp() == kMeOpVar) { - VarMeExpr *varmeexpr = static_cast(x); + VarMeExpr *varmeexpr = static_cast(x); verstUseCounts[varmeexpr->GetVstIdx()]++; return; } @@ -42,7 +44,7 @@ void HDSE::CheckBackSubsCandidacy(DassignMeStmt *dass) { if (dass->GetRHS()->GetMeOp() != kMeOpVar && dass->GetRHS()->GetMeOp() != kMeOpReg) { return; } - ScalarMeExpr *lhsscalar = static_cast(dass->GetLHS()); + ScalarMeExpr *lhsscalar = static_cast(dass->GetLHS()); OriginalSt *ost = lhsscalar->GetOst(); if (!ost->IsLocal()) { return; @@ -51,7 +53,7 @@ void HDSE::CheckBackSubsCandidacy(DassignMeStmt *dass) { if (ty->GetPrimType() == PTY_agg && ty->GetSize() <= 16) { return; } - ScalarMeExpr *rhsscalar = static_cast(dass->GetRHS()); + ScalarMeExpr *rhsscalar = static_cast(dass->GetRHS()); if (rhsscalar->GetDefBy() != kDefByMustDef) { return; } @@ -245,6 +247,13 @@ void HDSE::RemoveNotRequiredStmtsInBB(BB &bb) { } } bb.SetKind(kBBFallthru); + if (UpdateFreq()) { + int64_t succ0Freq = bb.GetSuccFreq()[0]; + bb.GetSuccFreq().resize(1); + bb.SetSuccFreq(0, bb.GetFrequency()); + ASSERT(bb.GetFrequency() >= succ0Freq, "sanity check"); + bb.GetSucc(0)->SetFrequency(bb.GetSucc(0)->GetFrequency() + (bb.GetFrequency() - succ0Freq)); + } } // A ivar contained in stmt if (stmt2NotNullExpr.find(mestmt) != stmt2NotNullExpr.end()) { @@ -267,8 +276,9 @@ void HDSE::RemoveNotRequiredStmtsInBB(BB &bb) { } else { // skip fold conditional branch because it may break recorded IfInfo. bool isPme = mirModule.CurFunction()->GetMeFunc()->GetPreMeFunc() != nullptr; - if (mestmt->IsCondBr() && !isPme) { // see if foldable to unconditional branch - CondGotoMeStmt *condbr = static_cast(mestmt); + if (mestmt->IsCondBr() && !isPme) { // see if foldable to unconditional branch + CondGotoMeStmt *condbr = static_cast(mestmt); + int64_t removedFreq = 0; if (!mirModule.IsJavaModule() && condbr->GetOpnd()->GetMeOp() == kMeOpConst) { CHECK_FATAL(IsPrimitiveInteger(condbr->GetOpnd()->GetPrimType()), "MeHDSE::DseProcess: branch condition must be integer type"); @@ -276,6 +286,9 @@ void HDSE::RemoveNotRequiredStmtsInBB(BB &bb) { (condbr->GetOp() == OP_brfalse && !condbr->GetOpnd()->IsZero())) { // delete the conditional branch BB *succbb = bb.GetSucc().back(); + if (UpdateFreq()) { + removedFreq = bb.GetSuccFreq().back(); + } succbb->RemoveBBFromPred(bb, false); if (succbb->GetPred().empty()) { needUNClean = true; @@ -286,6 +299,9 @@ void HDSE::RemoveNotRequiredStmtsInBB(BB &bb) { } else { // change to unconditional branch BB *succbb = bb.GetSucc().front(); + if (UpdateFreq()) { + removedFreq = bb.GetSuccFreq().front(); + } succbb->RemoveBBFromPred(bb, false); if (succbb->GetPred().empty()) { needUNClean = true; @@ -295,6 +311,11 @@ void HDSE::RemoveNotRequiredStmtsInBB(BB &bb) { GotoMeStmt *gotomestmt = irMap.New(condbr->GetOffset()); bb.ReplaceMeStmt(condbr, gotomestmt); } + if (UpdateFreq()) { + bb.GetSuccFreq().resize(1); + bb.SetSuccFreq(0, bb.GetFrequency()); + bb.GetSucc(0)->SetFrequency(bb.GetSucc(0)->GetFrequency() + removedFreq); + } } else { DetermineUseCounts(condbr->GetOpnd()); } @@ -303,17 +324,17 @@ void HDSE::RemoveNotRequiredStmtsInBB(BB &bb) { DetermineUseCounts(mestmt->GetOpnd(i)); } if (mestmt->GetOp() == OP_dassign) { - CheckBackSubsCandidacy(static_cast(mestmt)); + CheckBackSubsCandidacy(static_cast(mestmt)); } } } mestmt = nextstmt; } // update verstUseCOunts for uses in phi operands - for (std::pair phipair : bb.GetMePhiList()) { + for (std::pair phipair : bb.GetMePhiList()) { if (phipair.second->GetIsLive()) { for (ScalarMeExpr *phiOpnd : phipair.second->GetOpnds()) { - VarMeExpr *varx = dynamic_cast(phiOpnd); + VarMeExpr *varx = dynamic_cast(phiOpnd); if (varx) { verstUseCounts[varx->GetVstIdx()]++; } @@ -332,7 +353,7 @@ bool HDSE::NeedNotNullCheck(MeExpr &meExpr, const BB &bb) { if (meExpr.GetOp() == OP_addrof) { return false; } - if (meExpr.GetOp() == OP_iaddrof && static_cast(meExpr).GetFieldID() > 0) { + if (meExpr.GetOp() == OP_iaddrof && static_cast(meExpr).GetFieldID() > 0) { return false; } @@ -444,8 +465,7 @@ void HDSE::MarkRegDefByStmt(RegMeExpr ®MeExpr) { MarkPhiRequired(regMeExpr.GetDefPhi()); break; case kDefByChi: { - ASSERT(regMeExpr.GetOst()->GetIndirectLev() > 0, - "MarkRegDefByStmt: preg cannot be defined by chi"); + ASSERT(regMeExpr.GetOst()->GetIndirectLev() > 0, "MarkRegDefByStmt: preg cannot be defined by chi"); auto &defChi = regMeExpr.GetDefChi(); MarkChiNodeRequired(defChi); break; @@ -585,8 +605,7 @@ bool HDSE::ExprNonDeletable(const MeExpr &meExpr) const { } case kMeOpVar: { auto &varMeExpr = static_cast(meExpr); - return varMeExpr.IsVolatile() || - (decoupleStatic && varMeExpr.GetOst()->GetMIRSymbol()->IsGlobal()); + return varMeExpr.IsVolatile() || (decoupleStatic && varMeExpr.GetOst()->GetMIRSymbol()->IsGlobal()); } case kMeOpIvar: { auto &opIvar = static_cast(meExpr); @@ -616,7 +635,7 @@ bool HDSE::HasNonDeletableExpr(const MeStmt &meStmt) const { switch (op) { case OP_dassign: { auto &dasgn = static_cast(meStmt); - VarMeExpr *varMeExpr = static_cast(dasgn.GetVarLHS()); + VarMeExpr *varMeExpr = static_cast(dasgn.GetVarLHS()); return (varMeExpr != nullptr && varMeExpr->IsVolatile()) || ExprNonDeletable(*dasgn.GetRHS()) || (hdseKeepRef && dasgn.Propagated()) || dasgn.GetWasMayDassign() || (decoupleStatic && varMeExpr != nullptr && varMeExpr->GetOst()->GetMIRSymbol()->IsGlobal()); @@ -630,8 +649,8 @@ bool HDSE::HasNonDeletableExpr(const MeStmt &meStmt) const { case OP_iassign: { auto &iasgn = static_cast(meStmt); auto &ivarMeExpr = static_cast(*iasgn.GetLHSVal()); - return ivarMeExpr.IsVolatile() || ivarMeExpr.IsFinal() || - ExprNonDeletable(*iasgn.GetLHSVal()->GetBase()) || ExprNonDeletable(*iasgn.GetRHS()); + return ivarMeExpr.IsVolatile() || ivarMeExpr.IsFinal() || ExprNonDeletable(*iasgn.GetLHSVal()->GetBase()) || + ExprNonDeletable(*iasgn.GetRHS()); } default: return false; @@ -860,4 +879,4 @@ void HDSE::DoHDSE() { } RemoveNotRequiredStmts(); } -} // namespace maple +} // namespace maple diff --git a/src/mapleall/maple_me/src/me_bb_layout.cpp b/src/mapleall/maple_me/src/me_bb_layout.cpp index c60eefd96b..e515f12797 100644 --- a/src/mapleall/maple_me/src/me_bb_layout.cpp +++ b/src/mapleall/maple_me/src/me_bb_layout.cpp @@ -13,13 +13,14 @@ * See the Mulan PSL v2 for more details. */ #include "me_bb_layout.h" -#include "me_cfg.h" + #include "bb.h" +#include "maple_phase.h" +#include "me_cfg.h" +#include "me_critical_edge.h" #include "me_irmap.h" #include "me_option.h" #include "me_predict.h" -#include "maple_phase.h" -#include "me_critical_edge.h" // This BB layout strategy strictly obeys source ordering when inside try blocks. // This Optimization will reorder the bb layout. it start from the first bb of func. @@ -114,12 +115,10 @@ void BBLayout::BuildChainForLoops() { auto &loops = meLoop->GetMeLoops(); // sort loops from inner most to outer most // need use the same sort rules as prediction? - std::stable_sort(loops.begin(), loops.end(), [](const LoopDesc *loop1, const LoopDesc *loop2) { - return loop1->nestDepth > loop2->nestDepth; - }); + std::stable_sort(loops.begin(), loops.end(), + [](const LoopDesc *loop1, const LoopDesc *loop2) { return loop1->nestDepth > loop2->nestDepth; }); // build chain for loops one by one - auto *context = - layoutAlloc.GetMemPool()->New>(cfg->NumBBs(), false, layoutAlloc.Adapter()); + auto *context = layoutAlloc.GetMemPool()->New>(cfg->NumBBs(), false, layoutAlloc.Adapter()); for (auto *loop : loops) { BuildChainForLoop(loop, context); } @@ -188,13 +187,13 @@ void BBLayout::DoBuildChain(const BB &header, BBChain &chain, const MapleVector< } bool BBLayout::IsCandidateSucc(const BB &bb, const BB &succ, const MapleVector *context) { - if (!IsBBInCurrContext(succ, context)) { // succ must be in the current context (current loop or current func) + if (!IsBBInCurrContext(succ, context)) { // succ must be in the current context (current loop or current func) return false; } - if (bb2chain[succ.GetBBId()] == bb2chain[bb.GetBBId()]) { // bb and succ should belong to different chains + if (bb2chain[succ.GetBBId()] == bb2chain[bb.GetBBId()]) { // bb and succ should belong to different chains return false; } - if (succ.GetBBId() == 1) { // special case, exclude common exit BB + if (succ.GetBBId() == 1) { // special case, exclude common exit BB return false; } return true; @@ -240,7 +239,7 @@ BB *BBLayout::GetBestSucc(BB &bb, const BBChain &chain, const MapleVector continue; } uint32 currEdgeFreq = static_cast(bb.GetEdgeFreq(i)); // attention: entryBB->succFreq[i] is always 0 - if (bb.GetBBId() == 0) { // special case for common entry BB + if (bb.GetBBId() == 0) { // special case for common entry BB CHECK_FATAL(bb.GetSucc().size() == 1, "common entry BB should not have more than 1 succ"); bestSucc = succ; break; @@ -253,7 +252,7 @@ BB *BBLayout::GetBestSucc(BB &bb, const BBChain &chain, const MapleVector if (bestSucc != nullptr) { if (debugChainLayout) { LogInfo::MapleLogger() << "Select [range1 succ ]: "; - LogInfo::MapleLogger() << bb.GetBBId() << " -> " << bestSucc->GetBBId() << std::endl; + LogInfo::MapleLogger() << bb.GetBBId() << " -> " << bestSucc->GetBBId() << std::endl; } return bestSucc; } @@ -267,12 +266,12 @@ BB *BBLayout::GetBestSucc(BB &bb, const BBChain &chain, const MapleVector continue; } bool useBBFreq = false; - if (useBBFreq) { // use bb freq + if (useBBFreq) { // use bb freq if (header->GetFrequency() > bestFreq) { // find max bb freq bestFreq = header->GetFrequency(); bestSucc = header; } - } else { // use edge freq + } else { // use edge freq uint32 subBestFreq = 0; for (auto *pred : header->GetPred()) { uint32 curFreq = static_cast(pred->GetEdgeFreq(header)); @@ -595,8 +594,7 @@ void BBLayout::OptimizeBranchTarget(BB &bb) { // condgoto's succ layout: [0] fallthru succ, [1] target succ, [2-...] eh succ/wontexit succ // goto's succ layout: [0] target succ, [1-...] eh succ/wontexit succ BB *brTargetBB = bb.GetKind() == kBBCondGoto ? bb.GetSucc(1) : bb.GetSucc(0); - CHECK_FATAL((bb.GetKind() != kBBCondGoto || bb.GetSucc(1) != bb.GetSucc(0)), - "target is same as fallthru"); + CHECK_FATAL((bb.GetKind() != kBBCondGoto || bb.GetSucc(1) != bb.GetSucc(0)), "target is same as fallthru"); if (brTargetBB->GetAttributes(kBBAttrWontExit)) { return; } @@ -608,8 +606,7 @@ void BBLayout::OptimizeBranchTarget(BB &bb) { bbVisited[bb.GetBBId().GetIdx()] = true; OptimizeBranchTarget(*brTargetBB); // optimize stmt - BB *newTargetBB = - (brTargetBB->GetKind() == kBBCondGoto) ? brTargetBB->GetSucc(1) : brTargetBB->GetSucc(0); + BB *newTargetBB = (brTargetBB->GetKind() == kBBCondGoto) ? brTargetBB->GetSucc(1) : brTargetBB->GetSucc(0); if (newTargetBB == brTargetBB) { return; } @@ -682,7 +679,7 @@ void BBLayout::AddBB(BB &bb) { // If the pred bb is goto bb and the target bb of goto bb is the current bb which is be added to layoutBBs, change the // goto bb to fallthru bb. if (layoutBBs.size() > 1) { - BB *predBB = layoutBBs.at(layoutBBs.size() - 2); // Get the pred of bb. + BB *predBB = layoutBBs.at(layoutBBs.size() - 2); // Get the pred of bb. if (predBB->GetKind() != kBBGoto) { return; } @@ -879,7 +876,6 @@ void BBLayout::RemoveUnreachable(BB &bb) { } } - void BBLayout::UpdateNewBBWithAttrTry(const BB &bb, BB &fallthru) const { auto tryBB = &bb; fallthru.SetAttributes(kBBAttrIsTry); @@ -944,6 +940,9 @@ BB *BBLayout::CreateGotoBBAfterCondBB(BB &bb, BB &fallthru) { index--; fallthru.AddPred(*newFallthru, index); newFallthru->SetFrequency(fallthru.GetFrequency()); + if (cfg->UpdateCFGFreq()) { + newFallthru->PushBackSuccFreq(fallthru.GetFrequency()); + } if (enabledDebug) { LogInfo::MapleLogger() << "Created fallthru and goto original fallthru" << '\n'; } @@ -953,7 +952,9 @@ BB *BBLayout::CreateGotoBBAfterCondBB(BB &bb, BB &fallthru) { } void BBLayout::OptimizeEmptyFallThruBB(BB &bb) { - if (needDealWithTryBB) { return; } + if (needDealWithTryBB) { + return; + } auto *fallthru = bb.GetSucc().front(); while (fallthru && (fallthru->GetPred().size() == 1) && (BBEmptyAndFallthru(*fallthru) || BBContainsOnlyGoto(*fallthru)) && @@ -963,7 +964,7 @@ void BBLayout::OptimizeEmptyFallThruBB(BB &bb) { bb.ReplaceSucc(fallthru, newFallthru); ASSERT(fallthru->GetPred().empty(), "fallthru should not has other pred"); ChangeToFallthruFromCondGoto(bb); - bb.GetSucc().resize(1); // resize succ to 1 + bb.GetSucc().resize(1); // resize succ to 1 } else if (newFallthru->GetPred().size() == 1) { if (newFallthru->GetBBLabel() != 0) { // reset newFallthru label @@ -981,7 +982,7 @@ void BBLayout::OptimizeEmptyFallThruBB(BB &bb) { } void BBLayout::DumpBBPhyOrder() const { - LogInfo::MapleLogger() << func.GetName() << " final BB order " << '\n'; + LogInfo::MapleLogger() << func.GetName() << " final BB order " << '\n'; for (auto bb : layoutBBs) { LogInfo::MapleLogger() << bb->GetBBId(); if (bb != layoutBBs.back()) { @@ -1058,8 +1059,7 @@ void BBLayout::LayoutWithoutProf() { } ASSERT(!(isTry && GetTryOutstanding()), "cannot emit another try if last try has not been ended"); if (nextBB->GetAttributes(kBBAttrIsTryEnd)) { - ASSERT(cfg->GetTryBBFromEndTryBB(nextBB) == nextBB || - IsBBLaidOut(cfg->GetTryBBFromEndTryBB(nextBB)->GetBBId()), + ASSERT(cfg->GetTryBBFromEndTryBB(nextBB) == nextBB || IsBBLaidOut(cfg->GetTryBBFromEndTryBB(nextBB)->GetBBId()), "cannot emit endtry bb before its corresponding try bb"); } } @@ -1203,8 +1203,8 @@ void BBLayout::BuildEdges() { allEdges.emplace_back(layoutAlloc.GetMemPool()->New(bb, dest, w)); } } - std::stable_sort(allEdges.begin(), allEdges.end(), [](const BBEdge *edge1, const BBEdge *edge2) { - return edge1->GetWeight() > edge2->GetWeight(); }); + std::stable_sort(allEdges.begin(), allEdges.end(), + [](const BBEdge *edge1, const BBEdge *edge2) { return edge1->GetWeight() > edge2->GetWeight(); }); } BB *BBLayout::GetBBFromEdges() { @@ -1213,8 +1213,8 @@ BB *BBLayout::GetBBFromEdges() { BB *srcBB = edge->GetSrcBB(); BB *destBB = edge->GetDestBB(); if (enabledDebug) { - LogInfo::MapleLogger() << srcBB->GetBBId() << "->" << destBB->GetBBId() << " freq " - << srcBB->GetEdgeFreq(destBB) << '\n'; + LogInfo::MapleLogger() << srcBB->GetBBId() << "->" << destBB->GetBBId() << " freq " << srcBB->GetEdgeFreq(destBB) + << '\n'; } if (!laidOut[srcBB->GetBBId()]) { @@ -1251,7 +1251,7 @@ BB *BBLayout::NextBBProf(BB &bb) { return NextBBProf(*succBB); } // max freq intial - uint64 maxFreq = 0; + uint64 maxFreq = 0; size_t idx = 0; bool found = false; for (size_t i = 0; i < bb.GetSucc().size(); ++i) { @@ -1281,11 +1281,14 @@ void BBLayout::RebuildFreq() { auto *hook = phase->GetAnalysisInfoHook(); hook->ForceEraseAnalysisPhase(func.GetUniqueID(), &MEDominance::id); hook->ForceEraseAnalysisPhase(func.GetUniqueID(), &MELoopAnalysis::id); - dom = static_cast( - hook->ForceRunAnalysisPhase>(&MEDominance::id, func))->GetResult(); + dom = static_cast(hook->ForceRunAnalysisPhase>(&MEDominance::id, func)) + ->GetResult(); meLoop = static_cast( - hook->ForceRunAnalysisPhase>(&MELoopAnalysis::id, func))->GetResult(); - MePrediction::RebuildFreq(func, *dom, *meLoop); + hook->ForceRunAnalysisPhase>(&MELoopAnalysis::id, func)) + ->GetResult(); + if (!cfg->UpdateCFGFreq()) { + MePrediction::RebuildFreq(func, *dom, *meLoop); + } } void BBLayout::LayoutWithProf(bool useChainLayout) { @@ -1345,8 +1348,7 @@ void BBLayout::VerifyBB() { if (bb->GetKind() == kBBCondGoto) { auto *fallthru = bb->GetSucc(0); auto *targetBB = bb->GetSucc(1); - if (fallthru == targetBB || - (BBEmptyAndFallthru(*fallthru) && (fallthru->GetSucc(0) == targetBB))) { + if (fallthru == targetBB || (BBEmptyAndFallthru(*fallthru) && (fallthru->GetSucc(0) == targetBB))) { LogInfo::MapleLogger() << "WARN: cond BB " << bb->GetBBId() << " has same target"; } } @@ -1374,11 +1376,15 @@ bool MEBBLayout::PhaseRun(maple::MeFunction &f) { bbLayout->RunLayout(); f.SetLaidOutBBs(bbLayout->GetBBs()); - if (DEBUGFUNC_NEWPM(f)) { + if (DEBUGFUNC_NEWPM(f) || Options::profileUse) { // verify CFG : check condBB's succs should be different bbLayout->VerifyBB(); bbLayout->DumpBBPhyOrder(); - cfg->DumpToFile("afterBBLayout", false); + if (cfg->UpdateCFGFreq() && cfg->DumpIRProfileFile()) { + cfg->DumpToFile("after-bblayout", false, true); + } else { + cfg->DumpToFile("afterBBLayout", false); + } } return true; } diff --git a/src/mapleall/maple_me/src/me_cfg.cpp b/src/mapleall/maple_me/src/me_cfg.cpp index a46f55b1da..4f6d20be4c 100644 --- a/src/mapleall/maple_me/src/me_cfg.cpp +++ b/src/mapleall/maple_me/src/me_cfg.cpp @@ -13,30 +13,33 @@ * See the Mulan PSL v2 for more details. */ #include "me_cfg.h" -#include + #include +#include #include + #include "bb.h" -#include "ssa_mir_nodes.h" -#include "me_irmap.h" -#include "mir_builder.h" #include "me_critical_edge.h" +#include "me_irmap.h" #include "me_loop_canon.h" +#include "mir_builder.h" #include "mir_lower.h" +#include "ssa_mir_nodes.h" namespace { constexpr int kFuncNameLenLimit = 80; } namespace maple { -#define MATCH_STMT(stmt, kOpCode) do { \ - while ((stmt) != nullptr && (stmt)->GetOpCode() == OP_comment) { \ - (stmt) = (stmt)->GetNext(); \ - } \ - if ((stmt) == nullptr || (stmt)->GetOpCode() != (kOpCode)) { \ - return false; \ - } \ -} while (0) // END define +#define MATCH_STMT(stmt, kOpCode) \ + do { \ + while ((stmt) != nullptr && (stmt)->GetOpCode() == OP_comment) { \ + (stmt) = (stmt)->GetNext(); \ + } \ + if ((stmt) == nullptr || (stmt)->GetOpCode() != (kOpCode)) { \ + return false; \ + } \ + } while (0) // END define // determine if need to be replaced by assertnonnull bool MeCFG::IfReplaceWithAssertNonNull(const BB &bb) const { const StmtNode *stmt = bb.GetStmtNodes().begin().d(); @@ -308,7 +311,7 @@ bool MeCFG::FindUse(const StmtNode &stmt, StIdx stIdx) const { return FindExprUse(*iNode.GetRHS(), stIdx); } } - CASE_OP_ASSERT_NONNULL + CASE_OP_ASSERT_NONNULL case OP_eval: case OP_free: case OP_switch: { @@ -511,7 +514,6 @@ void MeCFG::FixMirCFG() { } } - // replace "if() throw NPE()" with assertnonnull void MeCFG::ReplaceWithAssertnonnull() { constexpr char rnnTypeName[] = @@ -681,7 +683,7 @@ void MeCFG::ConvertPhiList2IdentityAssigns(BB &meBB) const { DassignNode *dassign = func.GetMIRModule().GetMIRBuilder()->CreateStmtDassign(*st, 0, dread2); func.GetMeSSATab()->GetStmtsSSAPart().SetSSAPartOf( *dassign, func.GetMeSSATab()->GetStmtsSSAPart().GetSSAPartMp()->New( - &func.GetMeSSATab()->GetStmtsSSAPart().GetSSAPartAlloc())); + &func.GetMeSSATab()->GetStmtsSSAPart().GetSSAPartAlloc())); auto *theSSAPart = static_cast(func.GetMeSSATab()->GetStmtsSSAPart().SSAPartOf(*dassign)); theSSAPart->SetSSAVar(*((*phiIt).second.GetResult())); @@ -700,15 +702,15 @@ void MeCFG::ConvertMePhiList2IdentityAssigns(BB &meBB) const { CHECK_FATAL(ost, "ost is nullptr!"); if (ost->IsSymbolOst() && ost->GetIndirectLev() == 0) { MePhiNode *varPhi = phiIt->second; - auto *dassign = func.GetIRMap()->NewInPool( - static_cast(varPhi->GetLHS()), varPhi->GetOpnd(0)); + auto *dassign = + func.GetIRMap()->NewInPool(static_cast(varPhi->GetLHS()), varPhi->GetOpnd(0)); dassign->SetBB(varPhi->GetDefBB()); dassign->SetIsLive(varPhi->GetIsLive()); meBB.PrependMeStmt(dassign); } else if (ost->IsPregOst()) { MePhiNode *regPhi = phiIt->second; - auto *regAss = func.GetIRMap()->New( - OP_regassign, static_cast(regPhi->GetLHS()), regPhi->GetOpnd(0)); + auto *regAss = func.GetIRMap()->New(OP_regassign, static_cast(regPhi->GetLHS()), + regPhi->GetOpnd(0)); regPhi->GetLHS()->SetDefByStmt(*regAss); regPhi->GetLHS()->SetDefBy(kDefByStmt); regAss->SetBB(regPhi->GetDefBB()); @@ -779,6 +781,10 @@ void MeCFG::WontExitAnalysis() { newBB->SetKindReturn(); newBB->SetAttributes(kBBAttrArtificial); bb->AddSucc(*newBB); + // newBB is added as succ of bb, set freq 0 as its edge frequency + if (updateFreq) { + bb->PushBackSuccFreq(0); + } GetCommonExitBB()->AddExit(*newBB); bb->FindWillExitBBs(currVisitedBBs); // Mark other bbs in the loop as visited. } @@ -835,15 +841,13 @@ void MeCFG::VerifyLabels() const { if (stmtNodes.back().GetOpCode() == OP_throw) { continue; } - ASSERT( - GetLabelBBAt(static_cast(stmtNodes.back()).GetOffset())->GetBBLabel() == - static_cast(stmtNodes.back()).GetOffset(), - "undefined label in goto"); + ASSERT(GetLabelBBAt(static_cast(stmtNodes.back()).GetOffset())->GetBBLabel() == + static_cast(stmtNodes.back()).GetOffset(), + "undefined label in goto"); } else if (mirBB->GetKind() == kBBCondGoto) { - ASSERT( - GetLabelBBAt(static_cast(stmtNodes.back()).GetOffset())->GetBBLabel() == - static_cast(stmtNodes.back()).GetOffset(), - "undefined label in conditional branch"); + ASSERT(GetLabelBBAt(static_cast(stmtNodes.back()).GetOffset())->GetBBLabel() == + static_cast(stmtNodes.back()).GetOffset(), + "undefined label in conditional branch"); } else if (mirBB->GetKind() == kBBSwitch) { auto &switchStmt = static_cast(stmtNodes.back()); LabelIdx targetLabIdx = switchStmt.GetDefaultLabel(); @@ -966,7 +970,7 @@ void MeCFG::DumpToFile(const std::string &prefix, bool dumpInStrs, bool dumpEdge return; } std::ofstream cfgFile; - std::streambuf *coutBuf = LogInfo::MapleLogger().rdbuf(); // keep original cout buffer + std::streambuf *coutBuf = LogInfo::MapleLogger().rdbuf(); // keep original cout buffer std::streambuf *buf = cfgFile.rdbuf(); LogInfo::MapleLogger().rdbuf(buf); const std::string &fileName = ConstructFileNameToDump(prefix); @@ -980,7 +984,8 @@ void MeCFG::DumpToFile(const std::string &prefix, bool dumpInStrs, bool dumpEdge if (bIt == common_exit()) { // specical case for common_exit_bb for (auto it = bb->GetPred().begin(); it != bb->GetPred().end(); ++it) { - cfgFile << "BB" << (*it)->GetBBId()<< " -> " << "BB" << bb->GetBBId() << "[style=dotted];\n"; + cfgFile << "BB" << (*it)->GetBBId() << " -> " + << "BB" << bb->GetBBId() << "[style=dotted];\n"; } continue; } @@ -989,7 +994,8 @@ void MeCFG::DumpToFile(const std::string &prefix, bool dumpInStrs, bool dumpEdge } for (auto it = bb->GetSucc().begin(); it != bb->GetSucc().end(); ++it) { - cfgFile << "BB" << bb->GetBBId() << " -> " << "BB" << (*it)->GetBBId(); + cfgFile << "BB" << bb->GetBBId() << " -> " + << "BB" << (*it)->GetBBId(); if (bb == GetCommonEntryBB()) { cfgFile << "[style=dotted]"; continue; @@ -1013,20 +1019,19 @@ void MeCFG::DumpToFile(const std::string &prefix, bool dumpInStrs, bool dumpEdge } } if (laidOut != nullptr) { - static std::vector colors = { - "indianred1", "darkorange1", "lightyellow1", "green3", "cyan", "dodgerblue2", "purple2" - }; + static std::vector colors = {"indianred1", "darkorange1", "lightyellow1", "green3", + "cyan", "dodgerblue2", "purple2"}; uint32 colorIdx = 0; size_t clusterSize = laidOut->size() / colors.size(); uint32 cnt = 0; for (uint32 i = 0; i < laidOut->size(); ++i) { auto *bb = (*laidOut)[i]; auto bbId = bb->GetBBId(); - std::string bbNameLabel = dumpEdgeFreq ? - "BB" + std::to_string(bbId.GetIdx()) + "_freq_" + std::to_string(bb->GetFrequency()) : - "BB" + std::to_string(bbId.GetIdx()); - cfgFile << "BB" << bbId << "[style=filled, color=" << colors[colorIdx % colors.size()] << ", label=" << - bbNameLabel << "__" << i << "]\n"; + std::string bbNameLabel = + dumpEdgeFreq ? "BB" + std::to_string(bbId.GetIdx()) + "_freq_" + std::to_string(bb->GetFrequency()) + : "BB" + std::to_string(bbId.GetIdx()); + cfgFile << "BB" << bbId << "[style=filled, color=" << colors[colorIdx % colors.size()] + << ", label=" << bbNameLabel << "__" << i << "]\n"; ++cnt; if (cnt > clusterSize) { cnt = 0; @@ -1147,8 +1152,8 @@ bool MeCFG::UnifyRetBBs() { if (func.GetMirFunc()->IsReturnVoid()) { newRetBB->SetFirst(mirBuilder->CreateStmtReturn(nullptr)); } else { - unifiedFuncRet = mirBuilder->CreateSymbol(func.GetMirFunc()->GetReturnTyIdx(), "unified_func_ret", - kStVar, kScAuto, func.GetMirFunc(), kScopeLocal); + unifiedFuncRet = mirBuilder->CreateSymbol(func.GetMirFunc()->GetReturnTyIdx(), "unified_func_ret", kStVar, kScAuto, + func.GetMirFunc(), kScopeLocal); newRetBB->SetFirst(mirBuilder->CreateStmtReturn(mirBuilder->CreateExprDread(*unifiedFuncRet))); } newRetBB->SetLast(newRetBB->GetStmtNodes().begin().d()); @@ -1364,8 +1369,8 @@ void MeCFG::CreateBasicBlocks() { } break; } - // fall thru to handle as return - [[clang::fallthrough]]; + // fall thru to handle as return + [[clang::fallthrough]]; case OP_gosub: case OP_retsub: case OP_return: { @@ -1397,7 +1402,7 @@ void MeCFG::CreateBasicBlocks() { if (!curBB->IsEmpty()) { StmtNode *lastStmt = stmt->GetPrev(); ASSERT(curBB->GetStmtNodes().rbegin().base().d() == nullptr || - curBB->GetStmtNodes().rbegin().base().d() == lastStmt, + curBB->GetStmtNodes().rbegin().base().d() == lastStmt, "something wrong building BB"); curBB->SetLast(lastStmt); if (curBB->GetKind() == kBBUnknown) { @@ -1430,7 +1435,7 @@ void MeCFG::CreateBasicBlocks() { // prepare a new bb StmtNode *lastStmt = stmt->GetPrev(); ASSERT(curBB->GetStmtNodes().rbegin().base().d() == nullptr || - curBB->GetStmtNodes().rbegin().base().d() == lastStmt, + curBB->GetStmtNodes().rbegin().base().d() == lastStmt, "something wrong building BB"); curBB->SetLast(lastStmt); if (curBB->GetKind() == kBBUnknown) { @@ -1461,7 +1466,7 @@ void MeCFG::CreateBasicBlocks() { // prepare a new bb StmtNode *lastStmt = stmt->GetPrev(); ASSERT(curBB->GetStmtNodes().rbegin().base().d() == nullptr || - curBB->GetStmtNodes().rbegin().base().d() == lastStmt, + curBB->GetStmtNodes().rbegin().base().d() == lastStmt, "something wrong building BB"); curBB->SetLast(lastStmt); if (curBB->GetKind() == kBBUnknown) { @@ -1592,7 +1597,7 @@ void MeCFG::CreateBasicBlocks() { } } } while (nextStmt != nullptr); - ASSERT(tryStmt == nullptr, "unclosed try"); // tryandendtry should be one-one mapping + ASSERT(tryStmt == nullptr, "unclosed try"); // tryandendtry should be one-one mapping ASSERT(lastTryBB == nullptr, "unclosed tryBB"); // tryandendtry should be one-one mapping auto *lastBB = curBB; if (lastBB->IsEmpty()) { @@ -1622,8 +1627,7 @@ void MeCFG::BBTopologicalSort(SCCOfBBs &scc) { if (succ == nullptr) { continue; } - if (inQueue.find(succ) != inQueue.end() || - std::find(bbs.begin(), bbs.end(), succ) == bbs.end()) { + if (inQueue.find(succ) != inQueue.end() || std::find(bbs.begin(), bbs.end(), succ) == bbs.end()) { continue; } bool predAllVisited = true; @@ -1651,8 +1655,8 @@ void MeCFG::BBTopologicalSort(SCCOfBBs &scc) { } void MeCFG::BuildSCCDFS(BB &bb, uint32 &visitIndex, std::vector &sccNodes, - std::vector &visitedOrder, std::vector &lowestOrder, - std::vector &inStack, std::stack &visitStack) { + std::vector &visitedOrder, std::vector &lowestOrder, std::vector &inStack, + std::stack &visitStack) { uint32 id = bb.UintID(); visitedOrder[id] = visitIndex; lowestOrder[id] = visitIndex; @@ -1780,7 +1784,7 @@ void MeCFG::UpdateBranchTarget(BB &currBB, const BB &oldTarget, BB &newTarget, M } } else if (currBB.GetKind() == kBBCondGoto) { if (currBB.GetSucc(0) == &newTarget) { - return; // no need to update offset for fallthru BB + return; // no need to update offset for fallthru BB } BB *gotoBB = currBB.GetSucc().at(1); ASSERT(gotoBB == &newTarget, "[FUNC: %s]newTarget is not one of CondGoto's succ BB", func.GetName().c_str()); @@ -1817,7 +1821,7 @@ void MeCFG::UpdateBranchTarget(BB &currBB, const BB &oldTarget, BB &newTarget, M switchStmt.SetDefaultLabel(label); } for (size_t i = 0; i < switchStmt.GetSwitchTable().size(); ++i) { - LabelIdx caseLabel = switchStmt.GetSwitchTable().at(i).second; + LabelIdx caseLabel = switchStmt.GetSwitchTable().at(i).second; if (caseLabel == oldLabelIdx) { switchStmt.UpdateCaseLabelAt(i, label); } @@ -1874,7 +1878,7 @@ void MeCFG::ConstructEdgeFreqFromBBFreq() { // set bb frequency from stmt record void MeCFG::ConstructBBFreqFromStmtFreq() { - FuncProfInfo* funcData = func.GetMirFunc()->GetFuncProfData(); + FuncProfInfo *funcData = func.GetMirFunc()->GetFuncProfData(); if (!funcData) { return; } @@ -1884,13 +1888,14 @@ void MeCFG::ConstructBBFreqFromStmtFreq() { 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 { - LogInfo::MapleLogger() << "ERROR:: bb " << (*bIt)->GetBBId() << "frequency is not set" << "\n"; + LogInfo::MapleLogger() << "ERROR:: bb " << (*bIt)->GetBBId() << "frequency is not set" + << "\n"; ASSERT(0, "no freq set"); } } @@ -1911,10 +1916,13 @@ void MeCFG::ConstructBBFreqFromStmtFreq() { ConstructEdgeFreqFromBBFreq(); // clear stmtFreqs since cfg frequency is create funcData->stmtFreqs.clear(); + + // set updateFrequency with true + updateFreq = true; } void MeCFG::ConstructStmtFreq() { - FuncProfInfo* funcData = func.GetMirFunc()->GetFuncProfData(); + FuncProfInfo *funcData = func.GetMirFunc()->GetFuncProfData(); if (!funcData) { return; } @@ -1930,8 +1938,7 @@ void MeCFG::ConstructStmtFreq() { for (auto &stmt : bb->GetStmtNodes()) { Opcode op = stmt.GetOpCode(); // record bb start/end stmt - if (stmt.GetStmtID() == bb->GetFirst().GetStmtID() || - stmt.GetStmtID() == bb->GetLast().GetStmtID() || + if (stmt.GetStmtID() == bb->GetFirst().GetStmtID() || stmt.GetStmtID() == bb->GetLast().GetStmtID() || IsCallAssigned(op) || op == OP_call) { funcData->stmtFreqs[stmt.GetStmtID()] = bb->GetFrequency(); } @@ -1941,39 +1948,105 @@ void MeCFG::ConstructStmtFreq() { // bb frequency may be changed in transform phase, // update edgeFreq with new BB frequency by scale -void MeCFG::UpdateEdgeFreqWithNewBBFreq() { - for (size_t idx = 0; idx < bbVec.size(); ++idx) { - BB *currBB = bbVec[idx]; - if (currBB == nullptr || currBB->GetSucc().empty()) { +void MeCFG::UpdateEdgeFreqWithBBFreq() { + BuildSCC(); + for (size_t i = 0; i < GetSccTopologicalVec().size(); ++i) { + SCCOfBBs *scc = GetSccTopologicalVec()[i]; + CHECK_FATAL(scc != nullptr, "scc must not be null"); + if (scc->GetBBs().size() > 1) { + BBTopologicalSort(*scc); + } + const uint32 maxLoopCount = 2; + unsigned loopCount = scc->GetBBs().size() > 1 ? maxLoopCount : 1; + for (unsigned j = 0; j < loopCount; ++j) { + for (BB *bb : scc->GetBBs()) { + if (bb == nullptr) { + continue; + } + // collect pred total except entry + if (!bb->GetAttributes(kBBAttrIsEntry)) { + int64_t inputFreq = 0; + for (auto *pred : bb->GetPred()) { + int idx = pred->GetSuccIndex(*bb); + ASSERT(idx >= 0 && idx < pred->GetSuccFreq().size(), "sanity check"); + inputFreq += pred->GetSuccFreq()[idx]; + } + bb->SetFrequency(inputFreq); + } + // make bb frequency and succs frequency consistent + bb->UpdateEdgeFreqs(false); + } + } + } +} + +void MeCFG::ClearFuncFreqInfo() { + SetUpdateCFGFreq(false); + func.GetMirFunc()->SetFuncProfData(nullptr); + auto &bbVec = GetAllBBs(); + for (size_t i = 0; i < bbVec.size(); ++i) { // skip common entry and common exit + auto *bb = bbVec[i]; + if (bb == nullptr) { continue; } - // make bb frequency and succs frequency consistent - currBB->UpdateEdgeFreqs(); + bb->SetFrequency(0); + bb->GetSuccFreq().clear(); } } -void MeCFG::VerifyBBFreq() { +// return value is 0 means pass verification, else has problem +int MeCFG::VerifyBBFreq(bool checkFatal) { + int64_t entryFreq = func.GetMirFunc()->GetFuncProfData()->GetFuncFrequency(); + ASSERT(entryFreq >= 0, "sanity check"); + bool entryIsZero = entryFreq == 0 ? true : false; for (size_t i = 2; i < bbVec.size(); ++i) { // skip common entry and common exit auto *bb = bbVec[i]; if (bb == nullptr || bb->GetAttributes(kBBAttrIsEntry) || bb->GetAttributes(kBBAttrIsExit)) { continue; } - // wontexit bb may has wrong succ, skip it + // check case 1: entry count is zero, internal bb has frequency value > 0 + if (entryIsZero && bb->GetFrequency() > 0) { + if (checkFatal) { + LogInfo::MapleLogger() << func.GetName() << "wrong BB " << bb->GetBBId() << std::endl; + CHECK_FATAL(false, "VerifyBBFreq: function entryFreq is zero but internal bb frequency > 0"); + } else { + ClearFuncFreqInfo(); + return 1; + } + } + // check case 2: bb succ frequence numbers should be equal to succ number except wontexit bb + // may has wrong succ, skip it if (bb->GetSuccFreq().size() != bb->GetSucc().size() && !bb->GetAttributes(kBBAttrWontExit)) { - CHECK_FATAL(false, "VerifyBBFreq: succFreq size != succ size"); + if (checkFatal) { + LogInfo::MapleLogger() << func.GetName() << "wrong BB " << bb->GetBBId() << std::endl; + CHECK_FATAL(false, "VerifyBBFreq: succFreq size != succ size"); + } else { + ClearFuncFreqInfo(); + return 1; + } } - // bb freq == sum(out edge freq) + // check case 3: bb freq == sum(out edge freq) uint64 succSumFreq = 0; for (auto succFreq : bb->GetSuccFreq()) { succSumFreq += succFreq; } if (succSumFreq != bb->GetFrequency()) { - LogInfo::MapleLogger() << "[VerifyFreq failure] BB" << bb->GetBBId() << " freq: " << - bb->GetFrequency() << ", all succ edge freq sum: " << succSumFreq << std::endl; - LogInfo::MapleLogger() << func.GetName() << std::endl; - CHECK_FATAL(false, "VerifyFreq failure: bb freq != succ freq sum"); + int diff = succSumFreq - bb->GetFrequency(); + diff = diff >= 0 ? diff : -diff; + if (diff > 1) { + if (checkFatal) { + LogInfo::MapleLogger() << func.GetName() << "wrong BB " << bb->GetBBId() << std::endl; + LogInfo::MapleLogger() << " freq: " << bb->GetFrequency() << ", all succ edge freq sum: " << succSumFreq + << std::endl; + CHECK_FATAL(false, "VerifyFreq failure: bb freq != succ freq sum"); + } else { + ClearFuncFreqInfo(); + return 1; + } + } } } + return 0; } bool MEMeCfg::PhaseRun(MeFunction &f) { @@ -2007,31 +2080,33 @@ bool MEMeCfg::PhaseRun(MeFunction &f) { if (!f.GetMIRModule().IsJavaModule() && MeOption::unifyRets) { theCFG->UnifyRetBBs(); } + theCFG->Verify(); // construct bb freq from stmt freq if (Options::profileUse && f.GetMirFunc()->GetFuncProfData()) { theCFG->ConstructBBFreqFromStmtFreq(); + if (theCFG->DumpIRProfileFile()) { + std::string fileName = "after-mecfgbuild"; + if (f.IsPme()) { + fileName.append("-lfo"); + } else { + fileName.append("-mplme"); + } + theCFG->DumpToFile(fileName, false, true); + } } - theCFG->Verify(); return false; } bool MECfgVerifyFrequency::PhaseRun(MeFunction &f) { - if (Options::profileUse && f.GetMirFunc()->GetFuncProfData()) { + // if transform pass is not fully support, set disableFreqInfo to true + // function profile information will be deleted after verification phase + bool disableFreqInfo = false; + if (f.GetCfg()->UpdateCFGFreq()) { f.GetCfg()->VerifyBBFreq(); } - // hack code here: no use profile data after verifycation pass since - // following tranform phases related of cfg change are not touched - f.GetMirFunc()->SetFuncProfData(nullptr); - auto &bbVec = f.GetCfg()->GetAllBBs(); - for (size_t i = 0; i < bbVec.size(); ++i) { // skip common entry and common exit - auto *bb = bbVec[i]; - if (bb == nullptr) { - continue; - } - bb->SetFrequency(0); - bb->GetSuccFreq().clear(); - } - + if (!disableFreqInfo) return false; + // clear function profile information + f.GetCfg()->ClearFuncFreqInfo(); return false; } } // namespace maple diff --git a/src/mapleall/maple_me/src/me_critical_edge.cpp b/src/mapleall/maple_me/src/me_critical_edge.cpp index e47078d693..4dca8f82a2 100644 --- a/src/mapleall/maple_me/src/me_critical_edge.cpp +++ b/src/mapleall/maple_me/src/me_critical_edge.cpp @@ -13,13 +13,15 @@ * See the Mulan PSL v2 for more details. */ #include "me_critical_edge.h" + #include + #include "me_cfg.h" -#include "me_option.h" #include "me_dominance.h" #include "me_function.h" -#include "me_loop_analysis.h" #include "me_irmap.h" +#include "me_loop_analysis.h" +#include "me_option.h" // This phase finds critical edges and split them into two, because their // presence would restrict the optimizations performed by SSAPRE-based phases. @@ -98,8 +100,8 @@ void MeSplitCEdge::UpdateCaseLabel(BB &newBB, MeFunction &func, BB &pred, BB &su } } -void MeSplitCEdge::DealWithTryBB(const MeFunction &func, BB &pred, - BB &succ, BB *&newBB, bool &isInsertAfterPred) const { +void MeSplitCEdge::DealWithTryBB(const MeFunction &func, BB &pred, BB &succ, BB *&newBB, + bool &isInsertAfterPred) const { if ((!succ.GetStmtNodes().empty() && succ.GetStmtNodes().front().GetOpCode() == OP_try) || (!succ.IsMeStmtEmpty() && succ.GetFirstMe()->GetOp() == OP_try)) { newBB = &func.GetCfg()->InsertNewBasicBlock(pred, false); @@ -117,8 +119,8 @@ void MeSplitCEdge::DealWithTryBB(const MeFunction &func, BB &pred, void MeSplitCEdge::BreakCriticalEdge(MeFunction &func, BB &pred, BB &succ) const { if (isDebugFunc) { - LogInfo::MapleLogger() << "******before break : critical edge : BB" << pred.GetBBId() << " -> BB" << - succ.GetBBId() << "\n"; + LogInfo::MapleLogger() << "******before break : critical edge : BB" << pred.GetBBId() << " -> BB" << succ.GetBBId() + << "\n"; pred.Dump(&func.GetMIRModule()); succ.Dump(&func.GetMIRModule()); } @@ -160,8 +162,7 @@ void MeSplitCEdge::BreakCriticalEdge(MeFunction &func, BB &pred, BB &succ) const newBB->SetAttributes(kBBAttrArtificial); // update newBB frequency : copy predBB succFreq as newBB frequency - if (Options::profileUse && func.GetMirFunc()->GetFuncProfData() && - (!(func.IsPme() || func.IsLfo()))) { + if (cfg->UpdateCFGFreq() && (!(func.IsPme() || func.IsLfo()))) { int idx = pred.GetSuccIndex(*newBB); ASSERT(idx >= 0 && idx < pred.GetSucc().size(), "sanity check"); uint64_t freq = pred.GetEdgeFreq(idx); @@ -189,8 +190,7 @@ 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 || - (Options::profileUse && (func.IsPme() || func.IsLfo()))) { + if (Options::profileGen || (Options::profileUse && (func.IsPme() || func.IsLfo()))) { LabelIdx succLabel = succ.GetBBLabel(); ASSERT(succLabel != 0, "succ's label missed"); if (func.GetIRMap() != nullptr) { @@ -306,7 +306,7 @@ bool MESplitCEdge::PhaseRun(maple::MeFunction &f) { mscedge.SplitCriticalEdgeForMeFunc(f); if (Options::profileUse) { if ((f.IsPme() || f.IsLfo()) && f.GetPreMeFunc()) { - // new inserted BB will break while/if label information and IR layout + // new inserted BB break cached while/if label information and IR layout f.GetPreMeFunc()->label2IfInfo.clear(); f.GetPreMeFunc()->label2WhileInfo.clear(); f.GetPreMeFunc()->pmeCreatedIfLabelSet.clear(); diff --git a/src/mapleall/maple_me/src/me_dse.cpp b/src/mapleall/maple_me/src/me_dse.cpp index c2ad027a7e..2d393a9ada 100644 --- a/src/mapleall/maple_me/src/me_dse.cpp +++ b/src/mapleall/maple_me/src/me_dse.cpp @@ -13,6 +13,7 @@ * See the Mulan PSL v2 for more details. */ #include "me_dse.h" + #include namespace maple { @@ -33,7 +34,7 @@ void MeDSE::VerifyPhi() const { const OriginalSt *ost = func.GetMeSSATab()->GetOriginalStFromID(pair.first); CHECK_FATAL(ost, "ost is nullptr!"); CHECK_FATAL(!ost->IsSymbolOst() || ost->GetIndirectLev() != 0, - "phi is live and non-virtual in bb with zero or one pred"); + "phi is live and non-virtual in bb with zero or one pred"); } else if (pair.second.GetPhiOpnds().size() != predBBNums) { ASSERT(false, "phi opnd num is not consistent with pred bb num(need update phi)"); } @@ -71,8 +72,11 @@ bool MEDse::PhaseRun(maple::MeFunction &f) { f.Verify(); // cfg change , invalid results in MeFuncResultMgr if (dse.UpdatedCfg()) { - if (Options::profileUse && f.GetMirFunc()->GetFuncProfData()) { - f.GetCfg()->UpdateEdgeFreqWithNewBBFreq(); + if (f.GetCfg()->UpdateCFGFreq()) { + f.GetCfg()->UpdateEdgeFreqWithBBFreq(); + if (f.GetCfg()->DumpIRProfileFile()) { + f.GetCfg()->DumpToFile(("after-dse" + std::to_string(f.dseRuns)), false, true); + } } GetAnalysisInfoHook()->ForceEraseAnalysisPhase(f.GetUniqueID(), &MEDominance::id); } diff --git a/src/mapleall/maple_me/src/me_hdse.cpp b/src/mapleall/maple_me/src/me_hdse.cpp index 6283697dd9..9cc7fa1907 100644 --- a/src/mapleall/maple_me/src/me_hdse.cpp +++ b/src/mapleall/maple_me/src/me_hdse.cpp @@ -13,11 +13,13 @@ * See the Mulan PSL v2 for more details. */ #include "me_hdse.h" + #include + +#include "hdse.h" +#include "me_ssa.h" #include "ssa_mir_nodes.h" #include "ver_symbol.h" -#include "me_ssa.h" -#include "hdse.h" // The hdse phase performs dead store elimination using the well-known algorithm // based on SSA. The algorithm works as follows: @@ -55,7 +57,7 @@ void MeHDSE::ProcessWhileInfos() { if (preMeFunc == nullptr) { return; } - MapleMap::iterator it = preMeFunc->label2WhileInfo.begin(); + MapleMap::iterator it = preMeFunc->label2WhileInfo.begin(); for (; it != preMeFunc->label2WhileInfo.end(); ++it) { if (it->second->initExpr != nullptr && (it->second->initExpr->GetMeOp() == maple::kMeOpVar || it->second->initExpr->GetMeOp() == maple::kMeOpReg)) { @@ -66,7 +68,7 @@ void MeHDSE::ProcessWhileInfos() { void MeHDSE::BackwardSubstitution() { for (DassignMeStmt *dass : backSubsCands) { - ScalarMeExpr *rhsscalar = static_cast(dass->GetRHS()); + ScalarMeExpr *rhsscalar = static_cast(dass->GetRHS()); if (verstUseCounts[rhsscalar->GetVstIdx()] != 1) { continue; } @@ -110,9 +112,8 @@ void MakeEmptyTrysUnreachable(MeFunction &func) { } BB *endTry = *endTryIt; auto &meStmts = tryBB->GetMeStmts(); - if (tryBB->GetAttributes(kBBAttrIsTry) && !meStmts.empty() && - meStmts.front().GetOp() == OP_try && tryBB->GetMePhiList().empty() && - endTry->GetAttributes(kBBAttrIsTryEnd) && endTry->IsMeStmtEmpty()) { + if (tryBB->GetAttributes(kBBAttrIsTry) && !meStmts.empty() && meStmts.front().GetOp() == OP_try && + tryBB->GetMePhiList().empty() && endTry->GetAttributes(kBBAttrIsTryEnd) && endTry->IsMeStmtEmpty()) { // we found a try BB followed by an empty endtry BB BB *targetBB = endTry->GetSucc(0); while (!tryBB->GetPred().empty()) { @@ -190,6 +191,7 @@ bool MEHdse::PhaseRun(maple::MeFunction &f) { MeHDSE hdse = MeHDSE(f, *dom, *hMap, aliasClass, DEBUGFUNC_NEWPM(f)); hdse.hdseKeepRef = MeOption::dseKeepRef; + hdse.SetUpdateFreq(Options::profileUse && f.GetMirFunc()->GetFuncProfData()); if (f.hdseRuns > 2) { hdse.SetRemoveRedefine(true); } @@ -198,6 +200,13 @@ bool MEHdse::PhaseRun(maple::MeFunction &f) { MakeEmptyTrysUnreachable(f); (void)f.GetCfg()->UnreachCodeAnalysis(true); f.GetCfg()->WontExitAnalysis(); + // update frequency + if (hdse.UpdateFreq()) { + f.GetCfg()->UpdateEdgeFreqWithBBFreq(); + if (f.GetCfg()->DumpIRProfileFile()) { + f.GetCfg()->DumpToFile("after-HDSE" + std::to_string(f.hdseRuns), false, true); + } + } if (DEBUGFUNC_NEWPM(f)) { LogInfo::MapleLogger() << "\n============== HDSE =============" << '\n'; f.Dump(false); diff --git a/src/mapleall/maple_me/src/me_loop_canon.cpp b/src/mapleall/maple_me/src/me_loop_canon.cpp index 951da51ee7..05c4b15f8e 100644 --- a/src/mapleall/maple_me/src/me_loop_canon.cpp +++ b/src/mapleall/maple_me/src/me_loop_canon.cpp @@ -13,11 +13,13 @@ * See the Mulan PSL v2 for more details. */ #include "me_loop_canon.h" -#include + #include +#include + #include "me_cfg.h" -#include "me_option.h" #include "me_dominance.h" +#include "me_option.h" #include "me_phase_manager.h" namespace maple { @@ -39,8 +41,7 @@ void MeLoopCanon::FindHeadBBs(Dominance &dom, const BB *bb, std::mapGetBBLabel() != 0) { - const MapleUnorderedSet &addrTakenLabels = - func.GetMirFunc()->GetLabelTab()->GetAddrTakenLabels(); + const MapleUnorderedSet &addrTakenLabels = func.GetMirFunc()->GetLabelTab()->GetAddrTakenLabels(); if (addrTakenLabels.find(bb->GetBBLabel()) != addrTakenLabels.end()) { hasIgoto = true; } @@ -71,8 +72,7 @@ void MeLoopCanon::UpdateTheOffsetOfStmtWhenTargetBBIsChange(BB &curBB, const BB static_cast(lastStmt).GetOffset() == oldSuccBB.GetBBLabel()) { auto label = func.GetOrCreateBBLabel(newSuccBB); static_cast(lastStmt).SetOffset(label); - } else if (lastStmt.GetOp() == OP_goto && - static_cast(lastStmt).GetOffset() == oldSuccBB.GetBBLabel()) { + } else if (lastStmt.GetOp() == OP_goto && static_cast(lastStmt).GetOffset() == oldSuccBB.GetBBLabel()) { auto label = func.GetOrCreateBBLabel(newSuccBB); static_cast(lastStmt).SetOffset(label); } else if (lastStmt.GetOp() == OP_switch) { @@ -96,8 +96,19 @@ void MeLoopCanon::SplitPreds(const std::vector &splitList, BB *splittedBB, // quick split auto *pred = splitList[0]; auto index = pred->GetSuccIndex(*splittedBB); + // add frequency to mergedBB + if (updateFreqs) { + int idx = pred->GetSuccIndex(*splittedBB); + ASSERT(idx >= 0 && idx < pred->GetSucc().size(), "sanity check"); + uint64_t freq = pred->GetEdgeFreq(idx); + mergedBB->SetFrequency(freq); + mergedBB->PushBackSuccFreq(freq); + } splittedBB->ReplacePred(pred, mergedBB); pred->AddSucc(*mergedBB, static_cast(static_cast(index))); + if (updateFreqs) { + pred->AddSuccFreq(mergedBB->GetFrequency(), static_cast(static_cast(index))); + } if (!pred->GetMeStmts().empty()) { UpdateTheOffsetOfStmtWhenTargetBBIsChange(*pred, *splittedBB, *mergedBB); } @@ -112,6 +123,7 @@ void MeLoopCanon::SplitPreds(const std::vector &splitList, BB *splittedBB, mergedBB->GetMePhiList().emplace(latchLhs->GetOstIdx(), latchPhi); phiIter.second->GetOpnds().push_back(latchLhs); } + uint64_t freq = 0; for (BB *pred : splitList) { auto pos = splittedBB->GetPredIndex(*pred); for (auto &phiIter : mergedBB->GetMePhiList()) { @@ -119,7 +131,17 @@ void MeLoopCanon::SplitPreds(const std::vector &splitList, BB *splittedBB, phiIter.second->GetOpnds().push_back(splittedBB->GetMePhiList().at(phiIter.first)->GetOpnd(pos)); } splittedBB->RemovePhiOpnd(pos); + if (updateFreqs) { + int idx = pred->GetSuccIndex(*splittedBB); + ASSERT(idx >= 0 && idx < pred->GetSucc().size(), "sanity check"); + freq = pred->GetEdgeFreq(idx); + mergedBB->SetFrequency(mergedBB->GetFrequency() + freq); + } pred->ReplaceSucc(splittedBB, mergedBB); + if (updateFreqs) { + int idx = pred->GetSuccIndex(*mergedBB); + pred->SetSuccFreq(idx, freq); + } if (pred->GetMeStmts().empty()) { continue; } @@ -141,6 +163,9 @@ void MeLoopCanon::SplitPreds(const std::vector &splitList, BB *splittedBB, } } splittedBB->AddPred(*mergedBB); + if (updateFreqs) { + mergedBB->PushBackSuccFreq(mergedBB->GetFrequency()); + } isCFGChange = true; } @@ -151,16 +176,14 @@ void MeLoopCanon::Merge(const std::map> &heads) { BB *head = cfg->GetBBFromID(iter->first); // skip case : check latch bb is already added // one pred is preheader bb and the other is latch bb - if ((head->GetPred().size() == 2) && - (head->GetPred(0)->GetAttributes(kBBAttrArtificial)) && - (head->GetPred(0)->GetKind() == kBBFallthru) && - (head->GetPred(1)->GetAttributes(kBBAttrArtificial)) && + if ((head->GetPred().size() == 2) && (head->GetPred(0)->GetAttributes(kBBAttrArtificial)) && + (head->GetPred(0)->GetKind() == kBBFallthru) && (head->GetPred(1)->GetAttributes(kBBAttrArtificial)) && (head->GetPred(1)->GetKind() == kBBFallthru)) { continue; } auto *latchBB = cfg->NewBasicBlock(); latchBB->SetAttributes(kBBAttrArtificial); - latchBB->SetAttributes(kBBAttrIsInLoop); // latchBB is inloop + latchBB->SetAttributes(kBBAttrIsInLoop); // latchBB is inloop latchBB->SetKind(kBBFallthru); SplitPreds(iter->second, head, latchBB); } @@ -244,8 +267,17 @@ void MeLoopCanon::InsertExitBB(LoopDesc &loop) { BB *newExitBB = cfg->NewBasicBlock(); newExitBB->SetKind(kBBFallthru); auto pos = succ->GetPredIndex(*curBB); + uint64_t freq = 0; + if (updateFreqs) { + int idx = curBB->GetSuccIndex(*succ); + freq = curBB->GetSuccFreq()[idx]; + } curBB->ReplaceSucc(succ, newExitBB); succ->AddPred(*newExitBB, pos); + if (updateFreqs) { + newExitBB->SetFrequency(freq); + newExitBB->PushBackSuccFreq(freq); + } if (!curBB->GetMeStmts().empty()) { UpdateTheOffsetOfStmtWhenTargetBBIsChange(*curBB, *succ, *newExitBB); } @@ -299,7 +331,8 @@ bool MELoopCanon::PhaseRun(maple::MeFunction &f) { auto *dom = GET_ANALYSIS(MEDominance, f); ASSERT(dom != nullptr, "dom is null in MeDoLoopCanon::Run"); MemPool *loopCanonMp = GetPhaseMemPool(); - auto *meLoopCanon = loopCanonMp->New(f, DEBUGFUNC_NEWPM(f)); + bool updateFrequency = (Options::profileUse && f.GetMirFunc()->GetFuncProfData()); + auto *meLoopCanon = loopCanonMp->New(f, DEBUGFUNC_NEWPM(f), updateFrequency); // 1. Add preheaderBB and normalization headBB for loop. meLoopCanon->NormalizationHeadAndPreHeaderOfLoop(*dom); @@ -316,6 +349,9 @@ bool MELoopCanon::PhaseRun(maple::MeFunction &f) { meLoopCanon->NormalizationExitOfLoop(*meLoop); if (meLoopCanon->IsCFGChange()) { GetAnalysisInfoHook()->ForceEraseAnalysisPhase(f.GetUniqueID(), &MEDominance::id); + if (updateFrequency && (f.GetCfg()->DumpIRProfileFile())) { + f.GetCfg()->DumpToFile("after-loopcanon", false, true); + } } return true; } diff --git a/src/mapleall/maple_me/src/me_loop_inversion.cpp b/src/mapleall/maple_me/src/me_loop_inversion.cpp index 23a572736d..8da6423c2a 100644 --- a/src/mapleall/maple_me/src/me_loop_inversion.cpp +++ b/src/mapleall/maple_me/src/me_loop_inversion.cpp @@ -13,11 +13,13 @@ * See the Mulan PSL v2 for more details. */ #include "me_loop_inversion.h" -#include + #include +#include + #include "me_cfg.h" -#include "me_option.h" #include "me_dominance.h" +#include "me_option.h" #include "me_phase_manager.h" namespace maple { @@ -121,8 +123,7 @@ void MeLoopInversion::Convert(MeFunction &func, BB &bb, BB &pred, MapleMapfallthru is in loopbody, latchBB need convert condgoto and make original target as its fallthru bool swapSuccOfLatch = (swapSuccs.find(std::make_pair(&bb, &pred)) != swapSuccs.end()); if (isDebugFunc) { - LogInfo::MapleLogger() << "***loop convert: backedge bb->id " << bb.GetBBId() << " pred->id " - << pred.GetBBId(); + LogInfo::MapleLogger() << "***loop convert: backedge bb->id " << bb.GetBBId() << " pred->id " << pred.GetBBId(); if (swapSuccOfLatch) { LogInfo::MapleLogger() << " need swap succs\n"; } else { @@ -132,9 +133,9 @@ void MeLoopInversion::Convert(MeFunction &func, BB &bb, BB &pred, MapleMapNewBasicBlock(); latchBB->SetAttributes(kBBAttrArtificial); - latchBB->SetAttributes(kBBAttrIsInLoop); // latchBB is inloop + latchBB->SetAttributes(kBBAttrIsInLoop); // latchBB is inloop // update newBB frequency : copy predBB succFreq as latch frequency - if (Options::profileUse && func.GetMirFunc()->GetFuncProfData()) { + if (func.GetCfg()->UpdateCFGFreq()) { int idx = pred.GetSuccIndex(bb); ASSERT(idx >= 0 && idx < pred.GetSucc().size(), "sanity check"); uint64_t freq = pred.GetEdgeFreq(idx); @@ -144,7 +145,7 @@ void MeLoopInversion::Convert(MeFunction &func, BB &bb, BB &pred, MapleMapSetKind(bb.GetKind()); // update succFreq - if (Options::profileUse && func.GetMirFunc()->GetFuncProfData()) { - int succFreqSize = bb.GetSuccFreq().size(); - ASSERT(latchBB->GetSucc().size() == succFreqSize, "sanity check"); - // copy bb succFreq as latch frequency - for (int i = 0; i < succFreqSize; i++) { - latchBB->PushBackSuccFreq(bb.GetSuccFreq()[i]); - } - if (bb.GetFrequency() > 0) { - // swap frequency and fixed the frequency value - if (swapSuccOfLatch) { - ASSERT(latchBB->GetKind() == kBBCondGoto, "impossible"); - int64_t newftFreq = (latchBB->GetFrequency() == 0 || bb.GetSuccFreq()[1] == 0) ? 0 : 1; - int64_t newtgFreq = latchBB->GetFrequency() == 0 ? 0 : (latchBB->GetFrequency() - newftFreq); - latchBB->SetSuccFreq(0, newftFreq); - latchBB->SetSuccFreq(1, newtgFreq); // loop is changed to do-while format - int64_t bbsucc0Freq = bb.GetSucc(0)->GetFrequency() - newtgFreq; - int64_t bbsucc1Freq = bb.GetFrequency() - bbsucc0Freq; - bb.SetSuccFreq(0, bbsucc0Freq); - bb.SetSuccFreq(1, bbsucc1Freq); - } else if (latchBB->GetKind() == kBBCondGoto) { - int64_t newftFreq = (latchBB->GetFrequency() == 0 || bb.GetSuccFreq()[0] == 0) ? 0 : 1; - int64_t newtgFreq = latchBB->GetFrequency() == 0 ? 0 : (latchBB->GetFrequency() - newftFreq); - latchBB->SetSuccFreq(0, newftFreq); // freq to exit BB - latchBB->SetSuccFreq(1, newtgFreq); // loop is changed to do-while format - // update bb succ frequency - int64_t bbsucc0Freq = bb.GetSucc(0)->GetFrequency() - newftFreq; - int64_t bbsucc1Freq = bb.GetFrequency() - bbsucc0Freq; - bb.SetSuccFreq(0, bbsucc0Freq); - bb.SetSuccFreq(1, bbsucc1Freq); - } else if (latchBB->GetKind() == kBBFallthru || latchBB->GetKind() == kBBGoto) { - int64_t newsuccFreq = (latchBB->GetFrequency() == 0) ? 0 : latchBB->GetSuccFreq()[0] - 1; - latchBB->SetSuccFreq(0, newsuccFreq); // loop is changed to do-while format - bb.SetSuccFreq(0, bb.GetFrequency()); + if (func.GetCfg()->UpdateCFGFreq()) { + if (latchBB->GetKind() == kBBCondGoto) { + BB *succInloop = swapSuccOfLatch ? bb.GetSucc(0) : bb.GetSucc(1); + if ((latchBB->GetFrequency() != 0) && (succInloop->GetFrequency() > 0)) { + // loop is executed, bb->fallthru is in loopbody + int64_t latchFreq = latchBB->GetFrequency(); + if (swapSuccOfLatch) { + // bb fallthru is in loop, frequency of bb -> exitbb is set 0 + bb.SetSuccFreq(0, bb.GetFrequency()); + bb.SetSuccFreq(1, 0); + // latchBB fallthru is loop exit + ASSERT(bb.GetSucc(0)->GetFrequency() >= bb.GetFrequency(), "sanity check"); + int fallthrudiff = bb.GetSucc(0)->GetFrequency() - bb.GetFrequency(); + ASSERT(fallthrudiff >= 0, "sanity check"); + latchBB->PushBackSuccFreq(latchFreq - fallthrudiff); + latchBB->PushBackSuccFreq(fallthrudiff); + } else { + // bb->fallthru is loop exit, edge frequency of bb ->exitbb is set 0 + bb.SetSuccFreq(0, 0); + bb.SetSuccFreq(1, bb.GetFrequency()); + // latchBB fallthru is in loop + int fallthrudiff = bb.GetSucc(1)->GetFrequency() - bb.GetFrequency(); + ASSERT(fallthrudiff >= 0, "sanity check"); + latchBB->PushBackSuccFreq(fallthrudiff); + latchBB->PushBackSuccFreq(latchFreq - fallthrudiff); + } } else { - ASSERT(0, "NYI:: unexpected bb type"); + // loop is not executed + if (latchBB->GetFrequency() != 0) { + if (swapSuccOfLatch) { + bb.SetSuccFreq(0, 0); + bb.SetSuccFreq(1, bb.GetFrequency()); + } else { + bb.SetSuccFreq(0, bb.GetFrequency()); + bb.SetSuccFreq(1, 0); + } + } + ASSERT(latchBB->GetFrequency() == 0, "sanity check"); + latchBB->PushBackSuccFreq(0); + latchBB->PushBackSuccFreq(0); } + } else if (latchBB->GetKind() == kBBFallthru || latchBB->GetKind() == kBBGoto) { + int64_t newsuccFreq = (latchBB->GetFrequency() == 0) ? 0 : latchBB->GetSuccFreq()[0] - 1; + latchBB->SetSuccFreq(0, newsuccFreq); // loop is changed to do-while format + bb.SetSuccFreq(0, bb.GetFrequency()); + } else { + ASSERT(0, "NYI:: unexpected bb type"); } } // swap latchBB's succ if needed @@ -332,8 +344,8 @@ void MeLoopInversion::ExecuteLoopInversion(MeFunction &func, Dominance &dom) { } if ((NeedConvert(&func, *succ, *tmpPred, localAlloc, swapSuccs))) { if (isDebugFunc) { - LogInfo::MapleLogger() << "find new backedge " << succ->GetBBId() - << " <-- " << tmpPred->GetBBId() << '\n'; + LogInfo::MapleLogger() << "find new backedge " << succ->GetBBId() << " <-- " << tmpPred->GetBBId() + << '\n'; } backEdges.push_back(std::make_pair(succ, tmpPred)); } @@ -362,6 +374,9 @@ bool MELoopInversion::PhaseRun(maple::MeFunction &f) { if (meLoopInversion->IsCFGChange()) { GetAnalysisInfoHook()->ForceEraseAnalysisPhase(f.GetUniqueID(), &MEDominance::id); GetAnalysisInfoHook()->ForceEraseAnalysisPhase(f.GetUniqueID(), &MELoopAnalysis::id); + if (f.GetCfg()->UpdateCFGFreq() && (f.GetCfg()->DumpIRProfileFile())) { + f.GetCfg()->DumpToFile("after-loopinversion", false, true); + } } return true; } diff --git a/src/mapleall/maple_me/src/me_loop_unrolling.cpp b/src/mapleall/maple_me/src/me_loop_unrolling.cpp index 69caeb933a..5bc4f8cdfc 100644 --- a/src/mapleall/maple_me/src/me_loop_unrolling.cpp +++ b/src/mapleall/maple_me/src/me_loop_unrolling.cpp @@ -13,13 +13,15 @@ * See the Mulan PSL v2 for more details. */ #include "me_loop_unrolling.h" -#include + #include +#include + #include "me_cfg.h" #include "me_option.h" -#include "mir_module.h" -#include "mir_builder.h" #include "me_phase_manager.h" +#include "mir_builder.h" +#include "mir_module.h" namespace maple { bool LoopUnrollingExecutor::enableDebug = false; @@ -36,13 +38,15 @@ bool ProfileCheck(const maple::MeFunction &f) { auto &profile = f.GetMIRModule().GetProfile(); if (!profile.IsValid()) { if (LoopUnrollingExecutor::enableDebug) { - LogInfo::MapleLogger() << "DeCompress failed in loopUnrolling" << "\n"; + LogInfo::MapleLogger() << "DeCompress failed in loopUnrolling" + << "\n"; } return false; } if (!profile.CheckFuncHot(f.GetName())) { if (LoopUnrollingExecutor::enableDebug) { - LogInfo::MapleLogger() << "func is not hot" << "\n"; + LogInfo::MapleLogger() << "func is not hot" + << "\n"; } return false; } @@ -69,12 +73,12 @@ void LoopUnrolling::ComputeCodeSize(const MeStmt &meStmt, uint32 &cost) { case OP_brfalse: case OP_brtrue: case OP_maydassign: - CASE_OP_ASSERT_BOUNDARY { - cost += kTwoInsn; - break; - } + CASE_OP_ASSERT_BOUNDARY { + cost += kTwoInsn; + break; + } case OP_iassign: - CASE_OP_ASSERT_NONNULL + CASE_OP_ASSERT_NONNULL case OP_membaracquire: { cost += kThreeInsn; break; @@ -99,7 +103,7 @@ void LoopUnrolling::ComputeCodeSize(const MeStmt &meStmt, uint32 &cost) { } default: if (LoopUnrollingExecutor::enableDebug) { - LogInfo::MapleLogger() << "consider this op :"<< meStmt.GetOp() << "\n"; + LogInfo::MapleLogger() << "consider this op :" << meStmt.GetOp() << "\n"; } canUnroll = false; break; @@ -152,8 +156,8 @@ void LoopUnrolling::SetLabelWithCondGotoOrGotoBB(BB &bb, std::unordered_map &old2NewBB, BB &bb, - const BB &exitBB, BB &newHeadBB) { +void LoopUnrolling::ResetOldLabel2NewLabel(std::unordered_map &old2NewBB, BB &bb, const BB &exitBB, + BB &newHeadBB) { if (bb.GetKind() == kBBCondGoto) { CHECK_FATAL(!bb.GetMeStmts().empty(), "must not be empty"); CondGotoMeStmt &condGotoNode = static_cast(bb.GetMeStmts().back()); @@ -174,8 +178,8 @@ void LoopUnrolling::ResetOldLabel2NewLabel(std::unordered_map &old2New } // When loop unroll times more than two, use this function to update the preds and succs of duplicate loopbodys. -void LoopUnrolling::ResetOldLabel2NewLabel2(std::unordered_map &old2NewBB, BB &bb, - const BB &exitBB, BB &newHeadBB) { +void LoopUnrolling::ResetOldLabel2NewLabel2(std::unordered_map &old2NewBB, BB &bb, const BB &exitBB, + BB &newHeadBB) { if (bb.GetKind() == kBBCondGoto) { CHECK_FATAL(!bb.GetMeStmts().empty(), "must not be empty"); CondGotoMeStmt &condGotoNode = static_cast(bb.GetMeStmts().back()); @@ -194,23 +198,22 @@ void LoopUnrolling::ResetOldLabel2NewLabel2(std::unordered_map &old2Ne } } -void LoopUnrolling::ResetFrequency(const BB &curBB, const BB &succ, const BB &exitBB, - BB &curCopyBB, bool copyAllLoop) { +void LoopUnrolling::ResetFrequency(const BB &curBB, const BB &succ, const BB &exitBB, BB &curCopyBB, bool copyAllLoop) { if (resetFreqForUnrollWithVar && copyAllLoop) { if (&curBB == &exitBB && &succ == *loop->inloopBB2exitBBs.begin()->second->begin()) { curCopyBB.PushBackSuccFreq(loop->head->GetFrequency() % replicatedLoopNum == 0 ? 0 : 1); } if ((&curBB == loop->latch && &succ == loop->head) || (&curBB == &exitBB && &succ == loop->latch)) { - curCopyBB.PushBackSuccFreq(loop->head->GetFrequency() % replicatedLoopNum == 0 ? 0 : - loop->head->GetFrequency() % replicatedLoopNum - 1); + curCopyBB.PushBackSuccFreq( + loop->head->GetFrequency() % replicatedLoopNum == 0 ? 0 : loop->head->GetFrequency() % replicatedLoopNum - 1); } else { curCopyBB.PushBackSuccFreq(curBB.GetEdgeFreq(&succ) % replicatedLoopNum); } } else { - profValid && resetFreqForAfterInsertGoto ? - curCopyBB.PushBackSuccFreq(curBB.GetEdgeFreq(&succ) - 1 == 0 ? curBB.GetEdgeFreq(&succ) : - curBB.GetEdgeFreq(&succ) - 1) : - curCopyBB.PushBackSuccFreq(curBB.GetEdgeFreq(&succ)); + profValid &&resetFreqForAfterInsertGoto + ? curCopyBB.PushBackSuccFreq(curBB.GetEdgeFreq(&succ) - 1 == 0 ? curBB.GetEdgeFreq(&succ) + : curBB.GetEdgeFreq(&succ) - 1) + : curCopyBB.PushBackSuccFreq(curBB.GetEdgeFreq(&succ)); } } @@ -252,10 +255,9 @@ void LoopUnrolling::CopyLoopBodyForProfile(BB &newHeadBB, std::unordered_mapSetFrequency(succ->GetFrequency() % replicatedLoopNum); } } else { - resetFreqForAfterInsertGoto ? - newBB->SetFrequency(succ->GetFrequency() - 1 == 0 ? succ->GetFrequency() : - succ->GetFrequency() - 1) : - newBB->SetFrequency(succ->GetFrequency()); + resetFreqForAfterInsertGoto + ? newBB->SetFrequency(succ->GetFrequency() - 1 == 0 ? succ->GetFrequency() : succ->GetFrequency() - 1) + : newBB->SetFrequency(succ->GetFrequency()); } curCopyBB->AddSucc(*newBB); ResetFrequency(*curBB, *succ, exitBB, *curCopyBB, copyAllLoop); @@ -272,8 +274,8 @@ void LoopUnrolling::CopyLoopBodyForProfile(BB &newHeadBB, std::unordered_map &old2NewBB, - std::set &labelBBs, const BB &exitBB, bool copyAllLoop) { +void LoopUnrolling::CopyLoopBody(BB &newHeadBB, std::unordered_map &old2NewBB, std::set &labelBBs, + const BB &exitBB, bool copyAllLoop) { CreateLableAndInsertLabelBB(newHeadBB, labelBBs); std::queue bbQue; bbQue.push(loop->head); @@ -308,13 +310,13 @@ void LoopUnrolling::CopyLoopBody(BB &newHeadBB, std::unordered_map &ol // Update frequency of old BB. void LoopUnrolling::ResetFrequency(BB &bb) { auto freq = bb.GetFrequency() / replicatedLoopNum; - if (freq == 0 && partialCount == 0 && bb.GetFrequency() != 0) { + if ((!instrumentProf) && freq == 0 && partialCount == 0 && bb.GetFrequency() != 0) { freq = 1; } bb.SetFrequency(static_cast(freq + partialCount)); for (size_t i = 0; i < bb.GetSucc().size(); ++i) { auto currFreq = bb.GetEdgeFreq(i) / replicatedLoopNum; - if (currFreq == 0 && partialCount == 0 && bb.GetFrequency() != 0) { + if ((!instrumentProf) && currFreq == 0 && partialCount == 0 && bb.GetFrequency() != 0) { currFreq = 1; } bb.SetEdgeFreq(bb.GetSucc(i), currFreq + partialCount); @@ -366,10 +368,10 @@ void LoopUnrolling::AddEdgeForExitBBLastNew2OldBBEmpty(BB &exitBB, std::unordere bb->ReplaceSucc(&exitBB, &newHeadBB); exitBB.AddPred(*old2NewBB[bb], idx); if (profValid) { - resetFreqForAfterInsertGoto ? - (bb->GetEdgeFreq(idx) - 1 == 0 ? old2NewBB[bb]->PushBackSuccFreq(bb->GetEdgeFreq(idx)) : - old2NewBB[bb]->PushBackSuccFreq(bb->GetEdgeFreq(idx) - 1)) : - old2NewBB[bb]->PushBackSuccFreq(bb->GetEdgeFreq(idx)); + resetFreqForAfterInsertGoto + ? (bb->GetEdgeFreq(idx) - 1 == 0 ? old2NewBB[bb]->PushBackSuccFreq(bb->GetEdgeFreq(idx)) + : old2NewBB[bb]->PushBackSuccFreq(bb->GetEdgeFreq(idx) - 1)) + : old2NewBB[bb]->PushBackSuccFreq(bb->GetEdgeFreq(idx)); } ResetOldLabel2NewLabel(old2NewBB, *bb, exitBB, newHeadBB); } @@ -383,10 +385,10 @@ void LoopUnrolling::AddEdgeForExitBB(BB &exitBB, std::unordered_map &o bb->ReplaceSucc(&exitBB, &newHeadBB); exitBB.AddPred(*old2NewBB[lastNew2OldBB[bb]], idx); if (profValid) { - (resetFreqForAfterInsertGoto && firstResetForAfterInsertGoto) ? - (bb->GetEdgeFreq(idx) - 1 == 0 ? old2NewBB[lastNew2OldBB[bb]]->PushBackSuccFreq(bb->GetEdgeFreq(idx)) : - old2NewBB[lastNew2OldBB[bb]]->PushBackSuccFreq(bb->GetEdgeFreq(idx) - 1)) : - old2NewBB[lastNew2OldBB[bb]]->PushBackSuccFreq(bb->GetEdgeFreq(idx)); + (resetFreqForAfterInsertGoto && firstResetForAfterInsertGoto) + ? (bb->GetEdgeFreq(idx) - 1 == 0 ? old2NewBB[lastNew2OldBB[bb]]->PushBackSuccFreq(bb->GetEdgeFreq(idx)) + : old2NewBB[lastNew2OldBB[bb]]->PushBackSuccFreq(bb->GetEdgeFreq(idx) - 1)) + : old2NewBB[lastNew2OldBB[bb]]->PushBackSuccFreq(bb->GetEdgeFreq(idx)); firstResetForAfterInsertGoto = false; } ResetOldLabel2NewLabel2(old2NewBB, *bb, exitBB, newHeadBB); @@ -403,14 +405,14 @@ void LoopUnrolling::CopyAndInsertBB(bool isPartial) { ResetFrequency(*loop->head); ResetFrequency(); } - profValid && resetFreqForAfterInsertGoto ? - (loop->head->GetFrequency() - 1 == 0 ? newHeadBB->SetFrequency(loop->head->GetFrequency()) : - newHeadBB->SetFrequency(loop->head->GetFrequency() - 1)) : - newHeadBB->SetFrequency(loop->head->GetFrequency()); + profValid &&resetFreqForAfterInsertGoto + ? (loop->head->GetFrequency() - 1 == 0 ? newHeadBB->SetFrequency(loop->head->GetFrequency()) + : newHeadBB->SetFrequency(loop->head->GetFrequency() - 1)) + : newHeadBB->SetFrequency(loop->head->GetFrequency()); (void)old2NewBB.emplace(loop->head, newHeadBB); std::set labelBBs; - profValid ? CopyLoopBodyForProfile(*newHeadBB, old2NewBB, labelBBs, *exitBB, false) : - CopyLoopBody(*newHeadBB, old2NewBB, labelBBs, *exitBB, false); + profValid ? CopyLoopBodyForProfile(*newHeadBB, old2NewBB, labelBBs, *exitBB, false) + : CopyLoopBody(*newHeadBB, old2NewBB, labelBBs, *exitBB, false); if (isPartial) { partialSuccHead = newHeadBB; } @@ -653,7 +655,8 @@ bool LoopUnrolling::LoopPartialUnrollWithConst(uint64 tripCount) { uint32 index = 0; if (!DetermineUnrollTimes(index, true)) { if (LoopUnrollingExecutor::enableDebug) { - LogInfo::MapleLogger() << "CodeSize is too large" << "\n"; + LogInfo::MapleLogger() << "CodeSize is too large" + << "\n"; } return false; } @@ -709,8 +712,8 @@ void LoopUnrolling::CopyLoopForPartialAndPre(BB *&newHead, BB *&newExiting) { (void)old2NewBB.emplace(loop->head, newHeadBB); std::set labelBBs; resetFreqForUnrollWithVar = true; - profValid ? CopyLoopBodyForProfile(*newHeadBB, old2NewBB, labelBBs, *exitBB, true) : - CopyLoopBody(*newHeadBB, old2NewBB, labelBBs, *exitBB, true); + profValid ? CopyLoopBodyForProfile(*newHeadBB, old2NewBB, labelBBs, *exitBB, true) + : CopyLoopBody(*newHeadBB, old2NewBB, labelBBs, *exitBB, true); resetFreqForUnrollWithVar = false; for (auto bb : labelBBs) { if (bb->GetKind() == kBBCondGoto) { @@ -741,8 +744,8 @@ VarMeExpr *LoopUnrolling::CreateIndVarOrTripCountWithName(const std::string &nam } // i < tripcount / unrollTime -void LoopUnrolling::UpdateCondGotoStmt(BB &bb, VarMeExpr &indVar, MeExpr &tripCount, - MeExpr &unrollTimeExpr, uint32 offset) { +void LoopUnrolling::UpdateCondGotoStmt(BB &bb, VarMeExpr &indVar, MeExpr &tripCount, MeExpr &unrollTimeExpr, + uint32 offset) { for (auto &stmt : bb.GetMeStmts()) { bb.RemoveMeStmt(&stmt); } @@ -814,8 +817,8 @@ void LoopUnrolling::CopyLoopForPartial(BB &partialCondGoto, BB &exitedBB, BB &ex partialCondGoto.AddSucc(*partialHead); if (profValid) { partialCondGoto.PushBackSuccFreq(loop->head->GetFrequency() % replicatedLoopNum); - partialCondGoto.SetFrequency(static_cast(partialCondGoto.GetEdgeFreq(static_cast(0)) + - partialCondGoto.GetEdgeFreq(1))); + partialCondGoto.SetFrequency( + static_cast(partialCondGoto.GetEdgeFreq(static_cast(0)) + partialCondGoto.GetEdgeFreq(1))); } CHECK_FATAL(partialCondGoto.GetKind() == kBBCondGoto, "must be partialCondGoto"); CHECK_FATAL(!partialCondGoto.GetMeStmts().empty(), "must not be empty"); @@ -975,17 +978,19 @@ bool LoopUnrolling::LoopPartialUnrollWithVar(CR &cr, CRNode &varNode, uint32 j) uint32 index = 0; if (!DetermineUnrollTimes(index, false)) { if (LoopUnrollingExecutor::enableDebug) { - LogInfo::MapleLogger() << "codesize is too large" << "\n"; + LogInfo::MapleLogger() << "codesize is too large" + << "\n"; } return false; } if (LoopUnrollingExecutor::enableDebug) { - LogInfo::MapleLogger() << "partial unrolling with var" << "\n"; + LogInfo::MapleLogger() << "partial unrolling with var" + << "\n"; } if (LoopUnrollingExecutor::enableDump) { irMap->Dump(); - profValid ? cfg->DumpToFile("cfgIncludeFreqInfobeforeLoopPartialWithVarUnrolling", false, true) : - cfg->DumpToFile("cfgbeforeLoopPartialWithVarUnrolling"); + profValid ? cfg->DumpToFile("cfgIncludeFreqInfobeforeLoopPartialWithVarUnrolling", false, true) + : cfg->DumpToFile("cfgbeforeLoopPartialWithVarUnrolling"); } if (!SplitCondGotoBB()) { return false; @@ -1006,8 +1011,8 @@ bool LoopUnrolling::LoopPartialUnrollWithVar(CR &cr, CRNode &varNode, uint32 j) } if (LoopUnrollingExecutor::enableDump) { irMap->Dump(); - profValid ? cfg->DumpToFile("cfgIncludeFreqInfoafterLoopPartialWithVarUnrolling", false, true) : - cfg->DumpToFile("cfgafterLoopPartialWithVarUnrolling"); + profValid ? cfg->DumpToFile("cfgIncludeFreqInfoafterLoopPartialWithVarUnrolling", false, true) + : cfg->DumpToFile("cfgafterLoopPartialWithVarUnrolling"); } return true; } @@ -1021,7 +1026,7 @@ void LoopUnrollingExecutor::SetNestedLoop(const IdentifyLoops &meLoop, CHECK_NULL_FATAL(loop->parent); auto it = parentLoop.find(loop->parent); if (it == parentLoop.end()) { - parentLoop[loop->parent] = { loop }; + parentLoop[loop->parent] = {loop}; } else { parentLoop[loop->parent].insert(loop); } @@ -1064,7 +1069,8 @@ bool LoopUnrollingExecutor::PredIsOutOfLoopBB(const MeFunction &func, LoopDesc & return false; } -bool LoopUnrollingExecutor::IsCanonicalAndOnlyOneExitLoop(const MeFunction &func, LoopDesc &loop, +bool LoopUnrollingExecutor::IsCanonicalAndOnlyOneExitLoop( + const MeFunction &func, LoopDesc &loop, const std::unordered_map> &parentLoop) const { // Only handle one nested loop. if (parentLoop.find(&loop) != parentLoop.end() && ProfileCheck(func)) { @@ -1082,7 +1088,8 @@ bool LoopUnrollingExecutor::IsCanonicalAndOnlyOneExitLoop(const MeFunction &func CHECK_FATAL(headBB->GetPred().size() == 2, "head must has two preds"); if (!IsDoWhileLoop(func, loop)) { if (enableDebug) { - LogInfo::MapleLogger() << "While-do loop" << "\n"; + LogInfo::MapleLogger() << "While-do loop" + << "\n"; } return false; } @@ -1099,19 +1106,20 @@ bool LoopUnrollingExecutor::IsCanonicalAndOnlyOneExitLoop(const MeFunction &func bool LoopUnrolling::LoopUnrollingWithConst(uint64 tripCount, bool onlyFully) { if (tripCount == kInvalidTripCount) { if (LoopUnrollingExecutor::enableDebug) { - LogInfo::MapleLogger() << "tripCount is invalid" << "\n"; + LogInfo::MapleLogger() << "tripCount is invalid" + << "\n"; } return false; } if (LoopUnrollingExecutor::enableDebug) { - LogInfo::MapleLogger() << "start unrolling with const" << "\n"; + LogInfo::MapleLogger() << "start unrolling with const" + << "\n"; LogInfo::MapleLogger() << "tripCount: " << tripCount << "\n"; } if (LoopUnrollingExecutor::enableDebug) { irMap->Dump(); - func->IsIRProfValid() ? func->GetCfg()->DumpToFile("cfgIncludeFreqInfobeforLoopUnrolling", false, true) : - func->GetCfg()->DumpToFile("cfgbeforLoopUnrolling" + - std::to_string(loop->head->GetBBId())); + func->IsIRProfValid() ? func->GetCfg()->DumpToFile("cfgIncludeFreqInfobeforLoopUnrolling", false, true) + : func->GetCfg()->DumpToFile("cfgbeforLoopUnrolling" + std::to_string(loop->head->GetBBId())); } // fully unroll ReturnKindOfFullyUnroll returnKind = LoopFullyUnroll(static_cast(tripCount)); @@ -1120,13 +1128,14 @@ bool LoopUnrolling::LoopUnrollingWithConst(uint64 tripCount, bool onlyFully) { } if (returnKind == LoopUnrolling::kCanFullyUnroll) { if (LoopUnrollingExecutor::enableDebug) { - LogInfo::MapleLogger() << "fully unrolling" << "\n"; + LogInfo::MapleLogger() << "fully unrolling" + << "\n"; } if (LoopUnrollingExecutor::enableDebug) { irMap->Dump(); - func->IsIRProfValid() ? func->GetCfg()->DumpToFile("cfgIncludeFreqInfoafterLoopFullyUnrolling", false, true) : - func->GetCfg()->DumpToFile("cfgafterLoopFullyUnrolling" + - std::to_string(loop->head->GetBBId())); + func->IsIRProfValid() + ? func->GetCfg()->DumpToFile("cfgIncludeFreqInfoafterLoopFullyUnrolling", false, true) + : func->GetCfg()->DumpToFile("cfgafterLoopFullyUnrolling" + std::to_string(loop->head->GetBBId())); } return true; } @@ -1136,12 +1145,13 @@ bool LoopUnrolling::LoopUnrollingWithConst(uint64 tripCount, bool onlyFully) { // partial unroll with const if (LoopPartialUnrollWithConst(tripCount)) { if (LoopUnrollingExecutor::enableDebug) { - LogInfo::MapleLogger() << "partial unrolling with const" << "\n"; + LogInfo::MapleLogger() << "partial unrolling with const" + << "\n"; } if (LoopUnrollingExecutor::enableDebug) { irMap->Dump(); - func->IsIRProfValid() ? func->GetCfg()->DumpToFile("cfgIncludeFreqInfoafterLoopPartialWithConst", false, true) : - func->GetCfg()->DumpToFile("cfgafterLoopPartialWithConstUnrolling"); + func->IsIRProfValid() ? func->GetCfg()->DumpToFile("cfgIncludeFreqInfoafterLoopPartialWithConst", false, true) + : func->GetCfg()->DumpToFile("cfgafterLoopPartialWithConstUnrolling"); } return true; } @@ -1149,7 +1159,8 @@ bool LoopUnrolling::LoopUnrollingWithConst(uint64 tripCount, bool onlyFully) { } void LoopUnrollingExecutor::ExecuteLoopUnrolling(MeFunction &func, MeIRMap &irMap, - std::map>> &cands, IdentifyLoops &meLoop, const MapleAllocator &alloc) { + std::map>> &cands, + IdentifyLoops &meLoop, const MapleAllocator &alloc) { if (enableDebug) { LogInfo::MapleLogger() << func.GetName() << "\n"; } @@ -1167,6 +1178,9 @@ void LoopUnrollingExecutor::ExecuteLoopUnrolling(MeFunction &func, MeIRMap &irMa } LoopScalarAnalysisResult sa(irMap, loop); LoopUnrolling loopUnrolling(func, *loop, irMap, alloc, cands); + if (func.GetCfg()->UpdateCFGFreq()) { + loopUnrolling.SetInstrumentProf(true); + } uint64 tripCount = 0; CRNode *conditionCRNode = nullptr; CR *itCR = nullptr; @@ -1235,6 +1249,9 @@ bool MELoopUnrolling::PhaseRun(maple::MeFunction &f) { MeSSAUpdate ssaUpdate(f, *f.GetMeSSATab(), *dom, cands); ssaUpdate.Run(); GetAnalysisInfoHook()->ForceEraseAnalysisPhase(f.GetUniqueID(), &MELoopAnalysis::id); + if (f.GetCfg()->UpdateCFGFreq() && f.GetCfg()->DumpIRProfileFile()) { + f.GetCfg()->DumpToFile("after-meloopunroll", false, true); + } } if (DEBUGFUNC_NEWPM(f)) { f.GetCfg()->DumpToFile("afterloopunrolling", false); diff --git a/src/mapleall/maple_me/src/me_profile_use.cpp b/src/mapleall/maple_me/src/me_profile_use.cpp index 4d9c62b6ad..0041c51b0d 100644 --- a/src/mapleall/maple_me/src/me_profile_use.cpp +++ b/src/mapleall/maple_me/src/me_profile_use.cpp @@ -13,10 +13,12 @@ * See the Mulan PSL v2 for more details. */ #include "me_profile_use.h" + #include + #include "me_cfg.h" -#include "me_option.h" #include "me_function.h" +#include "me_option.h" namespace maple { BBUseInfo *MeProfUse::GetOrCreateBBUseInfo(const BB &bb) { @@ -206,8 +208,8 @@ bool MeProfUse::BuildEdgeCount() { uint64 hash = ComputeFuncHash(); if (hash != result.funcHash) { if (dump) { - LogInfo::MapleLogger() << func->GetName() << " hash doesn't match profile hash " - << result.funcHash << " func real hash " << hash << '\n'; + LogInfo::MapleLogger() << func->GetName() << " hash doesn't match profile hash " << result.funcHash + << " func real hash " << hash << '\n'; } return false; } @@ -218,8 +220,8 @@ bool MeProfUse::BuildEdgeCount() { } if (instrumentBBs.size() != result.totalCounter) { if (dump) { - LogInfo::MapleLogger() << func->GetName() << " counter doesn't match profile counter " - << result.totalCounter << " func real counter " << instrumentBBs.size() << '\n'; + LogInfo::MapleLogger() << func->GetName() << " counter doesn't match profile counter " << result.totalCounter + << " func real counter " << instrumentBBs.size() << '\n'; } return false; } @@ -295,7 +297,7 @@ bool MeProfUse::Run() { } FuncProfInfo *MeProfUse::GetFuncData() { - MplProfileData* profData = func->GetMIRModule().GetMapleProfile(); + MplProfileData *profData = func->GetMIRModule().GetMapleProfile(); if (!profData) { return nullptr; } @@ -316,14 +318,14 @@ bool MeProfUse::CheckSumFail(const uint64 hash, const uint32 expectedCheckSum, c } bool MeProfUse::MapleProfRun() { - FuncProfInfo* funcData = GetFuncData(); + FuncProfInfo *funcData = GetFuncData(); if (!funcData) { return false; } func->GetMirFunc()->SetFuncProfData(funcData); // early return if lineno fail if (CheckSumFail(ComputeLinenoHash(), funcData->linenoChecksum, "lineno")) { - func->GetMirFunc()->SetFuncProfData(nullptr); // clear func profile data + func->GetMirFunc()->SetFuncProfData(nullptr); // clear func profile data return false; } FindInstrumentEdges(); @@ -338,10 +340,10 @@ bool MeProfUse::MapleProfRun() { } if (instrumentBBs.size() != funcData->edgeCounts) { if (dump) { - LogInfo::MapleLogger() << func->GetName() << " counter doesn't match profile counter " - << funcData->edgeCounts << " func real counter " << instrumentBBs.size() << '\n'; + LogInfo::MapleLogger() << func->GetName() << " counter doesn't match profile counter " << funcData->edgeCounts + << " func real counter " << instrumentBBs.size() << '\n'; } - func->GetMirFunc()->SetFuncProfData(nullptr); // clear func profile data + func->GetMirFunc()->SetFuncProfData(nullptr); // clear func profile data return false; } size_t i = 0; @@ -370,16 +372,21 @@ bool MEProfUse::PhaseRun(maple::MeFunction &f) { if (Options::profileUse) { result = profUse.MapleProfRun(); if (result) { - f.GetCfg()->VerifyBBFreq(); + result = f.GetCfg()->VerifyBBFreq(); + if (result > 0 && (DEBUGFUNC_NEWPM(f))) { + LogInfo::MapleLogger() << "func profileUse verification fail" << std::endl; + } } } else { profUse.Run(); } - if (result) { + if (DEBUGFUNC_NEWPM(f)) { LogInfo::MapleLogger() << "******************after profile use dump function******************\n"; profUse.DumpFuncCFGEdgeFreq(); - f.GetCfg()->DumpToFile("afterProfileUse", false, true); + } + if (f.GetCfg()->DumpIRProfileFile()) { + f.GetCfg()->DumpToFile("after-ProfileUse", false, true); } return true; } diff --git a/src/mapleall/maple_me/src/me_value_range_prop.cpp b/src/mapleall/maple_me/src/me_value_range_prop.cpp index e2200a7077..6a706787db 100644 --- a/src/mapleall/maple_me/src/me_value_range_prop.cpp +++ b/src/mapleall/maple_me/src/me_value_range_prop.cpp @@ -13,14 +13,15 @@ * See the Mulan PSL v2 for more details. */ #include "me_value_range_prop.h" -#include "me_dominance.h" + #include "me_abco.h" -#include "me_ssa_update.h" +#include "me_dominance.h" #include "me_phase_manager.h" #include "me_safety_warning.h" +#include "me_ssa_update.h" namespace maple { -bool ValueRangePropagation::isDebug = false; +bool ValueRangePropagation::isDebug = true; constexpr size_t kNumOperands = 2; constexpr size_t kCodeSizeLimit = 2000; constexpr std::uint64_t kInvaliedBound = 0xdeadbeef; @@ -38,8 +39,8 @@ bool Bound::CanBeComparedWith(const Bound &bound) const { if (var == bound.GetVar()) { return true; } - return (*this == MinBound(primType) || *this == MaxBound(primType) || - bound == MinBound(primType) || bound == MaxBound(primType)); + return (*this == MinBound(primType) || *this == MaxBound(primType) || bound == MinBound(primType) || + bound == MaxBound(primType)); } bool Bound::operator<(const Bound &bound) const { @@ -78,6 +79,10 @@ void ValueRangePropagation::Execute() { dealWithPhi = true; DealWithPhi(**bIt); dealWithPhi = false; + if (func.GetCfg()->UpdateCFGFreq()) { + // update edge frequency + (*bIt)->UpdateEdgeFreqs(false); + } for (auto it = (*bIt)->GetMeStmts().begin(); it != (*bIt)->GetMeStmts().end();) { bool deleteStmt = false; if (!onlyPropVR) { @@ -95,8 +100,8 @@ void ValueRangePropagation::Execute() { ++it; continue; } - if (MeOption::safeRegionMode && (it->IsInSafeRegion()) && - kOpcodeInfo.IsCall(it->GetOp()) && instance_of(*it)) { + if (MeOption::safeRegionMode && (it->IsInSafeRegion()) && kOpcodeInfo.IsCall(it->GetOp()) && + instance_of(*it)) { MIRFunction *callFunc = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(static_cast(*it).GetPUIdx()); if (callFunc->IsUnSafe()) { @@ -122,40 +127,40 @@ void ValueRangePropagation::Execute() { InsertValueRangeOfCondExpr2Caches(**bIt, *it); break; } - CASE_OP_ASSERT_NONNULL { - if (!dealWithAssert) { - break; - } - // If the option safeRegion is open and the stmt is not in safe region, delete it. - if (MeOption::safeRegionMode && !it->IsInSafeRegion()) { - deleteStmt = true; - } else if (DealWithAssertNonnull(**bIt, *it)) { - if (ValueRangePropagation::isDebug) { - LogInfo::MapleLogger() << "=========delete assert nonnull=========\n"; - it->Dump(&irMap); - LogInfo::MapleLogger() << "=========delete assert nonnull=========\n"; + CASE_OP_ASSERT_NONNULL { + if (!dealWithAssert) { + break; + } + // If the option safeRegion is open and the stmt is not in safe region, delete it. + if (MeOption::safeRegionMode && !it->IsInSafeRegion()) { + deleteStmt = true; + } else if (DealWithAssertNonnull(**bIt, *it)) { + if (ValueRangePropagation::isDebug) { + LogInfo::MapleLogger() << "=========delete assert nonnull=========\n"; + it->Dump(&irMap); + LogInfo::MapleLogger() << "=========delete assert nonnull=========\n"; + } + deleteStmt = true; } - deleteStmt = true; - } - break; - } - CASE_OP_ASSERT_BOUNDARY { - if (!dealWithAssert) { break; } - // If the option safeRegion is open and the stmt is not in safe region, delete it. - if (MeOption::safeRegionMode && !it->IsInSafeRegion()) { - deleteStmt = true; - } else if (DealWithBoundaryCheck(**bIt, *it)) { - if (ValueRangePropagation::isDebug) { - LogInfo::MapleLogger() << "=========delete boundary check=========\n"; - it->Dump(&irMap); - LogInfo::MapleLogger() << "=========delete boundary check=========\n"; + CASE_OP_ASSERT_BOUNDARY { + if (!dealWithAssert) { + break; + } + // If the option safeRegion is open and the stmt is not in safe region, delete it. + if (MeOption::safeRegionMode && !it->IsInSafeRegion()) { + deleteStmt = true; + } else if (DealWithBoundaryCheck(**bIt, *it)) { + if (ValueRangePropagation::isDebug) { + LogInfo::MapleLogger() << "=========delete boundary check=========\n"; + it->Dump(&irMap); + LogInfo::MapleLogger() << "=========delete boundary check=========\n"; + } + deleteStmt = true; } - deleteStmt = true; + break; } - break; - } case OP_callassigned: { DealWithCallassigned(**bIt, *it); break; @@ -186,7 +191,8 @@ void ValueRangePropagation::DealWithCallassigned(const BB &bb, MeStmt &stmt) { auto &callassign = static_cast(stmt); MIRFunction *callFunc = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callassign.GetPUIdx()); if (callFunc->GetAttr(FUNCATTR_nonnull) && callassign.GetAssignedLHS() != nullptr) { - (void)Insert2Caches(bb.GetBBId(), callassign.GetAssignedLHS()->GetExprID(), + (void)Insert2Caches( + bb.GetBBId(), callassign.GetAssignedLHS()->GetExprID(), std::make_unique(Bound(nullptr, 0, callassign.GetAssignedLHS()->GetPrimType()), kNotEqual)); } } @@ -207,9 +213,8 @@ void ValueRangePropagation::DealWithSwitch(BB &bb, MeStmt &stmt) { // Can prop value range to target bb only when the pred size of target bb is one and // only one case can jump to the target bb. if (currbb->GetPred().size() == 1 && bbOfCases.insert(currbb->GetBBId()).second) { - (void)Insert2Caches( - currbb->GetBBId(), opnd->GetExprID(), - std::make_unique(Bound(nullptr, pair.first, PTY_i64), kEqual)); + (void)Insert2Caches(currbb->GetBBId(), opnd->GetExprID(), + std::make_unique(Bound(nullptr, pair.first, PTY_i64), kEqual)); } else { (void)Insert2Caches(currbb->GetBBId(), opnd->GetExprID(), nullptr); } @@ -257,7 +262,7 @@ void ValueRangePropagation::DeleteThePhiNodeWhichOnlyHasOneOpnd( } } -bool ValueRange::IsEqual(ValueRange *valueRangeRight) const { +bool ValueRange::IsEqual(ValueRange *valueRangeRight) const { if (valueRangeRight == nullptr) { return false; } @@ -268,14 +273,11 @@ bool ValueRange::IsEqual(ValueRange *valueRangeRight) const { case kLowerAndUpper: case kSpecialUpperForLoop: case kSpecialLowerForLoop: - return range.pair.upper == (valueRangeRight->GetUpper()) && - range.pair.lower == (valueRangeRight->GetLower()); + return range.pair.upper == (valueRangeRight->GetUpper()) && range.pair.lower == (valueRangeRight->GetLower()); case kOnlyHasLowerBound: - return range.pair.lower == (valueRangeRight->GetLower()) && - stride == valueRangeRight->GetStride(); + return range.pair.lower == (valueRangeRight->GetLower()) && stride == valueRangeRight->GetStride(); case kOnlyHasUpperBound: - return range.pair.upper == (valueRangeRight->GetUpper()) && - stride == valueRangeRight->GetStride(); + return range.pair.upper == (valueRangeRight->GetUpper()) && stride == valueRangeRight->GetStride(); case kNotEqual: case kEqual: return range.bound == (valueRangeRight->GetBound()); @@ -309,7 +311,7 @@ std::unique_ptr MergeVR(const ValueRange &vr1, const ValueRange &vr2 return nullptr; } if (upper2 < lower1 || upper1 < lower2) { - return intersect ? std::make_unique(kRTEmpty) : nullptr; // always false + return intersect ? std::make_unique(kRTEmpty) : nullptr; // always false } else if (upper2 == lower1) { return intersect ? std::make_unique(lower1, kEqual) : std::make_unique(lower2, upper1, kLowerAndUpper); @@ -317,9 +319,10 @@ std::unique_ptr MergeVR(const ValueRange &vr1, const ValueRange &vr2 return intersect ? std::make_unique(lower2, kEqual) : std::make_unique(lower1, upper2, kLowerAndUpper); } else { - return intersect ? - std::make_unique(std::max(lower1, lower2), std::min(upper1, upper2), kLowerAndUpper) : - std::make_unique(std::min(lower1, lower2), std::max(upper1, upper2), kLowerAndUpper); + return intersect ? std::make_unique(std::max(lower1, lower2), std::min(upper1, upper2), + kLowerAndUpper) + : std::make_unique(std::min(lower1, lower2), std::max(upper1, upper2), + kLowerAndUpper); } } case kEqual: { @@ -332,9 +335,9 @@ std::unique_ptr MergeVR(const ValueRange &vr1, const ValueRange &vr2 if (lower1 <= bound && bound <= upper1) { return intersect ? std::make_unique(bound, kEqual) : std::make_unique(lower1, upper1, kLowerAndUpper); - } else { // if (bound < lower1 || upper1 < bound) - return intersect ? std::make_unique(kRTEmpty) // always false - : nullptr; // can not merge + } else { // if (bound < lower1 || upper1 < bound) + return intersect ? std::make_unique(kRTEmpty) // always false + : nullptr; // can not merge } } case kNotEqual: { @@ -351,10 +354,10 @@ std::unique_ptr MergeVR(const ValueRange &vr1, const ValueRange &vr2 return intersect ? nullptr : std::make_unique(kRTComplete); } else if (bound == lower1) { return intersect ? std::make_unique(++lower1, upper1, kLowerAndUpper) - : std::make_unique(kRTComplete); // always true; - } else { // bound == upper1 + : std::make_unique(kRTComplete); // always true; + } else { // bound == upper1 return intersect ? std::make_unique(lower1, --upper1, kLowerAndUpper) - : std::make_unique(kRTComplete); // always true; + : std::make_unique(kRTComplete); // always true; } } default: @@ -369,7 +372,7 @@ std::unique_ptr MergeVR(const ValueRange &vr1, const ValueRange &vr2 } switch (vr2Type) { case kLowerAndUpper: { - return MergeVR(vr2, vr1, intersect); // swap two vr + return MergeVR(vr2, vr1, intersect); // swap two vr } case kEqual: { if (b1 == b2) { @@ -393,7 +396,7 @@ std::unique_ptr MergeVR(const ValueRange &vr1, const ValueRange &vr2 switch (vr2Type) { case kLowerAndUpper: case kEqual: { - return MergeVR(vr2, vr1, intersect); // swap two vr + return MergeVR(vr2, vr1, intersect); // swap two vr } case kNotEqual: { Bound b1 = vr1.GetBound(); @@ -418,7 +421,7 @@ std::unique_ptr MergeVR(const ValueRange &vr1, const ValueRange &vr2 MeExpr *GetCmpExprFromBound(Bound b, MeExpr &expr, MeIRMap *irmap, Opcode op) { int64 val = b.GetConstant(); - MeExpr *var = const_cast(b.GetVar()); + MeExpr *var = const_cast(b.GetVar()); PrimType ptyp = b.GetPrimType(); MeExpr *constExpr = irmap->CreateIntConstMeExpr(val, ptyp); MeExpr *resExpr = nullptr; @@ -505,19 +508,18 @@ std::unique_ptr ValueRangePropagation::ZeroIsInRange(const ValueRang valueRange.GetUpper().GetVar() == nullptr && valueRange.GetLower().GetConstant() < valueRange.GetUpper().GetConstant()) { if (valueRange.GetLower().GetConstant() == 0) { - return std::make_unique( - Bound(1, valueRange.GetLower().GetPrimType()), valueRange.GetUpper(), kLowerAndUpper); + return std::make_unique(Bound(1, valueRange.GetLower().GetPrimType()), valueRange.GetUpper(), + kLowerAndUpper); } if (valueRange.GetUpper().GetConstant() == 0) { - return std::make_unique( - valueRange.GetLower(), Bound(-1, valueRange.GetUpper().GetPrimType()), kLowerAndUpper); + return std::make_unique(valueRange.GetLower(), Bound(-1, valueRange.GetUpper().GetPrimType()), + kLowerAndUpper); } } return nullptr; } -std::unique_ptr ValueRangePropagation::FindValueRangeInCurrBBOrDominateBBs( - const BB &bb, MeExpr &opnd) { +std::unique_ptr ValueRangePropagation::FindValueRangeInCurrBBOrDominateBBs(const BB &bb, MeExpr &opnd) { auto *res = FindValueRangeInCurrentBB(bb.GetBBId(), opnd.GetExprID()); if (res != nullptr) { return CopyValueRange(*res); @@ -529,11 +531,10 @@ std::unique_ptr ValueRangePropagation::FindValueRangeInCurrBBOrDomin return nullptr; } -void SafetyCheckWithBoundaryError::HandleAssignWithDeadBeef( - const BB &bb, MeStmt &meStmt, MeExpr &indexOpnd, - MeExpr &boundOpnd) { +void SafetyCheckWithBoundaryError::HandleAssignWithDeadBeef(const BB &bb, MeStmt &meStmt, MeExpr &indexOpnd, + MeExpr &boundOpnd) { std::set visitedLHS; - std::vector stmts{ &meStmt }; + std::vector stmts{&meStmt}; vrp.JudgeTheConsistencyOfDefPointsOfBoundaryCheck(bb, indexOpnd, visitedLHS, stmts); visitedLHS.clear(); stmts.clear(); @@ -545,8 +546,8 @@ void SafetyCheckWithBoundaryError::HandleAssignWithDeadBeef( // valueRangeOfIndex zero is in range and in safe region mode, compiler err // valueRangeOfIndex is zero and not in safe region mode, compiler err void SafetyCheckWithNonnullError::HandleAssertNonnull(const MeStmt &meStmt, const ValueRange *valueRangeOfIndex) { - if ((valueRangeOfIndex == nullptr || valueRangeOfIndex->IsZeroInRange()) && - meStmt.IsInSafeRegion() && MeOption::safeRegionMode) { + if ((valueRangeOfIndex == nullptr || valueRangeOfIndex->IsZeroInRange()) && meStmt.IsInSafeRegion() && + MeOption::safeRegionMode) { (void)NeedDeleteTheAssertAfterErrorOrWarn(meStmt, true); } if (valueRangeOfIndex != nullptr && valueRangeOfIndex->IsEqualZero()) { @@ -558,8 +559,8 @@ bool SafetyCheckWithBoundaryError::HandleAssertError(const MeStmt &meStmt) { return NeedDeleteTheAssertAfterErrorOrWarn(meStmt); } -bool SafetyCheckWithBoundaryError::HandleAssertltOrAssertle( - const MeStmt &meStmt, Opcode op, int64 indexValue, int64 lengthValue) { +bool SafetyCheckWithBoundaryError::HandleAssertltOrAssertle(const MeStmt &meStmt, Opcode op, int64 indexValue, + int64 lengthValue) { if (kOpcodeInfo.IsAssertLeBoundary((op))) { if (indexValue > lengthValue) { return NeedDeleteTheAssertAfterErrorOrWarn(meStmt); @@ -572,19 +573,21 @@ bool SafetyCheckWithBoundaryError::HandleAssertltOrAssertle( return false; } -bool ValueRangePropagation::CompareConstantOfIndexAndLength( - const MeStmt &meStmt, const ValueRange &valueRangeOfIndex, ValueRange &valueRangeOfLengthPtr, Opcode op) { +bool ValueRangePropagation::CompareConstantOfIndexAndLength(const MeStmt &meStmt, const ValueRange &valueRangeOfIndex, + ValueRange &valueRangeOfLengthPtr, Opcode op) { if (safetyCheckBoundary->HandleAssertltOrAssertle(meStmt, op, valueRangeOfIndex.GetUpper().GetConstant(), valueRangeOfLengthPtr.GetBound().GetConstant())) { return true; } - return (kOpcodeInfo.IsAssertLeBoundary(op) ? - valueRangeOfIndex.GetUpper().GetConstant() <= valueRangeOfLengthPtr.GetBound().GetConstant() : - valueRangeOfIndex.GetUpper().GetConstant() < valueRangeOfLengthPtr.GetBound().GetConstant()); + return (kOpcodeInfo.IsAssertLeBoundary(op) + ? valueRangeOfIndex.GetUpper().GetConstant() <= valueRangeOfLengthPtr.GetBound().GetConstant() + : valueRangeOfIndex.GetUpper().GetConstant() < valueRangeOfLengthPtr.GetBound().GetConstant()); } bool ValueRangePropagation::CompareIndexWithUpper(const BB &bb, const MeStmt &meStmt, - const ValueRange &valueRangeOfIndex, ValueRange &valueRangeOfLengthPtr, Opcode op, const MeExpr *indexOpnd) { + const ValueRange &valueRangeOfIndex, + ValueRange &valueRangeOfLengthPtr, Opcode op, + const MeExpr *indexOpnd) { if (valueRangeOfIndex.GetRangeType() == kNotEqual || valueRangeOfLengthPtr.GetRangeType() == kNotEqual) { return false; } @@ -598,8 +601,8 @@ bool ValueRangePropagation::CompareIndexWithUpper(const BB &bb, const MeStmt &me upperOfLength)) { return true; } - return (kOpcodeInfo.IsAssertLeBoundary((op))) ? valueRangeOfIndex.GetUpper().GetConstant() <= lowerOfLength : - valueRangeOfIndex.GetUpper().GetConstant() < lowerOfLength; + return (kOpcodeInfo.IsAssertLeBoundary((op))) ? valueRangeOfIndex.GetUpper().GetConstant() <= lowerOfLength + : valueRangeOfIndex.GetUpper().GetConstant() < lowerOfLength; } if (!valueRangeOfIndex.IsConstantLowerAndUpper() || valueRangeOfIndex.GetLower().GetConstant() > valueRangeOfIndex.GetUpper().GetConstant() || @@ -624,8 +627,8 @@ bool ValueRangePropagation::CompareIndexWithUpper(const BB &bb, const MeStmt &me return true; } } - return (kOpcodeInfo.IsAssertLeBoundary((op))) ? valueRangeOfIndex.GetUpper().GetConstant() <= lowerOfLength : - valueRangeOfIndex.GetUpper().GetConstant() < lowerOfLength; + return (kOpcodeInfo.IsAssertLeBoundary((op))) ? valueRangeOfIndex.GetUpper().GetConstant() <= lowerOfLength + : valueRangeOfIndex.GetUpper().GetConstant() < lowerOfLength; } else if (valueRangeOfLengthPtr.GetRangeType() == kEqual) { // Opt array boundary check when the array length is a var. if (valueRangeOfIndex.GetRangeType() == kSpecialUpperForLoop || @@ -647,10 +650,9 @@ bool ValueRangePropagation::CompareIndexWithUpper(const BB &bb, const MeStmt &me } if (crNode->GetCRType() == kCRVarNode) { return (crNode->GetExpr() == valueRangeOfLengthPtr.GetBound().GetVar()) && - CompareConstantOfIndexAndLength(meStmt, valueRangeOfIndex, valueRangeOfLengthPtr, op); + CompareConstantOfIndexAndLength(meStmt, valueRangeOfIndex, valueRangeOfLengthPtr, op); } - if (crNode->GetCRType() != kCRAddNode || - static_cast(crNode)->GetOpndsSize() != kNumOperands || + if (crNode->GetCRType() != kCRAddNode || static_cast(crNode)->GetOpndsSize() != kNumOperands || static_cast(crNode)->GetOpnd(1)->GetExpr() == nullptr || static_cast(crNode)->GetOpnd(1)->GetExpr() != valueRangeOfLengthPtr.GetBound().GetVar() || static_cast(crNode)->GetOpnd(0)->GetCRType() != kCRConstNode) { @@ -662,8 +664,7 @@ bool ValueRangePropagation::CompareIndexWithUpper(const BB &bb, const MeStmt &me // expr = length - 1 // after analysis: valueRangeOfIndex : (lower(length), upper: (-2), kLowerAndUpper) int64 res = 0; - auto constantValue = - static_cast(static_cast(crNode)->GetOpnd(0))->GetConstValue(); + auto constantValue = static_cast(static_cast(crNode)->GetOpnd(0))->GetConstValue(); if (!AddOrSubWithConstant(valueRangeOfLengthPtr.GetUpper().GetPrimType(), OP_add, constantValue, valueRangeOfIndex.GetUpper().GetConstant(), res)) { return false; @@ -672,8 +673,8 @@ bool ValueRangePropagation::CompareIndexWithUpper(const BB &bb, const MeStmt &me valueRangeOfLengthPtr.GetBound().GetConstant())) { return true; } - return (kOpcodeInfo.IsAssertLeBoundary(op) ? res <= valueRangeOfLengthPtr.GetBound().GetConstant() : - res < valueRangeOfLengthPtr.GetBound().GetConstant()); + return (kOpcodeInfo.IsAssertLeBoundary(op) ? res <= valueRangeOfLengthPtr.GetBound().GetConstant() + : res < valueRangeOfLengthPtr.GetBound().GetConstant()); } else { return CompareConstantOfIndexAndLength(meStmt, valueRangeOfIndex, valueRangeOfLengthPtr, op); } @@ -686,9 +687,9 @@ bool ValueRangePropagation::CompareIndexWithUpper(const BB &bb, const MeStmt &me valueRangeOfLengthPtr.GetBound().GetConstant())) { return true; } - return kOpcodeInfo.IsAssertLeBoundary(op) ? - valueRangeOfIndex.GetUpper().GetConstant() <= valueRangeOfLengthPtr.GetBound().GetConstant() : - valueRangeOfIndex.GetUpper().GetConstant() < valueRangeOfLengthPtr.GetBound().GetConstant(); + return kOpcodeInfo.IsAssertLeBoundary(op) + ? valueRangeOfIndex.GetUpper().GetConstant() <= valueRangeOfLengthPtr.GetBound().GetConstant() + : valueRangeOfIndex.GetUpper().GetConstant() < valueRangeOfLengthPtr.GetBound().GetConstant(); } return false; } @@ -698,8 +699,9 @@ bool ValueRangePropagation::CompareIndexWithUpper(const BB &bb, const MeStmt &me bool ValueRangePropagation::IfAnalysisedBefore(const BB &bb, const MeStmt &stmt) { MeExpr &index = *stmt.GetOpnd(0); MeExpr &bound = *stmt.GetOpnd(1); - auto &analysisedArrayChecks = (kOpcodeInfo.IsAssertLowerBoundary(stmt.GetOp())) ? analysisedLowerBoundChecks : - (kOpcodeInfo.IsAssertLeBoundary(stmt.GetOp())) ? analysisedAssignBoundChecks : analysisedUpperBoundChecks; + auto &analysisedArrayChecks = (kOpcodeInfo.IsAssertLowerBoundary(stmt.GetOp())) ? analysisedLowerBoundChecks + : (kOpcodeInfo.IsAssertLeBoundary(stmt.GetOp())) ? analysisedAssignBoundChecks + : analysisedUpperBoundChecks; for (size_t i = 0; i < analysisedArrayChecks.size(); ++i) { auto *analysisedBB = func.GetCfg()->GetBBFromID(BBId(i)); if (!dom.Dominate(*analysisedBB, bb)) { @@ -720,8 +722,8 @@ bool ValueRangePropagation::IfAnalysisedBefore(const BB &bb, const MeStmt &stmt) return false; } -bool ValueRangePropagation::TheValueOfOpndIsInvaliedInABCO( - const BB &bb, const MeStmt *meStmt, MeExpr &boundOpnd, bool updateCaches) { +bool ValueRangePropagation::TheValueOfOpndIsInvaliedInABCO(const BB &bb, const MeStmt *meStmt, MeExpr &boundOpnd, + bool updateCaches) { if (boundOpnd.GetMeOp() == kMeOpConst && static_cast(boundOpnd).GetConstVal()->GetKind() == kConstInt && static_cast(static_cast(boundOpnd).GetExtIntValue()) == kInvaliedBound) { @@ -731,8 +733,8 @@ bool ValueRangePropagation::TheValueOfOpndIsInvaliedInABCO( return true; } else { auto *valueRange = FindValueRange(bb, boundOpnd); - if (valueRange != nullptr && valueRange->GetRangeType() != kNotEqual && - valueRange->IsConstant() && static_cast(valueRange->GetLower().GetConstant()) == kInvaliedBound) { + if (valueRange != nullptr && valueRange->GetRangeType() != kNotEqual && valueRange->IsConstant() && + static_cast(valueRange->GetLower().GetConstant()) == kInvaliedBound) { if (updateCaches) { Insert2AnalysisedArrayChecks(bb.GetBBId(), *meStmt->GetOpnd(1), *meStmt->GetOpnd(0), meStmt->GetOp()); } @@ -748,8 +750,9 @@ bool ValueRangePropagation::TheValueOfOpndIsInvaliedInABCO( // else: // p = GetBoundarylessPtr // error: p + i -void ValueRangePropagation::JudgeTheConsistencyOfDefPointsOfBoundaryCheck( - const BB &bb, MeExpr &expr, std::set &visitedLHS, std::vector &stmts) { +void ValueRangePropagation::JudgeTheConsistencyOfDefPointsOfBoundaryCheck(const BB &bb, MeExpr &expr, + std::set &visitedLHS, + std::vector &stmts) { if (TheValueOfOpndIsInvaliedInABCO(bb, nullptr, expr, false)) { std::string errorLog = "error: pointer assigned from multibranch requires the boundary info for all branches.\n"; for (size_t i = 0; i < stmts.size(); ++i) { @@ -761,7 +764,7 @@ void ValueRangePropagation::JudgeTheConsistencyOfDefPointsOfBoundaryCheck( } auto &srcPosition = stmts[i]->GetSrcPosition(); errorLog += func.GetMIRModule().GetFileNameFromFileNum(srcPosition.FileNum()) + ":" + - std::to_string(srcPosition.LineNum()) + "\n"; + std::to_string(srcPosition.LineNum()) + "\n"; } FATAL(kLncFatal, "%s", errorLog.c_str()); } @@ -846,8 +849,8 @@ static inline bool CanNotDoReplaceLoopVarOpt(const ValueRange *valueRange) { return type != kEqual && !(type == kLowerAndUpper && valueRange->IsAccurate()); } -void ValueRangePropagation::CollectIndexOpndWithBoundInLoop( - LoopDesc &loop, BB &bb, MeStmt &meStmt, MeExpr &opnd, std::map &index2NewExpr) { +void ValueRangePropagation::CollectIndexOpndWithBoundInLoop(LoopDesc &loop, BB &bb, MeStmt &meStmt, MeExpr &opnd, + std::map &index2NewExpr) { // If the var is opnd of ivar, can not replace it with the bound. // For example: array[s[i]] // assert(array + iread(s + i) * 4, array + 1024) @@ -887,20 +890,20 @@ void ValueRangePropagation::CollectIndexOpndWithBoundInLoop( MeExpr *ValueRangePropagation::GetAddressOfIndexOrBound(MeExpr &expr) const { if (expr.IsLeaf()) { - return (expr.IsScalar() && static_cast(expr).GetDefBy() == kDefByStmt) ? - GetAddressOfIndexOrBound(*static_cast(expr).GetDefStmt()->GetRHS()) : &expr; + return (expr.IsScalar() && static_cast(expr).GetDefBy() == kDefByStmt) + ? GetAddressOfIndexOrBound(*static_cast(expr).GetDefStmt()->GetRHS()) + : &expr; } return GetAddressOfIndexOrBound(*expr.GetOpnd(0)); } -void ValueRangePropagation::GetValueRangeOfCRNode( - const BB &bb, CRNode &opndOfCRNode, std::unique_ptr &resValueRange, PrimType pTypeOfArray) { +void ValueRangePropagation::GetValueRangeOfCRNode(const BB &bb, CRNode &opndOfCRNode, + std::unique_ptr &resValueRange, PrimType pTypeOfArray) { // Deal with the operand which is a constant. if (opndOfCRNode.GetCRType() == kCRConstNode) { int64 constant = static_cast(opndOfCRNode).GetConstValue(); - resValueRange = (resValueRange == nullptr) ? - std::make_unique(Bound(constant, pTypeOfArray), kEqual) : - AddOrSubWithValueRange(OP_add, *resValueRange, constant); + resValueRange = (resValueRange == nullptr) ? std::make_unique(Bound(constant, pTypeOfArray), kEqual) + : AddOrSubWithValueRange(OP_add, *resValueRange, constant); return; } // Deal with the operand which is a meexpr. @@ -910,8 +913,8 @@ void ValueRangePropagation::GetValueRangeOfCRNode( } auto valueRangOfOpnd = FindValueRangeInCurrBBOrDominateBBs(bb, *opndOfCRNode.GetExpr()); if (valueRangOfOpnd == nullptr) { - valueRangOfOpnd = std::make_unique( - Bound(opndOfCRNode.GetExpr(), opndOfCRNode.GetExpr()->GetPrimType()), kEqual); + valueRangOfOpnd = + std::make_unique(Bound(opndOfCRNode.GetExpr(), opndOfCRNode.GetExpr()->GetPrimType()), kEqual); if (resValueRange == nullptr) { resValueRange = std::move(valueRangOfOpnd); } else if (resValueRange->IsNotConstantVR()) { @@ -923,22 +926,22 @@ void ValueRangePropagation::GetValueRangeOfCRNode( } } } else if (valueRangOfOpnd->GetRangeType() == kNotEqual && resValueRange == nullptr) { - resValueRange = std::make_unique( - Bound(opndOfCRNode.GetExpr(), opndOfCRNode.GetExpr()->GetPrimType()), kEqual); + resValueRange = + std::make_unique(Bound(opndOfCRNode.GetExpr(), opndOfCRNode.GetExpr()->GetPrimType()), kEqual); } else if (valueRangOfOpnd->GetRangeType() == kOnlyHasUpperBound || valueRangOfOpnd->GetRangeType() == kOnlyHasLowerBound) { resValueRange = nullptr; } else { - resValueRange = (resValueRange == nullptr) ? std::move(valueRangOfOpnd) : - AddOrSubWithValueRange(OP_add, *resValueRange, *valueRangOfOpnd); + resValueRange = (resValueRange == nullptr) ? std::move(valueRangOfOpnd) + : AddOrSubWithValueRange(OP_add, *resValueRange, *valueRangOfOpnd); } } // Get the valueRange of index and bound, for example: // assertge(ptr, ptr + 8) -> the valueRange of index is 8 // assertge(ptr, ptr + len * 4 - 8) -> the valueRange of index is len - 2 -std::unique_ptr ValueRangePropagation::GetValueRangeOfCRNodes( - const BB &bb, PrimType pTypeOfArray, std::vector &crNodes) { +std::unique_ptr ValueRangePropagation::GetValueRangeOfCRNodes(const BB &bb, PrimType pTypeOfArray, + std::vector &crNodes) { if (crNodes.empty()) { return CreateValueRangeOfEqualZero(pTypeOfArray); } @@ -1022,12 +1025,14 @@ bool ValueRangePropagation::DealWithBoundaryCheck(BB &bb, MeStmt &meStmt) { } if (ValueRangePropagation::isDebug) { std::for_each(indexVector.begin(), indexVector.end(), [this](const CRNode *cr) { - sa.Dump(*cr); - std::cout << " ";}); + sa.Dump(*cr); + std::cout << " "; + }); LogInfo::MapleLogger() << "\n"; std::for_each(boundVector.begin(), boundVector.end(), [this](const CRNode *cr) { - sa.Dump(*cr); - std::cout << " ";}); + sa.Dump(*cr); + std::cout << " "; + }); LogInfo::MapleLogger() << "\n"; } // Get the valueRange of index and bound @@ -1037,8 +1042,7 @@ bool ValueRangePropagation::DealWithBoundaryCheck(BB &bb, MeStmt &meStmt) { return false; } if (kOpcodeInfo.IsAssertLowerBoundary(meStmt.GetOp())) { - if (BrStmtInRange(bb, *valueRangeOfIndex, *valueRangeOfbound, OP_ge, - valueRangeOfIndex->GetLower().GetPrimType())) { + if (BrStmtInRange(bb, *valueRangeOfIndex, *valueRangeOfbound, OP_ge, valueRangeOfIndex->GetLower().GetPrimType())) { // Can opt the boundary check. return true; } else if (BrStmtInRange(bb, *valueRangeOfIndex, *valueRangeOfbound, OP_lt, @@ -1048,8 +1052,8 @@ bool ValueRangePropagation::DealWithBoundaryCheck(BB &bb, MeStmt &meStmt) { return true; } } else if ((valueRangeOfIndex->GetRangeType() == kSpecialUpperForLoop || - valueRangeOfIndex->GetRangeType() == kOnlyHasLowerBound || - (valueRangeOfIndex->GetRangeType() == kLowerAndUpper && valueRangeOfIndex->IsAccurate())) && + valueRangeOfIndex->GetRangeType() == kOnlyHasLowerBound || + (valueRangeOfIndex->GetRangeType() == kLowerAndUpper && valueRangeOfIndex->IsAccurate())) && valueRangeOfIndex->GetLower().GetVar() == nullptr && valueRangeOfbound->GetLower().GetVar() == nullptr && valueRangeOfbound->GetUpper().GetVar() == nullptr) { if (valueRangeOfIndex->GetLower().GetConstant() < valueRangeOfbound->GetUpper().GetConstant()) { @@ -1063,8 +1067,8 @@ bool ValueRangePropagation::DealWithBoundaryCheck(BB &bb, MeStmt &meStmt) { return true; } } else if (valueRangeOfIndex->GetRangeType() == kLowerAndUpper && valueRangeOfIndex->IsAccurate() && - valueRangeOfIndex->IsConstantLowerAndUpper() && valueRangeOfbound->IsEqualZero() && - valueRangeOfIndex->GetLower().GetConstant() < 0) { + valueRangeOfIndex->IsConstantLowerAndUpper() && valueRangeOfbound->IsEqualZero() && + valueRangeOfIndex->GetLower().GetConstant() < 0) { // Error during static compilation. if (safetyCheckBoundary->HandleAssertError(meStmt)) { return true; @@ -1104,24 +1108,24 @@ bool SafetyCheck::NeedDeleteTheAssertAfterErrorOrWarn(const MeStmt &stmt, bool i switch (stmt.GetOp()) { case OP_calcassertlt: case OP_calcassertge: { - auto &newStmt = static_cast(stmt); + auto &newStmt = static_cast(stmt); GStrIdx curFuncNameIdx = func->GetMirFunc()->GetNameStrIdx(); GStrIdx stmtFuncNameIdx = GlobalTables::GetStrTable().GetStrIdxFromName(newStmt.GetFuncName().c_str()); if (curFuncNameIdx == stmtFuncNameIdx) { if (stmt.GetOp() == OP_calcassertlt) { - WARN(kLncWarn, "%s:%d warning: the pointer >= the upper bounds after calculation", - fileName, srcPosition.LineNum()); + WARN(kLncWarn, "%s:%d warning: the pointer >= the upper bounds after calculation", fileName, + srcPosition.LineNum()); } else if (stmt.GetOp() == OP_calcassertge) { - WARN(kLncWarn, "%s:%d warning: the pointer < the lower bounds after calculation", - fileName, srcPosition.LineNum()); + WARN(kLncWarn, "%s:%d warning: the pointer < the lower bounds after calculation", fileName, + srcPosition.LineNum()); } } else { if (stmt.GetOp() == OP_calcassertlt) { WARN(kLncWarn, "%s:%d warning: the pointer >= the upper bounds after calculation when inlined to %s", fileName, srcPosition.LineNum(), func->GetName().c_str()); } else if (stmt.GetOp() == OP_calcassertge) { - WARN(kLncWarn, "%s:%d warning: the pointer < the lower bounds after calculation when inlined to %s", - fileName, srcPosition.LineNum(), func->GetName().c_str()); + WARN(kLncWarn, "%s:%d warning: the pointer < the lower bounds after calculation when inlined to %s", fileName, + srcPosition.LineNum(), func->GetName().c_str()); } } return true; @@ -1129,20 +1133,20 @@ bool SafetyCheck::NeedDeleteTheAssertAfterErrorOrWarn(const MeStmt &stmt, bool i case OP_assignassertnonnull: case OP_assertnonnull: case OP_returnassertnonnull: { - auto &newStmt = static_cast(stmt); + auto &newStmt = static_cast(stmt); GStrIdx curFuncNameIdx = func->GetMirFunc()->GetNameStrIdx(); GStrIdx stmtFuncNameIdx = GlobalTables::GetStrTable().GetStrIdxFromName(newStmt.GetFuncName().c_str()); if (curFuncNameIdx == stmtFuncNameIdx) { if (isNullablePtr) { if (stmt.GetOp() == OP_assertnonnull) { - FATAL(kLncFatal, "%s:%d error: Dereference of nullable pointer in safe region", - fileName, srcPosition.LineNum()); + FATAL(kLncFatal, "%s:%d error: Dereference of nullable pointer in safe region", fileName, + srcPosition.LineNum()); } else if (stmt.GetOp() == OP_returnassertnonnull) { - FATAL(kLncFatal, "%s:%d error: %s return nonnull but got nullable pointer in safe region", - fileName, srcPosition.LineNum(), newStmt.GetFuncName().c_str()); + FATAL(kLncFatal, "%s:%d error: %s return nonnull but got nullable pointer in safe region", fileName, + srcPosition.LineNum(), newStmt.GetFuncName().c_str()); } else { - FATAL(kLncFatal, "%s:%d error: nullable pointer assignment of nonnull pointer in safe region", - fileName, srcPosition.LineNum()); + FATAL(kLncFatal, "%s:%d error: nullable pointer assignment of nonnull pointer in safe region", fileName, + srcPosition.LineNum()); } } else { if (stmt.GetOp() == OP_assertnonnull) { @@ -1157,12 +1161,12 @@ bool SafetyCheck::NeedDeleteTheAssertAfterErrorOrWarn(const MeStmt &stmt, bool i } else { if (isNullablePtr) { if (stmt.GetOp() == OP_assertnonnull) { - FATAL(kLncFatal, "%s:%d error: Dereference of nullable pointer in safe region when inlined to %s", - fileName, srcPosition.LineNum(), func->GetName().c_str()); + FATAL(kLncFatal, "%s:%d error: Dereference of nullable pointer in safe region when inlined to %s", fileName, + srcPosition.LineNum(), func->GetName().c_str()); } else if (stmt.GetOp() == OP_returnassertnonnull) { FATAL(kLncFatal, - "%s:%d error: %s return nonnull but got nullable pointer in safe region when inlined to %s", - fileName, srcPosition.LineNum(), newStmt.GetFuncName().c_str(), func->GetName().c_str()); + "%s:%d error: %s return nonnull but got nullable pointer in safe region when inlined to %s", fileName, + srcPosition.LineNum(), newStmt.GetFuncName().c_str(), func->GetName().c_str()); } else { FATAL(kLncFatal, "%s:%d error: nullable pointer assignment of nonnull pointer in safe region when inlined to %s", @@ -1170,27 +1174,29 @@ bool SafetyCheck::NeedDeleteTheAssertAfterErrorOrWarn(const MeStmt &stmt, bool i } } else { if (stmt.GetOp() == OP_assertnonnull) { - FATAL(kLncFatal, "%s:%d error: Dereference of null pointer when inlined to %s", - fileName, srcPosition.LineNum(), func->GetName().c_str()); + FATAL(kLncFatal, "%s:%d error: Dereference of null pointer when inlined to %s", fileName, + srcPosition.LineNum(), func->GetName().c_str()); } else if (stmt.GetOp() == OP_returnassertnonnull) { - FATAL(kLncFatal, "%s:%d error: %s return nonnull but got null pointer when inlined to %s", - fileName, srcPosition.LineNum(), newStmt.GetFuncName().c_str(), func->GetName().c_str()); + FATAL(kLncFatal, "%s:%d error: %s return nonnull but got null pointer when inlined to %s", fileName, + srcPosition.LineNum(), newStmt.GetFuncName().c_str(), func->GetName().c_str()); } else { - FATAL(kLncFatal, "%s:%d error: null assignment of nonnull pointer when inlined to %s", - fileName, srcPosition.LineNum(), func->GetName().c_str()); + FATAL(kLncFatal, "%s:%d error: null assignment of nonnull pointer when inlined to %s", fileName, + srcPosition.LineNum(), func->GetName().c_str()); } } } break; } case OP_callassertnonnull: { - auto &callStmt = static_cast(stmt); + auto &callStmt = static_cast(stmt); GStrIdx curFuncNameIdx = func->GetMirFunc()->GetNameStrIdx(); GStrIdx stmtFuncNameIdx = GlobalTables::GetStrTable().GetStrIdxFromName(callStmt.GetStmtFuncName().c_str()); if (curFuncNameIdx == stmtFuncNameIdx) { if (isNullablePtr) { - FATAL(kLncFatal, "%s:%d error: nullable pointer passed to %s that requires a nonnull pointer "\ - "for %s argument in safe region", fileName, srcPosition.LineNum(), callStmt.GetFuncName().c_str(), + FATAL(kLncFatal, + "%s:%d error: nullable pointer passed to %s that requires a nonnull pointer " + "for %s argument in safe region", + fileName, srcPosition.LineNum(), callStmt.GetFuncName().c_str(), GetNthStr(callStmt.GetParamIndex()).c_str()); } else { FATAL(kLncFatal, "%s:%d error: NULL passed to %s that requires a nonnull pointer for %s argument", fileName, @@ -1198,12 +1204,16 @@ bool SafetyCheck::NeedDeleteTheAssertAfterErrorOrWarn(const MeStmt &stmt, bool i } } else { if (isNullablePtr) { - FATAL(kLncFatal, "%s:%d error: nullable pointer passed to %s that requires a nonnull pointer "\ - "for %s argument in safe region when inlined to %s", fileName, srcPosition.LineNum(), - callStmt.GetFuncName().c_str(), GetNthStr(callStmt.GetParamIndex()).c_str(), func->GetName().c_str()); + FATAL(kLncFatal, + "%s:%d error: nullable pointer passed to %s that requires a nonnull pointer " + "for %s argument in safe region when inlined to %s", + fileName, srcPosition.LineNum(), callStmt.GetFuncName().c_str(), + GetNthStr(callStmt.GetParamIndex()).c_str(), func->GetName().c_str()); } else { - FATAL(kLncFatal, "%s:%d error: NULL passed to %s that requires a nonnull pointer for %s argument "\ - "when inlined to %s", fileName, srcPosition.LineNum(), callStmt.GetFuncName().c_str(), + FATAL(kLncFatal, + "%s:%d error: NULL passed to %s that requires a nonnull pointer for %s argument " + "when inlined to %s", + fileName, srcPosition.LineNum(), callStmt.GetFuncName().c_str(), GetNthStr(callStmt.GetParamIndex()).c_str(), func->GetName().c_str()); } } @@ -1213,16 +1223,16 @@ bool SafetyCheck::NeedDeleteTheAssertAfterErrorOrWarn(const MeStmt &stmt, bool i case OP_assignassertle: case OP_assertlt: case OP_assertge: { - auto &newStmt = static_cast(stmt); + auto &newStmt = static_cast(stmt); GStrIdx curFuncNameIdx = func->GetMirFunc()->GetNameStrIdx(); GStrIdx stmtFuncNameIdx = GlobalTables::GetStrTable().GetStrIdxFromName(newStmt.GetFuncName().c_str()); if (curFuncNameIdx == stmtFuncNameIdx) { if (stmt.GetOp() == OP_assertlt) { - FATAL(kLncFatal, "%s:%d error: the pointer >= the upper bounds when accessing the memory", - fileName, srcPosition.LineNum()); + FATAL(kLncFatal, "%s:%d error: the pointer >= the upper bounds when accessing the memory", fileName, + srcPosition.LineNum()); } else if (stmt.GetOp() == OP_assertge) { - FATAL(kLncFatal, "%s:%d error: the pointer < the lower bounds when accessing the memory", - fileName, srcPosition.LineNum()); + FATAL(kLncFatal, "%s:%d error: the pointer < the lower bounds when accessing the memory", fileName, + srcPosition.LineNum()); } else if (stmt.GetOp() == OP_assignassertle) { FATAL(kLncFatal, "%s:%d error: l-value boundary should not be larger than r-value boundary", fileName, srcPosition.LineNum()); @@ -1239,8 +1249,8 @@ bool SafetyCheck::NeedDeleteTheAssertAfterErrorOrWarn(const MeStmt &stmt, bool i fileName, srcPosition.LineNum(), func->GetName().c_str()); } else if (stmt.GetOp() == OP_assignassertle) { FATAL(kLncFatal, - "%s:%d error: l-value boundary should not be larger than r-value boundary when inlined to %s", - fileName, srcPosition.LineNum(), func->GetName().c_str()); + "%s:%d error: l-value boundary should not be larger than r-value boundary when inlined to %s", fileName, + srcPosition.LineNum(), func->GetName().c_str()); } else { FATAL(kLncFatal, "%s:%d error: return value's bounds does not match the function declaration for %s when inlined to %s", @@ -1259,9 +1269,11 @@ bool SafetyCheck::NeedDeleteTheAssertAfterErrorOrWarn(const MeStmt &stmt, bool i func->GetMIRModule().GetFileNameFromFileNum(srcPosition.FileNum()).c_str(), srcPosition.LineNum(), callStmt.GetFuncName().c_str(), GetNthStr(callStmt.GetParamIndex()).c_str()); } else { - FATAL(kLncFatal, "%s:%d error: the pointer's bounds does not match the function %s declaration "\ - "for the %s argument when inlined to %s", fileName, srcPosition.LineNum(), - callStmt.GetFuncName().c_str(), GetNthStr(callStmt.GetParamIndex()).c_str(), func->GetName().c_str()); + FATAL(kLncFatal, + "%s:%d error: the pointer's bounds does not match the function %s declaration " + "for the %s argument when inlined to %s", + fileName, srcPosition.LineNum(), callStmt.GetFuncName().c_str(), + GetNthStr(callStmt.GetParamIndex()).c_str(), func->GetName().c_str()); } break; } @@ -1322,8 +1334,8 @@ void ValueRangePropagation::ReplaceOpndWithConstMeExpr(const BB &bb, MeStmt &stm } // When the valuerange of expr is constant, collect it and do replace later. -void ValueRangePropagation::CollectMeExpr( - const BB &bb, MeStmt &stmt, MeExpr &meExpr, std::map> &expr2ConstantValue) { +void ValueRangePropagation::CollectMeExpr(const BB &bb, MeStmt &stmt, MeExpr &meExpr, + std::map> &expr2ConstantValue) { if (meExpr.GetMeOp() == kMeOpConst) { return; } @@ -1331,10 +1343,10 @@ void ValueRangePropagation::CollectMeExpr( if (valueRangeOfOperand != nullptr && valueRangeOfOperand->IsConstant() && valueRangeOfOperand->GetRangeType() != kNotEqual && stmt.GetOp() != OP_asm) { auto rangeType = valueRangeOfOperand->GetRangeType(); - int64 value = (rangeType == kEqual) ? valueRangeOfOperand->GetBound().GetConstant() : - valueRangeOfOperand->GetLower().GetConstant(); - PrimType pType = (rangeType == kEqual) ? valueRangeOfOperand->GetBound().GetPrimType() : - valueRangeOfOperand->GetLower().GetPrimType(); + int64 value = (rangeType == kEqual) ? valueRangeOfOperand->GetBound().GetConstant() + : valueRangeOfOperand->GetLower().GetConstant(); + PrimType pType = (rangeType == kEqual) ? valueRangeOfOperand->GetBound().GetPrimType() + : valueRangeOfOperand->GetLower().GetPrimType(); expr2ConstantValue[&meExpr] = std::make_pair(value, pType); return; } @@ -1352,9 +1364,9 @@ void ValueRangePropagation::CreateVRWithBitsSize(const BB &bb, const OpMeExpr &o if (bitsSize < 64) { auto pTypeOfOpMeExpr = opMeExpr.GetPrimType(); uint64 maxNumber = (1ULL << bitsSize) - 1; - (void)Insert2Caches(bb.GetBBId(), opMeExpr.GetExprID(), std::make_unique( - Bound(nullptr, 0, pTypeOfOpMeExpr), - Bound(maxNumber, pTypeOfOpMeExpr), kLowerAndUpper)); + (void)Insert2Caches(bb.GetBBId(), opMeExpr.GetExprID(), + std::make_unique(Bound(nullptr, 0, pTypeOfOpMeExpr), + Bound(maxNumber, pTypeOfOpMeExpr), kLowerAndUpper)); } } @@ -1362,8 +1374,10 @@ void ValueRangePropagation::DealWithOperand(const BB &bb, MeStmt &stmt, MeExpr & switch (meExpr.GetMeOp()) { case kMeOpConst: { if (static_cast(meExpr).GetConstVal()->GetKind() == kConstInt) { - (void)Insert2Caches(bb.GetBBId(), meExpr.GetExprID(), std::make_unique( - Bound(nullptr, static_cast(meExpr).GetExtIntValue(), meExpr.GetPrimType()), kEqual)); + (void)Insert2Caches( + bb.GetBBId(), meExpr.GetExprID(), + std::make_unique( + Bound(nullptr, static_cast(meExpr).GetExtIntValue(), meExpr.GetPrimType()), kEqual)); } break; } @@ -1432,13 +1446,13 @@ void ValueRangePropagation::DealWithOperand(const BB &bb, MeStmt &stmt, MeExpr & // Judge whether the truncated range is the same as the previous range. if (valueRange->IsEqualAfterCVT(valueRange->GetLower().GetPrimType(), pTypeOpnd) && valueRange->GetUpper().IsLessThanOrEqualTo(Bound(maxNumber, PTY_u64), PTY_u64)) { - (void) Insert2Caches(bb.GetBBId(), opMeExpr.GetExprID(), CopyValueRange(*valueRange)); + (void)Insert2Caches(bb.GetBBId(), opMeExpr.GetExprID(), CopyValueRange(*valueRange)); break; } } } } - [[clang::fallthrough]]; + [[clang::fallthrough]]; case OP_extractbits: { // extractbits () // Deal with the case like : @@ -1535,14 +1549,15 @@ bool ValueRangePropagation::DealWithCVT(const BB &bb, MeStmt &stmt, OpMeExpr &op } if ((fromType == PTY_u1 || fromType == PTY_u8 || fromType == PTY_u16 || fromType == PTY_u32 || fromType == PTY_a32 || - ((fromType == PTY_ref || fromType == PTY_ptr) && GetPrimTypeSize(fromType) == 4)) && + ((fromType == PTY_ref || fromType == PTY_ptr) && GetPrimTypeSize(fromType) == 4)) && GetPrimTypeBitSize(toType) > GetPrimTypeBitSize(fromType)) { auto *valueRange = FindValueRange(bb, opMeExpr); if (valueRange != nullptr) { return false; } - (void)Insert2Caches(bb.GetBBId(), opMeExpr.GetExprID(), std::make_unique( - Bound(nullptr, 0, fromType), Bound(GetMaxNumber(fromType), fromType), kLowerAndUpper)); + (void)Insert2Caches(bb.GetBBId(), opMeExpr.GetExprID(), + std::make_unique(Bound(nullptr, 0, fromType), + Bound(GetMaxNumber(fromType), fromType), kLowerAndUpper)); } return false; } @@ -1550,8 +1565,7 @@ bool ValueRangePropagation::DealWithCVT(const BB &bb, MeStmt &stmt, OpMeExpr &op // When unreachable bb has trystmt or endtry attribute, need update try and endtry bbs. void ValueRangePropagation::UpdateTryAttribute(BB &bb) { // update try end bb - if (bb.GetAttributes(kBBAttrIsTryEnd) && - (bb.GetMeStmts().empty() || (bb.GetMeStmts().front().GetOp() != OP_try))) { + if (bb.GetAttributes(kBBAttrIsTryEnd) && (bb.GetMeStmts().empty() || (bb.GetMeStmts().front().GetOp() != OP_try))) { auto *startTryBB = func.GetCfg()->GetTryBBFromEndTryBB(&bb); auto *newEndTry = func.GetCfg()->GetBBFromID(bb.GetBBId() - 1); CHECK_NULL_FATAL(newEndTry); @@ -1562,8 +1576,7 @@ void ValueRangePropagation::UpdateTryAttribute(BB &bb) { } } // update start try bb - if (!bb.GetMeStmts().empty() && bb.GetMeStmts().front().GetOp() == OP_try && - !bb.GetAttributes(kBBAttrIsTryEnd)) { + if (!bb.GetMeStmts().empty() && bb.GetMeStmts().front().GetOp() == OP_try && !bb.GetAttributes(kBBAttrIsTryEnd)) { for (auto &pair : func.GetCfg()->GetEndTryBB2TryBB()) { if (pair.second == &bb) { auto *newStartTry = func.GetCfg()->GetBBFromID(bb.GetBBId() + 1); @@ -1578,9 +1591,9 @@ void ValueRangePropagation::UpdateTryAttribute(BB &bb) { } // Insert the ost of phi opnds to their def bbs. -void ValueRangePropagation::InsertOstOfPhi2Cands( - BB &bb, size_t i, ScalarMeExpr *updateSSAExceptTheScalarExpr, - std::map> &ssaupdateCandsForCondExpr, bool setPhiIsDead) { +void ValueRangePropagation::InsertOstOfPhi2Cands(BB &bb, size_t i, ScalarMeExpr *updateSSAExceptTheScalarExpr, + std::map> &ssaupdateCandsForCondExpr, + bool setPhiIsDead) { for (auto &it : bb.GetMePhiList()) { if (setPhiIsDead) { it.second->SetIsLive(false); @@ -1613,8 +1626,8 @@ void ValueRangePropagation::PrepareForSSAUpdateWhenPredBBIsRemoved( int index = bb.GetPredIndex(pred); CHECK_FATAL(index != -1, "pred is not in preds of bb"); InsertOstOfPhi2Cands(bb, static_cast(index), updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); - auto updateSSAExceptTheOstIdx = updateSSAExceptTheScalarExpr == nullptr ? OStIdx(0) : - updateSSAExceptTheScalarExpr->GetOstIdx(); + auto updateSSAExceptTheOstIdx = + updateSSAExceptTheScalarExpr == nullptr ? OStIdx(0) : updateSSAExceptTheScalarExpr->GetOstIdx(); MeSSAUpdate::InsertDefPointsOfBBToSSACands(bb, cands, updateSSAExceptTheOstIdx); } @@ -1678,9 +1691,9 @@ int64 GetMinNumber(PrimType primType) { return std::numeric_limits::min(); case PTY_ref: case PTY_ptr: - if (GetPrimTypeSize(primType) == kFourByte) { // 32 bit + if (GetPrimTypeSize(primType) == kFourByte) { // 32 bit return std::numeric_limits::min(); - } else { // 64 bit + } else { // 64 bit CHECK_FATAL(GetPrimTypeSize(primType) == kEightByte, "must be 64 bit"); return std::numeric_limits::min(); } @@ -1713,9 +1726,9 @@ int64 GetMaxNumber(PrimType primType) { return std::numeric_limits::max(); case PTY_ref: case PTY_ptr: - if (GetPrimTypeSize(primType) == kFourByte) { // 32 bit + if (GetPrimTypeSize(primType) == kFourByte) { // 32 bit return std::numeric_limits::max(); - } else { // 64 bit + } else { // 64 bit CHECK_FATAL(GetPrimTypeSize(primType) == kEightByte, "must be 64 bit"); return std::numeric_limits::max(); } @@ -1730,15 +1743,14 @@ int64 GetMaxNumber(PrimType primType) { } // If the result of operator add or sub is overflow or underflow, return false. -bool ValueRangePropagation::AddOrSubWithConstant( - PrimType primType, Opcode op, int64 lhsConstant, int64 rhsConstant, int64 &res) const { +bool ValueRangePropagation::AddOrSubWithConstant(PrimType primType, Opcode op, int64 lhsConstant, int64 rhsConstant, + int64 &res) const { if (ConstantFold::IntegerOpIsOverflow(op, primType, lhsConstant, rhsConstant)) { return false; } if (IsPrimTypeUint64(primType)) { - res = (op == OP_add) ? - (static_cast(lhsConstant) + static_cast(rhsConstant)) : - (static_cast(lhsConstant) - static_cast(rhsConstant)); + res = (op == OP_add) ? (static_cast(lhsConstant) + static_cast(rhsConstant)) + : (static_cast(lhsConstant) - static_cast(rhsConstant)); } else { res = (op == OP_add) ? (lhsConstant + rhsConstant) : (lhsConstant - rhsConstant); } @@ -1785,8 +1797,8 @@ bool ValueRangePropagation::IsConstant(const BB &bb, MeExpr &expr, int64 &value, } // Create new valueRange when old valueRange add or sub with a valuerange. -std::unique_ptr ValueRangePropagation::AddOrSubWithValueRange( - Opcode op, ValueRange &valueRangeLeft, ValueRange &valueRangeRight) { +std::unique_ptr ValueRangePropagation::AddOrSubWithValueRange(Opcode op, ValueRange &valueRangeLeft, + ValueRange &valueRangeRight) { if (valueRangeLeft.GetRangeType() == kNotEqual || valueRangeRight.GetRangeType() == kNotEqual || valueRangeLeft.GetRangeType() == kOnlyHasLowerBound || valueRangeRight.GetRangeType() == kOnlyHasLowerBound || valueRangeLeft.GetRangeType() == kOnlyHasUpperBound || valueRangeRight.GetRangeType() == kOnlyHasUpperBound) { @@ -1816,19 +1828,19 @@ std::unique_ptr ValueRangePropagation::AddOrSubWithValueRange( int64 rhsLowerConst = valueRangeRight.GetLower().GetConstant(); int64 rhsUpperConst = valueRangeRight.GetUpper().GetConstant(); int64 res = 0; - if (!AddOrSubWithConstant(valueRangeLeft.GetLower().GetPrimType(), op, - valueRangeLeft.GetLower().GetConstant(), rhsLowerConst, res)) { + if (!AddOrSubWithConstant(valueRangeLeft.GetLower().GetPrimType(), op, valueRangeLeft.GetLower().GetConstant(), + rhsLowerConst, res)) { return nullptr; } Bound lower = Bound(valueRangeLeft.GetLower().GetVar(), res, valueRangeLeft.GetLower().GetPrimType()); res = 0; - if (!AddOrSubWithConstant(valueRangeLeft.GetLower().GetPrimType(), op, - valueRangeLeft.GetUpper().GetConstant(), rhsUpperConst, res)) { + if (!AddOrSubWithConstant(valueRangeLeft.GetLower().GetPrimType(), op, valueRangeLeft.GetUpper().GetConstant(), + rhsUpperConst, res)) { return nullptr; } Bound upper = Bound(valueRangeLeft.GetUpper().GetVar(), res, valueRangeLeft.GetUpper().GetPrimType()); return std::make_unique(lower, upper, kLowerAndUpper, - valueRangeLeft.IsAccurate() || valueRangeRight.IsAccurate()); + valueRangeLeft.IsAccurate() || valueRangeRight.IsAccurate()); } bool ValueRangePropagation::AddOrSubWithBound(Bound oldBound, Bound &resBound, int64 rhsConstant, Opcode op) { @@ -1841,8 +1853,8 @@ bool ValueRangePropagation::AddOrSubWithBound(Bound oldBound, Bound &resBound, i } // Create new valueRange when old valueRange add or sub with a constant. -std::unique_ptr ValueRangePropagation::AddOrSubWithValueRange( - Opcode op, ValueRange &valueRange, int64 rhsConstant) { +std::unique_ptr ValueRangePropagation::AddOrSubWithValueRange(Opcode op, ValueRange &valueRange, + int64 rhsConstant) { if (valueRange.GetRangeType() == kLowerAndUpper) { Bound lower; if (!AddOrSubWithBound(valueRange.GetLower(), lower, rhsConstant, op)) { @@ -1870,13 +1882,13 @@ std::unique_ptr ValueRangePropagation::AddOrSubWithValueRange( } // deal with the case like var % x, range is [1-x, x-1] -std::unique_ptr ValueRangePropagation::RemWithRhsValueRange( - const OpMeExpr &opMeExpr, int64 rhsConstant) const { +std::unique_ptr ValueRangePropagation::RemWithRhsValueRange(const OpMeExpr &opMeExpr, + int64 rhsConstant) const { int64 res = 0; int64 upperRes = 0; int64 lowerRes = 0; auto pType = opMeExpr.GetOpnd(1)->GetPrimType(); - if (pType == PTY_i64 && rhsConstant == GetMinNumber(PTY_i64)) { // var % x, if var is negative unlimited + if (pType == PTY_i64 && rhsConstant == GetMinNumber(PTY_i64)) { // var % x, if var is negative unlimited return nullptr; } if (Bound(rhsConstant, pType).IsGreaterThan(Bound(nullptr, 0, pType), pType)) { @@ -1909,7 +1921,7 @@ std::unique_ptr ValueRangePropagation::RemWithRhsValueRange( // Create new valueRange when old valueRange rem with a constant. std::unique_ptr ValueRangePropagation::RemWithValueRange(const BB &bb, const OpMeExpr &opMeExpr, - int64 rhsConstant) { + int64 rhsConstant) { auto remValueRange = RemWithRhsValueRange(opMeExpr, rhsConstant); if (remValueRange == nullptr) { return nullptr; @@ -1945,8 +1957,8 @@ std::unique_ptr ValueRangePropagation::RemWithValueRange(const BB &b } // Create valueRange when deal with OP_rem. -std::unique_ptr ValueRangePropagation::DealWithRem( - const BB &bb, const MeExpr &lhsVar, const OpMeExpr &opMeExpr) { +std::unique_ptr ValueRangePropagation::DealWithRem(const BB &bb, const MeExpr &lhsVar, + const OpMeExpr &opMeExpr) { if (!IsNeededPrimType(opMeExpr.GetPrimType())) { return nullptr; } @@ -2030,8 +2042,8 @@ void ValueRangePropagation::DealWithArrayLength(const BB &bb, MeExpr &lhs, MeExp } bool IsPrimTypeUint64(PrimType pType) { - if (pType == PTY_u64 || pType == PTY_a64 || ((pType == PTY_ref || pType == PTY_ptr) && - GetPrimTypeSize(pType) == kEightByte)) { + if (pType == PTY_u64 || pType == PTY_a64 || + ((pType == PTY_ref || pType == PTY_ptr) && GetPrimTypeSize(pType) == kEightByte)) { return true; } return false; @@ -2057,9 +2069,9 @@ int64 GetRealValue(int64 value, PrimType primType) { return static_cast(value); case PTY_ref: case PTY_ptr: - if (GetPrimTypeSize(primType) == kFourByte) { // 32 bit + if (GetPrimTypeSize(primType) == kFourByte) { // 32 bit return static_cast(value); - } else { // 64 bit + } else { // 64 bit CHECK_FATAL(GetPrimTypeSize(primType) == kEightByte, "must be 64 bit"); return static_cast(value); } @@ -2088,7 +2100,7 @@ std::unique_ptr ValueRangePropagation::CopyValueRange(ValueRange &va case kSpecialLowerForLoop: if (primType == PTY_begin) { return std::make_unique(valueRange.GetLower(), valueRange.GetUpper(), valueRange.GetRangeType(), - valueRange.IsAccurate()); + valueRange.IsAccurate()); } else { Bound lower = Bound(valueRange.GetLower().GetVar(), valueRange.GetLower().GetConstant(), primType); Bound upper = Bound(valueRange.GetUpper().GetVar(), valueRange.GetUpper().GetConstant(), primType); @@ -2154,8 +2166,8 @@ void ValueRangePropagation::DealWithAssign(BB &bb, const MeStmt &stmt) { } else if (rhs->GetMeOp() == kMeOpOp) { resVR = DealWithMeOp(bb, stmt); } else if (rhs->GetMeOp() == kMeOpConst && static_cast(rhs)->GetConstVal()->GetKind() == kConstInt) { - resVR = std::make_unique( - Bound(static_cast(rhs)->GetExtIntValue(), rhs->GetPrimType()), kEqual); + resVR = std::make_unique(Bound(static_cast(rhs)->GetExtIntValue(), rhs->GetPrimType()), + kEqual); } if (resVR != nullptr) { auto pTypeOfLHS = lhs->GetPrimType(); @@ -2163,8 +2175,7 @@ void ValueRangePropagation::DealWithAssign(BB &bb, const MeStmt &stmt) { auto primTypeOfVR = resVR->GetLower().GetPrimType(); // The rhs may be truncated when assigned to lhs, // so it is necessary to judge whether the range before and after is consistent. - if (resVR->IsEqualAfterCVT(pTypeOfLHS, pTypeOfRHS) && - resVR->IsEqualAfterCVT(pTypeOfLHS, primTypeOfVR) && + if (resVR->IsEqualAfterCVT(pTypeOfLHS, pTypeOfRHS) && resVR->IsEqualAfterCVT(pTypeOfLHS, primTypeOfVR) && resVR->IsEqualAfterCVT(pTypeOfRHS, primTypeOfVR)) { Insert2Caches(bb.GetBBId(), lhs->GetExprID(), CopyValueRange(*resVR, pTypeOfLHS)); } else { @@ -2216,8 +2227,7 @@ bool ValueRangePropagation::CanComputeLoopIndVar(const MeExpr &phiLHS, MeExpr &e // Create new value range when the loop induction var is monotonic increase. std::unique_ptr ValueRangePropagation::CreateValueRangeForMonotonicIncreaseVar( - const LoopDesc &loop, BB &exitBB, const BB &bb, OpMeExpr &opMeExpr, MeExpr &opnd1, - Bound &initBound, int64 stride) { + const LoopDesc &loop, BB &exitBB, const BB &bb, OpMeExpr &opMeExpr, MeExpr &opnd1, Bound &initBound, int64 stride) { BB *inLoopBB = nullptr; BB *outLoopBB = nullptr; if (loop.Has(*exitBB.GetSucc(0))) { @@ -2230,8 +2240,8 @@ std::unique_ptr ValueRangePropagation::CreateValueRangeForMonotonicI CHECK_FATAL(!loop.Has(*exitBB.GetSucc(0)), "must not in loop"); } int64 rightConstant = 0; - if (opMeExpr.GetOp() == OP_lt || opMeExpr.GetOp() == OP_ge || - opMeExpr.GetOp() == OP_ne || opMeExpr.GetOp() == OP_eq) { + if (opMeExpr.GetOp() == OP_lt || opMeExpr.GetOp() == OP_ge || opMeExpr.GetOp() == OP_ne || + opMeExpr.GetOp() == OP_eq) { rightConstant = -stride; } Bound upperBound; @@ -2258,8 +2268,8 @@ std::unique_ptr ValueRangePropagation::CreateValueRangeForMonotonicI auto valueRangeOfUpper = DealWithAddOrSub(bb, static_cast(opnd1)); if (valueRangeOfUpper != nullptr) { int64 res = 0; - if (AddOrSubWithConstant(opnd1.GetPrimType(), OP_add, valueRangeOfUpper->GetUpper().GetConstant(), - rightConstant, res)) { + if (AddOrSubWithConstant(opnd1.GetPrimType(), OP_add, valueRangeOfUpper->GetUpper().GetConstant(), rightConstant, + res)) { upperBound = Bound(valueRangeOfUpper->GetUpper().GetVar(), res, opnd1.GetPrimType()); } if (initBound.GetVar() == nullptr) { @@ -2277,16 +2287,15 @@ std::unique_ptr ValueRangePropagation::CreateValueRangeForMonotonicI } } if (initBound.GetVar() == nullptr) { - return std::make_unique( - initBound, Bound(&opnd1, rightConstant, initBound.GetPrimType()), kSpecialUpperForLoop); + return std::make_unique(initBound, Bound(&opnd1, rightConstant, initBound.GetPrimType()), + kSpecialUpperForLoop); } return nullptr; } // Create new value range when the loop induction var is monotonic decrease. std::unique_ptr ValueRangePropagation::CreateValueRangeForMonotonicDecreaseVar( - const LoopDesc &loop, BB &exitBB, const BB &bb, OpMeExpr &opMeExpr, MeExpr &opnd1, - Bound &initBound, int64 stride) { + const LoopDesc &loop, BB &exitBB, const BB &bb, OpMeExpr &opMeExpr, MeExpr &opnd1, Bound &initBound, int64 stride) { BB *inLoopBB = nullptr; BB *outLoopBB = nullptr; if (loop.Has(*exitBB.GetSucc(0))) { @@ -2299,8 +2308,8 @@ std::unique_ptr ValueRangePropagation::CreateValueRangeForMonotonicD CHECK_FATAL(!loop.Has(*exitBB.GetSucc(0)), "must not in loop"); } int64 rightConstant = 0; - if (opMeExpr.GetOp() == OP_le || opMeExpr.GetOp() == OP_gt || - opMeExpr.GetOp() == OP_ne || opMeExpr.GetOp() == OP_eq) { + if (opMeExpr.GetOp() == OP_le || opMeExpr.GetOp() == OP_gt || opMeExpr.GetOp() == OP_ne || + opMeExpr.GetOp() == OP_eq) { rightConstant = -stride; } Bound lowerBound; @@ -2318,12 +2327,12 @@ std::unique_ptr ValueRangePropagation::CreateValueRangeForMonotonicD } return nullptr; } - return initBound.GetVar() == nullptr ? std::make_unique(lowerBound, initBound, kLowerAndUpper) : - std::make_unique(lowerBound, initBound, kSpecialUpperForLoop); + return initBound.GetVar() == nullptr ? std::make_unique(lowerBound, initBound, kLowerAndUpper) + : std::make_unique(lowerBound, initBound, kSpecialUpperForLoop); } else { if (initBound.GetVar() == nullptr) { - return std::make_unique( - Bound(&opnd1, rightConstant, opnd1.GetPrimType()), initBound, kSpecialLowerForLoop); + return std::make_unique(Bound(&opnd1, rightConstant, opnd1.GetPrimType()), initBound, + kSpecialLowerForLoop); } } return nullptr; @@ -2356,7 +2365,7 @@ void ValueRangePropagation::TravelBBs(std::vector &reversePostOrderOfLoopBB if (unreachableBBs.find(bb) != unreachableBBs.end()) { continue; } - if (i != 0) { // The phi has already been dealed with. + if (i != 0) { // The phi has already been dealed with. DealWithPhi(*bb); } for (auto it = bb->GetMeStmts().begin(); it != bb->GetMeStmts().end(); ++it) { @@ -2445,7 +2454,7 @@ std::unique_ptr ValueRangePropagation::MergeValueRangeOfPhiOperands( } bool ValueRangePropagation::MergeVrOrInitAndBackedge(MePhiNode &mePhiNode, ValueRange &vrOfInitExpr, - ValueRange &valueRange, Bound &resBound) { + ValueRange &valueRange, Bound &resBound) { bool isOnlyHasLowerBound = vrOfInitExpr.GetRangeType() == kOnlyHasLowerBound; auto pType = mePhiNode.GetLHS()->GetPrimType(); auto upperBound = isOnlyHasLowerBound ? valueRange.GetBound() : vrOfInitExpr.GetBound(); @@ -2464,8 +2473,8 @@ bool ValueRangePropagation::MergeVrOrInitAndBackedge(MePhiNode &mePhiNode, Value } } int64 res = 0; - if (AddOrSubWithConstant(pType, isOnlyHasLowerBound ? OP_sub : OP_add, - valueRange.GetBound().GetConstant(), 1, res)) { + if (AddOrSubWithConstant(pType, isOnlyHasLowerBound ? OP_sub : OP_add, valueRange.GetBound().GetConstant(), 1, + res)) { resBound = Bound(valueRange.GetBound().GetVar(), res, pType); } else { return false; @@ -2478,8 +2487,9 @@ bool ValueRangePropagation::MergeVrOrInitAndBackedge(MePhiNode &mePhiNode, Value } // Calculate the valuerange of def-operand according to the valuerange of each rhs operand. -void ValueRangePropagation::MergeValueRangeOfPhiOperands(const LoopDesc &loop, const BB &bb, - std::vector> &valueRangeOfInitExprs, size_t indexOfInitExpr) { +void ValueRangePropagation::MergeValueRangeOfPhiOperands( + const LoopDesc &loop, const BB &bb, std::vector> &valueRangeOfInitExprs, + size_t indexOfInitExpr) { size_t index = 0; for (auto &it : bb.GetMePhiList()) { if (!it.second->GetIsLive()) { @@ -2497,8 +2507,8 @@ void ValueRangePropagation::MergeValueRangeOfPhiOperands(const LoopDesc &loop, c index++; continue; } - Bound resBound = vrOfInitExpr->GetRangeType() == kOnlyHasLowerBound ? - Bound(nullptr, GetMaxNumber(pType), pType) : Bound( nullptr, GetMinNumber(pType), pType); + Bound resBound = vrOfInitExpr->GetRangeType() == kOnlyHasLowerBound ? Bound(nullptr, GetMaxNumber(pType), pType) + : Bound(nullptr, GetMinNumber(pType), pType); bool vrCanBeComputed = true; index++; bool isAccurateBound = false; @@ -2508,16 +2518,14 @@ void ValueRangePropagation::MergeValueRangeOfPhiOperands(const LoopDesc &loop, c } auto *operand = mePhiNode->GetOpnd(i); auto *valueRange = FindValueRange(*bb.GetPred(i), *operand); - if (valueRange == nullptr || - valueRange->GetRangeType() == kOnlyHasUpperBound || - valueRange->GetRangeType() == kOnlyHasLowerBound || - vrOfInitExpr->IsEqual(valueRange) || + if (valueRange == nullptr || valueRange->GetRangeType() == kOnlyHasUpperBound || + valueRange->GetRangeType() == kOnlyHasLowerBound || vrOfInitExpr->IsEqual(valueRange) || !MergeVrOrInitAndBackedge(*mePhiNode, *vrOfInitExpr, *valueRange, resBound)) { vrCanBeComputed = false; break; } - isAccurateBound = valueRange->IsAccurate() || valueRange->GetRangeType() == kEqual || - valueRange->GetRangeType() == kNotEqual; + isAccurateBound = + valueRange->IsAccurate() || valueRange->GetRangeType() == kEqual || valueRange->GetRangeType() == kNotEqual; } if (!vrCanBeComputed) { continue; @@ -2526,9 +2534,9 @@ void ValueRangePropagation::MergeValueRangeOfPhiOperands(const LoopDesc &loop, c onlyRecordValueRangeInTempCache.push(false); bool isOnlyHasLowerBound = vrOfInitExpr->GetRangeType() == kOnlyHasLowerBound; - auto valueRangeOfPhi = isOnlyHasLowerBound ? - std::make_unique(vrOfInitExpr->GetBound(), resBound, kLowerAndUpper) : - std::make_unique(resBound, vrOfInitExpr->GetBound(), kLowerAndUpper); + auto valueRangeOfPhi = isOnlyHasLowerBound + ? std::make_unique(vrOfInitExpr->GetBound(), resBound, kLowerAndUpper) + : std::make_unique(resBound, vrOfInitExpr->GetBound(), kLowerAndUpper); if (!valueRangeOfPhi->IsConstantRange() || stride == 1) { if (loop.IsCanonicalAndOnlyHasOneExitBBLoop() && isAccurateBound) { valueRangeOfPhi->SetAccurate(true); @@ -2596,7 +2604,7 @@ bool ValueRangePropagation::Insert2Caches(BBId bbID, int32 exprID, std::unique_p // The rangeType of vrOfRHS is kEqual and the rangeType of vrOfLHS is kEqual, kNotEqual or kLowerAndUpper void ValueRangePropagation::JudgeEqual(MeExpr &expr, ValueRange &vrOfLHS, ValueRange &vrOfRHS, - std::unique_ptr &valueRangePtr) { + std::unique_ptr &valueRangePtr) { if (vrOfRHS.GetRangeType() != kEqual) { return; } @@ -2634,7 +2642,7 @@ void ValueRangePropagation::JudgeEqual(MeExpr &expr, ValueRange &vrOfLHS, ValueR } else if (vrOfLHS.GetRangeType() == kLowerAndUpper) { if (!vrOfLHS.GetLower().IsGreaterThan(vrOfLHS.GetUpper(), primType) && (vrOfLHS.GetLower().IsGreaterThan(vrOfRHS.GetBound(), primType) || - vrOfRHS.GetBound().IsGreaterThan(vrOfLHS.GetUpper(), primType))) { + vrOfRHS.GetBound().IsGreaterThan(vrOfLHS.GetUpper(), primType))) { // dealwith this case: // a = (b == c) // valueRange(b): kLowerAndUpper (1, Max) @@ -2783,8 +2791,9 @@ ValueRange *ValueRangePropagation::FindValueRange(const BB &bb, MeExpr &expr) { return nullptr; } -std::unique_ptr ValueRangePropagation::CreateInitVRForPhi(LoopDesc &loop, - const BB &bb, ScalarMeExpr &init, ScalarMeExpr &backedge, const ScalarMeExpr &lhsOfPhi) { +std::unique_ptr ValueRangePropagation::CreateInitVRForPhi(LoopDesc &loop, const BB &bb, ScalarMeExpr &init, + ScalarMeExpr &backedge, + const ScalarMeExpr &lhsOfPhi) { Bound initBound; ValueRange *valueRangeOfInit = FindValueRange(bb, init); if (valueRangeOfInit != nullptr && valueRangeOfInit->IsConstant() && valueRangeOfInit->GetRangeType() != kNotEqual) { @@ -2892,9 +2901,9 @@ void ValueRangePropagation::DealWithPhi(const BB &bb) { } if (backExprOfPhi.empty()) { valueRangeOfInitExprs.emplace_back(nullptr); - } else if (initExprsOfPhi.size() == 1 && backExprOfPhi.size() == 1) { // Create vr for initial value of phi node. - auto vrOfInitExpr = CreateInitVRForPhi( - *loop, bb, **initExprsOfPhi.begin(), **backExprOfPhi.begin(), *pair.second->GetLHS()); + } else if (initExprsOfPhi.size() == 1 && backExprOfPhi.size() == 1) { // Create vr for initial value of phi node. + auto vrOfInitExpr = + CreateInitVRForPhi(*loop, bb, **initExprsOfPhi.begin(), **backExprOfPhi.begin(), *pair.second->GetLHS()); valueRangeOfInitExprs.emplace_back(std::move(vrOfInitExpr)); } else { valueRangeOfInitExprs.emplace_back(nullptr); @@ -2950,8 +2959,7 @@ Bound ValueRangePropagation::Min(Bound leftBound, Bound rightBound) { // Judge whether the lower is in range. bool ValueRangePropagation::LowerInRange(const BB &bb, Bound lowerTemp, Bound lower, bool lowerIsZero) { - if ((lowerIsZero && lowerTemp.GetVar() == nullptr) || - (!lowerIsZero && lowerTemp.GetVar() == lower.GetVar())) { + if ((lowerIsZero && lowerTemp.GetVar() == nullptr) || (!lowerIsZero && lowerTemp.GetVar() == lower.GetVar())) { int64 lowerConstant = lowerIsZero ? 0 : lower.GetConstant(); return (lowerTemp.GetConstant() >= lowerConstant); } else { @@ -2964,8 +2972,7 @@ bool ValueRangePropagation::LowerInRange(const BB &bb, Bound lowerTemp, Bound lo return LowerInRange(bb, lowerRangeValue->GetLower(), lower, lowerIsZero); } else { Bound newLower; - if (CreateNewBoundWhenAddOrSub(OP_add, lowerRangeValue->GetBound(), - lowerTemp.GetConstant(), newLower)) { + if (CreateNewBoundWhenAddOrSub(OP_add, lowerRangeValue->GetBound(), lowerTemp.GetConstant(), newLower)) { return LowerInRange(bb, newLower, lower, lowerIsZero); } } @@ -2978,8 +2985,8 @@ bool ValueRangePropagation::LowerInRange(const BB &bb, Bound lowerTemp, Bound lo // Judge whether the upper is in range. bool ValueRangePropagation::UpperInRange(const BB &bb, Bound upperTemp, Bound upper, bool upperIsArrayLength) { if (upperTemp.GetVar() == upper.GetVar()) { - return upperIsArrayLength ? (upperTemp.GetConstant() < upper.GetConstant()) : - (upperTemp.GetConstant() <= upper.GetConstant()); + return upperIsArrayLength ? (upperTemp.GetConstant() < upper.GetConstant()) + : (upperTemp.GetConstant() <= upper.GetConstant()); } if (upperTemp.GetVar() == nullptr) { return false; @@ -2992,22 +2999,19 @@ bool ValueRangePropagation::UpperInRange(const BB &bb, Bound upperTemp, Bound up currVar = length2Def[currVar]; if (currVar == upper.GetVar()) { Bound newUpper; - if (CreateNewBoundWhenAddOrSub( - OP_add, upper, upperTemp.GetConstant(), newUpper)) { + if (CreateNewBoundWhenAddOrSub(OP_add, upper, upperTemp.GetConstant(), newUpper)) { return UpperInRange(bb, newUpper, upper, upperIsArrayLength); } else { return false; } } } - } else if (upperRangeValue->IfLowerEqualToUpper() && - upperRangeValue->GetUpper().GetVar() != upperVar) { + } else if (upperRangeValue->IfLowerEqualToUpper() && upperRangeValue->GetUpper().GetVar() != upperVar) { if (upperTemp.GetConstant() == 0) { return UpperInRange(bb, upperRangeValue->GetUpper(), upper, upperIsArrayLength); } else { Bound newUpper; - if (CreateNewBoundWhenAddOrSub(OP_add, upperRangeValue->GetBound(), - upperTemp.GetConstant(), newUpper)) { + if (CreateNewBoundWhenAddOrSub(OP_add, upperRangeValue->GetBound(), upperTemp.GetConstant(), newUpper)) { return UpperInRange(bb, newUpper, upper, upperIsArrayLength); } else { return false; @@ -3015,16 +3019,16 @@ bool ValueRangePropagation::UpperInRange(const BB &bb, Bound upperTemp, Bound up } } else if (!upperRangeValue->IfLowerEqualToUpper()) { if (length2Def.find(upperVar) != length2Def.end() && length2Def[upperVar] == upper.GetVar()) { - return upperIsArrayLength ? (upperTemp.GetConstant() < upper.GetConstant()) : - (upperTemp.GetConstant() <= upper.GetConstant()); + return upperIsArrayLength ? (upperTemp.GetConstant() < upper.GetConstant()) + : (upperTemp.GetConstant() <= upper.GetConstant()); } } return false; } // Judge whether the lower and upper are in range. -InRangeType ValueRangePropagation::InRange(const BB &bb, const ValueRange &rangeTemp, - const ValueRange &range, bool lowerIsZero) { +InRangeType ValueRangePropagation::InRange(const BB &bb, const ValueRange &rangeTemp, const ValueRange &range, + bool lowerIsZero) { bool lowerInRange = LowerInRange(bb, rangeTemp.GetLower(), range.GetLower(), lowerIsZero); Bound upperBound; if (lowerIsZero && !range.IfLowerEqualToUpper()) { @@ -3044,24 +3048,28 @@ InRangeType ValueRangePropagation::InRange(const BB &bb, const ValueRange &range } } -std::unique_ptr ValueRangePropagation::CombineTwoValueRange( - const ValueRange &leftRange, const ValueRange &rightRange, bool merge) { +std::unique_ptr ValueRangePropagation::CombineTwoValueRange(const ValueRange &leftRange, + const ValueRange &rightRange, bool merge) { if (merge) { return std::make_unique(Min(leftRange.GetLower(), rightRange.GetLower()), Max(leftRange.GetUpper(), rightRange.GetUpper()), kLowerAndUpper); } else { if (rightRange.GetRangeType() == kOnlyHasLowerBound) { - return std::make_unique(rightRange.GetLower(), Max(leftRange.GetUpper(), - Bound(GetMaxNumber(rightRange.GetUpper().GetPrimType()), rightRange.GetUpper().GetPrimType())), - kLowerAndUpper, rightRange.IsAccurate()); + return std::make_unique( + rightRange.GetLower(), + Max(leftRange.GetUpper(), + Bound(GetMaxNumber(rightRange.GetUpper().GetPrimType()), rightRange.GetUpper().GetPrimType())), + kLowerAndUpper, rightRange.IsAccurate()); } if (rightRange.GetRangeType() == kOnlyHasUpperBound) { - return std::make_unique(Min(leftRange.GetLower(), - Bound(GetMinNumber(rightRange.GetLower().GetPrimType()), rightRange.GetLower().GetPrimType())), - leftRange.GetUpper(), kLowerAndUpper, rightRange.IsAccurate()); + return std::make_unique( + Min(leftRange.GetLower(), + Bound(GetMinNumber(rightRange.GetLower().GetPrimType()), rightRange.GetLower().GetPrimType())), + leftRange.GetUpper(), kLowerAndUpper, rightRange.IsAccurate()); } return std::make_unique(Max(leftRange.GetLower(), rightRange.GetLower()), - Min(leftRange.GetUpper(), rightRange.GetUpper()), kLowerAndUpper, rightRange.IsAccurate()); + Min(leftRange.GetUpper(), rightRange.GetUpper()), kLowerAndUpper, + rightRange.IsAccurate()); } } @@ -3088,8 +3096,8 @@ void ValueRangePropagation::ChangeLoop2Goto(LoopDesc &loop, BB &bb, BB &succBB, void ValueRangePropagation::Insert2UnreachableBBs(BB &unreachableBB) { if (ValueRangePropagation::isDebug) { - LogInfo::MapleLogger() << "=====================delete bb " << unreachableBB.GetBBId() << - "========================\n"; + LogInfo::MapleLogger() << "=====================delete bb " << unreachableBB.GetBBId() + << "========================\n"; } unreachableBBs.insert(&unreachableBB); return; @@ -3104,9 +3112,20 @@ void ValueRangePropagation::AnalysisUnreachableBBOrEdge(BB &bb, BB &unreachableB UpdateProfile(*pred, bb, unreachableBB); } Insert2UnreachableBBs(unreachableBB); + // update frequency before cfg changed + int64_t removedFreq = 0; + if (func.GetCfg()->UpdateCFGFreq()) { + int idx = bb.GetSuccIndex(unreachableBB); + removedFreq = bb.GetSuccFreq()[idx]; + } bb.RemoveSucc(unreachableBB); bb.RemoveMeStmt(bb.GetLastMe()); bb.SetKind(kBBFallthru); + if (func.GetCfg()->UpdateCFGFreq()) { + bb.SetSuccFreq(0, bb.GetFrequency()); + succBB.SetFrequency(succBB.GetFrequency() + removedFreq); + unreachableBB.SetFrequency(0); + } auto *loop = loops->GetBBLoopParent(bb.GetBBId()); if (loop == nullptr) { return; @@ -3115,25 +3134,20 @@ void ValueRangePropagation::AnalysisUnreachableBBOrEdge(BB &bb, BB &unreachableB } // Judge whether the value range is in range. -bool ValueRangePropagation::BrStmtInRange(const BB &bb, const ValueRange &leftRange, - const ValueRange &rightRange, Opcode op, PrimType opndType, - bool judgeNotInRange) { +bool ValueRangePropagation::BrStmtInRange(const BB &bb, const ValueRange &leftRange, const ValueRange &rightRange, + Opcode op, PrimType opndType, bool judgeNotInRange) { Bound leftLower = leftRange.GetLower(); Bound leftUpper = leftRange.GetUpper(); Bound rightLower = rightRange.GetLower(); Bound rightUpper = rightRange.GetUpper(); RangeType leftRangeType = leftRange.GetRangeType(); RangeType rightRangeType = rightRange.GetRangeType(); - if (!IsNeededPrimType(opndType) || - leftLower.GetVar() != leftUpper.GetVar() || leftUpper.GetVar() != rightUpper.GetVar() || - rightUpper.GetVar() != rightLower.GetVar() || leftRangeType == kSpecialLowerForLoop || - leftRangeType == kSpecialUpperForLoop || - leftRange.GetRangeType() == kOnlyHasLowerBound || - leftRange.GetRangeType() == kOnlyHasUpperBound || - rightRangeType == kSpecialLowerForLoop || - rightRangeType == kSpecialUpperForLoop || - rightRange.GetRangeType() == kOnlyHasLowerBound || - rightRange.GetRangeType() == kOnlyHasUpperBound) { + if (!IsNeededPrimType(opndType) || leftLower.GetVar() != leftUpper.GetVar() || + leftUpper.GetVar() != rightUpper.GetVar() || rightUpper.GetVar() != rightLower.GetVar() || + leftRangeType == kSpecialLowerForLoop || leftRangeType == kSpecialUpperForLoop || + leftRange.GetRangeType() == kOnlyHasLowerBound || leftRange.GetRangeType() == kOnlyHasUpperBound || + rightRangeType == kSpecialLowerForLoop || rightRangeType == kSpecialUpperForLoop || + rightRange.GetRangeType() == kOnlyHasLowerBound || rightRange.GetRangeType() == kOnlyHasUpperBound) { return false; } if (judgeNotInRange) { @@ -3149,16 +3163,13 @@ bool ValueRangePropagation::BrStmtInRange(const BB &bb, const ValueRange &leftRa } } // deal the difference between i32 and u32. - if (leftLower.IsGreaterThan(leftUpper, opndType) || - rightLower.IsGreaterThan(rightUpper, opndType)) { + if (leftLower.IsGreaterThan(leftUpper, opndType) || rightLower.IsGreaterThan(rightUpper, opndType)) { return false; } if ((op == OP_eq && !judgeNotInRange) || (op == OP_ne && judgeNotInRange)) { // If the range of leftOpnd equal to the range of rightOpnd, remove the falseBranch. - return leftRangeType != kNotEqual && rightRangeType != kNotEqual && - leftLower.IsEqual(leftUpper, opndType) && - rightLower.IsEqual(rightUpper, opndType) && - leftLower.IsEqual(rightLower, opndType); + return leftRangeType != kNotEqual && rightRangeType != kNotEqual && leftLower.IsEqual(leftUpper, opndType) && + rightLower.IsEqual(rightUpper, opndType) && leftLower.IsEqual(rightLower, opndType); } else if ((op == OP_ne && !judgeNotInRange) || (op == OP_eq && judgeNotInRange)) { // If the range type of leftOpnd is kLowerAndUpper and the rightRange is not in range of it, // remove the trueBranch, such as : @@ -3166,9 +3177,9 @@ bool ValueRangePropagation::BrStmtInRange(const BB &bb, const ValueRange &leftRa // valueRange a: [1, max] // valueRange b: 0 return (leftRangeType != kNotEqual && rightRangeType != kNotEqual && - (leftLower.IsGreaterThan(rightUpper, opndType) || rightLower.IsGreaterThan(leftUpper, opndType))) || - (leftRangeType == kNotEqual && rightRangeType == kEqual && leftLower.IsEqual(rightLower, opndType)) || - (leftRangeType == kEqual && rightRangeType == kNotEqual && leftLower.IsEqual(rightLower, opndType)); + (leftLower.IsGreaterThan(rightUpper, opndType) || rightLower.IsGreaterThan(leftUpper, opndType))) || + (leftRangeType == kNotEqual && rightRangeType == kEqual && leftLower.IsEqual(rightLower, opndType)) || + (leftRangeType == kEqual && rightRangeType == kNotEqual && leftLower.IsEqual(rightLower, opndType)); } else if ((op == OP_lt && !judgeNotInRange) || (op == OP_ge && judgeNotInRange)) { return leftRangeType != kNotEqual && rightRangeType != kNotEqual && rightLower.IsGreaterThan(leftUpper, opndType); } else if ((op == OP_ge && !judgeNotInRange) || (op == OP_lt && judgeNotInRange)) { @@ -3191,42 +3202,40 @@ void ValueRangePropagation::GetTrueAndFalseBranch(Opcode op, BB &bb, BB *&trueBr } } -void ValueRangePropagation::CreateValueRangeForLeOrLt( - const MeExpr &opnd, const ValueRange *leftRange, Bound newRightUpper, Bound newRightLower, - const BB &trueBranch, const BB &falseBranch, bool isAccurate) { +void ValueRangePropagation::CreateValueRangeForLeOrLt(const MeExpr &opnd, const ValueRange *leftRange, + Bound newRightUpper, Bound newRightLower, const BB &trueBranch, + const BB &falseBranch, bool isAccurate) { CHECK_FATAL(IsEqualPrimType(newRightUpper.GetPrimType(), newRightLower.GetPrimType()), "must be equal"); if (leftRange == nullptr) { std::unique_ptr newTrueBranchRange = std::make_unique( ValueRange::MinBound(newRightUpper.GetPrimType()), newRightUpper, kLowerAndUpper, isAccurate); (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), std::move(newTrueBranchRange)); - std::unique_ptr newFalseBranchRange = std::make_unique(newRightLower, - ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); + std::unique_ptr newFalseBranchRange = std::make_unique( + newRightLower, ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), std::move(newFalseBranchRange)); } else if (leftRange->GetRangeType() == kOnlyHasLowerBound) { std::unique_ptr newRightRange = std::make_unique( ValueRange::MinBound(newRightUpper.GetPrimType()), newRightUpper, kLowerAndUpper, isAccurate); - std::unique_ptr newLeftRange = std::make_unique(leftRange->GetLower(), - ValueRange::MaxBound(leftRange->GetLower().GetPrimType()), kLowerAndUpper, isAccurate); - (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), - CombineTwoValueRange(*leftRange, *newRightRange)); - newRightRange = std::make_unique( - newRightLower, ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); + std::unique_ptr newLeftRange = std::make_unique( + leftRange->GetLower(), ValueRange::MaxBound(leftRange->GetLower().GetPrimType()), kLowerAndUpper, isAccurate); + (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), CombineTwoValueRange(*leftRange, *newRightRange)); + newRightRange = std::make_unique(newRightLower, ValueRange::MaxBound(newRightUpper.GetPrimType()), + kLowerAndUpper, isAccurate); } else if (leftRange->GetRangeType() == kOnlyHasUpperBound) { std::unique_ptr newRightRange = std::make_unique( ValueRange::MinBound(newRightUpper.GetPrimType()), newRightUpper, kLowerAndUpper, isAccurate); std::unique_ptr newLeftRange = std::make_unique( ValueRange::MinBound(newRightUpper.GetPrimType()), leftRange->GetBound(), kLowerAndUpper, isAccurate); - newRightRange = std::make_unique( - newRightLower, ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); - (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), - CombineTwoValueRange(*leftRange, *newRightRange)); + newRightRange = std::make_unique(newRightLower, ValueRange::MaxBound(newRightUpper.GetPrimType()), + kLowerAndUpper, isAccurate); + (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), CombineTwoValueRange(*leftRange, *newRightRange)); } else { std::unique_ptr newRightRange = std::make_unique( ValueRange::MinBound(newRightUpper.GetPrimType()), newRightUpper, kLowerAndUpper, isAccurate); auto resTrueBranchVR = CombineTwoValueRange(*leftRange, *newRightRange); (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), CopyValueRange(*resTrueBranchVR)); - newRightRange = std::make_unique( - newRightLower, ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); + newRightRange = std::make_unique(newRightLower, ValueRange::MaxBound(newRightUpper.GetPrimType()), + kLowerAndUpper, isAccurate); auto resFalseBranchVR = CombineTwoValueRange(*leftRange, *newRightRange); (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), CopyValueRange(*resFalseBranchVR)); // Deal with the case like: @@ -3245,55 +3254,52 @@ void ValueRangePropagation::CreateValueRangeForLeOrLt( } } -void ValueRangePropagation::CreateValueRangeForGeOrGt( - const MeExpr &opnd, const ValueRange *leftRange, Bound newRightUpper, Bound newRightLower, - const BB &trueBranch, const BB &falseBranch, bool isAccurate) { +void ValueRangePropagation::CreateValueRangeForGeOrGt(const MeExpr &opnd, const ValueRange *leftRange, + Bound newRightUpper, Bound newRightLower, const BB &trueBranch, + const BB &falseBranch, bool isAccurate) { CHECK_FATAL(IsEqualPrimType(newRightUpper.GetPrimType(), newRightLower.GetPrimType()), "must be equal"); if (leftRange == nullptr) { - std::unique_ptr newTrueBranchRange = std::make_unique(newRightLower, - ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); + std::unique_ptr newTrueBranchRange = std::make_unique( + newRightLower, ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), std::move(newTrueBranchRange)); std::unique_ptr newFalseBranchRange = std::make_unique( ValueRange::MinBound(newRightUpper.GetPrimType()), newRightUpper, kLowerAndUpper, isAccurate); (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), std::move(newFalseBranchRange)); } else if (leftRange->GetRangeType() == kOnlyHasLowerBound) { - auto newRightRange = std::make_unique( - ValueRange::MinBound(newRightUpper.GetPrimType()), newRightUpper, kLowerAndUpper, isAccurate); - (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), - CombineTwoValueRange(*leftRange, *newRightRange)); + auto newRightRange = std::make_unique(ValueRange::MinBound(newRightUpper.GetPrimType()), newRightUpper, + kLowerAndUpper, isAccurate); + (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), CombineTwoValueRange(*leftRange, *newRightRange)); } else if (leftRange->GetRangeType() == kOnlyHasUpperBound) { - std::unique_ptr newRightRange = std::make_unique(newRightLower, - ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); - (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), - CombineTwoValueRange(*leftRange, *newRightRange)); + std::unique_ptr newRightRange = std::make_unique( + newRightLower, ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); + (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), CombineTwoValueRange(*leftRange, *newRightRange)); } else { - std::unique_ptr newRightRange = std::make_unique(newRightLower, - ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); + std::unique_ptr newRightRange = std::make_unique( + newRightLower, ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), CombineTwoValueRange(*leftRange, *newRightRange)); newRightRange = std::make_unique(ValueRange::MinBound(newRightUpper.GetPrimType()), newRightUpper, - kLowerAndUpper, isAccurate); - (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), - CombineTwoValueRange(*leftRange, *newRightRange)); + kLowerAndUpper, isAccurate); + (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), CombineTwoValueRange(*leftRange, *newRightRange)); } } // Return true if the lower or upper of leftRange is equal to the bound of rightRange, like this: // leftRang: (5, constant) rightRange: (5) ==> return true; // leftRang: (constant, 5) rightRange: (5) ==> return true; -bool ValueRangePropagation::IfTheLowerOrUpperOfLeftRangeEqualToTheRightRange( - const ValueRange &leftRange, ValueRange &rightRange, bool isLower) const { - bool lowerOrUpperIsEqual = isLower ? leftRange.GetLower().GetConstant() == rightRange.GetBound().GetConstant() : - leftRange.GetUpper().GetConstant() == rightRange.GetBound().GetConstant(); +bool ValueRangePropagation::IfTheLowerOrUpperOfLeftRangeEqualToTheRightRange(const ValueRange &leftRange, + ValueRange &rightRange, + bool isLower) const { + bool lowerOrUpperIsEqual = isLower ? leftRange.GetLower().GetConstant() == rightRange.GetBound().GetConstant() + : leftRange.GetUpper().GetConstant() == rightRange.GetBound().GetConstant(); return leftRange.GetRangeType() == kLowerAndUpper && leftRange.IsConstantLowerAndUpper() && leftRange.GetLower().GetConstant() < leftRange.GetUpper().GetConstant() && lowerOrUpperIsEqual; } -void ValueRangePropagation::CreateValueRangeForNeOrEq( - const MeExpr &opnd, const ValueRange *leftRange, ValueRange &rightRange, const BB &trueBranch, - const BB &falseBranch) { +void ValueRangePropagation::CreateValueRangeForNeOrEq(const MeExpr &opnd, const ValueRange *leftRange, + ValueRange &rightRange, const BB &trueBranch, + const BB &falseBranch) { if (rightRange.GetRangeType() == kEqual) { - std::unique_ptr newTrueBranchRange = - std::make_unique(rightRange.GetBound(), kEqual); + std::unique_ptr newTrueBranchRange = std::make_unique(rightRange.GetBound(), kEqual); auto &opMeExpr = static_cast(opnd); if (opMeExpr.GetOp() == OP_zext && rightRange.IsConstant() && opMeExpr.GetOpnd(0)->GetPrimType() == GetIntegerPrimTypeBySizeAndSign(opMeExpr.GetBitsSize(), false)) { @@ -3301,8 +3307,7 @@ void ValueRangePropagation::CreateValueRangeForNeOrEq( } (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), std::move(newTrueBranchRange)); if (leftRange == nullptr) { - std::unique_ptr newFalseBranchRange = - std::make_unique(rightRange.GetBound(), kNotEqual); + std::unique_ptr newFalseBranchRange = std::make_unique(rightRange.GetBound(), kNotEqual); (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), std::move(newFalseBranchRange)); } else if (IfTheLowerOrUpperOfLeftRangeEqualToTheRightRange(*leftRange, rightRange, true)) { // Deal with this case: @@ -3329,18 +3334,15 @@ void ValueRangePropagation::CreateValueRangeForNeOrEq( (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), std::move(newFalseBranchRange)); } } else if (leftRange->GetRangeType() == kLowerAndUpper) { - std::unique_ptr newFalseBranchRange = - std::make_unique(rightRange.GetBound(), kNotEqual); + std::unique_ptr newFalseBranchRange = std::make_unique(rightRange.GetBound(), kNotEqual); (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), std::move(newFalseBranchRange)); } else if (leftRange->GetRangeType() == kOnlyHasLowerBound || leftRange->GetRangeType() == kOnlyHasUpperBound) { - std::unique_ptr newFalseBranchRange = - std::make_unique(rightRange.GetBound(), kNotEqual); + std::unique_ptr newFalseBranchRange = std::make_unique(rightRange.GetBound(), kNotEqual); (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), std::move(newFalseBranchRange)); } } else if (rightRange.GetRangeType() == kNotEqual) { if (leftRange == nullptr) { - std::unique_ptr newTrueBranchRange = - std::make_unique(rightRange.GetBound(), kNotEqual); + std::unique_ptr newTrueBranchRange = std::make_unique(rightRange.GetBound(), kNotEqual); (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), std::move(newTrueBranchRange)); } else if (IfTheLowerOrUpperOfLeftRangeEqualToTheRightRange(*leftRange, rightRange, true)) { Bound newLower; @@ -3357,8 +3359,7 @@ void ValueRangePropagation::CreateValueRangeForNeOrEq( (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), std::move(newTrueBranchRange)); } } else if (leftRange->GetRangeType() == kOnlyHasLowerBound || leftRange->GetRangeType() == kOnlyHasUpperBound) { - std::unique_ptr newTrueBranchRange = - std::make_unique(rightRange.GetBound(), kNotEqual); + std::unique_ptr newTrueBranchRange = std::make_unique(rightRange.GetBound(), kNotEqual); (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), std::move(newTrueBranchRange)); } } @@ -3368,8 +3369,8 @@ void ValueRangePropagation::CreateValueRangeForNeOrEq( // if a == 5 // If the valueRange of a is valuerange(5, kEqual), delete the false branch. // Else if the valeuRange of a is valueRange(5, kNotEqual), delete the ture branch. -bool ValueRangePropagation::ConditionBBCanBeDeletedAfterOPNeOrEq( - BB &bb, ValueRange &leftRange, ValueRange &rightRange, BB &falseBranch, BB &trueBranch) { +bool ValueRangePropagation::ConditionBBCanBeDeletedAfterOPNeOrEq(BB &bb, ValueRange &leftRange, ValueRange &rightRange, + BB &falseBranch, BB &trueBranch) { if ((leftRange.GetRangeType() == kEqual && rightRange.GetRangeType() == kEqual) && leftRange.GetBound().GetVar() == rightRange.GetBound().GetVar()) { if (leftRange.GetBound().GetConstant() == rightRange.GetBound().GetConstant()) { @@ -3407,7 +3408,7 @@ void ValueRangePropagation::UpdateProfile(BB &pred, BB &bb, const BB &targetBB) } auto *condGotoStmt = static_cast(bb.GetLastMe()); if (condGotoStmt->GetBranchProb() != kProbLikely && condGotoStmt->GetBranchProb() != kProbUnlikely) { - return; // need not update profile + return; // need not update profile } int32 targetBranchProb = 0; if (&targetBB == bb.GetSucc(0)) { @@ -3417,7 +3418,7 @@ void ValueRangePropagation::UpdateProfile(BB &pred, BB &bb, const BB &targetBB) targetBranchProb = condGotoStmt->GetBranchProb(); } BB *predCondGoto = &pred; - BB *succBB = &bb; // succ of predCondGoto to targetBB + BB *succBB = &bb; // succ of predCondGoto to targetBB while (predCondGoto != nullptr) { if (predCondGoto->GetKind() == kBBCondGoto) { break; @@ -3458,9 +3459,9 @@ void ValueRangePropagation::UpdateProfile(BB &pred, BB &bb, const BB &targetBB) // \ / \ ----> | | // \ / \ | | // false true false true -void ValueRangePropagation::RemoveUnreachableBB( - BB &condGotoBB, BB &trueBranch, ScalarMeExpr *updateSSAExceptTheScalarExpr, - std::map> &ssaupdateCandsForCondExpr) { +void ValueRangePropagation::RemoveUnreachableBB(BB &condGotoBB, BB &trueBranch, + ScalarMeExpr *updateSSAExceptTheScalarExpr, + std::map> &ssaupdateCandsForCondExpr) { CHECK_FATAL(condGotoBB.GetSucc().size() == kNumOperands, "must have 2 succ"); auto *succ0 = condGotoBB.GetSucc(0); auto *succ1 = condGotoBB.GetSucc(1); @@ -3472,6 +3473,12 @@ void ValueRangePropagation::RemoveUnreachableBB( UpdateProfile(*condGotoBB.GetPred(0), condGotoBB, trueBranch); } condGotoBB.SetKind(kBBFallthru); + // update frequency before cfg changed + if (func.GetCfg()->UpdateCFGFreq()) { + int64_t removedFreq = condGotoBB.GetSuccFreq()[1]; + condGotoBB.SetSuccFreq(0, condGotoBB.GetFrequency()); + succ0->SetFrequency(succ0->GetFrequency() + removedFreq); + } condGotoBB.RemoveSucc(*succ1); DeleteThePhiNodeWhichOnlyHasOneOpnd(*succ1, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); condGotoBB.RemoveMeStmt(condGotoBB.GetLastMe()); @@ -3484,7 +3491,16 @@ void ValueRangePropagation::RemoveUnreachableBB( UpdateProfile(*condGotoBB.GetPred(0), condGotoBB, trueBranch); } condGotoBB.SetKind(kBBFallthru); + int64_t removedFreq = 0; + // update frequency before cfg changed + if (func.GetCfg()->UpdateCFGFreq()) { + removedFreq = condGotoBB.GetSuccFreq()[0]; + } condGotoBB.RemoveSucc(*succ0); + if (func.GetCfg()->UpdateCFGFreq()) { + condGotoBB.SetSuccFreq(0, condGotoBB.GetFrequency()); + succ1->SetFrequency(succ1->GetFrequency() + removedFreq); + } DeleteThePhiNodeWhichOnlyHasOneOpnd(*succ0, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); condGotoBB.RemoveMeStmt(condGotoBB.GetLastMe()); } @@ -3542,7 +3558,7 @@ void ValueRangePropagation::CreateLabelForTargetBB(BB &pred, BB &newBB) { case kBBIgoto: CHECK_FATAL(false, "can not be here"); case kBBCondGoto: { - auto *condGotoStmt = static_cast(pred.GetLastMe()); + auto *condGotoStmt = static_cast(pred.GetLastMe()); if (&newBB == pred.GetSucc().at(1)) { condGotoStmt->SetOffset(func.GetOrCreateBBLabel(newBB)); } @@ -3640,10 +3656,22 @@ bool ValueRangePropagation::ChangeTheSuccOfPred2TrueBranch( if (exitCopyFallthru != nullptr) { PrepareForSSAUpdateWhenPredBBIsRemoved(pred, bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); size_t index = FindBBInSuccs(pred, bb); + int64_t edgeFreq = 0; + if (func.GetCfg()->UpdateCFGFreq()) { + edgeFreq = pred.GetSuccFreq()[index]; + } pred.RemoveSucc(bb); DeleteThePhiNodeWhichOnlyHasOneOpnd(bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); pred.AddSucc(*exitCopyFallthru, index); CreateLabelForTargetBB(pred, *exitCopyFallthru); + if (func.GetCfg()->UpdateCFGFreq()) { + exitCopyFallthru->SetFrequency(exitCopyFallthru->GetFrequency() + edgeFreq); + pred.AddSuccFreq(edgeFreq, index); + // update bb frequency + ASSERT(bb.GetFrequency() >= edgeFreq, "sanity check"); + bb.SetFrequency(bb.GetFrequency() - edgeFreq); + bb.UpdateEdgeFreqs(); + } return true; } if (CodeSizeIsOverflowOrTheOpOfStmtIsNotSupported(bb)) { @@ -3665,20 +3693,33 @@ bool ValueRangePropagation::ChangeTheSuccOfPred2TrueBranch( predOfCurrBB = currBB; currBB = currBB->GetSucc(0); CopyMeStmts(*currBB, *mergeAllFallthruBBs); - PrepareForSSAUpdateWhenPredBBIsRemoved( - *predOfCurrBB, *currBB, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); + PrepareForSSAUpdateWhenPredBBIsRemoved(*predOfCurrBB, *currBB, updateSSAExceptTheScalarExpr, + ssaupdateCandsForCondExpr); } if (predOfCurrBB != nullptr) { - PrepareForSSAUpdateWhenPredBBIsRemoved( - *predOfCurrBB, *currBB, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); + PrepareForSSAUpdateWhenPredBBIsRemoved(*predOfCurrBB, *currBB, updateSSAExceptTheScalarExpr, + ssaupdateCandsForCondExpr); } CHECK_FATAL(currBB->GetKind() == kBBCondGoto, "must be condgoto bb"); auto *gotoMeStmt = irMap.New(func.GetOrCreateBBLabel(trueBranch)); mergeAllFallthruBBs->AddMeStmtLast(gotoMeStmt); PrepareForSSAUpdateWhenPredBBIsRemoved(pred, bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); size_t index = FindBBInSuccs(pred, bb); + int64_t edgeFreq = 0; + if (func.GetCfg()->UpdateCFGFreq()) { + edgeFreq = pred.GetSuccFreq()[index]; + } pred.RemoveSucc(bb); pred.AddSucc(*mergeAllFallthruBBs, index); + if (func.GetCfg()->UpdateCFGFreq()) { + mergeAllFallthruBBs->SetFrequency(edgeFreq); + mergeAllFallthruBBs->PushBackSuccFreq(edgeFreq); + pred.AddSuccFreq(edgeFreq, index); + // update bb frequency + ASSERT(bb.GetFrequency() >= edgeFreq, "sanity check"); + bb.SetFrequency(bb.GetFrequency() - edgeFreq); + bb.UpdateEdgeFreqs(); + } mergeAllFallthruBBs->AddSucc(trueBranch); DeleteThePhiNodeWhichOnlyHasOneOpnd(bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); CreateLabelForTargetBB(pred, *mergeAllFallthruBBs); @@ -3708,8 +3749,8 @@ bool ValueRangePropagation::CopyFallthruBBAndRemoveUnreachableEdge( do { tmpPred = tmpPred->GetSucc(0); if (GetRealPredSize(*tmpPred) > 1) { - return ChangeTheSuccOfPred2TrueBranch( - pred, bb, trueBranch, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); + return ChangeTheSuccOfPred2TrueBranch(pred, bb, trueBranch, updateSSAExceptTheScalarExpr, + ssaupdateCandsForCondExpr); } } while (tmpPred->GetKind() != kBBCondGoto); if (GetRealPredSize(bb) != 1) { @@ -3735,27 +3776,56 @@ bool ValueRangePropagation::CopyFallthruBBAndRemoveUnreachableEdge( // true false true false true false // case1: the number of branches reaching to condBB > 1 // case2: the number of branches reaching to condBB == 1 -bool ValueRangePropagation::RemoveTheEdgeOfPredBB( - BB &pred, BB &bb, BB &trueBranch, ScalarMeExpr *updateSSAExceptTheScalarExpr, - std::map> &ssaupdateCandsForCondExpr) { +bool ValueRangePropagation::RemoveTheEdgeOfPredBB(BB &pred, BB &bb, BB &trueBranch, + ScalarMeExpr *updateSSAExceptTheScalarExpr, + std::map> &ssaupdateCandsForCondExpr) { CHECK_FATAL(bb.GetKind() == kBBCondGoto, "must be condgoto bb"); if (GetRealPredSize(bb) >= kNumOperands) { if (OnlyHaveCondGotoStmt(bb)) { PrepareForSSAUpdateWhenPredBBIsRemoved(pred, bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); size_t index = FindBBInSuccs(pred, bb); + int64_t edgeFreq = 0; + if (func.GetCfg()->UpdateCFGFreq()) { + edgeFreq = pred.GetSuccFreq()[index]; + ASSERT(bb.GetFrequency() >= edgeFreq, "sanity check"); + } pred.RemoveSucc(bb); DeleteThePhiNodeWhichOnlyHasOneOpnd(bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); pred.AddSucc(trueBranch, index); CreateLabelForTargetBB(pred, trueBranch); + if (func.GetCfg()->UpdateCFGFreq()) { + bb.SetFrequency(bb.GetFrequency() - edgeFreq); + size_t trueBranchIdx = bb.GetSuccIndex(trueBranch); + int64_t updatedtrueFreq = bb.GetSuccFreq()[trueBranchIdx] - edgeFreq; + // transform may not be consistent with frequency value + updatedtrueFreq = updatedtrueFreq > 0 ? updatedtrueFreq : 0; + bb.SetSuccFreq(trueBranchIdx, updatedtrueFreq); + pred.AddSuccFreq(edgeFreq, index); + } } else { auto *exitCopyFallthru = GetNewCopyFallthruBB(trueBranch, bb); if (exitCopyFallthru != nullptr) { PrepareForSSAUpdateWhenPredBBIsRemoved(pred, bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); size_t index = FindBBInSuccs(pred, bb); + int64_t edgeFreq = 0; + if (func.GetCfg()->UpdateCFGFreq()) { + edgeFreq = pred.GetSuccFreq()[index]; + ASSERT(bb.GetFrequency() >= edgeFreq, "sanity check"); + } pred.RemoveSucc(bb); DeleteThePhiNodeWhichOnlyHasOneOpnd(bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); pred.AddSucc(*exitCopyFallthru, index); CreateLabelForTargetBB(pred, *exitCopyFallthru); + if (func.GetCfg()->UpdateCFGFreq()) { + bb.SetFrequency(bb.GetFrequency() - edgeFreq); + exitCopyFallthru->SetFrequency(edgeFreq); + exitCopyFallthru->PushBackSuccFreq(edgeFreq); + size_t trueBranchIdx = bb.GetSuccIndex(trueBranch); + int64_t updatedtrueFreq = bb.GetSuccFreq()[trueBranchIdx] - edgeFreq; + ASSERT(updatedtrueFreq >= 0, "sanity check"); + bb.SetSuccFreq(trueBranchIdx, updatedtrueFreq); + pred.AddSuccFreq(edgeFreq, index); + } return true; } auto *newBB = CreateNewGotoBBWithoutCondGotoStmt(bb); @@ -3769,9 +3839,21 @@ bool ValueRangePropagation::RemoveTheEdgeOfPredBB( newBB->AddMeStmtLast(gotoMeStmt); PrepareForSSAUpdateWhenPredBBIsRemoved(pred, bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); size_t index = FindBBInSuccs(pred, bb); + int64_t edgeFreq = 0; + if (func.GetCfg()->UpdateCFGFreq()) { + edgeFreq = pred.GetSuccFreq()[index]; + ASSERT(bb.GetFrequency() >= edgeFreq, "sanity check"); + } pred.RemoveSucc(bb); pred.AddSucc(*newBB, index); newBB->AddSucc(trueBranch); + if (func.GetCfg()->UpdateCFGFreq()) { + bb.SetFrequency(bb.GetFrequency() - edgeFreq); + bb.UpdateEdgeFreqs(); + newBB->SetFrequency(edgeFreq); + newBB->PushBackSuccFreq(edgeFreq); + pred.AddSuccFreq(edgeFreq, index); + } DeleteThePhiNodeWhichOnlyHasOneOpnd(bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); (void)func.GetOrCreateBBLabel(trueBranch); CreateLabelForTargetBB(pred, *newBB); @@ -3784,15 +3866,15 @@ bool ValueRangePropagation::RemoveTheEdgeOfPredBB( } // tmpPred, tmpBB, reachableBB -bool ValueRangePropagation::RemoveUnreachableEdge( - BB &pred, BB &bb, BB &trueBranch, ScalarMeExpr *updateSSAExceptTheScalarExpr, - std::map> &ssaupdateCandsForCondExpr) { +bool ValueRangePropagation::RemoveUnreachableEdge(BB &pred, BB &bb, BB &trueBranch, + ScalarMeExpr *updateSSAExceptTheScalarExpr, + std::map> &ssaupdateCandsForCondExpr) { if (onlyPropVR) { return false; } if (bb.GetKind() == kBBFallthru || bb.GetKind() == kBBGoto) { - if (!CopyFallthruBBAndRemoveUnreachableEdge( - pred, bb, trueBranch, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr)) { + if (!CopyFallthruBBAndRemoveUnreachableEdge(pred, bb, trueBranch, updateSSAExceptTheScalarExpr, + ssaupdateCandsForCondExpr)) { return false; } } else { @@ -3801,8 +3883,8 @@ bool ValueRangePropagation::RemoveUnreachableEdge( } } if (ValueRangePropagation::isDebug) { - LogInfo::MapleLogger() << "===========delete edge " << pred.GetBBId() << " " << bb.GetBBId() << " " << - trueBranch.GetBBId() << "===========\n"; + LogInfo::MapleLogger() << "===========delete edge " << pred.GetBBId() << " " << bb.GetBBId() << " " + << trueBranch.GetBBId() << "===========\n"; } if (trueBranch.GetPred().size() > 1) { (void)func.GetOrCreateBBLabel(trueBranch); @@ -3812,14 +3894,16 @@ bool ValueRangePropagation::RemoveUnreachableEdge( } bool ValueRangePropagation::ConditionEdgeCanBeDeleted(BB &pred, BB &bb, const ValueRange *leftRange, - const ValueRange *rightRange, BB &falseBranch, BB &trueBranch, PrimType opndType, Opcode op, - ScalarMeExpr *updateSSAExceptTheScalarExpr, std::map> &ssaupdateCandsForCondExpr) { + const ValueRange *rightRange, BB &falseBranch, BB &trueBranch, + PrimType opndType, Opcode op, + ScalarMeExpr *updateSSAExceptTheScalarExpr, + std::map> &ssaupdateCandsForCondExpr) { if (leftRange == nullptr || rightRange == nullptr) { return false; } if (ValueRangePropagation::isDebug) { - LogInfo::MapleLogger() << "try to delete edge " << pred.GetBBId() << " " << bb.GetBBId() << " " << - trueBranch.GetBBId() << "\n"; + LogInfo::MapleLogger() << "try to delete edge " << pred.GetBBId() << " " << bb.GetBBId() << " " + << trueBranch.GetBBId() << "\n"; } /* Find the first bb with more than one pred */ auto *tmpPred = &pred; @@ -3833,12 +3917,11 @@ bool ValueRangePropagation::ConditionEdgeCanBeDeleted(BB &pred, BB &bb, const Va // opnd, tmpPred, tmpBB, reachableBB // remove falseBranch UpdateProfile(*tmpPred, *tmpBB, trueBranch); - return RemoveUnreachableEdge( - *tmpPred, *tmpBB, trueBranch, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); + return RemoveUnreachableEdge(*tmpPred, *tmpBB, trueBranch, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); } else if (BrStmtInRange(bb, *leftRange, *rightRange, antiOp, opndType)) { UpdateProfile(*tmpPred, *tmpBB, falseBranch); - return RemoveUnreachableEdge( - *tmpPred, *tmpBB, falseBranch, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); + return RemoveUnreachableEdge(*tmpPred, *tmpBB, falseBranch, updateSSAExceptTheScalarExpr, + ssaupdateCandsForCondExpr); } return false; } @@ -3863,8 +3946,9 @@ std::unique_ptr ValueRangePropagation::AntiValueRange(ValueRange &va return nullptr; } RangeType newType = (oldType == kEqual) ? kNotEqual : kEqual; - return std::make_unique(Bound(valueRange.GetBound().GetVar(), valueRange.GetBound().GetConstant(), - valueRange.GetBound().GetPrimType()), newType); + return std::make_unique( + Bound(valueRange.GetBound().GetVar(), valueRange.GetBound().GetConstant(), valueRange.GetBound().GetPrimType()), + newType); } void ValueRangePropagation::DeleteUnreachableBBs(BB &curBB, BB &falseBranch, BB &trueBranch) { @@ -3888,8 +3972,9 @@ void ValueRangePropagation::DeleteUnreachableBBs(BB &curBB, BB &falseBranch, BB } } -void ValueRangePropagation::PropValueRangeFromCondGotoToTrueAndFalseBranch( - const MeExpr &opnd0, ValueRange &rightRange, const BB &falseBranch, const BB &trueBranch) { +void ValueRangePropagation::PropValueRangeFromCondGotoToTrueAndFalseBranch(const MeExpr &opnd0, ValueRange &rightRange, + const BB &falseBranch, + const BB &trueBranch) { std::unique_ptr trueBranchValueRange; std::unique_ptr falseBranchValueRange; trueBranchValueRange = CopyValueRange(rightRange); @@ -3903,8 +3988,8 @@ void ValueRangePropagation::PropValueRangeFromCondGotoToTrueAndFalseBranch( // predOpnd: a, rhs of currOpnd in this bb // phiOpnds: (b, c), phi rhs of opnd in this bb // predOpnd or phiOpnds is uesd to find the valuerange in the pred of bb -void ValueRangePropagation::ReplaceOpndByDef(const BB &bb, MeExpr &currOpnd, MeExpr *&predOpnd, - MePhiNode *&phi, bool &thePhiIsInBB) { +void ValueRangePropagation::ReplaceOpndByDef(const BB &bb, MeExpr &currOpnd, MeExpr *&predOpnd, MePhiNode *&phi, + bool &thePhiIsInBB) { /* If currOpnd is not defined in bb, set opnd to currOpnd */ predOpnd = &currOpnd; /* find the rhs of opnd */ @@ -4009,9 +4094,10 @@ bool ValueRangePropagation::TowCompareOperandsAreInSameIterOfLoop(const MeExpr & return true; } -bool ValueRangePropagation::AnalysisValueRangeInPredsOfCondGotoBB( - BB &bb, MeExpr *opnd0, MeExpr &currOpnd, ValueRange *rightRange, - BB &falseBranch, BB &trueBranch, PrimType opndType, Opcode op, BB &condGoto) { +bool ValueRangePropagation::AnalysisValueRangeInPredsOfCondGotoBB(BB &bb, MeExpr *opnd0, MeExpr &currOpnd, + ValueRange *rightRange, BB &falseBranch, + BB &trueBranch, PrimType opndType, Opcode op, + BB &condGoto) { bool opt = false; /* Records the currOpnd of pred */ MeExpr *predOpnd = nullptr; @@ -4139,7 +4225,7 @@ bool ValueRangePropagation::AnalysisValueRangeInPredsOfCondGotoBB( } } if (ConditionEdgeCanBeDeleted(*pred, bb, valueRangeInPred, rightRange, falseBranch, trueBranch, opndType, op, - updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr)) { + updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr)) { if (updateSSAExceptTheScalarExpr != nullptr && phi != nullptr) { if (updateSSAExceptTheScalarExpr->GetDefBy() == kDefByStmt) { // PredOpnd is only used by condGoto stmt and phi, if the condGoto stmt can be deleted, need not update ssa @@ -4157,11 +4243,11 @@ bool ValueRangePropagation::AnalysisValueRangeInPredsOfCondGotoBB( opt = true; } else { /* avoid infinite loop, pred->GetKind() maybe kBBUnknown */ - if ((pred->GetKind() == kBBFallthru || pred->GetKind() == kBBGoto) && - pred->GetBBId() != falseBranch.GetBBId() && pred->GetBBId() != trueBranch.GetBBId() && - (opnd0 == nullptr || TowCompareOperandsAreInSameIterOfLoop(currOpnd, *opnd0))) { - opt |= AnalysisValueRangeInPredsOfCondGotoBB( - *pred, opnd0, *predOpnd, rightRange, falseBranch, trueBranch, opndType, op, condGoto); + if ((pred->GetKind() == kBBFallthru || pred->GetKind() == kBBGoto) && pred->GetBBId() != falseBranch.GetBBId() && + pred->GetBBId() != trueBranch.GetBBId() && + (opnd0 == nullptr || TowCompareOperandsAreInSameIterOfLoop(currOpnd, *opnd0))) { + opt |= AnalysisValueRangeInPredsOfCondGotoBB(*pred, opnd0, *predOpnd, rightRange, falseBranch, trueBranch, + opndType, op, condGoto); } } if (bb.GetPred().size() == predSize) { @@ -4201,8 +4287,8 @@ bool ValueRangePropagation::AnalysisValueRangeInPredsOfCondGotoBB( // ==> // if mx12 void ValueRangePropagation::ReplaceUsePoints(MePhiNode *phi) { - if (phi == nullptr || phi->GetDefBB() == nullptr || - phi->GetDefBB()->GetMePhiList().empty() || phi->GetOpnds().empty()) { + if (phi == nullptr || phi->GetDefBB() == nullptr || phi->GetDefBB()->GetMePhiList().empty() || + phi->GetOpnds().empty()) { return; } auto *opnd = phi->GetOpnd(0); @@ -4259,8 +4345,8 @@ Opcode ValueRangePropagation::GetOpAfterSwapThePositionsOfTwoOperands(Opcode op) } } -bool ValueRangePropagation::ConditionEdgeCanBeDeleted(BB &bb, MeExpr &opnd0, ValueRange *rightRange, - PrimType opndType, Opcode op) { +bool ValueRangePropagation::ConditionEdgeCanBeDeleted(BB &bb, MeExpr &opnd0, ValueRange *rightRange, PrimType opndType, + Opcode op) { if (onlyPropVR) { return false; } @@ -4280,8 +4366,8 @@ bool ValueRangePropagation::ConditionEdgeCanBeDeleted(BB &bb, MeExpr &opnd0, Val BB *trueBranch = nullptr; BB *falseBranch = nullptr; GetTrueAndFalseBranch(static_cast(bb.GetLastMe())->GetOp(), bb, trueBranch, falseBranch); - bool opt = AnalysisValueRangeInPredsOfCondGotoBB( - bb, nullptr, *currOpnd, rightRange, *falseBranch, *trueBranch, opndType, op, bb); + bool opt = AnalysisValueRangeInPredsOfCondGotoBB(bb, nullptr, *currOpnd, rightRange, *falseBranch, *trueBranch, + opndType, op, bb); if (!opt && bb.GetKind() == kBBCondGoto && static_cast(bb.GetLastMe())->GetOpnd()->GetNumOpnds() == kNumOperands) { // Swap the positions of two operands like : @@ -4296,8 +4382,8 @@ bool ValueRangePropagation::ConditionEdgeCanBeDeleted(BB &bb, MeExpr &opnd0, Val // opnd[1] = CONST 0 mx1 auto *valueRangeOfOpnd0 = FindValueRange(bb, opnd0); - opt = AnalysisValueRangeInPredsOfCondGotoBB(bb, currOpnd, *opnd1, valueRangeOfOpnd0, *falseBranch, - *trueBranch, opndType, GetOpAfterSwapThePositionsOfTwoOperands(op), bb); + opt = AnalysisValueRangeInPredsOfCondGotoBB(bb, currOpnd, *opnd1, valueRangeOfOpnd0, *falseBranch, *trueBranch, + opndType, GetOpAfterSwapThePositionsOfTwoOperands(op), bb); } bool canDeleteBB = false; for (size_t i = 0; i < bb.GetPred().size(); ++i) { @@ -4332,7 +4418,8 @@ Opcode ValueRangePropagation::GetTheOppositeOp(Opcode op) const { } void ValueRangePropagation::CreateValueRangeForCondGoto(const MeExpr &opnd, Opcode op, ValueRange *leftRange, - ValueRange &rightRange, const BB &trueBranch, const BB &falseBranch) { + ValueRange &rightRange, const BB &trueBranch, + const BB &falseBranch) { auto newRightUpper = rightRange.GetUpper(); auto newRightLower = rightRange.GetLower(); CHECK_FATAL(IsEqualPrimType(newRightUpper.GetPrimType(), newRightLower.GetPrimType()), "must be equal"); @@ -4360,23 +4447,21 @@ void ValueRangePropagation::CreateValueRangeForCondGoto(const MeExpr &opnd, Opco bool isAccurate = dealWithPhi && (rightRange.GetRangeType() == kEqual || rightRange.IsAccurate()); if (op == OP_lt || op == OP_le) { if (leftRange != nullptr && leftRange->GetRangeType() == kNotEqual) { - CreateValueRangeForLeOrLt( - opnd, nullptr, newRightUpper, newRightLower, trueBranch, falseBranch, isAccurate); + CreateValueRangeForLeOrLt(opnd, nullptr, newRightUpper, newRightLower, trueBranch, falseBranch, isAccurate); } else { CreateValueRangeForLeOrLt(opnd, leftRange, newRightUpper, newRightLower, trueBranch, falseBranch, isAccurate); } } else if (op == OP_gt || op == OP_ge) { if (leftRange != nullptr && leftRange->GetRangeType() == kNotEqual) { - CreateValueRangeForGeOrGt( - opnd, nullptr, newRightUpper, newRightLower, trueBranch, falseBranch, isAccurate); + CreateValueRangeForGeOrGt(opnd, nullptr, newRightUpper, newRightLower, trueBranch, falseBranch, isAccurate); } else { CreateValueRangeForGeOrGt(opnd, leftRange, newRightUpper, newRightLower, trueBranch, falseBranch, isAccurate); } } } -void ValueRangePropagation::DealWithCondGoto( - BB &bb, Opcode op, ValueRange *leftRange, ValueRange &rightRange, const CondGotoMeStmt &brMeStmt) { +void ValueRangePropagation::DealWithCondGoto(BB &bb, Opcode op, ValueRange *leftRange, ValueRange &rightRange, + const CondGotoMeStmt &brMeStmt) { MeExpr *opnd0 = nullptr; PrimType primType; if (IsCompareHasReverseOp(brMeStmt.GetOpnd()->GetOp())) { @@ -4410,12 +4495,13 @@ void ValueRangePropagation::DealWithCondGoto( } bool ValueRangePropagation::GetValueRangeOfCondGotoOpnd(const BB &bb, OpMeExpr &opMeExpr, MeExpr &opnd, - ValueRange *&valueRange, std::unique_ptr &rightRangePtr) { + ValueRange *&valueRange, + std::unique_ptr &rightRangePtr) { valueRange = FindValueRange(bb, opnd); if (valueRange == nullptr) { if (opnd.GetMeOp() == kMeOpConst && static_cast(opnd).GetConstVal()->GetKind() == kConstInt) { - rightRangePtr = std::make_unique(Bound(static_cast(opnd).GetExtIntValue(), - opnd.GetPrimType()), kEqual); + rightRangePtr = std::make_unique( + Bound(static_cast(opnd).GetExtIntValue(), opnd.GetPrimType()), kEqual); valueRange = rightRangePtr.get(); if (!Insert2Caches(bb.GetBBId(), opnd.GetExprID(), std::move(rightRangePtr))) { valueRange = nullptr; @@ -4454,8 +4540,8 @@ bool ValueRangePropagation::GetValueRangeOfCondGotoOpnd(const BB &bb, OpMeExpr & valueRange = rightRangePtr.get(); (void)Insert2Caches(bb.GetBBId(), opnd.GetExprID(), std::move(rightRangePtr)); } else if ((opnd.GetOp() == OP_ne && lhsBound.IsEqual(rhsBound, rhsPrimType) && lhsRangeType == kEqual) || - (opnd.GetOp() == OP_eq && !lhsBound.IsEqual(rhsBound, rhsPrimType) && lhsRangeType == kEqual) || - (opnd.GetOp() == OP_eq && lhsBound.IsEqual(rhsBound, rhsPrimType) && lhsRangeType == kNotEqual)) { + (opnd.GetOp() == OP_eq && !lhsBound.IsEqual(rhsBound, rhsPrimType) && lhsRangeType == kEqual) || + (opnd.GetOp() == OP_eq && lhsBound.IsEqual(rhsBound, rhsPrimType) && lhsRangeType == kNotEqual)) { rightRangePtr = std::make_unique(Bound(nullptr, 0, PTY_u1), kEqual); valueRange = rightRangePtr.get(); (void)Insert2Caches(bb.GetBBId(), opnd.GetExprID(), std::move(rightRangePtr)); @@ -4481,8 +4567,9 @@ MeExpr *ValueRangePropagation::GetDefOfBase(const IvarMeExpr &ivar) const { return var->GetDefStmt()->GetLHS(); } -void ValueRangePropagation::DealWithCondGotoWhenRightRangeIsNotExist( - BB &bb, const MeExpr &opnd0, MeExpr &opnd1, Opcode opOfBrStmt, Opcode conditionalOp, ValueRange *valueRangeOfLeft) { +void ValueRangePropagation::DealWithCondGotoWhenRightRangeIsNotExist(BB &bb, const MeExpr &opnd0, MeExpr &opnd1, + Opcode opOfBrStmt, Opcode conditionalOp, + ValueRange *valueRangeOfLeft) { PrimType prim = opnd1.GetPrimType(); if (!IsNeededPrimType(prim)) { return; @@ -4493,72 +4580,76 @@ void ValueRangePropagation::DealWithCondGotoWhenRightRangeIsNotExist( switch (conditionalOp) { case OP_ne: { (void)Insert2Caches(trueBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(Bound(&opnd1, prim), kNotEqual)); + std::make_unique(Bound(&opnd1, prim), kNotEqual)); (void)Insert2Caches(falseBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(Bound(&opnd1, prim), kEqual)); + std::make_unique(Bound(&opnd1, prim), kEqual)); break; } case OP_eq: { (void)Insert2Caches(trueBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(Bound(&opnd1, prim), kEqual)); + std::make_unique(Bound(&opnd1, prim), kEqual)); (void)Insert2Caches(falseBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(Bound(&opnd1, prim), kNotEqual)); + std::make_unique(Bound(&opnd1, prim), kNotEqual)); break; } case OP_le: { if (valueRangeOfLeft != nullptr && valueRangeOfLeft->GetRangeType() == kOnlyHasLowerBound) { (void)Insert2Caches(trueBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(valueRangeOfLeft->GetLower(), - Bound(&opnd1, prim), kLowerAndUpper, dealWithPhi)); + std::make_unique(valueRangeOfLeft->GetLower(), Bound(&opnd1, prim), + kLowerAndUpper, dealWithPhi)); } else { - (void)Insert2Caches(trueBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(Bound(GetMinNumber(prim), prim), - Bound(&opnd1, prim), kLowerAndUpper)); + (void)Insert2Caches( + trueBranch->GetBBId(), opnd0.GetExprID(), + std::make_unique(Bound(GetMinNumber(prim), prim), Bound(&opnd1, prim), kLowerAndUpper)); } - (void)Insert2Caches(falseBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(Bound(&opnd1, 1, prim), - Bound(GetMaxNumber(prim), prim), kLowerAndUpper)); + (void)Insert2Caches( + falseBranch->GetBBId(), opnd0.GetExprID(), + std::make_unique(Bound(&opnd1, 1, prim), Bound(GetMaxNumber(prim), prim), kLowerAndUpper)); break; } case OP_lt: { if (valueRangeOfLeft != nullptr && valueRangeOfLeft->GetRangeType() == kOnlyHasLowerBound) { (void)Insert2Caches(trueBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(valueRangeOfLeft->GetLower(), - Bound(&opnd1, -1, prim), kLowerAndUpper, dealWithPhi)); + std::make_unique(valueRangeOfLeft->GetLower(), Bound(&opnd1, -1, prim), + kLowerAndUpper, dealWithPhi)); } else { - (void)Insert2Caches(trueBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(Bound(GetMinNumber(prim), prim), - Bound(&opnd1, -1, prim), kLowerAndUpper)); + (void)Insert2Caches( + trueBranch->GetBBId(), opnd0.GetExprID(), + std::make_unique(Bound(GetMinNumber(prim), prim), Bound(&opnd1, -1, prim), kLowerAndUpper)); } - (void)Insert2Caches(falseBranch->GetBBId(), opnd0.GetExprID(), + (void)Insert2Caches( + falseBranch->GetBBId(), opnd0.GetExprID(), std::make_unique(Bound(&opnd1, prim), Bound(GetMaxNumber(prim), prim), kLowerAndUpper)); break; } case OP_ge: { if (valueRangeOfLeft != nullptr && valueRangeOfLeft->GetRangeType() == kOnlyHasUpperBound) { - (void)Insert2Caches(trueBranch->GetBBId(), opnd0.GetExprID(), std::make_unique( - Bound(&opnd1, prim), valueRangeOfLeft->GetBound(), kLowerAndUpper, dealWithPhi)); - } else { (void)Insert2Caches(trueBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(Bound(&opnd1, prim), - Bound(GetMaxNumber(prim), prim), kLowerAndUpper)); + std::make_unique(Bound(&opnd1, prim), valueRangeOfLeft->GetBound(), + kLowerAndUpper, dealWithPhi)); + } else { + (void)Insert2Caches( + trueBranch->GetBBId(), opnd0.GetExprID(), + std::make_unique(Bound(&opnd1, prim), Bound(GetMaxNumber(prim), prim), kLowerAndUpper)); } - (void)Insert2Caches(falseBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(Bound(GetMinNumber(prim), prim), - Bound(&opnd1, -1, prim), kLowerAndUpper)); + (void)Insert2Caches( + falseBranch->GetBBId(), opnd0.GetExprID(), + std::make_unique(Bound(GetMinNumber(prim), prim), Bound(&opnd1, -1, prim), kLowerAndUpper)); break; } case OP_gt: { if (valueRangeOfLeft != nullptr && valueRangeOfLeft->GetRangeType() == kOnlyHasUpperBound) { - (void)Insert2Caches(trueBranch->GetBBId(), opnd0.GetExprID(), std::make_unique( - Bound(&opnd1, 1, prim), valueRangeOfLeft->GetBound(), kLowerAndUpper, dealWithPhi)); - } else { (void)Insert2Caches(trueBranch->GetBBId(), opnd0.GetExprID(), + std::make_unique(Bound(&opnd1, 1, prim), valueRangeOfLeft->GetBound(), + kLowerAndUpper, dealWithPhi)); + } else { + (void)Insert2Caches( + trueBranch->GetBBId(), opnd0.GetExprID(), std::make_unique(Bound(&opnd1, 1, prim), Bound(GetMaxNumber(prim), prim), kLowerAndUpper)); } - (void)Insert2Caches(falseBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(Bound(GetMinNumber(prim), prim), - Bound(&opnd1, prim), kLowerAndUpper)); + (void)Insert2Caches( + falseBranch->GetBBId(), opnd0.GetExprID(), + std::make_unique(Bound(GetMinNumber(prim), prim), Bound(&opnd1, prim), kLowerAndUpper)); break; } default: @@ -4567,15 +4658,16 @@ void ValueRangePropagation::DealWithCondGotoWhenRightRangeIsNotExist( } void ValueRangePropagation::GetValueRangeForUnsignedInt(const BB &bb, OpMeExpr &opMeExpr, const MeExpr &opnd, - ValueRange *&valueRange, std::unique_ptr &rightRangePtr) { + ValueRange *&valueRange, + std::unique_ptr &rightRangePtr) { if (onlyPropVR) { return; } PrimType prim = opMeExpr.GetOpndType(); if (prim == PTY_u1 || prim == PTY_u8 || prim == PTY_u16 || prim == PTY_u32 || prim == PTY_a32 || ((prim == PTY_ref || prim == PTY_ptr) && GetPrimTypeSize(prim) == kFourByte)) { - rightRangePtr = std::make_unique( - Bound(nullptr, 0, prim), Bound(GetMaxNumber(prim), prim), kLowerAndUpper); + rightRangePtr = + std::make_unique(Bound(nullptr, 0, prim), Bound(GetMaxNumber(prim), prim), kLowerAndUpper); valueRange = rightRangePtr.get(); (void)Insert2Caches(bb.GetBBId(), opnd.GetExprID(), std::move(rightRangePtr)); } @@ -4586,8 +4678,8 @@ void ValueRangePropagation::GetValueRangeForUnsignedInt(const BB &bb, OpMeExpr & // a: valuerange(0, Max) // ==> // Example: if (a != 0) -bool ValueRangePropagation::DealWithSpecialCondGoto( - const BB &bb, OpMeExpr &opMeExpr, const ValueRange &leftRange, ValueRange &rightRange, CondGotoMeStmt &brMeStmt) { +bool ValueRangePropagation::DealWithSpecialCondGoto(const BB &bb, OpMeExpr &opMeExpr, const ValueRange &leftRange, + ValueRange &rightRange, CondGotoMeStmt &brMeStmt) { if (onlyPropVR) { return false; } @@ -4611,8 +4703,8 @@ bool ValueRangePropagation::DealWithSpecialCondGoto( if (leftRange.GetLower().GetConstant() != rightRange.GetBound().GetConstant()) { return false; } - auto *newExpr = irMap.CreateMeExprCompare(OP_ne, opMeExpr.GetPrimType(), - opMeExpr.GetOpndType(), *opMeExpr.GetOpnd(0), *opMeExpr.GetOpnd(1)); + auto *newExpr = irMap.CreateMeExprCompare(OP_ne, opMeExpr.GetPrimType(), opMeExpr.GetOpndType(), + *opMeExpr.GetOpnd(0), *opMeExpr.GetOpnd(1)); (void)irMap.ReplaceMeExprStmt(brMeStmt, opMeExpr, *newExpr); return true; } @@ -4635,8 +4727,8 @@ bool ValueRangePropagation::DealWithSpecialCondGoto( } } auto *newConstExpr = irMap.CreateIntConstMeExpr(leftRange.GetLower().GetConstant(), opMeExpr.GetOpndType()); - auto *newExpr = irMap.CreateMeExprCompare(OP_eq, opMeExpr.GetPrimType(), - opMeExpr.GetOpndType(), *opMeExpr.GetOpnd(0), *newConstExpr); + auto *newExpr = irMap.CreateMeExprCompare(OP_eq, opMeExpr.GetPrimType(), opMeExpr.GetOpndType(), *opMeExpr.GetOpnd(0), + *newConstExpr); (void)irMap.ReplaceMeExprStmt(brMeStmt, opMeExpr, *newExpr); return true; } @@ -4651,11 +4743,11 @@ void ValueRangePropagation::DealWithBrStmtWithOneOpnd(BB &bb, const CondGotoMeSt // op: OP_ne // rightRange: 0 // leftRange: const 1 or var a - std::unique_ptr rightRangePtr = std::make_unique( - Bound(nullptr, 0, opnd.GetPrimType()), kEqual); + std::unique_ptr rightRangePtr = + std::make_unique(Bound(nullptr, 0, opnd.GetPrimType()), kEqual); if (opnd.GetMeOp() == kMeOpConst && static_cast(opnd).GetConstVal()->GetKind() == kConstInt) { std::unique_ptr leftRangePtr = std::make_unique( - Bound(static_cast(opnd).GetExtIntValue(), opnd.GetPrimType()), kEqual); + Bound(static_cast(opnd).GetExtIntValue(), opnd.GetPrimType()), kEqual); DealWithCondGoto(bb, op, leftRangePtr.get(), *rightRangePtr.get(), stmt); } else { ValueRange *leftRange = FindValueRange(bb, opnd); @@ -4735,14 +4827,14 @@ bool ValueRangePropagation::AnalysisUnreachableForGeOrGt(BB &bb, const CondGotoM // mx1: valuerange [min(mx2_type), mx2-1] or [min(mx2_type), mx2] // ==> // remove falseBranch or trueBranch -bool ValueRangePropagation::AnalysisUnreachableForLeOrLt( - BB &bb, const CondGotoMeStmt &brMeStmt, const ValueRange &leftRange) { +bool ValueRangePropagation::AnalysisUnreachableForLeOrLt(BB &bb, const CondGotoMeStmt &brMeStmt, + const ValueRange &leftRange) { Opcode op = static_cast(brMeStmt.GetOpnd())->GetOp(); BB *trueBranch = nullptr; BB *falseBranch = nullptr; GetTrueAndFalseBranch(brMeStmt.GetOp(), bb, trueBranch, falseBranch); // When the redundant branch can be inferred directly from the condGoto stmt - if (op == OP_lt && leftRange.GetUpper().GetConstant() == -1) { + if (op == OP_lt && leftRange.GetUpper().GetConstant() == -1) { // falseBranch is unreachable AnalysisUnreachableBBOrEdge(bb, *falseBranch, *trueBranch); return true; @@ -4775,8 +4867,7 @@ bool ValueRangePropagation::AnalysisUnreachableForEqOrNe(BB &bb, const CondGotoM BB *falseBranch = nullptr; GetTrueAndFalseBranch(brMeStmt.GetOp(), bb, trueBranch, falseBranch); // When the redundant branch can be inferred directly from the condGoto stmt - if ((op == OP_eq && leftRange.GetRangeType() == kEqual) || - (op == OP_ne && leftRange.GetRangeType() == kNotEqual)) { + if ((op == OP_eq && leftRange.GetRangeType() == kEqual) || (op == OP_ne && leftRange.GetRangeType() == kNotEqual)) { // falseBranch is unreachable AnalysisUnreachableBBOrEdge(bb, *falseBranch, *trueBranch); return true; @@ -4791,21 +4882,20 @@ bool ValueRangePropagation::AnalysisUnreachableForEqOrNe(BB &bb, const CondGotoM // This function deals with the case like this: // Example: first brfalse mx1 eq(ne/gt/le/ge/lt) mx2 // second brfalse mx1 eq(ne/gt/le/ge/lt) mx2 ==> remove falseBranch or trueBranch -bool ValueRangePropagation::DealWithVariableRange(BB &bb, const CondGotoMeStmt &brMeStmt, - const ValueRange &leftRange) { +bool ValueRangePropagation::DealWithVariableRange(BB &bb, const CondGotoMeStmt &brMeStmt, const ValueRange &leftRange) { MeExpr *opnd1 = static_cast(brMeStmt.GetOpnd())->GetOpnd(1); // Example1: deal with like if (mx1 > mx2), when the valuerange of mx1 is [mx2+1, max(mx2_type)] // Example2: deal with like if (mx1 >= mx2), when the valuerange of mx1 is [mx2, max(mx2_type)] if (leftRange.GetLower().GetVar() == opnd1 && leftRange.GetUpper().GetVar() == nullptr && leftRange.UpperIsMax(opnd1->GetPrimType())) { return AnalysisUnreachableForGeOrGt(bb, brMeStmt, leftRange); - // Example1: deal with like if (mx1 < mx2), when the valuerange of mx1 is [min(mx2_type), mx2-1] - // Example2: deal with like if (mx1 <= mx2), when the valuerange of mx1 is [min(mx2_type), mx2] + // Example1: deal with like if (mx1 < mx2), when the valuerange of mx1 is [min(mx2_type), mx2-1] + // Example2: deal with like if (mx1 <= mx2), when the valuerange of mx1 is [min(mx2_type), mx2] } else if (leftRange.GetLower().GetVar() == nullptr && leftRange.GetUpper().GetVar() == opnd1 && - leftRange.LowerIsMin(opnd1->GetPrimType())) { + leftRange.LowerIsMin(opnd1->GetPrimType())) { return AnalysisUnreachableForLeOrLt(bb, brMeStmt, leftRange); - // Example: deal with like if (mx1 == mx2), when the valuerange of mx1 is [mx2, mx2] - // Example: deal with like if (mx1 != mx2), when the valuerange of mx1 is [mx2, mx2] + // Example: deal with like if (mx1 == mx2), when the valuerange of mx1 is [mx2, mx2] + // Example: deal with like if (mx1 != mx2), when the valuerange of mx1 is [mx2, mx2] } else if (leftRange.GetLower().GetVar() == opnd1 && leftRange.GetLower().GetConstant() == 0 && leftRange.GetUpper().GetVar() == opnd1 && leftRange.GetUpper().GetConstant() == 0) { return AnalysisUnreachableForEqOrNe(bb, brMeStmt, leftRange); @@ -4869,7 +4959,8 @@ void ValueRangePropagation::DealWithCondGoto(BB &bb, MeStmt &stmt) { } void ValueRangePropagation::DumpCaches() { - LogInfo::MapleLogger() << "================Dump value range===================" << "\n"; + LogInfo::MapleLogger() << "================Dump value range===================" + << "\n"; for (size_t i = 0; i < caches.size(); ++i) { LogInfo::MapleLogger() << "BBId: " << i << "\n"; auto &it = caches[i]; @@ -4877,17 +4968,16 @@ void ValueRangePropagation::DumpCaches() { if (bIt->second == nullptr) { continue; } - if (bIt->second->GetRangeType() == kLowerAndUpper || - bIt->second->GetRangeType() == kSpecialLowerForLoop || + if (bIt->second->GetRangeType() == kLowerAndUpper || bIt->second->GetRangeType() == kSpecialLowerForLoop || bIt->second->GetRangeType() == kSpecialUpperForLoop) { - std::string lower = (bIt->second->GetLower().GetVar() == nullptr) ? - std::to_string(bIt->second->GetLower().GetConstant()) : - "mx" + std::to_string(bIt->second->GetLower().GetVar()->GetExprID()) + " " + - std::to_string(bIt->second->GetLower().GetConstant()); - std::string upper = (bIt->second->GetUpper().GetVar() == nullptr) ? - std::to_string(bIt->second->GetUpper().GetConstant()) : - "mx" + std::to_string(bIt->second->GetUpper().GetVar()->GetExprID()) + " " + - std::to_string(bIt->second->GetUpper().GetConstant()); + std::string lower = (bIt->second->GetLower().GetVar() == nullptr) + ? std::to_string(bIt->second->GetLower().GetConstant()) + : "mx" + std::to_string(bIt->second->GetLower().GetVar()->GetExprID()) + " " + + std::to_string(bIt->second->GetLower().GetConstant()); + std::string upper = (bIt->second->GetUpper().GetVar() == nullptr) + ? std::to_string(bIt->second->GetUpper().GetConstant()) + : "mx" + std::to_string(bIt->second->GetUpper().GetVar()->GetExprID()) + " " + + std::to_string(bIt->second->GetUpper().GetConstant()); LogInfo::MapleLogger() << "mx" << bIt->first << " lower: " << lower << " upper: " << upper; if (bIt->second->GetRangeType() == kLowerAndUpper) { LogInfo::MapleLogger() << " kLowerAndUpper\n"; @@ -4897,22 +4987,23 @@ void ValueRangePropagation::DumpCaches() { LogInfo::MapleLogger() << " kSpecialUpperForLoop\n"; } } else if (bIt->second->GetRangeType() == kOnlyHasLowerBound) { - std::string lower = (bIt->second->GetBound().GetVar() == nullptr) ? - std::to_string(bIt->second->GetBound().GetConstant()) : - "mx" + std::to_string(bIt->second->GetBound().GetVar()->GetExprID()) + " " + - std::to_string(bIt->second->GetBound().GetConstant()); - LogInfo::MapleLogger() << "mx" << bIt->first << " lower: " << lower << " upper: max " << "kOnlyHasLowerBound\n"; + std::string lower = (bIt->second->GetBound().GetVar() == nullptr) + ? std::to_string(bIt->second->GetBound().GetConstant()) + : "mx" + std::to_string(bIt->second->GetBound().GetVar()->GetExprID()) + " " + + std::to_string(bIt->second->GetBound().GetConstant()); + LogInfo::MapleLogger() << "mx" << bIt->first << " lower: " << lower << " upper: max " + << "kOnlyHasLowerBound\n"; } else if (bIt->second->GetRangeType() == kOnlyHasUpperBound) { - std::string upper = (bIt->second->GetBound().GetVar() == nullptr) ? - std::to_string(bIt->second->GetBound().GetConstant()) : - "mx" + std::to_string(bIt->second->GetBound().GetVar()->GetExprID()) + " " + - std::to_string(bIt->second->GetBound().GetConstant()); + std::string upper = (bIt->second->GetBound().GetVar() == nullptr) + ? std::to_string(bIt->second->GetBound().GetConstant()) + : "mx" + std::to_string(bIt->second->GetBound().GetVar()->GetExprID()) + " " + + std::to_string(bIt->second->GetBound().GetConstant()); LogInfo::MapleLogger() << "mx" << bIt->first << " lower: min upper: " << upper << "kOnlyHasUpperBound\n"; } else if (bIt->second->GetRangeType() == kEqual || bIt->second->GetRangeType() == kNotEqual) { - std::string lower = (bIt->second->GetBound().GetVar() == nullptr) ? - std::to_string(bIt->second->GetBound().GetConstant()) : - "mx" + std::to_string(bIt->second->GetBound().GetVar()->GetExprID()) + " " + - std::to_string(bIt->second->GetBound().GetConstant()); + std::string lower = (bIt->second->GetBound().GetVar() == nullptr) + ? std::to_string(bIt->second->GetBound().GetConstant()) + : "mx" + std::to_string(bIt->second->GetBound().GetVar()->GetExprID()) + " " + + std::to_string(bIt->second->GetBound().GetConstant()); LogInfo::MapleLogger() << "mx" << bIt->first << " lower and upper: " << lower; if (bIt->second->GetRangeType() == kEqual) { LogInfo::MapleLogger() << " kEqual\n"; @@ -4922,7 +5013,8 @@ void ValueRangePropagation::DumpCaches() { } } } - LogInfo::MapleLogger() << "================Dump value range===================" << "\n"; + LogInfo::MapleLogger() << "================Dump value range===================" + << "\n"; } void MEValueRangePropagation::GetAnalysisDependence(maple::AnalysisDep &aDep) const { @@ -4952,7 +5044,7 @@ bool MEValueRangePropagation::PhaseRun(maple::MeFunction &f) { sa.SetComputeTripCountForLoopUnroll(false); ValueRangePropagation valueRangePropagation(f, *irMap, *dom, meLoop, *valueRangeMemPool, cands, sa, true); - SafetyCheck safetyCheck; // dummy + SafetyCheck safetyCheck; // dummy valueRangePropagation.SetSafetyBoundaryCheck(safetyCheck); valueRangePropagation.SetSafetyNonnullCheck(safetyCheck); @@ -4972,29 +5064,39 @@ bool MEValueRangePropagation::PhaseRun(maple::MeFunction &f) { MPLTimer timer; timer.Start(); if (ValueRangePropagation::isDebug) { - LogInfo::MapleLogger() << "***************ssaupdate value range prop***************" << "\n"; - LogInfo::MapleLogger() << "========size of ost " << cands.size() << " " << - f.GetMeSSATab()->GetOriginalStTableSize() << "========\n"; + LogInfo::MapleLogger() << "***************ssaupdate value range prop***************" + << "\n"; + LogInfo::MapleLogger() << "========size of ost " << cands.size() << " " + << f.GetMeSSATab()->GetOriginalStTableSize() << "========\n"; } ssaUpdate.Run(); timer.Stop(); if (ValueRangePropagation::isDebug) { LogInfo::MapleLogger() << "ssaupdate consumes cumulatively " << timer.Elapsed() << "seconds " << '\n'; - LogInfo::MapleLogger() << "***************ssaupdate value range prop***************" << "\n"; + LogInfo::MapleLogger() << "***************ssaupdate value range prop***************" + << "\n"; } } GetAnalysisInfoHook()->ForceEraseAnalysisPhase(f.GetUniqueID(), &MELoopAnalysis::id); GetAnalysisInfoHook()->ForceRunTransFormPhase(&MELoopCanon::id, f); + // update cfg frequency + if (f.GetCfg()->UpdateCFGFreq()) { + f.GetCfg()->UpdateEdgeFreqWithBBFreq(); + if (f.GetCfg()->DumpIRProfileFile()) { + f.GetCfg()->DumpToFile("after-valuerange" + std::to_string(f.vrpRuns), false, true); + } + } } // Run vrp twice when need check boundary and nullable pointer. if (MeOption::boundaryCheckMode != kNoCheck || MeOption::npeCheckMode != kNoCheck) { auto *hook = GetAnalysisInfoHook(); - dom = static_cast( - hook->ForceRunAnalysisPhase>(&MEDominance::id, f))->GetResult(); + dom = static_cast(hook->ForceRunAnalysisPhase>(&MEDominance::id, f)) + ->GetResult(); meLoop = static_cast( - hook->ForceRunAnalysisPhase>(&MELoopAnalysis::id, f))->GetResult(); - ValueRangePropagation valueRangePropagationWithOPTAssert( - f, *irMap, *dom, meLoop, *valueRangeMemPool, cands, sa, true, true); + hook->ForceRunAnalysisPhase>(&MELoopAnalysis::id, f)) + ->GetResult(); + ValueRangePropagation valueRangePropagationWithOPTAssert(f, *irMap, *dom, meLoop, *valueRangeMemPool, cands, sa, + true, true); SafetyCheckWithBoundaryError safetyCheckBoundaryError(f, valueRangePropagationWithOPTAssert); SafetyCheckWithNonnullError safetyCheckNonnullError(f); if (MeOption::boundaryCheckMode == kNoCheck) { @@ -5010,7 +5112,8 @@ bool MEValueRangePropagation::PhaseRun(maple::MeFunction &f) { valueRangePropagationWithOPTAssert.Execute(); CHECK_FATAL(!valueRangePropagationWithOPTAssert.IsCFGChange(), "must not change the cfg!"); if (ValueRangePropagation::isDebug) { - LogInfo::MapleLogger() << "***************after check***************" << "\n"; + LogInfo::MapleLogger() << "***************after check***************" + << "\n"; f.Dump(false); f.GetCfg()->DumpToFile("valuerange-after-safe" + std::to_string(f.vrpRuns)); } diff --git a/src/mapleall/maple_me/src/optimizeCFG.cpp b/src/mapleall/maple_me/src/optimizeCFG.cpp index cbfa5e01f7..6665d96580 100644 --- a/src/mapleall/maple_me/src/optimizeCFG.cpp +++ b/src/mapleall/maple_me/src/optimizeCFG.cpp @@ -13,8 +13,9 @@ * See the Mulan PSL v2 for more details. */ #include "optimizeCFG.h" -#include "me_phase_manager.h" + #include "factory.h" +#include "me_phase_manager.h" namespace maple { namespace { @@ -23,27 +24,27 @@ const char *funcName = nullptr; std::string phaseName; #define LOG_BBID(BB) ((BB)->GetBBId().GetIdx()) -#define DEBUG_LOG() if (debug) \ -LogInfo::MapleLogger() << "[" << phaseName << "] " +#define DEBUG_LOG() \ + if (debug) LogInfo::MapleLogger() << "[" << phaseName << "] " // return {trueBB, falseBB} -std::pair GetTrueFalseBrPair(BB *bb) { +std::pair GetTrueFalseBrPair(BB *bb) { if (bb == nullptr) { - return { nullptr, nullptr }; + return {nullptr, nullptr}; } if (bb->GetKind() == kBBCondGoto) { auto *condBr = static_cast(bb->GetLastMe()); CHECK_FATAL(condBr, "condBr is nullptr!"); if (condBr->GetOp() == OP_brtrue) { - return { bb->GetSucc(1), bb->GetSucc(0) }; + return {bb->GetSucc(1), bb->GetSucc(0)}; } else { ASSERT(condBr->GetOp() == OP_brfalse, "only support brtrue/brfalse"); - return { bb->GetSucc(0), bb->GetSucc(1) }; + return {bb->GetSucc(0), bb->GetSucc(1)}; } } else if (bb->GetKind() == kBBGoto) { - return { bb->GetSucc(0), nullptr }; + return {bb->GetSucc(0), nullptr}; } - return { nullptr, nullptr }; + return {nullptr, nullptr}; } // Only one fallthru is allowed for a bb at most , but a bb may have be more than one fallthru pred @@ -82,7 +83,7 @@ void CollectUnsafeExpr(MeExpr *expr, std::set &exprSet) { if (expr->GetMeOp() == kMeOpConst || expr->GetMeOp() == kMeOpVar) { return; } - if (expr->GetMeOp() == kMeOpIvar) { // do not use HasIvar here for efficiency reasons + if (expr->GetMeOp() == kMeOpIvar) { // do not use HasIvar here for efficiency reasons exprSet.insert(expr); } if (expr->GetOp() == OP_div || expr->GetOp() == OP_rem) { @@ -100,7 +101,7 @@ void CollectUnsafeExpr(MeExpr *expr, std::set &exprSet) { // expr not throw exception bool IsSafeExpr(const MeExpr *expr) { - if (expr->GetMeOp() == kMeOpIvar) { // do not use HasIvar here for efficiency reasons + if (expr->GetMeOp() == kMeOpIvar) { // do not use HasIvar here for efficiency reasons return false; } if (expr->GetOp() == OP_div || expr->GetOp() == OP_rem) { @@ -123,8 +124,7 @@ bool IsSafeExpr(const MeExpr *expr) { bool IsSimpleImm(uint64 imm) { return ((imm & (static_cast(0xffff) << 48u)) == imm) || ((imm & (static_cast(0xffff) << 32u)) == imm) || - ((imm & (static_cast(0xffff) << 16u)) == imm) || - ((imm & (static_cast(0xffff))) == imm) || + ((imm & (static_cast(0xffff) << 16u)) == imm) || ((imm & (static_cast(0xffff))) == imm) || (((~imm) & (static_cast(0xffff) << 48u)) == ~imm) || (((~imm) & (static_cast(0xffff) << 32u)) == ~imm) || (((~imm) & (static_cast(0xffff) << 16u)) == ~imm) || @@ -135,12 +135,12 @@ bool IsSimpleImm(uint64 imm) { // if non-simple imm exist, return it, otherwise return 0 int64 GetNonSimpleImm(MeExpr *expr) { if (expr->GetMeOp() == kMeOpConst && IsPrimitiveInteger(expr->GetPrimType())) { - int64 imm = static_cast(static_cast(expr)->GetConstVal())->GetExtValue(); + int64 imm = static_cast(static_cast(expr)->GetConstVal())->GetExtValue(); if (!IsSimpleImm(static_cast(imm))) { return imm; } } - return 0; // 0 is a simple imm + return 0; // 0 is a simple imm } // Check if ftBB has only one regassign stmt, if regassign exists, return it, otherwise return nullptr @@ -150,7 +150,7 @@ AssignMeStmt *GetSingleAssign(BB *bb) { while (stmt != nullptr && stmt->GetOp() == OP_comment) { stmt = stmt->GetNextMeStmt(); } - if (stmt == nullptr) { // empty bb or has only comment stmt + if (stmt == nullptr) { // empty bb or has only comment stmt return nullptr; } if (stmt->GetOp() == OP_regassign || stmt->GetOp() == OP_dassign) { @@ -193,7 +193,7 @@ bool IsAllOpndsNotDefByCurrBB(const MeExpr &expr, const BB &currBB, std::setGetPred().empty() && bb->GetSucc().empty() && phiNode.GetOpnds().size() == 1) { @@ -207,7 +207,7 @@ bool IsAllOpndsNotDefByCurrBB(const MeExpr &expr, const BB &currBB, std::setGetBB() != &currBB; } case kMeOpIvar: { - auto &ivar = static_cast(expr); + auto &ivar = static_cast(expr); if (!IsAllOpndsNotDefByCurrBB(*ivar.GetBase(), currBB, infLoopCheck)) { return false; } @@ -249,8 +249,8 @@ bool IsAllOpndsNotDefByCurrBB(const MeStmt &stmt) { MeExpr *GetInvertCond(MeIRMap *irmap, MeExpr *cond) { if (IsCompareHasReverseOp(cond->GetOp())) { - return irmap->CreateMeExprBinary(GetReverseCmpOp(cond->GetOp()), cond->GetPrimType(), - *cond->GetOpnd(0), *cond->GetOpnd(1)); + return irmap->CreateMeExprBinary(GetReverseCmpOp(cond->GetOp()), cond->GetPrimType(), *cond->GetOpnd(0), + *cond->GetOpnd(1)); } return irmap->CreateMeExprUnary(OP_lnot, cond->GetPrimType(), *cond); } @@ -258,8 +258,7 @@ MeExpr *GetInvertCond(MeIRMap *irmap, MeExpr *cond) { // Is subSet a subset of superSet? template inline bool IsSubset(const std::set &subSet, const std::set &superSet) { - return std::includes(superSet.begin(), superSet.end(), - subSet.begin(), subSet.end()); + return std::includes(superSet.begin(), superSet.end(), subSet.begin(), subSet.end()); } // before : predCond ---> succCond @@ -269,7 +268,7 @@ bool IsSafeToMergeCond(MeExpr *predCond, MeExpr *succCond) { // Make sure succCond is not dependent on predCond // e.g. if (ptr != nullptr) if (*ptr), the second condition depends on the first one if (predCond == succCond) { - return true; // same expr + return true; // same expr } if (!IsSafeExpr(succCond)) { std::set predSet; @@ -316,9 +315,9 @@ std::unique_ptr GetVRForSimpleCmpExpr(const MeExpr &expr) { if (!IsPrimitiveInteger(opndType)) { return nullptr; } - Bound opnd1Bound(nullptr, 0, opndType); // bound of expr's opnd1 + Bound opnd1Bound(nullptr, 0, opndType); // bound of expr's opnd1 if (expr.GetOpnd(1)->GetMeOp() == kMeOpConst) { - MIRConst *constVal = static_cast(expr.GetOpnd(1))->GetConstVal(); + MIRConst *constVal = static_cast(expr.GetOpnd(1))->GetConstVal(); if (constVal->GetKind() != kConstInt) { return nullptr; } @@ -380,7 +379,7 @@ BB *GetCommonDest(BB *predBB, BB *succBB) { } if (psucc0 != succBB && psucc1 != succBB) { - return nullptr; // predBB has no branch to succBB + return nullptr; // predBB has no branch to succBB } BB *commonBB = (psucc0 == succBB) ? psucc1 : psucc0; if (commonBB == nullptr) { @@ -517,7 +516,7 @@ bool UnreachBBAnalysis(const maple::MeFunction &f) { } return false; } -} // anonymous namespace +} // anonymous namespace // contains only one valid goto stmt bool HasOnlyMeGotoStmt(BB &bb) { @@ -600,8 +599,8 @@ bool IsMplEmptyBB(BB &bb) { // connectingBB has only one pred and succ, and has no stmt (except a single gotoStmt) in it bool IsConnectingBB(BB &bb) { return (bb.GetPred().size() == 1 && bb.GetSucc().size() == 1) && - (IsMeEmptyBB(bb) || HasOnlyMeGotoStmt(bb)) && // for meir, if no meir exist, it is empty - (IsMplEmptyBB(bb) || HasOnlyMplGotoStmt(bb)); // for mplir, if no mplir exist, it is empty + (IsMeEmptyBB(bb) || HasOnlyMeGotoStmt(bb)) && // for meir, if no meir exist, it is empty + (IsMplEmptyBB(bb) || HasOnlyMplGotoStmt(bb)); // for mplir, if no mplir exist, it is empty } // RealSucc is a non-connecting BB which is not empty (or has just a single gotoStmt). @@ -664,8 +663,8 @@ void EliminateEmptyConnectingBB(const BB *predBB, BB *emptyBB, const BB *stopBB, while (emptyBB != nullptr && emptyBB != stopBB && IsConnectingBB(*emptyBB)) { BB *succ = emptyBB->GetSucc(0); BB *pred = emptyBB->GetPred(0); - DEBUG_LOG() << "Delete empty connecting : BB" << LOG_BBID(pred) << "->BB" << LOG_BBID(emptyBB) - << "(deleted)->BB" << LOG_BBID(succ) << "\n"; + DEBUG_LOG() << "Delete empty connecting : BB" << LOG_BBID(pred) << "->BB" << LOG_BBID(emptyBB) << "(deleted)->BB" + << LOG_BBID(succ) << "\n"; if (pred->IsPredBB(*succ)) { pred->RemoveSucc(*emptyBB, true); emptyBB->RemoveSucc(*succ, true); @@ -688,27 +687,33 @@ bool HasFallthruPred(const BB &bb) { class OptimizeBB { public: OptimizeBB(BB *bb, MeFunction &func, std::map>> *candidates) - : currBB(bb), f(func), cfg(func.GetCfg()), irmap(func.GetIRMap()), - irBuilder(func.GetMIRModule().GetMIRBuilder()), isMeIR(irmap != nullptr), cands(candidates) {} + : currBB(bb), + f(func), + cfg(func.GetCfg()), + irmap(func.GetIRMap()), + irBuilder(func.GetMIRModule().GetMIRBuilder()), + isMeIR(irmap != nullptr), + cands(candidates) {} // optimize each currBB until no change occur bool OptBBIteratively(); // initial factory to create corresponding optimizer for currBB according to BBKind. void InitBBOptFactory(); private: - BB *currBB = nullptr; // BB we currently perform optimization on - MeFunction &f; // function we currently perform optimization on - MeCFG *cfg = nullptr; // requiring cfg to find pattern to optimize current BB - MeIRMap *irmap = nullptr; // used to create new MeExpr/MeStmt - MIRBuilder *irBuilder = nullptr; // used to create new BaseNode(expr)/StmtNode + BB *currBB = nullptr; // BB we currently perform optimization on + MeFunction &f; // function we currently perform optimization on + MeCFG *cfg = nullptr; // requiring cfg to find pattern to optimize current BB + MeIRMap *irmap = nullptr; // used to create new MeExpr/MeStmt + MIRBuilder *irBuilder = nullptr; // used to create new BaseNode(expr)/StmtNode bool isMeIR = false; - std::map>> *cands = nullptr; // candidates ost need to be updated ssa - std::map> candsOstInBB; // bb with ost needed to be updated - - bool repeatOpt = false; // It will be always set false by OptBBIteratively. If there is some optimization - // opportunity for currBB after a/some optimization, we should set it true. - // Otherwise it will stop after all optimizations finished and continue to nextBB. - enum BBErrStat { + std::map>> *cands = nullptr; // candidates ost need to be updated ssa + std::map> candsOstInBB; // bb with ost needed to be updated + + bool repeatOpt = false; // It will be always set false by OptBBIteratively. If there is some optimization + // opportunity for currBB after a/some optimization, we should set it true. + // Otherwise it will stop after all optimizations finished and continue to nextBB. + enum BBErrStat + { kBBNoErr, // BB is normal kBBErrNull, // BB is nullptr kBBErrOOB, // BB id is out-of-bound @@ -792,23 +797,23 @@ class OptimizeBB { repeatOpt = false; } #define CHECK_CURR_BB() \ -if (!CheckCurrBB()) { \ - return false; \ -} + if (!CheckCurrBB()) { \ + return false; \ + } #define ONLY_FOR_MEIR() \ -if (!isMeIR) { \ - return false; \ -} + if (!isMeIR) { \ + return false; \ + } }; -using OptBBFatory = FunctionFactory; +using OptBBFatory = FunctionFactory; bool OptimizeBB::CheckCurrBB() { - if (bbErrStat != kBBNoErr) { // has been checked before + if (bbErrStat != kBBNoErr) { // has been checked before return false; } - if (currBB == nullptr) { + if (currBB == nullptr) { bbErrStat = kBBErrNull; return false; } @@ -832,9 +837,9 @@ bool OptimizeBB::CheckCurrBB() { void OptimizeBB::UpdateBBIdInSSACand(const BBId &oldBBID, const BBId &newBBID) { auto it = candsOstInBB.find(oldBBID); if (it == candsOstInBB.end()) { - return; // no item to update + return; // no item to update } - auto &ostSet = candsOstInBB[newBBID]; // find or create + auto &ostSet = candsOstInBB[newBBID]; // find or create ostSet.insert(it->second.begin(), it->second.end()); candsOstInBB.erase(it); for (auto &cand : *cands) { @@ -854,7 +859,7 @@ void OptimizeBB::UpdateSSACandForBBPhiList(BB *bb, const BB *newBB) { if (!isMeIR || bb == nullptr || bb->GetMePhiList().empty()) { return; } - if (newBB == nullptr) { // if not specified, newBB is bb itself + if (newBB == nullptr) { // if not specified, newBB is bb itself newBB = bb; } std::set &ostSet = candsOstInBB[newBB->GetBBId()]; @@ -942,18 +947,18 @@ bool OptimizeBB::BranchBB2UncondBB(BB &bb) { } } - DEBUG_LOG() << "BranchBB2UncondBB : " << (bb.GetKind() == kBBCondGoto ? "Conditional " : "Switch ") - << "BB" << LOG_BBID(&bb) << " to unconditional BB\n"; + DEBUG_LOG() << "BranchBB2UncondBB : " << (bb.GetKind() == kBBCondGoto ? "Conditional " : "Switch ") << "BB" + << LOG_BBID(&bb) << " to unconditional BB\n"; // delete all empty bb between bb and destBB // note : bb and destBB will be connected after empty BB is deleted for (int i = static_cast(bb.GetSucc().size()) - 1; i >= 0; --i) { EliminateEmptyConnectingBB(&bb, bb.GetSucc(static_cast(i)), destBB, *cfg); } - while (bb.GetSucc().size() != 1) { // bb is an unconditional bb now, and its successor num should be 1 + while (bb.GetSucc().size() != 1) { // bb is an unconditional bb now, and its successor num should be 1 ASSERT(bb.GetSucc().back() == destBB, "[FUNC: %s]Goto BB%d has different destination", funcName, LOG_BBID(&bb)); bb.RemoveSucc(*bb.GetSucc().back()); } - if (Options::profileUse && !bb.GetSuccFreq().empty()) { + if (cfg->UpdateCFGFreq()) { ASSERT(bb.GetSuccFreq().size() == bb.GetSucc().size(), "sanity check"); bb.SetSuccFreq(0, bb.GetFrequency()); } @@ -1009,30 +1014,32 @@ bool OptimizeBB::OptimizeCondBB2UnCond() { CHECK_FATAL(brStmt, "brStmt is nullptr!"); bool isCondTrue = (!condExpr->IsZero()); bool isBrtrue = (brStmt->GetOp() == OP_brtrue); - if (isCondTrue != isBrtrue) { // goto fallthru BB + if (isCondTrue != isBrtrue) { // goto fallthru BB currBB->RemoveLastMeStmt(); currBB->SetKind(kBBFallthru); - if (Options::profileUse && !currBB->GetSuccFreq().empty()) { + if (cfg->UpdateCFGFreq()) { removedSuccFreq = currBB->GetSuccFreq()[1]; } currBB->RemoveSucc(*gtBB, true); // update frequency - if (Options::profileUse && !currBB->GetSuccFreq().empty()) { + if (cfg->UpdateCFGFreq()) { currBB->SetSuccFreq(0, currBB->GetFrequency()); ftBB->SetFrequency(ftBB->GetFrequency() + removedSuccFreq); + ftBB->UpdateEdgeFreqs(false); } } else { MeStmt *gotoStmt = irmap->CreateGotoMeStmt(f.GetOrCreateBBLabel(*gtBB), currBB, &brStmt->GetSrcPosition()); currBB->ReplaceMeStmt(brStmt, gotoStmt); currBB->SetKind(kBBGoto); // update frequency - if (Options::profileUse && !currBB->GetSuccFreq().empty()) { + if (cfg->UpdateCFGFreq()) { removedSuccFreq = currBB->GetSuccFreq()[0]; } currBB->RemoveSucc(*ftBB, true); - if (Options::profileUse && !currBB->GetSuccFreq().empty()) { + if (cfg->UpdateCFGFreq()) { currBB->SetSuccFreq(0, currBB->GetFrequency()); gtBB->SetFrequency(gtBB->GetFrequency() + removedSuccFreq); + gtBB->UpdateEdgeFreqs(false); } } SetBBRunAgain(); @@ -1048,25 +1055,27 @@ bool OptimizeBB::OptimizeCondBB2UnCond() { if (isCondTrue != isBrTrue) { currBB->RemoveLastStmt(); currBB->SetKind(kBBFallthru); - if (Options::profileUse && !currBB->GetSuccFreq().empty()) { + if (cfg->UpdateCFGFreq()) { removedSuccFreq = currBB->GetSuccFreq()[1]; } currBB->RemoveSucc(*gtBB); - if (Options::profileUse && !currBB->GetSuccFreq().empty()) { + if (cfg->UpdateCFGFreq()) { currBB->SetSuccFreq(0, currBB->GetFrequency()); ftBB->SetFrequency(ftBB->GetFrequency() + removedSuccFreq); + ftBB->UpdateEdgeFreqs(false); } } else { StmtNode *gotoStmt = irBuilder->CreateStmtGoto(OP_goto, f.GetOrCreateBBLabel(*gtBB)); currBB->ReplaceStmt(&brStmt, gotoStmt); currBB->SetKind(kBBGoto); - if (Options::profileUse && !currBB->GetSuccFreq().empty()) { + if (cfg->UpdateCFGFreq()) { removedSuccFreq = currBB->GetSuccFreq()[0]; } currBB->RemoveSucc(*ftBB); - if (Options::profileUse && !currBB->GetSuccFreq().empty()) { + if (cfg->UpdateCFGFreq()) { currBB->SetSuccFreq(0, currBB->GetFrequency()); gtBB->SetFrequency(gtBB->GetFrequency() + removedSuccFreq); + gtBB->UpdateEdgeFreqs(false); } } SetBBRunAgain(); @@ -1149,11 +1158,15 @@ bool OptimizeBB::RemoveSuccFromNoReturnBB() { if (phiNode->GetOpnds().size() < 1) { break; } - phiNode->GetOpnds().push_back(phiNode->GetOpnd(0)); // to maintain opnd num and predNum + phiNode->GetOpnds().push_back(phiNode->GetOpnd(0)); // to maintain opnd num and predNum } } (void)EliminateRedundantPhiList(retBB); ResetBBRunAgain(); + // add edge Frequency to exitbb + if (cfg->UpdateCFGFreq()) { + currBB->PushBackSuccFreq(0); + } } return true; } @@ -1205,15 +1218,14 @@ BB *OptimizeBB::MergeSuccIntoPred(BB *pred, BB *succ) { } } // update succFreqs before update succs - if (Options::profileUse && f.GetMirFunc()->GetFuncProfData() && - !succ->GetSuccFreq().empty()) { + if (cfg->UpdateCFGFreq() && !succ->GetSuccFreq().empty()) { // copy succFreqs of succ to pred for (int i = 0; i < succ->GetSuccFreq().size(); i++) { pred->PushBackSuccFreq(succ->GetSuccFreq()[i]); } } succ->MoveAllSuccToPred(pred, cfg->GetCommonExitBB()); - pred->RemoveSucc(*succ, false); // philist will not be associated with pred BB, no need to update phi here. + pred->RemoveSucc(*succ, false); // philist will not be associated with pred BB, no need to update phi here. if (!isSuccEmpty) { // only when we move stmt from succ to pred should we set attr and kind here pred->SetAttributes(succ->GetAttributes()); @@ -1237,11 +1249,11 @@ BB *OptimizeBB::MergeSuccIntoPred(BB *pred, BB *succ) { // update bbid : tell ssa-updater to update with new BBID UpdateBBIdInSSACand(succ->GetBBId(), pred->GetBBId()); } - DEBUG_LOG() << "Merge BB" << LOG_BBID(succ) << " to BB" << LOG_BBID(pred) - << ", and delete BB" << LOG_BBID(succ) << "\n"; + DEBUG_LOG() << "Merge BB" << LOG_BBID(succ) << " to BB" << LOG_BBID(pred) << ", and delete BB" << LOG_BBID(succ) + << "\n"; UpdateSSACandForBBPhiList(succ, pred); DeleteBB(succ); - succ->SetBBId(pred->GetBBId()); // succ has been merged to pred, and reference to succ should be set to pred too. + succ->SetBBId(pred->GetBBId()); // succ has been merged to pred, and reference to succ should be set to pred too. return pred; } @@ -1284,13 +1296,13 @@ bool OptimizeBB::IsProfitableForCond2Sel(MeExpr *condExpr, MeExpr *trueExpr, MeE if (trueExpr == falseExpr) { return true; } - ASSERT(IsSafeExpr(trueExpr), "[FUNC: %s]Please check for safety first", funcName) ; - ASSERT(IsSafeExpr(falseExpr), "[FUNC: %s]Please check for safety first", funcName) ; + ASSERT(IsSafeExpr(trueExpr), "[FUNC: %s]Please check for safety first", funcName); + ASSERT(IsSafeExpr(falseExpr), "[FUNC: %s]Please check for safety first", funcName); // try to simplify select expr MeExpr *selExpr = irmap->CreateMeExprSelect(trueExpr->GetPrimType(), *condExpr, *trueExpr, *falseExpr); MeExpr *simplifiedSel = irmap->SimplifyMeExpr(selExpr); if (simplifiedSel != selExpr) { - return true; // can be simplified + return true; // can be simplified } // We can check for every opnd of opndExpr, and calculate their cost according to cg's insn @@ -1315,30 +1327,30 @@ bool OptimizeBB::IsProfitableForCond2Sel(MeExpr *condExpr, MeExpr *trueExpr, MeE return true; } - // Ignoring connecting BB, two cases can be turn into select - // condBB condBB - // / \ / \ +// Ignoring connecting BB, two cases can be turn into select +// condBB condBB +// / \ / \ // ftBB gtBB | gtBB/ftBB - // x<- x<- | x<- - // \ / \ / - // jointBB jointBB +// x<- x<- | x<- +// \ / \ / +// jointBB jointBB bool OptimizeBB::CondBranchToSelect() { CHECK_CURR_BB(); - BB *ftBB = FindFirstRealSucc(currBB->GetSucc(0)); // fallthruBB - BB *gtBB = FindFirstRealSucc(currBB->GetSucc(1)); // gotoBB + BB *ftBB = FindFirstRealSucc(currBB->GetSucc(0)); // fallthruBB + BB *gtBB = FindFirstRealSucc(currBB->GetSucc(1)); // gotoBB if (ftBB == gtBB) { (void)BranchBB2UncondBB(*currBB); return true; } // if ftBB or gtBB itself is jointBB, just return itself; otherwise return real succ - BB *ftTargetBB = (ftBB->GetPred().size() == 1 && ftBB->GetSucc().size() == 1) ? FindFirstRealSucc(ftBB->GetSucc(0)) - : ftBB; - BB *gtTargetBB = (gtBB->GetPred().size() == 1 && gtBB->GetSucc().size() == 1) ? FindFirstRealSucc(gtBB->GetSucc(0)) - : gtBB; + BB *ftTargetBB = + (ftBB->GetPred().size() == 1 && ftBB->GetSucc().size() == 1) ? FindFirstRealSucc(ftBB->GetSucc(0)) : ftBB; + BB *gtTargetBB = + (gtBB->GetPred().size() == 1 && gtBB->GetSucc().size() == 1) ? FindFirstRealSucc(gtBB->GetSucc(0)) : gtBB; if (ftTargetBB != gtTargetBB) { return false; } - BB *jointBB = ftTargetBB; // common succ + BB *jointBB = ftTargetBB; // common succ // Check if ftBB has only one assign stmt, set ftStmt if a assign stmt exist AssignMeStmt *ftStmt = nullptr; if (ftBB != jointBB) { @@ -1363,7 +1375,7 @@ bool OptimizeBB::CondBranchToSelect() { // Here we found a pattern, collect select opnds and result reg ScalarMeExpr *ftLHS = nullptr; MeExpr *ftRHS = nullptr; - std::set chiListCands; // collect chilist if assign stmt has one + std::set chiListCands; // collect chilist if assign stmt has one if (ftStmt != nullptr) { ftLHS = static_cast(ftStmt->GetLHS()); ftRHS = ftStmt->GetRHS(); @@ -1411,9 +1423,9 @@ bool OptimizeBB::CondBranchToSelect() { DEBUG_LOG() << "Abort cond2sel for BB" << LOG_BBID(currBB) << ", because two ost assigned are not the same\n"; return false; } - DEBUG_LOG() << "Candidate cond2sel BB" << LOG_BBID(currBB) << "(cond)->{BB" << LOG_BBID(currBB->GetSucc(0)) - << ", BB" << LOG_BBID(currBB->GetSucc(1)) << "}->BB" << LOG_BBID(ftTargetBB) << "(jointBB)\n"; - if (ftRHS != gtRHS) { // if ftRHS is the same as gtRHS, they can be simplified, and no need to check safety + DEBUG_LOG() << "Candidate cond2sel BB" << LOG_BBID(currBB) << "(cond)->{BB" << LOG_BBID(currBB->GetSucc(0)) << ", BB" + << LOG_BBID(currBB->GetSucc(1)) << "}->BB" << LOG_BBID(ftTargetBB) << "(jointBB)\n"; + if (ftRHS != gtRHS) { // if ftRHS is the same as gtRHS, they can be simplified, and no need to check safety // black list if (!IsSafeExpr(ftRHS) || !IsSafeExpr(gtRHS)) { DEBUG_LOG() << "Abort cond2sel for BB" << LOG_BBID(currBB) << ", because trueExpr or falseExpr is not safe\n"; @@ -1432,7 +1444,7 @@ bool OptimizeBB::CondBranchToSelect() { DEBUG_LOG() << "Condition To Select : BB" << LOG_BBID(currBB) << "(cond)->[BB" << LOG_BBID(ftBB) << "(ft), BB" << LOG_BBID(gtBB) << "(gt)]->BB" << LOG_BBID(jointBB) << "(joint)\n"; ScalarMeExpr *resLHS = nullptr; - if (jointBB->GetPred().size() == 2) { // if jointBB has only ftBB and gtBB as its pred. + if (jointBB->GetPred().size() == 2) { // if jointBB has only ftBB and gtBB as its pred. // use phinode lhs as result auto it = jointBB->GetMePhiList().find(ftLHS->GetOstIdx()); if (it == jointBB->GetMePhiList().end()) { @@ -1446,7 +1458,7 @@ bool OptimizeBB::CondBranchToSelect() { // It is profitable for instruction selection if select opnd is a compare expression // select condExpr, trueExpr, falseExpr => select cmpExpr, trueExpr, falseExpr if (condExpr->IsScalar() && condExpr->GetPrimType() != PTY_u1) { - auto *scalarExpr = static_cast(condExpr); + auto *scalarExpr = static_cast(condExpr); if (scalarExpr->GetDefBy() == kDefByStmt) { MeStmt *defStmt = scalarExpr->GetDefStmt(); MeExpr *rhs = defStmt->GetRHS(); @@ -1471,7 +1483,7 @@ bool OptimizeBB::CondBranchToSelect() { } (void)BranchBB2UncondBB(*currBB); // update phi - if (jointBB->GetPred().size() == 1) { // jointBB has only currBB as its pred + if (jointBB->GetPred().size() == 1) { // jointBB has only currBB as its pred // just remove phinode jointBB->GetMePhiList().erase(resLHS->GetOstIdx()); } else { @@ -1515,11 +1527,11 @@ bool IsExprSameLexicalally(MeExpr *expr1, MeExpr *expr2) { if (const1->GetKind() == kConstInt) { return static_cast(const1)->GetExtValue() == static_cast(const2)->GetExtValue(); } else if (const1->GetKind() == kConstFloatConst) { - return IsFloatingPointNumBitsSame(static_cast(const1)->GetValue(), - static_cast(const2)->GetValue()); + return IsFloatingPointNumBitsSame(static_cast(const1)->GetValue(), + static_cast(const2)->GetValue()); } else if (const1->GetKind() == kConstDoubleConst) { - return IsFloatingPointNumBitsSame(static_cast(const1)->GetValue(), - static_cast(const2)->GetValue()); + return IsFloatingPointNumBitsSame(static_cast(const1)->GetValue(), + static_cast(const2)->GetValue()); } return false; } @@ -1705,18 +1717,18 @@ bool OptimizeBB::SkipRedundantCond(BB &pred, BB &succ) { } MeExpr *predCond = predBr->GetOpnd(0); MeExpr *succCond = succBr->GetOpnd(0); - auto ptfSucc = GetTrueFalseBrPair(&pred); // pred true and false - auto stfSucc = GetTrueFalseBrPair(&succ); // succ true and false + auto ptfSucc = GetTrueFalseBrPair(&pred); // pred true and false + auto stfSucc = GetTrueFalseBrPair(&succ); // succ true and false // Try to infer result of succCond from predCond bool isPredTrueBrSucc = (FindFirstRealSucc(ptfSucc.first) == &succ); BranchResult tfBranch = InferSuccCondBrFromPredCond(predCond, succCond, isPredTrueBrSucc); - if (tfBranch == kBrUnknown) { // succCond cannot be inferred from predCond + if (tfBranch == kBrUnknown) { // succCond cannot be inferred from predCond return false; } // if succ's cond can be inferred from pred's cond, pred can skip succ and branches to newTarget directly BB *newTarget = (tfBranch == kBrTrue) ? FindFirstRealSucc(stfSucc.first) : FindFirstRealSucc(stfSucc.second); if (newTarget == nullptr || newTarget == &succ) { - return false; + return false; } DEBUG_LOG() << "Condition in BB" << LOG_BBID(&succ) << " is redundant, since it has been checked in BB" << LOG_BBID(&pred) << ", BB" << LOG_BBID(&pred) << " can branch to BB" << LOG_BBID(newTarget) << "\n"; @@ -1726,7 +1738,7 @@ bool OptimizeBB::SkipRedundantCond(BB &pred, BB &succ) { // succ ... // / \ // ftBB gtBB - if (succ.GetPred().size() == 1) { // succ has only one pred + if (succ.GetPred().size() == 1) { // succ has only one pred // if newTarget is succ's gotoBB, and it has fallthru pred, we should add a goto stmt to succ's last // to replace condGoto stmt. Otherwise, newTarget will have two fallthru pred if (newTarget == FindFirstRealSucc(succ.GetSucc(1)) && HasFallthruPred(*newTarget)) { @@ -1744,7 +1756,17 @@ bool OptimizeBB::SkipRedundantCond(BB &pred, BB &succ) { DEBUG_LOG() << "SkipRedundantCond : Remove condBr in BB" << LOG_BBID(&succ) << ", turn it to fallthruBB\n"; } BB *rmBB = (FindFirstRealSucc(succ.GetSucc(0)) == newTarget) ? succ.GetSucc(1) : succ.GetSucc(0); + int64_t deletedSuccFreq = 0; + if (cfg->UpdateCFGFreq()) { + int idx = succ.GetSuccIndex(*rmBB); + deletedSuccFreq = succ.GetSuccFreq()[idx]; + } succ.RemoveSucc(*rmBB, true); + if (cfg->UpdateCFGFreq()) { + succ.SetSuccFreq(0, succ.GetFrequency()); + auto *succofSucc = succ.GetSucc(0); + succofSucc->SetFrequency(succofSucc->GetFrequency() + deletedSuccFreq); + } DEBUG_LOG() << "Remove succ BB" << LOG_BBID(rmBB) << " of pred BB" << LOG_BBID(&succ) << "\n"; return true; } else { @@ -1782,18 +1804,19 @@ bool OptimizeBB::SkipRedundantCond(BB &pred, BB &succ) { BB *replacedSucc = isPredTrueBrSucc ? ptfSucc.first : ptfSucc.second; EliminateEmptyConnectingBB(&pred, replacedSucc, &succ, *cfg); ASSERT(pred.IsPredBB(succ), "[FUNC: %s]After eliminate connecting BB, pred must be predecessor of succ", funcName); - int predPredIdx = succ.GetPredIndex(pred); // before replace succ, record predidx for UpdatePhiForMovingPred - pred.ReplaceSucc(&succ, newBB, false); // do not update phi here, UpdatePhiForMovingPred will do it + int predPredIdx = succ.GetPredIndex(pred); // before replace succ, record predidx for UpdatePhiForMovingPred + pred.ReplaceSucc(&succ, newBB, false); // do not update phi here, UpdatePhiForMovingPred will do it DEBUG_LOG() << "Replace succ BB" << LOG_BBID(replacedSucc) << " with BB" << LOG_BBID(newBB) << ": BB" - << LOG_BBID(&pred) << "->...->BB" << LOG_BBID(&succ) << "(skipped)" << " => BB" << LOG_BBID(&pred) - << "->BB" << LOG_BBID(newBB) << "(new)->BB" << LOG_BBID(newTarget) << "\n"; + << LOG_BBID(&pred) << "->...->BB" << LOG_BBID(&succ) << "(skipped)" + << " => BB" << LOG_BBID(&pred) << "->BB" << LOG_BBID(newBB) << "(new)->BB" << LOG_BBID(newTarget) + << "\n"; if (pred.GetSucc(1) == newBB) { cfg->UpdateBranchTarget(pred, succ, *newBB, f); } newTarget->AddPred(*newBB); UpdatePhiForMovingPred(predPredIdx, newBB, &succ, newTarget); // update newBB frequency : copy predBB succFreq as newBB frequency - if (Options::profileUse && f.GetMirFunc()->GetFuncProfData()) { + if (cfg->UpdateCFGFreq()) { int idx = pred.GetSuccIndex(*newBB); ASSERT(idx >= 0 && idx < pred.GetSucc().size(), "sanity check"); uint64_t freq = pred.GetEdgeFreq(idx); @@ -1804,6 +1827,13 @@ bool OptimizeBB::SkipRedundantCond(BB &pred, BB &succ) { uint32_t freqOfSucc = succ.GetFrequency(); ASSERT(freqOfSucc >= freq, "sanity check"); succ.SetFrequency(freqOfSucc - freq); + // update edge frequency + BB *affectedBB = (tfBranch == kBrTrue) ? stfSucc.first : stfSucc.second; + idx = succ.GetSuccIndex(*affectedBB); + ASSERT(idx >= 0 && idx < succ.GetSucc().size(), "sanity check"); + int64_t oldedgeFreq = succ.GetSuccFreq()[idx]; + ASSERT(oldedgeFreq >= freq, "sanity check"); + succ.SetSuccFreq(idx, (oldedgeFreq - freq)); } return true; } @@ -1892,7 +1922,7 @@ void OptimizeBB::UpdatePhiForMovingPred(int predIdxForCurr, const BB *pred, BB * // create a new version for new phi phiMeNode->SetLHS(irmap->CreateRegOrVarMeExprVersion(ostIdx)); } - UpdateSSACandForBBPhiList(succ); // new philist has been created in succ + UpdateSSACandForBBPhiList(succ); // new philist has been created in succ } else { // succ has other pred besides curr for (auto &phi : succPhiList) { @@ -1922,7 +1952,7 @@ void OptimizeBB::UpdatePhiForMovingPred(int predIdxForCurr, const BB *pred, BB * } else { auto *phiMeNode = irmap->NewInPool(); phiMeNode->SetDefBB(succ); - resPair.first->second = phiMeNode; // replace nullptr inserted before + resPair.first->second = phiMeNode; // replace nullptr inserted before auto &phiOpnds = phiMeNode->GetOpnds(); // insert opnd into New phiNode : all phiOpnds (except for pred) are phiNode lhs in curr phiOpnds.insert(phiOpnds.end(), succ->GetPred().size(), phi.second->GetLHS()); @@ -1961,7 +1991,7 @@ bool OptimizeBB::MergeGotoBBToPred(BB *succ, BB *pred) { if (!HasOnlyMeGotoStmt(*succ)) { return false; } - BB *newTarget = succ->GetSucc(0); // succ must have only one succ, because it is uncondBB + BB *newTarget = succ->GetSucc(0); // succ must have only one succ, because it is uncondBB if (newTarget == succ) { // succ goto itself, no need to update goto target to newTarget return false; @@ -1973,8 +2003,8 @@ bool OptimizeBB::MergeGotoBBToPred(BB *succ, BB *pred) { // pred is moved to newTarget if (pred->GetKind() == kBBFallthru) { CHECK_FATAL(succ->GetLastMe(), "LastMe is nullptr!"); - GotoMeStmt *gotoMeStmt = irmap->CreateGotoMeStmt(newTarget->GetBBLabel(), pred, - &succ->GetLastMe()->GetSrcPosition()); + GotoMeStmt *gotoMeStmt = + irmap->CreateGotoMeStmt(newTarget->GetBBLabel(), pred, &succ->GetLastMe()->GetSrcPosition()); pred->AddMeStmtLast(gotoMeStmt); pred->SetKind(kBBGoto); DEBUG_LOG() << "Insert Uncond stmt to fallthru BB" << LOG_BBID(currBB) << ", and goto BB" << LOG_BBID(newTarget) @@ -1982,15 +2012,29 @@ bool OptimizeBB::MergeGotoBBToPred(BB *succ, BB *pred) { } int predIdx = succ->GetPredIndex(*pred); bool needUpdatePhi = false; + int64_t removedFreq = 0; + if (cfg->UpdateCFGFreq()) { + int idx = pred->GetSuccIndex(*succ); + removedFreq = pred->GetSuccFreq()[idx]; + } if (pred->IsPredBB(*newTarget)) { - pred->RemoveSucc(*succ, true); // one of pred's succ has been newTarget, avoid duplicate succ here + pred->RemoveSucc(*succ, true); // one of pred's succ has been newTarget, avoid duplicate succ here + if (cfg->UpdateCFGFreq()) { + int idx = pred->GetSuccIndex(*newTarget); + pred->SetSuccFreq(idx, pred->GetSuccFreq()[idx] + removedFreq); + } } else { - pred->ReplaceSucc(succ, newTarget); // phi opnd is not removed from currBB's philist, we will remove it later + pred->ReplaceSucc(succ, newTarget); // phi opnd is not removed from currBB's philist, we will remove it later needUpdatePhi = true; } - - DEBUG_LOG() << "Merge Uncond BB" << LOG_BBID(succ) << " to its pred BB" << LOG_BBID(pred) - << ": BB" << LOG_BBID(pred) << "->BB" << LOG_BBID(succ) << "(merged)->BB" << LOG_BBID(newTarget) << "\n"; + if (cfg->UpdateCFGFreq()) { + int64_t succFreq = succ->GetFrequency(); + ASSERT(succFreq >= removedFreq, "sanity check"); + succ->SetFrequency(succFreq - removedFreq); + succ->SetSuccFreq(0, succ->GetFrequency()); + } + DEBUG_LOG() << "Merge Uncond BB" << LOG_BBID(succ) << " to its pred BB" << LOG_BBID(pred) << ": BB" << LOG_BBID(pred) + << "->BB" << LOG_BBID(succ) << "(merged)->BB" << LOG_BBID(newTarget) << "\n"; cfg->UpdateBranchTarget(*pred, *succ, *newTarget, f); if (needUpdatePhi) { // remove phiOpnd in succ, and add phiOpnd to newTarget @@ -2032,7 +2076,7 @@ bool OptimizeBB::OptimizeUncondBB() { return false; } // wont exit BB and has an edge to commonExit, if we merge it to pred and delete it, the egde will be cut off - if (currBB->GetSucc().size() == 2) { // 2 succ : first is gotoTarget, second is edge to commonExit + if (currBB->GetSucc().size() == 2) { // 2 succ : first is gotoTarget, second is edge to commonExit ASSERT(currBB->GetAttributes(kBBAttrWontExit), "[FUNC: %s]GotoBB%d is not wontexitBB, but has two succ", funcName, LOG_BBID(currBB)); return false; @@ -2094,11 +2138,11 @@ bool OptimizeBB::OptimizeSwitchBB() { if (swStmt->GetOpnd()->GetMeOp() != kMeOpConst) { return false; } - auto *swConstExpr = static_cast(swStmt->GetOpnd()); + auto *swConstExpr = static_cast(swStmt->GetOpnd()); MIRConst *swConstVal = swConstExpr->GetConstVal(); ASSERT(swConstVal->GetKind() == kConstInt, "[FUNC: %s]switch is only legal for integer val", funcName); int64 val = static_cast(swConstVal)->GetExtValue(); - BB *survivor = currBB->GetSucc(0); // init as default BB + BB *survivor = currBB->GetSucc(0); // init as default BB for (size_t i = 0; i < swStmt->GetSwitchTable().size(); ++i) { int64 caseVal = swStmt->GetSwitchTable().at(i).first; if (caseVal == val) { @@ -2155,8 +2199,8 @@ MeExpr *OptimizeBB::CombineCondByOffset(const MeExpr &expr) { MeExpr *geConst = geExpr->GetOpnd(1); PrimType lePtyp = leConst->GetPrimType(); PrimType gePtyp = geConst->GetPrimType(); - if (leConst->GetOp() != OP_constval || geConst->GetOp() != OP_constval || - lePtyp != gePtyp || !IsPrimitiveInteger(lePtyp)) { // only allowed for integer, because float cannot wrap around + if (leConst->GetOp() != OP_constval || geConst->GetOp() != OP_constval || lePtyp != gePtyp || + !IsPrimitiveInteger(lePtyp)) { // only allowed for integer, because float cannot wrap around return nullptr; } int64 leVal = static_cast(static_cast(leConst)->GetConstVal())->GetExtValue(); @@ -2172,9 +2216,9 @@ MeExpr *OptimizeBB::CombineCondByOffset(const MeExpr &expr) { (IsPrimitiveUnsigned(lePtyp) && static_cast(leVal) > static_cast(newGeVal))) { // e.g. x < 3 || x > 2 <==> true return irmap->CreateIntConstMeExpr(1, PTY_u1); - } else if (leVal == newGeVal) { // e.g. x < 3 || x > 3 <==> x != 3 - return irmap->CreateMeExprCompare( - OP_ne, PTY_u1, opndPtyp, *sameExpr, *irmap->CreateIntConstMeExpr(newGeVal, lePtyp)); + } else if (leVal == newGeVal) { // e.g. x < 3 || x > 3 <==> x != 3 + return irmap->CreateMeExprCompare(OP_ne, PTY_u1, opndPtyp, *sameExpr, + *irmap->CreateIntConstMeExpr(newGeVal, lePtyp)); } // (x < val1 || x > val2) <==> ((unsigned)(x - val1) > (val2 - val1)) MeExpr *newLeConst = irmap->CreateIntConstMeExpr(leVal, opndPtyp); @@ -2253,15 +2297,15 @@ bool OptimizeBB::FoldBranchToCommonDest(BB *pred, BB *succ) { return false; } if (!IsProfitableToMergeCond(predCond, succCond)) { - DEBUG_LOG() << "Abort Merging Two CondBB : Condition in successor BB" - << LOG_BBID(succ) << " is not simple enough and not profitable\n"; + DEBUG_LOG() << "Abort Merging Two CondBB : Condition in successor BB" << LOG_BBID(succ) + << " is not simple enough and not profitable\n"; return false; } // Start trying to merge two condition together if possible - auto ptfBrPair = GetTrueFalseBrPair(pred); // pred's true and false branches - auto stfBrPair = GetTrueFalseBrPair(succ); // succ's true and false branches + auto ptfBrPair = GetTrueFalseBrPair(pred); // pred's true and false branches + auto stfBrPair = GetTrueFalseBrPair(succ); // succ's true and false branches Opcode combinedCondOp = OP_undef; - bool invertSuccCond = false; // invert second condition, e.g. (cond1 && !cond2) + bool invertSuccCond = false; // invert second condition, e.g. (cond1 && !cond2) // all cases are listed as follow: // | case | predBB -> common | succBB -> common | invertSuccCond | or/and | // | ---- | ---------------- | ---------------- | -------------- | ------ | @@ -2273,16 +2317,16 @@ bool OptimizeBB::FoldBranchToCommonDest(BB *pred, BB *succ) { // pred's false branch to succ, so true branch to common bool isPredTrueToCommon = (FindFirstRealSucc(ptfBrPair.second) == succ); bool isSuccTrueToCommon = (FindFirstRealSucc(stfBrPair.first) == commonBB); - if (isPredTrueToCommon && isSuccTrueToCommon) { // case 1 + if (isPredTrueToCommon && isSuccTrueToCommon) { // case 1 invertSuccCond = false; combinedCondOp = OP_lior; - } else if (!isPredTrueToCommon && !isSuccTrueToCommon) { // case 2 + } else if (!isPredTrueToCommon && !isSuccTrueToCommon) { // case 2 invertSuccCond = false; combinedCondOp = OP_land; - } else if (isPredTrueToCommon && !isSuccTrueToCommon) { // case 3 + } else if (isPredTrueToCommon && !isSuccTrueToCommon) { // case 3 invertSuccCond = true; combinedCondOp = OP_lior; - } else if (!isPredTrueToCommon && isSuccTrueToCommon) { // case 4 + } else if (!isPredTrueToCommon && isSuccTrueToCommon) { // case 4 invertSuccCond = true; combinedCondOp = OP_land; } else { @@ -2309,7 +2353,7 @@ bool OptimizeBB::FoldBranchToCommonDest(BB *pred, BB *succ) { // remove succ and update cfg BB *exitBB = isSuccTrueToCommon ? stfBrPair.second : stfBrPair.first; pred->ReplaceSucc(succ, exitBB); - exitBB->RemovePred(*succ, false); // not update phi here, because its phi opnd is the same as before. + exitBB->RemovePred(*succ, false); // not update phi here, because its phi opnd is the same as before. // we should eliminate edge from succ to commonBB BB *toEliminateBB = isSuccTrueToCommon ? stfBrPair.first : stfBrPair.second; EliminateEmptyConnectingBB(succ, toEliminateBB, commonBB /* stop here */, *cfg); @@ -2352,6 +2396,11 @@ bool OptimizeBB::FoldBranchToCommonDest() { bool OptimizeBB::OptBBOnce() { CHECK_CURR_BB(); DEBUG_LOG() << "Try to optimize BB" << LOG_BBID(currBB) << "...\n"; + // bb frequency may be updated, make bb frequency and succs frequency consistent + // skip deadBB + if (cfg->UpdateCFGFreq() && (!currBB->GetPred().empty()) && (currBB->GetUniquePred() != currBB)) { + currBB->UpdateEdgeFreqs(false); + } bool everChanged = false; // eliminate dead BB : // 1.BB has no pred(expect then entry block) @@ -2414,7 +2463,7 @@ class OptimizeFuntionCFG { private: MeFunction &f; - std::map>> *cands = nullptr; // candidates ost need to update ssa + std::map>> *cands = nullptr; // candidates ost need to update ssa bool OptimizeFuncCFGIteratively(); bool OptimizeCFGForBB(BB *currBB); }; @@ -2437,10 +2486,6 @@ bool OptimizeFuntionCFG::OptimizeFuncCFGIteratively() { if (currBB == nullptr) { continue; } - // bb frequency may be updated, make bb frequency and succs frequency consistent - if (Options::profileUse && !currBB->GetSuccFreq().empty()) { - currBB->UpdateEdgeFreqs(); - } changed |= OptimizeCFGForBB(currBB); } everChanged |= changed; @@ -2486,15 +2531,14 @@ bool OptimizeMeFuncCFG(maple::MeFunction &f, std::mapValidBBNum(); // optimization entry - bool change = OptimizeFuntionCFG(f, ssaCand) - .OptimizeOnFunc(); + bool change = OptimizeFuntionCFG(f, ssaCand).OptimizeOnFunc(); if (change) { f.GetCfg()->WontExitAnalysis(); if (debug) { uint32 bbNumAfter = f.GetCfg()->ValidBBNum(); if (bbNumBefore != bbNumAfter) { - DEBUG_LOG() << "BBs' number " << (bbNumBefore > bbNumAfter ? "reduce" : "increase") - << " from " << bbNumBefore << " to " << bbNumAfter << "\n"; + DEBUG_LOG() << "BBs' number " << (bbNumBefore > bbNumAfter ? "reduce" : "increase") << " from " << bbNumBefore + << " to " << bbNumAfter << "\n"; } else { DEBUG_LOG() << "BBs' number keep the same as before (num = " << bbNumAfter << ")\n"; } @@ -2515,6 +2559,9 @@ bool MEOptimizeCFGNoSSA::PhaseRun(MeFunction &f) { debug = DEBUGFUNC_NEWPM(f); phaseName = PhaseName(); bool change = OptimizeMeFuncCFG(f, nullptr); + if (change && f.GetCfg()->DumpIRProfileFile()) { + f.GetCfg()->DumpToFile("after-OptimizeCFGNOSSA", false, f.GetCfg()->UpdateCFGFreq()); + } return change; } @@ -2540,7 +2587,10 @@ bool MEOptimizeCFG::PhaseRun(maple::MeFunction &f) { MeSSAUpdate ssaUpdate(f, *f.GetMeSSATab(), *dom, cands); ssaUpdate.Run(); } + if (f.GetCfg()->DumpIRProfileFile()) { + f.GetCfg()->DumpToFile("after-OptimizeCFG", false, f.GetCfg()->UpdateCFGFreq()); + } } return change; } -} // namespace maple +} // namespace maple diff --git a/src/mapleall/maple_util/include/mpl_profdata.h b/src/mapleall/maple_util/include/mpl_profdata.h index 6aa8c1520f..6f9f1b3a1d 100644 --- a/src/mapleall/maple_util/include/mpl_profdata.h +++ b/src/mapleall/maple_util/include/mpl_profdata.h @@ -15,10 +15,11 @@ #ifndef MAPLE_UTIL_INCLUDE_MPL_PROFDATA_H #define MAPLE_UTIL_INCLUDE_MPL_PROFDATA_H -#include "mempool_allocator.h" #include #include +#include "mempool_allocator.h" + namespace maple { #define HOTCALLSITEFREQ 100 enum UpdateFreqOp { @@ -31,23 +32,27 @@ enum UpdateFreqOp { // used for record cumulative datas struct ProfileSummaryHistogram { + uint32_t countRatio; uint32_t startValue; // count value range in [startValue, nextHistogramStart) uint32_t countNums; // Number of counters whose profile count falls in countValue range. uint64_t countMinVal; // Smallest profile count included in this range. uint64_t countCumValue; // Cumulative value of the profile counts - ProfileSummaryHistogram(uint32_t s, uint32_t num, uint64_t mincount, uint64_t cumcounts) : - startValue(s), countNums(num), countMinVal(mincount), countCumValue(cumcounts) { - } + ProfileSummaryHistogram(uint32_t s, uint32_t num, uint64_t mincount, uint64_t cumcounts) + : countRatio(0), startValue(s), countNums(num), countMinVal(mincount), countCumValue(cumcounts) {} }; class ProfileSummary { -public: - ProfileSummary(MapleAllocator* alloc) : histogram(alloc->Adapter()) {} - ProfileSummary(MapleAllocator *alloc, uint64_t checksum, uint32_t runtimes, - uint32_t totalcount, uint64_t maxcount, uint64_t sumcount) : - checkSum(checksum), run(runtimes), totalCount(totalcount), maxCount(maxcount), sumCount(sumcount), - histogram(alloc->Adapter()) {} + public: + ProfileSummary(MapleAllocator *alloc) : histogram(alloc->Adapter()) {} + ProfileSummary(MapleAllocator *alloc, uint64_t checksum, uint32_t runtimes, uint32_t totalcount, uint64_t maxcount, + uint64_t sumcount) + : checkSum(checksum), + run(runtimes), + totalCount(totalcount), + maxCount(maxcount), + sumCount(sumcount), + histogram(alloc->Adapter()) {} void SetSummary(uint64_t checksum, uint32_t runtimes, uint32_t totalcount, uint64_t maxcount, uint64_t sumcount) { checkSum = checksum; @@ -60,44 +65,70 @@ public: histogram.push_back(ProfileSummaryHistogram(s, num, mincount, cumcounts)); } void DumpSummary(); - uint64_t GetCheckSum() { return checkSum; } - uint32_t GetRun() { return run; } - uint32_t GetTotalCount() { return totalCount; } - uint64_t GetMaxCount() { return maxCount; } - uint64_t GetSumCount() { return sumCount; } - uint32_t GetHistogramLength() { return histogram.size(); } - MapleVector& GetHistogram() { return histogram; } - -private: - uint64_t checkSum; // checksum value of module - uint32_t run; // run times - uint32_t totalCount; // number of counters - uint64_t maxCount; // max counter value in single run - uint64_t sumCount; // sum of all counters accumulated. - MapleVector histogram; // record gcov_bucket_type histogram[GCOV_HISTOGRAM_SIZE]; + uint64_t GetCheckSum() { + return checkSum; + } + uint32_t GetRun() { + return run; + } + uint32_t GetTotalCount() { + return totalCount; + } + uint64_t GetMaxCount() { + return maxCount; + } + uint64_t GetSumCount() { + return sumCount; + } + uint32_t GetHistogramLength() { + return histogram.size(); + } + void ProcessHistogram(); + MapleVector &GetHistogram() { + return histogram; + } + + private: + uint64_t checkSum; // checksum value of module + uint32_t run; // run times + uint32_t totalCount; // number of counters + uint64_t maxCount; // max counter value in single run + uint64_t sumCount; // sum of all counters accumulated. + MapleVector histogram; // record gcov_bucket_type histogram[GCOV_HISTOGRAM_SIZE]; }; class FuncProfInfo { public: - FuncProfInfo(MapleAllocator* alloc, unsigned funcIdent, unsigned lineno_cs, - unsigned cfg_cs, unsigned countnum = 0) : ident(funcIdent), linenoChecksum(lineno_cs), - cfgChecksum(cfg_cs), edgeCounts(countnum), counts(alloc->Adapter()) {}; + FuncProfInfo(MapleAllocator *alloc, unsigned funcIdent, unsigned lineno_cs, unsigned cfg_cs, unsigned countnum = 0) + : ident(funcIdent), + linenoChecksum(lineno_cs), + cfgChecksum(cfg_cs), + edgeCounts(countnum), + counts(alloc->Adapter()){}; ~FuncProfInfo() = default; - uint64_t GetFuncFrequency() const { return entry_freq; } - void SetFuncFrequency(uint64_t freq) { entry_freq = freq; } + uint64_t GetFuncFrequency() const { + return entry_freq; + } + void SetFuncFrequency(uint64_t freq) { + entry_freq = freq; + } - uint64_t GetFuncRealFrequency() const { return real_entryfreq; } - void SetFuncRealFrequency(uint64_t freq) { real_entryfreq = freq; } + uint64_t GetFuncRealFrequency() const { + return real_entryfreq; + } + void SetFuncRealFrequency(uint64_t freq) { + real_entryfreq = freq; + } - std::unordered_map& GetStmtFreqs() { + std::unordered_map &GetStmtFreqs() { return stmtFreqs; } uint64_t GetStmtFreq(uint32_t stmtID) { if (stmtFreqs.count(stmtID) > 0) { return stmtFreqs[stmtID]; } - return -1; // unstored + return -1; // unstored } void SetStmtFreq(uint32_t stmtID, uint64_t freq) { stmtFreqs[stmtID] = freq; @@ -129,9 +160,9 @@ class FuncProfInfo { // Raw arc coverage counts. unsigned edgeCounts; MapleVector counts; - uint64_t entry_freq; // record entry bb frequence - std::unordered_map stmtFreqs; // stmt_id is key, counter value - uint64_t real_entryfreq; // function prof data may be modified after clone/inline + uint64_t entry_freq; // record entry bb frequence + std::unordered_map stmtFreqs; // stmt_id is key, counter value + uint64_t real_entryfreq; // function prof data may be modified after clone/inline }; class MplProfileData { @@ -140,7 +171,7 @@ class MplProfileData { FuncProfInfo *GetFuncProfile(unsigned puidx) { if (funcsCounter.count(puidx) > 0) { - return funcsCounter[puidx]; + return funcsCounter[puidx]; } return nullptr; } @@ -156,12 +187,18 @@ class MplProfileData { } void DumpProfileData(); void DumpFunctionsProfile(); - MapleUnorderedMap funcsCounter; // use puidx as key + bool IsHotCallSite(uint64_t freq); + + MapleUnorderedMap funcsCounter; // use puidx as key // record module profile information and statistics of count information ProfileSummary summary; -private: + uint64_t hotCountThreshold = 0; + + private: + uint64_t GetHotThreshold(); + MemPool *mp; MapleAllocator *alloc; }; -} // end namespace -#endif // MAPLE_UTIL_INCLUDE_MPL_PROFDATA_H +} // namespace maple +#endif // MAPLE_UTIL_INCLUDE_MPL_PROFDATA_H diff --git a/src/mapleall/maple_util/src/mpl_profdata.cpp b/src/mapleall/maple_util/src/mpl_profdata.cpp index 64e37ed9c0..16ef9da267 100644 --- a/src/mapleall/maple_util/src/mpl_profdata.cpp +++ b/src/mapleall/maple_util/src/mpl_profdata.cpp @@ -13,26 +13,29 @@ * See the Mulan PSL v2 for more details. */ #include "mpl_profdata.h" + #include "mpl_logging.h" +#include "option.h" + namespace maple { void ProfileSummary::DumpSummary() { LogInfo::MapleLogger() << "---------ProfileSummary-------------- \n"; LogInfo::MapleLogger() << " checkSum: " << std::hex << "0x" << checkSum << "\n"; - LogInfo::MapleLogger() << " runtimes: " << std::dec << run << "\n"; - LogInfo::MapleLogger() << " totalCounts: " << std::dec << totalCount << "\n"; + LogInfo::MapleLogger() << " runtimes: " << std::dec << run << "\n"; + LogInfo::MapleLogger() << " totalCounts: " << std::dec << totalCount << "\n"; LogInfo::MapleLogger() << " maxCount: " << std::dec << maxCount << "\n"; LogInfo::MapleLogger() << " count histogram: countRange countNum minCount cumCount \n"; for (auto &it : histogram) { - LogInfo::MapleLogger() <<" " << std::dec << it.startValue << "\t"; - LogInfo::MapleLogger() << std::dec << it. countNums<< "\t" << it.countMinVal << "\t" << it.countCumValue << "\n"; + LogInfo::MapleLogger() << " " << std::dec << it.startValue << "\t"; + LogInfo::MapleLogger() << std::dec << it.countNums << "\t" << it.countMinVal << "\t" << it.countCumValue << "\n"; } } void FuncProfInfo::DumpFunctionProfile() { LogInfo::MapleLogger() << "function ident " << std::dec << ident; LogInfo::MapleLogger() << " lino_checksum 0x" << std::hex << linenoChecksum << ", "; - LogInfo::MapleLogger() << " cfg_checksum 0x" << std::hex << cfgChecksum << "\n"; - LogInfo::MapleLogger() << " num_counts " << std::dec << edgeCounts << " : "; + LogInfo::MapleLogger() << " cfg_checksum 0x" << std::hex << cfgChecksum << "\n"; + LogInfo::MapleLogger() << " num_counts " << std::dec << edgeCounts << " : "; for (int i = 0; i < edgeCounts; i++) { LogInfo::MapleLogger() << std::dec << " " << counts[i]; } @@ -50,4 +53,48 @@ void MplProfileData::DumpProfileData() { summary.DumpSummary(); DumpFunctionsProfile(); } -} // endof namespace + +void ProfileSummary::ProcessHistogram() { + int countsum = 0; + int n = histogram.size(); + for (int i = n - 1; i >= 0; i--) { + countsum += histogram[i].countNums; + histogram[i].countRatio = ((float)(countsum) / (float)totalCount) * 100; + } +} + +#define HOTRATIO 90 +uint64_t MplProfileData::GetHotThreshold() { + for (auto &it : summary.GetHistogram()) { + if (it.countRatio >= HOTRATIO) { + hotCountThreshold = it.startValue; + } else { + if (hotCountThreshold == 0) { + hotCountThreshold = it.countMinVal; // set minValue in currentRange which satisfy hot ratio + } + return hotCountThreshold; + } + } + // should not be here + return 100; +} + +bool MplProfileData::IsHotCallSite(uint64_t freq) { + auto &h = summary.GetHistogram(); + if (hotCountThreshold == 0) { + if (Options::profileHotCountSeted) { + hotCountThreshold = Options::profileHotCount; + } else if (summary.GetTotalCount() > 0 && !h.empty() && h[0].countRatio == 0) { + // init countRatio and compute hotCountThreshold + summary.ProcessHistogram(); + hotCountThreshold = GetHotThreshold(); + } else if (h.empty()) { + // should not be here + ASSERT(0, "should not be here"); + hotCountThreshold = 1; + } + } + return freq >= hotCountThreshold; +} + +} // namespace maple diff --git a/src/mapleall/mpl2mpl/include/inline_transformer.h b/src/mapleall/mpl2mpl/include/inline_transformer.h index 1569f9b900..78137411b9 100644 --- a/src/mapleall/mpl2mpl/include/inline_transformer.h +++ b/src/mapleall/mpl2mpl/include/inline_transformer.h @@ -55,9 +55,8 @@ class InlineTransformer { callee(callee), callStmt(callStmt), dumpDetail(dumpDetail), - cg(cg) { - updateFreq = (Options::profileUse && caller.GetFuncProfData() && callee.GetFuncProfData()); - }; + cg(cg), + updateFreq(Options::profileUse && caller.GetFuncProfData() && callee.GetFuncProfData()){}; bool PerformInline(BlockNode &enclosingBlk); static void ReplaceSymbols(BaseNode*, uint32, const std::vector*); diff --git a/src/mapleall/mpl2mpl/src/call_graph.cpp b/src/mapleall/mpl2mpl/src/call_graph.cpp index ba629b6b56..cf25cc58b5 100644 --- a/src/mapleall/mpl2mpl/src/call_graph.cpp +++ b/src/mapleall/mpl2mpl/src/call_graph.cpp @@ -14,7 +14,6 @@ */ #include "call_graph.h" - #include "option.h" #include "retype.h" #include "string_utils.h" @@ -201,7 +200,7 @@ uint64_t CGNode::GetCallsiteFrequency(const StmtNode *callstmt) const { uint64_t CGNode::GetFuncFrequency() const { FuncProfInfo *funcInfo = mirFunc->GetFuncProfData(); if (funcInfo) { - return funcInfo->GetFuncFrequency(); + return funcInfo->GetFuncRealFrequency(); } ASSERT(0, "should not be here"); return 0; @@ -256,8 +255,8 @@ void CallGraph::DelNode(CGNode &node) { } } -CallGraph::CallGraph(MIRModule &m, MemPool &memPool, MemPool &templPool, - const KlassHierarchy &kh, const std::string &fn) +CallGraph::CallGraph(MIRModule &m, MemPool &memPool, MemPool &templPool, const KlassHierarchy &kh, + const std::string &fn) : AnalysisResult(&memPool), mirModule(&m), cgAlloc(&memPool), @@ -523,7 +522,7 @@ void CallGraph::RecordLocalConstValue(const StmtNode *stmt) { CallNode *CallGraph::ReplaceIcallToCall(BlockNode &body, IcallNode *icall, PUIdx newPUIdx) { MapleVector opnds(icall->GetNopnd().begin() + 1, icall->GetNopnd().end(), - CurFunction()->GetCodeMPAllocator().Adapter()); + CurFunction()->GetCodeMPAllocator().Adapter()); CallNode *newCall = nullptr; if (icall->GetOpCode() == OP_icall) { newCall = mirBuilder->CreateStmtCall(newPUIdx, opnds, OP_call); @@ -746,8 +745,8 @@ void CallGraph::HandleICall(BlockNode &body, CGNode &node, StmtNode *stmt, uint3 icallToFix.insert({funcType->GetTypeIndex(), tempSet}); } CHECK_FATAL(CurFunction()->GetPuidx() == node.GetPuIdx(), "Error"); - Callsite callSite = { callInfo, node.GetCallee().at(callInfo) }; - icallToFix.at(funcType->GetTypeIndex())->insert({ node.GetPuIdx(), callSite }); + Callsite callSite = {callInfo, node.GetCallee().at(callInfo)}; + icallToFix.at(funcType->GetTypeIndex())->insert({node.GetPuIdx(), callSite}); } void CallGraph::HandleBody(MIRFunction &func, BlockNode &body, CGNode &node, uint32 loopDepth) { @@ -1232,7 +1231,7 @@ void DoDevirtual(const Klass &klass, const KlassHierarchy &klassh) { Opcode op = stmt->GetOpCode(); switch (op) { case OP_comment: - CASE_OP_ASSERT_NONNULL + CASE_OP_ASSERT_NONNULL case OP_brtrue: case OP_brfalse: case OP_try: @@ -1501,7 +1500,7 @@ void DoDevirtual(const Klass &klass, const KlassHierarchy &klassh) { } } } - [[clang::fallthrough]]; + [[clang::fallthrough]]; case OP_call: case OP_callassigned: { CallNode *callNode = static_cast(stmt); @@ -1556,8 +1555,9 @@ void IPODevirtulize::DevirtualFinal() { if (GlobalTables::GetGsymTable().GetSymbolFromStrIdx(classType->GetStaticFieldsGStrIdx(i)) == nullptr) { continue; } - TyIdx tyIdx = GlobalTables::GetGsymTable().GetSymbolFromStrIdx( - classType->GetStaticFieldsPair(i).first)->GetInferredTyIdx(); + TyIdx tyIdx = GlobalTables::GetGsymTable() + .GetSymbolFromStrIdx(classType->GetStaticFieldsPair(i).first) + ->GetInferredTyIdx(); if (tyIdx != kInitTyIdx && tyIdx != kNoneTyIdx) { CHECK_FATAL(attribute.GetAttr(FLDATTR_final), "Must be final private"); if (debugFlag) { @@ -1743,10 +1743,10 @@ void CallGraph::RemoveFileStaticRootNodes() { [](const CGNode *root) { // root means no caller, we should also make sure that root is not be used in addroffunc auto mirFunc = root->GetMIRFunction(); - return root != nullptr && mirFunc != nullptr && // remove before - // if static functions or inline but not extern modified functions are not used anymore, - // they can be removed safely. - !root->IsAddrTaken() && (mirFunc->IsStatic() || (mirFunc->IsInline() && !mirFunc->IsExtern())); + return root != nullptr && mirFunc != nullptr && // remove before + // if static functions or inline but not extern modified functions are not used anymore, + // they can be removed safely. + !root->IsAddrTaken() && (mirFunc->IsStatic() || (mirFunc->IsInline() && !mirFunc->IsExtern())); }); for (auto *root : staticRoots) { // DFS delete root and its callee that is static and have no caller after root is deleted diff --git a/src/mapleall/mpl2mpl/src/inline.cpp b/src/mapleall/mpl2mpl/src/inline.cpp index 4b7543ee76..c5812daff9 100644 --- a/src/mapleall/mpl2mpl/src/inline.cpp +++ b/src/mapleall/mpl2mpl/src/inline.cpp @@ -117,7 +117,7 @@ void MInline::InitRCWhiteList() { void MInline::InitExcludedCaller() { std::set specialfunc = { - std::string("Landroid_2Fcontent_2Fpm_2FFallbackCategoryProvider_3B_7CloadFallbacks_7C_28_29V"), + std::string("Landroid_2Fcontent_2Fpm_2FFallbackCategoryProvider_3B_7CloadFallbacks_7C_28_29V"), }; for (auto it = specialfunc.begin(); it != specialfunc.end(); ++it) { GStrIdx strIdx = GlobalTables::GetStrTable().GetStrIdxFromName(*it); @@ -140,27 +140,40 @@ void MInline::InitExcludedCallee() { (void)excludedCallee.insert(strIdx); } std::set setArrayHotFunc = { - std::string("Landroid_2Ficu_2Fimpl_2Fduration_2FBasicDurationFormat_3B_7CformatDuration_7C_28Ljava_2Flang_2FObject_3B_29Ljava_2Flang_2FString_3B"), - std::string("Landroid_2Fapp_2FIActivityManager_24Stub_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_3BLandroid_2Fos_2FParcel_3BI_29Z"), - std::string("Landroid_2Fcontent_2Fpm_2FIPackageManager_24Stub_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_3BLandroid_2Fos_2FParcel_3BI_29Z"), - std::string("Landroid_2Fcontent_2FIContentService_24Stub_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_3BLandroid_2Fos_2FParcel_3BI_29Z"), - std::string("Lcom_2Fandroid_2Fserver_2Fam_2FHwActivityManagerService_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_3BLandroid_2Fos_2FParcel_3BI_29Z"), - std::string("Lcom_2Fandroid_2Fserver_2Fam_2FActivityManagerService_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_3BLandroid_2Fos_2FParcel_3BI_29Z"), - std::string("Ljava_2Flang_2Freflect_2FMethod_3B_7Cinvoke_7C_28Ljava_2Flang_2FObject_3BALjava_2Flang_2FObject_3B_29Ljava_2Flang_2FObject_3B"), + std::string("Landroid_2Ficu_2Fimpl_2Fduration_2FBasicDurationFormat_3B_7CformatDuration_7C_28Ljava_2Flang_" + "2FObject_3B_29Ljava_2Flang_2FString_3B"), + std::string("Landroid_2Fapp_2FIActivityManager_24Stub_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_3BLandroid_" + "2Fos_2FParcel_3BI_29Z"), + std::string("Landroid_2Fcontent_2Fpm_2FIPackageManager_24Stub_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_" + "3BLandroid_2Fos_2FParcel_3BI_29Z"), + std::string("Landroid_2Fcontent_2FIContentService_24Stub_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_3BLandroid_" + "2Fos_2FParcel_3BI_29Z"), + std::string("Lcom_2Fandroid_2Fserver_2Fam_2FHwActivityManagerService_3B_7ConTransact_7C_28ILandroid_2Fos_" + "2FParcel_3BLandroid_2Fos_2FParcel_3BI_29Z"), + std::string("Lcom_2Fandroid_2Fserver_2Fam_2FActivityManagerService_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_" + "3BLandroid_2Fos_2FParcel_3BI_29Z"), + std::string("Ljava_2Flang_2Freflect_2FMethod_3B_7Cinvoke_7C_28Ljava_2Flang_2FObject_3BALjava_2Flang_2FObject_3B_" + "29Ljava_2Flang_2FObject_3B"), std::string("Lcom_2Fandroid_2Fserver_2FSystemServer_3B_7Crun_7C_28_29V"), - std::string("Lcom_2Fandroid_2Finternal_2Ftelephony_2FIPhoneStateListener_24Stub_24Proxy_3B_7ConMessageWaitingIndicatorChanged_7C_28Z_29V"), + std::string("Lcom_2Fandroid_2Finternal_2Ftelephony_2FIPhoneStateListener_24Stub_24Proxy_3B_" + "7ConMessageWaitingIndicatorChanged_7C_28Z_29V"), std::string("Landroid_2Fview_2Fanimation_2FTransformation_3B_7C_3Cinit_3E_7C_28_29V"), std::string("Lcom_2Fandroid_2Fserver_2FSystemServer_3B_7CstartOtherServices_7C_28_29V"), std::string("Lcom_2Fandroid_2Fserver_2Fpm_2FSettings_3B_7CreadLPw_7C_28Ljava_2Futil_2FList_3B_29Z"), std::string("Lcom_2Fandroid_2Fserver_2Fam_2FActivityManagerService_3B_7CupdateOomAdjLocked_7C_28_29V"), - std::string("Lcom_2Fandroid_2Fserver_2Fpm_2FHwPackageManagerService_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_3BLandroid_2Fos_2FParcel_3BI_29Z"), - std::string("Lcom_2Fandroid_2Fserver_2Fpm_2FPackageManagerService_3B_7CgeneratePackageInfo_7C_28Lcom_2Fandroid_2Fserver_2Fpm_2FPackageSetting_3BII_29Landroid_2Fcontent_2Fpm_2FPackageInfo_3B"), - std::string("Ljava_2Flang_2FThrowable_3B_7CprintStackTrace_7C_28Ljava_2Flang_2FThrowable_24PrintStreamOrWriter_3B_29V"), + std::string("Lcom_2Fandroid_2Fserver_2Fpm_2FHwPackageManagerService_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_" + "3BLandroid_2Fos_2FParcel_3BI_29Z"), + std::string("Lcom_2Fandroid_2Fserver_2Fpm_2FPackageManagerService_3B_7CgeneratePackageInfo_7C_28Lcom_2Fandroid_" + "2Fserver_2Fpm_2FPackageSetting_3BII_29Landroid_2Fcontent_2Fpm_2FPackageInfo_3B"), + std::string( + "Ljava_2Flang_2FThrowable_3B_7CprintStackTrace_7C_28Ljava_2Flang_2FThrowable_24PrintStreamOrWriter_3B_29V"), std::string("Lcom_2Fandroid_2Fserver_2FSystemServer_3B_7CstartBootstrapServices_7C_28_29V"), std::string("Ljava_2Flang_2FThrowable_3B_7CgetOurStackTrace_7C_28_29ALjava_2Flang_2FStackTraceElement_3B"), std::string("Ldalvik_2Fsystem_2FVMStack_3B_7CgetStackClass2_7C_28_29Ljava_2Flang_2FClass_3B"), - std::string("Lcom_2Fandroid_2Fserver_2Fam_2FActivityManagerService_3B_7CattachApplicationLocked_7C_28Landroid_2Fapp_2FIApplicationThread_3BI_29Z"), - std::string("Lcom_2Fandroid_2Fserver_2FInputMethodManagerService_3B_7ChideCurrentInputLocked_7C_28ILandroid_2Fos_2FResultReceiver_3B_29Z"), + std::string("Lcom_2Fandroid_2Fserver_2Fam_2FActivityManagerService_3B_7CattachApplicationLocked_7C_28Landroid_" + "2Fapp_2FIApplicationThread_3BI_29Z"), + std::string("Lcom_2Fandroid_2Fserver_2FInputMethodManagerService_3B_7ChideCurrentInputLocked_7C_28ILandroid_2Fos_" + "2FResultReceiver_3B_29Z"), }; for (auto it = setArrayHotFunc.begin(); it != setArrayHotFunc.end(); ++it) { GStrIdx strIdx = GlobalTables::GetStrTable().GetStrIdxFromName(*it); @@ -251,7 +264,7 @@ FuncCostResultType MInline::GetFuncCost(const MIRFunction &func, const BaseNode break; } } - [[clang::fallthrough]]; + [[clang::fallthrough]]; case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_customcall: @@ -423,15 +436,17 @@ bool MInline::IsHotCallSite(const MIRFunction &caller, const MIRFunction &callee } // use maple instrument profile if (Options::profileUse) { - return caller.GetFuncProfData()->IsHotCallSite(callStmt.GetStmtID()); + if (!caller.GetFuncProfData()) return false; + int64_t freq = caller.GetFuncProfData()->GetStmtFreq(callStmt.GetStmtID()); + ASSERT(freq > 0, "sanity check"); + return module.GetMapleProfile()->IsHotCallSite((uint64_t)freq); } return module.GetProfile().CheckFuncHot(caller.GetName()); } bool MInline::FuncInlinable(const MIRFunction &func) const { std::string name = func.GetName(); - if (StringUtils::StartsWith(name, kReflectionClassStr) || - StringUtils::StartsWith(name, kJavaLangClassesStr) || + if (StringUtils::StartsWith(name, kReflectionClassStr) || StringUtils::StartsWith(name, kJavaLangClassesStr) || StringUtils::StartsWith(name, kJavaLangReferenceStr)) { return false; } @@ -686,7 +701,7 @@ static InlineResult GetInlineResult(uint32 threshold, uint32 thresholdType, uint } void MInline::AdjustInlineThreshold(const MIRFunction &caller, const MIRFunction &callee, const CallNode &callStmt, - uint32 &threshold, uint32 &thresholdType) { + uint32 &threshold, uint32 &thresholdType) { // Update threshold if this callsite is hot, or dealing with recursive function if (inlineWithProfile && IsHotCallSite(caller, callee, callStmt)) { threshold = hotFuncThreshold; @@ -705,9 +720,7 @@ void MInline::AdjustInlineThreshold(const MIRFunction &caller, const MIRFunction threshold <<= kRelaxThresholdForInlineHint; } // We don't always inline called_once callee to avoid super big caller - if (module.GetSrcLang() == kSrcLangC && - callee.GetAttr(FUNCATTR_called_once) && - callee.GetAttr(FUNCATTR_static)) { + if (module.GetSrcLang() == kSrcLangC && callee.GetAttr(FUNCATTR_called_once) && callee.GetAttr(FUNCATTR_static)) { threshold <<= kRelaxThresholdForCalledOnce; } } diff --git a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp index de5c758b74..ef050a798f 100644 --- a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp +++ b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp @@ -13,22 +13,26 @@ * See the Mulan PSL v2 for more details. */ -#include -#include -#include +#include "mpl_profdata_parser.h" + #include +#include #include +#include +#include +#include + #include #include -#include #include -#include "option.h" + #include "mpl_logging.h" -#include "mpl_profdata_parser.h" +#include "option.h" namespace maple { -template T ProfDataBinaryImportBase::ReadNum() { +template +T ProfDataBinaryImportBase::ReadNum() { unsigned NumBytesRead = 0; uint64_t Val = namemangler::DecodeULEB128(pos, &NumBytesRead); @@ -40,7 +44,7 @@ int ProfileSummaryImport::ReadSummary(MplProfileData *profData) { CHECK_FATAL(profData != nullptr, "sanity check"); uint64_t magicNum = ReadNum(); if (magicNum != kMapleProfDataMagicNumber) { - LogInfo::MapleLogger() << "magic number error, quit\n"; + LogInfo::MapleLogger() << "magic number error, quit\n"; return 1; } uint64_t checksum = ReadNum(); @@ -85,7 +89,7 @@ int FunctionProfileImport::ReadFuncProfile(MplProfileData *profData) { int MplProfDataParser::ReadMapleProfileData() { std::string mprofDataFile = Options::profile; if (mprofDataFile.empty()) { - if (const char* env_p = std::getenv("GCOV_PREFIX")) { + if (const char *env_p = std::getenv("GCOV_PREFIX")) { mprofDataFile.append(env_p); } else { mprofDataFile.append("."); @@ -105,18 +109,18 @@ int MplProfDataParser::ReadMapleProfileData() { return 1; } // get length of file - inputStream.seekg (0, inputStream.end); + inputStream.seekg(0, inputStream.end); int length = inputStream.tellg(); - inputStream.seekg (0, inputStream.beg); - const uint32_t sizeThreshold = 1024*10; + inputStream.seekg(0, inputStream.beg); + const uint32_t sizeThreshold = 1024 * 10; CHECK_FATAL(length <= sizeThreshold, "NYI::large .mprofdata file size is larger than threashold, do chunk memory\n"); std::unique_ptr buffer(new char[sizeof(char) * length]()); - inputStream.read (buffer.get(), length); + inputStream.read(buffer.get(), length); inputStream.close(); // read 1st part summary ProfileSummaryImport summaryImport(mprofDataFile, inputStream); - summaryImport.SetPosition((uint8_t *)buffer.get()); + summaryImport.SetPosition((uint8_t*)buffer.get()); int res = summaryImport.ReadSummary(profData); if (res) { LogInfo::MapleLogger() << "no summary part\n"; @@ -144,9 +148,9 @@ void MMplProfDataParser::GetAnalysisDependence(AnalysisDep &aDep) const { } bool MMplProfDataParser::PhaseRun(maple::MIRModule &m) { - - MemPool *memPool = m.GetMemPool(); // use global pool to store profile data - MplProfDataParser parser(m, memPool, true/*debug*/); + MemPool *memPool = m.GetMemPool(); // use global pool to store profile data + bool enableDebug = false; + MplProfDataParser parser(m, memPool, enableDebug); int res = parser.ReadMapleProfileData(); if (res) { // something wrong @@ -158,5 +162,4 @@ bool MMplProfDataParser::PhaseRun(maple::MIRModule &m) { return true; } - -} // end namespace maple +} // end namespace maple -- Gitee From 41aac20ffd3e95a65f8b7b24b08c7d77849bc2a7 Mon Sep 17 00:00:00 2001 From: linma Date: Fri, 29 Jul 2022 07:38:14 -0700 Subject: [PATCH 03/16] pgo: refine profiledata name and locations --- src/mapleall/maple_ir/include/mir_module.h | 11 +++-- src/mapleall/maple_ir/src/mir_nodes.cpp | 21 ++++---- .../mpl2mpl/src/mpl_profdata_parser.cpp | 48 ++++++++++++++++--- 3 files changed, 61 insertions(+), 19 deletions(-) diff --git a/src/mapleall/maple_ir/include/mir_module.h b/src/mapleall/maple_ir/include/mir_module.h index be748df3f5..f5965f008d 100644 --- a/src/mapleall/maple_ir/include/mir_module.h +++ b/src/mapleall/maple_ir/include/mir_module.h @@ -341,10 +341,13 @@ class MIRModule { } std::string GetProfileDataFileName() const { - std::string profileDataFileName = fileName.substr(0, fileName.find_last_of(".")); - std::replace(profileDataFileName.begin(), profileDataFileName.end(), '.', '_'); - std::replace(profileDataFileName.begin(), profileDataFileName.end(), '-', '_'); - std::replace(profileDataFileName.begin(), profileDataFileName.end(), '/', '_'); + std::string profileDataFileName = GetFileName().substr(0, GetFileName().find_last_of(".")); + char *gcov_path = std::getenv("GCOV_PREFIX"); + std::string gcov_prefix = gcov_path ? gcov_path : ""; + if (!gcov_prefix.empty() && (gcov_prefix.back() != '/')) { + gcov_prefix.append("/"); + } + profileDataFileName = gcov_prefix + profileDataFileName; return profileDataFileName; } diff --git a/src/mapleall/maple_ir/src/mir_nodes.cpp b/src/mapleall/maple_ir/src/mir_nodes.cpp index 0b37643e0a..1c9d267b67 100644 --- a/src/mapleall/maple_ir/src/mir_nodes.cpp +++ b/src/mapleall/maple_ir/src/mir_nodes.cpp @@ -686,10 +686,11 @@ void AddroflabelNode::Dump(int32 indent [[maybe_unused]]) const { void StmtNode::DumpBase(int32 indent) const { srcPosition.DumpLoc(lastPrintedLineNum, lastPrintedColumnNum); // 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"; + if (Options::profileUse && theMIRModule->CurFunction()->GetFuncProfData()) { + int64_t freq = static_cast(theMIRModule->CurFunction()->GetFuncProfData()->GetStmtFreq(GetStmtID())); + if (freq >= 0) { + LogInfo::MapleLogger() << "stmtID " << GetStmtID() << " freq " << freq << "\n"; + } } PrintIndentation(indent); LogInfo::MapleLogger() << kOpcodeInfo.GetTableItemAt(GetOpCode()).name; @@ -1323,8 +1324,10 @@ void BlockNode::Dump(int32 indent, const MIRSymbolTable *theSymTab, MIRPregTable srcPosition.DumpLoc(lastPrintedLineNum, lastPrintedColumnNum); // dump stmtFreqs if (Options::profileUse && theMIRModule->CurFunction()->GetFuncProfData()) { - LogInfo::MapleLogger() << "stmtID " << GetStmtID() << " freq " << - theMIRModule->CurFunction()->GetFuncProfData()->GetStmtFreq(GetStmtID()) << "\n"; + int64_t freq = static_cast(theMIRModule->CurFunction()->GetFuncProfData()->GetStmtFreq(GetStmtID())); + if (freq >= 0) { + LogInfo::MapleLogger() << "stmtID " << GetStmtID() << " freq " << freq << "\n"; + } } for (auto &stmt : GetStmtNodes()) { stmt.Dump(indent + 1); @@ -1339,8 +1342,10 @@ void LabelNode::Dump(int32 indent [[maybe_unused]]) const { } // dump stmtFreqs if (Options::profileUse && theMIRModule->CurFunction()->GetFuncProfData()) { - LogInfo::MapleLogger() << "stmtID " << GetStmtID() << " freq " << - theMIRModule->CurFunction()->GetFuncProfData()->GetStmtFreq(GetStmtID()) << "\n"; + int64_t freq = static_cast(theMIRModule->CurFunction()->GetFuncProfData()->GetStmtFreq(GetStmtID())); + if (freq >= 0) { + LogInfo::MapleLogger() << "stmtID " << GetStmtID() << " freq " << freq << "\n"; + } } LogInfo::MapleLogger() << "@" << theMIRModule->CurFunction()->GetLabelName(labelIdx) << " "; } diff --git a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp index ef050a798f..4d686e42ee 100644 --- a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp +++ b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp @@ -89,17 +89,51 @@ int FunctionProfileImport::ReadFuncProfile(MplProfileData *profData) { int MplProfDataParser::ReadMapleProfileData() { std::string mprofDataFile = Options::profile; if (mprofDataFile.empty()) { - if (const char *env_p = std::getenv("GCOV_PREFIX")) { - mprofDataFile.append(env_p); + if (const char *env_gcovprefix = std::getenv("GCOV_PREFIX")) { + mprofDataFile.append(env_gcovprefix); + if (mprofDataFile.back() != '/') { + mprofDataFile.append("/"); + } + if (dumpDetail) { + LogInfo::MapleLogger() << "set env gcov_prefix= " << mprofDataFile << std::endl; + } + uint32_t stripnum = 0; + if (const char *env_gcovprefixstrip = std::getenv("GCOV_PREFIX_STRIP")) { + std::string strip(env_gcovprefixstrip); + stripnum = std::stoi(strip); + if (dumpDetail) { + LogInfo::MapleLogger() << "set env gcov_prefix_strip=" << strip << std::endl; + } + } + std::string profDataFileName = m.GetProfileDataFileName(); + if (dumpDetail) { + LogInfo::MapleLogger() << "module profdata Name: " << profDataFileName << std::endl; + } + // reduce path in profDataFileName + while (stripnum > 0 && profDataFileName.size() > 1) { + auto pos = profDataFileName.find_first_of("/", 1); + profDataFileName = profDataFileName.substr(pos); + stripnum--; + } + if (dumpDetail) { + LogInfo::MapleLogger() << "after strip, module profdata Name: " << profDataFileName << std::endl; + } + CHECK_FATAL(profDataFileName.size() > 0, "sanity check"); + mprofDataFile.append(profDataFileName); } else { - mprofDataFile.append("."); + // if gcov_prefix is not set, find .mprofdata according to m.profiledata + mprofDataFile = m.GetProfileDataFileName(); + if (dumpDetail) { + LogInfo::MapleLogger() << "NO ENV, module profdata Name: " << mprofDataFile << std::endl; + } } - mprofDataFile.append("/"); - mprofDataFile.append(m.GetProfileDataFileName()); + // add .mprofdata mprofDataFile.append(namemangler::kMplProfFileNameExt); } ASSERT(!mprofDataFile.empty(), "null check"); - + if (dumpDetail) { + LogInfo::MapleLogger() << "will open mprofileData " << mprofDataFile << std::endl; + } // create mpl profdata profData = mempool->New(mempool, &alloc); // read .mprofdata @@ -149,7 +183,7 @@ void MMplProfDataParser::GetAnalysisDependence(AnalysisDep &aDep) const { bool MMplProfDataParser::PhaseRun(maple::MIRModule &m) { MemPool *memPool = m.GetMemPool(); // use global pool to store profile data - bool enableDebug = false; + bool enableDebug = false; // true to dump trace MplProfDataParser parser(m, memPool, enableDebug); int res = parser.ReadMapleProfileData(); if (res) { -- Gitee From 365812836d894255b4e830e4f4ce44e874976377 Mon Sep 17 00:00:00 2001 From: linma Date: Fri, 29 Jul 2022 07:43:04 -0700 Subject: [PATCH 04/16] missed file --- src/mapleall/mpl2mpl/src/gen_profile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mapleall/mpl2mpl/src/gen_profile.cpp b/src/mapleall/mpl2mpl/src/gen_profile.cpp index b586d91474..cff72a9561 100644 --- a/src/mapleall/mpl2mpl/src/gen_profile.cpp +++ b/src/mapleall/mpl2mpl/src/gen_profile.cpp @@ -106,7 +106,7 @@ void ProfileGen::CreateModProfDesc() { // Make the profile file name as fileName.gcda std::string profFileName = mod.GetProfileDataFileName() + namemangler::kProfFileNameExt; auto *profileFNMirConst = - modMP->New("./" + profFileName, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(PTY_a64))); + modMP->New(profFileName, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(PTY_a64))); modProfDescSymMirConst->AddItem(profileFNMirConst, 6); // Additional profiling (in addition to frequency profiling) should be added here -- Gitee From ce939e683173e5d5e27fbbc0543e7c07517ae94a Mon Sep 17 00:00:00 2001 From: linma Date: Thu, 21 Jul 2022 13:19:17 -0700 Subject: [PATCH 05/16] pgo: rewrite profile data parser to accept maple profile data format --- src/mapleall/maple_ipa/src/ipa_clone.cpp | 4 +- .../maple_ipa/src/ipa_phase_manager.cpp | 6 +- src/mapleall/maple_ir/include/mir_function.h | 8 +- src/mapleall/maple_ir/include/mir_lower.h | 2 +- src/mapleall/maple_ir/include/mir_module.h | 13 +- .../maple_me/include/me_profile_use.h | 5 +- src/mapleall/maple_me/include/pme_emit.h | 2 +- src/mapleall/maple_me/src/me_cfg.cpp | 4 +- src/mapleall/maple_me/src/me_profile_use.cpp | 26 +- src/mapleall/maple_util/BUILD.gn | 1 + .../{gcov_profile.h => mpl_profdata.h} | 115 ++++-- src/mapleall/maple_util/include/namemangler.h | 5 + src/mapleall/maple_util/src/mpl_profdata.cpp | 53 +++ src/mapleall/maple_util/src/namemangler.cpp | 92 +++++ src/mapleall/mpl2mpl/BUILD.gn | 2 +- src/mapleall/mpl2mpl/include/gcov_parser.h | 117 ------ .../mpl2mpl/include/inline_transformer.h | 6 +- .../mpl2mpl/include/mpl_profdata_parser.h | 111 ++++++ src/mapleall/mpl2mpl/src/call_graph.cpp | 4 +- src/mapleall/mpl2mpl/src/gcov_parser.cpp | 359 ------------------ src/mapleall/mpl2mpl/src/gen_profile.cpp | 2 +- src/mapleall/mpl2mpl/src/inline.cpp | 4 +- .../mpl2mpl/src/inline_transformer.cpp | 17 +- .../mpl2mpl/src/module_phase_manager.cpp | 4 +- .../mpl2mpl/src/mpl_profdata_parser.cpp | 162 ++++++++ 25 files changed, 567 insertions(+), 557 deletions(-) rename src/mapleall/maple_util/include/{gcov_profile.h => mpl_profdata.h} (37%) create mode 100644 src/mapleall/maple_util/src/mpl_profdata.cpp delete mode 100644 src/mapleall/mpl2mpl/include/gcov_parser.h create mode 100644 src/mapleall/mpl2mpl/include/mpl_profdata_parser.h delete mode 100644 src/mapleall/mpl2mpl/src/gcov_parser.cpp create mode 100644 src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp diff --git a/src/mapleall/maple_ipa/src/ipa_clone.cpp b/src/mapleall/maple_ipa/src/ipa_clone.cpp index b439e6fe0f..86cb99ee51 100644 --- a/src/mapleall/maple_ipa/src/ipa_clone.cpp +++ b/src/mapleall/maple_ipa/src/ipa_clone.cpp @@ -140,9 +140,9 @@ MIRFunction *IpaClone::IpaCloneFunctionWithFreq(MIRFunction &originalFunction, newFunc->SetBaseClassFuncNames(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fullName)); newFunc->GetFuncSymbol()->SetAppearsInCode(true); newFunc->SetPuidxOrigin(newFunc->GetPuidx()); - GcovFuncInfo *origProfData = originalFunction.GetFuncProfData(); + FuncProfInfo *origProfData = originalFunction.GetFuncProfData(); auto *moduleMp = mirBuilder.GetMirModule().GetMemPool(); - GcovFuncInfo *newProfData = moduleMp->New(&mirBuilder.GetMirModule().GetMPAllocator(), + FuncProfInfo *newProfData = moduleMp->New(&mirBuilder.GetMirModule().GetMPAllocator(), newFunc->GetPuidx(), 0, 0); // skip checksum information newFunc->SetFuncProfData(newProfData); newProfData->SetFuncFrequency(callSiteFreq); diff --git a/src/mapleall/maple_ipa/src/ipa_phase_manager.cpp b/src/mapleall/maple_ipa/src/ipa_phase_manager.cpp index e2271b3f5f..d473d76cb5 100644 --- a/src/mapleall/maple_ipa/src/ipa_phase_manager.cpp +++ b/src/mapleall/maple_ipa/src/ipa_phase_manager.cpp @@ -14,7 +14,7 @@ */ #include "ipa_phase_manager.h" #include "pme_emit.h" -#include "gcov_parser.h" +#include "mpl_profdata_parser.h" #define JAVALANG (mirModule.IsJavaModule()) #define CLANG (mirModule.IsCModule()) @@ -102,8 +102,8 @@ void IpaSccPM::GetAnalysisDependence(maple::AnalysisDep &aDep) const { aDep.AddPreserved(); aDep.AddPreserved(); if (Options::profileUse) { - aDep.AddRequired(); - aDep.AddPreserved(); + aDep.AddRequired(); + aDep.AddPreserved(); } } diff --git a/src/mapleall/maple_ir/include/mir_function.h b/src/mapleall/maple_ir/include/mir_function.h index 51e2be56a5..4c41e1ebac 100644 --- a/src/mapleall/maple_ir/include/mir_function.h +++ b/src/mapleall/maple_ir/include/mir_function.h @@ -1271,13 +1271,13 @@ class MIRFunction { InlineSummary *GetOrCreateInlineSummary(); - void SetFuncProfData(GcovFuncInfo *data) { + void SetFuncProfData(FuncProfInfo *data) { funcProfData = data; } - GcovFuncInfo* GetFuncProfData() { + FuncProfInfo* GetFuncProfData() { return funcProfData; } - GcovFuncInfo* GetFuncProfData() const { + FuncProfInfo* GetFuncProfData() const { return funcProfData; } void SetStmtFreq(uint32_t stmtID, uint64_t freq) { @@ -1384,7 +1384,7 @@ class MIRFunction { uint32 nCtrs = 0; // number of counters uint64 fileLinenoChksum = 0; uint64 cfgChksum = 0; - GcovFuncInfo *funcProfData = nullptr; + FuncProfInfo *funcProfData = nullptr; InlineSummary *inlineSummary = nullptr; void DumpFlavorLoweredThanMmpl() const; MIRFuncType *ReconstructFormals(const std::vector &symbols, bool clearOldArgs); diff --git a/src/mapleall/maple_ir/include/mir_lower.h b/src/mapleall/maple_ir/include/mir_lower.h index c2261326d1..e4229aa853 100644 --- a/src/mapleall/maple_ir/include/mir_lower.h +++ b/src/mapleall/maple_ir/include/mir_lower.h @@ -142,7 +142,7 @@ class MIRLower { virtual bool InLFO() const { return false; } - GcovFuncInfo *GetFuncProfData() const { + FuncProfInfo *GetFuncProfData() const { return mirFunc->GetFuncProfData(); } void CopyStmtFrequency(StmtNode *newStmt, StmtNode *oldStmt) { diff --git a/src/mapleall/maple_ir/include/mir_module.h b/src/mapleall/maple_ir/include/mir_module.h index 37c54a99b3..be748df3f5 100644 --- a/src/mapleall/maple_ir/include/mir_module.h +++ b/src/mapleall/maple_ir/include/mir_module.h @@ -22,7 +22,7 @@ #include "muid.h" #include "profile.h" #include "namemangler.h" -#include "gcov_profile.h" +#include "mpl_profdata.h" #if MIR_FEATURE_FULL #include #include @@ -268,11 +268,11 @@ class MIRModule { return profile; } - GcovProfileData* GetGcovProfile() { - return gcovProfile; + MplProfileData* GetMapleProfile() { + return mplProfile; } - void SetGcovProfile(GcovProfileData* info) { - gcovProfile = info; + void SetMapleProfile(MplProfileData* info) { + mplProfile = info; } void SetSomeSymbolNeedForDecl(bool s) { @@ -345,7 +345,6 @@ class MIRModule { std::replace(profileDataFileName.begin(), profileDataFileName.end(), '.', '_'); std::replace(profileDataFileName.begin(), profileDataFileName.end(), '-', '_'); std::replace(profileDataFileName.begin(), profileDataFileName.end(), '/', '_'); - profileDataFileName = profileDataFileName + namemangler::kProfFileNameExt; return profileDataFileName; } @@ -710,7 +709,7 @@ class MIRModule { MapleSet symbolSet; MapleVector symbolDefOrder; Profile profile; - GcovProfileData* gcovProfile; + MplProfileData* mplProfile; bool someSymbolNeedForwDecl = false; // some symbols' addressses used in initialization std::ostream &out; diff --git a/src/mapleall/maple_me/include/me_profile_use.h b/src/mapleall/maple_me/include/me_profile_use.h index a6a0be8df7..2014e80026 100644 --- a/src/mapleall/maple_me/include/me_profile_use.h +++ b/src/mapleall/maple_me/include/me_profile_use.h @@ -137,8 +137,7 @@ class MeProfUse : public PGOInstrument { bool IsSuccUseProf() const { return succCalcuAllEdgeFreq; } - bool GcovRun(); - GcovFuncInfo *GetFuncData(); + bool MapleProfRun(); bool CheckSumFail(const uint64 hash, const uint32 expectedCheckSum, const std::string &tag); private: bool IsAllZero(Profile::BBInfo &result) const; @@ -147,6 +146,8 @@ class MeProfUse : public PGOInstrument { void ComputeEdgeFreq(); void InitBBEdgeInfo(); void ComputeBBFreq(BBUseInfo &bbInfo, bool &changed); + FuncProfInfo *GetFuncData(); + uint64 SumEdgesCount(const MapleVector &edges) const; BBUseInfo *GetBBUseInfo(const BB &bb) const; BBUseInfo *GetOrCreateBBUseInfo(const BB &bb) ; diff --git a/src/mapleall/maple_me/include/pme_emit.h b/src/mapleall/maple_me/include/pme_emit.h index 1a192138e6..19424dd4d1 100644 --- a/src/mapleall/maple_me/include/pme_emit.h +++ b/src/mapleall/maple_me/include/pme_emit.h @@ -79,7 +79,7 @@ class PreMeEmitter : public AnalysisResult { MapleAllocator* GetCodeMPAlloc() { return codeMPAlloc; } MapleMap *GetPreMeStmtExtensionMap() { return &PreMeStmtExtensionMap; } MapleMap *GetPreMeExprExtensionMap() { return &PreMeExprExtensionMap; } - GcovFuncInfo *GetFuncProfData() { return mirFunc->GetFuncProfData(); } + FuncProfInfo *GetFuncProfData() { return mirFunc->GetFuncProfData(); } private: ArrayNode *ConvertToArray(BaseNode *x, TyIdx ptrTyIdx); diff --git a/src/mapleall/maple_me/src/me_cfg.cpp b/src/mapleall/maple_me/src/me_cfg.cpp index bad79a8d57..a46f55b1da 100644 --- a/src/mapleall/maple_me/src/me_cfg.cpp +++ b/src/mapleall/maple_me/src/me_cfg.cpp @@ -1874,7 +1874,7 @@ void MeCFG::ConstructEdgeFreqFromBBFreq() { // set bb frequency from stmt record void MeCFG::ConstructBBFreqFromStmtFreq() { - GcovFuncInfo* funcData = func.GetMirFunc()->GetFuncProfData(); + FuncProfInfo* funcData = func.GetMirFunc()->GetFuncProfData(); if (!funcData) { return; } @@ -1914,7 +1914,7 @@ void MeCFG::ConstructBBFreqFromStmtFreq() { } void MeCFG::ConstructStmtFreq() { - GcovFuncInfo* funcData = func.GetMirFunc()->GetFuncProfData(); + FuncProfInfo* funcData = func.GetMirFunc()->GetFuncProfData(); if (!funcData) { return; } diff --git a/src/mapleall/maple_me/src/me_profile_use.cpp b/src/mapleall/maple_me/src/me_profile_use.cpp index 0a4d1ea0f7..4d9c62b6ad 100644 --- a/src/mapleall/maple_me/src/me_profile_use.cpp +++ b/src/mapleall/maple_me/src/me_profile_use.cpp @@ -294,12 +294,12 @@ bool MeProfUse::Run() { return true; } -GcovFuncInfo *MeProfUse::GetFuncData() { - GcovProfileData *gcovData = func->GetMIRModule().GetGcovProfile(); - if (!gcovData) { +FuncProfInfo *MeProfUse::GetFuncData() { + MplProfileData* profData = func->GetMIRModule().GetMapleProfile(); + if (!profData) { return nullptr; } - GcovFuncInfo *funcData = gcovData->GetFuncProfile(func->GetUniqueID()); + FuncProfInfo *funcData = profData->GetFuncProfile(func->GetUniqueID()); return funcData; } @@ -315,20 +315,20 @@ bool MeProfUse::CheckSumFail(const uint64 hash, const uint32 expectedCheckSum, c return false; } -bool MeProfUse::GcovRun() { - GcovFuncInfo *funcData = GetFuncData(); +bool MeProfUse::MapleProfRun() { + FuncProfInfo* funcData = GetFuncData(); if (!funcData) { return false; } func->GetMirFunc()->SetFuncProfData(funcData); // early return if lineno fail - if (CheckSumFail(ComputeLinenoHash(), funcData->lineno_checksum, "lineno")) { + if (CheckSumFail(ComputeLinenoHash(), funcData->linenoChecksum, "lineno")) { func->GetMirFunc()->SetFuncProfData(nullptr); // clear func profile data return false; } FindInstrumentEdges(); // early return if cfgchecksum fail - if (CheckSumFail(ComputeFuncHash(), funcData->cfg_checksum, "func")) { + if (CheckSumFail(ComputeFuncHash(), funcData->cfgChecksum, "func")) { return false; } std::vector instrumentBBs; @@ -336,10 +336,10 @@ bool MeProfUse::GcovRun() { if (dump) { DumpEdgeInfo(); } - if (instrumentBBs.size() != funcData->num_counts) { + if (instrumentBBs.size() != funcData->edgeCounts) { if (dump) { LogInfo::MapleLogger() << func->GetName() << " counter doesn't match profile counter " - << funcData->num_counts << " func real counter " << instrumentBBs.size() << '\n'; + << funcData->edgeCounts << " func real counter " << instrumentBBs.size() << '\n'; } func->GetMirFunc()->SetFuncProfData(nullptr); // clear func profile data return false; @@ -368,8 +368,10 @@ bool MEProfUse::PhaseRun(maple::MeFunction &f) { MeProfUse profUse(f, *GetPhaseMemPool(), DEBUGFUNC_NEWPM(f)); bool result = true; if (Options::profileUse) { - result = profUse.GcovRun(); - f.GetCfg()->VerifyBBFreq(); + result = profUse.MapleProfRun(); + if (result) { + f.GetCfg()->VerifyBBFreq(); + } } else { profUse.Run(); } diff --git a/src/mapleall/maple_util/BUILD.gn b/src/mapleall/maple_util/BUILD.gn index a7341eae06..09f912369e 100755 --- a/src/mapleall/maple_util/BUILD.gn +++ b/src/mapleall/maple_util/BUILD.gn @@ -27,6 +27,7 @@ src_libmplutil = [ "src/error_code.cpp", "src/thread_env.cpp", "src/mpl_int_val.cpp", + "src/mpl_profdata.cpp" ] src_libcommandline = [ diff --git a/src/mapleall/maple_util/include/gcov_profile.h b/src/mapleall/maple_util/include/mpl_profdata.h similarity index 37% rename from src/mapleall/maple_util/include/gcov_profile.h rename to src/mapleall/maple_util/include/mpl_profdata.h index baf50aa973..6aa8c1520f 100644 --- a/src/mapleall/maple_util/include/gcov_profile.h +++ b/src/mapleall/maple_util/include/mpl_profdata.h @@ -1,32 +1,26 @@ /* - * Copyright (c) [2022] Futurewei Technologies Co., Ltd. All rights reserved. + * Copyright (c) [2022] Futurewei Technologies, Inc. All rights reserved. * - * OpenArkCompiler is licensed under the Mulan Permissive Software License v2. - * You can use this software according to the terms and conditions of the MulanPSL - 2.0. - * You may obtain a copy of MulanPSL - 2.0 at: + * 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: * - * https://opensource.org/licenses/MulanPSL-2.0 + * 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 MulanPSL - 2.0 for more details. + * See the Mulan PSL v2 for more details. */ -#ifndef MAPLE_UTIL_INCLUDE_GCOV_PROFILE_H -#define MAPLE_UTIL_INCLUDE_GCOV_PROFILE_H - +#ifndef MAPLE_UTIL_INCLUDE_MPL_PROFDATA_H +#define MAPLE_UTIL_INCLUDE_MPL_PROFDATA_H #include "mempool_allocator.h" #include #include namespace maple { -using gcov_unsigned_t = unsigned; -using gcov_type = int64_t; -using gcov_type_unsigned = uint64_t; -using location_t = unsigned; #define HOTCALLSITEFREQ 100 - enum UpdateFreqOp { kKeepOrigFreq = 0, kUpdateOrigFreq = 0x1, @@ -35,11 +29,60 @@ enum UpdateFreqOp { kUpdateUnrollRemainderFreq = 0x8, }; -class GcovFuncInfo { +// used for record cumulative datas +struct ProfileSummaryHistogram { + uint32_t startValue; // count value range in [startValue, nextHistogramStart) + uint32_t countNums; // Number of counters whose profile count falls in countValue range. + uint64_t countMinVal; // Smallest profile count included in this range. + uint64_t countCumValue; // Cumulative value of the profile counts + + ProfileSummaryHistogram(uint32_t s, uint32_t num, uint64_t mincount, uint64_t cumcounts) : + startValue(s), countNums(num), countMinVal(mincount), countCumValue(cumcounts) { + } +}; + +class ProfileSummary { +public: + ProfileSummary(MapleAllocator* alloc) : histogram(alloc->Adapter()) {} + ProfileSummary(MapleAllocator *alloc, uint64_t checksum, uint32_t runtimes, + uint32_t totalcount, uint64_t maxcount, uint64_t sumcount) : + checkSum(checksum), run(runtimes), totalCount(totalcount), maxCount(maxcount), sumCount(sumcount), + histogram(alloc->Adapter()) {} + + void SetSummary(uint64_t checksum, uint32_t runtimes, uint32_t totalcount, uint64_t maxcount, uint64_t sumcount) { + checkSum = checksum; + run = runtimes; + totalCount = totalcount; + maxCount = maxcount; + sumCount = sumcount; + } + void AddHistogramRecord(uint32_t s, uint32_t num, uint64_t mincount, uint64_t cumcounts) { + histogram.push_back(ProfileSummaryHistogram(s, num, mincount, cumcounts)); + } + void DumpSummary(); + uint64_t GetCheckSum() { return checkSum; } + uint32_t GetRun() { return run; } + uint32_t GetTotalCount() { return totalCount; } + uint64_t GetMaxCount() { return maxCount; } + uint64_t GetSumCount() { return sumCount; } + uint32_t GetHistogramLength() { return histogram.size(); } + MapleVector& GetHistogram() { return histogram; } + +private: + uint64_t checkSum; // checksum value of module + uint32_t run; // run times + uint32_t totalCount; // number of counters + uint64_t maxCount; // max counter value in single run + uint64_t sumCount; // sum of all counters accumulated. + MapleVector histogram; // record gcov_bucket_type histogram[GCOV_HISTOGRAM_SIZE]; +}; + +class FuncProfInfo { 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; + FuncProfInfo(MapleAllocator* alloc, unsigned funcIdent, unsigned lineno_cs, + unsigned cfg_cs, unsigned countnum = 0) : ident(funcIdent), linenoChecksum(lineno_cs), + cfgChecksum(cfg_cs), edgeCounts(countnum), counts(alloc->Adapter()) {}; + ~FuncProfInfo() = default; uint64_t GetFuncFrequency() const { return entry_freq; } void SetFuncFrequency(uint64_t freq) { entry_freq = freq; } @@ -77,34 +120,48 @@ class GcovFuncInfo { ASSERT(0, "should not be here"); return false; } + void DumpFunctionProfile(); + unsigned ident; - unsigned lineno_checksum; - unsigned cfg_checksum; + unsigned linenoChecksum; + unsigned cfgChecksum; // Raw arc coverage counts. - unsigned num_counts; - MapleVector counts; + unsigned edgeCounts; + MapleVector counts; uint64_t entry_freq; // record entry bb frequence std::unordered_map stmtFreqs; // stmt_id is key, counter value uint64_t real_entryfreq; // function prof data may be modified after clone/inline }; -class GcovProfileData { +class MplProfileData { public: - GcovProfileData(MapleAllocator *alloc) : funcsCounter(alloc->Adapter()) {} + MplProfileData(MemPool *m, MapleAllocator *a) : funcsCounter(a->Adapter()), summary(a), mp(m), alloc(a) {} - GcovFuncInfo *GetFuncProfile(unsigned puidx) { + FuncProfInfo *GetFuncProfile(unsigned puidx) { if (funcsCounter.count(puidx) > 0) { return funcsCounter[puidx]; } return nullptr; } - void AddFuncProfile(unsigned puidx, GcovFuncInfo *funcData) { + FuncProfInfo *AddNewFuncProfile(unsigned puidx, unsigned lino_cs, unsigned cfg_cs, unsigned countnum) { + FuncProfInfo *funcProf = mp->New(alloc, puidx, lino_cs, cfg_cs, countnum); + ASSERT(funcsCounter.count(puidx) == 0, "sanity check"); + funcsCounter[puidx] = funcProf; + return funcProf; + } + void AddFuncProfile(unsigned puidx, FuncProfInfo *funcData) { ASSERT(funcsCounter.count(puidx) == 0, "sanity check"); funcsCounter[puidx] = funcData; } - MapleUnorderedMap funcsCounter; // use puidx as key + void DumpProfileData(); + void DumpFunctionsProfile(); + MapleUnorderedMap funcsCounter; // use puidx as key + // record module profile information and statistics of count information + ProfileSummary summary; +private: + MemPool *mp; + MapleAllocator *alloc; }; - } // end namespace -#endif // MAPLE_UTIL_INCLUDE_GCOV_PROFILE_H +#endif // MAPLE_UTIL_INCLUDE_MPL_PROFDATA_H diff --git a/src/mapleall/maple_util/include/namemangler.h b/src/mapleall/maple_util/include/namemangler.h index 250e9ef8ba..c1b21573fe 100644 --- a/src/mapleall/maple_util/include/namemangler.h +++ b/src/mapleall/maple_util/include/namemangler.h @@ -190,6 +190,7 @@ static constexpr const char kBindingProtectedRegionStr[] = "__BindingProtectRegi static constexpr const char kClassNamePrefixStr[] = "L"; static constexpr const char kClassMethodSplitterStr[] = "_3B"; static constexpr const char kFuncGetCurrentCl[] = "MCC_GetCurrentClassLoader"; +static constexpr const char kMplProfFileNameExt[] = ".mprofdata"; // Serve as a global flag to indicate whether frequent strings have been compressed extern bool doCompression; @@ -212,6 +213,10 @@ uint32_t GetUnsignedLeb128Decode(const uint8_t **data); size_t GetUleb128Size(uint64_t val); size_t GetSleb128Size(int32_t val); bool NeedConvertUTF16(const std::string &str8); +uint32_t EncodeSLEB128(int64_t Value, std::ofstream &out); +uint32_t EncodeULEB128(uint64_t Value, std::ofstream &out); +uint64_t DecodeULEB128(const uint8_t *p, unsigned *n = nullptr, const uint8_t *end = nullptr); +int64_t DecodeSLEB128(const uint8_t *p, unsigned *n = nullptr, const uint8_t *end = nullptr); } // namespace namemangler #endif diff --git a/src/mapleall/maple_util/src/mpl_profdata.cpp b/src/mapleall/maple_util/src/mpl_profdata.cpp new file mode 100644 index 0000000000..64e37ed9c0 --- /dev/null +++ b/src/mapleall/maple_util/src/mpl_profdata.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) [2022] Futurewei Technologies, Inc. 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 "mpl_profdata.h" +#include "mpl_logging.h" +namespace maple { +void ProfileSummary::DumpSummary() { + LogInfo::MapleLogger() << "---------ProfileSummary-------------- \n"; + LogInfo::MapleLogger() << " checkSum: " << std::hex << "0x" << checkSum << "\n"; + LogInfo::MapleLogger() << " runtimes: " << std::dec << run << "\n"; + LogInfo::MapleLogger() << " totalCounts: " << std::dec << totalCount << "\n"; + LogInfo::MapleLogger() << " maxCount: " << std::dec << maxCount << "\n"; + LogInfo::MapleLogger() << " count histogram: countRange countNum minCount cumCount \n"; + for (auto &it : histogram) { + LogInfo::MapleLogger() <<" " << std::dec << it.startValue << "\t"; + LogInfo::MapleLogger() << std::dec << it. countNums<< "\t" << it.countMinVal << "\t" << it.countCumValue << "\n"; + } +} + +void FuncProfInfo::DumpFunctionProfile() { + LogInfo::MapleLogger() << "function ident " << std::dec << ident; + LogInfo::MapleLogger() << " lino_checksum 0x" << std::hex << linenoChecksum << ", "; + LogInfo::MapleLogger() << " cfg_checksum 0x" << std::hex << cfgChecksum << "\n"; + LogInfo::MapleLogger() << " num_counts " << std::dec << edgeCounts << " : "; + for (int i = 0; i < edgeCounts; i++) { + LogInfo::MapleLogger() << std::dec << " " << counts[i]; + } + LogInfo::MapleLogger() << "\n"; +} + +void MplProfileData::DumpFunctionsProfile() { + LogInfo::MapleLogger() << "---------FunctionProfile-------------- \n"; + for (auto &it : funcsCounter) { + it.second->DumpFunctionProfile(); + } +} + +void MplProfileData::DumpProfileData() { + summary.DumpSummary(); + DumpFunctionsProfile(); +} +} // endof namespace diff --git a/src/mapleall/maple_util/src/namemangler.cpp b/src/mapleall/maple_util/src/namemangler.cpp index b2dbd0ca91..151a97f371 100644 --- a/src/mapleall/maple_util/src/namemangler.cpp +++ b/src/mapleall/maple_util/src/namemangler.cpp @@ -16,6 +16,7 @@ #include #include #include +#include namespace namemangler { #ifdef __MRT_DEBUG @@ -593,4 +594,95 @@ size_t GetSleb128Size(int32_t v) { } return size; } + +// encode signed to output stream +uint32_t EncodeSLEB128(int64_t Value, std::ofstream &out) { + bool More; + uint32_t Count = 0; + do { + uint8_t Byte = Value & 0x7f; + // NOTE: this assumes that this signed shift is an arithmetic right shift. + Value >>= 7; + More = !((((Value == 0 ) && ((Byte & 0x40) == 0)) || + ((Value == -1) && ((Byte & 0x40) != 0)))); + Count++; + if (More) { + Byte |= 0x80; // Mark this byte to show that more bytes will follow. + } + out << (char)(Byte); + } while (More); + return Count; +} + +uint32_t EncodeULEB128(uint64_t Value, std::ofstream &out) { + uint32_t Count = 0; + do { + uint8_t Byte = Value & 0x7f; + Value >>= 7; + Count++; + if (Value != 0) { + Byte |= 0x80; // Mark this byte to show that more bytes will follow. + } + out << char(Byte); + } while (Value != 0); + return Count; +} + +// decode a ULEB128 value. +uint64_t DecodeULEB128(const uint8_t *p, unsigned *n, const uint8_t *end) { + const uint8_t *orig_p = p; + uint64_t Value = 0; + unsigned Shift = 0; + do { + if (p == end) { + if (n) + *n = (unsigned)(p - orig_p); + return 0; + } + uint64_t Slice = *p & 0x7f; + if ((Shift >= 64 && Slice != 0) || Slice << Shift >> Shift != Slice) { + if (n) + *n = (unsigned)(p - orig_p); + return 0; + } + Value += Slice << Shift; + Shift += 7; + } while (*p++ >= 128); + if (n) + *n = (unsigned)(p - orig_p); + return Value; +} + +//decode a SLEB128 value. +int64_t DecodeSLEB128(const uint8_t *p, unsigned *n, const uint8_t *end) { + const uint8_t *orig_p = p; + int64_t Value = 0; + unsigned Shift = 0; + uint8_t Byte; + do { + if (p == end) { + if (n) + *n = (unsigned)(p - orig_p); + return 0; + } + Byte = *p; + uint64_t Slice = Byte & 0x7f; + if ((Shift >= 64 && Slice != (Value < 0 ? 0x7f : 0x00)) || + (Shift == 63 && Slice != 0 && Slice != 0x7f)) { + if (n) + *n = (unsigned)(p - orig_p); + return 0; + } + Value |= Slice << Shift; + Shift += 7; + ++p; + } while (Byte >= 128); + // Sign extend negative numbers if needed. + if (Shift < 64 && (Byte & 0x40)) + Value |= (-1ULL) << Shift; + if (n) + *n = (unsigned)(p - orig_p); + return Value; +} + } // namespace namemangler diff --git a/src/mapleall/mpl2mpl/BUILD.gn b/src/mapleall/mpl2mpl/BUILD.gn index c41431ec49..63ba35bebe 100755 --- a/src/mapleall/mpl2mpl/BUILD.gn +++ b/src/mapleall/mpl2mpl/BUILD.gn @@ -57,7 +57,7 @@ src_libmpl2mpl = [ "src/inline_analyzer.cpp", "src/inline_transformer.cpp", "src/method_replace.cpp", - "src/gcov_parser.cpp", + "src/mpl_profdata_parser.cpp", ] configs = [ "${MAPLEALL_ROOT}:mapleallcompilecfg" ] diff --git a/src/mapleall/mpl2mpl/include/gcov_parser.h b/src/mapleall/mpl2mpl/include/gcov_parser.h deleted file mode 100644 index 85dcb3566d..0000000000 --- a/src/mapleall/mpl2mpl/include/gcov_parser.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) [2022] Futurewei Technologies Co., Ltd. All rights reserved. - * - * OpenArkCompiler is licensed under the Mulan Permissive Software License v2. - * You can use this software according to the terms and conditions of the MulanPSL - 2.0. - * You may obtain a copy of MulanPSL - 2.0 at: - * - * https://opensource.org/licenses/MulanPSL-2.0 - * - * 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 MulanPSL - 2.0 for more details. - */ - -#ifndef MAPLE_MPL2MPL_INCLUDE_GCOVPROFUSE_H -#define MAPLE_MPL2MPL_INCLUDE_GCOVPROFUSE_H -#include "mempool.h" -#include "mempool_allocator.h" -#include "bb.h" -#include "maple_phase_manager.h" -#include "gcov_profile.h" - -namespace maple { -using gcov_position_t = unsigned; -// counter defined in gcov-counter.def -enum { - GCOV_COUNTER_ARCS, - GCOV_COUNTER_V_INTERVAL, - GCOV_COUNTER_V_POW2, - GCOV_COUNTER_V_SINGLE, - GCOV_COUNTER_V_INDIR, - GCOV_COUNTER_AVERAGE, - GCOV_COUNTER_IOR, - GCOV_TIME_PROFILER, - GCOV_COUNTER_ICALL_TOPNV, - GCOV_COUNTERS -}; - -class GcovVar { - public: - GcovVar() { - file = nullptr; - buffer = nullptr; - } - FILE *file = nullptr; - gcov_position_t start = 0; - unsigned offset = 0; - unsigned length = 0; - unsigned overread = 0; - int error = 0; - int mode = 0; - int endian = 0; - size_t alloc = 0; - gcov_unsigned_t* buffer = nullptr; -}; - -class MGcovParser : public AnalysisResult { - public: - MGcovParser(MIRModule &mirmod, MemPool *memPool, bool debug) : AnalysisResult(memPool), m(mirmod), - alloc(memPool), localMP(memPool), gcovData(nullptr), dumpDetail(debug) { - gcovVar = localMP->New(); - } - ~MGcovParser() override { - localMP = nullptr; - gcovData = nullptr; - gcovVar = nullptr; - } - int ReadGcdaFile(); - void DumpFuncInfo(); - GcovProfileData *GetGcovData() { return gcovData; } - - private: - using gcov_bucket_type = struct { - gcov_unsigned_t num_counters; - gcov_type min_value; - gcov_type cum_value; - }; - - struct gcov_ctr_summary { - gcov_unsigned_t num; - gcov_unsigned_t runs; - gcov_type sum_all; - gcov_type run_max; - gcov_type sum_max; - gcov_bucket_type histogram[252]; - }; - struct gcov_summary { - gcov_unsigned_t checksum; - struct gcov_ctr_summary ctrs[GCOV_COUNTER_V_INTERVAL]; - }; - - int GcovReadMagic(gcov_unsigned_t magic, gcov_unsigned_t expected); - int GcovOpenFile(const char *name, int mode); - gcov_unsigned_t from_file(gcov_unsigned_t value); - const gcov_unsigned_t *GcovReadWords(unsigned words); - void GcovSync(gcov_position_t base, gcov_unsigned_t length); - int GcovCloseFile(void); - void GcovAllocate(unsigned length); - gcov_unsigned_t GcovReadUnsigned(void); - gcov_position_t GcovGetPosition(void); - gcov_type GcovReadCounter(void); - void GcovReadSummary(struct gcov_summary *summary); - - MIRModule &m; - MapleAllocator alloc; - MemPool *localMP; - GcovProfileData *gcovData; - GcovVar *gcovVar = nullptr; - bool dumpDetail; -}; - -MAPLE_MODULE_PHASE_DECLARE(M2MGcovParser) - -} // end of namespace maple - -#endif // MAPLE_MPL2MPL_INCLUDE_GCOVPROFUSE_H diff --git a/src/mapleall/mpl2mpl/include/inline_transformer.h b/src/mapleall/mpl2mpl/include/inline_transformer.h index 8d95a97381..1569f9b900 100644 --- a/src/mapleall/mpl2mpl/include/inline_transformer.h +++ b/src/mapleall/mpl2mpl/include/inline_transformer.h @@ -55,7 +55,10 @@ class InlineTransformer { callee(callee), callStmt(callStmt), dumpDetail(dumpDetail), - cg(cg) {} + cg(cg) { + updateFreq = (Options::profileUse && caller.GetFuncProfData() && callee.GetFuncProfData()); + }; + bool PerformInline(BlockNode &enclosingBlk); static void ReplaceSymbols(BaseNode*, uint32, const std::vector*); static void ConvertPStaticToFStatic(MIRFunction &func); @@ -91,6 +94,7 @@ class InlineTransformer { LabelIdx returnLabelIdx = 0; // The lableidx where the code will jump when the callee returns. StmtNode *labelStmt = nullptr; // The LabelNode we created for the callee, if needed. CallGraph *cg = nullptr; + bool updateFreq = false; }; } // namespace maple #endif // MPL2MPL_INCLUDE_INLINE_TRANSFORMER_H diff --git a/src/mapleall/mpl2mpl/include/mpl_profdata_parser.h b/src/mapleall/mpl2mpl/include/mpl_profdata_parser.h new file mode 100644 index 0000000000..95513fd835 --- /dev/null +++ b/src/mapleall/mpl2mpl/include/mpl_profdata_parser.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) [2022] Futurewei Technologies, Inc. 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_MPL2MPL_INCLUDE_GCOVPROFUSE_H +#define MAPLE_MPL2MPL_INCLUDE_GCOVPROFUSE_H +#include "mempool.h" +#include "mempool_allocator.h" +#include "bb.h" +#include "maple_phase_manager.h" +#include "mpl_profdata.h" + +namespace maple { +//maple profile data format +// Summary layout +// MagicNumber +// chesum +// run times +// counts number +// count Maxium value +// accumulated count sum +// cout histogram size (count statistic information used for hot function check) +// count lower bound <-- begin of histogram details +// countNum in current range +// minium value in count range +// accumulated count sum +// count range <-- another histogram element +// countNum +// minium value in cout range +// accumulated count sum +// Function profile layout (now only including edge profiling counts) +// function numbers +// function Ident (key number to identify each function(now use mirfunction->puidx) +// function line number checksum +// function cfg checksum +// counts number in function 0 +// count <-- begin of count value +// count +// counts number in function 1 +// count +// ... +// now only unsigned number in profile data, use ULEB128 to encode/decode value for file size + +const uint32_t kMapleProfDataMagicNumber = 0xA0EFEF; + +class ProfDataBinaryImportBase { +public: + ProfDataBinaryImportBase(std::string &filename, std::ifstream &input) : fileName(filename), + inputStream(input) {} + template T ReadNum(); + std::ifstream& GetInputStream() { return inputStream; } + std::string& GetProfDataFileName() { return fileName; } + void SetPosition(uint8_t *p) { pos = p; } + uint8_t *GetPosition() { return pos; } +private: + std::string &fileName; + std::ifstream &inputStream; + uint8_t *pos = nullptr; +}; + +class ProfileSummaryImport : public ProfDataBinaryImportBase { +public: + ProfileSummaryImport(std::string& outputFile, std::ifstream &input): + ProfDataBinaryImportBase(outputFile, input) {} + int ReadSummary(MplProfileData *); +private: + void ReadMProfMagic(); +}; + +class FunctionProfileImport : public ProfDataBinaryImportBase { +public: + FunctionProfileImport(std::string& inputFile, std::ifstream &input) : + ProfDataBinaryImportBase(inputFile, input) {} + int ReadFuncProfile(MplProfileData *profData); +}; + + +class MplProfDataParser : public AnalysisResult { + public: + MplProfDataParser(MIRModule &mirmod, MemPool *mp, bool debug) : AnalysisResult(mp), + m(mirmod), alloc(memPool), mempool(mp), dumpDetail(debug) { + } + virtual ~MplProfDataParser() { + } + MplProfileData *GetProfData() { return profData; } + int ReadMapleProfileData(); + private: + + MIRModule &m; + MapleAllocator alloc; + MemPool *mempool; + MplProfileData *profData = nullptr; + bool dumpDetail = false; +}; + +MAPLE_MODULE_PHASE_DECLARE(MMplProfDataParser) + +} // end of namespace maple + +#endif // MAPLE_MPL2MPL_INCLUDE_GCOVPROFUSE_H diff --git a/src/mapleall/mpl2mpl/src/call_graph.cpp b/src/mapleall/mpl2mpl/src/call_graph.cpp index 12e8664a26..ba629b6b56 100644 --- a/src/mapleall/mpl2mpl/src/call_graph.cpp +++ b/src/mapleall/mpl2mpl/src/call_graph.cpp @@ -190,7 +190,7 @@ bool CGNode::IsCalleeOf(CGNode *func) const { } uint64_t CGNode::GetCallsiteFrequency(const StmtNode *callstmt) const { - GcovFuncInfo *funcInfo = mirFunc->GetFuncProfData(); + FuncProfInfo *funcInfo = mirFunc->GetFuncProfData(); if (funcInfo->stmtFreqs.count(callstmt->GetStmtID()) > 0) { return funcInfo->stmtFreqs[callstmt->GetStmtID()]; } @@ -199,7 +199,7 @@ uint64_t CGNode::GetCallsiteFrequency(const StmtNode *callstmt) const { } uint64_t CGNode::GetFuncFrequency() const { - GcovFuncInfo *funcInfo = mirFunc->GetFuncProfData(); + FuncProfInfo *funcInfo = mirFunc->GetFuncProfData(); if (funcInfo) { return funcInfo->GetFuncFrequency(); } diff --git a/src/mapleall/mpl2mpl/src/gcov_parser.cpp b/src/mapleall/mpl2mpl/src/gcov_parser.cpp deleted file mode 100644 index f0f1373e90..0000000000 --- a/src/mapleall/mpl2mpl/src/gcov_parser.cpp +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Copyright (c) [2022] Futurewei Technologies Co., Ltd. All rights reserved. - * - * OpenArkCompiler is licensed under the Mulan Permissive Software License v2. - * You can use this software according to the terms and conditions of the MulanPSL - 2.0. - * You may obtain a copy of MulanPSL - 2.0 at: - * - * https://opensource.org/licenses/MulanPSL-2.0 - * - * 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 MulanPSL - 2.0 for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "option.h" -#include "mpl_logging.h" -#include "gcov_parser.h" - -namespace maple { -#define GCOV_DATA_MAGIC ((gcov_unsigned_t)0x67636461) /* "gcda" */ -#define GCOV_VERSION ((gcov_unsigned_t)0x4137352a) - -#ifndef ATTRIBUTE_UNUSED -#define ATTRIBUTE_UNUSED __attribute__((unused)) -#endif - -/* Convert a magic or version number to a 4 character string. */ -#define GCOV_UNSIGNED2STRING(ARRAY,VALUE) \ - ((ARRAY)[0] = (char)((VALUE) >> 24), \ - (ARRAY)[1] = (char)((VALUE) >> 16), \ - (ARRAY)[2] = (char)((VALUE) >> 8), \ - (ARRAY)[3] = (char)((VALUE) >> 0)) - -#define GCOV_TAG_FUNCTION ((gcov_unsigned_t)0x01000000) -#define GCOV_TAG_FUNCTION_LENGTH (3) -#define GCOV_TAG_BLOCKS ((gcov_unsigned_t)0x01410000) -#define GCOV_TAG_BLOCKS_LENGTH(NUM) (NUM) -#define GCOV_TAG_BLOCKS_NUM(LENGTH) (LENGTH) -#define GCOV_TAG_ARCS ((gcov_unsigned_t)0x01430000) -#define GCOV_TAG_ARCS_LENGTH(NUM) (1 + (NUM) * 2) -#define GCOV_TAG_ARCS_NUM(LENGTH) (((LENGTH) - 1) / 2) -#define GCOV_TAG_LINES ((gcov_unsigned_t)0x01450000) -#define GCOV_TAG_COUNTER_BASE ((gcov_unsigned_t)0x01a10000) -#define GCOV_TAG_COUNTER_LENGTH(NUM) ((NUM) * 2) -#define GCOV_TAG_COUNTER_NUM(LENGTH) ((LENGTH) / 2) -#define GCOV_TAG_OBJECT_SUMMARY ((gcov_unsigned_t)0xa1000000) /* Obsolete */ -#define GCOV_TAG_PROGRAM_SUMMARY ((gcov_unsigned_t)0xa3000000) -#define GCOV_TAG_SUMMARY_LENGTH(NUM) \ - (1 + GCOV_COUNTERS_SUMMABLE * (10 + 3 * 2) + (NUM) * 5) -#define GCOV_TAG_AFDO_FILE_NAMES ((gcov_unsigned_t)0xaa000000) -#define GCOV_TAG_AFDO_FUNCTION ((gcov_unsigned_t)0xac000000) -#define GCOV_TAG_AFDO_WORKING_SET ((gcov_unsigned_t)0xaf000000) - -// Convert a counter index to a tag -#define GCOV_TAG_FOR_COUNTER(COUNT) \ - (GCOV_TAG_COUNTER_BASE + ((gcov_unsigned_t)(COUNT) << 17)) - -// Return the number of set bits in X -static int popcount_hwi (unsigned long long x) { - int i, ret = 0; - size_t bits = sizeof (x) * CHAR_BIT; - for (i = 0; i < bits; i += 1) { - ret += x & 1; - x >>= 1; - } - return ret; -} - -gcov_position_t MGcovParser::GcovGetPosition (void) { - ((void)(0 && (gcovVar->mode > 0))); - return gcovVar->start + gcovVar->offset; -} - -int MGcovParser::GcovOpenFile(const char *name, int mode) { - ((void)(0 && (!gcovVar->file))); - gcovVar->start = 0; - gcovVar->offset = gcovVar->length = 0; - gcovVar->overread = -1u; - gcovVar->error = 0; - gcovVar->endian = 0; - gcovVar->alloc = 0; - if (mode >= 0) { - gcovVar->file = fopen(name, (mode > 0) ? "rb" : "r+b"); - } - if (gcovVar->file) { - mode = 1; - } else if (mode <= 0) { - gcovVar->file = fopen(name, "w+b"); - } - if (!gcovVar->file) return 0; - gcovVar->mode = mode ? mode : 1; - setbuf(gcovVar->file, (char *)0); - return 1; -} - -void MGcovParser::GcovAllocate (unsigned length) { - size_t new_size = gcovVar->alloc; - if (!new_size) { - new_size = (1 << 10); - } - new_size += length; - new_size *= 2; - gcovVar->alloc = new_size; - gcovVar->buffer= ((gcov_unsigned_t *) realloc ((gcovVar->buffer), (new_size << 2))); -} - -int MGcovParser::GcovReadMagic(gcov_unsigned_t magic, gcov_unsigned_t expected) { - if (magic == expected) return 1; - magic = (magic >> 16) | (magic << 16); - magic = ((magic & 0xff00ff) << 8) | ((magic >> 8) & 0xff00ff); - if (magic == expected) { - gcovVar->endian = 1; - return -1; - } - return 0; -} - -void MGcovParser::GcovSync(gcov_position_t base, gcov_unsigned_t length) { - ((void)(0 && (gcovVar->mode > 0))); - base += length; - if (base - gcovVar->start <= gcovVar->length) { - gcovVar->offset = base - gcovVar->start; - } else { - gcovVar->offset = gcovVar->length = 0; - fseek (gcovVar->file, base << 2, 0); - gcovVar->start = ftell (gcovVar->file) >> 2; - } -} - -const gcov_unsigned_t * MGcovParser::GcovReadWords (unsigned words) { - const gcov_unsigned_t *result; - unsigned excess = gcovVar->length - gcovVar->offset; - if (gcovVar->mode <= 0) - return nullptr; - if (excess < words) { - gcovVar->start += gcovVar->offset; - if (excess) { - memmove_s(gcovVar->buffer, excess * 4, gcovVar->buffer + gcovVar->offset, excess * 4); - } - gcovVar->offset = 0; - gcovVar->length = excess; - if (gcovVar->length + words > gcovVar->alloc) { - GcovAllocate(gcovVar->length + words); - } - excess = gcovVar->alloc - gcovVar->length; - excess = fread (gcovVar->buffer + gcovVar->length, 1, excess << 2, gcovVar->file) >> 2; - gcovVar->length += excess; - if (gcovVar->length < words) { - gcovVar->overread += words - gcovVar->length; - gcovVar->length = 0; - return 0; - } - } - result = &gcovVar->buffer[gcovVar->offset]; - gcovVar->offset += words; - return result; -} - -gcov_unsigned_t MGcovParser::from_file(gcov_unsigned_t value) { - if (gcovVar->endian) { - value = (value >> 16) | (value << 16); - value = ((value & 0xff00ff) << 8) | ((value >> 8) & 0xff00ff); - } - return value; -} - -gcov_unsigned_t MGcovParser::GcovReadUnsigned(void) { - gcov_unsigned_t value; - const gcov_unsigned_t *buffer = GcovReadWords(1); - if (!buffer) return 0; - value = from_file(buffer[0]); - return value; -} - -int MGcovParser::GcovCloseFile (void) { - if (gcovVar->file) { - fclose (gcovVar->file); - gcovVar->file = 0; - gcovVar->length = 0; - } - free (gcovVar->buffer); - gcovVar->alloc = 0; - gcovVar->buffer = nullptr; - gcovVar->mode = 0; - return gcovVar->error; -} - -gcov_type MGcovParser::GcovReadCounter (void) { - gcov_type value; - const gcov_unsigned_t *buffer = GcovReadWords(2); - if (!buffer) return 0; - value = from_file (buffer[0]); - if (sizeof (value) > sizeof (gcov_unsigned_t)) { - value |= ((gcov_type) from_file (buffer[1])) << 32; - } else if (buffer[1]) { - gcovVar->error = -1; - } - return value; -} - -void MGcovParser::GcovReadSummary (struct gcov_summary *summary) { - unsigned ix, h_ix, bv_ix, h_cnt = 0; - struct gcov_ctr_summary *csum; - unsigned histo_bitvector[(252 + 31) / 32]; - unsigned cur_bitvector; - summary->checksum = GcovReadUnsigned(); - for (csum = summary->ctrs, ix = (GCOV_COUNTER_ARCS + 1); ix--; csum++) { - csum->num = GcovReadUnsigned(); - csum->runs = GcovReadUnsigned(); - csum->sum_all = GcovReadCounter(); - csum->run_max = GcovReadCounter(); - csum->sum_max = GcovReadCounter(); - memset_s(csum->histogram, sizeof (gcov_bucket_type) * 252, 0, sizeof (gcov_bucket_type) * 252); - for (bv_ix = 0; bv_ix < (252 + 31) / 32; bv_ix++) { - histo_bitvector[bv_ix] = GcovReadUnsigned(); - h_cnt += popcount_hwi (histo_bitvector[bv_ix]); - } - bv_ix = 0; - h_ix = 0; - cur_bitvector = 0; - while (h_cnt--) { - while (!cur_bitvector) { - h_ix = bv_ix * 32; - if (bv_ix >= (252 + 31) / 32) { - CHECK_FATAL(false, "corrupted profile info: summary histogram " "bitvector is corrupt"); - } - cur_bitvector = histo_bitvector[bv_ix++]; - } - while (!(cur_bitvector & 0x1)) { - h_ix++; - cur_bitvector >>= 1; - } - if (h_ix >= 252) { - CHECK_FATAL(0, "corrupted profile info: summary histogram " "index is corrupt"); - } - csum->histogram[h_ix].num_counters = GcovReadUnsigned(); - csum->histogram[h_ix].min_value = GcovReadCounter(); - csum->histogram[h_ix].cum_value = GcovReadCounter(); - cur_bitvector >>= 1; - h_ix++; - } - } -} - -static unsigned object_runs; -static unsigned program_count; -// reference -int MGcovParser::ReadGcdaFile() { - std::string gcovDataFile = Options::profile; - if (gcovDataFile.empty()) { - if (const char* env_p = std::getenv("GCOV_PREFIX")) { - gcovDataFile.append(env_p); - } else { - gcovDataFile.append("."); - } - gcovDataFile.append("/"); - gcovDataFile.append(m.GetProfileDataFileName()); - } - ASSERT(!gcovDataFile.empty(), "null check"); - if (!GcovOpenFile(gcovDataFile.c_str(), 1)) { - LogInfo::MapleLogger() << "no data file " << gcovDataFile << " \n"; - Options::profileUse = false; // reset profileUse - return 0; - } - - if (!GcovReadMagic(GcovReadUnsigned(), GCOV_DATA_MAGIC)) { - LogInfo::MapleLogger() << gcovDataFile << " not a gcov data file\n"; - GcovCloseFile (); - return 1; - } - unsigned version = GcovReadUnsigned(); - if (version != GCOV_VERSION) { - char v[4], e[4]; - GCOV_UNSIGNED2STRING (v, version); - 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 = GcovReadUnsigned(); - - gcovData = localMP->New(&alloc); - GcovFuncInfo *funcInfo = nullptr; - while ((tag = GcovReadUnsigned())) { - unsigned length = GcovReadUnsigned(); - unsigned long base = GcovGetPosition(); - - if (tag == GCOV_TAG_PROGRAM_SUMMARY) { - struct gcov_summary summary; - GcovReadSummary(&summary); - object_runs += summary.ctrs[GCOV_COUNTER_ARCS].runs; - program_count++; - } else if (tag == GCOV_TAG_FUNCTION && length == GCOV_TAG_FUNCTION_LENGTH) { - unsigned ident; - /* Try to find the function in the list. To speed up the - search, first start from the last function found. */ - ident = GcovReadUnsigned(); - unsigned lineno_checksum = GcovReadUnsigned(); - unsigned cfg_checksum = GcovReadUnsigned(); - funcInfo = localMP->New(&alloc, ident, lineno_checksum, cfg_checksum); - (gcovData->funcsCounter)[ident] = funcInfo; - } else if (tag == GCOV_TAG_FOR_COUNTER (GCOV_COUNTER_ARCS)) { - funcInfo->num_counts = GCOV_TAG_COUNTER_NUM(length); - for (int ix = 0; ix != funcInfo->num_counts; ix++) { - funcInfo->counts.push_back(GcovReadCounter()); - } - } - GcovSync(base, length); - } - GcovCloseFile(); - - if (dumpDetail) { - DumpFuncInfo(); - } - return 0; -} - -void MGcovParser::DumpFuncInfo() { - for (auto &it : gcovData->funcsCounter) { - GcovFuncInfo *funcInfo = it.second; - LogInfo::MapleLogger() << "\nfunction ident " << std::dec << funcInfo->ident; - LogInfo::MapleLogger() << " lino_checksum 0x" << std::hex << funcInfo->lineno_checksum; - LogInfo::MapleLogger() << " cfg_checksum 0x" << std::hex << funcInfo->cfg_checksum << "\n"; - LogInfo::MapleLogger() << " num_counts " << std::dec << funcInfo->num_counts << " : "; - for (int i = 0; i < funcInfo->num_counts; i++) { - LogInfo::MapleLogger() << std::dec << " " << funcInfo->counts[i]; - } - } - LogInfo::MapleLogger() << "\n" ; -} - -void M2MGcovParser::GetAnalysisDependence(AnalysisDep &aDep) const { - aDep.SetPreservedAll(); -} - -bool M2MGcovParser::PhaseRun(maple::MIRModule &m) { - MemPool *memPool = m.GetMemPool(); // use global pool to store gcov data - MGcovParser gcovParser(m, memPool, true); - int res = gcovParser.ReadGcdaFile(); - if (res) { - // something wrong - return false; - } - m.SetGcovProfile(gcovParser.GetGcovData()); - return true; -} - - -} // end namespace maple diff --git a/src/mapleall/mpl2mpl/src/gen_profile.cpp b/src/mapleall/mpl2mpl/src/gen_profile.cpp index 2f1a0bdb0e..b586d91474 100644 --- a/src/mapleall/mpl2mpl/src/gen_profile.cpp +++ b/src/mapleall/mpl2mpl/src/gen_profile.cpp @@ -104,7 +104,7 @@ void ProfileGen::CreateModProfDesc() { modProfDescSymMirConst->AddItem(checksumMirConst, 5); // Make the profile file name as fileName.gcda - std::string profFileName = mod.GetProfileDataFileName(); + std::string profFileName = mod.GetProfileDataFileName() + namemangler::kProfFileNameExt; auto *profileFNMirConst = modMP->New("./" + profFileName, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(PTY_a64))); modProfDescSymMirConst->AddItem(profileFNMirConst, 6); diff --git a/src/mapleall/mpl2mpl/src/inline.cpp b/src/mapleall/mpl2mpl/src/inline.cpp index 4b1c4ca460..4b7543ee76 100644 --- a/src/mapleall/mpl2mpl/src/inline.cpp +++ b/src/mapleall/mpl2mpl/src/inline.cpp @@ -92,7 +92,7 @@ void MInline::InitParams() { } void MInline::InitProfile() const { - // gcov use different profile data, return + // maple profile use different profile data, return if (Options::profileUse) { return; } @@ -421,7 +421,7 @@ 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 + // use maple instrument profile if (Options::profileUse) { return caller.GetFuncProfData()->IsHotCallSite(callStmt.GetStmtID()); } diff --git a/src/mapleall/mpl2mpl/src/inline_transformer.cpp b/src/mapleall/mpl2mpl/src/inline_transformer.cpp index 87d79fab1a..030b077931 100644 --- a/src/mapleall/mpl2mpl/src/inline_transformer.cpp +++ b/src/mapleall/mpl2mpl/src/inline_transformer.cpp @@ -307,7 +307,7 @@ GotoNode *InlineTransformer::DoUpdateReturnStmts(BlockNode &newBody, StmtNode &s dStmt = builder.CreateStmtRegassign(mirPreg->GetPrimType(), pregIdx, currBaseNode); } dStmt->SetSrcPos(stmt.GetSrcPos()); - if (Options::profileUse) { + if (updateFreq) { caller.GetFuncProfData()->CopyStmtFreq(dStmt->GetStmtID(), stmt.GetStmtID()); caller.GetFuncProfData()->CopyStmtFreq(gotoNode->GetStmtID(), stmt.GetStmtID()); caller.GetFuncProfData()->EraseStmtFreq(stmt.GetStmtID()); @@ -315,7 +315,7 @@ GotoNode *InlineTransformer::DoUpdateReturnStmts(BlockNode &newBody, StmtNode &s newBody.ReplaceStmt1WithStmt2(&stmt, dStmt); newBody.InsertAfter(dStmt, gotoNode); } else { - if (Options::profileUse) { + if (updateFreq) { caller.GetFuncProfData()->CopyStmtFreq(gotoNode->GetStmtID(), stmt.GetStmtID()); caller.GetFuncProfData()->EraseStmtFreq(stmt.GetStmtID()); } @@ -458,10 +458,9 @@ BlockNode *InlineTransformer::CloneFuncBody(BlockNode &funcBody, bool recursiveF if (callee.IsFromMpltInline()) { return funcBody.CloneTree(theMIRModule->GetCurFuncCodeMPAllocator()); } - if (Options::profileUse) { + if (updateFreq) { auto *callerProfData = caller.GetFuncProfData(); auto *calleeProfData = callee.GetFuncProfData(); - ASSERT(callerProfData && calleeProfData, "nullptr check"); uint64_t callsiteFreq = callerProfData->GetStmtFreq(callStmt.GetStmtID()); uint64_t calleeEntryFreq = calleeProfData->GetFuncFrequency(); uint32_t updateOp = (kKeepOrigFreq | kUpdateFreqbyScale); @@ -560,7 +559,7 @@ void InlineTransformer::AssignActualsToFormals(BlockNode &newBody, uint32 stIdxO CHECK_NULL_FATAL(currBaseNode); CHECK_NULL_FATAL(formal); AssignActualToFormal(newBody, stIdxOff, regIdxOff, *currBaseNode, *formal); - if (Options::profileUse) { + if (updateFreq) { caller.GetFuncProfData()->CopyStmtFreq(newBody.GetFirst()->GetStmtID(), callStmt.GetStmtID()); } } @@ -604,7 +603,7 @@ void InlineTransformer::HandleReturn(BlockNode &newBody) { } } } - if (Options::profileUse && (labelStmt != nullptr) && (newBody.GetLast() == labelStmt)) { + if (updateFreq && (labelStmt != nullptr) && (newBody.GetLast() == labelStmt)) { caller.GetFuncProfData()->CopyStmtFreq(labelStmt->GetStmtID(), callStmt.GetStmtID()); } } @@ -621,7 +620,7 @@ void InlineTransformer::ReplaceCalleeBody(BlockNode &enclosingBlk, BlockNode &ne beginCmt += callee.GetName(); StmtNode *commNode = builder.CreateStmtComment(beginCmt.c_str()); enclosingBlk.InsertBefore(&callStmt, commNode); - if (Options::profileUse) { + if (updateFreq) { caller.GetFuncProfData()->CopyStmtFreq(commNode->GetStmtID(), callStmt.GetStmtID()); } // end inlining function @@ -637,7 +636,7 @@ void InlineTransformer::ReplaceCalleeBody(BlockNode &enclosingBlk, BlockNode &ne } commNode = builder.CreateStmtComment(endCmt.c_str()); enclosingBlk.InsertAfter(&callStmt, commNode); - if (Options::profileUse) { + if (updateFreq) { caller.GetFuncProfData()->CopyStmtFreq(commNode->GetStmtID(), callStmt.GetStmtID()); } CHECK_FATAL(callStmt.GetNext() != nullptr, "null ptr check"); @@ -661,7 +660,7 @@ void InlineTransformer::GenReturnLabel(BlockNode &newBody, uint32 inlinedTimes) // record the created label labelStmt = builder.CreateStmtLabel(returnLabelIdx); newBody.AddStatement(labelStmt); - if (Options::profileUse) { + if (updateFreq) { caller.GetFuncProfData()->CopyStmtFreq(labelStmt->GetStmtID(), callStmt.GetStmtID()); } } diff --git a/src/mapleall/mpl2mpl/src/module_phase_manager.cpp b/src/mapleall/mpl2mpl/src/module_phase_manager.cpp index 375fba0b8d..ff39484443 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 "gcov_parser.h" +#include "mpl_profdata_parser.h" #define JAVALANG (mirModule.IsJavaModule()) #define CLANG (mirModule.IsCModule()) @@ -109,7 +109,7 @@ MAPLE_ANALYSIS_PHASE_REGISTER(M2MCallGraph, callgraph) 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(MMplProfDataParser, grofDataParser) MAPLE_TRANSFORM_PHASE_REGISTER(M2MInline, inline) MAPLE_TRANSFORM_PHASE_REGISTER(M2MIPODevirtualize, ipodevirtulize) diff --git a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp new file mode 100644 index 0000000000..de5c758b74 --- /dev/null +++ b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp @@ -0,0 +1,162 @@ +/* + * Copyright (c) [2022] Futurewei Technologies, Inc. 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include "option.h" +#include "mpl_logging.h" +#include "mpl_profdata_parser.h" + +namespace maple { + +template T ProfDataBinaryImportBase::ReadNum() { + unsigned NumBytesRead = 0; + uint64_t Val = namemangler::DecodeULEB128(pos, &NumBytesRead); + + pos += NumBytesRead; + return static_cast(Val); +} + +int ProfileSummaryImport::ReadSummary(MplProfileData *profData) { + CHECK_FATAL(profData != nullptr, "sanity check"); + uint64_t magicNum = ReadNum(); + if (magicNum != kMapleProfDataMagicNumber) { + LogInfo::MapleLogger() << "magic number error, quit\n"; + return 1; + } + uint64_t checksum = ReadNum(); + uint32_t runtimes = ReadNum(); + uint32_t numofCounts = ReadNum(); + uint64_t maxCount = ReadNum(); + uint64_t sumCount = ReadNum(); + profData->summary.SetSummary(checksum, runtimes, numofCounts, maxCount, sumCount); + uint32_t veclen = ReadNum(); + + for (int i = 0; i < veclen; i++) { + uint32_t r1 = ReadNum(); + uint32_t r2 = ReadNum(); + uint64_t r3 = ReadNum(); + uint64_t r4 = ReadNum(); + profData->summary.AddHistogramRecord(r1, r2, r3, r4); + } + + return 0; +} + +int FunctionProfileImport::ReadFuncProfile(MplProfileData *profData) { + CHECK_FATAL(profData != nullptr, "sanity check"); + uint32_t funcNums = ReadNum(); + if (funcNums == 0) return 1; + + for (int i = 0; i < funcNums; i++) { + uint32_t funcIdent = ReadNum(); + uint32_t linocheckSum = ReadNum(); + uint32_t cfgcheckSum = ReadNum(); + uint32_t countNum = ReadNum(); + FuncProfInfo *funcProf = profData->AddNewFuncProfile(funcIdent, linocheckSum, cfgcheckSum, countNum); + CHECK_FATAL(funcProf != nullptr, "nullptr check"); + funcProf->counts.resize(countNum); + for (int j = 0; j < countNum; j++) { + funcProf->counts[j] = ReadNum(); + } + } + return 0; +} + +int MplProfDataParser::ReadMapleProfileData() { + std::string mprofDataFile = Options::profile; + if (mprofDataFile.empty()) { + if (const char* env_p = std::getenv("GCOV_PREFIX")) { + mprofDataFile.append(env_p); + } else { + mprofDataFile.append("."); + } + mprofDataFile.append("/"); + mprofDataFile.append(m.GetProfileDataFileName()); + mprofDataFile.append(namemangler::kMplProfFileNameExt); + } + ASSERT(!mprofDataFile.empty(), "null check"); + + // create mpl profdata + profData = mempool->New(mempool, &alloc); + // read .mprofdata + std::ifstream inputStream(mprofDataFile, (std::ios::in | std::ios::binary)); + if (!inputStream) { + LogInfo::MapleLogger() << "Could not open the file " << mprofDataFile << "\n"; + return 1; + } + // get length of file + inputStream.seekg (0, inputStream.end); + int length = inputStream.tellg(); + inputStream.seekg (0, inputStream.beg); + const uint32_t sizeThreshold = 1024*10; + CHECK_FATAL(length <= sizeThreshold, "NYI::large .mprofdata file size is larger than threashold, do chunk memory\n"); + + std::unique_ptr buffer(new char[sizeof(char) * length]()); + inputStream.read (buffer.get(), length); + inputStream.close(); + // read 1st part summary + ProfileSummaryImport summaryImport(mprofDataFile, inputStream); + summaryImport.SetPosition((uint8_t *)buffer.get()); + int res = summaryImport.ReadSummary(profData); + if (res) { + LogInfo::MapleLogger() << "no summary part\n"; + return 1; + } + if (dumpDetail) { + profData->summary.DumpSummary(); + } + // read 2nd part function profile data + FunctionProfileImport funcImport(mprofDataFile, inputStream); + funcImport.SetPosition(summaryImport.GetPosition()); + res = funcImport.ReadFuncProfile(profData); + if (res) { + LogInfo::MapleLogger() << "no function profile part\n"; + return 1; + } + if (dumpDetail) { + profData->DumpFunctionsProfile(); + } + return 0; +} + +void MMplProfDataParser::GetAnalysisDependence(AnalysisDep &aDep) const { + aDep.SetPreservedAll(); +} + +bool MMplProfDataParser::PhaseRun(maple::MIRModule &m) { + + MemPool *memPool = m.GetMemPool(); // use global pool to store profile data + MplProfDataParser parser(m, memPool, true/*debug*/); + int res = parser.ReadMapleProfileData(); + if (res) { + // something wrong + LogInfo::MapleLogger() << " parse .mprofdata error\n"; + return false; + } + m.SetMapleProfile(parser.GetProfData()); + + return true; +} + + +} // end namespace maple -- Gitee From 110abf03f5a21a2e8d23263f92eb8f07a6169fcd Mon Sep 17 00:00:00 2001 From: linma Date: Wed, 27 Jul 2022 13:43:28 -0700 Subject: [PATCH 06/16] pgo use: maintain frequency in valuerangeprop and optimizeCFg, fix frequency issue in loopinversion generate cfg dot file for profileuse debug --- src/mapleall/maple_me/include/bb.h | 33 +- src/mapleall/maple_me/include/hdse.h | 21 +- src/mapleall/maple_me/include/me_cfg.h | 39 +- src/mapleall/maple_me/include/me_loop_canon.h | 5 +- .../maple_me/include/me_loop_unrolling.h | 52 +- src/mapleall/maple_me/src/bb.cpp | 43 +- src/mapleall/maple_me/src/hdse.cpp | 59 +- src/mapleall/maple_me/src/me_bb_layout.cpp | 84 +- src/mapleall/maple_me/src/me_cfg.cpp | 249 ++-- .../maple_me/src/me_critical_edge.cpp | 22 +- src/mapleall/maple_me/src/me_dse.cpp | 10 +- src/mapleall/maple_me/src/me_hdse.cpp | 23 +- src/mapleall/maple_me/src/me_loop_canon.cpp | 60 +- .../maple_me/src/me_loop_inversion.cpp | 101 +- .../maple_me/src/me_loop_unrolling.cpp | 165 +-- src/mapleall/maple_me/src/me_profile_use.cpp | 35 +- .../maple_me/src/me_value_range_prop.cpp | 1154 +++++++++-------- src/mapleall/maple_me/src/optimizeCFG.cpp | 354 ++--- .../maple_util/include/mpl_profdata.h | 121 +- src/mapleall/maple_util/src/mpl_profdata.cpp | 61 +- .../mpl2mpl/include/inline_transformer.h | 5 +- src/mapleall/mpl2mpl/src/call_graph.cpp | 30 +- src/mapleall/mpl2mpl/src/inline.cpp | 57 +- .../mpl2mpl/src/mpl_profdata_parser.cpp | 41 +- 24 files changed, 1664 insertions(+), 1160 deletions(-) diff --git a/src/mapleall/maple_me/include/bb.h b/src/mapleall/maple_me/include/bb.h index 24d5327261..e0c01e71e8 100644 --- a/src/mapleall/maple_me/include/bb.h +++ b/src/mapleall/maple_me/include/bb.h @@ -14,18 +14,18 @@ */ #ifndef MAPLE_ME_INCLUDE_BB_H #define MAPLE_ME_INCLUDE_BB_H -#include "utils.h" #include "mpl_number.h" -#include "ptr_list_ref.h" #include "orig_symbol.h" -#include "ver_symbol.h" +#include "ptr_list_ref.h" #include "ssa.h" +#include "utils.h" +#include "ver_symbol.h" namespace maple { -class MeStmt; // circular dependency exists, no other choice -class MePhiNode; // circular dependency exists, no other choice +class MeStmt; // circular dependency exists, no other choice +class MePhiNode; // circular dependency exists, no other choice class PiassignMeStmt; // circular dependency exists, no other choice -class IRMap; // circular dependency exists, no other choice +class IRMap; // circular dependency exists, no other choice enum BBKind { kBBUnknown, // uninitialized kBBCondGoto, @@ -406,8 +406,17 @@ class BB { ASSERT(idx >= 0 && idx <= succFreq.size(), "sanity check"); succFreq[static_cast(idx)] = freq; } + void AddSuccFreq(uint64 freq, size_t pos = UINT32_MAX) { + ASSERT((pos <= succFreq.size() || pos == UINT32_MAX), "Invalid position."); + if (pos == UINT32_MAX) { + succFreq.push_back(freq); + } else { + succFreq.insert(succFreq.begin() + pos, freq); + } + } + // update edge frequency - void UpdateEdgeFreqs(); + void UpdateEdgeFreqs(bool updateSuccFreq = true); const MapleVector &GetSucc() const { return succ; @@ -487,7 +496,7 @@ class BB { auto iter = std::find(succ.begin(), succ.end(), bb); CHECK_FATAL(iter != std::end(succ), "%d is not the successor of %d", bb->UintID(), this->UintID()); CHECK_FATAL(succ.size() == succFreq.size(), "succfreq size %d doesn't match succ size %d", succFreq.size(), - succ.size()); + succ.size()); const size_t idx = static_cast(std::distance(succ.begin(), iter)); succFreq[idx] = freq; } @@ -496,7 +505,7 @@ class BB { succFreq.resize(succ.size()); } - BB* GetGroup() const { + BB *GetGroup() const { return group; } @@ -524,12 +533,13 @@ class BB { int GetPredIndex(const BB &predBB) const; int GetSuccIndex(const BB &succBB) const; void RemovePhiOpnd(int index); + private: bool IsInList(const MapleVector &bbList) const; int RemoveBBFromVector(MapleVector &bbVec) const; BBId id; - LabelIdx bbLabel = 0; // the BB's label + LabelIdx bbLabel = 0; // the BB's label MapleVector pred; // predecessor list MapleVector succ; // successor list // record the edge freq from curBB to succ BB @@ -540,8 +550,10 @@ class BB { uint32 frequency = 0; BBKind kind = kBBUnknown; uint32 attributes = 0; + public: StmtNodes stmtNodeList; + private: MeStmts meStmtList; BB *group; @@ -586,6 +598,7 @@ class SCCOfBBs { BB *GetEntry() { return entry; } + private: uint32 id; BB *entry; diff --git a/src/mapleall/maple_me/include/hdse.h b/src/mapleall/maple_me/include/hdse.h index c5a637c314..a00188d9c5 100644 --- a/src/mapleall/maple_me/include/hdse.h +++ b/src/mapleall/maple_me/include/hdse.h @@ -14,17 +14,17 @@ */ #ifndef MAPLE_ME_INCLUDE_HDSE_H #define MAPLE_ME_INCLUDE_HDSE_H +#include "alias_class.h" #include "bb.h" -#include "irmap.h" #include "dominance.h" -#include "alias_class.h" +#include "irmap.h" namespace maple { class MeIRMap; class HDSE { public: - HDSE(MIRModule &mod, const MapleVector &bbVec, BB &commonEntryBB, BB &commonExitBB, - Dominance &pDom, IRMap &map, const AliasClass *aliasClass, bool enabledDebug = false, bool decouple = false) + HDSE(MIRModule &mod, const MapleVector &bbVec, BB &commonEntryBB, BB &commonExitBB, Dominance &pDom, IRMap &map, + const AliasClass *aliasClass, bool enabledDebug = false, bool decouple = false) : hdseDebug(enabledDebug), mirModule(mod), bbVec(bbVec), @@ -48,6 +48,12 @@ class HDSE { void SetRemoveRedefine(bool val) { removeRedefine = val; } + void SetUpdateFreq(bool update) { + updateFreq = update; + } + bool UpdateFreq() { + return updateFreq; + } bool hdseDebug; bool hdseKeepRef = false; @@ -73,10 +79,11 @@ class HDSE { // Or the meExpr is opnd of a same type meExpr static const uint8 kExprTypeNotNull = 2; bool decoupleStatic = false; - bool needUNClean = false; // used to record if there's unreachable BB + bool needUNClean = false; // used to record if there's unreachable BB bool removeRedefine = false; // used to control if run ResolveContinuousRedefine() - MapleVector verstUseCounts; // index is vstIdx - std::forward_list backSubsCands; // backward substitution candidates + bool updateFreq = false; + MapleVector verstUseCounts; // index is vstIdx + std::forward_list backSubsCands; // backward substitution candidates private: void DseInit(); diff --git a/src/mapleall/maple_me/include/me_cfg.h b/src/mapleall/maple_me/include/me_cfg.h index d04e9addb1..8465e37e75 100644 --- a/src/mapleall/maple_me/include/me_cfg.h +++ b/src/mapleall/maple_me/include/me_cfg.h @@ -14,12 +14,13 @@ */ #ifndef MAPLE_ME_INCLUDE_ME_CFG_H #define MAPLE_ME_INCLUDE_ME_CFG_H -#include "me_function.h" #include "maple_phase.h" +#include "me_function.h" namespace maple { class MeCFG : public AnalysisResult { using BBPtrHolder = MapleVector; + public: using value_type = BBPtrHolder::value_type; using size_type = BBPtrHolder::size_type; @@ -86,7 +87,9 @@ class MeCFG : public AnalysisResult { hasDoWhile = hdw; } - MapleAllocator &GetAlloc() { return mecfgAlloc; } + MapleAllocator &GetAlloc() { + return mecfgAlloc; + } void SetNextBBId(uint32 currNextBBId) { nextBBId = currNextBBId; @@ -98,7 +101,9 @@ class MeCFG : public AnalysisResult { --nextBBId; } - MapleVector &GetAllBBs() { return bbVec; } + MapleVector &GetAllBBs() { + return bbVec; + } iterator begin() { return bbVec.begin(); @@ -296,8 +301,19 @@ class MeCFG : public AnalysisResult { void ConstructBBFreqFromStmtFreq(); void ConstructStmtFreq(); void ConstructEdgeFreqFromBBFreq(); - void UpdateEdgeFreqWithNewBBFreq(); - void VerifyBBFreq(); + void UpdateEdgeFreqWithBBFreq(); + int VerifyBBFreq(bool checkFatal = false); + void SetUpdateCFGFreq(bool b) { + updateFreq = b; + } + bool UpdateCFGFreq() const { + return updateFreq; + } + bool DumpIRProfileFile() const { + return dumpIRProfileFile; + } + void ClearFuncFreqInfo(); + private: void AddCatchHandlerForTryBB(BB &bb, MapleVector &exitBlocks); std::string ConstructFileNameToDump(const std::string &prefix) const; @@ -316,11 +332,14 @@ class MeCFG : public AnalysisResult { MapleAllocator mecfgAlloc; MeFunction &func; MapleSet patternSet; - BBPtrHolder bbVec; + BBPtrHolder bbVec; MapleUnorderedMap labelBBIdMap; MapleUnorderedMap bbTryNodeMap; // maps isTry bb to its try stmt MapleUnorderedMap endTryBB2TryBB; // maps endtry bb to its try bb bool hasDoWhile = false; + // following 2 variable are used in profileUse + bool updateFreq = false; // true to maintain cfg frequency in transform phase + bool dumpIRProfileFile = false; // true to dump cfg to files uint32 nextBBId = 0; // BB SCC @@ -331,10 +350,10 @@ class MeCFG : public AnalysisResult { }; MAPLE_FUNC_PHASE_DECLARE_BEGIN(MEMeCfg, MeFunction) - MeCFG *GetResult() { - return theCFG; - } - MeCFG *theCFG = nullptr; +MeCFG *GetResult() { + return theCFG; +} +MeCFG *theCFG = nullptr; MAPLE_MODULE_PHASE_DECLARE_END MAPLE_FUNC_PHASE_DECLARE_BEGIN(MECfgVerifyFrequency, MeFunction) MAPLE_FUNC_PHASE_DECLARE_END diff --git a/src/mapleall/maple_me/include/me_loop_canon.h b/src/mapleall/maple_me/include/me_loop_canon.h index 248a185127..cd76626574 100644 --- a/src/mapleall/maple_me/include/me_loop_canon.h +++ b/src/mapleall/maple_me/include/me_loop_canon.h @@ -21,7 +21,8 @@ namespace maple { // convert loop to do-while format class MeLoopCanon { public: - MeLoopCanon(MeFunction &f, bool enableDebugFunc) : func(f), isDebugFunc(enableDebugFunc) {} + MeLoopCanon(MeFunction &f, bool enableDebugFunc, bool updateFreq) + : func(f), isDebugFunc(enableDebugFunc), updateFreqs(updateFreq) {} virtual ~MeLoopCanon() = default; void NormalizationExitOfLoop(IdentifyLoops &meLoop); void NormalizationHeadAndPreHeaderOfLoop(Dominance &dom); @@ -33,6 +34,7 @@ class MeLoopCanon { void ResetIsCFGChange() { isCFGChange = false; } + private: void FindHeadBBs(Dominance &dom, const BB *bb, std::map> &heads) const; void SplitPreds(const std::vector &splitList, BB *splittedBB, BB *mergedBB); @@ -44,6 +46,7 @@ class MeLoopCanon { MeFunction &func; bool isDebugFunc; bool isCFGChange = false; + bool updateFreqs = false; }; MAPLE_FUNC_PHASE_DECLARE(MELoopCanon, MeFunction) diff --git a/src/mapleall/maple_me/include/me_loop_unrolling.h b/src/mapleall/maple_me/include/me_loop_unrolling.h index 4b0c81c075..1e5f57be8f 100644 --- a/src/mapleall/maple_me/include/me_loop_unrolling.h +++ b/src/mapleall/maple_me/include/me_loop_unrolling.h @@ -14,22 +14,23 @@ */ #ifndef MAPLE_ME_INCLUDE_LOOP_UNROLLING_H #define MAPLE_ME_INCLUDE_LOOP_UNROLLING_H -#include "me_scalar_analysis.h" +#include "me_cfg.h" +#include "me_dominance.h" #include "me_function.h" -#include "me_irmap_build.h" #include "me_ir.h" -#include "me_ssa_update.h" -#include "me_dominance.h" +#include "me_irmap_build.h" #include "me_loop_analysis.h" +#include "me_scalar_analysis.h" +#include "me_ssa_update.h" #include "profile.h" -#include "me_cfg.h" namespace maple { constexpr uint32 kMaxCost = 100; -constexpr uint8 unrollTimes[3] = { 8, 4, 2 }; // unrollTimes +constexpr uint8 unrollTimes[3] = {8, 4, 2}; // unrollTimes class LoopUnrolling { public: - enum ReturnKindOfFullyUnroll { + enum ReturnKindOfFullyUnroll + { kCanFullyUnroll, kCanNotSplitCondGoto, kCanNotFullyUnroll, @@ -37,14 +38,26 @@ class LoopUnrolling { LoopUnrolling(MeFunction &f, LoopDesc &l, MeIRMap &map, const MapleAllocator &alloc, std::map>> &candsTemp) - : func(&f), cfg(f.GetCfg()), loop(&l), irMap(&map), mpAllocator(alloc), - cands(candsTemp), lastNew2OldBB(mpAllocator.Adapter()), + : func(&f), + cfg(f.GetCfg()), + loop(&l), + irMap(&map), + mpAllocator(alloc), + cands(candsTemp), + lastNew2OldBB(mpAllocator.Adapter()), profValid(func->IsIRProfValid()) {} ~LoopUnrolling() = default; ReturnKindOfFullyUnroll LoopFullyUnroll(int64 tripCount); bool LoopPartialUnrollWithConst(uint64 tripCount); bool LoopPartialUnrollWithVar(CR &cr, CRNode &varNode, uint32 j); bool LoopUnrollingWithConst(uint64 tripCount, bool onlyFully = false); + void SetInstrumentProf(bool useInstrument) { + instrumentProf = useInstrument; + profValid = useInstrument; + } + bool GetInstrumentProf() const { + return instrumentProf; + } private: bool SplitCondGotoBB(); @@ -53,14 +66,12 @@ class LoopUnrolling { void SetLabelWithCondGotoOrGotoBB(BB &bb, std::unordered_map &old2NewBB, const BB &exitBB, LabelIdx oldlabIdx); - void ResetOldLabel2NewLabel(std::unordered_map &old2NewBB, BB &bb, - const BB &exitBB, BB &newHeadBB); - void ResetOldLabel2NewLabel2(std::unordered_map &old2NewBB, BB &bb, - const BB &exitBB, BB &newHeadBB); - void CopyLoopBody(BB &newHeadBB, std::unordered_map &old2NewBB, - std::set &labelBBs, const BB &exitBB, bool copyAllLoop); - void CopyLoopBodyForProfile(BB &newHeadBB, std::unordered_map &old2NewBB, - std::set &labelBBs, const BB &exitBB, bool copyAllLoop); + void ResetOldLabel2NewLabel(std::unordered_map &old2NewBB, BB &bb, const BB &exitBB, BB &newHeadBB); + void ResetOldLabel2NewLabel2(std::unordered_map &old2NewBB, BB &bb, const BB &exitBB, BB &newHeadBB); + void CopyLoopBody(BB &newHeadBB, std::unordered_map &old2NewBB, std::set &labelBBs, + const BB &exitBB, bool copyAllLoop); + void CopyLoopBodyForProfile(BB &newHeadBB, std::unordered_map &old2NewBB, std::set &labelBBs, + const BB &exitBB, bool copyAllLoop); void UpdateCondGotoBB(BB &bb, VarMeExpr &indVar, MeExpr &tripCount, MeExpr &unrollTimeExpr); void UpdateCondGotoStmt(BB &bb, VarMeExpr &indVar, MeExpr &tripCount, MeExpr &unrollTimeExpr, uint32 offset); void CreateIndVarAndCondGotoStmt(CR &cr, CRNode &varNode, BB &preCondGoto, uint32 unrollTime, uint32 i); @@ -85,7 +96,7 @@ class LoopUnrolling { bool canUnroll = true; MeFunction *func; - MeCFG *cfg; + MeCFG *cfg; LoopDesc *loop; MeIRMap *irMap; MapleAllocator mpAllocator; @@ -100,6 +111,7 @@ class LoopUnrolling { bool firstResetForAfterInsertGoto = true; bool resetFreqForUnrollWithVar = false; bool isUnrollWithVar = false; + bool instrumentProf = false; // use instrumented profiling }; class LoopUnrollingExecutor { @@ -109,8 +121,8 @@ class LoopUnrollingExecutor { static bool enableDebug; static bool enableDump; - void ExecuteLoopUnrolling(MeFunction &func, MeIRMap &irMap, - std::map>> &cands, IdentifyLoops &meLoop, const MapleAllocator &alloc); + void ExecuteLoopUnrolling(MeFunction &func, MeIRMap &irMap, std::map>> &cands, + IdentifyLoops &meLoop, const MapleAllocator &alloc); bool IsCFGChange() const { return isCFGChange; } diff --git a/src/mapleall/maple_me/src/bb.cpp b/src/mapleall/maple_me/src/bb.cpp index 7e7e7e5490..290a3c6caa 100644 --- a/src/mapleall/maple_me/src/bb.cpp +++ b/src/mapleall/maple_me/src/bb.cpp @@ -13,10 +13,13 @@ * See the Mulan PSL v2 for more details. */ #include "bb.h" + +#include + +#include "me_ir.h" +#include "me_ssa.h" #include "mempool_allocator.h" #include "ver_symbol.h" -#include "me_ssa.h" -#include "me_ir.h" namespace maple { std::string BB::StrAttribute() const { @@ -80,8 +83,8 @@ 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) { - mod->GetOut() << " freq: " << frequency << " "; + if (Options::profileUse && frequency >= 0) { + mod->GetOut() << " freq: " << frequency << " "; } mod->GetOut() << "]===============\n"; mod->GetOut() << "preds: "; @@ -299,8 +302,8 @@ void BB::MoveAllPredToSucc(BB *newSucc, BB *commonEntry) { } else { while (!GetPred().empty()) { BB *firstPred = GetPred(0); - if (IsSuccBB(*firstPred)) { // avoid replacing twice - firstPred->ReplaceSucc(this, newSucc, true); // firstPred will be removed from this->pred + if (IsSuccBB(*firstPred)) { // avoid replacing twice + firstPred->ReplaceSucc(this, newSucc, true); // firstPred will be removed from this->pred } } } @@ -336,8 +339,8 @@ void BB::MoveAllSuccToPred(BB *newPred, BB *commonExit) { } else { while (!GetSucc().empty()) { BB *firstSucc = GetSucc(0); - if (IsPredBB(*firstSucc)) { // avoid replacing twice - firstSucc->ReplacePred(this, newPred); // firstSucc will be removed from this->succ + if (IsPredBB(*firstSucc)) { // avoid replacing twice + firstSucc->ReplacePred(this, newPred); // firstSucc will be removed from this->succ } } } @@ -476,23 +479,31 @@ void BB::DumpMePhiList(const IRMap *irMap) { } } -// bb frequency is changed in tranform phase -// update its succ frequency by scaled value -void BB::UpdateEdgeFreqs() { +// update edge frequency by scaled value when bb frequency is changed +void BB::UpdateEdgeFreqs(bool updateBBFreqOfSucc) { int len = GetSucc().size(); ASSERT(len == GetSuccFreq().size(), "sanity check"); int64_t succFreqs = 0; for (int i = 0; i < len; i++) { succFreqs += GetSuccFreq()[i]; } - // early return if frequency is consistent - if (len == 0 || succFreqs == GetFrequency()) { - return; - } - for (size_t i = 0; i < len; ++i) { + int diff = abs(succFreqs - GetFrequency()); + if (len == 0 || diff <= 1) return; + int64_t scaledSum = 0; + for (int i = 0; i < len; i++) { int64_t sfreq = GetSuccFreq()[i]; int64_t scalefreq = (succFreqs == 0 ? (frequency / len) : (sfreq * frequency / succFreqs)); + scaledSum += scalefreq; SetSuccFreq(i, scalefreq); + // update succ frequency with new difference if needed + if (updateBBFreqOfSucc) { + auto *succ = GetSucc(i); + int64_t diff = scalefreq - sfreq; + int64_t succBBnewFreq = succ->GetFrequency() + diff; + if (succBBnewFreq >= 0) { + succ->SetFrequency(succBBnewFreq); + } + } } } diff --git a/src/mapleall/maple_me/src/hdse.cpp b/src/mapleall/maple_me/src/hdse.cpp index 9258b060e5..edf2096414 100644 --- a/src/mapleall/maple_me/src/hdse.cpp +++ b/src/mapleall/maple_me/src/hdse.cpp @@ -13,20 +13,22 @@ * See the Mulan PSL v2 for more details. */ #include "hdse.h" + #include -#include "ssa_mir_nodes.h" -#include "ver_symbol.h" + #include "irmap.h" -#include "opcode_info.h" #include "mir_preg.h" +#include "opcode_info.h" +#include "ssa_mir_nodes.h" #include "utils.h" +#include "ver_symbol.h" namespace maple { using namespace utils; void HDSE::DetermineUseCounts(MeExpr *x) { if (x->GetMeOp() == kMeOpVar) { - VarMeExpr *varmeexpr = static_cast(x); + VarMeExpr *varmeexpr = static_cast(x); verstUseCounts[varmeexpr->GetVstIdx()]++; return; } @@ -42,7 +44,7 @@ void HDSE::CheckBackSubsCandidacy(DassignMeStmt *dass) { if (dass->GetRHS()->GetMeOp() != kMeOpVar && dass->GetRHS()->GetMeOp() != kMeOpReg) { return; } - ScalarMeExpr *lhsscalar = static_cast(dass->GetLHS()); + ScalarMeExpr *lhsscalar = static_cast(dass->GetLHS()); OriginalSt *ost = lhsscalar->GetOst(); if (!ost->IsLocal()) { return; @@ -51,7 +53,7 @@ void HDSE::CheckBackSubsCandidacy(DassignMeStmt *dass) { if (ty->GetPrimType() == PTY_agg && ty->GetSize() <= 16) { return; } - ScalarMeExpr *rhsscalar = static_cast(dass->GetRHS()); + ScalarMeExpr *rhsscalar = static_cast(dass->GetRHS()); if (rhsscalar->GetDefBy() != kDefByMustDef) { return; } @@ -245,6 +247,13 @@ void HDSE::RemoveNotRequiredStmtsInBB(BB &bb) { } } bb.SetKind(kBBFallthru); + if (UpdateFreq()) { + int64_t succ0Freq = bb.GetSuccFreq()[0]; + bb.GetSuccFreq().resize(1); + bb.SetSuccFreq(0, bb.GetFrequency()); + ASSERT(bb.GetFrequency() >= succ0Freq, "sanity check"); + bb.GetSucc(0)->SetFrequency(bb.GetSucc(0)->GetFrequency() + (bb.GetFrequency() - succ0Freq)); + } } // A ivar contained in stmt if (stmt2NotNullExpr.find(mestmt) != stmt2NotNullExpr.end()) { @@ -267,8 +276,9 @@ void HDSE::RemoveNotRequiredStmtsInBB(BB &bb) { } else { // skip fold conditional branch because it may break recorded IfInfo. bool isPme = mirModule.CurFunction()->GetMeFunc()->GetPreMeFunc() != nullptr; - if (mestmt->IsCondBr() && !isPme) { // see if foldable to unconditional branch - CondGotoMeStmt *condbr = static_cast(mestmt); + if (mestmt->IsCondBr() && !isPme) { // see if foldable to unconditional branch + CondGotoMeStmt *condbr = static_cast(mestmt); + int64_t removedFreq = 0; if (!mirModule.IsJavaModule() && condbr->GetOpnd()->GetMeOp() == kMeOpConst) { CHECK_FATAL(IsPrimitiveInteger(condbr->GetOpnd()->GetPrimType()), "MeHDSE::DseProcess: branch condition must be integer type"); @@ -276,6 +286,9 @@ void HDSE::RemoveNotRequiredStmtsInBB(BB &bb) { (condbr->GetOp() == OP_brfalse && !condbr->GetOpnd()->IsZero())) { // delete the conditional branch BB *succbb = bb.GetSucc().back(); + if (UpdateFreq()) { + removedFreq = bb.GetSuccFreq().back(); + } succbb->RemoveBBFromPred(bb, false); if (succbb->GetPred().empty()) { needUNClean = true; @@ -286,6 +299,9 @@ void HDSE::RemoveNotRequiredStmtsInBB(BB &bb) { } else { // change to unconditional branch BB *succbb = bb.GetSucc().front(); + if (UpdateFreq()) { + removedFreq = bb.GetSuccFreq().front(); + } succbb->RemoveBBFromPred(bb, false); if (succbb->GetPred().empty()) { needUNClean = true; @@ -295,6 +311,11 @@ void HDSE::RemoveNotRequiredStmtsInBB(BB &bb) { GotoMeStmt *gotomestmt = irMap.New(condbr->GetOffset()); bb.ReplaceMeStmt(condbr, gotomestmt); } + if (UpdateFreq()) { + bb.GetSuccFreq().resize(1); + bb.SetSuccFreq(0, bb.GetFrequency()); + bb.GetSucc(0)->SetFrequency(bb.GetSucc(0)->GetFrequency() + removedFreq); + } } else { DetermineUseCounts(condbr->GetOpnd()); } @@ -303,17 +324,17 @@ void HDSE::RemoveNotRequiredStmtsInBB(BB &bb) { DetermineUseCounts(mestmt->GetOpnd(i)); } if (mestmt->GetOp() == OP_dassign) { - CheckBackSubsCandidacy(static_cast(mestmt)); + CheckBackSubsCandidacy(static_cast(mestmt)); } } } mestmt = nextstmt; } // update verstUseCOunts for uses in phi operands - for (std::pair phipair : bb.GetMePhiList()) { + for (std::pair phipair : bb.GetMePhiList()) { if (phipair.second->GetIsLive()) { for (ScalarMeExpr *phiOpnd : phipair.second->GetOpnds()) { - VarMeExpr *varx = dynamic_cast(phiOpnd); + VarMeExpr *varx = dynamic_cast(phiOpnd); if (varx) { verstUseCounts[varx->GetVstIdx()]++; } @@ -332,7 +353,7 @@ bool HDSE::NeedNotNullCheck(MeExpr &meExpr, const BB &bb) { if (meExpr.GetOp() == OP_addrof) { return false; } - if (meExpr.GetOp() == OP_iaddrof && static_cast(meExpr).GetFieldID() > 0) { + if (meExpr.GetOp() == OP_iaddrof && static_cast(meExpr).GetFieldID() > 0) { return false; } @@ -444,8 +465,7 @@ void HDSE::MarkRegDefByStmt(RegMeExpr ®MeExpr) { MarkPhiRequired(regMeExpr.GetDefPhi()); break; case kDefByChi: { - ASSERT(regMeExpr.GetOst()->GetIndirectLev() > 0, - "MarkRegDefByStmt: preg cannot be defined by chi"); + ASSERT(regMeExpr.GetOst()->GetIndirectLev() > 0, "MarkRegDefByStmt: preg cannot be defined by chi"); auto &defChi = regMeExpr.GetDefChi(); MarkChiNodeRequired(defChi); break; @@ -585,8 +605,7 @@ bool HDSE::ExprNonDeletable(const MeExpr &meExpr) const { } case kMeOpVar: { auto &varMeExpr = static_cast(meExpr); - return varMeExpr.IsVolatile() || - (decoupleStatic && varMeExpr.GetOst()->GetMIRSymbol()->IsGlobal()); + return varMeExpr.IsVolatile() || (decoupleStatic && varMeExpr.GetOst()->GetMIRSymbol()->IsGlobal()); } case kMeOpIvar: { auto &opIvar = static_cast(meExpr); @@ -616,7 +635,7 @@ bool HDSE::HasNonDeletableExpr(const MeStmt &meStmt) const { switch (op) { case OP_dassign: { auto &dasgn = static_cast(meStmt); - VarMeExpr *varMeExpr = static_cast(dasgn.GetVarLHS()); + VarMeExpr *varMeExpr = static_cast(dasgn.GetVarLHS()); return (varMeExpr != nullptr && varMeExpr->IsVolatile()) || ExprNonDeletable(*dasgn.GetRHS()) || (hdseKeepRef && dasgn.Propagated()) || dasgn.GetWasMayDassign() || (decoupleStatic && varMeExpr != nullptr && varMeExpr->GetOst()->GetMIRSymbol()->IsGlobal()); @@ -630,8 +649,8 @@ bool HDSE::HasNonDeletableExpr(const MeStmt &meStmt) const { case OP_iassign: { auto &iasgn = static_cast(meStmt); auto &ivarMeExpr = static_cast(*iasgn.GetLHSVal()); - return ivarMeExpr.IsVolatile() || ivarMeExpr.IsFinal() || - ExprNonDeletable(*iasgn.GetLHSVal()->GetBase()) || ExprNonDeletable(*iasgn.GetRHS()); + return ivarMeExpr.IsVolatile() || ivarMeExpr.IsFinal() || ExprNonDeletable(*iasgn.GetLHSVal()->GetBase()) || + ExprNonDeletable(*iasgn.GetRHS()); } default: return false; @@ -860,4 +879,4 @@ void HDSE::DoHDSE() { } RemoveNotRequiredStmts(); } -} // namespace maple +} // namespace maple diff --git a/src/mapleall/maple_me/src/me_bb_layout.cpp b/src/mapleall/maple_me/src/me_bb_layout.cpp index c60eefd96b..e515f12797 100644 --- a/src/mapleall/maple_me/src/me_bb_layout.cpp +++ b/src/mapleall/maple_me/src/me_bb_layout.cpp @@ -13,13 +13,14 @@ * See the Mulan PSL v2 for more details. */ #include "me_bb_layout.h" -#include "me_cfg.h" + #include "bb.h" +#include "maple_phase.h" +#include "me_cfg.h" +#include "me_critical_edge.h" #include "me_irmap.h" #include "me_option.h" #include "me_predict.h" -#include "maple_phase.h" -#include "me_critical_edge.h" // This BB layout strategy strictly obeys source ordering when inside try blocks. // This Optimization will reorder the bb layout. it start from the first bb of func. @@ -114,12 +115,10 @@ void BBLayout::BuildChainForLoops() { auto &loops = meLoop->GetMeLoops(); // sort loops from inner most to outer most // need use the same sort rules as prediction? - std::stable_sort(loops.begin(), loops.end(), [](const LoopDesc *loop1, const LoopDesc *loop2) { - return loop1->nestDepth > loop2->nestDepth; - }); + std::stable_sort(loops.begin(), loops.end(), + [](const LoopDesc *loop1, const LoopDesc *loop2) { return loop1->nestDepth > loop2->nestDepth; }); // build chain for loops one by one - auto *context = - layoutAlloc.GetMemPool()->New>(cfg->NumBBs(), false, layoutAlloc.Adapter()); + auto *context = layoutAlloc.GetMemPool()->New>(cfg->NumBBs(), false, layoutAlloc.Adapter()); for (auto *loop : loops) { BuildChainForLoop(loop, context); } @@ -188,13 +187,13 @@ void BBLayout::DoBuildChain(const BB &header, BBChain &chain, const MapleVector< } bool BBLayout::IsCandidateSucc(const BB &bb, const BB &succ, const MapleVector *context) { - if (!IsBBInCurrContext(succ, context)) { // succ must be in the current context (current loop or current func) + if (!IsBBInCurrContext(succ, context)) { // succ must be in the current context (current loop or current func) return false; } - if (bb2chain[succ.GetBBId()] == bb2chain[bb.GetBBId()]) { // bb and succ should belong to different chains + if (bb2chain[succ.GetBBId()] == bb2chain[bb.GetBBId()]) { // bb and succ should belong to different chains return false; } - if (succ.GetBBId() == 1) { // special case, exclude common exit BB + if (succ.GetBBId() == 1) { // special case, exclude common exit BB return false; } return true; @@ -240,7 +239,7 @@ BB *BBLayout::GetBestSucc(BB &bb, const BBChain &chain, const MapleVector continue; } uint32 currEdgeFreq = static_cast(bb.GetEdgeFreq(i)); // attention: entryBB->succFreq[i] is always 0 - if (bb.GetBBId() == 0) { // special case for common entry BB + if (bb.GetBBId() == 0) { // special case for common entry BB CHECK_FATAL(bb.GetSucc().size() == 1, "common entry BB should not have more than 1 succ"); bestSucc = succ; break; @@ -253,7 +252,7 @@ BB *BBLayout::GetBestSucc(BB &bb, const BBChain &chain, const MapleVector if (bestSucc != nullptr) { if (debugChainLayout) { LogInfo::MapleLogger() << "Select [range1 succ ]: "; - LogInfo::MapleLogger() << bb.GetBBId() << " -> " << bestSucc->GetBBId() << std::endl; + LogInfo::MapleLogger() << bb.GetBBId() << " -> " << bestSucc->GetBBId() << std::endl; } return bestSucc; } @@ -267,12 +266,12 @@ BB *BBLayout::GetBestSucc(BB &bb, const BBChain &chain, const MapleVector continue; } bool useBBFreq = false; - if (useBBFreq) { // use bb freq + if (useBBFreq) { // use bb freq if (header->GetFrequency() > bestFreq) { // find max bb freq bestFreq = header->GetFrequency(); bestSucc = header; } - } else { // use edge freq + } else { // use edge freq uint32 subBestFreq = 0; for (auto *pred : header->GetPred()) { uint32 curFreq = static_cast(pred->GetEdgeFreq(header)); @@ -595,8 +594,7 @@ void BBLayout::OptimizeBranchTarget(BB &bb) { // condgoto's succ layout: [0] fallthru succ, [1] target succ, [2-...] eh succ/wontexit succ // goto's succ layout: [0] target succ, [1-...] eh succ/wontexit succ BB *brTargetBB = bb.GetKind() == kBBCondGoto ? bb.GetSucc(1) : bb.GetSucc(0); - CHECK_FATAL((bb.GetKind() != kBBCondGoto || bb.GetSucc(1) != bb.GetSucc(0)), - "target is same as fallthru"); + CHECK_FATAL((bb.GetKind() != kBBCondGoto || bb.GetSucc(1) != bb.GetSucc(0)), "target is same as fallthru"); if (brTargetBB->GetAttributes(kBBAttrWontExit)) { return; } @@ -608,8 +606,7 @@ void BBLayout::OptimizeBranchTarget(BB &bb) { bbVisited[bb.GetBBId().GetIdx()] = true; OptimizeBranchTarget(*brTargetBB); // optimize stmt - BB *newTargetBB = - (brTargetBB->GetKind() == kBBCondGoto) ? brTargetBB->GetSucc(1) : brTargetBB->GetSucc(0); + BB *newTargetBB = (brTargetBB->GetKind() == kBBCondGoto) ? brTargetBB->GetSucc(1) : brTargetBB->GetSucc(0); if (newTargetBB == brTargetBB) { return; } @@ -682,7 +679,7 @@ void BBLayout::AddBB(BB &bb) { // If the pred bb is goto bb and the target bb of goto bb is the current bb which is be added to layoutBBs, change the // goto bb to fallthru bb. if (layoutBBs.size() > 1) { - BB *predBB = layoutBBs.at(layoutBBs.size() - 2); // Get the pred of bb. + BB *predBB = layoutBBs.at(layoutBBs.size() - 2); // Get the pred of bb. if (predBB->GetKind() != kBBGoto) { return; } @@ -879,7 +876,6 @@ void BBLayout::RemoveUnreachable(BB &bb) { } } - void BBLayout::UpdateNewBBWithAttrTry(const BB &bb, BB &fallthru) const { auto tryBB = &bb; fallthru.SetAttributes(kBBAttrIsTry); @@ -944,6 +940,9 @@ BB *BBLayout::CreateGotoBBAfterCondBB(BB &bb, BB &fallthru) { index--; fallthru.AddPred(*newFallthru, index); newFallthru->SetFrequency(fallthru.GetFrequency()); + if (cfg->UpdateCFGFreq()) { + newFallthru->PushBackSuccFreq(fallthru.GetFrequency()); + } if (enabledDebug) { LogInfo::MapleLogger() << "Created fallthru and goto original fallthru" << '\n'; } @@ -953,7 +952,9 @@ BB *BBLayout::CreateGotoBBAfterCondBB(BB &bb, BB &fallthru) { } void BBLayout::OptimizeEmptyFallThruBB(BB &bb) { - if (needDealWithTryBB) { return; } + if (needDealWithTryBB) { + return; + } auto *fallthru = bb.GetSucc().front(); while (fallthru && (fallthru->GetPred().size() == 1) && (BBEmptyAndFallthru(*fallthru) || BBContainsOnlyGoto(*fallthru)) && @@ -963,7 +964,7 @@ void BBLayout::OptimizeEmptyFallThruBB(BB &bb) { bb.ReplaceSucc(fallthru, newFallthru); ASSERT(fallthru->GetPred().empty(), "fallthru should not has other pred"); ChangeToFallthruFromCondGoto(bb); - bb.GetSucc().resize(1); // resize succ to 1 + bb.GetSucc().resize(1); // resize succ to 1 } else if (newFallthru->GetPred().size() == 1) { if (newFallthru->GetBBLabel() != 0) { // reset newFallthru label @@ -981,7 +982,7 @@ void BBLayout::OptimizeEmptyFallThruBB(BB &bb) { } void BBLayout::DumpBBPhyOrder() const { - LogInfo::MapleLogger() << func.GetName() << " final BB order " << '\n'; + LogInfo::MapleLogger() << func.GetName() << " final BB order " << '\n'; for (auto bb : layoutBBs) { LogInfo::MapleLogger() << bb->GetBBId(); if (bb != layoutBBs.back()) { @@ -1058,8 +1059,7 @@ void BBLayout::LayoutWithoutProf() { } ASSERT(!(isTry && GetTryOutstanding()), "cannot emit another try if last try has not been ended"); if (nextBB->GetAttributes(kBBAttrIsTryEnd)) { - ASSERT(cfg->GetTryBBFromEndTryBB(nextBB) == nextBB || - IsBBLaidOut(cfg->GetTryBBFromEndTryBB(nextBB)->GetBBId()), + ASSERT(cfg->GetTryBBFromEndTryBB(nextBB) == nextBB || IsBBLaidOut(cfg->GetTryBBFromEndTryBB(nextBB)->GetBBId()), "cannot emit endtry bb before its corresponding try bb"); } } @@ -1203,8 +1203,8 @@ void BBLayout::BuildEdges() { allEdges.emplace_back(layoutAlloc.GetMemPool()->New(bb, dest, w)); } } - std::stable_sort(allEdges.begin(), allEdges.end(), [](const BBEdge *edge1, const BBEdge *edge2) { - return edge1->GetWeight() > edge2->GetWeight(); }); + std::stable_sort(allEdges.begin(), allEdges.end(), + [](const BBEdge *edge1, const BBEdge *edge2) { return edge1->GetWeight() > edge2->GetWeight(); }); } BB *BBLayout::GetBBFromEdges() { @@ -1213,8 +1213,8 @@ BB *BBLayout::GetBBFromEdges() { BB *srcBB = edge->GetSrcBB(); BB *destBB = edge->GetDestBB(); if (enabledDebug) { - LogInfo::MapleLogger() << srcBB->GetBBId() << "->" << destBB->GetBBId() << " freq " - << srcBB->GetEdgeFreq(destBB) << '\n'; + LogInfo::MapleLogger() << srcBB->GetBBId() << "->" << destBB->GetBBId() << " freq " << srcBB->GetEdgeFreq(destBB) + << '\n'; } if (!laidOut[srcBB->GetBBId()]) { @@ -1251,7 +1251,7 @@ BB *BBLayout::NextBBProf(BB &bb) { return NextBBProf(*succBB); } // max freq intial - uint64 maxFreq = 0; + uint64 maxFreq = 0; size_t idx = 0; bool found = false; for (size_t i = 0; i < bb.GetSucc().size(); ++i) { @@ -1281,11 +1281,14 @@ void BBLayout::RebuildFreq() { auto *hook = phase->GetAnalysisInfoHook(); hook->ForceEraseAnalysisPhase(func.GetUniqueID(), &MEDominance::id); hook->ForceEraseAnalysisPhase(func.GetUniqueID(), &MELoopAnalysis::id); - dom = static_cast( - hook->ForceRunAnalysisPhase>(&MEDominance::id, func))->GetResult(); + dom = static_cast(hook->ForceRunAnalysisPhase>(&MEDominance::id, func)) + ->GetResult(); meLoop = static_cast( - hook->ForceRunAnalysisPhase>(&MELoopAnalysis::id, func))->GetResult(); - MePrediction::RebuildFreq(func, *dom, *meLoop); + hook->ForceRunAnalysisPhase>(&MELoopAnalysis::id, func)) + ->GetResult(); + if (!cfg->UpdateCFGFreq()) { + MePrediction::RebuildFreq(func, *dom, *meLoop); + } } void BBLayout::LayoutWithProf(bool useChainLayout) { @@ -1345,8 +1348,7 @@ void BBLayout::VerifyBB() { if (bb->GetKind() == kBBCondGoto) { auto *fallthru = bb->GetSucc(0); auto *targetBB = bb->GetSucc(1); - if (fallthru == targetBB || - (BBEmptyAndFallthru(*fallthru) && (fallthru->GetSucc(0) == targetBB))) { + if (fallthru == targetBB || (BBEmptyAndFallthru(*fallthru) && (fallthru->GetSucc(0) == targetBB))) { LogInfo::MapleLogger() << "WARN: cond BB " << bb->GetBBId() << " has same target"; } } @@ -1374,11 +1376,15 @@ bool MEBBLayout::PhaseRun(maple::MeFunction &f) { bbLayout->RunLayout(); f.SetLaidOutBBs(bbLayout->GetBBs()); - if (DEBUGFUNC_NEWPM(f)) { + if (DEBUGFUNC_NEWPM(f) || Options::profileUse) { // verify CFG : check condBB's succs should be different bbLayout->VerifyBB(); bbLayout->DumpBBPhyOrder(); - cfg->DumpToFile("afterBBLayout", false); + if (cfg->UpdateCFGFreq() && cfg->DumpIRProfileFile()) { + cfg->DumpToFile("after-bblayout", false, true); + } else { + cfg->DumpToFile("afterBBLayout", false); + } } return true; } diff --git a/src/mapleall/maple_me/src/me_cfg.cpp b/src/mapleall/maple_me/src/me_cfg.cpp index a46f55b1da..4f6d20be4c 100644 --- a/src/mapleall/maple_me/src/me_cfg.cpp +++ b/src/mapleall/maple_me/src/me_cfg.cpp @@ -13,30 +13,33 @@ * See the Mulan PSL v2 for more details. */ #include "me_cfg.h" -#include + #include +#include #include + #include "bb.h" -#include "ssa_mir_nodes.h" -#include "me_irmap.h" -#include "mir_builder.h" #include "me_critical_edge.h" +#include "me_irmap.h" #include "me_loop_canon.h" +#include "mir_builder.h" #include "mir_lower.h" +#include "ssa_mir_nodes.h" namespace { constexpr int kFuncNameLenLimit = 80; } namespace maple { -#define MATCH_STMT(stmt, kOpCode) do { \ - while ((stmt) != nullptr && (stmt)->GetOpCode() == OP_comment) { \ - (stmt) = (stmt)->GetNext(); \ - } \ - if ((stmt) == nullptr || (stmt)->GetOpCode() != (kOpCode)) { \ - return false; \ - } \ -} while (0) // END define +#define MATCH_STMT(stmt, kOpCode) \ + do { \ + while ((stmt) != nullptr && (stmt)->GetOpCode() == OP_comment) { \ + (stmt) = (stmt)->GetNext(); \ + } \ + if ((stmt) == nullptr || (stmt)->GetOpCode() != (kOpCode)) { \ + return false; \ + } \ + } while (0) // END define // determine if need to be replaced by assertnonnull bool MeCFG::IfReplaceWithAssertNonNull(const BB &bb) const { const StmtNode *stmt = bb.GetStmtNodes().begin().d(); @@ -308,7 +311,7 @@ bool MeCFG::FindUse(const StmtNode &stmt, StIdx stIdx) const { return FindExprUse(*iNode.GetRHS(), stIdx); } } - CASE_OP_ASSERT_NONNULL + CASE_OP_ASSERT_NONNULL case OP_eval: case OP_free: case OP_switch: { @@ -511,7 +514,6 @@ void MeCFG::FixMirCFG() { } } - // replace "if() throw NPE()" with assertnonnull void MeCFG::ReplaceWithAssertnonnull() { constexpr char rnnTypeName[] = @@ -681,7 +683,7 @@ void MeCFG::ConvertPhiList2IdentityAssigns(BB &meBB) const { DassignNode *dassign = func.GetMIRModule().GetMIRBuilder()->CreateStmtDassign(*st, 0, dread2); func.GetMeSSATab()->GetStmtsSSAPart().SetSSAPartOf( *dassign, func.GetMeSSATab()->GetStmtsSSAPart().GetSSAPartMp()->New( - &func.GetMeSSATab()->GetStmtsSSAPart().GetSSAPartAlloc())); + &func.GetMeSSATab()->GetStmtsSSAPart().GetSSAPartAlloc())); auto *theSSAPart = static_cast(func.GetMeSSATab()->GetStmtsSSAPart().SSAPartOf(*dassign)); theSSAPart->SetSSAVar(*((*phiIt).second.GetResult())); @@ -700,15 +702,15 @@ void MeCFG::ConvertMePhiList2IdentityAssigns(BB &meBB) const { CHECK_FATAL(ost, "ost is nullptr!"); if (ost->IsSymbolOst() && ost->GetIndirectLev() == 0) { MePhiNode *varPhi = phiIt->second; - auto *dassign = func.GetIRMap()->NewInPool( - static_cast(varPhi->GetLHS()), varPhi->GetOpnd(0)); + auto *dassign = + func.GetIRMap()->NewInPool(static_cast(varPhi->GetLHS()), varPhi->GetOpnd(0)); dassign->SetBB(varPhi->GetDefBB()); dassign->SetIsLive(varPhi->GetIsLive()); meBB.PrependMeStmt(dassign); } else if (ost->IsPregOst()) { MePhiNode *regPhi = phiIt->second; - auto *regAss = func.GetIRMap()->New( - OP_regassign, static_cast(regPhi->GetLHS()), regPhi->GetOpnd(0)); + auto *regAss = func.GetIRMap()->New(OP_regassign, static_cast(regPhi->GetLHS()), + regPhi->GetOpnd(0)); regPhi->GetLHS()->SetDefByStmt(*regAss); regPhi->GetLHS()->SetDefBy(kDefByStmt); regAss->SetBB(regPhi->GetDefBB()); @@ -779,6 +781,10 @@ void MeCFG::WontExitAnalysis() { newBB->SetKindReturn(); newBB->SetAttributes(kBBAttrArtificial); bb->AddSucc(*newBB); + // newBB is added as succ of bb, set freq 0 as its edge frequency + if (updateFreq) { + bb->PushBackSuccFreq(0); + } GetCommonExitBB()->AddExit(*newBB); bb->FindWillExitBBs(currVisitedBBs); // Mark other bbs in the loop as visited. } @@ -835,15 +841,13 @@ void MeCFG::VerifyLabels() const { if (stmtNodes.back().GetOpCode() == OP_throw) { continue; } - ASSERT( - GetLabelBBAt(static_cast(stmtNodes.back()).GetOffset())->GetBBLabel() == - static_cast(stmtNodes.back()).GetOffset(), - "undefined label in goto"); + ASSERT(GetLabelBBAt(static_cast(stmtNodes.back()).GetOffset())->GetBBLabel() == + static_cast(stmtNodes.back()).GetOffset(), + "undefined label in goto"); } else if (mirBB->GetKind() == kBBCondGoto) { - ASSERT( - GetLabelBBAt(static_cast(stmtNodes.back()).GetOffset())->GetBBLabel() == - static_cast(stmtNodes.back()).GetOffset(), - "undefined label in conditional branch"); + ASSERT(GetLabelBBAt(static_cast(stmtNodes.back()).GetOffset())->GetBBLabel() == + static_cast(stmtNodes.back()).GetOffset(), + "undefined label in conditional branch"); } else if (mirBB->GetKind() == kBBSwitch) { auto &switchStmt = static_cast(stmtNodes.back()); LabelIdx targetLabIdx = switchStmt.GetDefaultLabel(); @@ -966,7 +970,7 @@ void MeCFG::DumpToFile(const std::string &prefix, bool dumpInStrs, bool dumpEdge return; } std::ofstream cfgFile; - std::streambuf *coutBuf = LogInfo::MapleLogger().rdbuf(); // keep original cout buffer + std::streambuf *coutBuf = LogInfo::MapleLogger().rdbuf(); // keep original cout buffer std::streambuf *buf = cfgFile.rdbuf(); LogInfo::MapleLogger().rdbuf(buf); const std::string &fileName = ConstructFileNameToDump(prefix); @@ -980,7 +984,8 @@ void MeCFG::DumpToFile(const std::string &prefix, bool dumpInStrs, bool dumpEdge if (bIt == common_exit()) { // specical case for common_exit_bb for (auto it = bb->GetPred().begin(); it != bb->GetPred().end(); ++it) { - cfgFile << "BB" << (*it)->GetBBId()<< " -> " << "BB" << bb->GetBBId() << "[style=dotted];\n"; + cfgFile << "BB" << (*it)->GetBBId() << " -> " + << "BB" << bb->GetBBId() << "[style=dotted];\n"; } continue; } @@ -989,7 +994,8 @@ void MeCFG::DumpToFile(const std::string &prefix, bool dumpInStrs, bool dumpEdge } for (auto it = bb->GetSucc().begin(); it != bb->GetSucc().end(); ++it) { - cfgFile << "BB" << bb->GetBBId() << " -> " << "BB" << (*it)->GetBBId(); + cfgFile << "BB" << bb->GetBBId() << " -> " + << "BB" << (*it)->GetBBId(); if (bb == GetCommonEntryBB()) { cfgFile << "[style=dotted]"; continue; @@ -1013,20 +1019,19 @@ void MeCFG::DumpToFile(const std::string &prefix, bool dumpInStrs, bool dumpEdge } } if (laidOut != nullptr) { - static std::vector colors = { - "indianred1", "darkorange1", "lightyellow1", "green3", "cyan", "dodgerblue2", "purple2" - }; + static std::vector colors = {"indianred1", "darkorange1", "lightyellow1", "green3", + "cyan", "dodgerblue2", "purple2"}; uint32 colorIdx = 0; size_t clusterSize = laidOut->size() / colors.size(); uint32 cnt = 0; for (uint32 i = 0; i < laidOut->size(); ++i) { auto *bb = (*laidOut)[i]; auto bbId = bb->GetBBId(); - std::string bbNameLabel = dumpEdgeFreq ? - "BB" + std::to_string(bbId.GetIdx()) + "_freq_" + std::to_string(bb->GetFrequency()) : - "BB" + std::to_string(bbId.GetIdx()); - cfgFile << "BB" << bbId << "[style=filled, color=" << colors[colorIdx % colors.size()] << ", label=" << - bbNameLabel << "__" << i << "]\n"; + std::string bbNameLabel = + dumpEdgeFreq ? "BB" + std::to_string(bbId.GetIdx()) + "_freq_" + std::to_string(bb->GetFrequency()) + : "BB" + std::to_string(bbId.GetIdx()); + cfgFile << "BB" << bbId << "[style=filled, color=" << colors[colorIdx % colors.size()] + << ", label=" << bbNameLabel << "__" << i << "]\n"; ++cnt; if (cnt > clusterSize) { cnt = 0; @@ -1147,8 +1152,8 @@ bool MeCFG::UnifyRetBBs() { if (func.GetMirFunc()->IsReturnVoid()) { newRetBB->SetFirst(mirBuilder->CreateStmtReturn(nullptr)); } else { - unifiedFuncRet = mirBuilder->CreateSymbol(func.GetMirFunc()->GetReturnTyIdx(), "unified_func_ret", - kStVar, kScAuto, func.GetMirFunc(), kScopeLocal); + unifiedFuncRet = mirBuilder->CreateSymbol(func.GetMirFunc()->GetReturnTyIdx(), "unified_func_ret", kStVar, kScAuto, + func.GetMirFunc(), kScopeLocal); newRetBB->SetFirst(mirBuilder->CreateStmtReturn(mirBuilder->CreateExprDread(*unifiedFuncRet))); } newRetBB->SetLast(newRetBB->GetStmtNodes().begin().d()); @@ -1364,8 +1369,8 @@ void MeCFG::CreateBasicBlocks() { } break; } - // fall thru to handle as return - [[clang::fallthrough]]; + // fall thru to handle as return + [[clang::fallthrough]]; case OP_gosub: case OP_retsub: case OP_return: { @@ -1397,7 +1402,7 @@ void MeCFG::CreateBasicBlocks() { if (!curBB->IsEmpty()) { StmtNode *lastStmt = stmt->GetPrev(); ASSERT(curBB->GetStmtNodes().rbegin().base().d() == nullptr || - curBB->GetStmtNodes().rbegin().base().d() == lastStmt, + curBB->GetStmtNodes().rbegin().base().d() == lastStmt, "something wrong building BB"); curBB->SetLast(lastStmt); if (curBB->GetKind() == kBBUnknown) { @@ -1430,7 +1435,7 @@ void MeCFG::CreateBasicBlocks() { // prepare a new bb StmtNode *lastStmt = stmt->GetPrev(); ASSERT(curBB->GetStmtNodes().rbegin().base().d() == nullptr || - curBB->GetStmtNodes().rbegin().base().d() == lastStmt, + curBB->GetStmtNodes().rbegin().base().d() == lastStmt, "something wrong building BB"); curBB->SetLast(lastStmt); if (curBB->GetKind() == kBBUnknown) { @@ -1461,7 +1466,7 @@ void MeCFG::CreateBasicBlocks() { // prepare a new bb StmtNode *lastStmt = stmt->GetPrev(); ASSERT(curBB->GetStmtNodes().rbegin().base().d() == nullptr || - curBB->GetStmtNodes().rbegin().base().d() == lastStmt, + curBB->GetStmtNodes().rbegin().base().d() == lastStmt, "something wrong building BB"); curBB->SetLast(lastStmt); if (curBB->GetKind() == kBBUnknown) { @@ -1592,7 +1597,7 @@ void MeCFG::CreateBasicBlocks() { } } } while (nextStmt != nullptr); - ASSERT(tryStmt == nullptr, "unclosed try"); // tryandendtry should be one-one mapping + ASSERT(tryStmt == nullptr, "unclosed try"); // tryandendtry should be one-one mapping ASSERT(lastTryBB == nullptr, "unclosed tryBB"); // tryandendtry should be one-one mapping auto *lastBB = curBB; if (lastBB->IsEmpty()) { @@ -1622,8 +1627,7 @@ void MeCFG::BBTopologicalSort(SCCOfBBs &scc) { if (succ == nullptr) { continue; } - if (inQueue.find(succ) != inQueue.end() || - std::find(bbs.begin(), bbs.end(), succ) == bbs.end()) { + if (inQueue.find(succ) != inQueue.end() || std::find(bbs.begin(), bbs.end(), succ) == bbs.end()) { continue; } bool predAllVisited = true; @@ -1651,8 +1655,8 @@ void MeCFG::BBTopologicalSort(SCCOfBBs &scc) { } void MeCFG::BuildSCCDFS(BB &bb, uint32 &visitIndex, std::vector &sccNodes, - std::vector &visitedOrder, std::vector &lowestOrder, - std::vector &inStack, std::stack &visitStack) { + std::vector &visitedOrder, std::vector &lowestOrder, std::vector &inStack, + std::stack &visitStack) { uint32 id = bb.UintID(); visitedOrder[id] = visitIndex; lowestOrder[id] = visitIndex; @@ -1780,7 +1784,7 @@ void MeCFG::UpdateBranchTarget(BB &currBB, const BB &oldTarget, BB &newTarget, M } } else if (currBB.GetKind() == kBBCondGoto) { if (currBB.GetSucc(0) == &newTarget) { - return; // no need to update offset for fallthru BB + return; // no need to update offset for fallthru BB } BB *gotoBB = currBB.GetSucc().at(1); ASSERT(gotoBB == &newTarget, "[FUNC: %s]newTarget is not one of CondGoto's succ BB", func.GetName().c_str()); @@ -1817,7 +1821,7 @@ void MeCFG::UpdateBranchTarget(BB &currBB, const BB &oldTarget, BB &newTarget, M switchStmt.SetDefaultLabel(label); } for (size_t i = 0; i < switchStmt.GetSwitchTable().size(); ++i) { - LabelIdx caseLabel = switchStmt.GetSwitchTable().at(i).second; + LabelIdx caseLabel = switchStmt.GetSwitchTable().at(i).second; if (caseLabel == oldLabelIdx) { switchStmt.UpdateCaseLabelAt(i, label); } @@ -1874,7 +1878,7 @@ void MeCFG::ConstructEdgeFreqFromBBFreq() { // set bb frequency from stmt record void MeCFG::ConstructBBFreqFromStmtFreq() { - FuncProfInfo* funcData = func.GetMirFunc()->GetFuncProfData(); + FuncProfInfo *funcData = func.GetMirFunc()->GetFuncProfData(); if (!funcData) { return; } @@ -1884,13 +1888,14 @@ void MeCFG::ConstructBBFreqFromStmtFreq() { 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 { - LogInfo::MapleLogger() << "ERROR:: bb " << (*bIt)->GetBBId() << "frequency is not set" << "\n"; + LogInfo::MapleLogger() << "ERROR:: bb " << (*bIt)->GetBBId() << "frequency is not set" + << "\n"; ASSERT(0, "no freq set"); } } @@ -1911,10 +1916,13 @@ void MeCFG::ConstructBBFreqFromStmtFreq() { ConstructEdgeFreqFromBBFreq(); // clear stmtFreqs since cfg frequency is create funcData->stmtFreqs.clear(); + + // set updateFrequency with true + updateFreq = true; } void MeCFG::ConstructStmtFreq() { - FuncProfInfo* funcData = func.GetMirFunc()->GetFuncProfData(); + FuncProfInfo *funcData = func.GetMirFunc()->GetFuncProfData(); if (!funcData) { return; } @@ -1930,8 +1938,7 @@ void MeCFG::ConstructStmtFreq() { for (auto &stmt : bb->GetStmtNodes()) { Opcode op = stmt.GetOpCode(); // record bb start/end stmt - if (stmt.GetStmtID() == bb->GetFirst().GetStmtID() || - stmt.GetStmtID() == bb->GetLast().GetStmtID() || + if (stmt.GetStmtID() == bb->GetFirst().GetStmtID() || stmt.GetStmtID() == bb->GetLast().GetStmtID() || IsCallAssigned(op) || op == OP_call) { funcData->stmtFreqs[stmt.GetStmtID()] = bb->GetFrequency(); } @@ -1941,39 +1948,105 @@ void MeCFG::ConstructStmtFreq() { // bb frequency may be changed in transform phase, // update edgeFreq with new BB frequency by scale -void MeCFG::UpdateEdgeFreqWithNewBBFreq() { - for (size_t idx = 0; idx < bbVec.size(); ++idx) { - BB *currBB = bbVec[idx]; - if (currBB == nullptr || currBB->GetSucc().empty()) { +void MeCFG::UpdateEdgeFreqWithBBFreq() { + BuildSCC(); + for (size_t i = 0; i < GetSccTopologicalVec().size(); ++i) { + SCCOfBBs *scc = GetSccTopologicalVec()[i]; + CHECK_FATAL(scc != nullptr, "scc must not be null"); + if (scc->GetBBs().size() > 1) { + BBTopologicalSort(*scc); + } + const uint32 maxLoopCount = 2; + unsigned loopCount = scc->GetBBs().size() > 1 ? maxLoopCount : 1; + for (unsigned j = 0; j < loopCount; ++j) { + for (BB *bb : scc->GetBBs()) { + if (bb == nullptr) { + continue; + } + // collect pred total except entry + if (!bb->GetAttributes(kBBAttrIsEntry)) { + int64_t inputFreq = 0; + for (auto *pred : bb->GetPred()) { + int idx = pred->GetSuccIndex(*bb); + ASSERT(idx >= 0 && idx < pred->GetSuccFreq().size(), "sanity check"); + inputFreq += pred->GetSuccFreq()[idx]; + } + bb->SetFrequency(inputFreq); + } + // make bb frequency and succs frequency consistent + bb->UpdateEdgeFreqs(false); + } + } + } +} + +void MeCFG::ClearFuncFreqInfo() { + SetUpdateCFGFreq(false); + func.GetMirFunc()->SetFuncProfData(nullptr); + auto &bbVec = GetAllBBs(); + for (size_t i = 0; i < bbVec.size(); ++i) { // skip common entry and common exit + auto *bb = bbVec[i]; + if (bb == nullptr) { continue; } - // make bb frequency and succs frequency consistent - currBB->UpdateEdgeFreqs(); + bb->SetFrequency(0); + bb->GetSuccFreq().clear(); } } -void MeCFG::VerifyBBFreq() { +// return value is 0 means pass verification, else has problem +int MeCFG::VerifyBBFreq(bool checkFatal) { + int64_t entryFreq = func.GetMirFunc()->GetFuncProfData()->GetFuncFrequency(); + ASSERT(entryFreq >= 0, "sanity check"); + bool entryIsZero = entryFreq == 0 ? true : false; for (size_t i = 2; i < bbVec.size(); ++i) { // skip common entry and common exit auto *bb = bbVec[i]; if (bb == nullptr || bb->GetAttributes(kBBAttrIsEntry) || bb->GetAttributes(kBBAttrIsExit)) { continue; } - // wontexit bb may has wrong succ, skip it + // check case 1: entry count is zero, internal bb has frequency value > 0 + if (entryIsZero && bb->GetFrequency() > 0) { + if (checkFatal) { + LogInfo::MapleLogger() << func.GetName() << "wrong BB " << bb->GetBBId() << std::endl; + CHECK_FATAL(false, "VerifyBBFreq: function entryFreq is zero but internal bb frequency > 0"); + } else { + ClearFuncFreqInfo(); + return 1; + } + } + // check case 2: bb succ frequence numbers should be equal to succ number except wontexit bb + // may has wrong succ, skip it if (bb->GetSuccFreq().size() != bb->GetSucc().size() && !bb->GetAttributes(kBBAttrWontExit)) { - CHECK_FATAL(false, "VerifyBBFreq: succFreq size != succ size"); + if (checkFatal) { + LogInfo::MapleLogger() << func.GetName() << "wrong BB " << bb->GetBBId() << std::endl; + CHECK_FATAL(false, "VerifyBBFreq: succFreq size != succ size"); + } else { + ClearFuncFreqInfo(); + return 1; + } } - // bb freq == sum(out edge freq) + // check case 3: bb freq == sum(out edge freq) uint64 succSumFreq = 0; for (auto succFreq : bb->GetSuccFreq()) { succSumFreq += succFreq; } if (succSumFreq != bb->GetFrequency()) { - LogInfo::MapleLogger() << "[VerifyFreq failure] BB" << bb->GetBBId() << " freq: " << - bb->GetFrequency() << ", all succ edge freq sum: " << succSumFreq << std::endl; - LogInfo::MapleLogger() << func.GetName() << std::endl; - CHECK_FATAL(false, "VerifyFreq failure: bb freq != succ freq sum"); + int diff = succSumFreq - bb->GetFrequency(); + diff = diff >= 0 ? diff : -diff; + if (diff > 1) { + if (checkFatal) { + LogInfo::MapleLogger() << func.GetName() << "wrong BB " << bb->GetBBId() << std::endl; + LogInfo::MapleLogger() << " freq: " << bb->GetFrequency() << ", all succ edge freq sum: " << succSumFreq + << std::endl; + CHECK_FATAL(false, "VerifyFreq failure: bb freq != succ freq sum"); + } else { + ClearFuncFreqInfo(); + return 1; + } + } } } + return 0; } bool MEMeCfg::PhaseRun(MeFunction &f) { @@ -2007,31 +2080,33 @@ bool MEMeCfg::PhaseRun(MeFunction &f) { if (!f.GetMIRModule().IsJavaModule() && MeOption::unifyRets) { theCFG->UnifyRetBBs(); } + theCFG->Verify(); // construct bb freq from stmt freq if (Options::profileUse && f.GetMirFunc()->GetFuncProfData()) { theCFG->ConstructBBFreqFromStmtFreq(); + if (theCFG->DumpIRProfileFile()) { + std::string fileName = "after-mecfgbuild"; + if (f.IsPme()) { + fileName.append("-lfo"); + } else { + fileName.append("-mplme"); + } + theCFG->DumpToFile(fileName, false, true); + } } - theCFG->Verify(); return false; } bool MECfgVerifyFrequency::PhaseRun(MeFunction &f) { - if (Options::profileUse && f.GetMirFunc()->GetFuncProfData()) { + // if transform pass is not fully support, set disableFreqInfo to true + // function profile information will be deleted after verification phase + bool disableFreqInfo = false; + if (f.GetCfg()->UpdateCFGFreq()) { f.GetCfg()->VerifyBBFreq(); } - // hack code here: no use profile data after verifycation pass since - // following tranform phases related of cfg change are not touched - f.GetMirFunc()->SetFuncProfData(nullptr); - auto &bbVec = f.GetCfg()->GetAllBBs(); - for (size_t i = 0; i < bbVec.size(); ++i) { // skip common entry and common exit - auto *bb = bbVec[i]; - if (bb == nullptr) { - continue; - } - bb->SetFrequency(0); - bb->GetSuccFreq().clear(); - } - + if (!disableFreqInfo) return false; + // clear function profile information + f.GetCfg()->ClearFuncFreqInfo(); return false; } } // namespace maple diff --git a/src/mapleall/maple_me/src/me_critical_edge.cpp b/src/mapleall/maple_me/src/me_critical_edge.cpp index e47078d693..4dca8f82a2 100644 --- a/src/mapleall/maple_me/src/me_critical_edge.cpp +++ b/src/mapleall/maple_me/src/me_critical_edge.cpp @@ -13,13 +13,15 @@ * See the Mulan PSL v2 for more details. */ #include "me_critical_edge.h" + #include + #include "me_cfg.h" -#include "me_option.h" #include "me_dominance.h" #include "me_function.h" -#include "me_loop_analysis.h" #include "me_irmap.h" +#include "me_loop_analysis.h" +#include "me_option.h" // This phase finds critical edges and split them into two, because their // presence would restrict the optimizations performed by SSAPRE-based phases. @@ -98,8 +100,8 @@ void MeSplitCEdge::UpdateCaseLabel(BB &newBB, MeFunction &func, BB &pred, BB &su } } -void MeSplitCEdge::DealWithTryBB(const MeFunction &func, BB &pred, - BB &succ, BB *&newBB, bool &isInsertAfterPred) const { +void MeSplitCEdge::DealWithTryBB(const MeFunction &func, BB &pred, BB &succ, BB *&newBB, + bool &isInsertAfterPred) const { if ((!succ.GetStmtNodes().empty() && succ.GetStmtNodes().front().GetOpCode() == OP_try) || (!succ.IsMeStmtEmpty() && succ.GetFirstMe()->GetOp() == OP_try)) { newBB = &func.GetCfg()->InsertNewBasicBlock(pred, false); @@ -117,8 +119,8 @@ void MeSplitCEdge::DealWithTryBB(const MeFunction &func, BB &pred, void MeSplitCEdge::BreakCriticalEdge(MeFunction &func, BB &pred, BB &succ) const { if (isDebugFunc) { - LogInfo::MapleLogger() << "******before break : critical edge : BB" << pred.GetBBId() << " -> BB" << - succ.GetBBId() << "\n"; + LogInfo::MapleLogger() << "******before break : critical edge : BB" << pred.GetBBId() << " -> BB" << succ.GetBBId() + << "\n"; pred.Dump(&func.GetMIRModule()); succ.Dump(&func.GetMIRModule()); } @@ -160,8 +162,7 @@ void MeSplitCEdge::BreakCriticalEdge(MeFunction &func, BB &pred, BB &succ) const newBB->SetAttributes(kBBAttrArtificial); // update newBB frequency : copy predBB succFreq as newBB frequency - if (Options::profileUse && func.GetMirFunc()->GetFuncProfData() && - (!(func.IsPme() || func.IsLfo()))) { + if (cfg->UpdateCFGFreq() && (!(func.IsPme() || func.IsLfo()))) { int idx = pred.GetSuccIndex(*newBB); ASSERT(idx >= 0 && idx < pred.GetSucc().size(), "sanity check"); uint64_t freq = pred.GetEdgeFreq(idx); @@ -189,8 +190,7 @@ 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 || - (Options::profileUse && (func.IsPme() || func.IsLfo()))) { + if (Options::profileGen || (Options::profileUse && (func.IsPme() || func.IsLfo()))) { LabelIdx succLabel = succ.GetBBLabel(); ASSERT(succLabel != 0, "succ's label missed"); if (func.GetIRMap() != nullptr) { @@ -306,7 +306,7 @@ bool MESplitCEdge::PhaseRun(maple::MeFunction &f) { mscedge.SplitCriticalEdgeForMeFunc(f); if (Options::profileUse) { if ((f.IsPme() || f.IsLfo()) && f.GetPreMeFunc()) { - // new inserted BB will break while/if label information and IR layout + // new inserted BB break cached while/if label information and IR layout f.GetPreMeFunc()->label2IfInfo.clear(); f.GetPreMeFunc()->label2WhileInfo.clear(); f.GetPreMeFunc()->pmeCreatedIfLabelSet.clear(); diff --git a/src/mapleall/maple_me/src/me_dse.cpp b/src/mapleall/maple_me/src/me_dse.cpp index c2ad027a7e..2d393a9ada 100644 --- a/src/mapleall/maple_me/src/me_dse.cpp +++ b/src/mapleall/maple_me/src/me_dse.cpp @@ -13,6 +13,7 @@ * See the Mulan PSL v2 for more details. */ #include "me_dse.h" + #include namespace maple { @@ -33,7 +34,7 @@ void MeDSE::VerifyPhi() const { const OriginalSt *ost = func.GetMeSSATab()->GetOriginalStFromID(pair.first); CHECK_FATAL(ost, "ost is nullptr!"); CHECK_FATAL(!ost->IsSymbolOst() || ost->GetIndirectLev() != 0, - "phi is live and non-virtual in bb with zero or one pred"); + "phi is live and non-virtual in bb with zero or one pred"); } else if (pair.second.GetPhiOpnds().size() != predBBNums) { ASSERT(false, "phi opnd num is not consistent with pred bb num(need update phi)"); } @@ -71,8 +72,11 @@ bool MEDse::PhaseRun(maple::MeFunction &f) { f.Verify(); // cfg change , invalid results in MeFuncResultMgr if (dse.UpdatedCfg()) { - if (Options::profileUse && f.GetMirFunc()->GetFuncProfData()) { - f.GetCfg()->UpdateEdgeFreqWithNewBBFreq(); + if (f.GetCfg()->UpdateCFGFreq()) { + f.GetCfg()->UpdateEdgeFreqWithBBFreq(); + if (f.GetCfg()->DumpIRProfileFile()) { + f.GetCfg()->DumpToFile(("after-dse" + std::to_string(f.dseRuns)), false, true); + } } GetAnalysisInfoHook()->ForceEraseAnalysisPhase(f.GetUniqueID(), &MEDominance::id); } diff --git a/src/mapleall/maple_me/src/me_hdse.cpp b/src/mapleall/maple_me/src/me_hdse.cpp index 6283697dd9..9cc7fa1907 100644 --- a/src/mapleall/maple_me/src/me_hdse.cpp +++ b/src/mapleall/maple_me/src/me_hdse.cpp @@ -13,11 +13,13 @@ * See the Mulan PSL v2 for more details. */ #include "me_hdse.h" + #include + +#include "hdse.h" +#include "me_ssa.h" #include "ssa_mir_nodes.h" #include "ver_symbol.h" -#include "me_ssa.h" -#include "hdse.h" // The hdse phase performs dead store elimination using the well-known algorithm // based on SSA. The algorithm works as follows: @@ -55,7 +57,7 @@ void MeHDSE::ProcessWhileInfos() { if (preMeFunc == nullptr) { return; } - MapleMap::iterator it = preMeFunc->label2WhileInfo.begin(); + MapleMap::iterator it = preMeFunc->label2WhileInfo.begin(); for (; it != preMeFunc->label2WhileInfo.end(); ++it) { if (it->second->initExpr != nullptr && (it->second->initExpr->GetMeOp() == maple::kMeOpVar || it->second->initExpr->GetMeOp() == maple::kMeOpReg)) { @@ -66,7 +68,7 @@ void MeHDSE::ProcessWhileInfos() { void MeHDSE::BackwardSubstitution() { for (DassignMeStmt *dass : backSubsCands) { - ScalarMeExpr *rhsscalar = static_cast(dass->GetRHS()); + ScalarMeExpr *rhsscalar = static_cast(dass->GetRHS()); if (verstUseCounts[rhsscalar->GetVstIdx()] != 1) { continue; } @@ -110,9 +112,8 @@ void MakeEmptyTrysUnreachable(MeFunction &func) { } BB *endTry = *endTryIt; auto &meStmts = tryBB->GetMeStmts(); - if (tryBB->GetAttributes(kBBAttrIsTry) && !meStmts.empty() && - meStmts.front().GetOp() == OP_try && tryBB->GetMePhiList().empty() && - endTry->GetAttributes(kBBAttrIsTryEnd) && endTry->IsMeStmtEmpty()) { + if (tryBB->GetAttributes(kBBAttrIsTry) && !meStmts.empty() && meStmts.front().GetOp() == OP_try && + tryBB->GetMePhiList().empty() && endTry->GetAttributes(kBBAttrIsTryEnd) && endTry->IsMeStmtEmpty()) { // we found a try BB followed by an empty endtry BB BB *targetBB = endTry->GetSucc(0); while (!tryBB->GetPred().empty()) { @@ -190,6 +191,7 @@ bool MEHdse::PhaseRun(maple::MeFunction &f) { MeHDSE hdse = MeHDSE(f, *dom, *hMap, aliasClass, DEBUGFUNC_NEWPM(f)); hdse.hdseKeepRef = MeOption::dseKeepRef; + hdse.SetUpdateFreq(Options::profileUse && f.GetMirFunc()->GetFuncProfData()); if (f.hdseRuns > 2) { hdse.SetRemoveRedefine(true); } @@ -198,6 +200,13 @@ bool MEHdse::PhaseRun(maple::MeFunction &f) { MakeEmptyTrysUnreachable(f); (void)f.GetCfg()->UnreachCodeAnalysis(true); f.GetCfg()->WontExitAnalysis(); + // update frequency + if (hdse.UpdateFreq()) { + f.GetCfg()->UpdateEdgeFreqWithBBFreq(); + if (f.GetCfg()->DumpIRProfileFile()) { + f.GetCfg()->DumpToFile("after-HDSE" + std::to_string(f.hdseRuns), false, true); + } + } if (DEBUGFUNC_NEWPM(f)) { LogInfo::MapleLogger() << "\n============== HDSE =============" << '\n'; f.Dump(false); diff --git a/src/mapleall/maple_me/src/me_loop_canon.cpp b/src/mapleall/maple_me/src/me_loop_canon.cpp index 951da51ee7..05c4b15f8e 100644 --- a/src/mapleall/maple_me/src/me_loop_canon.cpp +++ b/src/mapleall/maple_me/src/me_loop_canon.cpp @@ -13,11 +13,13 @@ * See the Mulan PSL v2 for more details. */ #include "me_loop_canon.h" -#include + #include +#include + #include "me_cfg.h" -#include "me_option.h" #include "me_dominance.h" +#include "me_option.h" #include "me_phase_manager.h" namespace maple { @@ -39,8 +41,7 @@ void MeLoopCanon::FindHeadBBs(Dominance &dom, const BB *bb, std::mapGetBBLabel() != 0) { - const MapleUnorderedSet &addrTakenLabels = - func.GetMirFunc()->GetLabelTab()->GetAddrTakenLabels(); + const MapleUnorderedSet &addrTakenLabels = func.GetMirFunc()->GetLabelTab()->GetAddrTakenLabels(); if (addrTakenLabels.find(bb->GetBBLabel()) != addrTakenLabels.end()) { hasIgoto = true; } @@ -71,8 +72,7 @@ void MeLoopCanon::UpdateTheOffsetOfStmtWhenTargetBBIsChange(BB &curBB, const BB static_cast(lastStmt).GetOffset() == oldSuccBB.GetBBLabel()) { auto label = func.GetOrCreateBBLabel(newSuccBB); static_cast(lastStmt).SetOffset(label); - } else if (lastStmt.GetOp() == OP_goto && - static_cast(lastStmt).GetOffset() == oldSuccBB.GetBBLabel()) { + } else if (lastStmt.GetOp() == OP_goto && static_cast(lastStmt).GetOffset() == oldSuccBB.GetBBLabel()) { auto label = func.GetOrCreateBBLabel(newSuccBB); static_cast(lastStmt).SetOffset(label); } else if (lastStmt.GetOp() == OP_switch) { @@ -96,8 +96,19 @@ void MeLoopCanon::SplitPreds(const std::vector &splitList, BB *splittedBB, // quick split auto *pred = splitList[0]; auto index = pred->GetSuccIndex(*splittedBB); + // add frequency to mergedBB + if (updateFreqs) { + int idx = pred->GetSuccIndex(*splittedBB); + ASSERT(idx >= 0 && idx < pred->GetSucc().size(), "sanity check"); + uint64_t freq = pred->GetEdgeFreq(idx); + mergedBB->SetFrequency(freq); + mergedBB->PushBackSuccFreq(freq); + } splittedBB->ReplacePred(pred, mergedBB); pred->AddSucc(*mergedBB, static_cast(static_cast(index))); + if (updateFreqs) { + pred->AddSuccFreq(mergedBB->GetFrequency(), static_cast(static_cast(index))); + } if (!pred->GetMeStmts().empty()) { UpdateTheOffsetOfStmtWhenTargetBBIsChange(*pred, *splittedBB, *mergedBB); } @@ -112,6 +123,7 @@ void MeLoopCanon::SplitPreds(const std::vector &splitList, BB *splittedBB, mergedBB->GetMePhiList().emplace(latchLhs->GetOstIdx(), latchPhi); phiIter.second->GetOpnds().push_back(latchLhs); } + uint64_t freq = 0; for (BB *pred : splitList) { auto pos = splittedBB->GetPredIndex(*pred); for (auto &phiIter : mergedBB->GetMePhiList()) { @@ -119,7 +131,17 @@ void MeLoopCanon::SplitPreds(const std::vector &splitList, BB *splittedBB, phiIter.second->GetOpnds().push_back(splittedBB->GetMePhiList().at(phiIter.first)->GetOpnd(pos)); } splittedBB->RemovePhiOpnd(pos); + if (updateFreqs) { + int idx = pred->GetSuccIndex(*splittedBB); + ASSERT(idx >= 0 && idx < pred->GetSucc().size(), "sanity check"); + freq = pred->GetEdgeFreq(idx); + mergedBB->SetFrequency(mergedBB->GetFrequency() + freq); + } pred->ReplaceSucc(splittedBB, mergedBB); + if (updateFreqs) { + int idx = pred->GetSuccIndex(*mergedBB); + pred->SetSuccFreq(idx, freq); + } if (pred->GetMeStmts().empty()) { continue; } @@ -141,6 +163,9 @@ void MeLoopCanon::SplitPreds(const std::vector &splitList, BB *splittedBB, } } splittedBB->AddPred(*mergedBB); + if (updateFreqs) { + mergedBB->PushBackSuccFreq(mergedBB->GetFrequency()); + } isCFGChange = true; } @@ -151,16 +176,14 @@ void MeLoopCanon::Merge(const std::map> &heads) { BB *head = cfg->GetBBFromID(iter->first); // skip case : check latch bb is already added // one pred is preheader bb and the other is latch bb - if ((head->GetPred().size() == 2) && - (head->GetPred(0)->GetAttributes(kBBAttrArtificial)) && - (head->GetPred(0)->GetKind() == kBBFallthru) && - (head->GetPred(1)->GetAttributes(kBBAttrArtificial)) && + if ((head->GetPred().size() == 2) && (head->GetPred(0)->GetAttributes(kBBAttrArtificial)) && + (head->GetPred(0)->GetKind() == kBBFallthru) && (head->GetPred(1)->GetAttributes(kBBAttrArtificial)) && (head->GetPred(1)->GetKind() == kBBFallthru)) { continue; } auto *latchBB = cfg->NewBasicBlock(); latchBB->SetAttributes(kBBAttrArtificial); - latchBB->SetAttributes(kBBAttrIsInLoop); // latchBB is inloop + latchBB->SetAttributes(kBBAttrIsInLoop); // latchBB is inloop latchBB->SetKind(kBBFallthru); SplitPreds(iter->second, head, latchBB); } @@ -244,8 +267,17 @@ void MeLoopCanon::InsertExitBB(LoopDesc &loop) { BB *newExitBB = cfg->NewBasicBlock(); newExitBB->SetKind(kBBFallthru); auto pos = succ->GetPredIndex(*curBB); + uint64_t freq = 0; + if (updateFreqs) { + int idx = curBB->GetSuccIndex(*succ); + freq = curBB->GetSuccFreq()[idx]; + } curBB->ReplaceSucc(succ, newExitBB); succ->AddPred(*newExitBB, pos); + if (updateFreqs) { + newExitBB->SetFrequency(freq); + newExitBB->PushBackSuccFreq(freq); + } if (!curBB->GetMeStmts().empty()) { UpdateTheOffsetOfStmtWhenTargetBBIsChange(*curBB, *succ, *newExitBB); } @@ -299,7 +331,8 @@ bool MELoopCanon::PhaseRun(maple::MeFunction &f) { auto *dom = GET_ANALYSIS(MEDominance, f); ASSERT(dom != nullptr, "dom is null in MeDoLoopCanon::Run"); MemPool *loopCanonMp = GetPhaseMemPool(); - auto *meLoopCanon = loopCanonMp->New(f, DEBUGFUNC_NEWPM(f)); + bool updateFrequency = (Options::profileUse && f.GetMirFunc()->GetFuncProfData()); + auto *meLoopCanon = loopCanonMp->New(f, DEBUGFUNC_NEWPM(f), updateFrequency); // 1. Add preheaderBB and normalization headBB for loop. meLoopCanon->NormalizationHeadAndPreHeaderOfLoop(*dom); @@ -316,6 +349,9 @@ bool MELoopCanon::PhaseRun(maple::MeFunction &f) { meLoopCanon->NormalizationExitOfLoop(*meLoop); if (meLoopCanon->IsCFGChange()) { GetAnalysisInfoHook()->ForceEraseAnalysisPhase(f.GetUniqueID(), &MEDominance::id); + if (updateFrequency && (f.GetCfg()->DumpIRProfileFile())) { + f.GetCfg()->DumpToFile("after-loopcanon", false, true); + } } return true; } diff --git a/src/mapleall/maple_me/src/me_loop_inversion.cpp b/src/mapleall/maple_me/src/me_loop_inversion.cpp index 23a572736d..8da6423c2a 100644 --- a/src/mapleall/maple_me/src/me_loop_inversion.cpp +++ b/src/mapleall/maple_me/src/me_loop_inversion.cpp @@ -13,11 +13,13 @@ * See the Mulan PSL v2 for more details. */ #include "me_loop_inversion.h" -#include + #include +#include + #include "me_cfg.h" -#include "me_option.h" #include "me_dominance.h" +#include "me_option.h" #include "me_phase_manager.h" namespace maple { @@ -121,8 +123,7 @@ void MeLoopInversion::Convert(MeFunction &func, BB &bb, BB &pred, MapleMapfallthru is in loopbody, latchBB need convert condgoto and make original target as its fallthru bool swapSuccOfLatch = (swapSuccs.find(std::make_pair(&bb, &pred)) != swapSuccs.end()); if (isDebugFunc) { - LogInfo::MapleLogger() << "***loop convert: backedge bb->id " << bb.GetBBId() << " pred->id " - << pred.GetBBId(); + LogInfo::MapleLogger() << "***loop convert: backedge bb->id " << bb.GetBBId() << " pred->id " << pred.GetBBId(); if (swapSuccOfLatch) { LogInfo::MapleLogger() << " need swap succs\n"; } else { @@ -132,9 +133,9 @@ void MeLoopInversion::Convert(MeFunction &func, BB &bb, BB &pred, MapleMapNewBasicBlock(); latchBB->SetAttributes(kBBAttrArtificial); - latchBB->SetAttributes(kBBAttrIsInLoop); // latchBB is inloop + latchBB->SetAttributes(kBBAttrIsInLoop); // latchBB is inloop // update newBB frequency : copy predBB succFreq as latch frequency - if (Options::profileUse && func.GetMirFunc()->GetFuncProfData()) { + if (func.GetCfg()->UpdateCFGFreq()) { int idx = pred.GetSuccIndex(bb); ASSERT(idx >= 0 && idx < pred.GetSucc().size(), "sanity check"); uint64_t freq = pred.GetEdgeFreq(idx); @@ -144,7 +145,7 @@ void MeLoopInversion::Convert(MeFunction &func, BB &bb, BB &pred, MapleMapSetKind(bb.GetKind()); // update succFreq - if (Options::profileUse && func.GetMirFunc()->GetFuncProfData()) { - int succFreqSize = bb.GetSuccFreq().size(); - ASSERT(latchBB->GetSucc().size() == succFreqSize, "sanity check"); - // copy bb succFreq as latch frequency - for (int i = 0; i < succFreqSize; i++) { - latchBB->PushBackSuccFreq(bb.GetSuccFreq()[i]); - } - if (bb.GetFrequency() > 0) { - // swap frequency and fixed the frequency value - if (swapSuccOfLatch) { - ASSERT(latchBB->GetKind() == kBBCondGoto, "impossible"); - int64_t newftFreq = (latchBB->GetFrequency() == 0 || bb.GetSuccFreq()[1] == 0) ? 0 : 1; - int64_t newtgFreq = latchBB->GetFrequency() == 0 ? 0 : (latchBB->GetFrequency() - newftFreq); - latchBB->SetSuccFreq(0, newftFreq); - latchBB->SetSuccFreq(1, newtgFreq); // loop is changed to do-while format - int64_t bbsucc0Freq = bb.GetSucc(0)->GetFrequency() - newtgFreq; - int64_t bbsucc1Freq = bb.GetFrequency() - bbsucc0Freq; - bb.SetSuccFreq(0, bbsucc0Freq); - bb.SetSuccFreq(1, bbsucc1Freq); - } else if (latchBB->GetKind() == kBBCondGoto) { - int64_t newftFreq = (latchBB->GetFrequency() == 0 || bb.GetSuccFreq()[0] == 0) ? 0 : 1; - int64_t newtgFreq = latchBB->GetFrequency() == 0 ? 0 : (latchBB->GetFrequency() - newftFreq); - latchBB->SetSuccFreq(0, newftFreq); // freq to exit BB - latchBB->SetSuccFreq(1, newtgFreq); // loop is changed to do-while format - // update bb succ frequency - int64_t bbsucc0Freq = bb.GetSucc(0)->GetFrequency() - newftFreq; - int64_t bbsucc1Freq = bb.GetFrequency() - bbsucc0Freq; - bb.SetSuccFreq(0, bbsucc0Freq); - bb.SetSuccFreq(1, bbsucc1Freq); - } else if (latchBB->GetKind() == kBBFallthru || latchBB->GetKind() == kBBGoto) { - int64_t newsuccFreq = (latchBB->GetFrequency() == 0) ? 0 : latchBB->GetSuccFreq()[0] - 1; - latchBB->SetSuccFreq(0, newsuccFreq); // loop is changed to do-while format - bb.SetSuccFreq(0, bb.GetFrequency()); + if (func.GetCfg()->UpdateCFGFreq()) { + if (latchBB->GetKind() == kBBCondGoto) { + BB *succInloop = swapSuccOfLatch ? bb.GetSucc(0) : bb.GetSucc(1); + if ((latchBB->GetFrequency() != 0) && (succInloop->GetFrequency() > 0)) { + // loop is executed, bb->fallthru is in loopbody + int64_t latchFreq = latchBB->GetFrequency(); + if (swapSuccOfLatch) { + // bb fallthru is in loop, frequency of bb -> exitbb is set 0 + bb.SetSuccFreq(0, bb.GetFrequency()); + bb.SetSuccFreq(1, 0); + // latchBB fallthru is loop exit + ASSERT(bb.GetSucc(0)->GetFrequency() >= bb.GetFrequency(), "sanity check"); + int fallthrudiff = bb.GetSucc(0)->GetFrequency() - bb.GetFrequency(); + ASSERT(fallthrudiff >= 0, "sanity check"); + latchBB->PushBackSuccFreq(latchFreq - fallthrudiff); + latchBB->PushBackSuccFreq(fallthrudiff); + } else { + // bb->fallthru is loop exit, edge frequency of bb ->exitbb is set 0 + bb.SetSuccFreq(0, 0); + bb.SetSuccFreq(1, bb.GetFrequency()); + // latchBB fallthru is in loop + int fallthrudiff = bb.GetSucc(1)->GetFrequency() - bb.GetFrequency(); + ASSERT(fallthrudiff >= 0, "sanity check"); + latchBB->PushBackSuccFreq(fallthrudiff); + latchBB->PushBackSuccFreq(latchFreq - fallthrudiff); + } } else { - ASSERT(0, "NYI:: unexpected bb type"); + // loop is not executed + if (latchBB->GetFrequency() != 0) { + if (swapSuccOfLatch) { + bb.SetSuccFreq(0, 0); + bb.SetSuccFreq(1, bb.GetFrequency()); + } else { + bb.SetSuccFreq(0, bb.GetFrequency()); + bb.SetSuccFreq(1, 0); + } + } + ASSERT(latchBB->GetFrequency() == 0, "sanity check"); + latchBB->PushBackSuccFreq(0); + latchBB->PushBackSuccFreq(0); } + } else if (latchBB->GetKind() == kBBFallthru || latchBB->GetKind() == kBBGoto) { + int64_t newsuccFreq = (latchBB->GetFrequency() == 0) ? 0 : latchBB->GetSuccFreq()[0] - 1; + latchBB->SetSuccFreq(0, newsuccFreq); // loop is changed to do-while format + bb.SetSuccFreq(0, bb.GetFrequency()); + } else { + ASSERT(0, "NYI:: unexpected bb type"); } } // swap latchBB's succ if needed @@ -332,8 +344,8 @@ void MeLoopInversion::ExecuteLoopInversion(MeFunction &func, Dominance &dom) { } if ((NeedConvert(&func, *succ, *tmpPred, localAlloc, swapSuccs))) { if (isDebugFunc) { - LogInfo::MapleLogger() << "find new backedge " << succ->GetBBId() - << " <-- " << tmpPred->GetBBId() << '\n'; + LogInfo::MapleLogger() << "find new backedge " << succ->GetBBId() << " <-- " << tmpPred->GetBBId() + << '\n'; } backEdges.push_back(std::make_pair(succ, tmpPred)); } @@ -362,6 +374,9 @@ bool MELoopInversion::PhaseRun(maple::MeFunction &f) { if (meLoopInversion->IsCFGChange()) { GetAnalysisInfoHook()->ForceEraseAnalysisPhase(f.GetUniqueID(), &MEDominance::id); GetAnalysisInfoHook()->ForceEraseAnalysisPhase(f.GetUniqueID(), &MELoopAnalysis::id); + if (f.GetCfg()->UpdateCFGFreq() && (f.GetCfg()->DumpIRProfileFile())) { + f.GetCfg()->DumpToFile("after-loopinversion", false, true); + } } return true; } diff --git a/src/mapleall/maple_me/src/me_loop_unrolling.cpp b/src/mapleall/maple_me/src/me_loop_unrolling.cpp index 69caeb933a..5bc4f8cdfc 100644 --- a/src/mapleall/maple_me/src/me_loop_unrolling.cpp +++ b/src/mapleall/maple_me/src/me_loop_unrolling.cpp @@ -13,13 +13,15 @@ * See the Mulan PSL v2 for more details. */ #include "me_loop_unrolling.h" -#include + #include +#include + #include "me_cfg.h" #include "me_option.h" -#include "mir_module.h" -#include "mir_builder.h" #include "me_phase_manager.h" +#include "mir_builder.h" +#include "mir_module.h" namespace maple { bool LoopUnrollingExecutor::enableDebug = false; @@ -36,13 +38,15 @@ bool ProfileCheck(const maple::MeFunction &f) { auto &profile = f.GetMIRModule().GetProfile(); if (!profile.IsValid()) { if (LoopUnrollingExecutor::enableDebug) { - LogInfo::MapleLogger() << "DeCompress failed in loopUnrolling" << "\n"; + LogInfo::MapleLogger() << "DeCompress failed in loopUnrolling" + << "\n"; } return false; } if (!profile.CheckFuncHot(f.GetName())) { if (LoopUnrollingExecutor::enableDebug) { - LogInfo::MapleLogger() << "func is not hot" << "\n"; + LogInfo::MapleLogger() << "func is not hot" + << "\n"; } return false; } @@ -69,12 +73,12 @@ void LoopUnrolling::ComputeCodeSize(const MeStmt &meStmt, uint32 &cost) { case OP_brfalse: case OP_brtrue: case OP_maydassign: - CASE_OP_ASSERT_BOUNDARY { - cost += kTwoInsn; - break; - } + CASE_OP_ASSERT_BOUNDARY { + cost += kTwoInsn; + break; + } case OP_iassign: - CASE_OP_ASSERT_NONNULL + CASE_OP_ASSERT_NONNULL case OP_membaracquire: { cost += kThreeInsn; break; @@ -99,7 +103,7 @@ void LoopUnrolling::ComputeCodeSize(const MeStmt &meStmt, uint32 &cost) { } default: if (LoopUnrollingExecutor::enableDebug) { - LogInfo::MapleLogger() << "consider this op :"<< meStmt.GetOp() << "\n"; + LogInfo::MapleLogger() << "consider this op :" << meStmt.GetOp() << "\n"; } canUnroll = false; break; @@ -152,8 +156,8 @@ void LoopUnrolling::SetLabelWithCondGotoOrGotoBB(BB &bb, std::unordered_map &old2NewBB, BB &bb, - const BB &exitBB, BB &newHeadBB) { +void LoopUnrolling::ResetOldLabel2NewLabel(std::unordered_map &old2NewBB, BB &bb, const BB &exitBB, + BB &newHeadBB) { if (bb.GetKind() == kBBCondGoto) { CHECK_FATAL(!bb.GetMeStmts().empty(), "must not be empty"); CondGotoMeStmt &condGotoNode = static_cast(bb.GetMeStmts().back()); @@ -174,8 +178,8 @@ void LoopUnrolling::ResetOldLabel2NewLabel(std::unordered_map &old2New } // When loop unroll times more than two, use this function to update the preds and succs of duplicate loopbodys. -void LoopUnrolling::ResetOldLabel2NewLabel2(std::unordered_map &old2NewBB, BB &bb, - const BB &exitBB, BB &newHeadBB) { +void LoopUnrolling::ResetOldLabel2NewLabel2(std::unordered_map &old2NewBB, BB &bb, const BB &exitBB, + BB &newHeadBB) { if (bb.GetKind() == kBBCondGoto) { CHECK_FATAL(!bb.GetMeStmts().empty(), "must not be empty"); CondGotoMeStmt &condGotoNode = static_cast(bb.GetMeStmts().back()); @@ -194,23 +198,22 @@ void LoopUnrolling::ResetOldLabel2NewLabel2(std::unordered_map &old2Ne } } -void LoopUnrolling::ResetFrequency(const BB &curBB, const BB &succ, const BB &exitBB, - BB &curCopyBB, bool copyAllLoop) { +void LoopUnrolling::ResetFrequency(const BB &curBB, const BB &succ, const BB &exitBB, BB &curCopyBB, bool copyAllLoop) { if (resetFreqForUnrollWithVar && copyAllLoop) { if (&curBB == &exitBB && &succ == *loop->inloopBB2exitBBs.begin()->second->begin()) { curCopyBB.PushBackSuccFreq(loop->head->GetFrequency() % replicatedLoopNum == 0 ? 0 : 1); } if ((&curBB == loop->latch && &succ == loop->head) || (&curBB == &exitBB && &succ == loop->latch)) { - curCopyBB.PushBackSuccFreq(loop->head->GetFrequency() % replicatedLoopNum == 0 ? 0 : - loop->head->GetFrequency() % replicatedLoopNum - 1); + curCopyBB.PushBackSuccFreq( + loop->head->GetFrequency() % replicatedLoopNum == 0 ? 0 : loop->head->GetFrequency() % replicatedLoopNum - 1); } else { curCopyBB.PushBackSuccFreq(curBB.GetEdgeFreq(&succ) % replicatedLoopNum); } } else { - profValid && resetFreqForAfterInsertGoto ? - curCopyBB.PushBackSuccFreq(curBB.GetEdgeFreq(&succ) - 1 == 0 ? curBB.GetEdgeFreq(&succ) : - curBB.GetEdgeFreq(&succ) - 1) : - curCopyBB.PushBackSuccFreq(curBB.GetEdgeFreq(&succ)); + profValid &&resetFreqForAfterInsertGoto + ? curCopyBB.PushBackSuccFreq(curBB.GetEdgeFreq(&succ) - 1 == 0 ? curBB.GetEdgeFreq(&succ) + : curBB.GetEdgeFreq(&succ) - 1) + : curCopyBB.PushBackSuccFreq(curBB.GetEdgeFreq(&succ)); } } @@ -252,10 +255,9 @@ void LoopUnrolling::CopyLoopBodyForProfile(BB &newHeadBB, std::unordered_mapSetFrequency(succ->GetFrequency() % replicatedLoopNum); } } else { - resetFreqForAfterInsertGoto ? - newBB->SetFrequency(succ->GetFrequency() - 1 == 0 ? succ->GetFrequency() : - succ->GetFrequency() - 1) : - newBB->SetFrequency(succ->GetFrequency()); + resetFreqForAfterInsertGoto + ? newBB->SetFrequency(succ->GetFrequency() - 1 == 0 ? succ->GetFrequency() : succ->GetFrequency() - 1) + : newBB->SetFrequency(succ->GetFrequency()); } curCopyBB->AddSucc(*newBB); ResetFrequency(*curBB, *succ, exitBB, *curCopyBB, copyAllLoop); @@ -272,8 +274,8 @@ void LoopUnrolling::CopyLoopBodyForProfile(BB &newHeadBB, std::unordered_map &old2NewBB, - std::set &labelBBs, const BB &exitBB, bool copyAllLoop) { +void LoopUnrolling::CopyLoopBody(BB &newHeadBB, std::unordered_map &old2NewBB, std::set &labelBBs, + const BB &exitBB, bool copyAllLoop) { CreateLableAndInsertLabelBB(newHeadBB, labelBBs); std::queue bbQue; bbQue.push(loop->head); @@ -308,13 +310,13 @@ void LoopUnrolling::CopyLoopBody(BB &newHeadBB, std::unordered_map &ol // Update frequency of old BB. void LoopUnrolling::ResetFrequency(BB &bb) { auto freq = bb.GetFrequency() / replicatedLoopNum; - if (freq == 0 && partialCount == 0 && bb.GetFrequency() != 0) { + if ((!instrumentProf) && freq == 0 && partialCount == 0 && bb.GetFrequency() != 0) { freq = 1; } bb.SetFrequency(static_cast(freq + partialCount)); for (size_t i = 0; i < bb.GetSucc().size(); ++i) { auto currFreq = bb.GetEdgeFreq(i) / replicatedLoopNum; - if (currFreq == 0 && partialCount == 0 && bb.GetFrequency() != 0) { + if ((!instrumentProf) && currFreq == 0 && partialCount == 0 && bb.GetFrequency() != 0) { currFreq = 1; } bb.SetEdgeFreq(bb.GetSucc(i), currFreq + partialCount); @@ -366,10 +368,10 @@ void LoopUnrolling::AddEdgeForExitBBLastNew2OldBBEmpty(BB &exitBB, std::unordere bb->ReplaceSucc(&exitBB, &newHeadBB); exitBB.AddPred(*old2NewBB[bb], idx); if (profValid) { - resetFreqForAfterInsertGoto ? - (bb->GetEdgeFreq(idx) - 1 == 0 ? old2NewBB[bb]->PushBackSuccFreq(bb->GetEdgeFreq(idx)) : - old2NewBB[bb]->PushBackSuccFreq(bb->GetEdgeFreq(idx) - 1)) : - old2NewBB[bb]->PushBackSuccFreq(bb->GetEdgeFreq(idx)); + resetFreqForAfterInsertGoto + ? (bb->GetEdgeFreq(idx) - 1 == 0 ? old2NewBB[bb]->PushBackSuccFreq(bb->GetEdgeFreq(idx)) + : old2NewBB[bb]->PushBackSuccFreq(bb->GetEdgeFreq(idx) - 1)) + : old2NewBB[bb]->PushBackSuccFreq(bb->GetEdgeFreq(idx)); } ResetOldLabel2NewLabel(old2NewBB, *bb, exitBB, newHeadBB); } @@ -383,10 +385,10 @@ void LoopUnrolling::AddEdgeForExitBB(BB &exitBB, std::unordered_map &o bb->ReplaceSucc(&exitBB, &newHeadBB); exitBB.AddPred(*old2NewBB[lastNew2OldBB[bb]], idx); if (profValid) { - (resetFreqForAfterInsertGoto && firstResetForAfterInsertGoto) ? - (bb->GetEdgeFreq(idx) - 1 == 0 ? old2NewBB[lastNew2OldBB[bb]]->PushBackSuccFreq(bb->GetEdgeFreq(idx)) : - old2NewBB[lastNew2OldBB[bb]]->PushBackSuccFreq(bb->GetEdgeFreq(idx) - 1)) : - old2NewBB[lastNew2OldBB[bb]]->PushBackSuccFreq(bb->GetEdgeFreq(idx)); + (resetFreqForAfterInsertGoto && firstResetForAfterInsertGoto) + ? (bb->GetEdgeFreq(idx) - 1 == 0 ? old2NewBB[lastNew2OldBB[bb]]->PushBackSuccFreq(bb->GetEdgeFreq(idx)) + : old2NewBB[lastNew2OldBB[bb]]->PushBackSuccFreq(bb->GetEdgeFreq(idx) - 1)) + : old2NewBB[lastNew2OldBB[bb]]->PushBackSuccFreq(bb->GetEdgeFreq(idx)); firstResetForAfterInsertGoto = false; } ResetOldLabel2NewLabel2(old2NewBB, *bb, exitBB, newHeadBB); @@ -403,14 +405,14 @@ void LoopUnrolling::CopyAndInsertBB(bool isPartial) { ResetFrequency(*loop->head); ResetFrequency(); } - profValid && resetFreqForAfterInsertGoto ? - (loop->head->GetFrequency() - 1 == 0 ? newHeadBB->SetFrequency(loop->head->GetFrequency()) : - newHeadBB->SetFrequency(loop->head->GetFrequency() - 1)) : - newHeadBB->SetFrequency(loop->head->GetFrequency()); + profValid &&resetFreqForAfterInsertGoto + ? (loop->head->GetFrequency() - 1 == 0 ? newHeadBB->SetFrequency(loop->head->GetFrequency()) + : newHeadBB->SetFrequency(loop->head->GetFrequency() - 1)) + : newHeadBB->SetFrequency(loop->head->GetFrequency()); (void)old2NewBB.emplace(loop->head, newHeadBB); std::set labelBBs; - profValid ? CopyLoopBodyForProfile(*newHeadBB, old2NewBB, labelBBs, *exitBB, false) : - CopyLoopBody(*newHeadBB, old2NewBB, labelBBs, *exitBB, false); + profValid ? CopyLoopBodyForProfile(*newHeadBB, old2NewBB, labelBBs, *exitBB, false) + : CopyLoopBody(*newHeadBB, old2NewBB, labelBBs, *exitBB, false); if (isPartial) { partialSuccHead = newHeadBB; } @@ -653,7 +655,8 @@ bool LoopUnrolling::LoopPartialUnrollWithConst(uint64 tripCount) { uint32 index = 0; if (!DetermineUnrollTimes(index, true)) { if (LoopUnrollingExecutor::enableDebug) { - LogInfo::MapleLogger() << "CodeSize is too large" << "\n"; + LogInfo::MapleLogger() << "CodeSize is too large" + << "\n"; } return false; } @@ -709,8 +712,8 @@ void LoopUnrolling::CopyLoopForPartialAndPre(BB *&newHead, BB *&newExiting) { (void)old2NewBB.emplace(loop->head, newHeadBB); std::set labelBBs; resetFreqForUnrollWithVar = true; - profValid ? CopyLoopBodyForProfile(*newHeadBB, old2NewBB, labelBBs, *exitBB, true) : - CopyLoopBody(*newHeadBB, old2NewBB, labelBBs, *exitBB, true); + profValid ? CopyLoopBodyForProfile(*newHeadBB, old2NewBB, labelBBs, *exitBB, true) + : CopyLoopBody(*newHeadBB, old2NewBB, labelBBs, *exitBB, true); resetFreqForUnrollWithVar = false; for (auto bb : labelBBs) { if (bb->GetKind() == kBBCondGoto) { @@ -741,8 +744,8 @@ VarMeExpr *LoopUnrolling::CreateIndVarOrTripCountWithName(const std::string &nam } // i < tripcount / unrollTime -void LoopUnrolling::UpdateCondGotoStmt(BB &bb, VarMeExpr &indVar, MeExpr &tripCount, - MeExpr &unrollTimeExpr, uint32 offset) { +void LoopUnrolling::UpdateCondGotoStmt(BB &bb, VarMeExpr &indVar, MeExpr &tripCount, MeExpr &unrollTimeExpr, + uint32 offset) { for (auto &stmt : bb.GetMeStmts()) { bb.RemoveMeStmt(&stmt); } @@ -814,8 +817,8 @@ void LoopUnrolling::CopyLoopForPartial(BB &partialCondGoto, BB &exitedBB, BB &ex partialCondGoto.AddSucc(*partialHead); if (profValid) { partialCondGoto.PushBackSuccFreq(loop->head->GetFrequency() % replicatedLoopNum); - partialCondGoto.SetFrequency(static_cast(partialCondGoto.GetEdgeFreq(static_cast(0)) + - partialCondGoto.GetEdgeFreq(1))); + partialCondGoto.SetFrequency( + static_cast(partialCondGoto.GetEdgeFreq(static_cast(0)) + partialCondGoto.GetEdgeFreq(1))); } CHECK_FATAL(partialCondGoto.GetKind() == kBBCondGoto, "must be partialCondGoto"); CHECK_FATAL(!partialCondGoto.GetMeStmts().empty(), "must not be empty"); @@ -975,17 +978,19 @@ bool LoopUnrolling::LoopPartialUnrollWithVar(CR &cr, CRNode &varNode, uint32 j) uint32 index = 0; if (!DetermineUnrollTimes(index, false)) { if (LoopUnrollingExecutor::enableDebug) { - LogInfo::MapleLogger() << "codesize is too large" << "\n"; + LogInfo::MapleLogger() << "codesize is too large" + << "\n"; } return false; } if (LoopUnrollingExecutor::enableDebug) { - LogInfo::MapleLogger() << "partial unrolling with var" << "\n"; + LogInfo::MapleLogger() << "partial unrolling with var" + << "\n"; } if (LoopUnrollingExecutor::enableDump) { irMap->Dump(); - profValid ? cfg->DumpToFile("cfgIncludeFreqInfobeforeLoopPartialWithVarUnrolling", false, true) : - cfg->DumpToFile("cfgbeforeLoopPartialWithVarUnrolling"); + profValid ? cfg->DumpToFile("cfgIncludeFreqInfobeforeLoopPartialWithVarUnrolling", false, true) + : cfg->DumpToFile("cfgbeforeLoopPartialWithVarUnrolling"); } if (!SplitCondGotoBB()) { return false; @@ -1006,8 +1011,8 @@ bool LoopUnrolling::LoopPartialUnrollWithVar(CR &cr, CRNode &varNode, uint32 j) } if (LoopUnrollingExecutor::enableDump) { irMap->Dump(); - profValid ? cfg->DumpToFile("cfgIncludeFreqInfoafterLoopPartialWithVarUnrolling", false, true) : - cfg->DumpToFile("cfgafterLoopPartialWithVarUnrolling"); + profValid ? cfg->DumpToFile("cfgIncludeFreqInfoafterLoopPartialWithVarUnrolling", false, true) + : cfg->DumpToFile("cfgafterLoopPartialWithVarUnrolling"); } return true; } @@ -1021,7 +1026,7 @@ void LoopUnrollingExecutor::SetNestedLoop(const IdentifyLoops &meLoop, CHECK_NULL_FATAL(loop->parent); auto it = parentLoop.find(loop->parent); if (it == parentLoop.end()) { - parentLoop[loop->parent] = { loop }; + parentLoop[loop->parent] = {loop}; } else { parentLoop[loop->parent].insert(loop); } @@ -1064,7 +1069,8 @@ bool LoopUnrollingExecutor::PredIsOutOfLoopBB(const MeFunction &func, LoopDesc & return false; } -bool LoopUnrollingExecutor::IsCanonicalAndOnlyOneExitLoop(const MeFunction &func, LoopDesc &loop, +bool LoopUnrollingExecutor::IsCanonicalAndOnlyOneExitLoop( + const MeFunction &func, LoopDesc &loop, const std::unordered_map> &parentLoop) const { // Only handle one nested loop. if (parentLoop.find(&loop) != parentLoop.end() && ProfileCheck(func)) { @@ -1082,7 +1088,8 @@ bool LoopUnrollingExecutor::IsCanonicalAndOnlyOneExitLoop(const MeFunction &func CHECK_FATAL(headBB->GetPred().size() == 2, "head must has two preds"); if (!IsDoWhileLoop(func, loop)) { if (enableDebug) { - LogInfo::MapleLogger() << "While-do loop" << "\n"; + LogInfo::MapleLogger() << "While-do loop" + << "\n"; } return false; } @@ -1099,19 +1106,20 @@ bool LoopUnrollingExecutor::IsCanonicalAndOnlyOneExitLoop(const MeFunction &func bool LoopUnrolling::LoopUnrollingWithConst(uint64 tripCount, bool onlyFully) { if (tripCount == kInvalidTripCount) { if (LoopUnrollingExecutor::enableDebug) { - LogInfo::MapleLogger() << "tripCount is invalid" << "\n"; + LogInfo::MapleLogger() << "tripCount is invalid" + << "\n"; } return false; } if (LoopUnrollingExecutor::enableDebug) { - LogInfo::MapleLogger() << "start unrolling with const" << "\n"; + LogInfo::MapleLogger() << "start unrolling with const" + << "\n"; LogInfo::MapleLogger() << "tripCount: " << tripCount << "\n"; } if (LoopUnrollingExecutor::enableDebug) { irMap->Dump(); - func->IsIRProfValid() ? func->GetCfg()->DumpToFile("cfgIncludeFreqInfobeforLoopUnrolling", false, true) : - func->GetCfg()->DumpToFile("cfgbeforLoopUnrolling" + - std::to_string(loop->head->GetBBId())); + func->IsIRProfValid() ? func->GetCfg()->DumpToFile("cfgIncludeFreqInfobeforLoopUnrolling", false, true) + : func->GetCfg()->DumpToFile("cfgbeforLoopUnrolling" + std::to_string(loop->head->GetBBId())); } // fully unroll ReturnKindOfFullyUnroll returnKind = LoopFullyUnroll(static_cast(tripCount)); @@ -1120,13 +1128,14 @@ bool LoopUnrolling::LoopUnrollingWithConst(uint64 tripCount, bool onlyFully) { } if (returnKind == LoopUnrolling::kCanFullyUnroll) { if (LoopUnrollingExecutor::enableDebug) { - LogInfo::MapleLogger() << "fully unrolling" << "\n"; + LogInfo::MapleLogger() << "fully unrolling" + << "\n"; } if (LoopUnrollingExecutor::enableDebug) { irMap->Dump(); - func->IsIRProfValid() ? func->GetCfg()->DumpToFile("cfgIncludeFreqInfoafterLoopFullyUnrolling", false, true) : - func->GetCfg()->DumpToFile("cfgafterLoopFullyUnrolling" + - std::to_string(loop->head->GetBBId())); + func->IsIRProfValid() + ? func->GetCfg()->DumpToFile("cfgIncludeFreqInfoafterLoopFullyUnrolling", false, true) + : func->GetCfg()->DumpToFile("cfgafterLoopFullyUnrolling" + std::to_string(loop->head->GetBBId())); } return true; } @@ -1136,12 +1145,13 @@ bool LoopUnrolling::LoopUnrollingWithConst(uint64 tripCount, bool onlyFully) { // partial unroll with const if (LoopPartialUnrollWithConst(tripCount)) { if (LoopUnrollingExecutor::enableDebug) { - LogInfo::MapleLogger() << "partial unrolling with const" << "\n"; + LogInfo::MapleLogger() << "partial unrolling with const" + << "\n"; } if (LoopUnrollingExecutor::enableDebug) { irMap->Dump(); - func->IsIRProfValid() ? func->GetCfg()->DumpToFile("cfgIncludeFreqInfoafterLoopPartialWithConst", false, true) : - func->GetCfg()->DumpToFile("cfgafterLoopPartialWithConstUnrolling"); + func->IsIRProfValid() ? func->GetCfg()->DumpToFile("cfgIncludeFreqInfoafterLoopPartialWithConst", false, true) + : func->GetCfg()->DumpToFile("cfgafterLoopPartialWithConstUnrolling"); } return true; } @@ -1149,7 +1159,8 @@ bool LoopUnrolling::LoopUnrollingWithConst(uint64 tripCount, bool onlyFully) { } void LoopUnrollingExecutor::ExecuteLoopUnrolling(MeFunction &func, MeIRMap &irMap, - std::map>> &cands, IdentifyLoops &meLoop, const MapleAllocator &alloc) { + std::map>> &cands, + IdentifyLoops &meLoop, const MapleAllocator &alloc) { if (enableDebug) { LogInfo::MapleLogger() << func.GetName() << "\n"; } @@ -1167,6 +1178,9 @@ void LoopUnrollingExecutor::ExecuteLoopUnrolling(MeFunction &func, MeIRMap &irMa } LoopScalarAnalysisResult sa(irMap, loop); LoopUnrolling loopUnrolling(func, *loop, irMap, alloc, cands); + if (func.GetCfg()->UpdateCFGFreq()) { + loopUnrolling.SetInstrumentProf(true); + } uint64 tripCount = 0; CRNode *conditionCRNode = nullptr; CR *itCR = nullptr; @@ -1235,6 +1249,9 @@ bool MELoopUnrolling::PhaseRun(maple::MeFunction &f) { MeSSAUpdate ssaUpdate(f, *f.GetMeSSATab(), *dom, cands); ssaUpdate.Run(); GetAnalysisInfoHook()->ForceEraseAnalysisPhase(f.GetUniqueID(), &MELoopAnalysis::id); + if (f.GetCfg()->UpdateCFGFreq() && f.GetCfg()->DumpIRProfileFile()) { + f.GetCfg()->DumpToFile("after-meloopunroll", false, true); + } } if (DEBUGFUNC_NEWPM(f)) { f.GetCfg()->DumpToFile("afterloopunrolling", false); diff --git a/src/mapleall/maple_me/src/me_profile_use.cpp b/src/mapleall/maple_me/src/me_profile_use.cpp index 4d9c62b6ad..0041c51b0d 100644 --- a/src/mapleall/maple_me/src/me_profile_use.cpp +++ b/src/mapleall/maple_me/src/me_profile_use.cpp @@ -13,10 +13,12 @@ * See the Mulan PSL v2 for more details. */ #include "me_profile_use.h" + #include + #include "me_cfg.h" -#include "me_option.h" #include "me_function.h" +#include "me_option.h" namespace maple { BBUseInfo *MeProfUse::GetOrCreateBBUseInfo(const BB &bb) { @@ -206,8 +208,8 @@ bool MeProfUse::BuildEdgeCount() { uint64 hash = ComputeFuncHash(); if (hash != result.funcHash) { if (dump) { - LogInfo::MapleLogger() << func->GetName() << " hash doesn't match profile hash " - << result.funcHash << " func real hash " << hash << '\n'; + LogInfo::MapleLogger() << func->GetName() << " hash doesn't match profile hash " << result.funcHash + << " func real hash " << hash << '\n'; } return false; } @@ -218,8 +220,8 @@ bool MeProfUse::BuildEdgeCount() { } if (instrumentBBs.size() != result.totalCounter) { if (dump) { - LogInfo::MapleLogger() << func->GetName() << " counter doesn't match profile counter " - << result.totalCounter << " func real counter " << instrumentBBs.size() << '\n'; + LogInfo::MapleLogger() << func->GetName() << " counter doesn't match profile counter " << result.totalCounter + << " func real counter " << instrumentBBs.size() << '\n'; } return false; } @@ -295,7 +297,7 @@ bool MeProfUse::Run() { } FuncProfInfo *MeProfUse::GetFuncData() { - MplProfileData* profData = func->GetMIRModule().GetMapleProfile(); + MplProfileData *profData = func->GetMIRModule().GetMapleProfile(); if (!profData) { return nullptr; } @@ -316,14 +318,14 @@ bool MeProfUse::CheckSumFail(const uint64 hash, const uint32 expectedCheckSum, c } bool MeProfUse::MapleProfRun() { - FuncProfInfo* funcData = GetFuncData(); + FuncProfInfo *funcData = GetFuncData(); if (!funcData) { return false; } func->GetMirFunc()->SetFuncProfData(funcData); // early return if lineno fail if (CheckSumFail(ComputeLinenoHash(), funcData->linenoChecksum, "lineno")) { - func->GetMirFunc()->SetFuncProfData(nullptr); // clear func profile data + func->GetMirFunc()->SetFuncProfData(nullptr); // clear func profile data return false; } FindInstrumentEdges(); @@ -338,10 +340,10 @@ bool MeProfUse::MapleProfRun() { } if (instrumentBBs.size() != funcData->edgeCounts) { if (dump) { - LogInfo::MapleLogger() << func->GetName() << " counter doesn't match profile counter " - << funcData->edgeCounts << " func real counter " << instrumentBBs.size() << '\n'; + LogInfo::MapleLogger() << func->GetName() << " counter doesn't match profile counter " << funcData->edgeCounts + << " func real counter " << instrumentBBs.size() << '\n'; } - func->GetMirFunc()->SetFuncProfData(nullptr); // clear func profile data + func->GetMirFunc()->SetFuncProfData(nullptr); // clear func profile data return false; } size_t i = 0; @@ -370,16 +372,21 @@ bool MEProfUse::PhaseRun(maple::MeFunction &f) { if (Options::profileUse) { result = profUse.MapleProfRun(); if (result) { - f.GetCfg()->VerifyBBFreq(); + result = f.GetCfg()->VerifyBBFreq(); + if (result > 0 && (DEBUGFUNC_NEWPM(f))) { + LogInfo::MapleLogger() << "func profileUse verification fail" << std::endl; + } } } else { profUse.Run(); } - if (result) { + if (DEBUGFUNC_NEWPM(f)) { LogInfo::MapleLogger() << "******************after profile use dump function******************\n"; profUse.DumpFuncCFGEdgeFreq(); - f.GetCfg()->DumpToFile("afterProfileUse", false, true); + } + if (f.GetCfg()->DumpIRProfileFile()) { + f.GetCfg()->DumpToFile("after-ProfileUse", false, true); } return true; } diff --git a/src/mapleall/maple_me/src/me_value_range_prop.cpp b/src/mapleall/maple_me/src/me_value_range_prop.cpp index 3ac832808f..65ee00b5df 100644 --- a/src/mapleall/maple_me/src/me_value_range_prop.cpp +++ b/src/mapleall/maple_me/src/me_value_range_prop.cpp @@ -13,14 +13,15 @@ * See the Mulan PSL v2 for more details. */ #include "me_value_range_prop.h" -#include "me_dominance.h" + #include "me_abco.h" -#include "me_ssa_update.h" +#include "me_dominance.h" #include "me_phase_manager.h" #include "me_safety_warning.h" +#include "me_ssa_update.h" namespace maple { -bool ValueRangePropagation::isDebug = false; +bool ValueRangePropagation::isDebug = true; constexpr size_t kNumOperands = 2; constexpr size_t kCodeSizeLimit = 2000; constexpr std::uint64_t kInvaliedBound = 0xdeadbeef; @@ -38,8 +39,8 @@ bool Bound::CanBeComparedWith(const Bound &bound) const { if (var == bound.GetVar()) { return true; } - return (*this == MinBound(primType) || *this == MaxBound(primType) || - bound == MinBound(primType) || bound == MaxBound(primType)); + return (*this == MinBound(primType) || *this == MaxBound(primType) || bound == MinBound(primType) || + bound == MaxBound(primType)); } bool Bound::operator<(const Bound &bound) const { @@ -93,6 +94,10 @@ void ValueRangePropagation::Execute() { dealWithPhi = true; DealWithPhi(**bIt); dealWithPhi = false; + if (func.GetCfg()->UpdateCFGFreq()) { + // update edge frequency + (*bIt)->UpdateEdgeFreqs(false); + } for (auto it = (*bIt)->GetMeStmts().begin(); it != (*bIt)->GetMeStmts().end();) { bool deleteStmt = false; if (!onlyPropVR) { @@ -110,8 +115,8 @@ void ValueRangePropagation::Execute() { ++it; continue; } - if (MeOption::safeRegionMode && (it->IsInSafeRegion()) && - kOpcodeInfo.IsCall(it->GetOp()) && instance_of(*it)) { + if (MeOption::safeRegionMode && (it->IsInSafeRegion()) && kOpcodeInfo.IsCall(it->GetOp()) && + instance_of(*it)) { MIRFunction *callFunc = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(static_cast(*it).GetPUIdx()); if (callFunc->IsUnSafe()) { @@ -137,40 +142,40 @@ void ValueRangePropagation::Execute() { InsertValueRangeOfCondExpr2Caches(**bIt, *it); break; } - CASE_OP_ASSERT_NONNULL { - if (!dealWithAssert) { - break; - } - // If the option safeRegion is open and the stmt is not in safe region, delete it. - if (MeOption::safeRegionMode && !it->IsInSafeRegion()) { - deleteStmt = true; - } else if (DealWithAssertNonnull(**bIt, *it)) { - if (ValueRangePropagation::isDebug) { - LogInfo::MapleLogger() << "=========delete assert nonnull=========\n"; - it->Dump(&irMap); - LogInfo::MapleLogger() << "=========delete assert nonnull=========\n"; + CASE_OP_ASSERT_NONNULL { + if (!dealWithAssert) { + break; + } + // If the option safeRegion is open and the stmt is not in safe region, delete it. + if (MeOption::safeRegionMode && !it->IsInSafeRegion()) { + deleteStmt = true; + } else if (DealWithAssertNonnull(**bIt, *it)) { + if (ValueRangePropagation::isDebug) { + LogInfo::MapleLogger() << "=========delete assert nonnull=========\n"; + it->Dump(&irMap); + LogInfo::MapleLogger() << "=========delete assert nonnull=========\n"; + } + deleteStmt = true; } - deleteStmt = true; - } - break; - } - CASE_OP_ASSERT_BOUNDARY { - if (!dealWithAssert) { break; } - // If the option safeRegion is open and the stmt is not in safe region, delete it. - if (MeOption::safeRegionMode && !it->IsInSafeRegion()) { - deleteStmt = true; - } else if (DealWithBoundaryCheck(**bIt, *it)) { - if (ValueRangePropagation::isDebug) { - LogInfo::MapleLogger() << "=========delete boundary check=========\n"; - it->Dump(&irMap); - LogInfo::MapleLogger() << "=========delete boundary check=========\n"; + CASE_OP_ASSERT_BOUNDARY { + if (!dealWithAssert) { + break; + } + // If the option safeRegion is open and the stmt is not in safe region, delete it. + if (MeOption::safeRegionMode && !it->IsInSafeRegion()) { + deleteStmt = true; + } else if (DealWithBoundaryCheck(**bIt, *it)) { + if (ValueRangePropagation::isDebug) { + LogInfo::MapleLogger() << "=========delete boundary check=========\n"; + it->Dump(&irMap); + LogInfo::MapleLogger() << "=========delete boundary check=========\n"; + } + deleteStmt = true; } - deleteStmt = true; + break; } - break; - } case OP_callassigned: { DealWithCallassigned(**bIt, *it); break; @@ -201,7 +206,8 @@ void ValueRangePropagation::DealWithCallassigned(const BB &bb, MeStmt &stmt) { auto &callassign = static_cast(stmt); MIRFunction *callFunc = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callassign.GetPUIdx()); if (callFunc->GetAttr(FUNCATTR_nonnull) && callassign.GetAssignedLHS() != nullptr) { - (void)Insert2Caches(bb.GetBBId(), callassign.GetAssignedLHS()->GetExprID(), + (void)Insert2Caches( + bb.GetBBId(), callassign.GetAssignedLHS()->GetExprID(), std::make_unique(Bound(nullptr, 0, callassign.GetAssignedLHS()->GetPrimType()), kNotEqual)); } } @@ -222,9 +228,8 @@ void ValueRangePropagation::DealWithSwitch(BB &bb, MeStmt &stmt) { // Can prop value range to target bb only when the pred size of target bb is one and // only one case can jump to the target bb. if (currbb->GetPred().size() == 1 && bbOfCases.insert(currbb->GetBBId()).second) { - (void)Insert2Caches( - currbb->GetBBId(), opnd->GetExprID(), - std::make_unique(Bound(nullptr, pair.first, PTY_i64), kEqual)); + (void)Insert2Caches(currbb->GetBBId(), opnd->GetExprID(), + std::make_unique(Bound(nullptr, pair.first, PTY_i64), kEqual)); } else { (void)Insert2Caches(currbb->GetBBId(), opnd->GetExprID(), nullptr); } @@ -272,7 +277,7 @@ void ValueRangePropagation::DeleteThePhiNodeWhichOnlyHasOneOpnd( } } -bool ValueRange::IsEqual(ValueRange *valueRangeRight) const { +bool ValueRange::IsEqual(ValueRange *valueRangeRight) const { if (valueRangeRight == nullptr) { return false; } @@ -283,14 +288,11 @@ bool ValueRange::IsEqual(ValueRange *valueRangeRight) const { case kLowerAndUpper: case kSpecialUpperForLoop: case kSpecialLowerForLoop: - return range.pair.upper == (valueRangeRight->GetUpper()) && - range.pair.lower == (valueRangeRight->GetLower()); + return range.pair.upper == (valueRangeRight->GetUpper()) && range.pair.lower == (valueRangeRight->GetLower()); case kOnlyHasLowerBound: - return range.pair.lower == (valueRangeRight->GetLower()) && - stride == valueRangeRight->GetStride(); + return range.pair.lower == (valueRangeRight->GetLower()) && stride == valueRangeRight->GetStride(); case kOnlyHasUpperBound: - return range.pair.upper == (valueRangeRight->GetUpper()) && - stride == valueRangeRight->GetStride(); + return range.pair.upper == (valueRangeRight->GetUpper()) && stride == valueRangeRight->GetStride(); case kNotEqual: case kEqual: return range.bound == (valueRangeRight->GetBound()); @@ -324,7 +326,7 @@ std::unique_ptr MergeVR(const ValueRange &vr1, const ValueRange &vr2 return nullptr; } if (upper2 < lower1 || upper1 < lower2) { - return intersect ? std::make_unique(kRTEmpty) : nullptr; // always false + return intersect ? std::make_unique(kRTEmpty) : nullptr; // always false } else if (upper2 == lower1) { return intersect ? std::make_unique(lower1, kEqual) : std::make_unique(lower2, upper1, kLowerAndUpper); @@ -371,7 +373,7 @@ std::unique_ptr MergeVR(const ValueRange &vr1, const ValueRange &vr2 : std::make_unique(kRTComplete); // always true; } else if (bound == upper1) { return intersect ? std::make_unique(lower1, --upper1, kLowerAndUpper) - : std::make_unique(kRTComplete); // always true; + : std::make_unique(kRTComplete); // always true; } return nullptr; } @@ -387,7 +389,7 @@ std::unique_ptr MergeVR(const ValueRange &vr1, const ValueRange &vr2 } switch (vr2Type) { case kLowerAndUpper: { - return MergeVR(vr2, vr1, intersect); // swap two vr + return MergeVR(vr2, vr1, intersect); // swap two vr } case kEqual: { if (b1 == b2) { @@ -413,7 +415,7 @@ std::unique_ptr MergeVR(const ValueRange &vr1, const ValueRange &vr2 switch (vr2Type) { case kLowerAndUpper: case kEqual: { - return MergeVR(vr2, vr1, intersect); // swap two vr + return MergeVR(vr2, vr1, intersect); // swap two vr } case kNotEqual: { Bound b1 = vr1.GetBound(); @@ -439,7 +441,7 @@ std::unique_ptr MergeVR(const ValueRange &vr1, const ValueRange &vr2 MeExpr *GetCmpExprFromBound(Bound b, MeExpr &expr, MeIRMap *irmap, Opcode op) { int64 val = b.GetConstant(); - MeExpr *var = const_cast(b.GetVar()); + MeExpr *var = const_cast(b.GetVar()); PrimType ptyp = b.GetPrimType(); MeExpr *constExpr = irmap->CreateIntConstMeExpr(val, ptyp); MeExpr *resExpr = nullptr; @@ -526,19 +528,18 @@ std::unique_ptr ValueRangePropagation::ZeroIsInRange(const ValueRang valueRange.GetUpper().GetVar() == nullptr && valueRange.GetLower().GetConstant() < valueRange.GetUpper().GetConstant()) { if (valueRange.GetLower().GetConstant() == 0) { - return std::make_unique( - Bound(1, valueRange.GetLower().GetPrimType()), valueRange.GetUpper(), kLowerAndUpper); + return std::make_unique(Bound(1, valueRange.GetLower().GetPrimType()), valueRange.GetUpper(), + kLowerAndUpper); } if (valueRange.GetUpper().GetConstant() == 0) { - return std::make_unique( - valueRange.GetLower(), Bound(-1, valueRange.GetUpper().GetPrimType()), kLowerAndUpper); + return std::make_unique(valueRange.GetLower(), Bound(-1, valueRange.GetUpper().GetPrimType()), + kLowerAndUpper); } } return nullptr; } -std::unique_ptr ValueRangePropagation::FindValueRangeInCurrBBOrDominateBBs( - const BB &bb, MeExpr &opnd) { +std::unique_ptr ValueRangePropagation::FindValueRangeInCurrBBOrDominateBBs(const BB &bb, MeExpr &opnd) { auto *res = FindValueRangeInCurrentBB(bb.GetBBId(), opnd.GetExprID()); if (res != nullptr) { return CopyValueRange(*res); @@ -550,11 +551,10 @@ std::unique_ptr ValueRangePropagation::FindValueRangeInCurrBBOrDomin return nullptr; } -void SafetyCheckWithBoundaryError::HandleAssignWithDeadBeef( - const BB &bb, MeStmt &meStmt, MeExpr &indexOpnd, - MeExpr &boundOpnd) { +void SafetyCheckWithBoundaryError::HandleAssignWithDeadBeef(const BB &bb, MeStmt &meStmt, MeExpr &indexOpnd, + MeExpr &boundOpnd) { std::set visitedLHS; - std::vector stmts{ &meStmt }; + std::vector stmts{&meStmt}; vrp.JudgeTheConsistencyOfDefPointsOfBoundaryCheck(bb, indexOpnd, visitedLHS, stmts); visitedLHS.clear(); stmts.clear(); @@ -566,8 +566,8 @@ void SafetyCheckWithBoundaryError::HandleAssignWithDeadBeef( // valueRangeOfIndex zero is in range and in safe region mode, compiler err // valueRangeOfIndex is zero and not in safe region mode, compiler err void SafetyCheckWithNonnullError::HandleAssertNonnull(const MeStmt &meStmt, const ValueRange *valueRangeOfIndex) { - if ((valueRangeOfIndex == nullptr || valueRangeOfIndex->IsZeroInRange()) && - meStmt.IsInSafeRegion() && MeOption::safeRegionMode) { + if ((valueRangeOfIndex == nullptr || valueRangeOfIndex->IsZeroInRange()) && meStmt.IsInSafeRegion() && + MeOption::safeRegionMode) { (void)NeedDeleteTheAssertAfterErrorOrWarn(meStmt, true); } if (valueRangeOfIndex != nullptr && valueRangeOfIndex->IsEqualZero()) { @@ -579,8 +579,8 @@ bool SafetyCheckWithBoundaryError::HandleAssertError(const MeStmt &meStmt) { return NeedDeleteTheAssertAfterErrorOrWarn(meStmt); } -bool SafetyCheckWithBoundaryError::HandleAssertltOrAssertle( - const MeStmt &meStmt, Opcode op, int64 indexValue, int64 lengthValue) { +bool SafetyCheckWithBoundaryError::HandleAssertltOrAssertle(const MeStmt &meStmt, Opcode op, int64 indexValue, + int64 lengthValue) { if (kOpcodeInfo.IsAssertLeBoundary((op))) { if (indexValue > lengthValue) { return NeedDeleteTheAssertAfterErrorOrWarn(meStmt); @@ -593,19 +593,21 @@ bool SafetyCheckWithBoundaryError::HandleAssertltOrAssertle( return false; } -bool ValueRangePropagation::CompareConstantOfIndexAndLength( - const MeStmt &meStmt, const ValueRange &valueRangeOfIndex, ValueRange &valueRangeOfLengthPtr, Opcode op) { +bool ValueRangePropagation::CompareConstantOfIndexAndLength(const MeStmt &meStmt, const ValueRange &valueRangeOfIndex, + ValueRange &valueRangeOfLengthPtr, Opcode op) { if (safetyCheckBoundary->HandleAssertltOrAssertle(meStmt, op, valueRangeOfIndex.GetUpper().GetConstant(), valueRangeOfLengthPtr.GetBound().GetConstant())) { return true; } - return (kOpcodeInfo.IsAssertLeBoundary(op) ? - valueRangeOfIndex.GetUpper().GetConstant() <= valueRangeOfLengthPtr.GetBound().GetConstant() : - valueRangeOfIndex.GetUpper().GetConstant() < valueRangeOfLengthPtr.GetBound().GetConstant()); + return (kOpcodeInfo.IsAssertLeBoundary(op) + ? valueRangeOfIndex.GetUpper().GetConstant() <= valueRangeOfLengthPtr.GetBound().GetConstant() + : valueRangeOfIndex.GetUpper().GetConstant() < valueRangeOfLengthPtr.GetBound().GetConstant()); } bool ValueRangePropagation::CompareIndexWithUpper(const BB &bb, const MeStmt &meStmt, - const ValueRange &valueRangeOfIndex, ValueRange &valueRangeOfLengthPtr, Opcode op, const MeExpr *indexOpnd) { + const ValueRange &valueRangeOfIndex, + ValueRange &valueRangeOfLengthPtr, Opcode op, + const MeExpr *indexOpnd) { if (valueRangeOfIndex.GetRangeType() == kNotEqual || valueRangeOfLengthPtr.GetRangeType() == kNotEqual) { return false; } @@ -619,8 +621,8 @@ bool ValueRangePropagation::CompareIndexWithUpper(const BB &bb, const MeStmt &me upperOfLength)) { return true; } - return (kOpcodeInfo.IsAssertLeBoundary((op))) ? valueRangeOfIndex.GetUpper().GetConstant() <= lowerOfLength : - valueRangeOfIndex.GetUpper().GetConstant() < lowerOfLength; + return (kOpcodeInfo.IsAssertLeBoundary((op))) ? valueRangeOfIndex.GetUpper().GetConstant() <= lowerOfLength + : valueRangeOfIndex.GetUpper().GetConstant() < lowerOfLength; } if (!valueRangeOfIndex.IsConstantLowerAndUpper() || valueRangeOfIndex.GetLower().GetConstant() > valueRangeOfIndex.GetUpper().GetConstant() || @@ -645,8 +647,8 @@ bool ValueRangePropagation::CompareIndexWithUpper(const BB &bb, const MeStmt &me return true; } } - return (kOpcodeInfo.IsAssertLeBoundary((op))) ? valueRangeOfIndex.GetUpper().GetConstant() <= lowerOfLength : - valueRangeOfIndex.GetUpper().GetConstant() < lowerOfLength; + return (kOpcodeInfo.IsAssertLeBoundary((op))) ? valueRangeOfIndex.GetUpper().GetConstant() <= lowerOfLength + : valueRangeOfIndex.GetUpper().GetConstant() < lowerOfLength; } else if (valueRangeOfLengthPtr.GetRangeType() == kEqual) { // Opt array boundary check when the array length is a var. if (valueRangeOfIndex.GetRangeType() == kSpecialUpperForLoop || @@ -668,10 +670,9 @@ bool ValueRangePropagation::CompareIndexWithUpper(const BB &bb, const MeStmt &me } if (crNode->GetCRType() == kCRVarNode) { return (crNode->GetExpr() == valueRangeOfLengthPtr.GetBound().GetVar()) && - CompareConstantOfIndexAndLength(meStmt, valueRangeOfIndex, valueRangeOfLengthPtr, op); + CompareConstantOfIndexAndLength(meStmt, valueRangeOfIndex, valueRangeOfLengthPtr, op); } - if (crNode->GetCRType() != kCRAddNode || - static_cast(crNode)->GetOpndsSize() != kNumOperands || + if (crNode->GetCRType() != kCRAddNode || static_cast(crNode)->GetOpndsSize() != kNumOperands || static_cast(crNode)->GetOpnd(1)->GetExpr() == nullptr || static_cast(crNode)->GetOpnd(1)->GetExpr() != valueRangeOfLengthPtr.GetBound().GetVar() || static_cast(crNode)->GetOpnd(0)->GetCRType() != kCRConstNode) { @@ -683,8 +684,7 @@ bool ValueRangePropagation::CompareIndexWithUpper(const BB &bb, const MeStmt &me // expr = length - 1 // after analysis: valueRangeOfIndex : (lower(length), upper: (-2), kLowerAndUpper) int64 res = 0; - auto constantValue = - static_cast(static_cast(crNode)->GetOpnd(0))->GetConstValue(); + auto constantValue = static_cast(static_cast(crNode)->GetOpnd(0))->GetConstValue(); if (!AddOrSubWithConstant(valueRangeOfLengthPtr.GetUpper().GetPrimType(), OP_add, constantValue, valueRangeOfIndex.GetUpper().GetConstant(), res)) { return false; @@ -693,8 +693,8 @@ bool ValueRangePropagation::CompareIndexWithUpper(const BB &bb, const MeStmt &me valueRangeOfLengthPtr.GetBound().GetConstant())) { return true; } - return (kOpcodeInfo.IsAssertLeBoundary(op) ? res <= valueRangeOfLengthPtr.GetBound().GetConstant() : - res < valueRangeOfLengthPtr.GetBound().GetConstant()); + return (kOpcodeInfo.IsAssertLeBoundary(op) ? res <= valueRangeOfLengthPtr.GetBound().GetConstant() + : res < valueRangeOfLengthPtr.GetBound().GetConstant()); } else { return CompareConstantOfIndexAndLength(meStmt, valueRangeOfIndex, valueRangeOfLengthPtr, op); } @@ -707,9 +707,9 @@ bool ValueRangePropagation::CompareIndexWithUpper(const BB &bb, const MeStmt &me valueRangeOfLengthPtr.GetBound().GetConstant())) { return true; } - return kOpcodeInfo.IsAssertLeBoundary(op) ? - valueRangeOfIndex.GetUpper().GetConstant() <= valueRangeOfLengthPtr.GetBound().GetConstant() : - valueRangeOfIndex.GetUpper().GetConstant() < valueRangeOfLengthPtr.GetBound().GetConstant(); + return kOpcodeInfo.IsAssertLeBoundary(op) + ? valueRangeOfIndex.GetUpper().GetConstant() <= valueRangeOfLengthPtr.GetBound().GetConstant() + : valueRangeOfIndex.GetUpper().GetConstant() < valueRangeOfLengthPtr.GetBound().GetConstant(); } return false; } @@ -719,8 +719,9 @@ bool ValueRangePropagation::CompareIndexWithUpper(const BB &bb, const MeStmt &me bool ValueRangePropagation::IfAnalysisedBefore(const BB &bb, const MeStmt &stmt) { MeExpr &index = *stmt.GetOpnd(0); MeExpr &bound = *stmt.GetOpnd(1); - auto &analysisedArrayChecks = (kOpcodeInfo.IsAssertLowerBoundary(stmt.GetOp())) ? analysisedLowerBoundChecks : - (kOpcodeInfo.IsAssertLeBoundary(stmt.GetOp())) ? analysisedAssignBoundChecks : analysisedUpperBoundChecks; + auto &analysisedArrayChecks = (kOpcodeInfo.IsAssertLowerBoundary(stmt.GetOp())) ? analysisedLowerBoundChecks + : (kOpcodeInfo.IsAssertLeBoundary(stmt.GetOp())) ? analysisedAssignBoundChecks + : analysisedUpperBoundChecks; for (size_t i = 0; i < analysisedArrayChecks.size(); ++i) { auto *analysisedBB = func.GetCfg()->GetBBFromID(BBId(i)); if (!dom.Dominate(*analysisedBB, bb)) { @@ -741,8 +742,8 @@ bool ValueRangePropagation::IfAnalysisedBefore(const BB &bb, const MeStmt &stmt) return false; } -bool ValueRangePropagation::TheValueOfOpndIsInvaliedInABCO( - const BB &bb, const MeStmt *meStmt, MeExpr &boundOpnd, bool updateCaches) { +bool ValueRangePropagation::TheValueOfOpndIsInvaliedInABCO(const BB &bb, const MeStmt *meStmt, MeExpr &boundOpnd, + bool updateCaches) { if (boundOpnd.GetMeOp() == kMeOpConst && static_cast(boundOpnd).GetConstVal()->GetKind() == kConstInt && static_cast(static_cast(boundOpnd).GetExtIntValue()) == kInvaliedBound) { @@ -752,8 +753,8 @@ bool ValueRangePropagation::TheValueOfOpndIsInvaliedInABCO( return true; } else { auto *valueRange = FindValueRange(bb, boundOpnd); - if (valueRange != nullptr && valueRange->GetRangeType() != kNotEqual && - valueRange->IsConstant() && static_cast(valueRange->GetLower().GetConstant()) == kInvaliedBound) { + if (valueRange != nullptr && valueRange->GetRangeType() != kNotEqual && valueRange->IsConstant() && + static_cast(valueRange->GetLower().GetConstant()) == kInvaliedBound) { if (updateCaches) { Insert2AnalysisedArrayChecks(bb.GetBBId(), *meStmt->GetOpnd(1), *meStmt->GetOpnd(0), meStmt->GetOp()); } @@ -769,8 +770,9 @@ bool ValueRangePropagation::TheValueOfOpndIsInvaliedInABCO( // else: // p = GetBoundarylessPtr // error: p + i -void ValueRangePropagation::JudgeTheConsistencyOfDefPointsOfBoundaryCheck( - const BB &bb, MeExpr &expr, std::set &visitedLHS, std::vector &stmts) { +void ValueRangePropagation::JudgeTheConsistencyOfDefPointsOfBoundaryCheck(const BB &bb, MeExpr &expr, + std::set &visitedLHS, + std::vector &stmts) { if (TheValueOfOpndIsInvaliedInABCO(bb, nullptr, expr, false)) { std::string errorLog = "error: pointer assigned from multibranch requires the boundary info for all branches.\n"; for (size_t i = 0; i < stmts.size(); ++i) { @@ -782,7 +784,7 @@ void ValueRangePropagation::JudgeTheConsistencyOfDefPointsOfBoundaryCheck( } auto &srcPosition = stmts[i]->GetSrcPosition(); errorLog += func.GetMIRModule().GetFileNameFromFileNum(srcPosition.FileNum()) + ":" + - std::to_string(srcPosition.LineNum()) + "\n"; + std::to_string(srcPosition.LineNum()) + "\n"; } FATAL(kLncFatal, "%s", errorLog.c_str()); } @@ -867,8 +869,8 @@ static inline bool CanNotDoReplaceLoopVarOpt(const ValueRange *valueRange) { return type != kEqual && !(type == kLowerAndUpper && valueRange->IsAccurate()); } -void ValueRangePropagation::CollectIndexOpndWithBoundInLoop( - LoopDesc &loop, BB &bb, MeStmt &meStmt, MeExpr &opnd, std::map &index2NewExpr) { +void ValueRangePropagation::CollectIndexOpndWithBoundInLoop(LoopDesc &loop, BB &bb, MeStmt &meStmt, MeExpr &opnd, + std::map &index2NewExpr) { // If the var is opnd of ivar, can not replace it with the bound. // For example: array[s[i]] // assert(array + iread(s + i) * 4, array + 1024) @@ -908,20 +910,20 @@ void ValueRangePropagation::CollectIndexOpndWithBoundInLoop( MeExpr *ValueRangePropagation::GetAddressOfIndexOrBound(MeExpr &expr) const { if (expr.IsLeaf()) { - return (expr.IsScalar() && static_cast(expr).GetDefBy() == kDefByStmt) ? - GetAddressOfIndexOrBound(*static_cast(expr).GetDefStmt()->GetRHS()) : &expr; + return (expr.IsScalar() && static_cast(expr).GetDefBy() == kDefByStmt) + ? GetAddressOfIndexOrBound(*static_cast(expr).GetDefStmt()->GetRHS()) + : &expr; } return GetAddressOfIndexOrBound(*expr.GetOpnd(0)); } -void ValueRangePropagation::GetValueRangeOfCRNode( - const BB &bb, CRNode &opndOfCRNode, std::unique_ptr &resValueRange, PrimType pTypeOfArray) { +void ValueRangePropagation::GetValueRangeOfCRNode(const BB &bb, CRNode &opndOfCRNode, + std::unique_ptr &resValueRange, PrimType pTypeOfArray) { // Deal with the operand which is a constant. if (opndOfCRNode.GetCRType() == kCRConstNode) { int64 constant = static_cast(opndOfCRNode).GetConstValue(); - resValueRange = (resValueRange == nullptr) ? - std::make_unique(Bound(constant, pTypeOfArray), kEqual) : - AddOrSubWithValueRange(OP_add, *resValueRange, constant); + resValueRange = (resValueRange == nullptr) ? std::make_unique(Bound(constant, pTypeOfArray), kEqual) + : AddOrSubWithValueRange(OP_add, *resValueRange, constant); return; } // Deal with the operand which is a meexpr. @@ -931,8 +933,8 @@ void ValueRangePropagation::GetValueRangeOfCRNode( } auto valueRangOfOpnd = FindValueRangeInCurrBBOrDominateBBs(bb, *opndOfCRNode.GetExpr()); if (valueRangOfOpnd == nullptr) { - valueRangOfOpnd = std::make_unique( - Bound(opndOfCRNode.GetExpr(), opndOfCRNode.GetExpr()->GetPrimType()), kEqual); + valueRangOfOpnd = + std::make_unique(Bound(opndOfCRNode.GetExpr(), opndOfCRNode.GetExpr()->GetPrimType()), kEqual); if (resValueRange == nullptr) { resValueRange = std::move(valueRangOfOpnd); } else if (resValueRange->IsNotConstantVR()) { @@ -944,22 +946,22 @@ void ValueRangePropagation::GetValueRangeOfCRNode( } } } else if (valueRangOfOpnd->GetRangeType() == kNotEqual && resValueRange == nullptr) { - resValueRange = std::make_unique( - Bound(opndOfCRNode.GetExpr(), opndOfCRNode.GetExpr()->GetPrimType()), kEqual); + resValueRange = + std::make_unique(Bound(opndOfCRNode.GetExpr(), opndOfCRNode.GetExpr()->GetPrimType()), kEqual); } else if (valueRangOfOpnd->GetRangeType() == kOnlyHasUpperBound || valueRangOfOpnd->GetRangeType() == kOnlyHasLowerBound) { resValueRange = nullptr; } else { - resValueRange = (resValueRange == nullptr) ? std::move(valueRangOfOpnd) : - AddOrSubWithValueRange(OP_add, *resValueRange, *valueRangOfOpnd); + resValueRange = (resValueRange == nullptr) ? std::move(valueRangOfOpnd) + : AddOrSubWithValueRange(OP_add, *resValueRange, *valueRangOfOpnd); } } // Get the valueRange of index and bound, for example: // assertge(ptr, ptr + 8) -> the valueRange of index is 8 // assertge(ptr, ptr + len * 4 - 8) -> the valueRange of index is len - 2 -std::unique_ptr ValueRangePropagation::GetValueRangeOfCRNodes( - const BB &bb, PrimType pTypeOfArray, std::vector &crNodes) { +std::unique_ptr ValueRangePropagation::GetValueRangeOfCRNodes(const BB &bb, PrimType pTypeOfArray, + std::vector &crNodes) { if (crNodes.empty()) { return CreateValueRangeOfEqualZero(pTypeOfArray); } @@ -1043,12 +1045,14 @@ bool ValueRangePropagation::DealWithBoundaryCheck(BB &bb, MeStmt &meStmt) { } if (ValueRangePropagation::isDebug) { std::for_each(indexVector.begin(), indexVector.end(), [this](const CRNode *cr) { - sa.Dump(*cr); - std::cout << " ";}); + sa.Dump(*cr); + std::cout << " "; + }); LogInfo::MapleLogger() << "\n"; std::for_each(boundVector.begin(), boundVector.end(), [this](const CRNode *cr) { - sa.Dump(*cr); - std::cout << " ";}); + sa.Dump(*cr); + std::cout << " "; + }); LogInfo::MapleLogger() << "\n"; } // Get the valueRange of index and bound @@ -1058,8 +1062,7 @@ bool ValueRangePropagation::DealWithBoundaryCheck(BB &bb, MeStmt &meStmt) { return false; } if (kOpcodeInfo.IsAssertLowerBoundary(meStmt.GetOp())) { - if (BrStmtInRange(bb, *valueRangeOfIndex, *valueRangeOfbound, OP_ge, - valueRangeOfIndex->GetLower().GetPrimType())) { + if (BrStmtInRange(bb, *valueRangeOfIndex, *valueRangeOfbound, OP_ge, valueRangeOfIndex->GetLower().GetPrimType())) { // Can opt the boundary check. return true; } else if (BrStmtInRange(bb, *valueRangeOfIndex, *valueRangeOfbound, OP_lt, @@ -1069,8 +1072,8 @@ bool ValueRangePropagation::DealWithBoundaryCheck(BB &bb, MeStmt &meStmt) { return true; } } else if ((valueRangeOfIndex->GetRangeType() == kSpecialUpperForLoop || - valueRangeOfIndex->GetRangeType() == kOnlyHasLowerBound || - (valueRangeOfIndex->GetRangeType() == kLowerAndUpper && valueRangeOfIndex->IsAccurate())) && + valueRangeOfIndex->GetRangeType() == kOnlyHasLowerBound || + (valueRangeOfIndex->GetRangeType() == kLowerAndUpper && valueRangeOfIndex->IsAccurate())) && valueRangeOfIndex->GetLower().GetVar() == nullptr && valueRangeOfbound->GetLower().GetVar() == nullptr && valueRangeOfbound->GetUpper().GetVar() == nullptr) { if (valueRangeOfIndex->GetLower().GetConstant() < valueRangeOfbound->GetUpper().GetConstant()) { @@ -1084,8 +1087,8 @@ bool ValueRangePropagation::DealWithBoundaryCheck(BB &bb, MeStmt &meStmt) { return true; } } else if (valueRangeOfIndex->GetRangeType() == kLowerAndUpper && valueRangeOfIndex->IsAccurate() && - valueRangeOfIndex->IsConstantLowerAndUpper() && valueRangeOfbound->IsEqualZero() && - valueRangeOfIndex->GetLower().GetConstant() < 0) { + valueRangeOfIndex->IsConstantLowerAndUpper() && valueRangeOfbound->IsEqualZero() && + valueRangeOfIndex->GetLower().GetConstant() < 0) { // Error during static compilation. if (safetyCheckBoundary->HandleAssertError(meStmt)) { return true; @@ -1125,24 +1128,24 @@ bool SafetyCheck::NeedDeleteTheAssertAfterErrorOrWarn(const MeStmt &stmt, bool i switch (stmt.GetOp()) { case OP_calcassertlt: case OP_calcassertge: { - auto &newStmt = static_cast(stmt); + auto &newStmt = static_cast(stmt); GStrIdx curFuncNameIdx = func->GetMirFunc()->GetNameStrIdx(); GStrIdx stmtFuncNameIdx = GlobalTables::GetStrTable().GetStrIdxFromName(newStmt.GetFuncName().c_str()); if (curFuncNameIdx == stmtFuncNameIdx) { if (stmt.GetOp() == OP_calcassertlt) { - WARN(kLncWarn, "%s:%d warning: the pointer >= the upper bounds after calculation", - fileName, srcPosition.LineNum()); + WARN(kLncWarn, "%s:%d warning: the pointer >= the upper bounds after calculation", fileName, + srcPosition.LineNum()); } else if (stmt.GetOp() == OP_calcassertge) { - WARN(kLncWarn, "%s:%d warning: the pointer < the lower bounds after calculation", - fileName, srcPosition.LineNum()); + WARN(kLncWarn, "%s:%d warning: the pointer < the lower bounds after calculation", fileName, + srcPosition.LineNum()); } } else { if (stmt.GetOp() == OP_calcassertlt) { WARN(kLncWarn, "%s:%d warning: the pointer >= the upper bounds after calculation when inlined to %s", fileName, srcPosition.LineNum(), func->GetName().c_str()); } else if (stmt.GetOp() == OP_calcassertge) { - WARN(kLncWarn, "%s:%d warning: the pointer < the lower bounds after calculation when inlined to %s", - fileName, srcPosition.LineNum(), func->GetName().c_str()); + WARN(kLncWarn, "%s:%d warning: the pointer < the lower bounds after calculation when inlined to %s", fileName, + srcPosition.LineNum(), func->GetName().c_str()); } } return true; @@ -1150,20 +1153,20 @@ bool SafetyCheck::NeedDeleteTheAssertAfterErrorOrWarn(const MeStmt &stmt, bool i case OP_assignassertnonnull: case OP_assertnonnull: case OP_returnassertnonnull: { - auto &newStmt = static_cast(stmt); + auto &newStmt = static_cast(stmt); GStrIdx curFuncNameIdx = func->GetMirFunc()->GetNameStrIdx(); GStrIdx stmtFuncNameIdx = GlobalTables::GetStrTable().GetStrIdxFromName(newStmt.GetFuncName().c_str()); if (curFuncNameIdx == stmtFuncNameIdx) { if (isNullablePtr) { if (stmt.GetOp() == OP_assertnonnull) { - FATAL(kLncFatal, "%s:%d error: Dereference of nullable pointer in safe region", - fileName, srcPosition.LineNum()); + FATAL(kLncFatal, "%s:%d error: Dereference of nullable pointer in safe region", fileName, + srcPosition.LineNum()); } else if (stmt.GetOp() == OP_returnassertnonnull) { - FATAL(kLncFatal, "%s:%d error: %s return nonnull but got nullable pointer in safe region", - fileName, srcPosition.LineNum(), newStmt.GetFuncName().c_str()); + FATAL(kLncFatal, "%s:%d error: %s return nonnull but got nullable pointer in safe region", fileName, + srcPosition.LineNum(), newStmt.GetFuncName().c_str()); } else { - FATAL(kLncFatal, "%s:%d error: nullable pointer assignment of nonnull pointer in safe region", - fileName, srcPosition.LineNum()); + FATAL(kLncFatal, "%s:%d error: nullable pointer assignment of nonnull pointer in safe region", fileName, + srcPosition.LineNum()); } } else { if (stmt.GetOp() == OP_assertnonnull) { @@ -1178,12 +1181,12 @@ bool SafetyCheck::NeedDeleteTheAssertAfterErrorOrWarn(const MeStmt &stmt, bool i } else { if (isNullablePtr) { if (stmt.GetOp() == OP_assertnonnull) { - FATAL(kLncFatal, "%s:%d error: Dereference of nullable pointer in safe region when inlined to %s", - fileName, srcPosition.LineNum(), func->GetName().c_str()); + FATAL(kLncFatal, "%s:%d error: Dereference of nullable pointer in safe region when inlined to %s", fileName, + srcPosition.LineNum(), func->GetName().c_str()); } else if (stmt.GetOp() == OP_returnassertnonnull) { FATAL(kLncFatal, - "%s:%d error: %s return nonnull but got nullable pointer in safe region when inlined to %s", - fileName, srcPosition.LineNum(), newStmt.GetFuncName().c_str(), func->GetName().c_str()); + "%s:%d error: %s return nonnull but got nullable pointer in safe region when inlined to %s", fileName, + srcPosition.LineNum(), newStmt.GetFuncName().c_str(), func->GetName().c_str()); } else { FATAL(kLncFatal, "%s:%d error: nullable pointer assignment of nonnull pointer in safe region when inlined to %s", @@ -1191,27 +1194,29 @@ bool SafetyCheck::NeedDeleteTheAssertAfterErrorOrWarn(const MeStmt &stmt, bool i } } else { if (stmt.GetOp() == OP_assertnonnull) { - FATAL(kLncFatal, "%s:%d error: Dereference of null pointer when inlined to %s", - fileName, srcPosition.LineNum(), func->GetName().c_str()); + FATAL(kLncFatal, "%s:%d error: Dereference of null pointer when inlined to %s", fileName, + srcPosition.LineNum(), func->GetName().c_str()); } else if (stmt.GetOp() == OP_returnassertnonnull) { - FATAL(kLncFatal, "%s:%d error: %s return nonnull but got null pointer when inlined to %s", - fileName, srcPosition.LineNum(), newStmt.GetFuncName().c_str(), func->GetName().c_str()); + FATAL(kLncFatal, "%s:%d error: %s return nonnull but got null pointer when inlined to %s", fileName, + srcPosition.LineNum(), newStmt.GetFuncName().c_str(), func->GetName().c_str()); } else { - FATAL(kLncFatal, "%s:%d error: null assignment of nonnull pointer when inlined to %s", - fileName, srcPosition.LineNum(), func->GetName().c_str()); + FATAL(kLncFatal, "%s:%d error: null assignment of nonnull pointer when inlined to %s", fileName, + srcPosition.LineNum(), func->GetName().c_str()); } } } break; } case OP_callassertnonnull: { - auto &callStmt = static_cast(stmt); + auto &callStmt = static_cast(stmt); GStrIdx curFuncNameIdx = func->GetMirFunc()->GetNameStrIdx(); GStrIdx stmtFuncNameIdx = GlobalTables::GetStrTable().GetStrIdxFromName(callStmt.GetStmtFuncName().c_str()); if (curFuncNameIdx == stmtFuncNameIdx) { if (isNullablePtr) { - FATAL(kLncFatal, "%s:%d error: nullable pointer passed to %s that requires a nonnull pointer "\ - "for %s argument in safe region", fileName, srcPosition.LineNum(), callStmt.GetFuncName().c_str(), + FATAL(kLncFatal, + "%s:%d error: nullable pointer passed to %s that requires a nonnull pointer " + "for %s argument in safe region", + fileName, srcPosition.LineNum(), callStmt.GetFuncName().c_str(), GetNthStr(callStmt.GetParamIndex()).c_str()); } else { FATAL(kLncFatal, "%s:%d error: NULL passed to %s that requires a nonnull pointer for %s argument", fileName, @@ -1219,12 +1224,16 @@ bool SafetyCheck::NeedDeleteTheAssertAfterErrorOrWarn(const MeStmt &stmt, bool i } } else { if (isNullablePtr) { - FATAL(kLncFatal, "%s:%d error: nullable pointer passed to %s that requires a nonnull pointer "\ - "for %s argument in safe region when inlined to %s", fileName, srcPosition.LineNum(), - callStmt.GetFuncName().c_str(), GetNthStr(callStmt.GetParamIndex()).c_str(), func->GetName().c_str()); + FATAL(kLncFatal, + "%s:%d error: nullable pointer passed to %s that requires a nonnull pointer " + "for %s argument in safe region when inlined to %s", + fileName, srcPosition.LineNum(), callStmt.GetFuncName().c_str(), + GetNthStr(callStmt.GetParamIndex()).c_str(), func->GetName().c_str()); } else { - FATAL(kLncFatal, "%s:%d error: NULL passed to %s that requires a nonnull pointer for %s argument "\ - "when inlined to %s", fileName, srcPosition.LineNum(), callStmt.GetFuncName().c_str(), + FATAL(kLncFatal, + "%s:%d error: NULL passed to %s that requires a nonnull pointer for %s argument " + "when inlined to %s", + fileName, srcPosition.LineNum(), callStmt.GetFuncName().c_str(), GetNthStr(callStmt.GetParamIndex()).c_str(), func->GetName().c_str()); } } @@ -1234,16 +1243,16 @@ bool SafetyCheck::NeedDeleteTheAssertAfterErrorOrWarn(const MeStmt &stmt, bool i case OP_assignassertle: case OP_assertlt: case OP_assertge: { - auto &newStmt = static_cast(stmt); + auto &newStmt = static_cast(stmt); GStrIdx curFuncNameIdx = func->GetMirFunc()->GetNameStrIdx(); GStrIdx stmtFuncNameIdx = GlobalTables::GetStrTable().GetStrIdxFromName(newStmt.GetFuncName().c_str()); if (curFuncNameIdx == stmtFuncNameIdx) { if (stmt.GetOp() == OP_assertlt) { - FATAL(kLncFatal, "%s:%d error: the pointer >= the upper bounds when accessing the memory", - fileName, srcPosition.LineNum()); + FATAL(kLncFatal, "%s:%d error: the pointer >= the upper bounds when accessing the memory", fileName, + srcPosition.LineNum()); } else if (stmt.GetOp() == OP_assertge) { - FATAL(kLncFatal, "%s:%d error: the pointer < the lower bounds when accessing the memory", - fileName, srcPosition.LineNum()); + FATAL(kLncFatal, "%s:%d error: the pointer < the lower bounds when accessing the memory", fileName, + srcPosition.LineNum()); } else if (stmt.GetOp() == OP_assignassertle) { FATAL(kLncFatal, "%s:%d error: l-value boundary should not be larger than r-value boundary", fileName, srcPosition.LineNum()); @@ -1260,8 +1269,8 @@ bool SafetyCheck::NeedDeleteTheAssertAfterErrorOrWarn(const MeStmt &stmt, bool i fileName, srcPosition.LineNum(), func->GetName().c_str()); } else if (stmt.GetOp() == OP_assignassertle) { FATAL(kLncFatal, - "%s:%d error: l-value boundary should not be larger than r-value boundary when inlined to %s", - fileName, srcPosition.LineNum(), func->GetName().c_str()); + "%s:%d error: l-value boundary should not be larger than r-value boundary when inlined to %s", fileName, + srcPosition.LineNum(), func->GetName().c_str()); } else { FATAL(kLncFatal, "%s:%d error: return value's bounds does not match the function declaration for %s when inlined to %s", @@ -1280,9 +1289,11 @@ bool SafetyCheck::NeedDeleteTheAssertAfterErrorOrWarn(const MeStmt &stmt, bool i func->GetMIRModule().GetFileNameFromFileNum(srcPosition.FileNum()).c_str(), srcPosition.LineNum(), callStmt.GetFuncName().c_str(), GetNthStr(callStmt.GetParamIndex()).c_str()); } else { - FATAL(kLncFatal, "%s:%d error: the pointer's bounds does not match the function %s declaration "\ - "for the %s argument when inlined to %s", fileName, srcPosition.LineNum(), - callStmt.GetFuncName().c_str(), GetNthStr(callStmt.GetParamIndex()).c_str(), func->GetName().c_str()); + FATAL(kLncFatal, + "%s:%d error: the pointer's bounds does not match the function %s declaration " + "for the %s argument when inlined to %s", + fileName, srcPosition.LineNum(), callStmt.GetFuncName().c_str(), + GetNthStr(callStmt.GetParamIndex()).c_str(), func->GetName().c_str()); } break; } @@ -1343,8 +1354,8 @@ void ValueRangePropagation::ReplaceOpndWithConstMeExpr(const BB &bb, MeStmt &stm } // When the valuerange of expr is constant, collect it and do replace later. -void ValueRangePropagation::CollectMeExpr( - const BB &bb, MeStmt &stmt, MeExpr &meExpr, std::map> &expr2ConstantValue) { +void ValueRangePropagation::CollectMeExpr(const BB &bb, MeStmt &stmt, MeExpr &meExpr, + std::map> &expr2ConstantValue) { if (meExpr.GetMeOp() == kMeOpConst) { return; } @@ -1352,10 +1363,10 @@ void ValueRangePropagation::CollectMeExpr( if (valueRangeOfOperand != nullptr && valueRangeOfOperand->IsConstant() && valueRangeOfOperand->GetRangeType() != kNotEqual && stmt.GetOp() != OP_asm) { auto rangeType = valueRangeOfOperand->GetRangeType(); - int64 value = (rangeType == kEqual) ? valueRangeOfOperand->GetBound().GetConstant() : - valueRangeOfOperand->GetLower().GetConstant(); - PrimType pType = (rangeType == kEqual) ? valueRangeOfOperand->GetBound().GetPrimType() : - valueRangeOfOperand->GetLower().GetPrimType(); + int64 value = (rangeType == kEqual) ? valueRangeOfOperand->GetBound().GetConstant() + : valueRangeOfOperand->GetLower().GetConstant(); + PrimType pType = (rangeType == kEqual) ? valueRangeOfOperand->GetBound().GetPrimType() + : valueRangeOfOperand->GetLower().GetPrimType(); expr2ConstantValue[&meExpr] = std::make_pair(value, pType); return; } @@ -1373,9 +1384,9 @@ void ValueRangePropagation::CreateVRWithBitsSize(const BB &bb, const OpMeExpr &o if (bitsSize < 64) { auto pTypeOfOpMeExpr = opMeExpr.GetPrimType(); uint64 maxNumber = (1ULL << bitsSize) - 1; - (void)Insert2Caches(bb.GetBBId(), opMeExpr.GetExprID(), std::make_unique( - Bound(nullptr, 0, pTypeOfOpMeExpr), - Bound(maxNumber, pTypeOfOpMeExpr), kLowerAndUpper)); + (void)Insert2Caches(bb.GetBBId(), opMeExpr.GetExprID(), + std::make_unique(Bound(nullptr, 0, pTypeOfOpMeExpr), + Bound(maxNumber, pTypeOfOpMeExpr), kLowerAndUpper)); } } @@ -1383,8 +1394,10 @@ void ValueRangePropagation::DealWithOperand(const BB &bb, MeStmt &stmt, MeExpr & switch (meExpr.GetMeOp()) { case kMeOpConst: { if (static_cast(meExpr).GetConstVal()->GetKind() == kConstInt) { - (void)Insert2Caches(bb.GetBBId(), meExpr.GetExprID(), std::make_unique( - Bound(nullptr, static_cast(meExpr).GetExtIntValue(), meExpr.GetPrimType()), kEqual)); + (void)Insert2Caches( + bb.GetBBId(), meExpr.GetExprID(), + std::make_unique( + Bound(nullptr, static_cast(meExpr).GetExtIntValue(), meExpr.GetPrimType()), kEqual)); } break; } @@ -1453,13 +1466,13 @@ void ValueRangePropagation::DealWithOperand(const BB &bb, MeStmt &stmt, MeExpr & // Judge whether the truncated range is the same as the previous range. if (valueRange->IsEqualAfterCVT(valueRange->GetLower().GetPrimType(), pTypeOpnd) && valueRange->GetUpper().IsLessThanOrEqualTo(Bound(maxNumber, PTY_u64), PTY_u64)) { - (void) Insert2Caches(bb.GetBBId(), opMeExpr.GetExprID(), CopyValueRange(*valueRange)); + (void)Insert2Caches(bb.GetBBId(), opMeExpr.GetExprID(), CopyValueRange(*valueRange)); break; } } } } - [[clang::fallthrough]]; + [[clang::fallthrough]]; case OP_extractbits: { // extractbits () // Deal with the case like : @@ -1556,14 +1569,15 @@ bool ValueRangePropagation::DealWithCVT(const BB &bb, MeStmt &stmt, OpMeExpr &op } if ((fromType == PTY_u1 || fromType == PTY_u8 || fromType == PTY_u16 || fromType == PTY_u32 || fromType == PTY_a32 || - ((fromType == PTY_ref || fromType == PTY_ptr) && GetPrimTypeSize(fromType) == 4)) && + ((fromType == PTY_ref || fromType == PTY_ptr) && GetPrimTypeSize(fromType) == 4)) && GetPrimTypeBitSize(toType) > GetPrimTypeBitSize(fromType)) { auto *valueRange = FindValueRange(bb, opMeExpr); if (valueRange != nullptr) { return false; } - (void)Insert2Caches(bb.GetBBId(), opMeExpr.GetExprID(), std::make_unique( - Bound(nullptr, 0, fromType), Bound(GetMaxNumber(fromType), fromType), kLowerAndUpper)); + (void)Insert2Caches(bb.GetBBId(), opMeExpr.GetExprID(), + std::make_unique(Bound(nullptr, 0, fromType), + Bound(GetMaxNumber(fromType), fromType), kLowerAndUpper)); } return false; } @@ -1571,8 +1585,7 @@ bool ValueRangePropagation::DealWithCVT(const BB &bb, MeStmt &stmt, OpMeExpr &op // When unreachable bb has trystmt or endtry attribute, need update try and endtry bbs. void ValueRangePropagation::UpdateTryAttribute(BB &bb) { // update try end bb - if (bb.GetAttributes(kBBAttrIsTryEnd) && - (bb.GetMeStmts().empty() || (bb.GetMeStmts().front().GetOp() != OP_try))) { + if (bb.GetAttributes(kBBAttrIsTryEnd) && (bb.GetMeStmts().empty() || (bb.GetMeStmts().front().GetOp() != OP_try))) { auto *startTryBB = func.GetCfg()->GetTryBBFromEndTryBB(&bb); auto *newEndTry = func.GetCfg()->GetBBFromID(bb.GetBBId() - 1); CHECK_NULL_FATAL(newEndTry); @@ -1583,8 +1596,7 @@ void ValueRangePropagation::UpdateTryAttribute(BB &bb) { } } // update start try bb - if (!bb.GetMeStmts().empty() && bb.GetMeStmts().front().GetOp() == OP_try && - !bb.GetAttributes(kBBAttrIsTryEnd)) { + if (!bb.GetMeStmts().empty() && bb.GetMeStmts().front().GetOp() == OP_try && !bb.GetAttributes(kBBAttrIsTryEnd)) { for (auto &pair : func.GetCfg()->GetEndTryBB2TryBB()) { if (pair.second == &bb) { auto *newStartTry = func.GetCfg()->GetBBFromID(bb.GetBBId() + 1); @@ -1599,9 +1611,9 @@ void ValueRangePropagation::UpdateTryAttribute(BB &bb) { } // Insert the ost of phi opnds to their def bbs. -void ValueRangePropagation::InsertOstOfPhi2Cands( - BB &bb, size_t i, ScalarMeExpr *updateSSAExceptTheScalarExpr, - std::map> &ssaupdateCandsForCondExpr, bool setPhiIsDead) { +void ValueRangePropagation::InsertOstOfPhi2Cands(BB &bb, size_t i, ScalarMeExpr *updateSSAExceptTheScalarExpr, + std::map> &ssaupdateCandsForCondExpr, + bool setPhiIsDead) { for (auto &it : bb.GetMePhiList()) { if (setPhiIsDead) { it.second->SetIsLive(false); @@ -1634,8 +1646,8 @@ void ValueRangePropagation::PrepareForSSAUpdateWhenPredBBIsRemoved( int index = bb.GetPredIndex(pred); CHECK_FATAL(index != -1, "pred is not in preds of bb"); InsertOstOfPhi2Cands(bb, static_cast(index), updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); - auto updateSSAExceptTheOstIdx = updateSSAExceptTheScalarExpr == nullptr ? OStIdx(0) : - updateSSAExceptTheScalarExpr->GetOstIdx(); + auto updateSSAExceptTheOstIdx = + updateSSAExceptTheScalarExpr == nullptr ? OStIdx(0) : updateSSAExceptTheScalarExpr->GetOstIdx(); MeSSAUpdate::InsertDefPointsOfBBToSSACands(bb, cands, updateSSAExceptTheOstIdx); } @@ -1699,9 +1711,9 @@ int64 GetMinNumber(PrimType primType) { return std::numeric_limits::min(); case PTY_ref: case PTY_ptr: - if (GetPrimTypeSize(primType) == kFourByte) { // 32 bit + if (GetPrimTypeSize(primType) == kFourByte) { // 32 bit return std::numeric_limits::min(); - } else { // 64 bit + } else { // 64 bit CHECK_FATAL(GetPrimTypeSize(primType) == kEightByte, "must be 64 bit"); return std::numeric_limits::min(); } @@ -1734,9 +1746,9 @@ int64 GetMaxNumber(PrimType primType) { return std::numeric_limits::max(); case PTY_ref: case PTY_ptr: - if (GetPrimTypeSize(primType) == kFourByte) { // 32 bit + if (GetPrimTypeSize(primType) == kFourByte) { // 32 bit return std::numeric_limits::max(); - } else { // 64 bit + } else { // 64 bit CHECK_FATAL(GetPrimTypeSize(primType) == kEightByte, "must be 64 bit"); return std::numeric_limits::max(); } @@ -1751,15 +1763,14 @@ int64 GetMaxNumber(PrimType primType) { } // If the result of operator add or sub is overflow or underflow, return false. -bool ValueRangePropagation::AddOrSubWithConstant( - PrimType primType, Opcode op, int64 lhsConstant, int64 rhsConstant, int64 &res) const { +bool ValueRangePropagation::AddOrSubWithConstant(PrimType primType, Opcode op, int64 lhsConstant, int64 rhsConstant, + int64 &res) const { if (ConstantFold::IntegerOpIsOverflow(op, primType, lhsConstant, rhsConstant)) { return false; } if (IsPrimTypeUint64(primType)) { - res = (op == OP_add) ? - (static_cast(lhsConstant) + static_cast(rhsConstant)) : - (static_cast(lhsConstant) - static_cast(rhsConstant)); + res = (op == OP_add) ? (static_cast(lhsConstant) + static_cast(rhsConstant)) + : (static_cast(lhsConstant) - static_cast(rhsConstant)); } else { res = (op == OP_add) ? (lhsConstant + rhsConstant) : (lhsConstant - rhsConstant); } @@ -1806,8 +1817,8 @@ bool ValueRangePropagation::IsConstant(const BB &bb, MeExpr &expr, int64 &value, } // Create new valueRange when old valueRange add or sub with a valuerange. -std::unique_ptr ValueRangePropagation::AddOrSubWithValueRange( - Opcode op, ValueRange &valueRangeLeft, ValueRange &valueRangeRight) { +std::unique_ptr ValueRangePropagation::AddOrSubWithValueRange(Opcode op, ValueRange &valueRangeLeft, + ValueRange &valueRangeRight) { if (valueRangeLeft.GetRangeType() == kNotEqual || valueRangeRight.GetRangeType() == kNotEqual || valueRangeLeft.GetRangeType() == kOnlyHasLowerBound || valueRangeRight.GetRangeType() == kOnlyHasLowerBound || valueRangeLeft.GetRangeType() == kOnlyHasUpperBound || valueRangeRight.GetRangeType() == kOnlyHasUpperBound) { @@ -1837,19 +1848,19 @@ std::unique_ptr ValueRangePropagation::AddOrSubWithValueRange( int64 rhsLowerConst = valueRangeRight.GetLower().GetConstant(); int64 rhsUpperConst = valueRangeRight.GetUpper().GetConstant(); int64 res = 0; - if (!AddOrSubWithConstant(valueRangeLeft.GetLower().GetPrimType(), op, - valueRangeLeft.GetLower().GetConstant(), rhsLowerConst, res)) { + if (!AddOrSubWithConstant(valueRangeLeft.GetLower().GetPrimType(), op, valueRangeLeft.GetLower().GetConstant(), + rhsLowerConst, res)) { return nullptr; } Bound lower = Bound(valueRangeLeft.GetLower().GetVar(), res, valueRangeLeft.GetLower().GetPrimType()); res = 0; - if (!AddOrSubWithConstant(valueRangeLeft.GetLower().GetPrimType(), op, - valueRangeLeft.GetUpper().GetConstant(), rhsUpperConst, res)) { + if (!AddOrSubWithConstant(valueRangeLeft.GetLower().GetPrimType(), op, valueRangeLeft.GetUpper().GetConstant(), + rhsUpperConst, res)) { return nullptr; } Bound upper = Bound(valueRangeLeft.GetUpper().GetVar(), res, valueRangeLeft.GetUpper().GetPrimType()); return std::make_unique(lower, upper, kLowerAndUpper, - valueRangeLeft.IsAccurate() || valueRangeRight.IsAccurate()); + valueRangeLeft.IsAccurate() || valueRangeRight.IsAccurate()); } bool ValueRangePropagation::AddOrSubWithBound(Bound oldBound, Bound &resBound, int64 rhsConstant, Opcode op) { @@ -1862,8 +1873,8 @@ bool ValueRangePropagation::AddOrSubWithBound(Bound oldBound, Bound &resBound, i } // Create new valueRange when old valueRange add or sub with a constant. -std::unique_ptr ValueRangePropagation::AddOrSubWithValueRange( - Opcode op, ValueRange &valueRange, int64 rhsConstant) { +std::unique_ptr ValueRangePropagation::AddOrSubWithValueRange(Opcode op, ValueRange &valueRange, + int64 rhsConstant) { if (valueRange.GetRangeType() == kLowerAndUpper) { Bound lower; if (!AddOrSubWithBound(valueRange.GetLower(), lower, rhsConstant, op)) { @@ -1891,13 +1902,13 @@ std::unique_ptr ValueRangePropagation::AddOrSubWithValueRange( } // deal with the case like var % x, range is [1-x, x-1] -std::unique_ptr ValueRangePropagation::RemWithRhsValueRange( - const OpMeExpr &opMeExpr, int64 rhsConstant) const { +std::unique_ptr ValueRangePropagation::RemWithRhsValueRange(const OpMeExpr &opMeExpr, + int64 rhsConstant) const { int64 res = 0; int64 upperRes = 0; int64 lowerRes = 0; auto pType = opMeExpr.GetOpnd(1)->GetPrimType(); - if (pType == PTY_i64 && rhsConstant == GetMinNumber(PTY_i64)) { // var % x, if var is negative unlimited + if (pType == PTY_i64 && rhsConstant == GetMinNumber(PTY_i64)) { // var % x, if var is negative unlimited return nullptr; } if (Bound(rhsConstant, pType).IsGreaterThan(Bound(nullptr, 0, pType), pType)) { @@ -1930,7 +1941,7 @@ std::unique_ptr ValueRangePropagation::RemWithRhsValueRange( // Create new valueRange when old valueRange rem with a constant. std::unique_ptr ValueRangePropagation::RemWithValueRange(const BB &bb, const OpMeExpr &opMeExpr, - int64 rhsConstant) { + int64 rhsConstant) { auto remValueRange = RemWithRhsValueRange(opMeExpr, rhsConstant); if (remValueRange == nullptr) { return nullptr; @@ -1966,8 +1977,8 @@ std::unique_ptr ValueRangePropagation::RemWithValueRange(const BB &b } // Create valueRange when deal with OP_rem. -std::unique_ptr ValueRangePropagation::DealWithRem( - const BB &bb, const MeExpr &lhsVar, const OpMeExpr &opMeExpr) { +std::unique_ptr ValueRangePropagation::DealWithRem(const BB &bb, const MeExpr &lhsVar, + const OpMeExpr &opMeExpr) { if (!IsNeededPrimType(opMeExpr.GetPrimType())) { return nullptr; } @@ -2051,8 +2062,8 @@ void ValueRangePropagation::DealWithArrayLength(const BB &bb, MeExpr &lhs, MeExp } bool IsPrimTypeUint64(PrimType pType) { - if (pType == PTY_u64 || pType == PTY_a64 || ((pType == PTY_ref || pType == PTY_ptr) && - GetPrimTypeSize(pType) == kEightByte)) { + if (pType == PTY_u64 || pType == PTY_a64 || + ((pType == PTY_ref || pType == PTY_ptr) && GetPrimTypeSize(pType) == kEightByte)) { return true; } return false; @@ -2078,9 +2089,9 @@ int64 GetRealValue(int64 value, PrimType primType) { return static_cast(value); case PTY_ref: case PTY_ptr: - if (GetPrimTypeSize(primType) == kFourByte) { // 32 bit + if (GetPrimTypeSize(primType) == kFourByte) { // 32 bit return static_cast(value); - } else { // 64 bit + } else { // 64 bit CHECK_FATAL(GetPrimTypeSize(primType) == kEightByte, "must be 64 bit"); return static_cast(value); } @@ -2109,7 +2120,7 @@ std::unique_ptr ValueRangePropagation::CopyValueRange(ValueRange &va case kSpecialLowerForLoop: if (primType == PTY_begin) { return std::make_unique(valueRange.GetLower(), valueRange.GetUpper(), valueRange.GetRangeType(), - valueRange.IsAccurate()); + valueRange.IsAccurate()); } else { Bound lower = Bound(valueRange.GetLower().GetVar(), valueRange.GetLower().GetConstant(), primType); Bound upper = Bound(valueRange.GetUpper().GetVar(), valueRange.GetUpper().GetConstant(), primType); @@ -2175,8 +2186,8 @@ void ValueRangePropagation::DealWithAssign(BB &bb, const MeStmt &stmt) { } else if (rhs->GetMeOp() == kMeOpOp) { resVR = DealWithMeOp(bb, stmt); } else if (rhs->GetMeOp() == kMeOpConst && static_cast(rhs)->GetConstVal()->GetKind() == kConstInt) { - resVR = std::make_unique( - Bound(static_cast(rhs)->GetExtIntValue(), rhs->GetPrimType()), kEqual); + resVR = std::make_unique(Bound(static_cast(rhs)->GetExtIntValue(), rhs->GetPrimType()), + kEqual); } if (resVR != nullptr) { auto pTypeOfLHS = lhs->GetPrimType(); @@ -2184,8 +2195,7 @@ void ValueRangePropagation::DealWithAssign(BB &bb, const MeStmt &stmt) { auto primTypeOfVR = resVR->GetLower().GetPrimType(); // The rhs may be truncated when assigned to lhs, // so it is necessary to judge whether the range before and after is consistent. - if (resVR->IsEqualAfterCVT(pTypeOfLHS, pTypeOfRHS) && - resVR->IsEqualAfterCVT(pTypeOfLHS, primTypeOfVR) && + if (resVR->IsEqualAfterCVT(pTypeOfLHS, pTypeOfRHS) && resVR->IsEqualAfterCVT(pTypeOfLHS, primTypeOfVR) && resVR->IsEqualAfterCVT(pTypeOfRHS, primTypeOfVR)) { Insert2Caches(bb.GetBBId(), lhs->GetExprID(), CopyValueRange(*resVR, pTypeOfLHS)); } else { @@ -2237,8 +2247,7 @@ bool ValueRangePropagation::CanComputeLoopIndVar(const MeExpr &phiLHS, MeExpr &e // Create new value range when the loop induction var is monotonic increase. std::unique_ptr ValueRangePropagation::CreateValueRangeForMonotonicIncreaseVar( - const LoopDesc &loop, BB &exitBB, const BB &bb, OpMeExpr &opMeExpr, MeExpr &opnd1, - Bound &initBound, int64 stride) { + const LoopDesc &loop, BB &exitBB, const BB &bb, OpMeExpr &opMeExpr, MeExpr &opnd1, Bound &initBound, int64 stride) { BB *inLoopBB = nullptr; BB *outLoopBB = nullptr; if (loop.Has(*exitBB.GetSucc(0))) { @@ -2251,8 +2260,8 @@ std::unique_ptr ValueRangePropagation::CreateValueRangeForMonotonicI CHECK_FATAL(!loop.Has(*exitBB.GetSucc(0)), "must not in loop"); } int64 rightConstant = 0; - if (opMeExpr.GetOp() == OP_lt || opMeExpr.GetOp() == OP_ge || - opMeExpr.GetOp() == OP_ne || opMeExpr.GetOp() == OP_eq) { + if (opMeExpr.GetOp() == OP_lt || opMeExpr.GetOp() == OP_ge || opMeExpr.GetOp() == OP_ne || + opMeExpr.GetOp() == OP_eq) { rightConstant = -stride; } Bound upperBound; @@ -2279,8 +2288,8 @@ std::unique_ptr ValueRangePropagation::CreateValueRangeForMonotonicI auto valueRangeOfUpper = DealWithAddOrSub(bb, static_cast(opnd1)); if (valueRangeOfUpper != nullptr) { int64 res = 0; - if (AddOrSubWithConstant(opnd1.GetPrimType(), OP_add, valueRangeOfUpper->GetUpper().GetConstant(), - rightConstant, res)) { + if (AddOrSubWithConstant(opnd1.GetPrimType(), OP_add, valueRangeOfUpper->GetUpper().GetConstant(), rightConstant, + res)) { upperBound = Bound(valueRangeOfUpper->GetUpper().GetVar(), res, opnd1.GetPrimType()); } if (initBound.GetVar() == nullptr) { @@ -2298,16 +2307,15 @@ std::unique_ptr ValueRangePropagation::CreateValueRangeForMonotonicI } } if (initBound.GetVar() == nullptr) { - return std::make_unique( - initBound, Bound(&opnd1, rightConstant, initBound.GetPrimType()), kSpecialUpperForLoop); + return std::make_unique(initBound, Bound(&opnd1, rightConstant, initBound.GetPrimType()), + kSpecialUpperForLoop); } return nullptr; } // Create new value range when the loop induction var is monotonic decrease. std::unique_ptr ValueRangePropagation::CreateValueRangeForMonotonicDecreaseVar( - const LoopDesc &loop, BB &exitBB, const BB &bb, OpMeExpr &opMeExpr, MeExpr &opnd1, - Bound &initBound, int64 stride) { + const LoopDesc &loop, BB &exitBB, const BB &bb, OpMeExpr &opMeExpr, MeExpr &opnd1, Bound &initBound, int64 stride) { BB *inLoopBB = nullptr; BB *outLoopBB = nullptr; if (loop.Has(*exitBB.GetSucc(0))) { @@ -2320,8 +2328,8 @@ std::unique_ptr ValueRangePropagation::CreateValueRangeForMonotonicD CHECK_FATAL(!loop.Has(*exitBB.GetSucc(0)), "must not in loop"); } int64 rightConstant = 0; - if (opMeExpr.GetOp() == OP_le || opMeExpr.GetOp() == OP_gt || - opMeExpr.GetOp() == OP_ne || opMeExpr.GetOp() == OP_eq) { + if (opMeExpr.GetOp() == OP_le || opMeExpr.GetOp() == OP_gt || opMeExpr.GetOp() == OP_ne || + opMeExpr.GetOp() == OP_eq) { rightConstant = -stride; } Bound lowerBound; @@ -2339,12 +2347,12 @@ std::unique_ptr ValueRangePropagation::CreateValueRangeForMonotonicD } return nullptr; } - return initBound.GetVar() == nullptr ? std::make_unique(lowerBound, initBound, kLowerAndUpper) : - std::make_unique(lowerBound, initBound, kSpecialUpperForLoop); + return initBound.GetVar() == nullptr ? std::make_unique(lowerBound, initBound, kLowerAndUpper) + : std::make_unique(lowerBound, initBound, kSpecialUpperForLoop); } else { if (initBound.GetVar() == nullptr) { - return std::make_unique( - Bound(&opnd1, rightConstant, opnd1.GetPrimType()), initBound, kSpecialLowerForLoop); + return std::make_unique(Bound(&opnd1, rightConstant, opnd1.GetPrimType()), initBound, + kSpecialLowerForLoop); } } return nullptr; @@ -2377,7 +2385,7 @@ void ValueRangePropagation::TravelBBs(std::vector &reversePostOrderOfLoopBB if (unreachableBBs.find(bb) != unreachableBBs.end()) { continue; } - if (i != 0) { // The phi has already been dealed with. + if (i != 0) { // The phi has already been dealed with. DealWithPhi(*bb); } for (auto it = bb->GetMeStmts().begin(); it != bb->GetMeStmts().end(); ++it) { @@ -2466,7 +2474,7 @@ std::unique_ptr ValueRangePropagation::MergeValueRangeOfPhiOperands( } bool ValueRangePropagation::MergeVrOrInitAndBackedge(MePhiNode &mePhiNode, ValueRange &vrOfInitExpr, - ValueRange &valueRange, Bound &resBound) { + ValueRange &valueRange, Bound &resBound) { bool isOnlyHasLowerBound = vrOfInitExpr.GetRangeType() == kOnlyHasLowerBound; auto pType = mePhiNode.GetLHS()->GetPrimType(); auto upperBound = isOnlyHasLowerBound ? valueRange.GetBound() : vrOfInitExpr.GetBound(); @@ -2485,8 +2493,8 @@ bool ValueRangePropagation::MergeVrOrInitAndBackedge(MePhiNode &mePhiNode, Value } } int64 res = 0; - if (AddOrSubWithConstant(pType, isOnlyHasLowerBound ? OP_sub : OP_add, - valueRange.GetBound().GetConstant(), 1, res)) { + if (AddOrSubWithConstant(pType, isOnlyHasLowerBound ? OP_sub : OP_add, valueRange.GetBound().GetConstant(), 1, + res)) { resBound = Bound(valueRange.GetBound().GetVar(), res, pType); } else { return false; @@ -2499,8 +2507,9 @@ bool ValueRangePropagation::MergeVrOrInitAndBackedge(MePhiNode &mePhiNode, Value } // Calculate the valuerange of def-operand according to the valuerange of each rhs operand. -void ValueRangePropagation::MergeValueRangeOfPhiOperands(const LoopDesc &loop, const BB &bb, - std::vector> &valueRangeOfInitExprs, size_t indexOfInitExpr) { +void ValueRangePropagation::MergeValueRangeOfPhiOperands( + const LoopDesc &loop, const BB &bb, std::vector> &valueRangeOfInitExprs, + size_t indexOfInitExpr) { size_t index = 0; for (auto &it : bb.GetMePhiList()) { if (!it.second->GetIsLive()) { @@ -2518,8 +2527,8 @@ void ValueRangePropagation::MergeValueRangeOfPhiOperands(const LoopDesc &loop, c index++; continue; } - Bound resBound = vrOfInitExpr->GetRangeType() == kOnlyHasLowerBound ? - Bound(nullptr, GetMaxNumber(pType), pType) : Bound( nullptr, GetMinNumber(pType), pType); + Bound resBound = vrOfInitExpr->GetRangeType() == kOnlyHasLowerBound ? Bound(nullptr, GetMaxNumber(pType), pType) + : Bound(nullptr, GetMinNumber(pType), pType); bool vrCanBeComputed = true; index++; bool isAccurateBound = false; @@ -2529,16 +2538,14 @@ void ValueRangePropagation::MergeValueRangeOfPhiOperands(const LoopDesc &loop, c } auto *operand = mePhiNode->GetOpnd(i); auto *valueRange = FindValueRange(*bb.GetPred(i), *operand); - if (valueRange == nullptr || - valueRange->GetRangeType() == kOnlyHasUpperBound || - valueRange->GetRangeType() == kOnlyHasLowerBound || - vrOfInitExpr->IsEqual(valueRange) || + if (valueRange == nullptr || valueRange->GetRangeType() == kOnlyHasUpperBound || + valueRange->GetRangeType() == kOnlyHasLowerBound || vrOfInitExpr->IsEqual(valueRange) || !MergeVrOrInitAndBackedge(*mePhiNode, *vrOfInitExpr, *valueRange, resBound)) { vrCanBeComputed = false; break; } - isAccurateBound = valueRange->IsAccurate() || valueRange->GetRangeType() == kEqual || - valueRange->GetRangeType() == kNotEqual; + isAccurateBound = + valueRange->IsAccurate() || valueRange->GetRangeType() == kEqual || valueRange->GetRangeType() == kNotEqual; } if (!vrCanBeComputed) { continue; @@ -2547,9 +2554,9 @@ void ValueRangePropagation::MergeValueRangeOfPhiOperands(const LoopDesc &loop, c onlyRecordValueRangeInTempCache.push(false); bool isOnlyHasLowerBound = vrOfInitExpr->GetRangeType() == kOnlyHasLowerBound; - auto valueRangeOfPhi = isOnlyHasLowerBound ? - std::make_unique(vrOfInitExpr->GetBound(), resBound, kLowerAndUpper) : - std::make_unique(resBound, vrOfInitExpr->GetBound(), kLowerAndUpper); + auto valueRangeOfPhi = isOnlyHasLowerBound + ? std::make_unique(vrOfInitExpr->GetBound(), resBound, kLowerAndUpper) + : std::make_unique(resBound, vrOfInitExpr->GetBound(), kLowerAndUpper); if (!valueRangeOfPhi->IsConstantRange() || stride == 1) { if (loop.IsCanonicalAndOnlyHasOneExitBBLoop() && isAccurateBound) { valueRangeOfPhi->SetAccurate(true); @@ -2617,7 +2624,7 @@ bool ValueRangePropagation::Insert2Caches(BBId bbID, int32 exprID, std::unique_p // The rangeType of vrOfRHS is kEqual and the rangeType of vrOfLHS is kEqual, kNotEqual or kLowerAndUpper void ValueRangePropagation::JudgeEqual(MeExpr &expr, ValueRange &vrOfLHS, ValueRange &vrOfRHS, - std::unique_ptr &valueRangePtr) { + std::unique_ptr &valueRangePtr) { if (vrOfRHS.GetRangeType() != kEqual) { return; } @@ -2655,7 +2662,7 @@ void ValueRangePropagation::JudgeEqual(MeExpr &expr, ValueRange &vrOfLHS, ValueR } else if (vrOfLHS.GetRangeType() == kLowerAndUpper) { if (!vrOfLHS.GetLower().IsGreaterThan(vrOfLHS.GetUpper(), primType) && (vrOfLHS.GetLower().IsGreaterThan(vrOfRHS.GetBound(), primType) || - vrOfRHS.GetBound().IsGreaterThan(vrOfLHS.GetUpper(), primType))) { + vrOfRHS.GetBound().IsGreaterThan(vrOfLHS.GetUpper(), primType))) { // dealwith this case: // a = (b == c) // valueRange(b): kLowerAndUpper (1, Max) @@ -2804,8 +2811,9 @@ ValueRange *ValueRangePropagation::FindValueRange(const BB &bb, MeExpr &expr) { return nullptr; } -std::unique_ptr ValueRangePropagation::CreateInitVRForPhi(LoopDesc &loop, - const BB &bb, ScalarMeExpr &init, ScalarMeExpr &backedge, const ScalarMeExpr &lhsOfPhi) { +std::unique_ptr ValueRangePropagation::CreateInitVRForPhi(LoopDesc &loop, const BB &bb, ScalarMeExpr &init, + ScalarMeExpr &backedge, + const ScalarMeExpr &lhsOfPhi) { Bound initBound; ValueRange *valueRangeOfInit = FindValueRange(bb, init); if (valueRangeOfInit != nullptr && valueRangeOfInit->IsConstant() && valueRangeOfInit->GetRangeType() != kNotEqual) { @@ -2913,9 +2921,9 @@ void ValueRangePropagation::DealWithPhi(const BB &bb) { } if (backExprOfPhi.empty()) { valueRangeOfInitExprs.emplace_back(nullptr); - } else if (initExprsOfPhi.size() == 1 && backExprOfPhi.size() == 1) { // Create vr for initial value of phi node. - auto vrOfInitExpr = CreateInitVRForPhi( - *loop, bb, **initExprsOfPhi.begin(), **backExprOfPhi.begin(), *pair.second->GetLHS()); + } else if (initExprsOfPhi.size() == 1 && backExprOfPhi.size() == 1) { // Create vr for initial value of phi node. + auto vrOfInitExpr = + CreateInitVRForPhi(*loop, bb, **initExprsOfPhi.begin(), **backExprOfPhi.begin(), *pair.second->GetLHS()); valueRangeOfInitExprs.emplace_back(std::move(vrOfInitExpr)); } else { valueRangeOfInitExprs.emplace_back(nullptr); @@ -2971,8 +2979,7 @@ Bound ValueRangePropagation::Min(Bound leftBound, Bound rightBound) { // Judge whether the lower is in range. bool ValueRangePropagation::LowerInRange(const BB &bb, Bound lowerTemp, Bound lower, bool lowerIsZero) { - if ((lowerIsZero && lowerTemp.GetVar() == nullptr) || - (!lowerIsZero && lowerTemp.GetVar() == lower.GetVar())) { + if ((lowerIsZero && lowerTemp.GetVar() == nullptr) || (!lowerIsZero && lowerTemp.GetVar() == lower.GetVar())) { int64 lowerConstant = lowerIsZero ? 0 : lower.GetConstant(); return (lowerTemp.GetConstant() >= lowerConstant); } else { @@ -2985,8 +2992,7 @@ bool ValueRangePropagation::LowerInRange(const BB &bb, Bound lowerTemp, Bound lo return LowerInRange(bb, lowerRangeValue->GetLower(), lower, lowerIsZero); } else { Bound newLower; - if (CreateNewBoundWhenAddOrSub(OP_add, lowerRangeValue->GetBound(), - lowerTemp.GetConstant(), newLower)) { + if (CreateNewBoundWhenAddOrSub(OP_add, lowerRangeValue->GetBound(), lowerTemp.GetConstant(), newLower)) { return LowerInRange(bb, newLower, lower, lowerIsZero); } } @@ -2999,8 +3005,8 @@ bool ValueRangePropagation::LowerInRange(const BB &bb, Bound lowerTemp, Bound lo // Judge whether the upper is in range. bool ValueRangePropagation::UpperInRange(const BB &bb, Bound upperTemp, Bound upper, bool upperIsArrayLength) { if (upperTemp.GetVar() == upper.GetVar()) { - return upperIsArrayLength ? (upperTemp.GetConstant() < upper.GetConstant()) : - (upperTemp.GetConstant() <= upper.GetConstant()); + return upperIsArrayLength ? (upperTemp.GetConstant() < upper.GetConstant()) + : (upperTemp.GetConstant() <= upper.GetConstant()); } if (upperTemp.GetVar() == nullptr) { return false; @@ -3013,22 +3019,19 @@ bool ValueRangePropagation::UpperInRange(const BB &bb, Bound upperTemp, Bound up currVar = length2Def[currVar]; if (currVar == upper.GetVar()) { Bound newUpper; - if (CreateNewBoundWhenAddOrSub( - OP_add, upper, upperTemp.GetConstant(), newUpper)) { + if (CreateNewBoundWhenAddOrSub(OP_add, upper, upperTemp.GetConstant(), newUpper)) { return UpperInRange(bb, newUpper, upper, upperIsArrayLength); } else { return false; } } } - } else if (upperRangeValue->IfLowerEqualToUpper() && - upperRangeValue->GetUpper().GetVar() != upperVar) { + } else if (upperRangeValue->IfLowerEqualToUpper() && upperRangeValue->GetUpper().GetVar() != upperVar) { if (upperTemp.GetConstant() == 0) { return UpperInRange(bb, upperRangeValue->GetUpper(), upper, upperIsArrayLength); } else { Bound newUpper; - if (CreateNewBoundWhenAddOrSub(OP_add, upperRangeValue->GetBound(), - upperTemp.GetConstant(), newUpper)) { + if (CreateNewBoundWhenAddOrSub(OP_add, upperRangeValue->GetBound(), upperTemp.GetConstant(), newUpper)) { return UpperInRange(bb, newUpper, upper, upperIsArrayLength); } else { return false; @@ -3036,16 +3039,16 @@ bool ValueRangePropagation::UpperInRange(const BB &bb, Bound upperTemp, Bound up } } else if (!upperRangeValue->IfLowerEqualToUpper()) { if (length2Def.find(upperVar) != length2Def.end() && length2Def[upperVar] == upper.GetVar()) { - return upperIsArrayLength ? (upperTemp.GetConstant() < upper.GetConstant()) : - (upperTemp.GetConstant() <= upper.GetConstant()); + return upperIsArrayLength ? (upperTemp.GetConstant() < upper.GetConstant()) + : (upperTemp.GetConstant() <= upper.GetConstant()); } } return false; } // Judge whether the lower and upper are in range. -InRangeType ValueRangePropagation::InRange(const BB &bb, const ValueRange &rangeTemp, - const ValueRange &range, bool lowerIsZero) { +InRangeType ValueRangePropagation::InRange(const BB &bb, const ValueRange &rangeTemp, const ValueRange &range, + bool lowerIsZero) { bool lowerInRange = LowerInRange(bb, rangeTemp.GetLower(), range.GetLower(), lowerIsZero); Bound upperBound; if (lowerIsZero && !range.IfLowerEqualToUpper()) { @@ -3065,24 +3068,28 @@ InRangeType ValueRangePropagation::InRange(const BB &bb, const ValueRange &range } } -std::unique_ptr ValueRangePropagation::CombineTwoValueRange( - const ValueRange &leftRange, const ValueRange &rightRange, bool merge) { +std::unique_ptr ValueRangePropagation::CombineTwoValueRange(const ValueRange &leftRange, + const ValueRange &rightRange, bool merge) { if (merge) { return std::make_unique(Min(leftRange.GetLower(), rightRange.GetLower()), Max(leftRange.GetUpper(), rightRange.GetUpper()), kLowerAndUpper); } else { if (rightRange.GetRangeType() == kOnlyHasLowerBound) { - return std::make_unique(rightRange.GetLower(), Max(leftRange.GetUpper(), - Bound(GetMaxNumber(rightRange.GetUpper().GetPrimType()), rightRange.GetUpper().GetPrimType())), - kLowerAndUpper, rightRange.IsAccurate()); + return std::make_unique( + rightRange.GetLower(), + Max(leftRange.GetUpper(), + Bound(GetMaxNumber(rightRange.GetUpper().GetPrimType()), rightRange.GetUpper().GetPrimType())), + kLowerAndUpper, rightRange.IsAccurate()); } if (rightRange.GetRangeType() == kOnlyHasUpperBound) { - return std::make_unique(Min(leftRange.GetLower(), - Bound(GetMinNumber(rightRange.GetLower().GetPrimType()), rightRange.GetLower().GetPrimType())), - leftRange.GetUpper(), kLowerAndUpper, rightRange.IsAccurate()); + return std::make_unique( + Min(leftRange.GetLower(), + Bound(GetMinNumber(rightRange.GetLower().GetPrimType()), rightRange.GetLower().GetPrimType())), + leftRange.GetUpper(), kLowerAndUpper, rightRange.IsAccurate()); } return std::make_unique(Max(leftRange.GetLower(), rightRange.GetLower()), - Min(leftRange.GetUpper(), rightRange.GetUpper()), kLowerAndUpper, rightRange.IsAccurate()); + Min(leftRange.GetUpper(), rightRange.GetUpper()), kLowerAndUpper, + rightRange.IsAccurate()); } } @@ -3109,8 +3116,8 @@ void ValueRangePropagation::ChangeLoop2Goto(LoopDesc &loop, BB &bb, BB &succBB, void ValueRangePropagation::Insert2UnreachableBBs(BB &unreachableBB) { if (ValueRangePropagation::isDebug) { - LogInfo::MapleLogger() << "=====================delete bb " << unreachableBB.GetBBId() << - "========================\n"; + LogInfo::MapleLogger() << "=====================delete bb " << unreachableBB.GetBBId() + << "========================\n"; } unreachableBBs.insert(&unreachableBB); return; @@ -3125,9 +3132,20 @@ void ValueRangePropagation::AnalysisUnreachableBBOrEdge(BB &bb, BB &unreachableB UpdateProfile(*pred, bb, unreachableBB); } Insert2UnreachableBBs(unreachableBB); + // update frequency before cfg changed + int64_t removedFreq = 0; + if (func.GetCfg()->UpdateCFGFreq()) { + int idx = bb.GetSuccIndex(unreachableBB); + removedFreq = bb.GetSuccFreq()[idx]; + } bb.RemoveSucc(unreachableBB); bb.RemoveMeStmt(bb.GetLastMe()); bb.SetKind(kBBFallthru); + if (func.GetCfg()->UpdateCFGFreq()) { + bb.SetSuccFreq(0, bb.GetFrequency()); + succBB.SetFrequency(succBB.GetFrequency() + removedFreq); + unreachableBB.SetFrequency(0); + } auto *loop = loops->GetBBLoopParent(bb.GetBBId()); if (loop == nullptr) { return; @@ -3136,25 +3154,20 @@ void ValueRangePropagation::AnalysisUnreachableBBOrEdge(BB &bb, BB &unreachableB } // Judge whether the value range is in range. -bool ValueRangePropagation::BrStmtInRange(const BB &bb, const ValueRange &leftRange, - const ValueRange &rightRange, Opcode op, PrimType opndType, - bool judgeNotInRange) { +bool ValueRangePropagation::BrStmtInRange(const BB &bb, const ValueRange &leftRange, const ValueRange &rightRange, + Opcode op, PrimType opndType, bool judgeNotInRange) { Bound leftLower = leftRange.GetLower(); Bound leftUpper = leftRange.GetUpper(); Bound rightLower = rightRange.GetLower(); Bound rightUpper = rightRange.GetUpper(); RangeType leftRangeType = leftRange.GetRangeType(); RangeType rightRangeType = rightRange.GetRangeType(); - if (!IsNeededPrimType(opndType) || - leftLower.GetVar() != leftUpper.GetVar() || leftUpper.GetVar() != rightUpper.GetVar() || - rightUpper.GetVar() != rightLower.GetVar() || leftRangeType == kSpecialLowerForLoop || - leftRangeType == kSpecialUpperForLoop || - leftRange.GetRangeType() == kOnlyHasLowerBound || - leftRange.GetRangeType() == kOnlyHasUpperBound || - rightRangeType == kSpecialLowerForLoop || - rightRangeType == kSpecialUpperForLoop || - rightRange.GetRangeType() == kOnlyHasLowerBound || - rightRange.GetRangeType() == kOnlyHasUpperBound) { + if (!IsNeededPrimType(opndType) || leftLower.GetVar() != leftUpper.GetVar() || + leftUpper.GetVar() != rightUpper.GetVar() || rightUpper.GetVar() != rightLower.GetVar() || + leftRangeType == kSpecialLowerForLoop || leftRangeType == kSpecialUpperForLoop || + leftRange.GetRangeType() == kOnlyHasLowerBound || leftRange.GetRangeType() == kOnlyHasUpperBound || + rightRangeType == kSpecialLowerForLoop || rightRangeType == kSpecialUpperForLoop || + rightRange.GetRangeType() == kOnlyHasLowerBound || rightRange.GetRangeType() == kOnlyHasUpperBound) { return false; } if (judgeNotInRange) { @@ -3170,16 +3183,13 @@ bool ValueRangePropagation::BrStmtInRange(const BB &bb, const ValueRange &leftRa } } // deal the difference between i32 and u32. - if (leftLower.IsGreaterThan(leftUpper, opndType) || - rightLower.IsGreaterThan(rightUpper, opndType)) { + if (leftLower.IsGreaterThan(leftUpper, opndType) || rightLower.IsGreaterThan(rightUpper, opndType)) { return false; } if ((op == OP_eq && !judgeNotInRange) || (op == OP_ne && judgeNotInRange)) { // If the range of leftOpnd equal to the range of rightOpnd, remove the falseBranch. - return leftRangeType != kNotEqual && rightRangeType != kNotEqual && - leftLower.IsEqual(leftUpper, opndType) && - rightLower.IsEqual(rightUpper, opndType) && - leftLower.IsEqual(rightLower, opndType); + return leftRangeType != kNotEqual && rightRangeType != kNotEqual && leftLower.IsEqual(leftUpper, opndType) && + rightLower.IsEqual(rightUpper, opndType) && leftLower.IsEqual(rightLower, opndType); } else if ((op == OP_ne && !judgeNotInRange) || (op == OP_eq && judgeNotInRange)) { // If the range type of leftOpnd is kLowerAndUpper and the rightRange is not in range of it, // remove the trueBranch, such as : @@ -3187,9 +3197,9 @@ bool ValueRangePropagation::BrStmtInRange(const BB &bb, const ValueRange &leftRa // valueRange a: [1, max] // valueRange b: 0 return (leftRangeType != kNotEqual && rightRangeType != kNotEqual && - (leftLower.IsGreaterThan(rightUpper, opndType) || rightLower.IsGreaterThan(leftUpper, opndType))) || - (leftRangeType == kNotEqual && rightRangeType == kEqual && leftLower.IsEqual(rightLower, opndType)) || - (leftRangeType == kEqual && rightRangeType == kNotEqual && leftLower.IsEqual(rightLower, opndType)); + (leftLower.IsGreaterThan(rightUpper, opndType) || rightLower.IsGreaterThan(leftUpper, opndType))) || + (leftRangeType == kNotEqual && rightRangeType == kEqual && leftLower.IsEqual(rightLower, opndType)) || + (leftRangeType == kEqual && rightRangeType == kNotEqual && leftLower.IsEqual(rightLower, opndType)); } else if ((op == OP_lt && !judgeNotInRange) || (op == OP_ge && judgeNotInRange)) { return leftRangeType != kNotEqual && rightRangeType != kNotEqual && rightLower.IsGreaterThan(leftUpper, opndType); } else if ((op == OP_ge && !judgeNotInRange) || (op == OP_lt && judgeNotInRange)) { @@ -3212,42 +3222,40 @@ void ValueRangePropagation::GetTrueAndFalseBranch(Opcode op, BB &bb, BB *&trueBr } } -void ValueRangePropagation::CreateValueRangeForLeOrLt( - const MeExpr &opnd, const ValueRange *leftRange, Bound newRightUpper, Bound newRightLower, - const BB &trueBranch, const BB &falseBranch, bool isAccurate) { +void ValueRangePropagation::CreateValueRangeForLeOrLt(const MeExpr &opnd, const ValueRange *leftRange, + Bound newRightUpper, Bound newRightLower, const BB &trueBranch, + const BB &falseBranch, bool isAccurate) { CHECK_FATAL(IsEqualPrimType(newRightUpper.GetPrimType(), newRightLower.GetPrimType()), "must be equal"); if (leftRange == nullptr) { std::unique_ptr newTrueBranchRange = std::make_unique( ValueRange::MinBound(newRightUpper.GetPrimType()), newRightUpper, kLowerAndUpper, isAccurate); (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), std::move(newTrueBranchRange)); - std::unique_ptr newFalseBranchRange = std::make_unique(newRightLower, - ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); + std::unique_ptr newFalseBranchRange = std::make_unique( + newRightLower, ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), std::move(newFalseBranchRange)); } else if (leftRange->GetRangeType() == kOnlyHasLowerBound) { std::unique_ptr newRightRange = std::make_unique( ValueRange::MinBound(newRightUpper.GetPrimType()), newRightUpper, kLowerAndUpper, isAccurate); - std::unique_ptr newLeftRange = std::make_unique(leftRange->GetLower(), - ValueRange::MaxBound(leftRange->GetLower().GetPrimType()), kLowerAndUpper, isAccurate); - (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), - CombineTwoValueRange(*leftRange, *newRightRange)); - newRightRange = std::make_unique( - newRightLower, ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); + std::unique_ptr newLeftRange = std::make_unique( + leftRange->GetLower(), ValueRange::MaxBound(leftRange->GetLower().GetPrimType()), kLowerAndUpper, isAccurate); + (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), CombineTwoValueRange(*leftRange, *newRightRange)); + newRightRange = std::make_unique(newRightLower, ValueRange::MaxBound(newRightUpper.GetPrimType()), + kLowerAndUpper, isAccurate); } else if (leftRange->GetRangeType() == kOnlyHasUpperBound) { std::unique_ptr newRightRange = std::make_unique( ValueRange::MinBound(newRightUpper.GetPrimType()), newRightUpper, kLowerAndUpper, isAccurate); std::unique_ptr newLeftRange = std::make_unique( ValueRange::MinBound(newRightUpper.GetPrimType()), leftRange->GetBound(), kLowerAndUpper, isAccurate); - newRightRange = std::make_unique( - newRightLower, ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); - (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), - CombineTwoValueRange(*leftRange, *newRightRange)); + newRightRange = std::make_unique(newRightLower, ValueRange::MaxBound(newRightUpper.GetPrimType()), + kLowerAndUpper, isAccurate); + (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), CombineTwoValueRange(*leftRange, *newRightRange)); } else { std::unique_ptr newRightRange = std::make_unique( ValueRange::MinBound(newRightUpper.GetPrimType()), newRightUpper, kLowerAndUpper, isAccurate); auto resTrueBranchVR = CombineTwoValueRange(*leftRange, *newRightRange); (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), CopyValueRange(*resTrueBranchVR)); - newRightRange = std::make_unique( - newRightLower, ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); + newRightRange = std::make_unique(newRightLower, ValueRange::MaxBound(newRightUpper.GetPrimType()), + kLowerAndUpper, isAccurate); auto resFalseBranchVR = CombineTwoValueRange(*leftRange, *newRightRange); (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), CopyValueRange(*resFalseBranchVR)); // Deal with the case like: @@ -3266,55 +3274,52 @@ void ValueRangePropagation::CreateValueRangeForLeOrLt( } } -void ValueRangePropagation::CreateValueRangeForGeOrGt( - const MeExpr &opnd, const ValueRange *leftRange, Bound newRightUpper, Bound newRightLower, - const BB &trueBranch, const BB &falseBranch, bool isAccurate) { +void ValueRangePropagation::CreateValueRangeForGeOrGt(const MeExpr &opnd, const ValueRange *leftRange, + Bound newRightUpper, Bound newRightLower, const BB &trueBranch, + const BB &falseBranch, bool isAccurate) { CHECK_FATAL(IsEqualPrimType(newRightUpper.GetPrimType(), newRightLower.GetPrimType()), "must be equal"); if (leftRange == nullptr) { - std::unique_ptr newTrueBranchRange = std::make_unique(newRightLower, - ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); + std::unique_ptr newTrueBranchRange = std::make_unique( + newRightLower, ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), std::move(newTrueBranchRange)); std::unique_ptr newFalseBranchRange = std::make_unique( ValueRange::MinBound(newRightUpper.GetPrimType()), newRightUpper, kLowerAndUpper, isAccurate); (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), std::move(newFalseBranchRange)); } else if (leftRange->GetRangeType() == kOnlyHasLowerBound) { - auto newRightRange = std::make_unique( - ValueRange::MinBound(newRightUpper.GetPrimType()), newRightUpper, kLowerAndUpper, isAccurate); - (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), - CombineTwoValueRange(*leftRange, *newRightRange)); + auto newRightRange = std::make_unique(ValueRange::MinBound(newRightUpper.GetPrimType()), newRightUpper, + kLowerAndUpper, isAccurate); + (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), CombineTwoValueRange(*leftRange, *newRightRange)); } else if (leftRange->GetRangeType() == kOnlyHasUpperBound) { - std::unique_ptr newRightRange = std::make_unique(newRightLower, - ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); - (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), - CombineTwoValueRange(*leftRange, *newRightRange)); + std::unique_ptr newRightRange = std::make_unique( + newRightLower, ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); + (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), CombineTwoValueRange(*leftRange, *newRightRange)); } else { - std::unique_ptr newRightRange = std::make_unique(newRightLower, - ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); + std::unique_ptr newRightRange = std::make_unique( + newRightLower, ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), CombineTwoValueRange(*leftRange, *newRightRange)); newRightRange = std::make_unique(ValueRange::MinBound(newRightUpper.GetPrimType()), newRightUpper, - kLowerAndUpper, isAccurate); - (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), - CombineTwoValueRange(*leftRange, *newRightRange)); + kLowerAndUpper, isAccurate); + (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), CombineTwoValueRange(*leftRange, *newRightRange)); } } // Return true if the lower or upper of leftRange is equal to the bound of rightRange, like this: // leftRang: (5, constant) rightRange: (5) ==> return true; // leftRang: (constant, 5) rightRange: (5) ==> return true; -bool ValueRangePropagation::IfTheLowerOrUpperOfLeftRangeEqualToTheRightRange( - const ValueRange &leftRange, ValueRange &rightRange, bool isLower) const { - bool lowerOrUpperIsEqual = isLower ? leftRange.GetLower().GetConstant() == rightRange.GetBound().GetConstant() : - leftRange.GetUpper().GetConstant() == rightRange.GetBound().GetConstant(); +bool ValueRangePropagation::IfTheLowerOrUpperOfLeftRangeEqualToTheRightRange(const ValueRange &leftRange, + ValueRange &rightRange, + bool isLower) const { + bool lowerOrUpperIsEqual = isLower ? leftRange.GetLower().GetConstant() == rightRange.GetBound().GetConstant() + : leftRange.GetUpper().GetConstant() == rightRange.GetBound().GetConstant(); return leftRange.GetRangeType() == kLowerAndUpper && leftRange.IsConstantLowerAndUpper() && leftRange.GetLower().GetConstant() < leftRange.GetUpper().GetConstant() && lowerOrUpperIsEqual; } -void ValueRangePropagation::CreateValueRangeForNeOrEq( - const MeExpr &opnd, const ValueRange *leftRange, ValueRange &rightRange, const BB &trueBranch, - const BB &falseBranch) { +void ValueRangePropagation::CreateValueRangeForNeOrEq(const MeExpr &opnd, const ValueRange *leftRange, + ValueRange &rightRange, const BB &trueBranch, + const BB &falseBranch) { if (rightRange.GetRangeType() == kEqual) { - std::unique_ptr newTrueBranchRange = - std::make_unique(rightRange.GetBound(), kEqual); + std::unique_ptr newTrueBranchRange = std::make_unique(rightRange.GetBound(), kEqual); auto &opMeExpr = static_cast(opnd); if (opMeExpr.GetOp() == OP_zext && rightRange.IsConstant() && opMeExpr.GetOpnd(0)->GetPrimType() == GetIntegerPrimTypeBySizeAndSign(opMeExpr.GetBitsSize(), false)) { @@ -3322,8 +3327,7 @@ void ValueRangePropagation::CreateValueRangeForNeOrEq( } (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), std::move(newTrueBranchRange)); if (leftRange == nullptr) { - std::unique_ptr newFalseBranchRange = - std::make_unique(rightRange.GetBound(), kNotEqual); + std::unique_ptr newFalseBranchRange = std::make_unique(rightRange.GetBound(), kNotEqual); (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), std::move(newFalseBranchRange)); } else if (IfTheLowerOrUpperOfLeftRangeEqualToTheRightRange(*leftRange, rightRange, true)) { // Deal with this case: @@ -3350,18 +3354,15 @@ void ValueRangePropagation::CreateValueRangeForNeOrEq( (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), std::move(newFalseBranchRange)); } } else if (leftRange->GetRangeType() == kLowerAndUpper) { - std::unique_ptr newFalseBranchRange = - std::make_unique(rightRange.GetBound(), kNotEqual); + std::unique_ptr newFalseBranchRange = std::make_unique(rightRange.GetBound(), kNotEqual); (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), std::move(newFalseBranchRange)); } else if (leftRange->GetRangeType() == kOnlyHasLowerBound || leftRange->GetRangeType() == kOnlyHasUpperBound) { - std::unique_ptr newFalseBranchRange = - std::make_unique(rightRange.GetBound(), kNotEqual); + std::unique_ptr newFalseBranchRange = std::make_unique(rightRange.GetBound(), kNotEqual); (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), std::move(newFalseBranchRange)); } } else if (rightRange.GetRangeType() == kNotEqual) { if (leftRange == nullptr) { - std::unique_ptr newTrueBranchRange = - std::make_unique(rightRange.GetBound(), kNotEqual); + std::unique_ptr newTrueBranchRange = std::make_unique(rightRange.GetBound(), kNotEqual); (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), std::move(newTrueBranchRange)); } else if (IfTheLowerOrUpperOfLeftRangeEqualToTheRightRange(*leftRange, rightRange, true)) { Bound newLower; @@ -3378,8 +3379,7 @@ void ValueRangePropagation::CreateValueRangeForNeOrEq( (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), std::move(newTrueBranchRange)); } } else if (leftRange->GetRangeType() == kOnlyHasLowerBound || leftRange->GetRangeType() == kOnlyHasUpperBound) { - std::unique_ptr newTrueBranchRange = - std::make_unique(rightRange.GetBound(), kNotEqual); + std::unique_ptr newTrueBranchRange = std::make_unique(rightRange.GetBound(), kNotEqual); (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), std::move(newTrueBranchRange)); } } @@ -3389,8 +3389,8 @@ void ValueRangePropagation::CreateValueRangeForNeOrEq( // if a == 5 // If the valueRange of a is valuerange(5, kEqual), delete the false branch. // Else if the valeuRange of a is valueRange(5, kNotEqual), delete the ture branch. -bool ValueRangePropagation::ConditionBBCanBeDeletedAfterOPNeOrEq( - BB &bb, ValueRange &leftRange, ValueRange &rightRange, BB &falseBranch, BB &trueBranch) { +bool ValueRangePropagation::ConditionBBCanBeDeletedAfterOPNeOrEq(BB &bb, ValueRange &leftRange, ValueRange &rightRange, + BB &falseBranch, BB &trueBranch) { if ((leftRange.GetRangeType() == kEqual && rightRange.GetRangeType() == kEqual) && leftRange.GetBound().GetVar() == rightRange.GetBound().GetVar()) { if (leftRange.GetBound().GetConstant() == rightRange.GetBound().GetConstant()) { @@ -3428,7 +3428,7 @@ void ValueRangePropagation::UpdateProfile(BB &pred, BB &bb, const BB &targetBB) } auto *condGotoStmt = static_cast(bb.GetLastMe()); if (condGotoStmt->GetBranchProb() != kProbLikely && condGotoStmt->GetBranchProb() != kProbUnlikely) { - return; // need not update profile + return; // need not update profile } int32 targetBranchProb = 0; if (&targetBB == bb.GetSucc(0)) { @@ -3438,7 +3438,7 @@ void ValueRangePropagation::UpdateProfile(BB &pred, BB &bb, const BB &targetBB) targetBranchProb = condGotoStmt->GetBranchProb(); } BB *predCondGoto = &pred; - BB *succBB = &bb; // succ of predCondGoto to targetBB + BB *succBB = &bb; // succ of predCondGoto to targetBB while (predCondGoto != nullptr) { if (predCondGoto->GetKind() == kBBCondGoto) { break; @@ -3479,9 +3479,9 @@ void ValueRangePropagation::UpdateProfile(BB &pred, BB &bb, const BB &targetBB) // \ / \ ----> | | // \ / \ | | // false true false true -void ValueRangePropagation::RemoveUnreachableBB( - BB &condGotoBB, BB &trueBranch, ScalarMeExpr *updateSSAExceptTheScalarExpr, - std::map> &ssaupdateCandsForCondExpr) { +void ValueRangePropagation::RemoveUnreachableBB(BB &condGotoBB, BB &trueBranch, + ScalarMeExpr *updateSSAExceptTheScalarExpr, + std::map> &ssaupdateCandsForCondExpr) { CHECK_FATAL(condGotoBB.GetSucc().size() == kNumOperands, "must have 2 succ"); auto *succ0 = condGotoBB.GetSucc(0); auto *succ1 = condGotoBB.GetSucc(1); @@ -3493,6 +3493,12 @@ void ValueRangePropagation::RemoveUnreachableBB( UpdateProfile(*condGotoBB.GetPred(0), condGotoBB, trueBranch); } condGotoBB.SetKind(kBBFallthru); + // update frequency before cfg changed + if (func.GetCfg()->UpdateCFGFreq()) { + int64_t removedFreq = condGotoBB.GetSuccFreq()[1]; + condGotoBB.SetSuccFreq(0, condGotoBB.GetFrequency()); + succ0->SetFrequency(succ0->GetFrequency() + removedFreq); + } condGotoBB.RemoveSucc(*succ1); DeleteThePhiNodeWhichOnlyHasOneOpnd(*succ1, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); condGotoBB.RemoveMeStmt(condGotoBB.GetLastMe()); @@ -3505,7 +3511,16 @@ void ValueRangePropagation::RemoveUnreachableBB( UpdateProfile(*condGotoBB.GetPred(0), condGotoBB, trueBranch); } condGotoBB.SetKind(kBBFallthru); + int64_t removedFreq = 0; + // update frequency before cfg changed + if (func.GetCfg()->UpdateCFGFreq()) { + removedFreq = condGotoBB.GetSuccFreq()[0]; + } condGotoBB.RemoveSucc(*succ0); + if (func.GetCfg()->UpdateCFGFreq()) { + condGotoBB.SetSuccFreq(0, condGotoBB.GetFrequency()); + succ1->SetFrequency(succ1->GetFrequency() + removedFreq); + } DeleteThePhiNodeWhichOnlyHasOneOpnd(*succ0, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); condGotoBB.RemoveMeStmt(condGotoBB.GetLastMe()); } @@ -3563,7 +3578,7 @@ void ValueRangePropagation::CreateLabelForTargetBB(BB &pred, BB &newBB) { case kBBIgoto: CHECK_FATAL(false, "can not be here"); case kBBCondGoto: { - auto *condGotoStmt = static_cast(pred.GetLastMe()); + auto *condGotoStmt = static_cast(pred.GetLastMe()); if (&newBB == pred.GetSucc().at(1)) { condGotoStmt->SetOffset(func.GetOrCreateBBLabel(newBB)); } @@ -3661,10 +3676,22 @@ bool ValueRangePropagation::ChangeTheSuccOfPred2TrueBranch( if (exitCopyFallthru != nullptr) { PrepareForSSAUpdateWhenPredBBIsRemoved(pred, bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); size_t index = FindBBInSuccs(pred, bb); + int64_t edgeFreq = 0; + if (func.GetCfg()->UpdateCFGFreq()) { + edgeFreq = pred.GetSuccFreq()[index]; + } pred.RemoveSucc(bb); DeleteThePhiNodeWhichOnlyHasOneOpnd(bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); pred.AddSucc(*exitCopyFallthru, index); CreateLabelForTargetBB(pred, *exitCopyFallthru); + if (func.GetCfg()->UpdateCFGFreq()) { + exitCopyFallthru->SetFrequency(exitCopyFallthru->GetFrequency() + edgeFreq); + pred.AddSuccFreq(edgeFreq, index); + // update bb frequency + ASSERT(bb.GetFrequency() >= edgeFreq, "sanity check"); + bb.SetFrequency(bb.GetFrequency() - edgeFreq); + bb.UpdateEdgeFreqs(); + } return true; } if (CodeSizeIsOverflowOrTheOpOfStmtIsNotSupported(bb)) { @@ -3686,20 +3713,33 @@ bool ValueRangePropagation::ChangeTheSuccOfPred2TrueBranch( predOfCurrBB = currBB; currBB = currBB->GetSucc(0); CopyMeStmts(*currBB, *mergeAllFallthruBBs); - PrepareForSSAUpdateWhenPredBBIsRemoved( - *predOfCurrBB, *currBB, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); + PrepareForSSAUpdateWhenPredBBIsRemoved(*predOfCurrBB, *currBB, updateSSAExceptTheScalarExpr, + ssaupdateCandsForCondExpr); } if (predOfCurrBB != nullptr) { - PrepareForSSAUpdateWhenPredBBIsRemoved( - *predOfCurrBB, *currBB, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); + PrepareForSSAUpdateWhenPredBBIsRemoved(*predOfCurrBB, *currBB, updateSSAExceptTheScalarExpr, + ssaupdateCandsForCondExpr); } CHECK_FATAL(currBB->GetKind() == kBBCondGoto, "must be condgoto bb"); auto *gotoMeStmt = irMap.New(func.GetOrCreateBBLabel(trueBranch)); mergeAllFallthruBBs->AddMeStmtLast(gotoMeStmt); PrepareForSSAUpdateWhenPredBBIsRemoved(pred, bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); size_t index = FindBBInSuccs(pred, bb); + int64_t edgeFreq = 0; + if (func.GetCfg()->UpdateCFGFreq()) { + edgeFreq = pred.GetSuccFreq()[index]; + } pred.RemoveSucc(bb); pred.AddSucc(*mergeAllFallthruBBs, index); + if (func.GetCfg()->UpdateCFGFreq()) { + mergeAllFallthruBBs->SetFrequency(edgeFreq); + mergeAllFallthruBBs->PushBackSuccFreq(edgeFreq); + pred.AddSuccFreq(edgeFreq, index); + // update bb frequency + ASSERT(bb.GetFrequency() >= edgeFreq, "sanity check"); + bb.SetFrequency(bb.GetFrequency() - edgeFreq); + bb.UpdateEdgeFreqs(); + } mergeAllFallthruBBs->AddSucc(trueBranch); DeleteThePhiNodeWhichOnlyHasOneOpnd(bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); CreateLabelForTargetBB(pred, *mergeAllFallthruBBs); @@ -3729,8 +3769,8 @@ bool ValueRangePropagation::CopyFallthruBBAndRemoveUnreachableEdge( do { tmpPred = tmpPred->GetSucc(0); if (GetRealPredSize(*tmpPred) > 1) { - return ChangeTheSuccOfPred2TrueBranch( - pred, bb, trueBranch, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); + return ChangeTheSuccOfPred2TrueBranch(pred, bb, trueBranch, updateSSAExceptTheScalarExpr, + ssaupdateCandsForCondExpr); } } while (tmpPred->GetKind() != kBBCondGoto); if (GetRealPredSize(bb) != 1) { @@ -3756,27 +3796,56 @@ bool ValueRangePropagation::CopyFallthruBBAndRemoveUnreachableEdge( // true false true false true false // case1: the number of branches reaching to condBB > 1 // case2: the number of branches reaching to condBB == 1 -bool ValueRangePropagation::RemoveTheEdgeOfPredBB( - BB &pred, BB &bb, BB &trueBranch, ScalarMeExpr *updateSSAExceptTheScalarExpr, - std::map> &ssaupdateCandsForCondExpr) { +bool ValueRangePropagation::RemoveTheEdgeOfPredBB(BB &pred, BB &bb, BB &trueBranch, + ScalarMeExpr *updateSSAExceptTheScalarExpr, + std::map> &ssaupdateCandsForCondExpr) { CHECK_FATAL(bb.GetKind() == kBBCondGoto, "must be condgoto bb"); if (GetRealPredSize(bb) >= kNumOperands) { if (OnlyHaveCondGotoStmt(bb)) { PrepareForSSAUpdateWhenPredBBIsRemoved(pred, bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); size_t index = FindBBInSuccs(pred, bb); + int64_t edgeFreq = 0; + if (func.GetCfg()->UpdateCFGFreq()) { + edgeFreq = pred.GetSuccFreq()[index]; + ASSERT(bb.GetFrequency() >= edgeFreq, "sanity check"); + } pred.RemoveSucc(bb); DeleteThePhiNodeWhichOnlyHasOneOpnd(bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); pred.AddSucc(trueBranch, index); CreateLabelForTargetBB(pred, trueBranch); + if (func.GetCfg()->UpdateCFGFreq()) { + bb.SetFrequency(bb.GetFrequency() - edgeFreq); + size_t trueBranchIdx = bb.GetSuccIndex(trueBranch); + int64_t updatedtrueFreq = bb.GetSuccFreq()[trueBranchIdx] - edgeFreq; + // transform may not be consistent with frequency value + updatedtrueFreq = updatedtrueFreq > 0 ? updatedtrueFreq : 0; + bb.SetSuccFreq(trueBranchIdx, updatedtrueFreq); + pred.AddSuccFreq(edgeFreq, index); + } } else { auto *exitCopyFallthru = GetNewCopyFallthruBB(trueBranch, bb); if (exitCopyFallthru != nullptr) { PrepareForSSAUpdateWhenPredBBIsRemoved(pred, bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); size_t index = FindBBInSuccs(pred, bb); + int64_t edgeFreq = 0; + if (func.GetCfg()->UpdateCFGFreq()) { + edgeFreq = pred.GetSuccFreq()[index]; + ASSERT(bb.GetFrequency() >= edgeFreq, "sanity check"); + } pred.RemoveSucc(bb); DeleteThePhiNodeWhichOnlyHasOneOpnd(bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); pred.AddSucc(*exitCopyFallthru, index); CreateLabelForTargetBB(pred, *exitCopyFallthru); + if (func.GetCfg()->UpdateCFGFreq()) { + bb.SetFrequency(bb.GetFrequency() - edgeFreq); + exitCopyFallthru->SetFrequency(edgeFreq); + exitCopyFallthru->PushBackSuccFreq(edgeFreq); + size_t trueBranchIdx = bb.GetSuccIndex(trueBranch); + int64_t updatedtrueFreq = bb.GetSuccFreq()[trueBranchIdx] - edgeFreq; + ASSERT(updatedtrueFreq >= 0, "sanity check"); + bb.SetSuccFreq(trueBranchIdx, updatedtrueFreq); + pred.AddSuccFreq(edgeFreq, index); + } return true; } auto *newBB = CreateNewGotoBBWithoutCondGotoStmt(bb); @@ -3790,9 +3859,21 @@ bool ValueRangePropagation::RemoveTheEdgeOfPredBB( newBB->AddMeStmtLast(gotoMeStmt); PrepareForSSAUpdateWhenPredBBIsRemoved(pred, bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); size_t index = FindBBInSuccs(pred, bb); + int64_t edgeFreq = 0; + if (func.GetCfg()->UpdateCFGFreq()) { + edgeFreq = pred.GetSuccFreq()[index]; + ASSERT(bb.GetFrequency() >= edgeFreq, "sanity check"); + } pred.RemoveSucc(bb); pred.AddSucc(*newBB, index); newBB->AddSucc(trueBranch); + if (func.GetCfg()->UpdateCFGFreq()) { + bb.SetFrequency(bb.GetFrequency() - edgeFreq); + bb.UpdateEdgeFreqs(); + newBB->SetFrequency(edgeFreq); + newBB->PushBackSuccFreq(edgeFreq); + pred.AddSuccFreq(edgeFreq, index); + } DeleteThePhiNodeWhichOnlyHasOneOpnd(bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); (void)func.GetOrCreateBBLabel(trueBranch); CreateLabelForTargetBB(pred, *newBB); @@ -3805,15 +3886,15 @@ bool ValueRangePropagation::RemoveTheEdgeOfPredBB( } // tmpPred, tmpBB, reachableBB -bool ValueRangePropagation::RemoveUnreachableEdge( - BB &pred, BB &bb, BB &trueBranch, ScalarMeExpr *updateSSAExceptTheScalarExpr, - std::map> &ssaupdateCandsForCondExpr) { +bool ValueRangePropagation::RemoveUnreachableEdge(BB &pred, BB &bb, BB &trueBranch, + ScalarMeExpr *updateSSAExceptTheScalarExpr, + std::map> &ssaupdateCandsForCondExpr) { if (onlyPropVR) { return false; } if (bb.GetKind() == kBBFallthru || bb.GetKind() == kBBGoto) { - if (!CopyFallthruBBAndRemoveUnreachableEdge( - pred, bb, trueBranch, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr)) { + if (!CopyFallthruBBAndRemoveUnreachableEdge(pred, bb, trueBranch, updateSSAExceptTheScalarExpr, + ssaupdateCandsForCondExpr)) { return false; } } else { @@ -3822,8 +3903,8 @@ bool ValueRangePropagation::RemoveUnreachableEdge( } } if (ValueRangePropagation::isDebug) { - LogInfo::MapleLogger() << "===========delete edge " << pred.GetBBId() << " " << bb.GetBBId() << " " << - trueBranch.GetBBId() << "===========\n"; + LogInfo::MapleLogger() << "===========delete edge " << pred.GetBBId() << " " << bb.GetBBId() << " " + << trueBranch.GetBBId() << "===========\n"; } if (trueBranch.GetPred().size() > 1) { (void)func.GetOrCreateBBLabel(trueBranch); @@ -3833,14 +3914,16 @@ bool ValueRangePropagation::RemoveUnreachableEdge( } bool ValueRangePropagation::ConditionEdgeCanBeDeleted(BB &pred, BB &bb, const ValueRange *leftRange, - const ValueRange *rightRange, BB &falseBranch, BB &trueBranch, PrimType opndType, Opcode op, - ScalarMeExpr *updateSSAExceptTheScalarExpr, std::map> &ssaupdateCandsForCondExpr) { + const ValueRange *rightRange, BB &falseBranch, BB &trueBranch, + PrimType opndType, Opcode op, + ScalarMeExpr *updateSSAExceptTheScalarExpr, + std::map> &ssaupdateCandsForCondExpr) { if (leftRange == nullptr || rightRange == nullptr) { return false; } if (ValueRangePropagation::isDebug) { - LogInfo::MapleLogger() << "try to delete edge " << pred.GetBBId() << " " << bb.GetBBId() << " " << - trueBranch.GetBBId() << "\n"; + LogInfo::MapleLogger() << "try to delete edge " << pred.GetBBId() << " " << bb.GetBBId() << " " + << trueBranch.GetBBId() << "\n"; } /* Find the first bb with more than one pred */ auto *tmpPred = &pred; @@ -3854,12 +3937,11 @@ bool ValueRangePropagation::ConditionEdgeCanBeDeleted(BB &pred, BB &bb, const Va // opnd, tmpPred, tmpBB, reachableBB // remove falseBranch UpdateProfile(*tmpPred, *tmpBB, trueBranch); - return RemoveUnreachableEdge( - *tmpPred, *tmpBB, trueBranch, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); + return RemoveUnreachableEdge(*tmpPred, *tmpBB, trueBranch, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); } else if (BrStmtInRange(bb, *leftRange, *rightRange, antiOp, opndType)) { UpdateProfile(*tmpPred, *tmpBB, falseBranch); - return RemoveUnreachableEdge( - *tmpPred, *tmpBB, falseBranch, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); + return RemoveUnreachableEdge(*tmpPred, *tmpBB, falseBranch, updateSSAExceptTheScalarExpr, + ssaupdateCandsForCondExpr); } return false; } @@ -3884,8 +3966,9 @@ std::unique_ptr ValueRangePropagation::AntiValueRange(ValueRange &va return nullptr; } RangeType newType = (oldType == kEqual) ? kNotEqual : kEqual; - return std::make_unique(Bound(valueRange.GetBound().GetVar(), valueRange.GetBound().GetConstant(), - valueRange.GetBound().GetPrimType()), newType); + return std::make_unique( + Bound(valueRange.GetBound().GetVar(), valueRange.GetBound().GetConstant(), valueRange.GetBound().GetPrimType()), + newType); } void ValueRangePropagation::DeleteUnreachableBBs(BB &curBB, BB &falseBranch, BB &trueBranch) { @@ -3909,8 +3992,9 @@ void ValueRangePropagation::DeleteUnreachableBBs(BB &curBB, BB &falseBranch, BB } } -void ValueRangePropagation::PropValueRangeFromCondGotoToTrueAndFalseBranch( - const MeExpr &opnd0, ValueRange &rightRange, const BB &falseBranch, const BB &trueBranch) { +void ValueRangePropagation::PropValueRangeFromCondGotoToTrueAndFalseBranch(const MeExpr &opnd0, ValueRange &rightRange, + const BB &falseBranch, + const BB &trueBranch) { std::unique_ptr trueBranchValueRange; std::unique_ptr falseBranchValueRange; trueBranchValueRange = CopyValueRange(rightRange); @@ -3924,8 +4008,8 @@ void ValueRangePropagation::PropValueRangeFromCondGotoToTrueAndFalseBranch( // predOpnd: a, rhs of currOpnd in this bb // phiOpnds: (b, c), phi rhs of opnd in this bb // predOpnd or phiOpnds is uesd to find the valuerange in the pred of bb -void ValueRangePropagation::ReplaceOpndByDef(const BB &bb, MeExpr &currOpnd, MeExpr *&predOpnd, - MePhiNode *&phi, bool &thePhiIsInBB) { +void ValueRangePropagation::ReplaceOpndByDef(const BB &bb, MeExpr &currOpnd, MeExpr *&predOpnd, MePhiNode *&phi, + bool &thePhiIsInBB) { /* If currOpnd is not defined in bb, set opnd to currOpnd */ predOpnd = &currOpnd; /* find the rhs of opnd */ @@ -4030,9 +4114,10 @@ bool ValueRangePropagation::TowCompareOperandsAreInSameIterOfLoop(const MeExpr & return true; } -bool ValueRangePropagation::AnalysisValueRangeInPredsOfCondGotoBB( - BB &bb, MeExpr *opnd0, MeExpr &currOpnd, ValueRange *rightRange, - BB &falseBranch, BB &trueBranch, PrimType opndType, Opcode op, BB &condGoto) { +bool ValueRangePropagation::AnalysisValueRangeInPredsOfCondGotoBB(BB &bb, MeExpr *opnd0, MeExpr &currOpnd, + ValueRange *rightRange, BB &falseBranch, + BB &trueBranch, PrimType opndType, Opcode op, + BB &condGoto) { bool opt = false; /* Records the currOpnd of pred */ MeExpr *predOpnd = nullptr; @@ -4160,7 +4245,7 @@ bool ValueRangePropagation::AnalysisValueRangeInPredsOfCondGotoBB( } } if (ConditionEdgeCanBeDeleted(*pred, bb, valueRangeInPred, rightRange, falseBranch, trueBranch, opndType, op, - updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr)) { + updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr)) { if (updateSSAExceptTheScalarExpr != nullptr && phi != nullptr) { if (updateSSAExceptTheScalarExpr->GetDefBy() == kDefByStmt) { // PredOpnd is only used by condGoto stmt and phi, if the condGoto stmt can be deleted, need not update ssa @@ -4178,11 +4263,11 @@ bool ValueRangePropagation::AnalysisValueRangeInPredsOfCondGotoBB( opt = true; } else { /* avoid infinite loop, pred->GetKind() maybe kBBUnknown */ - if ((pred->GetKind() == kBBFallthru || pred->GetKind() == kBBGoto) && - pred->GetBBId() != falseBranch.GetBBId() && pred->GetBBId() != trueBranch.GetBBId() && - (opnd0 == nullptr || TowCompareOperandsAreInSameIterOfLoop(currOpnd, *opnd0))) { - opt |= AnalysisValueRangeInPredsOfCondGotoBB( - *pred, opnd0, *predOpnd, rightRange, falseBranch, trueBranch, opndType, op, condGoto); + if ((pred->GetKind() == kBBFallthru || pred->GetKind() == kBBGoto) && pred->GetBBId() != falseBranch.GetBBId() && + pred->GetBBId() != trueBranch.GetBBId() && + (opnd0 == nullptr || TowCompareOperandsAreInSameIterOfLoop(currOpnd, *opnd0))) { + opt |= AnalysisValueRangeInPredsOfCondGotoBB(*pred, opnd0, *predOpnd, rightRange, falseBranch, trueBranch, + opndType, op, condGoto); } } if (bb.GetPred().size() == predSize) { @@ -4222,8 +4307,8 @@ bool ValueRangePropagation::AnalysisValueRangeInPredsOfCondGotoBB( // ==> // if mx12 void ValueRangePropagation::ReplaceUsePoints(MePhiNode *phi) { - if (phi == nullptr || phi->GetDefBB() == nullptr || - phi->GetDefBB()->GetMePhiList().empty() || phi->GetOpnds().empty()) { + if (phi == nullptr || phi->GetDefBB() == nullptr || phi->GetDefBB()->GetMePhiList().empty() || + phi->GetOpnds().empty()) { return; } auto *opnd = phi->GetOpnd(0); @@ -4280,8 +4365,8 @@ Opcode ValueRangePropagation::GetOpAfterSwapThePositionsOfTwoOperands(Opcode op) } } -bool ValueRangePropagation::ConditionEdgeCanBeDeleted(BB &bb, MeExpr &opnd0, ValueRange *rightRange, - PrimType opndType, Opcode op) { +bool ValueRangePropagation::ConditionEdgeCanBeDeleted(BB &bb, MeExpr &opnd0, ValueRange *rightRange, PrimType opndType, + Opcode op) { if (onlyPropVR) { return false; } @@ -4301,8 +4386,8 @@ bool ValueRangePropagation::ConditionEdgeCanBeDeleted(BB &bb, MeExpr &opnd0, Val BB *trueBranch = nullptr; BB *falseBranch = nullptr; GetTrueAndFalseBranch(static_cast(bb.GetLastMe())->GetOp(), bb, trueBranch, falseBranch); - bool opt = AnalysisValueRangeInPredsOfCondGotoBB( - bb, nullptr, *currOpnd, rightRange, *falseBranch, *trueBranch, opndType, op, bb); + bool opt = AnalysisValueRangeInPredsOfCondGotoBB(bb, nullptr, *currOpnd, rightRange, *falseBranch, *trueBranch, + opndType, op, bb); if (!opt && bb.GetKind() == kBBCondGoto && static_cast(bb.GetLastMe())->GetOpnd()->GetNumOpnds() == kNumOperands) { // Swap the positions of two operands like : @@ -4317,8 +4402,8 @@ bool ValueRangePropagation::ConditionEdgeCanBeDeleted(BB &bb, MeExpr &opnd0, Val // opnd[1] = CONST 0 mx1 auto *valueRangeOfOpnd0 = FindValueRange(bb, opnd0); - opt = AnalysisValueRangeInPredsOfCondGotoBB(bb, currOpnd, *opnd1, valueRangeOfOpnd0, *falseBranch, - *trueBranch, opndType, GetOpAfterSwapThePositionsOfTwoOperands(op), bb); + opt = AnalysisValueRangeInPredsOfCondGotoBB(bb, currOpnd, *opnd1, valueRangeOfOpnd0, *falseBranch, *trueBranch, + opndType, GetOpAfterSwapThePositionsOfTwoOperands(op), bb); } bool canDeleteBB = false; for (size_t i = 0; i < bb.GetPred().size(); ++i) { @@ -4353,7 +4438,8 @@ Opcode ValueRangePropagation::GetTheOppositeOp(Opcode op) const { } void ValueRangePropagation::CreateValueRangeForCondGoto(const MeExpr &opnd, Opcode op, ValueRange *leftRange, - ValueRange &rightRange, const BB &trueBranch, const BB &falseBranch) { + ValueRange &rightRange, const BB &trueBranch, + const BB &falseBranch) { auto newRightUpper = rightRange.GetUpper(); auto newRightLower = rightRange.GetLower(); CHECK_FATAL(IsEqualPrimType(newRightUpper.GetPrimType(), newRightLower.GetPrimType()), "must be equal"); @@ -4381,23 +4467,21 @@ void ValueRangePropagation::CreateValueRangeForCondGoto(const MeExpr &opnd, Opco bool isAccurate = dealWithPhi && (rightRange.GetRangeType() == kEqual || rightRange.IsAccurate()); if (op == OP_lt || op == OP_le) { if (leftRange != nullptr && leftRange->GetRangeType() == kNotEqual) { - CreateValueRangeForLeOrLt( - opnd, nullptr, newRightUpper, newRightLower, trueBranch, falseBranch, isAccurate); + CreateValueRangeForLeOrLt(opnd, nullptr, newRightUpper, newRightLower, trueBranch, falseBranch, isAccurate); } else { CreateValueRangeForLeOrLt(opnd, leftRange, newRightUpper, newRightLower, trueBranch, falseBranch, isAccurate); } } else if (op == OP_gt || op == OP_ge) { if (leftRange != nullptr && leftRange->GetRangeType() == kNotEqual) { - CreateValueRangeForGeOrGt( - opnd, nullptr, newRightUpper, newRightLower, trueBranch, falseBranch, isAccurate); + CreateValueRangeForGeOrGt(opnd, nullptr, newRightUpper, newRightLower, trueBranch, falseBranch, isAccurate); } else { CreateValueRangeForGeOrGt(opnd, leftRange, newRightUpper, newRightLower, trueBranch, falseBranch, isAccurate); } } } -void ValueRangePropagation::DealWithCondGoto( - BB &bb, Opcode op, ValueRange *leftRange, ValueRange &rightRange, const CondGotoMeStmt &brMeStmt) { +void ValueRangePropagation::DealWithCondGoto(BB &bb, Opcode op, ValueRange *leftRange, ValueRange &rightRange, + const CondGotoMeStmt &brMeStmt) { MeExpr *opnd0 = nullptr; PrimType primType; if (IsCompareHasReverseOp(brMeStmt.GetOpnd()->GetOp())) { @@ -4431,12 +4515,13 @@ void ValueRangePropagation::DealWithCondGoto( } bool ValueRangePropagation::GetValueRangeOfCondGotoOpnd(const BB &bb, OpMeExpr &opMeExpr, MeExpr &opnd, - ValueRange *&valueRange, std::unique_ptr &rightRangePtr) { + ValueRange *&valueRange, + std::unique_ptr &rightRangePtr) { valueRange = FindValueRange(bb, opnd); if (valueRange == nullptr) { if (opnd.GetMeOp() == kMeOpConst && static_cast(opnd).GetConstVal()->GetKind() == kConstInt) { - rightRangePtr = std::make_unique(Bound(static_cast(opnd).GetExtIntValue(), - opnd.GetPrimType()), kEqual); + rightRangePtr = std::make_unique( + Bound(static_cast(opnd).GetExtIntValue(), opnd.GetPrimType()), kEqual); valueRange = rightRangePtr.get(); if (!Insert2Caches(bb.GetBBId(), opnd.GetExprID(), std::move(rightRangePtr))) { valueRange = nullptr; @@ -4475,8 +4560,8 @@ bool ValueRangePropagation::GetValueRangeOfCondGotoOpnd(const BB &bb, OpMeExpr & valueRange = rightRangePtr.get(); (void)Insert2Caches(bb.GetBBId(), opnd.GetExprID(), std::move(rightRangePtr)); } else if ((opnd.GetOp() == OP_ne && lhsBound.IsEqual(rhsBound, rhsPrimType) && lhsRangeType == kEqual) || - (opnd.GetOp() == OP_eq && !lhsBound.IsEqual(rhsBound, rhsPrimType) && lhsRangeType == kEqual) || - (opnd.GetOp() == OP_eq && lhsBound.IsEqual(rhsBound, rhsPrimType) && lhsRangeType == kNotEqual)) { + (opnd.GetOp() == OP_eq && !lhsBound.IsEqual(rhsBound, rhsPrimType) && lhsRangeType == kEqual) || + (opnd.GetOp() == OP_eq && lhsBound.IsEqual(rhsBound, rhsPrimType) && lhsRangeType == kNotEqual)) { rightRangePtr = std::make_unique(Bound(nullptr, 0, PTY_u1), kEqual); valueRange = rightRangePtr.get(); (void)Insert2Caches(bb.GetBBId(), opnd.GetExprID(), std::move(rightRangePtr)); @@ -4502,8 +4587,9 @@ MeExpr *ValueRangePropagation::GetDefOfBase(const IvarMeExpr &ivar) const { return var->GetDefStmt()->GetLHS(); } -void ValueRangePropagation::DealWithCondGotoWhenRightRangeIsNotExist( - BB &bb, const MeExpr &opnd0, MeExpr &opnd1, Opcode opOfBrStmt, Opcode conditionalOp, ValueRange *valueRangeOfLeft) { +void ValueRangePropagation::DealWithCondGotoWhenRightRangeIsNotExist(BB &bb, const MeExpr &opnd0, MeExpr &opnd1, + Opcode opOfBrStmt, Opcode conditionalOp, + ValueRange *valueRangeOfLeft) { PrimType prim = opnd1.GetPrimType(); if (!IsNeededPrimType(prim)) { return; @@ -4514,72 +4600,76 @@ void ValueRangePropagation::DealWithCondGotoWhenRightRangeIsNotExist( switch (conditionalOp) { case OP_ne: { (void)Insert2Caches(trueBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(Bound(&opnd1, prim), kNotEqual)); + std::make_unique(Bound(&opnd1, prim), kNotEqual)); (void)Insert2Caches(falseBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(Bound(&opnd1, prim), kEqual)); + std::make_unique(Bound(&opnd1, prim), kEqual)); break; } case OP_eq: { (void)Insert2Caches(trueBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(Bound(&opnd1, prim), kEqual)); + std::make_unique(Bound(&opnd1, prim), kEqual)); (void)Insert2Caches(falseBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(Bound(&opnd1, prim), kNotEqual)); + std::make_unique(Bound(&opnd1, prim), kNotEqual)); break; } case OP_le: { if (valueRangeOfLeft != nullptr && valueRangeOfLeft->GetRangeType() == kOnlyHasLowerBound) { (void)Insert2Caches(trueBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(valueRangeOfLeft->GetLower(), - Bound(&opnd1, prim), kLowerAndUpper, dealWithPhi)); + std::make_unique(valueRangeOfLeft->GetLower(), Bound(&opnd1, prim), + kLowerAndUpper, dealWithPhi)); } else { - (void)Insert2Caches(trueBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(Bound(GetMinNumber(prim), prim), - Bound(&opnd1, prim), kLowerAndUpper)); + (void)Insert2Caches( + trueBranch->GetBBId(), opnd0.GetExprID(), + std::make_unique(Bound(GetMinNumber(prim), prim), Bound(&opnd1, prim), kLowerAndUpper)); } - (void)Insert2Caches(falseBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(Bound(&opnd1, 1, prim), - Bound(GetMaxNumber(prim), prim), kLowerAndUpper)); + (void)Insert2Caches( + falseBranch->GetBBId(), opnd0.GetExprID(), + std::make_unique(Bound(&opnd1, 1, prim), Bound(GetMaxNumber(prim), prim), kLowerAndUpper)); break; } case OP_lt: { if (valueRangeOfLeft != nullptr && valueRangeOfLeft->GetRangeType() == kOnlyHasLowerBound) { (void)Insert2Caches(trueBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(valueRangeOfLeft->GetLower(), - Bound(&opnd1, -1, prim), kLowerAndUpper, dealWithPhi)); + std::make_unique(valueRangeOfLeft->GetLower(), Bound(&opnd1, -1, prim), + kLowerAndUpper, dealWithPhi)); } else { - (void)Insert2Caches(trueBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(Bound(GetMinNumber(prim), prim), - Bound(&opnd1, -1, prim), kLowerAndUpper)); + (void)Insert2Caches( + trueBranch->GetBBId(), opnd0.GetExprID(), + std::make_unique(Bound(GetMinNumber(prim), prim), Bound(&opnd1, -1, prim), kLowerAndUpper)); } - (void)Insert2Caches(falseBranch->GetBBId(), opnd0.GetExprID(), + (void)Insert2Caches( + falseBranch->GetBBId(), opnd0.GetExprID(), std::make_unique(Bound(&opnd1, prim), Bound(GetMaxNumber(prim), prim), kLowerAndUpper)); break; } case OP_ge: { if (valueRangeOfLeft != nullptr && valueRangeOfLeft->GetRangeType() == kOnlyHasUpperBound) { - (void)Insert2Caches(trueBranch->GetBBId(), opnd0.GetExprID(), std::make_unique( - Bound(&opnd1, prim), valueRangeOfLeft->GetBound(), kLowerAndUpper, dealWithPhi)); - } else { (void)Insert2Caches(trueBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(Bound(&opnd1, prim), - Bound(GetMaxNumber(prim), prim), kLowerAndUpper)); + std::make_unique(Bound(&opnd1, prim), valueRangeOfLeft->GetBound(), + kLowerAndUpper, dealWithPhi)); + } else { + (void)Insert2Caches( + trueBranch->GetBBId(), opnd0.GetExprID(), + std::make_unique(Bound(&opnd1, prim), Bound(GetMaxNumber(prim), prim), kLowerAndUpper)); } - (void)Insert2Caches(falseBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(Bound(GetMinNumber(prim), prim), - Bound(&opnd1, -1, prim), kLowerAndUpper)); + (void)Insert2Caches( + falseBranch->GetBBId(), opnd0.GetExprID(), + std::make_unique(Bound(GetMinNumber(prim), prim), Bound(&opnd1, -1, prim), kLowerAndUpper)); break; } case OP_gt: { if (valueRangeOfLeft != nullptr && valueRangeOfLeft->GetRangeType() == kOnlyHasUpperBound) { - (void)Insert2Caches(trueBranch->GetBBId(), opnd0.GetExprID(), std::make_unique( - Bound(&opnd1, 1, prim), valueRangeOfLeft->GetBound(), kLowerAndUpper, dealWithPhi)); - } else { (void)Insert2Caches(trueBranch->GetBBId(), opnd0.GetExprID(), + std::make_unique(Bound(&opnd1, 1, prim), valueRangeOfLeft->GetBound(), + kLowerAndUpper, dealWithPhi)); + } else { + (void)Insert2Caches( + trueBranch->GetBBId(), opnd0.GetExprID(), std::make_unique(Bound(&opnd1, 1, prim), Bound(GetMaxNumber(prim), prim), kLowerAndUpper)); } - (void)Insert2Caches(falseBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(Bound(GetMinNumber(prim), prim), - Bound(&opnd1, prim), kLowerAndUpper)); + (void)Insert2Caches( + falseBranch->GetBBId(), opnd0.GetExprID(), + std::make_unique(Bound(GetMinNumber(prim), prim), Bound(&opnd1, prim), kLowerAndUpper)); break; } default: @@ -4588,15 +4678,16 @@ void ValueRangePropagation::DealWithCondGotoWhenRightRangeIsNotExist( } void ValueRangePropagation::GetValueRangeForUnsignedInt(const BB &bb, OpMeExpr &opMeExpr, const MeExpr &opnd, - ValueRange *&valueRange, std::unique_ptr &rightRangePtr) { + ValueRange *&valueRange, + std::unique_ptr &rightRangePtr) { if (onlyPropVR) { return; } PrimType prim = opMeExpr.GetOpndType(); if (prim == PTY_u1 || prim == PTY_u8 || prim == PTY_u16 || prim == PTY_u32 || prim == PTY_a32 || ((prim == PTY_ref || prim == PTY_ptr) && GetPrimTypeSize(prim) == kFourByte)) { - rightRangePtr = std::make_unique( - Bound(nullptr, 0, prim), Bound(GetMaxNumber(prim), prim), kLowerAndUpper); + rightRangePtr = + std::make_unique(Bound(nullptr, 0, prim), Bound(GetMaxNumber(prim), prim), kLowerAndUpper); valueRange = rightRangePtr.get(); (void)Insert2Caches(bb.GetBBId(), opnd.GetExprID(), std::move(rightRangePtr)); } @@ -4607,8 +4698,8 @@ void ValueRangePropagation::GetValueRangeForUnsignedInt(const BB &bb, OpMeExpr & // a: valuerange(0, Max) // ==> // Example: if (a != 0) -bool ValueRangePropagation::DealWithSpecialCondGoto( - const BB &bb, OpMeExpr &opMeExpr, const ValueRange &leftRange, ValueRange &rightRange, CondGotoMeStmt &brMeStmt) { +bool ValueRangePropagation::DealWithSpecialCondGoto(const BB &bb, OpMeExpr &opMeExpr, const ValueRange &leftRange, + ValueRange &rightRange, CondGotoMeStmt &brMeStmt) { if (onlyPropVR) { return false; } @@ -4632,8 +4723,8 @@ bool ValueRangePropagation::DealWithSpecialCondGoto( if (leftRange.GetLower().GetConstant() != rightRange.GetBound().GetConstant()) { return false; } - auto *newExpr = irMap.CreateMeExprCompare(OP_ne, opMeExpr.GetPrimType(), - opMeExpr.GetOpndType(), *opMeExpr.GetOpnd(0), *opMeExpr.GetOpnd(1)); + auto *newExpr = irMap.CreateMeExprCompare(OP_ne, opMeExpr.GetPrimType(), opMeExpr.GetOpndType(), + *opMeExpr.GetOpnd(0), *opMeExpr.GetOpnd(1)); (void)irMap.ReplaceMeExprStmt(brMeStmt, opMeExpr, *newExpr); return true; } @@ -4656,8 +4747,8 @@ bool ValueRangePropagation::DealWithSpecialCondGoto( } } auto *newConstExpr = irMap.CreateIntConstMeExpr(leftRange.GetLower().GetConstant(), opMeExpr.GetOpndType()); - auto *newExpr = irMap.CreateMeExprCompare(OP_eq, opMeExpr.GetPrimType(), - opMeExpr.GetOpndType(), *opMeExpr.GetOpnd(0), *newConstExpr); + auto *newExpr = irMap.CreateMeExprCompare(OP_eq, opMeExpr.GetPrimType(), opMeExpr.GetOpndType(), *opMeExpr.GetOpnd(0), + *newConstExpr); (void)irMap.ReplaceMeExprStmt(brMeStmt, opMeExpr, *newExpr); return true; } @@ -4672,11 +4763,11 @@ void ValueRangePropagation::DealWithBrStmtWithOneOpnd(BB &bb, const CondGotoMeSt // op: OP_ne // rightRange: 0 // leftRange: const 1 or var a - std::unique_ptr rightRangePtr = std::make_unique( - Bound(nullptr, 0, opnd.GetPrimType()), kEqual); + std::unique_ptr rightRangePtr = + std::make_unique(Bound(nullptr, 0, opnd.GetPrimType()), kEqual); if (opnd.GetMeOp() == kMeOpConst && static_cast(opnd).GetConstVal()->GetKind() == kConstInt) { std::unique_ptr leftRangePtr = std::make_unique( - Bound(static_cast(opnd).GetExtIntValue(), opnd.GetPrimType()), kEqual); + Bound(static_cast(opnd).GetExtIntValue(), opnd.GetPrimType()), kEqual); DealWithCondGoto(bb, op, leftRangePtr.get(), *rightRangePtr.get(), stmt); } else { ValueRange *leftRange = FindValueRange(bb, opnd); @@ -4756,14 +4847,14 @@ bool ValueRangePropagation::AnalysisUnreachableForGeOrGt(BB &bb, const CondGotoM // mx1: valuerange [min(mx2_type), mx2-1] or [min(mx2_type), mx2] // ==> // remove falseBranch or trueBranch -bool ValueRangePropagation::AnalysisUnreachableForLeOrLt( - BB &bb, const CondGotoMeStmt &brMeStmt, const ValueRange &leftRange) { +bool ValueRangePropagation::AnalysisUnreachableForLeOrLt(BB &bb, const CondGotoMeStmt &brMeStmt, + const ValueRange &leftRange) { Opcode op = static_cast(brMeStmt.GetOpnd())->GetOp(); BB *trueBranch = nullptr; BB *falseBranch = nullptr; GetTrueAndFalseBranch(brMeStmt.GetOp(), bb, trueBranch, falseBranch); // When the redundant branch can be inferred directly from the condGoto stmt - if (op == OP_lt && leftRange.GetUpper().GetConstant() == -1) { + if (op == OP_lt && leftRange.GetUpper().GetConstant() == -1) { // falseBranch is unreachable AnalysisUnreachableBBOrEdge(bb, *falseBranch, *trueBranch); return true; @@ -4796,8 +4887,7 @@ bool ValueRangePropagation::AnalysisUnreachableForEqOrNe(BB &bb, const CondGotoM BB *falseBranch = nullptr; GetTrueAndFalseBranch(brMeStmt.GetOp(), bb, trueBranch, falseBranch); // When the redundant branch can be inferred directly from the condGoto stmt - if ((op == OP_eq && leftRange.GetRangeType() == kEqual) || - (op == OP_ne && leftRange.GetRangeType() == kNotEqual)) { + if ((op == OP_eq && leftRange.GetRangeType() == kEqual) || (op == OP_ne && leftRange.GetRangeType() == kNotEqual)) { // falseBranch is unreachable AnalysisUnreachableBBOrEdge(bb, *falseBranch, *trueBranch); return true; @@ -4812,21 +4902,20 @@ bool ValueRangePropagation::AnalysisUnreachableForEqOrNe(BB &bb, const CondGotoM // This function deals with the case like this: // Example: first brfalse mx1 eq(ne/gt/le/ge/lt) mx2 // second brfalse mx1 eq(ne/gt/le/ge/lt) mx2 ==> remove falseBranch or trueBranch -bool ValueRangePropagation::DealWithVariableRange(BB &bb, const CondGotoMeStmt &brMeStmt, - const ValueRange &leftRange) { +bool ValueRangePropagation::DealWithVariableRange(BB &bb, const CondGotoMeStmt &brMeStmt, const ValueRange &leftRange) { MeExpr *opnd1 = static_cast(brMeStmt.GetOpnd())->GetOpnd(1); // Example1: deal with like if (mx1 > mx2), when the valuerange of mx1 is [mx2+1, max(mx2_type)] // Example2: deal with like if (mx1 >= mx2), when the valuerange of mx1 is [mx2, max(mx2_type)] if (leftRange.GetLower().GetVar() == opnd1 && leftRange.GetUpper().GetVar() == nullptr && leftRange.UpperIsMax(opnd1->GetPrimType())) { return AnalysisUnreachableForGeOrGt(bb, brMeStmt, leftRange); - // Example1: deal with like if (mx1 < mx2), when the valuerange of mx1 is [min(mx2_type), mx2-1] - // Example2: deal with like if (mx1 <= mx2), when the valuerange of mx1 is [min(mx2_type), mx2] + // Example1: deal with like if (mx1 < mx2), when the valuerange of mx1 is [min(mx2_type), mx2-1] + // Example2: deal with like if (mx1 <= mx2), when the valuerange of mx1 is [min(mx2_type), mx2] } else if (leftRange.GetLower().GetVar() == nullptr && leftRange.GetUpper().GetVar() == opnd1 && - leftRange.LowerIsMin(opnd1->GetPrimType())) { + leftRange.LowerIsMin(opnd1->GetPrimType())) { return AnalysisUnreachableForLeOrLt(bb, brMeStmt, leftRange); - // Example: deal with like if (mx1 == mx2), when the valuerange of mx1 is [mx2, mx2] - // Example: deal with like if (mx1 != mx2), when the valuerange of mx1 is [mx2, mx2] + // Example: deal with like if (mx1 == mx2), when the valuerange of mx1 is [mx2, mx2] + // Example: deal with like if (mx1 != mx2), when the valuerange of mx1 is [mx2, mx2] } else if (leftRange.GetLower().GetVar() == opnd1 && leftRange.GetLower().GetConstant() == 0 && leftRange.GetUpper().GetVar() == opnd1 && leftRange.GetUpper().GetConstant() == 0) { return AnalysisUnreachableForEqOrNe(bb, brMeStmt, leftRange); @@ -4890,7 +4979,8 @@ void ValueRangePropagation::DealWithCondGoto(BB &bb, MeStmt &stmt) { } void ValueRangePropagation::DumpCaches() { - LogInfo::MapleLogger() << "================Dump value range===================" << "\n"; + LogInfo::MapleLogger() << "================Dump value range===================" + << "\n"; for (size_t i = 0; i < caches.size(); ++i) { LogInfo::MapleLogger() << "BBId: " << i << "\n"; auto &it = caches[i]; @@ -4898,17 +4988,16 @@ void ValueRangePropagation::DumpCaches() { if (bIt->second == nullptr) { continue; } - if (bIt->second->GetRangeType() == kLowerAndUpper || - bIt->second->GetRangeType() == kSpecialLowerForLoop || + if (bIt->second->GetRangeType() == kLowerAndUpper || bIt->second->GetRangeType() == kSpecialLowerForLoop || bIt->second->GetRangeType() == kSpecialUpperForLoop) { - std::string lower = (bIt->second->GetLower().GetVar() == nullptr) ? - std::to_string(bIt->second->GetLower().GetConstant()) : - "mx" + std::to_string(bIt->second->GetLower().GetVar()->GetExprID()) + " " + - std::to_string(bIt->second->GetLower().GetConstant()); - std::string upper = (bIt->second->GetUpper().GetVar() == nullptr) ? - std::to_string(bIt->second->GetUpper().GetConstant()) : - "mx" + std::to_string(bIt->second->GetUpper().GetVar()->GetExprID()) + " " + - std::to_string(bIt->second->GetUpper().GetConstant()); + std::string lower = (bIt->second->GetLower().GetVar() == nullptr) + ? std::to_string(bIt->second->GetLower().GetConstant()) + : "mx" + std::to_string(bIt->second->GetLower().GetVar()->GetExprID()) + " " + + std::to_string(bIt->second->GetLower().GetConstant()); + std::string upper = (bIt->second->GetUpper().GetVar() == nullptr) + ? std::to_string(bIt->second->GetUpper().GetConstant()) + : "mx" + std::to_string(bIt->second->GetUpper().GetVar()->GetExprID()) + " " + + std::to_string(bIt->second->GetUpper().GetConstant()); LogInfo::MapleLogger() << "mx" << bIt->first << " lower: " << lower << " upper: " << upper; if (bIt->second->GetRangeType() == kLowerAndUpper) { LogInfo::MapleLogger() << " kLowerAndUpper\n"; @@ -4918,22 +5007,23 @@ void ValueRangePropagation::DumpCaches() { LogInfo::MapleLogger() << " kSpecialUpperForLoop\n"; } } else if (bIt->second->GetRangeType() == kOnlyHasLowerBound) { - std::string lower = (bIt->second->GetBound().GetVar() == nullptr) ? - std::to_string(bIt->second->GetBound().GetConstant()) : - "mx" + std::to_string(bIt->second->GetBound().GetVar()->GetExprID()) + " " + - std::to_string(bIt->second->GetBound().GetConstant()); - LogInfo::MapleLogger() << "mx" << bIt->first << " lower: " << lower << " upper: max " << "kOnlyHasLowerBound\n"; + std::string lower = (bIt->second->GetBound().GetVar() == nullptr) + ? std::to_string(bIt->second->GetBound().GetConstant()) + : "mx" + std::to_string(bIt->second->GetBound().GetVar()->GetExprID()) + " " + + std::to_string(bIt->second->GetBound().GetConstant()); + LogInfo::MapleLogger() << "mx" << bIt->first << " lower: " << lower << " upper: max " + << "kOnlyHasLowerBound\n"; } else if (bIt->second->GetRangeType() == kOnlyHasUpperBound) { - std::string upper = (bIt->second->GetBound().GetVar() == nullptr) ? - std::to_string(bIt->second->GetBound().GetConstant()) : - "mx" + std::to_string(bIt->second->GetBound().GetVar()->GetExprID()) + " " + - std::to_string(bIt->second->GetBound().GetConstant()); + std::string upper = (bIt->second->GetBound().GetVar() == nullptr) + ? std::to_string(bIt->second->GetBound().GetConstant()) + : "mx" + std::to_string(bIt->second->GetBound().GetVar()->GetExprID()) + " " + + std::to_string(bIt->second->GetBound().GetConstant()); LogInfo::MapleLogger() << "mx" << bIt->first << " lower: min upper: " << upper << "kOnlyHasUpperBound\n"; } else if (bIt->second->GetRangeType() == kEqual || bIt->second->GetRangeType() == kNotEqual) { - std::string lower = (bIt->second->GetBound().GetVar() == nullptr) ? - std::to_string(bIt->second->GetBound().GetConstant()) : - "mx" + std::to_string(bIt->second->GetBound().GetVar()->GetExprID()) + " " + - std::to_string(bIt->second->GetBound().GetConstant()); + std::string lower = (bIt->second->GetBound().GetVar() == nullptr) + ? std::to_string(bIt->second->GetBound().GetConstant()) + : "mx" + std::to_string(bIt->second->GetBound().GetVar()->GetExprID()) + " " + + std::to_string(bIt->second->GetBound().GetConstant()); LogInfo::MapleLogger() << "mx" << bIt->first << " lower and upper: " << lower; if (bIt->second->GetRangeType() == kEqual) { LogInfo::MapleLogger() << " kEqual\n"; @@ -4943,7 +5033,8 @@ void ValueRangePropagation::DumpCaches() { } } } - LogInfo::MapleLogger() << "================Dump value range===================" << "\n"; + LogInfo::MapleLogger() << "================Dump value range===================" + << "\n"; } void MEValueRangePropagation::GetAnalysisDependence(maple::AnalysisDep &aDep) const { @@ -4973,7 +5064,7 @@ bool MEValueRangePropagation::PhaseRun(maple::MeFunction &f) { sa.SetComputeTripCountForLoopUnroll(false); ValueRangePropagation valueRangePropagation(f, *irMap, *dom, meLoop, *valueRangeMemPool, cands, sa, true); - SafetyCheck safetyCheck; // dummy + SafetyCheck safetyCheck; // dummy valueRangePropagation.SetSafetyBoundaryCheck(safetyCheck); valueRangePropagation.SetSafetyNonnullCheck(safetyCheck); @@ -4993,29 +5084,39 @@ bool MEValueRangePropagation::PhaseRun(maple::MeFunction &f) { MPLTimer timer; timer.Start(); if (ValueRangePropagation::isDebug) { - LogInfo::MapleLogger() << "***************ssaupdate value range prop***************" << "\n"; - LogInfo::MapleLogger() << "========size of ost " << cands.size() << " " << - f.GetMeSSATab()->GetOriginalStTableSize() << "========\n"; + LogInfo::MapleLogger() << "***************ssaupdate value range prop***************" + << "\n"; + LogInfo::MapleLogger() << "========size of ost " << cands.size() << " " + << f.GetMeSSATab()->GetOriginalStTableSize() << "========\n"; } ssaUpdate.Run(); timer.Stop(); if (ValueRangePropagation::isDebug) { LogInfo::MapleLogger() << "ssaupdate consumes cumulatively " << timer.Elapsed() << "seconds " << '\n'; - LogInfo::MapleLogger() << "***************ssaupdate value range prop***************" << "\n"; + LogInfo::MapleLogger() << "***************ssaupdate value range prop***************" + << "\n"; } } GetAnalysisInfoHook()->ForceEraseAnalysisPhase(f.GetUniqueID(), &MELoopAnalysis::id); GetAnalysisInfoHook()->ForceRunTransFormPhase(&MELoopCanon::id, f); + // update cfg frequency + if (f.GetCfg()->UpdateCFGFreq()) { + f.GetCfg()->UpdateEdgeFreqWithBBFreq(); + if (f.GetCfg()->DumpIRProfileFile()) { + f.GetCfg()->DumpToFile("after-valuerange" + std::to_string(f.vrpRuns), false, true); + } + } } // Run vrp twice when need check boundary and nullable pointer. if (MeOption::boundaryCheckMode != kNoCheck || MeOption::npeCheckMode != kNoCheck) { auto *hook = GetAnalysisInfoHook(); - dom = static_cast( - hook->ForceRunAnalysisPhase>(&MEDominance::id, f))->GetResult(); + dom = static_cast(hook->ForceRunAnalysisPhase>(&MEDominance::id, f)) + ->GetResult(); meLoop = static_cast( - hook->ForceRunAnalysisPhase>(&MELoopAnalysis::id, f))->GetResult(); - ValueRangePropagation valueRangePropagationWithOPTAssert( - f, *irMap, *dom, meLoop, *valueRangeMemPool, cands, sa, true, true); + hook->ForceRunAnalysisPhase>(&MELoopAnalysis::id, f)) + ->GetResult(); + ValueRangePropagation valueRangePropagationWithOPTAssert(f, *irMap, *dom, meLoop, *valueRangeMemPool, cands, sa, + true, true); SafetyCheckWithBoundaryError safetyCheckBoundaryError(f, valueRangePropagationWithOPTAssert); SafetyCheckWithNonnullError safetyCheckNonnullError(f); if (MeOption::boundaryCheckMode == kNoCheck) { @@ -5031,7 +5132,8 @@ bool MEValueRangePropagation::PhaseRun(maple::MeFunction &f) { valueRangePropagationWithOPTAssert.Execute(); CHECK_FATAL(!valueRangePropagationWithOPTAssert.IsCFGChange(), "must not change the cfg!"); if (ValueRangePropagation::isDebug) { - LogInfo::MapleLogger() << "***************after check***************" << "\n"; + LogInfo::MapleLogger() << "***************after check***************" + << "\n"; f.Dump(false); f.GetCfg()->DumpToFile("valuerange-after-safe" + std::to_string(f.vrpRuns)); } diff --git a/src/mapleall/maple_me/src/optimizeCFG.cpp b/src/mapleall/maple_me/src/optimizeCFG.cpp index cbfa5e01f7..6665d96580 100644 --- a/src/mapleall/maple_me/src/optimizeCFG.cpp +++ b/src/mapleall/maple_me/src/optimizeCFG.cpp @@ -13,8 +13,9 @@ * See the Mulan PSL v2 for more details. */ #include "optimizeCFG.h" -#include "me_phase_manager.h" + #include "factory.h" +#include "me_phase_manager.h" namespace maple { namespace { @@ -23,27 +24,27 @@ const char *funcName = nullptr; std::string phaseName; #define LOG_BBID(BB) ((BB)->GetBBId().GetIdx()) -#define DEBUG_LOG() if (debug) \ -LogInfo::MapleLogger() << "[" << phaseName << "] " +#define DEBUG_LOG() \ + if (debug) LogInfo::MapleLogger() << "[" << phaseName << "] " // return {trueBB, falseBB} -std::pair GetTrueFalseBrPair(BB *bb) { +std::pair GetTrueFalseBrPair(BB *bb) { if (bb == nullptr) { - return { nullptr, nullptr }; + return {nullptr, nullptr}; } if (bb->GetKind() == kBBCondGoto) { auto *condBr = static_cast(bb->GetLastMe()); CHECK_FATAL(condBr, "condBr is nullptr!"); if (condBr->GetOp() == OP_brtrue) { - return { bb->GetSucc(1), bb->GetSucc(0) }; + return {bb->GetSucc(1), bb->GetSucc(0)}; } else { ASSERT(condBr->GetOp() == OP_brfalse, "only support brtrue/brfalse"); - return { bb->GetSucc(0), bb->GetSucc(1) }; + return {bb->GetSucc(0), bb->GetSucc(1)}; } } else if (bb->GetKind() == kBBGoto) { - return { bb->GetSucc(0), nullptr }; + return {bb->GetSucc(0), nullptr}; } - return { nullptr, nullptr }; + return {nullptr, nullptr}; } // Only one fallthru is allowed for a bb at most , but a bb may have be more than one fallthru pred @@ -82,7 +83,7 @@ void CollectUnsafeExpr(MeExpr *expr, std::set &exprSet) { if (expr->GetMeOp() == kMeOpConst || expr->GetMeOp() == kMeOpVar) { return; } - if (expr->GetMeOp() == kMeOpIvar) { // do not use HasIvar here for efficiency reasons + if (expr->GetMeOp() == kMeOpIvar) { // do not use HasIvar here for efficiency reasons exprSet.insert(expr); } if (expr->GetOp() == OP_div || expr->GetOp() == OP_rem) { @@ -100,7 +101,7 @@ void CollectUnsafeExpr(MeExpr *expr, std::set &exprSet) { // expr not throw exception bool IsSafeExpr(const MeExpr *expr) { - if (expr->GetMeOp() == kMeOpIvar) { // do not use HasIvar here for efficiency reasons + if (expr->GetMeOp() == kMeOpIvar) { // do not use HasIvar here for efficiency reasons return false; } if (expr->GetOp() == OP_div || expr->GetOp() == OP_rem) { @@ -123,8 +124,7 @@ bool IsSafeExpr(const MeExpr *expr) { bool IsSimpleImm(uint64 imm) { return ((imm & (static_cast(0xffff) << 48u)) == imm) || ((imm & (static_cast(0xffff) << 32u)) == imm) || - ((imm & (static_cast(0xffff) << 16u)) == imm) || - ((imm & (static_cast(0xffff))) == imm) || + ((imm & (static_cast(0xffff) << 16u)) == imm) || ((imm & (static_cast(0xffff))) == imm) || (((~imm) & (static_cast(0xffff) << 48u)) == ~imm) || (((~imm) & (static_cast(0xffff) << 32u)) == ~imm) || (((~imm) & (static_cast(0xffff) << 16u)) == ~imm) || @@ -135,12 +135,12 @@ bool IsSimpleImm(uint64 imm) { // if non-simple imm exist, return it, otherwise return 0 int64 GetNonSimpleImm(MeExpr *expr) { if (expr->GetMeOp() == kMeOpConst && IsPrimitiveInteger(expr->GetPrimType())) { - int64 imm = static_cast(static_cast(expr)->GetConstVal())->GetExtValue(); + int64 imm = static_cast(static_cast(expr)->GetConstVal())->GetExtValue(); if (!IsSimpleImm(static_cast(imm))) { return imm; } } - return 0; // 0 is a simple imm + return 0; // 0 is a simple imm } // Check if ftBB has only one regassign stmt, if regassign exists, return it, otherwise return nullptr @@ -150,7 +150,7 @@ AssignMeStmt *GetSingleAssign(BB *bb) { while (stmt != nullptr && stmt->GetOp() == OP_comment) { stmt = stmt->GetNextMeStmt(); } - if (stmt == nullptr) { // empty bb or has only comment stmt + if (stmt == nullptr) { // empty bb or has only comment stmt return nullptr; } if (stmt->GetOp() == OP_regassign || stmt->GetOp() == OP_dassign) { @@ -193,7 +193,7 @@ bool IsAllOpndsNotDefByCurrBB(const MeExpr &expr, const BB &currBB, std::setGetPred().empty() && bb->GetSucc().empty() && phiNode.GetOpnds().size() == 1) { @@ -207,7 +207,7 @@ bool IsAllOpndsNotDefByCurrBB(const MeExpr &expr, const BB &currBB, std::setGetBB() != &currBB; } case kMeOpIvar: { - auto &ivar = static_cast(expr); + auto &ivar = static_cast(expr); if (!IsAllOpndsNotDefByCurrBB(*ivar.GetBase(), currBB, infLoopCheck)) { return false; } @@ -249,8 +249,8 @@ bool IsAllOpndsNotDefByCurrBB(const MeStmt &stmt) { MeExpr *GetInvertCond(MeIRMap *irmap, MeExpr *cond) { if (IsCompareHasReverseOp(cond->GetOp())) { - return irmap->CreateMeExprBinary(GetReverseCmpOp(cond->GetOp()), cond->GetPrimType(), - *cond->GetOpnd(0), *cond->GetOpnd(1)); + return irmap->CreateMeExprBinary(GetReverseCmpOp(cond->GetOp()), cond->GetPrimType(), *cond->GetOpnd(0), + *cond->GetOpnd(1)); } return irmap->CreateMeExprUnary(OP_lnot, cond->GetPrimType(), *cond); } @@ -258,8 +258,7 @@ MeExpr *GetInvertCond(MeIRMap *irmap, MeExpr *cond) { // Is subSet a subset of superSet? template inline bool IsSubset(const std::set &subSet, const std::set &superSet) { - return std::includes(superSet.begin(), superSet.end(), - subSet.begin(), subSet.end()); + return std::includes(superSet.begin(), superSet.end(), subSet.begin(), subSet.end()); } // before : predCond ---> succCond @@ -269,7 +268,7 @@ bool IsSafeToMergeCond(MeExpr *predCond, MeExpr *succCond) { // Make sure succCond is not dependent on predCond // e.g. if (ptr != nullptr) if (*ptr), the second condition depends on the first one if (predCond == succCond) { - return true; // same expr + return true; // same expr } if (!IsSafeExpr(succCond)) { std::set predSet; @@ -316,9 +315,9 @@ std::unique_ptr GetVRForSimpleCmpExpr(const MeExpr &expr) { if (!IsPrimitiveInteger(opndType)) { return nullptr; } - Bound opnd1Bound(nullptr, 0, opndType); // bound of expr's opnd1 + Bound opnd1Bound(nullptr, 0, opndType); // bound of expr's opnd1 if (expr.GetOpnd(1)->GetMeOp() == kMeOpConst) { - MIRConst *constVal = static_cast(expr.GetOpnd(1))->GetConstVal(); + MIRConst *constVal = static_cast(expr.GetOpnd(1))->GetConstVal(); if (constVal->GetKind() != kConstInt) { return nullptr; } @@ -380,7 +379,7 @@ BB *GetCommonDest(BB *predBB, BB *succBB) { } if (psucc0 != succBB && psucc1 != succBB) { - return nullptr; // predBB has no branch to succBB + return nullptr; // predBB has no branch to succBB } BB *commonBB = (psucc0 == succBB) ? psucc1 : psucc0; if (commonBB == nullptr) { @@ -517,7 +516,7 @@ bool UnreachBBAnalysis(const maple::MeFunction &f) { } return false; } -} // anonymous namespace +} // anonymous namespace // contains only one valid goto stmt bool HasOnlyMeGotoStmt(BB &bb) { @@ -600,8 +599,8 @@ bool IsMplEmptyBB(BB &bb) { // connectingBB has only one pred and succ, and has no stmt (except a single gotoStmt) in it bool IsConnectingBB(BB &bb) { return (bb.GetPred().size() == 1 && bb.GetSucc().size() == 1) && - (IsMeEmptyBB(bb) || HasOnlyMeGotoStmt(bb)) && // for meir, if no meir exist, it is empty - (IsMplEmptyBB(bb) || HasOnlyMplGotoStmt(bb)); // for mplir, if no mplir exist, it is empty + (IsMeEmptyBB(bb) || HasOnlyMeGotoStmt(bb)) && // for meir, if no meir exist, it is empty + (IsMplEmptyBB(bb) || HasOnlyMplGotoStmt(bb)); // for mplir, if no mplir exist, it is empty } // RealSucc is a non-connecting BB which is not empty (or has just a single gotoStmt). @@ -664,8 +663,8 @@ void EliminateEmptyConnectingBB(const BB *predBB, BB *emptyBB, const BB *stopBB, while (emptyBB != nullptr && emptyBB != stopBB && IsConnectingBB(*emptyBB)) { BB *succ = emptyBB->GetSucc(0); BB *pred = emptyBB->GetPred(0); - DEBUG_LOG() << "Delete empty connecting : BB" << LOG_BBID(pred) << "->BB" << LOG_BBID(emptyBB) - << "(deleted)->BB" << LOG_BBID(succ) << "\n"; + DEBUG_LOG() << "Delete empty connecting : BB" << LOG_BBID(pred) << "->BB" << LOG_BBID(emptyBB) << "(deleted)->BB" + << LOG_BBID(succ) << "\n"; if (pred->IsPredBB(*succ)) { pred->RemoveSucc(*emptyBB, true); emptyBB->RemoveSucc(*succ, true); @@ -688,27 +687,33 @@ bool HasFallthruPred(const BB &bb) { class OptimizeBB { public: OptimizeBB(BB *bb, MeFunction &func, std::map>> *candidates) - : currBB(bb), f(func), cfg(func.GetCfg()), irmap(func.GetIRMap()), - irBuilder(func.GetMIRModule().GetMIRBuilder()), isMeIR(irmap != nullptr), cands(candidates) {} + : currBB(bb), + f(func), + cfg(func.GetCfg()), + irmap(func.GetIRMap()), + irBuilder(func.GetMIRModule().GetMIRBuilder()), + isMeIR(irmap != nullptr), + cands(candidates) {} // optimize each currBB until no change occur bool OptBBIteratively(); // initial factory to create corresponding optimizer for currBB according to BBKind. void InitBBOptFactory(); private: - BB *currBB = nullptr; // BB we currently perform optimization on - MeFunction &f; // function we currently perform optimization on - MeCFG *cfg = nullptr; // requiring cfg to find pattern to optimize current BB - MeIRMap *irmap = nullptr; // used to create new MeExpr/MeStmt - MIRBuilder *irBuilder = nullptr; // used to create new BaseNode(expr)/StmtNode + BB *currBB = nullptr; // BB we currently perform optimization on + MeFunction &f; // function we currently perform optimization on + MeCFG *cfg = nullptr; // requiring cfg to find pattern to optimize current BB + MeIRMap *irmap = nullptr; // used to create new MeExpr/MeStmt + MIRBuilder *irBuilder = nullptr; // used to create new BaseNode(expr)/StmtNode bool isMeIR = false; - std::map>> *cands = nullptr; // candidates ost need to be updated ssa - std::map> candsOstInBB; // bb with ost needed to be updated - - bool repeatOpt = false; // It will be always set false by OptBBIteratively. If there is some optimization - // opportunity for currBB after a/some optimization, we should set it true. - // Otherwise it will stop after all optimizations finished and continue to nextBB. - enum BBErrStat { + std::map>> *cands = nullptr; // candidates ost need to be updated ssa + std::map> candsOstInBB; // bb with ost needed to be updated + + bool repeatOpt = false; // It will be always set false by OptBBIteratively. If there is some optimization + // opportunity for currBB after a/some optimization, we should set it true. + // Otherwise it will stop after all optimizations finished and continue to nextBB. + enum BBErrStat + { kBBNoErr, // BB is normal kBBErrNull, // BB is nullptr kBBErrOOB, // BB id is out-of-bound @@ -792,23 +797,23 @@ class OptimizeBB { repeatOpt = false; } #define CHECK_CURR_BB() \ -if (!CheckCurrBB()) { \ - return false; \ -} + if (!CheckCurrBB()) { \ + return false; \ + } #define ONLY_FOR_MEIR() \ -if (!isMeIR) { \ - return false; \ -} + if (!isMeIR) { \ + return false; \ + } }; -using OptBBFatory = FunctionFactory; +using OptBBFatory = FunctionFactory; bool OptimizeBB::CheckCurrBB() { - if (bbErrStat != kBBNoErr) { // has been checked before + if (bbErrStat != kBBNoErr) { // has been checked before return false; } - if (currBB == nullptr) { + if (currBB == nullptr) { bbErrStat = kBBErrNull; return false; } @@ -832,9 +837,9 @@ bool OptimizeBB::CheckCurrBB() { void OptimizeBB::UpdateBBIdInSSACand(const BBId &oldBBID, const BBId &newBBID) { auto it = candsOstInBB.find(oldBBID); if (it == candsOstInBB.end()) { - return; // no item to update + return; // no item to update } - auto &ostSet = candsOstInBB[newBBID]; // find or create + auto &ostSet = candsOstInBB[newBBID]; // find or create ostSet.insert(it->second.begin(), it->second.end()); candsOstInBB.erase(it); for (auto &cand : *cands) { @@ -854,7 +859,7 @@ void OptimizeBB::UpdateSSACandForBBPhiList(BB *bb, const BB *newBB) { if (!isMeIR || bb == nullptr || bb->GetMePhiList().empty()) { return; } - if (newBB == nullptr) { // if not specified, newBB is bb itself + if (newBB == nullptr) { // if not specified, newBB is bb itself newBB = bb; } std::set &ostSet = candsOstInBB[newBB->GetBBId()]; @@ -942,18 +947,18 @@ bool OptimizeBB::BranchBB2UncondBB(BB &bb) { } } - DEBUG_LOG() << "BranchBB2UncondBB : " << (bb.GetKind() == kBBCondGoto ? "Conditional " : "Switch ") - << "BB" << LOG_BBID(&bb) << " to unconditional BB\n"; + DEBUG_LOG() << "BranchBB2UncondBB : " << (bb.GetKind() == kBBCondGoto ? "Conditional " : "Switch ") << "BB" + << LOG_BBID(&bb) << " to unconditional BB\n"; // delete all empty bb between bb and destBB // note : bb and destBB will be connected after empty BB is deleted for (int i = static_cast(bb.GetSucc().size()) - 1; i >= 0; --i) { EliminateEmptyConnectingBB(&bb, bb.GetSucc(static_cast(i)), destBB, *cfg); } - while (bb.GetSucc().size() != 1) { // bb is an unconditional bb now, and its successor num should be 1 + while (bb.GetSucc().size() != 1) { // bb is an unconditional bb now, and its successor num should be 1 ASSERT(bb.GetSucc().back() == destBB, "[FUNC: %s]Goto BB%d has different destination", funcName, LOG_BBID(&bb)); bb.RemoveSucc(*bb.GetSucc().back()); } - if (Options::profileUse && !bb.GetSuccFreq().empty()) { + if (cfg->UpdateCFGFreq()) { ASSERT(bb.GetSuccFreq().size() == bb.GetSucc().size(), "sanity check"); bb.SetSuccFreq(0, bb.GetFrequency()); } @@ -1009,30 +1014,32 @@ bool OptimizeBB::OptimizeCondBB2UnCond() { CHECK_FATAL(brStmt, "brStmt is nullptr!"); bool isCondTrue = (!condExpr->IsZero()); bool isBrtrue = (brStmt->GetOp() == OP_brtrue); - if (isCondTrue != isBrtrue) { // goto fallthru BB + if (isCondTrue != isBrtrue) { // goto fallthru BB currBB->RemoveLastMeStmt(); currBB->SetKind(kBBFallthru); - if (Options::profileUse && !currBB->GetSuccFreq().empty()) { + if (cfg->UpdateCFGFreq()) { removedSuccFreq = currBB->GetSuccFreq()[1]; } currBB->RemoveSucc(*gtBB, true); // update frequency - if (Options::profileUse && !currBB->GetSuccFreq().empty()) { + if (cfg->UpdateCFGFreq()) { currBB->SetSuccFreq(0, currBB->GetFrequency()); ftBB->SetFrequency(ftBB->GetFrequency() + removedSuccFreq); + ftBB->UpdateEdgeFreqs(false); } } else { MeStmt *gotoStmt = irmap->CreateGotoMeStmt(f.GetOrCreateBBLabel(*gtBB), currBB, &brStmt->GetSrcPosition()); currBB->ReplaceMeStmt(brStmt, gotoStmt); currBB->SetKind(kBBGoto); // update frequency - if (Options::profileUse && !currBB->GetSuccFreq().empty()) { + if (cfg->UpdateCFGFreq()) { removedSuccFreq = currBB->GetSuccFreq()[0]; } currBB->RemoveSucc(*ftBB, true); - if (Options::profileUse && !currBB->GetSuccFreq().empty()) { + if (cfg->UpdateCFGFreq()) { currBB->SetSuccFreq(0, currBB->GetFrequency()); gtBB->SetFrequency(gtBB->GetFrequency() + removedSuccFreq); + gtBB->UpdateEdgeFreqs(false); } } SetBBRunAgain(); @@ -1048,25 +1055,27 @@ bool OptimizeBB::OptimizeCondBB2UnCond() { if (isCondTrue != isBrTrue) { currBB->RemoveLastStmt(); currBB->SetKind(kBBFallthru); - if (Options::profileUse && !currBB->GetSuccFreq().empty()) { + if (cfg->UpdateCFGFreq()) { removedSuccFreq = currBB->GetSuccFreq()[1]; } currBB->RemoveSucc(*gtBB); - if (Options::profileUse && !currBB->GetSuccFreq().empty()) { + if (cfg->UpdateCFGFreq()) { currBB->SetSuccFreq(0, currBB->GetFrequency()); ftBB->SetFrequency(ftBB->GetFrequency() + removedSuccFreq); + ftBB->UpdateEdgeFreqs(false); } } else { StmtNode *gotoStmt = irBuilder->CreateStmtGoto(OP_goto, f.GetOrCreateBBLabel(*gtBB)); currBB->ReplaceStmt(&brStmt, gotoStmt); currBB->SetKind(kBBGoto); - if (Options::profileUse && !currBB->GetSuccFreq().empty()) { + if (cfg->UpdateCFGFreq()) { removedSuccFreq = currBB->GetSuccFreq()[0]; } currBB->RemoveSucc(*ftBB); - if (Options::profileUse && !currBB->GetSuccFreq().empty()) { + if (cfg->UpdateCFGFreq()) { currBB->SetSuccFreq(0, currBB->GetFrequency()); gtBB->SetFrequency(gtBB->GetFrequency() + removedSuccFreq); + gtBB->UpdateEdgeFreqs(false); } } SetBBRunAgain(); @@ -1149,11 +1158,15 @@ bool OptimizeBB::RemoveSuccFromNoReturnBB() { if (phiNode->GetOpnds().size() < 1) { break; } - phiNode->GetOpnds().push_back(phiNode->GetOpnd(0)); // to maintain opnd num and predNum + phiNode->GetOpnds().push_back(phiNode->GetOpnd(0)); // to maintain opnd num and predNum } } (void)EliminateRedundantPhiList(retBB); ResetBBRunAgain(); + // add edge Frequency to exitbb + if (cfg->UpdateCFGFreq()) { + currBB->PushBackSuccFreq(0); + } } return true; } @@ -1205,15 +1218,14 @@ BB *OptimizeBB::MergeSuccIntoPred(BB *pred, BB *succ) { } } // update succFreqs before update succs - if (Options::profileUse && f.GetMirFunc()->GetFuncProfData() && - !succ->GetSuccFreq().empty()) { + if (cfg->UpdateCFGFreq() && !succ->GetSuccFreq().empty()) { // copy succFreqs of succ to pred for (int i = 0; i < succ->GetSuccFreq().size(); i++) { pred->PushBackSuccFreq(succ->GetSuccFreq()[i]); } } succ->MoveAllSuccToPred(pred, cfg->GetCommonExitBB()); - pred->RemoveSucc(*succ, false); // philist will not be associated with pred BB, no need to update phi here. + pred->RemoveSucc(*succ, false); // philist will not be associated with pred BB, no need to update phi here. if (!isSuccEmpty) { // only when we move stmt from succ to pred should we set attr and kind here pred->SetAttributes(succ->GetAttributes()); @@ -1237,11 +1249,11 @@ BB *OptimizeBB::MergeSuccIntoPred(BB *pred, BB *succ) { // update bbid : tell ssa-updater to update with new BBID UpdateBBIdInSSACand(succ->GetBBId(), pred->GetBBId()); } - DEBUG_LOG() << "Merge BB" << LOG_BBID(succ) << " to BB" << LOG_BBID(pred) - << ", and delete BB" << LOG_BBID(succ) << "\n"; + DEBUG_LOG() << "Merge BB" << LOG_BBID(succ) << " to BB" << LOG_BBID(pred) << ", and delete BB" << LOG_BBID(succ) + << "\n"; UpdateSSACandForBBPhiList(succ, pred); DeleteBB(succ); - succ->SetBBId(pred->GetBBId()); // succ has been merged to pred, and reference to succ should be set to pred too. + succ->SetBBId(pred->GetBBId()); // succ has been merged to pred, and reference to succ should be set to pred too. return pred; } @@ -1284,13 +1296,13 @@ bool OptimizeBB::IsProfitableForCond2Sel(MeExpr *condExpr, MeExpr *trueExpr, MeE if (trueExpr == falseExpr) { return true; } - ASSERT(IsSafeExpr(trueExpr), "[FUNC: %s]Please check for safety first", funcName) ; - ASSERT(IsSafeExpr(falseExpr), "[FUNC: %s]Please check for safety first", funcName) ; + ASSERT(IsSafeExpr(trueExpr), "[FUNC: %s]Please check for safety first", funcName); + ASSERT(IsSafeExpr(falseExpr), "[FUNC: %s]Please check for safety first", funcName); // try to simplify select expr MeExpr *selExpr = irmap->CreateMeExprSelect(trueExpr->GetPrimType(), *condExpr, *trueExpr, *falseExpr); MeExpr *simplifiedSel = irmap->SimplifyMeExpr(selExpr); if (simplifiedSel != selExpr) { - return true; // can be simplified + return true; // can be simplified } // We can check for every opnd of opndExpr, and calculate their cost according to cg's insn @@ -1315,30 +1327,30 @@ bool OptimizeBB::IsProfitableForCond2Sel(MeExpr *condExpr, MeExpr *trueExpr, MeE return true; } - // Ignoring connecting BB, two cases can be turn into select - // condBB condBB - // / \ / \ +// Ignoring connecting BB, two cases can be turn into select +// condBB condBB +// / \ / \ // ftBB gtBB | gtBB/ftBB - // x<- x<- | x<- - // \ / \ / - // jointBB jointBB +// x<- x<- | x<- +// \ / \ / +// jointBB jointBB bool OptimizeBB::CondBranchToSelect() { CHECK_CURR_BB(); - BB *ftBB = FindFirstRealSucc(currBB->GetSucc(0)); // fallthruBB - BB *gtBB = FindFirstRealSucc(currBB->GetSucc(1)); // gotoBB + BB *ftBB = FindFirstRealSucc(currBB->GetSucc(0)); // fallthruBB + BB *gtBB = FindFirstRealSucc(currBB->GetSucc(1)); // gotoBB if (ftBB == gtBB) { (void)BranchBB2UncondBB(*currBB); return true; } // if ftBB or gtBB itself is jointBB, just return itself; otherwise return real succ - BB *ftTargetBB = (ftBB->GetPred().size() == 1 && ftBB->GetSucc().size() == 1) ? FindFirstRealSucc(ftBB->GetSucc(0)) - : ftBB; - BB *gtTargetBB = (gtBB->GetPred().size() == 1 && gtBB->GetSucc().size() == 1) ? FindFirstRealSucc(gtBB->GetSucc(0)) - : gtBB; + BB *ftTargetBB = + (ftBB->GetPred().size() == 1 && ftBB->GetSucc().size() == 1) ? FindFirstRealSucc(ftBB->GetSucc(0)) : ftBB; + BB *gtTargetBB = + (gtBB->GetPred().size() == 1 && gtBB->GetSucc().size() == 1) ? FindFirstRealSucc(gtBB->GetSucc(0)) : gtBB; if (ftTargetBB != gtTargetBB) { return false; } - BB *jointBB = ftTargetBB; // common succ + BB *jointBB = ftTargetBB; // common succ // Check if ftBB has only one assign stmt, set ftStmt if a assign stmt exist AssignMeStmt *ftStmt = nullptr; if (ftBB != jointBB) { @@ -1363,7 +1375,7 @@ bool OptimizeBB::CondBranchToSelect() { // Here we found a pattern, collect select opnds and result reg ScalarMeExpr *ftLHS = nullptr; MeExpr *ftRHS = nullptr; - std::set chiListCands; // collect chilist if assign stmt has one + std::set chiListCands; // collect chilist if assign stmt has one if (ftStmt != nullptr) { ftLHS = static_cast(ftStmt->GetLHS()); ftRHS = ftStmt->GetRHS(); @@ -1411,9 +1423,9 @@ bool OptimizeBB::CondBranchToSelect() { DEBUG_LOG() << "Abort cond2sel for BB" << LOG_BBID(currBB) << ", because two ost assigned are not the same\n"; return false; } - DEBUG_LOG() << "Candidate cond2sel BB" << LOG_BBID(currBB) << "(cond)->{BB" << LOG_BBID(currBB->GetSucc(0)) - << ", BB" << LOG_BBID(currBB->GetSucc(1)) << "}->BB" << LOG_BBID(ftTargetBB) << "(jointBB)\n"; - if (ftRHS != gtRHS) { // if ftRHS is the same as gtRHS, they can be simplified, and no need to check safety + DEBUG_LOG() << "Candidate cond2sel BB" << LOG_BBID(currBB) << "(cond)->{BB" << LOG_BBID(currBB->GetSucc(0)) << ", BB" + << LOG_BBID(currBB->GetSucc(1)) << "}->BB" << LOG_BBID(ftTargetBB) << "(jointBB)\n"; + if (ftRHS != gtRHS) { // if ftRHS is the same as gtRHS, they can be simplified, and no need to check safety // black list if (!IsSafeExpr(ftRHS) || !IsSafeExpr(gtRHS)) { DEBUG_LOG() << "Abort cond2sel for BB" << LOG_BBID(currBB) << ", because trueExpr or falseExpr is not safe\n"; @@ -1432,7 +1444,7 @@ bool OptimizeBB::CondBranchToSelect() { DEBUG_LOG() << "Condition To Select : BB" << LOG_BBID(currBB) << "(cond)->[BB" << LOG_BBID(ftBB) << "(ft), BB" << LOG_BBID(gtBB) << "(gt)]->BB" << LOG_BBID(jointBB) << "(joint)\n"; ScalarMeExpr *resLHS = nullptr; - if (jointBB->GetPred().size() == 2) { // if jointBB has only ftBB and gtBB as its pred. + if (jointBB->GetPred().size() == 2) { // if jointBB has only ftBB and gtBB as its pred. // use phinode lhs as result auto it = jointBB->GetMePhiList().find(ftLHS->GetOstIdx()); if (it == jointBB->GetMePhiList().end()) { @@ -1446,7 +1458,7 @@ bool OptimizeBB::CondBranchToSelect() { // It is profitable for instruction selection if select opnd is a compare expression // select condExpr, trueExpr, falseExpr => select cmpExpr, trueExpr, falseExpr if (condExpr->IsScalar() && condExpr->GetPrimType() != PTY_u1) { - auto *scalarExpr = static_cast(condExpr); + auto *scalarExpr = static_cast(condExpr); if (scalarExpr->GetDefBy() == kDefByStmt) { MeStmt *defStmt = scalarExpr->GetDefStmt(); MeExpr *rhs = defStmt->GetRHS(); @@ -1471,7 +1483,7 @@ bool OptimizeBB::CondBranchToSelect() { } (void)BranchBB2UncondBB(*currBB); // update phi - if (jointBB->GetPred().size() == 1) { // jointBB has only currBB as its pred + if (jointBB->GetPred().size() == 1) { // jointBB has only currBB as its pred // just remove phinode jointBB->GetMePhiList().erase(resLHS->GetOstIdx()); } else { @@ -1515,11 +1527,11 @@ bool IsExprSameLexicalally(MeExpr *expr1, MeExpr *expr2) { if (const1->GetKind() == kConstInt) { return static_cast(const1)->GetExtValue() == static_cast(const2)->GetExtValue(); } else if (const1->GetKind() == kConstFloatConst) { - return IsFloatingPointNumBitsSame(static_cast(const1)->GetValue(), - static_cast(const2)->GetValue()); + return IsFloatingPointNumBitsSame(static_cast(const1)->GetValue(), + static_cast(const2)->GetValue()); } else if (const1->GetKind() == kConstDoubleConst) { - return IsFloatingPointNumBitsSame(static_cast(const1)->GetValue(), - static_cast(const2)->GetValue()); + return IsFloatingPointNumBitsSame(static_cast(const1)->GetValue(), + static_cast(const2)->GetValue()); } return false; } @@ -1705,18 +1717,18 @@ bool OptimizeBB::SkipRedundantCond(BB &pred, BB &succ) { } MeExpr *predCond = predBr->GetOpnd(0); MeExpr *succCond = succBr->GetOpnd(0); - auto ptfSucc = GetTrueFalseBrPair(&pred); // pred true and false - auto stfSucc = GetTrueFalseBrPair(&succ); // succ true and false + auto ptfSucc = GetTrueFalseBrPair(&pred); // pred true and false + auto stfSucc = GetTrueFalseBrPair(&succ); // succ true and false // Try to infer result of succCond from predCond bool isPredTrueBrSucc = (FindFirstRealSucc(ptfSucc.first) == &succ); BranchResult tfBranch = InferSuccCondBrFromPredCond(predCond, succCond, isPredTrueBrSucc); - if (tfBranch == kBrUnknown) { // succCond cannot be inferred from predCond + if (tfBranch == kBrUnknown) { // succCond cannot be inferred from predCond return false; } // if succ's cond can be inferred from pred's cond, pred can skip succ and branches to newTarget directly BB *newTarget = (tfBranch == kBrTrue) ? FindFirstRealSucc(stfSucc.first) : FindFirstRealSucc(stfSucc.second); if (newTarget == nullptr || newTarget == &succ) { - return false; + return false; } DEBUG_LOG() << "Condition in BB" << LOG_BBID(&succ) << " is redundant, since it has been checked in BB" << LOG_BBID(&pred) << ", BB" << LOG_BBID(&pred) << " can branch to BB" << LOG_BBID(newTarget) << "\n"; @@ -1726,7 +1738,7 @@ bool OptimizeBB::SkipRedundantCond(BB &pred, BB &succ) { // succ ... // / \ // ftBB gtBB - if (succ.GetPred().size() == 1) { // succ has only one pred + if (succ.GetPred().size() == 1) { // succ has only one pred // if newTarget is succ's gotoBB, and it has fallthru pred, we should add a goto stmt to succ's last // to replace condGoto stmt. Otherwise, newTarget will have two fallthru pred if (newTarget == FindFirstRealSucc(succ.GetSucc(1)) && HasFallthruPred(*newTarget)) { @@ -1744,7 +1756,17 @@ bool OptimizeBB::SkipRedundantCond(BB &pred, BB &succ) { DEBUG_LOG() << "SkipRedundantCond : Remove condBr in BB" << LOG_BBID(&succ) << ", turn it to fallthruBB\n"; } BB *rmBB = (FindFirstRealSucc(succ.GetSucc(0)) == newTarget) ? succ.GetSucc(1) : succ.GetSucc(0); + int64_t deletedSuccFreq = 0; + if (cfg->UpdateCFGFreq()) { + int idx = succ.GetSuccIndex(*rmBB); + deletedSuccFreq = succ.GetSuccFreq()[idx]; + } succ.RemoveSucc(*rmBB, true); + if (cfg->UpdateCFGFreq()) { + succ.SetSuccFreq(0, succ.GetFrequency()); + auto *succofSucc = succ.GetSucc(0); + succofSucc->SetFrequency(succofSucc->GetFrequency() + deletedSuccFreq); + } DEBUG_LOG() << "Remove succ BB" << LOG_BBID(rmBB) << " of pred BB" << LOG_BBID(&succ) << "\n"; return true; } else { @@ -1782,18 +1804,19 @@ bool OptimizeBB::SkipRedundantCond(BB &pred, BB &succ) { BB *replacedSucc = isPredTrueBrSucc ? ptfSucc.first : ptfSucc.second; EliminateEmptyConnectingBB(&pred, replacedSucc, &succ, *cfg); ASSERT(pred.IsPredBB(succ), "[FUNC: %s]After eliminate connecting BB, pred must be predecessor of succ", funcName); - int predPredIdx = succ.GetPredIndex(pred); // before replace succ, record predidx for UpdatePhiForMovingPred - pred.ReplaceSucc(&succ, newBB, false); // do not update phi here, UpdatePhiForMovingPred will do it + int predPredIdx = succ.GetPredIndex(pred); // before replace succ, record predidx for UpdatePhiForMovingPred + pred.ReplaceSucc(&succ, newBB, false); // do not update phi here, UpdatePhiForMovingPred will do it DEBUG_LOG() << "Replace succ BB" << LOG_BBID(replacedSucc) << " with BB" << LOG_BBID(newBB) << ": BB" - << LOG_BBID(&pred) << "->...->BB" << LOG_BBID(&succ) << "(skipped)" << " => BB" << LOG_BBID(&pred) - << "->BB" << LOG_BBID(newBB) << "(new)->BB" << LOG_BBID(newTarget) << "\n"; + << LOG_BBID(&pred) << "->...->BB" << LOG_BBID(&succ) << "(skipped)" + << " => BB" << LOG_BBID(&pred) << "->BB" << LOG_BBID(newBB) << "(new)->BB" << LOG_BBID(newTarget) + << "\n"; if (pred.GetSucc(1) == newBB) { cfg->UpdateBranchTarget(pred, succ, *newBB, f); } newTarget->AddPred(*newBB); UpdatePhiForMovingPred(predPredIdx, newBB, &succ, newTarget); // update newBB frequency : copy predBB succFreq as newBB frequency - if (Options::profileUse && f.GetMirFunc()->GetFuncProfData()) { + if (cfg->UpdateCFGFreq()) { int idx = pred.GetSuccIndex(*newBB); ASSERT(idx >= 0 && idx < pred.GetSucc().size(), "sanity check"); uint64_t freq = pred.GetEdgeFreq(idx); @@ -1804,6 +1827,13 @@ bool OptimizeBB::SkipRedundantCond(BB &pred, BB &succ) { uint32_t freqOfSucc = succ.GetFrequency(); ASSERT(freqOfSucc >= freq, "sanity check"); succ.SetFrequency(freqOfSucc - freq); + // update edge frequency + BB *affectedBB = (tfBranch == kBrTrue) ? stfSucc.first : stfSucc.second; + idx = succ.GetSuccIndex(*affectedBB); + ASSERT(idx >= 0 && idx < succ.GetSucc().size(), "sanity check"); + int64_t oldedgeFreq = succ.GetSuccFreq()[idx]; + ASSERT(oldedgeFreq >= freq, "sanity check"); + succ.SetSuccFreq(idx, (oldedgeFreq - freq)); } return true; } @@ -1892,7 +1922,7 @@ void OptimizeBB::UpdatePhiForMovingPred(int predIdxForCurr, const BB *pred, BB * // create a new version for new phi phiMeNode->SetLHS(irmap->CreateRegOrVarMeExprVersion(ostIdx)); } - UpdateSSACandForBBPhiList(succ); // new philist has been created in succ + UpdateSSACandForBBPhiList(succ); // new philist has been created in succ } else { // succ has other pred besides curr for (auto &phi : succPhiList) { @@ -1922,7 +1952,7 @@ void OptimizeBB::UpdatePhiForMovingPred(int predIdxForCurr, const BB *pred, BB * } else { auto *phiMeNode = irmap->NewInPool(); phiMeNode->SetDefBB(succ); - resPair.first->second = phiMeNode; // replace nullptr inserted before + resPair.first->second = phiMeNode; // replace nullptr inserted before auto &phiOpnds = phiMeNode->GetOpnds(); // insert opnd into New phiNode : all phiOpnds (except for pred) are phiNode lhs in curr phiOpnds.insert(phiOpnds.end(), succ->GetPred().size(), phi.second->GetLHS()); @@ -1961,7 +1991,7 @@ bool OptimizeBB::MergeGotoBBToPred(BB *succ, BB *pred) { if (!HasOnlyMeGotoStmt(*succ)) { return false; } - BB *newTarget = succ->GetSucc(0); // succ must have only one succ, because it is uncondBB + BB *newTarget = succ->GetSucc(0); // succ must have only one succ, because it is uncondBB if (newTarget == succ) { // succ goto itself, no need to update goto target to newTarget return false; @@ -1973,8 +2003,8 @@ bool OptimizeBB::MergeGotoBBToPred(BB *succ, BB *pred) { // pred is moved to newTarget if (pred->GetKind() == kBBFallthru) { CHECK_FATAL(succ->GetLastMe(), "LastMe is nullptr!"); - GotoMeStmt *gotoMeStmt = irmap->CreateGotoMeStmt(newTarget->GetBBLabel(), pred, - &succ->GetLastMe()->GetSrcPosition()); + GotoMeStmt *gotoMeStmt = + irmap->CreateGotoMeStmt(newTarget->GetBBLabel(), pred, &succ->GetLastMe()->GetSrcPosition()); pred->AddMeStmtLast(gotoMeStmt); pred->SetKind(kBBGoto); DEBUG_LOG() << "Insert Uncond stmt to fallthru BB" << LOG_BBID(currBB) << ", and goto BB" << LOG_BBID(newTarget) @@ -1982,15 +2012,29 @@ bool OptimizeBB::MergeGotoBBToPred(BB *succ, BB *pred) { } int predIdx = succ->GetPredIndex(*pred); bool needUpdatePhi = false; + int64_t removedFreq = 0; + if (cfg->UpdateCFGFreq()) { + int idx = pred->GetSuccIndex(*succ); + removedFreq = pred->GetSuccFreq()[idx]; + } if (pred->IsPredBB(*newTarget)) { - pred->RemoveSucc(*succ, true); // one of pred's succ has been newTarget, avoid duplicate succ here + pred->RemoveSucc(*succ, true); // one of pred's succ has been newTarget, avoid duplicate succ here + if (cfg->UpdateCFGFreq()) { + int idx = pred->GetSuccIndex(*newTarget); + pred->SetSuccFreq(idx, pred->GetSuccFreq()[idx] + removedFreq); + } } else { - pred->ReplaceSucc(succ, newTarget); // phi opnd is not removed from currBB's philist, we will remove it later + pred->ReplaceSucc(succ, newTarget); // phi opnd is not removed from currBB's philist, we will remove it later needUpdatePhi = true; } - - DEBUG_LOG() << "Merge Uncond BB" << LOG_BBID(succ) << " to its pred BB" << LOG_BBID(pred) - << ": BB" << LOG_BBID(pred) << "->BB" << LOG_BBID(succ) << "(merged)->BB" << LOG_BBID(newTarget) << "\n"; + if (cfg->UpdateCFGFreq()) { + int64_t succFreq = succ->GetFrequency(); + ASSERT(succFreq >= removedFreq, "sanity check"); + succ->SetFrequency(succFreq - removedFreq); + succ->SetSuccFreq(0, succ->GetFrequency()); + } + DEBUG_LOG() << "Merge Uncond BB" << LOG_BBID(succ) << " to its pred BB" << LOG_BBID(pred) << ": BB" << LOG_BBID(pred) + << "->BB" << LOG_BBID(succ) << "(merged)->BB" << LOG_BBID(newTarget) << "\n"; cfg->UpdateBranchTarget(*pred, *succ, *newTarget, f); if (needUpdatePhi) { // remove phiOpnd in succ, and add phiOpnd to newTarget @@ -2032,7 +2076,7 @@ bool OptimizeBB::OptimizeUncondBB() { return false; } // wont exit BB and has an edge to commonExit, if we merge it to pred and delete it, the egde will be cut off - if (currBB->GetSucc().size() == 2) { // 2 succ : first is gotoTarget, second is edge to commonExit + if (currBB->GetSucc().size() == 2) { // 2 succ : first is gotoTarget, second is edge to commonExit ASSERT(currBB->GetAttributes(kBBAttrWontExit), "[FUNC: %s]GotoBB%d is not wontexitBB, but has two succ", funcName, LOG_BBID(currBB)); return false; @@ -2094,11 +2138,11 @@ bool OptimizeBB::OptimizeSwitchBB() { if (swStmt->GetOpnd()->GetMeOp() != kMeOpConst) { return false; } - auto *swConstExpr = static_cast(swStmt->GetOpnd()); + auto *swConstExpr = static_cast(swStmt->GetOpnd()); MIRConst *swConstVal = swConstExpr->GetConstVal(); ASSERT(swConstVal->GetKind() == kConstInt, "[FUNC: %s]switch is only legal for integer val", funcName); int64 val = static_cast(swConstVal)->GetExtValue(); - BB *survivor = currBB->GetSucc(0); // init as default BB + BB *survivor = currBB->GetSucc(0); // init as default BB for (size_t i = 0; i < swStmt->GetSwitchTable().size(); ++i) { int64 caseVal = swStmt->GetSwitchTable().at(i).first; if (caseVal == val) { @@ -2155,8 +2199,8 @@ MeExpr *OptimizeBB::CombineCondByOffset(const MeExpr &expr) { MeExpr *geConst = geExpr->GetOpnd(1); PrimType lePtyp = leConst->GetPrimType(); PrimType gePtyp = geConst->GetPrimType(); - if (leConst->GetOp() != OP_constval || geConst->GetOp() != OP_constval || - lePtyp != gePtyp || !IsPrimitiveInteger(lePtyp)) { // only allowed for integer, because float cannot wrap around + if (leConst->GetOp() != OP_constval || geConst->GetOp() != OP_constval || lePtyp != gePtyp || + !IsPrimitiveInteger(lePtyp)) { // only allowed for integer, because float cannot wrap around return nullptr; } int64 leVal = static_cast(static_cast(leConst)->GetConstVal())->GetExtValue(); @@ -2172,9 +2216,9 @@ MeExpr *OptimizeBB::CombineCondByOffset(const MeExpr &expr) { (IsPrimitiveUnsigned(lePtyp) && static_cast(leVal) > static_cast(newGeVal))) { // e.g. x < 3 || x > 2 <==> true return irmap->CreateIntConstMeExpr(1, PTY_u1); - } else if (leVal == newGeVal) { // e.g. x < 3 || x > 3 <==> x != 3 - return irmap->CreateMeExprCompare( - OP_ne, PTY_u1, opndPtyp, *sameExpr, *irmap->CreateIntConstMeExpr(newGeVal, lePtyp)); + } else if (leVal == newGeVal) { // e.g. x < 3 || x > 3 <==> x != 3 + return irmap->CreateMeExprCompare(OP_ne, PTY_u1, opndPtyp, *sameExpr, + *irmap->CreateIntConstMeExpr(newGeVal, lePtyp)); } // (x < val1 || x > val2) <==> ((unsigned)(x - val1) > (val2 - val1)) MeExpr *newLeConst = irmap->CreateIntConstMeExpr(leVal, opndPtyp); @@ -2253,15 +2297,15 @@ bool OptimizeBB::FoldBranchToCommonDest(BB *pred, BB *succ) { return false; } if (!IsProfitableToMergeCond(predCond, succCond)) { - DEBUG_LOG() << "Abort Merging Two CondBB : Condition in successor BB" - << LOG_BBID(succ) << " is not simple enough and not profitable\n"; + DEBUG_LOG() << "Abort Merging Two CondBB : Condition in successor BB" << LOG_BBID(succ) + << " is not simple enough and not profitable\n"; return false; } // Start trying to merge two condition together if possible - auto ptfBrPair = GetTrueFalseBrPair(pred); // pred's true and false branches - auto stfBrPair = GetTrueFalseBrPair(succ); // succ's true and false branches + auto ptfBrPair = GetTrueFalseBrPair(pred); // pred's true and false branches + auto stfBrPair = GetTrueFalseBrPair(succ); // succ's true and false branches Opcode combinedCondOp = OP_undef; - bool invertSuccCond = false; // invert second condition, e.g. (cond1 && !cond2) + bool invertSuccCond = false; // invert second condition, e.g. (cond1 && !cond2) // all cases are listed as follow: // | case | predBB -> common | succBB -> common | invertSuccCond | or/and | // | ---- | ---------------- | ---------------- | -------------- | ------ | @@ -2273,16 +2317,16 @@ bool OptimizeBB::FoldBranchToCommonDest(BB *pred, BB *succ) { // pred's false branch to succ, so true branch to common bool isPredTrueToCommon = (FindFirstRealSucc(ptfBrPair.second) == succ); bool isSuccTrueToCommon = (FindFirstRealSucc(stfBrPair.first) == commonBB); - if (isPredTrueToCommon && isSuccTrueToCommon) { // case 1 + if (isPredTrueToCommon && isSuccTrueToCommon) { // case 1 invertSuccCond = false; combinedCondOp = OP_lior; - } else if (!isPredTrueToCommon && !isSuccTrueToCommon) { // case 2 + } else if (!isPredTrueToCommon && !isSuccTrueToCommon) { // case 2 invertSuccCond = false; combinedCondOp = OP_land; - } else if (isPredTrueToCommon && !isSuccTrueToCommon) { // case 3 + } else if (isPredTrueToCommon && !isSuccTrueToCommon) { // case 3 invertSuccCond = true; combinedCondOp = OP_lior; - } else if (!isPredTrueToCommon && isSuccTrueToCommon) { // case 4 + } else if (!isPredTrueToCommon && isSuccTrueToCommon) { // case 4 invertSuccCond = true; combinedCondOp = OP_land; } else { @@ -2309,7 +2353,7 @@ bool OptimizeBB::FoldBranchToCommonDest(BB *pred, BB *succ) { // remove succ and update cfg BB *exitBB = isSuccTrueToCommon ? stfBrPair.second : stfBrPair.first; pred->ReplaceSucc(succ, exitBB); - exitBB->RemovePred(*succ, false); // not update phi here, because its phi opnd is the same as before. + exitBB->RemovePred(*succ, false); // not update phi here, because its phi opnd is the same as before. // we should eliminate edge from succ to commonBB BB *toEliminateBB = isSuccTrueToCommon ? stfBrPair.first : stfBrPair.second; EliminateEmptyConnectingBB(succ, toEliminateBB, commonBB /* stop here */, *cfg); @@ -2352,6 +2396,11 @@ bool OptimizeBB::FoldBranchToCommonDest() { bool OptimizeBB::OptBBOnce() { CHECK_CURR_BB(); DEBUG_LOG() << "Try to optimize BB" << LOG_BBID(currBB) << "...\n"; + // bb frequency may be updated, make bb frequency and succs frequency consistent + // skip deadBB + if (cfg->UpdateCFGFreq() && (!currBB->GetPred().empty()) && (currBB->GetUniquePred() != currBB)) { + currBB->UpdateEdgeFreqs(false); + } bool everChanged = false; // eliminate dead BB : // 1.BB has no pred(expect then entry block) @@ -2414,7 +2463,7 @@ class OptimizeFuntionCFG { private: MeFunction &f; - std::map>> *cands = nullptr; // candidates ost need to update ssa + std::map>> *cands = nullptr; // candidates ost need to update ssa bool OptimizeFuncCFGIteratively(); bool OptimizeCFGForBB(BB *currBB); }; @@ -2437,10 +2486,6 @@ bool OptimizeFuntionCFG::OptimizeFuncCFGIteratively() { if (currBB == nullptr) { continue; } - // bb frequency may be updated, make bb frequency and succs frequency consistent - if (Options::profileUse && !currBB->GetSuccFreq().empty()) { - currBB->UpdateEdgeFreqs(); - } changed |= OptimizeCFGForBB(currBB); } everChanged |= changed; @@ -2486,15 +2531,14 @@ bool OptimizeMeFuncCFG(maple::MeFunction &f, std::mapValidBBNum(); // optimization entry - bool change = OptimizeFuntionCFG(f, ssaCand) - .OptimizeOnFunc(); + bool change = OptimizeFuntionCFG(f, ssaCand).OptimizeOnFunc(); if (change) { f.GetCfg()->WontExitAnalysis(); if (debug) { uint32 bbNumAfter = f.GetCfg()->ValidBBNum(); if (bbNumBefore != bbNumAfter) { - DEBUG_LOG() << "BBs' number " << (bbNumBefore > bbNumAfter ? "reduce" : "increase") - << " from " << bbNumBefore << " to " << bbNumAfter << "\n"; + DEBUG_LOG() << "BBs' number " << (bbNumBefore > bbNumAfter ? "reduce" : "increase") << " from " << bbNumBefore + << " to " << bbNumAfter << "\n"; } else { DEBUG_LOG() << "BBs' number keep the same as before (num = " << bbNumAfter << ")\n"; } @@ -2515,6 +2559,9 @@ bool MEOptimizeCFGNoSSA::PhaseRun(MeFunction &f) { debug = DEBUGFUNC_NEWPM(f); phaseName = PhaseName(); bool change = OptimizeMeFuncCFG(f, nullptr); + if (change && f.GetCfg()->DumpIRProfileFile()) { + f.GetCfg()->DumpToFile("after-OptimizeCFGNOSSA", false, f.GetCfg()->UpdateCFGFreq()); + } return change; } @@ -2540,7 +2587,10 @@ bool MEOptimizeCFG::PhaseRun(maple::MeFunction &f) { MeSSAUpdate ssaUpdate(f, *f.GetMeSSATab(), *dom, cands); ssaUpdate.Run(); } + if (f.GetCfg()->DumpIRProfileFile()) { + f.GetCfg()->DumpToFile("after-OptimizeCFG", false, f.GetCfg()->UpdateCFGFreq()); + } } return change; } -} // namespace maple +} // namespace maple diff --git a/src/mapleall/maple_util/include/mpl_profdata.h b/src/mapleall/maple_util/include/mpl_profdata.h index 6aa8c1520f..6f9f1b3a1d 100644 --- a/src/mapleall/maple_util/include/mpl_profdata.h +++ b/src/mapleall/maple_util/include/mpl_profdata.h @@ -15,10 +15,11 @@ #ifndef MAPLE_UTIL_INCLUDE_MPL_PROFDATA_H #define MAPLE_UTIL_INCLUDE_MPL_PROFDATA_H -#include "mempool_allocator.h" #include #include +#include "mempool_allocator.h" + namespace maple { #define HOTCALLSITEFREQ 100 enum UpdateFreqOp { @@ -31,23 +32,27 @@ enum UpdateFreqOp { // used for record cumulative datas struct ProfileSummaryHistogram { + uint32_t countRatio; uint32_t startValue; // count value range in [startValue, nextHistogramStart) uint32_t countNums; // Number of counters whose profile count falls in countValue range. uint64_t countMinVal; // Smallest profile count included in this range. uint64_t countCumValue; // Cumulative value of the profile counts - ProfileSummaryHistogram(uint32_t s, uint32_t num, uint64_t mincount, uint64_t cumcounts) : - startValue(s), countNums(num), countMinVal(mincount), countCumValue(cumcounts) { - } + ProfileSummaryHistogram(uint32_t s, uint32_t num, uint64_t mincount, uint64_t cumcounts) + : countRatio(0), startValue(s), countNums(num), countMinVal(mincount), countCumValue(cumcounts) {} }; class ProfileSummary { -public: - ProfileSummary(MapleAllocator* alloc) : histogram(alloc->Adapter()) {} - ProfileSummary(MapleAllocator *alloc, uint64_t checksum, uint32_t runtimes, - uint32_t totalcount, uint64_t maxcount, uint64_t sumcount) : - checkSum(checksum), run(runtimes), totalCount(totalcount), maxCount(maxcount), sumCount(sumcount), - histogram(alloc->Adapter()) {} + public: + ProfileSummary(MapleAllocator *alloc) : histogram(alloc->Adapter()) {} + ProfileSummary(MapleAllocator *alloc, uint64_t checksum, uint32_t runtimes, uint32_t totalcount, uint64_t maxcount, + uint64_t sumcount) + : checkSum(checksum), + run(runtimes), + totalCount(totalcount), + maxCount(maxcount), + sumCount(sumcount), + histogram(alloc->Adapter()) {} void SetSummary(uint64_t checksum, uint32_t runtimes, uint32_t totalcount, uint64_t maxcount, uint64_t sumcount) { checkSum = checksum; @@ -60,44 +65,70 @@ public: histogram.push_back(ProfileSummaryHistogram(s, num, mincount, cumcounts)); } void DumpSummary(); - uint64_t GetCheckSum() { return checkSum; } - uint32_t GetRun() { return run; } - uint32_t GetTotalCount() { return totalCount; } - uint64_t GetMaxCount() { return maxCount; } - uint64_t GetSumCount() { return sumCount; } - uint32_t GetHistogramLength() { return histogram.size(); } - MapleVector& GetHistogram() { return histogram; } - -private: - uint64_t checkSum; // checksum value of module - uint32_t run; // run times - uint32_t totalCount; // number of counters - uint64_t maxCount; // max counter value in single run - uint64_t sumCount; // sum of all counters accumulated. - MapleVector histogram; // record gcov_bucket_type histogram[GCOV_HISTOGRAM_SIZE]; + uint64_t GetCheckSum() { + return checkSum; + } + uint32_t GetRun() { + return run; + } + uint32_t GetTotalCount() { + return totalCount; + } + uint64_t GetMaxCount() { + return maxCount; + } + uint64_t GetSumCount() { + return sumCount; + } + uint32_t GetHistogramLength() { + return histogram.size(); + } + void ProcessHistogram(); + MapleVector &GetHistogram() { + return histogram; + } + + private: + uint64_t checkSum; // checksum value of module + uint32_t run; // run times + uint32_t totalCount; // number of counters + uint64_t maxCount; // max counter value in single run + uint64_t sumCount; // sum of all counters accumulated. + MapleVector histogram; // record gcov_bucket_type histogram[GCOV_HISTOGRAM_SIZE]; }; class FuncProfInfo { public: - FuncProfInfo(MapleAllocator* alloc, unsigned funcIdent, unsigned lineno_cs, - unsigned cfg_cs, unsigned countnum = 0) : ident(funcIdent), linenoChecksum(lineno_cs), - cfgChecksum(cfg_cs), edgeCounts(countnum), counts(alloc->Adapter()) {}; + FuncProfInfo(MapleAllocator *alloc, unsigned funcIdent, unsigned lineno_cs, unsigned cfg_cs, unsigned countnum = 0) + : ident(funcIdent), + linenoChecksum(lineno_cs), + cfgChecksum(cfg_cs), + edgeCounts(countnum), + counts(alloc->Adapter()){}; ~FuncProfInfo() = default; - uint64_t GetFuncFrequency() const { return entry_freq; } - void SetFuncFrequency(uint64_t freq) { entry_freq = freq; } + uint64_t GetFuncFrequency() const { + return entry_freq; + } + void SetFuncFrequency(uint64_t freq) { + entry_freq = freq; + } - uint64_t GetFuncRealFrequency() const { return real_entryfreq; } - void SetFuncRealFrequency(uint64_t freq) { real_entryfreq = freq; } + uint64_t GetFuncRealFrequency() const { + return real_entryfreq; + } + void SetFuncRealFrequency(uint64_t freq) { + real_entryfreq = freq; + } - std::unordered_map& GetStmtFreqs() { + std::unordered_map &GetStmtFreqs() { return stmtFreqs; } uint64_t GetStmtFreq(uint32_t stmtID) { if (stmtFreqs.count(stmtID) > 0) { return stmtFreqs[stmtID]; } - return -1; // unstored + return -1; // unstored } void SetStmtFreq(uint32_t stmtID, uint64_t freq) { stmtFreqs[stmtID] = freq; @@ -129,9 +160,9 @@ class FuncProfInfo { // Raw arc coverage counts. unsigned edgeCounts; MapleVector counts; - uint64_t entry_freq; // record entry bb frequence - std::unordered_map stmtFreqs; // stmt_id is key, counter value - uint64_t real_entryfreq; // function prof data may be modified after clone/inline + uint64_t entry_freq; // record entry bb frequence + std::unordered_map stmtFreqs; // stmt_id is key, counter value + uint64_t real_entryfreq; // function prof data may be modified after clone/inline }; class MplProfileData { @@ -140,7 +171,7 @@ class MplProfileData { FuncProfInfo *GetFuncProfile(unsigned puidx) { if (funcsCounter.count(puidx) > 0) { - return funcsCounter[puidx]; + return funcsCounter[puidx]; } return nullptr; } @@ -156,12 +187,18 @@ class MplProfileData { } void DumpProfileData(); void DumpFunctionsProfile(); - MapleUnorderedMap funcsCounter; // use puidx as key + bool IsHotCallSite(uint64_t freq); + + MapleUnorderedMap funcsCounter; // use puidx as key // record module profile information and statistics of count information ProfileSummary summary; -private: + uint64_t hotCountThreshold = 0; + + private: + uint64_t GetHotThreshold(); + MemPool *mp; MapleAllocator *alloc; }; -} // end namespace -#endif // MAPLE_UTIL_INCLUDE_MPL_PROFDATA_H +} // namespace maple +#endif // MAPLE_UTIL_INCLUDE_MPL_PROFDATA_H diff --git a/src/mapleall/maple_util/src/mpl_profdata.cpp b/src/mapleall/maple_util/src/mpl_profdata.cpp index 64e37ed9c0..16ef9da267 100644 --- a/src/mapleall/maple_util/src/mpl_profdata.cpp +++ b/src/mapleall/maple_util/src/mpl_profdata.cpp @@ -13,26 +13,29 @@ * See the Mulan PSL v2 for more details. */ #include "mpl_profdata.h" + #include "mpl_logging.h" +#include "option.h" + namespace maple { void ProfileSummary::DumpSummary() { LogInfo::MapleLogger() << "---------ProfileSummary-------------- \n"; LogInfo::MapleLogger() << " checkSum: " << std::hex << "0x" << checkSum << "\n"; - LogInfo::MapleLogger() << " runtimes: " << std::dec << run << "\n"; - LogInfo::MapleLogger() << " totalCounts: " << std::dec << totalCount << "\n"; + LogInfo::MapleLogger() << " runtimes: " << std::dec << run << "\n"; + LogInfo::MapleLogger() << " totalCounts: " << std::dec << totalCount << "\n"; LogInfo::MapleLogger() << " maxCount: " << std::dec << maxCount << "\n"; LogInfo::MapleLogger() << " count histogram: countRange countNum minCount cumCount \n"; for (auto &it : histogram) { - LogInfo::MapleLogger() <<" " << std::dec << it.startValue << "\t"; - LogInfo::MapleLogger() << std::dec << it. countNums<< "\t" << it.countMinVal << "\t" << it.countCumValue << "\n"; + LogInfo::MapleLogger() << " " << std::dec << it.startValue << "\t"; + LogInfo::MapleLogger() << std::dec << it.countNums << "\t" << it.countMinVal << "\t" << it.countCumValue << "\n"; } } void FuncProfInfo::DumpFunctionProfile() { LogInfo::MapleLogger() << "function ident " << std::dec << ident; LogInfo::MapleLogger() << " lino_checksum 0x" << std::hex << linenoChecksum << ", "; - LogInfo::MapleLogger() << " cfg_checksum 0x" << std::hex << cfgChecksum << "\n"; - LogInfo::MapleLogger() << " num_counts " << std::dec << edgeCounts << " : "; + LogInfo::MapleLogger() << " cfg_checksum 0x" << std::hex << cfgChecksum << "\n"; + LogInfo::MapleLogger() << " num_counts " << std::dec << edgeCounts << " : "; for (int i = 0; i < edgeCounts; i++) { LogInfo::MapleLogger() << std::dec << " " << counts[i]; } @@ -50,4 +53,48 @@ void MplProfileData::DumpProfileData() { summary.DumpSummary(); DumpFunctionsProfile(); } -} // endof namespace + +void ProfileSummary::ProcessHistogram() { + int countsum = 0; + int n = histogram.size(); + for (int i = n - 1; i >= 0; i--) { + countsum += histogram[i].countNums; + histogram[i].countRatio = ((float)(countsum) / (float)totalCount) * 100; + } +} + +#define HOTRATIO 90 +uint64_t MplProfileData::GetHotThreshold() { + for (auto &it : summary.GetHistogram()) { + if (it.countRatio >= HOTRATIO) { + hotCountThreshold = it.startValue; + } else { + if (hotCountThreshold == 0) { + hotCountThreshold = it.countMinVal; // set minValue in currentRange which satisfy hot ratio + } + return hotCountThreshold; + } + } + // should not be here + return 100; +} + +bool MplProfileData::IsHotCallSite(uint64_t freq) { + auto &h = summary.GetHistogram(); + if (hotCountThreshold == 0) { + if (Options::profileHotCountSeted) { + hotCountThreshold = Options::profileHotCount; + } else if (summary.GetTotalCount() > 0 && !h.empty() && h[0].countRatio == 0) { + // init countRatio and compute hotCountThreshold + summary.ProcessHistogram(); + hotCountThreshold = GetHotThreshold(); + } else if (h.empty()) { + // should not be here + ASSERT(0, "should not be here"); + hotCountThreshold = 1; + } + } + return freq >= hotCountThreshold; +} + +} // namespace maple diff --git a/src/mapleall/mpl2mpl/include/inline_transformer.h b/src/mapleall/mpl2mpl/include/inline_transformer.h index 1569f9b900..78137411b9 100644 --- a/src/mapleall/mpl2mpl/include/inline_transformer.h +++ b/src/mapleall/mpl2mpl/include/inline_transformer.h @@ -55,9 +55,8 @@ class InlineTransformer { callee(callee), callStmt(callStmt), dumpDetail(dumpDetail), - cg(cg) { - updateFreq = (Options::profileUse && caller.GetFuncProfData() && callee.GetFuncProfData()); - }; + cg(cg), + updateFreq(Options::profileUse && caller.GetFuncProfData() && callee.GetFuncProfData()){}; bool PerformInline(BlockNode &enclosingBlk); static void ReplaceSymbols(BaseNode*, uint32, const std::vector*); diff --git a/src/mapleall/mpl2mpl/src/call_graph.cpp b/src/mapleall/mpl2mpl/src/call_graph.cpp index ba629b6b56..cf25cc58b5 100644 --- a/src/mapleall/mpl2mpl/src/call_graph.cpp +++ b/src/mapleall/mpl2mpl/src/call_graph.cpp @@ -14,7 +14,6 @@ */ #include "call_graph.h" - #include "option.h" #include "retype.h" #include "string_utils.h" @@ -201,7 +200,7 @@ uint64_t CGNode::GetCallsiteFrequency(const StmtNode *callstmt) const { uint64_t CGNode::GetFuncFrequency() const { FuncProfInfo *funcInfo = mirFunc->GetFuncProfData(); if (funcInfo) { - return funcInfo->GetFuncFrequency(); + return funcInfo->GetFuncRealFrequency(); } ASSERT(0, "should not be here"); return 0; @@ -256,8 +255,8 @@ void CallGraph::DelNode(CGNode &node) { } } -CallGraph::CallGraph(MIRModule &m, MemPool &memPool, MemPool &templPool, - const KlassHierarchy &kh, const std::string &fn) +CallGraph::CallGraph(MIRModule &m, MemPool &memPool, MemPool &templPool, const KlassHierarchy &kh, + const std::string &fn) : AnalysisResult(&memPool), mirModule(&m), cgAlloc(&memPool), @@ -523,7 +522,7 @@ void CallGraph::RecordLocalConstValue(const StmtNode *stmt) { CallNode *CallGraph::ReplaceIcallToCall(BlockNode &body, IcallNode *icall, PUIdx newPUIdx) { MapleVector opnds(icall->GetNopnd().begin() + 1, icall->GetNopnd().end(), - CurFunction()->GetCodeMPAllocator().Adapter()); + CurFunction()->GetCodeMPAllocator().Adapter()); CallNode *newCall = nullptr; if (icall->GetOpCode() == OP_icall) { newCall = mirBuilder->CreateStmtCall(newPUIdx, opnds, OP_call); @@ -746,8 +745,8 @@ void CallGraph::HandleICall(BlockNode &body, CGNode &node, StmtNode *stmt, uint3 icallToFix.insert({funcType->GetTypeIndex(), tempSet}); } CHECK_FATAL(CurFunction()->GetPuidx() == node.GetPuIdx(), "Error"); - Callsite callSite = { callInfo, node.GetCallee().at(callInfo) }; - icallToFix.at(funcType->GetTypeIndex())->insert({ node.GetPuIdx(), callSite }); + Callsite callSite = {callInfo, node.GetCallee().at(callInfo)}; + icallToFix.at(funcType->GetTypeIndex())->insert({node.GetPuIdx(), callSite}); } void CallGraph::HandleBody(MIRFunction &func, BlockNode &body, CGNode &node, uint32 loopDepth) { @@ -1232,7 +1231,7 @@ void DoDevirtual(const Klass &klass, const KlassHierarchy &klassh) { Opcode op = stmt->GetOpCode(); switch (op) { case OP_comment: - CASE_OP_ASSERT_NONNULL + CASE_OP_ASSERT_NONNULL case OP_brtrue: case OP_brfalse: case OP_try: @@ -1501,7 +1500,7 @@ void DoDevirtual(const Klass &klass, const KlassHierarchy &klassh) { } } } - [[clang::fallthrough]]; + [[clang::fallthrough]]; case OP_call: case OP_callassigned: { CallNode *callNode = static_cast(stmt); @@ -1556,8 +1555,9 @@ void IPODevirtulize::DevirtualFinal() { if (GlobalTables::GetGsymTable().GetSymbolFromStrIdx(classType->GetStaticFieldsGStrIdx(i)) == nullptr) { continue; } - TyIdx tyIdx = GlobalTables::GetGsymTable().GetSymbolFromStrIdx( - classType->GetStaticFieldsPair(i).first)->GetInferredTyIdx(); + TyIdx tyIdx = GlobalTables::GetGsymTable() + .GetSymbolFromStrIdx(classType->GetStaticFieldsPair(i).first) + ->GetInferredTyIdx(); if (tyIdx != kInitTyIdx && tyIdx != kNoneTyIdx) { CHECK_FATAL(attribute.GetAttr(FLDATTR_final), "Must be final private"); if (debugFlag) { @@ -1743,10 +1743,10 @@ void CallGraph::RemoveFileStaticRootNodes() { [](const CGNode *root) { // root means no caller, we should also make sure that root is not be used in addroffunc auto mirFunc = root->GetMIRFunction(); - return root != nullptr && mirFunc != nullptr && // remove before - // if static functions or inline but not extern modified functions are not used anymore, - // they can be removed safely. - !root->IsAddrTaken() && (mirFunc->IsStatic() || (mirFunc->IsInline() && !mirFunc->IsExtern())); + return root != nullptr && mirFunc != nullptr && // remove before + // if static functions or inline but not extern modified functions are not used anymore, + // they can be removed safely. + !root->IsAddrTaken() && (mirFunc->IsStatic() || (mirFunc->IsInline() && !mirFunc->IsExtern())); }); for (auto *root : staticRoots) { // DFS delete root and its callee that is static and have no caller after root is deleted diff --git a/src/mapleall/mpl2mpl/src/inline.cpp b/src/mapleall/mpl2mpl/src/inline.cpp index 4b7543ee76..c5812daff9 100644 --- a/src/mapleall/mpl2mpl/src/inline.cpp +++ b/src/mapleall/mpl2mpl/src/inline.cpp @@ -117,7 +117,7 @@ void MInline::InitRCWhiteList() { void MInline::InitExcludedCaller() { std::set specialfunc = { - std::string("Landroid_2Fcontent_2Fpm_2FFallbackCategoryProvider_3B_7CloadFallbacks_7C_28_29V"), + std::string("Landroid_2Fcontent_2Fpm_2FFallbackCategoryProvider_3B_7CloadFallbacks_7C_28_29V"), }; for (auto it = specialfunc.begin(); it != specialfunc.end(); ++it) { GStrIdx strIdx = GlobalTables::GetStrTable().GetStrIdxFromName(*it); @@ -140,27 +140,40 @@ void MInline::InitExcludedCallee() { (void)excludedCallee.insert(strIdx); } std::set setArrayHotFunc = { - std::string("Landroid_2Ficu_2Fimpl_2Fduration_2FBasicDurationFormat_3B_7CformatDuration_7C_28Ljava_2Flang_2FObject_3B_29Ljava_2Flang_2FString_3B"), - std::string("Landroid_2Fapp_2FIActivityManager_24Stub_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_3BLandroid_2Fos_2FParcel_3BI_29Z"), - std::string("Landroid_2Fcontent_2Fpm_2FIPackageManager_24Stub_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_3BLandroid_2Fos_2FParcel_3BI_29Z"), - std::string("Landroid_2Fcontent_2FIContentService_24Stub_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_3BLandroid_2Fos_2FParcel_3BI_29Z"), - std::string("Lcom_2Fandroid_2Fserver_2Fam_2FHwActivityManagerService_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_3BLandroid_2Fos_2FParcel_3BI_29Z"), - std::string("Lcom_2Fandroid_2Fserver_2Fam_2FActivityManagerService_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_3BLandroid_2Fos_2FParcel_3BI_29Z"), - std::string("Ljava_2Flang_2Freflect_2FMethod_3B_7Cinvoke_7C_28Ljava_2Flang_2FObject_3BALjava_2Flang_2FObject_3B_29Ljava_2Flang_2FObject_3B"), + std::string("Landroid_2Ficu_2Fimpl_2Fduration_2FBasicDurationFormat_3B_7CformatDuration_7C_28Ljava_2Flang_" + "2FObject_3B_29Ljava_2Flang_2FString_3B"), + std::string("Landroid_2Fapp_2FIActivityManager_24Stub_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_3BLandroid_" + "2Fos_2FParcel_3BI_29Z"), + std::string("Landroid_2Fcontent_2Fpm_2FIPackageManager_24Stub_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_" + "3BLandroid_2Fos_2FParcel_3BI_29Z"), + std::string("Landroid_2Fcontent_2FIContentService_24Stub_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_3BLandroid_" + "2Fos_2FParcel_3BI_29Z"), + std::string("Lcom_2Fandroid_2Fserver_2Fam_2FHwActivityManagerService_3B_7ConTransact_7C_28ILandroid_2Fos_" + "2FParcel_3BLandroid_2Fos_2FParcel_3BI_29Z"), + std::string("Lcom_2Fandroid_2Fserver_2Fam_2FActivityManagerService_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_" + "3BLandroid_2Fos_2FParcel_3BI_29Z"), + std::string("Ljava_2Flang_2Freflect_2FMethod_3B_7Cinvoke_7C_28Ljava_2Flang_2FObject_3BALjava_2Flang_2FObject_3B_" + "29Ljava_2Flang_2FObject_3B"), std::string("Lcom_2Fandroid_2Fserver_2FSystemServer_3B_7Crun_7C_28_29V"), - std::string("Lcom_2Fandroid_2Finternal_2Ftelephony_2FIPhoneStateListener_24Stub_24Proxy_3B_7ConMessageWaitingIndicatorChanged_7C_28Z_29V"), + std::string("Lcom_2Fandroid_2Finternal_2Ftelephony_2FIPhoneStateListener_24Stub_24Proxy_3B_" + "7ConMessageWaitingIndicatorChanged_7C_28Z_29V"), std::string("Landroid_2Fview_2Fanimation_2FTransformation_3B_7C_3Cinit_3E_7C_28_29V"), std::string("Lcom_2Fandroid_2Fserver_2FSystemServer_3B_7CstartOtherServices_7C_28_29V"), std::string("Lcom_2Fandroid_2Fserver_2Fpm_2FSettings_3B_7CreadLPw_7C_28Ljava_2Futil_2FList_3B_29Z"), std::string("Lcom_2Fandroid_2Fserver_2Fam_2FActivityManagerService_3B_7CupdateOomAdjLocked_7C_28_29V"), - std::string("Lcom_2Fandroid_2Fserver_2Fpm_2FHwPackageManagerService_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_3BLandroid_2Fos_2FParcel_3BI_29Z"), - std::string("Lcom_2Fandroid_2Fserver_2Fpm_2FPackageManagerService_3B_7CgeneratePackageInfo_7C_28Lcom_2Fandroid_2Fserver_2Fpm_2FPackageSetting_3BII_29Landroid_2Fcontent_2Fpm_2FPackageInfo_3B"), - std::string("Ljava_2Flang_2FThrowable_3B_7CprintStackTrace_7C_28Ljava_2Flang_2FThrowable_24PrintStreamOrWriter_3B_29V"), + std::string("Lcom_2Fandroid_2Fserver_2Fpm_2FHwPackageManagerService_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_" + "3BLandroid_2Fos_2FParcel_3BI_29Z"), + std::string("Lcom_2Fandroid_2Fserver_2Fpm_2FPackageManagerService_3B_7CgeneratePackageInfo_7C_28Lcom_2Fandroid_" + "2Fserver_2Fpm_2FPackageSetting_3BII_29Landroid_2Fcontent_2Fpm_2FPackageInfo_3B"), + std::string( + "Ljava_2Flang_2FThrowable_3B_7CprintStackTrace_7C_28Ljava_2Flang_2FThrowable_24PrintStreamOrWriter_3B_29V"), std::string("Lcom_2Fandroid_2Fserver_2FSystemServer_3B_7CstartBootstrapServices_7C_28_29V"), std::string("Ljava_2Flang_2FThrowable_3B_7CgetOurStackTrace_7C_28_29ALjava_2Flang_2FStackTraceElement_3B"), std::string("Ldalvik_2Fsystem_2FVMStack_3B_7CgetStackClass2_7C_28_29Ljava_2Flang_2FClass_3B"), - std::string("Lcom_2Fandroid_2Fserver_2Fam_2FActivityManagerService_3B_7CattachApplicationLocked_7C_28Landroid_2Fapp_2FIApplicationThread_3BI_29Z"), - std::string("Lcom_2Fandroid_2Fserver_2FInputMethodManagerService_3B_7ChideCurrentInputLocked_7C_28ILandroid_2Fos_2FResultReceiver_3B_29Z"), + std::string("Lcom_2Fandroid_2Fserver_2Fam_2FActivityManagerService_3B_7CattachApplicationLocked_7C_28Landroid_" + "2Fapp_2FIApplicationThread_3BI_29Z"), + std::string("Lcom_2Fandroid_2Fserver_2FInputMethodManagerService_3B_7ChideCurrentInputLocked_7C_28ILandroid_2Fos_" + "2FResultReceiver_3B_29Z"), }; for (auto it = setArrayHotFunc.begin(); it != setArrayHotFunc.end(); ++it) { GStrIdx strIdx = GlobalTables::GetStrTable().GetStrIdxFromName(*it); @@ -251,7 +264,7 @@ FuncCostResultType MInline::GetFuncCost(const MIRFunction &func, const BaseNode break; } } - [[clang::fallthrough]]; + [[clang::fallthrough]]; case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_customcall: @@ -423,15 +436,17 @@ bool MInline::IsHotCallSite(const MIRFunction &caller, const MIRFunction &callee } // use maple instrument profile if (Options::profileUse) { - return caller.GetFuncProfData()->IsHotCallSite(callStmt.GetStmtID()); + if (!caller.GetFuncProfData()) return false; + int64_t freq = caller.GetFuncProfData()->GetStmtFreq(callStmt.GetStmtID()); + ASSERT(freq > 0, "sanity check"); + return module.GetMapleProfile()->IsHotCallSite((uint64_t)freq); } return module.GetProfile().CheckFuncHot(caller.GetName()); } bool MInline::FuncInlinable(const MIRFunction &func) const { std::string name = func.GetName(); - if (StringUtils::StartsWith(name, kReflectionClassStr) || - StringUtils::StartsWith(name, kJavaLangClassesStr) || + if (StringUtils::StartsWith(name, kReflectionClassStr) || StringUtils::StartsWith(name, kJavaLangClassesStr) || StringUtils::StartsWith(name, kJavaLangReferenceStr)) { return false; } @@ -686,7 +701,7 @@ static InlineResult GetInlineResult(uint32 threshold, uint32 thresholdType, uint } void MInline::AdjustInlineThreshold(const MIRFunction &caller, const MIRFunction &callee, const CallNode &callStmt, - uint32 &threshold, uint32 &thresholdType) { + uint32 &threshold, uint32 &thresholdType) { // Update threshold if this callsite is hot, or dealing with recursive function if (inlineWithProfile && IsHotCallSite(caller, callee, callStmt)) { threshold = hotFuncThreshold; @@ -705,9 +720,7 @@ void MInline::AdjustInlineThreshold(const MIRFunction &caller, const MIRFunction threshold <<= kRelaxThresholdForInlineHint; } // We don't always inline called_once callee to avoid super big caller - if (module.GetSrcLang() == kSrcLangC && - callee.GetAttr(FUNCATTR_called_once) && - callee.GetAttr(FUNCATTR_static)) { + if (module.GetSrcLang() == kSrcLangC && callee.GetAttr(FUNCATTR_called_once) && callee.GetAttr(FUNCATTR_static)) { threshold <<= kRelaxThresholdForCalledOnce; } } diff --git a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp index de5c758b74..ef050a798f 100644 --- a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp +++ b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp @@ -13,22 +13,26 @@ * See the Mulan PSL v2 for more details. */ -#include -#include -#include +#include "mpl_profdata_parser.h" + #include +#include #include +#include +#include +#include + #include #include -#include #include -#include "option.h" + #include "mpl_logging.h" -#include "mpl_profdata_parser.h" +#include "option.h" namespace maple { -template T ProfDataBinaryImportBase::ReadNum() { +template +T ProfDataBinaryImportBase::ReadNum() { unsigned NumBytesRead = 0; uint64_t Val = namemangler::DecodeULEB128(pos, &NumBytesRead); @@ -40,7 +44,7 @@ int ProfileSummaryImport::ReadSummary(MplProfileData *profData) { CHECK_FATAL(profData != nullptr, "sanity check"); uint64_t magicNum = ReadNum(); if (magicNum != kMapleProfDataMagicNumber) { - LogInfo::MapleLogger() << "magic number error, quit\n"; + LogInfo::MapleLogger() << "magic number error, quit\n"; return 1; } uint64_t checksum = ReadNum(); @@ -85,7 +89,7 @@ int FunctionProfileImport::ReadFuncProfile(MplProfileData *profData) { int MplProfDataParser::ReadMapleProfileData() { std::string mprofDataFile = Options::profile; if (mprofDataFile.empty()) { - if (const char* env_p = std::getenv("GCOV_PREFIX")) { + if (const char *env_p = std::getenv("GCOV_PREFIX")) { mprofDataFile.append(env_p); } else { mprofDataFile.append("."); @@ -105,18 +109,18 @@ int MplProfDataParser::ReadMapleProfileData() { return 1; } // get length of file - inputStream.seekg (0, inputStream.end); + inputStream.seekg(0, inputStream.end); int length = inputStream.tellg(); - inputStream.seekg (0, inputStream.beg); - const uint32_t sizeThreshold = 1024*10; + inputStream.seekg(0, inputStream.beg); + const uint32_t sizeThreshold = 1024 * 10; CHECK_FATAL(length <= sizeThreshold, "NYI::large .mprofdata file size is larger than threashold, do chunk memory\n"); std::unique_ptr buffer(new char[sizeof(char) * length]()); - inputStream.read (buffer.get(), length); + inputStream.read(buffer.get(), length); inputStream.close(); // read 1st part summary ProfileSummaryImport summaryImport(mprofDataFile, inputStream); - summaryImport.SetPosition((uint8_t *)buffer.get()); + summaryImport.SetPosition((uint8_t*)buffer.get()); int res = summaryImport.ReadSummary(profData); if (res) { LogInfo::MapleLogger() << "no summary part\n"; @@ -144,9 +148,9 @@ void MMplProfDataParser::GetAnalysisDependence(AnalysisDep &aDep) const { } bool MMplProfDataParser::PhaseRun(maple::MIRModule &m) { - - MemPool *memPool = m.GetMemPool(); // use global pool to store profile data - MplProfDataParser parser(m, memPool, true/*debug*/); + MemPool *memPool = m.GetMemPool(); // use global pool to store profile data + bool enableDebug = false; + MplProfDataParser parser(m, memPool, enableDebug); int res = parser.ReadMapleProfileData(); if (res) { // something wrong @@ -158,5 +162,4 @@ bool MMplProfDataParser::PhaseRun(maple::MIRModule &m) { return true; } - -} // end namespace maple +} // end namespace maple -- Gitee From b3227e77d2e5020c4d0cfe3bb406b84f51d67e53 Mon Sep 17 00:00:00 2001 From: linma Date: Fri, 29 Jul 2022 07:38:14 -0700 Subject: [PATCH 07/16] pgo: refine profiledata name and locations --- src/mapleall/maple_ir/include/mir_module.h | 11 +++-- src/mapleall/maple_ir/src/mir_nodes.cpp | 21 ++++---- .../mpl2mpl/src/mpl_profdata_parser.cpp | 48 ++++++++++++++++--- 3 files changed, 61 insertions(+), 19 deletions(-) diff --git a/src/mapleall/maple_ir/include/mir_module.h b/src/mapleall/maple_ir/include/mir_module.h index be748df3f5..f5965f008d 100644 --- a/src/mapleall/maple_ir/include/mir_module.h +++ b/src/mapleall/maple_ir/include/mir_module.h @@ -341,10 +341,13 @@ class MIRModule { } std::string GetProfileDataFileName() const { - std::string profileDataFileName = fileName.substr(0, fileName.find_last_of(".")); - std::replace(profileDataFileName.begin(), profileDataFileName.end(), '.', '_'); - std::replace(profileDataFileName.begin(), profileDataFileName.end(), '-', '_'); - std::replace(profileDataFileName.begin(), profileDataFileName.end(), '/', '_'); + std::string profileDataFileName = GetFileName().substr(0, GetFileName().find_last_of(".")); + char *gcov_path = std::getenv("GCOV_PREFIX"); + std::string gcov_prefix = gcov_path ? gcov_path : ""; + if (!gcov_prefix.empty() && (gcov_prefix.back() != '/')) { + gcov_prefix.append("/"); + } + profileDataFileName = gcov_prefix + profileDataFileName; return profileDataFileName; } diff --git a/src/mapleall/maple_ir/src/mir_nodes.cpp b/src/mapleall/maple_ir/src/mir_nodes.cpp index 579be730c5..d1204d70b2 100644 --- a/src/mapleall/maple_ir/src/mir_nodes.cpp +++ b/src/mapleall/maple_ir/src/mir_nodes.cpp @@ -686,10 +686,11 @@ void AddroflabelNode::Dump(int32 indent [[maybe_unused]]) const { void StmtNode::DumpBase(int32 indent) const { srcPosition.DumpLoc(lastPrintedLineNum, lastPrintedColumnNum); // 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"; + if (Options::profileUse && theMIRModule->CurFunction()->GetFuncProfData()) { + int64_t freq = static_cast(theMIRModule->CurFunction()->GetFuncProfData()->GetStmtFreq(GetStmtID())); + if (freq >= 0) { + LogInfo::MapleLogger() << "stmtID " << GetStmtID() << " freq " << freq << "\n"; + } } PrintIndentation(indent); LogInfo::MapleLogger() << kOpcodeInfo.GetTableItemAt(GetOpCode()).name; @@ -1323,8 +1324,10 @@ void BlockNode::Dump(int32 indent, const MIRSymbolTable *theSymTab, MIRPregTable srcPosition.DumpLoc(lastPrintedLineNum, lastPrintedColumnNum); // dump stmtFreqs if (Options::profileUse && theMIRModule->CurFunction()->GetFuncProfData()) { - LogInfo::MapleLogger() << "stmtID " << GetStmtID() << " freq " << - theMIRModule->CurFunction()->GetFuncProfData()->GetStmtFreq(GetStmtID()) << "\n"; + int64_t freq = static_cast(theMIRModule->CurFunction()->GetFuncProfData()->GetStmtFreq(GetStmtID())); + if (freq >= 0) { + LogInfo::MapleLogger() << "stmtID " << GetStmtID() << " freq " << freq << "\n"; + } } for (auto &stmt : GetStmtNodes()) { stmt.Dump(indent + 1); @@ -1339,8 +1342,10 @@ void LabelNode::Dump(int32 indent [[maybe_unused]]) const { } // dump stmtFreqs if (Options::profileUse && theMIRModule->CurFunction()->GetFuncProfData()) { - LogInfo::MapleLogger() << "stmtID " << GetStmtID() << " freq " << - theMIRModule->CurFunction()->GetFuncProfData()->GetStmtFreq(GetStmtID()) << "\n"; + int64_t freq = static_cast(theMIRModule->CurFunction()->GetFuncProfData()->GetStmtFreq(GetStmtID())); + if (freq >= 0) { + LogInfo::MapleLogger() << "stmtID " << GetStmtID() << " freq " << freq << "\n"; + } } LogInfo::MapleLogger() << "@" << theMIRModule->CurFunction()->GetLabelName(labelIdx) << " "; } diff --git a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp index ef050a798f..4d686e42ee 100644 --- a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp +++ b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp @@ -89,17 +89,51 @@ int FunctionProfileImport::ReadFuncProfile(MplProfileData *profData) { int MplProfDataParser::ReadMapleProfileData() { std::string mprofDataFile = Options::profile; if (mprofDataFile.empty()) { - if (const char *env_p = std::getenv("GCOV_PREFIX")) { - mprofDataFile.append(env_p); + if (const char *env_gcovprefix = std::getenv("GCOV_PREFIX")) { + mprofDataFile.append(env_gcovprefix); + if (mprofDataFile.back() != '/') { + mprofDataFile.append("/"); + } + if (dumpDetail) { + LogInfo::MapleLogger() << "set env gcov_prefix= " << mprofDataFile << std::endl; + } + uint32_t stripnum = 0; + if (const char *env_gcovprefixstrip = std::getenv("GCOV_PREFIX_STRIP")) { + std::string strip(env_gcovprefixstrip); + stripnum = std::stoi(strip); + if (dumpDetail) { + LogInfo::MapleLogger() << "set env gcov_prefix_strip=" << strip << std::endl; + } + } + std::string profDataFileName = m.GetProfileDataFileName(); + if (dumpDetail) { + LogInfo::MapleLogger() << "module profdata Name: " << profDataFileName << std::endl; + } + // reduce path in profDataFileName + while (stripnum > 0 && profDataFileName.size() > 1) { + auto pos = profDataFileName.find_first_of("/", 1); + profDataFileName = profDataFileName.substr(pos); + stripnum--; + } + if (dumpDetail) { + LogInfo::MapleLogger() << "after strip, module profdata Name: " << profDataFileName << std::endl; + } + CHECK_FATAL(profDataFileName.size() > 0, "sanity check"); + mprofDataFile.append(profDataFileName); } else { - mprofDataFile.append("."); + // if gcov_prefix is not set, find .mprofdata according to m.profiledata + mprofDataFile = m.GetProfileDataFileName(); + if (dumpDetail) { + LogInfo::MapleLogger() << "NO ENV, module profdata Name: " << mprofDataFile << std::endl; + } } - mprofDataFile.append("/"); - mprofDataFile.append(m.GetProfileDataFileName()); + // add .mprofdata mprofDataFile.append(namemangler::kMplProfFileNameExt); } ASSERT(!mprofDataFile.empty(), "null check"); - + if (dumpDetail) { + LogInfo::MapleLogger() << "will open mprofileData " << mprofDataFile << std::endl; + } // create mpl profdata profData = mempool->New(mempool, &alloc); // read .mprofdata @@ -149,7 +183,7 @@ void MMplProfDataParser::GetAnalysisDependence(AnalysisDep &aDep) const { bool MMplProfDataParser::PhaseRun(maple::MIRModule &m) { MemPool *memPool = m.GetMemPool(); // use global pool to store profile data - bool enableDebug = false; + bool enableDebug = false; // true to dump trace MplProfDataParser parser(m, memPool, enableDebug); int res = parser.ReadMapleProfileData(); if (res) { -- Gitee From 52b3a6fcc357b5877faac3bd2de19aed565aebaa Mon Sep 17 00:00:00 2001 From: linma Date: Fri, 29 Jul 2022 07:43:04 -0700 Subject: [PATCH 08/16] missed file --- src/mapleall/mpl2mpl/src/gen_profile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mapleall/mpl2mpl/src/gen_profile.cpp b/src/mapleall/mpl2mpl/src/gen_profile.cpp index b586d91474..cff72a9561 100644 --- a/src/mapleall/mpl2mpl/src/gen_profile.cpp +++ b/src/mapleall/mpl2mpl/src/gen_profile.cpp @@ -106,7 +106,7 @@ void ProfileGen::CreateModProfDesc() { // Make the profile file name as fileName.gcda std::string profFileName = mod.GetProfileDataFileName() + namemangler::kProfFileNameExt; auto *profileFNMirConst = - modMP->New("./" + profFileName, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(PTY_a64))); + modMP->New(profFileName, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(PTY_a64))); modProfDescSymMirConst->AddItem(profileFNMirConst, 6); // Additional profiling (in addition to frequency profiling) should be added here -- Gitee From 7853a10b57ecb02c3df77ff0845a3b63423c22ba Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Sat, 30 Jul 2022 22:10:08 -0700 Subject: [PATCH 09/16] Fixed the formatting issues --- src/mapleall/maple_me/src/me_cfg.cpp | 4 +- src/mapleall/maple_me/src/me_emit.cpp | 2 +- .../maple_me/src/me_loop_inversion.cpp | 35 +++-- src/mapleall/maple_me/src/pme_emit.cpp | 2 +- .../maple_util/include/mpl_profdata.h | 29 ++--- src/mapleall/maple_util/include/namemangler.h | 4 +- src/mapleall/maple_util/src/mpl_profdata.cpp | 2 +- src/mapleall/maple_util/src/namemangler.cpp | 121 +++++++++--------- .../mpl2mpl/include/mpl_profdata_parser.h | 7 +- .../mpl2mpl/src/mpl_profdata_parser.cpp | 45 ++++--- 10 files changed, 136 insertions(+), 115 deletions(-) diff --git a/src/mapleall/maple_me/src/me_cfg.cpp b/src/mapleall/maple_me/src/me_cfg.cpp index 4f6d20be4c..9a50e46c2f 100644 --- a/src/mapleall/maple_me/src/me_cfg.cpp +++ b/src/mapleall/maple_me/src/me_cfg.cpp @@ -1932,8 +1932,8 @@ void MeCFG::ConstructStmtFreq() { for (auto bIt = valid_begin(); bIt != eIt; ++bIt) { auto *bb = *bIt; if (bIt == common_entry()) { - funcData->entry_freq = bb->GetFrequency(); - funcData->real_entryfreq = funcData->entry_freq; + funcData->entryFreq = bb->GetFrequency(); + funcData->realEntryfreq = funcData->entryFreq; } for (auto &stmt : bb->GetStmtNodes()) { Opcode op = stmt.GetOpCode(); diff --git a/src/mapleall/maple_me/src/me_emit.cpp b/src/mapleall/maple_me/src/me_emit.cpp index 00e6f26cfe..7d308d2884 100644 --- a/src/mapleall/maple_me/src/me_emit.cpp +++ b/src/mapleall/maple_me/src/me_emit.cpp @@ -81,7 +81,7 @@ bool MEEmit::PhaseRun(maple::MeFunction &f) { mirFunction->SetBody(mirFunction->GetCodeMempool()->New()); if (Options::profileUse && mirFunction->GetFuncProfData()) { mirFunction->GetFuncProfData()->SetStmtFreq(mirFunction->GetBody()->GetStmtID(), - mirFunction->GetFuncProfData()->entry_freq); + mirFunction->GetFuncProfData()->entryFreq); } // initialize is_deleted field to true; will reset when emitting Maple IR for (size_t k = 1; k < mirFunction->GetSymTab()->GetSymbolTableSize(); ++k) { diff --git a/src/mapleall/maple_me/src/me_loop_inversion.cpp b/src/mapleall/maple_me/src/me_loop_inversion.cpp index 8da6423c2a..d3f9505fed 100644 --- a/src/mapleall/maple_me/src/me_loop_inversion.cpp +++ b/src/mapleall/maple_me/src/me_loop_inversion.cpp @@ -199,27 +199,38 @@ void MeLoopInversion::Convert(MeFunction &func, BB &bb, BB &pred, MapleMapGetKind() == kBBCondGoto) { BB *succInloop = swapSuccOfLatch ? bb.GetSucc(0) : bb.GetSucc(1); if ((latchBB->GetFrequency() != 0) && (succInloop->GetFrequency() > 0)) { - // loop is executed, bb->fallthru is in loopbody + // loop is executed int64_t latchFreq = latchBB->GetFrequency(); if (swapSuccOfLatch) { // bb fallthru is in loop, frequency of bb -> exitbb is set 0 - bb.SetSuccFreq(0, bb.GetFrequency()); - bb.SetSuccFreq(1, 0); // latchBB fallthru is loop exit - ASSERT(bb.GetSucc(0)->GetFrequency() >= bb.GetFrequency(), "sanity check"); int fallthrudiff = bb.GetSucc(0)->GetFrequency() - bb.GetFrequency(); - ASSERT(fallthrudiff >= 0, "sanity check"); - latchBB->PushBackSuccFreq(latchFreq - fallthrudiff); - latchBB->PushBackSuccFreq(fallthrudiff); + if (fallthrudiff >= 0) { + bb.SetSuccFreq(0, bb.GetFrequency()); + bb.SetSuccFreq(1, 0); + latchBB->PushBackSuccFreq(latchFreq - fallthrudiff); + latchBB->PushBackSuccFreq(fallthrudiff); + } else { // assume loop body executed only once + bb.SetSuccFreq(0, bb.GetSucc(0)->GetFrequency()); + bb.SetSuccFreq(1, bb.GetFrequency() - bb.GetSucc(0)->GetFrequency()); + latchBB->PushBackSuccFreq(latchBB->GetFrequency()); + latchBB->PushBackSuccFreq(0); + } } else { // bb->fallthru is loop exit, edge frequency of bb ->exitbb is set 0 - bb.SetSuccFreq(0, 0); - bb.SetSuccFreq(1, bb.GetFrequency()); // latchBB fallthru is in loop int fallthrudiff = bb.GetSucc(1)->GetFrequency() - bb.GetFrequency(); - ASSERT(fallthrudiff >= 0, "sanity check"); - latchBB->PushBackSuccFreq(fallthrudiff); - latchBB->PushBackSuccFreq(latchFreq - fallthrudiff); + if (fallthrudiff >= 0) { + bb.SetSuccFreq(1, bb.GetFrequency()); + bb.SetSuccFreq(0, 0); + latchBB->PushBackSuccFreq(latchFreq - fallthrudiff); + latchBB->PushBackSuccFreq(fallthrudiff); + } else { + bb.SetSuccFreq(1, bb.GetSucc(0)->GetFrequency()); + bb.SetSuccFreq(0, bb.GetFrequency() - bb.GetSucc(0)->GetFrequency()); + latchBB->PushBackSuccFreq(0); + latchBB->PushBackSuccFreq(latchBB->GetFrequency()); + } } } else { // loop is not executed diff --git a/src/mapleall/maple_me/src/pme_emit.cpp b/src/mapleall/maple_me/src/pme_emit.cpp index c3e80bb0fe..eed1401611 100644 --- a/src/mapleall/maple_me/src/pme_emit.cpp +++ b/src/mapleall/maple_me/src/pme_emit.cpp @@ -1097,7 +1097,7 @@ bool MEPreMeEmission::PhaseRun(MeFunction &f) { mirfunction->SetBody(curblk); // restore bb frequency to stmt if (Options::profileUse && emitter->GetFuncProfData()) { - emitter->GetFuncProfData()->SetStmtFreq(curblk->GetStmtID(), emitter->GetFuncProfData()->entry_freq); + emitter->GetFuncProfData()->SetStmtFreq(curblk->GetStmtID(), emitter->GetFuncProfData()->entryFreq); } uint32 i = 0; while (i < f.GetCfg()->GetAllBBs().size()) { diff --git a/src/mapleall/maple_util/include/mpl_profdata.h b/src/mapleall/maple_util/include/mpl_profdata.h index 6f9f1b3a1d..23cf6f99b9 100644 --- a/src/mapleall/maple_util/include/mpl_profdata.h +++ b/src/mapleall/maple_util/include/mpl_profdata.h @@ -15,13 +15,12 @@ #ifndef MAPLE_UTIL_INCLUDE_MPL_PROFDATA_H #define MAPLE_UTIL_INCLUDE_MPL_PROFDATA_H -#include #include - +#include #include "mempool_allocator.h" namespace maple { -#define HOTCALLSITEFREQ 100 +constexpr uint32_t HOTCALLSITEFREQ = 100; enum UpdateFreqOp { kKeepOrigFreq = 0, kUpdateOrigFreq = 0x1, @@ -44,7 +43,7 @@ struct ProfileSummaryHistogram { class ProfileSummary { public: - ProfileSummary(MapleAllocator *alloc) : histogram(alloc->Adapter()) {} + explicit ProfileSummary(MapleAllocator *alloc) : histogram(alloc->Adapter()) {} ProfileSummary(MapleAllocator *alloc, uint64_t checksum, uint32_t runtimes, uint32_t totalcount, uint64_t maxcount, uint64_t sumcount) : checkSum(checksum), @@ -99,26 +98,26 @@ class ProfileSummary { class FuncProfInfo { public: - FuncProfInfo(MapleAllocator *alloc, unsigned funcIdent, unsigned lineno_cs, unsigned cfg_cs, unsigned countnum = 0) + FuncProfInfo(MapleAllocator *alloc, unsigned funcIdent, unsigned linenoCs, unsigned cfgCs, unsigned countnum = 0) : ident(funcIdent), - linenoChecksum(lineno_cs), - cfgChecksum(cfg_cs), + linenoChecksum(linenoCs), + cfgChecksum(cfgCs), edgeCounts(countnum), counts(alloc->Adapter()){}; ~FuncProfInfo() = default; uint64_t GetFuncFrequency() const { - return entry_freq; + return entryFreq; } void SetFuncFrequency(uint64_t freq) { - entry_freq = freq; + entryFreq = freq; } uint64_t GetFuncRealFrequency() const { - return real_entryfreq; + return realEntryfreq; } void SetFuncRealFrequency(uint64_t freq) { - real_entryfreq = freq; + realEntryfreq = freq; } std::unordered_map &GetStmtFreqs() { @@ -160,9 +159,9 @@ class FuncProfInfo { // Raw arc coverage counts. unsigned edgeCounts; MapleVector counts; - uint64_t entry_freq; // record entry bb frequence + uint64_t entryFreq; // record entry bb frequence std::unordered_map stmtFreqs; // stmt_id is key, counter value - uint64_t real_entryfreq; // function prof data may be modified after clone/inline + uint64_t realEntryfreq; // function prof data may be modified after clone/inline }; class MplProfileData { @@ -175,8 +174,8 @@ class MplProfileData { } return nullptr; } - FuncProfInfo *AddNewFuncProfile(unsigned puidx, unsigned lino_cs, unsigned cfg_cs, unsigned countnum) { - FuncProfInfo *funcProf = mp->New(alloc, puidx, lino_cs, cfg_cs, countnum); + FuncProfInfo *AddNewFuncProfile(unsigned puidx, unsigned linoCs, unsigned cfgCs, unsigned countnum) { + FuncProfInfo *funcProf = mp->New(alloc, puidx, linoCs, cfgCs, countnum); ASSERT(funcsCounter.count(puidx) == 0, "sanity check"); funcsCounter[puidx] = funcProf; return funcProf; diff --git a/src/mapleall/maple_util/include/namemangler.h b/src/mapleall/maple_util/include/namemangler.h index c1b21573fe..c3333b16cf 100644 --- a/src/mapleall/maple_util/include/namemangler.h +++ b/src/mapleall/maple_util/include/namemangler.h @@ -213,8 +213,8 @@ uint32_t GetUnsignedLeb128Decode(const uint8_t **data); size_t GetUleb128Size(uint64_t val); size_t GetSleb128Size(int32_t val); bool NeedConvertUTF16(const std::string &str8); -uint32_t EncodeSLEB128(int64_t Value, std::ofstream &out); -uint32_t EncodeULEB128(uint64_t Value, std::ofstream &out); +uint32_t EncodeSLEB128(int64_t value, std::ofstream &out); +uint32_t EncodeULEB128(uint64_t value, std::ofstream &out); uint64_t DecodeULEB128(const uint8_t *p, unsigned *n = nullptr, const uint8_t *end = nullptr); int64_t DecodeSLEB128(const uint8_t *p, unsigned *n = nullptr, const uint8_t *end = nullptr); } // namespace namemangler diff --git a/src/mapleall/maple_util/src/mpl_profdata.cpp b/src/mapleall/maple_util/src/mpl_profdata.cpp index 16ef9da267..849b262239 100644 --- a/src/mapleall/maple_util/src/mpl_profdata.cpp +++ b/src/mapleall/maple_util/src/mpl_profdata.cpp @@ -36,7 +36,7 @@ void FuncProfInfo::DumpFunctionProfile() { LogInfo::MapleLogger() << " lino_checksum 0x" << std::hex << linenoChecksum << ", "; LogInfo::MapleLogger() << " cfg_checksum 0x" << std::hex << cfgChecksum << "\n"; LogInfo::MapleLogger() << " num_counts " << std::dec << edgeCounts << " : "; - for (int i = 0; i < edgeCounts; i++) { + for (unsigned i = 0; i < edgeCounts; i++) { LogInfo::MapleLogger() << std::dec << " " << counts[i]; } LogInfo::MapleLogger() << "\n"; diff --git a/src/mapleall/maple_util/src/namemangler.cpp b/src/mapleall/maple_util/src/namemangler.cpp index 151a97f371..cf84882c83 100644 --- a/src/mapleall/maple_util/src/namemangler.cpp +++ b/src/mapleall/maple_util/src/namemangler.cpp @@ -585,7 +585,7 @@ size_t GetSleb128Size(int32_t v) { int end = ((v >= 0) ? 0 : -1); while (hasMore) { - // judege whether has More valid rem + // judege whether has more valid rem hasMore = (rem != end) || ((static_cast(rem) & 1) != (static_cast((static_cast(v) >> 6)) & 1)); size++; @@ -596,93 +596,100 @@ size_t GetSleb128Size(int32_t v) { } // encode signed to output stream -uint32_t EncodeSLEB128(int64_t Value, std::ofstream &out) { - bool More; - uint32_t Count = 0; +uint32_t EncodeSLEB128(int64_t value, std::ofstream &out) { + bool more; + uint32_t count = 0; do { - uint8_t Byte = Value & 0x7f; + uint8_t byte = value & 0x7f; // NOTE: this assumes that this signed shift is an arithmetic right shift. - Value >>= 7; - More = !((((Value == 0 ) && ((Byte & 0x40) == 0)) || - ((Value == -1) && ((Byte & 0x40) != 0)))); - Count++; - if (More) { - Byte |= 0x80; // Mark this byte to show that more bytes will follow. + value >>= kGreybackOffset; + more = !((((value == 0) && ((byte & 0x40) == 0)) || + ((value == -1) && ((byte & 0x40) != 0)))); + count++; + if (more) { + byte |= 0x80; // Mark this byte to show that more bytes will follow. } - out << (char)(Byte); - } while (More); - return Count; + out << static_cast(byte); + } while (more); + return count; } -uint32_t EncodeULEB128(uint64_t Value, std::ofstream &out) { - uint32_t Count = 0; +uint32_t EncodeULEB128(uint64_t value, std::ofstream &out) { + uint32_t count = 0; do { - uint8_t Byte = Value & 0x7f; - Value >>= 7; - Count++; - if (Value != 0) { - Byte |= 0x80; // Mark this byte to show that more bytes will follow. + uint8_t byte = value & 0x7f; + value >>= kGreybackOffset; + count++; + if (value != 0) { + byte |= 0x80; // Mark this byte to show that more bytes will follow. } - out << char(Byte); - } while (Value != 0); - return Count; + out << char(byte); + } while (value != 0); + return count; } // decode a ULEB128 value. uint64_t DecodeULEB128(const uint8_t *p, unsigned *n, const uint8_t *end) { const uint8_t *orig_p = p; - uint64_t Value = 0; - unsigned Shift = 0; + uint64_t value = 0; + unsigned shift = 0; do { if (p == end) { - if (n) - *n = (unsigned)(p - orig_p); + if (n) { + *n = static_cast(p - orig_p); + } return 0; } - uint64_t Slice = *p & 0x7f; - if ((Shift >= 64 && Slice != 0) || Slice << Shift >> Shift != Slice) { - if (n) - *n = (unsigned)(p - orig_p); + uint64_t slice = *p & 0x7f; + if ((shift >= 64 && slice != 0) || ((slice << shift) >> shift) != slice) { + if (n) { + *n = static_cast(p - orig_p); + } return 0; } - Value += Slice << Shift; - Shift += 7; + value += slice << shift; + shift += kGreybackOffset; } while (*p++ >= 128); - if (n) - *n = (unsigned)(p - orig_p); - return Value; + if (n) { + *n = static_cast(p - orig_p); + } + return value; } -//decode a SLEB128 value. +// decode a SLEB128 value. int64_t DecodeSLEB128(const uint8_t *p, unsigned *n, const uint8_t *end) { const uint8_t *orig_p = p; - int64_t Value = 0; - unsigned Shift = 0; - uint8_t Byte; + int64_t value = 0; + unsigned shift = 0; + uint8_t byte; do { if (p == end) { - if (n) - *n = (unsigned)(p - orig_p); + if (n) { + *n = static_cast(p - orig_p); + } return 0; } - Byte = *p; - uint64_t Slice = Byte & 0x7f; - if ((Shift >= 64 && Slice != (Value < 0 ? 0x7f : 0x00)) || - (Shift == 63 && Slice != 0 && Slice != 0x7f)) { - if (n) - *n = (unsigned)(p - orig_p); + byte = *p; + uint64_t slice = byte & 0x7f; + if ((shift >= 64 && slice != (value < 0 ? 0x7f : 0x00)) || + (shift == 63 && slice != 0 && slice != 0x7f)) { + if (n) { + *n = static_cast(p - orig_p); + } return 0; } - Value |= Slice << Shift; - Shift += 7; + value |= slice << shift; + shift += kGreybackOffset; ++p; - } while (Byte >= 128); + } while (byte >= 128); // Sign extend negative numbers if needed. - if (Shift < 64 && (Byte & 0x40)) - Value |= (-1ULL) << Shift; - if (n) - *n = (unsigned)(p - orig_p); - return Value; + if (shift < 64 && (byte & 0x40)) { + value |= (-1LL) << shift; + } + if (n) { + *n = static_cast(p - orig_p); + } + return value; } } // namespace namemangler diff --git a/src/mapleall/mpl2mpl/include/mpl_profdata_parser.h b/src/mapleall/mpl2mpl/include/mpl_profdata_parser.h index 95513fd835..24470c0e66 100644 --- a/src/mapleall/mpl2mpl/include/mpl_profdata_parser.h +++ b/src/mapleall/mpl2mpl/include/mpl_profdata_parser.h @@ -22,7 +22,7 @@ #include "mpl_profdata.h" namespace maple { -//maple profile data format +// maple profile data format // Summary layout // MagicNumber // chesum @@ -81,7 +81,7 @@ private: class FunctionProfileImport : public ProfDataBinaryImportBase { public: FunctionProfileImport(std::string& inputFile, std::ifstream &input) : - ProfDataBinaryImportBase(inputFile, input) {} + ProfDataBinaryImportBase(inputFile, input) {} int ReadFuncProfile(MplProfileData *profData); }; @@ -91,8 +91,7 @@ class MplProfDataParser : public AnalysisResult { MplProfDataParser(MIRModule &mirmod, MemPool *mp, bool debug) : AnalysisResult(mp), m(mirmod), alloc(memPool), mempool(mp), dumpDetail(debug) { } - virtual ~MplProfDataParser() { - } + ~MplProfDataParser() = default; MplProfileData *GetProfData() { return profData; } int ReadMapleProfileData(); private: diff --git a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp index 4d686e42ee..dd0e747899 100644 --- a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp +++ b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp @@ -15,12 +15,12 @@ #include "mpl_profdata_parser.h" -#include +#include #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include @@ -33,11 +33,11 @@ namespace maple { template T ProfDataBinaryImportBase::ReadNum() { - unsigned NumBytesRead = 0; - uint64_t Val = namemangler::DecodeULEB128(pos, &NumBytesRead); + unsigned numBytesRead = 0; + uint64_t val = namemangler::DecodeULEB128(pos, &numBytesRead); - pos += NumBytesRead; - return static_cast(Val); + pos += numBytesRead; + return static_cast(val); } int ProfileSummaryImport::ReadSummary(MplProfileData *profData) { @@ -55,7 +55,7 @@ int ProfileSummaryImport::ReadSummary(MplProfileData *profData) { profData->summary.SetSummary(checksum, runtimes, numofCounts, maxCount, sumCount); uint32_t veclen = ReadNum(); - for (int i = 0; i < veclen; i++) { + for (uint32_t i = 0; i < veclen; i++) { uint32_t r1 = ReadNum(); uint32_t r2 = ReadNum(); uint64_t r3 = ReadNum(); @@ -69,9 +69,11 @@ int ProfileSummaryImport::ReadSummary(MplProfileData *profData) { int FunctionProfileImport::ReadFuncProfile(MplProfileData *profData) { CHECK_FATAL(profData != nullptr, "sanity check"); uint32_t funcNums = ReadNum(); - if (funcNums == 0) return 1; + if (funcNums == 0) { + return 1; + } - for (int i = 0; i < funcNums; i++) { + for (uint32_t i = 0; i < funcNums; i++) { uint32_t funcIdent = ReadNum(); uint32_t linocheckSum = ReadNum(); uint32_t cfgcheckSum = ReadNum(); @@ -79,7 +81,7 @@ int FunctionProfileImport::ReadFuncProfile(MplProfileData *profData) { FuncProfInfo *funcProf = profData->AddNewFuncProfile(funcIdent, linocheckSum, cfgcheckSum, countNum); CHECK_FATAL(funcProf != nullptr, "nullptr check"); funcProf->counts.resize(countNum); - for (int j = 0; j < countNum; j++) { + for (uint32_t j = 0; j < countNum; j++) { funcProf->counts[j] = ReadNum(); } } @@ -111,7 +113,10 @@ int MplProfDataParser::ReadMapleProfileData() { } // reduce path in profDataFileName while (stripnum > 0 && profDataFileName.size() > 1) { - auto pos = profDataFileName.find_first_of("/", 1); + size_t pos = profDataFileName.find_first_of("/", 1); + if (pos == std::string::npos) { + break; + } profDataFileName = profDataFileName.substr(pos); stripnum--; } @@ -143,18 +148,18 @@ int MplProfDataParser::ReadMapleProfileData() { return 1; } // get length of file - inputStream.seekg(0, inputStream.end); - int length = inputStream.tellg(); - inputStream.seekg(0, inputStream.beg); + inputStream.seekg(0, std::ios::end); + uint32_t length = inputStream.tellg(); + inputStream.seekg(0, std::ios::beg); const uint32_t sizeThreshold = 1024 * 10; CHECK_FATAL(length <= sizeThreshold, "NYI::large .mprofdata file size is larger than threashold, do chunk memory\n"); - std::unique_ptr buffer(new char[sizeof(char) * length]()); + std::unique_ptr buffer = std::make_unique(length); inputStream.read(buffer.get(), length); inputStream.close(); // read 1st part summary ProfileSummaryImport summaryImport(mprofDataFile, inputStream); - summaryImport.SetPosition((uint8_t*)buffer.get()); + summaryImport.SetPosition((uint8_t*)(buffer.get())); int res = summaryImport.ReadSummary(profData); if (res) { LogInfo::MapleLogger() << "no summary part\n"; @@ -183,7 +188,7 @@ void MMplProfDataParser::GetAnalysisDependence(AnalysisDep &aDep) const { bool MMplProfDataParser::PhaseRun(maple::MIRModule &m) { MemPool *memPool = m.GetMemPool(); // use global pool to store profile data - bool enableDebug = false; // true to dump trace + bool enableDebug = true; // true to dump trace MplProfDataParser parser(m, memPool, enableDebug); int res = parser.ReadMapleProfileData(); if (res) { -- Gitee From eb937a7eace4130827c5b96f62275df94eb5cd74 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Sun, 31 Jul 2022 08:57:42 -0700 Subject: [PATCH 10/16] Formating adjustments from the formating tool --- .../mpl2mpl/include/mpl_profdata_parser.h | 60 +++++++++++-------- .../mpl2mpl/src/mpl_profdata_parser.cpp | 6 +- 2 files changed, 37 insertions(+), 29 deletions(-) diff --git a/src/mapleall/mpl2mpl/include/mpl_profdata_parser.h b/src/mapleall/mpl2mpl/include/mpl_profdata_parser.h index 24470c0e66..1a83fa5c83 100644 --- a/src/mapleall/mpl2mpl/include/mpl_profdata_parser.h +++ b/src/mapleall/mpl2mpl/include/mpl_profdata_parser.h @@ -15,10 +15,10 @@ #ifndef MAPLE_MPL2MPL_INCLUDE_GCOVPROFUSE_H #define MAPLE_MPL2MPL_INCLUDE_GCOVPROFUSE_H -#include "mempool.h" -#include "mempool_allocator.h" #include "bb.h" #include "maple_phase_manager.h" +#include "mempool.h" +#include "mempool_allocator.h" #include "mpl_profdata.h" namespace maple { @@ -55,47 +55,55 @@ namespace maple { const uint32_t kMapleProfDataMagicNumber = 0xA0EFEF; class ProfDataBinaryImportBase { -public: - ProfDataBinaryImportBase(std::string &filename, std::ifstream &input) : fileName(filename), - inputStream(input) {} - template T ReadNum(); - std::ifstream& GetInputStream() { return inputStream; } - std::string& GetProfDataFileName() { return fileName; } - void SetPosition(uint8_t *p) { pos = p; } - uint8_t *GetPosition() { return pos; } -private: + public: + ProfDataBinaryImportBase(std::string &filename, std::ifstream &input) : fileName(filename), inputStream(input) {} + template + T ReadNum(); + std::ifstream &GetInputStream() { + return inputStream; + } + std::string &GetProfDataFileName() { + return fileName; + } + void SetPosition(uint8_t *p) { + pos = p; + } + uint8_t *GetPosition() { + return pos; + } + + private: std::string &fileName; std::ifstream &inputStream; uint8_t *pos = nullptr; }; class ProfileSummaryImport : public ProfDataBinaryImportBase { -public: - ProfileSummaryImport(std::string& outputFile, std::ifstream &input): - ProfDataBinaryImportBase(outputFile, input) {} - int ReadSummary(MplProfileData *); -private: + public: + ProfileSummaryImport(std::string &outputFile, std::ifstream &input) : ProfDataBinaryImportBase(outputFile, input) {} + int ReadSummary(MplProfileData*); + + private: void ReadMProfMagic(); }; class FunctionProfileImport : public ProfDataBinaryImportBase { -public: - FunctionProfileImport(std::string& inputFile, std::ifstream &input) : - ProfDataBinaryImportBase(inputFile, input) {} + public: + FunctionProfileImport(std::string &inputFile, std::ifstream &input) : ProfDataBinaryImportBase(inputFile, input) {} int ReadFuncProfile(MplProfileData *profData); }; - class MplProfDataParser : public AnalysisResult { public: - MplProfDataParser(MIRModule &mirmod, MemPool *mp, bool debug) : AnalysisResult(mp), - m(mirmod), alloc(memPool), mempool(mp), dumpDetail(debug) { - } + MplProfDataParser(MIRModule &mirmod, MemPool *mp, bool debug) + : AnalysisResult(mp), m(mirmod), alloc(memPool), mempool(mp), dumpDetail(debug) {} ~MplProfDataParser() = default; - MplProfileData *GetProfData() { return profData; } + MplProfileData *GetProfData() { + return profData; + } int ReadMapleProfileData(); - private: + private: MIRModule &m; MapleAllocator alloc; MemPool *mempool; @@ -105,6 +113,6 @@ class MplProfDataParser : public AnalysisResult { MAPLE_MODULE_PHASE_DECLARE(MMplProfDataParser) -} // end of namespace maple +} // end of namespace maple #endif // MAPLE_MPL2MPL_INCLUDE_GCOVPROFUSE_H diff --git a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp index dd0e747899..95bd0febdd 100644 --- a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp +++ b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp @@ -15,13 +15,13 @@ #include "mpl_profdata_parser.h" -#include #include + +#include #include #include #include #include - #include #include #include @@ -188,7 +188,7 @@ void MMplProfDataParser::GetAnalysisDependence(AnalysisDep &aDep) const { bool MMplProfDataParser::PhaseRun(maple::MIRModule &m) { MemPool *memPool = m.GetMemPool(); // use global pool to store profile data - bool enableDebug = true; // true to dump trace + bool enableDebug = true; // true to dump trace MplProfDataParser parser(m, memPool, enableDebug); int res = parser.ReadMapleProfileData(); if (res) { -- Gitee From 6f0e55b7cf681a99a866de2160669039ca27eb4c Mon Sep 17 00:00:00 2001 From: linma Date: Thu, 21 Jul 2022 13:19:17 -0700 Subject: [PATCH 11/16] pgo: rewrite profile data parser to accept maple profile data format --- src/mapleall/maple_ipa/src/ipa_clone.cpp | 4 +- .../maple_ipa/src/ipa_phase_manager.cpp | 6 +- src/mapleall/maple_ir/include/mir_function.h | 8 +- src/mapleall/maple_ir/include/mir_lower.h | 2 +- src/mapleall/maple_ir/include/mir_module.h | 13 +- .../maple_me/include/me_profile_use.h | 5 +- src/mapleall/maple_me/include/pme_emit.h | 2 +- src/mapleall/maple_me/src/me_cfg.cpp | 4 +- src/mapleall/maple_me/src/me_profile_use.cpp | 26 +- src/mapleall/maple_util/BUILD.gn | 1 + .../{gcov_profile.h => mpl_profdata.h} | 115 ++++-- src/mapleall/maple_util/include/namemangler.h | 5 + src/mapleall/maple_util/src/mpl_profdata.cpp | 53 +++ src/mapleall/maple_util/src/namemangler.cpp | 92 +++++ src/mapleall/mpl2mpl/BUILD.gn | 2 +- src/mapleall/mpl2mpl/include/gcov_parser.h | 117 ------ .../mpl2mpl/include/inline_transformer.h | 6 +- .../mpl2mpl/include/mpl_profdata_parser.h | 111 ++++++ src/mapleall/mpl2mpl/src/call_graph.cpp | 4 +- src/mapleall/mpl2mpl/src/gcov_parser.cpp | 359 ------------------ src/mapleall/mpl2mpl/src/gen_profile.cpp | 2 +- src/mapleall/mpl2mpl/src/inline.cpp | 4 +- .../mpl2mpl/src/inline_transformer.cpp | 17 +- .../mpl2mpl/src/module_phase_manager.cpp | 4 +- .../mpl2mpl/src/mpl_profdata_parser.cpp | 162 ++++++++ 25 files changed, 567 insertions(+), 557 deletions(-) rename src/mapleall/maple_util/include/{gcov_profile.h => mpl_profdata.h} (37%) create mode 100644 src/mapleall/maple_util/src/mpl_profdata.cpp delete mode 100644 src/mapleall/mpl2mpl/include/gcov_parser.h create mode 100644 src/mapleall/mpl2mpl/include/mpl_profdata_parser.h delete mode 100644 src/mapleall/mpl2mpl/src/gcov_parser.cpp create mode 100644 src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp diff --git a/src/mapleall/maple_ipa/src/ipa_clone.cpp b/src/mapleall/maple_ipa/src/ipa_clone.cpp index b439e6fe0f..86cb99ee51 100644 --- a/src/mapleall/maple_ipa/src/ipa_clone.cpp +++ b/src/mapleall/maple_ipa/src/ipa_clone.cpp @@ -140,9 +140,9 @@ MIRFunction *IpaClone::IpaCloneFunctionWithFreq(MIRFunction &originalFunction, newFunc->SetBaseClassFuncNames(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fullName)); newFunc->GetFuncSymbol()->SetAppearsInCode(true); newFunc->SetPuidxOrigin(newFunc->GetPuidx()); - GcovFuncInfo *origProfData = originalFunction.GetFuncProfData(); + FuncProfInfo *origProfData = originalFunction.GetFuncProfData(); auto *moduleMp = mirBuilder.GetMirModule().GetMemPool(); - GcovFuncInfo *newProfData = moduleMp->New(&mirBuilder.GetMirModule().GetMPAllocator(), + FuncProfInfo *newProfData = moduleMp->New(&mirBuilder.GetMirModule().GetMPAllocator(), newFunc->GetPuidx(), 0, 0); // skip checksum information newFunc->SetFuncProfData(newProfData); newProfData->SetFuncFrequency(callSiteFreq); diff --git a/src/mapleall/maple_ipa/src/ipa_phase_manager.cpp b/src/mapleall/maple_ipa/src/ipa_phase_manager.cpp index e2271b3f5f..d473d76cb5 100644 --- a/src/mapleall/maple_ipa/src/ipa_phase_manager.cpp +++ b/src/mapleall/maple_ipa/src/ipa_phase_manager.cpp @@ -14,7 +14,7 @@ */ #include "ipa_phase_manager.h" #include "pme_emit.h" -#include "gcov_parser.h" +#include "mpl_profdata_parser.h" #define JAVALANG (mirModule.IsJavaModule()) #define CLANG (mirModule.IsCModule()) @@ -102,8 +102,8 @@ void IpaSccPM::GetAnalysisDependence(maple::AnalysisDep &aDep) const { aDep.AddPreserved(); aDep.AddPreserved(); if (Options::profileUse) { - aDep.AddRequired(); - aDep.AddPreserved(); + aDep.AddRequired(); + aDep.AddPreserved(); } } diff --git a/src/mapleall/maple_ir/include/mir_function.h b/src/mapleall/maple_ir/include/mir_function.h index 51e2be56a5..4c41e1ebac 100644 --- a/src/mapleall/maple_ir/include/mir_function.h +++ b/src/mapleall/maple_ir/include/mir_function.h @@ -1271,13 +1271,13 @@ class MIRFunction { InlineSummary *GetOrCreateInlineSummary(); - void SetFuncProfData(GcovFuncInfo *data) { + void SetFuncProfData(FuncProfInfo *data) { funcProfData = data; } - GcovFuncInfo* GetFuncProfData() { + FuncProfInfo* GetFuncProfData() { return funcProfData; } - GcovFuncInfo* GetFuncProfData() const { + FuncProfInfo* GetFuncProfData() const { return funcProfData; } void SetStmtFreq(uint32_t stmtID, uint64_t freq) { @@ -1384,7 +1384,7 @@ class MIRFunction { uint32 nCtrs = 0; // number of counters uint64 fileLinenoChksum = 0; uint64 cfgChksum = 0; - GcovFuncInfo *funcProfData = nullptr; + FuncProfInfo *funcProfData = nullptr; InlineSummary *inlineSummary = nullptr; void DumpFlavorLoweredThanMmpl() const; MIRFuncType *ReconstructFormals(const std::vector &symbols, bool clearOldArgs); diff --git a/src/mapleall/maple_ir/include/mir_lower.h b/src/mapleall/maple_ir/include/mir_lower.h index c2261326d1..e4229aa853 100644 --- a/src/mapleall/maple_ir/include/mir_lower.h +++ b/src/mapleall/maple_ir/include/mir_lower.h @@ -142,7 +142,7 @@ class MIRLower { virtual bool InLFO() const { return false; } - GcovFuncInfo *GetFuncProfData() const { + FuncProfInfo *GetFuncProfData() const { return mirFunc->GetFuncProfData(); } void CopyStmtFrequency(StmtNode *newStmt, StmtNode *oldStmt) { diff --git a/src/mapleall/maple_ir/include/mir_module.h b/src/mapleall/maple_ir/include/mir_module.h index 37c54a99b3..be748df3f5 100644 --- a/src/mapleall/maple_ir/include/mir_module.h +++ b/src/mapleall/maple_ir/include/mir_module.h @@ -22,7 +22,7 @@ #include "muid.h" #include "profile.h" #include "namemangler.h" -#include "gcov_profile.h" +#include "mpl_profdata.h" #if MIR_FEATURE_FULL #include #include @@ -268,11 +268,11 @@ class MIRModule { return profile; } - GcovProfileData* GetGcovProfile() { - return gcovProfile; + MplProfileData* GetMapleProfile() { + return mplProfile; } - void SetGcovProfile(GcovProfileData* info) { - gcovProfile = info; + void SetMapleProfile(MplProfileData* info) { + mplProfile = info; } void SetSomeSymbolNeedForDecl(bool s) { @@ -345,7 +345,6 @@ class MIRModule { std::replace(profileDataFileName.begin(), profileDataFileName.end(), '.', '_'); std::replace(profileDataFileName.begin(), profileDataFileName.end(), '-', '_'); std::replace(profileDataFileName.begin(), profileDataFileName.end(), '/', '_'); - profileDataFileName = profileDataFileName + namemangler::kProfFileNameExt; return profileDataFileName; } @@ -710,7 +709,7 @@ class MIRModule { MapleSet symbolSet; MapleVector symbolDefOrder; Profile profile; - GcovProfileData* gcovProfile; + MplProfileData* mplProfile; bool someSymbolNeedForwDecl = false; // some symbols' addressses used in initialization std::ostream &out; diff --git a/src/mapleall/maple_me/include/me_profile_use.h b/src/mapleall/maple_me/include/me_profile_use.h index a6a0be8df7..2014e80026 100644 --- a/src/mapleall/maple_me/include/me_profile_use.h +++ b/src/mapleall/maple_me/include/me_profile_use.h @@ -137,8 +137,7 @@ class MeProfUse : public PGOInstrument { bool IsSuccUseProf() const { return succCalcuAllEdgeFreq; } - bool GcovRun(); - GcovFuncInfo *GetFuncData(); + bool MapleProfRun(); bool CheckSumFail(const uint64 hash, const uint32 expectedCheckSum, const std::string &tag); private: bool IsAllZero(Profile::BBInfo &result) const; @@ -147,6 +146,8 @@ class MeProfUse : public PGOInstrument { void ComputeEdgeFreq(); void InitBBEdgeInfo(); void ComputeBBFreq(BBUseInfo &bbInfo, bool &changed); + FuncProfInfo *GetFuncData(); + uint64 SumEdgesCount(const MapleVector &edges) const; BBUseInfo *GetBBUseInfo(const BB &bb) const; BBUseInfo *GetOrCreateBBUseInfo(const BB &bb) ; diff --git a/src/mapleall/maple_me/include/pme_emit.h b/src/mapleall/maple_me/include/pme_emit.h index 1a192138e6..19424dd4d1 100644 --- a/src/mapleall/maple_me/include/pme_emit.h +++ b/src/mapleall/maple_me/include/pme_emit.h @@ -79,7 +79,7 @@ class PreMeEmitter : public AnalysisResult { MapleAllocator* GetCodeMPAlloc() { return codeMPAlloc; } MapleMap *GetPreMeStmtExtensionMap() { return &PreMeStmtExtensionMap; } MapleMap *GetPreMeExprExtensionMap() { return &PreMeExprExtensionMap; } - GcovFuncInfo *GetFuncProfData() { return mirFunc->GetFuncProfData(); } + FuncProfInfo *GetFuncProfData() { return mirFunc->GetFuncProfData(); } private: ArrayNode *ConvertToArray(BaseNode *x, TyIdx ptrTyIdx); diff --git a/src/mapleall/maple_me/src/me_cfg.cpp b/src/mapleall/maple_me/src/me_cfg.cpp index ae76692bd4..f51391906f 100644 --- a/src/mapleall/maple_me/src/me_cfg.cpp +++ b/src/mapleall/maple_me/src/me_cfg.cpp @@ -1875,7 +1875,7 @@ void MeCFG::ConstructEdgeFreqFromBBFreq() { // set bb frequency from stmt record void MeCFG::ConstructBBFreqFromStmtFreq() { - GcovFuncInfo* funcData = func.GetMirFunc()->GetFuncProfData(); + FuncProfInfo* funcData = func.GetMirFunc()->GetFuncProfData(); if (!funcData) { return; } @@ -1915,7 +1915,7 @@ void MeCFG::ConstructBBFreqFromStmtFreq() { } void MeCFG::ConstructStmtFreq() { - GcovFuncInfo* funcData = func.GetMirFunc()->GetFuncProfData(); + FuncProfInfo* funcData = func.GetMirFunc()->GetFuncProfData(); if (!funcData) { return; } diff --git a/src/mapleall/maple_me/src/me_profile_use.cpp b/src/mapleall/maple_me/src/me_profile_use.cpp index 0a4d1ea0f7..4d9c62b6ad 100644 --- a/src/mapleall/maple_me/src/me_profile_use.cpp +++ b/src/mapleall/maple_me/src/me_profile_use.cpp @@ -294,12 +294,12 @@ bool MeProfUse::Run() { return true; } -GcovFuncInfo *MeProfUse::GetFuncData() { - GcovProfileData *gcovData = func->GetMIRModule().GetGcovProfile(); - if (!gcovData) { +FuncProfInfo *MeProfUse::GetFuncData() { + MplProfileData* profData = func->GetMIRModule().GetMapleProfile(); + if (!profData) { return nullptr; } - GcovFuncInfo *funcData = gcovData->GetFuncProfile(func->GetUniqueID()); + FuncProfInfo *funcData = profData->GetFuncProfile(func->GetUniqueID()); return funcData; } @@ -315,20 +315,20 @@ bool MeProfUse::CheckSumFail(const uint64 hash, const uint32 expectedCheckSum, c return false; } -bool MeProfUse::GcovRun() { - GcovFuncInfo *funcData = GetFuncData(); +bool MeProfUse::MapleProfRun() { + FuncProfInfo* funcData = GetFuncData(); if (!funcData) { return false; } func->GetMirFunc()->SetFuncProfData(funcData); // early return if lineno fail - if (CheckSumFail(ComputeLinenoHash(), funcData->lineno_checksum, "lineno")) { + if (CheckSumFail(ComputeLinenoHash(), funcData->linenoChecksum, "lineno")) { func->GetMirFunc()->SetFuncProfData(nullptr); // clear func profile data return false; } FindInstrumentEdges(); // early return if cfgchecksum fail - if (CheckSumFail(ComputeFuncHash(), funcData->cfg_checksum, "func")) { + if (CheckSumFail(ComputeFuncHash(), funcData->cfgChecksum, "func")) { return false; } std::vector instrumentBBs; @@ -336,10 +336,10 @@ bool MeProfUse::GcovRun() { if (dump) { DumpEdgeInfo(); } - if (instrumentBBs.size() != funcData->num_counts) { + if (instrumentBBs.size() != funcData->edgeCounts) { if (dump) { LogInfo::MapleLogger() << func->GetName() << " counter doesn't match profile counter " - << funcData->num_counts << " func real counter " << instrumentBBs.size() << '\n'; + << funcData->edgeCounts << " func real counter " << instrumentBBs.size() << '\n'; } func->GetMirFunc()->SetFuncProfData(nullptr); // clear func profile data return false; @@ -368,8 +368,10 @@ bool MEProfUse::PhaseRun(maple::MeFunction &f) { MeProfUse profUse(f, *GetPhaseMemPool(), DEBUGFUNC_NEWPM(f)); bool result = true; if (Options::profileUse) { - result = profUse.GcovRun(); - f.GetCfg()->VerifyBBFreq(); + result = profUse.MapleProfRun(); + if (result) { + f.GetCfg()->VerifyBBFreq(); + } } else { profUse.Run(); } diff --git a/src/mapleall/maple_util/BUILD.gn b/src/mapleall/maple_util/BUILD.gn index a7341eae06..09f912369e 100755 --- a/src/mapleall/maple_util/BUILD.gn +++ b/src/mapleall/maple_util/BUILD.gn @@ -27,6 +27,7 @@ src_libmplutil = [ "src/error_code.cpp", "src/thread_env.cpp", "src/mpl_int_val.cpp", + "src/mpl_profdata.cpp" ] src_libcommandline = [ diff --git a/src/mapleall/maple_util/include/gcov_profile.h b/src/mapleall/maple_util/include/mpl_profdata.h similarity index 37% rename from src/mapleall/maple_util/include/gcov_profile.h rename to src/mapleall/maple_util/include/mpl_profdata.h index baf50aa973..6aa8c1520f 100644 --- a/src/mapleall/maple_util/include/gcov_profile.h +++ b/src/mapleall/maple_util/include/mpl_profdata.h @@ -1,32 +1,26 @@ /* - * Copyright (c) [2022] Futurewei Technologies Co., Ltd. All rights reserved. + * Copyright (c) [2022] Futurewei Technologies, Inc. All rights reserved. * - * OpenArkCompiler is licensed under the Mulan Permissive Software License v2. - * You can use this software according to the terms and conditions of the MulanPSL - 2.0. - * You may obtain a copy of MulanPSL - 2.0 at: + * 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: * - * https://opensource.org/licenses/MulanPSL-2.0 + * 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 MulanPSL - 2.0 for more details. + * See the Mulan PSL v2 for more details. */ -#ifndef MAPLE_UTIL_INCLUDE_GCOV_PROFILE_H -#define MAPLE_UTIL_INCLUDE_GCOV_PROFILE_H - +#ifndef MAPLE_UTIL_INCLUDE_MPL_PROFDATA_H +#define MAPLE_UTIL_INCLUDE_MPL_PROFDATA_H #include "mempool_allocator.h" #include #include namespace maple { -using gcov_unsigned_t = unsigned; -using gcov_type = int64_t; -using gcov_type_unsigned = uint64_t; -using location_t = unsigned; #define HOTCALLSITEFREQ 100 - enum UpdateFreqOp { kKeepOrigFreq = 0, kUpdateOrigFreq = 0x1, @@ -35,11 +29,60 @@ enum UpdateFreqOp { kUpdateUnrollRemainderFreq = 0x8, }; -class GcovFuncInfo { +// used for record cumulative datas +struct ProfileSummaryHistogram { + uint32_t startValue; // count value range in [startValue, nextHistogramStart) + uint32_t countNums; // Number of counters whose profile count falls in countValue range. + uint64_t countMinVal; // Smallest profile count included in this range. + uint64_t countCumValue; // Cumulative value of the profile counts + + ProfileSummaryHistogram(uint32_t s, uint32_t num, uint64_t mincount, uint64_t cumcounts) : + startValue(s), countNums(num), countMinVal(mincount), countCumValue(cumcounts) { + } +}; + +class ProfileSummary { +public: + ProfileSummary(MapleAllocator* alloc) : histogram(alloc->Adapter()) {} + ProfileSummary(MapleAllocator *alloc, uint64_t checksum, uint32_t runtimes, + uint32_t totalcount, uint64_t maxcount, uint64_t sumcount) : + checkSum(checksum), run(runtimes), totalCount(totalcount), maxCount(maxcount), sumCount(sumcount), + histogram(alloc->Adapter()) {} + + void SetSummary(uint64_t checksum, uint32_t runtimes, uint32_t totalcount, uint64_t maxcount, uint64_t sumcount) { + checkSum = checksum; + run = runtimes; + totalCount = totalcount; + maxCount = maxcount; + sumCount = sumcount; + } + void AddHistogramRecord(uint32_t s, uint32_t num, uint64_t mincount, uint64_t cumcounts) { + histogram.push_back(ProfileSummaryHistogram(s, num, mincount, cumcounts)); + } + void DumpSummary(); + uint64_t GetCheckSum() { return checkSum; } + uint32_t GetRun() { return run; } + uint32_t GetTotalCount() { return totalCount; } + uint64_t GetMaxCount() { return maxCount; } + uint64_t GetSumCount() { return sumCount; } + uint32_t GetHistogramLength() { return histogram.size(); } + MapleVector& GetHistogram() { return histogram; } + +private: + uint64_t checkSum; // checksum value of module + uint32_t run; // run times + uint32_t totalCount; // number of counters + uint64_t maxCount; // max counter value in single run + uint64_t sumCount; // sum of all counters accumulated. + MapleVector histogram; // record gcov_bucket_type histogram[GCOV_HISTOGRAM_SIZE]; +}; + +class FuncProfInfo { 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; + FuncProfInfo(MapleAllocator* alloc, unsigned funcIdent, unsigned lineno_cs, + unsigned cfg_cs, unsigned countnum = 0) : ident(funcIdent), linenoChecksum(lineno_cs), + cfgChecksum(cfg_cs), edgeCounts(countnum), counts(alloc->Adapter()) {}; + ~FuncProfInfo() = default; uint64_t GetFuncFrequency() const { return entry_freq; } void SetFuncFrequency(uint64_t freq) { entry_freq = freq; } @@ -77,34 +120,48 @@ class GcovFuncInfo { ASSERT(0, "should not be here"); return false; } + void DumpFunctionProfile(); + unsigned ident; - unsigned lineno_checksum; - unsigned cfg_checksum; + unsigned linenoChecksum; + unsigned cfgChecksum; // Raw arc coverage counts. - unsigned num_counts; - MapleVector counts; + unsigned edgeCounts; + MapleVector counts; uint64_t entry_freq; // record entry bb frequence std::unordered_map stmtFreqs; // stmt_id is key, counter value uint64_t real_entryfreq; // function prof data may be modified after clone/inline }; -class GcovProfileData { +class MplProfileData { public: - GcovProfileData(MapleAllocator *alloc) : funcsCounter(alloc->Adapter()) {} + MplProfileData(MemPool *m, MapleAllocator *a) : funcsCounter(a->Adapter()), summary(a), mp(m), alloc(a) {} - GcovFuncInfo *GetFuncProfile(unsigned puidx) { + FuncProfInfo *GetFuncProfile(unsigned puidx) { if (funcsCounter.count(puidx) > 0) { return funcsCounter[puidx]; } return nullptr; } - void AddFuncProfile(unsigned puidx, GcovFuncInfo *funcData) { + FuncProfInfo *AddNewFuncProfile(unsigned puidx, unsigned lino_cs, unsigned cfg_cs, unsigned countnum) { + FuncProfInfo *funcProf = mp->New(alloc, puidx, lino_cs, cfg_cs, countnum); + ASSERT(funcsCounter.count(puidx) == 0, "sanity check"); + funcsCounter[puidx] = funcProf; + return funcProf; + } + void AddFuncProfile(unsigned puidx, FuncProfInfo *funcData) { ASSERT(funcsCounter.count(puidx) == 0, "sanity check"); funcsCounter[puidx] = funcData; } - MapleUnorderedMap funcsCounter; // use puidx as key + void DumpProfileData(); + void DumpFunctionsProfile(); + MapleUnorderedMap funcsCounter; // use puidx as key + // record module profile information and statistics of count information + ProfileSummary summary; +private: + MemPool *mp; + MapleAllocator *alloc; }; - } // end namespace -#endif // MAPLE_UTIL_INCLUDE_GCOV_PROFILE_H +#endif // MAPLE_UTIL_INCLUDE_MPL_PROFDATA_H diff --git a/src/mapleall/maple_util/include/namemangler.h b/src/mapleall/maple_util/include/namemangler.h index 250e9ef8ba..c1b21573fe 100644 --- a/src/mapleall/maple_util/include/namemangler.h +++ b/src/mapleall/maple_util/include/namemangler.h @@ -190,6 +190,7 @@ static constexpr const char kBindingProtectedRegionStr[] = "__BindingProtectRegi static constexpr const char kClassNamePrefixStr[] = "L"; static constexpr const char kClassMethodSplitterStr[] = "_3B"; static constexpr const char kFuncGetCurrentCl[] = "MCC_GetCurrentClassLoader"; +static constexpr const char kMplProfFileNameExt[] = ".mprofdata"; // Serve as a global flag to indicate whether frequent strings have been compressed extern bool doCompression; @@ -212,6 +213,10 @@ uint32_t GetUnsignedLeb128Decode(const uint8_t **data); size_t GetUleb128Size(uint64_t val); size_t GetSleb128Size(int32_t val); bool NeedConvertUTF16(const std::string &str8); +uint32_t EncodeSLEB128(int64_t Value, std::ofstream &out); +uint32_t EncodeULEB128(uint64_t Value, std::ofstream &out); +uint64_t DecodeULEB128(const uint8_t *p, unsigned *n = nullptr, const uint8_t *end = nullptr); +int64_t DecodeSLEB128(const uint8_t *p, unsigned *n = nullptr, const uint8_t *end = nullptr); } // namespace namemangler #endif diff --git a/src/mapleall/maple_util/src/mpl_profdata.cpp b/src/mapleall/maple_util/src/mpl_profdata.cpp new file mode 100644 index 0000000000..64e37ed9c0 --- /dev/null +++ b/src/mapleall/maple_util/src/mpl_profdata.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) [2022] Futurewei Technologies, Inc. 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 "mpl_profdata.h" +#include "mpl_logging.h" +namespace maple { +void ProfileSummary::DumpSummary() { + LogInfo::MapleLogger() << "---------ProfileSummary-------------- \n"; + LogInfo::MapleLogger() << " checkSum: " << std::hex << "0x" << checkSum << "\n"; + LogInfo::MapleLogger() << " runtimes: " << std::dec << run << "\n"; + LogInfo::MapleLogger() << " totalCounts: " << std::dec << totalCount << "\n"; + LogInfo::MapleLogger() << " maxCount: " << std::dec << maxCount << "\n"; + LogInfo::MapleLogger() << " count histogram: countRange countNum minCount cumCount \n"; + for (auto &it : histogram) { + LogInfo::MapleLogger() <<" " << std::dec << it.startValue << "\t"; + LogInfo::MapleLogger() << std::dec << it. countNums<< "\t" << it.countMinVal << "\t" << it.countCumValue << "\n"; + } +} + +void FuncProfInfo::DumpFunctionProfile() { + LogInfo::MapleLogger() << "function ident " << std::dec << ident; + LogInfo::MapleLogger() << " lino_checksum 0x" << std::hex << linenoChecksum << ", "; + LogInfo::MapleLogger() << " cfg_checksum 0x" << std::hex << cfgChecksum << "\n"; + LogInfo::MapleLogger() << " num_counts " << std::dec << edgeCounts << " : "; + for (int i = 0; i < edgeCounts; i++) { + LogInfo::MapleLogger() << std::dec << " " << counts[i]; + } + LogInfo::MapleLogger() << "\n"; +} + +void MplProfileData::DumpFunctionsProfile() { + LogInfo::MapleLogger() << "---------FunctionProfile-------------- \n"; + for (auto &it : funcsCounter) { + it.second->DumpFunctionProfile(); + } +} + +void MplProfileData::DumpProfileData() { + summary.DumpSummary(); + DumpFunctionsProfile(); +} +} // endof namespace diff --git a/src/mapleall/maple_util/src/namemangler.cpp b/src/mapleall/maple_util/src/namemangler.cpp index b2dbd0ca91..151a97f371 100644 --- a/src/mapleall/maple_util/src/namemangler.cpp +++ b/src/mapleall/maple_util/src/namemangler.cpp @@ -16,6 +16,7 @@ #include #include #include +#include namespace namemangler { #ifdef __MRT_DEBUG @@ -593,4 +594,95 @@ size_t GetSleb128Size(int32_t v) { } return size; } + +// encode signed to output stream +uint32_t EncodeSLEB128(int64_t Value, std::ofstream &out) { + bool More; + uint32_t Count = 0; + do { + uint8_t Byte = Value & 0x7f; + // NOTE: this assumes that this signed shift is an arithmetic right shift. + Value >>= 7; + More = !((((Value == 0 ) && ((Byte & 0x40) == 0)) || + ((Value == -1) && ((Byte & 0x40) != 0)))); + Count++; + if (More) { + Byte |= 0x80; // Mark this byte to show that more bytes will follow. + } + out << (char)(Byte); + } while (More); + return Count; +} + +uint32_t EncodeULEB128(uint64_t Value, std::ofstream &out) { + uint32_t Count = 0; + do { + uint8_t Byte = Value & 0x7f; + Value >>= 7; + Count++; + if (Value != 0) { + Byte |= 0x80; // Mark this byte to show that more bytes will follow. + } + out << char(Byte); + } while (Value != 0); + return Count; +} + +// decode a ULEB128 value. +uint64_t DecodeULEB128(const uint8_t *p, unsigned *n, const uint8_t *end) { + const uint8_t *orig_p = p; + uint64_t Value = 0; + unsigned Shift = 0; + do { + if (p == end) { + if (n) + *n = (unsigned)(p - orig_p); + return 0; + } + uint64_t Slice = *p & 0x7f; + if ((Shift >= 64 && Slice != 0) || Slice << Shift >> Shift != Slice) { + if (n) + *n = (unsigned)(p - orig_p); + return 0; + } + Value += Slice << Shift; + Shift += 7; + } while (*p++ >= 128); + if (n) + *n = (unsigned)(p - orig_p); + return Value; +} + +//decode a SLEB128 value. +int64_t DecodeSLEB128(const uint8_t *p, unsigned *n, const uint8_t *end) { + const uint8_t *orig_p = p; + int64_t Value = 0; + unsigned Shift = 0; + uint8_t Byte; + do { + if (p == end) { + if (n) + *n = (unsigned)(p - orig_p); + return 0; + } + Byte = *p; + uint64_t Slice = Byte & 0x7f; + if ((Shift >= 64 && Slice != (Value < 0 ? 0x7f : 0x00)) || + (Shift == 63 && Slice != 0 && Slice != 0x7f)) { + if (n) + *n = (unsigned)(p - orig_p); + return 0; + } + Value |= Slice << Shift; + Shift += 7; + ++p; + } while (Byte >= 128); + // Sign extend negative numbers if needed. + if (Shift < 64 && (Byte & 0x40)) + Value |= (-1ULL) << Shift; + if (n) + *n = (unsigned)(p - orig_p); + return Value; +} + } // namespace namemangler diff --git a/src/mapleall/mpl2mpl/BUILD.gn b/src/mapleall/mpl2mpl/BUILD.gn index c41431ec49..63ba35bebe 100755 --- a/src/mapleall/mpl2mpl/BUILD.gn +++ b/src/mapleall/mpl2mpl/BUILD.gn @@ -57,7 +57,7 @@ src_libmpl2mpl = [ "src/inline_analyzer.cpp", "src/inline_transformer.cpp", "src/method_replace.cpp", - "src/gcov_parser.cpp", + "src/mpl_profdata_parser.cpp", ] configs = [ "${MAPLEALL_ROOT}:mapleallcompilecfg" ] diff --git a/src/mapleall/mpl2mpl/include/gcov_parser.h b/src/mapleall/mpl2mpl/include/gcov_parser.h deleted file mode 100644 index 85dcb3566d..0000000000 --- a/src/mapleall/mpl2mpl/include/gcov_parser.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) [2022] Futurewei Technologies Co., Ltd. All rights reserved. - * - * OpenArkCompiler is licensed under the Mulan Permissive Software License v2. - * You can use this software according to the terms and conditions of the MulanPSL - 2.0. - * You may obtain a copy of MulanPSL - 2.0 at: - * - * https://opensource.org/licenses/MulanPSL-2.0 - * - * 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 MulanPSL - 2.0 for more details. - */ - -#ifndef MAPLE_MPL2MPL_INCLUDE_GCOVPROFUSE_H -#define MAPLE_MPL2MPL_INCLUDE_GCOVPROFUSE_H -#include "mempool.h" -#include "mempool_allocator.h" -#include "bb.h" -#include "maple_phase_manager.h" -#include "gcov_profile.h" - -namespace maple { -using gcov_position_t = unsigned; -// counter defined in gcov-counter.def -enum { - GCOV_COUNTER_ARCS, - GCOV_COUNTER_V_INTERVAL, - GCOV_COUNTER_V_POW2, - GCOV_COUNTER_V_SINGLE, - GCOV_COUNTER_V_INDIR, - GCOV_COUNTER_AVERAGE, - GCOV_COUNTER_IOR, - GCOV_TIME_PROFILER, - GCOV_COUNTER_ICALL_TOPNV, - GCOV_COUNTERS -}; - -class GcovVar { - public: - GcovVar() { - file = nullptr; - buffer = nullptr; - } - FILE *file = nullptr; - gcov_position_t start = 0; - unsigned offset = 0; - unsigned length = 0; - unsigned overread = 0; - int error = 0; - int mode = 0; - int endian = 0; - size_t alloc = 0; - gcov_unsigned_t* buffer = nullptr; -}; - -class MGcovParser : public AnalysisResult { - public: - MGcovParser(MIRModule &mirmod, MemPool *memPool, bool debug) : AnalysisResult(memPool), m(mirmod), - alloc(memPool), localMP(memPool), gcovData(nullptr), dumpDetail(debug) { - gcovVar = localMP->New(); - } - ~MGcovParser() override { - localMP = nullptr; - gcovData = nullptr; - gcovVar = nullptr; - } - int ReadGcdaFile(); - void DumpFuncInfo(); - GcovProfileData *GetGcovData() { return gcovData; } - - private: - using gcov_bucket_type = struct { - gcov_unsigned_t num_counters; - gcov_type min_value; - gcov_type cum_value; - }; - - struct gcov_ctr_summary { - gcov_unsigned_t num; - gcov_unsigned_t runs; - gcov_type sum_all; - gcov_type run_max; - gcov_type sum_max; - gcov_bucket_type histogram[252]; - }; - struct gcov_summary { - gcov_unsigned_t checksum; - struct gcov_ctr_summary ctrs[GCOV_COUNTER_V_INTERVAL]; - }; - - int GcovReadMagic(gcov_unsigned_t magic, gcov_unsigned_t expected); - int GcovOpenFile(const char *name, int mode); - gcov_unsigned_t from_file(gcov_unsigned_t value); - const gcov_unsigned_t *GcovReadWords(unsigned words); - void GcovSync(gcov_position_t base, gcov_unsigned_t length); - int GcovCloseFile(void); - void GcovAllocate(unsigned length); - gcov_unsigned_t GcovReadUnsigned(void); - gcov_position_t GcovGetPosition(void); - gcov_type GcovReadCounter(void); - void GcovReadSummary(struct gcov_summary *summary); - - MIRModule &m; - MapleAllocator alloc; - MemPool *localMP; - GcovProfileData *gcovData; - GcovVar *gcovVar = nullptr; - bool dumpDetail; -}; - -MAPLE_MODULE_PHASE_DECLARE(M2MGcovParser) - -} // end of namespace maple - -#endif // MAPLE_MPL2MPL_INCLUDE_GCOVPROFUSE_H diff --git a/src/mapleall/mpl2mpl/include/inline_transformer.h b/src/mapleall/mpl2mpl/include/inline_transformer.h index 8d95a97381..1569f9b900 100644 --- a/src/mapleall/mpl2mpl/include/inline_transformer.h +++ b/src/mapleall/mpl2mpl/include/inline_transformer.h @@ -55,7 +55,10 @@ class InlineTransformer { callee(callee), callStmt(callStmt), dumpDetail(dumpDetail), - cg(cg) {} + cg(cg) { + updateFreq = (Options::profileUse && caller.GetFuncProfData() && callee.GetFuncProfData()); + }; + bool PerformInline(BlockNode &enclosingBlk); static void ReplaceSymbols(BaseNode*, uint32, const std::vector*); static void ConvertPStaticToFStatic(MIRFunction &func); @@ -91,6 +94,7 @@ class InlineTransformer { LabelIdx returnLabelIdx = 0; // The lableidx where the code will jump when the callee returns. StmtNode *labelStmt = nullptr; // The LabelNode we created for the callee, if needed. CallGraph *cg = nullptr; + bool updateFreq = false; }; } // namespace maple #endif // MPL2MPL_INCLUDE_INLINE_TRANSFORMER_H diff --git a/src/mapleall/mpl2mpl/include/mpl_profdata_parser.h b/src/mapleall/mpl2mpl/include/mpl_profdata_parser.h new file mode 100644 index 0000000000..95513fd835 --- /dev/null +++ b/src/mapleall/mpl2mpl/include/mpl_profdata_parser.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) [2022] Futurewei Technologies, Inc. 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_MPL2MPL_INCLUDE_GCOVPROFUSE_H +#define MAPLE_MPL2MPL_INCLUDE_GCOVPROFUSE_H +#include "mempool.h" +#include "mempool_allocator.h" +#include "bb.h" +#include "maple_phase_manager.h" +#include "mpl_profdata.h" + +namespace maple { +//maple profile data format +// Summary layout +// MagicNumber +// chesum +// run times +// counts number +// count Maxium value +// accumulated count sum +// cout histogram size (count statistic information used for hot function check) +// count lower bound <-- begin of histogram details +// countNum in current range +// minium value in count range +// accumulated count sum +// count range <-- another histogram element +// countNum +// minium value in cout range +// accumulated count sum +// Function profile layout (now only including edge profiling counts) +// function numbers +// function Ident (key number to identify each function(now use mirfunction->puidx) +// function line number checksum +// function cfg checksum +// counts number in function 0 +// count <-- begin of count value +// count +// counts number in function 1 +// count +// ... +// now only unsigned number in profile data, use ULEB128 to encode/decode value for file size + +const uint32_t kMapleProfDataMagicNumber = 0xA0EFEF; + +class ProfDataBinaryImportBase { +public: + ProfDataBinaryImportBase(std::string &filename, std::ifstream &input) : fileName(filename), + inputStream(input) {} + template T ReadNum(); + std::ifstream& GetInputStream() { return inputStream; } + std::string& GetProfDataFileName() { return fileName; } + void SetPosition(uint8_t *p) { pos = p; } + uint8_t *GetPosition() { return pos; } +private: + std::string &fileName; + std::ifstream &inputStream; + uint8_t *pos = nullptr; +}; + +class ProfileSummaryImport : public ProfDataBinaryImportBase { +public: + ProfileSummaryImport(std::string& outputFile, std::ifstream &input): + ProfDataBinaryImportBase(outputFile, input) {} + int ReadSummary(MplProfileData *); +private: + void ReadMProfMagic(); +}; + +class FunctionProfileImport : public ProfDataBinaryImportBase { +public: + FunctionProfileImport(std::string& inputFile, std::ifstream &input) : + ProfDataBinaryImportBase(inputFile, input) {} + int ReadFuncProfile(MplProfileData *profData); +}; + + +class MplProfDataParser : public AnalysisResult { + public: + MplProfDataParser(MIRModule &mirmod, MemPool *mp, bool debug) : AnalysisResult(mp), + m(mirmod), alloc(memPool), mempool(mp), dumpDetail(debug) { + } + virtual ~MplProfDataParser() { + } + MplProfileData *GetProfData() { return profData; } + int ReadMapleProfileData(); + private: + + MIRModule &m; + MapleAllocator alloc; + MemPool *mempool; + MplProfileData *profData = nullptr; + bool dumpDetail = false; +}; + +MAPLE_MODULE_PHASE_DECLARE(MMplProfDataParser) + +} // end of namespace maple + +#endif // MAPLE_MPL2MPL_INCLUDE_GCOVPROFUSE_H diff --git a/src/mapleall/mpl2mpl/src/call_graph.cpp b/src/mapleall/mpl2mpl/src/call_graph.cpp index 315b8c1929..7e932a68a2 100644 --- a/src/mapleall/mpl2mpl/src/call_graph.cpp +++ b/src/mapleall/mpl2mpl/src/call_graph.cpp @@ -190,7 +190,7 @@ bool CGNode::IsCalleeOf(CGNode *func) const { } uint64_t CGNode::GetCallsiteFrequency(const StmtNode *callstmt) const { - GcovFuncInfo *funcInfo = mirFunc->GetFuncProfData(); + FuncProfInfo *funcInfo = mirFunc->GetFuncProfData(); if (funcInfo->stmtFreqs.count(callstmt->GetStmtID()) > 0) { return funcInfo->stmtFreqs[callstmt->GetStmtID()]; } @@ -199,7 +199,7 @@ uint64_t CGNode::GetCallsiteFrequency(const StmtNode *callstmt) const { } uint64_t CGNode::GetFuncFrequency() const { - GcovFuncInfo *funcInfo = mirFunc->GetFuncProfData(); + FuncProfInfo *funcInfo = mirFunc->GetFuncProfData(); if (funcInfo) { return funcInfo->GetFuncFrequency(); } diff --git a/src/mapleall/mpl2mpl/src/gcov_parser.cpp b/src/mapleall/mpl2mpl/src/gcov_parser.cpp deleted file mode 100644 index f0f1373e90..0000000000 --- a/src/mapleall/mpl2mpl/src/gcov_parser.cpp +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Copyright (c) [2022] Futurewei Technologies Co., Ltd. All rights reserved. - * - * OpenArkCompiler is licensed under the Mulan Permissive Software License v2. - * You can use this software according to the terms and conditions of the MulanPSL - 2.0. - * You may obtain a copy of MulanPSL - 2.0 at: - * - * https://opensource.org/licenses/MulanPSL-2.0 - * - * 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 MulanPSL - 2.0 for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "option.h" -#include "mpl_logging.h" -#include "gcov_parser.h" - -namespace maple { -#define GCOV_DATA_MAGIC ((gcov_unsigned_t)0x67636461) /* "gcda" */ -#define GCOV_VERSION ((gcov_unsigned_t)0x4137352a) - -#ifndef ATTRIBUTE_UNUSED -#define ATTRIBUTE_UNUSED __attribute__((unused)) -#endif - -/* Convert a magic or version number to a 4 character string. */ -#define GCOV_UNSIGNED2STRING(ARRAY,VALUE) \ - ((ARRAY)[0] = (char)((VALUE) >> 24), \ - (ARRAY)[1] = (char)((VALUE) >> 16), \ - (ARRAY)[2] = (char)((VALUE) >> 8), \ - (ARRAY)[3] = (char)((VALUE) >> 0)) - -#define GCOV_TAG_FUNCTION ((gcov_unsigned_t)0x01000000) -#define GCOV_TAG_FUNCTION_LENGTH (3) -#define GCOV_TAG_BLOCKS ((gcov_unsigned_t)0x01410000) -#define GCOV_TAG_BLOCKS_LENGTH(NUM) (NUM) -#define GCOV_TAG_BLOCKS_NUM(LENGTH) (LENGTH) -#define GCOV_TAG_ARCS ((gcov_unsigned_t)0x01430000) -#define GCOV_TAG_ARCS_LENGTH(NUM) (1 + (NUM) * 2) -#define GCOV_TAG_ARCS_NUM(LENGTH) (((LENGTH) - 1) / 2) -#define GCOV_TAG_LINES ((gcov_unsigned_t)0x01450000) -#define GCOV_TAG_COUNTER_BASE ((gcov_unsigned_t)0x01a10000) -#define GCOV_TAG_COUNTER_LENGTH(NUM) ((NUM) * 2) -#define GCOV_TAG_COUNTER_NUM(LENGTH) ((LENGTH) / 2) -#define GCOV_TAG_OBJECT_SUMMARY ((gcov_unsigned_t)0xa1000000) /* Obsolete */ -#define GCOV_TAG_PROGRAM_SUMMARY ((gcov_unsigned_t)0xa3000000) -#define GCOV_TAG_SUMMARY_LENGTH(NUM) \ - (1 + GCOV_COUNTERS_SUMMABLE * (10 + 3 * 2) + (NUM) * 5) -#define GCOV_TAG_AFDO_FILE_NAMES ((gcov_unsigned_t)0xaa000000) -#define GCOV_TAG_AFDO_FUNCTION ((gcov_unsigned_t)0xac000000) -#define GCOV_TAG_AFDO_WORKING_SET ((gcov_unsigned_t)0xaf000000) - -// Convert a counter index to a tag -#define GCOV_TAG_FOR_COUNTER(COUNT) \ - (GCOV_TAG_COUNTER_BASE + ((gcov_unsigned_t)(COUNT) << 17)) - -// Return the number of set bits in X -static int popcount_hwi (unsigned long long x) { - int i, ret = 0; - size_t bits = sizeof (x) * CHAR_BIT; - for (i = 0; i < bits; i += 1) { - ret += x & 1; - x >>= 1; - } - return ret; -} - -gcov_position_t MGcovParser::GcovGetPosition (void) { - ((void)(0 && (gcovVar->mode > 0))); - return gcovVar->start + gcovVar->offset; -} - -int MGcovParser::GcovOpenFile(const char *name, int mode) { - ((void)(0 && (!gcovVar->file))); - gcovVar->start = 0; - gcovVar->offset = gcovVar->length = 0; - gcovVar->overread = -1u; - gcovVar->error = 0; - gcovVar->endian = 0; - gcovVar->alloc = 0; - if (mode >= 0) { - gcovVar->file = fopen(name, (mode > 0) ? "rb" : "r+b"); - } - if (gcovVar->file) { - mode = 1; - } else if (mode <= 0) { - gcovVar->file = fopen(name, "w+b"); - } - if (!gcovVar->file) return 0; - gcovVar->mode = mode ? mode : 1; - setbuf(gcovVar->file, (char *)0); - return 1; -} - -void MGcovParser::GcovAllocate (unsigned length) { - size_t new_size = gcovVar->alloc; - if (!new_size) { - new_size = (1 << 10); - } - new_size += length; - new_size *= 2; - gcovVar->alloc = new_size; - gcovVar->buffer= ((gcov_unsigned_t *) realloc ((gcovVar->buffer), (new_size << 2))); -} - -int MGcovParser::GcovReadMagic(gcov_unsigned_t magic, gcov_unsigned_t expected) { - if (magic == expected) return 1; - magic = (magic >> 16) | (magic << 16); - magic = ((magic & 0xff00ff) << 8) | ((magic >> 8) & 0xff00ff); - if (magic == expected) { - gcovVar->endian = 1; - return -1; - } - return 0; -} - -void MGcovParser::GcovSync(gcov_position_t base, gcov_unsigned_t length) { - ((void)(0 && (gcovVar->mode > 0))); - base += length; - if (base - gcovVar->start <= gcovVar->length) { - gcovVar->offset = base - gcovVar->start; - } else { - gcovVar->offset = gcovVar->length = 0; - fseek (gcovVar->file, base << 2, 0); - gcovVar->start = ftell (gcovVar->file) >> 2; - } -} - -const gcov_unsigned_t * MGcovParser::GcovReadWords (unsigned words) { - const gcov_unsigned_t *result; - unsigned excess = gcovVar->length - gcovVar->offset; - if (gcovVar->mode <= 0) - return nullptr; - if (excess < words) { - gcovVar->start += gcovVar->offset; - if (excess) { - memmove_s(gcovVar->buffer, excess * 4, gcovVar->buffer + gcovVar->offset, excess * 4); - } - gcovVar->offset = 0; - gcovVar->length = excess; - if (gcovVar->length + words > gcovVar->alloc) { - GcovAllocate(gcovVar->length + words); - } - excess = gcovVar->alloc - gcovVar->length; - excess = fread (gcovVar->buffer + gcovVar->length, 1, excess << 2, gcovVar->file) >> 2; - gcovVar->length += excess; - if (gcovVar->length < words) { - gcovVar->overread += words - gcovVar->length; - gcovVar->length = 0; - return 0; - } - } - result = &gcovVar->buffer[gcovVar->offset]; - gcovVar->offset += words; - return result; -} - -gcov_unsigned_t MGcovParser::from_file(gcov_unsigned_t value) { - if (gcovVar->endian) { - value = (value >> 16) | (value << 16); - value = ((value & 0xff00ff) << 8) | ((value >> 8) & 0xff00ff); - } - return value; -} - -gcov_unsigned_t MGcovParser::GcovReadUnsigned(void) { - gcov_unsigned_t value; - const gcov_unsigned_t *buffer = GcovReadWords(1); - if (!buffer) return 0; - value = from_file(buffer[0]); - return value; -} - -int MGcovParser::GcovCloseFile (void) { - if (gcovVar->file) { - fclose (gcovVar->file); - gcovVar->file = 0; - gcovVar->length = 0; - } - free (gcovVar->buffer); - gcovVar->alloc = 0; - gcovVar->buffer = nullptr; - gcovVar->mode = 0; - return gcovVar->error; -} - -gcov_type MGcovParser::GcovReadCounter (void) { - gcov_type value; - const gcov_unsigned_t *buffer = GcovReadWords(2); - if (!buffer) return 0; - value = from_file (buffer[0]); - if (sizeof (value) > sizeof (gcov_unsigned_t)) { - value |= ((gcov_type) from_file (buffer[1])) << 32; - } else if (buffer[1]) { - gcovVar->error = -1; - } - return value; -} - -void MGcovParser::GcovReadSummary (struct gcov_summary *summary) { - unsigned ix, h_ix, bv_ix, h_cnt = 0; - struct gcov_ctr_summary *csum; - unsigned histo_bitvector[(252 + 31) / 32]; - unsigned cur_bitvector; - summary->checksum = GcovReadUnsigned(); - for (csum = summary->ctrs, ix = (GCOV_COUNTER_ARCS + 1); ix--; csum++) { - csum->num = GcovReadUnsigned(); - csum->runs = GcovReadUnsigned(); - csum->sum_all = GcovReadCounter(); - csum->run_max = GcovReadCounter(); - csum->sum_max = GcovReadCounter(); - memset_s(csum->histogram, sizeof (gcov_bucket_type) * 252, 0, sizeof (gcov_bucket_type) * 252); - for (bv_ix = 0; bv_ix < (252 + 31) / 32; bv_ix++) { - histo_bitvector[bv_ix] = GcovReadUnsigned(); - h_cnt += popcount_hwi (histo_bitvector[bv_ix]); - } - bv_ix = 0; - h_ix = 0; - cur_bitvector = 0; - while (h_cnt--) { - while (!cur_bitvector) { - h_ix = bv_ix * 32; - if (bv_ix >= (252 + 31) / 32) { - CHECK_FATAL(false, "corrupted profile info: summary histogram " "bitvector is corrupt"); - } - cur_bitvector = histo_bitvector[bv_ix++]; - } - while (!(cur_bitvector & 0x1)) { - h_ix++; - cur_bitvector >>= 1; - } - if (h_ix >= 252) { - CHECK_FATAL(0, "corrupted profile info: summary histogram " "index is corrupt"); - } - csum->histogram[h_ix].num_counters = GcovReadUnsigned(); - csum->histogram[h_ix].min_value = GcovReadCounter(); - csum->histogram[h_ix].cum_value = GcovReadCounter(); - cur_bitvector >>= 1; - h_ix++; - } - } -} - -static unsigned object_runs; -static unsigned program_count; -// reference -int MGcovParser::ReadGcdaFile() { - std::string gcovDataFile = Options::profile; - if (gcovDataFile.empty()) { - if (const char* env_p = std::getenv("GCOV_PREFIX")) { - gcovDataFile.append(env_p); - } else { - gcovDataFile.append("."); - } - gcovDataFile.append("/"); - gcovDataFile.append(m.GetProfileDataFileName()); - } - ASSERT(!gcovDataFile.empty(), "null check"); - if (!GcovOpenFile(gcovDataFile.c_str(), 1)) { - LogInfo::MapleLogger() << "no data file " << gcovDataFile << " \n"; - Options::profileUse = false; // reset profileUse - return 0; - } - - if (!GcovReadMagic(GcovReadUnsigned(), GCOV_DATA_MAGIC)) { - LogInfo::MapleLogger() << gcovDataFile << " not a gcov data file\n"; - GcovCloseFile (); - return 1; - } - unsigned version = GcovReadUnsigned(); - if (version != GCOV_VERSION) { - char v[4], e[4]; - GCOV_UNSIGNED2STRING (v, version); - 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 = GcovReadUnsigned(); - - gcovData = localMP->New(&alloc); - GcovFuncInfo *funcInfo = nullptr; - while ((tag = GcovReadUnsigned())) { - unsigned length = GcovReadUnsigned(); - unsigned long base = GcovGetPosition(); - - if (tag == GCOV_TAG_PROGRAM_SUMMARY) { - struct gcov_summary summary; - GcovReadSummary(&summary); - object_runs += summary.ctrs[GCOV_COUNTER_ARCS].runs; - program_count++; - } else if (tag == GCOV_TAG_FUNCTION && length == GCOV_TAG_FUNCTION_LENGTH) { - unsigned ident; - /* Try to find the function in the list. To speed up the - search, first start from the last function found. */ - ident = GcovReadUnsigned(); - unsigned lineno_checksum = GcovReadUnsigned(); - unsigned cfg_checksum = GcovReadUnsigned(); - funcInfo = localMP->New(&alloc, ident, lineno_checksum, cfg_checksum); - (gcovData->funcsCounter)[ident] = funcInfo; - } else if (tag == GCOV_TAG_FOR_COUNTER (GCOV_COUNTER_ARCS)) { - funcInfo->num_counts = GCOV_TAG_COUNTER_NUM(length); - for (int ix = 0; ix != funcInfo->num_counts; ix++) { - funcInfo->counts.push_back(GcovReadCounter()); - } - } - GcovSync(base, length); - } - GcovCloseFile(); - - if (dumpDetail) { - DumpFuncInfo(); - } - return 0; -} - -void MGcovParser::DumpFuncInfo() { - for (auto &it : gcovData->funcsCounter) { - GcovFuncInfo *funcInfo = it.second; - LogInfo::MapleLogger() << "\nfunction ident " << std::dec << funcInfo->ident; - LogInfo::MapleLogger() << " lino_checksum 0x" << std::hex << funcInfo->lineno_checksum; - LogInfo::MapleLogger() << " cfg_checksum 0x" << std::hex << funcInfo->cfg_checksum << "\n"; - LogInfo::MapleLogger() << " num_counts " << std::dec << funcInfo->num_counts << " : "; - for (int i = 0; i < funcInfo->num_counts; i++) { - LogInfo::MapleLogger() << std::dec << " " << funcInfo->counts[i]; - } - } - LogInfo::MapleLogger() << "\n" ; -} - -void M2MGcovParser::GetAnalysisDependence(AnalysisDep &aDep) const { - aDep.SetPreservedAll(); -} - -bool M2MGcovParser::PhaseRun(maple::MIRModule &m) { - MemPool *memPool = m.GetMemPool(); // use global pool to store gcov data - MGcovParser gcovParser(m, memPool, true); - int res = gcovParser.ReadGcdaFile(); - if (res) { - // something wrong - return false; - } - m.SetGcovProfile(gcovParser.GetGcovData()); - return true; -} - - -} // end namespace maple diff --git a/src/mapleall/mpl2mpl/src/gen_profile.cpp b/src/mapleall/mpl2mpl/src/gen_profile.cpp index 2f1a0bdb0e..b586d91474 100644 --- a/src/mapleall/mpl2mpl/src/gen_profile.cpp +++ b/src/mapleall/mpl2mpl/src/gen_profile.cpp @@ -104,7 +104,7 @@ void ProfileGen::CreateModProfDesc() { modProfDescSymMirConst->AddItem(checksumMirConst, 5); // Make the profile file name as fileName.gcda - std::string profFileName = mod.GetProfileDataFileName(); + std::string profFileName = mod.GetProfileDataFileName() + namemangler::kProfFileNameExt; auto *profileFNMirConst = modMP->New("./" + profFileName, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(PTY_a64))); modProfDescSymMirConst->AddItem(profileFNMirConst, 6); diff --git a/src/mapleall/mpl2mpl/src/inline.cpp b/src/mapleall/mpl2mpl/src/inline.cpp index 65b2c8d8a9..1bed8c0df2 100644 --- a/src/mapleall/mpl2mpl/src/inline.cpp +++ b/src/mapleall/mpl2mpl/src/inline.cpp @@ -92,7 +92,7 @@ void MInline::InitParams() { } void MInline::InitProfile() const { - // gcov use different profile data, return + // maple profile use different profile data, return if (Options::profileUse) { return; } @@ -421,7 +421,7 @@ 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 + // use maple instrument profile if (Options::profileUse) { return caller.GetFuncProfData()->IsHotCallSite(callStmt.GetStmtID()); } diff --git a/src/mapleall/mpl2mpl/src/inline_transformer.cpp b/src/mapleall/mpl2mpl/src/inline_transformer.cpp index d387f64d29..67a3abc455 100644 --- a/src/mapleall/mpl2mpl/src/inline_transformer.cpp +++ b/src/mapleall/mpl2mpl/src/inline_transformer.cpp @@ -307,7 +307,7 @@ GotoNode *InlineTransformer::DoUpdateReturnStmts(BlockNode &newBody, StmtNode &s dStmt = builder.CreateStmtRegassign(mirPreg->GetPrimType(), pregIdx, currBaseNode); } dStmt->SetSrcPos(stmt.GetSrcPos()); - if (Options::profileUse) { + if (updateFreq) { caller.GetFuncProfData()->CopyStmtFreq(dStmt->GetStmtID(), stmt.GetStmtID()); caller.GetFuncProfData()->CopyStmtFreq(gotoNode->GetStmtID(), stmt.GetStmtID()); caller.GetFuncProfData()->EraseStmtFreq(stmt.GetStmtID()); @@ -315,7 +315,7 @@ GotoNode *InlineTransformer::DoUpdateReturnStmts(BlockNode &newBody, StmtNode &s newBody.ReplaceStmt1WithStmt2(&stmt, dStmt); newBody.InsertAfter(dStmt, gotoNode); } else { - if (Options::profileUse) { + if (updateFreq) { caller.GetFuncProfData()->CopyStmtFreq(gotoNode->GetStmtID(), stmt.GetStmtID()); caller.GetFuncProfData()->EraseStmtFreq(stmt.GetStmtID()); } @@ -458,10 +458,9 @@ BlockNode *InlineTransformer::CloneFuncBody(BlockNode &funcBody, bool recursiveF if (callee.IsFromMpltInline()) { return funcBody.CloneTree(theMIRModule->GetCurFuncCodeMPAllocator()); } - if (Options::profileUse) { + if (updateFreq) { auto *callerProfData = caller.GetFuncProfData(); auto *calleeProfData = callee.GetFuncProfData(); - ASSERT(callerProfData && calleeProfData, "nullptr check"); uint64_t callsiteFreq = callerProfData->GetStmtFreq(callStmt.GetStmtID()); uint64_t calleeEntryFreq = calleeProfData->GetFuncFrequency(); uint32_t updateOp = (kKeepOrigFreq | kUpdateFreqbyScale); @@ -562,7 +561,7 @@ void InlineTransformer::AssignActualsToFormals(BlockNode &newBody, uint32 stIdxO CHECK_NULL_FATAL(currBaseNode); CHECK_NULL_FATAL(formal); AssignActualToFormal(newBody, stIdxOff, regIdxOff, *currBaseNode, *formal); - if (Options::profileUse) { + if (updateFreq) { caller.GetFuncProfData()->CopyStmtFreq(newBody.GetFirst()->GetStmtID(), callStmt.GetStmtID()); } } @@ -606,7 +605,7 @@ void InlineTransformer::HandleReturn(BlockNode &newBody) { } } } - if (Options::profileUse && (labelStmt != nullptr) && (newBody.GetLast() == labelStmt)) { + if (updateFreq && (labelStmt != nullptr) && (newBody.GetLast() == labelStmt)) { caller.GetFuncProfData()->CopyStmtFreq(labelStmt->GetStmtID(), callStmt.GetStmtID()); } } @@ -623,7 +622,7 @@ void InlineTransformer::ReplaceCalleeBody(BlockNode &enclosingBlk, BlockNode &ne beginCmt += callee.GetName(); StmtNode *commNode = builder.CreateStmtComment(beginCmt.c_str()); enclosingBlk.InsertBefore(&callStmt, commNode); - if (Options::profileUse) { + if (updateFreq) { caller.GetFuncProfData()->CopyStmtFreq(commNode->GetStmtID(), callStmt.GetStmtID()); } // end inlining function @@ -639,7 +638,7 @@ void InlineTransformer::ReplaceCalleeBody(BlockNode &enclosingBlk, BlockNode &ne } commNode = builder.CreateStmtComment(endCmt.c_str()); enclosingBlk.InsertAfter(&callStmt, commNode); - if (Options::profileUse) { + if (updateFreq) { caller.GetFuncProfData()->CopyStmtFreq(commNode->GetStmtID(), callStmt.GetStmtID()); } CHECK_FATAL(callStmt.GetNext() != nullptr, "null ptr check"); @@ -663,7 +662,7 @@ void InlineTransformer::GenReturnLabel(BlockNode &newBody, uint32 inlinedTimes) // record the created label labelStmt = builder.CreateStmtLabel(returnLabelIdx); newBody.AddStatement(labelStmt); - if (Options::profileUse) { + if (updateFreq) { caller.GetFuncProfData()->CopyStmtFreq(labelStmt->GetStmtID(), callStmt.GetStmtID()); } } diff --git a/src/mapleall/mpl2mpl/src/module_phase_manager.cpp b/src/mapleall/mpl2mpl/src/module_phase_manager.cpp index 375fba0b8d..ff39484443 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 "gcov_parser.h" +#include "mpl_profdata_parser.h" #define JAVALANG (mirModule.IsJavaModule()) #define CLANG (mirModule.IsCModule()) @@ -109,7 +109,7 @@ MAPLE_ANALYSIS_PHASE_REGISTER(M2MCallGraph, callgraph) 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(MMplProfDataParser, grofDataParser) MAPLE_TRANSFORM_PHASE_REGISTER(M2MInline, inline) MAPLE_TRANSFORM_PHASE_REGISTER(M2MIPODevirtualize, ipodevirtulize) diff --git a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp new file mode 100644 index 0000000000..de5c758b74 --- /dev/null +++ b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp @@ -0,0 +1,162 @@ +/* + * Copyright (c) [2022] Futurewei Technologies, Inc. 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include "option.h" +#include "mpl_logging.h" +#include "mpl_profdata_parser.h" + +namespace maple { + +template T ProfDataBinaryImportBase::ReadNum() { + unsigned NumBytesRead = 0; + uint64_t Val = namemangler::DecodeULEB128(pos, &NumBytesRead); + + pos += NumBytesRead; + return static_cast(Val); +} + +int ProfileSummaryImport::ReadSummary(MplProfileData *profData) { + CHECK_FATAL(profData != nullptr, "sanity check"); + uint64_t magicNum = ReadNum(); + if (magicNum != kMapleProfDataMagicNumber) { + LogInfo::MapleLogger() << "magic number error, quit\n"; + return 1; + } + uint64_t checksum = ReadNum(); + uint32_t runtimes = ReadNum(); + uint32_t numofCounts = ReadNum(); + uint64_t maxCount = ReadNum(); + uint64_t sumCount = ReadNum(); + profData->summary.SetSummary(checksum, runtimes, numofCounts, maxCount, sumCount); + uint32_t veclen = ReadNum(); + + for (int i = 0; i < veclen; i++) { + uint32_t r1 = ReadNum(); + uint32_t r2 = ReadNum(); + uint64_t r3 = ReadNum(); + uint64_t r4 = ReadNum(); + profData->summary.AddHistogramRecord(r1, r2, r3, r4); + } + + return 0; +} + +int FunctionProfileImport::ReadFuncProfile(MplProfileData *profData) { + CHECK_FATAL(profData != nullptr, "sanity check"); + uint32_t funcNums = ReadNum(); + if (funcNums == 0) return 1; + + for (int i = 0; i < funcNums; i++) { + uint32_t funcIdent = ReadNum(); + uint32_t linocheckSum = ReadNum(); + uint32_t cfgcheckSum = ReadNum(); + uint32_t countNum = ReadNum(); + FuncProfInfo *funcProf = profData->AddNewFuncProfile(funcIdent, linocheckSum, cfgcheckSum, countNum); + CHECK_FATAL(funcProf != nullptr, "nullptr check"); + funcProf->counts.resize(countNum); + for (int j = 0; j < countNum; j++) { + funcProf->counts[j] = ReadNum(); + } + } + return 0; +} + +int MplProfDataParser::ReadMapleProfileData() { + std::string mprofDataFile = Options::profile; + if (mprofDataFile.empty()) { + if (const char* env_p = std::getenv("GCOV_PREFIX")) { + mprofDataFile.append(env_p); + } else { + mprofDataFile.append("."); + } + mprofDataFile.append("/"); + mprofDataFile.append(m.GetProfileDataFileName()); + mprofDataFile.append(namemangler::kMplProfFileNameExt); + } + ASSERT(!mprofDataFile.empty(), "null check"); + + // create mpl profdata + profData = mempool->New(mempool, &alloc); + // read .mprofdata + std::ifstream inputStream(mprofDataFile, (std::ios::in | std::ios::binary)); + if (!inputStream) { + LogInfo::MapleLogger() << "Could not open the file " << mprofDataFile << "\n"; + return 1; + } + // get length of file + inputStream.seekg (0, inputStream.end); + int length = inputStream.tellg(); + inputStream.seekg (0, inputStream.beg); + const uint32_t sizeThreshold = 1024*10; + CHECK_FATAL(length <= sizeThreshold, "NYI::large .mprofdata file size is larger than threashold, do chunk memory\n"); + + std::unique_ptr buffer(new char[sizeof(char) * length]()); + inputStream.read (buffer.get(), length); + inputStream.close(); + // read 1st part summary + ProfileSummaryImport summaryImport(mprofDataFile, inputStream); + summaryImport.SetPosition((uint8_t *)buffer.get()); + int res = summaryImport.ReadSummary(profData); + if (res) { + LogInfo::MapleLogger() << "no summary part\n"; + return 1; + } + if (dumpDetail) { + profData->summary.DumpSummary(); + } + // read 2nd part function profile data + FunctionProfileImport funcImport(mprofDataFile, inputStream); + funcImport.SetPosition(summaryImport.GetPosition()); + res = funcImport.ReadFuncProfile(profData); + if (res) { + LogInfo::MapleLogger() << "no function profile part\n"; + return 1; + } + if (dumpDetail) { + profData->DumpFunctionsProfile(); + } + return 0; +} + +void MMplProfDataParser::GetAnalysisDependence(AnalysisDep &aDep) const { + aDep.SetPreservedAll(); +} + +bool MMplProfDataParser::PhaseRun(maple::MIRModule &m) { + + MemPool *memPool = m.GetMemPool(); // use global pool to store profile data + MplProfDataParser parser(m, memPool, true/*debug*/); + int res = parser.ReadMapleProfileData(); + if (res) { + // something wrong + LogInfo::MapleLogger() << " parse .mprofdata error\n"; + return false; + } + m.SetMapleProfile(parser.GetProfData()); + + return true; +} + + +} // end namespace maple -- Gitee From 152f45cdf0464104cdbc6c4b0dc3ec4c5c136e94 Mon Sep 17 00:00:00 2001 From: linma Date: Wed, 27 Jul 2022 13:43:28 -0700 Subject: [PATCH 12/16] pgo use: maintain frequency in valuerangeprop and optimizeCFg, fix frequency issue in loopinversion generate cfg dot file for profileuse debug --- src/mapleall/maple_me/include/bb.h | 33 +- src/mapleall/maple_me/include/hdse.h | 21 +- src/mapleall/maple_me/include/me_cfg.h | 39 +- src/mapleall/maple_me/include/me_loop_canon.h | 5 +- .../maple_me/include/me_loop_unrolling.h | 52 +- src/mapleall/maple_me/src/bb.cpp | 43 +- src/mapleall/maple_me/src/hdse.cpp | 59 +- src/mapleall/maple_me/src/me_bb_layout.cpp | 84 +- src/mapleall/maple_me/src/me_cfg.cpp | 249 ++-- .../maple_me/src/me_critical_edge.cpp | 22 +- src/mapleall/maple_me/src/me_dse.cpp | 10 +- src/mapleall/maple_me/src/me_hdse.cpp | 23 +- src/mapleall/maple_me/src/me_loop_canon.cpp | 60 +- .../maple_me/src/me_loop_inversion.cpp | 101 +- .../maple_me/src/me_loop_unrolling.cpp | 165 +-- src/mapleall/maple_me/src/me_profile_use.cpp | 35 +- .../maple_me/src/me_value_range_prop.cpp | 1152 +++++++++-------- src/mapleall/maple_me/src/optimizeCFG.cpp | 354 ++--- .../maple_util/include/mpl_profdata.h | 121 +- src/mapleall/maple_util/src/mpl_profdata.cpp | 61 +- .../mpl2mpl/include/inline_transformer.h | 5 +- src/mapleall/mpl2mpl/src/call_graph.cpp | 30 +- src/mapleall/mpl2mpl/src/inline.cpp | 57 +- .../mpl2mpl/src/mpl_profdata_parser.cpp | 41 +- 24 files changed, 1663 insertions(+), 1159 deletions(-) diff --git a/src/mapleall/maple_me/include/bb.h b/src/mapleall/maple_me/include/bb.h index 24d5327261..e0c01e71e8 100644 --- a/src/mapleall/maple_me/include/bb.h +++ b/src/mapleall/maple_me/include/bb.h @@ -14,18 +14,18 @@ */ #ifndef MAPLE_ME_INCLUDE_BB_H #define MAPLE_ME_INCLUDE_BB_H -#include "utils.h" #include "mpl_number.h" -#include "ptr_list_ref.h" #include "orig_symbol.h" -#include "ver_symbol.h" +#include "ptr_list_ref.h" #include "ssa.h" +#include "utils.h" +#include "ver_symbol.h" namespace maple { -class MeStmt; // circular dependency exists, no other choice -class MePhiNode; // circular dependency exists, no other choice +class MeStmt; // circular dependency exists, no other choice +class MePhiNode; // circular dependency exists, no other choice class PiassignMeStmt; // circular dependency exists, no other choice -class IRMap; // circular dependency exists, no other choice +class IRMap; // circular dependency exists, no other choice enum BBKind { kBBUnknown, // uninitialized kBBCondGoto, @@ -406,8 +406,17 @@ class BB { ASSERT(idx >= 0 && idx <= succFreq.size(), "sanity check"); succFreq[static_cast(idx)] = freq; } + void AddSuccFreq(uint64 freq, size_t pos = UINT32_MAX) { + ASSERT((pos <= succFreq.size() || pos == UINT32_MAX), "Invalid position."); + if (pos == UINT32_MAX) { + succFreq.push_back(freq); + } else { + succFreq.insert(succFreq.begin() + pos, freq); + } + } + // update edge frequency - void UpdateEdgeFreqs(); + void UpdateEdgeFreqs(bool updateSuccFreq = true); const MapleVector &GetSucc() const { return succ; @@ -487,7 +496,7 @@ class BB { auto iter = std::find(succ.begin(), succ.end(), bb); CHECK_FATAL(iter != std::end(succ), "%d is not the successor of %d", bb->UintID(), this->UintID()); CHECK_FATAL(succ.size() == succFreq.size(), "succfreq size %d doesn't match succ size %d", succFreq.size(), - succ.size()); + succ.size()); const size_t idx = static_cast(std::distance(succ.begin(), iter)); succFreq[idx] = freq; } @@ -496,7 +505,7 @@ class BB { succFreq.resize(succ.size()); } - BB* GetGroup() const { + BB *GetGroup() const { return group; } @@ -524,12 +533,13 @@ class BB { int GetPredIndex(const BB &predBB) const; int GetSuccIndex(const BB &succBB) const; void RemovePhiOpnd(int index); + private: bool IsInList(const MapleVector &bbList) const; int RemoveBBFromVector(MapleVector &bbVec) const; BBId id; - LabelIdx bbLabel = 0; // the BB's label + LabelIdx bbLabel = 0; // the BB's label MapleVector pred; // predecessor list MapleVector succ; // successor list // record the edge freq from curBB to succ BB @@ -540,8 +550,10 @@ class BB { uint32 frequency = 0; BBKind kind = kBBUnknown; uint32 attributes = 0; + public: StmtNodes stmtNodeList; + private: MeStmts meStmtList; BB *group; @@ -586,6 +598,7 @@ class SCCOfBBs { BB *GetEntry() { return entry; } + private: uint32 id; BB *entry; diff --git a/src/mapleall/maple_me/include/hdse.h b/src/mapleall/maple_me/include/hdse.h index c5a637c314..a00188d9c5 100644 --- a/src/mapleall/maple_me/include/hdse.h +++ b/src/mapleall/maple_me/include/hdse.h @@ -14,17 +14,17 @@ */ #ifndef MAPLE_ME_INCLUDE_HDSE_H #define MAPLE_ME_INCLUDE_HDSE_H +#include "alias_class.h" #include "bb.h" -#include "irmap.h" #include "dominance.h" -#include "alias_class.h" +#include "irmap.h" namespace maple { class MeIRMap; class HDSE { public: - HDSE(MIRModule &mod, const MapleVector &bbVec, BB &commonEntryBB, BB &commonExitBB, - Dominance &pDom, IRMap &map, const AliasClass *aliasClass, bool enabledDebug = false, bool decouple = false) + HDSE(MIRModule &mod, const MapleVector &bbVec, BB &commonEntryBB, BB &commonExitBB, Dominance &pDom, IRMap &map, + const AliasClass *aliasClass, bool enabledDebug = false, bool decouple = false) : hdseDebug(enabledDebug), mirModule(mod), bbVec(bbVec), @@ -48,6 +48,12 @@ class HDSE { void SetRemoveRedefine(bool val) { removeRedefine = val; } + void SetUpdateFreq(bool update) { + updateFreq = update; + } + bool UpdateFreq() { + return updateFreq; + } bool hdseDebug; bool hdseKeepRef = false; @@ -73,10 +79,11 @@ class HDSE { // Or the meExpr is opnd of a same type meExpr static const uint8 kExprTypeNotNull = 2; bool decoupleStatic = false; - bool needUNClean = false; // used to record if there's unreachable BB + bool needUNClean = false; // used to record if there's unreachable BB bool removeRedefine = false; // used to control if run ResolveContinuousRedefine() - MapleVector verstUseCounts; // index is vstIdx - std::forward_list backSubsCands; // backward substitution candidates + bool updateFreq = false; + MapleVector verstUseCounts; // index is vstIdx + std::forward_list backSubsCands; // backward substitution candidates private: void DseInit(); diff --git a/src/mapleall/maple_me/include/me_cfg.h b/src/mapleall/maple_me/include/me_cfg.h index d04e9addb1..8465e37e75 100644 --- a/src/mapleall/maple_me/include/me_cfg.h +++ b/src/mapleall/maple_me/include/me_cfg.h @@ -14,12 +14,13 @@ */ #ifndef MAPLE_ME_INCLUDE_ME_CFG_H #define MAPLE_ME_INCLUDE_ME_CFG_H -#include "me_function.h" #include "maple_phase.h" +#include "me_function.h" namespace maple { class MeCFG : public AnalysisResult { using BBPtrHolder = MapleVector; + public: using value_type = BBPtrHolder::value_type; using size_type = BBPtrHolder::size_type; @@ -86,7 +87,9 @@ class MeCFG : public AnalysisResult { hasDoWhile = hdw; } - MapleAllocator &GetAlloc() { return mecfgAlloc; } + MapleAllocator &GetAlloc() { + return mecfgAlloc; + } void SetNextBBId(uint32 currNextBBId) { nextBBId = currNextBBId; @@ -98,7 +101,9 @@ class MeCFG : public AnalysisResult { --nextBBId; } - MapleVector &GetAllBBs() { return bbVec; } + MapleVector &GetAllBBs() { + return bbVec; + } iterator begin() { return bbVec.begin(); @@ -296,8 +301,19 @@ class MeCFG : public AnalysisResult { void ConstructBBFreqFromStmtFreq(); void ConstructStmtFreq(); void ConstructEdgeFreqFromBBFreq(); - void UpdateEdgeFreqWithNewBBFreq(); - void VerifyBBFreq(); + void UpdateEdgeFreqWithBBFreq(); + int VerifyBBFreq(bool checkFatal = false); + void SetUpdateCFGFreq(bool b) { + updateFreq = b; + } + bool UpdateCFGFreq() const { + return updateFreq; + } + bool DumpIRProfileFile() const { + return dumpIRProfileFile; + } + void ClearFuncFreqInfo(); + private: void AddCatchHandlerForTryBB(BB &bb, MapleVector &exitBlocks); std::string ConstructFileNameToDump(const std::string &prefix) const; @@ -316,11 +332,14 @@ class MeCFG : public AnalysisResult { MapleAllocator mecfgAlloc; MeFunction &func; MapleSet patternSet; - BBPtrHolder bbVec; + BBPtrHolder bbVec; MapleUnorderedMap labelBBIdMap; MapleUnorderedMap bbTryNodeMap; // maps isTry bb to its try stmt MapleUnorderedMap endTryBB2TryBB; // maps endtry bb to its try bb bool hasDoWhile = false; + // following 2 variable are used in profileUse + bool updateFreq = false; // true to maintain cfg frequency in transform phase + bool dumpIRProfileFile = false; // true to dump cfg to files uint32 nextBBId = 0; // BB SCC @@ -331,10 +350,10 @@ class MeCFG : public AnalysisResult { }; MAPLE_FUNC_PHASE_DECLARE_BEGIN(MEMeCfg, MeFunction) - MeCFG *GetResult() { - return theCFG; - } - MeCFG *theCFG = nullptr; +MeCFG *GetResult() { + return theCFG; +} +MeCFG *theCFG = nullptr; MAPLE_MODULE_PHASE_DECLARE_END MAPLE_FUNC_PHASE_DECLARE_BEGIN(MECfgVerifyFrequency, MeFunction) MAPLE_FUNC_PHASE_DECLARE_END diff --git a/src/mapleall/maple_me/include/me_loop_canon.h b/src/mapleall/maple_me/include/me_loop_canon.h index 248a185127..cd76626574 100644 --- a/src/mapleall/maple_me/include/me_loop_canon.h +++ b/src/mapleall/maple_me/include/me_loop_canon.h @@ -21,7 +21,8 @@ namespace maple { // convert loop to do-while format class MeLoopCanon { public: - MeLoopCanon(MeFunction &f, bool enableDebugFunc) : func(f), isDebugFunc(enableDebugFunc) {} + MeLoopCanon(MeFunction &f, bool enableDebugFunc, bool updateFreq) + : func(f), isDebugFunc(enableDebugFunc), updateFreqs(updateFreq) {} virtual ~MeLoopCanon() = default; void NormalizationExitOfLoop(IdentifyLoops &meLoop); void NormalizationHeadAndPreHeaderOfLoop(Dominance &dom); @@ -33,6 +34,7 @@ class MeLoopCanon { void ResetIsCFGChange() { isCFGChange = false; } + private: void FindHeadBBs(Dominance &dom, const BB *bb, std::map> &heads) const; void SplitPreds(const std::vector &splitList, BB *splittedBB, BB *mergedBB); @@ -44,6 +46,7 @@ class MeLoopCanon { MeFunction &func; bool isDebugFunc; bool isCFGChange = false; + bool updateFreqs = false; }; MAPLE_FUNC_PHASE_DECLARE(MELoopCanon, MeFunction) diff --git a/src/mapleall/maple_me/include/me_loop_unrolling.h b/src/mapleall/maple_me/include/me_loop_unrolling.h index 4b0c81c075..1e5f57be8f 100644 --- a/src/mapleall/maple_me/include/me_loop_unrolling.h +++ b/src/mapleall/maple_me/include/me_loop_unrolling.h @@ -14,22 +14,23 @@ */ #ifndef MAPLE_ME_INCLUDE_LOOP_UNROLLING_H #define MAPLE_ME_INCLUDE_LOOP_UNROLLING_H -#include "me_scalar_analysis.h" +#include "me_cfg.h" +#include "me_dominance.h" #include "me_function.h" -#include "me_irmap_build.h" #include "me_ir.h" -#include "me_ssa_update.h" -#include "me_dominance.h" +#include "me_irmap_build.h" #include "me_loop_analysis.h" +#include "me_scalar_analysis.h" +#include "me_ssa_update.h" #include "profile.h" -#include "me_cfg.h" namespace maple { constexpr uint32 kMaxCost = 100; -constexpr uint8 unrollTimes[3] = { 8, 4, 2 }; // unrollTimes +constexpr uint8 unrollTimes[3] = {8, 4, 2}; // unrollTimes class LoopUnrolling { public: - enum ReturnKindOfFullyUnroll { + enum ReturnKindOfFullyUnroll + { kCanFullyUnroll, kCanNotSplitCondGoto, kCanNotFullyUnroll, @@ -37,14 +38,26 @@ class LoopUnrolling { LoopUnrolling(MeFunction &f, LoopDesc &l, MeIRMap &map, const MapleAllocator &alloc, std::map>> &candsTemp) - : func(&f), cfg(f.GetCfg()), loop(&l), irMap(&map), mpAllocator(alloc), - cands(candsTemp), lastNew2OldBB(mpAllocator.Adapter()), + : func(&f), + cfg(f.GetCfg()), + loop(&l), + irMap(&map), + mpAllocator(alloc), + cands(candsTemp), + lastNew2OldBB(mpAllocator.Adapter()), profValid(func->IsIRProfValid()) {} ~LoopUnrolling() = default; ReturnKindOfFullyUnroll LoopFullyUnroll(int64 tripCount); bool LoopPartialUnrollWithConst(uint64 tripCount); bool LoopPartialUnrollWithVar(CR &cr, CRNode &varNode, uint32 j); bool LoopUnrollingWithConst(uint64 tripCount, bool onlyFully = false); + void SetInstrumentProf(bool useInstrument) { + instrumentProf = useInstrument; + profValid = useInstrument; + } + bool GetInstrumentProf() const { + return instrumentProf; + } private: bool SplitCondGotoBB(); @@ -53,14 +66,12 @@ class LoopUnrolling { void SetLabelWithCondGotoOrGotoBB(BB &bb, std::unordered_map &old2NewBB, const BB &exitBB, LabelIdx oldlabIdx); - void ResetOldLabel2NewLabel(std::unordered_map &old2NewBB, BB &bb, - const BB &exitBB, BB &newHeadBB); - void ResetOldLabel2NewLabel2(std::unordered_map &old2NewBB, BB &bb, - const BB &exitBB, BB &newHeadBB); - void CopyLoopBody(BB &newHeadBB, std::unordered_map &old2NewBB, - std::set &labelBBs, const BB &exitBB, bool copyAllLoop); - void CopyLoopBodyForProfile(BB &newHeadBB, std::unordered_map &old2NewBB, - std::set &labelBBs, const BB &exitBB, bool copyAllLoop); + void ResetOldLabel2NewLabel(std::unordered_map &old2NewBB, BB &bb, const BB &exitBB, BB &newHeadBB); + void ResetOldLabel2NewLabel2(std::unordered_map &old2NewBB, BB &bb, const BB &exitBB, BB &newHeadBB); + void CopyLoopBody(BB &newHeadBB, std::unordered_map &old2NewBB, std::set &labelBBs, + const BB &exitBB, bool copyAllLoop); + void CopyLoopBodyForProfile(BB &newHeadBB, std::unordered_map &old2NewBB, std::set &labelBBs, + const BB &exitBB, bool copyAllLoop); void UpdateCondGotoBB(BB &bb, VarMeExpr &indVar, MeExpr &tripCount, MeExpr &unrollTimeExpr); void UpdateCondGotoStmt(BB &bb, VarMeExpr &indVar, MeExpr &tripCount, MeExpr &unrollTimeExpr, uint32 offset); void CreateIndVarAndCondGotoStmt(CR &cr, CRNode &varNode, BB &preCondGoto, uint32 unrollTime, uint32 i); @@ -85,7 +96,7 @@ class LoopUnrolling { bool canUnroll = true; MeFunction *func; - MeCFG *cfg; + MeCFG *cfg; LoopDesc *loop; MeIRMap *irMap; MapleAllocator mpAllocator; @@ -100,6 +111,7 @@ class LoopUnrolling { bool firstResetForAfterInsertGoto = true; bool resetFreqForUnrollWithVar = false; bool isUnrollWithVar = false; + bool instrumentProf = false; // use instrumented profiling }; class LoopUnrollingExecutor { @@ -109,8 +121,8 @@ class LoopUnrollingExecutor { static bool enableDebug; static bool enableDump; - void ExecuteLoopUnrolling(MeFunction &func, MeIRMap &irMap, - std::map>> &cands, IdentifyLoops &meLoop, const MapleAllocator &alloc); + void ExecuteLoopUnrolling(MeFunction &func, MeIRMap &irMap, std::map>> &cands, + IdentifyLoops &meLoop, const MapleAllocator &alloc); bool IsCFGChange() const { return isCFGChange; } diff --git a/src/mapleall/maple_me/src/bb.cpp b/src/mapleall/maple_me/src/bb.cpp index 7e7e7e5490..290a3c6caa 100644 --- a/src/mapleall/maple_me/src/bb.cpp +++ b/src/mapleall/maple_me/src/bb.cpp @@ -13,10 +13,13 @@ * See the Mulan PSL v2 for more details. */ #include "bb.h" + +#include + +#include "me_ir.h" +#include "me_ssa.h" #include "mempool_allocator.h" #include "ver_symbol.h" -#include "me_ssa.h" -#include "me_ir.h" namespace maple { std::string BB::StrAttribute() const { @@ -80,8 +83,8 @@ 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) { - mod->GetOut() << " freq: " << frequency << " "; + if (Options::profileUse && frequency >= 0) { + mod->GetOut() << " freq: " << frequency << " "; } mod->GetOut() << "]===============\n"; mod->GetOut() << "preds: "; @@ -299,8 +302,8 @@ void BB::MoveAllPredToSucc(BB *newSucc, BB *commonEntry) { } else { while (!GetPred().empty()) { BB *firstPred = GetPred(0); - if (IsSuccBB(*firstPred)) { // avoid replacing twice - firstPred->ReplaceSucc(this, newSucc, true); // firstPred will be removed from this->pred + if (IsSuccBB(*firstPred)) { // avoid replacing twice + firstPred->ReplaceSucc(this, newSucc, true); // firstPred will be removed from this->pred } } } @@ -336,8 +339,8 @@ void BB::MoveAllSuccToPred(BB *newPred, BB *commonExit) { } else { while (!GetSucc().empty()) { BB *firstSucc = GetSucc(0); - if (IsPredBB(*firstSucc)) { // avoid replacing twice - firstSucc->ReplacePred(this, newPred); // firstSucc will be removed from this->succ + if (IsPredBB(*firstSucc)) { // avoid replacing twice + firstSucc->ReplacePred(this, newPred); // firstSucc will be removed from this->succ } } } @@ -476,23 +479,31 @@ void BB::DumpMePhiList(const IRMap *irMap) { } } -// bb frequency is changed in tranform phase -// update its succ frequency by scaled value -void BB::UpdateEdgeFreqs() { +// update edge frequency by scaled value when bb frequency is changed +void BB::UpdateEdgeFreqs(bool updateBBFreqOfSucc) { int len = GetSucc().size(); ASSERT(len == GetSuccFreq().size(), "sanity check"); int64_t succFreqs = 0; for (int i = 0; i < len; i++) { succFreqs += GetSuccFreq()[i]; } - // early return if frequency is consistent - if (len == 0 || succFreqs == GetFrequency()) { - return; - } - for (size_t i = 0; i < len; ++i) { + int diff = abs(succFreqs - GetFrequency()); + if (len == 0 || diff <= 1) return; + int64_t scaledSum = 0; + for (int i = 0; i < len; i++) { int64_t sfreq = GetSuccFreq()[i]; int64_t scalefreq = (succFreqs == 0 ? (frequency / len) : (sfreq * frequency / succFreqs)); + scaledSum += scalefreq; SetSuccFreq(i, scalefreq); + // update succ frequency with new difference if needed + if (updateBBFreqOfSucc) { + auto *succ = GetSucc(i); + int64_t diff = scalefreq - sfreq; + int64_t succBBnewFreq = succ->GetFrequency() + diff; + if (succBBnewFreq >= 0) { + succ->SetFrequency(succBBnewFreq); + } + } } } diff --git a/src/mapleall/maple_me/src/hdse.cpp b/src/mapleall/maple_me/src/hdse.cpp index cbe9b325fc..89cda33a61 100644 --- a/src/mapleall/maple_me/src/hdse.cpp +++ b/src/mapleall/maple_me/src/hdse.cpp @@ -13,20 +13,22 @@ * See the Mulan PSL v2 for more details. */ #include "hdse.h" + #include -#include "ssa_mir_nodes.h" -#include "ver_symbol.h" + #include "irmap.h" -#include "opcode_info.h" #include "mir_preg.h" +#include "opcode_info.h" +#include "ssa_mir_nodes.h" #include "utils.h" +#include "ver_symbol.h" namespace maple { using namespace utils; void HDSE::DetermineUseCounts(MeExpr *x) { if (x->GetMeOp() == kMeOpVar) { - VarMeExpr *varmeexpr = static_cast(x); + VarMeExpr *varmeexpr = static_cast(x); verstUseCounts[varmeexpr->GetVstIdx()]++; return; } @@ -42,7 +44,7 @@ void HDSE::CheckBackSubsCandidacy(DassignMeStmt *dass) { if (dass->GetRHS()->GetMeOp() != kMeOpVar && dass->GetRHS()->GetMeOp() != kMeOpReg) { return; } - ScalarMeExpr *lhsscalar = static_cast(dass->GetLHS()); + ScalarMeExpr *lhsscalar = static_cast(dass->GetLHS()); OriginalSt *ost = lhsscalar->GetOst(); if (!ost->IsLocal()) { return; @@ -51,7 +53,7 @@ void HDSE::CheckBackSubsCandidacy(DassignMeStmt *dass) { if (ty->GetPrimType() == PTY_agg && ty->GetSize() <= 16) { return; } - ScalarMeExpr *rhsscalar = static_cast(dass->GetRHS()); + ScalarMeExpr *rhsscalar = static_cast(dass->GetRHS()); if (rhsscalar->GetDefBy() != kDefByMustDef) { return; } @@ -247,6 +249,13 @@ void HDSE::RemoveNotRequiredStmtsInBB(BB &bb) { } } bb.SetKind(kBBFallthru); + if (UpdateFreq()) { + int64_t succ0Freq = bb.GetSuccFreq()[0]; + bb.GetSuccFreq().resize(1); + bb.SetSuccFreq(0, bb.GetFrequency()); + ASSERT(bb.GetFrequency() >= succ0Freq, "sanity check"); + bb.GetSucc(0)->SetFrequency(bb.GetSucc(0)->GetFrequency() + (bb.GetFrequency() - succ0Freq)); + } } // A ivar contained in stmt if (stmt2NotNullExpr.find(mestmt) != stmt2NotNullExpr.end()) { @@ -269,8 +278,9 @@ void HDSE::RemoveNotRequiredStmtsInBB(BB &bb) { } else { // skip fold conditional branch because it may break recorded IfInfo. bool isPme = mirModule.CurFunction()->GetMeFunc()->GetPreMeFunc() != nullptr; - if (mestmt->IsCondBr() && !isPme) { // see if foldable to unconditional branch - CondGotoMeStmt *condbr = static_cast(mestmt); + if (mestmt->IsCondBr() && !isPme) { // see if foldable to unconditional branch + CondGotoMeStmt *condbr = static_cast(mestmt); + int64_t removedFreq = 0; if (!mirModule.IsJavaModule() && condbr->GetOpnd()->GetMeOp() == kMeOpConst) { CHECK_FATAL(IsPrimitiveInteger(condbr->GetOpnd()->GetPrimType()), "MeHDSE::DseProcess: branch condition must be integer type"); @@ -278,6 +288,9 @@ void HDSE::RemoveNotRequiredStmtsInBB(BB &bb) { (condbr->GetOp() == OP_brfalse && !condbr->GetOpnd()->IsZero())) { // delete the conditional branch BB *succbb = bb.GetSucc().back(); + if (UpdateFreq()) { + removedFreq = bb.GetSuccFreq().back(); + } succbb->RemoveBBFromPred(bb, false); if (succbb->GetPred().empty()) { needUNClean = true; @@ -288,6 +301,9 @@ void HDSE::RemoveNotRequiredStmtsInBB(BB &bb) { } else { // change to unconditional branch BB *succbb = bb.GetSucc().front(); + if (UpdateFreq()) { + removedFreq = bb.GetSuccFreq().front(); + } succbb->RemoveBBFromPred(bb, false); if (succbb->GetPred().empty()) { needUNClean = true; @@ -297,6 +313,11 @@ void HDSE::RemoveNotRequiredStmtsInBB(BB &bb) { GotoMeStmt *gotomestmt = irMap.New(condbr->GetOffset()); bb.ReplaceMeStmt(condbr, gotomestmt); } + if (UpdateFreq()) { + bb.GetSuccFreq().resize(1); + bb.SetSuccFreq(0, bb.GetFrequency()); + bb.GetSucc(0)->SetFrequency(bb.GetSucc(0)->GetFrequency() + removedFreq); + } } else { DetermineUseCounts(condbr->GetOpnd()); } @@ -305,17 +326,17 @@ void HDSE::RemoveNotRequiredStmtsInBB(BB &bb) { DetermineUseCounts(mestmt->GetOpnd(i)); } if (mestmt->GetOp() == OP_dassign) { - CheckBackSubsCandidacy(static_cast(mestmt)); + CheckBackSubsCandidacy(static_cast(mestmt)); } } } mestmt = nextstmt; } // update verstUseCOunts for uses in phi operands - for (std::pair phipair : bb.GetMePhiList()) { + for (std::pair phipair : bb.GetMePhiList()) { if (phipair.second->GetIsLive()) { for (ScalarMeExpr *phiOpnd : phipair.second->GetOpnds()) { - VarMeExpr *varx = dynamic_cast(phiOpnd); + VarMeExpr *varx = dynamic_cast(phiOpnd); if (varx) { verstUseCounts[varx->GetVstIdx()]++; } @@ -334,7 +355,7 @@ bool HDSE::NeedNotNullCheck(MeExpr &meExpr, const BB &bb) { if (meExpr.GetOp() == OP_addrof) { return false; } - if (meExpr.GetOp() == OP_iaddrof && static_cast(meExpr).GetFieldID() > 0) { + if (meExpr.GetOp() == OP_iaddrof && static_cast(meExpr).GetFieldID() > 0) { return false; } @@ -446,8 +467,7 @@ void HDSE::MarkRegDefByStmt(RegMeExpr ®MeExpr) { MarkPhiRequired(regMeExpr.GetDefPhi()); break; case kDefByChi: { - ASSERT(regMeExpr.GetOst()->GetIndirectLev() > 0, - "MarkRegDefByStmt: preg cannot be defined by chi"); + ASSERT(regMeExpr.GetOst()->GetIndirectLev() > 0, "MarkRegDefByStmt: preg cannot be defined by chi"); auto &defChi = regMeExpr.GetDefChi(); MarkChiNodeRequired(defChi); break; @@ -587,8 +607,7 @@ bool HDSE::ExprNonDeletable(const MeExpr &meExpr) const { } case kMeOpVar: { auto &varMeExpr = static_cast(meExpr); - return varMeExpr.IsVolatile() || - (decoupleStatic && varMeExpr.GetOst()->GetMIRSymbol()->IsGlobal()); + return varMeExpr.IsVolatile() || (decoupleStatic && varMeExpr.GetOst()->GetMIRSymbol()->IsGlobal()); } case kMeOpIvar: { auto &opIvar = static_cast(meExpr); @@ -618,7 +637,7 @@ bool HDSE::HasNonDeletableExpr(const MeStmt &meStmt) const { switch (op) { case OP_dassign: { auto &dasgn = static_cast(meStmt); - VarMeExpr *varMeExpr = static_cast(dasgn.GetVarLHS()); + VarMeExpr *varMeExpr = static_cast(dasgn.GetVarLHS()); return (varMeExpr != nullptr && varMeExpr->IsVolatile()) || ExprNonDeletable(*dasgn.GetRHS()) || (hdseKeepRef && dasgn.Propagated()) || dasgn.GetWasMayDassign() || (decoupleStatic && varMeExpr != nullptr && varMeExpr->GetOst()->GetMIRSymbol()->IsGlobal()); @@ -632,8 +651,8 @@ bool HDSE::HasNonDeletableExpr(const MeStmt &meStmt) const { case OP_iassign: { auto &iasgn = static_cast(meStmt); auto &ivarMeExpr = static_cast(*iasgn.GetLHSVal()); - return ivarMeExpr.IsVolatile() || ivarMeExpr.IsFinal() || - ExprNonDeletable(*iasgn.GetLHSVal()->GetBase()) || ExprNonDeletable(*iasgn.GetRHS()); + return ivarMeExpr.IsVolatile() || ivarMeExpr.IsFinal() || ExprNonDeletable(*iasgn.GetLHSVal()->GetBase()) || + ExprNonDeletable(*iasgn.GetRHS()); } default: return false; @@ -862,4 +881,4 @@ void HDSE::DoHDSE() { } RemoveNotRequiredStmts(); } -} // namespace maple +} // namespace maple diff --git a/src/mapleall/maple_me/src/me_bb_layout.cpp b/src/mapleall/maple_me/src/me_bb_layout.cpp index 850a013b07..8c5612db86 100644 --- a/src/mapleall/maple_me/src/me_bb_layout.cpp +++ b/src/mapleall/maple_me/src/me_bb_layout.cpp @@ -13,13 +13,14 @@ * See the Mulan PSL v2 for more details. */ #include "me_bb_layout.h" -#include "me_cfg.h" + #include "bb.h" +#include "maple_phase.h" +#include "me_cfg.h" +#include "me_critical_edge.h" #include "me_irmap.h" #include "me_option.h" #include "me_predict.h" -#include "maple_phase.h" -#include "me_critical_edge.h" // This BB layout strategy strictly obeys source ordering when inside try blocks. // This Optimization will reorder the bb layout. it start from the first bb of func. @@ -114,12 +115,10 @@ void BBLayout::BuildChainForLoops() { auto &loops = meLoop->GetMeLoops(); // sort loops from inner most to outer most // need use the same sort rules as prediction? - std::stable_sort(loops.begin(), loops.end(), [](const LoopDesc *loop1, const LoopDesc *loop2) { - return loop1->nestDepth > loop2->nestDepth; - }); + std::stable_sort(loops.begin(), loops.end(), + [](const LoopDesc *loop1, const LoopDesc *loop2) { return loop1->nestDepth > loop2->nestDepth; }); // build chain for loops one by one - auto *context = - layoutAlloc.GetMemPool()->New>(cfg->NumBBs(), false, layoutAlloc.Adapter()); + auto *context = layoutAlloc.GetMemPool()->New>(cfg->NumBBs(), false, layoutAlloc.Adapter()); for (auto *loop : loops) { BuildChainForLoop(loop, context); } @@ -188,13 +187,13 @@ void BBLayout::DoBuildChain(const BB &header, BBChain &chain, const MapleVector< } bool BBLayout::IsCandidateSucc(const BB &bb, const BB &succ, const MapleVector *context) { - if (!IsBBInCurrContext(succ, context)) { // succ must be in the current context (current loop or current func) + if (!IsBBInCurrContext(succ, context)) { // succ must be in the current context (current loop or current func) return false; } - if (bb2chain[succ.GetBBId()] == bb2chain[bb.GetBBId()]) { // bb and succ should belong to different chains + if (bb2chain[succ.GetBBId()] == bb2chain[bb.GetBBId()]) { // bb and succ should belong to different chains return false; } - if (succ.GetBBId() == 1) { // special case, exclude common exit BB + if (succ.GetBBId() == 1) { // special case, exclude common exit BB return false; } return true; @@ -240,7 +239,7 @@ BB *BBLayout::GetBestSucc(BB &bb, const BBChain &chain, const MapleVector continue; } uint32 currEdgeFreq = static_cast(bb.GetEdgeFreq(i)); // attention: entryBB->succFreq[i] is always 0 - if (bb.GetBBId() == 0) { // special case for common entry BB + if (bb.GetBBId() == 0) { // special case for common entry BB CHECK_FATAL(bb.GetSucc().size() == 1, "common entry BB should not have more than 1 succ"); bestSucc = succ; break; @@ -253,7 +252,7 @@ BB *BBLayout::GetBestSucc(BB &bb, const BBChain &chain, const MapleVector if (bestSucc != nullptr) { if (debugChainLayout) { LogInfo::MapleLogger() << "Select [range1 succ ]: "; - LogInfo::MapleLogger() << bb.GetBBId() << " -> " << bestSucc->GetBBId() << std::endl; + LogInfo::MapleLogger() << bb.GetBBId() << " -> " << bestSucc->GetBBId() << std::endl; } return bestSucc; } @@ -267,12 +266,12 @@ BB *BBLayout::GetBestSucc(BB &bb, const BBChain &chain, const MapleVector continue; } bool useBBFreq = false; - if (useBBFreq) { // use bb freq + if (useBBFreq) { // use bb freq if (header->GetFrequency() > bestFreq) { // find max bb freq bestFreq = header->GetFrequency(); bestSucc = header; } - } else { // use edge freq + } else { // use edge freq uint32 subBestFreq = 0; for (auto *pred : header->GetPred()) { uint32 curFreq = static_cast(pred->GetEdgeFreq(header)); @@ -595,8 +594,7 @@ void BBLayout::OptimizeBranchTarget(BB &bb) { // condgoto's succ layout: [0] fallthru succ, [1] target succ, [2-...] eh succ/wontexit succ // goto's succ layout: [0] target succ, [1-...] eh succ/wontexit succ BB *brTargetBB = bb.GetKind() == kBBCondGoto ? bb.GetSucc(1) : bb.GetSucc(0); - CHECK_FATAL((bb.GetKind() != kBBCondGoto || bb.GetSucc(1) != bb.GetSucc(0)), - "target is same as fallthru"); + CHECK_FATAL((bb.GetKind() != kBBCondGoto || bb.GetSucc(1) != bb.GetSucc(0)), "target is same as fallthru"); if (brTargetBB->GetAttributes(kBBAttrWontExit)) { return; } @@ -608,8 +606,7 @@ void BBLayout::OptimizeBranchTarget(BB &bb) { bbVisited[bb.GetBBId().GetIdx()] = true; OptimizeBranchTarget(*brTargetBB); // optimize stmt - BB *newTargetBB = - (brTargetBB->GetKind() == kBBCondGoto) ? brTargetBB->GetSucc(1) : brTargetBB->GetSucc(0); + BB *newTargetBB = (brTargetBB->GetKind() == kBBCondGoto) ? brTargetBB->GetSucc(1) : brTargetBB->GetSucc(0); if (newTargetBB == brTargetBB) { return; } @@ -682,7 +679,7 @@ void BBLayout::AddBB(BB &bb) { // If the pred bb is goto bb and the target bb of goto bb is the current bb which is be added to layoutBBs, change the // goto bb to fallthru bb. if (layoutBBs.size() > 1) { - BB *predBB = layoutBBs.at(layoutBBs.size() - 2); // Get the pred of bb. + BB *predBB = layoutBBs.at(layoutBBs.size() - 2); // Get the pred of bb. if (predBB->GetKind() != kBBGoto) { return; } @@ -880,7 +877,6 @@ void BBLayout::RemoveUnreachable(BB &bb) { } } - void BBLayout::UpdateNewBBWithAttrTry(const BB &bb, BB &fallthru) const { auto tryBB = &bb; fallthru.SetAttributes(kBBAttrIsTry); @@ -945,6 +941,9 @@ BB *BBLayout::CreateGotoBBAfterCondBB(BB &bb, BB &fallthru) { index--; fallthru.AddPred(*newFallthru, index); newFallthru->SetFrequency(fallthru.GetFrequency()); + if (cfg->UpdateCFGFreq()) { + newFallthru->PushBackSuccFreq(fallthru.GetFrequency()); + } if (enabledDebug) { LogInfo::MapleLogger() << "Created fallthru and goto original fallthru" << '\n'; } @@ -954,7 +953,9 @@ BB *BBLayout::CreateGotoBBAfterCondBB(BB &bb, BB &fallthru) { } void BBLayout::OptimizeEmptyFallThruBB(BB &bb) { - if (needDealWithTryBB) { return; } + if (needDealWithTryBB) { + return; + } auto *fallthru = bb.GetSucc().front(); while (fallthru && (fallthru->GetPred().size() == 1) && (BBEmptyAndFallthru(*fallthru) || BBContainsOnlyGoto(*fallthru)) && @@ -964,7 +965,7 @@ void BBLayout::OptimizeEmptyFallThruBB(BB &bb) { bb.ReplaceSucc(fallthru, newFallthru); ASSERT(fallthru->GetPred().empty(), "fallthru should not has other pred"); ChangeToFallthruFromCondGoto(bb); - bb.GetSucc().resize(1); // resize succ to 1 + bb.GetSucc().resize(1); // resize succ to 1 } else if (newFallthru->GetPred().size() == 1) { if (newFallthru->GetBBLabel() != 0) { // reset newFallthru label @@ -982,7 +983,7 @@ void BBLayout::OptimizeEmptyFallThruBB(BB &bb) { } void BBLayout::DumpBBPhyOrder() const { - LogInfo::MapleLogger() << func.GetName() << " final BB order " << '\n'; + LogInfo::MapleLogger() << func.GetName() << " final BB order " << '\n'; for (auto bb : layoutBBs) { LogInfo::MapleLogger() << bb->GetBBId(); if (bb != layoutBBs.back()) { @@ -1059,8 +1060,7 @@ void BBLayout::LayoutWithoutProf() { } ASSERT(!(isTry && GetTryOutstanding()), "cannot emit another try if last try has not been ended"); if (nextBB->GetAttributes(kBBAttrIsTryEnd)) { - ASSERT(cfg->GetTryBBFromEndTryBB(nextBB) == nextBB || - IsBBLaidOut(cfg->GetTryBBFromEndTryBB(nextBB)->GetBBId()), + ASSERT(cfg->GetTryBBFromEndTryBB(nextBB) == nextBB || IsBBLaidOut(cfg->GetTryBBFromEndTryBB(nextBB)->GetBBId()), "cannot emit endtry bb before its corresponding try bb"); } } @@ -1204,8 +1204,8 @@ void BBLayout::BuildEdges() { allEdges.emplace_back(layoutAlloc.GetMemPool()->New(bb, dest, w)); } } - std::stable_sort(allEdges.begin(), allEdges.end(), [](const BBEdge *edge1, const BBEdge *edge2) { - return edge1->GetWeight() > edge2->GetWeight(); }); + std::stable_sort(allEdges.begin(), allEdges.end(), + [](const BBEdge *edge1, const BBEdge *edge2) { return edge1->GetWeight() > edge2->GetWeight(); }); } BB *BBLayout::GetBBFromEdges() { @@ -1214,8 +1214,8 @@ BB *BBLayout::GetBBFromEdges() { BB *srcBB = edge->GetSrcBB(); BB *destBB = edge->GetDestBB(); if (enabledDebug) { - LogInfo::MapleLogger() << srcBB->GetBBId() << "->" << destBB->GetBBId() << " freq " - << srcBB->GetEdgeFreq(destBB) << '\n'; + LogInfo::MapleLogger() << srcBB->GetBBId() << "->" << destBB->GetBBId() << " freq " << srcBB->GetEdgeFreq(destBB) + << '\n'; } if (!laidOut[srcBB->GetBBId()]) { @@ -1252,7 +1252,7 @@ BB *BBLayout::NextBBProf(BB &bb) { return NextBBProf(*succBB); } // max freq intial - uint64 maxFreq = 0; + uint64 maxFreq = 0; size_t idx = 0; bool found = false; for (size_t i = 0; i < bb.GetSucc().size(); ++i) { @@ -1282,11 +1282,14 @@ void BBLayout::RebuildFreq() { auto *hook = phase->GetAnalysisInfoHook(); hook->ForceEraseAnalysisPhase(func.GetUniqueID(), &MEDominance::id); hook->ForceEraseAnalysisPhase(func.GetUniqueID(), &MELoopAnalysis::id); - dom = static_cast( - hook->ForceRunAnalysisPhase>(&MEDominance::id, func))->GetResult(); + dom = static_cast(hook->ForceRunAnalysisPhase>(&MEDominance::id, func)) + ->GetResult(); meLoop = static_cast( - hook->ForceRunAnalysisPhase>(&MELoopAnalysis::id, func))->GetResult(); - MePrediction::RebuildFreq(func, *dom, *meLoop); + hook->ForceRunAnalysisPhase>(&MELoopAnalysis::id, func)) + ->GetResult(); + if (!cfg->UpdateCFGFreq()) { + MePrediction::RebuildFreq(func, *dom, *meLoop); + } } void BBLayout::LayoutWithProf(bool useChainLayout) { @@ -1346,8 +1349,7 @@ void BBLayout::VerifyBB() { if (bb->GetKind() == kBBCondGoto) { auto *fallthru = bb->GetSucc(0); auto *targetBB = bb->GetSucc(1); - if (fallthru == targetBB || - (BBEmptyAndFallthru(*fallthru) && (fallthru->GetSucc(0) == targetBB))) { + if (fallthru == targetBB || (BBEmptyAndFallthru(*fallthru) && (fallthru->GetSucc(0) == targetBB))) { LogInfo::MapleLogger() << "WARN: cond BB " << bb->GetBBId() << " has same target"; } } @@ -1375,11 +1377,15 @@ bool MEBBLayout::PhaseRun(maple::MeFunction &f) { bbLayout->RunLayout(); f.SetLaidOutBBs(bbLayout->GetBBs()); - if (DEBUGFUNC_NEWPM(f)) { + if (DEBUGFUNC_NEWPM(f) || Options::profileUse) { // verify CFG : check condBB's succs should be different bbLayout->VerifyBB(); bbLayout->DumpBBPhyOrder(); - cfg->DumpToFile("afterBBLayout", false); + if (cfg->UpdateCFGFreq() && cfg->DumpIRProfileFile()) { + cfg->DumpToFile("after-bblayout", false, true); + } else { + cfg->DumpToFile("afterBBLayout", false); + } } return true; } diff --git a/src/mapleall/maple_me/src/me_cfg.cpp b/src/mapleall/maple_me/src/me_cfg.cpp index f51391906f..192b005f03 100644 --- a/src/mapleall/maple_me/src/me_cfg.cpp +++ b/src/mapleall/maple_me/src/me_cfg.cpp @@ -13,30 +13,33 @@ * See the Mulan PSL v2 for more details. */ #include "me_cfg.h" -#include + #include +#include #include + #include "bb.h" -#include "ssa_mir_nodes.h" -#include "me_irmap.h" -#include "mir_builder.h" #include "me_critical_edge.h" +#include "me_irmap.h" #include "me_loop_canon.h" +#include "mir_builder.h" #include "mir_lower.h" +#include "ssa_mir_nodes.h" namespace { constexpr int kFuncNameLenLimit = 80; } namespace maple { -#define MATCH_STMT(stmt, kOpCode) do { \ - while ((stmt) != nullptr && (stmt)->GetOpCode() == OP_comment) { \ - (stmt) = (stmt)->GetNext(); \ - } \ - if ((stmt) == nullptr || (stmt)->GetOpCode() != (kOpCode)) { \ - return false; \ - } \ -} while (0) // END define +#define MATCH_STMT(stmt, kOpCode) \ + do { \ + while ((stmt) != nullptr && (stmt)->GetOpCode() == OP_comment) { \ + (stmt) = (stmt)->GetNext(); \ + } \ + if ((stmt) == nullptr || (stmt)->GetOpCode() != (kOpCode)) { \ + return false; \ + } \ + } while (0) // END define // determine if need to be replaced by assertnonnull bool MeCFG::IfReplaceWithAssertNonNull(const BB &bb) const { const StmtNode *stmt = bb.GetStmtNodes().begin().d(); @@ -308,7 +311,7 @@ bool MeCFG::FindUse(const StmtNode &stmt, StIdx stIdx) const { return FindExprUse(*iNode.GetRHS(), stIdx); } } - CASE_OP_ASSERT_NONNULL + CASE_OP_ASSERT_NONNULL case OP_eval: case OP_free: case OP_switch: { @@ -511,7 +514,6 @@ void MeCFG::FixMirCFG() { } } - // replace "if() throw NPE()" with assertnonnull void MeCFG::ReplaceWithAssertnonnull() { constexpr char rnnTypeName[] = @@ -681,7 +683,7 @@ void MeCFG::ConvertPhiList2IdentityAssigns(BB &meBB) const { DassignNode *dassign = func.GetMIRModule().GetMIRBuilder()->CreateStmtDassign(*st, 0, dread2); func.GetMeSSATab()->GetStmtsSSAPart().SetSSAPartOf( *dassign, func.GetMeSSATab()->GetStmtsSSAPart().GetSSAPartMp()->New( - &func.GetMeSSATab()->GetStmtsSSAPart().GetSSAPartAlloc())); + &func.GetMeSSATab()->GetStmtsSSAPart().GetSSAPartAlloc())); auto *theSSAPart = static_cast(func.GetMeSSATab()->GetStmtsSSAPart().SSAPartOf(*dassign)); theSSAPart->SetSSAVar(*((*phiIt).second.GetResult())); @@ -700,15 +702,15 @@ void MeCFG::ConvertMePhiList2IdentityAssigns(BB &meBB) const { CHECK_FATAL(ost, "ost is nullptr!"); if (ost->IsSymbolOst() && ost->GetIndirectLev() == 0) { MePhiNode *varPhi = phiIt->second; - auto *dassign = func.GetIRMap()->NewInPool( - static_cast(varPhi->GetLHS()), varPhi->GetOpnd(0)); + auto *dassign = + func.GetIRMap()->NewInPool(static_cast(varPhi->GetLHS()), varPhi->GetOpnd(0)); dassign->SetBB(varPhi->GetDefBB()); dassign->SetIsLive(varPhi->GetIsLive()); meBB.PrependMeStmt(dassign); } else if (ost->IsPregOst()) { MePhiNode *regPhi = phiIt->second; - auto *regAss = func.GetIRMap()->New( - OP_regassign, static_cast(regPhi->GetLHS()), regPhi->GetOpnd(0)); + auto *regAss = func.GetIRMap()->New(OP_regassign, static_cast(regPhi->GetLHS()), + regPhi->GetOpnd(0)); regPhi->GetLHS()->SetDefByStmt(*regAss); regPhi->GetLHS()->SetDefBy(kDefByStmt); regAss->SetBB(regPhi->GetDefBB()); @@ -779,6 +781,10 @@ void MeCFG::WontExitAnalysis() { newBB->SetKindReturn(); newBB->SetAttributes(kBBAttrArtificial); bb->AddSucc(*newBB); + // newBB is added as succ of bb, set freq 0 as its edge frequency + if (updateFreq) { + bb->PushBackSuccFreq(0); + } GetCommonExitBB()->AddExit(*newBB); bb->FindWillExitBBs(currVisitedBBs); // Mark other bbs in the loop as visited. } @@ -835,15 +841,13 @@ void MeCFG::VerifyLabels() const { if (stmtNodes.back().GetOpCode() == OP_throw) { continue; } - ASSERT( - GetLabelBBAt(static_cast(stmtNodes.back()).GetOffset())->GetBBLabel() == - static_cast(stmtNodes.back()).GetOffset(), - "undefined label in goto"); + ASSERT(GetLabelBBAt(static_cast(stmtNodes.back()).GetOffset())->GetBBLabel() == + static_cast(stmtNodes.back()).GetOffset(), + "undefined label in goto"); } else if (mirBB->GetKind() == kBBCondGoto) { - ASSERT( - GetLabelBBAt(static_cast(stmtNodes.back()).GetOffset())->GetBBLabel() == - static_cast(stmtNodes.back()).GetOffset(), - "undefined label in conditional branch"); + ASSERT(GetLabelBBAt(static_cast(stmtNodes.back()).GetOffset())->GetBBLabel() == + static_cast(stmtNodes.back()).GetOffset(), + "undefined label in conditional branch"); } else if (mirBB->GetKind() == kBBSwitch) { auto &switchStmt = static_cast(stmtNodes.back()); LabelIdx targetLabIdx = switchStmt.GetDefaultLabel(); @@ -966,7 +970,7 @@ void MeCFG::DumpToFile(const std::string &prefix, bool dumpInStrs, bool dumpEdge return; } std::ofstream cfgFile; - std::streambuf *coutBuf = LogInfo::MapleLogger().rdbuf(); // keep original cout buffer + std::streambuf *coutBuf = LogInfo::MapleLogger().rdbuf(); // keep original cout buffer std::streambuf *buf = cfgFile.rdbuf(); LogInfo::MapleLogger().rdbuf(buf); const std::string &fileName = ConstructFileNameToDump(prefix); @@ -980,7 +984,8 @@ void MeCFG::DumpToFile(const std::string &prefix, bool dumpInStrs, bool dumpEdge if (bIt == common_exit()) { // specical case for common_exit_bb for (auto it = bb->GetPred().begin(); it != bb->GetPred().end(); ++it) { - cfgFile << "BB" << (*it)->GetBBId()<< " -> " << "BB" << bb->GetBBId() << "[style=dotted];\n"; + cfgFile << "BB" << (*it)->GetBBId() << " -> " + << "BB" << bb->GetBBId() << "[style=dotted];\n"; } continue; } @@ -989,7 +994,8 @@ void MeCFG::DumpToFile(const std::string &prefix, bool dumpInStrs, bool dumpEdge } for (auto it = bb->GetSucc().begin(); it != bb->GetSucc().end(); ++it) { - cfgFile << "BB" << bb->GetBBId() << " -> " << "BB" << (*it)->GetBBId(); + cfgFile << "BB" << bb->GetBBId() << " -> " + << "BB" << (*it)->GetBBId(); if (bb == GetCommonEntryBB()) { cfgFile << "[style=dotted]"; continue; @@ -1013,20 +1019,19 @@ void MeCFG::DumpToFile(const std::string &prefix, bool dumpInStrs, bool dumpEdge } } if (laidOut != nullptr) { - static std::vector colors = { - "indianred1", "darkorange1", "lightyellow1", "green3", "cyan", "dodgerblue2", "purple2" - }; + static std::vector colors = {"indianred1", "darkorange1", "lightyellow1", "green3", + "cyan", "dodgerblue2", "purple2"}; uint32 colorIdx = 0; size_t clusterSize = laidOut->size() / colors.size(); uint32 cnt = 0; for (uint32 i = 0; i < laidOut->size(); ++i) { auto *bb = (*laidOut)[i]; auto bbId = bb->GetBBId(); - std::string bbNameLabel = dumpEdgeFreq ? - "BB" + std::to_string(bbId.GetIdx()) + "_freq_" + std::to_string(bb->GetFrequency()) : - "BB" + std::to_string(bbId.GetIdx()); - cfgFile << "BB" << bbId << "[style=filled, color=" << colors[colorIdx % colors.size()] << ", label=" << - bbNameLabel << "__" << i << "]\n"; + std::string bbNameLabel = + dumpEdgeFreq ? "BB" + std::to_string(bbId.GetIdx()) + "_freq_" + std::to_string(bb->GetFrequency()) + : "BB" + std::to_string(bbId.GetIdx()); + cfgFile << "BB" << bbId << "[style=filled, color=" << colors[colorIdx % colors.size()] + << ", label=" << bbNameLabel << "__" << i << "]\n"; ++cnt; if (cnt > clusterSize) { cnt = 0; @@ -1147,8 +1152,8 @@ bool MeCFG::UnifyRetBBs() { if (func.GetMirFunc()->IsReturnVoid()) { newRetBB->SetFirst(mirBuilder->CreateStmtReturn(nullptr)); } else { - unifiedFuncRet = mirBuilder->CreateSymbol(func.GetMirFunc()->GetReturnTyIdx(), "unified_func_ret", - kStVar, kScAuto, func.GetMirFunc(), kScopeLocal); + unifiedFuncRet = mirBuilder->CreateSymbol(func.GetMirFunc()->GetReturnTyIdx(), "unified_func_ret", kStVar, kScAuto, + func.GetMirFunc(), kScopeLocal); newRetBB->SetFirst(mirBuilder->CreateStmtReturn(mirBuilder->CreateExprDread(*unifiedFuncRet))); } newRetBB->SetLast(newRetBB->GetStmtNodes().begin().d()); @@ -1364,8 +1369,8 @@ void MeCFG::CreateBasicBlocks() { } break; } - // fall thru to handle as return - [[clang::fallthrough]]; + // fall thru to handle as return + [[clang::fallthrough]]; case OP_gosub: case OP_retsub: case OP_return: { @@ -1397,7 +1402,7 @@ void MeCFG::CreateBasicBlocks() { if (!curBB->IsEmpty()) { StmtNode *lastStmt = stmt->GetPrev(); ASSERT(curBB->GetStmtNodes().rbegin().base().d() == nullptr || - curBB->GetStmtNodes().rbegin().base().d() == lastStmt, + curBB->GetStmtNodes().rbegin().base().d() == lastStmt, "something wrong building BB"); curBB->SetLast(lastStmt); if (curBB->GetKind() == kBBUnknown) { @@ -1430,7 +1435,7 @@ void MeCFG::CreateBasicBlocks() { // prepare a new bb StmtNode *lastStmt = stmt->GetPrev(); ASSERT(curBB->GetStmtNodes().rbegin().base().d() == nullptr || - curBB->GetStmtNodes().rbegin().base().d() == lastStmt, + curBB->GetStmtNodes().rbegin().base().d() == lastStmt, "something wrong building BB"); curBB->SetLast(lastStmt); if (curBB->GetKind() == kBBUnknown) { @@ -1461,7 +1466,7 @@ void MeCFG::CreateBasicBlocks() { // prepare a new bb StmtNode *lastStmt = stmt->GetPrev(); ASSERT(curBB->GetStmtNodes().rbegin().base().d() == nullptr || - curBB->GetStmtNodes().rbegin().base().d() == lastStmt, + curBB->GetStmtNodes().rbegin().base().d() == lastStmt, "something wrong building BB"); curBB->SetLast(lastStmt); if (curBB->GetKind() == kBBUnknown) { @@ -1592,7 +1597,7 @@ void MeCFG::CreateBasicBlocks() { } } } while (nextStmt != nullptr); - ASSERT(tryStmt == nullptr, "unclosed try"); // tryandendtry should be one-one mapping + ASSERT(tryStmt == nullptr, "unclosed try"); // tryandendtry should be one-one mapping ASSERT(lastTryBB == nullptr, "unclosed tryBB"); // tryandendtry should be one-one mapping auto *lastBB = curBB; if (lastBB->IsEmpty()) { @@ -1622,8 +1627,7 @@ void MeCFG::BBTopologicalSort(SCCOfBBs &scc) { if (succ == nullptr) { continue; } - if (inQueue.find(succ) != inQueue.end() || - std::find(bbs.begin(), bbs.end(), succ) == bbs.end()) { + if (inQueue.find(succ) != inQueue.end() || std::find(bbs.begin(), bbs.end(), succ) == bbs.end()) { continue; } bool predAllVisited = true; @@ -1651,8 +1655,8 @@ void MeCFG::BBTopologicalSort(SCCOfBBs &scc) { } void MeCFG::BuildSCCDFS(BB &bb, uint32 &visitIndex, std::vector &sccNodes, - std::vector &visitedOrder, std::vector &lowestOrder, - std::vector &inStack, std::stack &visitStack) { + std::vector &visitedOrder, std::vector &lowestOrder, std::vector &inStack, + std::stack &visitStack) { uint32 id = bb.UintID(); visitedOrder[id] = visitIndex; lowestOrder[id] = visitIndex; @@ -1780,7 +1784,7 @@ void MeCFG::UpdateBranchTarget(BB &currBB, const BB &oldTarget, BB &newTarget, M } } else if (currBB.GetKind() == kBBCondGoto) { if (currBB.GetSucc(0) == &newTarget) { - return; // no need to update offset for fallthru BB + return; // no need to update offset for fallthru BB } BB *gotoBB = currBB.GetSucc().at(1); ASSERT(gotoBB == &newTarget, "[FUNC: %s]newTarget is not one of CondGoto's succ BB", func.GetName().c_str()); @@ -1818,7 +1822,7 @@ void MeCFG::UpdateBranchTarget(BB &currBB, const BB &oldTarget, BB &newTarget, M switchStmt.SetDefaultLabel(label); } for (size_t i = 0; i < switchStmt.GetSwitchTable().size(); ++i) { - LabelIdx caseLabel = switchStmt.GetSwitchTable().at(i).second; + LabelIdx caseLabel = switchStmt.GetSwitchTable().at(i).second; if (caseLabel == oldLabelIdx) { switchStmt.UpdateCaseLabelAt(i, label); } @@ -1875,7 +1879,7 @@ void MeCFG::ConstructEdgeFreqFromBBFreq() { // set bb frequency from stmt record void MeCFG::ConstructBBFreqFromStmtFreq() { - FuncProfInfo* funcData = func.GetMirFunc()->GetFuncProfData(); + FuncProfInfo *funcData = func.GetMirFunc()->GetFuncProfData(); if (!funcData) { return; } @@ -1885,13 +1889,14 @@ void MeCFG::ConstructBBFreqFromStmtFreq() { 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 { - LogInfo::MapleLogger() << "ERROR:: bb " << (*bIt)->GetBBId() << "frequency is not set" << "\n"; + LogInfo::MapleLogger() << "ERROR:: bb " << (*bIt)->GetBBId() << "frequency is not set" + << "\n"; ASSERT(0, "no freq set"); } } @@ -1912,10 +1917,13 @@ void MeCFG::ConstructBBFreqFromStmtFreq() { ConstructEdgeFreqFromBBFreq(); // clear stmtFreqs since cfg frequency is create funcData->stmtFreqs.clear(); + + // set updateFrequency with true + updateFreq = true; } void MeCFG::ConstructStmtFreq() { - FuncProfInfo* funcData = func.GetMirFunc()->GetFuncProfData(); + FuncProfInfo *funcData = func.GetMirFunc()->GetFuncProfData(); if (!funcData) { return; } @@ -1931,8 +1939,7 @@ void MeCFG::ConstructStmtFreq() { for (auto &stmt : bb->GetStmtNodes()) { Opcode op = stmt.GetOpCode(); // record bb start/end stmt - if (stmt.GetStmtID() == bb->GetFirst().GetStmtID() || - stmt.GetStmtID() == bb->GetLast().GetStmtID() || + if (stmt.GetStmtID() == bb->GetFirst().GetStmtID() || stmt.GetStmtID() == bb->GetLast().GetStmtID() || IsCallAssigned(op) || op == OP_call) { funcData->stmtFreqs[stmt.GetStmtID()] = bb->GetFrequency(); } @@ -1942,39 +1949,105 @@ void MeCFG::ConstructStmtFreq() { // bb frequency may be changed in transform phase, // update edgeFreq with new BB frequency by scale -void MeCFG::UpdateEdgeFreqWithNewBBFreq() { - for (size_t idx = 0; idx < bbVec.size(); ++idx) { - BB *currBB = bbVec[idx]; - if (currBB == nullptr || currBB->GetSucc().empty()) { +void MeCFG::UpdateEdgeFreqWithBBFreq() { + BuildSCC(); + for (size_t i = 0; i < GetSccTopologicalVec().size(); ++i) { + SCCOfBBs *scc = GetSccTopologicalVec()[i]; + CHECK_FATAL(scc != nullptr, "scc must not be null"); + if (scc->GetBBs().size() > 1) { + BBTopologicalSort(*scc); + } + const uint32 maxLoopCount = 2; + unsigned loopCount = scc->GetBBs().size() > 1 ? maxLoopCount : 1; + for (unsigned j = 0; j < loopCount; ++j) { + for (BB *bb : scc->GetBBs()) { + if (bb == nullptr) { + continue; + } + // collect pred total except entry + if (!bb->GetAttributes(kBBAttrIsEntry)) { + int64_t inputFreq = 0; + for (auto *pred : bb->GetPred()) { + int idx = pred->GetSuccIndex(*bb); + ASSERT(idx >= 0 && idx < pred->GetSuccFreq().size(), "sanity check"); + inputFreq += pred->GetSuccFreq()[idx]; + } + bb->SetFrequency(inputFreq); + } + // make bb frequency and succs frequency consistent + bb->UpdateEdgeFreqs(false); + } + } + } +} + +void MeCFG::ClearFuncFreqInfo() { + SetUpdateCFGFreq(false); + func.GetMirFunc()->SetFuncProfData(nullptr); + auto &bbVec = GetAllBBs(); + for (size_t i = 0; i < bbVec.size(); ++i) { // skip common entry and common exit + auto *bb = bbVec[i]; + if (bb == nullptr) { continue; } - // make bb frequency and succs frequency consistent - currBB->UpdateEdgeFreqs(); + bb->SetFrequency(0); + bb->GetSuccFreq().clear(); } } -void MeCFG::VerifyBBFreq() { +// return value is 0 means pass verification, else has problem +int MeCFG::VerifyBBFreq(bool checkFatal) { + int64_t entryFreq = func.GetMirFunc()->GetFuncProfData()->GetFuncFrequency(); + ASSERT(entryFreq >= 0, "sanity check"); + bool entryIsZero = entryFreq == 0 ? true : false; for (size_t i = 2; i < bbVec.size(); ++i) { // skip common entry and common exit auto *bb = bbVec[i]; if (bb == nullptr || bb->GetAttributes(kBBAttrIsEntry) || bb->GetAttributes(kBBAttrIsExit)) { continue; } - // wontexit bb may has wrong succ, skip it + // check case 1: entry count is zero, internal bb has frequency value > 0 + if (entryIsZero && bb->GetFrequency() > 0) { + if (checkFatal) { + LogInfo::MapleLogger() << func.GetName() << "wrong BB " << bb->GetBBId() << std::endl; + CHECK_FATAL(false, "VerifyBBFreq: function entryFreq is zero but internal bb frequency > 0"); + } else { + ClearFuncFreqInfo(); + return 1; + } + } + // check case 2: bb succ frequence numbers should be equal to succ number except wontexit bb + // may has wrong succ, skip it if (bb->GetSuccFreq().size() != bb->GetSucc().size() && !bb->GetAttributes(kBBAttrWontExit)) { - CHECK_FATAL(false, "VerifyBBFreq: succFreq size != succ size"); + if (checkFatal) { + LogInfo::MapleLogger() << func.GetName() << "wrong BB " << bb->GetBBId() << std::endl; + CHECK_FATAL(false, "VerifyBBFreq: succFreq size != succ size"); + } else { + ClearFuncFreqInfo(); + return 1; + } } - // bb freq == sum(out edge freq) + // check case 3: bb freq == sum(out edge freq) uint64 succSumFreq = 0; for (auto succFreq : bb->GetSuccFreq()) { succSumFreq += succFreq; } if (succSumFreq != bb->GetFrequency()) { - LogInfo::MapleLogger() << "[VerifyFreq failure] BB" << bb->GetBBId() << " freq: " << - bb->GetFrequency() << ", all succ edge freq sum: " << succSumFreq << std::endl; - LogInfo::MapleLogger() << func.GetName() << std::endl; - CHECK_FATAL(false, "VerifyFreq failure: bb freq != succ freq sum"); + int diff = succSumFreq - bb->GetFrequency(); + diff = diff >= 0 ? diff : -diff; + if (diff > 1) { + if (checkFatal) { + LogInfo::MapleLogger() << func.GetName() << "wrong BB " << bb->GetBBId() << std::endl; + LogInfo::MapleLogger() << " freq: " << bb->GetFrequency() << ", all succ edge freq sum: " << succSumFreq + << std::endl; + CHECK_FATAL(false, "VerifyFreq failure: bb freq != succ freq sum"); + } else { + ClearFuncFreqInfo(); + return 1; + } + } } } + return 0; } bool MEMeCfg::PhaseRun(MeFunction &f) { @@ -2008,31 +2081,33 @@ bool MEMeCfg::PhaseRun(MeFunction &f) { if (!f.GetMIRModule().IsJavaModule() && MeOption::unifyRets) { theCFG->UnifyRetBBs(); } + theCFG->Verify(); // construct bb freq from stmt freq if (Options::profileUse && f.GetMirFunc()->GetFuncProfData()) { theCFG->ConstructBBFreqFromStmtFreq(); + if (theCFG->DumpIRProfileFile()) { + std::string fileName = "after-mecfgbuild"; + if (f.IsPme()) { + fileName.append("-lfo"); + } else { + fileName.append("-mplme"); + } + theCFG->DumpToFile(fileName, false, true); + } } - theCFG->Verify(); return false; } bool MECfgVerifyFrequency::PhaseRun(MeFunction &f) { - if (Options::profileUse && f.GetMirFunc()->GetFuncProfData()) { + // if transform pass is not fully support, set disableFreqInfo to true + // function profile information will be deleted after verification phase + bool disableFreqInfo = false; + if (f.GetCfg()->UpdateCFGFreq()) { f.GetCfg()->VerifyBBFreq(); } - // hack code here: no use profile data after verifycation pass since - // following tranform phases related of cfg change are not touched - f.GetMirFunc()->SetFuncProfData(nullptr); - auto &bbVec = f.GetCfg()->GetAllBBs(); - for (size_t i = 0; i < bbVec.size(); ++i) { // skip common entry and common exit - auto *bb = bbVec[i]; - if (bb == nullptr) { - continue; - } - bb->SetFrequency(0); - bb->GetSuccFreq().clear(); - } - + if (!disableFreqInfo) return false; + // clear function profile information + f.GetCfg()->ClearFuncFreqInfo(); return false; } } // namespace maple diff --git a/src/mapleall/maple_me/src/me_critical_edge.cpp b/src/mapleall/maple_me/src/me_critical_edge.cpp index e47078d693..4dca8f82a2 100644 --- a/src/mapleall/maple_me/src/me_critical_edge.cpp +++ b/src/mapleall/maple_me/src/me_critical_edge.cpp @@ -13,13 +13,15 @@ * See the Mulan PSL v2 for more details. */ #include "me_critical_edge.h" + #include + #include "me_cfg.h" -#include "me_option.h" #include "me_dominance.h" #include "me_function.h" -#include "me_loop_analysis.h" #include "me_irmap.h" +#include "me_loop_analysis.h" +#include "me_option.h" // This phase finds critical edges and split them into two, because their // presence would restrict the optimizations performed by SSAPRE-based phases. @@ -98,8 +100,8 @@ void MeSplitCEdge::UpdateCaseLabel(BB &newBB, MeFunction &func, BB &pred, BB &su } } -void MeSplitCEdge::DealWithTryBB(const MeFunction &func, BB &pred, - BB &succ, BB *&newBB, bool &isInsertAfterPred) const { +void MeSplitCEdge::DealWithTryBB(const MeFunction &func, BB &pred, BB &succ, BB *&newBB, + bool &isInsertAfterPred) const { if ((!succ.GetStmtNodes().empty() && succ.GetStmtNodes().front().GetOpCode() == OP_try) || (!succ.IsMeStmtEmpty() && succ.GetFirstMe()->GetOp() == OP_try)) { newBB = &func.GetCfg()->InsertNewBasicBlock(pred, false); @@ -117,8 +119,8 @@ void MeSplitCEdge::DealWithTryBB(const MeFunction &func, BB &pred, void MeSplitCEdge::BreakCriticalEdge(MeFunction &func, BB &pred, BB &succ) const { if (isDebugFunc) { - LogInfo::MapleLogger() << "******before break : critical edge : BB" << pred.GetBBId() << " -> BB" << - succ.GetBBId() << "\n"; + LogInfo::MapleLogger() << "******before break : critical edge : BB" << pred.GetBBId() << " -> BB" << succ.GetBBId() + << "\n"; pred.Dump(&func.GetMIRModule()); succ.Dump(&func.GetMIRModule()); } @@ -160,8 +162,7 @@ void MeSplitCEdge::BreakCriticalEdge(MeFunction &func, BB &pred, BB &succ) const newBB->SetAttributes(kBBAttrArtificial); // update newBB frequency : copy predBB succFreq as newBB frequency - if (Options::profileUse && func.GetMirFunc()->GetFuncProfData() && - (!(func.IsPme() || func.IsLfo()))) { + if (cfg->UpdateCFGFreq() && (!(func.IsPme() || func.IsLfo()))) { int idx = pred.GetSuccIndex(*newBB); ASSERT(idx >= 0 && idx < pred.GetSucc().size(), "sanity check"); uint64_t freq = pred.GetEdgeFreq(idx); @@ -189,8 +190,7 @@ 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 || - (Options::profileUse && (func.IsPme() || func.IsLfo()))) { + if (Options::profileGen || (Options::profileUse && (func.IsPme() || func.IsLfo()))) { LabelIdx succLabel = succ.GetBBLabel(); ASSERT(succLabel != 0, "succ's label missed"); if (func.GetIRMap() != nullptr) { @@ -306,7 +306,7 @@ bool MESplitCEdge::PhaseRun(maple::MeFunction &f) { mscedge.SplitCriticalEdgeForMeFunc(f); if (Options::profileUse) { if ((f.IsPme() || f.IsLfo()) && f.GetPreMeFunc()) { - // new inserted BB will break while/if label information and IR layout + // new inserted BB break cached while/if label information and IR layout f.GetPreMeFunc()->label2IfInfo.clear(); f.GetPreMeFunc()->label2WhileInfo.clear(); f.GetPreMeFunc()->pmeCreatedIfLabelSet.clear(); diff --git a/src/mapleall/maple_me/src/me_dse.cpp b/src/mapleall/maple_me/src/me_dse.cpp index c2ad027a7e..2d393a9ada 100644 --- a/src/mapleall/maple_me/src/me_dse.cpp +++ b/src/mapleall/maple_me/src/me_dse.cpp @@ -13,6 +13,7 @@ * See the Mulan PSL v2 for more details. */ #include "me_dse.h" + #include namespace maple { @@ -33,7 +34,7 @@ void MeDSE::VerifyPhi() const { const OriginalSt *ost = func.GetMeSSATab()->GetOriginalStFromID(pair.first); CHECK_FATAL(ost, "ost is nullptr!"); CHECK_FATAL(!ost->IsSymbolOst() || ost->GetIndirectLev() != 0, - "phi is live and non-virtual in bb with zero or one pred"); + "phi is live and non-virtual in bb with zero or one pred"); } else if (pair.second.GetPhiOpnds().size() != predBBNums) { ASSERT(false, "phi opnd num is not consistent with pred bb num(need update phi)"); } @@ -71,8 +72,11 @@ bool MEDse::PhaseRun(maple::MeFunction &f) { f.Verify(); // cfg change , invalid results in MeFuncResultMgr if (dse.UpdatedCfg()) { - if (Options::profileUse && f.GetMirFunc()->GetFuncProfData()) { - f.GetCfg()->UpdateEdgeFreqWithNewBBFreq(); + if (f.GetCfg()->UpdateCFGFreq()) { + f.GetCfg()->UpdateEdgeFreqWithBBFreq(); + if (f.GetCfg()->DumpIRProfileFile()) { + f.GetCfg()->DumpToFile(("after-dse" + std::to_string(f.dseRuns)), false, true); + } } GetAnalysisInfoHook()->ForceEraseAnalysisPhase(f.GetUniqueID(), &MEDominance::id); } diff --git a/src/mapleall/maple_me/src/me_hdse.cpp b/src/mapleall/maple_me/src/me_hdse.cpp index 6283697dd9..9cc7fa1907 100644 --- a/src/mapleall/maple_me/src/me_hdse.cpp +++ b/src/mapleall/maple_me/src/me_hdse.cpp @@ -13,11 +13,13 @@ * See the Mulan PSL v2 for more details. */ #include "me_hdse.h" + #include + +#include "hdse.h" +#include "me_ssa.h" #include "ssa_mir_nodes.h" #include "ver_symbol.h" -#include "me_ssa.h" -#include "hdse.h" // The hdse phase performs dead store elimination using the well-known algorithm // based on SSA. The algorithm works as follows: @@ -55,7 +57,7 @@ void MeHDSE::ProcessWhileInfos() { if (preMeFunc == nullptr) { return; } - MapleMap::iterator it = preMeFunc->label2WhileInfo.begin(); + MapleMap::iterator it = preMeFunc->label2WhileInfo.begin(); for (; it != preMeFunc->label2WhileInfo.end(); ++it) { if (it->second->initExpr != nullptr && (it->second->initExpr->GetMeOp() == maple::kMeOpVar || it->second->initExpr->GetMeOp() == maple::kMeOpReg)) { @@ -66,7 +68,7 @@ void MeHDSE::ProcessWhileInfos() { void MeHDSE::BackwardSubstitution() { for (DassignMeStmt *dass : backSubsCands) { - ScalarMeExpr *rhsscalar = static_cast(dass->GetRHS()); + ScalarMeExpr *rhsscalar = static_cast(dass->GetRHS()); if (verstUseCounts[rhsscalar->GetVstIdx()] != 1) { continue; } @@ -110,9 +112,8 @@ void MakeEmptyTrysUnreachable(MeFunction &func) { } BB *endTry = *endTryIt; auto &meStmts = tryBB->GetMeStmts(); - if (tryBB->GetAttributes(kBBAttrIsTry) && !meStmts.empty() && - meStmts.front().GetOp() == OP_try && tryBB->GetMePhiList().empty() && - endTry->GetAttributes(kBBAttrIsTryEnd) && endTry->IsMeStmtEmpty()) { + if (tryBB->GetAttributes(kBBAttrIsTry) && !meStmts.empty() && meStmts.front().GetOp() == OP_try && + tryBB->GetMePhiList().empty() && endTry->GetAttributes(kBBAttrIsTryEnd) && endTry->IsMeStmtEmpty()) { // we found a try BB followed by an empty endtry BB BB *targetBB = endTry->GetSucc(0); while (!tryBB->GetPred().empty()) { @@ -190,6 +191,7 @@ bool MEHdse::PhaseRun(maple::MeFunction &f) { MeHDSE hdse = MeHDSE(f, *dom, *hMap, aliasClass, DEBUGFUNC_NEWPM(f)); hdse.hdseKeepRef = MeOption::dseKeepRef; + hdse.SetUpdateFreq(Options::profileUse && f.GetMirFunc()->GetFuncProfData()); if (f.hdseRuns > 2) { hdse.SetRemoveRedefine(true); } @@ -198,6 +200,13 @@ bool MEHdse::PhaseRun(maple::MeFunction &f) { MakeEmptyTrysUnreachable(f); (void)f.GetCfg()->UnreachCodeAnalysis(true); f.GetCfg()->WontExitAnalysis(); + // update frequency + if (hdse.UpdateFreq()) { + f.GetCfg()->UpdateEdgeFreqWithBBFreq(); + if (f.GetCfg()->DumpIRProfileFile()) { + f.GetCfg()->DumpToFile("after-HDSE" + std::to_string(f.hdseRuns), false, true); + } + } if (DEBUGFUNC_NEWPM(f)) { LogInfo::MapleLogger() << "\n============== HDSE =============" << '\n'; f.Dump(false); diff --git a/src/mapleall/maple_me/src/me_loop_canon.cpp b/src/mapleall/maple_me/src/me_loop_canon.cpp index 951da51ee7..05c4b15f8e 100644 --- a/src/mapleall/maple_me/src/me_loop_canon.cpp +++ b/src/mapleall/maple_me/src/me_loop_canon.cpp @@ -13,11 +13,13 @@ * See the Mulan PSL v2 for more details. */ #include "me_loop_canon.h" -#include + #include +#include + #include "me_cfg.h" -#include "me_option.h" #include "me_dominance.h" +#include "me_option.h" #include "me_phase_manager.h" namespace maple { @@ -39,8 +41,7 @@ void MeLoopCanon::FindHeadBBs(Dominance &dom, const BB *bb, std::mapGetBBLabel() != 0) { - const MapleUnorderedSet &addrTakenLabels = - func.GetMirFunc()->GetLabelTab()->GetAddrTakenLabels(); + const MapleUnorderedSet &addrTakenLabels = func.GetMirFunc()->GetLabelTab()->GetAddrTakenLabels(); if (addrTakenLabels.find(bb->GetBBLabel()) != addrTakenLabels.end()) { hasIgoto = true; } @@ -71,8 +72,7 @@ void MeLoopCanon::UpdateTheOffsetOfStmtWhenTargetBBIsChange(BB &curBB, const BB static_cast(lastStmt).GetOffset() == oldSuccBB.GetBBLabel()) { auto label = func.GetOrCreateBBLabel(newSuccBB); static_cast(lastStmt).SetOffset(label); - } else if (lastStmt.GetOp() == OP_goto && - static_cast(lastStmt).GetOffset() == oldSuccBB.GetBBLabel()) { + } else if (lastStmt.GetOp() == OP_goto && static_cast(lastStmt).GetOffset() == oldSuccBB.GetBBLabel()) { auto label = func.GetOrCreateBBLabel(newSuccBB); static_cast(lastStmt).SetOffset(label); } else if (lastStmt.GetOp() == OP_switch) { @@ -96,8 +96,19 @@ void MeLoopCanon::SplitPreds(const std::vector &splitList, BB *splittedBB, // quick split auto *pred = splitList[0]; auto index = pred->GetSuccIndex(*splittedBB); + // add frequency to mergedBB + if (updateFreqs) { + int idx = pred->GetSuccIndex(*splittedBB); + ASSERT(idx >= 0 && idx < pred->GetSucc().size(), "sanity check"); + uint64_t freq = pred->GetEdgeFreq(idx); + mergedBB->SetFrequency(freq); + mergedBB->PushBackSuccFreq(freq); + } splittedBB->ReplacePred(pred, mergedBB); pred->AddSucc(*mergedBB, static_cast(static_cast(index))); + if (updateFreqs) { + pred->AddSuccFreq(mergedBB->GetFrequency(), static_cast(static_cast(index))); + } if (!pred->GetMeStmts().empty()) { UpdateTheOffsetOfStmtWhenTargetBBIsChange(*pred, *splittedBB, *mergedBB); } @@ -112,6 +123,7 @@ void MeLoopCanon::SplitPreds(const std::vector &splitList, BB *splittedBB, mergedBB->GetMePhiList().emplace(latchLhs->GetOstIdx(), latchPhi); phiIter.second->GetOpnds().push_back(latchLhs); } + uint64_t freq = 0; for (BB *pred : splitList) { auto pos = splittedBB->GetPredIndex(*pred); for (auto &phiIter : mergedBB->GetMePhiList()) { @@ -119,7 +131,17 @@ void MeLoopCanon::SplitPreds(const std::vector &splitList, BB *splittedBB, phiIter.second->GetOpnds().push_back(splittedBB->GetMePhiList().at(phiIter.first)->GetOpnd(pos)); } splittedBB->RemovePhiOpnd(pos); + if (updateFreqs) { + int idx = pred->GetSuccIndex(*splittedBB); + ASSERT(idx >= 0 && idx < pred->GetSucc().size(), "sanity check"); + freq = pred->GetEdgeFreq(idx); + mergedBB->SetFrequency(mergedBB->GetFrequency() + freq); + } pred->ReplaceSucc(splittedBB, mergedBB); + if (updateFreqs) { + int idx = pred->GetSuccIndex(*mergedBB); + pred->SetSuccFreq(idx, freq); + } if (pred->GetMeStmts().empty()) { continue; } @@ -141,6 +163,9 @@ void MeLoopCanon::SplitPreds(const std::vector &splitList, BB *splittedBB, } } splittedBB->AddPred(*mergedBB); + if (updateFreqs) { + mergedBB->PushBackSuccFreq(mergedBB->GetFrequency()); + } isCFGChange = true; } @@ -151,16 +176,14 @@ void MeLoopCanon::Merge(const std::map> &heads) { BB *head = cfg->GetBBFromID(iter->first); // skip case : check latch bb is already added // one pred is preheader bb and the other is latch bb - if ((head->GetPred().size() == 2) && - (head->GetPred(0)->GetAttributes(kBBAttrArtificial)) && - (head->GetPred(0)->GetKind() == kBBFallthru) && - (head->GetPred(1)->GetAttributes(kBBAttrArtificial)) && + if ((head->GetPred().size() == 2) && (head->GetPred(0)->GetAttributes(kBBAttrArtificial)) && + (head->GetPred(0)->GetKind() == kBBFallthru) && (head->GetPred(1)->GetAttributes(kBBAttrArtificial)) && (head->GetPred(1)->GetKind() == kBBFallthru)) { continue; } auto *latchBB = cfg->NewBasicBlock(); latchBB->SetAttributes(kBBAttrArtificial); - latchBB->SetAttributes(kBBAttrIsInLoop); // latchBB is inloop + latchBB->SetAttributes(kBBAttrIsInLoop); // latchBB is inloop latchBB->SetKind(kBBFallthru); SplitPreds(iter->second, head, latchBB); } @@ -244,8 +267,17 @@ void MeLoopCanon::InsertExitBB(LoopDesc &loop) { BB *newExitBB = cfg->NewBasicBlock(); newExitBB->SetKind(kBBFallthru); auto pos = succ->GetPredIndex(*curBB); + uint64_t freq = 0; + if (updateFreqs) { + int idx = curBB->GetSuccIndex(*succ); + freq = curBB->GetSuccFreq()[idx]; + } curBB->ReplaceSucc(succ, newExitBB); succ->AddPred(*newExitBB, pos); + if (updateFreqs) { + newExitBB->SetFrequency(freq); + newExitBB->PushBackSuccFreq(freq); + } if (!curBB->GetMeStmts().empty()) { UpdateTheOffsetOfStmtWhenTargetBBIsChange(*curBB, *succ, *newExitBB); } @@ -299,7 +331,8 @@ bool MELoopCanon::PhaseRun(maple::MeFunction &f) { auto *dom = GET_ANALYSIS(MEDominance, f); ASSERT(dom != nullptr, "dom is null in MeDoLoopCanon::Run"); MemPool *loopCanonMp = GetPhaseMemPool(); - auto *meLoopCanon = loopCanonMp->New(f, DEBUGFUNC_NEWPM(f)); + bool updateFrequency = (Options::profileUse && f.GetMirFunc()->GetFuncProfData()); + auto *meLoopCanon = loopCanonMp->New(f, DEBUGFUNC_NEWPM(f), updateFrequency); // 1. Add preheaderBB and normalization headBB for loop. meLoopCanon->NormalizationHeadAndPreHeaderOfLoop(*dom); @@ -316,6 +349,9 @@ bool MELoopCanon::PhaseRun(maple::MeFunction &f) { meLoopCanon->NormalizationExitOfLoop(*meLoop); if (meLoopCanon->IsCFGChange()) { GetAnalysisInfoHook()->ForceEraseAnalysisPhase(f.GetUniqueID(), &MEDominance::id); + if (updateFrequency && (f.GetCfg()->DumpIRProfileFile())) { + f.GetCfg()->DumpToFile("after-loopcanon", false, true); + } } return true; } diff --git a/src/mapleall/maple_me/src/me_loop_inversion.cpp b/src/mapleall/maple_me/src/me_loop_inversion.cpp index 23a572736d..8da6423c2a 100644 --- a/src/mapleall/maple_me/src/me_loop_inversion.cpp +++ b/src/mapleall/maple_me/src/me_loop_inversion.cpp @@ -13,11 +13,13 @@ * See the Mulan PSL v2 for more details. */ #include "me_loop_inversion.h" -#include + #include +#include + #include "me_cfg.h" -#include "me_option.h" #include "me_dominance.h" +#include "me_option.h" #include "me_phase_manager.h" namespace maple { @@ -121,8 +123,7 @@ void MeLoopInversion::Convert(MeFunction &func, BB &bb, BB &pred, MapleMapfallthru is in loopbody, latchBB need convert condgoto and make original target as its fallthru bool swapSuccOfLatch = (swapSuccs.find(std::make_pair(&bb, &pred)) != swapSuccs.end()); if (isDebugFunc) { - LogInfo::MapleLogger() << "***loop convert: backedge bb->id " << bb.GetBBId() << " pred->id " - << pred.GetBBId(); + LogInfo::MapleLogger() << "***loop convert: backedge bb->id " << bb.GetBBId() << " pred->id " << pred.GetBBId(); if (swapSuccOfLatch) { LogInfo::MapleLogger() << " need swap succs\n"; } else { @@ -132,9 +133,9 @@ void MeLoopInversion::Convert(MeFunction &func, BB &bb, BB &pred, MapleMapNewBasicBlock(); latchBB->SetAttributes(kBBAttrArtificial); - latchBB->SetAttributes(kBBAttrIsInLoop); // latchBB is inloop + latchBB->SetAttributes(kBBAttrIsInLoop); // latchBB is inloop // update newBB frequency : copy predBB succFreq as latch frequency - if (Options::profileUse && func.GetMirFunc()->GetFuncProfData()) { + if (func.GetCfg()->UpdateCFGFreq()) { int idx = pred.GetSuccIndex(bb); ASSERT(idx >= 0 && idx < pred.GetSucc().size(), "sanity check"); uint64_t freq = pred.GetEdgeFreq(idx); @@ -144,7 +145,7 @@ void MeLoopInversion::Convert(MeFunction &func, BB &bb, BB &pred, MapleMapSetKind(bb.GetKind()); // update succFreq - if (Options::profileUse && func.GetMirFunc()->GetFuncProfData()) { - int succFreqSize = bb.GetSuccFreq().size(); - ASSERT(latchBB->GetSucc().size() == succFreqSize, "sanity check"); - // copy bb succFreq as latch frequency - for (int i = 0; i < succFreqSize; i++) { - latchBB->PushBackSuccFreq(bb.GetSuccFreq()[i]); - } - if (bb.GetFrequency() > 0) { - // swap frequency and fixed the frequency value - if (swapSuccOfLatch) { - ASSERT(latchBB->GetKind() == kBBCondGoto, "impossible"); - int64_t newftFreq = (latchBB->GetFrequency() == 0 || bb.GetSuccFreq()[1] == 0) ? 0 : 1; - int64_t newtgFreq = latchBB->GetFrequency() == 0 ? 0 : (latchBB->GetFrequency() - newftFreq); - latchBB->SetSuccFreq(0, newftFreq); - latchBB->SetSuccFreq(1, newtgFreq); // loop is changed to do-while format - int64_t bbsucc0Freq = bb.GetSucc(0)->GetFrequency() - newtgFreq; - int64_t bbsucc1Freq = bb.GetFrequency() - bbsucc0Freq; - bb.SetSuccFreq(0, bbsucc0Freq); - bb.SetSuccFreq(1, bbsucc1Freq); - } else if (latchBB->GetKind() == kBBCondGoto) { - int64_t newftFreq = (latchBB->GetFrequency() == 0 || bb.GetSuccFreq()[0] == 0) ? 0 : 1; - int64_t newtgFreq = latchBB->GetFrequency() == 0 ? 0 : (latchBB->GetFrequency() - newftFreq); - latchBB->SetSuccFreq(0, newftFreq); // freq to exit BB - latchBB->SetSuccFreq(1, newtgFreq); // loop is changed to do-while format - // update bb succ frequency - int64_t bbsucc0Freq = bb.GetSucc(0)->GetFrequency() - newftFreq; - int64_t bbsucc1Freq = bb.GetFrequency() - bbsucc0Freq; - bb.SetSuccFreq(0, bbsucc0Freq); - bb.SetSuccFreq(1, bbsucc1Freq); - } else if (latchBB->GetKind() == kBBFallthru || latchBB->GetKind() == kBBGoto) { - int64_t newsuccFreq = (latchBB->GetFrequency() == 0) ? 0 : latchBB->GetSuccFreq()[0] - 1; - latchBB->SetSuccFreq(0, newsuccFreq); // loop is changed to do-while format - bb.SetSuccFreq(0, bb.GetFrequency()); + if (func.GetCfg()->UpdateCFGFreq()) { + if (latchBB->GetKind() == kBBCondGoto) { + BB *succInloop = swapSuccOfLatch ? bb.GetSucc(0) : bb.GetSucc(1); + if ((latchBB->GetFrequency() != 0) && (succInloop->GetFrequency() > 0)) { + // loop is executed, bb->fallthru is in loopbody + int64_t latchFreq = latchBB->GetFrequency(); + if (swapSuccOfLatch) { + // bb fallthru is in loop, frequency of bb -> exitbb is set 0 + bb.SetSuccFreq(0, bb.GetFrequency()); + bb.SetSuccFreq(1, 0); + // latchBB fallthru is loop exit + ASSERT(bb.GetSucc(0)->GetFrequency() >= bb.GetFrequency(), "sanity check"); + int fallthrudiff = bb.GetSucc(0)->GetFrequency() - bb.GetFrequency(); + ASSERT(fallthrudiff >= 0, "sanity check"); + latchBB->PushBackSuccFreq(latchFreq - fallthrudiff); + latchBB->PushBackSuccFreq(fallthrudiff); + } else { + // bb->fallthru is loop exit, edge frequency of bb ->exitbb is set 0 + bb.SetSuccFreq(0, 0); + bb.SetSuccFreq(1, bb.GetFrequency()); + // latchBB fallthru is in loop + int fallthrudiff = bb.GetSucc(1)->GetFrequency() - bb.GetFrequency(); + ASSERT(fallthrudiff >= 0, "sanity check"); + latchBB->PushBackSuccFreq(fallthrudiff); + latchBB->PushBackSuccFreq(latchFreq - fallthrudiff); + } } else { - ASSERT(0, "NYI:: unexpected bb type"); + // loop is not executed + if (latchBB->GetFrequency() != 0) { + if (swapSuccOfLatch) { + bb.SetSuccFreq(0, 0); + bb.SetSuccFreq(1, bb.GetFrequency()); + } else { + bb.SetSuccFreq(0, bb.GetFrequency()); + bb.SetSuccFreq(1, 0); + } + } + ASSERT(latchBB->GetFrequency() == 0, "sanity check"); + latchBB->PushBackSuccFreq(0); + latchBB->PushBackSuccFreq(0); } + } else if (latchBB->GetKind() == kBBFallthru || latchBB->GetKind() == kBBGoto) { + int64_t newsuccFreq = (latchBB->GetFrequency() == 0) ? 0 : latchBB->GetSuccFreq()[0] - 1; + latchBB->SetSuccFreq(0, newsuccFreq); // loop is changed to do-while format + bb.SetSuccFreq(0, bb.GetFrequency()); + } else { + ASSERT(0, "NYI:: unexpected bb type"); } } // swap latchBB's succ if needed @@ -332,8 +344,8 @@ void MeLoopInversion::ExecuteLoopInversion(MeFunction &func, Dominance &dom) { } if ((NeedConvert(&func, *succ, *tmpPred, localAlloc, swapSuccs))) { if (isDebugFunc) { - LogInfo::MapleLogger() << "find new backedge " << succ->GetBBId() - << " <-- " << tmpPred->GetBBId() << '\n'; + LogInfo::MapleLogger() << "find new backedge " << succ->GetBBId() << " <-- " << tmpPred->GetBBId() + << '\n'; } backEdges.push_back(std::make_pair(succ, tmpPred)); } @@ -362,6 +374,9 @@ bool MELoopInversion::PhaseRun(maple::MeFunction &f) { if (meLoopInversion->IsCFGChange()) { GetAnalysisInfoHook()->ForceEraseAnalysisPhase(f.GetUniqueID(), &MEDominance::id); GetAnalysisInfoHook()->ForceEraseAnalysisPhase(f.GetUniqueID(), &MELoopAnalysis::id); + if (f.GetCfg()->UpdateCFGFreq() && (f.GetCfg()->DumpIRProfileFile())) { + f.GetCfg()->DumpToFile("after-loopinversion", false, true); + } } return true; } diff --git a/src/mapleall/maple_me/src/me_loop_unrolling.cpp b/src/mapleall/maple_me/src/me_loop_unrolling.cpp index e398584e28..98a5429af0 100644 --- a/src/mapleall/maple_me/src/me_loop_unrolling.cpp +++ b/src/mapleall/maple_me/src/me_loop_unrolling.cpp @@ -13,13 +13,15 @@ * See the Mulan PSL v2 for more details. */ #include "me_loop_unrolling.h" -#include + #include +#include + #include "me_cfg.h" #include "me_option.h" -#include "mir_module.h" -#include "mir_builder.h" #include "me_phase_manager.h" +#include "mir_builder.h" +#include "mir_module.h" namespace maple { bool LoopUnrollingExecutor::enableDebug = false; @@ -36,13 +38,15 @@ bool ProfileCheck(const maple::MeFunction &f) { auto &profile = f.GetMIRModule().GetProfile(); if (!profile.IsValid()) { if (LoopUnrollingExecutor::enableDebug) { - LogInfo::MapleLogger() << "DeCompress failed in loopUnrolling" << "\n"; + LogInfo::MapleLogger() << "DeCompress failed in loopUnrolling" + << "\n"; } return false; } if (!profile.CheckFuncHot(f.GetName())) { if (LoopUnrollingExecutor::enableDebug) { - LogInfo::MapleLogger() << "func is not hot" << "\n"; + LogInfo::MapleLogger() << "func is not hot" + << "\n"; } return false; } @@ -69,12 +73,12 @@ void LoopUnrolling::ComputeCodeSize(const MeStmt &meStmt, uint32 &cost) { case OP_brfalse: case OP_brtrue: case OP_maydassign: - CASE_OP_ASSERT_BOUNDARY { - cost += kTwoInsn; - break; - } + CASE_OP_ASSERT_BOUNDARY { + cost += kTwoInsn; + break; + } case OP_iassign: - CASE_OP_ASSERT_NONNULL + CASE_OP_ASSERT_NONNULL case OP_membaracquire: { cost += kThreeInsn; break; @@ -99,7 +103,7 @@ void LoopUnrolling::ComputeCodeSize(const MeStmt &meStmt, uint32 &cost) { } default: if (LoopUnrollingExecutor::enableDebug) { - LogInfo::MapleLogger() << "consider this op :"<< meStmt.GetOp() << "\n"; + LogInfo::MapleLogger() << "consider this op :" << meStmt.GetOp() << "\n"; } canUnroll = false; break; @@ -152,8 +156,8 @@ void LoopUnrolling::SetLabelWithCondGotoOrGotoBB(BB &bb, std::unordered_map &old2NewBB, BB &bb, - const BB &exitBB, BB &newHeadBB) { +void LoopUnrolling::ResetOldLabel2NewLabel(std::unordered_map &old2NewBB, BB &bb, const BB &exitBB, + BB &newHeadBB) { if (bb.GetKind() == kBBCondGoto) { CHECK_FATAL(!bb.GetMeStmts().empty(), "must not be empty"); CondGotoMeStmt &condGotoNode = static_cast(bb.GetMeStmts().back()); @@ -174,8 +178,8 @@ void LoopUnrolling::ResetOldLabel2NewLabel(std::unordered_map &old2New } // When loop unroll times more than two, use this function to update the preds and succs of duplicate loopbodys. -void LoopUnrolling::ResetOldLabel2NewLabel2(std::unordered_map &old2NewBB, BB &bb, - const BB &exitBB, BB &newHeadBB) { +void LoopUnrolling::ResetOldLabel2NewLabel2(std::unordered_map &old2NewBB, BB &bb, const BB &exitBB, + BB &newHeadBB) { if (bb.GetKind() == kBBCondGoto) { CHECK_FATAL(!bb.GetMeStmts().empty(), "must not be empty"); CondGotoMeStmt &condGotoNode = static_cast(bb.GetMeStmts().back()); @@ -194,23 +198,22 @@ void LoopUnrolling::ResetOldLabel2NewLabel2(std::unordered_map &old2Ne } } -void LoopUnrolling::ResetFrequency(const BB &curBB, const BB &succ, const BB &exitBB, - BB &curCopyBB, bool copyAllLoop) { +void LoopUnrolling::ResetFrequency(const BB &curBB, const BB &succ, const BB &exitBB, BB &curCopyBB, bool copyAllLoop) { if (resetFreqForUnrollWithVar && copyAllLoop) { if (&curBB == &exitBB && &succ == *loop->inloopBB2exitBBs.begin()->second->begin()) { curCopyBB.PushBackSuccFreq(loop->head->GetFrequency() % replicatedLoopNum == 0 ? 0 : 1); } if ((&curBB == loop->latch && &succ == loop->head) || (&curBB == &exitBB && &succ == loop->latch)) { - curCopyBB.PushBackSuccFreq(loop->head->GetFrequency() % replicatedLoopNum == 0 ? 0 : - loop->head->GetFrequency() % replicatedLoopNum - 1); + curCopyBB.PushBackSuccFreq( + loop->head->GetFrequency() % replicatedLoopNum == 0 ? 0 : loop->head->GetFrequency() % replicatedLoopNum - 1); } else { curCopyBB.PushBackSuccFreq(curBB.GetEdgeFreq(&succ) % replicatedLoopNum); } } else { - profValid && resetFreqForAfterInsertGoto ? - curCopyBB.PushBackSuccFreq(curBB.GetEdgeFreq(&succ) - 1 == 0 ? curBB.GetEdgeFreq(&succ) : - curBB.GetEdgeFreq(&succ) - 1) : - curCopyBB.PushBackSuccFreq(curBB.GetEdgeFreq(&succ)); + profValid &&resetFreqForAfterInsertGoto + ? curCopyBB.PushBackSuccFreq(curBB.GetEdgeFreq(&succ) - 1 == 0 ? curBB.GetEdgeFreq(&succ) + : curBB.GetEdgeFreq(&succ) - 1) + : curCopyBB.PushBackSuccFreq(curBB.GetEdgeFreq(&succ)); } } @@ -252,10 +255,9 @@ void LoopUnrolling::CopyLoopBodyForProfile(BB &newHeadBB, std::unordered_mapSetFrequency(succ->GetFrequency() % replicatedLoopNum); } } else { - resetFreqForAfterInsertGoto ? - newBB->SetFrequency(succ->GetFrequency() - 1 == 0 ? succ->GetFrequency() : - succ->GetFrequency() - 1) : - newBB->SetFrequency(succ->GetFrequency()); + resetFreqForAfterInsertGoto + ? newBB->SetFrequency(succ->GetFrequency() - 1 == 0 ? succ->GetFrequency() : succ->GetFrequency() - 1) + : newBB->SetFrequency(succ->GetFrequency()); } curCopyBB->AddSucc(*newBB); ResetFrequency(*curBB, *succ, exitBB, *curCopyBB, copyAllLoop); @@ -272,8 +274,8 @@ void LoopUnrolling::CopyLoopBodyForProfile(BB &newHeadBB, std::unordered_map &old2NewBB, - std::set &labelBBs, const BB &exitBB, bool copyAllLoop) { +void LoopUnrolling::CopyLoopBody(BB &newHeadBB, std::unordered_map &old2NewBB, std::set &labelBBs, + const BB &exitBB, bool copyAllLoop) { CreateLableAndInsertLabelBB(newHeadBB, labelBBs); std::queue bbQue; bbQue.push(loop->head); @@ -308,13 +310,13 @@ void LoopUnrolling::CopyLoopBody(BB &newHeadBB, std::unordered_map &ol // Update frequency of old BB. void LoopUnrolling::ResetFrequency(BB &bb) { auto freq = bb.GetFrequency() / replicatedLoopNum; - if (freq == 0 && partialCount == 0 && bb.GetFrequency() != 0) { + if ((!instrumentProf) && freq == 0 && partialCount == 0 && bb.GetFrequency() != 0) { freq = 1; } bb.SetFrequency(static_cast(freq + partialCount)); for (size_t i = 0; i < bb.GetSucc().size(); ++i) { auto currFreq = bb.GetEdgeFreq(i) / replicatedLoopNum; - if (currFreq == 0 && partialCount == 0 && bb.GetFrequency() != 0) { + if ((!instrumentProf) && currFreq == 0 && partialCount == 0 && bb.GetFrequency() != 0) { currFreq = 1; } bb.SetEdgeFreq(bb.GetSucc(i), currFreq + partialCount); @@ -366,10 +368,10 @@ void LoopUnrolling::AddEdgeForExitBBLastNew2OldBBEmpty(BB &exitBB, std::unordere bb->ReplaceSucc(&exitBB, &newHeadBB); exitBB.AddPred(*old2NewBB[bb], idx); if (profValid) { - resetFreqForAfterInsertGoto ? - (bb->GetEdgeFreq(idx) - 1 == 0 ? old2NewBB[bb]->PushBackSuccFreq(bb->GetEdgeFreq(idx)) : - old2NewBB[bb]->PushBackSuccFreq(bb->GetEdgeFreq(idx) - 1)) : - old2NewBB[bb]->PushBackSuccFreq(bb->GetEdgeFreq(idx)); + resetFreqForAfterInsertGoto + ? (bb->GetEdgeFreq(idx) - 1 == 0 ? old2NewBB[bb]->PushBackSuccFreq(bb->GetEdgeFreq(idx)) + : old2NewBB[bb]->PushBackSuccFreq(bb->GetEdgeFreq(idx) - 1)) + : old2NewBB[bb]->PushBackSuccFreq(bb->GetEdgeFreq(idx)); } ResetOldLabel2NewLabel(old2NewBB, *bb, exitBB, newHeadBB); } @@ -383,10 +385,10 @@ void LoopUnrolling::AddEdgeForExitBB(BB &exitBB, std::unordered_map &o bb->ReplaceSucc(&exitBB, &newHeadBB); exitBB.AddPred(*old2NewBB[lastNew2OldBB[bb]], idx); if (profValid) { - (resetFreqForAfterInsertGoto && firstResetForAfterInsertGoto) ? - (bb->GetEdgeFreq(idx) - 1 == 0 ? old2NewBB[lastNew2OldBB[bb]]->PushBackSuccFreq(bb->GetEdgeFreq(idx)) : - old2NewBB[lastNew2OldBB[bb]]->PushBackSuccFreq(bb->GetEdgeFreq(idx) - 1)) : - old2NewBB[lastNew2OldBB[bb]]->PushBackSuccFreq(bb->GetEdgeFreq(idx)); + (resetFreqForAfterInsertGoto && firstResetForAfterInsertGoto) + ? (bb->GetEdgeFreq(idx) - 1 == 0 ? old2NewBB[lastNew2OldBB[bb]]->PushBackSuccFreq(bb->GetEdgeFreq(idx)) + : old2NewBB[lastNew2OldBB[bb]]->PushBackSuccFreq(bb->GetEdgeFreq(idx) - 1)) + : old2NewBB[lastNew2OldBB[bb]]->PushBackSuccFreq(bb->GetEdgeFreq(idx)); firstResetForAfterInsertGoto = false; } ResetOldLabel2NewLabel2(old2NewBB, *bb, exitBB, newHeadBB); @@ -403,14 +405,14 @@ void LoopUnrolling::CopyAndInsertBB(bool isPartial) { ResetFrequency(*loop->head); ResetFrequency(); } - profValid && resetFreqForAfterInsertGoto ? - (loop->head->GetFrequency() - 1 == 0 ? newHeadBB->SetFrequency(loop->head->GetFrequency()) : - newHeadBB->SetFrequency(loop->head->GetFrequency() - 1)) : - newHeadBB->SetFrequency(loop->head->GetFrequency()); + profValid &&resetFreqForAfterInsertGoto + ? (loop->head->GetFrequency() - 1 == 0 ? newHeadBB->SetFrequency(loop->head->GetFrequency()) + : newHeadBB->SetFrequency(loop->head->GetFrequency() - 1)) + : newHeadBB->SetFrequency(loop->head->GetFrequency()); (void)old2NewBB.emplace(loop->head, newHeadBB); std::set labelBBs; - profValid ? CopyLoopBodyForProfile(*newHeadBB, old2NewBB, labelBBs, *exitBB, false) : - CopyLoopBody(*newHeadBB, old2NewBB, labelBBs, *exitBB, false); + profValid ? CopyLoopBodyForProfile(*newHeadBB, old2NewBB, labelBBs, *exitBB, false) + : CopyLoopBody(*newHeadBB, old2NewBB, labelBBs, *exitBB, false); if (isPartial) { partialSuccHead = newHeadBB; } @@ -654,7 +656,8 @@ bool LoopUnrolling::LoopPartialUnrollWithConst(uint64 tripCount) { uint32 index = 0; if (!DetermineUnrollTimes(index, true)) { if (LoopUnrollingExecutor::enableDebug) { - LogInfo::MapleLogger() << "CodeSize is too large" << "\n"; + LogInfo::MapleLogger() << "CodeSize is too large" + << "\n"; } return false; } @@ -710,8 +713,8 @@ void LoopUnrolling::CopyLoopForPartialAndPre(BB *&newHead, BB *&newExiting) { (void)old2NewBB.emplace(loop->head, newHeadBB); std::set labelBBs; resetFreqForUnrollWithVar = true; - profValid ? CopyLoopBodyForProfile(*newHeadBB, old2NewBB, labelBBs, *exitBB, true) : - CopyLoopBody(*newHeadBB, old2NewBB, labelBBs, *exitBB, true); + profValid ? CopyLoopBodyForProfile(*newHeadBB, old2NewBB, labelBBs, *exitBB, true) + : CopyLoopBody(*newHeadBB, old2NewBB, labelBBs, *exitBB, true); resetFreqForUnrollWithVar = false; for (auto bb : labelBBs) { if (bb->GetKind() == kBBCondGoto) { @@ -742,8 +745,8 @@ VarMeExpr *LoopUnrolling::CreateIndVarOrTripCountWithName(const std::string &nam } // i < tripcount / unrollTime -void LoopUnrolling::UpdateCondGotoStmt(BB &bb, VarMeExpr &indVar, MeExpr &tripCount, - MeExpr &unrollTimeExpr, uint32 offset) { +void LoopUnrolling::UpdateCondGotoStmt(BB &bb, VarMeExpr &indVar, MeExpr &tripCount, MeExpr &unrollTimeExpr, + uint32 offset) { for (auto &stmt : bb.GetMeStmts()) { bb.RemoveMeStmt(&stmt); } @@ -815,8 +818,8 @@ void LoopUnrolling::CopyLoopForPartial(BB &partialCondGoto, BB &exitedBB, BB &ex partialCondGoto.AddSucc(*partialHead); if (profValid) { partialCondGoto.PushBackSuccFreq(loop->head->GetFrequency() % replicatedLoopNum); - partialCondGoto.SetFrequency(static_cast(partialCondGoto.GetEdgeFreq(static_cast(0)) + - partialCondGoto.GetEdgeFreq(1))); + partialCondGoto.SetFrequency( + static_cast(partialCondGoto.GetEdgeFreq(static_cast(0)) + partialCondGoto.GetEdgeFreq(1))); } CHECK_FATAL(partialCondGoto.GetKind() == kBBCondGoto, "must be partialCondGoto"); CHECK_FATAL(!partialCondGoto.GetMeStmts().empty(), "must not be empty"); @@ -976,17 +979,19 @@ bool LoopUnrolling::LoopPartialUnrollWithVar(CR &cr, CRNode &varNode, uint32 j) uint32 index = 0; if (!DetermineUnrollTimes(index, false)) { if (LoopUnrollingExecutor::enableDebug) { - LogInfo::MapleLogger() << "codesize is too large" << "\n"; + LogInfo::MapleLogger() << "codesize is too large" + << "\n"; } return false; } if (LoopUnrollingExecutor::enableDebug) { - LogInfo::MapleLogger() << "partial unrolling with var" << "\n"; + LogInfo::MapleLogger() << "partial unrolling with var" + << "\n"; } if (LoopUnrollingExecutor::enableDump) { irMap->Dump(); - profValid ? cfg->DumpToFile("cfgIncludeFreqInfobeforeLoopPartialWithVarUnrolling", false, true) : - cfg->DumpToFile("cfgbeforeLoopPartialWithVarUnrolling"); + profValid ? cfg->DumpToFile("cfgIncludeFreqInfobeforeLoopPartialWithVarUnrolling", false, true) + : cfg->DumpToFile("cfgbeforeLoopPartialWithVarUnrolling"); } if (!SplitCondGotoBB()) { return false; @@ -1007,8 +1012,8 @@ bool LoopUnrolling::LoopPartialUnrollWithVar(CR &cr, CRNode &varNode, uint32 j) } if (LoopUnrollingExecutor::enableDump) { irMap->Dump(); - profValid ? cfg->DumpToFile("cfgIncludeFreqInfoafterLoopPartialWithVarUnrolling", false, true) : - cfg->DumpToFile("cfgafterLoopPartialWithVarUnrolling"); + profValid ? cfg->DumpToFile("cfgIncludeFreqInfoafterLoopPartialWithVarUnrolling", false, true) + : cfg->DumpToFile("cfgafterLoopPartialWithVarUnrolling"); } return true; } @@ -1022,7 +1027,7 @@ void LoopUnrollingExecutor::SetNestedLoop(const IdentifyLoops &meLoop, CHECK_NULL_FATAL(loop->parent); auto it = parentLoop.find(loop->parent); if (it == parentLoop.end()) { - parentLoop[loop->parent] = { loop }; + parentLoop[loop->parent] = {loop}; } else { parentLoop[loop->parent].insert(loop); } @@ -1065,7 +1070,8 @@ bool LoopUnrollingExecutor::PredIsOutOfLoopBB(const MeFunction &func, LoopDesc & return false; } -bool LoopUnrollingExecutor::IsCanonicalAndOnlyOneExitLoop(const MeFunction &func, LoopDesc &loop, +bool LoopUnrollingExecutor::IsCanonicalAndOnlyOneExitLoop( + const MeFunction &func, LoopDesc &loop, const std::unordered_map> &parentLoop) const { // Only handle one nested loop. if (parentLoop.find(&loop) != parentLoop.end() && ProfileCheck(func)) { @@ -1083,7 +1089,8 @@ bool LoopUnrollingExecutor::IsCanonicalAndOnlyOneExitLoop(const MeFunction &func CHECK_FATAL(headBB->GetPred().size() == 2, "head must has two preds"); if (!IsDoWhileLoop(func, loop)) { if (enableDebug) { - LogInfo::MapleLogger() << "While-do loop" << "\n"; + LogInfo::MapleLogger() << "While-do loop" + << "\n"; } return false; } @@ -1100,19 +1107,20 @@ bool LoopUnrollingExecutor::IsCanonicalAndOnlyOneExitLoop(const MeFunction &func bool LoopUnrolling::LoopUnrollingWithConst(uint64 tripCount, bool onlyFully) { if (tripCount == kInvalidTripCount) { if (LoopUnrollingExecutor::enableDebug) { - LogInfo::MapleLogger() << "tripCount is invalid" << "\n"; + LogInfo::MapleLogger() << "tripCount is invalid" + << "\n"; } return false; } if (LoopUnrollingExecutor::enableDebug) { - LogInfo::MapleLogger() << "start unrolling with const" << "\n"; + LogInfo::MapleLogger() << "start unrolling with const" + << "\n"; LogInfo::MapleLogger() << "tripCount: " << tripCount << "\n"; } if (LoopUnrollingExecutor::enableDebug) { irMap->Dump(); - func->IsIRProfValid() ? func->GetCfg()->DumpToFile("cfgIncludeFreqInfobeforLoopUnrolling", false, true) : - func->GetCfg()->DumpToFile("cfgbeforLoopUnrolling" + - std::to_string(loop->head->GetBBId())); + func->IsIRProfValid() ? func->GetCfg()->DumpToFile("cfgIncludeFreqInfobeforLoopUnrolling", false, true) + : func->GetCfg()->DumpToFile("cfgbeforLoopUnrolling" + std::to_string(loop->head->GetBBId())); } // fully unroll ReturnKindOfFullyUnroll returnKind = LoopFullyUnroll(static_cast(tripCount)); @@ -1121,13 +1129,14 @@ bool LoopUnrolling::LoopUnrollingWithConst(uint64 tripCount, bool onlyFully) { } if (returnKind == LoopUnrolling::kCanFullyUnroll) { if (LoopUnrollingExecutor::enableDebug) { - LogInfo::MapleLogger() << "fully unrolling" << "\n"; + LogInfo::MapleLogger() << "fully unrolling" + << "\n"; } if (LoopUnrollingExecutor::enableDebug) { irMap->Dump(); - func->IsIRProfValid() ? func->GetCfg()->DumpToFile("cfgIncludeFreqInfoafterLoopFullyUnrolling", false, true) : - func->GetCfg()->DumpToFile("cfgafterLoopFullyUnrolling" + - std::to_string(loop->head->GetBBId())); + func->IsIRProfValid() + ? func->GetCfg()->DumpToFile("cfgIncludeFreqInfoafterLoopFullyUnrolling", false, true) + : func->GetCfg()->DumpToFile("cfgafterLoopFullyUnrolling" + std::to_string(loop->head->GetBBId())); } return true; } @@ -1137,12 +1146,13 @@ bool LoopUnrolling::LoopUnrollingWithConst(uint64 tripCount, bool onlyFully) { // partial unroll with const if (LoopPartialUnrollWithConst(tripCount)) { if (LoopUnrollingExecutor::enableDebug) { - LogInfo::MapleLogger() << "partial unrolling with const" << "\n"; + LogInfo::MapleLogger() << "partial unrolling with const" + << "\n"; } if (LoopUnrollingExecutor::enableDebug) { irMap->Dump(); - func->IsIRProfValid() ? func->GetCfg()->DumpToFile("cfgIncludeFreqInfoafterLoopPartialWithConst", false, true) : - func->GetCfg()->DumpToFile("cfgafterLoopPartialWithConstUnrolling"); + func->IsIRProfValid() ? func->GetCfg()->DumpToFile("cfgIncludeFreqInfoafterLoopPartialWithConst", false, true) + : func->GetCfg()->DumpToFile("cfgafterLoopPartialWithConstUnrolling"); } return true; } @@ -1150,7 +1160,8 @@ bool LoopUnrolling::LoopUnrollingWithConst(uint64 tripCount, bool onlyFully) { } void LoopUnrollingExecutor::ExecuteLoopUnrolling(MeFunction &func, MeIRMap &irMap, - std::map>> &cands, IdentifyLoops &meLoop, const MapleAllocator &alloc) { + std::map>> &cands, + IdentifyLoops &meLoop, const MapleAllocator &alloc) { if (enableDebug) { LogInfo::MapleLogger() << func.GetName() << "\n"; } @@ -1168,6 +1179,9 @@ void LoopUnrollingExecutor::ExecuteLoopUnrolling(MeFunction &func, MeIRMap &irMa } LoopScalarAnalysisResult sa(irMap, loop); LoopUnrolling loopUnrolling(func, *loop, irMap, alloc, cands); + if (func.GetCfg()->UpdateCFGFreq()) { + loopUnrolling.SetInstrumentProf(true); + } uint64 tripCount = 0; CRNode *conditionCRNode = nullptr; CR *itCR = nullptr; @@ -1236,6 +1250,9 @@ bool MELoopUnrolling::PhaseRun(maple::MeFunction &f) { MeSSAUpdate ssaUpdate(f, *f.GetMeSSATab(), *dom, cands); ssaUpdate.Run(); GetAnalysisInfoHook()->ForceEraseAnalysisPhase(f.GetUniqueID(), &MELoopAnalysis::id); + if (f.GetCfg()->UpdateCFGFreq() && f.GetCfg()->DumpIRProfileFile()) { + f.GetCfg()->DumpToFile("after-meloopunroll", false, true); + } } if (DEBUGFUNC_NEWPM(f)) { f.GetCfg()->DumpToFile("afterloopunrolling", false); diff --git a/src/mapleall/maple_me/src/me_profile_use.cpp b/src/mapleall/maple_me/src/me_profile_use.cpp index 4d9c62b6ad..0041c51b0d 100644 --- a/src/mapleall/maple_me/src/me_profile_use.cpp +++ b/src/mapleall/maple_me/src/me_profile_use.cpp @@ -13,10 +13,12 @@ * See the Mulan PSL v2 for more details. */ #include "me_profile_use.h" + #include + #include "me_cfg.h" -#include "me_option.h" #include "me_function.h" +#include "me_option.h" namespace maple { BBUseInfo *MeProfUse::GetOrCreateBBUseInfo(const BB &bb) { @@ -206,8 +208,8 @@ bool MeProfUse::BuildEdgeCount() { uint64 hash = ComputeFuncHash(); if (hash != result.funcHash) { if (dump) { - LogInfo::MapleLogger() << func->GetName() << " hash doesn't match profile hash " - << result.funcHash << " func real hash " << hash << '\n'; + LogInfo::MapleLogger() << func->GetName() << " hash doesn't match profile hash " << result.funcHash + << " func real hash " << hash << '\n'; } return false; } @@ -218,8 +220,8 @@ bool MeProfUse::BuildEdgeCount() { } if (instrumentBBs.size() != result.totalCounter) { if (dump) { - LogInfo::MapleLogger() << func->GetName() << " counter doesn't match profile counter " - << result.totalCounter << " func real counter " << instrumentBBs.size() << '\n'; + LogInfo::MapleLogger() << func->GetName() << " counter doesn't match profile counter " << result.totalCounter + << " func real counter " << instrumentBBs.size() << '\n'; } return false; } @@ -295,7 +297,7 @@ bool MeProfUse::Run() { } FuncProfInfo *MeProfUse::GetFuncData() { - MplProfileData* profData = func->GetMIRModule().GetMapleProfile(); + MplProfileData *profData = func->GetMIRModule().GetMapleProfile(); if (!profData) { return nullptr; } @@ -316,14 +318,14 @@ bool MeProfUse::CheckSumFail(const uint64 hash, const uint32 expectedCheckSum, c } bool MeProfUse::MapleProfRun() { - FuncProfInfo* funcData = GetFuncData(); + FuncProfInfo *funcData = GetFuncData(); if (!funcData) { return false; } func->GetMirFunc()->SetFuncProfData(funcData); // early return if lineno fail if (CheckSumFail(ComputeLinenoHash(), funcData->linenoChecksum, "lineno")) { - func->GetMirFunc()->SetFuncProfData(nullptr); // clear func profile data + func->GetMirFunc()->SetFuncProfData(nullptr); // clear func profile data return false; } FindInstrumentEdges(); @@ -338,10 +340,10 @@ bool MeProfUse::MapleProfRun() { } if (instrumentBBs.size() != funcData->edgeCounts) { if (dump) { - LogInfo::MapleLogger() << func->GetName() << " counter doesn't match profile counter " - << funcData->edgeCounts << " func real counter " << instrumentBBs.size() << '\n'; + LogInfo::MapleLogger() << func->GetName() << " counter doesn't match profile counter " << funcData->edgeCounts + << " func real counter " << instrumentBBs.size() << '\n'; } - func->GetMirFunc()->SetFuncProfData(nullptr); // clear func profile data + func->GetMirFunc()->SetFuncProfData(nullptr); // clear func profile data return false; } size_t i = 0; @@ -370,16 +372,21 @@ bool MEProfUse::PhaseRun(maple::MeFunction &f) { if (Options::profileUse) { result = profUse.MapleProfRun(); if (result) { - f.GetCfg()->VerifyBBFreq(); + result = f.GetCfg()->VerifyBBFreq(); + if (result > 0 && (DEBUGFUNC_NEWPM(f))) { + LogInfo::MapleLogger() << "func profileUse verification fail" << std::endl; + } } } else { profUse.Run(); } - if (result) { + if (DEBUGFUNC_NEWPM(f)) { LogInfo::MapleLogger() << "******************after profile use dump function******************\n"; profUse.DumpFuncCFGEdgeFreq(); - f.GetCfg()->DumpToFile("afterProfileUse", false, true); + } + if (f.GetCfg()->DumpIRProfileFile()) { + f.GetCfg()->DumpToFile("after-ProfileUse", false, true); } return true; } diff --git a/src/mapleall/maple_me/src/me_value_range_prop.cpp b/src/mapleall/maple_me/src/me_value_range_prop.cpp index 6092b9d83a..6b066e905f 100644 --- a/src/mapleall/maple_me/src/me_value_range_prop.cpp +++ b/src/mapleall/maple_me/src/me_value_range_prop.cpp @@ -13,14 +13,15 @@ * See the Mulan PSL v2 for more details. */ #include "me_value_range_prop.h" -#include "me_dominance.h" + #include "me_abco.h" -#include "me_ssa_update.h" +#include "me_dominance.h" #include "me_phase_manager.h" #include "me_safety_warning.h" +#include "me_ssa_update.h" namespace maple { -bool ValueRangePropagation::isDebug = false; +bool ValueRangePropagation::isDebug = true; constexpr size_t kNumOperands = 2; constexpr size_t kCodeSizeLimit = 2000; constexpr std::uint64_t kInvaliedBound = 0xdeadbeef; @@ -38,8 +39,8 @@ bool Bound::CanBeComparedWith(const Bound &bound) const { if (var == bound.GetVar()) { return true; } - return (*this == MinBound(primType) || *this == MaxBound(primType) || - bound == MinBound(primType) || bound == MaxBound(primType)); + return (*this == MinBound(primType) || *this == MaxBound(primType) || bound == MinBound(primType) || + bound == MaxBound(primType)); } bool Bound::operator<(const Bound &bound) const { @@ -93,6 +94,10 @@ void ValueRangePropagation::Execute() { dealWithPhi = true; DealWithPhi(**bIt); dealWithPhi = false; + if (func.GetCfg()->UpdateCFGFreq()) { + // update edge frequency + (*bIt)->UpdateEdgeFreqs(false); + } for (auto it = (*bIt)->GetMeStmts().begin(); it != (*bIt)->GetMeStmts().end();) { bool deleteStmt = false; if (!onlyPropVR) { @@ -110,8 +115,8 @@ void ValueRangePropagation::Execute() { ++it; continue; } - if (MeOption::safeRegionMode && (it->IsInSafeRegion()) && - kOpcodeInfo.IsCall(it->GetOp()) && instance_of(*it)) { + if (MeOption::safeRegionMode && (it->IsInSafeRegion()) && kOpcodeInfo.IsCall(it->GetOp()) && + instance_of(*it)) { MIRFunction *callFunc = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(static_cast(*it).GetPUIdx()); if (callFunc->IsUnSafe()) { @@ -137,40 +142,40 @@ void ValueRangePropagation::Execute() { InsertValueRangeOfCondExpr2Caches(**bIt, *it); break; } - CASE_OP_ASSERT_NONNULL { - if (!dealWithAssert) { - break; - } - // If the option safeRegion is open and the stmt is not in safe region, delete it. - if (MeOption::safeRegionMode && !it->IsInSafeRegion()) { - deleteStmt = true; - } else if (DealWithAssertNonnull(**bIt, *it)) { - if (ValueRangePropagation::isDebug) { - LogInfo::MapleLogger() << "=========delete assert nonnull=========\n"; - it->Dump(&irMap); - LogInfo::MapleLogger() << "=========delete assert nonnull=========\n"; + CASE_OP_ASSERT_NONNULL { + if (!dealWithAssert) { + break; + } + // If the option safeRegion is open and the stmt is not in safe region, delete it. + if (MeOption::safeRegionMode && !it->IsInSafeRegion()) { + deleteStmt = true; + } else if (DealWithAssertNonnull(**bIt, *it)) { + if (ValueRangePropagation::isDebug) { + LogInfo::MapleLogger() << "=========delete assert nonnull=========\n"; + it->Dump(&irMap); + LogInfo::MapleLogger() << "=========delete assert nonnull=========\n"; + } + deleteStmt = true; } - deleteStmt = true; - } - break; - } - CASE_OP_ASSERT_BOUNDARY { - if (!dealWithAssert) { break; } - // If the option safeRegion is open and the stmt is not in safe region, delete it. - if (MeOption::safeRegionMode && !it->IsInSafeRegion()) { - deleteStmt = true; - } else if (DealWithBoundaryCheck(**bIt, *it)) { - if (ValueRangePropagation::isDebug) { - LogInfo::MapleLogger() << "=========delete boundary check=========\n"; - it->Dump(&irMap); - LogInfo::MapleLogger() << "=========delete boundary check=========\n"; + CASE_OP_ASSERT_BOUNDARY { + if (!dealWithAssert) { + break; + } + // If the option safeRegion is open and the stmt is not in safe region, delete it. + if (MeOption::safeRegionMode && !it->IsInSafeRegion()) { + deleteStmt = true; + } else if (DealWithBoundaryCheck(**bIt, *it)) { + if (ValueRangePropagation::isDebug) { + LogInfo::MapleLogger() << "=========delete boundary check=========\n"; + it->Dump(&irMap); + LogInfo::MapleLogger() << "=========delete boundary check=========\n"; + } + deleteStmt = true; } - deleteStmt = true; + break; } - break; - } case OP_callassigned: { DealWithCallassigned(**bIt, *it); break; @@ -201,7 +206,8 @@ void ValueRangePropagation::DealWithCallassigned(const BB &bb, MeStmt &stmt) { auto &callassign = static_cast(stmt); MIRFunction *callFunc = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callassign.GetPUIdx()); if (callFunc->GetAttr(FUNCATTR_nonnull) && callassign.GetAssignedLHS() != nullptr) { - (void)Insert2Caches(bb.GetBBId(), callassign.GetAssignedLHS()->GetExprID(), + (void)Insert2Caches( + bb.GetBBId(), callassign.GetAssignedLHS()->GetExprID(), std::make_unique(Bound(nullptr, 0, callassign.GetAssignedLHS()->GetPrimType()), kNotEqual)); } } @@ -222,9 +228,8 @@ void ValueRangePropagation::DealWithSwitch(BB &bb, MeStmt &stmt) { // Can prop value range to target bb only when the pred size of target bb is one and // only one case can jump to the target bb. if (currbb->GetPred().size() == 1 && bbOfCases.insert(currbb->GetBBId()).second) { - (void)Insert2Caches( - currbb->GetBBId(), opnd->GetExprID(), - std::make_unique(Bound(nullptr, pair.first, PTY_i64), kEqual)); + (void)Insert2Caches(currbb->GetBBId(), opnd->GetExprID(), + std::make_unique(Bound(nullptr, pair.first, PTY_i64), kEqual)); } else { (void)Insert2Caches(currbb->GetBBId(), opnd->GetExprID(), nullptr); } @@ -272,7 +277,7 @@ void ValueRangePropagation::DeleteThePhiNodeWhichOnlyHasOneOpnd( } } -bool ValueRange::IsEqual(ValueRange *valueRangeRight) const { +bool ValueRange::IsEqual(ValueRange *valueRangeRight) const { if (valueRangeRight == nullptr) { return false; } @@ -283,14 +288,11 @@ bool ValueRange::IsEqual(ValueRange *valueRangeRight) const { case kLowerAndUpper: case kSpecialUpperForLoop: case kSpecialLowerForLoop: - return range.pair.upper == (valueRangeRight->GetUpper()) && - range.pair.lower == (valueRangeRight->GetLower()); + return range.pair.upper == (valueRangeRight->GetUpper()) && range.pair.lower == (valueRangeRight->GetLower()); case kOnlyHasLowerBound: - return range.pair.lower == (valueRangeRight->GetLower()) && - stride == valueRangeRight->GetStride(); + return range.pair.lower == (valueRangeRight->GetLower()) && stride == valueRangeRight->GetStride(); case kOnlyHasUpperBound: - return range.pair.upper == (valueRangeRight->GetUpper()) && - stride == valueRangeRight->GetStride(); + return range.pair.upper == (valueRangeRight->GetUpper()) && stride == valueRangeRight->GetStride(); case kNotEqual: case kEqual: return range.bound == (valueRangeRight->GetBound()); @@ -324,7 +326,7 @@ std::unique_ptr MergeVR(const ValueRange &vr1, const ValueRange &vr2 return nullptr; } if (upper2 < lower1 || upper1 < lower2) { - return intersect ? std::make_unique(kRTEmpty) : nullptr; // always false + return intersect ? std::make_unique(kRTEmpty) : nullptr; // always false } else if (upper2 == lower1) { return intersect ? std::make_unique(lower1, kEqual) : std::make_unique(lower2, upper1, kLowerAndUpper); @@ -371,7 +373,7 @@ std::unique_ptr MergeVR(const ValueRange &vr1, const ValueRange &vr2 : std::make_unique(kRTComplete); // always true; } else if (bound == upper1) { return intersect ? std::make_unique(lower1, --upper1, kLowerAndUpper) - : std::make_unique(kRTComplete); // always true; + : std::make_unique(kRTComplete); // always true; } return nullptr; } @@ -387,7 +389,7 @@ std::unique_ptr MergeVR(const ValueRange &vr1, const ValueRange &vr2 } switch (vr2Type) { case kLowerAndUpper: { - return MergeVR(vr2, vr1, intersect); // swap two vr + return MergeVR(vr2, vr1, intersect); // swap two vr } case kEqual: { if (b1 == b2) { @@ -413,7 +415,7 @@ std::unique_ptr MergeVR(const ValueRange &vr1, const ValueRange &vr2 switch (vr2Type) { case kLowerAndUpper: case kEqual: { - return MergeVR(vr2, vr1, intersect); // swap two vr + return MergeVR(vr2, vr1, intersect); // swap two vr } case kNotEqual: { Bound b1 = vr1.GetBound(); @@ -439,7 +441,7 @@ std::unique_ptr MergeVR(const ValueRange &vr1, const ValueRange &vr2 MeExpr *GetCmpExprFromBound(Bound b, MeExpr &expr, MeIRMap *irmap, Opcode op) { int64 val = b.GetConstant(); - MeExpr *var = const_cast(b.GetVar()); + MeExpr *var = const_cast(b.GetVar()); PrimType ptyp = b.GetPrimType(); MeExpr *constExpr = irmap->CreateIntConstMeExpr(val, ptyp); MeExpr *resExpr = nullptr; @@ -526,19 +528,18 @@ std::unique_ptr ValueRangePropagation::ZeroIsInRange(const ValueRang valueRange.GetUpper().GetVar() == nullptr && valueRange.GetLower().GetConstant() < valueRange.GetUpper().GetConstant()) { if (valueRange.GetLower().GetConstant() == 0) { - return std::make_unique( - Bound(1, valueRange.GetLower().GetPrimType()), valueRange.GetUpper(), kLowerAndUpper); + return std::make_unique(Bound(1, valueRange.GetLower().GetPrimType()), valueRange.GetUpper(), + kLowerAndUpper); } if (valueRange.GetUpper().GetConstant() == 0) { - return std::make_unique( - valueRange.GetLower(), Bound(-1, valueRange.GetUpper().GetPrimType()), kLowerAndUpper); + return std::make_unique(valueRange.GetLower(), Bound(-1, valueRange.GetUpper().GetPrimType()), + kLowerAndUpper); } } return nullptr; } -std::unique_ptr ValueRangePropagation::FindValueRangeInCurrBBOrDominateBBs( - const BB &bb, MeExpr &opnd) { +std::unique_ptr ValueRangePropagation::FindValueRangeInCurrBBOrDominateBBs(const BB &bb, MeExpr &opnd) { auto *res = FindValueRangeInCurrentBB(bb.GetBBId(), opnd.GetExprID()); if (res != nullptr) { return CopyValueRange(*res); @@ -550,11 +551,10 @@ std::unique_ptr ValueRangePropagation::FindValueRangeInCurrBBOrDomin return nullptr; } -void SafetyCheckWithBoundaryError::HandleAssignWithDeadBeef( - const BB &bb, MeStmt &meStmt, MeExpr &indexOpnd, - MeExpr &boundOpnd) { +void SafetyCheckWithBoundaryError::HandleAssignWithDeadBeef(const BB &bb, MeStmt &meStmt, MeExpr &indexOpnd, + MeExpr &boundOpnd) { std::set visitedLHS; - std::vector stmts{ &meStmt }; + std::vector stmts{&meStmt}; vrp.JudgeTheConsistencyOfDefPointsOfBoundaryCheck(bb, indexOpnd, visitedLHS, stmts); visitedLHS.clear(); stmts.clear(); @@ -566,8 +566,8 @@ void SafetyCheckWithBoundaryError::HandleAssignWithDeadBeef( // valueRangeOfIndex zero is in range and in safe region mode, compiler err // valueRangeOfIndex is zero and not in safe region mode, compiler err void SafetyCheckWithNonnullError::HandleAssertNonnull(const MeStmt &meStmt, const ValueRange *valueRangeOfIndex) { - if ((valueRangeOfIndex == nullptr || valueRangeOfIndex->IsZeroInRange()) && - meStmt.IsInSafeRegion() && MeOption::safeRegionMode) { + if ((valueRangeOfIndex == nullptr || valueRangeOfIndex->IsZeroInRange()) && meStmt.IsInSafeRegion() && + MeOption::safeRegionMode) { (void)NeedDeleteTheAssertAfterErrorOrWarn(meStmt, true); } if (valueRangeOfIndex != nullptr && valueRangeOfIndex->IsEqualZero()) { @@ -579,8 +579,8 @@ bool SafetyCheckWithBoundaryError::HandleAssertError(const MeStmt &meStmt) { return NeedDeleteTheAssertAfterErrorOrWarn(meStmt); } -bool SafetyCheckWithBoundaryError::HandleAssertltOrAssertle( - const MeStmt &meStmt, Opcode op, int64 indexValue, int64 lengthValue) { +bool SafetyCheckWithBoundaryError::HandleAssertltOrAssertle(const MeStmt &meStmt, Opcode op, int64 indexValue, + int64 lengthValue) { if (kOpcodeInfo.IsAssertLeBoundary((op))) { if (indexValue > lengthValue) { return NeedDeleteTheAssertAfterErrorOrWarn(meStmt); @@ -593,19 +593,21 @@ bool SafetyCheckWithBoundaryError::HandleAssertltOrAssertle( return false; } -bool ValueRangePropagation::CompareConstantOfIndexAndLength( - const MeStmt &meStmt, const ValueRange &valueRangeOfIndex, ValueRange &valueRangeOfLengthPtr, Opcode op) { +bool ValueRangePropagation::CompareConstantOfIndexAndLength(const MeStmt &meStmt, const ValueRange &valueRangeOfIndex, + ValueRange &valueRangeOfLengthPtr, Opcode op) { if (safetyCheckBoundary->HandleAssertltOrAssertle(meStmt, op, valueRangeOfIndex.GetUpper().GetConstant(), valueRangeOfLengthPtr.GetBound().GetConstant())) { return true; } - return (kOpcodeInfo.IsAssertLeBoundary(op) ? - valueRangeOfIndex.GetUpper().GetConstant() <= valueRangeOfLengthPtr.GetBound().GetConstant() : - valueRangeOfIndex.GetUpper().GetConstant() < valueRangeOfLengthPtr.GetBound().GetConstant()); + return (kOpcodeInfo.IsAssertLeBoundary(op) + ? valueRangeOfIndex.GetUpper().GetConstant() <= valueRangeOfLengthPtr.GetBound().GetConstant() + : valueRangeOfIndex.GetUpper().GetConstant() < valueRangeOfLengthPtr.GetBound().GetConstant()); } bool ValueRangePropagation::CompareIndexWithUpper(const BB &bb, const MeStmt &meStmt, - const ValueRange &valueRangeOfIndex, ValueRange &valueRangeOfLengthPtr, Opcode op, const MeExpr *indexOpnd) { + const ValueRange &valueRangeOfIndex, + ValueRange &valueRangeOfLengthPtr, Opcode op, + const MeExpr *indexOpnd) { if (valueRangeOfIndex.GetRangeType() == kNotEqual || valueRangeOfLengthPtr.GetRangeType() == kNotEqual) { return false; } @@ -619,8 +621,8 @@ bool ValueRangePropagation::CompareIndexWithUpper(const BB &bb, const MeStmt &me upperOfLength)) { return true; } - return (kOpcodeInfo.IsAssertLeBoundary((op))) ? valueRangeOfIndex.GetUpper().GetConstant() <= lowerOfLength : - valueRangeOfIndex.GetUpper().GetConstant() < lowerOfLength; + return (kOpcodeInfo.IsAssertLeBoundary((op))) ? valueRangeOfIndex.GetUpper().GetConstant() <= lowerOfLength + : valueRangeOfIndex.GetUpper().GetConstant() < lowerOfLength; } if (!valueRangeOfIndex.IsConstantLowerAndUpper() || valueRangeOfIndex.GetLower().GetConstant() > valueRangeOfIndex.GetUpper().GetConstant() || @@ -645,8 +647,8 @@ bool ValueRangePropagation::CompareIndexWithUpper(const BB &bb, const MeStmt &me return true; } } - return (kOpcodeInfo.IsAssertLeBoundary((op))) ? valueRangeOfIndex.GetUpper().GetConstant() <= lowerOfLength : - valueRangeOfIndex.GetUpper().GetConstant() < lowerOfLength; + return (kOpcodeInfo.IsAssertLeBoundary((op))) ? valueRangeOfIndex.GetUpper().GetConstant() <= lowerOfLength + : valueRangeOfIndex.GetUpper().GetConstant() < lowerOfLength; } else if (valueRangeOfLengthPtr.GetRangeType() == kEqual) { // Opt array boundary check when the array length is a var. if (valueRangeOfIndex.GetRangeType() == kSpecialUpperForLoop || @@ -668,10 +670,9 @@ bool ValueRangePropagation::CompareIndexWithUpper(const BB &bb, const MeStmt &me } if (crNode->GetCRType() == kCRVarNode) { return (crNode->GetExpr() == valueRangeOfLengthPtr.GetBound().GetVar()) && - CompareConstantOfIndexAndLength(meStmt, valueRangeOfIndex, valueRangeOfLengthPtr, op); + CompareConstantOfIndexAndLength(meStmt, valueRangeOfIndex, valueRangeOfLengthPtr, op); } - if (crNode->GetCRType() != kCRAddNode || - static_cast(crNode)->GetOpndsSize() != kNumOperands || + if (crNode->GetCRType() != kCRAddNode || static_cast(crNode)->GetOpndsSize() != kNumOperands || static_cast(crNode)->GetOpnd(1)->GetExpr() == nullptr || static_cast(crNode)->GetOpnd(1)->GetExpr() != valueRangeOfLengthPtr.GetBound().GetVar() || static_cast(crNode)->GetOpnd(0)->GetCRType() != kCRConstNode) { @@ -683,8 +684,7 @@ bool ValueRangePropagation::CompareIndexWithUpper(const BB &bb, const MeStmt &me // expr = length - 1 // after analysis: valueRangeOfIndex : (lower(length), upper: (-2), kLowerAndUpper) int64 res = 0; - auto constantValue = - static_cast(static_cast(crNode)->GetOpnd(0))->GetConstValue(); + auto constantValue = static_cast(static_cast(crNode)->GetOpnd(0))->GetConstValue(); if (!AddOrSubWithConstant(valueRangeOfLengthPtr.GetUpper().GetPrimType(), OP_add, constantValue, valueRangeOfIndex.GetUpper().GetConstant(), res)) { return false; @@ -693,8 +693,8 @@ bool ValueRangePropagation::CompareIndexWithUpper(const BB &bb, const MeStmt &me valueRangeOfLengthPtr.GetBound().GetConstant())) { return true; } - return (kOpcodeInfo.IsAssertLeBoundary(op) ? res <= valueRangeOfLengthPtr.GetBound().GetConstant() : - res < valueRangeOfLengthPtr.GetBound().GetConstant()); + return (kOpcodeInfo.IsAssertLeBoundary(op) ? res <= valueRangeOfLengthPtr.GetBound().GetConstant() + : res < valueRangeOfLengthPtr.GetBound().GetConstant()); } else { return CompareConstantOfIndexAndLength(meStmt, valueRangeOfIndex, valueRangeOfLengthPtr, op); } @@ -707,9 +707,9 @@ bool ValueRangePropagation::CompareIndexWithUpper(const BB &bb, const MeStmt &me valueRangeOfLengthPtr.GetBound().GetConstant())) { return true; } - return kOpcodeInfo.IsAssertLeBoundary(op) ? - valueRangeOfIndex.GetUpper().GetConstant() <= valueRangeOfLengthPtr.GetBound().GetConstant() : - valueRangeOfIndex.GetUpper().GetConstant() < valueRangeOfLengthPtr.GetBound().GetConstant(); + return kOpcodeInfo.IsAssertLeBoundary(op) + ? valueRangeOfIndex.GetUpper().GetConstant() <= valueRangeOfLengthPtr.GetBound().GetConstant() + : valueRangeOfIndex.GetUpper().GetConstant() < valueRangeOfLengthPtr.GetBound().GetConstant(); } return false; } @@ -719,8 +719,9 @@ bool ValueRangePropagation::CompareIndexWithUpper(const BB &bb, const MeStmt &me bool ValueRangePropagation::IfAnalysisedBefore(const BB &bb, const MeStmt &stmt) { MeExpr &index = *stmt.GetOpnd(0); MeExpr &bound = *stmt.GetOpnd(1); - auto &analysisedArrayChecks = (kOpcodeInfo.IsAssertLowerBoundary(stmt.GetOp())) ? analysisedLowerBoundChecks : - (kOpcodeInfo.IsAssertLeBoundary(stmt.GetOp())) ? analysisedAssignBoundChecks : analysisedUpperBoundChecks; + auto &analysisedArrayChecks = (kOpcodeInfo.IsAssertLowerBoundary(stmt.GetOp())) ? analysisedLowerBoundChecks + : (kOpcodeInfo.IsAssertLeBoundary(stmt.GetOp())) ? analysisedAssignBoundChecks + : analysisedUpperBoundChecks; for (size_t i = 0; i < analysisedArrayChecks.size(); ++i) { auto *analysisedBB = func.GetCfg()->GetBBFromID(BBId(i)); if (!dom.Dominate(*analysisedBB, bb)) { @@ -741,8 +742,8 @@ bool ValueRangePropagation::IfAnalysisedBefore(const BB &bb, const MeStmt &stmt) return false; } -bool ValueRangePropagation::TheValueOfOpndIsInvaliedInABCO( - const BB &bb, const MeStmt *meStmt, MeExpr &boundOpnd, bool updateCaches) { +bool ValueRangePropagation::TheValueOfOpndIsInvaliedInABCO(const BB &bb, const MeStmt *meStmt, MeExpr &boundOpnd, + bool updateCaches) { if (boundOpnd.GetMeOp() == kMeOpConst && static_cast(boundOpnd).GetConstVal()->GetKind() == kConstInt && static_cast(static_cast(boundOpnd).GetExtIntValue()) == kInvaliedBound) { @@ -752,8 +753,8 @@ bool ValueRangePropagation::TheValueOfOpndIsInvaliedInABCO( return true; } else { auto *valueRange = FindValueRange(bb, boundOpnd); - if (valueRange != nullptr && valueRange->GetRangeType() != kNotEqual && - valueRange->IsConstant() && static_cast(valueRange->GetLower().GetConstant()) == kInvaliedBound) { + if (valueRange != nullptr && valueRange->GetRangeType() != kNotEqual && valueRange->IsConstant() && + static_cast(valueRange->GetLower().GetConstant()) == kInvaliedBound) { if (updateCaches) { Insert2AnalysisedArrayChecks(bb.GetBBId(), *meStmt->GetOpnd(1), *meStmt->GetOpnd(0), meStmt->GetOp()); } @@ -769,8 +770,9 @@ bool ValueRangePropagation::TheValueOfOpndIsInvaliedInABCO( // else: // p = GetBoundarylessPtr // error: p + i -void ValueRangePropagation::JudgeTheConsistencyOfDefPointsOfBoundaryCheck( - const BB &bb, MeExpr &expr, std::set &visitedLHS, std::vector &stmts) { +void ValueRangePropagation::JudgeTheConsistencyOfDefPointsOfBoundaryCheck(const BB &bb, MeExpr &expr, + std::set &visitedLHS, + std::vector &stmts) { if (TheValueOfOpndIsInvaliedInABCO(bb, nullptr, expr, false)) { std::string errorLog = "error: pointer assigned from multibranch requires the boundary info for all branches.\n"; for (size_t i = 0; i < stmts.size(); ++i) { @@ -782,7 +784,7 @@ void ValueRangePropagation::JudgeTheConsistencyOfDefPointsOfBoundaryCheck( } auto &srcPosition = stmts[i]->GetSrcPosition(); errorLog += func.GetMIRModule().GetFileNameFromFileNum(srcPosition.FileNum()) + ":" + - std::to_string(srcPosition.LineNum()) + "\n"; + std::to_string(srcPosition.LineNum()) + "\n"; } FATAL(kLncFatal, "%s", errorLog.c_str()); } @@ -867,8 +869,8 @@ static inline bool CanNotDoReplaceLoopVarOpt(const ValueRange *valueRange) { return type != kEqual && !(type == kLowerAndUpper && valueRange->IsAccurate()); } -void ValueRangePropagation::CollectIndexOpndWithBoundInLoop( - LoopDesc &loop, BB &bb, MeStmt &meStmt, MeExpr &opnd, std::map &index2NewExpr) { +void ValueRangePropagation::CollectIndexOpndWithBoundInLoop(LoopDesc &loop, BB &bb, MeStmt &meStmt, MeExpr &opnd, + std::map &index2NewExpr) { // If the var is opnd of ivar, can not replace it with the bound. // For example: array[s[i]] // assert(array + iread(s + i) * 4, array + 1024) @@ -908,20 +910,20 @@ void ValueRangePropagation::CollectIndexOpndWithBoundInLoop( MeExpr *ValueRangePropagation::GetAddressOfIndexOrBound(MeExpr &expr) const { if (expr.IsLeaf()) { - return (expr.IsScalar() && static_cast(expr).GetDefBy() == kDefByStmt) ? - GetAddressOfIndexOrBound(*static_cast(expr).GetDefStmt()->GetRHS()) : &expr; + return (expr.IsScalar() && static_cast(expr).GetDefBy() == kDefByStmt) + ? GetAddressOfIndexOrBound(*static_cast(expr).GetDefStmt()->GetRHS()) + : &expr; } return GetAddressOfIndexOrBound(*expr.GetOpnd(0)); } -void ValueRangePropagation::GetValueRangeOfCRNode( - const BB &bb, CRNode &opndOfCRNode, std::unique_ptr &resValueRange, PrimType pTypeOfArray) { +void ValueRangePropagation::GetValueRangeOfCRNode(const BB &bb, CRNode &opndOfCRNode, + std::unique_ptr &resValueRange, PrimType pTypeOfArray) { // Deal with the operand which is a constant. if (opndOfCRNode.GetCRType() == kCRConstNode) { int64 constant = static_cast(opndOfCRNode).GetConstValue(); - resValueRange = (resValueRange == nullptr) ? - std::make_unique(Bound(constant, pTypeOfArray), kEqual) : - AddOrSubWithValueRange(OP_add, *resValueRange, constant); + resValueRange = (resValueRange == nullptr) ? std::make_unique(Bound(constant, pTypeOfArray), kEqual) + : AddOrSubWithValueRange(OP_add, *resValueRange, constant); return; } // Deal with the operand which is a meexpr. @@ -931,8 +933,8 @@ void ValueRangePropagation::GetValueRangeOfCRNode( } auto valueRangOfOpnd = FindValueRangeInCurrBBOrDominateBBs(bb, *opndOfCRNode.GetExpr()); if (valueRangOfOpnd == nullptr) { - valueRangOfOpnd = std::make_unique( - Bound(opndOfCRNode.GetExpr(), opndOfCRNode.GetExpr()->GetPrimType()), kEqual); + valueRangOfOpnd = + std::make_unique(Bound(opndOfCRNode.GetExpr(), opndOfCRNode.GetExpr()->GetPrimType()), kEqual); if (resValueRange == nullptr) { resValueRange = std::move(valueRangOfOpnd); } else if (resValueRange->IsNotConstantVR()) { @@ -944,22 +946,22 @@ void ValueRangePropagation::GetValueRangeOfCRNode( } } } else if (valueRangOfOpnd->GetRangeType() == kNotEqual && resValueRange == nullptr) { - resValueRange = std::make_unique( - Bound(opndOfCRNode.GetExpr(), opndOfCRNode.GetExpr()->GetPrimType()), kEqual); + resValueRange = + std::make_unique(Bound(opndOfCRNode.GetExpr(), opndOfCRNode.GetExpr()->GetPrimType()), kEqual); } else if (valueRangOfOpnd->GetRangeType() == kOnlyHasUpperBound || valueRangOfOpnd->GetRangeType() == kOnlyHasLowerBound) { resValueRange = nullptr; } else { - resValueRange = (resValueRange == nullptr) ? std::move(valueRangOfOpnd) : - AddOrSubWithValueRange(OP_add, *resValueRange, *valueRangOfOpnd); + resValueRange = (resValueRange == nullptr) ? std::move(valueRangOfOpnd) + : AddOrSubWithValueRange(OP_add, *resValueRange, *valueRangOfOpnd); } } // Get the valueRange of index and bound, for example: // assertge(ptr, ptr + 8) -> the valueRange of index is 8 // assertge(ptr, ptr + len * 4 - 8) -> the valueRange of index is len - 2 -std::unique_ptr ValueRangePropagation::GetValueRangeOfCRNodes( - const BB &bb, PrimType pTypeOfArray, std::vector &crNodes) { +std::unique_ptr ValueRangePropagation::GetValueRangeOfCRNodes(const BB &bb, PrimType pTypeOfArray, + std::vector &crNodes) { if (crNodes.empty()) { return CreateValueRangeOfEqualZero(pTypeOfArray); } @@ -1043,12 +1045,14 @@ bool ValueRangePropagation::DealWithBoundaryCheck(BB &bb, MeStmt &meStmt) { } if (ValueRangePropagation::isDebug) { std::for_each(indexVector.begin(), indexVector.end(), [this](const CRNode *cr) { - sa.Dump(*cr); - std::cout << " ";}); + sa.Dump(*cr); + std::cout << " "; + }); LogInfo::MapleLogger() << "\n"; std::for_each(boundVector.begin(), boundVector.end(), [this](const CRNode *cr) { - sa.Dump(*cr); - std::cout << " ";}); + sa.Dump(*cr); + std::cout << " "; + }); LogInfo::MapleLogger() << "\n"; } // Get the valueRange of index and bound @@ -1058,8 +1062,7 @@ bool ValueRangePropagation::DealWithBoundaryCheck(BB &bb, MeStmt &meStmt) { return false; } if (kOpcodeInfo.IsAssertLowerBoundary(meStmt.GetOp())) { - if (BrStmtInRange(bb, *valueRangeOfIndex, *valueRangeOfbound, OP_ge, - valueRangeOfIndex->GetLower().GetPrimType())) { + if (BrStmtInRange(bb, *valueRangeOfIndex, *valueRangeOfbound, OP_ge, valueRangeOfIndex->GetLower().GetPrimType())) { // Can opt the boundary check. return true; } else if (BrStmtInRange(bb, *valueRangeOfIndex, *valueRangeOfbound, OP_lt, @@ -1069,8 +1072,8 @@ bool ValueRangePropagation::DealWithBoundaryCheck(BB &bb, MeStmt &meStmt) { return true; } } else if ((valueRangeOfIndex->GetRangeType() == kSpecialUpperForLoop || - valueRangeOfIndex->GetRangeType() == kOnlyHasLowerBound || - (valueRangeOfIndex->GetRangeType() == kLowerAndUpper && valueRangeOfIndex->IsAccurate())) && + valueRangeOfIndex->GetRangeType() == kOnlyHasLowerBound || + (valueRangeOfIndex->GetRangeType() == kLowerAndUpper && valueRangeOfIndex->IsAccurate())) && valueRangeOfIndex->GetLower().GetVar() == nullptr && valueRangeOfbound->GetLower().GetVar() == nullptr && valueRangeOfbound->GetUpper().GetVar() == nullptr) { if (valueRangeOfIndex->GetLower().GetConstant() < valueRangeOfbound->GetUpper().GetConstant()) { @@ -1084,8 +1087,8 @@ bool ValueRangePropagation::DealWithBoundaryCheck(BB &bb, MeStmt &meStmt) { return true; } } else if (valueRangeOfIndex->GetRangeType() == kLowerAndUpper && valueRangeOfIndex->IsAccurate() && - valueRangeOfIndex->IsConstantLowerAndUpper() && valueRangeOfbound->IsEqualZero() && - valueRangeOfIndex->GetLower().GetConstant() < 0) { + valueRangeOfIndex->IsConstantLowerAndUpper() && valueRangeOfbound->IsEqualZero() && + valueRangeOfIndex->GetLower().GetConstant() < 0) { // Error during static compilation. if (safetyCheckBoundary->HandleAssertError(meStmt)) { return true; @@ -1125,24 +1128,24 @@ bool SafetyCheck::NeedDeleteTheAssertAfterErrorOrWarn(const MeStmt &stmt, bool i switch (stmt.GetOp()) { case OP_calcassertlt: case OP_calcassertge: { - auto &newStmt = static_cast(stmt); + auto &newStmt = static_cast(stmt); GStrIdx curFuncNameIdx = func->GetMirFunc()->GetNameStrIdx(); GStrIdx stmtFuncNameIdx = GlobalTables::GetStrTable().GetStrIdxFromName(newStmt.GetFuncName().c_str()); if (curFuncNameIdx == stmtFuncNameIdx) { if (stmt.GetOp() == OP_calcassertlt) { - WARN(kLncWarn, "%s:%d warning: the pointer >= the upper bounds after calculation", - fileName, srcPosition.LineNum()); + WARN(kLncWarn, "%s:%d warning: the pointer >= the upper bounds after calculation", fileName, + srcPosition.LineNum()); } else if (stmt.GetOp() == OP_calcassertge) { - WARN(kLncWarn, "%s:%d warning: the pointer < the lower bounds after calculation", - fileName, srcPosition.LineNum()); + WARN(kLncWarn, "%s:%d warning: the pointer < the lower bounds after calculation", fileName, + srcPosition.LineNum()); } } else { if (stmt.GetOp() == OP_calcassertlt) { WARN(kLncWarn, "%s:%d warning: the pointer >= the upper bounds after calculation when inlined to %s", fileName, srcPosition.LineNum(), func->GetName().c_str()); } else if (stmt.GetOp() == OP_calcassertge) { - WARN(kLncWarn, "%s:%d warning: the pointer < the lower bounds after calculation when inlined to %s", - fileName, srcPosition.LineNum(), func->GetName().c_str()); + WARN(kLncWarn, "%s:%d warning: the pointer < the lower bounds after calculation when inlined to %s", fileName, + srcPosition.LineNum(), func->GetName().c_str()); } } return true; @@ -1150,20 +1153,20 @@ bool SafetyCheck::NeedDeleteTheAssertAfterErrorOrWarn(const MeStmt &stmt, bool i case OP_assignassertnonnull: case OP_assertnonnull: case OP_returnassertnonnull: { - auto &newStmt = static_cast(stmt); + auto &newStmt = static_cast(stmt); GStrIdx curFuncNameIdx = func->GetMirFunc()->GetNameStrIdx(); GStrIdx stmtFuncNameIdx = GlobalTables::GetStrTable().GetStrIdxFromName(newStmt.GetFuncName().c_str()); if (curFuncNameIdx == stmtFuncNameIdx) { if (isNullablePtr) { if (stmt.GetOp() == OP_assertnonnull) { - FATAL(kLncFatal, "%s:%d error: Dereference of nullable pointer in safe region", - fileName, srcPosition.LineNum()); + FATAL(kLncFatal, "%s:%d error: Dereference of nullable pointer in safe region", fileName, + srcPosition.LineNum()); } else if (stmt.GetOp() == OP_returnassertnonnull) { - FATAL(kLncFatal, "%s:%d error: %s return nonnull but got nullable pointer in safe region", - fileName, srcPosition.LineNum(), newStmt.GetFuncName().c_str()); + FATAL(kLncFatal, "%s:%d error: %s return nonnull but got nullable pointer in safe region", fileName, + srcPosition.LineNum(), newStmt.GetFuncName().c_str()); } else { - FATAL(kLncFatal, "%s:%d error: nullable pointer assignment of nonnull pointer in safe region", - fileName, srcPosition.LineNum()); + FATAL(kLncFatal, "%s:%d error: nullable pointer assignment of nonnull pointer in safe region", fileName, + srcPosition.LineNum()); } } else { if (stmt.GetOp() == OP_assertnonnull) { @@ -1178,12 +1181,12 @@ bool SafetyCheck::NeedDeleteTheAssertAfterErrorOrWarn(const MeStmt &stmt, bool i } else { if (isNullablePtr) { if (stmt.GetOp() == OP_assertnonnull) { - FATAL(kLncFatal, "%s:%d error: Dereference of nullable pointer in safe region when inlined to %s", - fileName, srcPosition.LineNum(), func->GetName().c_str()); + FATAL(kLncFatal, "%s:%d error: Dereference of nullable pointer in safe region when inlined to %s", fileName, + srcPosition.LineNum(), func->GetName().c_str()); } else if (stmt.GetOp() == OP_returnassertnonnull) { FATAL(kLncFatal, - "%s:%d error: %s return nonnull but got nullable pointer in safe region when inlined to %s", - fileName, srcPosition.LineNum(), newStmt.GetFuncName().c_str(), func->GetName().c_str()); + "%s:%d error: %s return nonnull but got nullable pointer in safe region when inlined to %s", fileName, + srcPosition.LineNum(), newStmt.GetFuncName().c_str(), func->GetName().c_str()); } else { FATAL(kLncFatal, "%s:%d error: nullable pointer assignment of nonnull pointer in safe region when inlined to %s", @@ -1191,27 +1194,29 @@ bool SafetyCheck::NeedDeleteTheAssertAfterErrorOrWarn(const MeStmt &stmt, bool i } } else { if (stmt.GetOp() == OP_assertnonnull) { - FATAL(kLncFatal, "%s:%d error: Dereference of null pointer when inlined to %s", - fileName, srcPosition.LineNum(), func->GetName().c_str()); + FATAL(kLncFatal, "%s:%d error: Dereference of null pointer when inlined to %s", fileName, + srcPosition.LineNum(), func->GetName().c_str()); } else if (stmt.GetOp() == OP_returnassertnonnull) { - FATAL(kLncFatal, "%s:%d error: %s return nonnull but got null pointer when inlined to %s", - fileName, srcPosition.LineNum(), newStmt.GetFuncName().c_str(), func->GetName().c_str()); + FATAL(kLncFatal, "%s:%d error: %s return nonnull but got null pointer when inlined to %s", fileName, + srcPosition.LineNum(), newStmt.GetFuncName().c_str(), func->GetName().c_str()); } else { - FATAL(kLncFatal, "%s:%d error: null assignment of nonnull pointer when inlined to %s", - fileName, srcPosition.LineNum(), func->GetName().c_str()); + FATAL(kLncFatal, "%s:%d error: null assignment of nonnull pointer when inlined to %s", fileName, + srcPosition.LineNum(), func->GetName().c_str()); } } } break; } case OP_callassertnonnull: { - auto &callStmt = static_cast(stmt); + auto &callStmt = static_cast(stmt); GStrIdx curFuncNameIdx = func->GetMirFunc()->GetNameStrIdx(); GStrIdx stmtFuncNameIdx = GlobalTables::GetStrTable().GetStrIdxFromName(callStmt.GetStmtFuncName().c_str()); if (curFuncNameIdx == stmtFuncNameIdx) { if (isNullablePtr) { - FATAL(kLncFatal, "%s:%d error: nullable pointer passed to %s that requires a nonnull pointer "\ - "for %s argument in safe region", fileName, srcPosition.LineNum(), callStmt.GetFuncName().c_str(), + FATAL(kLncFatal, + "%s:%d error: nullable pointer passed to %s that requires a nonnull pointer " + "for %s argument in safe region", + fileName, srcPosition.LineNum(), callStmt.GetFuncName().c_str(), GetNthStr(callStmt.GetParamIndex()).c_str()); } else { FATAL(kLncFatal, "%s:%d error: NULL passed to %s that requires a nonnull pointer for %s argument", fileName, @@ -1219,12 +1224,16 @@ bool SafetyCheck::NeedDeleteTheAssertAfterErrorOrWarn(const MeStmt &stmt, bool i } } else { if (isNullablePtr) { - FATAL(kLncFatal, "%s:%d error: nullable pointer passed to %s that requires a nonnull pointer "\ - "for %s argument in safe region when inlined to %s", fileName, srcPosition.LineNum(), - callStmt.GetFuncName().c_str(), GetNthStr(callStmt.GetParamIndex()).c_str(), func->GetName().c_str()); + FATAL(kLncFatal, + "%s:%d error: nullable pointer passed to %s that requires a nonnull pointer " + "for %s argument in safe region when inlined to %s", + fileName, srcPosition.LineNum(), callStmt.GetFuncName().c_str(), + GetNthStr(callStmt.GetParamIndex()).c_str(), func->GetName().c_str()); } else { - FATAL(kLncFatal, "%s:%d error: NULL passed to %s that requires a nonnull pointer for %s argument "\ - "when inlined to %s", fileName, srcPosition.LineNum(), callStmt.GetFuncName().c_str(), + FATAL(kLncFatal, + "%s:%d error: NULL passed to %s that requires a nonnull pointer for %s argument " + "when inlined to %s", + fileName, srcPosition.LineNum(), callStmt.GetFuncName().c_str(), GetNthStr(callStmt.GetParamIndex()).c_str(), func->GetName().c_str()); } } @@ -1234,16 +1243,16 @@ bool SafetyCheck::NeedDeleteTheAssertAfterErrorOrWarn(const MeStmt &stmt, bool i case OP_assignassertle: case OP_assertlt: case OP_assertge: { - auto &newStmt = static_cast(stmt); + auto &newStmt = static_cast(stmt); GStrIdx curFuncNameIdx = func->GetMirFunc()->GetNameStrIdx(); GStrIdx stmtFuncNameIdx = GlobalTables::GetStrTable().GetStrIdxFromName(newStmt.GetFuncName().c_str()); if (curFuncNameIdx == stmtFuncNameIdx) { if (stmt.GetOp() == OP_assertlt) { - FATAL(kLncFatal, "%s:%d error: the pointer >= the upper bounds when accessing the memory", - fileName, srcPosition.LineNum()); + FATAL(kLncFatal, "%s:%d error: the pointer >= the upper bounds when accessing the memory", fileName, + srcPosition.LineNum()); } else if (stmt.GetOp() == OP_assertge) { - FATAL(kLncFatal, "%s:%d error: the pointer < the lower bounds when accessing the memory", - fileName, srcPosition.LineNum()); + FATAL(kLncFatal, "%s:%d error: the pointer < the lower bounds when accessing the memory", fileName, + srcPosition.LineNum()); } else if (stmt.GetOp() == OP_assignassertle) { FATAL(kLncFatal, "%s:%d error: l-value boundary should not be larger than r-value boundary", fileName, srcPosition.LineNum()); @@ -1260,8 +1269,8 @@ bool SafetyCheck::NeedDeleteTheAssertAfterErrorOrWarn(const MeStmt &stmt, bool i fileName, srcPosition.LineNum(), func->GetName().c_str()); } else if (stmt.GetOp() == OP_assignassertle) { FATAL(kLncFatal, - "%s:%d error: l-value boundary should not be larger than r-value boundary when inlined to %s", - fileName, srcPosition.LineNum(), func->GetName().c_str()); + "%s:%d error: l-value boundary should not be larger than r-value boundary when inlined to %s", fileName, + srcPosition.LineNum(), func->GetName().c_str()); } else { FATAL(kLncFatal, "%s:%d error: return value's bounds does not match the function declaration for %s when inlined to %s", @@ -1280,9 +1289,11 @@ bool SafetyCheck::NeedDeleteTheAssertAfterErrorOrWarn(const MeStmt &stmt, bool i func->GetMIRModule().GetFileNameFromFileNum(srcPosition.FileNum()).c_str(), srcPosition.LineNum(), callStmt.GetFuncName().c_str(), GetNthStr(callStmt.GetParamIndex()).c_str()); } else { - FATAL(kLncFatal, "%s:%d error: the pointer's bounds does not match the function %s declaration "\ - "for the %s argument when inlined to %s", fileName, srcPosition.LineNum(), - callStmt.GetFuncName().c_str(), GetNthStr(callStmt.GetParamIndex()).c_str(), func->GetName().c_str()); + FATAL(kLncFatal, + "%s:%d error: the pointer's bounds does not match the function %s declaration " + "for the %s argument when inlined to %s", + fileName, srcPosition.LineNum(), callStmt.GetFuncName().c_str(), + GetNthStr(callStmt.GetParamIndex()).c_str(), func->GetName().c_str()); } break; } @@ -1343,8 +1354,8 @@ void ValueRangePropagation::ReplaceOpndWithConstMeExpr(const BB &bb, MeStmt &stm } // When the valuerange of expr is constant, collect it and do replace later. -void ValueRangePropagation::CollectMeExpr( - const BB &bb, MeStmt &stmt, MeExpr &meExpr, std::map> &expr2ConstantValue) { +void ValueRangePropagation::CollectMeExpr(const BB &bb, MeStmt &stmt, MeExpr &meExpr, + std::map> &expr2ConstantValue) { if (meExpr.GetMeOp() == kMeOpConst) { return; } @@ -1352,10 +1363,10 @@ void ValueRangePropagation::CollectMeExpr( if (valueRangeOfOperand != nullptr && valueRangeOfOperand->IsConstant() && valueRangeOfOperand->GetRangeType() != kNotEqual && stmt.GetOp() != OP_asm) { auto rangeType = valueRangeOfOperand->GetRangeType(); - int64 value = (rangeType == kEqual) ? valueRangeOfOperand->GetBound().GetConstant() : - valueRangeOfOperand->GetLower().GetConstant(); - PrimType pType = (rangeType == kEqual) ? valueRangeOfOperand->GetBound().GetPrimType() : - valueRangeOfOperand->GetLower().GetPrimType(); + int64 value = (rangeType == kEqual) ? valueRangeOfOperand->GetBound().GetConstant() + : valueRangeOfOperand->GetLower().GetConstant(); + PrimType pType = (rangeType == kEqual) ? valueRangeOfOperand->GetBound().GetPrimType() + : valueRangeOfOperand->GetLower().GetPrimType(); expr2ConstantValue[&meExpr] = std::make_pair(value, pType); return; } @@ -1373,9 +1384,9 @@ void ValueRangePropagation::CreateVRWithBitsSize(const BB &bb, const OpMeExpr &o if (bitsSize < 64) { auto pTypeOfOpMeExpr = opMeExpr.GetPrimType(); uint64 maxNumber = (1ULL << bitsSize) - 1; - (void)Insert2Caches(bb.GetBBId(), opMeExpr.GetExprID(), std::make_unique( - Bound(nullptr, 0, pTypeOfOpMeExpr), - Bound(maxNumber, pTypeOfOpMeExpr), kLowerAndUpper)); + (void)Insert2Caches(bb.GetBBId(), opMeExpr.GetExprID(), + std::make_unique(Bound(nullptr, 0, pTypeOfOpMeExpr), + Bound(maxNumber, pTypeOfOpMeExpr), kLowerAndUpper)); } } @@ -1383,8 +1394,10 @@ void ValueRangePropagation::DealWithOperand(const BB &bb, MeStmt &stmt, MeExpr & switch (meExpr.GetMeOp()) { case kMeOpConst: { if (static_cast(meExpr).GetConstVal()->GetKind() == kConstInt) { - (void)Insert2Caches(bb.GetBBId(), meExpr.GetExprID(), std::make_unique( - Bound(nullptr, static_cast(meExpr).GetExtIntValue(), meExpr.GetPrimType()), kEqual)); + (void)Insert2Caches( + bb.GetBBId(), meExpr.GetExprID(), + std::make_unique( + Bound(nullptr, static_cast(meExpr).GetExtIntValue(), meExpr.GetPrimType()), kEqual)); } break; } @@ -1453,13 +1466,13 @@ void ValueRangePropagation::DealWithOperand(const BB &bb, MeStmt &stmt, MeExpr & // Judge whether the truncated range is the same as the previous range. if (valueRange->IsEqualAfterCVT(valueRange->GetLower().GetPrimType(), pTypeOpnd) && valueRange->GetUpper().IsLessThanOrEqualTo(Bound(maxNumber, PTY_u64), PTY_u64)) { - (void) Insert2Caches(bb.GetBBId(), opMeExpr.GetExprID(), CopyValueRange(*valueRange)); + (void)Insert2Caches(bb.GetBBId(), opMeExpr.GetExprID(), CopyValueRange(*valueRange)); break; } } } } - [[clang::fallthrough]]; + [[clang::fallthrough]]; case OP_extractbits: { // extractbits () // Deal with the case like : @@ -1556,14 +1569,15 @@ bool ValueRangePropagation::DealWithCVT(const BB &bb, MeStmt &stmt, OpMeExpr &op } if ((fromType == PTY_u1 || fromType == PTY_u8 || fromType == PTY_u16 || fromType == PTY_u32 || fromType == PTY_a32 || - ((fromType == PTY_ref || fromType == PTY_ptr) && GetPrimTypeSize(fromType) == 4)) && + ((fromType == PTY_ref || fromType == PTY_ptr) && GetPrimTypeSize(fromType) == 4)) && GetPrimTypeBitSize(toType) > GetPrimTypeBitSize(fromType)) { auto *valueRange = FindValueRange(bb, opMeExpr); if (valueRange != nullptr) { return false; } - (void)Insert2Caches(bb.GetBBId(), opMeExpr.GetExprID(), std::make_unique( - Bound(nullptr, 0, fromType), Bound(GetMaxNumber(fromType), fromType), kLowerAndUpper)); + (void)Insert2Caches(bb.GetBBId(), opMeExpr.GetExprID(), + std::make_unique(Bound(nullptr, 0, fromType), + Bound(GetMaxNumber(fromType), fromType), kLowerAndUpper)); } return false; } @@ -1571,8 +1585,7 @@ bool ValueRangePropagation::DealWithCVT(const BB &bb, MeStmt &stmt, OpMeExpr &op // When unreachable bb has trystmt or endtry attribute, need update try and endtry bbs. void ValueRangePropagation::UpdateTryAttribute(BB &bb) { // update try end bb - if (bb.GetAttributes(kBBAttrIsTryEnd) && - (bb.GetMeStmts().empty() || (bb.GetMeStmts().front().GetOp() != OP_try))) { + if (bb.GetAttributes(kBBAttrIsTryEnd) && (bb.GetMeStmts().empty() || (bb.GetMeStmts().front().GetOp() != OP_try))) { auto *startTryBB = func.GetCfg()->GetTryBBFromEndTryBB(&bb); auto *newEndTry = func.GetCfg()->GetBBFromID(bb.GetBBId() - 1); CHECK_NULL_FATAL(newEndTry); @@ -1583,8 +1596,7 @@ void ValueRangePropagation::UpdateTryAttribute(BB &bb) { } } // update start try bb - if (!bb.GetMeStmts().empty() && bb.GetMeStmts().front().GetOp() == OP_try && - !bb.GetAttributes(kBBAttrIsTryEnd)) { + if (!bb.GetMeStmts().empty() && bb.GetMeStmts().front().GetOp() == OP_try && !bb.GetAttributes(kBBAttrIsTryEnd)) { for (auto &pair : func.GetCfg()->GetEndTryBB2TryBB()) { if (pair.second == &bb) { auto *newStartTry = func.GetCfg()->GetBBFromID(bb.GetBBId() + 1); @@ -1599,9 +1611,9 @@ void ValueRangePropagation::UpdateTryAttribute(BB &bb) { } // Insert the ost of phi opnds to their def bbs. -void ValueRangePropagation::InsertOstOfPhi2Cands( - BB &bb, size_t i, ScalarMeExpr *updateSSAExceptTheScalarExpr, - std::map> &ssaupdateCandsForCondExpr, bool setPhiIsDead) { +void ValueRangePropagation::InsertOstOfPhi2Cands(BB &bb, size_t i, ScalarMeExpr *updateSSAExceptTheScalarExpr, + std::map> &ssaupdateCandsForCondExpr, + bool setPhiIsDead) { for (auto &it : bb.GetMePhiList()) { if (setPhiIsDead) { it.second->SetIsLive(false); @@ -1634,8 +1646,8 @@ void ValueRangePropagation::PrepareForSSAUpdateWhenPredBBIsRemoved( int index = bb.GetPredIndex(pred); CHECK_FATAL(index != -1, "pred is not in preds of bb"); InsertOstOfPhi2Cands(bb, static_cast(index), updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); - auto updateSSAExceptTheOstIdx = updateSSAExceptTheScalarExpr == nullptr ? OStIdx(0) : - updateSSAExceptTheScalarExpr->GetOstIdx(); + auto updateSSAExceptTheOstIdx = + updateSSAExceptTheScalarExpr == nullptr ? OStIdx(0) : updateSSAExceptTheScalarExpr->GetOstIdx(); MeSSAUpdate::InsertDefPointsOfBBToSSACands(bb, cands, updateSSAExceptTheOstIdx); } @@ -1699,9 +1711,9 @@ int64 GetMinNumber(PrimType primType) { return std::numeric_limits::min(); case PTY_ref: case PTY_ptr: - if (GetPrimTypeSize(primType) == kFourByte) { // 32 bit + if (GetPrimTypeSize(primType) == kFourByte) { // 32 bit return std::numeric_limits::min(); - } else { // 64 bit + } else { // 64 bit CHECK_FATAL(GetPrimTypeSize(primType) == kEightByte, "must be 64 bit"); return std::numeric_limits::min(); } @@ -1734,9 +1746,9 @@ int64 GetMaxNumber(PrimType primType) { return std::numeric_limits::max(); case PTY_ref: case PTY_ptr: - if (GetPrimTypeSize(primType) == kFourByte) { // 32 bit + if (GetPrimTypeSize(primType) == kFourByte) { // 32 bit return std::numeric_limits::max(); - } else { // 64 bit + } else { // 64 bit CHECK_FATAL(GetPrimTypeSize(primType) == kEightByte, "must be 64 bit"); return std::numeric_limits::max(); } @@ -1751,15 +1763,14 @@ int64 GetMaxNumber(PrimType primType) { } // If the result of operator add or sub is overflow or underflow, return false. -bool ValueRangePropagation::AddOrSubWithConstant( - PrimType primType, Opcode op, int64 lhsConstant, int64 rhsConstant, int64 &res) const { +bool ValueRangePropagation::AddOrSubWithConstant(PrimType primType, Opcode op, int64 lhsConstant, int64 rhsConstant, + int64 &res) const { if (ConstantFold::IntegerOpIsOverflow(op, primType, lhsConstant, rhsConstant)) { return false; } if (IsPrimTypeUint64(primType)) { - res = (op == OP_add) ? - (static_cast(lhsConstant) + static_cast(rhsConstant)) : - (static_cast(lhsConstant) - static_cast(rhsConstant)); + res = (op == OP_add) ? (static_cast(lhsConstant) + static_cast(rhsConstant)) + : (static_cast(lhsConstant) - static_cast(rhsConstant)); } else { res = (op == OP_add) ? (lhsConstant + rhsConstant) : (lhsConstant - rhsConstant); } @@ -1806,8 +1817,8 @@ bool ValueRangePropagation::IsConstant(const BB &bb, MeExpr &expr, int64 &value, } // Create new valueRange when old valueRange add or sub with a valuerange. -std::unique_ptr ValueRangePropagation::AddOrSubWithValueRange( - Opcode op, ValueRange &valueRangeLeft, ValueRange &valueRangeRight) { +std::unique_ptr ValueRangePropagation::AddOrSubWithValueRange(Opcode op, ValueRange &valueRangeLeft, + ValueRange &valueRangeRight) { if (valueRangeLeft.GetRangeType() == kNotEqual || valueRangeRight.GetRangeType() == kNotEqual || valueRangeLeft.GetRangeType() == kOnlyHasLowerBound || valueRangeRight.GetRangeType() == kOnlyHasLowerBound || valueRangeLeft.GetRangeType() == kOnlyHasUpperBound || valueRangeRight.GetRangeType() == kOnlyHasUpperBound) { @@ -1837,19 +1848,19 @@ std::unique_ptr ValueRangePropagation::AddOrSubWithValueRange( int64 rhsLowerConst = valueRangeRight.GetLower().GetConstant(); int64 rhsUpperConst = valueRangeRight.GetUpper().GetConstant(); int64 res = 0; - if (!AddOrSubWithConstant(valueRangeLeft.GetLower().GetPrimType(), op, - valueRangeLeft.GetLower().GetConstant(), rhsLowerConst, res)) { + if (!AddOrSubWithConstant(valueRangeLeft.GetLower().GetPrimType(), op, valueRangeLeft.GetLower().GetConstant(), + rhsLowerConst, res)) { return nullptr; } Bound lower = Bound(valueRangeLeft.GetLower().GetVar(), res, valueRangeLeft.GetLower().GetPrimType()); res = 0; - if (!AddOrSubWithConstant(valueRangeLeft.GetLower().GetPrimType(), op, - valueRangeLeft.GetUpper().GetConstant(), rhsUpperConst, res)) { + if (!AddOrSubWithConstant(valueRangeLeft.GetLower().GetPrimType(), op, valueRangeLeft.GetUpper().GetConstant(), + rhsUpperConst, res)) { return nullptr; } Bound upper = Bound(valueRangeLeft.GetUpper().GetVar(), res, valueRangeLeft.GetUpper().GetPrimType()); return std::make_unique(lower, upper, kLowerAndUpper, - valueRangeLeft.IsAccurate() || valueRangeRight.IsAccurate()); + valueRangeLeft.IsAccurate() || valueRangeRight.IsAccurate()); } bool ValueRangePropagation::AddOrSubWithBound(Bound oldBound, Bound &resBound, int64 rhsConstant, Opcode op) { @@ -1862,8 +1873,8 @@ bool ValueRangePropagation::AddOrSubWithBound(Bound oldBound, Bound &resBound, i } // Create new valueRange when old valueRange add or sub with a constant. -std::unique_ptr ValueRangePropagation::AddOrSubWithValueRange( - Opcode op, ValueRange &valueRange, int64 rhsConstant) { +std::unique_ptr ValueRangePropagation::AddOrSubWithValueRange(Opcode op, ValueRange &valueRange, + int64 rhsConstant) { if (valueRange.GetRangeType() == kLowerAndUpper) { Bound lower; if (!AddOrSubWithBound(valueRange.GetLower(), lower, rhsConstant, op)) { @@ -1891,13 +1902,13 @@ std::unique_ptr ValueRangePropagation::AddOrSubWithValueRange( } // deal with the case like var % x, range is [1-x, x-1] -std::unique_ptr ValueRangePropagation::RemWithRhsValueRange( - const OpMeExpr &opMeExpr, int64 rhsConstant) const { +std::unique_ptr ValueRangePropagation::RemWithRhsValueRange(const OpMeExpr &opMeExpr, + int64 rhsConstant) const { int64 res = 0; int64 upperRes = 0; int64 lowerRes = 0; auto pType = opMeExpr.GetOpnd(1)->GetPrimType(); - if (pType == PTY_i64 && rhsConstant == GetMinNumber(PTY_i64)) { // var % x, if var is negative unlimited + if (pType == PTY_i64 && rhsConstant == GetMinNumber(PTY_i64)) { // var % x, if var is negative unlimited return nullptr; } if (Bound(rhsConstant, pType).IsGreaterThan(Bound(nullptr, 0, pType), pType)) { @@ -1930,7 +1941,7 @@ std::unique_ptr ValueRangePropagation::RemWithRhsValueRange( // Create new valueRange when old valueRange rem with a constant. std::unique_ptr ValueRangePropagation::RemWithValueRange(const BB &bb, const OpMeExpr &opMeExpr, - int64 rhsConstant) { + int64 rhsConstant) { auto remValueRange = RemWithRhsValueRange(opMeExpr, rhsConstant); if (remValueRange == nullptr) { return nullptr; @@ -1966,8 +1977,8 @@ std::unique_ptr ValueRangePropagation::RemWithValueRange(const BB &b } // Create valueRange when deal with OP_rem. -std::unique_ptr ValueRangePropagation::DealWithRem( - const BB &bb, const MeExpr &lhsVar, const OpMeExpr &opMeExpr) { +std::unique_ptr ValueRangePropagation::DealWithRem(const BB &bb, const MeExpr &lhsVar, + const OpMeExpr &opMeExpr) { if (!IsNeededPrimType(opMeExpr.GetPrimType())) { return nullptr; } @@ -2051,8 +2062,8 @@ void ValueRangePropagation::DealWithArrayLength(const BB &bb, MeExpr &lhs, MeExp } bool IsPrimTypeUint64(PrimType pType) { - if (pType == PTY_u64 || pType == PTY_a64 || ((pType == PTY_ref || pType == PTY_ptr) && - GetPrimTypeSize(pType) == kEightByte)) { + if (pType == PTY_u64 || pType == PTY_a64 || + ((pType == PTY_ref || pType == PTY_ptr) && GetPrimTypeSize(pType) == kEightByte)) { return true; } return false; @@ -2078,9 +2089,9 @@ int64 GetRealValue(int64 value, PrimType primType) { return static_cast(value); case PTY_ref: case PTY_ptr: - if (GetPrimTypeSize(primType) == kFourByte) { // 32 bit + if (GetPrimTypeSize(primType) == kFourByte) { // 32 bit return static_cast(value); - } else { // 64 bit + } else { // 64 bit CHECK_FATAL(GetPrimTypeSize(primType) == kEightByte, "must be 64 bit"); return static_cast(value); } @@ -2109,7 +2120,7 @@ std::unique_ptr ValueRangePropagation::CopyValueRange(ValueRange &va case kSpecialLowerForLoop: if (primType == PTY_begin) { return std::make_unique(valueRange.GetLower(), valueRange.GetUpper(), valueRange.GetRangeType(), - valueRange.IsAccurate()); + valueRange.IsAccurate()); } else { Bound lower = Bound(valueRange.GetLower().GetVar(), valueRange.GetLower().GetConstant(), primType); Bound upper = Bound(valueRange.GetUpper().GetVar(), valueRange.GetUpper().GetConstant(), primType); @@ -2175,8 +2186,8 @@ void ValueRangePropagation::DealWithAssign(BB &bb, const MeStmt &stmt) { } else if (rhs->GetMeOp() == kMeOpOp) { resVR = DealWithMeOp(bb, stmt); } else if (rhs->GetMeOp() == kMeOpConst && static_cast(rhs)->GetConstVal()->GetKind() == kConstInt) { - resVR = std::make_unique( - Bound(static_cast(rhs)->GetExtIntValue(), rhs->GetPrimType()), kEqual); + resVR = std::make_unique(Bound(static_cast(rhs)->GetExtIntValue(), rhs->GetPrimType()), + kEqual); } if (resVR != nullptr) { auto pTypeOfLHS = lhs->GetPrimType(); @@ -2184,8 +2195,7 @@ void ValueRangePropagation::DealWithAssign(BB &bb, const MeStmt &stmt) { auto primTypeOfVR = resVR->GetLower().GetPrimType(); // The rhs may be truncated when assigned to lhs, // so it is necessary to judge whether the range before and after is consistent. - if (resVR->IsEqualAfterCVT(pTypeOfLHS, pTypeOfRHS) && - resVR->IsEqualAfterCVT(pTypeOfLHS, primTypeOfVR) && + if (resVR->IsEqualAfterCVT(pTypeOfLHS, pTypeOfRHS) && resVR->IsEqualAfterCVT(pTypeOfLHS, primTypeOfVR) && resVR->IsEqualAfterCVT(pTypeOfRHS, primTypeOfVR)) { Insert2Caches(bb.GetBBId(), lhs->GetExprID(), CopyValueRange(*resVR, pTypeOfLHS)); } else { @@ -2237,8 +2247,7 @@ bool ValueRangePropagation::CanComputeLoopIndVar(const MeExpr &phiLHS, MeExpr &e // Create new value range when the loop induction var is monotonic increase. std::unique_ptr ValueRangePropagation::CreateValueRangeForMonotonicIncreaseVar( - const LoopDesc &loop, BB &exitBB, const BB &bb, OpMeExpr &opMeExpr, MeExpr &opnd1, - Bound &initBound, int64 stride) { + const LoopDesc &loop, BB &exitBB, const BB &bb, OpMeExpr &opMeExpr, MeExpr &opnd1, Bound &initBound, int64 stride) { BB *inLoopBB = nullptr; BB *outLoopBB = nullptr; if (loop.Has(*exitBB.GetSucc(0))) { @@ -2251,8 +2260,8 @@ std::unique_ptr ValueRangePropagation::CreateValueRangeForMonotonicI CHECK_FATAL(!loop.Has(*exitBB.GetSucc(0)), "must not in loop"); } int64 rightConstant = 0; - if (opMeExpr.GetOp() == OP_lt || opMeExpr.GetOp() == OP_ge || - opMeExpr.GetOp() == OP_ne || opMeExpr.GetOp() == OP_eq) { + if (opMeExpr.GetOp() == OP_lt || opMeExpr.GetOp() == OP_ge || opMeExpr.GetOp() == OP_ne || + opMeExpr.GetOp() == OP_eq) { rightConstant = -stride; } Bound upperBound; @@ -2279,8 +2288,8 @@ std::unique_ptr ValueRangePropagation::CreateValueRangeForMonotonicI auto valueRangeOfUpper = DealWithAddOrSub(bb, static_cast(opnd1)); if (valueRangeOfUpper != nullptr) { int64 res = 0; - if (AddOrSubWithConstant(opnd1.GetPrimType(), OP_add, valueRangeOfUpper->GetUpper().GetConstant(), - rightConstant, res)) { + if (AddOrSubWithConstant(opnd1.GetPrimType(), OP_add, valueRangeOfUpper->GetUpper().GetConstant(), rightConstant, + res)) { upperBound = Bound(valueRangeOfUpper->GetUpper().GetVar(), res, opnd1.GetPrimType()); } if (initBound.GetVar() == nullptr) { @@ -2298,16 +2307,15 @@ std::unique_ptr ValueRangePropagation::CreateValueRangeForMonotonicI } } if (initBound.GetVar() == nullptr) { - return std::make_unique( - initBound, Bound(&opnd1, rightConstant, initBound.GetPrimType()), kSpecialUpperForLoop); + return std::make_unique(initBound, Bound(&opnd1, rightConstant, initBound.GetPrimType()), + kSpecialUpperForLoop); } return nullptr; } // Create new value range when the loop induction var is monotonic decrease. std::unique_ptr ValueRangePropagation::CreateValueRangeForMonotonicDecreaseVar( - const LoopDesc &loop, BB &exitBB, const BB &bb, OpMeExpr &opMeExpr, MeExpr &opnd1, - Bound &initBound, int64 stride) { + const LoopDesc &loop, BB &exitBB, const BB &bb, OpMeExpr &opMeExpr, MeExpr &opnd1, Bound &initBound, int64 stride) { BB *inLoopBB = nullptr; BB *outLoopBB = nullptr; if (loop.Has(*exitBB.GetSucc(0))) { @@ -2320,8 +2328,8 @@ std::unique_ptr ValueRangePropagation::CreateValueRangeForMonotonicD CHECK_FATAL(!loop.Has(*exitBB.GetSucc(0)), "must not in loop"); } int64 rightConstant = 0; - if (opMeExpr.GetOp() == OP_le || opMeExpr.GetOp() == OP_gt || - opMeExpr.GetOp() == OP_ne || opMeExpr.GetOp() == OP_eq) { + if (opMeExpr.GetOp() == OP_le || opMeExpr.GetOp() == OP_gt || opMeExpr.GetOp() == OP_ne || + opMeExpr.GetOp() == OP_eq) { rightConstant = -stride; } Bound lowerBound; @@ -2339,12 +2347,12 @@ std::unique_ptr ValueRangePropagation::CreateValueRangeForMonotonicD } return nullptr; } - return initBound.GetVar() == nullptr ? std::make_unique(lowerBound, initBound, kLowerAndUpper) : - std::make_unique(lowerBound, initBound, kSpecialUpperForLoop); + return initBound.GetVar() == nullptr ? std::make_unique(lowerBound, initBound, kLowerAndUpper) + : std::make_unique(lowerBound, initBound, kSpecialUpperForLoop); } else { if (initBound.GetVar() == nullptr) { - return std::make_unique( - Bound(&opnd1, rightConstant, opnd1.GetPrimType()), initBound, kSpecialLowerForLoop); + return std::make_unique(Bound(&opnd1, rightConstant, opnd1.GetPrimType()), initBound, + kSpecialLowerForLoop); } } return nullptr; @@ -2377,7 +2385,7 @@ void ValueRangePropagation::TravelBBs(std::vector &reversePostOrderOfLoopBB if (unreachableBBs.find(bb) != unreachableBBs.end()) { continue; } - if (i != 0) { // The phi has already been dealed with. + if (i != 0) { // The phi has already been dealed with. DealWithPhi(*bb); } for (auto it = bb->GetMeStmts().begin(); it != bb->GetMeStmts().end(); ++it) { @@ -2466,7 +2474,7 @@ std::unique_ptr ValueRangePropagation::MergeValueRangeOfPhiOperands( } bool ValueRangePropagation::MergeVrOrInitAndBackedge(MePhiNode &mePhiNode, ValueRange &vrOfInitExpr, - ValueRange &valueRange, Bound &resBound) { + ValueRange &valueRange, Bound &resBound) { bool isOnlyHasLowerBound = vrOfInitExpr.GetRangeType() == kOnlyHasLowerBound; auto pType = mePhiNode.GetLHS()->GetPrimType(); auto upperBound = isOnlyHasLowerBound ? valueRange.GetBound() : vrOfInitExpr.GetBound(); @@ -2485,8 +2493,8 @@ bool ValueRangePropagation::MergeVrOrInitAndBackedge(MePhiNode &mePhiNode, Value } } int64 res = 0; - if (AddOrSubWithConstant(pType, isOnlyHasLowerBound ? OP_sub : OP_add, - valueRange.GetBound().GetConstant(), 1, res)) { + if (AddOrSubWithConstant(pType, isOnlyHasLowerBound ? OP_sub : OP_add, valueRange.GetBound().GetConstant(), 1, + res)) { resBound = Bound(valueRange.GetBound().GetVar(), res, pType); } else { return false; @@ -2499,8 +2507,9 @@ bool ValueRangePropagation::MergeVrOrInitAndBackedge(MePhiNode &mePhiNode, Value } // Calculate the valuerange of def-operand according to the valuerange of each rhs operand. -void ValueRangePropagation::MergeValueRangeOfPhiOperands(const LoopDesc &loop, const BB &bb, - std::vector> &valueRangeOfInitExprs, size_t indexOfInitExpr) { +void ValueRangePropagation::MergeValueRangeOfPhiOperands( + const LoopDesc &loop, const BB &bb, std::vector> &valueRangeOfInitExprs, + size_t indexOfInitExpr) { size_t index = 0; for (auto &it : bb.GetMePhiList()) { if (!it.second->GetIsLive()) { @@ -2518,8 +2527,8 @@ void ValueRangePropagation::MergeValueRangeOfPhiOperands(const LoopDesc &loop, c index++; continue; } - Bound resBound = vrOfInitExpr->GetRangeType() == kOnlyHasLowerBound ? - Bound(nullptr, GetMaxNumber(pType), pType) : Bound( nullptr, GetMinNumber(pType), pType); + Bound resBound = vrOfInitExpr->GetRangeType() == kOnlyHasLowerBound ? Bound(nullptr, GetMaxNumber(pType), pType) + : Bound(nullptr, GetMinNumber(pType), pType); bool vrCanBeComputed = true; index++; bool isAccurateBound = false; @@ -2529,16 +2538,14 @@ void ValueRangePropagation::MergeValueRangeOfPhiOperands(const LoopDesc &loop, c } auto *operand = mePhiNode->GetOpnd(i); auto *valueRange = FindValueRange(*bb.GetPred(i), *operand); - if (valueRange == nullptr || - valueRange->GetRangeType() == kOnlyHasUpperBound || - valueRange->GetRangeType() == kOnlyHasLowerBound || - vrOfInitExpr->IsEqual(valueRange) || + if (valueRange == nullptr || valueRange->GetRangeType() == kOnlyHasUpperBound || + valueRange->GetRangeType() == kOnlyHasLowerBound || vrOfInitExpr->IsEqual(valueRange) || !MergeVrOrInitAndBackedge(*mePhiNode, *vrOfInitExpr, *valueRange, resBound)) { vrCanBeComputed = false; break; } - isAccurateBound = valueRange->IsAccurate() || valueRange->GetRangeType() == kEqual || - valueRange->GetRangeType() == kNotEqual; + isAccurateBound = + valueRange->IsAccurate() || valueRange->GetRangeType() == kEqual || valueRange->GetRangeType() == kNotEqual; } if (!vrCanBeComputed) { continue; @@ -2547,9 +2554,9 @@ void ValueRangePropagation::MergeValueRangeOfPhiOperands(const LoopDesc &loop, c onlyRecordValueRangeInTempCache.push(false); bool isOnlyHasLowerBound = vrOfInitExpr->GetRangeType() == kOnlyHasLowerBound; - auto valueRangeOfPhi = isOnlyHasLowerBound ? - std::make_unique(vrOfInitExpr->GetBound(), resBound, kLowerAndUpper) : - std::make_unique(resBound, vrOfInitExpr->GetBound(), kLowerAndUpper); + auto valueRangeOfPhi = isOnlyHasLowerBound + ? std::make_unique(vrOfInitExpr->GetBound(), resBound, kLowerAndUpper) + : std::make_unique(resBound, vrOfInitExpr->GetBound(), kLowerAndUpper); if (!valueRangeOfPhi->IsConstantRange() || stride == 1) { if (loop.IsCanonicalAndOnlyHasOneExitBBLoop() && isAccurateBound) { valueRangeOfPhi->SetAccurate(true); @@ -2617,7 +2624,7 @@ bool ValueRangePropagation::Insert2Caches(BBId bbID, int32 exprID, std::unique_p // The rangeType of vrOfRHS is kEqual and the rangeType of vrOfLHS is kEqual, kNotEqual or kLowerAndUpper void ValueRangePropagation::JudgeEqual(MeExpr &expr, ValueRange &vrOfLHS, ValueRange &vrOfRHS, - std::unique_ptr &valueRangePtr) { + std::unique_ptr &valueRangePtr) { if (vrOfRHS.GetRangeType() != kEqual) { return; } @@ -2655,7 +2662,7 @@ void ValueRangePropagation::JudgeEqual(MeExpr &expr, ValueRange &vrOfLHS, ValueR } else if (vrOfLHS.GetRangeType() == kLowerAndUpper) { if (!vrOfLHS.GetLower().IsGreaterThan(vrOfLHS.GetUpper(), primType) && (vrOfLHS.GetLower().IsGreaterThan(vrOfRHS.GetBound(), primType) || - vrOfRHS.GetBound().IsGreaterThan(vrOfLHS.GetUpper(), primType))) { + vrOfRHS.GetBound().IsGreaterThan(vrOfLHS.GetUpper(), primType))) { // dealwith this case: // a = (b == c) // valueRange(b): kLowerAndUpper (1, Max) @@ -2804,8 +2811,9 @@ ValueRange *ValueRangePropagation::FindValueRange(const BB &bb, MeExpr &expr) { return nullptr; } -std::unique_ptr ValueRangePropagation::CreateInitVRForPhi(LoopDesc &loop, - const BB &bb, ScalarMeExpr &init, ScalarMeExpr &backedge, const ScalarMeExpr &lhsOfPhi) { +std::unique_ptr ValueRangePropagation::CreateInitVRForPhi(LoopDesc &loop, const BB &bb, ScalarMeExpr &init, + ScalarMeExpr &backedge, + const ScalarMeExpr &lhsOfPhi) { Bound initBound; ValueRange *valueRangeOfInit = FindValueRange(bb, init); if (valueRangeOfInit != nullptr && valueRangeOfInit->IsConstant() && valueRangeOfInit->GetRangeType() != kNotEqual) { @@ -2914,9 +2922,9 @@ void ValueRangePropagation::DealWithPhi(const BB &bb) { } if (backExprOfPhi.empty()) { valueRangeOfInitExprs.emplace_back(nullptr); - } else if (initExprsOfPhi.size() == 1 && backExprOfPhi.size() == 1) { // Create vr for initial value of phi node. - auto vrOfInitExpr = CreateInitVRForPhi( - *loop, bb, **initExprsOfPhi.begin(), **backExprOfPhi.begin(), *pair.second->GetLHS()); + } else if (initExprsOfPhi.size() == 1 && backExprOfPhi.size() == 1) { // Create vr for initial value of phi node. + auto vrOfInitExpr = + CreateInitVRForPhi(*loop, bb, **initExprsOfPhi.begin(), **backExprOfPhi.begin(), *pair.second->GetLHS()); valueRangeOfInitExprs.emplace_back(std::move(vrOfInitExpr)); } else { valueRangeOfInitExprs.emplace_back(nullptr); @@ -2972,8 +2980,7 @@ Bound ValueRangePropagation::Min(Bound leftBound, Bound rightBound) { // Judge whether the lower is in range. bool ValueRangePropagation::LowerInRange(const BB &bb, Bound lowerTemp, Bound lower, bool lowerIsZero) { - if ((lowerIsZero && lowerTemp.GetVar() == nullptr) || - (!lowerIsZero && lowerTemp.GetVar() == lower.GetVar())) { + if ((lowerIsZero && lowerTemp.GetVar() == nullptr) || (!lowerIsZero && lowerTemp.GetVar() == lower.GetVar())) { int64 lowerConstant = lowerIsZero ? 0 : lower.GetConstant(); return (lowerTemp.GetConstant() >= lowerConstant); } else { @@ -2986,8 +2993,7 @@ bool ValueRangePropagation::LowerInRange(const BB &bb, Bound lowerTemp, Bound lo return LowerInRange(bb, lowerRangeValue->GetLower(), lower, lowerIsZero); } else { Bound newLower; - if (CreateNewBoundWhenAddOrSub(OP_add, lowerRangeValue->GetBound(), - lowerTemp.GetConstant(), newLower)) { + if (CreateNewBoundWhenAddOrSub(OP_add, lowerRangeValue->GetBound(), lowerTemp.GetConstant(), newLower)) { return LowerInRange(bb, newLower, lower, lowerIsZero); } } @@ -3000,8 +3006,8 @@ bool ValueRangePropagation::LowerInRange(const BB &bb, Bound lowerTemp, Bound lo // Judge whether the upper is in range. bool ValueRangePropagation::UpperInRange(const BB &bb, Bound upperTemp, Bound upper, bool upperIsArrayLength) { if (upperTemp.GetVar() == upper.GetVar()) { - return upperIsArrayLength ? (upperTemp.GetConstant() < upper.GetConstant()) : - (upperTemp.GetConstant() <= upper.GetConstant()); + return upperIsArrayLength ? (upperTemp.GetConstant() < upper.GetConstant()) + : (upperTemp.GetConstant() <= upper.GetConstant()); } if (upperTemp.GetVar() == nullptr) { return false; @@ -3014,22 +3020,19 @@ bool ValueRangePropagation::UpperInRange(const BB &bb, Bound upperTemp, Bound up currVar = length2Def[currVar]; if (currVar == upper.GetVar()) { Bound newUpper; - if (CreateNewBoundWhenAddOrSub( - OP_add, upper, upperTemp.GetConstant(), newUpper)) { + if (CreateNewBoundWhenAddOrSub(OP_add, upper, upperTemp.GetConstant(), newUpper)) { return UpperInRange(bb, newUpper, upper, upperIsArrayLength); } else { return false; } } } - } else if (upperRangeValue->IfLowerEqualToUpper() && - upperRangeValue->GetUpper().GetVar() != upperVar) { + } else if (upperRangeValue->IfLowerEqualToUpper() && upperRangeValue->GetUpper().GetVar() != upperVar) { if (upperTemp.GetConstant() == 0) { return UpperInRange(bb, upperRangeValue->GetUpper(), upper, upperIsArrayLength); } else { Bound newUpper; - if (CreateNewBoundWhenAddOrSub(OP_add, upperRangeValue->GetBound(), - upperTemp.GetConstant(), newUpper)) { + if (CreateNewBoundWhenAddOrSub(OP_add, upperRangeValue->GetBound(), upperTemp.GetConstant(), newUpper)) { return UpperInRange(bb, newUpper, upper, upperIsArrayLength); } else { return false; @@ -3037,16 +3040,16 @@ bool ValueRangePropagation::UpperInRange(const BB &bb, Bound upperTemp, Bound up } } else if (!upperRangeValue->IfLowerEqualToUpper()) { if (length2Def.find(upperVar) != length2Def.end() && length2Def[upperVar] == upper.GetVar()) { - return upperIsArrayLength ? (upperTemp.GetConstant() < upper.GetConstant()) : - (upperTemp.GetConstant() <= upper.GetConstant()); + return upperIsArrayLength ? (upperTemp.GetConstant() < upper.GetConstant()) + : (upperTemp.GetConstant() <= upper.GetConstant()); } } return false; } // Judge whether the lower and upper are in range. -InRangeType ValueRangePropagation::InRange(const BB &bb, const ValueRange &rangeTemp, - const ValueRange &range, bool lowerIsZero) { +InRangeType ValueRangePropagation::InRange(const BB &bb, const ValueRange &rangeTemp, const ValueRange &range, + bool lowerIsZero) { bool lowerInRange = LowerInRange(bb, rangeTemp.GetLower(), range.GetLower(), lowerIsZero); Bound upperBound; if (lowerIsZero && !range.IfLowerEqualToUpper()) { @@ -3066,24 +3069,28 @@ InRangeType ValueRangePropagation::InRange(const BB &bb, const ValueRange &range } } -std::unique_ptr ValueRangePropagation::CombineTwoValueRange( - const ValueRange &leftRange, const ValueRange &rightRange, bool merge) { +std::unique_ptr ValueRangePropagation::CombineTwoValueRange(const ValueRange &leftRange, + const ValueRange &rightRange, bool merge) { if (merge) { return std::make_unique(Min(leftRange.GetLower(), rightRange.GetLower()), Max(leftRange.GetUpper(), rightRange.GetUpper()), kLowerAndUpper); } else { if (rightRange.GetRangeType() == kOnlyHasLowerBound) { - return std::make_unique(rightRange.GetLower(), Max(leftRange.GetUpper(), - Bound(GetMaxNumber(rightRange.GetUpper().GetPrimType()), rightRange.GetUpper().GetPrimType())), - kLowerAndUpper, rightRange.IsAccurate()); + return std::make_unique( + rightRange.GetLower(), + Max(leftRange.GetUpper(), + Bound(GetMaxNumber(rightRange.GetUpper().GetPrimType()), rightRange.GetUpper().GetPrimType())), + kLowerAndUpper, rightRange.IsAccurate()); } if (rightRange.GetRangeType() == kOnlyHasUpperBound) { - return std::make_unique(Min(leftRange.GetLower(), - Bound(GetMinNumber(rightRange.GetLower().GetPrimType()), rightRange.GetLower().GetPrimType())), - leftRange.GetUpper(), kLowerAndUpper, rightRange.IsAccurate()); + return std::make_unique( + Min(leftRange.GetLower(), + Bound(GetMinNumber(rightRange.GetLower().GetPrimType()), rightRange.GetLower().GetPrimType())), + leftRange.GetUpper(), kLowerAndUpper, rightRange.IsAccurate()); } return std::make_unique(Max(leftRange.GetLower(), rightRange.GetLower()), - Min(leftRange.GetUpper(), rightRange.GetUpper()), kLowerAndUpper, rightRange.IsAccurate()); + Min(leftRange.GetUpper(), rightRange.GetUpper()), kLowerAndUpper, + rightRange.IsAccurate()); } } @@ -3110,8 +3117,8 @@ void ValueRangePropagation::ChangeLoop2Goto(LoopDesc &loop, BB &bb, BB &succBB, void ValueRangePropagation::Insert2UnreachableBBs(BB &unreachableBB) { if (ValueRangePropagation::isDebug) { - LogInfo::MapleLogger() << "=====================delete bb " << unreachableBB.GetBBId() << - "========================\n"; + LogInfo::MapleLogger() << "=====================delete bb " << unreachableBB.GetBBId() + << "========================\n"; } unreachableBBs.insert(&unreachableBB); return; @@ -3126,9 +3133,20 @@ void ValueRangePropagation::AnalysisUnreachableBBOrEdge(BB &bb, BB &unreachableB UpdateProfile(*pred, bb, unreachableBB); } Insert2UnreachableBBs(unreachableBB); + // update frequency before cfg changed + int64_t removedFreq = 0; + if (func.GetCfg()->UpdateCFGFreq()) { + int idx = bb.GetSuccIndex(unreachableBB); + removedFreq = bb.GetSuccFreq()[idx]; + } bb.RemoveSucc(unreachableBB); bb.RemoveMeStmt(bb.GetLastMe()); bb.SetKind(kBBFallthru); + if (func.GetCfg()->UpdateCFGFreq()) { + bb.SetSuccFreq(0, bb.GetFrequency()); + succBB.SetFrequency(succBB.GetFrequency() + removedFreq); + unreachableBB.SetFrequency(0); + } auto *loop = loops->GetBBLoopParent(bb.GetBBId()); if (loop == nullptr) { return; @@ -3137,25 +3155,20 @@ void ValueRangePropagation::AnalysisUnreachableBBOrEdge(BB &bb, BB &unreachableB } // Judge whether the value range is in range. -bool ValueRangePropagation::BrStmtInRange(const BB &bb, const ValueRange &leftRange, - const ValueRange &rightRange, Opcode op, PrimType opndType, - bool judgeNotInRange) { +bool ValueRangePropagation::BrStmtInRange(const BB &bb, const ValueRange &leftRange, const ValueRange &rightRange, + Opcode op, PrimType opndType, bool judgeNotInRange) { Bound leftLower = leftRange.GetLower(); Bound leftUpper = leftRange.GetUpper(); Bound rightLower = rightRange.GetLower(); Bound rightUpper = rightRange.GetUpper(); RangeType leftRangeType = leftRange.GetRangeType(); RangeType rightRangeType = rightRange.GetRangeType(); - if (!IsNeededPrimType(opndType) || - leftLower.GetVar() != leftUpper.GetVar() || leftUpper.GetVar() != rightUpper.GetVar() || - rightUpper.GetVar() != rightLower.GetVar() || leftRangeType == kSpecialLowerForLoop || - leftRangeType == kSpecialUpperForLoop || - leftRange.GetRangeType() == kOnlyHasLowerBound || - leftRange.GetRangeType() == kOnlyHasUpperBound || - rightRangeType == kSpecialLowerForLoop || - rightRangeType == kSpecialUpperForLoop || - rightRange.GetRangeType() == kOnlyHasLowerBound || - rightRange.GetRangeType() == kOnlyHasUpperBound) { + if (!IsNeededPrimType(opndType) || leftLower.GetVar() != leftUpper.GetVar() || + leftUpper.GetVar() != rightUpper.GetVar() || rightUpper.GetVar() != rightLower.GetVar() || + leftRangeType == kSpecialLowerForLoop || leftRangeType == kSpecialUpperForLoop || + leftRange.GetRangeType() == kOnlyHasLowerBound || leftRange.GetRangeType() == kOnlyHasUpperBound || + rightRangeType == kSpecialLowerForLoop || rightRangeType == kSpecialUpperForLoop || + rightRange.GetRangeType() == kOnlyHasLowerBound || rightRange.GetRangeType() == kOnlyHasUpperBound) { return false; } if (judgeNotInRange) { @@ -3171,16 +3184,13 @@ bool ValueRangePropagation::BrStmtInRange(const BB &bb, const ValueRange &leftRa } } // deal the difference between i32 and u32. - if (leftLower.IsGreaterThan(leftUpper, opndType) || - rightLower.IsGreaterThan(rightUpper, opndType)) { + if (leftLower.IsGreaterThan(leftUpper, opndType) || rightLower.IsGreaterThan(rightUpper, opndType)) { return false; } if ((op == OP_eq && !judgeNotInRange) || (op == OP_ne && judgeNotInRange)) { // If the range of leftOpnd equal to the range of rightOpnd, remove the falseBranch. - return leftRangeType != kNotEqual && rightRangeType != kNotEqual && - leftLower.IsEqual(leftUpper, opndType) && - rightLower.IsEqual(rightUpper, opndType) && - leftLower.IsEqual(rightLower, opndType); + return leftRangeType != kNotEqual && rightRangeType != kNotEqual && leftLower.IsEqual(leftUpper, opndType) && + rightLower.IsEqual(rightUpper, opndType) && leftLower.IsEqual(rightLower, opndType); } else if ((op == OP_ne && !judgeNotInRange) || (op == OP_eq && judgeNotInRange)) { // If the range type of leftOpnd is kLowerAndUpper and the rightRange is not in range of it, // remove the trueBranch, such as : @@ -3188,9 +3198,9 @@ bool ValueRangePropagation::BrStmtInRange(const BB &bb, const ValueRange &leftRa // valueRange a: [1, max] // valueRange b: 0 return (leftRangeType != kNotEqual && rightRangeType != kNotEqual && - (leftLower.IsGreaterThan(rightUpper, opndType) || rightLower.IsGreaterThan(leftUpper, opndType))) || - (leftRangeType == kNotEqual && rightRangeType == kEqual && leftLower.IsEqual(rightLower, opndType)) || - (leftRangeType == kEqual && rightRangeType == kNotEqual && leftLower.IsEqual(rightLower, opndType)); + (leftLower.IsGreaterThan(rightUpper, opndType) || rightLower.IsGreaterThan(leftUpper, opndType))) || + (leftRangeType == kNotEqual && rightRangeType == kEqual && leftLower.IsEqual(rightLower, opndType)) || + (leftRangeType == kEqual && rightRangeType == kNotEqual && leftLower.IsEqual(rightLower, opndType)); } else if ((op == OP_lt && !judgeNotInRange) || (op == OP_ge && judgeNotInRange)) { return leftRangeType != kNotEqual && rightRangeType != kNotEqual && rightLower.IsGreaterThan(leftUpper, opndType); } else if ((op == OP_ge && !judgeNotInRange) || (op == OP_lt && judgeNotInRange)) { @@ -3213,42 +3223,40 @@ void ValueRangePropagation::GetTrueAndFalseBranch(Opcode op, BB &bb, BB *&trueBr } } -void ValueRangePropagation::CreateValueRangeForLeOrLt( - const MeExpr &opnd, const ValueRange *leftRange, Bound newRightUpper, Bound newRightLower, - const BB &trueBranch, const BB &falseBranch, bool isAccurate) { +void ValueRangePropagation::CreateValueRangeForLeOrLt(const MeExpr &opnd, const ValueRange *leftRange, + Bound newRightUpper, Bound newRightLower, const BB &trueBranch, + const BB &falseBranch, bool isAccurate) { CHECK_FATAL(IsEqualPrimType(newRightUpper.GetPrimType(), newRightLower.GetPrimType()), "must be equal"); if (leftRange == nullptr) { std::unique_ptr newTrueBranchRange = std::make_unique( ValueRange::MinBound(newRightUpper.GetPrimType()), newRightUpper, kLowerAndUpper, isAccurate); (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), std::move(newTrueBranchRange)); - std::unique_ptr newFalseBranchRange = std::make_unique(newRightLower, - ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); + std::unique_ptr newFalseBranchRange = std::make_unique( + newRightLower, ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), std::move(newFalseBranchRange)); } else if (leftRange->GetRangeType() == kOnlyHasLowerBound) { std::unique_ptr newRightRange = std::make_unique( ValueRange::MinBound(newRightUpper.GetPrimType()), newRightUpper, kLowerAndUpper, isAccurate); - std::unique_ptr newLeftRange = std::make_unique(leftRange->GetLower(), - ValueRange::MaxBound(leftRange->GetLower().GetPrimType()), kLowerAndUpper, isAccurate); - (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), - CombineTwoValueRange(*leftRange, *newRightRange)); - newRightRange = std::make_unique( - newRightLower, ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); + std::unique_ptr newLeftRange = std::make_unique( + leftRange->GetLower(), ValueRange::MaxBound(leftRange->GetLower().GetPrimType()), kLowerAndUpper, isAccurate); + (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), CombineTwoValueRange(*leftRange, *newRightRange)); + newRightRange = std::make_unique(newRightLower, ValueRange::MaxBound(newRightUpper.GetPrimType()), + kLowerAndUpper, isAccurate); } else if (leftRange->GetRangeType() == kOnlyHasUpperBound) { std::unique_ptr newRightRange = std::make_unique( ValueRange::MinBound(newRightUpper.GetPrimType()), newRightUpper, kLowerAndUpper, isAccurate); std::unique_ptr newLeftRange = std::make_unique( ValueRange::MinBound(newRightUpper.GetPrimType()), leftRange->GetBound(), kLowerAndUpper, isAccurate); - newRightRange = std::make_unique( - newRightLower, ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); - (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), - CombineTwoValueRange(*leftRange, *newRightRange)); + newRightRange = std::make_unique(newRightLower, ValueRange::MaxBound(newRightUpper.GetPrimType()), + kLowerAndUpper, isAccurate); + (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), CombineTwoValueRange(*leftRange, *newRightRange)); } else { std::unique_ptr newRightRange = std::make_unique( ValueRange::MinBound(newRightUpper.GetPrimType()), newRightUpper, kLowerAndUpper, isAccurate); auto resTrueBranchVR = CombineTwoValueRange(*leftRange, *newRightRange); (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), CopyValueRange(*resTrueBranchVR)); - newRightRange = std::make_unique( - newRightLower, ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); + newRightRange = std::make_unique(newRightLower, ValueRange::MaxBound(newRightUpper.GetPrimType()), + kLowerAndUpper, isAccurate); auto resFalseBranchVR = CombineTwoValueRange(*leftRange, *newRightRange); (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), CopyValueRange(*resFalseBranchVR)); // Deal with the case like: @@ -3267,55 +3275,52 @@ void ValueRangePropagation::CreateValueRangeForLeOrLt( } } -void ValueRangePropagation::CreateValueRangeForGeOrGt( - const MeExpr &opnd, const ValueRange *leftRange, Bound newRightUpper, Bound newRightLower, - const BB &trueBranch, const BB &falseBranch, bool isAccurate) { +void ValueRangePropagation::CreateValueRangeForGeOrGt(const MeExpr &opnd, const ValueRange *leftRange, + Bound newRightUpper, Bound newRightLower, const BB &trueBranch, + const BB &falseBranch, bool isAccurate) { CHECK_FATAL(IsEqualPrimType(newRightUpper.GetPrimType(), newRightLower.GetPrimType()), "must be equal"); if (leftRange == nullptr) { - std::unique_ptr newTrueBranchRange = std::make_unique(newRightLower, - ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); + std::unique_ptr newTrueBranchRange = std::make_unique( + newRightLower, ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), std::move(newTrueBranchRange)); std::unique_ptr newFalseBranchRange = std::make_unique( ValueRange::MinBound(newRightUpper.GetPrimType()), newRightUpper, kLowerAndUpper, isAccurate); (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), std::move(newFalseBranchRange)); } else if (leftRange->GetRangeType() == kOnlyHasLowerBound) { - auto newRightRange = std::make_unique( - ValueRange::MinBound(newRightUpper.GetPrimType()), newRightUpper, kLowerAndUpper, isAccurate); - (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), - CombineTwoValueRange(*leftRange, *newRightRange)); + auto newRightRange = std::make_unique(ValueRange::MinBound(newRightUpper.GetPrimType()), newRightUpper, + kLowerAndUpper, isAccurate); + (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), CombineTwoValueRange(*leftRange, *newRightRange)); } else if (leftRange->GetRangeType() == kOnlyHasUpperBound) { - std::unique_ptr newRightRange = std::make_unique(newRightLower, - ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); - (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), - CombineTwoValueRange(*leftRange, *newRightRange)); + std::unique_ptr newRightRange = std::make_unique( + newRightLower, ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); + (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), CombineTwoValueRange(*leftRange, *newRightRange)); } else { - std::unique_ptr newRightRange = std::make_unique(newRightLower, - ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); + std::unique_ptr newRightRange = std::make_unique( + newRightLower, ValueRange::MaxBound(newRightUpper.GetPrimType()), kLowerAndUpper, isAccurate); (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), CombineTwoValueRange(*leftRange, *newRightRange)); newRightRange = std::make_unique(ValueRange::MinBound(newRightUpper.GetPrimType()), newRightUpper, - kLowerAndUpper, isAccurate); - (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), - CombineTwoValueRange(*leftRange, *newRightRange)); + kLowerAndUpper, isAccurate); + (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), CombineTwoValueRange(*leftRange, *newRightRange)); } } // Return true if the lower or upper of leftRange is equal to the bound of rightRange, like this: // leftRang: (5, constant) rightRange: (5) ==> return true; // leftRang: (constant, 5) rightRange: (5) ==> return true; -bool ValueRangePropagation::IfTheLowerOrUpperOfLeftRangeEqualToTheRightRange( - const ValueRange &leftRange, ValueRange &rightRange, bool isLower) const { - bool lowerOrUpperIsEqual = isLower ? leftRange.GetLower().GetConstant() == rightRange.GetBound().GetConstant() : - leftRange.GetUpper().GetConstant() == rightRange.GetBound().GetConstant(); +bool ValueRangePropagation::IfTheLowerOrUpperOfLeftRangeEqualToTheRightRange(const ValueRange &leftRange, + ValueRange &rightRange, + bool isLower) const { + bool lowerOrUpperIsEqual = isLower ? leftRange.GetLower().GetConstant() == rightRange.GetBound().GetConstant() + : leftRange.GetUpper().GetConstant() == rightRange.GetBound().GetConstant(); return leftRange.GetRangeType() == kLowerAndUpper && leftRange.IsConstantLowerAndUpper() && leftRange.GetLower().GetConstant() < leftRange.GetUpper().GetConstant() && lowerOrUpperIsEqual; } -void ValueRangePropagation::CreateValueRangeForNeOrEq( - const MeExpr &opnd, const ValueRange *leftRange, ValueRange &rightRange, const BB &trueBranch, - const BB &falseBranch) { +void ValueRangePropagation::CreateValueRangeForNeOrEq(const MeExpr &opnd, const ValueRange *leftRange, + ValueRange &rightRange, const BB &trueBranch, + const BB &falseBranch) { if (rightRange.GetRangeType() == kEqual) { - std::unique_ptr newTrueBranchRange = - std::make_unique(rightRange.GetBound(), kEqual); + std::unique_ptr newTrueBranchRange = std::make_unique(rightRange.GetBound(), kEqual); auto &opMeExpr = static_cast(opnd); if (opMeExpr.GetOp() == OP_zext && rightRange.IsConstant() && opMeExpr.GetOpnd(0)->GetPrimType() == GetIntegerPrimTypeBySizeAndSign(opMeExpr.GetBitsSize(), false)) { @@ -3323,8 +3328,7 @@ void ValueRangePropagation::CreateValueRangeForNeOrEq( } (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), std::move(newTrueBranchRange)); if (leftRange == nullptr) { - std::unique_ptr newFalseBranchRange = - std::make_unique(rightRange.GetBound(), kNotEqual); + std::unique_ptr newFalseBranchRange = std::make_unique(rightRange.GetBound(), kNotEqual); (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), std::move(newFalseBranchRange)); } else if (IfTheLowerOrUpperOfLeftRangeEqualToTheRightRange(*leftRange, rightRange, true)) { // Deal with this case: @@ -3351,18 +3355,15 @@ void ValueRangePropagation::CreateValueRangeForNeOrEq( (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), std::move(newFalseBranchRange)); } } else if (leftRange->GetRangeType() == kLowerAndUpper) { - std::unique_ptr newFalseBranchRange = - std::make_unique(rightRange.GetBound(), kNotEqual); + std::unique_ptr newFalseBranchRange = std::make_unique(rightRange.GetBound(), kNotEqual); (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), std::move(newFalseBranchRange)); } else if (leftRange->GetRangeType() == kOnlyHasLowerBound || leftRange->GetRangeType() == kOnlyHasUpperBound) { - std::unique_ptr newFalseBranchRange = - std::make_unique(rightRange.GetBound(), kNotEqual); + std::unique_ptr newFalseBranchRange = std::make_unique(rightRange.GetBound(), kNotEqual); (void)Insert2Caches(falseBranch.GetBBId(), opnd.GetExprID(), std::move(newFalseBranchRange)); } } else if (rightRange.GetRangeType() == kNotEqual) { if (leftRange == nullptr) { - std::unique_ptr newTrueBranchRange = - std::make_unique(rightRange.GetBound(), kNotEqual); + std::unique_ptr newTrueBranchRange = std::make_unique(rightRange.GetBound(), kNotEqual); (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), std::move(newTrueBranchRange)); } else if (IfTheLowerOrUpperOfLeftRangeEqualToTheRightRange(*leftRange, rightRange, true)) { Bound newLower; @@ -3379,8 +3380,7 @@ void ValueRangePropagation::CreateValueRangeForNeOrEq( (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), std::move(newTrueBranchRange)); } } else if (leftRange->GetRangeType() == kOnlyHasLowerBound || leftRange->GetRangeType() == kOnlyHasUpperBound) { - std::unique_ptr newTrueBranchRange = - std::make_unique(rightRange.GetBound(), kNotEqual); + std::unique_ptr newTrueBranchRange = std::make_unique(rightRange.GetBound(), kNotEqual); (void)Insert2Caches(trueBranch.GetBBId(), opnd.GetExprID(), std::move(newTrueBranchRange)); } } @@ -3390,8 +3390,8 @@ void ValueRangePropagation::CreateValueRangeForNeOrEq( // if a == 5 // If the valueRange of a is valuerange(5, kEqual), delete the false branch. // Else if the valeuRange of a is valueRange(5, kNotEqual), delete the ture branch. -bool ValueRangePropagation::ConditionBBCanBeDeletedAfterOPNeOrEq( - BB &bb, ValueRange &leftRange, ValueRange &rightRange, BB &falseBranch, BB &trueBranch) { +bool ValueRangePropagation::ConditionBBCanBeDeletedAfterOPNeOrEq(BB &bb, ValueRange &leftRange, ValueRange &rightRange, + BB &falseBranch, BB &trueBranch) { if ((leftRange.GetRangeType() == kEqual && rightRange.GetRangeType() == kEqual) && leftRange.GetBound().GetVar() == rightRange.GetBound().GetVar()) { if (leftRange.GetBound().GetConstant() == rightRange.GetBound().GetConstant()) { @@ -3429,7 +3429,7 @@ void ValueRangePropagation::UpdateProfile(BB &pred, BB &bb, const BB &targetBB) } auto *condGotoStmt = static_cast(bb.GetLastMe()); if (condGotoStmt->GetBranchProb() != kProbLikely && condGotoStmt->GetBranchProb() != kProbUnlikely) { - return; // need not update profile + return; // need not update profile } int32 targetBranchProb = 0; if (&targetBB == bb.GetSucc(0)) { @@ -3439,7 +3439,7 @@ void ValueRangePropagation::UpdateProfile(BB &pred, BB &bb, const BB &targetBB) targetBranchProb = condGotoStmt->GetBranchProb(); } BB *predCondGoto = &pred; - BB *succBB = &bb; // succ of predCondGoto to targetBB + BB *succBB = &bb; // succ of predCondGoto to targetBB while (predCondGoto != nullptr) { if (predCondGoto->GetKind() == kBBCondGoto) { break; @@ -3480,9 +3480,9 @@ void ValueRangePropagation::UpdateProfile(BB &pred, BB &bb, const BB &targetBB) // \ / \ ----> | | // \ / \ | | // false true false true -void ValueRangePropagation::RemoveUnreachableBB( - BB &condGotoBB, BB &trueBranch, ScalarMeExpr *updateSSAExceptTheScalarExpr, - std::map> &ssaupdateCandsForCondExpr) { +void ValueRangePropagation::RemoveUnreachableBB(BB &condGotoBB, BB &trueBranch, + ScalarMeExpr *updateSSAExceptTheScalarExpr, + std::map> &ssaupdateCandsForCondExpr) { CHECK_FATAL(condGotoBB.GetSucc().size() == kNumOperands, "must have 2 succ"); auto *succ0 = condGotoBB.GetSucc(0); auto *succ1 = condGotoBB.GetSucc(1); @@ -3494,6 +3494,12 @@ void ValueRangePropagation::RemoveUnreachableBB( UpdateProfile(*condGotoBB.GetPred(0), condGotoBB, trueBranch); } condGotoBB.SetKind(kBBFallthru); + // update frequency before cfg changed + if (func.GetCfg()->UpdateCFGFreq()) { + int64_t removedFreq = condGotoBB.GetSuccFreq()[1]; + condGotoBB.SetSuccFreq(0, condGotoBB.GetFrequency()); + succ0->SetFrequency(succ0->GetFrequency() + removedFreq); + } condGotoBB.RemoveSucc(*succ1); DeleteThePhiNodeWhichOnlyHasOneOpnd(*succ1, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); condGotoBB.RemoveMeStmt(condGotoBB.GetLastMe()); @@ -3506,7 +3512,16 @@ void ValueRangePropagation::RemoveUnreachableBB( UpdateProfile(*condGotoBB.GetPred(0), condGotoBB, trueBranch); } condGotoBB.SetKind(kBBFallthru); + int64_t removedFreq = 0; + // update frequency before cfg changed + if (func.GetCfg()->UpdateCFGFreq()) { + removedFreq = condGotoBB.GetSuccFreq()[0]; + } condGotoBB.RemoveSucc(*succ0); + if (func.GetCfg()->UpdateCFGFreq()) { + condGotoBB.SetSuccFreq(0, condGotoBB.GetFrequency()); + succ1->SetFrequency(succ1->GetFrequency() + removedFreq); + } DeleteThePhiNodeWhichOnlyHasOneOpnd(*succ0, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); condGotoBB.RemoveMeStmt(condGotoBB.GetLastMe()); } @@ -3664,10 +3679,22 @@ bool ValueRangePropagation::ChangeTheSuccOfPred2TrueBranch( if (exitCopyFallthru != nullptr) { PrepareForSSAUpdateWhenPredBBIsRemoved(pred, bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); size_t index = FindBBInSuccs(pred, bb); + int64_t edgeFreq = 0; + if (func.GetCfg()->UpdateCFGFreq()) { + edgeFreq = pred.GetSuccFreq()[index]; + } pred.RemoveSucc(bb); DeleteThePhiNodeWhichOnlyHasOneOpnd(bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); pred.AddSucc(*exitCopyFallthru, index); CreateLabelForTargetBB(pred, *exitCopyFallthru); + if (func.GetCfg()->UpdateCFGFreq()) { + exitCopyFallthru->SetFrequency(exitCopyFallthru->GetFrequency() + edgeFreq); + pred.AddSuccFreq(edgeFreq, index); + // update bb frequency + ASSERT(bb.GetFrequency() >= edgeFreq, "sanity check"); + bb.SetFrequency(bb.GetFrequency() - edgeFreq); + bb.UpdateEdgeFreqs(); + } return true; } if (CodeSizeIsOverflowOrTheOpOfStmtIsNotSupported(bb)) { @@ -3689,20 +3716,33 @@ bool ValueRangePropagation::ChangeTheSuccOfPred2TrueBranch( predOfCurrBB = currBB; currBB = currBB->GetSucc(0); CopyMeStmts(*currBB, *mergeAllFallthruBBs); - PrepareForSSAUpdateWhenPredBBIsRemoved( - *predOfCurrBB, *currBB, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); + PrepareForSSAUpdateWhenPredBBIsRemoved(*predOfCurrBB, *currBB, updateSSAExceptTheScalarExpr, + ssaupdateCandsForCondExpr); } if (predOfCurrBB != nullptr) { - PrepareForSSAUpdateWhenPredBBIsRemoved( - *predOfCurrBB, *currBB, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); + PrepareForSSAUpdateWhenPredBBIsRemoved(*predOfCurrBB, *currBB, updateSSAExceptTheScalarExpr, + ssaupdateCandsForCondExpr); } CHECK_FATAL(currBB->GetKind() == kBBCondGoto, "must be condgoto bb"); auto *gotoMeStmt = irMap.New(func.GetOrCreateBBLabel(trueBranch)); mergeAllFallthruBBs->AddMeStmtLast(gotoMeStmt); PrepareForSSAUpdateWhenPredBBIsRemoved(pred, bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); size_t index = FindBBInSuccs(pred, bb); + int64_t edgeFreq = 0; + if (func.GetCfg()->UpdateCFGFreq()) { + edgeFreq = pred.GetSuccFreq()[index]; + } pred.RemoveSucc(bb); pred.AddSucc(*mergeAllFallthruBBs, index); + if (func.GetCfg()->UpdateCFGFreq()) { + mergeAllFallthruBBs->SetFrequency(edgeFreq); + mergeAllFallthruBBs->PushBackSuccFreq(edgeFreq); + pred.AddSuccFreq(edgeFreq, index); + // update bb frequency + ASSERT(bb.GetFrequency() >= edgeFreq, "sanity check"); + bb.SetFrequency(bb.GetFrequency() - edgeFreq); + bb.UpdateEdgeFreqs(); + } mergeAllFallthruBBs->AddSucc(trueBranch); DeleteThePhiNodeWhichOnlyHasOneOpnd(bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); CreateLabelForTargetBB(pred, *mergeAllFallthruBBs); @@ -3732,8 +3772,8 @@ bool ValueRangePropagation::CopyFallthruBBAndRemoveUnreachableEdge( do { tmpPred = tmpPred->GetSucc(0); if (GetRealPredSize(*tmpPred) > 1) { - return ChangeTheSuccOfPred2TrueBranch( - pred, bb, trueBranch, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); + return ChangeTheSuccOfPred2TrueBranch(pred, bb, trueBranch, updateSSAExceptTheScalarExpr, + ssaupdateCandsForCondExpr); } } while (tmpPred->GetKind() != kBBCondGoto); if (GetRealPredSize(bb) != 1) { @@ -3759,27 +3799,56 @@ bool ValueRangePropagation::CopyFallthruBBAndRemoveUnreachableEdge( // true false true false true false // case1: the number of branches reaching to condBB > 1 // case2: the number of branches reaching to condBB == 1 -bool ValueRangePropagation::RemoveTheEdgeOfPredBB( - BB &pred, BB &bb, BB &trueBranch, ScalarMeExpr *updateSSAExceptTheScalarExpr, - std::map> &ssaupdateCandsForCondExpr) { +bool ValueRangePropagation::RemoveTheEdgeOfPredBB(BB &pred, BB &bb, BB &trueBranch, + ScalarMeExpr *updateSSAExceptTheScalarExpr, + std::map> &ssaupdateCandsForCondExpr) { CHECK_FATAL(bb.GetKind() == kBBCondGoto, "must be condgoto bb"); if (GetRealPredSize(bb) >= kNumOperands) { if (OnlyHaveCondGotoStmt(bb)) { PrepareForSSAUpdateWhenPredBBIsRemoved(pred, bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); size_t index = FindBBInSuccs(pred, bb); + int64_t edgeFreq = 0; + if (func.GetCfg()->UpdateCFGFreq()) { + edgeFreq = pred.GetSuccFreq()[index]; + ASSERT(bb.GetFrequency() >= edgeFreq, "sanity check"); + } pred.RemoveSucc(bb); DeleteThePhiNodeWhichOnlyHasOneOpnd(bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); pred.AddSucc(trueBranch, index); CreateLabelForTargetBB(pred, trueBranch); + if (func.GetCfg()->UpdateCFGFreq()) { + bb.SetFrequency(bb.GetFrequency() - edgeFreq); + size_t trueBranchIdx = bb.GetSuccIndex(trueBranch); + int64_t updatedtrueFreq = bb.GetSuccFreq()[trueBranchIdx] - edgeFreq; + // transform may not be consistent with frequency value + updatedtrueFreq = updatedtrueFreq > 0 ? updatedtrueFreq : 0; + bb.SetSuccFreq(trueBranchIdx, updatedtrueFreq); + pred.AddSuccFreq(edgeFreq, index); + } } else { auto *exitCopyFallthru = GetNewCopyFallthruBB(trueBranch, bb); if (exitCopyFallthru != nullptr) { PrepareForSSAUpdateWhenPredBBIsRemoved(pred, bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); size_t index = FindBBInSuccs(pred, bb); + int64_t edgeFreq = 0; + if (func.GetCfg()->UpdateCFGFreq()) { + edgeFreq = pred.GetSuccFreq()[index]; + ASSERT(bb.GetFrequency() >= edgeFreq, "sanity check"); + } pred.RemoveSucc(bb); DeleteThePhiNodeWhichOnlyHasOneOpnd(bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); pred.AddSucc(*exitCopyFallthru, index); CreateLabelForTargetBB(pred, *exitCopyFallthru); + if (func.GetCfg()->UpdateCFGFreq()) { + bb.SetFrequency(bb.GetFrequency() - edgeFreq); + exitCopyFallthru->SetFrequency(edgeFreq); + exitCopyFallthru->PushBackSuccFreq(edgeFreq); + size_t trueBranchIdx = bb.GetSuccIndex(trueBranch); + int64_t updatedtrueFreq = bb.GetSuccFreq()[trueBranchIdx] - edgeFreq; + ASSERT(updatedtrueFreq >= 0, "sanity check"); + bb.SetSuccFreq(trueBranchIdx, updatedtrueFreq); + pred.AddSuccFreq(edgeFreq, index); + } return true; } auto *newBB = CreateNewGotoBBWithoutCondGotoStmt(bb); @@ -3793,9 +3862,21 @@ bool ValueRangePropagation::RemoveTheEdgeOfPredBB( newBB->AddMeStmtLast(gotoMeStmt); PrepareForSSAUpdateWhenPredBBIsRemoved(pred, bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); size_t index = FindBBInSuccs(pred, bb); + int64_t edgeFreq = 0; + if (func.GetCfg()->UpdateCFGFreq()) { + edgeFreq = pred.GetSuccFreq()[index]; + ASSERT(bb.GetFrequency() >= edgeFreq, "sanity check"); + } pred.RemoveSucc(bb); pred.AddSucc(*newBB, index); newBB->AddSucc(trueBranch); + if (func.GetCfg()->UpdateCFGFreq()) { + bb.SetFrequency(bb.GetFrequency() - edgeFreq); + bb.UpdateEdgeFreqs(); + newBB->SetFrequency(edgeFreq); + newBB->PushBackSuccFreq(edgeFreq); + pred.AddSuccFreq(edgeFreq, index); + } DeleteThePhiNodeWhichOnlyHasOneOpnd(bb, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); (void)func.GetOrCreateBBLabel(trueBranch); CreateLabelForTargetBB(pred, *newBB); @@ -3808,15 +3889,15 @@ bool ValueRangePropagation::RemoveTheEdgeOfPredBB( } // tmpPred, tmpBB, reachableBB -bool ValueRangePropagation::RemoveUnreachableEdge( - BB &pred, BB &bb, BB &trueBranch, ScalarMeExpr *updateSSAExceptTheScalarExpr, - std::map> &ssaupdateCandsForCondExpr) { +bool ValueRangePropagation::RemoveUnreachableEdge(BB &pred, BB &bb, BB &trueBranch, + ScalarMeExpr *updateSSAExceptTheScalarExpr, + std::map> &ssaupdateCandsForCondExpr) { if (onlyPropVR) { return false; } if (bb.GetKind() == kBBFallthru || bb.GetKind() == kBBGoto) { - if (!CopyFallthruBBAndRemoveUnreachableEdge( - pred, bb, trueBranch, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr)) { + if (!CopyFallthruBBAndRemoveUnreachableEdge(pred, bb, trueBranch, updateSSAExceptTheScalarExpr, + ssaupdateCandsForCondExpr)) { return false; } } else { @@ -3825,8 +3906,8 @@ bool ValueRangePropagation::RemoveUnreachableEdge( } } if (ValueRangePropagation::isDebug) { - LogInfo::MapleLogger() << "===========delete edge " << pred.GetBBId() << " " << bb.GetBBId() << " " << - trueBranch.GetBBId() << "===========\n"; + LogInfo::MapleLogger() << "===========delete edge " << pred.GetBBId() << " " << bb.GetBBId() << " " + << trueBranch.GetBBId() << "===========\n"; } if (trueBranch.GetPred().size() > 1) { (void)func.GetOrCreateBBLabel(trueBranch); @@ -3836,14 +3917,16 @@ bool ValueRangePropagation::RemoveUnreachableEdge( } bool ValueRangePropagation::ConditionEdgeCanBeDeleted(BB &pred, BB &bb, const ValueRange *leftRange, - const ValueRange *rightRange, BB &falseBranch, BB &trueBranch, PrimType opndType, Opcode op, - ScalarMeExpr *updateSSAExceptTheScalarExpr, std::map> &ssaupdateCandsForCondExpr) { + const ValueRange *rightRange, BB &falseBranch, BB &trueBranch, + PrimType opndType, Opcode op, + ScalarMeExpr *updateSSAExceptTheScalarExpr, + std::map> &ssaupdateCandsForCondExpr) { if (leftRange == nullptr || rightRange == nullptr) { return false; } if (ValueRangePropagation::isDebug) { - LogInfo::MapleLogger() << "try to delete edge " << pred.GetBBId() << " " << bb.GetBBId() << " " << - trueBranch.GetBBId() << "\n"; + LogInfo::MapleLogger() << "try to delete edge " << pred.GetBBId() << " " << bb.GetBBId() << " " + << trueBranch.GetBBId() << "\n"; } /* Find the first bb with more than one pred */ auto *tmpPred = &pred; @@ -3857,12 +3940,11 @@ bool ValueRangePropagation::ConditionEdgeCanBeDeleted(BB &pred, BB &bb, const Va // opnd, tmpPred, tmpBB, reachableBB // remove falseBranch UpdateProfile(*tmpPred, *tmpBB, trueBranch); - return RemoveUnreachableEdge( - *tmpPred, *tmpBB, trueBranch, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); + return RemoveUnreachableEdge(*tmpPred, *tmpBB, trueBranch, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); } else if (BrStmtInRange(bb, *leftRange, *rightRange, antiOp, opndType)) { UpdateProfile(*tmpPred, *tmpBB, falseBranch); - return RemoveUnreachableEdge( - *tmpPred, *tmpBB, falseBranch, updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr); + return RemoveUnreachableEdge(*tmpPred, *tmpBB, falseBranch, updateSSAExceptTheScalarExpr, + ssaupdateCandsForCondExpr); } return false; } @@ -3887,8 +3969,9 @@ std::unique_ptr ValueRangePropagation::AntiValueRange(ValueRange &va return nullptr; } RangeType newType = (oldType == kEqual) ? kNotEqual : kEqual; - return std::make_unique(Bound(valueRange.GetBound().GetVar(), valueRange.GetBound().GetConstant(), - valueRange.GetBound().GetPrimType()), newType); + return std::make_unique( + Bound(valueRange.GetBound().GetVar(), valueRange.GetBound().GetConstant(), valueRange.GetBound().GetPrimType()), + newType); } void ValueRangePropagation::DeleteUnreachableBBs(BB &curBB, BB &falseBranch, BB &trueBranch) { @@ -3912,8 +3995,9 @@ void ValueRangePropagation::DeleteUnreachableBBs(BB &curBB, BB &falseBranch, BB } } -void ValueRangePropagation::PropValueRangeFromCondGotoToTrueAndFalseBranch( - const MeExpr &opnd0, ValueRange &rightRange, const BB &falseBranch, const BB &trueBranch) { +void ValueRangePropagation::PropValueRangeFromCondGotoToTrueAndFalseBranch(const MeExpr &opnd0, ValueRange &rightRange, + const BB &falseBranch, + const BB &trueBranch) { std::unique_ptr trueBranchValueRange; std::unique_ptr falseBranchValueRange; trueBranchValueRange = CopyValueRange(rightRange); @@ -3927,8 +4011,8 @@ void ValueRangePropagation::PropValueRangeFromCondGotoToTrueAndFalseBranch( // predOpnd: a, rhs of currOpnd in this bb // phiOpnds: (b, c), phi rhs of opnd in this bb // predOpnd or phiOpnds is uesd to find the valuerange in the pred of bb -void ValueRangePropagation::ReplaceOpndByDef(const BB &bb, MeExpr &currOpnd, MeExpr *&predOpnd, - MePhiNode *&phi, bool &thePhiIsInBB) { +void ValueRangePropagation::ReplaceOpndByDef(const BB &bb, MeExpr &currOpnd, MeExpr *&predOpnd, MePhiNode *&phi, + bool &thePhiIsInBB) { /* If currOpnd is not defined in bb, set opnd to currOpnd */ predOpnd = &currOpnd; /* find the rhs of opnd */ @@ -4033,9 +4117,10 @@ bool ValueRangePropagation::TowCompareOperandsAreInSameIterOfLoop(const MeExpr & return true; } -bool ValueRangePropagation::AnalysisValueRangeInPredsOfCondGotoBB( - BB &bb, MeExpr *opnd0, MeExpr &currOpnd, ValueRange *rightRange, - BB &falseBranch, BB &trueBranch, PrimType opndType, Opcode op, BB &condGoto) { +bool ValueRangePropagation::AnalysisValueRangeInPredsOfCondGotoBB(BB &bb, MeExpr *opnd0, MeExpr &currOpnd, + ValueRange *rightRange, BB &falseBranch, + BB &trueBranch, PrimType opndType, Opcode op, + BB &condGoto) { bool opt = false; /* Records the currOpnd of pred */ MeExpr *predOpnd = nullptr; @@ -4164,7 +4249,7 @@ bool ValueRangePropagation::AnalysisValueRangeInPredsOfCondGotoBB( } } if (ConditionEdgeCanBeDeleted(*pred, bb, valueRangeInPred, rightRange, falseBranch, trueBranch, opndType, op, - updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr)) { + updateSSAExceptTheScalarExpr, ssaupdateCandsForCondExpr)) { if (updateSSAExceptTheScalarExpr != nullptr && phi != nullptr) { if (updateSSAExceptTheScalarExpr->GetDefBy() == kDefByStmt) { // PredOpnd is only used by condGoto stmt and phi, if the condGoto stmt can be deleted, need not update ssa @@ -4182,11 +4267,11 @@ bool ValueRangePropagation::AnalysisValueRangeInPredsOfCondGotoBB( opt = true; } else { /* avoid infinite loop, pred->GetKind() maybe kBBUnknown */ - if ((pred->GetKind() == kBBFallthru || pred->GetKind() == kBBGoto) && - pred->GetBBId() != falseBranch.GetBBId() && pred->GetBBId() != trueBranch.GetBBId() && - (opnd0 == nullptr || TowCompareOperandsAreInSameIterOfLoop(currOpnd, *opnd0))) { - opt |= AnalysisValueRangeInPredsOfCondGotoBB( - *pred, opnd0, *predOpnd, rightRange, falseBranch, trueBranch, opndType, op, condGoto); + if ((pred->GetKind() == kBBFallthru || pred->GetKind() == kBBGoto) && pred->GetBBId() != falseBranch.GetBBId() && + pred->GetBBId() != trueBranch.GetBBId() && + (opnd0 == nullptr || TowCompareOperandsAreInSameIterOfLoop(currOpnd, *opnd0))) { + opt |= AnalysisValueRangeInPredsOfCondGotoBB(*pred, opnd0, *predOpnd, rightRange, falseBranch, trueBranch, + opndType, op, condGoto); } } if (bb.GetPred().size() == predSize) { @@ -4227,8 +4312,8 @@ bool ValueRangePropagation::AnalysisValueRangeInPredsOfCondGotoBB( // ==> // if mx12 void ValueRangePropagation::ReplaceUsePoints(MePhiNode *phi) { - if (phi == nullptr || phi->GetDefBB() == nullptr || - phi->GetDefBB()->GetMePhiList().empty() || phi->GetOpnds().empty()) { + if (phi == nullptr || phi->GetDefBB() == nullptr || phi->GetDefBB()->GetMePhiList().empty() || + phi->GetOpnds().empty()) { return; } auto *opnd = phi->GetOpnd(0); @@ -4286,8 +4371,8 @@ Opcode ValueRangePropagation::GetOpAfterSwapThePositionsOfTwoOperands(Opcode op) } } -bool ValueRangePropagation::ConditionEdgeCanBeDeleted(BB &bb, MeExpr &opnd0, ValueRange *rightRange, - PrimType opndType, Opcode op) { +bool ValueRangePropagation::ConditionEdgeCanBeDeleted(BB &bb, MeExpr &opnd0, ValueRange *rightRange, PrimType opndType, + Opcode op) { if (onlyPropVR) { return false; } @@ -4308,8 +4393,8 @@ bool ValueRangePropagation::ConditionEdgeCanBeDeleted(BB &bb, MeExpr &opnd0, Val BB *trueBranch = nullptr; BB *falseBranch = nullptr; GetTrueAndFalseBranch(static_cast(bb.GetLastMe())->GetOp(), bb, trueBranch, falseBranch); - bool opt = AnalysisValueRangeInPredsOfCondGotoBB( - bb, nullptr, *currOpnd, rightRange, *falseBranch, *trueBranch, opndType, op, bb); + bool opt = AnalysisValueRangeInPredsOfCondGotoBB(bb, nullptr, *currOpnd, rightRange, *falseBranch, *trueBranch, + opndType, op, bb); if (!opt && bb.GetKind() == kBBCondGoto && static_cast(bb.GetLastMe())->GetOpnd()->GetNumOpnds() == kNumOperands) { // Swap the positions of two operands like : @@ -4324,8 +4409,8 @@ bool ValueRangePropagation::ConditionEdgeCanBeDeleted(BB &bb, MeExpr &opnd0, Val // opnd[1] = CONST 0 mx1 auto *valueRangeOfOpnd0 = FindValueRange(bb, opnd0); - opt = AnalysisValueRangeInPredsOfCondGotoBB(bb, currOpnd, *opnd1, valueRangeOfOpnd0, *falseBranch, - *trueBranch, opndType, GetOpAfterSwapThePositionsOfTwoOperands(op), bb); + opt = AnalysisValueRangeInPredsOfCondGotoBB(bb, currOpnd, *opnd1, valueRangeOfOpnd0, *falseBranch, *trueBranch, + opndType, GetOpAfterSwapThePositionsOfTwoOperands(op), bb); } bool canDeleteBB = false; for (size_t i = 0; i < bb.GetPred().size(); ++i) { @@ -4360,7 +4445,8 @@ Opcode ValueRangePropagation::GetTheOppositeOp(Opcode op) const { } void ValueRangePropagation::CreateValueRangeForCondGoto(const MeExpr &opnd, Opcode op, ValueRange *leftRange, - ValueRange &rightRange, const BB &trueBranch, const BB &falseBranch) { + ValueRange &rightRange, const BB &trueBranch, + const BB &falseBranch) { auto newRightUpper = rightRange.GetUpper(); auto newRightLower = rightRange.GetLower(); CHECK_FATAL(IsEqualPrimType(newRightUpper.GetPrimType(), newRightLower.GetPrimType()), "must be equal"); @@ -4388,23 +4474,21 @@ void ValueRangePropagation::CreateValueRangeForCondGoto(const MeExpr &opnd, Opco bool isAccurate = dealWithPhi && (rightRange.GetRangeType() == kEqual || rightRange.IsAccurate()); if (op == OP_lt || op == OP_le) { if (leftRange != nullptr && leftRange->GetRangeType() == kNotEqual) { - CreateValueRangeForLeOrLt( - opnd, nullptr, newRightUpper, newRightLower, trueBranch, falseBranch, isAccurate); + CreateValueRangeForLeOrLt(opnd, nullptr, newRightUpper, newRightLower, trueBranch, falseBranch, isAccurate); } else { CreateValueRangeForLeOrLt(opnd, leftRange, newRightUpper, newRightLower, trueBranch, falseBranch, isAccurate); } } else if (op == OP_gt || op == OP_ge) { if (leftRange != nullptr && leftRange->GetRangeType() == kNotEqual) { - CreateValueRangeForGeOrGt( - opnd, nullptr, newRightUpper, newRightLower, trueBranch, falseBranch, isAccurate); + CreateValueRangeForGeOrGt(opnd, nullptr, newRightUpper, newRightLower, trueBranch, falseBranch, isAccurate); } else { CreateValueRangeForGeOrGt(opnd, leftRange, newRightUpper, newRightLower, trueBranch, falseBranch, isAccurate); } } } -void ValueRangePropagation::DealWithCondGoto( - BB &bb, Opcode op, ValueRange *leftRange, ValueRange &rightRange, const CondGotoMeStmt &brMeStmt) { +void ValueRangePropagation::DealWithCondGoto(BB &bb, Opcode op, ValueRange *leftRange, ValueRange &rightRange, + const CondGotoMeStmt &brMeStmt) { MeExpr *opnd0 = nullptr; PrimType primType; if (IsCompareHasReverseOp(brMeStmt.GetOpnd()->GetOp())) { @@ -4438,12 +4522,13 @@ void ValueRangePropagation::DealWithCondGoto( } bool ValueRangePropagation::GetValueRangeOfCondGotoOpnd(const BB &bb, OpMeExpr &opMeExpr, MeExpr &opnd, - ValueRange *&valueRange, std::unique_ptr &rightRangePtr) { + ValueRange *&valueRange, + std::unique_ptr &rightRangePtr) { valueRange = FindValueRange(bb, opnd); if (valueRange == nullptr) { if (opnd.GetMeOp() == kMeOpConst && static_cast(opnd).GetConstVal()->GetKind() == kConstInt) { - rightRangePtr = std::make_unique(Bound(static_cast(opnd).GetExtIntValue(), - opnd.GetPrimType()), kEqual); + rightRangePtr = std::make_unique( + Bound(static_cast(opnd).GetExtIntValue(), opnd.GetPrimType()), kEqual); valueRange = rightRangePtr.get(); if (!Insert2Caches(bb.GetBBId(), opnd.GetExprID(), std::move(rightRangePtr))) { valueRange = nullptr; @@ -4482,8 +4567,8 @@ bool ValueRangePropagation::GetValueRangeOfCondGotoOpnd(const BB &bb, OpMeExpr & valueRange = rightRangePtr.get(); (void)Insert2Caches(bb.GetBBId(), opnd.GetExprID(), std::move(rightRangePtr)); } else if ((opnd.GetOp() == OP_ne && lhsBound.IsEqual(rhsBound, rhsPrimType) && lhsRangeType == kEqual) || - (opnd.GetOp() == OP_eq && !lhsBound.IsEqual(rhsBound, rhsPrimType) && lhsRangeType == kEqual) || - (opnd.GetOp() == OP_eq && lhsBound.IsEqual(rhsBound, rhsPrimType) && lhsRangeType == kNotEqual)) { + (opnd.GetOp() == OP_eq && !lhsBound.IsEqual(rhsBound, rhsPrimType) && lhsRangeType == kEqual) || + (opnd.GetOp() == OP_eq && lhsBound.IsEqual(rhsBound, rhsPrimType) && lhsRangeType == kNotEqual)) { rightRangePtr = std::make_unique(Bound(nullptr, 0, PTY_u1), kEqual); valueRange = rightRangePtr.get(); (void)Insert2Caches(bb.GetBBId(), opnd.GetExprID(), std::move(rightRangePtr)); @@ -4509,8 +4594,9 @@ MeExpr *ValueRangePropagation::GetDefOfBase(const IvarMeExpr &ivar) const { return var->GetDefStmt()->GetLHS(); } -void ValueRangePropagation::DealWithCondGotoWhenRightRangeIsNotExist( - BB &bb, const MeExpr &opnd0, MeExpr &opnd1, Opcode opOfBrStmt, Opcode conditionalOp, ValueRange *valueRangeOfLeft) { +void ValueRangePropagation::DealWithCondGotoWhenRightRangeIsNotExist(BB &bb, const MeExpr &opnd0, MeExpr &opnd1, + Opcode opOfBrStmt, Opcode conditionalOp, + ValueRange *valueRangeOfLeft) { PrimType prim = opnd1.GetPrimType(); if (!IsNeededPrimType(prim)) { return; @@ -4521,72 +4607,76 @@ void ValueRangePropagation::DealWithCondGotoWhenRightRangeIsNotExist( switch (conditionalOp) { case OP_ne: { (void)Insert2Caches(trueBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(Bound(&opnd1, prim), kNotEqual)); + std::make_unique(Bound(&opnd1, prim), kNotEqual)); (void)Insert2Caches(falseBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(Bound(&opnd1, prim), kEqual)); + std::make_unique(Bound(&opnd1, prim), kEqual)); break; } case OP_eq: { (void)Insert2Caches(trueBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(Bound(&opnd1, prim), kEqual)); + std::make_unique(Bound(&opnd1, prim), kEqual)); (void)Insert2Caches(falseBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(Bound(&opnd1, prim), kNotEqual)); + std::make_unique(Bound(&opnd1, prim), kNotEqual)); break; } case OP_le: { if (valueRangeOfLeft != nullptr && valueRangeOfLeft->GetRangeType() == kOnlyHasLowerBound) { (void)Insert2Caches(trueBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(valueRangeOfLeft->GetLower(), - Bound(&opnd1, prim), kLowerAndUpper, dealWithPhi)); + std::make_unique(valueRangeOfLeft->GetLower(), Bound(&opnd1, prim), + kLowerAndUpper, dealWithPhi)); } else { - (void)Insert2Caches(trueBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(Bound(GetMinNumber(prim), prim), - Bound(&opnd1, prim), kLowerAndUpper)); + (void)Insert2Caches( + trueBranch->GetBBId(), opnd0.GetExprID(), + std::make_unique(Bound(GetMinNumber(prim), prim), Bound(&opnd1, prim), kLowerAndUpper)); } - (void)Insert2Caches(falseBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(Bound(&opnd1, 1, prim), - Bound(GetMaxNumber(prim), prim), kLowerAndUpper)); + (void)Insert2Caches( + falseBranch->GetBBId(), opnd0.GetExprID(), + std::make_unique(Bound(&opnd1, 1, prim), Bound(GetMaxNumber(prim), prim), kLowerAndUpper)); break; } case OP_lt: { if (valueRangeOfLeft != nullptr && valueRangeOfLeft->GetRangeType() == kOnlyHasLowerBound) { (void)Insert2Caches(trueBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(valueRangeOfLeft->GetLower(), - Bound(&opnd1, -1, prim), kLowerAndUpper, dealWithPhi)); + std::make_unique(valueRangeOfLeft->GetLower(), Bound(&opnd1, -1, prim), + kLowerAndUpper, dealWithPhi)); } else { - (void)Insert2Caches(trueBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(Bound(GetMinNumber(prim), prim), - Bound(&opnd1, -1, prim), kLowerAndUpper)); + (void)Insert2Caches( + trueBranch->GetBBId(), opnd0.GetExprID(), + std::make_unique(Bound(GetMinNumber(prim), prim), Bound(&opnd1, -1, prim), kLowerAndUpper)); } - (void)Insert2Caches(falseBranch->GetBBId(), opnd0.GetExprID(), + (void)Insert2Caches( + falseBranch->GetBBId(), opnd0.GetExprID(), std::make_unique(Bound(&opnd1, prim), Bound(GetMaxNumber(prim), prim), kLowerAndUpper)); break; } case OP_ge: { if (valueRangeOfLeft != nullptr && valueRangeOfLeft->GetRangeType() == kOnlyHasUpperBound) { - (void)Insert2Caches(trueBranch->GetBBId(), opnd0.GetExprID(), std::make_unique( - Bound(&opnd1, prim), valueRangeOfLeft->GetBound(), kLowerAndUpper, dealWithPhi)); - } else { (void)Insert2Caches(trueBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(Bound(&opnd1, prim), - Bound(GetMaxNumber(prim), prim), kLowerAndUpper)); + std::make_unique(Bound(&opnd1, prim), valueRangeOfLeft->GetBound(), + kLowerAndUpper, dealWithPhi)); + } else { + (void)Insert2Caches( + trueBranch->GetBBId(), opnd0.GetExprID(), + std::make_unique(Bound(&opnd1, prim), Bound(GetMaxNumber(prim), prim), kLowerAndUpper)); } - (void)Insert2Caches(falseBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(Bound(GetMinNumber(prim), prim), - Bound(&opnd1, -1, prim), kLowerAndUpper)); + (void)Insert2Caches( + falseBranch->GetBBId(), opnd0.GetExprID(), + std::make_unique(Bound(GetMinNumber(prim), prim), Bound(&opnd1, -1, prim), kLowerAndUpper)); break; } case OP_gt: { if (valueRangeOfLeft != nullptr && valueRangeOfLeft->GetRangeType() == kOnlyHasUpperBound) { - (void)Insert2Caches(trueBranch->GetBBId(), opnd0.GetExprID(), std::make_unique( - Bound(&opnd1, 1, prim), valueRangeOfLeft->GetBound(), kLowerAndUpper, dealWithPhi)); - } else { (void)Insert2Caches(trueBranch->GetBBId(), opnd0.GetExprID(), + std::make_unique(Bound(&opnd1, 1, prim), valueRangeOfLeft->GetBound(), + kLowerAndUpper, dealWithPhi)); + } else { + (void)Insert2Caches( + trueBranch->GetBBId(), opnd0.GetExprID(), std::make_unique(Bound(&opnd1, 1, prim), Bound(GetMaxNumber(prim), prim), kLowerAndUpper)); } - (void)Insert2Caches(falseBranch->GetBBId(), opnd0.GetExprID(), - std::make_unique(Bound(GetMinNumber(prim), prim), - Bound(&opnd1, prim), kLowerAndUpper)); + (void)Insert2Caches( + falseBranch->GetBBId(), opnd0.GetExprID(), + std::make_unique(Bound(GetMinNumber(prim), prim), Bound(&opnd1, prim), kLowerAndUpper)); break; } default: @@ -4595,15 +4685,16 @@ void ValueRangePropagation::DealWithCondGotoWhenRightRangeIsNotExist( } void ValueRangePropagation::GetValueRangeForUnsignedInt(const BB &bb, OpMeExpr &opMeExpr, const MeExpr &opnd, - ValueRange *&valueRange, std::unique_ptr &rightRangePtr) { + ValueRange *&valueRange, + std::unique_ptr &rightRangePtr) { if (onlyPropVR) { return; } PrimType prim = opMeExpr.GetOpndType(); if (prim == PTY_u1 || prim == PTY_u8 || prim == PTY_u16 || prim == PTY_u32 || prim == PTY_a32 || ((prim == PTY_ref || prim == PTY_ptr) && GetPrimTypeSize(prim) == kFourByte)) { - rightRangePtr = std::make_unique( - Bound(nullptr, 0, prim), Bound(GetMaxNumber(prim), prim), kLowerAndUpper); + rightRangePtr = + std::make_unique(Bound(nullptr, 0, prim), Bound(GetMaxNumber(prim), prim), kLowerAndUpper); valueRange = rightRangePtr.get(); (void)Insert2Caches(bb.GetBBId(), opnd.GetExprID(), std::move(rightRangePtr)); } @@ -4614,8 +4705,8 @@ void ValueRangePropagation::GetValueRangeForUnsignedInt(const BB &bb, OpMeExpr & // a: valuerange(0, Max) // ==> // Example: if (a != 0) -bool ValueRangePropagation::DealWithSpecialCondGoto( - const BB &bb, OpMeExpr &opMeExpr, const ValueRange &leftRange, ValueRange &rightRange, CondGotoMeStmt &brMeStmt) { +bool ValueRangePropagation::DealWithSpecialCondGoto(const BB &bb, OpMeExpr &opMeExpr, const ValueRange &leftRange, + ValueRange &rightRange, CondGotoMeStmt &brMeStmt) { if (onlyPropVR) { return false; } @@ -4639,8 +4730,8 @@ bool ValueRangePropagation::DealWithSpecialCondGoto( if (leftRange.GetLower().GetConstant() != rightRange.GetBound().GetConstant()) { return false; } - auto *newExpr = irMap.CreateMeExprCompare(OP_ne, opMeExpr.GetPrimType(), - opMeExpr.GetOpndType(), *opMeExpr.GetOpnd(0), *opMeExpr.GetOpnd(1)); + auto *newExpr = irMap.CreateMeExprCompare(OP_ne, opMeExpr.GetPrimType(), opMeExpr.GetOpndType(), + *opMeExpr.GetOpnd(0), *opMeExpr.GetOpnd(1)); (void)irMap.ReplaceMeExprStmt(brMeStmt, opMeExpr, *newExpr); return true; } @@ -4663,8 +4754,8 @@ bool ValueRangePropagation::DealWithSpecialCondGoto( } } auto *newConstExpr = irMap.CreateIntConstMeExpr(leftRange.GetLower().GetConstant(), opMeExpr.GetOpndType()); - auto *newExpr = irMap.CreateMeExprCompare(OP_eq, opMeExpr.GetPrimType(), - opMeExpr.GetOpndType(), *opMeExpr.GetOpnd(0), *newConstExpr); + auto *newExpr = irMap.CreateMeExprCompare(OP_eq, opMeExpr.GetPrimType(), opMeExpr.GetOpndType(), *opMeExpr.GetOpnd(0), + *newConstExpr); (void)irMap.ReplaceMeExprStmt(brMeStmt, opMeExpr, *newExpr); return true; } @@ -4679,11 +4770,11 @@ void ValueRangePropagation::DealWithBrStmtWithOneOpnd(BB &bb, const CondGotoMeSt // op: OP_ne // rightRange: 0 // leftRange: const 1 or var a - std::unique_ptr rightRangePtr = std::make_unique( - Bound(nullptr, 0, opnd.GetPrimType()), kEqual); + std::unique_ptr rightRangePtr = + std::make_unique(Bound(nullptr, 0, opnd.GetPrimType()), kEqual); if (opnd.GetMeOp() == kMeOpConst && static_cast(opnd).GetConstVal()->GetKind() == kConstInt) { std::unique_ptr leftRangePtr = std::make_unique( - Bound(static_cast(opnd).GetExtIntValue(), opnd.GetPrimType()), kEqual); + Bound(static_cast(opnd).GetExtIntValue(), opnd.GetPrimType()), kEqual); DealWithCondGoto(bb, op, leftRangePtr.get(), *rightRangePtr.get(), stmt); } else { ValueRange *leftRange = FindValueRange(bb, opnd); @@ -4763,14 +4854,14 @@ bool ValueRangePropagation::AnalysisUnreachableForGeOrGt(BB &bb, const CondGotoM // mx1: valuerange [min(mx2_type), mx2-1] or [min(mx2_type), mx2] // ==> // remove falseBranch or trueBranch -bool ValueRangePropagation::AnalysisUnreachableForLeOrLt( - BB &bb, const CondGotoMeStmt &brMeStmt, const ValueRange &leftRange) { +bool ValueRangePropagation::AnalysisUnreachableForLeOrLt(BB &bb, const CondGotoMeStmt &brMeStmt, + const ValueRange &leftRange) { Opcode op = static_cast(brMeStmt.GetOpnd())->GetOp(); BB *trueBranch = nullptr; BB *falseBranch = nullptr; GetTrueAndFalseBranch(brMeStmt.GetOp(), bb, trueBranch, falseBranch); // When the redundant branch can be inferred directly from the condGoto stmt - if (op == OP_lt && leftRange.GetUpper().GetConstant() == -1) { + if (op == OP_lt && leftRange.GetUpper().GetConstant() == -1) { // falseBranch is unreachable AnalysisUnreachableBBOrEdge(bb, *falseBranch, *trueBranch); return true; @@ -4803,8 +4894,7 @@ bool ValueRangePropagation::AnalysisUnreachableForEqOrNe(BB &bb, const CondGotoM BB *falseBranch = nullptr; GetTrueAndFalseBranch(brMeStmt.GetOp(), bb, trueBranch, falseBranch); // When the redundant branch can be inferred directly from the condGoto stmt - if ((op == OP_eq && leftRange.GetRangeType() == kEqual) || - (op == OP_ne && leftRange.GetRangeType() == kNotEqual)) { + if ((op == OP_eq && leftRange.GetRangeType() == kEqual) || (op == OP_ne && leftRange.GetRangeType() == kNotEqual)) { // falseBranch is unreachable AnalysisUnreachableBBOrEdge(bb, *falseBranch, *trueBranch); return true; @@ -4819,21 +4909,20 @@ bool ValueRangePropagation::AnalysisUnreachableForEqOrNe(BB &bb, const CondGotoM // This function deals with the case like this: // Example: first brfalse mx1 eq(ne/gt/le/ge/lt) mx2 // second brfalse mx1 eq(ne/gt/le/ge/lt) mx2 ==> remove falseBranch or trueBranch -bool ValueRangePropagation::DealWithVariableRange(BB &bb, const CondGotoMeStmt &brMeStmt, - const ValueRange &leftRange) { +bool ValueRangePropagation::DealWithVariableRange(BB &bb, const CondGotoMeStmt &brMeStmt, const ValueRange &leftRange) { MeExpr *opnd1 = static_cast(brMeStmt.GetOpnd())->GetOpnd(1); // Example1: deal with like if (mx1 > mx2), when the valuerange of mx1 is [mx2+1, max(mx2_type)] // Example2: deal with like if (mx1 >= mx2), when the valuerange of mx1 is [mx2, max(mx2_type)] if (leftRange.GetLower().GetVar() == opnd1 && leftRange.GetUpper().GetVar() == nullptr && leftRange.UpperIsMax(opnd1->GetPrimType())) { return AnalysisUnreachableForGeOrGt(bb, brMeStmt, leftRange); - // Example1: deal with like if (mx1 < mx2), when the valuerange of mx1 is [min(mx2_type), mx2-1] - // Example2: deal with like if (mx1 <= mx2), when the valuerange of mx1 is [min(mx2_type), mx2] + // Example1: deal with like if (mx1 < mx2), when the valuerange of mx1 is [min(mx2_type), mx2-1] + // Example2: deal with like if (mx1 <= mx2), when the valuerange of mx1 is [min(mx2_type), mx2] } else if (leftRange.GetLower().GetVar() == nullptr && leftRange.GetUpper().GetVar() == opnd1 && - leftRange.LowerIsMin(opnd1->GetPrimType())) { + leftRange.LowerIsMin(opnd1->GetPrimType())) { return AnalysisUnreachableForLeOrLt(bb, brMeStmt, leftRange); - // Example: deal with like if (mx1 == mx2), when the valuerange of mx1 is [mx2, mx2] - // Example: deal with like if (mx1 != mx2), when the valuerange of mx1 is [mx2, mx2] + // Example: deal with like if (mx1 == mx2), when the valuerange of mx1 is [mx2, mx2] + // Example: deal with like if (mx1 != mx2), when the valuerange of mx1 is [mx2, mx2] } else if (leftRange.GetLower().GetVar() == opnd1 && leftRange.GetLower().GetConstant() == 0 && leftRange.GetUpper().GetVar() == opnd1 && leftRange.GetUpper().GetConstant() == 0) { return AnalysisUnreachableForEqOrNe(bb, brMeStmt, leftRange); @@ -4897,7 +4986,8 @@ void ValueRangePropagation::DealWithCondGoto(BB &bb, MeStmt &stmt) { } void ValueRangePropagation::DumpCaches() { - LogInfo::MapleLogger() << "================Dump value range===================" << "\n"; + LogInfo::MapleLogger() << "================Dump value range===================" + << "\n"; for (size_t i = 0; i < caches.size(); ++i) { LogInfo::MapleLogger() << "BBId: " << i << "\n"; auto &it = caches[i]; @@ -4905,17 +4995,16 @@ void ValueRangePropagation::DumpCaches() { if (bIt->second == nullptr) { continue; } - if (bIt->second->GetRangeType() == kLowerAndUpper || - bIt->second->GetRangeType() == kSpecialLowerForLoop || + if (bIt->second->GetRangeType() == kLowerAndUpper || bIt->second->GetRangeType() == kSpecialLowerForLoop || bIt->second->GetRangeType() == kSpecialUpperForLoop) { - std::string lower = (bIt->second->GetLower().GetVar() == nullptr) ? - std::to_string(bIt->second->GetLower().GetConstant()) : - "mx" + std::to_string(bIt->second->GetLower().GetVar()->GetExprID()) + " " + - std::to_string(bIt->second->GetLower().GetConstant()); - std::string upper = (bIt->second->GetUpper().GetVar() == nullptr) ? - std::to_string(bIt->second->GetUpper().GetConstant()) : - "mx" + std::to_string(bIt->second->GetUpper().GetVar()->GetExprID()) + " " + - std::to_string(bIt->second->GetUpper().GetConstant()); + std::string lower = (bIt->second->GetLower().GetVar() == nullptr) + ? std::to_string(bIt->second->GetLower().GetConstant()) + : "mx" + std::to_string(bIt->second->GetLower().GetVar()->GetExprID()) + " " + + std::to_string(bIt->second->GetLower().GetConstant()); + std::string upper = (bIt->second->GetUpper().GetVar() == nullptr) + ? std::to_string(bIt->second->GetUpper().GetConstant()) + : "mx" + std::to_string(bIt->second->GetUpper().GetVar()->GetExprID()) + " " + + std::to_string(bIt->second->GetUpper().GetConstant()); LogInfo::MapleLogger() << "mx" << bIt->first << " lower: " << lower << " upper: " << upper; if (bIt->second->GetRangeType() == kLowerAndUpper) { LogInfo::MapleLogger() << " kLowerAndUpper\n"; @@ -4925,22 +5014,23 @@ void ValueRangePropagation::DumpCaches() { LogInfo::MapleLogger() << " kSpecialUpperForLoop\n"; } } else if (bIt->second->GetRangeType() == kOnlyHasLowerBound) { - std::string lower = (bIt->second->GetBound().GetVar() == nullptr) ? - std::to_string(bIt->second->GetBound().GetConstant()) : - "mx" + std::to_string(bIt->second->GetBound().GetVar()->GetExprID()) + " " + - std::to_string(bIt->second->GetBound().GetConstant()); - LogInfo::MapleLogger() << "mx" << bIt->first << " lower: " << lower << " upper: max " << "kOnlyHasLowerBound\n"; + std::string lower = (bIt->second->GetBound().GetVar() == nullptr) + ? std::to_string(bIt->second->GetBound().GetConstant()) + : "mx" + std::to_string(bIt->second->GetBound().GetVar()->GetExprID()) + " " + + std::to_string(bIt->second->GetBound().GetConstant()); + LogInfo::MapleLogger() << "mx" << bIt->first << " lower: " << lower << " upper: max " + << "kOnlyHasLowerBound\n"; } else if (bIt->second->GetRangeType() == kOnlyHasUpperBound) { - std::string upper = (bIt->second->GetBound().GetVar() == nullptr) ? - std::to_string(bIt->second->GetBound().GetConstant()) : - "mx" + std::to_string(bIt->second->GetBound().GetVar()->GetExprID()) + " " + - std::to_string(bIt->second->GetBound().GetConstant()); + std::string upper = (bIt->second->GetBound().GetVar() == nullptr) + ? std::to_string(bIt->second->GetBound().GetConstant()) + : "mx" + std::to_string(bIt->second->GetBound().GetVar()->GetExprID()) + " " + + std::to_string(bIt->second->GetBound().GetConstant()); LogInfo::MapleLogger() << "mx" << bIt->first << " lower: min upper: " << upper << "kOnlyHasUpperBound\n"; } else if (bIt->second->GetRangeType() == kEqual || bIt->second->GetRangeType() == kNotEqual) { - std::string lower = (bIt->second->GetBound().GetVar() == nullptr) ? - std::to_string(bIt->second->GetBound().GetConstant()) : - "mx" + std::to_string(bIt->second->GetBound().GetVar()->GetExprID()) + " " + - std::to_string(bIt->second->GetBound().GetConstant()); + std::string lower = (bIt->second->GetBound().GetVar() == nullptr) + ? std::to_string(bIt->second->GetBound().GetConstant()) + : "mx" + std::to_string(bIt->second->GetBound().GetVar()->GetExprID()) + " " + + std::to_string(bIt->second->GetBound().GetConstant()); LogInfo::MapleLogger() << "mx" << bIt->first << " lower and upper: " << lower; if (bIt->second->GetRangeType() == kEqual) { LogInfo::MapleLogger() << " kEqual\n"; @@ -4950,7 +5040,8 @@ void ValueRangePropagation::DumpCaches() { } } } - LogInfo::MapleLogger() << "================Dump value range===================" << "\n"; + LogInfo::MapleLogger() << "================Dump value range===================" + << "\n"; } void MEValueRangePropagation::GetAnalysisDependence(maple::AnalysisDep &aDep) const { @@ -4980,7 +5071,7 @@ bool MEValueRangePropagation::PhaseRun(maple::MeFunction &f) { sa.SetComputeTripCountForLoopUnroll(false); ValueRangePropagation valueRangePropagation(f, *irMap, *dom, meLoop, *valueRangeMemPool, cands, sa, true); - SafetyCheck safetyCheck; // dummy + SafetyCheck safetyCheck; // dummy valueRangePropagation.SetSafetyBoundaryCheck(safetyCheck); valueRangePropagation.SetSafetyNonnullCheck(safetyCheck); @@ -5000,29 +5091,39 @@ bool MEValueRangePropagation::PhaseRun(maple::MeFunction &f) { MPLTimer timer; timer.Start(); if (ValueRangePropagation::isDebug) { - LogInfo::MapleLogger() << "***************ssaupdate value range prop***************" << "\n"; - LogInfo::MapleLogger() << "========size of ost " << cands.size() << " " << - f.GetMeSSATab()->GetOriginalStTableSize() << "========\n"; + LogInfo::MapleLogger() << "***************ssaupdate value range prop***************" + << "\n"; + LogInfo::MapleLogger() << "========size of ost " << cands.size() << " " + << f.GetMeSSATab()->GetOriginalStTableSize() << "========\n"; } ssaUpdate.Run(); timer.Stop(); if (ValueRangePropagation::isDebug) { LogInfo::MapleLogger() << "ssaupdate consumes cumulatively " << timer.Elapsed() << "seconds " << '\n'; - LogInfo::MapleLogger() << "***************ssaupdate value range prop***************" << "\n"; + LogInfo::MapleLogger() << "***************ssaupdate value range prop***************" + << "\n"; } } GetAnalysisInfoHook()->ForceEraseAnalysisPhase(f.GetUniqueID(), &MELoopAnalysis::id); GetAnalysisInfoHook()->ForceRunTransFormPhase(&MELoopCanon::id, f); + // update cfg frequency + if (f.GetCfg()->UpdateCFGFreq()) { + f.GetCfg()->UpdateEdgeFreqWithBBFreq(); + if (f.GetCfg()->DumpIRProfileFile()) { + f.GetCfg()->DumpToFile("after-valuerange" + std::to_string(f.vrpRuns), false, true); + } + } } // Run vrp twice when need check boundary and nullable pointer. if (MeOption::boundaryCheckMode != kNoCheck || MeOption::npeCheckMode != kNoCheck) { auto *hook = GetAnalysisInfoHook(); - dom = static_cast( - hook->ForceRunAnalysisPhase>(&MEDominance::id, f))->GetResult(); + dom = static_cast(hook->ForceRunAnalysisPhase>(&MEDominance::id, f)) + ->GetResult(); meLoop = static_cast( - hook->ForceRunAnalysisPhase>(&MELoopAnalysis::id, f))->GetResult(); - ValueRangePropagation valueRangePropagationWithOPTAssert( - f, *irMap, *dom, meLoop, *valueRangeMemPool, cands, sa, true, true); + hook->ForceRunAnalysisPhase>(&MELoopAnalysis::id, f)) + ->GetResult(); + ValueRangePropagation valueRangePropagationWithOPTAssert(f, *irMap, *dom, meLoop, *valueRangeMemPool, cands, sa, + true, true); SafetyCheckWithBoundaryError safetyCheckBoundaryError(f, valueRangePropagationWithOPTAssert); SafetyCheckWithNonnullError safetyCheckNonnullError(f); if (MeOption::boundaryCheckMode == kNoCheck) { @@ -5038,7 +5139,8 @@ bool MEValueRangePropagation::PhaseRun(maple::MeFunction &f) { valueRangePropagationWithOPTAssert.Execute(); CHECK_FATAL(!valueRangePropagationWithOPTAssert.IsCFGChange(), "must not change the cfg!"); if (ValueRangePropagation::isDebug) { - LogInfo::MapleLogger() << "***************after check***************" << "\n"; + LogInfo::MapleLogger() << "***************after check***************" + << "\n"; f.Dump(false); f.GetCfg()->DumpToFile("valuerange-after-safe" + std::to_string(f.vrpRuns)); } diff --git a/src/mapleall/maple_me/src/optimizeCFG.cpp b/src/mapleall/maple_me/src/optimizeCFG.cpp index 0c89b82851..abbb818c29 100644 --- a/src/mapleall/maple_me/src/optimizeCFG.cpp +++ b/src/mapleall/maple_me/src/optimizeCFG.cpp @@ -13,8 +13,9 @@ * See the Mulan PSL v2 for more details. */ #include "optimizeCFG.h" -#include "me_phase_manager.h" + #include "factory.h" +#include "me_phase_manager.h" namespace maple { namespace { @@ -23,27 +24,27 @@ const char *funcName = nullptr; std::string phaseName; #define LOG_BBID(BB) ((BB)->GetBBId().GetIdx()) -#define DEBUG_LOG() if (debug) \ -LogInfo::MapleLogger() << "[" << phaseName << "] " +#define DEBUG_LOG() \ + if (debug) LogInfo::MapleLogger() << "[" << phaseName << "] " // return {trueBB, falseBB} -std::pair GetTrueFalseBrPair(BB *bb) { +std::pair GetTrueFalseBrPair(BB *bb) { if (bb == nullptr) { - return { nullptr, nullptr }; + return {nullptr, nullptr}; } if (bb->GetKind() == kBBCondGoto) { auto *condBr = static_cast(bb->GetLastMe()); CHECK_FATAL(condBr, "condBr is nullptr!"); if (condBr->GetOp() == OP_brtrue) { - return { bb->GetSucc(1), bb->GetSucc(0) }; + return {bb->GetSucc(1), bb->GetSucc(0)}; } else { ASSERT(condBr->GetOp() == OP_brfalse, "only support brtrue/brfalse"); - return { bb->GetSucc(0), bb->GetSucc(1) }; + return {bb->GetSucc(0), bb->GetSucc(1)}; } } else if (bb->GetKind() == kBBGoto) { - return { bb->GetSucc(0), nullptr }; + return {bb->GetSucc(0), nullptr}; } - return { nullptr, nullptr }; + return {nullptr, nullptr}; } // Only one fallthru is allowed for a bb at most , but a bb may have be more than one fallthru pred @@ -82,7 +83,7 @@ void CollectUnsafeExpr(MeExpr *expr, std::set &exprSet) { if (expr->GetMeOp() == kMeOpConst || expr->GetMeOp() == kMeOpVar) { return; } - if (expr->GetMeOp() == kMeOpIvar) { // do not use HasIvar here for efficiency reasons + if (expr->GetMeOp() == kMeOpIvar) { // do not use HasIvar here for efficiency reasons exprSet.insert(expr); } if (expr->GetOp() == OP_div || expr->GetOp() == OP_rem) { @@ -100,7 +101,7 @@ void CollectUnsafeExpr(MeExpr *expr, std::set &exprSet) { // expr not throw exception bool IsSafeExpr(const MeExpr *expr) { - if (expr->GetMeOp() == kMeOpIvar) { // do not use HasIvar here for efficiency reasons + if (expr->GetMeOp() == kMeOpIvar) { // do not use HasIvar here for efficiency reasons return false; } if (expr->GetOp() == OP_div || expr->GetOp() == OP_rem) { @@ -123,8 +124,7 @@ bool IsSafeExpr(const MeExpr *expr) { bool IsSimpleImm(uint64 imm) { return ((imm & (static_cast(0xffff) << 48u)) == imm) || ((imm & (static_cast(0xffff) << 32u)) == imm) || - ((imm & (static_cast(0xffff) << 16u)) == imm) || - ((imm & (static_cast(0xffff))) == imm) || + ((imm & (static_cast(0xffff) << 16u)) == imm) || ((imm & (static_cast(0xffff))) == imm) || (((~imm) & (static_cast(0xffff) << 48u)) == ~imm) || (((~imm) & (static_cast(0xffff) << 32u)) == ~imm) || (((~imm) & (static_cast(0xffff) << 16u)) == ~imm) || @@ -135,12 +135,12 @@ bool IsSimpleImm(uint64 imm) { // if non-simple imm exist, return it, otherwise return 0 int64 GetNonSimpleImm(MeExpr *expr) { if (expr->GetMeOp() == kMeOpConst && IsPrimitiveInteger(expr->GetPrimType())) { - int64 imm = static_cast(static_cast(expr)->GetConstVal())->GetExtValue(); + int64 imm = static_cast(static_cast(expr)->GetConstVal())->GetExtValue(); if (!IsSimpleImm(static_cast(imm))) { return imm; } } - return 0; // 0 is a simple imm + return 0; // 0 is a simple imm } // Check if ftBB has only one regassign stmt, if regassign exists, return it, otherwise return nullptr @@ -150,7 +150,7 @@ AssignMeStmt *GetSingleAssign(BB *bb) { while (stmt != nullptr && stmt->GetOp() == OP_comment) { stmt = stmt->GetNextMeStmt(); } - if (stmt == nullptr) { // empty bb or has only comment stmt + if (stmt == nullptr) { // empty bb or has only comment stmt return nullptr; } if (stmt->GetOp() == OP_regassign || stmt->GetOp() == OP_dassign) { @@ -193,7 +193,7 @@ bool IsAllOpndsNotDefByCurrBB(const MeExpr &expr, const BB &currBB, std::setGetPred().empty() && bb->GetSucc().empty() && phiNode.GetOpnds().size() == 1) { @@ -207,7 +207,7 @@ bool IsAllOpndsNotDefByCurrBB(const MeExpr &expr, const BB &currBB, std::setGetBB() != &currBB; } case kMeOpIvar: { - auto &ivar = static_cast(expr); + auto &ivar = static_cast(expr); if (!IsAllOpndsNotDefByCurrBB(*ivar.GetBase(), currBB, infLoopCheck)) { return false; } @@ -249,8 +249,8 @@ bool IsAllOpndsNotDefByCurrBB(const MeStmt &stmt) { MeExpr *GetInvertCond(MeIRMap *irmap, MeExpr *cond) { if (IsCompareHasReverseOp(cond->GetOp())) { - return irmap->CreateMeExprBinary(GetReverseCmpOp(cond->GetOp()), cond->GetPrimType(), - *cond->GetOpnd(0), *cond->GetOpnd(1)); + return irmap->CreateMeExprBinary(GetReverseCmpOp(cond->GetOp()), cond->GetPrimType(), *cond->GetOpnd(0), + *cond->GetOpnd(1)); } return irmap->CreateMeExprUnary(OP_lnot, cond->GetPrimType(), *cond); } @@ -258,8 +258,7 @@ MeExpr *GetInvertCond(MeIRMap *irmap, MeExpr *cond) { // Is subSet a subset of superSet? template inline bool IsSubset(const std::set &subSet, const std::set &superSet) { - return std::includes(superSet.begin(), superSet.end(), - subSet.begin(), subSet.end()); + return std::includes(superSet.begin(), superSet.end(), subSet.begin(), subSet.end()); } // before : predCond ---> succCond @@ -269,7 +268,7 @@ bool IsSafeToMergeCond(MeExpr *predCond, MeExpr *succCond) { // Make sure succCond is not dependent on predCond // e.g. if (ptr != nullptr) if (*ptr), the second condition depends on the first one if (predCond == succCond) { - return true; // same expr + return true; // same expr } if (!IsSafeExpr(succCond)) { std::set predSet; @@ -316,9 +315,9 @@ std::unique_ptr GetVRForSimpleCmpExpr(const MeExpr &expr) { if (!IsPrimitiveInteger(opndType)) { return nullptr; } - Bound opnd1Bound(nullptr, 0, opndType); // bound of expr's opnd1 + Bound opnd1Bound(nullptr, 0, opndType); // bound of expr's opnd1 if (expr.GetOpnd(1)->GetMeOp() == kMeOpConst) { - MIRConst *constVal = static_cast(expr.GetOpnd(1))->GetConstVal(); + MIRConst *constVal = static_cast(expr.GetOpnd(1))->GetConstVal(); if (constVal->GetKind() != kConstInt) { return nullptr; } @@ -380,7 +379,7 @@ BB *GetCommonDest(BB *predBB, BB *succBB) { } if (psucc0 != succBB && psucc1 != succBB) { - return nullptr; // predBB has no branch to succBB + return nullptr; // predBB has no branch to succBB } BB *commonBB = (psucc0 == succBB) ? psucc1 : psucc0; if (commonBB == nullptr) { @@ -517,7 +516,7 @@ bool UnreachBBAnalysis(const maple::MeFunction &f) { } return false; } -} // anonymous namespace +} // anonymous namespace // contains only one valid goto stmt bool HasOnlyMeGotoStmt(BB &bb) { @@ -600,8 +599,8 @@ bool IsMplEmptyBB(BB &bb) { // connectingBB has only one pred and succ, and has no stmt (except a single gotoStmt) in it bool IsConnectingBB(BB &bb) { return (bb.GetPred().size() == 1 && bb.GetSucc().size() == 1) && - (IsMeEmptyBB(bb) || HasOnlyMeGotoStmt(bb)) && // for meir, if no meir exist, it is empty - (IsMplEmptyBB(bb) || HasOnlyMplGotoStmt(bb)); // for mplir, if no mplir exist, it is empty + (IsMeEmptyBB(bb) || HasOnlyMeGotoStmt(bb)) && // for meir, if no meir exist, it is empty + (IsMplEmptyBB(bb) || HasOnlyMplGotoStmt(bb)); // for mplir, if no mplir exist, it is empty } // RealSucc is a non-connecting BB which is not empty (or has just a single gotoStmt). @@ -664,8 +663,8 @@ void EliminateEmptyConnectingBB(const BB *predBB, BB *emptyBB, const BB *stopBB, while (emptyBB != nullptr && emptyBB != stopBB && IsConnectingBB(*emptyBB)) { BB *succ = emptyBB->GetSucc(0); BB *pred = emptyBB->GetPred(0); - DEBUG_LOG() << "Delete empty connecting : BB" << LOG_BBID(pred) << "->BB" << LOG_BBID(emptyBB) - << "(deleted)->BB" << LOG_BBID(succ) << "\n"; + DEBUG_LOG() << "Delete empty connecting : BB" << LOG_BBID(pred) << "->BB" << LOG_BBID(emptyBB) << "(deleted)->BB" + << LOG_BBID(succ) << "\n"; if (pred->IsPredBB(*succ)) { pred->RemoveSucc(*emptyBB, true); emptyBB->RemoveSucc(*succ, true); @@ -688,27 +687,33 @@ bool HasFallthruPred(const BB &bb) { class OptimizeBB { public: OptimizeBB(BB *bb, MeFunction &func, std::map>> *candidates) - : currBB(bb), f(func), cfg(func.GetCfg()), irmap(func.GetIRMap()), - irBuilder(func.GetMIRModule().GetMIRBuilder()), isMeIR(irmap != nullptr), cands(candidates) {} + : currBB(bb), + f(func), + cfg(func.GetCfg()), + irmap(func.GetIRMap()), + irBuilder(func.GetMIRModule().GetMIRBuilder()), + isMeIR(irmap != nullptr), + cands(candidates) {} // optimize each currBB until no change occur bool OptBBIteratively(); // initial factory to create corresponding optimizer for currBB according to BBKind. void InitBBOptFactory(); private: - BB *currBB = nullptr; // BB we currently perform optimization on - MeFunction &f; // function we currently perform optimization on - MeCFG *cfg = nullptr; // requiring cfg to find pattern to optimize current BB - MeIRMap *irmap = nullptr; // used to create new MeExpr/MeStmt - MIRBuilder *irBuilder = nullptr; // used to create new BaseNode(expr)/StmtNode + BB *currBB = nullptr; // BB we currently perform optimization on + MeFunction &f; // function we currently perform optimization on + MeCFG *cfg = nullptr; // requiring cfg to find pattern to optimize current BB + MeIRMap *irmap = nullptr; // used to create new MeExpr/MeStmt + MIRBuilder *irBuilder = nullptr; // used to create new BaseNode(expr)/StmtNode bool isMeIR = false; - std::map>> *cands = nullptr; // candidates ost need to be updated ssa - std::map> candsOstInBB; // bb with ost needed to be updated - - bool repeatOpt = false; // It will be always set false by OptBBIteratively. If there is some optimization - // opportunity for currBB after a/some optimization, we should set it true. - // Otherwise it will stop after all optimizations finished and continue to nextBB. - enum BBErrStat { + std::map>> *cands = nullptr; // candidates ost need to be updated ssa + std::map> candsOstInBB; // bb with ost needed to be updated + + bool repeatOpt = false; // It will be always set false by OptBBIteratively. If there is some optimization + // opportunity for currBB after a/some optimization, we should set it true. + // Otherwise it will stop after all optimizations finished and continue to nextBB. + enum BBErrStat + { kBBNoErr, // BB is normal kBBErrNull, // BB is nullptr kBBErrOOB, // BB id is out-of-bound @@ -792,23 +797,23 @@ class OptimizeBB { repeatOpt = false; } #define CHECK_CURR_BB() \ -if (!CheckCurrBB()) { \ - return false; \ -} + if (!CheckCurrBB()) { \ + return false; \ + } #define ONLY_FOR_MEIR() \ -if (!isMeIR) { \ - return false; \ -} + if (!isMeIR) { \ + return false; \ + } }; -using OptBBFatory = FunctionFactory; +using OptBBFatory = FunctionFactory; bool OptimizeBB::CheckCurrBB() { - if (bbErrStat != kBBNoErr) { // has been checked before + if (bbErrStat != kBBNoErr) { // has been checked before return false; } - if (currBB == nullptr) { + if (currBB == nullptr) { bbErrStat = kBBErrNull; return false; } @@ -832,9 +837,9 @@ bool OptimizeBB::CheckCurrBB() { void OptimizeBB::UpdateBBIdInSSACand(const BBId &oldBBID, const BBId &newBBID) { auto it = candsOstInBB.find(oldBBID); if (it == candsOstInBB.end()) { - return; // no item to update + return; // no item to update } - auto &ostSet = candsOstInBB[newBBID]; // find or create + auto &ostSet = candsOstInBB[newBBID]; // find or create ostSet.insert(it->second.begin(), it->second.end()); candsOstInBB.erase(it); for (auto &cand : *cands) { @@ -854,7 +859,7 @@ void OptimizeBB::UpdateSSACandForBBPhiList(BB *bb, const BB *newBB) { if (!isMeIR || bb == nullptr || bb->GetMePhiList().empty()) { return; } - if (newBB == nullptr) { // if not specified, newBB is bb itself + if (newBB == nullptr) { // if not specified, newBB is bb itself newBB = bb; } std::set &ostSet = candsOstInBB[newBB->GetBBId()]; @@ -942,18 +947,18 @@ bool OptimizeBB::BranchBB2UncondBB(BB &bb) { } } - DEBUG_LOG() << "BranchBB2UncondBB : " << (bb.GetKind() == kBBCondGoto ? "Conditional " : "Switch ") - << "BB" << LOG_BBID(&bb) << " to unconditional BB\n"; + DEBUG_LOG() << "BranchBB2UncondBB : " << (bb.GetKind() == kBBCondGoto ? "Conditional " : "Switch ") << "BB" + << LOG_BBID(&bb) << " to unconditional BB\n"; // delete all empty bb between bb and destBB // note : bb and destBB will be connected after empty BB is deleted for (int i = static_cast(bb.GetSucc().size()) - 1; i >= 0; --i) { EliminateEmptyConnectingBB(&bb, bb.GetSucc(static_cast(i)), destBB, *cfg); } - while (bb.GetSucc().size() != 1) { // bb is an unconditional bb now, and its successor num should be 1 + while (bb.GetSucc().size() != 1) { // bb is an unconditional bb now, and its successor num should be 1 ASSERT(bb.GetSucc().back() == destBB, "[FUNC: %s]Goto BB%d has different destination", funcName, LOG_BBID(&bb)); bb.RemoveSucc(*bb.GetSucc().back()); } - if (Options::profileUse && !bb.GetSuccFreq().empty()) { + if (cfg->UpdateCFGFreq()) { ASSERT(bb.GetSuccFreq().size() == bb.GetSucc().size(), "sanity check"); bb.SetSuccFreq(0, bb.GetFrequency()); } @@ -1011,30 +1016,32 @@ bool OptimizeBB::OptimizeCondBB2UnCond() { CHECK_FATAL(brStmt, "brStmt is nullptr!"); bool isCondTrue = (!condExpr->IsZero()); bool isBrtrue = (brStmt->GetOp() == OP_brtrue); - if (isCondTrue != isBrtrue) { // goto fallthru BB + if (isCondTrue != isBrtrue) { // goto fallthru BB currBB->RemoveLastMeStmt(); currBB->SetKind(kBBFallthru); - if (Options::profileUse && !currBB->GetSuccFreq().empty()) { + if (cfg->UpdateCFGFreq()) { removedSuccFreq = currBB->GetSuccFreq()[1]; } currBB->RemoveSucc(*gtBB, true); // update frequency - if (Options::profileUse && !currBB->GetSuccFreq().empty()) { + if (cfg->UpdateCFGFreq()) { currBB->SetSuccFreq(0, currBB->GetFrequency()); ftBB->SetFrequency(ftBB->GetFrequency() + removedSuccFreq); + ftBB->UpdateEdgeFreqs(false); } } else { MeStmt *gotoStmt = irmap->CreateGotoMeStmt(f.GetOrCreateBBLabel(*gtBB), currBB, &brStmt->GetSrcPosition()); currBB->ReplaceMeStmt(brStmt, gotoStmt); currBB->SetKind(kBBGoto); // update frequency - if (Options::profileUse && !currBB->GetSuccFreq().empty()) { + if (cfg->UpdateCFGFreq()) { removedSuccFreq = currBB->GetSuccFreq()[0]; } currBB->RemoveSucc(*ftBB, true); - if (Options::profileUse && !currBB->GetSuccFreq().empty()) { + if (cfg->UpdateCFGFreq()) { currBB->SetSuccFreq(0, currBB->GetFrequency()); gtBB->SetFrequency(gtBB->GetFrequency() + removedSuccFreq); + gtBB->UpdateEdgeFreqs(false); } } SetBBRunAgain(); @@ -1050,25 +1057,27 @@ bool OptimizeBB::OptimizeCondBB2UnCond() { if (isCondTrue != isBrTrue) { currBB->RemoveLastStmt(); currBB->SetKind(kBBFallthru); - if (Options::profileUse && !currBB->GetSuccFreq().empty()) { + if (cfg->UpdateCFGFreq()) { removedSuccFreq = currBB->GetSuccFreq()[1]; } currBB->RemoveSucc(*gtBB); - if (Options::profileUse && !currBB->GetSuccFreq().empty()) { + if (cfg->UpdateCFGFreq()) { currBB->SetSuccFreq(0, currBB->GetFrequency()); ftBB->SetFrequency(ftBB->GetFrequency() + removedSuccFreq); + ftBB->UpdateEdgeFreqs(false); } } else { StmtNode *gotoStmt = irBuilder->CreateStmtGoto(OP_goto, f.GetOrCreateBBLabel(*gtBB)); currBB->ReplaceStmt(&brStmt, gotoStmt); currBB->SetKind(kBBGoto); - if (Options::profileUse && !currBB->GetSuccFreq().empty()) { + if (cfg->UpdateCFGFreq()) { removedSuccFreq = currBB->GetSuccFreq()[0]; } currBB->RemoveSucc(*ftBB); - if (Options::profileUse && !currBB->GetSuccFreq().empty()) { + if (cfg->UpdateCFGFreq()) { currBB->SetSuccFreq(0, currBB->GetFrequency()); gtBB->SetFrequency(gtBB->GetFrequency() + removedSuccFreq); + gtBB->UpdateEdgeFreqs(false); } } SetBBRunAgain(); @@ -1151,11 +1160,15 @@ bool OptimizeBB::RemoveSuccFromNoReturnBB() { if (phiNode->GetOpnds().size() < 1) { break; } - phiNode->GetOpnds().push_back(phiNode->GetOpnd(0)); // to maintain opnd num and predNum + phiNode->GetOpnds().push_back(phiNode->GetOpnd(0)); // to maintain opnd num and predNum } } (void)EliminateRedundantPhiList(retBB); ResetBBRunAgain(); + // add edge Frequency to exitbb + if (cfg->UpdateCFGFreq()) { + currBB->PushBackSuccFreq(0); + } } return true; } @@ -1207,15 +1220,14 @@ BB *OptimizeBB::MergeSuccIntoPred(BB *pred, BB *succ) { } } // update succFreqs before update succs - if (Options::profileUse && f.GetMirFunc()->GetFuncProfData() && - !succ->GetSuccFreq().empty()) { + if (cfg->UpdateCFGFreq() && !succ->GetSuccFreq().empty()) { // copy succFreqs of succ to pred for (int i = 0; i < succ->GetSuccFreq().size(); i++) { pred->PushBackSuccFreq(succ->GetSuccFreq()[i]); } } succ->MoveAllSuccToPred(pred, cfg->GetCommonExitBB()); - pred->RemoveSucc(*succ, false); // philist will not be associated with pred BB, no need to update phi here. + pred->RemoveSucc(*succ, false); // philist will not be associated with pred BB, no need to update phi here. if (!isSuccEmpty) { // only when we move stmt from succ to pred should we set attr and kind here pred->SetAttributes(succ->GetAttributes()); @@ -1239,11 +1251,11 @@ BB *OptimizeBB::MergeSuccIntoPred(BB *pred, BB *succ) { // update bbid : tell ssa-updater to update with new BBID UpdateBBIdInSSACand(succ->GetBBId(), pred->GetBBId()); } - DEBUG_LOG() << "Merge BB" << LOG_BBID(succ) << " to BB" << LOG_BBID(pred) - << ", and delete BB" << LOG_BBID(succ) << "\n"; + DEBUG_LOG() << "Merge BB" << LOG_BBID(succ) << " to BB" << LOG_BBID(pred) << ", and delete BB" << LOG_BBID(succ) + << "\n"; UpdateSSACandForBBPhiList(succ, pred); DeleteBB(succ); - succ->SetBBId(pred->GetBBId()); // succ has been merged to pred, and reference to succ should be set to pred too. + succ->SetBBId(pred->GetBBId()); // succ has been merged to pred, and reference to succ should be set to pred too. return pred; } @@ -1286,13 +1298,13 @@ bool OptimizeBB::IsProfitableForCond2Sel(MeExpr *condExpr, MeExpr *trueExpr, MeE if (trueExpr == falseExpr) { return true; } - ASSERT(IsSafeExpr(trueExpr), "[FUNC: %s]Please check for safety first", funcName) ; - ASSERT(IsSafeExpr(falseExpr), "[FUNC: %s]Please check for safety first", funcName) ; + ASSERT(IsSafeExpr(trueExpr), "[FUNC: %s]Please check for safety first", funcName); + ASSERT(IsSafeExpr(falseExpr), "[FUNC: %s]Please check for safety first", funcName); // try to simplify select expr MeExpr *selExpr = irmap->CreateMeExprSelect(trueExpr->GetPrimType(), *condExpr, *trueExpr, *falseExpr); MeExpr *simplifiedSel = irmap->SimplifyMeExpr(selExpr); if (simplifiedSel != selExpr) { - return true; // can be simplified + return true; // can be simplified } // We can check for every opnd of opndExpr, and calculate their cost according to cg's insn @@ -1317,30 +1329,30 @@ bool OptimizeBB::IsProfitableForCond2Sel(MeExpr *condExpr, MeExpr *trueExpr, MeE return true; } - // Ignoring connecting BB, two cases can be turn into select - // condBB condBB - // / \ / \ +// Ignoring connecting BB, two cases can be turn into select +// condBB condBB +// / \ / \ // ftBB gtBB | gtBB/ftBB - // x<- x<- | x<- - // \ / \ / - // jointBB jointBB +// x<- x<- | x<- +// \ / \ / +// jointBB jointBB bool OptimizeBB::CondBranchToSelect() { CHECK_CURR_BB(); - BB *ftBB = FindFirstRealSucc(currBB->GetSucc(0)); // fallthruBB - BB *gtBB = FindFirstRealSucc(currBB->GetSucc(1)); // gotoBB + BB *ftBB = FindFirstRealSucc(currBB->GetSucc(0)); // fallthruBB + BB *gtBB = FindFirstRealSucc(currBB->GetSucc(1)); // gotoBB if (ftBB == gtBB) { (void)BranchBB2UncondBB(*currBB); return true; } // if ftBB or gtBB itself is jointBB, just return itself; otherwise return real succ - BB *ftTargetBB = (ftBB->GetPred().size() == 1 && ftBB->GetSucc().size() == 1) ? FindFirstRealSucc(ftBB->GetSucc(0)) - : ftBB; - BB *gtTargetBB = (gtBB->GetPred().size() == 1 && gtBB->GetSucc().size() == 1) ? FindFirstRealSucc(gtBB->GetSucc(0)) - : gtBB; + BB *ftTargetBB = + (ftBB->GetPred().size() == 1 && ftBB->GetSucc().size() == 1) ? FindFirstRealSucc(ftBB->GetSucc(0)) : ftBB; + BB *gtTargetBB = + (gtBB->GetPred().size() == 1 && gtBB->GetSucc().size() == 1) ? FindFirstRealSucc(gtBB->GetSucc(0)) : gtBB; if (ftTargetBB != gtTargetBB) { return false; } - BB *jointBB = ftTargetBB; // common succ + BB *jointBB = ftTargetBB; // common succ // Check if ftBB has only one assign stmt, set ftStmt if a assign stmt exist AssignMeStmt *ftStmt = nullptr; if (ftBB != jointBB) { @@ -1365,7 +1377,7 @@ bool OptimizeBB::CondBranchToSelect() { // Here we found a pattern, collect select opnds and result reg ScalarMeExpr *ftLHS = nullptr; MeExpr *ftRHS = nullptr; - std::set chiListCands; // collect chilist if assign stmt has one + std::set chiListCands; // collect chilist if assign stmt has one if (ftStmt != nullptr) { ftLHS = static_cast(ftStmt->GetLHS()); ftRHS = ftStmt->GetRHS(); @@ -1413,9 +1425,9 @@ bool OptimizeBB::CondBranchToSelect() { DEBUG_LOG() << "Abort cond2sel for BB" << LOG_BBID(currBB) << ", because two ost assigned are not the same\n"; return false; } - DEBUG_LOG() << "Candidate cond2sel BB" << LOG_BBID(currBB) << "(cond)->{BB" << LOG_BBID(currBB->GetSucc(0)) - << ", BB" << LOG_BBID(currBB->GetSucc(1)) << "}->BB" << LOG_BBID(ftTargetBB) << "(jointBB)\n"; - if (ftRHS != gtRHS) { // if ftRHS is the same as gtRHS, they can be simplified, and no need to check safety + DEBUG_LOG() << "Candidate cond2sel BB" << LOG_BBID(currBB) << "(cond)->{BB" << LOG_BBID(currBB->GetSucc(0)) << ", BB" + << LOG_BBID(currBB->GetSucc(1)) << "}->BB" << LOG_BBID(ftTargetBB) << "(jointBB)\n"; + if (ftRHS != gtRHS) { // if ftRHS is the same as gtRHS, they can be simplified, and no need to check safety // black list if (!IsSafeExpr(ftRHS) || !IsSafeExpr(gtRHS)) { DEBUG_LOG() << "Abort cond2sel for BB" << LOG_BBID(currBB) << ", because trueExpr or falseExpr is not safe\n"; @@ -1434,7 +1446,7 @@ bool OptimizeBB::CondBranchToSelect() { DEBUG_LOG() << "Condition To Select : BB" << LOG_BBID(currBB) << "(cond)->[BB" << LOG_BBID(ftBB) << "(ft), BB" << LOG_BBID(gtBB) << "(gt)]->BB" << LOG_BBID(jointBB) << "(joint)\n"; ScalarMeExpr *resLHS = nullptr; - if (jointBB->GetPred().size() == 2) { // if jointBB has only ftBB and gtBB as its pred. + if (jointBB->GetPred().size() == 2) { // if jointBB has only ftBB and gtBB as its pred. // use phinode lhs as result auto it = jointBB->GetMePhiList().find(ftLHS->GetOstIdx()); if (it == jointBB->GetMePhiList().end()) { @@ -1448,7 +1460,7 @@ bool OptimizeBB::CondBranchToSelect() { // It is profitable for instruction selection if select opnd is a compare expression // select condExpr, trueExpr, falseExpr => select cmpExpr, trueExpr, falseExpr if (condExpr->IsScalar() && condExpr->GetPrimType() != PTY_u1) { - auto *scalarExpr = static_cast(condExpr); + auto *scalarExpr = static_cast(condExpr); if (scalarExpr->GetDefBy() == kDefByStmt) { MeStmt *defStmt = scalarExpr->GetDefStmt(); MeExpr *rhs = defStmt->GetRHS(); @@ -1473,7 +1485,7 @@ bool OptimizeBB::CondBranchToSelect() { } (void)BranchBB2UncondBB(*currBB); // update phi - if (jointBB->GetPred().size() == 1) { // jointBB has only currBB as its pred + if (jointBB->GetPred().size() == 1) { // jointBB has only currBB as its pred // just remove phinode jointBB->GetMePhiList().erase(resLHS->GetOstIdx()); } else { @@ -1517,11 +1529,11 @@ bool IsExprSameLexicalally(MeExpr *expr1, MeExpr *expr2) { if (const1->GetKind() == kConstInt) { return static_cast(const1)->GetExtValue() == static_cast(const2)->GetExtValue(); } else if (const1->GetKind() == kConstFloatConst) { - return IsFloatingPointNumBitsSame(static_cast(const1)->GetValue(), - static_cast(const2)->GetValue()); + return IsFloatingPointNumBitsSame(static_cast(const1)->GetValue(), + static_cast(const2)->GetValue()); } else if (const1->GetKind() == kConstDoubleConst) { - return IsFloatingPointNumBitsSame(static_cast(const1)->GetValue(), - static_cast(const2)->GetValue()); + return IsFloatingPointNumBitsSame(static_cast(const1)->GetValue(), + static_cast(const2)->GetValue()); } return false; } @@ -1707,18 +1719,18 @@ bool OptimizeBB::SkipRedundantCond(BB &pred, BB &succ) { } MeExpr *predCond = predBr->GetOpnd(0); MeExpr *succCond = succBr->GetOpnd(0); - auto ptfSucc = GetTrueFalseBrPair(&pred); // pred true and false - auto stfSucc = GetTrueFalseBrPair(&succ); // succ true and false + auto ptfSucc = GetTrueFalseBrPair(&pred); // pred true and false + auto stfSucc = GetTrueFalseBrPair(&succ); // succ true and false // Try to infer result of succCond from predCond bool isPredTrueBrSucc = (FindFirstRealSucc(ptfSucc.first) == &succ); BranchResult tfBranch = InferSuccCondBrFromPredCond(predCond, succCond, isPredTrueBrSucc); - if (tfBranch == kBrUnknown) { // succCond cannot be inferred from predCond + if (tfBranch == kBrUnknown) { // succCond cannot be inferred from predCond return false; } // if succ's cond can be inferred from pred's cond, pred can skip succ and branches to newTarget directly BB *newTarget = (tfBranch == kBrTrue) ? FindFirstRealSucc(stfSucc.first) : FindFirstRealSucc(stfSucc.second); if (newTarget == nullptr || newTarget == &succ) { - return false; + return false; } DEBUG_LOG() << "Condition in BB" << LOG_BBID(&succ) << " is redundant, since it has been checked in BB" << LOG_BBID(&pred) << ", BB" << LOG_BBID(&pred) << " can branch to BB" << LOG_BBID(newTarget) << "\n"; @@ -1728,7 +1740,7 @@ bool OptimizeBB::SkipRedundantCond(BB &pred, BB &succ) { // succ ... // / \ // ftBB gtBB - if (succ.GetPred().size() == 1) { // succ has only one pred + if (succ.GetPred().size() == 1) { // succ has only one pred // if newTarget is succ's gotoBB, and it has fallthru pred, we should add a goto stmt to succ's last // to replace condGoto stmt. Otherwise, newTarget will have two fallthru pred if (newTarget == FindFirstRealSucc(succ.GetSucc(1)) && HasFallthruPred(*newTarget)) { @@ -1746,7 +1758,17 @@ bool OptimizeBB::SkipRedundantCond(BB &pred, BB &succ) { DEBUG_LOG() << "SkipRedundantCond : Remove condBr in BB" << LOG_BBID(&succ) << ", turn it to fallthruBB\n"; } BB *rmBB = (FindFirstRealSucc(succ.GetSucc(0)) == newTarget) ? succ.GetSucc(1) : succ.GetSucc(0); + int64_t deletedSuccFreq = 0; + if (cfg->UpdateCFGFreq()) { + int idx = succ.GetSuccIndex(*rmBB); + deletedSuccFreq = succ.GetSuccFreq()[idx]; + } succ.RemoveSucc(*rmBB, true); + if (cfg->UpdateCFGFreq()) { + succ.SetSuccFreq(0, succ.GetFrequency()); + auto *succofSucc = succ.GetSucc(0); + succofSucc->SetFrequency(succofSucc->GetFrequency() + deletedSuccFreq); + } DEBUG_LOG() << "Remove succ BB" << LOG_BBID(rmBB) << " of pred BB" << LOG_BBID(&succ) << "\n"; return true; } else { @@ -1784,18 +1806,19 @@ bool OptimizeBB::SkipRedundantCond(BB &pred, BB &succ) { BB *replacedSucc = isPredTrueBrSucc ? ptfSucc.first : ptfSucc.second; EliminateEmptyConnectingBB(&pred, replacedSucc, &succ, *cfg); ASSERT(pred.IsPredBB(succ), "[FUNC: %s]After eliminate connecting BB, pred must be predecessor of succ", funcName); - int predPredIdx = succ.GetPredIndex(pred); // before replace succ, record predidx for UpdatePhiForMovingPred - pred.ReplaceSucc(&succ, newBB, false); // do not update phi here, UpdatePhiForMovingPred will do it + int predPredIdx = succ.GetPredIndex(pred); // before replace succ, record predidx for UpdatePhiForMovingPred + pred.ReplaceSucc(&succ, newBB, false); // do not update phi here, UpdatePhiForMovingPred will do it DEBUG_LOG() << "Replace succ BB" << LOG_BBID(replacedSucc) << " with BB" << LOG_BBID(newBB) << ": BB" - << LOG_BBID(&pred) << "->...->BB" << LOG_BBID(&succ) << "(skipped)" << " => BB" << LOG_BBID(&pred) - << "->BB" << LOG_BBID(newBB) << "(new)->BB" << LOG_BBID(newTarget) << "\n"; + << LOG_BBID(&pred) << "->...->BB" << LOG_BBID(&succ) << "(skipped)" + << " => BB" << LOG_BBID(&pred) << "->BB" << LOG_BBID(newBB) << "(new)->BB" << LOG_BBID(newTarget) + << "\n"; if (pred.GetSucc(1) == newBB) { cfg->UpdateBranchTarget(pred, succ, *newBB, f); } newTarget->AddPred(*newBB); UpdatePhiForMovingPred(predPredIdx, newBB, &succ, newTarget); // update newBB frequency : copy predBB succFreq as newBB frequency - if (Options::profileUse && f.GetMirFunc()->GetFuncProfData()) { + if (cfg->UpdateCFGFreq()) { int idx = pred.GetSuccIndex(*newBB); ASSERT(idx >= 0 && idx < pred.GetSucc().size(), "sanity check"); uint64_t freq = pred.GetEdgeFreq(idx); @@ -1806,6 +1829,13 @@ bool OptimizeBB::SkipRedundantCond(BB &pred, BB &succ) { uint32_t freqOfSucc = succ.GetFrequency(); ASSERT(freqOfSucc >= freq, "sanity check"); succ.SetFrequency(freqOfSucc - freq); + // update edge frequency + BB *affectedBB = (tfBranch == kBrTrue) ? stfSucc.first : stfSucc.second; + idx = succ.GetSuccIndex(*affectedBB); + ASSERT(idx >= 0 && idx < succ.GetSucc().size(), "sanity check"); + int64_t oldedgeFreq = succ.GetSuccFreq()[idx]; + ASSERT(oldedgeFreq >= freq, "sanity check"); + succ.SetSuccFreq(idx, (oldedgeFreq - freq)); } return true; } @@ -1894,7 +1924,7 @@ void OptimizeBB::UpdatePhiForMovingPred(int predIdxForCurr, const BB *pred, BB * // create a new version for new phi phiMeNode->SetLHS(irmap->CreateRegOrVarMeExprVersion(ostIdx)); } - UpdateSSACandForBBPhiList(succ); // new philist has been created in succ + UpdateSSACandForBBPhiList(succ); // new philist has been created in succ } else { // succ has other pred besides curr for (auto &phi : succPhiList) { @@ -1924,7 +1954,7 @@ void OptimizeBB::UpdatePhiForMovingPred(int predIdxForCurr, const BB *pred, BB * } else { auto *phiMeNode = irmap->NewInPool(); phiMeNode->SetDefBB(succ); - resPair.first->second = phiMeNode; // replace nullptr inserted before + resPair.first->second = phiMeNode; // replace nullptr inserted before auto &phiOpnds = phiMeNode->GetOpnds(); // insert opnd into New phiNode : all phiOpnds (except for pred) are phiNode lhs in curr phiOpnds.insert(phiOpnds.end(), succ->GetPred().size(), phi.second->GetLHS()); @@ -1963,7 +1993,7 @@ bool OptimizeBB::MergeGotoBBToPred(BB *succ, BB *pred) { if (!HasOnlyMeGotoStmt(*succ)) { return false; } - BB *newTarget = succ->GetSucc(0); // succ must have only one succ, because it is uncondBB + BB *newTarget = succ->GetSucc(0); // succ must have only one succ, because it is uncondBB if (newTarget == succ) { // succ goto itself, no need to update goto target to newTarget return false; @@ -1975,8 +2005,8 @@ bool OptimizeBB::MergeGotoBBToPred(BB *succ, BB *pred) { // pred is moved to newTarget if (pred->GetKind() == kBBFallthru) { CHECK_FATAL(succ->GetLastMe(), "LastMe is nullptr!"); - GotoMeStmt *gotoMeStmt = irmap->CreateGotoMeStmt(newTarget->GetBBLabel(), pred, - &succ->GetLastMe()->GetSrcPosition()); + GotoMeStmt *gotoMeStmt = + irmap->CreateGotoMeStmt(newTarget->GetBBLabel(), pred, &succ->GetLastMe()->GetSrcPosition()); pred->AddMeStmtLast(gotoMeStmt); pred->SetKind(kBBGoto); DEBUG_LOG() << "Insert Uncond stmt to fallthru BB" << LOG_BBID(currBB) << ", and goto BB" << LOG_BBID(newTarget) @@ -1984,15 +2014,29 @@ bool OptimizeBB::MergeGotoBBToPred(BB *succ, BB *pred) { } int predIdx = succ->GetPredIndex(*pred); bool needUpdatePhi = false; + int64_t removedFreq = 0; + if (cfg->UpdateCFGFreq()) { + int idx = pred->GetSuccIndex(*succ); + removedFreq = pred->GetSuccFreq()[idx]; + } if (pred->IsPredBB(*newTarget)) { - pred->RemoveSucc(*succ, true); // one of pred's succ has been newTarget, avoid duplicate succ here + pred->RemoveSucc(*succ, true); // one of pred's succ has been newTarget, avoid duplicate succ here + if (cfg->UpdateCFGFreq()) { + int idx = pred->GetSuccIndex(*newTarget); + pred->SetSuccFreq(idx, pred->GetSuccFreq()[idx] + removedFreq); + } } else { - pred->ReplaceSucc(succ, newTarget); // phi opnd is not removed from currBB's philist, we will remove it later + pred->ReplaceSucc(succ, newTarget); // phi opnd is not removed from currBB's philist, we will remove it later needUpdatePhi = true; } - - DEBUG_LOG() << "Merge Uncond BB" << LOG_BBID(succ) << " to its pred BB" << LOG_BBID(pred) - << ": BB" << LOG_BBID(pred) << "->BB" << LOG_BBID(succ) << "(merged)->BB" << LOG_BBID(newTarget) << "\n"; + if (cfg->UpdateCFGFreq()) { + int64_t succFreq = succ->GetFrequency(); + ASSERT(succFreq >= removedFreq, "sanity check"); + succ->SetFrequency(succFreq - removedFreq); + succ->SetSuccFreq(0, succ->GetFrequency()); + } + DEBUG_LOG() << "Merge Uncond BB" << LOG_BBID(succ) << " to its pred BB" << LOG_BBID(pred) << ": BB" << LOG_BBID(pred) + << "->BB" << LOG_BBID(succ) << "(merged)->BB" << LOG_BBID(newTarget) << "\n"; cfg->UpdateBranchTarget(*pred, *succ, *newTarget, f); if (needUpdatePhi) { // remove phiOpnd in succ, and add phiOpnd to newTarget @@ -2034,7 +2078,7 @@ bool OptimizeBB::OptimizeUncondBB() { return false; } // wont exit BB and has an edge to commonExit, if we merge it to pred and delete it, the egde will be cut off - if (currBB->GetSucc().size() == 2) { // 2 succ : first is gotoTarget, second is edge to commonExit + if (currBB->GetSucc().size() == 2) { // 2 succ : first is gotoTarget, second is edge to commonExit ASSERT(currBB->GetAttributes(kBBAttrWontExit), "[FUNC: %s]GotoBB%d is not wontexitBB, but has two succ", funcName, LOG_BBID(currBB)); return false; @@ -2096,11 +2140,11 @@ bool OptimizeBB::OptimizeSwitchBB() { if (swStmt->GetOpnd()->GetMeOp() != kMeOpConst) { return false; } - auto *swConstExpr = static_cast(swStmt->GetOpnd()); + auto *swConstExpr = static_cast(swStmt->GetOpnd()); MIRConst *swConstVal = swConstExpr->GetConstVal(); ASSERT(swConstVal->GetKind() == kConstInt, "[FUNC: %s]switch is only legal for integer val", funcName); int64 val = static_cast(swConstVal)->GetExtValue(); - BB *survivor = currBB->GetSucc(0); // init as default BB + BB *survivor = currBB->GetSucc(0); // init as default BB for (size_t i = 0; i < swStmt->GetSwitchTable().size(); ++i) { int64 caseVal = swStmt->GetSwitchTable().at(i).first; if (caseVal == val) { @@ -2157,8 +2201,8 @@ MeExpr *OptimizeBB::CombineCondByOffset(const MeExpr &expr) { MeExpr *geConst = geExpr->GetOpnd(1); PrimType lePtyp = leConst->GetPrimType(); PrimType gePtyp = geConst->GetPrimType(); - if (leConst->GetOp() != OP_constval || geConst->GetOp() != OP_constval || - lePtyp != gePtyp || !IsPrimitiveInteger(lePtyp)) { // only allowed for integer, because float cannot wrap around + if (leConst->GetOp() != OP_constval || geConst->GetOp() != OP_constval || lePtyp != gePtyp || + !IsPrimitiveInteger(lePtyp)) { // only allowed for integer, because float cannot wrap around return nullptr; } int64 leVal = static_cast(static_cast(leConst)->GetConstVal())->GetExtValue(); @@ -2174,9 +2218,9 @@ MeExpr *OptimizeBB::CombineCondByOffset(const MeExpr &expr) { (IsPrimitiveUnsigned(lePtyp) && static_cast(leVal) > static_cast(newGeVal))) { // e.g. x < 3 || x > 2 <==> true return irmap->CreateIntConstMeExpr(1, PTY_u1); - } else if (leVal == newGeVal) { // e.g. x < 3 || x > 3 <==> x != 3 - return irmap->CreateMeExprCompare( - OP_ne, PTY_u1, opndPtyp, *sameExpr, *irmap->CreateIntConstMeExpr(newGeVal, lePtyp)); + } else if (leVal == newGeVal) { // e.g. x < 3 || x > 3 <==> x != 3 + return irmap->CreateMeExprCompare(OP_ne, PTY_u1, opndPtyp, *sameExpr, + *irmap->CreateIntConstMeExpr(newGeVal, lePtyp)); } // (x < val1 || x > val2) <==> ((unsigned)(x - val1) > (val2 - val1)) MeExpr *newLeConst = irmap->CreateIntConstMeExpr(leVal, opndPtyp); @@ -2255,15 +2299,15 @@ bool OptimizeBB::FoldBranchToCommonDest(BB *pred, BB *succ) { return false; } if (!IsProfitableToMergeCond(predCond, succCond)) { - DEBUG_LOG() << "Abort Merging Two CondBB : Condition in successor BB" - << LOG_BBID(succ) << " is not simple enough and not profitable\n"; + DEBUG_LOG() << "Abort Merging Two CondBB : Condition in successor BB" << LOG_BBID(succ) + << " is not simple enough and not profitable\n"; return false; } // Start trying to merge two condition together if possible - auto ptfBrPair = GetTrueFalseBrPair(pred); // pred's true and false branches - auto stfBrPair = GetTrueFalseBrPair(succ); // succ's true and false branches + auto ptfBrPair = GetTrueFalseBrPair(pred); // pred's true and false branches + auto stfBrPair = GetTrueFalseBrPair(succ); // succ's true and false branches Opcode combinedCondOp = OP_undef; - bool invertSuccCond = false; // invert second condition, e.g. (cond1 && !cond2) + bool invertSuccCond = false; // invert second condition, e.g. (cond1 && !cond2) // all cases are listed as follow: // | case | predBB -> common | succBB -> common | invertSuccCond | or/and | // | ---- | ---------------- | ---------------- | -------------- | ------ | @@ -2275,16 +2319,16 @@ bool OptimizeBB::FoldBranchToCommonDest(BB *pred, BB *succ) { // pred's false branch to succ, so true branch to common bool isPredTrueToCommon = (FindFirstRealSucc(ptfBrPair.second) == succ); bool isSuccTrueToCommon = (FindFirstRealSucc(stfBrPair.first) == commonBB); - if (isPredTrueToCommon && isSuccTrueToCommon) { // case 1 + if (isPredTrueToCommon && isSuccTrueToCommon) { // case 1 invertSuccCond = false; combinedCondOp = OP_lior; - } else if (!isPredTrueToCommon && !isSuccTrueToCommon) { // case 2 + } else if (!isPredTrueToCommon && !isSuccTrueToCommon) { // case 2 invertSuccCond = false; combinedCondOp = OP_land; - } else if (isPredTrueToCommon && !isSuccTrueToCommon) { // case 3 + } else if (isPredTrueToCommon && !isSuccTrueToCommon) { // case 3 invertSuccCond = true; combinedCondOp = OP_lior; - } else if (!isPredTrueToCommon && isSuccTrueToCommon) { // case 4 + } else if (!isPredTrueToCommon && isSuccTrueToCommon) { // case 4 invertSuccCond = true; combinedCondOp = OP_land; } else { @@ -2311,7 +2355,7 @@ bool OptimizeBB::FoldBranchToCommonDest(BB *pred, BB *succ) { // remove succ and update cfg BB *exitBB = isSuccTrueToCommon ? stfBrPair.second : stfBrPair.first; pred->ReplaceSucc(succ, exitBB); - exitBB->RemovePred(*succ, false); // not update phi here, because its phi opnd is the same as before. + exitBB->RemovePred(*succ, false); // not update phi here, because its phi opnd is the same as before. // we should eliminate edge from succ to commonBB BB *toEliminateBB = isSuccTrueToCommon ? stfBrPair.first : stfBrPair.second; EliminateEmptyConnectingBB(succ, toEliminateBB, commonBB /* stop here */, *cfg); @@ -2354,6 +2398,11 @@ bool OptimizeBB::FoldBranchToCommonDest() { bool OptimizeBB::OptBBOnce() { CHECK_CURR_BB(); DEBUG_LOG() << "Try to optimize BB" << LOG_BBID(currBB) << "...\n"; + // bb frequency may be updated, make bb frequency and succs frequency consistent + // skip deadBB + if (cfg->UpdateCFGFreq() && (!currBB->GetPred().empty()) && (currBB->GetUniquePred() != currBB)) { + currBB->UpdateEdgeFreqs(false); + } bool everChanged = false; // eliminate dead BB : // 1.BB has no pred(expect then entry block) @@ -2416,7 +2465,7 @@ class OptimizeFuntionCFG { private: MeFunction &f; - std::map>> *cands = nullptr; // candidates ost need to update ssa + std::map>> *cands = nullptr; // candidates ost need to update ssa bool OptimizeFuncCFGIteratively(); bool OptimizeCFGForBB(BB *currBB); }; @@ -2439,10 +2488,6 @@ bool OptimizeFuntionCFG::OptimizeFuncCFGIteratively() { if (currBB == nullptr) { continue; } - // bb frequency may be updated, make bb frequency and succs frequency consistent - if (Options::profileUse && !currBB->GetSuccFreq().empty()) { - currBB->UpdateEdgeFreqs(); - } changed |= OptimizeCFGForBB(currBB); } everChanged |= changed; @@ -2488,15 +2533,14 @@ bool OptimizeMeFuncCFG(maple::MeFunction &f, std::mapValidBBNum(); // optimization entry - bool change = OptimizeFuntionCFG(f, ssaCand) - .OptimizeOnFunc(); + bool change = OptimizeFuntionCFG(f, ssaCand).OptimizeOnFunc(); if (change) { f.GetCfg()->WontExitAnalysis(); if (debug) { uint32 bbNumAfter = f.GetCfg()->ValidBBNum(); if (bbNumBefore != bbNumAfter) { - DEBUG_LOG() << "BBs' number " << (bbNumBefore > bbNumAfter ? "reduce" : "increase") - << " from " << bbNumBefore << " to " << bbNumAfter << "\n"; + DEBUG_LOG() << "BBs' number " << (bbNumBefore > bbNumAfter ? "reduce" : "increase") << " from " << bbNumBefore + << " to " << bbNumAfter << "\n"; } else { DEBUG_LOG() << "BBs' number keep the same as before (num = " << bbNumAfter << ")\n"; } @@ -2517,6 +2561,9 @@ bool MEOptimizeCFGNoSSA::PhaseRun(MeFunction &f) { debug = DEBUGFUNC_NEWPM(f); phaseName = PhaseName(); bool change = OptimizeMeFuncCFG(f, nullptr); + if (change && f.GetCfg()->DumpIRProfileFile()) { + f.GetCfg()->DumpToFile("after-OptimizeCFGNOSSA", false, f.GetCfg()->UpdateCFGFreq()); + } return change; } @@ -2542,7 +2589,10 @@ bool MEOptimizeCFG::PhaseRun(maple::MeFunction &f) { MeSSAUpdate ssaUpdate(f, *f.GetMeSSATab(), *dom, cands); ssaUpdate.Run(); } + if (f.GetCfg()->DumpIRProfileFile()) { + f.GetCfg()->DumpToFile("after-OptimizeCFG", false, f.GetCfg()->UpdateCFGFreq()); + } } return change; } -} // namespace maple +} // namespace maple diff --git a/src/mapleall/maple_util/include/mpl_profdata.h b/src/mapleall/maple_util/include/mpl_profdata.h index 6aa8c1520f..6f9f1b3a1d 100644 --- a/src/mapleall/maple_util/include/mpl_profdata.h +++ b/src/mapleall/maple_util/include/mpl_profdata.h @@ -15,10 +15,11 @@ #ifndef MAPLE_UTIL_INCLUDE_MPL_PROFDATA_H #define MAPLE_UTIL_INCLUDE_MPL_PROFDATA_H -#include "mempool_allocator.h" #include #include +#include "mempool_allocator.h" + namespace maple { #define HOTCALLSITEFREQ 100 enum UpdateFreqOp { @@ -31,23 +32,27 @@ enum UpdateFreqOp { // used for record cumulative datas struct ProfileSummaryHistogram { + uint32_t countRatio; uint32_t startValue; // count value range in [startValue, nextHistogramStart) uint32_t countNums; // Number of counters whose profile count falls in countValue range. uint64_t countMinVal; // Smallest profile count included in this range. uint64_t countCumValue; // Cumulative value of the profile counts - ProfileSummaryHistogram(uint32_t s, uint32_t num, uint64_t mincount, uint64_t cumcounts) : - startValue(s), countNums(num), countMinVal(mincount), countCumValue(cumcounts) { - } + ProfileSummaryHistogram(uint32_t s, uint32_t num, uint64_t mincount, uint64_t cumcounts) + : countRatio(0), startValue(s), countNums(num), countMinVal(mincount), countCumValue(cumcounts) {} }; class ProfileSummary { -public: - ProfileSummary(MapleAllocator* alloc) : histogram(alloc->Adapter()) {} - ProfileSummary(MapleAllocator *alloc, uint64_t checksum, uint32_t runtimes, - uint32_t totalcount, uint64_t maxcount, uint64_t sumcount) : - checkSum(checksum), run(runtimes), totalCount(totalcount), maxCount(maxcount), sumCount(sumcount), - histogram(alloc->Adapter()) {} + public: + ProfileSummary(MapleAllocator *alloc) : histogram(alloc->Adapter()) {} + ProfileSummary(MapleAllocator *alloc, uint64_t checksum, uint32_t runtimes, uint32_t totalcount, uint64_t maxcount, + uint64_t sumcount) + : checkSum(checksum), + run(runtimes), + totalCount(totalcount), + maxCount(maxcount), + sumCount(sumcount), + histogram(alloc->Adapter()) {} void SetSummary(uint64_t checksum, uint32_t runtimes, uint32_t totalcount, uint64_t maxcount, uint64_t sumcount) { checkSum = checksum; @@ -60,44 +65,70 @@ public: histogram.push_back(ProfileSummaryHistogram(s, num, mincount, cumcounts)); } void DumpSummary(); - uint64_t GetCheckSum() { return checkSum; } - uint32_t GetRun() { return run; } - uint32_t GetTotalCount() { return totalCount; } - uint64_t GetMaxCount() { return maxCount; } - uint64_t GetSumCount() { return sumCount; } - uint32_t GetHistogramLength() { return histogram.size(); } - MapleVector& GetHistogram() { return histogram; } - -private: - uint64_t checkSum; // checksum value of module - uint32_t run; // run times - uint32_t totalCount; // number of counters - uint64_t maxCount; // max counter value in single run - uint64_t sumCount; // sum of all counters accumulated. - MapleVector histogram; // record gcov_bucket_type histogram[GCOV_HISTOGRAM_SIZE]; + uint64_t GetCheckSum() { + return checkSum; + } + uint32_t GetRun() { + return run; + } + uint32_t GetTotalCount() { + return totalCount; + } + uint64_t GetMaxCount() { + return maxCount; + } + uint64_t GetSumCount() { + return sumCount; + } + uint32_t GetHistogramLength() { + return histogram.size(); + } + void ProcessHistogram(); + MapleVector &GetHistogram() { + return histogram; + } + + private: + uint64_t checkSum; // checksum value of module + uint32_t run; // run times + uint32_t totalCount; // number of counters + uint64_t maxCount; // max counter value in single run + uint64_t sumCount; // sum of all counters accumulated. + MapleVector histogram; // record gcov_bucket_type histogram[GCOV_HISTOGRAM_SIZE]; }; class FuncProfInfo { public: - FuncProfInfo(MapleAllocator* alloc, unsigned funcIdent, unsigned lineno_cs, - unsigned cfg_cs, unsigned countnum = 0) : ident(funcIdent), linenoChecksum(lineno_cs), - cfgChecksum(cfg_cs), edgeCounts(countnum), counts(alloc->Adapter()) {}; + FuncProfInfo(MapleAllocator *alloc, unsigned funcIdent, unsigned lineno_cs, unsigned cfg_cs, unsigned countnum = 0) + : ident(funcIdent), + linenoChecksum(lineno_cs), + cfgChecksum(cfg_cs), + edgeCounts(countnum), + counts(alloc->Adapter()){}; ~FuncProfInfo() = default; - uint64_t GetFuncFrequency() const { return entry_freq; } - void SetFuncFrequency(uint64_t freq) { entry_freq = freq; } + uint64_t GetFuncFrequency() const { + return entry_freq; + } + void SetFuncFrequency(uint64_t freq) { + entry_freq = freq; + } - uint64_t GetFuncRealFrequency() const { return real_entryfreq; } - void SetFuncRealFrequency(uint64_t freq) { real_entryfreq = freq; } + uint64_t GetFuncRealFrequency() const { + return real_entryfreq; + } + void SetFuncRealFrequency(uint64_t freq) { + real_entryfreq = freq; + } - std::unordered_map& GetStmtFreqs() { + std::unordered_map &GetStmtFreqs() { return stmtFreqs; } uint64_t GetStmtFreq(uint32_t stmtID) { if (stmtFreqs.count(stmtID) > 0) { return stmtFreqs[stmtID]; } - return -1; // unstored + return -1; // unstored } void SetStmtFreq(uint32_t stmtID, uint64_t freq) { stmtFreqs[stmtID] = freq; @@ -129,9 +160,9 @@ class FuncProfInfo { // Raw arc coverage counts. unsigned edgeCounts; MapleVector counts; - uint64_t entry_freq; // record entry bb frequence - std::unordered_map stmtFreqs; // stmt_id is key, counter value - uint64_t real_entryfreq; // function prof data may be modified after clone/inline + uint64_t entry_freq; // record entry bb frequence + std::unordered_map stmtFreqs; // stmt_id is key, counter value + uint64_t real_entryfreq; // function prof data may be modified after clone/inline }; class MplProfileData { @@ -140,7 +171,7 @@ class MplProfileData { FuncProfInfo *GetFuncProfile(unsigned puidx) { if (funcsCounter.count(puidx) > 0) { - return funcsCounter[puidx]; + return funcsCounter[puidx]; } return nullptr; } @@ -156,12 +187,18 @@ class MplProfileData { } void DumpProfileData(); void DumpFunctionsProfile(); - MapleUnorderedMap funcsCounter; // use puidx as key + bool IsHotCallSite(uint64_t freq); + + MapleUnorderedMap funcsCounter; // use puidx as key // record module profile information and statistics of count information ProfileSummary summary; -private: + uint64_t hotCountThreshold = 0; + + private: + uint64_t GetHotThreshold(); + MemPool *mp; MapleAllocator *alloc; }; -} // end namespace -#endif // MAPLE_UTIL_INCLUDE_MPL_PROFDATA_H +} // namespace maple +#endif // MAPLE_UTIL_INCLUDE_MPL_PROFDATA_H diff --git a/src/mapleall/maple_util/src/mpl_profdata.cpp b/src/mapleall/maple_util/src/mpl_profdata.cpp index 64e37ed9c0..16ef9da267 100644 --- a/src/mapleall/maple_util/src/mpl_profdata.cpp +++ b/src/mapleall/maple_util/src/mpl_profdata.cpp @@ -13,26 +13,29 @@ * See the Mulan PSL v2 for more details. */ #include "mpl_profdata.h" + #include "mpl_logging.h" +#include "option.h" + namespace maple { void ProfileSummary::DumpSummary() { LogInfo::MapleLogger() << "---------ProfileSummary-------------- \n"; LogInfo::MapleLogger() << " checkSum: " << std::hex << "0x" << checkSum << "\n"; - LogInfo::MapleLogger() << " runtimes: " << std::dec << run << "\n"; - LogInfo::MapleLogger() << " totalCounts: " << std::dec << totalCount << "\n"; + LogInfo::MapleLogger() << " runtimes: " << std::dec << run << "\n"; + LogInfo::MapleLogger() << " totalCounts: " << std::dec << totalCount << "\n"; LogInfo::MapleLogger() << " maxCount: " << std::dec << maxCount << "\n"; LogInfo::MapleLogger() << " count histogram: countRange countNum minCount cumCount \n"; for (auto &it : histogram) { - LogInfo::MapleLogger() <<" " << std::dec << it.startValue << "\t"; - LogInfo::MapleLogger() << std::dec << it. countNums<< "\t" << it.countMinVal << "\t" << it.countCumValue << "\n"; + LogInfo::MapleLogger() << " " << std::dec << it.startValue << "\t"; + LogInfo::MapleLogger() << std::dec << it.countNums << "\t" << it.countMinVal << "\t" << it.countCumValue << "\n"; } } void FuncProfInfo::DumpFunctionProfile() { LogInfo::MapleLogger() << "function ident " << std::dec << ident; LogInfo::MapleLogger() << " lino_checksum 0x" << std::hex << linenoChecksum << ", "; - LogInfo::MapleLogger() << " cfg_checksum 0x" << std::hex << cfgChecksum << "\n"; - LogInfo::MapleLogger() << " num_counts " << std::dec << edgeCounts << " : "; + LogInfo::MapleLogger() << " cfg_checksum 0x" << std::hex << cfgChecksum << "\n"; + LogInfo::MapleLogger() << " num_counts " << std::dec << edgeCounts << " : "; for (int i = 0; i < edgeCounts; i++) { LogInfo::MapleLogger() << std::dec << " " << counts[i]; } @@ -50,4 +53,48 @@ void MplProfileData::DumpProfileData() { summary.DumpSummary(); DumpFunctionsProfile(); } -} // endof namespace + +void ProfileSummary::ProcessHistogram() { + int countsum = 0; + int n = histogram.size(); + for (int i = n - 1; i >= 0; i--) { + countsum += histogram[i].countNums; + histogram[i].countRatio = ((float)(countsum) / (float)totalCount) * 100; + } +} + +#define HOTRATIO 90 +uint64_t MplProfileData::GetHotThreshold() { + for (auto &it : summary.GetHistogram()) { + if (it.countRatio >= HOTRATIO) { + hotCountThreshold = it.startValue; + } else { + if (hotCountThreshold == 0) { + hotCountThreshold = it.countMinVal; // set minValue in currentRange which satisfy hot ratio + } + return hotCountThreshold; + } + } + // should not be here + return 100; +} + +bool MplProfileData::IsHotCallSite(uint64_t freq) { + auto &h = summary.GetHistogram(); + if (hotCountThreshold == 0) { + if (Options::profileHotCountSeted) { + hotCountThreshold = Options::profileHotCount; + } else if (summary.GetTotalCount() > 0 && !h.empty() && h[0].countRatio == 0) { + // init countRatio and compute hotCountThreshold + summary.ProcessHistogram(); + hotCountThreshold = GetHotThreshold(); + } else if (h.empty()) { + // should not be here + ASSERT(0, "should not be here"); + hotCountThreshold = 1; + } + } + return freq >= hotCountThreshold; +} + +} // namespace maple diff --git a/src/mapleall/mpl2mpl/include/inline_transformer.h b/src/mapleall/mpl2mpl/include/inline_transformer.h index 1569f9b900..78137411b9 100644 --- a/src/mapleall/mpl2mpl/include/inline_transformer.h +++ b/src/mapleall/mpl2mpl/include/inline_transformer.h @@ -55,9 +55,8 @@ class InlineTransformer { callee(callee), callStmt(callStmt), dumpDetail(dumpDetail), - cg(cg) { - updateFreq = (Options::profileUse && caller.GetFuncProfData() && callee.GetFuncProfData()); - }; + cg(cg), + updateFreq(Options::profileUse && caller.GetFuncProfData() && callee.GetFuncProfData()){}; bool PerformInline(BlockNode &enclosingBlk); static void ReplaceSymbols(BaseNode*, uint32, const std::vector*); diff --git a/src/mapleall/mpl2mpl/src/call_graph.cpp b/src/mapleall/mpl2mpl/src/call_graph.cpp index 7e932a68a2..6dd6a88cab 100644 --- a/src/mapleall/mpl2mpl/src/call_graph.cpp +++ b/src/mapleall/mpl2mpl/src/call_graph.cpp @@ -14,7 +14,6 @@ */ #include "call_graph.h" - #include "option.h" #include "retype.h" #include "string_utils.h" @@ -201,7 +200,7 @@ uint64_t CGNode::GetCallsiteFrequency(const StmtNode *callstmt) const { uint64_t CGNode::GetFuncFrequency() const { FuncProfInfo *funcInfo = mirFunc->GetFuncProfData(); if (funcInfo) { - return funcInfo->GetFuncFrequency(); + return funcInfo->GetFuncRealFrequency(); } ASSERT(0, "should not be here"); return 0; @@ -257,8 +256,8 @@ void CallGraph::DelNode(CGNode &node) { } } -CallGraph::CallGraph(MIRModule &m, MemPool &memPool, MemPool &templPool, - const KlassHierarchy &kh, const std::string &fn) +CallGraph::CallGraph(MIRModule &m, MemPool &memPool, MemPool &templPool, const KlassHierarchy &kh, + const std::string &fn) : AnalysisResult(&memPool), mirModule(&m), cgAlloc(&memPool), @@ -524,7 +523,7 @@ void CallGraph::RecordLocalConstValue(const StmtNode *stmt) { CallNode *CallGraph::ReplaceIcallToCall(BlockNode &body, IcallNode *icall, PUIdx newPUIdx) { MapleVector opnds(icall->GetNopnd().begin() + 1, icall->GetNopnd().end(), - CurFunction()->GetCodeMPAllocator().Adapter()); + CurFunction()->GetCodeMPAllocator().Adapter()); CallNode *newCall = nullptr; if (icall->GetOpCode() == OP_icall) { newCall = mirBuilder->CreateStmtCall(newPUIdx, opnds, OP_call); @@ -747,8 +746,8 @@ void CallGraph::HandleICall(BlockNode &body, CGNode &node, StmtNode *stmt, uint3 icallToFix.insert({funcType->GetTypeIndex(), tempSet}); } CHECK_FATAL(CurFunction()->GetPuidx() == node.GetPuIdx(), "Error"); - Callsite callSite = { callInfo, node.GetCallee().at(callInfo) }; - icallToFix.at(funcType->GetTypeIndex())->insert({ node.GetPuIdx(), callSite }); + Callsite callSite = {callInfo, node.GetCallee().at(callInfo)}; + icallToFix.at(funcType->GetTypeIndex())->insert({node.GetPuIdx(), callSite}); } void CallGraph::HandleBody(MIRFunction &func, BlockNode &body, CGNode &node, uint32 loopDepth) { @@ -1235,7 +1234,7 @@ void DoDevirtual(const Klass &klass, const KlassHierarchy &klassh) { Opcode op = stmt->GetOpCode(); switch (op) { case OP_comment: - CASE_OP_ASSERT_NONNULL + CASE_OP_ASSERT_NONNULL case OP_brtrue: case OP_brfalse: case OP_try: @@ -1504,7 +1503,7 @@ void DoDevirtual(const Klass &klass, const KlassHierarchy &klassh) { } } } - [[clang::fallthrough]]; + [[clang::fallthrough]]; case OP_call: case OP_callassigned: { CallNode *callNode = static_cast(stmt); @@ -1559,8 +1558,9 @@ void IPODevirtulize::DevirtualFinal() { if (GlobalTables::GetGsymTable().GetSymbolFromStrIdx(classType->GetStaticFieldsGStrIdx(i)) == nullptr) { continue; } - TyIdx tyIdx = GlobalTables::GetGsymTable().GetSymbolFromStrIdx( - classType->GetStaticFieldsPair(i).first)->GetInferredTyIdx(); + TyIdx tyIdx = GlobalTables::GetGsymTable() + .GetSymbolFromStrIdx(classType->GetStaticFieldsPair(i).first) + ->GetInferredTyIdx(); if (tyIdx != kInitTyIdx && tyIdx != kNoneTyIdx) { CHECK_FATAL(attribute.GetAttr(FLDATTR_final), "Must be final private"); if (debugFlag) { @@ -1746,10 +1746,10 @@ void CallGraph::RemoveFileStaticRootNodes() { [](const CGNode *root) { // root means no caller, we should also make sure that root is not be used in addroffunc auto mirFunc = root->GetMIRFunction(); - return root != nullptr && mirFunc != nullptr && // remove before - // if static functions or inline but not extern modified functions are not used anymore, - // they can be removed safely. - !root->IsAddrTaken() && (mirFunc->IsStatic() || (mirFunc->IsInline() && !mirFunc->IsExtern())); + return root != nullptr && mirFunc != nullptr && // remove before + // if static functions or inline but not extern modified functions are not used anymore, + // they can be removed safely. + !root->IsAddrTaken() && (mirFunc->IsStatic() || (mirFunc->IsInline() && !mirFunc->IsExtern())); }); for (auto *root : staticRoots) { // DFS delete root and its callee that is static and have no caller after root is deleted diff --git a/src/mapleall/mpl2mpl/src/inline.cpp b/src/mapleall/mpl2mpl/src/inline.cpp index 1bed8c0df2..e0d6984461 100644 --- a/src/mapleall/mpl2mpl/src/inline.cpp +++ b/src/mapleall/mpl2mpl/src/inline.cpp @@ -117,7 +117,7 @@ void MInline::InitRCWhiteList() { void MInline::InitExcludedCaller() { std::set specialfunc = { - std::string("Landroid_2Fcontent_2Fpm_2FFallbackCategoryProvider_3B_7CloadFallbacks_7C_28_29V"), + std::string("Landroid_2Fcontent_2Fpm_2FFallbackCategoryProvider_3B_7CloadFallbacks_7C_28_29V"), }; for (auto it = specialfunc.begin(); it != specialfunc.end(); ++it) { GStrIdx strIdx = GlobalTables::GetStrTable().GetStrIdxFromName(*it); @@ -140,27 +140,40 @@ void MInline::InitExcludedCallee() { (void)excludedCallee.insert(strIdx); } std::set setArrayHotFunc = { - std::string("Landroid_2Ficu_2Fimpl_2Fduration_2FBasicDurationFormat_3B_7CformatDuration_7C_28Ljava_2Flang_2FObject_3B_29Ljava_2Flang_2FString_3B"), - std::string("Landroid_2Fapp_2FIActivityManager_24Stub_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_3BLandroid_2Fos_2FParcel_3BI_29Z"), - std::string("Landroid_2Fcontent_2Fpm_2FIPackageManager_24Stub_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_3BLandroid_2Fos_2FParcel_3BI_29Z"), - std::string("Landroid_2Fcontent_2FIContentService_24Stub_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_3BLandroid_2Fos_2FParcel_3BI_29Z"), - std::string("Lcom_2Fandroid_2Fserver_2Fam_2FHwActivityManagerService_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_3BLandroid_2Fos_2FParcel_3BI_29Z"), - std::string("Lcom_2Fandroid_2Fserver_2Fam_2FActivityManagerService_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_3BLandroid_2Fos_2FParcel_3BI_29Z"), - std::string("Ljava_2Flang_2Freflect_2FMethod_3B_7Cinvoke_7C_28Ljava_2Flang_2FObject_3BALjava_2Flang_2FObject_3B_29Ljava_2Flang_2FObject_3B"), + std::string("Landroid_2Ficu_2Fimpl_2Fduration_2FBasicDurationFormat_3B_7CformatDuration_7C_28Ljava_2Flang_" + "2FObject_3B_29Ljava_2Flang_2FString_3B"), + std::string("Landroid_2Fapp_2FIActivityManager_24Stub_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_3BLandroid_" + "2Fos_2FParcel_3BI_29Z"), + std::string("Landroid_2Fcontent_2Fpm_2FIPackageManager_24Stub_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_" + "3BLandroid_2Fos_2FParcel_3BI_29Z"), + std::string("Landroid_2Fcontent_2FIContentService_24Stub_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_3BLandroid_" + "2Fos_2FParcel_3BI_29Z"), + std::string("Lcom_2Fandroid_2Fserver_2Fam_2FHwActivityManagerService_3B_7ConTransact_7C_28ILandroid_2Fos_" + "2FParcel_3BLandroid_2Fos_2FParcel_3BI_29Z"), + std::string("Lcom_2Fandroid_2Fserver_2Fam_2FActivityManagerService_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_" + "3BLandroid_2Fos_2FParcel_3BI_29Z"), + std::string("Ljava_2Flang_2Freflect_2FMethod_3B_7Cinvoke_7C_28Ljava_2Flang_2FObject_3BALjava_2Flang_2FObject_3B_" + "29Ljava_2Flang_2FObject_3B"), std::string("Lcom_2Fandroid_2Fserver_2FSystemServer_3B_7Crun_7C_28_29V"), - std::string("Lcom_2Fandroid_2Finternal_2Ftelephony_2FIPhoneStateListener_24Stub_24Proxy_3B_7ConMessageWaitingIndicatorChanged_7C_28Z_29V"), + std::string("Lcom_2Fandroid_2Finternal_2Ftelephony_2FIPhoneStateListener_24Stub_24Proxy_3B_" + "7ConMessageWaitingIndicatorChanged_7C_28Z_29V"), std::string("Landroid_2Fview_2Fanimation_2FTransformation_3B_7C_3Cinit_3E_7C_28_29V"), std::string("Lcom_2Fandroid_2Fserver_2FSystemServer_3B_7CstartOtherServices_7C_28_29V"), std::string("Lcom_2Fandroid_2Fserver_2Fpm_2FSettings_3B_7CreadLPw_7C_28Ljava_2Futil_2FList_3B_29Z"), std::string("Lcom_2Fandroid_2Fserver_2Fam_2FActivityManagerService_3B_7CupdateOomAdjLocked_7C_28_29V"), - std::string("Lcom_2Fandroid_2Fserver_2Fpm_2FHwPackageManagerService_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_3BLandroid_2Fos_2FParcel_3BI_29Z"), - std::string("Lcom_2Fandroid_2Fserver_2Fpm_2FPackageManagerService_3B_7CgeneratePackageInfo_7C_28Lcom_2Fandroid_2Fserver_2Fpm_2FPackageSetting_3BII_29Landroid_2Fcontent_2Fpm_2FPackageInfo_3B"), - std::string("Ljava_2Flang_2FThrowable_3B_7CprintStackTrace_7C_28Ljava_2Flang_2FThrowable_24PrintStreamOrWriter_3B_29V"), + std::string("Lcom_2Fandroid_2Fserver_2Fpm_2FHwPackageManagerService_3B_7ConTransact_7C_28ILandroid_2Fos_2FParcel_" + "3BLandroid_2Fos_2FParcel_3BI_29Z"), + std::string("Lcom_2Fandroid_2Fserver_2Fpm_2FPackageManagerService_3B_7CgeneratePackageInfo_7C_28Lcom_2Fandroid_" + "2Fserver_2Fpm_2FPackageSetting_3BII_29Landroid_2Fcontent_2Fpm_2FPackageInfo_3B"), + std::string( + "Ljava_2Flang_2FThrowable_3B_7CprintStackTrace_7C_28Ljava_2Flang_2FThrowable_24PrintStreamOrWriter_3B_29V"), std::string("Lcom_2Fandroid_2Fserver_2FSystemServer_3B_7CstartBootstrapServices_7C_28_29V"), std::string("Ljava_2Flang_2FThrowable_3B_7CgetOurStackTrace_7C_28_29ALjava_2Flang_2FStackTraceElement_3B"), std::string("Ldalvik_2Fsystem_2FVMStack_3B_7CgetStackClass2_7C_28_29Ljava_2Flang_2FClass_3B"), - std::string("Lcom_2Fandroid_2Fserver_2Fam_2FActivityManagerService_3B_7CattachApplicationLocked_7C_28Landroid_2Fapp_2FIApplicationThread_3BI_29Z"), - std::string("Lcom_2Fandroid_2Fserver_2FInputMethodManagerService_3B_7ChideCurrentInputLocked_7C_28ILandroid_2Fos_2FResultReceiver_3B_29Z"), + std::string("Lcom_2Fandroid_2Fserver_2Fam_2FActivityManagerService_3B_7CattachApplicationLocked_7C_28Landroid_" + "2Fapp_2FIApplicationThread_3BI_29Z"), + std::string("Lcom_2Fandroid_2Fserver_2FInputMethodManagerService_3B_7ChideCurrentInputLocked_7C_28ILandroid_2Fos_" + "2FResultReceiver_3B_29Z"), }; for (auto it = setArrayHotFunc.begin(); it != setArrayHotFunc.end(); ++it) { GStrIdx strIdx = GlobalTables::GetStrTable().GetStrIdxFromName(*it); @@ -251,7 +264,7 @@ FuncCostResultType MInline::GetFuncCost(const MIRFunction &func, const BaseNode break; } } - [[clang::fallthrough]]; + [[clang::fallthrough]]; case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_customcall: @@ -423,15 +436,17 @@ bool MInline::IsHotCallSite(const MIRFunction &caller, const MIRFunction &callee } // use maple instrument profile if (Options::profileUse) { - return caller.GetFuncProfData()->IsHotCallSite(callStmt.GetStmtID()); + if (!caller.GetFuncProfData()) return false; + int64_t freq = caller.GetFuncProfData()->GetStmtFreq(callStmt.GetStmtID()); + ASSERT(freq > 0, "sanity check"); + return module.GetMapleProfile()->IsHotCallSite((uint64_t)freq); } return module.GetProfile().CheckFuncHot(caller.GetName()); } bool MInline::FuncInlinable(const MIRFunction &func) const { std::string name = func.GetName(); - if (StringUtils::StartsWith(name, kReflectionClassStr) || - StringUtils::StartsWith(name, kJavaLangClassesStr) || + if (StringUtils::StartsWith(name, kReflectionClassStr) || StringUtils::StartsWith(name, kJavaLangClassesStr) || StringUtils::StartsWith(name, kJavaLangReferenceStr)) { return false; } @@ -686,7 +701,7 @@ static InlineResult GetInlineResult(uint32 threshold, uint32 thresholdType, uint } void MInline::AdjustInlineThreshold(const MIRFunction &caller, const MIRFunction &callee, const CallNode &callStmt, - uint32 &threshold, uint32 &thresholdType) { + uint32 &threshold, uint32 &thresholdType) { // Update threshold if this callsite is hot, or dealing with recursive function if (inlineWithProfile && IsHotCallSite(caller, callee, callStmt)) { threshold = hotFuncThreshold; @@ -705,9 +720,7 @@ void MInline::AdjustInlineThreshold(const MIRFunction &caller, const MIRFunction threshold <<= kRelaxThresholdForInlineHint; } // We don't always inline called_once callee to avoid super big caller - if (module.GetSrcLang() == kSrcLangC && - callee.GetAttr(FUNCATTR_called_once) && - callee.GetAttr(FUNCATTR_static)) { + if (module.GetSrcLang() == kSrcLangC && callee.GetAttr(FUNCATTR_called_once) && callee.GetAttr(FUNCATTR_static)) { threshold <<= kRelaxThresholdForCalledOnce; } } diff --git a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp index de5c758b74..ef050a798f 100644 --- a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp +++ b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp @@ -13,22 +13,26 @@ * See the Mulan PSL v2 for more details. */ -#include -#include -#include +#include "mpl_profdata_parser.h" + #include +#include #include +#include +#include +#include + #include #include -#include #include -#include "option.h" + #include "mpl_logging.h" -#include "mpl_profdata_parser.h" +#include "option.h" namespace maple { -template T ProfDataBinaryImportBase::ReadNum() { +template +T ProfDataBinaryImportBase::ReadNum() { unsigned NumBytesRead = 0; uint64_t Val = namemangler::DecodeULEB128(pos, &NumBytesRead); @@ -40,7 +44,7 @@ int ProfileSummaryImport::ReadSummary(MplProfileData *profData) { CHECK_FATAL(profData != nullptr, "sanity check"); uint64_t magicNum = ReadNum(); if (magicNum != kMapleProfDataMagicNumber) { - LogInfo::MapleLogger() << "magic number error, quit\n"; + LogInfo::MapleLogger() << "magic number error, quit\n"; return 1; } uint64_t checksum = ReadNum(); @@ -85,7 +89,7 @@ int FunctionProfileImport::ReadFuncProfile(MplProfileData *profData) { int MplProfDataParser::ReadMapleProfileData() { std::string mprofDataFile = Options::profile; if (mprofDataFile.empty()) { - if (const char* env_p = std::getenv("GCOV_PREFIX")) { + if (const char *env_p = std::getenv("GCOV_PREFIX")) { mprofDataFile.append(env_p); } else { mprofDataFile.append("."); @@ -105,18 +109,18 @@ int MplProfDataParser::ReadMapleProfileData() { return 1; } // get length of file - inputStream.seekg (0, inputStream.end); + inputStream.seekg(0, inputStream.end); int length = inputStream.tellg(); - inputStream.seekg (0, inputStream.beg); - const uint32_t sizeThreshold = 1024*10; + inputStream.seekg(0, inputStream.beg); + const uint32_t sizeThreshold = 1024 * 10; CHECK_FATAL(length <= sizeThreshold, "NYI::large .mprofdata file size is larger than threashold, do chunk memory\n"); std::unique_ptr buffer(new char[sizeof(char) * length]()); - inputStream.read (buffer.get(), length); + inputStream.read(buffer.get(), length); inputStream.close(); // read 1st part summary ProfileSummaryImport summaryImport(mprofDataFile, inputStream); - summaryImport.SetPosition((uint8_t *)buffer.get()); + summaryImport.SetPosition((uint8_t*)buffer.get()); int res = summaryImport.ReadSummary(profData); if (res) { LogInfo::MapleLogger() << "no summary part\n"; @@ -144,9 +148,9 @@ void MMplProfDataParser::GetAnalysisDependence(AnalysisDep &aDep) const { } bool MMplProfDataParser::PhaseRun(maple::MIRModule &m) { - - MemPool *memPool = m.GetMemPool(); // use global pool to store profile data - MplProfDataParser parser(m, memPool, true/*debug*/); + MemPool *memPool = m.GetMemPool(); // use global pool to store profile data + bool enableDebug = false; + MplProfDataParser parser(m, memPool, enableDebug); int res = parser.ReadMapleProfileData(); if (res) { // something wrong @@ -158,5 +162,4 @@ bool MMplProfDataParser::PhaseRun(maple::MIRModule &m) { return true; } - -} // end namespace maple +} // end namespace maple -- Gitee From eab416e1a58594daba2b8e58ea91c8a9a2c234d5 Mon Sep 17 00:00:00 2001 From: linma Date: Fri, 29 Jul 2022 07:38:14 -0700 Subject: [PATCH 13/16] pgo: refine profiledata name and locations --- src/mapleall/maple_ir/include/mir_module.h | 11 +++-- src/mapleall/maple_ir/src/mir_nodes.cpp | 21 ++++---- .../mpl2mpl/src/mpl_profdata_parser.cpp | 48 ++++++++++++++++--- 3 files changed, 61 insertions(+), 19 deletions(-) diff --git a/src/mapleall/maple_ir/include/mir_module.h b/src/mapleall/maple_ir/include/mir_module.h index be748df3f5..f5965f008d 100644 --- a/src/mapleall/maple_ir/include/mir_module.h +++ b/src/mapleall/maple_ir/include/mir_module.h @@ -341,10 +341,13 @@ class MIRModule { } std::string GetProfileDataFileName() const { - std::string profileDataFileName = fileName.substr(0, fileName.find_last_of(".")); - std::replace(profileDataFileName.begin(), profileDataFileName.end(), '.', '_'); - std::replace(profileDataFileName.begin(), profileDataFileName.end(), '-', '_'); - std::replace(profileDataFileName.begin(), profileDataFileName.end(), '/', '_'); + std::string profileDataFileName = GetFileName().substr(0, GetFileName().find_last_of(".")); + char *gcov_path = std::getenv("GCOV_PREFIX"); + std::string gcov_prefix = gcov_path ? gcov_path : ""; + if (!gcov_prefix.empty() && (gcov_prefix.back() != '/')) { + gcov_prefix.append("/"); + } + profileDataFileName = gcov_prefix + profileDataFileName; return profileDataFileName; } diff --git a/src/mapleall/maple_ir/src/mir_nodes.cpp b/src/mapleall/maple_ir/src/mir_nodes.cpp index 579be730c5..d1204d70b2 100644 --- a/src/mapleall/maple_ir/src/mir_nodes.cpp +++ b/src/mapleall/maple_ir/src/mir_nodes.cpp @@ -686,10 +686,11 @@ void AddroflabelNode::Dump(int32 indent [[maybe_unused]]) const { void StmtNode::DumpBase(int32 indent) const { srcPosition.DumpLoc(lastPrintedLineNum, lastPrintedColumnNum); // 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"; + if (Options::profileUse && theMIRModule->CurFunction()->GetFuncProfData()) { + int64_t freq = static_cast(theMIRModule->CurFunction()->GetFuncProfData()->GetStmtFreq(GetStmtID())); + if (freq >= 0) { + LogInfo::MapleLogger() << "stmtID " << GetStmtID() << " freq " << freq << "\n"; + } } PrintIndentation(indent); LogInfo::MapleLogger() << kOpcodeInfo.GetTableItemAt(GetOpCode()).name; @@ -1323,8 +1324,10 @@ void BlockNode::Dump(int32 indent, const MIRSymbolTable *theSymTab, MIRPregTable srcPosition.DumpLoc(lastPrintedLineNum, lastPrintedColumnNum); // dump stmtFreqs if (Options::profileUse && theMIRModule->CurFunction()->GetFuncProfData()) { - LogInfo::MapleLogger() << "stmtID " << GetStmtID() << " freq " << - theMIRModule->CurFunction()->GetFuncProfData()->GetStmtFreq(GetStmtID()) << "\n"; + int64_t freq = static_cast(theMIRModule->CurFunction()->GetFuncProfData()->GetStmtFreq(GetStmtID())); + if (freq >= 0) { + LogInfo::MapleLogger() << "stmtID " << GetStmtID() << " freq " << freq << "\n"; + } } for (auto &stmt : GetStmtNodes()) { stmt.Dump(indent + 1); @@ -1339,8 +1342,10 @@ void LabelNode::Dump(int32 indent [[maybe_unused]]) const { } // dump stmtFreqs if (Options::profileUse && theMIRModule->CurFunction()->GetFuncProfData()) { - LogInfo::MapleLogger() << "stmtID " << GetStmtID() << " freq " << - theMIRModule->CurFunction()->GetFuncProfData()->GetStmtFreq(GetStmtID()) << "\n"; + int64_t freq = static_cast(theMIRModule->CurFunction()->GetFuncProfData()->GetStmtFreq(GetStmtID())); + if (freq >= 0) { + LogInfo::MapleLogger() << "stmtID " << GetStmtID() << " freq " << freq << "\n"; + } } LogInfo::MapleLogger() << "@" << theMIRModule->CurFunction()->GetLabelName(labelIdx) << " "; } diff --git a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp index ef050a798f..4d686e42ee 100644 --- a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp +++ b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp @@ -89,17 +89,51 @@ int FunctionProfileImport::ReadFuncProfile(MplProfileData *profData) { int MplProfDataParser::ReadMapleProfileData() { std::string mprofDataFile = Options::profile; if (mprofDataFile.empty()) { - if (const char *env_p = std::getenv("GCOV_PREFIX")) { - mprofDataFile.append(env_p); + if (const char *env_gcovprefix = std::getenv("GCOV_PREFIX")) { + mprofDataFile.append(env_gcovprefix); + if (mprofDataFile.back() != '/') { + mprofDataFile.append("/"); + } + if (dumpDetail) { + LogInfo::MapleLogger() << "set env gcov_prefix= " << mprofDataFile << std::endl; + } + uint32_t stripnum = 0; + if (const char *env_gcovprefixstrip = std::getenv("GCOV_PREFIX_STRIP")) { + std::string strip(env_gcovprefixstrip); + stripnum = std::stoi(strip); + if (dumpDetail) { + LogInfo::MapleLogger() << "set env gcov_prefix_strip=" << strip << std::endl; + } + } + std::string profDataFileName = m.GetProfileDataFileName(); + if (dumpDetail) { + LogInfo::MapleLogger() << "module profdata Name: " << profDataFileName << std::endl; + } + // reduce path in profDataFileName + while (stripnum > 0 && profDataFileName.size() > 1) { + auto pos = profDataFileName.find_first_of("/", 1); + profDataFileName = profDataFileName.substr(pos); + stripnum--; + } + if (dumpDetail) { + LogInfo::MapleLogger() << "after strip, module profdata Name: " << profDataFileName << std::endl; + } + CHECK_FATAL(profDataFileName.size() > 0, "sanity check"); + mprofDataFile.append(profDataFileName); } else { - mprofDataFile.append("."); + // if gcov_prefix is not set, find .mprofdata according to m.profiledata + mprofDataFile = m.GetProfileDataFileName(); + if (dumpDetail) { + LogInfo::MapleLogger() << "NO ENV, module profdata Name: " << mprofDataFile << std::endl; + } } - mprofDataFile.append("/"); - mprofDataFile.append(m.GetProfileDataFileName()); + // add .mprofdata mprofDataFile.append(namemangler::kMplProfFileNameExt); } ASSERT(!mprofDataFile.empty(), "null check"); - + if (dumpDetail) { + LogInfo::MapleLogger() << "will open mprofileData " << mprofDataFile << std::endl; + } // create mpl profdata profData = mempool->New(mempool, &alloc); // read .mprofdata @@ -149,7 +183,7 @@ void MMplProfDataParser::GetAnalysisDependence(AnalysisDep &aDep) const { bool MMplProfDataParser::PhaseRun(maple::MIRModule &m) { MemPool *memPool = m.GetMemPool(); // use global pool to store profile data - bool enableDebug = false; + bool enableDebug = false; // true to dump trace MplProfDataParser parser(m, memPool, enableDebug); int res = parser.ReadMapleProfileData(); if (res) { -- Gitee From f7dc96ffd5a28a8c8a7cc4e1fcde2a1b4ff8f737 Mon Sep 17 00:00:00 2001 From: linma Date: Fri, 29 Jul 2022 07:43:04 -0700 Subject: [PATCH 14/16] missed file --- src/mapleall/mpl2mpl/src/gen_profile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mapleall/mpl2mpl/src/gen_profile.cpp b/src/mapleall/mpl2mpl/src/gen_profile.cpp index b586d91474..cff72a9561 100644 --- a/src/mapleall/mpl2mpl/src/gen_profile.cpp +++ b/src/mapleall/mpl2mpl/src/gen_profile.cpp @@ -106,7 +106,7 @@ void ProfileGen::CreateModProfDesc() { // Make the profile file name as fileName.gcda std::string profFileName = mod.GetProfileDataFileName() + namemangler::kProfFileNameExt; auto *profileFNMirConst = - modMP->New("./" + profFileName, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(PTY_a64))); + modMP->New(profFileName, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(PTY_a64))); modProfDescSymMirConst->AddItem(profileFNMirConst, 6); // Additional profiling (in addition to frequency profiling) should be added here -- Gitee From 6500dddc070131fdbc1c477b46e9d5883de3be50 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Sat, 30 Jul 2022 22:10:08 -0700 Subject: [PATCH 15/16] Fixed the formatting issues --- src/mapleall/maple_me/src/me_cfg.cpp | 4 +- src/mapleall/maple_me/src/me_emit.cpp | 2 +- .../maple_me/src/me_loop_inversion.cpp | 35 +++-- src/mapleall/maple_me/src/pme_emit.cpp | 2 +- .../maple_util/include/mpl_profdata.h | 29 ++--- src/mapleall/maple_util/include/namemangler.h | 4 +- src/mapleall/maple_util/src/mpl_profdata.cpp | 2 +- src/mapleall/maple_util/src/namemangler.cpp | 121 +++++++++--------- .../mpl2mpl/include/mpl_profdata_parser.h | 7 +- .../mpl2mpl/src/mpl_profdata_parser.cpp | 45 ++++--- 10 files changed, 136 insertions(+), 115 deletions(-) diff --git a/src/mapleall/maple_me/src/me_cfg.cpp b/src/mapleall/maple_me/src/me_cfg.cpp index 192b005f03..3b9a752fde 100644 --- a/src/mapleall/maple_me/src/me_cfg.cpp +++ b/src/mapleall/maple_me/src/me_cfg.cpp @@ -1933,8 +1933,8 @@ void MeCFG::ConstructStmtFreq() { for (auto bIt = valid_begin(); bIt != eIt; ++bIt) { auto *bb = *bIt; if (bIt == common_entry()) { - funcData->entry_freq = bb->GetFrequency(); - funcData->real_entryfreq = funcData->entry_freq; + funcData->entryFreq = bb->GetFrequency(); + funcData->realEntryfreq = funcData->entryFreq; } for (auto &stmt : bb->GetStmtNodes()) { Opcode op = stmt.GetOpCode(); diff --git a/src/mapleall/maple_me/src/me_emit.cpp b/src/mapleall/maple_me/src/me_emit.cpp index 00e6f26cfe..7d308d2884 100644 --- a/src/mapleall/maple_me/src/me_emit.cpp +++ b/src/mapleall/maple_me/src/me_emit.cpp @@ -81,7 +81,7 @@ bool MEEmit::PhaseRun(maple::MeFunction &f) { mirFunction->SetBody(mirFunction->GetCodeMempool()->New()); if (Options::profileUse && mirFunction->GetFuncProfData()) { mirFunction->GetFuncProfData()->SetStmtFreq(mirFunction->GetBody()->GetStmtID(), - mirFunction->GetFuncProfData()->entry_freq); + mirFunction->GetFuncProfData()->entryFreq); } // initialize is_deleted field to true; will reset when emitting Maple IR for (size_t k = 1; k < mirFunction->GetSymTab()->GetSymbolTableSize(); ++k) { diff --git a/src/mapleall/maple_me/src/me_loop_inversion.cpp b/src/mapleall/maple_me/src/me_loop_inversion.cpp index 8da6423c2a..d3f9505fed 100644 --- a/src/mapleall/maple_me/src/me_loop_inversion.cpp +++ b/src/mapleall/maple_me/src/me_loop_inversion.cpp @@ -199,27 +199,38 @@ void MeLoopInversion::Convert(MeFunction &func, BB &bb, BB &pred, MapleMapGetKind() == kBBCondGoto) { BB *succInloop = swapSuccOfLatch ? bb.GetSucc(0) : bb.GetSucc(1); if ((latchBB->GetFrequency() != 0) && (succInloop->GetFrequency() > 0)) { - // loop is executed, bb->fallthru is in loopbody + // loop is executed int64_t latchFreq = latchBB->GetFrequency(); if (swapSuccOfLatch) { // bb fallthru is in loop, frequency of bb -> exitbb is set 0 - bb.SetSuccFreq(0, bb.GetFrequency()); - bb.SetSuccFreq(1, 0); // latchBB fallthru is loop exit - ASSERT(bb.GetSucc(0)->GetFrequency() >= bb.GetFrequency(), "sanity check"); int fallthrudiff = bb.GetSucc(0)->GetFrequency() - bb.GetFrequency(); - ASSERT(fallthrudiff >= 0, "sanity check"); - latchBB->PushBackSuccFreq(latchFreq - fallthrudiff); - latchBB->PushBackSuccFreq(fallthrudiff); + if (fallthrudiff >= 0) { + bb.SetSuccFreq(0, bb.GetFrequency()); + bb.SetSuccFreq(1, 0); + latchBB->PushBackSuccFreq(latchFreq - fallthrudiff); + latchBB->PushBackSuccFreq(fallthrudiff); + } else { // assume loop body executed only once + bb.SetSuccFreq(0, bb.GetSucc(0)->GetFrequency()); + bb.SetSuccFreq(1, bb.GetFrequency() - bb.GetSucc(0)->GetFrequency()); + latchBB->PushBackSuccFreq(latchBB->GetFrequency()); + latchBB->PushBackSuccFreq(0); + } } else { // bb->fallthru is loop exit, edge frequency of bb ->exitbb is set 0 - bb.SetSuccFreq(0, 0); - bb.SetSuccFreq(1, bb.GetFrequency()); // latchBB fallthru is in loop int fallthrudiff = bb.GetSucc(1)->GetFrequency() - bb.GetFrequency(); - ASSERT(fallthrudiff >= 0, "sanity check"); - latchBB->PushBackSuccFreq(fallthrudiff); - latchBB->PushBackSuccFreq(latchFreq - fallthrudiff); + if (fallthrudiff >= 0) { + bb.SetSuccFreq(1, bb.GetFrequency()); + bb.SetSuccFreq(0, 0); + latchBB->PushBackSuccFreq(latchFreq - fallthrudiff); + latchBB->PushBackSuccFreq(fallthrudiff); + } else { + bb.SetSuccFreq(1, bb.GetSucc(0)->GetFrequency()); + bb.SetSuccFreq(0, bb.GetFrequency() - bb.GetSucc(0)->GetFrequency()); + latchBB->PushBackSuccFreq(0); + latchBB->PushBackSuccFreq(latchBB->GetFrequency()); + } } } else { // loop is not executed diff --git a/src/mapleall/maple_me/src/pme_emit.cpp b/src/mapleall/maple_me/src/pme_emit.cpp index c3e80bb0fe..eed1401611 100644 --- a/src/mapleall/maple_me/src/pme_emit.cpp +++ b/src/mapleall/maple_me/src/pme_emit.cpp @@ -1097,7 +1097,7 @@ bool MEPreMeEmission::PhaseRun(MeFunction &f) { mirfunction->SetBody(curblk); // restore bb frequency to stmt if (Options::profileUse && emitter->GetFuncProfData()) { - emitter->GetFuncProfData()->SetStmtFreq(curblk->GetStmtID(), emitter->GetFuncProfData()->entry_freq); + emitter->GetFuncProfData()->SetStmtFreq(curblk->GetStmtID(), emitter->GetFuncProfData()->entryFreq); } uint32 i = 0; while (i < f.GetCfg()->GetAllBBs().size()) { diff --git a/src/mapleall/maple_util/include/mpl_profdata.h b/src/mapleall/maple_util/include/mpl_profdata.h index 6f9f1b3a1d..23cf6f99b9 100644 --- a/src/mapleall/maple_util/include/mpl_profdata.h +++ b/src/mapleall/maple_util/include/mpl_profdata.h @@ -15,13 +15,12 @@ #ifndef MAPLE_UTIL_INCLUDE_MPL_PROFDATA_H #define MAPLE_UTIL_INCLUDE_MPL_PROFDATA_H -#include #include - +#include #include "mempool_allocator.h" namespace maple { -#define HOTCALLSITEFREQ 100 +constexpr uint32_t HOTCALLSITEFREQ = 100; enum UpdateFreqOp { kKeepOrigFreq = 0, kUpdateOrigFreq = 0x1, @@ -44,7 +43,7 @@ struct ProfileSummaryHistogram { class ProfileSummary { public: - ProfileSummary(MapleAllocator *alloc) : histogram(alloc->Adapter()) {} + explicit ProfileSummary(MapleAllocator *alloc) : histogram(alloc->Adapter()) {} ProfileSummary(MapleAllocator *alloc, uint64_t checksum, uint32_t runtimes, uint32_t totalcount, uint64_t maxcount, uint64_t sumcount) : checkSum(checksum), @@ -99,26 +98,26 @@ class ProfileSummary { class FuncProfInfo { public: - FuncProfInfo(MapleAllocator *alloc, unsigned funcIdent, unsigned lineno_cs, unsigned cfg_cs, unsigned countnum = 0) + FuncProfInfo(MapleAllocator *alloc, unsigned funcIdent, unsigned linenoCs, unsigned cfgCs, unsigned countnum = 0) : ident(funcIdent), - linenoChecksum(lineno_cs), - cfgChecksum(cfg_cs), + linenoChecksum(linenoCs), + cfgChecksum(cfgCs), edgeCounts(countnum), counts(alloc->Adapter()){}; ~FuncProfInfo() = default; uint64_t GetFuncFrequency() const { - return entry_freq; + return entryFreq; } void SetFuncFrequency(uint64_t freq) { - entry_freq = freq; + entryFreq = freq; } uint64_t GetFuncRealFrequency() const { - return real_entryfreq; + return realEntryfreq; } void SetFuncRealFrequency(uint64_t freq) { - real_entryfreq = freq; + realEntryfreq = freq; } std::unordered_map &GetStmtFreqs() { @@ -160,9 +159,9 @@ class FuncProfInfo { // Raw arc coverage counts. unsigned edgeCounts; MapleVector counts; - uint64_t entry_freq; // record entry bb frequence + uint64_t entryFreq; // record entry bb frequence std::unordered_map stmtFreqs; // stmt_id is key, counter value - uint64_t real_entryfreq; // function prof data may be modified after clone/inline + uint64_t realEntryfreq; // function prof data may be modified after clone/inline }; class MplProfileData { @@ -175,8 +174,8 @@ class MplProfileData { } return nullptr; } - FuncProfInfo *AddNewFuncProfile(unsigned puidx, unsigned lino_cs, unsigned cfg_cs, unsigned countnum) { - FuncProfInfo *funcProf = mp->New(alloc, puidx, lino_cs, cfg_cs, countnum); + FuncProfInfo *AddNewFuncProfile(unsigned puidx, unsigned linoCs, unsigned cfgCs, unsigned countnum) { + FuncProfInfo *funcProf = mp->New(alloc, puidx, linoCs, cfgCs, countnum); ASSERT(funcsCounter.count(puidx) == 0, "sanity check"); funcsCounter[puidx] = funcProf; return funcProf; diff --git a/src/mapleall/maple_util/include/namemangler.h b/src/mapleall/maple_util/include/namemangler.h index c1b21573fe..c3333b16cf 100644 --- a/src/mapleall/maple_util/include/namemangler.h +++ b/src/mapleall/maple_util/include/namemangler.h @@ -213,8 +213,8 @@ uint32_t GetUnsignedLeb128Decode(const uint8_t **data); size_t GetUleb128Size(uint64_t val); size_t GetSleb128Size(int32_t val); bool NeedConvertUTF16(const std::string &str8); -uint32_t EncodeSLEB128(int64_t Value, std::ofstream &out); -uint32_t EncodeULEB128(uint64_t Value, std::ofstream &out); +uint32_t EncodeSLEB128(int64_t value, std::ofstream &out); +uint32_t EncodeULEB128(uint64_t value, std::ofstream &out); uint64_t DecodeULEB128(const uint8_t *p, unsigned *n = nullptr, const uint8_t *end = nullptr); int64_t DecodeSLEB128(const uint8_t *p, unsigned *n = nullptr, const uint8_t *end = nullptr); } // namespace namemangler diff --git a/src/mapleall/maple_util/src/mpl_profdata.cpp b/src/mapleall/maple_util/src/mpl_profdata.cpp index 16ef9da267..849b262239 100644 --- a/src/mapleall/maple_util/src/mpl_profdata.cpp +++ b/src/mapleall/maple_util/src/mpl_profdata.cpp @@ -36,7 +36,7 @@ void FuncProfInfo::DumpFunctionProfile() { LogInfo::MapleLogger() << " lino_checksum 0x" << std::hex << linenoChecksum << ", "; LogInfo::MapleLogger() << " cfg_checksum 0x" << std::hex << cfgChecksum << "\n"; LogInfo::MapleLogger() << " num_counts " << std::dec << edgeCounts << " : "; - for (int i = 0; i < edgeCounts; i++) { + for (unsigned i = 0; i < edgeCounts; i++) { LogInfo::MapleLogger() << std::dec << " " << counts[i]; } LogInfo::MapleLogger() << "\n"; diff --git a/src/mapleall/maple_util/src/namemangler.cpp b/src/mapleall/maple_util/src/namemangler.cpp index 151a97f371..cf84882c83 100644 --- a/src/mapleall/maple_util/src/namemangler.cpp +++ b/src/mapleall/maple_util/src/namemangler.cpp @@ -585,7 +585,7 @@ size_t GetSleb128Size(int32_t v) { int end = ((v >= 0) ? 0 : -1); while (hasMore) { - // judege whether has More valid rem + // judege whether has more valid rem hasMore = (rem != end) || ((static_cast(rem) & 1) != (static_cast((static_cast(v) >> 6)) & 1)); size++; @@ -596,93 +596,100 @@ size_t GetSleb128Size(int32_t v) { } // encode signed to output stream -uint32_t EncodeSLEB128(int64_t Value, std::ofstream &out) { - bool More; - uint32_t Count = 0; +uint32_t EncodeSLEB128(int64_t value, std::ofstream &out) { + bool more; + uint32_t count = 0; do { - uint8_t Byte = Value & 0x7f; + uint8_t byte = value & 0x7f; // NOTE: this assumes that this signed shift is an arithmetic right shift. - Value >>= 7; - More = !((((Value == 0 ) && ((Byte & 0x40) == 0)) || - ((Value == -1) && ((Byte & 0x40) != 0)))); - Count++; - if (More) { - Byte |= 0x80; // Mark this byte to show that more bytes will follow. + value >>= kGreybackOffset; + more = !((((value == 0) && ((byte & 0x40) == 0)) || + ((value == -1) && ((byte & 0x40) != 0)))); + count++; + if (more) { + byte |= 0x80; // Mark this byte to show that more bytes will follow. } - out << (char)(Byte); - } while (More); - return Count; + out << static_cast(byte); + } while (more); + return count; } -uint32_t EncodeULEB128(uint64_t Value, std::ofstream &out) { - uint32_t Count = 0; +uint32_t EncodeULEB128(uint64_t value, std::ofstream &out) { + uint32_t count = 0; do { - uint8_t Byte = Value & 0x7f; - Value >>= 7; - Count++; - if (Value != 0) { - Byte |= 0x80; // Mark this byte to show that more bytes will follow. + uint8_t byte = value & 0x7f; + value >>= kGreybackOffset; + count++; + if (value != 0) { + byte |= 0x80; // Mark this byte to show that more bytes will follow. } - out << char(Byte); - } while (Value != 0); - return Count; + out << char(byte); + } while (value != 0); + return count; } // decode a ULEB128 value. uint64_t DecodeULEB128(const uint8_t *p, unsigned *n, const uint8_t *end) { const uint8_t *orig_p = p; - uint64_t Value = 0; - unsigned Shift = 0; + uint64_t value = 0; + unsigned shift = 0; do { if (p == end) { - if (n) - *n = (unsigned)(p - orig_p); + if (n) { + *n = static_cast(p - orig_p); + } return 0; } - uint64_t Slice = *p & 0x7f; - if ((Shift >= 64 && Slice != 0) || Slice << Shift >> Shift != Slice) { - if (n) - *n = (unsigned)(p - orig_p); + uint64_t slice = *p & 0x7f; + if ((shift >= 64 && slice != 0) || ((slice << shift) >> shift) != slice) { + if (n) { + *n = static_cast(p - orig_p); + } return 0; } - Value += Slice << Shift; - Shift += 7; + value += slice << shift; + shift += kGreybackOffset; } while (*p++ >= 128); - if (n) - *n = (unsigned)(p - orig_p); - return Value; + if (n) { + *n = static_cast(p - orig_p); + } + return value; } -//decode a SLEB128 value. +// decode a SLEB128 value. int64_t DecodeSLEB128(const uint8_t *p, unsigned *n, const uint8_t *end) { const uint8_t *orig_p = p; - int64_t Value = 0; - unsigned Shift = 0; - uint8_t Byte; + int64_t value = 0; + unsigned shift = 0; + uint8_t byte; do { if (p == end) { - if (n) - *n = (unsigned)(p - orig_p); + if (n) { + *n = static_cast(p - orig_p); + } return 0; } - Byte = *p; - uint64_t Slice = Byte & 0x7f; - if ((Shift >= 64 && Slice != (Value < 0 ? 0x7f : 0x00)) || - (Shift == 63 && Slice != 0 && Slice != 0x7f)) { - if (n) - *n = (unsigned)(p - orig_p); + byte = *p; + uint64_t slice = byte & 0x7f; + if ((shift >= 64 && slice != (value < 0 ? 0x7f : 0x00)) || + (shift == 63 && slice != 0 && slice != 0x7f)) { + if (n) { + *n = static_cast(p - orig_p); + } return 0; } - Value |= Slice << Shift; - Shift += 7; + value |= slice << shift; + shift += kGreybackOffset; ++p; - } while (Byte >= 128); + } while (byte >= 128); // Sign extend negative numbers if needed. - if (Shift < 64 && (Byte & 0x40)) - Value |= (-1ULL) << Shift; - if (n) - *n = (unsigned)(p - orig_p); - return Value; + if (shift < 64 && (byte & 0x40)) { + value |= (-1LL) << shift; + } + if (n) { + *n = static_cast(p - orig_p); + } + return value; } } // namespace namemangler diff --git a/src/mapleall/mpl2mpl/include/mpl_profdata_parser.h b/src/mapleall/mpl2mpl/include/mpl_profdata_parser.h index 95513fd835..24470c0e66 100644 --- a/src/mapleall/mpl2mpl/include/mpl_profdata_parser.h +++ b/src/mapleall/mpl2mpl/include/mpl_profdata_parser.h @@ -22,7 +22,7 @@ #include "mpl_profdata.h" namespace maple { -//maple profile data format +// maple profile data format // Summary layout // MagicNumber // chesum @@ -81,7 +81,7 @@ private: class FunctionProfileImport : public ProfDataBinaryImportBase { public: FunctionProfileImport(std::string& inputFile, std::ifstream &input) : - ProfDataBinaryImportBase(inputFile, input) {} + ProfDataBinaryImportBase(inputFile, input) {} int ReadFuncProfile(MplProfileData *profData); }; @@ -91,8 +91,7 @@ class MplProfDataParser : public AnalysisResult { MplProfDataParser(MIRModule &mirmod, MemPool *mp, bool debug) : AnalysisResult(mp), m(mirmod), alloc(memPool), mempool(mp), dumpDetail(debug) { } - virtual ~MplProfDataParser() { - } + ~MplProfDataParser() = default; MplProfileData *GetProfData() { return profData; } int ReadMapleProfileData(); private: diff --git a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp index 4d686e42ee..dd0e747899 100644 --- a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp +++ b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp @@ -15,12 +15,12 @@ #include "mpl_profdata_parser.h" -#include +#include #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include @@ -33,11 +33,11 @@ namespace maple { template T ProfDataBinaryImportBase::ReadNum() { - unsigned NumBytesRead = 0; - uint64_t Val = namemangler::DecodeULEB128(pos, &NumBytesRead); + unsigned numBytesRead = 0; + uint64_t val = namemangler::DecodeULEB128(pos, &numBytesRead); - pos += NumBytesRead; - return static_cast(Val); + pos += numBytesRead; + return static_cast(val); } int ProfileSummaryImport::ReadSummary(MplProfileData *profData) { @@ -55,7 +55,7 @@ int ProfileSummaryImport::ReadSummary(MplProfileData *profData) { profData->summary.SetSummary(checksum, runtimes, numofCounts, maxCount, sumCount); uint32_t veclen = ReadNum(); - for (int i = 0; i < veclen; i++) { + for (uint32_t i = 0; i < veclen; i++) { uint32_t r1 = ReadNum(); uint32_t r2 = ReadNum(); uint64_t r3 = ReadNum(); @@ -69,9 +69,11 @@ int ProfileSummaryImport::ReadSummary(MplProfileData *profData) { int FunctionProfileImport::ReadFuncProfile(MplProfileData *profData) { CHECK_FATAL(profData != nullptr, "sanity check"); uint32_t funcNums = ReadNum(); - if (funcNums == 0) return 1; + if (funcNums == 0) { + return 1; + } - for (int i = 0; i < funcNums; i++) { + for (uint32_t i = 0; i < funcNums; i++) { uint32_t funcIdent = ReadNum(); uint32_t linocheckSum = ReadNum(); uint32_t cfgcheckSum = ReadNum(); @@ -79,7 +81,7 @@ int FunctionProfileImport::ReadFuncProfile(MplProfileData *profData) { FuncProfInfo *funcProf = profData->AddNewFuncProfile(funcIdent, linocheckSum, cfgcheckSum, countNum); CHECK_FATAL(funcProf != nullptr, "nullptr check"); funcProf->counts.resize(countNum); - for (int j = 0; j < countNum; j++) { + for (uint32_t j = 0; j < countNum; j++) { funcProf->counts[j] = ReadNum(); } } @@ -111,7 +113,10 @@ int MplProfDataParser::ReadMapleProfileData() { } // reduce path in profDataFileName while (stripnum > 0 && profDataFileName.size() > 1) { - auto pos = profDataFileName.find_first_of("/", 1); + size_t pos = profDataFileName.find_first_of("/", 1); + if (pos == std::string::npos) { + break; + } profDataFileName = profDataFileName.substr(pos); stripnum--; } @@ -143,18 +148,18 @@ int MplProfDataParser::ReadMapleProfileData() { return 1; } // get length of file - inputStream.seekg(0, inputStream.end); - int length = inputStream.tellg(); - inputStream.seekg(0, inputStream.beg); + inputStream.seekg(0, std::ios::end); + uint32_t length = inputStream.tellg(); + inputStream.seekg(0, std::ios::beg); const uint32_t sizeThreshold = 1024 * 10; CHECK_FATAL(length <= sizeThreshold, "NYI::large .mprofdata file size is larger than threashold, do chunk memory\n"); - std::unique_ptr buffer(new char[sizeof(char) * length]()); + std::unique_ptr buffer = std::make_unique(length); inputStream.read(buffer.get(), length); inputStream.close(); // read 1st part summary ProfileSummaryImport summaryImport(mprofDataFile, inputStream); - summaryImport.SetPosition((uint8_t*)buffer.get()); + summaryImport.SetPosition((uint8_t*)(buffer.get())); int res = summaryImport.ReadSummary(profData); if (res) { LogInfo::MapleLogger() << "no summary part\n"; @@ -183,7 +188,7 @@ void MMplProfDataParser::GetAnalysisDependence(AnalysisDep &aDep) const { bool MMplProfDataParser::PhaseRun(maple::MIRModule &m) { MemPool *memPool = m.GetMemPool(); // use global pool to store profile data - bool enableDebug = false; // true to dump trace + bool enableDebug = true; // true to dump trace MplProfDataParser parser(m, memPool, enableDebug); int res = parser.ReadMapleProfileData(); if (res) { -- Gitee From fe55016ae9d4489207add3465bed8eafc3aa0ba6 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Sun, 31 Jul 2022 08:57:42 -0700 Subject: [PATCH 16/16] Formating adjustments from the formating tool --- .../mpl2mpl/include/mpl_profdata_parser.h | 60 +++++++++++-------- .../mpl2mpl/src/mpl_profdata_parser.cpp | 6 +- 2 files changed, 37 insertions(+), 29 deletions(-) diff --git a/src/mapleall/mpl2mpl/include/mpl_profdata_parser.h b/src/mapleall/mpl2mpl/include/mpl_profdata_parser.h index 24470c0e66..1a83fa5c83 100644 --- a/src/mapleall/mpl2mpl/include/mpl_profdata_parser.h +++ b/src/mapleall/mpl2mpl/include/mpl_profdata_parser.h @@ -15,10 +15,10 @@ #ifndef MAPLE_MPL2MPL_INCLUDE_GCOVPROFUSE_H #define MAPLE_MPL2MPL_INCLUDE_GCOVPROFUSE_H -#include "mempool.h" -#include "mempool_allocator.h" #include "bb.h" #include "maple_phase_manager.h" +#include "mempool.h" +#include "mempool_allocator.h" #include "mpl_profdata.h" namespace maple { @@ -55,47 +55,55 @@ namespace maple { const uint32_t kMapleProfDataMagicNumber = 0xA0EFEF; class ProfDataBinaryImportBase { -public: - ProfDataBinaryImportBase(std::string &filename, std::ifstream &input) : fileName(filename), - inputStream(input) {} - template T ReadNum(); - std::ifstream& GetInputStream() { return inputStream; } - std::string& GetProfDataFileName() { return fileName; } - void SetPosition(uint8_t *p) { pos = p; } - uint8_t *GetPosition() { return pos; } -private: + public: + ProfDataBinaryImportBase(std::string &filename, std::ifstream &input) : fileName(filename), inputStream(input) {} + template + T ReadNum(); + std::ifstream &GetInputStream() { + return inputStream; + } + std::string &GetProfDataFileName() { + return fileName; + } + void SetPosition(uint8_t *p) { + pos = p; + } + uint8_t *GetPosition() { + return pos; + } + + private: std::string &fileName; std::ifstream &inputStream; uint8_t *pos = nullptr; }; class ProfileSummaryImport : public ProfDataBinaryImportBase { -public: - ProfileSummaryImport(std::string& outputFile, std::ifstream &input): - ProfDataBinaryImportBase(outputFile, input) {} - int ReadSummary(MplProfileData *); -private: + public: + ProfileSummaryImport(std::string &outputFile, std::ifstream &input) : ProfDataBinaryImportBase(outputFile, input) {} + int ReadSummary(MplProfileData*); + + private: void ReadMProfMagic(); }; class FunctionProfileImport : public ProfDataBinaryImportBase { -public: - FunctionProfileImport(std::string& inputFile, std::ifstream &input) : - ProfDataBinaryImportBase(inputFile, input) {} + public: + FunctionProfileImport(std::string &inputFile, std::ifstream &input) : ProfDataBinaryImportBase(inputFile, input) {} int ReadFuncProfile(MplProfileData *profData); }; - class MplProfDataParser : public AnalysisResult { public: - MplProfDataParser(MIRModule &mirmod, MemPool *mp, bool debug) : AnalysisResult(mp), - m(mirmod), alloc(memPool), mempool(mp), dumpDetail(debug) { - } + MplProfDataParser(MIRModule &mirmod, MemPool *mp, bool debug) + : AnalysisResult(mp), m(mirmod), alloc(memPool), mempool(mp), dumpDetail(debug) {} ~MplProfDataParser() = default; - MplProfileData *GetProfData() { return profData; } + MplProfileData *GetProfData() { + return profData; + } int ReadMapleProfileData(); - private: + private: MIRModule &m; MapleAllocator alloc; MemPool *mempool; @@ -105,6 +113,6 @@ class MplProfDataParser : public AnalysisResult { MAPLE_MODULE_PHASE_DECLARE(MMplProfDataParser) -} // end of namespace maple +} // end of namespace maple #endif // MAPLE_MPL2MPL_INCLUDE_GCOVPROFUSE_H diff --git a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp index dd0e747899..95bd0febdd 100644 --- a/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp +++ b/src/mapleall/mpl2mpl/src/mpl_profdata_parser.cpp @@ -15,13 +15,13 @@ #include "mpl_profdata_parser.h" -#include #include + +#include #include #include #include #include - #include #include #include @@ -188,7 +188,7 @@ void MMplProfDataParser::GetAnalysisDependence(AnalysisDep &aDep) const { bool MMplProfDataParser::PhaseRun(maple::MIRModule &m) { MemPool *memPool = m.GetMemPool(); // use global pool to store profile data - bool enableDebug = true; // true to dump trace + bool enableDebug = true; // true to dump trace MplProfDataParser parser(m, memPool, enableDebug); int res = parser.ReadMapleProfileData(); if (res) { -- Gitee