From 9868362a8784039c2ebaa3bff01550a13f32235b Mon Sep 17 00:00:00 2001 From: binaryfz Date: Thu, 29 Apr 2021 16:30:51 +0800 Subject: [PATCH] [mapleall]bugfix when opening inline.union addrofOst of union fields.[mplfeC] add calling a function using an address.Add sizeof and label --- .../include/cg/aarch64/aarch64_cgfunc.h | 1 + src/mapleall/maple_be/include/cg/cgfunc.h | 1 + .../src/cg/aarch64/aarch64_cgfunc.cpp | 100 +++++-------- src/mapleall/maple_me/include/alias_class.h | 1 + src/mapleall/maple_me/include/me_ssa_lpre.h | 1 + src/mapleall/maple_me/src/alias_class.cpp | 31 +++- src/mapleall/maple_me/src/me_alias_class.cpp | 1 + src/mapleall/maple_me/src/me_ssa_lpre.cpp | 32 +++++ src/mplfe/ast_input/include/ast_parser.h | 2 + src/mplfe/ast_input/include/ast_stmt.h | 19 +++ src/mplfe/ast_input/src/ast_expr.cpp | 16 ++- src/mplfe/ast_input/src/ast_parser.cpp | 133 ++++++++++++------ src/mplfe/ast_input/src/ast_stmt.cpp | 8 ++ src/mplfe/common/include/feir_builder.h | 1 + src/mplfe/common/include/feir_node_kind.def | 1 + src/mplfe/common/include/feir_stmt.h | 14 ++ src/mplfe/common/src/feir_builder.cpp | 5 + src/mplfe/common/src/feir_stmt.cpp | 23 ++- 18 files changed, 270 insertions(+), 120 deletions(-) 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 8f0138d598..d573788720 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -671,6 +671,7 @@ class AArch64CGFunc : public CGFunc { MemOperand *CheckAndCreateExtendMemOpnd(PrimType ptype, BaseNode &addrExpr, int32 offset, AArch64isa::MemoryOrdering memOrd); MemOperand &CreateNonExtendMemOpnd(PrimType ptype, const BaseNode &parent, BaseNode &addrExpr, int32 offset); + std::string GenerateMemOpndVerbose(const Operand &src); }; } /* namespace maplebe */ diff --git a/src/mapleall/maple_be/include/cg/cgfunc.h b/src/mapleall/maple_be/include/cg/cgfunc.h index c843d968d6..77e1fc4797 100644 --- a/src/mapleall/maple_be/include/cg/cgfunc.h +++ b/src/mapleall/maple_be/include/cg/cgfunc.h @@ -327,6 +327,7 @@ class CGFunc { case PTY_a32: case PTY_a64: case PTY_ptr: + case PTY_agg: return kRegTyInt; case PTY_f32: case PTY_f64: 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 851552724c..41569fff7b 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -239,18 +239,7 @@ void AArch64CGFunc::SelectLoadAcquire(Operand &dest, PrimType dtype, Operand &sr std::string key; if (isDirect && GetCG()->GenerateVerboseCG()) { - const MIRSymbol *sym = static_cast(&src)->GetSymbol(); - if (sym != nullptr) { - MIRStorageClass sc = sym->GetStorageClass(); - if (sc == kScFormal) { - key = "param: "; - } else if (sc == kScAuto) { - key = "local var: "; - } else { - key = "global: "; - } - key.append(sym->GetName()); - } + key = GenerateMemOpndVerbose(src); } /* Check if the right load-acquire instruction is available. */ @@ -310,18 +299,7 @@ void AArch64CGFunc::SelectStoreRelease(Operand &dest, PrimType dtype, Operand &s std::string key; if (isDirect && GetCG()->GenerateVerboseCG()) { - const MIRSymbol *sym = static_cast(&dest)->GetSymbol(); - if (sym != nullptr) { - MIRStorageClass sc = sym->GetStorageClass(); - if (sc == kScFormal) { - key = "param: "; - } else if (sc == kScAuto) { - key = "local var: "; - } else { - key = "global: "; - } - key.append(sym->GetName()); - } + key = GenerateMemOpndVerbose(dest); } /* Check if the right store-release instruction is available. */ @@ -451,6 +429,24 @@ void AArch64CGFunc::SelectCopyImm(Operand &dest, ImmOperand &src, PrimType dtype } } +std::string AArch64CGFunc::GenerateMemOpndVerbose(const Operand &src) { + ASSERT(src.GetKind() == Operand::kOpdMem, "Just checking"); + const MIRSymbol *symSecond = static_cast(&src)->GetSymbol(); + if (symSecond != nullptr) { + std::string key; + MIRStorageClass sc = symSecond->GetStorageClass(); + if (sc == kScFormal) { + key = "param: "; + } else if (sc == kScAuto) { + key = "local var: "; + } else { + key = "global: "; + } + return key.append(symSecond->GetName()); + } + return ""; +} + void AArch64CGFunc::SelectCopyMemOpnd(Operand &dest, PrimType dtype, uint32 dsize, Operand &src, PrimType stype) { AArch64isa::MemoryOrdering memOrd = AArch64isa::kMoNone; @@ -472,7 +468,11 @@ void AArch64CGFunc::SelectCopyMemOpnd(Operand &dest, PrimType dtype, uint32 dsiz CHECK_FATAL(dsize == ssize, "dsize %u expect equals ssize %u", dtype, ssize); insn = &GetCG()->BuildInstruction(PickLdInsn(ssize, stype), dest, src); } else { - mop = PickExtInsn(dtype, stype); + if (stype == PTY_agg && dtype == PTY_agg) { + mop = MOP_undef; + } else { + mop = PickExtInsn(dtype, stype); + } if (ssize == (GetPrimTypeSize(dtype) * kBitsPerByte) || mop == MOP_undef) { insn = &GetCG()->BuildInstruction(PickLdInsn(ssize, stype), dest, src); } else { @@ -483,19 +483,7 @@ void AArch64CGFunc::SelectCopyMemOpnd(Operand &dest, PrimType dtype, uint32 dsiz } if (GetCG()->GenerateVerboseCG()) { - const MIRSymbol *symSecond = static_cast(&src)->GetSymbol(); - if (symSecond != nullptr) { - std::string key; - MIRStorageClass sc = symSecond->GetStorageClass(); - if (sc == kScFormal) { - key = "param: "; - } else if (sc == kScAuto) { - key = "local var: "; - } else { - key = "global: "; - } - insn->SetComment(key.append(symSecond->GetName())); - } + insn->SetComment(GenerateMemOpndVerbose(src)); } GetCurBB()->AppendInsn(*insn); @@ -947,21 +935,8 @@ void AArch64CGFunc::SelectDassign(StIdx stIdx, FieldID fieldId, PrimType rhsPTyp Insn &insn = GetCG()->BuildInstruction(mOp, stOpnd, *memOpnd); if (GetCG()->GenerateVerboseCG()) { - const MIRSymbol *symSecond = static_cast(memOpnd)->GetSymbol(); - if (symSecond != nullptr) { - std::string key; - MIRStorageClass sc = symSecond->GetStorageClass(); - if (sc == kScFormal) { - key = "param: "; - } else if (sc == kScAuto) { - key = "local var: "; - } else { - key = "global: "; - } - insn.SetComment(key.append(symSecond->GetName())); - } + insn.SetComment(GenerateMemOpndVerbose(*memOpnd)); } - GetCurBB()->AppendInsn(insn); } else { AArch64CGFunc::SelectStoreRelease(*memOpnd, ptyp, stOpnd, ptyp, memOrd, true); @@ -1594,19 +1569,20 @@ Operand *AArch64CGFunc::SelectDread(const BaseNode &parent, DreadNode &expr) { offset = GetBecommon().GetFieldOffset(*structType, expr.GetFieldID()).first; parmCopy = IsParamStructCopy(*symbol); } - CHECK_FATAL(symType != PTY_agg, "dread type error"); + uint32 dataSize = GetPrimTypeBitSize(symType); uint32 aggSize = 0; if (symType == PTY_agg) { if (expr.GetPrimType() == PTY_agg) { aggSize = GetBecommon().GetTypeSize(symbol->GetType()->GetTypeIndex().GetIdx()); - dataSize = k64BitSize; + dataSize = aggSize; } else { dataSize = GetPrimTypeBitSize(expr.GetPrimType()); } } MemOperand *memOpnd = nullptr; if (aggSize > k8ByteSize) { + CHECK_FATAL(false, "SelectDread: aggregate of wrong size check IR"); if (parent.op == OP_eval) { if (symbol->GetAttr(ATTR_volatile)) { /* Need to generate loads for the upper parts of the struct. */ @@ -1869,12 +1845,6 @@ Operand *AArch64CGFunc::SelectIread(const BaseNode &parent, IreadNode &expr) { isRefField = true; /* read from an object array, or an high-dimentional array */ } } - if (pointedType->GetPrimType() == PTY_agg) { - maple::LogInfo::MapleLogger(kLlErr) << "Error: cannot find field in " << - GlobalTables::GetStrTable().GetStringFromStrIdx(pointedType->GetNameStrIdx()) << '\n'; - CHECK_FATAL(false, "cannot find field"); - return nullptr; - } } RegType regType = GetRegTyFromPrimTy(expr.GetPrimType()); @@ -1910,12 +1880,8 @@ Operand *AArch64CGFunc::SelectIread(const BaseNode &parent, IreadNode &expr) { } else { if (pointedType->IsStructType()) { MIRStructType *structType = static_cast(pointedType); - if (expr.GetFieldID()) { - /* size << 3, that is size * 8, change bytes to bits */ - bitSize = structType->GetSize() << 3; - } else { - destType = GetDestTypeFromAggSize(bitSize); - } + /* size << 3, that is size * 8, change bytes to bits */ + bitSize = structType->GetSize() << 3; } else { bitSize = GetPrimTypeBitSize(destType); } @@ -1937,7 +1903,7 @@ Operand *AArch64CGFunc::SelectIread(const BaseNode &parent, IreadNode &expr) { destType = PTY_u64; break; default: - CHECK_FATAL(false, "SelectIread: aggregate of wrong size"); + CHECK_FATAL(false, "SelectIRead: aggregate of wrong size check IR"); } } } diff --git a/src/mapleall/maple_me/include/alias_class.h b/src/mapleall/maple_me/include/alias_class.h index 00b825b1b8..e3565302f4 100644 --- a/src/mapleall/maple_me/include/alias_class.h +++ b/src/mapleall/maple_me/include/alias_class.h @@ -150,6 +150,7 @@ class AliasClass : public AnalysisResult { } void ApplyUnionForCopies(StmtNode &stmt); + void UnionAddrofOstOfUnionFields(); void CreateAssignSets(); void DumpAssignSets(); void UnionAllPointedTos(); diff --git a/src/mapleall/maple_me/include/me_ssa_lpre.h b/src/mapleall/maple_me/include/me_ssa_lpre.h index 8950363d77..cc5ddd3d79 100644 --- a/src/mapleall/maple_me/include/me_ssa_lpre.h +++ b/src/mapleall/maple_me/include/me_ssa_lpre.h @@ -34,6 +34,7 @@ class MeSSALPre : public SSAPre { private: void GenerateSaveRealOcc(MeRealOcc&) override; + MeExpr *GetTruncExpr(const VarMeExpr &theLHS, MeExpr &savedRHS); void GenerateReloadRealOcc(MeRealOcc&) override; MeExpr *PhiOpndFromRes(MeRealOcc&, size_t) const override; void ComputeVarAndDfPhis() override; diff --git a/src/mapleall/maple_me/src/alias_class.cpp b/src/mapleall/maple_me/src/alias_class.cpp index 31ccd81088..d3f8b22540 100644 --- a/src/mapleall/maple_me/src/alias_class.cpp +++ b/src/mapleall/maple_me/src/alias_class.cpp @@ -378,7 +378,7 @@ void AliasClass::ApplyUnionForCopies(StmtNode &stmt) { } case OP_call: case OP_callassigned: { - for (int32 i = 0; i < stmt.NumOpnds(); i++) { + for (uint32 i = 0; i < stmt.NumOpnds(); ++i) { CreateAliasElemsExpr(*stmt.Opnd(i)); } auto &call = static_cast(stmt); @@ -407,7 +407,7 @@ void AliasClass::ApplyUnionForCopies(StmtNode &stmt) { if (CallHasSideEffect(&stmt)) { bool hasnoprivatedefeffect = CallHasNoPrivateDefEffect(&stmt); auto &call = static_cast(stmt); - for (int32 i = 1; i < call.NumOpnds(); i++) { + for (uint32 i = 1; i < call.NumOpnds(); ++i) { AliasInfo ainfo = CreateAliasElemsExpr(*call.Opnd(i)); if (IsPotentialAddress(call.Opnd(i)->GetPrimType(), &mirModule) && ainfo.ae != nullptr) { if (call.Opnd(i)->GetOpCode() == OP_addrof && IsReadOnlyOst(ainfo.ae->GetOriginalSt())) { @@ -424,7 +424,7 @@ void AliasClass::ApplyUnionForCopies(StmtNode &stmt) { } case OP_icall: case OP_icallassigned: { - for (int32 i = 0; i < stmt.NumOpnds(); i++) { + for (uint32 i = 0; i < stmt.NumOpnds(); ++i) { CreateAliasElemsExpr(*stmt.Opnd(i)); } auto &call = static_cast(stmt); @@ -433,7 +433,7 @@ void AliasClass::ApplyUnionForCopies(StmtNode &stmt) { } case OP_intrinsiccall: case OP_intrinsiccallassigned: { - for (int32 i = 0; i < stmt.NumOpnds(); i++) { + for (uint32 i = 0; i < stmt.NumOpnds(); ++i) { CreateAliasElemsExpr(*stmt.Opnd(i)); } auto &intrnNode = static_cast(stmt); @@ -452,6 +452,29 @@ void AliasClass::ApplyUnionForCopies(StmtNode &stmt) { } } +void AliasClass::UnionAddrofOstOfUnionFields() { + // map stIdx of union to aliasElem of addrofOst of union fields + std::map sym2AddrofOstAE; + for (auto *aliasElem : id2Elem) { + auto &ost = aliasElem->GetOriginalSt(); + // indirect level of addrof ost eq -1 + if (ost.GetIndirectLev() != -1) { + continue; + } + ASSERT(ost.IsSymbolOst(), "only symbol has address"); + if (ost.GetMIRSymbol()->GetType()->GetKind() != kTypeUnion) { + continue; + } + StIdx stIdx = ost.GetMIRSymbol()->GetStIdx(); + auto it = sym2AddrofOstAE.find(stIdx); + if (it != sym2AddrofOstAE.end()) { + unionFind.Union(it->second->id, aliasElem->id); + } else { + sym2AddrofOstAE[stIdx] = aliasElem; + } + } +} + void AliasClass::CreateAssignSets() { // iterate through all the alias elems for (auto *aliasElem : id2Elem) { diff --git a/src/mapleall/maple_me/src/me_alias_class.cpp b/src/mapleall/maple_me/src/me_alias_class.cpp index 690094c831..d2ff55d57f 100644 --- a/src/mapleall/maple_me/src/me_alias_class.cpp +++ b/src/mapleall/maple_me/src/me_alias_class.cpp @@ -47,6 +47,7 @@ void MeAliasClass::DoAliasAnalysis() { ApplyUnionForCopies(stmt); } } + UnionAddrofOstOfUnionFields(); CreateAssignSets(); if (enabledDebug) { DumpAssignSets(); diff --git a/src/mapleall/maple_me/src/me_ssa_lpre.cpp b/src/mapleall/maple_me/src/me_ssa_lpre.cpp index d5dea07fa9..38a6a885e4 100644 --- a/src/mapleall/maple_me/src/me_ssa_lpre.cpp +++ b/src/mapleall/maple_me/src/me_ssa_lpre.cpp @@ -57,6 +57,9 @@ void MeSSALPre::GenerateSaveRealOcc(MeRealOcc &realOcc) { BB *savedBB = realOcc.GetMeStmt()->GetBB(); MeStmt *savedPrev = realOcc.GetMeStmt()->GetPrev(); MeStmt *savedNext = realOcc.GetMeStmt()->GetNext(); + // judge if lhs has smaller size than rhs, if so, we need solve truncation. + savedRHS = GetTruncExpr(*theLHS, *savedRHS); + // change original dassign/maydassign to regassign; // use placement new to modify in place, because other occ nodes are pointing // to this statement in order to get to the rhs expression; @@ -95,6 +98,35 @@ void MeSSALPre::GenerateSaveRealOcc(MeRealOcc &realOcc) { realOcc.SetSavedExpr(*regOrVar); } +MeExpr *MeSSALPre::GetTruncExpr(const VarMeExpr &theLHS, MeExpr &savedRHS) { + MIRType *lhsType = theLHS.GetType(); + if (theLHS.GetType()->GetKind() != kTypeBitField) { + return &savedRHS; + } + MIRBitFieldType *bitfieldTy = static_cast(lhsType); + if (GetPrimTypeBitSize(savedRHS.GetPrimType()) <= bitfieldTy->GetFieldSize()) { + return &savedRHS; + } + // insert OP_zext or OP_sext + Opcode extOp = IsSignedInteger(lhsType->GetPrimType()) ? OP_sext : OP_zext; + PrimType newPrimType = PTY_u32; + if (bitfieldTy->GetFieldSize() <= GetPrimTypeBitSize(PTY_u32)) { + if (IsSignedInteger(lhsType->GetPrimType())) { + newPrimType = PTY_i32; + } + } else { + if (IsSignedInteger(lhsType->GetPrimType())) { + newPrimType = PTY_i64; + } else { + newPrimType = PTY_u64; + } + } + OpMeExpr opmeexpr(-1, extOp, newPrimType, 1); + opmeexpr.SetBitsSize(bitfieldTy->GetFieldSize()); + opmeexpr.SetOpnd(0, &savedRHS); + return irMap->HashMeExpr(opmeexpr); +} + void MeSSALPre::GenerateReloadRealOcc(MeRealOcc &realOcc) { CHECK_FATAL(!realOcc.IsLHS(), "GenerateReloadRealOcc: cannot be LHS occurrence"); MeExpr *regOrVar = nullptr; diff --git a/src/mplfe/ast_input/include/ast_parser.h b/src/mplfe/ast_input/include/ast_parser.h index dfa63a4480..75696ff16a 100644 --- a/src/mplfe/ast_input/include/ast_parser.h +++ b/src/mplfe/ast_input/include/ast_parser.h @@ -65,6 +65,7 @@ class ASTParser { ASTStmt *PROCESS_STMT(WhileStmt); ASTStmt *PROCESS_STMT(DoStmt); ASTStmt *PROCESS_STMT(BreakStmt); + ASTStmt *PROCESS_STMT(LabelStmt); ASTStmt *PROCESS_STMT(ContinueStmt); ASTStmt *PROCESS_STMT(CompoundStmt); ASTStmt *PROCESS_STMT(GotoStmt); @@ -136,6 +137,7 @@ ASTDecl *ProcessDecl(MapleAllocator &allocator, const clang::Decl &decl); void TraverseDecl(const clang::Decl *decl, std::function const &functor); ASTDecl *GetAstDeclOfDeclRefExpr(MapleAllocator &allocator, const clang::Expr &expr); void SetSourceFileInfo(clang::Decl *decl); + uint32 GetSizeFromQualType(const clang::QualType qualType); uint32 fileIdx; const std::string fileName; std::unique_ptr astFile; diff --git a/src/mplfe/ast_input/include/ast_stmt.h b/src/mplfe/ast_input/include/ast_stmt.h index 825c325f36..daa94214ac 100644 --- a/src/mplfe/ast_input/include/ast_stmt.h +++ b/src/mplfe/ast_input/include/ast_stmt.h @@ -158,6 +158,25 @@ class ASTBreakStmt : public ASTStmt { std::list Emit2FEStmtImpl() const override; }; +class ASTLabelStmt : public ASTStmt { + public: + ASTLabelStmt() : ASTStmt(kASTStmtLabel) {} + ~ASTLabelStmt() override = default; + + void SetSubStmt(ASTStmt *stmt) { + subStmt = stmt; + } + + void SetLabelName(std::string &name) { + labelName = name; + } + + private: + std::list Emit2FEStmtImpl() const override; + std::string labelName; + ASTStmt *subStmt; +}; + class ASTContinueStmt : public ASTStmt { public: ASTContinueStmt() : ASTStmt(kASTStmtContinue) {} diff --git a/src/mplfe/ast_input/src/ast_expr.cpp b/src/mplfe/ast_input/src/ast_expr.cpp index b9f86fab0a..b80d8896b5 100644 --- a/src/mplfe/ast_input/src/ast_expr.cpp +++ b/src/mplfe/ast_input/src/ast_expr.cpp @@ -34,9 +34,15 @@ void ASTDeclRefExpr::SetASTDecl(ASTDecl *astDecl) { } UniqueFEIRExpr ASTDeclRefExpr::Emit2FEExprImpl(std::list &stmts) const { - UniqueFEIRVar feirVar = FEIRBuilder::CreateVarNameForC(var->GetName(), *(var->GetTypeDesc().front()), - var->IsGlobal(), false); - UniqueFEIRExpr feirRefExpr = FEIRBuilder::CreateExprDRead(std::move(feirVar)); + MIRType *mirType = var->GetTypeDesc().front(); + UniqueFEIRExpr feirRefExpr; + if (mirType->GetKind() == kTypePointer && + static_cast(mirType)->GetPointedType()->GetKind() == kTypeFunction) { + feirRefExpr = FEIRBuilder::CreateExprAddrofFunc(var->GetName()); + } else { + UniqueFEIRVar feirVar = FEIRBuilder::CreateVarNameForC(var->GetName(), *mirType, var->IsGlobal(), false); + feirRefExpr = FEIRBuilder::CreateExprDRead(std::move(feirVar)); + } return feirRefExpr; } @@ -469,8 +475,8 @@ void ASTInitListExpr::SetInitListType(MIRType *type) { } UniqueFEIRExpr ASTImplicitValueInitExpr::Emit2FEExprImpl(std::list &stmts) const { - CHECK_FATAL(false, "NIY"); - return nullptr; + // Other MIRTypeKind should enable + return FEIRBuilder::CreateExprConstAnyScalar(type->GetPrimType(), 0); } UniqueFEIRExpr ASTStringLiteral::Emit2FEExprImpl(std::list &stmts) const { diff --git a/src/mplfe/ast_input/src/ast_parser.cpp b/src/mplfe/ast_input/src/ast_parser.cpp index b0225df766..c0b25b3226 100644 --- a/src/mplfe/ast_input/src/ast_parser.cpp +++ b/src/mplfe/ast_input/src/ast_parser.cpp @@ -40,15 +40,13 @@ bool ASTParser::Verify() { } ASTBinaryOperatorExpr *ASTParser::AllocBinaryOperatorExpr(MapleAllocator &allocator, const clang::BinaryOperator &bo) { - if (bo.isAssignmentOp() && !bo.isCompoundAssignmentOp()) { - if (bo.isCompoundAssignmentOp()) { - auto *expr = ASTDeclsBuilder::ASTExprBuilder(allocator); - clang::BinaryOperator::Opcode opcode = clang::BinaryOperator::getOpForCompoundAssignment(bo.getOpcode()); - Opcode mirOpcode = ASTUtil::CvtBinaryOpcode(opcode); - expr->SetOpForCompoundAssign(mirOpcode); - } else { - return ASTDeclsBuilder::ASTExprBuilder(allocator); - } + if (bo.isCompoundAssignmentOp()) { + auto *expr = ASTDeclsBuilder::ASTExprBuilder(allocator); + clang::BinaryOperator::Opcode opcode = clang::BinaryOperator::getOpForCompoundAssignment(bo.getOpcode()); + Opcode mirOpcode = ASTUtil::CvtBinaryOpcode(opcode); + expr->SetOpForCompoundAssign(mirOpcode); + } else if (bo.isAssignmentOp()) { + return ASTDeclsBuilder::ASTExprBuilder(allocator); } if (bo.getOpcode() == clang::BO_Comma) { return ASTDeclsBuilder::ASTExprBuilder(allocator); @@ -114,6 +112,7 @@ ASTStmt *ASTParser::ProcessStmt(MapleAllocator &allocator, const clang::Stmt &st STMT_CASE(WhileStmt); STMT_CASE(DoStmt); STMT_CASE(BreakStmt); + STMT_CASE(LabelStmt); STMT_CASE(ContinueStmt); STMT_CASE(GotoStmt); STMT_CASE(SwitchStmt); @@ -420,6 +419,16 @@ ASTStmt *ASTParser::ProcessStmtBreakStmt(MapleAllocator &allocator, const clang: return astStmt; } +ASTStmt *ASTParser::ProcessStmtLabelStmt(MapleAllocator &allocator, const clang::LabelStmt &stmt) { + auto *astStmt = ASTDeclsBuilder::ASTStmtBuilder(allocator); + CHECK_FATAL(astStmt != nullptr, "astStmt is nullptr"); + ASTStmt *astSubStmt = ProcessStmt(allocator, *stmt.getSubStmt()); + std::string name(stmt.getName()); + astStmt->SetLabelName(name); + astStmt->SetSubStmt(astSubStmt); + return astStmt; +} + ASTStmt *ASTParser::ProcessStmtCaseStmt(MapleAllocator &allocator, const clang::CaseStmt &caseStmt) { ASTCaseStmt *astStmt = ASTDeclsBuilder::ASTStmtBuilder(allocator); CHECK_FATAL(astStmt != nullptr, "astStmt is nullptr"); @@ -613,8 +622,7 @@ ASTExpr *ASTParser::ProcessExprUnaryOperator(MapleAllocator &allocator, const cl int64 len; const clang::QualType qualType = subExpr->getType()->getPointeeType(); if (astFile->CvtType(qualType)->GetPrimType() == PTY_ptr) { - // GetAddr32 or GetAddr64 need check - MIRType *pointeeType = GlobalTables::GetTypeTable().GetAddr64(); + MIRType *pointeeType = GlobalTables::GetTypeTable().GetPtr(); len = static_cast(pointeeType->GetSize()); } else { const clang::QualType desugaredType = qualType.getDesugaredType(*(astFile->GetContext())); @@ -802,19 +810,47 @@ ASTExpr *ASTParser::ProcessExprArraySubscriptExpr(MapleAllocator &allocator, con return astArraySubscriptExpr; } +uint32 ASTParser::GetSizeFromQualType(const clang::QualType qualType) { + const clang::QualType desugaredType = qualType.getDesugaredType(*astFile->GetContext()); + return astFile->GetContext()->getTypeSizeInChars(desugaredType).getQuantity(); +} + ASTExpr *ASTParser::ProcessExprUnaryExprOrTypeTraitExpr(MapleAllocator &allocator, const clang::UnaryExprOrTypeTraitExpr &expr) { auto *astExprUnaryExprOrTypeTraitExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); CHECK_FATAL(astExprUnaryExprOrTypeTraitExpr != nullptr, "astExprUnaryExprOrTypeTraitExpr is nullptr"); - if (expr.isArgumentType()) { - astExprUnaryExprOrTypeTraitExpr->SetIsType(true); - astExprUnaryExprOrTypeTraitExpr->SetArgType(astFile->CvtType(expr.getArgumentType())); - } else { - ASTExpr *argExpr = ProcessExpr(allocator, expr.getArgumentExpr()); - if (argExpr == nullptr) { - return nullptr; + switch (expr.getKind()) { + case clang::UETT_SizeOf: { + uint32 size = 0; + if (expr.isArgumentType()) { + size = GetSizeFromQualType(expr.getArgumentType()); + } else { + const clang::Expr *argex = expr.getArgumentExpr(); + if (llvm::isa(argex->getType())) { + // C99 VLA + CHECK_FATAL(false, "NIY"); + break; + } else { + size = GetSizeFromQualType(argex->getType()); + } + } + auto integerExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); + integerExpr->SetType(PTY_i32); + integerExpr->SetVal(size); + return integerExpr; } - astExprUnaryExprOrTypeTraitExpr->SetArgExpr(argExpr); + case clang::UETT_PreferredAlignOf: + case clang::UETT_AlignOf: { + // C11 specification: ISO/IEC 9899:201x + CHECK_FATAL(false, "NIY"); + break; + } + case clang::UETT_VecStep: + CHECK_FATAL(false, "NIY"); + break; + case clang::UETT_OpenMPRequiredSimdAlign: + CHECK_FATAL(false, "NIY"); + break; } return astExprUnaryExprOrTypeTraitExpr; } @@ -1102,9 +1138,13 @@ ASTExpr *ASTParser::ProcessExprDeclRefExpr(MapleAllocator &allocator, const clan clang::QualType qualType = expr.getDecl()->getType(); MIRType *refType = astFile->CvtType(qualType); ASTDecl *astDecl = ASTDeclsBuilder::ASTDeclBuilder(allocator, fileName, refName, std::vector{refType}); - if (expr.getDecl()->getKind() == clang::Decl::Var) { + auto declKind = expr.getDecl()->getKind(); + if (declKind == clang::Decl::Var) { const auto *varDecl = llvm::cast(expr.getDecl()->getCanonicalDecl()); astDecl->SetGlobal(!varDecl->isLocalVarDeclOrParm()); + } else if (declKind == clang::Decl::Function) { + const auto *funcDecl = llvm::cast(expr.getDecl()->getCanonicalDecl()); + astDecl->SetGlobal(!funcDecl->isGlobal()); } else { // For comes from `EnumConstant` astDecl->SetGlobal(expr.getDecl()->getParentFunctionOrMethod() == nullptr); @@ -1124,33 +1164,42 @@ ASTExpr *ASTParser::ProcessExprBinaryOperator(MapleAllocator &allocator, const c ASTBinaryOperatorExpr *astBinOpExpr = AllocBinaryOperatorExpr(allocator, bo); CHECK_FATAL(astBinOpExpr != nullptr, "astBinOpExpr is nullptr"); clang::QualType qualType = bo.getType(); - // Complex type if (qualType->isAnyComplexType()) { CHECK_FATAL(false, "NIY"); } - - MIRType *retType = astFile->CvtType(qualType); - if (retType == nullptr) { - return nullptr; - } - astBinOpExpr->SetRetType(retType); - clang::Expr *lExpr = bo.getLHS(); - if (lExpr != nullptr) { - ASTExpr *astLExpr = ProcessExpr(allocator, lExpr); - if (astLExpr != nullptr) { - astBinOpExpr->SetLeftExpr(astLExpr); - } else { - return nullptr; + astBinOpExpr->SetRetType(astFile->CvtType(qualType)); + ASTExpr *astRExpr = ProcessExpr(allocator, bo.getRHS()); + ASTExpr *astLExpr = ProcessExpr(allocator, bo.getLHS()); + if (bo.getType()->isPointerType()) { + auto ptrSizeExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); + ptrSizeExpr->SetType(PTY_ptr); + ptrSizeExpr->SetVal(GetSizeFromQualType(bo.getType()->getPointeeType())); + if (bo.getLHS()->getType()->isPointerType()) { + auto rhs = ASTDeclsBuilder::ASTExprBuilder(allocator); + rhs->SetLeftExpr(astRExpr); + rhs->SetRightExpr(ptrSizeExpr); + rhs->SetOpcode(OP_mul); + astRExpr = rhs; + } else if (bo.getRHS()->getType()->isPointerType()) { + auto lhs = ASTDeclsBuilder::ASTExprBuilder(allocator); + lhs->SetLeftExpr(astLExpr); + lhs->SetRightExpr(ptrSizeExpr); + lhs->SetOpcode(OP_mul); + astLExpr = lhs; } } - clang::Expr *rExpr = bo.getRHS(); - if (rExpr != nullptr) { - ASTExpr *astRExpr = ProcessExpr(allocator, rExpr); - if (astRExpr != nullptr) { - astBinOpExpr->SetRightExpr(astRExpr); - } else { - return nullptr; - } + astBinOpExpr->SetLeftExpr(astLExpr); + astBinOpExpr->SetRightExpr(astRExpr); + if (bo.getOpcode() == clang::BO_Sub && bo.getRHS()->getType()->isPointerType() && + bo.getLHS()->getType()->isPointerType()) { + auto ptrSizeExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); + ptrSizeExpr->SetType(PTY_ptr); + ptrSizeExpr->SetVal(GetSizeFromQualType(bo.getRHS()->getType()->getPointeeType())); + auto retASTExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); + retASTExpr->SetLeftExpr(astBinOpExpr); + retASTExpr->SetRightExpr(ptrSizeExpr); + retASTExpr->SetOpcode(OP_div); + astBinOpExpr = retASTExpr; } return astBinOpExpr; } diff --git a/src/mplfe/ast_input/src/ast_stmt.cpp b/src/mplfe/ast_input/src/ast_stmt.cpp index c3707df9e7..66b5b3e685 100644 --- a/src/mplfe/ast_input/src/ast_stmt.cpp +++ b/src/mplfe/ast_input/src/ast_stmt.cpp @@ -154,6 +154,14 @@ std::list ASTBreakStmt::Emit2FEStmtImpl() const { return stmts; } +std::list ASTLabelStmt::Emit2FEStmtImpl() const { + std::list stmts; + auto feStmt = std::make_unique(labelName); + stmts.emplace_back(std::move(feStmt)); + stmts.splice(stmts.end(), subStmt->Emit2FEStmt()); + return stmts; +} + std::list ASTContinueStmt::Emit2FEStmtImpl() const { std::list stmts; auto stmt = std::make_unique(); diff --git a/src/mplfe/common/include/feir_builder.h b/src/mplfe/common/include/feir_builder.h index 32a9c50089..2999580315 100644 --- a/src/mplfe/common/include/feir_builder.h +++ b/src/mplfe/common/include/feir_builder.h @@ -45,6 +45,7 @@ class FEIRBuilder { static UniqueFEIRExpr CreateExprDRead(UniqueFEIRVar srcVar); static UniqueFEIRExpr CreateExprAddrof(const std::vector &array); static UniqueFEIRExpr CreateExprAddrofVar(UniqueFEIRVar srcVar); + static UniqueFEIRExpr CreateExprAddrofFunc(const std::string &addr); static UniqueFEIRExpr CreateExprIRead(UniqueFEIRType returnType, UniqueFEIRType ptrType, FieldID id, UniqueFEIRExpr expr); static UniqueFEIRExpr CreateExprTernary(Opcode op, UniqueFEIRType type, UniqueFEIRExpr cExpr, diff --git a/src/mplfe/common/include/feir_node_kind.def b/src/mplfe/common/include/feir_node_kind.def index 20276d07a4..2b306546a2 100644 --- a/src/mplfe/common/include/feir_node_kind.def +++ b/src/mplfe/common/include/feir_node_kind.def @@ -40,6 +40,7 @@ FEIR_NODE_KIND(ExprNary, "ExprNary") FEIR_NODE_KIND(ExprArray, "ExprArray") FEIR_NODE_KIND(ExprAddrof, "ExprAddrof") FEIR_NODE_KIND(ExprAddrofVar, "ExprAddrofVar") +FEIR_NODE_KIND(ExprAddrofFunc, "ExprAddrofFunc") FEIR_NODE_KIND(ExprIntrinsicop, "ExprIntrinsicop") FEIR_NODE_KIND(FEIRExprJavaMerge, "FEIRExprJavaMerge") FEIR_NODE_KIND(ExprTypeCvt, "ExprTypeCvt") diff --git a/src/mplfe/common/include/feir_stmt.h b/src/mplfe/common/include/feir_stmt.h index 84dcfc5103..f0847424d5 100644 --- a/src/mplfe/common/include/feir_stmt.h +++ b/src/mplfe/common/include/feir_stmt.h @@ -488,6 +488,20 @@ class FEIRExprAddrofVar : public FEIRExpr { std::unique_ptr varSrc; }; +class FEIRExprAddrofFunc : public FEIRExpr { + public: + explicit FEIRExprAddrofFunc(const std::string &addr) + : FEIRExpr(FEIRNodeKind::kExprAddrofFunc), funcAddr(addr) {} + ~FEIRExprAddrofFunc() = default; + + protected: + std::unique_ptr CloneImpl() const override; + BaseNode *GenMIRNodeImpl(MIRBuilder &mirBuilder) const override; + + private: + std::string funcAddr; +}; + // ---------- FEIRExprUnary ---------- class FEIRExprUnary : public FEIRExpr { public: diff --git a/src/mplfe/common/src/feir_builder.cpp b/src/mplfe/common/src/feir_builder.cpp index a885005398..2755aa6337 100644 --- a/src/mplfe/common/src/feir_builder.cpp +++ b/src/mplfe/common/src/feir_builder.cpp @@ -114,6 +114,11 @@ UniqueFEIRExpr FEIRBuilder::CreateExprAddrofVar(UniqueFEIRVar srcVar) { return expr; } +UniqueFEIRExpr FEIRBuilder::CreateExprAddrofFunc(const std::string &addr) { + UniqueFEIRExpr expr = std::make_unique(addr); + return expr; +} + UniqueFEIRExpr FEIRBuilder::CreateExprTernary(Opcode op, UniqueFEIRType type, UniqueFEIRExpr cExpr, UniqueFEIRExpr tExpr, UniqueFEIRExpr fExpr) { UniqueFEIRExpr expr = std::make_unique(op, std::move(type), std::move(cExpr), diff --git a/src/mplfe/common/src/feir_stmt.cpp b/src/mplfe/common/src/feir_stmt.cpp index 85543e475d..be01d77ebf 100644 --- a/src/mplfe/common/src/feir_stmt.cpp +++ b/src/mplfe/common/src/feir_stmt.cpp @@ -1986,7 +1986,8 @@ BaseNode *FEIRExprDRead::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { MIRSymbol *symbol = varSrc->GenerateMIRSymbol(mirBuilder); ASSERT(type != nullptr, "type is nullptr"); AddrofNode *node = mirBuilder.CreateExprDread(*type, *symbol); - if (type->IsMIRStructType() && (!fieldName.empty() || (fieldID != 0))) { + if ((type->IsMIRStructType() || type->GetKind() == MIRTypeKind::kTypeUnion) && + (!fieldName.empty() || (fieldID != 0))) { FieldID fieldIdVar = fieldID; if (fieldIdVar == 0) { fieldIdVar = mirBuilder.GetStructFieldIDFromFieldName(*type, fieldName); @@ -2021,7 +2022,7 @@ BaseNode *FEIRExprIRead::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { MIRPtrType *mirPtrType = static_cast(pointerType); MIRType *pointedMirType = mirPtrType->GetPointedType(); FieldID fid = fieldID; - if (pointedMirType->IsMIRStructType()) { + if (pointedMirType->IsMIRStructType() || pointedMirType->GetKind() == MIRTypeKind::kTypeUnion) { CHECK_FATAL(!fieldName.empty() || fid != 0, "error"); if (fid == 0) { fid = mirBuilder.GetStructFieldIDFromFieldName(*pointedMirType, fieldName); @@ -2071,6 +2072,20 @@ BaseNode *FEIRExprAddrofVar::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { return mirBuilder.CreateExprAddrof(0, *varSymbol); } +// ---------- FEIRExprAddrofFunc ---------- +std::unique_ptr FEIRExprAddrofFunc::CloneImpl() const { + CHECK_FATAL(false, "not support clone here"); + return nullptr; +} + +BaseNode *FEIRExprAddrofFunc::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { + GStrIdx strIdx = GlobalTables::GetStrTable().GetStrIdxFromName(funcAddr); + MIRFunction *mirFunc = FEManager::GetTypeManager().GetMIRFunction(strIdx, false); + CHECK_FATAL(mirFunc != nullptr, "can not get MIRFunction"); + return mirBuilder.CreateExprAddroffunc(mirFunc->GetPuidx(), + mirBuilder.GetMirModule().GetMemPool()); +} + // ---------- FEIRExprRegRead ---------- FEIRExprRegRead::FEIRExprRegRead(PrimType pty, int32 regNumIn) : FEIRExpr(FEIRNodeKind::kExprRegRead), prmType(pty), regNum(regNumIn) {} @@ -2533,6 +2548,10 @@ void FEIRExprBinary::SetExprTypeByOp() { void FEIRExprBinary::SetExprTypeByOpNormal() { PrimType primTypeOpnd0 = opnd0->GetPrimType(); PrimType primTypeOpnd1 = opnd1->GetPrimType(); + if (primTypeOpnd0 == PTY_ptr || primTypeOpnd1 == PTY_ptr) { + type->SetPrimType(PTY_ptr); + return; + } CHECK_FATAL(primTypeOpnd0 == primTypeOpnd1, "primtype of opnds must be the same"); type->SetPrimType(primTypeOpnd0); } -- Gitee