From fd36bd2c669287e3230a2953aeef8439ac008604 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Thu, 6 May 2021 00:12:04 -0700 Subject: [PATCH 1/3] Merged in flow-senstive alias analysis from incubator It is off by default; use --performFSAA to turn it on --- src/mapleall/maple_ir/include/mir_nodes.h | 1 + src/mapleall/maple_me/BUILD.gn | 1 + src/mapleall/maple_me/include/bb.h | 2 + src/mapleall/maple_me/include/me_fsaa.h | 57 ++++++ src/mapleall/maple_me/include/me_option.h | 1 + src/mapleall/maple_me/include/me_phases.def | 1 + src/mapleall/maple_me/include/ssa.h | 2 + src/mapleall/maple_me/include/ver_symbol.h | 2 +- src/mapleall/maple_me/src/me_dse.cpp | 13 +- src/mapleall/maple_me/src/me_fsaa.cpp | 176 ++++++++++++++++++ src/mapleall/maple_me/src/me_option.cpp | 16 +- .../maple_me/src/me_phase_manager.cpp | 1 + src/mapleall/maple_me/src/ssa.cpp | 8 +- 13 files changed, 276 insertions(+), 5 deletions(-) create mode 100644 src/mapleall/maple_me/include/me_fsaa.h create mode 100644 src/mapleall/maple_me/src/me_fsaa.cpp diff --git a/src/mapleall/maple_ir/include/mir_nodes.h b/src/mapleall/maple_ir/include/mir_nodes.h index 8079152627..b26f0254c6 100644 --- a/src/mapleall/maple_ir/include/mir_nodes.h +++ b/src/mapleall/maple_ir/include/mir_nodes.h @@ -1527,6 +1527,7 @@ class IassignNode : public StmtNode { private: TyIdx tyIdx; FieldID fieldID; + public: BaseNode *addrExpr; BaseNode *rhs; }; diff --git a/src/mapleall/maple_me/BUILD.gn b/src/mapleall/maple_me/BUILD.gn index 05f80eedf4..b6299f9976 100755 --- a/src/mapleall/maple_me/BUILD.gn +++ b/src/mapleall/maple_me/BUILD.gn @@ -88,6 +88,7 @@ src_libmplme = [ "src/me_subsum_rc.cpp", "src/me_func_opt.cpp", "src/me_verify.cpp", + "src/me_fsaa.cpp", ] src_libmplmewpo = [ diff --git a/src/mapleall/maple_me/include/bb.h b/src/mapleall/maple_me/include/bb.h index f4a496e983..6f787eff82 100644 --- a/src/mapleall/maple_me/include/bb.h +++ b/src/mapleall/maple_me/include/bb.h @@ -470,7 +470,9 @@ class BB { uint32 frequency = 0; BBKind kind = kBBUnknown; uint32 attributes = 0; + public: StmtNodes stmtNodeList; + private: MeStmts meStmtList; BB *group; }; diff --git a/src/mapleall/maple_me/include/me_fsaa.h b/src/mapleall/maple_me/include/me_fsaa.h new file mode 100644 index 0000000000..86334575e5 --- /dev/null +++ b/src/mapleall/maple_me/include/me_fsaa.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#ifndef MAPLE_ME_INCLUDE_ME_FSAA_H +#define MAPLE_ME_INCLUDE_ME_FSAA_H +#include "me_phase.h" +#include "me_option.h" +#include "me_function.h" +#include "dominance.h" +#include "ssa_tab.h" + +namespace maple { + +class FSAA { + public: + explicit FSAA(MeFunction *f, Dominance *dm): func(f), mirModule(&f->GetMIRModule()), ssaTab(f->GetMeSSATab()), dom(dm) {} + ~FSAA() {} + + BB *FindUniquePointerValueDefBB(VersionSt *vst); + void ProcessBB(BB *bb); + + bool needUpdateSSA = false; + private: + MeFunction *func; + MIRModule *mirModule; + SSATab *ssaTab; + Dominance *dom; + + std::string PhaseName() const { + return "fsaa"; + } +}; + +class MeDoFSAA : public MeFuncPhase { + public: + MeDoFSAA(MePhaseID id) : MeFuncPhase(id) {} + + ~MeDoFSAA() {} + + AnalysisResult *Run(MeFunction *ir, MeFuncResultMgr *m, ModuleResultMgr *mrm) override; + std::string PhaseName() const override { + return "fsaa"; + } +}; +} // namespace maple +#endif // MAPLE_ME_INCLUDE_ME_FSAA_H diff --git a/src/mapleall/maple_me/include/me_option.h b/src/mapleall/maple_me/include/me_option.h index a711e16cee..5d4112e588 100644 --- a/src/mapleall/maple_me/include/me_option.h +++ b/src/mapleall/maple_me/include/me_option.h @@ -121,6 +121,7 @@ class MeOption : public MapleDriverOptionBase { static bool nativeOpt; static bool placementRC; static bool subsumRC; + static bool performFSAA; static std::string inlineFuncList; static bool meVerify; #if MIR_JAVA diff --git a/src/mapleall/maple_me/include/me_phases.def b/src/mapleall/maple_me/include/me_phases.def index 53f926c404..25e6303645 100644 --- a/src/mapleall/maple_me/include/me_phases.def +++ b/src/mapleall/maple_me/include/me_phases.def @@ -60,4 +60,5 @@ FUNCTPHASE(MeFuncPhase_ANALYZERC, MeDoAnalyzeRC) FUNCAPHASE(MeFuncPhase_DELEGATERC, MeDoDelegateRC) FUNCAPHASE(MeFuncPhase_CONDBASEDRC, MeDoCondBasedRC) FUNCTPHASE(MeFuncPhase_RCLOWERING, MeDoRCLowering) +FUNCTPHASE(MeFuncPhase_FSAA, MeDoFSAA) FUNCTPHASE(MeFuncPhase_EMIT, MeDoEmit) diff --git a/src/mapleall/maple_me/include/ssa.h b/src/mapleall/maple_me/include/ssa.h index 111111fd03..9919b101f8 100644 --- a/src/mapleall/maple_me/include/ssa.h +++ b/src/mapleall/maple_me/include/ssa.h @@ -142,6 +142,8 @@ class SSA { SSATab *ssaTab; MapleVector &bbVec; Dominance *dom; + public: + bool runRenameOnly = false; }; } // namespace maple #endif // MAPLE_ME_INCLUDE_SSA_H diff --git a/src/mapleall/maple_me/include/ver_symbol.h b/src/mapleall/maple_me/include/ver_symbol.h index 2f8e1eac90..a47e7a0f12 100644 --- a/src/mapleall/maple_me/include/ver_symbol.h +++ b/src/mapleall/maple_me/include/ver_symbol.h @@ -57,7 +57,7 @@ class VersionSt { defBB = defbb; } - const BB *GetDefBB() const { + BB *GetDefBB() const { return defBB; } diff --git a/src/mapleall/maple_me/src/me_dse.cpp b/src/mapleall/maple_me/src/me_dse.cpp index cbfb9e49dd..5c7d54c5cb 100644 --- a/src/mapleall/maple_me/src/me_dse.cpp +++ b/src/mapleall/maple_me/src/me_dse.cpp @@ -18,6 +18,7 @@ #include "ver_symbol.h" #include "me_ssa.h" #include "me_cfg.h" +#include "me_fsaa.h" namespace maple { void MeDSE::VerifyPhi() const { @@ -60,7 +61,7 @@ void MeDSE::RunDSE() { } } -AnalysisResult *MeDoDSE::Run(MeFunction *func, MeFuncResultMgr *m, ModuleResultMgr*) { +AnalysisResult *MeDoDSE::Run(MeFunction *func, MeFuncResultMgr *m, ModuleResultMgr *mrm) { CHECK_NULL_FATAL(func); auto *postDom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); CHECK_NULL_FATAL(postDom); @@ -71,6 +72,16 @@ AnalysisResult *MeDoDSE::Run(MeFunction *func, MeFuncResultMgr *m, ModuleResultM if (dse.UpdatedCfg()) { m->InvalidAnalysisResult(MeFuncPhase_DOMINANCE, func); } + + if (func->GetMIRModule().IsCModule() && MeOption::performFSAA) { + /* invoke FSAA */ + MeDoFSAA doFSAA(MeFuncPhase_FSAA); + if (!MeOption::quiet) { + LogInfo::MapleLogger() << " == " << PhaseName() << " invokes [ " << doFSAA.PhaseName() << " ] ==\n"; + } + doFSAA.Run(func, m, mrm); + } + return nullptr; } } // namespace maple diff --git a/src/mapleall/maple_me/src/me_fsaa.cpp b/src/mapleall/maple_me/src/me_fsaa.cpp new file mode 100644 index 0000000000..438ac3f000 --- /dev/null +++ b/src/mapleall/maple_me/src/me_fsaa.cpp @@ -0,0 +1,176 @@ +/* + * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#include "me_fsaa.h" +#include "me_ssa.h" +#include "ssa_mir_nodes.h" +#include "me_option.h" + +// The FSAA phase performs flow-sensitive alias analysis. This is flow +// sensitive because, based on the SSA that has been constructed, it is +// possible to look up the assigned value of pointers. It focuses only on +// using known assigned pointer values to fine-tune the aliased items at +// iassign statements. When the base of an iassign statements has an assigned +// value that is unique (i.e. of known value or is pointing to read-only +// memory), it will go through the maydefs attached to the iassign statement to +// trim away any whose base cannot possibly be the same value as the base's +// assigned value. When any mayDef has bee deleted, the SSA form of the +// function will be updated by re-running only the SSA rename step, so as to +// maintain the correctness of the SSA form. + +using namespace std; + +namespace maple { + +// if the pointer represented by vst is found to have a unique pointer value, +// return the BB of the definition +BB *FSAA::FindUniquePointerValueDefBB(VersionSt *vst) { + if (vst->IsInitVersion()) { + return nullptr; + } + if (vst->GetDefType() != VersionSt::kAssign) { + return nullptr; + } + UnaryStmtNode *ass = static_cast(vst->GetAssignNode()); + BaseNode *rhs = ass->Opnd(0); + + if (rhs->GetOpCode() == OP_malloc || rhs->GetOpCode() == OP_gcmalloc || rhs->GetOpCode() == OP_gcpermalloc || + rhs->GetOpCode() == OP_gcmallocjarray || rhs->GetOpCode() == OP_alloca) { + return vst->GetDefBB(); + } else if (rhs->GetOpCode() == OP_dread) { + AddrofSSANode *dread = static_cast(rhs); + OriginalSt *ost = dread->GetSSAVar()->GetOst(); + if (ost->GetMIRSymbol()->IsLiteralPtr() || (ost->IsFinal() && !ost->IsLocal())) { + return vst->GetDefBB(); + } else { // rhs is another pointer; call recursively for its rhs + return FindUniquePointerValueDefBB(dread->GetSSAVar()); + } + return nullptr; + } else if (rhs->GetOpCode() == OP_iread) { + if (func->GetMirFunc()->IsConstructor() || func->GetMirFunc()->IsStatic() || func->GetMirFunc()->GetFormalDefVec().empty()) { + return nullptr; + } + // check if rhs is reading a final field thru this + IreadSSANode *iread = static_cast(rhs); + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread->GetTyIdx()); + MIRType *pointedty = static_cast(ty)->GetPointedType(); + if (pointedty->GetKind() == kTypeClass && + static_cast(pointedty)->IsFieldFinal(iread->GetFieldID()) && + iread->Opnd(0)->GetOpCode() == OP_dread) { + AddrofSSANode *basedread = static_cast(iread->Opnd(0)); + MIRSymbol *mirst = basedread->GetSSAVar()->GetOst()->GetMIRSymbol(); + if (mirst == func->GetMirFunc()->GetFormal(0)) { + return vst->GetDefBB(); + } + } + return nullptr; + } + return nullptr; +} + +void FSAA::ProcessBB(BB *bb) { + auto &stmtNodes = bb->GetStmtNodes(); + for (auto itStmt = stmtNodes.begin(); itStmt != stmtNodes.rbegin().base(); ++itStmt) { + if (itStmt->GetOpCode() != OP_iassign) { + continue; + } + IassignNode *iass = static_cast(&*itStmt); + VersionSt *vst = nullptr; + if (iass->addrExpr->GetOpCode() == OP_dread) { + vst = static_cast(iass->addrExpr)->GetSSAVar(); + } else if (iass->addrExpr->GetOpCode() == OP_regread) { + vst = static_cast(iass->addrExpr)->GetSSAVar(); + } else { + break; + } + BB *defBB = FindUniquePointerValueDefBB(vst); + if (defBB != nullptr) { + if (DEBUGFUNC(func)) { + LogInfo::MapleLogger() << "FSAA finds unique pointer value def\n"; + } + // delete any maydefnode in the list that is defined before defBB + TypeOfMayDefList *mayDefNodes = &ssaTab->GetStmtsSSAPart().GetMayDefNodesOf(*itStmt); + + bool hasErase; + do { + hasErase = false; + TypeOfMayDefList::iterator it = mayDefNodes->begin(); + // due to use of iterator, can do at most 1 erasion each iterator usage + for (; it != mayDefNodes->end(); it++) { + if ((*it).base == nullptr) { + } else { + BB *aliasedDefBB = (*it).base->GetDefBB(); + if (aliasedDefBB == nullptr) { + hasErase = true; + } else { + hasErase = defBB != aliasedDefBB && dom->Dominate(*aliasedDefBB, *defBB); + } + } + if (hasErase) { + if (DEBUGFUNC(func)) { + LogInfo::MapleLogger() << "FSAA deletes mayDef of "; + (*it).GetResult()->Dump(mirModule); + LogInfo::MapleLogger() << " in BB " << bb->GetBBId() << " at:" << endl; + itStmt->Dump(); + } + mayDefNodes->erase(it); + needUpdateSSA = true; + CHECK_FATAL(!mayDefNodes->empty(), "FSAA::ProcessBB: mayDefNodes of iassign rendered empty"); + break; + } + } + } while (hasErase); + } + } +} + +AnalysisResult *MeDoFSAA::Run(MeFunction *func, MeFuncResultMgr *m, ModuleResultMgr *mrm) { + SSATab *ssaTab = static_cast(m->GetAnalysisResult(MeFuncPhase_SSATAB, func)); + ASSERT(ssaTab != nullptr, "ssaTab phase has problem"); + + MeSSA *ssa = static_cast(m->GetAnalysisResult(MeFuncPhase_SSA, func)); + ASSERT(ssa != nullptr, "ssa phase has problem"); + + Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); + ASSERT(dom != nullptr, "dominance phase has problem"); + + FSAA fsaa(func, dom); + + for (BB *bb : func->GetAllBBs()) { + if (bb != nullptr) { + fsaa.ProcessBB(bb); + } + } + + if (fsaa.needUpdateSSA) { + ssa->runRenameOnly = true; + + ssa->InitRenameStack(ssaTab->GetOriginalStTable(), func->GetAllBBs().size(), ssaTab->GetVersionStTable()); + // recurse down dominator tree in pre-order traversal + MapleSet *children = &dom->domChildren[func->GetCommonEntryBB()->GetBBId()]; + for (BBId child : *children) { + ssa->RenameBB(*func->GetBBFromID(child)); + } + + ssa->VerifySSA(); + + if (DEBUGFUNC(func)) { + func->DumpFunction(); + } + } + + return nullptr; +} + +} // namespace maple diff --git a/src/mapleall/maple_me/src/me_option.cpp b/src/mapleall/maple_me/src/me_option.cpp index d96728e7a7..ce9c78a714 100644 --- a/src/mapleall/maple_me/src/me_option.cpp +++ b/src/mapleall/maple_me/src/me_option.cpp @@ -95,6 +95,7 @@ bool MeOption::nativeOpt = true; bool MeOption::enableEA = false; bool MeOption::placementRC = false; bool MeOption::subsumRC = false; +bool MeOption::performFSAA = false; std::string MeOption::inlineFuncList = ""; bool MeOption::meVerify = false; #if MIR_JAVA @@ -181,7 +182,7 @@ enum OptionIndex { kDassignPre, kAssign2finalPre, kSubsumRC, - kNoSubsumRC, + kPerformFSAA, kRegReadAtReturn, kProPatphi, kNoProPatphi, @@ -749,6 +750,16 @@ const Descriptor kUsage[] = { " --no-subsumrc \tDisable subsumrc\n", "me", {} }, + { kPerformFSAA, + kEnable, + "", + "performFSAA", + kBuildTypeExperimental, + kArgCheckPolicyBool, + " --performFSAA \tPerform flow sensitive alias analysis\n" + " --no-performFSAA \tDisable flow sensitive alias analysis\n", + "me", + {} }, { kCheckCastOpt, kEnable, "", @@ -1327,6 +1338,9 @@ bool MeOption::SolveOptions(const std::vector &opts, bool i subsumRC = (opt.Type() == kEnable); epreIncludeRef = (opt.Type() == kEnable); break; + case kPerformFSAA: + performFSAA = (opt.Type() == kEnable); + break; case kMeInlineHint: inlineFuncList = opt.Args(); break; diff --git a/src/mapleall/maple_me/src/me_phase_manager.cpp b/src/mapleall/maple_me/src/me_phase_manager.cpp index 6e1562fe13..c784cd686f 100644 --- a/src/mapleall/maple_me/src/me_phase_manager.cpp +++ b/src/mapleall/maple_me/src/me_phase_manager.cpp @@ -61,6 +61,7 @@ #include "me_emit.h" #include "me_rc_lowering.h" #include "gen_check_cast.h" +#include "me_fsaa.h" #if MIR_JAVA #include "sync_select.h" #endif // MIR_JAVA diff --git a/src/mapleall/maple_me/src/ssa.cpp b/src/mapleall/maple_me/src/ssa.cpp index 8d3410aae0..c3c59f583a 100644 --- a/src/mapleall/maple_me/src/ssa.cpp +++ b/src/mapleall/maple_me/src/ssa.cpp @@ -43,8 +43,12 @@ VersionSt *SSA::CreateNewVersion(VersionSt &vSym, BB &defBB) { return &vSym; } ASSERT(vSym.GetVersion() == kInitVersion, "renamed before"); - VersionSt *newVersionSym = - ssaTab->GetVersionStTable().CreateNextVersionSt(vSym.GetOst()); + VersionSt *newVersionSym = nullptr; + if (!runRenameOnly) { + newVersionSym = ssaTab->GetVersionStTable().CreateNextVersionSt(vSym.GetOst()); + } else { + newVersionSym = &vSym; + } vstStacks[vSym.GetOrigIdx()]->push(newVersionSym); newVersionSym->SetDefBB(&defBB); return newVersionSym; -- Gitee From 6352563b93104b0e1ec5af11b9813912387bf24f Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Thu, 6 May 2021 00:12:04 -0700 Subject: [PATCH 2/3] Merged in flow-senstive alias analysis from incubator It is off by default; use --performFSAA to turn it on --- src/mapleall/maple_ir/include/mir_nodes.h | 1 + src/mapleall/maple_me/BUILD.gn | 1 + src/mapleall/maple_me/include/bb.h | 2 + src/mapleall/maple_me/include/me_fsaa.h | 57 ++++++ src/mapleall/maple_me/include/me_option.h | 1 + src/mapleall/maple_me/include/me_phases.def | 1 + src/mapleall/maple_me/include/ssa.h | 2 + src/mapleall/maple_me/include/ver_symbol.h | 2 +- src/mapleall/maple_me/src/me_dse.cpp | 13 +- src/mapleall/maple_me/src/me_fsaa.cpp | 176 ++++++++++++++++++ src/mapleall/maple_me/src/me_option.cpp | 16 +- .../maple_me/src/me_phase_manager.cpp | 1 + src/mapleall/maple_me/src/ssa.cpp | 8 +- 13 files changed, 276 insertions(+), 5 deletions(-) create mode 100644 src/mapleall/maple_me/include/me_fsaa.h create mode 100644 src/mapleall/maple_me/src/me_fsaa.cpp diff --git a/src/mapleall/maple_ir/include/mir_nodes.h b/src/mapleall/maple_ir/include/mir_nodes.h index 8079152627..b26f0254c6 100644 --- a/src/mapleall/maple_ir/include/mir_nodes.h +++ b/src/mapleall/maple_ir/include/mir_nodes.h @@ -1527,6 +1527,7 @@ class IassignNode : public StmtNode { private: TyIdx tyIdx; FieldID fieldID; + public: BaseNode *addrExpr; BaseNode *rhs; }; diff --git a/src/mapleall/maple_me/BUILD.gn b/src/mapleall/maple_me/BUILD.gn index 05f80eedf4..b6299f9976 100755 --- a/src/mapleall/maple_me/BUILD.gn +++ b/src/mapleall/maple_me/BUILD.gn @@ -88,6 +88,7 @@ src_libmplme = [ "src/me_subsum_rc.cpp", "src/me_func_opt.cpp", "src/me_verify.cpp", + "src/me_fsaa.cpp", ] src_libmplmewpo = [ diff --git a/src/mapleall/maple_me/include/bb.h b/src/mapleall/maple_me/include/bb.h index f4a496e983..6f787eff82 100644 --- a/src/mapleall/maple_me/include/bb.h +++ b/src/mapleall/maple_me/include/bb.h @@ -470,7 +470,9 @@ class BB { uint32 frequency = 0; BBKind kind = kBBUnknown; uint32 attributes = 0; + public: StmtNodes stmtNodeList; + private: MeStmts meStmtList; BB *group; }; diff --git a/src/mapleall/maple_me/include/me_fsaa.h b/src/mapleall/maple_me/include/me_fsaa.h new file mode 100644 index 0000000000..86334575e5 --- /dev/null +++ b/src/mapleall/maple_me/include/me_fsaa.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#ifndef MAPLE_ME_INCLUDE_ME_FSAA_H +#define MAPLE_ME_INCLUDE_ME_FSAA_H +#include "me_phase.h" +#include "me_option.h" +#include "me_function.h" +#include "dominance.h" +#include "ssa_tab.h" + +namespace maple { + +class FSAA { + public: + explicit FSAA(MeFunction *f, Dominance *dm): func(f), mirModule(&f->GetMIRModule()), ssaTab(f->GetMeSSATab()), dom(dm) {} + ~FSAA() {} + + BB *FindUniquePointerValueDefBB(VersionSt *vst); + void ProcessBB(BB *bb); + + bool needUpdateSSA = false; + private: + MeFunction *func; + MIRModule *mirModule; + SSATab *ssaTab; + Dominance *dom; + + std::string PhaseName() const { + return "fsaa"; + } +}; + +class MeDoFSAA : public MeFuncPhase { + public: + MeDoFSAA(MePhaseID id) : MeFuncPhase(id) {} + + ~MeDoFSAA() {} + + AnalysisResult *Run(MeFunction *ir, MeFuncResultMgr *m, ModuleResultMgr *mrm) override; + std::string PhaseName() const override { + return "fsaa"; + } +}; +} // namespace maple +#endif // MAPLE_ME_INCLUDE_ME_FSAA_H diff --git a/src/mapleall/maple_me/include/me_option.h b/src/mapleall/maple_me/include/me_option.h index a711e16cee..5d4112e588 100644 --- a/src/mapleall/maple_me/include/me_option.h +++ b/src/mapleall/maple_me/include/me_option.h @@ -121,6 +121,7 @@ class MeOption : public MapleDriverOptionBase { static bool nativeOpt; static bool placementRC; static bool subsumRC; + static bool performFSAA; static std::string inlineFuncList; static bool meVerify; #if MIR_JAVA diff --git a/src/mapleall/maple_me/include/me_phases.def b/src/mapleall/maple_me/include/me_phases.def index 53f926c404..25e6303645 100644 --- a/src/mapleall/maple_me/include/me_phases.def +++ b/src/mapleall/maple_me/include/me_phases.def @@ -60,4 +60,5 @@ FUNCTPHASE(MeFuncPhase_ANALYZERC, MeDoAnalyzeRC) FUNCAPHASE(MeFuncPhase_DELEGATERC, MeDoDelegateRC) FUNCAPHASE(MeFuncPhase_CONDBASEDRC, MeDoCondBasedRC) FUNCTPHASE(MeFuncPhase_RCLOWERING, MeDoRCLowering) +FUNCTPHASE(MeFuncPhase_FSAA, MeDoFSAA) FUNCTPHASE(MeFuncPhase_EMIT, MeDoEmit) diff --git a/src/mapleall/maple_me/include/ssa.h b/src/mapleall/maple_me/include/ssa.h index 111111fd03..9919b101f8 100644 --- a/src/mapleall/maple_me/include/ssa.h +++ b/src/mapleall/maple_me/include/ssa.h @@ -142,6 +142,8 @@ class SSA { SSATab *ssaTab; MapleVector &bbVec; Dominance *dom; + public: + bool runRenameOnly = false; }; } // namespace maple #endif // MAPLE_ME_INCLUDE_SSA_H diff --git a/src/mapleall/maple_me/include/ver_symbol.h b/src/mapleall/maple_me/include/ver_symbol.h index 2f8e1eac90..a47e7a0f12 100644 --- a/src/mapleall/maple_me/include/ver_symbol.h +++ b/src/mapleall/maple_me/include/ver_symbol.h @@ -57,7 +57,7 @@ class VersionSt { defBB = defbb; } - const BB *GetDefBB() const { + BB *GetDefBB() const { return defBB; } diff --git a/src/mapleall/maple_me/src/me_dse.cpp b/src/mapleall/maple_me/src/me_dse.cpp index cbfb9e49dd..5c7d54c5cb 100644 --- a/src/mapleall/maple_me/src/me_dse.cpp +++ b/src/mapleall/maple_me/src/me_dse.cpp @@ -18,6 +18,7 @@ #include "ver_symbol.h" #include "me_ssa.h" #include "me_cfg.h" +#include "me_fsaa.h" namespace maple { void MeDSE::VerifyPhi() const { @@ -60,7 +61,7 @@ void MeDSE::RunDSE() { } } -AnalysisResult *MeDoDSE::Run(MeFunction *func, MeFuncResultMgr *m, ModuleResultMgr*) { +AnalysisResult *MeDoDSE::Run(MeFunction *func, MeFuncResultMgr *m, ModuleResultMgr *mrm) { CHECK_NULL_FATAL(func); auto *postDom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); CHECK_NULL_FATAL(postDom); @@ -71,6 +72,16 @@ AnalysisResult *MeDoDSE::Run(MeFunction *func, MeFuncResultMgr *m, ModuleResultM if (dse.UpdatedCfg()) { m->InvalidAnalysisResult(MeFuncPhase_DOMINANCE, func); } + + if (func->GetMIRModule().IsCModule() && MeOption::performFSAA) { + /* invoke FSAA */ + MeDoFSAA doFSAA(MeFuncPhase_FSAA); + if (!MeOption::quiet) { + LogInfo::MapleLogger() << " == " << PhaseName() << " invokes [ " << doFSAA.PhaseName() << " ] ==\n"; + } + doFSAA.Run(func, m, mrm); + } + return nullptr; } } // namespace maple diff --git a/src/mapleall/maple_me/src/me_fsaa.cpp b/src/mapleall/maple_me/src/me_fsaa.cpp new file mode 100644 index 0000000000..438ac3f000 --- /dev/null +++ b/src/mapleall/maple_me/src/me_fsaa.cpp @@ -0,0 +1,176 @@ +/* + * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#include "me_fsaa.h" +#include "me_ssa.h" +#include "ssa_mir_nodes.h" +#include "me_option.h" + +// The FSAA phase performs flow-sensitive alias analysis. This is flow +// sensitive because, based on the SSA that has been constructed, it is +// possible to look up the assigned value of pointers. It focuses only on +// using known assigned pointer values to fine-tune the aliased items at +// iassign statements. When the base of an iassign statements has an assigned +// value that is unique (i.e. of known value or is pointing to read-only +// memory), it will go through the maydefs attached to the iassign statement to +// trim away any whose base cannot possibly be the same value as the base's +// assigned value. When any mayDef has bee deleted, the SSA form of the +// function will be updated by re-running only the SSA rename step, so as to +// maintain the correctness of the SSA form. + +using namespace std; + +namespace maple { + +// if the pointer represented by vst is found to have a unique pointer value, +// return the BB of the definition +BB *FSAA::FindUniquePointerValueDefBB(VersionSt *vst) { + if (vst->IsInitVersion()) { + return nullptr; + } + if (vst->GetDefType() != VersionSt::kAssign) { + return nullptr; + } + UnaryStmtNode *ass = static_cast(vst->GetAssignNode()); + BaseNode *rhs = ass->Opnd(0); + + if (rhs->GetOpCode() == OP_malloc || rhs->GetOpCode() == OP_gcmalloc || rhs->GetOpCode() == OP_gcpermalloc || + rhs->GetOpCode() == OP_gcmallocjarray || rhs->GetOpCode() == OP_alloca) { + return vst->GetDefBB(); + } else if (rhs->GetOpCode() == OP_dread) { + AddrofSSANode *dread = static_cast(rhs); + OriginalSt *ost = dread->GetSSAVar()->GetOst(); + if (ost->GetMIRSymbol()->IsLiteralPtr() || (ost->IsFinal() && !ost->IsLocal())) { + return vst->GetDefBB(); + } else { // rhs is another pointer; call recursively for its rhs + return FindUniquePointerValueDefBB(dread->GetSSAVar()); + } + return nullptr; + } else if (rhs->GetOpCode() == OP_iread) { + if (func->GetMirFunc()->IsConstructor() || func->GetMirFunc()->IsStatic() || func->GetMirFunc()->GetFormalDefVec().empty()) { + return nullptr; + } + // check if rhs is reading a final field thru this + IreadSSANode *iread = static_cast(rhs); + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread->GetTyIdx()); + MIRType *pointedty = static_cast(ty)->GetPointedType(); + if (pointedty->GetKind() == kTypeClass && + static_cast(pointedty)->IsFieldFinal(iread->GetFieldID()) && + iread->Opnd(0)->GetOpCode() == OP_dread) { + AddrofSSANode *basedread = static_cast(iread->Opnd(0)); + MIRSymbol *mirst = basedread->GetSSAVar()->GetOst()->GetMIRSymbol(); + if (mirst == func->GetMirFunc()->GetFormal(0)) { + return vst->GetDefBB(); + } + } + return nullptr; + } + return nullptr; +} + +void FSAA::ProcessBB(BB *bb) { + auto &stmtNodes = bb->GetStmtNodes(); + for (auto itStmt = stmtNodes.begin(); itStmt != stmtNodes.rbegin().base(); ++itStmt) { + if (itStmt->GetOpCode() != OP_iassign) { + continue; + } + IassignNode *iass = static_cast(&*itStmt); + VersionSt *vst = nullptr; + if (iass->addrExpr->GetOpCode() == OP_dread) { + vst = static_cast(iass->addrExpr)->GetSSAVar(); + } else if (iass->addrExpr->GetOpCode() == OP_regread) { + vst = static_cast(iass->addrExpr)->GetSSAVar(); + } else { + break; + } + BB *defBB = FindUniquePointerValueDefBB(vst); + if (defBB != nullptr) { + if (DEBUGFUNC(func)) { + LogInfo::MapleLogger() << "FSAA finds unique pointer value def\n"; + } + // delete any maydefnode in the list that is defined before defBB + TypeOfMayDefList *mayDefNodes = &ssaTab->GetStmtsSSAPart().GetMayDefNodesOf(*itStmt); + + bool hasErase; + do { + hasErase = false; + TypeOfMayDefList::iterator it = mayDefNodes->begin(); + // due to use of iterator, can do at most 1 erasion each iterator usage + for (; it != mayDefNodes->end(); it++) { + if ((*it).base == nullptr) { + } else { + BB *aliasedDefBB = (*it).base->GetDefBB(); + if (aliasedDefBB == nullptr) { + hasErase = true; + } else { + hasErase = defBB != aliasedDefBB && dom->Dominate(*aliasedDefBB, *defBB); + } + } + if (hasErase) { + if (DEBUGFUNC(func)) { + LogInfo::MapleLogger() << "FSAA deletes mayDef of "; + (*it).GetResult()->Dump(mirModule); + LogInfo::MapleLogger() << " in BB " << bb->GetBBId() << " at:" << endl; + itStmt->Dump(); + } + mayDefNodes->erase(it); + needUpdateSSA = true; + CHECK_FATAL(!mayDefNodes->empty(), "FSAA::ProcessBB: mayDefNodes of iassign rendered empty"); + break; + } + } + } while (hasErase); + } + } +} + +AnalysisResult *MeDoFSAA::Run(MeFunction *func, MeFuncResultMgr *m, ModuleResultMgr *mrm) { + SSATab *ssaTab = static_cast(m->GetAnalysisResult(MeFuncPhase_SSATAB, func)); + ASSERT(ssaTab != nullptr, "ssaTab phase has problem"); + + MeSSA *ssa = static_cast(m->GetAnalysisResult(MeFuncPhase_SSA, func)); + ASSERT(ssa != nullptr, "ssa phase has problem"); + + Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); + ASSERT(dom != nullptr, "dominance phase has problem"); + + FSAA fsaa(func, dom); + + for (BB *bb : func->GetAllBBs()) { + if (bb != nullptr) { + fsaa.ProcessBB(bb); + } + } + + if (fsaa.needUpdateSSA) { + ssa->runRenameOnly = true; + + ssa->InitRenameStack(ssaTab->GetOriginalStTable(), func->GetAllBBs().size(), ssaTab->GetVersionStTable()); + // recurse down dominator tree in pre-order traversal + MapleSet *children = &dom->domChildren[func->GetCommonEntryBB()->GetBBId()]; + for (BBId child : *children) { + ssa->RenameBB(*func->GetBBFromID(child)); + } + + ssa->VerifySSA(); + + if (DEBUGFUNC(func)) { + func->DumpFunction(); + } + } + + return nullptr; +} + +} // namespace maple diff --git a/src/mapleall/maple_me/src/me_option.cpp b/src/mapleall/maple_me/src/me_option.cpp index d96728e7a7..ce9c78a714 100644 --- a/src/mapleall/maple_me/src/me_option.cpp +++ b/src/mapleall/maple_me/src/me_option.cpp @@ -95,6 +95,7 @@ bool MeOption::nativeOpt = true; bool MeOption::enableEA = false; bool MeOption::placementRC = false; bool MeOption::subsumRC = false; +bool MeOption::performFSAA = false; std::string MeOption::inlineFuncList = ""; bool MeOption::meVerify = false; #if MIR_JAVA @@ -181,7 +182,7 @@ enum OptionIndex { kDassignPre, kAssign2finalPre, kSubsumRC, - kNoSubsumRC, + kPerformFSAA, kRegReadAtReturn, kProPatphi, kNoProPatphi, @@ -749,6 +750,16 @@ const Descriptor kUsage[] = { " --no-subsumrc \tDisable subsumrc\n", "me", {} }, + { kPerformFSAA, + kEnable, + "", + "performFSAA", + kBuildTypeExperimental, + kArgCheckPolicyBool, + " --performFSAA \tPerform flow sensitive alias analysis\n" + " --no-performFSAA \tDisable flow sensitive alias analysis\n", + "me", + {} }, { kCheckCastOpt, kEnable, "", @@ -1327,6 +1338,9 @@ bool MeOption::SolveOptions(const std::vector &opts, bool i subsumRC = (opt.Type() == kEnable); epreIncludeRef = (opt.Type() == kEnable); break; + case kPerformFSAA: + performFSAA = (opt.Type() == kEnable); + break; case kMeInlineHint: inlineFuncList = opt.Args(); break; diff --git a/src/mapleall/maple_me/src/me_phase_manager.cpp b/src/mapleall/maple_me/src/me_phase_manager.cpp index 6e1562fe13..c784cd686f 100644 --- a/src/mapleall/maple_me/src/me_phase_manager.cpp +++ b/src/mapleall/maple_me/src/me_phase_manager.cpp @@ -61,6 +61,7 @@ #include "me_emit.h" #include "me_rc_lowering.h" #include "gen_check_cast.h" +#include "me_fsaa.h" #if MIR_JAVA #include "sync_select.h" #endif // MIR_JAVA diff --git a/src/mapleall/maple_me/src/ssa.cpp b/src/mapleall/maple_me/src/ssa.cpp index 8d3410aae0..c3c59f583a 100644 --- a/src/mapleall/maple_me/src/ssa.cpp +++ b/src/mapleall/maple_me/src/ssa.cpp @@ -43,8 +43,12 @@ VersionSt *SSA::CreateNewVersion(VersionSt &vSym, BB &defBB) { return &vSym; } ASSERT(vSym.GetVersion() == kInitVersion, "renamed before"); - VersionSt *newVersionSym = - ssaTab->GetVersionStTable().CreateNextVersionSt(vSym.GetOst()); + VersionSt *newVersionSym = nullptr; + if (!runRenameOnly) { + newVersionSym = ssaTab->GetVersionStTable().CreateNextVersionSt(vSym.GetOst()); + } else { + newVersionSym = &vSym; + } vstStacks[vSym.GetOrigIdx()]->push(newVersionSym); newVersionSym->SetDefBB(&defBB); return newVersionSym; -- Gitee From e8f9754ae9b347adf7d197a5422f724277f082e8 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Thu, 6 May 2021 19:48:59 -0700 Subject: [PATCH 3/3] Fix the bug that caused FSAA to assert; turn on FSAA --- src/mapleall/maple_me/src/me_option.cpp | 2 +- src/mapleall/maple_me/src/ssa.cpp | 3 +++ src/mapleall/mpl2mpl/src/constantfold.cpp | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/mapleall/maple_me/src/me_option.cpp b/src/mapleall/maple_me/src/me_option.cpp index ce9c78a714..ceb474ab4a 100644 --- a/src/mapleall/maple_me/src/me_option.cpp +++ b/src/mapleall/maple_me/src/me_option.cpp @@ -95,7 +95,7 @@ bool MeOption::nativeOpt = true; bool MeOption::enableEA = false; bool MeOption::placementRC = false; bool MeOption::subsumRC = false; -bool MeOption::performFSAA = false; +bool MeOption::performFSAA = true; std::string MeOption::inlineFuncList = ""; bool MeOption::meVerify = false; #if MIR_JAVA diff --git a/src/mapleall/maple_me/src/ssa.cpp b/src/mapleall/maple_me/src/ssa.cpp index c3c59f583a..157a026be9 100644 --- a/src/mapleall/maple_me/src/ssa.cpp +++ b/src/mapleall/maple_me/src/ssa.cpp @@ -85,6 +85,9 @@ void SSA::RenameDefs(StmtNode &stmt, BB &defBB) { mayDef.SetResult(newVersionSym); newVersionSym->SetDefType(VersionSt::kMayDef); newVersionSym->SetMayDef(&mayDef); + if (opcode == OP_iassign && mayDef.base != nullptr) { + mayDef.base = vstStacks[mayDef.base->GetOrigIdx()]->top(); + } } } } diff --git a/src/mapleall/mpl2mpl/src/constantfold.cpp b/src/mapleall/mpl2mpl/src/constantfold.cpp index 650289d852..2c459dd9fa 100644 --- a/src/mapleall/mpl2mpl/src/constantfold.cpp +++ b/src/mapleall/mpl2mpl/src/constantfold.cpp @@ -455,7 +455,7 @@ MIRConst *ConstantFold::FoldIntConstBinaryMIRConst(Opcode opcode, PrimType resul } case OP_sub: { if (useResult64) { - result64 = static_cast(intValueOfConst0 - intValueOfConst1); + result64 = static_cast(intValueOfConst0) - static_cast(intValueOfConst1); } else { result32 = static_cast(intValueOfConst0) - static_cast(intValueOfConst1); } -- Gitee