diff --git a/src/bin/jbc2mpl b/src/bin/jbc2mpl index aee412a93af74206de4d8a8009ff55bfee4ca3f6..b223ba678886ebc720052e7efbbe4ad8504c2994 100755 Binary files a/src/bin/jbc2mpl and b/src/bin/jbc2mpl differ diff --git a/src/bin/maple b/src/bin/maple index 618b90d182143618036632551d86c72417c6677a..b1e64f533f6c48ac77ba131be64eae4f162ffd80 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 47985003e41955818b7965894c26531c1474013d..327e8c2b5aacfba6913401476f7f294f06ad022b 100644 Binary files a/src/deplibs/libmplphase.a and b/src/deplibs/libmplphase.a differ diff --git a/src/deplibs/libmplutil.a b/src/deplibs/libmplutil.a index fb345169d0763720bd6f77a3623afdcc03c466e1..29f6dd1ec714b6e80e7ea794e7440ddbc705f2fb 100644 Binary files a/src/deplibs/libmplutil.a and b/src/deplibs/libmplutil.a differ diff --git a/src/maple_be/include/be/lower.h b/src/maple_be/include/be/lower.h index 4572d5c1773a745652bb30bc0ef38d6e31d66c31..3fa90522b634605e3236d2236248db18365f1439 100644 --- a/src/maple_be/include/be/lower.h +++ b/src/maple_be/include/be/lower.h @@ -193,6 +193,7 @@ class CGLowerer { /* if it defines a built-in to use for the given intrinsic, return the name. otherwise, return nullptr */ PUIdx GetBuiltinToUse(BuiltinFunctionID id) const; + void InitArrayClassCacheTableIndex(); MIRModule &mirModule; BECommon &beCommon; @@ -256,6 +257,7 @@ class CGLowerer { BlockNode *GenBlockNode(StmtNode &newCall, const CallReturnVector &p2nRets, const Opcode &opcode, const PUIdx &funcCalled, bool handledAtLowerLevel); BaseNode *GetClassInfoExprFromRuntime(const std::string &classInfo); + BaseNode *GetClassInfoExprFromArrayClassCache(const std::string &classInfo); BaseNode *GetClassInfoExpr(const std::string &classInfo); BaseNode *GetBaseNodeFromCurFunc(MIRFunction &curFunc, bool isJarray); @@ -267,6 +269,7 @@ class CGLowerer { MIRBuilder *mirBuilder = nullptr; uint32 labelIdx = 0; static std::unordered_map intrinFuncIDs; + static std::unordered_map arrayClassCacheIndex; }; } /* namespace maplebe */ diff --git a/src/maple_be/include/cg/aarch64/aarch64_cgfunc.h b/src/maple_be/include/cg/aarch64/aarch64_cgfunc.h index faab49b6388ede0b0472d4a63b9c1739914f48dc..7a44ed8e291242cf09a564cfe1ccecc013c5bdd7 100644 --- a/src/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -196,6 +196,7 @@ class AArch64CGFunc : public CGFunc { void SelectRangeGoto(RangeGotoNode &rangeGotoNode, Operand &opnd0) override; Operand *SelectLazyLoad(Operand &opnd0, PrimType primType) override; Operand *SelectLazyLoadStatic(MIRSymbol &st, int64 offset, PrimType primType) override; + Operand *SelectLoadArrayClassCache(MIRSymbol &st, int64 offset, PrimType primType) override; RegOperand &SelectCopy(Operand &src, PrimType stype, PrimType dtype) override; void SelectCopy(Operand &dest, PrimType dtype, Operand &src, PrimType stype); void SelectCopyImm(Operand &dest, ImmOperand &src, PrimType dtype); @@ -467,6 +468,8 @@ class AArch64CGFunc : public CGFunc { return memPool->New(*this); } + RegType GetRegisterType(regno_t reg) const override; + private: enum RelationOperator : uint8 { kAND, diff --git a/src/maple_be/include/cg/aarch64/aarch64_insn.h b/src/maple_be/include/cg/aarch64/aarch64_insn.h index 5c36c0405707946a58cab350f30b8f65f79094c4..c4093cfe9a765f840b763ed84a9b7fc863a28c30 100644 --- a/src/maple_be/include/cg/aarch64/aarch64_insn.h +++ b/src/maple_be/include/cg/aarch64/aarch64_insn.h @@ -94,6 +94,7 @@ class AArch64Insn : public Insn { bool IsClinit() const final; bool IsLazyLoad() const final; bool IsAdrpLdr() const final; + bool IsArrayClassCache() const final; bool HasLoop() const final; bool IsSpecialIntrinsic() const final; bool CanThrow() const final; @@ -162,6 +163,7 @@ class AArch64Insn : public Insn { void EmitClinitTail(Emitter&) const; void EmitLazyLoad(Emitter&) const; void EmitLazyLoadStatic(Emitter&) const; + void EmitArrayClassCacheLoad(Emitter&) const; void EmitCheckThrowPendingException(const CG&, Emitter&) const; void EmitGetAndAddInt(Emitter &emitter) const; void EmitGetAndSetInt(Emitter &emitter) const; diff --git a/src/maple_be/include/cg/aarch64/aarch64_isa.def b/src/maple_be/include/cg/aarch64/aarch64_isa.def index 06f930473d4c345a54310099e3ac97a0e0af4db6..f1877d72aaedacac860b52ed44e98aa0e2535018 100644 --- a/src/maple_be/include/cg/aarch64/aarch64_isa.def +++ b/src/maple_be/include/cg/aarch64/aarch64_isa.def @@ -272,6 +272,7 @@ MOP_lazy_ldr, MOP_lazy_ldr_static, MOP_lazy_tail, MOP_adrp_ldr, +MOP_arrayclass_cache_ldr, MOP_clinit_tail, MOP_get_and_addI, MOP_get_and_addL, diff --git a/src/maple_be/include/cg/aarch64/aarch64_peep.h b/src/maple_be/include/cg/aarch64/aarch64_peep.h index 889d1433223b9256aeaa759ab963998bf495ae18..3d56330cdcd651bb7a533086f1912e42083bff0b 100644 --- a/src/maple_be/include/cg/aarch64/aarch64_peep.h +++ b/src/maple_be/include/cg/aarch64/aarch64_peep.h @@ -466,7 +466,7 @@ class ComplexMemOperandLSLAArch64 : public PeepPattern { public: explicit ComplexMemOperandLSLAArch64(CGFunc &cgFunc) : PeepPattern(cgFunc) {} ~ComplexMemOperandLSLAArch64() override = default; - bool CheckShiftValid(AArch64MemOperand &memOpnd, BitShiftOperand &lsl); + bool CheckShiftValid(const AArch64MemOperand &memOpnd, BitShiftOperand &lsl) const; void Run(BB &bb, Insn &insn) override; }; diff --git a/src/maple_be/include/cg/cgbb.h b/src/maple_be/include/cg/cgbb.h index 136774320a598c84aeec78acea4ae3d134a763dc..d5803ee43571ce75867f4422cb69dae835b2222c 100644 --- a/src/maple_be/include/cg/cgbb.h +++ b/src/maple_be/include/cg/cgbb.h @@ -460,7 +460,7 @@ class BB { void ClearLiveInRegNO() { liveInRegNO.clear(); } - const MapleSet &GetLiveOutRegNO() { + const MapleSet &GetLiveOutRegNO() const { return liveOutRegNO; } void InsertLiveOutRegNO(regno_t arg) { @@ -717,4 +717,4 @@ struct BBIdCmp { }; } /* namespace maplebe */ -#endif /* MAPLEBE_INCLUDE_CG_CGBB_H */ \ No newline at end of file +#endif /* MAPLEBE_INCLUDE_CG_CGBB_H */ diff --git a/src/maple_be/include/cg/cgfunc.h b/src/maple_be/include/cg/cgfunc.h index cda973749246e22308c139eae5728420e6c19651..52afe3a1b28900836f268842d934d67e50a24aeb 100644 --- a/src/maple_be/include/cg/cgfunc.h +++ b/src/maple_be/include/cg/cgfunc.h @@ -232,6 +232,7 @@ class CGFunc { virtual void SelectRangeGoto(RangeGotoNode &rangeGotoNode, Operand &opnd0) = 0; virtual Operand *SelectLazyLoad(Operand &opnd0, PrimType primType) = 0; virtual Operand *SelectLazyLoadStatic(MIRSymbol &st, int64 offset, PrimType primType) = 0; + virtual Operand *SelectLoadArrayClassCache(MIRSymbol &st, int64 offset, PrimType primType) = 0; virtual void GenerateYieldpoint(BB &bb) = 0; virtual Operand &ProcessReturnReg(PrimType primType) = 0; @@ -332,7 +333,7 @@ class CGFunc { } /* return Register Type */ - RegType GetRegisterType(regno_t rNum) const { + virtual RegType GetRegisterType(regno_t rNum) const { CHECK(rNum < vRegTable.size(), "index out of range in GetVRegSize"); return vRegTable[rNum].GetType(); } diff --git a/src/maple_be/include/cg/dependence.h b/src/maple_be/include/cg/dependence.h index 7a2467d59da1c1ee2855baf90dba366b0d091b28..d414db22f2be524091bd8f3af5936026cd0bd7d1 100644 --- a/src/maple_be/include/cg/dependence.h +++ b/src/maple_be/include/cg/dependence.h @@ -21,7 +21,7 @@ namespace maplebe { using namespace maple; namespace { -constexpr maple::uint32 kMaxDependenceNum = 100; +constexpr maple::uint32 kMaxDependenceNum = 200; }; @@ -83,4 +83,4 @@ class DepAnalysis { }; } -#endif /* MAPLEBE_INCLUDE_CG_DEPENDENCE_H */ \ No newline at end of file +#endif /* MAPLEBE_INCLUDE_CG_DEPENDENCE_H */ diff --git a/src/maple_be/include/cg/deps.h b/src/maple_be/include/cg/deps.h index 56fa270dec379b9780403fbb073868ee1e7e4366..47d501f9d48aa3070f8cde3b55d47d39c6e40367 100644 --- a/src/maple_be/include/cg/deps.h +++ b/src/maple_be/include/cg/deps.h @@ -277,27 +277,31 @@ class DepNode { void InitPressure() { regPressure->InitPressure(); } - const int32 *GetPressure() const { + const MapleVector &GetPressure() const { return regPressure->GetPressure(); } - void SetPressure(int32 &pressure) { - regPressure->SetPressure(&pressure); - } + void IncPressureByIndex(int32 idx) { regPressure->IncPressureByIndex(idx); } void DecPressureByIndex(int32 idx) { regPressure->DecPressureByIndex(idx); } - void AddUseReg(regno_t reg) { - regPressure->AddUseReg(reg); + + const MapleVector &GetDeadDefNum() const { + return regPressure->GetDeadDefNum(); } - void AddDefReg(regno_t reg) { - regPressure->AddDefReg(reg); + void IncDeadDefByIndex(int32 idx) { + regPressure->IncDeadDefByIndex(idx); } + void SetRegUses(regno_t regNO, RegList ®List) { regPressure->SetRegUses(regNO, ®List); } + void SetRegDefs(regno_t regNO, RegList *regList) { + regPressure->SetRegDefs(regNO, regList); + } + int32 GetIncPressure() const { return regPressure->GetIncPressure(); } @@ -322,15 +326,12 @@ class DepNode { void SetPriority(int32 value) { regPressure->SetPriority(value); } - const MapleSet &GetUses() const { - return regPressure->GetUses(); - } - const MapleSet &GetDefs() const { - return regPressure->GetDefs(); - } - const MapleMap &GetRegUses() const { + const MapleUnorderedMap &GetRegUses() const { return regPressure->GetRegUses(); } + const MapleUnorderedMap &GetRegDefs() const { + return regPressure->GetRegDefs(); + } const Insn *GetLocInsn() const { return locInsn; @@ -391,4 +392,4 @@ class DepNode { }; } /* namespace maplebe */ -#endif /* MAPLEBE_INCLUDE_CG_DEPS_H */ \ No newline at end of file +#endif /* MAPLEBE_INCLUDE_CG_DEPS_H */ diff --git a/src/maple_be/include/cg/insn.h b/src/maple_be/include/cg/insn.h index 1f99e9fec23e7713ad53aa47b10d02c36e476335..28a5aa5548a7cac6a5ae2c2b2f6e5982fbaa6890 100644 --- a/src/maple_be/include/cg/insn.h +++ b/src/maple_be/include/cg/insn.h @@ -209,6 +209,10 @@ class Insn { return false; } + virtual bool IsArrayClassCache() const { + return false; + } + virtual bool IsReturn() const { return false; } diff --git a/src/maple_be/include/cg/pressure.h b/src/maple_be/include/cg/pressure.h index 1544ff328d9c08109f3cac5b56971c19d749305a..8b100284dbfef45cc540ba168dbd10053df0deb8 100644 --- a/src/maple_be/include/cg/pressure.h +++ b/src/maple_be/include/cg/pressure.h @@ -30,23 +30,24 @@ struct RegList { class RegPressure { public: explicit RegPressure(MapleAllocator &alloc) - : uses(alloc.Adapter()), defs(alloc.Adapter()), - regUses(alloc.Adapter()) {} + : regUses(alloc.Adapter()), regDefs(alloc.Adapter()), + pressure(alloc.Adapter()), deadDefNum(alloc.Adapter()) {} virtual ~RegPressure() = default; void DumpRegPressure() const; - void AddUseReg(regno_t regNO) { - uses.insert(regNO); - } - - void AddDefReg(regno_t regNO) { - defs.insert(regNO); + void SetRegUses(regno_t regNO, RegList *regList) { + regUses.insert(std::make_pair(regNO, regList)); } - void SetRegUses(regno_t regNO, RegList *regList) { - regUses.insert(std::pair(regNO, regList)); + void SetRegDefs(regno_t regNO, RegList *regList) { + auto it = regDefs.find(regNO); + if (it == regDefs.end()) { + regDefs.insert(std::make_pair(regNO, regList)); + } else { + it->second = regList; + } } static void SetMaxRegClassNum(int32 maxClassNum) { @@ -88,15 +89,10 @@ class RegPressure { void SetIncPressure(bool value) { incPressure = value; } - - const int32 *GetPressure() const { + const MapleVector &GetPressure() const { return pressure; } - void SetPressure(int32 *pressure) { - this->pressure = pressure; - } - void IncPressureByIndex(int32 index) { ++pressure[index]; } @@ -106,30 +102,36 @@ class RegPressure { } void InitPressure() { - FOR_ALL_REGCLASS(i) { - pressure[i] = 0; - incPressure = false; - } + pressure.resize(maxRegClassNum, 0); + deadDefNum.resize(maxRegClassNum, 0); + incPressure = false; } - const MapleSet &GetUses() const { - return uses; + const MapleVector &GetDeadDefNum() const { + return deadDefNum; } - const MapleSet &GetDefs() const { - return defs; + void IncDeadDefByIndex(int32 index) { + ++deadDefNum[index]; } - const MapleMap &GetRegUses() const { + const MapleUnorderedMap &GetRegUses() const { return regUses; } + const MapleUnorderedMap &GetRegDefs() const { + return regDefs; + } + private: - MapleSet uses; - MapleSet defs; /* save reglist of every uses'register */ - MapleMap regUses; - int32 *pressure = nullptr; + MapleUnorderedMap regUses; + /* save reglist of every defs'register */ + MapleUnorderedMap regDefs; + /* the number of the node needs registers */ + MapleVector pressure; + /* the count of dead define registers */ + MapleVector deadDefNum; /* max number of reg's class */ static int32 maxRegClassNum; int32 priority = 0; @@ -140,4 +142,4 @@ class RegPressure { }; } /* namespace maplebe */ -#endif /* MAPLEBE_INCLUDE_CG_PRESSURE_H */ \ No newline at end of file +#endif /* MAPLEBE_INCLUDE_CG_PRESSURE_H */ diff --git a/src/maple_be/include/cg/schedule.h b/src/maple_be/include/cg/schedule.h index 5558cc9cc30bcd465e2ea4c15bd4dd0aca946e88..ae5a1cd917209994d78fd3de618b7c8c9ad683cd 100644 --- a/src/maple_be/include/cg/schedule.h +++ b/src/maple_be/include/cg/schedule.h @@ -33,8 +33,7 @@ class RegPressureSchedule { void InitBBInfo(BB &b, MemPool &memPool, const MapleVector &nodes); void BuildPhyRegInfo(const std::vector ®NumVec); - void InitReadyList(const MapleVector &nodes); - void InitPressure(); + void Init(const MapleVector &nodes); void UpdateBBPressure(const DepNode &node); void CalculatePressure(DepNode &node, regno_t reg, bool def); void SortReadyList(); @@ -51,11 +50,17 @@ class RegPressureSchedule { void DoScheduling(MapleVector &nodes); private: + void DumpBBPressureInfo() const; + void DumpBBLiveInfo() const; + void DumpReadyList() const; + void DumpSelectInfo(const DepNode &node) const; + RegType GetRegisterType(regno_t reg) const; + CGFunc &cgFunc; BB *bb = nullptr; int32 *maxPressure = nullptr; int32 *curPressure = nullptr; - MapleSet liveReg; + MapleUnorderedSet liveReg; /* save node that has been scheduled. */ MapleVector scheduledNode; MapleVector readyList; diff --git a/src/maple_be/src/be/lower.cpp b/src/maple_be/src/be/lower.cpp index 627704202467c44ccb2d26955295b5bdb88f20b1..19381b9f415797c9f532a906a2d9ec055266c750 100644 --- a/src/maple_be/src/be/lower.cpp +++ b/src/maple_be/src/be/lower.cpp @@ -290,7 +290,8 @@ BaseNode *CGLowerer::LowerArrayDim(ArrayNode &array, int32 dim) { BaseNode *mpyNodes = mirModule.CurFuncCodeMemPool()->New(OP_mul); mpyNodes->SetPrimType(array.GetPrimType()); mpyNodes->SetOpnd(item, 0); - mpyNodes->SetOpnd(NodeConvert(array.GetPrimType(), *array.GetDim(mirModule, GlobalTables::GetTypeTable(), j)), 1); + mpyNodes->SetOpnd( + NodeConvert(array.GetPrimType(), *array.GetDim(mirModule, GlobalTables::GetTypeTable(), j)), 1); item = mpyNodes; } mpyNode->SetPrimType(array.GetPrimType()); @@ -836,7 +837,7 @@ BlockNode *CGLowerer::GenBlockNode(StmtNode &newCall, const CallReturnVector &p2 /* if VerboseCG, insert a comment */ if (ShouldAddAdditionalComment()) { CommentNode *cmnt = mirModule.CurFuncCodeMemPool()->New(mirModule); - cmnt->SetComment(kOpcodeInfo.GetName(opcode)); + cmnt->SetComment(kOpcodeInfo.GetName(opcode).c_str()); if (funcCalled == kFuncNotFound) { cmnt->Append(" : unknown"); } else { @@ -1408,19 +1409,7 @@ inline bool IsConstvalZero(const BaseNode &n) { std::vector> CGLowerer::builtinFuncIDs; std::unordered_map CGLowerer::intrinFuncIDs; - -/* get well known framework class 1st..6th element as pair first element */ -static std::vector> wellKnownFrameWorksClass{ -}; - -static uint32 GetWellKnownFrameWorksClassFlag(const std::string &className) { - for (auto it = wellKnownFrameWorksClass.begin(); it != wellKnownFrameWorksClass.end(); ++it) { - if (className == (*it).first) { - return (*it).second; - } - } - return 0; -} +std::unordered_map CGLowerer::arrayClassCacheIndex; MIRFunction *CGLowerer::RegisterFunctionVoidStarToVoid(BuiltinFunctionID id, const std::string &name, const std::string ¶mName) { @@ -2215,6 +2204,34 @@ BaseNode *CGLowerer::GetClassInfoExprFromRuntime(const std::string &classInfo) { return classInfoExpr; } +BaseNode *CGLowerer::GetClassInfoExprFromArrayClassCache(const std::string &classInfo) { + std::string klassJavaDescriptor; + namemangler::DecodeMapleNameToJavaDescriptor(classInfo, klassJavaDescriptor); + if (arrayClassCacheIndex.find(klassJavaDescriptor) == arrayClassCacheIndex.end()) { + return nullptr; + } + GStrIdx strIdx = GlobalTables::GetStrTable().GetStrIdxFromName( + namemangler::kArrayClassCacheTable + mirModule.GetFileNameAsPostfix()); + MIRSymbol *arrayClassSt = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx); + if (arrayClassSt == nullptr) { + return nullptr; + } + auto index = arrayClassCacheIndex[klassJavaDescriptor]; +#ifdef USE_32BIT_REF + const int32 width = 4; +#else + const int32 width = 8; +#endif /* USE_32BIT_REF */ + int64 offset = static_cast(index) * width; + ConstvalNode *offsetExpr = mirBuilder->CreateIntConst(offset, PTY_u32); + AddrofNode *baseExpr = mirBuilder->CreateExprAddrof(0, *arrayClassSt, mirModule.GetMemPool()); + MapleVector args(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); + args.push_back(baseExpr); + args.push_back(offsetExpr); + return mirBuilder->CreateExprIntrinsicop(INTRN_MPL_READ_ARRAYCLASS_CACHE_ENTRY, OP_intrinsicop, + *GlobalTables::GetTypeTable().GetPrimType(PTY_ref), args); +} + BaseNode *CGLowerer::GetClassInfoExpr(const std::string &classInfo) { BaseNode *classInfoExpr = nullptr; GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(classInfo); @@ -2251,7 +2268,10 @@ BaseNode *CGLowerer::LowerIntrinsicopWithType(const BaseNode &parent, Intrinsico bool classInfoFromRt = false; /* whether the classinfo is generated by RT */ ProcessClassInfo(*classType, classInfoFromRt, classInfo); if (classInfoFromRt) { - classInfoExpr = GetClassInfoExprFromRuntime(classInfo); + classInfoExpr = GetClassInfoExprFromArrayClassCache(classInfo); + if (classInfoExpr == nullptr) { + classInfoExpr = GetClassInfoExprFromRuntime(classInfo); + } } else { classInfoExpr = GetClassInfoExpr(classInfo); LowerTypePtr(*classInfoExpr); @@ -2305,6 +2325,9 @@ BaseNode *CGLowerer::LowerIntrinsicop(const BaseNode &parent, IntrinsicopNode &i if (intrinNode.GetIntrinsic() == INTRN_MPL_READ_OVTABLE_ENTRY_LAZY) { return &intrinNode; } + if (intrinNode.GetIntrinsic() == INTRN_MPL_READ_ARRAYCLASS_CACHE_ENTRY) { + return &intrinNode; + } CHECK_FATAL(false, "unexpected intrinsic type in CGLowerer::LowerIntrinsicop"); return &intrinNode; } @@ -2636,37 +2659,44 @@ void CGLowerer::LowerJarrayMalloc(const StmtNode &stmt, const JarrayMallocNode & std::string klassName = jaryType->GetJavaName(); std::string arrayClassInfoName; bool isPredefinedArrayClass = false; + BaseNode *arrayCacheNode = nullptr; if (jaryType->IsPrimitiveArray() && (jaryType->GetDim() <= kThreeDimArray)) { arrayClassInfoName = PRIMITIVECLASSINFO_PREFIX_STR + klassName; isPredefinedArrayClass = true; } else if (arrayNameForLower::kArrayKlassName.find(klassName) != arrayNameForLower::kArrayKlassName.end()) { arrayClassInfoName = CLASSINFO_PREFIX_STR + klassName; isPredefinedArrayClass = true; + } else { + arrayCacheNode = GetClassInfoExprFromArrayClassCache(klassName); } std::string funcName; MapleVector args(mirModule.GetMPAllocator().Adapter()); auto *curFunc = mirModule.CurFunction(); - if (isPredefinedArrayClass) { + if (isPredefinedArrayClass || (arrayCacheNode != nullptr)) { funcName = GetNewArrayFuncName(elemSize, perm); args.push_back(node.Opnd(0)); /* n_elems */ - GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(arrayClassInfoName); - MIRSymbol *arrayClassSym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx( - GlobalTables::GetStrTable().GetStrIdxFromName(arrayClassInfoName)); - if (arrayClassSym == nullptr) { - arrayClassSym = GlobalTables::GetGsymTable().CreateSymbol(kScopeGlobal); - arrayClassSym->SetNameStrIdx(strIdx); - arrayClassSym->SetStorageClass(kScGlobal); - arrayClassSym->SetSKind(kStVar); - if (CGOptions::IsPIC()) { - arrayClassSym->SetStorageClass(kScExtern); - } else { - arrayClassSym->SetAttr(ATTR_weak); + if (isPredefinedArrayClass) { + GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(arrayClassInfoName); + MIRSymbol *arrayClassSym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx( + GlobalTables::GetStrTable().GetStrIdxFromName(arrayClassInfoName)); + if (arrayClassSym == nullptr) { + arrayClassSym = GlobalTables::GetGsymTable().CreateSymbol(kScopeGlobal); + arrayClassSym->SetNameStrIdx(strIdx); + arrayClassSym->SetStorageClass(kScGlobal); + arrayClassSym->SetSKind(kStVar); + if (CGOptions::IsPIC()) { + arrayClassSym->SetStorageClass(kScExtern); + } else { + arrayClassSym->SetAttr(ATTR_weak); + } + GlobalTables::GetGsymTable().AddToStringSymbolMap(*arrayClassSym); + arrayClassSym->SetTyIdx((TyIdx)PTY_ptr); } - GlobalTables::GetGsymTable().AddToStringSymbolMap(*arrayClassSym); - arrayClassSym->SetTyIdx((TyIdx)PTY_ptr); + args.push_back(mirBuilder->CreateExprAddrof(0, *arrayClassSym)); + } else { + args.push_back(arrayCacheNode); } - args.push_back(mirBuilder->CreateExprAddrof(0, *arrayClassSym)); } else { funcName = perm ? "MCC_NewPermanentArray" : "MCC_NewObj_flexible_cname"; args.push_back(mirBuilder->CreateIntConst(elemSize, PTY_u32)); /* elem_size */ @@ -2678,9 +2708,8 @@ void CGLowerer::LowerJarrayMalloc(const StmtNode &stmt, const JarrayMallocNode & classNameExpr->SetPrimType(PTY_ptr); args.push_back(classNameExpr); /* class_name */ args.push_back(GetBaseNodeFromCurFunc(*curFunc, true)); - /* set class flag --> wellKnownClassFlag maybe 0 */ - uint32 wellKnownClassFlag = GetWellKnownFrameWorksClassFlag(jaryType->GetJavaName()); - args.push_back(mirBuilder->CreateIntConst(static_cast(wellKnownClassFlag), PTY_u32)); + /* set class flag 0 */ + args.push_back(mirBuilder->CreateIntConst(0, PTY_u32)); } MIRFunction *func = mirBuilder->GetOrCreateFunction(funcName, (TyIdx)(LOWERED_PTR_TYPE)); CallNode *callAssign = nullptr; @@ -2701,6 +2730,58 @@ bool CGLowerer::IsIntrinsicCallHandledAtLowerLevel(MIRIntrinsicID intrinsic) { return intrinsic == INTRN_MPL_ATOMIC_EXCHANGE_PTR; } +void CGLowerer::InitArrayClassCacheTableIndex() { + MIRSymbol *reflectStrtabSym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx( + GlobalTables::GetStrTable().GetOrCreateStrIdxFromName( + namemangler::kReflectionStrtabPrefixStr + mirModule.GetFileNameAsPostfix())); + MIRSymbol *reflectStartHotStrtabSym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx( + GlobalTables::GetStrTable().GetOrCreateStrIdxFromName( + namemangler::kReflectionStartHotStrtabPrefixStr + mirModule.GetFileNameAsPostfix())); + MIRSymbol *reflectBothHotStrtabSym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx( + GlobalTables::GetStrTable().GetOrCreateStrIdxFromName( + namemangler::kReflectionBothHotStrTabPrefixStr + mirModule.GetFileNameAsPostfix())); + MIRSymbol *reflectRunHotStrtabSym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx( + GlobalTables::GetStrTable().GetOrCreateStrIdxFromName( + namemangler::kReflectionRunHotStrtabPrefixStr + mirModule.GetFileNameAsPostfix())); + MIRSymbol *arrayCacheNameTableSym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx( + GlobalTables::GetStrTable().GetOrCreateStrIdxFromName( + namemangler::kArrayClassCacheNameTable + mirModule.GetFileNameAsPostfix())); + if (arrayCacheNameTableSym == nullptr) { + return; + } + MIRAggConst &aggConst = static_cast(*(arrayCacheNameTableSym->GetKonst())); + MIRSymbol *strTab = nullptr; + for (size_t i = 0; i < aggConst.GetConstVec().size(); ++i) { + MIRConst *elemConst = aggConst.GetConstVecItem(i); + uint32 intValue = static_cast(((safe_cast(elemConst))->GetValue()) & 0xFFFFFFFF); + bool isHotReflectStr = (intValue & 0x00000003) != 0; /* use the last two bits of intValue in this expression */ + if (isHotReflectStr) { + uint32 tag = (intValue & 0x00000003) - kCStringShift; /* use the last two bits of intValue in this expression */ + if (tag == kLayoutBootHot) { + strTab = reflectStartHotStrtabSym; + } else if (tag == kLayoutBothHot) { + strTab = reflectBothHotStrtabSym; + } else { + strTab = reflectRunHotStrtabSym; + } + } else { + strTab = reflectStrtabSym; + } + ASSERT(strTab != nullptr, "strTab is nullptr"); + std::string arrayClassName; + MIRAggConst *strAgg = static_cast(strTab->GetKonst()); + for (auto start = (intValue >> 2); start < strAgg->GetConstVec().size(); ++start) { /* the last two bits is flag */ + MIRIntConst *oneChar = static_cast(strAgg->GetConstVecItem(start)); + if ((oneChar != nullptr) && !oneChar->IsZero()) { + arrayClassName += static_cast(oneChar->GetValue()); + } else { + break; + } + } + arrayClassCacheIndex[arrayClassName] = i; + } +} + void CGLowerer::LowerFunc(MIRFunction &func) { labelIdx = 0; SetCurrentFunc(&func); diff --git a/src/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp b/src/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp index eb0ad3c398604570ea4fc628af390e2fb2aad545..1105b40926c75c3f9eabf246aeddadadea167a2c 100644 --- a/src/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -3612,6 +3612,13 @@ Operand *AArch64CGFunc::SelectLazyLoadStatic(MIRSymbol &st, int64 offset, PrimTy return &resOpnd; } +Operand *AArch64CGFunc::SelectLoadArrayClassCache(MIRSymbol &st, int64 offset, PrimType primType) { + StImmOperand &srcOpnd = CreateStImmOperand(st, offset, 0); + RegOperand &resOpnd = CreateRegisterOperandOfType(primType); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_arrayclass_cache_ldr, resOpnd, srcOpnd)); + return &resOpnd; +} + Operand *AArch64CGFunc::SelectAlloca(UnaryNode &node, Operand &opnd0) { ASSERT((node.GetPrimType() == PTY_a64), "wrong type"); PrimType stype = node.Opnd(0)->GetPrimType(); @@ -6217,4 +6224,14 @@ RegOperand *AArch64CGFunc::SelectStoreExcl(PrimType valPty, AArch64MemOperand &l return &result; } + +RegType AArch64CGFunc::GetRegisterType(regno_t reg) const { + if (AArch64isa::IsPhysicalRegister(reg)) { + return AArch64isa::GetRegType(static_cast(reg)); + } else if (reg == kRFLAG) { + return kRegTyCc; + } else { + return CGFunc::GetRegisterType(reg); + } +} } /* namespace maplebe */ diff --git a/src/maple_be/src/cg/aarch64/aarch64_dependence.cpp b/src/maple_be/src/cg/aarch64/aarch64_dependence.cpp index 894b7ee67c660735bafeb90cf95a9082a82971b9..d26474c2d7b544c4d8de126eb30b8d8bcb1cfd8d 100644 --- a/src/maple_be/src/cg/aarch64/aarch64_dependence.cpp +++ b/src/maple_be/src/cg/aarch64/aarch64_dependence.cpp @@ -626,7 +626,6 @@ DepNode *AArch64DepAnalysis::BuildSeparatorNode() { if (beforeRA) { RegPressure *regPressure = memPool.New(alloc); separatorNode->SetRegPressure(*regPressure); - separatorNode->SetPressure(*memPool.NewArray(RegPressure::GetMaxRegClassNum())); } return separatorNode; } @@ -825,7 +824,7 @@ void AArch64DepAnalysis::BuildSpecialInsnDependency(Insn &insn, DepNode &depNode AddDependence(*lastCallInsn->GetDepNode(), *insn.GetDepNode(), kDependenceTypeControl); } lastCallInsn = &insn; - } else if (insn.IsClinit() || insn.IsLazyLoad()) { + } else if (insn.IsClinit() || insn.IsLazyLoad() || insn.IsArrayClassCache()) { BuildDepsDirtyHeap(insn); BuildDepsDefReg(insn, kRFLAG); if (!insn.IsAdrpLdr()) { @@ -874,7 +873,6 @@ DepNode *AArch64DepAnalysis::GenerateDepNode(Insn &insn, MapleVector & if (beforeRA) { RegPressure *regPressure = memPool.New(alloc); depNode->SetRegPressure(*regPressure); - depNode->SetPressure(*memPool.NewArray(RegPressure::GetMaxRegClassNum())); } depNode->SetIndex(nodeSum); nodes.push_back(depNode); @@ -909,19 +907,20 @@ void AArch64DepAnalysis::UpdateRegUseAndDef(Insn &insn, DepNode &depNode) { for (auto regNO : useRegnos) { AppendRegUseList(insn, regNO); if (beforeRA) { - depNode.AddUseReg(regNO); depNode.SetRegUses(regNO, *regUses[regNO]); } } - for (const auto ®NO : defRegnos) { + + for (const auto regNO : defRegnos) { regDefs[regNO] = &insn; regUses[regNO] = nullptr; if (beforeRA) { - depNode.AddDefReg(regNO); + depNode.SetRegDefs(regNO, nullptr); } } } + /* Update stack and heap dependency */ void AArch64DepAnalysis::UpdateStackAndHeapDependency(DepNode &depNode, Insn &insn, const Insn &locInsn) { if (!insn.MayThrow()) { diff --git a/src/maple_be/src/cg/aarch64/aarch64_ebo.cpp b/src/maple_be/src/cg/aarch64/aarch64_ebo.cpp index d740650cb60e4f4207a1342cc69fd68a0ecf09e9..65c72c7caf5e907bed3b5184c7ade2b2a2e66399 100644 --- a/src/maple_be/src/cg/aarch64/aarch64_ebo.cpp +++ b/src/maple_be/src/cg/aarch64/aarch64_ebo.cpp @@ -677,6 +677,9 @@ bool AArch64Ebo::SpecialSequence(Insn &insn, const MapleVector &origI if ((baseInfo != nullptr) && (baseInfo->insn != nullptr)) { Insn *insn1 = baseInfo->insn; + if (insn1->GetBB() != insn.GetBB()) { + return false; + } InsnInfo *insnInfo1 = baseInfo->insnInfo; CHECK_NULL_FATAL(insnInfo1); MOperator opc1 = insn1->GetMachineOpcode(); @@ -736,6 +739,10 @@ bool AArch64Ebo::SpecialSequence(Insn &insn, const MapleVector &origI const int multiOfEight = 8; if ((!is64bits && (immVal < kStrLdrImm32UpperBound) && (immVal % multiOfFour == 0)) || (is64bits && (immVal < kStrLdrImm64UpperBound) && (immVal % multiOfEight == 0))) { + /* Reserved physicalReg beforeRA */ + if (beforeRegAlloc && op1->IsPhysicalRegister()) { + return false; + } MemOperand &mo = aarchFunc->CreateMemOpnd(*op1, immVal, size); Insn &ldrInsn = cgFunc->GetCG()->BuildInstruction(opCode, res, mo); insn.GetBB()->ReplaceInsn(insn, ldrInsn); diff --git a/src/maple_be/src/cg/aarch64/aarch64_insn.cpp b/src/maple_be/src/cg/aarch64/aarch64_insn.cpp index 4a2e79ac4f5f0f7ce92ffe51733928b8e48f8810..708ffbc25d94ebb18dbac0073a236e5d25c2e7fa 100644 --- a/src/maple_be/src/cg/aarch64/aarch64_insn.cpp +++ b/src/maple_be/src/cg/aarch64/aarch64_insn.cpp @@ -27,6 +27,7 @@ constexpr uint32 kClinitTailInsnCount = 2; constexpr uint32 kLazyLdrInsnCount = 2; constexpr uint32 kLazyLdrStaticInsnCount = 3; constexpr uint32 kCheckThrowPendingExceptionInsnCount = 5; +constexpr uint32 kArrayClassCacheLoadCount = 3; } uint32 AArch64Insn::GetResultNum() const { @@ -844,6 +845,57 @@ void AArch64Insn::EmitLazyLoadStatic(Emitter &emitter) const { emitter.Emit("]\t// lazy load static.\n"); } +void AArch64Insn::EmitArrayClassCacheLoad(Emitter &emitter) const { + /* adrp xd, :got:__arrayClassCacheTable$$xxx+offset + * ldr wd, [xd, #:got_lo12:__arrayClassCacheTable$$xxx+offset] + * ldr wzr, [xd] + */ + const AArch64MD *md = &AArch64CG::kMd[MOP_arrayclass_cache_ldr]; + uint32 opndIndex = 0; + uint32 propIndex = 0; + Operand *opnd0 = opnds[opndIndex++]; + Operand *opnd1 = opnds[opndIndex++]; + AArch64OpndProp *prop0 = md->GetOperand(propIndex++); + auto *stImmOpnd = static_cast(opnd1); + CHECK_FATAL(stImmOpnd != nullptr, "stImmOpnd is null in AArch64Insn::EmitLazyLoadStatic"); + + /* emit "adrp xd, :got:__arrayClassCacheTable$$xxx+offset" */ + emitter.Emit("\t").Emit("adrp").Emit("\t"); + opnd0->Emit(emitter, prop0); + emitter.Emit(", "); + emitter.Emit(stImmOpnd->GetName()); + if (stImmOpnd->GetOffset() != 0) { + emitter.Emit("+").Emit(stImmOpnd->GetOffset()); + } + emitter.Emit("\t// load array class.\n"); + + /* emit "ldr wd, [xd, #:got_lo12:__arrayClassCacheTable$$xxx+offset]" */ + emitter.Emit("\tldr\t"); + static_cast(opnd0)->SetRefField(true); +#ifdef USE_32BIT_REF + AArch64OpndProp prop2(prop0->GetOperandType(), prop0->GetRegProp(), prop0->GetSize() / 2); + opnd0->Emit(emitter, &prop2); /* ldr wd, ... for emui */ +#else + opnd0->Emit(emitter, prop0); /* ldr xd, ... for qemu */ +#endif /* USE_32BIT_REF */ + static_cast(opnd0)->SetRefField(false); + emitter.Emit(", "); + emitter.Emit("["); + opnd0->Emit(emitter, prop0); + emitter.Emit(","); + emitter.Emit("#"); + emitter.Emit(":lo12:").Emit(stImmOpnd->GetName()); + if (stImmOpnd->GetOffset() != 0) { + emitter.Emit("+").Emit(stImmOpnd->GetOffset()); + } + emitter.Emit("]\t// load array class.\n"); + + /* emit "ldr wzr, [xd]" */ + emitter.Emit("\t").Emit("ldr\twzr, ["); + opnd0->Emit(emitter, prop0); + emitter.Emit("]\t// check resolve array class.\n"); +} + void AArch64Insn::EmitCheckThrowPendingException(const CG& cg, Emitter &emitter) const { /* * mrs x16, TPIDR_EL0 @@ -913,6 +965,11 @@ void AArch64Insn::Emit(const CG &cg, Emitter &emitter) const { emitter.IncreaseJavaInsnCount(kLazyLdrStaticInsnCount); return; } + case MOP_arrayclass_cache_ldr: { + EmitArrayClassCacheLoad(emitter); + emitter.IncreaseJavaInsnCount(kArrayClassCacheLoadCount); + return; + } case MOP_get_and_addI: case MOP_get_and_addL: { EmitGetAndAddInt(emitter); @@ -1173,6 +1230,10 @@ bool AArch64Insn::IsAdrpLdr() const { return mOp == MOP_adrp_ldr; } +bool AArch64Insn::IsArrayClassCache() const { + return mOp == MOP_arrayclass_cache_ldr; +} + bool AArch64Insn::CanThrow() const { return AArch64CG::kMd[mOp].CanThrow(); } diff --git a/src/maple_be/src/cg/aarch64/aarch64_md.def b/src/maple_be/src/cg/aarch64/aarch64_md.def index 0e2b3c71f24ef506282423d5c3278b5f1a316970..f9b494c9a7f86cfffedd0911b3be93ed2fe1e067 100644 --- a/src/maple_be/src/cg/aarch64/aarch64_md.def +++ b/src/maple_be/src/cg/aarch64/aarch64_md.def @@ -668,6 +668,14 @@ */ {MOP_adrp_ldr, {mopdReg64ID, mopdLiteral},ISATOMIC|CANTHROW,kLtAdrpLdr,"intrinsic_adrpldr","0,1",2}, +/* + * will be emit to three instrunctions in a row: + * adrp xd, :got:__arrayClassCacheTable$$xxx+offset + * ldr xd, [xd,#:got_lo12:__arrayClassCacheTable$$xx+offset] + * ldr xzr, [xd] + */ +{MOP_arrayclass_cache_ldr, {mopdReg64ID,mopdLiteral},ISATOMIC|CANTHROW,kLtAdrpLdr,"intrinsic_loadarrayclass","0,1",3}, + /* * ldr x17, [xs,#112] * ldr wzr, [x17] diff --git a/src/maple_be/src/cg/aarch64/aarch64_peep.cpp b/src/maple_be/src/cg/aarch64/aarch64_peep.cpp index 458f6cff2a4c4804c759d22d9c7ed5b7714a901c..9088c785de6f7172eae7dc9dcf23e0c77df0f006 100644 --- a/src/maple_be/src/cg/aarch64/aarch64_peep.cpp +++ b/src/maple_be/src/cg/aarch64/aarch64_peep.cpp @@ -2075,18 +2075,18 @@ void ComplexMemOperandPreAddAArch64::Run(BB &bb, Insn &insn) { } } -bool ComplexMemOperandLSLAArch64::CheckShiftValid(AArch64MemOperand &memOpnd, BitShiftOperand &lsl) { +bool ComplexMemOperandLSLAArch64::CheckShiftValid(const AArch64MemOperand &memOpnd, BitShiftOperand &lsl) const { /* check if shift amount is valid */ uint32 lslAmount = lsl.GetShiftAmount(); - if ((memOpnd.GetSize() == k32BitSize && (lsl.GetShiftAmount() != 0 && lslAmount != 2)) || - (memOpnd.GetSize() == k64BitSize && (lsl.GetShiftAmount() != 0 && lslAmount != 3))) { + constexpr uint8 twoShiftBits = 2; + constexpr uint8 threeShiftBits = 3; + if ((memOpnd.GetSize() == k32BitSize && (lsl.GetShiftAmount() != 0 && lslAmount != twoShiftBits)) || + (memOpnd.GetSize() == k64BitSize && (lsl.GetShiftAmount() != 0 && lslAmount != threeShiftBits))) { return false; } - if (memOpnd.GetSize() != (k8BitSize << lslAmount)) { return false; } - return true; } diff --git a/src/maple_be/src/cg/cgfunc.cpp b/src/maple_be/src/cg/cgfunc.cpp index 3a28aa461b8b6f04d5a2f56e746a32490e861a76..d7ce782f4ebb048877dc53e06c8a0f45651e23b8 100644 --- a/src/maple_be/src/cg/cgfunc.cpp +++ b/src/maple_be/src/cg/cgfunc.cpp @@ -309,6 +309,14 @@ Operand *HandleIntrinOp(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc) auto mirIntConst = static_cast(constNode->GetConstVal()); return cgFunc.SelectLazyLoadStatic(*st, mirIntConst->GetValue(), intrinsicopNode.GetPrimType()); } + case INTRN_MPL_READ_ARRAYCLASS_CACHE_ENTRY: { + auto addrOfNode = static_cast(intrinsicopNode.Opnd(0)); + MIRSymbol *st = cgFunc.GetMirModule().CurFunction()->GetLocalOrGlobalSymbol(addrOfNode->GetStIdx()); + auto constNode = static_cast(intrinsicopNode.Opnd(1)); + CHECK_FATAL(constNode != nullptr, "null ptr check"); + auto mirIntConst = static_cast(constNode->GetConstVal()); + return cgFunc.SelectLoadArrayClassCache(*st, mirIntConst->GetValue(), intrinsicopNode.GetPrimType()); + } default: ASSERT(false, "Should not reach here."); return nullptr; diff --git a/src/maple_be/src/cg/emit.cpp b/src/maple_be/src/cg/emit.cpp index bbfdb4ad4faeaa5eebfd3478efc937ed58158757..5a85c8a3138a80cf52210a9b93c8aea7c56a4c68 100644 --- a/src/maple_be/src/cg/emit.cpp +++ b/src/maple_be/src/cg/emit.cpp @@ -990,6 +990,8 @@ void Emitter::InitRangeIdx2PerfixStr() { rangeIdx2PrefixStr[RangeIdx::kDecoupleStaticValue] = kDecoupleStaticValueStr; rangeIdx2PrefixStr[RangeIdx::kBssStart] = kBssSectionStr; rangeIdx2PrefixStr[RangeIdx::kLinkerSoHash] = kLinkerHashSoStr; + rangeIdx2PrefixStr[RangeIdx::kArrayClassCache] = kArrayClassCacheTable; + rangeIdx2PrefixStr[RangeIdx::kArrayClassCacheName] = kArrayClassCacheNameTable; } void Emitter::EmitIntConst(const MIRSymbol &mirSymbol, MIRAggConst &aggConst, uint32 itabConflictIndex, @@ -1035,8 +1037,9 @@ void Emitter::EmitIntConst(const MIRSymbol &mirSymbol, MIRAggConst &aggConst, ui /* process conflict table index larger than itabConflictIndex * 2 + 2 element */ bool isConflictPerfix = (idx >= (static_cast(itabConflictIndex) * 2 + 2)) && (idx % 2 == 0) && StringUtils::StartsWith(stName, ITAB_CONFLICT_PREFIX_STR); + bool isArrayClassCacheName = mirSymbol.IsArrayClassCacheName(); if (isClassInfo || isMethodsInfo || isFieldsInfo || mirSymbol.IsRegJNITab() || isInOffsetTab || - isStaticStr || isConflictPerfix) { + isStaticStr || isConflictPerfix || isArrayClassCacheName) { /* compare with all 1s */ uint32 index = static_cast((safe_cast(elemConst))->GetValue()) & 0xFFFFFFFF; bool isHotReflectStr = (index & 0x00000003) != 0; /* use the last two bits of index in this expression */ @@ -1068,7 +1071,8 @@ void Emitter::EmitIntConst(const MIRSymbol &mirSymbol, MIRAggConst &aggConst, ui EmitScalarConstant(*elemConst, false); #endif /* USE_32BIT_REF */ Emit("+" + strTabName); - if (mirSymbol.IsRegJNITab() || mirSymbol.IsReflectionMethodsInfo() || mirSymbol.IsReflectionFieldsInfo()) { + if (mirSymbol.IsRegJNITab() || mirSymbol.IsReflectionMethodsInfo() || mirSymbol.IsReflectionFieldsInfo() || + mirSymbol.IsArrayClassCacheName()) { Emit("-."); } if (StringUtils::StartsWith(stName, kDecoupleStaticKeyStr)) { @@ -1718,6 +1722,8 @@ void Emitter::EmitGlobalVariable() { std::vector staticDecoupleKeyVec; std::vector staticDecoupleValueVec; std::vector superClassStVec; + std::vector arrayClassCacheVec; + std::vector arrayClassCacheNameVec; for (size_t i = 0; i < size; ++i) { MIRSymbol *mirSymbol = GlobalTables::GetGsymTable().GetSymbolFromStidx(i); @@ -1742,6 +1748,12 @@ void Emitter::EmitGlobalVariable() { } else if (mirSymbol->GetName().find(kOffsetTabStr) == 0) { valueOffsetVec.push_back(mirSymbol); continue; + } else if (mirSymbol->IsArrayClassCache()) { + arrayClassCacheVec.push_back(mirSymbol); + continue; + } else if (mirSymbol->IsArrayClassCacheName()) { + arrayClassCacheNameVec.push_back(mirSymbol); + continue; } else if (mirSymbol->GetName().find(kLocalClassInfoStr) == 0) { localClassInfoVec.push_back(mirSymbol); continue; @@ -2058,6 +2070,11 @@ void Emitter::EmitGlobalVariable() { /* method address rw */ EmitMetaDataSymbolWithMarkFlag(methodAddrDatas, strIdx2Type, kMethodAddrDataPrefixStr, sectionNameIsEmpty, false); + /* array class cache table */ + EmitMuidTable(arrayClassCacheVec, strIdx2Type, kArrayClassCacheTable); + /* array class cache name table */ + EmitMuidTable(arrayClassCacheNameVec, strIdx2Type, kArrayClassCacheNameTable); + #if !defined(TARGARM32) /* finally emit __gxx_personality_v0 DW.ref */ if (!cg->GetMIRModule()->IsCModule()) { diff --git a/src/maple_be/src/cg/pressure.cpp b/src/maple_be/src/cg/pressure.cpp index 4adb9c1cc421699381d996fcd54aedc13c57ff7f..16e06e3ccf3e1cee8193309a0fb61e456a4702f0 100644 --- a/src/maple_be/src/cg/pressure.cpp +++ b/src/maple_be/src/cg/pressure.cpp @@ -28,13 +28,13 @@ void RegPressure::DumpRegPressure() const { PRINT_STR_VAL("near: ", near); LogInfo::MapleLogger() << "\n"; LogInfo::MapleLogger() << std::left << std::setw(width) << "usereg: "; - for (const auto &useRegNO : uses) { - LogInfo::MapleLogger() << "R" << useRegNO << " "; + for (const auto &useReg : regUses) { + LogInfo::MapleLogger() << "R" << useReg.first << " "; } LogInfo::MapleLogger() << "\n"; LogInfo::MapleLogger() << std::left << std::setw(width) << "defreg: "; - for (const auto &defRegNO : defs) { - LogInfo::MapleLogger() << "R" << defRegNO << " "; + for (const auto &defReg : regDefs) { + LogInfo::MapleLogger() << "R" << defReg.first << " "; } LogInfo::MapleLogger() << "\n"; } diff --git a/src/maple_be/src/cg/schedule.cpp b/src/maple_be/src/cg/schedule.cpp index cff7d94d8a987000e7a02b1dedddcbedf873c9b2..f0da826ea4df7ec1db3266f00cf06d041f1c7cec 100644 --- a/src/maple_be/src/cg/schedule.cpp +++ b/src/maple_be/src/cg/schedule.cpp @@ -21,6 +21,8 @@ #include "cg.h" #include "optimize_common.h" +#undef PRESCHED_DEBUG + namespace maplebe { /* ---- RegPressureSchedule function ---- */ void RegPressureSchedule::InitBBInfo(BB &b, MemPool &memPool, const MapleVector &nodes) { @@ -37,6 +39,11 @@ void RegPressureSchedule::InitBBInfo(BB &b, MemPool &memPool, const MapleVector< } } +/* return register type according to register number */ +RegType RegPressureSchedule::GetRegisterType(regno_t reg) const { + return cgFunc.GetRegisterType(reg); +} + /* Get amount of every physical register */ void RegPressureSchedule::BuildPhyRegInfo(const std::vector ®NumVec) { FOR_ALL_REGCLASS(i) { @@ -44,34 +51,42 @@ void RegPressureSchedule::BuildPhyRegInfo(const std::vector ®NumVec) { } } -void RegPressureSchedule::InitReadyList(const MapleVector &nodes) { - for (auto node : nodes) { - /* If a node is not been scheduled and there is no pred node of the node, add the node reaylist. */ - if ((node->GetState() == kNormal) && node->GetPreds().empty()) { - readyList.push_back(node); - node->SetState(kReady); - } - } -} - -/* initialize register pressure information according to bb's live-in data. */ -void RegPressureSchedule::InitPressure() { +/* initialize register pressure information according to bb's live-in data. + * initialize node's valid preds size. + */ +void RegPressureSchedule::Init(const MapleVector &nodes) { FOR_ALL_REGCLASS(i) { curPressure[i] = 0; + maxPressure[i] = 0; } - /* add all bb's live-in register to liveReg. */ - for (auto reg : bb->GetLiveInRegNO()) { - RegType regType = cgFunc.GetRegisterType(reg); - if (liveReg.find(reg) == liveReg.end()) { - liveReg.insert(reg); - /* increase the pressure of the register type. */ - ++curPressure[regType]; + + for (auto *node : nodes) { + /* initialize */ + node->InitPressure(); + + /* calculate the node uses'register pressure */ + for (auto &useReg : node->GetRegUses()) { + CalculatePressure(*node, useReg.first, false); } - } - FOR_ALL_REGCLASS(i) { - maxPressure[i] = curPressure[i]; + /* calculate the node defs'register pressure */ + for (auto &defReg : node->GetRegDefs()) { + CalculatePressure(*node, defReg.first, true); + + regno_t reg = defReg.first; + RegType regType = GetRegisterType(reg); + /* if no use list, a register is only defined, not be used */ + if (defReg.second == nullptr) { + node->IncDeadDefByIndex(regType); + } + } + + node->SetValidPredsSize(node->GetPreds().size()); } + + DepNode *firstNode = nodes.front(); + readyList.push_back(firstNode); + firstNode->SetState(kReady); } void RegPressureSchedule::SortReadyList() { @@ -92,30 +107,20 @@ bool RegPressureSchedule::DepNodePriorityCmp(const DepNode *node1, const DepNode return depthS1 > depthS2; } - return node1->GetNear() > node2->GetNear(); + int32 near1 = node1->GetNear(); + int32 near2 = node2->GetNear(); + if (near1 != near2) { + return node1->GetNear() > node2->GetNear(); + } + + return node1->GetSuccs().size() < node2->GetSuccs().size(); } -/* calculate a node register pressure base on current scheduling */ +/* set a node's incPressure is true, when a class register inscrease */ void RegPressureSchedule::ReCalculateDepNodePressure(DepNode &node) { - /* initialize */ - node.InitPressure(); - /* calculate the node uses'register pressure */ - for (auto reg : node.GetUses()) { - CalculatePressure(node, reg, false); - } - /* calculate the node defs'register pressure */ - for (auto reg : node.GetDefs()) { - CalculatePressure(node, reg, true); - } - /* if there is a type of register pressure increases, set incPressure as true. */ - const int32 *pressure = node.GetPressure(); - FOR_ALL_REGCLASS(i) { - if (pressure[i] > 0) { - node.SetIncPressure(true); - break; - } - } + auto &pressures = node.GetPressure(); + node.SetIncPressure(pressures[kRegisterInt] > 0); } /* calculate the maxDepth of every node in nodes. */ @@ -136,7 +141,7 @@ void RegPressureSchedule::CalculateMaxDepth(const MapleVector &nodes) void RegPressureSchedule::CalculateNear(const DepNode &node) { for (auto succ : node.GetSuccs()) { DepNode &to = succ->GetTo(); - if (to.GetNear() < node.GetNear() + 1) { + if (succ->GetDepType() == kDependenceTypeTrue && to.GetNear() < node.GetNear() + 1) { to.SetNear(node.GetNear() + 1); } } @@ -148,9 +153,6 @@ bool RegPressureSchedule::IsLastUse(const DepNode &node, regno_t regNO) const { ASSERT(it->second != nullptr, "valid iterator check"); ASSERT(it != node.GetRegUses().end(), "not find reg!"); RegList *regList = it->second; - if (bb->GetLiveOutRegNO().find(regNO) != bb->GetLiveOutRegNO().end()) { - return false; - } /* * except the node, if there are insn that has no scheduled in regNO'sregList, @@ -169,18 +171,14 @@ bool RegPressureSchedule::IsLastUse(const DepNode &node, regno_t regNO) const { } void RegPressureSchedule::CalculatePressure(DepNode &node, regno_t reg, bool def) { - RegType regType = cgFunc.GetRegisterType(reg); + RegType regType = GetRegisterType(reg); /* if def a register, register pressure increase. */ if (def) { - if (liveReg.find(reg) == liveReg.end()) { - node.IncPressureByIndex(regType); - } + node.IncPressureByIndex(regType); } else { /* if it is the last time using the reg, register pressure decrease. */ if (IsLastUse(node, reg)) { - if (liveReg.find(reg) != liveReg.end()) { - node.DecPressureByIndex(regType); - } + node.DecPressureByIndex(regType); } } } @@ -191,6 +189,12 @@ void RegPressureSchedule::UpdateLiveReg(const DepNode &node, regno_t reg, bool d if (liveReg.find(reg) == liveReg.end()) { liveReg.insert(reg); } + /* if no use list, a register is only defined, not be used */ + auto it = node.GetRegDefs().find(reg); + ASSERT(it != node.GetRegDefs().end(), "not find reg!"); + if (it->second == nullptr) { + liveReg.erase(reg); + } } else { if (IsLastUse(node, reg)) { if (liveReg.find(reg) != liveReg.end()) { @@ -202,38 +206,76 @@ void RegPressureSchedule::UpdateLiveReg(const DepNode &node, regno_t reg, bool d /* update register pressure information. */ void RegPressureSchedule::UpdateBBPressure(const DepNode &node) { - const MapleSet &uses = node.GetUses(); - const MapleSet &defs = node.GetDefs(); + for (auto &useReg : node.GetRegUses()) { + auto reg = useReg.first; - for (auto reg : uses) { +#ifdef PRESCHED_DEBUG UpdateLiveReg(node, reg, false); + if (liveReg.find(reg) == liveReg.end()) { + continue; + } +#endif + + /* find all insn that use the reg, if a insn use the reg lastly, insn'pressure - 1 */ + auto it = node.GetRegUses().find(reg); + ASSERT(it->second != nullptr, "valid iterator check"); + ASSERT(it != node.GetRegUses().end(), "not find reg!"); + RegList *regList = it->second; + + while (regList != nullptr) { + CHECK_NULL_FATAL(regList->insn); + DepNode *useNode = regList->insn->GetDepNode(); + if (useNode->GetState() == kScheduled) { + regList = regList->next; + continue; + } + + if (IsLastUse(*useNode, reg)) { + RegType regType = GetRegisterType(reg); + useNode->DecPressureByIndex(regType); + } + break; + } + } + +#ifdef PRESCHED_DEBUG + for (auto &defReg : node.GetRegDefs()) { + UpdateLiveReg(node, defReg.first, true); } - for (auto reg : defs) { - UpdateLiveReg(node, reg, true); +#endif + + const auto &pressures = node.GetPressure(); + const auto &deadDefNum = node.GetDeadDefNum(); +#ifdef PRESCHED_DEBUG + LogInfo::MapleLogger() << "node's pressure: "; + for (auto pressure : pressures) { + LogInfo::MapleLogger() << pressure[i] << " "; } - const int32 *pressure = node.GetPressure(); - ASSERT(pressure != nullptr, "get pressure in node failed in RegPressureSchedule::UpdateBBPressure"); + LogInfo::MapleLogger() << "\n"; +#endif + FOR_ALL_REGCLASS(i) { - curPressure[i] += pressure[i]; + curPressure[i] += pressures[i]; if (curPressure[i] > maxPressure[i]) { maxPressure[i] = curPressure[i]; } + curPressure[i] -= deadDefNum[i]; } } /* update node priority and try to update the priority of all node's ancestor. */ void RegPressureSchedule::UpdatePriority(DepNode &node) { - std::queue workQueue; - workQueue.push(&node); + std::vector workQueue; + workQueue.push_back(&node); node.SetPriority(maxPriority++); do { DepNode *nowNode = workQueue.front(); - workQueue.pop(); + workQueue.erase(workQueue.begin()); for (auto pred : nowNode->GetPreds()) { DepNode &from = pred->GetFrom(); - if (from.GetState() != kScheduled) { + if (from.GetState() != kScheduled && from.GetPriority() != maxPriority) { from.SetPriority(maxPriority); - workQueue.push(&from); + workQueue.push_back(&from); } } } while (!workQueue.empty()); @@ -241,13 +283,7 @@ void RegPressureSchedule::UpdatePriority(DepNode &node) { /* return true if all node's pred has been scheduled. */ bool RegPressureSchedule::CanSchedule(const DepNode &node) const { - for (auto pred : node.GetPreds()) { - DepNode &from = pred->GetFrom(); - if (from.GetState() != kScheduled) { - return false; - } - } - return true; + return node.GetValidPredsSize() == 0; } /* @@ -258,6 +294,8 @@ bool RegPressureSchedule::CanSchedule(const DepNode &node) const { void RegPressureSchedule::UpdateReadyList(const DepNode &node) { for (auto *succ : node.GetSuccs()) { DepNode &succNode = succ->GetTo(); + succNode.DescreaseValidPredsSize(); + if (((succ->GetDepType() == kDependenceTypeTrue) || CanSchedule(succNode)) && (succNode.GetState() == kNormal)) { readyList.push_back(&succNode); succNode.SetState(kReady); @@ -283,20 +321,85 @@ DepNode *RegPressureSchedule::ChooseNode() { return node; } +void RegPressureSchedule::DumpBBLiveInfo() const { + LogInfo::MapleLogger() << "Live In: "; + for (auto reg : bb->GetLiveInRegNO()) { + LogInfo::MapleLogger() << "R" <GetLiveOutRegNO()) { + LogInfo::MapleLogger() << "R" << reg << " "; + } + LogInfo::MapleLogger() << "\n"; +} + +void RegPressureSchedule::DumpReadyList() const { + LogInfo::MapleLogger() << "readyList: " << "\n"; + for (DepNode *it : readyList) { + if (CanSchedule(*it)) { + LogInfo::MapleLogger() << it->GetInsn()->GetId() << "CS "; + } else { + LogInfo::MapleLogger() << it->GetInsn()->GetId() << "NO "; + } + } + LogInfo::MapleLogger() << "\n"; +} + +void RegPressureSchedule::DumpSelectInfo(const DepNode &node) const { + LogInfo::MapleLogger() << "select a node: " << "\n"; + node.DumpSchedInfo(); + node.DumpRegPressure(); + node.GetInsn()->Dump(); + + LogInfo::MapleLogger() << "liveReg: "; + for (auto reg : liveReg) { + LogInfo::MapleLogger() << "R" << reg << " "; + } + LogInfo::MapleLogger() << "\n"; + + LogInfo::MapleLogger() << "\n"; +} + +void RegPressureSchedule::DumpBBPressureInfo() const { + LogInfo::MapleLogger() << "curPressure: "; + FOR_ALL_REGCLASS(i) { + LogInfo::MapleLogger() << curPressure[i] << " "; + } + LogInfo::MapleLogger() << "\n"; + + LogInfo::MapleLogger() << "maxPressure: "; + FOR_ALL_REGCLASS(i) { + LogInfo::MapleLogger() << maxPressure[i] << " "; + } + LogInfo::MapleLogger() << "\n"; +} + + void RegPressureSchedule::DoScheduling(MapleVector &nodes) { +#ifdef PRESCHED_DEBUG + LogInfo::MapleLogger() << "--------------- bb " << bb->GetId() <<" begin scheduling -------------" << "\n"; + DumpBBLiveInfo(); +#endif + /* initialize register pressure information and readylist. */ - InitPressure(); - InitReadyList(nodes); + Init(nodes); CalculateMaxDepth(nodes); - SortReadyList(); while (!readyList.empty()) { /* calculate register pressure */ - for (auto *it : readyList) { + for (DepNode *it : readyList) { ReCalculateDepNodePressure(*it); } /* choose a node can be scheduled currently. */ DepNode *node = ChooseNode(); +#ifdef PRESCHED_DEBUG + DumpBBPressureInfo(); + DumpReadyList(); + LogInfo::MapleLogger() << "first tmp select node: " << node->GetInsn()->GetId() << "\n"; +#endif + while (!CanSchedule(*node)) { UpdatePriority(*node); SortReadyList(); @@ -317,8 +420,14 @@ void RegPressureSchedule::DoScheduling(MapleVector &nodes) { } UpdateReadyList(*node); SortReadyList(); +#ifdef PRESCHED_DEBUG + DumpSelectInfo(*node); +#endif } +#ifdef PRESCHED_DEBUG + LogInfo::MapleLogger() << "---------------------------------- end --------------------------------" << "\n"; +#endif /* update nodes according to scheduledNode. */ nodes.clear(); for (auto node : scheduledNode) { diff --git a/src/maple_driver/src/driver_option_common.cpp b/src/maple_driver/src/driver_option_common.cpp index 16312bc885e7d9460e69439e99797766d00e4fc3..15c1154b2787659d9294c1316537347cf2e8b5f3 100644 --- a/src/maple_driver/src/driver_option_common.cpp +++ b/src/maple_driver/src/driver_option_common.cpp @@ -18,7 +18,7 @@ namespace { using namespace maple; using namespace mapleOption; const mapleOption::Descriptor usages[] = { - // index, type , shortOption , longOption, enableBuildType, checkPolicy, help, exeName, extra bins + // index, type, shortOption, longOption, enableBuildType, checkPolicy, help, exeName, extra bins { kUnknown, 0, "", diff --git a/src/maple_driver/src/driver_runner.cpp b/src/maple_driver/src/driver_runner.cpp index 26c15218a422ad85a318006c3477b86bcf355324..0c61d0bf7aadc97865b556503ea5215fc24fdbe7 100644 --- a/src/maple_driver/src/driver_runner.cpp +++ b/src/maple_driver/src/driver_runner.cpp @@ -334,6 +334,7 @@ void DriverRunner::RunCGFunctions(CG &cg, CgFuncPhaseManager &cgfpm) const { mirLowerer.Init(); CGLowerer theLowerer(*theModule, *beCommon, cg.GenerateExceptionHandlingCode(), cg.GenerateVerboseCG()); theLowerer.RegisterBuiltIns(); + theLowerer.InitArrayClassCacheTableIndex(); theLowerer.RegisterExternalLibraryFunctions(); theLowerer.SetCheckLoadStore(CGOptions::IsCheckArrayStore()); diff --git a/src/maple_ipa/include/callgraph.h b/src/maple_ipa/include/callgraph.h index c963a836fd5decb074968756eb42eb2e74b9666d..96e30e7d777afa3004e736578d7077f8978322ea 100644 --- a/src/maple_ipa/include/callgraph.h +++ b/src/maple_ipa/include/callgraph.h @@ -51,8 +51,8 @@ struct Comparator { // Information description of each callsite class CallInfo { public: - CallInfo(CallType type, MIRFunction &call, StmtNode *s, uint32 ld, uint32 stmtId, bool local = false) - : areAllArgsLocal(local), ctype(type), mirFunc(&call), callStmt(s), loopDepth(ld), id(stmtId) {} + CallInfo(CallType type, MIRFunction &call, StmtNode *node, uint32 ld, uint32 stmtId, bool local = false) + : areAllArgsLocal(local), cType(type), mirFunc(&call), callStmt(node), loopDepth(ld), id(stmtId) {} virtual ~CallInfo() {} @@ -60,16 +60,16 @@ class CallInfo { return id; } - const char *GetCalleeName() const; + const std::string GetCalleeName() const; CallType GetCallType() const { - return ctype; + return cType; } uint32 GetLoopDepth() const { return loopDepth; } - const char *GetCallTypeName() const; + const std::string GetCallTypeName() const; StmtNode *GetCallStmt() const { return callStmt; } @@ -88,7 +88,7 @@ class CallInfo { private: bool areAllArgsLocal; - CallType ctype; // Call type + CallType cType; // Call type MIRFunction *mirFunc; // Used to get signature StmtNode *callStmt; // Call statement uint32 loopDepth; @@ -315,8 +315,8 @@ class SCCNode { virtual ~SCCNode() {} - void AddCGNode(CGNode *cgn) { - cgNodes.push_back(cgn); + void AddCGNode(CGNode *node) { + cgNodes.push_back(node); } void Dump() const; @@ -471,7 +471,7 @@ class DoCallGraph : public ModulePhase { public: explicit DoCallGraph(ModulePhaseID id) : ModulePhase(id) {} - AnalysisResult *Run(MIRModule *module, ModuleResultMgr *m) override; + AnalysisResult *Run(MIRModule *module, ModuleResultMgr *mgr) override; std::string PhaseName() const override { return "callgraph"; } @@ -482,7 +482,7 @@ class DoCallGraph : public ModulePhase { class IPODevirtulize { public: IPODevirtulize(MIRModule *m, MemPool *memPool, KlassHierarchy *kh) - : cgalloc(memPool), mirBuilder(cgalloc.GetMemPool()->New(m)), klassh(kh), debugFlag(false) {} + : cgAlloc(memPool), mirBuilder(cgAlloc.GetMemPool()->New(m)), klassh(kh), debugFlag(false) {} virtual ~IPODevirtulize() = default; void DevirtualFinal(); @@ -491,19 +491,19 @@ class IPODevirtulize { } private: - MapleAllocator cgalloc; + void SearchDefInMemberMethods(const Klass &klass); + void SearchDefInClinit(const Klass &klass); + MapleAllocator cgAlloc; MIRBuilder *mirBuilder; KlassHierarchy *klassh; bool debugFlag; - void SearchDefInMemberMethods(const Klass &klass); - void SearchDefInClinit(const Klass &klass); }; class DoIPODevirtulize : public ModulePhase { public: explicit DoIPODevirtulize(ModulePhaseID id) : ModulePhase(id) {} - AnalysisResult *Run(MIRModule *module, ModuleResultMgr *m) override; + AnalysisResult *Run(MIRModule *module, ModuleResultMgr *mgr) override; std::string PhaseName() const override { return "ipodevirtulize"; } diff --git a/src/maple_ipa/include/clone.h b/src/maple_ipa/include/clone.h index 9a3d53828bdf38529246a2fb374d96691119fa64..2ae866a71729d42aa07459cebcb2166d2273fa24 100644 --- a/src/maple_ipa/include/clone.h +++ b/src/maple_ipa/include/clone.h @@ -58,7 +58,7 @@ class ReplaceRetIgnored { class Clone : public AnalysisResult { public: Clone(MIRModule *mod, MemPool *memPool, MIRBuilder &builder, KlassHierarchy *kh) - : AnalysisResult(memPool), mirModule(mod), allocator(memPool), dexBuilder(builder), kh(kh), + : AnalysisResult(memPool), mirModule(mod), allocator(memPool), mirBuilder(builder), kh(kh), replaceRetIgnored(memPool->New(memPool)) {} ~Clone() = default; @@ -72,8 +72,8 @@ class Clone : public AnalysisResult { void DoClone(); void CopyFuncInfo(const MIRFunction &originalFunction, MIRFunction &newFunc) const; void UpdateFuncInfo(MIRFunction &newFunc); - void CloneArgument(MIRFunction &riginalFunction, ArgVector &argument) const; - ReplaceRetIgnored *GetReplaceRetIgnored() { + void CloneArgument(MIRFunction &originalFunction, ArgVector &argument) const; + ReplaceRetIgnored *GetReplaceRetIgnored() const { return replaceRetIgnored; } @@ -82,7 +82,7 @@ class Clone : public AnalysisResult { private: MIRModule *mirModule; MapleAllocator allocator; - MIRBuilder &dexBuilder; + MIRBuilder &mirBuilder; KlassHierarchy *kh; ReplaceRetIgnored *replaceRetIgnored; }; @@ -93,7 +93,7 @@ class DoClone : public ModulePhase { virtual ~DoClone() = default; - AnalysisResult *Run(MIRModule *module, ModuleResultMgr *m) override; + AnalysisResult *Run(MIRModule *module, ModuleResultMgr *mgr) override; std::string PhaseName() const override { return "clone"; } diff --git a/src/maple_ipa/src/callgraph.cpp b/src/maple_ipa/src/callgraph.cpp index 0ed22ff54fc6ac680cb33594e96a6591203ac117..326a58aade87ec998d5beba4e4ca81b68c300b76 100644 --- a/src/maple_ipa/src/callgraph.cpp +++ b/src/maple_ipa/src/callgraph.cpp @@ -41,8 +41,8 @@ // is always compiled before caller. This benefits those optimizations // need interprocedure information like escape analysis. namespace maple { -const char *CallInfo::GetCallTypeName() const { - switch (ctype) { +const std::string CallInfo::GetCallTypeName() const { + switch (cType) { case kCallTypeCall: return "c"; case kCallTypeVirtualCall: @@ -67,25 +67,25 @@ const char *CallInfo::GetCallTypeName() const { return "polymorphiccall"; default: CHECK_FATAL(false, "unsupport CALL type"); - return nullptr; + return ""; } } -const char *CallInfo::GetCalleeName() const { - if ((ctype >= kCallTypeCall) && (ctype <= kCallTypeInterfaceCall)) { +const std::string CallInfo::GetCalleeName() const { + if ((cType >= kCallTypeCall) && (cType <= kCallTypeInterfaceCall)) { MIRFunction &mirf = *mirFunc; - return mirf.GetName().c_str(); - } else if (ctype == kCallTypeIcall) { + return mirf.GetName(); + } else if (cType == kCallTypeIcall) { return "IcallUnknown"; - } else if ((ctype >= kCallTypeIntrinsicCall) && (ctype <= kCallTypeIntrinsicCallWithType)) { + } else if ((cType >= kCallTypeIntrinsicCall) && (cType <= kCallTypeIntrinsicCallWithType)) { return "IntrinsicCall"; - } else if (ctype == kCallTypeCustomCall) { + } else if (cType == kCallTypeCustomCall) { return "CustomCall"; - } else if (ctype == kCallTypePolymorphicCall) { + } else if (cType == kCallTypePolymorphicCall) { return "PolymorphicCall"; } CHECK_FATAL(false, "should not be here"); - return nullptr; + return ""; } void CGNode::DumpDetail() const { @@ -113,10 +113,10 @@ void CGNode::DumpDetail() const { } } // dump caller - for (auto const &callernode : callerSet) { - CHECK_NULL_FATAL(callernode); - CHECK_NULL_FATAL(callernode->mirFunc); - LogInfo::MapleLogger() << "\tcaller : " << callernode->mirFunc->GetName() << std::endl; + for (auto const &callerNode : callerSet) { + CHECK_NULL_FATAL(callerNode); + CHECK_NULL_FATAL(callerNode->mirFunc); + LogInfo::MapleLogger() << "\tcaller : " << callerNode->mirFunc->GetName() << std::endl; } } @@ -202,7 +202,7 @@ void CallGraph::DelNode(CGNode &node) { auto *mirStructType = static_cast(classType); uint32 j = 0; for (; j < mirStructType->GetMethods().size(); ++j) { - if (mirStructType->GetMethods()[j].first == func->GetStIdx()) { + if (mirStructType->GetMethodsElement(j).first == func->GetStIdx()) { mirStructType->GetMethods().erase(mirStructType->GetMethods().begin() + j); break; } @@ -219,7 +219,7 @@ void CallGraph::DelNode(CGNode &node) { if (j < mirModule->GetFunctionList().size()) { mirModule->GetFunctionList().erase(mirModule->GetFunctionList().begin() + j); } - GlobalTables::GetFunctionTable().GetFuncTable()[i] = nullptr; + GlobalTables::GetFunctionTable().SetFunctionItem(i, nullptr); break; } } @@ -245,52 +245,52 @@ CallGraph::CallGraph(MIRModule &m, MemPool &memPool, KlassHierarchy &kh, const s numOfSccs(0) {} CallType CallGraph::GetCallType(Opcode op) const { - CallType t = kCallTypeInvalid; + CallType typeTemp = kCallTypeInvalid; switch (op) { case OP_call: case OP_callassigned: - t = kCallTypeCall; + typeTemp = kCallTypeCall; break; case OP_virtualcall: case OP_virtualcallassigned: - t = kCallTypeVirtualCall; + typeTemp = kCallTypeVirtualCall; break; case OP_superclasscall: case OP_superclasscallassigned: - t = kCallTypeSuperCall; + typeTemp = kCallTypeSuperCall; break; case OP_interfacecall: case OP_interfacecallassigned: - t = kCallTypeInterfaceCall; + typeTemp = kCallTypeInterfaceCall; break; case OP_icall: case OP_icallassigned: - t = kCallTypeIcall; + typeTemp = kCallTypeIcall; break; case OP_intrinsiccall: case OP_intrinsiccallassigned: - t = kCallTypeIntrinsicCall; + typeTemp = kCallTypeIntrinsicCall; break; case OP_xintrinsiccall: case OP_xintrinsiccallassigned: - t = kCallTypeXinitrinsicCall; + typeTemp = kCallTypeXinitrinsicCall; break; case OP_intrinsiccallwithtype: case OP_intrinsiccallwithtypeassigned: - t = kCallTypeIntrinsicCallWithType; + typeTemp = kCallTypeIntrinsicCallWithType; break; case OP_customcall: case OP_customcallassigned: - t = kCallTypeCustomCall; + typeTemp = kCallTypeCustomCall; break; case OP_polymorphiccall: case OP_polymorphiccallassigned: - t = kCallTypePolymorphicCall; + typeTemp = kCallTypePolymorphicCall; break; default: break; } - return t; + return typeTemp; } CGNode *CallGraph::GetCGNode(MIRFunction *func) const { @@ -431,7 +431,7 @@ void CallGraph::HandleBody(MIRFunction &func, BlockNode &body, CGNode &node, uin } else if (op == OP_if) { IfStmtNode *n = static_cast(stmt); HandleBody(func, *n->GetThenPart(), node, loopDepth); - if (n->GetElsePart()) { + if (n->GetElsePart() != nullptr) { HandleBody(func, *n->GetElsePart(), node, loopDepth); } } else { @@ -527,8 +527,8 @@ void CallGraph::HandleBody(MIRFunction &func, BlockNode &body, CGNode &node, uin MapleVector *cands = klass->GetCandidates(calleeFunc->GetBaseFuncNameWithTypeStrIdx()); // continue to search its implinterfaces if (cands == nullptr) { - for (Klass *implinterface : klass->GetImplInterfaces()) { - cands = implinterface->GetCandidates(calleeFunc->GetBaseFuncNameWithTypeStrIdx()); + for (Klass *implInterface : klass->GetImplInterfaces()) { + cands = implInterface->GetCandidates(calleeFunc->GetBaseFuncNameWithTypeStrIdx()); if (cands != nullptr && !cands->empty()) { break; } @@ -556,7 +556,7 @@ void CallGraph::HandleBody(MIRFunction &func, BlockNode &body, CGNode &node, uin break; } default: { - CHECK_FATAL(false, "TODO::unsupport call type"); + CHECK_FATAL(false, "NYI::unsupport call type"); } } } @@ -630,20 +630,20 @@ void IPODevirtulize::SearchDefInClinit(const Klass &klass) { MIRClassType *classType = static_cast(klass.GetMIRStructType()); std::vector staticFinalPrivateSymbols; for (uint32 i = 0; i < classType->GetStaticFields().size(); ++i) { - FieldAttrs attribute = classType->GetStaticFields()[i].second.second; + FieldAttrs attribute = classType->GetStaticFieldsPair(i).second.second; if (attribute.GetAttr(FLDATTR_final)) { staticFinalPrivateSymbols.push_back( - GlobalTables::GetGsymTable().GetSymbolFromStrIdx(classType->GetStaticFields()[i].first)); + GlobalTables::GetGsymTable().GetSymbolFromStrIdx(classType->GetStaticFieldsGStrIdx(i))); } } std::string typeName = klass.GetKlassName(); typeName.append(namemangler::kClinitSuffix); - GStrIdx clinitFuncGstridx = + GStrIdx clinitFuncGstrIdx = GlobalTables::GetStrTable().GetStrIdxFromName(namemangler::GetInternalNameLiteral(typeName)); - if (clinitFuncGstridx == 0u) { + if (clinitFuncGstrIdx == 0u) { return; } - MIRFunction *func = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(clinitFuncGstridx)->GetFunction(); + MIRFunction *func = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(clinitFuncGstrIdx)->GetFunction(); if (func->GetBody() == nullptr) { return; } @@ -707,7 +707,7 @@ void IPODevirtulize::SearchDefInClinit(const Klass &klass) { continue; } for (unsigned int i = 0; i < callNode->GetReturnVec().size(); ++i) { - StIdx stIdx = callNode->GetReturnVec()[i].first; + StIdx stIdx = callNode->GetReturnPair(i).first; MIRSymbol *tmpSymbol = func->GetLocalOrGlobalSymbol(stIdx); ResetInferredType(gcmallocSymbols, tmpSymbol); } @@ -742,10 +742,10 @@ void IPODevirtulize::SearchDefInMemberMethods(const Klass &klass) { MIRClassType *classType = static_cast(klass.GetMIRStructType()); std::vector finalPrivateFieldID; for (uint32 i = 0; i < classType->GetFieldsSize(); ++i) { - FieldAttrs attribute = classType->GetFields()[i].second.second; + FieldAttrs attribute = classType->GetFieldsElemt(i).second.second; if (attribute.GetAttr(FLDATTR_final)) { FieldID id = mirBuilder->GetStructFieldIDFromFieldNameParentFirst( - classType, GlobalTables::GetStrTable().GetStringFromStrIdx(classType->GetFields()[i].first)); + classType, GlobalTables::GetStrTable().GetStringFromStrIdx(classType->GetFieldsElemt(i).first)); finalPrivateFieldID.push_back(id); } } @@ -804,7 +804,7 @@ void IPODevirtulize::SearchDefInMemberMethods(const Klass &klass) { continue; } for (size_t j = 0; j < callNode->GetReturnVec().size(); ++j) { - StIdx stIdx = callNode->GetReturnVec()[j].first; + StIdx stIdx = callNode->GetReturnPair(j).first; MIRSymbol *tmpSymbol = func->GetLocalOrGlobalSymbol(stIdx); ResetInferredType(gcmallocSymbols, tmpSymbol); } @@ -820,8 +820,8 @@ void IPODevirtulize::SearchDefInMemberMethods(const Klass &klass) { break; } case OP_intrinsiccallwithtype: { - IntrinsiccallNode *callnode = static_cast(stmt); - if (callnode->GetIntrinsic() != INTRN_JAVA_CLINIT_CHECK) { + IntrinsiccallNode *callNode = static_cast(stmt); + if (callNode->GetIntrinsic() != INTRN_JAVA_CLINIT_CHECK) { ResetInferredType(gcmallocSymbols); } break; @@ -977,7 +977,7 @@ void DoDevirtual(const Klass &klass, const KlassHierarchy &klassh) { if (op == OP_interfacecallassigned || op == OP_virtualcallassigned) { CallNode *callNode = static_cast(stmt); for (unsigned int i = 0; i < callNode->GetReturnVec().size(); ++i) { - StIdx stIdx = callNode->GetReturnVec()[i].first; + StIdx stIdx = callNode->GetReturnPair(i).first; MIRSymbol *tmpSymbol = func->GetLocalOrGlobalSymbol(stIdx); ResetInferredType(inferredSymbols, tmpSymbol); } @@ -1105,7 +1105,7 @@ void DoDevirtual(const Klass &klass, const KlassHierarchy &klassh) { break; } else if (tmpMethod == nullptr) { LogInfo::MapleLogger() << "Error: func " << calleeFunc->GetName() << " is not found!" << std::endl; - ASSERT(tmpMethod, "Must not be null"); + ASSERT(tmpMethod != nullptr, "Must not be null"); } calleeNode->SetPUIdx(tmpMethod->GetPuidx()); if (op == OP_virtualcall || op == OP_interfacecall) { @@ -1133,8 +1133,8 @@ void DoDevirtual(const Klass &klass, const KlassHierarchy &klassh) { if (op == OP_interfacecallassigned || op == OP_virtualcallassigned) { CallNode *callNode = static_cast(stmt); for (unsigned int i = 0; i < callNode->GetReturnVec().size(); ++i) { - StIdx stidx = callNode->GetReturnVec()[i].first; - MIRSymbol *tmpSymbol = func->GetLocalOrGlobalSymbol(stidx); + StIdx stIdx = callNode->GetReturnPair(i).first; + MIRSymbol *tmpSymbol = func->GetLocalOrGlobalSymbol(stIdx); ResetInferredType(inferredSymbols, tmpSymbol); } } @@ -1148,7 +1148,7 @@ void DoDevirtual(const Klass &klass, const KlassHierarchy &klassh) { case OP_callassigned: { CallNode *callNode = static_cast(stmt); for (size_t i = 0; i < callNode->GetReturnVec().size(); ++i) { - StIdx stIdx = callNode->GetReturnVec()[i].first; + StIdx stIdx = callNode->GetReturnPair(i).first; MIRSymbol *tmpSymbol = func->GetLocalOrGlobalSymbol(stIdx); ResetInferredType(inferredSymbols, tmpSymbol); } @@ -1193,17 +1193,17 @@ void IPODevirtulize::DevirtualFinal() { } } for (uint32 i = 0; i < classType->GetStaticFields().size(); ++i) { - FieldAttrs attribute = classType->GetStaticFields()[i].second.second; - if (GlobalTables::GetGsymTable().GetSymbolFromStrIdx(classType->GetStaticFields()[i].first) == nullptr) { + FieldAttrs attribute = classType->GetStaticFieldsPair(i).second.second; + if (GlobalTables::GetGsymTable().GetSymbolFromStrIdx(classType->GetStaticFieldsGStrIdx(i)) == nullptr) { continue; } TyIdx tyIdx = GlobalTables::GetGsymTable().GetSymbolFromStrIdx( - classType->GetStaticFields()[i].first)->GetInferredTyIdx(); + classType->GetStaticFieldsPair(i).first)->GetInferredTyIdx(); if (tyIdx != kInitTyIdx && tyIdx != kNoneTyIdx) { CHECK_FATAL(attribute.GetAttr(FLDATTR_final), "Must be final private"); if (debugFlag) { LogInfo::MapleLogger() << "Final Private Static Variable:" + - GlobalTables::GetStrTable().GetStringFromStrIdx(classType->GetStaticFields()[i].first) << '\n'; + GlobalTables::GetStrTable().GetStringFromStrIdx(classType->GetStaticFieldsPair(i).first) << '\n'; } } } @@ -1231,16 +1231,16 @@ void CallGraph::GenCallGraph() { } else if (info->GetCallType() == kCallTypeCall) { node->AddCallsite(**itInner, calleeNode); } else if (info->GetCallType() == kCallTypeSuperCall) { - const MIRFunction *calleefunc = info->GetFunc(); - Klass *klass = klassh->GetKlassFromFunc(calleefunc); + const MIRFunction *calleeFunc = info->GetFunc(); + Klass *klass = klassh->GetKlassFromFunc(calleeFunc); if (klass == nullptr) { // Fix CI continue; } - MapleVector *cands = klass->GetCandidates(calleefunc->GetBaseFuncNameWithTypeStrIdx()); + MapleVector *cands = klass->GetCandidates(calleeFunc->GetBaseFuncNameWithTypeStrIdx()); // continue to search its implinterfaces if (cands == nullptr) { - for (Klass *implinterface : klass->GetImplInterfaces()) { - cands = implinterface->GetCandidates(calleefunc->GetBaseFuncNameWithTypeStrIdx()); + for (Klass *implInterface : klass->GetImplInterfaces()) { + cands = implInterface->GetCandidates(calleeFunc->GetBaseFuncNameWithTypeStrIdx()); if (cands != nullptr && !cands->empty()) { break; } @@ -1307,29 +1307,29 @@ void CallGraph::DumpToFile(bool dumpAll) { if (Options::noDot) { return; } - std::ofstream cgfile; - char *outName = nullptr; + std::ofstream cgFile; + std::string outName; MapleString outfile(fileName, GetMempool()); if (dumpAll) { outName = (outfile.append("-callgraph.dot")).c_str(); } else { outName = (outfile.append("-callgraphlight.dot")).c_str(); } - cgfile.open(outName, std::ios::trunc); - cgfile << "digraph graphname {\n"; + cgFile.open(outName, std::ios::trunc); + cgFile << "digraph graphname {\n"; for (auto const &it : nodesMap) { CGNode *node = it.second; // dump user defined function if (dumpAll) { - node->Dump(cgfile); + node->Dump(cgFile); } else { if ((node->GetMIRFunction() != nullptr) && (!node->GetMIRFunction()->IsEmpty())) { - node->Dump(cgfile); + node->Dump(cgFile); } } } - cgfile << "}\n"; - cgfile.close(); + cgFile << "}\n"; + cgFile.close(); } void CallGraph::BuildCallGraph() { @@ -1380,8 +1380,8 @@ void CallGraph::SetCompilationFunclist() const { } } } - if ((mirModule->GetCompilationList().size() != mirModule->GetFunctionList().size() && - mirModule->GetCompilationList().size() != mirModule->GetFunctionList().size() - mirModule->GetOptFuncsSize())) { + if (mirModule->GetCompilationList().size() != mirModule->GetFunctionList().size() && + mirModule->GetCompilationList().size() != mirModule->GetFunctionList().size() - mirModule->GetOptFuncsSize()) { CHECK_FATAL(false, "should be equal"); } } @@ -1491,11 +1491,11 @@ void SCCNode::DumpCycle() const { void SCCNode::Verify() const { if (cgNodes.size() <= 0) { - CHECK_FATAL(false, ""); + CHECK_FATAL(false, "the size of cgNodes less than zero"); } for (CGNode *const &node : cgNodes) { if (node->GetSCCNode() != this) { - CHECK_FATAL(false, ""); + CHECK_FATAL(false, "must equal this"); } } } @@ -1548,7 +1548,7 @@ void CallGraph::BuildSCCDFS(CGNode &caller, uint32 &visitIndex, std::vectorGetSCCNode() == nullptr) { - CHECK_FATAL(false, ""); + CHECK_FATAL(false, "nullptr check in CallGraph::VerifySCC()"); } } } @@ -1649,9 +1649,9 @@ void CGNode::AddCandsForCallNode(const KlassHierarchy &kh) { CHECK_NULL_FATAL(mirFunc); Klass *klass = kh.GetKlassFromFunc(mirFunc); if (klass != nullptr) { - MapleVector *v = klass->GetCandidates(mirFunc->GetBaseFuncNameWithTypeStrIdx()); - if (v != nullptr) { - vcallCands = *v; // Vector copy + MapleVector *vec = klass->GetCandidates(mirFunc->GetBaseFuncNameWithTypeStrIdx()); + if (vec != nullptr) { + vcallCands = *vec; // Vector copy } } } @@ -1678,15 +1678,15 @@ MIRFunction *CGNode::HasOneCandidate() const { return (count == 1) ? cand : nullptr; } -AnalysisResult *DoCallGraph::Run(MIRModule *module, ModuleResultMgr *m) { +AnalysisResult *DoCallGraph::Run(MIRModule *module, ModuleResultMgr *mgr) { MemPool *memPool = memPoolCtrler.NewMemPool("callgraph mempool"); - KlassHierarchy *klassh = static_cast(m->GetAnalysisResult(MoPhase_CHA, module)); + KlassHierarchy *klassh = static_cast(mgr->GetAnalysisResult(MoPhase_CHA, module)); CHECK_FATAL(klassh != nullptr, "CHA can't be null"); CallGraph *cg = memPool->New(*module, *memPool, *klassh, module->GetFileName()); cg->InitCallExternal(); cg->SetDebugFlag(TRACE_PHASE); cg->BuildCallGraph(); - m->AddResult(GetPhaseID(), *module, *cg); + mgr->AddResult(GetPhaseID(), *module, *cg); if (!module->IsInIPA() && module->firstInline) { // do retype MemPool *localMp = memPoolCtrler.NewMemPool(PhaseName()); @@ -1698,9 +1698,9 @@ AnalysisResult *DoCallGraph::Run(MIRModule *module, ModuleResultMgr *m) { return cg; } -AnalysisResult *DoIPODevirtulize::Run(MIRModule *module, ModuleResultMgr *m) { +AnalysisResult *DoIPODevirtulize::Run(MIRModule *module, ModuleResultMgr *mgr) { MemPool *memPool = memPoolCtrler.NewMemPool("ipodevirulize mempool"); - KlassHierarchy *klassh = static_cast(m->GetAnalysisResult(MoPhase_CHA, module)); + KlassHierarchy *klassh = static_cast(mgr->GetAnalysisResult(MoPhase_CHA, module)); CHECK_NULL_FATAL(klassh); IPODevirtulize *dev = memPool->New(module, memPool, klassh); // Devirtualize vcall of final variable diff --git a/src/maple_ipa/src/clone.cpp b/src/maple_ipa/src/clone.cpp index f0610c1401519fc7689518ef5bcb085299135b86..972726165b7c9e1643385415ea24df657567c451 100644 --- a/src/maple_ipa/src/clone.cpp +++ b/src/maple_ipa/src/clone.cpp @@ -102,9 +102,9 @@ MIRFunction *Clone::CloneFunction(MIRFunction &originalFunction, const std::stri fullName = fullName.append( namemangler::kNameSplitterStr).append(newBaseFuncName).append(namemangler::kNameSplitterStr).append(signature); MIRFunction *newFunc = - dexBuilder.CreateFunction(fullName, *retType, argument, false, originalFunction.GetBody() != nullptr); + mirBuilder.CreateFunction(fullName, *retType, argument, false, originalFunction.GetBody() != nullptr); CHECK_FATAL(newFunc != nullptr, "create cloned function failed"); - dexBuilder.GetMirModule().AddFunction(newFunc); + mirBuilder.GetMirModule().AddFunction(newFunc); Klass *klass = kh->GetKlassFromName(originalFunction.GetBaseClassName()); CHECK_FATAL(klass != nullptr, "getklass failed"); klass->AddMethod(newFunc); @@ -119,13 +119,13 @@ MIRFunction *Clone::CloneFunction(MIRFunction &originalFunction, const std::stri newFunc->SetBaseClassFuncNames(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fullName)); if (originalFunction.GetBody() != nullptr) { CopyFuncInfo(originalFunction, *newFunc); - MIRFunction *originalCurrFunction = dexBuilder.GetCurrentFunctionNotNull(); - dexBuilder.SetCurrentFunction(*newFunc); + MIRFunction *originalCurrFunction = mirBuilder.GetCurrentFunctionNotNull(); + mirBuilder.SetCurrentFunction(*newFunc); newFunc->SetBody( originalFunction.GetBody()->CloneTree(originalFunction.GetModule()->GetCurFuncCodeMPAllocator())); CloneSymbols(*newFunc, originalFunction); CloneLabels(*newFunc, originalFunction); - dexBuilder.SetCurrentFunction(*originalCurrFunction); + mirBuilder.SetCurrentFunction(*originalCurrFunction); } return newFunc; } @@ -140,9 +140,9 @@ void Clone::CopyFuncInfo(const MIRFunction &originalFunction, MIRFunction &newFu auto funcNameIdx = newFunc.GetBaseFuncNameStrIdx(); auto fullNameIdx = newFunc.GetNameStrIdx(); auto classNameIdx = newFunc.GetBaseClassNameStrIdx(); - auto metaFullNameIdx = dexBuilder.GetOrCreateStringIndex(kFullNameStr); - auto metaClassNameIdx = dexBuilder.GetOrCreateStringIndex(kClassNameStr); - auto metaFuncNameIdx = dexBuilder.GetOrCreateStringIndex(kFuncNameStr); + auto metaFullNameIdx = mirBuilder.GetOrCreateStringIndex(kFullNameStr); + auto metaClassNameIdx = mirBuilder.GetOrCreateStringIndex(kClassNameStr); + auto metaFuncNameIdx = mirBuilder.GetOrCreateStringIndex(kFuncNameStr); const MIRInfoVector &fnInfo = originalFunction.GetInfoVector(); const MapleVector &infoIsString = originalFunction.InfoIsString(); size_t size = fnInfo.size(); @@ -162,10 +162,10 @@ void Clone::CopyFuncInfo(const MIRFunction &originalFunction, MIRFunction &newFu void Clone::UpdateFuncInfo(MIRFunction &newFunc) { auto fullNameIdx = newFunc.GetNameStrIdx(); - auto metaFullNameIdx = dexBuilder.GetOrCreateStringIndex(kFullNameStr); + auto metaFullNameIdx = mirBuilder.GetOrCreateStringIndex(kFullNameStr); size_t size = newFunc.GetInfoVector().size(); for (size_t i = 0; i < size; ++i) { - if (newFunc.GetInfoVector()[i].first == metaFullNameIdx) { + if (newFunc.GetInfoPair(i).first == metaFullNameIdx) { newFunc.SetMIRInfoNum(i, fullNameIdx); break; } @@ -174,23 +174,23 @@ void Clone::UpdateFuncInfo(MIRFunction &newFunc) { // Clone all functions that would be invoked with their return value ignored // @param original_function The original function to be cloned -// @param dexBuilder A helper object +// @param mirBuilder A helper object // @return Pointer to the newly cloned function MIRFunction *Clone::CloneFunctionNoReturn(MIRFunction &originalFunction) { const std::string oldSignature = originalFunction.GetSignature(); const std::string kNewMethodBaseName = replaceRetIgnored->GenerateNewBaseName(originalFunction); - MIRFunction *originalCurrFunction = dexBuilder.GetMirModule().CurFunction(); + MIRFunction *originalCurrFunction = mirBuilder.GetMirModule().CurFunction(); MIRFunction *newFunction = CloneFunction(originalFunction, kNewMethodBaseName, GlobalTables::GetTypeTable().GetTypeFromTyIdx(1)); - // new stmt should be located in the newFunction->codemp, dexBuilder.CreateStmtReturn will use CurFunction().codemp + // new stmt should be located in the newFunction->codemp, mirBuilder.CreateStmtReturn will use CurFunction().codemp // to assign space for the new stmt. So we set it correctly here. - dexBuilder.GetMirModule().SetCurFunction(newFunction); + mirBuilder.GetMirModule().SetCurFunction(newFunction); if (originalFunction.GetBody() != nullptr) { auto *body = newFunction->GetBody(); for (auto &stmt : body->GetStmtNodes()) { if (stmt.GetOpCode() == OP_return) { - body->ReplaceStmt1WithStmt2(&stmt, dexBuilder.CreateStmtReturn(nullptr)); + body->ReplaceStmt1WithStmt2(&stmt, mirBuilder.CreateStmtReturn(nullptr)); } } } @@ -203,7 +203,7 @@ MIRFunction *Clone::CloneFunctionNoReturn(MIRFunction &originalFunction) { funcSt->SetNameStrIdx(fullNameStrIdx); GlobalTables::GetGsymTable().AddToStringSymbolMap(*funcSt); UpdateFuncInfo(*newFunction); - dexBuilder.GetMirModule().SetCurFunction(originalCurrFunction); + mirBuilder.GetMirModule().SetCurFunction(originalCurrFunction); return newFunction; } @@ -235,13 +235,13 @@ void Clone::DoClone() { } } -AnalysisResult *DoClone::Run(MIRModule *module, ModuleResultMgr *mrm) { +AnalysisResult *DoClone::Run(MIRModule *module, ModuleResultMgr *mgr) { MemPool *memPool = memPoolCtrler.NewMemPool(PhaseName()); maple::MIRBuilder dexMirBuilder(module); - KlassHierarchy *kh = static_cast(mrm->GetAnalysisResult(MoPhase_CHA, module)); + KlassHierarchy *kh = static_cast(mgr->GetAnalysisResult(MoPhase_CHA, module)); Clone *clone = memPool->New(module, memPool, dexMirBuilder, kh); clone->DoClone(); - mrm->AddResult(GetPhaseID(), *module, *clone); + mgr->AddResult(GetPhaseID(), *module, *clone); return clone; } } // namespace maple diff --git a/src/maple_ipa/src/retype.cpp b/src/maple_ipa/src/retype.cpp index 96e6f5a8ac0add609fa140b29ae3782820ac0485..563563096d9251b6287f6a6a5460aec56adb9b8e 100644 --- a/src/maple_ipa/src/retype.cpp +++ b/src/maple_ipa/src/retype.cpp @@ -67,7 +67,7 @@ void Retype::RetypeStmt(MIRFunction &func) { if (stmt.GetOpCode() == OP_comment) { continue; } - for (size_t i = 0; i < stmt.NumOpnds(); i++) { + for (size_t i = 0; i < stmt.NumOpnds(); ++i) { BaseNode *opnd = stmt.Opnd(i); if (opnd->GetOpCode() == OP_retype) { stmt.SetOpnd(opnd->Opnd(0), i); diff --git a/src/maple_ir/include/bin_mir_file.h b/src/maple_ir/include/bin_mir_file.h index 1bc8986ecd1472acbacc2c38f007c9ca6b44b45a..286b8ee3f90f29134a5fb3a80afd3111cca5f129 100644 --- a/src/maple_ir/include/bin_mir_file.h +++ b/src/maple_ir/include/bin_mir_file.h @@ -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. @@ -32,7 +32,8 @@ enum BinMirFileType { inline uint8 MakeVersionNum(uint8 major, uint8 minor) { uint8 mj = major & 0x0Fu; uint8 mn = minor & 0x0Fu; - return (mj << 4) | mn; + constexpr uint8 shiftNum = 4; + return (mj << shiftNum) | mn; } // file header for binary format kMmpl, 8B in total diff --git a/src/maple_ir/include/global_tables.h b/src/maple_ir/include/global_tables.h index f8864c348d46c11e9bc64a359a8c57a0a5b06897..4a4242d5d3c29768e1c5663f07192895a02ecd64 100644 --- a/src/maple_ir/include/global_tables.h +++ b/src/maple_ir/include/global_tables.h @@ -298,8 +298,10 @@ class TypeTable { } // Get or Create derived types. - MIRType *GetOrCreatePointerType(TyIdx pointedTyIdx, PrimType primType = PTY_ptr); - MIRType *GetOrCreatePointerType(const MIRType &pointTo, PrimType primType = PTY_ptr); + MIRType *GetOrCreatePointerType(TyIdx pointedTyIdx, PrimType primType = PTY_ptr, + const std::vector attrs = std::vector()); + MIRType *GetOrCreatePointerType(const MIRType &pointTo, PrimType primType = PTY_ptr, + const std::vector attrs = std::vector()); const MIRType *GetPointedTypeIfApplicable(MIRType &type) const; MIRType *GetPointedTypeIfApplicable(MIRType &type); MIRType *GetVoidPtr() const { @@ -543,6 +545,11 @@ class FunctionTable { return funcTable.at(pIdx); } + void SetFunctionItem(uint32 pIdx, MIRFunction *func) { + CHECK_FATAL(pIdx < funcTable.size(), "Invalid puIdx"); + funcTable[pIdx] = func; + } + private: std::vector funcTable; // index is PUIdx }; diff --git a/src/maple_ir/include/intrinsics.def b/src/maple_ir/include/intrinsics.def index 6bffa567154ce0cda0ee407ee8f51211929cf2ee..582088976215554df32eed7798a0a344a1b427ec 100644 --- a/src/maple_ir/include/intrinsics.def +++ b/src/maple_ir/include/intrinsics.def @@ -39,6 +39,8 @@ DEF_MIR_INTRINSIC(MPL_READ_OVTABLE_ENTRY_FIELD_LAZY,\ "__mpl_const_offset_field_lazy", INTRNISPURE, kArgTyA32, kArgTyDynany, kArgTyDynany, kArgTyDynany, kArgTyUndef, kArgTyUndef, kArgTyUndef) DEF_MIR_INTRINSIC(MPL_BOUNDARY_CHECK,\ "", INTRNISJAVA | INTRNNOSIDEEFFECT, kArgTyVoid, kArgTyU1, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) +DEF_MIR_INTRINSIC(MPL_READ_ARRAYCLASS_CACHE_ENTRY,\ + "__mpl_const_arrayclass_cache", kIntrnUndef, kArgTyPtr, kArgTyU32, kArgTyDynany, kArgTyDynany, kArgTyUndef, kArgTyUndef, kArgTyUndef) // start of RC Intrinsics with one parameters DEF_MIR_INTRINSIC(MCCIncRef,\ diff --git a/src/maple_ir/include/metadata_layout.h b/src/maple_ir/include/metadata_layout.h index e531698d1c6c78669bce3f3183d940a539259519..7c5654cf312c56055880906e9416c34a69f5e42b 100644 --- a/src/maple_ir/include/metadata_layout.h +++ b/src/maple_ir/include/metadata_layout.h @@ -37,7 +37,7 @@ struct DataRefOffset32 { template inline T GetDataRef() const; inline int32_t GetRawValue() const; - inline void SetRawValue(int64_t value); + inline void SetRawValue(int32_t value); }; struct DataRefOffsetPtr { @@ -46,8 +46,8 @@ struct DataRefOffsetPtr { inline void SetDataRef(T ref); template inline T GetDataRef() const; - inline int64_t GetRawValue() const; - inline void SetRawValue(int64_t value); + inline intptr_t GetRawValue() const; + inline void SetRawValue(intptr_t value); }; struct DataRefOffset { @@ -60,8 +60,8 @@ struct DataRefOffset { inline void SetDataRef(T ref); template inline T GetDataRef() const; - inline int64_t GetRawValue() const; - inline void SetRawValue(int64_t value); + inline intptr_t GetRawValue() const; + inline void SetRawValue(intptr_t value); }; struct MethodFieldRef { @@ -78,8 +78,8 @@ struct MethodFieldRef { inline bool IsCompact() const; template inline T GetCompactData() const; - inline int64_t GetRawValue() const; - inline void SetRawValue(int64_t value); + inline intptr_t GetRawValue() const; + inline void SetRawValue(intptr_t value); }; // DataRef aims for reference to data in maple file (generated by maple compiler) and is aligned to at least 4 bytes. diff --git a/src/maple_ir/include/mir_function.h b/src/maple_ir/include/mir_function.h index 1d2775b7b79ce618e8d6ae8c105c6efcdc4ecca1..c2f14d2a2631717a2eb5d85e1c35bb21b0d60b6e 100644 --- a/src/maple_ir/include/mir_function.h +++ b/src/maple_ir/include/mir_function.h @@ -527,9 +527,15 @@ class MIRFunction { const MIRInfoVector &GetInfoVector() const { return info; } + + const MIRInfoPair &GetInfoPair(size_t i) const { + return info.at(i); + } + void PushbackMIRInfo(const MIRInfoPair &pair) { info.push_back(pair); } + void SetMIRInfoNum(size_t idx, uint32 num) { info[idx].second = num; } diff --git a/src/maple_ir/include/mir_nodes.h b/src/maple_ir/include/mir_nodes.h index f7693c3dc7a485ccf47bdd0188084860852a834d..40f1267a9077a0fe472de491ab2c09a9f4645369 100644 --- a/src/maple_ir/include/mir_nodes.h +++ b/src/maple_ir/include/mir_nodes.h @@ -2134,6 +2134,10 @@ class RangeGotoNode : public UnaryStmtNode { return rangegotoTable; } + const SmallCasePair &GetRangeGotoTableItem(size_t i) const { + return rangegotoTable.at(i); + } + void SetRangeGotoTable(SmallCaseVector rt) { rangegotoTable = rt; } diff --git a/src/maple_ir/include/mir_symbol.h b/src/maple_ir/include/mir_symbol.h index 396497f050e81e2f6da212534b6026542aa67437..0dbb88a2b2d4071e43fba99780e55c65a84f1677 100644 --- a/src/maple_ir/include/mir_symbol.h +++ b/src/maple_ir/include/mir_symbol.h @@ -347,6 +347,8 @@ class MIRSymbol { bool IsMuidDataUndefMuidTab() const; bool IsMuidFuncMuidIdxMuidTab() const; bool IsMuidRangeTab() const; + bool IsArrayClassCache() const; + bool IsArrayClassCacheName() const; bool IsGctibSym() const; bool IsPrimordialObject() const; bool IgnoreRC() const; diff --git a/src/maple_ir/include/mir_type.h b/src/maple_ir/include/mir_type.h index 9e20926f9dea8a44769184fab7b3d9ed50ef3110..e3f6f337149a544a478cb34889a4aa6f3c727732 100755 --- a/src/maple_ir/include/mir_type.h +++ b/src/maple_ir/include/mir_type.h @@ -761,6 +761,14 @@ class MIRStructType : public MIRType { return staticFields; } + const FieldPair &GetStaticFieldsPair(size_t i) const { + return staticFields.at(i); + } + + GStrIdx GetStaticFieldsGStrIdx(size_t i) const { + return staticFields.at(i).first; + } + FieldVector &GetParentFields() { return parentFields; } diff --git a/src/maple_ir/include/opcode_info.h b/src/maple_ir/include/opcode_info.h index c4d1aa145a5c3d9d287a3deb5337c8fd1836768e..2f36d95431cd67c3f3c53126be5691daf7a122fe 100644 --- a/src/maple_ir/include/opcode_info.h +++ b/src/maple_ir/include/opcode_info.h @@ -50,7 +50,7 @@ constexpr unsigned long OPCODEMAYTHROWEXCEPTION = 1ULL << kOpcodePropMayThrowExc struct OpcodeDesc { uint8 instrucSize; // size of instruction in bytes uint16 flag; // stores the opcode property flags - const char *name; + std::string name; }; class OpcodeTable { @@ -123,7 +123,7 @@ class OpcodeTable { return MayThrowException(o); } - const char *GetName(Opcode o) const { + const std::string &GetName(Opcode o) const { ASSERT(o < OP_last, "invalid opcode"); return table[o].name; } diff --git a/src/maple_ir/src/global_tables.cpp b/src/maple_ir/src/global_tables.cpp index ea4e7818c2dd7719e95b25fac586df8d755a0491..d9c437d44ff82a243b2019131c8f428042c7bf5c 100755 --- a/src/maple_ir/src/global_tables.cpp +++ b/src/maple_ir/src/global_tables.cpp @@ -113,18 +113,25 @@ MIRType* TypeTable::GetOrCreateMIRTypeNode(MIRType &pType) { MIRType *TypeTable::voidPtrType = nullptr; // get or create a type that pointing to pointedTyIdx -MIRType *TypeTable::GetOrCreatePointerType(TyIdx pointedTyIdx, PrimType primType) { + MIRType *TypeTable::GetOrCreatePointerType(TyIdx pointedTyIdx, PrimType primType, + const std::vector attrs) { MIRPtrType type(pointedTyIdx, primType); + if (!attrs.empty()) { + for (auto &attr : attrs) { + type.SetTypeAttrs(attr); + } + } TyIdx tyIdx = GetOrCreateMIRType(&type); ASSERT(tyIdx < typeTable.size(), "index out of range in TypeTable::GetOrCreatePointerType"); return typeTable.at(tyIdx); } -MIRType *TypeTable::GetOrCreatePointerType(const MIRType &pointTo, PrimType primType) { +MIRType *TypeTable::GetOrCreatePointerType(const MIRType &pointTo, PrimType primType, + const std::vector attrs) { if (pointTo.GetPrimType() == PTY_constStr) { primType = PTY_ptr; } - return GetOrCreatePointerType(pointTo.GetTypeIndex(), primType); + return GetOrCreatePointerType(pointTo.GetTypeIndex(), primType, attrs); } const MIRType *TypeTable::GetPointedTypeIfApplicable(MIRType &type) const { diff --git a/src/maple_ir/src/mir_nodes.cpp b/src/maple_ir/src/mir_nodes.cpp index 7f4f79f455733e0be763b1f210ecbb6f37231e52..8fc9f2abc8e4cb30ef8521539e126964dab35cf1 100644 --- a/src/maple_ir/src/mir_nodes.cpp +++ b/src/maple_ir/src/mir_nodes.cpp @@ -39,7 +39,7 @@ const char *GetIntrinsicName(MIRIntrinsicID intrn) { } const char *BaseNode::GetOpName() const { - return kOpcodeInfo.GetTableItemAt(GetOpCode()).name; + return kOpcodeInfo.GetTableItemAt(GetOpCode()).name.c_str(); } bool BaseNode::MayThrowException() { diff --git a/src/maple_ir/src/mir_symbol.cpp b/src/maple_ir/src/mir_symbol.cpp index f1cd189cbbba48d28359fd9ae9f4d705d51ae640..e315514157c0c40d4cff586caadc4581e132fd2c 100644 --- a/src/maple_ir/src/mir_symbol.cpp +++ b/src/maple_ir/src/mir_symbol.cpp @@ -158,6 +158,14 @@ bool MIRSymbol::IsMuidRangeTab() const { return StringUtils::StartsWith(GetName(), kMuidRangeTabPrefixStr); } +bool MIRSymbol::IsArrayClassCache() const { + return StringUtils::StartsWith(GetName(), kArrayClassCacheTable); +} + +bool MIRSymbol::IsArrayClassCacheName() const { + return StringUtils::StartsWith(GetName(), kArrayClassCacheNameTable); +} + bool MIRSymbol::IsClassInitBridge() const { return StringUtils::StartsWith(GetName(), CLASS_INIT_BRIDGE_PREFIX_STR); } diff --git a/src/maple_me/include/me_abco.h b/src/maple_me/include/me_abco.h index 4c9d9464fea2f8de9fe210eeb670d0cddf81a35c..6d4e44f1a06216ff7b9635de03f9a73e830b389c 100755 --- a/src/maple_me/include/me_abco.h +++ b/src/maple_me/include/me_abco.h @@ -255,7 +255,7 @@ class MeABC { bool CleanABCInStmt(MeStmt &meStmt, NaryMeExpr &naryMeExpr); MeExpr *ReplaceArrayExpr(MeExpr &rhs, MeExpr &naryMeExpr, MeStmt *ivarStmt); bool HasRelativeWithLength(MeExpr &meExpr); - bool ProveGreaterZ(MeExpr &weight); + bool ProveGreaterZ(const MeExpr &weight); void ReSolveEdge(); Dominance *GetDominace() { return dom; diff --git a/src/maple_me/include/me_critical_edge.h b/src/maple_me/include/me_critical_edge.h index fa1c516aafda2c791047d46d3b4789319518ccca..455e71934f527809318670bf405d731f807cf554 100644 --- a/src/maple_me/include/me_critical_edge.h +++ b/src/maple_me/include/me_critical_edge.h @@ -32,7 +32,7 @@ class MeDoSplitCEdge : public MeFuncPhase { } private: - void UpdateNewBBInTry(BB &newBB, BB &pred) const; + void UpdateNewBBInTry(BB &newBB, const BB &pred) const; void UpdateGotoLabel(BB &newBB, MeFunction &func, BB &pred, BB &succ) const; void UpdateCaseLabel(BB &newBB, MeFunction &func, BB &pred, BB &succ) const; void BreakCriticalEdge(MeFunction &func, BB &pred, BB &succ) const; diff --git a/src/maple_me/include/me_ir.h b/src/maple_me/include/me_ir.h index be0064672b64921381e2f9718c3b3da1d89c23c6..018334f4521fb76b61b39fa296310859c24a6459 100755 --- a/src/maple_me/include/me_ir.h +++ b/src/maple_me/include/me_ir.h @@ -207,7 +207,7 @@ class ScalarMeExpr : public MeExpr { ~ScalarMeExpr() = default; - bool IsIdentical(MeExpr&) { + bool IsIdentical(MeExpr&) const { CHECK_FATAL(false, "ScalarMeExpr::IsIdentical() should not be called"); return true; } diff --git a/src/maple_me/src/me_abco.cpp b/src/maple_me/src/me_abco.cpp index 6e7637553ce2ad0993907661d1066bcefa30957b..636abaa2571e1ec74e21c809f427b3b39e262654 100755 --- a/src/maple_me/src/me_abco.cpp +++ b/src/maple_me/src/me_abco.cpp @@ -1332,7 +1332,7 @@ void MeABC::CollectCareInsns() { CHECK_FATAL(arrayNewChecks.size() == arrayChecks.size(), "must be"); } -bool MeABC::ProveGreaterZ(MeExpr &weight) { +bool MeABC::ProveGreaterZ(const MeExpr &weight) { ESSABaseNode &zNode = inequalityGraph->GetNode(0); ESSABaseNode *idxNode = &(inequalityGraph->GetNode(weight)); bool lowerResult = prove->DemandProve(zNode, *idxNode, kLower); diff --git a/src/maple_me/src/me_bypath_eh.cpp b/src/maple_me/src/me_bypath_eh.cpp index c1632fa7d7923506b6c73a7467a397d559ccecdb..5452487ed2f3f528defc7713d37499cd80da600d 100644 --- a/src/maple_me/src/me_bypath_eh.cpp +++ b/src/maple_me/src/me_bypath_eh.cpp @@ -58,6 +58,14 @@ bool MeDoBypathEH::DoBypathException(BB *tryBB, BB *catchBB, const Klass *catchC pTypeIdx = (static_cast(pType))->GetPointedType()->GetTypeIndex(); throwClass = kh.GetKlassFromTyIdx(pTypeIdx); rhExpr = iread; + } else if (node->Opnd(0)->GetOpCode() == OP_constval) { + /* + * when cfg changed, this phase will re-run, + * some throw would like: + * throw (constval ref 0) + * see: https://gitlab.huawei.com/Maple/ArkKit/issues/283 + */ + continue; } else { CHECK_FATAL(false, "Can't be here!"); } @@ -65,6 +73,8 @@ bool MeDoBypathEH::DoBypathException(BB *tryBB, BB *catchBB, const Klass *catchC continue; } MIRBuilder *mirBuilder = func.GetMIRModule().GetMIRBuilder(); + UnaryStmtNode *nullCheck = mirBuilder->CreateStmtUnary(OP_assertnonnull, rhExpr); + bb->InsertStmtBefore(stmt, nullCheck); DassignNode *copyStmt = mirBuilder->CreateStmtDassign(stIdx, 0, rhExpr); bb->InsertStmtBefore(stmt, copyStmt); CHECK_NULL_FATAL(catchBB); diff --git a/src/maple_me/src/me_critical_edge.cpp b/src/maple_me/src/me_critical_edge.cpp index 40c28e3322d81eca931406b5a5d768e662583127..1af410e86c5b9099b539e08d66d3c19b4ab0edd0 100644 --- a/src/maple_me/src/me_critical_edge.cpp +++ b/src/maple_me/src/me_critical_edge.cpp @@ -32,7 +32,7 @@ // newbb is always appended at the end of bb_vec_ and pred/succ will be updated. // The bblayout phase will determine the final layout order of the bbs. namespace maple { -void MeDoSplitCEdge::UpdateNewBBInTry(BB &newBB, BB &pred) const { +void MeDoSplitCEdge::UpdateNewBBInTry(BB &newBB, const BB &pred) const { newBB.SetAttributes(kBBAttrIsTry); for (auto *candCatch : pred.GetSucc()) { if (candCatch != nullptr && candCatch->GetAttributes(kBBAttrIsCatch)) { diff --git a/src/maple_me/src/me_rename2preg.cpp b/src/maple_me/src/me_rename2preg.cpp index 261ded04473db89406b71edf88ac9261ba1f1f83..230919751ef46d0efb45a9e1e60249ebec85fba3 100755 --- a/src/maple_me/src/me_rename2preg.cpp +++ b/src/maple_me/src/me_rename2preg.cpp @@ -378,7 +378,7 @@ class SSARename2Preg { return; } - VarMeExpr &varExpr =(utils::ToRef(lhs)); + VarMeExpr &varExpr = (utils::ToRef(lhs)); RegMeExpr *pRegExpr = RenameVar(aliasClass, varExpr); if (pRegExpr == nullptr) { return; diff --git a/src/maple_phase/include/phase.h b/src/maple_phase/include/phase.h index 4420d9daa402ae02b52aadb9cb5cb2cc50a8bebc..0a544988590f456b28ac5b9c8a8ecb4da3f931ed 100644 --- a/src/maple_phase/include/phase.h +++ b/src/maple_phase/include/phase.h @@ -99,7 +99,7 @@ class Phase { MemPoolCtrler *mpCtrler = &memPoolCtrler; }; -template +template class AnalysisResultManager { public: explicit AnalysisResultManager(MapleAllocator *alloc) diff --git a/src/maple_util/include/mpl_number.h b/src/maple_util/include/mpl_number.h index f4db2a0534be43c5a3dec434f98b31bda198fd22..69b0b118f3053d4ef06de9399b5f831f79afd270 100644 --- a/src/maple_util/include/mpl_number.h +++ b/src/maple_util/include/mpl_number.h @@ -82,7 +82,7 @@ class Number { } template>, - meta_not>>::value>> + meta_not>>::value>> explicit operator U() const noexcept { return static_cast(val); } @@ -179,73 +179,73 @@ inline Number operator-(const Number &lhs, const Number } template, std::is_enum>::value>> + typename = std::enable_if_t, std::is_enum>::value>> inline bool operator==(const Number &lhs, const U &rhs) { return lhs.get() == rhs; } template, std::is_enum>::value>> + typename = std::enable_if_t, std::is_enum>::value>> inline bool operator==(const U &lhs, const Number &rhs) { return lhs == rhs.get(); } template, std::is_enum>::value>> + typename = std::enable_if_t, std::is_enum>::value>> inline bool operator!=(const Number &lhs, const U &rhs) { return !(lhs == rhs); } template, std::is_enum>::value>> + typename = std::enable_if_t, std::is_enum>::value>> inline bool operator!=(const U &lhs, const Number &rhs) { return !(lhs == rhs); } template, std::is_enum>::value>> + typename = std::enable_if_t, std::is_enum>::value>> inline bool operator<(const Number &lhs, const U &rhs) { return lhs.get() < rhs; } template, std::is_enum>::value>> + typename = std::enable_if_t, std::is_enum>::value>> inline bool operator<(const U &lhs, const Number &rhs) { return lhs < rhs.get(); } template, std::is_enum>::value>> + typename = std::enable_if_t, std::is_enum>::value>> inline bool operator<=(const Number &lhs, const U &rhs) { return lhs.get() <= rhs; } template, std::is_enum>::value>> + typename = std::enable_if_t, std::is_enum>::value>> inline bool operator<=(const U &lhs, const Number &rhs) { return lhs <= rhs.get(); } template, std::is_enum>::value>> + typename = std::enable_if_t, std::is_enum>::value>> inline bool operator>(const Number &lhs, const U &rhs) { return !(lhs <= rhs); } template, std::is_enum>::value>> + typename = std::enable_if_t, std::is_enum>::value>> inline bool operator>(const U &lhs, const Number &rhs) { return !(lhs <= rhs); } template, std::is_enum>::value>> + typename = std::enable_if_t, std::is_enum>::value>> inline bool operator>=(const Number &lhs, const U &rhs) { return !(lhs < rhs); } template, std::is_enum>::value>> + typename = std::enable_if_t, std::is_enum>::value>> inline bool operator>=(const U &lhs, const Number &rhs) { return !(lhs < rhs); } @@ -278,7 +278,8 @@ inline OS &operator<<(OS &os, const Number &num) { template using Index = Number; -}} +} +} namespace std { template diff --git a/src/maple_util/include/muid.h b/src/maple_util/include/muid.h index 2a7acdebd19ed1ecdd5b0505bd59097d6e393881..99138a579b1e10e0bc0834aee31322db984f94b5 100644 --- a/src/maple_util/include/muid.h +++ b/src/maple_util/include/muid.h @@ -66,11 +66,11 @@ class MUID { public: union { #ifdef USE_64BIT_MUID - uint32_t words[kNumLowAndHigh]; + uint32_t words[kNumLowAndHigh] = { 0 }; uint8_t bytes[kMuidLength]; uint64_t raw; #else - uint64_t words[kNumLowAndHigh]; + uint64_t words[kNumLowAndHigh] = { 0 }; uint8_t bytes[kMuidLength]; #endif // USE_64BIT_MUID } data; @@ -116,21 +116,12 @@ class MUID { #endif // USE_64BIT_MUID return sbuf.str(); } - - // Return 64-bit size hash for AArch64. - uint64_t hash() const { -#ifdef USE_64BIT_MUID - return data.raw; -#else - return data.words[0]; // Just return one word. -#endif // USE_64BIT_MUID - } }; void MuidInit(MuidContext &status); void MuidDecode(MuidContext &status, const unsigned char &data, uint64_t size); -template +template void FullEncode(T &result, MuidContext &status); void MuidEncode(unsigned char (&result)[kDigestShortHashLength], MuidContext &status); void MuidEncode(unsigned char (&result)[kDigestHashLength], MuidContext &status, bool use64Bit = false); diff --git a/src/maple_util/include/namemangler.h b/src/maple_util/include/namemangler.h index e997b85743af4780d2a030b1d5bf3d283fb6569e..f6dcafc89b40487f1a86b311940c46d086e2ff06 100644 --- a/src/maple_util/include/namemangler.h +++ b/src/maple_util/include/namemangler.h @@ -156,6 +156,8 @@ static constexpr const char kCallFastNativeExt[] = "MCC_CallFastNativeExt"; static constexpr const char kCallSlowNativeExt[] = "MCC_CallSlowNativeExt"; static constexpr const char kSetReliableUnwindContextFunc[] = "MCC_SetReliableUnwindContext"; +static constexpr const char kArrayClassCacheTable[] = "__arrayClassCacheTable"; +static constexpr const char kArrayClassCacheNameTable[] = "__muid_ro_arrayClassCacheNameTable"; static constexpr const char kFunctionLayoutStr[] = "__func_layout__"; static constexpr const char kFunctionProfileTabPrefixStr[] = "__muid_profile_func_tab"; diff --git a/src/maple_util/include/ptr.h b/src/maple_util/include/ptr.h index a6a8a6b790401bec57e8c7eb06f289e75732aca9..c530999b2a709b2c70fa6a33f7e78db1d853b1ad 100644 --- a/src/maple_util/include/ptr.h +++ b/src/maple_util/include/ptr.h @@ -28,7 +28,7 @@ template Check = CheckNothing> class Ptr { public: using Pointer = T*; - using element_type = T; + using ElementType = T; constexpr Ptr() noexcept : pointer(nullptr) { @@ -293,6 +293,7 @@ template CheckT> inline bool operator>=(std::nullptr_t, const Ptr &rhs) { return !(rhs > nullptr); } -}} +} +} #endif //DIY_CPLUSPLUS_SAFE_PTR_H diff --git a/src/maple_util/include/safe_ptr.h b/src/maple_util/include/safe_ptr.h index 3bea5d76b5cb06fbc5422fd27304c1a13a0c3f53..c8220ea065501aa23dce0100d1f47881204521ae 100644 --- a/src/maple_util/include/safe_ptr.h +++ b/src/maple_util/include/safe_ptr.h @@ -14,7 +14,7 @@ */ #ifndef MAPLE_UTIL_SAFE_PTR_H #define MAPLE_UTIL_SAFE_PTR_H -#include +#include "mpl_logging.h" #include "ptr.h" namespace maple { @@ -29,7 +29,7 @@ class SafePtr { using Base = Ptr>; public: using pointer = typename Base::Pointer; - using ElementType = typename Base::element_type; + using ElementType = typename Base::ElementType; constexpr SafePtr() noexcept = delete; diff --git a/src/mpl2mpl/include/annotation_analysis.h b/src/mpl2mpl/include/annotation_analysis.h index 101916fb0235f22451d8292e418fc5e4478b8fa5..71dc24c2a116f81e6eff8eee30fa387e973f4ad7 100644 --- a/src/mpl2mpl/include/annotation_analysis.h +++ b/src/mpl2mpl/include/annotation_analysis.h @@ -262,11 +262,11 @@ class AnnotationAnalysis : AnalysisResult { void AnalysisAnnotation(); void AnnotationCleanUp(); void AnalysisAnnotationForClass(MIRPragma &classPragma); - void AnalysisAnnotationForVar(MIRPragma &varPragma, MIRStructType &structType); + void AnalysisAnnotationForVar(const MIRPragma &varPragma, MIRStructType &structType); void AnalysisAnnotationForFunc(MIRPragma &funcPragma, MIRStructType &structType); AnnotationType *ReadInGenericType(AnnotationParser &aParser, MIRStructType *sType); GenericDeclare *ReadInGenericDeclare(AnnotationParser &aParser, MIRStructType *mirStructType = nullptr); - std::string ReadInAllSubString(MIRPragma &classPragma); + std::string ReadInAllSubString(const MIRPragma &classPragma); void AAForClassInfo(MIRStructType &structType); void AAForFuncVarInfo(MIRStructType &structType); void AnalysisAnnotationForFuncLocalVar(MIRFunction &func, AnnotationParser &aParser, MIRStructType &structType); diff --git a/src/mpl2mpl/include/muid_replacement.h b/src/mpl2mpl/include/muid_replacement.h old mode 100755 new mode 100644 index b03a9ca7b5a568500766fa434e192bac9f018839..b4cbb019eb8b877e01240d063709af9f6f7642c8 --- a/src/mpl2mpl/include/muid_replacement.h +++ b/src/mpl2mpl/include/muid_replacement.h @@ -52,7 +52,9 @@ enum RangeIdx { kDecoupleStaticValue = 19, kBssStart = 20, kLinkerSoHash = 21, - kNewMaxNum = 22 // New num + kArrayClassCache = 22, + kArrayClassCacheName = 23, + kNewMaxNum = 24 // New num }; class MUIDReplacement : public FuncOptimizeImpl { @@ -118,6 +120,11 @@ class MUIDReplacement : public FuncOptimizeImpl { void CollectSuperClassArraySymbolData(); static MIRSymbol *GetSymbolFromName(const std::string &name); ConstvalNode* GetConstvalNode(int64 index); + void InsertArrayClassSet(const MIRType &type); + MIRType *GetIntrinsicConstArrayClass(StmtNode &stmt); + void CollectArrayClass(); + void GenArrayClassCache(); + std::unordered_set arrayClassSet; // The following sets are for internal uses. Sorting order does not matter here. std::unordered_set funcDefSet; std::unordered_set funcUndefSet; diff --git a/src/mpl2mpl/include/reflection_analysis.h b/src/mpl2mpl/include/reflection_analysis.h index a02093e701bee6b92091ef4f1f69eeb4f0f924f9..e0ffe77a468b1fbbd74665cf1e25da57e1a33976 100644 --- a/src/mpl2mpl/include/reflection_analysis.h +++ b/src/mpl2mpl/include/reflection_analysis.h @@ -220,6 +220,7 @@ class ReflectionAnalysis : public AnalysisResult { std::map *paramNumArray = nullptr, int *paramIndex = nullptr); void AppendValueByType(std::string &annoArr, const MIRPragmaElement &elem); bool IsAnonymousClass(const std::string &annotationString); + bool IsLocalClass(const std::string annotationString); bool IsPrivateClass(const MIRClassType &classType) const; bool IsStaticClass(const MIRStructType &classType) const; int8 JudgePara(MIRStructType &ctype); diff --git a/src/mpl2mpl/src/annotation_analysis.cpp b/src/mpl2mpl/src/annotation_analysis.cpp index 6c73b3fc1a3736bc9926fb69f4720c47166dcb74..af5c658fcfac3b0b739777ec7d72a9a20640d06d 100644 --- a/src/mpl2mpl/src/annotation_analysis.cpp +++ b/src/mpl2mpl/src/annotation_analysis.cpp @@ -18,7 +18,7 @@ namespace maple { char AnnotationAnalysis::annoDeclare = ':'; char AnnotationAnalysis::annoSemiColon = ';'; int AnnotationType::atime = 0; -MIRStructType *GetClassTypeFromName(std::string &className) { +MIRStructType *GetClassTypeFromName(const std::string &className) { GStrIdx strIdx = GlobalTables::GetStrTable().GetStrIdxFromName(className); if (strIdx == 0) { strIdx = GlobalTables::GetStrTable().GetStrIdxFromName("Ljava_2Flang_2FObject_3B"); @@ -369,7 +369,7 @@ GenericDeclare *AnnotationAnalysis::ReadInGenericDeclare(AnnotationParser &aPars return gDeclare; } -std::string AnnotationAnalysis::ReadInAllSubString(MIRPragma &classPragma) { +std::string AnnotationAnalysis::ReadInAllSubString(const MIRPragma &classPragma) { GStrIdx gStrIdx; std::string signature; CHECK_FATAL(classPragma.GetElementVector().size() == 1, "must be"); @@ -454,7 +454,7 @@ void AnnotationAnalysis::AnalysisAnnotationForFunc(MIRPragma &funcPragma, MIRStr AnalysisAnnotationForFuncLocalVar(*func, aParser, structType); } -void AnnotationAnalysis::AnalysisAnnotationForVar(MIRPragma &varPragma, MIRStructType &structType) { +void AnnotationAnalysis::AnalysisAnnotationForVar(const MIRPragma &varPragma, MIRStructType &structType) { std::string signature = ReadInAllSubString(varPragma); AnnotationParser aParser(signature); ATokenKind tk = aParser.GetNextToken(); diff --git a/src/mpl2mpl/src/muid_replacement.cpp b/src/mpl2mpl/src/muid_replacement.cpp index 81c35dd6dba3a1b67a413e53de9414f42de11842..ff58e0bfd0d57c8d4ad003d80b81840349ee8844 100644 --- a/src/mpl2mpl/src/muid_replacement.cpp +++ b/src/mpl2mpl/src/muid_replacement.cpp @@ -113,6 +113,96 @@ void MUIDReplacement::DumpMUIDFile(bool isFunc) { outFile.close(); } +void MUIDReplacement::InsertArrayClassSet(const MIRType &type) { + auto jArrayType = static_cast(type); + std::string klassJavaDescriptor; + namemangler::DecodeMapleNameToJavaDescriptor(jArrayType.GetJavaName(), klassJavaDescriptor); + arrayClassSet.insert(klassJavaDescriptor); +} + +MIRType *MUIDReplacement::GetIntrinsicConstArrayClass(StmtNode &stmt) { + Opcode op = stmt.GetOpCode(); + if (op == OP_dassign || op == OP_regassign) { + auto &unode = static_cast(stmt); + BaseNode &rhsOpnd = *(unode.GetRHS()); + Opcode rhsOp = rhsOpnd.GetOpCode(); + if (rhsOp == OP_intrinsicopwithtype) { + auto &intrinNode = static_cast(rhsOpnd); + MIRIntrinsicID intrinsicID = intrinNode.GetIntrinsic(); + if (intrinsicID == INTRN_JAVA_CONST_CLASS || intrinsicID == INTRN_JAVA_INSTANCE_OF) { + TyIdx tyIdx = intrinNode.GetTyIdx(); + MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); + MIRPtrType *ptrType = static_cast(type); + MIRType *jArrayTy = ptrType->GetPointedType(); + if (jArrayTy->GetKind() == kTypeArray || jArrayTy->GetKind() == kTypeJArray) { + return jArrayTy; + } + } + } else if ((rhsOp == OP_gcmallocjarray) || (rhsOp == OP_gcpermallocjarray)) { + JarrayMallocNode &jarrayMallocNode = static_cast(rhsOpnd); + TyIdx tyIdx = jarrayMallocNode.GetTyIdx(); + MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); + if (type->GetKind() == kTypeArray || type->GetKind() == kTypeJArray) { + return type; + } + } + } + return nullptr; +} + +void MUIDReplacement::CollectArrayClass() { + for (MIRFunction *mirFunc : GetMIRModule().GetFunctionList()) { + if (mirFunc->GetBody() == nullptr) { + continue; + } + StmtNode *stmt = mirFunc->GetBody()->GetFirst(); + StmtNode *nextStmt = nullptr; + while (stmt) { + nextStmt = stmt->GetNext(); + MIRType *jArrayTy = GetIntrinsicConstArrayClass(*stmt); + if (jArrayTy != nullptr) { + InsertArrayClassSet(*jArrayTy); + } + stmt = nextStmt; + } + } +} + +void MUIDReplacement::GenArrayClassCache() { + if (arrayClassSet.size() == 0) { + return; + } +#ifdef USE_32BIT_REF + MIRType *mType = GlobalTables::GetTypeTable().GetUInt32(); +#else + MIRType *mType = GlobalTables::GetTypeTable().GetUInt64(); +#endif + auto arrayType = GlobalTables::GetTypeTable().GetOrCreateArrayType(*mType, static_cast(arrayClassSet.size())); + auto *arrayClassNameConst = GetMIRModule().GetMemPool()->New(GetMIRModule(), *arrayType); + auto *arrayClassConst = GetMIRModule().GetMemPool()->New(GetMIRModule(), *arrayType); + ASSERT_NOT_NULL(arrayClassNameConst); + ASSERT_NOT_NULL(arrayClassConst); + // magic number, must consistent with kMplArrayClassCacheMagicNumber(0x1a3) in runtime, defined in mrt_common.h. + constexpr int32 arrayClassCacheMagicNumber = 0x1a3; + for (auto arrayClassName : arrayClassSet) { + uint32 typeNameIdx = ReflectionAnalysis::FindOrInsertRepeatString(arrayClassName); + MIRIntConst *nameConstValue = GlobalTables::GetIntConstTable().GetOrCreateIntConst(typeNameIdx, *mType); + arrayClassNameConst->PushBack(nameConstValue); + MIRIntConst *constValue = + GlobalTables::GetIntConstTable().GetOrCreateIntConst(arrayClassCacheMagicNumber, *mType); + arrayClassConst->PushBack(constValue); + } + MIRSymbol *arrayClassNameSt = GetMIRModule().GetMIRBuilder()->CreateGlobalDecl( + namemangler::kArrayClassCacheNameTable + GetMIRModule().GetFileNameAsPostfix(), *arrayType); + arrayClassNameSt->SetStorageClass(kScFstatic); + arrayClassNameSt->SetKonst(arrayClassNameConst); + + MIRSymbol *arrayClassCacheSt = GetMIRModule().GetMIRBuilder()->CreateGlobalDecl( + namemangler::kArrayClassCacheTable + GetMIRModule().GetFileNameAsPostfix(), *arrayType); + arrayClassCacheSt->SetStorageClass(kScFstatic); + arrayClassCacheSt->SetKonst(arrayClassConst); +} + void MUIDReplacement::CollectFuncAndDataFromKlasses() { // Iterate klasses for (Klass *klass : klassHierarchy->GetTopoSortedKlasses()) { @@ -914,7 +1004,7 @@ void MUIDReplacement::ReplaceFieldTypeTable(const std::string &name) { uint32 index = static_cast(FieldProperty::kPClassType); auto *aggrC = static_cast(oldTabEntry); CHECK_NULL_FATAL(aggrC->GetConstVecItem(index)); - if(aggrC->GetConstVecItem(index)->GetKind() == kConstInt) { + if (aggrC->GetConstVecItem(index)->GetKind() == kConstInt) { continue; } else { ReplaceAddrofConst(aggrC->GetConstVecItem(index), true); @@ -1190,7 +1280,13 @@ void MUIDReplacement::ReplaceDassign(MIRFunction ¤tFunc, const DassignNode destExpr = builder->CreateExprDread(*symPtrSym); } // Replace dassignNode with iassignNode - MIRType *destPtrType = GlobalTables::GetTypeTable().GetOrCreatePointerType(*mirSymbol->GetType()); + std::vector attrs; + if (mirSymbol->IsVolatile()) { + TypeAttrs tempAttrs; + tempAttrs.SetAttr(ATTR_volatile); + attrs.push_back(tempAttrs); + } + MIRType *destPtrType = GlobalTables::GetTypeTable().GetOrCreatePointerType(*mirSymbol->GetType(), PTY_ptr, attrs); StmtNode *iassignNode = builder->CreateStmtIassign(*destPtrType, 0, destExpr, dassignNode.Opnd(0)); currentFunc.GetBody()->ReplaceStmt1WithStmt2(&dassignNode, iassignNode); } @@ -1406,6 +1502,9 @@ void MUIDReplacement::GenerateTables() { CollectFuncAndDataFromGlobalTab(); CollectFuncAndDataFromFuncList(); CollectSuperClassArraySymbolData(); + CollectArrayClass(); + GenArrayClassCache(); + GenerateFuncDefTable(); GenerateDataDefTable(); GenerateUnifiedUndefTable(); diff --git a/src/mpl2mpl/src/reflection_analysis.cpp b/src/mpl2mpl/src/reflection_analysis.cpp index 6cb49f0561b8d126ece3383185adc4609cdf8390..41233776485a1d534d17edeb425bb27362cb5f95 100755 --- a/src/mpl2mpl/src/reflection_analysis.cpp +++ b/src/mpl2mpl/src/reflection_analysis.cpp @@ -59,6 +59,8 @@ constexpr int kModifierRCWeak = 25; // 0x01000000 constexpr int kModifierHiddenApiGrey = 26; // 0x02000000 constexpr int kModifierHiddenApiBlack = 27; // 0x04000000 constexpr int kModifierAFOriginPublic = 28; // 0x08000000 +constexpr int kModifierLocalClass = 29; // 0x10000000 +constexpr int kModifierLocalClassVaild = 30; // 0x20000000 for compatibility // +1 is needed here because our field id starts with 0 pointing to the struct itself constexpr uint32 kObjKlassFieldID = static_cast(ClassProperty::kShadow) + 1; @@ -129,6 +131,7 @@ constexpr int kAnonymousClassIndex = 5; constexpr char kAnonymousClassSuffix[] = "30"; constexpr char kInnerClassStr[] = "Lark/annotation/InnerClass;"; constexpr char kEnclosingClassStr[] = "Lark/annotation/EnclosingClass;"; +constexpr char kEnclosingMethod[] = "Lark/annotation/EnclosingMethod;"; constexpr char kArkAnnotationEnclosingClassStr[] = "Lark_2Fannotation_2FEnclosingClass_3B"; } // namespace @@ -148,7 +151,7 @@ std::string ReflectionAnalysis::strTabRunHot = std::string(1, '\0'); bool ReflectionAnalysis::strTabInited = false; void ReflectionAnalysis::GenFieldTypeClassInfo(const MIRType &type, const Klass &klass, std::string &classInfo, - const std::string fieldName, bool &isClass) { + const std::string fieldName, bool &isClass) { switch (type.GetKind()) { case kTypeScalar: { isClass = false; @@ -1504,6 +1507,7 @@ void ReflectionAnalysis::GenClassMetaData(Klass &klass) { std::map idxNumMap; GenAnnotation(idxNumMap, annoArray, *structType, kPragmaClass, klass.GetKlassName(), invalidIdx); bool isAnonymous = IsAnonymousClass(annoArray); + bool isLocalClass = IsLocalClass(annoArray); CheckPrivateInnerAndNoSubClass(klass, annoArray); #ifndef USE_32BIT_REF // @flag @@ -1519,6 +1523,9 @@ void ReflectionAnalysis::GenClassMetaData(Klass &klass) { #endif // USE_32BIT_REF // @modifier: For class fill ClassAccessFlags. uint32 modifier = GetClassAccessFlags(*structType); + modifier |= (isLocalClass << (kModifierLocalClass - 1)); + modifier |= (1 << (kModifierLocalClassVaild - 1)); + mirBuilder.AddIntFieldConst(classMetadataROType, *newConst, fieldID++, modifier); // @annotation: Set annotation field. uint32_t signatureIdx = GetAnnoCstrIndex(idxNumMap, annoArray, false); @@ -1634,6 +1641,16 @@ bool ReflectionAnalysis::IsAnonymousClass(const std::string &annotationString) { return false; } +bool ReflectionAnalysis::IsLocalClass(const std::string annotationString) { + uint32_t idx = ReflectionAnalysis::FindOrInsertReflectString(kEnclosingMethod); + std::string target = annoDelimiterPrefix + std::to_string(idx) + annoDelimiter; + size_t pos = annotationString.find(target, 0); + if (pos != std::string::npos) { + return true; + } + return false; +} + TyIdx ReflectionAnalysis::GenMetaStructType(MIRModule &mirModule, MIRStructType &metaType, const std::string &str) { const GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(str); TyIdx tyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&metaType); diff --git a/src/mplfe/common/src/feir_stmt.cpp b/src/mplfe/common/src/feir_stmt.cpp index 1750c4912ca8a7187fba408da8de05a510bd5d98..65831c6bf37cf1ec404e95f40b7f66f71b876e8a 100644 --- a/src/mplfe/common/src/feir_stmt.cpp +++ b/src/mplfe/common/src/feir_stmt.cpp @@ -861,7 +861,7 @@ std::unique_ptr FEIRExprTypeCvt::CloneImpl() const { BaseNode *FEIRExprTypeCvt::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { auto ptrFunc = funcPtrMapForParseExpr.find(op); - ASSERT(ptrFunc != funcPtrMapForParseExpr.end(), "unsupported op: %s", kOpcodeInfo.GetName(op)); + ASSERT(ptrFunc != funcPtrMapForParseExpr.end(), "unsupported op: %s", kOpcodeInfo.GetName(op).c_str()); return (this->*(ptrFunc->second))(mirBuilder); } @@ -938,7 +938,7 @@ std::unique_ptr FEIRExprExtractBits::CloneImpl() const { BaseNode *FEIRExprExtractBits::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { auto ptrFunc = funcPtrMapForParseExpr.find(op); - ASSERT(ptrFunc != funcPtrMapForParseExpr.end(), "unsupported op: %s", kOpcodeInfo.GetName(op)); + ASSERT(ptrFunc != funcPtrMapForParseExpr.end(), "unsupported op: %s", kOpcodeInfo.GetName(op).c_str()); return (this->*(ptrFunc->second))(mirBuilder); } @@ -1017,7 +1017,7 @@ std::unique_ptr FEIRExprBinary::CloneImpl() const { BaseNode *FEIRExprBinary::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { auto ptrFunc = funcPtrMapForGenMIRNode.find(op); - ASSERT(ptrFunc != funcPtrMapForGenMIRNode.end(), "unsupported op: %s", kOpcodeInfo.GetName(op)); + ASSERT(ptrFunc != funcPtrMapForGenMIRNode.end(), "unsupported op: %s", kOpcodeInfo.GetName(op).c_str()); return (this->*(ptrFunc->second))(mirBuilder); }