diff --git a/src/bin/jbc2mpl b/src/bin/jbc2mpl index 12a8e81f50c4d39613a5670c29626d78ffb2f584..1c67ae4c8782f70e3038b05c199e3f5990cf6a12 100755 Binary files a/src/bin/jbc2mpl and b/src/bin/jbc2mpl differ diff --git a/src/bin/maple b/src/bin/maple index 940360dce09d4c93fb1d44b26025a6d80dfbc735..4e9a47076aa3cada9a1e7ab61728f7aa88fe7ebd 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 e251505f93b91576cf43067baf8e1488f24a4812..33eeec2cb4a3a927359185c44d193cc4ac232883 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 e910dbeb345bd7e6f6fccfa0872d6a74ed1a46bf..9cb48dd32c6de9a9597ff5a9ef7cb7f734a66ca0 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 76a4b300cab8de94ac9456081983b598f7a2e3b6..5b8267cd8a30cb91e909fa57c114f390a6989250 100644 --- a/src/maple_be/include/be/lower.h +++ b/src/maple_be/include/be/lower.h @@ -21,6 +21,7 @@ #include #include "intrinsics.h" /* For IntrinDesc. This includes 'intrinsic_op.h' as well */ #include "becommon.h" +#include "cg.h" #include "bbt.h" /* MapleIR headers. */ #include "mir_nodes.h" @@ -156,6 +157,7 @@ class CGLowerer { void LowerEntry(MIRFunction &func); StmtNode *LowerCall(CallNode &call, StmtNode *&stmt, BlockNode &block); + void SplitCallArg(CallNode &callNode, BaseNode *newOpnd, size_t i, BlockNode &newBlk); void CleanupBranches(MIRFunction &func) const; diff --git a/src/maple_be/include/cg/aarch64/aarch64_cgfunc.h b/src/maple_be/include/cg/aarch64/aarch64_cgfunc.h index 25b6343fb03ccbbbf12bf5513b9525aa191e3597..78a874ac03e8c665fa0aacb58d1c87a205cca951 100644 --- a/src/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -307,6 +307,7 @@ class AArch64CGFunc : public CGFunc { Operand &GetOrCreateFuncNameOpnd(const MIRSymbol &symbol); void GenerateYieldpoint(BB &bb) override; + Operand &ProcessReturnReg(PrimType primType) override; void GenerateCleanupCode(BB &bb) override; bool NeedCleanup() override; void GenerateCleanupCodeForExtEpilog(BB &bb) override; diff --git a/src/maple_be/include/cg/cg_option.h b/src/maple_be/include/cg/cg_option.h index 34ad082785001a9075906c4143459054f0db5d96..d14bc338e34b6ca9b5a56589d1e666cef83ebbbc 100644 --- a/src/maple_be/include/cg/cg_option.h +++ b/src/maple_be/include/cg/cg_option.h @@ -81,8 +81,7 @@ class CGOptions : public MapleDriverOptionBase { enum ABIType : uint8 { kABIHard, kABISoft, - kABISoftFP, - kABIUndef + kABISoftFP }; /* * The default CG option values are: diff --git a/src/maple_be/include/cg/cgfunc.h b/src/maple_be/include/cg/cgfunc.h index f8e83145a58b32771e8419a06a84d407e0b9f1dd..a9ddb5ce85f6c14c03a4b4a5424bab182bc65f3a 100644 --- a/src/maple_be/include/cg/cgfunc.h +++ b/src/maple_be/include/cg/cgfunc.h @@ -221,6 +221,7 @@ class CGFunc { virtual Operand *SelectLazyLoad(Operand &opnd0, PrimType primType) = 0; virtual Operand *SelectLazyLoadStatic(MIRSymbol &st, int64 offset, PrimType primType) = 0; virtual void GenerateYieldpoint(BB &bb) = 0; + virtual Operand &ProcessReturnReg(PrimType primType) = 0; virtual Operand &GetOrCreateRflag() = 0; virtual const Operand *GetRflag() const = 0; diff --git a/src/maple_be/mdgen/src/mdgenerator.cpp b/src/maple_be/mdgen/src/mdgenerator.cpp index 994698667a997f53f660a8673c9ccdd58704953a..05781b805dd339e6659e4950cc177a161d60a03b 100644 --- a/src/maple_be/mdgen/src/mdgenerator.cpp +++ b/src/maple_be/mdgen/src/mdgenerator.cpp @@ -62,7 +62,7 @@ void SchedInfoGen::EmitArchDef() { void SchedInfoGen::EmitUnitIdDef() { MDClass unitClass = GetSpecificClass("Unit"); outFile.open(GetOFileDir() + "/mplad_unit_id.def", std::ios::out); - ASSERT(outFile.is_open(), "Failed to open output file: %s/mplad_unit_id.def", GetOFileDir().c_str()); + CHECK_FATAL(outFile.is_open(), "Failed to open output file: %s/mplad_unit_id.def", GetOFileDir().c_str()); EmitFileHead(outFile, "function unit ID"); for (auto unitIdx : unitClass.GetchildObjNames()) { outFile << " " << curKeeper.GetStrByIdx(unitIdx) << ",\n"; @@ -73,7 +73,7 @@ void SchedInfoGen::EmitUnitIdDef() { void SchedInfoGen::EmitUnitNameDef() { MDClass unitClass = GetSpecificClass("Unit"); outFile.open(GetOFileDir() + "/mplad_unit_name.def", std::ios::out); - ASSERT(outFile.is_open(), "Failed to open output file: %s/mplad_unit_name.def", GetOFileDir().c_str()); + CHECK_FATAL(outFile.is_open(), "Failed to open output file: %s/mplad_unit_name.def", GetOFileDir().c_str()); EmitFileHead(outFile, "function unit name"); for (auto unitIdx : unitClass.GetchildObjNames()) { std::string unitPureName = curKeeper.GetStrByIdx(unitIdx); @@ -89,7 +89,7 @@ void SchedInfoGen::EmitUnitNameDef() { void SchedInfoGen::EmitUnitDef() { MDClass unitClass = GetSpecificClass("Unit"); outFile.open(GetOFileDir() + "/mplad_unit_define.def", std::ios::out); - ASSERT(outFile.is_open(), "Failed to open output file: %s/mplad_unit_define.def", GetOFileDir().c_str()); + CHECK_FATAL(outFile.is_open(), "Failed to open output file: %s/mplad_unit_define.def", GetOFileDir().c_str()); EmitFileHead(outFile, "function units "); bool isUnitNumDef = false; for (size_t i = 0; i < unitClass.GetMDObjectSize(); ++i) { @@ -138,7 +138,7 @@ void SchedInfoGen::EmitUnitDef() { void SchedInfoGen::EmitLatencyDef() { MDClass resvClass = GetSpecificClass("Reservation"); outFile.open(GetOFileDir() + "/mplad_latency_type.def", std::ios::out); - ASSERT(outFile.is_open(), "Failed to open output file: %s/mplad_latency_type.def", GetOFileDir().c_str()); + CHECK_FATAL(outFile.is_open(), "Failed to open output file: %s/mplad_latency_type.def", GetOFileDir().c_str()); EmitFileHead(outFile, " latency type definition "); for (auto resvIdx : resvClass.GetchildObjNames()) { outFile << " " << curKeeper.GetStrByIdx(resvIdx) << ",\n"; @@ -149,8 +149,8 @@ void SchedInfoGen::EmitLatencyDef() { void SchedInfoGen::EmitResvDef() { MDClass resvClass = GetSpecificClass("Reservation"); outFile.open(GetOFileDir() + "/mplad_reservation_define.def", std::ios::out); - ASSERT(outFile.is_open(), "Failed to open output file: %s/mplad_reservation_define.def", - GetOFileDir().c_str()); + CHECK_FATAL(outFile.is_open(), "Failed to open output file: %s/mplad_reservation_define.def", + GetOFileDir().c_str()); EmitFileHead(outFile, "reservations"); for (size_t i = 0; i < resvClass.GetMDObjectSize(); ++i) { const MDObject &singleResv = resvClass.GetOneMDObject(i); diff --git a/src/maple_be/src/be/lower.cpp b/src/maple_be/src/be/lower.cpp index 29565b71999e69db0e29777abab5b7bb44bbdc18..e68d1c9f1c0869222f398b5c1adc55008af39e96 100644 --- a/src/maple_be/src/be/lower.cpp +++ b/src/maple_be/src/be/lower.cpp @@ -1060,6 +1060,28 @@ MIRType *CGLowerer::GetArrayNodeType(BaseNode &baseNode) { return arrayElemType; } +void CGLowerer::SplitCallArg(CallNode &callNode, BaseNode *newOpnd, size_t i, BlockNode &newBlk) { + if (newOpnd->GetOpCode() != OP_regread && newOpnd->GetOpCode() != OP_constval && + newOpnd->GetOpCode() != OP_dread && newOpnd->GetOpCode() != OP_addrof && + newOpnd->GetOpCode() != OP_iaddrof && newOpnd->GetOpCode() != OP_constval && + newOpnd->GetOpCode() != OP_conststr && newOpnd->GetOpCode() != OP_conststr16) { + if (CGOptions::GetInstance().GetOptimizeLevel() == CGOptions::kLevel0) { + MIRType *type = GlobalTables::GetTypeTable().GetPrimType(newOpnd->GetPrimType()); + MIRSymbol *ret = CreateNewRetVar(*type, kIntrnRetValPrefix); + DassignNode *dassignNode = mirBuilder->CreateStmtDassign(*ret, 0, newOpnd); + newBlk.AddStatement(dassignNode); + callNode.SetOpnd(mirBuilder->CreateExprDread(*type, 0, *ret), i); + } else { + PregIdx pregIdx = mirModule.CurFunction()->GetPregTab()->CreatePreg(newOpnd->GetPrimType()); + RegassignNode *temp = mirBuilder->CreateStmtRegassign(newOpnd->GetPrimType(), pregIdx, newOpnd); + newBlk.AddStatement(temp); + callNode.SetOpnd(mirBuilder->CreateExprRegread(newOpnd->GetPrimType(), pregIdx), i); + } + } else { + callNode.SetOpnd(newOpnd, i); + } +} + StmtNode *CGLowerer::LowerCall(CallNode &callNode, StmtNode *&nextStmt, BlockNode &newBlk) { /* * nextStmt in-out @@ -1079,7 +1101,12 @@ StmtNode *CGLowerer::LowerCall(CallNode &callNode, StmtNode *&nextStmt, BlockNod } for (size_t i = 0; i < callNode.GetNopndSize(); ++i) { - callNode.SetOpnd(LowerExpr(callNode, *callNode.GetNopndAt(i), newBlk), i); + BaseNode *newOpnd = LowerExpr(callNode, *callNode.GetNopndAt(i), newBlk); +#if TARGAARCH64 + callNode.SetOpnd(newOpnd, i); +#else + SplitCallArg(callNode, newOpnd, i, newBlk); +#endif } if (isArrayStore && checkLoadStore) { @@ -1800,8 +1827,8 @@ StmtNode *CGLowerer::LowerIntrinsicopDassign(const DassignNode &dsNode, */ BaseNode *CGLowerer::LowerJavascriptIntrinsicop(IntrinsicopNode &intrinNode, const IntrinDesc &desc) { MIRSymbol *st = GlobalTables::GetGsymTable().CreateSymbol(kScopeGlobal); - const std::string name = desc.name; CHECK_FATAL(desc.name != nullptr, "desc's name should not be nullptr"); + const std::string name = desc.name; st->SetNameStrIdx(name); st->SetStorageClass(kScText); st->SetSKind(kStFunc); diff --git a/src/maple_be/src/cg/aarch64/aarch64_abi.cpp b/src/maple_be/src/cg/aarch64/aarch64_abi.cpp index 3de48ff5bae7be707d85633de930620e0cad1727..83839806c9ae5bcf3fcc0ed981ca41f2c1c3c8ef 100644 --- a/src/maple_be/src/cg/aarch64/aarch64_abi.cpp +++ b/src/maple_be/src/cg/aarch64/aarch64_abi.cpp @@ -501,7 +501,6 @@ void ParmLocator::ProcessPtyAggWhenLocateNextParm(MIRType &mirType, PLocInfo &pL if (pLoc.reg0 == kRinvalid) { nextGeneralRegNO = AArch64Abi::kNumIntParmRegs; } - ASSERT(AArch64Abi::kNumIntParmRegs == 8, "AArch64Abi::kNumIntParmRegs should be set to 8"); } else { /* * 0 returned from ClassifyAggregate(). This means the whole data diff --git a/src/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp b/src/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp index 98a7721ec06914388a2343a551d84c036fa7341f..74f8bc7c6c6c86fdb7ee3a1c67cd038c23bdc22d 100644 --- a/src/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -79,11 +79,13 @@ MOperator PickLdStInsn(bool isLoad, uint32 bitSize, PrimType primType, AArch64is ASSERT(primType != PTY_ref, "should have been lowered"); ASSERT(bitSize >= k8BitSize, "PTY_u1 should have been lowered?"); ASSERT(__builtin_popcount(bitSize) == 1, "PTY_u1 should have been lowered?"); - ASSERT((isLoad && ((memOrd == AArch64isa::kMoNone) || (memOrd == AArch64isa::kMoAcquire) || - (memOrd == AArch64isa::kMoAcquireRcpc) || (memOrd == AArch64isa::kMoLoacquire))) || - (!isLoad && ((memOrd == AArch64isa::kMoNone) || (memOrd == AArch64isa::kMoRelease) || - (memOrd == AArch64isa::kMoLorelease))), - "unknown Memory Order"); + if (isLoad) { + ASSERT((memOrd == AArch64isa::kMoNone) || (memOrd == AArch64isa::kMoAcquire) || + (memOrd == AArch64isa::kMoAcquireRcpc) || (memOrd == AArch64isa::kMoLoacquire), "unknown Memory Order"); + } else { + ASSERT((memOrd == AArch64isa::kMoNone) || (memOrd == AArch64isa::kMoRelease) || + (memOrd == AArch64isa::kMoLorelease), "unknown Memory Order"); + } /* __builtin_ffs(x) returns: 0 -> 0, 1 -> 1, 2 -> 2, 4 -> 3, 8 -> 4 */ if (IsPrimitiveInteger(primType)) { @@ -3949,6 +3951,10 @@ void AArch64CGFunc::GenerateYieldpoint(BB &bb) { bb.AppendInsn(yieldPoint); } +Operand &AArch64CGFunc::ProcessReturnReg(PrimType primType) { + return GetTargetRetOperand(primType); +} + Operand &AArch64CGFunc::GetTargetRetOperand(PrimType primType) { uint32 bitSize = GetPrimTypeBitSize(primType) < k32BitSize ? k32BitSize : GetPrimTypeBitSize(primType); return GetOrCreatePhysicalRegisterOperand(IsPrimitiveFloat(primType) ? S0 : R0, bitSize, diff --git a/src/maple_be/src/cg/aarch64/aarch64_color_ra.cpp b/src/maple_be/src/cg/aarch64/aarch64_color_ra.cpp index 64787fa1010ed9534a26101d3662919c4d217971..36805601e0c3252af332dc3533a00504b42c9a19 100644 --- a/src/maple_be/src/cg/aarch64/aarch64_color_ra.cpp +++ b/src/maple_be/src/cg/aarch64/aarch64_color_ra.cpp @@ -2549,7 +2549,7 @@ MemOperand *GraphColorRegAllocator::GetSpillOrReuseMem(LiveRange &lr, uint32 reg } else { #endif /* REUSE_SPILLMEM */ regno_t baseRegNO; - if (!isDef) { + if (!isDef && lr.GetRegNO() == kRegTyInt) { /* src will use its' spill reg as baseRegister when offset out-of-range * add x16, x29, #max-offset //out-of-range * ldr x16, [x16, #offset] //reload diff --git a/src/maple_be/src/cg/cg.cpp b/src/maple_be/src/cg/cg.cpp index 2eb6f62a5e38991486bc5598ab44fea0ba5c02ab..12cc32fe27f61c42f03ec8a41880ac31adfc4a99 100644 --- a/src/maple_be/src/cg/cg.cpp +++ b/src/maple_be/src/cg/cg.cpp @@ -65,7 +65,7 @@ void CG::GenExtraTypeMetadata(const std::string &classListFileName, const std::s } else { /* Visit listed classes. */ std::ifstream inFile(classListFileName); - ASSERT(inFile.is_open(), "Failed to open file: %s", classListFileName.c_str()); + CHECK_FATAL(inFile.is_open(), "Failed to open file: %s", classListFileName.c_str()); std::string str; /* check each class name first and expose all unknown classes */ diff --git a/src/maple_be/src/cg/cgfunc.cpp b/src/maple_be/src/cg/cgfunc.cpp index 471530bae3c2ce484eadfbc0d89d5760d3ead627..ae19c1a2f36b434ef38abcc55a921f8c1be977ef 100644 --- a/src/maple_be/src/cg/cgfunc.cpp +++ b/src/maple_be/src/cg/cgfunc.cpp @@ -37,7 +37,7 @@ Operand *HandleRegread(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc) { (void)parent; auto ®ReadNode = static_cast(expr); if (regReadNode.GetRegIdx() == -kSregRetval0) { - return &(cgFunc.GetTargetRetOperand(regReadNode.GetPrimType())); + return &cgFunc.ProcessReturnReg(regReadNode.GetPrimType()); } return cgFunc.SelectRegread(regReadNode); } @@ -590,9 +590,11 @@ void HandleMembar(StmtNode &stmt, CGFunc &cgFunc) { if (stmt.GetOpCode() != OP_membarrelease) { return; } +#if TARGAARCH64 if (CGOptions::UseBarriersForVolatile()) { return; } +#endif StmtNode *secondStmt = stmt.GetRealNext(); if (secondStmt == nullptr || ((secondStmt->GetOpCode() != OP_iassign) && (secondStmt->GetOpCode() != OP_dassign))) { @@ -739,9 +741,15 @@ bool CGFunc::CheckSkipMembarOp(StmtNode &stmt) { if ((opCode == OP_membarstorestore) && func.IsConstructor() && MemBarOpt(stmt)) { return true;; } +#if TARGARM32 + if (nextStmt->GetOpCode() == OP_membaracquire) { + isVolLoad = true; + } +#else if ((!CGOptions::UseBarriersForVolatile()) && (nextStmt->GetOpCode() == OP_membaracquire)) { isVolLoad = true; } +#endif /* TARGARM32 */ return false; } @@ -767,6 +775,11 @@ void CGFunc::GenerateInstruction() { if (tempLoad && !isVolLoad) { stmt = stmt->GetNext(); } + +#if TARGARM32 + isVolLoad = false; +#endif + /* * skip the membarstoreload if there is the pattern for volatile write( membarrelease + store + membarstoreload ) * membarrelease + store + membarstoreload -> stlr diff --git a/src/maple_be/src/cg/emit.cpp b/src/maple_be/src/cg/emit.cpp index d9a395ab1e24b44d830d92177fd43c0d6210453a..ac56b66176d84fc4ac65540f5ed22c7a130d933b 100644 --- a/src/maple_be/src/cg/emit.cpp +++ b/src/maple_be/src/cg/emit.cpp @@ -175,19 +175,21 @@ void Emitter::EmitFileInfo(const std::string &fileName) { Emit("\t.arm\n"); Emit("\t.fpu vfpv4\n"); Emit("\t.arch armv7-a\n"); - Emit("\t.eabi_attribute 15, 1\n"); - Emit("\t.eabi_attribute 16, 1\n"); - Emit("\t.eabi_attribute 17, 2\n"); - Emit("\t.eabi_attribute 28, 1\n"); - Emit("\t.eabi_attribute 20, 1\n"); - Emit("\t.eabi_attribute 21, 1\n"); - Emit("\t.eabi_attribute 23, 3\n"); - Emit("\t.eabi_attribute 24, 1\n"); - Emit("\t.eabi_attribute 25, 1\n"); - Emit("\t.eabi_attribute 26, 2\n"); + Emit("\t.eabi_attribute Tag_ABI_PCS_RW_data, 1\n"); + Emit("\t.eabi_attribute Tag_ABI_PCS_RO_data, 1\n"); + Emit("\t.eabi_attribute Tag_ABI_PCS_GOT_use, 2\n"); + if (CGOptions::GetABIType() == CGOptions::kABIHard) { + Emit("\t.eabi_attribute Tag_ABI_VFP_args, 1\n"); + } + Emit("\t.eabi_attribute Tag_ABI_FP_denormal, 1\n"); + Emit("\t.eabi_attribute Tag_ABI_FP_exceptions, 1\n"); + Emit("\t.eabi_attribute Tag_ABI_FP_number_model, 3\n"); + Emit("\t.eabi_attribute Tag_ABI_align_needed, 1\n"); + Emit("\t.eabi_attribute Tag_ABI_align_preserved, 1\n"); + Emit("\t.eabi_attribute Tag_ABI_enum_size, 2\n"); Emit("\t.eabi_attribute 30, 6\n"); - Emit("\t.eabi_attribute 34, 1\n"); - Emit("\t.eabi_attribute 18, 4\n"); + Emit("\t.eabi_attribute Tag_CPU_unaligned_access, 1\n"); + Emit("\t.eabi_attribute Tag_ABI_PCS_wchar_t, 4\n"); #endif /* TARGARM32 */ } diff --git a/src/maple_ipa/include/callgraph.h b/src/maple_ipa/include/callgraph.h index faaa784591d977ad98c3beba32b0a7f24457590c..15f09f4a42e19dbe6c1afa4160b0b0b1b959efd0 100644 --- a/src/maple_ipa/include/callgraph.h +++ b/src/maple_ipa/include/callgraph.h @@ -219,6 +219,10 @@ class CGNode { return callees.size(); } + const MapleMap>*, Comparator> &GetCallee() const { + return callees; + } + MapleMap>*, Comparator> &GetCallee() { return callees; } diff --git a/src/maple_ipa/include/retype.h b/src/maple_ipa/include/retype.h index 11ad1fa638970d1d5d2635eaec32cb2738852d91..7533839589c5e448066ef6e8d9edf97519446ba2 100644 --- a/src/maple_ipa/include/retype.h +++ b/src/maple_ipa/include/retype.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. @@ -21,21 +21,20 @@ namespace maple { class Retype { public: - MIRModule *mirmodule; + MIRModule *mirModule; MapleAllocator allocator; - MIRBuilder &dexbuilder; + MIRBuilder &dexBuilder; KlassHierarchy *klassh; public: - explicit Retype(MIRModule *mod, MemPool *memPool, MIRBuilder &builder, KlassHierarchy *k) - : mirmodule(mod), allocator(memPool), dexbuilder(builder), klassh(k) {} + Retype(MIRModule *mod, MemPool *memPool, MIRBuilder &builder, KlassHierarchy *k) + : mirModule(mod), allocator(memPool), dexBuilder(builder), klassh(k) {} virtual ~Retype() {} - void ReplaceRetypeExpr(const BaseNode *opnd); - void Retypestmt(MIRFunction *func); - void DoRetype(); + void ReplaceRetypeExpr(const BaseNode &opnd) const; + void RetypeStmt(MIRFunction &func) const; + void DoRetype() const; }; - } // namespace maple #endif // MAPLE_IPA_INCLUDE_RETYPE_H diff --git a/src/maple_ipa/src/callgraph.cpp b/src/maple_ipa/src/callgraph.cpp index 370cbe5380c57f477bb70b02cf87a1e83ff5008d..85b5b880ec9a8f9d0a216fb62c9d2e40318056c1 100644 --- a/src/maple_ipa/src/callgraph.cpp +++ b/src/maple_ipa/src/callgraph.cpp @@ -1036,7 +1036,7 @@ void DoDevirtual(const Klass &klass, const KlassHierarchy &klassh) { targetKlass = klassh.GetKlassFromTyIdx(retType->GetTypeIndex()); } if (targetKlass == nullptr && !isCalleeScalar) { - CHECK_FATAL(targetKlass != nullptr, "null ptr check"); + CHECK_FATAL(false, "null ptr check"); } Klass *curRetKlass = nullptr; bool isCurrVtabScalar = false; diff --git a/src/maple_ipa/src/retype.cpp b/src/maple_ipa/src/retype.cpp index 0e4e1539dfc1a81e0f34be1fcb70c11d791e9a64..b89437398aa2c7c6e00df7bad5ef0418f435825c 100644 --- a/src/maple_ipa/src/retype.cpp +++ b/src/maple_ipa/src/retype.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2019] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. @@ -17,25 +17,25 @@ #include namespace maple { -void Retype::ReplaceRetypeExpr(const BaseNode *expr) { - if (expr->NumOpnds() == 0) { +void Retype::ReplaceRetypeExpr(const BaseNode &expr) const { + if (expr.NumOpnds() == 0) { return; } - for (size_t i = 0; i < expr->NumOpnds(); i++) { - BaseNode *opnd = expr->Opnd(i); + for (size_t i = 0; i < expr.NumOpnds(); ++i) { + BaseNode *opnd = expr.Opnd(i); if (opnd->GetOpCode() == OP_retype) { opnd->SetOpnd(opnd->Opnd(0), i); continue; } - ReplaceRetypeExpr(opnd); + ReplaceRetypeExpr(*opnd); } } -void Retype::Retypestmt(MIRFunction *func) { - if (func->IsEmpty()) { +void Retype::RetypeStmt(MIRFunction &func) const { + if (func.IsEmpty()) { return; } - for (auto &stmt : func->GetBody()->GetStmtNodes()) { + for (auto &stmt : func.GetBody()->GetStmtNodes()) { if (stmt.GetOpCode() == OP_comment) { continue; } @@ -45,19 +45,18 @@ void Retype::Retypestmt(MIRFunction *func) { stmt.SetOpnd(opnd->Opnd(0), i); continue; } else { - ReplaceRetypeExpr(opnd); + ReplaceRetypeExpr(*opnd); } } } } -void Retype::DoRetype() { - for (MIRFunction *func : mirmodule->GetFunctionList()) { +void Retype::DoRetype() const { + for (MIRFunction *func : mirModule->GetFunctionList()) { if (func->IsEmpty()) { continue; } - Retypestmt(func); + RetypeStmt(*func); } } - } // namespace maple diff --git a/src/maple_ir/include/metadata_layout.h b/src/maple_ir/include/metadata_layout.h index 22bf2902c199d758c5e97687f7c2b4ba292c9b95..f0d1eb2195cf7419457d88aa64f6d2a9cb941a17 100644 --- a/src/maple_ir/include/metadata_layout.h +++ b/src/maple_ir/include/metadata_layout.h @@ -82,17 +82,16 @@ struct MethodFieldRef { inline void SetRawValue(int64_t value); }; -/* DataRef aims for reference to data in maple file (generated by maple compiler) and is aligned to at least 4 bytes. - Perhaps MDataRef is more fit, still DataRef is chosen to make it common. - DataRef allows 4 formats of value: - 0. "label_name" for direct reference - 1. "label_name - . + 1" for padding unused - 2. "label_name - . + 2" for reference in offset format - 3. "indirect.label_name - . + 3" for indirect reference - this format aims to support lld which does not support expression "global_symbol - ." - DataRef is self-decoded by also encoding the format and is defined for binary compatibility. - If no compatibility problem is involved, DataRefOffsetPtr is preferred. - */ +// DataRef aims for reference to data in maple file (generated by maple compiler) and is aligned to at least 4 bytes. +// Perhaps MDataRef is more fit, still DataRef is chosen to make it common. +// DataRef allows 4 formats of value: +// 0. "label_name" for direct reference +// 1. "label_name - . + 1" for padding unused +// 2. "label_name - . + 2" for reference in offset format +// 3. "indirect.label_name - . + 3" for indirect reference +// this format aims to support lld which does not support expression "global_symbol - ." +// DataRef is self-decoded by also encoding the format and is defined for binary compatibility. +// If no compatibility problem is involved, DataRefOffsetPtr is preferred. enum DataRefFormat { kDataRefIsDirect = 0, // must be 0 kDataRefPadding = 1, // unused @@ -121,15 +120,14 @@ struct DataRef { template inline T GetRawValue() const; }; -/* GctibRef aims to represent a reference to gctib in maple file, which is an offset by default. - GctibRef is meant to have pointer size and aligned to at least 4 bytes. - GctibRef allows 2 formats of value: - 0. "label_name - . + 0" for reference in offset format - 1. "indirect.label_name - . + 1" for indirect reference - this format aims to support lld which does not support expression "global_symbol - ." - GctibRef is self-decoded by also encoding the format and is defined for binary compatibility. - If no compatibility problem is involved, DataRef is preferred. - */ +// GctibRef aims to represent a reference to gctib in maple file, which is an offset by default. +// GctibRef is meant to have pointer size and aligned to at least 4 bytes. +// GctibRef allows 2 formats of value: +// 0. "label_name - . + 0" for reference in offset format +// 1. "indirect.label_name - . + 1" for indirect reference +// this format aims to support lld which does not support expression "global_symbol - ." +// GctibRef is self-decoded by also encoding the format and is defined for binary compatibility. +// If no compatibility problem is involved, DataRef is preferred. enum GctibRefFormat { kGctibRefIsOffset = 0, // default kGctibRefIsIndirect = 1, diff --git a/src/maple_ir/include/mir_nodes.h b/src/maple_ir/include/mir_nodes.h index e58fbd8aa191548515f0e41f36a3cea0da5ef3e5..a7ea7184fa61af6d8e02789e85a614cfbce7c863 100644 --- a/src/maple_ir/include/mir_nodes.h +++ b/src/maple_ir/include/mir_nodes.h @@ -931,7 +931,6 @@ class IntrinsicopNode : public NaryNode { const IntrinDesc &GetIntrinDesc() const { return IntrinDesc::intrinTable[intrinsic]; } - private: MIRIntrinsicID intrinsic; TyIdx tyIdx; @@ -1948,7 +1947,6 @@ class UnaryStmtNode : public StmtNode { void SetOpnd(BaseNode *node, size_t) override { uOpnd = node; } - private: BaseNode *uOpnd = nullptr; }; diff --git a/src/maple_ir/include/mir_preg.h b/src/maple_ir/include/mir_preg.h index 53d308aa6a19c3a926875e7ff1488832a6cb15a0..b654afd32d79b3a7a45b91d84adb8ea2f939d641 100644 --- a/src/maple_ir/include/mir_preg.h +++ b/src/maple_ir/include/mir_preg.h @@ -172,6 +172,10 @@ class MIRPregTable { return pregTable; } + const MapleVector &GetPregTable() const { + return pregTable; + } + const MIRPreg *GetPregTableItem(const uint32 index) const { CHECK_FATAL(index < pregTable.size(), "array index out of range"); return pregTable[index]; diff --git a/src/maple_ir/src/lexer.cpp b/src/maple_ir/src/lexer.cpp index 533b33f25a22d9d9ef9fb836fe299b42311420d9..cce8291a3f76d9e8e39c087934c2f7583fe12f48 100644 --- a/src/maple_ir/src/lexer.cpp +++ b/src/maple_ir/src/lexer.cpp @@ -460,6 +460,7 @@ TokenKind MIRLexer::GetTokenWithPrefixDoubleQuotation() { const uint32 octShift1 = 3; const uint32 octShift2 = 6; const uint32 octLength = 3; + ASSERT(curIdx + octLength < line.size(), "index out of range"); uint32 cNew = (static_cast(GetCharAtWithLowerCheck(curIdx + 1) - '0') << octShift2) + (static_cast(GetCharAtWithLowerCheck(curIdx + 2) - '0') << octShift1) + static_cast(GetCharAtWithLowerCheck(curIdx + 3) - '0'); diff --git a/src/maple_me/include/me_ssa_devirtual.h b/src/maple_me/include/me_ssa_devirtual.h index b38b2d6222e61da8a35b717bff9eca4ec8b769f0..bab72181fa40e9a1f044231a43c3931ed36295a2 100644 --- a/src/maple_me/include/me_ssa_devirtual.h +++ b/src/maple_me/include/me_ssa_devirtual.h @@ -21,6 +21,8 @@ namespace maple { class MeSSADevirtual : public SSADevirtual { public: + MeSSADevirtual(MemPool &memPool, MIRModule &mod, MeFunction &func, IRMap &irMap, KlassHierarchy &kh, Dominance &dom) + : SSADevirtual(memPool, mod, irMap, kh, dom, func.GetAllBBs().size()), func(&func) {} MeSSADevirtual(MemPool &memPool, MIRModule &mod, MeFunction &func, IRMap &irMap, KlassHierarchy &kh, Dominance &dom, Clone &clone) : SSADevirtual(memPool, mod, irMap, kh, dom, func.GetAllBBs().size(), clone), func(&func) {} diff --git a/src/maple_me/include/ssa_devirtual.h b/src/maple_me/include/ssa_devirtual.h index 6b1ca93657b5c342efa96df8b150b315edb22034..f453ef994ac4c43c921d82b431ffeec91bda92c8 100644 --- a/src/maple_me/include/ssa_devirtual.h +++ b/src/maple_me/include/ssa_devirtual.h @@ -26,14 +26,14 @@ class SSADevirtual { public: static bool debug; SSADevirtual(MemPool &memPool, MIRModule &currMod, IRMap &irMap, KlassHierarchy &currKh, - Dominance &currDom, size_t bbVecSize, Clone &currClone) + Dominance &currDom, size_t bbVecSize) : devirtualAlloc(&memPool), mod(&currMod), irMap(&irMap), kh(&currKh), dom(&currDom), bbVisited(bbVecSize, false, devirtualAlloc.Adapter()), - clone(&currClone), + clone(nullptr), retTy(kNotSeen), inferredRetTyIdx(0), totalVirtualCalls(0), @@ -41,11 +41,19 @@ class SSADevirtual { totalInterfaceCalls(0), optedInterfaceCalls(0), nullCheckCount(0) {} + SSADevirtual(MemPool &memPool, MIRModule &currMod, IRMap &irMap, KlassHierarchy &currKh, + Dominance &currDom, size_t bbVecSize, Clone &currClone) + : SSADevirtual(memPool, currMod, irMap, currKh, currDom, bbVecSize) { + clone = &currClone; + } virtual ~SSADevirtual() = default; void Perform(BB &entryBB); + void SetClone(Clone &currClone) { + clone = &currClone; + } protected: virtual MIRFunction *GetMIRFunction() const { return nullptr; diff --git a/src/maple_me/src/me_ssa_devirtual.cpp b/src/maple_me/src/me_ssa_devirtual.cpp index 650f27003138419a2afb81cf3ef46e17a0ec559d..158247b830dec8c09a1373df642be2e083946553 100644 --- a/src/maple_me/src/me_ssa_devirtual.cpp +++ b/src/maple_me/src/me_ssa_devirtual.cpp @@ -25,11 +25,14 @@ AnalysisResult *MeDoSSADevirtual::Run(MeFunction *func, MeFuncResultMgr *frm, Mo CHECK_FATAL(mrm != nullptr, "Needs module result manager for ipa"); auto *kh = static_cast(mrm->GetAnalysisResult(MoPhase_CHA, &func->GetMIRModule())); ASSERT(kh != nullptr, "KlassHierarchy has problem"); - Clone *clone = nullptr; + MeSSADevirtual meSSADevirtual(*NewMemPool(), func->GetMIRModule(), *func, *irMap, *kh, *dom); if (Options::O2) { - clone = static_cast(mrm->GetAnalysisResult(MoPhase_CLONE, &func->GetMIRModule())); + Clone *clone = static_cast(mrm->GetAnalysisResult(MoPhase_CLONE, &func->GetMIRModule())); + if (clone != nullptr) { + meSSADevirtual.SetClone(*clone); + } } - MeSSADevirtual meSSADevirtual(*NewMemPool(), func->GetMIRModule(), *func, *irMap, *kh, *dom, *clone); + if (DEBUGFUNC(func)) { SSADevirtual::debug = true; } diff --git a/src/maple_util/src/profile.cpp b/src/maple_util/src/profile.cpp index 50a933721eb9b0d2bf1f6ef72038d3f708851510..8b1bca0fdd47ff6ef6f6c4ee65e85bd79484b41b 100644 --- a/src/maple_util/src/profile.cpp +++ b/src/maple_util/src/profile.cpp @@ -242,7 +242,7 @@ bool Profile::DeCompress(const std::string &path, const std::string &dexNameInne if (!in) { if (errno != ENOENT && errno != EACCES) { LogInfo::MapleLogger() << "WARN: DeCompress(" - << "), failed to open " << path << ", " << strerror(errno) << '\n';; + << "), failed to open " << path << '\n';; } res = false; return res; @@ -255,14 +255,14 @@ bool Profile::DeCompress(const std::string &path, const std::string &dexNameInne char *buf = reinterpret_cast(bufVector.data()); if (!in.read(buf, byteCount)) { LogInfo::MapleLogger() << "WARN: DeCompress(" - << "), failed to read all data for " << path << ", " << strerror(errno) << '\n';; + << "), failed to read all data for " << path << '\n';; res = false; in.close(); return res; } if (byteCount < sizeof(Header)) { LogInfo::MapleLogger() << "WARN: DeCompress(" - << "), failed, read no data for " << path << ", " << strerror(errno) << '\n';; + << "), failed, read no data for " << path << '\n';; res = false; in.close(); return res; diff --git a/src/mpl2mpl/include/native_stub_func.h b/src/mpl2mpl/include/native_stub_func.h index e6a0c0abff7c1f47efe86e48be5f16e0939ea12d..b0b60602f99d66d0d76d343aad41c5f7d3c79793 100644 --- a/src/mpl2mpl/include/native_stub_func.h +++ b/src/mpl2mpl/include/native_stub_func.h @@ -31,6 +31,8 @@ constexpr int kJniTypeMapleCriticalNative = 1; // Equal to real critical native, func will be set critical attribute. // In theory it's incorrect because passing incorrect args. Ex. Linux.getuid constexpr int kJniTypeCriticalNative = 2; +// Equal to critical native but need to pass env and classObj. Ex. Character.isDigitImpl +constexpr int kJniTypeCriticalNeedArg = 3; constexpr int kInvalidCode = 0x01; class NativeFuncProperty { @@ -71,7 +73,7 @@ class NativeStubFuncGeneration : public FuncOptimizeImpl { void GenerateRegisteredNativeFuncCall(MIRFunction &func, const MIRFunction &nativeFunc, MapleVector &args, const MIRSymbol *ret); StmtNode *CreateNativeWrapperCallNode(MIRFunction &func, BaseNode *funcPtr, MapleVector &args, - const MIRSymbol *ret); + const MIRSymbol *ret, bool needIndirectCall); void GenerateNativeWrapperFuncCall(MIRFunction &func, const MIRFunction &nativeFunc, MapleVector &args, const MIRSymbol *ret); void GenerateHelperFuncDecl(); diff --git a/src/mpl2mpl/src/native_stub_func.cpp b/src/mpl2mpl/src/native_stub_func.cpp index ce05da2e5172101f5b499e94c273e790d2137f88..6d0b4285594d988484e45eefab14620858a6ec37 100644 --- a/src/mpl2mpl/src/native_stub_func.cpp +++ b/src/mpl2mpl/src/native_stub_func.cpp @@ -40,7 +40,7 @@ NativeStubFuncGeneration::NativeStubFuncGeneration(MIRModule &mod, KlassHierarch MIRFunction &NativeStubFuncGeneration::GetOrCreateDefaultNativeFunc(MIRFunction &stubFunc) { // If only support dynamic binding , we won't stub any weak symbols - if (Options::regNativeDynamicOnly && !(IsStaticBindingListMode() && IsStaticBindingMethod(stubFunc.GetName()))) { + if (Options::regNativeDynamicOnly && !(IsStaticBindingMethod(stubFunc.GetName()))) { return stubFunc; } std::string nativeName = NameMangler::NativeJavaName(stubFunc.GetName().c_str()); @@ -209,7 +209,8 @@ void NativeStubFuncGeneration::ProcessFunc(MIRFunction *func) { if (Options::regNativeFunc) { GenerateRegisteredNativeFuncCall(*func, nativeFunc, allocCallArgs, stubFuncRet); } - if (func->GetReturnType()->GetPrimType() == PTY_ref) { + bool needDecodeRef = (func->GetReturnType()->GetPrimType() == PTY_ref); + if (needDecodeRef) { MapleVector decodeArgs(func->GetCodeMempoolAllocator().Adapter()); CHECK_FATAL(stubFuncRet != nullptr, "stubfunc_ret is nullptr"); decodeArgs.push_back(builder->CreateExprDread(*stubFuncRet)); @@ -240,8 +241,9 @@ void NativeStubFuncGeneration::ProcessFunc(MIRFunction *func) { NaryStmtNode *syncExit = builder->CreateStmtNary(OP_syncexit, monitor); func->GetBody()->AddStatement(syncExit); } + bool needCheckExceptionCall = needNativeCall; // check pending exception just before leaving this stub frame except for critical natives - if (needNativeCall) { + if (needCheckExceptionCall) { MapleVector getExceptArgs(func->GetCodeMempoolAllocator().Adapter()); CallNode *callGetExceptFunc = builder->CreateStmtCallAssigned(MRTCheckThrowPendingExceptionFunc->GetPuidx(), getExceptArgs, nullptr, OP_callassigned); @@ -334,6 +336,7 @@ void NativeStubFuncGeneration::GenerateRegisteredNativeFuncCall(MIRFunction &fun NativeFuncProperty funcProperty; bool needCheckThrowPendingExceptionFunc = (!func.GetAttr(FUNCATTR_critical_native)) && (funcProperty.jniType == kJniTypeNormal); + bool needIndirectCall = func.GetAttr(FUNCATTR_critical_native) || func.GetAttr(FUNCATTR_fast_native); // Get current native method function ptr from reg_jni_func_tab slot // and define a temp register for shift operation auto funcPtrAndOpPreg = func.GetPregTab()->CreatePreg(PTY_ptr); @@ -359,13 +362,13 @@ void NativeStubFuncGeneration::GenerateRegisteredNativeFuncCall(MIRFunction &fun // default mode, it will generate a weak function, which can link in compile time // dynamic only mode, it won't generate any weak function, it can't link in compile time // static binding list mode, it will generate a weak function only in list - if (IsStaticBindingListMode() && IsStaticBindingMethod(func.GetName())) { + if (IsStaticBindingMethod(func.GetName())) { // Get current func_ptr (strong/weak symbol address) auto *nativeFuncAddr = builder->CreateExprAddroffunc(nativeFunc.GetPuidx()); funcptrAssign = builder->CreateStmtRegassign(PTY_ptr, funcptrPreg, nativeFuncAddr); func.GetBody()->AddStatement(funcptrAssign); // Define wrapper function call - StmtNode *wrapperCall = CreateNativeWrapperCallNode(func, readFuncPtr, args, ret); + StmtNode *wrapperCall = CreateNativeWrapperCallNode(func, readFuncPtr, args, ret, needIndirectCall); func.GetBody()->AddStatement(wrapperCall); } else if (!Options::regNativeDynamicOnly) { // Qemu func.GetBody()->AddStatement(funcptrAssign); @@ -405,10 +408,10 @@ void NativeStubFuncGeneration::GenerateRegisteredNativeFuncCall(MIRFunction &fun ifStmt->GetThenPart()->AddStatement(subIfStmt); if (needCheckThrowPendingExceptionFunc) { func.GetBody()->AddStatement(ifStmt); - StmtNode *wrapperCall = CreateNativeWrapperCallNode(func, readFuncPtr, args, ret); + StmtNode *wrapperCall = CreateNativeWrapperCallNode(func, readFuncPtr, args, ret, needIndirectCall); func.GetBody()->AddStatement(wrapperCall); } else { - StmtNode *wrapperCall = CreateNativeWrapperCallNode(func, readFuncPtr, args, ret); + StmtNode *wrapperCall = CreateNativeWrapperCallNode(func, readFuncPtr, args, ret, needIndirectCall); ifStmt->GetThenPart()->AddStatement(wrapperCall); MapleVector opnds(builder->GetCurrentFuncCodeMpAllocator()->Adapter()); CallNode *callGetExceptFunc = builder->CreateStmtCallAssigned(MRTCheckThrowPendingExceptionFunc->GetPuidx(), @@ -417,7 +420,7 @@ void NativeStubFuncGeneration::GenerateRegisteredNativeFuncCall(MIRFunction &fun auto *elseBlock = func.GetCodeMempool()->New(); ifStmt->SetElsePart(elseBlock); ifStmt->SetNumOpnds(kOperandNumTernary); - wrapperCall = CreateNativeWrapperCallNode(func, readFuncPtr, args, ret); + wrapperCall = CreateNativeWrapperCallNode(func, readFuncPtr, args, ret, needIndirectCall); elseBlock->AddStatement(wrapperCall); func.GetBody()->AddStatement(ifStmt); } @@ -439,7 +442,7 @@ void NativeStubFuncGeneration::GenerateRegisteredNativeFuncCall(MIRFunction &fun ifStmt->GetThenPart()->AddStatement(callGetExceptFunc); } func.GetBody()->AddStatement(ifStmt); - StmtNode *wrapperCall = CreateNativeWrapperCallNode(func, readFuncPtr, args, ret); + StmtNode *wrapperCall = CreateNativeWrapperCallNode(func, readFuncPtr, args, ret, needIndirectCall); func.GetBody()->AddStatement(wrapperCall); } return; @@ -473,7 +476,8 @@ void NativeStubFuncGeneration::GenerateRegisteredNativeFuncCall(MIRFunction &fun } StmtNode *NativeStubFuncGeneration::CreateNativeWrapperCallNode(MIRFunction &func, BaseNode *funcPtr, - MapleVector &args, const MIRSymbol *ret) { + MapleVector &args, const MIRSymbol *ret, + bool needIndirectCall) { #ifdef USE_ARM32_MACRO constexpr size_t numOfArgs = 4; #else @@ -486,7 +490,7 @@ StmtNode *NativeStubFuncGeneration::CreateNativeWrapperCallNode(MIRFunction &fun // Push back all original args. wrapperArgs.insert(wrapperArgs.end(), args.begin(), args.end()); // Do not need native wrapper for fast natives or critical natives. - if (func.GetAttr(FUNCATTR_fast_native) || func.GetAttr(FUNCATTR_critical_native)) { + if (needIndirectCall) { if (ret == nullptr) { return builder->CreateStmtIcall(wrapperArgs); } else { @@ -586,6 +590,9 @@ void NativeStubFuncGeneration::InitStaticBindingMethodList() { } bool NativeStubFuncGeneration::IsStaticBindingMethod(const std::string &methodName) const { + if (!IsStaticBindingListMode()) { + return false; + } return (staticBindingMethodsSet.find(NameMangler::NativeJavaName(methodName.c_str())) != staticBindingMethodsSet.end()); }