diff --git a/src/mapleall/bin/dex2mpl b/src/mapleall/bin/dex2mpl index 729738c96818833dc28736dc5c62901bb6e8418b..4b545d9b2d028bbd75f353e317d154ce4ee47fe1 100755 Binary files a/src/mapleall/bin/dex2mpl and b/src/mapleall/bin/dex2mpl differ diff --git a/src/mapleall/bin/jbc2mpl b/src/mapleall/bin/jbc2mpl index 7a2bf855da407b622c3ff660e832dbbd5ee3a1a0..fc705463ca662978de824ae385968171245d2b08 100755 Binary files a/src/mapleall/bin/jbc2mpl and b/src/mapleall/bin/jbc2mpl differ diff --git a/src/mapleall/maple_be/include/be/common_utils.h b/src/mapleall/maple_be/include/be/common_utils.h index 2307a9f01631864a38c77aec4a759e94392288a0..96a785eade3466f97c41ecf713f7e0601369c2fd 100644 --- a/src/mapleall/maple_be/include/be/common_utils.h +++ b/src/mapleall/maple_be/include/be/common_utils.h @@ -32,6 +32,7 @@ constexpr uint32 kBaseOffsetAlignment = 3; constexpr uint32 k1FConst = 31; constexpr uint32 k0BitSize = 0; constexpr uint32 k1BitSize = 1; +constexpr uint32 k2BitSize = 2; constexpr uint32 k4BitSize = 4; constexpr uint32 k6BitSize = 6; constexpr uint32 k8BitSize = 8; @@ -125,6 +126,7 @@ constexpr int32 kMaxPimm32 = 16380; constexpr int32 kMaxPimm64 = 32760; constexpr int32 kMaxPimm[k4BitSize] = {kMaxPimm8, kMaxPimm16, kMaxPimm32, kMaxPimm64}; +constexpr int32 kMaxPairPimm[k2BitSize] = {k256BitSize, k512BitSize}; constexpr int32 kMax12UnsignedImm = 4096; constexpr int32 kMax13UnsignedImm = 8192; diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h index dfa1bf83ee5cfb6a22df8b90095837d2c2c857b7..9e9588d806a717b6c943adf123b995d3c3590f15 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -93,6 +93,7 @@ class AArch64CGFunc : public CGFunc { void SelectAssertNull(UnaryStmtNode &stmt) override; AArch64MemOperand *GenLargeAggFormalMemOpnd(const MIRSymbol &sym, uint32 alignUsed, int32 offset); AArch64MemOperand *FixLargeMemOpnd(MemOperand &memOpnd, uint32 align); + AArch64MemOperand *FixLargeMemOpnd(MOperator mOp, MemOperand &memOpnd, uint32 dSize, uint32 opndIdx); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; void SelectAggIassign(IassignNode &stmt, Operand &lhsAddrOpnd) override; @@ -461,9 +462,10 @@ class AArch64CGFunc : public CGFunc { bool CheckIfSplitOffsetWithAdd(const AArch64MemOperand &memOpnd, uint32 bitLen); RegOperand *GetBaseRegForSplit(uint32 baseRegNum); + AArch64MemOperand &SplitOffsetWithAddInstruction(const AArch64MemOperand &memOpnd, uint32 bitLen, uint32 baseRegNum = AArch64reg::kRinvalid, bool isDest = false, - Insn *insn = nullptr); + Insn *insn = nullptr, bool forPair = false); AArch64MemOperand &CreateReplacementMemOperand(uint32 bitLen, RegOperand &baseReg, int32 offset); bool HasStackLoadStore(); diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_insn.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_insn.h index 0362bc5c9751e81738fcfba468c7a323dd1aca98..25b09425caae670ac83ab355b46831bb29667677 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_insn.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_insn.h @@ -195,8 +195,8 @@ struct VectorRegSpec { class AArch64VectorInsn : public AArch64Insn { public: AArch64VectorInsn(MemPool &memPool, MOperator opc) - : AArch64Insn(memPool, opc), - regSpecList(localAlloc.Adapter()) { + : AArch64Insn(memPool, opc), + regSpecList(localAlloc.Adapter()) { regSpecList.clear(); } @@ -207,7 +207,6 @@ class AArch64VectorInsn : public AArch64Insn { } VectorRegSpec *GetAndRemoveRegSpecFromList() { - //ASSERT(regSpecList.size() > 0, "regSpecList empty"); if (regSpecList.size() == 0) { VectorRegSpec *vecSpec = CG::GetCurCGFuncNoConst()->GetMemoryPool()->New(); return vecSpec; diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_operand.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_operand.h index f964e99a69ea9ea90ecf6fbbcafc2708c53e5b4c..d68f455534ad70fbed2705a20b713369a0206052 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_operand.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_operand.h @@ -105,7 +105,6 @@ class AArch64RegOperand : public RegOperand { return vecLaneSize; } - bool operator==(const AArch64RegOperand &opnd) const; bool operator<(const AArch64RegOperand &opnd) const; @@ -703,7 +702,18 @@ class AArch64MemOperand : public MemOperand { /* alignment is between kAlignmentOf8Bit and kAlignmentOf64Bit */ ASSERT(alignment >= kOffsetAlignmentOf8Bit, "error val:alignment"); ASSERT(alignment <= kOffsetAlignmentOf64Bit, "error val:alignment"); - return (kMaxPimms[alignment]); + return (kMaxPimm[alignment]); + } + + static int32 GetMaxPairPIMM(uint32 dSize) { + ASSERT(dSize >= k32BitSize, "error val:dSize"); + ASSERT(dSize <= k64BitSize, "error val:dSize"); + ASSERT((dSize & (dSize - 1)) == 0, "error val:dSize"); + int32 alignment = GetImmediateOffsetAlignment(dSize); + /* alignment is between kAlignmentOf8Bit and kAlignmentOf64Bit */ + ASSERT(alignment >= kOffsetAlignmentOf32Bit, "error val:alignment"); + ASSERT(alignment <= kOffsetAlignmentOf64Bit, "error val:alignment"); + return (kMaxPairPimm[alignment - k2BitSize]); } bool IsOffsetMisaligned(uint32 dSize) const { @@ -837,8 +847,6 @@ class AArch64MemOperand : public MemOperand { static constexpr int32 kLdpStp64SimmLowerBound = -512; /* multiple of 8 */ static constexpr int32 kLdpStp64SimmUpperBound = 504; - static const int32 kMaxPimms[4]; - AArch64AddressingMode addrMode; uint32 extend; /* used with offset register ; AddrMode_B_OR_X */ diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp index eaacdf46ba5f89a0ad133af7ec7975362b45bde6..3de800ff061cedb70e03f8bc16246739d878ff63 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -717,7 +717,8 @@ void AArch64CGFunc::SelectCopy(Operand &dest, PrimType dtype, Operand &src, Prim vecSpecSrc->vecLaneMax = k16BitSize; VectorRegSpec *vecSpecDest = GetMemoryPool()->New(); vecSpecDest->vecLaneMax = k16BitSize; - Insn *insn = &GetCG()->BuildInstruction(dsize <= k64BitSize ? MOP_vmovuu : MOP_vmovvv, dest, src); + Insn *insn = + &GetCG()->BuildInstruction(dsize <= k64BitSize ? MOP_vmovuu : MOP_vmovvv, dest, src); static_cast(insn)->PushRegSpecEntry(vecSpecDest); static_cast(insn)->PushRegSpecEntry(vecSpecSrc); GetCurBB()->AppendInsn(*insn); @@ -835,7 +836,8 @@ RegOperand *AArch64CGFunc::GetBaseRegForSplit(uint32 baseRegNum) { } AArch64MemOperand &AArch64CGFunc::SplitOffsetWithAddInstruction(const AArch64MemOperand &memOpnd, uint32 bitLen, - uint32 baseRegNum, bool isDest, Insn *insn) { + uint32 baseRegNum, bool isDest, + Insn *insn, bool forPair) { ASSERT((memOpnd.GetAddrMode() == AArch64MemOperand::kAddrModeBOi), "expect kAddrModeBOi memOpnd"); ASSERT(memOpnd.IsIntactIndexed(), "expect intactIndexed memOpnd"); AArch64OfstOperand *ofstOpnd = memOpnd.GetOffsetImmediate(); @@ -854,9 +856,20 @@ AArch64MemOperand &AArch64CGFunc::SplitOffsetWithAddInstruction(const AArch64Mem * ADD TEMP_REG, X29, ADDEND * LDR/STR TEMP_REG, [ TEMP_REG, #NEW_OFFSET ] */ - int32 maxPimm = memOpnd.GetMaxPIMM(bitLen); + int32 maxPimm = 0; + if (!forPair) { + maxPimm = memOpnd.GetMaxPIMM(bitLen); + } else { + maxPimm = memOpnd.GetMaxPairPIMM(bitLen); + } + ASSERT(maxPimm != 0, "get max pimm failed"); + + bool misAlignment = false; int32 q0 = opndVal / maxPimm; int32 addend = q0 * maxPimm; + if (addend == 0) { + misAlignment = true; + } int32 r0 = opndVal - addend; int32 alignment = memOpnd.GetImmediateOffsetAlignment(bitLen); int32 q1 = static_cast(r0) >> static_cast(alignment); @@ -864,15 +877,43 @@ AArch64MemOperand &AArch64CGFunc::SplitOffsetWithAddInstruction(const AArch64Mem addend = addend + r1; RegOperand *origBaseReg = memOpnd.GetBaseRegister(); ASSERT(origBaseReg != nullptr, "nullptr check"); + + if (misAlignment && addend != 0) { + ImmOperand &immAddend = CreateImmOperand(static_cast(q1) << static_cast(alignment), k64BitSize, true); + if (memOpnd.GetOffsetImmediate()->GetVary() == kUnAdjustVary) { + immAddend.SetVary(kUnAdjustVary); + } + RegOperand *resOpnd = GetBaseRegForSplit(baseRegNum); + if (insn == nullptr) { + SelectAdd(*resOpnd, *origBaseReg, immAddend, PTY_i64); + } else { + SelectAddAfterInsn(*resOpnd, *origBaseReg, immAddend, PTY_i64, isDest, *insn); + } + AArch64MemOperand &newMemOpnd = CreateReplacementMemOperand(bitLen, *resOpnd, r1); + newMemOpnd.SetStackMem(memOpnd.IsStackMem()); + return newMemOpnd; + } + if (addend > 0) { int32 t = addend; - constexpr uint32 suffixClear = 0xfffff000; + uint32 suffixClear = 0xfffff000; + if (forPair) { + suffixClear = 0xffffff00; + } addend = (static_cast(addend) & suffixClear); q1 = (static_cast(q1) << static_cast(alignment)) + (t - addend); - if (AArch64MemOperand::IsPIMMOffsetOutOfRange(q1, bitLen)) { - addend = (static_cast(opndVal) & suffixClear); - q1 = opndVal - addend; + if (!forPair) { + if (AArch64MemOperand::IsPIMMOffsetOutOfRange(q1, bitLen)) { + addend = (static_cast(opndVal) & suffixClear); + q1 = opndVal - addend; + } + } else { + if (q1 < 0 || q1 > maxPimm) { + addend = (static_cast(opndVal) & suffixClear); + q1 = opndVal - addend; + } } + ImmOperand &immAddend = CreateImmOperand(addend, k64BitSize, true); if (memOpnd.GetOffsetImmediate()->GetVary() == kUnAdjustVary) { immAddend.SetVary(kUnAdjustVary); @@ -1068,6 +1109,21 @@ AArch64MemOperand *AArch64CGFunc::FixLargeMemOpnd(MemOperand &memOpnd, uint32 al return lhsMemOpnd; } +AArch64MemOperand *AArch64CGFunc::FixLargeMemOpnd(MOperator mOp, MemOperand &memOpnd, uint32 dSize, uint32 opndIdx) { + auto *a64MemOpnd = static_cast(&memOpnd); + if ((a64MemOpnd->GetMemVaryType() == kNotVary) && !IsOperandImmValid(mOp, &memOpnd, opndIdx)) { + if (opndIdx == kInsnSecondOpnd) { + a64MemOpnd = &SplitOffsetWithAddInstruction(*a64MemOpnd, dSize); + } else if (opndIdx == kInsnThirdOpnd) { + a64MemOpnd = &SplitOffsetWithAddInstruction( + *a64MemOpnd, dSize, AArch64reg::kRinvalid, false, nullptr, true); + } else { + CHECK_FATAL(false, "NYI"); + } + } + return a64MemOpnd; +} + AArch64MemOperand *AArch64CGFunc::GenLargeAggFormalMemOpnd(const MIRSymbol &sym, uint32 align, int32 offset) { MemOperand *memOpnd; if (sym.GetStorageClass() == kScFormal && GetBecommon().GetTypeSize(sym.GetTyIdx()) > k16ByteSize) { @@ -1172,7 +1228,7 @@ void AArch64CGFunc::SelectAggDassign(DassignNode &stmt) { if (doPair) { AArch64OfstOperand &lhsOfstOpnd1 = GetOrCreateOfstOpnd(lhsBaseOffset + copySize, k32BitSize); MemOperand *lhsMemOpnd1 = - &GetOrCreateMemOpnd(addrMode, copySize * k8BitSize, lhsBaseReg, nullptr, &lhsOfstOpnd1, sym); + &GetOrCreateMemOpnd(addrMode, copySize * k8BitSize, lhsBaseReg, nullptr, &lhsOfstOpnd1, sym); lhsMemOpnd1 = FixLargeMemOpnd(*lhsMemOpnd1, copySize); GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOp, *result1, *lhsMemOpnd1)); } @@ -1278,7 +1334,7 @@ void AArch64CGFunc::SelectAggDassign(DassignNode &stmt) { if (doPair) { AArch64OfstOperand &lhsOfstOpnd1 = GetOrCreateOfstOpnd(lhsBaseOffset + copySize, k32BitSize); MemOperand *lhsMemOpnd1 = - &GetOrCreateMemOpnd(addrMode, copySize * k8BitSize, lhsBaseReg, nullptr, &lhsOfstOpnd1, sym); + &GetOrCreateMemOpnd(addrMode, copySize * k8BitSize, lhsBaseReg, nullptr, &lhsOfstOpnd1, sym); lhsMemOpnd1 = FixLargeMemOpnd(*lhsMemOpnd1, copySize); GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOp, *result1, *lhsMemOpnd1)); } @@ -1603,15 +1659,16 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { /* generate the load */ RegOperand &result = CreateVirtualRegisterOperand(NewVReg(kRegTyInt, std::max(4u, copySize))); MOperator mOpLDP = (copySize == k4BitSize) ? MOP_wldp : MOP_xldp; - bool isInRange = IsOperandImmValid(mOpLDP, rhsMemOpnd, kInsnThirdOpnd); - bool doPair = (!rhsIsLo12 && (copySize >= k4BitSize) && ((i + 1) < (lhsSize / copySize)) && isInRange); + bool doPair = (!rhsIsLo12 && (copySize >= k4BitSize) && ((i + 1) < (lhsSize / copySize))); RegOperand *result1 = nullptr; if (doPair) { regno_t vRegNO1 = NewVReg(kRegTyInt, std::max(4u, copySize)); result1 = &CreateVirtualRegisterOperand(vRegNO1); + rhsMemOpnd = FixLargeMemOpnd(mOpLDP, *static_cast(rhsMemOpnd), result.GetSize(), kInsnThirdOpnd); GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOpLDP, result, *result1, *rhsMemOpnd)); } else { MOperator mOp = PickLdInsn(copySize * k8BitSize, PTY_u32); + rhsMemOpnd = FixLargeMemOpnd(mOp, *static_cast(rhsMemOpnd), result.GetSize(), kInsnSecondOpnd); GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOp, result, *rhsMemOpnd)); } /* generate the store */ @@ -1620,10 +1677,12 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { static_cast(&lhsAddrOpnd), nullptr, &ofstOpnd, nullptr); if (doPair) { MOperator mOpSTP = (copySize == k4BitSize) ? MOP_wstp : MOP_xstp; + lhsMemOpnd = FixLargeMemOpnd(mOpSTP, *static_cast(lhsMemOpnd), result.GetSize(), kInsnThirdOpnd); GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOpSTP, result, *result1, *lhsMemOpnd)); i++; } else { MOperator mOp = PickStInsn(copySize * k8BitSize, PTY_u32); + lhsMemOpnd = FixLargeMemOpnd(mOp, *static_cast(lhsMemOpnd), copySize * k8BitSize, kInsnSecondOpnd); GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOp, result, *lhsMemOpnd)); } } @@ -1714,19 +1773,18 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { AArch64OfstOperand &rhsOfstOpnd = GetOrCreateOfstOpnd(rhsOffset + i * copySize, k32BitSize); Operand *rhsMemOpnd = &GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, operandSize, static_cast(rhsAddrOpnd), nullptr, &rhsOfstOpnd, nullptr); - bool isInRange = IsOperandImmValid(mOpLDP, rhsMemOpnd, kInsnThirdOpnd); - if (!isInRange) { - rhsMemOpnd = &SplitOffsetWithAddInstruction(*static_cast(rhsMemOpnd), operandSize); - } + RegOperand &result = CreateVirtualRegisterOperand(NewVReg(kRegTyInt, std::max(4u, copySize))); - bool doPair = ((copySize >= k4BitSize) && ((i + 1) < (lhsSize / copySize)) && isInRange); + bool doPair = ((copySize >= k4BitSize) && ((i + 1) < (lhsSize / copySize))); Insn *insn = nullptr; RegOperand *result1 = nullptr; if (doPair) { + rhsMemOpnd = FixLargeMemOpnd(mOpLDP, *static_cast(rhsMemOpnd), operandSize, kInsnThirdOpnd); result1 = &CreateVirtualRegisterOperand(NewVReg(kRegTyInt, std::max(4u, copySize))); insn = &GetCG()->BuildInstruction(mOpLDP, result, *result1, *rhsMemOpnd); } else { MOperator mOp = PickLdInsn(operandSize, PTY_u32); + rhsMemOpnd = FixLargeMemOpnd(mOp, *static_cast(rhsMemOpnd), operandSize, kInsnSecondOpnd); insn = &GetCG()->BuildInstruction(mOp, result, *rhsMemOpnd); } insn->MarkAsAccessRefField(isRefField); @@ -1736,15 +1794,13 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { AArch64OfstOperand &lhsOfstOpnd = GetOrCreateOfstOpnd(lhsOffset + i * copySize, k32BitSize); Operand *lhsMemOpnd = &GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, operandSize, static_cast(&lhsAddrOpnd), nullptr, &lhsOfstOpnd, nullptr); - isInRange = IsOperandImmValid(mOpSTP, lhsMemOpnd, kInsnThirdOpnd); - if (!isInRange) { - lhsMemOpnd = &SplitOffsetWithAddInstruction(*static_cast(lhsMemOpnd), operandSize); - } if (doPair) { + lhsMemOpnd = FixLargeMemOpnd(mOpSTP, *static_cast(lhsMemOpnd), operandSize, kInsnThirdOpnd); GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOpSTP, result, *result1, *lhsMemOpnd)); i++; } else { MOperator mOp = PickStInsn(operandSize, PTY_u32); + lhsMemOpnd = FixLargeMemOpnd(mOp, *static_cast(lhsMemOpnd), operandSize, kInsnSecondOpnd); GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOp, result, *lhsMemOpnd)); } } @@ -3733,7 +3789,7 @@ Operand *AArch64CGFunc::SelectBnot(UnaryNode &node, Operand &opnd0) { Operand *AArch64CGFunc::SelectExtractbits(ExtractbitsNode &node, Operand &srcOpnd) { PrimType dtype = node.GetPrimType(); RegOperand &resOpnd = CreateRegisterOperandOfType(dtype); - bool isSigned = IsSignedInteger(dtype); + bool isSigned = (node.GetOpCode() == OP_sext) ? true : (node.GetOpCode() == OP_zext) ? false : IsSignedInteger(dtype); uint8 bitOffset = node.GetBitsOffset(); uint8 bitSize = node.GetBitsSize(); bool is64Bits = (GetPrimTypeBitSize(dtype) == k64BitSize); @@ -4801,8 +4857,8 @@ Operand &AArch64CGFunc::GetTargetRetOperand(PrimType primType, int32 sReg) { AArch64reg pReg; if (sReg < 0) { return GetOrCreatePhysicalRegisterOperand( - IsPrimitiveFloat(primType) || (GetPrimTypeLanes(primType) > 0) ? S0 : R0, - bitSize, GetRegTyFromPrimTy(primType)); + IsPrimitiveFloat(primType) || (GetPrimTypeLanes(primType) > 0) ? S0 : R0, + bitSize, GetRegTyFromPrimTy(primType)); } else { switch (sReg) { case kSregRetval0: @@ -5631,7 +5687,11 @@ AArch64RegOperand *AArch64CGFunc::SelectParmListDreadAccessField(const MIRSymbol } else { memOpnd = &GetOrCreateMemOpnd(sym, (kSizeOfPtr * parmNum + offset), memSize); } - GetCurBB()->AppendInsn(cg->BuildInstruction(PickLdInsn(dataSizeBits, primType), *parmOpnd, *memOpnd)); + MOperator selectedMop = PickLdInsn(dataSizeBits, primType); + if (!IsOperandImmValid(selectedMop, memOpnd, kInsnSecondOpnd)) { + memOpnd = &SplitOffsetWithAddInstruction(*static_cast(memOpnd), dataSizeBits); + } + GetCurBB()->AppendInsn(cg->BuildInstruction(selectedMop, *parmOpnd, *memOpnd)); return parmOpnd; } @@ -5658,7 +5718,11 @@ void AArch64CGFunc::CreateCallStructParamPassByReg(AArch64reg reg, MemOperand &m ASSERT(0, "CreateCallStructParamPassByReg: Unknown state"); } - GetCurBB()->AppendInsn(cg->BuildInstruction(PickLdInsn(dataSizeBits, pType), *parmOpnd, memOpnd)); + MOperator selectedMop = PickLdInsn(dataSizeBits, pType); + if (!IsOperandImmValid(selectedMop, &memOpnd, kInsnSecondOpnd)) { + memOpnd = SplitOffsetWithAddInstruction(static_cast(memOpnd), dataSizeBits); + } + GetCurBB()->AppendInsn(cg->BuildInstruction(selectedMop, *parmOpnd, memOpnd)); srcOpnds.PushOpnd(*parmOpnd); } @@ -6528,8 +6592,8 @@ AArch64RegOperand &AArch64CGFunc::GetOrCreatePhysicalRegisterOperand(AArch64reg if (size <= k32BitSize) { size = k32BitSize; aarch64PhyRegIdx = aarch64PhyRegIdx << 1; - } else { - size = size == k128BitSize ? k128BitSize : k64BitSize; + } else { + size = (size == k128BitSize) ? k128BitSize : k64BitSize; aarch64PhyRegIdx = (aarch64PhyRegIdx << 1) + 1; } ASSERT(aarch64PhyRegIdx < k256BitSize, "phyRegOperandTable index out of range"); @@ -7980,7 +8044,9 @@ RegOperand *AArch64CGFunc::SelectVectorFromScalar(IntrinsicopNode &intrnNode) { ConstvalNode *constvalNode = static_cast(argExpr); MIRConst *mirConst = constvalNode->GetConstVal(); int32 val = safe_cast(mirConst)->GetValue(); - if (val >= -128 && val <= 255) { + const int32 kMinImmVal = -128; + const int32 kMaxImmVal = 255; + if (val >= kMinImmVal && val <= kMaxImmVal) { Insn *insn = &GetCG()->BuildInstruction(MOP_vmovvi, *res, *immOpnd); static_cast(insn)->PushRegSpecEntry(vecSpec); GetCurBB()->AppendInsn(*insn); @@ -8096,7 +8162,7 @@ RegOperand *AArch64CGFunc::SelectVectorSetElement(IntrinsicopNode &intrnNode) { VectorRegSpec *vecSpecSrc = GetMemoryPool()->New(); vecSpecSrc->vecLaneMax = GetPrimTypeLanes(vType); - BaseNode *arg2 = intrnNode.Opnd(2); /* lane const operand */ + BaseNode *arg2 = intrnNode.Opnd(kInsnThirdOpnd); /* lane const operand */ Operand *opnd2 = HandleExpr(intrnNode, *arg2); if (opnd2->IsConstImmediate()) { ConstvalNode *constvalNode = static_cast(arg2); @@ -8130,7 +8196,7 @@ RegOperand *AArch64CGFunc::SelectVectorMerge(IntrinsicopNode &intrnNode) { VectorRegSpec *vecSpecOpd2 = GetMemoryPool()->New(); vecSpecOpd2->vecLaneMax = GetPrimTypeLanes(o2Type); - BaseNode *arg3 = intrnNode.Opnd(2); /* lane const operand */ + BaseNode *arg3 = intrnNode.Opnd(kInsnThirdOpnd); /* lane const operand */ Operand *opnd3 = HandleExpr(intrnNode, *arg3); if (!opnd3->IsConstImmediate()) { CHECK_FATAL(0, "VectorSetElement does not have lane const"); @@ -8156,7 +8222,7 @@ RegOperand *AArch64CGFunc::SelectVectorReverse(IntrinsicopNode &intrnNode, uint3 VectorRegSpec *vecSpecSrc = GetMemoryPool()->New(); vecSpecSrc->vecLaneMax = GetPrimTypeLanes(srcType); - MOperator mOp = size >= 64 ? MOP_vrev64vv : (size >= 32 ? MOP_vrev32vv : MOP_vrev16vv); + MOperator mOp = size >= k64BitSize ? MOP_vrev64vv : (size >= k32BitSize ? MOP_vrev32vv : MOP_vrev16vv); Insn *insn = &GetCG()->BuildInstruction(mOp, *res, srcOpnd); static_cast(insn)->PushRegSpecEntry(vecSpecDest); static_cast(insn)->PushRegSpecEntry(vecSpecSrc); diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_global.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_global.cpp index eb83856f46fb3ecac9cbd284c9d27f8ab2722638..d0e57282288b274a4bd5a339825d6588e2edc798 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_global.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_global.cpp @@ -226,6 +226,9 @@ bool ForwardPropPattern::CheckCondition(Insn &insn) { } Operand &firstOpnd = insn.GetOperand(kInsnFirstOpnd); Operand &secondOpnd = insn.GetOperand(kInsnSecondOpnd); + if (firstOpnd.GetSize() != secondOpnd.GetSize()) { + return false; + } RegOperand &firstRegOpnd = static_cast(firstOpnd); RegOperand &secondRegOpnd = static_cast(secondOpnd); uint32 firstRegNO = firstRegOpnd.GetRegisterNumber(); @@ -349,7 +352,9 @@ bool BackPropPattern::CheckAndGetOpnd(Insn &insn) { if (RegOperand::IsSameReg(firstOpnd, secondOpnd)) { return false; } - + if (firstOpnd.GetSize() != secondOpnd.GetSize()) { + return false; + } firstRegOpnd = &static_cast(firstOpnd); secondRegOpnd = &static_cast(secondOpnd); if (firstRegOpnd->IsZeroRegister() || !firstRegOpnd->IsVirtualRegister() || !secondRegOpnd->IsVirtualRegister()) { diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp index 364b836ba4623a6b93552adf32965ce8836b3d15..bf233e6c476e264f04b2dfdab77340f36fc7600e 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp @@ -58,6 +58,14 @@ void AArch64FPLROffsetAdjustment::AdjustmentOffsetForOpnd(Insn &insn, AArch64CGF insn.SetOperand(i, newMemOpnd); } } + if (ofstOpnd->GetVary() == kNotVary) { + bool condition = aarchCGFunc.IsOperandImmValid(insn.GetMachineOpcode(), &memOpnd, i); + if (!condition) { + AArch64MemOperand &newMemOpnd = aarchCGFunc.SplitOffsetWithAddInstruction( + memOpnd, memOpnd.GetSize(), static_cast(R17), false, &insn); + insn.SetOperand(i, newMemOpnd); + } + } } else if (opnd.IsIntImmediate()) { AdjustmentOffsetForImmOpnd(insn, i, aarchCGFunc); } diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_operand.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_operand.cpp index f2a16c709f19143610344abf9970a659c573619f..e34b9b8723ac1244bd247cebee35d6e6632dd9b7 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_operand.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_operand.cpp @@ -84,15 +84,15 @@ void AArch64RegOperand::Emit(Emitter &emitter, const OpndProp *opndProp) const { break; } case kRegTyFloat: { - ASSERT((opndSize == k8BitSize || opndSize == k16BitSize || opndSize == k32BitSize || opndSize == k64BitSize - || opndSize == k128BitSize), "illegal register size"); + ASSERT((opndSize == k8BitSize || opndSize == k16BitSize || opndSize == k32BitSize || + opndSize == k64BitSize || opndSize == k128BitSize), "illegal register size"); int32 laneSize = GetVecLaneSize(); if (static_cast(opndProp)->IsVectorOperand() && laneSize != 0) { std::string width; if (opndSize == k128BitSize) { - width = laneSize == 16 ? "b" : (laneSize == 8 ? "h" : (laneSize == 4 ? "s" : "d")); + width = laneSize == k16BitSize ? "b" : (laneSize == k8BitSize ? "h" : (laneSize == k4BitSize ? "s" : "d")); } else if (opndSize == k64BitSize) { - width = laneSize == 8 ? "b" : (laneSize == 4 ? "h" : "s"); + width = laneSize == k8BitSize ? "b" : (laneSize == k4BitSize ? "h" : "s"); } int16 lanePos = GetVecLanePosition(); emitter.Emit(AArch64CG::vectorRegNames[regNO]); @@ -206,8 +206,6 @@ void StImmOperand::Emit(Emitter &emitter, const OpndProp *opndProp) const { } } -const int32 AArch64MemOperand::kMaxPimms[4] = { kMaxPimm8, kMaxPimm16, kMaxPimm32, kMaxPimm64 }; - Operand *AArch64MemOperand::GetOffset() const { switch (addrMode) { case kAddrModeBOi: @@ -230,7 +228,8 @@ void AArch64MemOperand::Emit(Emitter &emitter, const OpndProp *opndProp) const { #if DEBUG const AArch64MD *md = &AArch64CG::kMd[emitter.GetCurrentMOP()]; bool isLDSTpair = md->IsLoadStorePair(); - ASSERT(md->Is64Bit() || md->GetOperandSize() <= k32BitSize || md->GetOperandSize() == k128BitSize, "unexpected opnd size"); + ASSERT(md->Is64Bit() || md->GetOperandSize() <= k32BitSize || md->GetOperandSize() == k128BitSize, + "unexpected opnd size"); #endif if (addressMode == AArch64MemOperand::kAddrModeBOi) { emitter.Emit("["); @@ -250,7 +249,6 @@ void AArch64MemOperand::Emit(Emitter &emitter, const OpndProp *opndProp) const { * The ARMv8-A architecture allows many types of load and store accesses to be arbitrarily aligned. * The Cortex- A57 processor handles most unaligned accesses without performance penalties. */ - //ASSERT(!IsOffsetMisaligned(md->GetOperandSize()), "should not be OffsetMisaligned"); #if DEBUG if (IsOffsetMisaligned(md->GetOperandSize())) { INFO(kLncInfo, "The Memory operand's offset is misaligned:", ""); diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp index 3cd16e26c986ee1b5ed4aa4286b03db0bceb3816..561106aa209bfa3b9f856b2d210e3b49484a07be 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp @@ -26,7 +26,6 @@ const std::set kFrameWhiteListFunc { bool IsFuncNeedFrame(const std::string &funcName) { return kFrameWhiteListFunc.find(funcName) != kFrameWhiteListFunc.end(); } -constexpr uint32 k2BitSize = 2; constexpr int32 kSoeChckOffset = 8192; enum RegsPushPop : uint8 { diff --git a/src/mapleall/maple_be/src/cg/cgfunc.cpp b/src/mapleall/maple_be/src/cg/cgfunc.cpp index df61e2a60881d9ca00043f4820e50d741aaccf90..940e07d1d281060d8d64856f0ee21d2c000b3a96 100644 --- a/src/mapleall/maple_be/src/cg/cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/cgfunc.cpp @@ -396,7 +396,7 @@ Operand *HandleIntrinOp(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc) case INTRN_vector_set_element_v4u32: return cgFunc.SelectVectorSetElement(intrinsicopNode); case INTRN_vector_reverse_v16u8: - return cgFunc.SelectVectorReverse(intrinsicopNode, 32); + return cgFunc.SelectVectorReverse(intrinsicopNode, k32BitSize); default: ASSERT(false, "Should not reach here."); return nullptr; diff --git a/src/mapleall/maple_driver/src/driver_runner.cpp b/src/mapleall/maple_driver/src/driver_runner.cpp index 4373c730ae169437fbac2f1f78dce497f7b6d507..2de1a56f37b079d7011799fb66d3d8cc32e2c36d 100644 --- a/src/mapleall/maple_driver/src/driver_runner.cpp +++ b/src/mapleall/maple_driver/src/driver_runner.cpp @@ -332,7 +332,7 @@ void DriverRunner::ProcessCGPhase(const std::string &outputFile, const std::stri if (!cgOptions->SuppressFileInfo()) { cg->GetEmitter()->EmitFileInfo(actualInput); } - if (withDwarf) { + if (cgOptions->WithDwarf()) { cg->GetEmitter()->EmitDIHeader(); } // Run the cg optimizations phases diff --git a/src/mapleall/maple_ir/include/intrinsic_vector.def b/src/mapleall/maple_ir/include/intrinsic_vector.def index 349a94b36e8c4976f3cf6f3e496ad7491a3b2466..f79bcaf5d36b87e7d4439d333e5b4c6c219f14f2 100644 --- a/src/mapleall/maple_ir/include/intrinsic_vector.def +++ b/src/mapleall/maple_ir/include/intrinsic_vector.def @@ -675,8 +675,8 @@ DEF_MIR_INTRINSIC(vector_store_v2f32, "vector_store_v2f32", INTRNISVECTOR, // Temporary intrinsics that should be replaced by standard ops. DEF_MIR_INTRINSIC(vector_and_v8u16, "vector_and_v8u16", kArgTyV8U16, kArgTyV8U16, kArgTyV8U16) -DEF_MIR_INTRINSIC(vector_and_v4i32, "vector_and_v4i32", kArgTyV4I32, - kArgTyV4I32, kArgTyV4I32) +DEF_MIR_INTRINSIC(vector_and_v4u32, "vector_and_v4u32", kArgTyV4U32, + kArgTyV4U32, kArgTyV4U32) DEF_MIR_INTRINSIC(vector_eq_v8u16, "vector_eq_v8u16", kArgTyV8U16, kArgTyV8U16, kArgTyV8U16) DEF_MIR_INTRINSIC(vector_shl_v8u16, "vector_shl_v8u16", kArgTyV8U16, kArgTyV8U16, diff --git a/src/mapleall/maple_ir/include/mir_nodes.h b/src/mapleall/maple_ir/include/mir_nodes.h index 2d5bd71ad71f9ce1623f4b110db0594fd77bf18c..9e6582f7da444540468c04a346303a8325cbf7b6 100644 --- a/src/mapleall/maple_ir/include/mir_nodes.h +++ b/src/mapleall/maple_ir/include/mir_nodes.h @@ -3178,12 +3178,13 @@ enum AsmQualifierKind : unsigned { // they are alreadgy Maple IR keywords class AsmNode : public NaryStmtNode { public: - explicit AsmNode(MapleAllocator *alloc) : NaryStmtNode(*alloc, OP_asm), - asmString(alloc->GetMemPool()), inputConstraints(alloc->Adapter()), - asmOutputs(alloc->Adapter()), outputConstraints(alloc->Adapter()), - clobberList(alloc->Adapter()), gotoLabels(alloc->Adapter()), qualifiers(0) {} + explicit AsmNode(MapleAllocator &alloc) + : NaryStmtNode(alloc, OP_asm), + asmString(alloc.GetMemPool()), inputConstraints(alloc.Adapter()), + asmOutputs(alloc.Adapter()), outputConstraints(alloc.Adapter()), + clobberList(alloc.Adapter()), gotoLabels(alloc.Adapter()), qualifiers(0) {} - AsmNode(AsmNode &node) = delete; + AsmNode(const AsmNode &node) = delete; AsmNode &operator=(const AsmNode &node) = delete; virtual ~AsmNode() = default; @@ -3195,6 +3196,8 @@ class AsmNode : public NaryStmtNode { return (qualifiers & (1U << static_cast(x))) != 0; } + void DumpOutputs(int32 indent, std::string &uStr) const; + void DumpInputOperands(int32 indent, std::string &uStr) const; void Dump(int32 indent) const override; MapleString asmString; diff --git a/src/mapleall/maple_ir/include/mir_type.h b/src/mapleall/maple_ir/include/mir_type.h index bb8eedd33e9e25c5652a9e17422760d20ebe1c68..5c1a400c3906fdd1735b84f71dea370f6ed6d1cc 100644 --- a/src/mapleall/maple_ir/include/mir_type.h +++ b/src/mapleall/maple_ir/include/mir_type.h @@ -432,6 +432,9 @@ struct OffsetType { } OffsetType operator+(int64 offset) const { + if (this->IsInvalid()) { + return *this; + } int64 sum = this->val + offset; if (sum >= kOffsetMin && sum <= kOffsetMax) { return OffsetType(static_cast(sum)); diff --git a/src/mapleall/maple_ir/src/bin_func_export.cpp b/src/mapleall/maple_ir/src/bin_func_export.cpp index f2ef3c5ff40a485b5bf78f9354f1a66656594da2..9095fa04d5d8efe5d786a35e87f32f3c88d6b449 100644 --- a/src/mapleall/maple_ir/src/bin_func_export.cpp +++ b/src/mapleall/maple_ir/src/bin_func_export.cpp @@ -592,25 +592,25 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { // the outputs size_t count = asmNode->asmOutputs.size(); WriteNum(count); - for (int32 i = 0; i < count; i++) { + for (size_t i = 0; i < count; i++) { OutputUsrStr(asmNode->outputConstraints[i]); } OutputReturnValues(&asmNode->asmOutputs); // the clobber list count = asmNode->clobberList.size(); WriteNum(count); - for (int32 i = 0; i < count; i++) { + for (size_t i = 0; i < count; ++i) { OutputUsrStr(asmNode->clobberList[i]); } // the labels count = asmNode->gotoLabels.size(); WriteNum(count); - for (int32 i = 0; i < count; i++) { + for (size_t i = 0; i < count; ++i) { WriteNum(asmNode->gotoLabels[i]); } // the inputs WriteNum(asmNode->NumOpnds()); - for (int32 i = 0; i < asmNode->numOpnds; i++) { + for (int32 i = 0; i < asmNode->numOpnds; ++i) { OutputUsrStr(asmNode->inputConstraints[i]); } break; diff --git a/src/mapleall/maple_ir/src/bin_func_import.cpp b/src/mapleall/maple_ir/src/bin_func_import.cpp index 41c226782f34384ad03c1f4ec2b4dfd898423e46..dda938d12612675895739e91c68139909909c58e 100644 --- a/src/mapleall/maple_ir/src/bin_func_import.cpp +++ b/src/mapleall/maple_ir/src/bin_func_import.cpp @@ -27,7 +27,7 @@ using namespace std; namespace maple { void BinaryMplImport::ImportInfoVector(MIRInfoVector &infoVector, MapleVector &infoVectorIsString) { int64 size = ReadNum(); - for (int64 i = 0; i < size; i++) { + for (int64 i = 0; i < size; ++i) { GStrIdx gStrIdx = ImportStr(); bool isstring = ReadNum(); infoVectorIsString.push_back(isstring); @@ -98,7 +98,7 @@ void BinaryMplImport::ImportLocalSymTab(MIRFunction *func) { int64 tag = ReadNum(); CHECK_FATAL(tag == kBinSymStart, "kBinSymStart expected in ImportLocalSymTab()"); int32 size = ReadInt(); - for (int64 i = 0; i < size; i++) { + for (int64 i = 0; i < size; ++i) { ImportLocalSymbol(func); } tag = ReadNum(); @@ -109,7 +109,7 @@ void BinaryMplImport::ImportPregTab(const MIRFunction *func) { int64 tag = ReadNum(); CHECK_FATAL(tag == kBinPregStart, "kBinPregStart expected in ImportPregTab()"); int32 size = ReadInt(); - for (int64 i = 0; i < size; i++) { + for (int64 i = 0; i < size; ++i) { int64 tag = ReadNum(); if (tag == 0) { func->GetPregTab()->GetPregTable().push_back(nullptr); @@ -131,7 +131,7 @@ void BinaryMplImport::ImportLabelTab(MIRFunction *func) { int64 tag = ReadNum(); CHECK_FATAL(tag == kBinLabelStart, "kBinLabelStart expected in ImportLabelTab()"); int32 size = ReadNum(); - for (int64 i = 0; i < size; i++) { + for (int64 i = 0; i < size; ++i) { GStrIdx gStrIdx = ImportStr(); (void)func->GetLabelTab()->AddLabel(gStrIdx); } @@ -143,7 +143,7 @@ void BinaryMplImport::ImportLocalTypeNameTable(MIRTypeNameTable *typeNameTab) { int64 tag = ReadNum(); CHECK_FATAL(tag == kBinTypenameStart, "kBinTypenameStart expected in ImportLocalTypeNameTable()"); int32 size = ReadNum(); - for (int64 i = 0; i < size; i++) { + for (int64 i = 0; i < size; ++i) { GStrIdx strIdx = ImportStr(); TyIdx tyIdx = ImportType(); typeNameTab->SetGStrIdxToTyIdx(strIdx, tyIdx); @@ -156,7 +156,7 @@ void BinaryMplImport::ImportFormalsStIdx(MIRFunction *func) { int64 tag = ReadNum(); CHECK_FATAL(tag == kBinFormalStart, "kBinFormalStart expected in ImportFormalsStIdx()"); int32 size = ReadNum(); - for (int64 i = 0; i < size; i++) { + for (int64 i = 0; i < size; ++i) { uint32 indx = ReadNum(); func->GetFormalDefVec()[i].formalSym = func->GetSymTab()->GetSymbolFromStIdx(indx); } @@ -168,7 +168,7 @@ void BinaryMplImport::ImportAliasMap(MIRFunction *func) { int64 tag = ReadNum(); CHECK_FATAL(tag == kBinAliasMapStart, "kBinAliasMapStart expected in ImportAliasMap()"); int32 size = ReadInt(); - for (int32 i = 0; i < size; i++) { + for (int32 i = 0; i < size; ++i) { MIRAliasVars aliasvars; GStrIdx strIdx = ImportStr(); aliasvars.memPoolStrIdx = ImportStr(); @@ -382,7 +382,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { ArrayNode *arrNode = mod.CurFuncCodeMemPool()->New(func->GetCodeMPAllocator(), typ, tidx, boundsCheck); uint32 n = ReadNum(); - for (uint32 i = 0; i < n; i++) { + for (uint32 i = 0; i < n; ++i) { arrNode->GetNopnd().push_back(ImportExpression(func)); } arrNode->SetNumOpnds(arrNode->GetNopnd().size()); @@ -392,7 +392,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { IntrinsicopNode *intrnNode = mod.CurFuncCodeMemPool()->New(func->GetCodeMPAllocator(), op, typ); intrnNode->SetIntrinsic((MIRIntrinsicID)ReadNum()); uint32 n = ReadNum(); - for (uint32 i = 0; i < n; i++) { + for (uint32 i = 0; i < n; ++i) { intrnNode->GetNopnd().push_back(ImportExpression(func)); } intrnNode->SetNumOpnds(intrnNode->GetNopnd().size()); @@ -404,7 +404,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { intrnNode->SetIntrinsic((MIRIntrinsicID)ReadNum()); intrnNode->SetTyIdx(ImportType()); uint32 n = ReadNum(); - for (uint32 i = 0; i < n; i++) { + for (uint32 i = 0; i < n; ++i) { intrnNode->GetNopnd().push_back(ImportExpression(func)); } intrnNode->SetNumOpnds(intrnNode->GetNopnd().size()); @@ -425,7 +425,7 @@ void BinaryMplImport::ImportReturnValues(MIRFunction *func, CallReturnVector *re int64 tag = ReadNum(); CHECK_FATAL(tag == kBinReturnvals, "expecting return values"); uint32 size = ReadNum(); - for (uint32 i = 0; i < size; i++) { + for (uint32 i = 0; i < size; ++i) { uint32 idx = ReadNum(); FieldID fid = ReadNum(); PregIdx16 ridx = ReadNum(); @@ -508,7 +508,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { s->SetPUIdx(ImportFuncViaSymName()); numOpr = ReadNum(); s->SetNumOpnds(numOpr); - for (int32 i = 0; i < numOpr; i++) { + for (int32 i = 0; i < numOpr; ++i) { s->GetNopnd().push_back(ImportExpression(func)); } stmt = s; @@ -526,7 +526,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { ImportReturnValues(func, &s->GetReturnVec()); numOpr = ReadNum(); s->SetNumOpnds(numOpr); - for (int32 i = 0; i < numOpr; i++) { + for (int32 i = 0; i < numOpr; ++i) { s->GetNopnd().push_back(ImportExpression(func)); } stmt = s; @@ -538,7 +538,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { s->SetTyIdx(ImportType()); numOpr = ReadNum(); s->SetNumOpnds(numOpr); - for (int32 i = 0; i < numOpr; i++) { + for (int32 i = 0; i < numOpr; ++i) { s->GetNopnd().push_back(ImportExpression(func)); } stmt = s; @@ -551,7 +551,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { ImportReturnValues(func, &s->GetReturnVec()); numOpr = ReadNum(); s->SetNumOpnds(numOpr); - for (int32 i = 0; i < numOpr; i++) { + for (int32 i = 0; i < numOpr; ++i) { s->GetNopnd().push_back(ImportExpression(func)); } stmt = s; @@ -562,7 +562,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { s->SetRetTyIdx(ImportType()); numOpr = ReadNum(); s->SetNumOpnds(numOpr); - for (int32 i = 0; i < numOpr; i++) { + for (int32 i = 0; i < numOpr; ++i) { s->GetNopnd().push_back(ImportExpression(func)); } stmt = s; @@ -574,7 +574,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { ImportReturnValues(func, &s->GetReturnVec()); numOpr = ReadNum(); s->SetNumOpnds(numOpr); - for (int32 i = 0; i < numOpr; i++) { + for (int32 i = 0; i < numOpr; ++i) { s->GetNopnd().push_back(ImportExpression(func)); } stmt = s; @@ -586,7 +586,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { s->SetIntrinsic((MIRIntrinsicID)ReadNum()); numOpr = ReadNum(); s->SetNumOpnds(numOpr); - for (int32 i = 0; i < numOpr; i++) { + for (int32 i = 0; i < numOpr; ++i) { s->GetNopnd().push_back(ImportExpression(func)); } stmt = s; @@ -599,7 +599,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { ImportReturnValues(func, &s->GetReturnVec()); numOpr = ReadNum(); s->SetNumOpnds(numOpr); - for (int32 i = 0; i < numOpr; i++) { + for (int32 i = 0; i < numOpr; ++i) { s->GetNopnd().push_back(ImportExpression(func)); } if (s->GetReturnVec().size() == 1 && s->GetReturnVec()[0].first.Idx() != 0) { @@ -617,7 +617,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { s->SetTyIdx(ImportType()); numOpr = ReadNum(); s->SetNumOpnds(numOpr); - for (int32 i = 0; i < numOpr; i++) { + for (int32 i = 0; i < numOpr; ++i) { s->GetNopnd().push_back(ImportExpression(func)); } stmt = s; @@ -630,7 +630,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { ImportReturnValues(func, &s->GetReturnVec()); numOpr = ReadNum(); s->SetNumOpnds(numOpr); - for (int32 i = 0; i < numOpr; i++) { + for (int32 i = 0; i < numOpr; ++i) { s->GetNopnd().push_back(ImportExpression(func)); } if (s->GetReturnVec().size() == 1 && s->GetReturnVec()[0].first.Idx() != 0) { @@ -648,7 +648,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { NaryStmtNode *s = func->GetCodeMemPool()->New(mod, op); numOpr = ReadNum(); s->SetNumOpnds(numOpr); - for (int32 i = 0; i < numOpr; i++) { + for (int32 i = 0; i < numOpr; ++i) { s->GetNopnd().push_back(ImportExpression(func)); } stmt = s; @@ -705,7 +705,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { SwitchNode *s = mod.CurFuncCodeMemPool()->New(mod); s->SetDefaultLabel(ReadNum()); uint32 tagSize = ReadNum(); - for (uint32 i = 0; i < tagSize; i++) { + for (uint32 i = 0; i < tagSize; ++i) { int64 casetag = ReadNum(); LabelIdx lidx(ReadNum()); CasePair cpair = std::make_pair(casetag, lidx); @@ -735,7 +735,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { case OP_catch: { CatchNode *s = mod.CurFuncCodeMemPool()->New(mod); uint32 numTys = ReadNum(); - for (uint32 i = 0; i < numTys; i++) { + for (uint32 i = 0; i < numTys; ++i) { s->PushBack(ImportType()); } stmt = s; @@ -774,7 +774,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { break; } case OP_asm: { - AsmNode *s = mod.CurFuncCodeMemPool()->New(&mod.GetCurFuncCodeMPAllocator()); + AsmNode *s = mod.CurFuncCodeMemPool()->New(mod.GetCurFuncCodeMPAllocator()); s->qualifiers = ReadNum(); string str; ReadAsciiStr(str); @@ -782,31 +782,31 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { // the outputs size_t count = ReadNum(); UStrIdx strIdx; - for (int32 i = 0; i < count; i++) { + for (size_t i = 0; i < count; ++i) { strIdx = ImportUsrStr(); s->outputConstraints.push_back(strIdx); } ImportReturnValues(func, &s->asmOutputs); // the clobber list count = ReadNum(); - for (int32 i = 0; i < count; i++) { + for (size_t i = 0; i < count; ++i) { strIdx = ImportUsrStr(); s->clobberList.push_back(strIdx); } // the labels count = ReadNum(); - for (int32 i = 0; i < count; i++) { + for (size_t i = 0; i < count; ++i) { LabelIdx lidx = ReadNum(); s->gotoLabels.push_back(lidx); } // the inputs numOpr = ReadNum(); s->SetNumOpnds(numOpr); - for (int32 i = 0; i < numOpr; i++) { + for (int32 i = 0; i < numOpr; ++i) { strIdx = ImportUsrStr(); s->inputConstraints.push_back(strIdx); } - for (int32 i = 0; i < numOpr; i++) { + for (int32 i = 0; i < numOpr; ++i) { s->GetNopnd().push_back(ImportExpression(func)); } stmt = s; @@ -828,7 +828,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { void BinaryMplImport::ReadFunctionBodyField() { (void)ReadInt(); /// skip total size int32 size = ReadInt(); - for (int64 i = 0; i < size; i++) { + for (int64 i = 0; i < size; ++i) { PUIdx puIdx = ImportFunction(); MIRFunction *fn = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); mod.SetCurFunction(fn); diff --git a/src/mapleall/maple_ir/src/mir_builder.cpp b/src/mapleall/maple_ir/src/mir_builder.cpp index 6fae92961f4e26a60983af63e1f2b38fe697f792..700795ccebb4b95844d174575e5341ef21788fbb 100644 --- a/src/mapleall/maple_ir/src/mir_builder.cpp +++ b/src/mapleall/maple_ir/src/mir_builder.cpp @@ -618,11 +618,11 @@ AddrofNode *MIRBuilder::CreateExprDread(PregIdx pregID, PrimType pty) { IreadNode *MIRBuilder::CreateExprIread(const MIRType &returnType, const MIRType &ptrType, FieldID fieldID, BaseNode *addr) { TyIdx returnTypeIdx = returnType.GetTypeIndex(); - CHECK(returnTypeIdx < GlobalTables::GetTypeTable().GetTypeTable().size(), + ASSERT(returnTypeIdx < GlobalTables::GetTypeTable().GetTypeTable().size(), "index out of range in MIRBuilder::CreateExprIread"); ASSERT(fieldID != 0 || ptrType.GetPrimType() != PTY_agg, "Error: Fieldid should not be 0 when trying to iread a field from type "); - PrimType type = GetRegPrimType(returnType.GetPrimType()); + PrimType type = GlobalTables::GetTypeTable().GetPrimTypeFromTyIdx(returnTypeIdx); return GetCurrentFuncCodeMp()->New(OP_iread, type, ptrType.GetTypeIndex(), fieldID, addr); } diff --git a/src/mapleall/maple_ir/src/mir_nodes.cpp b/src/mapleall/maple_ir/src/mir_nodes.cpp index 2fe85dad09dd5a8449988b3bb40bcde254e4d444..e28b16e0dfec79c3f91fcc273e11f37683a34f51 100644 --- a/src/mapleall/maple_ir/src/mir_nodes.cpp +++ b/src/mapleall/maple_ir/src/mir_nodes.cpp @@ -1176,13 +1176,13 @@ void CommentNode::Dump(int32 indent) const { LogInfo::MapleLogger() << "#" << comment << '\n'; } -static void EmitStr(const MapleString *mplStr) { - const char *str = mplStr->c_str(); - size_t len = mplStr->length(); +static void EmitStr(const MapleString &mplStr) { + const char *str = mplStr.c_str(); + size_t len = mplStr.length(); LogInfo::MapleLogger() << "\""; // don't expand special character; convert all \s to \\s in string - for (int i = 0; i < len; i++) { + for (size_t i = 0; i < len; ++i) { /* Referred to GNU AS: 3.6.1.1 Strings */ constexpr int kBufSize = 5; constexpr int kFirstChar = 0; @@ -1214,7 +1214,7 @@ static void EmitStr(const MapleString *mplStr) { LogInfo::MapleLogger() << buf; } else { /* all others, print as number */ - int ret = snprintf_s(buf, sizeof(buf), 4, "\\%03o", (*str) & 0xFF); + int ret = snprintf_s(buf, sizeof(buf), kBufSize - 1, "\\%03o", (*str) & 0xFF); if (ret < 0) { FATAL(kLncFatal, "snprintf_s failed"); } @@ -1227,34 +1227,18 @@ static void EmitStr(const MapleString *mplStr) { LogInfo::MapleLogger() << "\"\n"; } -void AsmNode::Dump(int32 indent) const { - if (srcPosition.FileNum() != 0 && srcPosition.LineNum() != 0 && srcPosition.LineNum() != lastPrintedLineNum && - theMIRModule->CurFunction()->WithLocInfo()) { - LogInfo::MapleLogger() << "LOC " << srcPosition.FileNum() << " " << srcPosition.LineNum() << '\n'; - lastPrintedLineNum = srcPosition.LineNum(); - } - PrintIndentation(indent); - LogInfo::MapleLogger() << kOpcodeInfo.GetName(op); - if (GetQualifier(kASMvolatile)) - LogInfo::MapleLogger() << " volatile"; - if (GetQualifier(kASMinline)) - LogInfo::MapleLogger() << " inline"; - if (GetQualifier(kASMgoto)) - LogInfo::MapleLogger() << " goto"; - LogInfo::MapleLogger() << " { "; - EmitStr(&asmString); - // print outputs - PrintIndentation(indent+1); +void AsmNode::DumpOutputs(int32 indent, std::string &uStr) const { + PrintIndentation(indent + 1); LogInfo::MapleLogger() << " :"; size_t numOutputs = asmOutputs.size(); - std::string uStr; + const MIRFunction *mirFunc = theMIRModule->CurFunction(); if (numOutputs == 0) { LogInfo::MapleLogger() << '\n'; } else { for (size_t i = 0; i < numOutputs; i++) { if (i != 0) { - PrintIndentation(indent+2); + PrintIndentation(indent + 2); // Increase the indent by 2 bytes. } uStr = GlobalTables::GetUStrTable().GetStringFromStrIdx(outputConstraints[i]); PrintString(uStr); @@ -1282,20 +1266,22 @@ void AsmNode::Dump(int32 indent) const { LogInfo::MapleLogger() << '\n'; } } - // print input operands - PrintIndentation(indent+1); +} + +void AsmNode::DumpInputOperands(int32 indent, std::string &uStr) const { + PrintIndentation(indent + 1); LogInfo::MapleLogger() << " :"; if (numOpnds == 0) { LogInfo::MapleLogger() << '\n'; } else { for (size_t i = 0; i < numOpnds; i++) { if (i != 0) { - PrintIndentation(indent+2); + PrintIndentation(indent + 2); // Increase the indent by 2 bytes. } uStr = GlobalTables::GetUStrTable().GetStringFromStrIdx(inputConstraints[i]); PrintString(uStr); LogInfo::MapleLogger() << " ("; - GetNopndAt(i)->Dump(indent+4); + GetNopndAt(i)->Dump(indent + 4); // Increase the indent by 4 bytes. LogInfo::MapleLogger() << ")"; if (i != numOpnds - 1) { LogInfo::MapleLogger() << ','; @@ -1303,8 +1289,31 @@ void AsmNode::Dump(int32 indent) const { LogInfo::MapleLogger() << "\n"; } } - // print clobber list - PrintIndentation(indent+1); +} + +void AsmNode::Dump(int32 indent) const { + if (srcPosition.FileNum() != 0 && srcPosition.LineNum() != 0 && srcPosition.LineNum() != lastPrintedLineNum && + theMIRModule->CurFunction()->WithLocInfo()) { + LogInfo::MapleLogger() << "LOC " << srcPosition.FileNum() << " " << srcPosition.LineNum() << '\n'; + lastPrintedLineNum = srcPosition.LineNum(); + } + PrintIndentation(indent); + LogInfo::MapleLogger() << kOpcodeInfo.GetName(op); + if (GetQualifier(kASMvolatile)) + LogInfo::MapleLogger() << " volatile"; + if (GetQualifier(kASMinline)) + LogInfo::MapleLogger() << " inline"; + if (GetQualifier(kASMgoto)) + LogInfo::MapleLogger() << " goto"; + LogInfo::MapleLogger() << " { "; + EmitStr(asmString); + // print outputs + std::string uStr; + DumpOutputs(indent, uStr); + // print input operands + DumpInputOperands(indent, uStr); + // print clobber list + PrintIndentation(indent + 1); LogInfo::MapleLogger() << " :"; for (size_t i = 0; i < clobberList.size(); i++) { uStr = GlobalTables::GetUStrTable().GetStringFromStrIdx(clobberList[i]); @@ -1315,7 +1324,7 @@ void AsmNode::Dump(int32 indent) const { } LogInfo::MapleLogger() << '\n'; // print labels - PrintIndentation(indent+1); + PrintIndentation(indent + 1); LogInfo::MapleLogger() << " :"; for (size_t i = 0; i < gotoLabels.size(); i++) { LabelIdx offset = gotoLabels[i]; diff --git a/src/mapleall/maple_ir/src/mir_parser.cpp b/src/mapleall/maple_ir/src/mir_parser.cpp index 2bc7f8d157a973152b6ba6f54d54f9b72ef3d1e8..67eadd6c7c3ea7fa8f16dfa19670cc7ba3a35bed 100644 --- a/src/mapleall/maple_ir/src/mir_parser.cpp +++ b/src/mapleall/maple_ir/src/mir_parser.cpp @@ -1082,7 +1082,7 @@ bool MIRParser::ParseCallReturns(CallReturnVector &retsvec) { } bool MIRParser::ParseStmtAsm(StmtNodePtr &stmt) { - AsmNode *asmNode = mod.CurFuncCodeMemPool()->New(&mod.GetCurFuncCodeMPAllocator()); + AsmNode *asmNode = mod.CurFuncCodeMemPool()->New(mod.GetCurFuncCodeMPAllocator()); lexer.NextToken(); // parse qualifiers while (lexer.GetTokenKind() == TK_volatile || @@ -1090,10 +1090,19 @@ bool MIRParser::ParseStmtAsm(StmtNodePtr &stmt) { lexer.GetTokenKind() == TK_goto) { AsmQualifierKind qual; switch (lexer.GetTokenKind()) { - case TK_volatile: qual = kASMvolatile; break; - case TK_inline: qual = kASMinline; break; + case TK_volatile: { + qual = kASMvolatile; + break; + } + case TK_inline: { + qual = kASMinline; + break; + } case TK_goto: - default: qual = kASMgoto; break; + default: { + qual = kASMgoto; + break; + } } asmNode->SetQualifier(qual); lexer.NextToken(); @@ -1121,7 +1130,7 @@ bool MIRParser::ParseStmtAsm(StmtNodePtr &stmt) { UStrIdx uStrIdx; CallReturnPair retpair; while (lexer.GetTokenKind() == TK_string) { - // parse an output constraint string + // parse an output constraint string uStrIdx = GlobalTables::GetUStrTable().GetOrCreateStrIdxFromName(lexer.GetName()); lexer.NextToken(); if (!ParseCallReturnPair(retpair)) { @@ -1142,7 +1151,7 @@ bool MIRParser::ParseStmtAsm(StmtNodePtr &stmt) { lexer.NextToken(); // parse inputs while (lexer.GetTokenKind() == TK_string) { - // parse an input constraint string + // parse an input constraint string uStrIdx = GlobalTables::GetUStrTable().GetOrCreateStrIdxFromName(lexer.GetName()); if (lexer.NextToken() != TK_lparen) { Error("expect ( but get "); @@ -1173,7 +1182,7 @@ bool MIRParser::ParseStmtAsm(StmtNodePtr &stmt) { lexer.NextToken(); // parse clobber list while (lexer.GetTokenKind() == TK_string) { - // parse an input constraint string + // parse an input constraint string uStrIdx = GlobalTables::GetUStrTable().GetOrCreateStrIdxFromName(lexer.GetName()); asmNode->clobberList.push_back(uStrIdx); if (lexer.NextToken() == TK_coma) { diff --git a/src/mapleall/maple_me/include/alias_class.h b/src/mapleall/maple_me/include/alias_class.h index 5772272a3ae4a611ca2aa2cfa4e9d1f912734d12..2fd7d8a0f0c5db18a520ec9cfead24b314eb3c92 100644 --- a/src/mapleall/maple_me/include/alias_class.h +++ b/src/mapleall/maple_me/include/alias_class.h @@ -168,6 +168,7 @@ class AliasClass : public AnalysisResult { void GenericInsertMayDefUse(StmtNode &stmt, BBId bbID); static bool MayAliasBasicAA(const OriginalSt *ostA, const OriginalSt *ostB); + bool MayAlias(const OriginalSt *ostA, const OriginalSt *ostB) const; protected: virtual bool InConstructorLikeFunc() const { diff --git a/src/mapleall/maple_me/include/dse.h b/src/mapleall/maple_me/include/dse.h index 118345945db3c67cfee3bbb926c63ae74467e089..0a5376f6d71df6e480e6e94d3e25905527792f71 100644 --- a/src/mapleall/maple_me/include/dse.h +++ b/src/mapleall/maple_me/include/dse.h @@ -22,16 +22,19 @@ #include "safe_ptr.h" #include "ssa_tab.h" #include "mir_module.h" +#include "alias_class.h" namespace maple { class DSE { public: - DSE(std::vector &&bbVec, BB &commonEntryBB, BB &commonExitBB, SSATab &ssaTab, - Dominance &postDom, bool enableDebug = false, bool decouple = false, bool islfo = false) + DSE(std::vector &&bbVec, BB &commonEntryBB, BB &commonExitBB, SSATab &ssaTab, Dominance &postDom, + const AliasClass *aliasClass, bool enableDebug = false, bool decouple = false, bool islfo = false) : enableDebug(enableDebug), bbVec(bbVec), commonEntryBB(commonEntryBB), commonExitBB(commonExitBB), ssaTab(ssaTab), - postDom(postDom), bbRequired(bbVec.size(), false), + postDom(postDom), + aliasInfo(aliasClass), + bbRequired(bbVec.size(), false), exprRequired(ssaTab.GetVersionStTableSize(), false), decoupleStatic(decouple), isLfo(islfo) {} @@ -120,6 +123,7 @@ class DSE { BB &commonExitBB; SSATab &ssaTab; Dominance &postDom; + const AliasClass *aliasInfo; std::vector bbRequired; std::vector exprRequired; std::forward_list> workList{}; diff --git a/src/mapleall/maple_me/include/hdse.h b/src/mapleall/maple_me/include/hdse.h index 094aa36ce0033d96c786c2b5a5bfe9671b1d94cf..d89aac89fbc7a114fe39e984bd0c048152dc70d2 100644 --- a/src/mapleall/maple_me/include/hdse.h +++ b/src/mapleall/maple_me/include/hdse.h @@ -17,13 +17,14 @@ #include "bb.h" #include "irmap.h" #include "dominance.h" +#include "alias_class.h" namespace maple { class MeIRMap; class HDSE { public: HDSE(MIRModule &mod, const MapleVector &bbVec, BB &commonEntryBB, BB &commonExitBB, - Dominance &pDom, IRMap &map, bool enabledDebug = false, bool decouple = false) + Dominance &pDom, IRMap &map, const AliasClass *aliasClass, bool enabledDebug = false, bool decouple = false) : hdseDebug(enabledDebug), mirModule(mod), bbVec(bbVec), @@ -31,6 +32,7 @@ class HDSE { commonExitBB(commonExitBB), postDom(pDom), irMap(map), + aliasInfo(aliasClass), bbRequired(bbVec.size(), false), decoupleStatic(decouple) {} @@ -106,6 +108,7 @@ class HDSE { BB &commonExitBB; Dominance &postDom; IRMap &irMap; + const AliasClass *aliasInfo; std::vector bbRequired; std::vector exprLive; std::forward_list workList; diff --git a/src/mapleall/maple_me/include/irmap.h b/src/mapleall/maple_me/include/irmap.h index 6a74b838d3b471768125f73f9275dc64c0eb68de..71b80ed9826643a4558523e5dece5bd60ae9375d 100644 --- a/src/mapleall/maple_me/include/irmap.h +++ b/src/mapleall/maple_me/include/irmap.h @@ -125,6 +125,7 @@ class IRMap : public AnalysisResult { ScalarMeExpr *ret, TyIdx tyIdx = TyIdx()); MeExpr *SimplifyOpMeExpr(OpMeExpr *opmeexpr); MeExpr *SimplifyMeExpr(MeExpr *x); + static void SimplifyIvar(IvarMeExpr *ivar); template T *NewInPool(Arguments&&... args) { diff --git a/src/mapleall/maple_me/include/me_dse.h b/src/mapleall/maple_me/include/me_dse.h index 43c58183d75d9c72697d258d2b0cdbd2e9acb3bd..b4d9fea3654fd57a01d939ec12a3e463c271376f 100644 --- a/src/mapleall/maple_me/include/me_dse.h +++ b/src/mapleall/maple_me/include/me_dse.h @@ -26,10 +26,10 @@ namespace maple { class MeDSE : public DSE { public: - MeDSE(MeFunction &func, Dominance *dom, bool enabledDebug) + MeDSE(MeFunction &func, Dominance *dom, const AliasClass *aliasClass, bool enabledDebug) : DSE(std::vector(func.GetCfg()->GetAllBBs().begin(), func.GetCfg()->GetAllBBs().end()), *func.GetCfg()->GetCommonEntryBB(), *func.GetCfg()->GetCommonExitBB(), *func.GetMeSSATab(), - *dom, enabledDebug, MeOption::decoupleStatic, func.IsLfo()), + *dom, aliasClass, enabledDebug, MeOption::decoupleStatic, func.IsLfo()), func(func), cfg(func.GetCfg()) {} virtual ~MeDSE() = default; diff --git a/src/mapleall/maple_me/include/me_hdse.h b/src/mapleall/maple_me/include/me_hdse.h index d3ce2a72643e7b668786692f23fcced79a791d61..a965e572bda2e87f6185f1e9e7956a602d08eb12 100644 --- a/src/mapleall/maple_me/include/me_hdse.h +++ b/src/mapleall/maple_me/include/me_hdse.h @@ -25,9 +25,9 @@ namespace maple { class MeHDSE : public HDSE { public: - MeHDSE(MeFunction &f, Dominance &pDom, IRMap &map, bool enabledDebug) + MeHDSE(MeFunction &f, Dominance &pDom, IRMap &map, const AliasClass *aliasClass, bool enabledDebug) : HDSE(f.GetMIRModule(), f.GetCfg()->GetAllBBs(), *f.GetCfg()->GetCommonEntryBB(), *f.GetCfg()->GetCommonExitBB(), - pDom, map, enabledDebug, MeOption::decoupleStatic), func(f) {} + pDom, map, aliasClass, enabledDebug, MeOption::decoupleStatic), func(f) {} virtual ~MeHDSE() = default; void BackwardSubstitution(); diff --git a/src/mapleall/maple_me/include/me_ir.h b/src/mapleall/maple_me/include/me_ir.h index 0793a28f5f5f99bc813314399d6b966540221c9a..ff156e5a81a8a458d8658edce1709523c24009a4 100644 --- a/src/mapleall/maple_me/include/me_ir.h +++ b/src/mapleall/maple_me/include/me_ir.h @@ -881,15 +881,19 @@ class OpMeExpr : public MeExpr { class IvarMeExpr : public MeExpr { public: + IvarMeExpr(int32 exprid, PrimType t, TyIdx tidx, FieldID fid, Opcode op) + : MeExpr(exprid, kMeOpIvar, op, t, 1), tyIdx(tidx), fieldID(fid) {} + IvarMeExpr(int32 exprid, PrimType t, TyIdx tidx, FieldID fid) - : MeExpr(exprid, kMeOpIvar, OP_iread, t, 1), tyIdx(tidx), fieldID(fid) {} + : IvarMeExpr(exprid, t, tidx, fid, OP_iread) {} IvarMeExpr(int32 exprid, const IvarMeExpr &ivarme) - : MeExpr(exprid, kMeOpIvar, OP_iread, ivarme.GetPrimType(), 1), + : MeExpr(exprid, kMeOpIvar, ivarme.op, ivarme.GetPrimType(), 1), defStmt(ivarme.defStmt), base(ivarme.base), tyIdx(ivarme.tyIdx), fieldID(ivarme.fieldID), + offset(ivarme.offset), volatileFromBaseSymbol(ivarme.volatileFromBaseSymbol) { mu = ivarme.mu; } @@ -955,6 +959,14 @@ class IvarMeExpr : public MeExpr { fieldID = fieldIDVal; } + int32 GetOffset() const { + return offset; + } + + void SetOffset(int32 val) { + offset = val; + } + bool GetMaybeNull() const { return maybeNull; } @@ -983,7 +995,8 @@ class IvarMeExpr : public MeExpr { uint32 GetHashIndex() const override { constexpr uint32 kIvarHashShift = 4; - return static_cast(OP_iread) + fieldID + (static_cast(base->GetExprID()) << kIvarHashShift); + return static_cast(op) + fieldID + static_cast(offset) + + (static_cast(base->GetExprID()) << kIvarHashShift); } MIRType *GetType() const override { @@ -1000,6 +1013,7 @@ class IvarMeExpr : public MeExpr { TyIdx tyIdx{ 0 }; TyIdx inferredTyIdx{ 0 }; // may be a subclass of above tyIdx FieldID fieldID = 0; + int32 offset = 0; bool maybeNull = true; // false if definitely not null bool volatileFromBaseSymbol = false; // volatile due to its base symbol being volatile ScalarMeExpr *mu = nullptr; // use of mu, only one for IvarMeExpr diff --git a/src/mapleall/maple_me/include/me_rename2preg.h b/src/mapleall/maple_me/include/me_rename2preg.h index bab487a25ae08cb028babd53777ad62333a731fa..427a2003473a9c59960e4bcd0a4c39c8471a608d 100644 --- a/src/mapleall/maple_me/include/me_rename2preg.h +++ b/src/mapleall/maple_me/include/me_rename2preg.h @@ -30,17 +30,20 @@ class SSARename2Preg { sym2reg_map(std::less(), alloc.Adapter()), vstidx2reg_map(alloc.Adapter()), parm_used_vec(alloc.Adapter()), - reg_formal_vec(alloc.Adapter()) {} + reg_formal_vec(alloc.Adapter()), + ostDefedByChi(ssaTab->GetOriginalStTableSize(), false, alloc.Adapter()), + ostUsedByMu(ssaTab->GetOriginalStTableSize(), false, alloc.Adapter()), + ostUsedByDread(ssaTab->GetOriginalStTableSize(), false, alloc.Adapter()) {} void RunSelf(); void PromoteEmptyFunction(); private: - AliasElem *GetAliasElem(const OriginalSt *ost) { + const MapleSet *GetAliasSet(const OriginalSt *ost) { if (ost->GetIndex() >= aliasclass->GetAliasElemCount()) { return nullptr; } - return aliasclass->FindAliasElem(*ost); + return aliasclass->FindAliasElem(*ost)->GetClassSet(); } void Rename2PregStmt(MeStmt *); @@ -54,6 +57,8 @@ class SSARename2Preg { void UpdateMirFunctionFormal(); void SetupParmUsed(const VarMeExpr *); void Init(); + void CollectUsedOst(MeExpr *meExpr); + void CollectDefUseInfoOfOst(); std::string PhaseName() const { return "rename2preg"; } @@ -69,6 +74,9 @@ class SSARename2Preg { MapleVector parm_used_vec; // if parameter is not used, it's false, otherwise true // if the parameter got promoted, the nth of func->mirFunc->_formal is the nth of reg_formal_vec, otherwise nullptr; MapleVector reg_formal_vec; + MapleVector ostDefedByChi; + MapleVector ostUsedByMu; + MapleVector ostUsedByDread; public: uint32 rename2pregCount = 0; }; diff --git a/src/mapleall/maple_me/include/ssa_epre.h b/src/mapleall/maple_me/include/ssa_epre.h index 5db9da0a2a7f79c1b5872f0892cff40bfbcbf50c..ad60e8c102e8fa085227b607a62662982b275e2e 100644 --- a/src/mapleall/maple_me/include/ssa_epre.h +++ b/src/mapleall/maple_me/include/ssa_epre.h @@ -57,6 +57,9 @@ class SSAEPre : public SSAPre { if (!workCand->isSRCand) { return x; } + if (x->GetMeOp() != kMeOpVar && x->GetMeOp() != kMeOpReg) { + return x; + } return static_cast(ResolveAllInjuringDefs(static_cast(x))); } void SubstituteOpnd(MeExpr *x, MeExpr *oldopnd, MeExpr *newopnd) override; diff --git a/src/mapleall/maple_me/src/alias_class.cpp b/src/mapleall/maple_me/src/alias_class.cpp index b73418fd791fba639919dfb8c93de47346aa0135..909a29a860d71d047b217bc19af755c0a28dfb98 100644 --- a/src/mapleall/maple_me/src/alias_class.cpp +++ b/src/mapleall/maple_me/src/alias_class.cpp @@ -1301,6 +1301,11 @@ bool AliasClass::MayAliasBasicAA(const OriginalSt *ostA, const OriginalSt *ostB) } // indirectLevA == 0 && indirectLevB == 0 + // preg has no alias + if (ostA->IsPregOst() || ostB->IsPregOst()) { + return false; + } + // different zero-level-var not alias each other if (ostA->GetMIRSymbol() != ostB->GetMIRSymbol()) { return false; @@ -1335,6 +1340,27 @@ bool AliasClass::MayAliasBasicAA(const OriginalSt *ostA, const OriginalSt *ostB) return (fieldIdA <= fieldIdB + fieldNumOfOstB) && (fieldIdB <= fieldIdA + fieldNumOfOstA); } +bool AliasClass::MayAlias(const OriginalSt *ostA, const OriginalSt *ostB) const { + if (!MayAliasBasicAA(ostA, ostB)) { + return false; + } + + if (ostA->GetIndex() >= osym2Elem.size()) { + return true; + } + if (ostB->GetIndex() >= osym2Elem.size()) { + return true; + } + + auto aliasElemA = osym2Elem[ostA->GetIndex()]; + auto aliasSet = aliasElemA->GetClassSet(); + if (aliasSet == nullptr) { + return false; + } + auto aliasElemB = osym2Elem[ostB->GetIndex()]; + return (aliasSet->find(aliasElemB->GetClassID()) != aliasSet->end()); +} + // here starts pass 2 code void AliasClass::InsertMayUseExpr(BaseNode &expr) { for (size_t i = 0; i < expr.NumOpnds(); ++i) { @@ -1673,8 +1699,7 @@ void AliasClass::CollectMayDefForMustDefs(const StmtNode &stmt, std::setGetClassID() && - aliasElem->GetOriginalSt().GetTyIdx() == lhsAe->GetOriginalSt().GetMIRSymbol()->GetTyIdx()) { + if (elemID != lhsAe->GetClassID()) { (void)mayDefOsts.insert(&aliasElem->GetOriginalSt()); } } diff --git a/src/mapleall/maple_me/src/dse.cpp b/src/mapleall/maple_me/src/dse.cpp index d0c9dc7888e16b30e96f1698583bcc55d2e1902a..f2a30e965f4816b3e5a8d674e88ac116d95fe629 100644 --- a/src/mapleall/maple_me/src/dse.cpp +++ b/src/mapleall/maple_me/src/dse.cpp @@ -260,7 +260,18 @@ void DSE::PropagateUseLive(const VersionSt &vst) { const MayDefNode *mayDef = vst.GetMayDef(); ASSERT(mayDef->GetResult() == &vst, "MarkVst: wrong corresponding version st in maydef"); const VersionSt *verSt = mayDef->GetOpnd(); - MarkStmtRequired(ToRef(mayDef->GetStmt()), ToRef(dfBB)); + + auto defStmt = mayDef->GetStmt(); + if (kOpcodeInfo.IsCallAssigned(defStmt->GetOpCode())) { + MapleVector &mustDefs = ssaTab.GetStmtMustDefNodes(*defStmt); + for (auto &node : mustDefs) { + if (aliasInfo->MayAlias(node.GetResult()->GetOst(), vst.GetOst())) { + AddToWorkList(node.GetResult()); + } + } + } + + MarkStmtRequired(ToRef(defStmt), ToRef(dfBB)); AddToWorkList(verSt); } else { const MustDefNode *mustDef = vst.GetMustDef(); diff --git a/src/mapleall/maple_me/src/hdse.cpp b/src/mapleall/maple_me/src/hdse.cpp index 5747d537c17aa3cc6df6d70e031ee55ef7b2db14..63b6e17dccae57f8c7a73c3acc9e93b04e71b59f 100644 --- a/src/mapleall/maple_me/src/hdse.cpp +++ b/src/mapleall/maple_me/src/hdse.cpp @@ -181,6 +181,17 @@ void HDSE::MarkChiNodeRequired(ChiMeNode &chiNode) { chiNode.SetIsLive(true); workList.push_front(chiNode.GetRHS()); MeStmt *meStmt = chiNode.GetBase(); + + // set MustDefNode live, which defines the chiNode. + auto *mustDefList = meStmt->GetMustDefList(); + if (mustDefList != nullptr) { + for (auto &mustDef : *mustDefList) { + if (aliasInfo->MayAlias(mustDef.GetLHS()->GetOst(), chiNode.GetLHS()->GetOst())) { + mustDef.SetIsLive(true); + } + } + } + MarkStmtRequired(*meStmt); } diff --git a/src/mapleall/maple_me/src/irmap.cpp b/src/mapleall/maple_me/src/irmap.cpp index 2203f717b6e3563210b13d70f3102381ff3785b5..33971323975bbad0b6a874998e7896b231f8d971 100644 --- a/src/mapleall/maple_me/src/irmap.cpp +++ b/src/mapleall/maple_me/src/irmap.cpp @@ -193,6 +193,51 @@ IvarMeExpr *IRMap::BuildLHSIvar(MeExpr &baseAddr, PrimType primType, const TyIdx return meDef; } +static std::pair SimplifyBaseAddressOfIvar(MeExpr *base) { + if (base->GetOp() == OP_add || base->GetOp() == OP_sub) { + auto offsetNode = base->GetOpnd(1); + if (offsetNode->GetOp() == OP_constval) { + // get offset value + auto *mirConst = static_cast(offsetNode)->GetConstVal(); + CHECK_FATAL(mirConst->GetKind() == kConstInt, "must be integer const"); + auto offsetInByte = static_cast(mirConst)->GetValue(); + OffsetType offset(kOffsetUnknown); + offset.Set(base->GetOp() == OP_add ? offsetInByte : -offsetInByte); + if (offset.IsInvalid()) { + return std::make_pair(base, offset); + } + + const auto &baseNodeAndOffset = SimplifyBaseAddressOfIvar(base->GetOpnd(0)); + auto newOffset = offset + baseNodeAndOffset.second; + if (newOffset.IsInvalid()) { + return std::make_pair(base->GetOpnd(0), offset); + } + return std::make_pair(baseNodeAndOffset.first, newOffset); + } + } + return std::make_pair(base, OffsetType::InvalidOffset()); +} + +void IRMap::SimplifyIvar(IvarMeExpr *ivar) { + const auto &newBaseAndOffset = SimplifyBaseAddressOfIvar(ivar->GetBase()); + if (newBaseAndOffset.second.IsInvalid()) { + return; + } + + auto newOffset = newBaseAndOffset.second + ivar->GetOffset(); + if (newOffset.IsInvalid()) { + return; + } + + ivar->SetBase(newBaseAndOffset.first); + if (newOffset.val != 0) { + ivar->SetOp(OP_ireadoff); + } else { + ivar->SetOp(OP_iread); + } + ivar->SetOffset(newOffset.val); +} + IvarMeExpr *IRMap::BuildLHSIvar(MeExpr &baseAddr, IassignMeStmt &iassignMeStmt, FieldID fieldID) { MIRType *ptrMIRType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(iassignMeStmt.GetTyIdx()); auto *realMIRType = static_cast(ptrMIRType); @@ -203,8 +248,13 @@ IvarMeExpr *IRMap::BuildLHSIvar(MeExpr &baseAddr, IassignMeStmt &iassignMeStmt, ty = realMIRType->GetPointedType(); } auto *meDef = New(exprID++, ty->GetPrimType(), iassignMeStmt.GetTyIdx(), fieldID); + if (iassignMeStmt.GetLHSVal() != nullptr && iassignMeStmt.GetLHSVal()->GetOffset() != 0) { + meDef->SetOp(OP_ireadoff); + meDef->SetOffset(iassignMeStmt.GetLHSVal()->GetOffset()); + } meDef->SetBase(&baseAddr); meDef->SetDefStmt(&iassignMeStmt); + SimplifyIvar(meDef); PutToBucket(meDef->GetHashIndex() % mapHashLength, *meDef); return meDef; } diff --git a/src/mapleall/maple_me/src/irmap_build.cpp b/src/mapleall/maple_me/src/irmap_build.cpp index 15cb82e7fd055d9ef0068b73b441b9eb25cd8648..c7e2485342a7f88d40b7ddd354b2485c22952f8a 100644 --- a/src/mapleall/maple_me/src/irmap_build.cpp +++ b/src/mapleall/maple_me/src/irmap_build.cpp @@ -334,7 +334,7 @@ MeExpr *IRMapBuild::BuildExpr(BaseNode &mirNode, bool atParm, bool noProp) { if (typesize < GetPrimTypeSize(addrOfNode.GetPrimType()) && typesize != 0) { // need to insert a convert if (typesize < 4) { - OpMeExpr opmeexpr(kInvalidExprID, IsSignedInteger(addrOfNode.GetPrimType()) ? OP_sext : OP_zext, + OpMeExpr opmeexpr(kInvalidExprID, IsSignedInteger(retmeexpr->GetPrimType()) ? OP_sext : OP_zext, addrOfNode.GetPrimType(), 1); opmeexpr.SetBitsSize(static_cast(typesize * 8)); opmeexpr.SetOpnd(0, retmeexpr); @@ -371,6 +371,7 @@ MeExpr *IRMapBuild::BuildExpr(BaseNode &mirNode, bool atParm, bool noProp) { ivarMeExpr->SetVolatileFromBaseSymbol(true); } } + IRMap::SimplifyIvar(ivarMeExpr); IvarMeExpr *canIvar = static_cast(irMap->HashMeExpr(*ivarMeExpr)); delete ivarMeExpr; ASSERT(static_cast(canIvar)->GetMu() != nullptr, "BuildExpr: ivar node cannot have mu == nullptr"); @@ -389,7 +390,7 @@ MeExpr *IRMapBuild::BuildExpr(BaseNode &mirNode, bool atParm, bool noProp) { if (typesize < GetPrimTypeSize(iReadSSANode.GetPrimType()) && typesize != 0) { // need to insert a convert if (typesize < 4) { - OpMeExpr opmeexpr(kInvalidExprID, IsSignedInteger(iReadSSANode.GetPrimType()) ? OP_sext : OP_zext, + OpMeExpr opmeexpr(kInvalidExprID, IsSignedInteger(retmeexpr->GetPrimType()) ? OP_sext : OP_zext, iReadSSANode.GetPrimType(), 1); opmeexpr.SetBitsSize(static_cast(typesize * 8)); opmeexpr.SetOpnd(0, retmeexpr); @@ -578,7 +579,8 @@ MeStmt *IRMapBuild::BuildIassignMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) IassignMeStmt *meStmt = irMap->NewInPool(&stmt); meStmt->SetTyIdx(iasNode.GetTyIdx()); meStmt->SetRHS(BuildExpr(*iasNode.GetRHS(), false, false)); - meStmt->SetLHSVal(irMap->BuildLHSIvar(*BuildExpr(*iasNode.Opnd(0), false, false), *meStmt, iasNode.GetFieldID())); + meStmt->SetLHSVal(irMap->BuildLHSIvar( + *BuildExpr(*iasNode.Opnd(0), false, false), *meStmt, iasNode.GetFieldID())); if (mirModule.IsCModule()) { bool isVolt = false; for (MayDefNode maydef : ssaPart.GetMayDefNodes()) { diff --git a/src/mapleall/maple_me/src/irmap_emit.cpp b/src/mapleall/maple_me/src/irmap_emit.cpp index c03282e655a4f2517f880136671d5bdfcfa263ed..da22f1d8b0451a58a1f09c38da5dbc41f0c8c14f 100644 --- a/src/mapleall/maple_me/src/irmap_emit.cpp +++ b/src/mapleall/maple_me/src/irmap_emit.cpp @@ -265,7 +265,17 @@ BaseNode &IvarMeExpr::EmitExpr(SSATab &ssaTab) { CHECK_NULL_FATAL(base); auto *ireadNode = ssaTab.GetModule().CurFunction()->GetCodeMempool()->New(OP_iread, PrimType(GetPrimType())); - ireadNode->SetOpnd(&base->EmitExpr(ssaTab), 0); + if (offset == 0) { + ireadNode->SetOpnd(&base->EmitExpr(ssaTab), 0); + } else { + auto *mirType = GlobalTables::GetTypeTable().GetInt32(); + auto *mirConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst(offset, *mirType); + auto *codeMemPool = ssaTab.GetModule().CurFunction()->GetCodeMempool(); + auto *constValNode = codeMemPool->New(mirType->GetPrimType(), mirConst); + auto *newAddrNode = + codeMemPool->New(OP_add, base->GetPrimType(), &(base->EmitExpr(ssaTab)), constValNode); + ireadNode->SetOpnd(newAddrNode, 0); + } ireadNode->SetFieldID(fieldID); ireadNode->SetTyIdx(tyIdx); ASSERT(ireadNode->GetPrimType() != kPtyInvalid, ""); @@ -337,7 +347,17 @@ StmtNode &IassignMeStmt::EmitStmt(SSATab &ssaTab) { auto *iassignNode = ssaTab.GetModule().CurFunction()->GetCodeMempool()->New(); iassignNode->SetTyIdx(tyIdx); iassignNode->SetFieldID(lhsVar->GetFieldID()); - iassignNode->SetAddrExpr(&lhsVar->GetBase()->EmitExpr(ssaTab)); + if (lhsVar->GetOffset() == 0) { + iassignNode->SetAddrExpr(&lhsVar->GetBase()->EmitExpr(ssaTab)); + } else { + auto *mirType = GlobalTables::GetTypeTable().GetInt32(); + auto *mirConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst(lhsVar->GetOffset(), *mirType); + auto *codeMemPool = ssaTab.GetModule().CurFunction()->GetCodeMempool(); + auto *constValNode = codeMemPool->New(mirType->GetPrimType(), mirConst); + auto *newAddrNode = codeMemPool->New( + OP_add, lhsVar->GetBase()->GetPrimType(), &(lhsVar->GetBase()->EmitExpr(ssaTab)), constValNode); + iassignNode->SetAddrExpr(newAddrNode); + } iassignNode->SetRHS(&rhs->EmitExpr(ssaTab)); iassignNode->SetSrcPos(GetSrcPosition()); return *iassignNode; diff --git a/src/mapleall/maple_me/src/me_delegate_rc.cpp b/src/mapleall/maple_me/src/me_delegate_rc.cpp index 6e10df2fa5cfcd32c0eadc08426cbe05b618d05b..2f0a2560d6ed3ff3a5d37afcea610fd0eaebd299 100644 --- a/src/mapleall/maple_me/src/me_delegate_rc.cpp +++ b/src/mapleall/maple_me/src/me_delegate_rc.cpp @@ -830,7 +830,8 @@ AnalysisResult *MeDoDelegateRC::Run(MeFunction *func, MeFuncResultMgr *m, Module ASSERT(dom != nullptr, "dominance phase has problem"); { // invoke hdse to update isLive only - MeHDSE hdse(*func, *dom, *func->GetIRMap(), DEBUGFUNC(func)); + auto aliasClass = static_cast(m->GetAnalysisResult(MeFuncPhase_ALIASCLASS, func)); + MeHDSE hdse(*func, *dom, *func->GetIRMap(), aliasClass, DEBUGFUNC(func)); hdse.InvokeHDSEUpdateLive(); } if (DEBUGFUNC(func)) { diff --git a/src/mapleall/maple_me/src/me_dse.cpp b/src/mapleall/maple_me/src/me_dse.cpp index e6cc71110ce1973bbf5fc4abf12c8ed8677c1637..d9f293fa5baa48c05ed10622dfee6e6dcf2846d6 100644 --- a/src/mapleall/maple_me/src/me_dse.cpp +++ b/src/mapleall/maple_me/src/me_dse.cpp @@ -65,7 +65,8 @@ 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)); + auto *aliasClass = static_cast(m->GetAnalysisResult(MeFuncPhase_ALIASCLASS, func)); + MeDSE dse(*func, postDom, aliasClass, DEBUGFUNC(func)); dse.RunDSE(); func->Verify(); // cfg change , invalid results in MeFuncResultMgr diff --git a/src/mapleall/maple_me/src/me_hdse.cpp b/src/mapleall/maple_me/src/me_hdse.cpp index 69de2a716b509eb6585eda6ba2db62aa244d5585..ab1fe9cde7681f38ab0c7b4e7a7d436bc24cfe75 100644 --- a/src/mapleall/maple_me/src/me_hdse.cpp +++ b/src/mapleall/maple_me/src/me_hdse.cpp @@ -169,10 +169,12 @@ void MeDoHDSE::MakeEmptyTrysUnreachable(MeFunction &func) { AnalysisResult *MeDoHDSE::Run(MeFunction *func, MeFuncResultMgr *m, ModuleResultMgr*) { auto *postDom = static_cast(m->GetAnalysisResult(MeFuncPhase_DOMINANCE, func)); CHECK_NULL_FATAL(postDom); + auto *aliasClass = static_cast(m->GetAnalysisResult(MeFuncPhase_ALIASCLASS, func)); + CHECK_NULL_FATAL(aliasClass); auto *hMap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func)); CHECK_NULL_FATAL(hMap); - MeHDSE hdse(*func, *postDom, *hMap, DEBUGFUNC(func)); + MeHDSE hdse(*func, *postDom, *hMap, aliasClass, DEBUGFUNC(func)); hdse.hdseKeepRef = MeOption::dseKeepRef; hdse.DoHDSE(); hdse.BackwardSubstitution(); diff --git a/src/mapleall/maple_me/src/me_ir.cpp b/src/mapleall/maple_me/src/me_ir.cpp index 9c7209b8a03dab3ab8f7c0da3d7c0785e1a98fde..62bca2a909b7a560ce2f1ffda857a7aa0ee13d40 100644 --- a/src/mapleall/maple_me/src/me_ir.cpp +++ b/src/mapleall/maple_me/src/me_ir.cpp @@ -345,7 +345,7 @@ bool IvarMeExpr::IsUseSameSymbol(const MeExpr &expr) const { } auto &ivarMeExpr = static_cast(expr); CHECK_FATAL(base != nullptr, "base is null"); - if (base->IsUseSameSymbol(*ivarMeExpr.base) && fieldID == ivarMeExpr.fieldID) { + if (base->IsUseSameSymbol(*ivarMeExpr.base) && fieldID == ivarMeExpr.fieldID && offset == ivarMeExpr.offset) { return true; } return false; @@ -390,7 +390,8 @@ bool IvarMeExpr::IsRCWeak() const { // (argument expr), then update its mu: expr->mu = this->mu. bool IvarMeExpr::IsIdentical(IvarMeExpr &expr, bool inConstructor) const { CHECK_FATAL(expr.base != nullptr, "null ptr check"); - if (base->GetExprID() != expr.base->GetExprID() || fieldID != expr.fieldID || tyIdx != expr.tyIdx) { + if (base->GetExprID() != expr.base->GetExprID() || fieldID != expr.fieldID || + offset != expr.offset || tyIdx != expr.tyIdx) { return false; } @@ -914,6 +915,9 @@ void IvarMeExpr::Dump(const IRMap *irMap, int32 indent) const { LogInfo::MapleLogger() << "base = "; CHECK_FATAL(base != nullptr, "base is null"); base->Dump(irMap, indent + 1); + if (op == OP_ireadoff) { + LogInfo::MapleLogger() << " (offset)" << offset; + } LogInfo::MapleLogger() << '\n'; PrintIndentation(indent + 1); LogInfo::MapleLogger() << "- MU: {"; diff --git a/src/mapleall/maple_me/src/me_rename2preg.cpp b/src/mapleall/maple_me/src/me_rename2preg.cpp index 5cc0f56ff7c79f6dd22853d769af7c821aa6757c..5523ccca88b8f5ba434db7c94efb81150869f085 100644 --- a/src/mapleall/maple_me/src/me_rename2preg.cpp +++ b/src/mapleall/maple_me/src/me_rename2preg.cpp @@ -26,9 +26,6 @@ namespace maple { RegMeExpr *SSARename2Preg::RenameVar(const VarMeExpr *varmeexpr) { - if (varmeexpr->GetOst()->GetFieldID() != 0) { - return nullptr; - } const OriginalSt *ost = varmeexpr->GetOst(); if (ost->GetIndirectLev() != 0) { return nullptr; @@ -56,22 +53,44 @@ RegMeExpr *SSARename2Preg::RenameVar(const VarMeExpr *varmeexpr) { } return varreg; } else { - const OriginalSt *origOst = ost; - if (origOst->GetIndex() >= aliasclass->GetAliasElemCount()) { + if (ost->GetIndex() >= aliasclass->GetAliasElemCount()) { return nullptr; } - if (!mirst->IsLocal() || mirst->GetStorageClass() == kScPstatic || mirst->GetStorageClass() == kScFstatic) { + // var can be renamed to preg if ost of var: + // 1. not used by MU or defined by CHI; + // 2. aliased-ost of ost is not used anywhere (by MU or dread). + // If defining of aliased-ost defines ost as well. + // There must be a CHI defines ost, and this condition is included in the prev condition. + // Therefore, condition 2 not includes defined-by-CHI. + if (ostDefedByChi[ost->GetIndex()] || ostUsedByMu[ost->GetIndex()]) { return nullptr; } - if (origOst->IsAddressTaken()) { - return nullptr; + + auto *aliasSet = GetAliasSet(ost); + if (aliasSet != nullptr) { + for (auto aeId : *aliasSet) { + auto aliasedOst = aliasclass->FindID2Elem(aeId)->GetOst(); + if (aliasedOst == ost) { + continue; + } + // If an ost aliases with a formal, it is defined at entry by the formal. + // Cannot rename the ost to preg. + if (aliasedOst->IsFormal()) { + return nullptr; + } + bool aliasedOstUsed = ostUsedByMu[aliasedOst->GetIndex()] || ostUsedByDread[aliasedOst->GetIndex()]; + if (aliasedOstUsed && AliasClass::MayAliasBasicAA(ost, aliasedOst)) { + return nullptr; + } + } } - AliasElem *aliaselem = GetAliasElem(origOst); - if (aliaselem && aliaselem->GetClassSet()) { + + if (!mirst->IsLocal() || mirst->GetStorageClass() == kScPstatic || mirst->GetStorageClass() == kScFstatic) { return nullptr; } + RegMeExpr *curtemp = nullptr; - MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(mirst->GetTyIdx()); + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ost->GetTyIdx()); if (ty->GetKind() != kTypeScalar && ty->GetKind() != kTypePointer) { return nullptr; } @@ -305,6 +324,46 @@ void SSARename2Preg::UpdateMirFunctionFormal() { } } +void SSARename2Preg::CollectUsedOst(MeExpr *meExpr) { + if (meExpr->GetMeOp() == kMeOpIvar) { + auto *mu = static_cast(meExpr)->GetMu(); + ostUsedByMu[mu->GetOstIdx()] = true; + } else if (meExpr->GetMeOp() == kMeOpVar) { + auto ostIdx = static_cast(meExpr)->GetOstIdx(); + ostUsedByDread[ostIdx] = true; + } + for (uint32 id = 0; id < meExpr->GetNumOpnds(); ++id) { + CollectUsedOst(meExpr->GetOpnd(id)); + } +} + +void SSARename2Preg::CollectDefUseInfoOfOst() { + for (BB *meBB : func->GetCfg()->GetAllBBs()) { + if (meBB == nullptr) { + continue; + } + for (MeStmt &stmt: meBB->GetMeStmts()) { + for (uint32 id = 0; id < stmt.NumMeStmtOpnds(); ++id) { + CollectUsedOst(stmt.GetOpnd(id)); + } + + auto *muList = stmt.GetMuList(); + if (muList != nullptr) { + for (const auto &mu : *muList) { + ostUsedByMu[mu.first] = true; + } + } + + auto *chiList = stmt.GetChiList(); + if (chiList != nullptr) { + for (const auto &chi : *chiList) { + ostDefedByChi[chi.first] = true; + } + } + } + } +} + void SSARename2Preg::Init() { uint32 formalsize = func->GetMirFunc()->GetFormalDefVec().size(); parm_used_vec.resize(formalsize); @@ -314,6 +373,8 @@ void SSARename2Preg::Init() { void SSARename2Preg::RunSelf() { auto cfg = func->GetCfg(); Init(); + CollectDefUseInfoOfOst(); + for (BB *mebb : cfg->GetAllBBs()) { if (mebb == nullptr) { continue; diff --git a/src/mapleall/maple_me/src/me_scalar_analysis.cpp b/src/mapleall/maple_me/src/me_scalar_analysis.cpp index ed9896e5b37ec5b1b25baf7f20b654818bffa884..abd553f218ed27c78040b533d7d6a6c34827bd05 100644 --- a/src/mapleall/maple_me/src/me_scalar_analysis.cpp +++ b/src/mapleall/maple_me/src/me_scalar_analysis.cpp @@ -902,7 +902,9 @@ bool IsLegal(MeStmt &meStmt) { return false; } auto *opMeExpr = static_cast(meCmp); - CHECK_FATAL(opMeExpr->GetNumOpnds() == kNumOpnds, "must be"); + if (opMeExpr->GetNumOpnds() != kNumOpnds) { + return false; + } if (opMeExpr->GetOp() != OP_ge && opMeExpr->GetOp() != OP_le && opMeExpr->GetOp() != OP_lt && opMeExpr->GetOp() != OP_gt && opMeExpr->GetOp() != OP_eq) { diff --git a/src/mapleall/maple_me/src/me_ssa_epre.cpp b/src/mapleall/maple_me/src/me_ssa_epre.cpp index 0335d5a007743e156fb7dd1b9c1205d829c1c171..ef4730c43e93be3ea8dedc6a45cd9b73e0e290b8 100644 --- a/src/mapleall/maple_me/src/me_ssa_epre.cpp +++ b/src/mapleall/maple_me/src/me_ssa_epre.cpp @@ -115,7 +115,8 @@ AnalysisResult *MeDoSSAEPre::Run(MeFunction *func, MeFuncResultMgr *m, ModuleRes placeRC.ApplySSUPre(); } if (ssaPre.strengthReduction) { // for deleting redundant injury repairs - MeHDSE hdse(*func, *dom, *func->GetIRMap(), DEBUGFUNC(func)); + auto aliasClass = static_cast(m->GetAnalysisResult(MeFuncPhase_ALIASCLASS, func)); + MeHDSE hdse(*func, *dom, *func->GetIRMap(), aliasClass, DEBUGFUNC(func)); if (!MeOption::quiet) { LogInfo::MapleLogger() << " == " << PhaseName() << " invokes [ " << hdse.PhaseName() << " ] ==\n"; } diff --git a/src/mapleall/maple_me/src/me_ssa_update.cpp b/src/mapleall/maple_me/src/me_ssa_update.cpp index 35094d66f535366e40016458c147aa1e32ab2e4e..79eec3837c909cc5935a2ab1cd908eb05601f0c0 100644 --- a/src/mapleall/maple_me/src/me_ssa_update.cpp +++ b/src/mapleall/maple_me/src/me_ssa_update.cpp @@ -93,9 +93,8 @@ MeExpr *MeSSAUpdate::RenameExpr(MeExpr &meExpr, bool &changed) { MeExpr *newbase = RenameExpr(*ivarMeExpr.GetBase(), needRehash); if (needRehash) { changed = true; - IvarMeExpr newMeExpr(kInvalidExprID, ivarMeExpr.GetPrimType(), ivarMeExpr.GetTyIdx(), ivarMeExpr.GetFieldID()); + IvarMeExpr newMeExpr(kInvalidExprID, ivarMeExpr); newMeExpr.SetBase(newbase); - newMeExpr.SetMuVal(ivarMeExpr.GetMu()); return irMap.HashMeExpr(newMeExpr); } return &meExpr; diff --git a/src/mapleall/maple_me/src/me_ssu_pre.cpp b/src/mapleall/maple_me/src/me_ssu_pre.cpp index 8b640dfe4a2da99cd81760cf300293cbbbfd5798..fa9388ea4fea01e26949d2ddfbd1f865ebff2cab 100644 --- a/src/mapleall/maple_me/src/me_ssu_pre.cpp +++ b/src/mapleall/maple_me/src/me_ssu_pre.cpp @@ -277,7 +277,23 @@ void MeSSUPre::Rename() { if (!occStack.empty()) { SOcc *topOcc = occStack.top(); if (topOcc->GetOccTy() == kSOccLambda) { - static_cast(topOcc)->SetIsUpsafe(false); + // make sure this lambda is dominated by at least one kill occurrence + for (SOcc *realOcc : workCand->GetRealOccs()) { + if (realOcc->GetOccTy() == kSOccUse || realOcc->GetOccTy() == kSOccPhi) { + continue; + } + CHECK_FATAL(realOcc->GetOccTy() == kSOccReal, "just check"); + if ((preKind == kDecrefPre || preKind == kSecondDecrefPre) && + !static_cast(realOcc)->GetRealFromDef()) { + continue; + } + CHECK_NULL_FATAL(dom); + if (!dom->Dominate(realOcc->GetBB(), topOcc->GetBB())) { + continue; + } + static_cast(topOcc)->SetIsUpsafe(false); + break; + } } } break; diff --git a/src/mapleall/maple_me/src/prop.cpp b/src/mapleall/maple_me/src/prop.cpp index 9f1a6920df883f4dffb422a4b43fa321da4f89d0..9ce58009ea9b9cdef0e073a7aca713b4824e4317 100644 --- a/src/mapleall/maple_me/src/prop.cpp +++ b/src/mapleall/maple_me/src/prop.cpp @@ -520,8 +520,9 @@ void Prop::TraversalMeStmt(MeStmt &meStmt) { auto &ivarStmt = static_cast(meStmt); ivarStmt.SetRHS(&PropMeExpr(utils::ToRef(ivarStmt.GetRHS()), subProped, false)); if (ivarStmt.GetLHSVal()->GetBase()->GetMeOp() != kMeOpVar || config.propagateBase) { - MeExpr *propedExpr = &PropMeExpr(utils::ToRef(ivarStmt.GetLHSVal()->GetBase()), subProped, false); - if (propedExpr->GetOp() == OP_constval) { + auto *baseOfIvar = ivarStmt.GetLHSVal()->GetBase(); + MeExpr *propedExpr = &PropMeExpr(utils::ToRef(baseOfIvar), subProped, false); + if (propedExpr == baseOfIvar || propedExpr->GetOp() == OP_constval) { subProped = false; } else { ivarStmt.GetLHSVal()->SetBase(propedExpr); diff --git a/src/mapleall/maple_me/src/ssa_epre_for_sr.cpp b/src/mapleall/maple_me/src/ssa_epre_for_sr.cpp index e7d0665bbe0bea252ab7c48c3f2aeca448c6cc84..e49de489411b858539393f2c594a42eef74664cd 100644 --- a/src/mapleall/maple_me/src/ssa_epre_for_sr.cpp +++ b/src/mapleall/maple_me/src/ssa_epre_for_sr.cpp @@ -279,7 +279,7 @@ MeExpr* SSAEPre::SRRepairInjuries(MeOccur *useocc, MePhiNode *scalarPhi = (defphiocc->GetRegPhi() ? defphiocc->GetRegPhi() : defphiocc->GetVarPhi()); repairedTemp = scalarPhi->GetLHS(); } - if (useexpr == nullptr) { + if (useexpr == nullptr || repairedTemp == nullptr) { return repairedTemp; } for (int32 i = 0; i < useexpr->GetNumOpnds(); i++) { diff --git a/src/mapleall/maple_me/src/ssa_pre.cpp b/src/mapleall/maple_me/src/ssa_pre.cpp index 855af1e8ce28c3c89d730fe26c3adf7b87514404..8fb85a44b49556b0ddcd80109238620b20afd13c 100644 --- a/src/mapleall/maple_me/src/ssa_pre.cpp +++ b/src/mapleall/maple_me/src/ssa_pre.cpp @@ -1395,7 +1395,8 @@ void SSAPre::BuildWorkListStmt(MeStmt &stmt, uint32 seqStmt, bool isRebuilt, MeE BuildWorkListExpr(*meStmt, static_cast(seqStmt), *thrMeStmt->GetOpnd(), isRebuilt, tempVar, true); break; } - case OP_iassign: { + case OP_iassign: + case OP_iassignoff: { auto *ivarStmt = static_cast(meStmt); BuildWorkListExpr(*meStmt, static_cast(seqStmt), *ivarStmt->GetRHS(), isRebuilt, tempVar, true); BuildWorkListExpr(*meStmt, static_cast(seqStmt), diff --git a/src/mapleall/mpl2mpl/include/simplify.h b/src/mapleall/mpl2mpl/include/simplify.h index 0b88d584f74f611edaddcebe6eedc2e324303b3f..59284336f4e100d38f8675e42df21680699d28e3 100644 --- a/src/mapleall/mpl2mpl/include/simplify.h +++ b/src/mapleall/mpl2mpl/include/simplify.h @@ -41,6 +41,7 @@ class Simplify : public FuncOptimizeImpl { bool IsMathMax(const std::string funcName); bool SimplifyMathMethod(const StmtNode &stmt, BlockNode &block); void SimplifyCallAssigned(const StmtNode &stmt, BlockNode &block); + void SplitAggCopy(StmtNode *stmt, BlockNode *block, MIRFunction *func); }; class DoSimplify : public ModulePhase { public: diff --git a/src/mapleall/mpl2mpl/src/simplify.cpp b/src/mapleall/mpl2mpl/src/simplify.cpp index 4352ccddddc3040371c71a051dc976694d0025cb..08e382ac49e1a0ad9fabf4edfb18dad3c37e4d4e 100644 --- a/src/mapleall/mpl2mpl/src/simplify.cpp +++ b/src/mapleall/mpl2mpl/src/simplify.cpp @@ -93,6 +93,57 @@ void Simplify::SimplifyCallAssigned(const StmtNode &stmt, BlockNode &block) { } } +void Simplify::SplitAggCopy(StmtNode *stmt, BlockNode *block, MIRFunction *func) { + if (stmt->GetOpCode() == OP_dassign && stmt->Opnd(0)->GetOpCode() == OP_dread && + stmt->Opnd(0)->GetPrimType() == PTY_agg) { + auto *dassign = static_cast(stmt); + const auto &lhsStIdx = dassign->GetStIdx(); + auto *dread = static_cast(stmt->Opnd(0)); + const auto &rhsStIdx = dread->GetStIdx(); + + auto lhsSymbol = func->GetLocalOrGlobalSymbol(lhsStIdx); + auto lhsMIRType = lhsSymbol->GetType(); + auto lhsFieldID = dassign->GetFieldID(); + if (lhsFieldID != 0) { + CHECK_FATAL(lhsMIRType->IsStructType(), "only struct has non-zero fieldID"); + lhsMIRType = static_cast(lhsMIRType)->GetFieldType(lhsFieldID); + } + + auto rhsSymbol = func->GetLocalOrGlobalSymbol(rhsStIdx); + auto rhsMIRType = rhsSymbol->GetType(); + auto rhsFieldID = dread->GetFieldID(); + if (rhsFieldID != 0) { + CHECK_FATAL(rhsMIRType->IsStructType(), "only struct has non-zero fieldID"); + rhsMIRType = static_cast(rhsMIRType)->GetFieldType(rhsFieldID); + } + + if (!lhsSymbol->IsLocal() && !rhsSymbol->IsLocal()) { + return; + } + + if (lhsMIRType != rhsMIRType) { + return; + } + + if (lhsMIRType->IsStructType()) { + auto *structType = static_cast(lhsMIRType); + constexpr uint32 upperLimitOfFieldNum = 10; + if (lhsMIRType->NumberOfFieldIDs() > upperLimitOfFieldNum) { + return; + } + auto mirBuiler = func->GetModule()->GetMIRBuilder(); + for (uint id = 1; id <= lhsMIRType->NumberOfFieldIDs(); ++id) { + auto newRHS = mirBuiler->CreateDread(*rhsSymbol, structType->GetFieldType(id)->GetPrimType()); + newRHS->SetFieldID(id + rhsFieldID); + auto newDassign = mirBuiler->CreateStmtDassign(lhsStIdx, lhsFieldID + id, newRHS); + newDassign->SetSrcPos(stmt->GetSrcPos()); + block->InsertBefore(stmt, newDassign); + } + block->RemoveStmt(stmt); + } + } +} + void Simplify::ProcessFunc(MIRFunction *func) { if (func->IsEmpty()) { return; @@ -135,6 +186,10 @@ void Simplify::ProcessFuncStmt(MIRFunction &func, StmtNode *stmt, BlockNode *blo SimplifyCallAssigned(*stmt, *block); break; } + case OP_dassign: { + SplitAggCopy(stmt, block, &func); + break; + } default: { break; } diff --git a/src/mplfe/ast_input/include/ast_expr.h b/src/mplfe/ast_input/include/ast_expr.h index 8dae6b6d3f0f3281f2f30241ba861667ec020764..263a6d8f147e9a8032557152dc21c68975fbd2f2 100644 --- a/src/mplfe/ast_input/include/ast_expr.h +++ b/src/mplfe/ast_input/include/ast_expr.h @@ -586,8 +586,8 @@ class ASTInitListExpr : public ASTExpr { ASTInitListExpr *initList, std::list &stmts) const; void ProcessDesignatedInitUpdater(std::variant, UniqueFEIRExpr> &base, ASTExpr *expr, std::list &stmts) const; - void ProcessStringLiteralInitList(UniqueFEIRExpr addrOfCharArray, MIRArrayType *arrayType, - UniqueFEIRExpr addrofStringLiteral, std::list &stmts) const; + void ProcessStringLiteralInitList(UniqueFEIRExpr addrOfCharArray, UniqueFEIRExpr addrOfStringLiteral, + uint32 stringLength, std::list &stmts) const; MIRConst *GenerateMIRConstForArray() const; MIRConst *GenerateMIRConstForStruct() const; std::vector initExprs; @@ -721,6 +721,10 @@ class ASTStringLiteral : public ASTExpr { length = len; } + size_t GetLength() { + return length; + } + void SetCodeUnits(std::vector &units) { codeUnits = std::move(units); } @@ -783,8 +787,8 @@ class ASTArraySubscriptExpr : public ASTExpr { isVLA = flag; } - void SetVLASizeExprs(std::vector &exprs) { - vlaSizeExprs = exprs; + void SetVLASizeExpr(ASTExpr *expr) { + vlaSizeExpr = expr; } private: @@ -796,7 +800,7 @@ class ASTArraySubscriptExpr : public ASTExpr { MIRType *arrayType = nullptr; ASTExpr *idxExpr = nullptr; bool isVLA = false; - std::vector vlaSizeExprs; + ASTExpr *vlaSizeExpr = nullptr; }; class ASTExprUnaryExprOrTypeTraitExpr : public ASTExpr { @@ -1246,6 +1250,7 @@ class ASTConditionalOperator : public ASTExpr { ASTExpr *condExpr = nullptr; ASTExpr *trueExpr = nullptr; ASTExpr *falseExpr = nullptr; + std::string varName = FEUtils::GetSequentialName("levVar_"); }; class ASTArrayInitLoopExpr : public ASTExpr { diff --git a/src/mplfe/ast_input/include/ast_parser.h b/src/mplfe/ast_input/include/ast_parser.h index fc873f890011e76cdcdb4d2d47928c1900cfaf6e..6f1085414e8e6ad273c70d2214c6319643b45540 100644 --- a/src/mplfe/ast_input/include/ast_parser.h +++ b/src/mplfe/ast_input/include/ast_parser.h @@ -157,6 +157,7 @@ class ASTParser { ASTDecl *GetAstDeclOfDeclRefExpr(MapleAllocator &allocator, const clang::Expr &expr); void SetSourceFileInfo(clang::Decl *decl); uint32 GetSizeFromQualType(const clang::QualType qualType); + ASTExpr *GetTypeSizeFromQualType(MapleAllocator &allocator, const clang::QualType qualType); uint32_t GetAlignOfType(const clang::QualType currQualType, clang::UnaryExprOrTypeTrait exprKind); uint32_t GetAlignOfExpr(const clang::Expr &expr, clang::UnaryExprOrTypeTrait exprKind); ASTExpr *BuildExprToComputeSizeFromVLA(MapleAllocator &allocator, const clang::QualType &qualType); diff --git a/src/mplfe/ast_input/include/ast_stmt.h b/src/mplfe/ast_input/include/ast_stmt.h index ee8f3cb87a3221969f35fa13af643103f30c3188..df563253e151c8389ab699eab8d96699158b05d0 100644 --- a/src/mplfe/ast_input/include/ast_stmt.h +++ b/src/mplfe/ast_input/include/ast_stmt.h @@ -51,6 +51,8 @@ class ASTStmt { return srcFileLineNum; } + void UseCompareAsCondFEExpr(UniqueFEIRExpr &condFEExpr) const; + protected: virtual std::list Emit2FEStmtImpl() const = 0; ASTStmtOp op; diff --git a/src/mplfe/ast_input/lib/ast_interface.cpp b/src/mplfe/ast_input/lib/ast_interface.cpp index 984a2cb8c2fe7f518d029951c16f0afdffbe8608..255dd3096941740b3edaf675bf68994aee85bf97 100644 --- a/src/mplfe/ast_input/lib/ast_interface.cpp +++ b/src/mplfe/ast_input/lib/ast_interface.cpp @@ -328,12 +328,12 @@ void LibAstFile::EmitTypeName(const clang::RecordType &recoType, std::stringstre } nsStack.pop(); } - const char *name = recoDecl->getName().data(); - if (strcmp(name, "") == 0) { + auto nameStr = recoDecl->getName().str(); + if (nameStr.empty()) { uint32_t id = recoType.getDecl()->getLocation().getRawEncoding(); - name = GetOrCreateMappedUnnamedName(id).c_str(); + nameStr = GetOrCreateMappedUnnamedName(id); } - ss << name; + ss << nameStr; } else { uint32_t id = recoType.getDecl()->getLocation().getRawEncoding(); ss << GetOrCreateMappedUnnamedName(id); diff --git a/src/mplfe/ast_input/lib/ast_type.cpp b/src/mplfe/ast_input/lib/ast_type.cpp index 99e54110ee6e398698b0d0ec8aafdedf5cba0223..ff402e7ba76763b55994e9036895cfac6a1dc204 100644 --- a/src/mplfe/ast_input/lib/ast_type.cpp +++ b/src/mplfe/ast_input/lib/ast_type.cpp @@ -38,9 +38,11 @@ PrimType LibAstFile::CvtPrimType(const clang::BuiltinType::Kind kind) const { case clang::BuiltinType::Bool: return PTY_u1; case clang::BuiltinType::Char_U: + return astContext->CharTy->isSignedIntegerType() ? PTY_i8 : PTY_u8; case clang::BuiltinType::UChar: return PTY_u8; case clang::BuiltinType::WChar_U: + return astContext->WCharTy->isSignedIntegerType() ? PTY_i16 : PTY_u16; case clang::BuiltinType::UShort: return PTY_u16; case clang::BuiltinType::UInt: diff --git a/src/mplfe/ast_input/src/ast_expr.cpp b/src/mplfe/ast_input/src/ast_expr.cpp index e24c7278967fb604ef82a22be87d8d37cdbbaf06..a4f450527cfdba966b08774d19eb2211f827e579 100644 --- a/src/mplfe/ast_input/src/ast_expr.cpp +++ b/src/mplfe/ast_input/src/ast_expr.cpp @@ -216,7 +216,15 @@ UniqueFEIRExpr ASTCallExpr::AddRetExpr(std::unique_ptr &callStmt callStmt->SetVar(var->Clone()); } stmts.emplace_back(std::move(callStmt)); - return FEIRBuilder::CreateExprDRead(std::move(dreadVar)); + if (!IsFirstArgRet() && args.size() == 1) { + std::stringstream ss; + ss << varName << ".mcall"; + UniqueFEIRVar mCallVar = FEIRBuilder::CreateVarNameForC(ss.str(), *retType, false, false); + auto stmt = FEIRBuilder::CreateStmtDAssign(mCallVar->Clone(), FEIRBuilder::CreateExprDRead(dreadVar->Clone())); + stmts.emplace_back(std::move(stmt)); + dreadVar = mCallVar->Clone(); + } + return FEIRBuilder::CreateExprDRead(dreadVar->Clone()); } std::unique_ptr ASTCallExpr::GenCallStmt() const { @@ -269,7 +277,9 @@ ASTValue *ASTCastExpr::GetConstantValueImpl() const { } MIRConst *ASTCastExpr::GenerateMIRConstImpl() const { - if (isArrayToPointerDecay && child->GetASTOp() == kASTStringLiteral) { + std::list stmts; + auto feExpr = child->Emit2FEExpr(stmts); + if (isArrayToPointerDecay && feExpr->GetKind() == FEIRNodeKind::kExprAddrof) { return FEManager::GetModule().GetMemPool()->New( GetConstantValue()->val.strIdx, *GlobalTables::GetTypeTable().GetPrimType(PTY_a64)); } else if (isArrayToPointerDecay && child->GetASTOp() == kASTOpRef) { @@ -292,18 +302,22 @@ MIRConst *ASTCastExpr::GenerateMIRConstImpl() const { } MIRConst *ASTCastExpr::GenerateMIRDoubleConst() const { - switch (GetConstantValue()->pty) { - case PTY_f32: { + MIRConst *childConst = child->GenerateMIRConst(); + switch (childConst->GetKind()) { + case kConstFloatConst: { return FEManager::GetModule().GetMemPool()->New( - static_cast(GetConstantValue()->val.f32), *GlobalTables::GetTypeTable().GetPrimType(PTY_f64)); + static_cast(static_cast(childConst)->GetValue()), + *GlobalTables::GetTypeTable().GetPrimType(PTY_f64)); } - case PTY_i64: { + case kConstInt: { return FEManager::GetModule().GetMemPool()->New( - static_cast(GetConstantValue()->val.i64), *GlobalTables::GetTypeTable().GetPrimType(PTY_f64)); + static_cast(static_cast(childConst)->GetValue()), + *GlobalTables::GetTypeTable().GetPrimType(PTY_f64)); } - case PTY_f64: { + case kConstDoubleConst: { return FEManager::GetModule().GetMemPool()->New( - static_cast(GetConstantValue()->val.f64), *GlobalTables::GetTypeTable().GetPrimType(PTY_f64)); + static_cast(static_cast(childConst)->GetValue()), + *GlobalTables::GetTypeTable().GetPrimType(PTY_f64)); } default: { CHECK_FATAL(false, "Unsupported pty type: %d", GetConstantValue()->pty); @@ -313,14 +327,17 @@ MIRConst *ASTCastExpr::GenerateMIRDoubleConst() const { } MIRConst *ASTCastExpr::GenerateMIRFloatConst() const { - switch (GetConstantValue()->pty) { - case PTY_f64: { + MIRConst *childConst = child->GenerateMIRConst(); + switch (childConst->GetKind()) { + case kConstDoubleConst: { return FEManager::GetModule().GetMemPool()->New( - static_cast(GetConstantValue()->val.f64), *GlobalTables::GetTypeTable().GetPrimType(PTY_f32)); + static_cast(static_cast(childConst)->GetValue()), + *GlobalTables::GetTypeTable().GetPrimType(PTY_f32)); } - case PTY_i64: { + case kConstInt: { return FEManager::GetModule().GetMemPool()->New( - static_cast(GetConstantValue()->val.i64), *GlobalTables::GetTypeTable().GetPrimType(PTY_f32)); + static_cast(static_cast(childConst)->GetValue()), + *GlobalTables::GetTypeTable().GetPrimType(PTY_f32)); } default: { CHECK_FATAL(false, "Unsupported pty type: %d", GetConstantValue()->pty); @@ -330,26 +347,28 @@ MIRConst *ASTCastExpr::GenerateMIRFloatConst() const { } MIRConst *ASTCastExpr::GenerateMIRIntConst() const { - switch (GetConstantValue()->pty) { - case PTY_f64: { + MIRConst *childConst = child->GenerateMIRConst(); + switch (childConst->GetKind()) { + case kConstDoubleConst: { return FEManager::GetModule().GetMemPool()->New( - static_cast(GetConstantValue()->val.f64), *GlobalTables::GetTypeTable().GetPrimType(PTY_i64)); + static_cast(static_cast(childConst)->GetValue()), + *GlobalTables::GetTypeTable().GetPrimType(PTY_i64)); } - case PTY_i64: { + case kConstInt: { PrimType srcPrimType = src->GetPrimType(); - int64 val = GetConstantValue()->val.i64; + int64 val = static_cast(childConst)->GetValue(); switch (srcPrimType) { case PTY_u8: - val = static_cast(GetConstantValue()->val.i64); + val = static_cast(val); break; case PTY_u16: - val = static_cast(GetConstantValue()->val.i64); + val = static_cast(val); break; case PTY_u32: - val = static_cast(GetConstantValue()->val.i64); + val = static_cast(val); break; case PTY_u64: - val = static_cast(GetConstantValue()->val.i64); + val = static_cast(val); break; default: break; @@ -357,9 +376,15 @@ MIRConst *ASTCastExpr::GenerateMIRIntConst() const { return FEManager::GetModule().GetMemPool()->New( val, *GlobalTables::GetTypeTable().GetPrimType(PTY_i64)); } - case PTY_a64: { + case kConstStrConst: { return FEManager::GetModule().GetMemPool()->New( - static_cast(GetConstantValue()->val.strIdx), *GlobalTables::GetTypeTable().GetPrimType(PTY_a64)); + static_cast(static_cast(childConst)->GetValue()), + *GlobalTables::GetTypeTable().GetPrimType(PTY_a64)); + } + case kConstAddrof: { + return FEManager::GetModule().GetMemPool()->New( + static_cast(static_cast(childConst)->GetOffset()), + *GlobalTables::GetTypeTable().GetPrimType(PTY_i64)); } default: { CHECK_FATAL(false, "Unsupported pty type: %d", GetConstantValue()->pty); @@ -944,13 +969,12 @@ void ASTInitListExpr::ProcessInitList(std::variant &stmts) const { +void ASTInitListExpr::ProcessStringLiteralInitList(UniqueFEIRExpr addrOfCharArray, UniqueFEIRExpr addrOfStringLiteral, + uint32 stringLength, std::list &stmts) const { std::unique_ptr> argExprList = std::make_unique>(); argExprList->emplace_back(addrOfCharArray->Clone()); - argExprList->emplace_back(addrofStringLiteral->Clone()); - argExprList->emplace_back(FEIRBuilder::CreateExprConstI32(arrayType->GetSize())); + argExprList->emplace_back(addrOfStringLiteral->Clone()); + argExprList->emplace_back(FEIRBuilder::CreateExprConstI32(stringLength)); std::unique_ptr memcpyStmt = std::make_unique( INTRN_C_memcpy, nullptr, nullptr, std::move(argExprList)); stmts.emplace_back(std::move(memcpyStmt)); @@ -1035,9 +1059,8 @@ void ASTInitListExpr::ProcessStructInitList(std::variantGetKind() == kTypeArray && initList->initExprs[i]->GetASTOp() == kASTStringLiteral) { auto addrOfElement = std::make_unique(baseStructFEPtrType->Clone(), fieldID, std::get(base)->Clone()); - ProcessStringLiteralInitList(addrOfElement->Clone(), static_cast(fieldMirType), - elemExpr->Clone(), - stmts); + ProcessStringLiteralInitList(addrOfElement->Clone(), elemExpr->Clone(), + static_cast(initList->initExprs[i])->GetLength(), stmts); } else { auto stmt = std::make_unique(baseStructFEPtrType->Clone(), std::get(base)->Clone(), @@ -1050,9 +1073,8 @@ void ASTInitListExpr::ProcessStructInitList(std::variantGetKind() == kTypeArray && initList->initExprs[i]->GetASTOp() == kASTStringLiteral) { auto addrOfElement = std::make_unique(var->Clone()); addrOfElement->SetFieldID(fieldID); - ProcessStringLiteralInitList(addrOfElement->Clone(), static_cast(fieldMirType), - elemExpr->Clone(), - stmts); + ProcessStringLiteralInitList(addrOfElement->Clone(), elemExpr->Clone(), + static_cast(initList->initExprs[i])->GetLength(), stmts); } else { auto stmt = std::make_unique(var->Clone(), elemExpr->Clone(), fieldID); stmts.emplace_back(std::move(stmt)); @@ -1091,8 +1113,8 @@ void ASTInitListExpr::ProcessArrayInitList(UniqueFEIRExpr addrOfArray, ASTInitLi } else { UniqueFEIRExpr elemExpr = initList->initExprs[i]->Emit2FEExpr(stmts); if (elementType->GetKind() == kTypeArray && initList->initExprs[i]->GetASTOp() == kASTStringLiteral) { - ProcessStringLiteralInitList(addrOfElemExpr->Clone(), static_cast(elementPtrType), - elemExpr->Clone(), stmts); + ProcessStringLiteralInitList(addrOfElemExpr->Clone(), elemExpr->Clone(), + static_cast(initList->initExprs[i])->GetLength(), stmts); } else { auto stmt = FEIRBuilder::CreateStmtIAssign(elementPtrFEType->Clone(), addrOfElemExpr->Clone(), elemExpr->Clone(), @@ -1197,7 +1219,7 @@ UniqueFEIRExpr ASTArraySubscriptExpr::Emit2FEExprImpl(std::list auto mirPtrType = GlobalTables::GetTypeTable().GetOrCreatePointerType(*mirType); auto fePtrType = std::make_unique(*mirPtrType); UniqueFEIRExpr addrOfArray; - if (arrayType->GetKind() == MIRTypeKind::kTypeArray) { + if (arrayType->GetKind() == MIRTypeKind::kTypeArray && !isVLA) { if(CheckFirstDimIfZero()) { // return multi-dim array addr directly if its first dim size was 0. return baseAddrFEExpr; @@ -1214,7 +1236,7 @@ UniqueFEIRExpr ASTArraySubscriptExpr::Emit2FEExprImpl(std::list auto feIdxExpr = idxExpr->Emit2FEExpr(stmts); UniqueFEIRExpr feSizeExpr; if (isVLA) { - feSizeExpr = vlaSizeExprs[0]->Emit2FEExpr(stmts); + feSizeExpr = vlaSizeExpr->Emit2FEExpr(stmts); } else { feSizeExpr = FEIRBuilder::CreateExprConstU64(mirType->GetSize()); } @@ -1295,7 +1317,6 @@ UniqueFEIRExpr ASTMemberExpr::Emit2FEExprImpl(std::list &stmts) std::string fieldName = memberName; bool isArrow = this->isArrow; MIRType *baseType = this->baseType; - std::string tmpStructName; if (baseExpr->GetASTOp() == kASTMemberExpr) { std::list memberNameList; memberNameList.emplace_back(memberName); @@ -1328,7 +1349,8 @@ UniqueFEIRExpr ASTMemberExpr::Emit2FEExprImpl(std::list &stmts) FieldID fieldID = FEUtils::GetStructFieldID(structType, fieldName); UniqueFEIRType memberFEType = std::make_unique(*memberType); if (baseFEExpr->GetKind() == FEIRNodeKind::kExprIRead) { - static_cast(baseFEExpr.get())->SetFieldID(fieldID); + FieldID baseID = static_cast(baseFEExpr.get())->GetFieldID(); + static_cast(baseFEExpr.get())->SetFieldID(baseID + fieldID); baseFEExpr->SetType(std::move(memberFEType)); return baseFEExpr; } @@ -1338,7 +1360,8 @@ UniqueFEIRExpr ASTMemberExpr::Emit2FEExprImpl(std::list &stmts) addrofExpr->SetFieldID(fieldID); return addrofExpr; } else { - return FEIRBuilder::CreateExprDReadAggField(std::move(tmpVar), fieldID, std::move(memberFEType)); + FieldID baseID = static_cast(baseFEExpr.get())->GetFieldID(); + return FEIRBuilder::CreateExprDReadAggField(std::move(tmpVar), baseID + fieldID, std::move(memberFEType)); } } return nullptr; @@ -1691,13 +1714,6 @@ UniqueFEIRExpr ASTConditionalOperator::Emit2FEExprImpl(std::list UniqueFEIRExpr trueFEIRExpr = trueExpr->Emit2FEExpr(trueStmts); std::list falseStmts; UniqueFEIRExpr falseFEIRExpr = falseExpr->Emit2FEExpr(falseStmts); - // There are no extra nested statements in the expressions, (e.g., a < 1 ? 1 : 2), use ternary FEIRExpr - if (trueStmts.empty() && falseStmts.empty()) { - CHECK_NULL_FATAL(mirType); - UniqueFEIRType type = std::make_unique(*mirType); - return FEIRBuilder::CreateExprTernary(OP_select, std::move(type), std::move(condFEIRExpr), - std::move(trueFEIRExpr), std::move(falseFEIRExpr)); - } // when subExpr is void if (trueFEIRExpr == nullptr || falseFEIRExpr == nullptr) { UniqueFEIRStmt stmtIf = FEIRBuilder::CreateStmtIf(std::move(condFEIRExpr), trueStmts, falseStmts); @@ -1705,10 +1721,9 @@ UniqueFEIRExpr ASTConditionalOperator::Emit2FEExprImpl(std::list return nullptr; } // Otherwise, (e.g., a < 1 ? 1 : a++) create a temporary var to hold the return trueExpr or falseExpr value - CHECK_FATAL(trueFEIRExpr->GetPrimType() == falseFEIRExpr->GetPrimType(), - "The types of trueFEIRExpr and falseFEIRExpr are inconsistent"); + trueFEIRExpr->CheckPrimTypeEq(trueFEIRExpr->GetPrimType(), falseFEIRExpr->GetPrimType()); MIRType *retType = trueFEIRExpr->GetType()->GenerateMIRTypeAuto(); - UniqueFEIRVar tempVar = FEIRBuilder::CreateVarNameForC(FEUtils::GetSequentialName("levVar_"), *retType); + UniqueFEIRVar tempVar = FEIRBuilder::CreateVarNameForC(varName, *retType); UniqueFEIRVar tempVarCloned1 = tempVar->Clone(); UniqueFEIRVar tempVarCloned2 = tempVar->Clone(); UniqueFEIRStmt retTrueStmt = FEIRBuilder::CreateStmtDAssign(std::move(tempVar), std::move(trueFEIRExpr)); diff --git a/src/mplfe/ast_input/src/ast_parser.cpp b/src/mplfe/ast_input/src/ast_parser.cpp index 913075141ae2e616e5c851ec2f011108ef88a7e2..1e331090f387c10e8e030d6631de83ba344d9d86 100644 --- a/src/mplfe/ast_input/src/ast_parser.cpp +++ b/src/mplfe/ast_input/src/ast_parser.cpp @@ -1105,50 +1105,17 @@ ASTExpr *ASTParser::ProcessExprArraySubscriptExpr(MapleAllocator &allocator, con } auto arrayMirType = astFile->CvtType(arrayQualType); astArraySubscriptExpr->SetArrayType(arrayMirType); - std::vector vlaTypeSizeExprs; - if (llvm::isa(arrayQualType) - || (llvm::isa(arrayQualType) && - llvm::cast(arrayQualType)->getPointeeType()->isVariableArrayType())) { - if (llvm::isa(arrayQualType)) { - arrayQualType = llvm::cast(arrayQualType)->getPointeeType(); - auto astSizeExpr = BuildExprToComputeSizeFromVLA(allocator, arrayQualType);; - vlaTypeSizeExprs.emplace_back(astSizeExpr); - } + + clang::QualType exprType = expr.getType().getCanonicalType(); + if (llvm::isa(exprType)) { astArraySubscriptExpr->SetIsVLA(true); - auto elementTypeSizeExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); - elementTypeSizeExpr->SetVal(GetSizeFromQualType(llvm::cast(arrayQualType)->getElementType())); - elementTypeSizeExpr->SetType(PTY_i32); - while (arrayQualType->isArrayType()) { - if (llvm::isa(arrayQualType)) { - auto sizeExpr = llvm::cast(arrayQualType)->getSizeExpr(); - auto astSizeExpr = ProcessExpr(allocator, sizeExpr); - auto astBOExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); - astBOExpr->SetRetType(GlobalTables::GetTypeTable().GetPrimType(PTY_i64)); - astBOExpr->SetOpcode(OP_mul); - astBOExpr->SetLeftExpr(astSizeExpr); - astBOExpr->SetRightExpr(elementTypeSizeExpr); - vlaTypeSizeExprs.emplace_back(astBOExpr); - } else if (llvm::isa(arrayQualType)) { - auto size = llvm::cast(arrayQualType)->getSize().getSExtValue(); - auto astIntegerExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); - astIntegerExpr->SetVal(size); - astIntegerExpr->SetType(PTY_i32); - auto astBOExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); - astBOExpr->SetRetType(GlobalTables::GetTypeTable().GetPrimType(PTY_i64)); - astBOExpr->SetOpcode(OP_mul); - astBOExpr->SetLeftExpr(astIntegerExpr); - astBOExpr->SetRightExpr(elementTypeSizeExpr); - vlaTypeSizeExprs.emplace_back(astBOExpr); - } - vlaTypeSizeExprs.pop_back(); - vlaTypeSizeExprs.push_back(elementTypeSizeExpr); - astArraySubscriptExpr->SetVLASizeExprs(vlaTypeSizeExprs); - arrayQualType = llvm::cast(arrayQualType)->getElementType(); - } + ASTExpr *vlaTypeSizeExpr = GetTypeSizeFromQualType(allocator, exprType); + + astArraySubscriptExpr->SetVLASizeExpr(vlaTypeSizeExpr); } ASTExpr *astBaseExpr = ProcessExpr(allocator, base); astArraySubscriptExpr->SetBaseExpr(astBaseExpr); - auto *mirType = astFile->CvtType(expr.getType().getCanonicalType()); + auto *mirType = astFile->CvtType(exprType); astArraySubscriptExpr->SetType(mirType); return astArraySubscriptExpr; } @@ -1158,6 +1125,26 @@ uint32 ASTParser::GetSizeFromQualType(const clang::QualType qualType) { return astFile->GetContext()->getTypeSizeInChars(desugaredType).getQuantity(); } +ASTExpr *ASTParser::GetTypeSizeFromQualType(MapleAllocator &allocator, const clang::QualType qualType) { + const clang::QualType desugaredType = qualType.getDesugaredType(*astFile->GetContext()); + if (llvm::isa(desugaredType)) { + ASTExpr *vlaSizeExpr = ProcessExpr(allocator, llvm::cast(desugaredType)->getSizeExpr()); + ASTExpr *vlaElemTypeSizeExpr = + GetTypeSizeFromQualType(allocator, llvm::cast(desugaredType)->getElementType()); + ASTBinaryOperatorExpr *sizeExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); + sizeExpr->SetRetType(GlobalTables::GetTypeTable().GetPrimType(PTY_i64)); + sizeExpr->SetOpcode(OP_mul); + sizeExpr->SetLeftExpr(vlaSizeExpr); + sizeExpr->SetRightExpr(vlaElemTypeSizeExpr); + return sizeExpr; + } else { + ASTIntegerLiteral *sizeExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); + sizeExpr->SetVal(astFile->GetContext()->getTypeSizeInChars(desugaredType).getQuantity()); + sizeExpr->SetType(PTY_i32); + return sizeExpr; + } +} + uint32_t ASTParser::GetAlignOfType(const clang::QualType currQualType, clang::UnaryExprOrTypeTrait exprKind) { clang::QualType qualType = currQualType; clang::CharUnits alignInCharUnits = clang::CharUnits::Zero(); @@ -1722,10 +1709,17 @@ ASTExpr *ASTParser::ProcessExprBinaryOperator(MapleAllocator &allocator, const c } // ptr +/- if (boType->isPointerType() && clang::BinaryOperator::isAdditiveOp(clangOpCode) && lhsType->isPointerType() && - rhsType->isIntegerType() && !boType->isVoidPointerType()) { + rhsType->isIntegerType() && !boType->isVoidPointerType() && GetSizeFromQualType(boType->getPointeeType()) != 1) { auto ptrSizeExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); ptrSizeExpr->SetType(PTY_i32); - ptrSizeExpr->SetVal(GetSizeFromQualType(boType->getPointeeType())); + auto boMirType = astFile->CvtType(boType); + auto typeSize = GetSizeFromQualType(boType->getPointeeType()); + MIRType *pointedType = GlobalTables::GetTypeTable().GetTypeFromTyIdx( + static_cast(boMirType)->GetPointedTyIdx()); + if (pointedType->GetPrimType() == PTY_f64) { + typeSize = 8; // 8 is f64 byte num, because now f128 also cvt to f64 + } + ptrSizeExpr->SetVal(typeSize); if (lhsType->isPointerType()) { auto rhs = ASTDeclsBuilder::ASTExprBuilder(allocator); rhs->SetLeftExpr(astRExpr); @@ -1741,12 +1735,14 @@ ASTExpr *ASTParser::ProcessExprBinaryOperator(MapleAllocator &allocator, const c lhs->SetRetType(GlobalTables::GetTypeTable().GetPrimType(PTY_i32)); astLExpr = lhs; } + astBinOpExpr->SetCvtNeeded(true); } astBinOpExpr->SetLeftExpr(astLExpr); astBinOpExpr->SetRightExpr(astRExpr); // ptr - ptr if (clangOpCode == clang::BO_Sub && rhsType->isPointerType() && - lhsType->isPointerType() && !rhsType->isVoidPointerType()) { + lhsType->isPointerType() && !rhsType->isVoidPointerType() && + GetSizeFromQualType(rhsType->getPointeeType()) != 1) { auto ptrSizeExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); ptrSizeExpr->SetType(astBinOpExpr->GetRetType()->GetPrimType()); ptrSizeExpr->SetVal(GetSizeFromQualType(rhsType->getPointeeType())); @@ -2269,7 +2265,6 @@ bool ASTParser::RetrieveGlobalVars(MapleAllocator &allocator) { if (val == nullptr) { return false; } - val->SetGlobal(true); astVars.emplace_back(val); } return true; diff --git a/src/mplfe/ast_input/src/ast_stmt.cpp b/src/mplfe/ast_input/src/ast_stmt.cpp index 8131668e459ef0367db9f401ac230589bc860708..b14d7d6daf9293c24b431e0b4b5ddd64be6f2466 100644 --- a/src/mplfe/ast_input/src/ast_stmt.cpp +++ b/src/mplfe/ast_input/src/ast_stmt.cpp @@ -37,6 +37,24 @@ std::list ASTStmtDummy::Emit2FEStmtImpl() const { return stmts; } +void ASTStmt::UseCompareAsCondFEExpr(UniqueFEIRExpr &condFEExpr) const { + if (condFEExpr->GetKind() == kExprBinary) { + if (static_cast(condFEExpr.get())->IsComparative()) { + return; + } + } + if (condFEExpr->GetKind() == kExprConst) { + if (static_cast(condFEExpr.get())->GetValue().u64 != 0) { + condFEExpr = FEIRBuilder::CreateExprConstI32(1); + } else { + condFEExpr = FEIRBuilder::CreateExprConstI32(0); + } + } else { + UniqueFEIRExpr zeroExpr = FEIRBuilder::CreateExprConstAnyScalar(condFEExpr->GetPrimType(), 0); + condFEExpr = FEIRBuilder::CreateExprBinary(OP_ne, std::move(condFEExpr), std::move(zeroExpr)); + } +} + // ---------- ASTCompoundStmt ---------- void ASTCompoundStmt::SetASTStmt(ASTStmt *astStmt) { astStmts.emplace_back(astStmt); @@ -79,6 +97,7 @@ std::list ASTIfStmt::Emit2FEStmtImpl() const { elseStmts = elseStmt->Emit2FEStmt(); } UniqueFEIRExpr condFEExpr = condExpr->Emit2FEExpr(stmts); + UseCompareAsCondFEExpr(condFEExpr); UniqueFEIRStmt ifStmt; ifStmt = FEIRBuilder::CreateStmtIf(std::move(condFEExpr), thenStmts, elseStmts); ifStmt->SetSrcFileInfo(GetSrcFileIdx(), GetSrcFileLineNum()); @@ -122,6 +141,7 @@ std::list ASTForStmt::Emit2FEStmtImpl() const { condFEExpr = condExpr->Emit2FEExpr(condStmts); bodyFEStmts.splice(bodyFEStmts.cend(), condStmts); } + UseCompareAsCondFEExpr(condFEExpr); UniqueFEIRStmt whileStmt = std::make_unique(OP_while, std::move(condFEExpr), std::move(bodyFEStmts)); whileStmt->SetSrcFileInfo(GetSrcFileIdx(), GetSrcFileLineNum()); stmts.emplace_back(std::move(whileStmt)); @@ -146,6 +166,7 @@ std::list ASTWhileStmt::Emit2FEStmtImpl() const { (void)condExpr->Emit2FEExpr(condPreStmts); bodyFEStmts.emplace_back(std::move(labelBodyEndStmt)); bodyFEStmts.splice(bodyFEStmts.end(), condPreStmts); + UseCompareAsCondFEExpr(condFEExpr); auto whileStmt = std::make_unique(OP_while, std::move(condFEExpr), std::move(bodyFEStmts)); whileStmt->SetSrcFileInfo(GetSrcFileIdx(), GetSrcFileLineNum()); stmts.splice(stmts.end(), condStmts); @@ -172,6 +193,7 @@ std::list ASTDoStmt::Emit2FEStmtImpl() const { std::list condStmts; UniqueFEIRExpr condFEExpr = condExpr->Emit2FEExpr(condStmts); bodyFEStmts.splice(bodyFEStmts.end(), condStmts); + UseCompareAsCondFEExpr(condFEExpr); UniqueFEIRStmt whileStmt = std::make_unique(OP_dowhile, std::move(condFEExpr), std::move(bodyFEStmts)); whileStmt->SetSrcFileInfo(GetSrcFileIdx(), GetSrcFileLineNum()); diff --git a/src/mplfe/ast_input/src/ast_struct2fe_helper.cpp b/src/mplfe/ast_input/src/ast_struct2fe_helper.cpp index 630add52e8b0855859caca371cefbecde274b7ae..70eda308dc65bc57493c2b69f41b1ac2a4ce8d9d 100644 --- a/src/mplfe/ast_input/src/ast_struct2fe_helper.cpp +++ b/src/mplfe/ast_input/src/ast_struct2fe_helper.cpp @@ -151,7 +151,9 @@ bool ASTGlobalVar2FEHelper::ProcessDeclImpl(MapleAllocator &allocator) { if (typeAttrs.GetAttr(ATTR_extern)) { mirSymbol->SetStorageClass(MIRStorageClass::kScExtern); typeAttrs.ResetAttr(AttrKind::ATTR_extern); - } else { + } else if (typeAttrs.GetAttr(ATTR_static)) { + mirSymbol->SetStorageClass(MIRStorageClass::kScFstatic); + } else { mirSymbol->SetStorageClass(MIRStorageClass::kScGlobal); } mirSymbol->SetAttrs(typeAttrs); diff --git a/src/mplfe/common/include/fe_utils.h b/src/mplfe/common/include/fe_utils.h index d08d71cc9702e97a425ec2f087b3eaa890fc7473..db43ab81d6515856129dd510418321f4c279b3f5 100644 --- a/src/mplfe/common/include/fe_utils.h +++ b/src/mplfe/common/include/fe_utils.h @@ -41,7 +41,8 @@ class FEUtils { static std::string GetSequentialName0(const std::string &prefix, uint32_t num); static std::string GetSequentialName(const std::string &prefix); static FieldID GetStructFieldID(MIRStructType *base, const std::string &fieldName); - static bool TraverseToNamedField(MIRStructType &structType, GStrIdx nameIdx, FieldID &fieldID); + static bool TraverseToNamedField(MIRStructType &structType, GStrIdx nameIdx, FieldID &fieldID, + bool isTopLevel = true); static MIRType *GetStructFieldType(MIRStructType *type, FieldID feildID); static MIRConst *CreateImplicitConst(MIRType *type); diff --git a/src/mplfe/common/include/fe_utils_ast.h b/src/mplfe/common/include/fe_utils_ast.h index 2487868e2638e8b7b17f19908b91478013ea6d47..ebadb5d20c43b564bdcba5ffb297ab00bcce7921 100644 --- a/src/mplfe/common/include/fe_utils_ast.h +++ b/src/mplfe/common/include/fe_utils_ast.h @@ -48,6 +48,9 @@ std::function OpGenerator(Opcode op, T p0, T p1) { case OP_div: { return [p0, p1]() { return p0 / p1; }; } + case OP_rem: { + return [p0, p1]() { return static_cast(p0) % static_cast(p1); }; + } case OP_shl: { return [p0, p1]() { return static_cast(p0) << static_cast(p1); }; } @@ -58,6 +61,9 @@ std::function OpGenerator(Opcode op, T p0, T p1) { case OP_bior: { return [p0, p1]() { return static_cast(p0) | static_cast(p1); }; } + case OP_band: { + return [p0, p1]() { return static_cast(p0) & static_cast(p1); }; + } case OP_bxor: { return [p0, p1]() { return static_cast(p0) ^ static_cast(p1); }; } diff --git a/src/mplfe/common/include/feir_stmt.h b/src/mplfe/common/include/feir_stmt.h index 09aa6481a9aa85c45fa1222a9a3833de005cf1be..7ac157a50bfa900877d3b39b1911b2536694e02c 100644 --- a/src/mplfe/common/include/feir_stmt.h +++ b/src/mplfe/common/include/feir_stmt.h @@ -334,10 +334,13 @@ class FEIRExpr { } void CheckPrimTypeEq(PrimType type0, PrimType type1) const { - if ((type0 == PTY_u64 && type1 == PTY_ptr) || (type0 == PTY_ptr && type1 == PTY_u64)) { + if (type0 == PTY_ptr || type1 == PTY_ptr) { return; } - CHECK_FATAL(type0 == type1, "primtype of opnds must be the same"); + CHECK_FATAL(type0 == type1 || + GetRegPrimType(type0) == type1 || + type0 == GetRegPrimType(type1), + "primtype of opnds must be the same"); } protected: @@ -1973,7 +1976,7 @@ class FEIRStmtCaseForC : public FEIRStmt { void AddFeirStmt(UniqueFEIRStmt stmt) { subStmts.emplace_back(std::move(stmt)); } - const std::map &GetPesudoLabelMap() const { + const std::map> &GetPesudoLabelMap() const { return pesudoLabelMap; } @@ -1983,7 +1986,8 @@ class FEIRStmtCaseForC : public FEIRStmt { private: int64 lCaseLabel; - std::map pesudoLabelMap = std::map(); + std::map> pesudoLabelMap = + std::map>(); std::list subStmts; }; @@ -2508,6 +2512,7 @@ class FEIRStmtBreak : public FEIRStmt { } std::list GenMIRStmtsImpl(MIRBuilder &mirBuilder) const override; + private: std::string breakLabelName; }; diff --git a/src/mplfe/common/src/fe_utils.cpp b/src/mplfe/common/src/fe_utils.cpp index de47bb46d228f99a77010946e5a142ec606a37a3..b5c55870332225caf3e0708533ab7e1ab8011880 100644 --- a/src/mplfe/common/src/fe_utils.cpp +++ b/src/mplfe/common/src/fe_utils.cpp @@ -195,18 +195,22 @@ std::string FEUtils::GetSequentialName(const std::string &prefix) { return name; } -bool FEUtils::TraverseToNamedField(MIRStructType &structType, GStrIdx nameIdx, FieldID &fieldID) { +bool FEUtils::TraverseToNamedField(MIRStructType &structType, GStrIdx nameIdx, FieldID &fieldID, bool isTopLevel) { for (uint32 fieldIdx = 0; fieldIdx < structType.GetFieldsSize(); ++fieldIdx) { ++fieldID; TyIdx fieldTyIdx = structType.GetFieldsElemt(fieldIdx).second.first; MIRType *fieldType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fieldTyIdx); ASSERT(fieldType != nullptr, "fieldType is null"); - if (structType.GetFieldsElemt(fieldIdx).first == nameIdx) { + if (isTopLevel && structType.GetFieldsElemt(fieldIdx).first == nameIdx) { return true; } - if (fieldType->IsStructType()) { + // The fields of an embedded structure array are assigned fieldIDs + if (fieldType->GetKind() == kTypeArray) { + fieldType = fieldType->EmbeddedStructType(); + } + if (fieldType != nullptr && fieldType->IsStructType()) { auto *subStructType = static_cast(fieldType); - if (TraverseToNamedField(*subStructType, nameIdx, fieldID)) { + if (TraverseToNamedField(*subStructType, nameIdx, fieldID, false)) { return true; } } @@ -238,6 +242,10 @@ MIRType *FEUtils::GetStructFieldType(MIRStructType *type, FieldID fieldID) { MIRConst *FEUtils::CreateImplicitConst(MIRType *type) { switch (type->GetPrimType()) { + case PTY_u1: { + return GlobalTables::GetIntConstTable().GetOrCreateIntConst( + 0, *GlobalTables::GetTypeTable().GetPrimType(PTY_u1)); + } case PTY_u8: { return GlobalTables::GetIntConstTable().GetOrCreateIntConst( 0, *GlobalTables::GetTypeTable().GetPrimType(PTY_u8)); diff --git a/src/mplfe/common/src/feir_builder.cpp b/src/mplfe/common/src/feir_builder.cpp index 27b92a084aa04d9d44970c827b40ff2849d41834..2590dbbb16dbbc797327797ce304dab498e1c9b6 100644 --- a/src/mplfe/common/src/feir_builder.cpp +++ b/src/mplfe/common/src/feir_builder.cpp @@ -209,6 +209,8 @@ UniqueFEIRExpr FEIRBuilder::CreateExprConstAnyScalar(PrimType primType, int64 va case PTY_i16: case PTY_i32: case PTY_i64: + case PTY_ptr: + case PTY_a64: return std::make_unique(val, primType); case PTY_f128: // Not Implemented @@ -623,6 +625,10 @@ UniqueFEIRStmt FEIRBuilder::AssginStmtField(UniqueFEIRExpr addrExpr, UniqueFEIRE auto ireadExpr = static_cast(addrExpr.get()); stmt = CreateStmtIAssign(ireadExpr->GetClonedPtrType(), ireadExpr->GetClonedOpnd(), std::move(srcExpr), baseID + fieldID); + } else if (addrExpr->GetKind() == kExprIAddrof) { + auto iaddrofExpr = static_cast(addrExpr.get()); + stmt = CreateStmtIAssign(iaddrofExpr->GetClonedPtrType(), iaddrofExpr->GetClonedOpnd(), + std::move(srcExpr), baseID + fieldID); } else { CHECK_FATAL(false, "unsupported expr in AssginStmtField"); } diff --git a/src/mplfe/common/src/feir_stmt.cpp b/src/mplfe/common/src/feir_stmt.cpp index 4d8b15f219da3e56a82b4dff4123abd1fca43478..c9e112f89da53ad24ff023e41b392d4f18a3ba83 100644 --- a/src/mplfe/common/src/feir_stmt.cpp +++ b/src/mplfe/common/src/feir_stmt.cpp @@ -1060,7 +1060,7 @@ FEIRStmtCaseForC::FEIRStmtCaseForC(int64 label) void FEIRStmtCaseForC::AddCaseTag2CaseVec(int64 lCaseTag, int64 rCaseTag) { auto pLabel = std::make_unique(lCaseLabel); for (int64 csTag = lCaseTag; csTag <= rCaseTag; ++csTag) { - pesudoLabelMap.insert(std::pair(csTag, pLabel.get())); + pesudoLabelMap.insert(std::pair>(csTag, std::move(pLabel))); } } @@ -1068,7 +1068,7 @@ std::list FEIRStmtCaseForC::GenMIRStmtsImpl(MIRBuilder &mirBuilder) c std::list ans; CaseVector &caseVec = *AstSwitchUtil::Instance().GetTopOfNestedCaseVectors().first; StmtNode *mirLabelStmt = nullptr; - for (auto targetPair : GetPesudoLabelMap()) { + for (auto &targetPair : GetPesudoLabelMap()) { targetPair.second->GenerateLabelIdx(mirBuilder); caseVec.push_back(std::make_pair(targetPair.first, targetPair.second->GetMIRLabelIdx())); } @@ -2229,12 +2229,20 @@ BaseNode *FEIRExprDRead::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { MIRType *type = varSrc->GetType()->GenerateMIRTypeAuto(); MIRSymbol *symbol = varSrc->GenerateMIRSymbol(mirBuilder); ASSERT(type != nullptr, "type is nullptr"); + PrimType regType = GetRegPrimType(type->GetPrimType()); + if (regType != type->GetPrimType()) { + type = GlobalTables::GetTypeTable().GetPrimType(regType); + } AddrofNode *node = mirBuilder.CreateExprDread(*type, *symbol); if (fieldID != 0) { CHECK_FATAL((type->GetKind() == MIRTypeKind::kTypeStruct || type->GetKind() == MIRTypeKind::kTypeUnion), "If fieldID is not 0, then the variable must be a structure"); CHECK_NULL_FATAL(fieldType); MIRType *fieldMIRType = fieldType->GenerateMIRTypeAuto(); + PrimType regType = GetRegPrimType(fieldMIRType->GetPrimType()); + if (regType != fieldMIRType->GetPrimType()) { + fieldMIRType = GlobalTables::GetTypeTable().GetPrimType(regType); + } node = mirBuilder.CreateExprDread(*fieldMIRType, fieldID, *symbol); } return node; @@ -2379,8 +2387,8 @@ std::vector FEIRExprAddrofVar::GetVarUsesImpl() const { // ---------- FEIRExprAddrofFunc ---------- std::unique_ptr FEIRExprAddrofFunc::CloneImpl() const { - CHECK_FATAL(false, "not support clone here"); - return nullptr; + auto expr = std::make_unique(funcAddr); + return expr; } BaseNode *FEIRExprAddrofFunc::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { diff --git a/src/mplfe/common/src/feir_var.cpp b/src/mplfe/common/src/feir_var.cpp index ffc64b1bb8e68117bf80e2d77825cdb31d6fedda..a69ea48a47696771ea768d6694683a996c29bab0 100644 --- a/src/mplfe/common/src/feir_var.cpp +++ b/src/mplfe/common/src/feir_var.cpp @@ -135,7 +135,9 @@ MIRSymbol *FEIRVar::GenerateGlobalMIRSymbolImpl(MIRBuilder &builder) const { gSymbol->SetStorageClass(MIRStorageClass::kScExtern); attrs.ResetAttr(AttrKind::ATTR_extern); } else { - gSymbol->SetStorageClass(MIRStorageClass::kScGlobal); + if (gSymbol->GetStorageClass() == MIRStorageClass::kScInvalid) { + gSymbol->SetStorageClass(MIRStorageClass::kScGlobal); + } } return gSymbol; } diff --git a/src/mplfe/test/feir_builder_test.cpp b/src/mplfe/test/feir_builder_test.cpp index ce7ddb9c27ac7de7f097fd1edc35d36229fcf996..5f6dd9937f002bff58e37c7ea4691a4246466b91 100644 --- a/src/mplfe/test/feir_builder_test.cpp +++ b/src/mplfe/test/feir_builder_test.cpp @@ -98,7 +98,7 @@ TEST_F(FEIRBuilderTest, CreateRetypeShort2Float) { ASSERT_EQ(mirStmts.size(), 1); mirStmts.front()->Dump(); std::string dumpStr = GetBufferString(); - std::string pattern = std::string("dassign %Reg0_F 0 (cvt f32 i16 (dread i16 %Reg0_S))"); + std::string pattern = std::string("dassign %Reg0_F 0 (cvt f32 i16 (dread i32 %Reg0_S))"); EXPECT_EQ(dumpStr.find(pattern), 0); RestoreCout(); } @@ -128,7 +128,7 @@ TEST_F(FEIRBuilderTest, CreateRetypeShort2Ref) { mirStmts.front()->Dump(); std::string dumpStr = GetBufferString(); EXPECT_EQ(dumpStr.find("dassign %Reg0_R"), 0); - EXPECT_EQ(dumpStr.find(" 0 (cvt ref i16 (dread i16 %Reg0_S))", 15) != std::string::npos, true); + EXPECT_EQ(dumpStr.find(" 0 (cvt ref i16 (dread i32 %Reg0_S))", 15) != std::string::npos, true); RestoreCout(); } diff --git a/src/mplfe/test/feir_stmt_test.cpp b/src/mplfe/test/feir_stmt_test.cpp index 3e8116af0b30f857271f4d7aaf9c71864b9f0c68..38dfdd2e2fda9f6d47a3e9eda7284b673ffc3223 100644 --- a/src/mplfe/test/feir_stmt_test.cpp +++ b/src/mplfe/test/feir_stmt_test.cpp @@ -248,7 +248,7 @@ TEST_F(FEIRStmtTest, FEIRExprBinary_lshr) { RedirectCout(); baseNode->Dump(); std::string dumpStr = GetBufferString(); - std::string pattern = std::string("lshr i32 \\(dread i32 %Reg0_I, dread i8 %Reg1_B\\)") + MPLFEUTRegx::Any(); + std::string pattern = std::string("lshr i32 \\(dread i32 %Reg0_I, dread i32 %Reg1_B\\)") + MPLFEUTRegx::Any(); EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); RestoreCout(); } @@ -286,7 +286,7 @@ TEST_F(FEIRStmtTest, FEIRExprTernary_add) { baseNode->Dump(); std::string dumpStr = GetBufferString(); std::string pattern = - std::string("select i32 \\(dread u1 %Reg0_Z, dread i32 %Reg1_I, dread i32 %Reg2_I\\)") + MPLFEUTRegx::Any(); + std::string("select i32 \\(dread u32 %Reg0_Z, dread i32 %Reg1_I, dread i32 %Reg2_I\\)") + MPLFEUTRegx::Any(); EXPECT_EQ(MPLFEUTRegx::Match(dumpStr, pattern), true); RestoreCout(); std::vector varUses = expr2->GetVarUses(); @@ -324,7 +324,7 @@ TEST_F(FEIRStmtTest, FEIRStmtIf) { RedirectCout(); baseNodes.front()->Dump(); std::string pattern = - "if (dread u1 %Reg0_Z) {\n"\ + "if (dread u32 %Reg0_Z) {\n"\ " dassign %Reg0_I 0 (dread i32 %Reg1_I)\n"\ "}\n"\ "else {\n"\ diff --git a/src/mrt/deplibs/libcore-static-binding-jni-qemu.a b/src/mrt/deplibs/libcore-static-binding-jni-qemu.a index 054bcd96a98437ca3c078326bfb0961b5539c7e1..66751d9359b11cc91ad1deb7e72a23c8444c04fe 100644 Binary files a/src/mrt/deplibs/libcore-static-binding-jni-qemu.a and b/src/mrt/deplibs/libcore-static-binding-jni-qemu.a differ