diff --git a/src/BUILD.gn b/src/BUILD.gn index 7eabe88f0288d70440bdbeb7155ea06af1381681..230071bdae5447167ad3fd097571e716ceed0884 100644 --- a/src/BUILD.gn +++ b/src/BUILD.gn @@ -1,4 +1,4 @@ -# +iiii# # Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. # # OpenArkCompiler is licensed under the Mulan PSL v1. diff --git a/src/bin/jbc2mpl b/src/bin/jbc2mpl index ce80cf95074a54a3022d571e57dde99960c168f4..5c28c11e03a041f5965df08a2db93f9d0559853a 100755 Binary files a/src/bin/jbc2mpl and b/src/bin/jbc2mpl differ diff --git a/src/bin/maple b/src/bin/maple index f10aeeb18bbeba96a01b459167cf703e94cc8306..e620cd2a1730e210b88d070b0bebe5fa299ae98c 100755 Binary files a/src/bin/maple and b/src/bin/maple differ diff --git a/src/maple_ir/include/intrinsics.def b/src/maple_ir/include/intrinsics.def index 5bb44c353218a73019335e5bdd3aab30aafe7d8c..80e95079597c165a6b4173509cc6be615ba8f122 100644 --- a/src/maple_ir/include/intrinsics.def +++ b/src/maple_ir/include/intrinsics.def @@ -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. @@ -18,7 +18,7 @@ DEF_MIR_INTRINSIC(UNDEFINED,\ DEF_MIR_INTRINSIC(MPL_ATOMIC_EXCHANGE_PTR,\ "__mpl_atomic_exchange_ptr", kIntrnIsAtomic, kArgTyPtr, kArgTyPtr, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) DEF_MIR_INTRINSIC(MPL_CLINIT_CHECK,\ - "__mpl_clinit_check", INTRNISJAVA | INTRNNOSIDEEFFECT, kArgTyVoid, kArgTyDynany, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) + "__mpl_clinit_check", INTRNISJAVA | INTRNNOSIDEEFFECT | INTRNISSPECIAL, kArgTyVoid, kArgTyDynany, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) DEF_MIR_INTRINSIC(MPL_CLEAR_STACK,\ "__mpl_clear_stack", kIntrnUndef, kArgTyVoid, kArgTyDynany, kArgTyDynany, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) DEF_MIR_INTRINSIC(MPL_GET_VTAB_FUNC,\ @@ -53,6 +53,8 @@ DEF_MIR_INTRINSIC(MCCSetObjectPermanent,\ "MCC_SetObjectPermanent", INTRNISRC | INTRNNOSIDEEFFECT, kArgTyVoid, kArgTyRef) // start of RC Intrinsics with two parameters +DEF_MIR_INTRINSIC(MCCCheckArrayStore,\ + "MCC_Reflect_Check_Arraystore", INTRNISRC | INTRNNOSIDEEFFECT, kArgTyVoid, kArgTyRef, kArgTyRef) DEF_MIR_INTRINSIC(MCCIncDecRef,\ "MCC_IncDecRef_NaiveRCFast", INTRNISRC | INTRNNOSIDEEFFECT, kArgTyVoid, kArgTyRef, kArgTyRef) DEF_MIR_INTRINSIC(MCCIncDecRefReset,\ @@ -109,19 +111,20 @@ DEF_MIR_INTRINSIC(MCCWriteWeak,\ "MCC_WriteWeakField", INTRNISRC | INTRNNOSIDEEFFECT, kArgTyVoid, kArgTyRef, kArgTyRef, kArgTyRef) DEF_MIR_INTRINSIC(MPL_CLEANUP_LOCALREFVARS,\ - "__mpl_cleanup_localrefvars", INTRNISJAVA | INTRNNOSIDEEFFECT, kArgTyUndef, kArgTyRef, kArgTyRef, kArgTyRef, kArgTyRef, kArgTyRef, kArgTyRef) + "__mpl_cleanup_localrefvars", INTRNISJAVA | INTRNNOSIDEEFFECT | INTRNISSPECIAL, kArgTyUndef, kArgTyRef, kArgTyRef, kArgTyRef, kArgTyRef, kArgTyRef, kArgTyRef) DEF_MIR_INTRINSIC(MPL_CLEANUP_LOCALREFVARS_SKIP,\ - "__mpl_cleanup_localrefvars_skip", INTRNISJAVA | INTRNNOSIDEEFFECT, kArgTyUndef, kArgTyRef, kArgTyRef, kArgTyRef, kArgTyRef, kArgTyRef, kArgTyRef) + "__mpl_cleanup_localrefvars_skip", INTRNISJAVA | INTRNNOSIDEEFFECT | INTRNISSPECIAL, kArgTyUndef, kArgTyRef, kArgTyRef, kArgTyRef, kArgTyRef, kArgTyRef, kArgTyRef) DEF_MIR_INTRINSIC(MPL_MEMSET_LOCALVAR,\ "", kIntrnUndef, kArgTyPtr, kArgTyU32, kArgTyU8, kArgTyU32, kArgTyUndef, kArgTyUndef, kArgTyUndef) DEF_MIR_INTRINSIC(MPL_SET_CLASS,\ "", kIntrnUndef, kArgTyPtr, kArgTyPtr, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) DEF_MIR_INTRINSIC(MPL_CLEANUP_NORETESCOBJS,\ - "__mpl_cleanup_noretescobjs", INTRNISJAVA | INTRNNOSIDEEFFECT, kArgTyUndef, kArgTyRef, kArgTyRef,\ + "__mpl_cleanup_noretescobjs", INTRNISJAVA | INTRNNOSIDEEFFECT | INTRNISSPECIAL, kArgTyUndef, kArgTyRef, kArgTyRef,\ kArgTyRef, kArgTyRef, kArgTyRef, kArgTyRef) // start of GC Intrinsics #include "intrinsic_java.def" +#include "simplifyintrinsics.def" DEF_MIR_INTRINSIC(LAST,\ nullptr, kIntrnUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) diff --git a/src/maple_ir/include/intrinsics.h b/src/maple_ir/include/intrinsics.h index d9c3ae5ceac66b6ba3a5a28f74ae1d9f3b2ac1ff..780e4d4a9352482be30f9888109fe789c50c3a21 100644 --- a/src/maple_ir/include/intrinsics.h +++ b/src/maple_ir/include/intrinsics.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 IntrinProperty { kIntrnIsPure, kIntrnNeverReturn, kIntrnIsAtomic, - kIntrnIsRC + kIntrnIsRC, + kIntrnIsSpecial }; enum IntrinArgType { @@ -85,6 +86,7 @@ constexpr uint32 INTRNISPURE = 1U << kIntrnIsPure; constexpr uint32 INTRNNEVERRETURN = 1U << kIntrnNeverReturn; constexpr uint32 INTRNATOMIC = 1U << kIntrnIsAtomic; constexpr uint32 INTRNISRC = 1U << kIntrnIsRC; +constexpr uint32 INTRNISSPECIAL = 1U << kIntrnIsSpecial; class MIRType; // circular dependency exists, no other choice class MIRModule; // circular dependency exists, no other choice struct IntrinDesc { @@ -136,6 +138,10 @@ struct IntrinDesc { return properties & INTRNISRC; } + bool IsSpecial() const { + return properties & INTRNISSPECIAL; + } + bool HasNoSideEffect() const { return properties & INTRNNOSIDEEFFECT; } diff --git a/src/maple_ir/include/option.h b/src/maple_ir/include/option.h index 102d7e4f438ca451e259b32a72ee2bf736124571..cd3c1de0f56d527869d7bb9ab43bdcfaa2829675 100644 --- a/src/maple_ir/include/option.h +++ b/src/maple_ir/include/option.h @@ -82,6 +82,7 @@ class Options { #if MIR_JAVA static bool skipVirtualMethod; #endif + static bool checkArrayStore; private: MapleAllocator optionAlloc; std::vector phaseSeq; diff --git a/src/maple_ir/include/simplifyintrinsics.def b/src/maple_ir/include/simplifyintrinsics.def new file mode 100644 index 0000000000000000000000000000000000000000..30c04a7c4576da4d1562a9e3f4ff346b3b3ad804 --- /dev/null +++ b/src/maple_ir/include/simplifyintrinsics.def @@ -0,0 +1,31 @@ +/* + * 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. + * You may obtain a copy of Mulan PSL v1 at: + * + * http://license.coscl.org.cn/MulanPSL + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v1 for more details. + */ + +/* INTRINSIC(STR, NAME) */ +DEF_MIR_INTRINSIC(GET_AND_ADDI, "Lsun_2Fmisc_2FUnsafe_3B_7CgetAndAddInt_7C_28Ljava_2Flang_2FObject_3BJI_29I",\ + INTRNISJAVA | INTRNISSPECIAL, kArgTyI32, kArgTyRef, kArgTyRef, kArgTyI64, kArgTyI32) +DEF_MIR_INTRINSIC(GET_AND_ADDL, "Lsun_2Fmisc_2FUnsafe_3B_7CgetAndAddLong_7C_28Ljava_2Flang_2FObject_3BJJ_29J",\ + INTRNISJAVA | INTRNISSPECIAL, kArgTyI64, kArgTyRef, kArgTyRef, kArgTyI64, kArgTyI64) +DEF_MIR_INTRINSIC(GET_AND_SETI, "Lsun_2Fmisc_2FUnsafe_3B_7CgetAndSetInt_7C_28Ljava_2Flang_2FObject_3BJI_29I",\ + INTRNISJAVA | INTRNISSPECIAL, kArgTyI32, kArgTyRef, kArgTyRef, kArgTyI64, kArgTyI32) +DEF_MIR_INTRINSIC(GET_AND_SETL, "Lsun_2Fmisc_2FUnsafe_3B_7CgetAndSetLong_7C_28Ljava_2Flang_2FObject_3BJJ_29J",\ + INTRNISJAVA | INTRNISSPECIAL, kArgTyI64, kArgTyRef, kArgTyRef, kArgTyI64, kArgTyI64) +DEF_MIR_INTRINSIC(COMP_AND_SWAPI, "Lsun_2Fmisc_2FUnsafe_3B_7CcompareAndSwapInt_7C_28Ljava_2Flang_2FObject_3BJII_29Z",\ + INTRNISJAVA | INTRNISSPECIAL, kArgTyU1, kArgTyRef, kArgTyRef, kArgTyI64, kArgTyI32, kArgTyI32) +DEF_MIR_INTRINSIC(COMP_AND_SWAPL, "Lsun_2Fmisc_2FUnsafe_3B_7CcompareAndSwapLong_7C_28Ljava_2Flang_2FObject_3BJJJ_29Z",\ + INTRNISJAVA | INTRNISSPECIAL, kArgTyU1, kArgTyRef, kArgTyRef, kArgTyI64, kArgTyI64, kArgTyI64) +DEF_MIR_INTRINSIC(STR_INDEXOF, "Ljava_2Flang_2FString_3B_7CindexOf_7C_28Ljava_2Flang_2FString_3B_29I",\ + INTRNISJAVA | INTRNISSPECIAL, kArgTyI32, kArgTyRef, kArgTyRef) + diff --git a/src/maple_ir/src/option.cpp b/src/maple_ir/src/option.cpp index e6eeda9c9388eabf6825852c186d6b42aae663b1..813d18839e115e161e2b3669159de42f24352c0d 100644 --- a/src/maple_ir/src/option.cpp +++ b/src/maple_ir/src/option.cpp @@ -55,6 +55,7 @@ bool Options::emitVtableImpl = false; #if MIR_JAVA bool Options::skipVirtualMethod = false; #endif +bool Options::checkArrayStore = false; enum OptionIndex { kUnknown, kHelp, @@ -89,6 +90,7 @@ enum OptionIndex { kMapleLinker, kMplnkDumpMuid, kEmitVtableImpl, + kCheckArrayStore, }; const Descriptor kUsage[] = { @@ -163,6 +165,8 @@ const Descriptor kUsage[] = { #if MIR_JAVA { kSkipVirtual, 0, "", "skipvirtual", kBuildTypeAll, kArgCheckPolicyNone, " --skipvirtual" }, #endif + { kCheckArrayStore, 0, "", "check-array-store", kBuildTypeAll, kArgCheckPolicyNone, + " --check-array-store Check array store[default off]" }, { 0, 0, nullptr, nullptr, kBuildTypeAll, kArgCheckPolicyNone, nullptr } }; @@ -278,6 +282,9 @@ bool Options::ParseOptions(int argc, char **argv, std::string &fileName) const { Options::skipVirtualMethod = true; break; #endif + case kCheckArrayStore: + Options::checkArrayStore = true; + break; default: result = false; ASSERT(false, "unhandled case in Options"); diff --git a/src/maple_me/include/me_rc_lowering.h b/src/maple_me/include/me_rc_lowering.h index 6a58eae885f524576b3912362bc4a1939c1119d1..58d996fa5e8b666de0f096b5d9e09c0a411f9631 100644 --- a/src/maple_me/include/me_rc_lowering.h +++ b/src/maple_me/include/me_rc_lowering.h @@ -89,6 +89,8 @@ class RCLowering { void HandleReturnStmt(); void HandleAssignMeStmt(MeStmt &stmt, MeExpr *pendingDec); MIRIntrinsicID SelectWriteBarrier(const MeStmt &stmt); + MIRType *GetArrayNodeType(VarMeExpr &var); + void CheckArrayStore(IntrinsiccallMeStmt &writeRefCall); MeFunction &func; MIRModule &mirModule; IRMap &irMap; diff --git a/src/maple_me/src/me_rc_lowering.cpp b/src/maple_me/src/me_rc_lowering.cpp index d5467bab225bf3c72b68b75159bfd6aebc41eab1..8abc62b3dd1c3a3b8bbfe395e21c25266245515d 100644 --- a/src/maple_me/src/me_rc_lowering.cpp +++ b/src/maple_me/src/me_rc_lowering.cpp @@ -342,6 +342,66 @@ void RCLowering::HandleAssignMeStmtVarLHS(MeStmt &stmt, MeExpr *pendingDec) { assignedPtrSym.insert(lsym); } +MIRType *RCLowering::GetArrayNodeType(VarMeExpr &var) { + const MIRSymbol *arrayElemSym = ssaTab.GetMIRSymbolFromID(var.GetOStIdx()); + MIRType *baseType = arrayElemSym->GetType(); + MIRType *arrayElemType = nullptr; + if (baseType != nullptr) { + MIRType *stType = GlobalTables::GetTypeTable().GetTypeFromTyIdx( + static_cast(baseType)->GetPointedTyIdx()); + while (kTypeJArray == stType->GetKind()) { + MIRJarrayType *baseType1 = static_cast(stType); + MIRType *elemType = baseType1->GetElemType(); + if (elemType->GetKind() == kTypePointer) { + const TyIdx &index = static_cast(elemType)->GetPointedTyIdx(); + stType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(index); + } else { + stType = elemType; + } + } + arrayElemType = stType; + } + return arrayElemType; +} + +void RCLowering::CheckArrayStore(IntrinsiccallMeStmt &writeRefCall) { + if (!Options::checkArrayStore) { + return; + } + MIRIntrinsicID intrnID = writeRefCall.GetIntrinsic(); + if (!((INTRN_MCCWriteVolNoInc <= intrnID) && (intrnID <= INTRN_MCCWrite))) { + return; + } + if (writeRefCall.GetOpnd(1)->GetOp() != OP_iaddrof) { + return; + } + OpMeExpr *opExpr = static_cast(writeRefCall.GetOpnd(1)); + if (opExpr->GetOpnd(0)->GetOp() != OP_array) { + return; + } + MeExpr *arrayNode = writeRefCall.GetOpnd(0); + if (arrayNode->GetMeOp() != kMeOpVar) { + return; + } + VarMeExpr *arrayVar = static_cast(arrayNode); + MeExpr *valueNode = writeRefCall.GetOpnd(2); + if (valueNode->GetMeOp() != kMeOpVar) { + return; + } + MIRType *arrayElemType = GetArrayNodeType(*arrayVar); + MIRType *valueRealType = GetArrayNodeType(*(static_cast(valueNode))); + if ((arrayElemType != nullptr) && (arrayElemType->GetKind() == kTypeClass) && + static_cast(arrayElemType)->IsFinal() && + (valueRealType != nullptr) && (valueRealType->GetKind() == kTypeClass) && + static_cast(valueRealType)->IsFinal() && + (valueRealType->GetTypeIndex() == arrayElemType->GetTypeIndex())) { + return; + } + std::vector opnds = { arrayNode, valueNode }; + IntrinsiccallMeStmt *checkStmt = irMap.CreateIntrinsicCallMeStmt(INTRN_MCCCheckArrayStore, opnds); + writeRefCall.GetBB()->InsertMeStmtBefore(&writeRefCall, checkStmt); +} + void RCLowering::HandleAssignToGlobalVar(MeStmt &stmt) { MeExpr *lhs = stmt.GetLHS(); CHECK_FATAL(lhs != nullptr, "null ptr check"); @@ -353,6 +413,7 @@ void RCLowering::HandleAssignToGlobalVar(MeStmt &stmt) { std::vector opnds = { irMap.CreateAddrofMeExpr(*lhs), rhs }; IntrinsiccallMeStmt *writeRefCall = CreateRCIntrinsic(SelectWriteBarrier(stmt), stmt, opnds); bb->ReplaceMeStmt(&stmt, writeRefCall); + CheckArrayStore(*writeRefCall); } void RCLowering::HandleAssignToLocalVar(MeStmt &stmt, MeExpr *pendingDec) { @@ -436,6 +497,7 @@ void RCLowering::HandleAssignMeStmtIvarLHS(MeStmt &stmt) { { &lhsInner->GetBase()->GetAddrExprBase(), irMap.CreateAddrofMeExpr(*lhsInner), rhsInner }; IntrinsiccallMeStmt *writeRefCall = CreateRCIntrinsic(intrinsicID, stmt, opnds); stmt.GetBB()->ReplaceMeStmt(&stmt, writeRefCall); + CheckArrayStore(*writeRefCall); } void RCLowering::HandleAssignMeStmt(MeStmt &stmt, MeExpr *pendingDec) { @@ -654,6 +716,10 @@ void RCLowering::HandleReturnRegread(RetMeStmt &ret) { opnds->erase(iter); opnds->push_back(retVar); // pin it to end of std::vector cleanup->SetIntrinsic(INTRN_MPL_CLEANUP_LOCALREFVARS_SKIP); + MIRSymbol *sym = ssaTab.GetMIRSymbolFromID(retVar->GetOStIdx()); + if (sym->GetAttr(ATTR_localrefvar)) { + func.GetMirFunc()->InsertMIRSymbol(sym); + } break; } } diff --git a/src/mpl2mpl/include/vtable_impl.h b/src/mpl2mpl/include/vtable_impl.h index afbf28acf9f47cf512bf7cfc2c9224c0decf829c..d3d63eeba90f09aeba67e7d25d951451a66fb541 100644 --- a/src/mpl2mpl/include/vtable_impl.h +++ b/src/mpl2mpl/include/vtable_impl.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. @@ -37,6 +37,7 @@ class VtableImpl : public FuncOptimizeImpl { private: void ReplaceResolveInterface(StmtNode &stmt, const ResolveFuncNode &resolveNode); + void Intrinsify(MIRFunction &func, CallNode &cnode); MIRModule *mirModule; MIRFunction *mccItabFunc; }; diff --git a/src/mpl2mpl/src/vtable_impl.cpp b/src/mpl2mpl/src/vtable_impl.cpp index 99de42f21740f26bd630a46748e941d1f5350528..df2fea5a2e190a5b239ad2c6e577d22e5f3118a1 100644 --- a/src/mpl2mpl/src/vtable_impl.cpp +++ b/src/mpl2mpl/src/vtable_impl.cpp @@ -32,7 +32,43 @@ VtableImpl::VtableImpl(MIRModule *mod, KlassHierarchy *kh, bool dump) mccItabFunc = builder->GetOrCreateFunction(kInterfaceMethod, TyIdx(PTY_ptr)); mccItabFunc->SetAttr(FUNCATTR_nosideeffect); } - +#if TARGARM || TARGAARCH64 +void VtableImpl::Intrinsify(MIRFunction &func, CallNode &cnode) { + MIRFunction *calleeFunc = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(cnode.GetPUIdx()); + const std::string funcName = calleeFunc->GetName(); + MIRIntrinsicID intrnId = INTRN_UNDEFINED; + if (funcName == "Lsun_2Fmisc_2FUnsafe_3B_7CgetAndAddInt_7C_28Ljava_2Flang_2FObject_3BJI_29I") { + intrnId = INTRN_GET_AND_ADDI; + } else if (funcName == "Lsun_2Fmisc_2FUnsafe_3B_7CgetAndAddLong_7C_28Ljava_2Flang_2FObject_3BJJ_29J") { + intrnId = INTRN_GET_AND_ADDL; + } else if (funcName == "Lsun_2Fmisc_2FUnsafe_3B_7CgetAndSetInt_7C_28Ljava_2Flang_2FObject_3BJI_29I") { + intrnId = INTRN_GET_AND_SETI; + } else if (funcName == "Lsun_2Fmisc_2FUnsafe_3B_7CgetAndSetLong_7C_28Ljava_2Flang_2FObject_3BJJ_29J") { + intrnId = INTRN_GET_AND_SETL; + } else if (funcName == "Lsun_2Fmisc_2FUnsafe_3B_7CcompareAndSwapInt_7C_28Ljava_2Flang_2FObject_3BJII_29Z") { + intrnId = INTRN_COMP_AND_SWAPI; + } else if (funcName == "Lsun_2Fmisc_2FUnsafe_3B_7CcompareAndSwapLong_7C_28Ljava_2Flang_2FObject_3BJJJ_29Z") { + intrnId = INTRN_COMP_AND_SWAPL; + } + if (intrnId == INTRN_UNDEFINED) { + return; + } + CallReturnVector retvs = cnode.GetReturnVec(); + if (!retvs.empty()) { + StIdx stidx = retvs.begin()->first; + StmtNode *intrnCallStmt = nullptr; + if (stidx.Idx() != 0) { + MIRSymbol *retSt = currFunc->GetLocalOrGlobalSymbol(stidx); + intrnCallStmt = builder->CreateStmtIntrinsicCallAssigned(intrnId, cnode.GetNopnd(), retSt); + } else { + ASSERT (retvs.begin()->second.IsReg(), "return value must be preg"); + PregIdx pregIdx = retvs.begin()->second.GetPregIdx(); + intrnCallStmt = builder->CreateStmtIntrinsicCallAssigned(intrnId, cnode.GetNopnd(), pregIdx); + } + func.GetBody()->ReplaceStmt1WithStmt2(&cnode, intrnCallStmt); + } +} +#endif void VtableImpl::ProcessFunc(MIRFunction *func) { if (func->IsEmpty()) { return; @@ -43,6 +79,24 @@ void VtableImpl::ProcessFunc(MIRFunction *func) { while (stmt != nullptr) { next = stmt->GetNext(); Opcode opcode = stmt->GetOpCode(); +#if TARGARM || TARGAARCH64 + if (kOpcodeInfo.IsCallAssigned(opcode)) { + CallNode *cnode = static_cast(stmt); + MIRFunction *calleefunc = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(cnode->GetPUIdx()); + const std::set intrisicsList { +#define DEF_MIR_INTRINSIC(X, NAME, INTRN_CLASS, RETURN_TYPE, ...) NAME, +#include "simplifyintrinsics.def" +#undef DEF_MIR_INTRINSIC + }; + const std::string funcName = calleefunc->GetName(); + if (Options::O2 && intrisicsList.find(funcName) != intrisicsList.end() && + funcName != "Ljava_2Flang_2FString_3B_7CindexOf_7C_28Ljava_2Flang_2FString_3B_29I") { + Intrinsify(*func, *cnode); + stmt = next; + continue; + } + } +#endif switch (opcode) { case OP_regassign: { auto *regassign = static_cast(stmt);