diff --git a/Makefile b/Makefile index eb4864a7be47c0d83243b73cf9b4ac3e5c570800..27e45931a0c27b2b3afb6b57d2ed337b69c5e2b2 100644 --- a/Makefile +++ b/Makefile @@ -95,6 +95,19 @@ js2mpl: mplbe: $(call build_gn, ${GN_OPTIONS}, mplbe) +.PHONY: mplme +mplme: + $(call build_gn, ${GN_OPTIONS}, mplme) + +.PHONY: mplipa_js +mplipa_js: + $(call build_gn, ${GN_OPTIONS}, mplipa_js) + +.PHONY: mplme_js +mplme_js: + $(call build_gn, ${GN_OPTIONS_MPLJS}, mplme) + mv ${OUTPUT_BIN_DIR}/mplme ${OUTPUT_BIN_DIR}/mplme_js + .PHONY: mplbe_js mplbe_js: $(call build_gn, ${GN_OPTIONS_MPLJS}, mplbe) diff --git a/mapleall/maple_be/include/cg/ark/ark_mir_emit.h b/mapleall/maple_be/include/cg/ark/ark_mir_emit.h index d5d6948c2839c6e57eb13107d546b2d3ff68c39d..333c29da177676aa9db35f1213e6bbfc77e2f1e7 100644 --- a/mapleall/maple_be/include/cg/ark/ark_mir_emit.h +++ b/mapleall/maple_be/include/cg/ark/ark_mir_emit.h @@ -220,7 +220,8 @@ enum RE_FuncAttr { FuncAttrFinalize = 1 << 1, FuncAttrStatic = 1 << 2, FuncAttrConstructor = 1 << 3, - FuncAttrJSStrict = 1 << 4 + FuncAttrJSStrict = 1 << 4, + FuncAttrJSArgument = 1 << 5 }; class RE_Func { @@ -279,6 +280,9 @@ class RE_Func { void SetJSStrictAttr() { funcAttrs |= FuncAttrJSStrict; } + void SetJSArgumentAttr() { + funcAttrs |= FuncAttrJSArgument; + } void AddFormalPreg(int pregno) { formalPregs[pregno] = 1+numFormalArgs++; } diff --git a/mapleall/maple_be/src/be/mmpl/mmpl_lowerer.cpp b/mapleall/maple_be/src/be/mmpl/mmpl_lowerer.cpp index aba6a98c7fec3bb3006c0e108826db36e13b75b4..0d40e6206861ff1c7f9cfacf442dc9dd481cbfb0 100644 --- a/mapleall/maple_be/src/be/mmpl/mmpl_lowerer.cpp +++ b/mapleall/maple_be/src/be/mmpl/mmpl_lowerer.cpp @@ -80,7 +80,7 @@ BaseNode *MmplLowerer::LowerAddrof(AddrofNode *expr) { offset += symbol->IsLocal() ? memlayout->sym_alloc_table[symbol->GetStIndex()].offset : globmemlayout->sym_alloc_table[symbol->GetStIndex()].offset; return (offset == 0) ? rrn - : mirModule.mirBuilder->CreateExprBinary(OP_add, GlobalTables::GetTypeTable().GetTypeFromTyIdx((TyIdx)LOWERED_PTR_TYPE), rrn, + : mirModule.mirBuilder->CreateExprBinary(OP_add, GlobalTables::GetTypeTable().GetTypeFromTyIdx((TyIdx)expr->primType), rrn, mirModule.mirBuilder->GetConstInt(offset)); } diff --git a/mapleall/maple_be/src/be/mmpl/mmpl_mem_layout.cpp b/mapleall/maple_be/src/be/mmpl/mmpl_mem_layout.cpp index 5440ef8e13e7ca270e1f485e33bc0bf4423fc446..0adeb091815b46039858e8671c01b785a37c4acd 100644 --- a/mapleall/maple_be/src/be/mmpl/mmpl_mem_layout.cpp +++ b/mapleall/maple_be/src/be/mmpl/mmpl_mem_layout.cpp @@ -160,8 +160,8 @@ void MmplMemLayout::LayoutStackFrame(void) { seg_FPbased.size -= seg_formal.size; seg_FPbased.size = RoundDown(seg_FPbased.size, SIZEOFPTR); seg_formal.how_alloc.offset = seg_FPbased.size; - LogInfo::MapleLogger() << "LAYOUT: seg_formal at seg_FPbased offset " << seg_formal.how_alloc.offset << " with size " - << seg_formal.size << std::endl; + //LogInfo::MapleLogger() << "LAYOUT: seg_formal at seg_FPbased offset " << seg_formal.how_alloc.offset << " with size " + // << seg_formal.size << std::endl; // allocate the local variables uint32 symtabsize = func->symTab->GetSymbolTableSize(); @@ -194,8 +194,8 @@ void MmplMemLayout::LayoutStackFrame(void) { seg_SPbased.size = RoundUp(seg_SPbased.size, SIZEOFPTR); seg_SPbased.size += seg_actual.size; seg_SPbased.size = RoundUp(seg_SPbased.size, SIZEOFPTR); - LogInfo::MapleLogger() << "LAYOUT: seg_actual at seg_SPbased offset " << seg_actual.how_alloc.offset << " with size " - << seg_actual.size << std::endl; + //LogInfo::MapleLogger() << "LAYOUT: seg_actual at seg_SPbased offset " << seg_actual.how_alloc.offset << " with size " + // << seg_actual.size << std::endl; // go thru the function's symbol table to set typetagged and refcounted bitvectors if (UpformalSize() != 0) { @@ -443,7 +443,7 @@ GlobalMemLayout::GlobalMemLayout(BECommon &be, MapleAllocator *mallocator) sym_alloc_table[stindex].offset = seg_GPbased.size; seg_GPbased.size += be.type_size_table[sym->GetTyIdx().GetIdx()]; // LogInfo::MapleLogger() << "LAYOUT: global %" << GlobalTables::GetStringFromGstridx(sym->GetNameStridx()); - LogInfo::MapleLogger() << " at GPbased offset " << sym_alloc_table[stindex].offset << std::endl; + // LogInfo::MapleLogger() << " at GPbased offset " << sym_alloc_table[stindex].offset << std::endl; } } seg_GPbased.size = RoundUp(seg_GPbased.size, SIZEOFPTR); diff --git a/mapleall/maple_be/src/cg/ark/ark_mir_emit.cpp b/mapleall/maple_be/src/cg/ark/ark_mir_emit.cpp index 4a212a8715fb6bc4132ea812f75f43a1d37f3542..3c0ea910e6f575fd636166372c04d30cc564ecaf 100644 --- a/mapleall/maple_be/src/cg/ark/ark_mir_emit.cpp +++ b/mapleall/maple_be/src/cg/ark/ark_mir_emit.cpp @@ -1161,6 +1161,7 @@ void MirGenerator::EmitAsmFuncInfo(MIRFunction *func) { if (GlobalTables::GetStrTable().GetStringFromStrIdx(func->GetBaseFuncNameStridx()) == "finalize") curFunc.SetFinalizeAttr(); } else { if (func->GetAttr(FUNCATTR_strict)) curFunc.SetJSStrictAttr(); + if (func->GetAttr(FUNCATTR_jsarguments)) curFunc.SetJSArgumentAttr(); } curFunc.evalStackDepth = MaxEvalStack(func); // insert interpreter shim and signature diff --git a/mapleall/maple_ipa/BUILD.gn b/mapleall/maple_ipa/BUILD.gn index 45f7296edc8c7a7d06090b0886da94b539a9f01c..cc15c8c9bae3b593bcac698158a192c959408a7d 100644 --- a/mapleall/maple_ipa/BUILD.gn +++ b/mapleall/maple_ipa/BUILD.gn @@ -67,3 +67,23 @@ executable("mplipa"){ "${HUAWEI_SECURE_C_ROOT}:libHWSecureC", ] } + +executable("mplipa_js"){ + sources = [ + "src/ipadriver-js.cpp", + ] + + include_dirs = include_directories + + deps = [ + ":libmplipa", + "${MAPLEALL_ROOT}/maple_me:libmplme", + "${MAPLEALL_ROOT}/maple_ir:libmplir", + "${MAPLEALL_ROOT}/mpl2mpl:libmpl2mpl", + "${MAPLEALL_ROOT}/maple_me:libmplmewpo", + "${MAPLEALL_ROOT}/maple_phase:libmplphase", + "${MAPLEALL_ROOT}/mempool:libmempool", + "${MAPLEALL_ROOT}/maple_util:libmplutil", + "${HUAWEI_SECURE_C_ROOT}:libHWSecureC", + ] +} diff --git a/mapleall/maple_ipa/include/greedyinline.h b/mapleall/maple_ipa/include/greedyinline.h index 49d9460ec5e53fa7193d25b07f1549eae8fc9107..d01d6fb7f80b7b46b9a3c19a9ba926cf2c23bd46 100644 --- a/mapleall/maple_ipa/include/greedyinline.h +++ b/mapleall/maple_ipa/include/greedyinline.h @@ -86,6 +86,15 @@ class GreedyInline : public MInline { LoopDepthBonusFactor = 10; WeightScaleFactor = 400; } + GreedyInline(MIRModule &mod, MemPool *mp, CallGraph *cg, double grt) : MInline(mod, mp, nullptr, cg), growth_rate_threshold(grt) { + // todo change case for all fields + max_nodes_threshold = 80; + InlineWeightThreshold = 0; + BenefitConstantArgument = 2; + BenefitVariableArgument = 0; + LoopDepthBonusFactor = 10; + WeightScaleFactor = 400; + } ~GreedyInline() {} diff --git a/mapleall/maple_ipa/src/callgraph.cpp b/mapleall/maple_ipa/src/callgraph.cpp index 3e26de13846ebdfd225a3cf4e3af03ab85225a4c..4b8845ab8dce24e95b8096dd538d301e928d574d 100644 --- a/mapleall/maple_ipa/src/callgraph.cpp +++ b/mapleall/maple_ipa/src/callgraph.cpp @@ -366,6 +366,7 @@ CGNode *CallGraph::GetOrGenCGNode(PUIdx puIdx) { void CallGraph::HandleBody(MIRFunction *func, BlockNode *body, CGNode *node, uint32 loopDepth) { char *line = nullptr; StmtNode *stmtNext = nullptr; + bool isJavaScript = func->module->IsJsModule(); for (StmtNode *stmt = body->GetFirst(); stmt != nullptr; stmt = stmtNext) { stmtNext = static_cast(stmt)->GetNext(); Opcode op = stmt->op; @@ -397,6 +398,9 @@ void CallGraph::HandleBody(MIRFunction *func, BlockNode *body, CGNode *node, uin // Add a call node whether or not the calleefunc has its body CGNode *calleenode = GetOrGenCGNode(calleefunc->puIdx); ASSERT(calleenode != nullptr, "calleenode is null in CallGraph::HandleBody"); + if (isJavaScript) { + calleenode->IncrNodeCountBy(1); + } calleenode->AddCaller(node); node->AddCallsite(callinfo, calleenode); Klass *klass = klassh->GetKlassFromFunc(calleefunc); @@ -568,6 +572,9 @@ void CallGraph::HandleBody(MIRFunction *func, BlockNode *body, CGNode *node, uin CallInfo *callinfo = GenCallInfo(kCallTypeCall, line, actualMirfunc, stmt, loopDepth, stmt->stmtID); CGNode *calleenode = GetOrGenCGNode(actualMirfunc->puIdx); ASSERT(calleenode != nullptr, "calleenode is null in CallGraph::HandleBody"); + if (isJavaScript) { + calleenode->IncrNodeCountBy(1); + } calleenode->AddCaller(node); node->AddCallsite(callinfo, calleenode); } else { @@ -576,6 +583,9 @@ void CallGraph::HandleBody(MIRFunction *func, BlockNode *body, CGNode *node, uin CallInfo *callinfo = GenCallInfo(kCallTypeCall, line, calleefunc, stmt, loopDepth, stmt->stmtID); CGNode *calleenode = GetOrGenCGNode(calleefunc->puIdx); ASSERT(calleenode != nullptr, "calleenode is null in CallGraph::HandleBody"); + if (isJavaScript) { + calleenode->IncrNodeCountBy(1); + } calleenode->AddCaller(node); node->AddCallsite(callinfo, calleenode); } diff --git a/mapleall/maple_ipa/src/greedyinline.cpp b/mapleall/maple_ipa/src/greedyinline.cpp index 8b13a3973cd93477d5c1e0e41111384a01e5d67b..ef34161373c90c0fe3312e46ed458afd427233ae 100644 --- a/mapleall/maple_ipa/src/greedyinline.cpp +++ b/mapleall/maple_ipa/src/greedyinline.cpp @@ -392,10 +392,16 @@ void GreedyInline::Inline() { caller->GetMIRFuncName().c_str()); } MIRFunction *callerFunc = caller->GetMIRFunction(); + MIRFunction *calleeFunc = callee->GetMIRFunction(); CallNode *callStmt = static_cast(cs.ci->GetCallStmt()); + if (mod_.IsJsModule()) { + if (callStmt->NumOpnds() != calleeFunc->formalDefVec.size() || calleeFunc->GetAttr(FUNCATTR_jsarguments)) { + break; + } + } BlockNode *enclosingBlk = FindEnclosingBlk(callerFunc->body, callStmt); CHECK_FATAL(enclosingBlk, "null ptr check"); - PerformInline(callerFunc, enclosingBlk, callStmt, callee->GetMIRFunction()); + PerformInline(callerFunc, enclosingBlk, callStmt, calleeFunc); UpdateCallGraph(cs); UpdateCallSites(cs, callSites, canInline); @@ -407,9 +413,15 @@ AnalysisResult *DoGreedyInline::Run(MIRModule *module, ModuleResultMgr *m) { MemPool *mp = mempoolctrler.NewMemPool("inline mempool"); CallGraph *cg = static_cast(m->GetAnalysisResult(MoPhase_CALLGRAPH_ANALYSIS, module)); CHECK_FATAL(cg != nullptr, "Expecting a valid CallGraph, found nullptr"); - GreedyInline ginline(*module, mp, cg); - cg->DumpToFile(false); - ginline.Inline(); + if (module->IsJsModule()) { + GreedyInline ginline(*module, mp, cg, 1.10); + cg->DumpToFile(false); + ginline.Inline(); + } else { + GreedyInline ginline(*module, mp, cg); + cg->DumpToFile(false); + ginline.Inline(); + } cg->DumpToFile(true); maple::ConstantFold cf(module); for (MapleVector::iterator it = module->functionList.begin(); it != module->functionList.end(); diff --git a/mapleall/maple_ipa/src/ipadriver-js.cpp b/mapleall/maple_ipa/src/ipadriver-js.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e10e5140c25181fd27e9ae863fad18c7549f99de --- /dev/null +++ b/mapleall/maple_ipa/src/ipadriver-js.cpp @@ -0,0 +1,184 @@ +/* + * Copyright (c) [2020] Huawei Technologies Co., Ltd. All rights reserved. + * + * OpenArkCompiler is licensed under the Mulan Permissive Software License v2. + * You can use this software according to the terms and conditions of the MulanPSL - 2.0. + * You may obtain a copy of MulanPSL - 2.0 at: + * + * https://opensource.org/licenses/MulanPSL-2.0 + * + * 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 MulanPSL - 2.0 for more details. + */ + +#include +#include +#include "mir_parser.h" +#include "opcode_info.h" +#include "callgraph.h" +#include "me_cfg.h" +#include "module_phase_manager.h" +#include "option_parser.h" +#include "inline.h" +#include "moduleipa.h" +#include "interleaved_manager.h" +#include "option.h" +#include "simplify.h" +#include "bin_mpl_import.h" + +/* + * Inter procedual analysis + * 1. function side effect. + * 2. escape analysis + * Don't make any modification on mpl. Analysis result will be written into mplt +*/ +using namespace std; +using namespace mapleOption; + +static bool effectIpa = false; +static bool timePhases = false; + +string optName = "inline"; +#define MPLIPA_VERSION "mplipa (CBG Programming Platform TD V100R001C00B824SP01) 1.1.824.1 20181213" + +enum OptionIndex { kUnknown, kHelp, kVersion, kOptL1, kOptL2, kEffectIPA, kInlineHint, kQuiet, kTimePhases }; + +const Descriptor kUsage[] = { + { kUnknown, 0, "", "", kBuildTypeAll, kArgCheckPolicyUnknown, + "USAGE: mplipa [options] *.mpl\n\n" + "OPTIONS:" }, + { kHelp, 0, "h", "help", kBuildTypeAll, kArgCheckPolicyNone, " -h, --help Print usage and exit" }, + { kVersion, 0, "v", "version", kBuildTypeAll, kArgCheckPolicyNone, " -v, --version Print version and exit" }, + + { kOptL1, 0, "", "O1", kBuildTypeAll, kArgCheckPolicyNone, " --O1 Enable basic inlining" }, + { kOptL2, 0, "", "O2", kBuildTypeAll, kArgCheckPolicyNone, " --O2 Enable greedy inlining" }, + { kEffectIPA, 0, "", "effectipa", kBuildTypeAll, kArgCheckPolicyNone, + " --effectipa Enable method side effect for ipa" }, + { kInlineHint, 0, "", "inlinefunclist", kBuildTypeAll, kArgCheckPolicyRequired, + "--inlinefunclist= Inlining related configuration" }, + { kQuiet, 0, "", "quiet", kBuildTypeAll, kArgCheckPolicyNone, " --quiet Disable out debug info" }, + { kTimePhases, 0, "", "time-phases", kBuildTypeAll, kArgCheckPolicyNone, " --time-phases Timing phases and print percentages" }, + { 0, 0, nullptr, nullptr, kBuildTypeAll, kArgCheckPolicyUnknown, nullptr } +}; + +void ParseCmdline(int argc, char **argv, vector &fileNames) { + OptionParser optionParser(kUsage); + int ret = optionParser.Parse(argc, argv); + CHECK_FATAL(ret == ErrorCode::kErrorNoError, "option parser error"); + // Default value + MInline::inlineFuncList = ""; + for (auto opt : optionParser.GetOptions()) { + switch (opt.Index()) { + case kHelp: + if (opt.Args().empty()) { + optionParser.PrintUsage(); + exit(1); + } + break; + case kOptL1: + optName = "inline"; + break; + case kOptL2: + optName = "greedyinline"; + break; + case kEffectIPA: + effectIpa = true; + break; + case kQuiet: + MeOption::quiet = true; + Options::quiet = true; + break; + case kTimePhases: + timePhases = true; + break; + case kVersion: + LogInfo::MapleLogger() << MPLIPA_VERSION << std::endl; + break; + case kInlineHint: + MInline::inlineFuncList = opt.Args(); + break; + default: + ASSERT(false, "unhandled case in ParseCmdline"); + } + } + + for (int i = 0; i < optionParser.GetNonOptionsCount(); i++) { + fileNames.push_back(optionParser.GetNonOptions().at(i)); + } +} + +void DoIpaSideEffectAnalysis(MIRModule *mirModule) { + MemPool *optmp = mempoolctrler.NewMemPool("ipa sideeffect mempool"); + vector modphases; + std::string ipainput; + InterleavedManager mgr(optmp, mirModule, ipainput, timePhases); + if (mirModule->IsJsModule()) { + modphases.push_back(string("callgraph")); + MInline::level = 3; + modphases.push_back(string("greedyinline")); + mgr.AddPhases(modphases, true, timePhases); + mgr.Run(); + } else { + modphases.push_back(string("classhierarchy")); + modphases.push_back(string("ipodevirtulize")); + modphases.push_back(string("callgraph")); + Simplify::doclinitopt = true; + modphases.push_back(string("Simplify")); + MInline::level = 2; + modphases.push_back(string("inline")); + mgr.AddPhases(modphases, true, timePhases); + modphases.clear(); + + vector mephases; + mephases.push_back(string("cfgbuild")); + mephases.push_back(string("ssatab")); + mephases.push_back(string("aliasclass")); + mephases.push_back(string("ssa")); + mephases.push_back(string("dse")); + mephases.push_back(string("irmapbuild")); + mephases.push_back(string("ssadevirt")); + mephases.push_back(string("emit")); + mgr.AddPhases(mephases, false, timePhases); + mephases.clear(); + + modphases.push_back(string("callgraph")); + mgr.AddPhases(modphases, true, timePhases); + modphases.clear(); + + mephases.push_back(string("cfgbuild")); + mephases.push_back(string("ssatab")); + mephases.push_back(string("aliasclass")); + mephases.push_back(string("ssa")); + mephases.push_back(string("dse")); + mephases.push_back(string("irmapbuild")); + mephases.push_back(string("ssadevirt")); + mephases.push_back(string("sideeffect")); + mgr.AddPhases(mephases, false, timePhases); + modphases.clear(); + + modphases.push_back(string("updatemplt")); + mgr.AddPhases(modphases, true, timePhases); + mgr.Run(); + } + mempoolctrler.DeleteMemPool(optmp); +} + +int main(int argc, char **argv) { + vector fileNames; + ParseCmdline(argc, argv, fileNames); + + MemPool *modulemp = mempoolctrler.NewMemPool("maple modulephase mempool"); + MIRModule *themodule = new maple::MIRModule(fileNames[0].c_str()); + maple::MIRParser theparser(*themodule); + if (theparser.ParseMIR(0, 0, true, false)) { + DoIpaSideEffectAnalysis(themodule); + } else { + theparser.EmitError(themodule->fileName.c_str()); + return 1; + } + themodule->OutputAsciiMpl(".inline", ".mpl"); + mempoolctrler.DeleteMemPool(modulemp); + return 0; +} diff --git a/mapleall/maple_ir/include/all_attributes.def b/mapleall/maple_ir/include/all_attributes.def index 1f1edacd738f9d9bfb9fab03b87e59b026267b86..d0c1f5a43261dae0b27652241d03875e8ced1dbf 100644 --- a/mapleall/maple_ir/include/all_attributes.def +++ b/mapleall/maple_ir/include/all_attributes.def @@ -80,4 +80,5 @@ #endif #ifdef FUNC_ATTR ATTR(firstarg_return) + ATTR(jsarguments) #endif diff --git a/mapleall/maple_ir/include/js2mpl/jsintrinsic.def b/mapleall/maple_ir/include/js2mpl/jsintrinsic.def index 16a8b078ada6ee95d5ed74a31905952a0b933cb0..8b0bbbfcc04f05b6dff72763252daac4ae46a7d7 100644 --- a/mapleall/maple_ir/include/js2mpl/jsintrinsic.def +++ b/mapleall/maple_ir/include/js2mpl/jsintrinsic.def @@ -116,3 +116,5 @@ DEF_MIR_INTRINSIC(JSOP_MORE_ITERATOR,\ __jsop_more_iterator, INTRNISJS, kArgTyU32, kArgTyPtr, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) DEF_MIR_INTRINSIC(JS_ADDSYSEVENTLISTENER,\ __js_add_sysevent_listener, INTRNISJS, kArgTyU32, kArgTyDynany, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) +DEF_MIR_INTRINSIC(JSOP_INITPROP,\ + __jsop_initprop, INTRNISJS, kArgTyVoid, kArgTyDynany, kArgTyDynany, kArgTyDynany, kArgTyUndef, kArgTyUndef, kArgTyUndef) diff --git a/mapleall/maple_ir/src/mir_parser_expr.cpp b/mapleall/maple_ir/src/mir_parser_expr.cpp index df46f743b50a0231d883cfbfe931e6552caf21b1..55946719b1133eb3cc562f9e7a9a1a7f4d17327a 100644 --- a/mapleall/maple_ir/src/mir_parser_expr.cpp +++ b/mapleall/maple_ir/src/mir_parser_expr.cpp @@ -895,6 +895,9 @@ bool MIRParser::ParseExprExtractbits(BaseNode *&expr) { return false; } PrimType primType = GlobalTables::GetTypeTable().typeTable.at(tyIdx.GetIdx())->primType; + if(primType == PTY_dynany) { + primType = PTY_i32; + } if (!IsPrimitiveInteger(primType)) { Error("sematical error expect int type for extractbits"); return false; diff --git a/mapleall/maple_me/include/alias_class.h b/mapleall/maple_me/include/alias_class.h index 89f14d0005157cb62ca2b056a76b7066c2c01242..6c3a7142148b5a932b5a199e595afe12a745086e 100644 --- a/mapleall/maple_me/include/alias_class.h +++ b/mapleall/maple_me/include/alias_class.h @@ -168,6 +168,7 @@ class AliasClass : public AnalysisResult { void InsertMayDefUseIntrncall(StmtNode *stmt, BBId bbid); void InsertMayDefUseClinitCheck(IntrinsiccallNode *stmt, BBId bbid); virtual BB *GetBB(BBId id) = 0; + void ProcessAliasForJS(IntrinsiccallNode *); }; } // namespace maple #endif // end MAPLE_ME_INCLUDE_ALIASCLASS_H diff --git a/mapleall/maple_me/src/alias_class.cpp b/mapleall/maple_me/src/alias_class.cpp index 6edfdd707d9733cff5cc23b4d2f5ceb20ee75a6a..9521c2c201cadedb666ae5bc568aaf1fbd86c432 100644 --- a/mapleall/maple_me/src/alias_class.cpp +++ b/mapleall/maple_me/src/alias_class.cpp @@ -1551,6 +1551,29 @@ void AliasClass::InsertMayDefUseClinitCheck(IntrinsiccallNode *stmt, BBId bbid) return; } +void AliasClass::ProcessAliasForJS(IntrinsiccallNode *innode) { + if (innode->intrinsic == INTRN_JS_NEW_ARR_ELEMS) { + BaseNode *addrNode = innode->Opnd(0); + ASSERT(addrNode->op == OP_addrof, "the first op of INTRN_JS_NEW_ARR_ELEMS is supposed to be addrof"); + AliasInfo aInfo = CreateAliasElemsExpr(addrNode); + MayDefMayUsePart *theSSAPart = static_cast(ssaTab->stmtsSSAPart.SsapartOf(innode)); + std::set mayUseOsts; + for (OriginalSt *nextLevelOst : aInfo.ae->ost->nextlevelnodes) { + AliasElem *indAe = FindAliasElem(nextLevelOst); + if (!indAe->ost->isFinal || finalFieldAlias) { + if (indAe->classSet == nullptr) { + mayUseOsts.insert(indAe->ost); + } else { + for (uint elemId : *(indAe->classSet)) { + mayUseOsts.insert(id2Elem[elemId]->ost); + } + } + } + } + InsertMayUseNodeExcludeFinalOst(mayUseOsts, &(theSSAPart->mayUseNodes)); + } +} + void AliasClass::GenericInsertMayDefUse(StmtNode *stmt, BBId bbid) { switch (stmt->op) { case OP_return: { @@ -1609,12 +1632,18 @@ void AliasClass::GenericInsertMayDefUse(StmtNode *stmt, BBId bbid) { } case OP_intrinsiccall: case OP_xintrinsiccall: - case OP_intrinsiccallassigned: case OP_xintrinsiccallassigned: case OP_intrinsiccallwithtypeassigned: { InsertMayDefUseIntrncall(stmt, bbid); break; } + case OP_intrinsiccallassigned: { + if (mirModule->srcLang == kSrcLangJs) { + ProcessAliasForJS(static_cast(stmt)); + } + InsertMayDefUseIntrncall(stmt, bbid); + break; + } case OP_maydassign: case OP_dassign: { InsertMayUseExpr(stmt->Opnd(0)); diff --git a/mapleall/maple_me/src/me_cfg.cpp b/mapleall/maple_me/src/me_cfg.cpp index f707e165d9b5e8222c8108341aee24b8f3dbe14d..3277287894d0dff27ca04104761db3d4c5b62b49 100644 --- a/mapleall/maple_me/src/me_cfg.cpp +++ b/mapleall/maple_me/src/me_cfg.cpp @@ -219,30 +219,54 @@ void MirCFG::BuildMirCFG() { } } /* deal try blocks, add catch handler to try's succ */ - if (func->mirModule.IsJavaModule() && bb->isTry) { + if ((func->mirModule.IsJavaModule() || func->mirModule.IsJsModule()) && bb->isTry) { ASSERT((bbTryNodeMap.find(bb) != bbTryNodeMap.end()), "try bb without try"); StmtNode *stmt = bbTryNodeMap[bb]; - TryNode *trynode = static_cast(stmt); bool hasfinallyhandler = false; - /* add exception handler bb */ - for (uint32 i = 0; i < trynode->offsets.size(); i++) { - LabelIdx labelIdx = trynode->offsets[i]; - ASSERT(labelBBIdMap.find(labelIdx) != labelBBIdMap.end(), ""); - BB *meBb = labelBBIdMap[labelIdx]; - ASSERT(meBb != nullptr && meBb->IsCatch(), ""); - uint32 si = 0; - if (meBb->IsJavaFinally() || meBb->IsCatch()) { - hasfinallyhandler = true; + if (func->mirModule.IsJavaModule()) { + TryNode *trynode = static_cast(stmt); + /* add exception handler bb */ + for (uint32 i = 0; i < trynode->offsets.size(); i++) { + LabelIdx labelIdx = trynode->offsets[i]; + ASSERT(labelBBIdMap.find(labelIdx) != labelBBIdMap.end(), ""); + BB *meBb = labelBBIdMap[labelIdx]; + ASSERT(meBb != nullptr && meBb->IsCatch(), ""); + uint32 si = 0; + if (meBb->IsJavaFinally() || meBb->IsCatch()) { + hasfinallyhandler = true; + } + /* avoid redundant succ */ + for (; si < bb->succ.size(); si++) { + if (meBb == bb->succ[si]) { + break; + } + } + if (si == bb->succ.size()) { + bb->succ.push_back(meBb); + meBb->pred.push_back(bb); + } } - /* avoid redundant succ */ - for (; si < bb->succ.size(); si++) { - if (meBb == bb->succ[si]) { - break; + } else { + JsTryNode *tryNode = static_cast(stmt); + LabelIdx catchLbl = (LabelIdx)tryNode->catchOffset; + if (catchLbl != 0) { + ASSERT(labelBBIdMap.find(catchLbl) != labelBBIdMap.end(), ""); + BB *meBb = labelBBIdMap[catchLbl]; + ASSERT(meBb != nullptr && meBb->IsCatch(), ""); + uint32 si = 0; + for (; si < bb->succ.size(); si++) { + if (meBb == bb->succ[si]) { + break; + } + } + if (si == bb->succ.size()) { + bb->succ.push_back(meBb); + meBb->pred.push_back(bb); } } - if (si == bb->succ.size()) { - bb->succ.push_back(meBb); - meBb->pred.push_back(bb); + LabelIdx finalLbl = (LabelIdx)tryNode->finallyOffset; + if (finalLbl != 0) { + hasfinallyhandler = true; } } /* if try block don't have finally catch handler, add commonExitBB as its succ */ @@ -251,7 +275,7 @@ void MirCFG::BuildMirCFG() { bb->isExit = true; // may exit exitblocks.push_back(bb); } - } else if ((func->mirModule.IsJavaModule()) && bb->isExit) { + } else if (((func->mirModule.IsJavaModule()) || func->mirModule.IsJsModule()) && bb->isExit) { // deal with throw bb, if throw bb in a tryblock and has finallyhandler StmtNode *lastStmt = bb->stmtNodeList.last; if (lastStmt && lastStmt->op == OP_throw) { diff --git a/mapleall/maple_me/src/me_fsaa.cpp b/mapleall/maple_me/src/me_fsaa.cpp index de9f76e3bc0f89b259c0771bf5ea8be4af098505..57db94f784d3d6b5dc8c3a94e049aa276a112b3f 100644 --- a/mapleall/maple_me/src/me_fsaa.cpp +++ b/mapleall/maple_me/src/me_fsaa.cpp @@ -51,7 +51,7 @@ BB *FSAA::FindUniquePointerValueDefBB(VersionSt *vst) { } if (rhs->op == OP_malloc || rhs->op == OP_gcmalloc || rhs->op == OP_gcpermalloc || - rhs->op == OP_gcmallocjarray) { + rhs->op == OP_gcmallocjarray || rhs->op == OP_alloca) { return vst->defBB; } else if (rhs->op == OP_dread) { AddrofSSANode *dread = static_cast(rhs); diff --git a/mapleall/maple_me/src/me_function.cpp b/mapleall/maple_me/src/me_function.cpp index c47e8c25b0329e01d161eb95f5fe0885d0dfc801..ab8e0e3724a63e259da78f35a7191c7f51893798 100644 --- a/mapleall/maple_me/src/me_function.cpp +++ b/mapleall/maple_me/src/me_function.cpp @@ -26,6 +26,7 @@ #include "me_phase.h" #define JAVALANG (mirModule.IsJavaModule()) +#define JSLANG (mirModule.IsJsModule()) using namespace std; @@ -185,7 +186,7 @@ void MeFunction::CreateBasicBlocks(MirCFG *cfg) { curbb->kind = kBBGoto; if (nextstmt) { BB *newbb = NewBasicBlock(); - if (JAVALANG && !tryStmtStack.empty()) { + if ((JSLANG || JAVALANG) && !tryStmtStack.empty()) { SetTryBlockInfo(tryStmtStack.top(), tryBBStack.top(), nextstmt, curbb, newbb); } curbb = newbb; @@ -208,7 +209,7 @@ void MeFunction::CreateBasicBlocks(MirCFG *cfg) { curbb->SetFirst(stmt); } - if (JAVALANG && static_cast(stmt)->GetRhs()->MayThrowException()) { + if ((JAVALANG || JSLANG) && static_cast(stmt)->GetRhs()->MayThrowException()) { stmt->op = OP_maydassign; if (!tryStmtStack.empty()) { // breaks new BB only inside try blocks @@ -233,7 +234,7 @@ void MeFunction::CreateBasicBlocks(MirCFG *cfg) { curbb->SetLast(stmt); curbb->kind = kBBCondGoto; BB *newbb = NewBasicBlock(); - if (JAVALANG && !tryStmtStack.empty()) { + if ((JSLANG || JAVALANG) && !tryStmtStack.empty()) { SetTryBlockInfo(tryStmtStack.top(), tryBBStack.top(), nextstmt, curbb, newbb); } curbb = newbb; @@ -247,7 +248,7 @@ void MeFunction::CreateBasicBlocks(MirCFG *cfg) { break; } case OP_throw: - if (JAVALANG && !tryStmtStack.empty()) { + if ((JAVALANG || JSLANG) && !tryStmtStack.empty()) { // handle as goto if (curbb->IsEmpty()) { curbb->SetFirst(stmt); @@ -309,6 +310,7 @@ void MeFunction::CreateBasicBlocks(MirCFG *cfg) { tryBBStack.pop(); break; } + case OP_jstry: case OP_cpptry: case OP_try: case OP_javatry: { @@ -329,7 +331,7 @@ void MeFunction::CreateBasicBlocks(MirCFG *cfg) { tryStmtStack.push(stmt); tryBBStack.push(curbb); curbb->isTry = true; - if (JAVALANG) { + if (JAVALANG || JSLANG) { cfg->bbTryNodeMap[curbb] = tryStmtStack.top(); // prepare a new bb that contains only a OP_javatry. It is needed // to work correctly: assignments in a try block should not affect @@ -361,6 +363,7 @@ void MeFunction::CreateBasicBlocks(MirCFG *cfg) { curbb->isEntry = true; break; } + case OP_jscatch: case OP_catch: case OP_javacatch: { // start a new bb @@ -381,21 +384,23 @@ void MeFunction::CreateBasicBlocks(MirCFG *cfg) { } curbb->SetFirst(stmt); curbb->isCatch = true; - CatchNode *catchnode = static_cast(stmt); - // ASSERT(catchnode->exceptionTyIdxVec.size() == 1, "TODO: handle exceptionTyIdxVec"); - const MapleVector &exceptiontyidxvec = catchnode->exceptionTyIdxVec; - for (uint32 i = 0; i < exceptiontyidxvec.size(); i++) { - MIRType *etype = GlobalTables::GetTypeTable().GetTypeFromTyIdx(exceptiontyidxvec[i]); - ASSERT( - etype != nullptr && (etype->GetPrimType() == maple::PTY_ptr || etype->GetPrimType() == maple::PTY_ref), ""); - MIRPtrType *eptype = static_cast(etype); - MIRType *pointtype = GlobalTables::GetTypeTable().GetTypeFromTyIdx(eptype->pointedTyIdx); - const std::string &ename = GlobalTables::GetStrTable().GetStringFromStrIdx(pointtype->nameStrIdx); - if ((pointtype->primType == maple::PTY_void) || (ename.compare("Ljava/lang/Throwable;") == 0) || - (ename.compare("Ljava/lang/Exception;") == 0)) { - // "Ljava/lang/Exception;" is risk to set isJavaFinally because it - // only deal with "throw exception". if throw error, it's wrong - curbb->isJavaFinally = true; // this is a start of finally handler + if (!JSLANG) { + CatchNode *catchnode = static_cast(stmt); + // ASSERT(catchnode->exceptionTyIdxVec.size() == 1, "TODO: handle exceptionTyIdxVec"); + const MapleVector &exceptiontyidxvec = catchnode->exceptionTyIdxVec; + for (uint32 i = 0; i < exceptiontyidxvec.size(); i++) { + MIRType *etype = GlobalTables::GetTypeTable().GetTypeFromTyIdx(exceptiontyidxvec[i]); + ASSERT( + etype != nullptr && (etype->GetPrimType() == maple::PTY_ptr || etype->GetPrimType() == maple::PTY_ref), ""); + MIRPtrType *eptype = static_cast(etype); + MIRType *pointtype = GlobalTables::GetTypeTable().GetTypeFromTyIdx(eptype->pointedTyIdx); + const std::string &ename = GlobalTables::GetStrTable().GetStringFromStrIdx(pointtype->nameStrIdx); + if ((pointtype->primType == maple::PTY_void) || (ename.compare("Ljava/lang/Throwable;") == 0) || + (ename.compare("Ljava/lang/Exception;") == 0)) { + // "Ljava/lang/Exception;" is risk to set isJavaFinally because it + // only deal with "throw exception". if throw error, it's wrong + curbb->isJavaFinally = true; // this is a start of finally handler + } } } break; @@ -409,7 +414,7 @@ void MeFunction::CreateBasicBlocks(MirCFG *cfg) { StmtNode *curLast = curbb->stmtNodeList.last; CHECK_FATAL((curLast == nullptr || curLast == laststmt), "something wrong building BB"); if ((curLast == nullptr) && (laststmt->op != OP_label)) { - if (mirModule.IsJavaModule() && laststmt->op == OP_endtry) { + if ((JAVALANG || JSLANG) && laststmt->op == OP_endtry) { if (curbb->stmtNodeList.first == nullptr) { curbb->SetLast(nullptr); } else { @@ -428,7 +433,7 @@ void MeFunction::CreateBasicBlocks(MirCFG *cfg) { BB *newbb = NewBasicBlock(); if (!tryStmtStack.empty()) { newbb->isTry = true; - if (JAVALANG) { + if (JAVALANG || JSLANG) { cfg->bbTryNodeMap[newbb] = tryStmtStack.top(); } } @@ -448,14 +453,6 @@ void MeFunction::CreateBasicBlocks(MirCFG *cfg) { curbb->bbLabel = labidx; break; } - case OP_jscatch: { - if (curbb->IsEmpty()) { - curbb->SetFirst(stmt); - } - curbb->isEntry = true; - curbb->isJSCatch = true; - break; - } case OP_finally: { CHECK_FATAL(curbb->IsEmpty(), ""); curbb->SetFirst(stmt); diff --git a/mapleall/maple_me/src/me_phase_manager.cpp b/mapleall/maple_me/src/me_phase_manager.cpp index cd7010fe1bedce9019d96f9c8712957004fc54fc..27a514ff4a465723c5b9d8dfd9bda0ce13f9ca9d 100644 --- a/mapleall/maple_me/src/me_phase_manager.cpp +++ b/mapleall/maple_me/src/me_phase_manager.cpp @@ -147,6 +147,18 @@ void MeFuncPhaseManager::AddPhases(const std::unordered_set &skipPh bool o2 = MeOption::optLevel >= 2; bool o3 = MeOption::optLevel >= 3; + if (module.IsJsModule()) { + addPhase("cfgbuild"); + addPhase("ssatab"); + addPhase("aliasclass"); + addPhase("ssa"); + addPhase("dse"); + addPhase("irmapbuild"); + addPhase("hprop"); + addPhase("hdse"); + addPhase("emit"); + return; + } /* default phase sequence */ if (o3) { addPhase("cfgbuild"); diff --git a/tools/setup_tools.sh b/tools/setup_tools.sh index 47e491744792966b2b69948b881bc28079b46234..e2141ce50f29a77936d5702fc0c105901bc0387e 100755 --- a/tools/setup_tools.sh +++ b/tools/setup_tools.sh @@ -16,45 +16,47 @@ set -e -if [ ! -f ../bin/ast2mpl ]; then - cd ../bin/ast2mpl_files +TOOLS=`pwd` +echo TOOLS=$TOOLS + +if [ ! -f $TOOLS/../bin/ast2mpl ]; then + cd $TOOLS/../bin/ast2mpl_files cat ast2mpl_aa ast2mpl_ab ast2mpl_ac ast2mpl_ad > ast2mpl.gz gunzip ast2mpl.gz chmod 775 ast2mpl mv ast2mpl .. - cd ../../tools echo Merged ast2mpl. fi -if [ ! -f ./ninja/ninja ]; then - mkdir -p ./ninja - cd ./ninja || exit 3 +if [ ! -f $TOOLS/ninja/ninja ]; then + mkdir -p $TOOLS/ninja + cd $TOOLS/ninja || exit 3 wget https://github.com/ninja-build/ninja/releases/download/v1.10.0/ninja-linux.zip unzip ninja-linux.zip - cd .. echo Downloaded ninja. fi -if [ ! -f ./gn/gn ]; then +if [ ! -f $TOOLS/gn/gn ]; then + cd $TOOLS git clone https://gitee.com/xlnb/gn_binary.git gn chmod +x gn/gn echo Downloaded gn. fi -if [ ! -f ./open64_prebuilt/README.md ]; then - git clone https://gitee.com/open64ark/open64_prebuilt.git +if [ ! -f $TOOLS/open64_prebuilt/README.md ]; then + cd $TOOLS + git clone --depth 1 https://gitee.com/open64ark/open64_prebuilt.git -b mapleall fi -if [ ! -f ./open64_prebuilt/x86/riscv64/bin/clangfe ]; then - cd ./open64_prebuilt/x86 - git pull +if [ ! -f $TOOLS/open64_prebuilt/x86/riscv64/bin/clangfe ]; then + cd $TOOLS/open64_prebuilt/x86 tar zxf open64ark-aarch64.tar.gz tar zxf open64ark-riscv.tar.gz mv riscv riscv64 - cd ../.. echo Downloaded open64_prebuilt. fi -if [ ! -f ./dwarf/include/dwarf2.h ]; then +if [ ! -f $TOOLS/dwarf/include/dwarf2.h ]; then + cd $TOOLS git clone https://gitee.com/hu-_-wen/dwarf_files.git dwarf echo Downloaded dwarf header files. fi