diff --git a/src/mapleall/bin/dex2mpl b/src/mapleall/bin/dex2mpl index 750a4eb19b957d2eb4b59d6e966ec5d0f40e3e41..729738c96818833dc28736dc5c62901bb6e8418b 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 d5ec6ed4ca3076a7d4f69a848d9fbaa33bbf2702..7a2bf855da407b622c3ff660e832dbbd5ee3a1a0 100755 Binary files a/src/mapleall/bin/jbc2mpl and b/src/mapleall/bin/jbc2mpl differ diff --git a/src/mapleall/maple_be/BUILD.gn b/src/mapleall/maple_be/BUILD.gn index 431cb5affe62448a23601f4dc034cdb865acb462..01d287f2a63c09401c30aceea06edde8e2b604bb 100644 --- a/src/mapleall/maple_be/BUILD.gn +++ b/src/mapleall/maple_be/BUILD.gn @@ -26,7 +26,7 @@ include_directories = [ "${MAPLEALL_ROOT}/maple_ipa/include", "${MAPLEALL_ROOT}/maple_phase/include", "${THIRD_PARTY_ROOT}/bounds_checking_function/include", - "${THIRD_PARTY_ROOT}/llvm_modified/include/llvm/BinaryFormat", + "${THIRD_PARTY_ROOT}/dwarf_h/include", "${THIRD_PARTY_ROOT}/bounds_checking_function/include" ] 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 c544a2067f5c658aebb64af5e3888d98e6e4d9f1..3764b9926253c8da81c4759f4c1b09f92a617e05 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -227,7 +227,7 @@ class AArch64CGFunc : public CGFunc { LabelOperand &GetOrCreateLabelOperand(LabelIdx labIdx) override; LabelOperand &GetOrCreateLabelOperand(BB &bb) override; LabelOperand &CreateFuncLabelOperand(const MIRSymbol &func); - uint32 GetAggCopySize(uint32 offset1, uint32 offset2, uint32 alignment); + uint32 GetAggCopySize(uint32 offset1, uint32 offset2, uint32 alignment) const; AArch64ImmOperand &CreateImmOperand(PrimType ptyp, int64 val) override { return CreateImmOperand(val, GetPrimTypeBitSize(ptyp), IsSignedInteger(ptyp)); 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 a8fbf05a2555115518ce103c743916fc5310c969..cb3ae6a6a7ee87986774a5914c3502e50e9d387c 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_operand.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_operand.h @@ -346,6 +346,10 @@ class StImmOperand : public Operand { return offset; } + void SetOffset(int64 newOffset) { + offset = newOffset; + } + int32 GetRelocs() const { return relocs; } 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 cdc2479c570aae6a62c64688d10cd9b1adcc5bc6..5024936740e405f3680c2b7bf7f21d3ae692a1cd 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -1121,23 +1121,23 @@ void AArch64CGFunc::SelectAggDassign(DassignNode &stmt) { for (uint32 i = 0; i < (lhsSize / copySize); i++) { uint32 rhsBaseOffset = i * copySize + rhsOffsetVal; uint32 lhsBaseOffset = i * copySize + lhsOffsetVal; - AArch64MemOperand::AArch64AddressingMode addrMode = rhsIsLo12 ? - AArch64MemOperand::kAddrModeLo12Li : AArch64MemOperand::kAddrModeBOi; + AArch64MemOperand::AArch64AddressingMode addrMode = + rhsIsLo12 ? AArch64MemOperand::kAddrModeLo12Li : AArch64MemOperand::kAddrModeBOi; MIRSymbol *sym = rhsIsLo12 ? rhsSymbol : nullptr; AArch64OfstOperand &rhsOfstOpnd = GetOrCreateOfstOpnd(rhsBaseOffset, k32BitSize); - MemOperand *rhsMemOpnd; - rhsMemOpnd = &GetOrCreateMemOpnd(addrMode, copySize * k8BitSize, rhsBaseReg, nullptr, &rhsOfstOpnd, sym); + /* generate the load */ + MemOperand *rhsMemOpnd = + &GetOrCreateMemOpnd(addrMode, copySize * k8BitSize, rhsBaseReg, nullptr, &rhsOfstOpnd, sym); rhsMemOpnd = FixLargeMemOpnd(*rhsMemOpnd, copySize); /* generate the load */ RegOperand &result = CreateVirtualRegisterOperand(NewVReg(kRegTyInt, std::max(4u, copySize))); - bool doPair = (!rhsIsLo12 && !lhsIsLo12 && (copySize >= 4) && ((i + 1) < (lhsSize / copySize)) && - !AArch64MemOperand::IsSIMMOffsetOutOfRange(rhsBaseOffset, (copySize == 8), true) && - !AArch64MemOperand::IsSIMMOffsetOutOfRange(lhsBaseOffset, (copySize == 8), true)); + MOperator mOpLDP = (copySize == k4BitSize) ? MOP_wldp : MOP_xldp; + bool doPair = (!rhsIsLo12 && !lhsIsLo12 && (copySize >= k4BitSize) && ((i + 1) < (lhsSize / copySize)) && + IsOperandImmValid(mOpLDP, rhsMemOpnd, kInsnThirdOpnd)); RegOperand *result1 = nullptr; if (doPair) { result1 = &CreateVirtualRegisterOperand(NewVReg(kRegTyInt, std::max(4u, copySize))); - MOperator mOp = (copySize == 4) ? MOP_wldp : MOP_xldp; - GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOp, result, *result1, *rhsMemOpnd)); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOpLDP, result, *result1, *rhsMemOpnd)); } else { MOperator mOp = PickLdInsn(copySize * k8BitSize, PTY_u32); GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOp, result, *rhsMemOpnd)); @@ -1146,12 +1146,12 @@ void AArch64CGFunc::SelectAggDassign(DassignNode &stmt) { AArch64OfstOperand &lhsOfstOpnd = GetOrCreateOfstOpnd(lhsBaseOffset, k32BitSize); addrMode = lhsIsLo12 ? AArch64MemOperand::kAddrModeLo12Li : AArch64MemOperand::kAddrModeBOi; sym = lhsIsLo12 ? lhsSymbol : nullptr; - MemOperand *lhsMemOpnd; - lhsMemOpnd = &GetOrCreateMemOpnd(addrMode, copySize * k8BitSize, lhsBaseReg, nullptr, &lhsOfstOpnd, sym); + MemOperand *lhsMemOpnd = + &GetOrCreateMemOpnd(addrMode, copySize * k8BitSize, lhsBaseReg, nullptr, &lhsOfstOpnd, sym); lhsMemOpnd = FixLargeMemOpnd(*lhsMemOpnd, copySize); - if (doPair) { - MOperator mOp = (copySize == 4) ? MOP_wstp : MOP_xstp; - GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOp, result, *result1, *lhsMemOpnd)); + MOperator mOpSTP = (copySize == k4BitSize) ? MOP_wstp : MOP_xstp; + if (doPair && IsOperandImmValid(mOpSTP, lhsMemOpnd, kInsnThirdOpnd)) { + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOpSTP, result, *result1, *lhsMemOpnd)); i++; } else { MOperator mOp = PickStInsn(copySize * k8BitSize, PTY_u32); @@ -1169,8 +1169,8 @@ void AArch64CGFunc::SelectAggDassign(DassignNode &stmt) { } /* generate the load */ MemOperand *rhsMemOpnd; - AArch64MemOperand::AArch64AddressingMode addrMode = rhsIsLo12 ? - AArch64MemOperand::kAddrModeLo12Li : AArch64MemOperand::kAddrModeBOi; + AArch64MemOperand::AArch64AddressingMode addrMode = + rhsIsLo12 ? AArch64MemOperand::kAddrModeLo12Li : AArch64MemOperand::kAddrModeBOi; MIRSymbol *sym = rhsIsLo12 ? rhsSymbol : nullptr; AArch64OfstOperand &rhsOfstOpnd = GetOrCreateOfstOpnd(lhsSizeCovered + rhsOffsetVal, k32BitSize); rhsMemOpnd = &GetOrCreateMemOpnd(addrMode, newAlignUsed * k8BitSize, rhsBaseReg, nullptr, &rhsOfstOpnd, sym); @@ -1221,20 +1221,19 @@ void AArch64CGFunc::SelectAggDassign(DassignNode &stmt) { /* generate the load */ AArch64OfstOperand &ofstOpnd = GetOrCreateOfstOpnd(rhsBaseOffset, k32BitSize); MemOperand *rhsMemOpnd = &GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, copySize * k8BitSize, - addrOpnd, nullptr, &ofstOpnd, nullptr); + addrOpnd, nullptr, &ofstOpnd, nullptr); rhsMemOpnd = FixLargeMemOpnd(*rhsMemOpnd, copySize); regno_t vRegNO = NewVReg(kRegTyInt, std::max(4u, copySize)); RegOperand &result = CreateVirtualRegisterOperand(vRegNO); - bool doPair = (!lhsIsLo12 && copySize >=4) && ((i + 1) < (lhsSize / copySize)) && - !AArch64MemOperand::IsSIMMOffsetOutOfRange(rhsBaseOffset, (copySize == 8), true) && - !AArch64MemOperand::IsSIMMOffsetOutOfRange(lhsBaseOffset, (copySize == 8), true); - Insn *insn; + MOperator mOpLDP = (copySize == k4BitSize) ? MOP_wldp : MOP_xldp; + bool doPair = (!lhsIsLo12 && copySize >= k4BitSize) && ((i + 1) < (lhsSize / copySize)) && + IsOperandImmValid(mOpLDP, rhsMemOpnd, kInsnThirdOpnd); + Insn *insn = nullptr; RegOperand *result1 = nullptr; if (doPair) { regno_t vRegNO1 = NewVReg(kRegTyInt, std::max(4u, copySize)); result1 = &CreateVirtualRegisterOperand(vRegNO1); - MOperator mOp = (copySize == 4) ? MOP_wldp : MOP_xldp; - insn = &GetCG()->BuildInstruction(mOp, result, *result1, *rhsMemOpnd); + insn = &GetCG()->BuildInstruction(mOpLDP, result, *result1, *rhsMemOpnd); } else { MOperator mOp = PickLdInsn(copySize * k8BitSize, PTY_u32); insn = &GetCG()->BuildInstruction(mOp, result, *rhsMemOpnd); @@ -1242,23 +1241,23 @@ void AArch64CGFunc::SelectAggDassign(DassignNode &stmt) { insn->MarkAsAccessRefField(isRefField); GetCurBB()->AppendInsn(*insn); /* generate the store */ - AArch64MemOperand::AArch64AddressingMode addrMode = lhsIsLo12 ? - AArch64MemOperand::kAddrModeLo12Li : AArch64MemOperand::kAddrModeBOi; + AArch64MemOperand::AArch64AddressingMode addrMode = + lhsIsLo12 ? AArch64MemOperand::kAddrModeLo12Li : AArch64MemOperand::kAddrModeBOi; MIRSymbol *sym = lhsIsLo12 ? lhsSymbol : nullptr; AArch64OfstOperand &lhsOfstOpnd = GetOrCreateOfstOpnd(lhsBaseOffset, k32BitSize); - MemOperand *lhsMemOpnd; - lhsMemOpnd = &GetOrCreateMemOpnd(addrMode, copySize * k8BitSize, lhsBaseReg, nullptr, &lhsOfstOpnd, sym); + MemOperand *lhsMemOpnd = + &GetOrCreateMemOpnd(addrMode, copySize * k8BitSize, lhsBaseReg, nullptr, &lhsOfstOpnd, sym); lhsMemOpnd = FixLargeMemOpnd(*lhsMemOpnd, copySize); - if (doPair) { - MOperator mOp = (copySize == 4) ? MOP_wstp : MOP_xstp; - GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOp, result, *result1, *lhsMemOpnd)); + MOperator mOpSTP = (copySize == k4BitSize) ? MOP_wstp : MOP_xstp; + if (doPair && IsOperandImmValid(mOpSTP, lhsMemOpnd, kInsnThirdOpnd)) { + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOpSTP, result, *result1, *lhsMemOpnd)); i++; } else { MOperator mOp = PickStInsn(copySize * k8BitSize, PTY_u32); GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOp, result, *lhsMemOpnd)); } } - /* take care of extra content at the end less than the unit */ + /* take care of extra content at the end less than the unit of alignUsed */ uint64 lhsSizeCovered = (lhsSize / copySize) * copySize; uint32 newAlignUsed = copySize; while (lhsSizeCovered < lhsSize) { @@ -1270,7 +1269,7 @@ void AArch64CGFunc::SelectAggDassign(DassignNode &stmt) { /* generate the load */ AArch64OfstOperand &ofstOpnd = GetOrCreateOfstOpnd(rhsOffset + lhsSizeCovered, k32BitSize); MemOperand *rhsMemOpnd = &GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, newAlignUsed * k8BitSize, - addrOpnd, nullptr, &ofstOpnd, nullptr); + addrOpnd, nullptr, &ofstOpnd, nullptr); rhsMemOpnd = FixLargeMemOpnd(*rhsMemOpnd, newAlignUsed); RegOperand &result = CreateVirtualRegisterOperand(NewVReg(kRegTyInt, std::max(4u, newAlignUsed))); MOperator mOp = PickLdInsn(newAlignUsed * k8BitSize, PTY_u32); @@ -1278,8 +1277,8 @@ void AArch64CGFunc::SelectAggDassign(DassignNode &stmt) { insn.MarkAsAccessRefField(isRefField); GetCurBB()->AppendInsn(insn); /* generate the store */ - AArch64MemOperand::AArch64AddressingMode addrMode = lhsIsLo12 ? - AArch64MemOperand::kAddrModeLo12Li : AArch64MemOperand::kAddrModeBOi; + AArch64MemOperand::AArch64AddressingMode addrMode = + lhsIsLo12 ? AArch64MemOperand::kAddrModeLo12Li : AArch64MemOperand::kAddrModeBOi; MIRSymbol *sym = lhsIsLo12 ? lhsSymbol : nullptr; AArch64OfstOperand &lhsOfstOpnd = GetOrCreateOfstOpnd(lhsSizeCovered + lhsOffsetVal, k32BitSize); MemOperand *lhsMemOpnd; @@ -1564,23 +1563,23 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { for (uint32 i = 0; i < (lhsSize / copySize); ++i) { uint32 rhsBaseOffset = rhsOffsetVal + i * copySize; uint32 lhsBaseOffset = lhsOffset + i * copySize; - AArch64MemOperand::AArch64AddressingMode addrMode = rhsIsLo12 ? - AArch64MemOperand::kAddrModeLo12Li : AArch64MemOperand::kAddrModeBOi; + AArch64MemOperand::AArch64AddressingMode addrMode = + rhsIsLo12 ? AArch64MemOperand::kAddrModeLo12Li : AArch64MemOperand::kAddrModeBOi; MIRSymbol *sym = rhsIsLo12 ? rhsSymbol : nullptr; AArch64OfstOperand &rhsOfstOpnd = GetOrCreateOfstOpnd(rhsBaseOffset, k32BitSize); - MemOperand *rhsMemOpnd; - rhsMemOpnd = &GetOrCreateMemOpnd(addrMode, copySize * k8BitSize, rhsBaseReg, nullptr, &rhsOfstOpnd, sym); + MemOperand *rhsMemOpnd = + &GetOrCreateMemOpnd(addrMode, copySize * k8BitSize, rhsBaseReg, nullptr, &rhsOfstOpnd, sym); rhsMemOpnd = FixLargeMemOpnd(*rhsMemOpnd, copySize); /* generate the load */ RegOperand &result = CreateVirtualRegisterOperand(NewVReg(kRegTyInt, std::max(4u, copySize))); - bool doPair = (!rhsIsLo12 && (copySize >= 4) && ((i + 1) < (lhsSize / copySize)) && - !AArch64MemOperand::IsSIMMOffsetOutOfRange(rhsBaseOffset, (copySize == 8), true)); + MOperator mOpLDP = (copySize == k4BitSize) ? MOP_wldp : MOP_xldp; + bool isInRange = IsOperandImmValid(mOpLDP, rhsMemOpnd, kInsnThirdOpnd); + bool doPair = (!rhsIsLo12 && (copySize >= k4BitSize) && ((i + 1) < (lhsSize / copySize)) && isInRange); RegOperand *result1 = nullptr; if (doPair) { regno_t vRegNO1 = NewVReg(kRegTyInt, std::max(4u, copySize)); result1 = &CreateVirtualRegisterOperand(vRegNO1); - MOperator mOp = (copySize == 4) ? MOP_wldp : MOP_xldp; - GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOp, result, *result1, *rhsMemOpnd)); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOpLDP, result, *result1, *rhsMemOpnd)); } else { MOperator mOp = PickLdInsn(copySize * k8BitSize, PTY_u32); GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOp, result, *rhsMemOpnd)); @@ -1590,8 +1589,8 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { Operand *lhsMemOpnd = &GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, copySize * k8BitSize, static_cast(&lhsAddrOpnd), nullptr, &ofstOpnd, nullptr); if (doPair) { - MOperator mOp = (copySize == 4) ? MOP_wstp : MOP_xstp; - GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOp, result, *result1, *lhsMemOpnd)); + MOperator mOpSTP = (copySize == k4BitSize) ? MOP_wstp : MOP_xstp; + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOpSTP, result, *result1, *lhsMemOpnd)); i++; } else { MOperator mOp = PickStInsn(copySize * k8BitSize, PTY_u32); @@ -1607,12 +1606,12 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { if ((lhsSizeCovered + newAlignUsed) > lhsSize) { continue; } - AArch64MemOperand::AArch64AddressingMode addrMode = rhsIsLo12 ? - AArch64MemOperand::kAddrModeLo12Li : AArch64MemOperand::kAddrModeBOi; + AArch64MemOperand::AArch64AddressingMode addrMode = + rhsIsLo12 ? AArch64MemOperand::kAddrModeLo12Li : AArch64MemOperand::kAddrModeBOi; MIRSymbol *sym = rhsIsLo12 ? rhsSymbol : nullptr; AArch64OfstOperand &rhsOfstOpnd = GetOrCreateOfstOpnd(lhsSizeCovered + rhsOffsetVal, k32BitSize); - MemOperand *rhsMemOpnd; - rhsMemOpnd = &GetOrCreateMemOpnd(addrMode, newAlignUsed * k8BitSize, rhsBaseReg, nullptr, &rhsOfstOpnd, sym); + MemOperand *rhsMemOpnd = + &GetOrCreateMemOpnd(addrMode, newAlignUsed * k8BitSize, rhsBaseReg, nullptr, &rhsOfstOpnd, sym); rhsMemOpnd = FixLargeMemOpnd(*rhsMemOpnd, newAlignUsed); /* generate the load */ Operand &result = CreateVirtualRegisterOperand(NewVReg(kRegTyInt, std::max(4u, newAlignUsed))); @@ -1623,8 +1622,7 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { Operand &lhsMemOpnd = GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, newAlignUsed * k8BitSize, static_cast(&lhsAddrOpnd), nullptr, &ofstOpnd, static_cast(nullptr)); mOp = PickStInsn(newAlignUsed * k8BitSize, PTY_u32); - GetCurBB()->AppendInsn( - GetCG()->BuildInstruction(mOp, result, lhsMemOpnd)); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOp, result, lhsMemOpnd)); lhsSizeCovered += newAlignUsed; } } else { /* rhs is iread */ @@ -1682,20 +1680,21 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { for (uint32 i = 0; i < (lhsSize / copySize); i++) { /* generate the load */ uint32 operandSize = copySize * k8BitSize; + MOperator mOpLDP = (copySize == k4BitSize) ? MOP_wldp : MOP_xldp; AArch64OfstOperand &rhsOfstOpnd = GetOrCreateOfstOpnd(rhsOffset + i * copySize, k32BitSize); Operand *rhsMemOpnd = &GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, operandSize, static_cast(rhsAddrOpnd), nullptr, &rhsOfstOpnd, nullptr); - if (IsImmediateOffsetOutOfRange(*static_cast(rhsMemOpnd), operandSize)) { + 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 >= 4) && ((i + 1) < (lhsSize / copySize))); - Insn *insn; + bool doPair = ((copySize >= k4BitSize) && ((i + 1) < (lhsSize / copySize)) && isInRange); + Insn *insn = nullptr; RegOperand *result1 = nullptr; if (doPair) { result1 = &CreateVirtualRegisterOperand(NewVReg(kRegTyInt, std::max(4u, copySize))); - MOperator mOp = (copySize == 4) ? MOP_wldp : MOP_xldp; - insn = &GetCG()->BuildInstruction(mOp, result, *result1, *rhsMemOpnd); + insn = &GetCG()->BuildInstruction(mOpLDP, result, *result1, *rhsMemOpnd); } else { MOperator mOp = PickLdInsn(operandSize, PTY_u32); insn = &GetCG()->BuildInstruction(mOp, result, *rhsMemOpnd); @@ -1703,15 +1702,16 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { insn->MarkAsAccessRefField(isRefField); GetCurBB()->AppendInsn(*insn); /* generate the store */ + MOperator mOpSTP = (copySize == k4BitSize) ? MOP_wstp : MOP_xstp; AArch64OfstOperand &lhsOfstOpnd = GetOrCreateOfstOpnd(lhsOffset + i * copySize, k32BitSize); Operand *lhsMemOpnd = &GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, operandSize, static_cast(&lhsAddrOpnd), nullptr, &lhsOfstOpnd, nullptr); - if (IsImmediateOffsetOutOfRange(*static_cast(lhsMemOpnd), operandSize)) { + isInRange = IsOperandImmValid(mOpSTP, lhsMemOpnd, kInsnThirdOpnd); + if (!isInRange) { lhsMemOpnd = &SplitOffsetWithAddInstruction(*static_cast(lhsMemOpnd), operandSize); } if (doPair) { - MOperator mOp = (copySize == 4) ? MOP_wstp : MOP_xstp; - GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOp, result, *result1, *lhsMemOpnd)); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOpSTP, result, *result1, *lhsMemOpnd)); i++; } else { MOperator mOp = PickStInsn(operandSize, PTY_u32); @@ -1729,20 +1729,27 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { } /* generate the load */ AArch64OfstOperand &rhsOfstOpnd = GetOrCreateOfstOpnd(rhsOffset + lhsSizeCovered, k32BitSize); - Operand &rhsMemOpnd = GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, newAlignUsed * k8BitSize, + uint64 memOpndSize = newAlignUsed * k8BitSize; + Operand *rhsMemOpnd = &GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, memOpndSize, static_cast(rhsAddrOpnd), nullptr, &rhsOfstOpnd, nullptr); regno_t vRegNO = NewVReg(kRegTyInt, std::max(4u, newAlignUsed)); RegOperand &result = CreateVirtualRegisterOperand(vRegNO); - Insn &insn = - GetCG()->BuildInstruction(PickLdInsn(newAlignUsed * k8BitSize, PTY_u32), result, rhsMemOpnd); + MOperator mOpLD = PickLdInsn(newAlignUsed * k8BitSize, PTY_u32); + if (!IsOperandImmValid(mOpLD, rhsMemOpnd, kInsnSecondOpnd)) { + rhsMemOpnd = &SplitOffsetWithAddInstruction(*static_cast(rhsMemOpnd), memOpndSize); + } + Insn &insn = GetCG()->BuildInstruction(mOpLD, result, *rhsMemOpnd); insn.MarkAsAccessRefField(isRefField); GetCurBB()->AppendInsn(insn); /* generate the store */ AArch64OfstOperand &lhsOfstOpnd = GetOrCreateOfstOpnd(lhsOffset + lhsSizeCovered, k32BitSize); - Operand &lhsMemOpnd = GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, newAlignUsed * k8BitSize, + Operand *lhsMemOpnd = &GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeBOi, memOpndSize, static_cast(&lhsAddrOpnd), nullptr, &lhsOfstOpnd, nullptr); - GetCurBB()->AppendInsn( - GetCG()->BuildInstruction(PickStInsn(newAlignUsed * k8BitSize, PTY_u32), result, lhsMemOpnd)); + MOperator mOpST = PickStInsn(memOpndSize, PTY_u32); + if (!IsOperandImmValid(mOpST, lhsMemOpnd, kInsnSecondOpnd)) { + lhsMemOpnd = &SplitOffsetWithAddInstruction(*static_cast(lhsMemOpnd), memOpndSize); + } + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mOpST, result, *lhsMemOpnd)); lhsSizeCovered += newAlignUsed; } } @@ -6539,7 +6546,7 @@ LabelOperand &AArch64CGFunc::CreateFuncLabelOperand(const MIRSymbol &funcSymbol) return *memPool->New(funcName); } -uint32 AArch64CGFunc::GetAggCopySize(uint32 offset1, uint32 offset2, uint32 alignment) { +uint32 AArch64CGFunc::GetAggCopySize(uint32 offset1, uint32 offset2, uint32 alignment) const { /* Generating a larger sized mem op than alignment if allowed by aggregate starting address */ uint32 offsetAlign1 = (offset1 == 0) ? k8ByteSize : offset1; uint32 offsetAlign2 = (offset2 == 0) ? k8ByteSize : offset2; 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 9c16f9b9319238c89a6cb3854f43031c759c5cb3..36863c1387732890b5af6ec645e45b5794956043 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_global.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_global.cpp @@ -349,7 +349,7 @@ bool BackPropPattern::CheckAndGetOpnd(Insn &insn) { firstRegOpnd = &static_cast(firstOpnd); secondRegOpnd = &static_cast(secondOpnd); - if (firstRegOpnd->IsZeroRegister() || !secondRegOpnd->IsVirtualRegister()) { + if (firstRegOpnd->IsZeroRegister() || !firstRegOpnd->IsVirtualRegister() || !secondRegOpnd->IsVirtualRegister()) { return false; } firstRegNO = firstRegOpnd->GetRegisterNumber(); diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_peep.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_peep.cpp index 81cc38f83e3cd09da1b0915b31693277cd71246c..45590d7dc6f443cb1344c47fbff1eba417d655ea 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_peep.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_peep.cpp @@ -1997,6 +1997,7 @@ void ComplexMemOperandAArch64::Run(BB &bb, Insn &insn) { if (thisMop != MOP_xadrpl12) { return; } + MOperator nextMop = nextInsn->GetMachineOpcode(); if (nextMop && ((nextMop >= MOP_wldrsb && nextMop <= MOP_dldp) || (nextMop >= MOP_wstrb && nextMop <= MOP_dstp))) { @@ -2034,6 +2035,16 @@ void ComplexMemOperandAArch64::Run(BB &bb, Insn &insn) { auto &stImmOpnd = static_cast(insn.GetOperand(kInsnThirdOpnd)); AArch64OfstOperand &offOpnd = aarch64CGFunc->GetOrCreateOfstOpnd( stImmOpnd.GetOffset() + memOpnd->GetOffsetImmediate()->GetOffsetValue(), k32BitSize); + if (cgFunc.GetMirModule().IsCModule()) { + Insn *prevInsn = insn.GetPrev(); + MOperator prevMop = prevInsn->GetMachineOpcode(); + if (prevMop != MOP_xadrp) { + return; + } else { + auto &prevStImmOpnd = static_cast(prevInsn->GetOperand(kInsnSecondOpnd)); + prevStImmOpnd.SetOffset(offOpnd.GetValue()); + } + } auto &newBaseOpnd = static_cast(insn.GetOperand(kInsnSecondOpnd)); AArch64MemOperand &newMemOpnd = aarch64CGFunc->GetOrCreateMemOpnd(AArch64MemOperand::kAddrModeLo12Li, memOpnd->GetSize(), diff --git a/src/mapleall/maple_be/src/cg/cgfunc.cpp b/src/mapleall/maple_be/src/cg/cgfunc.cpp index 33225735844b50855e0ece790e2bddf80ffe8944..3b487ffcbe647dc998c3cc5ef61f4ec752f8c727 100644 --- a/src/mapleall/maple_be/src/cg/cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/cgfunc.cpp @@ -1267,10 +1267,15 @@ void CGFunc::DumpCGIR() const { FOR_ALL_BB_CONST(bb, this) { LogInfo::MapleLogger() << "=== BB " << " <" << bb->GetKindName(); if (bb->GetLabIdx() != MIRLabelTable::GetDummyLabel()) { - LogInfo::MapleLogger() << "[labeled with " << bb->GetLabIdx() << "]"; + LogInfo::MapleLogger() << "[labeled with " << bb->GetLabIdx(); + LogInfo::MapleLogger() << " ==> @" << func.GetLabelName(bb->GetLabIdx()) << "]"; } LogInfo::MapleLogger() << "> <" << bb->GetId() << "> "; + if (bb->GetLoop()) { + LogInfo::MapleLogger() << "[Loop level " << bb->GetLoop()->GetLoopLevel(); + LogInfo::MapleLogger() << ", head BB " << bb->GetLoop()->GetHeader()->GetId() << "]"; + } if (bb->IsCleanup()) { LogInfo::MapleLogger() << "[is_cleanup] "; } diff --git a/src/mapleall/maple_ipa/src/inline.cpp b/src/mapleall/maple_ipa/src/inline.cpp index 6173eee3fa63d30e417f40968c0d26461b4907dc..575a994b07f7610768d89c43fa293f804014274d 100644 --- a/src/mapleall/maple_ipa/src/inline.cpp +++ b/src/mapleall/maple_ipa/src/inline.cpp @@ -640,6 +640,22 @@ void MInline::ConvertPStaticToFStatic(MIRFunction &func) const { bool success = GlobalTables::GetGsymTable().AddToStringSymbolMap(*newSym); CHECK_FATAL(success, "Found repeated global symbols!"); oldStIdx2New[i] = newSym->GetStIdx().FullIdx(); + // If a pstatic symbol `foo` is initialized by address of another pstatic symbol `bar`, we need update the stIdx + // of foo's initial value. Example code: + // static int bar = 42; + // static int *foo = &bar; + if ((newSym->GetSKind() == kStConst || newSym->GetSKind() == kStVar) && newSym->GetKonst() != nullptr && + newSym->GetKonst()->GetKind() == kConstAddrof) { + auto *addrofConst = static_cast(newSym->GetKonst()); + StIdx valueStIdx = addrofConst->GetSymbolIndex(); + if (!valueStIdx.IsGlobal()) { + MIRSymbol *valueSym = func.GetSymbolTabItem(valueStIdx.Idx()); + if (valueSym->GetStorageClass() == kScPstatic) { + valueStIdx.SetFullIdx(oldStIdx2New[valueStIdx.Idx()]); + addrofConst->SetSymbolIndex(valueStIdx); + } + } + } } else { StIdx newStIdx(oldStIdx); newStIdx.SetIdx(oldStIdx.Idx() - pstaticNum); @@ -990,28 +1006,28 @@ FuncCostResultType MInline::GetFuncCost(const MIRFunction &func, const BaseNode case OP_intrinsicopwithtype: { const IntrinsicopNode &node = static_cast(baseNode); switch(node.GetIntrinsic()) { - case INTRN_JAVA_CONST_CLASS: - case INTRN_JAVA_ARRAY_LENGTH: - cost += kOneInsn; - break; - case INTRN_JAVA_MERGE: - cost += kHalfInsn; - break; - case INTRN_JAVA_INSTANCE_OF: - cost += kPentupleInsn; - break; - case INTRN_MPL_READ_OVTABLE_ENTRY: - cost += kDoubleInsn; - break; - case INTRN_C_ctz32: - case INTRN_C_clz32: - case INTRN_C_constant_p: - cost += kOneInsn; - break; - default: - // Other intrinsics generate a call - cost += kPentupleInsn; - break; + case INTRN_JAVA_CONST_CLASS: + case INTRN_JAVA_ARRAY_LENGTH: + cost += kOneInsn; + break; + case INTRN_JAVA_MERGE: + cost += kHalfInsn; + break; + case INTRN_JAVA_INSTANCE_OF: + cost += kPentupleInsn; + break; + case INTRN_MPL_READ_OVTABLE_ENTRY: + cost += kDoubleInsn; + break; + case INTRN_C_ctz32: + case INTRN_C_clz32: + case INTRN_C_constant_p: + cost += kOneInsn; + break; + default: + // Other intrinsics generate a call + cost += kPentupleInsn; + break; } break; } diff --git a/src/mapleall/maple_ir/include/intrinsic_vector.def b/src/mapleall/maple_ir/include/intrinsic_vector.def index 5614883370641d3e048e1985188230adb79288c9..855f19feb1b9b0950f970d394b1883757908ef50 100644 --- a/src/mapleall/maple_ir/include/intrinsic_vector.def +++ b/src/mapleall/maple_ir/include/intrinsic_vector.def @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Futurewei Technologies, Inc. + * Copyright (c) [2021] Futurewei Technologies, Inc. * * OpenArkCompiler is licensed under the Mulan Permissive Software License v2. * You can use this software according to the terms and conditions of the MulanPSL - 2.0. diff --git a/src/mapleall/maple_ir/include/mir_const.h b/src/mapleall/maple_ir/include/mir_const.h index 3f08d5ba65e5afdfc176f4fc3bb88bebcc7f5d01..2d28f355a1097ff706854ebf98e793c1d68ec5c4 100644 --- a/src/mapleall/maple_ir/include/mir_const.h +++ b/src/mapleall/maple_ir/include/mir_const.h @@ -166,6 +166,10 @@ class MIRAddrofConst : public MIRConst { return stIdx; } + void SetSymbolIndex(StIdx idx) { + stIdx = idx; + } + FieldID GetFieldID() const { return fldID; } diff --git a/src/mapleall/maple_ir/include/mir_nodes.h b/src/mapleall/maple_ir/include/mir_nodes.h index b26f0254c64a09f60451c553704bbae02f40e198..30e29785eaa371d76d8f33b2e5d95102e5d4006a 100644 --- a/src/mapleall/maple_ir/include/mir_nodes.h +++ b/src/mapleall/maple_ir/include/mir_nodes.h @@ -184,6 +184,10 @@ class BaseNode : public BaseNodeT { return kOpcodeInfo.IsCondBr(GetOpCode()); } + bool IsConstval() const { + return op == OP_constval; + } + virtual bool Verify() const { return true; } diff --git a/src/mapleall/maple_ir/include/mir_type.h b/src/mapleall/maple_ir/include/mir_type.h index 3a483326efae2db8b59e792c981591c92d8bfd3b..d852a46893a1552d5a1483697f8d32e947f05b38 100644 --- a/src/mapleall/maple_ir/include/mir_type.h +++ b/src/mapleall/maple_ir/include/mir_type.h @@ -414,6 +414,48 @@ class GenericAttrs { #if MIR_FEATURE_FULL constexpr size_t kShiftNumOfTypeKind = 8; constexpr size_t kShiftNumOfNameStrIdx = 6; +constexpr int32 kOffsetUnknown = INT_MAX; +constexpr int32 kOffsetMax = (INT_MAX - 1); +constexpr int32 kOffsetMin = INT_MIN; +struct OffsetType { + explicit OffsetType(int32 offset) : val(offset) {} + ~OffsetType() = default; + + void Set(int64 offsetVal) { + val = (offsetVal >= kOffsetMin && offsetVal <= kOffsetMax) ? static_cast(offsetVal) + : kOffsetUnknown; + } + + bool IsInvalid() const { + return val == kOffsetUnknown; + } + + OffsetType operator+(int64 offset) const { + int64 sum = this->val + offset; + if (sum >= kOffsetMin && sum <= kOffsetMax) { + return OffsetType(static_cast(sum)); + } + return OffsetType(kOffsetUnknown); + } + + OffsetType operator+(OffsetType other) const { + return other + val; + } + + bool operator<(OffsetType other) const { + return val < other.val; + } + + bool operator==(OffsetType other) const { + return val == other.val; + } + + static OffsetType InvalidOffset() { + return OffsetType(kOffsetUnknown); + } + + int32 val = kOffsetUnknown; +}; class MIRStructType; // circular dependency exists, no other choice @@ -704,6 +746,17 @@ class MIRArrayType : public MIRType { return hIdx % kTypeHashLength; } + int64 OffsetInByteFromArrayAddress(std::vector arrayIndex) { + ASSERT(dim == arrayIndex.size(), "number of array index incorrect"); + int64 offset = 0; + uint32 numberOfElemInLowerDim = 1; + for (uint32 id = 1; id <= dim; ++id) { + offset += arrayIndex[dim - id] * numberOfElemInLowerDim; + numberOfElemInLowerDim *= sizeArray[dim - id]; + } + return offset * static_cast(GetElemType()->GetSize()); + } + std::string GetMplTypeName() const override; std::string GetCompactMplTypeName() const override; bool HasFields() const override; @@ -760,6 +813,10 @@ class MIRFarrayType : public MIRType { size_t NumberOfFieldIDs() const override; MIRStructType *EmbeddedStructType() override; + int64 OffsetInByteFromArrayAddress(int64 arrayIndex) { + return arrayIndex * static_cast(GetElemType()->GetSize()); + } + private: TyIdx elemTyIdx; }; diff --git a/src/mapleall/maple_me/include/alias_class.h b/src/mapleall/maple_me/include/alias_class.h index 9c342f6c5d92ca90016d19265c9ab23e576ebc20..5772272a3ae4a611ca2aa2cfa4e9d1f912734d12 100644 --- a/src/mapleall/maple_me/include/alias_class.h +++ b/src/mapleall/maple_me/include/alias_class.h @@ -180,7 +180,7 @@ class AliasClass : public AnalysisResult { bool CallHasSideEffect(StmtNode *stmt) const; bool CallHasNoPrivateDefEffect(StmtNode *stmt) const; AliasElem *FindOrCreateAliasElem(OriginalSt &ost); - AliasElem *FindOrCreateExtraLevAliasElem(BaseNode &expr, TyIdx tyIdx, FieldID fieldId); + AliasElem *FindOrCreateExtraLevAliasElem(BaseNode &expr, const TyIdx &tyIdx, FieldID fieldId); AliasInfo CreateAliasElemsExpr(BaseNode &expr); void SetNotAllDefsSeenForMustDefs(const StmtNode &callas); void SetPtrOpndNextLevNADS(const BaseNode &opnd, AliasElem *aliasElem, bool hasNoPrivateDefEffect); @@ -188,7 +188,7 @@ class AliasClass : public AnalysisResult { bool hasNoPrivateDefEffect); void ApplyUnionForFieldsInAggCopy(const OriginalSt *lhsost, const OriginalSt *rhsost); void ApplyUnionForDassignCopy(AliasElem &lhsAe, AliasElem *rhsAe, BaseNode &rhs); - bool SetNextLevNADSForPtrIntegerCopy(AliasElem &lhsAe, const AliasElem *rhsAe, BaseNode &rhs); + bool SetNextLevNADSForEscapePtr(AliasElem &lhsAe, BaseNode &rhs); void CreateMirroringAliasElems(const OriginalSt *ost1, OriginalSt *ost2); AliasElem *FindOrCreateDummyNADSAe(); AliasElem &FindOrCreateAliasElemOfAddrofOSt(OriginalSt &oSt); diff --git a/src/mapleall/maple_me/include/hdse.h b/src/mapleall/maple_me/include/hdse.h index 3f5a79cbbf0b85a8ff97bbf918b723b1d3216b6a..094aa36ce0033d96c786c2b5a5bfe9671b1d94cf 100644 --- a/src/mapleall/maple_me/include/hdse.h +++ b/src/mapleall/maple_me/include/hdse.h @@ -95,7 +95,10 @@ class HDSE { RemoveNotRequiredStmtsInBB(*bb); } } - + virtual bool IsLfo() { + return false; + } + virtual void ProcessWhileInfos() {} protected: MIRModule &mirModule; MapleVector bbVec; diff --git a/src/mapleall/maple_me/include/lfo_inject_iv.h b/src/mapleall/maple_me/include/lfo_inject_iv.h index d2a5ab7b825b281925cb284d688fd1cf60198e00..c432ef44a310cfd9ac5aaa95d0cd2cfb70f1b598 100644 --- a/src/mapleall/maple_me/include/lfo_inject_iv.h +++ b/src/mapleall/maple_me/include/lfo_inject_iv.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) [2021] Huawei Technologies Co., Ltd. All rights reserved. * * OpenArkCompiler is licensed under the Mulan Permissive Software License v2. * You can use this software according to the terms and conditions of the MulanPSL - 2.0. diff --git a/src/mapleall/maple_me/include/lfo_iv_canon.h b/src/mapleall/maple_me/include/lfo_iv_canon.h index 3775bf9d424f8f0cf4ad4a377b11a4e1e90afa23..e535e66facbc5ead4a2538d4fbcd05716bf5ab2f 100644 --- a/src/mapleall/maple_me/include/lfo_iv_canon.h +++ b/src/mapleall/maple_me/include/lfo_iv_canon.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) [2021] Huawei Technologies Co., Ltd. All rights reserved. * * OpenArkCompiler is licensed under the Mulan Permissive Software License v2. * You can use this software according to the terms and conditions of the MulanPSL - 2.0. @@ -22,7 +22,6 @@ #include "me_phase.h" namespace maple { - // describe characteristics of one IV class IVDesc { public: @@ -33,8 +32,8 @@ class IVDesc { public: explicit IVDesc(OriginalSt *o) : ost(o) { - MIRType *mirtype = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ost->GetTyIdx()); - primType = mirtype->GetPrimType(); + MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ost->GetTyIdx()); + primType = mirType->GetPrimType(); } }; @@ -54,8 +53,8 @@ class IVCanon { MeExpr *tripCount = nullptr; public: - explicit IVCanon(MemPool *m, MeFunction *f, Dominance *dom, LoopDesc *ldesc, uint32 id, LfoWhileInfo *winfo) : - mp(m), alloc(m), func(f), dominance(dom), ssatab(f->GetMeSSATab()), + IVCanon(MemPool *m, MeFunction *f, Dominance *dom, LoopDesc *ldesc, uint32 id, LfoWhileInfo *winfo) + : mp(m), alloc(m), func(f), dominance(dom), ssatab(f->GetMeSSATab()), aloop(ldesc), loopID(id), whileInfo(winfo), ivvec(alloc.Adapter()) {} bool ResolveExprValue(MeExpr *x, ScalarMeExpr *philhs); int32 ComputeIncrAmt(MeExpr *x, ScalarMeExpr *philhs, int32 *appearances); @@ -72,7 +71,7 @@ class IVCanon { class DoLfoIVCanon : public MeFuncPhase { public: - DoLfoIVCanon(MePhaseID id) : MeFuncPhase(id) {} + explicit DoLfoIVCanon(MePhaseID id) : MeFuncPhase(id) {} ~DoLfoIVCanon() {} diff --git a/src/mapleall/maple_me/include/lfo_mir_lower.h b/src/mapleall/maple_me/include/lfo_mir_lower.h index b346edb063092ba78d9f792387469295c99b819c..166eb9d5513f34235e249c3ae8538414cf2ff04c 100644 --- a/src/mapleall/maple_me/include/lfo_mir_lower.h +++ b/src/mapleall/maple_me/include/lfo_mir_lower.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) [2021] Huawei Technologies Co., Ltd. All rights reserved. * * OpenArkCompiler is licensed under the Mulan Permissive Software License v2. * You can use this software according to the terms and conditions of the MulanPSL - 2.0. diff --git a/src/mapleall/maple_me/include/lfo_mir_nodes.h b/src/mapleall/maple_me/include/lfo_mir_nodes.h index 2d497bc3c068e244c393b44228de2994cb2078c4..76cd39ec70c20209d7d99dcbd0f933d2760b4709 100644 --- a/src/mapleall/maple_me/include/lfo_mir_nodes.h +++ b/src/mapleall/maple_me/include/lfo_mir_nodes.h @@ -31,7 +31,7 @@ class LfoParentPart { while (dParent && dParent != this) { dParent = dParent->parent; } - return dParent != NULL; + return dParent != nullptr; } }; diff --git a/src/mapleall/maple_me/include/lfo_pre_emit.h b/src/mapleall/maple_me/include/lfo_pre_emit.h index 2f4fd749199c3faa3881344c7066060c7bef0d1e..5ed8ca4b538305e57b62687f168e2fc2dbff33ac 100644 --- a/src/mapleall/maple_me/include/lfo_pre_emit.h +++ b/src/mapleall/maple_me/include/lfo_pre_emit.h @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) [2021] Huawei Technologies Co., Ltd. All rights reserved. * * OpenArkCompiler is licensed under the Mulan Permissive Software License v2. * You can use this software according to the terms and conditions of the MulanPSL - 2.0. diff --git a/src/mapleall/maple_me/include/me_hdse.h b/src/mapleall/maple_me/include/me_hdse.h index 7b9dab50f7af3987437a98ee6e2f8276a987dd4a..d3ce2a72643e7b668786692f23fcced79a791d61 100644 --- a/src/mapleall/maple_me/include/me_hdse.h +++ b/src/mapleall/maple_me/include/me_hdse.h @@ -27,13 +27,19 @@ class MeHDSE : public HDSE { public: MeHDSE(MeFunction &f, Dominance &pDom, IRMap &map, bool enabledDebug) : HDSE(f.GetMIRModule(), f.GetCfg()->GetAllBBs(), *f.GetCfg()->GetCommonEntryBB(), *f.GetCfg()->GetCommonExitBB(), - pDom, map, enabledDebug, MeOption::decoupleStatic) {} + pDom, map, enabledDebug, MeOption::decoupleStatic), func(f) {} virtual ~MeHDSE() = default; void BackwardSubstitution(); std::string PhaseName() const { return "hdse"; } + private: + bool IsLfo() { + return func.IsLfo(); + } + void ProcessWhileInfos(); + MeFunction &func; }; class MeDoHDSE : public MeFuncPhase { diff --git a/src/mapleall/maple_me/include/occur.h b/src/mapleall/maple_me/include/occur.h index 96f2633637b9ad6ee27648da99c05d4c12f8a24c..c4da174ec6e19ccef83baa14728c767063c2f951 100644 --- a/src/mapleall/maple_me/include/occur.h +++ b/src/mapleall/maple_me/include/occur.h @@ -493,9 +493,8 @@ class MePhiOcc : public MeOccur { // each singly linked list repersents each bucket in workCandHashTable class PreWorkCand { public: - PreWorkCand(MapleAllocator &alloc, int32 idx, MeExpr *meExpr, PUIdx pIdx) + PreWorkCand(MapleAllocator &alloc, MeExpr *meExpr, PUIdx pIdx) : next(nullptr), - index(idx), realOccs(alloc.Adapter()), theMeExpr(meExpr), puIdx(pIdx), @@ -621,7 +620,7 @@ class PreWorkCand { private: void InsertRealOccAt(MeRealOcc &occ, MapleVector::iterator it, PUIdx pIdx); PreWorkCand *next; - int32 index; + int32 index = 0; MapleVector realOccs; // maintained in order of dt_preorder MeExpr *theMeExpr; // the expression of this workcand PUIdx puIdx; // if 0, its occ span multiple PUs; initial value must @@ -637,8 +636,8 @@ class PreWorkCand { class PreStmtWorkCand : public PreWorkCand { public: - PreStmtWorkCand(MapleAllocator &alloc, int32 idx, MeStmt &meStmt, PUIdx pIdx) - : PreWorkCand(alloc, idx, nullptr, pIdx), theMeStmt(&meStmt), lhsIsFinal(false) {} + PreStmtWorkCand(MapleAllocator &alloc, MeStmt &meStmt, PUIdx pIdx) + : PreWorkCand(alloc, nullptr, pIdx), theMeStmt(&meStmt), lhsIsFinal(false) {} virtual ~PreStmtWorkCand() = default; diff --git a/src/mapleall/maple_me/include/orig_symbol.h b/src/mapleall/maple_me/include/orig_symbol.h index 2e48b267859140a3a79210982ef9970367130ef7..bc8e44be3564c076db23757fb5c7e8fc3582e468 100644 --- a/src/mapleall/maple_me/include/orig_symbol.h +++ b/src/mapleall/maple_me/include/orig_symbol.h @@ -175,6 +175,14 @@ class OriginalSt { this->fieldID = fieldID; } + const OffsetType &GetOffset() const { + return offset; + } + + void SetOffset(const OffsetType &offsetVal) { + offset = offsetVal; + } + bool IsIgnoreRC() const { return ignoreRC; } @@ -257,6 +265,7 @@ class OriginalSt { index(index), versionsIndices(alloc.Adapter()), fieldID(fieldID), + offset(kOffsetUnknown), isLocal(local), isFormal(isFormal), ignoreRC(ignoreRC), @@ -270,6 +279,7 @@ class OriginalSt { size_t zeroVersionIndex = 0; // same as versionsIndices[0] TyIdx tyIdx{ 0 }; // type of this symbol at this level; 0 for unknown FieldID fieldID; // at each level of indirection + OffsetType offset; int8 indirectLev = 0; // level of indirection; -1 for address, 0 for itself bool isLocal; // get from defined stmt or use expr bool isFormal; // it's from the formal parameters so the type must be kSymbolOst or kPregOst after rename2preg @@ -286,10 +296,11 @@ class OriginalSt { class SymbolFieldPair { public: - SymbolFieldPair(const StIdx &stIdx, FieldID fld) : stIdx(stIdx), fldID(fld) {} + SymbolFieldPair(const StIdx &stIdx, FieldID fld, const OffsetType &offset = OffsetType(kOffsetUnknown)) + : stIdx(stIdx), fldIDAndOffset((static_cast(offset.val) << 32) + fld) {} ~SymbolFieldPair() = default; bool operator==(const SymbolFieldPair& pairA) const { - return (pairA.stIdx == stIdx) && (pairA.fldID == fldID); + return (pairA.stIdx == stIdx) && (pairA.fldIDAndOffset == fldIDAndOffset); } const StIdx &GetStIdx() const { @@ -297,12 +308,12 @@ class SymbolFieldPair { } FieldID GetFieldID() const { - return fldID; + return static_cast(fldIDAndOffset); } private: StIdx stIdx; - FieldID fldID; + int64 fldIDAndOffset; }; struct HashSymbolFieldPair { @@ -318,6 +329,10 @@ class OriginalStTable { ~OriginalStTable() = default; OriginalSt *FindOrCreateSymbolOriginalSt(MIRSymbol &mirSt, PUIdx puIdx, FieldID fld); + std::pair FindOrCreateSymbolOriginalSt(MIRSymbol &mirSt, PUIdx puIdx, FieldID fld, + const TyIdx &tyIdx, const OffsetType &offset = OffsetType(kOffsetUnknown)); + OriginalSt *CreateSymbolOriginalSt(MIRSymbol &mirSt, PUIdx puIdx, FieldID fld, const TyIdx &tyIdx, + const OffsetType &offset = OffsetType(kOffsetUnknown)); OriginalSt *FindOrCreatePregOriginalSt(PregIdx pregIdx, PUIdx puIdx); OriginalSt *CreateSymbolOriginalSt(MIRSymbol &mirSt, PUIdx pidx, FieldID fld); OriginalSt *CreatePregOriginalSt(PregIdx pregIdx, PUIdx puIdx); diff --git a/src/mapleall/maple_me/include/prop.h b/src/mapleall/maple_me/include/prop.h index ab5e0a0795d1378e609a0ad8df37ef85650a4159..6cd16b0e2c82cf9c01ea2d3626e981282482fc35 100644 --- a/src/mapleall/maple_me/include/prop.h +++ b/src/mapleall/maple_me/include/prop.h @@ -41,7 +41,7 @@ class Prop { MeExpr *CheckTruncation(MeExpr *lhs, MeExpr *rhs) const; MeExpr &PropVar(VarMeExpr &varmeExpr, bool atParm, bool checkPhi) const; MeExpr &PropReg(RegMeExpr ®meExpr, bool atParm) const; - MeExpr &PropIvar(IvarMeExpr &ivarMeExpr) const; + MeExpr &PropIvar(IvarMeExpr &ivarMeExpr); void PropUpdateDef(MeExpr &meExpr); void PropUpdateChiListDef(const MapleMap &chiList); void PropUpdateMustDefList(MeStmt *mestmt); diff --git a/src/mapleall/maple_me/src/alias_class.cpp b/src/mapleall/maple_me/src/alias_class.cpp index d9971417c0c9438b2e540ac212567d4ac1531a52..b73418fd791fba639919dfb8c93de47346aa0135 100644 --- a/src/mapleall/maple_me/src/alias_class.cpp +++ b/src/mapleall/maple_me/src/alias_class.cpp @@ -175,23 +175,84 @@ AliasElem *AliasClass::FindOrCreateAliasElem(OriginalSt &ost) { return aliasElem; } -AliasElem *AliasClass::FindOrCreateExtraLevAliasElem(BaseNode &expr, TyIdx tyIdx, FieldID fieldId) { - AliasInfo ainfo = CreateAliasElemsExpr(kOpcodeInfo.IsTypeCvt(expr.GetOpCode()) ? *expr.Opnd(0) : expr); - if (!mirModule.IsCModule()) { - if (ainfo.ae == nullptr) { - return nullptr; - } - } else if (ainfo.ae == nullptr || IsNullOrDummySymbolOst(ainfo.ae->GetOst())) { +AliasElem *AliasClass::FindOrCreateExtraLevAliasElem(BaseNode &baseAddress, const TyIdx &tyIdx, FieldID fieldId) { + auto *baseAddr = RemoveTypeConvertionIfExist(&baseAddress); + AliasInfo aliasInfoOfBaseAddress = CreateAliasElemsExpr(*baseAddr); + if (aliasInfoOfBaseAddress.ae == nullptr) { + return FindOrCreateDummyNADSAe(); + } + if (mirModule.IsCModule() && IsNullOrDummySymbolOst(aliasInfoOfBaseAddress.ae->GetOst())) { return FindOrCreateDummyNADSAe(); } + + auto *ostOfBaseAddress = aliasInfoOfBaseAddress.ae->GetOst(); + // create exact virtual-var for iread (array (addrof %array, i32 index)) + if (baseAddr->GetOpCode() == OP_array && baseAddr->Opnd(0)->GetOpCode() == OP_addrof && + static_cast(baseAddr->Opnd(0))->GetFieldID() == 0) { + bool allIndexIsConst = true; + std::vector arrayIndexVector(baseAddr->NumOpnds() - 1, 0); + for (uint32 opndId = 1; opndId < baseAddr->NumOpnds(); ++opndId) { + auto *opnd = baseAddr->Opnd(opndId); + if (!opnd->IsConstval()) { + allIndexIsConst = false; + break; + } + auto mirConst = static_cast(opnd)->GetConstVal(); + ASSERT(mirConst->GetKind() == kConstInt, "array index must be integer"); + auto index = static_cast(mirConst)->GetValue(); + arrayIndexVector[opndId - 1] = index; + } + OffsetType offsetInByte(kOffsetUnknown); + if (allIndexIsConst) { + auto *ptrTypeOfArrayType = + GlobalTables::GetTypeTable().GetTypeFromTyIdx(static_cast(baseAddr)->GetTyIdx()); + ASSERT(ptrTypeOfArrayType->IsMIRPtrType(), "must be pointer type"); + auto *arrayType = static_cast(ptrTypeOfArrayType)->GetPointedType(); + switch (arrayType->GetKind()) { + case kTypeArray: { + offsetInByte.Set( + static_cast(arrayType)->OffsetInByteFromArrayAddress(arrayIndexVector)); + break; + } + case kTypeFArray: + case kTypeJArray: { + ASSERT(arrayIndexVector.size() == 1, "FArray/JArray has single index"); + offsetInByte.Set( + static_cast(arrayType)->OffsetInByteFromArrayAddress(arrayIndexVector.front())); + break; + } + default: { + CHECK_FATAL(false, "unsupported array type"); + break; + } + } + } + auto mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); + ASSERT(mirType->IsMIRPtrType(), "must be pointer type"); + auto elemTypeIndex = static_cast(mirType)->GetPointedTyIdx(); + const auto &ostPair = + ssaTab.GetOriginalStTable().FindOrCreateSymbolOriginalSt(*ostOfBaseAddress->GetMIRSymbol(), + ostOfBaseAddress->GetPuIdx(), 0, elemTypeIndex, OffsetType(offsetInByte)); + auto *newOst = ostPair.first; + newOst->SetPrevLevelOst(ostOfBaseAddress); + if (ostPair.second) { + ostOfBaseAddress->AddNextLevelOst(newOst, true); + } + if (newOst->GetIndex() == osym2Elem.size()) { + osym2Elem.push_back(nullptr); + ssaTab.GetVersionStTable().CreateZeroVersionSt(newOst); + } + return FindOrCreateAliasElem(*newOst); + } + + auto *typeOfBaseOst = ostOfBaseAddress->GetType(); + const TyIdx &tyIdxOfBaseOst = typeOfBaseOst->GetTypeIndex(); OriginalSt *newOst = nullptr; - if (mirModule.IsCModule() && ainfo.ae->GetOriginalSt().GetTyIdx() != tyIdx) { - newOst = ssaTab.FindOrCreateExtraLevOriginalSt( - ainfo.ae->GetOst(), ainfo.ae->GetOriginalSt().GetTyIdx(), 0); + if (mirModule.IsCModule() && tyIdxOfBaseOst != tyIdx) { + newOst = ssaTab.FindOrCreateExtraLevOriginalSt(ostOfBaseAddress, tyIdxOfBaseOst, 0); } else { - newOst = ssaTab.FindOrCreateExtraLevOriginalSt( - ainfo.ae->GetOst(), ainfo.fieldID ? ainfo.ae->GetOriginalSt().GetTyIdx() : tyIdx, - fieldId + ainfo.fieldID); + newOst = ssaTab.FindOrCreateExtraLevOriginalSt(ostOfBaseAddress, + aliasInfoOfBaseAddress.fieldID ? tyIdxOfBaseOst : tyIdx, fieldId + aliasInfoOfBaseAddress.fieldID); } CHECK_FATAL(newOst != nullptr, "null ptr check"); if (newOst->GetIndex() == osym2Elem.size()) { @@ -257,8 +318,7 @@ AliasInfo AliasClass::CreateAliasElemsExpr(BaseNode &expr) { } case OP_iread: { auto &iread = static_cast(expr); - return AliasInfo( - FindOrCreateExtraLevAliasElem(utils::ToRef(iread.Opnd(0)), iread.GetTyIdx(), iread.GetFieldID()), 0); + return AliasInfo(FindOrCreateExtraLevAliasElem(*iread.Opnd(0), iread.GetTyIdx(), iread.GetFieldID()), 0); } case OP_iaddrof: { auto &iread = static_cast(expr); @@ -407,26 +467,23 @@ void AliasClass::ApplyUnionForFieldsInAggCopy(const OriginalSt *lhsost, const Or } } -// at lhs = rhs, if lhs is not an address (e.g. i64) and rhs is an address(e.g. ptr), or vice versa, -// then rhs's(or lhs's) next level may be defined by lhs(or rhs) -// if a preceding case occurs, return true. -bool AliasClass::SetNextLevNADSForPtrIntegerCopy(AliasElem &lhsAe, const AliasElem *rhsAe, BaseNode &rhs) { - // for lhs = rhs, if one is address and the other is not, there must be type convertion between them. - // And we know that CreateAliasElemsExpr(cvt expr) will return nullptr - if (rhsAe != nullptr) { - return false; - } +// There are three cases that cause ptr escape from its original definition: +// 1. pointer formal parameters for function definition; (has been dealed in UnionForNADS) +// 2. pointer actual parameters for function call; (has been dealed in call stmts) +// 3. pointer assigned to other variable whose alias will never be analyzed. (dealed here) +// - integer <- ptr or vice versa +// - agg <- ptr or vice versa +// +// return true if ptr escapes +bool AliasClass::SetNextLevNADSForEscapePtr(AliasElem &lhsAe, BaseNode &rhs) { TyIdx lhsTyIdx = lhsAe.GetOriginalSt().GetTyIdx(); PrimType lhsPtyp = GlobalTables::GetTypeTable().GetTypeFromTyIdx(lhsTyIdx)->GetPrimType(); BaseNode *realRhs = RemoveTypeConvertionIfExist(&rhs); PrimType rhsPtyp = realRhs->GetPrimType(); if (lhsPtyp != rhsPtyp) { - if (IsPotentialAddress(lhsPtyp, &mirModule) && !IsPotentialAddress(rhsPtyp, &mirModule)) { - // ptr <- (ptr)integer + if ((IsPotentialAddress(lhsPtyp, &mirModule) && !IsPotentialAddress(rhsPtyp, &mirModule)) || + (!IsPotentialAddress(lhsPtyp, &mirModule) && IsPotentialAddress(rhsPtyp, &mirModule))) { lhsAe.SetNextLevNotAllDefsSeen(true); - return true; - } else if (!IsPotentialAddress(lhsPtyp, &mirModule) && IsPotentialAddress(rhsPtyp, &mirModule)) { - // integer <- (integer)ptr AliasInfo realRhsAinfo = CreateAliasElemsExpr(*realRhs); if (realRhsAinfo.ae != nullptr) { realRhsAinfo.ae->SetNextLevNotAllDefsSeen(true); @@ -449,8 +506,7 @@ bool AliasClass::SetNextLevNADSForPtrIntegerCopy(AliasElem &lhsAe, const AliasEl } void AliasClass::ApplyUnionForDassignCopy(AliasElem &lhsAe, AliasElem *rhsAe, BaseNode &rhs) { - // case like "integer <- (integer)ptr" or "ptr <- (ptr)integer", we should set ptr's nextLev not all def seen - if (SetNextLevNADSForPtrIntegerCopy(lhsAe, rhsAe, rhs)) { + if (SetNextLevNADSForEscapePtr(lhsAe, rhs)) { return; } if (rhsAe == nullptr || rhsAe->GetOriginalSt().GetIndirectLev() > 0 || rhsAe->IsNotAllDefsSeen()) { @@ -544,8 +600,8 @@ void AliasClass::ApplyUnionForCopies(StmtNode &stmt) { case OP_iassign: { auto &iassignNode = static_cast(stmt); AliasInfo rhsAinfo = CreateAliasElemsExpr(*iassignNode.Opnd(1)); - AliasElem *lhsAliasElem = FindOrCreateExtraLevAliasElem(*iassignNode.Opnd(0), iassignNode.GetTyIdx(), - iassignNode.GetFieldID()); + AliasElem *lhsAliasElem = + FindOrCreateExtraLevAliasElem(*iassignNode.Opnd(0), iassignNode.GetTyIdx(), iassignNode.GetFieldID()); if (lhsAliasElem != nullptr) { ApplyUnionForDassignCopy(*lhsAliasElem, rhsAinfo.ae, *iassignNode.Opnd(1)); } @@ -706,25 +762,10 @@ void AliasClass::UnionAllPointedTos() { } // process the union among the pointed's of assignsets void AliasClass::ApplyUnionForPointedTos() { - // first, process nextLevNotAllDefsSeen for alias elems + // first, process nextLevNotAllDefsSeen for alias elems until no change bool change = false; - for (AliasElem *aliaselem : id2Elem) { - if (aliaselem->IsNextLevNotAllDefsSeen()) { - MapleVector &nextLevelNodes = - aliaselem->GetOriginalSt().GetNextLevelOsts(); - auto ostit = nextLevelNodes.begin(); - for (; ostit != nextLevelNodes.end(); ++ostit) { - AliasElem *indae = FindAliasElem(**ostit); - if (!indae->GetOriginalSt().IsFinal() && !indae->IsNotAllDefsSeen()) { - indae->SetNotAllDefsSeen(true); - indae->SetNextLevNotAllDefsSeen(true); - change = true; - } - } - } - } - // do one more time to ensure proper propagation - if (change) { + do { + change = false; for (AliasElem *aliaselem : id2Elem) { if (aliaselem->IsNextLevNotAllDefsSeen()) { const auto &nextLevelNodes = aliaselem->GetOriginalSt().GetNextLevelOsts(); @@ -734,11 +775,12 @@ void AliasClass::ApplyUnionForPointedTos() { if (!indae->GetOriginalSt().IsFinal() && !indae->IsNotAllDefsSeen()) { indae->SetNotAllDefsSeen(true); indae->SetNextLevNotAllDefsSeen(true); + change = true; } } } } - } + } while (change); MapleSet tempset(std::less(), acAlloc.Adapter()); for (AliasElem *aliaselem : id2Elem) { @@ -1252,7 +1294,8 @@ bool AliasClass::MayAliasBasicAA(const OriginalSt *ostA, const OriginalSt *ostB) return false; } - // basicAA cannot analysis alias relation of virtual-var + // flow-insensitive basicAA cannot analysis alias relation of virtual-var. + // Pointer arithmetic may changed value of pointer, and result in aggPtr->fldA alias with aggPtr->fldB. if (indirectLevA > 0 || indirectLevB > 0) { return true; } @@ -1268,16 +1311,25 @@ bool AliasClass::MayAliasBasicAA(const OriginalSt *ostA, const OriginalSt *ostB) return true; } + // alias analysis based on offset, currently only valid for array-element. + OffsetType offsetA = ostA->GetOffset(); + OffsetType offsetB = ostB->GetOffset(); + auto typeA = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ostA->GetTyIdx()); + auto typeB = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ostB->GetTyIdx()); + if (!offsetA.IsInvalid() && !offsetB.IsInvalid()) { + // return if memory of ostA and ostB overlap + return offsetA < (offsetB + static_cast(typeB->GetSize())) && + offsetB < (offsetA + static_cast(typeA->GetSize())); + } + + // alias analysis based on fieldId FieldID fieldIdA = ostA->GetFieldID(); FieldID fieldIdB = ostB->GetFieldID(); if (fieldIdA == 0 || fieldIdB == 0 || fieldIdA == fieldIdB) { return true; } - auto typeA = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ostA->GetTyIdx()); uint32 fieldNumOfOstA = typeA->NumberOfFieldIDs(); - - auto typeB = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ostB->GetTyIdx()); uint32 fieldNumOfOstB = typeB->NumberOfFieldIDs(); // ostA and ostB overlaps with each other in memory return (fieldIdA <= fieldIdB + fieldNumOfOstB) && (fieldIdB <= fieldIdA + fieldNumOfOstA); @@ -1454,7 +1506,7 @@ void AliasClass::CollectMayDefForDassign(const StmtNode &stmt, std::set &mayDefOsts) { auto &iassignNode = static_cast(stmt); - AliasInfo baseAinfo = CreateAliasElemsExpr(*iassignNode.Opnd(0)); - AliasElem *lhsAe = nullptr; - if (baseAinfo.ae != nullptr) { - // get the next-level-ost that will be assigned to - if (mirModule.IsCModule() && baseAinfo.ae->GetOriginalSt().GetTyIdx() != iassignNode.GetTyIdx()) { - // in case of type incompatible, set fieldId to zero of the mayDefed virtual-var - lhsAe = FindOrCreateExtraLevAliasElem(*iassignNode.Opnd(0), iassignNode.GetTyIdx(), 0); - } else if (!mirModule.IsCModule() || iassignNode.GetFieldID() == 0 || - baseAinfo.ae->GetOriginalSt().GetIndirectLev() == -1 || - baseAinfo.ae->GetOriginalSt().GetTyIdx() == iassignNode.GetTyIdx()) { - OriginalSt *lhsOst = nullptr; - TyIdx tyIdxOfIass = iassignNode.GetTyIdx(); - OriginalSt &ostOfBaseExpr = baseAinfo.ae->GetOriginalSt(); - TyIdx tyIdxOfBaseOSt = ostOfBaseExpr.GetTyIdx(); - FieldID fldOfIass = iassignNode.GetFieldID() + baseAinfo.fieldID; - for (OriginalSt *nextLevelNode : ostOfBaseExpr.GetNextLevelOsts()) { - FieldID fldOfNextLevelOSt = nextLevelNode->GetFieldID(); - if (IsEquivalentField(tyIdxOfIass, fldOfIass, tyIdxOfBaseOSt, fldOfNextLevelOSt)) { - lhsOst = nextLevelNode; - break; - } - } - CHECK_FATAL(lhsOst != nullptr, "AliasClass::InsertMayUseExpr: cannot find next level ost"); - lhsAe = osym2Elem[lhsOst->GetIndex()]; - } else { - lhsAe = FindOrCreateDummyNADSAe(); - } - } else { - lhsAe = FindOrCreateDummyNADSAe(); - } + AliasElem *lhsAe = + FindOrCreateExtraLevAliasElem(*iassignNode.Opnd(0), iassignNode.GetTyIdx(), iassignNode.GetFieldID()); + // lhsAe does not alias with any aliasElem if (lhsAe->GetClassSet() == nullptr) { (void)mayDefOsts.insert(&lhsAe->GetOriginalSt()); diff --git a/src/mapleall/maple_me/src/hdse.cpp b/src/mapleall/maple_me/src/hdse.cpp index 48b483c55bc27c9df619f8793302c6c632e54547..5747d537c17aa3cc6df6d70e031ee55ef7b2db14 100644 --- a/src/mapleall/maple_me/src/hdse.cpp +++ b/src/mapleall/maple_me/src/hdse.cpp @@ -367,6 +367,10 @@ void HDSE::PropagateUseLive(MeExpr &meExpr) { bool HDSE::ExprHasSideEffect(const MeExpr &meExpr) const { Opcode op = meExpr.GetOp(); + // in c language, OP_array has no side-effect + if (mirModule.IsCModule() && op == OP_array) { + return false; + } if (kOpcodeInfo.HasSideEffect(op)) { return true; } @@ -387,6 +391,7 @@ bool HDSE::ExprNonDeletable(const MeExpr &meExpr) const { if (ExprHasSideEffect(meExpr)) { return true; } + switch (meExpr.GetMeOp()) { case kMeOpReg: { auto ®MeExpr = static_cast(meExpr); @@ -613,6 +618,9 @@ void HDSE::MarkSpecialStmtRequired() { } } } + if (IsLfo()) { + ProcessWhileInfos(); + } } void HDSE::DseInit() { diff --git a/src/mapleall/maple_me/src/lfo_inject_iv.cpp b/src/mapleall/maple_me/src/lfo_inject_iv.cpp index 7589ac51349e35d970ab363f232c65a6198bbf10..a44f97ca056fe7a81962417ca243761b020de168 100644 --- a/src/mapleall/maple_me/src/lfo_inject_iv.cpp +++ b/src/mapleall/maple_me/src/lfo_inject_iv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) [2021] Huawei Technologies Co., Ltd. All rights reserved. * * OpenArkCompiler is licensed under the Mulan Permissive Software License v2. * You can use this software according to the terms and conditions of the MulanPSL - 2.0. @@ -69,7 +69,7 @@ AnalysisResult *DoLfoInjectIV::Run(MeFunction *func, MeFuncResultMgr *m, ModuleR // initialize IV to 0 at loop entry DassignNode *dass = mirbuilder->CreateStmtDassign(st->GetStIdx(), 0, mirbuilder->CreateIntConst(0, PTY_i64)); - StmtNode *laststmt = entrybb->IsEmpty() ? NULL : &entrybb->GetLast(); + StmtNode *laststmt = entrybb->IsEmpty() ? nullptr : &entrybb->GetLast(); if (laststmt && (laststmt->op == OP_brfalse || laststmt->op == OP_brtrue || laststmt->op == OP_goto || laststmt->op == OP_igoto || laststmt->op == OP_switch)) { diff --git a/src/mapleall/maple_me/src/lfo_iv_canon.cpp b/src/mapleall/maple_me/src/lfo_iv_canon.cpp index 856cc40aa0007e88dc946a2711aa142d5f9a2585..fb8a380f7c484814b2a87af5a9dfa3e26b3341d6 100644 --- a/src/mapleall/maple_me/src/lfo_iv_canon.cpp +++ b/src/mapleall/maple_me/src/lfo_iv_canon.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) [2021] Huawei Technologies Co., Ltd. All rights reserved. * * OpenArkCompiler is licensed under the Mulan Permissive Software License v2. * You can use this software according to the terms and conditions of the MulanPSL - 2.0. @@ -22,36 +22,33 @@ // S.-M. Liu, R. Lo and F. Chow, "Loop Induction Variable // Canonicalization in Parallelizing Compiler", Intl. Conf. on Parallel // Architectures and Compilation Techniques (PACT 96), Oct 1996. - -using namespace std; - namespace maple { - +using namespace std; // Resolve value of x; return false if result is not of induction expression // form; goal is to resolve to an expression where the only non-constant is // philhs -bool IVCanon::ResolveExprValue(MeExpr *x, ScalarMeExpr *philhs) { +bool IVCanon::ResolveExprValue(MeExpr *x, ScalarMeExpr *phiLHS) { switch (x->GetMeOp()) { case kMeOpConst: return IsPrimitiveInteger(x->GetPrimType()); case kMeOpVar: case kMeOpReg:{ - if (x == philhs) { + if (x == phiLHS) { return true; } ScalarMeExpr *scalar = static_cast(x); if (scalar->GetDefBy() != kDefByStmt) { return false; } - AssignMeStmt *defstmt = static_cast(scalar->GetDefStmt()); - return ResolveExprValue(defstmt->GetRHS(), philhs); + AssignMeStmt *defStmt = static_cast(scalar->GetDefStmt()); + return ResolveExprValue(defStmt->GetRHS(), phiLHS); } case kMeOpOp: { // restricting to only + and - for now if (x->GetOp() != OP_add && x->GetOp() != OP_sub) { return false; } - OpMeExpr *opexp = static_cast(x); - return ResolveExprValue(opexp->GetOpnd(0), philhs) && - ResolveExprValue(opexp->GetOpnd(1), philhs); + OpMeExpr *opExpr = static_cast(x); + return ResolveExprValue(opExpr->GetOpnd(0), phiLHS) && + ResolveExprValue(opExpr->GetOpnd(1), phiLHS); } default: ; } @@ -60,41 +57,42 @@ bool IVCanon::ResolveExprValue(MeExpr *x, ScalarMeExpr *philhs) { // appearances accumulates the number of appearances of the induction variable; // it is negative if it is subtracted -int32 IVCanon::ComputeIncrAmt(MeExpr *x, ScalarMeExpr *philhs, int32 *appearances) { +int32 IVCanon::ComputeIncrAmt(MeExpr *x, ScalarMeExpr *phiLHS, int32 *appearances) { switch (x->GetMeOp()) { - case kMeOpConst: { - MIRConst *konst = static_cast(x)->GetConstVal(); - CHECK_FATAL(konst->GetKind() == kConstInt, "ComputeIncrAmt: must be integer constant"); - MIRIntConst *intconst = static_cast(konst); - return intconst->GetValue(); - } - case kMeOpVar: - case kMeOpReg:{ - if (x == philhs) { - *appearances = 1; - return 0; + case kMeOpConst: { + MIRConst *konst = static_cast(x)->GetConstVal(); + CHECK_FATAL(konst->GetKind() == kConstInt, "ComputeIncrAmt: must be integer constant"); + MIRIntConst *intConst = static_cast(konst); + return intConst->GetValue(); } - ScalarMeExpr *scalar = static_cast(x); - CHECK_FATAL(scalar->GetDefBy() == kDefByStmt, "ComputeIncrAmt: cannot be here"); - AssignMeStmt *defstmt = static_cast(scalar->GetDefStmt()); - return ComputeIncrAmt(defstmt->GetRHS(), philhs, appearances); - } - case kMeOpOp: { - CHECK_FATAL(x->GetOp() == OP_add || x->GetOp() == OP_sub, "ComputeIncrAmt: cannot be here"); - OpMeExpr *opexp = static_cast(x); - int32 appear0 = 0; - int64 incrAmt0 = ComputeIncrAmt(opexp->GetOpnd(0), philhs, &appear0); - int32 appear1 = 0; - int64 incrAmt1 = ComputeIncrAmt(opexp->GetOpnd(1), philhs, &appear1); - if (x->GetOp() == OP_sub) { - *appearances = appear0 - appear1; - return incrAmt0 - incrAmt1; - } else { - *appearances = appear0 + appear1; - return incrAmt0 + incrAmt1; + case kMeOpVar: + case kMeOpReg:{ + if (x == phiLHS) { + *appearances = 1; + return 0; + } + ScalarMeExpr *scalar = static_cast(x); + CHECK_FATAL(scalar->GetDefBy() == kDefByStmt, "ComputeIncrAmt: cannot be here"); + AssignMeStmt *defstmt = static_cast(scalar->GetDefStmt()); + return ComputeIncrAmt(defstmt->GetRHS(), phiLHS, appearances); } - } - default: ; + case kMeOpOp: { + CHECK_FATAL(x->GetOp() == OP_add || x->GetOp() == OP_sub, "ComputeIncrAmt: cannot be here"); + OpMeExpr *opexp = static_cast(x); + int32 appear0 = 0; + int64 incrAmt0 = ComputeIncrAmt(opexp->GetOpnd(0), phiLHS, &appear0); + int32 appear1 = 0; + int64 incrAmt1 = ComputeIncrAmt(opexp->GetOpnd(1), phiLHS, &appear1); + if (x->GetOp() == OP_sub) { + *appearances = appear0 - appear1; + return incrAmt0 - incrAmt1; + } else { + *appearances = appear0 + appear1; + return incrAmt0 + incrAmt1; + } + } + default: + break; } CHECK_FATAL(false, "ComputeIncrAmt: should not be here"); return 0; @@ -104,12 +102,12 @@ int32 IVCanon::ComputeIncrAmt(MeExpr *x, ScalarMeExpr *philhs, int32 *appearance void IVCanon::CharacterizeIV(ScalarMeExpr *initversion, ScalarMeExpr *loopbackversion, ScalarMeExpr *philhs) { IVDesc *ivdesc = mp->New(initversion->GetOst()); if (initversion->GetDefBy() == kDefByStmt) { - AssignMeStmt *defstmt = static_cast(initversion->GetDefStmt()); - if (defstmt->GetRHS()->GetMeOp() == kMeOpConst || - defstmt->GetRHS()->GetMeOp() == kMeOpAddrof || - defstmt->GetRHS()->GetMeOp() == kMeOpConststr || - defstmt->GetRHS()->GetMeOp() == kMeOpConststr16) { - ivdesc->initExpr = defstmt->GetRHS(); + AssignMeStmt *defStmt = static_cast(initversion->GetDefStmt()); + if (defStmt->GetRHS()->GetMeOp() == kMeOpConst || + defStmt->GetRHS()->GetMeOp() == kMeOpAddrof || + defStmt->GetRHS()->GetMeOp() == kMeOpConststr || + defStmt->GetRHS()->GetMeOp() == kMeOpConststr16) { + ivdesc->initExpr = defStmt->GetRHS(); } else { ivdesc->initExpr = initversion; } @@ -165,40 +163,41 @@ bool IVCanon::IsLoopInvariant(MeExpr *x) { return true; } switch (x->GetMeOp()) { - case kMeOpAddrof: - case kMeOpAddroffunc: - case kMeOpConst: - case kMeOpConststr: - case kMeOpConststr16: - case kMeOpSizeoftype: - case kMeOpFieldsDist: return true; - case kMeOpVar: - case kMeOpReg: { - ScalarMeExpr *scalar = static_cast(x); - BB *defBB = scalar->DefByBB(); - return defBB == nullptr || dominance->Dominate(*defBB, *aloop->head); - } - case kMeOpIvar: { - IvarMeExpr *ivar = static_cast(x); - BB *defBB = ivar->GetMu()->DefByBB(); - return defBB == nullptr || dominance->Dominate(*defBB, *aloop->head); - } - case kMeOpOp: { - OpMeExpr *opexp = static_cast(x); - return IsLoopInvariant(opexp->GetOpnd(0)) && - IsLoopInvariant(opexp->GetOpnd(1)) && - IsLoopInvariant(opexp->GetOpnd(2)); - } - case kMeOpNary: { - NaryMeExpr *opexp = static_cast(x); - for (uint32 i = 0; i < opexp->GetNumOpnds(); i++) { - if (!IsLoopInvariant(opexp->GetOpnd(i))) { - return false; + case kMeOpAddrof: + case kMeOpAddroffunc: + case kMeOpConst: + case kMeOpConststr: + case kMeOpConststr16: + case kMeOpSizeoftype: + case kMeOpFieldsDist: return true; + case kMeOpVar: + case kMeOpReg: { + ScalarMeExpr *scalar = static_cast(x); + BB *defBB = scalar->DefByBB(); + return defBB == nullptr || dominance->Dominate(*defBB, *aloop->head); + } + case kMeOpIvar: { + IvarMeExpr *ivar = static_cast(x); + BB *defBB = ivar->GetMu()->DefByBB(); + return defBB == nullptr || dominance->Dominate(*defBB, *aloop->head); + } + case kMeOpOp: { + OpMeExpr *opexp = static_cast(x); + return IsLoopInvariant(opexp->GetOpnd(0)) && + IsLoopInvariant(opexp->GetOpnd(1)) && + IsLoopInvariant(opexp->GetOpnd(2)); + } + case kMeOpNary: { + NaryMeExpr *opexp = static_cast(x); + for (uint32 i = 0; i < opexp->GetNumOpnds(); i++) { + if (!IsLoopInvariant(opexp->GetOpnd(i))) { + return false; + } } + return true; } - return true; - } - default: ; + default: + break; } return false; } @@ -213,10 +212,10 @@ void IVCanon::ComputeTripCount() { if (!kOpcodeInfo.IsCompare(condbr->GetOpnd()->GetOp())) { return; } - OpMeExpr *testexp = static_cast(condbr->GetOpnd()); + OpMeExpr *testExpr = static_cast(condbr->GetOpnd()); // make the side that consists of a single IV the left operand // check left operand - ScalarMeExpr *iv = dynamic_cast(testexp->GetOpnd(0)); + ScalarMeExpr *iv = dynamic_cast(testExpr->GetOpnd(0)); IVDesc *ivdesc = nullptr; if (iv) { for (uint32 i = 0; i < ivvec.size(); i++) { @@ -227,7 +226,7 @@ void IVCanon::ComputeTripCount() { } } if (ivdesc == nullptr) { // check second operand - iv = dynamic_cast(testexp->GetOpnd(1)); + iv = dynamic_cast(testExpr->GetOpnd(1)); if (iv) { for (uint32 i = 0; i < ivvec.size(); i++) { if (iv->GetOst() == ivvec[i]->ost) { @@ -237,26 +236,35 @@ void IVCanon::ComputeTripCount() { } } if (ivdesc) { // swap the 2 sides - Opcode newop = testexp->GetOp(); - switch (testexp->GetOp()) { - case OP_lt: newop = OP_gt; break; - case OP_le: newop = OP_ge; break; - case OP_gt: newop = OP_lt; break; - case OP_ge: newop = OP_le; break; - default: ; + Opcode newop = testExpr->GetOp(); + switch (testExpr->GetOp()) { + case OP_lt: + newop = OP_gt; + break; + case OP_le: + newop = OP_ge; + break; + case OP_gt: + newop = OP_lt; + break; + case OP_ge: + newop = OP_le; + break; + default: + break; } - OpMeExpr opmeexpr(-1, newop, testexp->GetPrimType(), 2); - opmeexpr.SetOpnd(0, testexp->GetOpnd(1)); - opmeexpr.SetOpnd(1, testexp->GetOpnd(0)); - opmeexpr.SetOpndType(testexp->GetOpndType()); - testexp = static_cast(irMap->HashMeExpr(opmeexpr)); - condbr->SetOpnd(0, testexp); + OpMeExpr opMeExpr(-1, newop, testExpr->GetPrimType(), 2); + opMeExpr.SetOpnd(0, testExpr->GetOpnd(1)); + opMeExpr.SetOpnd(1, testExpr->GetOpnd(0)); + opMeExpr.SetOpndType(testExpr->GetOpndType()); + testExpr = static_cast(irMap->HashMeExpr(opMeExpr)); + condbr->SetOpnd(0, testExpr); } } if (ivdesc == nullptr || ivdesc->stepValue == 0) { return; // no IV in the termination test } - if (!IsLoopInvariant(testexp->GetOpnd(1))) { + if (!IsLoopInvariant(testExpr->GetOpnd(1))) { return; // the right side is not loop-invariant } @@ -272,14 +280,15 @@ void IVCanon::ComputeTripCount() { } // form the trip count expression - PrimType primTypeUsed = testexp->GetOpnd(0)->GetPrimType(); + PrimType primTypeUsed = testExpr->GetOpnd(0)->GetPrimType(); PrimType divPrimType = primTypeUsed; if (ivdesc->stepValue < 0) { divPrimType = GetSignedPrimType(divPrimType); } OpMeExpr add(-1, OP_add, primTypeUsed, 2); - add.SetOpnd(0, testexp->GetOpnd(1)); // IV bound - add.SetOpnd(1, irMap->CreateIntConstMeExpr(ivdesc->stepValue > 0 ? ivdesc->stepValue-1 : ivdesc->stepValue+1, primTypeUsed)); + add.SetOpnd(0, testExpr->GetOpnd(1)); // IV bound + add.SetOpnd(1, irMap->CreateIntConstMeExpr(ivdesc->stepValue > 0 ? ivdesc->stepValue - 1 + : ivdesc->stepValue + 1, primTypeUsed)); MeExpr *subx = irMap->HashMeExpr(add); if (!ivdesc->initExpr->IsZero()) { OpMeExpr subtract(-1, OP_sub, primTypeUsed, 2); @@ -308,13 +317,13 @@ void IVCanon::CanonEntryValues() { initName.append(std::to_string(i)); initName.append(".init"); GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(initName); - ScalarMeExpr *scalarmeexpr = func->GetIRMap()->CreateNewVar(strIdx, ivdesc->primType, false); + ScalarMeExpr *scalarMeExpr = func->GetIRMap()->CreateNewVar(strIdx, ivdesc->primType, false); #else // create preg ScalarMeExpr *scalarmeexpr = func->irMap->CreateRegMeExpr(ivdesc->primType); #endif - AssignMeStmt *ass = func->GetIRMap()->CreateAssignMeStmt(*scalarmeexpr, *ivdesc->initExpr, *aloop->preheader); + AssignMeStmt *ass = func->GetIRMap()->CreateAssignMeStmt(*scalarMeExpr, *ivdesc->initExpr, *aloop->preheader); aloop->preheader->AddMeStmtLast(ass); - ivdesc->initExpr = scalarmeexpr; + ivdesc->initExpr = scalarMeExpr; } } } @@ -399,17 +408,17 @@ void IVCanon::ReplaceSecondaryIVPhis() { MeExpr *mulx = iterCountUsed; if (ivdesc->stepValue != 1) { PrimType primTypeUsed = ivdesc->stepValue < 0 ? GetSignedPrimType(ivdesc->primType) : ivdesc->primType; - OpMeExpr mulmeexpr(-1, OP_mul, primTypeUsed, 2); - mulmeexpr.SetOpnd(0, mulx); - mulmeexpr.SetOpnd(1, func->GetIRMap()->CreateIntConstMeExpr(ivdesc->stepValue, primTypeUsed)); - mulx = func->GetIRMap()->HashMeExpr(mulmeexpr); + OpMeExpr mulMeExpr(-1, OP_mul, primTypeUsed, 2); + mulMeExpr.SetOpnd(0, mulx); + mulMeExpr.SetOpnd(1, func->GetIRMap()->CreateIntConstMeExpr(ivdesc->stepValue, primTypeUsed)); + mulx = func->GetIRMap()->HashMeExpr(mulMeExpr); } - OpMeExpr addmeexpr(-1, OP_add, ivdesc->primType, 2); + OpMeExpr addMeExpr(-1, OP_add, ivdesc->primType, 2); MeExpr *addx = mulx; if (!ivdesc->initExpr->IsZero()) { - addmeexpr.SetOpnd(0, ivdesc->initExpr); - addmeexpr.SetOpnd(1, mulx); - addx = func->GetIRMap()->HashMeExpr(addmeexpr); + addMeExpr.SetOpnd(0, ivdesc->initExpr); + addMeExpr.SetOpnd(1, mulx); + addx = func->GetIRMap()->HashMeExpr(addMeExpr); } AssignMeStmt *ass = func->GetIRMap()->CreateAssignMeStmt(*phi->GetLHS(), *addx, *headBB); headBB->PrependMeStmt(ass); @@ -427,16 +436,16 @@ void IVCanon::ReplaceSecondaryIVPhis() { } void IVCanon::PerformIVCanon() { - BB *headbb = aloop->head; + BB *headBB = aloop->head; uint32 phiOpndIdxOfInit = 1; uint32 phiOpndIdxOfLoopBack = 0; - if (aloop->loopBBs.count(headbb->GetPred(0)->GetBBId()) == 0) { + if (aloop->loopBBs.count(headBB->GetPred(0)->GetBBId()) == 0) { phiOpndIdxOfInit = 0; phiOpndIdxOfLoopBack = 1; } - CHECK_FATAL(aloop->tail == headbb->GetPred(phiOpndIdxOfLoopBack), "PerformIVCanon: tail BB inaccurate"); + CHECK_FATAL(aloop->tail == headBB->GetPred(phiOpndIdxOfLoopBack), "PerformIVCanon: tail BB inaccurate"); // go thru the list of phis at the loop head to find all IVs - for (std::pair mapEntry: headbb->GetMePhiList()) { + for (std::pair mapEntry: headBB->GetMePhiList()) { OriginalSt *ost = ssatab->GetOriginalStFromID(mapEntry.first); if (!ost->IsIVCandidate()) { continue; @@ -450,8 +459,9 @@ void IVCanon::PerformIVCanon() { } FindPrimaryIV(); if (DEBUGFUNC(func)) { - LogInfo::MapleLogger() << "****** while loop at label " << "@" << func->GetMirFunc()->GetLabelName(headbb->GetBBLabel()); - LogInfo::MapleLogger() << ", BB id:" << headbb->GetBBId() << " has IVs:" << endl; + LogInfo::MapleLogger() << "****** while loop at label " << "@" + << func->GetMirFunc()->GetLabelName(headBB->GetBBLabel()); + LogInfo::MapleLogger() << ", BB id:" << headBB->GetBBId() << " has IVs:" << endl; for (uint32 i = 0; i < ivvec.size(); i++) { IVDesc *ivdesc = ivvec[i]; ivdesc->ost->Dump(); @@ -484,14 +494,14 @@ AnalysisResult *DoLfoIVCanon::Run(MeFunction *func, MeFuncResultMgr *m, ModuleRe MeIRMap *irmap = static_cast(m->GetAnalysisResult(MeFuncPhase_IRMAPBUILD, func)); ASSERT(irmap != nullptr, "hssamap has problem"); - IdentifyLoops *identloops = static_cast(m->GetAnalysisResult(MeFuncPhase_MELOOP, func)); - CHECK_FATAL(identloops != nullptr, "identloops has problem"); + IdentifyLoops *identLoops = static_cast(m->GetAnalysisResult(MeFuncPhase_MELOOP, func)); + CHECK_FATAL(identLoops != nullptr, "identloops has problem"); LfoFunction *lfoFunc = func->GetLfoFunc(); // loop thru all the loops in reverse order so inner loops are processed first - for (int32 i = identloops->GetMeLoops().size()-1; i >= 0; i--) { - LoopDesc *aloop = identloops->GetMeLoops()[i]; + for (int32 i = identLoops->GetMeLoops().size()-1; i >= 0; i--) { + LoopDesc *aloop = identLoops->GetMeLoops()[i]; BB *headbb = aloop->head; // check if the label has associated LfoWhileInfo if (headbb->GetBBLabel() == 0) { @@ -529,5 +539,4 @@ AnalysisResult *DoLfoIVCanon::Run(MeFunction *func, MeFuncResultMgr *m, ModuleRe return nullptr; } - } // namespace maple diff --git a/src/mapleall/maple_me/src/lfo_mir_lower.cpp b/src/mapleall/maple_me/src/lfo_mir_lower.cpp index a164c2114437b21d05a3210f3943427cf1aa0148..87c26d4f2bf71faa8af92887ddfa570864b65725 100644 --- a/src/mapleall/maple_me/src/lfo_mir_lower.cpp +++ b/src/mapleall/maple_me/src/lfo_mir_lower.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) [2021] Huawei Technologies Co., Ltd. All rights reserved. * * OpenArkCompiler is licensed under the Mulan Permissive Software License v2. * You can use this software according to the terms and conditions of the MulanPSL - 2.0. diff --git a/src/mapleall/maple_me/src/lfo_pre_emit.cpp b/src/mapleall/maple_me/src/lfo_pre_emit.cpp index 5553ab5ffbfb9a123ac15a0690d4fde75f50992c..355ef60196665692ae176a94b27cad44f1a7f208 100644 --- a/src/mapleall/maple_me/src/lfo_pre_emit.cpp +++ b/src/mapleall/maple_me/src/lfo_pre_emit.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) [2020] Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) [2021] Huawei Technologies Co., Ltd. All rights reserved. * * OpenArkCompiler is licensed under the Mulan Permissive Software License v2. * You can use this software according to the terms and conditions of the MulanPSL - 2.0. @@ -281,7 +281,7 @@ StmtNode* LfoPreEmitter::EmitLfoStmt(MeStmt *mestmt, LfoParentPart *parent) { case OP_goto: { GotoMeStmt *gotoStmt = static_cast(mestmt); if (lfoFunc->LabelCreatedByLfo(gotoStmt->GetOffset())) { - return NULL; + return nullptr; } LfoGotoNode *gto = codeMP->New(OP_goto, parent); gto->SetOffset(gotoStmt->GetOffset()); diff --git a/src/mapleall/maple_me/src/me_critical_edge.cpp b/src/mapleall/maple_me/src/me_critical_edge.cpp index 2dcaf9894f10b67808643d5d1d5cc6f2a5ab2890..0d5cbd8bf7020805f5a1eb95edd940a66bb43fb1 100644 --- a/src/mapleall/maple_me/src/me_critical_edge.cpp +++ b/src/mapleall/maple_me/src/me_critical_edge.cpp @@ -172,7 +172,7 @@ void MeDoSplitCEdge::BreakCriticalEdge(MeFunction &func, BB &pred, BB &succ) con AnalysisResult *MeDoSplitCEdge::Run(MeFunction *func, MeFuncResultMgr *m, ModuleResultMgr*) { MeCFG *cfg = func->GetCfg(); - if (cfg == NULL) { + if (cfg == nullptr) { cfg = static_cast(m->GetAnalysisResult(MeFuncPhase_MECFG, func)); } std::vector> criticalEdge; diff --git a/src/mapleall/maple_me/src/me_hdse.cpp b/src/mapleall/maple_me/src/me_hdse.cpp index 0b7832ff98adc0b86cbfabea8445da751b70d2e9..69de2a716b509eb6585eda6ba2db62aa244d5585 100644 --- a/src/mapleall/maple_me/src/me_hdse.cpp +++ b/src/mapleall/maple_me/src/me_hdse.cpp @@ -51,6 +51,20 @@ // up the CFG. namespace maple { +// mark initExpr in whileinfo live +void MeHDSE::ProcessWhileInfos() { + LfoFunction *lfoFunc = func.GetLfoFunc(); + if (lfoFunc == nullptr) { + return; + } + MapleMap::iterator it = lfoFunc->label2WhileInfo.begin(); + for (; it != lfoFunc->label2WhileInfo.end(); it++) { + if (it->second->initExpr != nullptr && it->second->initExpr->GetMeOp() != maple::kMeOpConst) { + workList.push_front(it->second->initExpr); + } + } +} + void MeHDSE::BackwardSubstitution() { for (DassignMeStmt *dass : backSubsCands) { ScalarMeExpr *rhsscalar = static_cast(dass->GetRHS()); diff --git a/src/mapleall/maple_me/src/me_ssa.cpp b/src/mapleall/maple_me/src/me_ssa.cpp index 3c7f1add16163cb2d55c135a891ab0ed314157fc..023ee9c67bc3b0943f2c1ec5ea0044159b50ece7 100644 --- a/src/mapleall/maple_me/src/me_ssa.cpp +++ b/src/mapleall/maple_me/src/me_ssa.cpp @@ -150,15 +150,15 @@ void MeSSA::InsertIdentifyAssignments(IdentifyLoops *identloops) { MIRType *mirtype = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ost->GetTyIdx()); if (ost->IsSymbolOst()) { AddrofNode *dread = func->GetMirFunc()->GetCodeMempool()->New(OP_dread, - mirtype->GetPrimType(), ost->GetMIRSymbol()->GetStIdx(), ost->GetFieldID()); + mirtype->GetPrimType(), ost->GetMIRSymbol()->GetStIdx(), ost->GetFieldID()); AddrofSSANode *ssadread = func->GetMirFunc()->GetCodeMempool()->New(*dread); ssadread->SetSSAVar(*ssatab->GetVersionStTable().GetZeroVersionSt(ost)); DassignNode *dass = mirbuilder->CreateStmtDassign(*ost->GetMIRSymbol(), ost->GetFieldID(), ssadread); aloop->exitBB->PrependStmtNode(dass); - MayDefPartWithVersionSt *thessapart = - ssatab->GetStmtsSSAPart().GetSSAPartMp()->New(&ssatab->GetStmtsSSAPart().GetSSAPartAlloc()); + MayDefPartWithVersionSt *thessapart = ssatab->GetStmtsSSAPart().GetSSAPartMp()->New( + &ssatab->GetStmtsSSAPart().GetSSAPartAlloc()); ssatab->GetStmtsSSAPart().SetSSAPartOf(*dass, thessapart); thessapart->SetSSAVar(*ssatab->GetVersionStTable().GetZeroVersionSt(ost)); } else { @@ -177,7 +177,8 @@ void MeSSA::InsertIdentifyAssignments(IdentifyLoops *identloops) { ssatab->AddDefBB4Ost(ost->GetIndex(), aloop->exitBB->GetBBId()); } if (eDebug) { - LogInfo::MapleLogger() << "****** Identity assignments inserted at loop exit BB " << aloop->exitBB->GetBBId() << std::endl; + LogInfo::MapleLogger() << "****** Identity assignments inserted at loop exit BB " + << aloop->exitBB->GetBBId() << "\n"; } } } diff --git a/src/mapleall/maple_me/src/me_stmt_pre.cpp b/src/mapleall/maple_me/src/me_stmt_pre.cpp index 757707a7cda5a66f3e4c34c9014d791d69b7357f..5e8b3ed4b376c8351316f35ddf4b26b8af7e62e2 100644 --- a/src/mapleall/maple_me/src/me_stmt_pre.cpp +++ b/src/mapleall/maple_me/src/me_stmt_pre.cpp @@ -781,7 +781,7 @@ PreStmtWorkCand *MeStmtPre::CreateStmtRealOcc(MeStmt &meStmt, int seqStmt) { return wkCand; } // workCand not yet created; create a new one and add to workList - wkCand = ssaPreMemPool->New(ssaPreAllocator, workList.size(), meStmt, GetPUIdx()); + wkCand = ssaPreMemPool->New(ssaPreAllocator, meStmt, GetPUIdx()); wkCand->SetHasLocalOpnd(true); // dummy workList.push_back(wkCand); wkCand->AddRealOccAsLast(*newOcc, GetPUIdx()); diff --git a/src/mapleall/maple_me/src/orig_symbol.cpp b/src/mapleall/maple_me/src/orig_symbol.cpp index 0a1153c5a410db8f18324ba3b95bb775f249f6d1..19ddeaaf7451f5162f23020bfc114d42739989d6 100644 --- a/src/mapleall/maple_me/src/orig_symbol.cpp +++ b/src/mapleall/maple_me/src/orig_symbol.cpp @@ -31,6 +31,9 @@ bool OriginalSt::Equal(const OriginalSt &ost) const { void OriginalSt::Dump() const { if (IsSymbolOst()) { LogInfo::MapleLogger() << (symOrPreg.mirSt->IsGlobal() ? "$" : "%") << symOrPreg.mirSt->GetName(); + if (!offset.IsInvalid()) { + LogInfo::MapleLogger() << "{" << "offset:" << offset.val << "}"; + } if (fieldID != 0) { LogInfo::MapleLogger() << "{" << fieldID << "}"; } @@ -77,6 +80,31 @@ OriginalSt *OriginalStTable::FindOrCreateSymbolOriginalSt(MIRSymbol &mirst, PUId return originalStVector[it->second]; } +OriginalSt *OriginalStTable::CreateSymbolOriginalSt(MIRSymbol &mirSt, PUIdx puIdx, FieldID fld, const TyIdx &tyIdx, + const OffsetType &offset) { + auto *ost = alloc.GetMemPool()->New(originalStVector.size(), mirSt, puIdx, fld, alloc); + ost->SetOffset(offset); + ost->SetTyIdx(tyIdx); + ost->SetIsFinal(mirSt.IsFinal()); + ost->SetIsPrivate(mirSt.IsPrivate()); + originalStVector.push_back(ost); + mirSt2Ost[SymbolFieldPair(mirSt.GetStIdx(), fld, offset)] = ost->GetIndex(); + return ost; +} + +std::pair OriginalStTable::FindOrCreateSymbolOriginalSt(MIRSymbol &mirst, PUIdx pidx, + FieldID fld, const TyIdx &tyIdx, const OffsetType &offset) { + auto it = mirSt2Ost.find(SymbolFieldPair(mirst.GetStIdx(), fld, offset)); + if (it == mirSt2Ost.end()) { + // create a new OriginalSt + auto *newOst = CreateSymbolOriginalSt(mirst, pidx, fld, tyIdx, offset); + return std::make_pair(newOst, true); + } + CHECK_FATAL(it->second < originalStVector.size(), + "index out of range in OriginalStTable::FindOrCreateSymbolOriginalSt"); + return std::make_pair(originalStVector[it->second], false); +} + OriginalSt *OriginalStTable::FindOrCreatePregOriginalSt(PregIdx regidx, PUIdx pidx) { auto it = preg2Ost.find(regidx); return (it == preg2Ost.end()) ? CreatePregOriginalSt(regidx, pidx) diff --git a/src/mapleall/maple_me/src/prop.cpp b/src/mapleall/maple_me/src/prop.cpp index b1d1edf9fb8e30ab4924ebd31fb515924430e6de..9f1a6920df883f4dffb422a4b43fa321da4f89d0 100644 --- a/src/mapleall/maple_me/src/prop.cpp +++ b/src/mapleall/maple_me/src/prop.cpp @@ -394,7 +394,7 @@ MeExpr &Prop::PropReg(RegMeExpr ®MeExpr, bool atParm) const { return regMeExpr; } -MeExpr &Prop::PropIvar(IvarMeExpr &ivarMeExpr) const { +MeExpr &Prop::PropIvar(IvarMeExpr &ivarMeExpr) { IassignMeStmt *defStmt = ivarMeExpr.GetDefStmt(); if (defStmt == nullptr || ivarMeExpr.IsVolatile()) { return ivarMeExpr; @@ -403,6 +403,21 @@ MeExpr &Prop::PropIvar(IvarMeExpr &ivarMeExpr) const { if (rhs.GetDepth() <= kPropTreeLevel && Propagatable(rhs, utils::ToRef(defStmt->GetBB()), false)) { return rhs; } + if (mirModule.IsCModule() && ivarMeExpr.GetPrimType() != PTY_agg) { + auto *tmpReg = irMap.CreateRegMeExpr(ivarMeExpr); + + // create new verstStack for new RegMeExpr + ASSERT(vstLiveStackVec.size() == tmpReg->GetOstIdx(), "there is prev created ost not tracked"); + auto *verstStack = propMapAlloc.GetMemPool()->New>(propMapAlloc.Adapter()); + verstStack->push(tmpReg); + vstLiveStackVec.push_back(verstStack); + + auto newRHS = CheckTruncation(&ivarMeExpr, &rhs); + auto *regassign = irMap.CreateAssignMeStmt(*tmpReg, *newRHS, *defStmt->GetBB()); + defStmt->SetRHS(tmpReg); + defStmt->GetBB()->InsertMeStmtBefore(defStmt, regassign); + return *tmpReg; + } return ivarMeExpr; } diff --git a/src/mapleall/maple_me/src/ssa_pre.cpp b/src/mapleall/maple_me/src/ssa_pre.cpp index 12b46830f57ef3f3ad73f3fb314bef84896c9b92..855af1e8ce28c3c89d730fe26c3adf7b87514404 100644 --- a/src/mapleall/maple_me/src/ssa_pre.cpp +++ b/src/mapleall/maple_me/src/ssa_pre.cpp @@ -1293,7 +1293,6 @@ MeRealOcc *SSAPre::CreateRealOcc(MeStmt &meStmt, int seqStmt, MeExpr &meExpr, bo newOcc->SetIsLHS(isLHS); if (wkCand != nullptr) { if (isRebuilt) { - CHECK_FATAL(wkCand->GetIndex() >= reBuiltOccIndex, "new ssapre work candidate is found as old work candidate"); // insert to realOccs in dt_preorder of the BBs and seq in each BB wkCand->AddRealOccSorted(*dom, *newOcc, GetPUIdx()); } else { @@ -1302,7 +1301,7 @@ MeRealOcc *SSAPre::CreateRealOcc(MeStmt &meStmt, int seqStmt, MeExpr &meExpr, bo return newOcc; } // workcand not yet created; create a new one and add to worklist - wkCand = ssaPreMemPool->New(ssaPreAllocator, workList.size(), &meExpr, GetPUIdx()); + wkCand = ssaPreMemPool->New(ssaPreAllocator, &meExpr, GetPUIdx()); wkCand->SetHasLocalOpnd(CheckIfAnyLocalOpnd(meExpr)); if (EpreLocalRefVar() && wkCand->GetTheMeExpr()->GetMeOp() == kMeOpIvar) { // set wkCand->NeedLocalRefVar() flag @@ -1613,6 +1612,7 @@ void SSAPre::ApplySSAPRE() { break; } workCand = workList.front(); + workCand->SetIndex(static_cast(cnt)); workList.pop_front(); if (workCand->GetRealOccs().empty()) { continue; diff --git a/src/mapleall/mpl2mpl/src/simplify.cpp b/src/mapleall/mpl2mpl/src/simplify.cpp index 664dabea84da80f7a05ea9f77fd2492c717aad93..4352ccddddc3040371c71a051dc976694d0025cb 100644 --- a/src/mapleall/mpl2mpl/src/simplify.cpp +++ b/src/mapleall/mpl2mpl/src/simplify.cpp @@ -22,16 +22,12 @@ constexpr char kFuncNamePrefixOfMathSqrt[] = "Ljava_2Flang_2FMath_3B_7Csqrt_7C_2 constexpr char kFuncNamePrefixOfMathAbs[] = "Ljava_2Flang_2FMath_3B_7Cabs_7C"; constexpr char kFuncNamePrefixOfMathMax[] = "Ljava_2Flang_2FMath_3B_7Cmax_7C"; constexpr char kFuncNamePrefixOfMathMin[] = "Ljava_2Flang_2FMath_3B_7Cmin_7C"; -constexpr char kFuncNameOfMathSqrt[] = "sqrt"; constexpr char kFuncNameOfMathAbs[] = "abs"; -constexpr char kFuncNameOfMathMax[] = "max"; -constexpr char kFuncNameOfMathMin[] = "min"; } // namespace namespace maple { bool Simplify::IsMathSqrt(const std::string funcName) { - return (mirMod.IsCModule() && (strcmp(funcName.c_str(), kFuncNameOfMathSqrt) == 0)) || - (mirMod.IsJavaModule() && (strcmp(funcName.c_str(), kFuncNamePrefixOfMathSqrt) == 0)); + return (mirMod.IsJavaModule() && (strcmp(funcName.c_str(), kFuncNamePrefixOfMathSqrt) == 0)); } bool Simplify::IsMathAbs(const std::string funcName) { @@ -40,13 +36,11 @@ bool Simplify::IsMathAbs(const std::string funcName) { } bool Simplify::IsMathMax(const std::string funcName) { - return (mirMod.IsCModule() && (strcmp(funcName.c_str(), kFuncNameOfMathMax) == 0)) || - (mirMod.IsJavaModule() && (strcmp(funcName.c_str(), kFuncNamePrefixOfMathMax) == 0)); + return (mirMod.IsJavaModule() && (strcmp(funcName.c_str(), kFuncNamePrefixOfMathMax) == 0)); } bool Simplify::IsMathMin(const std::string funcName) { - return (mirMod.IsCModule() && (strcmp(funcName.c_str(), kFuncNameOfMathMin) == 0)) || - (mirMod.IsJavaModule() && (strcmp(funcName.c_str(), kFuncNamePrefixOfMathMin) == 0)); + return (mirMod.IsJavaModule() && (strcmp(funcName.c_str(), kFuncNamePrefixOfMathMin) == 0)); } bool Simplify::SimplifyMathMethod(const StmtNode &stmt, BlockNode &block) { diff --git a/src/mplfe/ast_input/include/ast_decl.h b/src/mplfe/ast_input/include/ast_decl.h index ea54ea55ef8dd7b1d47c926751cc8eb8d8d7ae22..c5c52d34c3909fd951081ff08af121a832f4a001 100644 --- a/src/mplfe/ast_input/include/ast_decl.h +++ b/src/mplfe/ast_input/include/ast_decl.h @@ -31,7 +31,8 @@ enum DeclKind { kASTFunc, kASTStruct, kASTVar, - kASTLocalEnumDecl, + kASTEnumConstant, + kASTEnumDecl, }; class ASTDecl { @@ -210,24 +211,40 @@ class ASTVar : public ASTDecl { ASTExpr *initExpr = nullptr; }; +class ASTEnumConstant : public ASTDecl { + public: + ASTEnumConstant(const std::string &srcFile, const std::string &nameIn, const std::vector &typeDescIn, + const GenericAttrs &genAttrsIn) + : ASTDecl(srcFile, nameIn, typeDescIn) { + genAttrs = genAttrsIn; + declKind = kASTEnumConstant; + } + ~ASTEnumConstant() = default; + + void SetValue(int32 val); + int32 GetValue() const; + private: + MIRConst *Translate2MIRConstImpl() const override; + int32 value = 0; +}; + // only process local `EnumDecl` here -class ASTLocalEnumDecl : public ASTDecl { +class ASTEnumDecl : public ASTDecl { public: - ASTLocalEnumDecl(const std::string &srcFile, const std::string &nameIn, const std::vector &typeDescIn, + ASTEnumDecl(const std::string &srcFile, const std::string &nameIn, const std::vector &typeDescIn, const GenericAttrs &genAttrsIn) : ASTDecl(srcFile, nameIn, typeDescIn) { genAttrs = genAttrsIn; - declKind = kASTLocalEnumDecl; + declKind = kASTEnumDecl; } - ~ASTLocalEnumDecl() = default; + ~ASTEnumDecl() = default; - void PushConstantVar(ASTVar *var) { - vars.emplace_back(var); + void PushConstant(ASTEnumConstant *c) { + consts.emplace_back(c); } private: - void GenerateInitStmtImpl(std::list &stmts) override; - std::list vars; + std::list consts; }; } // namespace maple #endif // MPLFE_AST_INPUT_INCLUDE_AST_DECL_H diff --git a/src/mplfe/ast_input/include/ast_decl_builder.h b/src/mplfe/ast_input/include/ast_decl_builder.h index 39e49afa15b17d339ba6e15ab8f7df908427310c..efa3137e4e6de438117118951e48511d4ad84abf 100644 --- a/src/mplfe/ast_input/include/ast_decl_builder.h +++ b/src/mplfe/ast_input/include/ast_decl_builder.h @@ -46,15 +46,26 @@ class ASTDeclsBuilder { return static_cast(declesTable[id]); } - static ASTLocalEnumDecl *ASTLocalEnumDeclBuilder(MapleAllocator &allocator, const std::string &srcFile, + static ASTEnumConstant *ASTEnumConstBuilder(MapleAllocator &allocator, const std::string &srcFile, + const std::string &varName, const std::vector &desc, + const GenericAttrs &genAttrsIn, int64 id = INT64_MAX) { + if (id == INT64_MAX) { + return allocator.GetMemPool()->New(srcFile, varName, desc, genAttrsIn); + } else if (declesTable[id] == nullptr) { + declesTable[id] = allocator.GetMemPool()->New(srcFile, varName, desc, genAttrsIn); + } + return static_cast(declesTable[id]); + } + + static ASTEnumDecl *ASTLocalEnumDeclBuilder(MapleAllocator &allocator, const std::string &srcFile, const std::string &varName, const std::vector &desc, const GenericAttrs &genAttrsIn, int64 id = INT64_MAX) { if (id == INT64_MAX) { - return allocator.GetMemPool()->New(srcFile, varName, desc, genAttrsIn); + return allocator.GetMemPool()->New(srcFile, varName, desc, genAttrsIn); } else if (declesTable[id] == nullptr) { - declesTable[id] = allocator.GetMemPool()->New(srcFile, varName, desc, genAttrsIn); + declesTable[id] = allocator.GetMemPool()->New(srcFile, varName, desc, genAttrsIn); } - return static_cast(declesTable[id]); + return static_cast(declesTable[id]); } static ASTFunc *ASTFuncBuilder(MapleAllocator &allocator, const std::string &srcFile, const std::string &nameIn, diff --git a/src/mplfe/ast_input/include/ast_expr.h b/src/mplfe/ast_input/include/ast_expr.h index 1068cf9b3591f2cf5bcbf2f3ba646a89d210f3ce..8dae6b6d3f0f3281f2f30241ba861667ec020764 100644 --- a/src/mplfe/ast_input/include/ast_expr.h +++ b/src/mplfe/ast_input/include/ast_expr.h @@ -31,6 +31,10 @@ struct ASTValue { } val = { 0 }; PrimType pty = PTY_begin; + PrimType GetPrimType() const { + return pty; + } + MIRConst *Translate2MIRConst() const; }; @@ -47,7 +51,7 @@ class ASTExpr { UniqueFEIRExpr Emit2FEExpr(std::list &stmts) const; UniqueFEIRExpr ImplicitInitFieldValue(MIRType *type, std::list &stmts) const; - virtual MIRType *GetType() { + virtual MIRType *GetType() const { return mirType; } @@ -104,6 +108,8 @@ class ASTExpr { return refedDecl; } + virtual UniqueFEIRExpr CreateZeroExprCompare(UniqueFEIRExpr feExpr, Opcode op) const; + ASTOp op; MIRType *mirType = nullptr; ASTDecl *refedDecl = nullptr; @@ -127,10 +133,6 @@ class ASTCastExpr : public ASTExpr { return child; } - MIRType *GetType() override { - return child->GetType(); - } - void SetSrcType(MIRType *type) { src = type; } @@ -224,6 +226,11 @@ class ASTUnaryOperatorExpr : public ASTExpr { explicit ASTUnaryOperatorExpr(ASTOp o) : ASTExpr(o) {} ~ASTUnaryOperatorExpr() = default; void SetUOExpr(ASTExpr*); + + ASTExpr *GetUOExpr() const { + return expr; + } + void SetSubType(MIRType *type); MIRType *GetMIRType() { @@ -270,6 +277,9 @@ class ASTUOMinusExpr: public ASTUnaryOperatorExpr { ASTUOMinusExpr() : ASTUnaryOperatorExpr(kASTOpMinus) {} ~ASTUOMinusExpr() = default; + protected: + MIRConst *GenerateMIRConstImpl() const override; + private: UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; }; @@ -462,12 +472,30 @@ class ASTCompoundLiteralExpr : public ASTExpr { ASTCompoundLiteralExpr() : ASTExpr(kASTOpCompoundLiteralExp) {} ~ASTCompoundLiteralExpr() = default; void SetCompoundLiteralType(MIRType *clType); + + MIRType *GetCompoundLiteralType() const { + return compoundLiteralType; + } + void SetASTExpr(ASTExpr*); + ASTExpr* GetASTExpr() const { + return child; + } + + void SetInitName(std::string argInitName) { + initName = argInitName; + } + + std::string GetInitName() const { + return initName; + } + private: UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; ASTExpr *child = nullptr; MIRType *compoundLiteralType; + std::string initName; }; class ASTOffsetOfExpr : public ASTExpr { @@ -640,13 +668,13 @@ class ASTBinaryOperatorExpr : public ASTExpr { cvtNeeded = needed; } - MIRType *SelectBinaryOperatorType(UniqueFEIRExpr &left, UniqueFEIRExpr &right) const; + UniqueFEIRType SelectBinaryOperatorType(UniqueFEIRExpr &left, UniqueFEIRExpr &right) const; protected: MIRConst *GenerateMIRConstImpl() const override; UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; - Opcode opcode; + Opcode opcode = OP_undef; MIRType *retType = nullptr; MIRType *complexElementType = nullptr; ASTExpr *leftExpr = nullptr; @@ -685,7 +713,7 @@ class ASTStringLiteral : public ASTExpr { type = srcType; } - MIRType *GetType() override { + MIRType *GetType() const override { return type; } @@ -734,19 +762,11 @@ class ASTArraySubscriptExpr : public ASTExpr { } void SetIdxExpr(ASTExpr *astExpr) { - idxExprs.push_back(astExpr); + idxExpr = astExpr; } - std::vector GetIdxExpr() const { - return idxExprs; - } - - void SetBaseExprType(MIRType *ty) { - baseExprTypes.emplace_back(ty); - } - - const std::vector &GetBaseExprType() const { - return baseExprTypes; + ASTExpr *GetIdxExpr() const { + return idxExpr; } void SetArrayType(MIRType *ty) { @@ -757,15 +777,26 @@ class ASTArraySubscriptExpr : public ASTExpr { return arrayType; } - int32 TranslateArraySubscript2Offset() const; + int32 CalculateOffset() const; + + void SetIsVLA(bool flag) { + isVLA = flag; + } + + void SetVLASizeExprs(std::vector &exprs) { + vlaSizeExprs = exprs; + } private: + ASTExpr *FindFinalBase() const; + MIRConst *GenerateMIRConstImpl() const override; bool CheckFirstDimIfZero() const; UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; ASTExpr *baseExpr = nullptr; - mutable MIRType *arrayType = nullptr; - std::vector baseExprTypes; - mutable std::vector idxExprs; + MIRType *arrayType = nullptr; + ASTExpr *idxExpr = nullptr; + bool isVLA = false; + std::vector vlaSizeExprs; }; class ASTExprUnaryExprOrTypeTraitExpr : public ASTExpr { @@ -837,9 +868,13 @@ class ASTMemberExpr : public ASTExpr { return isArrow; } - ASTMemberExpr *findFinalMember(ASTMemberExpr *startExpr, std::list &memberNames) const; + const ASTMemberExpr *FindFinalMember(const ASTMemberExpr *startExpr, std::list &memberNames) const; + + const ASTExpr *FindFinalBase() const; + int32 CalculateOffset(MIRStructType &baseStructType) const; private: + MIRConst *GenerateMIRConstImpl() const override; UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; ASTExpr *baseExpr = nullptr; std::string memberName; @@ -1023,8 +1058,18 @@ class ASTParenExpr : public ASTExpr { child = astExpr; } + protected: + MIRConst *GenerateMIRConstImpl() const override { + return child->GenerateMIRConst(); + } + private: UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; + + ASTValue *GetConstantValueImpl() const override { + return child->GetConstantValue(); + } + ASTExpr *child = nullptr; }; @@ -1083,6 +1128,7 @@ class ASTFloatingLiteral : public ASTExpr { private: UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; + MIRConst *GenerateMIRConstImpl() const override; double val; FloatKind kind; }; @@ -1147,6 +1193,9 @@ class ASTConstantExpr : public ASTExpr { child = astExpr; } + protected: + MIRConst *GenerateMIRConstImpl() const override; + private: ASTExpr *child = nullptr; UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; @@ -1306,7 +1355,7 @@ class ASTAtomicExpr : public ASTExpr { atomicOp = op; } - MIRType *GetType() override { + MIRType *GetType() const override { return type; } diff --git a/src/mplfe/ast_input/include/ast_op.h b/src/mplfe/ast_input/include/ast_op.h index cc4f125711dc0667180d5043bdd80605c6e57813..70ee298a2b8ad41132aee90f0c0803c09886af54 100644 --- a/src/mplfe/ast_input/include/ast_op.h +++ b/src/mplfe/ast_input/include/ast_op.h @@ -164,6 +164,7 @@ enum ASTStmtOp { kASTStmtCallExpr, kASTStmtAtomicExpr, kASTStmtGCCAsmStmt, + kASTOffsetOfStmt, }; } // namespace maple #endif // MPLFE_AST_INPUT_INCLUDE_AST_OP_H diff --git a/src/mplfe/ast_input/include/ast_parser.h b/src/mplfe/ast_input/include/ast_parser.h index bbec4012a7e68847a7e6e8295877296c4c3f9e84..fc873f890011e76cdcdb4d2d47928c1900cfaf6e 100644 --- a/src/mplfe/ast_input/include/ast_parser.h +++ b/src/mplfe/ast_input/include/ast_parser.h @@ -39,7 +39,6 @@ class ASTParser { bool RetrieveFuncs(MapleAllocator &allocator); bool RetrieveGlobalVars(MapleAllocator &allocator); - bool ProcessGlobalEnums(MapleAllocator &allocator); bool ProcessGlobalTypeDef(MapleAllocator &allocator); const std::string &GetSourceFileName() const; @@ -81,6 +80,7 @@ class ASTParser { ASTStmt *PROCESS_STMT(DeclStmt); ASTStmt *PROCESS_STMT(AtomicExpr); ASTStmt *PROCESS_STMT(GCCAsmStmt); + ASTStmt *PROCESS_STMT(OffsetOfExpr); bool HasDefault(const clang::Stmt &stmt); // ProcessExpr @@ -172,6 +172,7 @@ ASTExpr *ParseBuiltinFunc(MapleAllocator &allocator, const clang::CallExpr &expr ASTExpr *PARSE_BUILTIIN_FUNC(ConstantP); ASTExpr *PARSE_BUILTIIN_FUNC(Signbit); ASTExpr *PARSE_BUILTIIN_FUNC(Isinfsign); + ASTExpr *PARSE_BUILTIIN_FUNC(HugeVal); static std::map builtingFuncPtrMap; uint32 fileIdx; diff --git a/src/mplfe/ast_input/include/ast_stmt.h b/src/mplfe/ast_input/include/ast_stmt.h index 4a7ac948748d102559294ac10be3279b8a36407b..ee8f3cb87a3221969f35fa13af643103f30c3188 100644 --- a/src/mplfe/ast_input/include/ast_stmt.h +++ b/src/mplfe/ast_input/include/ast_stmt.h @@ -302,11 +302,16 @@ class ASTSwitchStmt : public ASTStmt { return hasDefualt; } + void SetCondType(MIRType *type) { + condType = type; + } + private: std::list Emit2FEStmtImpl() const override; - ASTStmt *condStmt; - ASTExpr *condExpr; - ASTStmt *bodyStmt; + ASTStmt *condStmt = nullptr; + ASTExpr *condExpr = nullptr; + ASTStmt *bodyStmt = nullptr; + MIRType *condType = nullptr; bool hasDefualt = false; }; @@ -573,5 +578,14 @@ class ASTGCCAsmStmt : public ASTStmt { std::vector clobbers; // Not parsing asm label here, asm label info is enclosed in `Decl attr` }; + +class ASTOffsetOfStmt : public ASTStmt { + public: + ASTOffsetOfStmt() : ASTStmt(kASTOffsetOfStmt) {} + ~ASTOffsetOfStmt() override = default; + + private: + std::list Emit2FEStmtImpl() const override; +}; } // namespace maple #endif // MPLFE_AST_INPUT_INCLUDE_AST_STMT_H diff --git a/src/mplfe/ast_input/lib/ast_interface.cpp b/src/mplfe/ast_input/lib/ast_interface.cpp index f55e0ddb0ff0b8960c3f06f74cf77ca70753fb15..984a2cb8c2fe7f518d029951c16f0afdffbe8608 100644 --- a/src/mplfe/ast_input/lib/ast_interface.cpp +++ b/src/mplfe/ast_input/lib/ast_interface.cpp @@ -291,6 +291,15 @@ const std::string LibAstFile::GetOrCreateMappedUnnamedName(uint32_t id) { return unnamedSymbolMap[id]; } +const std::string LibAstFile::GetOrCreateCompoundLiteralExprInitName(uint32_t id) { + std::map::iterator it = CompoundLiteralExprInitSymbolMap.find(id); + if (it == CompoundLiteralExprInitSymbolMap.end()) { + const std::string name = FEUtils::GetSequentialName("unNamedInit"); + CompoundLiteralExprInitSymbolMap[id] = name; + } + return CompoundLiteralExprInitSymbolMap[id]; +} + void LibAstFile::EmitTypeName(const clang::RecordType &recoType, std::stringstream &ss) { clang::RecordDecl *recoDecl = recoType.getDecl(); std::string str = recoType.desugar().getAsString(); diff --git a/src/mplfe/ast_input/lib/ast_interface.h b/src/mplfe/ast_input/lib/ast_interface.h index 92674bc35b3d4d81b89e6d8de5e42b1bf0e536a5..fb6b348a2ea488d0d12e5e4d6ab1b0881225de44 100644 --- a/src/mplfe/ast_input/lib/ast_interface.h +++ b/src/mplfe/ast_input/lib/ast_interface.h @@ -42,6 +42,7 @@ class LibAstFile { AstUnitDecl *GetAstUnitDecl(); std::string GetMangledName(const clang::NamedDecl &decl); const std::string GetOrCreateMappedUnnamedName(uint32_t id); + const std::string GetOrCreateCompoundLiteralExprInitName(uint32_t id); void EmitTypeName(const clang::QualType qualType, std::stringstream &ss); void EmitTypeName(const clang::RecordType &qualType, std::stringstream &ss); @@ -87,6 +88,7 @@ class LibAstFile { RecordDeclMap recordDeclMap; std::set recordDeclSet; std::map unnamedSymbolMap; + std::map CompoundLiteralExprInitSymbolMap; MIRModule *module; MapleList &recordDecles; diff --git a/src/mplfe/ast_input/lib/ast_type.cpp b/src/mplfe/ast_input/lib/ast_type.cpp index ee3f942b5a242b42e20ba854d67c411cdb50a198..99e54110ee6e398698b0d0ec8aafdedf5cba0223 100644 --- a/src/mplfe/ast_input/lib/ast_type.cpp +++ b/src/mplfe/ast_input/lib/ast_type.cpp @@ -71,7 +71,6 @@ PrimType LibAstFile::CvtPrimType(const clang::BuiltinType::Kind kind) const { return PTY_f64; case clang::BuiltinType::LongDouble: case clang::BuiltinType::Float128: - WARN(kLncWarn, "True Type is Float128, cvt double, but it is not exact"); return PTY_f64; case clang::BuiltinType::NullPtr: // default 64-bit, need to update return PTY_a64; @@ -117,7 +116,9 @@ MIRType *LibAstFile::CvtOtherType(const clang::QualType srcType) { } else if (srcType->isFunctionType()) { destType = CvtFunctionType(srcType); } else if (srcType->isEnumeralType()) { - destType = GlobalTables::GetTypeTable().GetInt32(); + const clang::EnumType *enumTy = llvm::dyn_cast(srcType); + clang::QualType qt = enumTy->getDecl()->getIntegerType(); + destType = CvtType(qt); } else if (srcType->isAtomicType()) { const auto *atomicType = llvm::cast(srcType); destType = CvtType(atomicType->getValueType()); @@ -129,8 +130,11 @@ MIRType *LibAstFile::CvtOtherType(const clang::QualType srcType) { MIRType *LibAstFile::CvtRecordType(const clang::QualType srcType) { const auto *recordType = llvm::cast(srcType); clang::RecordDecl *recordDecl = recordType->getDecl(); - if (!recordDecl->isLambda() && recordDecl->isImplicit() && recordDeclSet.emplace(recordDecl).second == true) { - recordDecles.emplace_back(recordDecl); + if (!recordDecl->isLambda() && recordDeclSet.emplace(recordDecl).second == true) { + auto itor = std::find(recordDecles.begin(), recordDecles.end(), recordDecl); + if (itor == recordDecles.end()) { + recordDecles.emplace_back(recordDecl); + } } MIRStructType *type = nullptr; std::stringstream ss; diff --git a/src/mplfe/ast_input/src/ast_decl.cpp b/src/mplfe/ast_input/src/ast_decl.cpp index 62e31cd4237d86494236305548473dd4a8e28b5d..182b3a0c0592ac2822d5637a85717d8fd54ca65f 100644 --- a/src/mplfe/ast_input/src/ast_decl.cpp +++ b/src/mplfe/ast_input/src/ast_decl.cpp @@ -126,11 +126,18 @@ void ASTVar::GenerateInitStmtImpl(std::list &stmts) { stmts.emplace_back(std::move(stmt)); } -// ---------- ASTLocalEnumDecl ---------- -void ASTLocalEnumDecl::GenerateInitStmtImpl(std::list &stmts) { - for (auto var : vars) { - var->GenerateInitStmt(stmts); - } +// ---------- ASTEnumConstant ---------- +void ASTEnumConstant::SetValue(int32 val) { + value = val; +} + +int32 ASTEnumConstant::GetValue() const { + return value; +} + +MIRConst *ASTEnumConstant::Translate2MIRConstImpl() const { + return GlobalTables::GetIntConstTable().GetOrCreateIntConst( + value, *GlobalTables::GetTypeTable().GetPrimType(PTY_i32)); } // ---------- ASTFunc --------- diff --git a/src/mplfe/ast_input/src/ast_expr.cpp b/src/mplfe/ast_input/src/ast_expr.cpp index baa5ff6b9d52415bcaf3ac3001629de58b5f9561..e24c7278967fb604ef82a22be87d8d37cdbbaf06 100644 --- a/src/mplfe/ast_input/src/ast_expr.cpp +++ b/src/mplfe/ast_input/src/ast_expr.cpp @@ -116,6 +116,13 @@ MIRConst *ASTExpr::GenerateMIRConstImpl() const { return value->Translate2MIRConst(); } +UniqueFEIRExpr ASTExpr::CreateZeroExprCompare(UniqueFEIRExpr feExpr, Opcode op) const { + UniqueFEIRExpr zeroConstExpr = (feExpr->GetPrimType() == PTY_ptr) ? + FEIRBuilder::CreateExprConstPtrNull() : + FEIRBuilder::CreateExprConstAnyScalar(feExpr->GetPrimType(), 0); + return FEIRBuilder::CreateExprMathBinary(op, feExpr->Clone(), std::move(zeroConstExpr)); +} + // ---------- ASTDeclRefExpr --------- MIRConst *ASTDeclRefExpr::GenerateMIRConstImpl() const { MIRType *mirType = refedDecl->GetTypeDesc().front(); @@ -127,6 +134,12 @@ MIRConst *ASTDeclRefExpr::GenerateMIRConstImpl() const { MIRFunction *mirFunc = funcSymbol->GetFunction(); CHECK_FATAL(mirFunc != nullptr, "Same name symbol with function: %s", refedDecl->GetName().c_str()); return FEManager::GetModule().GetMemPool()->New(mirFunc->GetPuidx(), *mirType); + } else if (!isConstantFolded) { + ASTDecl *var = refedDecl; + MIRSymbol *mirSymbol = FEManager::GetMIRBuilder().GetOrCreateGlobalDecl( + var->GenerateUniqueVarName(), *(var->GetTypeDesc().front())); + return FEManager::GetModule().GetMemPool()->New( + mirSymbol->GetStIdx(), 0, *(var->GetTypeDesc().front())); } else { return GetConstantValue()->Translate2MIRConst(); } @@ -140,6 +153,10 @@ UniqueFEIRExpr ASTDeclRefExpr::Emit2FEExprImpl(std::list &stmts) static_cast(mirType)->GetPointedType()->GetKind() == kTypeFunction) { feirRefExpr = FEIRBuilder::CreateExprAddrofFunc(refedDecl->GetName()); } else { + if (refedDecl->GetDeclKind() == kASTEnumConstant) { + return FEIRBuilder::CreateExprConstAnyScalar(refedDecl->GetTypeDesc().front()->GetPrimType(), + static_cast(refedDecl)->GetValue()); + } UniqueFEIRVar feirVar = FEIRBuilder::CreateVarNameForC(refedDecl->GenerateUniqueVarName(), *mirType, refedDecl->IsGlobal(), false); feirVar->SetAttrs(attrs); @@ -441,6 +458,31 @@ void ASTUnaryOperatorExpr::SetSubType(MIRType *type) { subType = type; } +MIRConst *ASTUOMinusExpr::GenerateMIRConstImpl() const { + auto unsignedConst = GetUOExpr()->GenerateMIRConst(); + switch (unsignedConst->GetKind()) { + case kConstInt: { + auto value = static_cast(unsignedConst)->GetValue(); + return FEManager::GetModule().GetMemPool()->New( + value*(-1), *GlobalTables::GetTypeTable().GetPrimType(PTY_i64)); // -1 is neg + } + case kConstFloatConst: { + auto value = static_cast(unsignedConst)->GetValue(); + return FEManager::GetModule().GetMemPool()->New( + value*(-1.0f), *GlobalTables::GetTypeTable().GetPrimType(PTY_f32)); // -1.0f is neg + } + case kConstDoubleConst: { + auto value = static_cast(unsignedConst)->GetValue(); + return FEManager::GetModule().GetMemPool()->New( + value*(-1.0), *GlobalTables::GetTypeTable().GetPrimType(PTY_f64)); // -1.0 is neg + } + default: { + CHECK_FATAL(false, "Unsupported yet"); + return nullptr; + } + } +} + UniqueFEIRExpr ASTUOMinusExpr::Emit2FEExprImpl(std::list &stmts) const { ASTExpr *childExpr = expr; CHECK_FATAL(childExpr != nullptr, "childExpr is nullptr"); @@ -524,26 +566,29 @@ UniqueFEIRExpr ASTUOPreDecExpr::Emit2FEExprImpl(std::list &stmts MIRConst *ASTUOAddrOfExpr::GenerateMIRConstImpl() const { switch (expr->GetASTOp()) { - case kASTOpRef: { - ASTDecl *var = static_cast(expr)->GetASTDecl(); - MIRSymbol *mirSymbol = FEManager::GetMIRBuilder().GetOrCreateGlobalDecl( - var->GenerateUniqueVarName(), *(var->GetTypeDesc().front())); - MIRAddrofConst *konst = FEManager::GetModule().GetMemPool()->New( - mirSymbol->GetStIdx(), 0, *(var->GetTypeDesc().front())); - return konst; - } - case kASTSubscriptExpr: { - ASTDecl *var = static_cast(expr)->GetBaseExpr()->GetASTDecl(); - MIRSymbol *mirSymbol = FEManager::GetMIRBuilder().GetOrCreateGlobalDecl( - var->GenerateUniqueVarName(), *(var->GetTypeDesc().front())); - int32 offset = static_cast(expr)->TranslateArraySubscript2Offset(); - MIRAddrofConst *konst = FEManager::GetModule().GetMemPool()->New( - mirSymbol->GetStIdx(), 0, *(var->GetTypeDesc().front()), offset); - return konst; - } + case kASTOpCompoundLiteralExp: { + auto astCompoundLiteralExpr = static_cast(expr); + // CompoundLiteral Symbol + MIRSymbol *compoundLiteralMirSymbol = FEManager::GetMIRBuilder().GetOrCreateGlobalDecl( + astCompoundLiteralExpr->GetInitName(), + *astCompoundLiteralExpr->GetCompoundLiteralType()); + + auto child = static_cast(expr)->GetASTExpr(); + auto mirConst = child->GenerateMIRConst(); // InitListExpr in CompoundLiteral gen struct + compoundLiteralMirSymbol->SetKonst(mirConst); + + MIRAddrofConst *mirAddrofConst = FEManager::GetModule().GetMemPool()->New( + compoundLiteralMirSymbol->GetStIdx(), 0, *astCompoundLiteralExpr->GetCompoundLiteralType()); + return mirAddrofConst; + } + case kASTOpRef: + case kASTSubscriptExpr: case kASTMemberExpr: { - CHECK_FATAL(false, "MemberExpr and SubscriptExpr nested NIY"); - return nullptr; + return expr->GenerateMIRConst(); + } + case kASTStringLiteral: { + return FEManager::GetModule().GetMemPool()->New( + expr->GetConstantValue()->val.strIdx, *GlobalTables::GetTypeTable().GetPrimType(PTY_a64)); } default: { CHECK_FATAL(false, "lValue in expr: %d NIY", expr->GetASTOp()); @@ -562,10 +607,13 @@ UniqueFEIRExpr ASTUOAddrOfExpr::Emit2FEExprImpl(std::list &stmts static_cast(childFEIRExpr.get())->GetVar()->Clone(), childFEIRExpr->GetFieldID()); } else if (childFEIRExpr->GetKind() == kExprIRead) { auto ireadExpr = static_cast(childFEIRExpr.get()); + if (ireadExpr->GetFieldID() == 0) { + return ireadExpr->GetClonedOpnd(); + } addrOfExpr = std::make_unique(ireadExpr->GetClonedPtrType(), ireadExpr->GetFieldID(), ireadExpr->GetClonedOpnd()); } else if (childFEIRExpr->GetKind() == kExprIAddrof || childFEIRExpr->GetKind() == kExprAddrofVar || - childFEIRExpr->GetKind() == kExprAddrofFunc) { + childFEIRExpr->GetKind() == kExprAddrofFunc || childFEIRExpr->GetKind() == kExprAddrof) { return childFEIRExpr; } else { CHECK_FATAL(false, "unsupported expr kind %d", childFEIRExpr->GetKind()); @@ -781,10 +829,14 @@ UniqueFEIRExpr ASTOffsetOfExpr::Emit2FEExprImpl(std::list &stmts // ---------- ASTInitListExpr ---------- MIRConst *ASTInitListExpr::GenerateMIRConstImpl() const { - if (!initListType->IsStructType()) { + if (initListType->GetKind() == kTypeArray) { return GenerateMIRConstForArray(); - } else { + } else if (initListType->GetKind() == kTypeStruct || initListType->GetKind() == kTypeUnion) { return GenerateMIRConstForStruct(); + } else if (isTransparent) { + return initExprs[0]->GenerateMIRConst(); + } else { + CHECK_FATAL(false, "not handle now"); } } @@ -1093,27 +1145,49 @@ UniqueFEIRExpr ASTStringLiteral::Emit2FEExprImpl(std::list &stmt } // ---------- ASTArraySubscriptExpr ---------- -int32 ASTArraySubscriptExpr::TranslateArraySubscript2Offset() const { +int32 ASTArraySubscriptExpr::CalculateOffset() const { int32 offset = 0; - for (std::size_t i = 0; i < idxExprs.size(); ++i) { - CHECK_FATAL(idxExprs[i]->GetConstantValue() != nullptr, "Not constant value for constant initializer"); - offset += baseExprTypes[i]->GetSize() * idxExprs[i]->GetConstantValue()->val.i64; - } + CHECK_FATAL(idxExpr->GetConstantValue() != nullptr, "Not constant value for constant initializer"); + offset += mirType->GetSize() * idxExpr->GetConstantValue()->val.i64; return offset; } +ASTExpr *ASTArraySubscriptExpr::FindFinalBase() const { + if (baseExpr->GetASTOp() == kASTSubscriptExpr) { + return static_cast(baseExpr)->FindFinalBase(); + } + return baseExpr; +} + +MIRConst *ASTArraySubscriptExpr::GenerateMIRConstImpl() const { + int32 offset = CalculateOffset(); + const ASTExpr *base = FindFinalBase(); + MIRConst *baseConst = base->GenerateMIRConst(); + if (baseConst->GetKind() == kConstStrConst) { + MIRStrConst *strConst = static_cast(baseConst); + std::string str = GlobalTables::GetUStrTable().GetStringFromStrIdx(strConst->GetValue()); + CHECK_FATAL(str.length() >= static_cast(offset), "Invalid operation"); + str = str.substr(offset); + UStrIdx strIdx = GlobalTables::GetUStrTable().GetOrCreateStrIdxFromName(str); + return FEManager::GetModule().GetMemPool()->New( + strIdx, *GlobalTables::GetTypeTable().GetPrimType(PTY_a64)); + } else if (baseConst->GetKind() == kConstAddrof) { + MIRAddrofConst *konst = static_cast(baseConst); + return FEManager::GetModule().GetMemPool()->New(konst->GetSymbolIndex(), konst->GetFieldID(), + konst->GetType(), konst->GetOffset() + offset); + } else { + CHECK_FATAL(false, "Unsupported MIRConst: %d", baseConst->GetKind()); + } +} + bool ASTArraySubscriptExpr::CheckFirstDimIfZero() const { - bool needChange = false; auto tmpArrayType = static_cast(arrayType); uint32 size = tmpArrayType->GetSizeArrayItem(0); - uint32 oriDim = idxExprs.size(); + uint32 oriDim = tmpArrayType->GetDim(); if (size == 0 && oriDim >= 2) { // 2 is the array dim - arrayType = GlobalTables::GetTypeTable().GetOrCreateArrayType(*tmpArrayType->GetElemType(), - tmpArrayType->GetSizeArrayItem(1)); - idxExprs.pop_back(); - needChange = true; + return true; } - return needChange; + return false; } UniqueFEIRExpr ASTArraySubscriptExpr::Emit2FEExprImpl(std::list &stmts) const { @@ -1125,28 +1199,32 @@ UniqueFEIRExpr ASTArraySubscriptExpr::Emit2FEExprImpl(std::list UniqueFEIRExpr addrOfArray; if (arrayType->GetKind() == MIRTypeKind::kTypeArray) { if(CheckFirstDimIfZero()) { - arrayFEType = std::make_unique(*arrayType); + // return multi-dim array addr directly if its first dim size was 0. + return baseAddrFEExpr; } std::list feIdxExprs; - for (auto idxExpr : idxExprs) { - auto feIdxExpr = idxExpr->Emit2FEExpr(stmts); - feIdxExprs.push_front(std::move(feIdxExpr)); - } + auto feIdxExpr = idxExpr->Emit2FEExpr(stmts); + feIdxExprs.push_front(std::move(feIdxExpr)); addrOfArray = FEIRBuilder::CreateExprAddrofArray(arrayFEType->Clone(), std::move(baseAddrFEExpr), "", feIdxExprs); } else { std::vector offsetExprs; UniqueFEIRExpr offsetExpr; auto sizeType = std::make_unique(*GlobalTables::GetTypeTable().GetPrimType(PTY_u64)); - for (int i = 0; i < idxExprs.size(); i++) { - auto feIdxExpr = idxExprs[i]->Emit2FEExpr(stmts); - auto feSizeExpr = FEIRBuilder::CreateExprConstU64(baseExprTypes[i]->GetSize()); - if (feIdxExpr->GetPrimType() != PTY_i64) { - feIdxExpr = FEIRBuilder::CreateExprCvtPrim(std::move(feIdxExpr), PTY_i64); - } - auto feOffsetExpr = FEIRBuilder::CreateExprBinary(sizeType->Clone(), OP_mul, std::move(feIdxExpr), - std::move(feSizeExpr)); - offsetExprs.emplace_back(std::move(feOffsetExpr)); + + auto feIdxExpr = idxExpr->Emit2FEExpr(stmts); + UniqueFEIRExpr feSizeExpr; + if (isVLA) { + feSizeExpr = vlaSizeExprs[0]->Emit2FEExpr(stmts); + } else { + feSizeExpr = FEIRBuilder::CreateExprConstU64(mirType->GetSize()); + } + if (feIdxExpr->GetPrimType() != PTY_i64) { + feIdxExpr = FEIRBuilder::CreateExprCvtPrim(std::move(feIdxExpr), PTY_i64); } + auto feOffsetExpr = FEIRBuilder::CreateExprBinary(sizeType->Clone(), OP_mul, std::move(feIdxExpr), + std::move(feSizeExpr)); + offsetExprs.emplace_back(std::move(feOffsetExpr)); + if (offsetExprs.size() == 1) { offsetExpr = std::move(offsetExprs[0]); } else if (offsetExprs.size() >= 2) { @@ -1170,12 +1248,46 @@ UniqueFEIRExpr ASTExprUnaryExprOrTypeTraitExpr::Emit2FEExprImpl(std::list &memberNames) const { + +MIRConst *ASTMemberExpr::GenerateMIRConstImpl() const { + const ASTExpr *base = FindFinalBase(); + MIRAddrofConst *konst = static_cast(base->GenerateMIRConst()); + MIRType *baseStructType = + base->GetType()->IsMIRPtrType() ? static_cast(base->GetType())->GetPointedType() : + base->GetType(); + CHECK_FATAL(baseStructType->IsMIRStructType() || baseStructType->GetKind() == kTypeUnion, "Invalid"); + int32 offset = CalculateOffset(static_cast(*baseStructType)); + return FEManager::GetModule().GetMemPool()->New(konst->GetSymbolIndex(), konst->GetFieldID(), + konst->GetType(), konst->GetOffset() + offset); +} + +int32 ASTMemberExpr::CalculateOffset(MIRStructType &baseStructType) const { + int32 offset = 0; + FieldID id = FEManager::GetMIRBuilder().GetStructFieldIDFromFieldName(baseStructType, memberName); + for (int32 i = 0; i < id; ++i) { + if (baseStructType.GetFieldType(i)->IsMIRStructType() || baseStructType.GetFieldType(i)->GetKind() == kTypeUnion) { + continue; + } + offset += std::max(static_cast(baseStructType.GetFieldType(i)->GetSize()), + static_cast(baseStructType.GetFieldType(i)->GetAlign())); + } + return offset; +} + +const ASTExpr *ASTMemberExpr::FindFinalBase() const { + if (baseExpr->GetASTOp() == kASTMemberExpr) { + return static_cast(baseExpr)->FindFinalBase(); + } + return baseExpr; +} + +const ASTMemberExpr *ASTMemberExpr::FindFinalMember(const ASTMemberExpr *startExpr, + std::list &memberNames) const { memberNames.emplace_back(startExpr->memberName); if (startExpr->isArrow || startExpr->baseExpr->GetASTOp() != kASTMemberExpr) { return startExpr; } - return findFinalMember(static_cast(startExpr->baseExpr), memberNames); + return FindFinalMember(static_cast(startExpr->baseExpr), memberNames); } UniqueFEIRExpr ASTMemberExpr::Emit2FEExprImpl(std::list &stmts) const { @@ -1187,7 +1299,7 @@ UniqueFEIRExpr ASTMemberExpr::Emit2FEExprImpl(std::list &stmts) if (baseExpr->GetASTOp() == kASTMemberExpr) { std::list memberNameList; memberNameList.emplace_back(memberName); - ASTMemberExpr *finalMember = findFinalMember(static_cast(baseExpr), memberNameList); + const ASTMemberExpr *finalMember = FindFinalMember(static_cast(baseExpr), memberNameList); baseFEExpr = finalMember->baseExpr->Emit2FEExpr(stmts); isArrow = finalMember->isArrow; baseType = finalMember->baseType; @@ -1248,8 +1360,37 @@ UniqueFEIRExpr ASTDesignatedInitUpdateExpr::Emit2FEExprImpl(std::listGenerateMIRConst(); - auto rightConst = rightExpr->GenerateMIRConst(); + MIRConst *leftConst = leftExpr->GenerateMIRConst(); + MIRConst *rightConst = nullptr; + + if (opcode == OP_lior) { + if (!leftConst->IsZero()) { + return GlobalTables::GetIntConstTable().GetOrCreateIntConst(1, + *GlobalTables::GetTypeTable().GetPrimType(PTY_i32)); + } else { + rightConst = rightExpr->GenerateMIRConst(); + if (!rightConst->IsZero()) { + return GlobalTables::GetIntConstTable().GetOrCreateIntConst(1, + *GlobalTables::GetTypeTable().GetPrimType(PTY_i32)); + } else { + return GlobalTables::GetIntConstTable().GetOrCreateIntConst(0, + *GlobalTables::GetTypeTable().GetPrimType(PTY_i32)); + } + } + } + rightConst = rightExpr->GenerateMIRConst(); + if (opcode == OP_land) { + if (leftConst->IsZero()) { + return GlobalTables::GetIntConstTable().GetOrCreateIntConst(0, + *GlobalTables::GetTypeTable().GetPrimType(PTY_i32)); + } else if (rightConst->IsZero()) { + return GlobalTables::GetIntConstTable().GetOrCreateIntConst(0, + *GlobalTables::GetTypeTable().GetPrimType(PTY_i32)); + } else { + return GlobalTables::GetIntConstTable().GetOrCreateIntConst(1, + *GlobalTables::GetTypeTable().GetPrimType(PTY_i32)); + } + } if (leftConst->GetKind() == rightConst->GetKind()) { switch (leftConst->GetKind()) { case kConstInt: { @@ -1307,8 +1448,9 @@ MIRConst *ASTBinaryOperatorExpr::GenerateMIRConstImpl() const { return nullptr; } -MIRType *ASTBinaryOperatorExpr::SelectBinaryOperatorType(UniqueFEIRExpr &left, UniqueFEIRExpr &right) const { - std::map BinaryTypePriority = { +UniqueFEIRType ASTBinaryOperatorExpr::SelectBinaryOperatorType(UniqueFEIRExpr &left, UniqueFEIRExpr &right) const { + // For arithmetical calculation only + std::map binaryTypePriority = { {PTY_u1, 0}, {PTY_i8, 1}, {PTY_u8, 2}, @@ -1321,15 +1463,29 @@ MIRType *ASTBinaryOperatorExpr::SelectBinaryOperatorType(UniqueFEIRExpr &left, U {PTY_f32, 9}, {PTY_f64, 10} }; + UniqueFEIRType feirType = std::make_unique(*retType); + if (!cvtNeeded) { + return feirType; + } + if (binaryTypePriority.find(left->GetPrimType()) == binaryTypePriority.end() || + binaryTypePriority.find(right->GetPrimType()) == binaryTypePriority.end()) { + if (left->GetPrimType() != feirType->GetPrimType()) { + left = FEIRBuilder::CreateExprCvtPrim(std::move(left), feirType->GetPrimType()); + } + if (right->GetPrimType() != feirType->GetPrimType()) { + right = FEIRBuilder::CreateExprCvtPrim(std::move(right), feirType->GetPrimType()); + } + return feirType; + } MIRType *dstType; - if (BinaryTypePriority[left->GetPrimType()] > BinaryTypePriority[right->GetPrimType()]) { + if (binaryTypePriority[left->GetPrimType()] > binaryTypePriority[right->GetPrimType()]) { right = FEIRBuilder::CreateExprCvtPrim(std::move(right), left->GetPrimType()); dstType = left->GetType()->GenerateMIRTypeAuto(); } else { left = FEIRBuilder::CreateExprCvtPrim(std::move(left), right->GetPrimType()); dstType = right->GetType()->GenerateMIRTypeAuto(); } - return dstType; + return std::make_unique(*dstType); } UniqueFEIRExpr ASTBinaryOperatorExpr::Emit2FEExprImpl(std::list &stmts) const { @@ -1379,7 +1535,8 @@ UniqueFEIRExpr ASTBinaryOperatorExpr::Emit2FEExprImpl(std::list std::string labelName = FEUtils::GetSequentialName("shortCircuit_label_"); auto leftFEExpr = leftExpr->Emit2FEExpr(stmts); - auto leftStmt = std::make_unique(shortCircuit->Clone(), leftFEExpr->Clone(), 0); + auto leftCond = CreateZeroExprCompare(std::move(leftFEExpr), OP_ne); + auto leftStmt = std::make_unique(shortCircuit->Clone(), leftCond->Clone(), 0); stmts.emplace_back(std::move(leftStmt)); auto dreadExpr = FEIRBuilder::CreateExprDRead(shortCircuit->Clone()); @@ -1387,7 +1544,8 @@ UniqueFEIRExpr ASTBinaryOperatorExpr::Emit2FEExprImpl(std::list stmts.emplace_back(std::move(condGoToExpr)); auto rightFEExpr = rightExpr->Emit2FEExpr(stmts); - auto rightStmt = std::make_unique(shortCircuit->Clone(), rightFEExpr->Clone(), 0); + auto rightCond = CreateZeroExprCompare(std::move(rightFEExpr), OP_ne); + auto rightStmt = std::make_unique(shortCircuit->Clone(), rightCond->Clone(), 0); stmts.emplace_back(std::move(rightStmt)); auto labelStmt = std::make_unique(labelName); @@ -1400,13 +1558,7 @@ UniqueFEIRExpr ASTBinaryOperatorExpr::Emit2FEExprImpl(std::list } else { auto leftFEExpr = leftExpr->Emit2FEExpr(stmts); auto rightFEExpr = rightExpr->Emit2FEExpr(stmts); - UniqueFEIRType feirType; - if (cvtNeeded) { - MIRType *dstType = SelectBinaryOperatorType(leftFEExpr, rightFEExpr); - feirType = std::make_unique(*dstType); - } else { - feirType = std::make_unique(*retType); - } + UniqueFEIRType feirType = SelectBinaryOperatorType(leftFEExpr, rightFEExpr); return FEIRBuilder::CreateExprBinary(std::move(feirType), opcode, std::move(leftFEExpr), std::move(rightFEExpr)); } } @@ -1494,6 +1646,20 @@ UniqueFEIRExpr ASTIntegerLiteral::Emit2FEExprImpl(std::list &stm } // ---------- ASTFloatingLiteral ---------- +MIRConst *ASTFloatingLiteral::GenerateMIRConstImpl() const { + MemPool *mp = FEManager::GetManager().GetModule().GetMemPool(); + MIRConst *cst; + MIRType *type; + if (kind == F32) { + type = GlobalTables::GetTypeTable().GetPrimType(PTY_f32); + cst = mp->New(static_cast(val), *type); + } else { + type = GlobalTables::GetTypeTable().GetPrimType(PTY_f64); + cst = mp->New(val, *type); + } + return cst; +} + UniqueFEIRExpr ASTFloatingLiteral::Emit2FEExprImpl(std::list &stmts) const { UniqueFEIRExpr expr; if (kind == F32) { @@ -1560,6 +1726,14 @@ UniqueFEIRExpr ASTConstantExpr::Emit2FEExprImpl(std::list &stmts return nullptr; } +MIRConst *ASTConstantExpr::GenerateMIRConstImpl() const { + if (child->GetConstantValue()->GetPrimType() == PTY_begin) { + return child->GenerateMIRConst(); + } else { + return child->GetConstantValue()->Translate2MIRConst(); + } +} + // ---------- ASTImaginaryLiteral ---------- UniqueFEIRExpr ASTImaginaryLiteral::Emit2FEExprImpl(std::list &stmts) const { CHECK_NULL_FATAL(complexType); @@ -1838,7 +2012,14 @@ UniqueFEIRExpr ASTExprStmtExpr::Emit2FEExprImpl(std::list &stmts lastCpdStmt = static_cast(bodyStmt); } if (lastCpdStmt->GetASTStmtList().size() != 0 && lastCpdStmt->GetASTStmtList().back()->GetExprs().size() != 0) { - return lastCpdStmt->GetASTStmtList().back()->GetExprs().back()->Emit2FEExpr(stmts0); + UniqueFEIRExpr feirExpr = lastCpdStmt->GetASTStmtList().back()->GetExprs().back()->Emit2FEExpr(stmts0); + for (int i = 0; i < stmts0.size(); ++i) { + stmts.pop_back(); + } + for (auto &stmt : stmts0) { + stmts.emplace_back(std::move(stmt)); + } + return feirExpr; } return nullptr; } diff --git a/src/mplfe/ast_input/src/ast_input.cpp b/src/mplfe/ast_input/src/ast_input.cpp index 4ee5fbf09bfc23b54a987bb148fd40d6d8fc6c4a..72d2084e313ce342ffca17e7318bb97259b480fd 100644 --- a/src/mplfe/ast_input/src/ast_input.cpp +++ b/src/mplfe/ast_input/src/ast_input.cpp @@ -27,7 +27,6 @@ bool ASTInput::ReadASTFile(MapleAllocator &allocatorIn, uint32 index, const std: TRY_DO(astParser->OpenFile()); TRY_DO(astParser->Verify()); TRY_DO(astParser->PreProcessAST()); - TRY_DO(astParser->ProcessGlobalEnums(allocatorIn)); // Some implicit record decl would be retrieved in func body at use, // so we put `RetrieveFuncs` before `RetrieveStructs` TRY_DO(astParser->RetrieveFuncs(allocatorIn)); diff --git a/src/mplfe/ast_input/src/ast_parser.cpp b/src/mplfe/ast_input/src/ast_parser.cpp index 9b340fa33cd4cfd00974cd60eec161951f60dc2c..913075141ae2e616e5c851ec2f011108ef88a7e2 100644 --- a/src/mplfe/ast_input/src/ast_parser.cpp +++ b/src/mplfe/ast_input/src/ast_parser.cpp @@ -123,6 +123,7 @@ ASTStmt *ASTParser::ProcessStmt(MapleAllocator &allocator, const clang::Stmt &st STMT_CASE(NullStmt); STMT_CASE(AtomicExpr); STMT_CASE(GCCAsmStmt); + STMT_CASE(OffsetOfExpr); default: { CHECK_FATAL(false, "ASTStmt: %s NIY", stmt.getStmtClassName()); return nullptr; @@ -130,6 +131,17 @@ ASTStmt *ASTParser::ProcessStmt(MapleAllocator &allocator, const clang::Stmt &st } } +ASTStmt *ASTParser::ProcessStmtOffsetOfExpr(MapleAllocator &allocator, const clang::OffsetOfExpr &expr) { + auto *astStmt = ASTDeclsBuilder::ASTStmtBuilder(allocator); + CHECK_FATAL(astStmt != nullptr, "astStmt is nullptr"); + ASTExpr *astExpr = ProcessExpr(allocator, &expr); + if (astExpr == nullptr) { + return nullptr; + } + astStmt->SetASTExpr(astExpr); + return astStmt; +} + ASTStmt *ASTParser::ProcessStmtUnaryOperator(MapleAllocator &allocator, const clang::UnaryOperator &unaryOp) { ASTUnaryOperatorStmt *astUOStmt = ASTDeclsBuilder::ASTStmtBuilder(allocator); CHECK_FATAL(astUOStmt != nullptr, "astUOStmt is nullptr"); @@ -435,6 +447,9 @@ ASTStmt *ASTParser::ProcessStmtSwitchStmt(MapleAllocator &allocator, const clang astStmt->SetCondStmt(condStmt); // switch cond expr ASTExpr *condExpr = switchStmt.getCond() == nullptr ? nullptr : ProcessExpr(allocator, switchStmt.getCond()); + if (condExpr != nullptr) { + astStmt->SetCondType(astFile->CvtType(switchStmt.getCond()->getType())); + } astStmt->SetCondExpr(condExpr); // switch body stmt ASTStmt *bodyStmt = switchStmt.getBody() == nullptr ? nullptr : @@ -639,16 +654,20 @@ ASTValue *ASTParser::TranslateExprEval(MapleAllocator &allocator, const clang::E return astValue; } -#define EXPR_CASE(CLASS) \ - case clang::Stmt::CLASS##Class: { \ - ASTExpr *astExpr = ProcessExpr##CLASS(allocator, llvm::cast(*expr)); \ - if (astExpr == nullptr) { \ - return nullptr; \ - } \ - astExpr->SetConstantValue(TranslateExprEval(allocator, expr)); \ - Pos loc = astFile->GetStmtLOC(*expr); \ - astExpr->SetSrcLOC(loc.first, loc.second); \ - return astExpr; \ +#define EXPR_CASE(CLASS) \ + case clang::Stmt::CLASS##Class: { \ + ASTExpr *astExpr = ProcessExpr##CLASS(allocator, llvm::cast(*expr)); \ + if (astExpr == nullptr) { \ + return nullptr; \ + } \ + MIRType *exprType = astFile->CvtType(expr->getType()); \ + astExpr->SetType(exprType); \ + if (expr->isConstantInitializer(*astFile->GetNonConstAstContext(), false, nullptr)) { \ + astExpr->SetConstantValue(TranslateExprEval(allocator, expr)); \ + } \ + Pos loc = astFile->GetStmtLOC(*expr); \ + astExpr->SetSrcLOC(loc.first, loc.second); \ + return astExpr; \ } ASTExpr *ASTParser::ProcessExpr(MapleAllocator &allocator, const clang::Expr *expr) { @@ -776,13 +795,9 @@ const clang::Expr *ASTParser::PeelParen2(const clang::Expr &expr) { const clang::Expr *exprPtr = &expr; while (llvm::isa(exprPtr) || (llvm::isa(exprPtr) && - llvm::cast(exprPtr)->getOpcode() == clang::UO_Extension) || - (llvm::isa(exprPtr) && - (llvm::cast(exprPtr)->getCastKind() == clang::CK_BitCast))) { + llvm::cast(exprPtr)->getOpcode() == clang::UO_Extension)) { if (llvm::isa(exprPtr)) { exprPtr = llvm::cast(exprPtr)->getSubExpr(); - } else if (llvm::isa(exprPtr)) { - exprPtr = llvm::cast(exprPtr)->getSubExpr(); } else { exprPtr = llvm::cast(exprPtr)->getSubExpr(); } @@ -916,6 +931,9 @@ ASTExpr *ASTParser::ProcessExprCompoundLiteralExpr(MapleAllocator &allocator, if (astExpr == nullptr) { return nullptr; } + static uint32 unNamedCount = 0; + auto initListName = astFile->GetOrCreateCompoundLiteralExprInitName(unNamedCount++); + astCompoundLiteralExpr->SetInitName(initListName); astCompoundLiteralExpr->SetASTExpr(astExpr); return astCompoundLiteralExpr; } @@ -970,34 +988,72 @@ ASTExpr *ASTParser::ProcessExprInitListExpr(MapleAllocator &allocator, const cla return astInitListExpr; } -ASTExpr *ASTParser::ProcessExprOffsetOfExpr(MapleAllocator &allocator, const clang::OffsetOfExpr &expr) {\ - ASTOffsetOfExpr *astOffsetOfExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); - CHECK_FATAL(astOffsetOfExpr != nullptr, "astOffsetOfExpr is nullptr"); - clang::FieldDecl *field = expr.getComponent(0).getField(); - const clang::QualType qualType = field->getParent()->getTypeForDecl()->getCanonicalTypeInternal(); - MIRType *structType = astFile->CvtType(qualType); - astOffsetOfExpr->SetStructType(structType); - std::string filedName = astFile->GetMangledName(*field); - astOffsetOfExpr->SetFieldName(filedName); - const auto *recordType = llvm::cast(qualType); - clang::RecordDecl *recordDecl = recordType->getDecl(); - const clang::ASTRecordLayout &recordLayout = astFile->GetContext()->getASTRecordLayout(recordDecl); - - clang::RecordDecl::field_iterator it; - uint64_t filedIdx = 0; - for (it = recordDecl->field_begin(); it != recordDecl->field_end(); ++it) { - std::string name = (*it)->getNameAsString(); - if (name == filedName) { - filedIdx = (*it)->getFieldIndex(); - break; +ASTExpr *ASTParser::ProcessExprOffsetOfExpr(MapleAllocator &allocator, const clang::OffsetOfExpr &expr) { + if (expr.isEvaluatable(*astFile->GetContext())) { + clang::Expr::EvalResult result; + bool success = expr.EvaluateAsInt(result, *astFile->GetContext()); + if (success) { + auto astExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); + astExpr->SetVal(result.Val.getInt().getExtValue()); + astExpr->SetType(PTY_u64); + return astExpr; } } - CHECK_FATAL(it != recordDecl->field_end(), "cann't find field %s in the struct", filedName.c_str()); - uint64 offsetInBits = recordLayout.getFieldOffset(filedIdx); - size_t offset = offsetInBits >> kBitToByteShift; - astOffsetOfExpr->SetOffset(offset); - - return astOffsetOfExpr; + uint64_t offset = 0; + std::vector vlaOffsetExprs; + for (int i = 0; i < expr.getNumComponents(); i++) { + auto comp = expr.getComponent(i); + if (comp.getKind() == clang::OffsetOfNode::Kind::Field) { + uint filedIdx = comp.getField()->getFieldIndex(); + offset += astFile->GetContext()->getASTRecordLayout(comp.getField()->getParent()).getFieldOffset(filedIdx) + >> kBitToByteShift; + } else if (comp.getKind() == clang::OffsetOfNode::Kind::Array) { + int idx = comp.getArrayExprIndex(); + auto idxExpr = expr.getIndexExpr(idx); + auto arrayType = expr.getComponent(i - 1).getField()->getType(); + auto elementType = llvm::cast(arrayType)->getElementType(); + uint32 elementSize = GetSizeFromQualType(elementType); + auto astSizeExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); + astSizeExpr->SetVal(elementSize); + astSizeExpr->SetType(PTY_u64); + auto astExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); + astExpr->SetOpcode(OP_mul); + astExpr->SetLeftExpr(ProcessExpr(allocator, idxExpr)); + astExpr->SetRightExpr(astSizeExpr); + astExpr->SetRetType(GlobalTables::GetTypeTable().GetPrimType(PTY_u64)); + vlaOffsetExprs.emplace_back(astExpr); + } else { + CHECK_FATAL(false, "NIY"); + } + } + ASTExpr *vlaOffsetExpr = nullptr; + if (vlaOffsetExprs.size() == 1) { + vlaOffsetExpr = vlaOffsetExprs[0]; + } else if (vlaOffsetExprs.size() >= 2) { + auto astExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); + astExpr->SetRetType(GlobalTables::GetTypeTable().GetPrimType(PTY_u64)); + astExpr->SetLeftExpr(vlaOffsetExprs[0]); + astExpr->SetRightExpr(vlaOffsetExprs[1]); + if (vlaOffsetExprs.size() >= 3) { + for (int i = 2; i < vlaOffsetExprs.size(); i++) { + auto astSubExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); + astSubExpr->SetRetType(GlobalTables::GetTypeTable().GetPrimType(PTY_u64)); + astSubExpr->SetLeftExpr(astExpr); + astSubExpr->SetRightExpr(vlaOffsetExprs[i]); + astExpr = astSubExpr; + } + } + vlaOffsetExpr = astExpr; + } + auto astSizeExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); + astSizeExpr->SetVal(offset); + astSizeExpr->SetType(PTY_u64); + auto astExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); + astExpr->SetOpcode(OP_add); + astExpr->SetLeftExpr(astSizeExpr); + astExpr->SetRightExpr(vlaOffsetExpr); + astExpr->SetRetType(GlobalTables::GetTypeTable().GetPrimType(PTY_u64)); + return astExpr; } ASTExpr *ASTParser::ProcessExprVAArgExpr(MapleAllocator &allocator, const clang::VAArgExpr &expr) { @@ -1036,35 +1092,59 @@ ASTExpr *ASTParser::ProcessExprStringLiteral(MapleAllocator &allocator, const cl ASTExpr *ASTParser::ProcessExprArraySubscriptExpr(MapleAllocator &allocator, const clang::ArraySubscriptExpr &expr) { auto *astArraySubscriptExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); CHECK_FATAL(astArraySubscriptExpr != nullptr, "astArraySubscriptExpr is nullptr"); - auto *exprTmp = const_cast(&expr); - auto base = exprTmp->getBase(); - while (exprTmp != nullptr && exprTmp->getStmtClass() == clang::Stmt::ArraySubscriptExprClass) { - base = exprTmp->getBase(); - base = const_cast(PeelParen2(*base)); - MIRType *baseExprType = astFile->CvtType(exprTmp->getType()); - astArraySubscriptExpr->SetBaseExprType(baseExprType); - ASTExpr *idxExpr = ProcessExpr(allocator, exprTmp->getIdx()); - astArraySubscriptExpr->SetIdxExpr(idxExpr); - if (idxExpr == nullptr) { - return nullptr; - } - if (base->getStmtClass() != clang::Stmt::ImplicitCastExprClass) { - break; + auto base = expr.getBase(); + + base = PeelParen2(*base); + ASTExpr *idxExpr = ProcessExpr(allocator, expr.getIdx()); + astArraySubscriptExpr->SetIdxExpr(idxExpr); + + clang::QualType arrayQualType = base->getType().getCanonicalType(); + if (base->getStmtClass() == clang::Stmt::ImplicitCastExprClass && + !static_cast(base)->isPartOfExplicitCast()) { + arrayQualType = static_cast(base)->getSubExpr()->getType().getCanonicalType(); + } + 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); } - if (PeelParen2(*static_cast(base)->getSubExpr())->getStmtClass() != - clang::Stmt::ArraySubscriptExprClass) { - break; + 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(); } - base = const_cast(PeelParen2(*static_cast(base)->getSubExpr())); - exprTmp = static_cast(base); - } - if (base->getStmtClass() == clang::Stmt::ImplicitCastExprClass && - !static_cast(base)->isPartOfExplicitCast()) { - auto arrayMirType = astFile->CvtType( - static_cast(base)->getSubExpr()->getType().getCanonicalType()); - astArraySubscriptExpr->SetArrayType(arrayMirType); - } else { - astArraySubscriptExpr->SetArrayType(astFile->CvtType(base->getType().getCanonicalType())); } ASTExpr *astBaseExpr = ProcessExpr(allocator, base); astArraySubscriptExpr->SetBaseExpr(astBaseExpr); @@ -1115,10 +1195,20 @@ ASTExpr *ASTParser::BuildExprToComputeSizeFromVLA(MapleAllocator &allocator, con if (llvm::isa(qualType)) { ASTExpr *lhs = BuildExprToComputeSizeFromVLA(allocator, llvm::cast(qualType)->getElementType()); ASTExpr *rhs = nullptr; - CHECK_FATAL(llvm::isa(qualType), "the type must be vla type"); - clang::Expr *sizeExpr = llvm::cast(qualType)->getSizeExpr(); - rhs = ProcessExpr(allocator, sizeExpr); - CHECK_FATAL(sizeExpr->getType()->isIntegerType(), "the type should be integer"); + CHECK_FATAL(llvm::isa(qualType), "the type must be array type"); + if (llvm::isa(qualType)) { + clang::Expr *sizeExpr = llvm::cast(qualType)->getSizeExpr(); + rhs = ProcessExpr(allocator, sizeExpr); + CHECK_FATAL(sizeExpr->getType()->isIntegerType(), "the type should be integer"); + } else if (llvm::isa(qualType)) { + uint32 size = llvm::cast(qualType)->getSize().getSExtValue(); + auto astExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); + astExpr->SetVal(size); + astExpr->SetType(PTY_i32); + rhs = astExpr; + } else { + CHECK_FATAL(false, "NIY"); + } auto *astBOExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); astBOExpr->SetRetType(GlobalTables::GetTypeTable().GetPrimType(PTY_u64)); astBOExpr->SetOpcode(OP_mul); @@ -1447,14 +1537,10 @@ ASTExpr *ASTParser::ProcessExprFloatingLiteral(MapleAllocator &allocator, const val = static_cast(apf.convertToFloat()); astFloatingLiteral->SetKind(F32); astFloatingLiteral->SetVal(val); - } else if (&fltSem == &llvm::APFloat::IEEEquad()) { - WARN(kLncWarn, "True Type is Float128, try to get a approximate double, but it is not exact"); - val = static_cast(llvm::cast(expr).getValueAsApproximateDouble()); - astFloatingLiteral->SetKind(F64); - astFloatingLiteral->SetVal(val); - } else if (&fltSem == &llvm::APFloat::x87DoubleExtended()) { - WARN(kLncWarn, "True Type is Float128, try to get a approximate double, but it is not exact"); - val = static_cast(llvm::cast(expr).getValueAsApproximateDouble()); + } else if (&fltSem == &llvm::APFloat::IEEEquad() || &fltSem == &llvm::APFloat::x87DoubleExtended()) { + bool losesInfo; + apf.convert(llvm::APFloat::IEEEdouble(), llvm::APFloatBase::roundingMode::rmNearestTiesToAway, &losesInfo); + val = static_cast(apf.convertToDouble()); astFloatingLiteral->SetKind(F64); astFloatingLiteral->SetVal(val); } else { @@ -1636,7 +1722,7 @@ ASTExpr *ASTParser::ProcessExprBinaryOperator(MapleAllocator &allocator, const c } // ptr +/- if (boType->isPointerType() && clang::BinaryOperator::isAdditiveOp(clangOpCode) && lhsType->isPointerType() && - rhsType->isIntegerType()) { + rhsType->isIntegerType() && !boType->isVoidPointerType()) { auto ptrSizeExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); ptrSizeExpr->SetType(PTY_i32); ptrSizeExpr->SetVal(GetSizeFromQualType(boType->getPointeeType())); @@ -1659,7 +1745,8 @@ ASTExpr *ASTParser::ProcessExprBinaryOperator(MapleAllocator &allocator, const c astBinOpExpr->SetLeftExpr(astLExpr); astBinOpExpr->SetRightExpr(astRExpr); // ptr - ptr - if (clangOpCode == clang::BO_Sub && rhsType->isPointerType() && lhsType->isPointerType()) { + if (clangOpCode == clang::BO_Sub && rhsType->isPointerType() && + lhsType->isPointerType() && !rhsType->isVoidPointerType()) { auto ptrSizeExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); ptrSizeExpr->SetType(astBinOpExpr->GetRetType()->GetPrimType()); ptrSizeExpr->SetVal(GetSizeFromQualType(rhsType->getPointeeType())); @@ -1937,7 +2024,10 @@ ASTDecl *ASTParser::ProcessDeclRecordDecl(MapleAllocator &allocator, const clang } if (!recDecl.isDefinedOutsideFunctionOrMethod()) { // Record function scope type decl in global with unique suffix identified - astStructs.emplace_back(curStructOrUnion); + auto itor = std::find(astStructs.begin(), astStructs.end(), curStructOrUnion); + if (itor == astStructs.end()) { + astStructs.emplace_back(curStructOrUnion); + } } return curStructOrUnion; } @@ -2015,9 +2105,6 @@ ASTDecl *ASTParser::ProcessDeclFieldDecl(MapleAllocator &allocator, const clang: return nullptr; } if (decl.isBitField()) { - if (qualType->isEnumeralType()) { - fieldType = GlobalTables::GetTypeTable().GetUInt32(); - } unsigned bitSize = decl.getBitWidthValue(*(astFile->GetContext())); MIRBitFieldType mirBFType(static_cast(bitSize), fieldType->GetPrimType()); auto bfTypeIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&mirBFType); @@ -2083,7 +2170,7 @@ ASTDecl *ASTParser::ProcessDeclParmVarDecl(MapleAllocator &allocator, const clan } ASTDecl *ASTParser::ProcessDeclEnumDecl(MapleAllocator &allocator, const clang::EnumDecl &enumDecl) { - ASTLocalEnumDecl *localEnumDecl = static_cast(ASTDeclsBuilder::GetASTDecl(enumDecl.getID())); + ASTEnumDecl *localEnumDecl = static_cast(ASTDeclsBuilder::GetASTDecl(enumDecl.getID())); if (localEnumDecl != nullptr) { return localEnumDecl; } @@ -2094,7 +2181,7 @@ ASTDecl *ASTParser::ProcessDeclEnumDecl(MapleAllocator &allocator, const clang:: std::vector{}, attrs, enumDecl.getID()); TraverseDecl(&enumDecl, [&](clang::Decl *child) { CHECK_FATAL(child->getKind() == clang::Decl::EnumConstant, "Unsupported decl kind: %u", child->getKind()); - localEnumDecl->PushConstantVar(static_cast(ProcessDecl(allocator, *child))); + localEnumDecl->PushConstant(static_cast(ProcessDecl(allocator, *child))); }); return localEnumDecl; } @@ -2114,28 +2201,19 @@ ASTDecl *ASTParser::ProcessDeclTypedefDecl(MapleAllocator &allocator, const clan } ASTDecl *ASTParser::ProcessDeclEnumConstantDecl(MapleAllocator &allocator, const clang::EnumConstantDecl &decl) { - ASTVar *astVar = static_cast(ASTDeclsBuilder::GetASTDecl(decl.getID())); - if (astVar != nullptr) { - return astVar; + ASTEnumConstant *astConst = static_cast(ASTDeclsBuilder::GetASTDecl(decl.getID())); + if (astConst != nullptr) { + return astConst; } GenericAttrs attrs; astFile->CollectAttrs(*clang::dyn_cast(&decl), attrs, kPublic); const std::string &varName = clang::dyn_cast(&decl)->getNameAsString(); MIRType *mirType = astFile->CvtType(clang::dyn_cast(&decl)->getType()); - astVar = - ASTDeclsBuilder::ASTVarBuilder(allocator, fileName, varName, std::vector{mirType}, attrs, decl.getID()); - auto constExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); - constExpr->SetVal( - static_cast(clang::dyn_cast(&decl)->getInitVal().getExtValue())); - constExpr->SetType(mirType->GetPrimType()); - - ASTValue *astValue = AllocASTValue(allocator); - astValue->val.i64 = static_cast(clang::dyn_cast(&decl)->getInitVal().getExtValue()); - astValue->pty = PTY_i64; - constExpr->SetConstantValue(astValue); - - astVar->SetInitExpr(constExpr); - return astVar; + astConst = ASTDeclsBuilder::ASTEnumConstBuilder( + allocator, fileName, varName, std::vector{mirType}, attrs, decl.getID()); + + astConst->SetValue(static_cast(clang::dyn_cast(&decl)->getInitVal().getExtValue())); + return astConst; } ASTDecl *ASTParser::ProcessDeclLabelDecl(MapleAllocator &allocator, const clang::LabelDecl &decl) { @@ -2158,7 +2236,11 @@ bool ASTParser::RetrieveStructs(MapleAllocator &allocator) { return false; } curStructOrUnion->SetGlobal(true); - astStructs.emplace_back(curStructOrUnion); + auto itor = std::find(astStructs.begin(), astStructs.end(), curStructOrUnion); + if (itor != astStructs.end()) { + } else { + astStructs.emplace_back(curStructOrUnion); + } } return true; } @@ -2193,15 +2275,6 @@ bool ASTParser::RetrieveGlobalVars(MapleAllocator &allocator) { return true; } -bool ASTParser::ProcessGlobalEnums(MapleAllocator &allocator) { - for (auto gEnumDecl : globalEnumDecles) { - TraverseDecl(gEnumDecl, [&](clang::Decl *child) { - astVars.emplace_back(static_cast(ProcessDecl(allocator, *child))); - }); - } - return true; -} - bool ASTParser::ProcessGlobalTypeDef(MapleAllocator &allocator) { for (auto gTypeDefDecl : globalTypeDefDecles) { (void)ProcessDecl(allocator, *gTypeDefDecl); diff --git a/src/mplfe/ast_input/src/ast_parser_builting_func.cpp b/src/mplfe/ast_input/src/ast_parser_builting_func.cpp index 525ed9bf3b2dc2d33e71d70e000a08d738ea6ef7..294dac9ea505addfe168a5fd30d42145d42ffc72 100644 --- a/src/mplfe/ast_input/src/ast_parser_builting_func.cpp +++ b/src/mplfe/ast_input/src/ast_parser_builting_func.cpp @@ -92,6 +92,7 @@ std::map ASTParser::InitBuiltinFuncP ans["__builtin_constant_p"] = &ASTParser::ParseBuiltinConstantP; ans["__builtin_signbit"] = &ASTParser::ParseBuiltinSignbit; ans["__builtin_isinf_sign"] = &ASTParser::ParseBuiltinIsinfsign; + ans["__builtin_huge_val"] = &ASTParser::ParseBuiltinHugeVal; return ans; } @@ -153,4 +154,12 @@ ASTExpr *ASTParser::ParseBuiltinIsinfsign(MapleAllocator &allocator, const clang } return nullptr; } + +ASTExpr *ASTParser::ParseBuiltinHugeVal(MapleAllocator &allocator, const clang::CallExpr &expr, + std::stringstream &ss) const { + ASTFloatingLiteral *astFloatingLiteral = ASTDeclsBuilder::ASTExprBuilder(allocator); + astFloatingLiteral->SetKind(F64); + astFloatingLiteral->SetVal(std::numeric_limits::infinity()); + return astFloatingLiteral; +} } // namespace maple \ No newline at end of file diff --git a/src/mplfe/ast_input/src/ast_stmt.cpp b/src/mplfe/ast_input/src/ast_stmt.cpp index 50a0939484d4f9db4fa1c9c46a363895a63e6edf..8131668e459ef0367db9f401ac230589bc860708 100644 --- a/src/mplfe/ast_input/src/ast_stmt.cpp +++ b/src/mplfe/ast_input/src/ast_stmt.cpp @@ -90,7 +90,8 @@ std::list ASTForStmt::Emit2FEStmtImpl() const { std::list stmts; std::string loopBodyEndLabelName = FEUtils::GetSequentialName("dowhile_body_end_"); std::string loopEndLabelName = FEUtils::GetSequentialName("dowhile_end_"); - AstLoopUtil::Instance().PushLoop(std::make_pair(loopBodyEndLabelName, loopEndLabelName)); + AstLoopUtil::Instance().PushBreak(loopEndLabelName); + AstLoopUtil::Instance().PushContinue(loopBodyEndLabelName); auto labelBodyEndStmt = std::make_unique(loopBodyEndLabelName); auto labelLoopEndStmt = std::make_unique(loopEndLabelName); if (initStmt != nullptr) { @@ -125,7 +126,8 @@ std::list ASTForStmt::Emit2FEStmtImpl() const { whileStmt->SetSrcFileInfo(GetSrcFileIdx(), GetSrcFileLineNum()); stmts.emplace_back(std::move(whileStmt)); stmts.emplace_back(std::move(labelLoopEndStmt)); - AstLoopUtil::Instance().PopCurrentLoop(); + AstLoopUtil::Instance().PopCurrentBreak(); + AstLoopUtil::Instance().PopCurrentContinue(); return stmts; } @@ -133,7 +135,8 @@ std::list ASTWhileStmt::Emit2FEStmtImpl() const { std::list stmts; std::string loopBodyEndLabelName = FEUtils::GetSequentialName("dowhile_body_end_"); std::string loopEndLabelName = FEUtils::GetSequentialName("dowhile_end_"); - AstLoopUtil::Instance().PushLoop(std::make_pair(loopBodyEndLabelName, loopEndLabelName)); + AstLoopUtil::Instance().PushBreak(loopEndLabelName); + AstLoopUtil::Instance().PushContinue(loopBodyEndLabelName); auto labelBodyEndStmt = std::make_unique(loopBodyEndLabelName); auto labelLoopEndStmt = std::make_unique(loopEndLabelName); std::list bodyFEStmts = bodyStmt->Emit2FEStmt(); @@ -148,7 +151,8 @@ std::list ASTWhileStmt::Emit2FEStmtImpl() const { stmts.splice(stmts.end(), condStmts); stmts.emplace_back(std::move(whileStmt)); stmts.emplace_back(std::move(labelLoopEndStmt)); - AstLoopUtil::Instance().PopCurrentLoop(); + AstLoopUtil::Instance().PopCurrentBreak(); + AstLoopUtil::Instance().PopCurrentContinue(); return stmts; } @@ -156,7 +160,8 @@ std::list ASTDoStmt::Emit2FEStmtImpl() const { std::list stmts; std::string loopBodyEndLabelName = FEUtils::GetSequentialName("dowhile_body_end_"); std::string loopEndLabelName = FEUtils::GetSequentialName("dowhile_end_"); - AstLoopUtil::Instance().PushLoop(std::make_pair(loopBodyEndLabelName, loopEndLabelName)); + AstLoopUtil::Instance().PushBreak(loopEndLabelName); + AstLoopUtil::Instance().PushContinue(loopBodyEndLabelName); auto labelBodyEndStmt = std::make_unique(loopBodyEndLabelName); auto labelLoopEndStmt = std::make_unique(loopEndLabelName); std::list bodyFEStmts; @@ -172,15 +177,16 @@ std::list ASTDoStmt::Emit2FEStmtImpl() const { whileStmt->SetSrcFileInfo(GetSrcFileIdx(), GetSrcFileLineNum()); stmts.emplace_back(std::move(whileStmt)); stmts.emplace_back(std::move(labelLoopEndStmt)); - AstLoopUtil::Instance().PopCurrentLoop(); + AstLoopUtil::Instance().PopCurrentBreak(); + AstLoopUtil::Instance().PopCurrentContinue(); return stmts; } std::list ASTBreakStmt::Emit2FEStmtImpl() const { std::list stmts; auto stmt = std::make_unique(); - if (!AstLoopUtil::Instance().IsLoopLabelsEmpty()) { - stmt->SetLoopLabelName(AstLoopUtil::Instance().GetCurrentLoop().second); + if (!AstLoopUtil::Instance().IsBreakLabelsEmpty()) { + stmt->SetBreakLabelName(AstLoopUtil::Instance().GetCurrentBreak()); } stmt->SetSrcFileInfo(GetSrcFileIdx(), GetSrcFileLineNum()); stmts.emplace_back(std::move(stmt)); @@ -200,7 +206,7 @@ std::list ASTContinueStmt::Emit2FEStmtImpl() const { std::list stmts; auto stmt = std::make_unique(); stmt->SetSrcFileInfo(GetSrcFileIdx(), GetSrcFileLineNum()); - stmt->SetLabelName(AstLoopUtil::Instance().GetCurrentLoop().first); + stmt->SetLabelName(AstLoopUtil::Instance().GetCurrentContinue()); stmts.emplace_back(std::move(stmt)); return stmts; } @@ -239,12 +245,21 @@ std::list ASTIndirectGotoStmt::Emit2FEStmtImpl() const { std::list ASTSwitchStmt::Emit2FEStmtImpl() const { std::list stmts; UniqueFEIRExpr expr = condExpr->Emit2FEExpr(stmts); - auto switchStmt = std::make_unique(std::move(expr), hasDefualt); + std::string exitName = AstSwitchUtil::Instance().CreateEndOrExitLabelName(); + AstLoopUtil::Instance().PushBreak(exitName); + std::string tmpName = FEUtils::GetSequentialName("switch_cond"); + UniqueFEIRVar tmpVar = FEIRBuilder::CreateVarNameForC(tmpName, *condType); + UniqueFEIRStmt condStmt = FEIRBuilder::CreateStmtDAssign(tmpVar->Clone(), std::move(expr)); + stmts.emplace_back(std::move(condStmt)); + auto dread = FEIRBuilder::CreateExprDRead(tmpVar->Clone()); + auto switchStmt = std::make_unique(std::move(dread), hasDefualt); + switchStmt->SetBreakLabelName(exitName); switchStmt->SetSrcFileInfo(GetSrcFileIdx(), GetSrcFileLineNum()); for (auto &s : bodyStmt->Emit2FEStmt()) { switchStmt.get()->AddFeirStmt(std::move(s)); } stmts.emplace_back(std::move(switchStmt)); + AstLoopUtil::Instance().PopCurrentBreak(); return stmts; } @@ -391,7 +406,13 @@ std::list ASTCallExprStmt::ProcessBuiltinVaCopy() const { } std::list ASTCallExprStmt::ProcessBuiltinPrefetch() const { + // __builtin_prefetch is not supported, only parsing args including stmts std::list stmts; + ASTCallExpr *callExpr = static_cast(exprs.front()); + std::vector argsExprs = callExpr->GetArgsExpr(); + for (int32 i = 0; i <= argsExprs.size() - 1; ++i) { + (void)argsExprs[i]->Emit2FEExpr(stmts); + } return stmts; } @@ -420,8 +441,14 @@ std::list ASTParenExprStmt::Emit2FEStmtImpl() const { // ---------- ASTIntegerLiteralStmt ---------- std::list ASTIntegerLiteralStmt::Emit2FEStmtImpl() const { - CHECK_FATAL(false, "NYI"); std::list stmts; + std::list feExprs; + auto feExpr = exprs.front()->Emit2FEExpr(stmts); + if (feExpr != nullptr) { + feExprs.emplace_back(std::move(feExpr)); + auto stmt = std::make_unique(OP_eval, std::move(feExprs)); + stmts.emplace_back(std::move(stmt)); + } return stmts; } @@ -447,8 +474,14 @@ std::list ASTConditionalOperatorStmt::Emit2FEStmtImpl() const { // ---------- ASTCharacterLiteralStmt ---------- std::list ASTCharacterLiteralStmt::Emit2FEStmtImpl() const { - CHECK_FATAL(false, "NYI"); std::list stmts; + std::list feExprs; + auto feExpr = exprs.front()->Emit2FEExpr(stmts); + if (feExpr != nullptr) { + feExprs.emplace_back(std::move(feExpr)); + auto stmt = std::make_unique(OP_eval, std::move(feExprs)); + stmts.emplace_back(std::move(stmt)); + } return stmts; } @@ -526,4 +559,17 @@ std::list ASTGCCAsmStmt::Emit2FEStmtImpl() const { // Translate asm info to FEIR and MIR. return stmts; } + +std::list ASTOffsetOfStmt::Emit2FEStmtImpl() const { + CHECK_FATAL(exprs.front() != nullptr, "child expr must not be nullptr!"); + std::list stmts; + std::list feExprs; + auto feExpr = exprs.front()->Emit2FEExpr(stmts); + if (feExpr != nullptr) { + feExprs.emplace_back(std::move(feExpr)); + auto stmt = std::make_unique(OP_eval, std::move(feExprs)); + stmts.emplace_back(std::move(stmt)); + } + return stmts; +} } // namespace maple diff --git a/src/mplfe/ast_input/src/ast_struct2fe_helper.cpp b/src/mplfe/ast_input/src/ast_struct2fe_helper.cpp index a1bd8f38f1707759999a4aa5d9633feabc3f307b..630add52e8b0855859caca371cefbecde274b7ae 100644 --- a/src/mplfe/ast_input/src/ast_struct2fe_helper.cpp +++ b/src/mplfe/ast_input/src/ast_struct2fe_helper.cpp @@ -143,7 +143,18 @@ bool ASTGlobalVar2FEHelper::ProcessDeclImpl(MapleAllocator &allocator) { if (mirSymbol == nullptr) { return false; } - mirSymbol->SetAttrs(astVar.GetGenericAttrs().ConvertToTypeAttrs()); + auto typeAttrs = astVar.GetGenericAttrs().ConvertToTypeAttrs(); + // do not allow extern var override global var + if (mirSymbol->GetAttrs().GetAttrFlag() != 0 && typeAttrs.GetAttr(ATTR_extern)) { + return true; + } + if (typeAttrs.GetAttr(ATTR_extern)) { + mirSymbol->SetStorageClass(MIRStorageClass::kScExtern); + typeAttrs.ResetAttr(AttrKind::ATTR_extern); + } else { + mirSymbol->SetStorageClass(MIRStorageClass::kScGlobal); + } + mirSymbol->SetAttrs(typeAttrs); ASTExpr *initExpr = astVar.GetInitExpr(); if (initExpr == nullptr) { return true; diff --git a/src/mplfe/common/include/fe_utils.h b/src/mplfe/common/include/fe_utils.h index dd116985379aa0417b149990672b99485c4e1b59..d08d71cc9702e97a425ec2f087b3eaa890fc7473 100644 --- a/src/mplfe/common/include/fe_utils.h +++ b/src/mplfe/common/include/fe_utils.h @@ -329,14 +329,19 @@ class AstLoopUtil { } ~AstLoopUtil() = default; - void PushLoop(const std::pair &labelPair); - std::pair GetCurrentLoop(); - void PopCurrentLoop(); - bool IsLoopLabelsEmpty () const; + void PushBreak(std::string labelPair); + std::string GetCurrentBreak(); + void PopCurrentBreak(); + bool IsBreakLabelsEmpty() const; + void PushContinue(std::string label); + std::string GetCurrentContinue(); + bool IsContinueLabelsEmpty() const; + void PopCurrentContinue(); private: AstLoopUtil() = default; - std::stack> loopLabels = std::stack>(); + std::stack loopLabels = std::stack(); + std::stack continueLabels = std::stack(); }; } // namespace maple #endif // MPLFE_INCLUDE_FE_UTILS_H \ No newline at end of file diff --git a/src/mplfe/common/include/fe_utils_ast.h b/src/mplfe/common/include/fe_utils_ast.h index de15fc932f8866f9230847347c820dfe196cdb64..2487868e2638e8b7b17f19908b91478013ea6d47 100644 --- a/src/mplfe/common/include/fe_utils_ast.h +++ b/src/mplfe/common/include/fe_utils_ast.h @@ -37,29 +37,51 @@ template std::function OpGenerator(Opcode op, T p0, T p1) { switch (op) { case OP_add: { - return [&]() { return p0 + p1; }; + return [p0, p1]() { return p0 + p1; }; } case OP_sub: { - return [&]() { return p0 - p1; }; + return [p0, p1]() { return p0 - p1; }; } case OP_mul: { - return [&]() { return p0 * p1; }; + return [p0, p1]() { return p0 * p1; }; } case OP_div: { - return [&]() { return p0 / p1; }; + return [p0, p1]() { return p0 / p1; }; } case OP_shl: { - return [&]() { return static_cast(p0) << static_cast(p1); }; + return [p0, p1]() { return static_cast(p0) << static_cast(p1); }; } case OP_lshr: case OP_ashr: { - return [&]() { return static_cast(p0) >> static_cast(p1); }; + return [p0, p1]() { return static_cast(p0) >> static_cast(p1); }; } case OP_bior: { - return [&]() { return static_cast(p0) | static_cast(p1); }; + return [p0, p1]() { return static_cast(p0) | static_cast(p1); }; } case OP_bxor: { - return [&]() { return static_cast(p0) ^ static_cast(p1); }; + return [p0, p1]() { return static_cast(p0) ^ static_cast(p1); }; + } + case OP_land: { + return [p0, p1]() { + if (!p0) { + return static_cast(0); + } else if (!p1) { + return static_cast(0); + } else { + return static_cast(1); + } + }; + } + case OP_lior: { + return [p0, p1]() { + if (p0) { + return static_cast(1); + } else if (p1) { + return static_cast(1); + } else { + return static_cast(0); + } + }; } default: { return nullptr; diff --git a/src/mplfe/common/include/feir_stmt.h b/src/mplfe/common/include/feir_stmt.h index f6dff8697afdeefbea12ce17c7f341015d87d1a3..09aa6481a9aa85c45fa1222a9a3833de005cf1be 100644 --- a/src/mplfe/common/include/feir_stmt.h +++ b/src/mplfe/common/include/feir_stmt.h @@ -333,6 +333,13 @@ class FEIRExpr { return CalculateDefs4AllUsesImpl(checkPoint, udChain); } + void CheckPrimTypeEq(PrimType type0, PrimType type1) const { + if ((type0 == PTY_u64 && type1 == PTY_ptr) || (type0 == PTY_ptr && type1 == PTY_u64)) { + return; + } + CHECK_FATAL(type0 == type1, "primtype of opnds must be the same"); + } + protected: virtual std::unique_ptr CloneImpl() const = 0; virtual BaseNode *GenMIRNodeImpl(MIRBuilder &mirBuilder) const = 0; @@ -517,7 +524,9 @@ class FEIRExprAddrofConstArray : public FEIRExpr { explicit FEIRExprAddrofConstArray(const std::vector &arrayIn, MIRType *typeIn) : FEIRExpr(FEIRNodeKind::kExprAddrof, FEIRTypeHelper::CreateTypeNative(*GlobalTables::GetTypeTable().GetPtrType())), - array(arrayIn), type(typeIn) {} + type(typeIn) { + std::copy(arrayIn.begin(), arrayIn.end(), std::back_inserter(array)); + } ~FEIRExprAddrofConstArray() = default; uint32 GetStringLiteralSize() const { @@ -1938,6 +1947,10 @@ class FEIRStmtSwitchForC : public FEIRStmt { hasDefault = argHasDefault; } + void SetBreakLabelName(std::string name) { + breakLabelName = std::move(name); + } + protected: std::string DumpDotStringImpl() const override; void RegisterDFGNodes2CheckPointImpl(FEIRStmtCheckPoint &checkPoint) override; @@ -1948,6 +1961,7 @@ class FEIRStmtSwitchForC : public FEIRStmt { UniqueFEIRExpr expr; bool hasDefault = true; std::list subStmts; + std::string breakLabelName; }; // ---------- FEIRStmtCaseForC ---------- @@ -1959,7 +1973,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; } @@ -1969,7 +1983,7 @@ class FEIRStmtCaseForC : public FEIRStmt { private: int64 lCaseLabel; - std::map pesudoLabelMap = std::map(); + std::map pesudoLabelMap = std::map(); std::list subStmts; }; @@ -2484,16 +2498,8 @@ class FEIRStmtBreak : public FEIRStmt { FEIRStmtBreak(): FEIRStmt(FEIRNodeKind::kStmtBreak) {} ~FEIRStmtBreak() = default; - void SetLoopLabelName(std::string name){ - loopLabelName = std::move(name); - } - - void SetSwitchLabelName(std::string name){ - switchLabelName = std::move(name); - } - - void SetIsFromSwitch(bool fromSwitch) { - isFromSwitch = fromSwitch; + void SetBreakLabelName(std::string name) { + breakLabelName = std::move(name); } protected: @@ -2503,9 +2509,7 @@ class FEIRStmtBreak : public FEIRStmt { std::list GenMIRStmtsImpl(MIRBuilder &mirBuilder) const override; private: - std::string loopLabelName; - std::string switchLabelName; - bool isFromSwitch = false; + std::string breakLabelName; }; class FEIRStmtContinue : public FEIRStmt { diff --git a/src/mplfe/common/src/fe_utils.cpp b/src/mplfe/common/src/fe_utils.cpp index 99edc2adf300ed485ea9764797e4f5fd6e5df1b8..de47bb46d228f99a77010946e5a142ec606a37a3 100644 --- a/src/mplfe/common/src/fe_utils.cpp +++ b/src/mplfe/common/src/fe_utils.cpp @@ -409,19 +409,35 @@ const std::string &AstSwitchUtil::GetTopOfBreakLabels() const { return nestedBreakLabels.top(); } -void AstLoopUtil::PushLoop(const std::pair &labelPair) { +void AstLoopUtil::PushBreak(std::string labelPair) { loopLabels.push(labelPair); } -std::pair AstLoopUtil::GetCurrentLoop(){ +std::string AstLoopUtil::GetCurrentBreak() { return loopLabels.top(); } -bool AstLoopUtil::IsLoopLabelsEmpty() const { +bool AstLoopUtil::IsBreakLabelsEmpty() const { return loopLabels.empty(); } -void AstLoopUtil::PopCurrentLoop(){ +void AstLoopUtil::PopCurrentBreak() { loopLabels.pop(); } + +void AstLoopUtil::PushContinue(std::string labelPair) { + continueLabels.push(labelPair); +} + +std::string AstLoopUtil::GetCurrentContinue() { + return continueLabels.top(); +} + +bool AstLoopUtil::IsContinueLabelsEmpty() const { + return continueLabels.empty(); +} + +void AstLoopUtil::PopCurrentContinue() { + continueLabels.pop(); +} } // namespace maple diff --git a/src/mplfe/common/src/feir_stmt.cpp b/src/mplfe/common/src/feir_stmt.cpp index a96f6a1e29d084f137e4151788ed7ffd8c4893dd..4d8b15f219da3e56a82b4dff4123abd1fca43478 100644 --- a/src/mplfe/common/src/feir_stmt.cpp +++ b/src/mplfe/common/src/feir_stmt.cpp @@ -1020,22 +1020,12 @@ std::list FEIRStmtSwitchForC::GenMIRStmtsImpl(MIRBuilder &mirBuilder) MIRModule &module = mirBuilder.GetMirModule(); CaseVector *caseVec = module.CurFuncCodeMemPool()->New(module.CurFuncCodeMemPoolAllocator()->Adapter()); std::string endName = AstSwitchUtil::Instance().CreateEndOrExitLabelName(); - std::string exitName = AstSwitchUtil::Instance().CreateEndOrExitLabelName(); - AstSwitchUtil::Instance().MarkLabelUnUsed(endName); - AstSwitchUtil::Instance().MarkLabelUnUsed(exitName); LabelIdx swDefaultLabel = mirBuilder.GetOrCreateMIRLabel(endName); // end label - AstSwitchUtil::Instance().PushNestedBreakLabels(exitName); // exit label AstSwitchUtil::Instance().PushNestedCaseVectors(std::pair(caseVec, swDefaultLabel)); BaseNode *exprNode = expr->GenMIRNode(mirBuilder); BlockNode *tempBlock = module.CurFuncCodeMemPool()->New(); CaseVector &switchTable = *AstSwitchUtil::Instance().GetTopOfNestedCaseVectors().first; for (auto &sub : subStmts) { - if (sub.get()->GetKind() == FEIRNodeKind::kStmtBreak) { - AstSwitchUtil::Instance().MarkLabelUsed(exitName); - auto feirStmtBreak = static_cast(sub.get()); - feirStmtBreak->SetSwitchLabelName(exitName); - feirStmtBreak->SetIsFromSwitch(true); - } for (auto mirStmt : sub->GenMIRStmts(mirBuilder)) { tempBlock->AddStatement(mirStmt); } @@ -1050,13 +1040,9 @@ std::list FEIRStmtSwitchForC::GenMIRStmtsImpl(MIRBuilder &mirBuilder) StmtNode *mirSwExitLabelStmt = mirBuilder.CreateStmtLabel(endLab); ans.push_back(mirSwExitLabelStmt); } - - if (AstSwitchUtil::Instance().CheckLabelUsed(exitName)) { - LabelIdx exitLab = mirBuilder.GetOrCreateMIRLabel(exitName); - StmtNode *mirSwExitLabelStmt = mirBuilder.CreateStmtLabel(exitLab); - ans.push_back(mirSwExitLabelStmt); - } - AstSwitchUtil::Instance().PopNestedBreakLabels(); + LabelIdx exitLab = mirBuilder.GetOrCreateMIRLabel(breakLabelName); + StmtNode *mirSwExitLabelStmt = mirBuilder.CreateStmtLabel(exitLab); + ans.push_back(mirSwExitLabelStmt); AstSwitchUtil::Instance().PopNestedCaseVectors(); return ans; } @@ -1074,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, pLabel.get())); } } @@ -1093,13 +1079,6 @@ std::list FEIRStmtCaseForC::GenMIRStmtsImpl(MIRBuilder &mirBuilder) c } } for (auto &sub : subStmts) { - if (sub.get()->GetKind() == FEIRNodeKind::kStmtBreak) { - std::string switchBreakLabelName = AstSwitchUtil::Instance().GetTopOfBreakLabels(); - AstSwitchUtil::Instance().MarkLabelUsed(switchBreakLabelName); - auto feirStmtBreak = static_cast(sub.get()); - feirStmtBreak->SetSwitchLabelName(switchBreakLabelName); - feirStmtBreak->SetIsFromSwitch(true); - } ans.splice(ans.end(), sub.get()->GenMIRStmts(mirBuilder)); } return ans; @@ -1119,13 +1098,6 @@ std::list FEIRStmtDefaultForC::GenMIRStmtsImpl(MIRBuilder &mirBuilder StmtNode *mirLabelStmt = mirBuilder.CreateStmtLabel(AstSwitchUtil::Instance().GetTopOfNestedCaseVectors().second); ans.emplace_back(mirLabelStmt); for (auto &sub : subStmts) { - if (sub.get()->GetKind() == FEIRNodeKind::kStmtBreak) { - std::string switchBreakLabelName = AstSwitchUtil::Instance().GetTopOfBreakLabels(); - AstSwitchUtil::Instance().MarkLabelUsed(switchBreakLabelName); - auto feirStmtBreak = static_cast(sub.get()); - feirStmtBreak->SetSwitchLabelName(switchBreakLabelName); - feirStmtBreak->SetIsFromSwitch(true); - } ans.splice(ans.end(), sub.get()->GenMIRStmts(mirBuilder)); } return ans; @@ -2873,7 +2845,7 @@ BaseNode *FEIRExprBinary::GenMIRNodeNormal(MIRBuilder &mirBuilder) const { BaseNode *FEIRExprBinary::GenMIRNodeCompare(MIRBuilder &mirBuilder) const { BaseNode *nodeOpnd0 = opnd0->GenMIRNode(mirBuilder); BaseNode *nodeOpnd1 = opnd1->GenMIRNode(mirBuilder); - CHECK_FATAL(nodeOpnd0->GetPrimType() == nodeOpnd1->GetPrimType(), "primtype of opnds must be the same"); + CheckPrimTypeEq(nodeOpnd0->GetPrimType(), nodeOpnd1->GetPrimType()); MIRType *mirTypeSrc = GlobalTables::GetTypeTable().GetTypeFromTyIdx( TyIdx(static_cast(nodeOpnd0->GetPrimType()))); MIRType *mirTypeDst = GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(static_cast(type->GetPrimType()))); @@ -2884,7 +2856,7 @@ BaseNode *FEIRExprBinary::GenMIRNodeCompare(MIRBuilder &mirBuilder) const { BaseNode *FEIRExprBinary::GenMIRNodeCompareU1(MIRBuilder &mirBuilder) const { BaseNode *nodeOpnd0 = opnd0->GenMIRNode(mirBuilder); BaseNode *nodeOpnd1 = opnd1->GenMIRNode(mirBuilder); - CHECK_FATAL(nodeOpnd0->GetPrimType() == nodeOpnd1->GetPrimType(), "primtype of opnds must be the same"); + CheckPrimTypeEq(nodeOpnd0->GetPrimType(), nodeOpnd1->GetPrimType()); MIRType *mirTypeSrc = GlobalTables::GetTypeTable().GetTypeFromTyIdx( TyIdx(static_cast(nodeOpnd0->GetPrimType()))); // When the int32 is used to process Java, an error will be reported during the verification. @@ -2952,7 +2924,7 @@ void FEIRExprBinary::SetExprTypeByOpNormal() { type->SetPrimType(PTY_ptr); return; } - CHECK_FATAL(primTypeOpnd0 == primTypeOpnd1, "primtype of opnds must be the same"); + CheckPrimTypeEq(primTypeOpnd0, primTypeOpnd1); type->SetPrimType(primTypeOpnd0); } @@ -2967,7 +2939,7 @@ void FEIRExprBinary::SetExprTypeByOpShift() { void FEIRExprBinary::SetExprTypeByOpLogic() { PrimType primTypeOpnd0 = opnd0->GetPrimType(); PrimType primTypeOpnd1 = opnd1->GetPrimType(); - CHECK_FATAL(primTypeOpnd0 == primTypeOpnd1, "primtype of opnds must be the same"); + CheckPrimTypeEq(primTypeOpnd0, primTypeOpnd1); CHECK_FATAL(IsPrimitiveInteger(primTypeOpnd0), "logic's opnds must be integer"); type->SetPrimType(primTypeOpnd0); } @@ -2995,8 +2967,8 @@ FEIRExprTernary::FEIRExprTernary(Opcode argOp, std::unique_ptr argType SetOpnd(std::move(argOpnd1), 1); SetOpnd(std::move(argOpnd2), 2); PrimType primType = type->GetPrimType(); - CHECK_FATAL(primType == opnd1->GetPrimType(), "primtype of true opnd must be the same"); - CHECK_FATAL(primType == opnd2->GetPrimType(), "primtype of false opnd must be the same"); + CheckPrimTypeEq(primType, opnd1->GetPrimType()); + CheckPrimTypeEq(primType, opnd2->GetPrimType()); } std::unique_ptr FEIRExprTernary::CloneImpl() const { @@ -3070,7 +3042,7 @@ void FEIRExprTernary::SetOpnd(std::unique_ptr argOpnd, uint32 idx) { void FEIRExprTernary::SetExprTypeByOp() { PrimType primTypeOpnd1 = opnd1->GetPrimType(); PrimType primTypeOpnd2 = opnd2->GetPrimType(); - CHECK_FATAL(primTypeOpnd1 == primTypeOpnd2, "primtype of opnds must be the same"); + CheckPrimTypeEq(primTypeOpnd1, primTypeOpnd2); type->SetPrimType(primTypeOpnd1); } @@ -4029,9 +4001,8 @@ std::list FEIRStmtDoWhile::GenMIRStmtsImpl(MIRBuilder &mirBuilder) co std::list FEIRStmtBreak::GenMIRStmtsImpl(MIRBuilder &mirBuilder) const { std::list stmts; - std::string labelName = isFromSwitch ? switchLabelName : loopLabelName; - CHECK_FATAL(!labelName.empty(), "labelName is null!"); - LabelIdx labelIdx = mirBuilder.GetOrCreateMIRLabel(labelName); + CHECK_FATAL(!breakLabelName.empty(), "labelName is null!"); + LabelIdx labelIdx = mirBuilder.GetOrCreateMIRLabel(breakLabelName); GotoNode *gotoNode = mirBuilder.CreateStmtGoto(OP_goto, labelIdx); stmts.emplace_back(gotoNode); return stmts; diff --git a/src/mplfe/common/src/feir_var.cpp b/src/mplfe/common/src/feir_var.cpp index ce0b5a80cac54b498b0911389446d743a8ad5cdc..ffc64b1bb8e68117bf80e2d77825cdb31d6fedda 100644 --- a/src/mplfe/common/src/feir_var.cpp +++ b/src/mplfe/common/src/feir_var.cpp @@ -98,7 +98,9 @@ MIRSymbol *FEIRVar::GenerateGlobalMIRSymbolImpl(MIRBuilder &builder) const { std::string name = GetName(*mirType); GStrIdx nameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(name); MIRSymbol *gSymbol = builder.GetOrCreateGlobalDecl(name, *mirType); - if (gSymbol->GetAttrs().GetAttrFlag() != 0) { + auto attrs = const_cast(genAttrs).ConvertToTypeAttrs(); + // do not allow extern var override global var + if (gSymbol->GetAttrs().GetAttrFlag() != 0 && attrs.GetAttr(ATTR_extern)) { return gSymbol; } // Set global var attr once @@ -129,6 +131,12 @@ MIRSymbol *FEIRVar::GenerateGlobalMIRSymbolImpl(MIRBuilder &builder) const { } } } + if (attrs.GetAttr(ATTR_extern)) { + gSymbol->SetStorageClass(MIRStorageClass::kScExtern); + attrs.ResetAttr(AttrKind::ATTR_extern); + } else { + gSymbol->SetStorageClass(MIRStorageClass::kScGlobal); + } return gSymbol; } diff --git a/src/mplfe/test/feir_test_base.cpp b/src/mplfe/test/feir_test_base.cpp index fc3baf833df0f38f18ab12e7ed8ffe53b6eca429..378a511ddbdda2a6c68370f119c9bb0b45b677f1 100644 --- a/src/mplfe/test/feir_test_base.cpp +++ b/src/mplfe/test/feir_test_base.cpp @@ -15,17 +15,19 @@ #include "feir_test_base.h" #include "mplfe_ut_environment.h" #include "fe_utils.h" +#include "fe_manager.h" namespace maple { MemPool *FEIRTestBase::mp = nullptr; FEIRTestBase::FEIRTestBase() : allocator(mp), - mirBuilder(&MPLFEUTEnvironment::GetMIRModule()), - func(&MPLFEUTEnvironment::GetMIRModule(), StIdx(0, 0)) { - func.Init(); - func.NewBody(); - mirBuilder.SetCurrentFunction(func); + mirBuilder(&MPLFEUTEnvironment::GetMIRModule()) { + func = FEManager::GetTypeManager().GetMIRFunction("mock_func", false); + if (func == nullptr) { + func = FEManager::GetTypeManager().CreateFunction("mock_func", "void", std::vector{}, false, false); + } + mirBuilder.SetCurrentFunction(*func); } void FEIRTestBase::SetUpTestCase() {