diff --git a/BUILD.gn b/BUILD.gn index e35c304bf09575c1743a64166a5ae68588a02c9a..fca908c868b08738a836d47a064c648a674cdd50 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -18,3 +18,12 @@ group("mapleall") { "${MAPLEALL_ROOT}:mapleall" ] } + +group("js2mpl") { + deps = [] + if(IS_JS2MPL_EXISTS == "1"){ + deps = [ + "${JS2MPL_ROOT}:js2mpl" + ] + } +} diff --git a/Makefile b/Makefile index f944bdf813955b85b961f089ef5ac0374dce7008..ba140ce914dd9b4bdb1f30a3a99f5c3cb2986c6b 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,7 @@ BUILD_TYPE := RELEASE HOST_ARCH := 64 MIR_JAVA := 1 GN := ${MAPLE_ROOT}/tools/gn/gn -NINJA := ${MAPLE_ROOT}/tools/ninja_1.9.0/ninja +NINJA := ${MAPLE_ROOT}/tools/ninja/ninja USE_CLANG_OP := 1 HOST_ARCH_OP := 64 @@ -28,7 +28,7 @@ USE_ZRT := 0 DEFERRAL_RC := OFF STRICT_NAIVE_RC := OFF RC_TESTING := OFF -USE_MALLOC := +USE_MALLOC := COV_CHECK := 0 ifeq ($(TARGET_PROCESSOR), aarch64) @@ -71,6 +71,14 @@ default: mapleall mapleall: $(call build_gn, ${GN_OPTIONS}, irbuild maple mplcg) +.PHONY: js2mpl +js2mpl: + $(call build_gn, ${GN_OPTIONS}, js2mpl) + +.PHONY: mplbe +mplbe: + $(call build_gn, ${GN_OPTIONS}, mplbe) + .PHONY: install install: mapleall $(shell mkdir -p ${MAPLE_ROOT}/bin; \ diff --git a/README.md b/README.md index 4f0fea8929cc4a81c799c74aad1a70ca8f06b9ab..d05b41f0959624d718141441959460cb9231c028 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,10 @@ The directory structure as follows: out : created during make ``` +### Branches +1. master branch: for stable versions +2. dev branch: for daily development + ### Set up tools 1. `cd $MAPLE_ROOT` 2. `cd tools` diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn index bbed5bee8dbbf44785f2414eb94f57525d299082..a53f63197833169acda79c04a91a8c39e039db66 100644 --- a/build/config/BUILDCONFIG.gn +++ b/build/config/BUILDCONFIG.gn @@ -17,6 +17,8 @@ # declare here will be implicitly global. # List all the input args + +# Define global args declare_args() { GN_INSTALL_PREFIX = "" GN_BUILD_TYPE = "" @@ -36,9 +38,14 @@ declare_args() { TARGET = "" USE_OJ_LIBCORE = 0 } - -# Define global args MAPLE_ROOT = getenv("MAPLE_ROOT") +IS_JS2MPL_EXISTS = getenv("IS_JS2MPL_EXISTS") +if (IS_JS2MPL_EXISTS == "1") { + HOST_ARCH = 32 + JAVA = 0 + TARGET = "vm" + JAVA_OP = 0 +} DYNAMICLANG = true RC_V2 = true if (X86_ARK == 1) { @@ -66,6 +73,7 @@ MAPLEALL_ROOT = "${MAPLE_ROOT}/mapleall" MAPLE_RE_ROOT = "${MAPLE_ROOT}/maple_engine" HUAWEI_SECURE_C_ROOT = "${MAPLE_ROOT}/huawei_secure_c" DWARF_ROOT = "${MAPLE_ROOT}/tools/dwarf" +JS2MPL_ROOT = "${MAPLE_ROOT}/js2mpl" # Toolchain setup if (USE_CLANG == 1) { diff --git a/examples/C/maple_riscv_with_whirl2mpl.sh b/examples/C/maple_riscv_with_whirl2mpl.sh index a4bc859fed9dd5b00e346524b5b7bbdc45a345fc..8c07645646ee996a211c9109a6d27e8841f905a2 100755 --- a/examples/C/maple_riscv_with_whirl2mpl.sh +++ b/examples/C/maple_riscv_with_whirl2mpl.sh @@ -38,7 +38,7 @@ $MAPLE_ROOT/tools/open64_prebuilt/x86/riscv64/bin/clangfe $FLAGS $name.c > doit. echo $MAPLE_ROOT/tools/open64_prebuilt/x86/riscv64/bin/whirl2mpl $name.B $MAPLE_ROOT/tools/open64_prebuilt/x86/riscv64/bin/whirl2mpl $name.B >> doit.log 2>&1 -echo $MAPLE_ROOT/bin/riscv64-clang-release/maple -exe=me,mplcg -option="-O2 --quiet:-O2 -quiet" $name.bpl +echo $MAPLE_ROOT/bin/riscv64-clang-release/maple -exe=me,mplcg -option=\"-O2 --quiet:-O2 -quiet\" $name.bpl $MAPLE_ROOT/bin/riscv64-clang-release/maple -exe=me,mplcg -option="-O2 --quiet:-O2 -quiet" $name.bpl >> doit.log 2>&1 echo /usr/riscv64-linux-gnu/bin/riscv64-unknown-linux-gnu-gcc -o $name.out $name.s diff --git a/maple_engine/include/mre_opcodes.def b/maple_engine/include/mre_opcodes.def index ea5bae16f5f039fb3485baa75a2d854750f92d38..804fc5711e15d1bc9f801b8abef614175b0cea26 100644 --- a/maple_engine/include/mre_opcodes.def +++ b/maple_engine/include/mre_opcodes.def @@ -22,3 +22,6 @@ OPCODE(brtrue32, none, none, none) OPCODE(brfalse32, none, none, none) OPCODE(goto32, none, none, none) + OPCODE(ireadfpoff32, none, none, none) + OPCODE(iassignfpoff32, none, none, none) + diff --git a/mapleall/BUILD.gn b/mapleall/BUILD.gn index 1f16e2ef9f323c7d09f81a1b7d2ed65c85d3c2e5..476fecc7e6166f3b9b31f8dc9772b2342630a07e 100644 --- a/mapleall/BUILD.gn +++ b/mapleall/BUILD.gn @@ -57,10 +57,10 @@ config("mapleallcompilecfg"){ if(HOST_ARCH == 32){ libs = [ - "-lz", - "-lpthread", - "-ldl", - "-lelf", + "z", + "pthread", + "dl", + "elf", ] ldflags = [] diff --git a/mapleall/maple_be/include/be/be_common.h b/mapleall/maple_be/include/be/be_common.h index 2fdb4cc6e81fb6239aa40535c68e180ad415f8c1..927c5384782d4cba0feacd807f5144d7e2dfda43 100644 --- a/mapleall/maple_be/include/be/be_common.h +++ b/mapleall/maple_be/include/be/be_common.h @@ -31,10 +31,10 @@ namespace maplebe { -#if TARGX86_64 || TARGAARCH64 || TARGARK || TARGRISCV64 +#if TARGX86_64 || TARGAARCH64 || TARGARK || TARGRISCV64 || TARGVM #define LOWERED_PTR_TYPE PTY_a64 #define SIZEOFPTR 8 -#elif TARGX86 || TARGARM || TARGVM +#elif TARGX86 || TARGARM #define LOWERED_PTR_TYPE PTY_a32 #define SIZEOFPTR 4 #else diff --git a/mapleall/maple_be/include/be/be_lowerer.h b/mapleall/maple_be/include/be/be_lowerer.h index 7b81689342988732a6f7476f309f834f71c8f0cd..23096da23ca7759d1a9e3259558a56b24391ddf2 100644 --- a/mapleall/maple_be/include/be/be_lowerer.h +++ b/mapleall/maple_be/include/be/be_lowerer.h @@ -141,8 +141,8 @@ class BELowerer { } DassignNode *SaveReturnValueInLocal(StIdx, uint16); - void LowerCallStmt(StmtNode *, StmtNode *&, BlockNode *, MIRType *retty = nullptr); - BlockNode *LowerCallAssignedStmt(StmtNode *); + void LowerCallStmt(StmtNode *, StmtNode *&, BlockNode *, MIRType *retty = nullptr, bool uselvar = false); + BlockNode *LowerCallAssignedStmt(StmtNode *, bool uselvar = false); BaseNode *LowerRem(BaseNode *rem, BlockNode *); BlockNode *LowerJavaThrow(UnaryStmtNode *); BaseNode *LowerJavaDiv(BaseNode *, BinaryNode *, BlockNode *); @@ -224,7 +224,7 @@ class BELowerer { return kfuncNotFound; } - StmtNode *LowerCall(CallNode *, StmtNode *&, BlockNode *, MIRType *retty = nullptr);; + StmtNode *LowerCall(CallNode *, StmtNode *&, BlockNode *, MIRType *retty = nullptr, bool uselvar = false); void CleanupBranches(MIRFunction *func); diff --git a/mapleall/maple_be/include/cg/aarch64/README b/mapleall/maple_be/include/cg/aarch64/README deleted file mode 100644 index 49adeb02fb37663b2c1b706d2e2a8f5d93434afd..0000000000000000000000000000000000000000 --- a/mapleall/maple_be/include/cg/aarch64/README +++ /dev/null @@ -1,16 +0,0 @@ -# -# Copyright (c) [2020] Huawei Technologies Co., Ltd. All rights reserved. -# -# 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. -# - -To add or modify a MOP, you need to change aarch64_isa.def.h, and then run "perl gen_mop.pl" to generate aarch64isa.def. You should NOT modify aarch64isa.def manually. diff --git a/mapleall/maple_be/include/cg/aarch64/aarch64_cg_func.h b/mapleall/maple_be/include/cg/aarch64/aarch64_cg_func.h index 70a50152c640ba12ac8878b47377f9455e9f1480..4c21a12f939ca6f5fb99b0486588d4d4663d388d 100644 --- a/mapleall/maple_be/include/cg/aarch64/aarch64_cg_func.h +++ b/mapleall/maple_be/include/cg/aarch64/aarch64_cg_func.h @@ -100,6 +100,7 @@ class AArch64CGFunc : public CGFunc { MapleSet gen_memopnds_requiring_offset_adjustment_; unsigned int refCount; // Ref count number. 0 if function don't have "bl MCC_InitializeLocalStackRef" int beginOffset; // Begin offset based x29. + regno_t retRegType; // scalar return register type Insn *yieldPointInsn; // The insn of yield point at the entry of the func. static const uint32 kParmMemcpySize = 40; @@ -191,6 +192,7 @@ class AArch64CGFunc : public CGFunc { gen_memopnds_requiring_offset_adjustment_(mallocator->Adapter()), refCount(0), beginOffset(0), + retRegType(kRegTyUndef), yieldPointInsn(nullptr) { ujavaCatch.regno_javaCatch = 0; current_cfa_ = 0; diff --git a/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h b/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h index 7907bc84fa71ce31f1625b331046d1d38fc02c35..a7f7da9a7cc8ae9b3e393076b3e654c99e8d4eaa 100644 --- a/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h +++ b/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h @@ -649,6 +649,7 @@ class GraphColorRegAllocator : public RegAllocator { spillMemopnd0(nullptr), spillMemopnd1(nullptr), spillMemopnd2(nullptr), + doMultiPass(false), #ifdef USE_LRA doLRA(true), #else @@ -741,6 +742,7 @@ class GraphColorRegAllocator : public RegAllocator { regno_t intSpillFillRegs[3]; regno_t fpSpillFillRegs[3]; + bool doMultiPass; bool doLRA; bool doOptProlog; bool hasSpill; diff --git a/mapleall/maple_be/include/cg/aarch64/aarch64_insn.h b/mapleall/maple_be/include/cg/aarch64/aarch64_insn.h index 3340454cf9abcc7bb5ba4b432788aacb36d5beea..1b2135e95b493d00690edf84a4f986e403cc526a 100644 --- a/mapleall/maple_be/include/cg/aarch64/aarch64_insn.h +++ b/mapleall/maple_be/include/cg/aarch64/aarch64_insn.h @@ -141,6 +141,8 @@ class AArch64Insn : public Insn { bool IsDestRegAlsoSrcReg() const override; + bool IsUncondBranch() const override; + bool IsDataMoveInstruction() const override; bool IsConversionInstruction() const override; diff --git a/mapleall/maple_be/include/cg/aarch64/aarch64_md.def b/mapleall/maple_be/include/cg/aarch64/aarch64_md.def index 361bd1859feecee75c493da5ab4ddba5a369aa57..8c4b1a2784b089437aff851c938bc31780da2f0b 100644 --- a/mapleall/maple_be/include/cg/aarch64/aarch64_md.def +++ b/mapleall/maple_be/include/cg/aarch64/aarch64_md.def @@ -612,7 +612,7 @@ DEFINE_MOP(MOP_xcmnrr, {MOPD_RegCCD, MOPD_Reg64IS,MOPD_Reg64IS,MOPD_Undef,MOPD_U // AArch64 branches // MOP_xbr -- branch to register -DEFINE_MOP(MOP_xbr, {MOPD_Reg64IS,MOPD_Undef,MOPD_Undef,MOPD_Undef,MOPD_Undef},ISBRANCH,kLtBranch,"br","0", 0, 1) +DEFINE_MOP(MOP_xbr, {MOPD_Reg64IS,MOPD_Literal,MOPD_Undef,MOPD_Undef,MOPD_Undef},ISBRANCH,kLtBranch,"br","0", 0, 1) // MOP_Tbbuncond DEFINE_MOP(MOP_xuncond, {MOPD_Label,MOPD_Undef,MOPD_Undef,MOPD_Undef,MOPD_Undef},ISBRANCH,kLtBranch,"b","0", 0, 1) 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 d07de81f69c341e2e37000a2539c8c52a6e80ceb..4cf4445356f803f8f0d08c352c022e6a5c443b54 100644 --- a/mapleall/maple_be/include/cg/ark/ark_mir_emit.h +++ b/mapleall/maple_be/include/cg/ark/ark_mir_emit.h @@ -353,7 +353,8 @@ class MirGenerator : public CmplGenerator { void EmitAsmCall(CallNode *fstmt); void EmitAsmComment(CommentNode *comment); void EmitBytes(uint8 *b, int count); - void EmitBytesComment(uint8 *b, int count, string &comment); + void EmitBytesComment(uint8 *b, int count, const string &comment); + void EmitBytesCommentOffset(uint8 *b, int count, const string &comment, int offset); void EmitAsmShort(uint16 s); void EmitAsmWord(uint32 word); void EmitAsmWord(uint32 word, string comment); @@ -370,6 +371,9 @@ class MirGenerator : public CmplGenerator { void EmitString(const std::string &str, int bytes); void EmitStringNoTab(const std::string &str, int bytes); void EmitYieldPoint(void); + void EmitModuleInfo(void); + void EmitGlobalDecl(void); + void EmitOpCodes(void); void CheckYieldPointInsert(StmtNode *fstmt); int GetFormalsInfo(MIRFunction *func); int GetLocalsInfo(MIRFunction *func); @@ -377,6 +381,7 @@ class MirGenerator : public CmplGenerator { uint32 GetFieldOffsetType(TyIdx tyidx, FieldID fieldid, MIRType *&); RE_Opcode MapEHOpcode(RE_Opcode op); void CheckInsertOpCvt(Opcode expr, PrimType exprType, PrimType insnType); + std::string BuildLabelString(LabelIdx lbidx); int GetFuncOffset(void) { return funcOffset; diff --git a/mapleall/maple_be/include/cg/cfi.h b/mapleall/maple_be/include/cg/cfi.h index f16b198dd6ed7bfb68b1536c322f7c491edee202..1343012f66e1d331ea32b189a6683426a2b14d9b 100644 --- a/mapleall/maple_be/include/cg/cfi.h +++ b/mapleall/maple_be/include/cg/cfi.h @@ -101,6 +101,10 @@ class CfiInsn : public maplebe::Insn { return false; } + bool IsUncondBranch() const override { + return false; + } + bool IsDataMoveInstruction() const override { return false; } diff --git a/mapleall/maple_be/include/cg/cg.h b/mapleall/maple_be/include/cg/cg.h index 95804c3af83d245a0441353c285bf103268af3b7..63288b156fc3ddb648aff48768aff2dd4f01e774 100644 --- a/mapleall/maple_be/include/cg/cg.h +++ b/mapleall/maple_be/include/cg/cg.h @@ -84,6 +84,7 @@ class CG { MIRSymbol *dbg_trace_enter_; MIRSymbol *dbg_trace_exit_; MIRSymbol *dbg_func_profile_; + static std::map> funcWrapLabels; public: explicit CG(MIRModule *mod, const CGOptions &cgopt, bool runCg, const char *output) diff --git a/mapleall/maple_be/include/cg/dbg.h b/mapleall/maple_be/include/cg/dbg.h index c9aa3a2da2dcbe28b822c1908e30436aa547ac63..d59d44b24830dce07b840a5740fc5b9d4daf2085 100644 --- a/mapleall/maple_be/include/cg/dbg.h +++ b/mapleall/maple_be/include/cg/dbg.h @@ -92,6 +92,10 @@ class DbgInsn : public maplebe::Insn { return false; } + bool IsUncondBranch() const override { + return false; + } + bool IsDataMoveInstruction() const override { return false; } diff --git a/mapleall/maple_be/include/cg/emit.h b/mapleall/maple_be/include/cg/emit.h index 7238b0bd2edd07e2498d33f849149311db4c776f..d2c402bc5bcb0971fa72af3b88fae300ef123daf 100644 --- a/mapleall/maple_be/include/cg/emit.h +++ b/mapleall/maple_be/include/cg/emit.h @@ -86,6 +86,7 @@ class Emitter { private: MOperator curr_mop; MapleMap labdie2labidx_table; + MapleMap fileMap; vector stringPtr; @@ -95,7 +96,8 @@ class Emitter { arraySize(0), isFlexibleArray(false), curr_mop(UINT_MAX), - labdie2labidx_table(std::less(), cg->mirModule->memPoolAllocator.Adapter()) { + labdie2labidx_table(std::less(), cg->mirModule->memPoolAllocator.Adapter()), + fileMap(std::less(), cg->mirModule->memPoolAllocator.Adapter()) { out.open(asmFileName.c_str(), std::ios::trunc); MIRModule &mirModule = *cg_->mirModule; asminfo_ = mirModule.memPool->New(0, mirModule.memPool); @@ -195,6 +197,7 @@ class Emitter { void EmitStmtLabel(const char *, LabelIdx); void EmitBBHeaderLabel(const char *, const char *, LabelIdx, CGFunc &); void EmitLabelPair(const char *, const LabelPair &); + void EmitLabelForFunc(MIRFunction *, LabelIdx); // Emit alignment directive (".align") // diff --git a/mapleall/maple_be/include/cg/insn.h b/mapleall/maple_be/include/cg/insn.h index 2009f5a5e8b8fbf494619604dcfa3796b3482bf0..a69b7d8fa7febd53b9a2708a267465f3db17f998 100644 --- a/mapleall/maple_be/include/cg/insn.h +++ b/mapleall/maple_be/include/cg/insn.h @@ -606,6 +606,8 @@ class Insn { return false; } + virtual bool IsUncondBranch() const = 0; + virtual bool IsDataMoveInstruction() const = 0; virtual bool IsConversionInstruction() const = 0; diff --git a/mapleall/maple_be/include/cg/riscv64/README b/mapleall/maple_be/include/cg/riscv64/README deleted file mode 100644 index 0bf11923b49bd69d698a4c070140410c1548972d..0000000000000000000000000000000000000000 --- a/mapleall/maple_be/include/cg/riscv64/README +++ /dev/null @@ -1,16 +0,0 @@ -# -# Copyright (c) [2020] Huawei Technologies Co.,Ltd.All rights reserved. -# -# OpenArkCompiler is licensed under the Mulan PSL v1. -# You can use this software according to the terms and conditions of the Mulan PSL v1. -# You may obtain a copy of Mulan PSL v1 at: -# -# http://license.coscl.org.cn/MulanPSL -# -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR -# FIT FOR A PARTICULAR PURPOSE. -# See the Mulan PSL v1 for more details. -# - -To add or modify a MOP, you need to change riscv64_isa.def.h, and then run "perl gen_mop.pl" to generate riscv64isa.def. You should NOT modify riscv64isa.def manually. diff --git a/mapleall/maple_be/include/cg/riscv64/riscv64_abi.h b/mapleall/maple_be/include/cg/riscv64/riscv64_abi.h index a087fdcc7c73a31e98d31efb008516bd11b5a545..2396d74bcd1067993963bf6bd08ced152d6d1c91 100644 --- a/mapleall/maple_be/include/cg/riscv64/riscv64_abi.h +++ b/mapleall/maple_be/include/cg/riscv64/riscv64_abi.h @@ -102,6 +102,7 @@ class ParmLocator { virtual ~ParmLocator() {} // Return size of aggregate structure copy on stack. + void LocateCallNodeParm(MIRType *ty, PLocInfo &ploc, uint32 retSize, bool isFirst, bool isvararg); int32 LocateNextParm(MIRType *ty, PLocInfo &ploc, bool isFirst = false, bool isvararg = false); int32 LocateRetValue(MIRType *ty, PLocInfo &ploc); void InitPlocInfo(PLocInfo &ploc); diff --git a/mapleall/maple_be/include/cg/riscv64/riscv64_cg_func.h b/mapleall/maple_be/include/cg/riscv64/riscv64_cg_func.h index 7371b48552b1045f99aa7448ca5f09f9afde3b5d..6594467595db716368436b1bd4130efd886f0bfe 100644 --- a/mapleall/maple_be/include/cg/riscv64/riscv64_cg_func.h +++ b/mapleall/maple_be/include/cg/riscv64/riscv64_cg_func.h @@ -98,6 +98,7 @@ class Riscv64CGFunc : public CGFunc { // some caller-saved registers. unsigned int refCount; // Ref count number. 0 if function don't have "bl MCC_InitializeLocalStackRef" int beginOffset; // Begin offset based x29. + regno_t retRegType; // scalar return register type Insn *yieldPointInsn; // The insn of yield point at the entry of the func. static const uint32 kParmMemcpySize = 40; @@ -190,6 +191,7 @@ class Riscv64CGFunc : public CGFunc { gen_memopnds_requiring_offset_adjustment_(mallocator->Adapter()), refCount(0), beginOffset(0), + retRegType(kRegTyUndef), yieldPointInsn(nullptr) { ujavaCatch.regno_javaCatch = 0; current_cfa_ = 0; @@ -674,6 +676,8 @@ class Riscv64CGFunc : public CGFunc { void GeneratePopRegs(); + Operand *FixLargeStackOffset(ImmOperand *iopnd); + Riscv64MemOperand *CreateStkTopOpnd(int32 offset, int32 size); // if offset < 0, allocation; otherwise, deallocation @@ -818,7 +822,7 @@ class Riscv64CGFunc : public CGFunc { MemOperand *LoadStructCopyBase(MIRSymbol *symbol, int32 offset, int datasize) override; - void ReplaceLargeStackOffsetImm(Insn *insn); + bool ReplaceLargeStackOffsetImm(Insn *insn); }; } // namespace maplebe diff --git a/mapleall/maple_be/include/cg/riscv64/riscv64_color_ra.h b/mapleall/maple_be/include/cg/riscv64/riscv64_color_ra.h index 4b79f20d2ccd47493b1bda5b8e4ea78db7c24397..da0a9ce3bc0bd54b66d0fadf910891a1ebc71924 100644 --- a/mapleall/maple_be/include/cg/riscv64/riscv64_color_ra.h +++ b/mapleall/maple_be/include/cg/riscv64/riscv64_color_ra.h @@ -654,6 +654,7 @@ class GraphColorRegAllocator : public RegAllocator { spillMemopnd0(nullptr), spillMemopnd1(nullptr), spillMemopnd2(nullptr), + doMultiPass(false), #ifdef USE_LRA doLRA(true), #else @@ -743,6 +744,7 @@ class GraphColorRegAllocator : public RegAllocator { regno_t intSpillFillRegs[3]; regno_t fpSpillFillRegs[3]; + bool doMultiPass; bool doLRA; bool doOptProlog; bool hasSpill; @@ -812,7 +814,7 @@ class GraphColorRegAllocator : public RegAllocator { MemOperand *GetConsistentReuseMem(uint32 vregno, uint32 size, RegType regtype); MemOperand *GetCommonReuseMem(uint32 vregno, uint32 size, RegType regtype); MemOperand *GetReuseMem(uint32 vregno, uint32 size, RegType regtype); - MemOperand *GetSpillMem(uint32 vregno, Insn *insn, Riscv64reg_t regno, uint8 &isOutOfRange); + MemOperand *GetSpillMem(uint32 vregno, Insn *insn, Riscv64reg_t regno, uint8 &isOutOfRange, bool isDef); bool GetAvailableSpillReg(set &cannotUseReg, LiveRange *lr, uint64 &usedRegMask); void CollectCannotUseReg(set &cannotUseReg, LiveRange *lr, Insn *insn); bool PickRegForSpill(LiveRange *lr, Insn *insn, uint64 &usedRegMask, bool isDef); diff --git a/mapleall/maple_be/include/cg/riscv64/riscv64_insn.h b/mapleall/maple_be/include/cg/riscv64/riscv64_insn.h index 7f83fa7223e95cec7ec01e85fbb0a11da2457a39..6b413e662207cc147c014d9de5f5374a9e87312f 100644 --- a/mapleall/maple_be/include/cg/riscv64/riscv64_insn.h +++ b/mapleall/maple_be/include/cg/riscv64/riscv64_insn.h @@ -141,6 +141,8 @@ class Riscv64Insn : public Insn { bool IsDestRegAlsoSrcReg() const override; + bool IsUncondBranch() const override; + bool IsDataMoveInstruction() const override; bool IsConversionInstruction() const override; diff --git a/mapleall/maple_be/include/cg/riscv64/riscv64_md.def b/mapleall/maple_be/include/cg/riscv64/riscv64_md.def index 8a22639632d707770f2a0c9d8010387378eccb75..ec0a63aac23c0c7386b7cddf1b545e993f33a49c 100644 --- a/mapleall/maple_be/include/cg/riscv64/riscv64_md.def +++ b/mapleall/maple_be/include/cg/riscv64/riscv64_md.def @@ -37,7 +37,7 @@ DEFINE_MOP(MOP_xmov52up, {MOPD_Reg64ID,MOPD_Imm64,MOPD_Undef,MOPD_Undef,MOPD_Und // MOP_xvmovsr -DEFINE_MOP(MOP_xvmovsr, {MOPD_Reg32FD,MOPD_Reg32IS,MOPD_Undef,MOPD_Undef,MOPD_Undef},ISMOVE,kLtR2f,"fmv.s.w","0,1", 1, 1) +DEFINE_MOP(MOP_xvmovsr, {MOPD_Reg32FD,MOPD_Reg32IS,MOPD_Undef,MOPD_Undef,MOPD_Undef},ISMOVE,kLtR2f,"fmv.s.x","0,1", 1, 1) // MOP_xvmovdr DEFINE_MOP(MOP_xvmovdr, {MOPD_Reg64FD,MOPD_Reg64IS,MOPD_Undef,MOPD_Undef,MOPD_Undef},ISMOVE,kLtR2f,"fmv.d.x","0,1", 1, 1) // MOP_xvmovrs @@ -402,7 +402,7 @@ DEFINE_MOP(MOP_xcmprr, {MOPD_Reg64IS,MOPD_Reg64IS,MOPD_Undef,MOPD_Undef,MOPD_Und // Riscv64 branches // MOP_xbr -- branch to register -DEFINE_MOP(MOP_xbr, {MOPD_Reg64IS,MOPD_Undef,MOPD_Undef,MOPD_Undef,MOPD_Undef},ISBRANCH,kLtBranch,"jr","0", 0, 1) +DEFINE_MOP(MOP_xbr, {MOPD_Reg64IS,MOPD_Literal,MOPD_Undef,MOPD_Undef,MOPD_Undef},ISBRANCH,kLtBranch,"jr","0", 0, 1) // MOP_Tbbuncond DEFINE_MOP(MOP_xuncond, {MOPD_Label,MOPD_Undef,MOPD_Undef,MOPD_Undef,MOPD_Undef},ISBRANCH,kLtBranch,"j","0", 0, 1) @@ -518,7 +518,7 @@ DEFINE_MOP(MOP_clinit_tail, {MOPD_Reg64IS,MOPD_Undef,MOPD_Undef,MOPD_Undef,MOPD_ // MOP_tail_call_opt_xbl -- branch without link (call); this is a special definition DEFINE_MOP(MOP_tail_call_opt_xbl, {MOPD_FuncName,MOPD_LISTS,MOPD_Undef,MOPD_Undef,MOPD_Undef},CANTHROW,kLtBranch,"tail","0", 0, 2) // MOP_tail_call_opt_xblr -- branch without link (call) to register; this is a special definition -DEFINE_MOP(MOP_tail_call_opt_xblr, {MOPD_Reg64IS,MOPD_LISTS,MOPD_Undef,MOPD_Undef,MOPD_Undef},CANTHROW,kLtBranch,"br","0", 0, 2) +DEFINE_MOP(MOP_tail_call_opt_xblr, {MOPD_Reg64IS,MOPD_LISTS,MOPD_Undef,MOPD_Undef,MOPD_Undef},CANTHROW,kLtBranch,"jr","0", 0, 2) // All pseudo instructons need to be inserted after this point and before MOP_pseudo_last diff --git a/mapleall/maple_be/include/cg/riscv64/riscv64_peep.h b/mapleall/maple_be/include/cg/riscv64/riscv64_peep.h index 02e7ac758b63a6f5dd83ba85ac9ae1849fcaa24d..bbdbc52ab83bc8e4bb91d3e090bc97732c123191 100644 --- a/mapleall/maple_be/include/cg/riscv64/riscv64_peep.h +++ b/mapleall/maple_be/include/cg/riscv64/riscv64_peep.h @@ -45,6 +45,7 @@ class Riscv64Peep { } ~Riscv64Peep(){}; + void RemoveSingleInstruction(); void RemoveIdenticalLoadAndStore(); void Peephole0(); void Peephole(); @@ -61,6 +62,7 @@ class Riscv64Peep { void PrePeepholeOpt(); void PrePeepholeOpt1(); void ReplaceInstruction(); + bool IfOperandIsLiveAfterInsn(RegOperand *regOpnd, Insn *insn); }; // class Riscv64Peep diff --git a/mapleall/maple_be/src/be/be_lowerer.cpp b/mapleall/maple_be/src/be/be_lowerer.cpp index ee958279440ff2334b5994a25c5c5a888099e5b2..c7da9bb70a52df3468a0e5ed0af09a1fc5ae90bc 100644 --- a/mapleall/maple_be/src/be/be_lowerer.cpp +++ b/mapleall/maple_be/src/be/be_lowerer.cpp @@ -989,7 +989,12 @@ void BELowerer::LowerIassign(IassignNode *iassign, BlockNode *newblk) { } DassignNode *BELowerer::SaveReturnValueInLocal(StIdx stIdx, uint16 fieldID) { - MIRSymbol *var = mirModule.CurFunction()->symTab->GetSymbolFromStIdx(stIdx.Idx()); + MIRSymbol *var; + if (stIdx.IsGlobal()) { + var = GlobalTables::GetGsymTable().GetSymbolFromStIdx(stIdx.Idx()); + } else { + var = mirModule.CurFunction()->symTab->GetSymbolFromStIdx(stIdx.Idx()); + } CHECK_FATAL(var, ""); RegreadNode *regread = mirModule.mirBuilder->CreateExprRegread( GlobalTables::GetTypeTable().typeTable.at(var->GetTyIdx().GetIdx())->GetPrimType(), -kSregRetval0); @@ -1052,7 +1057,7 @@ BlockNode *BELowerer::LowerJavaThrow(UnaryStmtNode *throwstmt) { } // to lower call (including icall) and intrinsicall statements -void BELowerer::LowerCallStmt(StmtNode *stmt, StmtNode *&nextstmt, BlockNode *newblk, MIRType *retty) { +void BELowerer::LowerCallStmt(StmtNode *stmt, StmtNode *&nextstmt, BlockNode *newblk, MIRType *retty, bool uselvar) { StmtNode *newstmt = nullptr; if (stmt->op == OP_intrinsiccall) { IntrinsiccallNode *intrnnode = static_cast(stmt); @@ -1068,13 +1073,13 @@ void BELowerer::LowerCallStmt(StmtNode *stmt, StmtNode *&nextstmt, BlockNode *ne } if (newstmt->op == OP_call || newstmt->op == OP_icall) { - newstmt = LowerCall(static_cast(newstmt), nextstmt, newblk, retty); + newstmt = LowerCall(static_cast(newstmt), nextstmt, newblk, retty, uselvar); } newblk->AddStatement(newstmt); } -BlockNode *BELowerer::LowerCallAssignedStmt(StmtNode *stmt) { +BlockNode *BELowerer::LowerCallAssignedStmt(StmtNode *stmt, bool uselvar) { BlockNode *blk = mirModule.CurFuncCodeMemPool()->New(); StmtNode *newcall = nullptr; CallReturnVector *p2nrets = nullptr; @@ -1231,7 +1236,12 @@ BlockNode *BELowerer::LowerCallAssignedStmt(StmtNode *stmt) { MIRType *rettype = nullptr; if (p2nrets->size() == 1) { StIdx stIdx = (*p2nrets)[0].first; - MIRSymbol *sym = GetCurrentFunc()->symTab->GetSymbolFromStIdx(stIdx.Idx()); + MIRSymbol *sym; + if (stIdx.IsGlobal()) { + sym = GlobalTables::GetGsymTable().GetSymbolFromStIdx(stIdx.Idx()); + } else { + sym = GetCurrentFunc()->symTab->GetSymbolFromStIdx(stIdx.Idx()); + } bool sizeIs0 = false; if (sym) { rettype = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->tyIdx); @@ -1276,8 +1286,8 @@ BlockNode *BELowerer::LowerCallAssignedStmt(StmtNode *stmt) { } CHECK_FATAL(!dstmt || dstmt->GetNext() == nullptr, ""); - LowerCallStmt(newcall, dstmt, blk, rettype); - if (dstmt != nullptr) { + LowerCallStmt(newcall, dstmt, blk, rettype, uselvar ? true : false); + if (!uselvar && dstmt != nullptr) { blk->AddStatement(dstmt); } } @@ -1342,10 +1352,39 @@ BlockNode *BELowerer::LowerBlock(BlockNode *block) { break; } case OP_callassigned: + case OP_icallassigned: { + // pass the addr of lvar if this is a struct call assignment + bool lvar = false; + if (nextstmt && nextstmt->op == OP_dassign) { + BaseNode *bnode = static_cast(nextstmt)->GetRhs(); + DreadNode *dnode = dynamic_cast(bnode); + if (dnode) { + MIRType *dtype = mirModule.CurFunction()->GetLocalOrGlobalSymbol(dnode->stIdx)->GetType(); + if (dnode->op == OP_dread && dnode->primType == PTY_agg && dtype->GetSize() > 16) { + CallNode *callnode = static_cast(stmt); + CallReturnVector *p2nrets = &callnode->returnValues; + if (p2nrets->size() == 1) { + CallReturnPair pair = (*p2nrets)[0]; + if (pair.first == dnode->stIdx && + pair.second.fieldID == dnode->fieldID) { + DassignNode *dnode_stmt = static_cast(nextstmt); + if (dnode_stmt->fieldID == 0) { + (*p2nrets)[0].first = dnode_stmt->stIdx; + (*p2nrets)[0].second.fieldID = dnode_stmt->fieldID; + nextstmt = nextstmt->GetNext(); // skip dassign + lvar = true; + } + } + } + } + } + } + newblk->AppendStatementsFromBlock(LowerCallAssignedStmt(stmt, lvar)); + break; + } case OP_virtualcallassigned: case OP_superclasscallassigned: case OP_interfacecallassigned: - case OP_icallassigned: case OP_intrinsiccallassigned: case OP_xintrinsiccallassigned: case OP_intrinsiccallwithtypeassigned: @@ -1380,9 +1419,7 @@ BlockNode *BELowerer::LowerBlock(BlockNode *block) { } // Do not leave comment stmt to mmpl. case OP_comment: - if (!IsTargetMMPL()) { - newblk->AddStatement(stmt); - } + newblk->AddStatement(stmt); break; case OP_try: case OP_javatry: @@ -1434,7 +1471,7 @@ BlockNode *BELowerer::LowerBlock(BlockNode *block) { return newblk; } -StmtNode *BELowerer::LowerCall(CallNode *callnode, StmtNode *&nextstmt /*in-out*/, BlockNode *newblk, MIRType *retty) { +StmtNode *BELowerer::LowerCall(CallNode *callnode, StmtNode *&nextstmt /*in-out*/, BlockNode *newblk, MIRType *retty, bool uselvar) { // call $foo(constVal u32 128) // dassign %jlt (dread agg %%retval) bool isarraystore = false; @@ -1542,7 +1579,7 @@ StmtNode *BELowerer::LowerCall(CallNode *callnode, StmtNode *&nextstmt /*in-out* return callnode; } - if (retty && becommon.type_size_table[retty->tyIdx.GetIdx()] <= 16) { + if (!uselvar && retty && becommon.type_size_table[retty->tyIdx.GetIdx()] <= 16) { // return structure fitting in one or two regs. return callnode; } diff --git a/mapleall/maple_be/src/be/mmpl/mmpl_lowerer.cpp b/mapleall/maple_be/src/be/mmpl/mmpl_lowerer.cpp index c91631ba1f48fe32ff8982ce052e763fe0b7a532..aba6a98c7fec3bb3006c0e108826db36e13b75b4 100644 --- a/mapleall/maple_be/src/be/mmpl/mmpl_lowerer.cpp +++ b/mapleall/maple_be/src/be/mmpl/mmpl_lowerer.cpp @@ -62,7 +62,7 @@ PregIdx MmplLowerer::GetSpecialRegFromSt(const MIRSymbol *sym) { } BaseNode *MmplLowerer::ReadregNodeForSymbol(MIRSymbol *sym) { - return mirModule.mirBuilder->CreateExprRegread(PTY_a32, GetSpecialRegFromSt(sym)); + return mirModule.mirBuilder->CreateExprRegread(LOWERED_PTR_TYPE, GetSpecialRegFromSt(sym)); } BaseNode *MmplLowerer::LowerAddrof(AddrofNode *expr) { @@ -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)PTY_a32), rrn, + : mirModule.mirBuilder->CreateExprBinary(OP_add, GlobalTables::GetTypeTable().GetTypeFromTyIdx((TyIdx)LOWERED_PTR_TYPE), rrn, mirModule.mirBuilder->GetConstInt(offset)); } @@ -103,7 +103,7 @@ BaseNode *MmplLowerer::LowerDread(AddrofNode *expr) { symty, memlayout->sym_alloc_table[symbol->GetStIndex()].offset + offset); return ireadoff; } else { - BaseNode *rrn = mirModule.mirBuilder->CreateExprRegread(PTY_a32, spcreg); + BaseNode *rrn = mirModule.mirBuilder->CreateExprRegread(LOWERED_PTR_TYPE, spcreg); SymbolAlloc &symalloc = symbol->IsLocal() ? memlayout->sym_alloc_table[symbol->GetStIndex()] : globmemlayout->sym_alloc_table[symbol->GetStIndex()]; IreadoffNode *ireadoff = mirModule.mirBuilder->CreateExprIreadoff(symty, symalloc.offset + offset, rrn); diff --git a/mapleall/maple_be/src/cg/aarch64/aarch64_cg.cpp b/mapleall/maple_be/src/cg/aarch64/aarch64_cg.cpp index 947e8d4dc0d7340b884f1c7dda70f464dfbf3b1c..4817f53a572e8e16425695da0ef7c412b1b1d6ff 100644 --- a/mapleall/maple_be/src/cg/aarch64/aarch64_cg.cpp +++ b/mapleall/maple_be/src/cg/aarch64/aarch64_cg.cpp @@ -319,6 +319,10 @@ bool AArch64Insn::IsDestRegAlsoSrcReg() const { return prop0->IsRegDef() && prop0->IsRegUse(); } +bool AArch64Insn::IsUncondBranch() const { + return (mop_ == MOP_xbr || mop_ == MOP_xuncond); +} + bool AArch64Insn::IsDataMoveInstruction() const { return ((AArch64CG::kMd[mop_].properties_ & ISMOVE) != 0); } diff --git a/mapleall/maple_be/src/cg/aarch64/aarch64_cg_func.cpp b/mapleall/maple_be/src/cg/aarch64/aarch64_cg_func.cpp index 13b93508869df761a8200686c09bbef115b47060..27cad3ef2083cd05d948033645da834ce4966741 100644 --- a/mapleall/maple_be/src/cg/aarch64/aarch64_cg_func.cpp +++ b/mapleall/maple_be/src/cg/aarch64/aarch64_cg_func.cpp @@ -2207,9 +2207,9 @@ void AArch64CGFunc::GenerateProlog(BB * bb) { if (cg->cgopt_.WithSrc()) { uint32 tempmaxsize = mirModule.srcFileInfo.size(); uint32 endfilenum = mirModule.srcFileInfo[tempmaxsize - 1].second; - if (func->srcPosition.Filenum() != 0 && func->srcPosition.Filenum() <= endfilenum) { - Operand *o0 = CreateDbgImmOperand(func->srcPosition.Filenum()); - int64_t lineNum = func->srcPosition.Linenum(); + if (func->GetFuncSymbol()->srcPosition.Filenum() != 0 && func->GetFuncSymbol()->srcPosition.Filenum() <= endfilenum) { + Operand *o0 = CreateDbgImmOperand(func->GetFuncSymbol()->srcPosition.Filenum()); + int64_t lineNum = func->GetFuncSymbol()->srcPosition.Linenum(); if (lineNum == 0) { if (func->funcAttrs.GetAttr(FUNCATTR_native)) { lineNum = 0xffffe; @@ -2225,7 +2225,7 @@ void AArch64CGFunc::GenerateProlog(BB * bb) { Operand *o0 = CreateDbgImmOperand(1); // line number might not be available. //CG_ASSERT(func->srcPosition.MplLinenum(), "return check"); - Operand *o1 = CreateDbgImmOperand(func->srcPosition.MplLinenum()); + Operand *o1 = CreateDbgImmOperand(func->GetFuncSymbol()->srcPosition.MplLinenum()); Insn *loc = cg->BuildInstruction(mpldbg::OP_DBG_loc, o0, o1); curbb->AppendInsn(loc); } @@ -2314,6 +2314,16 @@ void AArch64CGFunc::GenerateProlog(BB * bb) { } void AArch64CGFunc::GenerateRet(BB * bb) { + MOperator mop; + AArch64reg_t preg; + if (retRegType == kRegTyInt) { + mop = MOP_pseudo_ret_int; + preg = R0; + } else { + mop = MOP_pseudo_ret_float; + preg = V0; + } + bb->AppendInsn(cg->BuildInstruction(mop, GetOrCreatePhysicalRegisterOperand(preg, 64, kRegTyInt))); bb->AppendInsn(cg->BuildInstruction(MOP_xret)); } @@ -2442,12 +2452,9 @@ bool AArch64CGFunc::TailCallOpt() { CG_ASSERT(regsToRestore.size() >= 2, "Forgot FP and LR ?"); - if ((mirModule.IsCModule()) && - static_cast(memlayout)->locals().size > 0) { - return false; - } - - if (CLANG && func->GetAttr(FUNCATTR_varargs)) { + if (CLANG && + ((static_cast(memlayout)->locals().size > 0) || + func->GetAttr(FUNCATTR_varargs) || HasVLAOrAlloca())) { return false; } @@ -4382,16 +4389,31 @@ void AArch64CGFunc::SelectReturn(NaryStmtNode * stmt, Operand * opnd0) { if (retmech.regcount > 0) { if (RegOperand *regopnd = dynamic_cast(opnd0)) { if (regopnd->GetRegisterNumber() != retmech.reg0) { + if (AArch64isa::IsGPRegister(retmech.reg0)) { + retRegType = kRegTyInt; + } else { + retRegType = kRegTyFloat; + } retopnd = GetOrCreatePhysicalRegisterOperand(retmech.reg0, regopnd->size_, GetRegTyFromPrimTyAarch64(retmech.ptype0)); SelectCopy(retopnd, retmech.ptype0, regopnd, retmech.ptype0); } } else if (AArch64MemOperand *memopnd = dynamic_cast(opnd0)) { + if (IsPrimitivePureScalar(retmech.ptype0)) { + retRegType = kRegTyInt; + } else { + retRegType = kRegTyFloat; + } retopnd = GetOrCreatePhysicalRegisterOperand(retmech.reg0, GetPrimTypeBitSize(retmech.ptype0), GetRegTyFromPrimTyAarch64(retmech.ptype0)); MOperator mop = PickLdInsn(memopnd->size_, retmech.ptype0); curbb->AppendInsn(cg->BuildInstruction(mop, retopnd, memopnd)); } else if (opnd0->IsConstImmediate()) { + if (IsPrimitivePureScalar(retmech.ptype0)) { + retRegType = kRegTyInt; + } else { + retRegType = kRegTyFloat; + } ImmOperand *immopnd = static_cast(opnd0); retopnd = GetOrCreatePhysicalRegisterOperand(retmech.reg0, GetPrimTypeBitSize(retmech.ptype0), GetRegTyFromPrimTyAarch64(retmech.ptype0)); @@ -5064,7 +5086,7 @@ void AArch64CGFunc::InsertJumpPad(Insn *insn) { } ImmOperand *targetLabelOpnd = CreateImmOperand(targetLabel, 32, false); padBB->AppendInsn(cg->BuildInstruction(MOP_adrp_label, targetAddr, targetLabelOpnd)); - padBB->AppendInsn(cg->BuildInstruction(MOP_xbr, targetAddr)); + padBB->AppendInsn(cg->BuildInstruction(MOP_xbr, targetAddr, targetLabelOpnd)); padBB->SetKind(BB::kBBIgoto); padBB->preds.push_back(bb); padBB->succs.push_back(targetBB); diff --git a/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp b/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp index f696c9c05404b8eb08e5e2d2447605e876ca6637..a4fb6f1b8447cdf154c8529064e59687c0ead7ea 100644 --- a/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp +++ b/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp @@ -64,6 +64,7 @@ const uint32 kSwitchCaseNum = 5; const uint32 kLoopWeight = 10; const uint32 kMaxParamNum = 8; const uint32 kNumPregBits = V31 + 1; +const uint32 kNumInsnThreashold = 200000; #define GCRA_DUMP CGDEBUGFUNC(cgfunc_) @@ -1159,13 +1160,14 @@ bool GraphColorRegAllocator::IsLocalReg(LiveRange *lr) { } void GraphColorRegAllocator::CheckInterference(LiveRange *lr1, LiveRange *lr2) { - uint64 bitArr[bbBuckets]; - BIT_ARR_AND(lr1->bmember, lr2->bmember, bitArr, bbBuckets); +// uint64 bitArr[bbBuckets]; +// BIT_ARR_AND(lr1->bmember, lr2->bmember, bitArr, bbBuckets); uint32 lastBitSet; uint32 overlapNum = 0; bool stop = false; + for (uint32 i = 0; i < bbBuckets; i++) { - uint64 val = bitArr[i]; + uint64 val = lr1->bmember[i] & lr2->bmember[i]; if (val) { for (uint32 x = 0; x < (sizeof(uint64) * CHAR_BIT); x++) { if (val & (1LL << x)) { @@ -1235,23 +1237,54 @@ void GraphColorRegAllocator::BuildInterferenceGraph() { std::vector fpLrVec; BuildInterferenceGraphSeparateIntFp(intLrVec, fpLrVec); - std::vector::iterator it1, it2; - for (it1 = intLrVec.begin(); it1 != intLrVec.end(); it1++) { - LiveRange *lr1 = *it1; + int sz = intLrVec.size(); + + // Checking interferences among LVs consumes significant amount of time. + // Take advantage of the fact that a large portion of LVs are short-lived + // Delay to do the same to FP + std::vector idxLastBucket(sz); + for (int i = 0; i < sz; i++) { + uint32 count = 0; + uint32 lastPos; + LiveRange *lr = intLrVec[i]; + for (int j = 0; j < bbBuckets; j++) { + if (lr->bmember[j]) { + count++; + lastPos = j; + } + } + if (count == 1) { + idxLastBucket[i] = lastPos; + } else { + idxLastBucket[i] = -1; + } + } + + for (int i = 0; i < sz; i++) { + LiveRange *lr1 = intLrVec[i]; CalculatePriority(lr1); - for (it2 = it1 + 1; it2 != intLrVec.end(); it2++) { - LiveRange *lr2 = *it2; - if (lr1->regno < lr2->regno) { - CheckInterference(lr1, lr2); + int32 iLastBucketIdx = idxLastBucket[i]; + + for (int j = i + 1; j < sz; j++) { + int32 jLastBucketIdx = idxLastBucket[j]; + LiveRange *lr2 = intLrVec[j]; + if (lr1->regno < lr2->regno ) { + if (iLastBucketIdx == -1 && jLastBucketIdx == -1) { + CheckInterference(lr1, lr2); + } else if ((iLastBucketIdx >= 0 && lr1->bmember[iLastBucketIdx] & lr2->bmember[iLastBucketIdx]) || + (jLastBucketIdx >= 0 && lr1->bmember[jLastBucketIdx] & lr2->bmember[jLastBucketIdx])) { + CheckInterference(lr1, lr2); + } } } } - for (it1 = fpLrVec.begin(); it1 != fpLrVec.end(); it1++) { - LiveRange *lr1 = *it1; + sz = fpLrVec.size(); + for (int i = 0; i < sz; i++) { + LiveRange *lr1 = fpLrVec[i]; CalculatePriority(lr1); - for (it2 = it1 + 1; it2 != fpLrVec.end(); it2++) { - LiveRange *lr2 = *it2; + for (int j = i + 1; j < sz; j++) { + LiveRange *lr2 = fpLrVec[j]; if (lr1->regno < lr2->regno) { CheckInterference(lr1, lr2); } @@ -3342,7 +3375,7 @@ void GraphColorRegAllocator::SpillLiveRangeForSpills() { // Iterate through all instructions and change the vreg to preg. void GraphColorRegAllocator::FinalizeRegisters() { - if (CGOptions::doMultiPassColorRA && hasSpill) { + if (doMultiPass && hasSpill) { SpillLiveRangeForSpills(); return; } @@ -3424,6 +3457,9 @@ bool GraphColorRegAllocator::AllocateRegisters() { } } CG_ASSERT(cnt <= cgfunc_->GetTotalNumberOfInstructions(), "Incorrect insn count"); + if ((cnt < kNumInsnThreashold) && CGOptions::doMultiPassColorRA) { + doMultiPass = true; + } #ifdef PROPAGATE_REG if (cgfunc_->IsAfterRegAlloc() == false) { @@ -3438,7 +3474,7 @@ bool GraphColorRegAllocator::AllocateRegisters() { } #endif - if (CGOptions::doMultiPassColorRA) { + if (doMultiPass) { doLRA = false; doOptProlog = false; } @@ -3456,7 +3492,6 @@ bool GraphColorRegAllocator::AllocateRegisters() { LocalRegisterAllocator(false); } #endif // DO_PRE_LRA - BuildInterferenceGraph(); Separate(); @@ -3477,7 +3512,7 @@ bool GraphColorRegAllocator::AllocateRegisters() { cgfunc_->DumpCGIR(); } - if (CGOptions::doMultiPassColorRA && hasSpill) { + if (doMultiPass && hasSpill) { return false; } else { return true; diff --git a/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp b/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp index 82e960a9adc31a84ea02b964539630a5dd9e69d5..34dc3168b335a6c7c609c2b368ae2c3e800b82aa 100644 --- a/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp +++ b/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp @@ -742,13 +742,29 @@ bool AArch64Ebo::SpecialSequence(Insn *insn, Operand **opnds, OpndInfo **origInf RegOperand *res1 = static_cast(insn1->GetOperand(0)); if (RegistersIdentical(res1, op1) && RegistersIdentical(res1, res2) && GetOpndInfo(base2, -1) != nullptr && GetOpndInfo(base2, -1)->redefined == false) { - immVal = imm0Val + imm1->GetValue() + ((imm2->GetValue()) << 12); + if (before_regalloc) { + immVal = imm0Val + imm1->GetValue() + ((imm2->GetValue()) << 12); + } else if (RegistersIdentical(res2, base2)) { + if (RegistersIdentical(insn1->GetOperand(0), insn1->GetOperand(1))) { + return false; + } else { + immVal = imm0Val + imm1->GetValue() + ((imm2->GetValue()) << 12); + } + } else { + immVal = imm0Val + imm1->GetValue() + ((imm2->GetValue()) << 12); + } op1 = base2; } else { return false; } } else { - immVal = imm0Val + imm1->GetValue(); + if (before_regalloc) { + immVal = imm0Val + imm1->GetValue(); + } else if (RegistersIdentical(insn1->GetOperand(0), insn1->GetOperand(1))) { + immVal = imm0Val; + } else { + immVal = imm0Val + imm1->GetValue(); + } } if ((!is64bits && immVal < STR_LDR_IMM32_UPPER_BOUND && immVal % 4 == 0) || (is64bits && immVal < STR_LDR_IMM64_UPPER_BOUND && immVal % 8 == 0)) { diff --git a/mapleall/maple_be/src/cg/aarch64/aarch64_emit.cpp b/mapleall/maple_be/src/cg/aarch64/aarch64_emit.cpp index b5ffd2b9529bb740d93fe8b405ce4f39c2960328..96ad8cbf775321654cc7a8d425bd609b625171d6 100644 --- a/mapleall/maple_be/src/cg/aarch64/aarch64_emit.cpp +++ b/mapleall/maple_be/src/cg/aarch64/aarch64_emit.cpp @@ -231,7 +231,7 @@ void AArch64Insn::EmitAdrpLabel(CG &cg, Emitter &emitter) { emitter.Emit("\t").Emit("adrp").Emit("\t"); opnd0->Emit(emitter, prop0); emitter.Emit(", "); - const char *idx = std::to_string(CG::curPuIdx).c_str(); + const char *idx = strdup(std::to_string(CG::curPuIdx).c_str()); emitter.Emit(".label.").Emit(idx).Emit("__").Emit(lidx).Emit("\n"); // add xd, xd, #lo12:label @@ -530,7 +530,9 @@ void AArch64CGFunc::Emit() { // nothing } else { emitter.Emit("\t.globl\t").Emit(funcSt->GetName()).Emit("\n"); - emitter.Emit("\t.hidden\t").Emit(funcSt->GetName()).Emit("\n"); + if (!func->IsC()) { + emitter.Emit("\t.hidden\t").Emit(funcSt->GetName()).Emit("\n"); + } } emitter.Emit("\t.type\t").Emit(funcSt->GetName()).Emit(", %function\n"); @@ -586,7 +588,7 @@ void AArch64CGFunc::Emit() { LSDAHeader *lsdaheader = ehfunc->lsda_header; const char *funcname = funcSt->GetName().c_str(); // .word .label.lsda_label-func_start_label - const char *idx = std::to_string(CG::curPuIdx).c_str(); + const char *idx = strdup(std::to_string(CG::curPuIdx).c_str()); emitter.Emit("\t.word ") .Emit(".label.") .Emit(idx) @@ -668,7 +670,7 @@ void AArch64CGFunc::Emit() { MIRLblConst *lblconst = static_cast(arrayConst->constVec[i]); CHECK_FATAL(lblconst, "null ptr check"); emitter.Emit("\t.quad\t"); - const char *idx = std::to_string(CG::curPuIdx).c_str(); + const char *idx = strdup(std::to_string(CG::curPuIdx).c_str()); emitter.Emit(".label.").Emit(idx).Emit("__").Emit(lblconst->value); emitter.Emit(" - ").Emit(st->GetName().c_str()); emitter.Emit("\n"); @@ -688,7 +690,7 @@ void AArch64CGFunc::EmitFastLSDA() // the fast_exception_handling lsda // .word 0xFFFFFFFF // .word .label.LTest_3B_7C_3Cinit_3E_7C_28_29V3-func_start_label emitter->Emit("\t.word 0xFFFFFFFF\n"); - const char *idx = std::to_string(CG::curPuIdx).c_str(); + const char *idx = strdup(std::to_string(CG::curPuIdx).c_str()); if (NeedCleanup()) { emitter->Emit("\t.word ") .Emit(".label.") @@ -775,7 +777,7 @@ void AArch64CGFunc::EmitFullLSDA() // the normal gcc_except_table emitter->EmitLabelPair(funcname, cleaupCode); } else if (func->IsJava()) { CG_ASSERT(!exitbbsvec.empty(), "exitbbsvec is empty in AArch64CGFunc::EmitFullLSDA"); - const char *idx = std::to_string(CG::curPuIdx).c_str(); + const char *idx = strdup(std::to_string(CG::curPuIdx).c_str()); emitter->Emit("\t.uleb128 ") .Emit(".label.") .Emit(idx) @@ -823,7 +825,7 @@ void AArch64CGFunc::EmitFullLSDA() // the normal gcc_except_table emitter->EmitLabelPair(funcname, cleaupCode); } else { CG_ASSERT(!exitbbsvec.empty(), "exitbbsvec is empty in AArch64CGFunc::EmitFullLSDA"); - const char *idx = std::to_string(CG::curPuIdx).c_str(); + const char *idx = strdup(std::to_string(CG::curPuIdx).c_str()); emitter->Emit("\t.uleb128 ") .Emit(".label.") .Emit(idx) @@ -1043,7 +1045,7 @@ void AArch64CGFunc::EmitOperand(Operand *opnd, OpndProp *prop) { outf << stopnd->GetName(); } } else if (LabelOperand *lblopnd = dynamic_cast(opnd)) { - const char *idx = std::to_string(CG::curPuIdx).c_str(); + const char *idx = strdup(std::to_string(CG::curPuIdx).c_str()); outf << ".label." << idx << "__" << lblopnd->labidx_; } else if (FuncNameOperand *fn = dynamic_cast(opnd)) { outf << fn->GetName(); diff --git a/mapleall/maple_be/src/cg/aarch64/aarch64_insn.cpp b/mapleall/maple_be/src/cg/aarch64/aarch64_insn.cpp index 89db7a13f8d0e38aea9f0c77a9f1f491a862b1b5..fe5e25deb5b54af305a067dca8c3c57d16426443 100644 --- a/mapleall/maple_be/src/cg/aarch64/aarch64_insn.cpp +++ b/mapleall/maple_be/src/cg/aarch64/aarch64_insn.cpp @@ -246,6 +246,7 @@ int32_t AArch64Insn::CopyOperands() { * Get the jump target label operand index from the given instruction. * Note: MOP_xbr is a jump instruction, but the target is unknown at compile time, * because a register instead of label. So we don't take it as a branching instruction. + * Howeer for special long range branch patch, the label is installed in this case. */ int AArch64Insn::GetJumpTargetIdx() const { int operandIdx = 0; @@ -255,6 +256,11 @@ int AArch64Insn::GetJumpTargetIdx() const { operandIdx = 0; break; } + case MOP_xbr: { + CHECK_FATAL(opnds[1] != 0, "ERR"); + operandIdx = 1; + break; + } // conditional jump case MOP_bmi: case MOP_bvc: diff --git a/mapleall/maple_be/src/cg/aarch64/aarch64_insn_slct.cpp b/mapleall/maple_be/src/cg/aarch64/aarch64_insn_slct.cpp index ffd6a58df694c586178e68baaa83a7944e8f23ab..f10d21f3367c7d3b8e028f824d3870d29e103f7b 100644 --- a/mapleall/maple_be/src/cg/aarch64/aarch64_insn_slct.cpp +++ b/mapleall/maple_be/src/cg/aarch64/aarch64_insn_slct.cpp @@ -2160,7 +2160,7 @@ Operand *AArch64CGFunc::SelectGCMalloc(GCMallocNode *node) { vector opndvec{ resopnd, opndSize, opndAlign }; - const char *funcName = GetIntrinsicFuncName(INTRN_MCCNewObj).c_str(); + const char *funcName = strdup(GetIntrinsicFuncName(INTRN_MCCNewObj).c_str()); SelectLibCall(funcName, opndvec, PTY_u64, rettype); return resopnd; @@ -2201,7 +2201,7 @@ Operand *AArch64CGFunc::SelectJarrayMalloc(JarrayMallocNode *node, Operand *opnd vector opndvec{ resopnd, opndFixedSize, opndElemSize, opndNElems64, opndAlign }; - const char *funcName = GetIntrinsicFuncName(INTRN_MCCNewObjFlexibleCname).c_str(); + const char *funcName = strdup(GetIntrinsicFuncName(INTRN_MCCNewObjFlexibleCname).c_str()); SelectLibCall(funcName, opndvec, PTY_u64, rettype); // Generate the store of the object length field diff --git a/mapleall/maple_be/src/cg/aarch64/aarch64_load_store.cpp b/mapleall/maple_be/src/cg/aarch64/aarch64_load_store.cpp index 1a97719189bb8c29436681310f71ffe007d71f1e..497215a8cd2ad5aaa532cfb5215e2a3a79122221 100644 --- a/mapleall/maple_be/src/cg/aarch64/aarch64_load_store.cpp +++ b/mapleall/maple_be/src/cg/aarch64/aarch64_load_store.cpp @@ -2229,18 +2229,37 @@ Operand *AArch64CGFunc::SelectIntconst(MIRIntConst *intconst, PrimType pty) { template Operand *SelectLiteral(T *c, MIRFunction *func, uint32 labelIdx, AArch64CGFunc *cgfunc) { - MIRSymbol *st = func->symTab->CreateSymbol(kScopeLocal); - std::string lblstr(".LB_"); - MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStIdx(func->stIdx.Idx()); - std::string funcname = funcSt->GetName(); - lblstr.append(funcname).append(to_string(labelIdx)); - st->SetNameStridx(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lblstr)); - st->storageClass = kScPstatic; - st->sKind = kStConst; - st->SetConst(c); - PrimType primty = c->type->GetPrimType(); - st->SetTyIdx(c->type->tyIdx); - uint32 typeBitsize = GetPrimTypeBitSize(primty); + // SelectLiteral is only for MIRFloatConst and MIRDoubleConst + MIRSymbol* sym = nullptr; + for (uint32_t idx = 0; idx < func->symTab->GetSymbolTableSize(); idx++) { + auto tsym = func->symTab->GetSymbolFromStIdx(idx); + if (tsym && + (tsym->storageClass == kScPstatic) && + (tsym->sKind == kStConst) && + (tsym->GetTyIdx() == c->type->tyIdx) && + (static_cast(tsym->GetConst())->GetValue() == c->GetValue())) { + sym = tsym; + break; + } + } + + MIRSymbol *st; + uint32 typeBitsize = GetPrimTypeBitSize(c->type->GetPrimType()); + + if (sym) { + st = sym; // Reuse the existing symbol + } else { // Create a new symbol + st = func->symTab->CreateSymbol(kScopeLocal); + std::string lblstr(".LB_"); + MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStIdx(func->stIdx.Idx()); + std::string funcname = funcSt->GetName(); + lblstr.append(funcname).append(to_string(labelIdx)); + st->SetNameStridx(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lblstr)); + st->storageClass = kScPstatic; + st->sKind = kStConst; + st->SetConst(c); + st->SetTyIdx(c->type->tyIdx); + } switch (c->kind) { case kConstFloatConst: @@ -2252,9 +2271,6 @@ Operand *SelectLiteral(T *c, MIRFunction *func, uint32 labelIdx, AArch64CGFunc * return (c->IsZero() && !(c->IsNeg())) ? static_cast(cgfunc->GetOrCreateFpZeroOperand(typeBitsize)) : static_cast(cgfunc->GetOrCreateMemOpnd(st, 0, typeBitsize)); } - case kConstVecInt: { - return static_cast(cgfunc->GetOrCreateMemOpnd(st, 0, typeBitsize)); - } default: { ASSERT(0, "Unsupported const type"); return nullptr; @@ -2271,7 +2287,20 @@ Operand *AArch64CGFunc::SelectDoubleconst(MIRDoubleConst *doubleconst) { } Operand *AArch64CGFunc::SelectVectorIntconst(MIRVectorIntConst *vecIntconst) { - return SelectLiteral(vecIntconst, func, labelIdx++, this); + // Dup of MIRVectorIntConst is highly unlikely. May check dup in future + MIRSymbol *st = func->symTab->CreateSymbol(kScopeLocal); + std::string lblstr(".LB_"); + MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStIdx(func->stIdx.Idx()); + std::string funcname = funcSt->GetName(); + lblstr.append(funcname).append(to_string(labelIdx)); + st->SetNameStridx(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lblstr)); + st->storageClass = kScPstatic; + st->sKind = kStConst; + st->SetConst(vecIntconst); + PrimType primty = vecIntconst->type->GetPrimType(); + st->SetTyIdx(vecIntconst->type->tyIdx); + uint32 typeBitsize = GetPrimTypeBitSize(primty); + return static_cast(GetOrCreateMemOpnd(st, 0, typeBitsize)); } template diff --git a/mapleall/maple_be/src/cg/aarch64/aarch64_optimize_common.cpp b/mapleall/maple_be/src/cg/aarch64/aarch64_optimize_common.cpp index 79b994a7e76dd1df944be08db9845cdd3e829ec3..59569fc4983383068417edf6335a61a0fb7b623a 100644 --- a/mapleall/maple_be/src/cg/aarch64/aarch64_optimize_common.cpp +++ b/mapleall/maple_be/src/cg/aarch64/aarch64_optimize_common.cpp @@ -119,6 +119,16 @@ void AArch64InsnVisitor::ModifyJumpTarget(Operand *targetOperand, BB *&bb) { } CHECK_FATAL(modified, "ModifyJumpTarget: Could not change jump target"); return; + } else if (bb->GetKind() == BB::kBBGoto) { + for (Insn *insn = bb->lastinsn; insn != nullptr; insn = insn->prev) { + if (insn->GetMachineOpcode() == MOP_adrp_label) { + maple::LabelIdx labidx = static_cast(targetOperand)->labidx_; + LabelOperand *label = static_cast(GetCGFunc())->GetOrCreateLabelOperand(labidx); + insn->SetOperand(1, label); + break; + } + } + // fallthru below to patch the branch insn } int targetIdx = bb->lastinsn->GetJumpTargetIdx(); bb->lastinsn->SetOperand(targetIdx, targetOperand); @@ -170,7 +180,14 @@ Insn *AArch64InsnVisitor::CloneInsn(Insn *originalInsn) { AArch64Insn *tobeCloned = static_cast(originalInsn); Insn *newInsn = mp->Clone(*tobeCloned); for (uint32 i = 0; i < Insn::kMaxOperandNum; i++) { - newInsn->opnds[i] = originalInsn->opnds[i]; + ImmOperand *iopnd = dynamic_cast(originalInsn->opnds[i]); + if (iopnd && iopnd->IsVary()) { + AArch64ImmOperand *cloneImm = static_cast(originalInsn->opnds[i]); + ImmOperand *newIopnd = mp->Clone(*cloneImm); + newInsn->opnds[i] = newIopnd; + } else { + newInsn->opnds[i] = originalInsn->opnds[i]; + } } return newInsn; } else if (dynamic_cast(originalInsn)) { diff --git a/mapleall/maple_be/src/cg/aarch64/aarch64_peep.cpp b/mapleall/maple_be/src/cg/aarch64/aarch64_peep.cpp index 6bb77903839d209fb60e41d0103e2de115f574c4..433c5f933eccb56e5b193cd7253d5344cb4ea69d 100644 --- a/mapleall/maple_be/src/cg/aarch64/aarch64_peep.cpp +++ b/mapleall/maple_be/src/cg/aarch64/aarch64_peep.cpp @@ -1460,8 +1460,10 @@ void AArch64Peep::DeleteMovAfterCbzOrCbnz() { MOperator condbrMop = condbr->GetMachineOpcode(); if (condbrMop == MOP_wcbnz || condbrMop == MOP_xcbnz) { processBb = bb->next; - } else { + } else if (condbrMop == MOP_wcbz || condbrMop == MOP_xcbz) { processBb = cgfunc->theCFG->GetTargetSuc(bb); + } else { + continue; } CG_ASSERT(processBb != nullptr, "process_bb is null in AArch64Peep::DeleteMovAfterCbzOrCbnz"); @@ -2049,6 +2051,27 @@ void AArch64Peep::ComplexMemOperandOpt() { nextInsn->SetOperand(1, newMemOpnd); bb->RemoveInsn(insn); } + } else if (thisMop == MOP_xmovri32 || thisMop == MOP_xmovri64) { + // mov x0, #1 (small val) => mov x0, #1 + // ldr x1, [x2, x0, SXTW #2] ldr x1, [x2, #4] + MOperator nextMop = nextInsn->GetMachineOpcode(); + if (nextMop && + ((nextMop >= MOP_wldrsb && nextMop <= MOP_dldp) || (nextMop >= MOP_wstrb && nextMop <= MOP_dstp))) { + AArch64MemOperand *memOpnd = static_cast(nextInsn->GetMemOpnd()); + if (memOpnd->GetAddrMode() == AArch64MemOperand::kAddrModeBOrX) { + regno_t movReg = static_cast(insn->opnds[0])->GetRegisterNumber(); + regno_t offReg = memOpnd->GetOffsetRegister()->GetRegisterNumber(); + if (movReg == offReg) { + int32 mul = static_cast(insn->opnds[1])->GetValue() << memOpnd->ShiftAmount(); + if (mul < 256) { + AArch64MemOperand *newMemOpnd = + acgfunc->GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, memOpnd->GetSize(), + memOpnd->GetBaseRegister(), nullptr, acgfunc->GetOrCreateOfstOpnd(mul, 32), memOpnd->GetSymbol()); + nextInsn->SetOperand(1, newMemOpnd); + } + } + } + } } } } @@ -2072,8 +2095,9 @@ void AArch64Peep::ComplexMemOperandOptLSL() { MOperator thisMop = insn->GetMachineOpcode(); if (thisMop == MOP_xaddrrrs) { MOperator nextMop = nextInsn->GetMachineOpcode(); + // load/store byte not eligible. if (nextMop && - ((nextMop >= MOP_wldrsb && nextMop <= MOP_dldr) || (nextMop >= MOP_wstrb && nextMop <= MOP_dstr))) { + ((nextMop >= MOP_wldrsh && nextMop <= MOP_dldr) || (nextMop >= MOP_wstrh && nextMop <= MOP_dstr))) { // Check if base register of nextInsn and the dest operand of insn are identical. AArch64MemOperand *memOpnd = static_cast(nextInsn->GetMemOpnd()); CG_ASSERT(memOpnd != nullptr, "null ptr check"); @@ -2112,6 +2136,10 @@ void AArch64Peep::ComplexMemOperandOptLSL() { } BitShiftOperand *lsl = static_cast(insn->GetOperand(3)); uint32 shftsize = lsl->GetShiftAmount(); + if ((nextMop == MOP_wldrsh || nextMop == MOP_wldrh || nextMop == MOP_wstrh) && shftsize > 1) { + // half word only allows shift value of 1 or less + continue; + } if ((memOpnd->GetSize() == 32 && (shftsize != 0 && shftsize != 2)) || (memOpnd->GetSize() == 64 && (shftsize != 0 && shftsize != 3))) { continue; diff --git a/mapleall/maple_be/src/cg/ark/ark_emit.cpp b/mapleall/maple_be/src/cg/ark/ark_emit.cpp index 93f62d641b6e70fa8771f9096206f576cbedafbc..905a119b3ca328b2df5ad0cb77f04bef59691b3c 100644 --- a/mapleall/maple_be/src/cg/ark/ark_emit.cpp +++ b/mapleall/maple_be/src/cg/ark/ark_emit.cpp @@ -195,7 +195,9 @@ void ArkCGFunc::Emit() { // nothing } else { emitter.Emit("\t.globl\t").Emit(funcSt->GetName()).Emit("\n"); - emitter.Emit("\t.hidden\t").Emit(funcSt->GetName()).Emit("\n"); + if (!func->module->IsJsModule()) { + emitter.Emit("\t.hidden\t").Emit(funcSt->GetName()).Emit("\n"); + } } emitter.Emit("\t.type\t").Emit(funcSt->GetName()).Emit(", %function\n"); @@ -207,7 +209,9 @@ void ArkCGFunc::Emit() { emitter.Emit("\t// mir2bin func begin: ========================\n"); emitter.Emit("\t.cfi_startproc\n"); - emitter.Emit("\t.cfi_personality 155, DW.ref.__mpl_personality_v0\n"); + if (!func->module->IsJsModule()) { + emitter.Emit("\t.cfi_personality 155, DW.ref.__mpl_personality_v0\n"); + } emitter.mirg_->EmitFunc(cg->curCgFunc->func); emitter.Emit("\t.cfi_endproc\n"); emitter.Emit(".label.end."+funcSt->GetName()+":\n"); 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 be2da39629e520cc03617730b461a41b3b7e410d..6384687547e33f55e148c02595b1586acb05475d 100644 --- a/mapleall/maple_be/src/cg/ark/ark_mir_emit.cpp +++ b/mapleall/maple_be/src/cg/ark/ark_mir_emit.cpp @@ -30,6 +30,8 @@ #include #define CLANG (mmodule.IsCModule()) +#define JAVALANG (mmodule.IsJavaModule()) +#define JAVASCRIPT (mmodule.IsJsModule()) using std::hex; @@ -119,13 +121,13 @@ std::set PreDefClassInfo = { // TODO: add memcmpMpl to list when we have x86 replacement. // NOTE: IntrinsicList is moved to special_func.cpp -inline void MirGenerator::EmitString(const std::string &str, int bytes) { +inline void MirGenerator::EmitString(const std::string &str, int bytes=0) { int offset = GetFuncOffset(); os << "\t" << str << "\n"; SetFuncOffset(offset + bytes); } -inline void MirGenerator::EmitStringNoTab(const std::string &str, int bytes) { +inline void MirGenerator::EmitStringNoTab(const std::string &str, int bytes=0) { int offset = GetFuncOffset(); os << str << "\n"; SetFuncOffset(offset + bytes); @@ -282,7 +284,11 @@ void MirGenerator::EmitExpr(Opcode curOp, PrimType curPrimType, BaseNode *fexpr) ASSERT(preg, "preg is null"); regName.append("%"); regName.append(std::to_string(preg->pregNo)); - expr.param.frameIdx = curFunc.EncodePreg(preg->pregNo); + if (JAVASCRIPT) { + expr.param.frameIdx = preg->pregNo; + } else { + expr.param.frameIdx = curFunc.EncodePreg(preg->pregNo); + } EmitAsmBaseNode(expr, regName); // check for regread of less than 4 bytes CheckInsertOpCvt(curOp, curPrimType, fexpr->primType); @@ -302,6 +308,20 @@ void MirGenerator::EmitExpr(Opcode curOp, PrimType curPrimType, BaseNode *fexpr) } break; } + case OP_ireadfpoff: { + ASSERT(JAVASCRIPT, "OP_ireadfpoff in non Maple JS input"); + int32 offset = static_cast(fexpr)->offset; + // generate 4 byte instr if offset fits in 16 bits else generate 8 byte instr + if (offset <= 32767 && offset >= -32768) { + expr.param.offset = offset; + EmitAsmBaseNode(expr); + } else { + expr.op = RE_ireadfpoff32; + EmitAsmBaseNode(expr); + EmitAsmWord(offset); + } + break; + } case OP_select: FlattenExpr(fexpr); // no extra fields to handle @@ -415,6 +435,13 @@ void MirGenerator::EmitExpr(Opcode curOp, PrimType curPrimType, BaseNode *fexpr) EmitAsmBaseNode(expr); EmitAsmConststr(reinterpret_cast(fexpr)->strIdx); break; + case OP_intrinsicop: { + IntrinsicopNode *intrinsicop = (IntrinsicopNode *)fexpr; + expr.param.intrinsic.intrinsicId = intrinsicop->intrinsic; + FlattenExpr(fexpr); + EmitAsmBaseNode(expr, GetIntrinsicName(intrinsicop->intrinsic)); + break; + } default: MIR_FATAL("unknown expression opcode: [%d]:(%s)\n", fexpr->op, kOpcodeInfo.GetName(fexpr->op)); } @@ -473,6 +500,21 @@ void MirGenerator::EmitStmt(StmtNode *fstmt) { } break; } + case OP_iassignfpoff: { + ASSERT(JAVASCRIPT, "OP_iassignfpoff in non Maple JS input"); + int32 offset = static_cast(fstmt)->offset; + FlattenExpr(fstmt); + // generate 4 byte instr if offset fits in 16 bits else generate 8 byte instr + if (offset <= 32767 && offset >= -32768) { + stmt.param.offset = offset; + EmitAsmBaseNode(stmt); + } else { + stmt.op = RE_iassignfpoff32; + EmitAsmBaseNode(stmt); + EmitAsmWord(offset); + } + break; + } case OP_regassign: { string regName; FlattenExpr(fstmt); @@ -480,7 +522,11 @@ void MirGenerator::EmitStmt(StmtNode *fstmt) { ASSERT(preg, "preg is null"); regName.append("%"); regName.append(std::to_string(preg->pregNo)); - stmt.param.frameIdx = curFunc.EncodePreg(preg->pregNo); + if (JAVASCRIPT) { + stmt.param.frameIdx = preg->pregNo; + } else { + stmt.param.frameIdx = curFunc.EncodePreg(preg->pregNo); + } EmitAsmBaseNode(stmt, regName); break; } @@ -512,6 +558,11 @@ void MirGenerator::EmitStmt(StmtNode *fstmt) { EmitAsmBaseNode(stmt); EmitAsmLabel(((GotoNode *)fstmt)->offset, true); break; + case OP_gosub: + stmt.op = RE_gosub; + EmitAsmBaseNode(stmt); + EmitAsmLabel(((GotoNode *)fstmt)->offset, true); + break; case OP_rangegoto: { RangegotoNode *rNode = static_cast(fstmt); SmallCaseVector &rTable = rNode->rangegotoTable; @@ -522,9 +573,7 @@ void MirGenerator::EmitStmt(StmtNode *fstmt) { EmitAsmBaseNode(stmt); // emit base instr with num jump table entry EmitAsmWord(rNode->tagOffset); // emit tagOffset for (int i = 0; i < numCases; i++) { // emit jump table - MIRFunction *func = GetCurFunction(); - string label = "mirbin_label_"+to_string(func->puIdxOrigin)+"_"+to_string(rTable[i].second); - EmitString(".4byte "+label+"-. "+"\t// jmptbl["+to_string(rTable[i].first)+"]", 2); + EmitString(".4byte "+BuildLabelString(rTable[i].second)+"-. "+"\t// jmptbl["+to_string(rTable[i].first)+"]", 4); } break; } @@ -669,6 +718,30 @@ void MirGenerator::EmitStmt(StmtNode *fstmt) { EmitAsmBaseNode(stmt); curFunc.currentTry = nullptr; break; + case OP_cleanuptry: + case OP_finally: + case OP_retsub: + EmitAsmBaseNode(stmt); + break; + case OP_jstry: { + JsTryNode *jstry = static_cast(fstmt); + EmitAsmBaseNode(stmt); + if (jstry->catchOffset) { + EmitAsmLabel(jstry->catchOffset, true); + } else { + EmitString(".long 0", 4); + } + if (jstry->finallyOffset) { + EmitAsmLabel(jstry->finallyOffset, true); + } else { + EmitString(".long 0", 4); + } + break; + } + case OP_jscatch: { + EmitAsmBaseNode(stmt); + break; + } default: MIR_FATAL("unknown statement opcode: [%d]:(%s)\n", fstmt->op, kOpcodeInfo.GetName(fstmt->op)); } @@ -1079,46 +1152,96 @@ void MirGenerator::EmitAsmFuncInfo(MIRFunction *func) { //printf("func %d \n", func->puIdxOrigin); curFunc.Init(func); - curFunc.numFormalArgs = GetFormalsInfo(func); - curFunc.numAutoVars = GetLocalsInfo(func) + 2; // incl. %%retval0 and %%thrownval + if (!JAVASCRIPT) { + curFunc.numFormalArgs = GetFormalsInfo(func); + curFunc.numAutoVars = GetLocalsInfo(func) + 2; // incl. %%retval0 and %%thrownval + if (func->IsWeak()) curFunc.SetWeakAttr(); + if (func->IsStatic()) curFunc.SetStaticAttr(); + if (func->IsConstructor()) curFunc.SetConstructorAttr(); + if (GlobalTables::GetStrTable().GetStringFromStrIdx(func->GetBaseFuncNameStridx()) == "finalize") curFunc.SetFinalizeAttr(); + } curFunc.evalStackDepth = MaxEvalStack(func); + // insert interpreter shim and signature + if (JAVASCRIPT) { + os << "\t.ascii \"MPJS\"\n"; + os << infoLabel << ":\n"; + os << "\t" << ".long " << codeLabel << " - .\n"; + + int formalsBlkBitVectBytes = BlkSize2BitvectorSize(func->upFormalSize); + int localsBlkBitVectBytes = BlkSize2BitvectorSize(func->frameSize); + os << "\t" << ".word " << func->upFormalSize << ", " << func->frameSize << ", " << curFunc.evalStackDepth << ", " << 0 << "\t// upFormalSize, frameSize, evalStackDepth\n"; + os << "\t" << ".word " << formalsBlkBitVectBytes << ", " << localsBlkBitVectBytes << "\t\t// formalWords bit vector byte count, localWords bit vector byte count\n"; + if (formalsBlkBitVectBytes) { + EmitBytesCommentOffset(func->formalWordsTypeTagged, formalsBlkBitVectBytes, "// formalWordsTypeTagged", 0); + EmitBytesCommentOffset(func->formalWordsRefCounted, formalsBlkBitVectBytes, "// formalWordsRefCounted", 0); + } + if (localsBlkBitVectBytes) { + EmitBytesCommentOffset(func->localWordsTypeTagged, localsBlkBitVectBytes, "// localWordsTypeTagged", 0); + EmitBytesCommentOffset(func->localWordsRefCounted, localsBlkBitVectBytes, "// localWordsRefCounted", 0); + } + } else { + os << "\t.ascii \"MPLI\"\n"; + os << infoLabel << ":\n"; + os << "\t" << ".long " << codeLabel << " - .\n"; + os << "\t" << ".word " << curFunc.numFormalArgs << ", " << curFunc.numAutoVars << ", " << curFunc.evalStackDepth << ", " << curFunc.funcAttrs << " // func storage info\n"; - if (func->IsWeak()) curFunc.SetWeakAttr(); - if (func->IsStatic()) curFunc.SetStaticAttr(); - if (func->IsConstructor()) curFunc.SetConstructorAttr(); - if (GlobalTables::GetStrTable().GetStringFromStrIdx(func->GetBaseFuncNameStridx()) == "finalize") curFunc.SetFinalizeAttr(); + if (curFunc.numFormalArgs) { + os << "\t" << "// PrimType of formal arguments\n"; + } + EmitAsmFormalArgInfo(func); + if (curFunc.numAutoVars) { + os << "\t" << "// PrimType of automatic variables\n"; + } + EmitAsmAutoVarsInfo(func); - // insert interpreter shim and signature - os << "\t.ascii \"MPLI\"\n"; - os << infoLabel << ":\n"; - os << "\t" << ".long " << codeLabel << " - .\n"; - os << "\t" << ".word " << curFunc.numFormalArgs << ", " << curFunc.numAutoVars << ", " << curFunc.evalStackDepth << ", " << curFunc.funcAttrs << " // func storage info\n"; + if (curFunc.numFormalArgs) { + os << "\t" << "// Name of formal arguments\n"; + } + EmitAsmFormalArgNameInfo(func); + if (curFunc.numAutoVars) { + os << "\t" << "// Name of automatic variables\n"; + } + EmitAsmAutoVarsNameInfo(func); - if (curFunc.numFormalArgs) { - os << "\t" << "// PrimType of formal arguments\n"; - } - EmitAsmFormalArgInfo(func); - if (curFunc.numAutoVars) { - os << "\t" << "// PrimType of automatic variables\n"; + for (std::pair it : curFunc.func->aliasVarMap) { + os << "\t// ALIAS %" << GlobalTables::GetStrTable().GetStringFromStrIdx(it.first) << " %" + << GlobalTables::GetStrTable().GetStringFromStrIdx(it.second.memPoolStrIdx) << "\n"; + } } - EmitAsmAutoVarsInfo(func); - if (curFunc.numFormalArgs) { - os << "\t" << "// Name of formal arguments\n"; - } - EmitAsmFormalArgNameInfo(func); - if (curFunc.numAutoVars) { - os << "\t" << "// Name of automatic variables\n"; + os << "\t.p2align 1\n"; + os << codeLabel << ":\n"; +} + +void MirGenerator::EmitModuleInfo(void) { + EmitOpCodes(); + if (JAVASCRIPT) { + EmitGlobalDecl(); } - EmitAsmAutoVarsNameInfo(func); +} - for (std::pair it : curFunc.func->aliasVarMap) { - os << "\t// ALIAS %" << GlobalTables::GetStrTable().GetStringFromStrIdx(it.first) << " %" - << GlobalTables::GetStrTable().GetStringFromStrIdx(it.second.memPoolStrIdx) << "\n"; +void MirGenerator::EmitOpCodes(void) { + // gen opcodes - skip entry 0 (kOpUndef) and handle duplicate name (OP_dassign, OP_maydassign) + EmitStringNoTab("\nOP_dassign = 1"); + EmitStringNoTab("OP_maydassign = 2"); + for (int i = 3; i < kREOpLast; ++i) { + EmitStringNoTab(string("OP_")+RE_OpName[i]+" = "+to_string(i)); } + EmitStringNoTab(""); +} - os << "\t.p2align 1\n"; - os << codeLabel << ":\n"; +void MirGenerator::EmitGlobalDecl(void) { + os << "\t.section\t.rodata\n"; + os << "\t.p2align 3\n"; + os << "\t.global __mpljs_module_decl__\n"; + os << "__mpljs_module_decl__:\n"; + os << "\t.word " << mmodule.globalMemSize << "\t// globalMemSize byte count\n"; + if (mmodule.globalMemSize) { + EmitBytesCommentOffset(mmodule.globalBlkMap, mmodule.globalMemSize, "\t// globalMemMap", 0);; + os << "\t.word " << BlkSize2BitvectorSize(mmodule.globalMemSize) << "\t// globalwordstypetagged/refcounted byte count\n"; + EmitBytesCommentOffset(mmodule.globalWordsTypeTagged, BlkSize2BitvectorSize(mmodule.globalMemSize), "\t// globalwordstypetagged", 0); + EmitBytesCommentOffset(mmodule.globalWordsRefCounted, BlkSize2BitvectorSize(mmodule.globalMemSize), "\t// globalwordsrefcounted", 0); + } } void MirGenerator::EmitAsmBaseNode(mre_instr_t &m) { @@ -1158,7 +1281,7 @@ void MirGenerator::EmitBytes(uint8 *b, int count) { EmitString(ss.str(), count); } -void MirGenerator::EmitBytesComment(uint8 *b, int count, string &comment) { +void MirGenerator::EmitBytesCommentOffset(uint8 *b, int count, const string &comment, int offset=0) { stringstream ss; ss << ".byte "; for (int i=0; icomment.c_str() && stmt->comment.c_str()[stmt->comment.length()-1] == '\\') { + // remove trailing slash in comment line otherwuse gnu g++-5 treats next line as + // continuation of comment and skips compiling it + stmt->comment.c_str()[stmt->comment.length()-1] = 0; + } os << "\t// " << stmt->comment.data << "\n"; } @@ -1324,15 +1456,36 @@ void MirGenerator::EmitYieldPoint(void) { EmitAsmBaseNode(node); } +std::string MirGenerator::BuildLabelString(LabelIdx lbidx) { + MIRFunction *func = GetCurFunction(); + string label; + + // Many strangeness with labels if we generate labels into .s + // by the label's name in string table: + // - we get @ and | characters in name string that the assembler complains + // - duplicate name strings across different label idx in the same function + // - duplicate label idx in same function if all of CG's phases are run. + if (JAVASCRIPT){ + string labelName = func->GetLabelName(lbidx); + replace(labelName.begin(), labelName.end(), '@', '_'); + replace(labelName.begin(), labelName.end(), '|', '_'); + // cannot use puIdxOrigin because they are all 0 in js2mpl generated mpl + MIRSymbol *fnSt = GlobalTables::GetGsymTable().GetSymbolFromStIdx(func->stIdx.Idx()); + label = "mirbin_label_"+fnSt->GetName()+"_"+labelName; + } else { + label = "mirbin_label_"+ to_string(func->puIdxOrigin)+"_"+to_string(lbidx); + } + return label; +} + void MirGenerator::EmitAsmLabel(LabelIdx lbidx, bool genOffset) { MIRFunction *func = GetCurFunction(); - string label = "mirbin_label_"+to_string(func->puIdxOrigin)+"_"+to_string(lbidx); // TODO: fix issue - currently have to disable fpm->run in CG to avoid duplicate labels if (genOffset) { - EmitString(".long "+label+"-.", 4); + EmitString(".long "+BuildLabelString(lbidx)+"-.", 4); } else { - os << label+":\n"; + os << BuildLabelString(lbidx)+":\n"; } } @@ -1352,14 +1505,13 @@ void MirGenerator::EmitAsmConststr(UStrIdx strIdx) { } RE_Opcode MirGenerator::MapEHOpcode(RE_Opcode op) { - MIRModule *module = GetCurFunction()->module; - if (module->IsCModule()) { + if (CLANG) { if (op == RE_catch) { op = RE_cppcatch; } else if (op == RE_try) { op = RE_cpptry; } - } else if (module->IsJavaModule()) { + } else if (JAVALANG) { if (op == RE_catch) { op = RE_javacatch; } else if (op == RE_try) { diff --git a/mapleall/maple_be/src/cg/cfg_optimizer.cpp b/mapleall/maple_be/src/cg/cfg_optimizer.cpp index 0b4f345a4ae0ab972dc899d95a5c8ac3d656b4c0..58dbce10cddb02a3a8af457052c1e31648b012bc 100644 --- a/mapleall/maple_be/src/cg/cfg_optimizer.cpp +++ b/mapleall/maple_be/src/cg/cfg_optimizer.cpp @@ -229,7 +229,7 @@ bool ChainingPattern::Optimize(BB *&curbb) { } Insn *brInsn = nullptr; for (brInsn = curbb->lastinsn; brInsn != curbb->firstinsn->prev; brInsn = brInsn->prev) { - if (brInsn->mop_ == MOP_xuncond) { + if (brInsn->IsUncondBranch()) { break; } } @@ -239,7 +239,7 @@ bool ChainingPattern::Optimize(BB *&curbb) { if (newTarget->GetKind() == BB::kBBGoto) { Insn *br = nullptr; for (br = newTarget->lastinsn; br != newTarget->firstinsn->prev; br = brInsn->prev) { - if (br->mop_ == MOP_xuncond) { + if (br->IsUncondBranch()) { break; } } @@ -380,7 +380,7 @@ bool FlipBRPattern::Optimize(BB *&curbb) { Insn *brInsn = nullptr; for (brInsn = ftBB->lastinsn; brInsn != ftBB->firstinsn->prev; brInsn = brInsn->prev) { #if !TARGARK - if (brInsn->mop_ == MOP_xuncond) { + if (brInsn->IsUncondBranch()) { break; } #endif diff --git a/mapleall/maple_be/src/cg/cfi.cpp b/mapleall/maple_be/src/cg/cfi.cpp index 577226f9442b9ed6d890a6d516b7274c7692e250..afbd63b5e8588af51bd7d57918417ed4817ca507 100644 --- a/mapleall/maple_be/src/cg/cfi.cpp +++ b/mapleall/maple_be/src/cg/cfi.cpp @@ -98,7 +98,7 @@ void StrOperand::dump() { } void LabelOperand::Emit(Emitter &emitter, OpndProp *opndprop) { - const char *idx = std::to_string(CG::curPuIdx).c_str(); + const char *idx = strdup(std::to_string(CG::curPuIdx).c_str()); emitter.Emit(".label.").Emit(idx).Emit("__").Emit(labidx_); } diff --git a/mapleall/maple_be/src/cg/cg.cpp b/mapleall/maple_be/src/cg/cg.cpp index 26441e7ec9d68baabdb593e8b49c1189ca3dc745..cd1c0aaf44ca1abd158f1fc2cb1f2cc0e6187654 100644 --- a/mapleall/maple_be/src/cg/cg.cpp +++ b/mapleall/maple_be/src/cg/cg.cpp @@ -39,6 +39,7 @@ const char *BB::bbNames[BB::kBBLast] = { "BB_ft", "BB_if", "BB_goto", CGFunc *CG::curCgFunc = nullptr; PUIdx CG::curPuIdx = 0; +std::map> CG::funcWrapLabels; const char *CG::kCMacroDefSuffix = ".macros.def"; const char *CG::kGctibSuffix = ".gctib.s"; diff --git a/mapleall/maple_be/src/cg/cg_driver.cpp b/mapleall/maple_be/src/cg/cg_driver.cpp index e358e0892185e73c1d4ee84b0e884bf03c7aee1a..4cff699a0f992a16ba696a444ad533b6f41c795a 100644 --- a/mapleall/maple_be/src/cg/cg_driver.cpp +++ b/mapleall/maple_be/src/cg/cg_driver.cpp @@ -113,6 +113,11 @@ int main(int argc, char **argv) { fpm.RegisterFuncPhases(); /*scan cg_phases.def and create phase object */ fpm.SetCgPhase(kCgPhaseMainopt); + // generate debuginfo + if (cgoption.WithDwarf()) { + themodule->dbgInfo->BuildDebugInfo(); + } + std::string::size_type lastdot = fileName.find_last_of("."); std::string output; std::string basename; @@ -172,9 +177,14 @@ int main(int argc, char **argv) { } if (cgoption.run_cg_flag) { - // 1. LowerIR. - thecg.LowerIR(); +#if TARGARK + if (!themodule->IsJsModule()) { +#endif + thecg.LowerIR(); +#if TARGARK + } +#endif // 2. Generate the output file BECommon &becommon = *g->becommon; @@ -189,13 +199,10 @@ int main(int argc, char **argv) { mirGen->OutputMIR(cgoption.genMirMpl); thecg.emitter_->mirg_ = mirGen; - // gen opcodes - skip entry 0 (kOpUndef) and handle duplicate name (OP_dassign, OP_maydassign) - thecg.emitter_->Emit("\nOP_dassign = 1\n"); - thecg.emitter_->Emit("OP_maydassign = 2\n"); - for (int i = 3; i < kREOpLast; ++i) { - thecg.emitter_->Emit(string("OP_")+RE_OpName[i]+" = "+to_string(i)+"\n"); + mirGen->EmitOpCodes(); + if (themodule->IsJsModule()) { + mirGen->EmitGlobalDecl(); } - // load profile info for class meta data - uses same binary metadata profile (meta.list) as mpl2mpl uint32 javaNameIdx = themodule->GetFileinfo(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName("INFO_filename")); const std::string &javaName = GlobalTables::GetStrTable().GetStringFromStrIdx(GStrIdx(javaNameIdx)); diff --git a/mapleall/maple_be/src/cg/cg_func.cpp b/mapleall/maple_be/src/cg/cg_func.cpp index 3b47d0f6f49e29870cb3c45a9ae3e0c571013f97..1b586ad44c06fc43fa449662696e2c42bcb4c7cd 100644 --- a/mapleall/maple_be/src/cg/cg_func.cpp +++ b/mapleall/maple_be/src/cg/cg_func.cpp @@ -169,6 +169,10 @@ void CGFunc::CreateStartEndLabel() { fdie->SetAttr(DW_AT_low_pc, startLblidx); fdie->SetAttr(DW_AT_high_pc, endLblidx); } + // add start/end labels into the static map table in class cg + auto it = CG::funcWrapLabels.find(func); + CG_ASSERT(it == CG::funcWrapLabels.end(), ""); + CG::funcWrapLabels[func] = make_pair(startLblidx, endLblidx); } void CGFunc::HandleLabel(LabelNode *stmt) { @@ -1046,7 +1050,6 @@ void CGFunc::HandleFunction(void) { for (; stmt; stmt = stmt->GetNext()) { needSplit = false; // insert Insn for .loc before cg for the stmt - //stmt->Dump(func->module,0); if (cg->cgopt_.WithLoc() && stmt->op != OP_label && stmt->op != OP_comment) { // if original src file location info is availiable for this stmt, // use it and skip mpl file location info for this stmt @@ -1059,17 +1062,16 @@ void CGFunc::HandleFunction(void) { Insn *loc = cg->BuildInstruction(mpldbg::OP_DBG_loc, o0, o1); curbb->AppendInsn(loc); lastsrcloc = newsrcloc; - } else { - // .loc for mpl file - uint32 newmplloc = cg->cgopt_.WithMpl() ? stmt->srcPosition.MplLinenum() : 0; - if (newmplloc != 0 && newmplloc != lastmplloc) { - uint32 fileid = 1; - Operand *o0 = CreateDbgImmOperand(fileid); - Operand *o1 = CreateDbgImmOperand(newmplloc); - Insn *loc = cg->BuildInstruction(mpldbg::OP_DBG_loc, o0, o1); - curbb->AppendInsn(loc); - lastmplloc = newmplloc; - } + } + // .loc for mpl file + uint32 newmplloc = cg->cgopt_.WithMpl() ? stmt->srcPosition.MplLinenum() : 0; + if (newmplloc != 0 && newmplloc != lastmplloc) { + uint32 fileid = 1; + Operand *o0 = CreateDbgImmOperand(fileid); + Operand *o1 = CreateDbgImmOperand(newmplloc); + Insn *loc = cg->BuildInstruction(mpldbg::OP_DBG_loc, o0, o1); + curbb->AppendInsn(loc); + lastmplloc = newmplloc; } } isVolLoad = false; diff --git a/mapleall/maple_be/src/cg/emit.cpp b/mapleall/maple_be/src/cg/emit.cpp index f94eef2d3ac021ed9cf31a65a82c061867b85090..c9e63089c92cf8cd1b4546133a48b53cc4e62aab 100644 --- a/mapleall/maple_be/src/cg/emit.cpp +++ b/mapleall/maple_be/src/cg/emit.cpp @@ -51,7 +51,7 @@ void Emitter::EmitBBHeaderLabel(const char * funcName, const char * lineCommentH cgFunc.cg->label_order_cnt_++; } - const char *puIdx = std::to_string(CG::curPuIdx).c_str(); + const char *puIdx = strdup(std::to_string(CG::curPuIdx).c_str()); const std::string& labelName = cgFunc.func->labelTab->GetName(labelIdx); Emit(".label.").Emit(puIdx).Emit("__").Emit(labelIdx).Emit(":\t\t") @@ -73,6 +73,11 @@ void Emitter::EmitLabelPair(const char *name, const LabelPair &pairlabel) { out << "\n"; } +void Emitter::EmitLabelForFunc(MIRFunction *func, LabelIdx labidx) { + const char *idx = static_cast(strdup(std::to_string(func->puIdx).c_str())); + out << ".label." << idx << "__" << labidx; +} + Asmlabel Emitter::GetTypeAsmInfoName(PrimType pty) { uint32 size = GetPrimTypeSize(pty); switch (size) { @@ -128,6 +133,9 @@ void Emitter::EmitFileInfo(const std::string &fileName) { Emit(irFile.c_str()); Emit("\n"); + // save directory path in index 0 + fileMap[0] = path; + // .file #num src_file_name if (cg_->cgopt_.WithLoc()) { if (cg_->cgopt_.WithAsm()) { @@ -138,8 +146,10 @@ void Emitter::EmitFileInfo(const std::string &fileName) { Emit("1 "); Emit(irFile.c_str()); Emit("\n"); + fileMap[1] = irFile; if (cg_->cgopt_.WithSrc()) { // insert a list of src files + int i = 2; for (auto it : cg_->mirModule->srcFileInfo) { if (cg_->cgopt_.WithAsm()) { Emit("\t// "); @@ -149,6 +159,7 @@ void Emitter::EmitFileInfo(const std::string &fileName) { const std::string kStr = GlobalTables::GetStrTable().GetStringFromStrIdx(it.first); Emit(kStr.c_str()); Emit("\"\n"); + fileMap[i++] = kStr; } } } @@ -976,7 +987,6 @@ void Emitter::EmitConstantTable(MIRSymbol *st, MIRConst *ct, const std::mapIsReflectionMethodInfoCompact() && i == static_cast(METHOD_COMPACT::kMod)) { MIRAddroffuncConst *funcaddr = dynamic_cast(aggconst->constVec[METHOD_COMPACT::kAddr]); if (funcaddr) { - const char *idx = std::to_string(GlobalTables::GetFunctionTable().GetFunctionFromPuidx(funcaddr->GetValue())->puIdx).c_str(); Emit(".label.name." + GlobalTables::GetFunctionTable().GetFunctionFromPuidx(funcaddr->GetValue())->GetName()); Emit(":\n"); } @@ -1948,7 +1958,9 @@ void Emitter::EmitGlobalVariable() { } else { EmitAsmLabel(st, kAsmGlbl); } - EmitAsmLabel(st, kAsmHidden); + if (!cg_->mirModule->IsCModule() ) { + EmitAsmLabel(st, kAsmHidden); + } } else if (st->storageClass == kScFstatic) { EmitAsmLabel(st, kAsmLocal); } diff --git a/mapleall/maple_be/src/cg/emit_dbg.cpp b/mapleall/maple_be/src/cg/emit_dbg.cpp index 43b903cd763460c5f59033c5bba164f29d4ad2d3..98cce27892d71f033b01ed11cb1ce2f21957aab2 100644 --- a/mapleall/maple_be/src/cg/emit_dbg.cpp +++ b/mapleall/maple_be/src/cg/emit_dbg.cpp @@ -19,8 +19,15 @@ #include "cg_assert.h" #include "be_common.h" // SIZEOFPTR #include "global_tables.h" +#include "mir_builder.h" #include "mir_symbol.h" +#if TARGRISCV64 +#define CMNT "\t# " +#else +#define CMNT "\t// " +#endif + namespace maple { const char *get_DW_TAG_name(unsigned n); const char *get_DW_FORM_name(unsigned n); @@ -131,9 +138,9 @@ void Emitter::EmitDIFooter() { } void Emitter::EmitDIHeaderFileInfo() { - Emit("// dummy header file 1\n"); - Emit("// dummy header file 2\n"); - Emit("// dummy header file 3\n"); + Emit(CMNT "dummy header file 1\n"); + Emit(CMNT "dummy header file 2\n"); + Emit(CMNT "dummy header file 3\n"); } void Emitter::AddLabelDieToLabelIdxMapping(DBGDie *lbldie, LabelIdx lblidx) { @@ -239,7 +246,7 @@ void Emitter::EmitDIAttrValue(DBGDie *die, DBGDieAttr *attr, dw_at attrName, dw_ case DW_FORM_string: { const string &name = GlobalTables::GetStrTable().GetStringFromStrIdx(attr->val_.id); Emit("\"").Emit(name).Emit("\""); - Emit("\t// len = "); + Emit(CMNT "len = "); EmitDecUnsigned(name.length() + 1); } break; case DW_FORM_strp: @@ -284,11 +291,24 @@ void Emitter::EmitDIAttrValue(DBGDie *die, DBGDieAttr *attr, dw_at attrName, dw_ } CHECK_FATAL(name != nullptr, "name is null in Emitter::EmitDIAttrValue"); const string &str = GlobalTables::GetStrTable().GetStringFromStrIdx(name->val_.id); - EmitLabelRef(str.c_str(), attr->val_.id); + + MIRBuilder *mirbuilder = cg_->mirModule->mirBuilder; + MIRFunction *mfunc = mirbuilder->GetFunctionFromName(str); + MapleMap >::iterator it = + CG::funcWrapLabels.find(mfunc); + if (it != CG::funcWrapLabels.end()) { + EmitLabelForFunc(mfunc, (*it).second.second); // end label + } else { + EmitLabelRef(str.c_str(), attr->val_.id); // maybe deadbeef + } Emit("-"); - DBGDieAttr *lowpc = LFindAttribute(attrvec, DW_AT_low_pc); - CHECK_FATAL(lowpc != nullptr, "lowpc is null in Emitter::EmitDIAttrValue"); - EmitLabelRef(str.c_str(), lowpc->val_.id); + if (it != CG::funcWrapLabels.end()) { + EmitLabelForFunc(mfunc, (*it).second.first); // start label + } else { + DBGDieAttr *lowpc = LFindAttribute(attrvec, DW_AT_low_pc); + CHECK_FATAL(lowpc != nullptr, "lowpc is null in Emitter::EmitDIAttrValue"); + EmitLabelRef(str.c_str(), lowpc->val_.id); // maybe deadbeef + } } } else { EmitHexUnsigned(attr->val_.i); @@ -315,7 +335,15 @@ void Emitter::EmitDIAttrValue(DBGDie *die, DBGDieAttr *attr, dw_at attrName, dw_ } CHECK_FATAL(name != nullptr, "name is null in Emitter::EmitDIAttrValue"); const string &str = GlobalTables::GetStrTable().GetStringFromStrIdx(name->val_.id); - EmitLabelRef(str.c_str(), attr->val_.id); + MIRBuilder *mirbuilder = cg_->mirModule->mirBuilder; + MIRFunction *mfunc = mirbuilder->GetFunctionFromName(str); + MapleMap >::iterator + it = CG::funcWrapLabels.find(mfunc); + if (it != CG::funcWrapLabels.end()) { + EmitLabelForFunc(mfunc, (*it).second.first); // it is a + } else { + EmitLabelRef(str.c_str(), attr->val_.id); // maybe deadbeef + } } else if (tagName == DW_TAG_label) { LabelIdx labelIdx = GetLabelIdxForLabelDie(die); DBGDie *subpgm = die->parent; @@ -348,7 +376,7 @@ void Emitter::EmitDIAttrValue(DBGDie *die, DBGDieAttr *attr, dw_at attrName, dw_ } else { // unknown type, missing mplt EmitHexUnsigned(di->dummytypedie_->Offset); - Emit("\t// Warning: dummy type used"); + Emit(CMNT "Warning: dummy type used"); } } else if (attrName == DW_AT_specification || attrName == DW_AT_sibling) { DBGDie *die = di->GetDie(attr->val_.u); @@ -414,7 +442,7 @@ void Emitter::EmitDIDebugInfoSection(DebugInfo *mirdi) { // $ 7.5.1.1 Emit("\t.4byte\t"); EmitHexUnsigned(mirdi->debug_info_length_); - Emit(" // section length\n"); + Emit(CMNT "section length\n"); // DWARF version. uhalf. Emit("\t.2byte\t0x" XSTR(DWARF_VERSION) "\n"); // 4 for version 4. // debug_abbrev_offset. 4byte for 32-bit, 8byte for 64-bit @@ -442,7 +470,7 @@ void Emitter::EmitDIDebugInfoSection(DebugInfo *mirdi) { emitter->Emit("\t.uleb128 "); emitter->EmitHexUnsigned(die->abbrevid_); if (verbose) { - emitter->Emit("\t// "); + emitter->Emit(CMNT); CHECK_FATAL(maple::get_DW_TAG_name(die->tag_) != nullptr, "get_DW_TAG_name(die->tag_) return null in Emitter::EmitDIDebugInfoSection"); emitter->Emit(maple::get_DW_TAG_name(die->tag_)); @@ -462,16 +490,37 @@ void Emitter::EmitDIDebugInfoSection(DebugInfo *mirdi) { CHECK_FATAL(diae != nullptr, "diae is null in Emitter::EmitDIDebugInfoSection"); MapleVector &apl = diae->attrpairs_; // attribute pair list + string sfile, spath; + if (diae->tag_ == DW_TAG_compile_unit && sfile.empty()) { + // get full source path from fileMap[2] + string srcPath = emitter->fileMap[2]; + size_t t = srcPath.rfind("/"); + CG_ASSERT(t != string::npos, ""); + sfile = srcPath.substr(t+1); + spath = srcPath.substr(0, t-1); + } + for (int i = 0; i < diae->attrpairs_.size(); i += 2) { DBGDieAttr *attr = LFindAttribute(die->attrvec_, dw_at(apl[i])); if (!LShouldEmit(unsigned(apl[i + 1]))) { continue; } + // update DW_AT_name and DW_AT_comp_dir attrs under DW_TAG_compile_unit + // to be C/C++ + if (!sfile.empty()) { + if (attr->dwattr_ == DW_AT_name) { + attr->val_.id = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(sfile).GetIdx(); + emitter->cg_->mirModule->dbgInfo->strps_.insert(attr->val_.id); + } else if (attr->dwattr_ == DW_AT_comp_dir) { + attr->val_.id = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(spath).GetIdx(); + emitter->cg_->mirModule->dbgInfo->strps_.insert(attr->val_.id); + } + } emitter->Emit("\t"); emitter->EmitDIFormSpecification(unsigned(apl[i + 1])); emitter->EmitDIAttrValue(die, attr, unsigned(apl[i]), diae->tag_, mirdi); if (verbose) { - emitter->Emit("\t// "); + emitter->Emit(CMNT); emitter->Emit(maple::get_DW_AT_name(unsigned(apl[i]))); emitter->Emit(" : "); emitter->Emit(maple::get_DW_FORM_name(unsigned(apl[i + 1]))); @@ -508,7 +557,7 @@ void Emitter::EmitDIDebugAbbrevSection(DebugInfo *mirdi) { Emit("\t.uleb128 "); EmitHexUnsigned(diae->abbrevid_); if (verbose) { - Emit("\t// Abbrev Entry ID"); + Emit(CMNT "Abbrev Entry ID"); } Emit("\n"); // TAG @@ -517,7 +566,7 @@ void Emitter::EmitDIDebugAbbrevSection(DebugInfo *mirdi) { CHECK_FATAL(maple::get_DW_TAG_name(diae->tag_) != nullptr, "get_DW_TAG_name return null in Emitter::EmitDIDebugAbbrevSection"); if (verbose) { - Emit("\t// "); + Emit(CMNT); Emit(maple::get_DW_TAG_name(diae->tag_)); } Emit("\n"); @@ -527,7 +576,7 @@ void Emitter::EmitDIDebugAbbrevSection(DebugInfo *mirdi) { Emit("\t.byte "); EmitHexUnsigned(diae->withchildren_); if (verbose) { - Emit(diae->withchildren_ ? "\t// DW_CHILDREN_yes" : "\t// DW_CHILDREN_no"); + Emit(diae->withchildren_ ? CMNT "DW_CHILDREN_yes" : CMNT "DW_CHILDREN_no"); } Emit("\n"); @@ -538,7 +587,7 @@ void Emitter::EmitDIDebugAbbrevSection(DebugInfo *mirdi) { CHECK_FATAL(maple::get_DW_AT_name(unsigned(apl[i])) != nullptr, "get_DW_AT_name return null in Emitter::EmitDIDebugAbbrevSection"); if (verbose) { - Emit("\t// "); + Emit(CMNT); Emit(maple::get_DW_AT_name(unsigned(apl[i]))); } Emit("\n"); @@ -547,7 +596,7 @@ void Emitter::EmitDIDebugAbbrevSection(DebugInfo *mirdi) { CHECK_FATAL(maple::get_DW_FORM_name(unsigned(apl[i + 1])) != nullptr, "get_DW_FORM_name return null in Emitter::EmitDIDebugAbbrevSection"); if (verbose) { - Emit("\t// "); + Emit(CMNT); Emit(maple::get_DW_FORM_name(unsigned(apl[i + 1]))); } Emit("\n"); diff --git a/mapleall/maple_be/src/cg/riscv64/riscv64_abi.cpp b/mapleall/maple_be/src/cg/riscv64/riscv64_abi.cpp index 4194bd5bdb394f83451e33dadb45bbb33401192c..39999d78bf11bb5373ee6b7cd91cfd06f478e61b 100644 --- a/mapleall/maple_be/src/cg/riscv64/riscv64_abi.cpp +++ b/mapleall/maple_be/src/cg/riscv64/riscv64_abi.cpp @@ -491,6 +491,17 @@ int32 ParmLocator::LocateNextParm(MIRType *ty, PLocInfo &ploc, bool isFirst, boo return aggCopySize; } +void ParmLocator::LocateCallNodeParm(MIRType *ty, PLocInfo &ploc, uint32 retSize, bool isFirst, bool isVararg) { + if (isFirst && retSize > 16) { + InitPlocInfo(ploc); + ploc.reg0 = AllocateGPRegister(); + return; + } else { + LocateNextParm(ty, ploc, isFirst && retSize > 16, isVararg); + return; + } +} + // instantiated with the type of the function return value, it describes how // the return value is to be passed back to the caller ReturnMechanism::ReturnMechanism(MIRType *retty, BECommon &be) diff --git a/mapleall/maple_be/src/cg/riscv64/riscv64_cg.cpp b/mapleall/maple_be/src/cg/riscv64/riscv64_cg.cpp index c70f351ccc1d3d1d86a67bf16f8b1c3caa27bc8f..fd85e0055d4ba87c060aafa3ec9afe3b7b09c2e6 100644 --- a/mapleall/maple_be/src/cg/riscv64/riscv64_cg.cpp +++ b/mapleall/maple_be/src/cg/riscv64/riscv64_cg.cpp @@ -319,6 +319,10 @@ bool Riscv64Insn::IsDestRegAlsoSrcReg() const { return prop0->IsRegDef() && prop0->IsRegUse(); } +bool Riscv64Insn::IsUncondBranch() const { + return (mop_ == MOP_xbr || mop_ == MOP_xuncond); +} + bool Riscv64Insn::IsDataMoveInstruction() const { return ((Riscv64CG::kMd[mop_].properties_ & ISMOVE) != 0); } diff --git a/mapleall/maple_be/src/cg/riscv64/riscv64_cg_func.cpp b/mapleall/maple_be/src/cg/riscv64/riscv64_cg_func.cpp index b1487a78c6b9b83879f3bf86bfb0bdee0b2dbef3..c0cc29b3ee1e6319dcba492278660a7d83294a47 100644 --- a/mapleall/maple_be/src/cg/riscv64/riscv64_cg_func.cpp +++ b/mapleall/maple_be/src/cg/riscv64/riscv64_cg_func.cpp @@ -852,7 +852,11 @@ void Riscv64CGFunc::AppendInstructionDeallocateCallFrame(Riscv64reg_t reg0, Risc } Operand *spOpnd = GetOrCreatePhysicalRegisterOperand(RSP, 64, kRegTyInt); Operand *immopnd = CreateImmOperand(stackFrameSize, 32, true); - SelectAdd(spOpnd, spOpnd, immopnd, PTY_u64); + Operand *offset = FixLargeStackOffset(static_cast(immopnd)); + if (offset == nullptr) { + offset = immopnd; + } + SelectAdd(spOpnd, spOpnd, offset, PTY_u64); } else { Insn *deallocInsn = cg->BuildInstruction(mop, o0, o1, o2); curbb->AppendInsn(deallocInsn); @@ -887,7 +891,11 @@ void Riscv64CGFunc::AppendInstructionDeallocateCallFrameDebug(Riscv64reg_t reg0, curbb->AppendInsn(cg->BuildInstruction(cfi::OP_CFI_restore, CreateCfiRegOperand(RRA, 64))); Operand *spOpnd = GetOrCreatePhysicalRegisterOperand(RSP, 64, kRegTyInt); Operand *immopnd = CreateImmOperand(stackFrameSize, 32, true); - SelectAdd(spOpnd, spOpnd, immopnd, PTY_u64); + Operand *offset = FixLargeStackOffset(static_cast(immopnd)); + if (offset == nullptr) { + offset = immopnd; + } + SelectAdd(spOpnd, spOpnd, offset, PTY_u64); } else { RegOperand *rsp = GetOrCreatePhysicalRegisterOperand(RSP, SIZEOFPTR * 8, kRegTyInt); Riscv64OfstOperand *ofopnd = GetOrCreateOfstOpnd(0, 32); @@ -901,8 +909,15 @@ void Riscv64CGFunc::AppendInstructionDeallocateCallFrameDebug(Riscv64reg_t reg0, curbb->AppendInsn(deallocInsn); curbb->AppendInsn(cg->BuildInstruction(cfi::OP_CFI_restore, CreateCfiRegOperand(RRA, 64))); // Restore old sp + MOperator mop = MOP_xaddrri12; ImmOperand *iopnd = CreateImmOperand(stackFrameSize, 32, true); - Insn *spAdd = cg->BuildInstruction(MOP_xaddrri12, rsp, rsp, iopnd); + Operand *offset = FixLargeStackOffset(iopnd); + if (offset) { + mop = MOP_xaddrrr; + } else { + offset = iopnd; + } + Insn *spAdd = cg->BuildInstruction(mop, rsp, rsp, offset); curbb->AppendInsn(spAdd); } @@ -960,7 +975,11 @@ void Riscv64CGFunc::AppendInstructionDeallocateCallFrameDebug(Riscv64reg_t reg0, Operand *spOpnd = GetOrCreatePhysicalRegisterOperand(RSP, 64, kRegTyInt); Operand *immopnd = CreateImmOperand(stackFrameSize, 32, true); - SelectAdd(spOpnd, spOpnd, immopnd, PTY_u64); + Operand *offset = FixLargeStackOffset(static_cast(immopnd)); + if (offset == nullptr) { + offset = immopnd; + } + SelectAdd(spOpnd, spOpnd, offset, PTY_u64); } } @@ -1138,6 +1157,17 @@ void Riscv64CGFunc::GeneratePopRegs() { split_stpldp_base_offset = 0; } +Operand *Riscv64CGFunc::FixLargeStackOffset(ImmOperand *iopnd) { + if (static_cast(iopnd)->IsInSimmBitSize(11) == false) { + // Cannot use kIntSpareReg here since all registers have been restored in epilog + Riscv64RegOperand *dst = GetOrCreatePhysicalRegisterOperand(R31, 64, kRegTyInt); + Insn *li = cg->BuildInstruction(MOP_xmovri64, dst, CreateImmOperand(iopnd->GetValue(), 64, false)); + curbb->AppendInsn(li); + return dst; + } + return nullptr; +} + void Riscv64CGFunc::Genstackguard(BB *bb) { if (cg->AddStackGuard()) { BB *formerCurbb = curbb; @@ -2017,10 +2047,10 @@ void Riscv64CGFunc::GenerateProlog(BB * bb) { if (cg->cgopt_.WithSrc()) { uint32 tempmaxsize = mirModule.srcFileInfo.size(); uint32 endfilenum = mirModule.srcFileInfo[tempmaxsize - 1].second; - if (func->srcPosition.Filenum() != 0 && func->srcPosition.Filenum() <= endfilenum) { - Operand *o0 = CreateDbgImmOperand(func->srcPosition.Filenum()); + if (func->GetFuncSymbol()->srcPosition.Filenum() != 0 && func->GetFuncSymbol()->srcPosition.Filenum() <= endfilenum) { + Operand *o0 = CreateDbgImmOperand(func->GetFuncSymbol()->srcPosition.Filenum()); // Operand *o1 = CreateDbgImmOperand((func->srcPosition->Linenum() ? func->srcPosition->Linenum() : 1)); - int64_t lineNum = func->srcPosition.Linenum(); + int64_t lineNum = func->GetFuncSymbol()->srcPosition.Linenum(); if (lineNum == 0) { if (func->funcAttrs.GetAttr(FUNCATTR_native)) { lineNum = 0xffffe; @@ -2036,7 +2066,7 @@ void Riscv64CGFunc::GenerateProlog(BB * bb) { Operand *o0 = CreateDbgImmOperand(1); // line number might not be available. //CG_ASSERT(func->srcPosition.MplLinenum(), "return check"); - Operand *o1 = CreateDbgImmOperand(func->srcPosition.MplLinenum()); + Operand *o1 = CreateDbgImmOperand(func->GetFuncSymbol()->srcPosition.MplLinenum()); Insn *loc = cg->BuildInstruction(mpldbg::OP_DBG_loc, o0, o1); curbb->AppendInsn(loc); } @@ -2116,6 +2146,16 @@ void Riscv64CGFunc::GenerateProlog(BB * bb) { } void Riscv64CGFunc::GenerateRet(BB * bb) { + MOperator mop; + Riscv64reg_t preg; + if (retRegType == kRegTyInt) { + mop = MOP_pseudo_ret_int; + preg = R10; + } else { + mop = MOP_pseudo_ret_float; + preg = V10; + } + bb->AppendInsn(cg->BuildInstruction(mop, GetOrCreatePhysicalRegisterOperand(preg, 64, kRegTyInt))); bb->AppendInsn(cg->BuildInstruction(MOP_xret)); } @@ -2244,12 +2284,9 @@ bool Riscv64CGFunc::TailCallOpt() { CG_ASSERT(regsToRestore.size() >= 2, "Forgot FP and LR ?"); - if ((mirModule.IsCModule()) && - static_cast(memlayout)->locals().size > 0) { - return false; - } - - if (CLANG && func->GetAttr(FUNCATTR_varargs)) { + if (CLANG && + ((static_cast(memlayout)->locals().size > 0) || + func->GetAttr(FUNCATTR_varargs) || HasVLAOrAlloca())) { return false; } @@ -3524,6 +3561,12 @@ bool Riscv64CGFunc::CallIsVararg(StmtNode *narynode, uint32 &namedFormals, BB *b }; varargFunc = fType->isVarArgs; namedFormals = fType->paramTypeList.size(); + } else if (fNode->op == OP_retype) { + RetypeNode *rNode = static_cast(fNode); + pType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(rNode->tyIdx)); + fType = static_cast(pType->GetPointedType()); + varargFunc = fType->isVarArgs; + namedFormals = fType->paramTypeList.size(); } else { CG_ASSERT(0, "cannot process this icall"); } @@ -3671,7 +3714,7 @@ void Riscv64CGFunc::SelectParmList(StmtNode * narynode, Riscv64ListOperand * src expregopnd = static_cast(opnd); } - parmlocator.LocateNextParm(ty, ploc, pnum == 0 && retSize > 16, variadArg); + parmlocator.LocateCallNodeParm(ty, ploc, retSize, pnum == 0, variadArg); if (ploc.reg0 != 0) { // load to the register Riscv64RegOperand *parmregopnd = nullptr; if (islockcall && i == 1) { @@ -4146,16 +4189,31 @@ void Riscv64CGFunc::SelectReturn(NaryStmtNode * stmt, Operand * opnd0) { if (retmech.regcount > 0) { if (RegOperand *regopnd = dynamic_cast(opnd0)) { if (regopnd->GetRegisterNumber() != retmech.reg0) { + if (Riscv64isa::IsGPRegister(retmech.reg0)) { + retRegType = kRegTyInt; + } else { + retRegType = kRegTyFloat; + } retopnd = GetOrCreatePhysicalRegisterOperand(retmech.reg0, regopnd->size_, GetRegTyFromPrimTyRiscv64(retmech.ptype0)); SelectCopy(retopnd, retmech.ptype0, regopnd, retmech.ptype0); } } else if (Riscv64MemOperand *memopnd = dynamic_cast(opnd0)) { + if (IsPrimitivePureScalar(retmech.ptype0)) { + retRegType = kRegTyInt; + } else { + retRegType = kRegTyFloat; + } retopnd = GetOrCreatePhysicalRegisterOperand(retmech.reg0, GetPrimTypeBitSize(retmech.ptype0), GetRegTyFromPrimTyRiscv64(retmech.ptype0)); MOperator mop = PickLdInsn(memopnd->size_, retmech.ptype0); curbb->AppendInsn(cg->BuildInstruction(mop, retopnd, memopnd)); } else if (opnd0->IsConstImmediate()) { + if (IsPrimitivePureScalar(retmech.ptype0)) { + retRegType = kRegTyInt; + } else { + retRegType = kRegTyFloat; + } ImmOperand *immopnd = static_cast(opnd0); retopnd = GetOrCreatePhysicalRegisterOperand(retmech.reg0, GetPrimTypeBitSize(retmech.ptype0), GetRegTyFromPrimTyRiscv64(retmech.ptype0)); @@ -4406,7 +4464,7 @@ MemOperand *Riscv64CGFunc::GetOrCreateMemOpnd(MIRSymbol * symbol, int32 offset, there is no need to repeat the offset in the actual mem opnd. */ return memPool->New(size, staddropnd, - static_cast(nullptr), GetOrCreateOfstOpnd(0, 32), symbol); + static_cast(nullptr), GetOrCreateOfstOpnd(0, 32), nullptr); } else { CG_ASSERT(false, "NYI"); } @@ -4613,6 +4671,11 @@ void Riscv64CGFunc::SelectLibCall(const char *name, vector &opndvec, } curbb->AppendInsn(callInsn); func->SetHasCall(); + curbb->SetKind(BB::kBBCall); + BB *newbb = CreateNewBB(); + curbb->AppendBB(newbb); + curbb = newbb; + // get return value Operand *opnd0 = opndvec[0]; ReturnMechanism retmech(GlobalTables::GetTypeTable().typeTable.at(retprmtype), becommon); @@ -4788,7 +4851,7 @@ void Riscv64CGFunc::InsertJumpPad(Insn *insn) { } LabelOperand *targetLabelOpnd = GetOrCreateLabelOperand(targetLabel); padBB->AppendInsn(cg->BuildInstruction(MOP_laddr, targetAddr, targetLabelOpnd)); - padBB->AppendInsn(cg->BuildInstruction(MOP_xbr, targetAddr)); + padBB->AppendInsn(cg->BuildInstruction(MOP_xbr, targetAddr, targetLabelOpnd)); padBB->SetKind(BB::kBBIgoto); padBB->preds.push_back(bb); padBB->succs.push_back(targetBB); @@ -4808,7 +4871,7 @@ void Riscv64CGFunc::ConvertJumpToRegJump(Insn *insn) { Insn *loadLabelInsn = cg->BuildInstruction(MOP_laddr, targetAddr, targetLabelOpnd); bb->InsertInsnBefore(insn, loadLabelInsn); - Insn *regJumpInsn = cg->BuildInstruction(MOP_xbr, targetAddr); + Insn *regJumpInsn = cg->BuildInstruction(MOP_xbr, targetAddr, targetLabelOpnd); bb->ReplaceInsn(insn, regJumpInsn); } @@ -4835,40 +4898,84 @@ void Riscv64CGFunc::OffsetAdjustmentForFPLR() { RegOperand *regop = dynamic_cast(oper); if (regop && regop->IsOfVary()) { insn->SetOperand(i, GetOrCreateStackBaseRegOperand()); + MOperator mop = insn->GetMachineOpcode(); + if (mop == MOP_xmovrr || mop == MOP_wmovrr) { + insn->SetMOP(MOP_xaddrri12); + ImmOperand *iopnd = CreateImmOperand(0, 64, false); + insn->SetOperand(2, iopnd); + iopnd->SetVary(true); + } } } else if (oper->IsMemoryAccessOperand()) { Riscv64MemOperand *memoper = dynamic_cast(oper); + MemOperand *newMemOpnd = nullptr; if (memoper && memoper->GetBaseRegister() && memoper->GetBaseRegister()->IsOfVary()) { - memoper->SetBaseRegister(static_cast(GetOrCreateStackBaseRegOperand())); + newMemOpnd = static_cast(static_cast(memoper)->Clone(memPool)); + newMemOpnd->SetBaseRegister(static_cast(GetOrCreateStackBaseRegOperand())); + insn->SetOperand(i, newMemOpnd); } - if (memoper) { - Riscv64OfstOperand *oo = memoper->GetOffsetImmediate(); - if (oo->IsVary()) { - if (!UseFP() && !HasVLAOrAlloca() && argsToStkpassSize > 0) { - oo->AdjustOffset(static_cast(memlayout)->RealStackFrameSize()); - } else { - oo->AdjustOffset(static_cast(memlayout)->RealStackFrameSize() - - argsToStkpassSize); - } - oo->SetVary(false); + Riscv64OfstOperand *oo = nullptr; + if (newMemOpnd) { + oo = static_cast(newMemOpnd)->GetOffsetImmediate(); + } + if (oo && oo->IsVary()) { + int32 offset; + Riscv64MemLayout *layout = static_cast(memlayout); + if (!UseFP() && !HasVLAOrAlloca() && argsToStkpassSize > 0) { + offset = layout->RealStackFrameSize(); + } else { + offset = layout->RealStackFrameSize() - argsToStkpassSize; + } + oo = static_cast(static_cast(oo)->Clone(memPool)); + newMemOpnd->SetOffsetOperand(oo); + oo->AdjustOffset(offset); + if (oo->IsInBitSize(11) == false) { + Riscv64RegOperand *dst = GetOrCreatePhysicalRegisterOperand(Riscv64Abi::kIntSpareReg, 64, kRegTyInt); + Insn *li = cg->BuildInstruction(MOP_xmovri64, dst, CreateImmOperand(oo->GetOffsetValue(), 64, false)); + insn->bb->InsertInsnBefore(insn, li); + Insn *add = cg->BuildInstruction(MOP_xaddrrr, dst, newMemOpnd->GetBaseRegister(), dst); + insn->bb->InsertInsnBefore(insn, add); + newMemOpnd->SetBaseRegister(dst); + oo->SetOffsetValue(0); } + oo->SetVary(false); } - } else if (oper->IsIntImmediate()) { ImmOperand *imo = dynamic_cast(oper); OfstOperand *imo1 = dynamic_cast(oper); if (imo || imo1) { if (imo->IsVary()) { if (!UseFP() && !HasVLAOrAlloca() && argsToStkpassSize > 0) { - imo->Add(static_cast(memlayout)->RealStackFrameSize()); + if (imo) { + ImmOperand *newImmOpnd = static_cast(static_cast(imo)->Clone(memPool)); + newImmOpnd->Add(static_cast(memlayout)->RealStackFrameSize()); + insn->SetOperand(i, newImmOpnd); + imo = newImmOpnd; + } else { + OfstOperand *newOfstOpnd = static_cast(static_cast(imo)->Clone(memPool)); + newOfstOpnd->Add(static_cast(memlayout)->RealStackFrameSize()); + insn->SetOperand(i, newOfstOpnd); + imo = static_cast(newOfstOpnd); + } } else { - imo->Add(static_cast(memlayout)->RealStackFrameSize() - argsToStkpassSize); + if (imo) { + ImmOperand *newImmOpnd = static_cast(static_cast(imo)->Clone(memPool)); + newImmOpnd->Add(static_cast(memlayout)->RealStackFrameSize() - argsToStkpassSize); + insn->SetOperand(i, newImmOpnd); + imo = newImmOpnd; + } else { + OfstOperand *newOfstOpnd = static_cast(static_cast(imo)->Clone(memPool)); + newOfstOpnd->Add(static_cast(memlayout)->RealStackFrameSize() - argsToStkpassSize); + insn->SetOperand(i, newOfstOpnd); + imo = static_cast(newOfstOpnd); + } if (insn->GetMachineOpcode() != MOP_xmovri64 && !static_cast(imo)->IsInBitSize(11)) { - ReplaceLargeStackOffsetImm(insn); - bb->RemoveInsn(insn); + if (ReplaceLargeStackOffsetImm(insn)) { + bb->RemoveInsn(insn); + } } } } @@ -5246,8 +5353,22 @@ MemOperand *Riscv64CGFunc::LoadStructCopyBase(MIRSymbol *symbol, int32 offset, i return CreateMemOpnd(vreg2, offset, datasize); } -void Riscv64CGFunc::ReplaceLargeStackOffsetImm(Insn *insn) { - CHECK_FATAL(0, "FIX"); +// Return true to remove insn +bool Riscv64CGFunc::ReplaceLargeStackOffsetImm(Insn *insn) { + MOperator opc = insn->GetMachineOpcode(); + switch (opc) { + case MOP_xaddrri12: { + Operand *dst = insn->opnds[0]; + Insn *li = cg->BuildInstruction(MOP_xmovri64, dst, insn->opnds[2]); + insn->bb->InsertInsnBefore(insn, li); + insn->SetOperand(2, dst); + insn->SetMOP(MOP_xaddrrr); + return false; + } + default: + CHECK_FATAL(0, "FIX"); + } + return true; } } // namespace maplebe diff --git a/mapleall/maple_be/src/cg/riscv64/riscv64_color_ra.cpp b/mapleall/maple_be/src/cg/riscv64/riscv64_color_ra.cpp index 7fb1be0ede073d286eb01c32f8474190d9e6768a..3e216bdfee87fe11e97554edcbdc1811714ba36a 100644 --- a/mapleall/maple_be/src/cg/riscv64/riscv64_color_ra.cpp +++ b/mapleall/maple_be/src/cg/riscv64/riscv64_color_ra.cpp @@ -64,6 +64,7 @@ const uint32 kSwitchCaseNum = 5; const uint32 kLoopWeight = 10; const uint32 kMaxParamNum = 8; const uint32 kNumPregBits = V31 + 1; +const uint32 kNumInsnThreashold = 200000; #define GCRA_DUMP CGDEBUGFUNC(cgfunc_) @@ -1100,7 +1101,6 @@ MemOperand *GraphColorRegAllocator::CreateSpillMem(uint32 spillIdx) { bool GraphColorRegAllocator::IsLocalReg(regno_t regno) { LiveRange *lr = lrVec[regno]; if (lr == nullptr) { - LogInfo::MapleLogger() << "unexpected regno " << regno << endl; return true; } if (lr->splitLr) { @@ -1119,13 +1119,13 @@ bool GraphColorRegAllocator::IsLocalReg(LiveRange *lr) { } void GraphColorRegAllocator::CheckInterference(LiveRange *lr1, LiveRange *lr2) { - uint64 bitArr[bbBuckets]; - BIT_ARR_AND(lr1->bmember, lr2->bmember, bitArr, bbBuckets); +// uint64 bitArr[bbBuckets]; +// BIT_ARR_AND(lr1->bmember, lr2->bmember, bitArr, bbBuckets); uint32 lastBitSet; uint32 overlapNum = 0; bool stop = false; for (uint32 i = 0; i < bbBuckets; i++) { - uint64 val = bitArr[i]; + uint64 val = lr1->bmember[i] & lr2->bmember[i]; if (val) { for (uint32 x = 0; x < (sizeof(uint64) * CHAR_BIT); x++) { if (val & (1LL << x)) { @@ -1195,23 +1195,54 @@ void GraphColorRegAllocator::BuildInterferenceGraph() { std::vector fpLrVec; BuildInterferenceGraphSeparateIntFp(intLrVec, fpLrVec); - std::vector::iterator it1, it2; - for (it1 = intLrVec.begin(); it1 != intLrVec.end(); it1++) { - LiveRange *lr1 = *it1; + int sz = intLrVec.size(); + + // Checking interferences among LVs consumes significant amount of time. + // Take advantage of the fact that a large portion of LVs are short-lived + // Delay to do the same to FP + std::vector idxLastBucket(sz); + for (int i = 0; i < sz; i++) { + uint32 count = 0; + uint32 lastPos; + LiveRange *lr = intLrVec[i]; + for (int j = 0; j < bbBuckets; j++) { + if (lr->bmember[j]) { + count++; + lastPos = j; + } + } + if (count == 1) { + idxLastBucket[i] = lastPos; + } else { + idxLastBucket[i] = -1; + } + } + + for (int i = 0; i < sz; i++) { + LiveRange *lr1 = intLrVec[i]; CalculatePriority(lr1); - for (it2 = it1 + 1; it2 != intLrVec.end(); it2++) { - LiveRange *lr2 = *it2; - if (lr1->regno < lr2->regno) { - CheckInterference(lr1, lr2); + int32 iLastBucketIdx = idxLastBucket[i]; + + for (int j = i + 1; j < sz; j++) { + int32 jLastBucketIdx = idxLastBucket[j]; + LiveRange *lr2 = intLrVec[j]; + if (lr1->regno < lr2->regno ) { + if (iLastBucketIdx == -1 && jLastBucketIdx == -1) { + CheckInterference(lr1, lr2); + } else if ((iLastBucketIdx >= 0 && lr1->bmember[iLastBucketIdx] & lr2->bmember[iLastBucketIdx]) || + (jLastBucketIdx >= 0 && lr1->bmember[jLastBucketIdx] & lr2->bmember[jLastBucketIdx])) { + CheckInterference(lr1, lr2); + } } } } - for (it1 = fpLrVec.begin(); it1 != fpLrVec.end(); it1++) { - LiveRange *lr1 = *it1; + sz = fpLrVec.size(); + for (int i = 0; i < sz; i++) { + LiveRange *lr1 = fpLrVec[i]; CalculatePriority(lr1); - for (it2 = it1 + 1; it2 != fpLrVec.end(); it2++) { - LiveRange *lr2 = *it2; + for (int j = i + 1; j < sz; j++) { + LiveRange *lr2 = fpLrVec[j]; if (lr1->regno < lr2->regno) { CheckInterference(lr1, lr2); } @@ -2568,7 +2599,8 @@ MemOperand *GraphColorRegAllocator::GetCommonReuseMem(uint32 vregno, uint32 size END_FOREACH_REG_ARR_ELEM FOREACH_REG_ARR_ELEM_NOT_SET(conflict, regno) { - if (regno >= numVregs) { + if (regno >= numVregs || IsLocalReg(regno)) { + // conflict is for globals. Cannot factor into locals. break; } LiveRange *noConflictLr = lrVec[regno]; @@ -2604,11 +2636,11 @@ MemOperand *GraphColorRegAllocator::GetReuseMem(uint32 vregno, uint32 size, RegT } MemOperand *GraphColorRegAllocator::GetSpillMem(uint32 vregno, Insn *insn, Riscv64reg_t regno, - uint8 &isOutOfRange) { + uint8 &isOutOfRange, bool isDef) { Riscv64CGFunc *a64cgfunc = static_cast(cgfunc_); MemOperand *memopnd; memopnd = a64cgfunc->GetOrCreatSpillMem(vregno); - return (a64cgfunc->AdjustMemOperandIfOffsetOutOfRange(memopnd, vregno, insn, regno, isOutOfRange)); + return (a64cgfunc->AdjustMemOperandIfOffsetOutOfRange(memopnd, vregno, insn, regno, isOutOfRange, isDef)); } void GraphColorRegAllocator::SpillOperandForSpillPre(Insn *insn, Operand *opnd, RegOperand *phyopnd, uint32 spillIdx, @@ -2762,7 +2794,7 @@ MemOperand *GraphColorRegAllocator::GetSpillOrReuseMem(LiveRange *lr, uint32 reg baseRegNO = Riscv64Abi::kIntSpareReg; } ASSERT(baseRegNO != kRinvalid, "invalid base register number"); - memopnd = GetSpillMem(lr->regno, insn, (Riscv64reg_t)(baseRegNO), isOutOfRange); + memopnd = GetSpillMem(lr->regno, insn, (Riscv64reg_t)(baseRegNO), isOutOfRange, isDef); #ifdef REUSE_SPILLMEM if (isOutOfRange == 0) { lr->spillMem = memopnd; @@ -2811,21 +2843,27 @@ Insn *GraphColorRegAllocator::SpillOperand(Insn *insn, Operand *opnd, bool isDef if (insn->next && insn->next->GetMachineOpcode() == MOP_clinit_tail) { insn->bb->InsertInsnAfter(insn->next, spillDefInsn); } else { - insn->bb->InsertInsnAfter(insn, spillDefInsn); + if (isOutOfRange) { + insn->bb->InsertInsnAfter(insn->next->next, spillDefInsn); + } else { + insn->bb->InsertInsnAfter(insn, spillDefInsn); + } } + } else { + if (insn->GetMachineOpcode() == MOP_clinit_tail) { + return nullptr; + } + LiveRange *lr = lrVec[regno]; + Insn *spillUseInsn = nullptr; + lr->spillReg = pregNo; + memopnd = GetSpillOrReuseMem(lr, regsize, isOutOfRange, insn, false); + spillUseInsn = cg->BuildInstruction(a64cgfunc->PickLdInsn(regsize, stype), phyopnd, memopnd); + spillUseInsn->SetSpillOp(); + std::string comment = " RELOAD vreg: " + std::to_string(regno); + spillUseInsn->AddComment(comment); + insn->bb->InsertInsnBefore(insn, spillUseInsn); } - if (insn->GetMachineOpcode() == MOP_clinit_tail) { - return nullptr; - } - LiveRange *lr = lrVec[regno]; - Insn *spillUseInsn = nullptr; - lr->spillReg = pregNo; - memopnd = GetSpillOrReuseMem(lr, regsize, isOutOfRange, insn, false); - spillUseInsn = cg->BuildInstruction(a64cgfunc->PickLdInsn(regsize, stype), phyopnd, memopnd); - spillUseInsn->SetSpillOp(); - std::string comment = " RELOAD vreg: " + std::to_string(regno); - spillUseInsn->AddComment(comment); - insn->bb->InsertInsnBefore(insn, spillUseInsn); + if (spillDefInsn) { return spillDefInsn; } else { @@ -3335,7 +3373,7 @@ void GraphColorRegAllocator::SpillLiveRangeForSpills() { // Iterate through all instructions and change the vreg to preg. void GraphColorRegAllocator::FinalizeRegisters() { - if (CGOptions::doMultiPassColorRA && hasSpill) { + if (doMultiPass && hasSpill) { SpillLiveRangeForSpills(); return; } @@ -3423,6 +3461,9 @@ bool GraphColorRegAllocator::AllocateRegisters() { } } CG_ASSERT(cnt <= cgfunc_->GetTotalNumberOfInstructions(), "Incorrect insn count"); + if ((cnt < kNumInsnThreashold) && CGOptions::doMultiPassColorRA) { + doMultiPass = true; + } #ifdef PROPAGATE_REG if (cgfunc_->IsAfterRegAlloc() == false) { @@ -3437,7 +3478,7 @@ bool GraphColorRegAllocator::AllocateRegisters() { } #endif - if (CGOptions::doMultiPassColorRA) { + if (doMultiPass) { doLRA = false; doOptProlog = false; } @@ -3476,7 +3517,7 @@ bool GraphColorRegAllocator::AllocateRegisters() { cgfunc_->DumpCGIR(); } - if (CGOptions::doMultiPassColorRA && hasSpill) { + if (doMultiPass && hasSpill) { return false; } else { return true; diff --git a/mapleall/maple_be/src/cg/riscv64/riscv64_ebo.cpp b/mapleall/maple_be/src/cg/riscv64/riscv64_ebo.cpp index 1ea1c1992c9297667eb593916b2d473f38706ea2..021db50679bb0b2be3bf94f10f43ec749f2bdcf7 100644 --- a/mapleall/maple_be/src/cg/riscv64/riscv64_ebo.cpp +++ b/mapleall/maple_be/src/cg/riscv64/riscv64_ebo.cpp @@ -314,9 +314,9 @@ bool Riscv64Ebo::DoConstProp(Insn *insn, int idx, Operand *opnd) { switch (mopcode) { case MOP_xiorrrr: { if (src->GetValue() == 0) { - insn->mop_ = MOP_xiorrri13; - src->SetSize(12); - insn->SetOperand(idx + 1, src); + Riscv64CGFunc *a64cgfunc = static_cast(cgfunc); + RegOperand *zero = a64cgfunc->GetOrCreatePhysicalRegisterOperand((Riscv64reg_t)R0, 64, kRegTyInt); + insn->SetOperand(idx + 1, zero); return true; } break; @@ -438,24 +438,24 @@ bool Riscv64Ebo::ConstantOperand(Insn *insn, Operand **opnds, OpndInfo **opndInf return true; } // For the imm is 0. Then replace the insn by a move insn. - if ((insn->GetMachineOpcode() >= MOP_xaddrrr && insn->GetMachineOpcode() <= MOP_sadd && imm->IsZero()) || - (!first && insn->GetMachineOpcode() >= MOP_xsubrrr && insn->GetMachineOpcode() <= MOP_ssub && imm->IsZero())) { + if (imm->IsVary() == false && + ((insn->GetMachineOpcode() >= MOP_xaddrrr && insn->GetMachineOpcode() <= MOP_sadd && imm->IsZero()) || + (!first && insn->GetMachineOpcode() >= MOP_xsubrrr && insn->GetMachineOpcode() <= MOP_ssub && imm->IsZero()))) { bb->ReplaceInsn(insn, cgfunc->cg->BuildInstruction(dsize == 64 ? MOP_xmovrr : MOP_wmovrr, res, op)); return true; } if (insn->GetMachineOpcode() == MOP_xaddrrr || insn->GetMachineOpcode() == MOP_waddrrr) { -// if (imm->IsInBitSize(24)) { - // ADD Wd|WSP, Wn|WSP, #imm{, shift} ; 32-bit general registers - // ADD Xd|SP, Xn|SP, #imm{, shift} ; 64-bit general registers - // imm : 0 ~ 4095, shift: none, LSL #0, or LSL #12 - // riscv64 assembly takes up to 24-bits, if the lower 12 bits is all 0 - if (imm->IsInBitSize(11)) { - bb->ReplaceInsn( - insn, cgfunc->cg->BuildInstruction(dsize == 64 ? MOP_xaddrri12 : MOP_waddrri12, res, op, imm)); - retval = true; + if (imm->IsInBitSize(11)) { + if (imm->IsVary()) { + Riscv64CGFunc *aarchfunc = static_cast(cgfunc); + imm = aarchfunc->CreateImmOperand(imm->GetValue(), 64, false); + imm->SetVary(true); } -// } + bb->ReplaceInsn( + insn, cgfunc->cg->BuildInstruction(dsize == 64 ? MOP_xaddrri12 : MOP_waddrri12, res, op, imm)); + retval = true; + } } // Look for the sequence which can be simpified. if (retval == true || insn->GetMachineOpcode() == MOP_xaddrri12 || insn->GetMachineOpcode() == MOP_waddrri12) { @@ -472,7 +472,7 @@ bool Riscv64Ebo::ConstantOperand(Insn *insn, Operand **opnds, OpndInfo **opndInf int64_t val = imm0->GetValue() + imm->GetValue(); Riscv64CGFunc *aarchfunc = static_cast(cgfunc); Riscv64ImmOperand *imm1 = aarchfunc->CreateImmOperand(val, dsize, imm0->IsSignedValue()); - if (imm0->IsVary()) { + if (imm->IsVary() || imm0->IsVary()) { imm1->SetVary(true); } if (imm1->IsInBitSize(11)) { @@ -527,6 +527,17 @@ bool Riscv64Ebo::SpecialSequence(Insn *insn, Operand **opnds, OpndInfo **origInf } break; } + case MOP_xsxtw64: { + OpndInfo *opndinfo = origInfo[0]; + if (opndinfo == nullptr) { + return false; + } + Insn *prevInsn = origInfo[0]->insn; + if (prevInsn && (prevInsn->GetMachineOpcode() == opc)) { + insn->SetMOP(MOP_xmovrr); + } + break; + } case MOP_wstr: case MOP_xstr: case MOP_wldr: @@ -590,6 +601,10 @@ bool Riscv64Ebo::SpecialSequence(Insn *insn, Operand **opnds, OpndInfo **origInf if ((!is64bits && immVal < STR_LDR_IMM32_UPPER_BOUND && immVal % 4 == 0) || (is64bits && immVal < STR_LDR_IMM64_UPPER_BOUND && immVal % 8 == 0)) { MemOperand *mo = aarchfunc->CreateMemOpnd(op1, immVal, size); + if (imm0->IsVary() || imm1->IsVary()) { + ImmOperand *ofst = static_cast(mo->GetOffsetOperand()); + ofst->SetVary(true); + } Insn *ldInsn = cgfunc->cg->BuildInstruction(opc, res, mo); insn->bb->ReplaceInsn(insn, ldInsn); return true; diff --git a/mapleall/maple_be/src/cg/riscv64/riscv64_emit.cpp b/mapleall/maple_be/src/cg/riscv64/riscv64_emit.cpp index 9779e095df81e1f9add6f940caea740b051d5a83..31a5c7302bcc97ac80a60ff1f1fd363f304d42c6 100644 --- a/mapleall/maple_be/src/cg/riscv64/riscv64_emit.cpp +++ b/mapleall/maple_be/src/cg/riscv64/riscv64_emit.cpp @@ -226,14 +226,14 @@ void Riscv64Insn::EmitAdrpLabel(CG &cg, Emitter &emitter) { //GStrIdx strIdx = CG::curCgFunc->mirModule.CurFunction()->labelTab->labelTable[lidx]; //string labelStr = GlobalTables::GetStrTable().GetStringFromStrIdx(strIdx); - // adrp xd, label + // lui xd, %hi(label) emitter.Emit("\t").Emit("lui").Emit("\t"); opnd0->Emit(emitter, prop0); emitter.Emit(", "); - const char *idx = std::to_string(CG::curPuIdx).c_str(); + const char *idx = strdup(std::to_string(CG::curPuIdx).c_str()); emitter.Emit("%hi(").Emit(".label.").Emit(idx).Emit("__").Emit(lidx).Emit(")\n"); - // add xd, xd, #lo12:label + // addi xd, xd, %lo(label) emitter.Emit("\taddi\t"); opnd0->Emit(emitter, prop0); emitter.Emit(", "); @@ -566,7 +566,9 @@ void Riscv64CGFunc::Emit() { // nothing } else { emitter.Emit("\t.globl\t").Emit(funcSt->GetName()).Emit("\n"); - emitter.Emit("\t.hidden\t").Emit(funcSt->GetName()).Emit("\n"); + if (!func->IsC()) { + emitter.Emit("\t.hidden\t").Emit(funcSt->GetName()).Emit("\n"); + } } emitter.Emit("\t.type\t").Emit(funcSt->GetName()).Emit(", %function\n"); @@ -621,7 +623,7 @@ void Riscv64CGFunc::Emit() { LSDAHeader *lsdaheader = ehfunc->lsda_header; const char *funcname = funcSt->GetName().c_str(); // .word .label.lsda_label-func_start_label - const char *idx = std::to_string(CG::curPuIdx).c_str(); + const char *idx = strdup(std::to_string(CG::curPuIdx).c_str()); emitter.Emit("\t.word ") .Emit(".label.") .Emit(idx) @@ -703,7 +705,7 @@ void Riscv64CGFunc::Emit() { MIRLblConst *lblconst = static_cast(arrayConst->constVec[i]); CHECK_FATAL(lblconst, "null ptr check"); emitter.Emit("\t.quad\t"); - const char *idx = std::to_string(CG::curPuIdx).c_str(); + const char *idx = strdup(std::to_string(CG::curPuIdx).c_str()); emitter.Emit(".label.").Emit(idx).Emit("__").Emit(lblconst->value); emitter.Emit(" - ").Emit(st->GetName().c_str()); emitter.Emit("\n"); @@ -726,7 +728,7 @@ void Riscv64CGFunc::EmitFastLSDA() // the fast_exception_handling lsda // .word 0xFFFFFFFF // .word .label.LTest_3B_7C_3Cinit_3E_7C_28_29V3-func_start_label emitter->Emit("\t.word 0xFFFFFFFF\n"); - const char *idx = std::to_string(CG::curPuIdx).c_str(); + const char *idx = strdup(std::to_string(CG::curPuIdx).c_str()); if (NeedCleanup()) { emitter->Emit("\t.word ") .Emit(".label.") @@ -818,7 +820,7 @@ void Riscv64CGFunc::EmitFullLSDA() // the normal gcc_except_table emitter->EmitLabelPair(funcname, cleaupCode); } else if (func->IsJava()) { CG_ASSERT(!exitbbsvec.empty(), "exitbbsvec is empty in Riscv64CGFunc::EmitFullLSDA"); - const char *idx = std::to_string(CG::curPuIdx).c_str(); + const char *idx = strdup(std::to_string(CG::curPuIdx).c_str()); emitter->Emit("\t.4byte ") .Emit(".label.") .Emit(idx) @@ -866,7 +868,7 @@ void Riscv64CGFunc::EmitFullLSDA() // the normal gcc_except_table emitter->EmitLabelPair(funcname, cleaupCode); } else { CG_ASSERT(!exitbbsvec.empty(), "exitbbsvec is empty in Riscv64CGFunc::EmitFullLSDA"); - const char *idx = std::to_string(CG::curPuIdx).c_str(); + const char *idx = strdup(std::to_string(CG::curPuIdx).c_str()); emitter->Emit("\t.uleb128 ") .Emit(".label.") .Emit(idx) @@ -1045,7 +1047,7 @@ void Riscv64CGFunc::EmitOperand(Operand *opnd, OpndProp *prop) { outf << stopnd->GetName(); } } else if (LabelOperand *lblopnd = dynamic_cast(opnd)) { - const char *idx = std::to_string(CG::curPuIdx).c_str(); + const char *idx = strdup(std::to_string(CG::curPuIdx).c_str()); outf << ".label." << idx << "__" << lblopnd->labidx_; } else if (FuncNameOperand *fn = dynamic_cast(opnd)) { outf << fn->GetName(); diff --git a/mapleall/maple_be/src/cg/riscv64/riscv64_insn.cpp b/mapleall/maple_be/src/cg/riscv64/riscv64_insn.cpp index 013b40d2b8ae88f5d773e3f6a6ec92a8a2dafe14..94c8a34be1cac51ff7d94b8e2bed31c1af1808e3 100644 --- a/mapleall/maple_be/src/cg/riscv64/riscv64_insn.cpp +++ b/mapleall/maple_be/src/cg/riscv64/riscv64_insn.cpp @@ -246,6 +246,7 @@ int32_t Riscv64Insn::CopyOperands() { * Get the jump target label operand index from the given instruction. * Note: MOP_xbr is a jump instruction, but the target is unknown at compile time, * because a register instead of label. So we don't take it as a branching instruction. + * Howeer for special long range branch patch, the label is installed in this case. */ int Riscv64Insn::GetJumpTargetIdx() const { int operandIdx = 0; @@ -255,6 +256,11 @@ int Riscv64Insn::GetJumpTargetIdx() const { operandIdx = 0; break; } + case MOP_xbr: { + CHECK_FATAL(opnds[1] != 0, "ERR"); + operandIdx = 1; + break; + } // conditional jump case MOP_beq: case MOP_bne: diff --git a/mapleall/maple_be/src/cg/riscv64/riscv64_insn_slct.cpp b/mapleall/maple_be/src/cg/riscv64/riscv64_insn_slct.cpp index 58685b23c7c901c10a61d0416256d2ff6a761e81..3c05f9d8b8aec56f74b34f737ee0b05dc33d1a61 100644 --- a/mapleall/maple_be/src/cg/riscv64/riscv64_insn_slct.cpp +++ b/mapleall/maple_be/src/cg/riscv64/riscv64_insn_slct.cpp @@ -504,6 +504,15 @@ void Riscv64CGFunc::SelectMpy(Operand *resopnd, Operand *opnd0, Operand *opnd1, int64 immValue = llabs(imm->GetValue()); if (immValue != 0 && (immValue & (immValue - 1)) == 0) { if (otherop->op_kind_ != Operand::Opd_Register) { + if (otherop->op_kind_ == Operand::Opd_Immediate) { + // both operands are immediates + ImmOperand *otherImm = static_cast(otherop); + int64 otherImmVal = llabs(otherImm->GetValue()); + otherImm->SetValue(otherImmVal * immValue); + SelectCopy(otherop, prmtype, prmtype); + curbb->lastinsn->SetOperand(0, resopnd); + return; + } otherop = SelectCopy(otherop, prmtype, prmtype); } Riscv64ImmOperand *shiftnum = CreateImmOperand(__builtin_ffsll(immValue) - 1, dsize, false); @@ -805,8 +814,8 @@ void Riscv64CGFunc::SelectCmpOp(Operand *resopnd, Operand *opnd0, Operand *opnd1 bool doZext0 = false; bool doZext1 = false; - if (!IsSignedInteger(operandType) && dsize < 64) { - if (opnd0->IsRegister()) { // only for unsigned + if (dsize < 64) { + if (opnd0->IsRegister()) { opnd0 = SelectZeroSignExt(opnd0, operandType); } if (opnd1->IsRegister()) { @@ -2057,6 +2066,52 @@ Operand *Riscv64CGFunc::SelectCvt(BaseNode *parent, TypeCvtNode *node, Operand * if (fromtype == totype) { return opnd0; // noop } + if (IsPrimitiveInteger(fromtype) && IsPrimitiveInteger(totype) && + opnd0->op_kind_ == Operand::Opd_Immediate && + GetPrimTypeBitSize(fromtype) < GetPrimTypeBitSize(totype)) { + ImmOperand *otherImm = static_cast(opnd0); + int64 imm = otherImm->GetValue(); + switch (GetPrimTypeBitSize(fromtype)) { + case 8: { + int64 val; + if (IsSignedInteger(totype)) { + val = 0x7f; + } else { + val = 0xff; + } + if ((imm & val) == imm) { + return LoadIntoRegister(opnd0, fromtype); + } + break; + } + case 16: { + int64 val; + if (IsSignedInteger(totype)) { + val = 0x7fff; + } else { + val = 0xffff; + } + if ((imm & val) == imm) { + return LoadIntoRegister(opnd0, fromtype); + } + break; + } + case 32: { + int64 val; + if (IsSignedInteger(totype)) { + val = 0x7fffffff; + } else { + val = 0xffffffff; + } + if ((imm & val) == imm) { + return LoadIntoRegister(opnd0, fromtype); + } + break; + } + default: + break; + } + } Operand *resopnd = static_cast(CreateRegisterOperandOfType(totype)); if (IsPrimitiveFloat(totype) && IsPrimitiveInteger(fromtype)) { SelectCvtInt2Float(resopnd, opnd0, totype, fromtype); @@ -2475,7 +2530,7 @@ Operand *Riscv64CGFunc::SelectGCMalloc(GCMallocNode *node) { vector opndvec{ resopnd, opndSize, opndAlign }; - const char *funcName = GetIntrinsicFuncName(INTRN_MCCNewObj).c_str(); + const char *funcName = strdup(GetIntrinsicFuncName(INTRN_MCCNewObj).c_str()); SelectLibCall(funcName, opndvec, PTY_u64, rettype); return resopnd; @@ -2516,7 +2571,7 @@ Operand *Riscv64CGFunc::SelectJarrayMalloc(JarrayMallocNode *node, Operand *opnd vector opndvec{ resopnd, opndFixedSize, opndElemSize, opndNElems64, opndAlign }; - const char *funcName = GetIntrinsicFuncName(INTRN_MCCNewObjFlexibleCname).c_str(); + const char *funcName = strdup(GetIntrinsicFuncName(INTRN_MCCNewObjFlexibleCname).c_str()); SelectLibCall(funcName, opndvec, PTY_u64, rettype); // Generate the store of the object length field diff --git a/mapleall/maple_be/src/cg/riscv64/riscv64_load_store.cpp b/mapleall/maple_be/src/cg/riscv64/riscv64_load_store.cpp index a19b4b2d126d511e1d89f074014a2f6745937966..4a161f3e43a7d23e85df4f3ea0fa511b611b802a 100644 --- a/mapleall/maple_be/src/cg/riscv64/riscv64_load_store.cpp +++ b/mapleall/maple_be/src/cg/riscv64/riscv64_load_store.cpp @@ -158,11 +158,10 @@ MOperator Riscv64CGFunc::PickMovInsn(PrimType primtype) { } MOperator Riscv64CGFunc::PickMovInsn(RegOperand *lhs, RegOperand *rhs) { - CG_ASSERT(lhs->GetSize() == rhs->GetSize(), "PickMovInsn: unequal size NYI"); - //CG_ASSERT((lhs->GetSize() < 64 || lhs->GetRegisterType() == kRegTyFloat), "should split the 64 bits or more mov"); + //CG_ASSERT(lhs->GetSize() == rhs->GetSize(), "PickMovInsn: unequal size NYI"); if (lhs->GetRegisterType() == kRegTyInt) { if (rhs->GetRegisterType() == kRegTyInt) { - return MOP_wmovrr; + return ((lhs->GetSize() == 64) ? MOP_xmovrr : MOP_xmovrr); } else { return (rhs->GetSize() == 64) ? MOP_xvmovrd : MOP_xvmovrs; } @@ -384,7 +383,7 @@ void Riscv64CGFunc::SelectCopy(Operand *dest, PrimType dtype, Operand *src, Prim } Operand::OperandType opnd0ty = dest->op_kind_; Operand::OperandType opnd1ty = src->op_kind_; - CG_ASSERT((dsize >= ssize || opnd0ty == Operand::Opd_Mem), "NYI"); + //CG_ASSERT((dsize >= ssize || opnd0ty == Operand::Opd_Mem), "NYI"); CG_ASSERT((opnd0ty == Operand::Opd_Register || opnd1ty == Operand::Opd_Register), "either src or dest should be register"); @@ -892,9 +891,82 @@ void Riscv64CGFunc::SelectAggDassign(DassignNode *stmt) { // is no need to split it into smaller accesses. bool parmCopy = IsParamStructCopy(rhssymbol); alignused = std::min(lhsalign, rhsalign); - Operand *rhsmemopnd = nullptr; - Operand *lhsmemopnd = nullptr; - for (uint32 i = 0; i < (lhssize / alignused); i++) { + MemOperand *rhsmemopnd = nullptr; + MemOperand *lhsmemopnd = nullptr; + uint32 numElems = lhssize / alignused; + if (numElems > 4) { + vector opndvec; + RegOperand *vreg; + vreg = CreateVirtualRegisterOperand(New_V_Reg(kRegTyInt, 8)); + opndvec.push_back(vreg); // result + Riscv64OfstOperand *offopnd = GetOrCreateOfstOpnd(lhsoffset, 32); + if (lhssymbol->storageClass == kScFormal && becommon.type_size_table[lhssymbol->tyIdx.GetIdx()] > 16) { + RegOperand *vreg; + lhsmemopnd = GetOrCreateMemOpnd(lhssymbol, 0, alignused * BITS_PER_BYTE); + vreg = CreateVirtualRegisterOperand(New_V_Reg(kRegTyInt, BITS_PER_BYTE)); + Insn *ldInsn = cg->BuildInstruction(PickLdInsn(64, PTY_i64), vreg, lhsmemopnd); + curbb->AppendInsn(ldInsn); + lhsmemopnd = GetOrCreateMemOpnd(64, vreg, nullptr, GetOrCreateOfstOpnd(lhsoffset, 32), nullptr); + } else { + lhsmemopnd = GetOrCreateMemOpnd(lhssymbol, lhsoffset, alignused * BITS_PER_BYTE); + } + vreg = CreateVirtualRegisterOperand(New_V_Reg(kRegTyInt, BITS_PER_BYTE)); + ImmOperand *offOpnd = static_cast(lhsmemopnd->GetOffsetOperand()); + int64 val = offOpnd->GetValue(); + Operand *base = lhsmemopnd->GetBaseRegister(); + if (val > 0x7ff) { + Insn *insn; + RegOperand *tmpreg; + tmpreg = CreateVirtualRegisterOperand(New_V_Reg(kRegTyInt, BITS_PER_BYTE)); + ImmOperand *newImmOpnd = CreateImmOperand(val, 64, false); + insn = cg->BuildInstruction(MOP_xmovri64, tmpreg, newImmOpnd); + curbb->AppendInsn(insn); + insn = cg->BuildInstruction(MOP_xaddrrr, vreg, base, tmpreg); + curbb->AppendInsn(insn); + } else { + if (val == 0) { + vreg = static_cast(base); + } else { + Insn *insn = cg->BuildInstruction(MOP_xaddrri12, vreg, base, offOpnd); + curbb->AppendInsn(insn); + } + } + opndvec.push_back(vreg); // param 0 + if (parmCopy) { + rhsmemopnd = LoadStructCopyBase(rhssymbol, rhsoffset, alignused * BITS_PER_BYTE); + } else { + rhsmemopnd = GetOrCreateMemOpnd(rhssymbol, rhsoffset, alignused * BITS_PER_BYTE); + } + vreg = CreateVirtualRegisterOperand(New_V_Reg(kRegTyInt, BITS_PER_BYTE)); + offOpnd = static_cast(rhsmemopnd->GetOffsetOperand()); + val = offOpnd->GetValue(); + base = rhsmemopnd->GetBaseRegister(); + if (val > 0x7ff) { + Insn *insn; + RegOperand *tmpreg; + tmpreg = CreateVirtualRegisterOperand(New_V_Reg(kRegTyInt, 8)); + ImmOperand *newImmOpnd = CreateImmOperand(val, 64, false); + insn = cg->BuildInstruction(MOP_xmovri64, tmpreg, newImmOpnd); + curbb->AppendInsn(insn); + insn = cg->BuildInstruction(MOP_xaddrrr, vreg, base, tmpreg); + curbb->AppendInsn(insn); + } else { + if (val == 0) { + vreg = static_cast(base); + } else { + Insn *insn = cg->BuildInstruction(MOP_xaddrri12, vreg, base, offOpnd); + curbb->AppendInsn(insn); + } + } + opndvec.push_back(vreg); // param 1 + vreg = CreateVirtualRegisterOperand(New_V_Reg(kRegTyInt, 8)); + Riscv64ImmOperand *sizeOpnd = CreateImmOperand(numElems * alignused, 64, false); + curbb->AppendInsn(cg->BuildInstruction(MOP_xmovri64, vreg, sizeOpnd)); + opndvec.push_back(vreg); // param 2 + SelectLibCall("memcpy", opndvec, PTY_a64, PTY_a64); + return; + } + for (uint32 i = 0; i < numElems; i++) { // generate the load if (parmCopy) { rhsmemopnd = LoadStructCopyBase(rhssymbol, rhsoffset + i * alignused, alignused * BITS_PER_BYTE); @@ -1350,10 +1422,76 @@ void Riscv64CGFunc::SelectAggIassign(IassignNode *stmt, Operand *lhsaddropnd) { } alignused = std::min(lhsalign, rhsalign); - Operand *rhsmemopnd = nullptr; - Operand *lhsmemopnd = nullptr; + MemOperand *rhsmemopnd = nullptr; + MemOperand *lhsmemopnd = nullptr; bool parmCopy = IsParamStructCopy(rhssymbol); - for (uint32 i = 0; i < (lhssize / alignused); i++) { + uint32 numElems = lhssize / alignused; + if (numElems > 4) { + vector opndvec; + RegOperand *vreg; + vreg = CreateVirtualRegisterOperand(New_V_Reg(kRegTyInt, 8)); + opndvec.push_back(vreg); // result + Riscv64OfstOperand *offopnd = GetOrCreateOfstOpnd(lhsoffset, 32); + lhsmemopnd = GetOrCreateMemOpnd(alignused * 8, + static_cast(lhsaddropnd), nullptr, offopnd, + static_cast(nullptr)); + vreg = CreateVirtualRegisterOperand(New_V_Reg(kRegTyInt, 8)); + ImmOperand *offOpnd = static_cast(lhsmemopnd->GetOffsetOperand()); + int64 val = offOpnd->GetValue(); + Operand *base = lhsmemopnd->GetBaseRegister(); + if (val > 0x7ff) { + Insn *insn; + RegOperand *tmpreg; + tmpreg = CreateVirtualRegisterOperand(New_V_Reg(kRegTyInt, 8)); + ImmOperand *newImmOpnd = CreateImmOperand(val, 64, false); + insn = cg->BuildInstruction(MOP_xmovri64, tmpreg, newImmOpnd); + curbb->AppendInsn(insn); + insn = cg->BuildInstruction(MOP_xaddrrr, vreg, base, tmpreg); + curbb->AppendInsn(insn); + } else { + if (val == 0) { + vreg = static_cast(base); + } else { + Insn *insn = cg->BuildInstruction(MOP_xaddrri12, vreg, base, offOpnd); + curbb->AppendInsn(insn); + } + } + opndvec.push_back(vreg); // param 0 + if (parmCopy) { + rhsmemopnd = LoadStructCopyBase(rhssymbol, rhsoffset, alignused * 8); + } else { + rhsmemopnd = GetOrCreateMemOpnd(rhssymbol, rhsoffset, alignused * 8); + } + vreg = CreateVirtualRegisterOperand(New_V_Reg(kRegTyInt, 8)); + offOpnd = static_cast(rhsmemopnd->GetOffsetOperand()); + val = offOpnd->GetValue(); + base = rhsmemopnd->GetBaseRegister(); + if (val > 0x7ff) { + Insn *insn; + RegOperand *tmpreg; + tmpreg = CreateVirtualRegisterOperand(New_V_Reg(kRegTyInt, 8)); + ImmOperand *newImmOpnd = CreateImmOperand(val, 64, false); + insn = cg->BuildInstruction(MOP_xmovri64, tmpreg, newImmOpnd); + curbb->AppendInsn(insn); + insn = cg->BuildInstruction(MOP_xaddrrr, vreg, base, tmpreg); + curbb->AppendInsn(insn); + } else { + if (val == 0) { + vreg = static_cast(base); + } else { + Insn *insn = cg->BuildInstruction(MOP_xaddrri12, vreg, base, offOpnd); + curbb->AppendInsn(insn); + } + } + opndvec.push_back(vreg); // param 1 + vreg = CreateVirtualRegisterOperand(New_V_Reg(kRegTyInt, 8)); + Riscv64ImmOperand *sizeOpnd = CreateImmOperand(numElems * alignused, 64, false); + curbb->AppendInsn(cg->BuildInstruction(MOP_xmovri64, vreg, sizeOpnd)); + opndvec.push_back(vreg); // param 2 + SelectLibCall("memcpy", opndvec, PTY_a64, PTY_a64); + return; + } + for (uint32 i = 0; i < numElems; i++) { // generate the load if (parmCopy) { rhsmemopnd = LoadStructCopyBase(rhssymbol, rhsoffset + i * alignused, alignused * 8); @@ -2030,33 +2168,46 @@ Operand *Riscv64CGFunc::SelectIntconst(MIRIntConst *intconst, PrimType parentPty } template -Operand *SelectLiteral(T *c, MIRFunction *func, uint32 labelIdx, Riscv64CGFunc *cgfunc) { - MIRSymbol *st = func->symTab->CreateSymbol(kScopeLocal); - std::string lblstr(".LB_"); - MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStIdx(func->stIdx.Idx()); - std::string funcname = funcSt->GetName(); - lblstr.append(funcname).append(to_string(labelIdx)); - st->SetNameStridx(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lblstr)); - st->storageClass = kScPstatic; - st->sKind = kStConst; - st->SetConst(c); - PrimType primty = c->type->GetPrimType(); - st->SetTyIdx(c->type->tyIdx); - uint32 typeBitsize = GetPrimTypeBitSize(primty); +Operand *SelectLiteral(T *c, MIRFunction *func, uint32 labelIdx, Riscv64CGFunc *cgfunc, bool isZero) { + // SelectLiteral is only for MIRFloatConst and MIRDoubleConst + MIRSymbol* sym = nullptr; + for (uint32_t idx = 0; idx < func->symTab->GetSymbolTableSize(); idx++) { + auto tsym = func->symTab->GetSymbolFromStIdx(idx); + if (tsym && + (tsym->storageClass == kScPstatic) && + (tsym->sKind == kStConst) && + (tsym->GetTyIdx() == c->type->tyIdx) && + (static_cast(tsym->GetConst())->GetValue() == c->GetValue())) { + sym = tsym; + break; + } + } + + MIRSymbol *st; + uint32 typeBitsize = GetPrimTypeBitSize(c->type->GetPrimType()); + + if (sym) { + st = sym; // Reuse the existing symbol + } else { // Create a new symbol + st = func->symTab->CreateSymbol(kScopeLocal); + std::string lblstr(".LB_"); + MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStIdx(func->stIdx.Idx()); + std::string funcname = funcSt->GetName(); + lblstr.append(funcname).append(to_string(labelIdx)); + st->SetNameStridx(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lblstr)); + st->storageClass = kScPstatic; + st->sKind = kStConst; + st->SetConst(c); + st->SetTyIdx(c->type->tyIdx); + } switch (c->kind) { case kConstFloatConst: case kConstDoubleConst: { // Handling of -0.0. Use zero reg only for +0.0, not -0.0. - if (cgfunc->mirModule.IsCModule()) { - return static_cast(cgfunc->GetOrCreateMemOpnd(st, 0, typeBitsize)); - } - return (c->IsZero() && !(c->IsNeg())) ? static_cast(cgfunc->GetOrCreateFpZeroOperand(typeBitsize)) + return (isZero && !(c->IsNeg())) ? static_cast(cgfunc->GetOrCreateFpZeroOperand(typeBitsize)) : static_cast(cgfunc->GetOrCreateMemOpnd(st, 0, typeBitsize)); } - case kConstVecInt: { - return static_cast(cgfunc->GetOrCreateMemOpnd(st, 0, typeBitsize)); - } default: { ASSERT(0, "Unsupported const type"); return nullptr; @@ -2065,15 +2216,36 @@ Operand *SelectLiteral(T *c, MIRFunction *func, uint32 labelIdx, Riscv64CGFunc * } Operand *Riscv64CGFunc::SelectFloatconst(MIRFloatConst *floatconst) { - return SelectLiteral(floatconst, func, labelIdx++, this); + bool isZero = false; + if (floatconst->GetIntValue() == 0) { + isZero = true; + } + return SelectLiteral(floatconst, func, labelIdx++, this, isZero); } Operand *Riscv64CGFunc::SelectDoubleconst(MIRDoubleConst *doubleconst) { - return SelectLiteral(doubleconst, func, labelIdx++, this); + bool isZero = false; + if (doubleconst->GetIntValue() == 0) { + isZero = true; + } + return SelectLiteral(doubleconst, func, labelIdx++, this, isZero); } Operand *Riscv64CGFunc::SelectVectorIntconst(MIRVectorIntConst *vecIntconst) { - return SelectLiteral(vecIntconst, func, labelIdx++, this); + // Dup of MIRVectorIntConst is highly unlikely. May check dup in future + MIRSymbol *st = func->symTab->CreateSymbol(kScopeLocal); + std::string lblstr(".LB_"); + MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStIdx(func->stIdx.Idx()); + std::string funcname = funcSt->GetName(); + lblstr.append(funcname).append(to_string(labelIdx)); + st->SetNameStridx(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lblstr)); + st->storageClass = kScPstatic; + st->sKind = kStConst; + st->SetConst(vecIntconst); + PrimType primty = vecIntconst->type->GetPrimType(); + st->SetTyIdx(vecIntconst->type->tyIdx); + uint32 typeBitsize = GetPrimTypeBitSize(primty); + return static_cast(GetOrCreateMemOpnd(st, 0, typeBitsize)); } template diff --git a/mapleall/maple_be/src/cg/riscv64/riscv64_operand.cpp b/mapleall/maple_be/src/cg/riscv64/riscv64_operand.cpp index a492f3d1e55fb13a485ece17df981b650b745376..ca6ce0bb84d1ce6709a989871243d9851fbeb7a4 100644 --- a/mapleall/maple_be/src/cg/riscv64/riscv64_operand.cpp +++ b/mapleall/maple_be/src/cg/riscv64/riscv64_operand.cpp @@ -140,19 +140,37 @@ void Riscv64MemOperand::Emit(Emitter &emitter, OpndProp *prop) { #if DEBUG CG_ASSERT(isVector || is64bit || md->GetOperandSize() <= 32, ""); #endif + MIRSymbol *symbol = GetSymbol(); Riscv64OfstOperand *offset = GetOffsetImmediate(); - if (offset) { - if (CGOptions::doPIC && offset->op_kind_ == Opd_StImmediate && - (((StImmOperand *)offset)->GetSymbol()->GetStorageClass() == kScGlobal || - ((StImmOperand *)offset)->GetSymbol()->GetStorageClass() == kScExtern)) { - emitter.Emit("#:got_lo12:"); - emitter.Emit(((StImmOperand *)offset)->GetName()); - } else { - CG_ASSERT(!IsPIMMOffsetOutOfRange(offset->GetOffsetValue(), size_), ""); - if (!offset->IsZero()) { - offset->Emit(emitter, nullptr); - } + if (symbol && (symbol->IsGlobal() || symbol->storageClass == kScPstatic || + symbol->storageClass == kScFstatic)) { + emitter.Emit("%lo("); + // check for sKind since it might be created by cg. (i.eg. LB_*) + if (symbol->storageClass == kScPstatic && symbol->sKind != kStConst && + symbol->IsLocal()) { + emitter.Emit(symbol->GetName() + to_string(CG::curPuIdx)); + } else { + emitter.Emit(symbol->GetName()); + } + if (offset && !offset->IsZero()) { + emitter.Emit("+"); + offset->Emit(emitter, nullptr); + } + emitter.Emit(")"); + } else if (offset) { + if (CGOptions::doPIC && offset->op_kind_ == Opd_StImmediate && + (((StImmOperand *)offset)->GetSymbol()->GetStorageClass() == + kScGlobal || + ((StImmOperand *)offset)->GetSymbol()->GetStorageClass() == + kScExtern)) { + emitter.Emit("#:got_lo12:"); + emitter.Emit(((StImmOperand *)offset)->GetName()); + } else { + CG_ASSERT(!IsPIMMOffsetOutOfRange(offset->GetOffsetValue(), size_), ""); + if (!offset->IsZero()) { + offset->Emit(emitter, nullptr); } + } } emitter.Emit("("); Riscv64RegOperand *baseReg = static_cast(GetBaseRegister()); diff --git a/mapleall/maple_be/src/cg/riscv64/riscv64_optimize_common.cpp b/mapleall/maple_be/src/cg/riscv64/riscv64_optimize_common.cpp index a537e8f61dd52587d3a908e52b9c26e599b4a399..c8c1e0caa22e728e079d0ad0df212033c803086b 100644 --- a/mapleall/maple_be/src/cg/riscv64/riscv64_optimize_common.cpp +++ b/mapleall/maple_be/src/cg/riscv64/riscv64_optimize_common.cpp @@ -86,10 +86,21 @@ void Riscv64InsnVisitor::ModifyJumpTarget(Operand *targetOperand, BB *&bb) { ImmOperand *immopnd = static_cast(GetCGFunc())->CreateImmOperand(labidx, 8, false); insn->SetOperand(1, immopnd); modified = true; + break; } } CHECK_FATAL(modified, "ModifyJumpTarget: Could not change jump target"); return; + } else if (bb->GetKind() == BB::kBBGoto) { + for (Insn *insn = bb->lastinsn; insn != nullptr; insn = insn->prev) { + if (insn->GetMachineOpcode() == MOP_laddr) { + maple::LabelIdx labidx = static_cast(targetOperand)->labidx_; + LabelOperand *label = static_cast(GetCGFunc())->GetOrCreateLabelOperand(labidx); + insn->SetOperand(1, label); + break; + } + } + // fallthru below to patch the branch insn } int targetIdx = bb->lastinsn->GetJumpTargetIdx(); bb->lastinsn->SetOperand(targetIdx, targetOperand); @@ -141,7 +152,14 @@ Insn *Riscv64InsnVisitor::CloneInsn(Insn *originalInsn) { Riscv64Insn *tobeCloned = static_cast(originalInsn); Insn *newInsn = mp->Clone(*tobeCloned); for (uint32 i = 0; i < Insn::kMaxOperandNum; i++) { - newInsn->opnds[i] = originalInsn->opnds[i]; + ImmOperand *iopnd = dynamic_cast(originalInsn->opnds[i]); + if (iopnd && iopnd->IsVary()) { + Riscv64ImmOperand *cloneImm = static_cast(originalInsn->opnds[i]); + ImmOperand *newIopnd = mp->Clone(*cloneImm); + newInsn->opnds[i] = newIopnd; + } else { + newInsn->opnds[i] = originalInsn->opnds[i]; + } } return newInsn; } else if (dynamic_cast(originalInsn)) { diff --git a/mapleall/maple_be/src/cg/riscv64/riscv64_peep.cpp b/mapleall/maple_be/src/cg/riscv64/riscv64_peep.cpp index 61af315669ea5d30912fdfaeb0897826a383c86f..fa1bcc0b71b03f5cad2c6f89bd89350c63722520 100644 --- a/mapleall/maple_be/src/cg/riscv64/riscv64_peep.cpp +++ b/mapleall/maple_be/src/cg/riscv64/riscv64_peep.cpp @@ -98,10 +98,38 @@ void Riscv64Peep::RemoveIdenticalLoadAndStore() { } void Riscv64Peep::Peephole0() { + RemoveSingleInstruction(); RemoveIdenticalLoadAndStore(); DeleteMovAfterCbzOrCbnz(); } +void Riscv64Peep::RemoveSingleInstruction() { + FOR_ALL_BB(bb, cgfunc) { + FOR_BB_INSNS_SAFE(insn, bb, ninsn) { + MOperator mop = insn->GetMachineOpcode(); + switch (mop) { + case MOP_wmovrr: + case MOP_xmovrr: + if (IsSameReg(insn->opnds[0], insn->opnds[1])) { + // mov r1, r1 + bb->RemoveInsn(insn); + } + break; + case MOP_waddrri12: + case MOP_xaddrri12: + if (IsSameReg(insn->opnds[0], insn->opnds[1]) && + static_cast(insn->opnds[2])->GetValue() == 0) { + // add r1, r1, 0 + bb->RemoveInsn(insn); + } + break; + default: + break; + } + } + } +} + /* We optimize the following pattern in this function: * A: Remove redundant mov which src and dest opnd is exactly same * B: Combining 2 STRs into 1 stp or 2 LDRs into 1 ldp, when they are @@ -132,10 +160,9 @@ void Riscv64Peep::Peephole0() { */ void Riscv64Peep::Peephole() { RemoveIdenticalLoadAndStore(); - Riscv64CGFunc *acgfunc = static_cast(cgfunc); // Delete insn moving the same register, this will simplify the following two passes. - FOR_ALL_BB(bb, acgfunc) { + FOR_ALL_BB(bb, cgfunc) { FOR_BB_INSNS_SAFE(insn, bb, ninsn) { if (!insn->IsMachineInstruction()) { continue; @@ -394,8 +421,7 @@ void Riscv64Peep::Peephole() { } void Riscv64Peep::PostRemoveSext() { - Riscv64CGFunc *acgfunc = static_cast(cgfunc); - FOR_ALL_BB(bb, acgfunc) { + FOR_ALL_BB(bb, cgfunc) { if (bb->firstinsn && bb->firstinsn->GetMachineOpcode() == MOP_wmovrr) { RegOperand *reg1 = static_cast(bb->firstinsn->opnds[1]); if (reg1->GetRegisterNumber() == R10 && @@ -420,8 +446,7 @@ void Riscv64Peep::PostRemoveSext() { } void Riscv64Peep::RemoveSext() { - Riscv64CGFunc *acgfunc = static_cast(cgfunc); - FOR_ALL_BB(bb, acgfunc) { + FOR_ALL_BB(bb, cgfunc) { FOR_BB_INSNS_REV_SAFE(insn, bb, ninsn) { if (!insn->IsMachineInstruction()) { continue; @@ -666,8 +691,10 @@ void Riscv64Peep::DeleteMovAfterCbzOrCbnz() { MOperator condbrMop = condbr->GetMachineOpcode(); if (condbrMop == MOP_bnez) { processBb = bb->next; - } else { + } else if (condbrMop == MOP_beqz) { processBb = cgfunc->theCFG->GetTargetSuc(bb); + } else { + continue; } CG_ASSERT(processBb != nullptr, "process_bb is null in Riscv64Peep::DeleteMovAfterCbzOrCbnz"); @@ -807,6 +834,7 @@ Insn *Riscv64Peep::DefInsnOfOperandInBB(BB *bb, Insn *startinsn, Insn *checkinsn void Riscv64Peep::PrePeepholeOpt() { RemoveSext(); ReplaceInstruction(); + ComplexMemOperandOpt(); } void Riscv64Peep::PrePeepholeOpt1() { @@ -816,21 +844,17 @@ void Riscv64Peep::PrePeepholeOpt1() { orr w21, #0, w0 ====> mov w21, w0 */ void Riscv64Peep::ReplaceInstruction() { - Riscv64CGFunc *acgfunc = static_cast(cgfunc); - FOR_ALL_BB(bb, acgfunc) { + FOR_ALL_BB(bb, cgfunc) { FOR_BB_INSNS(insn, bb) { if (!insn->IsMachineInstruction()) { continue; } Operand *opndOfOrr = nullptr; - Operand *opnd1OfMov = nullptr; - Operand *opnd2OfMov = nullptr; ImmOperand *immOpnd = nullptr; Riscv64RegOperand *reg1 = nullptr; Riscv64RegOperand *reg2 = nullptr; - MOperator thisMop = insn->GetMachineOpcode(); - switch (thisMop) { - case MOP_xiorrri13: { // opnd1 is reg64 and opnd3 is immediate. + switch (insn->GetMachineOpcode()) { + case MOP_xiorrri13: { // opnd2 is immediate. opndOfOrr = insn->opnds[2]; CG_ASSERT(opndOfOrr->IsIntImmediate(), "expects immediate operand"); immOpnd = static_cast(opndOfOrr); @@ -841,6 +865,18 @@ void Riscv64Peep::ReplaceInstruction() { } break; } + case MOP_xiorrrr: { // either opnd1 or opnd2 is r0 + if (static_cast(insn->opnds[1])->GetRegisterNumber() == R0) { + reg1 = static_cast(insn->opnds[0]); + reg2 = static_cast(insn->opnds[2]); + bb->ReplaceInsn(insn, cg->BuildInstruction(MOperator(MOP_xmovrr), reg1, reg2)); + } else if (static_cast(insn->opnds[2])->GetRegisterNumber() == R0) { + reg1 = static_cast(insn->opnds[0]); + reg2 = static_cast(insn->opnds[1]); + bb->ReplaceInsn(insn, cg->BuildInstruction(MOperator(MOP_xmovrr), reg1, reg2)); + } + break; + } default: break; } @@ -848,6 +884,130 @@ void Riscv64Peep::ReplaceInstruction() { } } +/* Check if a regOpnd is live after insn. True if live, otherwise false. + */ +bool Riscv64Peep::IfOperandIsLiveAfterInsn(RegOperand *regOpnd, Insn *insn) { + CG_ASSERT(insn, "insn should not be nullptr."); + + for (Insn *nextInsn = insn->next; + nextInsn && nextInsn != insn->bb->lastinsn->next; + nextInsn = nextInsn->next) { + if (!nextInsn->IsMachineInstruction()) { + continue; + } + + for (int i = Insn::kMaxOperandNum - 1; i >= 0; i--) { + Operand *opnd = nextInsn->opnds[i]; + if (opnd == nullptr) { + continue; + } + + if (opnd->IsMemoryAccessOperand()) { + MemOperand *mem = static_cast(opnd); + Operand *base = mem->GetBaseRegister(); + Operand *offset = mem->GetOffset(); + + if (base && base->IsRegister()) { + RegOperand *tmpRegOpnd = static_cast(base); + if (tmpRegOpnd->GetRegisterNumber() == regOpnd->GetRegisterNumber()) { + return true; + } + } + if (offset && offset->IsRegister()) { + RegOperand *tmpRegOpnd = static_cast(offset); + if (tmpRegOpnd->GetRegisterNumber() == regOpnd->GetRegisterNumber()) { + return true; + } + } + } + + if (opnd->IsRegister()) { + RegOperand *tmpRegOpnd = static_cast(opnd); + if (tmpRegOpnd->GetRegisterNumber() == regOpnd->GetRegisterNumber()) { + const Riscv64MD *md = + &Riscv64CG::kMd[static_cast(nextInsn)->mop_]; + Riscv64OpndProp *regprop = + static_cast(md->operand_[i]); + bool isUse = regprop->IsUse(); + if (isUse) { + return true; + } else { + // Redefined, no need to check live-out. + return false; + } + } + } + } + } + + // Check if it is live-out. + if (insn->bb->liveout_regno.find(regOpnd->GetRegisterNumber()) != + insn->bb->liveout_regno.end()) { + return true; + } + + return false; +} + +/* addi rY, rX, %lo(a) + ld rZ, (rY) + ==> + ld rZ, %lo(a)(rX) + */ +void Riscv64Peep::ComplexMemOperandOpt() { + Riscv64CGFunc *acgfunc = static_cast(cgfunc); + FOR_ALL_BB(bb, acgfunc) { + Insn *nextInsn = nullptr; + + for (Insn *insn = bb->firstinsn; insn; insn = nextInsn) { + nextInsn = insn->GetNextMachineInsn(); + if (nextInsn == nullptr) { + continue; + } + MOperator thisMop = insn->GetMachineOpcode(); + if (thisMop == MOP_adrpl12) { + MOperator nextMop = nextInsn->GetMachineOpcode(); + if (nextMop && ((nextMop >= MOP_wldrsb && nextMop <= MOP_dldr) || + (nextMop >= MOP_wstrb && nextMop <= MOP_dstr))) { + // Check if base register of nextInsn and the dest operand of insn are + // identical. + Riscv64MemOperand *memOpnd = + static_cast(nextInsn->GetMemOpnd()); + CG_ASSERT(memOpnd != nullptr, + "memOpnd is null in Riscv64Peep::ComplexMemOperandOpt"); + + RegOperand *regOpnd = static_cast(insn->GetOperand(0)); + + // Check if dest operand of add insn is identical with base register + // of nextInsn. + if (memOpnd->GetBaseRegister() != regOpnd) { + continue; + } + + // Check if rY is used after ldr insn or if it is in live-out. + if (IfOperandIsLiveAfterInsn(regOpnd, nextInsn)) { + continue; + } + + StImmOperand *stImmOpnd = + static_cast(insn->GetOperand(2)); + Riscv64OfstOperand *offopnd = acgfunc->GetOrCreateOfstOpnd( + stImmOpnd->GetOffset() + + memOpnd->GetOffsetImmediate()->GetOffsetValue(), + 32); + RegOperand *newBaseOpnd = + static_cast(insn->GetOperand(1)); + Riscv64MemOperand *newMemOpnd = acgfunc->GetOrCreateMemOpnd( + memOpnd->GetSize(), newBaseOpnd, nullptr, offopnd, + stImmOpnd->GetSymbol()); + nextInsn->SetOperand(1, newMemOpnd); + bb->RemoveInsn(insn); + } + } + } + } +} + AnalysisResult *CgDoPrePeepHole::Run(CGFunc *cgfunc, CgFuncResultMgr *m) { LiveAnalysis *live = nullptr; // It doesn't need live range information when -O1, because the register will not live out of bb. diff --git a/mapleall/maple_driver/defs/phases.def b/mapleall/maple_driver/defs/phases.def index f4df6bb9b7cc83036d10ee427416ba42d76d19c0..8ac0e00b10b04ee7ebaf9f064b5e569dc77fc563 100644 --- a/mapleall/maple_driver/defs/phases.def +++ b/mapleall/maple_driver/defs/phases.def @@ -31,13 +31,22 @@ ADD_MODPREPHASE("DeCouple", Options::buildApp) } // mephase begin if (HasThisPhase(kMplMe)) { -ADD_MEPHASE("loopcanon", MeOption::optLevel >= 2) -ADD_MEPHASE("splitcriticaledge", MeOption::optLevel >= 2) +ADD_MEPHASE("cfgbuild", theModule->IsCModule() && MeOption::optLevel >= 3) +ADD_MEPHASE("injectiv", theModule->IsCModule() && MeOption::optLevel >= 3) +ADD_MEPHASE("ssatab", theModule->IsCModule() && MeOption::optLevel >= 3) +ADD_MEPHASE("aliasclass", theModule->IsCModule() && MeOption::optLevel >= 3) +ADD_MEPHASE("ssa", theModule->IsCModule() && MeOption::optLevel >= 3) +ADD_MEPHASE("dse", theModule->IsCModule() && MeOption::optLevel >= 3) +ADD_MEPHASE("irmapbuild", theModule->IsCModule() && MeOption::optLevel >= 3) +ADD_MEPHASE("ivcanon", theModule->IsCModule() && MeOption::optLevel >= 3) +ADD_MEPHASE("hprop", theModule->IsCModule() && MeOption::optLevel >= 3) +ADD_MEPHASE("hdse", theModule->IsCModule() && MeOption::optLevel >= 3) +ADD_MEPHASE("lfopreemit", theModule->IsCModule() && MeOption::optLevel >= 3) +ADD_MEPHASE("cfgbuild", theModule->IsJavaModule() || MeOption::optLevel >= 1) ADD_MEPHASE("ssatab", theModule->IsJavaModule() || MeOption::optLevel >= 1) ADD_MEPHASE("aliasclass", theModule->IsJavaModule() || MeOption::optLevel >= 1) ADD_MEPHASE("ssa", theModule->IsJavaModule() || MeOption::optLevel >= 1) ADD_MEPHASE("dse", MeOption::optLevel >= 1) -ADD_MEPHASE("fsaa", MeOption::optLevel >= 1) ADD_MEPHASE("irmapbuild", MeOption::optLevel >= 1 || theModule->IsJavaModule()) ADD_MEPHASE("bdcopt", MeOption::optLevel >= 1 && theModule->IsJavaModule()) ADD_MEPHASE("syncselect", MeOption::optLevel >= 1 && theModule->IsJavaModule()) @@ -45,9 +54,9 @@ ADD_MEPHASE("ssadevirt", MeOption::optLevel >= 1 && theModule->IsJavaModule()) ADD_MEPHASE("hprop", MeOption::optLevel >= 1) ADD_MEPHASE("symrename", MeOption::optLevel >= 1) ADD_MEPHASE("hdse", MeOption::optLevel >= 1) +ADD_MEPHASE("cfgopt", MeOption::optLevel >= 2 && theModule->IsJavaModule()) ADD_MEPHASE("may2dassign", MeOption::optLevel >= 1 && theModule->IsJavaModule()) ADD_MEPHASE("condbasednpc", MeOption::optLevel >= 1 && theModule->IsJavaModule()) -ADD_MEPHASE("cfgopt", MeOption::optLevel >= 2 && theModule->IsJavaModule()) ADD_MEPHASE("epre", MeOption::optLevel >= 2) ADD_MEPHASE("stmtpre", MeOption::optLevel >= 2 && theModule->IsJavaModule()) ADD_MEPHASE("analyzerc", theModule->IsJavaModule()) diff --git a/mapleall/maple_driver/src/driver_runner.cpp b/mapleall/maple_driver/src/driver_runner.cpp index 46864e67c98630003704d173475ae131443d772e..5b9e6408dfc30c859a7873bd53b72552f9ea49ac 100644 --- a/mapleall/maple_driver/src/driver_runner.cpp +++ b/mapleall/maple_driver/src/driver_runner.cpp @@ -224,6 +224,19 @@ void DriverRunner::ProcessMpl2mplAndMeAndMplCgPhases(const std::string &interimO // emit after module phase if (printOutExe == kMpl2mpl || printOutExe == kMplMe || genVtableImpl || Options::emitVtableImpl) { theModule->Emit(interimOutputFile); + +//#define DUMP_ME_IR_IN_BPL 1 +#if DUMP_ME_IR_IN_BPL + size_t index = 0; + std::string bplFileName(interimOutputFile); + index = bplFileName.find(".mpl", index); + if (index != std::string::npos) { + bplFileName.replace(index, 4, ".bpl"); + BinaryMplt binMplt(*theModule); + binMplt.GetBinExport().not2mplt = true; + binMplt.Export(bplFileName, nullptr); + } +#endif } timer.Stop(); diff --git a/mapleall/maple_ipa/src/clone.cpp b/mapleall/maple_ipa/src/clone.cpp index 5b6a9103841631236598289fcd5e737a330c8d8d..6aaea21d1d6628299a142183ec4a7fd77b5f447d 100644 --- a/mapleall/maple_ipa/src/clone.cpp +++ b/mapleall/maple_ipa/src/clone.cpp @@ -117,7 +117,7 @@ MIRFunction *Clone::CloneFunction(MIRFunction *const originalFunction, const std classType->methods.push_back( MethodPair(newFunc->stIdx, TyidxFuncAttrPair(newFunc->GetFuncSymbol()->GetTyIdx(), originalFunction->funcAttrs))); newFunc->flag = originalFunction->flag; - newFunc->srcPosition = originalFunction->srcPosition; + newFunc->GetFuncSymbol()->srcPosition = originalFunction->GetFuncSymbol()->srcPosition; newFunc->SetAttrs(originalFunction->GetAttrs()); newFunc->SetBaseClassFuncNames(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fullName)); newFunc->easummary = originalFunction->easummary; diff --git a/mapleall/maple_ipa/src/interleaved_manager.cpp b/mapleall/maple_ipa/src/interleaved_manager.cpp index 05af2131675de257886bc1534f81480111c0b46e..a35c27b4b4971cf25fa890150363813cdcd05397 100644 --- a/mapleall/maple_ipa/src/interleaved_manager.cpp +++ b/mapleall/maple_ipa/src/interleaved_manager.cpp @@ -50,7 +50,6 @@ void InterleavedManager::AddPhases(const std::vector &phases, bool } else { // MeFuncPhase MeFuncPhaseManager *fpm = GetMempool()->New(GetMempool(), &mirModule, mrm); fpm->RegisterFuncPhases(); - fpm->mePhaseType = kMePhaseMainopt; if (genmpl) { fpm->genMeMpl = true; } diff --git a/mapleall/maple_ipa/src/ipadriver.cpp b/mapleall/maple_ipa/src/ipadriver.cpp index 4a148dd6fcc67ec8640881f89760a97896008503..977304b7179c99263c63f42e6e16c9b27b2160c6 100644 --- a/mapleall/maple_ipa/src/ipadriver.cpp +++ b/mapleall/maple_ipa/src/ipadriver.cpp @@ -129,10 +129,12 @@ void DoIpaSideEffectAnalysis(MIRModule *mirModule) { modphases.clear(); vector mephases; - mephases.push_back(string("loopcanon")); - mephases.push_back(string("splitcriticaledge")); + 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); @@ -142,8 +144,12 @@ void DoIpaSideEffectAnalysis(MIRModule *mirModule) { 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); diff --git a/mapleall/maple_ir/include/debug_info.h b/mapleall/maple_ir/include/debug_info.h index 776cea75e37bfd3d706b8d4966c2b78abe0a3d8c..428f28a57a59780a7fd62f42c475c9b410541803 100644 --- a/mapleall/maple_ir/include/debug_info.h +++ b/mapleall/maple_ir/include/debug_info.h @@ -392,7 +392,7 @@ class DebugInfo { DBGDieAttr *CreateAttr(dw_at attr, dw_form form, uint64 val); DBGDie *CreateVarDie(MIRSymbol *sym, uint32 lnum); - DBGDie *CreateFormalParaDie(MIRType *type, GStrIdx nameidx, uint32 lnum); + DBGDie *CreateFormalParaDie(MIRFunction *func, MIRType *type, GStrIdx nameidx, uint32 lnum); DBGDie *CreateFieldDie(maple::FieldPair pair, uint32 lnum); DBGDie *CreateStructTypeDie(GStrIdx strIdx, const MIRStructType *type, bool update = false); DBGDie *CreateClassTypeDie(GStrIdx strIdx, const MIRClassType *type); diff --git a/mapleall/maple_ir/include/intrinsics.def b/mapleall/maple_ir/include/intrinsics.def index 91d027ef1d83ed5edfe656b478b4ffac45d75d60..18889bb75a6bfb759be6961a20a2d83e282bb99e 100644 --- a/mapleall/maple_ir/include/intrinsics.def +++ b/mapleall/maple_ir/include/intrinsics.def @@ -192,6 +192,7 @@ DEF_MIR_INTRINSIC(MCCNewPermanentArray,\ #include "intrinsic_misc.def" #include "intrinsic_c.def" +#include "js2mpl/jsintrinsic_eng.def" DEF_MIR_INTRINSIC(LAST,\ nullptr, kIntrnUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) diff --git a/mapleall/maple_ir/include/js2mpl/jsintrinsic.def b/mapleall/maple_ir/include/js2mpl/jsintrinsic.def index 7d5650cb339bab285f610982201d2ce775bd3cca..1c42c3d4ea6ceec35048de41802e96e71061be46 100644 --- a/mapleall/maple_ir/include/js2mpl/jsintrinsic.def +++ b/mapleall/maple_ir/include/js2mpl/jsintrinsic.def @@ -116,3 +116,4 @@ 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) + diff --git a/mapleall/maple_ir/include/js2mpl/jsintrinsic_eng.def b/mapleall/maple_ir/include/js2mpl/jsintrinsic_eng.def new file mode 100644 index 0000000000000000000000000000000000000000..aed902742f6e4a95a41b964a1639ca996df91948 --- /dev/null +++ b/mapleall/maple_ir/include/js2mpl/jsintrinsic_eng.def @@ -0,0 +1,34 @@ +/* + * 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. + */ + +// DEF_MIR_INTRINSIC(STR, NAME, INTRN_CLASS, RETURN_TYPE, ARG0, ARG1, ARG2, ARG3, ARG4, ARG5) +DEF_MIR_INTRINSIC(JS_GET_ARGUMENTOBJECT,\ + __jsobj_get_or_create_argument, INTRNISJS | INTRNISPURE, kArgTySimpleobj, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) +DEF_MIR_INTRINSIC(JS_GET_ERROR_OBJECT,\ + __jsobj_get_or_create_error, INTRNISJS | INTRNISPURE, kArgTySimpleobj, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) +DEF_MIR_INTRINSIC(JS_GET_EVALERROR_OBJECT,\ + __jsobj_get_or_create_evalError, INTRNISJS | INTRNISPURE, kArgTySimpleobj, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) +DEF_MIR_INTRINSIC(JS_GET_RANGEERROR_OBJECT,\ + __jsobj_get_or_create_rangeError, INTRNISJS | INTRNISPURE, kArgTySimpleobj, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) +DEF_MIR_INTRINSIC(JS_GET_REFERENCEERROR_OBJECT,\ + __jsobj_get_or_create_referenceError, INTRNISJS | INTRNISPURE, kArgTySimpleobj, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) +DEF_MIR_INTRINSIC(JS_GET_SYNTAXERROR_OBJECT,\ + __jsobj_get_or_create_syntaxError, INTRNISJS | INTRNISPURE, kArgTySimpleobj, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) +DEF_MIR_INTRINSIC(JS_GET_TYPEERROR_OBJECT,\ + __jsobj_get_or_create_typeError, INTRNISJS | INTRNISPURE, kArgTySimpleobj, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) +DEF_MIR_INTRINSIC(JS_GET_URIERROR_OBJECT,\ + __jsobj_get_or_create_uriError, INTRNISJS | INTRNISPURE, kArgTySimpleobj, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) +DEF_MIR_INTRINSIC(JSOP_ASSERTVALUE, + __jsop_assert_value, INTRNISJS, kArgTyDynany, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) diff --git a/mapleall/maple_ir/include/mir_function.h b/mapleall/maple_ir/include/mir_function.h index 4802dea3e4465ceaffa7435134bd74d318da5b40..db21a203abcb3be30841f9da653b6fab20daf639 100644 --- a/mapleall/maple_ir/include/mir_function.h +++ b/mapleall/maple_ir/include/mir_function.h @@ -28,8 +28,6 @@ #define DEBUGME true namespace maple { -class BlockNode; -class SrcPosition; enum MIRFuncProp { kFuncPropNone = 0, @@ -93,7 +91,6 @@ class MIRFunction : public mir_func_t { MapleAllocator codeMemPoolTmpAllocator; bool useTmpMp; BlockNode *body; - SrcPosition srcPosition; FuncAttrs funcAttrs; uint32 flag; uint16 hashCode; // for methodmetadata order @@ -520,6 +517,10 @@ class MIRFunction : public mir_func_t { return classTyIdx.GetIdx(); } + bool IsC() const { + return module->srcLang == kSrcLangC; + } + MIRType *GetNodeType(base_node_t *node); #ifdef DEBUGME void SetUpGDBEnv(); diff --git a/mapleall/maple_ir/include/mir_module.h b/mapleall/maple_ir/include/mir_module.h index 90016499451ebf3c911bb7c96264d8151d7eb7b7..1f5dd23b94091dd390859499be14554bea234849 100644 --- a/mapleall/maple_ir/include/mir_module.h +++ b/mapleall/maple_ir/include/mir_module.h @@ -240,6 +240,10 @@ class MIRModule : public mir_module_t { return srcLang == kSrcLangC || srcLang == kSrcLangCPlusPlus; } + bool IsJsModule() const { + return srcLang == kSrcLangJs; + } + void ReleaseCurFuncMpTmp(); inline void SetUseFuncCodeMpTmp() { useFuncCodeMpTmp = true; diff --git a/mapleall/maple_ir/include/mir_nodes.h b/mapleall/maple_ir/include/mir_nodes.h index 7b51441780377661bd732d4f6c18009de0165ab7..239d43646c4dcc3f86ee4a7a9d68250a77f9be22 100644 --- a/mapleall/maple_ir/include/mir_nodes.h +++ b/mapleall/maple_ir/include/mir_nodes.h @@ -25,6 +25,7 @@ #include "mir_module.h" #include "mir_const.h" #include "maple_string.h" +#include "src_position.h" #include "ptr_list_ref.h" namespace maple { @@ -1333,78 +1334,6 @@ class AddroflabelNode : public BaseNode { } }; -// to store source position information -class SrcPosition { - private: - union { - struct { - uint16 fileNum; - uint16 column : 12; - uint16 stmtBegin : 1; - uint16 bbBegin : 1; - uint16 unused : 2; - } fileColumn; - uint32 word0; - } u; - uint32 lineNum; // line number of original src file, like foo.java - uint32 mplLineNum; // line number of mpl file - public: - SrcPosition() : lineNum(0), mplLineNum(0) { - u.word0 = 0; - } - - virtual ~SrcPosition() = default; - - uint32 RawData() const { - return u.word0; - } - - uint32 Filenum() const { - return u.fileColumn.fileNum; - } - - uint32 Column() const { - return u.fileColumn.column; - } - - uint32 Linenum() const { - return lineNum; - } - - uint32 MplLinenum() const { - return mplLineNum; - } - - void SetFilenum(int n) { - u.fileColumn.fileNum = n; - } - - void SetColumn(int n) { - u.fileColumn.column = n; - } - - void SetLinenum(int n) { - lineNum = n; - } - - void SetRawData(uint32 n) { - u.word0 = n; - } - - void SetMplLinenum(int n) { - mplLineNum = n; - } - - void CondSetLinenum(int n) { - lineNum = lineNum ? lineNum : n; - } - - void CondSetFilenum(int n) { - uint32 i = u.fileColumn.fileNum; - u.fileColumn.fileNum = i ? i : n; - } -}; - // for cleanuptry, jscatch, finally, retsub, endtry, membaracquire, membarrelease, // membarstoreload, membarstorestore class StmtNode : public BaseNode, public PtrListNodeBase { diff --git a/mapleall/maple_ir/include/mir_parser.h b/mapleall/maple_ir/include/mir_parser.h index 6d92c3b69b35a949f30ee15b7fc54bf2b9b5b001..75fba4048deb562e6e118fb44d5f4bf4da9bac01 100644 --- a/mapleall/maple_ir/include/mir_parser.h +++ b/mapleall/maple_ir/include/mir_parser.h @@ -155,7 +155,8 @@ class MIRParser { mod.SetCurFunction((mir_func_t *)dummyFunction); } - bool ParseLoc(StmtNode *&stmt); + bool ParseLoc(); + bool ParseLocStmt(StmtNode *&stmt); bool ParseAlias(StmtNode *&stmt); uint8 *ParseWordsInfo(uint32 size); bool ParseSwitchCase(int32 &constVal, LabelIdx &lblidx); @@ -306,7 +307,7 @@ class MIRParser { void FixupForwardReferencedTypeByMap(); // common func - void SetSrcPos(StmtNode *stmt, uint32 mplNum); + void SetSrcPos(SrcPosition &srcPosition, uint32 mplNum); void CollectIncompleteTypes(); bool IsIncomplete() { diff --git a/mapleall/maple_ir/include/mir_symbol.h b/mapleall/maple_ir/include/mir_symbol.h index 0651f64fada7ba3efbc425740a0834fb1e0915eb..465e5e27d4914073aeee9925f47e3bbf718191aa 100644 --- a/mapleall/maple_ir/include/mir_symbol.h +++ b/mapleall/maple_ir/include/mir_symbol.h @@ -17,6 +17,7 @@ #define MAPLE_IR_INCLUDE_MIR_SYMBOL_H #include "mir_const.h" #include "mir_preg.h" +#include "src_position.h" #include constexpr int kScopeLocal = 2; // the default scope level for function variables @@ -53,6 +54,7 @@ enum MIRStorageClass : uint8 { // to represent a single symbol class MIRSymbol { public: + static uint32 lastPrintedLinenum; // used during printing ascii output union SymbolType { // a symbol can either be a const or a function or a preg which currently used for formal MIRConst *konst; MIRFunction *mirFunc; @@ -77,6 +79,7 @@ class MIRSymbol { TypeAttrs typeAttrs; GStrIdx nameStrIdx; SymbolType value; + SrcPosition srcPosition; // where the symbol is defined static GStrIdx reflectClassNameIdx; static GStrIdx reflectMethodNameIdx; diff --git a/mapleall/maple_ir/include/mir_type.h b/mapleall/maple_ir/include/mir_type.h index 56ff3f957574141b47f73de03bcf9e6accc7f365..5202beb301858b754fa1e457a49a60d475d721a1 100644 --- a/mapleall/maple_ir/include/mir_type.h +++ b/mapleall/maple_ir/include/mir_type.h @@ -41,6 +41,7 @@ using FieldVector = std::vector; extern bool VerifyPrimType(PrimType pty1, PrimType pty2); // verify if pty1 and pty2 match extern uint32 GetPrimTypeSize(PrimType pty); // answer in bytes; 0 if unknown extern uint32 GetPrimTypeP2Size(PrimType pty); // answer in bytes in power-of-two. +extern const PrimType GetSignedPrimType(PrimType pty); // return signed version extern const char *GetPrimTypeName(PrimType ty); extern const char *GetPrimTypeJavaName(PrimType ty); diff --git a/mapleall/maple_ir/include/src_position.h b/mapleall/maple_ir/include/src_position.h new file mode 100644 index 0000000000000000000000000000000000000000..2fe7e54b0ff0327818b0828403c7ea59675b88f9 --- /dev/null +++ b/mapleall/maple_ir/include/src_position.h @@ -0,0 +1,94 @@ +/* + * 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. + */ + +#ifndef MAPLE_IR_INCLUDE_SRC_POSITION_H +#define MAPLE_IR_INCLUDE_SRC_POSITION_H + +namespace maple { + +// to store source position information +class SrcPosition { + private: + union { + struct { + uint16 fileNum; + uint16 column : 12; + uint16 stmtBegin : 1; + uint16 bbBegin : 1; + uint16 unused : 2; + } fileColumn; + uint32 word0; + } u; + uint32 lineNum; // line number of original src file, like foo.java + uint32 mplLineNum; // line number of mpl file + public: + SrcPosition() : lineNum(0), mplLineNum(0) { + u.word0 = 0; + } + + virtual ~SrcPosition() = default; + + uint32 RawData() const { + return u.word0; + } + + uint32 Filenum() const { + return u.fileColumn.fileNum; + } + + uint32 Column() const { + return u.fileColumn.column; + } + + uint32 Linenum() const { + return lineNum; + } + + uint32 MplLinenum() const { + return mplLineNum; + } + + void SetFilenum(int n) { + u.fileColumn.fileNum = n; + } + + void SetColumn(int n) { + u.fileColumn.column = n; + } + + void SetLinenum(int n) { + lineNum = n; + } + + void SetRawData(uint32 n) { + u.word0 = n; + } + + void SetMplLinenum(int n) { + mplLineNum = n; + } + + void CondSetLinenum(int n) { + lineNum = lineNum ? lineNum : n; + } + + void CondSetFilenum(int n) { + uint32 i = u.fileColumn.fileNum; + u.fileColumn.fileNum = i ? i : n; + } +}; +} // namespace maple +#endif // MAPLE_IR_INCLUDE_SRC_POSITION_H + diff --git a/mapleall/maple_ir/src/bin_func_export.cpp b/mapleall/maple_ir/src/bin_func_export.cpp index 18efb3dc1b7d0571baae59a37b0c7aaf8d9bff17..0e7969d911794ed95d5802b1f8aed8d2146fce1f 100644 --- a/mapleall/maple_ir/src/bin_func_export.cpp +++ b/mapleall/maple_ir/src/bin_func_export.cpp @@ -61,11 +61,14 @@ void BinaryMplExport::OutputLocalSymbol(const MIRSymbol *sym) { WriteNum(kBinSymbol); WriteNum(sym->GetStIndex()); // preserve original st index OutputStr(sym->nameStrIdx); - OutputTypeViaTypeName(sym->tyIdx); WriteNum(sym->sKind); WriteNum(sym->storageClass); OutputTypeAttrs(sym->typeAttrs); WriteNum(sym->isTmp); + if (sym->sKind == kStVar || sym->sKind == kStFunc) { + OutputSrcPos(sym->srcPosition); + } + OutputTypeViaTypeName(sym->tyIdx); if (sym->sKind == kStPreg) { WriteNum(sym->value.preg->pregNo); } else if (sym->sKind == kStConst || sym->sKind == kStVar) { diff --git a/mapleall/maple_ir/src/bin_func_import.cpp b/mapleall/maple_ir/src/bin_func_import.cpp index ad6c88d7892f6a4d136de95da0a517fc88315a86..9aadcc41179683d0bdace668d2e21f3ed9885c86 100644 --- a/mapleall/maple_ir/src/bin_func_import.cpp +++ b/mapleall/maple_ir/src/bin_func_import.cpp @@ -72,11 +72,14 @@ void BinaryMplImport::ImportLocalSymbol(MIRFunction *func) { MIRSymbol *sym = func->symTab->CreateSymbol(kScopeLocal); sym->nameStrIdx = ImportStr(); func->symTab->AddToStringSymbolMap(sym); - sym->tyIdx = ImportType(); sym->sKind = (MIRSymKind)ReadNum(); sym->storageClass = (MIRStorageClass)ReadNum(); sym->typeAttrs = ImportTypeAttrs(); sym->isTmp = ReadNum(); + if (sym->sKind == kStVar || sym->sKind == kStFunc) { + ImportSrcPos(sym->srcPosition); + } + sym->tyIdx = ImportType(); if (sym->sKind == kStPreg) { uint32 thepregno = ReadNum(); MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->tyIdx); diff --git a/mapleall/maple_ir/src/bin_mpl_export.cpp b/mapleall/maple_ir/src/bin_mpl_export.cpp index d1e6682345c379411e1c4a5bed7730a6376c5c3d..46656fb63900498558e70d04440e486240a3cd22 100644 --- a/mapleall/maple_ir/src/bin_mpl_export.cpp +++ b/mapleall/maple_ir/src/bin_mpl_export.cpp @@ -625,6 +625,9 @@ void BinaryMplExport::OutputSymbol(MIRSymbol *sym) { } else { CHECK_FATAL(false, "should not used"); } + if (sym->sKind == kStVar || sym->sKind == kStFunc) { + OutputSrcPos(sym->srcPosition); + } OutputTypeViaTypeName(sym->tyIdx); } diff --git a/mapleall/maple_ir/src/bin_mpl_import.cpp b/mapleall/maple_ir/src/bin_mpl_import.cpp index ae9132845d4600b2018cfeccd3ae5c5e9a6afb04..ed3571d87f226160e69728acf147682fd41bcc38 100644 --- a/mapleall/maple_ir/src/bin_mpl_import.cpp +++ b/mapleall/maple_ir/src/bin_mpl_import.cpp @@ -784,6 +784,9 @@ MIRSymbol *BinaryMplImport::InSymbol(MIRFunction *func) { sym->value.mirFunc = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); } } + if (sKind == kStVar || sKind == kStFunc) { + ImportSrcPos(sym->srcPosition); + } TyIdx tyIdx = ImportType(); sym->tyIdx = tyIdx; if (sKind == kStPreg) { diff --git a/mapleall/maple_ir/src/constant_fold.cpp b/mapleall/maple_ir/src/constant_fold.cpp index ed3dcc407815bee2744aadec3084598e8d4a7e51..864e0da77f9813342ca13715470966704c1b0730 100644 --- a/mapleall/maple_ir/src/constant_fold.cpp +++ b/mapleall/maple_ir/src/constant_fold.cpp @@ -1967,7 +1967,8 @@ StmtNode *ConstantFold::SimplifyBlock(BlockNode *n) { StmtNode *prevstmt = nullptr; do { StmtNode *retval = Simplify(s); - if (retval != nullptr) { + if (retval != nullptr && + !(retval->op == OP_block && static_cast(retval)->IsEmpty())) { if (retval->op == OP_block) { BlockNode *blk = static_cast(retval); n->ReplaceStmtWithBlock(s, blk); diff --git a/mapleall/maple_ir/src/debug_info.cpp b/mapleall/maple_ir/src/debug_info.cpp index 88efdcc15e33c937ed8435b65622412e0c99bab6..e19645c0845c0fb1659e2ba3a6697e50acc1dfe9 100644 --- a/mapleall/maple_ir/src/debug_info.cpp +++ b/mapleall/maple_ir/src/debug_info.cpp @@ -329,11 +329,17 @@ void DebugInfo::BuildDebugInfo() { } // function decl if (stridx_dieid_map_.find(func->GetNameStridx().GetIdx()) == stridx_dieid_map_.end()) { - GetOrCreateFuncDeclDie(func, 0); + DBGDie *fdie = GetOrCreateFuncDeclDie(func, 0); + if (!func->classTyIdx.GetIdx() && func->body) { + cu_->AddSubVec(fdie); + } } // function def if (funcdef_stridx_dieid_map_.find(func->GetNameStridx().GetIdx()) == funcdef_stridx_dieid_map_.end()) { - GetOrCreateFuncDefDie(func, 0); + DBGDie *fdie = GetOrCreateFuncDefDie(func, 0); + if (!func->classTyIdx.GetIdx() && func->body) { + cu_->AddSubVec(fdie); + } } } @@ -385,7 +391,7 @@ LabelIdx DebugInfo::GetLabelIdx(GStrIdx strIdx) { return labidx; } -DBGDie *DebugInfo::CreateFormalParaDie(MIRType *type, GStrIdx nameidx, uint32 lnum) { +DBGDie *DebugInfo::CreateFormalParaDie(MIRFunction *func, MIRType *type, GStrIdx nameidx, uint32 lnum) { DBGDie *die = mod_->memPool->New(mod_, DW_TAG_formal_parameter); (void)GetOrCreateTypeDie(type); @@ -397,7 +403,7 @@ DBGDie *DebugInfo::CreateFormalParaDie(MIRType *type, GStrIdx nameidx, uint32 ln die->AddAttr(DW_AT_decl_file, DW_FORM_data4, mplsrcidx_.GetIdx()); die->AddAttr(DW_AT_decl_line, DW_FORM_data4, lnum); die->AddSimpLocAttr(DW_AT_location, DW_FORM_exprloc, kDbgDefaultVal); - SetLocalDie(nameidx, die); + SetLocalDie(func, nameidx, die); } return die; } @@ -521,7 +527,7 @@ DBGDie *DebugInfo::GetOrCreateFuncDeclDie(MIRFunction *func, uint32 lnum) { GStrIdx strIdx(0); for (uint32 i = 0; i < func->formalDefVec.size(); i++) { MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(func->formalDefVec[i].formalTyIdx); - DBGDie *param = CreateFormalParaDie(type, strIdx, lnum); + DBGDie *param = CreateFormalParaDie(func, type, strIdx, lnum); die->AddSubVec(param); } @@ -561,7 +567,7 @@ DBGDie *DebugInfo::GetOrCreateFuncDefDie(MIRFunction *func, uint32 lnum) { // formal parameter for (uint32 i = 0; i < func->formalDefVec.size(); i++) { MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(func->formalDefVec[i].formalTyIdx); - DBGDie *pdie = CreateFormalParaDie(type, func->formalDefVec[i].formalStrIdx, lnum); + DBGDie *pdie = CreateFormalParaDie(func, type, func->formalDefVec[i].formalStrIdx, lnum); die->AddSubVec(pdie); } @@ -858,6 +864,9 @@ DBGDie *DebugInfo::CreateStructTypeDie(GStrIdx strIdx, const MIRStructType *stru MIRSymbol *symbol = GlobalTables::GetGsymTable().GetSymbolFromStIdx(fp.first.Idx()); ASSERT(symbol && symbol->sKind == kStFunc, "member function symbol not exist"); MIRFunction *func = symbol->value.mirFunc; + if (!func->body) { + continue; + } ASSERT(func, "member function not exist"); DBGDie *fdie = GetOrCreateFuncDefDie(func, 0); cu_->AddSubVec(fdie); diff --git a/mapleall/maple_ir/src/lexer.cpp b/mapleall/maple_ir/src/lexer.cpp index 58074f34275a367782799345469a1a05f891a5e0..4bb6e2f5e8fca35ade10d5a812ec0998fc961e85 100644 --- a/mapleall/maple_ir/src/lexer.cpp +++ b/mapleall/maple_ir/src/lexer.cpp @@ -360,7 +360,7 @@ TokenKind MIRLexer::GetTokenWithPrefixPercent() { TokenKind MIRLexer::GetTokenWithPrefixAmpersand() { // token with prefix '&' char c = GetCurrentCharWithUpperCheck(); - if (isalpha(c) || c == '_') { + if (isalpha(c) || c == '_' || c == '$') { GenName(); return TK_fname; } else { diff --git a/mapleall/maple_ir/src/mir_function.cpp b/mapleall/maple_ir/src/mir_function.cpp index 22af22836e5ea99243730975423da1a13929ad0e..d965fffac63c9aba3552305153d3232c639e01bc 100644 --- a/mapleall/maple_ir/src/mir_function.cpp +++ b/mapleall/maple_ir/src/mir_function.cpp @@ -43,6 +43,12 @@ void MIRFunction::Dump(bool withoutBody) { module->SetCurFunction(this); MIRSymbol *fnSt = GlobalTables::GetGsymTable().GetSymbolFromStIdx(stIdx.Idx()); + if (!withoutBody) { + if (fnSt->srcPosition.Filenum() != 0 && fnSt->srcPosition.Linenum() != 0 && fnSt->srcPosition.Linenum() != MIRSymbol::lastPrintedLinenum) { + LogInfo::MapleLogger() << "LOC " << fnSt->srcPosition.Filenum() << " " << fnSt->srcPosition.Linenum() << std::endl; + MIRSymbol::lastPrintedLinenum = fnSt->srcPosition.Linenum(); + } + } LogInfo::MapleLogger() << "func " << "&" << fnSt->GetName(); funcAttrs.DumpAttributes(); diff --git a/mapleall/maple_ir/src/mir_parser_expr.cpp b/mapleall/maple_ir/src/mir_parser_expr.cpp index bb615588f0ccca12c4d90b5d105b82f875032bd6..df46f743b50a0231d883cfbfe931e6552caf21b1 100644 --- a/mapleall/maple_ir/src/mir_parser_expr.cpp +++ b/mapleall/maple_ir/src/mir_parser_expr.cpp @@ -1159,11 +1159,14 @@ bool MIRParser::ParseExprIntrinsicopwithtype(BaseNode *&expr) { bool MIRParser::ParseScalarValue(MIRConst *&stype, MIRType *type) { PrimType ptp = type->primType; if (IsPrimitiveInteger(ptp) || IsPrimitiveDynType(ptp) || ptp == PTY_gen) { - if (lexer.GetTokenKind() != TK_intconst) { + if (lexer.GetTokenKind() == TK_intconst) { + stype = mod.memPool->New(lexer.GetTheIntVal(), type); + } else if (lexer.GetTokenKind() == TK_doubleconst) { + stype = mod.memPool->New(lexer.GetTheDoubleVal(), type); + } else { Error("constant value incompatible with integer type at "); return false; } - stype = mod.memPool->New(lexer.GetTheIntVal(), type); } else if (ptp == PTY_f32) { if (lexer.GetTokenKind() != TK_floatconst) { Error("constant value incompatible with single-precision float type at "); diff --git a/mapleall/maple_ir/src/mir_parser_stmt.cpp b/mapleall/maple_ir/src/mir_parser_stmt.cpp index 2c03125f2896fbefd3c9869fde43bbf6146ec8f1..d4e8dbafb8ec35051ca1296c75a552fe8c8980ae 100644 --- a/mapleall/maple_ir/src/mir_parser_stmt.cpp +++ b/mapleall/maple_ir/src/mir_parser_stmt.cpp @@ -1631,7 +1631,7 @@ bool MIRParser::ParseNaryStmtSyncExit(StmtNode* &stmt) { return ParseNaryStmt(stmt, OP_syncexit); } -bool MIRParser::ParseLoc(StmtNode *&stmt) { +bool MIRParser::ParseLoc() { if (lexer.NextToken() != TK_intconst) { Error("expect intconst in LOC but get "); return false; @@ -1649,6 +1649,10 @@ bool MIRParser::ParseLoc(StmtNode *&stmt) { return true; } +bool MIRParser::ParseLocStmt(StmtNode *&stmt) { + return ParseLoc(); +} + bool MIRParser::ParseStatement(StmtNode *&stmt) { paramTokenKindForStmt = lexer.GetTokenKind(); uint32 mplNum = lexer.GetLineNum(); @@ -1701,7 +1705,6 @@ bool MIRParser::ParseStmtBlock(BlockNode* &blk) { return false; } if (stmt != nullptr) { // stmt is nullptr if it is a LOC - // SetSrcPos(stmt, mplNum); blk->AddStatement(stmt); } } else { @@ -1730,7 +1733,7 @@ void MIRParser::ParseStmtBlockForSeenComment(BlockNode* blk, uint32 mplNum) { for (size_t i = 0; i < lexer.seenComments.size(); i++) { CommentNode *cmnt = mod.CurFuncCodeMemPool()->New(&mod); cmnt->comment = lexer.seenComments[i]; - SetSrcPos(cmnt, mplNum); + SetSrcPos(cmnt->srcPosition, mplNum); blk->AddStatement(cmnt); } lexer.GetSeenComments().clear(); @@ -1742,6 +1745,7 @@ bool MIRParser::ParseStmtBlockForVar(TokenKind stmtTK) { MIRSymbol *st = fn->symTab->CreateSymbol(kScopeLocal); st->SetStorageClass(kScAuto); st->sKind = kStVar; + SetSrcPos(st->srcPosition, lexer.GetLineNum()); if (stmtTK == TK_tempvar) { st->isTmp = true; } @@ -2000,7 +2004,7 @@ std::map MIRParser::InitFuncPtrMapForPar funcPtrMap[TK_assertge] = &MIRParser::ParseBinaryStmtAssertGE; funcPtrMap[TK_assertlt] = &MIRParser::ParseBinaryStmtAssertLT; funcPtrMap[TK_label] = &MIRParser::ParseStmtLabel; - funcPtrMap[TK_LOC] = &MIRParser::ParseLoc; + funcPtrMap[TK_LOC] = &MIRParser::ParseLocStmt; funcPtrMap[TK_ALIAS] = &MIRParser::ParseAlias; return funcPtrMap; } @@ -2024,10 +2028,10 @@ std::map MIRParser::InitFuncPtrMapF return funcPtrMap; } -void MIRParser::SetSrcPos(StmtNode *stmt, uint32 mplNum) { - stmt->srcPosition.SetFilenum(lastFileNum); - stmt->srcPosition.SetLinenum(lastLineNum); - stmt->srcPosition.SetMplLinenum(mplNum); +void MIRParser::SetSrcPos(SrcPosition &srcPosition, uint32 mplNum) { + srcPosition.SetFilenum(lastFileNum); + srcPosition.SetLinenum(lastLineNum); + srcPosition.SetMplLinenum(mplNum); } } // namespace maple diff --git a/mapleall/maple_ir/src/mir_symbol.cpp b/mapleall/maple_ir/src/mir_symbol.cpp index 40368b5dbd0b0b5e0c6b578f92edb3ca94703a6a..8408a00a0c33beea7d353fa8bbac5222c6c91dcc 100644 --- a/mapleall/maple_ir/src/mir_symbol.cpp +++ b/mapleall/maple_ir/src/mir_symbol.cpp @@ -25,6 +25,7 @@ #include "literal_str_name.h" namespace maple { +uint32 MIRSymbol::lastPrintedLinenum = 0; MIRType *MIRSymbol::GetType() const { return GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); @@ -275,6 +276,12 @@ bool MIRSymbol::IgnoreRC() { // is RC needed } void MIRSymbol::Dump(bool isLocal, int32 indent, bool suppressinit, const MIRSymbolTable *localsymtab) const { + if (sKind == kStVar || sKind == kStFunc) { + if (srcPosition.Filenum() != 0 && srcPosition.Linenum() != 0 && srcPosition.Linenum() != lastPrintedLinenum) { + LogInfo::MapleLogger() << "LOC " << srcPosition.Filenum() << " " << srcPosition.Linenum() << std::endl; + lastPrintedLinenum = srcPosition.Linenum(); + } + } if (storageClass == kScUnused) { return; } diff --git a/mapleall/maple_ir/src/mir_type.cpp b/mapleall/maple_ir/src/mir_type.cpp index 0807c5b035b98d7f02e30e118a2fbab9ec2de0f7..fb2cab4d6baf20b48367738ea15f566892a9a530 100644 --- a/mapleall/maple_ir/src/mir_type.cpp +++ b/mapleall/maple_ir/src/mir_type.cpp @@ -163,9 +163,10 @@ uint32 GetPrimTypeSize(PrimType pty) { case PTY_f32: case PTY_i32: case PTY_u32: + return 4; case PTY_simplestr: case PTY_simpleobj: - return 4; + return 8; case PTY_a64: case PTY_c64: case PTY_f64: @@ -248,6 +249,26 @@ uint32 GetPrimTypeP2Size(PrimType pty) { } } +// return the signed version that has the same size +const PrimType GetSignedPrimType(PrimType pty) { + switch (pty) { + case PTY_ptr: + case PTY_ref: + case PTY_a64: + case PTY_u64: + return PTY_i64; + case PTY_u8: + return PTY_i8; + case PTY_u16: + return PTY_i16; + case PTY_a32: + case PTY_u32: + return PTY_i32; + default: ; + } + return pty; +} + const char *GetPrimTypeName(PrimType ty) { #define LOAD_ALGO_PRIMARY_TYPE switch (ty) { diff --git a/mapleall/maple_ir/src/parser.cpp b/mapleall/maple_ir/src/parser.cpp index 6fe54421674c3db8f441d51f6a0970c89f6c2646..1e9f2cddbc3180feb9dc695401e41429656cbb90 100644 --- a/mapleall/maple_ir/src/parser.cpp +++ b/mapleall/maple_ir/src/parser.cpp @@ -735,6 +735,7 @@ bool MIRParser::ParseFields(MIRStructType &type) { GlobalTables::GetGsymTable().AddToStringSymbolMap(funcSt); funcSt->storageClass = kScText; funcSt->sKind = kStFunc; + SetSrcPos(funcSt->srcPosition, lexer.GetLineNum()); MIRFunction *fn = mod.memPool->New(&mod, funcSt->GetStIdx()); fn->puIdx = GlobalTables::GetFunctionTable().funcTable.size(); @@ -1999,6 +2000,7 @@ bool MIRParser::ParseFunction(uint32 fileidx) { GlobalTables::GetGsymTable().AddToStringSymbolMap(funcSt); funcSt->storageClass = kScText; funcSt->sKind = kStFunc; + SetSrcPos(funcSt->srcPosition, lexer.GetLineNum()); fn = mod.memPool->New(&mod, funcSt->GetStIdx()); fn->puIdx = GlobalTables::GetFunctionTable().funcTable.size(); @@ -2026,7 +2028,7 @@ bool MIRParser::ParseFunction(uint32 fileidx) { mod.AddFunction(fn); // set maple line number for function - fn->srcPosition.SetMplLinenum(lexer.GetLineNum()); + fn->GetFuncSymbol()->srcPosition.SetMplLinenum(lexer.GetLineNum()); // initialize source line number to be 0 // to avoid carrying over info from previous function @@ -2043,8 +2045,8 @@ bool MIRParser::ParseFunction(uint32 fileidx) { fn->body = block; // set source file number for function - fn->srcPosition.SetLinenum(firstLineNum); - fn->srcPosition.SetFilenum(lastFileNum); + fn->GetFuncSymbol()->srcPosition.SetLinenum(firstLineNum); + fn->GetFuncSymbol()->srcPosition.SetFilenum(lastFileNum); // check if any local type name is undefined for (auto it : fn->typeNameTab->gStrIdxToTyIdxMap) { @@ -2579,6 +2581,7 @@ std::map MIRParser::InitFuncPtrMap funcPtrMap[TK_srcfileinfo] = &MIRParser::ParseMIRForSrcFileInfo; funcPtrMap[TK_import] = &MIRParser::ParseMIRForImport; funcPtrMap[TK_importpath] = &MIRParser::ParseMIRForImportPath; + funcPtrMap[TK_LOC] = &MIRParser::ParseLoc; return funcPtrMap; } @@ -2627,6 +2630,7 @@ bool MIRParser::ParseMIRForVar() { newst->SetAttrs(st.GetAttrs()); newst->SetNameStridx(st.GetNameStridx()); newst->value = st.value; + SetSrcPos(newst->srcPosition, lexer.GetLineNum()); } return true; } diff --git a/mapleall/maple_me/BUILD.gn b/mapleall/maple_me/BUILD.gn index 51f6db8399373131d2d852e1cc3c8e9b2fb7fb73..01d06ec0ac59312e126f6d376c5ede0f7f0568b4 100644 --- a/mapleall/maple_me/BUILD.gn +++ b/mapleall/maple_me/BUILD.gn @@ -74,7 +74,11 @@ static_library("libmplme"){ "src/me_delegate_rc.cpp", "src/me_fsaa.cpp", "src/me_sym_rename.cpp", - "src/me_predict.cpp" + "src/me_predict.cpp", + "src/lfo_mir_lower.cpp", + "src/lfo_pre_emit.cpp", + "src/lfo_inject_iv.cpp", + "src/lfo_iv_canon.cpp", ] include_dirs = include_directories diff --git a/mapleall/maple_me/include/bb.h b/mapleall/maple_me/include/bb.h index d68095bac190e0111e76d1ae2b13c4176060cefb..6277382fbba6e8ac5ffa3edc01f0509904758873 100644 --- a/mapleall/maple_me/include/bb.h +++ b/mapleall/maple_me/include/bb.h @@ -101,7 +101,7 @@ class BB { LabelIdx bbLabel; // the BB's label MapleVector pred; // predecessor list MapleVector succ; // successor list - MapleMap phiList; + MapleMap *phiList; MapleMap mePhiList; StmtNodes stmtNodeList; MeStmts meStmtList; @@ -121,12 +121,12 @@ class BB { bool isInLoop : 1; // Is bb in a loop body public: - BB(MapleAllocator *alloc, MapleAllocator *versAlloc, BBId id) + BB(MapleAllocator *alloc, BBId id) : id(id), bbLabel(0), pred(2, nullptr, alloc->Adapter()), succ(2, nullptr, alloc->Adapter()), - phiList(versAlloc->Adapter()), + phiList(nullptr), mePhiList(alloc->Adapter()), frequency(0), kind(kBBUnknown), @@ -147,12 +147,12 @@ class BB { succ.pop_back(); } - BB(MapleAllocator *alloc, MapleAllocator *versAlloc, BBId id, StmtNode *fstmt, StmtNode *lstmt) + BB(MapleAllocator *alloc, BBId id, StmtNode *fstmt, StmtNode *lstmt) : id(id), bbLabel(0), pred(2, nullptr, alloc->Adapter()), succ(2, nullptr, alloc->Adapter()), - phiList(versAlloc->Adapter()), + phiList(nullptr), mePhiList(alloc->Adapter()), stmtNodeList(fstmt, lstmt), frequency(0) { diff --git a/mapleall/maple_me/include/dse.h b/mapleall/maple_me/include/dse.h index 0cfc8dc4c362300b7b32edf24c0740c298e1fd3a..a962dc2906c0cb91755728e0dfa1e92231cad7bf 100644 --- a/mapleall/maple_me/include/dse.h +++ b/mapleall/maple_me/include/dse.h @@ -20,7 +20,7 @@ #include "dominance.h" namespace maple { -class DSE { +class DSE : public AnalysisResult { public: MIRModule *mirModule; StmtsSSAPart *stmtsSSAPart; @@ -30,7 +30,8 @@ class DSE { MapleUnorderedSet stmt_required; // key is stmtID; required if in set std::forward_list worklist; explicit DSE(MIRModule *mod, StmtsSSAPart *ssapart, Dominance *dom, MemPool *mp) - : mirModule(mod), + : AnalysisResult(mp), + mirModule(mod), stmtsSSAPart(ssapart), pdom(dom), dse_allocator(mp), diff --git a/mapleall/maple_me/include/hdse.h b/mapleall/maple_me/include/hdse.h index a4e8b8576ca2766ea201ba38ebf3178fa7aa0523..59e425f1545138c45c4f4d7e12871f9422488b52 100644 --- a/mapleall/maple_me/include/hdse.h +++ b/mapleall/maple_me/include/hdse.h @@ -64,6 +64,8 @@ class HDSE { void MarkStmtNeeded(MeStmt *); bool ExprNonDeletable(MeExpr *x); void DseProcessBB(BB *); + virtual bool IsLfo() { return false; } + virtual void ProcessWhileInfos() {} public: void DseProcess(); void Update(); diff --git a/mapleall/maple_me/include/irmap.h b/mapleall/maple_me/include/irmap.h index 36ddd774a16558288ac7524bf6f380d4cb7d8f66..0e517ab32f8f45c4a3901791a6740927e7f25bc3 100644 --- a/mapleall/maple_me/include/irmap.h +++ b/mapleall/maple_me/include/irmap.h @@ -45,7 +45,7 @@ class IRMap : public AnalysisResult { dominance(dom), irMapAlloc(mp), tempAlloc(tempmp), - exprID(0), + exprID(1), // starts from 1 mapHashLength(hashTableSize), hashTable(mapHashLength, nullptr, irMapAlloc.Adapter()), verst2MeExprTable(ssaTab->versionStTable.Size(), nullptr, irMapAlloc.Adapter()), @@ -141,6 +141,9 @@ class IRMap : public AnalysisResult { TyIdx tyidx = TyIdx()); MeExpr *CreateAddrofMeExprFromNewSymbol(MIRSymbol *, PUIdx); + MeExpr *SimplifyOpMeExpr(OpMeExpr *opmeexpr); + MeExpr *SimplifyMeExpr(MeExpr *opmeexpr); + template inline T *NewInPool(Arguments... args) { return irMapAlloc.GetMemPool()->New(&irMapAlloc, args...); diff --git a/mapleall/maple_me/include/lfo_function.h b/mapleall/maple_me/include/lfo_function.h new file mode 100644 index 0000000000000000000000000000000000000000..5a74f9ff37b19ee025a3f46e859ef7e176a5d185 --- /dev/null +++ b/mapleall/maple_me/include/lfo_function.h @@ -0,0 +1,70 @@ +/* + * 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. + */ + +#ifndef MAPLE_LFO_INCLUDE_LFO_FUNCTION_H +#define MAPLE_LFO_INCLUDE_LFO_FUNCTION_H +#include "lfo_mir_nodes.h" +#include "me_ir.h" + +namespace maple { + +class MeFunction; + +class LfoWhileInfo { + public: + MIRSymbol *injectedIVSym = nullptr; // the injected IV + OriginalSt *ivOst = nullptr; // the primary IV + MeExpr *initExpr = nullptr; + int32 stepValue = 0; + MeExpr *tripCount = nullptr; + bool canConvertDoloop = false; +}; + +class LfoIfInfo { + public: + LabelIdx endLabel = 0; // the label that is out of the if statement + LabelIdx elseLabel = 0; // the label that is the begin of else branch +}; + + +class LfoFunction { + public: + MemPool *lfomp; + MapleAllocator lfoAlloc; + MeFunction *meFunc; + MapleMap label2WhileInfo; // key is label at beginning of lowered while code sequence + MapleMap label2IfInfo; // key is target label of first conditional branch of lowered if code sequence + MapleSet lfoCreatedLabelSet; // for the labels that were created by lfo, we won't emit it + + public: + LfoFunction(MemPool *mp, MeFunction *func) : + lfomp(mp), + lfoAlloc(mp), + meFunc(func), + label2WhileInfo(lfoAlloc.Adapter()), + label2IfInfo(lfoAlloc.Adapter()), + lfoCreatedLabelSet(lfoAlloc.Adapter()) {} + + void SetLabelCreatedByLfo(LabelIdx lbidx) { + lfoCreatedLabelSet.insert(lbidx); + } + + bool LabelCreatedByLfo(LabelIdx lbidx) { + return lfoCreatedLabelSet.count(lbidx) != 0; + } +}; + +} // namespace maple +#endif // MAPLE_LFO_INCLUDE_LFO_FUNCTION_H diff --git a/mapleall/maple_me/include/lfo_inject_iv.h b/mapleall/maple_me/include/lfo_inject_iv.h new file mode 100644 index 0000000000000000000000000000000000000000..056260502749d127abe2593b31728edaf22c9294 --- /dev/null +++ b/mapleall/maple_me/include/lfo_inject_iv.h @@ -0,0 +1,32 @@ +/* + * 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. + */ + +#ifndef MAPLE_ME_INCLUDE_LFO_INJECT_IV_H +#define MAPLE_ME_INCLUDE_LFO_INJECT_IV_H +#include "me_phase.h" + +namespace maple { + +/*emit ir to specified file*/ +class DoLfoInjectIV : public MeFuncPhase { + public: + DoLfoInjectIV(MePhaseID id) : MeFuncPhase(id) {} + + AnalysisResult *Run(MeFunction *func, MeFuncResultMgr *m) override; + std::string PhaseName() const override { return "injectiv"; } +}; + +} // namespace maple +#endif // MAPLE_ME_INCLUDE_LFO_INJECT_IV_H diff --git a/mapleall/maple_me/include/lfo_iv_canon.h b/mapleall/maple_me/include/lfo_iv_canon.h new file mode 100644 index 0000000000000000000000000000000000000000..2c6f4d61a6e64538a88f7ee3fffa23e2a498d876 --- /dev/null +++ b/mapleall/maple_me/include/lfo_iv_canon.h @@ -0,0 +1,87 @@ +/* + * 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. + */ + +#ifndef MAPLE_ME_INCLUDE_LFO_IV_CANON_H +#define MAPLE_ME_INCLUDE_LFO_IV_CANON_H + +#include "lfo_function.h" +#include "me_ident_loops.h" +#include "me_irmap.h" +#include "me_phase.h" + +namespace maple { + +// describe characteristics of one IV +class IVDesc { + public: + OriginalSt *ost; + PrimType primType; + MeExpr *initExpr = nullptr; + int32 stepValue = 0; + + public: + explicit IVDesc(OriginalSt *o) : ost(o) { + MIRType *mirtype = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ost->tyIdx); + primType = mirtype->primType; + } +}; + +// this is for processing a single loop +class IVCanon { + public: + MemPool *mp; + MapleAllocator alloc; + MeFunction *func; + Dominance *dominance; + SSATab *ssatab; + LoopDesc *aloop; + uint32 loopID; + LfoWhileInfo *whileInfo; + MapleVector ivvec; + int32 idxPrimaryIV = -1; // the index in ivvec of the primary IV + MeExpr *tripCount = nullptr; + + public: + explicit IVCanon(MemPool *m, MeFunction *f, Dominance *dom, LoopDesc *ldesc, uint32 id, LfoWhileInfo *winfo) : + mp(m), alloc(m), func(f), dominance(dom), ssatab(f->meSSATab), + aloop(ldesc), loopID(id), whileInfo(winfo), ivvec(alloc.Adapter()) {} + bool ResolveExprValue(MeExpr *x, ScalarMeExpr *philhs); + int32 ComputeIncrAmt(MeExpr *x, ScalarMeExpr *philhs, int32 *appearances); + void CharacterizeIV(ScalarMeExpr *initversion, ScalarMeExpr *loopbackversion, ScalarMeExpr *philhs); + void FindPrimaryIV(); + bool IsLoopInvariant(MeExpr *x); + void CanonEntryValues(); + void ComputeTripCount(); + void CanonExitValues(); + void ReplaceSecondaryIVPhis(); + void PerformIVCanon(); + std::string PhaseName() const { return "ivcanon"; } +}; + +class DoLfoIVCanon : public MeFuncPhase { + public: + DoLfoIVCanon(MePhaseID id) : MeFuncPhase(id) {} + + ~DoLfoIVCanon() {} + + AnalysisResult *Run(MeFunction *func, MeFuncResultMgr *m) override; + + std::string PhaseName() const override { return "ivcanon"; } + + private: + void IVCanonLoop(LoopDesc *aloop, LfoWhileInfo *whileInfo); +}; +} // namespace maple +#endif // MAPLE_ME_INCLUDE_LFO_IV_CANON_H diff --git a/mapleall/maple_me/include/lfo_mir_lower.h b/mapleall/maple_me/include/lfo_mir_lower.h new file mode 100644 index 0000000000000000000000000000000000000000..005c29103da05afefea634e7c1909b705eb54489 --- /dev/null +++ b/mapleall/maple_me/include/lfo_mir_lower.h @@ -0,0 +1,33 @@ +/* + * 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. + */ + +#ifndef MAPLE_ME_INCLUDE_LFO_MIR_LOWER_H +#define MAPLE_ME_INCLUDE_LFO_MIR_LOWER_H +#include "mir_lower.h" +#include "me_function.h" +class LFOMIRLower : public MIRLower { + public: + MeFunction *func; + LfoFunction *lfoFunc; + + public: + LFOMIRLower(MIRModule &mod, MeFunction *f) : MIRLower(mod, f->mirFunc), + func(f), + lfoFunc(f->lfoFunc) {} + + BlockNode *LowerWhileStmt(WhileStmtNode *); + BlockNode *LowerIfStmt(IfStmtNode *ifstmt, bool recursive = true); +}; +#endif // MAPLE_ME_INCLUDE_LFO_MIR_LOWER_H diff --git a/mapleall/maple_me/include/lfo_mir_nodes.h b/mapleall/maple_me/include/lfo_mir_nodes.h new file mode 100644 index 0000000000000000000000000000000000000000..852e8d8ec5d17f04497c129a1e91f44c0206cd07 --- /dev/null +++ b/mapleall/maple_me/include/lfo_mir_nodes.h @@ -0,0 +1,335 @@ +/* + * 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. + */ + +#ifndef MAPLE_ME_INCLUDE_LFO_MIR_NODES_H_ +#define MAPLE_ME_INCLUDE_LFO_MIR_NODES_H_ +#include "me_ir.h" +#include "mir_nodes.h" + +namespace maple { + +class LfoParentPart { + public: + LfoParentPart *parent; + + public: + LfoParentPart (LfoParentPart *pt) : parent(pt) {} + virtual BaseNode *Cvt2BaseNode() = 0; + bool IsParentOf(LfoParentPart *canNode) { + LfoParentPart *dParent = canNode->parent; + while(dParent && dParent != this) + dParent = dParent->parent; + return dParent != NULL; + } +}; + +class LfoUnaryNode : public UnaryNode, public LfoParentPart{ + public: + LfoUnaryNode(Opcode o, PrimType ptyp, LfoParentPart *parent) : UnaryNode(o, ptyp), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoTypeCvtNode : public TypeCvtNode, public LfoParentPart { + public: + LfoTypeCvtNode(Opcode o, PrimType ptyp, LfoParentPart *parent) : + TypeCvtNode(o, ptyp), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoRetypeNode : public RetypeNode, public LfoParentPart { + public: + LfoRetypeNode(Opcode o, PrimType ptyp, LfoParentPart *parent) : + RetypeNode(ptyp), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoExtractbitsNode : public ExtractbitsNode, public LfoParentPart { + public: + LfoExtractbitsNode(Opcode o, PrimType ptyp, LfoParentPart *parent) : ExtractbitsNode(o, ptyp), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoIreadNode : public IreadNode, public LfoParentPart { + public: + IvarMeExpr *ivarx; + + public: + LfoIreadNode(Opcode o, PrimType ptyp, LfoParentPart *parent, IvarMeExpr *v) : + IreadNode(o, ptyp), LfoParentPart(parent), ivarx(v) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoIaddrofNode : public IreadNode, public LfoParentPart { + public: + LfoIaddrofNode(Opcode o, PrimType pty, LfoParentPart *parent) : IreadNode(o, pty), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoBinaryNode : public BinaryNode, public LfoParentPart { + public: + LfoBinaryNode (Opcode o, PrimType typ, LfoParentPart *parent) : BinaryNode (o,typ), + LfoParentPart (parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoCompareNode : public CompareNode, public LfoParentPart { + public: + LfoCompareNode (Opcode o, PrimType typ, PrimType otype, BaseNode *l, BaseNode *r, LfoParentPart *parent) : + CompareNode (o, typ, otype, l, r), LfoParentPart (parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoTernaryNode : public TernaryNode, public LfoParentPart { + public: + LfoTernaryNode (Opcode o, PrimType ptyp, LfoParentPart *parent) : TernaryNode(o, ptyp), + LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoNaryNode : public NaryNode, public LfoParentPart { + public: + LfoNaryNode (MapleAllocator *allc, Opcode o, PrimType pty, LfoParentPart *parent) : NaryNode (allc, o, pty), + LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoIntrinsicopNode : public IntrinsicopNode, public LfoParentPart { + public: + LfoIntrinsicopNode (MapleAllocator *allc, Opcode o, PrimType ptyp, TyIdx tidx, LfoParentPart *parent) : + IntrinsicopNode(allc, o, ptyp, tidx), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoConstvalNode : public ConstvalNode, public LfoParentPart { + public: + LfoConstvalNode(MIRConst *constv, LfoParentPart *parent) : ConstvalNode(constv->type->primType, constv), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoConststrNode : public ConststrNode, public LfoParentPart { + public: + LfoConststrNode(PrimType ptyp, UStrIdx i, LfoParentPart *parent) : ConststrNode(ptyp, i), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoConststr16Node : public Conststr16Node, public LfoParentPart { + public: + LfoConststr16Node(PrimType ptyp, U16StrIdx i, LfoParentPart *parent) : Conststr16Node(ptyp, i), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoSizeoftypeNode : public SizeoftypeNode, public LfoParentPart { + public: + LfoSizeoftypeNode(PrimType ptyp, TyIdx tidx, LfoParentPart *parent) : SizeoftypeNode(ptyp, tidx), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoArrayNode : public ArrayNode, public LfoParentPart { + public: + LfoArrayNode(MapleAllocator *allc, PrimType typ, TyIdx idx, LfoParentPart *parent) : ArrayNode (allc, typ, idx), LfoParentPart (parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoDreadNode : public AddrofNode, public LfoParentPart { + public: + VarMeExpr *varx; + + public: + LfoDreadNode(PrimType ptyp, StIdx sidx, FieldID fid, LfoParentPart *parent, VarMeExpr *v) : + AddrofNode(OP_dread, ptyp, sidx, fid), LfoParentPart(parent), varx(v) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoAddrofNode : public AddrofNode, public LfoParentPart { + public: + LfoAddrofNode(PrimType ptyp, StIdx sidx, FieldID fid, LfoParentPart *parent) : AddrofNode(OP_addrof, ptyp, sidx, fid), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoRegreadNode : public RegreadNode, public LfoParentPart { + public: + ScalarMeExpr *scalarx; + + public: + LfoRegreadNode(LfoParentPart *parent, ScalarMeExpr *s) : RegreadNode(), LfoParentPart(parent), scalarx(s) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoAddroffuncNode : public AddroffuncNode, public LfoParentPart { + public: + LfoAddroffuncNode(PrimType ptyp, PUIdx pidx, LfoParentPart *parent) : AddroffuncNode(ptyp, pidx), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoAddroflabelNode : public AddroflabelNode, public LfoParentPart { + public: + LfoAddroflabelNode(uint32 o, LfoParentPart *parent) : AddroflabelNode(o), LfoParentPart (parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoGCMallocNode : public GCMallocNode, public LfoParentPart { + public: + LfoGCMallocNode(Opcode o, PrimType pty, TyIdx tidx, LfoParentPart *parent) : GCMallocNode(o, pty, tidx), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoFieldsDistNode : public FieldsDistNode, public LfoParentPart { + public: + LfoFieldsDistNode(PrimType ptyp, TyIdx tidx, FieldID f1, FieldID f2, LfoParentPart *parent) : + FieldsDistNode(ptyp, tidx, f1, f2), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoIassignNode : public IassignNode, public LfoParentPart { + public: + IassignMeStmt *iasgn; + + public: + LfoIassignNode(LfoParentPart *parent, IassignMeStmt *ia) : IassignNode(), LfoParentPart(parent), iasgn(ia) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoGotoNode : public GotoNode, public LfoParentPart { + public: + LfoGotoNode (Opcode o, LfoParentPart *parent) : GotoNode(o), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoDassignNode : public DassignNode, public LfoParentPart { + public: + DassignMeStmt *dasgn; + + public: + LfoDassignNode(LfoParentPart *parent, DassignMeStmt *das) : DassignNode(), LfoParentPart(parent), dasgn(das) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoRegassignNode : public RegassignNode, public LfoParentPart { + public: + AssignMeStmt *asgn; + + public: + LfoRegassignNode(LfoParentPart *parent, AssignMeStmt *as) : RegassignNode(), LfoParentPart(parent), asgn(as) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoCondGotoNode : public CondGotoNode, public LfoParentPart { + public: + LfoCondGotoNode(Opcode o, LfoParentPart *parent) : CondGotoNode(o), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoWhileStmtNode : public WhileStmtNode, public LfoParentPart { + public: + LfoWhileStmtNode(LfoParentPart *parent) : WhileStmtNode(OP_while), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoDoloopNode : public DoloopNode, public LfoParentPart { + public: + LfoDoloopNode (LfoParentPart *parent) : DoloopNode (), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } + void InitLfoDoloopNode (StIdx stIdx, bool ispg, BaseNode *startExp, BaseNode *contExp, BaseNode *incrExp, BlockNode *blk) { + doVarStIdx = stIdx; + isPreg = ispg; + startExpr = startExp; + condExpr = contExp; + incrExpr = incrExp; + doBody = blk; + } +}; + +class LfoNaryStmtNode : public NaryStmtNode, public LfoParentPart { + public: + LfoNaryStmtNode (MapleAllocator *allc, Opcode o, LfoParentPart *parent) : + NaryStmtNode(allc, o), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoReturnStmtNode : public NaryStmtNode, public LfoParentPart { + public: + RetMeStmt *retmestmt; + + public: + LfoReturnStmtNode(MapleAllocator *allc, LfoParentPart *parent, RetMeStmt *ret) : + NaryStmtNode(allc, OP_return), LfoParentPart(parent), retmestmt(ret) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoCallNode : public CallNode, public LfoParentPart { + public: + CallMeStmt *callmestmt; + + public: + LfoCallNode(MapleAllocator *allc, Opcode o, LfoParentPart *parent, CallMeStmt *cl) : CallNode(allc, o), LfoParentPart(parent), callmestmt(cl) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoIcallNode : public IcallNode, public LfoParentPart { + public: + IcallMeStmt *icallmestmt; + + public: + LfoIcallNode (MapleAllocator *allc, Opcode o, TyIdx idx, LfoParentPart *parent, IcallMeStmt *ic) : + IcallNode (allc, o, idx), LfoParentPart(parent), icallmestmt(ic) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoIntrinsiccallNode : public IntrinsiccallNode, public LfoParentPart { + public: + IntrinsiccallMeStmt *intrinmestmt; + + public: + LfoIntrinsiccallNode (MapleAllocator *allc, Opcode o, MIRIntrinsicID id, LfoParentPart *parent, IntrinsiccallMeStmt *intncall) : + IntrinsiccallNode(allc, o, id), LfoParentPart(parent), intrinmestmt(intncall) {} + BaseNode *Cvt2BaseNode () { return this; } +}; + +class LfoIfStmtNode : public IfStmtNode, public LfoParentPart { + public: + LfoIfStmtNode(LfoParentPart *parent) : IfStmtNode(),LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoBlockNode : public BlockNode, public LfoParentPart { + public: + LfoBlockNode (LfoParentPart *parent) : BlockNode(),LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoStmtNode : public StmtNode, public LfoParentPart { + public: + LfoStmtNode (LfoParentPart *parent, Opcode o) : StmtNode (o), + LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +class LfoUnaryStmtNode : public UnaryStmtNode, public LfoParentPart { + public: + LfoUnaryStmtNode(Opcode o, LfoParentPart *parent) : UnaryStmtNode(o), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { + return this; + } +}; + +class LfoSwitchNode : public SwitchNode, public LfoParentPart { + public: + LfoSwitchNode(MapleAllocator *allc, LfoParentPart *parent) : + SwitchNode(allc), LfoParentPart(parent) {} + BaseNode *Cvt2BaseNode() { return this; } +}; + +} // namespace maple +#endif // MAPLE_LFO_INCLUDE_LFO_MIR_NODES_H_ diff --git a/mapleall/maple_me/include/lfo_pre_emit.h b/mapleall/maple_me/include/lfo_pre_emit.h new file mode 100644 index 0000000000000000000000000000000000000000..7e8dd0cfd4a2b67b0f5353ed1568caaddba1f73c --- /dev/null +++ b/mapleall/maple_me/include/lfo_pre_emit.h @@ -0,0 +1,62 @@ +/* + * 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. + */ + +#ifndef MAPLE_ME_INCLUDE_LFO_PRE_EMIT_H +#define MAPLE_ME_INCLUDE_LFO_PRE_EMIT_H +#include "me_irmap.h" +#include "me_phase.h" + +namespace maple { + +class LfoPreEmitter { + private: + MeIRMap *meirmap; + LfoFunction *lfoFunc; + MIRFunction *mirFunc; + MemPool *codeMP; + MapleAllocator *codeMPAlloc; + MirCFG *cfg; + + public: + LfoPreEmitter(MeIRMap *hmap, LfoFunction *f) : meirmap(hmap), + lfoFunc(f), + mirFunc(f->meFunc->mirFunc), + codeMP(f->meFunc->mirFunc->codeMemPool), + codeMPAlloc(&f->meFunc->mirFunc->codeMemPoolAllocator), + cfg(f->meFunc->theCFG) {} + + private: + LfoParentPart *EmitLfoExpr(MeExpr*, LfoParentPart *); + StmtNode* EmitLfoStmt(MeStmt *, LfoParentPart *); + void EmitBB(BB *, LfoBlockNode *); + DoloopNode *EmitLfoDoloop(BB *, LfoBlockNode *, LfoWhileInfo *); + WhileStmtNode *EmitLfoWhile(BB *, LfoBlockNode *); + uint32 Raise2LfoWhile(uint32, LfoBlockNode *); + uint32 Raise2LfoIf(uint32, LfoBlockNode *); + public: + uint32 EmitLfoBB(uint32, LfoBlockNode *); +}; + +/*emit ir to specified file*/ +class DoLfoPreEmission : public MeFuncPhase { + public: + DoLfoPreEmission(MePhaseID id) : MeFuncPhase(id) {} + + AnalysisResult *Run(MeFunction *func, MeFuncResultMgr *m) override; + std::string PhaseName() const override { return "lfopreemit"; } +}; + +} // namespace maple +#endif // MAPLE_ME_INCLUDE_LFO_PRE_EMIT_H diff --git a/mapleall/maple_me/include/me_alias_class.h b/mapleall/maple_me/include/me_alias_class.h index ed4027bafaea7a3bbac617599bd1c2cbd60cd235..275dfe1ebc5bb3dc5a24f0adbaaf6b675b733714 100644 --- a/mapleall/maple_me/include/me_alias_class.h +++ b/mapleall/maple_me/include/me_alias_class.h @@ -18,6 +18,7 @@ #include "alias_class.h" #include "me_phase.h" #include "me_function.h" +#include "me_cfg.h" namespace maple { @@ -33,10 +34,10 @@ class MeAliasClass : public AliasClass { MeFunction *func; BB *GetBB(BBId id) { - if (func->bbVec.size() < id.idx) { + if (func->theCFG->bbVec.size() < id.idx) { return nullptr; } - return func->bbVec[id.idx]; + return func->theCFG->bbVec[id.idx]; } bool InConstructorFunc() { @@ -49,10 +50,14 @@ class MeAliasClass : public AliasClass { }; class MeDoAliasClass : public MeFuncPhase { + ModuleResultMgr *moduleResultMgr; public: - explicit MeDoAliasClass(MePhaseID id) : MeFuncPhase(id) {} + explicit MeDoAliasClass(MePhaseID id) : MeFuncPhase(id), moduleResultMgr(nullptr) {} AnalysisResult *Run(MeFunction *ir, MeFuncResultMgr *m, ModuleResultMgr *mrm) override; + AnalysisResult *Run(MeFunction *ir, MeFuncResultMgr *m) override { + return Run(ir, m, moduleResultMgr); + } std::string PhaseName() const override { return "aliasclass"; } diff --git a/mapleall/maple_me/include/me_bb_layout.h b/mapleall/maple_me/include/me_bb_layout.h index 10275941ca29c64a4c6d15e1b1e57285e4658f82..965b6f1e7587d96d8d7419c4f4422cf42fd42846 100644 --- a/mapleall/maple_me/include/me_bb_layout.h +++ b/mapleall/maple_me/include/me_bb_layout.h @@ -16,6 +16,7 @@ #ifndef MAPLE_ME_INCLUDE_ME_BB_LAYOUT_H #define MAPLE_ME_INCLUDE_ME_BB_LAYOUT_H #include "me_function.h" +#include "me_cfg.h" #include "me_phase.h" namespace maple { @@ -23,6 +24,7 @@ namespace maple { class BBLayout : public AnalysisResult { private: MeFunction *func; + MirCFG *cfg; MapleAllocator layoutAlloc; MapleVector layoutBBs; // gives the determined layout order BBId curBBId; // to index into func->bbVec to return the next BB @@ -35,21 +37,22 @@ class BBLayout : public AnalysisResult { explicit BBLayout(MemPool *mp, MeFunction *f) : AnalysisResult(mp), func(f), + cfg(f->theCFG), layoutAlloc(mp), layoutBBs(layoutAlloc.Adapter()), curBBId(0), bbCreated(false), - laidOut(func->bbVec.size(), false, layoutAlloc.Adapter()), + laidOut(f->theCFG->bbVec.size(), false, layoutAlloc.Adapter()), tryOutstanding(false) { - laidOut[func->commonEntryBB->id.idx] = true; - laidOut[func->commonExitBB->id.idx] = true; + laidOut[func->theCFG->commonEntryBB->id.idx] = true; + laidOut[func->theCFG->commonExitBB->id.idx] = true; } BB *NextBB() { // return the next BB following strictly program input order curBBId.idx++; - while (curBBId.idx < func->bbVec.size()) { - BB *nextbb = func->bbVec[curBBId.idx]; + while (curBBId.idx < cfg->bbVec.size()) { + BB *nextbb = cfg->bbVec[curBBId.idx]; if (nextbb != nullptr && !laidOut[nextbb->id.idx]) { return nextbb; } diff --git a/mapleall/maple_me/include/me_cfg.h b/mapleall/maple_me/include/me_cfg.h index df6805c383648715fc55a431562eda3add9ab786..1182d1d225171e45cceca7535a87f88ee55c2a62 100644 --- a/mapleall/maple_me/include/me_cfg.h +++ b/mapleall/maple_me/include/me_cfg.h @@ -21,16 +21,44 @@ namespace maple { -class MirCFG { +class MirCFG : public AnalysisResult { public: MeFunction *func; - bool hasDoWhile; + MapleAllocator cfgAlloc; + BB *first_bb; + BB *last_bb; + BB *commonEntryBB; + BB *commonExitBB; + uint32 nextBBId; + MapleVector bbVec; + MapleUnorderedMap labelBBIdMap; + MapleUnorderedMap bbTryNodeMap; // maps isTry bb to its try stmt + MapleUnorderedMap endTryBB2TryBB; // maps endtry bb to its try bb MapleSet pattern_set_; + bool hasDoWhile; - explicit MirCFG(MeFunction *f) : func(f), hasDoWhile(false), pattern_set_(f->alloc.Adapter()) {} + explicit MirCFG(MeFunction *f, MemPool *mp) : AnalysisResult(mp), + func(f), + cfgAlloc(mp), + first_bb(nullptr), + last_bb(nullptr), + commonEntryBB(nullptr), + commonExitBB(nullptr), + nextBBId(0), + bbVec(cfgAlloc.Adapter()), + labelBBIdMap(cfgAlloc.Adapter()), + bbTryNodeMap(cfgAlloc.Adapter()), + endTryBB2TryBB(cfgAlloc.Adapter()), + pattern_set_(cfgAlloc.Adapter()), + hasDoWhile(false) {} ~MirCFG() {} + uint32 NumBBs(void) const { return nextBBId; } + + BB *NextBB(const BB *bb); + BB *PrevBB(const BB *bb); + void DeleteBasicBlock(const BB *bb); bool IfReplaceWithAssertnonnull(BB *bb); void BuildMirCFG(); void ReplaceWithAssertnonnull(); @@ -43,5 +71,17 @@ class MirCFG { void DumpToFile(const char *prefix, bool dumpinstrs = false); void AddAuxilaryBB(); }; + +class MeDoCfgBuild : public MeFuncPhase { + public: + explicit MeDoCfgBuild(MePhaseID id) : MeFuncPhase(id) {} + + ~MeDoCfgBuild() {} + + AnalysisResult *Run(MeFunction *func, MeFuncResultMgr *m) override; + std::string PhaseName() const override { + return "cfgbuild"; + } +}; } // namespace maple #endif // MAPLE_ME_INCLUDE_ME_CFG_H diff --git a/mapleall/maple_me/include/me_delegate_rc.h b/mapleall/maple_me/include/me_delegate_rc.h index bf88768fdc3894cd45ef9b21ed64ba354865ed52..552315a6cabfa03cdc000b2aa42ca6d2a2ed5481 100644 --- a/mapleall/maple_me/include/me_delegate_rc.h +++ b/mapleall/maple_me/include/me_delegate_rc.h @@ -20,7 +20,7 @@ #include "me_irmap.h" namespace maple { -class DelegateRC : public AnalysisResult { +class DelegateRC { private: MeFunction *func; IRMap *irMap; @@ -35,9 +35,8 @@ class DelegateRC : public AnalysisResult { MapleVector verst_derefedcopied; // true if it is dereferenced or copied MapleVector verst_cantdecrefearly; // true if it is unsafe to insert early decref in form B1 delegation - DelegateRC(MeFunction *f, Dominance *dom, MemPool *mp, MemPool *tempmp) - : AnalysisResult(mp), - func(f), + DelegateRC(MeFunction *f, Dominance *dom, MemPool *tempmp) + : func(f), irMap(func->irMap), ssaTab(f->meSSATab), dominance(dom), diff --git a/mapleall/maple_me/include/me_dominance.h b/mapleall/maple_me/include/me_dominance.h index 53256c077b05389b28674d65f9c8be14f26bd88c..c48f565871318efc01ce0b34a1c3dcc304ee159c 100644 --- a/mapleall/maple_me/include/me_dominance.h +++ b/mapleall/maple_me/include/me_dominance.h @@ -17,6 +17,7 @@ #define MAPLE_ME_INCLUDE_ME_DOMINANCE_H #include "dominance.h" #include "me_function.h" +#include "me_cfg.h" #include "me_phase.h" namespace maple { diff --git a/mapleall/maple_me/include/me_dse.h b/mapleall/maple_me/include/me_dse.h index fa33bd86a8e93aedad2aee55697b912e396eab91..7d5af93ad4c6a468e4efc1ec87f4c8885e8e2ece 100644 --- a/mapleall/maple_me/include/me_dse.h +++ b/mapleall/maple_me/include/me_dse.h @@ -22,14 +22,15 @@ #include "me_option.h" #include "dominance.h" #include "me_function.h" +#include "me_cfg.h" #include "dse.h" namespace maple { -class MeDSE : private DSE { +class MeDSE : public DSE { public: explicit MeDSE(MeFunction *f, Dominance *dom, MemPool *mp) - : DSE(&f->mirModule, &f->meSSATab->stmtsSSAPart, dom, mp), func(f), cfg_updated(false) {} + : DSE(&f->mirModule, &f->meSSATab->stmtsSSAPart, dom, mp), func(f), cfg(f->theCFG), cfg_updated(false) {} void DseInit(); void DseProcess(); @@ -47,10 +48,11 @@ class MeDSE : private DSE { private: MeFunction *func; + MirCFG *cfg; bool cfg_updated; BB *GetBB(BBId id) { - return func->bbVec.at(id.idx); + return cfg->bbVec[id.idx]; } }; diff --git a/mapleall/maple_me/include/me_function.h b/mapleall/maple_me/include/me_function.h index 8c7ee3c698f0527585cb888ddf6bb5837a7ca160..7297686abbf30c1377b59dfca4e893eb9085a628 100644 --- a/mapleall/maple_me/include/me_function.h +++ b/mapleall/maple_me/include/me_function.h @@ -27,6 +27,7 @@ #include "ssa_tab.h" #include "func_emit.h" #include "me_ir.h" +#include "lfo_function.h" namespace maple { @@ -42,77 +43,59 @@ extern SSATab *g_ssatab; class MeFunction : public FuncEmit { public: - MemPool *memPool; - MapleAllocator alloc; - MemPool *versMemPool; - MapleAllocator versAlloc; MIRModule &mirModule; MIRFunction *mirFunc; - BB *first_bb_; - BB *last_bb_; - BB *commonEntryBB; - BB *commonExitBB; - uint32 nextBBId; - /* mempool */ - MapleUnorderedMap labelBBIdMap; - MapleVector bbVec; MirCFG *theCFG; SSATab *meSSATab; MeIRMap *irMap; - MapleUnorderedMap bbTryNodeMap; // maps isTry bb to its try stmt - MapleUnorderedMap endTryBB2TryBB; // maps endtry bb to its try bb - /* input */ std::string fileName; + LfoFunction *lfoFunc; uint32 regNum; // count virtual registers bool hasEH; /* current has try statement */ bool secondPass; // second pass for the same function - bool isLno; + bool isLfo; bool placementRCOn; // whethering doing placement RC - explicit MeFunction(MIRModule *mod, MIRFunction *func, MemPool *mp, MemPool *versmp, const std::string &fileName, - bool issecondpass = false, bool islno = false) - : memPool(mp), - alloc(mp), - versMemPool(versmp), - versAlloc(versmp), - mirModule(*mod), + explicit MeFunction(MIRModule *mod, MIRFunction *func, const std::string &fileName, + bool issecondpass, bool islfo) + : mirModule(*mod), mirFunc(func), - first_bb_(nullptr), - last_bb_(nullptr), - commonEntryBB(nullptr), - commonExitBB(nullptr), - nextBBId(0), - labelBBIdMap(alloc.Adapter()), - bbVec(alloc.Adapter()), + theCFG(nullptr), meSSATab(nullptr), - bbTryNodeMap(alloc.Adapter()), - endTryBB2TryBB(alloc.Adapter()), - fileName(fileName) { - PartialInit(issecondpass); - isLno = islno; + irMap(nullptr), + fileName(fileName), + lfoFunc(nullptr), + regNum(0), + hasEH(false), + secondPass(issecondpass), + isLfo(islfo), + placementRCOn(false) { + if (mod->IsJavaModule() && (mirFunc->info.size() > 0)) { + // set regNum + std::string string("INFO_registers"); + GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(string); + regNum = mirModule.CurFunction()->GetInfo(strIdx); + // set hasEH + std::string trynum("INFO_tries_size"); + strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(trynum); + uint32 num = mirModule.CurFunction()->GetInfo(strIdx); + hasEH = (num != 0); + } } virtual ~MeFunction() {} - uint32 NumBBs(void) const { - return nextBBId; - } - void DumpFunction(); void DumpFunctionNoSSA(); void DumpMeFunc(); void DumpMayDUFunction(); - virtual void Prepare(unsigned long rangeNum); void Verify(); const std::string &GetName() const { return mirModule.CurFunction()->GetName(); } BB *NewBasicBlock(); - void DeleteBasicBlock(const BB *bb); - BB *NextBB(const BB *bb); - BB *PrevBB(const BB *bb); /* create label for bb */ void CreateBBLabel(BB *bb); @@ -132,11 +115,11 @@ class MeFunction : public FuncEmit { return secondPass; } + void CreateBasicBlocks(MirCFG *cfg); + void RemoveEhEdgesInSyncRegion(); + private: - void PartialInit(bool issecondpass); - void CreateBasicBlocks(); void SetTryBlockInfo(StmtNode *javatryStmt, BB *lastjavatryBb, const StmtNode *nextstmt, BB *curbb, BB *newbb); - void RemoveEhEdgesInSyncRegion(); }; } // namespace maple #endif // MAPLE_ME_INCLUDE_ME_FUNCTION_H diff --git a/mapleall/maple_me/include/me_hdse.h b/mapleall/maple_me/include/me_hdse.h index c280ca69855d6af96b783d4f28e30c221f35f88f..5a9882c474a3f1789fcbd2b2bffd24afc9cbf4ab 100644 --- a/mapleall/maple_me/include/me_hdse.h +++ b/mapleall/maple_me/include/me_hdse.h @@ -29,7 +29,7 @@ namespace maple { class MeHDSE : public HDSE { public: explicit MeHDSE(MeFunction *f, Dominance *pdom, IRMap *map) - : HDSE(&f->mirModule, f->meSSATab, pdom, map, mempoolctrler.NewMemPool(PhaseName().c_str()), f->bbVec), + : HDSE(&f->mirModule, f->meSSATab, pdom, map, mempoolctrler.NewMemPool(PhaseName().c_str()), f->theCFG->bbVec), func(f), verstUseCounts(dse_allocator.Adapter()), backSubsCands(dse_allocator.Adapter()) {} @@ -50,6 +50,8 @@ class MeHDSE : public HDSE { std::string PhaseName() const { return "hdse"; } + bool IsLfo() { return func->isLfo; } + void ProcessWhileInfos(); MeFunction *func; MapleVector verstUseCounts; // index is vstIdx diff --git a/mapleall/maple_me/include/me_hti.h b/mapleall/maple_me/include/me_hti.h index 2a2e17ef79343b187e69cdaabb87cfdc49d97d01..3e7eb63a44137447f59ca29026d6f7b0333f031f 100644 --- a/mapleall/maple_me/include/me_hti.h +++ b/mapleall/maple_me/include/me_hti.h @@ -53,7 +53,7 @@ class MeTI { orig_type(vst_size, kPtyInvalid, ti_allocator.Adapter()), inferred_type(vst_size, kPtyInvalid, ti_allocator.Adapter()), new_symbol(vst_size, nullptr, ti_allocator.Adapter()), - bb_rebuilt(func->bbVec.size(), false, ti_allocator.Adapter()), + bb_rebuilt(func->theCFG->bbVec.size(), false, ti_allocator.Adapter()), worklist(std::less(), ti_allocator.Adapter()) {} void BuildUseFromExpr(MeExpr *expr, MeStmt *mestmt); diff --git a/mapleall/maple_me/include/me_ident_loops.h b/mapleall/maple_me/include/me_ident_loops.h index b637d6bdb0b4578a12a762be6af167fa9dd93c2c..5895c950cf038f5c524ab1e22890d3310903e843 100644 --- a/mapleall/maple_me/include/me_ident_loops.h +++ b/mapleall/maple_me/include/me_ident_loops.h @@ -16,6 +16,7 @@ #ifndef MAPLE_ME_INCLUDE_ME_IDENT_LOOP_H #define MAPLE_ME_INCLUDE_ME_IDENT_LOOP_H #include "me_function.h" +#include "me_cfg.h" #include "bb.h" #include "me_phase.h" #include "dominance.h" @@ -29,12 +30,15 @@ class LoopDesc { public: BB *head; BB *tail; + LoopDesc *parent = nullptr; // points to its closest nesting loop + BB *entry = nullptr; MapleSet loop_bbs; - LoopDesc *parent; // points to its closest nesting loop - uint32 nestdepth; // the nesting depth + BB *exitBB = nullptr; + BB *startbodyBB = nullptr; + uint32 nestdepth = 0; // the nesting depth LoopDesc(MapleAllocator *alloc, BB *headbb, BB *tailbb) - : head(headbb), tail(tailbb), loop_bbs(alloc->Adapter()), parent(nullptr), nestdepth(0) {} + : head(headbb), tail(tailbb), loop_bbs(alloc->Adapter()) {} bool Has(const BB *bb) { return loop_bbs.find(bb->id) != loop_bbs.end(); @@ -44,8 +48,7 @@ class LoopDesc { // IdentifyLoop records all the loops in a MeFunction. class IdentifyLoops : public AnalysisResult { public: - MemPool *meloop_mp; - MapleAllocator meloop_alloc; + MapleAllocator alloc; MeFunction *func; Dominance *dominance; MapleVector meloops; @@ -53,22 +56,22 @@ class IdentifyLoops : public AnalysisResult { explicit IdentifyLoops(MemPool *mp, MeFunction *mf, Dominance *dm) : AnalysisResult(mp), - meloop_mp(mp), - meloop_alloc(mp), + alloc(mp), func(mf), dominance(dm), - meloops(meloop_alloc.Adapter()), - bbloopparent(func->bbVec.size(), nullptr, meloop_alloc.Adapter()) {} + meloops(alloc.Adapter()), + bbloopparent(func->theCFG->bbVec.size(), nullptr, alloc.Adapter()) {} - LoopDesc *CreateLoopDesc(BB *hd, BB *tail); void SetLoopParent4BB(const BB *bb, LoopDesc *aloop); + void SetLoopEntry(LoopDesc *aloop); + void SetExitBB(LoopDesc *aloop); void ProcessBB(BB *bb); void Dump(); }; -class MeDoMeLoop : public MeFuncPhase { +class MeDoIdentLoops : public MeFuncPhase { public: - explicit MeDoMeLoop(MePhaseID id) : MeFuncPhase(id) {} + explicit MeDoIdentLoops(MePhaseID id) : MeFuncPhase(id) {} AnalysisResult *Run(MeFunction *func, MeFuncResultMgr *m) override; std::string PhaseName() const override { diff --git a/mapleall/maple_me/include/me_ir.h b/mapleall/maple_me/include/me_ir.h index 1e717ed68b54c4330117f01582a86562edc9d79d..e66652f5485cd308d370058246982583904c76c2 100644 --- a/mapleall/maple_me/include/me_ir.h +++ b/mapleall/maple_me/include/me_ir.h @@ -25,7 +25,6 @@ class MeStmt; class IRMap; class SSATab; class VarMeExpr; -class RegMeExpr; class OriginalSt; class Dominance; class AssignMeStmt; @@ -149,7 +148,7 @@ typedef enum { class MePhiNode; -// base class for VarMeExpr and RegMeExpr +// base class for VarMeExpr class ScalarMeExpr : public MeExpr { public: OriginalSt *ost; @@ -185,9 +184,18 @@ class ScalarMeExpr : public MeExpr { bool IsDefByPhi() const { return defBy == kDefByPhi; } + PregIdx GetPregIdx() const { + CHECK_FATAL(ost->IsPregSymbol(), "GetPregIdx: not a preg"); + return ost->symOrPreg.pregIdx; + } BB *DefByBB(); + BaseNode *EmitExpr(SSATab *ssaTab); + ScalarMeExpr *FindDefByStmt(std::set *visited); + void Dump(IRMap *, int32 indent = 0); }; +using RegMeExpr = ScalarMeExpr; + // represant dread class VarMeExpr : public ScalarMeExpr { public: @@ -216,20 +224,6 @@ class VarMeExpr : public ScalarMeExpr { VarMeExpr *ResolveVarMeValue(); }; -class RegMeExpr : public ScalarMeExpr { - public: - PregIdx16 regIdx; - - RegMeExpr(int32 exprid, OriginalSt *ost, uint32 vidx, PrimType ptyp) - : ScalarMeExpr(exprid, ost, vidx, kMeOpReg, OP_regread, ptyp), - regIdx(ost->GetPregIdx()) {} - ~RegMeExpr() {} - - void Dump(IRMap *, int32 indent = 0); - BaseNode *EmitExpr(SSATab *); - RegMeExpr *FindDefByStmt(std::set *visited); -}; - class MePhiNode { public: ScalarMeExpr *lhs = nullptr; @@ -421,9 +415,8 @@ class FieldsDistMeExpr : public MeExpr { class AddrofMeExpr : public MeExpr { public: OStIdx ostIdx; // the index in MEOptimizer: OriginalStTable; - FieldID fieldID; - AddrofMeExpr(int32 exprid, PrimType t, OStIdx idx) : MeExpr(exprid, kMeOpAddrof, OP_addrof, t, 0), ostIdx(idx), fieldID(0) {} + AddrofMeExpr(int32 exprid, PrimType t, OStIdx idx) : MeExpr(exprid, kMeOpAddrof, OP_addrof, t, 0), ostIdx(idx) {} ~AddrofMeExpr() {} void Dump(IRMap *, int32 indent = 0); @@ -432,7 +425,7 @@ class AddrofMeExpr : public MeExpr { return false; } const AddrofMeExpr *x = static_cast(meexpr); - if (ostIdx != x->ostIdx || fieldID != x->fieldID) { + if (ostIdx != x->ostIdx) { return false; } return true; @@ -879,16 +872,9 @@ class MustDefMeNode { bool isLive; MustDefMeNode(ScalarMeExpr *x, MeStmt *mestmt) : lhs(x), base(mestmt), isLive(true) { - if (x->meOp == kMeOpReg) { - RegMeExpr *reg = static_cast(x); - reg->defBy = kDefByMustdef; - reg->def.defMustDef = this; - } else { - CHECK_FATAL(x->meOp == kMeOpVar, "unexpected opcode"); - VarMeExpr * var = static_cast(x); - var->defBy = kDefByMustdef; - var->def.defMustDef = this; - } + ScalarMeExpr *reg = static_cast(x); + reg->defBy = kDefByMustdef; + reg->def.defMustDef = this; } MustDefMeNode(const MustDefMeNode& mustDef) { lhs = mustDef.lhs; diff --git a/mapleall/maple_me/include/me_irmap.h b/mapleall/maple_me/include/me_irmap.h index 2744d4e5477d46874001224bcd78333d58608b37..90fc3499105aa582c3c007998a47b37f061af94f 100644 --- a/mapleall/maple_me/include/me_irmap.h +++ b/mapleall/maple_me/include/me_irmap.h @@ -17,6 +17,7 @@ #define MAPLE_ME_INCLUDE_ME_IRMAP_H #include "ssa_tab.h" #include "me_function.h" +#include "me_cfg.h" #include "irmap.h" const int kHmapHashLength = 24593; // from planetmath.org/goodhashtableprimes @@ -35,11 +36,11 @@ class MeIRMap : public IRMap { // following are virtual functions BB *GetBB(BBId id) { - return mirFunc->bbVec.at(id.idx); + return mirFunc->theCFG->bbVec.at(id.idx); } BB *GetBBForLabidx(LabelIdx lidx, PUIdx pidx = 0) { - return mirFunc->labelBBIdMap[lidx]; + return mirFunc->theCFG->labelBBIdMap[lidx]; } void Dump(); diff --git a/mapleall/maple_me/include/me_phase.h b/mapleall/maple_me/include/me_phase.h index 2f0bffb5e58ca40666ebdf960b42f87eba51e6fc..8dd0f2421079b1c172bb0a08449d60536850da60 100644 --- a/mapleall/maple_me/include/me_phase.h +++ b/mapleall/maple_me/include/me_phase.h @@ -42,7 +42,6 @@ class MeFuncPhase : public Phase { public: MeFuncPhase(MePhaseID id) : Phase() { phaseID = id; - isCFGChanged = false; } /* if phase is analysis phase, return analysis result @@ -73,22 +72,10 @@ class MeFuncPhase : public Phase { virtual std::string PhaseName() const = 0; virtual ~MeFuncPhase(){}; - void SetChangeCFG() { - isCFGChanged = true; - } - - bool IsChangedCFG() const { - return isCFGChanged; - } - - void ClearChangeCFG() { - isCFGChanged = false; - } private: MePhaseID phaseID; std::string prevPhaseName; /* used in filename for emit */ - bool isCFGChanged; // is this phase changed CFG }; } // namespace maple #endif // MAPLE_ME_IMCLUDE_ME_PHASE_H diff --git a/mapleall/maple_me/include/me_phase_manager.h b/mapleall/maple_me/include/me_phase_manager.h index cdb8c22516f7eedd3a4c2cf811f24e0c18b57002..708940f259b7f3a547a4192b450fd8e1cff3c4e6 100644 --- a/mapleall/maple_me/include/me_phase_manager.h +++ b/mapleall/maple_me/include/me_phase_manager.h @@ -24,7 +24,6 @@ #include "me_phase.h" namespace maple { -typedef enum { kMePhaseInvalid, kMePhaseMainopt, kMePhaseLno } MePhaseType; /* driver of Me */ class MeFuncPhaseManager : public PhaseManager { @@ -33,7 +32,6 @@ class MeFuncPhaseManager : public PhaseManager { MeFuncResultMgr arFuncManager; MIRModule &module; ModuleResultMgr *modResMgr; - MePhaseType mePhaseType; bool genMeMpl; bool timePhases; @@ -42,7 +40,6 @@ class MeFuncPhaseManager : public PhaseManager { arFuncManager(GetMemAllocator()), module(*mod), modResMgr(mrm), - mePhaseType(kMePhaseInvalid), genMeMpl(false), timePhases(false) {} @@ -55,10 +52,6 @@ class MeFuncPhaseManager : public PhaseManager { void AddPhases(const std::unordered_set &skipPhases); void AddPhasesNoDefault(const std::vector &phases); - void SetMePhase(MePhaseType mephase) { - mePhaseType = mephase; - } - void SetModResMgr(ModuleResultMgr *mrm) { modResMgr = mrm; } @@ -75,9 +68,6 @@ class MeFuncPhaseManager : public PhaseManager { } bool FuncFilter(const std::string &, const std::string &); - - private: - void RunMainOpt(MIRFunction *, uint64, const std::string &); }; } // namespace maple #endif // MAPLE_ME_INCLUDE_ME_PHASE_MANAGER_H diff --git a/mapleall/maple_me/include/me_phases.def b/mapleall/maple_me/include/me_phases.def index 66071268a1cf4cd635e426ebb212c9e64d9fd4a1..9298a0e10f8d09f55d1857b6fbbb9c315414122d 100644 --- a/mapleall/maple_me/include/me_phases.def +++ b/mapleall/maple_me/include/me_phases.def @@ -18,17 +18,18 @@ FUNCAPHASE(MeFuncPhase_SSATAB, MeDoSSATab) FUNCAPHASE(MeFuncPhase_ALIASCLASS, MeDoAliasClass) FUNCAPHASE(MeFuncPhase_IRMAPBUILD, MeDoIrMapBuild) FUNCAPHASE(MeFuncPhase_PREDICT, MeDoPredict) -FUNCAPHASE(MeFuncPhase_MELOOP, MeDoMeLoop) +FUNCAPHASE(MeFuncPhase_IDENTLOOPS, MeDoIdentLoops) FUNCAPHASE(MeFuncPhase_MEBDCOPT, MeDoBDCOpt) FUNCAPHASE(MeFuncPhase_BBLAYOUT, MeDoBBLayout) -FUNCAPHASE(MeFuncPhase_DELEGATERC, MeDoDelegateRC) +FUNCTPHASE(MeFuncPhase_DELEGATERC, MeDoDelegateRC) FUNCAPHASE(MeFuncPhase_CONDBASEDNPC, MeDoCondBasedNPC) +FUNCAPHASE(MeFuncPhase_CFGBUILD, MeDoCfgBuild) FUNCTPHASE(MeFuncPhase_CONDBASEDRC, MeDoCondBasedRC) FUNCTPHASE(MeFuncPhase_MAY2DASSIGN, MeDoMay2Dassign) -FUNCTPHASE(MeFuncPhase_SSA, MeDoSSA) +FUNCAPHASE(MeFuncPhase_SSA, MeDoSSA) FUNCTPHASE(MeFuncPhase_LOOPCANON, MeDoLoopCanon) FUNCTPHASE(MeFuncPhase_SPLITCEDGE, MeDoSplitCEdge) -FUNCTPHASE(MeFuncPhase_DSE, MeDoDSE) +FUNCAPHASE(MeFuncPhase_DSE, MeDoDSE) FUNCTPHASE(MeFuncPhase_TI, MeDohTI) FUNCTPHASE(MeFuncPhase_HPROP, MeDoMeProp) FUNCTPHASE(MeFuncPhase_HDSE, MeDohDSE) @@ -50,3 +51,6 @@ FUNCTPHASE(MeFuncPhase_ANALYZERC, MeDoAnalyzeRC) FUNCTPHASE(MeFuncPhase_RCLOWERING, MeDoRCLowering) FUNCTPHASE(MeFuncPhase_FSAA, MeDoFSAA) FUNCTPHASE(MeFuncPhase_SYMRENAME, MeDoSymRename) +FUNCTPHASE(MeFuncPhase_LFOPREEMIT, DoLfoPreEmission) +FUNCTPHASE(MeFuncPhase_LFOINJECTIV, DoLfoInjectIV) +FUNCTPHASE(MeFuncPhase_LFOIVCANON, DoLfoIVCanon) diff --git a/mapleall/maple_me/include/me_placement_opt.h b/mapleall/maple_me/include/me_placement_opt.h index bc20b9646c3b5baacd92c9a7c3f939e4fe08f9a7..f31a2b1c57306fe218f109990f1b2f3cfcf23685 100644 --- a/mapleall/maple_me/include/me_placement_opt.h +++ b/mapleall/maple_me/include/me_placement_opt.h @@ -105,7 +105,7 @@ class PlacementOpt { classcount(0), inserted_bbs(std::less(), percand_allocator.Adapter()), lastuse_bbs(std::less(), percand_allocator.Adapter()) { - for (BB *entrybb : func->commonEntryBB->succ) { + for (BB *entrybb : func->theCFG->commonEntryBB->succ) { entry_dfns.insert(dominance->pdtDfn[entrybb->id.idx]); } } diff --git a/mapleall/maple_me/include/me_predict.h b/mapleall/maple_me/include/me_predict.h index 301d7f966140b70b86298501f5d8e111a91742ed..c7c1e8bd13fbb907957874367cc533bacaf5bb1d 100644 --- a/mapleall/maple_me/include/me_predict.h +++ b/mapleall/maple_me/include/me_predict.h @@ -68,6 +68,7 @@ class MePrediction : public AnalysisResult { mePredAlloc(mp), tmpAlloc(tmppool), func(mf), + cfg(mf->theCFG), dom(dm), meLoop(loops), hmap(map), @@ -101,6 +102,7 @@ class MePrediction : public AnalysisResult { MapleAllocator mePredAlloc; MapleAllocator tmpAlloc; MeFunction *func; + MirCFG *cfg; Dominance *dom; IdentifyLoops *meLoop; MeIRMap *hmap; diff --git a/mapleall/maple_me/include/me_prop.h b/mapleall/maple_me/include/me_prop.h index 6c6291551d5b9ab6c9ce30eebd3bc187a3b3eee4..fdc1a69e04539c03aaa3c04e0864c310bd6aa7a7 100644 --- a/mapleall/maple_me/include/me_prop.h +++ b/mapleall/maple_me/include/me_prop.h @@ -26,7 +26,7 @@ class MeProp : public Prop { public: MeProp(MeIRMap *hmap, Dominance *dom, MemPool *mp, bool propbase, bool propiloadref, bool propglobalref, bool propfinaliloadref, bool propiloadrefNonparm, bool nopropatphi) - : Prop(hmap, dom, mp, hmap->mirFunc->bbVec.size(), propbase, propiloadref, propglobalref, propfinaliloadref, + : Prop(hmap, dom, mp, hmap->mirFunc->theCFG->bbVec.size(), propbase, propiloadref, propglobalref, propfinaliloadref, propiloadrefNonparm, nopropatphi), func(hmap->mirFunc) {} @@ -34,7 +34,7 @@ class MeProp : public Prop { MeFunction *func; BB *GetBB(BBId id) { - return func->bbVec.at(id.idx); + return func->theCFG->bbVec.at(id.idx); } bool InConstructorFunc() { diff --git a/mapleall/maple_me/include/me_ssa.h b/mapleall/maple_me/include/me_ssa.h index d57869a6da0ccfb082510dda80ae62ccf5b4348e..b3590e7629461a67fea265fcb10e80a0c4bc2925 100644 --- a/mapleall/maple_me/include/me_ssa.h +++ b/mapleall/maple_me/include/me_ssa.h @@ -16,28 +16,30 @@ #ifndef MAPLE_ME_INCLUDE_ME_SSA_H #define MAPLE_ME_INCLUDE_ME_SSA_H #include "me_function.h" +#include "me_cfg.h" +#include "me_ident_loops.h" #include "ssa.h" namespace maple { class Dominance; -class MeSSA : public maple::SSA, public AnalysisResult { +class MeSSA : public maple::SSA { public: - MeFunction *mirFunc; + MeFunction *func; private: bool VerifySSAOpnd(BaseNode *node); public: - explicit MeSSA(MeFunction *func, SSATab *stab, Dominance *dom, MemPool *mp) : - SSA(mp, stab, dom, func->bbVec), AnalysisResult(mp), mirFunc(func) {} + explicit MeSSA(MeFunction *f, SSATab *stab, Dominance *dom, MemPool *mp) : + SSA(mp, stab, dom, f->theCFG->bbVec), func(f) {} ~MeSSA() {} - void BuildSSA(); void InsertPhiNode(); bool VerifySSA(); + void InsertIdentifyAssignments(IdentifyLoops *identloops); std::string PhaseName() const { return "ssa"; } diff --git a/mapleall/maple_me/include/me_ssa_devirtual.h b/mapleall/maple_me/include/me_ssa_devirtual.h index ce943efc55191ca213059fe92c86b6dac70d7b04..d5874874514034cad955f407f19408d111cec7ff 100644 --- a/mapleall/maple_me/include/me_ssa_devirtual.h +++ b/mapleall/maple_me/include/me_ssa_devirtual.h @@ -23,13 +23,13 @@ class MeSSADevirtual : public SSADevirtual { public: MeSSADevirtual(MemPool *mp, MIRModule *mod, MeFunction *f, IRMap *irMap, KlassHierarchy *kh, Dominance *dom, Clone *clone) - : SSADevirtual(mp, mod, irMap, kh, dom, f->bbVec.size(), clone), func(f) {} + : SSADevirtual(mp, mod, irMap, kh, dom, f->theCFG->bbVec.size(), clone), func(f) {} ~MeSSADevirtual() {} protected: BB *GetBB(BBId id) override { - return func->bbVec[id.idx]; + return func->theCFG->bbVec[id.idx]; } MIRFunction *GetMIRFunction() override { diff --git a/mapleall/maple_me/include/me_ssa_epre.h b/mapleall/maple_me/include/me_ssa_epre.h index d3451a322caabf445617c302a6d1180816123e10..e061a6259b529ece9edf773790b6bb21a0307d06 100644 --- a/mapleall/maple_me/include/me_ssa_epre.h +++ b/mapleall/maple_me/include/me_ssa_epre.h @@ -47,8 +47,8 @@ class MeSSAEPre : public SSAEPre { private: void BuildWorkList(); BB *GetBB(BBId id) { - CHECK(id.idx < func->bbVec.size(), "index out of range in MeSSAEPre::GetBB"); - return func->bbVec[id.idx]; + CHECK(id.idx < func->theCFG->bbVec.size(), "index out of range in MeSSAEPre::GetBB"); + return func->theCFG->bbVec[id.idx]; } PUIdx GetPuidx(MeStmt *stmt) { diff --git a/mapleall/maple_me/include/me_ssa_lpre.h b/mapleall/maple_me/include/me_ssa_lpre.h index 7c81d74d00316b42c2818a967531aad8e817cdfc..2fc3bdca26f53e493750595badfb56622391ae2c 100644 --- a/mapleall/maple_me/include/me_ssa_lpre.h +++ b/mapleall/maple_me/include/me_ssa_lpre.h @@ -70,8 +70,8 @@ class MeSSALPre : public SSAPre { void BuildWorkListExpr(MeStmt *, int32, MeExpr *, bool, MeExpr *, bool isRootExpr); void BuildWorkList(); BB *GetBB(BBId id) { - CHECK(id.idx < func->bbVec.size(), "index out of range in MeSSALPre::GetBB"); - return func->bbVec[id.idx]; + CHECK(id.idx < func->theCFG->bbVec.size(), "index out of range in MeSSALPre::GetBB"); + return func->theCFG->bbVec[id.idx]; } PUIdx GetPuidx(MeStmt *stmt) { diff --git a/mapleall/maple_me/include/me_ssa_tab.h b/mapleall/maple_me/include/me_ssa_tab.h index e076ecdee915de706d20efc1c720034aca7ab1c5..97a7e64c0e4e9a1de59a876868d4a8fa2903422b 100644 --- a/mapleall/maple_me/include/me_ssa_tab.h +++ b/mapleall/maple_me/include/me_ssa_tab.h @@ -16,6 +16,7 @@ #ifndef MAPLE_ME_INCLUDE_ME_SSA_TAB_H #define MAPLE_ME_INCLUDE_ME_SSA_TAB_H #include "me_function.h" +#include "me_cfg.h" #include "me_phase.h" namespace maple { diff --git a/mapleall/maple_me/include/me_stmt_pre.h b/mapleall/maple_me/include/me_stmt_pre.h index 2783fe3d5338e1abd1a9496d8e0154c71f3e5bff..4d9f5e2b52718be5c6f52f6fcc95cc7c9a900d71 100644 --- a/mapleall/maple_me/include/me_stmt_pre.h +++ b/mapleall/maple_me/include/me_stmt_pre.h @@ -71,7 +71,7 @@ class MeStmtPre : public SSAEPre { void RemoveUnecessaryDassign(DassignMeStmt *); void DoSSAFRE(); BB *GetBB(BBId id) { - return func->bbVec[id.idx]; + return func->theCFG->bbVec[id.idx]; } PUIdx GetPuidx(MeStmt *stmt) { diff --git a/mapleall/maple_me/include/orig_symbol.h b/mapleall/maple_me/include/orig_symbol.h index ae60386dd3cd47a8160160ede94665fae884b27c..79b50710060db5d04d159ff491d900757078668e 100644 --- a/mapleall/maple_me/include/orig_symbol.h +++ b/mapleall/maple_me/include/orig_symbol.h @@ -154,7 +154,18 @@ class OriginalSt { return symRenamed || (indexRenamedFrom.idx != 0); } - ~OriginalSt(){}; + bool IsIVCandidate() const { + if (indirectLev != 0 || + (IsSymbol() && GetMIRSymbol()->GetName() == "__nads_dummysym__")) { + return false; + } + MIRType *mirtype = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); + return IsPrimitiveInteger(mirtype->primType) && mirtype->typeKind != kTypeBitField; + } + + MIRType *GetType() const { + return GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); + } }; // This Table is for original symobols only. There is no SSA info attached and SSA is built based on this table. diff --git a/mapleall/maple_me/include/prop.h b/mapleall/maple_me/include/prop.h index a0e3d4cef886ddf9777a3d9ee85c9de352e42dae..d29256e8b0b8133151212eeef4e2fa85d0e68f73 100644 --- a/mapleall/maple_me/include/prop.h +++ b/mapleall/maple_me/include/prop.h @@ -25,6 +25,12 @@ namespace maple { class IRMap; class Dominance; +enum Propagatability { + kPropNo, + kPropOnlyWithInverse, + kPropYes, +}; + class Prop { public: IRMap *irMap; @@ -73,13 +79,16 @@ class Prop { bool IsVersionConsistent(const std::vector &vervec, const MapleVector *> &vstLiveStack) const; bool IvarIsFinalField(const IvarMeExpr *ivarmeexpr); - bool Propagatable(MeExpr *x, BB *frombb, bool atParm); + int32 InvertibleOccurrences(ScalarMeExpr *scalar, MeExpr *x); + bool IsFunctionOfCurVersion(ScalarMeExpr *scalar, ScalarMeExpr *cur); + Propagatability Propagatable(MeExpr *x, BB *frombb, bool atParm, bool checkInverse = false, ScalarMeExpr *propagatingScalar = nullptr); + MeExpr *FormInverse(ScalarMeExpr *v, MeExpr *x, MeExpr *formingExp); + MeExpr *RehashUsingInverse(MeExpr *x); MeExpr *CheckTruncation(MeExpr *lhs, MeExpr *rhs); MeExpr *PropReg(RegMeExpr *regmeexpr, bool atParm); void TraversalMeStmt(MeStmt *); public: - MeExpr *SimplifyMeExpr(OpMeExpr *); MeExpr *PropMeExpr(MeExpr *meexpr, bool &isproped, bool atParm); MeExpr *PropVar(VarMeExpr *varmeexpr, bool atParm, bool checkPhi); MeExpr *PropIvar(IvarMeExpr *ivarmeexpr); diff --git a/mapleall/maple_me/include/ssa.h b/mapleall/maple_me/include/ssa.h index cc2aa79daa30dd7f8a18cf5d7c4d6b4ac58081fc..7599fc15a656398d0cebd55537dfcc90bf284a8a 100644 --- a/mapleall/maple_me/include/ssa.h +++ b/mapleall/maple_me/include/ssa.h @@ -18,6 +18,7 @@ #include #include "mir_module.h" #include "mir_nodes.h" +#include "me_phase.h" namespace maple { @@ -42,7 +43,7 @@ class PhiNode { void Dump(const MIRModule *mod); }; -class SSA { +class SSA : public AnalysisResult { public: MapleAllocator ssaAlloc; MapleVector *> vstStacks; // rename stack for variable versions @@ -54,7 +55,8 @@ class SSA { bool runRenameOnly = false; SSA(MemPool *mp, SSATab *stab, Dominance *dm, MapleVector &bbvec) - : ssaAlloc(mp), + : AnalysisResult(mp), + ssaAlloc(mp), vstStacks(ssaAlloc.Adapter()), bbRenamed(ssaAlloc.Adapter()), bbVec(bbvec), diff --git a/mapleall/maple_me/include/ssa_mir_nodes.h b/mapleall/maple_me/include/ssa_mir_nodes.h index 9dd55e31ec55e598fd4430568eaa178b5646fd38..d950722097d1183b2bcdbeb33413915070d36dbf 100644 --- a/mapleall/maple_me/include/ssa_mir_nodes.h +++ b/mapleall/maple_me/include/ssa_mir_nodes.h @@ -59,7 +59,7 @@ class MayDefNode { result->Dump(mod); LogInfo::MapleLogger() << " = MAYD("; opnd->Dump(mod); - LogInfo::MapleLogger() << ")" << std::endl; + LogInfo::MapleLogger() << ")"; } }; diff --git a/mapleall/maple_me/include/ssa_tab.h b/mapleall/maple_me/include/ssa_tab.h index 719bb4fde14a7fe1c1b6a5f52cfbacbdc518d0c6..e7b1f04a8093184eda26b20ccf8fbaee5a1afbb4 100644 --- a/mapleall/maple_me/include/ssa_tab.h +++ b/mapleall/maple_me/include/ssa_tab.h @@ -78,10 +78,6 @@ class SSATab : public AnalysisResult { OriginalSt *GetOriginalStFromid(OStIdx id) { return originalStTable.GetOriginalStFromid(id); } - OriginalSt *GetSymbolOriginalStFromid(OStIdx id) { - OriginalSt *ost = originalStTable.GetOriginalStFromid(id); - return ost; - } MIRSymbol *GetMIRSymbolFromid(OStIdx id) { return originalStTable.GetMIRSymbolFromid(id); } diff --git a/mapleall/maple_me/src/alias_class.cpp b/mapleall/maple_me/src/alias_class.cpp index a5ce793466f3ace6d16288c38d805c06238ce66b..6edfdd707d9733cff5cc23b4d2f5ceb20ee75a6a 100644 --- a/mapleall/maple_me/src/alias_class.cpp +++ b/mapleall/maple_me/src/alias_class.cpp @@ -178,7 +178,8 @@ AliasElem *AliasClass::FindOrCreateAliasElem(OriginalSt *ost) { if (aelem->ost->isFormal && ost->indirectLev != -1) { aelem->nextLevNotAllDefsSeen = true; } - if (!mirModule->IsCModule() && ost->indirectLev > 1) { + if (ost->indirectLev > 1) { + aelem->notAllDefsSeen = true; aelem->nextLevNotAllDefsSeen = true; } id2Elem.push_back(aelem); @@ -1190,7 +1191,9 @@ void AliasClass::CollectMayDefForDassign(const StmtNode *stmt, std::setHasFields()) { if (ostOfLhsAe->fieldID < ostOfAliasAe->fieldID || ostOfLhsAe->fieldID > (ostOfAliasAe->fieldID + (int32)aliasAeType->NumberOfFieldIDs())) { - continue; + if (!lhsAeType->HasFields()) { + continue; + } } } } diff --git a/mapleall/maple_me/src/bb.cpp b/mapleall/maple_me/src/bb.cpp index c379b73215866ab27c0e94342c7c4ce31a8210bc..24f36472830c47eb1b481c1cea64b5e29b6722b6 100644 --- a/mapleall/maple_me/src/bb.cpp +++ b/mapleall/maple_me/src/bb.cpp @@ -162,14 +162,14 @@ MeStmt *BB::GetTheOnlyMeStmtWithGoto() { void BB::DumpPhi(const MIRModule *mod) { MapleMap::iterator phiIt; - for (phiIt = phiList.begin(); phiIt != phiList.end(); phiIt++) { + for (phiIt = phiList->begin(); phiIt != phiList->end(); phiIt++) { (*phiIt).second.Dump(mod); } } PhiNode *BB::PhiofVerstInserted(VersionSt *vsym) { - MapleMap::iterator phiit = phiList.find(vsym->ost); - return (phiit != phiList.end()) ? &(*phiit).second : nullptr; + MapleMap::iterator phiit = phiList->find(vsym->ost); + return (phiit != phiList->end()) ? &(*phiit).second : nullptr; } void BB::InsertPhi(MapleAllocator *alloc, VersionSt *vsym) { @@ -180,7 +180,7 @@ void BB::InsertPhi(MapleAllocator *alloc, VersionSt *vsym) { phinode.phiOpnds.push_back(vsym); } - phiList.insert(std::make_pair(vsym->ost, phinode)); + phiList->insert(std::make_pair(vsym->ost, phinode)); } bool BB::IsInList(MapleVector &bblist) const { @@ -217,9 +217,11 @@ int BB::RemoveBBFromVector(MapleVector &bvec) { void BB::RemoveBBFromPred(BB *bb) { int index = bb->RemoveBBFromVector(pred); - for (auto phiIt = phiList.begin(); phiIt != phiList.end(); phiIt++) { - MapleVector *opnds = &(*phiIt).second.phiOpnds; - opnds->erase(opnds->begin() + index); + if (phiList) { + for (auto phiIt = phiList->begin(); phiIt != phiList->end(); phiIt++) { + MapleVector *opnds = &(*phiIt).second.phiOpnds; + opnds->erase(opnds->begin() + index); + } } for (auto phiIt = mePhiList.begin(); phiIt != mePhiList.end(); phiIt++) { MapleVector *opnds = &(*phiIt).second->opnds; diff --git a/mapleall/maple_me/src/hdse.cpp b/mapleall/maple_me/src/hdse.cpp index aaf97298e79bb9b9ce75d13b05e5c096e07a053a..9c128454e8a1da31150891e8f642c14b01312bb4 100644 --- a/mapleall/maple_me/src/hdse.cpp +++ b/mapleall/maple_me/src/hdse.cpp @@ -24,6 +24,8 @@ #include "opcode_info.h" #include "mir_preg.h" +#define JAVALANG (irMap->ssaTab->mirModule.IsJavaModule()) + namespace maple { void HDSE::MarkExprNeeded(MeExpr *meexpr) { @@ -65,7 +67,7 @@ void HDSE::MarkExprNeeded(MeExpr *meexpr) { } case kMeOpReg: { RegMeExpr *regread = static_cast(meexpr); - PregIdx regIdx = regread->regIdx; + PregIdx regIdx = regread->GetPregIdx(); if (regIdx == -kSregRetval0) { if (regread->def.defStmt) { MarkStmtNeeded(regread->def.defStmt); @@ -204,7 +206,7 @@ void HDSE::MarkBBNeeded(BB *bb) { CHECK_FATAL((laststmt->IsCondBr() || op == OP_switch || op == OP_igoto || op == OP_retsub || op == OP_throw || cdBb->InTryBlock() || cdBb->WontExit()), "HDSE::MarkBBNeeded: control dependent on unexpected statement"); - if ((laststmt->IsCondBr() || op == OP_goto || op == OP_switch || op == OP_retsub || op == OP_throw) && + if ((laststmt->IsCondBr() || op == OP_goto || op == OP_switch || op == OP_igoto || op == OP_retsub || op == OP_throw) && !laststmt->isLive) { laststmt->isLive = true; UnaryMeStmt *unarystmt = dynamic_cast(laststmt); @@ -290,7 +292,7 @@ void HDSE::MarkStmtNeeded(MeStmt *mestmt) { } bool HDSE::ExprNonDeletable(MeExpr *x) { - if (kOpcodeInfo.HasSideEffect(x->op)) { + if (JAVALANG && kOpcodeInfo.HasSideEffect(x->op)) { return true; } switch (x->meOp) { @@ -305,7 +307,7 @@ bool HDSE::ExprNonDeletable(MeExpr *x) { return false; case kMeOpReg: { RegMeExpr *r = static_cast(x); - return (r->regIdx == -kSregThrownval); + return (r->GetPregIdx() == -kSregThrownval); } case kMeOpVar: { VarMeExpr *v = static_cast(x); @@ -518,6 +520,9 @@ void HDSE::DseProcess() { BB *bb = bbVec[i]; DseProcessBB(bb); } + if (IsLfo()) { + ProcessWhileInfos(); + } while (!worklist.empty()) { MeExpr *meexpr = worklist.front(); worklist.pop_front(); diff --git a/mapleall/maple_me/src/ipa_side_effect.cpp b/mapleall/maple_me/src/ipa_side_effect.cpp index 98830bd95833259406160b3fc0e7046062199f0a..3d93f113abd34caee4bbf069755ad9480aaf27b2 100644 --- a/mapleall/maple_me/src/ipa_side_effect.cpp +++ b/mapleall/maple_me/src/ipa_side_effect.cpp @@ -672,7 +672,7 @@ void IpaSideEffect::SideEffectAnalyzeBB(maple::BB *bb, vector &bbvisited) MapleSet *domChildren = &dominance->domChildren[bbid.idx]; for (const BBId &bbid : *domChildren) { BBId childbbid = bbid; - SideEffectAnalyzeBB(mefunc->bbVec.at(childbbid.idx), bbvisited); + SideEffectAnalyzeBB(mefunc->theCFG->bbVec[childbbid.idx], bbvisited); } } @@ -922,25 +922,25 @@ void IpaSideEffect::TrimCallGraph(maple::BB *bb, vector &bbvisited) { MapleSet *domChildren = &dominance->domChildren[bbid.idx]; for (MapleSet::iterator bbit = domChildren->begin(); bbit != domChildren->end(); bbit++) { BBId childbbid = *bbit; - TrimCallGraph(mefunc->bbVec.at(childbbid.idx), bbvisited); + TrimCallGraph(mefunc->theCFG->bbVec[childbbid.idx], bbvisited); } } void IpaSideEffect::DoAnalysis() { MapFuncNameToPuidx(); - BB *entrybb = mefunc->commonEntryBB; + BB *entrybb = mefunc->theCFG->commonEntryBB; MIRFunction *mirFunc = mefunc->mirFunc; sccId = GetSCCNodeId(mirFunc); if (mirFunc->body == nullptr) { // External function from mplt, need to update effects UpdateExternalFuncSideEffects(mirFunc); } else { - vector bbvisited(mefunc->bbVec.size(), false); + vector bbvisited(mefunc->theCFG->bbVec.size(), false); // Trim call graph based on the result of devirtualization TrimCallGraph(entrybb, bbvisited); SetEffectsForAllCallees(mirFunc); if (!(notPure && hasUse && hasDef && hasRetallocobj && hasThrexception)) { - vector bbvisited(mefunc->bbVec.size(), false); + vector bbvisited(mefunc->theCFG->bbVec.size(), false); SideEffectAnalyzeBB(entrybb, bbvisited); } } diff --git a/mapleall/maple_me/src/irmap.cpp b/mapleall/maple_me/src/irmap.cpp index e7f665ef3bc91a332534290f72a08c7b1a1cf38d..eca5f5e7cd8e0bdd6152b39696ceb85b716f1847 100644 --- a/mapleall/maple_me/src/irmap.cpp +++ b/mapleall/maple_me/src/irmap.cpp @@ -18,6 +18,7 @@ #include "ssa.h" #include #include "mir_builder.h" +#include "constant_fold.h" // This file contains infrastructure support for Hashed SSA Form. @@ -76,7 +77,7 @@ VarMeExpr *IRMap::CreateNewLocalrefvarTemp(GStrIdx strIdx, TyIdx tidx) { RegMeExpr *IRMap::CreateRegMeExprVersion(OriginalSt *ost) { RegMeExpr *regreadexpr = - New(exprID++, ost, verst2MeExprTable.size(), ost->GetMIRPreg()->primType); + New(exprID++, ost, verst2MeExprTable.size(), kMeOpReg, OP_regread, ost->GetMIRPreg()->primType); verst2MeExprTable.push_back(regreadexpr); return regreadexpr; } @@ -206,7 +207,6 @@ MeExpr *IRMap::HashMeExpr(MeExpr *meexpr) { case kMeOpAddrof: { AddrofMeExpr *addrofmeexpr = static_cast(meexpr); AddrofMeExpr *newaddrofmeexpr = New(exprID++, meexpr->primType, addrofmeexpr->ostIdx); - newaddrofmeexpr->fieldID = addrofmeexpr->fieldID; PutToBucket(hidx, newaddrofmeexpr); return newaddrofmeexpr; } @@ -611,8 +611,227 @@ MeExpr *IRMap::CreateAddrofMeExprFromNewSymbol(MIRSymbol *st, PUIdx puIdx) { baseOst->versionsIndex.push_back(baseOst->zeroVersionIndex); AddrofMeExpr addrofme(-1, PTY_ptr, baseOst->index); - addrofme.fieldID = 0; return HashMeExpr(&addrofme); } -} // namespace maple +MeExpr *IRMap::SimplifyOpMeExpr(OpMeExpr *opmeexpr) { + Opcode opop = opmeexpr->op; + switch (opop) { + case OP_cvt: { + // return nullptr; + OpMeExpr *cvtmeexpr = static_cast(opmeexpr); + MeExpr *opnd0 = cvtmeexpr->GetOpnd(0); + if (opnd0->meOp == kMeOpConst) { + ConstantFold cf(mirModule); + MIRConst *tocvt = + cf.FoldTypeCvtMIRConst(static_cast(opnd0)->constVal, opnd0->primType, cvtmeexpr->primType); + if (tocvt) { + return CreateConstMeExpr(cvtmeexpr->primType, tocvt); + } + } + if (opnd0->op == OP_cvt) { + OpMeExpr *cvtopnd0 = static_cast(opnd0); + // cvtopnd0 should have tha same type as cvtopnd0->GetOpnd(0) or cvtmeexpr, + // and the type size of cvtopnd0 should be ge(>=) one of them. + // Otherwise, deleting the cvt of cvtopnd0 may result in information loss. + if (maple::GetPrimTypeSize(cvtopnd0->primType) >= maple::GetPrimTypeSize(cvtopnd0->GetOpnd(0)->primType)) { + if ((maple::IsPrimitiveInteger(cvtopnd0->primType) && maple::IsPrimitiveInteger(cvtopnd0->GetOpnd(0)->primType)) || + (maple::IsPrimitiveFloat(cvtopnd0->primType) && maple::IsPrimitiveFloat(cvtopnd0->GetOpnd(0)->primType))) { + return CreateMeExprTypeCvt(cvtmeexpr->primType, cvtopnd0->opndType, cvtopnd0->GetOpnd(0)); + } + } + if (maple::GetPrimTypeSize(cvtopnd0->primType) >= maple::GetPrimTypeSize(cvtmeexpr->primType)) { + if ((maple::IsPrimitiveInteger(cvtopnd0->primType) && maple::IsPrimitiveInteger(cvtmeexpr->primType)) || + (maple::IsPrimitiveFloat(cvtopnd0->primType) && maple::IsPrimitiveFloat(cvtmeexpr->primType))) { + return CreateMeExprTypeCvt(cvtmeexpr->primType, cvtopnd0->opndType, cvtopnd0->GetOpnd(0)); + } + } + } + return nullptr; + } + case OP_add: + case OP_sub: + case OP_mul: + case OP_div: + case OP_rem: + case OP_ashr: + case OP_lshr: + case OP_shl: + case OP_max: + case OP_min: + case OP_band: + case OP_bior: + case OP_bxor: + case OP_cand: + case OP_land: + case OP_cior: + case OP_lior: + case OP_depositbits: { + if (!IsPrimitiveInteger(opmeexpr->primType)) { + return nullptr; + } + MeExpr *opnd0 = opmeexpr->GetOpnd(0); + MeExpr *opnd1 = opmeexpr->GetOpnd(1); + if (opop == OP_sub && opnd0 == opnd1) { + return CreateIntConstMeExpr(0, opmeexpr->primType); + } + if (opnd0->meOp != kMeOpConst || opnd1->meOp != kMeOpConst) { + return nullptr; + } + maple::ConstantFold cf(mirModule); + MIRIntConst *opnd0const = static_cast(static_cast(opnd0)->constVal); + MIRIntConst *opnd1const = static_cast(static_cast(opnd1)->constVal); + if ((opop == OP_div || opop == OP_rem)) { + int64 opnd0constValue = opnd0const->value; + int64 opnd1constValue = opnd1const->value; + PrimType resPtyp = opmeexpr->primType; + if (opnd1constValue == 0 || + (opnd1constValue == -1 && ((resPtyp == PTY_i32 && opnd0constValue == MININT32) || + (resPtyp == PTY_i64 && opnd0constValue == MININT64)))) { + return nullptr; + } + } + MIRConst *resconst = cf.FoldIntConstBinaryMIRConst(opmeexpr->op, + opmeexpr->primType, opnd0const, opnd1const); + return CreateConstMeExpr(opmeexpr->primType, resconst); + } + case OP_ne: + case OP_eq: + case OP_lt: + case OP_le: + case OP_ge: + case OP_gt: + case OP_cmp: + case OP_cmpl: + case OP_cmpg: { + MeExpr *opnd0 = opmeexpr->GetOpnd(0); + MeExpr *opnd1 = opmeexpr->GetOpnd(1); + bool isneeq = (opop == OP_ne || opop == OP_eq); + if (opnd0->meOp == kMeOpConst && opnd1->meOp == kMeOpConst) { + maple::ConstantFold cf(mirModule); + MIRConst *opnd0const = static_cast(opnd0)->constVal; + MIRConst *opnd1const = static_cast(opnd1)->constVal; + MIRConst *resconst = cf.FoldConstComparisonMIRConst(opmeexpr->op, opmeexpr->primType, opmeexpr->opndType, + opnd0const, opnd0->primType, opnd1const, opnd1->primType); + return CreateConstMeExpr(opmeexpr->primType, resconst); + } else if (isneeq && ((opnd0->meOp == kMeOpAddrof && opnd1->meOp == kMeOpConst) || + (opnd0->meOp == kMeOpConst && opnd1->meOp == kMeOpAddrof))) { + MIRConst *resconst = nullptr; + if (opnd0->meOp == kMeOpAddrof) { + MIRConst *constopnd1 = static_cast(opnd1)->constVal; + if (constopnd1->IsZero()) { + // addrof will not be zero, so this comparison can be replaced with a constant + resconst = mirModule->memPool->New((opop == OP_ne), GlobalTables::GetTypeTable().typeTable.at(PTY_u1)); + } + } else { + MIRConst *constopnd0 = static_cast(opnd0)->constVal; + if (constopnd0->IsZero()) { + // addrof will not be zero, so this comparison can be replaced with a constant + resconst = mirModule->memPool->New((opop == OP_ne), GlobalTables::GetTypeTable().typeTable.at(PTY_u1)); + } + } + if (resconst) { + return CreateConstMeExpr(opmeexpr->primType, resconst); + } + } else if (isneeq && opnd0->op == OP_select && + (opnd1->meOp == kMeOpConst && IsPrimitivePureScalar(opnd1->primType))) { + OpMeExpr *opmeopnd0 = static_cast(opnd0); + if (opmeopnd0->op == OP_select) { + MeExpr *opnd01 = opmeopnd0->GetOpnd(1); + MeExpr *opnd02 = opmeopnd0->GetOpnd(2); + if (opnd01->meOp == kMeOpConst && IsPrimitivePureScalar(opnd01->primType) && opnd02->meOp == kMeOpConst && + IsPrimitivePureScalar(opnd02->primType)) { + MIRConst *constopnd1 = static_cast(opnd1)->constVal; + MIRConst *constopnd01 = static_cast(opnd01)->constVal; + MIRConst *constopnd02 = static_cast(opnd02)->constVal; + bool needswapopnd = false; + bool canbereplaced = false; + bool isne = opmeexpr->op == OP_ne; + if (isne && constopnd1->IsZero() && constopnd01->IsOne() && constopnd02->IsZero()) { + canbereplaced = true; + } else if (isne && constopnd1->IsZero() && constopnd01->IsZero() && constopnd02->IsOne()) { + canbereplaced = true; + } else if (isne && constopnd1->IsOne() && constopnd01->IsOne() && constopnd02->IsZero()) { + needswapopnd = true; + canbereplaced = true; + } else if (isne && constopnd1->IsOne() && constopnd01->IsZero() && constopnd02->IsOne()) { + needswapopnd = true; + canbereplaced = true; + } else if (!isne && constopnd1->IsZero() && constopnd01->IsOne() && constopnd02->IsZero()) { + needswapopnd = true; + canbereplaced = true; + } else if (!isne && constopnd1->IsZero() && constopnd01->IsZero() && constopnd02->IsOne()) { + needswapopnd = true; + canbereplaced = true; + } else if (!isne && constopnd1->IsOne() && constopnd01->IsOne() && constopnd02->IsZero()) { + canbereplaced = true; + } else if (!isne && constopnd1->IsOne() && constopnd01->IsZero() && constopnd02->IsOne()) { + canbereplaced = true; + } + if (canbereplaced) { + OpMeExpr newopmeexpr(-1, OP_select, PTY_u1, 3); + newopmeexpr.SetOpnd(opmeopnd0->GetOpnd(0), 0); + ConstMeExpr xnewopnd01(-1, constopnd01, PTY_u1); + MeExpr *newopnd01 = HashMeExpr(&xnewopnd01); + ConstMeExpr xnewopnd02(-1, constopnd02, PTY_u1); + MeExpr *newopnd02 = HashMeExpr(&xnewopnd02); + if (needswapopnd) { + newopmeexpr.SetOpnd(newopnd02, 1); + newopmeexpr.SetOpnd(newopnd01, 2); + } else { + newopmeexpr.SetOpnd(newopnd01, 1); + newopmeexpr.SetOpnd(newopnd02, 2); + } + return HashMeExpr(&newopmeexpr); + } + } + } + } + return nullptr; + } + default: + return nullptr; + } +} + +MeExpr *IRMap::SimplifyMeExpr(MeExpr *x) { + switch (x->meOp) { + case kMeOpAddrof: + case kMeOpAddroffunc: + case kMeOpConst: + case kMeOpConststr: + case kMeOpConststr16: + case kMeOpSizeoftype: + case kMeOpFieldsDist: + case kMeOpVar: + case kMeOpReg: + case kMeOpIvar: return x; + case kMeOpOp: { + OpMeExpr *opexp = static_cast(x); + opexp->SetOpnd(SimplifyMeExpr(opexp->GetOpnd(0)), 0); + if (opexp->numOpnds > 1) { + opexp->SetOpnd(SimplifyMeExpr(opexp->GetOpnd(1)), 1); + if (opexp->numOpnds > 2) { + opexp->SetOpnd(SimplifyMeExpr(opexp->GetOpnd(2)), 2); + } + } + MeExpr *newexp = SimplifyOpMeExpr(opexp); + if (newexp) { + return newexp; + } + return opexp; + } + case kMeOpNary: { + NaryMeExpr *opexp = static_cast(x); + for (uint32 i = 0; i < opexp->numOpnds; i++) { + opexp->SetOpnd(SimplifyMeExpr(opexp->GetOpnd(i)), i); + } + // TODO do the simplification of this op + return opexp; + } + default: ; + } + return x; +} + +} // namespace maple diff --git a/mapleall/maple_me/src/irmap_build.cpp b/mapleall/maple_me/src/irmap_build.cpp index ed89f8ad2f7d57e1d4d73773c356874e68efd7bd..8154bcf95625ba79702089144b2ae967a6e5677b 100644 --- a/mapleall/maple_me/src/irmap_build.cpp +++ b/mapleall/maple_me/src/irmap_build.cpp @@ -47,7 +47,7 @@ RegMeExpr *IrMapBuild::GetOrCreateRegFromVerSt(const VersionSt *verst) { OriginalSt *ost = verst->ost; ASSERT(ost->ostType == OriginalSt::kPregOst, "GetOrCreateRegFromVerSt: PregOST expected"); - RegMeExpr *regx = irMap->New(irMap->exprID++, ost, vindex, ost->GetMIRPreg()->primType); + RegMeExpr *regx = irMap->New(irMap->exprID++, ost, vindex, kMeOpReg, OP_regread, ost->GetMIRPreg()->primType); irMap->verst2MeExprTable[vindex] = regx; return regx; } @@ -111,7 +111,7 @@ void IrMapBuild::BuildMustdefList(MeStmt *mestmt, MapleVector &must } void IrMapBuild::BuildPhiMeNode(BB *bb) { - for (MapleMap::iterator phiit = bb->phiList.begin(); phiit != bb->phiList.end(); phiit++) { + for (MapleMap::iterator phiit = bb->phiList->begin(); phiit != bb->phiList->end(); phiit++) { OriginalSt *origst = (*phiit).first; VersionSt *verst = (*phiit).second.result; MePhiNode *phimenode = irMap->NewInPool(); @@ -172,7 +172,6 @@ MeExpr *IrMapBuild::BuildExpr(BaseNode *mirnode, bool atParm, bool noProp) { VersionSt *verst = addrofnode->ssaVar; OriginalSt *ost = verst->ost; AddrofMeExpr addrofme(-1, mirnode->primType, ost->index); - addrofme.fieldID = addrofnode->fieldID; retmeexpr = irMap->HashMeExpr(&addrofme); break; } @@ -187,7 +186,7 @@ MeExpr *IrMapBuild::BuildExpr(BaseNode *mirnode, bool atParm, bool noProp) { MeExpr *propedMeExpr = propagater->PropVar(varmeexpr, atParm, true); MeExpr *simplifiedMeexpr = nullptr; if (propedMeExpr->meOp == kMeOpOp) { - simplifiedMeexpr =propagater->SimplifyMeExpr(static_cast(propedMeExpr)); + simplifiedMeexpr = irMap->SimplifyOpMeExpr(static_cast(propedMeExpr)); } retmeexpr = simplifiedMeexpr ? simplifiedMeexpr : propedMeExpr; } else { @@ -269,7 +268,7 @@ MeExpr *IrMapBuild::BuildExpr(BaseNode *mirnode, bool atParm, bool noProp) { MeExpr *propedMeExpr = propagater->PropIvar(canIvar); MeExpr *simplifiedMeexpr = nullptr; if (propedMeExpr->meOp == kMeOpOp) { - simplifiedMeexpr =propagater->SimplifyMeExpr(static_cast(propedMeExpr)); + simplifiedMeexpr = irMap->SimplifyOpMeExpr(static_cast(propedMeExpr)); } retmeexpr = simplifiedMeexpr ? simplifiedMeexpr : propedMeExpr; } else { diff --git a/mapleall/maple_me/src/irmap_emit.cpp b/mapleall/maple_me/src/irmap_emit.cpp index f91557227d6ad53f9d9bfcb4e5877413c57bdd37..a17a3c74dc0ec27d098cf5768bf78741265b1ec1 100644 --- a/mapleall/maple_me/src/irmap_emit.cpp +++ b/mapleall/maple_me/src/irmap_emit.cpp @@ -46,8 +46,8 @@ BaseNode *VarMeExpr::EmitExpr(SSATab *ssaTab) { BaseNode *RegMeExpr::EmitExpr(SSATab *ssaTab) { RegreadNode *regread = ssaTab->mirModule.CurFunction()->codeMemPool->New(); regread->primType = primType; - regread->regIdx = regIdx; - ASSERT(regIdx < 0 || static_cast(regIdx) < ssaTab->mirModule.CurFunction()->pregTab->Size(), + regread->regIdx = GetPregIdx(); + ASSERT(regread->regIdx < 0 || static_cast(regread->regIdx) < ssaTab->mirModule.CurFunction()->pregTab->Size(), "RegMeExpr::EmitExpr: pregidx exceeds preg table size"); return regread; } @@ -83,12 +83,13 @@ BaseNode *FieldsDistMeExpr::EmitExpr(SSATab *ssaTab) { } BaseNode *AddrofMeExpr::EmitExpr(SSATab *ssaTab) { - MIRSymbol *sym = ssaTab->GetMIRSymbolFromid(ostIdx); + OriginalSt *ost = ssaTab->GetOriginalStFromid(ostIdx); + MIRSymbol *sym = ost->GetMIRSymbol(); if (sym->IsLocal()) { sym->ResetIsDeleted(); } AddrofNode *addrofnode = - ssaTab->mirModule.CurFunction()->codeMemPool->New(OP_addrof, primType, sym->stIdx, fieldID); + ssaTab->mirModule.CurFunction()->codeMemPool->New(OP_addrof, primType, sym->stIdx, ost->fieldID); return addrofnode; } @@ -247,14 +248,7 @@ BaseNode *NaryMeExpr::EmitExpr(SSATab *ssaTab) { nodeToReturn = arrnode; } else { IntrinsicopNode *intrinnode; - if (op == OP_intrinsicopwithtype) { - IntrinsicopNode *intrinwith = - ssaTab->mirModule.CurFunction()->codeMemPool->New(&(ssaTab->mirModule), OP_intrinsicopwithtype, primType); - intrinwith->tyIdx = tyIdx; - intrinnode = intrinwith; - } else - intrinnode = - ssaTab->mirModule.CurFunction()->codeMemPool->New(&(ssaTab->mirModule), OP_intrinsicop, primType); + intrinnode = ssaTab->mirModule.CurFunction()->codeMemPool->New(&(ssaTab->mirModule), op, primType, tyIdx); intrinnode->numOpnds = numOpnds; intrinnode->intrinsic = intrinsic; nopndpart = intrinnode; @@ -290,7 +284,7 @@ StmtNode *AssignMeStmt::EmitStmt(SSATab *ssaTab) { } if (lhs->meOp == kMeOpReg) { RegassignNode *regassignstmt = - ssaTab->mirModule.mirBuilder->CreateStmtRegassign(lhs->primType, GetRegLhs()->regIdx, rhs->EmitExpr(ssaTab)); + ssaTab->mirModule.mirBuilder->CreateStmtRegassign(lhs->primType, GetRegLhs()->GetPregIdx(), rhs->EmitExpr(ssaTab)); regassignstmt->srcPosition = srcPos; return regassignstmt; } else { @@ -358,7 +352,7 @@ void MeStmt::EmitCallReturnVector(SSATab *ssaTab, CallReturnVector *returnValues MIRSymbol *sym = ost->GetMIRSymbol(); returnValues->push_back(CallReturnPair(sym->GetStIdx(), RegFieldPair(0, 0))); } else if (meexpr->meOp == kMeOpReg) { - returnValues->push_back(CallReturnPair(StIdx(), RegFieldPair(0, static_cast(meexpr)->regIdx))); + returnValues->push_back(CallReturnPair(StIdx(), RegFieldPair(0, static_cast(meexpr)->GetPregIdx()))); } } diff --git a/mapleall/maple_me/src/lfo_inject_iv.cpp b/mapleall/maple_me/src/lfo_inject_iv.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b8f219e1df02d8f73bac65442c5c9aa853d4dd65 --- /dev/null +++ b/mapleall/maple_me/src/lfo_inject_iv.cpp @@ -0,0 +1,92 @@ +/* + * 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 "lfo_inject_iv.h" +#include "dominance.h" +#include "me_ident_loops.h" +#include "me_option.h" +#include "mir_builder.h" +#include + +namespace maple { + +AnalysisResult *DoLfoInjectIV::Run(MeFunction *func, MeFuncResultMgr *m) { + Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func, !MeOption::quiet)); + CHECK_FATAL(dom, "dominance phase has problem"); + IdentifyLoops *identloops = static_cast(m->GetAnalysisResult(MeFuncPhase_IDENTLOOPS, func, !MeOption::quiet)); + CHECK_FATAL(identloops != nullptr, "identloops has problem"); + + uint32 ivCount = 0; + MIRBuilder *mirbuilder = func->mirModule.mirBuilder; + LfoFunction *lfoFunc = func->lfoFunc; + + for (LoopDesc *aloop : identloops->meloops) { + BB *headbb = aloop->head; + // check if the label has associated LfoWhileInfo + if (headbb->bbLabel == 0) { + continue; + } + if (headbb->pred.size() != 2) { + continue; // won't insert IV for loops with > 1 tail bbs + } + MapleMap::iterator it = lfoFunc->label2WhileInfo.find(headbb->bbLabel); + if (it == lfoFunc->label2WhileInfo.end()) { + continue; + } + LfoWhileInfo *whileInfo = it->second; + // find the entry BB as the predecessor of headbb that dominates headbb + MapleVector::iterator predit = headbb->pred.begin(); + for ( ; predit != headbb->pred.end(); predit++) { + if (dom->Dominate(*predit, headbb)) + break; + } + if (predit == headbb->pred.end()) { + continue; // cannot insert IV for this loop + } + BB *entrybb = *predit; + + // create the IV for this loop + std::string ivName("injected.iv"); + ivName.append(std::to_string(++ivCount)); + GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(ivName); + MIRSymbol *st = mirbuilder->CreateSymbol((TyIdx)PTY_i64, strIdx, kStVar, kScAuto, kScopeLocal, func->mirFunc); + whileInfo->injectedIVSym = st; + if (DEBUGFUNC(func)) { + LogInfo::MapleLogger() << "****** Injected IV " << st->GetName() << " in while loop at label "; + LogInfo::MapleLogger() << "@" << func->mirFunc->GetLabelName(headbb->bbLabel) << std::endl; + } + + // initialize IV to 0 at loop entry + DassignNode *dass = mirbuilder->CreateStmtDassign(st, 0, mirbuilder->CreateIntConst(0, PTY_i64)); + StmtNode *laststmt = entrybb->stmtNodeList.last; + if (laststmt && + (laststmt->op == OP_brfalse || laststmt->op == OP_brtrue || laststmt->op == OP_goto || laststmt->op == OP_igoto || laststmt->op == OP_switch)) { + entrybb->InsertStmtBefore(laststmt, dass); + } else { + entrybb->AddStmtNode(dass); + } + + // insert IV increment at loop tail BB + BB *tailbb = aloop->tail; + AddrofNode *dread = mirbuilder->CreateExprDread(GlobalTables::GetTypeTable().GetInt64(), 0, st); + BinaryNode *addnode = mirbuilder->CreateExprBinary(OP_add, GlobalTables::GetTypeTable().GetInt64(), dread, mirbuilder->CreateIntConst(1, PTY_i64)); + dass = mirbuilder->CreateStmtDassign(st, 0, addnode); + laststmt = tailbb->stmtNodeList.last; + tailbb->InsertStmtBefore(laststmt, dass); + } + return nullptr; +} + +} // namespace maple diff --git a/mapleall/maple_me/src/lfo_iv_canon.cpp b/mapleall/maple_me/src/lfo_iv_canon.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8891974d737d8f77d8bf304ae3287538cddd9e20 --- /dev/null +++ b/mapleall/maple_me/src/lfo_iv_canon.cpp @@ -0,0 +1,535 @@ +/* + * 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 "lfo_iv_canon.h" +#include "me_option.h" +#include "lfo_function.h" + +// This phase implements Step 4 of the paper: +// S.-M. Liu, R. Lo and F. Chow, "Loop Induction Variable +// Canonicalization in Parallelizing Compiler", Intl. Conf. on Parallel +// Architectures and Compilation Techniques (PACT 96), Oct 1996. + +using namespace std; + +namespace maple { + +// Resolve value of x; return false if result is not of induction expression +// form; goal is to resolve to an expression where the only non-constant is +// philhs +bool IVCanon::ResolveExprValue(MeExpr *x, ScalarMeExpr *philhs) { + switch (x->meOp) { + case kMeOpConst: return IsPrimitiveInteger(x->primType); + case kMeOpVar: + case kMeOpReg:{ + if (x == philhs) { + return true; + } + ScalarMeExpr *scalar = static_cast(x); + if (scalar->defBy != kDefByStmt) { + return false; + } + AssignMeStmt *defstmt = scalar->def.defStmt; + return ResolveExprValue(defstmt->rhs, philhs); + } + case kMeOpOp: { // restricting to only + and - for now + if (x->op != OP_add && x->op != OP_sub) { + return false; + } + OpMeExpr *opexp = static_cast(x); + return ResolveExprValue(opexp->GetOpnd(0), philhs) && + ResolveExprValue(opexp->GetOpnd(1), philhs); + } + default: ; + } + return false; +} + +// appearances accumulates the number of appearances of the induction variable; +// it is negative if it is subtracted +int32 IVCanon::ComputeIncrAmt(MeExpr *x, ScalarMeExpr *philhs, int32 *appearances) { + switch (x->meOp) { + case kMeOpConst: { + MIRConst *konst = static_cast(x)->constVal; + CHECK_FATAL(konst->kind == kConstInt, "ComputeIncrAmt: must be integer constant"); + MIRIntConst *intconst = static_cast(konst); + return intconst->value; + } + case kMeOpVar: + case kMeOpReg:{ + if (x == philhs) { + *appearances = 1; + return 0; + } + ScalarMeExpr *scalar = static_cast(x); + CHECK_FATAL(scalar->defBy == kDefByStmt, "ComputeIncrAmt: cannot be here"); + AssignMeStmt *defstmt = scalar->def.defStmt; + return ComputeIncrAmt(defstmt->rhs, philhs, appearances); + } + case kMeOpOp: { + CHECK_FATAL(x->op == OP_add || x->op == OP_sub, "ComputeIncrAmt: cannot be here"); + OpMeExpr *opexp = static_cast(x); + int32 appear0 = 0; + int64 incrAmt0 = ComputeIncrAmt(opexp->GetOpnd(0), philhs, &appear0); + int32 appear1 = 0; + int64 incrAmt1 = ComputeIncrAmt(opexp->GetOpnd(1), philhs, &appear1); + if (x->op == OP_sub) { + *appearances = appear0 - appear1; + return incrAmt0 - incrAmt1; + } else { + *appearances = appear0 + appear1; + return incrAmt0 + incrAmt1; + } + } + default: ; + } + CHECK_FATAL(false, "ComputeIncrAmt: should not be here"); + return 0; +} + +// determine the initial and step values of the IV and push info to ivvec +void IVCanon::CharacterizeIV(ScalarMeExpr *initversion, ScalarMeExpr *loopbackversion, ScalarMeExpr *philhs) { + IVDesc *ivdesc = mp->New(initversion->ost); + if (initversion->defBy == kDefByStmt) { + AssignMeStmt *defstmt = initversion->def.defStmt; + if (defstmt->rhs->meOp == kMeOpConst || + defstmt->rhs->meOp == kMeOpAddrof || + defstmt->rhs->meOp == kMeOpConststr || + defstmt->rhs->meOp == kMeOpConststr16) { + ivdesc->initExpr = defstmt->rhs; + } else { + ivdesc->initExpr = initversion; + } + } else { + ivdesc->initExpr = initversion; + } + int32 appearances = 0; + ivdesc->stepValue = ComputeIncrAmt(loopbackversion, philhs, &appearances); + if (appearances == 1) { + ivvec.push_back(ivdesc); + } +} + +void IVCanon::FindPrimaryIV() { + for (uint32 i = 0; i < ivvec.size(); i++) { + IVDesc *ivdesc = ivvec[i]; + if (ivdesc->stepValue == 1) { + bool injected = false; + if (ivdesc->ost->IsSymbol() && + strncmp(ivdesc->ost->GetMIRSymbol()->GetName().c_str(), "injected.iv", 11) == 0) { + injected = true; + } + if (injected) { + if (idxPrimaryIV == -1) { + idxPrimaryIV = i; + } + } else { + // verify its increment is the last statement in loop body + BB *tailbb = aloop->tail; + MeStmt *laststmt = tailbb->meStmtList.last->prev; // skipping the branch stmt + if (laststmt == nullptr || laststmt->op != OP_dassign) { + continue; + } + DassignMeStmt *lastdass = static_cast(laststmt); + if (strncmp(lastdass->lhs->ost->GetMIRSymbol()->GetName().c_str(), "injected.iv", 11) == 0) { + laststmt = laststmt->prev; + if (laststmt == nullptr || laststmt->op != OP_dassign) { + continue; + } + lastdass = static_cast(laststmt); + } + if (lastdass->lhs->ost == ivdesc->ost) { + idxPrimaryIV = i; + return; + } + } + } + } +} + +bool IVCanon::IsLoopInvariant(MeExpr *x) { + if (x == nullptr) { + return true; + } + switch (x->meOp) { + case kMeOpAddrof: + case kMeOpAddroffunc: + case kMeOpConst: + case kMeOpConststr: + case kMeOpConststr16: + case kMeOpSizeoftype: + case kMeOpFieldsDist: return true; + case kMeOpVar: + case kMeOpReg: { + ScalarMeExpr *scalar = static_cast(x); + BB *defBB = scalar->DefByBB(); + return defBB == nullptr || dominance->Dominate(defBB, aloop->head); + } + case kMeOpIvar: { + IvarMeExpr *ivar = static_cast(x); + BB *defBB = ivar->mu->DefByBB(); + return defBB == nullptr || dominance->Dominate(defBB, aloop->head); + } + case kMeOpOp: { + OpMeExpr *opexp = static_cast(x); + return IsLoopInvariant(opexp->GetOpnd(0)) && + IsLoopInvariant(opexp->GetOpnd(1)) && + IsLoopInvariant(opexp->GetOpnd(2)); + } + case kMeOpNary: { + NaryMeExpr *opexp = static_cast(x); + for (uint32 i = 0; i < opexp->numOpnds; i++) { + if (!IsLoopInvariant(opexp->GetOpnd(i))) { + return false; + } + } + return true; + } + default: ; + } + return false; +} + +void IVCanon::ComputeTripCount() { + MeIRMap *irMap = func->irMap; + // find the termination test expression + if (!aloop->head->meStmtList.last->IsCondBr()) { + return; + } + CondGotoMeStmt *condbr = static_cast(aloop->head->meStmtList.last); + if (!kOpcodeInfo.IsCompare(condbr->opnd->op)) { + return; + } + OpMeExpr *testexp = static_cast(condbr->opnd); + // make the side that consists of a single IV the left operand + // check left operand + ScalarMeExpr *iv = dynamic_cast(testexp->GetOpnd(0)); + IVDesc *ivdesc = nullptr; + if (iv) { + for (uint32 i = 0; i < ivvec.size(); i++) { + if (iv->ost == ivvec[i]->ost) { + ivdesc = ivvec[i]; + break; + } + } + } + if (ivdesc == nullptr) { // check second operand + iv = dynamic_cast(testexp->GetOpnd(1)); + if (iv) { + for (uint32 i = 0; i < ivvec.size(); i++) { + if (iv->ost == ivvec[i]->ost) { + ivdesc = ivvec[i]; + break; + } + } + } + if (ivdesc) { // swap the 2 sides + Opcode newop = testexp->op; + switch (testexp->op) { + case OP_lt: newop = OP_gt; break; + case OP_le: newop = OP_ge; break; + case OP_gt: newop = OP_lt; break; + case OP_ge: newop = OP_le; break; + default: ; + } + OpMeExpr opmeexpr(-1, newop, testexp->primType, 2); + opmeexpr.SetOpnd(testexp->GetOpnd(1), 0); + opmeexpr.SetOpnd(testexp->GetOpnd(0), 1); + opmeexpr.opndType = testexp->opndType; + testexp = static_cast(irMap->HashMeExpr(&opmeexpr)); + condbr->opnd = testexp; + } + } + if (ivdesc == nullptr || ivdesc->stepValue == 0) { + return; // no IV in the termination test + } + if (!IsLoopInvariant(testexp->GetOpnd(1))) { + return; // the right side is not loop-invariant + } + + // check the termination test is in the right sense + if (ivdesc->stepValue > 0) { + if (condbr->opnd->op == OP_gt || condbr->opnd->op == OP_ge) { + return; + } + } else { + if (condbr->opnd->op == OP_lt || condbr->opnd->op == OP_le) { + return; + } + } + + // form the trip count expression + PrimType primTypeUsed = testexp->GetOpnd(0)->primType; + PrimType divPrimType = primTypeUsed; + if (ivdesc->stepValue < 0) { + divPrimType = GetSignedPrimType(divPrimType); + } + OpMeExpr add(-1, OP_add, primTypeUsed, 2); + add.SetOpnd(testexp->GetOpnd(1), 0); // IV bound + add.SetOpnd(irMap->CreateIntConstMeExpr(ivdesc->stepValue > 0 ? ivdesc->stepValue-1 : ivdesc->stepValue+1, primTypeUsed), 1); + MeExpr *subx = irMap->HashMeExpr(&add); + if (!ivdesc->initExpr->IsZero()) { + OpMeExpr subtract(-1, OP_sub, primTypeUsed, 2); + subtract.SetOpnd(subx, 0); + subtract.SetOpnd(ivdesc->initExpr, 1); + subx = irMap->HashMeExpr(&subtract); + } + MeExpr *divx = subx; + if (ivdesc->stepValue != 1) { + OpMeExpr divide(-1, OP_div, divPrimType, 2); + divide.SetOpnd(divx, 0); + divide.SetOpnd(irMap->CreateIntConstMeExpr(ivdesc->stepValue, divPrimType),1); + divx = irMap->HashMeExpr(÷); + } + tripCount = irMap->SimplifyMeExpr(dynamic_cast(divx)); +} + +void IVCanon::CanonEntryValues() { + for (uint32 i = 0; i < ivvec.size(); i++) { + IVDesc *ivdesc = ivvec[i]; + if (ivdesc->initExpr->meOp == kMeOpVar || ivdesc->initExpr->meOp == kMeOpReg) { +#if 1 // create temp var + std::string initName = ivdesc->ost->GetMIRSymbol()->GetName(); + initName.append(std::to_string(ivdesc->ost->fieldID)); + initName.append(std::to_string(loopID)); + initName.append(std::to_string(i)); + initName.append(".init"); + GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(initName); + ScalarMeExpr *scalarmeexpr = func->irMap->CreateNewVar(strIdx, ivdesc->primType, false); +#else // create preg + ScalarMeExpr *scalarmeexpr = func->irMap->CreateRegMeExpr(ivdesc->primType); +#endif + AssignMeStmt *ass = func->irMap->CreateAssignMeStmt(scalarmeexpr, ivdesc->initExpr, aloop->entry); + aloop->entry->AddMeStmtLast(ass); + ivdesc->initExpr = scalarmeexpr; + } + } +} + +void IVCanon::CanonExitValues() { + for (IVDesc *ivdesc : ivvec) { + BB *exitBB = aloop->exitBB; + // look for the identity assignment + MeStmt *stmt = exitBB->meStmtList.first; + while (stmt) { + if (stmt->op == OP_dassign || stmt->op == OP_regassign) { + AssignMeStmt *ass = static_cast(stmt); + if (ass->lhs->ost == ivdesc->ost) { + break; + } + } + stmt = stmt->next; + } + CHECK_FATAL(stmt != nullptr, "CanonExitValues: cannot find identity assignments at an exit node"); + AssignMeStmt *ass = static_cast(stmt); + CHECK_FATAL(ass->rhs->meOp == kMeOpVar || ass->rhs->meOp == kMeOpReg, + "CanonExitValues: assignment at exit node is not identity assignment"); + ScalarMeExpr *rhsvar = static_cast(ass->rhs); + CHECK_FATAL(rhsvar->ost == ivdesc->ost, + "CanonExitValues: assignment at exit node is not identity assignment"); + MeExpr *tripCountUsed = tripCount; + if (GetPrimTypeSize(tripCount->primType) != GetPrimTypeSize(ivdesc->primType)) { + OpMeExpr cvtx(-1, OP_cvt, ivdesc->primType, 1); + cvtx.SetOpnd(tripCount, 0); + cvtx.opndType = tripCount->primType; + tripCountUsed = func->irMap->HashMeExpr(&cvtx); + } + MeExpr *mulx = tripCountUsed; + if (ivdesc->stepValue != 1) { + PrimType primTypeUsed = ivdesc->stepValue < 0 ? GetSignedPrimType(ivdesc->primType) : ivdesc->primType; + OpMeExpr mulmeexpr(-1, OP_mul, primTypeUsed, 2); + mulmeexpr.SetOpnd(mulx, 0); + mulmeexpr.SetOpnd(func->irMap->CreateIntConstMeExpr(ivdesc->stepValue, primTypeUsed), 1); + mulx = func->irMap->HashMeExpr(&mulmeexpr); + } + MeExpr *addx = mulx; + if (!ivdesc->initExpr->IsZero()) { + OpMeExpr addmeexpr(-1, OP_add, ivdesc->primType, 2); + addmeexpr.SetOpnd(ivdesc->initExpr, 0); + addmeexpr.SetOpnd(mulx, 1); + addx = func->irMap->HashMeExpr(&addmeexpr); + } + ass->rhs = addx; + } +} + +void IVCanon::ReplaceSecondaryIVPhis() { + BB *headBB = aloop->head; + // first, form the expression of the primary IV minus its init value + IVDesc *primaryIVDesc = ivvec[idxPrimaryIV]; + // find its phi in the phi list at the loop head + MapleMap::iterator it = headBB->mePhiList.find(primaryIVDesc->ost->index); + MePhiNode *phi = it->second; + MeExpr *iterCountExpr = phi->lhs; + if (!primaryIVDesc->initExpr->IsZero()) { + OpMeExpr submeexpr(-1, OP_sub, primaryIVDesc->primType, 2); + submeexpr.SetOpnd(phi->lhs, 0); + submeexpr.SetOpnd(primaryIVDesc->initExpr, 1); + iterCountExpr = func->irMap->HashMeExpr(&submeexpr); + } + + for (uint32 i = 0; i < ivvec.size(); i++) { + if (i == idxPrimaryIV) { + continue; + } + IVDesc *ivdesc = ivvec[i]; + // find its phi in the phi list at the loop head + it = headBB->mePhiList.find(ivdesc->ost->index); + phi = it->second; + + MeExpr *iterCountUsed = iterCountExpr; + if (GetPrimTypeSize(iterCountExpr->primType) != GetPrimTypeSize(ivdesc->primType)) { + OpMeExpr cvtx(-1, OP_cvt, ivdesc->primType, 1); + cvtx.SetOpnd(iterCountExpr, 0); + cvtx.opndType = iterCountExpr->primType; + iterCountUsed = func->irMap->HashMeExpr(&cvtx); + } + MeExpr *mulx = iterCountUsed; + if (ivdesc->stepValue != 1) { + PrimType primTypeUsed = ivdesc->stepValue < 0 ? GetSignedPrimType(ivdesc->primType) : ivdesc->primType; + OpMeExpr mulmeexpr(-1, OP_mul, primTypeUsed, 2); + mulmeexpr.SetOpnd(mulx, 0); + mulmeexpr.SetOpnd(func->irMap->CreateIntConstMeExpr(ivdesc->stepValue, primTypeUsed), 1); + mulx = func->irMap->HashMeExpr(&mulmeexpr); + } + OpMeExpr addmeexpr(-1, OP_add, ivdesc->primType, 2); + MeExpr *addx = mulx; + if (!ivdesc->initExpr->IsZero()) { + addmeexpr.SetOpnd(ivdesc->initExpr, 0); + addmeexpr.SetOpnd(mulx, 1); + addx = func->irMap->HashMeExpr(&addmeexpr); + } + AssignMeStmt *ass = func->irMap->CreateAssignMeStmt(phi->lhs, addx, headBB); + headBB->PrependMeStmt(ass); + // change phi's lhs to new version + ScalarMeExpr *newlhs; + if (phi->lhs->meOp == kMeOpVar) { + newlhs = func->irMap->CreateVarMeExprVersion(ivdesc->ost); + } else { + newlhs = func->irMap->CreateRegMeExprVersion(ivdesc->ost); + } + phi->lhs = newlhs; + newlhs->defBy = kDefByPhi; + newlhs->def.defPhi = phi; + } +} + +void IVCanon::PerformIVCanon() { + BB *headbb = aloop->head; + uint32 phiOpndIdxOfInit = 1; + uint32 phiOpndIdxOfLoopBack = 0; + if (aloop->loop_bbs.count(headbb->pred[0]->id) == 0) { + phiOpndIdxOfInit = 0; + phiOpndIdxOfLoopBack = 1; + } + CHECK_FATAL(aloop->tail == headbb->pred[phiOpndIdxOfLoopBack], "PerformIVCanon: tail BB inaccurate"); + // go thru the list of phis at the loop head to find all IVs + for (std::pair mapEntry: headbb->mePhiList) { + OriginalSt *ost = ssatab->GetOriginalStFromid(mapEntry.first); + if (!ost->IsIVCandidate()) { + continue; + } + ScalarMeExpr *philhs = mapEntry.second->lhs; + ScalarMeExpr *initVersion = mapEntry.second->opnds[phiOpndIdxOfInit]; + ScalarMeExpr *loopbackVersion = mapEntry.second->opnds[phiOpndIdxOfLoopBack]; + if (ResolveExprValue(loopbackVersion, philhs)) { + CharacterizeIV(initVersion, loopbackVersion, philhs); + } + } + FindPrimaryIV(); + if (DEBUGFUNC(func)) { + LogInfo::MapleLogger() << "****** while loop at label " << "@" << func->mirFunc->GetLabelName(headbb->bbLabel); + LogInfo::MapleLogger() << ", BB id:" << headbb->id.idx << " has IVs:" << endl; + for (uint32 i = 0; i < ivvec.size(); i++) { + IVDesc *ivdesc = ivvec[i]; + ivdesc->ost->Dump(); + LogInfo::MapleLogger() << " step: " << ivdesc->stepValue << " initExpr: "; + ivdesc->initExpr->Dump(0); + if (i == idxPrimaryIV) { + LogInfo::MapleLogger() << " [PRIMARY IV]"; + } + LogInfo::MapleLogger() << endl; + } + } + CanonEntryValues(); + ComputeTripCount(); + if (tripCount == nullptr) { + return; + } + if (DEBUGFUNC(func)) { + LogInfo::MapleLogger() << "****** trip count is: "; + tripCount->Dump(func->irMap, 0); + LogInfo::MapleLogger() << endl; + } + CanonExitValues(); + ReplaceSecondaryIVPhis(); +} + +AnalysisResult *DoLfoIVCanon::Run(MeFunction *func, MeFuncResultMgr *m) { + Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func, !MeOption::quiet)); + ASSERT(dom != nullptr, "dominance phase has problem"); + + MeIRMap *irmap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func, !MeOption::quiet)); + ASSERT(irmap != nullptr, "hssamap has problem"); + + IdentifyLoops *identloops = static_cast(m->GetAnalysisResult(MeFuncPhase_IDENTLOOPS, func, !MeOption::quiet)); + CHECK_FATAL(identloops != nullptr, "identloops has problem"); + + LfoFunction *lfoFunc = func->lfoFunc; + + // loop thru all the loops in reverse order so inner loops are processed first + for (int32 i = identloops->meloops.size()-1; i >= 0; i--) { + LoopDesc *aloop = identloops->meloops[i]; + BB *headbb = aloop->head; + // check if the label has associated LfoWhileInfo + if (headbb->bbLabel == 0) { + continue; + } + if (aloop->exitBB == nullptr || aloop->entry == nullptr) { + continue; + } + MapleMap::iterator it = lfoFunc->label2WhileInfo.find(headbb->bbLabel); + if (it == lfoFunc->label2WhileInfo.end()) { + continue; + } + LfoWhileInfo *whileInfo = it->second; + if (whileInfo->injectedIVSym == nullptr) { + continue; + } + MemPool *ivmp = mempoolctrler.NewMemPool(PhaseName().c_str()); + IVCanon ivCanon(ivmp, func, dom, aloop, i, whileInfo); + ivCanon.PerformIVCanon(); + // transfer primary IV info to whileinfo + if (ivCanon.idxPrimaryIV != -1) { + IVDesc *primaryIVDesc = ivCanon.ivvec[ivCanon.idxPrimaryIV]; + CHECK_FATAL(primaryIVDesc->ost->IsSymbol(), "primary IV cannot be preg"); + whileInfo->ivOst = primaryIVDesc->ost; + whileInfo->initExpr = primaryIVDesc->initExpr; + whileInfo->stepValue = primaryIVDesc->stepValue; + whileInfo->tripCount = ivCanon.tripCount; + whileInfo->canConvertDoloop = ivCanon.tripCount != nullptr; + } + mempoolctrler.DeleteMemPool(ivmp); + } + if (DEBUGFUNC(func)) { + LogInfo::MapleLogger() << "\n============== After IV Canonicalization =============" << endl; + irmap->Dump(); + } + + return nullptr; +} + +} // namespace maple diff --git a/mapleall/maple_me/src/lfo_mir_lower.cpp b/mapleall/maple_me/src/lfo_mir_lower.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cc11cde78487c566180ee93d5332abaf179ea70c --- /dev/null +++ b/mapleall/maple_me/src/lfo_mir_lower.cpp @@ -0,0 +1,181 @@ +/* + * 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 "mir_builder.h" +#include "lfo_mir_lower.h" + +using namespace maple; + +// is lowered to : +// label +// brfalse +// +// goto +// label + +BlockNode *LFOMIRLower::LowerWhileStmt(WhileStmtNode *whilestmt) { + MIRBuilder *mirbuilder = mirModule.mirBuilder; +//DoCondVarProp(whilestmt); + whilestmt->body = LowerBlock(whilestmt->body); + BlockNode *blk = mirModule.CurFuncCodeMemPool()->New(); + LabelIdx whilelblidx = func->mirFunc->labelTab->CreateLabel(); + mirModule.CurFunction()->labelTab->AddToStringLabelMap(whilelblidx); + LabelNode *whilelblstmt = mirModule.CurFuncCodeMemPool()->New(); + whilelblstmt->labelIdx = whilelblidx; + LfoWhileInfo *whileInfo = lfoFunc->lfomp->New(); + lfoFunc->SetLabelCreatedByLfo(whilelblidx); + lfoFunc->label2WhileInfo.insert(std::make_pair(whilelblidx, whileInfo)); + blk->AddStatement(whilelblstmt); + CondGotoNode *brfalsestmt = mirModule.CurFuncCodeMemPool()->New(OP_brfalse); + brfalsestmt->uOpnd = whilestmt->uOpnd; + brfalsestmt->srcPosition = whilestmt->srcPosition; + // add jump label target later + blk->AddStatement(brfalsestmt); + + // creaate body + LabelIdx bodylidx = mirModule.CurFunction()->labelTab->CreateLabel(); + CHECK_FATAL(whilestmt->body, "null ptr check"); + blk->AppendStatementsFromBlock(whilestmt->body); + GotoNode *whilegotonode = mirbuilder->CreateStmtGoto(OP_goto, whilelblidx); + blk->AddStatement(whilegotonode); + // create endlabel + LabelIdx endlblidx = mirModule.CurFunction()->labelTab->CreateLabel(); + lfoFunc->SetLabelCreatedByLfo(endlblidx); + mirModule.CurFunction()->labelTab->AddToStringLabelMap(endlblidx); + LabelNode *endlblstmt = mirModule.CurFuncCodeMemPool()->New(); + endlblstmt->labelIdx = endlblidx; + brfalsestmt->offset = endlblidx; + blk->AddStatement(endlblstmt); + return blk; +} + +BlockNode *LFOMIRLower::LowerIfStmt(IfStmtNode *ifstmt, bool recursive) { + bool thenempty = ifstmt->thenPart == nullptr || ifstmt->thenPart->GetFirst() == nullptr; + bool elseempty = ifstmt->elsePart == nullptr || ifstmt->elsePart->GetFirst() == nullptr; + + if (recursive) { + if (!thenempty) { + ifstmt->thenPart = LowerBlock(ifstmt->thenPart); + } + if (!elseempty) { + ifstmt->elsePart = LowerBlock(ifstmt->elsePart); + } + } + + BlockNode *blk = mirModule.CurFuncCodeMemPool()->New(); + MIRFunction *mirFunc = func->mirFunc; + MIRBuilder *mirbuilder = mirModule.mirBuilder; + + if (thenempty && elseempty) { + // generate EVAL statement + UnaryStmtNode *evalstmt = mirModule.CurFuncCodeMemPool()->New(OP_eval); + evalstmt->uOpnd = ifstmt->uOpnd; + evalstmt->srcPosition = ifstmt->srcPosition; + blk->AddStatement(evalstmt); + } else if (elseempty) { + // brfalse + // + // label + CondGotoNode *brfalsestmt = mirModule.CurFuncCodeMemPool()->New(OP_brfalse); + brfalsestmt->uOpnd = ifstmt->uOpnd; + brfalsestmt->srcPosition = ifstmt->srcPosition; + LabelIdx endlabelidx = mirFunc->labelTab->CreateLabel(); + mirFunc->labelTab->AddToStringLabelMap(endlabelidx); + lfoFunc->SetLabelCreatedByLfo(endlabelidx); + LfoIfInfo *ifInfo = lfoFunc->lfomp->New(); + brfalsestmt->offset = endlabelidx; + blk->AddStatement(brfalsestmt); + + blk->AppendStatementsFromBlock(ifstmt->thenPart); + + LabelNode *labstmt = mirModule.CurFuncCodeMemPool()->New(); + labstmt->labelIdx = endlabelidx; + ifInfo->endLabel = endlabelidx; + lfoFunc->label2IfInfo.insert(std::make_pair(endlabelidx, ifInfo)); + blk->AddStatement(labstmt); + } else if (thenempty) { + // brtrue + // + // label + CondGotoNode *brtruestmt = mirModule.CurFuncCodeMemPool()->New(OP_brtrue); + brtruestmt->uOpnd = ifstmt->uOpnd; + brtruestmt->srcPosition = ifstmt->srcPosition; + LabelIdx endlabelidx = mirFunc->labelTab->CreateLabel(); + lfoFunc->SetLabelCreatedByLfo(endlabelidx); + LfoIfInfo *ifInfo = lfoFunc->lfomp->New(); + mirFunc->labelTab->AddToStringLabelMap(endlabelidx); + brtruestmt->offset = endlabelidx; + blk->AddStatement(brtruestmt); + + blk->AppendStatementsFromBlock(ifstmt->elsePart); + + LabelNode *labstmt = mirModule.CurFuncCodeMemPool()->New(); + labstmt->labelIdx = endlabelidx; + ifInfo->endLabel = endlabelidx; + lfoFunc->label2IfInfo.insert(std::make_pair(endlabelidx, ifInfo)); + blk->AddStatement(labstmt); + } else { + // brfalse + // + // goto + // label + // + // label + CondGotoNode *brfalsestmt = mirModule.CurFuncCodeMemPool()->New(OP_brfalse); + brfalsestmt->uOpnd = ifstmt->uOpnd; + brfalsestmt->srcPosition = ifstmt->srcPosition; + LabelIdx elselabelidx = mirFunc->labelTab->CreateLabel(); + mirFunc->labelTab->AddToStringLabelMap(elselabelidx); + lfoFunc->SetLabelCreatedByLfo(elselabelidx); + LfoIfInfo *ifInfo = lfoFunc->lfomp->New(); + brfalsestmt->offset = elselabelidx; + blk->AddStatement(brfalsestmt); + ifInfo->elseLabel = elselabelidx; + lfoFunc->label2IfInfo.insert(std::make_pair(elselabelidx, ifInfo)); + + blk->AppendStatementsFromBlock(ifstmt->thenPart); + bool fallthru_from_then = !BlockNoFallThru(ifstmt->thenPart); + LabelIdx endlabelidx = 0; + + if (fallthru_from_then) { + GotoNode *gotostmt = mirModule.CurFuncCodeMemPool()->New(OP_goto); + endlabelidx = mirFunc->labelTab->CreateLabel(); + mirFunc->labelTab->AddToStringLabelMap(endlabelidx); + lfoFunc->SetLabelCreatedByLfo(endlabelidx); + gotostmt->offset = endlabelidx; + blk->AddStatement(gotostmt); + } + + LabelNode *labstmt = mirModule.CurFuncCodeMemPool()->New(); + labstmt->labelIdx = elselabelidx; + blk->AddStatement(labstmt); + + blk->AppendStatementsFromBlock(ifstmt->elsePart); + + if (fallthru_from_then) { + labstmt = mirModule.CurFuncCodeMemPool()->New(); + labstmt->labelIdx = endlabelidx; + blk->AddStatement(labstmt); + } + if (endlabelidx == 0) { // create end label + endlabelidx = mirbuilder->CreateLabidx(mirFunc); + lfoFunc->SetLabelCreatedByLfo(endlabelidx); + LabelNode *endlabelnode = mirbuilder->CreateStmtLabel(endlabelidx); + blk->AddStatement(endlabelnode); + } + ifInfo->endLabel = endlabelidx; + } + return blk; +} diff --git a/mapleall/maple_me/src/lfo_pre_emit.cpp b/mapleall/maple_me/src/lfo_pre_emit.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6df02d04263abf80e82c4b70d0c86f9bfb55b5c7 --- /dev/null +++ b/mapleall/maple_me/src/lfo_pre_emit.cpp @@ -0,0 +1,715 @@ +/* + * 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 "me_irmap.h" +#include "lfo_mir_nodes.h" +#include "lfo_function.h" +#include "lfo_pre_emit.h" +#include "constant_fold.h" +#include "mir_lower.h" + +namespace maple { + +LfoParentPart *LfoPreEmitter::EmitLfoExpr(MeExpr *meexpr, LfoParentPart *parent) { + switch (meexpr->op) { + case OP_constval: { + LfoConstvalNode *lcvlNode = + codeMP->New(static_cast(meexpr)->constVal, parent); + return lcvlNode; + } + case OP_dread: { + VarMeExpr *varmeexpr = static_cast(meexpr); + MIRSymbol *sym = varmeexpr->ost->GetMIRSymbol(); + LfoDreadNode *ldnode = codeMP->New(varmeexpr->primType, sym->stIdx, varmeexpr->ost->fieldID, parent, varmeexpr); + return ldnode; + } + case OP_eq: + case OP_ne: + case OP_ge: + case OP_gt: + case OP_le: + case OP_cmp: + case OP_cmpl: + case OP_cmpg: + case OP_lt: { + OpMeExpr *cmpNode = static_cast(meexpr); + LfoCompareNode *lnocmpNode = + codeMP->New(meexpr->op, cmpNode->primType, cmpNode->opndType, + nullptr, nullptr, parent); + LfoParentPart *opnd0 = EmitLfoExpr(cmpNode->GetOpnd(0), lnocmpNode); + LfoParentPart *opnd1 = EmitLfoExpr(cmpNode->GetOpnd(1), lnocmpNode); + lnocmpNode->bOpnd[0] = opnd0->Cvt2BaseNode(); + lnocmpNode->bOpnd[1] = opnd1->Cvt2BaseNode(); + lnocmpNode->opndType = cmpNode->opndType; + return lnocmpNode; + } + case OP_array: { + NaryMeExpr *arrExpr = static_cast(meexpr); + LfoArrayNode *lnoarrNode = + codeMP->New(codeMPAlloc, arrExpr->primType, arrExpr->tyIdx, parent); + lnoarrNode->tyIdx = arrExpr->tyIdx; + lnoarrNode->boundsCheck = arrExpr->boundCheck; + for (uint32 i = 0; i < arrExpr->numOpnds; i++) { + LfoParentPart *opnd = EmitLfoExpr(arrExpr->GetOpnd(i), lnoarrNode); + lnoarrNode->nOpnd.push_back(opnd->Cvt2BaseNode()); + } + lnoarrNode->numOpnds = meexpr->numOpnds; + return lnoarrNode; + } + case OP_ashr: + case OP_band: + case OP_bior: + case OP_bxor: + case OP_cand: + case OP_cior: + case OP_div: + case OP_land: + case OP_lior: + case OP_lshr: + case OP_max: + case OP_min: + case OP_mul: + case OP_rem: + case OP_shl: + case OP_sub: + case OP_add: { + OpMeExpr *opExpr = static_cast(meexpr); + LfoBinaryNode *lnobinNode = + codeMP->New(meexpr->op, meexpr->primType, parent); + lnobinNode->bOpnd[0] = EmitLfoExpr(opExpr->GetOpnd(0), lnobinNode)->Cvt2BaseNode(); + lnobinNode->bOpnd[1] = EmitLfoExpr(opExpr->GetOpnd(1), lnobinNode)->Cvt2BaseNode(); + return lnobinNode; + } + case OP_iread: { + IvarMeExpr *ivarExpr = static_cast(meexpr); + LfoIreadNode *lnoirdNode = codeMP->New(meexpr->op, meexpr->primType, parent, ivarExpr); + lnoirdNode->uOpnd = EmitLfoExpr(ivarExpr->base, lnoirdNode)->Cvt2BaseNode(); + lnoirdNode->tyIdx = ivarExpr->tyIdx; + lnoirdNode->fieldID = ivarExpr->fieldID; + return lnoirdNode; + } + case OP_addrof: { + AddrofMeExpr *addrMeexpr = static_cast (meexpr); + OriginalSt *ost = meirmap->ssaTab->GetOriginalStFromid(addrMeexpr->ostIdx); + MIRSymbol *sym = ost->GetMIRSymbol(); + LfoAddrofNode *lnoaddrofNode = codeMP->New(addrMeexpr->primType, sym->stIdx, ost->fieldID, parent); + return lnoaddrofNode; + } + case OP_addroflabel: { + AddroflabelMeExpr *addroflabel = static_cast(meexpr); + LfoAddroflabelNode *lnoaddroflabel = codeMP->New(addroflabel->labelIdx, parent); + lnoaddroflabel->primType = PTY_ptr; + lnoaddroflabel->primType = meexpr->primType; + return lnoaddroflabel; + } + case OP_addroffunc: { + AddroffuncMeExpr *addrMeexpr = static_cast(meexpr); + LfoAddroffuncNode *addrfunNode = codeMP->New(addrMeexpr->primType, addrMeexpr->puIdx, parent); + return addrfunNode; + } + case OP_gcmalloc: + case OP_gcpermalloc: + case OP_stackmalloc: { + GcmallocMeExpr *gcMeexpr = static_cast (meexpr); + LfoGCMallocNode *gcMnode = codeMP->New(meexpr->op, meexpr->primType, gcMeexpr->tyIdx, parent); + gcMnode->tyIdx = gcMeexpr->tyIdx; + return gcMnode; + } + case OP_retype: { + OpMeExpr *opMeexpr = static_cast(meexpr); + LfoRetypeNode *lnoRetNode = codeMP->New(OP_retype, meexpr->primType, parent); + lnoRetNode->fromPrimType = opMeexpr->opndType; + lnoRetNode->tyIdx = opMeexpr->tyIdx; + lnoRetNode->uOpnd = EmitLfoExpr(opMeexpr->GetOpnd(0), lnoRetNode)->Cvt2BaseNode(); + return lnoRetNode; + } + case OP_ceil: + case OP_cvt: + case OP_floor: + case OP_trunc: { + OpMeExpr *opMeexpr = static_cast(meexpr); + LfoTypeCvtNode *tycvtNode = codeMP->New(meexpr->op, meexpr->primType, parent); + tycvtNode->fromPrimType = opMeexpr->opndType; + tycvtNode->uOpnd = EmitLfoExpr(opMeexpr->GetOpnd(0), tycvtNode)->Cvt2BaseNode(); + return tycvtNode; + } + case OP_sext: + case OP_zext: + case OP_extractbits: { + OpMeExpr *opMeexpr = static_cast(meexpr); + LfoExtractbitsNode *extNode = codeMP->New(meexpr->op, meexpr->primType, parent); + extNode->uOpnd = EmitLfoExpr(opMeexpr->GetOpnd(0), extNode)->Cvt2BaseNode(); + extNode->bitsOffset = opMeexpr->bitsOffset; + extNode->bitsSize = opMeexpr->bitsSize; + return extNode; + } + case OP_regread: { + RegMeExpr *regMeexpr = static_cast(meexpr); + LfoRegreadNode *regNode = codeMP->New(parent, regMeexpr); + regNode->primType = regMeexpr->primType; + regNode->regIdx = regMeexpr->GetPregIdx(); + return regNode; + } + case OP_sizeoftype: { + SizeoftypeMeExpr *sizeofMeexpr = static_cast(meexpr); + LfoSizeoftypeNode *sizeofTynode = codeMP->New(sizeofMeexpr->primType, sizeofMeexpr->tyIdx, parent); + return sizeofTynode; + } + case OP_fieldsdist: { + FieldsDistMeExpr *fdMeexpr = static_cast(meexpr); + LfoFieldsDistNode *fieldsNode = codeMP->New( + fdMeexpr->primType, fdMeexpr->GetTyIdx(), fdMeexpr->GetFieldID1(), + fdMeexpr->GetFieldID2(), parent); + return fieldsNode; + } + case OP_conststr: { + ConststrMeExpr *constrMeexpr = static_cast(meexpr); + LfoConststrNode *constrNode = codeMP->New(constrMeexpr->primType, constrMeexpr->strIdx, parent); + return constrNode; + } + case OP_conststr16: { + Conststr16MeExpr *constr16Meexpr = static_cast(meexpr); + LfoConststr16Node *constr16Node = codeMP->New(constr16Meexpr->primType, constr16Meexpr->strIdx, parent); + return constr16Node; + } + case OP_abs: + case OP_bnot: + case OP_lnot: + case OP_neg: + case OP_recip: + case OP_sqrt: + case OP_alloca: + case OP_malloc: { + OpMeExpr *opMeexpr = static_cast(meexpr); + LfoUnaryNode *unNode = codeMP->New(meexpr->op, meexpr->primType, parent); + unNode->uOpnd = EmitLfoExpr(opMeexpr->GetOpnd(0), unNode)->Cvt2BaseNode(); + return unNode; + } + case OP_iaddrof: { + OpMeExpr *opMeexpr = static_cast(meexpr); + LfoIaddrofNode *unNode = codeMP->New(meexpr->op, meexpr->primType, parent); + unNode->uOpnd = EmitLfoExpr(opMeexpr->GetOpnd(0), unNode)->Cvt2BaseNode(); + unNode->tyIdx = opMeexpr->tyIdx; + unNode->fieldID = opMeexpr->fieldID; + return unNode; + } + case OP_select: { + OpMeExpr *opMeexpr = static_cast(meexpr); + LfoTernaryNode *tNode = codeMP->New(OP_select, meexpr->primType, parent); + tNode->topnd[0] = EmitLfoExpr(opMeexpr->GetOpnd(0), tNode)->Cvt2BaseNode(); + tNode->topnd[1] = EmitLfoExpr(opMeexpr->GetOpnd(1), tNode)->Cvt2BaseNode(); + tNode->topnd[2] = EmitLfoExpr(opMeexpr->GetOpnd(2), tNode)->Cvt2BaseNode(); + return tNode; + } + case OP_intrinsicop: + case OP_intrinsicopwithtype: { + NaryMeExpr *nMeexpr = static_cast(meexpr); + LfoIntrinsicopNode *intrnNode = codeMP->New(codeMPAlloc, meexpr->op, meexpr->primType, nMeexpr->tyIdx, parent); + intrnNode->intrinsic = nMeexpr->intrinsic; + for (uint32 i = 0; i < nMeexpr->numOpnds; i++) { + LfoParentPart *opnd = EmitLfoExpr(nMeexpr->GetOpnd(i), intrnNode); + intrnNode->nOpnd.push_back(opnd->Cvt2BaseNode()); + } + intrnNode->numOpnds = nMeexpr->numOpnds; + return intrnNode; + } + default: + CHECK_FATAL(false, "NYI"); + } +} + +StmtNode* LfoPreEmitter::EmitLfoStmt(MeStmt *mestmt, LfoParentPart *parent) { + switch (mestmt->op) { + case OP_dassign: { + DassignMeStmt *dsmestmt = static_cast(mestmt); + LfoDassignNode *dass = codeMP->New(parent, dsmestmt); + MIRSymbol *sym = dsmestmt->lhs->ost->GetMIRSymbol(); + dass->stIdx = sym->stIdx; + dass->fieldID = static_cast(dsmestmt->lhs)->ost->fieldID; + dass->uOpnd= EmitLfoExpr(dsmestmt->rhs, dass)->Cvt2BaseNode(); + dass->srcPosition = dsmestmt->srcPos; + return dass; + } + case OP_regassign: { + AssignMeStmt *asMestmt = static_cast(mestmt); + LfoRegassignNode *lrssnode = codeMP->New(parent, asMestmt); + lrssnode->primType = asMestmt->lhs->primType; + lrssnode->regIdx = asMestmt->GetRegLhs()->GetPregIdx(); + lrssnode->uOpnd= EmitLfoExpr(asMestmt->rhs, lrssnode)->Cvt2BaseNode(); + lrssnode->srcPosition = asMestmt->srcPos; + return lrssnode; + } + case OP_iassign: { + IassignMeStmt *iass = static_cast(mestmt); + LfoIassignNode *lnoIassign = codeMP->New(parent, iass); + lnoIassign->tyIdx = iass->tyIdx; + lnoIassign->fieldID = iass->lhsVar->fieldID; + lnoIassign->addrExpr = EmitLfoExpr(iass->lhsVar->base, lnoIassign)->Cvt2BaseNode(); + lnoIassign->rhs = EmitLfoExpr(iass->rhs, lnoIassign)->Cvt2BaseNode(); + lnoIassign->srcPosition = iass->srcPos; + return lnoIassign; + } + case OP_return: { + RetMeStmt *retMestmt = static_cast(mestmt); + LfoReturnStmtNode *lnoRet = codeMP->New(codeMPAlloc, parent, retMestmt); + for (uint32 i = 0; i < retMestmt->opnds.size(); i++) { + lnoRet->nOpnd.push_back(EmitLfoExpr(retMestmt->opnds[i], lnoRet)->Cvt2BaseNode()); + } + lnoRet->numOpnds = retMestmt->opnds.size(); + lnoRet->srcPosition = retMestmt->srcPos; + return lnoRet; + } + case OP_goto: { + GotoMeStmt *gotoStmt = static_cast(mestmt); + if (lfoFunc->LabelCreatedByLfo(gotoStmt->offset)) { + return NULL; + } + LfoGotoNode *gto = codeMP->New(OP_goto, parent); + gto->offset = gotoStmt->offset; + gto->srcPosition = gotoStmt->srcPos; + return gto; + } + case OP_igoto: { + UnaryMeStmt *igotoMeStmt = static_cast(mestmt); + LfoUnaryStmtNode *igto = codeMP->New(OP_igoto, parent); + igto->uOpnd = EmitLfoExpr(igotoMeStmt->opnd, igto)->Cvt2BaseNode(); + igto->srcPosition = igotoMeStmt->srcPos; + return igto; + } + case OP_comment: { + CommentMeStmt *cmtmeNode = static_cast(mestmt); + CommentNode *cmtNode = codeMP->New(codeMPAlloc); + cmtNode->comment = cmtmeNode->comment; + cmtNode->srcPosition = cmtmeNode->srcPos; + return cmtNode; + } + case OP_call: + case OP_virtualcall: + case OP_virtualicall: + case OP_superclasscall: + case OP_interfacecall: + case OP_interfaceicall: + case OP_customcall: + case OP_callassigned: + case OP_virtualcallassigned: + case OP_virtualicallassigned: + case OP_superclasscallassigned: + case OP_interfacecallassigned: + case OP_interfaceicallassigned: + case OP_customcallassigned: + case OP_polymorphiccall: + case OP_polymorphiccallassigned: { + CallMeStmt *callMeStmt = static_cast(mestmt); + LfoCallNode *callnode = codeMP->New(codeMPAlloc, mestmt->op, parent, callMeStmt); + callnode->puIdx = callMeStmt->puIdx; + callnode->tyIdx = callMeStmt->tyIdx; + callnode->numOpnds = callMeStmt->opnds.size(); + callnode->srcPosition = callMeStmt->srcPos; + mestmt->EmitCallReturnVector(meirmap->mirFunc->meSSATab, &callnode->returnValues); + for (uint32 i = 0; i < callMeStmt->opnds.size(); i++) { + callnode->nOpnd.push_back(EmitLfoExpr(callMeStmt->opnds[i], callnode)->Cvt2BaseNode()); + } + return callnode; + } + case OP_icall: + case OP_icallassigned: { + IcallMeStmt *icallMeStmt = static_cast (mestmt); + LfoIcallNode *icallnode = codeMP->New(codeMPAlloc, OP_icallassigned, icallMeStmt->retTyIdx, parent, icallMeStmt); + for (uint32 i = 0; i < icallMeStmt->opnds.size(); i++) { + icallnode->nOpnd.push_back(EmitLfoExpr(icallMeStmt->opnds[i], icallnode)->Cvt2BaseNode()); + } + icallnode->numOpnds = icallMeStmt->opnds.size(); + icallnode->srcPosition = mestmt->srcPos; + mestmt->EmitCallReturnVector(meirmap->mirFunc->meSSATab, &icallnode->returnValues); + icallnode->retTyIdx = TyIdx(PTY_void); + for (uint32 j = 0; j < icallnode->returnValues.size(); j++) { + CallReturnPair retpair = icallnode->returnValues[j]; + if (!retpair.second.IsReg()) { + StIdx stIdx = retpair.first; + MIRSymbolTable *symtab = mirFunc->symTab; + MIRSymbol *sym = symtab->GetSymbolFromStIdx(stIdx.Idx()); + icallnode->retTyIdx = sym->GetType()->GetTypeIndex(); + } else { + PregIdx pregidx = (PregIdx)retpair.second.pregIdx; + MIRPreg *preg = mirFunc->pregTab->PregFromPregIdx(pregidx); + icallnode->retTyIdx = TyIdx(preg->primType); + } + } + return icallnode; + } + case OP_intrinsiccall: + case OP_xintrinsiccall: + case OP_intrinsiccallassigned: + case OP_xintrinsiccallassigned: + case OP_intrinsiccallwithtype: + case OP_intrinsiccallwithtypeassigned: { + IntrinsiccallMeStmt *callMeStmt = static_cast (mestmt); + LfoIntrinsiccallNode *callnode = codeMP->New(codeMPAlloc, + mestmt->op, callMeStmt->intrinsic, parent, callMeStmt); + callnode->intrinsic = callMeStmt->intrinsic; + callnode->tyIdx = callMeStmt->tyIdx; + for (uint32 i = 0; i < callMeStmt->opnds.size(); i++) { + callnode->nOpnd.push_back(EmitLfoExpr(callMeStmt->opnds[i], callnode)->Cvt2BaseNode()); + } + callnode->numOpnds = callnode->nOpnd.size(); + callnode->srcPosition = mestmt->srcPos; + if (kOpcodeInfo.IsCallAssigned(mestmt->op)) { + mestmt->EmitCallReturnVector(meirmap->mirFunc->meSSATab, &callnode->returnValues); + for (uint32 j = 0; j < callnode->returnValues.size(); j++) { + CallReturnPair retpair = callnode->returnValues[j]; + if (!retpair.second.IsReg()) { + StIdx stIdx = retpair.first; + if (stIdx.Islocal()) { + MIRSymbolTable *symtab = mirFunc->symTab; + MIRSymbol *sym = symtab->GetSymbolFromStIdx(stIdx.Idx()); + } + } + } + } + return callnode; + } + case OP_jscatch: + case OP_finally: + case OP_endtry: + case OP_cleanuptry: + case OP_membaracquire: + case OP_membarrelease: + case OP_membarstorestore: + case OP_membarstoreload: { + LfoStmtNode *lnoStmtNode = codeMP->New(parent, mestmt->op); + lnoStmtNode->srcPosition = mestmt->srcPos; + return lnoStmtNode; + } + case OP_retsub: { + LfoStmtNode * usesStmtNode = codeMP->New(parent, mestmt->op); + usesStmtNode->srcPosition = mestmt->srcPos; + return usesStmtNode; + } + case OP_brfalse: + case OP_brtrue: { + LfoCondGotoNode *lnoCondNode = codeMP->New(mestmt->op, parent); + CondGotoMeStmt *condMeStmt = static_cast (mestmt); + lnoCondNode->offset = condMeStmt->offset; + lnoCondNode->srcPosition = mestmt->srcPos; + lnoCondNode->uOpnd = EmitLfoExpr(condMeStmt->opnd, lnoCondNode)->Cvt2BaseNode(); + return lnoCondNode; + } + case OP_try: + case OP_cpptry: + case OP_javatry: { + TryNode *jvTryNode = codeMP->New(codeMPAlloc, mestmt->op); + TryMeStmt *tryMeStmt = static_cast (mestmt); + uint32 offsetsSize = tryMeStmt->offsets.size(); + jvTryNode->offsets.resize(offsetsSize); + for (uint32 i = 0; i < offsetsSize; i++) { + jvTryNode->offsets[i] = tryMeStmt->offsets[i]; + } + jvTryNode->srcPosition = tryMeStmt->srcPos; + return jvTryNode; + } + case OP_cppcatch: { + CppCatchNode *cppCatchNode = codeMP->New(); + CppCatchMeStmt *catchMestmt = static_cast (mestmt); + cppCatchNode->exceptionTyIdx = catchMestmt->exceptionTyIdx; + cppCatchNode->srcPosition = catchMestmt->srcPos; + return cppCatchNode; + } + case OP_catch: + case OP_javacatch: { + CatchNode *jvCatchNode = codeMP->New(codeMPAlloc); + JavaCatchMeStmt *catchMestmt = static_cast (mestmt); + jvCatchNode->exceptionTyIdxVec = catchMestmt->exceptionTyIdxVec; + jvCatchNode->srcPosition = catchMestmt->srcPos; + return jvCatchNode; + } + case OP_throw: { + LfoUnaryStmtNode *throwStmt = codeMP->New(mestmt->op, parent); + ThrowMeStmt *throwMeStmt = static_cast(mestmt); + throwStmt->uOpnd = EmitLfoExpr(throwMeStmt->opnd, throwStmt)->Cvt2BaseNode(); + throwStmt->srcPosition = throwMeStmt->srcPos; + return throwStmt; + } + case OP_assertnonnull: + case OP_eval: + case OP_free: { + LfoUnaryStmtNode *unaryStmt = codeMP->New(mestmt->op, parent); + UnaryMeStmt *uMeStmt = static_cast(mestmt); + unaryStmt->uOpnd = EmitLfoExpr(uMeStmt->opnd, unaryStmt)->Cvt2BaseNode(); + unaryStmt->srcPosition = uMeStmt->srcPos; + return unaryStmt; + } + case OP_switch: { + LfoSwitchNode *switchNode = codeMP->New(codeMPAlloc, parent); + SwitchMeStmt *meSwitch = static_cast(mestmt); + switchNode->switchOpnd = EmitLfoExpr(meSwitch->opnd, switchNode)->Cvt2BaseNode(); + switchNode->defaultLabel = meSwitch->defaultLabel; + switchNode->switchTable = meSwitch->switchTable; + switchNode->srcPosition = meSwitch->srcPos; + return switchNode; + } + default: + CHECK_FATAL(false, "nyi"); + } +} + +void LfoPreEmitter::EmitBB(BB *bb, LfoBlockNode *curblk) { + CHECK_FATAL(curblk != nullptr, "null ptr check"); + // emit head. label + LabelIdx labidx = bb->bbLabel; + if (labidx != 0 && !lfoFunc->LabelCreatedByLfo(labidx)) { + // not a empty bb + LabelNode *lbnode = codeMP->New(); + lbnode->labelIdx = labidx; + curblk->AddStatement(lbnode); + } + for (auto mestmt : bb->meStmtList) { + StmtNode *stmt = EmitLfoStmt(mestmt, curblk); + if (!stmt) // can be null i.e, a goto to a label that was created by lno lower + continue; + curblk->AddStatement(stmt); + } + if (bb->IsEndTry()) { + /* generate op_endtry */ + StmtNode *endtry = codeMP->New(OP_endtry); + curblk->AddStatement(endtry); + } +} + +DoloopNode *LfoPreEmitter::EmitLfoDoloop(BB *mewhilebb, LfoBlockNode *curblk, LfoWhileInfo *whileInfo) { + LabelIdx labidx = mewhilebb->bbLabel; + MeStmt *lastmestmt = mewhilebb->meStmtList.last; + CHECK_FATAL(lastmestmt->prev == nullptr || dynamic_cast(lastmestmt->prev) == nullptr, + "EmitLfoWhile: there are other statements at while header bb"); + LfoDoloopNode *lnoDoloopnode = codeMP->New(curblk); + lnoDoloopnode->doVarStIdx = whileInfo->ivOst->GetMIRSymbol()->stIdx; + CondGotoMeStmt *condGotostmt = static_cast(lastmestmt); + lnoDoloopnode->startExpr = EmitLfoExpr(whileInfo->initExpr, lnoDoloopnode)->Cvt2BaseNode(); + lnoDoloopnode->condExpr = EmitLfoExpr(condGotostmt->opnd, lnoDoloopnode)->Cvt2BaseNode(); + lnoDoloopnode->doBody = codeMP->New(lnoDoloopnode); + MIRIntConst *intConst = mirFunc->dataMemPool->New(whileInfo->stepValue, whileInfo->ivOst->GetType()); + LfoConstvalNode *lfoconstnode = codeMP->New(intConst, lnoDoloopnode); + lnoDoloopnode->incrExpr = lfoconstnode; + lnoDoloopnode->isPreg = false; + curblk->AddStatement(lnoDoloopnode); + return lnoDoloopnode; +} + +WhileStmtNode *LfoPreEmitter::EmitLfoWhile(BB *meWhilebb, LfoBlockNode *curblk) { + LabelIdx labidx = meWhilebb->bbLabel; + MeStmt *lastmestmt = meWhilebb->meStmtList.last; + CHECK_FATAL(lastmestmt->prev == nullptr || dynamic_cast(lastmestmt->prev) == nullptr, + "EmitLfoWhile: there are other statements at while header bb"); + LfoWhileStmtNode *lnoWhilestmt = codeMP->New(curblk); + CondGotoMeStmt *condGotostmt = static_cast(lastmestmt); + lnoWhilestmt->uOpnd = EmitLfoExpr(condGotostmt->opnd, lnoWhilestmt)->Cvt2BaseNode(); + lnoWhilestmt->body = codeMP->New(lnoWhilestmt); + curblk->AddStatement(lnoWhilestmt); + return lnoWhilestmt; +} + +uint32 LfoPreEmitter::Raise2LfoWhile(uint32 curj, LfoBlockNode *curblk) { + MapleVector &bbvec = cfg->bbVec; + BB *curbb = bbvec[curj]; + LabelIdx whilelabidx = curbb->bbLabel; + LfoWhileInfo *whileInfo = lfoFunc->label2WhileInfo[whilelabidx]; + + // find the end label bb + BB *suc0 = curbb->succ[0]; + BB *suc1 = curbb->succ[1]; + MeStmt *laststmt = curbb->meStmtList.last; + CHECK_FATAL(laststmt->op == OP_brfalse, "Riase2LfoWhile: NYI"); + CondGotoMeStmt *condgotomestmt = static_cast(laststmt); + BB *endlblbb = condgotomestmt->offset == suc1->bbLabel ? suc1 : suc0; + BB *firstWhilebb = condgotomestmt->offset == suc1->bbLabel ? suc0 : suc1; + LfoBlockNode *lfoDobody = nullptr; + if (whileInfo->canConvertDoloop) { // emit doloop + DoloopNode *doloopnode = EmitLfoDoloop(curbb, curblk, whileInfo); + ++curj; + lfoDobody = static_cast(doloopnode->doBody); + } else { // emit while loop + WhileStmtNode *whileNode = EmitLfoWhile(curbb, curblk); + ++curj; + lfoDobody = static_cast (whileNode->body); + } + // emit loop body + while (bbvec[curj]->id != endlblbb->id) { + curj = EmitLfoBB(curj, lfoDobody); + while (bbvec[curj] == nullptr) { + curj++; + } + } + if (whileInfo->canConvertDoloop) { // delete the increment statement + StmtNode *bodylaststmt = lfoDobody->GetLast(); + CHECK_FATAL(bodylaststmt->op == OP_dassign, "Raise2LfoWhile: cannot find increment stmt"); + DassignNode *dassnode = static_cast(bodylaststmt); + CHECK_FATAL(dassnode->stIdx == whileInfo->ivOst->GetMIRSymbol()->stIdx, + "Raise2LfoWhile: cannot find IV increment"); + lfoDobody->RemoveStmt(dassnode); + } + return curj; +} + +uint32 LfoPreEmitter::Raise2LfoIf(uint32 curj, LfoBlockNode *curblk) { + MapleVector &bbvec = cfg->bbVec; + BB *curbb = bbvec[curj]; + // emit BB contents before the if statement + LabelIdx labidx = curbb->bbLabel; + if (labidx != 0 && !lfoFunc->LabelCreatedByLfo(labidx)) { + LabelNode *lbnode = mirFunc->codeMemPool->New(); + lbnode->labelIdx = labidx; + curblk->AddStatement(lbnode); + } + MeStmt *mestmt = curbb->meStmtList.first; + while (mestmt->op != OP_brfalse && mestmt->op != OP_brtrue) { + StmtNode *stmt = EmitLfoStmt(mestmt, curblk); + curblk->AddStatement(stmt); + mestmt = mestmt->next; + } + // emit the if statement + CHECK_FATAL(mestmt != nullptr && (mestmt->op == OP_brfalse || mestmt->op == OP_brtrue), "Raise2LfoIf: cannot find conditional branch"); + CondGotoMeStmt *condgoto = static_cast (mestmt); + LfoIfInfo *ifInfo = lfoFunc->label2IfInfo[condgoto->offset]; + CHECK_FATAL(ifInfo->endLabel != 0, "Raise2LfoIf: endLabel not found"); + LfoIfStmtNode *lnoIfstmtNode = mirFunc->codeMemPool->New(curblk); + LfoParentPart *condnode = EmitLfoExpr(condgoto->opnd, lnoIfstmtNode); + lnoIfstmtNode->uOpnd = condnode->Cvt2BaseNode(); + curblk->AddStatement(lnoIfstmtNode); + if (ifInfo->elseLabel != 0) { // both else and then are not empty; + LfoBlockNode *elseBlk = codeMP->New(lnoIfstmtNode); + LfoBlockNode *thenBlk = codeMP->New(lnoIfstmtNode); + lnoIfstmtNode->thenPart = thenBlk; + lnoIfstmtNode->elsePart = elseBlk; + BB *elsemebb = cfg->labelBBIdMap[ifInfo->elseLabel]; + BB *endmebb = cfg->labelBBIdMap[ifInfo->endLabel]; + CHECK_FATAL(elsemebb, "Raise2LfoIf: cannot find else BB"); + CHECK_FATAL(endmebb, "Raise2LfoIf: cannot find BB at end of IF"); + // emit then branch; + uint32 j = curj + 1; + while (j != elsemebb->id.idx) { + j = EmitLfoBB(j, thenBlk); + } + CHECK_FATAL(j < bbvec.size(), ""); + while (j != endmebb->id.idx) { + j = EmitLfoBB(j, elseBlk); + } + CHECK_FATAL(j < bbvec.size(), ""); + return j; + } else { // there is only then or else part in this if stmt + LfoBlockNode *branchBlock = codeMP->New(lnoIfstmtNode); + LfoBlockNode *emptyBlock = codeMP->New(lnoIfstmtNode); + if (condgoto->op == OP_brtrue) { + lnoIfstmtNode->elsePart = branchBlock; + lnoIfstmtNode->thenPart = emptyBlock; + } else { + lnoIfstmtNode->thenPart = branchBlock; + lnoIfstmtNode->elsePart = emptyBlock; + } + BB *endmebb = cfg->labelBBIdMap[ifInfo->endLabel]; + uint32 j = curj + 1; + while (j != endmebb->id.idx) { + j = EmitLfoBB(j, branchBlock); + } + CHECK_FATAL(j < bbvec.size(), ""); + return j; + } +} + +uint32 LfoPreEmitter::EmitLfoBB(uint32 curj, LfoBlockNode *curblk) { + MapleVector &bbvec = cfg->bbVec; + BB *mebb = bbvec[curj]; + if (!mebb || mebb == cfg->commonEntryBB || mebb == cfg->commonExitBB) { + return curj + 1; + } + if (mebb->bbLabel != 0) { + MapleMap::iterator it = lfoFunc->label2WhileInfo.find(mebb->bbLabel); + if (it != lfoFunc->label2WhileInfo.end()) { + if (mebb->succ.size() == 2) { + curj = Raise2LfoWhile(curj, curblk); + return curj; + } else { + lfoFunc->lfoCreatedLabelSet.erase(mebb->bbLabel); + } + } + } + if (!mebb->meStmtList.empty() && + (mebb->meStmtList.last->op == OP_brfalse || + mebb->meStmtList.last->op == OP_brtrue)) { + CondGotoMeStmt *condgoto = static_cast(mebb->meStmtList.last); + MapleMap::iterator it = lfoFunc->label2IfInfo.find(condgoto->offset); + if (it != lfoFunc->label2IfInfo.end()) { + curj = Raise2LfoIf(curj, curblk); + return curj; + } + } + EmitBB(mebb, curblk); + return ++curj; +} + +AnalysisResult *DoLfoPreEmission::Run(MeFunction *func, MeFuncResultMgr *m) { + if (func->theCFG->NumBBs() == 0) { + func->isLfo = false; + return nullptr; + } + MeIRMap *hmap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func)); + ASSERT(hmap != nullptr, "irmapbuild has problem"); + MIRFunction *mirfunction = func->mirFunc; + if (mirfunction->codeMemPool != nullptr) { + mempoolctrler.DeleteMemPool(mirfunction->codeMemPool); + } + mirfunction->codeMemPool = mempoolctrler.NewMemPool("IR from IRMap::Emit()"); + mirfunction->codeMemPoolAllocator.SetMemPool(mirfunction->codeMemPool); +#if 0 + mirfunction->body = mirfunction->codeMemPool->New(); + for (uint32 i = 0; i < func->theCFG->bbVec.size(); i++) { + BB *bb = func->theCFG->bbVec[i]; + if (bb == nullptr) { + continue; + } + bb->EmitBB(func->meSSATab, func->mirFunc->body, func->mirFunc->freqMap, true); + } +#else + LfoPreEmitter emitter(hmap, func->lfoFunc); + LfoBlockNode *curblk = func->mirFunc->codeMemPool->New(nullptr); + mirfunction->body = curblk; + uint32 i = 0; + while (i < func->theCFG->bbVec.size()) { + i = emitter.EmitLfoBB(i, curblk); + } +#endif + + m->InvalidAllResults(); + func->meSSATab = nullptr; + func->irMap = nullptr; + func->isLfo = false; + + maple::ConstantFold cf(&func->mirModule); + cf.Simplify(func->mirFunc->body); + + if (DEBUGFUNC(func)) { + LogInfo::MapleLogger() << "\n**** After lfopreemit phase ****\n"; + mirfunction->Dump(false); + } + +#if 1 // use this only if directly feeding to mainopt + MIRLower mirlowerer(func->mirModule, mirfunction); + mirlowerer.SetLowerME(); + mirlowerer.SetLowerExpandArray(); + mirlowerer.LowerFunc(mirfunction); +#endif + + return nullptr; +} + +} // namespace maple diff --git a/mapleall/maple_me/src/me_alias_class.cpp b/mapleall/maple_me/src/me_alias_class.cpp index 23d9a0313381843039f8cd72e438f301ead6089c..ff9f754dbb8353619379ae7b7543875ad3b36e9f 100644 --- a/mapleall/maple_me/src/me_alias_class.cpp +++ b/mapleall/maple_me/src/me_alias_class.cpp @@ -20,6 +20,7 @@ #include "ssa_mir_nodes.h" #include "ssa_tab.h" #include "me_function.h" +#include "me_cfg.h" #include "mpl_timer.h" using namespace std; @@ -37,7 +38,7 @@ void MeAliasClass::PerformAliasClass() { if (DEBUGFUNC(func)) { LogInfo::MapleLogger() << "\n============ Alias Classification Pass 1 ============" << endl; } - for (BB *bb : func->bbVec) { + for (BB *bb : func->theCFG->bbVec) { if (bb == nullptr) { continue; } @@ -77,7 +78,7 @@ void MeAliasClass::PerformAliasClass() { if (DEBUGFUNC(func)) { LogInfo::MapleLogger() << "\n============ Alias Classification Pass 2 ============" << endl; } - for (BB *bb : func->bbVec) { + for (BB *bb : func->theCFG->bbVec) { if (bb == nullptr) { continue; } @@ -92,11 +93,17 @@ void MeAliasClass::PerformAliasClass() { } AnalysisResult *MeDoAliasClass::Run(MeFunction *func, MeFuncResultMgr *m, ModuleResultMgr *mrm) { - SSATab *ssaTab = static_cast(m->GetAnalysisResult(MeFuncPhase_SSATAB, func)); + moduleResultMgr = mrm; // later it can be called with only first 2 parameters + + MirCFG *cfg = static_cast(m->GetAnalysisResult(MeFuncPhase_CFGBUILD, func, !MeOption::quiet)); + SSATab *ssaTab = static_cast(m->GetAnalysisResult(MeFuncPhase_SSATAB, func, !MeOption::quiet)); ASSERT(ssaTab != nullptr, "ssatbb phase has problem"); MemPool *aliasclassmp = mempoolctrler.NewMemPool(PhaseName().c_str()); - KlassHierarchy *kh = static_cast(mrm->GetAnalysisResult(MoPhase_CHA, &func->mirModule)); + KlassHierarchy *kh = nullptr; + if (func->mirModule.IsJavaModule()) { + kh = static_cast(mrm->GetAnalysisResult(MoPhase_CHA, &func->mirModule, !MeOption::quiet)); + } MeAliasClass *aliasclass = aliasclassmp->New( aliasclassmp, &func->mirModule, func->meSSATab, func, MeOption::lessThrowAlias, MeOption::finalFieldAlias, diff --git a/mapleall/maple_me/src/me_analyzerc.cpp b/mapleall/maple_me/src/me_analyzerc.cpp index 2fc2d89e601683546d613ae5c45ec18c633980d5..f37b8a92b66c724ccb1294fc9a1117575cd45ba9 100644 --- a/mapleall/maple_me/src/me_analyzerc.cpp +++ b/mapleall/maple_me/src/me_analyzerc.cpp @@ -100,7 +100,7 @@ RCItem *AnalyzeRC::FindOrCreateRCItem(OriginalSt *ost) { RCItem *rci = analyzercMp->New(ost, &analyzercAllocator); rcitemsmap[ost->index] = rci; if (ost->indexRenamedFrom.idx != 0) { // change to use the original ost - ost = ssaTab->GetSymbolOriginalStFromid(ost->indexRenamedFrom); + ost = ssaTab->GetOriginalStFromid(ost->indexRenamedFrom); } if (ost->index.idx >= aliasclass->osym2Elem.size()) { rci->noalias = true; @@ -146,7 +146,7 @@ bool AnalyzeRC::NeedIncref(MeStmt *stmt) { // identify assignments to ref pointers and insert decref before it and incref // after it void AnalyzeRC::IdentifyRCStmts() { - for (BB *bb : func->bbVec) { + for (BB *bb : func->theCFG->bbVec) { if (bb == nullptr) { continue; } @@ -227,7 +227,7 @@ void AnalyzeRC::InsertEntryIncrefs4Formals() { formalOstVec.push_back(ost); FindOrCreateRCItem(ost); MeStmt *dass = CreateIncrefZeroVersion(ost); - dass->bb = func->first_bb_; + dass->bb = func->theCFG->first_bb; dass->bb->AddMeStmtFirst(dass); } } @@ -244,7 +244,7 @@ void AnalyzeRC::InsertEntryIncrefs4Formals() { return; } // insert decref for the formals at each return - for (BB *bb : func->commonExitBB->pred) { + for (BB *bb : func->theCFG->commonExitBB->pred) { MeStmt *lastMeStmt = bb->meStmtList.last; if (lastMeStmt == nullptr || lastMeStmt->op != OP_return) { continue; @@ -257,7 +257,7 @@ void AnalyzeRC::InsertEntryIncrefs4Formals() { } void AnalyzeRC::CreateCleanupIntrinsics() { - for (BB *bb : func->commonExitBB->pred) { + for (BB *bb : func->theCFG->commonExitBB->pred) { MeStmt *lastMeStmt = bb->meStmtList.last; if (lastMeStmt && lastMeStmt->op == OP_return) { IntrinsiccallMeStmt *intrn = irMap->NewInPool(OP_intrinsiccall, INTRN_MPL_CLEANUP_LOCALREFVARS); @@ -336,7 +336,7 @@ void AnalyzeRC::RenameRefPtrs(BB *bb) { MapleSet *domChildren = &dominance->domChildren[bb->id.idx]; for (MapleSet::iterator bbit = domChildren->begin(); bbit != domChildren->end(); bbit++) { BBId childbbid = *bbit; - RenameRefPtrs(func->bbVec[childbbid.idx]); + RenameRefPtrs(func->theCFG->bbVec[childbbid.idx]); } // restore the stacks to their size at entry to this function invocation @@ -377,9 +377,9 @@ void AnalyzeRC::InsertInitAtPUEntry(RCItem *rci) { } else { dass = CreateDassignInit(rci->ost->index); } - dass->bb = func->first_bb_; + dass->bb = func->theCFG->first_bb; dass->bb->AddMeStmtFirst(dass); - rci->occurBBs.insert(func->first_bb_->id); + rci->occurBBs.insert(func->theCFG->first_bb->id); } void AnalyzeRC::CollectLocalRefPointerUses(MeExpr *x, BBId bbid) { @@ -469,7 +469,7 @@ void AnalyzeRC::RenameDecrefsBeforeExit(BB *bb) { MapleSet *domChildren = &dominance->domChildren[bb->id.idx]; for (MapleSet::iterator bbit = domChildren->begin(); bbit != domChildren->end(); bbit++) { BBId childbbid = *bbit; - RenameDecrefsBeforeExit(func->bbVec[childbbid.idx]); + RenameDecrefsBeforeExit(func->theCFG->bbVec[childbbid.idx]); } // restore the stacks to their size at entry to this function invocation @@ -538,7 +538,7 @@ static bool BBHasCall(BB *bb) { } void AnalyzeRC::OptimizeRC() { - for (BB *bb : func->bbVec) { + for (BB *bb : func->theCFG->bbVec) { if (bb == nullptr) { continue; } @@ -639,7 +639,7 @@ void AnalyzeRC::OptimizeRC() { } placeopt.ComputePlacement(&rci->occurBBs); for (BBId bbid : placeopt.inserted_bbs) { - BB *insertedbb = func->bbVec[bbid.idx]; + BB *insertedbb = func->theCFG->bbVec[bbid.idx]; MeStmt *insertedLast = insertedbb->meStmtList.last; if (insertedbb->succ.size() == 0 && insertedLast && insertedLast->op == OP_return && !BBHasCall(insertedbb)) { @@ -669,7 +669,7 @@ void AnalyzeRC::OptimizeRC() { } } for (BBId bbid : placeopt.lastuse_bbs) { - BB *lastusebb = func->bbVec[bbid.idx]; + BB *lastusebb = func->theCFG->bbVec[bbid.idx]; MeStmt *lastStmt = lastusebb->meStmtList.last; if (lastusebb->succ.empty() && lastStmt && lastStmt->op == OP_throw) { continue; // decref before exit not needed if exitting via throw @@ -712,7 +712,7 @@ void AnalyzeRC::OptimizeRC() { } } } - RenameDecrefsBeforeExit(func->commonEntryBB); + RenameDecrefsBeforeExit(func->theCFG->commonEntryBB); } // among the arguments in the intrinsiccall to INTRN_CLEANUP_LOCALREFVARS, those @@ -722,7 +722,7 @@ void AnalyzeRC::OptimizeRC() { // whether it is zero version or not, because it always has incref inserted // at function entry. void AnalyzeRC::RemoveUnneededCleanups() { - for (BB *bb : func->commonExitBB->pred) { + for (BB *bb : func->theCFG->commonExitBB->pred) { MeStmt *lastMeStmt = bb->meStmtList.last; if (lastMeStmt == nullptr || lastMeStmt->op != OP_return) { continue; @@ -767,15 +767,15 @@ void AnalyzeRC::RemoveUnneededCleanups() { } AnalysisResult *MeDoAnalyzeRC::Run(MeFunction *func, MeFuncResultMgr *m) { - Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); + MeIRMap *hmap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func, !MeOption::quiet)); + ASSERT(hmap != nullptr, "irmapbuild phase has problem"); + + Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func, !MeOption::quiet)); ASSERT(dom != nullptr, "dominance phase has problem"); - AliasClass *aliasclass = static_cast(m->GetAnalysisResult(MeFuncPhase_ALIASCLASS, func)); + AliasClass *aliasclass = static_cast(m->GetAnalysisResult(MeFuncPhase_ALIASCLASS, func, !MeOption::quiet)); ASSERT(aliasclass != nullptr, "aliasclass phase has problem"); - MeIRMap *hmap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func)); - ASSERT(hmap != nullptr, "hssamap has problem"); - MIRFunction *mirfunction = func->mirFunc; func->mirModule.hints = kRcAnalyzed; @@ -802,7 +802,7 @@ AnalysisResult *MeDoAnalyzeRC::Run(MeFunction *func, MeFuncResultMgr *m) { if (!analyzerc.skip_localrefvars) { analyzerc.CreateCleanupIntrinsics(); } - analyzerc.RenameRefPtrs(func->commonEntryBB); + analyzerc.RenameRefPtrs(func->theCFG->commonEntryBB); if (MeOption::optLevel > 0 && !analyzerc.skip_localrefvars) { analyzerc.RemoveUnneededCleanups(); } @@ -817,13 +817,19 @@ AnalysisResult *MeDoAnalyzeRC::Run(MeFunction *func, MeFuncResultMgr *m) { } // end of analyzerc's scope if (!MeOption::nodelegaterc && !func->placementRCOn && MeOption::rcLowering && MeOption::optLevel > 0) { - m->GetAnalysisResult(MeFuncPhase_DELEGATERC, func); + MeDoDelegateRC dodelegaterc(MeFuncPhase_DELEGATERC); + if (!MeOption::quiet) { + LogInfo::MapleLogger() << " == " << PhaseName() << " invokes [ " << dodelegaterc.PhaseName() << " ] ==\n"; + } + dodelegaterc.Run(func, m); } if (!MeOption::nocondbasedrc && MeOption::rcLowering && MeOption::optLevel > 0) { MeDoCondBasedRC docondbasedrc(MeFuncPhase_CONDBASEDRC); + if (!MeOption::quiet) { + LogInfo::MapleLogger() << " == " << PhaseName() << " invokes [ " << docondbasedrc.PhaseName() << " ] ==\n"; + } docondbasedrc.Run(func, m); -// m->GetAnalysisResult(MeFuncPhase_CONDBASEDRC, func); } return nullptr; diff --git a/mapleall/maple_me/src/me_bb_layout.cpp b/mapleall/maple_me/src/me_bb_layout.cpp index bddd25cd05fbc9c91c9b56be6acaaa2559fb2a8c..7af14a744cc927d93f69efa794076e789ffe91c8 100644 --- a/mapleall/maple_me/src/me_bb_layout.cpp +++ b/mapleall/maple_me/src/me_bb_layout.cpp @@ -444,8 +444,8 @@ AnalysisResult *MeDoBBLayout::Run(MeFunction *func, MeFuncResultMgr *m) { BBLayout *bblayout = layoutMp->New(layoutMp, func); // assume commonEntryBB is always bb 0 - CHECK_FATAL(func->bbVec[0] == func->commonEntryBB, "assume bb[0] is the commont entry bb"); - BB *bb = func->first_bb_; + CHECK_FATAL(func->theCFG->bbVec[0] == func->theCFG->commonEntryBB, "assume bb[0] is the commont entry bb"); + BB *bb = func->theCFG->first_bb; while (bb != nullptr) { bblayout->AddBB(bb); if (bb->kind == kBBCondGoto || bb->kind == kBBGoto) { @@ -465,7 +465,7 @@ AnalysisResult *MeDoBBLayout::Run(MeFunction *func, MeFuncResultMgr *m) { CHECK_FATAL(!(isJavatry && bblayout->tryOutstanding), "cannot emit another javatry if last javatry has not been ended"); if (nextbb->isTryEnd) { - BB *trybb = func->endTryBB2TryBB[nextbb]; + BB *trybb = func->theCFG->endTryBB2TryBB[nextbb]; CHECK_FATAL(trybb == nextbb || bblayout->laidOut[trybb->id.idx], "cannot emit endtry bb before its corresponding try bb"); } diff --git a/mapleall/maple_me/src/me_bdc_opt.cpp b/mapleall/maple_me/src/me_bdc_opt.cpp index 7dd9408c6de8c194842fa7ce349a4b17361ede82..5d4f30904587669413f3da5d29948428afce9bac 100644 --- a/mapleall/maple_me/src/me_bdc_opt.cpp +++ b/mapleall/maple_me/src/me_bdc_opt.cpp @@ -515,7 +515,7 @@ bool MeBDC::AnalyzeExitCondGoto(LoopDesc *mploop, ScalarMeExpr *meexpr, const BB CHECK_FATAL(bb->id.idx < dom->pdomFrontier.size(), "out of range in MeBDC::AnalyzeExitCondGoto"); MapleSet *pdomfrt = &dom->pdomFrontier[bb->id.idx]; for (MapleSet::iterator it = pdomfrt->begin(); it != pdomfrt->end(); it++) { - BB *cdbb = mefunc->bbVec[it->idx]; + BB *cdbb = mefunc->theCFG->bbVec[it->idx]; if (!mploop->Has(cdbb)) { continue; } @@ -592,7 +592,7 @@ void MeBDC::DoBdcForLoop(LoopDesc *mploop) { MapleSet &loopbbs = mploop->loop_bbs; std::vector> arrayvec; for (MapleSet::iterator stit = loopbbs.begin(); stit != loopbbs.end(); stit++) { - BB *bb = mefunc->bbVec[stit->idx]; + BB *bb = mefunc->theCFG->bbVec[stit->idx]; for (auto mestmt : bb->meStmtList) { for (int32 iii = 0; iii < mestmt->NumMeStmtOpnds(); iii++) { MeExpr *meexpr = mestmt->GetMeStmtOpnd(iii); @@ -985,7 +985,7 @@ bool MeBDC::AnalyzeABDCByCondArrayExpr(BB *bb, NaryMeExpr *arrayexpr) { uint32 sizeofbb = dom->bbVec.size(); std::vector visitedmap(sizeofbb, false); while (pdomfrt->size() == 1) { - BB *cdbb = mefunc->bbVec[(pdomfrt->begin())->idx]; + BB *cdbb = mefunc->theCFG->bbVec[(pdomfrt->begin())->idx]; if (visitedmap[cdbb->id.idx]) { break; } @@ -1089,7 +1089,7 @@ void MeBDC::DoIt() { // do #2 - #4 // first collect all the array expr std::vector> arrayvec; - for (BB *bb : mefunc->bbVec) { + for (BB *bb : mefunc->theCFG->bbVec) { if (!bb) { continue; } @@ -1119,11 +1119,11 @@ AnalysisResult *MeDoBDCOpt::Run(MeFunction *func, MeFuncResultMgr *frm, ModuleRe if (func->secondPass) { return nullptr; } - Dominance *dom = static_cast(frm->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); + Dominance *dom = static_cast(frm->GetAnalysisResult(MeFuncPhase_DOMINANCE, func, !MeOption::quiet)); ASSERT(dom, "dominance phase has problem"); - MeIRMap *hmap = static_cast(frm->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func)); + MeIRMap *hmap = static_cast(frm->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func, !MeOption::quiet)); ASSERT(hmap, "hssamap has problem"); - IdentifyLoops *meloop = static_cast(frm->GetAnalysisResult(MeFuncPhase_MELOOP, func)); + IdentifyLoops *meloop = static_cast(frm->GetAnalysisResult(MeFuncPhase_IDENTLOOPS, func, !MeOption::quiet)); CHECK_FATAL(meloop, "meloop has problem"); MemPool *dobdcoptmp = mempoolctrler.NewMemPool(PhaseName().c_str()); MeBDC *mebdc = dobdcoptmp->New(func, meloop); diff --git a/mapleall/maple_me/src/me_cfg.cpp b/mapleall/maple_me/src/me_cfg.cpp index d6af5fa79ab439dafc3aec86888a4cb6616e2115..f707e165d9b5e8222c8108341aee24b8f3dbe14d 100644 --- a/mapleall/maple_me/src/me_cfg.cpp +++ b/mapleall/maple_me/src/me_cfg.cpp @@ -23,11 +23,53 @@ #include #include "name_mangler.h" #include +#include "me_loop_canon.h" +#include "me_critical_edge.h" using namespace std; namespace maple { +/* get next bb in bbVec*/ +BB *MirCFG::NextBB(const BB *bb) { + if (bb->id.idx == bbVec.size() - 1) { + return nullptr; + } + uint32 i = bb->id.idx + 1; + for (; i < bbVec.size(); i++) { + if (bbVec[i] != nullptr) { + return bbVec[i]; + } + } + return nullptr; +} + +/* get prev bb in bbVec*/ +BB *MirCFG::PrevBB(const BB *bb) { + if (bb->id.idx == 0) { + return nullptr; + } + int32 i = bb->id.idx - 1; + for (; i >= 0; i--) { + if (bbVec[i] != nullptr) { + return bbVec[i]; + } + } + return nullptr; +} + +void MirCFG::DeleteBasicBlock(const BB *bb) { + ASSERT(bbVec[bb->id.idx] == bb, ""); + /* update first_bb_ and last_bb if needed */ + if (first_bb == bb) { + first_bb = NextBB(bb); + } else if (last_bb == bb) { + last_bb = PrevBB(bb); + } + bbVec[bb->id.idx] = nullptr; + return; +} + // determine if need to be replaced by assertnonnull bool MirCFG::IfReplaceWithAssertnonnull(BB *bb) { StmtNode *stmt = bb->stmtNodeList.first; @@ -87,12 +129,12 @@ bool MirCFG::IfReplaceWithAssertnonnull(BB *bb) { } void MirCFG::BuildMirCFG() { - MapleVector entryblocks(func->alloc.Adapter()); - MapleVector exitblocks(func->alloc.Adapter()); + std::vector entryblocks; + std::vector exitblocks;; // bbVec[0,1] are common entry/exit bb - for (uint32 i = func->commonExitBB->id.idx + 1; i < func->bbVec.size(); i++) { - BB *bb = func->bbVec[i]; + for (uint32 i = commonExitBB->id.idx + 1; i < bbVec.size(); i++) { + BB *bb = bbVec[i]; if (bb == nullptr) { continue; } @@ -111,7 +153,7 @@ void MirCFG::BuildMirCFG() { CHECK_FATAL(lastStmt->op == OP_goto, ""); GotoNode *gotostmt = static_cast(lastStmt); LabelIdx lblidx = (LabelIdx)gotostmt->offset; - BB *meBb = func->labelBBIdMap[lblidx]; + BB *meBb = labelBBIdMap[lblidx]; bb->succ.push_back(meBb); meBb->pred.push_back(bb); break; @@ -120,14 +162,14 @@ void MirCFG::BuildMirCFG() { StmtNode *laststmt = bb->stmtNodeList.last; CHECK_FATAL(laststmt->IsCondBr(), ""); /* succ[0] is fallthru, succ[1] is gotobb */ - BB *rightnextbb = func->NextBB(bb); + BB *rightnextbb = NextBB(bb); CHECK_FATAL(rightnextbb, "null ptr check "); rightnextbb->pred.push_back(bb); bb->succ.push_back(rightnextbb); /* link goto */ CondGotoNode *gotostmt = static_cast(laststmt); LabelIdx lblidx = (LabelIdx)gotostmt->offset; - BB *meBb = func->labelBBIdMap[lblidx]; + BB *meBb = labelBBIdMap[lblidx]; bb->succ.push_back(meBb); meBb->pred.push_back(bb); /* can the gotostmt be replaced by assertnonnull ? */ @@ -141,12 +183,12 @@ void MirCFG::BuildMirCFG() { CHECK_FATAL(laststmt->op == OP_switch, ""); SwitchNode *switchstmt = static_cast(laststmt); LabelIdx lblidx = switchstmt->defaultLabel; - BB *mirbb = func->labelBBIdMap[lblidx]; + BB *mirbb = labelBBIdMap[lblidx]; bb->succ.push_back(mirbb); mirbb->pred.push_back(bb); for (uint32_t j = 0; j < switchstmt->switchTable.size(); j++) { lblidx = switchstmt->switchTable[j].second; - BB *mebb = func->labelBBIdMap[lblidx]; + BB *mebb = labelBBIdMap[lblidx]; // Avoid duplicate succs. MapleVector::iterator it = std::find(bb->succ.begin(), bb->succ.end(), mebb); if (it == bb->succ.end()) { @@ -158,7 +200,7 @@ void MirCFG::BuildMirCFG() { } case kBBIgoto: { for (LabelIdx lidx : func->mirFunc->labelTab->addrTakenLabels) { - BB *mebb = func->labelBBIdMap[lidx]; + BB *mebb = labelBBIdMap[lidx]; bb->succ.push_back(mebb); mebb->pred.push_back(bb); } @@ -168,7 +210,7 @@ void MirCFG::BuildMirCFG() { break; default: { // fall through? - BB *rightnextbb = func->NextBB(bb); + BB *rightnextbb = NextBB(bb); if (rightnextbb) { rightnextbb->pred.push_back(bb); bb->succ.push_back(rightnextbb); @@ -178,15 +220,15 @@ void MirCFG::BuildMirCFG() { } /* deal try blocks, add catch handler to try's succ */ if (func->mirModule.IsJavaModule() && bb->isTry) { - ASSERT((func->bbTryNodeMap.find(bb) != func->bbTryNodeMap.end()), "try bb without try"); - StmtNode *stmt = func->bbTryNodeMap[bb]; + 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(func->labelBBIdMap.find(labelIdx) != func->labelBBIdMap.end(), ""); - BB *meBb = func->labelBBIdMap[labelIdx]; + ASSERT(labelBBIdMap.find(labelIdx) != labelBBIdMap.end(), ""); + BB *meBb = labelBBIdMap[labelIdx]; ASSERT(meBb != nullptr && meBb->IsCatch(), ""); uint32 si = 0; if (meBb->IsJavaFinally() || meBb->IsCatch()) { @@ -221,12 +263,12 @@ void MirCFG::BuildMirCFG() { } } // merge all blocks in entryblocks - for (MapleVector::iterator it = entryblocks.begin(); it != entryblocks.end(); ++it) { - func->commonEntryBB->succ.push_back(*it); + for (std::vector::iterator it = entryblocks.begin(); it != entryblocks.end(); ++it) { + commonEntryBB->succ.push_back(*it); } // merge all blocks in exitblocks - for (MapleVector::iterator it = exitblocks.begin(); it != exitblocks.end(); ++it) { - func->commonExitBB->pred.push_back(*it); + for (std::vector::iterator it = exitblocks.begin(); it != exitblocks.end(); ++it) { + commonExitBB->pred.push_back(*it); } } @@ -241,7 +283,7 @@ void MirCFG::ReplaceWithAssertnonnull() { return; } for (LabelIdx lblidx : pattern_set_) { - BB *bb = func->labelBBIdMap[lblidx]; + BB *bb = labelBBIdMap[lblidx]; /* if BB->pred.size()==0, it won't enter this function */ for (uint32 i = 0; i < bb->pred.size(); i++) { BB *innerBb = bb->pred[i]; @@ -289,32 +331,34 @@ void MirCFG::ReplaceWithAssertnonnull() { // used only after DSE because it looks at live field of VersionSt void MirCFG::ConvertPhis2IdentityAssigns(BB *mebb) { - MapleMap::iterator phiIt = mebb->phiList.begin(); - while (phiIt != mebb->phiList.end()) { - if (!(*phiIt).second.result->IsLive()) { + if (mebb->phiList) { + MapleMap::iterator phiIt = mebb->phiList->begin(); + while (phiIt != mebb->phiList->end()) { + if (!(*phiIt).second.result->IsLive()) { + phiIt++; + continue; + } + // replace phi with identify assignment as it only has 1 opnd + OriginalSt *ost = (*phiIt).first; + if (ost->ostType == OriginalSt::kSymbolOst && ost->indirectLev == 0) { + MIRSymbol *st = ost->GetMIRSymbol(); + MIRType *stype = GlobalTables::GetTypeTable().GetTypeFromTyIdx(st->GetTyIdx()); + AddrofNode *dread = func->mirModule.mirBuilder->CreateDread(st, GetRegPrimType(stype->GetPrimType())); + AddrofSSANode *dread2 = func->mirFunc->codeMemPool->New(dread); + dread2->ssaVar = (*phiIt).second.phiOpnds[0]; + DassignNode *dass = func->mirModule.mirBuilder->CreateStmtDassign(st, 0, dread2); + func->meSSATab->stmtsSSAPart.SetSsapartOf(dass, + func->meSSATab->stmtsSSAPart.ssaPartMp->New( + &func->meSSATab->stmtsSSAPart.ssaPartAlloc)); + MayDefPartWithVersionSt *thessapart = + static_cast(func->meSSATab->stmtsSSAPart.SsapartOf(dass)); + thessapart->ssaVar = (*phiIt).second.result; + mebb->PrependStmtNode(dass); + } phiIt++; - continue; } - // replace phi with identify assignment as it only has 1 opnd - OriginalSt *ost = (*phiIt).first; - if (ost->ostType == OriginalSt::kSymbolOst && ost->indirectLev == 0) { - MIRSymbol *st = ost->GetMIRSymbol(); - MIRType *stype = GlobalTables::GetTypeTable().GetTypeFromTyIdx(st->GetTyIdx()); - AddrofNode *dread = func->mirModule.mirBuilder->CreateDread(st, GetRegPrimType(stype->GetPrimType())); - AddrofSSANode *dread2 = func->mirFunc->codeMemPool->New(dread); - dread2->ssaVar = (*phiIt).second.phiOpnds[0]; - DassignNode *dass = func->mirModule.mirBuilder->CreateStmtDassign(st, 0, dread2); - func->meSSATab->stmtsSSAPart.SetSsapartOf(dass, - func->meSSATab->stmtsSSAPart.ssaPartMp->New( - &func->meSSATab->stmtsSSAPart.ssaPartAlloc)); - MayDefPartWithVersionSt *thessapart = - static_cast(func->meSSATab->stmtsSSAPart.SsapartOf(dass)); - thessapart->ssaVar = (*phiIt).second.result; - mebb->PrependStmtNode(dass); - } - phiIt++; + mebb->phiList->clear(); // delete all the phis } - mebb->phiList.clear(); // delete all the phis MapleMap::iterator mePhiIt = mebb->mePhiList.begin(); while (mePhiIt != mebb->mePhiList.end()) { @@ -344,44 +388,44 @@ void MirCFG::ConvertPhis2IdentityAssigns(BB *mebb) { // analyse the CFG to find the BBs that are not reachable from function entries // and delete them void MirCFG::UnreachCodeAnalysis(bool updatePhi) { - std::vector visitedBBs(func->NumBBs(), false); - func->commonEntryBB->FindReachableBBs(visitedBBs); + std::vector visitedBBs(NumBBs(), false); + commonEntryBB->FindReachableBBs(visitedBBs); // delete the unreached bb BB *bb = nullptr; - for (uint32_t i = 0; i < func->bbVec.size(); i++) { - bb = func->bbVec[i]; - if (!visitedBBs[i] && bb && !bb->isEntry && bb != func->commonExitBB) { + for (uint32_t i = 0; i < bbVec.size(); i++) { + bb = bbVec[i]; + if (!visitedBBs[i] && bb && !bb->isEntry && bb != commonExitBB) { bb->wontExit = true; /* avoid redundant pred before adding to commonExitBB's pred list */ uint32 pi = 0; - for (; pi < func->commonExitBB->pred.size(); pi++) { - if (bb == func->commonExitBB->pred[pi]) { + for (; pi < commonExitBB->pred.size(); pi++) { + if (bb == commonExitBB->pred[pi]) { break; } } - if (pi == func->commonExitBB->pred.size()) { - func->commonExitBB->pred.push_back(bb); + if (pi == commonExitBB->pred.size()) { + commonExitBB->pred.push_back(bb); } if (!MeOption::quiet) { LogInfo::MapleLogger() << "#### BB " << bb->id.idx << " deleted because unreachable\n"; } if (bb->isTryEnd) { // unreachable bb has try end info - BB *trybb = func->endTryBB2TryBB[bb]; + BB *trybb = endTryBB2TryBB[bb]; if (visitedBBs[trybb->id.idx]) { // corresponding try is still around // move endtry tag to previous non-deleted bb int j = static_cast(i) - 1; for (; j >= 0; j--) { - if (func->bbVec[j] != nullptr) { - func->bbVec[j]->isTryEnd = true; - func->endTryBB2TryBB[func->bbVec[j]] = func->endTryBB2TryBB[bb]; + if (bbVec[j] != nullptr) { + bbVec[j]->isTryEnd = true; + endTryBB2TryBB[bbVec[j]] = endTryBB2TryBB[bb]; break; } } } } - func->DeleteBasicBlock(bb); + DeleteBasicBlock(bb); // remove the bb from its succ's pred list for (MapleVector::iterator it = bb->succ.begin(); it != bb->succ.end(); it++) { BB *sucbb = *it; @@ -392,15 +436,17 @@ void MirCFG::UnreachCodeAnalysis(bool updatePhi) { if (sucbb->pred.size() == 1) { ConvertPhis2IdentityAssigns(sucbb); } else if (sucbb->pred.empty()) { - sucbb->phiList.clear(); + if (sucbb->phiList) { + sucbb->phiList->clear(); + } } } } // remove the bb from commonExitBB's pred list if it is there - for (MapleVector::iterator it = func->commonExitBB->pred.begin(); - it != func->commonExitBB->pred.end(); it++) { + for (MapleVector::iterator it = commonExitBB->pred.begin(); + it != commonExitBB->pred.end(); it++) { if (*it == bb) { - func->commonExitBB->RemoveBBFromPred(bb); + commonExitBB->RemoveBBFromPred(bb); break; } } @@ -412,17 +458,17 @@ void MirCFG::UnreachCodeAnalysis(bool updatePhi) { // are BBs inside infinite loops; mark their wontExit flag and create // artificial edges from them to commonExitBB void MirCFG::WontExitAnalysis() { - if (func->NumBBs() == 0) { + if (NumBBs() == 0) { return; } - vector visitedBBs(func->NumBBs(), false); - func->commonExitBB->FindWillExitBBs(visitedBBs); + vector visitedBBs(NumBBs(), false); + commonExitBB->FindWillExitBBs(visitedBBs); BB *bb = nullptr; - uint32_t bbvecsize = func->bbVec.size(); + uint32_t bbvecsize = bbVec.size(); for (uint32_t i = 0; i < bbvecsize; i++) { - bb = func->bbVec[i]; - if (!visitedBBs[i] && bb && (bb != func->commonEntryBB)) { + bb = bbVec[i]; + if (!visitedBBs[i] && bb && (bb != commonEntryBB)) { bb->wontExit = true; if (!MeOption::quiet) { printf("#### BB %d wont exit\n", i); @@ -436,7 +482,7 @@ void MirCFG::WontExitAnalysis() { bb->succ.push_back(newbb); newbb->pred.push_back(bb); - func->commonExitBB->pred.push_back(newbb); + commonExitBB->pred.push_back(newbb); } } } @@ -446,13 +492,13 @@ void MirCFG::WontExitAnalysis() { // Check bb-vec and bb-list are strictly consistent. void MirCFG::Verify() { // Check every bb in bb-list. - for (BB *bb : func->bbVec) { + for (BB *bb : bbVec) { if (bb == nullptr) { continue; } - ASSERT(bb->id.idx < func->bbVec.size(), "CFG Error!"); - ASSERT(func->bbVec[bb->id.idx] == bb, "CFG Error!"); - if (bb->IsEmpty() || bb == func->commonEntryBB || bb == func->commonExitBB) { + ASSERT(bb->id.idx < bbVec.size(), "CFG Error!"); + ASSERT(bbVec[bb->id.idx] == bb, "CFG Error!"); + if (bb->IsEmpty() || bb == commonEntryBB || bb == commonExitBB) { continue; } ASSERT(bb->kind != kBBUnknown, ""); @@ -477,8 +523,8 @@ void MirCFG::Verify() { // check that all the target labels in jump statements are defined void MirCFG::VerifyLabels(void) { - for (uint32_t i = 0; i < func->bbVec.size(); i++) { - BB *mirbb = func->bbVec[i]; + for (uint32_t i = 0; i < bbVec.size(); i++) { + BB *mirbb = bbVec[i]; if (mirbb == nullptr) { continue; } @@ -491,21 +537,21 @@ void MirCFG::VerifyLabels(void) { } GotoNode *gotostmt = static_cast(mirbb->stmtNodeList.last); LabelIdx targetLabidx = (LabelIdx)gotostmt->offset; - BB *bb = func->labelBBIdMap[targetLabidx]; + BB *bb = labelBBIdMap[targetLabidx]; CHECK_FATAL(bb->bbLabel == targetLabidx, "undefined label in goto"); } else if (mirbb->kind == kBBCondGoto) { CondGotoNode *cgotostmt = static_cast(mirbb->stmtNodeList.last); LabelIdx targetLabidx = (LabelIdx)cgotostmt->offset; - BB *bb = func->labelBBIdMap[targetLabidx]; + BB *bb = labelBBIdMap[targetLabidx]; CHECK_FATAL(bb->bbLabel == targetLabidx, "undefined label in conditional branch"); } else if (mirbb->kind == kBBSwitch) { SwitchNode *switchstmt = static_cast(mirbb->stmtNodeList.last); LabelIdx targetLabidx = switchstmt->defaultLabel; - BB *bb = func->labelBBIdMap[targetLabidx]; + BB *bb = labelBBIdMap[targetLabidx]; CHECK_FATAL(bb->bbLabel == targetLabidx, "undefined label in switch"); for (uint32_t j = 0; j < switchstmt->switchTable.size(); j++) { targetLabidx = switchstmt->switchTable[j].second; - bb = func->labelBBIdMap[targetLabidx]; + bb = labelBBIdMap[targetLabidx]; CHECK_FATAL(bb->bbLabel == targetLabidx, "undefined switch target label"); } } @@ -517,11 +563,11 @@ void MirCFG::Dump() { // map visited_map; // set visited_set; printf("####### CFG Dump: "); - CHECK_FATAL(func->NumBBs() != 0, "size to be allocated is 0"); - bool *visitedMap = static_cast(calloc(func->NumBBs(), sizeof(bool))); + CHECK_FATAL(NumBBs() != 0, "size to be allocated is 0"); + bool *visitedMap = static_cast(calloc(NumBBs(), sizeof(bool))); if (visitedMap != nullptr) { queue qu; - qu.push(func->first_bb_); + qu.push(first_bb); while (!qu.empty()) { BB *bb = qu.front(); qu.pop(); @@ -595,11 +641,11 @@ void MirCFG::DumpToFile(const char *prefix, bool dumpinstrs) { cfgfile << "digraph {\n"; cfgfile << " # /*" << func->GetName().c_str() << " (red line is exception handler)*/\n"; /* dump edge */ - for (BB *bb : func->bbVec) { + for (BB *bb : bbVec) { if (bb == nullptr) { continue; } - if (bb == func->commonExitBB) { + if (bb == commonExitBB) { /* specical case for commonExitBB */ for (auto it = bb->pred.begin(); it != bb->pred.end(); it++) { cfgfile << "BB" << (*it)->id.idx << " -> " @@ -610,7 +656,7 @@ void MirCFG::DumpToFile(const char *prefix, bool dumpinstrs) { for (auto it = bb->succ.begin(); it != bb->succ.end(); it++) { cfgfile << "BB" << bb->id.idx << " -> " << "BB" << (*it)->id.idx; - if (bb == func->commonEntryBB) { + if (bb == commonEntryBB) { cfgfile << "[style=dotted];\n"; continue; } @@ -624,7 +670,7 @@ void MirCFG::DumpToFile(const char *prefix, bool dumpinstrs) { } /* dump instruction in each BB */ if (dumpinstrs) { - for (BB *bb : func->bbVec) { + for (BB *bb : bbVec) { if (bb == nullptr || bb->IsEmpty()) { continue; } @@ -637,8 +683,10 @@ void MirCFG::DumpToFile(const char *prefix, bool dumpinstrs) { cfgfile << "@" << func->mirFunc->GetLabelName(bb->bbLabel) << ":\n"; } MapleMap::iterator phiIt; - for (phiIt = bb->phiList.begin(); phiIt != bb->phiList.end(); phiIt++) { - (*phiIt).second.Dump(&(func->mirModule)); + if (bb->phiList) { + for (phiIt = bb->phiList->begin(); phiIt != bb->phiList->end(); phiIt++) { + (*phiIt).second.Dump(&(func->mirModule)); + } } StmtNode *stmt = bb->stmtNodeList.first; do { @@ -661,4 +709,39 @@ void MirCFG::DumpToFile(const char *prefix, bool dumpinstrs) { LogInfo::MapleLogger().rdbuf(coutbuf); } +AnalysisResult *MeDoCfgBuild::Run(MeFunction *func, MeFuncResultMgr *m) { + MemPool *cfgMp = mempoolctrler.NewMemPool(PhaseName().c_str()); + MirCFG *cfg = cfgMp->New(func, cfgMp); + func->theCFG = cfg; + func->CreateBasicBlocks(cfg); + if (func->theCFG->NumBBs() == 0) { + /* there's no basicblock generated */ + return cfg; + } + func->RemoveEhEdgesInSyncRegion(); + + cfg->BuildMirCFG(); + cfg->ReplaceWithAssertnonnull(); + cfg->VerifyLabels(); + cfg->UnreachCodeAnalysis(); + cfg->WontExitAnalysis(); + cfg->Verify(); + + if (!func->isLfo && MeOption::optLevel >= 2) { + MeDoLoopCanon doLoopCanon(MeFuncPhase_LOOPCANON); + if (!MeOption::quiet) { + LogInfo::MapleLogger() << " == " << PhaseName() << " invokes [ " << doLoopCanon.PhaseName() << " ] ==\n"; + } + doLoopCanon.Run(func, m); + + MeDoSplitCEdge doSplitCEdge(MeFuncPhase_SPLITCEDGE); + if (!MeOption::quiet) { + LogInfo::MapleLogger() << " == " << PhaseName() << " invokes [ " << doSplitCEdge.PhaseName() << " ] ==\n"; + } + doSplitCEdge.Run(func, m); + } + + return cfg; +} + } // namespace maple diff --git a/mapleall/maple_me/src/me_cfg_opt.cpp b/mapleall/maple_me/src/me_cfg_opt.cpp index ae2439762804ff9881903e05a5b4cc40e3a1283e..e93b7f798ec64bc3696d75142150381519413e6e 100644 --- a/mapleall/maple_me/src/me_cfg_opt.cpp +++ b/mapleall/maple_me/src/me_cfg_opt.cpp @@ -80,8 +80,8 @@ bool MeCfgOpt::HasFloatCmp(MeExpr *meexpr) { } bool MeCfgOpt::PreCheck(MeFunction *func) { - const uint32 kSize = func->bbVec.size(); - MapleVector &bbvec = func->bbVec; + const uint32 kSize = func->theCFG->bbVec.size(); + MapleVector &bbvec = func->theCFG->bbVec; for (uint32 i = 0; i < kSize; i++) { BB *bb = bbvec[i]; if (!bb) { @@ -114,8 +114,8 @@ bool MeCfgOpt::Run(MeFunction *func) { } uint32 i = 0; uint32 nexti = -1; - const uint32 kSize = func->bbVec.size(); - MapleVector &bbvec = func->bbVec; + const uint32 kSize = func->theCFG->bbVec.size(); + MapleVector &bbvec = func->theCFG->bbVec; while (i < kSize) { nexti = i + 1; BB *bb = bbvec[i]; @@ -220,8 +220,8 @@ bool MeCfgOpt::Run(MeFunction *func) { } void MeDoCfgOpt::EmitMapleir(MeFunction *func, MeFuncResultMgr *m) { - if (func->NumBBs() > 0) { - BBLayout *layoutbbs = static_cast(m->GetAnalysisResult(MeFuncPhase_BBLAYOUT, func)); + if (func->theCFG->NumBBs() > 0) { + BBLayout *layoutbbs = static_cast(m->GetAnalysisResult(MeFuncPhase_BBLAYOUT, func, !MeOption::quiet)); CHECK_FATAL(func->irMap != nullptr, ""); MIRFunction *mirfunction = func->mirFunc; if (mirfunction->codeMemPool != nullptr) { @@ -245,13 +245,15 @@ void MeDoCfgOpt::EmitMapleir(MeFunction *func, MeFuncResultMgr *m) { AnalysisResult *MeDoCfgOpt::Run(MeFunction *func, MeFuncResultMgr *m) { MIRFunction *mirfunction = func->mirFunc; - MeIRMap *irMap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func)); + MeIRMap *irMap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func, !MeOption::quiet)); ASSERT(irMap != nullptr, ""); MeCfgOpt cfgopt(irMap); if (cfgopt.Run(func)) { - SetChangeCFG(); EmitMapleir(func, m); + m->InvalidAllResults(); + func->meSSATab = nullptr; + func->irMap = nullptr; return nullptr; } diff --git a/mapleall/maple_me/src/me_condbased_opt.cpp b/mapleall/maple_me/src/me_condbased_opt.cpp index ced657a8dc936a1581ec969503f861903ef335a0..b78d46a8705ba00ddbd3ebd4076790832c233a1b 100644 --- a/mapleall/maple_me/src/me_condbased_opt.cpp +++ b/mapleall/maple_me/src/me_condbased_opt.cpp @@ -95,7 +95,7 @@ bool CondBased::NullValueFromTestCond(VarMeExpr *varmeexpr, BB *bb, bool expecte bool provennull = false; while (pdomfrt->size() == 1) { - BB *cdbb = func->bbVec[(pdomfrt->begin())->idx]; + BB *cdbb = func->theCFG->bbVec[(pdomfrt->begin())->idx]; if (visitedmap[cdbb->id.idx]) { break; } @@ -236,11 +236,14 @@ bool CondBased::IsNotNullValue(VarMeExpr *varmeexpr, UnaryMeStmt *assertmestmt, } AnalysisResult *MeDoCondBasedRC::Run(MeFunction *func, MeFuncResultMgr *m) { - Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); + MeIRMap *irMap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func, !MeOption::quiet)); + ASSERT(irMap != nullptr, "irmapbuild phase has problem"); + Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func, !MeOption::quiet)); + ASSERT(dom != nullptr, "dominance phase has problem"); CondBased condbasedrc(func, dom); - for (BB *bb : func->bbVec) { + for (BB *bb : func->theCFG->bbVec) { if (bb == nullptr) { continue; } @@ -279,10 +282,13 @@ AnalysisResult *MeDoCondBasedRC::Run(MeFunction *func, MeFuncResultMgr *m) { } AnalysisResult *MeDoCondBasedNPC::Run(MeFunction *func, MeFuncResultMgr *m) { - Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); + MeIRMap *irMap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func, !MeOption::quiet)); + ASSERT(irMap != nullptr, "irmapbuild phase has problem"); + Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func, !MeOption::quiet)); + ASSERT(dom != nullptr, "dominance phase has problem"); CondBased condbasednpc(func, dom); - for (BB *bb : func->bbVec) { + for (BB *bb : func->theCFG->bbVec) { if (bb == nullptr) { continue; } diff --git a/mapleall/maple_me/src/me_const_prop.cpp b/mapleall/maple_me/src/me_const_prop.cpp index ffd1be0057561d40bdc613e3bfda4186b19f0a44..f29e07742b7f311eeb4a9778dfca40887eef36dc 100644 --- a/mapleall/maple_me/src/me_const_prop.cpp +++ b/mapleall/maple_me/src/me_const_prop.cpp @@ -20,6 +20,7 @@ #include "constant_fold.h" #include "mir_nodes.h" #include "me_function.h" +#include "me_cfg.h" #include "ssa_mir_nodes.h" #include "mir_builder.h" @@ -130,8 +131,8 @@ static bool IsConstant(BaseNode *stmt, MapleMap constan void MeConstProp::IntraConstProp() { MapleMap constantMp(std::less(), constprop_alloc.Adapter()); maple::ConstantFold cf(&func->mirModule); - for (uint32 i = 0; i < func->bbVec.size(); i++) { - BB *bb = func->bbVec[i]; + for (uint32 i = 0; i < func->theCFG->bbVec.size(); i++) { + BB *bb = func->theCFG->bbVec[i]; if (bb == nullptr) { continue; } diff --git a/mapleall/maple_me/src/me_critical_edge.cpp b/mapleall/maple_me/src/me_critical_edge.cpp index 8429ae36fd3626318f2555ea0417688667616758..5577682a945709eba8d14119f52fb16e45221b9d 100644 --- a/mapleall/maple_me/src/me_critical_edge.cpp +++ b/mapleall/maple_me/src/me_critical_edge.cpp @@ -51,13 +51,13 @@ void MeDoSplitCEdge::BreakCriticalEdge(MeFunction *func, BB *pred, BB *succ) { newbb->kind = kBBFallthru; /* default kind */ newbb->artificial = true; /* use replace instead of remove/add to keep position in pred/succ */ - if (pred == func->commonEntryBB) { + if (pred == func->theCFG->commonEntryBB) { pred->ReplaceSuccOfCommonEntryBB(succ, newbb); newbb->succ.push_back(succ); succ->pred.push_back(newbb); newbb->isEntry = true; succ->isEntry = false; - func->first_bb_ = newbb; + func->theCFG->first_bb = newbb; } else { pred->ReplaceSucc(succ, newbb); succ->ReplacePred(pred, newbb); @@ -112,11 +112,11 @@ AnalysisResult *MeDoSplitCEdge::Run(MeFunction *func, MeFuncResultMgr *m) { MapleAllocator localAlloc(localmp); MapleVector> criticaledge(localAlloc.Adapter()); - for (BB *bb : func->bbVec) { + for (BB *bb : func->theCFG->bbVec) { if (bb == nullptr) { continue; } - if (bb == func->commonExitBB) { + if (bb == func->theCFG->commonExitBB) { continue; } MapleVector &preds = bb->pred; @@ -136,9 +136,9 @@ AnalysisResult *MeDoSplitCEdge::Run(MeFunction *func, MeFuncResultMgr *m) { } } // separate treatment for commonEntryBB's succ BBs - for (BB *entrybb : func->commonEntryBB->succ) { + for (BB *entrybb : func->theCFG->commonEntryBB->succ) { if (entrybb->pred.size() > 0 && !entrybb->IsCatch()) { - criticaledge.push_back(std::make_pair(func->commonEntryBB, entrybb)); + criticaledge.push_back(std::make_pair(func->theCFG->commonEntryBB, entrybb)); } } if (criticaledge.size() > 0) { @@ -156,7 +156,7 @@ AnalysisResult *MeDoSplitCEdge::Run(MeFunction *func, MeFuncResultMgr *m) { func->DumpFunctionNoSSA(); func->theCFG->DumpToFile("cfgafterbreak"); } - m->InvalidAllResults(); + m->InvalidAnalysisResult(MeFuncPhase_DOMINANCE, func); } mempoolctrler.DeleteMemPool(localmp); return nullptr; diff --git a/mapleall/maple_me/src/me_delegate_rc.cpp b/mapleall/maple_me/src/me_delegate_rc.cpp index 184defa41039679d8655fefd46fa4c6cd4de5dbb..b2267416752132cfb01d19d83e073443cdb0bc10 100644 --- a/mapleall/maple_me/src/me_delegate_rc.cpp +++ b/mapleall/maple_me/src/me_delegate_rc.cpp @@ -467,7 +467,7 @@ void DelegateRC::DelegateRCTemp(MeStmt *stmt) { if (rhs->IsGcmalloc() || (rhs->meOp == kMeOpIvar && !static_cast(rhs)->IsFinal()) || (rhs->meOp == kMeOpVar && !ost->isFinal && ost->GetMIRSymbol()->IsGlobal()) || - (rhs->op == OP_regread && static_cast(rhs)->regIdx == -kSregThrownval)) { + (rhs->op == OP_regread && static_cast(rhs)->GetPregIdx() == -kSregThrownval)) { if (retmestmt->bb == defStmt->bb && ContainAllTheUses(val, stmt, defStmt)) { RegMeExpr *curreg = RHSTempDelegated(ret, stmt); if (curreg != nullptr) { @@ -553,7 +553,7 @@ bool DelegateRC::CanOmitRC4LHSVar(MeStmt *stmt, bool &onlyWithDecref) { // condition B1 if (!verst_derefedcopied[thelhs->vstIdx]) { onlyWithDecref = therhs->op == OP_gcmalloc || therhs->op == OP_gcmallocjarray || - (therhs->op == OP_regread && static_cast(therhs)->regIdx == -kSregThrownval); + (therhs->op == OP_regread && static_cast(therhs)->GetPregIdx() == -kSregThrownval); if (onlyWithDecref && verst_cantdecrefearly[thelhs->vstIdx]) { onlyWithDecref = false; return false; @@ -684,7 +684,7 @@ void DelegateRC::RenameDelegatedRefVarUses(MeStmt *mestmt, MeExpr *meexpr) { AnalysisResult *MeDoDelegateRC::Run(MeFunction *func, MeFuncResultMgr *m) { static uint32 pUcount = 0; - Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); + Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func, !MeOption::quiet)); ASSERT(dom != nullptr, "dominance phase has problem"); { // scope needed for mempool release @@ -701,23 +701,22 @@ AnalysisResult *MeDoDelegateRC::Run(MeFunction *func, MeFuncResultMgr *m) { } MemPool *tempmp = mempoolctrler.NewMemPool("delegaterc temps"); - MemPool *mp = mempoolctrler.NewMemPool(PhaseName().c_str()); - DelegateRC *delegaterc = mp->New(func, dom, mp, tempmp); + DelegateRC delegaterc(func, dom, tempmp); if (pUcount > MeOption::delrcPULimit) { pUcount++; - return delegaterc; + return nullptr; } if (pUcount == MeOption::delrcPULimit) { LogInfo::MapleLogger() << func->mirFunc->GetName() << " is last PU optimized by delegaterc under -delrcpulimit option" << endl; } // first pass: set cantdelegate flag and count uses - for (BB *bb : func->bbVec) { + for (BB *bb : func->theCFG->bbVec) { if (bb == nullptr) { continue; } - delegaterc->SetCantDelegate(bb->mePhiList); + delegaterc.SetCantDelegate(bb->mePhiList); for (auto stmt : bb->meStmtList) { if (stmt->op == OP_decref && // do not count decref operands static_cast(stmt)->opnd->meOp == kMeOpVar) { @@ -731,7 +730,7 @@ AnalysisResult *MeDoDelegateRC::Run(MeFunction *func, MeFuncResultMgr *m) { } } for (int32 i = 0; i < stmt->NumMeStmtOpnds(); i++) { - delegaterc->CollectUsesInfo(stmt->GetMeStmtOpnd(i)); + delegaterc.CollectUsesInfo(stmt->GetMeStmtOpnd(i)); } if (stmt->op == OP_dassign || stmt->op == OP_maydassign || stmt->op == OP_regassign || stmt->op == OP_syncenter || @@ -743,7 +742,7 @@ AnalysisResult *MeDoDelegateRC::Run(MeFunction *func, MeFuncResultMgr *m) { } VarMeExpr *copiedvar = dynamic_cast(curopnd); if (copiedvar) { - delegaterc->verst_derefedcopied[copiedvar->vstIdx] = true; + delegaterc.verst_derefedcopied[copiedvar->vstIdx] = true; } } else if (stmt->op == OP_iassign) { // look at copied rhs @@ -754,13 +753,13 @@ AnalysisResult *MeDoDelegateRC::Run(MeFunction *func, MeFuncResultMgr *m) { } VarMeExpr *copiedvar = dynamic_cast(curopnd); if (copiedvar) { - delegaterc->verst_derefedcopied[copiedvar->vstIdx] = true; + delegaterc.verst_derefedcopied[copiedvar->vstIdx] = true; } // check dereferencing IvarMeExpr *lhsivar = iass->lhsVar; if (lhsivar->base->meOp == kMeOpVar) { VarMeExpr *basevar = static_cast(lhsivar->base); - delegaterc->verst_derefedcopied[basevar->vstIdx] = true; + delegaterc.verst_derefedcopied[basevar->vstIdx] = true; } } else if (kOpcodeInfo.IsCall(stmt->op)) { // processsed passed operands @@ -771,7 +770,7 @@ AnalysisResult *MeDoDelegateRC::Run(MeFunction *func, MeFuncResultMgr *m) { } VarMeExpr *passedvar = dynamic_cast(curopnd); if (passedvar) { - delegaterc->verst_derefedcopied[passedvar->vstIdx] = true; + delegaterc.verst_derefedcopied[passedvar->vstIdx] = true; } } } @@ -779,16 +778,16 @@ AnalysisResult *MeDoDelegateRC::Run(MeFunction *func, MeFuncResultMgr *m) { } // main pass - for (BB *bb : func->bbVec) { + for (BB *bb : func->theCFG->bbVec) { if (bb == nullptr) { continue; } for (auto stmt : bb->meStmtList) { bool withDecref = false; - if (delegaterc->CanOmitRC4LHSVar(stmt, withDecref)) { - delegaterc->DelegateHandleNoRCStmt(stmt, withDecref); // Form B + if (delegaterc.CanOmitRC4LHSVar(stmt, withDecref)) { + delegaterc.DelegateHandleNoRCStmt(stmt, withDecref); // Form B } else { - delegaterc->DelegateRCTemp(stmt); // Form A + delegaterc.DelegateRCTemp(stmt); // Form A } } } @@ -796,7 +795,7 @@ AnalysisResult *MeDoDelegateRC::Run(MeFunction *func, MeFuncResultMgr *m) { // final pass: rename the uses of the delegated ref pointer variable versions; // set live_localrefvars based on appearances on LHS std::set liveLocalrefvars; // to detect dead localrefvars - for (BB *bb : func->bbVec) { + for (BB *bb : func->theCFG->bbVec) { if (bb == nullptr) { continue; } @@ -812,7 +811,7 @@ AnalysisResult *MeDoDelegateRC::Run(MeFunction *func, MeFuncResultMgr *m) { } } for (int32 i = 0; i < stmt->NumMeStmtOpnds(); i++) { - delegaterc->RenameDelegatedRefVarUses(stmt, stmt->GetMeStmtOpnd(i)); + delegaterc.RenameDelegatedRefVarUses(stmt, stmt->GetMeStmtOpnd(i)); } // for live_localrefvars if (stmt->op == OP_dassign || stmt->op == OP_maydassign) { @@ -839,7 +838,7 @@ AnalysisResult *MeDoDelegateRC::Run(MeFunction *func, MeFuncResultMgr *m) { } // postpass: go through the cleanup intrinsics to delete dead localrefvars - for (BB *bb : func->commonExitBB->pred) { + for (BB *bb : func->theCFG->commonExitBB->pred) { MeStmt *lastMeStmt = bb->meStmtList.last; if (lastMeStmt == nullptr || lastMeStmt->op != OP_return) { continue; @@ -877,7 +876,7 @@ AnalysisResult *MeDoDelegateRC::Run(MeFunction *func, MeFuncResultMgr *m) { } } if (MeOption::earlydecref) { // delete decref if opnd not in livelocalrefvars - for (BB *bb : func->bbVec) { + for (BB *bb : func->theCFG->bbVec) { if (bb == nullptr) { continue; } @@ -907,7 +906,7 @@ AnalysisResult *MeDoDelegateRC::Run(MeFunction *func, MeFuncResultMgr *m) { mempoolctrler.DeleteMemPool(tempmp); pUcount++; - return delegaterc; + return nullptr; } } // namespace maple diff --git a/mapleall/maple_me/src/me_dominance.cpp b/mapleall/maple_me/src/me_dominance.cpp index 5aa61b4834e90b2aa9c807a39292789f522154c9..324c69435c13eb9c4f2858f813f6b1fbed2b1eaf 100644 --- a/mapleall/maple_me/src/me_dominance.cpp +++ b/mapleall/maple_me/src/me_dominance.cpp @@ -32,7 +32,7 @@ void MeDominance::Run() { ComputeDomChildren(); ComputeIterDomFrontiers(); uint32 num = 0; - ComputeDtPreorder(func->commonEntryBB, num); + ComputeDtPreorder(func->theCFG->commonEntryBB, num); dtPreOrder.resize(num); ComputeDtDfn(); @@ -42,7 +42,7 @@ void MeDominance::Run() { ComputePdomChildren(); ComputeIterPdomFrontiers(); num = 0; - ComputePdtPreorder(func->commonExitBB, num); + ComputePdtPreorder(func->theCFG->commonExitBB, num); pdtPreOrder.resize(num); ComputePdtDfn(); } @@ -52,7 +52,7 @@ AnalysisResult *MeDoDominance::Run(MeFunction *func, MeFuncResultMgr *m) { MemPool *tmppool = mempoolctrler.NewMemPool("dominance temps"); MeDominance *dom = - mp->New(mp, tmppool, (MapleVector *)&func->bbVec, func->commonEntryBB, func->commonExitBB, func); + mp->New(mp, tmppool, (MapleVector *)&func->theCFG->bbVec, func->theCFG->commonEntryBB, func->theCFG->commonExitBB, func); dom->Run(); diff --git a/mapleall/maple_me/src/me_driver.cpp b/mapleall/maple_me/src/me_driver.cpp index 101394b9c61fa5d6bc9d8a9db4f8977270325834..55b6cc536807791a1b068675dd32a9d5abfd32ec 100644 --- a/mapleall/maple_me/src/me_driver.cpp +++ b/mapleall/maple_me/src/me_driver.cpp @@ -56,7 +56,6 @@ int main(int argc, char **argv) { // new functional phase manager MeFuncPhaseManager fpm(optmp, &themodule); fpm.RegisterFuncPhases(); // scan me_phases.def and create phase object - fpm.SetMePhase(kMePhaseMainopt); MIRParser theparser(themodule); if (!isbpl) { @@ -73,13 +72,15 @@ int main(int argc, char **argv) { } } - ModulePhaseManager mpm(modulemp, &themodule); - mpm.RegisterModulePhases(); - vector modphases; - modphases.push_back(string("classhierarchy")); - mpm.AddModulePhases(modphases); - mpm.Run(); - fpm.SetModResMgr(mpm.GetModResultMgr()); + if (themodule.IsJavaModule()) { + ModulePhaseManager mpm(modulemp, &themodule); + mpm.RegisterModulePhases(); + vector modphases; + modphases.push_back(string("classhierarchy")); + mpm.AddModulePhases(modphases); + mpm.Run(); + fpm.SetModResMgr(mpm.GetModResultMgr()); + } if (!isbpl && MeOption::parserOpt & kCheckCompleteType) { theparser.EmitIncompleteTypes(); } @@ -110,6 +111,9 @@ int main(int argc, char **argv) { // delete mempool mempoolctrler.DeleteMemPool(optmp); mempoolctrler.DeleteMemPool(modulemp); - LogInfo::MapleLogger() << "me consumes " << timer.Elapsed() << " seconds" << endl; + timer.Stop(); + if (!MeOption::quiet) { + LogInfo::MapleLogger() << "me consumes " << timer.ElapsedMicroseconds() << " micro-seconds" << endl; + } return 0; } diff --git a/mapleall/maple_me/src/me_dse.cpp b/mapleall/maple_me/src/me_dse.cpp index a947c73bed1263c1e2f34ea21988924f3d6d24a8..76d9471e4f6626cd6da1934c88d95cd7abe0d2eb 100644 --- a/mapleall/maple_me/src/me_dse.cpp +++ b/mapleall/maple_me/src/me_dse.cpp @@ -19,6 +19,7 @@ #include "ver_symbol.h" #include "me_ssa.h" #include "me_cfg.h" +#include "me_fsaa.h" // This phase do dead store elimination. This optimization is done on SSA // version basis. @@ -36,8 +37,8 @@ namespace maple { // step 2 : mark the special stmts. void MeDSE::DseProcess() { - for (int32 i = func->bbVec.size() - 1; i >= 0; i--) { - BB *bb = func->bbVec[i]; + for (int32 i = cfg->bbVec.size() - 1; i >= 0; i--) { + BB *bb = cfg->bbVec[i]; if (bb == nullptr) { continue; } @@ -119,6 +120,16 @@ void MeDSE::DseProcess() { MarkStmt(stmt, bb); break; } + if (func->isLfo) { + if (strncmp(sym->GetName().c_str(), "injected.iv", 11) == 0) { + MarkStmt(stmt, bb); // preserve injected IVs + } else if (dass->uOpnd->op == OP_dread) { + AddrofNode *dread = static_cast(dass->uOpnd); + if (dass->stIdx == dread->stIdx && dass->fieldID == dread->fieldID) { + MarkStmt(stmt, bb); // preserve identify assignments + } + } + } MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->tyIdx); bool typevolatile = false; if (dass->fieldID == 0) { @@ -133,6 +144,14 @@ void MeDSE::DseProcess() { } case OP_regassign: { RegassignNode *rass = static_cast(stmt); + if (func->isLfo) { + if (rass->uOpnd->op == OP_regread) { + RegreadNode *regread = static_cast(rass->uOpnd); + if (rass->regIdx == regread->regIdx) { + MarkStmt(stmt, bb); // preserve identify assignments + } + } + } if (ExprNonDeletable(rass->Opnd(0))) { MarkStmt(stmt, bb); } @@ -211,7 +230,7 @@ void MeDSE::UpdateStmt(BB *bb) { bb->RemoveBBFromSucc(succbb); succbb->RemoveBBFromPred(bb); if (succbb->pred.size() == 1) { - func->theCFG->ConvertPhis2IdentityAssigns(succbb); + cfg->ConvertPhis2IdentityAssigns(succbb); } break; } @@ -293,7 +312,7 @@ void MeDSE::UpdateStmt(BB *bb) { } void MeDSE::Update() { - for (BB *bb : func->bbVec) { + for (BB *bb : cfg->bbVec) { if (bb == nullptr) { continue; } @@ -303,15 +322,15 @@ void MeDSE::Update() { void MeDSE::DseInit() { // Init bb's required flag - bb_required.resize(func->bbVec.size()); + bb_required.resize(cfg->bbVec.size()); for (uint32 i = 0; i < bb_required.size(); i++) { bb_required[i] = false; } - if (func->commonEntryBB != func->first_bb_) { - bb_required[func->commonEntryBB->id.idx] = true; + if (cfg->commonEntryBB != cfg->first_bb) { + bb_required[cfg->commonEntryBB->id.idx] = true; } - if (func->commonExitBB != func->last_bb_) { - bb_required[func->commonExitBB->id.idx] = true; + if (cfg->commonExitBB != cfg->last_bb) { + bb_required[cfg->commonExitBB->id.idx] = true; } // Init the versionst table; @@ -323,12 +342,12 @@ void MeDSE::DseInit() { } void MeDSE::VerifyPhi() { - for (auto bb : func->bbVec) { - if (bb == nullptr || bb == func->commonExitBB || bb->phiList.empty()) { + for (auto bb : cfg->bbVec) { + if (bb == nullptr || bb == cfg->commonExitBB || bb->phiList->empty()) { continue; } uint32 predbbNums = bb->pred.size(); - for (auto phiitem : bb->phiList) { + for (auto phiitem : *bb->phiList) { if (phiitem.second.result->IsLive()) { if (predbbNums <= 1) { OriginalSt *ost = phiitem.first; @@ -355,7 +374,7 @@ void MeDSE::Dse() { } Update(); /* remove unreached BB */ - func->theCFG->UnreachCodeAnalysis(/* update_phi */ true); + cfg->UnreachCodeAnalysis(/* update_phi */ true); VerifyPhi(); if (DEBUGFUNC(func)) { func->DumpFunction(); @@ -363,25 +382,35 @@ void MeDSE::Dse() { } AnalysisResult *MeDoDSE::Run(MeFunction *func, MeFuncResultMgr *m) { - Dominance *pdom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); + MeSSA *ssa = static_cast(m->GetAnalysisResult(MeFuncPhase_SSA, func, !MeOption::quiet)); + ASSERT(ssa != nullptr, "ssa phase has problem"); + Dominance *pdom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func, !MeOption::quiet)); ASSERT(pdom != nullptr, "dominance phase has problem"); - SSATab *ssaTab = static_cast(m->GetAnalysisResult(MeFuncPhase_SSATAB, func)); + SSATab *ssaTab = static_cast(m->GetAnalysisResult(MeFuncPhase_SSATAB, func, !MeOption::quiet)); ASSERT(ssaTab != nullptr, "ssaTab phase has problem"); MemPool *dsemp = mempoolctrler.NewMemPool(PhaseName().c_str()); - MeDSE dse(func, pdom, dsemp); - dse.Dse(); + MeDSE *dse = dsemp->New(func, pdom, dsemp); + dse->Dse(); func->Verify(); /* cfg change , invalid results in MeFuncResultMgr */ - if (dse.UpdatedCfg()) { + if (dse->UpdatedCfg()) { m->InvalidAnalysisResult(MeFuncPhase_DOMINANCE, func); } - /* this is a transform phase, delete mempool */ - mempoolctrler.DeleteMemPool(dsemp); - return nullptr; + + if (func->mirModule.IsCModule()) { + /* invoke FSAA */ + MeDoFSAA doFSAA(MeFuncPhase_FSAA); + if (!MeOption::quiet) { + LogInfo::MapleLogger() << " == " << PhaseName() << " invokes [ " << doFSAA.PhaseName() << " ] ==\n"; + } + doFSAA.Run(func, m); + } + + return dse; } } // namespace maple diff --git a/mapleall/maple_me/src/me_emit.cpp b/mapleall/maple_me/src/me_emit.cpp index 434e2d071e3e2fd1817f5acdfa81da1216c01ae5..fbe7f285d68ca5a17249fd3a8700559ec9e6fc4a 100644 --- a/mapleall/maple_me/src/me_emit.cpp +++ b/mapleall/maple_me/src/me_emit.cpp @@ -21,7 +21,7 @@ #include "me_predict.h" static const std::set kHssaPhases{ - "irMap", "hprop", "hssa", "hdse", "ssadevirt", "ea", "epre", + "irmapbuild", "hprop", "hssa", "hdse", "ssadevirt", "ea", "epre", "lpre", "stmtpre", "rename2preg", "ti", "analyzerc", "spre", "rclowering", "delegaterc", "condbasedrc", "condbasednpc", "may2dassign", "pregrename", "bdcopt", "syncselect", "cfgopt", "ssadevirt", "placementrc", "symrename", @@ -32,23 +32,22 @@ namespace maple { /* emit IR to specified file */ AnalysisResult *MeDoEmission::Run(MeFunction *func, MeFuncResultMgr *m) { std::string passName = GetPreviousPhaseName(); // get previous phase + if (passName == "lfopreemit" || passName == "cfgopt") { + return nullptr; + } + + MirCFG *cfg = static_cast(m->GetAnalysisResult(MeFuncPhase_CFGBUILD, func, !MeOption::quiet)); + ASSERT(cfg != nullptr, "cfgbuild phase has problem"); + bool emitHssaOrAfter = kHssaPhases.find(std::string(passName)) != kHssaPhases.end(); - if (func->NumBBs() > 0) { + if (func->theCFG->NumBBs() > 0) { /* generate bblist after layout (bb physical position) */ - if (!MeOption::quiet) { - CHECK_FATAL(m->GetAnalysisPhase(MeFuncPhase_BBLAYOUT) && m->GetAnalysisPhase(MeFuncPhase_BBLAYOUT)->PhaseName().c_str(), - "null ptr check"); - LogInfo::MapleLogger() << "===== Check/run Depended Phase [ " << m->GetAnalysisPhase(MeFuncPhase_BBLAYOUT)->PhaseName() - << " ]=====\n"; - } if (emitHssaOrAfter) { - MePrediction *predict = static_cast(m->GetAnalysisResult(MeFuncPhase_PREDICT, func)); - } - BBLayout *layoutbbs = static_cast(m->GetAnalysisResult(MeFuncPhase_BBLAYOUT, func)); - if (!MeOption::quiet) { - LogInfo::MapleLogger() << "===== Depended Phase ended =====\n"; + MePrediction *predict = static_cast(m->GetAnalysisResult(MeFuncPhase_PREDICT, func, !MeOption::quiet)); + ASSERT(predict != nullptr, "predict phase has problem"); } + BBLayout *layoutbbs = static_cast(m->GetAnalysisResult(MeFuncPhase_BBLAYOUT, func, !MeOption::quiet)); ASSERT(layoutbbs != nullptr, "layout phase has problem"); if (emitHssaOrAfter) { ASSERT(func->irMap != nullptr, ""); @@ -84,7 +83,7 @@ AnalysisResult *MeDoEmission::Run(MeFunction *func, MeFuncResultMgr *m) { LogInfo::MapleLogger() << "\n==============after meemit =============" << std::endl; func->mirFunc->Dump(); LogInfo::MapleLogger() << "\nRC operations do not need locking" << std::endl; - for (BB *bb : func->bbVec) { + for (BB *bb : func->theCFG->bbVec) { if (bb == nullptr) { continue; } diff --git a/mapleall/maple_me/src/me_fsaa.cpp b/mapleall/maple_me/src/me_fsaa.cpp index 8167369446068e8d3d40154153bc807a33e921e3..de9f76e3bc0f89b259c0771bf5ea8be4af098505 100644 --- a/mapleall/maple_me/src/me_fsaa.cpp +++ b/mapleall/maple_me/src/me_fsaa.cpp @@ -141,34 +141,34 @@ void FSAA::ProcessBB(BB *bb) { } AnalysisResult *MeDoFSAA::Run(MeFunction *func, MeFuncResultMgr *m) { - SSATab *ssaTab = static_cast(m->GetAnalysisResult(MeFuncPhase_SSATAB, func)); + SSATab *ssaTab = static_cast(m->GetAnalysisResult(MeFuncPhase_SSATAB, func, !MeOption::quiet)); ASSERT(ssaTab != nullptr, "ssaTab phase has problem"); - Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); + MeSSA *ssa = static_cast(m->GetAnalysisResult(MeFuncPhase_SSA, func, !MeOption::quiet)); + ASSERT(ssa != nullptr, "ssa phase has problem"); + + Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func, !MeOption::quiet)); ASSERT(dom != nullptr, "dominance phase has problem"); FSAA fsaa(func, dom); - for (BB *bb : func->bbVec) { + for (BB *bb : func->theCFG->bbVec) { if (bb != nullptr) { fsaa.ProcessBB(bb); } } if (fsaa.needUpdateSSA) { - MemPool *ssamp = mempoolctrler.NewMemPool(PhaseName().c_str()); - MeSSA ssa(func, ssaTab, dom, ssamp); - ssa.runRenameOnly = true; + ssa->runRenameOnly = true; - ssa.InitRenameStack(&ssaTab->originalStTable, func->bbVec.size(), ssaTab->versionStTable); + ssa->InitRenameStack(&ssaTab->originalStTable, func->theCFG->bbVec.size(), ssaTab->versionStTable); // recurse down dominator tree in pre-order traversal - MapleSet *children = &dom->domChildren[func->commonEntryBB->id.idx]; + MapleSet *children = &dom->domChildren[func->theCFG->commonEntryBB->id.idx]; for (BBId child : *children) { - ssa.RenameBB(func->bbVec[child.idx]); + ssa->RenameBB(func->theCFG->bbVec[child.idx]); } - mempoolctrler.DeleteMemPool(ssamp); - ssa.VerifySSA(); + ssa->VerifySSA(); if (DEBUGFUNC(func)) { func->DumpFunction(); diff --git a/mapleall/maple_me/src/me_function.cpp b/mapleall/maple_me/src/me_function.cpp index 9bb6672352935cfeb96801f514b39e977ad95780..c47e8c25b0329e01d161eb95f5fe0885d0dfc801 100644 --- a/mapleall/maple_me/src/me_function.cpp +++ b/mapleall/maple_me/src/me_function.cpp @@ -37,36 +37,18 @@ MeIRMap *g_irmap = nullptr; SSATab *g_ssatab = nullptr; #endif -void MeFunction::PartialInit(bool issecondpass) { - theCFG = nullptr; - irMap = nullptr; - - regNum = 0; - hasEH = false; - secondPass = issecondpass; - maple::ConstantFold cf(&mirModule); - cf.Simplify(mirModule.CurFunction()->body); - if (JAVALANG && (mirModule.CurFunction()->info.size() > 0)) { - std::string string("INFO_registers"); - GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(string); - regNum = mirModule.CurFunction()->GetInfo(strIdx); - std::string trynum("INFO_tries_size"); - strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(trynum); - uint32 num = mirModule.CurFunction()->GetInfo(strIdx); - hasEH = (num != 0); - } -} - void MeFunction::DumpFunction() { - for (BB *bb : bbVec) { + for (BB *bb : theCFG->bbVec) { if (bb == nullptr) { continue; } bb->DumpHeader(&mirModule); MapleMap::iterator phiIt; - for (phiIt = bb->phiList.begin(); phiIt != bb->phiList.end(); phiIt++) { - (*phiIt).second.Dump(&mirModule); + if (bb->phiList) { + for (phiIt = bb->phiList->begin(); phiIt != bb->phiList->end(); phiIt++) { + (*phiIt).second.Dump(&mirModule); + } } for (auto stmt : bb->stmtNodeList) { @@ -76,14 +58,14 @@ void MeFunction::DumpFunction() { } void MeFunction::DumpFunctionNoSSA() { - for (BB *bb : bbVec) { + for (BB *bb : theCFG->bbVec) { if (bb == nullptr) { continue; } bb->DumpHeader(&mirModule); MapleMap::iterator phiIt; - for (phiIt = bb->phiList.begin(); phiIt != bb->phiList.end(); phiIt++) { + for (phiIt = bb->phiList->begin(); phiIt != bb->phiList->end(); phiIt++) { (*phiIt).second.Dump(&mirModule); } @@ -94,7 +76,7 @@ void MeFunction::DumpFunctionNoSSA() { } void MeFunction::DumpMeFunc() { - for (BB *bb : bbVec) { + for (BB *bb : theCFG->bbVec) { if (bb == nullptr) { continue; } @@ -108,7 +90,7 @@ void MeFunction::DumpMeFunc() { } void MeFunction::DumpMayDUFunction() { - for (BB *bb : bbVec) { + for (BB *bb : theCFG->bbVec) { if (bb == nullptr) { continue; } @@ -138,10 +120,10 @@ void MeFunction::SetTryBlockInfo(StmtNode *javatryStmt, BB *lastjavatryBb, const if (nextstmt->op == OP_endtry) { curbb->isTryEnd = true; ASSERT(lastjavatryBb != nullptr, ""); - endTryBB2TryBB[curbb] = lastjavatryBb; + theCFG->endTryBB2TryBB[curbb] = lastjavatryBb; } else { newbb->isTry = true; - bbTryNodeMap[newbb] = javatryStmt; + theCFG->bbTryNodeMap[newbb] = javatryStmt; } } @@ -167,24 +149,28 @@ BaseNode *CreateDummyReturnValue(MIRBuilder *mirBuilder, MIRType *retty) { return nullptr; } -void MeFunction::CreateBasicBlocks() { - if (mirModule.CurFunction()->IsEmpty()) { +void MeFunction::CreateBasicBlocks(MirCFG *cfg) { + if (mirFunc->IsEmpty()) { if (!MeOption::quiet) { LogInfo::MapleLogger() << "function is empty, cfg is nullptr\n"; } return; } /* create common_entry/exit bb first as bbVec[0] and bbVec[1] */ - commonEntryBB = NewBasicBlock(); - commonEntryBB->isEntry = true; - commonExitBB = NewBasicBlock(); - commonExitBB->isExit = true; - - first_bb_ = NewBasicBlock(); - first_bb_->isEntry = true; - StmtNode *nextstmt = mirModule.CurFunction()->body->GetFirst(); + cfg->commonEntryBB = NewBasicBlock(); + cfg->commonEntryBB->isEntry = true; + cfg->commonExitBB = NewBasicBlock(); + cfg->commonExitBB->isExit = true; + + cfg->first_bb = NewBasicBlock(); + cfg->first_bb->isEntry = true; + StmtNode *nextstmt = mirFunc->body->GetFirst(); ASSERT(nextstmt != nullptr, "function has no statement"); - BB *curbb = first_bb_; + BB *curbb = cfg->first_bb; + if (nextstmt->op == OP_label) { // create empty BB before the entry label + curbb->kind = kBBFallthru; + curbb = NewBasicBlock(); + } std::stack tryStmtStack; std::stack tryBBStack; // bb containing javatry_stmt do { @@ -307,7 +293,7 @@ void MeFunction::CreateBasicBlocks() { curbb->kind = kBBFallthru; } curbb->isTryEnd = true; - endTryBB2TryBB[curbb] = tryBBStack.top(); + cfg->endTryBB2TryBB[curbb] = tryBBStack.top(); curbb = NewBasicBlock(); } else { // endtry has already been processed in SetTryBlockInfo() for java @@ -315,7 +301,7 @@ void MeFunction::CreateBasicBlocks() { // create the empty BB curbb->kind = kBBFallthru; curbb->isTryEnd = true; - endTryBB2TryBB[curbb] = tryBBStack.top(); + cfg->endTryBB2TryBB[curbb] = tryBBStack.top(); curbb = NewBasicBlock(); } } @@ -344,7 +330,7 @@ void MeFunction::CreateBasicBlocks() { tryBBStack.push(curbb); curbb->isTry = true; if (JAVALANG) { - bbTryNodeMap[curbb] = tryStmtStack.top(); + 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 // assignments before the try block as exceptions might occur. @@ -443,12 +429,22 @@ void MeFunction::CreateBasicBlocks() { if (!tryStmtStack.empty()) { newbb->isTry = true; if (JAVALANG) { - bbTryNodeMap[newbb] = tryStmtStack.top(); + cfg->bbTryNodeMap[newbb] = tryStmtStack.top(); + } + } + curbb = newbb; + } else if (lfoFunc && lfoFunc->label2WhileInfo.find(labidx) != lfoFunc->label2WhileInfo.end()) { + curbb->kind = kBBFallthru; + BB *newbb = NewBasicBlock(); + if (!tryStmtStack.empty()) { + newbb->isTry = true; + if (JAVALANG) { + cfg->bbTryNodeMap[newbb] = tryStmtStack.top(); } } curbb = newbb; } - labelBBIdMap[labidx] = curbb; + cfg->labelBBIdMap[labidx] = curbb; curbb->bbLabel = labidx; break; } @@ -493,95 +489,29 @@ void MeFunction::CreateBasicBlocks() { } while (nextstmt); ASSERT(tryStmtStack.empty(), "CreateBasicBlcoks: missing endtry"); ASSERT(tryBBStack.empty(), "CreateBasicBlocks: javatry and endtry should be one-to-one mapping"); - last_bb_ = curbb; - if (last_bb_->IsEmpty() || last_bb_->kind == kBBUnknown) { + cfg->last_bb = curbb; + if (cfg->last_bb->IsEmpty() || cfg->last_bb->kind == kBBUnknown) { // insert a return statement MIRType *retty = mirModule.CurFunction()->GetReturnType(); BaseNode *retOpnd = CreateDummyReturnValue(mirModule.mirBuilder, retty); - last_bb_->stmtNodeList.push_back(mirModule.mirBuilder->CreateStmtReturn(retOpnd)); - last_bb_->isExit = true; - last_bb_->kind = kBBReturn; + cfg->last_bb->stmtNodeList.push_back(mirModule.mirBuilder->CreateStmtReturn(retOpnd)); + cfg->last_bb->isExit = true; + cfg->last_bb->kind = kBBReturn; } return; } -void MeFunction::Prepare(unsigned long rangeNum) { - if (!MeOption::quiet) - LogInfo::MapleLogger() << "---Preparing Function < " << mirModule.CurFunction()->GetName() << " > [" << rangeNum << "] ---\n"; - /* lower first */ - MIRLower mirlowerer(mirModule, mirModule.CurFunction()); - if (!isLno) { - mirlowerer.SetLowerME(); - mirlowerer.SetLowerExpandArray(); - mirlowerer.LowerFunc(mirModule.CurFunction()); - } - CreateBasicBlocks(); - if (NumBBs() == 0) { - /* there's no basicblock generated */ - return; - } - RemoveEhEdgesInSyncRegion(); - - theCFG = memPool->New(this); - theCFG->BuildMirCFG(); - theCFG->ReplaceWithAssertnonnull(); - theCFG->VerifyLabels(); - theCFG->UnreachCodeAnalysis(); - theCFG->WontExitAnalysis(); - theCFG->Verify(); -} - void MeFunction::Verify() { theCFG->Verify(); theCFG->VerifyLabels(); } BB *MeFunction::NewBasicBlock() { - BB *newbb = memPool->New(&alloc, &versAlloc, BBId(nextBBId++)); - bbVec.push_back(newbb); + BB *newbb = theCFG->cfgAlloc.mp->New(&theCFG->cfgAlloc, BBId(theCFG->nextBBId++)); + theCFG->bbVec.push_back(newbb); return newbb; } -void MeFunction::DeleteBasicBlock(const BB *bb) { - ASSERT(bbVec[bb->id.idx] == bb, ""); - /* update first_bb_ and last_bb if needed */ - if (first_bb_ == bb) { - first_bb_ = NextBB(bb); - } else if (last_bb_ == bb) { - last_bb_ = PrevBB(bb); - } - bbVec.at(bb->id.idx) = nullptr; - return; -} - -/* get next bb in bbVec*/ -BB *MeFunction::NextBB(const BB *bb) { - if (bb->id.idx == bbVec.size() - 1) { - return nullptr; - } - uint32 i = bb->id.idx + 1; - for (; i < bbVec.size(); i++) { - if (bbVec[i] != nullptr) { - return bbVec[i]; - } - } - return nullptr; -} - -/* get prev bb in bbVec*/ -BB *MeFunction::PrevBB(const BB *bb) { - if (bb->id.idx == 0) { - return nullptr; - } - int32 i = bb->id.idx - 1; - for (; i >= 0; i--) { - if (bbVec[i] != nullptr) { - return bbVec[i]; - } - } - return nullptr; -} - /* clone stmtnode in orig bb to newbb */ void MeFunction::CloneBasicBlock(BB *newbb, BB *orig) { if (orig == nullptr || orig->IsEmpty()) { @@ -626,9 +556,9 @@ BB *MeFunction::SplitBB(BB *bb, StmtNode *splitPoint) { bb->kind = kBBFallthru; // Special Case: commonExitBB is orig bb's succ - for (uint32 i = 0; i < commonExitBB->pred.size(); i++) { - if (commonExitBB->pred[i] == bb) { - commonExitBB->pred[i] = newbb; + for (uint32 i = 0; i < theCFG->commonExitBB->pred.size(); i++) { + if (theCFG->commonExitBB->pred[i] == bb) { + theCFG->commonExitBB->pred[i] = newbb; break; } } @@ -645,7 +575,7 @@ BB *MeFunction::SplitBB(BB *bb, StmtNode *splitPoint) { // Setup flags newbb->CopyFlagsAfterSplit(bb); newbb->isTryEnd = bb->isTryEnd; - endTryBB2TryBB[newbb] = endTryBB2TryBB[bb]; + theCFG->endTryBB2TryBB[newbb] = theCFG->endTryBB2TryBB[bb]; bb->isExit = false; bb->isTryEnd = false; return newbb; @@ -657,10 +587,10 @@ void MeFunction::CreateBBLabel(BB *bb) { return; } - LabelIdx label = mirModule.CurFunction()->labelTab->CreateLabelWithPrefix('m'); - mirModule.CurFunction()->labelTab->AddToStringLabelMap(label); + LabelIdx label = mirFunc->labelTab->CreateLabelWithPrefix('m'); + mirFunc->labelTab->AddToStringLabelMap(label); bb->bbLabel = label; - labelBBIdMap.insert(make_pair(label, bb)); + theCFG->labelBBIdMap.insert(make_pair(label, bb)); } // Recognize the following kind of simple pattern and remove corresponding EH edges @@ -670,11 +600,11 @@ void MeFunction::CreateBBLabel(BB *bb) { // endtry // throw (dread ptr %Reg0_R524935) void MeFunction::RemoveEhEdgesInSyncRegion() { - if (endTryBB2TryBB.size() != 1) { + if (theCFG->endTryBB2TryBB.size() != 1) { return; } - for (auto iter : endTryBB2TryBB) { + for (auto iter : theCFG->endTryBB2TryBB) { BB *tryBB = iter.second; BB *endtryBB = iter.first; // Filter out complex cases @@ -682,7 +612,7 @@ void MeFunction::RemoveEhEdgesInSyncRegion() { !endtryBB->IsJavaFinally() || endtryBB->stmtNodeList.last->op != OP_syncexit || (tryBB->stmtNodeList.last->op != OP_javatry && tryBB->stmtNodeList.last->op != OP_try)) { return; } - for (auto it : bbTryNodeMap) { + for (auto it : theCFG->bbTryNodeMap) { BB *bb = it.first; if (bb != tryBB && bb != endtryBB) { for (auto stmt : bb->stmtNodeList) { @@ -695,7 +625,7 @@ void MeFunction::RemoveEhEdgesInSyncRegion() { } // Unmark unnecessary isTry flags - for (auto it : bbTryNodeMap) { + for (auto it : theCFG->bbTryNodeMap) { BB *bb = it.first; if (bb != tryBB && bb != endtryBB) { bb->isTry = false; diff --git a/mapleall/maple_me/src/me_hdse.cpp b/mapleall/maple_me/src/me_hdse.cpp index cc3d725b8b094b44d736a4c8a4b088241c6c0d59..0086aa3ef524a3ddf78b46a61b6f0ae6902c67da 100644 --- a/mapleall/maple_me/src/me_hdse.cpp +++ b/mapleall/maple_me/src/me_hdse.cpp @@ -57,12 +57,12 @@ namespace maple { void MeHDSE::DseInit() { // Init bb's required flag bb_required.resize(0); - bb_required.resize(func->bbVec.size(), false); - if (func->commonEntryBB != func->first_bb_) { - bb_required[func->commonEntryBB->id.idx] = true; + bb_required.resize(func->theCFG->bbVec.size(), false); + if (func->theCFG->commonEntryBB != func->theCFG->first_bb) { + bb_required[func->theCFG->commonEntryBB->id.idx] = true; } - if (func->commonExitBB != func->last_bb_) { - bb_required[func->commonExitBB->id.idx] = true; + if (func->theCFG->commonExitBB != func->theCFG->last_bb) { + bb_required[func->theCFG->commonExitBB->id.idx] = true; } // Init all MeExpr to be dead; @@ -75,7 +75,7 @@ void MeHDSE::DseInit() { void MeHDSE::DseInitFull() { DseInit(); - for (BB *bb : func->bbVec) { + for (BB *bb : func->theCFG->bbVec) { if (bb == nullptr) { continue; } @@ -108,6 +108,15 @@ void MeHDSE::DseInitFull() { } } +void MeHDSE::ProcessWhileInfos() { + MapleMap::iterator it = func->lfoFunc->label2WhileInfo.begin(); + for ( ; it != func->lfoFunc->label2WhileInfo.end(); it++) { + if (it->second->initExpr != nullptr) { + worklist.push_front(it->second->initExpr); + } + } +} + void MeHDSE::DetermineUseCounts(MeExpr *x) { if (x->meOp == kMeOpVar) { VarMeExpr *varmeexpr = static_cast(x); @@ -245,7 +254,7 @@ void MeHDSE::BackwardSubstitution() { } void MeDohDSE::MakeEmptyTrysUnreachable(MeFunction *func) { - MapleVector &bbVec = func->bbVec; + MapleVector &bbVec = func->theCFG->bbVec; for (uint32_t i = 0; i < bbVec.size(); i++) { BB *trybb = bbVec[i]; if (trybb != nullptr && trybb->isTry && trybb->meStmtList.first != nullptr && @@ -330,9 +339,9 @@ void MeDohDSE::MakeEmptyTrysUnreachable(MeFunction *func) { } AnalysisResult *MeDohDSE::Run(MeFunction *func, MeFuncResultMgr *m) { - Dominance *pdom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); + Dominance *pdom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func, !MeOption::quiet)); - MeIRMap *hmap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func)); + MeIRMap *hmap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func, !MeOption::quiet)); ASSERT(hmap != nullptr, "hssamap is nullptr"); MeHDSE hdse(func, pdom, hmap); @@ -350,6 +359,7 @@ AnalysisResult *MeDohDSE::Run(MeFunction *func, MeFuncResultMgr *m) { func->theCFG->UnreachCodeAnalysis(/* update_phi = */ true); func->theCFG->WontExitAnalysis(); m->InvalidAnalysisResult(MeFuncPhase_DOMINANCE, func); + m->InvalidAnalysisResult(MeFuncPhase_IDENTLOOPS, func); if (DEBUGFUNC(func)) { LogInfo::MapleLogger() << "\n============== HDSE =============" << std::endl; hmap->Dump(); diff --git a/mapleall/maple_me/src/me_hti.cpp b/mapleall/maple_me/src/me_hti.cpp index 3ac22dd7ff539526b0401ab3fb3fb78dcb8b2026..5a16e030f4cd0a0c93f90291ae27b11ef0a4038b 100644 --- a/mapleall/maple_me/src/me_hti.cpp +++ b/mapleall/maple_me/src/me_hti.cpp @@ -374,7 +374,7 @@ void MeTI::BuildUseAndFindMustNotInfersFromStmt(MeStmt *stmt) { // this is the only time we traverse the program code void MeTI::BuildUseListsAndFindMustNotInfers() { - for (BB *bb : func->bbVec) { + for (BB *bb : func->theCFG->bbVec) { if (bb == nullptr) { continue; } @@ -981,7 +981,7 @@ MeStmt *MeTI::CreateDassign(MeExpr *lhs, MeExpr *rhs, uint32_t fieldId, BBId bbI DassignMeStmt *mestmt = module->memPool->New(&irMap->irMapAlloc, stmt); mestmt->rhs = rhs; mestmt->UpdateLhs(var); - mestmt->bb = func->bbVec.at(bbId.idx); + mestmt->bb = func->theCFG->bbVec[bbId.idx]; return mestmt; } @@ -1628,7 +1628,7 @@ void MeTI::TypeInfer() { DumpStatus(); // rebuild BBs via preorder traversal of the dominator tree for (BBId bbid : dom->dtPreOrder) { - RebuildBB(func->bbVec[bbid.idx]); + RebuildBB(func->theCFG->bbVec[bbid.idx]); } if (DEBUGFUNC(func)) { LogInfo::MapleLogger() << "\n============== TypeInference =============" << endl; @@ -1637,9 +1637,9 @@ void MeTI::TypeInfer() { } AnalysisResult *MeDohTI::Run(MeFunction *func, MeFuncResultMgr *m) { - Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); + Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func, !MeOption::quiet)); - MeIRMap *hmap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func)); + MeIRMap *hmap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func, !MeOption::quiet)); ASSERT(hmap != nullptr, "hssamap is nullptr"); MemPool *timp = mempoolctrler.NewMemPool(PhaseName().c_str()); diff --git a/mapleall/maple_me/src/me_ident_loops.cpp b/mapleall/maple_me/src/me_ident_loops.cpp index 881e1e38cfef8496a4230dacc1e37dadcb95ff6d..d9ccf862b05673cd4df07bf946cc54efd1717b69 100644 --- a/mapleall/maple_me/src/me_ident_loops.cpp +++ b/mapleall/maple_me/src/me_ident_loops.cpp @@ -24,12 +24,6 @@ namespace maple { -LoopDesc *IdentifyLoops::CreateLoopDesc(BB *hd, BB *tail) { - LoopDesc *newloop = meloop_mp->New(&meloop_alloc, hd, tail); - meloops.push_back(newloop); - return newloop; -} - void IdentifyLoops::SetLoopParent4BB(const BB *bb, LoopDesc *aloop) { if (bbloopparent[bb->id.idx] != nullptr) { if (aloop->parent == nullptr) { @@ -40,15 +34,45 @@ void IdentifyLoops::SetLoopParent4BB(const BB *bb, LoopDesc *aloop) { bbloopparent[bb->id.idx] = aloop; } +void IdentifyLoops::SetLoopEntry(LoopDesc *aloop) { + BB *headBB = aloop->head; + // the entry BB is the predecessor of headBB that dominates headBB + MapleVector::iterator predit = headBB->pred.begin(); + for ( ; predit != headBB->pred.end(); predit++) { + if (dominance->Dominate(*predit, headBB)) + break; + } + if (predit == headBB->pred.end()) { + return; // not a well-formed loop + } + aloop->entry = *predit; +} + +void IdentifyLoops::SetExitBB(LoopDesc *aloop) { + BB *headBB = aloop->head; + // the exit BB is the succeessor of headBB that does not belong to the loop + if (headBB->succ.size() != 2) { + return; + } + if (aloop->loop_bbs.count(headBB->succ[0]->id) != 1) { + aloop->exitBB = headBB->succ[0]; + aloop->startbodyBB = headBB->succ[1]; + } else { + aloop->exitBB = headBB->succ[1]; + aloop->startbodyBB = headBB->succ[0]; + } +} + // process each BB in preorder traversal of dominator tree void IdentifyLoops::ProcessBB(BB *bb) { - if (bb == nullptr || bb == func->commonExitBB) { + if (bb == nullptr || bb == func->theCFG->commonExitBB) { return; } for (BB *pred : bb->pred) { if (dominance->Dominate(bb, pred)) { // create a loop with bb as loop head and pred as loop tail - LoopDesc *aloop = CreateLoopDesc(bb, pred); + LoopDesc *aloop = alloc.mp->New(&alloc, bb, pred); + meloops.push_back(aloop); std::list bodylist; bodylist.push_back(pred); while (!bodylist.empty()) { @@ -66,13 +90,15 @@ void IdentifyLoops::ProcessBB(BB *bb) { } aloop->loop_bbs.insert(bb->id); SetLoopParent4BB(bb, aloop); + SetLoopEntry(aloop); + SetExitBB(aloop); } } // recursive call MapleSet *domChildren = &dominance->domChildren[bb->id.idx]; for (MapleSet::iterator bbit = domChildren->begin(); bbit != domChildren->end(); bbit++) { - ProcessBB(func->bbVec.at(bbit->idx)); + ProcessBB(func->theCFG->bbVec.at(bbit->idx)); } } @@ -91,12 +117,12 @@ void IdentifyLoops::Dump() { } } -AnalysisResult *MeDoMeLoop::Run(MeFunction *func, MeFuncResultMgr *m) { - Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); +AnalysisResult *MeDoIdentLoops::Run(MeFunction *func, MeFuncResultMgr *m) { + Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func, !MeOption::quiet)); CHECK_FATAL(dom, "dominance phase has problem"); MemPool *meloopmp = mempoolctrler.NewMemPool(PhaseName().c_str()); IdentifyLoops *identloops = meloopmp->New(meloopmp, func, dom); - identloops->ProcessBB(func->commonEntryBB); + identloops->ProcessBB(func->theCFG->commonEntryBB); if (DEBUGFUNC(func)) { identloops->Dump(); } diff --git a/mapleall/maple_me/src/me_ir.cpp b/mapleall/maple_me/src/me_ir.cpp index 30b0a6b7ae0a0f0a49be08c7c863594e537d2ec9..52b85f9e245d36883da87912291af066ea60e459 100644 --- a/mapleall/maple_me/src/me_ir.cpp +++ b/mapleall/maple_me/src/me_ir.cpp @@ -530,7 +530,7 @@ void MePhiNode::Dump(IRMap *irMap) { LogInfo::MapleLogger() << "VAR:"; ost->Dump(); } else { - PregIdx16 regId = static_cast(lhs)->regIdx; + PregIdx16 regId = static_cast(lhs)->GetPregIdx(); LogInfo::MapleLogger() << "REGVAR: " << regId; LogInfo::MapleLogger() << "(%" << irMap->mirModule->CurFunction()->pregTab->PregFromPregIdx(static_cast(regId))->pregNo @@ -562,8 +562,8 @@ void VarMeExpr::Dump(IRMap *irMap, int32 indent) { } void RegMeExpr::Dump(IRMap *irMap, int32 indent) { - LogInfo::MapleLogger() << "REGINDX:" << regIdx; - LogInfo::MapleLogger() << " %" << irMap->mirModule->CurFunction()->pregTab->PregFromPregIdx(static_cast(regIdx))->pregNo; + LogInfo::MapleLogger() << "REGINDX:" << GetPregIdx(); + LogInfo::MapleLogger() << " %" << irMap->mirModule->CurFunction()->pregTab->PregFromPregIdx(static_cast(GetPregIdx()))->pregNo; LogInfo::MapleLogger() << " mx" << exprID; } @@ -629,7 +629,7 @@ void FieldsDistMeExpr::Dump(IRMap *irMap, int32 indent) { void AddrofMeExpr::Dump(IRMap *irMap, int32 indent) { LogInfo::MapleLogger() << "ADDROF:"; irMap->ssaTab->GetOriginalStFromid(ostIdx)->Dump(); - LogInfo::MapleLogger() << " (field)" << fieldID; + LogInfo::MapleLogger() << " (field)" << irMap->ssaTab->GetOriginalStFromid(ostIdx)->fieldID; LogInfo::MapleLogger() << " mx" << exprID; } @@ -1209,7 +1209,7 @@ bool MeExpr::IsJavaMerge() { } if (naryx->GetOpnd(0)->meOp == kMeOpReg) { RegMeExpr *r = static_cast(naryx->GetOpnd(0)); - return r->regIdx >= 0; + return r->GetPregIdx() >= 0; } return false; } @@ -1228,7 +1228,7 @@ bool MeExpr::PointsToSomethingThatNeedsIncref() { } if (meOp == kMeOpReg) { RegMeExpr *r = static_cast(this); - return r->regIdx != -kSregThrownval; + return r->GetPregIdx() != -kSregThrownval; } return false; } diff --git a/mapleall/maple_me/src/me_irmap.cpp b/mapleall/maple_me/src/me_irmap.cpp index 8b1d70e6e5752fce7ac79241f60b6925f99d3bd3..68481bb3532bb01b2a3f0260d087559f599a7c9d 100644 --- a/mapleall/maple_me/src/me_irmap.cpp +++ b/mapleall/maple_me/src/me_irmap.cpp @@ -27,7 +27,7 @@ void MeIRMap::Dump() { MemPool *backup = mirfunction->codeMemPool; mirfunction->SetMemPool(mempoolctrler.NewMemPool("IR Dump")); LogInfo::MapleLogger() << "===================Me IR dump==================\n"; - for (BB *bb : mirFunc->bbVec) { + for (BB *bb : mirFunc->theCFG->bbVec) { if (bb == nullptr) { continue; } diff --git a/mapleall/maple_me/src/me_irmap_build.cpp b/mapleall/maple_me/src/me_irmap_build.cpp index 03d37368208e7ada1ac7ea1a60505156be9fb846..19fdb1f568c57f65efcfae181426370f84e306b8 100644 --- a/mapleall/maple_me/src/me_irmap_build.cpp +++ b/mapleall/maple_me/src/me_irmap_build.cpp @@ -15,15 +15,29 @@ #include "me_irmap_build.h" #include "irmap_build.h" +#include "me_ssa.h" #include "me_prop.h" +#include "me_alias_class.h" +#include "me_dse.h" // This phase converts Maple IR to MeIR. namespace maple { AnalysisResult *MeDoIrMapBuild::Run(MeFunction *func, MeFuncResultMgr *m) { - Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); + MirCFG *cfg = static_cast(m->GetAnalysisResult(MeFuncPhase_CFGBUILD, func, !MeOption::quiet)); + ASSERT(cfg != nullptr, "cfgbuild phase has problem"); + SSATab *ssatab = static_cast(m->GetAnalysisResult(MeFuncPhase_SSATAB, func, !MeOption::quiet)); + CHECK_FATAL(ssatab, "ssatab phase has problem"); + MeAliasClass *aliasclass = static_cast(m->GetAnalysisResult(MeFuncPhase_ALIASCLASS, func, !MeOption::quiet)); + ASSERT(aliasclass != nullptr, "aliasclass phase has problem"); + MeSSA *ssa = static_cast(m->GetAnalysisResult(MeFuncPhase_SSA, func, !MeOption::quiet)); + CHECK_FATAL(ssa, "ssa phase has problem"); + MeDSE *dse = static_cast(m->GetAnalysisResult(MeFuncPhase_DSE, func, !MeOption::quiet)); + CHECK_FATAL(dse, "dse phase has problem"); + Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func, !MeOption::quiet)); CHECK_FATAL(dom, "dominance phase has problem"); + MemPool *irmapmp = mempoolctrler.NewMemPool(PhaseName().c_str()); MemPool *tempmp = mempoolctrler.NewMemPool("meirmap temporaries"); @@ -36,8 +50,8 @@ AnalysisResult *MeDoIrMapBuild::Run(MeFunction *func, MeFuncResultMgr *m) { MemPool *propMp = mempoolctrler.NewMemPool("meirbuild prop"); MeProp meprop(irMap, dom, propMp, false, false, false, false, false, false); IrMapBuild irmapbuild(irMap, &meprop); - std::vector bbIrmapProcessed(func->NumBBs(), false); - irmapbuild.BuildBB(func->commonEntryBB, bbIrmapProcessed); + std::vector bbIrmapProcessed(func->theCFG->NumBBs(), false); + irmapbuild.BuildBB(func->theCFG->commonEntryBB, bbIrmapProcessed); if (DEBUGFUNC(func)) { irMap->Dump(); } @@ -49,19 +63,23 @@ AnalysisResult *MeDoIrMapBuild::Run(MeFunction *func, MeFuncResultMgr *m) { MIRFunction *mirFunc = func->mirFunc; mempoolctrler.DeleteMemPool(mirFunc->codeMemPool); mirFunc->codeMemPool = nullptr; + // delete versionst_table // nullify all references to the versionst_table contents for (uint32 i = 0; i < func->meSSATab->versionStTable.versionStVector.size(); i++) { func->meSSATab->versionStTable.versionStVector[i] = nullptr; } // clear BB's phiList which uses versionst; nullify first_stmt_, last_stmt_ - for (BB *bb : func->bbVec) { + for (BB *bb : func->theCFG->bbVec) { if (bb == nullptr) { continue; } - bb->phiList.clear(); + bb->phiList->clear(); + bb->phiList = nullptr; bb->stmtNodeList.clear(); } + m->InvalidAnalysisResult(MeFuncPhase_SSA, func); + m->InvalidAnalysisResult(MeFuncPhase_DSE, func); mempoolctrler.DeleteMemPool(func->meSSATab->vers_mp); mempoolctrler.DeleteMemPool(propMp); return irMap; diff --git a/mapleall/maple_me/src/me_loop_canon.cpp b/mapleall/maple_me/src/me_loop_canon.cpp index 0eba35b8789dd8d2f6ea0aede19ece24a4c81eca..6f09cd5744cba7e35b803464800aea3151fdfd56 100644 --- a/mapleall/maple_me/src/me_loop_canon.cpp +++ b/mapleall/maple_me/src/me_loop_canon.cpp @@ -194,13 +194,13 @@ void MeDoLoopCanon::Convert(MeFunction *func, BB *bb, BB *pred, MapleMap(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); + Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func, !MeOption::quiet)); CHECK_FATAL(dom != nullptr, "dom is null in MeDoLoopCanon::Run"); // set MirCFG's hasDoWhile flag MirCFG *cfg = func->theCFG; - for (BB *bb : func->bbVec) { - if (bb == nullptr || bb == func->commonEntryBB || bb == func->commonExitBB) { + for (BB *bb : cfg->bbVec) { + if (bb == nullptr || bb == cfg->commonEntryBB || bb == cfg->commonExitBB) { continue; } if (bb->kind != kBBCondGoto) { @@ -229,15 +229,15 @@ AnalysisResult *MeDoLoopCanon::Run(MeFunction *func, MeFuncResultMgr *m) { MapleMap swapSuccs(std::less(), localAlloc.Adapter()); /* collect backedge first: if bb dominator its pred, then the edge pred->bb is a backedge */ - for (BB *bb : func->bbVec) { - if (bb == nullptr || bb == func->commonEntryBB || bb == func->commonExitBB) { + for (BB *bb : cfg->bbVec) { + if (bb == nullptr || bb == cfg->commonEntryBB || bb == cfg->commonExitBB) { continue; } MapleVector &preds = bb->pred; for (BB *pred : preds) { - ASSERT(func->commonEntryBB && pred, ""); + ASSERT(cfg->commonEntryBB && pred, ""); /* bb is reachable from entry && bb dominator pred */ - if (dom->Dominate(func->commonEntryBB, bb) && dom->Dominate(bb, pred) && !pred->wontExit && + if (dom->Dominate(cfg->commonEntryBB, bb) && dom->Dominate(bb, pred) && !pred->wontExit && (NeedConvert(func, bb, pred, localAlloc, swapSuccs))) { if (DEBUGFUNC(func)) { LogInfo::MapleLogger() << "find backedge " << bb->id.idx << " <-- " << pred->id.idx << endl; diff --git a/mapleall/maple_me/src/me_lower_globals.cpp b/mapleall/maple_me/src/me_lower_globals.cpp index a0fc0e248ea1ed11ba89c50a82fc45950baa909f..f7f6054fcd6a76d7aa2fa76c0cd7dae49350762b 100644 --- a/mapleall/maple_me/src/me_lower_globals.cpp +++ b/mapleall/maple_me/src/me_lower_globals.cpp @@ -68,10 +68,10 @@ void LowerGlobals::LowerGlobalDreads(MeStmt *stmt, MeExpr *x) { } case kMeOpAddrof: { AddrofMeExpr *theaddrof = static_cast(x); - if (theaddrof->fieldID == 0) { + OriginalSt *ost = ssaTab->GetOriginalStFromid(theaddrof->ostIdx); + if (ost->fieldID == 0) { break; } - OriginalSt *ost = ssaTab->GetSymbolOriginalStFromid(theaddrof->ostIdx); if (ost->isLocal) { break; } @@ -80,7 +80,6 @@ void LowerGlobals::LowerGlobalDreads(MeStmt *stmt, MeExpr *x) { (FieldID)0); AddrofMeExpr addrofmeexpr(-1, PTY_ptr, baseost->index); - addrofmeexpr.fieldID = 0; AddrofMeExpr *newaddrof = static_cast(irMap->HashMeExpr(&addrofmeexpr)); MIRPtrType pointtype(baseost->tyIdx, PTY_ptr); @@ -88,7 +87,7 @@ void LowerGlobals::LowerGlobalDreads(MeStmt *stmt, MeExpr *x) { OpMeExpr iaddrof(-1, OP_iaddrof, PTY_ptr, 1); iaddrof.tyIdx = addrtyidx; - iaddrof.fieldID = theaddrof->fieldID; + iaddrof.fieldID = ost->fieldID; iaddrof.SetOpnd(newaddrof, 0); OpMeExpr *theiaddrof = static_cast(irMap->HashMeExpr(&iaddrof)); @@ -102,7 +101,7 @@ void LowerGlobals::LowerGlobalDreads(MeStmt *stmt, MeExpr *x) { } void LowerGlobals::Run() { - for (BB *bb : func->bbVec) { + for (BB *bb : func->theCFG->bbVec) { if (bb == nullptr) { continue; } diff --git a/mapleall/maple_me/src/me_may_to_dassign.cpp b/mapleall/maple_me/src/me_may_to_dassign.cpp index 301c758e5fe88b3e0d1a00405dc12178886833d4..838c0b0d8d2bf693777bd887faec27be4cb97cea 100644 --- a/mapleall/maple_me/src/me_may_to_dassign.cpp +++ b/mapleall/maple_me/src/me_may_to_dassign.cpp @@ -22,7 +22,7 @@ namespace maple { bool May2Dassign::Doit() { bool changed = false; - for (BB *bb : func->bbVec) { + for (BB *bb : func->theCFG->bbVec) { if (bb == nullptr) { continue; } @@ -48,6 +48,11 @@ bool May2Dassign::Doit() { } AnalysisResult *MeDoMay2Dassign::Run(MeFunction *func, MeFuncResultMgr *m) { + MirCFG *cfg = static_cast(m->GetAnalysisResult(MeFuncPhase_CFGBUILD, func, !MeOption::quiet)); + ASSERT(cfg != nullptr, "cfgbuild phase has problem"); + MeIRMap *irMap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func, !MeOption::quiet)); + ASSERT(irMap != nullptr, "irmapbuild phase has problem"); + May2Dassign may2dassign(func); may2dassign.Doit(); diff --git a/mapleall/maple_me/src/me_phase_manager.cpp b/mapleall/maple_me/src/me_phase_manager.cpp index e92288e152e9c6ec7f5b656e6f5aff37869ef6c7..cd7010fe1bedce9019d96f9c8712957004fc54fc 100644 --- a/mapleall/maple_me/src/me_phase_manager.cpp +++ b/mapleall/maple_me/src/me_phase_manager.cpp @@ -56,6 +56,12 @@ #include "me_fsaa.h" #include "me_sym_rename.h" #include "mpl_timer.h" +#include "constant_fold.h" +#include "mir_lower.h" +#include "lfo_pre_emit.h" +#include "lfo_mir_lower.h" +#include "lfo_inject_iv.h" +#include "lfo_iv_canon.h" using namespace std; @@ -82,7 +88,7 @@ void MeFuncPhaseManager::RunFuncPhase(MeFunction *func, MeFuncPhase *phase) { // 4. run: skip mplme phase except "emit" if no cfg in MeFunction AnalysisResult *r = nullptr; MePhaseID phaseid = phase->GetPhaseId(); - if ((func->NumBBs() > 0) || (phaseid == MeFuncPhase_EMIT) || (phaseid == MeFuncPhase_SSARENAME2PREG)) { + if ((phaseid == MeFuncPhase_CFGBUILD) || (func->theCFG && func->theCFG->NumBBs() > 0) || (phaseid == MeFuncPhase_EMIT)) { r = phase->Run(func, &arFuncManager, modResMgr); } #ifdef DEBUG_TIMER @@ -139,69 +145,70 @@ void MeFuncPhaseManager::AddPhases(const std::unordered_set &skipPh } }; - bool o2 = MeOption::optLevel == 2; - if (mePhaseType == kMePhaseMainopt) { - /* default phase sequence */ - if (o2) { - addPhase("loopcanon"); - addPhase("splitcriticaledge"); - } - addPhase("ssatab"); - addPhase("aliasclass"); - addPhase("ssa"); - addPhase("dse"); - addPhase("fsaa"); - if (JAVALANG) { - // addPhase("bdcopt"); - // addPhase("syncselect"); - // addPhase("ssadevirt"); - // addPhase("ea"); - } - addPhase("hprop"); - addPhase("symrename"); - addPhase("hdse"); - if (JAVALANG) { - addPhase("may2dassign"); - addPhase("condbasednpc"); - } - if (o2 && JAVALANG) { - addPhase("cfgopt"); - } - if (o2) { - addPhase("epre"); - if (JAVALANG) { - addPhase("stmtpre"); - } - } - if (JAVALANG && !MeOption::noRC) { - addPhase("analyzerc"); - if (MeOption::rcLowering) { - addPhase("rclowering"); - } - } - addPhase("rename2preg"); - if (o2) { - addPhase("lpre"); - // addPhase("storepre"); - } - addPhase("emit"); - } else { + bool o2 = MeOption::optLevel >= 2; + bool o3 = MeOption::optLevel >= 3; + /* default phase sequence */ + if (o3) { + addPhase("cfgbuild"); + addPhase("injectiv"); addPhase("ssatab"); addPhase("aliasclass"); addPhase("ssa"); addPhase("dse"); addPhase("irmapbuild"); - addPhase("loopivcan"); + addPhase("ivcanon"); addPhase("hprop"); addPhase("hdse"); - addPhase("lnoemit"); + addPhase("lfopreemit"); +#if 0 addPhase("loopinfo"); if (JAVALANG) { addPhase("lfobdce"); } else { addPhase("autosimd"); } +#endif + } + addPhase("cfgbuild"); + addPhase("ssatab"); + addPhase("aliasclass"); + addPhase("ssa"); + addPhase("dse"); + addPhase("irmapbuild"); + if (JAVALANG) { + addPhase("bdcopt"); + addPhase("syncselect"); + // addPhase("ssadevirt"); + // addPhase("ea"); + } + addPhase("hprop"); + addPhase("symrename"); + addPhase("hdse"); + if (o2 && JAVALANG) { + addPhase("cfgopt"); + } + if (JAVALANG) { + addPhase("may2dassign"); + addPhase("condbasednpc"); } + if (o2) { + addPhase("epre"); + if (JAVALANG) { + addPhase("stmtpre"); + } + } + if (JAVALANG && !MeOption::noRC) { + addPhase("analyzerc"); + if (MeOption::rcLowering) { + addPhase("rclowering"); + } + } + addPhase("rename2preg"); + if (o2) { + addPhase("lpre"); + // addPhase("storepre"); + } + addPhase("emit"); } // match sub string of function name @@ -212,7 +219,7 @@ bool MeFuncPhaseManager::FuncFilter(const string &filter, const std::string &nam return false; } -void MeFuncPhaseManager::RunMainOpt(MIRFunction *mirFunc, uint64 rangenum, const string &meinput) { +void MeFuncPhaseManager::Run(MIRFunction *mirFunc, uint64 rangenum, const string &meinput) { if (!MeOption::quiet) LogInfo::MapleLogger() << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>> Optimizing Function < " << mirFunc->GetName() << " id=" << mirFunc->puIdxOrigin << " >---\n"; @@ -221,16 +228,30 @@ void MeFuncPhaseManager::RunMainOpt(MIRFunction *mirFunc, uint64 rangenum, const LogInfo::MapleLogger() << "Function < " << mirFunc->GetName() << "not optimized because it has setjmp\n"; return; } - MemPool *funcmp = mempoolctrler.NewMemPool("mapleme per-function mempool"); - MemPool *versmp = mempoolctrler.NewMemPool("first verst mempool"); - MeFunction func(&module, mirFunc, funcmp, versmp, meinput, false, mePhaseType == kMePhaseLno); + MemPool *lfomp = nullptr; + MeFunction func(&module, mirFunc, meinput, false, MeOption::optLevel == 3); #if DEBUG g_mirmodule = &module; g_func = &func; #endif - func.Prepare(rangenum); + // call constant folding + maple::ConstantFold cf(&module); + cf.Simplify(mirFunc->body); + + if (!MeOption::quiet) + LogInfo::MapleLogger() << "---Preparing Function < " << module.CurFunction()->GetName() << " > [" << rangenum << "] ---\n"; + if (MeOption::optLevel >= 3) { + lfomp = mempoolctrler.NewMemPool("lfo"); + func.lfoFunc = lfomp->New(lfomp, &func); + LFOMIRLower lfomirlowerer(module, &func); + lfomirlowerer.LowerFunc(mirFunc); + } else { // lower for mainopt + MIRLower mirlowerer(module, mirFunc); + mirlowerer.SetLowerME(); + mirlowerer.SetLowerExpandArray(); + mirlowerer.LowerFunc(mirFunc); + } std::string phaseName; - MeFuncPhase *changecfgphase = nullptr; /* each function level phase */ bool dumpFunc = FuncFilter(MeOption::dumpFunc, func.GetName()); int phaseIndex = 0; @@ -276,64 +297,11 @@ void MeFuncPhaseManager::RunMainOpt(MIRFunction *mirFunc, uint64 rangenum, const --it; --it; // restore iterator to emit } - if (p->IsChangedCFG()) { - changecfgphase = p; - p->ClearChangeCFG(); - break; - } } GetAnalysisResultManager()->InvalidAllResults(); - if (changecfgphase) { - // do all the phases start over - MemPool *versmp2 = mempoolctrler.NewMemPool("second verst mempool"); - MeFunction func2(&module, mirFunc, funcmp, versmp2, meinput, true); - func2.Prepare(rangenum); - for (auto it = PhaseSeqBegin(); it != PhaseSeqEnd(); it++) { - PhaseID id = GetPhaseId(it); - MeFuncPhase *p = static_cast(GetPhase(id)); - CHECK_FATAL(p, "null ptr check "); - if (p == changecfgphase) { - continue; - } - - if (MeOption::skipFrom.compare(p->PhaseName()) == 0) { - // fast-forward to emit pass, which is last pass - while (++it != PhaseSeqEnd()) - ; - --it; // restore iterator - id = GetPhaseId(it); - p = static_cast(GetPhase(id)); - CHECK_FATAL(p, "null ptr check "); - } - - p->SetPreviousPhaseName(phaseName); /* prev phase name is for filename used in emission after phase */ - phaseName = p->PhaseName(); // new phase name - bool dumpPhase = MeOption::DumpPhase(phaseName); - - if (MeOption::dumpBefore && dumpFunc && dumpPhase) { - LogInfo::MapleLogger() << ">>>>>Second time Dump before " << phaseName << " <<<<<\n"; - func2.DumpFunction(); - } - RunFuncPhase(&func2, p); - if (MeOption::dumpAfter && dumpFunc && dumpPhase) { - LogInfo::MapleLogger() << ">>>>>Second time Dump after " << phaseName << " <<<<<\n"; - func2.DumpFunction(); - } - if (MeOption::skipAfter.compare(phaseName) == 0) { - // fast-forward to emit pass, which is last pass - while (++it != PhaseSeqEnd()) - ; - --it; - --it; // restore iterator to emit - } - } - GetAnalysisResultManager()->InvalidAllResults(); + if (MeOption::optLevel >= 3) { + mempoolctrler.DeleteMemPool(lfomp); } - mempoolctrler.DeleteMemPool(funcmp); -} - -void MeFuncPhaseManager::Run(MIRFunction *mirFunc, uint64 rangenum, const string &meinput) { - RunMainOpt(mirFunc, rangenum, meinput); } } // namespace maple diff --git a/mapleall/maple_me/src/me_placement_opt.cpp b/mapleall/maple_me/src/me_placement_opt.cpp index e2d6a692bf0c29cc0e70d75d28986bf075ef127f..51b8be0f99da81e3bf496150b2c4ea4ad3c719f4 100644 --- a/mapleall/maple_me/src/me_placement_opt.cpp +++ b/mapleall/maple_me/src/me_placement_opt.cpp @@ -52,7 +52,7 @@ void PlacementOpt::FormLambdas() { lambda_dfns.clear(); for (uint32 dfn : occur_dfns) { BBId bbid = dominance->pdtPreOrder[dfn]; - BB *bb = func->bbVec[bbid.idx]; + BB *bb = func->theCFG->bbVec[bbid.idx]; GetIterPdomFrontier(bb, &lambda_dfns); } } @@ -61,7 +61,7 @@ void PlacementOpt::FormLambdaRes() { lambdares_dfns.clear(); for (uint32 dfn : lambda_dfns) { BBId bbid = dominance->pdtPreOrder[dfn]; - BB *bb = func->bbVec[bbid.idx]; + BB *bb = func->theCFG->bbVec[bbid.idx]; for (BB *succ : bb->succ) { lambdares_dfns.insert(dominance->pdtDfn[succ->id.idx]); } @@ -156,7 +156,7 @@ void PlacementOpt::CreateSortedOccs() { // initialize lambdaRes vector in each BBLambdaOcc node for (BBLambdaOcc *lambdaOcc : lambda_occs) { - BB *bb = func->bbVec[lambdaOcc->bbid.idx]; + BB *bb = func->theCFG->bbVec[lambdaOcc->bbid.idx]; for (BB *succbb : bb->succ) { lambdaOcc->lambdaRes.push_back(bb2lambdaresMap[succbb->id]); } @@ -167,7 +167,7 @@ void PlacementOpt::RenameOccs() { MapleStack occStack(percand_allocator.Adapter()); for (BBOcc *occ : ordered_occs) { while (!occStack.empty() && - !dominance->Postdominate(func->bbVec[occStack.top()->bbid.idx], func->bbVec[occ->bbid.idx])) { + !dominance->Postdominate(func->theCFG->bbVec[occStack.top()->bbid.idx], func->theCFG->bbVec[occ->bbid.idx])) { occStack.pop(); } switch (occ->occty) { @@ -300,7 +300,7 @@ void PlacementOpt::ComputeCanbeant() { } } // check for critical edge - BB *insertbb = func->bbVec[lmbdares0->bbid.idx]; + BB *insertbb = func->theCFG->bbVec[lmbdares0->bbid.idx]; if (insertbb->pred.size() > 1) { ResetCanbeant(lambdaOcc); has_crit_edge = true; @@ -385,7 +385,7 @@ void PlacementOpt::ComputePlacement(MapleSet *occurbbs) { continue; } } - BB *insertbb = func->bbVec[lambdares0->bbid.idx]; + BB *insertbb = func->theCFG->bbVec[lambdares0->bbid.idx]; CHECK_FATAL(insertbb->pred.size() == 1, "ComputePlacement: cannot insert at critical edge"); inserted_bbs.insert(lambdares0->bbid); } diff --git a/mapleall/maple_me/src/me_predict.cpp b/mapleall/maple_me/src/me_predict.cpp index 90118dba5d2e7d29aa821c9392cdbd561665f741..45f79585c0125eac2831eeb86760ed08f517ea2f 100644 --- a/mapleall/maple_me/src/me_predict.cpp +++ b/mapleall/maple_me/src/me_predict.cpp @@ -109,7 +109,7 @@ Predictor MePrediction::ReturnPrediction(MeExpr *val, Prediction *prediction) { // Predict edge E with the given PROBABILITY. void MePrediction::PredictEdge(Edge *e, Predictor predictor, int probability) { - if (e->src != func->commonEntryBB && e->src->succ.size() > 1) { + if (e->src != cfg->commonEntryBB && e->src->succ.size() > 1) { BB *src = e->src; EdgePrediction *i = tmpAlloc.GetMemPool()->New(e); EdgePrediction *pred = bbPredictions[src->id.idx]; @@ -135,7 +135,7 @@ void MePrediction::PredEdgeDef(Edge *e, Predictor predictor, Prediction taken) { of this basic blocks as unlikely. */ void MePrediction::BBLevelPredictions() { RetMeStmt *retStmt = NULL; - for (BB *bb : func->commonExitBB->pred) { + for (BB *bb : cfg->commonExitBB->pred) { MeStmt *meLast = bb->meStmtList.last; if (meLast && meLast->op == OP_return) { retStmt = static_cast(meLast); @@ -176,14 +176,14 @@ void MePrediction::BBLevelPredictions() { // Make edges for all bbs in the cfg. void MePrediction::Init() { - bbPredictions.resize(func->bbVec.size()); - edges.resize(func->bbVec.size()); - bbVisited.resize(func->bbVec.size()); - for (uint32_t i = 0; i < func->bbVec.size(); i++) { + bbPredictions.resize(cfg->bbVec.size()); + edges.resize(cfg->bbVec.size()); + bbVisited.resize(cfg->bbVec.size()); + for (uint32_t i = 0; i < cfg->bbVec.size(); i++) { bbVisited[i] = true; bbPredictions[i] = nullptr; edges[i] = nullptr; - BB *bb = func->bbVec[i]; + BB *bb = cfg->bbVec[i]; if (bb == nullptr) { continue; } @@ -193,11 +193,11 @@ void MePrediction::Init() { edges[i] = e; } } - if (func->commonEntryBB != func->first_bb_) { - bbVisited[func->commonEntryBB->id.idx] = true; + if (cfg->commonEntryBB != cfg->first_bb) { + bbVisited[cfg->commonEntryBB->id.idx] = true; } - if (func->commonExitBB != func->last_bb_) { - bbVisited[func->commonExitBB->id.idx] = true; + if (cfg->commonExitBB != cfg->last_bb) { + bbVisited[cfg->commonExitBB->id.idx] = true; } } @@ -239,7 +239,7 @@ void MePrediction::PredictLoops() { // Find loop exit bbs. MapleVector exits(tmpAlloc.Adapter()); for (MapleSet::iterator stit = loopbbs.begin(); stit != loopbbs.end(); stit++) { - BB *bb = func->bbVec[stit->idx]; + BB *bb = cfg->bbVec[stit->idx]; if (bb->succ.size() < 2) { continue; } @@ -349,7 +349,7 @@ void MePrediction::EstimateBBProb(BB *bb) { Edge *findEdgeResult = FindEdge(bb, dest); CHECK_FATAL(findEdgeResult != nullptr, "null ptr check"); PredEdgeDef(findEdgeResult, kPredEarlyReturn, kNotTaken); - } else if (dest != func->commonExitBB && dest != bb && dom->Dominate(bb, dest) && !dom->Postdominate(dest, bb)) { + } else if (dest != cfg->commonExitBB && dest != bb && dom->Dominate(bb, dest) && !dom->Postdominate(dest, bb)) { for (auto stmt : dest->meStmtList) { if (stmt->op == OP_call || stmt->op == OP_callassigned) { PUIdx puIdx = static_cast(stmt)->puIdx; @@ -614,23 +614,23 @@ void MePrediction::EstimateLoops() { for (uint32_t i = 0; i < bbVisited.size(); i++) { bbVisited[i] = false; } - if (func->commonEntryBB != func->first_bb_) { - bbVisited[func->commonEntryBB->id.idx] = false; + if (cfg->commonEntryBB != cfg->first_bb) { + bbVisited[cfg->commonEntryBB->id.idx] = false; } - if (func->commonExitBB != func->last_bb_) { - bbVisited[func->commonExitBB->id.idx] = false; + if (cfg->commonExitBB != cfg->last_bb) { + bbVisited[cfg->commonExitBB->id.idx] = false; } - func->commonEntryBB->frequency = kFreqBase; - for (BB *bb : func->commonEntryBB->succ) { + cfg->commonEntryBB->frequency = kFreqBase; + for (BB *bb : cfg->commonEntryBB->succ) { PropagateFreq(bb, bb); } } void MePrediction::EstimateBBFrequencies() { - BB *entry = func->commonEntryBB; + BB *entry = cfg->commonEntryBB; edges[entry->id.idx]->probability = PROB_ALWAYS; double backProb = 0; - for (uint32_t i = 0; i < func->bbVec.size(); i++) { + for (uint32_t i = 0; i < cfg->bbVec.size(); i++) { Edge *e = edges[i]; while (e) { if (e->probability > 0) { @@ -658,19 +658,19 @@ void MePrediction::EstimateProbability() { SortLoops(); PredictLoops(); } - for (uint32 i = 0; i < func->bbVec.size(); i++) { - BB *bb = func->bbVec[i]; + for (uint32 i = 0; i < cfg->bbVec.size(); i++) { + BB *bb = cfg->bbVec[i]; if (bb != nullptr) { EstimateBBProb(bb); } } - for (uint32 i = 0; i < func->bbVec.size(); i++) { - BB *bb = func->bbVec[i]; + for (uint32 i = 0; i < cfg->bbVec.size(); i++) { + BB *bb = cfg->bbVec[i]; if (bb != nullptr) { CombinePredForBB(bb); } } - for (uint32 i = 0; i < func->bbVec.size(); i++) { + for (uint32 i = 0; i < cfg->bbVec.size(); i++) { int32_t all = 0; for (Edge *e = edges[i]; e != nullptr; e = e->next) { if (predictDebug) { @@ -688,15 +688,14 @@ void MePrediction::EstimateProbability() { // Estimate the execution frequecy for all bbs. AnalysisResult *MeDoPredict::Run(MeFunction *func, MeFuncResultMgr *m) { - MeIRMap *hmap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func)); + MeIRMap *hmap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func, !MeOption::quiet)); CHECK_FATAL(hmap != nullptr, "hssamap is nullptr"); - Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); + Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func, !MeOption::quiet)); CHECK_FATAL(dom, "dominance phase has problem"); - m->InvalidAnalysisResult(MeFuncPhase_MELOOP, func); - IdentifyLoops *meloop = static_cast(m->GetAnalysisResult(MeFuncPhase_MELOOP, func)); - CHECK_FATAL(meloop != NULL, "meloop has problem"); + IdentifyLoops *meloop = static_cast(m->GetAnalysisResult(MeFuncPhase_IDENTLOOPS, func, !MeOption::quiet)); + CHECK_FATAL(meloop != nullptr, "identloops has problem"); std::string mePredPhaseName = PhaseName(); MemPool *mePredMp = mempoolctrler.NewMemPool(mePredPhaseName.c_str()); diff --git a/mapleall/maple_me/src/me_prop.cpp b/mapleall/maple_me/src/me_prop.cpp index e5ef29ee889140262fdef5928421050927810066..44c127bf58433f13175989c100868a894b68ff63 100644 --- a/mapleall/maple_me/src/me_prop.cpp +++ b/mapleall/maple_me/src/me_prop.cpp @@ -27,10 +27,10 @@ namespace maple { AnalysisResult *MeDoMeProp::Run(MeFunction *func, MeFuncResultMgr *m) { - Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); + Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func, !MeOption::quiet)); ASSERT(dom != nullptr, "dominance phase has problem"); - MeIRMap *hmap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func)); + MeIRMap *hmap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func, !MeOption::quiet)); ASSERT(hmap != nullptr, "hssamap has problem"); MemPool *propmp = mempoolctrler.NewMemPool(PhaseName().c_str()); @@ -38,7 +38,7 @@ AnalysisResult *MeDoMeProp::Run(MeFunction *func, MeFuncResultMgr *m) { MeOption::propglobalref, MeOption::propfinaliloadref, MeOption::propiloadrefnonparm, MeOption::propatphi); MIRFunction *mirfunction = func->mirFunc; - meprop.TraversalBB(func->commonEntryBB); + meprop.TraversalBB(func->theCFG->commonEntryBB); mempoolctrler.DeleteMemPool(propmp); if (DEBUGFUNC(func)) { LogInfo::MapleLogger() << "\n============== After Copy Propagation =============" << std::endl; diff --git a/mapleall/maple_me/src/me_rc_lowering.cpp b/mapleall/maple_me/src/me_rc_lowering.cpp index 64884667540aa7b418d77cd64fc05f2083cd8580..bad004f98616ec0e278e83643d77487cb3249502 100755 --- a/mapleall/maple_me/src/me_rc_lowering.cpp +++ b/mapleall/maple_me/src/me_rc_lowering.cpp @@ -760,7 +760,7 @@ void RCLowering::PostBBLower() { } } // compact RC - for (BB *bb : func->bbVec) { + for (BB *bb : func->theCFG->bbVec) { if (bb) { CompactRC(bb); } @@ -857,7 +857,7 @@ VarMeExpr *RCLowering::GetMeExprForNewTemp(bool isLocalrefvar) { // where local ref assignments can be ignored // functions with global write cannot use fast path void RCLowering::FastRCLower(BB *bb) { - MapleMap exceptionAllocsites(func->alloc.Adapter()); + std::map exceptionAllocsites; for (auto stmt : bb->meStmtList) { Opcode opcode = stmt->op; @@ -1135,7 +1135,10 @@ void RCLowering::FastRCLower(BB *bb) { } AnalysisResult *MeDoRCLowering::Run(MeFunction *func, MeFuncResultMgr *m, ModuleResultMgr *mrm) { - KlassHierarchy *kh = static_cast(mrm->GetAnalysisResult(MoPhase_CHA, &func->mirModule)); + MeIRMap *irMap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func, !MeOption::quiet)); + ASSERT(irMap != nullptr, "irmapbuild phase has problem"); + + KlassHierarchy *kh = static_cast(mrm->GetAnalysisResult(MoPhase_CHA, &func->mirModule, !MeOption::quiet)); RCLowering rcLowering(func, kh); func->mirModule.hints |= kRcLowered; @@ -1153,7 +1156,7 @@ AnalysisResult *MeDoRCLowering::Run(MeFunction *func, MeFuncResultMgr *m, Module bool fastLowering = func->mirFunc->GetAttr(FUNCATTR_rclocalunowned); if (fastLowering) { - for (BB *bb : func->bbVec) { + for (BB *bb : func->theCFG->bbVec) { if (bb != nullptr) { rcLowering.FastRCLower(bb); } @@ -1175,8 +1178,8 @@ AnalysisResult *MeDoRCLowering::Run(MeFunction *func, MeFuncResultMgr *m, Module } } - for (BB *bb : func->bbVec) { - if (bb == nullptr || bb == func->commonEntryBB || bb == func->commonExitBB) { + for (BB *bb : func->theCFG->bbVec) { + if (bb == nullptr || bb == func->theCFG->commonEntryBB || bb == func->theCFG->commonExitBB) { continue; } rcLowering.EpreFixup(bb); diff --git a/mapleall/maple_me/src/me_rename_to_preg.cpp b/mapleall/maple_me/src/me_rename_to_preg.cpp index 25f27a4c6119c37d907f9eee22e23adbfe81cc61..e0fc36230a57ba8ae2029b367a4022e8724e8769 100644 --- a/mapleall/maple_me/src/me_rename_to_preg.cpp +++ b/mapleall/maple_me/src/me_rename_to_preg.cpp @@ -58,7 +58,7 @@ RegMeExpr *SSARename2Preg::RenameVar(VarMeExpr *varmeexpr) { } else { const OriginalSt *origOst = ost; if (ost->indexRenamedFrom.idx != 0) { // change to use the original ost - origOst = ssaTab->GetSymbolOriginalStFromid(ost->indexRenamedFrom); + origOst = ssaTab->GetOriginalStFromid(ost->indexRenamedFrom); } if (origOst->index.idx >= aliasclass->osym2Elem.size()) { return nullptr; @@ -79,7 +79,7 @@ RegMeExpr *SSARename2Preg::RenameVar(VarMeExpr *varmeexpr) { return nullptr; } curtemp = meirmap->CreateRegMeExpr(ty); - OriginalSt *pregOst = ssaTab->originalStTable.CreatePregOriginalSt(curtemp->regIdx, func->mirFunc->puIdx); + OriginalSt *pregOst = ssaTab->originalStTable.CreatePregOriginalSt(curtemp->GetPregIdx(), func->mirFunc->puIdx); pregOst->isFormal = ost->isFormal; sym2reg_map[ost->index] = pregOst; vstidx2reg_map.insert(make_pair(varmeexpr->exprID, curtemp)); @@ -289,7 +289,7 @@ void SSARename2Preg::UpdateMirFunctionFormal() { } else { RegMeExpr *regformal = reg_formal_vec[i]; if (regformal) { - PregIdx16 regIdx = regformal->regIdx; + PregIdx16 regIdx = regformal->GetPregIdx(); MIRSymbol *oldformalst = mirFunc->formalDefVec[i].formalSym; MIRSymbol *newformalst = mirbuilder->CreatePregFormalSymbol(oldformalst->tyIdx, regIdx, mirFunc); mirFunc->formalDefVec[i].formalSym = newformalst; @@ -306,7 +306,7 @@ void SSARename2Preg::Init() { void SSARename2Preg::RunSelf() { Init(); - for (BB *mebb : func->bbVec) { + for (BB *mebb : func->theCFG->bbVec) { if (mebb == nullptr) { continue; } @@ -315,7 +315,7 @@ void SSARename2Preg::RunSelf() { LogInfo::MapleLogger() << " working on phi part of BB" << mebb->id.idx << endl; } MapleMap &phiList = mebb->mePhiList; - MapleMap regPhiList(func->alloc.Adapter()); + MapleMap regPhiList(func->theCFG->cfgAlloc.Adapter()); for (std::pair apair : phiList) { if (!apair.second->UseReg()) { Rename2PregPhi(mebb, apair.second, regPhiList); @@ -340,8 +340,11 @@ void SSARename2Preg::PromoteEmptyFunction() { } AnalysisResult *MeDoSSARename2Preg::Run(MeFunction *func, MeFuncResultMgr *m) { + MeIRMap *irMap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func)); + ASSERT(irMap != nullptr, ""); + MemPool *renamemp = mempoolctrler.NewMemPool(PhaseName().c_str()); - if (func->bbVec.size() == 0) { + if (func->theCFG->bbVec.size() == 0) { // empty function, we only promote the parameter SSARename2Preg emptyrenamer(renamemp, func, nullptr, nullptr); emptyrenamer.PromoteEmptyFunction(); @@ -349,9 +352,6 @@ AnalysisResult *MeDoSSARename2Preg::Run(MeFunction *func, MeFuncResultMgr *m) { return nullptr; } - MeIRMap *irMap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func)); - ASSERT(irMap != nullptr, ""); - AliasClass *aliasclass = static_cast(m->GetAnalysisResult(MeFuncPhase_ALIASCLASS, func)); ASSERT(aliasclass != nullptr, ""); diff --git a/mapleall/maple_me/src/me_ssa.cpp b/mapleall/maple_me/src/me_ssa.cpp index 952196cce6827edd0dba48d639699156dfce88d3..966674f963adff407ed9f9e0a71de3fa53fcfbc6 100644 --- a/mapleall/maple_me/src/me_ssa.cpp +++ b/mapleall/maple_me/src/me_ssa.cpp @@ -21,6 +21,9 @@ #include "ver_symbol.h" #include "dominance.h" #include "me_function.h" +#include "me_cfg.h" +#include "me_alias_class.h" +#include "mir_builder.h" /* This phase builds the SSA form of a function. Before this we have got the dominator tree @@ -51,18 +54,6 @@ using namespace std; namespace maple { -void MeSSA::BuildSSA() { - InsertPhiNode(); - - InitRenameStack(&mirFunc->meSSATab->originalStTable, mirFunc->bbVec.size(), mirFunc->meSSATab->versionStTable); - - // recurse down dominator tree in pre-order traversal - MapleSet *children = &dom_->domChildren[mirFunc->commonEntryBB->id.idx]; - for (BBId child : *children) { - RenameBB(mirFunc->bbVec[child.idx]); - } -} - void MeSSA::InsertPhiNode() { for (uint32 i = 1; i < ssaTab->originalStTable.Size(); i++) { OriginalSt *ost = ssaTab->GetOriginalStFromid(OStIdx(i)); @@ -83,14 +74,14 @@ void MeSSA::InsertPhiNode() { for (BBId bbid : phibbs) { BB *phiBB = bbVec[bbid.idx]; CHECK_FATAL(phiBB != nullptr, "MeSSA::InsertPhiNode: non-existent BB for definition"); - phiBB->InsertPhi(&mirFunc->alloc, vst); + phiBB->InsertPhi(&func->meSSATab->vers_alloc, vst); } } } bool MeSSA::VerifySSAOpnd(BaseNode *node) { Opcode op = node->op; - uint32 vtableSize = mirFunc->meSSATab->versionStTable.Size(); + uint32 vtableSize = func->meSSATab->versionStTable.Size(); if (op == OP_dread || op == OP_addrof) { AddrofSSANode *addrofssanode = static_cast(node); VersionSt *verSt = addrofssanode->ssaVar; @@ -109,9 +100,9 @@ bool MeSSA::VerifySSAOpnd(BaseNode *node) { } bool MeSSA::VerifySSA() { - VersionStTable *versionsttable = &mirFunc->meSSATab->versionStTable; - uint32 vtableSize = mirFunc->meSSATab->versionStTable.Size(); - for (BB *bb : mirFunc->bbVec) { + VersionStTable *versionsttable = &func->meSSATab->versionStTable; + uint32 vtableSize = func->meSSATab->versionStTable.Size(); + for (BB *bb : func->theCFG->bbVec) { if (bb == nullptr) { continue; } @@ -120,11 +111,11 @@ bool MeSSA::VerifySSA() { opcode = stmt->op; if (opcode == OP_dassign) { MayDefPartWithVersionSt *thessapart = - static_cast(mirFunc->meSSATab->stmtsSSAPart.SsapartOf(stmt)); + static_cast(func->meSSATab->stmtsSSAPart.SsapartOf(stmt)); VersionSt *verSt = thessapart->ssaVar; ASSERT(verSt->index < vtableSize, ""); } else if (opcode == OP_regassign) { - VersionSt *verSt = static_cast(mirFunc->meSSATab->stmtsSSAPart.SsapartOf(stmt)); + VersionSt *verSt = static_cast(func->meSSATab->stmtsSSAPart.SsapartOf(stmt)); ASSERT(verSt->index < vtableSize, ""); } for (int32 i = 0; i < stmt->NumOpnds(); i++) { @@ -135,20 +126,110 @@ bool MeSSA::VerifySSA() { return true; } +void MeSSA::InsertIdentifyAssignments(IdentifyLoops *identloops) { + MIRBuilder *mirbuilder = func->mirModule.mirBuilder; + LfoFunction *lfoFunc = func->lfoFunc; + SSATab *ssatab = func->meSSATab; + MapleVector &bbVec = func->theCFG->bbVec; + + for (LoopDesc *aloop : identloops->meloops) { + BB *headbb = aloop->head; + // check if the label has associated LfoWhileInfo + if (headbb->bbLabel == 0) { + continue; + } + if (aloop->exitBB == nullptr) { + continue; + } + MapleMap::iterator it = lfoFunc->label2WhileInfo.find(headbb->bbLabel); + if (it == lfoFunc->label2WhileInfo.end()) { + continue; + } + if (headbb->pred.size() != 2) { + continue; + } + // collect the symbols for inserting identity assignments + std::set ostSet; + for (std::pair mapEntry: *(headbb->phiList)) { + OriginalSt *ost = mapEntry.first; + if (ost->IsIVCandidate()) { + ostSet.insert(ost); + } + } + if (ostSet.empty()) { + continue; + } + // for the exitBB, insert identify assignment for any var that has phi at + // headbb + for (OriginalSt *ost : ostSet) { + MIRType *mirtype = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ost->tyIdx); + if (ost->IsSymbol()) { + AddrofNode dread(OP_dread, mirtype->primType, ost->GetMIRSymbol()->stIdx, ost->fieldID); + AddrofSSANode *ssadread = func->mirFunc->codeMemPool->New(&dread); + ssadread->ssaVar = ssatab->versionStTable.GetZeroVersionSt(ost); + + DassignNode *dass = mirbuilder->CreateStmtDassign(ost->GetMIRSymbol(), ost->fieldID, ssadread); + aloop->exitBB->PrependStmtNode(dass); + + MayDefPartWithVersionSt *thessapart = + ssatab->stmtsSSAPart.ssaPartMp->New(&ssatab->stmtsSSAPart.ssaPartAlloc); + ssatab->stmtsSSAPart.SetSsapartOf(dass, thessapart); + thessapart->ssaVar = ssatab->versionStTable.GetZeroVersionSt(ost); + } else { + RegreadNode regread(ost->GetPregIdx()); + MIRPreg *preg = func->mirFunc->pregTab->PregFromPregIdx(ost->GetPregIdx()); + regread.primType = preg->primType; + RegreadSSANode *ssaregread = func->mirFunc->codeMemPool->New(®read); + ssaregread->ssaVar = ssatab->versionStTable.GetZeroVersionSt(ost); + + RegassignNode *rass = mirbuilder->CreateStmtRegassign(mirtype->primType, ost->GetPregIdx(), ssaregread); + aloop->exitBB->PrependStmtNode(rass); + + VersionSt *vst = ssatab->versionStTable.GetZeroVersionSt(ost); + ssatab->stmtsSSAPart.SetSsapartOf(rass, vst); + } + ssatab->AddDefBB4Ost(ost->index, aloop->exitBB->id); + } + if (DEBUGFUNC(func)) { + LogInfo::MapleLogger() << "****** Identity assignments inserted at loop exit BB " << aloop->exitBB->id.idx << std::endl; + } + } +} + AnalysisResult *MeDoSSA::Run(MeFunction *func, MeFuncResultMgr *m) { - Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); + MirCFG *cfg = static_cast(m->GetAnalysisResult(MeFuncPhase_CFGBUILD, func, !MeOption::quiet)); + ASSERT(cfg != nullptr, "cfgbuild phase has problem"); + + Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func, !MeOption::quiet)); ASSERT(dom != nullptr, "dominance phase has problem"); - SSATab *ssaTab = static_cast(m->GetAnalysisResult(MeFuncPhase_SSATAB, func)); - ASSERT(ssaTab != nullptr, "ssaTab phase has problem"); + SSATab *ssaTab = static_cast(m->GetAnalysisResult(MeFuncPhase_SSATAB, func, !MeOption::quiet)); + ASSERT(ssaTab != nullptr, "ssatab phase has problem"); + + MeAliasClass *aliasclass = static_cast(m->GetAnalysisResult(MeFuncPhase_ALIASCLASS, func, !MeOption::quiet)); + ASSERT(aliasclass != nullptr, "aliasclass phase has problem"); MemPool *ssamp = mempoolctrler.NewMemPool(PhaseName().c_str()); - MeSSA ssa(func, func->meSSATab, dom, ssamp); - ssa.BuildSSA(); + MeSSA *ssa = ssamp->New(func, func->meSSATab, dom, ssamp); + + ssa->InsertPhiNode(); + + if (func->isLfo) { + IdentifyLoops *identloops = static_cast(m->GetAnalysisResult(MeFuncPhase_IDENTLOOPS, func, !MeOption::quiet)); + CHECK_FATAL(identloops != nullptr, "identloops has problem"); + ssa->InsertIdentifyAssignments(identloops); + } + + ssa->InitRenameStack(&func->meSSATab->originalStTable, func->theCFG->bbVec.size(), func->meSSATab->versionStTable); + + // recurse down dominator tree in pre-order traversal + MapleSet *children = &dom->domChildren[func->theCFG->commonEntryBB->id.idx]; + for (BBId child : *children) { + ssa->RenameBB(func->theCFG->bbVec[child.idx]); + } - mempoolctrler.DeleteMemPool(ssamp); - ssa.VerifySSA(); + ssa->VerifySSA(); if (DEBUGFUNC(func)) { ssaTab->versionStTable.Dump(&ssaTab->mirModule); @@ -158,7 +239,7 @@ AnalysisResult *MeDoSSA::Run(MeFunction *func, MeFuncResultMgr *m) { func->DumpFunction(); } - return nullptr; + return ssa; } } // namespace maple diff --git a/mapleall/maple_me/src/me_ssa_devirtual.cpp b/mapleall/maple_me/src/me_ssa_devirtual.cpp index 36891e2470a9a71ba4fab506c95fc3e770aad82e..c94716182566348491c715947da07a3d65beda1d 100644 --- a/mapleall/maple_me/src/me_ssa_devirtual.cpp +++ b/mapleall/maple_me/src/me_ssa_devirtual.cpp @@ -20,16 +20,16 @@ namespace maple { AnalysisResult *MeDoSSADevirtual::Run(MeFunction *func, MeFuncResultMgr *frm, ModuleResultMgr *mrm) { - Dominance *dom = static_cast(frm->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); + Dominance *dom = static_cast(frm->GetAnalysisResult(MeFuncPhase_DOMINANCE, func, !MeOption::quiet)); ASSERT(dom, "dominance phase has problem"); - MeIRMap *hmap = static_cast(frm->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func)); + MeIRMap *hmap = static_cast(frm->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func, !MeOption::quiet)); ASSERT(hmap, "hssamap has problem"); CHECK_FATAL(mrm != nullptr, "Needs module result manager for ipa"); - KlassHierarchy *kh = static_cast(mrm->GetAnalysisResult(MoPhase_CHA, &func->mirModule)); + KlassHierarchy *kh = static_cast(mrm->GetAnalysisResult(MoPhase_CHA, &func->mirModule, !MeOption::quiet)); ASSERT(kh != nullptr, ""); Clone *clone = nullptr; if (Options::O2) { - clone = static_cast(mrm->GetAnalysisResult(MoPhase_CLONE, &func->mirModule)); + clone = static_cast(mrm->GetAnalysisResult(MoPhase_CLONE, &func->mirModule, !MeOption::quiet)); } MemPool *ssadevirtualmp = mempoolctrler.NewMemPool(PhaseName().c_str()); MeSSADevirtual *messadevirtual = @@ -40,7 +40,7 @@ AnalysisResult *MeDoSSADevirtual::Run(MeFunction *func, MeFuncResultMgr *frm, Mo SSADevirtual::debug = true; } - messadevirtual->Perform(func->commonEntryBB); + messadevirtual->Perform(func->theCFG->commonEntryBB); /* this is a transform phase, delete mempool */ mempoolctrler.DeleteMemPool(ssadevirtualmp); diff --git a/mapleall/maple_me/src/me_ssa_epre.cpp b/mapleall/maple_me/src/me_ssa_epre.cpp index 9a740b9129f41119ad508d44fd462cbcaa71259c..85b901f967a6ced0551ef42cd46bb8c48ef37176 100644 --- a/mapleall/maple_me/src/me_ssa_epre.cpp +++ b/mapleall/maple_me/src/me_ssa_epre.cpp @@ -25,7 +25,7 @@ namespace maple { void MeSSAEPre::BuildWorkList() { const MapleVector &preorderDt = dominance->dtPreOrder; for (uint32 i = 0; i < preorderDt.size(); i++) { - BB *bb = func->bbVec[preorderDt[i].idx]; + BB *bb = func->theCFG->bbVec[preorderDt[i].idx]; BuildWorkListBB(bb); } } @@ -36,11 +36,11 @@ AnalysisResult *MeDoSSAEPre::Run(MeFunction *func, MeFuncResultMgr *m) { pUcount++; return nullptr; } - Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); + MeIRMap *irMap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func, !MeOption::quiet)); + ASSERT(irMap != nullptr, "irmapbuild phase has problem"); + Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func, !MeOption::quiet)); ASSERT(dom != nullptr, "dominance phase has problem"); - MeIRMap *irMap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func)); - ASSERT(irMap != nullptr, "irMap phase has problem"); MemPool *ssapremp = mempoolctrler.NewMemPool(PhaseName().c_str()); MemPool *percandmp = mempoolctrler.NewMemPool("Per EPRE Candidate"); diff --git a/mapleall/maple_me/src/me_ssa_lpre.cpp b/mapleall/maple_me/src/me_ssa_lpre.cpp index db409605db704f782b56d8eccb2bead8fff24d67..e8b06816a8c1bee18c1c7053151ee748996a7ddd 100644 --- a/mapleall/maple_me/src/me_ssa_lpre.cpp +++ b/mapleall/maple_me/src/me_ssa_lpre.cpp @@ -39,7 +39,7 @@ void MeSSALPre::GenerateSaveRealocc(MeRealOcc *realocc) { MIRSymbol *oldformalst = varmeexpr->ost->GetMIRSymbol(); RegMeExpr *regformal = static_cast(regorvar); MIRSymbol *newformalst = - mirModule->mirBuilder->CreatePregFormalSymbol(oldformalst->tyIdx, regformal->regIdx, func->mirFunc); + mirModule->mirBuilder->CreatePregFormalSymbol(oldformalst->tyIdx, regformal->GetPregIdx(), func->mirFunc); uint32 i = 0; for (; i < func->mirFunc->formalDefVec.size(); i++) if (func->mirFunc->formalDefVec[i].formalSym == oldformalst) { @@ -171,7 +171,7 @@ bool MeSSALPre::ScreenRHS4LHSoccur(const MeExpr *rhs) const { return rhs->primType != PTY_ref; case kMeOpReg: return !((rhs->primType == PTY_ref || rhs->primType == PTY_ptr) && - static_cast(rhs)->regIdx == -kSregThrownval); + static_cast(rhs)->GetPregIdx() == -kSregThrownval); default: return true; } @@ -201,7 +201,7 @@ void MeSSALPre::BuildEntryLhsOcc4Formals() { work_cand->real_occs.insert(occit, occ); // insert at beginning occ->is_lhs = true; occ->is_formal_at_entry = true; - occ->mirbb = func->first_bb_; + occ->mirbb = func->theCFG->first_bb; } void MeSSALPre::BuildWorkListLHSOcc(MeStmt *mestmt, int32 seqstmt) { @@ -354,8 +354,8 @@ void MeSSALPre::BuildWorkList() { const MapleVector &preorderDt = dominance->dtPreOrder; for (uint32 i = 0; i < numbbs; i++) { - CHECK(preorderDt[i].idx < func->bbVec.size(), "index out of range in MeSSALPre::BuildWorkList"); - BB *bb = func->bbVec[preorderDt[i].idx]; + CHECK(preorderDt[i].idx < func->theCFG->bbVec.size(), "index out of range in MeSSALPre::BuildWorkList"); + BB *bb = func->theCFG->bbVec[preorderDt[i].idx]; BuildWorkListBB(bb); } } @@ -374,13 +374,14 @@ AnalysisResult *MeDoSSALPre::Run(MeFunction *func, MeFuncResultMgr *m) { pUcount++; return nullptr; } - Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); - ASSERT(dom != nullptr, ""); - MeIRMap *irMap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func)); - ASSERT(irMap != nullptr, ""); + MeIRMap *irMap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func, !MeOption::quiet)); + ASSERT(irMap != nullptr, "irmapbuild phase has problem"); - IdentifyLoops *identloops = static_cast(m->GetAnalysisResult(MeFuncPhase_MELOOP, func)); + Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func, !MeOption::quiet)); + ASSERT(dom != nullptr, "dominance phase has problem"); + + IdentifyLoops *identloops = static_cast(m->GetAnalysisResult(MeFuncPhase_IDENTLOOPS, func, !MeOption::quiet)); CHECK_FATAL(identloops != nullptr, "meloop has problem"); bool lprePuLimitSpecified = MeOption::lprePULimit != UINT32_MAX; diff --git a/mapleall/maple_me/src/me_ssa_tab.cpp b/mapleall/maple_me/src/me_ssa_tab.cpp index ee72f6690e8fcc2681339e6708b3996486395b1e..0e8998bf1a071f0935bca5c98ace1c9bbc9a7c38 100644 --- a/mapleall/maple_me/src/me_ssa_tab.cpp +++ b/mapleall/maple_me/src/me_ssa_tab.cpp @@ -29,17 +29,20 @@ AnalysisResult *MeDoSSATab::Run(MeFunction *func, MeFuncResultMgr *m) { } MemPool *mp = mempoolctrler.NewMemPool(PhaseName().c_str()); // allocate ssaTab including its SSAPart to store SSA information for statements - SSATab *ssaTab = mp->New(mp, func->versMemPool, &func->mirModule, func->bbVec.size()); + MemPool *versmp = mempoolctrler.NewMemPool("version st mempool"); + SSATab *ssaTab = mp->New(mp, versmp, &func->mirModule, func->theCFG->bbVec.size()); func->meSSATab = ssaTab; #if DEBUG g_ssatab = ssaTab; #endif // pass through the program statements - for (BB *bb : func->bbVec) { + for (BB *bb : func->theCFG->bbVec) { if (bb == nullptr) { continue; } + // allocate phiList for the bb + bb->phiList = versmp->New>(ssaTab->vers_alloc.Adapter()); for (auto stmt : bb->stmtNodeList) { ssaTab->CreateSSAStmt(stmt, bb); // this adds the SSANodes for exprs } diff --git a/mapleall/maple_me/src/me_ssa_update.cpp b/mapleall/maple_me/src/me_ssa_update.cpp index 9c56ec328a1c6165b97d8ac3f1e9c6fb3b0c48af..40fdb3d2978c41398a0798a39bf4019e2a70ba52 100644 --- a/mapleall/maple_me/src/me_ssa_update.cpp +++ b/mapleall/maple_me/src/me_ssa_update.cpp @@ -34,7 +34,7 @@ void SSAUpdate::InsertPhis() { } for (BBId bbid : dfSet) { // insert a phi node - BB *bb = func->bbVec[bbid.idx]; + BB *bb = func->theCFG->bbVec[bbid.idx]; MapleMap::iterator philistit = bb->mePhiList.find(it->first); if (philistit != bb->mePhiList.end()) { philistit->second->isLive = true; @@ -220,7 +220,7 @@ void SSAUpdate::RenameBB(BB *bb) { // recurse down dominator tree in pre-order traversal MapleSet *children = &dom->domChildren[bb->id.idx]; for (BBId child : *children) { - RenameBB(func->bbVec[child.idx]); + RenameBB(func->theCFG->bbVec[child.idx]); } // pop stacks back to where they were at entry to this BB @@ -238,16 +238,16 @@ void SSAUpdate::Run() { // push zero-version varmeexpr nodes to rename stacks MapleMap *>::iterator it = renameStacks.begin(); for (; it != renameStacks.end(); it++) { - OriginalSt *ost = ssaTab->GetSymbolOriginalStFromid(it->first); + OriginalSt *ost = ssaTab->GetOriginalStFromid(it->first); VarMeExpr *zeroversvar = irMap->GetOrCreateZeroVersionVarMeExpr(ost); MapleStack *renamestack = it->second; renamestack->push(zeroversvar); } // recurse down dominator tree in pre-order traversal - MapleSet *children = &dom->domChildren[func->commonEntryBB->id.idx]; + MapleSet *children = &dom->domChildren[func->theCFG->commonEntryBB->id.idx]; for (BBId child : *children) { - RenameBB(func->bbVec[child.idx]); + RenameBB(func->theCFG->bbVec[child.idx]); } } diff --git a/mapleall/maple_me/src/me_ssu_pre.cpp b/mapleall/maple_me/src/me_ssu_pre.cpp index dc97cada8b3a47fc840ca7d847ec2f2ca9bf0add..2ca6e772ecc55bb7a338b1d1cacb2eb399b137fe 100644 --- a/mapleall/maple_me/src/me_ssu_pre.cpp +++ b/mapleall/maple_me/src/me_ssu_pre.cpp @@ -339,7 +339,7 @@ void MeSSUPre::CreateSortedOccs() { std::multiset lambdares_dfns; for (uint32 dfn : lambda_dfns) { BBId bbid = dominance->pdtPreOrder[dfn]; - BB *bb = func->bbVec[bbid.idx]; + BB *bb = func->theCFG->bbVec[bbid.idx]; for (BB *succ : bb->succ) { lambdares_dfns.insert(dominance->pdtDfn[succ->id.idx]); } @@ -363,11 +363,11 @@ void MeSSUPre::CreateSortedOccs() { } SLambdaOcc *nextLambdaocc = nullptr; if (lambdadfnIt != lambda_dfns.end()) { - nextLambdaocc = ssuPreMempool->New(func->bbVec[dominance->pdtPreOrder[*lambdadfnIt].idx], &ssuPreAlloc); + nextLambdaocc = ssuPreMempool->New(func->theCFG->bbVec[dominance->pdtPreOrder[*lambdadfnIt].idx], &ssuPreAlloc); } SLambdaResOcc *nextLambdaresocc = nullptr; if (lambdaresdfnIt != lambdares_dfns.end()) { - nextLambdaresocc = ssuPreMempool->New(func->bbVec[dominance->pdtPreOrder[*lambdaresdfnIt].idx]); + nextLambdaresocc = ssuPreMempool->New(func->theCFG->bbVec[dominance->pdtPreOrder[*lambdaresdfnIt].idx]); std::unordered_map>::iterator it = bb2lambdaresMap.find(dominance->pdtPreOrder[*lambdaresdfnIt]); @@ -425,7 +425,7 @@ void MeSSUPre::CreateSortedOccs() { lambdadfnIt++; if (lambdadfnIt != lambda_dfns.end()) { nextLambdaocc = - ssuPreMempool->New(func->bbVec[dominance->pdtPreOrder[*lambdadfnIt].idx], &ssuPreAlloc); + ssuPreMempool->New(func->theCFG->bbVec[dominance->pdtPreOrder[*lambdadfnIt].idx], &ssuPreAlloc); } else { nextLambdaocc = nullptr; } @@ -434,7 +434,7 @@ void MeSSUPre::CreateSortedOccs() { CHECK_FATAL(lambdaresdfnIt != lambdares_dfns.end(), "iterator check"); lambdaresdfnIt++; if (lambdaresdfnIt != lambdares_dfns.end()) { - nextLambdaresocc = ssuPreMempool->New(func->bbVec[dominance->pdtPreOrder[*lambdaresdfnIt].idx]); + nextLambdaresocc = ssuPreMempool->New(func->theCFG->bbVec[dominance->pdtPreOrder[*lambdaresdfnIt].idx]); std::unordered_map>::iterator it = bb2lambdaresMap.find(dominance->pdtPreOrder[*lambdaresdfnIt]); if (it == bb2lambdaresMap.end()) { @@ -473,7 +473,7 @@ void MeSSUPre::CreateSortedOccs() { } void MeSSUPre::ApplySSUPre() { - BuildWorkListBB(func->commonExitBB); + BuildWorkListBB(func->theCFG->commonExitBB); if (prekind != k2ndDecrefPre) { // #0 build worklist CreateEmptyCleanupIntrinsics(); } diff --git a/mapleall/maple_me/src/me_stmt_pre.cpp b/mapleall/maple_me/src/me_stmt_pre.cpp index 66a5bc02f8b352487506a46db84d5b8ef7f6baa9..bd021af8205286f560ffe52860b2cab6c7b72ff8 100644 --- a/mapleall/maple_me/src/me_stmt_pre.cpp +++ b/mapleall/maple_me/src/me_stmt_pre.cpp @@ -721,7 +721,7 @@ void MeStmtPre::ConstructUseOccurMap() { // do a pass over the program const MapleVector &preorderDt = dominance->dtPreOrder; for (uint32 i = 0; i < preorderDt.size(); i++) { - BB *bb = func->bbVec[preorderDt[i].idx]; + BB *bb = func->theCFG->bbVec[preorderDt[i].idx]; for (auto stmt : bb->meStmtList) { for (int32 j = 0; j < stmt->NumMeStmtOpnds(); j++) { ConstructUseOccurMapExpr(i, stmt->GetMeStmtOpnd(j)); @@ -925,7 +925,7 @@ void MeStmtPre::BuildWorkListBB(BB *bb) { if (!MeOption::dassignpre || !dassmestmt->rhs->IsLeaf() || !dassmestmt->chiList.empty() || dassmestmt->NeedIncref() || (dassmestmt->rhs->op == OP_regread && - static_cast(dassmestmt->rhs)->regIdx == -kSregThrownval)) { + static_cast(dassmestmt->rhs)->GetPregIdx() == -kSregThrownval)) { // update version stacks MapleStack *pstack = versionStackVec.at(dassmestmt->lhs->ost->index.idx); pstack->push(dassmestmt->GetVarLhs()); @@ -1074,7 +1074,7 @@ void MeStmtPre::BuildWorkList() { versionStackVec[ost->index.idx] = versStack; } - BuildWorkListBB(func->commonEntryBB); + BuildWorkListBB(func->theCFG->commonEntryBB); } void MeStmtPre::RemoveUnecessaryDassign(DassignMeStmt *dssmestmt) { @@ -1092,11 +1092,12 @@ void MeStmtPre::RemoveUnecessaryDassign(DassignMeStmt *dssmestmt) { } AnalysisResult *MeDoStmtPre::Run(MeFunction *func, MeFuncResultMgr *m) { - Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); + MeIRMap *irMap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func, !MeOption::quiet)); + ASSERT(irMap != nullptr, "irMap phase has problem"); + + Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func, !MeOption::quiet)); ASSERT(dom != nullptr, "dominance phase has problem"); - MeIRMap *irMap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func)); - ASSERT(irMap != nullptr, "irMap phase has problem"); MemPool *ssapremp = mempoolctrler.NewMemPool(PhaseName().c_str()); MemPool *percandmp = mempoolctrler.NewMemPool("Per STMTPRE Candidate"); diff --git a/mapleall/maple_me/src/me_store_pre.cpp b/mapleall/maple_me/src/me_store_pre.cpp index 6249e36a0089783147119a5b9a695cb9f9a0dbe8..280c998c6d0934e50d5dc9c92a32970967f61a7d 100644 --- a/mapleall/maple_me/src/me_store_pre.cpp +++ b/mapleall/maple_me/src/me_store_pre.cpp @@ -42,7 +42,7 @@ void MeStorePre::CheckCreateCurTemp() { // each bb. The return value is the cur_temp version that contains the RHS value // at the entry to bb; RegMeExpr* MeStorePre::EnsureRhsInCurTemp(BB *bb) { - CHECK_FATAL(bb != func->commonEntryBB, "EnsureRhsInCurTemp: cannot find earlier definition"); + CHECK_FATAL(bb != func->theCFG->commonEntryBB, "EnsureRhsInCurTemp: cannot find earlier definition"); // see if processed before MapleUnorderedMap::iterator map_it = bb_cur_temp_map.find(bb); if (map_it != bb_cur_temp_map.end()) { @@ -207,13 +207,13 @@ void MeStorePre::CreateRealOcc(OStIdx oidx, MeStmt *mestmt) { if (mapit != workcand_map.end()) { wkcand = mapit->second; } else { - OriginalSt *ost = ssaTab->GetSymbolOriginalStFromid(oidx); + OriginalSt *ost = ssaTab->GetOriginalStFromid(oidx); wkcand = ssuPreMempool->New(&ssuPreAlloc, ost); workcand_map[oidx] = wkcand; // if it is local symbol, insert artificial real occ at commonExitBB if (ost->isLocal) { SRealOcc *artocc = ssuPreMempool->New(); - artocc->mirbb = func->commonExitBB; + artocc->mirbb = func->theCFG->commonExitBB; wkcand->real_occs.push_back(artocc); } } @@ -253,7 +253,7 @@ void MeStorePre::CreateKillOcc(OStIdx oidx, BB *bb) { // create kill occurs for all the symbols that alias with muost void MeStorePre::CreateSpreKillOccsThruAliasing(const OriginalSt *muost, BB *bb) { if (muost->indexRenamedFrom.idx != 0) { // change to use the original ost - muost = ssaTab->GetSymbolOriginalStFromid(muost->indexRenamedFrom); + muost = ssaTab->GetOriginalStFromid(muost->indexRenamedFrom); } if (muost->index.idx >= aliasclass->osym2Elem.size()) { return; @@ -364,18 +364,18 @@ void MeStorePre::BuildWorkListBB(BB *bb) { // recurse on child BBs in post-dominator tree for (BBId bbid : dominance->pdomChildren[bb->id.idx]) { - BuildWorkListBB(func->bbVec[bbid.idx]); + BuildWorkListBB(func->theCFG->bbVec[bbid.idx]); } } AnalysisResult *MeDoStorePre::Run(MeFunction *func, MeFuncResultMgr *m) { - Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); + Dominance *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func, !MeOption::quiet)); ASSERT(dom != nullptr, "dominance phase has problem"); - AliasClass *aliasclass = static_cast(m->GetAnalysisResult(MeFuncPhase_ALIASCLASS, func)); + AliasClass *aliasclass = static_cast(m->GetAnalysisResult(MeFuncPhase_ALIASCLASS, func, !MeOption::quiet)); ASSERT(aliasclass != nullptr, "aliasclass phase has problem"); - MeIRMap *irMap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func)); + MeIRMap *irMap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func, !MeOption::quiet)); CHECK_FATAL(irMap != nullptr, "irMap phase has problem"); MemPool *spremp = mempoolctrler.NewMemPool(PhaseName().c_str()); diff --git a/mapleall/maple_me/src/me_sym_rename.cpp b/mapleall/maple_me/src/me_sym_rename.cpp index 8e84132ce61553285629083af3d915e88f6ae048..1f061a41b4660392babee324864f57a81cf56390 100644 --- a/mapleall/maple_me/src/me_sym_rename.cpp +++ b/mapleall/maple_me/src/me_sym_rename.cpp @@ -31,8 +31,8 @@ namespace maple { void SymRename::PerformSymRename() { UnionFind unionFind(mp, irMap->verst2MeExprTable.size()); // conduct a pass over the program code to perform union-find - for (BB *bb : func->bbVec) { - if (bb == nullptr || bb == func->commonEntryBB || bb == func->commonExitBB) { + for (BB *bb : func->theCFG->bbVec) { + if (bb == nullptr || bb == func->theCFG->commonEntryBB || bb == func->theCFG->commonExitBB) { continue; } // go thru all the phi's in the program to perform union-find @@ -80,7 +80,7 @@ void SymRename::PerformSymRename() { } MapleMap::iterator chiit = chilist->begin(); for (; chiit != chilist->end(); chiit++) { - OriginalSt *ost = ssaTab->GetSymbolOriginalStFromid(chiit->first); + OriginalSt *ost = ssaTab->GetOriginalStFromid(chiit->first); if (!ost->IsSymbol() || !IsSymRenameCand(ost)) { continue; } @@ -146,7 +146,7 @@ void SymRename::PerformSymRename() { } // allocate a new OriginalSt for versions belonging to this live range - OriginalSt *origOst = ssaTab->GetSymbolOriginalStFromid(origOstIdx); + OriginalSt *origOst = ssaTab->GetOriginalStFromid(origOstIdx); origOst->symRenamed = true; OriginalSt *newOst = ssaTab->CreateSymbolOriginalSt(origOst->GetMIRSymbol(), origOst->puIdx, origOst->fieldID); newOst->ignoreRC = origOst->ignoreRC; @@ -190,9 +190,9 @@ void SymRename::PerformSymRename() { } AnalysisResult *MeDoSymRename::Run(MeFunction *func, MeFuncResultMgr *m) { - SSATab *ssaTab = static_cast(m->GetAnalysisResult(MeFuncPhase_SSATAB, func)); + SSATab *ssaTab = static_cast(m->GetAnalysisResult(MeFuncPhase_SSATAB, func, !MeOption::quiet)); ASSERT(ssaTab != nullptr, "ssaTab phase has problem"); - MeIRMap *irMap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func)); + MeIRMap *irMap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func, !MeOption::quiet)); ASSERT(irMap != nullptr, "irmapbuild phase has problem"); SymRename symrename(func); diff --git a/mapleall/maple_me/src/occur.cpp b/mapleall/maple_me/src/occur.cpp index 8a294f12b3d3e227c4763a838d402922f507951d..450e543b062d64f6812704aa2d8852fe3b2c8f94 100644 --- a/mapleall/maple_me/src/occur.cpp +++ b/mapleall/maple_me/src/occur.cpp @@ -187,7 +187,7 @@ uint32 PreWorkCand::ComputeWorkCandHashIndex(MeExpr *x) { } case kMeOpReg: { RegMeExpr *regmeexpr = static_cast(x); - hidx = (static_cast(regmeexpr->regIdx)) << 6; + hidx = (static_cast(regmeexpr->GetPregIdx())) << 6; break; } case kMeOpIvar: { diff --git a/mapleall/maple_me/src/prop.cpp b/mapleall/maple_me/src/prop.cpp index 6e7fb6b320e73295f9338fb54a72296fc477dd59..11ec2e24050afd177b8ff738aad9104f82f6ba0b 100644 --- a/mapleall/maple_me/src/prop.cpp +++ b/mapleall/maple_me/src/prop.cpp @@ -57,183 +57,6 @@ Prop::Prop(IRMap *hmap, Dominance *dom, MemPool *mp, uint32 bbvecsize, bool prop } } -MeExpr *Prop::SimplifyMeExpr(OpMeExpr *opmeexpr) { - Opcode opop = opmeexpr->op; - switch (opop) { - case OP_cvt: { - // return nullptr; - OpMeExpr *cvtmeexpr = static_cast(opmeexpr); - MeExpr *opnd0 = cvtmeexpr->GetOpnd(0); - if (opnd0->meOp == kMeOpConst) { - maple::ConstantFold cf(mirModule); - MIRConst *tocvt = - cf.FoldTypeCvtMIRConst(static_cast(opnd0)->constVal, opnd0->primType, cvtmeexpr->primType); - if (tocvt) { - return irMap->CreateConstMeExpr(cvtmeexpr->primType, tocvt); - } - } - if (opnd0->op == OP_cvt) { - OpMeExpr *cvtopnd0 = static_cast(opnd0); - // cvtopnd0 should have tha same type as cvtopnd0->GetOpnd(0) or cvtmeexpr, - // and the type size of cvtopnd0 should be ge(>=) one of them. - // Otherwise, deleting the cvt of cvtopnd0 may result in information loss. - if (maple::GetPrimTypeSize(cvtopnd0->primType) >= maple::GetPrimTypeSize(cvtopnd0->GetOpnd(0)->primType)) { - if ((maple::IsPrimitiveInteger(cvtopnd0->primType) && maple::IsPrimitiveInteger(cvtopnd0->GetOpnd(0)->primType)) || - (maple::IsPrimitiveFloat(cvtopnd0->primType) && maple::IsPrimitiveFloat(cvtopnd0->GetOpnd(0)->primType))) { - return irMap->CreateMeExprTypeCvt(cvtmeexpr->primType, cvtopnd0->opndType, cvtopnd0->GetOpnd(0)); - } - } - if (maple::GetPrimTypeSize(cvtopnd0->primType) >= maple::GetPrimTypeSize(cvtmeexpr->primType)) { - if ((maple::IsPrimitiveInteger(cvtopnd0->primType) && maple::IsPrimitiveInteger(cvtmeexpr->primType)) || - (maple::IsPrimitiveFloat(cvtopnd0->primType) && maple::IsPrimitiveFloat(cvtmeexpr->primType))) { - return irMap->CreateMeExprTypeCvt(cvtmeexpr->primType, cvtopnd0->opndType, cvtopnd0->GetOpnd(0)); - } - } - } - return nullptr; - } - case OP_add: - case OP_sub: - case OP_mul: - case OP_div: - case OP_rem: - case OP_ashr: - case OP_lshr: - case OP_shl: - case OP_max: - case OP_min: - case OP_band: - case OP_bior: - case OP_bxor: - case OP_cand: - case OP_land: - case OP_cior: - case OP_lior: - case OP_depositbits: { - if (!IsPrimitiveInteger(opmeexpr->primType)) { - return nullptr; - } - MeExpr *opnd0 = opmeexpr->GetOpnd(0); - MeExpr *opnd1 = opmeexpr->GetOpnd(1); - if (opnd0->meOp != kMeOpConst || opnd1->meOp != kMeOpConst) { - return nullptr; - } - maple::ConstantFold cf(mirModule); - MIRIntConst *opnd0const = static_cast(static_cast(opnd0)->constVal); - MIRIntConst *opnd1const = static_cast(static_cast(opnd1)->constVal); - if ((opop == OP_div || opop == OP_rem)) { - int64 opnd0constValue = opnd0const->value; - int64 opnd1constValue = opnd1const->value; - PrimType resPtyp = opmeexpr->primType; - if (opnd1constValue == 0 || - (opnd1constValue == -1 && ((resPtyp == PTY_i32 && opnd0constValue == MININT32) || - (resPtyp == PTY_i64 && opnd0constValue == MININT64)))) { - return nullptr; - } - } - MIRConst *resconst = cf.FoldIntConstBinaryMIRConst(opmeexpr->op, - opmeexpr->primType, opnd0const, opnd1const); - return irMap->CreateConstMeExpr(opmeexpr->primType, resconst); - } - case OP_ne: - case OP_eq: - case OP_lt: - case OP_le: - case OP_ge: - case OP_gt: - case OP_cmp: - case OP_cmpl: - case OP_cmpg: { - MeExpr *opnd0 = opmeexpr->GetOpnd(0); - MeExpr *opnd1 = opmeexpr->GetOpnd(1); - bool isneeq = (opop == OP_ne || opop == OP_eq); - if (opnd0->meOp == kMeOpConst && opnd1->meOp == kMeOpConst) { - maple::ConstantFold cf(mirModule); - MIRConst *opnd0const = static_cast(opnd0)->constVal; - MIRConst *opnd1const = static_cast(opnd1)->constVal; - MIRConst *resconst = cf.FoldConstComparisonMIRConst(opmeexpr->op, opmeexpr->primType, opmeexpr->opndType, - opnd0const, opnd0->primType, opnd1const, opnd1->primType); - return irMap->CreateConstMeExpr(opmeexpr->primType, resconst); - } else if (isneeq && ((opnd0->meOp == kMeOpAddrof && opnd1->meOp == kMeOpConst) || - (opnd0->meOp == kMeOpConst && opnd1->meOp == kMeOpAddrof))) { - MIRConst *resconst = nullptr; - if (opnd0->meOp == kMeOpAddrof) { - MIRConst *constopnd1 = static_cast(opnd1)->constVal; - if (constopnd1->IsZero()) { - // addrof will not be zero, so this comparison can be replaced with a constant - resconst = mirModule->memPool->New((opop == OP_ne), GlobalTables::GetTypeTable().typeTable.at(PTY_u1)); - } - } else { - MIRConst *constopnd0 = static_cast(opnd0)->constVal; - if (constopnd0->IsZero()) { - // addrof will not be zero, so this comparison can be replaced with a constant - resconst = mirModule->memPool->New((opop == OP_ne), GlobalTables::GetTypeTable().typeTable.at(PTY_u1)); - } - } - if (resconst) { - return irMap->CreateConstMeExpr(opmeexpr->primType, resconst); - } - } else if (isneeq && opnd0->op == OP_select && - (opnd1->meOp == kMeOpConst && IsPrimitivePureScalar(opnd1->primType))) { - OpMeExpr *opmeopnd0 = static_cast(opnd0); - if (opmeopnd0->op == OP_select) { - MeExpr *opnd01 = opmeopnd0->GetOpnd(1); - MeExpr *opnd02 = opmeopnd0->GetOpnd(2); - if (opnd01->meOp == kMeOpConst && IsPrimitivePureScalar(opnd01->primType) && opnd02->meOp == kMeOpConst && - IsPrimitivePureScalar(opnd02->primType)) { - MIRConst *constopnd1 = static_cast(opnd1)->constVal; - MIRConst *constopnd01 = static_cast(opnd01)->constVal; - MIRConst *constopnd02 = static_cast(opnd02)->constVal; - bool needswapopnd = false; - bool canbereplaced = false; - bool isne = opmeexpr->op == OP_ne; - if (isne && constopnd1->IsZero() && constopnd01->IsOne() && constopnd02->IsZero()) { - canbereplaced = true; - } else if (isne && constopnd1->IsZero() && constopnd01->IsZero() && constopnd02->IsOne()) { - canbereplaced = true; - } else if (isne && constopnd1->IsOne() && constopnd01->IsOne() && constopnd02->IsZero()) { - needswapopnd = true; - canbereplaced = true; - } else if (isne && constopnd1->IsOne() && constopnd01->IsZero() && constopnd02->IsOne()) { - needswapopnd = true; - canbereplaced = true; - } else if (!isne && constopnd1->IsZero() && constopnd01->IsOne() && constopnd02->IsZero()) { - needswapopnd = true; - canbereplaced = true; - } else if (!isne && constopnd1->IsZero() && constopnd01->IsZero() && constopnd02->IsOne()) { - needswapopnd = true; - canbereplaced = true; - } else if (!isne && constopnd1->IsOne() && constopnd01->IsOne() && constopnd02->IsZero()) { - canbereplaced = true; - } else if (!isne && constopnd1->IsOne() && constopnd01->IsZero() && constopnd02->IsOne()) { - canbereplaced = true; - } - if (canbereplaced) { - OpMeExpr newopmeexpr(-1, OP_select, PTY_u1, 3); - newopmeexpr.SetOpnd(opmeopnd0->GetOpnd(0), 0); - ConstMeExpr xnewopnd01(-1, constopnd01, PTY_u1); - MeExpr *newopnd01 = irMap->HashMeExpr(&xnewopnd01); - ConstMeExpr xnewopnd02(-1, constopnd02, PTY_u1); - MeExpr *newopnd02 = irMap->HashMeExpr(&xnewopnd02); - if (needswapopnd) { - newopmeexpr.SetOpnd(newopnd02, 1); - newopmeexpr.SetOpnd(newopnd01, 2); - } else { - newopmeexpr.SetOpnd(newopnd01, 1); - newopmeexpr.SetOpnd(newopnd02, 2); - } - return irMap->HashMeExpr(&newopmeexpr); - } - } - } - } - return nullptr; - } - default: - return nullptr; - } -} - void Prop::PropUpdateDef(MeExpr *meexpr) { ASSERT(meexpr->meOp == kMeOpVar || meexpr->meOp == kMeOpReg, ""); OStIdx ostIdx; @@ -241,7 +64,7 @@ void Prop::PropUpdateDef(MeExpr *meexpr) { ostIdx = static_cast(meexpr)->ost->index; } else { ostIdx = static_cast(meexpr)->ost->index; - if (static_cast(meexpr)->regIdx < 0) { + if (static_cast(meexpr)->GetPregIdx() < 0) { return; } } @@ -334,9 +157,66 @@ bool Prop::IvarIsFinalField(const IvarMeExpr *ivarmeexpr) { return attrs.GetAttr(FLDATTR_final); } -// check if the expression x can be legally forward-substitute the variable that -// it was assigned to; x is from bb -bool Prop::Propagatable(MeExpr *x, BB *frombb, bool atParm) { +// if x contains operations that has no accurate inverse, return -1; also return +// -1 if x contains any scalar other than x that is not current version; +// otherwise, the return value is the number of occurrences of scalar. +int32 Prop::InvertibleOccurrences(ScalarMeExpr *scalar, MeExpr *x) { + switch (x->meOp) { + case kMeOpConst: return 0; + case kMeOpReg: { + RegMeExpr *regreadx = static_cast(x); + if (regreadx->GetPregIdx() < 0) { + return -1; + } + } + // fall thru + case kMeOpVar: + if (x == scalar) { + return 1; + } + if (Propagatable(x, nullptr, false, false, nullptr) == kPropYes) { + return 0; + } + return -1; + case kMeOpOp: + if (!IsPrimitiveInteger(x->primType)) { + return -1; + } + if (x->op == OP_neg) { + return InvertibleOccurrences(scalar, x->GetOpnd(0)); + } + if (x->op == OP_add || x->op == OP_sub) { + int32 invertibleOccs0 = InvertibleOccurrences(scalar, x->GetOpnd(0)); + if (invertibleOccs0 == -1) { + return -1; + } + int32 invertibleOccs1 = InvertibleOccurrences(scalar, x->GetOpnd(1)); + if (invertibleOccs1 == -1 || (invertibleOccs0 + invertibleOccs1 > 1)) { + return -1; + } + return invertibleOccs0 + invertibleOccs1; + } + // fall thru + default: return -1; + } +} + +// return true if scalar can be expressed as a function of current version cur +bool Prop::IsFunctionOfCurVersion(ScalarMeExpr *scalar, ScalarMeExpr *cur) { + if (cur == nullptr || cur->defBy != kDefByStmt) { + return false; + } + AssignMeStmt *ass = cur->def.defStmt; + return InvertibleOccurrences(scalar, ass->rhs) == 1; +} + +// check if the expression x can legally forward-substitute the variable that it +// was assigned to; x is from bb; if checkInverse is true and there is live range +// overlap for a scalar within x, do the additional check of whether the scalar's +// previous version can be expressed in terms of its current version. +// propagatingScalar is used only if checkInverse is true; it gives the +// propagating scalar so we can avoid doing the checkInverse checking for it. +Propagatability Prop::Propagatable(MeExpr *x, BB *frombb, bool atParm, bool checkInverse, ScalarMeExpr *propagatingScalar) { MeExprOp meOp = x->meOp; switch (meOp) { case kMeOpAddrof: @@ -346,101 +226,287 @@ bool Prop::Propagatable(MeExpr *x, BB *frombb, bool atParm) { case kMeOpConststr: case kMeOpConststr16: case kMeOpSizeoftype: - return true; + return kPropYes; case kMeOpGcmalloc: - return false; + return kPropNo; case kMeOpNary: { if (x->op == OP_intrinsicop || x->op == OP_intrinsicopwithtype) { - return false; + return kPropNo; } NaryMeExpr *narymeexpr = static_cast(x); + Propagatability propmin = kPropYes; for (uint32 i = 0; i < narymeexpr->numOpnds; i++) { - if (!Propagatable(narymeexpr->GetOpnd(i), frombb, false)) { - return false; + Propagatability prop = Propagatable(narymeexpr->GetOpnd(i), frombb, false, checkInverse, propagatingScalar); + if (prop == kPropNo) { + return kPropNo; } + propmin = std::min(propmin, prop); } - return true; + return propmin; } case kMeOpReg: { RegMeExpr *regreadx = static_cast(x); - if (regreadx->regIdx < 0) { - return false; + if (regreadx->GetPregIdx() < 0) { + return kPropNo; } else { // get the current definition version vector regreadxVec; CollectSubVarMeExpr(x, regreadxVec); - return IsVersionConsistent(regreadxVec, vst_live_stack_vec); + if (IsVersionConsistent(regreadxVec, vst_live_stack_vec)) { + return kPropYes; + } else if (checkInverse && regreadx->ost != propagatingScalar->ost) { + MapleStack *pstack = vst_live_stack_vec[regreadx->ost->index.idx]; + return IsFunctionOfCurVersion(regreadx, static_cast(pstack->top())) ? kPropOnlyWithInverse : kPropNo; + } else { + return kPropNo; + } } } case kMeOpVar: { VarMeExpr *varmeexpr = static_cast(x); if (varmeexpr->IsVolatile(ssaTab)) { - return false; + return kPropNo; } MIRSymbol *st = varmeexpr->ost->GetMIRSymbol(); if (st->wpofakeParm || st->wpofakeRet) { - return false; + return kPropNo; } if (!propagate_global_ref && st->IsGlobal() && !st->IsFinal() && !st->IgnoreRC() && !st->IsLiteralPtr()) { - return false; + return kPropNo; } if (LocalToDifferentPU(st->stIdx, frombb)) { - return false; + return kPropNo; + } + if (varmeexpr->defBy == kDefByMustdef && varmeexpr->GetType()->primType == PTY_agg) { + return kPropNo; // keep temps for storing call return values single use } // get the current definition version vector varmeexprVec; CollectSubVarMeExpr(x, varmeexprVec); - return IsVersionConsistent(varmeexprVec, vst_live_stack_vec); + if (IsVersionConsistent(varmeexprVec, vst_live_stack_vec)) { + return kPropYes; + } else if (checkInverse && varmeexpr->ost != propagatingScalar->ost && + varmeexpr->GetType()->typeKind != kTypeBitField) { + MapleStack *pstack = vst_live_stack_vec[varmeexpr->ost->index.idx]; + return IsFunctionOfCurVersion(varmeexpr, static_cast(pstack->top())) ? kPropOnlyWithInverse : kPropNo; + } else { + return kPropNo; + } } case kMeOpIvar: { IvarMeExpr *ivarmeexpr = static_cast(x); if (!IvarIsFinalField(ivarmeexpr) && !GlobalTables::GetTypeTable().typeTable[ivarmeexpr->tyIdx.GetIdx()]->PointsToConstString()) { if ((!propagate_iload_ref || (propagate_iload_ref_nonparm && atParm)) && ivarmeexpr->primType == PTY_ref) { - return false; + return kPropNo; } } if (frombb->InTryBlock() && !curbb->InTryBlock()) { - return false; - } - if (!Propagatable(ivarmeexpr->base, frombb, false)) { - return false; + return kPropNo; } if (ivarmeexpr->IsVolatile() || ivarmeexpr->IsRCWeak()) { - return false; + return kPropNo; + } + Propagatability prop0 = Propagatable(ivarmeexpr->base, frombb, false, false, nullptr); + if (prop0 == kPropNo) { + return kPropNo; } // get the current definition version vector varmeexprVec; CollectSubVarMeExpr(x, varmeexprVec); - return IsVersionConsistent(varmeexprVec, vst_live_stack_vec); + return IsVersionConsistent(varmeexprVec, vst_live_stack_vec) ? prop0 : kPropNo; } case kMeOpOp: { if (kOpcodeInfo.NotPure(x->op)) { - return false; + return kPropNo; } if (x->op == OP_gcmallocjarray) { - return false; + return kPropNo; } OpMeExpr *meopexpr = static_cast(x); MeExpr *opnd0 = meopexpr->GetOpnd(0); - if (!Propagatable(opnd0, frombb, false)) { - return false; + Propagatability prop0 = Propagatable(opnd0, frombb, false, checkInverse, propagatingScalar); + if (prop0 == kPropNo) { + return kPropNo; } MeExpr *opnd1 = meopexpr->GetOpnd(1); if (!opnd1) { - return true; + return prop0; } - if (!Propagatable(opnd1, frombb, false)) { - return false; + Propagatability prop1 = Propagatable(opnd1, frombb, false, checkInverse, propagatingScalar); + if (prop1 == kPropNo) { + return kPropNo; } + prop1 = std::min(prop0, prop1); MeExpr *opnd2 = meopexpr->GetOpnd(2); if (!opnd2) { - return true; + return prop1; } - return Propagatable(opnd2, frombb, false); + Propagatability prop2 = Propagatable(opnd2, frombb, false, checkInverse, propagatingScalar); + return std::min(prop1, prop2); } default: CHECK_FATAL(false, "MeProp::Propagatable() NYI"); - return false; + return kPropNo; + } +} + +// Expression x contains v; form and return the inverse of this expression based +// on the current version of v by descending x; formingExp is the tree being +// constructed during the descent; x must contain one and only one occurrence of +// v; work is done when it reaches the v node inside x. +MeExpr *Prop::FormInverse(ScalarMeExpr *v, MeExpr *x, MeExpr *formingExp) { + MeExpr *newx = nullptr; + switch (x->meOp) { + case kMeOpVar: + case kMeOpReg: + if (x == v) { + return formingExp; + }; + return x; + case kMeOpOp: { + OpMeExpr *opx = static_cast(x); + if (opx->op == OP_neg) { // negate formingExp and recurse down + OpMeExpr negx(-1, OP_neg, opx->primType, 1); + negx.SetOpnd(formingExp, 0); + newx = irMap->HashMeExpr(&negx); + return FormInverse(v, opx->GetOpnd(0), newx); + } + if (opx->op == OP_add) { // 2 patterns depending on which side contains v + OpMeExpr subx(-1, OP_sub, opx->primType, 2); + subx.SetOpnd(formingExp, 0); + if (InvertibleOccurrences(v, opx->GetOpnd(0)) == 0) { + // ( ..i2.. ) = y + ( ..i1.. ) becomes ( ..i2.. ) - y = ( ..i1.. ) + // form formingExp - opx->GetOpnd(0) + subx.SetOpnd(opx->GetOpnd(0), 1); + newx = irMap->HashMeExpr(&subx); + return FormInverse(v, opx->GetOpnd(1), newx); + } else { + // ( ..i2.. ) = ( ..i1.. ) + y becomes ( ..i2.. ) - y = ( ..i1.. ) + // form formingExp - opx->GetOpnd(1) + subx.SetOpnd(opx->GetOpnd(1), 1); + newx = irMap->HashMeExpr(&subx); + return FormInverse(v, opx->GetOpnd(0), newx); + } + } + if (opx->op == OP_sub) { + if (InvertibleOccurrences(v, opx->GetOpnd(0)) == 0) { + // ( ..i2.. ) = y - ( ..i1.. ) becomes y - ( ..i2.. ) = ( ..i1.. ) + // form opx->GetOpnd(0) - formingExp + OpMeExpr subx(-1, OP_sub, opx->primType, 2); + subx.SetOpnd(opx->GetOpnd(0), 0); + subx.SetOpnd(formingExp, 1); + newx = irMap->HashMeExpr(&subx); + return FormInverse(v, opx->GetOpnd(1), newx); + } else { + // ( ..i2.. ) = ( ..i1.. ) - y becomes ( ..i2.. ) + y = ( ..i1.. ) + // form formingExp + opx->GetOpnd(1) + OpMeExpr addx(-1, OP_add, opx->primType, 2); + addx.SetOpnd(formingExp, 0); + addx.SetOpnd(opx->GetOpnd(1), 1); + newx = irMap->HashMeExpr(&addx); + return FormInverse(v, opx->GetOpnd(0), newx); + } + } + // fall-thru + } + default: CHECK_FATAL(false, "FormInverse: should not see these nodes"); + } +} + +// recurse down the expression tree x; at the scalar whose version is different +// from the current version, replace it by an expression corresponding to the +// inverse of how its current version is computed from it; if there is no change, +// return NULL; if there is change, rehash on the way back +MeExpr *Prop::RehashUsingInverse(MeExpr *x) { + switch (x->meOp) { + case kMeOpVar: + case kMeOpReg: { + ScalarMeExpr *scalar = static_cast(x); + MapleStack *pstack = vst_live_stack_vec[scalar->ost->index.idx]; + if (pstack == nullptr || pstack->top() == scalar) { + return nullptr; + } + ScalarMeExpr *curScalar = static_cast(pstack->top()); + return FormInverse(scalar, curScalar->def.defStmt->rhs, curScalar); + } + case kMeOpIvar: { + IvarMeExpr *ivarx = static_cast(x); + MeExpr *result = RehashUsingInverse(ivarx->base); + if (result != nullptr) { + IvarMeExpr newivarx(-1, ivarx->primType, ivarx->tyIdx, ivarx->fieldID); + newivarx.base = result; + newivarx.mu = ivarx->mu; + return irMap->HashMeExpr(&newivarx); + } + return nullptr; + } + case kMeOpOp: { + OpMeExpr *opx = static_cast(x); + MeExpr *res0 = RehashUsingInverse(opx->GetOpnd(0)); + MeExpr *res1 = nullptr; + MeExpr *res2 = nullptr; + if (opx->numOpnds > 1) { + res1 = RehashUsingInverse(opx->GetOpnd(1)); + if (opx->numOpnds > 2) { + res2 = RehashUsingInverse(opx->GetOpnd(2)); + } + } + if (res0 == nullptr && res1 == nullptr && res2 == nullptr) { + return nullptr; + } + OpMeExpr newopx(-1, opx->op, opx->primType, opx->numOpnds); + newopx.opndType = opx->opndType; + newopx.bitsOffset = opx->bitsOffset; + newopx.bitsSize = opx->bitsSize; + newopx.tyIdx = opx->tyIdx; + newopx.fieldID = opx->fieldID; + if (res0) { + newopx.SetOpnd(res0, 0); + } else { + newopx.SetOpnd(opx->GetOpnd(0), 0); + } + if (opx->numOpnds > 1) { + if (res1) { + newopx.SetOpnd(res1, 1); + } else { + newopx.SetOpnd(opx->GetOpnd(1), 1); + } + if (opx->numOpnds > 2) { + if (res1) { + newopx.SetOpnd(res2, 2); + } else { + newopx.SetOpnd(opx->GetOpnd(2), 2); + } + } + } + return irMap->HashMeExpr(&newopx); + } + case kMeOpNary: { + NaryMeExpr *naryx = static_cast(x); + std::vector results(naryx->numOpnds, nullptr); + bool needRehash = false; + uint32 i; + for (i = 0; i < naryx->numOpnds; i++) { + results[i] = RehashUsingInverse(naryx->GetOpnd(i)); + if (results[i] != nullptr) { + needRehash = true; + } + } + if (!needRehash) { + return nullptr; + } + NaryMeExpr newnaryx(&prop_map_alloc, -1, naryx->op, naryx->primType, + naryx->numOpnds, naryx->tyIdx, naryx->intrinsic, naryx->boundCheck); + for (i = 0; i < naryx->numOpnds; i++) { + if (results[i] != nullptr) { + newnaryx.SetOpnd(results[i], i); + } else { + newnaryx.SetOpnd(naryx->GetOpnd(i), i); + } + } + return irMap->HashMeExpr(&newnaryx); + } + default: return nullptr; } } @@ -508,6 +574,34 @@ MeExpr *Prop::CheckTruncation(MeExpr *lhs, MeExpr *rhs) { return irMap->HashMeExpr(&opmeexpr); } } + // if lhs is function pointer and rhs is not, insert a retype + if (lhsTy->typeKind == kTypePointer) { + MIRPtrType *lhsPtrType = static_cast(lhsTy); + if (lhsPtrType->GetPointedType()->typeKind == kTypeFunction) { + bool needRetype = true; + MIRType *rhsTy = nullptr; + if (rhs->meOp == kMeOpVar) { + VarMeExpr *rhsvarx = static_cast(rhs); + rhsTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(rhsvarx->ost->tyIdx); + } else if (rhs->meOp == kMeOpIvar) { + IvarMeExpr *rhsivarx = static_cast(rhs); + MIRPtrType *rhsPtrType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(rhsivarx->tyIdx)); + rhsTy = rhsPtrType->GetPointedType(); + if (rhsivarx->fieldID != 0) { + rhsTy = static_cast(rhsTy)->GetFieldType(rhsivarx->fieldID); + } + } + if (rhsTy != nullptr && rhsTy == lhsPtrType) { + needRetype = false; + } + if (needRetype) { + OpMeExpr opmeexpr(-1, OP_retype, lhsPtrType->primType, 1); + opmeexpr.tyIdx = lhsPtrType->tyIdx; + opmeexpr.SetOpnd(rhs, 0); + return irMap->HashMeExpr(&opmeexpr); + } + } + } return rhs; } @@ -525,11 +619,18 @@ MeExpr *Prop::PropVar(VarMeExpr *varmeexpr, bool atParm, bool checkPhi) { DassignMeStmt *defStmt = dynamic_cast(varmeexpr->def.defStmt); CHECK_FATAL(defStmt != nullptr, "dynamic cast result is nullptr"); MeExpr *rhs = defStmt->rhs; - if (rhs->GetDepth() <= kPropTreeLevel && Propagatable(rhs, defStmt->bb, atParm)) { + if (rhs->GetDepth() > kPropTreeLevel) { + return varmeexpr; + } + Propagatability propagatable = Propagatable(rhs, defStmt->bb, atParm, true, varmeexpr); + if (propagatable != kPropNo) { // mark propagated for iread ref if (rhs->meOp == kMeOpIvar && rhs->primType == PTY_ref) { defStmt->propagated = true; } + if (propagatable == kPropOnlyWithInverse) { + rhs = RehashUsingInverse(rhs); + } return CheckTruncation(varmeexpr, rhs); } else { return varmeexpr; @@ -566,7 +667,14 @@ MeExpr *Prop::PropReg(RegMeExpr *regmeexpr, bool atParm) { } ASSERT(defStmt, ""); MeExpr *rhs = defStmt->rhs; - if (rhs->GetDepth() <= kPropTreeLevel && Propagatable(rhs, defStmt->bb, atParm)) { + if (rhs->GetDepth() > kPropTreeLevel) { + return regmeexpr; + } + Propagatability propagatable = Propagatable(rhs, defStmt->bb, atParm, true, regmeexpr); + if (propagatable != kPropNo) { + if (propagatable == kPropOnlyWithInverse) { + rhs = RehashUsingInverse(rhs); + } return rhs; } } @@ -579,7 +687,7 @@ MeExpr *Prop::PropIvar(IvarMeExpr *ivarmeexpr) { return ivarmeexpr; } MeExpr *rhs = defStmt->rhs; - if (rhs->GetDepth() <= kPropTreeLevel && Propagatable(rhs, defStmt->bb, false)) { + if (rhs->GetDepth() <= kPropTreeLevel && Propagatable(rhs, defStmt->bb, false) != kPropNo) { return CheckTruncation(ivarmeexpr, rhs); } return ivarmeexpr; @@ -599,7 +707,7 @@ MeExpr *Prop::PropMeExpr(MeExpr *meexpr, bool &isproped, bool atParm) { } case kMeOpReg: { RegMeExpr *regexpr = static_cast(meexpr); - if (regexpr->regIdx < 0) { + if (regexpr->GetPregIdx() < 0) { return meexpr; } MeExpr *propmeexpr = PropReg(regexpr, atParm); @@ -646,7 +754,7 @@ MeExpr *Prop::PropMeExpr(MeExpr *meexpr, bool &isproped, bool atParm) { newmeexpr.bitsSize = meopexpr->bitsSize; newmeexpr.tyIdx = meopexpr->tyIdx; newmeexpr.fieldID = meopexpr->fieldID; - MeExpr *splfmeexpr = SimplifyMeExpr(&newmeexpr); + MeExpr *splfmeexpr = irMap->SimplifyOpMeExpr(&newmeexpr); return splfmeexpr ? splfmeexpr : irMap->HashMeExpr(&newmeexpr); } else { return meopexpr; diff --git a/mapleall/maple_me/src/ssa.cpp b/mapleall/maple_me/src/ssa.cpp index 2bfc7fb6b189d4508b670503e27ffed4112fbc8c..a9d7fd716b23c7b090e28a9f1312011c1a9239e9 100644 --- a/mapleall/maple_me/src/ssa.cpp +++ b/mapleall/maple_me/src/ssa.cpp @@ -64,7 +64,7 @@ VersionSt *SSA::CreateNewVersion(VersionSt *vsym, BB *defBb) { void SSA::RenamePhi(BB *bb) { MapleMap::iterator phiIt; - for (phiIt = bb->phiList.begin(); phiIt != bb->phiList.end(); phiIt++) { + for (phiIt = bb->phiList->begin(); phiIt != bb->phiList->end(); phiIt++) { VersionSt *vsym = (*phiIt).second.result; VersionSt *newVsym = CreateNewVersion(vsym, bb); @@ -345,7 +345,7 @@ void SSA::RenamePhiUseInSucc(BB *bb) { } ASSERT(index < succBb->pred.size(), "RenamePhiUseInSucc: cannot find corresponding pred"); // rename the phiOpnds[index] in all the phis in succ_bb - for (MapleMap::iterator phiIt = succBb->phiList.begin(); phiIt != succBb->phiList.end(); + for (MapleMap::iterator phiIt = succBb->phiList->begin(); phiIt != succBb->phiList->end(); phiIt++) phiIt->second.phiOpnds[index] = vstStacks[phiIt->second.phiOpnds[index]->GetOrigIdx().idx]->top(); } diff --git a/mapleall/maple_me/src/ssa_epre_for_sr.cpp b/mapleall/maple_me/src/ssa_epre_for_sr.cpp index 25e7322a5d388fad9560c691e919b1fc099aeffe..4edc528b1202cdccb5e65facc151350f87c120da 100644 --- a/mapleall/maple_me/src/ssa_epre_for_sr.cpp +++ b/mapleall/maple_me/src/ssa_epre_for_sr.cpp @@ -189,7 +189,7 @@ static MeExpr *FindLaterRepairedTemp(MeExpr *temp, MeStmt *injuringDef) { while (rass != nullptr) { CHECK_FATAL(rass->op == OP_regassign && rass->isIncDecStmt, "FindLaterRepairedTemp: failed to find repair statement"); - if (rass->GetRegLhs()->regIdx == static_cast(temp)->regIdx) { + if (rass->GetRegLhs()->GetPregIdx() == static_cast(temp)->GetPregIdx()) { return rass->lhs; } rass = static_cast(rass->next); diff --git a/mapleall/maple_me/src/ssa_mir_nodes.cpp b/mapleall/maple_me/src/ssa_mir_nodes.cpp index 6dfe0ac5e3e264859635430fe15f9cd436272831..3a8ad448c9f33b2df788e11a05594dc0e05c92a8 100644 --- a/mapleall/maple_me/src/ssa_mir_nodes.cpp +++ b/mapleall/maple_me/src/ssa_mir_nodes.cpp @@ -35,17 +35,20 @@ void GenericSSAPrint(MIRModule *mod, BaseNode *x, int32 indent, StmtsSSAPart *st MayDefPartWithVersionSt *thessapart = static_cast(stmtsSsaprt->SsapartOf(y)); thessapart->ssaVar->Dump(mod); thessapart->MayDefPart::Print(mod, indent); + LogInfo::MapleLogger() << endl; return; } case OP_regassign: { LogInfo::MapleLogger() << " "; VersionSt *thessapart = static_cast(stmtsSsaprt->SsapartOf(y)); thessapart->Dump(mod); + LogInfo::MapleLogger() << endl; return; } case OP_iassign: { MayDefPart *thessapart = static_cast(stmtsSsaprt->SsapartOf(y)); thessapart->MayDefPart::Print(mod, indent); + LogInfo::MapleLogger() << endl; return; } case OP_throw: @@ -53,7 +56,7 @@ void GenericSSAPrint(MIRModule *mod, BaseNode *x, int32 indent, StmtsSSAPart *st case OP_return: { MayUsePart *thessapart = static_cast(stmtsSsaprt->SsapartOf(y)); thessapart->MayUsePart::Print(mod, indent); - LogInfo::MapleLogger() << std::endl; + LogInfo::MapleLogger() << endl; return; } case OP_syncenter: @@ -74,6 +77,7 @@ void GenericSSAPrint(MIRModule *mod, BaseNode *x, int32 indent, StmtsSSAPart *st thessapart->MayUsePart::Print(mod, indent); LogInfo::MapleLogger() << std::endl; thessapart->MayDefPart::Print(mod, indent); + LogInfo::MapleLogger() << endl; return; } case OP_callassigned: @@ -90,8 +94,11 @@ void GenericSSAPrint(MIRModule *mod, BaseNode *x, int32 indent, StmtsSSAPart *st case OP_intrinsiccallwithtypeassigned: { MayDefMayUseMustDefPart *thessapart = static_cast(stmtsSsaprt->SsapartOf(y)); thessapart->MayUsePart::Print(mod, indent); + LogInfo::MapleLogger() << endl; thessapart->MustDefPart::Print(mod, indent); + LogInfo::MapleLogger() << endl; thessapart->MayDefPart::Print(mod, indent); + LogInfo::MapleLogger() << endl; return; } default: diff --git a/mapleall/maple_me/src/sync_select.cpp b/mapleall/maple_me/src/sync_select.cpp index 77186921bf123af43c1ef21721e2ea0182c57e59..fcfdf460bcfe18858ee4ede015baf465639eb61b 100644 --- a/mapleall/maple_me/src/sync_select.cpp +++ b/mapleall/maple_me/src/sync_select.cpp @@ -46,7 +46,7 @@ void SyncSelect::SetSyncKind(StmtNode *stmt, uint32_t n) const { } void SyncSelect::SetAllSyncKind(uint32_t n) { - for (auto bb : currfunc_->bbVec) { + for (auto bb : currfunc_->theCFG->bbVec) { if (bb == nullptr) { continue; } diff --git a/mapleall/maple_phase/include/phase.h b/mapleall/maple_phase/include/phase.h index 05c154f0d94a412d820fdd14e4a33724d568c522..c993f655f01a1f306570ffb9b508ef20844459cb 100644 --- a/mapleall/maple_phase/include/phase.h +++ b/mapleall/maple_phase/include/phase.h @@ -78,7 +78,7 @@ class AnalysisResultManager { } /* analysis result use global mempool and allocator */ - AnalysisResult *GetAnalysisResult(PhaseIDT id, UnitIR *ir) { + AnalysisResult *GetAnalysisResult(PhaseIDT id, UnitIR *ir, bool verbose = false) { ASSERT(ir, "ir is null in AnalysisResultManager::GetAnalysisResult"); std::pair key = std::make_pair(id, ir); if (analysisResults.find(key) != analysisResults.end()) { @@ -87,6 +87,9 @@ class AnalysisResultManager { PhaseT *anaphase = GetAnalysisPhase(id); ASSERT(anaphase != nullptr, "anaphse is null in AnalysisResultManager::GetAnalysisResult"); if (std::string(anaphase->PhaseName()) != Options::skipPhase) { + if (verbose) { + LogInfo::MapleLogger() << " ++ depended phase [ " << anaphase->PhaseName() << " ] invoked\n"; + } AnalysisResult *result = anaphase->Run(ir, this); analysisResults[key] = result; /* add r to analysisResults */ return result; diff --git a/mapleall/mpl2mpl/BUILD.gn b/mapleall/mpl2mpl/BUILD.gn index 75aa3619e0477cc6ee618709f6059eb2d17d25c2..ecb7bbba85f1597ad36dc412d337e7d62449184c 100644 --- a/mapleall/mpl2mpl/BUILD.gn +++ b/mapleall/mpl2mpl/BUILD.gn @@ -53,7 +53,7 @@ static_library("libmpl2mpl"){ include_dirs = include_directories - output_name = "liblibmpl2mpl" + output_name = "libmpl2mpl" output_dir = "${root_out_dir}/lib/${HOST_ARCH}" } diff --git a/mapleall/mpl2mpl/src/native_stub_func.cpp b/mapleall/mpl2mpl/src/native_stub_func.cpp index ba1535dc00e0fd04120190e855198a6712731b3f..208b0e45d1dc7a9e7ded3001bf8960c089169dd0 100644 --- a/mapleall/mpl2mpl/src/native_stub_func.cpp +++ b/mapleall/mpl2mpl/src/native_stub_func.cpp @@ -65,7 +65,7 @@ MIRFunction *GenNativeStubFunc::GetOrCreateDefaultNativeFunc(MIRFunction *stubFu std::string nativeName = NameMangler::NativeJavaName(stubFunc->GetName().c_str()); // No need to create a default function with exact arguments here MIRFunction *nativeFunc = builder->GetOrCreateFunction(nativeName, stubFunc->GetReturnTyIdx()); - nativeFunc->srcPosition.SetMplLinenum(stubFunc->srcPosition.MplLinenum()); + nativeFunc->GetFuncSymbol()->srcPosition.SetMplLinenum(stubFunc->GetFuncSymbol()->srcPosition.MplLinenum()); if (!nativeFunc->body) { if (nativeFunc->symTab == nullptr) { diff --git a/tools/setup_tools.sh b/tools/setup_tools.sh index 34068c4363faae785e11260b951a01e22dcc2944..47e491744792966b2b69948b881bc28079b46234 100755 --- a/tools/setup_tools.sh +++ b/tools/setup_tools.sh @@ -14,6 +14,8 @@ # See the MulanPSL - 2.0 for more details. # +set -e + if [ ! -f ../bin/ast2mpl ]; then cd ../bin/ast2mpl_files cat ast2mpl_aa ast2mpl_ab ast2mpl_ac ast2mpl_ad > ast2mpl.gz @@ -24,13 +26,13 @@ if [ ! -f ../bin/ast2mpl ]; then echo Merged ast2mpl. fi -if [ ! -f ./ninja_1.9.0/ninja ]; then - mkdir -p ./ninja_1.9.0 - cd ./ninja_1.9.0 || exit 3 - wget https://github.com/ninja-build/ninja/releases/download/v1.9.0/ninja-linux.zip +if [ ! -f ./ninja/ninja ]; then + mkdir -p ./ninja + cd ./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 1.9.0. + echo Downloaded ninja. fi if [ ! -f ./gn/gn ]; then