diff --git a/src/bin/jbc2mpl b/src/bin/jbc2mpl index 8cf35911375409c7a31cc1e449919aab9c43d5a0..2ad498a2eb8478ca053475d708161e35d0d502af 100755 Binary files a/src/bin/jbc2mpl and b/src/bin/jbc2mpl differ diff --git a/src/bin/maple b/src/bin/maple index 08017e8d8df11bbfd53a466f8fe11da4c705964a..0f5b3166f40c48c164e07747271b2b1b99760362 100755 Binary files a/src/bin/maple and b/src/bin/maple differ diff --git a/src/deplibs/libmplphase.a b/src/deplibs/libmplphase.a index 6abb8796f8073c4f9be0cecb996c547c3ceeb692..ca1ed9dfbe87951d7a3d5ec221e0c1eefaf59d0e 100644 Binary files a/src/deplibs/libmplphase.a and b/src/deplibs/libmplphase.a differ diff --git a/src/deplibs/libmplutil.a b/src/deplibs/libmplutil.a index fca65f2c2e2d244c91075e6d915480e86d415ac6..dc9e9e919d31623b7d68a4b756894e71351bce4f 100644 Binary files a/src/deplibs/libmplutil.a and b/src/deplibs/libmplutil.a differ diff --git a/src/maple_be/include/be/common_utils.h b/src/maple_be/include/be/common_utils.h index ab10e3c7cb66d7d3e83a3788874a5ddb3be32965..b2f3583e753a1d04527f1e1b911eff61d8895d22 100644 --- a/src/maple_be/include/be/common_utils.h +++ b/src/maple_be/include/be/common_utils.h @@ -66,8 +66,8 @@ constexpr int32 kInsnEighthOpnd = 7; /* Check whether the value is an even number. */ constexpr int32 kDivide2 = 2; constexpr int32 kRegNum2 = 2; -constexpr int32 kModNum2 = 2; constexpr int32 kStepNum2 = 2; +constexpr int32 kSign4ByteSize = 4; /* * if the number of local refvar is less than 12, use stp or str to init local refvar diff --git a/src/maple_be/include/be/lower.h b/src/maple_be/include/be/lower.h index e92cd6bc48c9f2ab9a69c1aeb6e2d43df854aec4..76a4b300cab8de94ac9456081983b598f7a2e3b6 100644 --- a/src/maple_be/include/be/lower.h +++ b/src/maple_be/include/be/lower.h @@ -120,6 +120,8 @@ class CGLowerer { void LowerGCMalloc(const BaseNode &node, const GCMallocNode &gcNode, BlockNode &blkNode, bool perm = false); + std::string GetNewArrayFuncName(const uint32 elemSize, const bool perm) const; + void LowerJarrayMalloc(const StmtNode &stmt, const JarrayMallocNode &node, BlockNode &block, bool perm = false); BaseNode *LowerAddrof(AddrofNode &addrof) { diff --git a/src/maple_be/include/cg/aarch64/aarch64_cgfunc.h b/src/maple_be/include/cg/aarch64/aarch64_cgfunc.h index 69bdddae4b7a0e9030ae1ec90351a4ca62c768f6..6cb19f0fd9102720080ea5ff72fbb8200990c187 100644 --- a/src/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -265,7 +265,7 @@ class AArch64CGFunc : public CGFunc { return GetOrCreatePhysicalRegisterOperand(RFP, kSizeOfPtr * kBitsPerByte, kRegTyInt); } - MemOperand &GetOrCreateMemOpnd(const MIRSymbol &symbol, int32 offset, uint32 size, bool forLocalRef = false) override; + MemOperand &GetOrCreateMemOpnd(const MIRSymbol &symbol, int32 offset, uint32 size, bool forLocalRef = false); AArch64MemOperand &GetOrCreateMemOpnd(AArch64MemOperand::AArch64AddressingMode, uint32, RegOperand*, RegOperand*, OfstOperand*, const MIRSymbol*); @@ -278,9 +278,9 @@ class AArch64CGFunc : public CGFunc { return CreateMemOpnd(baseOpnd, offset, size); } - MemOperand &CreateMemOpnd(RegOperand &baseOpnd, int32 offset, uint32 size) override; + MemOperand &CreateMemOpnd(RegOperand &baseOpnd, int32 offset, uint32 size); - MemOperand &CreateMemOpnd(RegOperand &baseOpnd, int32 offset, uint32 size, const MIRSymbol &sym) override; + MemOperand &CreateMemOpnd(RegOperand &baseOpnd, int32 offset, uint32 size, const MIRSymbol &sym); MemOperand &CreateMemOpnd(PrimType ptype, const BaseNode &parent, BaseNode &addrExpr, int32 offset = 0, AArch64isa::MemoryOrdering memOrd = AArch64isa::kMoNone); @@ -420,6 +420,7 @@ class AArch64CGFunc : public CGFunc { MOperator PickStInsn(uint32 bitSize, PrimType primType, AArch64isa::MemoryOrdering memOrd = AArch64isa::kMoNone); MOperator PickLdInsn(uint32 bitSize, PrimType primType, AArch64isa::MemoryOrdering memOrd = AArch64isa::kMoNone); + bool CheckIfSplitOffsetWithAdd(const AArch64MemOperand &memOpnd, uint32 bitLen); AArch64MemOperand &SplitOffsetWithAddInstruction(const AArch64MemOperand &memOpnd, uint32 bitLen, AArch64reg baseRegNum = AArch64reg::kRinvalid, uint32 isDest = 0, Insn *insn = nullptr); @@ -567,6 +568,7 @@ class AArch64CGFunc : public CGFunc { bool GenerateCompareWithZeroInstruction(Opcode jmpOp, Opcode cmpOp, bool is64Bits, LabelOperand &targetOpnd, Operand &opnd0); void SelectMPLClinitCheck(IntrinsiccallNode&); + void SelectMPLProfCounterInc(IntrinsiccallNode &intrnNode); /* Helper functions for translating complex Maple IR instructions/inrinsics */ void SelectDassign(StIdx stIdx, FieldID fieldId, PrimType rhsPType, Operand &opnd0); LabelIdx CreateLabeledBB(StmtNode &stmt); diff --git a/src/maple_be/include/cg/aarch64/aarch64_insn.h b/src/maple_be/include/cg/aarch64/aarch64_insn.h index 8eb1d440af54d70deeeef8aae0c599ef9368e1d8..0127e84295b945ce447cf557f68f6dbae4aef491 100644 --- a/src/maple_be/include/cg/aarch64/aarch64_insn.h +++ b/src/maple_be/include/cg/aarch64/aarch64_insn.h @@ -167,6 +167,7 @@ class AArch64Insn : public Insn { void EmitGetAndSetInt(Emitter &emitter) const; void EmitCompareAndSwapInt(Emitter &emitter) const; void EmitStringIndexOf(Emitter &emitter) const; + void EmitCounter(const CG&, Emitter&) const; }; class AArch64cleancallInsn : public AArch64Insn { diff --git a/src/maple_be/include/cg/aarch64/aarch64_isa.def b/src/maple_be/include/cg/aarch64/aarch64_isa.def index df42ddc6d51d09f21c4f15c06e32cf0a54f0f5e6..06f930473d4c345a54310099e3ac97a0e0af4db6 100644 --- a/src/maple_be/include/cg/aarch64/aarch64_isa.def +++ b/src/maple_be/include/cg/aarch64/aarch64_isa.def @@ -267,6 +267,7 @@ MOP_dmb_ishld, MOP_dmb_ishst, MOP_dmb_ish, MOP_clinit, +MOP_counter, MOP_lazy_ldr, MOP_lazy_ldr_static, MOP_lazy_tail, diff --git a/src/maple_be/include/cg/aarch64/aarch64_memlayout.h b/src/maple_be/include/cg/aarch64/aarch64_memlayout.h index a01fd609e9ca3587ecd917cbd94cae6040952a7d..9e4e5179086b1481bf5870d68d76fb99d1ba66a5 100644 --- a/src/maple_be/include/cg/aarch64/aarch64_memlayout.h +++ b/src/maple_be/include/cg/aarch64/aarch64_memlayout.h @@ -175,12 +175,12 @@ class AArch64MemLayout : public MemLayout { MemSegment segSpillReg = MemSegment(kMsSpillReg); MemSegment segLocals = MemSegment(kMsLocals); /* these are accessed via Frame Pointer */ int32 fixStackSize = 0; - void setSegmentSize(AArch64SymbolAlloc &symbolAlloc, MemSegment &segment, uint32 typeIdx); - void layoutFormalParams(); - void layoutActualParams(); - void layoutLocalVariales(std::vector &tempVar, std::vector &returnDelays); - void layoutEAVariales(std::vector &tempVar); - void layoutReturnRef(std::vector &returnDelays); + void SetSegmentSize(AArch64SymbolAlloc &symbolAlloc, MemSegment &segment, uint32 typeIdx); + void LayoutFormalParams(); + void LayoutActualParams(); + void LayoutLocalVariales(std::vector &tempVar, std::vector &returnDelays); + void LayoutEAVariales(std::vector &tempVar); + void LayoutReturnRef(std::vector &returnDelays); }; } /* namespace maplebe */ diff --git a/src/maple_be/include/cg/cfi.def b/src/maple_be/include/cg/cfi.def index 8686655ccc454c6996ffc78245530eb6309b2e3a..85ede3e259877dc2b1e54c61b05111d936896081 100644 --- a/src/maple_be/include/cg/cfi.def +++ b/src/maple_be/include/cg/cfi.def @@ -46,3 +46,8 @@ CFI_DEFINE( signal_frame, , 0, Undef, Undef, Undef ) CFI_DEFINE( window_save, , 0, Undef, Undef, Undef ) CFI_DEFINE( escape, , 2, StImmediate, List /*expression[, ...]*/, Undef ) CFI_DEFINE( val_encoded_addr, , 3, Register, Immediate, StImmediate ) + +ARM_DIRECTIVES_DEFINE( save, , 1, List, Undef, Undef ) +ARM_DIRECTIVES_DEFINE( vsave, , 1, List, Undef, Undef ) +ARM_DIRECTIVES_DEFINE( setfp, , 2, Register, Immediate, Undef ) +ARM_DIRECTIVES_DEFINE( pad, , 1, Immediate, Undef, Undef ) diff --git a/src/maple_be/include/cg/cfi.h b/src/maple_be/include/cg/cfi.h index 960fbebcbb6f0ad477337d29dd0fcb8856bd24e5..697efd6e1548ef7a1c97b42f9063b4dab9da10c0 100644 --- a/src/maple_be/include/cg/cfi.h +++ b/src/maple_be/include/cg/cfi.h @@ -47,8 +47,10 @@ using namespace maple; enum CfiOpcode : uint8 { #define CFI_DEFINE(k, sub, n, o0, o1, o2) OP_CFI_##k##sub, +#define ARM_DIRECTIVES_DEFINE(k, sub, n, o0, o1, o2) OP_ARM_DIRECTIVES_##k##sub, #include "cfi.def" #undef CFI_DEFINE +#undef ARM_DIRECTIVES_DEFINE kOpCfiLast }; @@ -211,4 +213,4 @@ class LabelOperand : public maplebe::Operand { }; } /* namespace cfi */ -#endif /* MAPLEBE_INCLUDE_CG_CFI_H */ \ No newline at end of file +#endif /* MAPLEBE_INCLUDE_CG_CFI_H */ diff --git a/src/maple_be/include/cg/cgfunc.h b/src/maple_be/include/cg/cgfunc.h index fc795e98e4581969270b96e00e8d55b02271d3c0..5ed67c860fda3885e14d18e27ad09dc45fd92757 100644 --- a/src/maple_be/include/cg/cgfunc.h +++ b/src/maple_be/include/cg/cgfunc.h @@ -232,10 +232,6 @@ class CGFunc { virtual RegOperand &GetOrCreateFramePointerRegOperand() = 0; virtual RegOperand &GetOrCreateStackBaseRegOperand() = 0; virtual uint32 GetBaseOffset(const SymbolAlloc &symbolAlloc) = 0; - virtual MemOperand &GetOrCreateMemOpnd(const MIRSymbol &symbol, int32 offset, - uint32 size, bool forLocalRef = false) = 0; - virtual MemOperand &CreateMemOpnd(RegOperand &baseOpnd, int32 offset, uint32 size) = 0; - virtual MemOperand &CreateMemOpnd(RegOperand &baseOpnd, int32 offset, uint32 size, const MIRSymbol &sym) = 0; virtual Operand &GetZeroOpnd(uint32 size) = 0; virtual Operand &CreateCfiRegOperand(uint32 reg, uint32 size) = 0; virtual Operand &GetTargetRetOperand(PrimType primType) = 0; @@ -247,6 +243,9 @@ class CGFunc { virtual Operand *GetTrueOpnd() { return nullptr; } + virtual void ClearUnreachableGotInfos(BB &bb) { + return; + } LabelIdx CreateLabel(); virtual Operand &CreateFPImmZero(PrimType primType) = 0; diff --git a/src/maple_be/include/cg/datainfo.h b/src/maple_be/include/cg/datainfo.h index 897b5317bc99ea9fd7e2e68a9a90800d8ad664e5..545d0a4a1cd1c1c210642ebc306fb09681b7be5e 100644 --- a/src/maple_be/include/cg/datainfo.h +++ b/src/maple_be/include/cg/datainfo.h @@ -1,190 +1,190 @@ -/* - * 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. - */ -#ifndef MAPLEBE_INCLUDE_CG_DATAINFO_H -#define MAPLEBE_INCLUDE_CG_DATAINFO_H -#include - -namespace maplebe { -class DataInfo { - public: - explicit DataInfo(uint32 bitNum) : info(bitNum / kWordSize + 1, 0ULL) {} - - ~DataInfo() = default; - - void SetBit(uint32 bitNO) { - ASSERT(bitNO < info.size() * kWordSize, "Out of Range"); - info[bitNO / kWordSize] |= (1ULL << (bitNO % kWordSize)); - } - - void ResetBit(uint32 bitNO) { - info[bitNO / kWordSize] &= (~(1ULL << (bitNO % kWordSize))); - } - - bool TestBit(uint32 bitNO) const { - return (info[bitNO / kWordSize] & (1ULL << (bitNO % kWordSize))) != 0ULL; - } - - const uint64 &GetElem(uint32 index) const { - ASSERT(index < info.size(), "out of range"); - return info[index]; - } - - void SetElem(uint32 index, uint64 val) { - ASSERT(index < info.size(), "out of range"); - info[index] = val; - } - - bool NoneBit() const { - for (auto &data : info) { - if (data != 0ULL) { - return false; - } - } - return true; - } - - size_t Size() const { - return info.size() * kWordSize; - } - - const std::vector &GetInfo() const { - return info; - } - - bool IsEqual(const DataInfo &secondInfo) const { - auto infoSize = static_cast(info.size()); - ASSERT(infoSize == secondInfo.GetInfo().size(), "two dataInfo's size different"); - for (int32 i = 0; i != infoSize; i++) { - if (info[i] != secondInfo.GetElem(i)) { - return false; - } - } - return true; - } - - void AndBits(const DataInfo &secondInfo) { - auto infoSize = static_cast(info.size()); - ASSERT(infoSize == secondInfo.GetInfo().size(), "two dataInfo's size different"); - for (int32 i = 0; i != infoSize; i++) { - info[i] &= secondInfo.GetElem(i); - } - } - - void OrBits(const DataInfo &secondInfo) { - auto infoSize = static_cast(info.size()); - ASSERT(infoSize == secondInfo.GetInfo().size(), "two dataInfo's size different"); - for (int32 i = 0; i != infoSize; i++) { - info[i] |= secondInfo.GetElem(i); - } - } - - void OrDesignateBits(const DataInfo &secondInfo, uint32 infoIndex) { - ASSERT(infoIndex < secondInfo.GetInfo().size(), "out of secondInfo's range"); - ASSERT(infoIndex < info.size(), "out of secondInfo's range"); - info[infoIndex] |= secondInfo.GetElem(infoIndex); - } - - void EorBits(const DataInfo &secondInfo) { - auto infoSize = static_cast(info.size()); - ASSERT(infoSize == secondInfo.GetInfo().size(), "two dataInfo's size different"); - for (int32 i = 0; i != infoSize; i++) { - info[i] ^= secondInfo.GetElem(i); - } - } - - /* if bit in secondElem is 1, bit in current DataInfo is set 0 */ - void Difference(const DataInfo &secondInfo) { - auto infoSize = static_cast(info.size()); - ASSERT(infoSize == secondInfo.GetInfo().size(), "two dataInfo's size different"); - for (int32 i = 0; i != infoSize; i++) { - info[i] &= (~(secondInfo.GetElem(i))); - } - } - - void ResetAllBit() { - for (auto &data : info) { - data = 0ULL; - } - } - - void EnlargeCapacityToAdaptSize(uint32 bitNO) { - /* add one more size for each enlarge action */ - auto sizeToEnlarge = static_cast((bitNO / kWordSize + 1) - info.size()); - for (int32 i = 0; i < sizeToEnlarge; i++) { - info.push_back(0ULL); - } - } - - void GetNonZeroElemsIndex(std::set &index) { - auto infoSize = static_cast(info.size()); - for (int32 i = 0; i < infoSize; i++) { - if (info[i] != 0ULL) { - index.insert(i); - } - } - } - - int32 GetInfoIndex(const uint32 bitNO) const { - return bitNO / kWordSize; - } - - std::set GetBitsOfInfo() const { - std::set wordRes; - wordRes.clear(); - for (size_t i = 0; i != info.size(); ++i) { - uint32 result = 0; - uint64 word = info[i]; - uint32 offset = 0; - uint32 baseWord = 0; - bool firstTime = true; - while (word) { - int32 index = __builtin_ffsll(word); - if (index == 0) { - continue; - } - if (index == k64BitSize) { - /* when the highest bit is 1, the shift operation will cause error, need special treatment. */ - result = i * kWordSize + (index - 1); - wordRes.insert(result); - break; - } - if (firstTime) { - offset = index - 1; - baseWord = i * kWordSize; - firstTime = false; - } else { - offset = index; - baseWord = 0; - } - result += baseWord + offset; - wordRes.insert(result); - word = word >> static_cast(index); - } - } - return wordRes; - } - - void ClearDataInfo() { - info.clear(); - info.shrink_to_fit(); - } - - private: - /* long type has 8 bytes, 64 bits */ - static constexpr int32 kWordSize = 64; - std::vector info; -}; -} /* namespace maplebe */ -#endif /* MAPLEBE_INCLUDE_CG_INSN_H */ +/* + * 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. + */ +#ifndef MAPLEBE_INCLUDE_CG_DATAINFO_H +#define MAPLEBE_INCLUDE_CG_DATAINFO_H +#include + +namespace maplebe { +class DataInfo { + public: + explicit DataInfo(uint32 bitNum) : info(bitNum / kWordSize + 1, 0ULL) {} + + ~DataInfo() = default; + + void SetBit(uint32 bitNO) { + ASSERT(bitNO < info.size() * kWordSize, "Out of Range"); + info[bitNO / kWordSize] |= (1ULL << (bitNO % kWordSize)); + } + + void ResetBit(uint32 bitNO) { + info[bitNO / kWordSize] &= (~(1ULL << (bitNO % kWordSize))); + } + + bool TestBit(uint32 bitNO) const { + return (info[bitNO / kWordSize] & (1ULL << (bitNO % kWordSize))) != 0ULL; + } + + const uint64 &GetElem(uint32 index) const { + ASSERT(index < info.size(), "out of range"); + return info[index]; + } + + void SetElem(uint32 index, uint64 val) { + ASSERT(index < info.size(), "out of range"); + info[index] = val; + } + + bool NoneBit() const { + for (auto &data : info) { + if (data != 0ULL) { + return false; + } + } + return true; + } + + size_t Size() const { + return info.size() * kWordSize; + } + + const std::vector &GetInfo() const { + return info; + } + + bool IsEqual(const DataInfo &secondInfo) const { + auto infoSize = static_cast(info.size()); + ASSERT(infoSize == secondInfo.GetInfo().size(), "two dataInfo's size different"); + for (int32 i = 0; i != infoSize; i++) { + if (info[i] != secondInfo.GetElem(i)) { + return false; + } + } + return true; + } + + void AndBits(const DataInfo &secondInfo) { + auto infoSize = static_cast(info.size()); + ASSERT(infoSize == secondInfo.GetInfo().size(), "two dataInfo's size different"); + for (int32 i = 0; i != infoSize; i++) { + info[i] &= secondInfo.GetElem(i); + } + } + + void OrBits(const DataInfo &secondInfo) { + auto infoSize = static_cast(info.size()); + ASSERT(infoSize == secondInfo.GetInfo().size(), "two dataInfo's size different"); + for (int32 i = 0; i != infoSize; i++) { + info[i] |= secondInfo.GetElem(i); + } + } + + void OrDesignateBits(const DataInfo &secondInfo, uint32 infoIndex) { + ASSERT(infoIndex < secondInfo.GetInfo().size(), "out of secondInfo's range"); + ASSERT(infoIndex < info.size(), "out of secondInfo's range"); + info[infoIndex] |= secondInfo.GetElem(infoIndex); + } + + void EorBits(const DataInfo &secondInfo) { + auto infoSize = static_cast(info.size()); + ASSERT(infoSize == secondInfo.GetInfo().size(), "two dataInfo's size different"); + for (int32 i = 0; i != infoSize; i++) { + info[i] ^= secondInfo.GetElem(i); + } + } + + /* if bit in secondElem is 1, bit in current DataInfo is set 0 */ + void Difference(const DataInfo &secondInfo) { + auto infoSize = static_cast(info.size()); + ASSERT(infoSize == secondInfo.GetInfo().size(), "two dataInfo's size different"); + for (int32 i = 0; i != infoSize; i++) { + info[i] &= (~(secondInfo.GetElem(i))); + } + } + + void ResetAllBit() { + for (auto &data : info) { + data = 0ULL; + } + } + + void EnlargeCapacityToAdaptSize(uint32 bitNO) { + /* add one more size for each enlarge action */ + auto sizeToEnlarge = static_cast((bitNO / kWordSize + 1) - info.size()); + for (int32 i = 0; i < sizeToEnlarge; i++) { + info.push_back(0ULL); + } + } + + void GetNonZeroElemsIndex(std::set &index) { + auto infoSize = static_cast(info.size()); + for (int32 i = 0; i < infoSize; i++) { + if (info[i] != 0ULL) { + index.insert(i); + } + } + } + + int32 GetInfoIndex(const uint32 bitNO) const { + return bitNO / kWordSize; + } + + std::set GetBitsOfInfo() const { + std::set wordRes; + wordRes.clear(); + for (size_t i = 0; i != info.size(); ++i) { + uint32 result = 0; + uint64 word = info[i]; + uint32 offset = 0; + uint32 baseWord = 0; + bool firstTime = true; + while (word) { + int32 index = __builtin_ffsll(word); + if (index == 0) { + continue; + } + if (index == k64BitSize) { + /* when the highest bit is 1, the shift operation will cause error, need special treatment. */ + result = i * kWordSize + (index - 1); + wordRes.insert(result); + break; + } + if (firstTime) { + offset = index - 1; + baseWord = i * kWordSize; + firstTime = false; + } else { + offset = index; + baseWord = 0; + } + result += baseWord + offset; + wordRes.insert(result); + word = word >> static_cast(index); + } + } + return wordRes; + } + + void ClearDataInfo() { + info.clear(); + info.shrink_to_fit(); + } + + private: + /* long type has 8 bytes, 64 bits */ + static constexpr int32 kWordSize = 64; + std::vector info; +}; +} /* namespace maplebe */ +#endif /* MAPLEBE_INCLUDE_CG_INSN_H */ diff --git a/src/maple_be/include/cg/emit.h b/src/maple_be/include/cg/emit.h index 6c94fd4b02f8e37eabecaa770c1714bd2c3de245..dc71c415496f9cd7793ab745642c3d5df6bd04a7 100644 --- a/src/maple_be/include/cg/emit.h +++ b/src/maple_be/include/cg/emit.h @@ -31,7 +31,7 @@ #include "mir_const.h" #include "mempool_allocator.h" #include "muid_replacement.h" -#include "name_mangler.h" +#include "namemangler.h" namespace maplebe { constexpr int32 kSizeOfDecoupleStaticStruct = 4; diff --git a/src/maple_be/src/be/lower.cpp b/src/maple_be/src/be/lower.cpp index 078c344d5bf9b2d1710ad0224b5ec043c6fed508..e9b20fe29a5df979f1325d9514b5ff0a09677415 100644 --- a/src/maple_be/src/be/lower.cpp +++ b/src/maple_be/src/be/lower.cpp @@ -1351,10 +1351,10 @@ std::vector> CGLowerer::builtinFu std::unordered_map CGLowerer::intrinFuncIDs; /* get well known framework class 1st..6th element as pair first element */ -static std::vector> wellKnownFrameWorksClass{ +static std::vector> wellKnownFrameWorksClass{ }; -static uint64 GetWellKnownFrameWorksClassFlag(const std::string &className) { +static uint32 GetWellKnownFrameWorksClassFlag(const std::string &className) { for (auto it = wellKnownFrameWorksClass.begin(); it != wellKnownFrameWorksClass.end(); ++it) { if (className == (*it).first) { return (*it).second; @@ -2535,11 +2535,21 @@ void CGLowerer::LowerGCMalloc(const BaseNode &node, const GCMallocNode &gcmalloc blkNode.AppendStatementsFromBlock(*LowerCallAssignedStmt(*callAssign)); } -void CGLowerer::LowerJarrayMalloc(const StmtNode &stmt, const JarrayMallocNode &node, BlockNode &blkNode, bool perm) { - MIRFunction *func = mirBuilder->GetOrCreateFunction((perm ? "MCC_NewPermanentArray" : "MCC_NewObj_flexible_cname"), - (TyIdx)(LOWERED_PTR_TYPE)); - MapleVector args(mirModule.GetMPAllocator().Adapter()); +std::string CGLowerer::GetNewArrayFuncName(const uint32 elemSize, const bool perm) const { + if (elemSize == 1) { + return perm ? "MCC_NewPermArray8" : "MCC_NewArray8"; + } + if (elemSize == 2) { + return perm ? "MCC_NewPermArray16" : "MCC_NewArray16"; + } + if (elemSize == 4) { + return perm ? "MCC_NewPermArray32" : "MCC_NewArray32"; + } + CHECK_FATAL((elemSize == 8), "Invalid elemSize."); + return perm ? "MCC_NewPermArray64" : "MCC_NewArray64"; +} +void CGLowerer::LowerJarrayMalloc(const StmtNode &stmt, const JarrayMallocNode &node, BlockNode &blkNode, bool perm) { /* Extract jarray type */ TyIdx tyIdx = node.GetTyIdx(); MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); @@ -2550,14 +2560,11 @@ void CGLowerer::LowerJarrayMalloc(const StmtNode &stmt, const JarrayMallocNode & /* Inspect element type */ MIRType *elemType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(jaryType->GetElemTyIdx()); PrimType elemPrimType = elemType->GetPrimType(); - uint64 elemSize = GetPrimTypeSize(elemPrimType); + uint32 elemSize = GetPrimTypeSize(elemPrimType); if (elemType->GetKind() != kTypeScalar) { /* element is reference */ elemSize = AArch64RTSupport::kRefFieldSize; } - args.push_back(mirBuilder->CreateIntConst(elemSize, PTY_u64)); /* elem_size */ - args.push_back(node.Opnd(0)); /* n_elems */ - std::string klassName = jaryType->GetJavaName(); std::string arrayClassInfoName; bool isPredefinedArrayClass = false; @@ -2568,7 +2575,13 @@ void CGLowerer::LowerJarrayMalloc(const StmtNode &stmt, const JarrayMallocNode & arrayClassInfoName = CLASSINFO_PREFIX_STR + klassName; isPredefinedArrayClass = true; } + + std::string funcName; + MapleVector args(mirModule.GetMPAllocator().Adapter()); + auto *curFunc = mirModule.CurFunction(); if (isPredefinedArrayClass) { + funcName = GetNewArrayFuncName(elemSize, perm); + args.push_back(node.Opnd(0)); /* n_elems */ GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(arrayClassInfoName); MIRSymbol *arrayClassSym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx( GlobalTables::GetStrTable().GetStrIdxFromName(arrayClassInfoName)); @@ -2587,21 +2600,21 @@ void CGLowerer::LowerJarrayMalloc(const StmtNode &stmt, const JarrayMallocNode & } args.push_back(mirBuilder->CreateExprAddrof(0, *arrayClassSym)); } else { + funcName = perm ? "MCC_NewPermanentArray" : "MCC_NewObj_flexible_cname"; + args.push_back(mirBuilder->CreateIntConst(elemSize, PTY_u32)); /* elem_size */ + args.push_back(node.Opnd(0)); /* n_elems */ std::string klassJavaDescriptor; NameMangler::DecodeMapleNameToJavaDescriptor(klassName, klassJavaDescriptor); UStrIdx classNameStrIdx = GlobalTables::GetUStrTable().GetOrCreateStrIdxFromName(klassJavaDescriptor); ConststrNode *classNameExpr = mirModule.GetMemPool()->New(classNameStrIdx); classNameExpr->SetPrimType(PTY_ptr); args.push_back(classNameExpr); /* class_name */ + args.push_back(GetBaseNodeFromCurFunc(*curFunc, true)); + /* set class flag --> wellKnownClassFlag maybe 0 */ + uint32 wellKnownClassFlag = GetWellKnownFrameWorksClassFlag(jaryType->GetJavaName()); + args.push_back(mirBuilder->CreateIntConst(static_cast(wellKnownClassFlag), PTY_u32)); } - - auto *curFunc = mirModule.CurFunction(); - args.push_back(GetBaseNodeFromCurFunc(*curFunc, true)); - /* set class flag which is 11110000 */ - const uint32 kClassObjectFlag = 0xF0; - uint64 wellKnownClassFlag = GetWellKnownFrameWorksClassFlag(jaryType->GetJavaName()); - uint64 classFlag = isPredefinedArrayClass ? (wellKnownClassFlag | kClassObjectFlag) : wellKnownClassFlag; - args.push_back(mirBuilder->CreateIntConst(classFlag, PTY_u64)); + MIRFunction *func = mirBuilder->GetOrCreateFunction(funcName, (TyIdx)(LOWERED_PTR_TYPE)); CallNode *callAssign = nullptr; if (stmt.GetOpCode() == OP_dassign) { auto &dsNode = static_cast(stmt); diff --git a/src/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp b/src/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp index 2f8f88bf0099c97aed35eced0c4242d9b516eba3..57619fac5c0e754ce9d80964418cc09ff404b124 100644 --- a/src/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -693,6 +693,22 @@ AArch64MemOperand &AArch64CGFunc::CreateReplacementMemOperand(uint32 bitLen, return static_cast(CreateMemOpnd(baseReg, offset, bitLen)); } +bool AArch64CGFunc::CheckIfSplitOffsetWithAdd(const AArch64MemOperand &memOpnd, uint32 bitLen) { + if (memOpnd.GetAddrMode() != AArch64MemOperand::kAddrModeBOi || !memOpnd.IsIntactIndexed()) { + return false; + } + AArch64OfstOperand *ofstOpnd = memOpnd.GetOffsetImmediate(); + int32 opndVal = ofstOpnd->GetOffsetValue(); + int32 maxPimm = memOpnd.GetMaxPIMM(bitLen); + int32 q0 = opndVal / maxPimm; + int32 addend = q0 * maxPimm; + int32 r0 = opndVal - addend; + int32 alignment = memOpnd.GetImmediateOffsetAlignment(bitLen); + int32 r1 = static_cast(r0) & ((1u << static_cast(alignment)) - 1); + addend = addend + r1; + return (addend > 0); +} + AArch64MemOperand &AArch64CGFunc::SplitOffsetWithAddInstruction(const AArch64MemOperand &memOpnd, uint32 bitLen, AArch64reg baseRegNum, uint32 isDest, Insn *insn) { ASSERT((memOpnd.GetAddrMode() == AArch64MemOperand::kAddrModeBOi), "expect kAddrModeBOi memOpnd"); @@ -5568,11 +5584,14 @@ MemOperand *AArch64CGFunc::AdjustMemOperandIfOffsetOutOfRange( if (vrNum >= vRegTable.size()) { CHECK_FATAL(false, "index out of range in AArch64CGFunc::AdjustMemOperandIfOffsetOutOfRange"); } - int32 dataSize = vRegTable[vrNum].GetSize() * kBitsPerByte; - if (IsImmediateOffsetOutOfRange(*static_cast(memOpnd), dataSize)) { - isOutOfRange = 1; + uint32 dataSize = vRegTable[vrNum].GetSize() * kBitsPerByte; + auto *a64MemOpnd = static_cast(memOpnd); + if (IsImmediateOffsetOutOfRange(*a64MemOpnd, dataSize)) { + if (CheckIfSplitOffsetWithAdd(*a64MemOpnd, dataSize)) { + isOutOfRange = 1; + } memOpnd = - &SplitOffsetWithAddInstruction(*static_cast(memOpnd), dataSize, regNum, isDest, &insn); + &SplitOffsetWithAddInstruction(*a64MemOpnd, dataSize, regNum, isDest, &insn); } else { isOutOfRange = 0; } @@ -5908,6 +5927,34 @@ bool AArch64CGFunc::IsDuplicateAsmList(const MIRSymbol &sym) const { return false; } +void AArch64CGFunc::SelectMPLProfCounterInc(IntrinsiccallNode &intrnNode) { + ASSERT(intrnNode.NumOpnds() == 1, "must be 1 operand"); + BaseNode *arg1 = intrnNode.Opnd(0); + ASSERT(arg1 != nullptr, "nullptr check"); + regno_t vRegNO1 = NewVReg(GetRegTyFromPrimTy(PTY_a64), GetPrimTypeSize(PTY_a64)); + RegOperand &vReg1 = CreateVirtualRegisterOperand(vRegNO1); + vReg1.SetRegNotBBLocal(); + static MIRSymbol *bbProfileTab = nullptr; + if (!bbProfileTab) { + std::string bbProfileName = NameMangler::kBBProfileTabPrefixStr + GetMirModule().GetFileNameAsPostfix(); + bbProfileTab = GetMirModule().GetMIRBuilder()->GetGlobalDecl(bbProfileName); + CHECK_FATAL(bbProfileTab != nullptr, "expect bb profile tab"); + } + ConstvalNode *constvalNode = static_cast(arg1); + MIRConst *mirConst = constvalNode->GetConstVal(); + ASSERT(mirConst != nullptr, "nullptr check"); + CHECK_FATAL(mirConst->GetKind() == kConstInt, "expect MIRIntConst type"); + MIRIntConst *mirIntConst = safe_cast(mirConst); + uint32 idx = GetPrimTypeSize(PTY_u32) * mirIntConst->GetValue(); + if (!GetCG()->IsQuiet()) { + maple::logInfo.MapleLogger(kLlErr) << "Id index " << idx << std::endl; + } + StImmOperand &stOpnd = CreateStImmOperand(*bbProfileTab, idx, 0); + Insn &newInsn = GetCG()->BuildInstruction(MOP_counter, vReg1, stOpnd); + newInsn.SetDoNotRemove(true); + GetCurBB()->AppendInsn(newInsn); +} + void AArch64CGFunc::SelectMPLClinitCheck(IntrinsiccallNode &intrnNode) { ASSERT(intrnNode.NumOpnds() == 1, "must be 1 operand"); BaseNode *arg = intrnNode.Opnd(0); @@ -5982,6 +6029,10 @@ void AArch64CGFunc::SelectIntrinCall(IntrinsiccallNode &intrinsiccallNode) { SelectMPLClinitCheck(intrinsiccallNode); return; } + if (intrinsic == INTRN_MPL_PROF_COUNTER_INC) { /* special case */ + SelectMPLProfCounterInc(intrinsiccallNode); + return; + } if ((intrinsic == INTRN_MPL_CLEANUP_LOCALREFVARS) || (intrinsic == INTRN_MPL_CLEANUP_LOCALREFVARS_SKIP) || (intrinsic == INTRN_MPL_CLEANUP_NORETESCOBJS)) { return; diff --git a/src/maple_be/src/cg/aarch64/aarch64_color_ra.cpp b/src/maple_be/src/cg/aarch64/aarch64_color_ra.cpp index a6d236376b16399e947061c0153db9aad3f57bef..f819bf7484707d949893ccda4accdcc2546485df 100644 --- a/src/maple_be/src/cg/aarch64/aarch64_color_ra.cpp +++ b/src/maple_be/src/cg/aarch64/aarch64_color_ra.cpp @@ -1882,9 +1882,9 @@ void GraphColorRegAllocator::SplitLr(LiveRange &lr) { } #ifdef REUSE_SPILLMEM /* Copy the original conflict vector for spill reuse optimization */ - lr->SetOldConflict(cgFunc->GetMemoryPool()->NewArray(regBuckets)); + lr.SetOldConflict(cgFunc->GetMemoryPool()->NewArray(regBuckets)); for (uint32 i = 0; i < regBuckets; ++i) { - lr.GetOldConflict()[i] = lr.GetBBConflict()[i]; + lr.SetBBConflictElem(i, lr.GetBBConflictElem(i)); } #endif /* REUSE_SPILLMEM */ @@ -2539,7 +2539,21 @@ MemOperand *GraphColorRegAllocator::GetSpillOrReuseMem(LiveRange &lr, uint32 reg lr.SetSpillSize((regSize <= k32) ? k32 : k64); } else { #endif /* REUSE_SPILLMEM */ - memOpnd = GetSpillMem(lr.GetRegNO(), isDef, insn, static_cast(lr.GetSpillReg()), isOutOfRange); + regno_t baseRegNO = kRinvalid; + if (isDef) { + MapleSet &spillRegSet = (lr.GetRegType() == kRegTyInt) ? intSpillRegSet : fpSpillRegSet; + regno_t basis = (lr.GetRegType() == kRegTyInt) ? R0 : V0; + for (auto reg : spillRegSet) { + if ((reg + basis) != lr.GetSpillReg()) { + baseRegNO = (reg + basis); + break; + } + } + } else { + baseRegNO = lr.GetSpillReg(); + } + ASSERT(baseRegNO != kRinvalid, "invalid base register number"); + memOpnd = GetSpillMem(lr.GetRegNO(), isDef, insn, static_cast(baseRegNO), isOutOfRange); #ifdef REUSE_SPILLMEM if (isOutOfRange == 0) { lr.SetSpillMem(*memOpnd); @@ -2690,7 +2704,6 @@ regno_t GraphColorRegAllocator::PickRegForSpill(uint64 &usedRegMask, RegType reg ++regNumIt; } spillReg = *regNumIt + base; - ASSERT((usedRegMask & (1UL << (spillReg - pregInterval))) == 0, "spillReg should not be used"); return spillReg; } else { /* Temporary find a unused reg to spill */ diff --git a/src/maple_be/src/cg/aarch64/aarch64_insn.cpp b/src/maple_be/src/cg/aarch64/aarch64_insn.cpp index 28eb761d50587c627698cf19b4acc48f184ea82a..7c4bae0fa247cf6d0564fe80af5acc08fb59d04e 100644 --- a/src/maple_be/src/cg/aarch64/aarch64_insn.cpp +++ b/src/maple_be/src/cg/aarch64/aarch64_insn.cpp @@ -550,6 +550,55 @@ void AArch64Insn::EmitGetAndSetInt(Emitter &emitter) const { emitter.Emit("\n"); } +void AArch64Insn::EmitCounter(const CG &cg, Emitter &emitter) const { + /* + * adrp x1, __profile_bb_table$$GetBoolean_dex+4 + * ldr w17, [x1, #:lo12:__profile_bb_table$$GetBoolean_dex+4] + * add w17, w17, #1 + * str w17, [x1, #:lo12:__profile_bb_table$$GetBoolean_dex+4] + */ + const AArch64MD *md = &AArch64CG::kMd[MOP_counter]; + + Operand *opnd0 = opnds[kInsnFirstOpnd]; + Operand *opnd1 = opnds[kInsnSecondOpnd]; + OpndProp *prop0 = md->operand[kInsnFirstOpnd]; + StImmOperand *stImmOpnd = static_cast(opnd1); + CHECK_FATAL(stImmOpnd != nullptr, "stImmOpnd is null in AArch64Insn::EmitCounter"); + /* emit nop for breakpoint */ + if (cg.GetCGOptions().WithDwarf()) { + emitter.Emit("\t").Emit("nop").Emit("\n"); + } + + /* emit adrp */ + emitter.Emit("\t").Emit("adrp").Emit("\t"); + opnd0->Emit(emitter, prop0); + emitter.Emit(","); + emitter.Emit(stImmOpnd->GetName()); + emitter.Emit("+").Emit(stImmOpnd->GetOffset()); + emitter.Emit("\n"); + /* emit ldr */ + emitter.Emit("\t").Emit("ldr").Emit("\tw17, ["); + opnd0->Emit(emitter, prop0); + emitter.Emit(","); + emitter.Emit("#"); + emitter.Emit(":lo12:").Emit(stImmOpnd->GetName()); + emitter.Emit("+").Emit(stImmOpnd->GetOffset()); + emitter.Emit("]"); + emitter.Emit("\n"); + /* emit add */ + emitter.Emit("\t").Emit("add").Emit("\tw17, w17, #1"); + emitter.Emit("\n"); + /* emit str */ + emitter.Emit("\t").Emit("str").Emit("\tw17, ["); + opnd0->Emit(emitter, prop0); + emitter.Emit(","); + emitter.Emit("#"); + emitter.Emit(":lo12:").Emit(stImmOpnd->GetName()); + emitter.Emit("+").Emit(stImmOpnd->GetOffset()); + emitter.Emit("]"); + emitter.Emit("\n"); +} + void AArch64Insn::EmitClinit(const CG &cg, Emitter &emitter) const { /* * adrp x3, __muid_data_undef_tab$$GetBoolean_dex+144 @@ -838,6 +887,10 @@ void AArch64Insn::Emit(const CG &cg, Emitter &emitter) const { } return; } + case MOP_counter: { + EmitCounter(cg, emitter); + return; + } case MOP_clinit_tail: { EmitClinitTail(emitter); emitter.IncreaseJavaInsnCount(kClinitTailInsnCount); diff --git a/src/maple_be/src/cg/aarch64/aarch64_md.def b/src/maple_be/src/cg/aarch64/aarch64_md.def index 3dfc816b77421592b0dfd5fee6cdfa3b1174ea7e..fe89f03404e628524d7edac977309436fc850c1d 100644 --- a/src/maple_be/src/cg/aarch64/aarch64_md.def +++ b/src/maple_be/src/cg/aarch64/aarch64_md.def @@ -633,6 +633,16 @@ */ {MOP_clinit, {mopdReg64ID,mopdLiteral},ISATOMIC|CANTHROW,kLtClinit,"intrinsic_clinit","0,1",4}, +/* + * MOP_counter + * will be emit to five instructions in a row: + * adrp x1, :got:__profile_table + idx + * ldr w17, [x1,#:got_lo12:__profile_table] + * add w17, w17, #1 + * str w17,[x1,,#:got_lo12:__profile_table] + */ +{MOP_counter, {mopdReg64ID,mopdLiteral},ISATOMIC|CANTHROW,kLtClinit,"intrinsic_counter","0,1", 4}, + /* * will be emit to two instrunctions in a row: * ldr wd, [xs] // xd and xs should be differenct register diff --git a/src/maple_be/src/cg/aarch64/aarch64_memlayout.cpp b/src/maple_be/src/cg/aarch64/aarch64_memlayout.cpp index 98d9ed5d1f25c9fa41261f56645b192bfd3e5d94..c9fb92303a01d1848405e219e0aaade6dfc61863 100644 --- a/src/maple_be/src/cg/aarch64/aarch64_memlayout.cpp +++ b/src/maple_be/src/cg/aarch64/aarch64_memlayout.cpp @@ -96,13 +96,14 @@ uint32 AArch64MemLayout::ComputeStackSpaceRequirementForCall(StmtNode &stmt, boo return sizeOfArgsToStkPass; } -void AArch64MemLayout::setSegmentSize(AArch64SymbolAlloc &symbolAlloc, MemSegment &segment, uint32 typeIdx) { +void AArch64MemLayout::SetSegmentSize(AArch64SymbolAlloc &symbolAlloc, MemSegment &segment, uint32 typeIdx) { segment.SetSize(static_cast(RoundUp(static_cast(segment.GetSize()), be.GetTypeAlign(typeIdx)))); symbolAlloc.SetOffset(segment.GetSize()); segment.SetSize(segment.GetSize() + static_cast(be.GetTypeSize(typeIdx))); segment.SetSize(static_cast(RoundUp(static_cast(segment.GetSize()), kSizeOfPtr))); } -void AArch64MemLayout::layoutFormalParams() { + +void AArch64MemLayout::LayoutFormalParams() { ParmLocator parmLocator(be); PLocInfo ploc; for (size_t i = 0; i < mirFunction->GetFormalCount(); ++i) { @@ -118,7 +119,7 @@ void AArch64MemLayout::layoutFormalParams() { symLoc->SetRegisters(ploc.reg0, ploc.reg1); if (mirFunction->GetNthParamAttr(i).GetAttr(ATTR_localrefvar)) { symLoc->SetMemSegment(segRefLocals); - setSegmentSize(*symLoc, segRefLocals, ptyIdx); + SetSegmentSize(*symLoc, segRefLocals, ptyIdx); } else if (!sym->IsPreg()) { symLoc->SetMemSegment(GetSegArgsRegPassed()); /* the type's alignment requirement may be smaller than a registser's byte size */ @@ -138,14 +139,14 @@ void AArch64MemLayout::layoutFormalParams() { SetLocalRegLocInfo(sym->GetStIdx(), *symLoc); AArch64SymbolAlloc *symLoc1 = memAllocator->GetMemPool()->New(); symLoc1->SetMemSegment(segRefLocals); - setSegmentSize(*symLoc1, segRefLocals, ptyIdx); + SetSegmentSize(*symLoc1, segRefLocals, ptyIdx); SetSymAllocInfo(stIndex, *symLoc1); } } } } -void AArch64MemLayout::layoutLocalVariales(std::vector &tempVar, std::vector &returnDelays) { +void AArch64MemLayout::LayoutLocalVariales(std::vector &tempVar, std::vector &returnDelays) { uint32 symTabSize = mirFunction->GetSymTab()->GetSymbolTableSize(); for (uint32 i = 0; i < symTabSize; ++i) { MIRSymbol *sym = mirFunction->GetSymTab()->GetSymbolFromStIdx(i); @@ -182,7 +183,7 @@ void AArch64MemLayout::layoutLocalVariales(std::vector &tempVar, std } } -void AArch64MemLayout::layoutEAVariales(std::vector &tempVar) { +void AArch64MemLayout::LayoutEAVariales(std::vector &tempVar) { for (auto sym : tempVar) { uint32 stIndex = sym->GetStIndex(); TyIdx tyIdx = sym->GetTyIdx(); @@ -196,7 +197,7 @@ void AArch64MemLayout::layoutEAVariales(std::vector &tempVar) { } } -void AArch64MemLayout::layoutReturnRef(std::vector &returnDelays) { +void AArch64MemLayout::LayoutReturnRef(std::vector &returnDelays) { for (auto sym : returnDelays) { uint32 stIndex = sym->GetStIndex(); TyIdx tyIdx = sym->GetTyIdx(); @@ -222,7 +223,7 @@ void AArch64MemLayout::layoutReturnRef(std::vector &returnDelays) { segLocals.SetSize(RoundUp(segLocals.GetSize(), kSizeOfPtr)); } -void AArch64MemLayout::layoutActualParams() { +void AArch64MemLayout::LayoutActualParams() { for (size_t i = 0; i < mirFunction->GetFormalCount(); ++i) { MIRSymbol *sym = mirFunction->GetFormal(i); if (sym->IsPreg()) { @@ -256,7 +257,7 @@ void AArch64MemLayout::layoutActualParams() { } void AArch64MemLayout::LayoutStackFrame() { - layoutFormalParams(); + LayoutFormalParams(); /* * We do need this as LDR/STR with immediate * requires imm be aligned at a 8/4-byte boundary, @@ -268,17 +269,17 @@ void AArch64MemLayout::LayoutStackFrame() { /* allocate the local variables in the stack */ std::vector EATempVar; std::vector retDelays; - layoutLocalVariales(EATempVar, retDelays); - layoutEAVariales(EATempVar); + LayoutLocalVariales(EATempVar, retDelays); + LayoutEAVariales(EATempVar); /* handle ret_ref sym now */ - layoutReturnRef(retDelays); + LayoutReturnRef(retDelays); /* * for the actual arguments that cannot be pass through registers * need to allocate space for caller-save registers */ - layoutActualParams(); + LayoutActualParams(); fixStackSize = RealStackFrameSize(); } @@ -358,4 +359,4 @@ int32 AArch64MemLayout::GetRefLocBaseLoc() const { } return beforeSize + kSizeOfFplr; } -} /* namespace maplebe */ \ No newline at end of file +} /* namespace maplebe */ diff --git a/src/maple_be/src/cg/aarch64/aarch64_operand.cpp b/src/maple_be/src/cg/aarch64/aarch64_operand.cpp index 3e1086d579d33b036698de3f7c1feadf195bbb3e..6b7bbfe255d0ba7192d7b50c407fd5bbb27eda9f 100644 --- a/src/maple_be/src/cg/aarch64/aarch64_operand.cpp +++ b/src/maple_be/src/cg/aarch64/aarch64_operand.cpp @@ -277,8 +277,10 @@ void AArch64MemOperand::Emit(Emitter &emitter, const OpndProp *opndProp) const { emitter.Emit(","); /* extend, #0, of #3/#2 */ emitter.Emit(GetExtendAsString()); - emitter.Emit(" #"); - emitter.Emit(ShiftAmount()); + if (GetExtendAsString() == "LSL" || ShiftAmount() != 0) { + emitter.Emit(" #"); + emitter.Emit(ShiftAmount()); + } } emitter.Emit("]"); } else if (addressMode == AArch64MemOperand::kAddrModeLiteral) { diff --git a/src/maple_be/src/cg/cfi.cpp b/src/maple_be/src/cg/cfi.cpp index 143431b036a4fc3d21e2fe99f541e0905221edc3..04526b6abcaf8178f2a406cd000404bd79190c8e 100644 --- a/src/maple_be/src/cg/cfi.cpp +++ b/src/maple_be/src/cg/cfi.cpp @@ -32,8 +32,11 @@ struct CfiDescr { static CfiDescr cfiDescrTable[kOpCfiLast + 1] = { #define CFI_DEFINE(k, sub, n, o0, o1, o2) \ { ".cfi_" #k, n, { Operand::kOpd##o0, Operand::kOpd##o1, Operand::kOpd##o2 } }, +#define ARM_DIRECTIVES_DEFINE(k, sub, n, o0, o1, o2) \ + { "." #k, n, { Operand::kOpd##o0, Operand::kOpd##o1, Operand::kOpd##o2 } }, #include "cfi.def" #undef CFI_DEFINE +#undef ARM_DIRECTIVES_DEFINE { ".cfi_undef", 0, { Operand::kOpdUndef, Operand::kOpdUndef, Operand::kOpdUndef } } }; diff --git a/src/maple_be/src/cg/cg_cfg.cpp b/src/maple_be/src/cg/cg_cfg.cpp index 610c91c086938f2187fa12503958b8e2398f59d9..01f7ed515ed595ae5984fd4a8471364240fedc22 100644 --- a/src/maple_be/src/cg/cg_cfg.cpp +++ b/src/maple_be/src/cg/cg_cfg.cpp @@ -468,6 +468,9 @@ void CGCFG::UnreachCodeAnalysis() { unreachBB->ClearSuccs(); unreachBB->ClearEhSuccs(); + + /* Clear insns in GOT Map. */ + cgFunc->ClearUnreachableGotInfos(*unreachBB); } } diff --git a/src/maple_be/src/cg/emit.cpp b/src/maple_be/src/cg/emit.cpp index 75877aa9dd913efdf95c9981a496743d1c1eada6..0e7b5c994a36bdbf869c9724def20194e4272b36 100644 --- a/src/maple_be/src/cg/emit.cpp +++ b/src/maple_be/src/cg/emit.cpp @@ -174,6 +174,20 @@ void Emitter::EmitFileInfo(const std::string &fileName) { */ Emit("\t.arm\n"); Emit("\t.fpu vfpv4\n"); + Emit("\t.arch armv7-a\n"); + Emit("\t.eabi_attribute 15, 1\n"); + Emit("\t.eabi_attribute 16, 1\n"); + Emit("\t.eabi_attribute 17, 2\n"); + Emit("\t.eabi_attribute 28, 1\n"); + Emit("\t.eabi_attribute 20, 1\n"); + Emit("\t.eabi_attribute 21, 1\n"); + Emit("\t.eabi_attribute 23, 3\n"); + Emit("\t.eabi_attribute 24, 1\n"); + Emit("\t.eabi_attribute 25, 1\n"); + Emit("\t.eabi_attribute 26, 2\n"); + Emit("\t.eabi_attribute 30, 6\n"); + Emit("\t.eabi_attribute 34, 1\n"); + Emit("\t.eabi_attribute 18, 4\n"); #endif /* TARGARM32 */ } @@ -808,8 +822,9 @@ void Emitter::EmitAddrofSymbolConst(const MIRSymbol &mirSymbol, MIRConst &elemCo return; } #ifdef USE_32BIT_REF - if (mirSymbol.IsReflectionHashTabBucket() || (stName.find(ITAB_PREFIX_STR) == 0)) { - Emit("\t.long\t"); + if (mirSymbol.IsReflectionHashTabBucket() || (stName.find(ITAB_PREFIX_STR) == 0) || + (mirSymbol.IsReflectionClassInfo() && (idx == static_cast(ClassProperty::kInfoRo)))) { + Emit("\t.word\t"); } else { #if TARGAARCH64 Emit("\t.quad\t"); diff --git a/src/maple_be/src/cg/proepilog.cpp b/src/maple_be/src/cg/proepilog.cpp index 4ba393333dabd7767562a75ffabc8700461585ab..722979bc030fe776f9f2b22463c8d5453b90eeb2 100644 --- a/src/maple_be/src/cg/proepilog.cpp +++ b/src/maple_be/src/cg/proepilog.cpp @@ -32,7 +32,6 @@ Insn *GenProEpilog::InsertCFIDefCfaOffset(int32 &cfiOffset, Insn &insertAfter) { Insn &cfiInsn = currCG->BuildInstruction(cfi::OP_CFI_def_cfa_offset, cgFunc.CreateCfiImmOperand(cfiOffset, k64BitSize)); Insn *newIPoint = cgFunc.GetCurBB()->InsertInsnAfter(insertAfter, cfiInsn); - CHECK_FATAL(cgFunc.GetDbgCallFrameOffset() == 0, "InsertCFIDefCfaOffset() should be called only once?"); cgFunc.SetDbgCallFrameOffset(cfiOffset); return newIPoint; } diff --git a/src/maple_be/src/cg/script/genmop.py b/src/maple_be/src/cg/script/genmop.py index 74d97170e923c3b2b24c242521c37f07e302f94c..f7df82ef64ae86a13c53bba3ce4ead673f5a49f0 100644 --- a/src/maple_be/src/cg/script/genmop.py +++ b/src/maple_be/src/cg/script/genmop.py @@ -61,6 +61,8 @@ def process(mdfilename, newmdfilename): if(os.path.exists(newmdfilename) and (os.stat(mdfilename).st_mtime < os.stat(newmdfilename).st_mtime)): pass else: + if (os.path.exists(newmdfilename)): + os.remove(newmdfilename) with open( mdfilename, "r" ) as infile: lines = [] for l in infile: diff --git a/src/maple_driver/include/usages.h b/src/maple_driver/include/usages.h index fe2574f80ed13c0c64e24654c68a9ccf10ac2b82..a9354e1b404dcab3cb96168a680bfb09eecc4c35 100644 --- a/src/maple_driver/include/usages.h +++ b/src/maple_driver/include/usages.h @@ -116,6 +116,8 @@ enum OptionIndex : uint64 { kMpl2MplNativeOpt, kMpl2MplOptL2, kMpl2MplNoDot, + kGenIRProfile, + kTestCase, // ----------mplcg begin--------- kCGQuiet, kPie, diff --git a/src/maple_driver/src/maple_comb_compiler.cpp b/src/maple_driver/src/maple_comb_compiler.cpp index a3657bf2f56d25de2d6e253fa064f7dd71dc25b4..1c8b72022e1146f0e926b1fef0d648607e63cd6b 100644 --- a/src/maple_driver/src/maple_comb_compiler.cpp +++ b/src/maple_driver/src/maple_comb_compiler.cpp @@ -442,6 +442,12 @@ Options *MapleCombCompiler::MakeMpl2MplOptions(const MplOptions &options, MemPoo case kMpl2MplNoDot: mpl2mplOption->noDot = (opt.Type() == kEnable); break; + case kGenIRProfile: + mpl2mplOption->genIRProfile = (opt.Type() == kEnable); + break; + case kTestCase: + mpl2mplOption->testCase = (opt.Type() == kEnable); + break; default: WARN(kLncWarn, "input invalid key for mpl2mpl " + opt.OptionKey()); break; diff --git a/src/maple_driver/src/mpl_options.cpp b/src/maple_driver/src/mpl_options.cpp index 89d1043a9414d11f3f4d4d21274c9a6063c6fefb..03e20f631c97ad26615a2a7f2081b36c67cc9937 100644 --- a/src/maple_driver/src/mpl_options.cpp +++ b/src/maple_driver/src/mpl_options.cpp @@ -1088,6 +1088,32 @@ const mapleOption::Descriptor usages[] = { " --no-nodot \tEnable dot file generation from cfg\n", "mpl2mpl", { { nullptr, nullptr, nullptr, nullptr } } }, + { kGenIRProfile, + kEnable, + nullptr, + "ir-profile-gen", + nullptr, + false, + nullptr, + mapleOption::BuildType::kBuildTypeAll, + mapleOption::ArgCheckPolicy::kArgCheckPolicyBool, + " --ir-profile-gen \tGen IR level Profile\n" + " --no-ir-profile-gen \tDisable Gen IR level Profile\n", + "mpl2mpl", + { { nullptr, nullptr, nullptr, nullptr } } }, + { kTestCase, + kEnable, + nullptr, + "testcase", + nullptr, + false, + nullptr, + mapleOption::BuildType::kBuildTypeAll, + mapleOption::ArgCheckPolicy::kArgCheckPolicyBool, + " --testcase \tTest Case\n" + " --no-testcase \tDisable Test Case\n", + "mpl2mpl", + { { nullptr, nullptr, nullptr, nullptr } } }, // mplcg { kPie, kEnable, diff --git a/src/maple_ipa/include/clone.h b/src/maple_ipa/include/clone.h index 88d4dfe63c5593ed0697f9d1e20362ef8cfce6d5..055706702eb6c412c1f5ab6eb002480767808fc9 100644 --- a/src/maple_ipa/include/clone.h +++ b/src/maple_ipa/include/clone.h @@ -35,12 +35,12 @@ class ReplaceRetIgnored { bool ShouldReplaceWithVoidFunc(const CallMeStmt *stmt, const MIRFunction *calleeFunc) const; std::string GenerateNewBaseName(const MIRFunction *originalFunc); std::string GenerateNewFullName(const MIRFunction *originalFunc); - const std::set *GetTobeClonedFuncNames() const { + const MapleSet *GetTobeClonedFuncNames() const { return &toBeClonedFuncNames; } bool IsInCloneList(const std::string &funcName) const { - return toBeClonedFuncNames.find(funcName) != toBeClonedFuncNames.end(); + return toBeClonedFuncNames.find(MapleString(funcName, memPool)) != toBeClonedFuncNames.end(); } static bool IsClonedFunc(const std::string &funcName) { @@ -48,8 +48,9 @@ class ReplaceRetIgnored { } private: + MemPool *memPool; maple::MapleAllocator allocator; - std::set toBeClonedFuncNames; + MapleSet toBeClonedFuncNames; bool RealShouldReplaceWithVoidFunc(Opcode op, size_t nRetSize, const MIRFunction *calleeFunc) const; }; class Clone : public AnalysisResult { diff --git a/src/maple_ipa/src/clone.cpp b/src/maple_ipa/src/clone.cpp index c78c73a93d09e9abd74265ef215618c3db7037da..94b16d6770cbae6130521e1ea79f4018d75cf5b2 100644 --- a/src/maple_ipa/src/clone.cpp +++ b/src/maple_ipa/src/clone.cpp @@ -23,7 +23,8 @@ // This mainly contains the clone of funcbody(include labels, symbols, arguments, // etc.) and the update of the new func infomation. namespace maple { -ReplaceRetIgnored::ReplaceRetIgnored(MemPool *memPool) : allocator(memPool) { +ReplaceRetIgnored::ReplaceRetIgnored(MemPool *memPool) + : memPool(memPool), allocator(memPool), toBeClonedFuncNames(allocator.Adapter()) { } bool ReplaceRetIgnored::RealShouldReplaceWithVoidFunc(Opcode op, size_t nRetSize, @@ -226,11 +227,11 @@ void Clone::UpdateReturnVoidIfPossible(CallMeStmt *callMeStmt, const MIRFunction void Clone::DoClone() { std::set clonedNewFuncMap; - for (const std::string &funcName : *(replaceRetIgnored->GetTobeClonedFuncNames())) { - GStrIdx gStrIdx = GlobalTables::GetStrTable().GetStrIdxFromName(funcName); + for (const MapleString &funcName : *(replaceRetIgnored->GetTobeClonedFuncNames())) { + GStrIdx gStrIdx = GlobalTables::GetStrTable().GetStrIdxFromName(std::string(funcName.c_str())); MIRSymbol *symbol = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(gStrIdx); if (nullptr != symbol) { - GStrIdx gStrIdxOfFunc = GlobalTables::GetStrTable().GetStrIdxFromName(funcName); + GStrIdx gStrIdxOfFunc = GlobalTables::GetStrTable().GetStrIdxFromName(std::string(funcName.c_str())); MIRFunction *oriFunc = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(gStrIdxOfFunc)->GetFunction(); mirModule->SetCurFunction(oriFunc); clonedNewFuncMap.insert(CloneFunctionNoReturn(oriFunc)->GetName()); diff --git a/src/maple_ipa/src/interleaved_manager.cpp b/src/maple_ipa/src/interleaved_manager.cpp index e41d87f5ba9720e52c1fd52a0e9ddd5f18815455..eaa94bd1f96b64023d9a059df1f54bfa1b56ac9a 100644 --- a/src/maple_ipa/src/interleaved_manager.cpp +++ b/src/maple_ipa/src/interleaved_manager.cpp @@ -79,6 +79,7 @@ void InterleavedManager::Run() { // If rangeNum < MeOption::range[0], Move to the next function with rangeNum++ uint64 rangeNum = 0; for (auto *func : *compList) { + ASSERT_NOT_NULL(func); if (MeOption::useRange && (rangeNum < MeOption::range[0] || rangeNum > MeOption::range[1])) { ++rangeNum; continue; diff --git a/src/maple_ir/include/global_tables.h b/src/maple_ir/include/global_tables.h index 8f48e409ea021d5915b546cd56d97edf14453b00..8f3a61c6057f99a49568fdee72cc37918695748c 100644 --- a/src/maple_ir/include/global_tables.h +++ b/src/maple_ir/include/global_tables.h @@ -22,7 +22,7 @@ #include "types_def.h" #include "prim_types.h" #include "mir_module.h" -#include "name_mangler.h" +#include "namemangler.h" #include "mir_type.h" #include "mir_const.h" diff --git a/src/maple_ir/include/intrinsics.def b/src/maple_ir/include/intrinsics.def index fe33c4bfeb9af60bc3e3e16246d116d11919cc31..6bffa567154ce0cda0ee407ee8f51211929cf2ee 100644 --- a/src/maple_ir/include/intrinsics.def +++ b/src/maple_ir/include/intrinsics.def @@ -19,6 +19,8 @@ DEF_MIR_INTRINSIC(MPL_ATOMIC_EXCHANGE_PTR,\ "__mpl_atomic_exchange_ptr", kIntrnIsAtomic, kArgTyPtr, kArgTyPtr, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) DEF_MIR_INTRINSIC(MPL_CLINIT_CHECK,\ "__mpl_clinit_check", INTRNISJAVA | INTRNNOSIDEEFFECT | INTRNISSPECIAL, kArgTyVoid, kArgTyDynany, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) +DEF_MIR_INTRINSIC(MPL_PROF_COUNTER_INC,\ + "__mpl_prof_counter_inc", INTRNNOSIDEEFFECT | INTRNISSPECIAL, kArgTyVoid, kArgTyU32, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) DEF_MIR_INTRINSIC(MPL_CLEAR_STACK,\ "__mpl_clear_stack", kIntrnUndef, kArgTyVoid, kArgTyDynany, kArgTyDynany, kArgTyUndef, kArgTyUndef, kArgTyUndef, kArgTyUndef) DEF_MIR_INTRINSIC(MPL_GET_VTAB_FUNC,\ @@ -124,6 +126,10 @@ DEF_MIR_INTRINSIC(MPL_CLEANUP_NORETESCOBJS,\ // start of GC Intrinsics +// start of Profile Intrinsics +DEF_MIR_INTRINSIC(MCCSaveProf,\ + "MCC_SaveProfile", INTRNISRC | INTRNNOSIDEEFFECT, kArgTyVoid, kArgTyRef) + #include "intrinsic_java.def" #include "simplifyintrinsics.def" DEF_MIR_INTRINSIC(LAST,\ diff --git a/src/maple_ir/include/java_eh_lower.h b/src/maple_ir/include/java_eh_lower.h index 59596b0d2b57904598c952813afd0f82e37a8e0a..fa483a4c6464635a42ba363c767c2d27009b972f 100644 --- a/src/maple_ir/include/java_eh_lower.h +++ b/src/maple_ir/include/java_eh_lower.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2019] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. @@ -21,7 +21,7 @@ namespace maple { class JavaEHLowerer : public FuncOptimizeImpl { public: - JavaEHLowerer(MIRModule *mod, KlassHierarchy *kh, bool dump) : FuncOptimizeImpl(mod, kh, dump) {} + JavaEHLowerer(MIRModule &mod, KlassHierarchy *kh, bool dump) : FuncOptimizeImpl(mod, kh, dump) {} ~JavaEHLowerer() = default; FuncOptimizeImpl *Clone() override { diff --git a/src/maple_ir/include/metadata_layout.h b/src/maple_ir/include/metadata_layout.h index 016518f22b8af930cd4569d2e32760db0b040ae0..3049b737d7115832848050bcea15ba0095da297d 100644 --- a/src/maple_ir/include/metadata_layout.h +++ b/src/maple_ir/include/metadata_layout.h @@ -25,8 +25,11 @@ using MetaRef = uint32_t; // consistent with reffield_t in address.h #else using MetaRef = uintptr_t; // consistent iwth reffield_t in address.h #endif // USE_32BIT_REF + // DataRefOffset aims to represent a reference to data in maple file, which is already an offset. // DataRefOffset is meant to have pointer size and aligned to at least 4 bytes. +// All Xx32 data types defined in this file aim to use 32 bits to save 64-bit address, and thus are +// specific for 64-bit platforms. struct DataRefOffset32 { int32_t refOffset; template @@ -72,7 +75,7 @@ struct DataRefOffset { 3. "indirect.label_name - . + 3" for indirect reference this format aims to support lld which does not support expression "global_symbol - ." DataRef is self-decoded by also encoding the format and is defined for binary compatibility. - If no compatibility problem is involved, DataRefOffset64 is preferred. + If no compatibility problem is involved, DataRefOffset is preferred. */ enum DataRefFormat { kDataRefIsDirect = 0, // must be 0 @@ -140,8 +143,17 @@ struct GctibRef { // Unlike DataRef, the format of MByteRef is determined by its value. struct MByteRef { uintptr_t refVal; // initializer prefers this field to be a pointer + +#if defined(__arm__) || defined(USE_ARM32_MACRO) + // assume address range 0 ~ 256MB is unused in arm runtime + // OffsetMin ~ OffsetMax is the value range of encoded offset + static constexpr intptr_t FarthestOffset = 128 * 1024 * 1024; + static constexpr intptr_t PositiveOffsetBias = 128 * 1024 * 1024; + static constexpr intptr_t OffsetMin = PositiveOffsetBias + 0; + static constexpr intptr_t OffsetMax = PositiveOffsetBias + FarthestOffset; +#else enum { - kBiasBitPosition = sizeof(refVal) * 8 - 4, // the most significant 3 bits + kBiasBitPosition = sizeof(refVal) * 8 - 4, // the most significant 4 bits }; static constexpr uintptr_t FarthestOffset = 256 * 1024 * 1024; // according to kDsoLoadedAddessEnd = 0xF0000000 @@ -149,6 +161,7 @@ struct MByteRef { static constexpr uintptr_t PositiveOffsetBias = static_cast(6) << kBiasBitPosition; static constexpr uintptr_t PositiveOffsetMin = 0 + PositiveOffsetBias; static constexpr uintptr_t PositiveOffsetMax = FarthestOffset + PositiveOffsetBias; +#endif template inline T GetRef() const; @@ -272,17 +285,12 @@ struct ClassMetadata { DataRef vTable; // vTable of current class, used for interface call, will insert the content into classinfo GctibRef gctib; // for rc - union { - DataRef ro; - struct { - #ifdef USE_32BIT_REF - DataRef32 classinforo; - DataRef32 cacheFalseClass; - #else - DataRef classinforo; - #endif - }; - }; +#ifdef USE_32BIT_REF + DataRef32 classInfoRo; + DataRef32 cacheFalseClass; +#else + DataRef classInfoRo; +#endif union { uintptr_t initState; // a readable address for initState means initialized diff --git a/src/maple_ir/include/mir_function.h b/src/maple_ir/include/mir_function.h index 8369293ba90f06bac00f186e8b468d5e6383907a..2a5a60baa505530e6ab65582bb7e90914bc9b888 100644 --- a/src/maple_ir/include/mir_function.h +++ b/src/maple_ir/include/mir_function.h @@ -22,6 +22,7 @@ #include "intrinsics.h" #include "file_layout.h" #include "mir_nodes.h" +#include "profile.h" namespace maple { @@ -684,6 +685,7 @@ class MIRFunction { MeFunction *GetMeFunc() { return meFunc; } + void SetMeFunc(MeFunction *func) { meFunc = func; } @@ -776,6 +778,18 @@ class MIRFunction { } + void AddProfileDesc(uint64 hash, uint32 start, uint32 end) { + profileDesc = module->GetMemPool()->New(hash, start, end); + } + + const IRProfileDesc *GetProfInf() { + if (profileDesc == nullptr) { + // return profileDesc with default value + profileDesc = module->GetMemPool()->New(); + } + return profileDesc; + } + private: MIRModule *module; // the module that owns this function PUIdx puIdx = 0; // the PU index of this function @@ -849,6 +863,7 @@ class MIRFunction { // to hold unmangled class and function names MeFunction *meFunc = nullptr; EAConnectionGraph *eacg = nullptr; + IRProfileDesc *profileDesc = nullptr; GStrIdx baseClassStrIdx{0}; // the string table index of base class name GStrIdx baseFuncStrIdx{0}; // the string table index of base function name // the string table index of base function name mangled with type info diff --git a/src/maple_ir/include/option.h b/src/maple_ir/include/option.h index dcbfc99f53bd7324138a9c422164060253a1e8f9..dfc843657780e55672f09ae2478cc993bf656f51 100644 --- a/src/maple_ir/include/option.h +++ b/src/maple_ir/include/option.h @@ -89,6 +89,8 @@ class Options { static std::string proFileFuncData; static std::string proFileClassData; static bool profileStaticFields; + static bool genIRProfile; + static bool testCase; static bool checkArrayStore; private: MapleAllocator optionAlloc; diff --git a/src/maple_ir/src/bin_mpl_export.cpp b/src/maple_ir/src/bin_mpl_export.cpp index f3da6190089d16061abfa6f9cf67a175ce320c35..c91ac7032079b75d764000e9e0e43bc79fabe3a4 100644 --- a/src/maple_ir/src/bin_mpl_export.cpp +++ b/src/maple_ir/src/bin_mpl_export.cpp @@ -16,7 +16,7 @@ #include #include #include "mir_function.h" -#include "name_mangler.h" +#include "namemangler.h" #include "opcode_info.h" #include "mir_pragma.h" #include "bin_mplt.h" diff --git a/src/maple_ir/src/bin_mpl_import.cpp b/src/maple_ir/src/bin_mpl_import.cpp index feee24529cca4f4357fd6333acc118522c3ff8e5..683be89188789265db770aeda8949553b830dfc5 100644 --- a/src/maple_ir/src/bin_mpl_import.cpp +++ b/src/maple_ir/src/bin_mpl_import.cpp @@ -19,7 +19,7 @@ #include #include "bin_mpl_export.h" #include "mir_function.h" -#include "name_mangler.h" +#include "namemangler.h" #include "opcode_info.h" #include "mir_pragma.h" #include "mir_builder.h" diff --git a/src/maple_ir/src/driver.cpp b/src/maple_ir/src/driver.cpp index 20298bf4b2b4c3248b1ee585a162f5b04bebe807..4dcd1807be2d0154eacccb847fcc793d2c1072e5 100644 --- a/src/maple_ir/src/driver.cpp +++ b/src/maple_ir/src/driver.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2019] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. diff --git a/src/maple_ir/src/mir_nodes.cpp b/src/maple_ir/src/mir_nodes.cpp index 2a1b62b4950b1fda5e9902daec25f423cc046087..5024f2872ceaebe46514c5e2139813d06bcd3e88 100644 --- a/src/maple_ir/src/mir_nodes.cpp +++ b/src/maple_ir/src/mir_nodes.cpp @@ -19,7 +19,7 @@ #include "printing.h" #include "maple_string.h" #include "opcode_info.h" -#include "name_mangler.h" +#include "namemangler.h" #include "utils.h" namespace maple { diff --git a/src/maple_ir/src/mir_symbol.cpp b/src/maple_ir/src/mir_symbol.cpp index 8bd6eb9b68bc914649e206d038aa8c49c6b60105..0fd86d7f025791747afccb70b4486ec89c00ea97 100644 --- a/src/maple_ir/src/mir_symbol.cpp +++ b/src/maple_ir/src/mir_symbol.cpp @@ -21,7 +21,7 @@ #include "reflection_analysis.h" #include "printing.h" #include "native_stub_func.h" -#include "literal_str_name.h" +#include "literalstrname.h" #include "string_utils.h" namespace maple { diff --git a/src/maple_ir/src/mir_type.cpp b/src/maple_ir/src/mir_type.cpp index 434e4dfabb34475b3a1e7e63bef559f3561836ad..6f1b0944ae3c78848e6e5997bcad538e0cf2fa55 100644 --- a/src/maple_ir/src/mir_type.cpp +++ b/src/maple_ir/src/mir_type.cpp @@ -17,7 +17,7 @@ #include #include "mir_symbol.h" #include "printing.h" -#include "name_mangler.h" +#include "namemangler.h" #include "global_tables.h" #include "mir_builder.h" #include "cfg_primitive_types.h" diff --git a/src/maple_ir/src/option.cpp b/src/maple_ir/src/option.cpp index e9db67c9256b5706cdb8ac9c17762a82b4fb880e..73253f4a1812590a3db2032e3479fc34bf751194 100644 --- a/src/maple_ir/src/option.cpp +++ b/src/maple_ir/src/option.cpp @@ -58,6 +58,8 @@ bool Options::skipVirtualMethod = false; bool Options::nativeOpt = true; bool Options::O2 = false; bool Options::noDot = false; +bool Options::genIRProfile = false; +bool Options::testCase = false; bool Options::profileStaticFields = false; std::string Options::proFileData = ""; std::string Options::proFileFuncData = ""; diff --git a/src/maple_ir/src/parser.cpp b/src/maple_ir/src/parser.cpp index 075f7fb74c4ca4014f3a417f041eda9767b6678a..8e8d5adc2583d317900d186f7bc33270c1ec253a 100644 --- a/src/maple_ir/src/parser.cpp +++ b/src/maple_ir/src/parser.cpp @@ -18,7 +18,7 @@ #include #include "mir_parser.h" #include "mir_function.h" -#include "name_mangler.h" +#include "namemangler.h" #include "opcode_info.h" #include "mir_pragma.h" #include "bin_mplt.h" diff --git a/src/maple_me/BUILD.gn b/src/maple_me/BUILD.gn index cf68b225cfbeb0e3f192532c59c1a68ee5c36639..cba7020bb685f51b4e9bfe7f42dd49b257172d39 100644 --- a/src/maple_me/BUILD.gn +++ b/src/maple_me/BUILD.gn @@ -32,6 +32,8 @@ src_libmplme = [ "src/me_critical_edge.cpp", "src/me_bb_layout.cpp", "src/me_bypath_eh.cpp", + "src/me_profile_gen.cpp", + "src/me_profile_use.cpp", "src/me_cfg.cpp", "src/me_dse.cpp", "src/me_hdse.cpp", diff --git a/src/maple_me/include/bb.h b/src/maple_me/include/bb.h index 7ed4022f8bc76803164d727b06b39fc0723a95b2..ff0a4ad0da62ce0313cf646d5744c0da01b279e6 100644 --- a/src/maple_me/include/bb.h +++ b/src/maple_me/include/bb.h @@ -50,7 +50,8 @@ enum BBAttr : uint32 { kBBAttrIsJavaFinally = utils::bit_field_v<9>, kBBAttrArtificial = utils::bit_field_v<10>, kBBAttrIsInLoop = utils::bit_field_v<11>, - kBBAttrIsInLoopForEA = utils::bit_field_v<12> + kBBAttrIsInLoopForEA = utils::bit_field_v<12>, + kBBAttrIsInstrument = utils::bit_field_v<13> }; constexpr uint32 kBBVectorInitialSize = 2; @@ -65,10 +66,12 @@ class BB { : id(id), pred(kBBVectorInitialSize, nullptr, alloc->Adapter()), succ(kBBVectorInitialSize, nullptr, alloc->Adapter()), + succFreq(alloc->Adapter()), phiList(versAlloc->Adapter()), meVarPhiList(alloc->Adapter()), meRegPhiList(alloc->Adapter()), - meVarPiList(alloc->Adapter()) { + meVarPiList(alloc->Adapter()), + group(this) { pred.pop_back(); pred.pop_back(); succ.pop_back(); @@ -79,11 +82,13 @@ class BB { : id(id), pred(kBBVectorInitialSize, nullptr, alloc->Adapter()), succ(kBBVectorInitialSize, nullptr, alloc->Adapter()), + succFreq(alloc->Adapter()), phiList(versAlloc->Adapter()), meVarPhiList(alloc->Adapter()), meRegPhiList(alloc->Adapter()), meVarPiList(alloc->Adapter()), - stmtNodeList(firstStmt, lastStmt) { + stmtNodeList(firstStmt, lastStmt), + group(this) { pred.pop_back(); pred.pop_back(); succ.pop_back(); @@ -366,11 +371,36 @@ class BB { return meRegPhiList; } + uint64 GetEdgeFreq(const BB *bb) const { + auto edgeFreq = succFreq.find(bb); + CHECK_FATAL(edgeFreq != succFreq.end(), "bb's edge freq must be set before use"); + return edgeFreq->second; + } + + void SetEdgeFreq(const BB *bb, uint64 freq) { + auto iter = std::find(succ.begin(), succ.end(), bb); + CHECK_FATAL(iter != std::end(succ), "%d is not the successor of %d", bb->UintID(), this->UintID()); + succFreq[bb] = freq; + } + + BB* GetGroup() const { + return group; + } + + void SetGroup(BB *g) { + group = g; + } + + void ClearGroup() { + group = this; + } private: BBId id; LabelIdx bbLabel = 0; // the BB's label MapleVector pred; // predecessor list MapleVector succ; // successor list + // record the edge freq from curBB to succ BB + MapleMap succFreq; MapleMap phiList; MapleMap meVarPhiList; MapleMap meRegPhiList; @@ -380,6 +410,7 @@ class BB { uint32 attributes = 0; StmtNodes stmtNodeList; MeStmts meStmtList; + BB *group; }; using BBId = BB::BBId; diff --git a/src/maple_me/include/hdse.h b/src/maple_me/include/hdse.h index 55a06334b8944aa11c3aff7037c878a8e88050a1..cebd3e7b1e5cb5f977ed3dc2b8b02f5f7b3ee20e 100644 --- a/src/maple_me/include/hdse.h +++ b/src/maple_me/include/hdse.h @@ -24,7 +24,6 @@ class HDSE { public: HDSE(MIRModule &mod, const MapleVector &bbVec, BB &commonEntryBB, BB &commonExitBB, SSATab &ssaTab, Dominance &pDom, IRMap &map, bool enabledDebug = false) - : hdseDebug(enabledDebug), mirModule(mod), bbVec(bbVec), @@ -51,7 +50,7 @@ class HDSE { void RemoveNotRequiredStmtsInBB(BB &bb); template void MarkPhiRequired(VarOrRegPhiNode &mePhiNode); - void MarkMuListRequired(MapleMap &); + void MarkMuListRequired(MapleMap&); void MarkChiNodeRequired(ChiMeNode &chiNode); bool ExprNonDeletable(const MeExpr &expr) const; bool StmtMustRequired(const MeStmt &stmt, const BB &bb) const; diff --git a/src/maple_me/include/me_cfg.h b/src/maple_me/include/me_cfg.h index 4fa0d590d527d79d36082751b1e37742bcdbe286..89d9f32658686d63eb171c469d7bd9a5d105fb2e 100644 --- a/src/maple_me/include/me_cfg.h +++ b/src/maple_me/include/me_cfg.h @@ -32,7 +32,7 @@ class MeCFG { void Verify() const; void VerifyLabels() const; void Dump() const; - void DumpToFile(const std::string &prefix, bool dumpInStrs = false) const; + void DumpToFile(const std::string &prefix, bool dumpInStrs = false, bool dumpEdgeFreq = false) const; bool FindExprUse(const BaseNode &expr, StIdx stIdx) const; bool FindUse(const StmtNode &stmt, StIdx stIdx) const; bool FindDef(const StmtNode &stmt, StIdx stIdx) const; diff --git a/src/maple_me/include/me_cfg_mst.h b/src/maple_me/include/me_cfg_mst.h new file mode 100644 index 0000000000000000000000000000000000000000..7086312d30389d8ec7a1a15384e4e7fd692b49ff --- /dev/null +++ b/src/maple_me/include/me_cfg_mst.h @@ -0,0 +1,175 @@ +/* + * 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. + */ +#ifndef MAPLE_ME_INCLUDE_CFGMST_H +#define MAPLE_ME_INCLUDE_CFGMST_H + +#include "me_function.h" +#include "bb.h" + +namespace maple { +template +class CFGMST { + public: + CFGMST(MeFunction &func, MemPool &mp, bool dump) : func(&func), mp(&mp), dump(dump) {} + BB *FindGroup(BB *bb); + bool UnionGroups(BB *src, BB *dest); + void ComputeMST(); + void SortEdges(); + void AddEdge(BB *src, BB *dest, uint64 w, bool isCritical = false, bool isFake = false); + bool IsCritialEdge(const BB *src, const BB *dest) const { + return src->GetSucc().size() > 1 && dest->GetPred().size() > 1; + } + const std::vector &GetAllEdges() const { + return allEdges; + } + + uint32 GetAllEdgesSize() const { + return allEdges.size(); + } + + uint32 GetAllBBs() const { + return totalBB; + } + + void GetInstrumentEdges(std::vector &instrumentEdges) const { + for (const auto &e : allEdges) { + if (!e->IsInMST()) { + instrumentEdges.push_back(e); + } + } + } + + void BuildEdges(); + void DumpEdgesInfo() const; + private: + static constexpr int normalEdgeWeight = 2; + static constexpr int exitEdgeWeight = 3; + static constexpr int fakeExitEdgeWeight = 4; + static constexpr int criticalEdgeWeight = 4; + std::vector allEdges; + MeFunction *func; + MemPool *mp; + bool dump; + uint32 totalBB = 0; +}; + +template +void CFGMST::DumpEdgesInfo() const { + for (auto &edge : allEdges) { + BB *src = edge->GetSrcBB(); + BB *dest = edge->GetDestBB(); + LogInfo::MapleLogger() << "BB" << src->GetBBId() << "->" + << "BB" << dest->GetBBId() << " weight " << edge->GetWeight(); + if (edge->IsInMST()) { + LogInfo::MapleLogger() << " in Mst\n"; + } else { + LogInfo::MapleLogger() << " not in Mst\n"; + } + } +} + +template +BB *CFGMST::FindGroup(BB *bb) { + if (bb->GetGroup() != bb) { + BB *group = bb->GetGroup(); + bb->SetGroup(FindGroup(group)); + } + return bb->GetGroup(); +} + +template +bool CFGMST::UnionGroups(BB *src, BB *dest) { + BB *srcGroup = FindGroup(src); + BB *destGroup = FindGroup(dest); + if (srcGroup == destGroup) { + return false; + } + srcGroup->SetGroup(destGroup); + return true; +} + +template +void CFGMST::ComputeMST() { + BuildEdges(); + SortEdges(); + /* only one edge means only one bb */ + if (allEdges.size() == 1) { + if (dump) { + LogInfo::MapleLogger() << "only one edge in " << func->GetMirFunc()->GetName() << std::endl; + } + return; + } + for (auto &e : allEdges) { + if (UnionGroups(e->GetSrcBB(), e->GetDestBB())) { + e->SetInMST(); + } + } +} + +template +void CFGMST::AddEdge(BB *src, BB *dest, uint64 w, bool isCritical, bool isFake) { + if (src == nullptr || dest == nullptr) { + return; + } + bool found = false; + for (auto &edge : allEdges) { + if (edge->GetSrcBB() == src && edge->GetDestBB() == dest) { + uint64 weight = edge->GetWeight(); + weight++; + edge->SetWeight(weight); + found = true; + } + } + if (!found) { + allEdges.emplace_back(mp->New(src, dest, w, isCritical, isFake)); + } +} + +template +void CFGMST::SortEdges() { + std::stable_sort(allEdges.begin(), allEdges.end(), + [](const Edge *edge1, const Edge *edge2) { return edge1->GetWeight() > edge2->GetWeight(); }); +} + +template +void CFGMST::BuildEdges() { + BB *entry = func->GetCommonEntryBB(); + BB *exit = nullptr; + auto eIt = func->valid_end(); + for (auto bIt = func->valid_begin(); bIt != eIt; ++bIt) { + auto *bb = *bIt; + if (bIt == func->common_exit()) { + exit = *bIt; + continue; + } + totalBB++; + for (auto *succBB : bb->GetSucc()) { + /* exitBB incoming edge allocate high weight */ + if (succBB->GetKind() == BBKind::kBBReturn) { + AddEdge(bb, succBB, exitEdgeWeight); + continue; + } + AddEdge(bb, succBB, normalEdgeWeight); + } + } + + for (BB *bb : func->GetCommonExitBB()->GetPred()) { + AddEdge(bb, exit, fakeExitEdgeWeight, false, true); + } + /* insert fake edge to keep consistent */ + AddEdge(exit, entry, UINT64_MAX, false, true); +} +} // namespace maple +#endif // MAPLE_ME_INCLUDE_CFGMST_H diff --git a/src/maple_me/include/me_cond_based.h b/src/maple_me/include/me_cond_based.h index f0da8e875dff1c5b4dd87e305ba54d3e1b5fe63b..808cb0de10d9acadc341b114c4bc51ef77af2793 100644 --- a/src/maple_me/include/me_cond_based.h +++ b/src/maple_me/include/me_cond_based.h @@ -22,7 +22,7 @@ namespace maple { class MeCondBased { public: - MeCondBased(MeFunction *func, Dominance *dom) : func(func), dominance(dom) {} + MeCondBased(MeFunction &func, Dominance &dom) : func(&func), dominance(&dom) {} ~MeCondBased() = default; bool NullValueFromTestCond(const VarMeExpr&, const BB&, bool) const; diff --git a/src/maple_me/include/me_cond_based_npc.h b/src/maple_me/include/me_cond_based_npc.h index ea2acbbbae7723448568d00c2af663d977511c05..348588c678968d1df730814b384b351463d5ac05 100644 --- a/src/maple_me/include/me_cond_based_npc.h +++ b/src/maple_me/include/me_cond_based_npc.h @@ -19,7 +19,7 @@ namespace maple { class CondBasedNPC : public MeCondBased { public: - CondBasedNPC(MeFunction *func, Dominance *dom) : MeCondBased(func, dom) {} + CondBasedNPC(MeFunction &func, Dominance &dom) : MeCondBased(func, dom) {} ~CondBasedNPC() = default; void DoCondBasedNPC() const; diff --git a/src/maple_me/include/me_cond_based_rc.h b/src/maple_me/include/me_cond_based_rc.h index ea4bf853c0ee119e99259f2cd9fcbb05a953abda..e2fb9fa3c63c4d553f522ef2984d3dae18562a33 100644 --- a/src/maple_me/include/me_cond_based_rc.h +++ b/src/maple_me/include/me_cond_based_rc.h @@ -19,7 +19,7 @@ namespace maple { class CondBasedRC : public MeCondBased { public: - CondBasedRC(MeFunction *f, Dominance *dom) : MeCondBased(f, dom) {} + CondBasedRC(MeFunction &f, Dominance &dom) : MeCondBased(f, dom) {} virtual ~CondBasedRC() = default; }; diff --git a/src/maple_me/include/me_dse.h b/src/maple_me/include/me_dse.h index 34f6a9663e133fec56865b9e5eb2d7a8b625e287..239999278ac8b5932a459e13dc829f6b2fe672a4 100644 --- a/src/maple_me/include/me_dse.h +++ b/src/maple_me/include/me_dse.h @@ -26,11 +26,11 @@ namespace maple { class MeDSE : public DSE { public: - MeDSE(MeFunction *f, Dominance *dom, bool enabledDebug) - : DSE(std::vector(f->GetAllBBs().begin(), f->GetAllBBs().end()), - *f->GetCommonEntryBB(), *f->GetCommonExitBB(), *f->GetMeSSATab(), + MeDSE(MeFunction &func, Dominance *dom, bool enabledDebug) + : DSE(std::vector(func.GetAllBBs().begin(), func.GetAllBBs().end()), + *func.GetCommonEntryBB(), *func.GetCommonExitBB(), *func.GetMeSSATab(), *dom, enabledDebug), - func(*f) {} + func(func) {} virtual ~MeDSE() = default; void RunDSE(); diff --git a/src/maple_me/include/me_function.h b/src/maple_me/include/me_function.h index fa00528986da7fc0b456c6cad4b37b1882c7caac..8801072bdd62bb9a9c63b1fef3a0192743301a0f 100644 --- a/src/maple_me/include/me_function.h +++ b/src/maple_me/include/me_function.h @@ -26,6 +26,7 @@ #include "func_emit.h" #include "me_ir.h" #include "me_ssa.h" +#include "profile.h" namespace maple { class MeCFG; // circular dependency exists, no other choice @@ -449,6 +450,18 @@ class MeFunction : public FuncEmit { return memPool; } + void AddProfileDesc(uint64 hash, uint32 start, uint32 end) { + mirFunc->AddProfileDesc(hash, start, end); + } + + const IRProfileDesc *GetProfInf() { + if (profileDesc == nullptr) { + // return profileDesc with default value + profileDesc = memPool->New(); + } + return profileDesc; + } + void PartialInit(bool isSecondPass); const MapleVector &GetSccTopologicalVec() const { @@ -495,6 +508,7 @@ class MeFunction : public FuncEmit { uint32 hints = 0; bool hasEH = false; /* current has try statement */ bool secondPass = false; // second pass for the same function + IRProfileDesc *profileDesc = nullptr; }; } // namespace maple #endif // MAPLE_ME_INCLUDE_ME_FUNCTION_H diff --git a/src/maple_me/include/me_inequality_graph.h b/src/maple_me/include/me_inequality_graph.h index 795630dc9458a689fdd1537ff2298789f365b420..498c778a3a1b782c7e9ee027047aca86c1e629ef 100644 --- a/src/maple_me/include/me_inequality_graph.h +++ b/src/maple_me/include/me_inequality_graph.h @@ -19,9 +19,6 @@ #include #include -constexpr maple::int32 kUpperBound = -1; -constexpr maple::int32 kLowerBound = 0; - namespace maple { enum ESSANodeKind : std::uint8_t { kVarNode, @@ -42,7 +39,7 @@ enum EdgeType : std::uint8_t { kNone, kUpperInvalid, kLowerInvalid, - kNoneInValid + kNoneInvalid }; enum DumpType : std::uint8_t { @@ -99,12 +96,12 @@ class InequalEdge { void SetEdgeTypeInValid() { CHECK_FATAL(edgeType == kLower || edgeType == kUpper || edgeType == kNone, "must be"); - edgeType = edgeType == kLower ? kLowerInvalid : edgeType == kUpper ? kUpperInvalid : kNoneInValid; + edgeType = edgeType == kLower ? kLowerInvalid : (edgeType == kUpper ? kUpperInvalid : kNoneInvalid); } void SetEdgeTypeValid() { - CHECK_FATAL(edgeType == kLowerInvalid || edgeType == kUpperInvalid || edgeType == kNoneInValid, "must be"); - edgeType = edgeType == kLowerInvalid ? kLower : edgeType == kUpperInvalid ? kUpper : kNone; + CHECK_FATAL(edgeType == kLowerInvalid || edgeType == kUpperInvalid || edgeType == kNoneInvalid, "must be"); + edgeType = edgeType == kLowerInvalid ? kLower : (edgeType == kUpperInvalid ? kUpper : kNone); } EdgeType GetEdgeType() const { @@ -139,7 +136,7 @@ class InequalEdge { return edgeType == kUpper ? value.constValue <= edge.GetConstValue() : value.constValue >= edge.GetConstValue(); } - bool GreaterEqual(int32 val) const{ + bool GreaterEqual(int32 val) const { return edgeType == kUpper ? value.constValue >= val : value.constValue <= val; } @@ -172,6 +169,8 @@ class ESSABaseNode { public: struct ESSABaseNodeComparator { bool operator()(const ESSABaseNode *lhs, const ESSABaseNode *rhs) const { + ASSERT_NOT_NULL(lhs); + ASSERT_NOT_NULL(rhs); return lhs->GetID() < rhs->GetID(); } }; diff --git a/src/maple_me/include/me_loop_analysis.h b/src/maple_me/include/me_loop_analysis.h index 2ec728e19999cf9f258d6c4ca92de1da9a081b48..ea79c5950409ef9e6161f0c1d0af14936328adc8 100644 --- a/src/maple_me/include/me_loop_analysis.h +++ b/src/maple_me/include/me_loop_analysis.h @@ -28,25 +28,25 @@ struct LoopDesc { MapleSet loopBBs; LoopDesc *parent; // points to its closest nesting loop uint32 nestDepth; // the nesting depth - LoopDesc(MapleAllocator *alloc, BB *headBB, BB *tailBB) - : head(headBB), tail(tailBB), loopBBs(alloc->Adapter()), parent(nullptr), nestDepth(0) {} + LoopDesc(MapleAllocator &alloc, BB *headBB, BB *tailBB) + : head(headBB), tail(tailBB), loopBBs(alloc.Adapter()), parent(nullptr), nestDepth(0) {} - bool Has(const BB *bb) const { - return loopBBs.find(bb->GetBBId()) != loopBBs.end(); + bool Has(const BB &bb) const { + return loopBBs.find(bb.GetBBId()) != loopBBs.end(); } }; // IdentifyLoop records all the loops in a MeFunction. class IdentifyLoops : public AnalysisResult { public: - IdentifyLoops(MemPool *memPool, MeFunction *mf, Dominance *dm) + IdentifyLoops(MemPool *memPool, MeFunction &mf, Dominance *dm) : AnalysisResult(memPool), meLoopMemPool(memPool), meLoopAlloc(memPool), func(mf), dominance(dm), meLoops(meLoopAlloc.Adapter()), - bbLoopParent(func->GetAllBBs().size(), nullptr, meLoopAlloc.Adapter()) {} + bbLoopParent(func.GetAllBBs().size(), nullptr, meLoopAlloc.Adapter()) {} virtual ~IdentifyLoops() = default; @@ -67,7 +67,7 @@ class IdentifyLoops : public AnalysisResult { private: MemPool *meLoopMemPool; MapleAllocator meLoopAlloc; - MeFunction *func; + MeFunction &func; Dominance *dominance; MapleVector meLoops; MapleVector bbLoopParent; // gives closest nesting loop for each bb diff --git a/src/maple_me/include/me_lower_globals.h b/src/maple_me/include/me_lower_globals.h index 6582619a2fa9b6a5286881aa67d4fa8efa190e90..82984ceb0826300b24e56366fec4b27f5a866343 100644 --- a/src/maple_me/include/me_lower_globals.h +++ b/src/maple_me/include/me_lower_globals.h @@ -20,16 +20,12 @@ namespace maple { class MeLowerGlobals { public: - MeLowerGlobals(MeFunction *func, SSATab *ssaTab) : func(func), irMap(func->GetIRMap()), ssaTable(ssaTab) {} - MeLowerGlobals(const MeLowerGlobals &p) = default; - + MeLowerGlobals(MeFunction &func, SSATab *ssaTab) : func(func), irMap(func.GetIRMap()), ssaTable(ssaTab) {} ~MeLowerGlobals() = default; - MeLowerGlobals &operator=(const MeLowerGlobals &p) = default; - void Run(); private: - MeFunction *func; + MeFunction &func; IRMap *irMap; SSATab *ssaTable; void LowerGlobalDreads(MeStmt &stmt, MeExpr &expr); diff --git a/src/maple_me/include/me_may2dassign.h b/src/maple_me/include/me_may2dassign.h index 765da6349063b0d066d8266d96e2e7ea4badfea6..70a9e51f66ed3c760a370d5d3aa9b0c99206af92 100644 --- a/src/maple_me/include/me_may2dassign.h +++ b/src/maple_me/include/me_may2dassign.h @@ -21,13 +21,13 @@ namespace maple { class May2Dassign { public: - explicit May2Dassign(MeFunction *f) : func(f), irMap(f->GetIRMap()), ssaTab(f->GetMeSSATab()) {} + explicit May2Dassign(MeFunction &func) : func(func), irMap(func.GetIRMap()), ssaTab(func.GetMeSSATab()) {} ~May2Dassign() = default; void DoIt(); private: - MeFunction *func; + MeFunction &func; IRMap *irMap; SSATab *ssaTab; }; diff --git a/src/maple_me/include/me_pgo_instrument.h b/src/maple_me/include/me_pgo_instrument.h new file mode 100644 index 0000000000000000000000000000000000000000..86b86afffb2489afdda8c955ddb2abf856b7b100 --- /dev/null +++ b/src/maple_me/include/me_pgo_instrument.h @@ -0,0 +1,151 @@ +/* + * 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. + */ +#ifndef MAPLE_ME_INCLUDE_PGOINSTRUMENT_H +#define MAPLE_ME_INCLUDE_PGOINSTRUMENT_H + +#include "bb.h" +#include "me_cfg_mst.h" +#include "itab_util.h" + +namespace maple { +class BBEdge { + public: + BBEdge(BB *src, BB *dest, uint64 w = 1, bool isCritical = false, bool isFake = false) + : srcBB(src), destBB(dest), weight(w), inMST(false), isCritical(isCritical), isFake(isFake) {} + + ~BBEdge() = default; + + BB *GetSrcBB() const { + return srcBB; + } + + BB *GetDestBB() const { + return destBB; + } + + uint64 GetWeight() const { + return weight; + } + + void SetWeight(uint64 w) { + weight = w; + } + + bool IsCritical() const { + return isCritical; + } + + bool IsFake() const { + return isFake; + } + + bool IsInMST() const { + return inMST; + } + + void SetInMST() { + inMST = true; + } + + private: + BB *srcBB; + BB *destBB; + uint64 weight; + bool inMST; + bool isCritical; + bool isFake; +}; + +template +class PGOInstrument { + public: + PGOInstrument(MeFunction &func, MemPool &mp, bool dump) : mst(func, mp, dump), func(&func), mp(&mp), dump(dump) {} + + void FindInstrumentEdges() { + mst.ComputeMST(); + } + + ~PGOInstrument() { + ClearBBGroupInfo(); + } + + const std::vector &GetAllEdges() { + return mst.GetAllEdges(); + } + + uint32 GetAllBBs() { + return mst.GetAllBBs(); + } + + void GetInstrumentBBs(std::vector &bbs) const { + std::vector instrumentEdges; + mst.GetInstrumentEdges(instrumentEdges); + for (auto &edge : instrumentEdges) { + BB *src = edge->GetSrcBB(); + BB *dest = edge->GetDestBB(); + /* instrument the srcbb if it has a single succ */ + if (src->GetSucc().size() <= 1) { + if (src == func->GetCommonEntryBB()) { + bbs.push_back(dest); + } else { + bbs.push_back(src); + } + } else if (!edge->IsCritical()) { + bbs.push_back(dest); + } else { + LogInfo::MapleLogger() << "impossible case " << src->GetBBId() << " " << dest->GetBBId(); + } + } + } + + void DumpEdgeInfo() const { + mst.DumpEdgesInfo(); + } + + uint64 ComputeFuncHash() { + uint64 allEdgeSize = mst.GetAllEdgesSize(); + std::ostringstream ss; + auto eIt = func->valid_end(); + // compute func CFG hash,used to verify function IR change + for (auto bIt = func->valid_begin(); bIt != eIt; ++bIt) { + auto *bb = *bIt; + if (bIt == func->common_exit()) { + continue; + } + for (auto *succBB : bb->GetSucc()) { + ss << succBB->GetBBId() << " "; + } + } + uint32 hashCode = DJBHash(ss.str().c_str()); + return (allEdgeSize << edgeSizeInfoShift) | hashCode; + } + + void ClearBBGroupInfo() { + auto eIt = func->valid_end(); + for (auto bIt = func->valid_begin(); bIt != eIt; ++bIt) { + auto *bb = *bIt; + bb->ClearGroup(); + } + } + + private: + static constexpr uint32 edgeSizeInfoShift = 32; + CFGMST mst; + MeFunction *func; + MemPool *mp; + bool dump; +}; +} // namespace maple +#endif // MAPLE_ME_INCLUDE_PGOINSTRUMENT_H diff --git a/src/maple_me/include/me_phase.h b/src/maple_me/include/me_phase.h index 12ecd694ee44156909af2ad3e60f3fd05e1b0c70..24ba75023b4f1de3bb30f02192433b02da051bf5 100644 --- a/src/maple_me/include/me_phase.h +++ b/src/maple_me/include/me_phase.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2019] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. @@ -70,6 +70,11 @@ class MeFuncPhase : public Phase { isCFGChanged = false; } + void ClearString() { + prevPhaseName.clear(); + prevPhaseName.shrink_to_fit(); + } + private: MePhaseID phaseID; std::string prevPhaseName = ""; // used in filename for emit, init prev_phasename as nullptr diff --git a/src/maple_me/include/me_phases.def b/src/maple_me/include/me_phases.def index 20a0c2a2b900b716b2647190645489ac8a0c8441..8491bde2daeafa68a010279843bac8eccc35587b 100644 --- a/src/maple_me/include/me_phases.def +++ b/src/maple_me/include/me_phases.def @@ -25,6 +25,8 @@ FUNCAPHASE(MeFuncPhase_CONDBASEDNPC, MeDoCondBasedNPC) FUNCTPHASE(MeFuncPhase_MAY2DASSIGN, MeDoMay2Dassign) FUNCTPHASE(MeFuncPhase_LOOPCANON, MeDoLoopCanon) FUNCTPHASE(MeFuncPhase_SPLITCEDGE, MeDoSplitCEdge) +FUNCTPHASE(MeFuncPhase_PROFGEN, MeDoProfGen) +FUNCTPHASE(MeFuncPhase_PROFUSE, MeDoProfUse) FUNCTPHASE(MeFuncPhase_DSE, MeDoDSE) FUNCTPHASE(MeFuncPhase_HPROP, MeDoMeProp) FUNCTPHASE(MeFuncPhase_HDSE, MeDoHDSE) diff --git a/src/mplfe/common/include/fe_string_manager.h b/src/maple_me/include/me_profile_gen.h similarity index 37% rename from src/mplfe/common/include/fe_string_manager.h rename to src/maple_me/include/me_profile_gen.h index d7dcc77c9d2b9f9f33cb3420ed9801cdee8e22d3..fcac0654412caec984e931de65a2af4add10e418 100644 --- a/src/mplfe/common/include/fe_string_manager.h +++ b/src/maple_me/include/me_profile_gen.h @@ -12,15 +12,47 @@ * FIT FOR A PARTICULAR PURPOSE. * See the Mulan PSL v1 for more details. */ -#ifndef MPLFE_INCLUDE_COMMON_FE_STRING_MANAGER_H -#define MPLFE_INCLUDE_COMMON_FE_STRING_MANAGER_H -#include "mir_module.h" +#ifndef MAPLE_ME_INCLUDE_PROFILEGEN_H +#define MAPLE_ME_INCLUDE_PROFILEGEN_H + +#include "me_phase.h" +#include "me_pgo_instrument.h" +#include "bb.h" +#include "me_irmap.h" namespace maple { -class FEStringManager { +class BBEdge; +class MeProfGen : public PGOInstrument { + public: + MeProfGen(MeFunction &func, MemPool &mp, MeIRMap &hMap, bool dump) + : PGOInstrument(func, mp, dump), func(&func), hMap(&hMap), dump(dump) { + Init(); + } + void InstrumentFunc(); + private: + void Init(); + void InstrumentBB(BB &bb); + void SaveProfile(); + MeFunction *func; + MeIRMap *hMap; + bool dump; + static uint64 counterIdx; + static uint64 totalBB; + static uint64 instrumentBB; + static MIRSymbol *bbCounterTabSym; + static bool firstRun; +}; + +class MeDoProfGen : public MeFuncPhase { public: - FEStringManager(); - ~FEStringManager() = default; + explicit MeDoProfGen(MePhaseID id) : MeFuncPhase(id) {} + + ~MeDoProfGen() = default; + + AnalysisResult *Run(MeFunction *func, MeFuncResultMgr *m, ModuleResultMgr *mrm) override; + std::string PhaseName() const override { + return "profileGen"; + } }; } // namespace maple -#endif // MPLFE_INCLUDE_COMMON_FE_STRING_MANAGER_H \ No newline at end of file +#endif // MAPLE_ME_INCLUDE_PROFILEGEN_H diff --git a/src/maple_me/include/me_profile_use.h b/src/maple_me/include/me_profile_use.h new file mode 100644 index 0000000000000000000000000000000000000000..886a4152f86fbc9000085819b75c6e3a31764c62 --- /dev/null +++ b/src/maple_me/include/me_profile_use.h @@ -0,0 +1,166 @@ +/* + * 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. + */ +#ifndef MAPLE_ME_INCLUDE_PROFILEUSE_H +#define MAPLE_ME_INCLUDE_PROFILEUSE_H + +#include "me_phase.h" +#include "me_pgo_instrument.h" +#include "bb.h" + +namespace maple { +class BBUseEdge : public BBEdge { + public: + BBUseEdge(BB *src, BB *dest, uint64 w = 1, bool isCritical = false, bool isFake = false) + : BBEdge(src, dest, w, isCritical, isFake) {} + + void SetCount(uint64 value) { + countValue = value; + valid = true; + } + + uint64 GetCount() const { + return countValue; + } + + bool GetStatus() const { + return valid; + } + private: + bool valid = false; + uint64 countValue = 0; +}; + + +class BBUseInfo { + public: + BBUseInfo() {} + + void SetCount(uint64 value) { + countValue = value; + valid = true; + } + uint64 GetCount() const { + return countValue; + } + + bool GetStatus() const { + return valid; + } + + void AddOutEdge(BBUseEdge *e) { + outEdges.push_back(e); + if (!e->GetStatus()) { + unknownOutEdges++; + } + } + + void AddInEdge(BBUseEdge *e) { + inEdges.push_back(e); + if (!e->GetStatus()) { + unknownInEdges++; + } + } + + const std::vector &GetInEdges() const { + return inEdges; + } + + std::vector &GetInEdges() { + return inEdges; + } + + uint32 GetInEdgeSize() const { + return inEdges.size(); + } + + const std::vector &GetOutEdges() const { + return outEdges; + } + + std::vector &GetOutEdges() { + return outEdges; + } + + uint32 GetOutEdgeSize() const { + return outEdges.size(); + } + + void DecreaseUnKnownOutEdges() { + unknownOutEdges--; + } + + void DecreaseUnKnownInEdges() { + unknownInEdges--; + } + + uint32 GetUnknownOutEdges() const { + return unknownOutEdges; + } + + uint32 GetUnknownInEdges() const { + return unknownInEdges; + } + + private: + bool valid = false; + uint64 countValue = 0; + uint32 unknownInEdges = 0; + uint32 unknownOutEdges = 0; + std::vector inEdges; + std::vector outEdges; +}; + +class MeProfUse : public PGOInstrument { + public: + MeProfUse(MeFunction &func, MemPool &mp, bool dump) : PGOInstrument(func, mp, dump), + func(&func), mp(&mp), dump(dump) {} + bool BuildEdgeCount(); + void SetFuncEdgeInfo(); + void DumpFuncCFGEdgeFreq() const; + bool Run(); + bool IsSuccUseProf() const { + return succCalcuAllEdgeFreq; + } + private: + void SetEdgeCount(BBUseEdge &edge, uint32 value); + void SetEdgeCount(std::vector &edges, uint64 value); + void ComputeEdgeFreq(); + void InitBBEdgeInfo(); + void ComputeBBFreq(BBUseInfo &bbInfo, bool &changed); + uint64 SumEdgesCount(const std::vector &edges) const; + BBUseInfo *GetBBUseInfo(const BB &bb) const; + BBUseInfo *GetOrCreateBBUseInfo(const BB &bb) ; + MeFunction *func; + MemPool *mp; + bool dump; + bool succCalcuAllEdgeFreq = false; + std::unordered_map bbProfileInfo; +}; + +class MeDoProfUse : public MeFuncPhase { + public: + explicit MeDoProfUse(MePhaseID id) : MeFuncPhase(id) {} + + ~MeDoProfUse() = default; + + AnalysisResult *Run(MeFunction *func, MeFuncResultMgr *m, ModuleResultMgr *mrm) override; + std::string PhaseName() const override { + return "profileUse"; + } + + private: +}; +} // namespace maple +#endif // MAPLE_ME_INCLUDE_PROFILEUSE_H diff --git a/src/maple_me/include/me_ssu_pre.h b/src/maple_me/include/me_ssu_pre.h index 0ed421699e911d6a8630be863d22da9912a86e06..34c0431bb904497cecb6f17de393a626717141ae 100644 --- a/src/maple_me/include/me_ssu_pre.h +++ b/src/maple_me/include/me_ssu_pre.h @@ -31,7 +31,7 @@ enum SOccType { class SOcc { public: - SOcc(SOccType ty, BB *bb) : occTy(ty), classId(0), mirBB(bb), use(nullptr) {} + SOcc(SOccType ty, BB &bb) : occTy(ty), classId(0), mirBB(bb), use(nullptr) {} virtual ~SOcc() = default; @@ -39,7 +39,7 @@ class SOcc { bool IsPostDominate(Dominance *dom, const SOcc *occ) const { CHECK_NULL_FATAL(occ); CHECK_NULL_FATAL(dom); - return dom->PostDominate(*mirBB, *occ->mirBB); + return dom->PostDominate(mirBB, occ->mirBB); } SOccType GetOccTy() const { @@ -58,18 +58,14 @@ class SOcc { this->classId = id; } - BB *GetBB() { + BB &GetBB() { return mirBB; } - const BB *GetBB() const { + const BB &GetBB() const { return mirBB; } - void SetBB(BB &currMirBB) { - this->mirBB = &currMirBB; - } - SOcc *GetUse() const { return use; } @@ -81,23 +77,23 @@ class SOcc { private: SOccType occTy; uint32 classId; - BB *mirBB; // the BB it occurs in + BB &mirBB; // the BB it occurs in SOcc *use; // points to its single use }; class SRealOcc : public SOcc { public: - SRealOcc() - : SOcc(kSOccReal, nullptr), meStmt(nullptr), vMeExpr(nullptr), realFromDef(false), redundant(true) {} + SRealOcc(BB &bb) + : SOcc(kSOccReal, bb), meStmt(nullptr), vMeExpr(nullptr), realFromDef(false), redundant(true) {} explicit SRealOcc(MeStmt &s) - : SOcc(kSOccReal, s.GetBB()), meStmt(&s), vMeExpr(nullptr), realFromDef(false), redundant(true) {} + : SOcc(kSOccReal, *s.GetBB()), meStmt(&s), vMeExpr(nullptr), realFromDef(false), redundant(true) {} SRealOcc(MeStmt &s, VarMeExpr &v) - : SOcc(kSOccReal, s.GetBB()), meStmt(&s), vMeExpr(&v), realFromDef(false), redundant(true) {} + : SOcc(kSOccReal, *s.GetBB()), meStmt(&s), vMeExpr(&v), realFromDef(false), redundant(true) {} SRealOcc(BB &bb, VarMeExpr &v) - : SOcc(kSOccReal, &bb), meStmt(nullptr), vMeExpr(&v), realFromDef(false), redundant(true) {} + : SOcc(kSOccReal, bb), meStmt(nullptr), vMeExpr(&v), realFromDef(false), redundant(true) {} virtual ~SRealOcc() = default; void Dump() const { - LogInfo::MapleLogger() << "RealOcc at bb" << GetBB()->GetBBId(); + LogInfo::MapleLogger() << "RealOcc at bb" << GetBB().GetBBId(); if (realFromDef) { LogInfo::MapleLogger() << "(from-def)"; } @@ -140,11 +136,11 @@ class SLambdaOcc; class SLambdaResOcc : public SOcc { public: explicit SLambdaResOcc(BB &bb) - : SOcc(kSOccLambdaRes, &bb), useLambdaOcc(nullptr), hasRealUse(false), insertHere(false) {} + : SOcc(kSOccLambdaRes, bb), useLambdaOcc(nullptr), hasRealUse(false), insertHere(false) {} virtual ~SLambdaResOcc() = default; void Dump() const { - LogInfo::MapleLogger() << "LambdaResOcc at bb" << GetBB()->GetBBId() << " classId" << GetClassId(); + LogInfo::MapleLogger() << "LambdaResOcc at bb" << GetBB().GetBBId() << " classId" << GetClassId(); } const SLambdaOcc *GetUseLambdaOcc() const { @@ -180,7 +176,7 @@ class SLambdaResOcc : public SOcc { class SLambdaOcc : public SOcc { public: SLambdaOcc(BB &bb, MapleAllocator &alloc) - : SOcc(kSOccLambda, &bb), isUpsafe(true), isCanBeAnt(true), isEarlier(true), lambdaRes(alloc.Adapter()) {} + : SOcc(kSOccLambda, bb), isUpsafe(true), isCanBeAnt(true), isEarlier(true), lambdaRes(alloc.Adapter()) {} virtual ~SLambdaOcc() = default; bool WillBeAnt() const { @@ -188,7 +184,7 @@ class SLambdaOcc : public SOcc { } void Dump() const { - LogInfo::MapleLogger() << "LambdaOcc at bb" << GetBB()->GetBBId() << " classId" << GetClassId() << " Lambda["; + LogInfo::MapleLogger() << "LambdaOcc at bb" << GetBB().GetBBId() << " classId" << GetClassId() << " Lambda["; for (size_t i = 0; i < lambdaRes.size(); i++) { lambdaRes[i]->Dump(); if (i != lambdaRes.size() - 1) { @@ -235,27 +231,27 @@ class SLambdaOcc : public SOcc { class SEntryOcc : public SOcc { public: - explicit SEntryOcc(BB &bb) : SOcc(kSOccEntry, &bb) {} + explicit SEntryOcc(BB &bb) : SOcc(kSOccEntry, bb) {} virtual ~SEntryOcc() = default; void Dump() const { - LogInfo::MapleLogger() << "EntryOcc at bb" << GetBB()->GetBBId(); + LogInfo::MapleLogger() << "EntryOcc at bb" << GetBB().GetBBId(); } }; class SUseOcc : public SOcc { public: - explicit SUseOcc(BB &bb) : SOcc(kSOccUse, &bb) {} + explicit SUseOcc(BB &bb) : SOcc(kSOccUse, bb) {} virtual ~SUseOcc() = default; void Dump() const { - LogInfo::MapleLogger() << "UseOcc at bb" << GetBB()->GetBBId(); + LogInfo::MapleLogger() << "UseOcc at bb" << GetBB().GetBBId(); } }; class SPhiOcc : public SOcc { public: - SPhiOcc(BB &bb, MeVarPhiNode &p, VarMeExpr &v) : SOcc(kSOccPhi, &bb), phi(&p), vMeExpr(&v) {}; + SPhiOcc(BB &bb, MeVarPhiNode &p, VarMeExpr &v) : SOcc(kSOccPhi, bb), phi(&p), vMeExpr(&v) {}; virtual ~SPhiOcc() = default; @@ -276,7 +272,7 @@ class SPhiOcc : public SOcc { } void Dump() const { - LogInfo::MapleLogger() << "PhiOcc at bb" << GetBB()->GetBBId(); + LogInfo::MapleLogger() << "PhiOcc at bb" << GetBB().GetBBId(); } private: @@ -374,28 +370,6 @@ class MeSSUPre { void ApplySSUPre(); protected: - MeFunction *func; - SSATab *ssaTab; - MeIRMap *irMap; - MIRModule *mirModule; - Dominance *dom; - MemPool *spreMp; - MapleAllocator spreAllocator; - MapleMap workCandMap; - SpreWorkCand *workCand; // current SpreWorkCand - // step 1 lambda insertion data structures: - // following are set of BBs in terms of their dfn's; index into - // dominance->pdt_preorder to get their bbid's - MapleSet lambdaDfns; // set by FormLambdas() - // step 2 renaming - uint32 classCount; // for assigning new class id - // the following 3 lists are all maintained in order of pdt_preorder - MapleVector allOccs; // cleared at start of each workcand - MapleVector lambdaOccs; // cleared at start of each workcand - MapleVector entryOccs; // this is shared by all workcands - // used in steps 5 and 6 - MapleSet catchBlocks2Insert; // need insertions at entries to these catch blocks - bool enabledDebug; // step 6 methods virtual void CodeMotion() = 0; // step 5 methods @@ -426,6 +400,29 @@ class MeSSUPre { virtual void BuildWorkListBB(BB *bb) = 0; virtual void PerCandInit() = 0; virtual void CreateEmptyCleanupIntrinsics() {} + + MeFunction *func; + SSATab *ssaTab; + MeIRMap *irMap; + MIRModule *mirModule; + Dominance *dom; + MemPool *spreMp; + MapleAllocator spreAllocator; + MapleMap workCandMap; + SpreWorkCand *workCand; // current SpreWorkCand + // step 1 lambda insertion data structures: + // following are set of BBs in terms of their dfn's; index into + // dominance->pdt_preorder to get their bbid's + MapleSet lambdaDfns; // set by FormLambdas() + // step 2 renaming + uint32 classCount; // for assigning new class id + // the following 3 lists are all maintained in order of pdt_preorder + MapleVector allOccs; // cleared at start of each workcand + MapleVector lambdaOccs; // cleared at start of each workcand + MapleVector entryOccs; // this is shared by all workcands + // used in steps 5 and 6 + MapleSet catchBlocks2Insert; // need insertions at entries to these catch blocks + bool enabledDebug; }; }; // namespace maple #endif // MAPLE_ME_INCLUDE_MESSUPRE_H diff --git a/src/maple_me/include/me_stmt_pre.h b/src/maple_me/include/me_stmt_pre.h index 14550afa2a6080f56cf83beaefc5c477fbf2794e..e51d86863fc95edf5b6607697b0337179b6ff64d 100644 --- a/src/maple_me/include/me_stmt_pre.h +++ b/src/maple_me/include/me_stmt_pre.h @@ -24,10 +24,10 @@ class MeStmtPre : public SSAEPre { public: // a symbol is a candidate for ssaupdate if its ostidx key exists in the map; // the mapped set gives bbs where dassign's are inserted by stmtpre for the symbol - MeStmtPre(MeFunction *func, IRMap &map, Dominance &dom, MemPool &memPool, MemPool &mp2, uint32 limit) + MeStmtPre(MeFunction &func, IRMap &map, Dominance &dom, MemPool &memPool, MemPool &mp2, uint32 limit) : SSAEPre(map, dom, memPool, mp2, kStmtPre, limit, true, false), candsForSSAUpdate(std::less(), ssaPreAllocator.Adapter()), - func(func), + func(&func), versionStackVec(ssaTab->GetOriginalStTable().GetOriginalStVector().size(), nullptr, ssaPreAllocator.Adapter()), useOccurMap(std::less(), ssaPreAllocator.Adapter()) {} diff --git a/src/maple_me/include/me_store_pre.h b/src/maple_me/include/me_store_pre.h index 967c53ea83240f0bb4c2050e976e0f05755214c7..94aa0f4807c8e35dac5b0e1164d1b36c72b7555f 100644 --- a/src/maple_me/include/me_store_pre.h +++ b/src/maple_me/include/me_store_pre.h @@ -30,10 +30,6 @@ class MeStorePre : public MeSSUPre { inline bool IsJavaLang() const { return mirModule->IsJavaModule(); } - AliasClass *aliasClass; - // step 6 code motion - RegMeExpr *curTemp; // the preg for the RHS of inserted stores - MapleUnorderedMap bbCurTempMap; // map bb to curTemp version // step 6 methods void CheckCreateCurTemp(); RegMeExpr *EnsureRHSInCurTemp(BB &bb); @@ -49,6 +45,11 @@ class MeStorePre : public MeSSUPre { curTemp = nullptr; bbCurTempMap.clear(); } + + AliasClass *aliasClass; + // step 6 code motion + RegMeExpr *curTemp; // the preg for the RHS of inserted stores + MapleUnorderedMap bbCurTempMap; // map bb to curTemp version }; class MeDoStorePre : public MeFuncPhase { diff --git a/src/maple_me/include/occur.h b/src/maple_me/include/occur.h index 724549849b093b268aa14c32fb4ccfd03e896910..7a024ac532777902b89187524e918a8b2d98d074 100644 --- a/src/maple_me/include/occur.h +++ b/src/maple_me/include/occur.h @@ -17,7 +17,6 @@ // the data structures that represent occurrences and work candidates for SSAPRE #include "me_function.h" #include "irmap.h" -const int kWorkCandHashLength = 229; namespace maple { enum OccType { @@ -122,6 +121,7 @@ class MeRealOcc : public MeOccur { } Opcode GetOpcodeOfMeStmt() const { + ASSERT_NOT_NULL(meStmt); return meStmt->GetOp(); } @@ -229,6 +229,7 @@ class MeInsertedOcc : public MeOccur { } Opcode GetOpcodeOfMeStmt() const { + ASSERT_NOT_NULL(meStmt); return meStmt->GetOp(); } @@ -472,6 +473,7 @@ class MePhiOcc : public MeOccur { bool IsOpndDefByRealOrInserted() const; void Dump(const IRMap&) const; + private: bool isDownSafe; // default is true bool speculativeDownSafe; // is downsafe due to speculation @@ -487,6 +489,20 @@ class MePhiOcc : public MeOccur { // each singly linked list repersents each bucket in workCandHashTable class PreWorkCand { public: + static const uint32 workCandHashLength = 229; + static uint32 ComputeWorkCandHashIndex(const MeExpr &meExpr); + static std::array &GetWorkcandHashTable() { + return workCandHashTable; + } + + static PreWorkCand *GetWorkcandFromIndex(size_t idx) { + return workCandHashTable[idx]; + } + + static void SetWorkCandAt(size_t idx, PreWorkCand &workCand) { + workCandHashTable[idx] = &workCand; + } + PreWorkCand(MapleAllocator &alloc, int32 idx, MeExpr *meExpr, PUIdx pIdx) : next(nullptr), index(idx), @@ -518,13 +534,14 @@ class PreWorkCand { void AddRealOccSorted(const Dominance &dom, MeRealOcc &occ, PUIdx pIdx); PrimType GetPrimType() const { + ASSERT_NOT_NULL(theMeExpr); PrimType pTyp = theMeExpr->GetPrimType(); CHECK_FATAL(pTyp != kPtyInvalid, "invalid primtype"); return pTyp; } - static uint32 ComputeWorkCandHashIndex(const MeExpr &meExpr); - virtual void DumpCand(IRMap &irMap) { + virtual void DumpCand(IRMap &irMap) const { + ASSERT_NOT_NULL(theMeExpr); theMeExpr->Dump(&irMap); } @@ -610,19 +627,9 @@ class PreWorkCand { needLocalRefVar = need; } - static std::array &GetWorkcandHashTable() { - return workCandHashTable; - } - - static PreWorkCand *GetWorkcandFromIndex(size_t idx) { - return workCandHashTable[idx]; - } - - static void SetWorkCandAt(size_t idx, PreWorkCand &workCand) { - workCandHashTable[idx] = &workCand; - } - private: + static std::array workCandHashTable; + void InsertRealOccAt(MeRealOcc &occ, MapleVector::iterator it, PUIdx pIdx); PreWorkCand *next; int32 index; MapleVector realOccs; // maintained in order of dt_preorder @@ -634,8 +641,6 @@ class PreWorkCand { bool redo2HandleCritEdges : 1; // redo to make critical edges affect canbevail bool needLocalRefVar : 1; // for the candidate, if necessary to introduce // localrefvar in addition to the temp register to for saving the value - static std::array workCandHashTable; - void InsertRealOccAt(MeRealOcc &occ, MapleVector::iterator it, PUIdx pIdx); }; class PreStmtWorkCand : public PreWorkCand { @@ -645,7 +650,7 @@ class PreStmtWorkCand : public PreWorkCand { virtual ~PreStmtWorkCand() = default; static uint32 ComputeStmtWorkCandHashIndex(const MeStmt &stmt); - void DumpCand(IRMap &irMap) { + void DumpCand(IRMap &irMap) const { theMeStmt->Dump(&irMap); } @@ -661,7 +666,7 @@ class PreStmtWorkCand : public PreWorkCand { theMeStmt = &stmt; } - bool LHSIsFinal() { + bool LHSIsFinal() const { return lhsIsFinal; } diff --git a/src/maple_me/include/preg_renamer.h b/src/maple_me/include/preg_renamer.h index 78f600a984e9049985934a5e2e8b0e5392e6f598..bf4731e0789d9520ca9760616f27cde0d0ee9d63 100644 --- a/src/maple_me/include/preg_renamer.h +++ b/src/maple_me/include/preg_renamer.h @@ -32,6 +32,7 @@ class PregRenamer { MeIRMap *irMap; bool enabledDebug; }; + class MeDoPregRename : public MeFuncPhase { public: explicit MeDoPregRename(MePhaseID id) : MeFuncPhase(id) {} diff --git a/src/maple_me/include/prop.h b/src/maple_me/include/prop.h index 3c62c09a9641df5c66e018082e031134a2c3f841..6ef6d126a06ec70b80084cc31b06f38aab05ecb0 100644 --- a/src/maple_me/include/prop.h +++ b/src/maple_me/include/prop.h @@ -41,8 +41,6 @@ class Prop { void DoProp(); protected: - Dominance &dom; - virtual void UpdateCurFunction(BB&) const { } @@ -50,6 +48,8 @@ class Prop { return false; } + Dominance &dom; + private: using SafeMeExprPtr = utils::SafePtr; void TraversalBB(BB &bb); diff --git a/src/maple_me/include/ssa_epre.h b/src/maple_me/include/ssa_epre.h index 237df61aee7db70a99bf40089227817ee0140805..0de035869a8d0efaedaee6a757e77e119825baee 100644 --- a/src/maple_me/include/ssa_epre.h +++ b/src/maple_me/include/ssa_epre.h @@ -33,7 +33,7 @@ class SSAEPre : public SSAPre { void ComputeVarAndDfPhis(); void BuildWorkListExpr(MeStmt &meStmt, int32 seqStmt, MeExpr&, bool isReBuild, MeExpr *tempVar, bool isRootExpr); void BuildWorkListIvarLHSOcc(MeStmt &meStmt, int32 seqStmt, bool isReBuild, MeExpr *tempVar); - void CollectVarForMeExpr(MeExpr &meExpr, std::vector &varVec) const ; + void CollectVarForMeExpr(MeExpr &meExpr, std::vector &varVec) const; void CollectVarForCand(MeRealOcc &realOcc, std::vector &varVec) const; bool LeafIsVolatile(const MeExpr *x) const { const VarMeExpr *v = safe_cast(x); diff --git a/src/maple_me/include/ssa_pre.h b/src/maple_me/include/ssa_pre.h index b9cc744bfb28a635101726841aa324880d8e0c73..f38bf0e8386e0dd51852ef1ce82b52c7976ef93f 100644 --- a/src/maple_me/include/ssa_pre.h +++ b/src/maple_me/include/ssa_pre.h @@ -141,13 +141,13 @@ class SSAPre { // step 5 Finalize methods virtual void Finalize1(); void SetSave(MeOccur &defX); - void SetReplacement(MePhiOcc &occ, MeOccur *repDef); + void SetReplacement(MePhiOcc &occ, MeOccur &repDef); virtual void Finalize2(); // step 4 willbevail methods void ComputeCanBeAvail() const; void ResetCanBeAvail(MePhiOcc &occ) const; void ComputeLater() const; - void ResetLater(MePhiOcc *occ) const; + void ResetLater(MePhiOcc &occ) const; // step 3 downsafety methods void ResetDS(MePhiOpndOcc &phiOpnd) const; void ComputeDS() const; @@ -174,7 +174,7 @@ class SSAPre { virtual void BuildWorkListExpr(MeStmt &meStmt, int32 seqStmt, MeExpr &meExpr, bool isRebuilt, MeExpr *tempVar, bool isRootExpr) = 0; - virtual void BuildWorkListStmt(MeStmt* meStmt, uint32 seqStmt, bool isRebuilt, MeExpr *tempVar = nullptr); + virtual void BuildWorkListStmt(MeStmt &stmt, uint32 seqStmt, bool isRebuilt, MeExpr *tempVar = nullptr); virtual void BuildWorkListBB(BB *bb); virtual void ConstructUseOccurMap() {} diff --git a/src/maple_me/src/dse.cpp b/src/maple_me/src/dse.cpp index 5a74d9d2b6083f578876f048933823a2729378f1..67265b7432992599355b67e486c7530a5c0f458d 100644 --- a/src/maple_me/src/dse.cpp +++ b/src/maple_me/src/dse.cpp @@ -134,7 +134,7 @@ void DSE::CheckRemoveCallAssignedReturn(StmtNode &stmt) { } DumpStmt(stmt, "**** DSE1 deleting return value assignment in: "); CallReturnVector *rets = stmt.GetCallReturnVector(); - CHECK_FATAL(rets != nullptr, "null ptr check "); + CHECK_FATAL(rets != nullptr, "null ptr check"); rets->clear(); mustDefs.clear(); break; diff --git a/src/maple_me/src/hdse.cpp b/src/maple_me/src/hdse.cpp index 303051d10924c4a9915f6cb7b9fda12495a96d76..806aaaa6f67df831d8d82eb2ad2117f5205dd631 100644 --- a/src/maple_me/src/hdse.cpp +++ b/src/maple_me/src/hdse.cpp @@ -33,7 +33,6 @@ // 3. For the nodes in worklist mark the def stmt as needed just as step 2 and // pop the node from the worklist. // 4. Repeat step 3 until the worklist is empty. - namespace maple { using namespace utils; @@ -272,7 +271,7 @@ void HDSE::MarkLastStmtInPDomBBRequired(const BB &bb) { CHECK_FATAL((lastStmt.IsCondBr() || op == OP_switch || op == OP_retsub || op == OP_throw || cdBB->GetAttributes(kBBAttrIsTry) || cdBB->GetAttributes(kBBAttrWontExit)), "HDSE::MarkLastStmtInPDomBBRequired: control dependent on unexpected statement"); - if ((IsBranch(op) || op == OP_retsub || op == OP_throw)) { + if ((IsBranch(op) || op == OP_retsub || op == OP_throw)) { MarkStmtRequired(lastStmt); } } @@ -305,7 +304,7 @@ void HDSE::MarkSingleUseLive(MeExpr &meExpr) { return; } SetExprNeeded(meExpr); - MeExprOp meOp = meExpr.GetMeOp(); + MeExprOp meOp = meExpr.GetMeOp(); switch (meOp) { case kMeOpVar: case kMeOpReg: { @@ -401,12 +400,9 @@ void HDSE::MarkSpecialStmtRequired() { void HDSE::DseInit() { // Init bb's required flag - if (&commonEntryBB != *bbVec.begin()) { - bbRequired[commonEntryBB.GetBBId()] = true; - } - if (&commonExitBB != *bbVec.end()) { - bbRequired[commonExitBB.GetBBId()] = true; - } + bbRequired[commonEntryBB.GetBBId()] = true; + bbRequired[commonExitBB.GetBBId()] = true; + // Init all MeExpr to be dead; exprLive.resize(irMap.GetExprID(), false); diff --git a/src/maple_me/src/me_abco.cpp b/src/maple_me/src/me_abco.cpp index dd6ac35af853492e83b41efaff5cb82d7b619bae..be461616916c3067d4be18cef7fe48b76332a492 100644 --- a/src/maple_me/src/me_abco.cpp +++ b/src/maple_me/src/me_abco.cpp @@ -210,6 +210,7 @@ bool MeABC::ExistedPiNode(BB &bb, BB &parentBB, VarMeExpr &rhs) { void MeABC::CreatePhi(VarMeExpr &rhs, BB &dfBB) { VarMeExpr *phiNewLHS = CreateNewPiExpr(rhs); + ASSERT_NOT_NULL(phiNewLHS); MeVarPhiNode *newPhi = GetMemPool()->New(phiNewLHS, &GetAllocator()); newPhi->SetDefBB(&dfBB); newPhi->GetOpnds().resize(dfBB.GetPred().size(), &rhs); @@ -475,7 +476,7 @@ bool MeABC::ReplaceMeExprStmtOpnd(uint32 opndID, MeStmt &meStmt, MeExpr &oldVar, newExpr = ReplaceMeExprExpr(*opnd, oldVar, newVar); replaced = (newExpr != opnd); if (isFromIassign) { - static_cast(&meStmt)->SetLHSVal(static_cast(newExpr)); + static_cast(&meStmt)->SetLHSVal(static_cast(newExpr)); } else { meStmt.SetOpnd(opndID, newExpr); } @@ -796,18 +797,24 @@ bool MeABC::BuildBrMeStmtInGraph(MeStmt &meStmt) { MeExpr *MeABC::TryToResolveVar(MeExpr &expr, std::set &visitedPhi, MeExpr &dummyExpr, bool isConst) { CHECK_FATAL(expr.GetMeOp() == kMeOpVar, "must be"); auto *var = static_cast(&expr); - if (var->GetDefBy() == kDefByStmt && isConst && !var->GetDefStmt()->GetRHS()->IsLeaf()) { - return nullptr; - } - if (var->GetDefBy() == kDefByStmt && isConst && var->GetDefStmt()->GetRHS()->GetMeOp() == kMeOpConst) { - return var->GetDefStmt()->GetRHS(); - } - if (var->GetDefBy() == kDefByStmt && !isConst && var->GetDefStmt()->GetRHS()->GetMeOp() == kMeOpIvar) { - return var->GetDefStmt()->GetRHS(); - } - if (var->GetDefBy() == kDefByStmt && isConst) { - CHECK_FATAL(var->GetDefStmt()->GetRHS()->GetMeOp() == kMeOpVar, "must be"); - return TryToResolveVar(*(var->GetDefStmt()->GetRHS()), visitedPhi, dummyExpr, isConst); + + if (var->GetDefBy() == kDefByStmt) { + ASSERT_NOT_NULL(var->GetDefStmt()); + auto *rhs = var->GetDefStmt()->GetRHS(); + CHECK_NULL_FATAL(rhs); + if (isConst && !rhs->IsLeaf()) { + return nullptr; + } + if (isConst && rhs->GetMeOp() == kMeOpConst) { + return rhs; + } + if (!isConst && rhs->GetMeOp() == kMeOpIvar) { + return rhs; + } + if (isConst) { + CHECK_FATAL(rhs->GetMeOp() == kMeOpVar, "must be"); + return TryToResolveVar(*rhs, visitedPhi, dummyExpr, isConst); + } } if (var->GetDefBy() == kDefByPhi) { @@ -839,6 +846,7 @@ MeExpr *MeABC::TryToResolveVar(MeExpr &expr, std::set &visitedPhi bool MeABC::BuildAssignInGraph(MeStmt &meStmt) { MeExpr *lhs = meStmt.GetLHS(); MeExpr *rhs = meStmt.GetRHS(); + CHECK_NULL_FATAL(lhs); CHECK_NULL_FATAL(rhs); if (!lhs->IsLeaf()) { return false; @@ -1261,6 +1269,7 @@ bool MeABC::CleanABCInStmt(MeStmt &meStmt, NaryMeExpr &naryMeExpr) { case OP_dassign: case OP_maydassign: { MeExpr *rhs = meStmt.GetRHS(); + ASSERT_NOT_NULL(rhs); CHECK_FATAL(!rhs->IsLeaf(), "must be"); MeExpr *newRHS = ReplaceArrayExpr(*rhs, naryMeExpr, nullptr); replaced = rhs != newRHS; diff --git a/src/maple_me/src/me_analyze_rc.cpp b/src/maple_me/src/me_analyze_rc.cpp index bd959b69480e01d3e957628e8f1c29e94e50cb03..86accbec2ef5c5cdf8638ab2a5c85b3e1b7db53d 100644 --- a/src/maple_me/src/me_analyze_rc.cpp +++ b/src/maple_me/src/me_analyze_rc.cpp @@ -62,7 +62,9 @@ // if number of live localrefvars is more than this limit at a return, we will // not insert the intrinsiccall to CLEANUP_LOCALREFVARS +namespace { constexpr int kCleanupLocalRefVarsLimit = 200; +} // namespace namespace maple { void RCItem::Dump() { diff --git a/src/maple_me/src/me_bypath_eh.cpp b/src/maple_me/src/me_bypath_eh.cpp index c66989d35e6554c4f4be3803c891365eefa2a28e..a95ff3d5a3f8e441cf93a88c80bc504793369ae9 100644 --- a/src/maple_me/src/me_bypath_eh.cpp +++ b/src/maple_me/src/me_bypath_eh.cpp @@ -181,6 +181,7 @@ StmtNode *MeDoBypathEH::IsSyncExit(BB &syncBB, MeFunction &func, LabelIdx second return nullptr; } auto *dreadNode = static_cast(throwStmt->GetRHS()); + ASSERT_NOT_NULL(dreadNode); if (dreadNode->GetStIdx() != dassignNode->GetStIdx()) { return nullptr; } @@ -222,7 +223,7 @@ void MeDoBypathEH::BypathException(MeFunction &func, const KlassHierarchy &kh) c if (tryNode->GetOffsetsCount() == 1) { labelIdx = tryNode->GetOffset(0); } else if (tryNode->GetOffsetsCount() == 2) { // Deal with sync - BB *catchBB = nullptr; + BB *catchBB = nullptr; for (BB *bbInner : func.GetAllBBs()) { if (bbInner == nullptr) { continue; @@ -330,7 +331,7 @@ void MeDoBypathEH::BypathException(MeFunction &func, const KlassHierarchy &kh) c } AnalysisResult *MeDoBypathEH::Run(MeFunction *func, MeFuncResultMgr*, ModuleResultMgr *mrm) { - auto *kh = static_cast(mrm->GetAnalysisResult(MoPhase_CHA, &func->GetMIRModule())); + auto *kh = static_cast(mrm->GetAnalysisResult(MoPhase_CHA, &func->GetMIRModule())); CHECK_NULL_FATAL(kh); BypathException(*func, *kh); return nullptr; diff --git a/src/maple_me/src/me_cfg.cpp b/src/maple_me/src/me_cfg.cpp index 7b01fa8872bda22c37c6726b4a4e20832b5f4e4f..6e6617f09a318d7198c6de5b13eadb5ae3fe7294 100644 --- a/src/maple_me/src/me_cfg.cpp +++ b/src/maple_me/src/me_cfg.cpp @@ -836,7 +836,7 @@ void MeCFG::DumpToFileInStrs(std::ofstream &cfgFile) const { } // generate dot file for cfg -void MeCFG::DumpToFile(const std::string &prefix, bool dumpInStrs) const { +void MeCFG::DumpToFile(const std::string &prefix, bool dumpInStrs, bool dumpEdgeFreq) const { if (MeOption::noDot) { return; } @@ -860,16 +860,24 @@ void MeCFG::DumpToFile(const std::string &prefix, bool dumpInStrs) const { } continue; } + if (bb->GetAttributes(kBBAttrIsInstrument)) { + cfgFile << "BB" << bb->GetBBId() << "[color=blue];\n"; + } + for (auto it = bb->GetSucc().begin(); it != bb->GetSucc().end(); ++it) { cfgFile << "BB" << bb->GetBBId() << " -> " << "BB" << (*it)->GetBBId(); if (bb == func.GetCommonEntryBB()) { - cfgFile << "[style=dotted];\n"; + cfgFile << "[style=dotted]"; continue; } if ((*it)->GetAttributes(kBBAttrIsCatch)) { /* succ is exception handler */ - cfgFile << "[color=red];\n"; + cfgFile << "[color=red]"; + } + + if (dumpEdgeFreq) { + cfgFile << "[label=" << bb->GetEdgeFreq(*it) << "];\n"; } else { cfgFile << ";\n"; } diff --git a/src/maple_me/src/me_cond_based_opt.cpp b/src/maple_me/src/me_cond_based_opt.cpp index e347d4fe6936cbca43e47d8a14dad4e095a5e1eb..4f6d46ab6dc53213fdea72f1b5c175c43eecac69 100644 --- a/src/maple_me/src/me_cond_based_opt.cpp +++ b/src/maple_me/src/me_cond_based_opt.cpp @@ -243,7 +243,7 @@ void CondBasedNPC::DoCondBasedNPC() const { AnalysisResult *MeDoCondBasedRC::Run(MeFunction *func, MeFuncResultMgr *m, ModuleResultMgr*) { auto *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); ASSERT(dom != nullptr, "dominance phase has problem"); - CondBasedRC condBasedRC(func, dom); + CondBasedRC condBasedRC(*func, *dom); auto eIt = func->valid_end(); for (auto bIt = func->valid_begin(); bIt != eIt; ++bIt) { auto *bb = *bIt; @@ -279,7 +279,7 @@ AnalysisResult *MeDoCondBasedRC::Run(MeFunction *func, MeFuncResultMgr *m, Modul AnalysisResult *MeDoCondBasedNPC::Run(MeFunction *func, MeFuncResultMgr *m, ModuleResultMgr*) { auto *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); ASSERT(dom != nullptr, "dominance phase has problem"); - CondBasedNPC condBasedNPC(func, dom); + CondBasedNPC condBasedNPC(*func, *dom); condBasedNPC.DoCondBasedNPC(); return nullptr; } diff --git a/src/maple_me/src/me_critical_edge.cpp b/src/maple_me/src/me_critical_edge.cpp index 98cbbd7f9cd06c6429a5ffeb9a373dc842f0ad8b..5fa21f1916522c286ff2fc9df52d8c814a6e81c9 100644 --- a/src/maple_me/src/me_critical_edge.cpp +++ b/src/maple_me/src/me_critical_edge.cpp @@ -31,7 +31,6 @@ // // newbb is always appended at the end of bb_vec_ and pred/succ will be updated. // The bblayout phase will determine the final layout order of the bbs. - namespace maple { void MeDoSplitCEdge::BreakCriticalEdge(MeFunction &func, BB &pred, BB &succ) const { if (DEBUGFUNC(&func)) { diff --git a/src/maple_me/src/me_delegate_rc.cpp b/src/maple_me/src/me_delegate_rc.cpp index c5abad9f715efc241d892fa14c6b7d2a02a4fa73..32adaae4f48e25f27a1d27bf132793f03e985ccd 100644 --- a/src/maple_me/src/me_delegate_rc.cpp +++ b/src/maple_me/src/me_delegate_rc.cpp @@ -143,7 +143,7 @@ void DelegateRC::CollectDerefedOrCopied(const MeExpr &expr) { // collect the def of basevar if (baseVar->GetDefBy() == kDefByStmt) { MeStmt *defStmt = baseVar->GetDefStmt(); - if (defStmt->GetOp() == OP_dassign && defStmt->GetRHS()->GetOp() == OP_cvt) { + if (defStmt->GetOp() == OP_dassign && defStmt->GetRHS() != nullptr && defStmt->GetRHS()->GetOp() == OP_cvt) { SaveDerefedOrCopiedVst(defStmt->GetRHS()->GetOpnd(0)); } } else if (baseVar->GetDefBy() == kDefByPhi) { @@ -151,7 +151,8 @@ void DelegateRC::CollectDerefedOrCopied(const MeExpr &expr) { for (VarMeExpr *phiOpnd : defPhi.GetOpnds()) { if (phiOpnd->GetDefBy() == kDefByStmt) { MeStmt *defStmt = phiOpnd->GetDefStmt(); - if (defStmt->GetOp() == OP_dassign && defStmt->GetRHS()->GetOp() == OP_cvt) { + if (defStmt->GetOp() == OP_dassign && defStmt->GetRHS() != nullptr && + defStmt->GetRHS()->GetOp() == OP_cvt) { SaveDerefedOrCopiedVst(defStmt->GetRHS()->GetOpnd(0)); } } @@ -239,6 +240,7 @@ bool DelegateRC::MayThrowException(const MeStmt &stmt) const { } if (CheckOp(stmt, OP_regassign)) { + ASSERT_NOT_NULL(stmt.GetRHS()); return stmt.GetRHS()->GetOp() == OP_gcmalloc || stmt.GetRHS()->GetOp() == OP_gcmallocjarray; } @@ -768,7 +770,7 @@ void DelegateRC::CleanUpDeadLocalRefVar(const std::set &liveLocalrefvars } AnalysisResult *MeDoDelegateRC::Run(MeFunction *func, MeFuncResultMgr *m, ModuleResultMgr*) { - static uint32 pUcount = 0; + static uint32 puCount = 0; auto *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); ASSERT(dom != nullptr, "dominance phase has problem"); { @@ -780,11 +782,11 @@ AnalysisResult *MeDoDelegateRC::Run(MeFunction *func, MeFuncResultMgr *m, Module LogInfo::MapleLogger() << " Processing " << func->GetMirFunc()->GetName() << '\n'; } DelegateRC delegaterc(*func, *dom, NewMemPool(), DEBUGFUNC(func)); - if (pUcount > MeOption::delRcPULimit) { - ++pUcount; + if (puCount > MeOption::delRcPULimit) { + ++puCount; return nullptr; } - if (pUcount == MeOption::delRcPULimit) { + if (puCount == MeOption::delRcPULimit) { LogInfo::MapleLogger() << func->GetMirFunc()->GetName() << " is last PU optimized by delegaterc under -delrcpulimit option" << '\n'; } @@ -795,14 +797,14 @@ AnalysisResult *MeDoDelegateRC::Run(MeFunction *func, MeFuncResultMgr *m, Module // final pass: rename the uses of the delegated ref pointer variable versions; // set live_localrefvars based on appearances on LHS // to detect dead localrefvars - std::set liveLocalrefvars = delegaterc.RenameAndGetLiveLocalRefVar(); + std::set liveLocalRefVars = delegaterc.RenameAndGetLiveLocalRefVar(); // postpass: go through the cleanup intrinsics to delete dead localrefvars - delegaterc.CleanUpDeadLocalRefVar(liveLocalrefvars); + delegaterc.CleanUpDeadLocalRefVar(liveLocalRefVars); if (DEBUGFUNC(func)) { LogInfo::MapleLogger() << "\n============== After DELEGATE RC =============" << '\n'; func->GetIRMap()->Dump(); } - ++pUcount; + ++puCount; return nullptr; } } // namespace maple diff --git a/src/maple_me/src/me_dse.cpp b/src/maple_me/src/me_dse.cpp index 7073089e17567793659d239e739ced6231700d66..55a193e0331d1b0130d8ceb8eaa48e72ed6d2561 100644 --- a/src/maple_me/src/me_dse.cpp +++ b/src/maple_me/src/me_dse.cpp @@ -33,7 +33,7 @@ void MeDSE::VerifyPhi() const { size_t predBBNums = bb->GetPred().size(); for (auto &pair : bb->GetPhiList()) { if (IsSymbolLived(*pair.second.GetResult())) { - if (predBBNums <= 1) { + if (predBBNums <= 1) { // phi is live and non-virtual in bb with 0 or 1 pred const OriginalSt *ost = pair.first; CHECK_FATAL(!ost->IsSymbolOst() || ost->GetIndirectLev() != 0, "phi is live and non-virtual in bb with zero or one pred"); @@ -64,7 +64,7 @@ AnalysisResult *MeDoDSE::Run(MeFunction *func, MeFuncResultMgr *m, ModuleResultM CHECK_NULL_FATAL(func); auto *postDom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); CHECK_NULL_FATAL(postDom); - MeDSE dse(func, postDom, DEBUGFUNC(func)); + MeDSE dse(*func, postDom, DEBUGFUNC(func)); dse.RunDSE(); func->Verify(); // cfg change , invalid results in MeFuncResultMgr diff --git a/src/maple_me/src/me_inequality_graph.cpp b/src/maple_me/src/me_inequality_graph.cpp index 41e41f6340bed03b4bdf6e121434e4d86729b5c2..38b6b7ad964d427d2278e7fd035d4e0652ede100 100644 --- a/src/maple_me/src/me_inequality_graph.cpp +++ b/src/maple_me/src/me_inequality_graph.cpp @@ -14,6 +14,11 @@ */ #include "me_inequality_graph.h" +namespace { +constexpr maple::int32 kUpperBound = -1; +constexpr maple::int32 kLowerBound = 0; +} // namespace + namespace maple { ESSAConstNode *InequalityGraph::GetOrCreateConstNode(int value) { if (HasNode(value)) { @@ -233,13 +238,14 @@ std::string InequalityGraph::GetColor(EdgeType type) const { return "color = blue, style=dashed"; case kNone: return "color = black"; - case kNoneInValid: + case kNoneInvalid: return "color = black, style=dashed"; } } void InequalityGraph::DumpDotEdges(IRMap &irMap, const std::pair &map, std::ostream &out, std::string &from) const { + ASSERT_NOT_NULL(map.second); if (map.second->IsVarValue()) { std::string to = GetName(*(map.first), irMap); std::string positive = map.second->GetVarValue().IsPositive() ? "" : "-"; @@ -266,10 +272,10 @@ void InequalityGraph::DumpDotNodes(IRMap &irMap, std::ostream &out, DumpType dum if (dumpType == kDumpNone) { DumpDotEdges(irMap, *iterConstEdges, out, from); } else if ((dumpType == kDumpUpperAndNone) && - (edgeType == kUpper || edgeType == kNone || edgeType == kUpperInvalid || edgeType == kNoneInValid)) { + (edgeType == kUpper || edgeType == kNone || edgeType == kUpperInvalid || edgeType == kNoneInvalid)) { DumpDotEdges(irMap, *iterConstEdges, out, from); } else if ((dumpType == kDumpLowerAndNone) && - (edgeType == kLower || edgeType == kNone || edgeType == kLowerInvalid || edgeType == kNoneInValid)) { + (edgeType == kLower || edgeType == kNone || edgeType == kLowerInvalid || edgeType == kNoneInvalid)) { DumpDotEdges(irMap, *iterConstEdges, out, from); } } @@ -282,11 +288,11 @@ void InequalityGraph::DumpDotNodes(IRMap &irMap, std::ostream &out, DumpType dum DumpDotEdges(irMap, *iterConstEdges, out, from); } else if ((dumpType == kDumpUpperAndNone) && (edgeType == kUpper || edgeType == kNone || - edgeType == kUpperInvalid || edgeType == kNoneInValid)) { + edgeType == kUpperInvalid || edgeType == kNoneInvalid)) { DumpDotEdges(irMap, *iterConstEdges, out, from); } else if ((dumpType == kDumpLowerAndNone) && (edgeType == kLower || edgeType == kNone || - edgeType == kLowerInvalid || edgeType == kNoneInValid)) { + edgeType == kLowerInvalid || edgeType == kNoneInvalid)) { DumpDotEdges(irMap, *iterConstEdges, out, from); } } @@ -297,10 +303,10 @@ void InequalityGraph::DumpDotNodes(IRMap &irMap, std::ostream &out, DumpType dum if (dumpType == kDumpNone) { DumpDotEdges(irMap, *iterVarEdges, out, from); } else if ((dumpType == kDumpUpperAndNone) && - (edgeType == kUpper || edgeType == kNone || edgeType == kUpperInvalid || edgeType == kNoneInValid)) { + (edgeType == kUpper || edgeType == kNone || edgeType == kUpperInvalid || edgeType == kNoneInvalid)) { DumpDotEdges(irMap, *iterVarEdges, out, from); } else if ((dumpType == kDumpLowerAndNone) && - (edgeType == kLower || edgeType == kNone || edgeType == kLowerInvalid || edgeType == kNoneInValid)) { + (edgeType == kLower || edgeType == kNone || edgeType == kLowerInvalid || edgeType == kNoneInvalid)) { DumpDotEdges(irMap, *iterVarEdges, out, from); } } @@ -332,7 +338,7 @@ bool ABCD::DemandProve(const MeExpr &arrayNode, const MeExpr &idx) { ESSABaseNode &zNode = inequalityGraph->GetNode(0); bool upperResult = ABCD::DemandProve(aNode, *idxNode, kUpper); bool lowerResult = ABCD::DemandProve(zNode, *idxNode, kLower); - return upperResult && lowerResult; + return upperResult && lowerResult; } bool ABCD::DemandProve(ESSABaseNode &firstNode, ESSABaseNode &secondNode, EdgeType edgeType) { diff --git a/src/maple_me/src/me_loop_analysis.cpp b/src/maple_me/src/me_loop_analysis.cpp index 142151587c3991dedac934fc90b8afcafa0461d5..a53e34d57999b83c21f2c1cda595ef6e9e94139e 100644 --- a/src/maple_me/src/me_loop_analysis.cpp +++ b/src/maple_me/src/me_loop_analysis.cpp @@ -14,15 +14,15 @@ */ #include "me_loop_analysis.h" -// This phase analyses the CFG and identify the loops. The implementation is +// This phase analyses the CFG and identify the loops. The implementation is // based on the idea that, given two basic block a and b, if b is a's pred and -// a dominates b, then there is a loop from a to b. Loop identification is done -// in a preorder traversal of the dominator tree. In this order, outer loop is -// always detected before its nested loop(s). The building of the LoopDesc data +// a dominates b, then there is a loop from a to b. Loop identification is done +// in a preorder traversal of the dominator tree. In this order, outer loop is +// always detected before its nested loop(s). The building of the LoopDesc data // structure takes advantage of this ordering. namespace maple { LoopDesc *IdentifyLoops::CreateLoopDesc(BB &hd, BB &tail) { - LoopDesc *newLoop = meLoopMemPool->New(&meLoopAlloc, &hd, &tail); + LoopDesc *newLoop = meLoopMemPool->New(meLoopAlloc, &hd, &tail); meLoops.push_back(newLoop); return newLoop; } @@ -31,6 +31,7 @@ void IdentifyLoops::SetLoopParent4BB(const BB &bb, LoopDesc &loopDesc) { if (bbLoopParent[bb.GetBBId()] != nullptr) { if (loopDesc.parent == nullptr) { loopDesc.parent = bbLoopParent[bb.GetBBId()]; + ASSERT_NOT_NULL(loopDesc.parent); loopDesc.nestDepth = loopDesc.parent->nestDepth + 1; } } @@ -39,7 +40,7 @@ void IdentifyLoops::SetLoopParent4BB(const BB &bb, LoopDesc &loopDesc) { // process each BB in preorder traversal of dominator tree void IdentifyLoops::ProcessBB(BB *bb) { - if (bb == nullptr || bb == func->GetCommonExitBB()) { + if (bb == nullptr || bb == func.GetCommonExitBB()) { return; } for (BB *pred : bb->GetPred()) { @@ -68,17 +69,17 @@ void IdentifyLoops::ProcessBB(BB *bb) { // recursive call const MapleSet &domChildren = dominance->GetDomChildren(bb->GetBBId()); for (auto bbIt = domChildren.begin(); bbIt != domChildren.end(); ++bbIt) { - ProcessBB(func->GetAllBBs().at(*bbIt)); + ProcessBB(func.GetAllBBs().at(*bbIt)); } } void IdentifyLoops::Dump() const { - for (LoopDesc *mploop : meLoops) { + for (LoopDesc *meLoop : meLoops) { // loop - LogInfo::MapleLogger() << "nest depth: " << mploop->nestDepth << " loop head BB: " << mploop->head->GetBBId() - << " tail BB:" << mploop->tail->GetBBId() << '\n'; + LogInfo::MapleLogger() << "nest depth: " << meLoop->nestDepth << " loop head BB: " << meLoop->head->GetBBId() + << " tail BB:" << meLoop->tail->GetBBId() << '\n'; LogInfo::MapleLogger() << "loop body:"; - for (auto it = mploop->loopBBs.begin(); it != mploop->loopBBs.end(); ++it) { + for (auto it = meLoop->loopBBs.begin(); it != meLoop->loopBBs.end(); ++it) { BBId bbId = *it; LogInfo::MapleLogger() << bbId << " "; } @@ -87,12 +88,12 @@ void IdentifyLoops::Dump() const { } void IdentifyLoops::MarkBB() { - for (LoopDesc *mploop : meLoops) { - for (BBId bbId : mploop->loopBBs) { - if (func->GetAllBBs().at(bbId) == nullptr) { + for (LoopDesc *meLoop : meLoops) { + for (BBId bbId : meLoop->loopBBs) { + if (func.GetAllBBs().at(bbId) == nullptr) { continue; } - func->GetAllBBs().at(bbId)->SetAttributes(kBBAttrIsInLoopForEA); + func.GetAllBBs().at(bbId)->SetAttributes(kBBAttrIsInLoopForEA); } } } @@ -101,7 +102,7 @@ AnalysisResult *MeDoMeLoop::Run(MeFunction *func, MeFuncResultMgr *m, ModuleResu auto *dom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); ASSERT(dom != nullptr, "dominance phase has problem"); MemPool *meLoopMp = NewMemPool(); - IdentifyLoops *identLoops = meLoopMp->New(meLoopMp, func, dom); + IdentifyLoops *identLoops = meLoopMp->New(meLoopMp, *func, dom); identLoops->ProcessBB(func->GetCommonEntryBB()); if (DEBUGFUNC(func)) { identLoops->Dump(); diff --git a/src/maple_me/src/me_loop_canon.cpp b/src/maple_me/src/me_loop_canon.cpp index f90045b98b407d596e1b4b0a5ad6d5fcb840a1ff..108503e18b6d5921e8990c43fd20c7cb4b87de5d 100644 --- a/src/maple_me/src/me_loop_canon.cpp +++ b/src/maple_me/src/me_loop_canon.cpp @@ -135,19 +135,19 @@ void MeDoLoopCanon::Convert(MeFunction &func, BB &bb, BB &pred, MapleMap(pred.GetStmtNodes().back()); ASSERT(bb.GetBBLabel() != 0, "wrong bb label"); - LabelIdx oldlabIdx = bb.GetBBLabel(); + LabelIdx oldLabIdx = bb.GetBBLabel(); LabelIdx label = func.GetOrCreateBBLabel(*latchBB); - if (switchStmt.GetDefaultLabel() == oldlabIdx) { + if (switchStmt.GetDefaultLabel() == oldLabIdx) { switchStmt.SetDefaultLabel(label); } for (size_t i = 0; i < switchStmt.GetSwitchTable().size(); i++) { LabelIdx labelIdx = switchStmt.GetCasePair(i).second; - if (labelIdx == oldlabIdx) { + if (labelIdx == oldLabIdx) { switchStmt.UpdateCaseLabelAt(i, label); } } @@ -220,7 +220,7 @@ AnalysisResult *MeDoLoopCanon::Run(MeFunction *func, MeFuncResultMgr *m, ModuleR auto *bb = *bIt; MapleVector &preds = bb->GetPred(); for (BB *pred : preds) { - ASSERT(func->GetCommonEntryBB(), "impossible"); + ASSERT(func->GetCommonEntryBB() != nullptr, "impossible"); ASSERT_NOT_NULL(pred); // bb is reachable from entry && bb dominator pred if (dom->Dominate(*func->GetCommonEntryBB(), *bb) && dom->Dominate(*bb, *pred) && diff --git a/src/maple_me/src/me_lower_globals.cpp b/src/maple_me/src/me_lower_globals.cpp index 054c952df7a42520761bba3ce99d0f531927fb53..bf6c2d11fb2434bc98f6755c1465caaba4a75357 100644 --- a/src/maple_me/src/me_lower_globals.cpp +++ b/src/maple_me/src/me_lower_globals.cpp @@ -61,7 +61,7 @@ void MeLowerGlobals::LowerGlobalDreads(MeStmt &stmt, MeExpr &expr) { // lower to ivar to expose addrof OriginalSt *baseOst = ost; if (ost->GetFieldID() != 0) { - PUIdx puIdx = func->GetMirFunc()->GetPuidx(); + PUIdx puIdx = func.GetMirFunc()->GetPuidx(); baseOst = ssaTable->FindOrCreateSymbolOriginalSt(*ost->GetMIRSymbol(), puIdx, 0); } auto *addrofExpr = static_cast(irMap->CreateAddrofMeExpr(varExpr)); @@ -81,12 +81,13 @@ void MeLowerGlobals::LowerGlobalDreads(MeStmt &stmt, MeExpr &expr) { break; } // lower to iaddrof to expose addrof with 0 fieldID - PUIdx puIdx = func->GetMirFunc()->GetPuidx(); + PUIdx puIdx = func.GetMirFunc()->GetPuidx(); OriginalSt *baseOst = ssaTable->FindOrCreateSymbolOriginalSt(*ost->GetMIRSymbol(), - func->GetMirFunc()->GetPuidx(), 0); + func.GetMirFunc()->GetPuidx(), 0); MeExpr *newAddrofExpr = irMap->CreateAddrofMeExprFromSymbol(*ost->GetMIRSymbol(), puIdx); MIRPtrType ptrType(baseOst->GetTyIdx(), PTY_ptr); TyIdx addrTyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&ptrType); + ASSERT_NOT_NULL(irMap); MeExpr *iaddrofExpr = irMap->CreateIaddrofMeExpr(addrofExpr, addrTyIdx, *newAddrofExpr); (void)irMap->ReplaceMeExprStmt(stmt, addrofExpr, *iaddrofExpr); break; @@ -97,8 +98,8 @@ void MeLowerGlobals::LowerGlobalDreads(MeStmt &stmt, MeExpr &expr) { } void MeLowerGlobals::Run() { - auto eIt = func->valid_end(); - for (auto bIt = func->valid_begin(); bIt != eIt; ++bIt) { + auto eIt = func.valid_end(); + for (auto bIt = func.valid_begin(); bIt != eIt; ++bIt) { auto *bb = *bIt; for (auto &stmt : bb->GetMeStmts()) { for (size_t i = 0; i < stmt.NumMeStmtOpnds(); ++i) { @@ -114,7 +115,7 @@ void MeLowerGlobals::Run() { OriginalSt *baseOst = ost; if (ost->GetFieldID() != 0) { baseOst = ssaTable->FindOrCreateSymbolOriginalSt(*ost->GetMIRSymbol(), - func->GetMirFunc()->GetPuidx(), 0); + func.GetMirFunc()->GetPuidx(), 0); } MeExpr *addrof = irMap->CreateAddrofMeExpr(baseOst->GetIndex()); MIRPtrType ptrType(baseOst->GetTyIdx(), PTY_ptr); @@ -122,7 +123,7 @@ void MeLowerGlobals::Run() { MeExpr *lhs = dass.GetLHS(); CHECK_NULL_FATAL(lhs); auto *lhsIvar = static_cast(irMap->CreateIvarMeExpr(*lhs, addrTyIdx, *addrof)); - IassignMeStmt *iass = irMap->NewInPool(addrTyIdx, lhsIvar, dass.GetRHS(), &*dass.GetChiList()); + IassignMeStmt *iass = irMap->NewInPool(addrTyIdx, lhsIvar, dass.GetRHS(), &*dass.GetChiList()); iass->SetBB(bb); iass->SetSrcPos(dass.GetSrcPosition()); iass->SetIsLive(true); diff --git a/src/maple_me/src/me_may2dassign.cpp b/src/maple_me/src/me_may2dassign.cpp index 4fbe780dd6eb30722f262b382032aa60f4e0ff84..2e0018d6ada5b5405a2e771ab091fb5f429535b5 100644 --- a/src/maple_me/src/me_may2dassign.cpp +++ b/src/maple_me/src/me_may2dassign.cpp @@ -17,8 +17,8 @@ // this phase converts all maydassign back to dassign namespace maple { void May2Dassign::DoIt() { - auto eIt = func->valid_end(); - for (auto bIt = func->valid_begin(); bIt != eIt; ++bIt) { + auto eIt = func.valid_end(); + for (auto bIt = func.valid_begin(); bIt != eIt; ++bIt) { auto *bb = *bIt; for (auto &stmt : bb->GetMeStmts()) { if (stmt.GetOp() != OP_maydassign) { @@ -27,10 +27,10 @@ void May2Dassign::DoIt() { auto &mass = static_cast(stmt); // chiList for Maydassign has only 1 element CHECK_FATAL(!mass.GetChiList()->empty(), "chiList is empty in DoIt"); - VarMeExpr *thelhs = mass.GetChiList()->begin()->second->GetLHS(); - ASSERT(mass.GetMayDassignSym() == ssaTab->GetOriginalStFromID(thelhs->GetOStIdx()), + VarMeExpr *theLhs = mass.GetChiList()->begin()->second->GetLHS(); + ASSERT(mass.GetMayDassignSym() == ssaTab->GetOriginalStFromID(theLhs->GetOStIdx()), "MeDoMay2Dassign: cannot find maydassign lhs"); - auto *dass = static_cast(irMap->CreateDassignMeStmt(*thelhs, *mass.GetRHS(), *bb)); + auto *dass = static_cast(irMap->CreateDassignMeStmt(*theLhs, *mass.GetRHS(), *bb)); dass->SetNeedDecref(mass.NeedDecref()); dass->SetNeedIncref(mass.NeedIncref()); dass->SetWasMayDassign(true); @@ -42,8 +42,8 @@ void May2Dassign::DoIt() { } AnalysisResult *MeDoMay2Dassign::Run(MeFunction *func, MeFuncResultMgr*, ModuleResultMgr*) { - May2Dassign may2dassign(func); - may2dassign.DoIt(); + May2Dassign may2Dassign(*func); + may2Dassign.DoIt(); return nullptr; } } // namespace maple diff --git a/src/maple_me/src/me_phase_manager.cpp b/src/maple_me/src/me_phase_manager.cpp index f509126fa0954bca95f5f4b6c8642d566f82ea29..2b3131ef801feed58c0916e69a6204418498da54 100644 --- a/src/maple_me/src/me_phase_manager.cpp +++ b/src/maple_me/src/me_phase_manager.cpp @@ -22,6 +22,8 @@ #include "me_alias_class.h" #include "me_bypath_eh.h" #include "me_critical_edge.h" +#include "me_profile_gen.h" +#include "me_profile_use.h" #include "me_loop_canon.h" #include "me_abco.h" #include "me_dse.h" @@ -65,6 +67,7 @@ void MeFuncPhaseManager::RunFuncPhase(MeFunction *func, MeFuncPhase *phase) { if ((func->NumBBs() > 0) || (phaseID == MeFuncPhase_EMIT)) { analysisRes = phase->Run(func, &arFuncManager, modResMgr); phase->ReleaseMemPool(analysisRes == nullptr ? nullptr : analysisRes->GetMempool()); + phase->ClearString(); } if (analysisRes != nullptr) { // if phase is an analysis Phase, add result to arm diff --git a/src/maple_me/src/me_profile_gen.cpp b/src/maple_me/src/me_profile_gen.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7982e911c6ea322a1068daac1a9082f96dc45522 --- /dev/null +++ b/src/maple_me/src/me_profile_gen.cpp @@ -0,0 +1,129 @@ +/* + * 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. + */ +#include "me_profile_gen.h" +#include +#include "me_cfg.h" +#include "me_option.h" +#include "me_function.h" +#include "me_irmap.h" +#include "mir_builder.h" + +/* + * This phase do CFG edge profile using a minimum spanning tree based + * on the following paper: + * [1] Donald E. Knuth, Francis R. Stevenson. Optimal measurement of points + * FOR program frequency counts. BIT Numerical Mathematics 1973, Volume 13, + * Issue 3, pp 313-322 + * The count of edge on spanning tree can be derived from + * those edges not on the spanning tree. Knuth proves this method instruments + * the minimum number of edges. + */ + +namespace maple { +uint64 MeProfGen::counterIdx = 0; +uint64 MeProfGen::totalBB = 0; +uint64 MeProfGen::instrumentBB = 0; +bool MeProfGen::firstRun = true; +MIRSymbol *MeProfGen::bbCounterTabSym = nullptr; + +void MeProfGen::Init() { + if (!firstRun) { + return; + } + MIRArrayType &muidIdxArrayType = + *GlobalTables::GetTypeTable().GetOrCreateArrayType(*GlobalTables::GetTypeTable().GetUInt32(), 0); + std::string bbProfileName = NameMangler::kBBProfileTabPrefixStr + func->GetMIRModule().GetFileNameAsPostfix(); + bbCounterTabSym = func->GetMIRModule().GetMIRBuilder()->CreateGlobalDecl(bbProfileName.c_str(), muidIdxArrayType); + MIRAggConst *bbProfileTab = func->GetMIRModule().GetMemPool()->New( + func->GetMIRModule(), *GlobalTables::GetTypeTable().GetUInt32()); + bbCounterTabSym->SetKonst(bbProfileTab); + bbCounterTabSym->SetStorageClass(kScFstatic); + firstRun = false; +} + +void MeProfGen::InstrumentBB(BB &bb) { + /* append intrinsic call at the begin of bb */ + CHECK_FATAL(counterIdx != (UINT32_MAX / GetPrimTypeSize(PTY_u32)), "profile counter overflow"); + MeExpr *arg0 = hMap->CreateIntConstMeExpr(counterIdx, PTY_u32); + std::vector opnds = { arg0 }; + IntrinsiccallMeStmt *counterIncCall = hMap->CreateIntrinsicCallMeStmt(INTRN_MPL_PROF_COUNTER_INC, opnds); + bb.AddMeStmtFirst(counterIncCall); + bb.SetAttributes(kBBAttrIsInstrument); + counterIdx++; + if (dump) { + LogInfo::MapleLogger() << "instrument on BB" << bb.GetBBId() << "\n"; + } +} + +void MeProfGen::SaveProfile() { + if (!Options::testCase) { + return; + } + if (func->GetName().find("main") != std::string::npos) { + std::vector opnds; + IntrinsiccallMeStmt *saveProfCall = hMap->CreateIntrinsicCallMeStmt(INTRN_MCCSaveProf, opnds); + for (BB *exitBB : func->GetCommonExitBB()->GetPred()) { + exitBB->AddMeStmtFirst(saveProfCall); + } + } +} + +void MeProfGen::InstrumentFunc() { + FindInstrumentEdges(); + std::vector instrumentBBs; + GetInstrumentBBs(instrumentBBs); + // record the current counter start, used in the function profile description + uint32 counterStart = counterIdx; + MIRAggConst *bbProfileTab = safe_cast(bbCounterTabSym->GetKonst()); + for (auto *bb : instrumentBBs) { + MIRIntConst *indexConst = + func->GetMIRModule().GetMemPool()->New(0, *GlobalTables::GetTypeTable().GetUInt32()); + bbProfileTab->PushBack(indexConst); + InstrumentBB(*bb); + } + + uint32 counterEnd = counterIdx - 1; + uint64 hash = ComputeFuncHash(); + func->AddProfileDesc(hash, counterStart, counterEnd); + instrumentBB += instrumentBBs.size(); + totalBB += GetAllBBs(); + SaveProfile(); + if (dump) { + LogInfo::MapleLogger() << "******************after profile gen dump function******************\n"; + func->Dump(true); + } + if (Options::testCase || dump) { + LogInfo::MapleLogger() << func->GetName() << " profile description info: " + << "func hash " << std::hex << hash << std::dec << " counter range [" + << counterStart << "," << counterEnd << "]\n"; + } +} + +AnalysisResult *MeDoProfGen::Run(MeFunction *func, MeFuncResultMgr *m, ModuleResultMgr*) { + MemPool *tempMp = NewMemPool(); + auto *hMap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAP, func)); + CHECK_FATAL(hMap != nullptr, "hssamap is nullptr"); + MeProfGen profGen(*func, *tempMp, *hMap, DEBUGFUNC(func)); + profGen.InstrumentFunc(); + + if (DEBUGFUNC(func)) { + LogInfo::MapleLogger() << "dump edge info in profile gen phase " << func->GetMirFunc()->GetName() << std::endl; + func->GetTheCfg()->DumpToFile("afterProfileGen", false); + profGen.DumpEdgeInfo(); + } + + return nullptr; +} +} // namespace maple diff --git a/src/maple_me/src/me_profile_use.cpp b/src/maple_me/src/me_profile_use.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4ff41048d805056c18c3409faf51dfd1ce60f618 --- /dev/null +++ b/src/maple_me/src/me_profile_use.cpp @@ -0,0 +1,280 @@ +/* + * 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. + */ +#include "me_profile_use.h" +#include +#include "me_cfg.h" +#include "me_option.h" +#include "me_function.h" + +namespace maple { +BBUseInfo *MeProfUse::GetOrCreateBBUseInfo(const BB &bb) { + auto item = bbProfileInfo.find(&bb); + if (item != bbProfileInfo.end()) { + return item->second; + } else { + BBUseInfo *useInfo = mp->New(); + bbProfileInfo.insert(std::make_pair(&bb, useInfo)); + return useInfo; + } +} + +BBUseInfo *MeProfUse::GetBBUseInfo(const BB &bb) const { + auto item = bbProfileInfo.find(&bb); + ASSERT(item->second != nullptr, "bb info not created"); + return item->second; +} + +uint64 MeProfUse::SumEdgesCount(const std::vector &edges) const { + uint64 count = 0; + for (const auto &e : edges) { + count += e->GetCount(); + } + return count; +} + +/* create BB use info */ +void MeProfUse::InitBBEdgeInfo() { + for (auto &e : GetAllEdges()) { + BB *src = e->GetSrcBB(); + BB *dest = e->GetDestBB(); + auto srcUseInfo = GetOrCreateBBUseInfo(*src); + srcUseInfo->AddOutEdge(e); + auto destUseInfo = GetOrCreateBBUseInfo(*dest); + destUseInfo->AddInEdge(e); + } + for (auto &e : GetAllEdges()) { + if (e->IsInMST()) { + continue; + } + BB *src = e->GetSrcBB(); + auto srcUseInfo = GetBBUseInfo(*src); + if (srcUseInfo->GetStatus() && srcUseInfo->GetOutEdgeSize() == 1) { + SetEdgeCount(*e, srcUseInfo->GetCount()); + } else { + BB *dest = e->GetDestBB(); + auto destUseInfo = GetBBUseInfo(*dest); + if (destUseInfo->GetStatus() && destUseInfo->GetInEdgeSize() == 1) { + SetEdgeCount(*e, destUseInfo->GetCount()); + } + } + if (e->GetStatus()) { + continue; + } + SetEdgeCount(*e, 0); + } +} + +// If all input edges or output edges determined, caculate BB freq +void MeProfUse::ComputeBBFreq(BBUseInfo &bbInfo, bool &change) { + uint64 count = 0; + if (!bbInfo.GetStatus()) { + if (bbInfo.GetUnknownOutEdges() == 0) { + count = SumEdgesCount(bbInfo.GetOutEdges()); + bbInfo.SetCount(count); + change = true; + } else if (bbInfo.GetUnknownInEdges() == 0) { + count = SumEdgesCount(bbInfo.GetInEdges()); + bbInfo.SetCount(count); + change = true; + } + } +} + +/* compute all edge freq in the cfg without consider exception */ +void MeProfUse::ComputeEdgeFreq() { + bool change = true; + size_t pass = 0; + auto eIt = func->valid_end(); + while (change) { + change = false; + pass++; + CHECK_FATAL(pass != UINT8_MAX, "parse all edges fail"); + /* + * use the bb edge to infer the bb's count,when all bb's count is valid + * then all edges count is valid + */ + for (auto bIt = func->valid_begin(); bIt != eIt; ++bIt) { + auto *bb = *bIt; + BBUseInfo *useInfo = GetBBUseInfo(*bb); + if (useInfo == nullptr) { + continue; + } + ComputeBBFreq(*useInfo, change); + if (useInfo->GetStatus()) { + if (useInfo->GetUnknownOutEdges() == 1) { + uint64 total = 0; + uint64 outCount = SumEdgesCount(useInfo->GetOutEdges()); + if (useInfo->GetCount() > outCount) { + total = useInfo->GetCount() - outCount; + } + SetEdgeCount(useInfo->GetOutEdges(), total); + change = true; + } + if (useInfo->GetUnknownInEdges() == 1) { + uint64 total = 0; + uint64 inCount = SumEdgesCount(useInfo->GetInEdges()); + if (useInfo->GetCount() > inCount) { + total = useInfo->GetCount() - inCount; + } + SetEdgeCount(useInfo->GetInEdges(), total); + change = true; + } + } + } + } + if (dump) { + LogInfo::MapleLogger() << "parse all edges in " << pass << " pass" << '\n'; + } +} + +/* + * this used to set the edge count for the unknown edge + * ensure only one unkown edge in the edges + */ +void MeProfUse::SetEdgeCount(std::vector &edges, uint64 value) { + for (const auto &e : edges) { + if (!e->GetStatus()) { + e->SetCount(value); + BBUseInfo *srcInfo = GetBBUseInfo(*(e->GetSrcBB())); + BBUseInfo *destInfo = GetBBUseInfo(*(e->GetDestBB())); + srcInfo->DecreaseUnKnownOutEdges(); + destInfo->DecreaseUnKnownInEdges(); + return; + } + } + CHECK(false, "can't find unkown edge"); +} + +void MeProfUse::SetEdgeCount(BBUseEdge &e, uint32 value) { + // edge counter already valid skip + if (e.GetStatus()) { + return; + } + e.SetCount(value); + BBUseInfo *srcInfo = GetBBUseInfo(*(e.GetSrcBB())); + BBUseInfo *destInfo = GetBBUseInfo(*(e.GetDestBB())); + srcInfo->DecreaseUnKnownOutEdges(); + destInfo->DecreaseUnKnownInEdges(); + return; +} + +bool MeProfUse::BuildEdgeCount() { + Profile::BBInfo result; + bool ret = true; + ret = func->GetMIRModule().GetProfile().GetFunctionBBProf(func->GetName(), result); + if (!ret) { + if (dump) { + LogInfo::MapleLogger() << func->GetName() << " isn't in profile" << '\n'; + } + return false; + } + FindInstrumentEdges(); + uint64 hash = ComputeFuncHash(); + if (hash != result.funcHash) { + if (dump) { + LogInfo::MapleLogger() << func->GetName() << " hash doesn't match profile hash " + << result.funcHash << " func real hash " << hash << '\n'; + } + return false; + } + std::vector instrumentBBs; + GetInstrumentBBs(instrumentBBs); + if (dump) { + DumpEdgeInfo(); + } + if (instrumentBBs.size() != result.totalCounter) { + if (dump) { + LogInfo::MapleLogger() << func->GetName() << " counter doesn't match profile counter " + << result.totalCounter << " func real counter " << instrumentBBs.size() << '\n'; + } + return false; + } + size_t i = 0; + for (auto *bb : instrumentBBs) { + auto *bbUseInfo = GetOrCreateBBUseInfo(*bb); + bbUseInfo->SetCount(result.counter[i]); + i++; + } + + InitBBEdgeInfo(); + ComputeEdgeFreq(); + succCalcuAllEdgeFreq = true; + if (Options::testCase) { + LogInfo::MapleLogger() << func->GetName() << " succ compute all edges " << '\n'; + } + return true; +} + +void MeProfUse::SetFuncEdgeInfo() { + auto eIt = func->valid_end(); + for (auto bIt = func->valid_begin(); bIt != eIt; ++bIt) { + if (bIt == func->common_entry() || bIt == func->common_exit()) { + continue; + } + auto *bb = *bIt; + auto *bbInfo = GetBBUseInfo(*bb); + bb->SetFrequency(bbInfo->GetCount()); + auto outEdges = bbInfo->GetOutEdges(); + for (auto *e : outEdges) { + auto *destBB = e->GetDestBB(); + // common_exit's pred's BB doesn't have succ BB of common exit + // so skip this edge + if (destBB == func->GetCommonExitBB()) { + continue; + } + bb->SetEdgeFreq(destBB, e->GetCount()); + } + } +} + +void MeProfUse::DumpFuncCFGEdgeFreq() const { + LogInfo::MapleLogger() << "populate status " << succCalcuAllEdgeFreq << "\n"; + if (!succCalcuAllEdgeFreq) { + return; + } + auto eIt = func->valid_end(); + for (auto bIt = func->valid_begin(); bIt != eIt; ++bIt) { + if (bIt == func->common_entry() || bIt == func->common_exit()) { + continue; + } + auto bb = *bIt; + LogInfo::MapleLogger() << bb->GetBBId() << " freq " << bb->GetFrequency() << '\n'; + for (const auto *succBB : bb->GetSucc()) { + LogInfo::MapleLogger() << "edge " << bb->GetBBId() << "->" << succBB->GetBBId() << " freq " + << bb->GetEdgeFreq(succBB) << '\n'; + } + } +} + +bool MeProfUse::Run() { + if (!BuildEdgeCount()) { + return false; + } + SetFuncEdgeInfo(); + return true; +} + +AnalysisResult *MeDoProfUse::Run(MeFunction *func, MeFuncResultMgr *m, ModuleResultMgr*) { + MemPool *tempMp = NewMemPool(); + MeProfUse profUse(*func, *tempMp, DEBUGFUNC(func)); + profUse.Run(); + if (DEBUGFUNC(func) && profUse.IsSuccUseProf()) { + LogInfo::MapleLogger() << "******************after profile use dump function******************\n"; + profUse.DumpFuncCFGEdgeFreq(); + func->GetTheCfg()->DumpToFile("afterProfileUse", false, true); + } + return nullptr; +} +} // namespace maple diff --git a/src/maple_me/src/me_rename2preg.cpp b/src/maple_me/src/me_rename2preg.cpp index f73cfa62fb4db0b9f8ffe06fa898b99b84e8cf17..2bd0dd2d450b92c88b7d0c76ef33f4bcbd8c220c 100644 --- a/src/maple_me/src/me_rename2preg.cpp +++ b/src/maple_me/src/me_rename2preg.cpp @@ -31,14 +31,14 @@ using namespace maple; template struct ExtractPhaseClass {}; template <> struct ExtractPhaseClass { - using type = MeIRMap; + using Type = MeIRMap; }; template <> struct ExtractPhaseClass { - using type = AliasClass; + using Type = AliasClass; }; -template ::type>> +template ::Type>> inline RetT GetAnalysisResult(MeFunction &func, MeFuncResultMgr &funcRst) { return static_cast(funcRst.GetAnalysisResult(id, &func)); } @@ -308,11 +308,11 @@ class SSARename2Preg { if (regExpr != nullptr) { MeExpr *oldRhs = nullptr; if (instance_of(stmt)) { - auto *dAStmt = static_cast(&stmt); - oldRhs = dAStmt->GetRHS(); + auto *dassStmt = static_cast(&stmt); + oldRhs = dassStmt->GetRHS(); } else if (instance_of(stmt)) { - auto *mayDAStmt = static_cast(&stmt); - oldRhs = mayDAStmt->GetRHS(); + auto *mayDassStmt = static_cast(&stmt); + oldRhs = mayDassStmt->GetRHS(); } else { CHECK_FATAL(false, "NYI"); } @@ -415,7 +415,6 @@ class SSARename2Preg { CacheProxy cacheProxy; FormalRenaming formal; }; - } namespace maple { @@ -431,6 +430,5 @@ AnalysisResult *MeDoSSARename2Preg::Run(MeFunction *func, MeFuncResultMgr *funcR std::string MeDoSSARename2Preg::PhaseName() const { return SSARename2Preg::PhaseName(); } - } // namespace maple diff --git a/src/maple_me/src/me_ssa_lpre.cpp b/src/maple_me/src/me_ssa_lpre.cpp index debd6e597342722fab24ec0ace8f67c2e6d04d68..71eae551432b9261cebcadf69ab1c837093ae7a4 100644 --- a/src/maple_me/src/me_ssa_lpre.cpp +++ b/src/maple_me/src/me_ssa_lpre.cpp @@ -384,7 +384,7 @@ AnalysisResult *MeDoSSALPre::Run(MeFunction *irFunc, MeFuncResultMgr *funcMgr, M irFunc->Dump(false); } } - MeLowerGlobals lowerGlobals(irFunc, irFunc->GetMeSSATab()); + MeLowerGlobals lowerGlobals(*irFunc, irFunc->GetMeSSATab()); lowerGlobals.Run(); { MeSSALPre ssaLpre(*irFunc, *irMap, *dom, *NewMemPool(), *NewMemPool(), kAddrPre, lpreLimitUsed); diff --git a/src/maple_me/src/me_ssu_pre.cpp b/src/maple_me/src/me_ssu_pre.cpp index 2e2124f183b7adbe41462bc841f232608a424d8d..0224f7272aadbccfa2d06dd1ffb38e2b333e5637 100644 --- a/src/maple_me/src/me_ssu_pre.cpp +++ b/src/maple_me/src/me_ssu_pre.cpp @@ -49,16 +49,17 @@ void MeSSUPre::Finalize() { lambdaResOcc->GetUse()->GetOccTy() == kSOccLambda && !static_cast(lambdaResOcc->GetUse())->WillBeAnt())) { // insert a store - BB *insertBB = lambdaResOcc->GetBB(); + BB *insertBB = &lambdaResOcc->GetBB(); if (insertBB->GetAttributes(kBBAttrIsCatch)) { if (preKind == kDecrefPre) { catchBlocks2Insert.insert(insertBB->GetBBId()); } // else { kStorePre: omit insertion at entry of catch blocks } break; } - if (lambdaResOcc->GetBB()->GetPred().size() != 1) { // critical edge + if (lambdaResOcc->GetBB().GetPred().size() != 1) { // critical edge if (preKind != kDecrefPre && preKind != kSecondDecrefPre) { CHECK_FATAL(false, "MeSSUPre::Finalize: insertion at critical edge"); + ASSERT_NOT_NULL(workCand); workCand->SetHasCriticalEdge(true); return; } @@ -287,7 +288,7 @@ void MeSSUPre::Rename() { continue; } CHECK_NULL_FATAL(dom); - if (!dom->Dominate(*realOcc->GetBB(), *topOcc->GetBB())) { + if (!dom->Dominate(realOcc->GetBB(), topOcc->GetBB())) { continue; } static_cast(topOcc)->SetIsUpsafe(false); @@ -383,14 +384,14 @@ void MeSSUPre::FormLambdas() { std::vector visitedMap(func->NumBBs(), false); CHECK_NULL_FATAL(workCand); for (SOcc *occ : workCand->GetRealOccs()) { - GetIterPdomFrontier(*occ->GetBB(), lambdaDfns, visitedMap); + GetIterPdomFrontier(occ->GetBB(), lambdaDfns, visitedMap); } } // form allOccs inclusive of real, use, lambda, lambdaRes, entry occurrences; // form lambdaOccs containing only the lambdas void MeSSUPre::CreateSortedOccs() { - // form lambdaRes occs based on the succs of the lambda occs ; result is + // form lambdaRes occs based on the succs of the lambda occs; result is // stored in lambdaResDfns std::multiset lambdaResDfns; for (uint32 dfn : lambdaDfns) { @@ -402,7 +403,7 @@ void MeSSUPre::CreateSortedOccs() { } allOccs.clear(); lambdaOccs.clear(); - std::unordered_map> bb2lambdaResMap; + std::unordered_map> bb2LambdaResMap; auto realOccIt = workCand->GetRealOccs().begin(); auto entryOccIt = entryOccs.begin(); auto lambdaDfnIt = lambdaDfns.begin(); @@ -423,10 +424,10 @@ void MeSSUPre::CreateSortedOccs() { SLambdaResOcc *nextLambdaResOcc = nullptr; if (lambdaResDfnIt != lambdaResDfns.end()) { nextLambdaResOcc = spreMp->New(*func->GetAllBBs().at(dom->GetPdtPreOrderItem(*lambdaResDfnIt))); - auto it = bb2lambdaResMap.find(dom->GetPdtPreOrderItem(*lambdaResDfnIt)); - if (it == bb2lambdaResMap.end()) { + auto it = bb2LambdaResMap.find(dom->GetPdtPreOrderItem(*lambdaResDfnIt)); + if (it == bb2LambdaResMap.end()) { std::forward_list newlist = { nextLambdaResOcc }; - bb2lambdaResMap[dom->GetPdtPreOrderItem(*lambdaResDfnIt)] = newlist; + bb2LambdaResMap[dom->GetPdtPreOrderItem(*lambdaResDfnIt)] = newlist; } else { it->second.push_front(nextLambdaResOcc); } @@ -437,16 +438,16 @@ void MeSSUPre::CreateSortedOccs() { if (nextLambdaOcc != nullptr) { pickedOcc = nextLambdaOcc; } - if (nextRealOcc != nullptr && (pickedOcc == nullptr || dom->GetPdtDfnItem(nextRealOcc->GetBB()->GetBBId()) < - dom->GetPdtDfnItem(pickedOcc->GetBB()->GetBBId()))) { + if (nextRealOcc != nullptr && (pickedOcc == nullptr || dom->GetPdtDfnItem(nextRealOcc->GetBB().GetBBId()) < + dom->GetPdtDfnItem(pickedOcc->GetBB().GetBBId()))) { pickedOcc = nextRealOcc; } if (nextLambdaResOcc != nullptr && - (pickedOcc == nullptr || *lambdaResDfnIt < dom->GetPdtDfnItem(pickedOcc->GetBB()->GetBBId()))) { + (pickedOcc == nullptr || *lambdaResDfnIt < dom->GetPdtDfnItem(pickedOcc->GetBB().GetBBId()))) { pickedOcc = nextLambdaResOcc; } - if (nextEntryOcc != nullptr && (pickedOcc == nullptr || dom->GetPdtDfnItem(nextEntryOcc->GetBB()->GetBBId()) < - dom->GetPdtDfnItem(pickedOcc->GetBB()->GetBBId()))) { + if (nextEntryOcc != nullptr && (pickedOcc == nullptr || dom->GetPdtDfnItem(nextEntryOcc->GetBB().GetBBId()) < + dom->GetPdtDfnItem(pickedOcc->GetBB().GetBBId()))) { pickedOcc = nextEntryOcc; } if (pickedOcc != nullptr) { @@ -491,10 +492,10 @@ void MeSSUPre::CreateSortedOccs() { nextLambdaResOcc = spreMp->New(*func->GetAllBBs().at(dom->GetPdtPreOrderItem(*lambdaResDfnIt))); CHECK_NULL_FATAL(dom); - auto it = bb2lambdaResMap.find(dom->GetPdtPreOrderItem(*lambdaResDfnIt)); - if (it == bb2lambdaResMap.end()) { + auto it = bb2LambdaResMap.find(dom->GetPdtPreOrderItem(*lambdaResDfnIt)); + if (it == bb2LambdaResMap.end()) { std::forward_list newlist = { nextLambdaResOcc }; - bb2lambdaResMap[dom->GetPdtPreOrderItem(*lambdaResDfnIt)] = newlist; + bb2LambdaResMap[dom->GetPdtPreOrderItem(*lambdaResDfnIt)] = newlist; } else { it->second.push_front(nextLambdaResOcc); } @@ -510,11 +511,11 @@ void MeSSUPre::CreateSortedOccs() { } while (pickedOcc != nullptr); // initialize lambdaRes vector in each SLambdaOcc node for (SLambdaOcc *lambdaOcc : lambdaOccs) { - for (BB *succ : lambdaOcc->GetBB()->GetSucc()) { - SLambdaResOcc *lambdaResOcc = bb2lambdaResMap[succ->GetBBId()].front(); + for (BB *succ : lambdaOcc->GetBB().GetSucc()) { + SLambdaResOcc *lambdaResOcc = bb2LambdaResMap[succ->GetBBId()].front(); lambdaOcc->GetLambdaRes().push_back(lambdaResOcc); lambdaResOcc->SetUseLambdaOcc(*lambdaOcc); - bb2lambdaResMap[succ->GetBBId()].pop_front(); + bb2LambdaResMap[succ->GetBBId()].pop_front(); } } if (enabledDebug) { diff --git a/src/maple_me/src/me_stmt_pre.cpp b/src/maple_me/src/me_stmt_pre.cpp index 286526aa3a9e62392da6217c2642d8ca93354953..906013290ef24b15e2e1c4594443140ee2729c8a 100644 --- a/src/maple_me/src/me_stmt_pre.cpp +++ b/src/maple_me/src/me_stmt_pre.cpp @@ -97,6 +97,7 @@ void MeStmtPre::CodeMotion() { if (call->GetAssignedLHS() != nullptr) { CHECK_FATAL(call->GetAssignedLHS()->GetMeOp() == kMeOpVar, "should be var"); auto *var = static_cast(call->GetAssignedLHS()); + ASSERT_NOT_NULL(var); OStIdx ostIdx = var->GetOStIdx(); if (candsForSSAUpdate.find(ostIdx) == candsForSSAUpdate.end()) { MapleSet *bbSet = @@ -684,7 +685,7 @@ void MeStmtPre::CreateSortedOccs() { if (!realOccInserted) { workCand->GetRealOccs().clear(); } - // initialize phiOpnds vector in each MePhiOcc node and defPhiOcc field in + // initialize phiOpnds vector in each MePhiOcc node and defPhiOcc field in // each MePhiOpndOcc node for (MePhiOcc *phiOcc : phiOccs) for (BB *pred : phiOcc->GetBB()->GetPred()) { @@ -944,7 +945,7 @@ void MeStmtPre::BuildWorkListBB(BB *bb) { if (NoPriorUseInBB(dassMeStmt.GetVarLHS(), &stmt)) { (void)CreateStmtRealOcc(stmt, seqStmt); } - } else if (dassMeStmt.GetLHS()->IsUseSameSymbol(*dassMeStmt.GetRHS())) { + } else if (dassMeStmt.GetLHS() != nullptr && dassMeStmt.GetLHS()->IsUseSameSymbol(*dassMeStmt.GetRHS())) { RemoveUnnecessaryDassign(dassMeStmt); } // update version stacks @@ -1061,7 +1062,7 @@ AnalysisResult *MeDoStmtPre::Run(MeFunction *func, MeFuncResultMgr *m, ModuleRes ASSERT(dom != nullptr, "dominance phase has problem"); auto *irMap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAP, func)); ASSERT(irMap != nullptr, "irMap phase has problem"); - MeStmtPre ssaPre(func, *irMap, *dom, *NewMemPool(), *NewMemPool(), MeOption::stmtprePULimit); + MeStmtPre ssaPre(*func, *irMap, *dom, *NewMemPool(), *NewMemPool(), MeOption::stmtprePULimit); if (DEBUGFUNC(func)) { ssaPre.SetSSAPreDebug(true); } diff --git a/src/maple_me/src/me_store_pre.cpp b/src/maple_me/src/me_store_pre.cpp index 72cb2091e692d9c759683c91f95ecdd0d1121ee2..fc0dbc693d19ddffed9e4da4def5f4f0412fe50d 100644 --- a/src/maple_me/src/me_store_pre.cpp +++ b/src/maple_me/src/me_store_pre.cpp @@ -20,6 +20,7 @@ void MeStorePre::CheckCreateCurTemp() { if (curTemp != nullptr) { return; } + ASSERT_NOT_NULL(irMap); // try to use the same preg that LPRE used for the variable auto mapIt = irMap->FindLpreTmpsItem(workCand->GetOst()->GetIndex()); if (mapIt == irMap->GetLpreTmpsEnd()) { @@ -54,6 +55,7 @@ RegMeExpr *MeStorePre::EnsureRHSInCurTemp(BB &bb) { if (enabledDebug) { LogInfo::MapleLogger() << "EnsureRHSInCurTemp: found dassign at BB" << bb.GetBBId() << '\n'; } + ASSERT_NOT_NULL(curTemp); if (dass->GetRHS()->GetMeOp() == kMeOpReg && static_cast(dass->GetRHS())->GetOstIdx() == curTemp->GetOstIdx()) { return static_cast(dass->GetRHS()); @@ -140,7 +142,7 @@ void MeStorePre::CodeMotion() { // form the lhs VarMeExpr node VarMeExpr *lhsVar = irMap->CreateVarMeExprVersion(*workCand->GetTheVar()); // create a new dassign - BB *insertBB = lambdaResOcc->GetBB(); + BB *insertBB = &lambdaResOcc->GetBB(); CheckCreateCurTemp(); CHECK_FATAL(insertBB->GetPred().size() == 1, "CodeMotion: encountered critical edge"); RegMeExpr *rhsReg = EnsureRHSInCurTemp(*insertBB->GetPred(0)); @@ -161,6 +163,7 @@ void MeStorePre::CodeMotion() { } } // pass 2 only doing deletion + ASSERT_NOT_NULL(workCand); for (SOcc *occ : workCand->GetRealOccs()) { if (occ->GetOccTy() != kSOccReal) { continue; @@ -175,9 +178,9 @@ void MeStorePre::CodeMotion() { evalStmt->SetBB(dass->GetBB()); evalStmt->SetSrcPos(dass->GetSrcPosition()); evalStmt->SetMeStmtOpndValue(dass->GetRHS()); - realOcc->GetBB()->InsertMeStmtBefore(dass, evalStmt); + realOcc->GetBB().InsertMeStmtBefore(dass, evalStmt); } - realOcc->GetBB()->RemoveMeStmt(dass); + realOcc->GetBB().RemoveMeStmt(dass); } else { CHECK_FATAL(kOpcodeInfo.IsCallAssigned(realOcc->GetStmt()->GetOp()), "CodeMotion: callassign expected"); MapleVector *mustDefList = realOcc->GetStmt()->GetMustDefList(); @@ -201,8 +204,7 @@ void MeStorePre::CreateRealOcc(OStIdx ostIdx, MeStmt &meStmt) { workCandMap[ostIdx] = wkCand; // if it is local symbol, insert artificial real occ at common_exit_bb if (ost->IsLocal()) { - SRealOcc *artOcc = spreMp->New(); - artOcc->SetBB(*func->GetCommonExitBB()); + SRealOcc *artOcc = spreMp->New(*func->GetCommonExitBB()); wkCand->GetRealOccs().push_back(artOcc); } } @@ -224,19 +226,19 @@ void MeStorePre::CreateRealOcc(OStIdx ostIdx, MeStmt &meStmt) { // create a new use occurrence for symbol oidx in given bb void MeStorePre::CreateUseOcc(OStIdx ostIdx, BB &bb) const { - SpreWorkCand *wkcand = nullptr; + SpreWorkCand *wkCand = nullptr; auto mapIt = workCandMap.find(ostIdx); if (mapIt == workCandMap.end()) { return; } - wkcand = mapIt->second; - CHECK_FATAL(!wkcand->GetRealOccs().empty(), "empty container check"); - SOcc *lastOcc = wkcand->GetRealOccs().back(); - if (lastOcc->GetOccTy() == kSOccUse && lastOcc->GetBB() == &bb) { + wkCand = mapIt->second; + CHECK_FATAL(!wkCand->GetRealOccs().empty(), "empty container check"); + SOcc *lastOcc = wkCand->GetRealOccs().back(); + if (lastOcc->GetOccTy() == kSOccUse && &lastOcc->GetBB() == &bb) { return; // no need to push consecutive use occurrences at same BB } SUseOcc *newOcc = spreMp->New(bb); - wkcand->GetRealOccs().push_back(newOcc); + wkCand->GetRealOccs().push_back(newOcc); } // create use occurs for all the symbols that alias with muost @@ -287,7 +289,7 @@ void MeStorePre::CreateSpreUseOccsForAll(BB &bb) const { CHECK_NULL_FATAL(wkCand); CHECK_FATAL(!wkCand->GetRealOccs().empty(), "container empty check"); SOcc *lastOcc = wkCand->GetRealOccs().back(); - if (lastOcc->GetOccTy() == kSOccUse && lastOcc->GetBB() == &bb) { + if (lastOcc->GetOccTy() == kSOccUse && &lastOcc->GetBB() == &bb) { continue; // no need to push consecutive use occurrences at same BB } SUseOcc *newOcc = spreMp->New(bb); diff --git a/src/maple_me/src/occur.cpp b/src/maple_me/src/occur.cpp index fc98363ba57e4b7734186fdfbc532e86cee4a4f8..69b11d2c1799128fa3c01fbb8d06feee645e21a9 100644 --- a/src/maple_me/src/occur.cpp +++ b/src/maple_me/src/occur.cpp @@ -31,7 +31,7 @@ constexpr uint32_t kOffsetNaryMeStmtOpnd = 2; } namespace maple { -std::array PreWorkCand::workCandHashTable; +std::array PreWorkCand::workCandHashTable; void MeOccur::DumpOccur(IRMap &irMap) { MIRModule *mod = &irMap.GetSSATab().GetModule(); @@ -156,6 +156,7 @@ void MeRealOcc::Dump(const IRMap &irMap) const { if (meExpr != nullptr) { meExpr->Dump(&irMap); } else { + ASSERT_NOT_NULL(meStmt); meStmt->Dump(&irMap); } if (meStmt != nullptr && meStmt->GetBB()) { @@ -225,7 +226,7 @@ uint32 PreWorkCand::ComputeWorkCandHashIndex(const MeExpr &meExpr) { case kMeOpIvar: { auto &iVar = static_cast(meExpr); hashIdx = ComputeWorkCandHashIndex(*iVar.GetBase()) + - (static_cast(iVar.GetTyIdx()) << kOffsetIvarMeExprTyIdx) + iVar.GetFieldID(); + (static_cast(iVar.GetTyIdx()) << kOffsetIvarMeExprTyIdx) + iVar.GetFieldID(); break; } case kMeOpOp: { @@ -249,7 +250,7 @@ uint32 PreWorkCand::ComputeWorkCandHashIndex(const MeExpr &meExpr) { default: CHECK_FATAL(false, "MeOP NIY"); } - return hashIdx % kWorkCandHashLength; + return hashIdx % workCandHashLength; } // insert occ as realOccs[pos] after shifting the vector elements further down @@ -356,6 +357,6 @@ uint32 PreStmtWorkCand::ComputeStmtWorkCandHashIndex(const MeStmt &stmt) { default: CHECK_FATAL(false, "ComputeStmtWorkCandHashIndex: NYI"); } - return hIdx % kWorkCandHashLength; + return hIdx % workCandHashLength; } } // namespace maple diff --git a/src/maple_me/src/preg_renamer.cpp b/src/maple_me/src/preg_renamer.cpp index ef55dd8a9ed2de10447c3a2104f83c8cbc548559..930cb4d862116fcb2212301e892f5f053ea098e6 100644 --- a/src/maple_me/src/preg_renamer.cpp +++ b/src/maple_me/src/preg_renamer.cpp @@ -19,6 +19,7 @@ namespace maple { void PregRenamer::EnqueDefUses(std::list &qu, RegMeExpr *node, std::set &curVisited) const { + CHECK_NULL_FATAL(node); // get its define if (node->GetDefBy() == kDefByPhi) { MeRegPhiNode &defPhi = node->GetDefPhi(); @@ -81,7 +82,7 @@ void PregRenamer::RunSelf() const { if (curNode->GetDefBy() == kDefByNo) { // if any use are from zero version, we stop renaming all the candidates related to it issue #1420 useDefFromZeroVersion = true; - } else if (curNode->DefByBB()->GetAttributes(kBBAttrIsTry)) { + } else if (curNode->DefByBB() != nullptr && curNode->DefByBB()->GetAttributes(kBBAttrIsTry)) { definedInTryBlock = true; } } diff --git a/src/maple_me/src/prop.cpp b/src/maple_me/src/prop.cpp index 847dcedb807b151fa3cc0a1f1540cf6f5a545a64..1bc2f269fe5f3723fffa12a6b3e22df56e3d2a54 100644 --- a/src/maple_me/src/prop.cpp +++ b/src/maple_me/src/prop.cpp @@ -100,6 +100,7 @@ MeExpr *Prop::SimplifyCompareSelectConstMeExpr(const OpMeExpr &opMeExpr, const M return nullptr; } + // negative one is invalid ExprID OpMeExpr newopMeExpr(-1); newopMeExpr.InitBase(OP_select, PTY_u1, 3); newopMeExpr.SetOpnd(0, opMeOpnd0.GetOpnd(0)); @@ -316,6 +317,7 @@ bool Prop::Propagatable(const MeExpr &expr, const BB &fromBB, bool atParm) const return false; } } + ASSERT_NOT_NULL(curBB); if (fromBB.GetAttributes(kBBAttrIsTry) && !curBB->GetAttributes(kBBAttrIsTry)) { return false; } diff --git a/src/maple_me/src/ssa_devirtual.cpp b/src/maple_me/src/ssa_devirtual.cpp index 4d8e78833c91d36007e1cd5ba0ca33d08a4c356f..0b55c55c0806b1bdc5311340e3854411d5e45e80 100644 --- a/src/maple_me/src/ssa_devirtual.cpp +++ b/src/maple_me/src/ssa_devirtual.cpp @@ -13,6 +13,7 @@ * See the Mulan PSL v1 for more details. */ #include "ssa_devirtual.h" + // This phase performs devirtualization based on SSA. Ideally, we should have // precise alias information, so that for each reference we know exactly the // objects it refers to, then the exact method it calls. However, precise alias @@ -207,6 +208,7 @@ bool SSADevirtual::DevirtualizeCall(CallMeStmt &callStmt) { } if (i == inferredTypeCandidates.size() && inferredFunction != nullptr) { if (SSADevirtual::debug) { + ASSERT_NOT_NULL(GetMIRFunction()); LogInfo::MapleLogger() << "Devirutalize based on set of inferred types: In " << GetMIRFunction()->GetName() << "; Devirtualize: " << mirFunc.GetName() << '\n'; } @@ -239,44 +241,44 @@ void SSADevirtual::InsertNullCheck(const CallMeStmt &callStmt, MeExpr &receiver) callStmt.GetBB()->InsertMeStmtBefore(&callStmt, nullCheck); } -void SSADevirtual::PropVarInferredType(VarMeExpr &VarMeExpr) const { - if (VarMeExpr.GetInferredTyIdx() != 0u) { +void SSADevirtual::PropVarInferredType(VarMeExpr &varMeExpr) const { + if (varMeExpr.GetInferredTyIdx() != 0u) { return; } - if (VarMeExpr.GetDefBy() == kDefByStmt) { - DassignMeStmt &defStmt = utils::ToRef(safe_cast(VarMeExpr.GetDefStmt())); + if (varMeExpr.GetDefBy() == kDefByStmt) { + DassignMeStmt &defStmt = utils::ToRef(safe_cast(varMeExpr.GetDefStmt())); MeExpr *rhs = defStmt.GetRHS(); if (rhs->GetOp() == OP_gcmalloc) { - VarMeExpr.SetInferredTyIdx(static_cast(rhs)->GetTyIdx()); - VarMeExpr.SetMaybeNull(false); + varMeExpr.SetInferredTyIdx(static_cast(rhs)->GetTyIdx()); + varMeExpr.SetMaybeNull(false); if (SSADevirtual::debug) { - MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(VarMeExpr.GetInferredTyIdx()); - LogInfo::MapleLogger() << "[SSA-DEVIRT] [TYPE-INFERRING] mx" << VarMeExpr.GetExprID() << " "; + MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(varMeExpr.GetInferredTyIdx()); + LogInfo::MapleLogger() << "[SSA-DEVIRT] [TYPE-INFERRING] mx" << varMeExpr.GetExprID() << " "; type->Dump(0, false); LogInfo::MapleLogger() << '\n'; } } else { TyIdx tyIdx = GetInferredTyIdx(*rhs); - VarMeExpr.SetMaybeNull(MaybeNull(*rhs)); + varMeExpr.SetMaybeNull(MaybeNull(*rhs)); if (tyIdx != 0u) { - VarMeExpr.SetInferredTyIdx(tyIdx); + varMeExpr.SetInferredTyIdx(tyIdx); if (SSADevirtual::debug) { - MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(VarMeExpr.GetInferredTyIdx()); - LogInfo::MapleLogger() << "[SSA-DEVIRT] [TYPE-INFERRING] mx" << VarMeExpr.GetExprID() << " "; + MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(varMeExpr.GetInferredTyIdx()); + LogInfo::MapleLogger() << "[SSA-DEVIRT] [TYPE-INFERRING] mx" << varMeExpr.GetExprID() << " "; type->Dump(0, false); LogInfo::MapleLogger() << '\n'; } } } - if (VarMeExpr.GetInferredTyIdx() != 0u) { + if (varMeExpr.GetInferredTyIdx() != 0u) { OriginalSt *ost = irMap->GetSSATab().GetOriginalStFromID(defStmt.GetVarLHS()->GetOStIdx()); MIRSymbol *mirSym = ost->GetMIRSymbol(); if (mirSym->IsStatic() && mirSym->IsFinal()) { // static final field can store and propagate inferred typeinfo if (mirSym->GetInferredTyIdx() == kInitTyIdx) { // mirSym->_inferred_tyIdx has not been set before - mirSym->SetInferredTyIdx(VarMeExpr.GetInferredTyIdx()); - } else if (mirSym->GetInferredTyIdx() != VarMeExpr.GetInferredTyIdx()) { + mirSym->SetInferredTyIdx(varMeExpr.GetInferredTyIdx()); + } else if (mirSym->GetInferredTyIdx() != varMeExpr.GetInferredTyIdx()) { // If mirSym->_inferred_tyIdx has been set before, it means we have // seen a divergence on control flow. Set to NONE if not all // branches reach the same conclusion. @@ -284,7 +286,7 @@ void SSADevirtual::PropVarInferredType(VarMeExpr &VarMeExpr) const { } } } - } else if (VarMeExpr.GetDefBy() == kDefByPhi) { + } else if (varMeExpr.GetDefBy() == kDefByPhi) { if (SSADevirtual::debug) { LogInfo::MapleLogger() << "[SSA-DEVIRT] [TYPE-INFERRING] " << "Def by phi " << '\n'; } @@ -457,8 +459,8 @@ void SSADevirtual::TraversalMeStmt(MeStmt &meStmt) { case OP_assertnonnull: case OP_eval: case OP_free: { - auto *umeStmt = static_cast(&meStmt); - VisitMeExpr(umeStmt->GetOpnd()); + auto *unaryStmt = static_cast(&meStmt); + VisitMeExpr(unaryStmt->GetOpnd()); break; } case OP_call: diff --git a/src/maple_me/src/ssa_epre.cpp b/src/maple_me/src/ssa_epre.cpp index 8fc603e022adb59ac759af6705bd2a30d9388d4e..9efe03818f3166c2d5ce87f12bd8ff4ed58814c1 100644 --- a/src/maple_me/src/ssa_epre.cpp +++ b/src/maple_me/src/ssa_epre.cpp @@ -121,7 +121,7 @@ void SSAEPre::GenerateSaveRealOcc(MeRealOcc &realOcc) { bool isReplaced = irMap->ReplaceMeExprStmt(*realOcc.GetMeStmt(), *realOcc.GetMeExpr(), *regOrVar); // rebuild worklist if (isReplaced) { - BuildWorkListStmt(realOcc.GetMeStmt(), realOcc.GetSequence(), true, regOrVar); + BuildWorkListStmt(*realOcc.GetMeStmt(), realOcc.GetSequence(), true, regOrVar); } realOcc.SetSavedExpr(*regOrVar); } @@ -152,7 +152,7 @@ void SSAEPre::GenerateReloadRealOcc(MeRealOcc &realOcc) { bool isReplaced = irMap->ReplaceMeExprStmt(*realOcc.GetMeStmt(), *realOcc.GetMeExpr(), *regOrVar); // update worklist if (isReplaced) { - BuildWorkListStmt(realOcc.GetMeStmt(), realOcc.GetSequence(), true, regOrVar); + BuildWorkListStmt(*realOcc.GetMeStmt(), realOcc.GetSequence(), true, regOrVar); } } diff --git a/src/maple_me/src/ssa_pre.cpp b/src/maple_me/src/ssa_pre.cpp index 7cdf18e8ac9b91058b6ad55343aabef4176cfcf0..b84ecf69c56a4c551d552219399ad8dcbdcfdd7f 100644 --- a/src/maple_me/src/ssa_pre.cpp +++ b/src/maple_me/src/ssa_pre.cpp @@ -91,7 +91,7 @@ MeExpr *SSAPre::CreateNewCurTemp(const MeExpr &meExpr) { } VarMeExpr *SSAPre::CreateNewCurLocalRefVar() { - if (curLocalRefVar) { + if (curLocalRefVar != nullptr) { // only need to create a new version VarMeExpr *tempVar = irMap->CreateVarMeExprVersion(static_cast(*curLocalRefVar)); return tempVar; @@ -103,6 +103,7 @@ VarMeExpr *SSAPre::CreateNewCurLocalRefVar() { auto *realMIRType = static_cast(mirType); FieldID fieldID = ivarMeExpr->GetFieldID(); curLocalRefVar = irMap->CreateNewLocalRefVarTmp(NewTempStrIdx(), realMIRType->GetPointedTyIdxWithFieldID(fieldID)); + ASSERT_NOT_NULL(curLocalRefVar); ssaTab->SetEPreLocalRefVar(curLocalRefVar->GetOStIdx(), true); SetAddedNewLocalRefVars(true); return curLocalRefVar; @@ -114,6 +115,7 @@ void SSAPre::GenerateSaveInsertedOcc(MeInsertedOcc &insertedOcc) { "GenerateSaveInsertedOcc: inconsistent puIdx"); MeExpr *regOrVar = CreateNewCurTemp(*insertedOcc.GetMeExpr()); MeStmt *newMeStmt = nullptr; + ASSERT_NOT_NULL(workCand); if (!workCand->NeedLocalRefVar() || GetPlacementRCOn()) { if (regOrVar->GetMeOp() == kMeOpReg) { newMeStmt = irMap->CreateRegassignMeStmt(*regOrVar, *insertedOcc.GetMeExpr(), *insertedOcc.GetBB()); @@ -156,6 +158,7 @@ void SSAPre::GenerateSavePhiOcc(MePhiOcc &phiOcc) { phiOcc.SetVarPhi(*phiVar); } // update the phi opnds later + ASSERT_NOT_NULL(workCand); if (workCand->NeedLocalRefVar() && !GetPlacementRCOn()) { VarMeExpr *localRefVar = CreateNewCurLocalRefVar(); temp2LocalRefVarMap[static_cast(regOrVar)] = localRefVar; @@ -417,7 +420,7 @@ void SSAPre::SetSave(MeOccur &defX) { } } -void SSAPre::SetReplacement(MePhiOcc &occ, MeOccur *repDef) { +void SSAPre::SetReplacement(MePhiOcc &occ, MeOccur &repDef) { occ.SetIsRemoved(true); // exclude recursive PhiOcc for (auto it = phiOccs.begin(); it != phiOccs.end(); ++it) { MePhiOcc *phiOcc = *it; @@ -430,19 +433,20 @@ void SSAPre::SetReplacement(MePhiOcc &occ, MeOccur *repDef) { // exclude recursive def SetReplacement(*phiOcc, repDef); } else { - phiOpnd->SetDef(repDef); // replace phiOpnd of phiOcc by replacing def repDef - phiOpnd->SetClassID(repDef->GetClassID()); + phiOpnd->SetDef(&repDef); // replace phiOpnd of phiOcc by replacing def repDef + phiOpnd->SetClassID(repDef.GetClassID()); phiOpnd->SetIsPhiOpndReload(true); } } } } + ASSERT_NOT_NULL(workCand); for (auto it = workCand->GetRealOccs().begin(); it != workCand->GetRealOccs().end(); ++it) { MeRealOcc *realOcc = *it; // when realOcc satisfying reload and def of it is occ, do the replacement if (realOcc->IsReload() && realOcc->GetDef() == &occ) { - realOcc->SetDef(repDef); - realOcc->SetClassID(repDef->GetClassID()); + realOcc->SetDef(&repDef); + realOcc->SetClassID(repDef.GetClassID()); } } } @@ -477,11 +481,11 @@ void SSAPre::Finalize2() { switch (defOcc->GetOccType()) { case kOccReal: case kOccInserted: - SetReplacement(*phiOcc, defOcc); + SetReplacement(*phiOcc, *defOcc); break; case kOccPhiocc: if (!static_cast(defOcc)->IsExtraneous()) { - SetReplacement(*phiOcc, defOcc); + SetReplacement(*phiOcc, *defOcc); } break; default: @@ -553,6 +557,7 @@ void SSAPre::ComputeCanBeAvail() const { ResetCanBeAvail(*phiOcc); } } + ASSERT_NOT_NULL(workCand); if (workCand->Redo2HandleCritEdges() && phiOcc->IsCanBeAvail()) { // check critical edges bool existCritEdge = false; @@ -568,16 +573,16 @@ void SSAPre::ComputeCanBeAvail() const { } } -void SSAPre::ResetLater(MePhiOcc *occ) const { - occ->SetIsLater(false); +void SSAPre::ResetLater(MePhiOcc &occ) const { + occ.SetIsLater(false); // the following loop is to find occ's use list and reset them for (auto it = phiOccs.begin(); it != phiOccs.end(); ++it) { MePhiOcc *phiOcc = *it; for (MePhiOpndOcc *phiOpnd : phiOcc->GetPhiOpnds()) { - if (phiOpnd->GetDef() != nullptr && phiOpnd->GetDef() == occ) { + if (phiOpnd->GetDef() != nullptr && phiOpnd->GetDef() == &occ) { // when comes here, phiOpnd->GetDef() is a use of occ if (phiOcc->IsLater()) { - ResetLater(phiOcc); + ResetLater(*phiOcc); } } } @@ -600,7 +605,7 @@ void SSAPre::ComputeLater() const { } } if (existNonNullDef || phiOcc->SpeculativeDownSafe()) { - ResetLater(phiOcc); + ResetLater(*phiOcc); } } } @@ -874,6 +879,7 @@ MeExpr *SSAPre::GetReplaceMeExpr(const MeExpr &opnd, const BB &ePhiBB, size_t j) } } if (retExpr != nullptr && retExpr->GetPrimType() == kPtyInvalid) { + ASSERT_NOT_NULL(workCand); retExpr->SetPtyp(workCand->GetPrimType()); } return retExpr; @@ -1104,8 +1110,8 @@ void SSAPre::CreateSortedOccs() { nextPhiOpndOcc = perCandMemPool->New(*GetBB(dom->GetDtPreOrderItem(*phiOpndDfnIt))); auto it = bb2PhiOpndMap.find(dom->GetDtPreOrderItem(*phiOpndDfnIt)); if (it == bb2PhiOpndMap.end()) { - std::forward_list newlist = { nextPhiOpndOcc }; - bb2PhiOpndMap[dom->GetDtPreOrderItem(*phiOpndDfnIt)] = newlist; + std::forward_list newList = { nextPhiOpndOcc }; + bb2PhiOpndMap[dom->GetDtPreOrderItem(*phiOpndDfnIt)] = newList; } else { it->second.push_front(nextPhiOpndOcc); } @@ -1119,7 +1125,7 @@ void SSAPre::CreateSortedOccs() { } } } while (pickedOcc != nullptr); - // initialize phiOpnds vector in each MePhiOcc node and defPhiOcc field in + // initialize phiOpnds vector in each MePhiOcc node and defPhiOcc field in // each MePhiOpndOcc node for (MePhiOcc *phiOcc : phiOccs) for (BB *pred : phiOcc->GetBB()->GetPred()) { @@ -1152,6 +1158,7 @@ MeStmt *SSAPre::CopyMeStmt(const MeStmt &meStmt) const { } MeExpr *SSAPre::CopyMeExpr(const MeExpr &expr) const { + ASSERT_NOT_NULL(irMap); MapleAllocator *irMapAlloc = &irMap->GetIRMapAlloc(); switch (expr.GetMeOp()) { case kMeOpOp: { @@ -1191,7 +1198,7 @@ bool SSAPre::DefVarDominateOcc(const MeExpr *meExpr, const MeOccur &meOcc) const return true; // it's an original variable which dominates everything case kDefByStmt: { MeStmt *meStmt = varMeExpr->GetDefStmt(); - CHECK_FATAL(meStmt, "should have a def meStmt"); + CHECK_FATAL(meStmt != nullptr, "should have a def meStmt"); BB *defBB = meStmt->GetBB(); if (occBB == defBB) { return false; @@ -1229,7 +1236,7 @@ bool SSAPre::DefVarDominateOcc(const MeExpr *meExpr, const MeOccur &meOcc) const return dom->Dominate(*defBB, *occBB); } default: - CHECK_FATAL(false, "to be done"); + CHECK_FATAL(false, "NYI"); } } else { CHECK_FATAL(meExpr->GetMeOp() == kMeOpReg, "invalid value of meExpr->GetMeOp()"); @@ -1239,7 +1246,7 @@ bool SSAPre::DefVarDominateOcc(const MeExpr *meExpr, const MeOccur &meOcc) const return true; // original st dominates everything case kDefByStmt: { MeStmt *meStmt = regMeExpr->GetDefStmt(); - CHECK_FATAL(meStmt, "invalid value of meStmt"); + CHECK_FATAL(meStmt != nullptr, "invalid value of meStmt"); BB *defBB = meStmt->GetBB(); if (occBB == defBB) { return false; @@ -1266,7 +1273,7 @@ bool SSAPre::DefVarDominateOcc(const MeExpr *meExpr, const MeOccur &meOcc) const return dom->Dominate(*defBB, *occBB); } default: - CHECK_FATAL(false, "to be done"); + CHECK_FATAL(false, "NYI"); } } } @@ -1397,8 +1404,9 @@ void SSAPre::CreateMembarOccAtCatch(BB &bb) { } } -void SSAPre::BuildWorkListStmt(MeStmt *meStmt, uint32 seqStmt, bool isRebuilt, MeExpr *tempVar) { +void SSAPre::BuildWorkListStmt(MeStmt &stmt, uint32 seqStmt, bool isRebuilt, MeExpr *tempVar) { IncTreeid(); + MeStmt *meStmt = &stmt; Opcode op = meStmt->GetOp(); switch (op) { case OP_jstry: @@ -1543,7 +1551,7 @@ void SSAPre::BuildWorkListStmt(MeStmt *meStmt, uint32 seqStmt, bool isRebuilt, M intrn->GetIntrinsic() == INTRN_MCCSetObjectPermanent) { break; } - // fall thru + // fall thru } case OP_xintrinsiccall: case OP_intrinsiccallwithtype: @@ -1583,12 +1591,13 @@ void SSAPre::BuildWorkListStmt(MeStmt *meStmt, uint32 seqStmt, bool isRebuilt, M } void SSAPre::BuildWorkListBB(BB *bb) { + ASSERT_NOT_NULL(bb); if (GetSpillAtCatch() && bb->GetAttributes(kBBAttrIsCatch)) { CreateMembarOccAtCatch(*bb); } uint32 seqStmt = 0; for (auto &stmt : bb->GetMeStmts()) { - BuildWorkListStmt(&stmt, ++seqStmt, false); + BuildWorkListStmt(stmt, ++seqStmt, false); } if (bb->GetAttributes(kBBAttrIsExit) || bb->GetAttributes(kBBAttrWontExit)) { CreateExitOcc(*bb); diff --git a/src/maple_phase/include/phase_impl.h b/src/maple_phase/include/phase_impl.h index 47a5f37e1bcc53c6bf2538b74acb7a03be4a23cc..fc684feffdec9c4848564dc9c836b8b19c7e505e 100644 --- a/src/maple_phase/include/phase_impl.h +++ b/src/maple_phase/include/phase_impl.h @@ -22,7 +22,7 @@ namespace maple { class FuncOptimizeImpl : public MplTaskParam { public: - explicit FuncOptimizeImpl(MIRModule *mod, KlassHierarchy *kh = nullptr, bool trace = false); + explicit FuncOptimizeImpl(MIRModule &mod, KlassHierarchy *kh = nullptr, bool trace = false); virtual ~FuncOptimizeImpl(); // Each phase needs to implement its own Clone virtual FuncOptimizeImpl *Clone() = 0; @@ -70,7 +70,7 @@ class FuncOptimizeIterator { #define OPT_TEMPLATE(OPT_NAME) \ auto *kh = static_cast(mrm->GetAnalysisResult(MoPhase_CHA, mod)); \ ASSERT_NOT_NULL(kh); \ - FuncOptimizeIterator opt(PhaseName(), new OPT_NAME(mod, kh, TRACE_PHASE)); \ + FuncOptimizeIterator opt(PhaseName(), new OPT_NAME(*mod, kh, TRACE_PHASE)); \ opt.Run(); } // namespace maple #endif // MAPLE_PHASE_INCLUDE_PHASE_IMPL_H diff --git a/src/maple_util/include/literal_str_name.h b/src/maple_util/include/literalstrname.h similarity index 87% rename from src/maple_util/include/literal_str_name.h rename to src/maple_util/include/literalstrname.h index a2227e4bd44b2e6f0413019853256fb25f53a809..41fd08b6af3c8fef0a5dd56487aa7ead07b406b9 100644 --- a/src/maple_util/include/literal_str_name.h +++ b/src/maple_util/include/literalstrname.h @@ -12,25 +12,21 @@ * FIT FOR A PARTICULAR PURPOSE. * See the Mulan PSL v1 for more details. */ -#ifndef MAPLE_UTIL_INCLUDE_LITERAL_STR_NAME_H -#define MAPLE_UTIL_INCLUDE_LITERAL_STR_NAME_H +#ifndef MRT_INCLUDE_LITERALSTRNAME_H +#define MRT_INCLUDE_LITERALSTRNAME_H #include #include #include "muid.h" // literal string naming is shared between maple compiler and runtime, thus not in namespace maplert -#ifdef MUID_LENGTH -#undef MUID_LENGTH -#define MUID_LENGTH 16 -#endif - const std::string kConstString = "_C_STR_"; const std::string kConstStringPtr = "_PTR_C_STR_"; -constexpr int kConstStringLen = 7; const std::string kLocalStringPrefix = "L_STR_"; +constexpr int kConstStringLen = 7; +constexpr unsigned int kDigestHashLength = 16; union DigestHash { - uint8_t bytes[MUID_LENGTH]; + uint8_t bytes[kDigestHashLength]; struct { uint64_t first; uint64_t second; @@ -57,7 +53,7 @@ class LiteralStrName { return hash; } - static std::string GetHexStr(const uint8_t *bytes, unsigned len); + static std::string GetHexStr(const uint8_t *bytes, uint32_t len); static std::string GetLiteralStrName(const uint8_t *bytes, uint32_t len); static std::string ComputeMuid(const uint8_t *bytes, uint32_t len); }; diff --git a/src/maple_util/include/muid.h b/src/maple_util/include/muid.h index 346f352b2b8892e80bf4ed3642f888a4c1bc8061..e5ae7cd1fdb64b9c98800de706042ac09b46b00d 100644 --- a/src/maple_util/include/muid.h +++ b/src/maple_util/include/muid.h @@ -30,11 +30,9 @@ constexpr unsigned int kApkNamespace = 0x80; constexpr unsigned int kBitMask = 0x3f; #ifdef USE_64BIT_MUID -#undef MUID_LENGTH -#define MUID_LENGTH 8 +constexpr unsigned int kMuidLength = 8; #else -#undef MUID_LENGTH -#define MUID_LENGTH 16 +constexpr unsigned int kMuidLength = 16; #endif // USE_64BIT_MUID // muid-related files are shared between maple compiler and runtime, thus not in @@ -51,10 +49,10 @@ struct MUID { #ifdef USE_64BIT_MUID uint64_t raw; uint32_t words[2]; - uint8_t bytes[MUID_LENGTH]; + uint8_t bytes[kMuidLength]; #else uint64_t words[2]; - uint8_t bytes[MUID_LENGTH]; + uint8_t bytes[kMuidLength]; #endif // USE_64BIT_MUID } data; @@ -63,18 +61,18 @@ struct MUID { data.words[1] = 0; } inline bool IsSystemNameSpace() const { - return (data.bytes[MUID_LENGTH - 1] & ~kBitMask) == kSystemNamespace; + return (data.bytes[kMuidLength - 1] & ~kBitMask) == kSystemNamespace; } inline bool IsApkNameSpace() const { - return (data.bytes[MUID_LENGTH - 1] & ~kBitMask) == kApkNamespace; + return (data.bytes[kMuidLength - 1] & ~kBitMask) == kApkNamespace; } inline void SetSystemNameSpace() { - data.bytes[MUID_LENGTH - 1] &= kBitMask; - data.bytes[MUID_LENGTH - 1] |= kSystemNamespace; + data.bytes[kMuidLength - 1] &= kBitMask; + data.bytes[kMuidLength - 1] |= kSystemNamespace; } inline void SetApkNameSpace() { - data.bytes[MUID_LENGTH - 1] &= kBitMask; - data.bytes[MUID_LENGTH - 1] |= kApkNamespace; + data.bytes[kMuidLength - 1] &= kBitMask; + data.bytes[kMuidLength - 1] |= kApkNamespace; } bool operator<(const MUID &muid) const { return (data.words[1] < muid.data.words[1] || diff --git a/src/maple_util/include/name_mangler.h b/src/maple_util/include/namemangler.h similarity index 98% rename from src/maple_util/include/name_mangler.h rename to src/maple_util/include/namemangler.h index 3b84b42b2a5c2fa36665add926f6f78f7a6d58d3..256ee5274d01782f49ca20a294df24649dbb190e 100644 --- a/src/maple_util/include/name_mangler.h +++ b/src/maple_util/include/namemangler.h @@ -12,8 +12,8 @@ * FIT FOR A PARTICULAR PURPOSE. * See the Mulan PSL v1 for more details. */ -#ifndef MAPLE_UTIL_INCLUDE_NAME_MANGLER_H -#define MAPLE_UTIL_INCLUDE_NAME_MANGLER_H +#ifndef NAMEMANGLER_H +#define NAMEMANGLER_H #include #include @@ -148,7 +148,8 @@ static constexpr const char kFunctionLayoutStr[] = "__func_layout__"; static constexpr const char kFunctionProfileTabPrefixStr[] = "__muid_profile_func_tab"; -static constexpr const char kBBProfileTabPrefixStr[] = "__bb_profile_tab"; +static constexpr const char kBBProfileTabPrefixStr[] = "__muid_prof_counter_tab"; +static constexpr const char kFuncIRProfInfTabPrefixStr[] = "__muid_prof_ir_desc_tab"; static constexpr const char kBindingProtectedRegionStr[] = "__BindingProtectRegion__"; diff --git a/src/maple_util/include/profile.h b/src/maple_util/include/profile.h index 27f4365f57d7aef454f75d0f5aaf19d14c0bed5c..24662ed45174d4bbfb06b40c967804e1aafffc36 100644 --- a/src/maple_util/include/profile.h +++ b/src/maple_util/include/profile.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2019] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. @@ -24,14 +24,36 @@ #include "option.h" namespace maple { + +struct IRProfileDesc { + uint32 counterStart = 0; + uint32 counterEnd = 0; + uint64 funcHash = 0; + IRProfileDesc() = default; + IRProfileDesc(uint64 hash, uint32 start, uint32 end) : counterStart(start), counterEnd(end), funcHash(hash) {} +}; + + class Profile { public: struct FuncItem { uint32 callTimes; uint8 type; }; + // function ir profile info + struct BBInfo { + uint64 funcHash = 0; + uint32 totalCounter = 0; + std::vector counter; + BBInfo() = default; + BBInfo(uint64 hash, uint32 num, std::vector &&counter) + : funcHash(hash), totalCounter(num), counter(counter) {} + BBInfo(uint64 hash, uint32 num, std::initializer_list iList) : funcHash(hash), totalCounter(num), + counter(iList) {} + }; static const uint8 kStringEnd; + void InitTestData(); bool CheckFuncHot(const std::string &className) const; bool CheckMethodHot(const std::string &className) const; bool CheckFieldHot(const std::string &className) const; @@ -42,6 +64,7 @@ class Profile { // default get all kind profile bool DeCompress(const std::string &fileName, const std::string &dexName, ProfileType type = kAll); const std::unordered_map &GetFunctionProf() const; + bool GetFunctionBBProf(const std::string &funcName, BBInfo &result); size_t GetLiteralProfileSize() const; bool CheckProfValid() const; bool CheckDexValid(uint32 idx); @@ -67,13 +90,18 @@ class Profile { std::unordered_map reflectionStrData; std::unordered_map funcProfData; std::unordered_set &GetMeta(uint8 type); + std::unordered_map funcBBProfData; + std::unordered_map funcDesc; + std::vector counterTab; bool CheckProfileHeader(const Header *header) const; std::string GetProfileNameByType(uint8 type) const; + std::string GetFunctionName(uint32 classIdx, uint32 methodIdx, uint32 sigIdx); void ParseMeta(const char *data, int fileNum, std::unordered_set &metaData); void ParseReflectionStr(const char *data, int fileNum); void ParseFunc(const char *data, int fileNum); void ParseLiteral(const char *data, const char *end); + void ParseIRFuncDesc(const char *data, int fileNum); + void ParseCounterTab(const char *data, int fileNum); }; - } // namespace maple #endif // MAPLE_UTIL_INCLUDE_PROFILE_H diff --git a/src/maple_util/include/profile_type.h b/src/maple_util/include/profile_type.h index 90b73c0ddc2565dc81d584fb7478d61d8476b226..9852d8f49c406d29089eec8422caca3f51896db1 100644 --- a/src/maple_util/include/profile_type.h +++ b/src/maple_util/include/profile_type.h @@ -31,7 +31,8 @@ enum ProfileType : uint8_t { kReflectionStr = 0x04, kLiteral = 0x05, kBBInfo = 0x06, - kAll = 0x07, + kIRCounter = 0x07, + kAll = 0x08, kFileDesc = 0xFF }; @@ -55,6 +56,23 @@ struct FunctionItem { : classIdx(classIdx), methodIdx(methodIdx), sigIdx(sigIdx), callTimes(callTimes), type(type) {} }; +struct FunctionIRProfItem { + uint64_t hash; + uint32_t classIdx; + uint32_t methodIdx; + uint32_t sigIdx; + uint32_t counterStart; + uint32_t counterEnd; + FunctionIRProfItem(uint64_t hash, uint32_t classIdx, uint32_t methodIdx, uint32_t sigIdx, uint32_t start, + uint32_t end) : hash(hash), classIdx(classIdx), methodIdx(methodIdx), sigIdx(sigIdx), + counterStart(start), counterEnd(end) {} +}; + +struct FuncCounterItem { + uint32_t callTimes; + FuncCounterItem(uint32_t callTimes) : callTimes(callTimes) {} +}; + struct MetaItem { uint32_t idx; MetaItem(uint32_t idx) : idx(idx) {} @@ -66,12 +84,11 @@ struct ReflectionStrItem { ReflectionStrItem(uint32_t idx, uint8_t type) : type(type), idx(idx) {} }; -template struct MapleFileProf { uint32_t idx; uint32_t num; uint32_t size; - T items[1]; + MapleFileProf(uint32_t idx, uint32_t num, uint32_t size) : idx(idx), num(num), size(size) {} }; constexpr int kMagicNum = 14; diff --git a/src/maple_util/src/profile.cpp b/src/maple_util/src/profile.cpp index c98cf444d4f87e017e77215f85344bc4d0ccce7a..eea403bf6c93ee5da56dfabd13593cf7242edef5 100644 --- a/src/maple_util/src/profile.cpp +++ b/src/maple_util/src/profile.cpp @@ -24,7 +24,7 @@ #include #include #include -#include "name_mangler.h" +#include "namemangler.h" #include "file_layout.h" #include "types_def.h" @@ -65,6 +65,10 @@ std::string Profile::GetProfileNameByType(uint8 type) const { return "ReflectionStr"; case kLiteral: return "Literal"; + case kBBInfo: + return "IRProfDescption"; + case kIRCounter: + return "IRProfCounter"; case kFileDesc: return "FileDescription"; default: @@ -96,70 +100,122 @@ void Profile::ParseLiteral(const char *data, const char *end) { } } +std::string Profile::GetFunctionName(uint32 classIdx, uint32 methodIdx, uint32 sigIdx) { + std::string className = NameMangler::EncodeName(strMap.at(classIdx)); + std::string methodName = NameMangler::EncodeName(strMap.at(methodIdx)); + std::string sigName = NameMangler::EncodeName(strMap.at(sigIdx)); + std::string funcName = className + "_7C" + methodName + "_7C" + sigName; + return funcName; +} + void Profile::ParseFunc(const char *data, int fileNum) { - const MapleFileProf *funcProf = nullptr; + const MapleFileProf *funcProf = nullptr; const FunctionItem *funcItem = nullptr; uint32 offset = 0; for (int32 mapleFileIdx = 0; mapleFileIdx < fileNum; mapleFileIdx++) { - funcProf = reinterpret_cast*>(data + offset); + funcProf = reinterpret_cast(data + offset); if (CheckDexValid(funcProf->idx)) { if (debug) { LogInfo::MapleLogger() << "FuncProfile" << ":" << strMap.at(funcProf->idx) << ":" << funcProf->num << "\n"; } - for (uint32 item = 0; item < funcProf->num; item++) { - funcItem = &(funcProf->items[item]); + funcItem = reinterpret_cast(data + offset + sizeof(MapleFileProf)); + for (uint32 item = 0; item < funcProf->num; item++, ++funcItem) { if (funcItem->type >= kLayoutTypeCount) { if (debug) { LogInfo::MapleLogger() << "ParseFunc Error usupport type " << funcItem->type << "\n"; } continue; } - std::string className = NameMangler::EncodeName(strMap.at(funcItem->classIdx)); - std::string methodName = NameMangler::EncodeName(strMap.at(funcItem->methodIdx)); - std::string sigName = NameMangler::EncodeName(strMap.at(funcItem->sigIdx)); - std::string funcName = className + "_7C" + methodName + "_7C" + sigName; + std::string funcName = GetFunctionName(funcItem->classIdx, funcItem->methodIdx, funcItem->sigIdx); funcProfData.insert( std::make_pair(funcName, (FuncItem){ .callTimes = funcItem->callTimes, .type = funcItem->type })); } } // new maple file's profile - offset += sizeof(MapleFileProf) + sizeof(FunctionItem) * (funcProf->num - 1); + offset += sizeof(MapleFileProf) + funcProf->size; + } +} + +void Profile::ParseIRFuncDesc(const char *data, int fileNum) { + const MapleFileProf *funcProf = nullptr; + const FunctionIRProfItem *funcItem = nullptr; + uint32 offset = 0; + for (int32 mapleFileIdx = 0; mapleFileIdx < fileNum; mapleFileIdx++) { + funcProf = reinterpret_cast(data + offset); + if (CheckDexValid(funcProf->idx)) { + if (debug) { + LogInfo::MapleLogger() << "IRFuncProfile" << ":" << strMap.at(funcProf->idx) << ":" << funcProf->num << "\n"; + } + funcItem = reinterpret_cast(data + offset + sizeof(MapleFileProf)); + for (uint32 item = 0; item < funcProf->num; ++item, ++funcItem) { + if ((funcItem->counterStart <= counterTab.size()) && (funcItem->counterEnd <= counterTab.size())) { + auto begin = counterTab.begin() + funcItem->counterStart; + auto end = counterTab.begin() + funcItem->counterEnd + 1; + std::vector tempCounter(begin, end); + BBInfo bbInfo(funcItem->hash, tempCounter.size(), std::move(tempCounter)); + std::string funcName = GetFunctionName(funcItem->classIdx, funcItem->methodIdx, funcItem->sigIdx); + funcBBProfData.emplace(std::make_pair(funcName, bbInfo)); + } + } + } + // new maple file's profile + offset += sizeof(MapleFileProf) + funcProf->size; + } +} + +void Profile::ParseCounterTab(const char *data, int fileNum) { + const MapleFileProf *counterProf = nullptr; + uint32 offset = 0; + for (int32 mapleFileIdx = 0; mapleFileIdx < fileNum; mapleFileIdx++) { + counterProf = reinterpret_cast(data + offset); + if (CheckDexValid(counterProf->idx)) { + if (debug) { + LogInfo::MapleLogger() << "module name " << strMap.at(counterProf->idx) << std::endl; + } + const FuncCounterItem *item = reinterpret_cast(data + offset + sizeof(MapleFileProf)); + for (uint32 i = 0; i < counterProf->num; ++i, ++item) { + counterTab.emplace_back(item->callTimes); + } + } + offset += sizeof(MapleFileProf) + counterProf->size; } } void Profile::ParseMeta(const char *data, int fileNum, std::unordered_set &metaData) { - const MapleFileProf *metaProf = nullptr; + const MapleFileProf *metaProf = nullptr; uint32 offset = 0; for (int32 mapleFileIdx = 0; mapleFileIdx < fileNum; mapleFileIdx++) { - metaProf = reinterpret_cast*>(data + offset); + metaProf = reinterpret_cast(data + offset); if (CheckDexValid(metaProf->idx)) { if (debug) { - LogInfo::MapleLogger() << "dex name " << strMap.at(metaProf->idx) << '\n';; + LogInfo::MapleLogger() << "module name " << strMap.at(metaProf->idx) << '\n'; } - for (uint32 item = 0; item < metaProf->num; item++) { - const MetaItem *metaItem = &(metaProf->items[item]); + const MetaItem *metaItem = reinterpret_cast(data + offset + sizeof(MapleFileProf)); + for (uint32 item = 0; item < metaProf->num; ++item, ++metaItem) { metaData.insert(strMap.at(metaItem->idx)); } } - offset += sizeof(MapleFileProf) + sizeof(MetaItem) * (metaProf->num - 1); + offset += sizeof(MapleFileProf) + metaProf->size; } } void Profile::ParseReflectionStr(const char *data, int fileNum) { - const MapleFileProf *metaProf = nullptr; + const MapleFileProf *metaProf = nullptr; uint32 offset = 0; for (int32 mapleFileIdx = 0; mapleFileIdx < fileNum; mapleFileIdx++) { - metaProf = reinterpret_cast*>(data + offset); + metaProf = reinterpret_cast(data + offset); if (CheckDexValid(metaProf->idx)) { if (debug) { - LogInfo::MapleLogger() << "dex name " << strMap.at(metaProf->idx) << '\n';; + LogInfo::MapleLogger() << "module name " << strMap.at(metaProf->idx) << '\n'; } - for (uint32 item = 0; item < metaProf->num; item++) { - const ReflectionStrItem *strItem = &(metaProf->items[item]); + + const ReflectionStrItem *strItem = + reinterpret_cast(data + offset + sizeof(MapleFileProf)); + for (uint32 item = 0; item < metaProf->num; ++item, ++strItem) { reflectionStrData.insert(std::make_pair(strMap.at(strItem->idx), strItem->type)); } } - offset += sizeof(MapleFileProf) + sizeof(ReflectionStrItem) * (metaProf->num - 1); + offset += sizeof(MapleFileProf) + metaProf->size; } } @@ -269,6 +325,12 @@ bool Profile::DeCompress(const std::string &path, const std::string &dexNameInne case kLiteral: ParseLiteral(proFileData,strBuf); break; + case kBBInfo: + ParseIRFuncDesc(proFileData, profileDataInfo->mapleFileNum); + break; + case kIRCounter: + ParseCounterTab(proFileData, profileDataInfo->mapleFileNum); + break; case kFileDesc: { uint32_t appPackageNameIdx = *reinterpret_cast(proFileData); this->appPackageName = strMap.at(appPackageNameIdx); @@ -394,6 +456,15 @@ const std::unordered_map& Profile::GetFunctionPr return funcProfData; } +bool Profile::GetFunctionBBProf(const std::string &funcName, Profile::BBInfo &result) { + auto item = funcBBProfData.find(funcName); + if (item == funcBBProfData.end()) { + return false; + } + result = item->second; + return true; +} + std::unordered_set &Profile::GetMeta(uint8 type) { switch (type) { case kClassMeta: diff --git a/src/mpl2mpl/include/analyzector.h b/src/mpl2mpl/include/analyzector.h index f30c274c4eaaac47881663f43a90eb3db582890e..2178435152f38bd16afc7be4e6111f0e174122d9 100644 --- a/src/mpl2mpl/include/analyzector.h +++ b/src/mpl2mpl/include/analyzector.h @@ -19,7 +19,7 @@ namespace maple { class AnalyzeCtor : public FuncOptimizeImpl { public: - AnalyzeCtor(MIRModule *mod, KlassHierarchy *kh, bool trace) : FuncOptimizeImpl(mod, kh, trace) {} + AnalyzeCtor(MIRModule &mod, KlassHierarchy *kh, bool trace) : FuncOptimizeImpl(mod, kh, trace) {} ~AnalyzeCtor() = default; FuncOptimizeImpl *Clone() override { @@ -30,9 +30,9 @@ class AnalyzeCtor : public FuncOptimizeImpl { void Finish() override; private: + void ProcessStmt(StmtNode&) override; bool hasSideEffect = false; std::unordered_set fieldSet; - void ProcessStmt(StmtNode&) override; }; class DoAnalyzeCtor : public ModulePhase { diff --git a/src/mpl2mpl/include/class_init.h b/src/mpl2mpl/include/class_init.h index 007240d224c1ec3b82739578fced8a82937be3e3..10ca430a350899f94551d5a7f6d7101c83d3e8aa 100644 --- a/src/mpl2mpl/include/class_init.h +++ b/src/mpl2mpl/include/class_init.h @@ -21,7 +21,7 @@ namespace maple { class ClassInit : public FuncOptimizeImpl { public: - ClassInit(MIRModule *mod, KlassHierarchy *kh, bool dump) : FuncOptimizeImpl(mod, kh, dump) {} + ClassInit(MIRModule &mod, KlassHierarchy *kh, bool dump) : FuncOptimizeImpl(mod, kh, dump) {} ~ClassInit() = default; FuncOptimizeImpl *Clone() override { diff --git a/src/mpl2mpl/include/coderelayout.h b/src/mpl2mpl/include/coderelayout.h index 5549359addd166b726bf8d1fa916d36a3b1f0708..8be4c99076480793b0bddfaa6f4bd2b87eb0c33c 100644 --- a/src/mpl2mpl/include/coderelayout.h +++ b/src/mpl2mpl/include/coderelayout.h @@ -22,7 +22,7 @@ namespace maple { class CodeReLayout : public FuncOptimizeImpl { public: - CodeReLayout(MIRModule *mod, KlassHierarchy *kh, bool dump); + CodeReLayout(MIRModule &mod, KlassHierarchy *kh, bool dump); ~CodeReLayout() = default; FuncOptimizeImpl *Clone() override { @@ -33,11 +33,6 @@ class CodeReLayout : public FuncOptimizeImpl { void Finish() override; private: - const std::string exeFuncTag = "executedFuncStart"; - const std::string profileStartTag = "#profile_start"; - const std::string profileSummaryTag = "#profile_summary"; - std::unordered_map str2SymMap; - uint32 layoutCount[static_cast(LayoutType::kLayoutTypeCount)] = {}; std::string StaticFieldFilename(const std::string &mplFile) const; void GenLayoutSym(); void AddStaticFieldRecord(); @@ -46,6 +41,11 @@ class CodeReLayout : public FuncOptimizeImpl { void InsertProfileBeforeDread(const StmtNode *stmt, BaseNode *opnd); MIRSymbol *GetorCreateStaticFieldSym(const std::string &fieldName); MIRSymbol *GenStrSym(const std::string &str); + const std::string exeFuncTag = "executedFuncStart"; + const std::string profileStartTag = "#profile_start"; + const std::string profileSummaryTag = "#profile_summary"; + std::unordered_map str2SymMap; + uint32 layoutCount[static_cast(LayoutType::kLayoutTypeCount)] = {}; }; class DoCodeReLayout : public ModulePhase { diff --git a/src/mpl2mpl/include/constantfold.h b/src/mpl2mpl/include/constantfold.h index 8bea0dc5d70f840717bf37fd641a712277b1fcd8..914738c18b010d7c33c03621eb34e392f74ccf6c 100644 --- a/src/mpl2mpl/include/constantfold.h +++ b/src/mpl2mpl/include/constantfold.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2019] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. @@ -21,6 +21,10 @@ namespace maple { class ConstantFold : public FuncOptimizeImpl { public: + ConstantFold(MIRModule &mod, KlassHierarchy *kh, bool trace) : FuncOptimizeImpl(mod, kh, trace), mirModule(&mod) {} + + explicit ConstantFold(MIRModule &mod) : FuncOptimizeImpl(mod, nullptr, false), mirModule(&mod) {} + // Fold an expression. // // It returns a new expression if there was something to fold, or @@ -34,10 +38,6 @@ class ConstantFold : public FuncOptimizeImpl { // simplification, it returns nullptr. StmtNode *Simplify(StmtNode *node); - ConstantFold(MIRModule *mod, KlassHierarchy *kh, bool trace) : FuncOptimizeImpl(mod, kh, trace), mirModule(mod) {} - - ConstantFold(MIRModule *mod) : FuncOptimizeImpl(mod, nullptr, false), mirModule(mod) {} - FuncOptimizeImpl *Clone() { return new ConstantFold(*this); } @@ -45,14 +45,13 @@ class ConstantFold : public FuncOptimizeImpl { void ProcessFunc(MIRFunction *func); virtual ~ConstantFold() = default; - MIRConst *FoldFloorMIRConst(const MIRConst*, PrimType, PrimType) const; - MIRConst *FoldRoundMIRConst(const MIRConst*, PrimType, PrimType) const; - MIRConst *FoldTypeCvtMIRConst(const MIRConst*, PrimType, PrimType) const; - MIRConst *FoldSignExtendMIRConst(Opcode, PrimType, uint8, const MIRConst*) const; + MIRConst *FoldFloorMIRConst(const MIRConst&, PrimType, PrimType) const; + MIRConst *FoldRoundMIRConst(const MIRConst&, PrimType, PrimType) const; + MIRConst *FoldTypeCvtMIRConst(const MIRConst&, PrimType, PrimType) const; + MIRConst *FoldSignExtendMIRConst(Opcode, PrimType, uint8, const MIRConst&) const; MIRConst *FoldConstComparisonMIRConst(Opcode, PrimType, PrimType, const MIRConst&, const MIRConst&); private: - MIRModule *mirModule; StmtNode *SimplifyBinary(BinaryStmtNode *node); StmtNode *SimplifyBlock(BlockNode *node); StmtNode *SimplifyCondGoto(CondGotoNode *node); @@ -71,7 +70,7 @@ class ConstantFold : public FuncOptimizeImpl { std::pair FoldCompare(CompareNode *node); std::pair FoldDepositbits(DepositbitsNode *node); std::pair FoldExtractbits(ExtractbitsNode *node); - ConstvalNode *FoldSignExtend(Opcode opcode, PrimType resultType, uint8 size, const ConstvalNode *cst) const; + ConstvalNode *FoldSignExtend(Opcode opcode, PrimType resultType, uint8 size, const ConstvalNode &cst) const; std::pair FoldIread(IreadNode *node); std::pair FoldSizeoftype(SizeoftypeNode *node) const; std::pair FoldRetype(RetypeNode *node); @@ -79,11 +78,11 @@ class ConstantFold : public FuncOptimizeImpl { std::pair FoldUnary(UnaryNode *node); std::pair FoldTernary(TernaryNode *node); std::pair FoldTypeCvt(TypeCvtNode *node); - ConstvalNode *FoldCeil(const ConstvalNode *cst, PrimType fromType, PrimType toType) const; - ConstvalNode *FoldFloor(const ConstvalNode *cst, PrimType fromType, PrimType toType) const; - ConstvalNode *FoldRound(const ConstvalNode *cst, PrimType fromType, PrimType toType) const; - ConstvalNode *FoldTrunk(const ConstvalNode *cst, PrimType fromType, PrimType toType) const; - ConstvalNode *FoldTypeCvt(const ConstvalNode *cst, PrimType fromType, PrimType toType) const; + ConstvalNode *FoldCeil(const ConstvalNode &cst, PrimType fromType, PrimType toType) const; + ConstvalNode *FoldFloor(const ConstvalNode &cst, PrimType fromType, PrimType toType) const; + ConstvalNode *FoldRound(const ConstvalNode &cst, PrimType fromType, PrimType toType) const; + ConstvalNode *FoldTrunk(const ConstvalNode &cst, PrimType fromType, PrimType toType) const; + ConstvalNode *FoldTypeCvt(const ConstvalNode &cst, PrimType fromType, PrimType toType) const; ConstvalNode *FoldConstComparison(Opcode opcode, PrimType resultType, PrimType opndType, const ConstvalNode &const0, const ConstvalNode &const1) const; ConstvalNode *FoldConstBinary(Opcode opcode, PrimType resultType, const ConstvalNode &const0, @@ -112,6 +111,7 @@ class ConstantFold : public FuncOptimizeImpl { std::pair DispatchFold(BaseNode *node); BaseNode *PairToExpr(PrimType resultType, const std::pair &pair) const; BaseNode *SimplifyDoubleCompare(CompareNode &node) const; + MIRModule *mirModule; }; class DoConstantFold : public ModulePhase { diff --git a/src/mpl2mpl/include/gen_check_cast.h b/src/mpl2mpl/include/gen_check_cast.h index dea7a64ef29bd1857921fa68b18d4432e1bcdf5d..f5962cd845a8ee312c42a8d18dc2e6bac0693618 100644 --- a/src/mpl2mpl/include/gen_check_cast.h +++ b/src/mpl2mpl/include/gen_check_cast.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2019] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. @@ -22,7 +22,7 @@ namespace maple { class CheckCastGenerator : public FuncOptimizeImpl { public: - CheckCastGenerator(MIRModule *mod, KlassHierarchy *kh, bool dump); + CheckCastGenerator(MIRModule &mod, KlassHierarchy *kh, bool dump); ~CheckCastGenerator() {} FuncOptimizeImpl *Clone() override { diff --git a/src/mpl2mpl/include/java_intrn_lowering.h b/src/mpl2mpl/include/java_intrn_lowering.h index 9fccb8e065223d541d04ecdc7cee578e9ca07f5f..2aee6967f36f9a3e3b7981eb101ce032c8ed2599 100644 --- a/src/mpl2mpl/include/java_intrn_lowering.h +++ b/src/mpl2mpl/include/java_intrn_lowering.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2019] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. @@ -22,7 +22,7 @@ namespace maple { class JavaIntrnLowering : public FuncOptimizeImpl { public: - JavaIntrnLowering(MIRModule *mod, KlassHierarchy *kh, bool dump); + JavaIntrnLowering(MIRModule &mod, KlassHierarchy *kh, bool dump); ~JavaIntrnLowering() = default; FuncOptimizeImpl *Clone() override { diff --git a/src/mpl2mpl/include/muid_replacement.h b/src/mpl2mpl/include/muid_replacement.h index cf22a78bd1a3dac567e05e254d7b4644d6caab63..01a3572e5fd96029f47e467ee288fda1ba42b66a 100644 --- a/src/mpl2mpl/include/muid_replacement.h +++ b/src/mpl2mpl/include/muid_replacement.h @@ -57,7 +57,7 @@ enum RangeIdx { class MUIDReplacement : public FuncOptimizeImpl { public: - MUIDReplacement(MIRModule *mod, KlassHierarchy *kh, bool dump); + MUIDReplacement(MIRModule &mod, KlassHierarchy *kh, bool dump); ~MUIDReplacement() = default; FuncOptimizeImpl *Clone() override { @@ -82,6 +82,8 @@ class MUIDReplacement : public FuncOptimizeImpl { kRadicalLazyBinding = 2 }; + void InitRangeTabUseSym(std::vector &workList, MIRStructType &rangeTabEntryType, + MIRAggConst &rangeTabConst); void GenerateTables(); void GenerateFuncDefTable(); void GenerateDataDefTable(); @@ -158,6 +160,7 @@ class MUIDReplacement : public FuncOptimizeImpl { MIRSymbol *funcMuidIdxTabSym = nullptr; MIRSymbol *rangeTabSym = nullptr; MIRSymbol *funcProfileTabSym = nullptr; + MIRSymbol *funcProfInfTabSym = nullptr; std::map funcDefMap; std::map dataDefMap; std::map funcUndefMap; diff --git a/src/mpl2mpl/include/native_stub_func.h b/src/mpl2mpl/include/native_stub_func.h index bb74a8a0939d9fd4c73d2066ebf301cfeef9e97b..be6c55cad938cbdcfdc37abb78abf361022785be 100644 --- a/src/mpl2mpl/include/native_stub_func.h +++ b/src/mpl2mpl/include/native_stub_func.h @@ -55,7 +55,7 @@ class NativeFuncProperty { class NativeStubFuncGeneration : public FuncOptimizeImpl { public: - NativeStubFuncGeneration(MIRModule *mod, KlassHierarchy *kh, bool dump); + NativeStubFuncGeneration(MIRModule &mod, KlassHierarchy *kh, bool dump); ~NativeStubFuncGeneration() = default; void ProcessFunc(MIRFunction *func) override; diff --git a/src/mpl2mpl/include/reflection_analysis.h b/src/mpl2mpl/include/reflection_analysis.h index f9233ca7762fe126a86c854dc900b5fa1da6adfc..f157d4f7ff8af822939e7ce719c15e61bb4160ff 100644 --- a/src/mpl2mpl/include/reflection_analysis.h +++ b/src/mpl2mpl/include/reflection_analysis.h @@ -54,6 +54,9 @@ enum class ClassProperty : uint32 { kVtab, kGctib, kInfoRo, +#ifdef USE_32BIT_REF + kInstanceOfCacheFalse, +#endif kClint }; @@ -197,11 +200,11 @@ class ReflectionAnalysis : public AnalysisResult { static void GenMetadataType(MIRModule &mirModule); static MIRType *GetRefFieldType(); static TyIdx GenMetaStructType(MIRModule &mirModule, MIRStructType &metaType, const std::string &str); - int64 GetHashIndex(const std::string &strName); + uint32 GetHashIndex(const std::string &strName); static void GenHotClassNameString(const Klass &klass); uint32 FindOrInsertReflectString(const std::string &str); static void InitReflectString(); - int64 BKDRHash(const std::string &strName, uint32 seed); + uint32 BKDRHash(const std::string &strName, uint32 seed); void GenClassHashMetaData(); void MarkWeakMethods(); diff --git a/src/mpl2mpl/include/vtable_analysis.h b/src/mpl2mpl/include/vtable_analysis.h index ebba5c02bfb3baab60a39018576507a0f4291ea5..da1477be93bdc6bf5f74516349ffd39b6b207e51 100644 --- a/src/mpl2mpl/include/vtable_analysis.h +++ b/src/mpl2mpl/include/vtable_analysis.h @@ -28,7 +28,7 @@ constexpr unsigned int kShiftCountBit = 8 * 4; // Get the low 32bit class VtableAnalysis : public FuncOptimizeImpl { public: - VtableAnalysis(MIRModule *mod, KlassHierarchy *kh, bool dump); + VtableAnalysis(MIRModule &mod, KlassHierarchy *kh, bool dump); ~VtableAnalysis() = default; static std::string DecodeBaseNameWithType(const MIRFunction &func); static bool IsVtableCandidate(const MIRFunction &func); diff --git a/src/mpl2mpl/include/vtable_impl.h b/src/mpl2mpl/include/vtable_impl.h index afbf28acf9f47cf512bf7cfc2c9224c0decf829c..72cc896949706737904b0c295fb217f4878c5b27 100644 --- a/src/mpl2mpl/include/vtable_impl.h +++ b/src/mpl2mpl/include/vtable_impl.h @@ -27,7 +27,7 @@ enum CallKind { class VtableImpl : public FuncOptimizeImpl { public: - VtableImpl(MIRModule *mod, KlassHierarchy *kh, bool dump); + VtableImpl(MIRModule &mod, KlassHierarchy *kh, bool dump); ~VtableImpl() = default; void ProcessFunc(MIRFunction *func) override; diff --git a/src/mpl2mpl/src/coderelayout.cpp b/src/mpl2mpl/src/coderelayout.cpp index ee3c0b315c6e66b05cedfcebdfcaca66fb6ca6b2..914afa99c72df0e2de06966ae75dc6167f244bf5 100644 --- a/src/mpl2mpl/src/coderelayout.cpp +++ b/src/mpl2mpl/src/coderelayout.cpp @@ -25,7 +25,7 @@ // 2.both-hot function which is hot in phone run phase and phone boot phase // 3.run-hot function which is only hot in phone run phase // Every functon have just one layout type,layout the function -// together according there layout type.Currently the layout is below +// together according there layout type.Currently the layout is below // // [BootHot] // [BothHot] @@ -35,7 +35,7 @@ // [Executed] function excuted in some condition // [Unused] namespace maple { -CodeReLayout::CodeReLayout(MIRModule *mod, KlassHierarchy *kh, bool dump) : FuncOptimizeImpl(mod, kh, dump) { +CodeReLayout::CodeReLayout(MIRModule &mod, KlassHierarchy *kh, bool dump) : FuncOptimizeImpl(mod, kh, dump) { if (!Options::proFileData.empty()) { size_t pos = 0; if ((pos = Options::proFileData.find(':')) != std::string::npos) { @@ -185,7 +185,11 @@ void CodeReLayout::Finish() { } } std::stable_sort(GetMIRModule().GetFunctionList().begin(), GetMIRModule().GetFunctionList().end(), - [](const MIRFunction *a, const MIRFunction *b) { return a->GetLayoutType() < b->GetLayoutType(); }); + [](const MIRFunction *a, const MIRFunction *b) { + ASSERT_NOT_NULL(a); + ASSERT_NOT_NULL(b); + return a->GetLayoutType() < b->GetLayoutType(); + }); uint32 last = 0; for (uint32 i = 0; i <= static_cast(LayoutType::kLayoutRunHot); i++) { if (trace) { @@ -193,7 +197,11 @@ void CodeReLayout::Finish() { } std::stable_sort(GetMIRModule().GetFunctionList().begin() + last, GetMIRModule().GetFunctionList().begin() + last + layoutCount[i], - [](const MIRFunction *a, const MIRFunction *b) { return a->GetCallTimes() < b->GetCallTimes(); }); + [](const MIRFunction *a, const MIRFunction *b) { + ASSERT_NOT_NULL(a); + ASSERT_NOT_NULL(b); + return a->GetCallTimes() < b->GetCallTimes(); + }); last += layoutCount[i]; } // Create layoutInfo diff --git a/src/mpl2mpl/src/constantfold.cpp b/src/mpl2mpl/src/constantfold.cpp index a37652fff116cd092289ae83393077003d97e683..35b4a427228df8ccacedc6dc1754073cd6293b53 100644 --- a/src/mpl2mpl/src/constantfold.cpp +++ b/src/mpl2mpl/src/constantfold.cpp @@ -560,14 +560,14 @@ ConstvalNode *ConstantFold::FoldFPConstBinary(Opcode opcode, PrimType resultType CHECK_NULL_FATAL(floatConst0); CHECK_NULL_FATAL(floatConst1); } - float constValuefloat = 0.0; + float constValueFloat = 0.0; double constValueDouble = 0.0; switch (opcode) { case OP_add: { if (useDouble) { constValueDouble = doubleConst0->GetValue() + doubleConst1->GetValue(); } else { - constValuefloat = floatConst0->GetValue() + floatConst1->GetValue(); + constValueFloat = floatConst0->GetValue() + floatConst1->GetValue(); } break; } @@ -575,7 +575,7 @@ ConstvalNode *ConstantFold::FoldFPConstBinary(Opcode opcode, PrimType resultType if (useDouble) { constValueDouble = doubleConst0->GetValue() - doubleConst1->GetValue(); } else { - constValuefloat = floatConst0->GetValue() - floatConst1->GetValue(); + constValueFloat = floatConst0->GetValue() - floatConst1->GetValue(); } break; } @@ -583,7 +583,7 @@ ConstvalNode *ConstantFold::FoldFPConstBinary(Opcode opcode, PrimType resultType if (useDouble) { constValueDouble = doubleConst0->GetValue() * doubleConst1->GetValue(); } else { - constValuefloat = floatConst0->GetValue() * floatConst1->GetValue(); + constValueFloat = floatConst0->GetValue() * floatConst1->GetValue(); } break; } @@ -592,7 +592,7 @@ ConstvalNode *ConstantFold::FoldFPConstBinary(Opcode opcode, PrimType resultType if (useDouble) { constValueDouble = doubleConst0->GetValue() / doubleConst1->GetValue(); } else { - constValuefloat = floatConst0->GetValue() / floatConst1->GetValue(); + constValueFloat = floatConst0->GetValue() / floatConst1->GetValue(); } break; } @@ -601,7 +601,7 @@ ConstvalNode *ConstantFold::FoldFPConstBinary(Opcode opcode, PrimType resultType constValueDouble = (doubleConst0->GetValue() >= doubleConst1->GetValue()) ? doubleConst0->GetValue() : doubleConst1->GetValue(); } else { - constValuefloat = (floatConst0->GetValue() >= floatConst1->GetValue()) ? floatConst0->GetValue() + constValueFloat = (floatConst0->GetValue() >= floatConst1->GetValue()) ? floatConst0->GetValue() : floatConst1->GetValue(); } break; @@ -611,7 +611,7 @@ ConstvalNode *ConstantFold::FoldFPConstBinary(Opcode opcode, PrimType resultType constValueDouble = (doubleConst0->GetValue() <= doubleConst1->GetValue()) ? doubleConst0->GetValue() : doubleConst1->GetValue(); } else { - constValuefloat = (floatConst0->GetValue() <= floatConst1->GetValue()) ? floatConst0->GetValue() + constValueFloat = (floatConst0->GetValue() <= floatConst1->GetValue()) ? floatConst0->GetValue() : floatConst1->GetValue(); } break; @@ -638,7 +638,7 @@ ConstvalNode *ConstantFold::FoldFPConstBinary(Opcode opcode, PrimType resultType if (resultType == PTY_f64) { resultConst->SetConstVal(GlobalTables::GetFpConstTable().GetOrCreateDoubleConst(constValueDouble)); } else { - resultConst->SetConstVal(GlobalTables::GetFpConstTable().GetOrCreateFloatConst(constValuefloat)); + resultConst->SetConstVal(GlobalTables::GetFpConstTable().GetOrCreateFloatConst(constValueFloat)); } return resultConst; } @@ -1012,19 +1012,18 @@ std::pair ConstantFold::FoldUnary(UnaryNode *node) { return std::make_pair(result, sum); } -ConstvalNode *ConstantFold::FoldCeil(const ConstvalNode *cst, PrimType fromType, PrimType toType) const { +ConstvalNode *ConstantFold::FoldCeil(const ConstvalNode &cst, PrimType fromType, PrimType toType) const { ConstvalNode *resultConst = mirModule->CurFuncCodeMemPool()->New(); resultConst->SetPrimType(toType); MIRType &resultType = *GlobalTables::GetTypeTable().GetPrimType(toType); - CHECK_NULL_FATAL(cst); if (fromType == PTY_f32) { - const MIRFloatConst *constValue = safe_cast(cst->GetConstVal()); + const MIRFloatConst *constValue = safe_cast(cst.GetConstVal()); ASSERT_NOT_NULL(constValue); - float floutValue = ceil(constValue->GetValue()); + float floatValue = ceil(constValue->GetValue()); resultConst->SetConstVal(GlobalTables::GetIntConstTable().GetOrCreateIntConst( - static_cast(floutValue), resultType)); + static_cast(floatValue), resultType)); } else { - const MIRDoubleConst *constValue = safe_cast(cst->GetConstVal()); + const MIRDoubleConst *constValue = safe_cast(cst.GetConstVal()); ASSERT_NOT_NULL(constValue); double doubleValue = ceil(constValue->GetValue()); resultConst->SetConstVal(GlobalTables::GetIntConstTable().GetOrCreateIntConst( @@ -1033,53 +1032,46 @@ ConstvalNode *ConstantFold::FoldCeil(const ConstvalNode *cst, PrimType fromType, return resultConst; } -MIRConst *ConstantFold::FoldFloorMIRConst(const MIRConst *cst, PrimType fromType, PrimType toType) const { +MIRConst *ConstantFold::FoldFloorMIRConst(const MIRConst &cst, PrimType fromType, PrimType toType) const { MIRType &resultType = *GlobalTables::GetTypeTable().GetPrimType(toType); - CHECK_NULL_FATAL(cst); if (fromType == PTY_f32) { - const MIRFloatConst *constValue = safe_cast(cst); - ASSERT_NOT_NULL(constValue); - float floutValue = floor(constValue->GetValue()); + const auto &constValue = static_cast(cst); + float floutValue = floor(constValue.GetValue()); return GlobalTables::GetIntConstTable().GetOrCreateIntConst(static_cast(floutValue), resultType); } else { - const MIRDoubleConst *constValue = safe_cast(cst); - ASSERT_NOT_NULL(constValue); - double doubleValue = floor(constValue->GetValue()); + const auto &constValue = static_cast(cst); + double doubleValue = floor(constValue.GetValue()); return GlobalTables::GetIntConstTable().GetOrCreateIntConst(static_cast(doubleValue), resultType); } } -ConstvalNode *ConstantFold::FoldFloor(const ConstvalNode *cst, PrimType fromType, PrimType toType) const { +ConstvalNode *ConstantFold::FoldFloor(const ConstvalNode &cst, PrimType fromType, PrimType toType) const { ConstvalNode *resultConst = mirModule->CurFuncCodeMemPool()->New(); resultConst->SetPrimType(toType); - resultConst->SetConstVal(FoldFloorMIRConst(cst->GetConstVal(), fromType, toType)); + resultConst->SetConstVal(FoldFloorMIRConst(*cst.GetConstVal(), fromType, toType)); return resultConst; } -MIRConst *ConstantFold::FoldRoundMIRConst(const MIRConst *cst, PrimType fromType, PrimType toType) const { +MIRConst *ConstantFold::FoldRoundMIRConst(const MIRConst &cst, PrimType fromType, PrimType toType) const { MIRType &resultType = *GlobalTables::GetTypeTable().GetPrimType(toType); if (fromType == PTY_f32) { - const MIRFloatConst *constValue = safe_cast(cst); - ASSERT_NOT_NULL(constValue); - float floatValue = round(constValue->GetValue()); + const auto &constValue = static_cast(cst); + float floatValue = round(constValue.GetValue()); return GlobalTables::GetIntConstTable().GetOrCreateIntConst(static_cast(floatValue), resultType); } else if (fromType == PTY_f64) { - const MIRDoubleConst *constValue = safe_cast(cst); - ASSERT_NOT_NULL(constValue); - double doubleValue = round(constValue->GetValue()); + const auto &constValue = static_cast(cst); + double doubleValue = round(constValue.GetValue()); return GlobalTables::GetIntConstTable().GetOrCreateIntConst(static_cast(doubleValue), resultType); } else if (toType == PTY_f32 && IsPrimitiveInteger(fromType)) { - const MIRIntConst *constValue = safe_cast(cst); - ASSERT_NOT_NULL(constValue); - int64 fromValue = constValue->GetValue(); + const auto &constValue = static_cast(cst); + int64 fromValue = constValue.GetValue(); float floatValue = round(static_cast(fromValue)); if (static_cast(floatValue) == fromValue) { return GlobalTables::GetFpConstTable().GetOrCreateFloatConst(floatValue); } } else if (toType == PTY_f64 && IsPrimitiveInteger(fromType)) { - const MIRIntConst *constValue = safe_cast(cst); - ASSERT_NOT_NULL(constValue); - int64 fromValue = constValue->GetValue(); + const auto &constValue = static_cast(cst); + int64 fromValue = constValue.GetValue(); double doubleValue = round(static_cast(fromValue)); if (static_cast(doubleValue) == fromValue) { return GlobalTables::GetFpConstTable().GetOrCreateDoubleConst(doubleValue); @@ -1088,27 +1080,25 @@ MIRConst *ConstantFold::FoldRoundMIRConst(const MIRConst *cst, PrimType fromType return nullptr; } -ConstvalNode *ConstantFold::FoldRound(const ConstvalNode *cst, PrimType fromType, PrimType toType) const { +ConstvalNode *ConstantFold::FoldRound(const ConstvalNode &cst, PrimType fromType, PrimType toType) const { ConstvalNode *resultConst = mirModule->CurFuncCodeMemPool()->New(); resultConst->SetPrimType(toType); - CHECK_NULL_FATAL(cst); - resultConst->SetConstVal(FoldRoundMIRConst(cst->GetConstVal(), fromType, toType)); + resultConst->SetConstVal(FoldRoundMIRConst(*cst.GetConstVal(), fromType, toType)); return resultConst; } -ConstvalNode *ConstantFold::FoldTrunk(const ConstvalNode *cst, PrimType fromType, PrimType toType) const { +ConstvalNode *ConstantFold::FoldTrunk(const ConstvalNode &cst, PrimType fromType, PrimType toType) const { ConstvalNode *resultConst = mirModule->CurFuncCodeMemPool()->New(); resultConst->SetPrimType(toType); MIRType &resultType = *GlobalTables::GetTypeTable().GetPrimType(toType); - CHECK_NULL_FATAL(cst); if (fromType == PTY_f32) { - const MIRFloatConst *constValue = safe_cast(cst->GetConstVal()); + const MIRFloatConst *constValue = safe_cast(cst.GetConstVal()); CHECK_NULL_FATAL(constValue); float floutValue = trunc(constValue->GetValue()); resultConst->SetConstVal(GlobalTables::GetIntConstTable().GetOrCreateIntConst( static_cast(floutValue), resultType)); } else { - const MIRDoubleConst *constValue = safe_cast(cst->GetConstVal()); + const MIRDoubleConst *constValue = safe_cast(cst.GetConstVal()); CHECK_NULL_FATAL(constValue); double doubleValue = trunc(constValue->GetValue()); resultConst->SetConstVal(GlobalTables::GetIntConstTable().GetOrCreateIntConst( @@ -1117,7 +1107,7 @@ ConstvalNode *ConstantFold::FoldTrunk(const ConstvalNode *cst, PrimType fromType return resultConst; } -MIRConst *ConstantFold::FoldTypeCvtMIRConst(const MIRConst *cst, PrimType fromType, PrimType toType) const { +MIRConst *ConstantFold::FoldTypeCvtMIRConst(const MIRConst &cst, PrimType fromType, PrimType toType) const { if (IsPrimitiveDynType(fromType) || IsPrimitiveDynType(toType)) { // do not fold return nullptr; @@ -1169,9 +1159,8 @@ MIRConst *ConstantFold::FoldTypeCvtMIRConst(const MIRConst *cst, PrimType fromTy return nullptr; } -ConstvalNode *ConstantFold::FoldTypeCvt(const ConstvalNode *cst, PrimType fromType, PrimType toType) const { - CHECK_NULL_FATAL(cst); - MIRConst *toConstValue = FoldTypeCvtMIRConst(cst->GetConstVal(), fromType, toType); +ConstvalNode *ConstantFold::FoldTypeCvt(const ConstvalNode &cst, PrimType fromType, PrimType toType) const { + MIRConst *toConstValue = FoldTypeCvtMIRConst(*cst.GetConstVal(), fromType, toType); if (toConstValue == nullptr) { return nullptr; } @@ -1189,23 +1178,23 @@ std::pair ConstantFold::FoldTypeCvt(TypeCvtNode *node) { if (cst != nullptr) { switch (node->GetOpCode()) { case OP_ceil: { - result = FoldCeil(cst, node->FromType(), node->GetPrimType()); + result = FoldCeil(*cst, node->FromType(), node->GetPrimType()); break; } case OP_cvt: { - result = FoldTypeCvt(cst, node->FromType(), node->GetPrimType()); + result = FoldTypeCvt(*cst, node->FromType(), node->GetPrimType()); break; } case OP_floor: { - result = FoldFloor(cst, node->FromType(), node->GetPrimType()); + result = FoldFloor(*cst, node->FromType(), node->GetPrimType()); break; } case OP_round: { - result = FoldRound(cst, node->FromType(), node->GetPrimType()); + result = FoldRound(*cst, node->FromType(), node->GetPrimType()); break; } case OP_trunc: { - result = FoldTrunk(cst, node->FromType(), node->GetPrimType()); + result = FoldTrunk(*cst, node->FromType(), node->GetPrimType()); break; } default: @@ -1228,7 +1217,7 @@ std::pair ConstantFold::FoldTypeCvt(TypeCvtNode *node) { } MIRConst *ConstantFold::FoldSignExtendMIRConst(Opcode opcode, PrimType resultType, uint8 size, - const MIRConst *cst) const { + const MIRConst &cst) const { const MIRIntConst *constVal = safe_cast(cst); ASSERT_NOT_NULL(constVal); uint64 result64 = 0; @@ -1243,10 +1232,9 @@ MIRConst *ConstantFold::FoldSignExtendMIRConst(Opcode opcode, PrimType resultTyp } ConstvalNode *ConstantFold::FoldSignExtend(Opcode opcode, PrimType resultType, uint8 size, - const ConstvalNode *cst) const { + const ConstvalNode &cst) const { ConstvalNode *resultConst = mirModule->CurFuncCodeMemPool()->New(); - CHECK_NULL_FATAL(cst); - MIRConst *toConst = FoldSignExtendMIRConst(opcode, resultType, size, cst->GetConstVal()); + MIRConst *toConst = FoldSignExtendMIRConst(opcode, resultType, size, *cst.GetConstVal()); resultConst->SetPrimType(toConst->GetType().GetPrimType()); resultConst->SetConstVal(toConst); return resultConst; @@ -1262,7 +1250,7 @@ std::pair ConstantFold::FoldExtractbits(ExtractbitsNode *node) std::pair p = DispatchFold(node->Opnd(0)); ConstvalNode *cst = safe_cast(p.first); if (cst != nullptr && (opcode == OP_sext || opcode == OP_zext)) { - result = FoldSignExtend(opcode, node->GetPrimType(), size, cst); + result = FoldSignExtend(opcode, node->GetPrimType(), size, *cst); } else { BaseNode *e = PairToExpr(node->Opnd(0)->GetPrimType(), p); if (e != node->Opnd(0)) { @@ -1325,15 +1313,15 @@ std::pair ConstantFold::FoldBinary(BinaryNode *node) { ConstvalNode *rConst = safe_cast(r); bool isInt = IsPrimitiveInteger(primType); if (lConst != nullptr && rConst != nullptr) { - MIRIntConst *lConstVal = safe_cast(lConst->GetConstVal()); - MIRIntConst *rConstVal = safe_cast(rConst->GetConstVal()); + MIRConst *lConstVal = lConst->GetConstVal(); + MIRConst *rConstVal = rConst->GetConstVal(); ASSERT_NOT_NULL(lConstVal); ASSERT_NOT_NULL(rConstVal); // Don't fold div by 0, for floats div by 0 is well defined. if ((op == OP_div || op == OP_rem) && isInt && - (rConstVal->GetValue() == 0 || - lConstVal->GetValue() == LONG_MIN || - lConstVal->GetValue() == INT_MIN)) { + (static_cast(rConstVal)->GetValue() == 0 || + static_cast(lConstVal)->GetValue() == LONG_MIN || + static_cast(lConstVal)->GetValue() == INT_MIN)) { result = NewBinaryNode(node, op, primType, lConst, rConst); sum = 0; } else { @@ -1751,9 +1739,11 @@ StmtNode *ConstantFold::SimplifyIassign(IassignNode *node) { if (returnValue != nullptr) { node->SetRHS(returnValue); } - switch (node->Opnd(0)->GetOpCode()) { + auto *opnd = node->Opnd(0); + ASSERT_NOT_NULL(opnd); + switch (opnd->GetOpCode()) { case OP_addrof: { - AddrofNode *addrofNode = static_cast(node->Opnd(0)); + AddrofNode *addrofNode = static_cast(opnd); DassignNode *dassignNode = mirModule->CurFuncCodeMemPool()->New(); dassignNode->SetStIdx(addrofNode->GetStIdx()); dassignNode->SetRHS(node->GetRHS()); @@ -1761,7 +1751,7 @@ StmtNode *ConstantFold::SimplifyIassign(IassignNode *node) { return dassignNode; } case OP_iaddrof: { - IreadNode *iaddrofNode = static_cast(node->Opnd(0)); + IreadNode *iaddrofNode = static_cast(opnd); if (iaddrofNode->Opnd(0)->GetOpCode() == OP_dread) { AddrofNode *dreadNode = static_cast(iaddrofNode->Opnd(0)); node->SetFieldID(node->GetFieldID() + iaddrofNode->GetFieldID()); diff --git a/src/mpl2mpl/src/gen_check_cast.cpp b/src/mpl2mpl/src/gen_check_cast.cpp index 112c455e13f835c6aff0c16d78711e1f773a1821..2b3cbf1f839de957945fea4de68563413613f78d 100644 --- a/src/mpl2mpl/src/gen_check_cast.cpp +++ b/src/mpl2mpl/src/gen_check_cast.cpp @@ -34,7 +34,7 @@ constexpr char kMCCReflectCheckCastingArray[] = "MCC_Reflect_Check_Casting_Array // before the stmt. // #2 optimise instance-of && cast namespace maple { -CheckCastGenerator::CheckCastGenerator(MIRModule *mod, KlassHierarchy *kh, bool dump) +CheckCastGenerator::CheckCastGenerator(MIRModule &mod, KlassHierarchy *kh, bool dump) : FuncOptimizeImpl(mod, kh, dump) { InitTypes(); InitFuncs(); diff --git a/src/mpl2mpl/src/java_intrn_lowering.cpp b/src/mpl2mpl/src/java_intrn_lowering.cpp index 0ab64f31bdf7b41393a51ca0dcbfa616028ab670..9ea10a31558b8fe6d7d0e91359b8283a8dbb9989 100644 --- a/src/mpl2mpl/src/java_intrn_lowering.cpp +++ b/src/mpl2mpl/src/java_intrn_lowering.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2019] Huawei Technologies Co.,Ltd.All rights reserved. + * Copyright (c) [2019-2020] Huawei Technologies Co.,Ltd.All rights reserved. * * OpenArkCompiler is licensed under the Mulan PSL v1. * You can use this software according to the terms and conditions of the Mulan PSL v1. @@ -31,7 +31,7 @@ inline bool IsConstvalZero(BaseNode &node) { return (node.GetOpCode() == OP_constval) && (static_cast(node).GetConstVal()->IsZero()); } -JavaIntrnLowering::JavaIntrnLowering(MIRModule *mod, KlassHierarchy *kh, bool dump) +JavaIntrnLowering::JavaIntrnLowering(MIRModule &mod, KlassHierarchy *kh, bool dump) : FuncOptimizeImpl(mod, kh, dump) { } diff --git a/src/mpl2mpl/src/muid_replacement.cpp b/src/mpl2mpl/src/muid_replacement.cpp index 1d78e30ddd2c718547ad45cad1e72b0ca2718c74..ed7b2ceccf3c0afe0c3a9c6136e6ea69f6bf6c20 100644 --- a/src/mpl2mpl/src/muid_replacement.cpp +++ b/src/mpl2mpl/src/muid_replacement.cpp @@ -23,8 +23,14 @@ constexpr char kMplLinkerVersionNumber[] = "MPL-LINKER V1.1"; constexpr char kMuidFuncPtrStr[] = "__muid_funcptr"; constexpr char kMuidSymPtrStr[] = "__muid_symptr"; +#ifdef USE_ARM32_MACRO +constexpr maple::uint32 kFromUndefIndexMask = 0x40000000; +constexpr maple::uint32 kFromDefIndexMask = 0x20000000; +#else constexpr maple::uint64 kFromUndefIndexMask = 0x4000000000000000; constexpr maple::uint64 kFromDefIndexMask = 0x2000000000000000; +#endif + } // namespace @@ -39,7 +45,7 @@ constexpr maple::uint64 kFromDefIndexMask = 0x2000000000000000; namespace maple { MUID MUIDReplacement::mplMuid; -MUIDReplacement::MUIDReplacement(MIRModule *mod, KlassHierarchy *kh, bool dump) +MUIDReplacement::MUIDReplacement(MIRModule &mod, KlassHierarchy *kh, bool dump) : FuncOptimizeImpl(mod, kh, dump) { isLibcore = (GetSymbolFromName(NameMangler::GetInternalNameLiteral(NameMangler::kJavaLangObjectStr)) != nullptr); GenerateTables(); @@ -286,6 +292,16 @@ void MUIDReplacement::GenerateFuncDefTable() { *GlobalTables::GetTypeTable().GetUInt32()); auto *funcInfTabEntryType = static_cast(GlobalTables::GetTypeTable().GetOrCreateStructType( "MUIDFuncInfTabEntry", funcinffields, parentFields, GetMIRModule())); + + FieldVector funcProfinffields; + GlobalTables::GetTypeTable().PushIntoFieldVector(funcProfinffields, "hash", + *GlobalTables::GetTypeTable().GetUInt64()); + GlobalTables::GetTypeTable().PushIntoFieldVector(funcProfinffields, "start", + *GlobalTables::GetTypeTable().GetUInt32()); + GlobalTables::GetTypeTable().PushIntoFieldVector(funcProfinffields, "end", + *GlobalTables::GetTypeTable().GetUInt32()); + auto *funcProfInfTabEntryType = static_cast(GlobalTables::GetTypeTable().GetOrCreateStructType( + "FuncProfInfTabEntry", funcProfinffields, parentFields, GetMIRModule())); FieldVector muidFields; #ifdef USE_64BIT_MUID GlobalTables::GetTypeTable().PushIntoFieldVector(muidFields, "muidLow", *GlobalTables::GetTypeTable().GetUInt32()); @@ -303,6 +319,10 @@ void MUIDReplacement::GenerateFuncDefTable() { MIRAggConst *funcInfTabConst = GetMIRModule().GetMemPool()->New(GetMIRModule(), funcInfArrayType); MIRArrayType &muidArrayType = *GlobalTables::GetTypeTable().GetOrCreateArrayType(*funcDefMuidTabEntryType, arraySize); MIRAggConst *funcDefMuidTabConst = GetMIRModule().GetMemPool()->New(GetMIRModule(), muidArrayType); + MIRArrayType &funcProfInfArrayType = + *GlobalTables::GetTypeTable().GetOrCreateArrayType(*funcProfInfTabEntryType, arraySize); + MIRAggConst *funcProfInfTabConst = + GetMIRModule().GetMemPool()->New(GetMIRModule(), funcProfInfArrayType); // Create funcDefSet to store functions sorted by address std::vector> funcDefArray; idx = 0; @@ -330,6 +350,20 @@ void MUIDReplacement::GenerateFuncDefTable() { tempConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst(tempIdx, *GlobalTables::GetTypeTable().GetUInt32()); muidIdxTabConst->SetConstVecItem(idx, *tempConst); + } + if (Options::genIRProfile) { + auto funcProfInf = mirFunc->GetProfInf(); + MIRAggConst *funcProfInfEntryConst = GetMIRModule().GetMemPool()->New(GetMIRModule(), + *funcProfInfTabEntryType); + uint32 funcProfInfFieldID = 1; + + builder->AddIntFieldConst(*funcProfInfTabEntryType, + *funcProfInfEntryConst, funcProfInfFieldID++, funcProfInf->funcHash); + builder->AddIntFieldConst(*funcProfInfTabEntryType, + *funcProfInfEntryConst, funcProfInfFieldID++, funcProfInf->counterStart); + builder->AddIntFieldConst(*funcProfInfTabEntryType, + *funcProfInfEntryConst, funcProfInfFieldID++, funcProfInf->counterEnd); + funcProfInfTabConst->PushBack(funcProfInfEntryConst); } // Store the real idx of funcdefTab, for ReplaceAddroffuncConst->FindIndexFromDefTable defMuidIdxMap[muid] = idx; @@ -390,6 +424,13 @@ void MUIDReplacement::GenerateFuncDefTable() { funcMuidIdxTabSym->SetKonst(muidIdxTabConst); funcMuidIdxTabSym->SetStorageClass(kScFstatic); } + + if (!funcProfInfTabConst->GetConstVec().empty()) { + std::string profInfTabName = NameMangler::kFuncIRProfInfTabPrefixStr + GetMIRModule().GetFileNameAsPostfix(); + funcProfInfTabSym = builder->CreateGlobalDecl(profInfTabName, funcProfInfArrayType); + funcProfInfTabSym->SetKonst(funcProfInfTabConst); + funcProfInfTabSym->SetStorageClass(kScFstatic); + } if (Options::dumpMuidFile) { DumpMUIDFile(true); } @@ -631,6 +672,22 @@ void MUIDReplacement::GenerateUnifiedUndefTable() { } } +void MUIDReplacement::InitRangeTabUseSym(std::vector &workList, MIRStructType &rangeTabEntryType, + MIRAggConst &rangeTabConst) { + for (MIRSymbol *mirSymbol : workList) { + MIRAggConst *entryConst = GetMIRModule().GetMemPool()->New(GetMIRModule(), rangeTabEntryType); + uint32 fieldID = 1; + if (mirSymbol != nullptr) { + builder->AddAddrofFieldConst(rangeTabEntryType, *entryConst, fieldID++, *mirSymbol); + builder->AddAddrofFieldConst(rangeTabEntryType, *entryConst, fieldID++, *mirSymbol); + } else { + builder->AddIntFieldConst(rangeTabEntryType, *entryConst, fieldID++, 0); + builder->AddIntFieldConst(rangeTabEntryType, *entryConst, fieldID++, 0); + } + rangeTabConst.PushBack(entryConst); + } +} + // RangeTable stores begin and end of all MUID tables void MUIDReplacement::GenerateRangeTable() { FieldVector parentFields; @@ -687,18 +744,7 @@ void MUIDReplacement::GenerateRangeTable() { funcMuidIdxTabSym, funcProfileTabSym }; - for (MIRSymbol *mirSymbol : workList) { - MIRAggConst *entryConst = GetMIRModule().GetMemPool()->New(GetMIRModule(), rangeTabEntryType); - uint32 fieldID = 1; - if (mirSymbol != nullptr) { - builder->AddAddrofFieldConst(rangeTabEntryType, *entryConst, fieldID++, *mirSymbol); - builder->AddAddrofFieldConst(rangeTabEntryType, *entryConst, fieldID++, *mirSymbol); - } else { - builder->AddIntFieldConst(rangeTabEntryType, *entryConst, fieldID++, 0); - builder->AddIntFieldConst(rangeTabEntryType, *entryConst, fieldID++, 0); - } - rangeTabConst->PushBack(entryConst); - } + InitRangeTabUseSym(workList, rangeTabEntryType, *rangeTabConst); for (int i = RangeIdx::kOldMaxNum + 1; i < RangeIdx::kNewMaxNum; ++i) { uint32 fieldID = 1; MIRAggConst *entryConst = GetMIRModule().GetMemPool()->New(GetMIRModule(), rangeTabEntryType); @@ -706,6 +752,13 @@ void MUIDReplacement::GenerateRangeTable() { builder->AddIntFieldConst(rangeTabEntryType, *entryConst, fieldID++, i); rangeTabConst->PushBack(entryConst); } + std::string bbProfileName = NameMangler::kBBProfileTabPrefixStr + GetMIRModule().GetFileNameAsPostfix(); + MIRSymbol *funcProfCounterTabSym = GetSymbolFromName(bbProfileName); + std::vector irProfWorkList = { + funcProfInfTabSym, + funcProfCounterTabSym + }; + InitRangeTabUseSym(irProfWorkList, rangeTabEntryType, *rangeTabConst); if (!rangeTabConst->GetConstVec().empty()) { rangeArrayType.SetSizeArrayItem(0, rangeTabConst->GetConstVec().size()); std::string rangeTabName = NameMangler::kMuidRangeTabPrefixStr + GetMIRModule().GetFileNameAsPostfix(); diff --git a/src/mpl2mpl/src/native_stub_func.cpp b/src/mpl2mpl/src/native_stub_func.cpp index c0d2de888ea59b36fddb9b1513a17e29b1239e48..37d735be271174cd3d642b2fc56c0a46dc9c9e5f 100644 --- a/src/mpl2mpl/src/native_stub_func.cpp +++ b/src/mpl2mpl/src/native_stub_func.cpp @@ -15,7 +15,7 @@ #include "native_stub_func.h" #include #include -#include "name_mangler.h" +#include "namemangler.h" #include "vtable_analysis.h" #include "reflection_analysis.h" @@ -25,10 +25,10 @@ // for the preparations before the actual native function is called, // including the parameter mapping, GC preparation, and so on. namespace maple { -NativeStubFuncGeneration::NativeStubFuncGeneration(MIRModule *mod, KlassHierarchy *kh, bool dump) +NativeStubFuncGeneration::NativeStubFuncGeneration(MIRModule &mod, KlassHierarchy *kh, bool dump) : FuncOptimizeImpl(mod, kh, dump) { MIRType *jstrType = GlobalTables::GetTypeTable().GetOrCreateClassType( - NameMangler::GetInternalNameLiteral(NameMangler::kJavaLangStringStr), *mod); + NameMangler::GetInternalNameLiteral(NameMangler::kJavaLangStringStr), mod); auto *jstrPointerType = static_cast(GlobalTables::GetTypeTable().GetOrCreatePointerType(*jstrType, PTY_ref)); jstrPointerTypeIdx = jstrPointerType->GetTypeIndex(); @@ -284,7 +284,11 @@ void NativeStubFuncGeneration::ProcessFunc(MIRFunction *func) { void NativeStubFuncGeneration::GenerateRegFuncTabEntryType() { MIRArrayType &arrayType = +#ifdef USE_ARM32_MACRO + *GlobalTables::GetTypeTable().GetOrCreateArrayType(*GlobalTables::GetTypeTable().GetUInt32(), 0); +#else *GlobalTables::GetTypeTable().GetOrCreateArrayType(*GlobalTables::GetTypeTable().GetVoidPtr(), 0); +#endif regFuncTabConst = GetMIRModule().GetMemPool()->New(GetMIRModule(), arrayType); std::string regFuncTab = NameMangler::kRegJNIFuncTabPrefixStr + GetMIRModule().GetFileNameAsPostfix(); regFuncSymbol = builder->CreateSymbol(regFuncTabConst->GetType().GetTypeIndex(), regFuncTab, kStVar, @@ -292,12 +296,20 @@ void NativeStubFuncGeneration::GenerateRegFuncTabEntryType() { } void NativeStubFuncGeneration::GenerateRegFuncTabEntry() { +#ifdef USE_ARM32_MACRO + constexpr int locIdxShift = 3; +#else constexpr int locIdxShift = 4; +#endif constexpr uint64 locIdxMask = 0xFF00000000000000; uint64 locIdx = regFuncTabConst->GetConstVec().size(); auto *newConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst(static_cast((locIdx << locIdxShift) | locIdxMask), +#ifdef USE_ARM32_MACRO + *GlobalTables::GetTypeTable().GetUInt32()); +#else *GlobalTables::GetTypeTable().GetVoidPtr()); +#endif regFuncTabConst->PushBack(newConst); } diff --git a/src/mpl2mpl/src/reflection_analysis.cpp b/src/mpl2mpl/src/reflection_analysis.cpp index 08abf832cb3950ac6fcf1dde891e69051a1b9767..ecb5093098ce3b3ba3dc2b410376b68b642488ed 100644 --- a/src/mpl2mpl/src/reflection_analysis.cpp +++ b/src/mpl2mpl/src/reflection_analysis.cpp @@ -23,7 +23,7 @@ #include "option.h" #include "muid_replacement.h" #include "mir_builder.h" -#include "name_mangler.h" +#include "namemangler.h" #include "itab_util.h" #include "string_utils.h" #include "metadata_layout.h" @@ -84,6 +84,8 @@ constexpr char kMonitorStr[] = "monitor"; constexpr char kObjsizeStr[] = "objsize"; #ifndef USE_32BIT_REF constexpr char kPaddingStr[] = "padding"; +#else +constexpr char kInstanceOfCacheFalseStr[] = "instanceOfCacheFalse"; #endif constexpr char kTypeNameStr[] = "typeName"; constexpr char kClassNameStr[] = "classname"; @@ -1286,9 +1288,9 @@ uint32 ReflectionAnalysis::GetAnnoCstrIndex(std::map &idxNumMap, const return signatureIdx; } -int64 ReflectionAnalysis::BKDRHash(const std::string &strName, uint32 seed) { +uint32 ReflectionAnalysis::BKDRHash(const std::string &strName, uint32 seed) { const char *name = strName.c_str(); - int64 hash = 0; + uint32 hash = 0; while (*name) { uint8_t uName = *name++; hash = hash * seed + uName; @@ -1296,12 +1298,15 @@ int64 ReflectionAnalysis::BKDRHash(const std::string &strName, uint32 seed) { return hash; } -int64 ReflectionAnalysis::GetHashIndex(const std::string &strName) { +uint32 ReflectionAnalysis::GetHashIndex(const std::string &strName) { constexpr int hashSeed = 211; return BKDRHash(strName, hashSeed); } void ReflectionAnalysis::GenHotClassNameString(const Klass &klass) { + if (klass.IsInterface()) { + return; + } MIRClassType *classType = klass.GetMIRClassType(); if (!classType->IsLocal()) { // External class. @@ -1353,7 +1358,7 @@ void ReflectionAnalysis::GenClassMetaData(Klass &klass) { reflectionMuidStr += klassName; std::string klassJavaDescriptor; NameMangler::DecodeMapleNameToJavaDescriptor(klassName, klassJavaDescriptor); - int64 hashIndex = GetHashIndex(klassJavaDescriptor); + uint32 hashIndex = GetHashIndex(klassJavaDescriptor); if (kRADebug) { LogInfo::MapleLogger(kLlErr) << "========= Gen Class: " << klassJavaDescriptor << " (" << hashIndex << ") ========\n"; @@ -1513,6 +1518,9 @@ void ReflectionAnalysis::GenClassMetaData(Klass &klass) { mirBuilder.AddAddrofFieldConst(classMetadataType, *newConst, fieldID++, *gctibSt); // @classinfo ro. mirBuilder.AddAddrofFieldConst(classMetadataType, *newConst, fieldID++, *classMetadataROSymbolType); +#ifdef USE_32BIT_REF + mirBuilder.AddIntFieldConst(classMetadataType, *newConst, fieldID++, 0); +#endif // Set default value to class initialization state. if (klassH->NeedClinitCheckRecursively(klass)) { @@ -1607,7 +1615,12 @@ void ReflectionAnalysis::GenMetadataType(MIRModule &mirModule) { GlobalTables::GetTypeTable().AddFieldToStructType(classMetadataType, kItabStr, *typeVoidPtr); GlobalTables::GetTypeTable().AddFieldToStructType(classMetadataType, kVtabStr, *typeVoidPtr); GlobalTables::GetTypeTable().AddFieldToStructType(classMetadataType, kGctibStr, *typeVoidPtr); +#ifdef USE_32BIT_REF + GlobalTables::GetTypeTable().AddFieldToStructType(classMetadataType, kClassinforoStr, *typeI32); + GlobalTables::GetTypeTable().AddFieldToStructType(classMetadataType, kInstanceOfCacheFalseStr, *typeU32); +#else GlobalTables::GetTypeTable().AddFieldToStructType(classMetadataType, kClassinforoStr, *typeVoidPtr); +#endif // USE_32BIT_REF GlobalTables::GetTypeTable().AddFieldToStructType(classMetadataType, kClinitbridgeStr, *typeVoidPtr); classMetadataTyIdx = GenMetaStructType(mirModule, classMetadataType, NameMangler::kClassMetadataTypeName); MIRStructType classMetadataROType(kTypeStruct); diff --git a/src/mpl2mpl/src/vtable_analysis.cpp b/src/mpl2mpl/src/vtable_analysis.cpp index 2fe661600e8777b11e03c3a4924e795f232f5698..19ad4619513b11186bce52bdb9a662fa78a83e29 100644 --- a/src/mpl2mpl/src/vtable_analysis.cpp +++ b/src/mpl2mpl/src/vtable_analysis.cpp @@ -31,7 +31,7 @@ constexpr uint32 kKlassVtabFieldID = static_cast(ClassProperty::kVtab) + // table.If the hash number is conflicted,we stored the whole completed methodname at the // end of interface table. namespace maple { -VtableAnalysis::VtableAnalysis(MIRModule *mod, KlassHierarchy *kh, bool dump) : FuncOptimizeImpl(mod, kh, dump) { +VtableAnalysis::VtableAnalysis(MIRModule &mod, KlassHierarchy *kh, bool dump) : FuncOptimizeImpl(mod, kh, dump) { voidPtrType = GlobalTables::GetTypeTable().GetVoidPtr(); // zeroConst and oneConst are shared amony itab entries. It is safe to share them because // they are never removed by anybody. diff --git a/src/mpl2mpl/src/vtable_impl.cpp b/src/mpl2mpl/src/vtable_impl.cpp index 99de42f21740f26bd630a46748e941d1f5350528..a1d817ef6fb37c21179a0f5b07caeb472746f9e0 100644 --- a/src/mpl2mpl/src/vtable_impl.cpp +++ b/src/mpl2mpl/src/vtable_impl.cpp @@ -27,8 +27,8 @@ constexpr char kInterfaceMethod[] = "MCC_getFuncPtrFromItabSecondHash64"; } // namespace namespace maple { -VtableImpl::VtableImpl(MIRModule *mod, KlassHierarchy *kh, bool dump) - : FuncOptimizeImpl(mod, kh, dump), mirModule(mod) { +VtableImpl::VtableImpl(MIRModule &mod, KlassHierarchy *kh, bool dump) + : FuncOptimizeImpl(mod, kh, dump), mirModule(&mod) { mccItabFunc = builder->GetOrCreateFunction(kInterfaceMethod, TyIdx(PTY_ptr)); mccItabFunc->SetAttr(FUNCATTR_nosideeffect); } diff --git a/src/mplfe/BUILD.gn b/src/mplfe/BUILD.gn index ba4f417b7952945601280f05c321f174742e2770..7077f8d9e8cbc8e0239f8aae57a7317b7a488f62 100644 --- a/src/mplfe/BUILD.gn +++ b/src/mplfe/BUILD.gn @@ -40,10 +40,11 @@ static_library("lib_mplfe_util") { "${MAPLEALL_ROOT}/mplfe/common/src/fe_input_helper.cpp", "${MAPLEALL_ROOT}/mplfe/common/src/fe_manager.cpp", "${MAPLEALL_ROOT}/mplfe/common/src/fe_options.cpp", - "${MAPLEALL_ROOT}/mplfe/common/src/fe_string_manager.cpp", + "${MAPLEALL_ROOT}/mplfe/common/src/fe_java_string_manager.cpp", "${MAPLEALL_ROOT}/mplfe/common/src/fe_timer_ns.cpp", "${MAPLEALL_ROOT}/mplfe/common/src/fe_type_hierarchy.cpp", "${MAPLEALL_ROOT}/mplfe/common/src/fe_type_manager.cpp", + "${MAPLEALL_ROOT}/mplfe/common/src/fe_struct_elem_info.cpp", "${MAPLEALL_ROOT}/mplfe/common/src/fe_utils.cpp", "${MAPLEALL_ROOT}/mplfe/common/src/fe_utils_java.cpp", "${MAPLEALL_ROOT}/mplfe/common/src/feir_builder.cpp", diff --git a/src/mplfe/common/include/fe_config_parallel.h b/src/mplfe/common/include/fe_config_parallel.h index 87ec5d49c412cef00357d4ba57d246c637096c9a..ff504b6187d04dc4f73ed2f07fcefe33f7587b83 100644 --- a/src/mplfe/common/include/fe_config_parallel.h +++ b/src/mplfe/common/include/fe_config_parallel.h @@ -14,6 +14,9 @@ */ #ifndef MPLFE_INCLUDE_COMMON_FE_CONFIG_PARALLEL_H #define MPLFE_INCLUDE_COMMON_FE_CONFIG_PARALLEL_H +#include +#include +#include #include "types_def.h" #include "mpl_logging.h" @@ -22,7 +25,7 @@ class FEConfigParallel { public: FEConfigParallel(); ~FEConfigParallel() = default; - static FEConfigParallel GetInstance() { + static FEConfigParallel &GetInstance() { return instance; } @@ -42,13 +45,34 @@ class FEConfigParallel { return enableParallel && (nThread > 1); } + void RegisterRunThreadID(std::thread::id tid) { + mtx.lock(); + CHECK_FATAL(runThreadIDs.insert(tid).second == true, "failed to register thread id"); + mtx.unlock(); + } + + bool RunThreadParallelForbidden() { + if (!enableParallel) { + return false; + } + std::thread::id tid = std::this_thread::get_id(); + return runThreadIDs.find(tid) != runThreadIDs.end(); + } + private: static FEConfigParallel instance; uint32 nThread; bool enableParallel; + std::set runThreadIDs; + std::mutex mtx; }; -#define MPLFE_PARALLEL_FORBIDDEN() \ - CHECK_FATAL(FEConfigParallel::GetInstance().IsInParallelMode() == false, "this method is forbidden in parallel mode"); +#define MPLFE_PARALLEL_FORBIDDEN() \ + do { \ + if (FEConfigParallel::GetInstance().RunThreadParallelForbidden()) { \ + maple::logInfo.EmitErrorMessage("MPLFE_PARALLEL_FORBIDDEN", __FILE__, __LINE__, "\n"); \ + FATAL(kLncFatal, "Forbidden invocation in parallel run thread"); \ + } \ + } while (0) } // namespace maple #endif // MPLFE_INCLUDE_COMMON_FE_PARALLEL_CONFIG_H diff --git a/src/mplfe/common/include/fe_java_string_manager.h b/src/mplfe/common/include/fe_java_string_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..fba82b13e3c069a69ba47a0740cf11d053efe774 --- /dev/null +++ b/src/mplfe/common/include/fe_java_string_manager.h @@ -0,0 +1,64 @@ +/* + * 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. + */ +#ifndef MPLFE_INCLUDE_COMMON_FE_JAVA_STRING_MANAGER_H +#define MPLFE_INCLUDE_COMMON_FE_JAVA_STRING_MANAGER_H +#include +#include +#include +#include "mir_module.h" +#include "mir_builder.h" + +namespace maple { +class FEJavaStringManager { + public: + explicit FEJavaStringManager(MIRModule &argModule); + ~FEJavaStringManager() = default; + // profiling + void LoadProfilingData(const std::string &profileFileName); + MIRSymbol *GetLiteralPtrVar(const MIRSymbol *var) const; + MIRSymbol *GetLiteralPtrVar(const std::string &str) const; + MIRSymbol *GetLiteralPtrVar(const std::u16string &strU16) const; + // methods for string + MIRSymbol *CreateLiteralVar(MIRBuilder &mirBuilder, const std::string &str, bool isFieldValue); + MIRSymbol *CreateLiteralVar(MIRBuilder &mirBuilder, const std::u16string &strU16, bool isFieldValue); + MIRSymbol *GetLiteralVar(const std::string &str) const; + MIRSymbol *GetLiteralVar(const std::u16string &strU16) const; + static std::string GetLiteralGlobalName(const std::u16string &strU16); + static bool IsAllASCII(const std::u16string &strU16); + + private: + using DWBuffer = struct { + uint64_t data; + uint32_t pos; + }; + + MIRArrayType *ConstructArrayType4Str(const std::u16string &strU16, bool compressible) const; + MIRAggConst *CreateByteArrayConst(const std::u16string &str, MIRArrayType &byteArrayType, bool compressible) const; + static std::vector SwapBytes(const std::u16string &strU16); + static uint16 ExchangeBytesPosition(uint16 input); + template + static void AddDataIntoByteArray(MIRAggConst &newConst, MemPool &mp, DWBuffer &buf, T data, MIRType &uInt64); + static void FinishByteArray(MIRAggConst &newConst, MemPool &mp, DWBuffer &buf, MIRType &uInt64); + + MIRModule &module; + bool useCompressedJavaString = true; + std::unordered_set preloadSet; + std::unordered_set literalSet; + std::unordered_set fieldValueSet; + std::map literalMap; + MIRType *typeString = nullptr; +}; +} // namespace maple +#endif // MPLFE_INCLUDE_COMMON_FE_JAVA_STRING_MANAGER_H \ No newline at end of file diff --git a/src/mplfe/common/include/fe_manager.h b/src/mplfe/common/include/fe_manager.h index 52557ace581f6392345ceecd89b262076bc38c70..334f5b3b4f3961879faa4b82c945f8e1377ff33e 100644 --- a/src/mplfe/common/include/fe_manager.h +++ b/src/mplfe/common/include/fe_manager.h @@ -18,7 +18,7 @@ #include "mir_module.h" #include "mir_builder.h" #include "fe_type_manager.h" -#include "fe_string_manager.h" +#include "fe_java_string_manager.h" namespace maple { class FEManager { @@ -33,9 +33,9 @@ class FEManager { return manager->typeManager; } - static FEStringManager &GetStringManager() { + static FEJavaStringManager &GetJavaStringManager() { ASSERT(manager, "manager is not initialize"); - return manager->stringManager; + return manager->javaStringManager; } static MIRBuilder &GetMIRBuilder() { @@ -59,9 +59,10 @@ class FEManager { static FEManager *manager; MIRModule &module; FETypeManager typeManager; - FEStringManager stringManager; + FEJavaStringManager javaStringManager; MIRBuilder builder; - FEManager(MIRModule &moduleIn) : module(moduleIn), typeManager(module), stringManager(), builder(&module) {} + explicit FEManager(MIRModule &moduleIn) + : module(moduleIn), typeManager(module), javaStringManager(moduleIn), builder(&module) {} ~FEManager() = default; }; } // namespace maple diff --git a/src/mplfe/common/include/fe_struct_elem_info.h b/src/mplfe/common/include/fe_struct_elem_info.h index 9e91ff5c1f2ec6b47d1190f1b2b3a60345821ea1..53956c5e0047fbf9c271838ebb0530877efa55a2 100644 --- a/src/mplfe/common/include/fe_struct_elem_info.h +++ b/src/mplfe/common/include/fe_struct_elem_info.h @@ -16,64 +16,163 @@ #define MPLFE_INCLUDE_COMMON_FE_STRUCT_ELEM_INFO_H #include #include "global_tables.h" +#include "fe_configs.h" +#include "feir_type.h" namespace maple { class FEStructElemInfo { public: - FEStructElemInfo(const GStrIdx &argFullNameIdxOrin, const GStrIdx &argFullNameIdxMpl) - : fullNameIdxOrin(argFullNameIdxOrin), - fullNameIdxMpl(argFullNameIdxMpl), - isMethod(false), - isStatic(false) {} + FEStructElemInfo(const GStrIdx &argFullNameIdx, MIRSrcLang argSrcLang, bool argIsStatic); + virtual ~FEStructElemInfo() = default; - ~FEStructElemInfo() = default; - void SetIsMethod(bool flag) { - isMethod = flag; + void Prepare(MIRBuilder &mirBuilder, bool argIsStatic) { + PrepareImpl(mirBuilder, argIsStatic); } - bool IsMethod() const { - return isMethod; + const std::string &GetStructName() const { + return GlobalTables::GetStrTable().GetStringFromStrIdx(structNameIdx); } - void SetIsStatic(bool flag) { - isStatic = flag; + const std::string &GetElemName() const { + return GlobalTables::GetStrTable().GetStringFromStrIdx(elemNameIdx); + } + + const std::string &GetSignatureName() const { + return GlobalTables::GetStrTable().GetStringFromStrIdx(signatureNameIdx); } bool IsStatic() const { return isStatic; } - void SetFullNameIdxOrin(const GStrIdx &idx) { - fullNameIdxOrin = idx; + bool IsMethod() const { + return isMethod; } - GStrIdx GetFullNameIdxOrin() const { - return fullNameIdxOrin; + bool IsDefined() const { + return isDefined; } - void SetFullNameIdxMpl(const GStrIdx &idx) { - fullNameIdxMpl = idx; + void SetDefined() { + isDefined = true; } - GStrIdx GetFullNameIdxMpl() const { - return fullNameIdxMpl; + void SetUndefined() { + isDefined = false; } - const std::string &GetFullNameOrin() const { - return GlobalTables::GetStrTable().GetStringFromStrIdx(fullNameIdxOrin); + bool IsFromDex() const { + return isFromDex; } - const std::string &GetFullNameMpl() const { - return GlobalTables::GetStrTable().GetStringFromStrIdx(fullNameIdxMpl); + void SetFromDex() { + isFromDex = true; } - private: - GStrIdx fullNameIdxOrin; - GStrIdx fullNameIdxMpl; - bool isMethod : 1; + MIRSrcLang GetSrcLang() const { + return srcLang; + } + + void SetSrcLang(MIRSrcLang lang) { + srcLang = lang; + } + + LLT_PROTECTED: + void Init(); + void InitJava(); + virtual void PrepareImpl(MIRBuilder &mirBuilder, bool argIsStatic) = 0; + + GStrIdx fullNameIdx; // in maple format + MIRSrcLang srcLang : 8; bool isStatic : 1; -}; // class FEStructElemInfo + bool isMethod : 1; + bool isDefined : 1; + bool isFromDex : 1; + bool isPrepared : 1; + GStrIdx structNameIdx; // in maple format + GStrIdx elemNameIdx; // in maple format + GStrIdx signatureNameIdx; // in maple format +}; using UniqueFEStructElemInfo = std::unique_ptr; + +class FEStructFieldInfo : public FEStructElemInfo { + public: + FEStructFieldInfo(const GStrIdx &argFullNameIdx, MIRSrcLang argSrcLang, bool argIsStatic); + ~FEStructFieldInfo() = default; + GStrIdx GetFieldNameIdx() const { + return fieldNameIdx; + } + + FieldID GetFieldID() const { + return fieldID; + } + + const UniqueFEIRType &GetType() const { + return fieldType; + } + + LLT_PROTECTED: + void PrepareImpl(MIRBuilder &mirBuilder, bool argIsStatic) override; + + LLT_PRIVATE: + void LoadFieldType(); + void LoadFieldTypeJava(); + void PrepareStaticField(MIRStructType &structType); + void PrepareNonStaticField(MIRStructType &structType, MIRBuilder &mirBuilder); + bool SearchStructFieldJava(MIRStructType &structType, MIRBuilder &mirBuilder, bool argIsStatic, + bool allowPrivate = true); + bool SearchStructFieldJava(const TyIdx &tyIdx, MIRBuilder &mirBuilder, bool argIsStatic, bool allowPrivate = true); + bool CompareFieldType(const FieldPair &fieldPair) const; + + UniqueFEIRType fieldType; + GStrIdx fieldNameIdx; + FieldID fieldID; +}; + +class FEStructMethodInfo : public FEStructElemInfo { + public: + FEStructMethodInfo(const GStrIdx &argFullNameIdx, MIRSrcLang argSrcLang, bool argIsStatic); + ~FEStructMethodInfo() = default; + PUIdx GetPuIdx() const; + bool IsConstructor() const { + return isConstructor; + } + + bool IsReturnVoid() const { + return isReturnVoid; + } + + const UniqueFEIRType &GetReturnType() const { + return retType; + } + + const UniqueFEIRType &GetOwnerType() const { + return ownerType; + } + + const std::vector &GetArgTypes() const { + return argTypes; + } + + LLT_PROTECTED: + void PrepareImpl(MIRBuilder &mirBuilder, bool argIsStatic) override; + + LLT_PRIVATE: + void LoadMethodType(); + void LoadMethodTypeJava(); + void PrepareMethod(); + void PrepareImplJava(MIRBuilder &mirBuilder, bool argIsStatic); + bool SearchStructMethodJava(MIRStructType &structType, MIRBuilder &mirBuilder, bool argIsStatic, + bool allowPrivate = true); + bool SearchStructMethodJava(const TyIdx &tyIdx, MIRBuilder &mirBuilder, bool argIsStatic, bool allowPrivate = true); + std::vector argTypes; + UniqueFEIRType retType; + UniqueFEIRType ownerType; + GStrIdx methodNameIdx; + MIRFunction *mirFunc; + bool isReturnVoid; + bool isConstructor; +}; } // namespace maple -#endif // MPLFE_INCLUDE_COMMON_FE_STRUCT_ELEM_INFO_H \ No newline at end of file +#endif // MPLFE_INCLUDE_COMMON_FE_STRUCT_ELEM_INFO_H diff --git a/src/mplfe/common/include/fe_type_manager.h b/src/mplfe/common/include/fe_type_manager.h index deb75103f85ecc34dcb1073beea86b788248d8da..ae6973b621520e963c5c41fc3c35a72cc255afc0 100644 --- a/src/mplfe/common/include/fe_type_manager.h +++ b/src/mplfe/common/include/fe_type_manager.h @@ -66,6 +66,23 @@ using FEStructTypePair = std::pair; class FETypeManager { public: + // ---------- prim FEIRType ---------- + const static UniqueFEIRType kPrimFEIRTypeUnknown; + const static UniqueFEIRType kPrimFEIRTypeU1; + const static UniqueFEIRType kPrimFEIRTypeI8; + const static UniqueFEIRType kPrimFEIRTypeU8; + const static UniqueFEIRType kPrimFEIRTypeI16; + const static UniqueFEIRType kPrimFEIRTypeU16; + const static UniqueFEIRType kPrimFEIRTypeI32; + const static UniqueFEIRType kPrimFEIRTypeU32; + const static UniqueFEIRType kPrimFEIRTypeI64; + const static UniqueFEIRType kPrimFEIRTypeU64; + const static UniqueFEIRType kPrimFEIRTypeF32; + const static UniqueFEIRType kPrimFEIRTypeF64; + const static UniqueFEIRType kFEIRTypeJavaObject; + const static UniqueFEIRType kFEIRTypeJavaClass; + const static UniqueFEIRType kFEIRTypeJavaString; + explicit FETypeManager(MIRModule &moduleIn); ~FETypeManager(); void ReleaseMemPool(); @@ -107,6 +124,8 @@ class FETypeManager { return GetOrCreateClassOrInterfacePtrType(nameIdx, isInterface, typeFlag, isCreate); } + MIRStructType *GetStructTypeFromName(const std::string &name); + MIRStructType *GetStructTypeFromName(const GStrIdx &nameIdx); MIRType *GetOrCreateTypeFromName(const std::string &name, FETypeFlag typeFlag, bool usePtr); MIRType *GetOrCreatePointerType(const MIRType &type); MIRType *GetOrCreateArrayType(MIRType &elemType, uint8 dim); @@ -115,9 +134,9 @@ class FETypeManager { // ---------- methods for StructElemInfo ---------- // structIdx = 0: global field/function without owner structure - FEStructElemInfo *RegisterStructElemInfo(const GStrIdx &structIdx, const GStrIdx &fullNameIdxOrin, - const GStrIdx &fullNameIdxMpl); - FEStructElemInfo *GetStructElemInfo(const GStrIdx &structIdx, const GStrIdx &fullNameIdxMpl) const; + FEStructElemInfo *RegisterStructFieldInfo(const GStrIdx &fullNameIdx, MIRSrcLang srcLang, bool isStatic); + FEStructElemInfo *RegisterStructMethodInfo(const GStrIdx &fullNameIdx, MIRSrcLang srcLang, bool isStatic); + FEStructElemInfo *GetStructElemInfo(const GStrIdx &fullNameIdx) const; // ---------- methods for MIRFunction ---------- /** @@ -143,6 +162,17 @@ class FETypeManager { MIRFunction *CreateFunction(const std::string &methodName, const std::string &returnTypeName, const std::vector &argTypeNames, bool isVarg, bool isStatic); + // MCC function + void InitMCCFunctions(); + MIRFunction *GetMCCFunction(const std::string &funcName) const; + MIRFunction *GetMCCFunction(const GStrIdx &funcNameIdx) const; + MIRFunction *GetMCCGetOrInsertLiteral() const { + return funcMCCGetOrInsertLiteral; + } + + // anti-proguard + bool IsAntiProguardFieldStruct(const GStrIdx &structNameIdx); + static bool IsStructType(const MIRType &type); static PrimType GetPrimType(const std::string &name); static MIRType *GetMIRTypeForPrim(char c); @@ -165,28 +195,39 @@ class FETypeManager { private: void UpdateStructNameTypeMapFromTypeTable(const std::string &mpltName, FETypeFlag flag); void UpdateNameFuncMapFromTypeTable(); + + // MCC function + void InitFuncMCCGetOrInsertLiteral(); + MIRModule &module; MemPool *mp; MapleAllocator allocator; MIRBuilder builder; // map - MapleUnorderedMap structNameTypeMap; + std::unordered_map structNameTypeMap; // map - MapleUnorderedMap structNameSrcMap; + std::unordered_map structNameSrcMap; // list> - MapleList> structSameNameSrcList; + std::list> structSameNameSrcList; FETypeSameNamePolicy sameNamePolicy; MIRSrcLang srcLang; // ---------- struct elem info ---------- - std::map> mapStructElemInfo; + std::map mapStructElemInfo; std::list listStructElemInfo; // ---------- function list ---------- - MapleUnorderedMap nameFuncMap; - MapleUnorderedMap nameStaticFuncMap; - MapleUnorderedMap mpltNameFuncMap; - MapleUnorderedMap mpltNameStaticFuncMap; + std::unordered_map nameFuncMap; + std::unordered_map nameStaticFuncMap; + std::unordered_map mpltNameFuncMap; + std::unordered_map mpltNameStaticFuncMap; + + // ---------- MCC function list ---------- + std::unordered_map nameMCCFuncMap; + MIRFunction *funcMCCGetOrInsertLiteral; + + // ---------- antiproguard ---------- + std::set setAntiProguardFieldStructIdx; }; } // namespace maple #endif // MPLFE_INCLUDE_COMMON_FE_TYPE_MANAGER_H diff --git a/src/mplfe/common/include/feir_builder.h b/src/mplfe/common/include/feir_builder.h index d1059819b3cf26850d9993eafe058ecf9a4db833..0eca33e39dbfdd9ef962ce3b6c7eb850139ca938 100644 --- a/src/mplfe/common/include/feir_builder.h +++ b/src/mplfe/common/include/feir_builder.h @@ -60,6 +60,8 @@ class FEIRBuilder { static UniqueFEIRStmt CreateStmtGoto(uint32 targetLabelIdx); static UniqueFEIRStmt CreateStmtCondGoto(uint32 targetLabelIdx, Opcode op, UniqueFEIRExpr expr); static UniqueFEIRStmt CreateStmtSwitch(UniqueFEIRExpr expr); + static UniqueFEIRStmt CreateStmtJavaConstClass(UniqueFEIRVar dstVar, UniqueFEIRType type); + static UniqueFEIRStmt CreateStmtJavaConstString(UniqueFEIRVar dstVar, const GStrIdx &strIdx); static UniqueFEIRStmt CreateStmtJavaCheckCast(UniqueFEIRVar dstVar, UniqueFEIRVar srcVar, UniqueFEIRType type); static UniqueFEIRStmt CreateStmtJavaInstanceOf(UniqueFEIRVar dstVar, UniqueFEIRVar srcVar, UniqueFEIRType type); static std::list CreateStmtArrayStore(UniqueFEIRVar varElem, UniqueFEIRVar varArray, diff --git a/src/mplfe/common/include/feir_stmt.h b/src/mplfe/common/include/feir_stmt.h index 6f6252b327077f785d55f20f1604405ecd35d7cb..534ea763fa4704465ed4e71b743d091435f1f9c7 100644 --- a/src/mplfe/common/include/feir_stmt.h +++ b/src/mplfe/common/include/feir_stmt.h @@ -30,6 +30,7 @@ #include "fe_utils.h" #include "general_stmt.h" #include "feir_var.h" +#include "fe_struct_elem_info.h" namespace maple { class FEIRBuilder; @@ -41,6 +42,9 @@ enum FEIRNodeKind : uint8 { kStmtPesudo, kStmtDAssign, kStmtJavaTypeCheck, + kStmtJavaConstClass, + kStmtJavaConstString, + kStmtJavaMultiANewArray, kStmtCallAssign, kStmtIntrinsicCallAssign, kStmtIAssign, @@ -51,6 +55,8 @@ enum FEIRNodeKind : uint8 { kStmtCondGoto, kStmtSwitch, kStmtArrayStore, + kStmtFieldStore, + kStmtFieldLoad, kExpr, kExprNestable, kExprNonNestable, @@ -605,7 +611,6 @@ class FEIRStmtAssign : public FEIRStmt { } void SetVar(std::unique_ptr argVar) { - CHECK_FATAL(argVar != nullptr, "input var is nullptr"); var = std::move(argVar); } @@ -660,6 +665,55 @@ class FEIRStmtJavaTypeCheck : public FEIRStmtAssign { std::unique_ptr type; }; +// ---------- FEIRStmtJavaConstClass ---------- +class FEIRStmtJavaConstClass : public FEIRStmtAssign { + public: + FEIRStmtJavaConstClass(std::unique_ptr argVar, std::unique_ptr argType); + ~FEIRStmtJavaConstClass() = default; + + protected: + std::list GenMIRStmtsImpl(MIRBuilder &mirBuilder) const override; + std::unique_ptr type; +}; + +// ---------- FEIRStmtJavaConstString ---------- +class FEIRStmtJavaConstString : public FEIRStmtAssign { + public: + FEIRStmtJavaConstString(std::unique_ptr argVar, const GStrIdx &argStrIdx); + ~FEIRStmtJavaConstString() = default; + + protected: + std::list GenMIRStmtsImpl(MIRBuilder &mirBuilder) const override; + + private: + GStrIdx strIdx; +}; + +// ---------- FEIRStmtJavaMultiANewArray ---------- +class FEIRStmtJavaMultiANewArray : public FEIRStmtAssign { + public: + FEIRStmtJavaMultiANewArray(std::unique_ptr argVar, std::unique_ptr argType); + ~FEIRStmtJavaMultiANewArray() = default; + void AddVarSize(std::unique_ptr varSize); + void AddVarSizeRev(std::unique_ptr varSize); + + protected: + std::list GenMIRStmtsImpl(MIRBuilder &mirBuilder) const override; + + private: + static const UniqueFEIRVar &GetVarSize(); + static const UniqueFEIRVar &GetVarClass(); + static const UniqueFEIRType &GetTypeAnnotation(); + static FEStructMethodInfo &GetMethodInfoNewInstance(); + + std::unique_ptr type; + std::list> exprSizes; + static UniqueFEIRVar varSize; + static UniqueFEIRVar varClass; + static UniqueFEIRType typeAnnotation; + static FEStructMethodInfo *methodInfoNewInstance; +}; + // ---------- FEIRStmtUseOnly ---------- class FEIRStmtUseOnly : public FEIRStmt { public: @@ -823,6 +877,76 @@ class FEIRStmtArrayStore : public FEIRStmt { UniqueFEIRType typeArray; }; +// ---------- FEIRStmtFieldStore ---------- +class FEIRStmtFieldStore : public FEIRStmt { + public: + FEIRStmtFieldStore(UniqueFEIRVar argVarObj, UniqueFEIRVar argVarField, FEStructFieldInfo &argFieldInfo, + bool argIsStatic); + ~FEIRStmtFieldStore() = default; + + protected: + std::list GenMIRStmtsImpl(MIRBuilder &mirBuilder) const override; + + private: + std::list GenMIRStmtsImplForStatic(MIRBuilder &mirBuilder) const; + std::list GenMIRStmtsImplForNonStatic(MIRBuilder &mirBuilder) const; + + UniqueFEIRVar varObj; + UniqueFEIRVar varField; + FEStructFieldInfo &fieldInfo; + bool isStatic; +}; + +// ---------- FEIRStmtFieldLoad ---------- +class FEIRStmtFieldLoad : public FEIRStmtAssign { + public: + FEIRStmtFieldLoad(UniqueFEIRVar argVarObj, UniqueFEIRVar argVarField, FEStructFieldInfo &argFieldInfo, + bool argIsStatic); + ~FEIRStmtFieldLoad() = default; + + protected: + std::list GenMIRStmtsImpl(MIRBuilder &mirBuilder) const override; + + private: + std::list GenMIRStmtsImplForStatic(MIRBuilder &mirBuilder) const; + std::list GenMIRStmtsImplForNonStatic(MIRBuilder &mirBuilder) const; + + UniqueFEIRVar varObj; + FEStructFieldInfo &fieldInfo; + bool isStatic; +}; + +// ---------- FEIRStmtCallAssign ---------- +class FEIRStmtCallAssign : public FEIRStmtAssign { + public: + FEIRStmtCallAssign(FEStructMethodInfo &argMethodInfo, Opcode argMIROp, UniqueFEIRVar argVarRet, bool argIsStatic); + ~FEIRStmtCallAssign() = default; + void AddExprArg(UniqueFEIRExpr exprArg) { + exprArgs.push_back(std::move(exprArg)); + } + + void AddExprArgReverse(UniqueFEIRExpr exprArg) { + exprArgs.push_front(std::move(exprArg)); + } + + static std::map InitMapOpAssignToOp(); + static std::map InitMapOpToOpAssign(); + + protected: + std::list GenMIRStmtsImpl(MIRBuilder &mirBuilder) const override; + + private: + Opcode AdjustMIROp() const; + + FEStructMethodInfo &methodInfo; + Opcode mirOp; + UniqueFEIRVar varRet; + bool isStatic; + std::list exprArgs; + static std::map mapOpAssignToOp; + static std::map mapOpToOpAssign; +}; + // ---------- FEIRStmtPesudoLOC ---------- class FEIRStmtPesudoLOC : public FEIRStmt { public: diff --git a/src/mplfe/common/include/feir_type.h b/src/mplfe/common/include/feir_type.h index 77fee735f998c0666ba5dc0c1248a534dc3738e5..f8f1ef39c36dc0e17594aa721c3a10bed41f3162 100644 --- a/src/mplfe/common/include/feir_type.h +++ b/src/mplfe/common/include/feir_type.h @@ -35,6 +35,7 @@ class FEIRType { FEIRType(FEIRTypeKind argKind, PrimType argPrimType); virtual ~FEIRType() = default; static std::unique_ptr NewType(FEIRTypeKind argKind = kFEIRTypeDefault); + MIRType *GenerateMIRTypeAuto(MIRSrcLang srcLang) const; bool IsSameKind(const FEIRType &type) const { return kind == type.kind; } @@ -47,6 +48,10 @@ class FEIRType { return primType; } + PrimType GetRealPrimType() const { + return IsScalar() ? primType : PTY_ref; + } + void SetPrimType(PrimType argPrimType) { primType = argPrimType; } diff --git a/src/mplfe/common/include/mplfe_compiler_component.h b/src/mplfe/common/include/mplfe_compiler_component.h index 5a6fcb855a9f5d594d616a8eab2ab8854f6fd791..0d3d321baafa1af76ffac63d2d304423ec497f0d 100644 --- a/src/mplfe/common/include/mplfe_compiler_component.h +++ b/src/mplfe/common/include/mplfe_compiler_component.h @@ -47,6 +47,9 @@ class FEFunctionProcessSchedular : public MplScheduler { dumpTime = arg; } + protected: + void CallbackThreadMainStart() override; + private: std::list> tasks; }; @@ -120,4 +123,4 @@ class MPLFECompilerComponent { std::unique_ptr phaseResultTotal; }; } // namespace maple -#endif \ No newline at end of file +#endif diff --git a/src/mplfe/common/src/fe_config_parallel.cpp b/src/mplfe/common/src/fe_config_parallel.cpp index c8d3e96947b9847d4ff443cd4faaaf7ff79b97b7..58ce40745846d2f575cdf3c13c161e4de27d96b3 100644 --- a/src/mplfe/common/src/fe_config_parallel.cpp +++ b/src/mplfe/common/src/fe_config_parallel.cpp @@ -16,8 +16,8 @@ #include "mpl_logging.h" namespace maple { +FEConfigParallel FEConfigParallel::instance; + FEConfigParallel::FEConfigParallel() : nThread(1), enableParallel(false) {} - -FEConfigParallel FEConfigParallel::instance; } // namespace maple \ No newline at end of file diff --git a/src/mplfe/common/src/fe_function_phase_result.cpp b/src/mplfe/common/src/fe_function_phase_result.cpp index 5b5ce28652d897f9741462b98d4531e566f94648..ccb1572f290b5581ec4a51bf93a5885d56da023a 100644 --- a/src/mplfe/common/src/fe_function_phase_result.cpp +++ b/src/mplfe/common/src/fe_function_phase_result.cpp @@ -1,60 +1,60 @@ -/* - * 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. - */ -#include "fe_function_phase_result.h" -#include "mpl_logging.h" - -namespace maple { -void FEFunctionPhaseResult::Combine(const FEFunctionPhaseResult &result) { - for (const std::string &name : result.phaseNames) { - auto itResult = result.phaseTimes.find(name); - CHECK_FATAL(itResult != result.phaseTimes.end(), "invalid result: without time recorded"); - int64 t = itResult->second; - auto itLocal = phaseTimes.find(name); - if (itLocal == phaseTimes.end()) { - phaseNames.push_back(name); - phaseTimes[name] = t; - } else { - phaseTimes[name] = itLocal->second + t; - } - } -} - -void FEFunctionPhaseResult::Dump() { - for (const std::string &name :phaseNames) { - auto it = phaseTimes.find(name); - CHECK_FATAL(it != phaseTimes.end(), "phase time is undefined for %s", name.c_str()); - INFO(kLncInfo, "[PhaseTime] %s: %lld ns", name.c_str(), it->second); - } -} - -void FEFunctionPhaseResult::DumpMS() { - for (const std::string &name :phaseNames) { - auto it = phaseTimes.find(name); - CHECK_FATAL(it != phaseTimes.end(), "phase time is undefined for %s", name.c_str()); - INFO(kLncInfo, "[PhaseTime] %s: %.2lf ms", name.c_str(), it->second / 1000000.0); // 1ms = 1000000 ns - } -} - -bool FEFunctionPhaseResult::Finish(bool isSuccess) { - success = isSuccess; - if (enable && recordTime) { - timer.Stop(); - CHECK_FATAL(!currPhaseName.empty(), "Phase Name is empty"); - int64 t = timer.GetTimeNS(); - phaseTimes[currPhaseName] = t; - } - return success; -} +/* + * 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. + */ +#include "fe_function_phase_result.h" +#include "mpl_logging.h" + +namespace maple { +void FEFunctionPhaseResult::Combine(const FEFunctionPhaseResult &result) { + for (const std::string &name : result.phaseNames) { + auto itResult = result.phaseTimes.find(name); + CHECK_FATAL(itResult != result.phaseTimes.end(), "invalid result: without time recorded"); + int64 t = itResult->second; + auto itLocal = phaseTimes.find(name); + if (itLocal == phaseTimes.end()) { + phaseNames.push_back(name); + phaseTimes[name] = t; + } else { + phaseTimes[name] = itLocal->second + t; + } + } +} + +void FEFunctionPhaseResult::Dump() { + for (const std::string &name :phaseNames) { + auto it = phaseTimes.find(name); + CHECK_FATAL(it != phaseTimes.end(), "phase time is undefined for %s", name.c_str()); + INFO(kLncInfo, "[PhaseTime] %s: %lld ns", name.c_str(), it->second); + } +} + +void FEFunctionPhaseResult::DumpMS() { + for (const std::string &name :phaseNames) { + auto it = phaseTimes.find(name); + CHECK_FATAL(it != phaseTimes.end(), "phase time is undefined for %s", name.c_str()); + INFO(kLncInfo, "[PhaseTime] %s: %.2lf ms", name.c_str(), it->second / 1000000.0); // 1ms = 1000000 ns + } +} + +bool FEFunctionPhaseResult::Finish(bool isSuccess) { + success = isSuccess; + if (enable && recordTime) { + timer.Stop(); + CHECK_FATAL(!currPhaseName.empty(), "Phase Name is empty"); + int64 t = timer.GetTimeNS(); + phaseTimes[currPhaseName] = t; + } + return success; +} } // namespace maple \ No newline at end of file diff --git a/src/mplfe/common/src/fe_java_string_manager.cpp b/src/mplfe/common/src/fe_java_string_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..347fef0c68673b84e44c9f12e0574b4dea499641 --- /dev/null +++ b/src/mplfe/common/src/fe_java_string_manager.cpp @@ -0,0 +1,249 @@ +/* + * 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. + */ +#include "fe_java_string_manager.h" +#include +#include "global_tables.h" +#include "namemangler.h" +#include "muid.h" +#include "literalstrname.h" +#include "fe_config_parallel.h" +#include "feir_type.h" + +namespace maple { +FEJavaStringManager::FEJavaStringManager(MIRModule &argModule) + : module(argModule) {} + +void FEJavaStringManager::LoadProfilingData(const std::string &profileFileName) { + std::ifstream inFile(profileFileName); + if (!inFile.is_open()) { + WARN(kLncWarn, "Cannot open literal profile data file %s", profileFileName.c_str()); + return; + } + std::string literalName; + while (std::getline(inFile, literalName)) { + if (!literalName.empty()) { + preloadSet.insert(literalName); + } + } + inFile.close(); +} + +MIRSymbol *FEJavaStringManager::GetLiteralPtrVar(const MIRSymbol *var) const { + auto it = literalMap.find(var); + if (it != literalMap.end()) { + return it->second; + } else { + return nullptr; + } +} + +MIRSymbol *FEJavaStringManager::GetLiteralPtrVar(const std::string &str) const { + MIRSymbol *literalVar = GetLiteralVar(str); + return GetLiteralPtrVar(literalVar); +} + +MIRSymbol *FEJavaStringManager::GetLiteralPtrVar(const std::u16string &strU16) const { + MIRSymbol *literalVar = GetLiteralVar(strU16); + return GetLiteralPtrVar(literalVar); +} + +MIRSymbol *FEJavaStringManager::CreateLiteralVar(MIRBuilder &mirBuilder, const std::string &str, bool isFieldValue) { + std::u16string strU16; + NameMangler::UTF8ToUTF16(strU16, str); + return CreateLiteralVar(mirBuilder, strU16, isFieldValue); +} + +MIRSymbol *FEJavaStringManager::CreateLiteralVar(MIRBuilder &mirBuilder, const std::u16string &strU16, + bool isFieldValue) { + MPLFE_PARALLEL_FORBIDDEN(); + if (typeString == nullptr) { + FEIRTypeDefault type(PTY_ref); + type.LoadFromJavaTypeName("Ljava/lang/String;", false); + typeString = type.GenerateMIRTypeAuto(kSrcLangJava); + } + MIRSymbol *literalVar = GetLiteralVar(strU16); + if (literalVar != nullptr) { + return literalVar; + } + std::string literalGlobalName = GetLiteralGlobalName(strU16); + bool compress = useCompressedJavaString && IsAllASCII(strU16); + MIRArrayType *byteArrayType = ConstructArrayType4Str(strU16, compress); + literalVar = mirBuilder.GetOrCreateGlobalDecl(literalGlobalName.c_str(), *byteArrayType); + MIRAggConst *strConst = CreateByteArrayConst(strU16, *byteArrayType, compress); + literalVar->SetKonst(strConst); + literalVar->SetAttr(ATTR_readonly); + literalVar->SetStorageClass(kScFstatic); + bool isHotLiteral = false; + if (preloadSet.find(literalGlobalName) != preloadSet.end()) { + isHotLiteral = true; + literalSet.insert(literalVar); + } + if (isFieldValue) { + fieldValueSet.insert(literalVar); + } + if (isFieldValue || isHotLiteral) { + std::string literalGlobalPtrName = NameMangler::kPtrPrefixStr + literalGlobalName; + MIRSymbol *literalVarPtr = mirBuilder.GetOrCreateGlobalDecl(literalGlobalPtrName.c_str(), *typeString); + literalVarPtr->SetStorageClass(literalVar->GetStorageClass()); + AddrofNode *expr = mirBuilder.CreateExprAddrof(0, *literalVar, module.GetMemPool()); + MIRConst *cst = module.GetMemPool()->New( + expr->GetStIdx(), expr->GetFieldID(), *GlobalTables::GetTypeTable().GetPtr()); + literalVarPtr->SetKonst(cst); + literalMap[literalVar] = literalVarPtr; + } + GlobalTables::GetConstPool().GetConstU16StringPool().insert(std::make_pair(strU16, literalVar)); + return literalVar; +} + +MIRSymbol *FEJavaStringManager::GetLiteralVar(const std::string &str) const { + std::u16string strU16; + NameMangler::UTF8ToUTF16(strU16, str); + return GetLiteralVar(strU16); +} + +MIRSymbol *FEJavaStringManager::GetLiteralVar(const std::u16string &strU16) const { + auto it = GlobalTables::GetConstPool().GetConstU16StringPool().find(strU16); + if (it != GlobalTables::GetConstPool().GetConstU16StringPool().end()) { + return it->second; + } + return nullptr; +} + +std::string FEJavaStringManager::GetLiteralGlobalName(const std::u16string &strU16) { + std::string literalGlobalName; + std::vector swapped = SwapBytes(strU16); + if (strU16.length() == 0) { + literalGlobalName = LiteralStrName::GetLiteralStrName(swapped.data(), 0); + } else { + literalGlobalName = LiteralStrName::GetLiteralStrName(swapped.data(), strU16.length() << 1); + } + return literalGlobalName; +} + +bool FEJavaStringManager::IsAllASCII(const std::u16string &strU16) { + if (strU16.length() == 0) { + return false; + } + for (size_t i = 0; i < strU16.length(); ++i) { + uint16 val = ExchangeBytesPosition(strU16[i]); + if (val >= CHAR_MAX) { + return false; + } + } + return true; +} + +MIRArrayType *FEJavaStringManager::ConstructArrayType4Str(const std::u16string &strU16, bool compressible) const { + MPLFE_PARALLEL_FORBIDDEN(); + uint32 arraySize[1]; + int length = compressible ? strU16.length() : (strU16.length() * 2); // use 2 bytes per char in uncompress mode +#ifdef JAVA_OBJ_IN_MFILE +#ifdef USE_32BIT_REF + int sizeInBytes = 16 + length; // shadow(4B)+monitor(4B)+count(4B)+hash(4B)+content +#else // !USE_32BIT_REF + int sizeInBytes = 20 + length; // shadow(8B)+monitor(4B)+count(4B)+hash(4B)+content +#endif // USE_32BIT_REF +#else // !JAVA_OBJ_IN_MFILE + int sizeInBytes = 8 + length; // count(4B)+hash(4B)+content +#endif // JAVA_OBJ_IN_MFILE + int sizeInLongs = (sizeInBytes - 1) / 8 + 1; // round up to 8B units + arraySize[0] = sizeInLongs; + MIRArrayType *byteArrayType = static_cast( + GlobalTables::GetTypeTable().GetOrCreateArrayType(*GlobalTables::GetTypeTable().GetUInt64(), 1, arraySize)); + return byteArrayType; +} + +MIRAggConst *FEJavaStringManager::CreateByteArrayConst(const std::u16string &strU16, MIRArrayType &byteArrayType, + bool compressible) const { + MIRAggConst *newconst = module.GetMemPool()->New(module, byteArrayType); + MIRType *uInt64 = GlobalTables::GetTypeTable().GetUInt64(); + MemPool *mp = module.GetMemPool(); + DWBuffer currData = { 0, 0 }; + +#ifdef JAVA_OBJ_IN_MFILE + // @shadow + // To avoid linker touch cold pages, the classinfo is not set ready in file. + // It will be set at runtime +#ifdef USE_32BIT_REF + AddDataIntoByteArray(*newconst, *mp, currData, static_cast(0), *uInt64); +#else + AddDataIntoByteArray(*newconst, *mp, currData, static_cast(0), *uInt64); +#endif // USE_32BIT_REF + // @monitor + AddDataIntoByteArray(*newconst, *mp, currData, static_cast(0), *uInt64); +#endif // JAVA_OBJ_IN_MFILE + + // @count + uint32_t strCount = strU16.length() ? ((strU16.length() * 2) | compressible) : 0; + AddDataIntoByteArray(*newconst, *mp, currData, strCount, *uInt64); + + // @hash + uint32_t hash = LiteralStrName::CalculateHashSwapByte(strU16.data(), strU16.length()); + AddDataIntoByteArray(*newconst, *mp, currData, hash, *uInt64); + + // @content + if (compressible) { + for (size_t i = 0; i < strU16.size(); i++) { + AddDataIntoByteArray(*newconst, *mp, currData, static_cast(ExchangeBytesPosition(strU16[i])), *uInt64); + } + } else { + for (size_t i = 0; i < strU16.size(); i++) { + AddDataIntoByteArray(*newconst, *mp, currData, static_cast(ExchangeBytesPosition(strU16[i])), *uInt64); + } + } + // in case there're remaining data in the buffer + FinishByteArray(*newconst, *mp, currData, *uInt64); + return newconst; +} + +std::vector FEJavaStringManager::SwapBytes(const std::u16string &strU16) { + std::vector out; + for (size_t i = 0; i < strU16.length(); ++i) { + uint16 c16 = strU16[i]; + out.push_back((c16 & 0xFF00) >> 8); + out.push_back(c16 & 0xFF); + } + out.push_back(0); + out.push_back(0); + return out; +} + +uint16 FEJavaStringManager::ExchangeBytesPosition(uint16 input) { + uint16 lowerByte = input << 8; + uint16 higherByte = input >> 8; + return lowerByte | higherByte; +} + +template +void FEJavaStringManager::AddDataIntoByteArray(MIRAggConst &newConst, MemPool &mp, DWBuffer &buf, T data, + MIRType &uInt64) { + if (buf.pos == 8) { // buffer is already full + newConst.PushBack(mp.New(buf.data, uInt64)); + buf.data = 0; + buf.pos = 0; + } + CHECK_FATAL(((buf.pos + sizeof(T)) <= 8), "inserted data exceeds current buffer capacity"); + buf.data |= ((static_cast(data)) << (buf.pos * 8)); + buf.pos += sizeof(T); +} + +void FEJavaStringManager::FinishByteArray(MIRAggConst &newConst, MemPool &mp, DWBuffer &buf, MIRType &uInt64) { + if (buf.pos > 0) { // there're data inside buffer + newConst.PushBack(mp.New(buf.data, uInt64)); + buf.data = 0; + buf.pos = 0; + } +} +} // namespace maple \ No newline at end of file diff --git a/src/mplfe/common/src/fe_string_manager.cpp b/src/mplfe/common/src/fe_string_manager.cpp deleted file mode 100644 index f09b418f849d2eed16be1577ddcd791eb7102c33..0000000000000000000000000000000000000000 --- a/src/mplfe/common/src/fe_string_manager.cpp +++ /dev/null @@ -1,19 +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. - */ -#include "fe_string_manager.h" - -namespace maple { -FEStringManager::FEStringManager() {} -} // namespace maple \ No newline at end of file diff --git a/src/mplfe/common/src/fe_struct_elem_info.cpp b/src/mplfe/common/src/fe_struct_elem_info.cpp new file mode 100644 index 0000000000000000000000000000000000000000..453770a20f2a982f741ce6d0a3757e91fdd7a9b3 --- /dev/null +++ b/src/mplfe/common/src/fe_struct_elem_info.cpp @@ -0,0 +1,384 @@ +/* + * 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. + */ +#include "fe_struct_elem_info.h" +#include "global_tables.h" +#include "mpl_logging.h" +#include "namemangler.h" +#include "fe_utils.h" +#include "fe_manager.h" +#include "jbc_util.h" + +namespace maple { +// ---------- FEStructElemInfo ---------- +FEStructElemInfo::FEStructElemInfo(const GStrIdx &argFullNameIdx, MIRSrcLang argSrcLang, bool argIsStatic) + : fullNameIdx(argFullNameIdx), + srcLang(argSrcLang), + isStatic(argIsStatic), + isMethod(false), + isDefined(false), + isFromDex(false), + isPrepared(false), + structNameIdx(0) { + // fieldNameIdx(0), + // typeNameIdx(0), + // fieldID(0) { + Init(); +} + +void FEStructElemInfo::Init() { + switch (srcLang) { + case kSrcLangJava: + InitJava(); + break; + default: + WARN(kLncWarn, "unsupported language"); + break; + } +} + +void FEStructElemInfo::InitJava() { + std::string fullNameMpl = GlobalTables::GetStrTable().GetStringFromStrIdx(fullNameIdx); + std::string fullNameJava = NameMangler::DecodeName(fullNameMpl); + std::vector names = FEUtils::Split(fullNameJava, '|'); + // 3 parts: ClassName|ElemName|Signature + CHECK_FATAL(names.size() == 3, "invalid elem name %s", fullNameJava.c_str()); + // names[0]: structName + structNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(NameMangler::EncodeName(names[0])); + // names[1]: elemName + elemNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(NameMangler::EncodeName(names[1])); + // names[2]: signature + signatureNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(NameMangler::EncodeName(names[2])); +} + +// ---------- FEStructFieldInfo ---------- +FEStructFieldInfo::FEStructFieldInfo(const GStrIdx &argFullNameIdx, MIRSrcLang argSrcLang, bool argIsStatic) + : FEStructElemInfo(argFullNameIdx, argSrcLang, argIsStatic), + fieldType(nullptr), + fieldNameIdx(0), + fieldID(0) { + isMethod = false; + LoadFieldType(); +} + +void FEStructFieldInfo::PrepareImpl(MIRBuilder &mirBuilder, bool argIsStatic) { + if (isPrepared && argIsStatic == isStatic) { + return; + } + // Prepare + const std::string &structName = GetStructName(); + std::string rawName = structName + NameMangler::kNameSplitterStr + GetElemName(); + fieldNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(rawName); + fieldID = UINT32_MAX; + MIRStructType *structType = FEManager::GetTypeManager().GetStructTypeFromName(structName); + if (structType == nullptr) { + isDefined = false; + isPrepared = true; + return; + } + isDefined = SearchStructFieldJava(*structType, mirBuilder, argIsStatic); + if (isDefined) { + return; + } + rawName = rawName + NameMangler::kNameSplitterStr + GetSignatureName(); + WARN(kLncErr, "use undefined %s field %s", argIsStatic ? "static" : "", rawName.c_str()); + isPrepared = true; + isStatic = argIsStatic; + return; +} + +void FEStructFieldInfo::LoadFieldType() { + switch (srcLang) { + case kSrcLangJava: + LoadFieldTypeJava(); + break; + default: + WARN(kLncWarn, "unsupported language"); + break; + } +} + +void FEStructFieldInfo::LoadFieldTypeJava() { + fieldType = std::make_unique(PTY_unknown); + static_cast(fieldType.get())->LoadFromJavaTypeName(GetSignatureName(), true); +} + +void FEStructFieldInfo::PrepareStaticField(MIRStructType &structType) { + std::string ownerStructName = structType.GetName(); + const std::string &fieldName = GetElemName(); + std::string fullName = ownerStructName + NameMangler::kNameSplitterStr + fieldName; + fieldNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fullName); + isPrepared = true; + isStatic = true; +} + +void FEStructFieldInfo::PrepareNonStaticField(MIRStructType &structType, MIRBuilder &mirBuilder) { + FEIRTypeDefault feType(PTY_unknown); + feType.LoadFromJavaTypeName(GetSignatureName(), true); + MIRType *fieldType = feType.GenerateMIRTypeAuto(srcLang); + uint32 idx = 0; + uint32 idx1 = 0; + mirBuilder.TraverseToNamedFieldWithType(structType, elemNameIdx, fieldType->GetTypeIndex(), idx1, idx); + fieldID = idx; + isPrepared = true; + isStatic = false; +} + +bool FEStructFieldInfo::SearchStructFieldJava(MIRStructType &structType, MIRBuilder &mirBuilder, bool argIsStatic, + bool allowPrivate) { + if (structType.IsIncomplete()) { + return false; + } + GStrIdx nameIdx = elemNameIdx; + if (argIsStatic) { + // suppose anti-proguard is off + std::string fullName = structType.GetCompactMplTypeName() + NameMangler::kNameSplitterStr + GetElemName(); + nameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fullName); + } + const FieldVector &fields = argIsStatic ? structType.GetStaticFields() : structType.GetFields(); + for (const FieldPair &fieldPair : fields) { + if (fieldPair.first != nameIdx) { + continue; + } + if (fieldPair.second.second.GetAttr(FLDATTR_private) && !allowPrivate) { + continue; + } + if (CompareFieldType(fieldPair)) { + if (argIsStatic) { + PrepareStaticField(structType); + } else { + PrepareNonStaticField(structType, mirBuilder); + } + return true; + } + } + // search parent + bool found = false; + if (structType.GetKind() == kTypeClass) { + // parent + MIRClassType &classType = static_cast(structType); + found = SearchStructFieldJava(classType.GetParentTyIdx(), mirBuilder, argIsStatic, false); + // implemented + for (const TyIdx &tyIdx : classType.GetInterfaceImplemented()) { + found = found || SearchStructFieldJava(tyIdx, mirBuilder, argIsStatic, false); + } + } else if (structType.GetKind() == kTypeInterface) { + // parent + MIRInterfaceType &interfaceType = static_cast(structType); + for (const TyIdx &tyIdx : interfaceType.GetParentsTyIdx()) { + found = found || SearchStructFieldJava(tyIdx, mirBuilder, argIsStatic, false); + } + } else { + CHECK_FATAL(false, "not supported yet"); + } + return found; +} + +bool FEStructFieldInfo::SearchStructFieldJava(const TyIdx &tyIdx, MIRBuilder &mirBuilder, bool argIsStatic, + bool allowPrivate) { + MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); + if (type == nullptr) { + return false; + } + if (type->IsIncomplete()) { + return false; + } + if (type->GetKind() == kTypeClass || type->GetKind() == kTypeInterface) { + MIRStructType *structType = static_cast(type); + return SearchStructFieldJava(*structType, mirBuilder, argIsStatic, allowPrivate); + } else { + ERR(kLncErr, "parent type should be StructType"); + return false; + } +} + +bool FEStructFieldInfo::CompareFieldType(const FieldPair &fieldPair) const { + MIRType *fieldType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fieldPair.second.first); + std::string typeName = fieldType->GetCompactMplTypeName(); + if (GetSignatureName().compare(typeName) == 0) { + return true; + } else { + return false; + } +} + +// ---------- FEStructMethodInfo ---------- +FEStructMethodInfo::FEStructMethodInfo(const GStrIdx &argFullNameIdx, MIRSrcLang argSrcLang, bool argIsStatic) + : FEStructElemInfo(argFullNameIdx, argSrcLang, argIsStatic), + methodNameIdx(fullNameIdx), + mirFunc(nullptr), + isReturnVoid(false) { + isMethod = true; + LoadMethodType(); +} + +PUIdx FEStructMethodInfo::GetPuIdx() const { + CHECK_NULL_FATAL(mirFunc); + return mirFunc->GetPuidx(); +} + +void FEStructMethodInfo::PrepareImpl(MIRBuilder &mirBuilder, bool argIsStatic) { + if (isPrepared && argIsStatic == isStatic) { + return; + } + switch (srcLang) { + case kSrcLangJava: + PrepareImplJava(mirBuilder, argIsStatic); + break; + default: + CHECK_FATAL(false, "unsupported src lang"); + } + PrepareMethod(); +} + +void FEStructMethodInfo::PrepareImplJava(MIRBuilder &mirBuilder, bool argIsStatic) { + // Prepare + const std::string &structName = GetStructName(); + MIRStructType *structType = nullptr; + if (!structName.empty() && structName[0] == 'A') { + structType = FEManager::GetTypeManager().GetStructTypeFromName("Ljava_2Flang_2FObject_3B"); + } else { + structType = FEManager::GetTypeManager().GetStructTypeFromName(structName); + } + isStatic = argIsStatic; + isDefined = false; + if (structType != nullptr) { + isDefined = SearchStructMethodJava(*structType, mirBuilder, argIsStatic); + if (isDefined) { + return; + } + } + std::string methodName = GlobalTables::GetStrTable().GetStringFromStrIdx(fullNameIdx); + WARN(kLncWarn, "undefined %s method: %s", isStatic ? "static" : "", methodName.c_str()); +} + +void FEStructMethodInfo::LoadMethodType() { + switch (srcLang) { + case kSrcLangJava: + LoadMethodTypeJava(); + break; + default: + WARN(kLncWarn, "unsupported language"); + break; + } +} + +void FEStructMethodInfo::LoadMethodTypeJava() { + std::string signatureJava = + NameMangler::DecodeName(GlobalTables::GetStrTable().GetStringFromStrIdx(fullNameIdx)); + std::vector typeNames = jbc::JBCUtil::SolveMethodSignature(signatureJava); + CHECK_FATAL(typeNames.size() > 0, "invalid method signature: %s", signatureJava.c_str()); + // constructor check + const std::string &funcName = GetElemName(); + isConstructor = (funcName.find("init_28") == 0); + // return type + retType = std::make_unique(PTY_unknown); + if (typeNames[0].compare("V") == 0) { + isReturnVoid = true; + } + static_cast(retType.get())->LoadFromJavaTypeName(typeNames[0], false); + // argument types + argTypes.clear(); + for (size_t i = 1; i < typeNames.size(); i++) { + UniqueFEIRType argType = std::make_unique(PTY_unknown); + static_cast(argType.get())->LoadFromJavaTypeName(typeNames[i], false); + argTypes.push_back(std::move(argType)); + } + // owner type + ownerType = std::make_unique(PTY_unknown); + static_cast(ownerType.get())->LoadFromJavaTypeName(GetStructName(), true); +} + +void FEStructMethodInfo::PrepareMethod() { + mirFunc = FEManager::GetTypeManager().GetMIRFunction(methodNameIdx, isStatic); + if (mirFunc == nullptr) { + MIRType *mirRetType = retType->GenerateMIRTypeAuto(srcLang); + // args type + std::vector argsTypeIdx; + for (const UniqueFEIRType &argType : argTypes) { + MIRType *mirArgType = argType->GenerateMIRTypeAuto(srcLang); + argsTypeIdx.push_back(mirArgType->GetTypeIndex()); + } + mirFunc = FEManager::GetTypeManager().CreateFunction(methodNameIdx, mirRetType->GetTypeIndex(), argsTypeIdx, false, + isStatic); + } + isPrepared = true; +} + +bool FEStructMethodInfo::SearchStructMethodJava(MIRStructType &structType, MIRBuilder &mirBuilder, bool argIsStatic, + bool allowPrivate) { + if (structType.IsIncomplete()) { + return false; + } + std::string fullName = structType.GetCompactMplTypeName() + NameMangler::kNameSplitterStr + GetElemName() + + NameMangler::kNameSplitterStr + GetSignatureName(); + GStrIdx nameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fullName); + for (const MethodPair &methodPair : structType.GetMethods()) { + const MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(methodPair.first.Idx(), true); + CHECK_NULL_FATAL(sym); + if (methodPair.second.second.GetAttr(FUNCATTR_private) && !allowPrivate) { + continue; + } + if (methodPair.second.second.GetAttr(FUNCATTR_static) != argIsStatic) { + continue; + } + if (sym->GetNameStrIdx() == nameIdx) { + isStatic = argIsStatic; + if (isStatic) { + methodNameIdx = nameIdx; + } + PrepareMethod(); + return true; + } + } + // search parent + bool found = false; + if (structType.GetKind() == kTypeClass) { + // parent + MIRClassType &classType = static_cast(structType); + found = SearchStructMethodJava(classType.GetParentTyIdx(), mirBuilder, argIsStatic, false); + // implemented + for (const TyIdx &tyIdx : classType.GetInterfaceImplemented()) { + found = found || SearchStructMethodJava(tyIdx, mirBuilder, argIsStatic, false); + } + } else if (structType.GetKind() == kTypeInterface) { + // parent + MIRInterfaceType &interfaceType = static_cast(structType); + for (const TyIdx &tyIdx : interfaceType.GetParentsTyIdx()) { + found = found || SearchStructMethodJava(tyIdx, mirBuilder, argIsStatic, false); + } + } else { + CHECK_FATAL(false, "not supported yet"); + } + return found; +} + +bool FEStructMethodInfo::SearchStructMethodJava(const TyIdx &tyIdx, MIRBuilder &mirBuilder, bool argIsStatic, + bool allowPrivate) { + MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); + if (type == nullptr) { + return false; + } + if (type->IsIncomplete()) { + return false; + } + if (type->GetKind() == kTypeClass || type->GetKind() == kTypeInterface) { + MIRStructType *structType = static_cast(type); + return SearchStructMethodJava(*structType, mirBuilder, argIsStatic, allowPrivate); + } else { + ERR(kLncErr, "parent type should be StructType"); + return false; + } +} +} // namespace maple diff --git a/src/mplfe/common/src/fe_type_manager.cpp b/src/mplfe/common/src/fe_type_manager.cpp index 7fafad6d10a9bbc6f4e7e48d22cbef5c95b995ab..412f003caf464c23dce07e30799bb844fb523905 100644 --- a/src/mplfe/common/src/fe_type_manager.cpp +++ b/src/mplfe/common/src/fe_type_manager.cpp @@ -22,19 +22,32 @@ #include "fe_config_parallel.h" namespace maple { +const UniqueFEIRType FETypeManager::kPrimFEIRTypeUnknown = std::make_unique(PTY_unknown); +const UniqueFEIRType FETypeManager::kPrimFEIRTypeU1 = std::make_unique(PTY_u1); +const UniqueFEIRType FETypeManager::kPrimFEIRTypeI8 = std::make_unique(PTY_i8); +const UniqueFEIRType FETypeManager::kPrimFEIRTypeU8 = std::make_unique(PTY_u8); +const UniqueFEIRType FETypeManager::kPrimFEIRTypeI16 = std::make_unique(PTY_i16); +const UniqueFEIRType FETypeManager::kPrimFEIRTypeU16 = std::make_unique(PTY_u16); +const UniqueFEIRType FETypeManager::kPrimFEIRTypeI32 = std::make_unique(PTY_i32); +const UniqueFEIRType FETypeManager::kPrimFEIRTypeU32 = std::make_unique(PTY_u32); +const UniqueFEIRType FETypeManager::kPrimFEIRTypeI64 = std::make_unique(PTY_i64); +const UniqueFEIRType FETypeManager::kPrimFEIRTypeU64 = std::make_unique(PTY_u64); +const UniqueFEIRType FETypeManager::kPrimFEIRTypeF32 = std::make_unique(PTY_f32); +const UniqueFEIRType FETypeManager::kPrimFEIRTypeF64 = std::make_unique(PTY_f64); +const UniqueFEIRType FETypeManager::kFEIRTypeJavaObject = std::make_unique(PTY_ref); +const UniqueFEIRType FETypeManager::kFEIRTypeJavaClass = std::make_unique(PTY_ref); +const UniqueFEIRType FETypeManager::kFEIRTypeJavaString = std::make_unique(PTY_ref); + FETypeManager::FETypeManager(MIRModule &moduleIn) : module(moduleIn), mp(memPoolCtrler.NewMemPool("mempool for FETypeManager")), allocator(mp), builder(&module), - structNameTypeMap(allocator.Adapter()), - structNameSrcMap(allocator.Adapter()), - structSameNameSrcList(allocator.Adapter()), - srcLang(kSrcLangJava), - nameFuncMap(allocator.Adapter()), - nameStaticFuncMap(allocator.Adapter()), - mpltNameFuncMap(allocator.Adapter()), - mpltNameStaticFuncMap(allocator.Adapter()) {} + srcLang(kSrcLangJava) { + static_cast(kFEIRTypeJavaObject.get())->LoadFromJavaTypeName("Ljava/lang/Object;", false); + static_cast(kFEIRTypeJavaClass.get())->LoadFromJavaTypeName("Ljava/lang/Class;", false); + static_cast(kFEIRTypeJavaString.get())->LoadFromJavaTypeName("Ljava/lang/String;", false); +} FETypeManager::~FETypeManager() { mp = nullptr; @@ -200,6 +213,20 @@ MIRType *FETypeManager::GetOrCreateClassOrInterfacePtrType(const GStrIdx &nameId return ptrType; } +MIRStructType *FETypeManager::GetStructTypeFromName(const std::string &name) { + GStrIdx nameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(name); + return GetStructTypeFromName(nameIdx); +} + +MIRStructType *FETypeManager::GetStructTypeFromName(const GStrIdx &nameIdx) { + auto it = structNameTypeMap.find(nameIdx); + if (it == structNameTypeMap.end()) { + return nullptr; + } else { + return it->second.first; + } +} + MIRType *FETypeManager::GetOrCreateTypeFromName(const std::string &name, FETypeFlag typeFlag, bool usePtr) { CHECK_FATAL(!name.empty(), "type name is empty"); PrimType pty = GetPrimType(name); @@ -276,29 +303,40 @@ void FETypeManager::AddClassToModule(const MIRStructType &structType) { module.AddClass(structType.GetTypeIndex()); } -FEStructElemInfo *FETypeManager::RegisterStructElemInfo(const GStrIdx &structIdx, const GStrIdx &fullNameIdxOrin, - const GStrIdx &fullNameIdxMpl) { - FEStructElemInfo *ptrInfo = GetStructElemInfo(structIdx, fullNameIdxMpl); +FEStructElemInfo *FETypeManager::RegisterStructFieldInfo(const GStrIdx &fullNameIdx, MIRSrcLang srcLang, + bool isStatic) { + FEStructElemInfo *ptrInfo = GetStructElemInfo(fullNameIdx); if (ptrInfo != nullptr) { return ptrInfo; } - UniqueFEStructElemInfo info = std::make_unique(fullNameIdxOrin, fullNameIdxMpl); + UniqueFEStructElemInfo info = std::make_unique(fullNameIdx, srcLang, isStatic); ptrInfo = info.get(); listStructElemInfo.push_back(std::move(info)); - mapStructElemInfo[structIdx][fullNameIdxMpl] = ptrInfo; + CHECK_FATAL(mapStructElemInfo.insert(std::make_pair(fullNameIdx, ptrInfo)).second == true, + "register struct elem info failed"); return ptrInfo; } -FEStructElemInfo *FETypeManager::GetStructElemInfo(const GStrIdx &structIdx, const GStrIdx &fullNameIdxMpl) const { - auto itStruct = mapStructElemInfo.find(structIdx); - if (itStruct == mapStructElemInfo.end()) { - return nullptr; +FEStructElemInfo *FETypeManager::RegisterStructMethodInfo(const GStrIdx &fullNameIdx, MIRSrcLang srcLang, + bool isStatic) { + FEStructElemInfo *ptrInfo = GetStructElemInfo(fullNameIdx); + if (ptrInfo != nullptr) { + return ptrInfo; } - auto itInfo = itStruct->second.find(fullNameIdxMpl); - if (itInfo == itStruct->second.end()) { + UniqueFEStructElemInfo info = std::make_unique(fullNameIdx, srcLang, isStatic); + ptrInfo = info.get(); + listStructElemInfo.push_back(std::move(info)); + CHECK_FATAL(mapStructElemInfo.insert(std::make_pair(fullNameIdx, ptrInfo)).second == true, + "register struct elem info failed"); + return ptrInfo; +} + +FEStructElemInfo *FETypeManager::GetStructElemInfo(const GStrIdx &fullNameIdx) const { + auto it = mapStructElemInfo.find(fullNameIdx); + if (it == mapStructElemInfo.end()) { return nullptr; } - return itInfo->second; + return it->second; } MIRFunction *FETypeManager::GetMIRFunction(const std::string &classMethodName, bool isStatic){ @@ -307,13 +345,13 @@ MIRFunction *FETypeManager::GetMIRFunction(const std::string &classMethodName, b } MIRFunction *FETypeManager::GetMIRFunction(const GStrIdx &nameIdx, bool isStatic) { - const MapleUnorderedMap &funcMap = isStatic ? nameStaticFuncMap : nameFuncMap; + const std::unordered_map &funcMap = isStatic ? nameStaticFuncMap : nameFuncMap; auto it = funcMap.find(nameIdx); if (it != funcMap.end()) { return it->second; } - const MapleUnorderedMap &mpltFuncMap = isStatic ? mpltNameStaticFuncMap : - mpltNameFuncMap; + const std::unordered_map &mpltFuncMap = isStatic ? mpltNameStaticFuncMap : + mpltNameFuncMap; auto it2 = mpltFuncMap.find(nameIdx); if (it2 != mpltFuncMap.end()) { return it2->second; @@ -385,6 +423,10 @@ MIRFunction *FETypeManager::CreateFunction(const std::string &methodName, const return CreateFunction(nameIdx, returnType->GetTypeIndex(), argsTypeIdx, isVarg, isStatic); } +bool FETypeManager::IsAntiProguardFieldStruct(const GStrIdx &structNameIdx) { + return setAntiProguardFieldStructIdx.find(structNameIdx) != setAntiProguardFieldStructIdx.end(); +} + bool FETypeManager::IsStructType(const MIRType &type) { MIRTypeKind kind = type.GetKind(); return kind == kTypeStruct || kind == kTypeStructIncomplete || @@ -467,4 +509,31 @@ std::string FETypeManager::TypeAttrsToString(const TypeAttrs &attrs) { ss << " "; return ss.str(); } -} // namespace maple + +void FETypeManager::InitMCCFunctions() { + InitFuncMCCGetOrInsertLiteral(); +} + +void FETypeManager::InitFuncMCCGetOrInsertLiteral() { + std::string funcName = "MCC_GetOrInsertLiteral"; + GStrIdx nameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(funcName); + MIRType *typeString = kFEIRTypeJavaString->GenerateMIRTypeAuto(kSrcLangJava); + std::vector argsType; + funcMCCGetOrInsertLiteral = CreateFunction(nameIdx, typeString->GetTypeIndex(), argsType, false, false); + nameMCCFuncMap[nameIdx] = funcMCCGetOrInsertLiteral; +} + +MIRFunction *FETypeManager::GetMCCFunction(const std::string &funcName) const { + GStrIdx funcNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(funcName); + return GetMCCFunction(funcNameIdx); +} + +MIRFunction *FETypeManager::GetMCCFunction(const GStrIdx &funcNameIdx) const { + auto it = nameMCCFuncMap.find(funcNameIdx); + if (it == nameMCCFuncMap.end()) { + return nullptr; + } else { + return it->second; + } +} +} // namespace maple \ No newline at end of file diff --git a/src/mplfe/common/src/fe_utils_java.cpp b/src/mplfe/common/src/fe_utils_java.cpp index 67ae9a062eaf6ee6c1c4fe338a73e24b0886ffd2..c01223e06fe1b18318c13d09d103406fbc80f232 100644 --- a/src/mplfe/common/src/fe_utils_java.cpp +++ b/src/mplfe/common/src/fe_utils_java.cpp @@ -13,7 +13,7 @@ * See the Mulan PSL v1 for more details. */ #include "fe_utils_java.h" -#include "name_mangler.h" +#include "namemangler.h" namespace maple { std::vector FEUtilJava::SolveMethodSignature(std::string signature, bool inMpl) { @@ -57,4 +57,4 @@ std::string FEUtilJava::SolveParamNameInJavaFormat(const std::string &signature) } } } -} // namespace maple \ No newline at end of file +} // namespace maple diff --git a/src/mplfe/common/src/feir_builder.cpp b/src/mplfe/common/src/feir_builder.cpp index 9d1ade71db2e1a3125238640c1d2c5fa532504e3..6262f9a813808f26e056e9f36dec6cf69ffd43d0 100644 --- a/src/mplfe/common/src/feir_builder.cpp +++ b/src/mplfe/common/src/feir_builder.cpp @@ -17,6 +17,7 @@ #include "global_tables.h" #include "feir_var_reg.h" #include "feir_var_name.h" +#include "fe_type_manager.h" namespace maple { UniqueFEIRType FEIRBuilder::CreateType(PrimType basePty, const GStrIdx &baseNameIdx, uint32 dim) { @@ -186,6 +187,20 @@ UniqueFEIRStmt FEIRBuilder::CreateStmtSwitch(UniqueFEIRExpr expr) { return stmt; } +UniqueFEIRStmt FEIRBuilder::CreateStmtJavaConstClass(UniqueFEIRVar dstVar, UniqueFEIRType type) { + UniqueFEIRType dstType = FETypeManager::kFEIRTypeJavaClass->Clone(); + dstVar->SetType(std::move(dstType)); + UniqueFEIRStmt stmt = std::make_unique(std::move(dstVar), std::move(type)); + return stmt; +} + +UniqueFEIRStmt FEIRBuilder::CreateStmtJavaConstString(UniqueFEIRVar dstVar, const GStrIdx &strIdx) { + UniqueFEIRType dstType = FETypeManager::kFEIRTypeJavaClass->Clone(); + dstVar->SetType(std::move(dstType)); + UniqueFEIRStmt stmt = std::make_unique(std::move(dstVar), strIdx); + return stmt; +} + UniqueFEIRStmt FEIRBuilder::CreateStmtJavaCheckCast(UniqueFEIRVar dstVar, UniqueFEIRVar srcVar, UniqueFEIRType type) { UniqueFEIRExpr expr = CreateExprDRead(std::move(srcVar)); UniqueFEIRStmt stmt = std::make_unique(std::move(dstVar), std::move(expr), std::move(type), diff --git a/src/mplfe/common/src/feir_stmt.cpp b/src/mplfe/common/src/feir_stmt.cpp index e098956ca87cc5aa77522bfa515478b993f5855d..11040270b46140b9468fc4de5e18bdc6bced539f 100644 --- a/src/mplfe/common/src/feir_stmt.cpp +++ b/src/mplfe/common/src/feir_stmt.cpp @@ -14,10 +14,12 @@ */ #include "feir_stmt.h" #include "opcode_info.h" -#include "feir_builder.h" +#include "literalstrname.h" #include "mir_type.h" +#include "feir_builder.h" #include "feir_var_reg.h" #include "feir_var_name.h" +#include "fe_manager.h" #include "mplfe_env.h" namespace maple { @@ -124,7 +126,6 @@ FEIRStmtAssign::FEIRStmtAssign(FEIRNodeKind argKind, std::unique_ptr ar : FEIRStmt(argKind), hasException(false), var(std::move(argVar)) { - CHECK_FATAL(var != nullptr, "input var is nullptr"); } // ---------- FEStmtDAssign ---------- @@ -177,6 +178,154 @@ std::list FEIRStmtJavaTypeCheck::GenMIRStmtsImpl(MIRBuilder &mirBuild return ans; } +// ---------- FEIRStmtJavaConstClass ---------- +FEIRStmtJavaConstClass::FEIRStmtJavaConstClass(std::unique_ptr argVar, std::unique_ptr argType) + : FEIRStmtAssign(FEIRNodeKind::kStmtJavaConstClass, std::move(argVar)), + type(std::move(argType)) {} + +std::list FEIRStmtJavaConstClass::GenMIRStmtsImpl(MIRBuilder &mirBuilder) const { + std::list ans; + MIRSymbol *varSym = var->GenerateLocalMIRSymbol(mirBuilder); + MapleVector args(mirBuilder.GetCurrentFuncCodeMpAllocator()->Adapter()); + MIRType *ptrType = type->GenerateMIRTypeAuto(kSrcLangJava); + BaseNode *expr = + mirBuilder.CreateExprIntrinsicop(INTRN_JAVA_CONST_CLASS, OP_intrinsicopwithtype, *ptrType, args); + StmtNode *stmt = mirBuilder.CreateStmtDassign(*varSym, 0, expr); + ans.push_back(stmt); + return ans; +} + +// ---------- FEIRStmtJavaConstString ---------- +FEIRStmtJavaConstString::FEIRStmtJavaConstString(std::unique_ptr argVar, const GStrIdx &argStrIdx) + : FEIRStmtAssign(FEIRNodeKind::kStmtJavaConstString, std::move(argVar)), + strIdx(argStrIdx) {} + +std::list FEIRStmtJavaConstString::GenMIRStmtsImpl(MIRBuilder &mirBuilder) const { + std::list ans; + const std::string &str = GlobalTables::GetStrTable().GetStringFromStrIdx(strIdx); + MIRSymbol *literalVal = FEManager::GetJavaStringManager().GetLiteralVar(str); + if (literalVal == nullptr) { + literalVal = FEManager::GetJavaStringManager().CreateLiteralVar(mirBuilder, str, false); + } + MIRSymbol *literalValPtr = FEManager::GetJavaStringManager().GetLiteralPtrVar(literalVal); + if (literalValPtr == nullptr) { + std::string localStrName = kLocalStringPrefix + std::to_string(static_cast(strIdx)); + MIRType *typeString = FETypeManager::kFEIRTypeJavaString->GenerateMIRTypeAuto(kSrcLangJava); + MIRSymbol *symbolLocal = mirBuilder.GetOrCreateLocalDecl(localStrName.c_str(), *typeString); + MapleVector args(mirBuilder.GetCurrentFuncCodeMpAllocator()->Adapter()); + args.push_back(mirBuilder.CreateExprAddrof(0, *literalVal)); + StmtNode *stmtCreate = mirBuilder.CreateStmtCallAssigned( + FEManager::GetTypeManager().GetMCCGetOrInsertLiteral()->GetPuidx(), args, symbolLocal, OP_callassigned); + ans.push_back(stmtCreate); + literalValPtr = symbolLocal; + } + MIRSymbol *varDst = var->GenerateLocalMIRSymbol(mirBuilder); + AddrofNode *node = mirBuilder.CreateDread(*literalValPtr, PTY_ptr); + StmtNode *stmt = mirBuilder.CreateStmtDassign(*varDst, 0, node); + ans.push_back(stmt); + return ans; +} + +// ---------- FEIRStmtJavaMultiANewArray ---------- +UniqueFEIRVar FEIRStmtJavaMultiANewArray::varSize = nullptr; +UniqueFEIRVar FEIRStmtJavaMultiANewArray::varClass = nullptr; +UniqueFEIRType FEIRStmtJavaMultiANewArray::typeAnnotation = nullptr; +FEStructMethodInfo *FEIRStmtJavaMultiANewArray::methodInfoNewInstance = nullptr; + +FEIRStmtJavaMultiANewArray::FEIRStmtJavaMultiANewArray(std::unique_ptr argVar, + std::unique_ptr argType) + : FEIRStmtAssign(FEIRNodeKind::kStmtJavaMultiANewArray, std::move(argVar)), + type(std::move(argType)) {} + +void FEIRStmtJavaMultiANewArray::AddVarSize(std::unique_ptr varSize) { + varSize->SetType(FETypeManager::kPrimFEIRTypeI32->Clone()); + UniqueFEIRExpr expr = FEIRBuilder::CreateExprDRead(std::move(varSize)); + exprSizes.push_back(std::move(expr)); +} + +void FEIRStmtJavaMultiANewArray::AddVarSizeRev(std::unique_ptr varSize) { + varSize->SetType(FETypeManager::kPrimFEIRTypeI32->Clone()); + UniqueFEIRExpr expr = FEIRBuilder::CreateExprDRead(std::move(varSize)); + exprSizes.push_front(std::move(expr)); +} + +std::list FEIRStmtJavaMultiANewArray::GenMIRStmtsImpl(MIRBuilder &mirBuilder) const { + std::list ans; + // size array fill + MapleVector argsSizeArrayFill(mirBuilder.GetCurrentFuncCodeMpAllocator()->Adapter()); + for (const UniqueFEIRExpr &expr : exprSizes) { + BaseNode *node = expr->GenMIRNode(mirBuilder); + argsSizeArrayFill.push_back(node); + } + MIRSymbol *symSize = GetVarSize()->GenerateLocalMIRSymbol(mirBuilder); + StmtNode *stmtSizeArrayFill = mirBuilder.CreateStmtIntrinsicCallAssigned(INTRN_JAVA_ARRAY_FILL, argsSizeArrayFill, + symSize, TyIdx(PTY_i32)); + ans.push_back(stmtSizeArrayFill); + // class annotation + FEIRStmtJavaConstClass feStmtConstClass(GetVarClass()->Clone(), GetTypeAnnotation()->Clone()); + std::list stmtsConstClass = feStmtConstClass.GenMIRStmts(mirBuilder); + ans.insert(ans.end(), stmtsConstClass.begin(), stmtsConstClass.end()); + // invoke newInstance + UniqueFEIRVar varRetCall = var->Clone(); + varRetCall->SetType(FETypeManager::kFEIRTypeJavaObject->Clone()); + FEIRStmtCallAssign feStmtCall(GetMethodInfoNewInstance(), OP_call, varRetCall->Clone(), true); + feStmtCall.AddExprArg(FEIRBuilder::CreateExprDRead(GetVarClass()->Clone())); + feStmtCall.AddExprArg(FEIRBuilder::CreateExprDRead(GetVarSize()->Clone())); + std::list stmtsCall = feStmtCall.GenMIRStmts(mirBuilder); + ans.insert(ans.end(), stmtsCall.begin(), stmtsCall.end()); + // check cast + var->SetType(type->Clone()); + UniqueFEIRExpr expr = std::make_unique(std::move(varRetCall)); + FEIRStmtJavaTypeCheck feStmtCheck(var->Clone(), std::move(expr), type->Clone(), FEIRStmtJavaTypeCheck::kCheckCast); + std::list stmtsCheck = feStmtCheck.GenMIRStmts(mirBuilder); + ans.insert(ans.end(), stmtsCheck.begin(), stmtsCheck.end()); + return ans; +} + +const UniqueFEIRVar &FEIRStmtJavaMultiANewArray::GetVarSize() { + if (varSize != nullptr) { + return varSize; + } + MPLFE_PARALLEL_FORBIDDEN(); + GStrIdx varNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName("tmpsize"); + UniqueFEIRType varSizeType = FETypeManager::kPrimFEIRTypeI32->Clone(); + varSizeType->ArrayIncrDim(); + varSize = std::make_unique(varNameIdx, std::move(varSizeType), true); + return varSize; +} + +const UniqueFEIRVar &FEIRStmtJavaMultiANewArray::GetVarClass() { + if (varClass != nullptr) { + return varClass; + } + MPLFE_PARALLEL_FORBIDDEN(); + GStrIdx varNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName("tmpclass"); + varClass = std::make_unique(varNameIdx, FETypeManager::kFEIRTypeJavaClass->Clone(), true); + return varClass; +} + +const UniqueFEIRType &FEIRStmtJavaMultiANewArray::GetTypeAnnotation() { + if (typeAnnotation != nullptr) { + return typeAnnotation; + } + MPLFE_PARALLEL_FORBIDDEN(); + typeAnnotation = std::make_unique(PTY_ref); + static_cast(typeAnnotation.get())->LoadFromJavaTypeName("Ljava/lang/annotation/Annotation;", false); + return typeAnnotation; +} + +FEStructMethodInfo &FEIRStmtJavaMultiANewArray::GetMethodInfoNewInstance() { + if (methodInfoNewInstance != nullptr) { + return *methodInfoNewInstance; + } + std::string methodNameJava = "Ljava/lang/reflect/Array;|newInstance|(Ljava/lang/Class;[I)Ljava/lang/Object;"; + GStrIdx methodNameIdx = + GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(NameMangler::EncodeName(methodNameJava)); + methodInfoNewInstance = static_cast( + FEManager::GetTypeManager().RegisterStructMethodInfo(methodNameIdx, kSrcLangJava, true)); + return *methodInfoNewInstance; +} + // ---------- FEIRStmtUseOnly ---------- FEIRStmtUseOnly::FEIRStmtUseOnly(FEIRNodeKind argKind, Opcode argOp, std::unique_ptr argExpr) : FEIRStmt(argKind), @@ -300,6 +449,160 @@ std::list FEIRStmtArrayStore::GenMIRStmtsImpl(MIRBuilder &mirBuilder) return std::list({ stmt }); } +// ---------- FEIRStmtFieldStore ---------- +FEIRStmtFieldStore::FEIRStmtFieldStore(UniqueFEIRVar argVarObj, UniqueFEIRVar argVarField, + FEStructFieldInfo &argFieldInfo, bool argIsStatic) + : FEIRStmt(FEIRNodeKind::kStmtFieldStore), + varObj(std::move(argVarObj)), + varField(std::move(argVarField)), + fieldInfo(argFieldInfo), + isStatic(argIsStatic) {} + +std::list FEIRStmtFieldStore::GenMIRStmtsImpl(MIRBuilder &mirBuilder) const { + // prepare and find root + fieldInfo.Prepare(mirBuilder, isStatic); + if (isStatic) { + return GenMIRStmtsImplForStatic(mirBuilder); + } else { + return GenMIRStmtsImplForNonStatic(mirBuilder); + } +} + +std::list FEIRStmtFieldStore::GenMIRStmtsImplForStatic(MIRBuilder &mirBuilder) const { + CHECK_FATAL(fieldInfo.GetFieldNameIdx() != 0, "invalid name idx"); + UniqueFEIRVar varTarget = std::make_unique(fieldInfo.GetFieldNameIdx(), fieldInfo.GetType()->Clone()); + varTarget->SetGlobal(true); + UniqueFEIRExpr exprDRead = FEIRBuilder::CreateExprDRead(varField->Clone()); + UniqueFEIRStmt stmtDAssign = FEIRBuilder::CreateStmtDAssign(std::move(varTarget), std::move(exprDRead)); + return stmtDAssign->GenMIRStmts(mirBuilder); +} + +std::list FEIRStmtFieldStore::GenMIRStmtsImplForNonStatic(MIRBuilder &mirBuilder) const { + std::list ans; + FieldID fieldID = fieldInfo.GetFieldID(); + CHECK_FATAL(fieldID != 0, "invalid field ID"); + MIRStructType *structType = FEManager::GetTypeManager().GetStructTypeFromName(fieldInfo.GetStructName()); + CHECK_NULL_FATAL(structType); + MIRType *ptrStructType = GlobalTables::GetTypeTable().GetOrCreatePointerType(*structType, PTY_ref); + UniqueFEIRExpr exprDReadObj = FEIRBuilder::CreateExprDRead(varObj->Clone()); + UniqueFEIRExpr exprDReadField = FEIRBuilder::CreateExprDRead(varField->Clone()); + BaseNode *nodeObj = exprDReadObj->GenMIRNode(mirBuilder); + BaseNode *nodeField = exprDReadField->GenMIRNode(mirBuilder); + StmtNode *stmt = mirBuilder.CreateStmtIassign(*ptrStructType, fieldID, nodeObj, nodeField); + ans.push_back(stmt); + return ans; +} + +// ---------- FEIRStmtFieldLoad ---------- +FEIRStmtFieldLoad::FEIRStmtFieldLoad(UniqueFEIRVar argVarObj, UniqueFEIRVar argVarField, + FEStructFieldInfo &argFieldInfo, bool argIsStatic) + : FEIRStmtAssign(FEIRNodeKind::kStmtFieldLoad, std::move(argVarField)), + varObj(std::move(argVarObj)), + fieldInfo(argFieldInfo), + isStatic(argIsStatic) {} + +std::list FEIRStmtFieldLoad::GenMIRStmtsImpl(MIRBuilder &mirBuilder) const { + // prepare and find root + fieldInfo.Prepare(mirBuilder, isStatic); + if (isStatic) { + return GenMIRStmtsImplForStatic(mirBuilder); + } else { + return GenMIRStmtsImplForNonStatic(mirBuilder); + } +} + +std::list FEIRStmtFieldLoad::GenMIRStmtsImplForStatic(MIRBuilder &mirBuilder) const { + UniqueFEIRVar varTarget = std::make_unique(fieldInfo.GetFieldNameIdx(), fieldInfo.GetType()->Clone()); + varTarget->SetGlobal(true); + UniqueFEIRExpr exprDRead = FEIRBuilder::CreateExprDRead(std::move(varTarget)); + UniqueFEIRStmt stmtDAssign = FEIRBuilder::CreateStmtDAssign(var->Clone(), std::move(exprDRead)); + return stmtDAssign->GenMIRStmts(mirBuilder); +} + +std::list FEIRStmtFieldLoad::GenMIRStmtsImplForNonStatic(MIRBuilder &mirBuilder) const { + std::list ans; + FieldID fieldID = fieldInfo.GetFieldID(); + CHECK_FATAL(fieldID != 0, "invalid field ID"); + MIRStructType *structType = FEManager::GetTypeManager().GetStructTypeFromName(fieldInfo.GetStructName()); + CHECK_NULL_FATAL(structType); + MIRType *ptrStructType = GlobalTables::GetTypeTable().GetOrCreatePointerType(*structType, PTY_ref); + MIRType *fieldType = fieldInfo.GetType()->GenerateMIRTypeAuto(fieldInfo.GetSrcLang()); + UniqueFEIRExpr exprDReadObj = FEIRBuilder::CreateExprDRead(varObj->Clone()); + BaseNode *nodeObj = exprDReadObj->GenMIRNode(mirBuilder); + BaseNode *nodeVal = mirBuilder.CreateExprIread(*fieldType, *ptrStructType, fieldID, nodeObj); + MIRSymbol *valRet = var->GenerateLocalMIRSymbol(mirBuilder); + StmtNode *stmt = mirBuilder.CreateStmtDassign(*valRet, 0, nodeVal); + ans.push_back(stmt); + return ans; +} + +// ---------- FEIRStmtCallAssign ---------- +std::map FEIRStmtCallAssign::mapOpAssignToOp = FEIRStmtCallAssign::InitMapOpAssignToOp(); +std::map FEIRStmtCallAssign::mapOpToOpAssign = FEIRStmtCallAssign::InitMapOpToOpAssign(); + +FEIRStmtCallAssign::FEIRStmtCallAssign(FEStructMethodInfo &argMethodInfo, Opcode argMIROp, UniqueFEIRVar argVarRet, + bool argIsStatic) + : FEIRStmtAssign(FEIRNodeKind::kStmtCallAssign, std::move(argVarRet)), + methodInfo(argMethodInfo), + mirOp(argMIROp), + varRet(std::move(argVarRet)), + isStatic(argIsStatic) {} + +std::map FEIRStmtCallAssign::InitMapOpAssignToOp() { + std::map ans; + ans[OP_callassigned] = OP_call; + ans[OP_virtualcallassigned] = OP_virtualcall; + ans[OP_superclasscallassigned] = OP_superclasscall; + ans[OP_interfacecallassigned] = OP_interfacecall; + return ans; +} + +std::map FEIRStmtCallAssign::InitMapOpToOpAssign() { + std::map ans; + ans[OP_call] = OP_callassigned; + ans[OP_virtualcall] = OP_virtualcallassigned; + ans[OP_superclasscall] = OP_superclasscallassigned; + ans[OP_interfacecall] = OP_interfacecallassigned; + return ans; +} + +std::list FEIRStmtCallAssign::GenMIRStmtsImpl(MIRBuilder &mirBuilder) const { + std::list ans; + StmtNode *stmtCall = nullptr; + // prepare and find root + methodInfo.Prepare(mirBuilder, isStatic); + Opcode op = AdjustMIROp(); + MapleVector args(mirBuilder.GetCurrentFuncCodeMpAllocator()->Adapter()); + for (const UniqueFEIRExpr &exprArg : exprArgs) { + BaseNode *node = exprArg->GenMIRNode(mirBuilder); + args.push_back(node); + } + PUIdx puIdx = methodInfo.GetPuIdx(); + if (methodInfo.IsReturnVoid()) { + stmtCall = mirBuilder.CreateStmtCall(puIdx, args, op); + } else { + MIRSymbol *retVarSym = var->GenerateLocalMIRSymbol(mirBuilder); + stmtCall = mirBuilder.CreateStmtCallAssigned(puIdx, args, retVarSym, op); + } + ans.push_back(stmtCall); + return ans; +} + +Opcode FEIRStmtCallAssign::AdjustMIROp() const { + if (methodInfo.IsReturnVoid()) { + auto it = mapOpAssignToOp.find(mirOp); + if (it != mapOpAssignToOp.end()) { + return it->second; + } + } else { + auto it = mapOpToOpAssign.find(mirOp); + if (it != mapOpToOpAssign.end()) { + return it->second; + } + } + return mirOp; +} + // ---------- FEIRExpr ---------- FEIRExpr::FEIRExpr(FEIRNodeKind argKind) : kind(argKind), diff --git a/src/mplfe/common/src/feir_type.cpp b/src/mplfe/common/src/feir_type.cpp index 16b4e5eee381a5f123c58e6624440c8e64072695..66300fe316144d744e686c23b0dee9699e165bfb 100644 --- a/src/mplfe/common/src/feir_type.cpp +++ b/src/mplfe/common/src/feir_type.cpp @@ -58,6 +58,17 @@ std::unique_ptr FEIRType::NewType(FEIRTypeKind argKind) { } } +MIRType *FEIRType::GenerateMIRTypeAuto(MIRSrcLang srcLang) const { + MPLFE_PARALLEL_FORBIDDEN(); + switch (srcLang) { + case kSrcLangJava: + return GenerateMIRType(!IsScalar()); + default: + CHECK_FATAL(kLncErr, "unsupported language"); + return nullptr; + } +} + // ---------- FEIRTypeDefault ---------- FEIRTypeDefault::FEIRTypeDefault() : FEIRTypeDefault(PTY_void, GStrIdx(0), 0) {} @@ -235,7 +246,7 @@ MIRType *FEIRTypeDefault::GenerateMIRTypeInternal(const GStrIdx &argTypeNameIdx, baseType = GenerateMIRTypeForPrim(); type = FEManager::GetTypeManager().GetOrCreateArrayType(*baseType, dim); } - if (primType != PTY_ref || argTypeNameIdx.GetIdx() == 0) { + if (IsScalar()) { return type; } return usePtr ? FEManager::GetTypeManager().GetOrCreatePointerType(*type) : type; diff --git a/src/mplfe/common/src/feir_var.cpp b/src/mplfe/common/src/feir_var.cpp index e0dfac1f5a2e462f4104def1f2011f747d806b0b..f359a97877327bf1f9c06b97059c5d2c237f4374 100644 --- a/src/mplfe/common/src/feir_var.cpp +++ b/src/mplfe/common/src/feir_var.cpp @@ -96,8 +96,7 @@ MIRSymbol *FEIRVar::GenerateGlobalMIRSymbolImpl(MIRBuilder &builder) const { MPLFE_PARALLEL_FORBIDDEN(); MIRType *mirType = type->GenerateMIRType(); CHECK_NULL_FATAL(mirType); - MIRType *mirPtrType = (type->IsPreciseRefType()) ? - GlobalTables::GetTypeTable().GetOrCreatePointerType(*mirType) : mirType; + MIRType *mirPtrType = (type->IsScalar()) ? mirType : GlobalTables::GetTypeTable().GetOrCreatePointerType(*mirType); CHECK_NULL_FATAL(mirPtrType); std::string name = GetName(*mirPtrType); return builder.GetOrCreateGlobalDecl(name, *mirPtrType); @@ -107,8 +106,7 @@ MIRSymbol *FEIRVar::GenerateLocalMIRSymbolImpl(MIRBuilder &builder) const { MPLFE_PARALLEL_FORBIDDEN(); MIRType *mirType = type->GenerateMIRType(); CHECK_NULL_FATAL(mirType); - MIRType *mirPtrType = (type->IsPreciseRefType()) ? - GlobalTables::GetTypeTable().GetOrCreatePointerType(*mirType) : mirType; + MIRType *mirPtrType = (type->IsScalar()) ? mirType : GlobalTables::GetTypeTable().GetOrCreatePointerType(*mirType); CHECK_NULL_FATAL(mirPtrType); std::string name = GetName(*mirPtrType); return builder.GetOrCreateLocalDecl(name, *mirPtrType); diff --git a/src/mplfe/common/src/feir_var_name.cpp b/src/mplfe/common/src/feir_var_name.cpp index 0c0036f09f050cb73916a061407505357d97bafb..507694be44e6320f055524d6b52271fc2ff0b649 100644 --- a/src/mplfe/common/src/feir_var_name.cpp +++ b/src/mplfe/common/src/feir_var_name.cpp @@ -23,10 +23,10 @@ std::string FEIRVarName::GetNameImpl(const MIRType &mirType) const { ss << name; if (withType) { ss << "_"; - if (type->IsPreciseRefType()) { - ss << "R" << mirType.GetTypeIndex().GetIdx(); - } else { + if (type->IsScalar()) { ss << GetPrimTypeName(type->GetPrimType()); + } else { + ss << "R" << mirType.GetTypeIndex().GetIdx(); } } return ss.str(); diff --git a/src/mplfe/common/src/mplfe.cpp b/src/mplfe/common/src/mplfe.cpp index 39f9c8ebeb59f63887a398a38cfeb55e485f84e3..66463b5eb539bb495875a8d4d80a6ea86420f80b 100644 --- a/src/mplfe/common/src/mplfe.cpp +++ b/src/mplfe/common/src/mplfe.cpp @@ -19,6 +19,7 @@ #include "fe_errno.h" #include "mpl_timer.h" #include "mplfe_env.h" +#include "fe_manager.h" using namespace maple; int main(int argc, char **argv) { @@ -42,6 +43,7 @@ int main(int argc, char **argv) { compiler.ParseInputs(); compiler.PreProcessDecls(); compiler.ProcessDecls(); + FEManager::GetTypeManager().InitMCCFunctions(); compiler.PreProcessWithFunctions(); compiler.ProcessFunctions(); CHECK_FATAL(success, "Compile Error"); diff --git a/src/mplfe/common/src/mplfe_compiler.cpp b/src/mplfe/common/src/mplfe_compiler.cpp index 4e36b1ce14a99fbc7485d093a03ebb21be1d005f..1d697621438626997c74cb21e7387817cb8707c6 100644 --- a/src/mplfe/common/src/mplfe_compiler.cpp +++ b/src/mplfe/common/src/mplfe_compiler.cpp @@ -188,6 +188,7 @@ void MPLFECompiler::ProcessFunctions() { ASSERT(comp != nullptr, "nullptr check"); uint32 nthreads = FEOptions::GetInstance().GetNThreads(); if (comp->Parallelable() && nthreads > 0) { + FEConfigParallel::GetInstance().EnableParallel(); success = comp->ProcessFunctionParallel(nthreads) && success; } else { success = comp->ProcessFunctionSerial() && success; diff --git a/src/mplfe/common/src/mplfe_compiler_component.cpp b/src/mplfe/common/src/mplfe_compiler_component.cpp index 08615e95fbb8bb38751f5f085a241de49265a727..8a0ecdc90822e901e6de50f15c9416243c3dbcef 100644 --- a/src/mplfe/common/src/mplfe_compiler_component.cpp +++ b/src/mplfe/common/src/mplfe_compiler_component.cpp @@ -16,6 +16,7 @@ #include #include "fe_macros.h" #include "fe_timer.h" +#include "fe_config_parallel.h" namespace maple { // ---------- FEFunctionProcessTask ---------- @@ -41,6 +42,14 @@ void FEFunctionProcessSchedular::AddFunctionProcessTask(const std::unique_ptr= FEOptions::kDumpLevelInfoDebug) { + INFO(kLncInfo, "Start Run Thread (tid=%lx)", tid); + } + FEConfigParallel::GetInstance().RegisterRunThreadID(tid); +} + // ---------- MPLFECompilerComponent ---------- MPLFECompilerComponent::MPLFECompilerComponent(MIRModule &argModule, MIRSrcLang argSrcLang) : module(argModule), diff --git a/src/mplfe/jbc_input/include/jbc_class2fe_helper.h b/src/mplfe/jbc_input/include/jbc_class2fe_helper.h index 6a95c154be4e521dbd569d4c31fbbaf1b4fc0f5c..44f261c7e363d4da3711da65f56c0d185db9375e 100644 --- a/src/mplfe/jbc_input/include/jbc_class2fe_helper.h +++ b/src/mplfe/jbc_input/include/jbc_class2fe_helper.h @@ -75,6 +75,7 @@ class JBCClassMethod2FEHelper : public FEInputMethodHelper { } protected: + bool ProcessDeclImpl(MapleAllocator &allocator) override; void SolveReturnAndArgTypesImpl(MapleAllocator &allocator) override; std::string GetMethodNameImpl(bool inMpl) const override; FuncAttrs GetAttrsImpl() const override; diff --git a/src/mplfe/jbc_input/include/jbc_class_const.h b/src/mplfe/jbc_input/include/jbc_class_const.h index fbda8c20c9cb8219eb8857f80f70bb4de4c5efde..02aa4ada22d965ae4e78b70d71b1e4dc8a0338cf 100644 --- a/src/mplfe/jbc_input/include/jbc_class_const.h +++ b/src/mplfe/jbc_input/include/jbc_class_const.h @@ -23,6 +23,7 @@ #include "simple_xml.h" #include "basic_io.h" #include "fe_struct_elem_info.h" +#include "feir_type.h" namespace maple { namespace jbc { @@ -231,6 +232,10 @@ class JBCConstClass : public JBCConst { return MapleStringToStd(nameMpl); } + const FEIRType *GetFEIRType() const { + return feType; + } + protected: bool ParseFileImpl(BasicIORead &io) override; bool PreProcessImpl(const JBCConstPool &constPool) override; @@ -245,6 +250,7 @@ class JBCConstClass : public JBCConst { GStrIdx strIdxMpl; MapleString nameOrin; MapleString nameMpl; + FEIRType *feType = nullptr; }; class JBCConstString : public JBCConst { @@ -322,10 +328,16 @@ class JBCConstRef : public JBCConst { return constClass; } - const FEStructElemInfo *GetFEStructElemInfo() const { + FEStructElemInfo *GetFEStructElemInfo() const { + CHECK_NULL_FATAL(feStructElemInfo); return feStructElemInfo; } + const FEIRType *GetOwnerFEIRType() const { + CHECK_NULL_FATAL(constClass); + return constClass->GetFEIRType(); + } + protected: bool ParseFileImpl(BasicIORead &io) override; bool PreProcessImpl(const JBCConstPool &constPool) override; diff --git a/src/mplfe/jbc_input/include/jbc_opcode.h b/src/mplfe/jbc_input/include/jbc_opcode.h index 32c11d1133f58aa755fbc808efa72a76662cf947..d26a8d0bc4ef907c4134a3fc1e44daf260519aea 100644 --- a/src/mplfe/jbc_input/include/jbc_opcode.h +++ b/src/mplfe/jbc_input/include/jbc_opcode.h @@ -23,6 +23,7 @@ #include "mempool_allocator.h" #include "factory.h" #include "basic_io.h" +#include "feir_type.h" namespace maple { namespace jbc { @@ -557,6 +558,7 @@ class JBCOpNew : public JBCOp { GStrIdx GetTypeNameIdx(const JBCConstPool &constPool) const; std::string GetTypeName(const JBCConstPool &constPool) const; + const FEIRType *GetFEIRType(const JBCConstPool &constPool) const; uint16 GetRefTypeIdx() const { return refTypeIdx; } @@ -582,6 +584,7 @@ class JBCOpNew : public JBCOp { private: static std::map> InitMapOpInputTypes(); std::string GetPrimTypeName() const; + const UniqueFEIRType &GetPrimFEIRType() const; uint16 refTypeIdx; uint8 primType; @@ -613,6 +616,7 @@ class JBCOpMultiANewArray : public JBCOp { const std::vector &GetInputTypesFromStackImpl() const override; std::vector GetInputTypesFromStackImpl(const JBCConstPool &constPool) const override; JBCPrimType GetOutputTypesToStackImpl() const override; + std::string DumpImpl(const JBCConstPool &constPool) const override; private: uint16 refTypeIdx; diff --git a/src/mplfe/jbc_input/include/jbc_stack2fe_helper.h b/src/mplfe/jbc_input/include/jbc_stack2fe_helper.h index ea8473156b64b4c1b4e62ae6b9f843f2fead222b..0bfd9bbd18a33a7f34c2850b04c58b0e96551192 100644 --- a/src/mplfe/jbc_input/include/jbc_stack2fe_helper.h +++ b/src/mplfe/jbc_input/include/jbc_stack2fe_helper.h @@ -87,6 +87,7 @@ class JBCStack2FEHelper { } static PrimType JBCStackItemTypeToPrimType(jbc::JBCPrimType itemType); + static PrimType SimplifyPrimType(PrimType pty); protected: bool useNestExpr; diff --git a/src/mplfe/jbc_input/include/jbc_stmt.h b/src/mplfe/jbc_input/include/jbc_stmt.h index e6e6af67a8bef124941ff35e4b755d0075b00e8e..b68acf47853132a00c1cced90319d7681f410ce6 100644 --- a/src/mplfe/jbc_input/include/jbc_stmt.h +++ b/src/mplfe/jbc_input/include/jbc_stmt.h @@ -183,6 +183,18 @@ class JBCStmtInst : public JBCStmt { std::list EmitToFEIRForOpInvoke(JBCStack2FEHelper &stack2feHelper, const jbc::JBCConstPool &constPool, bool &success) const; + std::list EmitToFEIRForOpInvokeVirtual(JBCStack2FEHelper &stack2feHelper, + const jbc::JBCConstPool &constPool, + bool &success) const; + std::list EmitToFEIRForOpInvokeStatic(JBCStack2FEHelper &stack2feHelper, + const jbc::JBCConstPool &constPool, + bool &success) const; + std::list EmitToFEIRForOpInvokeInterface(JBCStack2FEHelper &stack2feHelper, + const jbc::JBCConstPool &constPool, + bool &success) const; + std::list EmitToFEIRForOpInvokeSpecial(JBCStack2FEHelper &stack2feHelper, + const jbc::JBCConstPool &constPool, + bool &success) const; std::list EmitToFEIRForOpNew(JBCStack2FEHelper &stack2feHelper, const jbc::JBCConstPool &constPool, bool &success) const; @@ -211,6 +223,8 @@ class JBCStmtInst : public JBCStmt { UniqueFEIRStmt GenerateStmtForConstI64(JBCStack2FEHelper &stack2feHelper, int64 val, bool &success) const; UniqueFEIRStmt GenerateStmtForConstF32(JBCStack2FEHelper &stack2feHelper, float val, bool &success) const; UniqueFEIRStmt GenerateStmtForConstF64(JBCStack2FEHelper &stack2feHelper, double val, bool &success) const; + void PrepareInvokeParametersAndReturn(JBCStack2FEHelper &stack2feHelper, const FEStructMethodInfo &info, + FEIRStmtCallAssign &callStmt, bool isStatic) const; }; class JBCStmtPesudoLabel; diff --git a/src/mplfe/jbc_input/src/jbc_class2fe_helper.cpp b/src/mplfe/jbc_input/src/jbc_class2fe_helper.cpp index 5fcee9d7649729dca09badb2e826a1e287049732..6923b99186f2840e5d1dbe53c996a0cdafae84e2 100644 --- a/src/mplfe/jbc_input/src/jbc_class2fe_helper.cpp +++ b/src/mplfe/jbc_input/src/jbc_class2fe_helper.cpp @@ -157,7 +157,13 @@ bool JBCClassField2FEHelper::ProcessDeclWithContainerImpl(MapleAllocator &alloca std::string name = field.IsStatic() ? (klassName + "|") : ""; name += fieldName; name += withType ? ("|" + typeName) : ""; + std::string fullName = klassName + "|" + fieldName + "|" + typeName; GStrIdx idx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(NameMangler::EncodeName(name)); + GStrIdx fullNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(NameMangler::EncodeName(fullName)); + FEStructElemInfo *elemInfo = FEManager::GetTypeManager().RegisterStructFieldInfo(fullNameIdx, kSrcLangJava, + field.IsStatic()); + elemInfo->SetDefined(); + elemInfo->SetFromDex(); FieldAttrs attrs = AccessFlag2Attribute(field.GetAccessFlag()); std::string typeNameMpl = NameMangler::EncodeName(typeName); MIRType *fieldType = FEManager::GetTypeManager().GetOrCreateTypeFromName(typeNameMpl, FETypeFlag::kSrcUnknown, true); @@ -215,6 +221,16 @@ JBCClassMethod2FEHelper::JBCClassMethod2FEHelper(MapleAllocator &allocator, cons srcLang = kSrcLangJava; } +bool JBCClassMethod2FEHelper::ProcessDeclImpl(MapleAllocator &allocator) { + std::string methodName = GetMethodName(true); + GStrIdx methodNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(methodName); + FEStructElemInfo *elemInfo = FEManager::GetTypeManager().RegisterStructMethodInfo(methodNameIdx, kSrcLangJava, + IsStatic()); + elemInfo->SetDefined(); + elemInfo->SetFromDex(); + return FEInputMethodHelper::ProcessDeclImpl(allocator); +} + void JBCClassMethod2FEHelper::SolveReturnAndArgTypesImpl(MapleAllocator &allocator) { MemPool *mp = allocator.GetMemPool(); ASSERT(mp != nullptr, "mempool is nullptr"); diff --git a/src/mplfe/jbc_input/src/jbc_class_const.cpp b/src/mplfe/jbc_input/src/jbc_class_const.cpp index 594733763f4f945c3b9b787637bcb8c9cf4104ed..70ce76a2f2eafc867df59258fdf58deb5ca3e23a 100644 --- a/src/mplfe/jbc_input/src/jbc_class_const.cpp +++ b/src/mplfe/jbc_input/src/jbc_class_const.cpp @@ -184,6 +184,7 @@ JBCConstClass::JBCConstClass(MapleAllocator &alloc, JBCConstTag t) nameOrin("", alloc.GetMemPool()), nameMpl("", alloc.GetMemPool()) { rawData.nameIdx = 0; + feType = alloc.GetMemPool()->New(PTY_ref); } JBCConstClass::JBCConstClass(MapleAllocator &alloc, JBCConstTag t, JBCConstPoolIdx argNameIdx) @@ -195,6 +196,7 @@ JBCConstClass::JBCConstClass(MapleAllocator &alloc, JBCConstTag t, JBCConstPoolI nameMpl("", alloc.GetMemPool()) { CHECK_FATAL(t == kConstClass, "invalid tag"); rawData.nameIdx = argNameIdx; + feType = alloc.GetMemPool()->New(PTY_ref); } JBCConstClass::~JBCConstClass() { @@ -217,6 +219,7 @@ bool JBCConstClass::PreProcessImpl(const JBCConstPool &constPool) { strIdxOrin = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(MapleStringToStd(nameOrin)); nameMpl = NameMangler::EncodeName(nameOrin.c_str()); strIdxMpl = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(MapleStringToStd(nameMpl)); + static_cast(feType)->LoadFromJavaTypeName(MapleStringToStd(nameMpl), true); return true; } @@ -297,12 +300,13 @@ bool JBCConstRef::PrepareFEStructElemInfo() { const std::string &className = constClass->GetClassNameOrin(); const std::string &elemName = constNameAndType->GetName(); const std::string &descName = constNameAndType->GetDesc(); - std::string fullNameOrin = className + "." + elemName + descName; - std::string fullNameMpl = NameMangler::EncodeName(className + "|" + elemName + "|" + descName); - GStrIdx fullNameIdxOrin = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fullNameOrin); - GStrIdx fullNameIdxMpl = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fullNameMpl); - feStructElemInfo = FEManager::GetTypeManager().RegisterStructElemInfo(constClass->GetClassNameIdxMpl(), - fullNameIdxOrin, fullNameIdxMpl); + std::string fullName = NameMangler::EncodeName(className + "|" + elemName + "|" + descName); + GStrIdx fullNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fullName); + if (tag == kConstFieldRef) { + feStructElemInfo = FEManager::GetTypeManager().RegisterStructFieldInfo(fullNameIdx, kSrcLangJava, false); + } else { + feStructElemInfo = FEManager::GetTypeManager().RegisterStructMethodInfo(fullNameIdx, kSrcLangJava, false); + } return feStructElemInfo != nullptr; } diff --git a/src/mplfe/jbc_input/src/jbc_opcode.cpp b/src/mplfe/jbc_input/src/jbc_opcode.cpp index b2880343af07e960ad7afc8a161d69f5258c52f8..e9069e92e29d254b18a996479510d02214b652dd 100644 --- a/src/mplfe/jbc_input/src/jbc_opcode.cpp +++ b/src/mplfe/jbc_input/src/jbc_opcode.cpp @@ -16,6 +16,7 @@ #include "jbc_class_const.h" #include "jbc_class_const_pool.h" #include "jbc_util.h" +#include "fe_type_manager.h" namespace maple { namespace jbc { @@ -1346,6 +1347,23 @@ std::string JBCOpNew::GetTypeName(const JBCConstPool &constPool) const { } } +const FEIRType *JBCOpNew::GetFEIRType(const JBCConstPool &constPool) const { + switch (op) { + case jbc::kOpNew: + case jbc::kOpANewArray: { + const JBCConst *constRaw = constPool.GetConstByIdxWithTag(refTypeIdx, JBCConstTag::kConstClass); + CHECK_NULL_FATAL(constRaw); + const JBCConstClass *constClass = static_cast(constRaw); + return constClass->GetFEIRType(); + } + case jbc::kOpNewArray: + return GetPrimFEIRType().get(); + default: + CHECK_FATAL(false, "Unexpected opcode %s for New", GetOpcodeName().c_str()); + return FETypeManager::kPrimFEIRTypeUnknown.get(); + } +} + std::string JBCOpNew::GetPrimTypeName() const { switch (primType) { case kPrimInt: @@ -1369,6 +1387,29 @@ std::string JBCOpNew::GetPrimTypeName() const { } } +const UniqueFEIRType &JBCOpNew::GetPrimFEIRType() const { + switch (primType) { + case kPrimInt: + return FETypeManager::kPrimFEIRTypeI32; + case kPrimBoolean: + return FETypeManager::kPrimFEIRTypeU1; + case kPrimByte: + return FETypeManager::kPrimFEIRTypeI8; + case kPrimShort: + return FETypeManager::kPrimFEIRTypeI16; + case kPrimChar: + return FETypeManager::kPrimFEIRTypeU16; + case kPrimLong: + return FETypeManager::kPrimFEIRTypeI64; + case kPrimFloat: + return FETypeManager::kPrimFEIRTypeF32; + case kPrimDouble: + return FETypeManager::kPrimFEIRTypeF64; + default: + return FETypeManager::kPrimFEIRTypeUnknown; + } +} + std::map> JBCOpNew::InitMapOpInputTypes() { std::map> ans; ans[kOpNew] = emptyPrimTypes; @@ -1405,6 +1446,20 @@ JBCPrimType JBCOpMultiANewArray::GetOutputTypesToStackImpl() const { return kTypeRef; } +std::string JBCOpMultiANewArray::DumpImpl(const JBCConstPool &constPool) const { + std::stringstream ss; + ss << GetOpcodeName() << " "; + const JBCConst *constRaw = constPool.GetConstByIdx(refTypeIdx); + CHECK_NULL_FATAL(constRaw); + if (constRaw->GetTag() == kConstClass) { + const JBCConstClass *constClass = static_cast(constRaw); + ss << constClass->GetClassNameOrin() << " dim=" << uint32{ dim }; + } else { + ss << "invalid const tag"; + } + return ss.str(); +} + // ---------- JBCOpTypeCheck ---------- std::map> JBCOpTypeCheck::mapOpInputTypes = JBCOpTypeCheck::InitMapOpInputTypes(); std::map JBCOpTypeCheck::mapOpOutputType = JBCOpTypeCheck::InitMapOpOutputType(); diff --git a/src/mplfe/jbc_input/src/jbc_stack2fe_helper.cpp b/src/mplfe/jbc_input/src/jbc_stack2fe_helper.cpp index fb813fc71580b54b4441fb25fbbede5a03503c1e..c0a8d926bb4e37e8713f391283685bf2ffd5de6d 100644 --- a/src/mplfe/jbc_input/src/jbc_stack2fe_helper.cpp +++ b/src/mplfe/jbc_input/src/jbc_stack2fe_helper.cpp @@ -352,6 +352,18 @@ PrimType JBCStack2FEHelper::JBCStackItemTypeToPrimType(jbc::JBCPrimType itemType } } +PrimType JBCStack2FEHelper::SimplifyPrimType(PrimType pty) { + switch (pty) { + case PTY_u1: // boolean + case PTY_i8: // byte + case PTY_i16: // short + case PTY_u16: // char + return PTY_i32; + default: + return pty; + } +} + std::vector JBCStack2FEHelper::JBCStackItemTypesToPrimTypes(const std::vector itemTypes) { std::vector primTypes; for (jbc::JBCPrimType itemType : itemTypes) { diff --git a/src/mplfe/jbc_input/src/jbc_stmt.cpp b/src/mplfe/jbc_input/src/jbc_stmt.cpp index 93daa26d3e4d467dba95b44e8051ab5ded9128eb..9632067ed95c3061edf10d194778d9a5e552d8ae 100644 --- a/src/mplfe/jbc_input/src/jbc_stmt.cpp +++ b/src/mplfe/jbc_input/src/jbc_stmt.cpp @@ -18,6 +18,7 @@ #include #include "feir_stmt.h" #include "feir_builder.h" +#include "fe_struct_elem_info.h" #include "opcodes.h" namespace maple { @@ -363,12 +364,18 @@ std::list JBCStmtInst::EmitToFEIRForOpLdc(JBCStack2FEHelper &sta stmtDAssign = GenerateStmtForConstF64(stack2feHelper, const8B->GetDouble(), success); break; } - case jbc::kConstString: - (void)stack2feHelper.PushItem(PTY_ref); + case jbc::kConstString: { + const jbc::JBCConstString *constString = static_cast(constRaw); + UniqueFEIRVar varDst = stack2feHelper.PushItem(PTY_ref); + stmtDAssign = FEIRBuilder::CreateStmtJavaConstString(std::move(varDst), constString->GetStrIdx()); break; - case jbc::kConstClass: - (void)stack2feHelper.PushItem(PTY_ref); + } + case jbc::kConstClass: { + const jbc::JBCConstClass *constClass = static_cast(constRaw); + UniqueFEIRVar varDst = stack2feHelper.PushItem(PTY_ref); + stmtDAssign = FEIRBuilder::CreateStmtJavaConstClass(std::move(varDst), constClass->GetFEIRType()->Clone()); break; + } default: ERR(kLncErr, "EmitToFEIRForOpLdc: unsupported const kind"); success = false; @@ -390,7 +397,11 @@ std::list JBCStmtInst::EmitToFEIRForOpLoad(JBCStack2FEHelper &st PrimType pty = JBCStack2FEHelper::JBCStackItemTypeToPrimType(stackOutType); uint32 regNum = stack2feHelper.GetRegNumForSlot(opLoad.GetSlotIdx()); UniqueFEIRVar var = FEIRBuilder::CreateVarReg(regNum, pty); - success = success && stack2feHelper.PushItem(std::move(var), pty); + UniqueFEIRVar varStack = stack2feHelper.PushItem(pty); + success = success && (varStack != nullptr); + UniqueFEIRExpr expr = FEIRBuilder::CreateExprDRead(std::move(var)); + UniqueFEIRStmt stmt = FEIRBuilder::CreateStmtDAssign(std::move(varStack), std::move(expr)); + ans.push_back(std::move(stmt)); return ans; } @@ -637,28 +648,198 @@ std::list JBCStmtInst::EmitToFEIRForOpReturn(JBCStack2FEHelper & std::list JBCStmtInst::EmitToFEIRForOpStaticFieldOpr(JBCStack2FEHelper &stack2feHelper, const jbc::JBCConstPool &constPool, bool &success) const { - return EmitToFEIRCommon2(stack2feHelper, constPool, success); + std::list ans; + const jbc::JBCOpFieldOpr &opField = static_cast(op); + const jbc::JBCConst *constRaw = + constPool.GetConstByIdxWithTag(opField.GetFieldIdx(), jbc::JBCConstTag::kConstFieldRef); + CHECK_NULL_FATAL(constRaw); + const jbc::JBCConstRef *constRef = static_cast(constRaw); + FEStructFieldInfo *fieldInfo = static_cast(constRef->GetFEStructElemInfo()); + CHECK_NULL_FATAL(fieldInfo); + const UniqueFEIRType &fieldType = fieldInfo->GetType(); + PrimType pty = fieldType->IsScalar() ? fieldType->GetPrimType() : PTY_ref; + pty = JBCStack2FEHelper::SimplifyPrimType(pty); + if (op.GetOpcode() == jbc::kOpGetStatic) { + UniqueFEIRVar var = stack2feHelper.PushItem(pty); + UniqueFEIRStmt stmt = std::make_unique(nullptr, std::move(var), *fieldInfo, true); + ans.push_back(std::move(stmt)); + } else { + UniqueFEIRVar var = stack2feHelper.PopItem(pty); + UniqueFEIRStmt stmt = std::make_unique(nullptr, std::move(var), *fieldInfo, true); + ans.push_back(std::move(stmt)); + } + return ans; } std::list JBCStmtInst::EmitToFEIRForOpFieldOpr(JBCStack2FEHelper &stack2feHelper, const jbc::JBCConstPool &constPool, bool &success) const { - return EmitToFEIRCommon2(stack2feHelper, constPool, success); + std::list ans; + const jbc::JBCOpFieldOpr &opField = static_cast(op); + const jbc::JBCConst *constRaw = + constPool.GetConstByIdxWithTag(opField.GetFieldIdx(), jbc::JBCConstTag::kConstFieldRef); + CHECK_NULL_FATAL(constRaw); + const jbc::JBCConstRef *constRef = static_cast(constRaw); + FEStructFieldInfo *fieldInfo = static_cast(constRef->GetFEStructElemInfo()); + CHECK_NULL_FATAL(fieldInfo); + const UniqueFEIRType &fieldType = fieldInfo->GetType(); + PrimType pty = fieldType->IsScalar() ? fieldType->GetPrimType() : PTY_ref; + pty = JBCStack2FEHelper::SimplifyPrimType(pty); + if (op.GetOpcode() == jbc::kOpGetField) { + UniqueFEIRVar varObj = stack2feHelper.PopItem(PTY_ref); + UniqueFEIRVar var = stack2feHelper.PushItem(pty); + UniqueFEIRStmt stmt = std::make_unique(std::move(varObj), std::move(var), *fieldInfo, false); + ans.push_back(std::move(stmt)); + } else { + UniqueFEIRVar var = stack2feHelper.PopItem(pty); + UniqueFEIRVar varObj = stack2feHelper.PopItem(PTY_ref); + UniqueFEIRStmt stmt = std::make_unique(std::move(varObj), std::move(var), *fieldInfo, false); + ans.push_back(std::move(stmt)); + } + return ans; } std::list JBCStmtInst::EmitToFEIRForOpInvoke(JBCStack2FEHelper &stack2feHelper, const jbc::JBCConstPool &constPool, bool &success) const { + switch (op.GetOpcode()) { + case jbc::kOpInvokeVirtual: + return EmitToFEIRForOpInvokeVirtual(stack2feHelper, constPool, success); + case jbc::kOpInvokeSpecial: + return EmitToFEIRForOpInvokeSpecial(stack2feHelper, constPool, success); + case jbc::kOpInvokeStatic: + return EmitToFEIRForOpInvokeStatic(stack2feHelper, constPool, success); + case jbc::kOpInvokeInterface: + return EmitToFEIRForOpInvokeInterface(stack2feHelper, constPool, success); + case jbc::kOpInvokeDynamic: + // WARN(kLncWarn, "unsupported op: invokedynamic"); + break; + default: + CHECK_FATAL(false, "unsupported op: %s", op.GetOpcodeName().c_str()); + break; + } return EmitToFEIRCommon2(stack2feHelper, constPool, success); } +void JBCStmtInst::PrepareInvokeParametersAndReturn(JBCStack2FEHelper &stack2feHelper, + const FEStructMethodInfo &info, + FEIRStmtCallAssign &callStmt, + bool isStatic) const { + const std::vector &argTypes = info.GetArgTypes(); + for (int i = argTypes.size() - 1; i >= 0; --i) { + const UniqueFEIRType &argType = argTypes[static_cast(i)]; + PrimType pty = argType->GetRealPrimType(); + UniqueFEIRVar var = stack2feHelper.PopItem(JBCStack2FEHelper::SimplifyPrimType(pty)); + UniqueFEIRExpr expr = FEIRBuilder::CreateExprDRead(std::move(var)); + callStmt.AddExprArgReverse(std::move(expr)); + } + if (!isStatic) { + // push this + const UniqueFEIRType &thisType = info.GetOwnerType(); + PrimType pty = thisType->GetRealPrimType(); + UniqueFEIRVar var = stack2feHelper.PopItem(JBCStack2FEHelper::SimplifyPrimType(pty)); + UniqueFEIRExpr expr = FEIRBuilder::CreateExprDRead(std::move(var)); + callStmt.AddExprArgReverse(std::move(expr)); + } + if (!info.IsReturnVoid()) { + const UniqueFEIRType &retType = info.GetReturnType(); + PrimType pty = retType->GetRealPrimType(); + UniqueFEIRVar var = stack2feHelper.PushItem(JBCStack2FEHelper::SimplifyPrimType(pty)); + callStmt.SetVar(std::move(var)); + } +} + +std::list JBCStmtInst::EmitToFEIRForOpInvokeVirtual(JBCStack2FEHelper &stack2feHelper, + const jbc::JBCConstPool &constPool, + bool &success) const { + std::list ans; + const jbc::JBCOpInvoke &opInvoke = static_cast(op); + const jbc::JBCConst *constRaw = constPool.GetConstByIdx(opInvoke.GetMethodIdx()); + if (constRaw == nullptr || + (constRaw->GetTag() != jbc::JBCConstTag::kConstMethodRef && + constRaw->GetTag() != jbc::JBCConstTag::kConstInterfaceMethodRef)) { + success = false; + return ans; + } + const jbc::JBCConstRef *constRef = static_cast(constRaw); + FEStructMethodInfo *methodInfo = static_cast(constRef->GetFEStructElemInfo()); + UniqueFEIRStmt stmt = std::make_unique(*methodInfo, OP_virtualcall, nullptr, false); + FEIRStmtCallAssign *ptrStmt = static_cast(stmt.get()); + PrepareInvokeParametersAndReturn(stack2feHelper, *methodInfo, *ptrStmt, false); + ans.push_back(std::move(stmt)); + return ans; +} + +std::list JBCStmtInst::EmitToFEIRForOpInvokeStatic(JBCStack2FEHelper &stack2feHelper, + const jbc::JBCConstPool &constPool, + bool &success) const { + std::list ans; + const jbc::JBCOpInvoke &opInvoke = static_cast(op); + const jbc::JBCConst *constRaw = constPool.GetConstByIdx(opInvoke.GetMethodIdx()); + if (constRaw == nullptr || + (constRaw->GetTag() != jbc::JBCConstTag::kConstMethodRef && + constRaw->GetTag() != jbc::JBCConstTag::kConstInterfaceMethodRef)) { + success = false; + return ans; + } + const jbc::JBCConstRef *constRef = static_cast(constRaw); + FEStructMethodInfo *methodInfo = static_cast(constRef->GetFEStructElemInfo()); + UniqueFEIRStmt stmt = std::make_unique(*methodInfo, OP_call, nullptr, true); + FEIRStmtCallAssign *ptrStmt = static_cast(stmt.get()); + PrepareInvokeParametersAndReturn(stack2feHelper, *methodInfo, *ptrStmt, true); + ans.push_back(std::move(stmt)); + return ans; +} + +std::list JBCStmtInst::EmitToFEIRForOpInvokeInterface(JBCStack2FEHelper &stack2feHelper, + const jbc::JBCConstPool &constPool, + bool &success) const { + std::list ans; + const jbc::JBCOpInvoke &opInvoke = static_cast(op); + const jbc::JBCConst *constRaw = constPool.GetConstByIdx(opInvoke.GetMethodIdx()); + if (constRaw == nullptr || + (constRaw->GetTag() != jbc::JBCConstTag::kConstMethodRef && + constRaw->GetTag() != jbc::JBCConstTag::kConstInterfaceMethodRef)) { + success = false; + return ans; + } + const jbc::JBCConstRef *constRef = static_cast(constRaw); + FEStructMethodInfo *methodInfo = static_cast(constRef->GetFEStructElemInfo()); + UniqueFEIRStmt stmt = std::make_unique(*methodInfo, OP_interfacecall, nullptr, false); + FEIRStmtCallAssign *ptrStmt = static_cast(stmt.get()); + PrepareInvokeParametersAndReturn(stack2feHelper, *methodInfo, *ptrStmt, false); + ans.push_back(std::move(stmt)); + return ans; +} + +std::list JBCStmtInst::EmitToFEIRForOpInvokeSpecial(JBCStack2FEHelper &stack2feHelper, + const jbc::JBCConstPool &constPool, + bool &success) const { + std::list ans; + const jbc::JBCOpInvoke &opInvoke = static_cast(op); + const jbc::JBCConst *constRaw = constPool.GetConstByIdx(opInvoke.GetMethodIdx()); + if (constRaw == nullptr || + (constRaw->GetTag() != jbc::JBCConstTag::kConstMethodRef && + constRaw->GetTag() != jbc::JBCConstTag::kConstInterfaceMethodRef)) { + success = false; + return ans; + } + const jbc::JBCConstRef *constRef = static_cast(constRaw); + FEStructMethodInfo *methodInfo = static_cast(constRef->GetFEStructElemInfo()); + Opcode mirOp = methodInfo->IsConstructor() ? OP_call : OP_superclasscall; + UniqueFEIRStmt stmt = std::make_unique(*methodInfo, mirOp, nullptr, false); + FEIRStmtCallAssign *ptrStmt = static_cast(stmt.get()); + PrepareInvokeParametersAndReturn(stack2feHelper, *methodInfo, *ptrStmt, false); + ans.push_back(std::move(stmt)); + return ans; +} + std::list JBCStmtInst::EmitToFEIRForOpNew(JBCStack2FEHelper &stack2feHelper, const jbc::JBCConstPool &constPool, bool &success) const { std::list ans; const jbc::JBCOpNew &opNew = static_cast(op); - std::string typeName = opNew.GetTypeName(constPool); - UniqueFEIRType type = FEIRBuilder::CreateTypeByJavaName(typeName, true); + UniqueFEIRType type = opNew.GetFEIRType(constPool)->Clone(); UniqueFEIRExpr expr(nullptr); switch (op.GetOpcode()) { case jbc::kOpNew: { @@ -695,7 +876,37 @@ std::list JBCStmtInst::EmitToFEIRForOpNew(JBCStack2FEHelper &sta std::list JBCStmtInst::EmitToFEIRForOpMultiANewArray(JBCStack2FEHelper &stack2feHelper, const jbc::JBCConstPool &constPool, bool &success) const { - return EmitToFEIRCommon2(stack2feHelper, constPool, success); + std::list ans; + const jbc::JBCOpMultiANewArray &opArray = static_cast(op); + const jbc::JBCConst *constRaw = constPool.GetConstByIdxWithTag(opArray.GetRefTypeIdx(), + jbc::JBCConstTag::kConstClass); + if (constRaw == nullptr) { + success = false; + return ans; + } + const jbc::JBCConstClass *constClass = static_cast(constRaw); + UniqueFEIRStmt stmt = std::make_unique(nullptr, constClass->GetFEIRType()->Clone()); + std::vector stackInTypes = op.GetInputTypesFromStack(constPool); + std::reverse(stackInTypes.begin(), stackInTypes.end()); + for (jbc::JBCPrimType popType : stackInTypes) { + PrimType pty = JBCStack2FEHelper::JBCStackItemTypeToPrimType(popType); + UniqueFEIRVar var = stack2feHelper.PopItem(pty); + if (var == nullptr) { + success = false; + return ans; + } + static_cast(stmt.get())->AddVarSizeRev(std::move(var)); + } + jbc::JBCPrimType stackOutType = op.GetOutputTypesToStack(constPool); + if (stackOutType == jbc::JBCPrimType::kTypeDefault) { + success = false; + return ans; + } + PrimType pty = JBCStack2FEHelper::JBCStackItemTypeToPrimType(stackOutType); + UniqueFEIRVar varRet = stack2feHelper.PushItem(pty); + static_cast(stmt.get())->SetVar(std::move(varRet)); + ans.push_back(std::move(stmt)); + return ans; } std::list JBCStmtInst::EmitToFEIRForOpThrow(JBCStack2FEHelper &stack2feHelper, @@ -727,8 +938,6 @@ std::list JBCStmtInst::EmitToFEIRForOpTypeCheck(JBCStack2FEHelpe PrimType ptyOut = (opcode == jbc::kOpCheckCast) ? PTY_ref : PTY_i32; UniqueFEIRVar varIn = stack2feHelper.PopItem(ptyIn); UniqueFEIRVar varOut = stack2feHelper.PushItem(ptyOut); - UniqueFEIRType type = std::make_unique(PTY_ref); - FEIRTypeDefault *ptrType = static_cast(type.get()); uint16 constIdx = opTypeCheck.GetTypeIdx(); const jbc::JBCConst *constRaw = constPool.GetConstByIdxWithTag(constIdx, jbc::JBCConstTag::kConstClass); if (constRaw == nullptr) { @@ -736,7 +945,7 @@ std::list JBCStmtInst::EmitToFEIRForOpTypeCheck(JBCStack2FEHelpe return ans; } const jbc::JBCConstClass *constClass = static_cast(constRaw); - ptrType->LoadFromJavaTypeName(constClass->GetClassNameMpl(), true); + UniqueFEIRType type = constClass->GetFEIRType()->Clone(); if (opcode == jbc::kOpCheckCast) { UniqueFEIRStmt stmt = FEIRBuilder::CreateStmtJavaCheckCast(std::move(varOut), std::move(varIn), std::move(type)); ans.push_back(std::move(stmt));