diff --git a/src/bin/jbc2mpl b/src/bin/jbc2mpl index c604fc2d7102b6abca60af6e85b59e917d920c7d..1c6a732a9172dc5d5af693cc7c3fe1f258aa4a4b 100755 Binary files a/src/bin/jbc2mpl and b/src/bin/jbc2mpl differ diff --git a/src/bin/maple b/src/bin/maple index f6920f5c88f54a1397ae7362fc1dee90c442a3f5..0be32734f30a97ef9cf564193d8d915b11f6effc 100755 Binary files a/src/bin/maple and b/src/bin/maple differ diff --git a/src/deplibs/libmplphase.a b/src/deplibs/libmplphase.a index 9fb5d414f01a31a2840ab5a1147d3bf7ad04bccf..91972c3b37a61b641ce16d822432ad1cf1069545 100644 Binary files a/src/deplibs/libmplphase.a and b/src/deplibs/libmplphase.a differ diff --git a/src/maple_driver/src/option_parser.cpp b/src/maple_driver/src/option_parser.cpp index bbd4031073ac4cf78fab77e2c6f8eba2818ddf7e..351f428b3e233b4aeebf99f6d6280ce41658f911 100644 --- a/src/maple_driver/src/option_parser.cpp +++ b/src/maple_driver/src/option_parser.cpp @@ -130,10 +130,15 @@ void OptionParser::PrintUsage(const std::string &helpType) const { } #endif - +#ifdef OPTION_PARSER_EXTRAOPT bool OptionParser::HandleKeyValue(const std::string &key, const std::string &value, bool isValueEmpty, std::vector &inputOption, const std::string &exeName, bool isAllOption) { +#else +bool OptionParser::HandleKeyValue(const std::string &key, const std::string &value, bool isValueEmpty, + std::vector &inputOption, const std::string&, + bool isAllOption) { +#endif if (key.empty()) { if (!isAllOption) { LogInfo::MapleLogger(kLlErr) << "Cannot recognize " << value << '\n'; diff --git a/src/maple_ir/include/mir_nodes.h b/src/maple_ir/include/mir_nodes.h index de31dea95f6d4b5657d7a2f65181b4e33cf03028..bf343d09c816d2b1abd2cc6f053bbeb61decc3fd 100644 --- a/src/maple_ir/include/mir_nodes.h +++ b/src/maple_ir/include/mir_nodes.h @@ -140,12 +140,12 @@ class BaseNode { ptyp = type; } - virtual BaseNode *Opnd(size_t i = 0) const { + virtual BaseNode *Opnd(size_t) const { ASSERT(0, "override needed"); return nullptr; } - virtual void SetOpnd(BaseNode *node, size_t i = 0) { + virtual void SetOpnd(BaseNode*, size_t) { ASSERT(0, "This should not happen"); } @@ -216,8 +216,7 @@ class UnaryNode : public BaseNode { return node; } - BaseNode *Opnd(size_t i = 0) const override { - ASSERT(i == 0, "Invalid operand idx in UnaryNode"); + BaseNode *Opnd(size_t) const override { return uOpnd; } @@ -225,7 +224,7 @@ class UnaryNode : public BaseNode { return 1; } - void SetOpnd(BaseNode *node, size_t i = 0) override { + void SetOpnd(BaseNode *node, size_t) override { uOpnd = node; } @@ -288,7 +287,7 @@ class RetypeNode : public TypeCvtNode { RetypeNode *CloneTree(MapleAllocator &allocator) const override { auto *node = allocator.GetMemPool()->New(*this); - node->SetOpnd(Opnd()->CloneTree(allocator)); + node->SetOpnd(Opnd(0)->CloneTree(allocator), 0); return node; } @@ -324,7 +323,7 @@ class ExtractbitsNode : public UnaryNode { ExtractbitsNode *CloneTree(MapleAllocator &allocator) const override { auto *node = allocator.GetMemPool()->New(*this); - node->SetOpnd(Opnd()->CloneTree(allocator)); + node->SetOpnd(Opnd(0)->CloneTree(allocator), 0); return node; } @@ -397,7 +396,7 @@ class JarrayMallocNode : public UnaryNode { JarrayMallocNode *CloneTree(MapleAllocator &allocator) const override { auto *node = allocator.GetMemPool()->New(*this); - node->SetOpnd(Opnd()->CloneTree(allocator)); + node->SetOpnd(Opnd(0)->CloneTree(allocator), 0); return node; } @@ -431,7 +430,7 @@ class IreadNode : public UnaryNode { IreadNode *CloneTree(MapleAllocator &allocator) const override { auto *node = allocator.GetMemPool()->New(*this); - node->SetOpnd(Opnd()->CloneTree(allocator)); + node->SetOpnd(Opnd(0)->CloneTree(allocator), 0); return node; } @@ -453,7 +452,7 @@ class IreadNode : public UnaryNode { // the base of an address expr is either a leaf or an iread BaseNode &GetAddrExprBase() const { - BaseNode *base = Opnd(); + BaseNode *base = Opnd(0); while (base->NumOpnds() != 0 && base->GetOpCode() != OP_iread) { base = base->Opnd(0); } @@ -483,7 +482,7 @@ class IreadoffNode : public UnaryNode { IreadoffNode *CloneTree(MapleAllocator &allocator) const override { auto *node = allocator.GetMemPool()->New(*this); - node->SetOpnd(Opnd()->CloneTree(allocator)); + node->SetOpnd(Opnd(0)->CloneTree(allocator), 0); return node; } @@ -1782,13 +1781,11 @@ class SwitchNode : public StmtNode { return node; } - BaseNode *Opnd(size_t i) const override { - ASSERT(i == 0, "it is not same as original"); + BaseNode *Opnd(size_t) const override { return switchOpnd; } - void SetOpnd(BaseNode *node, size_t i = 0) override { - ASSERT(i == 0, "it is not same as original"); + void SetOpnd(BaseNode *node, size_t) override { switchOpnd = node; } @@ -1928,7 +1925,7 @@ class UnaryStmtNode : public StmtNode { UnaryStmtNode *CloneTree(MapleAllocator &allocator) const override { auto *node = allocator.GetMemPool()->New(*this); node->SetStmtID(stmtIDNext++); - node->SetOpnd(uOpnd->CloneTree(allocator)); + node->SetOpnd(uOpnd->CloneTree(allocator), 0); return node; } @@ -1944,13 +1941,11 @@ class UnaryStmtNode : public StmtNode { this->SetOpnd(rhs, 0); } - BaseNode *Opnd(size_t i = 0) const override { - ASSERT(i == 0, "Unary operand"); + BaseNode *Opnd(size_t) const override { return uOpnd; } - void SetOpnd(BaseNode *node, size_t i = 0) override { - ASSERT(i == 0, "Unary operand"); + void SetOpnd(BaseNode *node, size_t) override { uOpnd = node; } @@ -1980,7 +1975,7 @@ class DassignNode : public UnaryStmtNode { DassignNode *CloneTree(MapleAllocator &allocator) const override { auto *node = allocator.GetMemPool()->New(*this); node->SetStmtID(stmtIDNext++); - node->SetOpnd(Opnd()->CloneTree(allocator)); + node->SetOpnd(Opnd(0)->CloneTree(allocator), 0); return node; } @@ -2040,7 +2035,7 @@ class RegassignNode : public UnaryStmtNode { RegassignNode *CloneTree(MapleAllocator &allocator) const override { auto *node = allocator.GetMemPool()->New(*this); node->SetStmtID(stmtIDNext++); - node->SetOpnd(Opnd()->CloneTree(allocator)); + node->SetOpnd(Opnd(0)->CloneTree(allocator), 0); return node; } @@ -2088,7 +2083,7 @@ class CondGotoNode : public UnaryStmtNode { CondGotoNode *CloneTree(MapleAllocator &allocator) const override { auto *node = allocator.GetMemPool()->New(*this); node->SetStmtID(stmtIDNext++); - node->SetOpnd(Opnd()->CloneTree(allocator)); + node->SetOpnd(Opnd(0)->CloneTree(allocator), 0); return node; } @@ -2121,7 +2116,7 @@ class RangeGotoNode : public UnaryStmtNode { bool Verify() const override; RangeGotoNode *CloneTree(MapleAllocator &allocator) const override { auto *node = allocator.GetMemPool()->New(allocator, *this); - node->SetOpnd(Opnd()->CloneTree(allocator)); + node->SetOpnd(Opnd(0)->CloneTree(allocator), 0); for (size_t i = 0; i < rangegotoTable.size(); ++i) { node->rangegotoTable.push_back(rangegotoTable[i]); } @@ -2269,7 +2264,7 @@ class IfStmtNode : public UnaryStmtNode { IfStmtNode *CloneTree(MapleAllocator &allocator) const override { auto *node = allocator.GetMemPool()->New(*this); node->SetStmtID(stmtIDNext++); - node->SetOpnd(Opnd()->CloneTree(allocator)); + node->SetOpnd(Opnd()->CloneTree(allocator), 0); node->thenPart = thenPart->CloneTree(allocator); if (elsePart != nullptr) { node->elsePart = elsePart->CloneTree(allocator); @@ -2279,7 +2274,7 @@ class IfStmtNode : public UnaryStmtNode { BaseNode *Opnd(size_t i = 0) const override { if (i == 0) { - return UnaryStmtNode::Opnd(); + return UnaryStmtNode::Opnd(0); } else if (i == 1) { return thenPart; } else if (i == 2) { @@ -2331,7 +2326,7 @@ class WhileStmtNode : public UnaryStmtNode { WhileStmtNode *CloneTree(MapleAllocator &allocator) const override { auto *node = allocator.GetMemPool()->New(*this); node->SetStmtID(stmtIDNext++); - node->SetOpnd(Opnd()->CloneTree(allocator)); + node->SetOpnd(Opnd(0)->CloneTree(allocator), 0); node->body = body->CloneTree(allocator); return node; } @@ -2502,7 +2497,7 @@ class ForeachelemNode : public StmtNode { loopBody = loopBodyValue; } - BaseNode *Opnd(size_t i = 0) const override { + BaseNode *Opnd(size_t) const override { return loopBody; } @@ -2606,7 +2601,7 @@ class IassignFPoffNode : public UnaryStmtNode { IassignFPoffNode(PrimType primType, int32 offset, BaseNode *src) : IassignFPoffNode(offset) { SetPrimType(primType); - SetOpnd(src); + SetOpnd(src, 0); } virtual ~IassignFPoffNode() = default; @@ -2617,7 +2612,7 @@ class IassignFPoffNode : public UnaryStmtNode { IassignFPoffNode *CloneTree(MapleAllocator &allocator) const override { auto *node = allocator.GetMemPool()->New(*this); node->SetStmtID(stmtIDNext++); - node->SetOpnd(Opnd()->CloneTree(allocator)); + node->SetOpnd(Opnd(0)->CloneTree(allocator), 0); return node; } diff --git a/src/maple_ir/src/bin_mpl_export.cpp b/src/maple_ir/src/bin_mpl_export.cpp index 0d74a1ae7c7517182ec75acf551e22591bba962e..fcd5b6af9223b7d03f9087ca9ae8369a94ebc8bc 100644 --- a/src/maple_ir/src/bin_mpl_export.cpp +++ b/src/maple_ir/src/bin_mpl_export.cpp @@ -261,9 +261,7 @@ void OutputTypeInterface(const MIRType &ty, BinaryMplExport &mplExport) { } } -void OutputTypeConstString(const MIRType &ty, BinaryMplExport&) { - ASSERT(false, "Type's kind not yet implemented: %d", ty.GetKind()); -} +void OutputTypeConstString(const MIRType&, BinaryMplExport&) {} void InitOutputTypeFactory() { RegisterFactoryFunction(kTypeScalar, OutputTypeScalar); diff --git a/src/maple_ir/src/mir_builder.cpp b/src/maple_ir/src/mir_builder.cpp index 9d099dc2b438d92e290d08fd544db7ed756253eb..cf09e91b895485ad3d435df196996225191139e0 100644 --- a/src/maple_ir/src/mir_builder.cpp +++ b/src/maple_ir/src/mir_builder.cpp @@ -897,7 +897,7 @@ UnaryStmtNode *MIRBuilder::CreateStmtThrow(BaseNode *rVal) { IfStmtNode *MIRBuilder::CreateStmtIf(BaseNode *cond) { auto *ifStmt = GetCurrentFuncCodeMp()->New(); - ifStmt->SetOpnd(cond); + ifStmt->SetOpnd(cond, 0); BlockNode *thenBlock = GetCurrentFuncCodeMp()->New(); ifStmt->SetThenPart(thenBlock); return ifStmt; @@ -905,7 +905,7 @@ IfStmtNode *MIRBuilder::CreateStmtIf(BaseNode *cond) { IfStmtNode *MIRBuilder::CreateStmtIfThenElse(BaseNode *cond) { auto *ifStmt = GetCurrentFuncCodeMp()->New(); - ifStmt->SetOpnd(cond); + ifStmt->SetOpnd(cond, 0); auto *thenBlock = GetCurrentFuncCodeMp()->New(); ifStmt->SetThenPart(thenBlock); auto *elseBlock = GetCurrentFuncCodeMp()->New(); diff --git a/src/maple_ir/src/mir_lower.cpp b/src/maple_ir/src/mir_lower.cpp index f4afac516082320a4ec822e1b638db70ff690b20..cbae7783d213014139ccb7d4365a935e99c385b6 100644 --- a/src/maple_ir/src/mir_lower.cpp +++ b/src/maple_ir/src/mir_lower.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2019] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. @@ -19,7 +19,7 @@ namespace maple { LabelIdx MIRLower::CreateCondGotoStmt(Opcode op, BlockNode &blk, const IfStmtNode &ifStmt) { auto *brStmt = mirModule.CurFuncCodeMemPool()->New(op); - brStmt->SetOpnd(ifStmt.Opnd()); + brStmt->SetOpnd(ifStmt.Opnd(), 0); brStmt->SetSrcPos(ifStmt.GetSrcPos()); LabelIdx lableIdx = mirModule.CurFunction()->GetLabelTab()->CreateLabel(); (void)mirModule.CurFunction()->GetLabelTab()->AddToStringLabelMap(lableIdx); @@ -89,7 +89,7 @@ BlockNode *MIRLower::LowerIfStmt(IfStmtNode &ifStmt, bool recursive) { if (thenEmpty && elseEmpty) { // generate EVAL statement auto *evalStmt = mirModule.CurFuncCodeMemPool()->New(OP_eval); - evalStmt->SetOpnd(ifStmt.Opnd()); + evalStmt->SetOpnd(ifStmt.Opnd(), 0); evalStmt->SetSrcPos(ifStmt.GetSrcPos()); blk->AddStatement(evalStmt); } else if (elseEmpty) { @@ -126,7 +126,7 @@ BlockNode *MIRLower::LowerWhileStmt(WhileStmtNode &whileStmt) { whileStmt.SetBody(LowerBlock(*whileStmt.GetBody())); auto *blk = mirModule.CurFuncCodeMemPool()->New(); auto *brFalseStmt = mirModule.CurFuncCodeMemPool()->New(OP_brfalse); - brFalseStmt->SetOpnd(whileStmt.Opnd()); + brFalseStmt->SetOpnd(whileStmt.Opnd(0), 0); brFalseStmt->SetSrcPos(whileStmt.GetSrcPos()); LabelIdx lalbeIdx = mirModule.CurFunction()->GetLabelTab()->CreateLabel(); (void)mirModule.CurFunction()->GetLabelTab()->AddToStringLabelMap(lalbeIdx); @@ -139,7 +139,7 @@ BlockNode *MIRLower::LowerWhileStmt(WhileStmtNode &whileStmt) { blk->AddStatement(lableStmt); blk->AppendStatementsFromBlock(*whileStmt.GetBody()); auto *brTrueStmt = mirModule.CurFuncCodeMemPool()->New(OP_brtrue); - brTrueStmt->SetOpnd(whileStmt.Opnd()->CloneTree(mirModule.GetCurFuncCodeMPAllocator())); + brTrueStmt->SetOpnd(whileStmt.Opnd(0)->CloneTree(mirModule.GetCurFuncCodeMPAllocator()), 0); brTrueStmt->SetOffset(bodyLableIdx); blk->AddStatement(brTrueStmt); lableStmt = mirModule.CurFuncCodeMemPool()->New(); @@ -169,7 +169,7 @@ BlockNode *MIRLower::LowerDoloopStmt(DoloopNode &doloop) { auto *startRegassign = mirModule.CurFuncCodeMemPool()->New(); startRegassign->SetRegIdx(regIdx); startRegassign->SetPrimType(primType); - startRegassign->SetOpnd(doloop.GetStartExpr()); + startRegassign->SetOpnd(doloop.GetStartExpr(), 0); startRegassign->SetSrcPos(doloop.GetSrcPos()); blk->AddStatement(startRegassign); } else { @@ -180,7 +180,7 @@ BlockNode *MIRLower::LowerDoloopStmt(DoloopNode &doloop) { blk->AddStatement(startDassign); } auto *brFalseStmt = mirModule.CurFuncCodeMemPool()->New(OP_brfalse); - brFalseStmt->SetOpnd(doloop.GetCondExpr()); + brFalseStmt->SetOpnd(doloop.GetCondExpr(), 0); LabelIdx lIdx = mirModule.CurFunction()->GetLabelTab()->CreateLabel(); (void)mirModule.CurFunction()->GetLabelTab()->AddToStringLabelMap(lIdx); brFalseStmt->SetOffset(lIdx); @@ -204,7 +204,7 @@ BlockNode *MIRLower::LowerDoloopStmt(DoloopNode &doloop) { auto *endRegassign = mirModule.CurFuncCodeMemPool()->New(); endRegassign->SetRegIdx(regIdx); endRegassign->SetPrimType(doVarPType); - endRegassign->SetOpnd(add); + endRegassign->SetOpnd(add, 0); blk->AddStatement(endRegassign); } else { const MIRSymbol *doVarSym = mirModule.CurFunction()->GetLocalOrGlobalSymbol(doloop.GetDoVarStIdx()); @@ -219,7 +219,7 @@ BlockNode *MIRLower::LowerDoloopStmt(DoloopNode &doloop) { blk->AddStatement(endDassign); } auto *brTrueStmt = mirModule.CurFuncCodeMemPool()->New(OP_brtrue); - brTrueStmt->SetOpnd(doloop.GetCondExpr()->CloneTree(mirModule.GetCurFuncCodeMPAllocator())); + brTrueStmt->SetOpnd(doloop.GetCondExpr()->CloneTree(mirModule.GetCurFuncCodeMPAllocator()), 0); brTrueStmt->SetOffset(bodyLabelIdx); blk->AddStatement(brTrueStmt); labelStmt = mirModule.CurFuncCodeMemPool()->New(); @@ -244,7 +244,7 @@ BlockNode *MIRLower::LowerDowhileStmt(WhileStmtNode &doWhileStmt) { blk->AddStatement(labelStmt); blk->AppendStatementsFromBlock(*doWhileStmt.GetBody()); auto *brTrueStmt = mirModule.CurFuncCodeMemPool()->New(OP_brtrue); - brTrueStmt->SetOpnd(doWhileStmt.Opnd()); + brTrueStmt->SetOpnd(doWhileStmt.Opnd(0), 0); brTrueStmt->SetOffset(lIdx); blk->AddStatement(brTrueStmt); return blk; @@ -299,14 +299,14 @@ void MIRLower::LowerBrCondition(BlockNode &block) { nextStmt = stmt->GetNext(); if (stmt->IsCondBr()) { auto *condGoto = static_cast(stmt); - if (condGoto->Opnd()->GetOpCode() == OP_cand || condGoto->Opnd()->GetOpCode() == OP_cior) { - auto *cond = static_cast(condGoto->Opnd()); + if (condGoto->Opnd(0)->GetOpCode() == OP_cand || condGoto->Opnd(0)->GetOpCode() == OP_cior) { + auto *cond = static_cast(condGoto->Opnd(0)); if ((stmt->GetOpCode() == OP_brfalse && cond->GetOpCode() == OP_cand) || (stmt->GetOpCode() == OP_brtrue && cond->GetOpCode() == OP_cior)) { // short-circuit target label is same as original condGoto stmt - condGoto->SetOpnd(cond->GetBOpnd(0)); + condGoto->SetOpnd(cond->GetBOpnd(0), 0); auto *newCondGoto = mirModule.CurFuncCodeMemPool()->New(Opcode(stmt->GetOpCode())); - newCondGoto->SetOpnd(cond->GetBOpnd(1)); + newCondGoto->SetOpnd(cond->GetBOpnd(1), 0); newCondGoto->SetOffset(condGoto->GetOffset()); block.InsertAfter(newCondGoto, condGoto); nextStmt = stmt; // so it will be re-processed if another cand/cior @@ -325,10 +325,10 @@ void MIRLower::LowerBrCondition(BlockNode &block) { } auto *newCondGoto = mirModule.CurFuncCodeMemPool()->New( stmt->GetOpCode() == OP_brfalse ? OP_brtrue : OP_brfalse); - newCondGoto->SetOpnd(cond->GetBOpnd(0)); + newCondGoto->SetOpnd(cond->GetBOpnd(0), 0); newCondGoto->SetOffset(lIdx); block.InsertBefore(condGoto, newCondGoto); - condGoto->SetOpnd(cond->GetBOpnd(1)); + condGoto->SetOpnd(cond->GetBOpnd(1), 0); nextStmt = newCondGoto; // so it will be re-processed if another cand/cior } } diff --git a/src/maple_ir/src/mir_nodes.cpp b/src/maple_ir/src/mir_nodes.cpp index b36d093c3a9cf6a4f04da73282398d83d06399a0..c8097141b9b99cc69413926dbd9f000e8e83726f 100644 --- a/src/maple_ir/src/mir_nodes.cpp +++ b/src/maple_ir/src/mir_nodes.cpp @@ -215,7 +215,7 @@ void CatchNode::Dump() const { this->BaseNode::Dump(); } -void UnaryNode::DumpOpnd(const MIRModule &mod, int indent) const { +void UnaryNode::DumpOpnd(const MIRModule&, int indent) const { LogInfo::MapleLogger() << " ("; uOpnd->Dump(indent); LogInfo::MapleLogger() << ")"; @@ -270,7 +270,7 @@ void IreadoffNode::Dump(int32 indent) const { DumpOpnd(*theMIRModule, indent); } -void IreadFPoffNode::Dump(int32 indent) const { +void IreadFPoffNode::Dump(int32) const { LogInfo::MapleLogger() << kOpcodeInfo.GetTableItemAt(GetOpCode()).name << " " << GetPrimTypeName(GetPrimType()); LogInfo::MapleLogger() << " " << offset; } @@ -542,7 +542,7 @@ void RegreadNode::Dump(int32) const { } } -void AddroffuncNode::Dump(int32 indent) const { +void AddroffuncNode::Dump(int32) const { LogInfo::MapleLogger() << kOpcodeInfo.GetTableItemAt(GetOpCode()).name << " " << GetPrimTypeName(GetPrimType()); MIRFunction *func = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); LogInfo::MapleLogger() << " &" << GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx())->GetName(); @@ -651,7 +651,7 @@ void RegassignNode::Dump(int32 indent) const { } } LogInfo::MapleLogger() << " ("; - UnaryStmtNode::Opnd()->Dump(indent + 1); + UnaryStmtNode::Opnd(0)->Dump(indent + 1); LogInfo::MapleLogger() << ")\n"; } @@ -731,7 +731,7 @@ void CondGotoNode::Dump(int32 indent) const { StmtNode::DumpBase(indent); LogInfo::MapleLogger() << " @" << theMIRModule->CurFunction()->GetLabelName((LabelIdx)offset); LogInfo::MapleLogger() << " ("; - Opnd()->Dump(indent); + Opnd(0)->Dump(indent); LogInfo::MapleLogger() << ")\n"; } @@ -756,7 +756,7 @@ void SwitchNode::Dump(int32 indent) const { void RangeGotoNode::Dump(int32 indent) const { StmtNode::DumpBase(indent); LogInfo::MapleLogger() << " ("; - Opnd()->Dump(indent); + Opnd(0)->Dump(indent); LogInfo::MapleLogger() << ") " << tagOffset << " {"; for (auto it = rangegotoTable.begin(); it != rangegotoTable.end(); it++) { LogInfo::MapleLogger() << '\n'; @@ -786,7 +786,7 @@ void MultiwayNode::Dump(int32 indent) const { LogInfo::MapleLogger() << " }\n"; } -void UnaryStmtNode::DumpOpnd(const MIRModule &mod, int indent) const { +void UnaryStmtNode::DumpOpnd(const MIRModule&, int indent) const { LogInfo::MapleLogger() << " ("; uOpnd->Dump(indent); LogInfo::MapleLogger() << ")"; @@ -839,7 +839,7 @@ void WhileStmtNode::Dump(int32 indent) const { StmtNode::DumpBase(indent); if (GetOpCode() == OP_while) { LogInfo::MapleLogger() << " ("; - Opnd()->Dump(indent); + Opnd(0)->Dump(indent); LogInfo::MapleLogger() << ")"; body->Dump(indent); } else { // OP_dowhile @@ -849,7 +849,7 @@ void WhileStmtNode::Dump(int32 indent) const { } PrintIndentation(indent); LogInfo::MapleLogger() << "} ("; - Opnd()->Dump(indent); + Opnd(0)->Dump(indent); LogInfo::MapleLogger() << ")\n"; } } @@ -1463,19 +1463,19 @@ bool TypeCvtNode::Verify() const { bool opndTypeVerf = true; bool opndSizeVerf = true; if (GetOpCode() == OP_ceil || GetOpCode() == OP_floor || GetOpCode() == OP_round || GetOpCode() == OP_trunc) { - opndTypeVerf = FloatIntCvtTypeVerify(GetPrimType(), Opnd()->GetPrimType()); + opndTypeVerf = FloatIntCvtTypeVerify(GetPrimType(), Opnd(0)->GetPrimType()); } else if (GetOpCode() == OP_retype) { - if (GetPrimTypeSize(GetPrimType()) != GetPrimTypeSize(Opnd()->GetPrimType())) { + if (GetPrimTypeSize(GetPrimType()) != GetPrimTypeSize(Opnd(0)->GetPrimType())) { opndSizeVerf = false; LogInfo::MapleLogger() << "\n#Error:The size of opnd0 and prim-type must be the same\n"; } } - bool opndExprVerf = Opnd()->Verify(); + bool opndExprVerf = Opnd(0)->Verify(); return opndTypeVerf && opndSizeVerf && opndExprVerf; } bool IreadNode::Verify() const { - bool addrExprVerf = Opnd()->Verify(); + bool addrExprVerf = Opnd(0)->Verify(); bool pTypeVerf = ReadTypeVerify(*this); bool structVerf = true; if (GetTypeKind(tyIdx) != kTypePointer) { @@ -1532,12 +1532,12 @@ bool IreadFPoffNode::Verify() const { } bool ExtractbitsNode::Verify() const { - bool opndExprVerf = Opnd()->Verify(); - bool opndTypeVerf = ArithTypeVerify(*Opnd()); - bool compVerf = CompatibleTypeVerify(*Opnd(), *this); + bool opndExprVerf = Opnd(0)->Verify(); + bool opndTypeVerf = ArithTypeVerify(*Opnd(0)); + bool compVerf = CompatibleTypeVerify(*Opnd(0), *this); bool resTypeVerf = UnaryTypeVerify0(GetPrimType()); constexpr int numBitsInByte = 8; - bool opnd0SizeVerf = (numBitsInByte * GetPrimTypeSize(Opnd()->GetPrimType()) >= bitsSize); + bool opnd0SizeVerf = (numBitsInByte * GetPrimTypeSize(Opnd(0)->GetPrimType()) >= bitsSize); if (!opnd0SizeVerf) { LogInfo::MapleLogger() << "\n#Error: The operand of extractbits must be large enough to contain the specified bitfield\n"; @@ -1734,21 +1734,21 @@ bool IassignoffNode::Verify() const { } bool IassignFPoffNode::Verify() const { - bool rhsVerf = Opnd()->Verify(); - bool compVerf = CompatibleTypeVerify(*this, *Opnd()); + bool rhsVerf = Opnd(0)->Verify(); + bool compVerf = CompatibleTypeVerify(*this, *Opnd(0)); return rhsVerf && compVerf; } bool RegassignNode::Verify() const { - bool rhsVerf = Opnd()->Verify(); - bool compVerf = CompatibleTypeVerify(*this, *Opnd()); + bool rhsVerf = Opnd(0)->Verify(); + bool compVerf = CompatibleTypeVerify(*this, *Opnd(0)); return rhsVerf && compVerf; } bool CondGotoNode::Verify() const { - bool opndExprVerf = UnaryStmtNode::Opnd()->Verify(); + bool opndExprVerf = UnaryStmtNode::Opnd(0)->Verify(); bool opndTypeVerf = true; - if (!IsPrimitiveInteger(UnaryStmtNode::Opnd()->GetPrimType())) { + if (!IsPrimitiveInteger(UnaryStmtNode::Opnd(0)->GetPrimType())) { opndTypeVerf = false; LogInfo::MapleLogger() << "\n#Error:the operand of brfalse and trfalse must be primitive integer\n"; } @@ -1770,8 +1770,8 @@ bool BinaryStmtNode::Verify() const { } bool RangeGotoNode::Verify() const { - bool opndExprVerf = Opnd()->Verify(); - bool opndTypeVerf = IntTypeVerify(Opnd()->GetPrimType()); + bool opndExprVerf = Opnd(0)->Verify(); + bool opndTypeVerf = IntTypeVerify(Opnd(0)->GetPrimType()); if (!opndTypeVerf) { LogInfo::MapleLogger() << "\n#Error: the operand of rangegoto must be in [i32,u32,i64,u64]\n"; } @@ -1812,7 +1812,7 @@ bool IfStmtNode::Verify() const { } bool WhileStmtNode::Verify() const { - bool condVerf = Opnd()->Verify(); + bool condVerf = Opnd(0)->Verify(); bool bodyVerf = true; if (body != nullptr) { bodyVerf = body->Verify(); diff --git a/src/maple_ir/src/mir_parser.cpp b/src/maple_ir/src/mir_parser.cpp index 946e81470b4e4257f128be0cc39c70fb1e0f8b95..ce7dbf7470dd7286970cbdee6b11b7bcfe6a15e9 100644 --- a/src/maple_ir/src/mir_parser.cpp +++ b/src/maple_ir/src/mir_parser.cpp @@ -88,7 +88,7 @@ bool MIRParser::ParseStmtRegassign(StmtNodePtr &stmt) { if (!ParseExprOneOperand(expr)) { return false; } - regAssign->SetOpnd(expr); + regAssign->SetOpnd(expr, 0); if (regAssign->GetRegIdx() > 0) { // check type consistenency for the preg MIRPreg *preg = mod.CurFunction()->GetPregTab()->PregFromPregIdx(regAssign->GetRegIdx()); if (preg->GetPrimType() == kPtyInvalid) { @@ -187,7 +187,7 @@ bool MIRParser::ParseStmtIassignFPoff(StmtNodePtr &stmt) { if (!ParseExprOneOperand(expr)) { return false; } - iAssignOff->SetOpnd(expr); + iAssignOff->SetOpnd(expr, 0); lexer.NextToken(); stmt = iAssignOff; return true; @@ -330,7 +330,7 @@ bool MIRParser::ParseStmtIf(StmtNodePtr &stmt) { if (!ParseExprOneOperand(expr)) { return false; } - ifStmt->SetOpnd(expr); + ifStmt->SetOpnd(expr, 0); if (lexer.NextToken() != TK_lbrace) { Error("expect { begin if body but get "); return false; @@ -372,7 +372,7 @@ bool MIRParser::ParseStmtWhile(StmtNodePtr &stmt) { if (!ParseExprOneOperand(expr)) { return false; } - whileStmt->SetOpnd(expr); + whileStmt->SetOpnd(expr, 0); if (lexer.NextToken() != TK_lbrace) { Error("expect { begin if body but get "); return false; @@ -407,7 +407,7 @@ bool MIRParser::ParseStmtDowhile(StmtNodePtr &stmt) { if (!ParseExprOneOperand(expr)) { return false; } - whileStmt->SetOpnd(expr); + whileStmt->SetOpnd(expr, 0); lexer.NextToken(); stmt = whileStmt; return true; @@ -485,7 +485,7 @@ bool MIRParser::ParseStmtBr(StmtNodePtr &stmt) { if (!ParseExprOneOperand(expr)) { return false; } - condGoto->SetOpnd(expr); + condGoto->SetOpnd(expr, 0); stmt = condGoto; lexer.NextToken(); return true; @@ -572,7 +572,7 @@ bool MIRParser::ParseStmtRangegoto(StmtNodePtr &stmt) { return false; } if (!IsPrimitiveInteger(expr->GetPrimType())) { - rangeGotoNode->SetOpnd(expr); + rangeGotoNode->SetOpnd(expr, 0); Error("expect expression return integer but get "); return false; } @@ -1168,7 +1168,7 @@ bool MIRParser::ParseUnaryStmt(Opcode op, StmtNodePtr &stmt) { if (!ParseExprOneOperand(expr)) { return false; } - throwStmt->SetOpnd(expr); + throwStmt->SetOpnd(expr, 0); lexer.NextToken(); return true; } @@ -2095,7 +2095,7 @@ bool MIRParser::ParseExprIreadIaddrof(IreadNode &expr) { if (!ParseExprOneOperand(opnd0)) { return false; } - expr.SetOpnd(opnd0); + expr.SetOpnd(opnd0, 0); lexer.NextToken(); return true; } @@ -2150,7 +2150,7 @@ bool MIRParser::ParseExprIreadoff(BaseNodePtr &expr) { Error("ParseExprIreadoff when paring one operand"); return false; } - iReadOff->SetOpnd(opnd); + iReadOff->SetOpnd(opnd, 0); lexer.NextToken(); return true; } @@ -2294,7 +2294,7 @@ bool MIRParser::ParseExprUnary(BaseNodePtr &expr) { Error("parsing unary wrong "); return false; } - unaryNode->SetOpnd(opnd); + unaryNode->SetOpnd(opnd, 0); lexer.NextToken(); return true; } @@ -2355,7 +2355,7 @@ bool MIRParser::ParseExprJarray(BaseNodePtr &expr) { Error("parsing unary wrong "); return false; } - jarrayNode->SetOpnd(opnd); + jarrayNode->SetOpnd(opnd, 0); lexer.NextToken(); return true; } @@ -2401,7 +2401,7 @@ bool MIRParser::ParseExprExtractbits(BaseNodePtr &expr) { Error("ParseExprExtractbits failed"); return false; } - extrctNode->SetOpnd(opnd); + extrctNode->SetOpnd(opnd, 0); lexer.NextToken(); return true; } @@ -2432,7 +2432,7 @@ bool MIRParser::ParseExprTyconvert(BaseNodePtr &expr) { if (!ParseExprOneOperand(opnd)) { return false; } - cvtNode->SetOpnd(opnd); + cvtNode->SetOpnd(opnd, 0); if (op == OP_retype) { cvtNode->SetFromType(opnd->GetPrimType()); } @@ -2460,7 +2460,7 @@ bool MIRParser::ParseExprRetype(BaseNodePtr &expr) { if (!ParseExprOneOperand(opnd)) { return false; } - cvtNode->SetOpnd(opnd); + cvtNode->SetOpnd(opnd, 0); cvtNode->SetFromType(opnd->GetPrimType()); lexer.NextToken(); return true; diff --git a/src/maple_me/BUILD.gn b/src/maple_me/BUILD.gn index 33658c3e3d6601e569f33596558676ec1ca53c2b..d3e780f58cd401d8b043f763beceaac5708ae629 100644 --- a/src/maple_me/BUILD.gn +++ b/src/maple_me/BUILD.gn @@ -45,6 +45,8 @@ src_libmplme = [ "src/ssa_epre.cpp", "src/ssa_pre.cpp", "src/occur.cpp", + "src/me_inequality_graph.cpp", + "src/me_abco.cpp", ] src_libmplmewpo = [ diff --git a/src/maple_me/include/dse.h b/src/maple_me/include/dse.h index 9c3744a3e75439504abcf17f8c6dede14a793145..42d9300b3e2a89d903c3a7842d61b9b618846eaa 100644 --- a/src/maple_me/include/dse.h +++ b/src/maple_me/include/dse.h @@ -26,7 +26,7 @@ namespace maple { class DSE { public: - DSE(MIRModule &mod, std::vector &&bbVec, BB &commonEntryBB, BB &commonExitBB, SSATab &ssaTab, + DSE(MIRModule&, std::vector &&bbVec, BB &commonEntryBB, BB &commonExitBB, SSATab &ssaTab, Dominance &postDom, bool enableDebug = false) : enableDebug(enableDebug), bbVec(bbVec), commonEntryBB(commonEntryBB), diff --git a/src/maple_me/include/me_abco.h b/src/maple_me/include/me_abco.h new file mode 100644 index 0000000000000000000000000000000000000000..28f54918389847f5df56b72ed7cd152ae76e46f8 --- /dev/null +++ b/src/maple_me/include/me_abco.h @@ -0,0 +1,300 @@ +/* + * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * + * http://license.coscl.org.cn/MulanPSL + * + * 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 v1 for more details. + */ +#ifndef MAPLEME_INCLUDE_ME_ABCOPT +#define MAPLEME_INCLUDE_ME_ABCOPT +#include "me_function.h" +#include "me_irmap.h" +#include "me_ir.h" +#include "me_inequality_graph.h" +#include "me_cfg.h" +namespace maple { +struct StmtComparator { + bool operator()(const std::pair &lhs, const std::pair &rhs) const { + if (lhs.first != rhs.first) { + return lhs.first < rhs.first; + } else { + return lhs.second < rhs.second; + } + } +}; +class CarePoint { + public: + enum CareKind { + kMeStmt, + kMePhi + }; + + explicit CarePoint(CareKind ck) : careKind(ck) {} + ~CarePoint() = default; + + bool IsCareMeStmt() const { + return careKind == kMeStmt; + } + + MeStmt *GetMeStmt() { + CHECK_FATAL(careKind == kMeStmt, "must be"); + return value.meStmt; + } + + const MeStmt *GetMeStmt() const { + CHECK_FATAL(careKind == kMeStmt, "must be"); + return value.meStmt; + } + + MeVarPhiNode *GetMePhi() { + CHECK_FATAL(careKind == kMePhi, "must be"); + return value.phiNode; + } + + const MeVarPhiNode *GetMePhi() const { + CHECK_FATAL(careKind == kMePhi, "must be"); + return value.phiNode; + } + + void SetMeStmt(MeStmt &meStmt) { + CHECK_FATAL(careKind == kMeStmt, "must be"); + value.meStmt = &meStmt; + } + + void SetMePhi(MeVarPhiNode &phi) { + CHECK_FATAL(careKind == kMePhi, "must be"); + value.phiNode = φ + } + + private: + CareKind careKind; + union CareStmt { + MeStmt *meStmt; + MeVarPhiNode *phiNode; + }; + CareStmt value; +}; +class DefPoint { + public: + enum DefineKind { + kDefByPi, + kDefByPhi + }; + + explicit DefPoint(DefineKind dk) : defKind(dk) {} + ~DefPoint() = default; + + void SetDefPi(PiassignMeStmt &s) { + CHECK_FATAL(defKind == kDefByPi, "must be"); + value.pi = &s; + } + + PiassignMeStmt *GetPiStmt() { + CHECK_FATAL(defKind == kDefByPi, "must be"); + return value.pi; + } + + const PiassignMeStmt *GetPiStmt() const { + CHECK_FATAL(defKind == kDefByPi, "must be"); + return value.pi; + } + + void SetDefPhi(MeVarPhiNode &s) { + CHECK_FATAL(defKind == kDefByPhi, "must be"); + value.phi = &s; + } + + BB *GetBB() const { + if (defKind == kDefByPi) { + return value.pi->GetBB(); + } else { + return value.phi->GetDefBB(); + } + } + + BB *GetGeneratedByBB() const { + CHECK_FATAL(defKind == kDefByPi, "must be"); + return value.pi->GetGeneratedBy()->GetBB(); + } + + VarMeExpr *GetRHS() const { + if (defKind == kDefByPi) { + return value.pi->GetRHS(); + } else { + return value.phi->GetOpnd(0); + } + } + + VarMeExpr *GetLHS() const { + if (defKind == kDefByPi) { + return value.pi->GetLHS(); + } else { + return value.phi->GetLHS(); + } + } + + const OStIdx &GetOStIdx() const { + if (defKind == kDefByPi) { + return value.pi->GetRHS()->GetOStIdx(); + } else { + return value.phi->GetOpnd(0)->GetOStIdx(); + } + } + + bool IsPiStmt() const { + return defKind == kDefByPi; + } + + bool IsGeneratedByBr() const { + CHECK_FATAL(defKind == kDefByPi, "must be"); + MeStmt *stmt = value.pi->GetGeneratedBy(); + if (stmt->GetOp() == OP_brtrue || stmt->GetOp() == OP_brfalse) { + return true; + } + return false; + } + + void RemoveFromBB() { + if (defKind == kDefByPi) { + if (IsGeneratedByBr()) { + GetBB()->GetPiList().clear(); + } else { + GetBB()->RemoveMeStmt(value.pi); + } + } else { + GetBB()->GetMevarPhiList().erase(GetOStIdx()); + } + } + + void Dump(IRMap &irMap) { + LogInfo::MapleLogger() << "New Def : " << '\n'; + if (defKind == kDefByPi) { + value.pi->Dump(&irMap); + } else { + value.phi->Dump(&irMap); + } + LogInfo::MapleLogger() << '\n'; + } + + private: + DefineKind defKind; + union DefStmt { + PiassignMeStmt *pi; + MeVarPhiNode *phi; + }; + DefStmt value; +}; +class MeABC { + public: + static bool kDebug; + MeABC(MeFunction &meFunction, Dominance &dom, MeIRMap &map, MemPool &pool) + : meFunc(&meFunction), + dom(&dom), + irMap(&map), + memPool(&pool), + allocator(&pool), + inequalityGraph(nullptr), + prove(nullptr), + forbidenPi(nullptr) {} + ~MeABC() = default; + void executeABCO(); + + private: + MeFunction *meFunc; + Dominance *dom; + MeIRMap *irMap; + MemPool *memPool; + MapleAllocator allocator; + std::unique_ptr inequalityGraph; + std::unique_ptr prove; + MeStmt *forbidenPi; + std::map arrayChecks; + std::map arrayNewChecks; + std::set careMeStmts; + std::set careMePhis; + std::map> containsBB; + std::vector newDefPoints; + std::vector carePoints; + std::map newDef2Old; + std::map, MeExpr*, StmtComparator> modifiedStmt; + std::map> modifiedPhi; + std::set visitedBBs; + std::set targetMeStmt; + bool CollectABC(); + void RemoveExtraNodes(); + void InsertPiNodes(); + bool ExistedPhiNode(BB &bb, VarMeExpr &rhs); + void InsertPhiNodes(); + void Rename(); + void RenameStartPiBr(DefPoint &newDefPoint); + void RenameStartPiArray(DefPoint &newDefPoint); + void RenameStartPhi(DefPoint &newDefPoint); + void ReplacePiPhiInSuccs(BB &bb, VarMeExpr &newVar); + bool ReplaceStmt(MeStmt &meStmt, VarMeExpr &newVar, VarMeExpr &oldVar); + void ReplaceBB(BB &bb, BB &parentBB, DefPoint &newDefPoint); + bool IsLegal(MeStmt &meStmt); + void ABCCollectArrayExpr(MeStmt &meStmt, MeExpr &meExpr, bool isUpdate = false); + void CollectCareInsns(); + bool ExistedPiNode(BB &bb, BB &parentBB, VarMeExpr &rhs); + void CreatePhi(VarMeExpr &rhs, BB &dfBB); + VarMeExpr *CreateNewPiExpr(MeExpr &opnd); + void CreateNewPiStmt(VarMeExpr *lhs, MeExpr &rhs, BB &bb, MeStmt &generatedBy, bool isToken); + void CreateNewPiStmt(VarMeExpr *lhs, MeExpr &rhs, MeStmt &generatedBy); + MeExpr *ReplaceMeExprExpr(MeExpr &origExpr, MeExpr &oldVar, MeExpr &repExpr); + MeExpr *NewMeExpr(MeExpr &meExpr); + bool ReplaceMeExprStmtOpnd(uint32 opndID, MeStmt &meStmt, MeExpr &oldVar, MeExpr &newVar, bool update); + bool ReplaceStmtWithNewVar(MeStmt &meStmt, MeExpr &oldVar, MeExpr &newVar, bool update); + bool IsVirtualVar(VarMeExpr &var, SSATab &ssaTab) const; + ESSABaseNode *GetOrCreateRHSNode(MeExpr &expr); + void BuildPhiInGraph(MeVarPhiNode &phi); + void BuildSoloPiInGraph(PiassignMeStmt &piMeStmt); + bool BuildArrayCheckInGraph(MeStmt &meStmt); + bool BuildBrMeStmtInGraph(MeStmt &meStmt); + bool BuildAssignInGraph(MeStmt &meStmt); + MeExpr *TryToResolveVar(MeExpr &expr, std::set &visitedPhi, MeExpr &dummyExpr, bool isConst); + bool BuildStmtInGraph(MeStmt &meStmt); + void AddUseDef(MeExpr &meExpr); + void AddCareInsn(MeStmt &defS); + void AddCarePhi(MeVarPhiNode &defP); + void BuildInequalityGraph(); + void FindRedundantABC(MeStmt &meStmt, NaryMeExpr &naryMeExpr); + void InitNewStartPoint(MeStmt &meStmt, NaryMeExpr &nMeExpr); + void DeleteABC(); + bool CleanABCInStmt(MeStmt &meStmt, NaryMeExpr &naryMeExpr); + MeExpr *ReplaceArrayExpr(MeExpr &rhs, MeExpr &naryMeExpr, MeStmt *ivarStmt); + + Dominance *GetDominace() { + return dom; + }; + + MemPool *GetMemPool() { + return memPool; + }; + + MapleAllocator &GetAllocator() { + return allocator; + }; + + MeIRMap *GetIRMap() { + return irMap; + }; +}; +class MeDoABCOpt : public MeFuncPhase { + public: + explicit MeDoABCOpt(MePhaseID id) : MeFuncPhase(id) {} + ~MeDoABCOpt() = default; + AnalysisResult *Run(MeFunction *func, MeFuncResultMgr *frm, ModuleResultMgr *mrm) override; + + std::string PhaseName() const override { + return "abcopt"; + } +}; +} +#endif diff --git a/src/maple_me/include/me_inequality_graph.h b/src/maple_me/include/me_inequality_graph.h new file mode 100644 index 0000000000000000000000000000000000000000..e10d129d82e562eeeee8180da1d25f36a880e3df --- /dev/null +++ b/src/maple_me/include/me_inequality_graph.h @@ -0,0 +1,405 @@ +/* + * Copyright (c) [2019] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * + * http://license.coscl.org.cn/MulanPSL + * + * 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 v1 for more details. + */ +#ifndef MAPLEME_INCLUDE_ME_INEQUALITY_GRAPH_H +#define MAPLEME_INCLUDE_ME_INEQUALITY_GRAPH_H +#include +#include +#include +#include + +constexpr maple::int32 kUpperBound = -1; +constexpr maple::int32 kLowerBound = 0; + +namespace maple { +enum ESSANodeKind : std::uint8_t { + kVarNode, + kPhiNode, + kConstNode, + kArrayNode +}; + +enum ProveResult : std::uint8_t { + kFalse, + kReduced, + kTrue +}; + +enum EdgeType : std::uint8_t { + kUpper, + kLower, + kNone, + kUpperInvalid, + kLowerInvalid, + kNoneInValid +}; + +enum DumpType : std::uint8_t { + kDumpUpperAndNone, + kDumpLowerAndNone, + kDumpNone +}; + +class VarValue { + public: + VarValue(MeExpr &expr, bool pos) : meExpr(&expr), isPositive(pos) {} + ~VarValue() = default; + + bool IsPositive() const { + return isPositive; + } + + const MeExpr &GetVarMeExpr() const { + return *meExpr; + } + + private: + MeExpr *meExpr; + bool isPositive; +}; + +class InequalEdge { + public: + InequalEdge(int v, EdgeType t) : edgeType(t), isVarValue(false), pairEdge(nullptr) { + value.constValue = v; + } + InequalEdge(MeExpr &expr, bool positive, EdgeType t) : edgeType(t), isVarValue(true), pairEdge(nullptr) { + value.varValue = new VarValue(expr, positive); + } + InequalEdge(InequalEdge &edge, InequalEdge &nextEdge) + : edgeType(edge.GetEdgeType()), + isVarValue(false), + pairEdge(nullptr) { + if (edge.GetEdgeType() == kLower) { + value.constValue = edge.value.constValue + nextEdge.GetConstValue(); + } else { + value.constValue = edge.value.constValue - nextEdge.GetConstValue(); + } + } + ~InequalEdge() { + if (isVarValue) { + delete(value.varValue); + value.varValue = nullptr; + } + } + + void SetEdgeTypeInValid() { + CHECK_FATAL(edgeType == kLower || edgeType == kUpper || edgeType == kNone, "must be"); + edgeType = edgeType == kLower ? kLowerInvalid : edgeType == kUpper ? kUpperInvalid : kNoneInValid; + } + + void SetEdgeTypeValid() { + CHECK_FATAL(edgeType == kLowerInvalid || edgeType == kUpperInvalid || edgeType == kNoneInValid, "must be"); + edgeType = edgeType == kLowerInvalid ? kLower : edgeType == kUpperInvalid ? kUpper : kNone; + } + + EdgeType GetEdgeType() const { + return edgeType; + } + + int GetConstValue() const { + return value.constValue; + } + + const VarValue &GetVarValue() const { + return *(value.varValue); + } + + bool IsVarValue() const { + return isVarValue; + } + void SetPairEdge(InequalEdge &pe) { + CHECK_FATAL(pairEdge == nullptr || pairEdge == &pe, "must be"); + pairEdge = &pe; + } + InequalEdge *GetPairEdge() { + return pairEdge; + } + + const InequalEdge *GetPairEdge() const { + return pairEdge; + } + + bool leq(const InequalEdge &edge) const { + ASSERT(edgeType == edge.GetEdgeType(), "two edges must have the same type: upper or lower"); + return edgeType == kUpper ? value.constValue <= edge.GetConstValue() : value.constValue >= edge.GetConstValue(); + } + + bool geq(int32 val) const{ + return edgeType == kUpper ? value.constValue >= val : value.constValue <= val; + } + + bool IsSame(InequalEdge &e) const { + if (edgeType != e.GetEdgeType()) { + return false; + } + if (isVarValue != e.IsVarValue()) { + return false; + } + if (isVarValue) { + return value.varValue->IsPositive() == e.GetVarValue().IsPositive() && + &value.varValue->GetVarMeExpr() == &e.GetVarValue().GetVarMeExpr(); + } else { + return value.constValue == e.GetConstValue(); + } + } + + private: + union { + int32 constValue; + VarValue *varValue; + } value; + EdgeType edgeType; + bool isVarValue; + InequalEdge *pairEdge; +}; + +class ESSABaseNode { + public: + struct ESSABaseNodeComparator { + bool operator()(const ESSABaseNode *lhs, const ESSABaseNode *rhs) const { + return lhs->GetID() < rhs->GetID(); + } + }; + ESSABaseNode(int i, MeExpr *expr, ESSANodeKind k) : id(i), meExpr(expr), kind(k) {} + virtual ~ESSABaseNode() { + // delete edges + for (auto iter = inWithConstEdge.begin(); iter != inWithConstEdge.end(); ++iter) { + delete iter->second; + iter->second = nullptr; + } + for (auto iter = inWithVarEdge.begin(); iter != inWithVarEdge.end(); ++iter) { + delete iter->second; + iter->second = nullptr; + } + } + + virtual const MeExpr &GetMeExpr() const { + return *meExpr; + } + + virtual ESSANodeKind GetKind() const { + return kind; + } + + virtual const std::multimap &GetOutWithConstEdgeMap() const { + return outWithConstEdge; + } + + virtual const std::multimap &GetOutWithVarEdgeMap() const { + return outWithVarEdge; + } + + virtual const std::multimap &GetInWithConstEdgeMap() const { + return inWithConstEdge; + } + + virtual const std::multimap &GetInWithVarEdgeMap() const { + return inWithVarEdge; + } + + virtual void InsertOutWithConstEdgeMap(ESSABaseNode &node, InequalEdge &e) { + outWithConstEdge.insert(std::pair(&node, &e)); + } + + virtual void InsertOutWithVarEdgeMap(ESSABaseNode &node, InequalEdge &e) { + outWithVarEdge.insert(std::pair(&node, &e)); + } + + virtual void InsertInWithConstEdgeMap(ESSABaseNode &node, InequalEdge &e) { + inWithConstEdge.insert(std::pair(&node, &e)); + } + + virtual void InsertInWithVarEdgeMap(ESSABaseNode &node, InequalEdge &e) { + inWithVarEdge.insert(std::pair(&node, &e)); + } + + virtual std::string GetExprID() const { + CHECK_FATAL(meExpr != nullptr, "must be"); + return std::to_string(meExpr->GetExprID()); + } + + int GetID() const { + return id; + } + + protected: + int id; + MeExpr *meExpr; + ESSANodeKind kind; + std::multimap outWithConstEdge; + std::multimap outWithVarEdge; + std::multimap inWithConstEdge; + std::multimap inWithVarEdge; +}; + +class ESSAVarNode : public ESSABaseNode { + public: + explicit ESSAVarNode(int i, MeExpr &e) : ESSABaseNode(i, &e, kVarNode) {} + ~ESSAVarNode() = default; +}; + +class ESSAConstNode : public ESSABaseNode { + public: + explicit ESSAConstNode(int i, int v) : ESSABaseNode(i, nullptr, kConstNode), value(v) {} + ~ESSAConstNode() = default; + + int GetValue() const { + return value; + } + + virtual std::string GetExprID() const { + return std::to_string(GetValue()) + " Const"; + } + + private: + int value; +}; + +class ESSAArrayNode : public ESSABaseNode { + public: + explicit ESSAArrayNode(int i, MeExpr &e) : ESSABaseNode(i, &e, kArrayNode) {} + ~ESSAArrayNode() = default; +}; + +class ESSAPhiNode : public ESSABaseNode { + public: + explicit ESSAPhiNode(int i, MeExpr &e) : ESSABaseNode(i, &e, kPhiNode) {} + ~ESSAPhiNode() { + for (auto pair : inPhiNodes) { + delete pair.second; + pair.second = nullptr; + } + } + + const std::vector &GetPhiOpnds() const { + return phiOpnds; + } + + void SetPhiOpnds(MapleVector &nodes) { + for (auto iter = nodes.begin(); iter != nodes.end(); ++iter) { + phiOpnds.push_back(*iter); + } + } + const std::multimap &GetInPhiEdgeMap() const { + return inPhiNodes; + } + + const std::multimap &GetOutPhiEdgeMap() const { + return outPhiNodes; + } + void InsertInPhiEdgeMap(ESSABaseNode &node, InequalEdge &e) { + inPhiNodes.insert(std::pair(&node, &e)); + } + void InsertOutPhiEdgeMap(ESSABaseNode &node, InequalEdge &e) { + outPhiNodes.insert(std::pair(&node, &e)); + } + + private: + std::vector phiOpnds; + std::multimap inPhiNodes; + std::multimap outPhiNodes; +}; + +class InequalityGraph { + public: + explicit InequalityGraph(MeFunction &func) : meFunction(&func) { + nodeCount = 0; + ESSAConstNode *node = new ESSAConstNode(GetValidID(), 0); + constNodes[0] = node; + } + ~InequalityGraph() { + // delete nodes + for (auto iter = varNodes.begin(); iter != varNodes.end(); ++iter) { + delete iter->second; + iter->second = nullptr; + } + + for (auto iter = constNodes.begin(); iter != constNodes.end(); ++iter) { + delete iter->second; + iter->second = nullptr; + } + } + + ESSAConstNode *GetOrCreateConstNode(int value); + ESSAVarNode *GetOrCreateVarNode(MeExpr &meExpr); + ESSAPhiNode *GetOrCreatePhiNode(MeVarPhiNode &phiNode); + ESSAArrayNode *GetOrCreateArrayNode(MeExpr &meExpr); + InequalEdge *AddEdge(ESSABaseNode &from, ESSABaseNode &to, int value, EdgeType type); + void AddPhiEdge(ESSABaseNode &from, ESSABaseNode &to, EdgeType type); + void AddEdge(ESSABaseNode &from, ESSABaseNode &to, MeExpr &value, bool positive, EdgeType type); + void ConnectTrivalEdge(); + void DumpDotFile(IRMap &irMap, DumpType dumpType) const; + ESSABaseNode &GetNode(MeExpr &meExpr); + ESSABaseNode &GetNode(int32 value); + bool HasNode(MeExpr &meExpr) const; + int GetValidID() { + ++nodeCount; + return nodeCount; + } + private: + std::string GetColor(EdgeType type) const; + bool HasNode(int value) const; + InequalEdge *HasEdge(ESSABaseNode &from, ESSABaseNode &to, InequalEdge &type) const; + std::string GetName(ESSABaseNode &node, IRMap &irMap) const; + std::string GetName(const MeExpr &meExpr, IRMap &irMap) const; + void DumpDotNodes(IRMap &irMap, std::ostream &out, DumpType dumpType, std::map nodes) const; + void DumpDotEdges(IRMap &irMap, const std::pair &map, + std::ostream &out, std::string &from) const; + + MeFunction *meFunction; + std::map varNodes; + std::map constNodes; + int nodeCount; +}; + +class ABCD { + public: + static constexpr int kDFSLimit = 100000; + explicit ABCD(InequalityGraph &graph) : inequalityGraph(&graph), recursiveCount(0) {} + ~ABCD() = default; + + bool DemandProve(MeExpr &arrayNode, MeExpr &idx); + + private: + using meet_function = ProveResult (*)(ProveResult, ProveResult); + static ProveResult max(ProveResult res1, ProveResult res2) { + if (res1 == kTrue || res2 == kTrue) { + return kTrue; + } + if (res1 == kReduced || res2 == kReduced) { + return kReduced; + } + return kFalse; + } + static ProveResult min(ProveResult res1, ProveResult res2) { + if (res1 == kFalse || res2 == kFalse) { + return kFalse; + } + if (res1 == kTrue || res2 == kTrue) { + return kTrue; + } + return kReduced; + } + bool DemandProve(ESSABaseNode &aNode, ESSABaseNode &bNode, EdgeType eType); + ProveResult Prove(ESSABaseNode &a, ESSABaseNode &b, InequalEdge &e); + ProveResult UpdateCacheResult(ESSABaseNode &a, ESSABaseNode &b, InequalEdge &e, meet_function meet); + void PrintTracing(); + InequalityGraph *inequalityGraph; + std::map active; + std::vector tracing; + int recursiveCount; +}; +} // namespace maple +#endif diff --git a/src/maple_me/include/me_ir.h b/src/maple_me/include/me_ir.h index a3e4076bae89f29fdd79dc1b9add122197229254..6c7dd746cca82f8cd417d02930a0f045f97fdf5e 100644 --- a/src/maple_me/include/me_ir.h +++ b/src/maple_me/include/me_ir.h @@ -950,8 +950,7 @@ class IvarMeExpr : public MeExpr { bool IsUseSameSymbol(const MeExpr&) const override; bool IsIdentical(IvarMeExpr &expr) const; MeExpr *GetIdenticalExpr(MeExpr &expr) const override; - MeExpr *GetOpnd(size_t idx) const override { - ASSERT(idx == 0, "IvarMeExpr can only have 1 operand"); + MeExpr *GetOpnd(size_t) const override { return base; } diff --git a/src/maple_me/src/irmap_emit.cpp b/src/maple_me/src/irmap_emit.cpp index cfbf0a6353a98f6ddf08e1199ecbeda83ba0a94c..06abfe17be0092b2054ffd8bc63a6f9a7c5b5a8e 100644 --- a/src/maple_me/src/irmap_emit.cpp +++ b/src/maple_me/src/irmap_emit.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2019] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. @@ -158,7 +158,7 @@ BaseNode &OpMeExpr::EmitExpr(SSATab &ssaTab) { case OP_malloc: { auto *unaryNode = ssaTab.GetModule().CurFunction()->GetCodeMempool()->New(Opcode(GetOp()), PrimType(GetPrimType())); - unaryNode->SetOpnd(&opnds[0]->EmitExpr(ssaTab)); + unaryNode->SetOpnd(&opnds[0]->EmitExpr(ssaTab), 0); return *unaryNode; } case OP_sext: @@ -166,7 +166,7 @@ BaseNode &OpMeExpr::EmitExpr(SSATab &ssaTab) { case OP_extractbits: { auto *unode = ssaTab.GetModule().CurFunction()->GetCodeMempool()->New( Opcode(GetOp()), PrimType(GetPrimType())); - unode->SetOpnd(&opnds[0]->EmitExpr(ssaTab)); + unode->SetOpnd(&opnds[0]->EmitExpr(ssaTab), 0); unode->SetBitsOffset(bitsOffset); unode->SetBitsSize(bitsSize); return *unode; @@ -186,14 +186,14 @@ BaseNode &OpMeExpr::EmitExpr(SSATab &ssaTab) { case OP_trunc: { auto *cvtNode = ssaTab.GetModule().CurFunction()->GetCodeMempool()->New( Opcode(GetOp()), PrimType(GetPrimType())); - cvtNode->SetOpnd(&opnds[0]->EmitExpr(ssaTab)); + cvtNode->SetOpnd(&opnds[0]->EmitExpr(ssaTab), 0); cvtNode->SetFromType(opndType); return *cvtNode; } case OP_retype: { auto *cvtNode = ssaTab.GetModule().CurFunction()->GetCodeMempool()->New(PrimType(GetPrimType())); - cvtNode->SetOpnd(&opnds[0]->EmitExpr(ssaTab)); + cvtNode->SetOpnd(&opnds[0]->EmitExpr(ssaTab), 0); cvtNode->SetFromType(opndType); cvtNode->SetTyIdx(tyIdx); return *cvtNode; @@ -202,7 +202,7 @@ BaseNode &OpMeExpr::EmitExpr(SSATab &ssaTab) { case OP_gcpermallocjarray: { auto *arrayMalloc = ssaTab.GetModule().CurFunction()->GetCodeMempool()->New( Opcode(GetOp()), PrimType(GetPrimType())); - arrayMalloc->SetOpnd(&opnds[0]->EmitExpr(ssaTab)); + arrayMalloc->SetOpnd(&opnds[0]->EmitExpr(ssaTab), 0); arrayMalloc->SetTyIdx(tyIdx); return *arrayMalloc; } @@ -218,7 +218,7 @@ BaseNode &OpMeExpr::EmitExpr(SSATab &ssaTab) { case OP_iaddrof: { auto *iaddrof = ssaTab.GetModule().CurFunction()->GetCodeMempool()->New(OP_iaddrof, PrimType(GetPrimType())); - iaddrof->SetOpnd(&opnds[0]->EmitExpr(ssaTab)); + iaddrof->SetOpnd(&opnds[0]->EmitExpr(ssaTab), 0); iaddrof->SetTyIdx(tyIdx); iaddrof->SetFieldID(fieldID); return *iaddrof; @@ -256,7 +256,7 @@ BaseNode &IvarMeExpr::EmitExpr(SSATab &ssaTab) { CHECK_NULL_FATAL(base); auto *ireadNode = ssaTab.GetModule().CurFunction()->GetCodeMempool()->New(OP_iread, PrimType(GetPrimType())); - ireadNode->SetOpnd(&base->EmitExpr(ssaTab)); + ireadNode->SetOpnd(&base->EmitExpr(ssaTab), 0); ireadNode->SetFieldID(fieldID); ireadNode->SetTyIdx(tyIdx); ASSERT(ireadNode->GetPrimType() != kPtyInvalid, ""); @@ -492,7 +492,7 @@ StmtNode &GotoMeStmt::EmitStmt(SSATab &ssaTab) { StmtNode &CondGotoMeStmt::EmitStmt(SSATab &ssaTab) { auto *cgNode = ssaTab.GetModule().CurFunction()->GetCodeMempool()->New(Opcode(GetOp())); cgNode->SetOffset(offset); - cgNode->SetOpnd(&GetOpnd()->EmitExpr(ssaTab)); + cgNode->SetOpnd(&GetOpnd()->EmitExpr(ssaTab), 0); cgNode->SetSrcPos(GetSrcPosition()); return *cgNode; } diff --git a/src/maple_me/src/me_abco.cpp b/src/maple_me/src/me_abco.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e075aafdb9b184d42ae4b39baccf1562245a26f5 --- /dev/null +++ b/src/maple_me/src/me_abco.cpp @@ -0,0 +1,1356 @@ +/* + * Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * + * http://license.coscl.org.cn/MulanPSL + * + * 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 v1 for more details. + */ +#include "me_abco.h" +namespace maple { +bool MeABC::kDebug = false; +constexpr int kNumOpnds = 2; +constexpr int kPiStmtUpperBound = 2; +constexpr int kPiListSize = 2; + +void MeABC::ABCCollectArrayExpr(MeStmt &meStmt, MeExpr &meExpr, bool isUpdate) { + if (meExpr.GetOp() == OP_array) { + auto *nMeExpr = static_cast(&meExpr); + if (nMeExpr->GetBoundCheck()) { + if (!isUpdate) { + CHECK_FATAL(arrayChecks.find(&meStmt) == arrayChecks.end(), "Must be"); + arrayChecks[&meStmt] = nMeExpr; + CHECK_FATAL(meStmt.GetOp() == OP_dassign || meStmt.GetOp() == OP_iassign || + meStmt.GetOp() == OP_maydassign, "must be"); + if (containsBB.find(meStmt.GetBB()) == containsBB.end()) { + containsBB[meStmt.GetBB()] = { &meStmt }; + } else { + containsBB[meStmt.GetBB()].push_back(&meStmt); + } + } else { + CHECK_FATAL(arrayNewChecks.find(&meStmt) == arrayNewChecks.end(), "Must be"); + arrayNewChecks[&meStmt] = nMeExpr; + } + } + } + for (int32 i = 0; i < meExpr.GetNumOpnds(); ++i) { + ABCCollectArrayExpr(meStmt, *(meExpr.GetOpnd(i)), isUpdate); + } +} + +bool MeABC::IsLegal(MeStmt &meStmt) { + CHECK_FATAL(meStmt.IsCondBr(), "must be"); + auto *brMeStmt = static_cast(&meStmt); + MeExpr *meCmp = brMeStmt->GetOpnd(); + // may be we need consider ne, eq, and only one opnd in branch insn + if (meCmp->GetMeOp() != kMeOpOp) { + return false; + } + auto *opMeExpr = static_cast(meCmp); + CHECK_FATAL(opMeExpr->GetNumOpnds() == kNumOpnds, "must be"); + if (opMeExpr->GetOp() != OP_ge && opMeExpr->GetOp() != OP_le && + opMeExpr->GetOp() != OP_lt && opMeExpr->GetOp() != OP_gt && + opMeExpr->GetOp() != OP_ne && opMeExpr->GetOp() != OP_eq) { + return false; + } + MeExpr *opnd1 = opMeExpr->GetOpnd(0); + MeExpr *opnd2 = opMeExpr->GetOpnd(1); + if ((opnd1->GetMeOp() != kMeOpVar && opnd1->GetMeOp() != kMeOpConst) || + (opnd2->GetMeOp() != kMeOpVar && opnd2->GetMeOp() != kMeOpConst)) { + return false; + } + if (!IsPrimitivePureScalar(opnd1->GetPrimType()) || !IsPrimitivePureScalar(opnd2->GetPrimType())) { + return false; + } + return true; +} + +VarMeExpr *MeABC::CreateNewPiExpr(MeExpr &opnd) { + if (opnd.GetMeOp() == kMeOpConst) { + return nullptr; + } + CHECK_FATAL(opnd.GetMeOp() == kMeOpVar, "must be"); + SSATab &ssaTab = irMap->GetSSATab(); + OriginalSt *ost = ssaTab.GetOriginalStFromID(static_cast(&opnd)->GetOStIdx()); + CHECK_FATAL(ost != nullptr && !ost->IsVolatile(), "must be"); + VarMeExpr *var = irMap->NewInPool(irMap->GetExprID(), ost->GetIndex(), + irMap->GetVerst2MeExprTable().size()); + irMap->SetExprID(irMap->GetExprID() + 1); + irMap->PushBackVerst2MeExprTable(var); + ost->PushbackVersionIndex(var->GetVstIdx()); + var->InitBase(opnd.GetOp(), opnd.GetPrimType(), 0); + return var; +} + +void MeABC::CreateNewPiStmt(VarMeExpr *lhs, MeExpr &rhs, BB &bb, MeStmt &generatedBy, bool isToken) { + if (lhs == nullptr) { + return; + } + PiassignMeStmt *meStmt = GetMemPool()->New(&GetAllocator()); + meStmt->SetGeneratedBy(generatedBy); + meStmt->SetRHS(*(static_cast(&rhs))); + meStmt->SetLHS(*lhs); + meStmt->SetBB(&bb); + meStmt->SetIsToken(isToken); + lhs->SetDefBy(kDefByStmt); + lhs->SetDefStmt(meStmt); + bb.InsertPi(*(generatedBy.GetBB()), *meStmt); + DefPoint *newDef = GetMemPool()->New(DefPoint::DefineKind::kDefByPi); + newDef->SetDefPi(*meStmt); + newDefPoints.push_back(newDef); + newDef2Old[newDef] = static_cast(&rhs); +} + +void MeABC::CreateNewPiStmt(VarMeExpr *lhs, MeExpr &rhs, MeStmt &generatedBy) { + if (lhs == nullptr) { + return; + } + PiassignMeStmt *meStmt = GetMemPool()->New(&GetAllocator()); + meStmt->SetGeneratedBy(generatedBy); + meStmt->SetRHS(*(static_cast(&rhs))); + meStmt->SetLHS(*lhs); + meStmt->SetBB(generatedBy.GetBB()); + lhs->SetDefBy(kDefByStmt); + lhs->SetDefStmt(meStmt); + generatedBy.GetBB()->InsertMeStmtAfter(&generatedBy, meStmt); + DefPoint *newDef = GetMemPool()->New(DefPoint::DefineKind::kDefByPi); + newDef->SetDefPi(*meStmt); + newDefPoints.push_back(newDef); + newDef2Old[newDef] = static_cast(&rhs); +} + +void MeABC::InsertPiNodes() { + for (auto bIt = meFunc->valid_begin(), eIt = meFunc->valid_end(); bIt != eIt; ++bIt) { + BB *bb = *bIt; + if (bb->GetKind() == kBBCondGoto && IsLegal(*(bb->GetLastMe()))) { + auto *brMeStmt = static_cast(bb->GetLastMe()); + BB *brTarget = bb->GetSucc(1); + BB *brFallThru = bb->GetSucc(0); + CHECK_FATAL(brMeStmt->GetOffset() == brTarget->GetBBLabel(), "must be"); + auto *opMeExpr = static_cast(brMeStmt->GetOpnd()); + MeExpr *opnd1 = opMeExpr->GetOpnd(0); + MeExpr *opnd2 = opMeExpr->GetOpnd(1); + VarMeExpr *brTargetNewOpnd1 = CreateNewPiExpr(*opnd1); + VarMeExpr *brTargetNewOpnd2 = CreateNewPiExpr(*opnd2); + CreateNewPiStmt(brTargetNewOpnd1, *opnd1, *brTarget, *brMeStmt, true); + CreateNewPiStmt(brTargetNewOpnd2, *opnd2, *brTarget, *brMeStmt, true); + VarMeExpr *brFallThruNewOpnd1 = CreateNewPiExpr(*opnd1); + VarMeExpr *brFallThruNewOpnd2 = CreateNewPiExpr(*opnd2); + CreateNewPiStmt(brFallThruNewOpnd1, *opnd1, *brFallThru, *brMeStmt, false); + CreateNewPiStmt(brFallThruNewOpnd2, *opnd2, *brFallThru, *brMeStmt, false); + } + auto it = containsBB.find(bb); + if (it == containsBB.end()) { + continue; + } + std::vector &arryChk = it->second; + for (MeStmt *meStmt : arryChk) { + NaryMeExpr *nMeExpr = arrayChecks[meStmt]; + CHECK_FATAL(nMeExpr->GetOpnds().size() == kNumOpnds, "must be"); + MeExpr *opnd1 = nMeExpr->GetOpnd(0); + MeExpr *opnd2 = nMeExpr->GetOpnd(1); + // consider whether we should create pi if opnd2 is const + CHECK_FATAL(opnd1->GetMeOp() == kMeOpVar, "must be"); + CHECK_FATAL(opnd1->GetPrimType() == PTY_ref, "must be"); + CHECK_FATAL(opnd2->GetMeOp() == kMeOpVar || opnd2->GetMeOp() == kMeOpConst, "must be"); + VarMeExpr *arracyCheckOpnd2 = CreateNewPiExpr(*opnd2); + CreateNewPiStmt(arracyCheckOpnd2, *opnd2, *meStmt); + } + } +} + +bool MeABC::CollectABC() { + auto eIt = meFunc->valid_end(); + for (auto bIt = meFunc->valid_begin(); bIt != eIt; ++bIt) { + for (auto &meStmt : (*bIt)->GetMeStmts()) { + for (size_t i = 0; i < meStmt.NumMeStmtOpnds(); ++i) { + ABCCollectArrayExpr(meStmt, *(meStmt.GetOpnd(i))); + } + } + } + return !arrayChecks.empty(); +} + +bool MeABC::ExistedPhiNode(BB &bb, VarMeExpr &rhs) { + return bb.GetMevarPhiList().find(rhs.GetOStIdx()) != bb.GetMevarPhiList().end(); +} + +bool MeABC::ExistedPiNode(BB &bb, BB &parentBB, VarMeExpr &rhs) { + MapleMap> &piList = bb.GetPiList(); + auto it = piList.find(&parentBB); + if (it == piList.end()) { + return false; + } + std::vector &piStmts = it->second; + CHECK_FATAL(piStmts.size() >= 1 && piStmts.size() <= kPiStmtUpperBound, "must be"); + PiassignMeStmt *pi1 = piStmts.at(0); + if (pi1->GetLHS()->GetOStIdx() == rhs.GetOStIdx()) { + return true; + } + if (piStmts.size() == kPiStmtUpperBound) { + PiassignMeStmt *pi2 = piStmts.at(1); + if (pi2->GetLHS()->GetOStIdx() == rhs.GetOStIdx()) { + return true; + } + } + return false; +} + +void MeABC::CreatePhi(VarMeExpr &rhs, BB &dfBB) { + VarMeExpr *phiNewLHS = CreateNewPiExpr(rhs); + MeVarPhiNode *newPhi = GetMemPool()->New(phiNewLHS, &GetAllocator()); + newPhi->SetDefBB(&dfBB); + newPhi->GetOpnds().resize(dfBB.GetPred().size(), &rhs); + newPhi->SetPiAdded(); + dfBB.GetMevarPhiList().insert(std::make_pair(phiNewLHS->GetOStIdx(), newPhi)); + DefPoint *newDef = GetMemPool()->New(DefPoint::DefineKind::kDefByPhi); + newDef->SetDefPhi(*newPhi); + newDefPoints.push_back(newDef); + newDef2Old[newDef] = &rhs; +} + +void MeABC::InsertPhiNodes() { + for (size_t i = 0; i < newDefPoints.size(); ++i) { + DefPoint *newDefStmt = newDefPoints[i]; + BB *newDefBB = newDefStmt->GetBB(); + VarMeExpr *rhs = newDefStmt->GetRHS(); + if (newDefStmt->IsPiStmt()) { + BB *genByBB = newDefStmt->GetGeneratedByBB(); + if (!dom->Dominate(*genByBB, *newDefBB) && !ExistedPhiNode(*newDefBB, *rhs)) { + CreatePhi(*rhs, *newDefBB); + continue; + } + } + BB *oldDefBB = rhs->DefByBB(); + if (oldDefBB == nullptr) { + oldDefBB = meFunc->GetCommonEntryBB(); + CHECK_FATAL(rhs->IsZeroVersion(irMap->GetSSATab()), "must be"); + } + CHECK_FATAL(newDefBB != nullptr && oldDefBB != nullptr, "must be"); + MapleSet &dfs = dom->GetDomFrontier(newDefBB->GetBBId()); + for (auto bbID : dfs) { + BB *dfBB = meFunc->GetBBFromID(bbID); + if (!dom->Dominate(*oldDefBB, *dfBB)) { + MapleSet &dfsTmp = dom->GetDomFrontier(oldDefBB->GetBBId()); + CHECK_FATAL(dfsTmp.find(bbID) != dfsTmp.end(), "must be"); + continue; + } + if (ExistedPhiNode(*dfBB, *rhs)) { + continue; + } + CreatePhi(*rhs, *dfBB); + } + } +} + +void MeABC::RenameStartPiBr(DefPoint &newDefPoint) { + const OStIdx &ostIdx = newDefPoint.GetOStIdx(); + BB *newDefBB = newDefPoint.GetBB(); + if (ExistedPhiNode(*(newDefPoint.GetBB()), *(newDefPoint.GetRHS()))) { + MeVarPhiNode* phi = newDefBB->GetMevarPhiList()[ostIdx]; + BB *genByBB = newDefPoint.GetGeneratedByBB(); + size_t index = 0; + while (index < newDefBB->GetPred().size()) { + if (newDefBB->GetPred(index) == genByBB) { + break; + } + ++index; + } + CHECK_FATAL(index < newDefBB->GetPred().size(), "must be"); + VarMeExpr *oldVar = phi->GetOpnd(index); + phi->SetOpnd(index, newDefPoint.GetLHS()); + if (!phi->IsPiAdded()) { + if (modifiedPhi.find(phi) == modifiedPhi.end()) { + modifiedPhi[phi] = std::vector(phi->GetOpnds().size(), nullptr); + } + if (modifiedPhi[phi][index] == nullptr) { + modifiedPhi[phi][index] = oldVar; + } + } + return; + } + RenameStartPhi(newDefPoint); +} + +void MeABC::RenameStartPiArray(DefPoint &newDefPoint) { + BB *newDefBB = newDefPoint.GetBB(); + MeStmt *piStmt = newDefPoint.GetPiStmt(); + if (piStmt != newDefBB->GetLastMe()) { + for (MeStmt *meStmt = piStmt->GetNext(); meStmt != nullptr; meStmt = meStmt->GetNext()) { + if (ReplaceStmt(*meStmt, *(newDefPoint.GetLHS()), *(newDef2Old[&newDefPoint]))) { + return; + } + } + } + ReplacePiPhiInSuccs(*newDefBB, *(newDefPoint.GetLHS())); + const MapleSet &children = dom->GetDomChildren(newDefBB->GetBBId()); + for (const BBId &child : children) { + ReplaceBB(*(meFunc->GetBBFromID(child)), *newDefBB, newDefPoint); + } +} + +void MeABC::RenameStartPhi(DefPoint &newDefPoint) { + BB *newDefBB = newDefPoint.GetBB(); + for (MeStmt &meStmt : newDefBB->GetMeStmts()) { + if (ReplaceStmt(meStmt, *newDefPoint.GetLHS(), *newDef2Old[&newDefPoint])) { + return; + } + } + ReplacePiPhiInSuccs(*newDefBB, *(newDefPoint.GetLHS())); + const MapleSet &children = dom->GetDomChildren(newDefBB->GetBBId()); + for (const BBId &child : children) { + ReplaceBB(*(meFunc->GetBBFromID(child)), *newDefBB, newDefPoint); + } +} + +void MeABC::ReplacePiPhiInSuccs(BB &bb, VarMeExpr &newVar) { + for (BB *succBB : bb.GetSucc()) { + MapleMap> &piList = succBB->GetPiList(); + auto it1 = piList.find(&bb); + if (it1 != piList.end()) { + std::vector &piStmts = it1->second; + // the size of pi statements must be 1 or 2 + CHECK_FATAL(piStmts.size() >= 1 && piStmts.size() <= 2, "must be"); + PiassignMeStmt *pi1 = piStmts.at(0); + if (pi1->GetLHS()->GetOStIdx() == newVar.GetOStIdx()) { + pi1->SetRHS(newVar); + continue; + } + if (piStmts.size() == kPiStmtUpperBound) { + PiassignMeStmt *pi2 = piStmts.at(1); + if (pi2->GetLHS()->GetOStIdx() == newVar.GetOStIdx()) { + pi2->SetRHS(newVar); + continue; + } + } + } + size_t index = 0; + while (index < succBB->GetPred().size()) { + if (succBB->GetPred(index) == &bb) { + break; + } + ++index; + } + CHECK_FATAL(index < succBB->GetPred().size(), "must be"); + MapleMap &phiList = succBB->GetMevarPhiList(); + auto it2 = phiList.find(newVar.GetOStIdx()); + if (it2 != phiList.end()) { + MeVarPhiNode *phi = it2->second; + VarMeExpr *oldVar = phi->GetOpnd(index); + phi->SetOpnd(index, &newVar); + if (!phi->IsPiAdded()) { + if (modifiedPhi.find(phi) == modifiedPhi.end()) { + modifiedPhi[phi] = std::vector(phi->GetOpnds().size(), nullptr); + } + if (modifiedPhi[phi][index] == nullptr) { + modifiedPhi[phi][index] = oldVar; + } + } + } + } +} + +MeExpr *MeABC::NewMeExpr(MeExpr &meExpr) { + switch (meExpr.GetMeOp()) { + case kMeOpIvar: { + auto &ivarMeExpr = static_cast(meExpr); + IvarMeExpr *newIvarExpr = GetMemPool()->New(irMap->GetExprID(), ivarMeExpr); + irMap->SetExprID(irMap->GetExprID() + 1); + return newIvarExpr; + } + case kMeOpOp: { + auto &opMeExpr = static_cast(meExpr); + OpMeExpr *newOpMeExpr = GetMemPool()->New(opMeExpr, irMap->GetExprID()); + irMap->SetExprID(irMap->GetExprID() + 1); + return newOpMeExpr; + } + case kMeOpNary: { + auto &naryMeExpr = static_cast(meExpr); + NaryMeExpr *newNaryMeExpr = GetMemPool()->New(&GetAllocator(), irMap->GetExprID(), naryMeExpr); + irMap->SetExprID(irMap->GetExprID() + 1); + newNaryMeExpr->InitBase(meExpr.GetOp(), meExpr.GetPrimType(), meExpr.GetNumOpnds()); + return newNaryMeExpr; + } + default: + CHECK_FATAL(false, "impossible"); + } +} + +MeExpr *MeABC::ReplaceMeExprExpr(MeExpr &origExpr, MeExpr &meExpr, MeExpr &repExpr) { + if (origExpr.IsLeaf()) { + return &origExpr; + } + switch (origExpr.GetMeOp()) { + case kMeOpOp: { + auto &opMeExpr = static_cast(origExpr); + OpMeExpr newMeExpr(opMeExpr, kInvalidExprID); + bool needRehash = false; + for (uint32 i = 0; i < kOperandNumTernary; ++i) { + if (opMeExpr.GetOpnd(i) == nullptr) { + continue; + } + if (opMeExpr.GetOpnd(i) == &meExpr) { + needRehash = true; + newMeExpr.SetOpnd(i, &repExpr); + } else if (!opMeExpr.GetOpnd(i)->IsLeaf()) { + newMeExpr.SetOpnd(i, ReplaceMeExprExpr(*newMeExpr.GetOpnd(i), meExpr, repExpr)); + if (newMeExpr.GetOpnd(i) != opMeExpr.GetOpnd(i)) { + needRehash = true; + } + } + } + return needRehash ? NewMeExpr(newMeExpr) : &origExpr; + } + case kMeOpNary: { + auto &naryMeExpr = static_cast(origExpr); + NaryMeExpr newMeExpr(&GetAllocator(), kInvalidExprID, naryMeExpr); + const MapleVector &opnds = naryMeExpr.GetOpnds(); + bool needRehash = false; + for (size_t i = 0; i < opnds.size(); ++i) { + MeExpr *opnd = opnds[i]; + if (opnd == &meExpr) { + newMeExpr.SetOpnd(i, &repExpr); + needRehash = true; + } else if (!opnd->IsLeaf()) { + newMeExpr.SetOpnd(i, ReplaceMeExprExpr(*newMeExpr.GetOpnd(i), meExpr, repExpr)); + if (newMeExpr.GetOpnd(i) != opnd) { + needRehash = true; + } + } + } + return needRehash ? NewMeExpr(newMeExpr) : &origExpr; + } + case kMeOpIvar: { + auto &ivarExpr = static_cast(origExpr); + IvarMeExpr newMeExpr(kInvalidExprID, ivarExpr); + bool needRehash = false; + if (ivarExpr.GetBase() == &meExpr) { + newMeExpr.SetBase(&repExpr); + needRehash = true; + } else if (!ivarExpr.GetBase()->IsLeaf()) { + newMeExpr.SetBase(ReplaceMeExprExpr(*newMeExpr.GetBase(), meExpr, repExpr)); + if (newMeExpr.GetBase() != ivarExpr.GetBase()) { + needRehash = true; + } + } + return needRehash ? NewMeExpr(newMeExpr) : &origExpr; + } + default: + CHECK_FATAL(false, "NYI"); + } +} + +bool MeABC::ReplaceMeExprStmtOpnd(uint32 opndID, MeStmt &meStmt, MeExpr &oldVar, MeExpr &newVar, bool update) { + MeExpr *opnd = meStmt.GetOpnd(opndID); + bool isFromIassign = (meStmt.GetOp() == OP_iassign) && (opndID == 0); + if (isFromIassign) { + opnd = static_cast(&meStmt)->GetLHSVal(); + } + bool replaced = false; + MeExpr *newExpr = nullptr; + if (opnd == &oldVar) { + if (isFromIassign) { + static_cast(&meStmt)->SetLHSVal(static_cast(&newVar)); + } else { + meStmt.SetOpnd(opndID, &newVar); + } + replaced = true; + } else if (!opnd->IsLeaf()) { + newExpr = ReplaceMeExprExpr(*opnd, oldVar, newVar); + replaced = (newExpr != opnd); + if (isFromIassign) { + static_cast(&meStmt)->SetLHSVal(static_cast(newExpr)); + } else { + meStmt.SetOpnd(opndID, newExpr); + } + } + if (replaced && update) { + if (modifiedStmt.find(std::make_pair(&meStmt, opndID)) == modifiedStmt.end()) { + modifiedStmt[std::make_pair(&meStmt, opndID)] = opnd; + } + } + return replaced; +} + +bool MeABC::ReplaceStmtWithNewVar(MeStmt &meStmt, MeExpr &oldVar, MeExpr &newVar, bool update) { + bool isReplaced = false; + switch (meStmt.GetOp()) { + case OP_dassign: + case OP_maydassign: + case OP_brtrue: + case OP_brfalse: { + isReplaced = ReplaceMeExprStmtOpnd(0, meStmt, oldVar, newVar, update); + break; + } + case OP_iassign: { + bool baseIsReplaced = ReplaceMeExprStmtOpnd(0, meStmt, oldVar, newVar, update); + bool rhsReplaced = ReplaceMeExprStmtOpnd(1, meStmt, oldVar, newVar, update); + isReplaced = baseIsReplaced || rhsReplaced; + break; + } + case OP_regassign: { + CHECK_FATAL(false, "should not happen"); + } + default: { + break; + } + } + return isReplaced; +} + +bool MeABC::ReplaceStmt(MeStmt &meStmt, VarMeExpr &newVar, VarMeExpr &oldVar) { + if (meStmt.GetOp() == OP_piassign) { + auto *pi = static_cast(&meStmt); + if (pi->GetRHS() == &oldVar) { + pi->SetRHS(newVar); + } + } else { + (void)ReplaceStmtWithNewVar(meStmt, oldVar, newVar, true); + } + const OStIdx &ostIdx = newVar.GetOStIdx(); + MapleMap *chiList = meStmt.GetChiList(); + if (chiList != nullptr && chiList->find(ostIdx) != chiList->end()) { + return true; + } + MeExpr *lhs = meStmt.GetAssignedLHS(); + if (lhs != nullptr && lhs->GetMeOp() == kMeOpVar && static_cast(lhs)->GetOStIdx() == ostIdx) { + return true; + } + lhs = meStmt.GetLHS(); + if (lhs != nullptr && lhs->GetMeOp() == kMeOpVar && static_cast(lhs)->GetOStIdx() == ostIdx) { + return true; + } + return false; +} + +void MeABC::Rename() { + for (size_t i = 0; i < newDefPoints.size(); ++i) { + DefPoint *newDefStmt = newDefPoints[i]; + visitedBBs.clear(); + if (newDefStmt->IsPiStmt()) { + if (newDefStmt->IsGeneratedByBr()) { + RenameStartPiBr(*newDefStmt); + } else { + RenameStartPiArray(*newDefStmt); + } + } else { + RenameStartPhi(*newDefStmt); + } + } +} + +void MeABC::ReplaceBB(BB &bb, BB &parentBB, DefPoint &newDefPoint) { + if (visitedBBs.find(&bb) != visitedBBs.end()) { + return; + } + visitedBBs.insert(&bb); + if (ExistedPhiNode(bb, *(newDefPoint.GetLHS())) || ExistedPiNode(bb, parentBB, *(newDefPoint.GetLHS()))) { + return; + } + for (MeStmt &meStmt : bb.GetMeStmts()) { + if (ReplaceStmt(meStmt, *(newDefPoint.GetLHS()), *(newDef2Old[&newDefPoint]))) { + return; + } + } + ReplacePiPhiInSuccs(bb, *(newDefPoint.GetLHS())); + const MapleSet &children = dom->GetDomChildren(bb.GetBBId()); + for (const BBId &child : children) { + ReplaceBB(*(meFunc->GetBBFromID(child)), bb, newDefPoint); + } +} + +void MeABC::RemoveExtraNodes() { + for (DefPoint *defP : newDefPoints) { + defP->RemoveFromBB(); + } + for (auto pair : modifiedStmt) { + MeStmt *meStmt = pair.first.first; + MeExpr *newVar = nullptr; + if ((meStmt->GetOp() == OP_iassign) && (pair.first.second == 0)) { + newVar = static_cast(meStmt)->GetLHSVal(); + } else { + newVar = meStmt->GetOpnd(pair.first.second); + } + MeExpr *oldVar = pair.second; + bool replaced = ReplaceStmtWithNewVar(*meStmt, *newVar, *oldVar, false); + CHECK_FATAL(replaced, "must be"); + } + for (auto pair : modifiedPhi) { + MeVarPhiNode *phi = pair.first; + for (size_t i = 0; i < pair.second.size(); ++i) { + size_t index = i; + VarMeExpr *oldVar = pair.second[i]; + if (oldVar != nullptr) { + phi->SetOpnd(index, oldVar); + } + } + } + memPoolCtrler.DeleteMemPool(memPool); +} + +bool MeABC::IsVirtualVar(VarMeExpr &var, SSATab &ssaTab) const { + const OriginalSt *ost = ssaTab.GetOriginalStFromID(var.GetOStIdx()); + return ost->GetIndirectLev() > 0; +} + +ESSABaseNode *MeABC::GetOrCreateRHSNode(MeExpr &expr) { + auto &rhs = static_cast(expr); + ESSABaseNode *result = nullptr; + if (rhs.GetDefBy() != kDefByPhi) { + result = inequalityGraph->GetOrCreateVarNode(rhs); + } else { + MeVarPhiNode *defPhi = &(rhs.GetDefPhi()); + result = inequalityGraph->GetOrCreatePhiNode(*defPhi); + } + return result; +} + +void MeABC::BuildPhiInGraph(MeVarPhiNode &phi) { + if (!IsPrimitivePureScalar(phi.GetLHS()->GetPrimType())) { + MeExpr *varExpr = phi.GetLHS(); + std::set visitedPhi; + ConstMeExpr dummyExpr(kInvalidExprID, nullptr); + varExpr = TryToResolveVar(*varExpr, visitedPhi, dummyExpr, false); + if (varExpr != nullptr && varExpr != &dummyExpr) { + ESSAArrayNode *arrayNode = inequalityGraph->GetOrCreateArrayNode(*(phi.GetLHS())); + ESSAVarNode *varNode = inequalityGraph->GetOrCreateVarNode(*varExpr); + InequalEdge *pairEdge1 = inequalityGraph->AddEdge(*arrayNode, *varNode, 0, EdgeType::kUpper); + InequalEdge *pairEdge2 = inequalityGraph->AddEdge(*varNode, *arrayNode, 0, EdgeType::kUpper); + pairEdge1->SetPairEdge(*pairEdge2); + pairEdge2->SetPairEdge(*pairEdge1); + } + return; + } + if (IsVirtualVar(*(phi.GetLHS()), irMap->GetSSATab())) { + return; + } + for (VarMeExpr *phiRHS : phi.GetOpnds()) { + AddUseDef(*phiRHS); + } +} + +void MeABC::BuildSoloPiInGraph(PiassignMeStmt &piMeStmt) { + VarMeExpr *piLHS = piMeStmt.GetLHS(); + VarMeExpr *piRHS = piMeStmt.GetRHS(); + AddUseDef(*piRHS); + ESSAVarNode *piLHSNode = inequalityGraph->GetOrCreateVarNode(*piLHS); + ESSABaseNode *piRHSNode = GetOrCreateRHSNode(*piRHS); + (void)inequalityGraph->AddEdge(*piRHSNode, *piLHSNode, 0, EdgeType::kUpper); + (void)inequalityGraph->AddEdge(*piLHSNode, *piRHSNode, 0, EdgeType::kLower); +} + +bool MeABC::BuildArrayCheckInGraph(MeStmt &meStmt) { + CHECK_FATAL(meStmt.GetOp() == OP_piassign, "must be"); + auto *piMeStmt = static_cast(&meStmt); + BuildSoloPiInGraph(*piMeStmt); + if (piMeStmt == forbidenPi) { + return true; + } + MeStmt *generatedByMeStmt = piMeStmt->GetGeneratedBy(); + CHECK_FATAL(arrayChecks.find(generatedByMeStmt) != arrayChecks.end(), "must be"); + NaryMeExpr *arrCheck = arrayChecks[generatedByMeStmt]; + MeExpr *opnd1 = arrCheck->GetOpnd(0); + MeExpr *opnd2 = arrCheck->GetOpnd(1); + CHECK_FATAL(opnd1->GetMeOp() == kMeOpVar, "must be"); + CHECK_FATAL(opnd1->GetPrimType() == PTY_ref, "must be"); + CHECK_FATAL(opnd2->GetMeOp() == kMeOpVar, "must be"); + AddUseDef(*opnd1); + VarMeExpr *piLHS = piMeStmt->GetLHS(); + ESSAArrayNode *arrayNode = inequalityGraph->GetOrCreateArrayNode(*opnd1); + ESSAVarNode *piLHSNode = inequalityGraph->GetOrCreateVarNode(*piLHS); + (void)inequalityGraph->AddEdge(*arrayNode, *piLHSNode, -1, EdgeType::kNone); + (void)inequalityGraph->AddEdge(*piLHSNode, *(inequalityGraph->GetOrCreateConstNode(0)), 0, EdgeType::kNone); + return true; +} + +Opcode TransCmpOp(Opcode cmpOp, Opcode brOp) { + if (brOp == OP_brtrue) { + return cmpOp; + } + switch (cmpOp) { + case OP_ge: + return OP_lt; + case OP_le: + return OP_gt; + case OP_lt: + return OP_ge; + case OP_gt: + return OP_le; + case OP_ne: + return OP_eq; + case OP_eq: + return OP_ne; + default: + CHECK_FATAL(false, "must be"); + } +} + +bool MeABC::BuildBrMeStmtInGraph(MeStmt &meStmt) { + auto *brMeStmt = static_cast(&meStmt); + BB *brBB = brMeStmt->GetBB(); + BB *brTarget = brBB->GetSucc(1); + BB *brFallThru = brBB->GetSucc(0); + CHECK_FATAL(brMeStmt->GetOffset() == brTarget->GetBBLabel(), "must be"); + MapleMap> &brTargetPiBBList = brTarget->GetPiList(); + MapleMap> &brFallThruPiBBList = brFallThru->GetPiList(); + if (brTargetPiBBList.find(brBB) == brTargetPiBBList.end()) { + return false; + } + for (PiassignMeStmt* piMeStmt : brTargetPiBBList[brBB]) { + BuildSoloPiInGraph(*piMeStmt); + } + for (PiassignMeStmt* piMeStmt : brFallThruPiBBList[brBB]) { + BuildSoloPiInGraph(*piMeStmt); + } + std::vector &brTargetPiList = brTargetPiBBList[brBB]; + std::vector &brFallThruPiList = brFallThruPiBBList[brBB]; + ESSABaseNode *brTargetOpnd1 = nullptr; + ESSABaseNode *brTargetOpnd2 = nullptr; + ESSABaseNode *brFallThruOpnd1 = nullptr; + ESSABaseNode *brFallThruOpnd2 = nullptr; + auto *opMeExpr = static_cast(brMeStmt->GetOpnd()); + MeExpr *opOpnd1 = opMeExpr->GetOpnd(0); + MeExpr *opOpnd2 = opMeExpr->GetOpnd(1); + if (brTargetPiList.size() == kPiListSize) { + brTargetOpnd1 = inequalityGraph->GetOrCreateVarNode(*brTargetPiList[0]->GetLHS()); + brTargetOpnd2 = inequalityGraph->GetOrCreateVarNode(*brTargetPiList[1]->GetLHS()); + brFallThruOpnd1 = inequalityGraph->GetOrCreateVarNode(*brFallThruPiList.at(0)->GetLHS()); + brFallThruOpnd2 = inequalityGraph->GetOrCreateVarNode(*brFallThruPiList.at(1)->GetLHS()); + AddUseDef(*opOpnd1); + AddUseDef(*opOpnd2); + } else if (opOpnd1->GetMeOp() == kMeOpConst) { + brTargetOpnd1 = inequalityGraph->GetOrCreateConstNode(static_cast(opOpnd1)->GetIntValue()); + brTargetOpnd2 = inequalityGraph->GetOrCreateVarNode(*brTargetPiList[0]->GetLHS()); + brFallThruOpnd1 = inequalityGraph->GetOrCreateConstNode(static_cast(opOpnd1)->GetIntValue()); + brFallThruOpnd2 = inequalityGraph->GetOrCreateVarNode(*brFallThruPiList.at(0)->GetLHS()); + AddUseDef(*opOpnd2); + } else if (opOpnd2->GetMeOp() == kMeOpConst) { + brTargetOpnd1 = inequalityGraph->GetOrCreateVarNode(*brTargetPiList[0]->GetLHS()); + brTargetOpnd2 = inequalityGraph->GetOrCreateConstNode(static_cast(opOpnd2)->GetIntValue()); + brFallThruOpnd1 = inequalityGraph->GetOrCreateVarNode(*brFallThruPiList.at(0)->GetLHS()); + brFallThruOpnd2 = inequalityGraph->GetOrCreateConstNode(static_cast(opOpnd2)->GetIntValue()); + AddUseDef(*opOpnd1); + } else { + CHECK_FATAL(false, "impossible"); + } + Opcode cmpOp = TransCmpOp(opMeExpr->GetOp(), brMeStmt->GetOp()); + switch (cmpOp) { + case OP_ge: { + (void)inequalityGraph->AddEdge(*brTargetOpnd1, *brTargetOpnd2, 0, EdgeType::kNone); + (void)inequalityGraph->AddEdge(*brFallThruOpnd2, *brFallThruOpnd1, -1, EdgeType::kNone); + break; + } + case OP_le: { + (void)inequalityGraph->AddEdge(*brTargetOpnd2, *brTargetOpnd1, 0, EdgeType::kNone); + (void)inequalityGraph->AddEdge(*brFallThruOpnd1, *brFallThruOpnd2, -1, EdgeType::kNone); + break; + } + case OP_lt: { + (void)inequalityGraph->AddEdge(*brTargetOpnd2, *brTargetOpnd1, -1, EdgeType::kNone); + (void)inequalityGraph->AddEdge(*brFallThruOpnd1, *brFallThruOpnd2, 0, EdgeType::kNone); + break; + } + case OP_gt: { + (void)inequalityGraph->AddEdge(*brTargetOpnd1, *brTargetOpnd2, -1, EdgeType::kNone); + (void)inequalityGraph->AddEdge(*brFallThruOpnd2, *brFallThruOpnd1, 0, EdgeType::kNone); + break; + } + case OP_ne: { + InequalEdge *pairEdge1 = inequalityGraph->AddEdge(*brFallThruOpnd1, *brFallThruOpnd2, 0, EdgeType::kUpper); + InequalEdge *pairEdge2 = inequalityGraph->AddEdge(*brFallThruOpnd2, *brFallThruOpnd1, 0, EdgeType::kUpper); + pairEdge1->SetPairEdge(*pairEdge2); + pairEdge2->SetPairEdge(*pairEdge1); + pairEdge1 = inequalityGraph->AddEdge(*brFallThruOpnd2, *brFallThruOpnd1, 0, EdgeType::kLower); + pairEdge2 = inequalityGraph->AddEdge(*brFallThruOpnd1, *brFallThruOpnd2, 0, EdgeType::kLower); + pairEdge1->SetPairEdge(*pairEdge2); + pairEdge2->SetPairEdge(*pairEdge1); + break; + } + case OP_eq: { + InequalEdge *pairEdge1 = inequalityGraph->AddEdge(*brTargetOpnd1, *brTargetOpnd2, 0, EdgeType::kUpper); + InequalEdge *pairEdge2 = inequalityGraph->AddEdge(*brTargetOpnd2, *brTargetOpnd1, 0, EdgeType::kUpper); + pairEdge1->SetPairEdge(*pairEdge2); + pairEdge2->SetPairEdge(*pairEdge1); + pairEdge1 = inequalityGraph->AddEdge(*brTargetOpnd2, *brTargetOpnd1, 0, EdgeType::kLower); + pairEdge2 = inequalityGraph->AddEdge(*brTargetOpnd1, *brTargetOpnd2, 0, EdgeType::kLower); + pairEdge1->SetPairEdge(*pairEdge2); + pairEdge2->SetPairEdge(*pairEdge1); + break; + } + default: + CHECK_FATAL(false, "impossible"); + } + return true; +} + +MeExpr *MeABC::TryToResolveVar(MeExpr &expr, std::set &visitedPhi, MeExpr &dummyExpr, bool isConst) { + CHECK_FATAL(expr.GetMeOp() == kMeOpVar, "must be"); + auto *var = static_cast(&expr); + if (var->GetDefBy() == kDefByStmt && isConst && !var->GetDefStmt()->GetRHS()->IsLeaf()) { + return nullptr; + } + if (var->GetDefBy() == kDefByStmt && isConst && var->GetDefStmt()->GetRHS()->GetMeOp() == kMeOpConst) { + return var->GetDefStmt()->GetRHS(); + } + if (var->GetDefBy() == kDefByStmt && !isConst && var->GetDefStmt()->GetRHS()->GetMeOp() == kMeOpIvar) { + return var->GetDefStmt()->GetRHS(); + } + if (var->GetDefBy() == kDefByStmt && isConst) { + CHECK_FATAL(var->GetDefStmt()->GetRHS()->GetMeOp() == kMeOpVar, "must be"); + return TryToResolveVar(*(var->GetDefStmt()->GetRHS()), visitedPhi, dummyExpr, isConst); + } + + if (var->GetDefBy() == kDefByPhi) { + MeVarPhiNode *phi = &(var->GetDefPhi()); + if (visitedPhi.find(phi) != visitedPhi.end()) { + return &dummyExpr; + } + visitedPhi.insert(phi); + std::set res; + for (VarMeExpr *phiOpnd : phi->GetOpnds()) { + MeExpr *tmp = TryToResolveVar(*phiOpnd, visitedPhi, dummyExpr, isConst); + if (tmp == nullptr) { + return nullptr; + } + if (tmp != &dummyExpr) { + res.insert(tmp); + } + } + if (res.size() == 1) { + return *(res.begin()); + } else if (res.size() == 0) { + return &dummyExpr; + } + } + + return nullptr; +} + +bool MeABC::BuildAssignInGraph(MeStmt &meStmt) { + MeExpr *lhs = meStmt.GetLHS(); + MeExpr *rhs = meStmt.GetRHS(); + CHECK_NULL_FATAL(rhs); + if (!lhs->IsLeaf()) { + return false; + } + if (!IsPrimitivePureScalar(lhs->GetPrimType()) && rhs->GetOp() != OP_gcmallocjarray && + rhs->GetPrimType() != PTY_ref) { + return false; + } + if (!rhs->IsLeaf() && rhs->GetMeOp() != kMeOpOp && rhs->GetMeOp() != kMeOpNary && rhs->GetPrimType() != PTY_ref) { + return false; + } + if (rhs->GetMeOp() == kMeOpOp) { + auto *opMeExpr = static_cast(rhs); + switch (opMeExpr->GetOp()) { + case OP_gcmallocjarray: { + ESSAArrayNode *arrLength = inequalityGraph->GetOrCreateArrayNode(*lhs); + CHECK_FATAL(opMeExpr->GetNumOpnds() == 1, "must be"); + ESSABaseNode *rhsNode = nullptr; + if (opMeExpr->GetOpnd(0)->GetMeOp() == kMeOpVar) { + rhsNode = GetOrCreateRHSNode(*opMeExpr->GetOpnd(0)); + AddUseDef(*(opMeExpr->GetOpnd(0))); + // Try to resolve Var is assigned from Const + MeExpr *varExpr = opMeExpr->GetOpnd(0); + std::set visitedPhi; + ConstMeExpr dummyExpr(kInvalidExprID, nullptr); + varExpr = TryToResolveVar(*varExpr, visitedPhi, dummyExpr, true); + if (varExpr != nullptr && varExpr != &dummyExpr) { + CHECK_FATAL(varExpr->GetMeOp() == kMeOpConst, "must be"); + ESSAConstNode *constNode = inequalityGraph->GetOrCreateConstNode( + static_cast(varExpr)->GetIntValue()); + (void)inequalityGraph->AddEdge(*arrLength, *constNode, 0, EdgeType::kNone); + } + } else { + CHECK_FATAL(opMeExpr->GetOpnd(0)->GetMeOp() == kMeOpConst, "must be"); + rhsNode = inequalityGraph->GetOrCreateConstNode( + static_cast(opMeExpr->GetOpnd(0))->GetIntValue()); + } + (void)inequalityGraph->AddEdge(*arrLength, *rhsNode, 0, EdgeType::kNone); + return true; + } + case OP_sub: { + CHECK_FATAL(opMeExpr->GetNumOpnds() == kNumOpnds, "must be"); + MeExpr *opnd1 = opMeExpr->GetOpnd(0); + MeExpr *opnd2 = opMeExpr->GetOpnd(1); + if (!opnd1->IsLeaf() || !opnd2->IsLeaf()) { + return false; + } + ESSAVarNode *lhsNode = inequalityGraph->GetOrCreateVarNode(*lhs); + if (opnd1->GetMeOp() == kMeOpConst || opnd2->GetMeOp() == kMeOpConst) { + if (opnd1->GetMeOp() == kMeOpConst && opnd2->GetMeOp() == kMeOpConst) { + CHECK_FATAL(false, "consider this pattern"); + } else if (opnd2->GetMeOp() == kMeOpConst) { + ESSABaseNode *rhsNode = GetOrCreateRHSNode(*opnd1); + AddUseDef(*opnd1); + InequalEdge *pairEdge1 = inequalityGraph->AddEdge(*rhsNode, *lhsNode, + -static_cast(opnd2)->GetIntValue(), EdgeType::kUpper); + InequalEdge *pairEdge2 = inequalityGraph->AddEdge(*lhsNode, *rhsNode, + static_cast(opnd2)->GetIntValue(), EdgeType::kUpper); + pairEdge1->SetPairEdge(*pairEdge2); + pairEdge2->SetPairEdge(*pairEdge1); + pairEdge1 = inequalityGraph->AddEdge(*lhsNode, *rhsNode, + static_cast(opnd2)->GetIntValue(), EdgeType::kLower); + pairEdge2 = inequalityGraph->AddEdge(*rhsNode, *lhsNode, + -static_cast(opnd2)->GetIntValue(), EdgeType::kLower); + pairEdge1->SetPairEdge(*pairEdge2); + pairEdge2->SetPairEdge(*pairEdge1); + return true; + }else { + // support this pattern later + // CHECK_FATAL(false, "consider this pattern"); + return false; + } + } else if (opnd1->GetMeOp() == kMeOpVar && opnd2->GetMeOp() == kMeOpVar) { + // Try to resolve Var is assigned from Const + std::set visitedPhi; + ConstMeExpr dummyExpr(kInvalidExprID, nullptr); + opnd2 = TryToResolveVar(*opnd2, visitedPhi, dummyExpr, true); + if (opnd2 != nullptr && opnd2 != &dummyExpr) { + CHECK_FATAL(opnd2->GetMeOp() == kMeOpConst, "must be"); + ESSABaseNode *rhsNode = GetOrCreateRHSNode(*opnd1); + AddUseDef(*opnd1); + InequalEdge *pairEdge1 = inequalityGraph->AddEdge(*rhsNode, *lhsNode, + -static_cast(opnd2)->GetIntValue(), EdgeType::kUpper); + InequalEdge *pairEdge2 = inequalityGraph->AddEdge(*lhsNode, *rhsNode, + static_cast(opnd2)->GetIntValue(), EdgeType::kUpper); + pairEdge1->SetPairEdge(*pairEdge2); + pairEdge2->SetPairEdge(*pairEdge1); + pairEdge1 = inequalityGraph->AddEdge(*lhsNode, *rhsNode, + static_cast(opnd2)->GetIntValue(), EdgeType::kLower); + pairEdge2 = inequalityGraph->AddEdge(*rhsNode, *lhsNode, + -static_cast(opnd2)->GetIntValue(), EdgeType::kLower); + pairEdge1->SetPairEdge(*pairEdge2); + pairEdge2->SetPairEdge(*pairEdge1); + return true; + } else { + return false; + } + } else { + // support this pattern later + return false; + } + CHECK_FATAL(false, "impossible"); + } + case OP_add: { + CHECK_FATAL(opMeExpr->GetNumOpnds() == kNumOpnds, "must be"); + MeExpr *opnd1 = opMeExpr->GetOpnd(0); + MeExpr *opnd2 = opMeExpr->GetOpnd(1); + if (!opnd1->IsLeaf() || !opnd2->IsLeaf()) { + return false; + } + ESSAVarNode *lhsNode = inequalityGraph->GetOrCreateVarNode(*lhs); + if (opnd1->GetMeOp() == kMeOpConst || opnd2->GetMeOp() == kMeOpConst) { + if (opnd1->GetMeOp() == kMeOpConst && opnd2->GetMeOp() == kMeOpConst) { + CHECK_FATAL(false, "consider this pattern"); + } else if (opnd2->GetMeOp() == kMeOpConst) { + ESSABaseNode *rhsNode = GetOrCreateRHSNode(*opnd1); + AddUseDef(*opnd1); + InequalEdge *pairEdge1 = inequalityGraph->AddEdge(*rhsNode, *lhsNode, + static_cast(opnd2)->GetIntValue(), EdgeType::kUpper); + InequalEdge *pairEdge2 = inequalityGraph->AddEdge(*lhsNode, *rhsNode, + -static_cast(opnd2)->GetIntValue(), EdgeType::kUpper); + pairEdge1->SetPairEdge(*pairEdge2); + pairEdge2->SetPairEdge(*pairEdge1); + pairEdge1 = inequalityGraph->AddEdge(*lhsNode, *rhsNode, + -static_cast(opnd2)->GetIntValue(), EdgeType::kLower); + pairEdge2 = inequalityGraph->AddEdge(*rhsNode, *lhsNode, + static_cast(opnd2)->GetIntValue(), EdgeType::kLower); + pairEdge1->SetPairEdge(*pairEdge2); + pairEdge2->SetPairEdge(*pairEdge1); + return true; + } else { + ESSABaseNode *rhsNode = GetOrCreateRHSNode(*opnd2); + AddUseDef(*opnd2); + InequalEdge *pairEdge1 = inequalityGraph->AddEdge(*rhsNode, *lhsNode, + static_cast(opnd1)->GetIntValue(), EdgeType::kUpper); + InequalEdge *pairEdge2 = inequalityGraph->AddEdge(*lhsNode, *rhsNode, + -static_cast(opnd1)->GetIntValue(), EdgeType::kUpper); + pairEdge1->SetPairEdge(*pairEdge2); + pairEdge2->SetPairEdge(*pairEdge1); + pairEdge1 = inequalityGraph->AddEdge(*lhsNode, *rhsNode, + -static_cast(opnd1)->GetIntValue(), EdgeType::kLower); + pairEdge2 = inequalityGraph->AddEdge(*rhsNode, *lhsNode, + static_cast(opnd1)->GetIntValue(), EdgeType::kLower); + pairEdge1->SetPairEdge(*pairEdge2); + pairEdge2->SetPairEdge(*pairEdge1); + return true; + } + } else { + // support this pattern later + return false; + } + CHECK_FATAL(false, "impossible"); + } + case OP_band: { + CHECK_FATAL(opMeExpr->GetNumOpnds() == kNumOpnds, "must be"); + MeExpr *opnd1 = opMeExpr->GetOpnd(0); + MeExpr *opnd2 = opMeExpr->GetOpnd(1); + if (!opnd1->IsLeaf() || !opnd2->IsLeaf()) { + return false; + } + ESSAVarNode *lhsNode = inequalityGraph->GetOrCreateVarNode(*lhs); + ESSABaseNode *rhsNode1 = nullptr; + ESSABaseNode *rhsNode2 = nullptr; + if (IsUnsignedInteger(opnd1->GetPrimType())) { + AddUseDef(*opnd1); + rhsNode1 = GetOrCreateRHSNode(*opnd1); + } else if (opnd1->GetMeOp() == kMeOpConst && static_cast(opnd1)->GetIntValue() >= 0) { + rhsNode1 = inequalityGraph->GetOrCreateConstNode(static_cast(opnd1)->GetIntValue()); + } + if (IsUnsignedInteger(opnd2->GetPrimType())) { + AddUseDef(*opnd2); + rhsNode2 = GetOrCreateRHSNode(*opnd2); + } else if (opnd2->GetMeOp() == kMeOpConst && static_cast(opnd2)->GetIntValue() >= 0) { + rhsNode2 = inequalityGraph->GetOrCreateConstNode(static_cast(opnd2)->GetIntValue()); + } + if (rhsNode1 == nullptr && rhsNode2 == nullptr) { + return false; + } + if (rhsNode1 != nullptr) { + (void)inequalityGraph->AddEdge(*rhsNode1, *lhsNode, 0, EdgeType::kUpper); + } + if (rhsNode2 != nullptr) { + (void)inequalityGraph->AddEdge(*rhsNode2, *lhsNode, 0, EdgeType::kUpper); + } + (void)inequalityGraph->AddEdge(*lhsNode, *(inequalityGraph->GetOrCreateConstNode(0)), 0, EdgeType::kNone); + return true; + } + default: + return false; + } + } else if (rhs->GetMeOp() == kMeOpNary) { + auto *nary = static_cast(rhs); + if (nary->GetIntrinsic() != INTRN_JAVA_ARRAY_LENGTH) { + return false; + } + ESSAVarNode *lhsNode = inequalityGraph->GetOrCreateVarNode(*lhs); + CHECK_FATAL(nary->GetOpnds().size() == 1, "must be"); + MeExpr *array = nary->GetOpnd(0); + if (IsPrimitivePureScalar(array->GetPrimType())) { + return false; + } + CHECK_FATAL(array->GetPrimType() == PTY_ref, "must be"); + AddUseDef(*array); + ESSAArrayNode *arrLength = inequalityGraph->GetOrCreateArrayNode(*array); + (void)inequalityGraph->AddEdge(*arrLength, *lhsNode, 0, EdgeType::kUpper); + (void)inequalityGraph->AddEdge(*lhsNode, *arrLength, 0, EdgeType::kLower); + return true; + } else if (rhs->GetPrimType() == PTY_ref) { + if ((rhs->GetMeOp() == kMeOpVar || rhs->GetMeOp() == kMeOpIvar) && (lhs->GetPrimType() == PTY_ref)) { + ESSAVarNode *ivarNode = inequalityGraph->GetOrCreateVarNode(*rhs); + ESSAArrayNode *arrayNode = inequalityGraph->GetOrCreateArrayNode(*lhs); + InequalEdge *pairEdge1 = inequalityGraph->AddEdge(*ivarNode, *arrayNode, 0, EdgeType::kUpper); + InequalEdge *pairEdge2 = inequalityGraph->AddEdge(*arrayNode, *ivarNode, 0, EdgeType::kUpper); + pairEdge1->SetPairEdge(*pairEdge2); + pairEdge2->SetPairEdge(*pairEdge1); + return true; + } else { + return false; + } + } else { + CHECK_FATAL(rhs->GetMeOp() == kMeOpVar || rhs->GetMeOp() == kMeOpConst, "must be"); + ESSAVarNode *lhsNode = inequalityGraph->GetOrCreateVarNode(*lhs); + if (rhs->GetMeOp() == kMeOpVar) { + AddUseDef(*rhs); + ESSABaseNode *rhsNode = GetOrCreateRHSNode(*rhs); + InequalEdge *pairEdge1 = inequalityGraph->AddEdge(*rhsNode, *lhsNode, 0, EdgeType::kUpper); + InequalEdge *pairEdge2 = inequalityGraph->AddEdge(*lhsNode, *rhsNode, 0, EdgeType::kUpper); + pairEdge1->SetPairEdge(*pairEdge2); + pairEdge2->SetPairEdge(*pairEdge1); + pairEdge1 = inequalityGraph->AddEdge(*lhsNode, *rhsNode, 0, EdgeType::kLower); + pairEdge2 = inequalityGraph->AddEdge(*rhsNode, *lhsNode, 0, EdgeType::kLower); + pairEdge1->SetPairEdge(*pairEdge2); + pairEdge2->SetPairEdge(*pairEdge1); + } else { + ESSAConstNode *rhsNode = inequalityGraph->GetOrCreateConstNode(static_cast(rhs)->GetIntValue()); + InequalEdge *pairEdge1 = inequalityGraph->AddEdge(*rhsNode, *lhsNode, 0, EdgeType::kUpper); + InequalEdge *pairEdge2 = inequalityGraph->AddEdge(*lhsNode, *rhsNode, 0, EdgeType::kUpper); + pairEdge1->SetPairEdge(*pairEdge2); + pairEdge2->SetPairEdge(*pairEdge1); + pairEdge1 = inequalityGraph->AddEdge(*lhsNode, *rhsNode, 0, EdgeType::kLower); + pairEdge2 = inequalityGraph->AddEdge(*rhsNode, *lhsNode, 0, EdgeType::kLower); + pairEdge1->SetPairEdge(*pairEdge2); + pairEdge2->SetPairEdge(*pairEdge1); + } + return true; + } +} + +bool MeABC::BuildStmtInGraph(MeStmt &meStmt) { + bool validInsn = false; + switch (meStmt.GetOp()) { + case OP_dassign: + case OP_maydassign: { + validInsn = BuildAssignInGraph(meStmt); + break; + } + case OP_piassign: { + validInsn = BuildArrayCheckInGraph(meStmt); + break; + } + case OP_brfalse: + case OP_brtrue: { + validInsn = BuildBrMeStmtInGraph(meStmt); + break; + } + default: + break; + } + return validInsn; +} +void MeABC::AddCareInsn(MeStmt &defS) { + MeStmt *defStmt = &defS; + if (careMeStmts.find(defStmt) == careMeStmts.end()) { + CarePoint *carePoint = GetMemPool()->New(CarePoint::CareKind::kMeStmt); + carePoint->SetMeStmt(*defStmt); + carePoints.push_back(carePoint); + careMeStmts.insert(defStmt); + } +} +void MeABC::AddCarePhi(MeVarPhiNode &defP) { + MeVarPhiNode *defPhi = &defP; + if (careMePhis.find(defPhi) == careMePhis.end()) { + CarePoint *carePoint = GetMemPool()->New(CarePoint::CareKind::kMePhi); + carePoint->SetMePhi(*defPhi); + carePoints.push_back(carePoint); + careMePhis.insert(defPhi); + } +} +void MeABC::AddUseDef(MeExpr &meExpr) { + CHECK_FATAL(meExpr.GetMeOp() == kMeOpVar, "must be"); + auto *varOpnd1 = static_cast(&meExpr); + switch (varOpnd1->GetDefBy()) { + case kDefByStmt: { + MeStmt *meStmt = varOpnd1->GetDefStmt(); + MeStmt *defStmt = meStmt; + if (meStmt->GetOp() == OP_piassign) { + MeStmt *tmp = static_cast(meStmt)->GetGeneratedBy(); + if (tmp->IsCondBr()) { + defStmt = tmp; + } + } + AddCareInsn(*defStmt); + break; + } + case kDefByChi: { + MeStmt *defStmt = varOpnd1->GetDefChi().GetBase(); + AddCareInsn(*defStmt); + break; + } + case kDefByPhi: { + MeVarPhiNode *defPhi = &varOpnd1->GetDefPhi(); + AddCarePhi(*defPhi); + break; + } + case kDefByNo: { + CHECK_FATAL(varOpnd1->IsZeroVersion(irMap->GetSSATab()), "must be"); + break; + } + case kDefByMustDef: { + break; + } + } +} + +void MeABC::CollectCareInsns() { + for (auto pair : arrayChecks) { + MeStmt *meStmt = pair.first; + for (size_t iii = 0; iii < meStmt->NumMeStmtOpnds(); ++iii) { + ABCCollectArrayExpr(*meStmt, *(meStmt->GetOpnd(iii)), true); + } + } + CHECK_FATAL(arrayNewChecks.size() == arrayChecks.size(), "must be"); +} + +void MeABC::BuildInequalityGraph() { + for (size_t i = 0; i < carePoints.size(); ++i) { + CarePoint *cp = carePoints[i]; + if (cp->IsCareMeStmt()) { + (void)BuildStmtInGraph(*(cp->GetMeStmt())); + } else { + BuildPhiInGraph(*(cp->GetMePhi())); + } + } + inequalityGraph->ConnectTrivalEdge(); +} + +void MeABC::FindRedundantABC(MeStmt &meStmt, NaryMeExpr &naryMeExpr) { + MeExpr *opnd1 = naryMeExpr.GetOpnd(0); + MeExpr *opnd2 = naryMeExpr.GetOpnd(1); + CHECK_FATAL(opnd1->GetMeOp() == kMeOpVar && opnd1->GetPrimType() == PTY_ref, "must be"); + if (!inequalityGraph->HasNode(*opnd1)) { + if (MeABC::kDebug) { + LogInfo::MapleLogger() << "Array Node Not Found" << '\n'; + meStmt.Dump(irMap); + } + return; + } + if (opnd2->GetMeOp() == kMeOpVar && !inequalityGraph->HasNode(*opnd2)) { + if (MeABC::kDebug) { + LogInfo::MapleLogger() << "Array Index Not Found" << '\n'; + meStmt.Dump(irMap); + } + return; + } + if (prove->DemandProve(*opnd1, *opnd2)) { + if (MeABC::kDebug) { + LogInfo::MapleLogger() << "Find One OPT" << '\n'; + meStmt.Dump(irMap); + } + targetMeStmt.insert(&meStmt); + } else { + if (MeABC::kDebug) { + LogInfo::MapleLogger() << "Can not OPT" << '\n'; + meStmt.Dump(irMap); + } + } +} + +MeExpr *MeABC::ReplaceArrayExpr(MeExpr &rhs, MeExpr &naryMeExpr, MeStmt *ivarStmt) { + if (rhs.IsLeaf()) { + return nullptr; + } + if (&rhs == &naryMeExpr) { + auto *oldNaryMeExpr = static_cast(&naryMeExpr); + NaryMeExpr tmpNaryMeExpr(&(irMap->GetIRMapAlloc()), kInvalidExprID, *oldNaryMeExpr); + CHECK_FATAL(tmpNaryMeExpr.GetBoundCheck(), "must be"); + tmpNaryMeExpr.SetBoundCheck(false); + MeExpr *newNaryMeExpr = irMap->HashMeExpr(tmpNaryMeExpr); + return newNaryMeExpr; + } + CHECK_FATAL(rhs.GetMeOp() == kMeOpIvar, "must be"); + MeExpr *newBase = ReplaceArrayExpr(*static_cast(rhs).GetBase(), naryMeExpr, ivarStmt); + CHECK_FATAL(newBase, "must be"); + MeExpr *newIvarExpr = nullptr; + if (ivarStmt == nullptr) { + auto *oldIvarExpr = static_cast(&rhs); + IvarMeExpr tmpIvarMeExpr(kInvalidExprID, *oldIvarExpr); + tmpIvarMeExpr.SetBase(newBase); + newIvarExpr = irMap->HashMeExpr(tmpIvarMeExpr); + } else { + auto &iassingMeStmt = *static_cast(ivarStmt); + newIvarExpr = irMap->BuildLHSIvar(*newBase, iassingMeStmt, iassingMeStmt.GetLHSVal()->GetFieldID()); + } + return newIvarExpr; +} + +bool MeABC::CleanABCInStmt(MeStmt &meStmt, NaryMeExpr &naryMeExpr) { + bool replaced = false; + switch (meStmt.GetOp()) { + case OP_dassign: + case OP_maydassign: { + MeExpr *rhs = meStmt.GetRHS(); + CHECK_FATAL(!rhs->IsLeaf(), "must be"); + MeExpr *newRHS = ReplaceArrayExpr(*rhs, naryMeExpr, nullptr); + replaced = rhs != newRHS; + meStmt.SetOpnd(0, newRHS); + break; + } + case OP_iassign: { + CHECK_FATAL(meStmt.GetRHS()->IsLeaf(), "must be"); + MeExpr *lhs = static_cast(&meStmt)->GetLHSVal(); + MeExpr *newLHS = ReplaceArrayExpr(*lhs, naryMeExpr, &meStmt); + replaced = lhs != newLHS; + static_cast(&meStmt)->SetLHSVal(static_cast(newLHS)); + break; + } + default: + CHECK_FATAL(false, "must be"); + } + return replaced; +} + +void MeABC::DeleteABC() { + for (MeStmt *meStmt : targetMeStmt) { + NaryMeExpr *naryMeExpr = arrayChecks[meStmt]; + bool replaced = CleanABCInStmt(*meStmt, *naryMeExpr); + CHECK_FATAL(replaced, "must be"); + } +} + +void MeABC::InitNewStartPoint(MeStmt &meStmt, NaryMeExpr &nMeExpr) { + careMeStmts.clear(); + careMePhis.clear(); + carePoints.clear(); + inequalityGraph = std::make_unique(*meFunc); + CHECK_FATAL(inequalityGraph != nullptr, "inequalityGraph is nullptr"); + prove = std::make_unique(*inequalityGraph); + CHECK_FATAL(prove != nullptr, "prove is nullptr"); + CHECK_FATAL(nMeExpr.GetNumOpnds() == kNumOpnds, "msut be"); + MeExpr *opnd1 = nMeExpr.GetOpnd(0); + MeExpr *opnd2 = nMeExpr.GetOpnd(1); + CHECK_FATAL(opnd1->GetMeOp() == kMeOpVar, "must be"); + AddUseDef(*opnd1); + if (opnd2->GetMeOp() == kMeOpVar) { + AddUseDef(*opnd2); + } else { + CHECK_FATAL(opnd2->GetMeOp() == kMeOpConst, "must be"); + (void)inequalityGraph->GetOrCreateConstNode(static_cast(opnd2)->GetIntValue()); + } + BB *curBB = meStmt.GetBB(); + if (curBB->GetPiList().size()) { + for (auto pair : curBB->GetPiList()) { + CHECK_FATAL(pair.second.size() >= 1, "must be"); + PiassignMeStmt *pi = pair.second[0]; + AddUseDef(*pi->GetLHS()); + } + } + forbidenPi = meStmt.GetNextMeStmt(); + CHECK_FATAL(forbidenPi != nullptr, "forbidenPi is nullptr"); + CHECK_FATAL(forbidenPi->GetOp() == OP_piassign, "must be"); +} + +void MeABC::executeABCO() { + MeABC::kDebug = false; + if (CollectABC()) { + if (MeABC::kDebug) { + LogInfo::MapleLogger() << meFunc->GetName() << "\n"; + irMap->Dump(); + } + InsertPiNodes(); + InsertPhiNodes(); + Rename(); + CollectCareInsns(); + for (auto pair : arrayNewChecks) { + InitNewStartPoint(*(pair.first), *(static_cast(pair.second))); + BuildInequalityGraph(); + if (MeABC::kDebug) { + meFunc->GetTheCfg()->DumpToFile(meFunc->GetName()); + inequalityGraph->DumpDotFile(*irMap, DumpType::kDumpUpperAndNone); + inequalityGraph->DumpDotFile(*irMap, DumpType::kDumpLowerAndNone); + } + FindRedundantABC(*(pair.first), *(static_cast(pair.second))); + } + RemoveExtraNodes(); + DeleteABC(); + inequalityGraph = nullptr; + prove = nullptr; + } +} + +AnalysisResult *MeDoABCOpt::Run(MeFunction *func, MeFuncResultMgr *frm, ModuleResultMgr*) { + if (func->GetSecondPass()) { + return nullptr; + } + CHECK_FATAL(frm != nullptr, "frm is nullptr"); + auto *dom = static_cast(frm->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); + CHECK_FATAL(dom != nullptr, "dominance phase has problem"); + auto *irMap = static_cast(frm->GetAnalysisResult(MeFuncPhase_IRMAP, func)); + CHECK_FATAL(irMap != nullptr, "irMap phase has problem"); + MemPool *abcoMemPool = memPoolCtrler.NewMemPool(PhaseName()); + MeABC meABC(*func, *dom, *irMap, *abcoMemPool); + meABC.executeABCO(); + if (DEBUGFUNC(func)) { + LogInfo::MapleLogger() << "\n============== After boundary check optimization =============" << std::endl; + irMap->Dump(); + } + return nullptr; +} +} diff --git a/src/maple_me/src/me_bypath_eh.cpp b/src/maple_me/src/me_bypath_eh.cpp index b345d6d14583e20b3d9f9fb3964e75ec101863b0..0432ed1b0ab0ecaeb3c06a9aaafc685b79aa8051 100644 --- a/src/maple_me/src/me_bypath_eh.cpp +++ b/src/maple_me/src/me_bypath_eh.cpp @@ -37,8 +37,8 @@ bool MeDoBypathEH::DoBypathException(BB *tryBB, BB *catchBB, Klass *catchClass, auto *node = static_cast(stmt); BaseNode *rhExpr = nullptr; Klass *throwClass = nullptr; - if (node->Opnd()->GetOpCode() == OP_dread) { - auto *dread = static_cast(node->Opnd()); + if (node->Opnd(0)->GetOpCode() == OP_dread) { + auto *dread = static_cast(node->Opnd(0)); StIdx ehObjIdx = dread->GetStIdx(); const MIRSymbol *ehObjSymbol = func->GetMirFunc()->GetLocalOrGlobalSymbol(ehObjIdx); MIRType *pType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ehObjSymbol->GetTyIdx()); @@ -46,8 +46,8 @@ bool MeDoBypathEH::DoBypathException(BB *tryBB, BB *catchBB, Klass *catchClass, TyIdx pTypeIdx = (static_cast(pType))->GetPointedType()->GetTypeIndex(); throwClass = kh->GetKlassFromTyIdx(pTypeIdx); rhExpr = dread; - } else if (node->Opnd()->GetOpCode() == OP_iread) { - auto *iread = static_cast(node->Opnd()); + } else if (node->Opnd(0)->GetOpCode() == OP_iread) { + auto *iread = static_cast(node->Opnd(0)); MIRType *pType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread->GetTyIdx()); CHECK_FATAL(pType->GetKind() == kTypePointer, "must be pointer"); TyIdx pTypeIdx = (static_cast(pType))->GetPointedType()->GetTypeIndex(); diff --git a/src/maple_me/src/me_inequality_graph.cpp b/src/maple_me/src/me_inequality_graph.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ce64b20ec6a8e4617528d178af6caf2d937c89ae --- /dev/null +++ b/src/maple_me/src/me_inequality_graph.cpp @@ -0,0 +1,437 @@ +/* + * Copyright (c) [2019] Huawei Technologies Co.,Ltd.All rights reserved. + * + * OpenArkCompiler is licensed under the Mulan PSL v1. + * You can use this software according to the terms and conditions of the Mulan PSL v1. + * You may obtain a copy of Mulan PSL v1 at: + * + * http://license.coscl.org.cn/MulanPSL + * + * 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 v1 for more details. + */ +#include "me_inequality_graph.h" + +namespace maple { + ESSAConstNode *InequalityGraph::GetOrCreateConstNode(int value) { + if (HasNode(value)) { + return static_cast(constNodes[value]); + } + ESSAConstNode *newConstNode = new ESSAConstNode(GetValidID(), value); + CHECK_FATAL(newConstNode != nullptr, "new failed"); + constNodes[value] = newConstNode; + return newConstNode; + } + + ESSAVarNode *InequalityGraph::GetOrCreateVarNode(MeExpr &meExpr) { + if (HasNode(meExpr)) { + return static_cast(varNodes[meExpr.GetExprID()]); + } + CHECK_FATAL(meExpr.GetMeOp() == kMeOpVar || meExpr.GetMeOp() == kMeOpIvar, "meExpr must be VarMeExpr"); + ESSAVarNode *newVarNode = new ESSAVarNode(GetValidID(), meExpr); + CHECK_FATAL(newVarNode != nullptr, "new failed"); + varNodes[meExpr.GetExprID()] = newVarNode; + return newVarNode; + } + + ESSAPhiNode *InequalityGraph::GetOrCreatePhiNode(MeVarPhiNode &phiNode) { + MeExpr *expr = phiNode.GetLHS(); + CHECK_FATAL(expr != nullptr, "meExpr phiNode must has lhs"); + if (HasNode(*expr)) { + return static_cast(varNodes[expr->GetExprID()]); + } + CHECK_FATAL(expr->GetMeOp() == kMeOpVar, "meExpr must be VarMeExpr"); + ESSAPhiNode *newPhiNode = new ESSAPhiNode(GetValidID(), *expr); + CHECK_FATAL(newPhiNode != nullptr, "new failed"); + newPhiNode->SetPhiOpnds(phiNode.GetOpnds()); + varNodes[expr->GetExprID()] = newPhiNode; + for (VarMeExpr *phiRHS : phiNode.GetOpnds()) { + ESSABaseNode *rhs = nullptr; + if (phiRHS->GetDefBy() != kDefByPhi) { + rhs = GetOrCreateVarNode(*phiRHS); + } else { + MeVarPhiNode *defPhi = &(phiRHS->GetDefPhi()); + rhs = GetOrCreatePhiNode(*defPhi); + } + AddPhiEdge(*rhs, *newPhiNode, EdgeType::kUpper); + AddPhiEdge(*newPhiNode, *rhs, EdgeType::kLower); + } + CHECK_FATAL(newPhiNode->GetPhiOpnds().size() == newPhiNode->GetInPhiEdgeMap().size(), "must be"); + return newPhiNode; + } + + ESSAArrayNode *InequalityGraph::GetOrCreateArrayNode(MeExpr &meExpr) { + if (HasNode(meExpr)) { + return static_cast(varNodes[meExpr.GetExprID()]); + } + CHECK_FATAL(meExpr.GetMeOp() == kMeOpVar, "meExpr must be VarMeExpr"); + ESSAArrayNode *newArrayNode = new ESSAArrayNode(GetValidID(), meExpr); + CHECK_FATAL(newArrayNode != nullptr, "new failed"); + varNodes[meExpr.GetExprID()] = newArrayNode; + return newArrayNode; + } + + InequalEdge *InequalityGraph::AddEdge(ESSABaseNode &from, ESSABaseNode &to, int value, EdgeType type) { + InequalEdge tmpEdge = InequalEdge(value, type); + InequalEdge *edge = HasEdge(from, to, tmpEdge); + if (edge != nullptr) { + return edge; + } + edge = new InequalEdge(value, type); + CHECK_FATAL(edge != nullptr, "new failed"); + from.InsertOutWithConstEdgeMap(to, *edge); + to.InsertInWithConstEdgeMap(from, *edge); + return edge; + } + + void InequalityGraph::AddPhiEdge(ESSABaseNode &from, ESSABaseNode &to, EdgeType type) { + InequalEdge *edge = new InequalEdge(0, type); + CHECK_FATAL(edge != nullptr, "new failed"); + if (type == EdgeType::kUpper) { + from.InsertOutWithConstEdgeMap(to, *edge); + CHECK_FATAL(to.GetKind() == kPhiNode, "must be"); + static_cast(to).InsertInPhiEdgeMap(from, *edge); + } else { + CHECK_FATAL(from.GetKind() == kPhiNode, "must be"); + static_cast(from).InsertOutPhiEdgeMap(to, *edge); + to.InsertInWithConstEdgeMap(from, *edge); + } + } + + void InequalityGraph::AddEdge(ESSABaseNode &from, ESSABaseNode &to, MeExpr &value, bool positive, EdgeType type) { + InequalEdge tmpEdge = InequalEdge(value, positive, type); + if (HasEdge(from, to, tmpEdge)) { + return; + } + InequalEdge *edge = new InequalEdge(value, positive, type); + CHECK_FATAL(edge != nullptr, "new failed"); + from.InsertOutWithVarEdgeMap(to, *edge); + to.InsertInWithVarEdgeMap(from, *edge); + } + + bool InequalityGraph::HasNode(MeExpr &meExpr) const { + return (varNodes.find(meExpr.GetExprID()) == varNodes.end()) ? false : true; + } + + bool InequalityGraph::HasNode(int32 value) const { + return (constNodes.find(value) == constNodes.end()) ? false : true; + } + + void InequalityGraph::ConnectTrivalEdge() { + int32 prevValue = 0; + ESSABaseNode* prevNode = nullptr; + for (auto pair : constNodes) { + int32 value = pair.first; + ESSABaseNode* node = pair.second; + if (prevNode == nullptr) { + prevValue = value; + prevNode = node; + continue; + } + CHECK_FATAL(value > prevValue, "must be"); + InequalEdge *pairEdge1 = AddEdge(*node, *prevNode, prevValue - value, EdgeType::kNone); + InequalEdge *pairEdge2 = AddEdge(*prevNode, *node, value - prevValue, EdgeType::kNone); + pairEdge1->SetPairEdge(*pairEdge2); + pairEdge2->SetPairEdge(*pairEdge1); + prevValue = value; + prevNode = node; + } + } + + ESSABaseNode &InequalityGraph::GetNode(MeExpr &meExpr) { + CHECK_FATAL(HasNode(meExpr), "node is not created"); + return *varNodes[meExpr.GetExprID()]; + } + + ESSABaseNode &InequalityGraph::GetNode(int32 value) { + CHECK_FATAL(HasNode(value), "node is not created"); + return *constNodes[value]; + } + + InequalEdge *InequalityGraph::HasEdge(ESSABaseNode &from, ESSABaseNode &to, InequalEdge &type) const { + auto miter = from.GetOutWithConstEdgeMap().equal_range(&to); + for (auto it = miter.first; it != miter.second; ++it) { + if (it->second->IsSame(type)) { + return it->second; + } + } + miter = from.GetOutWithVarEdgeMap().equal_range(&to); + for (auto it = miter.first; it != miter.second; ++it) { + if (it->second->IsSame(type)) { + return it->second; + } + } + return nullptr; + } + + std::string InequalityGraph::GetName(const MeExpr &meExpr, IRMap &irMap) const { + std::string name; + MeExprOp meOp = meExpr.GetMeOp(); + CHECK_FATAL(meOp == kMeOpVar, "must be VarMeExpr"); + const auto *varMeExpr = static_cast(&meExpr); + MIRSymbol *sym = irMap.GetSSATab().GetMIRSymbolFromID(varMeExpr->GetOStIdx()); + name = sym->GetName() + "\\nmx" + std::to_string(meExpr.GetExprID()); + return name; + } + + std::string InequalityGraph::GetName(ESSABaseNode &node, IRMap &irMap) const { + std::string name; + if (node.GetKind() == kConstNode) { + return std::to_string((*static_cast(&node)).GetValue()); + } + const MeExpr *meExpr = &(node.GetMeExpr()); + CHECK_FATAL(meExpr != nullptr, "meExpr is nullptr"); + const VarMeExpr *varMeExpr = nullptr; + if (meExpr->GetMeOp() == kMeOpVar) { + varMeExpr = static_cast(meExpr); + } else if (meExpr->GetMeOp() == kMeOpIvar) { + const auto *ivarMeExpr = static_cast(meExpr); + const MeExpr *base = ivarMeExpr->GetBase(); + if (base->GetMeOp() == kMeOpVar) { + varMeExpr = static_cast(base); + } else { + name = "ivar" + std::to_string(ivarMeExpr->GetExprID()); + return name; + } + } + MIRSymbol *sym = irMap.GetSSATab().GetMIRSymbolFromID(varMeExpr->GetOStIdx()); + name = sym->GetName() + "\\nmx" + std::to_string(meExpr->GetExprID()); + if (node.GetKind() == kArrayNode) { + name += ".length"; + } else if (node.GetKind() == kPhiNode) { + name += " = phi("; + for (auto iter = (*static_cast(&node)).GetPhiOpnds().begin(); + iter != (*static_cast(&node)).GetPhiOpnds().end(); ++iter) { + name += "mx" + std::to_string((*iter)->GetExprID()) + ", "; + } + name += ")"; + } + name += "\\nID: " + std::to_string(node.GetID()); + return name; + } + + std::string InequalityGraph::GetColor(EdgeType type) const { + switch (type) { + case kUpper: + return "color = red"; + case kUpperInvalid: + return "color = red, style=dashed"; + case kLower: + return "color = blue"; + case kLowerInvalid: + return "color = blue, style=dashed"; + case kNone: + return "color = black"; + case kNoneInValid: + return "color = black, style=dashed"; + } + } + + void InequalityGraph::DumpDotEdges(IRMap &irMap, const std::pair &map, + std::ostream &out, std::string &from) const { + if (map.second->IsVarValue()) { + std::string to = GetName(*(map.first), irMap); + std::string positive = map.second->GetVarValue().IsPositive() ? "" : "-"; + std::string color = GetColor(map.second->GetEdgeType()); + out << "\"" << from << "\" -> \"" << to << "\" "; + out << "[label=\"" << positive << GetName(map.second->GetVarValue().GetVarMeExpr(), irMap) + << "\" " << color << "];\n"; + } else { + std::string to = GetName(*(map.first), irMap); + std::string color = GetColor(map.second->GetEdgeType()); + out << "\"" << from << "\" -> \"" << to << "\" "; + out << "[label=\"" << map.second->GetConstValue() << "\" " << color << "];\n"; + } + } + + void InequalityGraph::DumpDotNodes(IRMap &irMap, std::ostream &out, DumpType dumpType, + std::map nodes) const { + for (auto iter = nodes.begin(); iter != nodes.end(); ++iter) { + std::string from = GetName(*(iter->second), irMap); + out << "\"" << from << "\";\n"; + for (auto iterConstEdges = iter->second->GetOutWithConstEdgeMap().begin(); + iterConstEdges != iter->second->GetOutWithConstEdgeMap().end(); ++iterConstEdges) { + EdgeType edgeType = iterConstEdges->second->GetEdgeType(); + if (dumpType == kDumpNone) { + DumpDotEdges(irMap, *iterConstEdges, out, from); + } else if ((dumpType == kDumpUpperAndNone) && + (edgeType == kUpper || edgeType == kNone || edgeType == kUpperInvalid || edgeType == kNoneInValid)) { + DumpDotEdges(irMap, *iterConstEdges, out, from); + } else if ((dumpType == kDumpLowerAndNone) && + (edgeType == kLower || edgeType == kNone || edgeType == kLowerInvalid || edgeType == kNoneInValid)) { + DumpDotEdges(irMap, *iterConstEdges, out, from); + } + } + if (iter->second->GetKind() == kPhiNode) { + auto *phiNode = static_cast(iter->second); + for (auto iterConstEdges = phiNode->GetOutPhiEdgeMap().begin(); + iterConstEdges != phiNode->GetOutPhiEdgeMap().end(); ++iterConstEdges) { + EdgeType edgeType = iterConstEdges->second->GetEdgeType(); + if (dumpType == kDumpNone) { + DumpDotEdges(irMap, *iterConstEdges, out, from); + } else if ((dumpType == kDumpUpperAndNone) && + (edgeType == kUpper || edgeType == kNone || + edgeType == kUpperInvalid || edgeType == kNoneInValid)) { + DumpDotEdges(irMap, *iterConstEdges, out, from); + } else if ((dumpType == kDumpLowerAndNone) && + (edgeType == kLower || edgeType == kNone || + edgeType == kLowerInvalid || edgeType == kNoneInValid)) { + DumpDotEdges(irMap, *iterConstEdges, out, from); + } + } + } + for (auto iterVarEdges = iter->second->GetOutWithVarEdgeMap().begin(); + iterVarEdges != iter->second->GetOutWithVarEdgeMap().end(); ++iterVarEdges) { + EdgeType edgeType = iterVarEdges->second->GetEdgeType(); + if (dumpType == kDumpNone) { + DumpDotEdges(irMap, *iterVarEdges, out, from); + } else if ((dumpType == kDumpUpperAndNone) && + (edgeType == kUpper || edgeType == kNone || edgeType == kUpperInvalid || edgeType == kNoneInValid)) { + DumpDotEdges(irMap, *iterVarEdges, out, from); + } else if ((dumpType == kDumpLowerAndNone) && + (edgeType == kLower || edgeType == kNone || edgeType == kLowerInvalid || edgeType == kNoneInValid)) { + DumpDotEdges(irMap, *iterVarEdges, out, from); + } + } + } + } + + void InequalityGraph::DumpDotFile(IRMap &irMap, DumpType dumpType) const { + std::filebuf fileBuf; + std::string dumpT = dumpType == kDumpUpperAndNone ? "Upper_" : "Lower_"; + std::string outFile = dumpT + meFunction->GetName() + "-inequalityGraph.dot"; + fileBuf.open(outFile, std::ios::trunc | std::ios::out); + std::ostream essaDotFile(&fileBuf); + essaDotFile << "digraph InequalityGraph {\n"; + DumpDotNodes(irMap, essaDotFile, dumpType, constNodes); + DumpDotNodes(irMap, essaDotFile, dumpType, varNodes); + essaDotFile << "}\n"; + fileBuf.close(); + } + + bool ABCD::DemandProve(MeExpr &arrayNode, MeExpr &idx) { + ESSABaseNode &aNode = inequalityGraph->GetNode(arrayNode); + ESSABaseNode *idxNode = nullptr; + if (idx.GetMeOp() == kMeOpVar) { + idxNode = &(inequalityGraph->GetNode(idx)); + } else { + CHECK_FATAL(idx.GetMeOp() == kMeOpConst, "must be"); + idxNode = &(inequalityGraph->GetNode(static_cast(idx).GetIntValue())); + } + ESSABaseNode &zNode = inequalityGraph->GetNode(0); + bool upperResult = ABCD::DemandProve(aNode, *idxNode, kUpper); + bool lowerResult = ABCD::DemandProve(zNode, *idxNode, kLower); + return upperResult && lowerResult; + } + + bool ABCD::DemandProve(ESSABaseNode &aNode, ESSABaseNode &bNode, EdgeType eType) { + InequalEdge *e = eType == kUpper ? new InequalEdge(kUpperBound, eType) : new InequalEdge(kLowerBound, eType); + active.clear(); + ProveResult res = Prove(aNode, bNode, *e); + delete(e); + return res == kTrue; + } + + void ABCD::PrintTracing() { + for (size_t i = 0; i < tracing.size(); i++) { + std::cout << "Traversing Node : " << tracing[i]->GetExprID() << '\n'; + } + std::cout << '\n'; + } + + ProveResult ABCD::Prove(ESSABaseNode &aNode, ESSABaseNode &bNode, InequalEdge &edge) { + ++recursiveCount; + if (recursiveCount > kDFSLimit) { + return kFalse; + } + // std::cout << "Traversing Node : " << bNode.GetExprID() << '\n'; + tracing.push_back(&bNode); + if (&aNode == &bNode) { + if (edge.geq(0)) { + tracing.pop_back(); + return kTrue; + } else { + tracing.pop_back(); + return kFalse; + } + } + bool hasPreNode = false; + auto constEdge = (edge.GetEdgeType() == kUpper) ? bNode.GetInWithConstEdgeMap() : bNode.GetOutWithConstEdgeMap(); + for (auto iter = constEdge.begin(); iter != constEdge.end(); ++iter) { + if (iter->second->GetEdgeType() == edge.GetEdgeType() || iter->second->GetEdgeType() == EdgeType::kNone) { + hasPreNode = true; + break; + } + } + if (bNode.GetKind() == kPhiNode) { + hasPreNode = true; + } + if (!hasPreNode) { + tracing.pop_back(); + return kFalse; + } + + if (active.find(&bNode) != active.end()) { + if (active.find(&bNode)->second->leq(edge)) { + tracing.pop_back(); + return kReduced; + } else { + tracing.pop_back(); + return kFalse; + } + } + + active[&bNode] = &edge; + ProveResult res = bNode.GetKind() == kPhiNode ? UpdateCacheResult(aNode, bNode, edge, min) + : UpdateCacheResult(aNode, bNode, edge, max); + active.erase(&bNode); + tracing.pop_back(); + return res; + } + + ProveResult ABCD::UpdateCacheResult(ESSABaseNode &aNode, ESSABaseNode &bNode, InequalEdge &edge, meet_function meet) { + ProveResult res = meet == min ? kReduced : kFalse; + if (meet == min) { + CHECK_FATAL(bNode.GetKind() == kPhiNode, "must be"); + auto& bPhiNode = static_cast(bNode); + auto constEdgeMap = (edge.GetEdgeType() == kUpper) ? bPhiNode.GetInPhiEdgeMap() : bPhiNode.GetOutPhiEdgeMap(); + for (auto iter = constEdgeMap.begin(); iter != constEdgeMap.end(); ++iter) { + if (((res == kTrue) && (meet == max)) || ((res == kFalse) && (meet == min))) { + break; + } + InequalEdge *in = iter->second; + if (in->GetEdgeType() == edge.GetEdgeType() || in->GetEdgeType() == kNone) { + InequalEdge nextEdge(edge, *in); + if (in->GetPairEdge()) { + in->GetPairEdge()->SetEdgeTypeInValid(); + } + res = meet(res, Prove(aNode, *(iter->first), nextEdge)); + if (in->GetPairEdge()) { + in->GetPairEdge()->SetEdgeTypeValid(); + } + } + } + } + auto constEdgeMap = (edge.GetEdgeType() == kUpper) ? bNode.GetInWithConstEdgeMap() : bNode.GetOutWithConstEdgeMap(); + for (auto iter = constEdgeMap.begin(); iter != constEdgeMap.end(); ++iter) { + if (res == kTrue) { + break; + } + InequalEdge *in = iter->second; + if (in->GetEdgeType() == edge.GetEdgeType() || in->GetEdgeType() == kNone) { + InequalEdge nextEdge(edge, *in); + if (in->GetPairEdge()) { + in->GetPairEdge()->SetEdgeTypeInValid(); + } + res = max(res, Prove(aNode, *(iter->first), nextEdge)); + if (in->GetPairEdge()) { + in->GetPairEdge()->SetEdgeTypeValid(); + } + } + } + + return res; + } +} // namespace maple diff --git a/src/maple_me/src/ver_symbol.cpp b/src/maple_me/src/ver_symbol.cpp index fab15a05021b843654ca259529d2ac56bd6678d7..b8226cf71aaa04d8b187b3ec4a0f47c2558cbb58 100644 --- a/src/maple_me/src/ver_symbol.cpp +++ b/src/maple_me/src/ver_symbol.cpp @@ -19,7 +19,7 @@ namespace maple { VersionSt VersionStTable::dummyVST(0, 0, nullptr); -void VersionSt::DumpDefStmt(const MIRModule *mod) const { +void VersionSt::DumpDefStmt(const MIRModule*) const { if (version <= 0) { return; } diff --git a/src/mpl2mpl/src/java_eh_lower.cpp b/src/mpl2mpl/src/java_eh_lower.cpp index 3c56ff4ee5ec91ef17705f82f26b0438ba6ca910..c2ebca05af2bb077214a13251fdbca1e6b65d74b 100644 --- a/src/mpl2mpl/src/java_eh_lower.cpp +++ b/src/mpl2mpl/src/java_eh_lower.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2019] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. @@ -114,7 +114,7 @@ void JavaEHLowerer::DoLowerBoundaryCheck(IntrinsiccallNode &intrincall, BlockNod const size_t intrincallNopndSize = intrincall.GetNopndSize(); CHECK_FATAL(intrincallNopndSize > 0, "null ptr check"); CondGotoNode *brFalseStmt = GetMIRModule().CurFuncCodeMemPool()->New(OP_brfalse); - brFalseStmt->SetOpnd(DoLowerExpr(*(intrincall.GetNopndAt(0)), newblk)); + brFalseStmt->SetOpnd(DoLowerExpr(*(intrincall.GetNopndAt(0)), newblk), 0); brFalseStmt->SetSrcPos(intrincall.GetSrcPos()); LabelIdx lbidx = GetMIRModule().CurFunction()->GetLabelTab()->CreateLabel(); GetMIRModule().CurFunction()->GetLabelTab()->AddToStringLabelMap(lbidx); @@ -154,7 +154,7 @@ BlockNode *JavaEHLowerer::DoLowerBlock(BlockNode &block) { BlockNode *thenPart = ifStmtNode->GetThenPart(); BlockNode *elsePart = ifStmtNode->GetElsePart(); ASSERT(ifStmtNode->Opnd() != nullptr, "null ptr check!"); - ifStmtNode->SetOpnd(DoLowerExpr(*(ifStmtNode->Opnd()), *newBlock)); + ifStmtNode->SetOpnd(DoLowerExpr(*(ifStmtNode->Opnd()), *newBlock), 0); ifStmtNode->SetThenPart(DoLowerBlock(*thenPart)); if (elsePart != nullptr) { ifStmtNode->SetElsePart(DoLowerBlock(*elsePart)); @@ -166,7 +166,7 @@ BlockNode *JavaEHLowerer::DoLowerBlock(BlockNode &block) { case OP_dowhile: { auto *whileStmtNode = static_cast(stmt); BaseNode *testOpnd = whileStmtNode->Opnd(0); - whileStmtNode->SetOpnd(DoLowerExpr(*testOpnd, *newBlock)); + whileStmtNode->SetOpnd(DoLowerExpr(*testOpnd, *newBlock), 0); whileStmtNode->SetBody(DoLowerBlock(*(whileStmtNode->GetBody()))); newBlock->AddStatement(whileStmtNode); break; diff --git a/src/mpl2mpl/src/muid_replacement.cpp b/src/mpl2mpl/src/muid_replacement.cpp index 2dd2094664fc0a003407fb1b8e8e1aad862e3d89..a96a7c70467a964f498adb2c0ec055d28a0b94bc 100644 --- a/src/mpl2mpl/src/muid_replacement.cpp +++ b/src/mpl2mpl/src/muid_replacement.cpp @@ -168,7 +168,7 @@ void MUIDReplacement::CollectFuncAndDataFromFuncList() { break; } case OP_regassign: { - auto *rhs = static_cast(stmt)->Opnd(); + auto *rhs = static_cast(stmt)->Opnd(0); if (rhs != nullptr && rhs->GetOpCode() == OP_addroffunc) { puidx = static_cast(rhs)->GetPUIdx(); } @@ -199,7 +199,7 @@ void MUIDReplacement::CollectImplicitUndefClassInfo(StmtNode &stmt) { rhs = dNode->GetRHS(); } else if (stmt.GetOpCode() == OP_regassign) { auto *rNode = static_cast(&stmt); - rhs = rNode->Opnd(); + rhs = rNode->Opnd(0); } else if (stmt.GetOpCode() == OP_catch) { auto *jNode = static_cast(&stmt); for (TyIdx typeIdx : jNode->GetExceptionTyIdxVec()) { @@ -896,10 +896,10 @@ void MUIDReplacement::ReplaceDirectInvokeOrAddroffunc(MIRFunction ¤tFunc, puidx = static_cast(dassignNode->GetRHS())->GetPUIdx(); } else if (stmt.GetOpCode() == OP_regassign) { regassignNode = static_cast(&stmt); - if (regassignNode->Opnd()->GetOpCode() != OP_addroffunc) { + if (regassignNode->Opnd(0)->GetOpCode() != OP_addroffunc) { return; } - puidx = static_cast(regassignNode->Opnd())->GetPUIdx(); + puidx = static_cast(regassignNode->Opnd(0))->GetPUIdx(); } else { CHECK_FATAL(false, "unexpected stmt type in ReplaceDirectInvokeOrAddroffunc"); } @@ -973,7 +973,7 @@ void MUIDReplacement::ReplaceDirectInvokeOrAddroffunc(MIRFunction ¤tFunc, } else if (dassignNode != nullptr) { dassignNode->SetRHS(readFuncPtr); } else if (regassignNode != nullptr) { - regassignNode->SetOpnd(readFuncPtr); + regassignNode->SetOpnd(readFuncPtr, 0); } } @@ -1089,7 +1089,7 @@ BaseNode *MUIDReplacement::ReplaceDreadExpr(MIRFunction *currentFunc, StmtNode * default: { if (expr->IsUnaryNode()) { uOpnd = static_cast(expr); - uOpnd->SetOpnd(ReplaceDreadExpr(currentFunc, stmt, uOpnd->Opnd()), i); + uOpnd->SetOpnd(ReplaceDreadExpr(currentFunc, stmt, uOpnd->Opnd(0)), i); } else if (expr->IsBinaryNode()) { bopnds = static_cast(expr); for (i = 0; i < bopnds->NumOpnds(); ++i) { diff --git a/src/mpl2mpl/src/vtable_impl.cpp b/src/mpl2mpl/src/vtable_impl.cpp index b8629c5b7a81393397d9801368a611633b443ebc..99de42f21740f26bd630a46748e941d1f5350528 100644 --- a/src/mpl2mpl/src/vtable_impl.cpp +++ b/src/mpl2mpl/src/vtable_impl.cpp @@ -46,7 +46,7 @@ void VtableImpl::ProcessFunc(MIRFunction *func) { switch (opcode) { case OP_regassign: { auto *regassign = static_cast(stmt); - BaseNode *rhs = regassign->Opnd(); + BaseNode *rhs = regassign->Opnd(0); ASSERT_NOT_NULL(rhs); if (rhs->GetOpCode() == OP_resolveinterfacefunc) { ReplaceResolveInterface(*stmt, *(static_cast(rhs))); @@ -148,7 +148,7 @@ void VtableImpl::ReplaceResolveInterface(StmtNode &stmt, const ResolveFuncNode & currFunc->GetBody()->InsertBefore(&stmt, ifStmt); if (stmt.GetOpCode() == OP_regassign) { auto *regAssign = static_cast(&stmt); - regAssign->SetOpnd(builder->CreateExprRegread(compactPtrPrim, pregFuncPtr)); + regAssign->SetOpnd(builder->CreateExprRegread(compactPtrPrim, pregFuncPtr), 0); } else { auto *icall = static_cast(&stmt); const size_t nopndSize = icall->GetNopndSize();