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 0584b99103c57be991a72947a201612089a7530c..7e3f2a5fcb68f168ccf3d3907171ca33606d148b 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_peep.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_peep.cpp @@ -305,7 +305,6 @@ void RemoveIdenticalLoadAndStoreAArch64::Run(BB &bb, Insn &insn) { if ((mop1 == MOP_wstr && mop2 == MOP_wstr) || (mop1 == MOP_xstr && mop2 == MOP_xstr)) { if (IsMemOperandsIdentical(insn, *nextInsn)) { bb.RemoveInsn(insn); - insn = *nextInsn; } } else if ((mop1 == MOP_wstr && mop2 == MOP_wldr) || (mop1 == MOP_xstr && mop2 == MOP_xldr)) { if (IsMemOperandsIdentical(insn, *nextInsn)) { @@ -464,7 +463,6 @@ void CombineContiLoadAndStoreAArch64::Run(BB &bb, Insn &insn) { } bb.RemoveInsn(insn); bb.RemoveInsn(*nextInsn); - insn = *nn; } /* pattern found */ } @@ -882,11 +880,9 @@ void ContiLDRorSTRToSameMEMAArch64::Run(BB &bb, Insn &insn) { CG *cg = cgFunc.GetCG(); bb.InsertInsnAfter(*prevInsn, cg->BuildInstruction(newOp, reg1, reg2)); bb.RemoveInsn(insn); - insn = *(prevInsn->GetNext()); } else if (reg1.GetRegisterNumber() == reg2.GetRegisterNumber() && base1->GetRegisterNumber() != reg2.GetRegisterNumber()) { bb.RemoveInsn(insn); - insn = *prevInsn; } } diff --git a/src/mapleall/maple_be/src/cg/emit.cpp b/src/mapleall/maple_be/src/cg/emit.cpp index 615ca4cce2c57bbc02a2838f5650c5f6f4e63df7..46f16dbb1a849edabb7f6833c76d3d2f4fe2ae50 100644 --- a/src/mapleall/maple_be/src/cg/emit.cpp +++ b/src/mapleall/maple_be/src/cg/emit.cpp @@ -1869,7 +1869,7 @@ void Emitter::EmitStringPointers() { continue; } uint32 strId = idx.GetIdx(); - const char *str = GlobalTables::GetUStrTable().GetStringFromStrIdx(idx).c_str(); + std::string str = GlobalTables::GetUStrTable().GetStringFromStrIdx(idx); Emit("\t.align 3\n"); Emit(".LSTR__").Emit(strId).Emit(":\n"); std::string mplstr(str); diff --git a/src/mapleall/maple_me/include/alias_class.h b/src/mapleall/maple_me/include/alias_class.h index 474762badd4fe85afaf61daa99ff9afbabd27309..b8d18bbefc2586b32a79ffa7afdd8983f7799c22 100644 --- a/src/mapleall/maple_me/include/alias_class.h +++ b/src/mapleall/maple_me/include/alias_class.h @@ -193,7 +193,8 @@ class AliasClass : public AnalysisResult { void SetPtrOpndsNextLevNADS(unsigned int start, unsigned int end, MapleVector &opnds, bool hasNoPrivateDefEffect); void ApplyUnionForFieldsInAggCopy(const OriginalSt *lhsost, const OriginalSt *rhsost); - void ApplyUnionForDassignCopy(const AliasElem &lhsAe, const AliasElem *rhsAe, const BaseNode &rhs); + void ApplyUnionForDassignCopy(AliasElem &lhsAe, AliasElem *rhsAe, BaseNode &rhs); + bool SetNextLevNADSForPtrIntegerCopy(AliasElem &lhsAe, const AliasElem *rhsAe, BaseNode &rhs); void CreateMirroringAliasElems(const OriginalSt *ost1, OriginalSt *ost2); AliasElem *FindOrCreateDummyNADSAe(); bool IsPointedTo(OriginalSt &oSt); diff --git a/src/mapleall/maple_me/include/me_bb_analyze.h b/src/mapleall/maple_me/include/me_bb_analyze.h index dedb2bd56c8c1a66622f42652517853967229ecf..e538684194d59382ef2188632005806a2c503aec 100644 --- a/src/mapleall/maple_me/include/me_bb_analyze.h +++ b/src/mapleall/maple_me/include/me_bb_analyze.h @@ -30,8 +30,8 @@ class BBAnalyze : public AnalysisResult { virtual ~BBAnalyze() = default; void SetHotAndColdBBCountThreshold(); - bool CheckBBHot(const BBId bbId); - bool CheckBBCold(const BBId bbId); + bool CheckBBHot(const BBId bbId) const; + bool CheckBBCold(const BBId bbId) const; uint32 getHotBBCountThreshold() const; uint32 getColdBBCountThreshold() const; diff --git a/src/mapleall/maple_me/include/me_cfg.h b/src/mapleall/maple_me/include/me_cfg.h index b48f723257f9d95635f2e6e944ffcf27b2a48053..354991848473602bcca561b8365fab6f7435056c 100644 --- a/src/mapleall/maple_me/include/me_cfg.h +++ b/src/mapleall/maple_me/include/me_cfg.h @@ -33,7 +33,7 @@ class MeCFG : public AnalysisResult { using reverse_iterator = BBPtrHolder::reverse_iterator; using const_reverse_iterator = BBPtrHolder::const_reverse_iterator; - explicit MeCFG(MemPool *memPool, MeFunction &f) + MeCFG(MemPool *memPool, MeFunction &f) : AnalysisResult(memPool), mp(memPool), mecfgAlloc(memPool), @@ -263,7 +263,10 @@ class MeCFG : public AnalysisResult { endTryBB2TryBB[endTryBB] = endTryBB2TryBB[otherTryBB]; } - MemPool * GetMempool() const { return mp; } + MemPool *GetMempool() const { + return mp; + } + void CreateBasicBlocks(); private: diff --git a/src/mapleall/maple_me/include/me_ssa_devirtual.h b/src/mapleall/maple_me/include/me_ssa_devirtual.h index f2d90f71b3c3e91f16aa1ba494426f6bbf916f70..adf6688a2bea8c64c2dc4739f7f6e1cca061c0aa 100644 --- a/src/mapleall/maple_me/include/me_ssa_devirtual.h +++ b/src/mapleall/maple_me/include/me_ssa_devirtual.h @@ -26,7 +26,8 @@ class MeSSADevirtual : public SSADevirtual { : SSADevirtual(memPool, mod, irMap, kh, dom, func.GetCfg()->GetAllBBs().size(), skipReturnTypeOpt), func(&func) {} MeSSADevirtual(MemPool &memPool, MIRModule &mod, MeFunction &func, IRMap &irMap, KlassHierarchy &kh, Dominance &dom, Clone &clone, bool skipReturnTypeOpt) - : SSADevirtual(memPool, mod, irMap, kh, dom, func.GetCfg()->GetAllBBs().size(), clone, skipReturnTypeOpt), func(&func) {} + : SSADevirtual(memPool, mod, irMap, kh, dom, func.GetCfg()->GetAllBBs().size(), clone, skipReturnTypeOpt), + func(&func) {} ~MeSSADevirtual() = default; diff --git a/src/mapleall/maple_me/src/alias_class.cpp b/src/mapleall/maple_me/src/alias_class.cpp index 6b874a47e543f6b8bcad7d274ca1310b1b365969..24138cc294ca9a2c93b6399bded654f0ba115187 100644 --- a/src/mapleall/maple_me/src/alias_class.cpp +++ b/src/mapleall/maple_me/src/alias_class.cpp @@ -394,10 +394,49 @@ void AliasClass::ApplyUnionForFieldsInAggCopy(const OriginalSt *lhsost, const Or } } -void AliasClass::ApplyUnionForDassignCopy(const AliasElem &lhsAe, const AliasElem *rhsAe, const BaseNode &rhs) { +// if epxr is cvt/retype, remove type convertion +BaseNode &RemoveTypeConvertionIfExist(BaseNode &expr) { + if (expr.GetOpCode() == OP_cvt || expr.GetOpCode() == OP_retype) { + return RemoveTypeConvertionIfExist(*expr.Opnd(0)); + } + return expr; +} + +// 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; + } + 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)) { + lhsAe.SetNextLevNotAllDefsSeen(true); + return true; + } else if (!IsPotentialAddress(lhsPtyp, &mirModule) && IsPotentialAddress(rhsPtyp, &mirModule)) { + AliasInfo realRhsAinfo = CreateAliasElemsExpr(realRhs); + if (realRhsAinfo.ae != nullptr) { + realRhsAinfo.ae->SetNextLevNotAllDefsSeen(true); + } + return true; + } + } + return false; +} + +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)) { + return; + } if (rhsAe == nullptr || rhsAe->GetOriginalSt().GetIndirectLev() > 0 || rhsAe->IsNotAllDefsSeen()) { - AliasElem *aliasElem = FindAliasElem(lhsAe.GetOriginalSt()); - aliasElem->SetNextLevNotAllDefsSeen(true); + lhsAe.SetNextLevNotAllDefsSeen(true); return; } if (mirModule.IsCModule()) { @@ -472,7 +511,6 @@ void AliasClass::ApplyUnionForCopies(StmtNode &stmt) { if (ost->GetFieldID() != 0) { (void)FindOrCreateAliasElemOfAddrofZeroFieldIDOSt(*ost); } - AliasElem *lhsAe = FindOrCreateAliasElem(*ost); ASSERT_NOT_NULL(lhsAe); ApplyUnionForDassignCopy(*lhsAe, rhsAinfo.ae, *stmt.Opnd(0)); diff --git a/src/mapleall/maple_me/src/me_bb_analyze.cpp b/src/mapleall/maple_me/src/me_bb_analyze.cpp index 1e18dfef2786b306148d4adf996b6c0139fccdc4..f56edc6ea196588935580f854b8f5aa59ef8ec08 100644 --- a/src/mapleall/maple_me/src/me_bb_analyze.cpp +++ b/src/mapleall/maple_me/src/me_bb_analyze.cpp @@ -31,12 +31,12 @@ namespace maple { coldBBCountThreshold = times.at(coldIndex); } - bool BBAnalyze::CheckBBHot(const BBId bbId) { + bool BBAnalyze::CheckBBHot(const BBId bbId) const { BB *bb = cfg->GetBBFromID(bbId); return bb->GetFrequency() >= hotBBCountThreshold; } - bool BBAnalyze::CheckBBCold(const BBId bbId) { + bool BBAnalyze::CheckBBCold(const BBId bbId) const { BB *bb = cfg->GetBBFromID(bbId); return bb->GetFrequency() <= coldBBCountThreshold; } diff --git a/src/mapleall/maple_me/src/me_cfg.cpp b/src/mapleall/maple_me/src/me_cfg.cpp index 4ec7d5c8ddb50d29eb7166633d86361ea344a4c9..9f1f410318c0f582062d2f1f5f73d5e33b25b024 100644 --- a/src/mapleall/maple_me/src/me_cfg.cpp +++ b/src/mapleall/maple_me/src/me_cfg.cpp @@ -1475,7 +1475,6 @@ void MeCFG::CreateBasicBlocks() { BB *newBB = NewBasicBlock(); if (tryStmt != nullptr) { newBB->SetAttributes(kBBAttrIsTry); - //bbTryNodeMap[newBB] = tryStmt; SetBBTryNodeMap(*newBB, *tryStmt); } curBB = newBB; @@ -1556,8 +1555,6 @@ AnalysisResult *MeDoMeCfg::Run(MeFunction *func, MeFuncResultMgr *m, ModuleResul theCFG->WontExitAnalysis(); theCFG->Verify(); - // TODOFORTEST - // if (func->GetMIRModule().IsCModule()) { if (mrm == nullptr) { MeDoLoopCanon doLoopCanon(MeFuncPhase_LOOPCANON); if (!MeOption::quiet) { @@ -1573,5 +1570,4 @@ AnalysisResult *MeDoMeCfg::Run(MeFunction *func, MeFuncResultMgr *m, ModuleResul } return theCFG; } - } // namespace maple diff --git a/src/mapleall/maple_me/src/me_gc_write_barrier_opt.cpp b/src/mapleall/maple_me/src/me_gc_write_barrier_opt.cpp index 20147757215786f06445edeae4cacfc2de9b5dbc..c374106f767869e9cfb02bc8dcad135557bfd233 100644 --- a/src/mapleall/maple_me/src/me_gc_write_barrier_opt.cpp +++ b/src/mapleall/maple_me/src/me_gc_write_barrier_opt.cpp @@ -34,7 +34,7 @@ AnalysisResult *MeDoGCWriteBarrierOpt::Run(MeFunction *func, MeFuncResultMgr *fu void GCWriteBarrierOpt::Prepare() { callBBs.resize(func.GetCfg()->NumBBs()); - visited.resize(func.GetCfg()->NumBBs()); + visited.resize(func.GetCfg()->NumBBs()); if (enabledDebug) { LogInfo::MapleLogger() << "\n============== Before GC WRITE BARRIER OPT =============" << '\n'; func.Dump(false); diff --git a/src/mapleall/maple_me/src/me_phase_manager.cpp b/src/mapleall/maple_me/src/me_phase_manager.cpp index 5a93265d6e29e49f70572f5a31a82827906efc79..96d1572c82af9ef04106ced2d2a4f0e42aefb3b7 100644 --- a/src/mapleall/maple_me/src/me_phase_manager.cpp +++ b/src/mapleall/maple_me/src/me_phase_manager.cpp @@ -236,7 +236,6 @@ void MeFuncPhaseManager::Run(MIRFunction *mirFunc, uint64 rangeNum, const std::s mirFunc->SetMeFunc(&func); } std::string phaseName = ""; -// MeFuncPhase *changeCFGPhase = nullptr; // each function level phase bool dumpFunc = FuncFilter(MeOption::dumpFunc, func.GetName()); size_t phaseIndex = 0; diff --git a/src/mapleall/maple_me/src/me_placement_rc.cpp b/src/mapleall/maple_me/src/me_placement_rc.cpp index 66cfe64ff8a2ccfdfe06a05b0e28c9db90acd276..8592c4e611088df906b5d8f032d3b43357ad3345 100644 --- a/src/mapleall/maple_me/src/me_placement_rc.cpp +++ b/src/mapleall/maple_me/src/me_placement_rc.cpp @@ -571,7 +571,8 @@ void PlacementRC::CodeMotionForReal(SOcc &occ, const UnaryMeStmt *entryIncref) { // Special case: delete the formal's entry incref if (realOcc.GetStmt() == nullptr) { if (!MeOption::gcOnly) { - CHECK_FATAL(lastUseBB == func->GetCfg()->GetFirstBB(), "PlacementRC::CodeMotion: realOcc from entry incref has wrong bb"); + CHECK_FATAL(lastUseBB == func->GetCfg()->GetFirstBB(), + "PlacementRC::CodeMotion: realOcc from entry incref has wrong bb"); DeleteEntryIncref(realOcc, entryIncref); } return; diff --git a/src/mplfe/ast_input/include/ast_decl.h b/src/mplfe/ast_input/include/ast_decl.h index 7603bd46ae16b965bd9fc2e93dc55f5868c60af6..a9060504744d73a9706add5779d34720537ea87d 100644 --- a/src/mplfe/ast_input/include/ast_decl.h +++ b/src/mplfe/ast_input/include/ast_decl.h @@ -60,9 +60,15 @@ class ASTDecl { pos = p; } + MIRConst *Translate2MIRConst() const; + std::string GenerateUniqueVarName(); protected: + virtual MIRConst *Translate2MIRConstImpl() const { + CHECK_FATAL(false, "Maybe implemented for other ASTDecls"); + return nullptr; + } virtual void GenerateInitStmtImpl(std::list &stmts) {} bool isGlobalDecl; bool isParam = false; @@ -102,7 +108,7 @@ class ASTFunc : public ASTDecl { std::list EmitASTStmtToFEIR() const; private: - // typeDesc format: [retType, arg0, arg1 ... argN] + // typeDesc format: [funcType, retType, arg0, arg1 ... argN] ASTStmt *compound; // func body std::vector parmNames; }; @@ -160,6 +166,7 @@ class ASTVar : public ASTDecl { std::unique_ptr Translate2FEIRVar(); private: + MIRConst *Translate2MIRConstImpl() const override; void GenerateInitStmtImpl(std::list &stmts) override; ASTExpr *initExpr = nullptr; }; diff --git a/src/mplfe/ast_input/include/ast_decl_builder.h b/src/mplfe/ast_input/include/ast_decl_builder.h index 8f17e308fabe9e1909852fcb2b32f0b244f29a3a..f9bcc02123df2f03eb1b785fd080b337c7fc7e46 100644 --- a/src/mplfe/ast_input/include/ast_decl_builder.h +++ b/src/mplfe/ast_input/include/ast_decl_builder.h @@ -18,16 +18,32 @@ #include "mempool_allocator.h" namespace maple { +static std::map declesTable; class ASTDeclsBuilder { public: + static ASTDecl *GetASTDecl(int64 id) { + ASTDecl *decl = declesTable[id]; + return decl; + } + static ASTDecl *ASTDeclBuilder(MapleAllocator &allocator, const std::string &srcFile, - const std::string &nameIn, const std::vector &typeDescIn) { - return allocator.GetMemPool()->New(srcFile, nameIn, typeDescIn); + const std::string &nameIn, const std::vector &typeDescIn, int64 id = INT64_MAX) { + if (id == INT64_MAX) { + return allocator.GetMemPool()->New(srcFile, nameIn, typeDescIn); // for temp decl + } else if (declesTable[id] == nullptr) { + declesTable[id] = allocator.GetMemPool()->New(srcFile, nameIn, typeDescIn); + } + return declesTable[id]; } static ASTVar *ASTVarBuilder(MapleAllocator &allocator, const std::string &srcFile, const std::string &varName, - const std::vector &desc, const GenericAttrs &genAttrsIn) { - return allocator.GetMemPool()->New(srcFile, varName, desc, genAttrsIn); + 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 ASTLocalEnumDecl *ASTLocalEnumDeclBuilder(MapleAllocator &allocator, const std::string &srcFile, @@ -37,8 +53,13 @@ class ASTDeclsBuilder { static ASTFunc *ASTFuncBuilder(MapleAllocator &allocator, const std::string &srcFile, const std::string &nameIn, const std::vector &typeDescIn, const GenericAttrs &genAttrsIn, - const std::vector &parmNamesIn) { - return allocator.GetMemPool()->New(srcFile, nameIn, typeDescIn, genAttrsIn, parmNamesIn); + const std::vector &parmNamesIn, int64 id = INT64_MAX) { + if (id == INT64_MAX) { + allocator.GetMemPool()->New(srcFile, nameIn, typeDescIn, genAttrsIn, parmNamesIn); + } else if (declesTable[id] == nullptr) { + declesTable[id] = allocator.GetMemPool()->New(srcFile, nameIn, typeDescIn, genAttrsIn, parmNamesIn); + } + return static_cast(declesTable[id]); } template @@ -52,8 +73,13 @@ class ASTDeclsBuilder { } static ASTStruct *ASTStructBuilder(MapleAllocator &allocator, const std::string &srcFile, const std::string &nameIn, - const std::vector &typeDescIn, const GenericAttrs &genAttrsIn) { - return allocator.GetMemPool()->New(srcFile, nameIn, typeDescIn, genAttrsIn); + const std::vector &typeDescIn, const GenericAttrs &genAttrsIn, int64 id = INT64_MAX) { + if (id == INT64_MAX) { + allocator.GetMemPool()->New(srcFile, nameIn, typeDescIn, genAttrsIn); + } else if (declesTable[id] == nullptr) { + declesTable[id] = allocator.GetMemPool()->New(srcFile, nameIn, typeDescIn, genAttrsIn); + } + return static_cast(declesTable[id]); } static ASTField *ASTFieldBuilder(MapleAllocator &allocator, const std::string &srcFile, const std::string &varName, diff --git a/src/mplfe/ast_input/include/ast_expr.h b/src/mplfe/ast_input/include/ast_expr.h index 6b59291ffd21a2e7493ba9c1861c3de0905fbb4a..ca27a77453cf1a1d979c6863f73efb33b266ad38 100644 --- a/src/mplfe/ast_input/include/ast_expr.h +++ b/src/mplfe/ast_input/include/ast_expr.h @@ -20,6 +20,19 @@ namespace maple { class ASTDecl; class ASTStmt; +struct ASTValue { + union Value { + int32 i32; + float f32; + int64 i64; + double f64; + UStrIdx strIdx; + } val = { 0 }; + PrimType pty = PTY_begin; + + MIRConst *Translate2MIRConst() const; +}; + class ASTExpr { public: explicit ASTExpr(ASTOp o) : op(o) {} @@ -47,11 +60,30 @@ class ASTExpr { return op; } + void SetConstantValue(ASTValue *val) { + isConstantFolded = (val != nullptr); + value = val; + } + + ASTValue *GetConstantValue() const { + return GetConstantValueImpl(); + } + + MIRConst *GenerateMIRConst() const { + return GenerateMIRConstImpl(); + } + protected: + virtual ASTValue *GetConstantValueImpl() const { + return value; + } + virtual MIRConst *GenerateMIRConstImpl() const; virtual UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const = 0; ASTOp op; MIRType *mirType = nullptr; ASTDecl *refedDecl = nullptr; + bool isConstantFolded = false; + ASTValue *value = nullptr; }; class ASTImplicitCastExpr : public ASTExpr { @@ -101,6 +133,10 @@ class ASTImplicitCastExpr : public ASTExpr { imageZero = flag; } + void SetIsArrayToPointerDecay(bool flag) { + isArrayToPointerDecay = flag; + } + bool IsBuilinFunc() const { return isBuilinFunc; } @@ -110,15 +146,21 @@ class ASTImplicitCastExpr : public ASTExpr { } protected: + ASTValue *GetConstantValueImpl() const override; + MIRConst *GenerateMIRConstImpl() const override; UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; private: + MIRConst *GenerateMIRDoubleConst() const; + MIRConst *GenerateMIRFloatConst() const; + MIRConst *GenerateMIRIntConst() const; ASTExpr *child = nullptr; MIRType *src = nullptr; MIRType *dst = nullptr; bool isNeededCvt = false; MIRType *complexType = nullptr; bool imageZero = false; + bool isArrayToPointerDecay = false; bool isBuilinFunc = false; }; @@ -128,6 +170,7 @@ class ASTDeclRefExpr : public ASTExpr { ~ASTDeclRefExpr() = default; protected: + MIRConst *GenerateMIRConstImpl() const override; UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; }; @@ -203,20 +246,22 @@ class ASTUOLNotExpr: public ASTUnaryOperatorExpr { class ASTUOPostIncExpr: public ASTUnaryOperatorExpr { public: - ASTUOPostIncExpr() : ASTUnaryOperatorExpr(kASTOpPostInc) {} + ASTUOPostIncExpr() : ASTUnaryOperatorExpr(kASTOpPostInc), tempVarName(FEUtils::GetSequentialName("postinc_")) {} ~ASTUOPostIncExpr() = default; private: UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; + std::string tempVarName; }; class ASTUOPostDecExpr: public ASTUnaryOperatorExpr { public: - ASTUOPostDecExpr() : ASTUnaryOperatorExpr(kASTOpPostDec) {} + ASTUOPostDecExpr() : ASTUnaryOperatorExpr(kASTOpPostDec), tempVarName(FEUtils::GetSequentialName("postdec_")) {} ~ASTUOPostDecExpr() = default; private: UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; + std::string tempVarName; }; class ASTUOPreIncExpr: public ASTUnaryOperatorExpr { @@ -235,6 +280,7 @@ class ASTUOPreDecExpr: public ASTUnaryOperatorExpr { private: UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; + std::string tempVarName; }; class ASTUOAddrOfExpr: public ASTUnaryOperatorExpr { @@ -242,6 +288,9 @@ class ASTUOAddrOfExpr: public ASTUnaryOperatorExpr { ASTUOAddrOfExpr() : ASTUnaryOperatorExpr(kASTOpAddrOf) {} ~ASTUOAddrOfExpr() = default; + protected: + MIRConst *GenerateMIRConstImpl() const override; + private: UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; }; @@ -387,12 +436,15 @@ class ASTInitListExpr : public ASTExpr { void SetInitListVarName(const std::string &argVarName) { varName = argVarName; - }; + } private: + MIRConst *GenerateMIRConstImpl() const override; UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; void Emit2FEExprForArray(std::list &stmts) const; void Emit2FEExprForStruct(std::list &stmts) const; + MIRConst *GenerateMIRConstForArray() const; + MIRConst *GenerateMIRConstForStruct() const; std::vector fillers; MIRType *initListType; std::string varName; @@ -422,6 +474,10 @@ class ASTBinaryOperatorExpr : public ASTExpr { retType = type; } + MIRType *GetRetType() const { + return retType; + } + void SetLeftExpr(ASTExpr *expr) { leftExpr = expr; } @@ -481,6 +537,9 @@ class ASTImplicitValueInitExpr : public ASTExpr { type = srcType; } + protected: + MIRConst *GenerateMIRConstImpl() const override; + private: UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; MIRType *type; @@ -511,6 +570,9 @@ class ASTStringLiteral : public ASTExpr { return codeUnits; } + protected: + MIRConst *GenerateMIRConstImpl() const override; + private: UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; MIRType *type; @@ -668,6 +730,7 @@ class ASTDesignatedInitUpdateExpr : public ASTExpr { } private: + MIRConst *GenerateMIRConstImpl() const override; UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; ASTExpr *baseExpr; ASTExpr *updaterExpr; @@ -861,6 +924,16 @@ class ASTCharacterLiteral : public ASTExpr { PrimType type; }; +struct VaArgInfo { + bool isGPReg; // GP or FP/SIMD arg reg + int regOffset; + int stackOffset; + // If the argument type is a Composite Type that is larger than 16 bytes, + // then the argument is copied to memory allocated by the caller and replaced by a pointer to the copy. + bool isCopyedMem; + bool isHFA; // Homogeneous Floating-point Aggregate +}; + class ASTVAArgExpr : public ASTExpr { public: ASTVAArgExpr() : ASTExpr(kASTVAArgExpr) {} @@ -871,8 +944,13 @@ class ASTVAArgExpr : public ASTExpr { } private: - ASTExpr *child = nullptr; UniqueFEIRExpr Emit2FEExprImpl(std::list &stmts) const override; + VaArgInfo ProcessValistArgInfo(MIRType &type) const; + bool IsHFAType(MIRStructType &type) const; + void CvtHFA2Struct(MIRStructType &structType, UniqueFEIRVar vaArgVar, UniqueFEIRVar copyedVar, + std::list &stmts) const; + + ASTExpr *child = nullptr; }; class ASTCompoundAssignOperatorExpr : public ASTAssignExpr { diff --git a/src/mplfe/ast_input/include/ast_parser.h b/src/mplfe/ast_input/include/ast_parser.h index 822761b0fd9643ebc49de8cab93c2ec546c035bc..983617e47d80f31aae5e9696b62503dba930836d 100644 --- a/src/mplfe/ast_input/include/ast_parser.h +++ b/src/mplfe/ast_input/include/ast_parser.h @@ -85,6 +85,8 @@ class ASTParser { // ProcessExpr const clang::Expr *PeelParen(const clang::Expr &expr); ASTUnaryOperatorExpr *AllocUnaryOperatorExpr(MapleAllocator &allocator, const clang::UnaryOperator &expr); + ASTValue *AllocASTValue(MapleAllocator &allocator) const; + ASTValue *TranslateExprEval(MapleAllocator &allocator, const clang::Expr *expr) const; ASTExpr *ProcessExpr(MapleAllocator &allocator, const clang::Expr *expr); ASTBinaryOperatorExpr *AllocBinaryOperatorExpr(MapleAllocator &allocator, const clang::BinaryOperator &bo); #define PROCESS_EXPR(CLASS) ProcessExpr##CLASS(MapleAllocator&, const clang::CLASS&) @@ -136,10 +138,14 @@ class ASTParser { ASTDecl *PROCESS_DECL(Function); ASTDecl *PROCESS_DECL(Record); ASTDecl *PROCESS_DECL(Var); + ASTDecl *PROCESS_DECL(ParmVar); ASTDecl *PROCESS_DECL(Enum); ASTDecl *PROCESS_DECL(Typedef); + ASTDecl *PROCESS_DECL(EnumConstant); private: + ASTValue *TranslateRValue2ASTValue(MapleAllocator &allocator, const clang::Expr *expr) const; + ASTValue *TranslateLValue2ASTValue(MapleAllocator &allocator, const clang::Expr *expr) const; void TraverseDecl(const clang::Decl *decl, std::function const &functor); ASTDecl *GetAstDeclOfDeclRefExpr(MapleAllocator &allocator, const clang::Expr &expr); void SetSourceFileInfo(clang::Decl *decl); diff --git a/src/mplfe/ast_input/lib/ast_type.cpp b/src/mplfe/ast_input/lib/ast_type.cpp index 766459bfed926f7dc24fb2a0a79819677125b87f..0f0813a46a2ece4be36dfa9bb5de3b0846468189 100644 --- a/src/mplfe/ast_input/lib/ast_type.cpp +++ b/src/mplfe/ast_input/lib/ast_type.cpp @@ -184,8 +184,7 @@ MIRType *LibAstFile::CvtArrayType(const clang::QualType srcType) { } if (srcType->isIncompleteArrayType()) { - // create pointer type - retType = GlobalTables::GetTypeTable().GetOrCreatePointerType(*retType); + retType = GlobalTables::GetTypeTable().GetOrCreateArrayType(*retType, 1); } return retType; } diff --git a/src/mplfe/ast_input/src/ast_decl.cpp b/src/mplfe/ast_input/src/ast_decl.cpp index c0efad941454df188cf178bd4bdc9e2cfa706dcc..eb6462fc5643068d1a18a0a63286f22434ff1ce7 100644 --- a/src/mplfe/ast_input/src/ast_decl.cpp +++ b/src/mplfe/ast_input/src/ast_decl.cpp @@ -33,6 +33,10 @@ const std::vector &ASTDecl::GetTypeDesc() const { return typeDesc; } +MIRConst *ASTDecl::Translate2MIRConst() const { + return Translate2MIRConstImpl(); +} + std::string ASTDecl::GenerateUniqueVarName() { // add `_line_column` suffix for avoiding local var name conflict if (isGlobalDecl || isParam) { @@ -51,6 +55,10 @@ std::unique_ptr ASTVar::Translate2FEIRVar() { return feirVar; } +MIRConst *ASTVar::Translate2MIRConstImpl() const { + return initExpr->GenerateMIRConst(); +} + void ASTVar::GenerateInitStmtImpl(std::list &stmts) { if (GetInitExpr() == nullptr) { return; diff --git a/src/mplfe/ast_input/src/ast_expr.cpp b/src/mplfe/ast_input/src/ast_expr.cpp index 8cf4187b23e119698aac4c009bec5d83195c7008..f3e80e1e7f197f06ecfefb1ecc919c1772b0da6d 100644 --- a/src/mplfe/ast_input/src/ast_expr.cpp +++ b/src/mplfe/ast_input/src/ast_expr.cpp @@ -25,6 +25,35 @@ #include "ast_util.h" namespace maple { +// ---------- ASTValue ---------- +MIRConst *ASTValue::Translate2MIRConst() const { + switch (pty) { + case PTY_i32: { + return GlobalTables::GetIntConstTable().GetOrCreateIntConst( + val.i32, *GlobalTables::GetTypeTable().GetPrimType(PTY_i32)); + } + case PTY_i64: { + return GlobalTables::GetIntConstTable().GetOrCreateIntConst( + val.i64, *GlobalTables::GetTypeTable().GetPrimType(PTY_i64)); + } + case PTY_f32: { + return FEManager::GetModule().GetMemPool()->New( + val.f32, *GlobalTables::GetTypeTable().GetPrimType(PTY_f32)); + } + case PTY_f64: { + return FEManager::GetModule().GetMemPool()->New( + val.f64, *GlobalTables::GetTypeTable().GetPrimType(PTY_f64)); + } + case PTY_a64: { + return FEManager::GetModule().GetMemPool()->New( + val.strIdx, *GlobalTables::GetTypeTable().GetPrimType(PTY_a64)); + } + default: { + CHECK_FATAL(false, "Unsupported Primitive type: %d", pty); + } + } +} + // ---------- ASTExpr ---------- UniqueFEIRExpr ASTExpr::Emit2FEExpr(std::list &stmts) const { return Emit2FEExprImpl(stmts); @@ -75,7 +104,31 @@ UniqueFEIRExpr ASTExpr::ImplicitInitFieldValue(MIRType *type, std::listTranslate2MIRConst(); +} + // ---------- ASTDeclRefExpr --------- +MIRConst *ASTDeclRefExpr::GenerateMIRConstImpl() const { + MIRType *mirType = refedDecl->GetTypeDesc().front(); + if (mirType->GetKind() == kTypePointer && + static_cast(mirType)->GetPointedType()->GetKind() == kTypeFunction) { + GStrIdx idx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(refedDecl->GetName()); +#ifndef USE_OPS + MIRSymbol *funcSymbol = SymbolBuilder::Instance().GetSymbolFromStrIdx(idx); +#else + MIRSymbol *funcSymbol = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(idx); +#endif + CHECK_FATAL(funcSymbol != nullptr, "Should process func decl before var decl"); + 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 { + return GetConstantValue()->Translate2MIRConst(); + } +} + UniqueFEIRExpr ASTDeclRefExpr::Emit2FEExprImpl(std::list &stmts) const { MIRType *mirType = refedDecl->GetTypeDesc().front(); UniqueFEIRExpr feirRefExpr; @@ -179,6 +232,78 @@ UniqueFEIRExpr ASTCallExpr::Emit2FEExprImpl(std::list &stmts) co } // ---------- ASTImplicitCastExpr ---------- +ASTValue *ASTImplicitCastExpr::GetConstantValueImpl() const { + return child->GetConstantValue(); +} + +MIRConst *ASTImplicitCastExpr::GenerateMIRConstImpl() const { + if (isArrayToPointerDecay && child->GetASTOp() == kASTStringLiteral) { + return FEManager::GetModule().GetMemPool()->New( + GetConstantValue()->val.strIdx, *GlobalTables::GetTypeTable().GetPrimType(PTY_a64)); + } else if (isNeededCvt) { + if (dst->GetPrimType() == PTY_f64) { + return GenerateMIRDoubleConst(); + } else if (dst->GetPrimType() == PTY_f32) { + return GenerateMIRFloatConst(); + } else { + return GenerateMIRIntConst(); + } + } else { + return child->GenerateMIRConst(); + } +} + +MIRConst *ASTImplicitCastExpr::GenerateMIRDoubleConst() const { + switch (GetConstantValue()->pty) { + case PTY_f32: { + return FEManager::GetModule().GetMemPool()->New( + static_cast(GetConstantValue()->val.f32), *GlobalTables::GetTypeTable().GetPrimType(PTY_f64)); + } + case PTY_i64: { + return FEManager::GetModule().GetMemPool()->New( + static_cast(GetConstantValue()->val.i64), *GlobalTables::GetTypeTable().GetPrimType(PTY_f64)); + } + default: { + CHECK_FATAL(false, "Unsupported pty type: %d", GetConstantValue()->pty); + return nullptr; + } + } +} + +MIRConst *ASTImplicitCastExpr::GenerateMIRFloatConst() const { + switch (GetConstantValue()->pty) { + case PTY_f64: { + return FEManager::GetModule().GetMemPool()->New( + static_cast(GetConstantValue()->val.f64), *GlobalTables::GetTypeTable().GetPrimType(PTY_f32)); + } + case PTY_i64: { + return FEManager::GetModule().GetMemPool()->New( + static_cast(GetConstantValue()->val.i64), *GlobalTables::GetTypeTable().GetPrimType(PTY_f32)); + } + default: { + CHECK_FATAL(false, "Unsupported pty type: %d", GetConstantValue()->pty); + return nullptr; + } + } +} + +MIRConst *ASTImplicitCastExpr::GenerateMIRIntConst() const { + switch (GetConstantValue()->pty) { + case PTY_f64: { + return FEManager::GetModule().GetMemPool()->New( + static_cast(GetConstantValue()->val.f64), *GlobalTables::GetTypeTable().GetPrimType(PTY_i64)); + } + case PTY_i64: { + return FEManager::GetModule().GetMemPool()->New( + GetConstantValue()->val.i64, *GlobalTables::GetTypeTable().GetPrimType(PTY_i64)); + } + default: { + CHECK_FATAL(false, "Unsupported pty type: %d", GetConstantValue()->pty); + return nullptr; + } + } +} + UniqueFEIRExpr ASTImplicitCastExpr::Emit2FEExprImpl(std::list &stmts) const { const ASTExpr *childExpr = child; CHECK_FATAL(childExpr != nullptr, "childExpr is nullptr"); @@ -295,7 +420,7 @@ UniqueFEIRExpr ASTUOPostIncExpr::Emit2FEExprImpl(std::list &stmt UniqueFEIRVar selfVar = FEIRBuilder::CreateVarNameForC(refedDecl->GenerateUniqueVarName(), *subType, isGlobal, false); UniqueFEIRVar selfMoveVar = selfVar->Clone(); - UniqueFEIRVar tempVar = FEIRBuilder::CreateVarNameForC(FEUtils::GetSequentialName("postinc_"), *subType); + UniqueFEIRVar tempVar = FEIRBuilder::CreateVarNameForC(tempVarName, *subType); UniqueFEIRVar tempMoveVar = tempVar->Clone(); UniqueFEIRExpr readSelfExpr = FEIRBuilder::CreateExprDRead(std::move(selfMoveVar)); UniqueFEIRStmt readSelfstmt = FEIRBuilder::CreateStmtDAssign(std::move(tempMoveVar), std::move(readSelfExpr)); @@ -321,7 +446,7 @@ UniqueFEIRExpr ASTUOPostDecExpr::Emit2FEExprImpl(std::list &stmt UniqueFEIRVar selfVar = FEIRBuilder::CreateVarNameForC(refedDecl->GenerateUniqueVarName(), *subType, isGlobal, false); UniqueFEIRVar selfMoveVar = selfVar->Clone(); - UniqueFEIRVar tempVar = FEIRBuilder::CreateVarNameForC(FEUtils::GetSequentialName("postinc_"), *subType); + UniqueFEIRVar tempVar = FEIRBuilder::CreateVarNameForC(tempVarName, *subType); UniqueFEIRVar tempMoveVar = tempVar->Clone(); UniqueFEIRExpr readSelfExpr = FEIRBuilder::CreateExprDRead(std::move(selfMoveVar)); UniqueFEIRStmt readSelfstmt = FEIRBuilder::CreateStmtDAssign(std::move(tempMoveVar), @@ -379,6 +504,23 @@ UniqueFEIRExpr ASTUOPreDecExpr::Emit2FEExprImpl(std::list &stmts return feirRefExpr; } +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; + } + default: { + CHECK_FATAL(false, "lValue in expr: %d NIY", expr->GetASTOp()); + } + } + return nullptr; +} + UniqueFEIRExpr ASTUOAddrOfExpr::Emit2FEExprImpl(std::list &stmts) const { ASTExpr *childExpr = expr; CHECK_FATAL(childExpr != nullptr, "childExpr is nullptr"); @@ -428,7 +570,7 @@ UniqueFEIRExpr ASTUODerefExpr::Emit2FEExprImpl(std::list &stmts) static_cast(uoType)->GetPointedType()->GetKind() == kTypeFunction) { return childFEIRExpr; } - UniqueFEIRExpr derefExpr = FEIRBuilder::CreateExprIRead(std::move(retType), std::move(ptrType), 0, + UniqueFEIRExpr derefExpr = FEIRBuilder::CreateExprIRead(std::move(retType), std::move(ptrType), std::move(childFEIRExpr)); return derefExpr; } @@ -611,6 +753,47 @@ UniqueFEIRExpr ASTOffsetOfExpr::Emit2FEExprImpl(std::list &stmts } // ---------- ASTInitListExpr ---------- +MIRConst *ASTInitListExpr::GenerateMIRConstImpl() const { + if (!initListType->IsStructType()) { + return GenerateMIRConstForArray(); + } else { + return GenerateMIRConstForStruct(); + } +} + +MIRConst *ASTInitListExpr::GenerateMIRConstForArray() const { + if (fillers.size() == 1 && fillers[0]->GetASTOp() == kASTStringLiteral) { + return fillers[0]->GenerateMIRConst(); + } + MIRAggConst *aggConst = FEManager::GetModule().GetMemPool()->New(FEManager::GetModule(), *initListType); +#ifndef USE_OPS + CHECK_FATAL(false, "Not support"); +#else + for (size_t i = 0; i < fillers.size(); ++i) { + if (fillers[i]->GetASTOp() == kASTImplicitValueInitExpr) { + continue; + } + aggConst->AddItem(fillers[i]->GenerateMIRConst(), 0); + } +#endif + return aggConst; +} + +MIRConst *ASTInitListExpr::GenerateMIRConstForStruct() const { + MIRAggConst *aggConst = FEManager::GetModule().GetMemPool()->New(FEManager::GetModule(), *initListType); +#ifndef USE_OPS + CHECK_FATAL(false, "Not support"); +#else + for (size_t i = 0; i < fillers.size(); ++i) { + if (fillers[i]->GetASTOp() == kASTImplicitValueInitExpr) { + continue; + } + aggConst->AddItem(fillers[i]->GenerateMIRConst(), i + 1); + } +#endif + return aggConst; +} + UniqueFEIRExpr ASTInitListExpr::Emit2FEExprImpl(std::list &stmts) const { if (!initListType->IsStructType()) { Emit2FEExprForArray(stmts); @@ -714,10 +897,27 @@ void ASTInitListExpr::SetInitListType(MIRType *type) { initListType = type; } +// ---------- ASTImplicitValueInitExpr ---------- +MIRConst *ASTImplicitValueInitExpr::GenerateMIRConstImpl() const { + CHECK_FATAL(false, "Should not generate const val for ImplicitValueInitExpr"); + return nullptr; +} + UniqueFEIRExpr ASTImplicitValueInitExpr::Emit2FEExprImpl(std::list &stmts) const { return ImplicitInitFieldValue(type, stmts); } +MIRConst *ASTStringLiteral::GenerateMIRConstImpl() const { + MIRType *elemType = GlobalTables::GetTypeTable().GetPrimType(PTY_i8); + MIRType *arrayTypeWithSize = GlobalTables::GetTypeTable().GetOrCreateArrayType(*elemType, codeUnits.size()); + MIRAggConst *val = FEManager::GetModule().GetMemPool()->New(FEManager::GetModule(), *arrayTypeWithSize); + for (uint32 i = 0; i < codeUnits.size(); ++i) { + MIRConst *cst = FEManager::GetModule().GetMemPool()->New(codeUnits[i], *elemType); + val->PushBack(cst); + } + return val; +} + UniqueFEIRExpr ASTStringLiteral::Emit2FEExprImpl(std::list &stmts) const { UniqueFEIRExpr expr = std::make_unique(codeUnits); CHECK_NULL_FATAL(expr); @@ -791,6 +991,11 @@ UniqueFEIRExpr ASTMemberExpr::Emit2FEExprImpl(std::list &stmts) } } +// ---------- ASTDesignatedInitUpdateExpr ---------- +MIRConst *ASTDesignatedInitUpdateExpr::GenerateMIRConstImpl() const { + return FEManager::GetModule().GetMemPool()->New(FEManager::GetModule(), *initListType); +} + UniqueFEIRExpr ASTDesignatedInitUpdateExpr::Emit2FEExprImpl(std::list &stmts) const { UniqueFEIRVar feirVar = FEIRBuilder::CreateVarNameForC(initListVarName, *initListType); UniqueFEIRExpr baseFEIRExpr = baseExpr->Emit2FEExpr(stmts); @@ -809,8 +1014,8 @@ UniqueFEIRExpr ASTBinaryOperatorExpr::Emit2FEExprImpl(std::list rightRealExpr->Emit2FEExpr(stmts)); UniqueFEIRExpr imagFEExpr = FEIRBuilder::CreateExprBinary(opcode, leftImagExpr->Emit2FEExpr(stmts), rightImagExpr->Emit2FEExpr(stmts)); - auto realStmt = FEIRBuilder::CreateStmtDAssign(tempVar->Clone(), std::move(realFEExpr), kComplexRealID); - auto imagStmt = FEIRBuilder::CreateStmtDAssign(tempVar->Clone(), std::move(imagFEExpr), kComplexImagID); + auto realStmt = FEIRBuilder::CreateStmtDAssignAggField(tempVar->Clone(), std::move(realFEExpr), kComplexRealID); + auto imagStmt = FEIRBuilder::CreateStmtDAssignAggField(tempVar->Clone(), std::move(imagFEExpr), kComplexImagID); stmts.emplace_back(std::move(realStmt)); stmts.emplace_back(std::move(imagStmt)); auto dread = FEIRBuilder::CreateExprDRead(std::move(tempVar)); @@ -834,7 +1039,8 @@ UniqueFEIRExpr ASTBinaryOperatorExpr::Emit2FEExprImpl(std::list } else { auto leftFEExpr = leftExpr->Emit2FEExpr(stmts); auto rightFEExpr = rightExpr->Emit2FEExpr(stmts); - return FEIRBuilder::CreateExprBinary(opcode, std::move(leftFEExpr), std::move(rightFEExpr)); + UniqueFEIRType feirType = std::make_unique(*retType); + return FEIRBuilder::CreateExprBinary(std::move(feirType), opcode, std::move(leftFEExpr), std::move(rightFEExpr)); } } @@ -1019,7 +1225,165 @@ UniqueFEIRExpr ASTCompoundAssignOperatorExpr::Emit2FEExprImpl(std::list &stmts) const { - return nullptr; + CHECK_NULL_FATAL(mirType); + VaArgInfo info = ProcessValistArgInfo(*mirType); + UniqueFEIRExpr dreadVaList = child->Emit2FEExpr(stmts); + CHECK_FATAL(dreadVaList->GetKind() == kExprDRead, "expr must be kExprDRead, %u", dreadVaList->GetKind()); + UniqueFEIRVar vaListVar = static_cast(dreadVaList.get())->GetVar()->Clone(); + // The va_arg_offset temp var is created and assigned from __gr_offs or __vr_offs of va_list + MIRType *int32Type = GlobalTables::GetTypeTable().GetInt32(); + UniqueFEIRVar offsetVar = FEIRBuilder::CreateVarNameForC(FEUtils::GetSequentialName("va_arg_offs_"), *int32Type); + UniqueFEIRExpr dreadVaListOffset = FEIRBuilder::CreateExprDReadAggField( + vaListVar->Clone(), info.isGPReg ? 4 : 5, int32Type); + UniqueFEIRStmt dassignOffsetVar = FEIRBuilder::CreateStmtDAssign(offsetVar->Clone(), dreadVaListOffset->Clone()); + stmts.emplace_back(std::move(dassignOffsetVar)); + UniqueFEIRExpr dreadOffsetVar = FEIRBuilder::CreateExprDRead(offsetVar->Clone()); + // The va_arg temp var is created and assigned in tow following way: + // If the va_arg_offs is vaild, i.e., its value should be (0 - (8 - named_arg) * 8) ~ 0, + // the va_arg will be got from GP or FP/SIMD arg reg, otherwise va_arg will be got from stack. + // See https://developer.arm.com/documentation/ihi0055/latest/ for more info about the va_list type + MIRType *uint64Type = GlobalTables::GetTypeTable().GetUInt64(); + UniqueFEIRType uint64FEIRType = std::make_unique(*uint64Type); + MIRType *ptrType = GlobalTables::GetTypeTable().GetOrCreatePointerType((!info.isCopyedMem ? *mirType : *uint64Type)); + UniqueFEIRVar vaArgVar = FEIRBuilder::CreateVarNameForC(FEUtils::GetSequentialName("va_arg"), *ptrType); + UniqueFEIRExpr dreadVaArgTop = FEIRBuilder::CreateExprDReadAggField( + vaListVar->Clone(), info.isGPReg ? 2 : 3, uint64Type); + UniqueFEIRExpr cvtOffset = FEIRBuilder::CreateExprCvtPrim(dreadOffsetVar->Clone(), PTY_u64); + UniqueFEIRExpr addTopAndOffs = FEIRBuilder::CreateExprBinary(OP_add, std::move(dreadVaArgTop), std::move(cvtOffset)); + UniqueFEIRStmt dassignVaArgFromReg = FEIRBuilder::CreateStmtDAssign(vaArgVar->Clone(), std::move(addTopAndOffs)); + UniqueFEIRExpr condLower = FEIRBuilder::CreateExprBinary( // checking validity: regOffset < 0 + OP_lt, dreadOffsetVar->Clone(), FEIRBuilder::CreateExprConstI32(0)); + UniqueFEIRExpr condUpper = FEIRBuilder::CreateExprBinary( // checking validity: regOffset + next offset <= 0 + OP_le, dreadVaListOffset->Clone(), FEIRBuilder::CreateExprConstI32(0)); + UniqueFEIRExpr ArgAUnitOffs = FEIRBuilder::CreateExprBinary( + OP_add, dreadOffsetVar->Clone(), FEIRBuilder::CreateExprConstI32(info.regOffset)); + std::list trueStmtsInLower; + std::list trueStmtsInUpper; + std::list falseStmtsInLower; + // The va_arg will be got from GP or FP/SIMD arg reg and set next reg setoff + UniqueFEIRStmt dassignArgNextOffs = FEIRBuilder::CreateStmtDAssignAggField( + vaListVar->Clone(), std::move(ArgAUnitOffs), info.isGPReg ? 4 : 5); + trueStmtsInUpper.emplace_back(std::move(dassignVaArgFromReg)); + if (info.isHFA && !info.isCopyedMem) { + UniqueFEIRVar copyedVar = FEIRBuilder::CreateVarNameForC(FEUtils::GetSequentialName("va_arg_struct"), *mirType); + CvtHFA2Struct(*static_cast(mirType), vaArgVar->Clone(), std::move(copyedVar), trueStmtsInUpper); + } + UniqueFEIRStmt stmtIfCondUpper = FEIRBuilder::CreateStmtIfWithoutElse(std::move(condUpper), trueStmtsInUpper); + trueStmtsInLower.emplace_back(std::move(dassignArgNextOffs)); + trueStmtsInLower.emplace_back(std::move(stmtIfCondUpper)); + // Otherwise, the va_arg will be got from stack and set next stack setoff + UniqueFEIRExpr dreadStackTop = FEIRBuilder::CreateExprDReadAggField(vaListVar->Clone(), 1, uint64Type); + UniqueFEIRStmt dassignVaArgFromStack = FEIRBuilder::CreateStmtDAssign(vaArgVar->Clone(), dreadStackTop->Clone()); + UniqueFEIRExpr stackAUnitOffs = FEIRBuilder::CreateExprBinary( + OP_add, dreadStackTop->Clone(), FEIRBuilder::CreateExprConstU64(info.stackOffset)); + UniqueFEIRStmt dassignStackNextOffs = FEIRBuilder::CreateStmtDAssignAggField( + vaListVar->Clone(), std::move(stackAUnitOffs), 1); + falseStmtsInLower.emplace_back(std::move(dassignVaArgFromStack)); + falseStmtsInLower.emplace_back(std::move(dassignStackNextOffs)); + UniqueFEIRStmt stmtIfCondLower = FEIRBuilder::CreateStmtIf(std::move(condLower), trueStmtsInLower, falseStmtsInLower); + stmts.emplace_back(std::move(stmtIfCondLower)); + // return va_arg + UniqueFEIRExpr dreadRetVar = FEIRBuilder::CreateExprDRead(vaArgVar->Clone()); + if (info.isCopyedMem) { + UniqueFEIRType ptrPtrFEIRType = std::make_unique( + *GlobalTables::GetTypeTable().GetOrCreatePointerType(*ptrType)); + dreadRetVar = FEIRBuilder::CreateExprIRead( + std::move(uint64FEIRType), std::move(ptrPtrFEIRType), std::move(dreadRetVar)); + } + UniqueFEIRType baseFEIRType = std::make_unique(*mirType); + UniqueFEIRType ptrFEIRType = std::make_unique(*ptrType); + UniqueFEIRExpr retExpr = FEIRBuilder::CreateExprIRead( + std::move(baseFEIRType), std::move(ptrFEIRType), std::move(dreadRetVar)); + return retExpr; +} + +VaArgInfo ASTVAArgExpr::ProcessValistArgInfo(MIRType &type) const { + VaArgInfo info; + if (type.IsScalarType()) { + switch (type.GetPrimType()) { + case PTY_f32: // float is automatically promoted to double when passed to va_arg + WARN(kLncWarn, "error: float is promoted to double when passed to va_arg"); + case PTY_f64: // double + info = { false, 16, 8, false, false }; + break; + case PTY_i32: + case PTY_i64: + info = { true, 8, 8, false, false }; + break; + default: // bool, char, short, and unscoped enumerations are converted to int or wider integer types + WARN(kLncWarn, "error: bool, char, short, and unscoped enumerations are promoted to int or "\ + "wider integer types when passed to va_arg"); + info = { true, 8, 8, false, false }; + break; + } + } else if (type.IsMIRPtrType()) { + info = { true, 8, 8, false, false }; + } else if (type.IsStructType()) { + MIRStructType structType = static_cast(type); + size_t size = structType.GetSize(); + size = (size + 7) & -8; // size round up 8 + if (size > 16) { + info = { true, 8, 8, true, false }; + } else if (IsHFAType(structType)) { + int fieldsSize = static_cast(structType.GetFieldsSize()); + info = { false, fieldsSize * 16, static_cast(size), false, true }; + } else { + info = { true, static_cast(size), static_cast(size), false, false }; + } + } else { + CHECK_FATAL(false, "unsupport mirtype"); + } + return info; +} + +// Homogeneous Floating-point Aggregate: +// A data type with 2 to 4 identical floating-point members, either floats or doubles. (including 1 members here) +bool ASTVAArgExpr::IsHFAType(MIRStructType &type) const { + size_t size = type.GetFieldsSize(); + if (size < 1 || size > 4) { + return false; + } + PrimType firstFieldPrimType; + for (size_t i = 0; i < size; ++i) { + MIRType *fieldType = type.GetElemType(i); + if (fieldType->GetPrimType() != PTY_f32 && fieldType->GetPrimType() != PTY_f64) { + return false; + } + if (i == 0) { + firstFieldPrimType = fieldType->GetPrimType(); + } else { + if (fieldType->GetPrimType() != firstFieldPrimType) { + return false; + } + } + } + return true; +} + +// When va_arg is HFA struct, +// if it is passed as parameter in register then each uniquely addressable field goes in its own register. +// So its fields in FP/SIMD arg reg are still 128 bit and should be converted float or double type fields. +void ASTVAArgExpr::CvtHFA2Struct(MIRStructType &structType, UniqueFEIRVar vaArgVar, UniqueFEIRVar copyedVar, + std::list &stmts) const { + int size = static_cast(structType.GetFieldsSize()); + MIRType *fieldType = structType.GetElemType(0); + MIRType *ptrMirType = GlobalTables::GetTypeTable().GetOrCreatePointerType(*fieldType); + UniqueFEIRType baseType = std::make_unique(*fieldType); + UniqueFEIRType ptrType = std::make_unique(*ptrMirType); + for (int i = 0; i < size; ++i) { + UniqueFEIRExpr dreadVaArg = FEIRBuilder::CreateExprDRead(vaArgVar->Clone()); + if (i != 0) { + dreadVaArg = FEIRBuilder::CreateExprBinary( + OP_add, std::move(dreadVaArg), FEIRBuilder::CreateExprConstU64(16 * i)); + } + UniqueFEIRExpr ireadVaArg = FEIRBuilder::CreateExprIRead(baseType->Clone(), ptrType->Clone(), dreadVaArg->Clone()); + UniqueFEIRStmt dassignCopyedVar = FEIRBuilder::CreateStmtDAssignAggField( + copyedVar->Clone(), std::move(ireadVaArg), (i + 1)); + stmts.emplace_back(std::move(dassignCopyedVar)); + } + UniqueFEIRExpr addrofCopyedVar = FEIRBuilder::CreateExprAddrofVar(copyedVar->Clone()); + UniqueFEIRStmt assignVar = FEIRBuilder::CreateStmtDAssign(vaArgVar->Clone(), std::move(addrofCopyedVar)); + stmts.emplace_back(std::move(assignVar)); } // ---------- ASTCStyleCastExpr ---------- diff --git a/src/mplfe/ast_input/src/ast_parser.cpp b/src/mplfe/ast_input/src/ast_parser.cpp index 0d5ae053e6cb6838af0c987715b7d235c23a919a..21f7d95304642acf3dc6ee8902650469a0ebead5 100644 --- a/src/mplfe/ast_input/src/ast_parser.cpp +++ b/src/mplfe/ast_input/src/ast_parser.cpp @@ -340,7 +340,7 @@ ASTStmt *ASTParser::ProcessStmtForStmt(MapleAllocator &allocator, const clang::F astStmt->SetIncExpr(incExpr); } ASTStmt *bodyStmt = nullptr; - if (llvm::isa(forStmt.getBody())) { + if (forStmt.getBody()->getStmtClass() == clang::Stmt::CompoundStmtClass) { const auto *tmpCpdStmt = llvm::cast(forStmt.getBody()); bodyStmt = ProcessStmtCompoundStmt(allocator, *tmpCpdStmt); } else { @@ -359,7 +359,7 @@ ASTStmt *ASTParser::ProcessStmtWhileStmt(MapleAllocator &allocator, const clang: } astStmt->SetCondExpr(condExpr); ASTStmt *bodyStmt = nullptr; - if (llvm::isa(whileStmt.getBody())) { + if (whileStmt.getBody()->getStmtClass() == clang::Stmt::CompoundStmtClass) { const auto *tmpCpdStmt = llvm::cast(whileStmt.getBody()); bodyStmt = ProcessStmtCompoundStmt(allocator, *tmpCpdStmt); } else { @@ -542,9 +542,83 @@ ASTStmt *ASTParser::ProcessStmtDeclStmt(MapleAllocator &allocator, const clang:: return astStmt; } -#define EXPR_CASE(CLASS) \ - case clang::Stmt::CLASS##Class: \ - return ProcessExpr##CLASS(allocator, llvm::cast(*expr)); +ASTValue *ASTParser::TranslateRValue2ASTValue(MapleAllocator &allocator, const clang::Expr *expr) const { + ASTValue *astValue = nullptr; + clang::Expr::EvalResult result; + if (expr->EvaluateAsRValue(result, *(astFile->GetContext()))) { + astValue = AllocASTValue(allocator); + if (result.Val.isInt()) { + astValue->val.i64 = static_cast(result.Val.getInt().getExtValue()); + astValue->pty = PTY_i64; + } else if (result.Val.isFloat()) { + MIRType *exprMirType = astFile->CvtType(expr->getType()); + if (exprMirType->GetPrimType() == PTY_f64) { + astValue->val.f64 = result.Val.getFloat().convertToDouble(); + astValue->pty = PTY_f64; + } else { + astValue->val.f32 = result.Val.getFloat().convertToFloat(); + astValue->pty = PTY_f32; + } + } else if (result.Val.isComplexInt() || result.Val.isComplexFloat()) { + WARN(kLncWarn, "Unsupported complex value in MIR"); + } else if (result.Val.isVector() || result.Val.isMemberPointer() || result.Val.isAddrLabelDiff()) { + CHECK_FATAL(false, "NIY"); + } + // Others: Agg const processed in `InitListExpr` + } + return astValue; +} + +ASTValue *ASTParser::TranslateLValue2ASTValue(MapleAllocator &allocator, const clang::Expr *expr) const { + ASTValue *astValue = nullptr; + clang::Expr::EvalResult result; + if (expr->EvaluateAsLValue(result, *(astFile->GetContext()))) { + astValue = AllocASTValue(allocator); + const clang::APValue::LValueBase &lvBase = result.Val.getLValueBase(); + if (lvBase.is()) { + const clang::Expr *lvExpr = lvBase.get(); + astValue->pty = PTY_a64; + switch (lvExpr->getStmtClass()) { + case clang::Stmt::StringLiteralClass: { + std::string str = llvm::cast(*lvExpr).getString().str(); + UStrIdx strIdx = GlobalTables::GetUStrTable().GetOrCreateStrIdxFromName(str); + astValue->val.strIdx = strIdx; + break; + } + case clang::Stmt::PredefinedExprClass: { + std::string str = llvm::cast(*lvExpr).getFunctionName()->getString().str(); + UStrIdx strIdx = GlobalTables::GetUStrTable().GetOrCreateStrIdxFromName(str); + astValue->val.strIdx = strIdx; + break; + } + default: { + CHECK_FATAL(false, "Unsupported expr :%s in LValue", lvExpr->getStmtClassName()); + } + } + } else { + // `valueDecl` processed in corresponding expr + bool isValueDeclInLValueBase = lvBase.is(); + CHECK_FATAL(isValueDeclInLValueBase, "Unsupported lValue base"); + } + } + return astValue; +} + +ASTValue *ASTParser::TranslateExprEval(MapleAllocator &allocator, const clang::Expr *expr) const { + ASTValue *astValue = TranslateRValue2ASTValue(allocator, expr); + if (astValue == nullptr) { + astValue = TranslateLValue2ASTValue(allocator, expr); + } + return astValue; +} + +#define EXPR_CASE(CLASS) \ + case clang::Stmt::CLASS##Class: { \ + ASTExpr *astExpr = ProcessExpr##CLASS(allocator, llvm::cast(*expr)); \ + astExpr->SetConstantValue(TranslateExprEval(allocator, expr)); \ + return astExpr; \ + } + ASTExpr *ASTParser::ProcessExpr(MapleAllocator &allocator, const clang::Expr *expr) { if (expr == nullptr) { return nullptr; @@ -633,6 +707,10 @@ ASTUnaryOperatorExpr *ASTParser::AllocUnaryOperatorExpr(MapleAllocator &allocato } } +ASTValue *ASTParser::AllocASTValue(MapleAllocator &allocator) const { + return allocator.GetMemPool()->New(); +} + const clang::Expr *ASTParser::PeelParen(const clang::Expr &expr) { const clang::Expr *exprPtr = &expr; while (llvm::isa(exprPtr) || @@ -828,6 +906,7 @@ ASTExpr *ASTParser::ProcessExprVAArgExpr(MapleAllocator &allocator, const clang: return nullptr; } astVAArgExpr->SetASTExpr(astExpr); + astVAArgExpr->SetType(astFile->CvtType(expr.getType())); return astVAArgExpr; } @@ -1198,6 +1277,11 @@ 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()); @@ -1214,7 +1298,10 @@ ASTExpr *ASTParser::ProcessExprImplicitCastExpr(MapleAllocator &allocator, const CHECK_FATAL(astImplicitCastExpr != nullptr, "astImplicitCastExpr is nullptr"); switch (expr.getCastKind()) { case clang::CK_NoOp: + break; case clang::CK_ArrayToPointerDecay: + astImplicitCastExpr->SetIsArrayToPointerDecay(true); + break; case clang::CK_FunctionToPointerDecay: case clang::CK_LValueToRValue: case clang::CK_BitCast: @@ -1276,14 +1363,10 @@ ASTExpr *ASTParser::ProcessExprDeclRefExpr(MapleAllocator &allocator, const clan CHECK_FATAL(astRefExpr != nullptr, "astRefExpr is nullptr"); switch (expr.getStmtClass()) { case clang::Stmt::DeclRefExprClass: { - const auto *namedDecl = llvm::dyn_cast(expr.getDecl()->getCanonicalDecl()); - std::string refName = astFile->GetMangledName(*namedDecl); - clang::QualType qualType = expr.getDecl()->getType(); - MIRType *refType = astFile->CvtType(qualType); - ASTDecl *astDecl = ASTDeclsBuilder::ASTDeclBuilder(allocator, fileName, refName, std::vector{refType}); - astDecl->SetDeclPos(astFile->GetDeclPosInfo(*namedDecl)); - astDecl->SetGlobal(expr.getDecl()->getCanonicalDecl()->isDefinedOutsideFunctionOrMethod()); - astDecl->SetIsParam(expr.getDecl()->getKind() == clang::Decl::ParmVar); + ASTDecl *astDecl = ASTDeclsBuilder::GetASTDecl(expr.getDecl()->getCanonicalDecl()->getID()); + if (astDecl == nullptr) { + astDecl = ProcessDecl(allocator, *(expr.getDecl()->getCanonicalDecl())); + } astRefExpr->SetASTDecl(astDecl); astRefExpr->SetType(astDecl->GetTypeDesc().front()); return astRefExpr; @@ -1338,19 +1421,21 @@ ASTExpr *ASTParser::ProcessExprBinaryOperator(MapleAllocator &allocator, const c ASTExpr *astLExpr = ProcessExpr(allocator, bo.getLHS()); if (bo.getType()->isPointerType() && bo.isAdditiveOp()) { auto ptrSizeExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); - ptrSizeExpr->SetType(PTY_ptr); + ptrSizeExpr->SetType(astBinOpExpr->GetRetType()->GetPrimType()); 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); + rhs->SetRetType(astBinOpExpr->GetRetType()); astRExpr = rhs; } else if (bo.getRHS()->getType()->isPointerType()) { auto lhs = ASTDeclsBuilder::ASTExprBuilder(allocator); lhs->SetLeftExpr(astLExpr); lhs->SetRightExpr(ptrSizeExpr); lhs->SetOpcode(OP_mul); + lhs->SetRetType(astBinOpExpr->GetRetType()); astLExpr = lhs; } } @@ -1359,12 +1444,13 @@ ASTExpr *ASTParser::ProcessExprBinaryOperator(MapleAllocator &allocator, const c if (bo.getOpcode() == clang::BO_Sub && bo.getRHS()->getType()->isPointerType() && bo.getLHS()->getType()->isPointerType()) { auto ptrSizeExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); - ptrSizeExpr->SetType(PTY_ptr); + ptrSizeExpr->SetType(astBinOpExpr->GetRetType()->GetPrimType()); ptrSizeExpr->SetVal(GetSizeFromQualType(bo.getRHS()->getType()->getPointeeType())); auto retASTExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); retASTExpr->SetLeftExpr(astBinOpExpr); retASTExpr->SetRightExpr(ptrSizeExpr); retASTExpr->SetOpcode(OP_div); + retASTExpr->SetRetType(astBinOpExpr->GetRetType()); astBinOpExpr = retASTExpr; } return astBinOpExpr; @@ -1586,8 +1672,10 @@ ASTDecl *ASTParser::ProcessDecl(MapleAllocator &allocator, const clang::Decl &de DECL_CASE(Field); DECL_CASE(Record); DECL_CASE(Var); + DECL_CASE(ParmVar); DECL_CASE(Enum); DECL_CASE(Typedef); + DECL_CASE(EnumConstant); default: CHECK_FATAL(false, "ASTDecl: %s NIY", decl.getDeclKindName()); return nullptr; @@ -1610,8 +1698,8 @@ ASTDecl *ASTParser::ProcessDeclRecordDecl(MapleAllocator &allocator, const clang uint32 id = qType->getAs()->getDecl()->getLocation().getRawEncoding(); structName = astFile->GetOrCreateMappedUnnamedName(id); } - ASTStruct *curStructOrUnion = - ASTDeclsBuilder::ASTStructBuilder(allocator, fileName, structName, std::vector{recType}, attrs); + ASTStruct *curStructOrUnion = ASTDeclsBuilder::ASTStructBuilder( + allocator, fileName, structName, std::vector{recType}, attrs, recDecl.getID()); if (recDecl.isUnion()) { curStructOrUnion->SetIsUnion(); } @@ -1656,32 +1744,28 @@ ASTDecl *ASTParser::ProcessDeclFunctionDecl(MapleAllocator &allocator, const cla if (!ASTUtil::IsValidName(funcName)) { ASTUtil::AdjustName(funcName); } + std::vector typeDescIn; + clang::QualType funcQualType = funcDecl.getType(); + MIRType *mirFuncType = astFile->CvtType(funcQualType); + typeDescIn.push_back(mirFuncType); clang::QualType qualType = funcDecl.getReturnType(); MIRType *retType = astFile->CvtType(qualType); if (retType == nullptr) { return nullptr; } - std::vector typeDescIn; std::vector parmNamesIn; typeDescIn.push_back(retType); unsigned int numParam = funcDecl.getNumParams(); for (uint32_t i = 0; i < numParam; ++i) { const clang::ParmVarDecl *parmDecl = funcDecl.getParamDecl(i); - const clang::QualType parmQualType = parmDecl->getType(); - std::string parmName = parmDecl->getNameAsString(); - if (parmName.length() == 0) { - parmName = FEUtils::GetSequentialName0("arg|", i); - } - parmNamesIn.emplace_back(parmName); - MIRType *paramType = astFile->CvtType(parmQualType); - if (paramType == nullptr) { - return nullptr; - } - typeDescIn.push_back(paramType); + ASTDecl *parmVarDecl = ProcessDeclParmVarDecl(allocator, *parmDecl); + parmNamesIn.emplace_back(parmVarDecl->GetName()); + typeDescIn.push_back(parmVarDecl->GetTypeDesc().front()); } GenericAttrs attrs; astFile->CollectFuncAttrs(funcDecl, attrs, kPublic); - ASTFunc *astFunc = ASTDeclsBuilder::ASTFuncBuilder(allocator, fileName, funcName, typeDescIn, attrs, parmNamesIn); + ASTFunc *astFunc = ASTDeclsBuilder::ASTFuncBuilder( + allocator, fileName, funcName, typeDescIn, attrs, parmNamesIn, funcDecl.getID()); CHECK_FATAL(astFunc != nullptr, "astFunc is nullptr"); if (funcDecl.hasBody()) { ASTStmt *astCompoundStmt = ProcessStmtCompoundStmt(allocator, @@ -1730,7 +1814,8 @@ ASTDecl *ASTParser::ProcessDeclVarDecl(MapleAllocator &allocator, const clang::V } GenericAttrs attrs; astFile->CollectAttrs(varDecl, attrs, kPublic); - ASTVar *astVar = ASTDeclsBuilder::ASTVarBuilder(allocator, fileName, varName, std::vector{varType}, attrs); + ASTVar *astVar = ASTDeclsBuilder::ASTVarBuilder( + allocator, fileName, varName, std::vector{varType}, attrs, varDecl.getID()); if (varDecl.hasInit()) { astVar->SetDeclPos(astFile->GetDeclPosInfo(varDecl)); @@ -1744,6 +1829,24 @@ ASTDecl *ASTParser::ProcessDeclVarDecl(MapleAllocator &allocator, const clang::V return astVar; } +ASTDecl *ASTParser::ProcessDeclParmVarDecl(MapleAllocator &allocator, const clang::ParmVarDecl &parmVarDecl) { + const clang::QualType parmQualType = parmVarDecl.getType(); + std::string parmName = parmVarDecl.getNameAsString(); + if (parmName.length() == 0) { + parmName = FEUtils::GetSequentialName("arg|"); + } + MIRType *paramType = astFile->CvtType(parmQualType); + if (paramType == nullptr) { + return nullptr; + } + GenericAttrs attrs; + astFile->CollectAttrs(parmVarDecl, attrs, kPublic); + ASTVar *parmVar = ASTDeclsBuilder::ASTVarBuilder( + allocator, fileName, parmName, std::vector{paramType}, attrs, parmVarDecl.getID()); + parmVar->SetIsParam(true); + return parmVar; +} + ASTDecl *ASTParser::ProcessDeclEnumDecl(MapleAllocator &allocator, const clang::EnumDecl &enumDecl) { GenericAttrs attrs; astFile->CollectAttrs(*clang::dyn_cast(&enumDecl), attrs, kPublic); @@ -1752,19 +1855,7 @@ ASTDecl *ASTParser::ProcessDeclEnumDecl(MapleAllocator &allocator, const clang:: std::vector{}, attrs); TraverseDecl(&enumDecl, [&](clang::Decl *child) { CHECK_FATAL(child->getKind() == clang::Decl::EnumConstant, "Unsupported decl kind: %u", child->getKind()); - GenericAttrs attrs0; - astFile->CollectAttrs(*clang::dyn_cast(child), attrs0, kPublic); - const std::string &varName = clang::dyn_cast(child)->getNameAsString(); - MIRType *mirType = astFile->CvtType(clang::dyn_cast(child)->getType()); - ASTVar *astVar = - ASTDeclsBuilder::ASTVarBuilder(allocator, fileName, varName, std::vector{mirType}, attrs0); - astVar->SetDeclPos(astFile->GetDeclPosInfo(*child)); - auto constExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); - constExpr->SetVal( - static_cast(clang::dyn_cast(child)->getInitVal().getExtValue())); - constExpr->SetType(mirType->GetPrimType()); - astVar->SetInitExpr(constExpr); - localEnumDecl->PushConstantVar(astVar); + localEnumDecl->PushConstantVar(static_cast(ProcessDecl(allocator, *child))); }); return localEnumDecl; } @@ -1783,6 +1874,27 @@ ASTDecl *ASTParser::ProcessDeclTypedefDecl(MapleAllocator &allocator, const clan return nullptr; // skip primitive type and explicit declared type } +ASTDecl *ASTParser::ProcessDeclEnumConstantDecl(MapleAllocator &allocator, const clang::EnumConstantDecl &decl) { + 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 *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; +} + bool ASTParser::RetrieveStructs(MapleAllocator &allocator) { for (auto &decl : recordDecles) { clang::RecordDecl *recDecl = llvm::cast(decl->getCanonicalDecl()); @@ -1829,20 +1941,7 @@ bool ASTParser::RetrieveGlobalVars(MapleAllocator &allocator) { bool ASTParser::ProcessGlobalEnums(MapleAllocator &allocator) { for (auto gEnumDecl : globalEnumDecles) { TraverseDecl(gEnumDecl, [&](clang::Decl *child) { - CHECK_FATAL(child->getKind() == clang::Decl::EnumConstant, "Unsupported decl kind: %u", child->getKind()); - GenericAttrs attrs; - astFile->CollectAttrs(*clang::dyn_cast(child), attrs, kPublic); - const std::string &varName = clang::dyn_cast(child)->getNameAsString(); - MIRType *mirType = astFile->CvtType(clang::dyn_cast(child)->getType()); - ASTVar *astVar = - ASTDeclsBuilder::ASTVarBuilder(allocator, fileName, varName, std::vector{mirType}, attrs); - auto constExpr = ASTDeclsBuilder::ASTExprBuilder(allocator); - constExpr->SetVal( - static_cast(clang::dyn_cast(child)->getInitVal().getExtValue())); - constExpr->SetType(mirType->GetPrimType()); - astVar->SetInitExpr(constExpr); - astVar->SetGlobal(true); - astVars.emplace_back(astVar); + astVars.emplace_back(static_cast(ProcessDecl(allocator, *child))); }); } return true; diff --git a/src/mplfe/ast_input/src/ast_stmt.cpp b/src/mplfe/ast_input/src/ast_stmt.cpp index 692c834074f55dee77a0fa73376fb5f51035a73b..5db6119c8d7b1fadef5e1a2434b6cf5dbff45944 100644 --- a/src/mplfe/ast_input/src/ast_stmt.cpp +++ b/src/mplfe/ast_input/src/ast_stmt.cpp @@ -81,14 +81,17 @@ std::list ASTForStmt::Emit2FEStmtImpl() const { std::list feStmts = initStmt->Emit2FEStmt(); stmts.splice(stmts.cend(), feStmts); } + std::list bodyFEStmts = bodyStmt->Emit2FEStmt(); + bodyFEStmts.emplace_back(std::move(labelBodyEndStmt)); UniqueFEIRExpr condFEExpr; if (condExpr != nullptr) { condFEExpr = condExpr->Emit2FEExpr(stmts); + std::list condStmts; + condFEExpr = condExpr->Emit2FEExpr(condStmts); + bodyFEStmts.splice(bodyFEStmts.cend(), condStmts); } else { condFEExpr = std::make_unique(static_cast(1), PTY_i32); } - std::list bodyFEStmts = bodyStmt->Emit2FEStmt(); - bodyFEStmts.emplace_back(std::move(labelBodyEndStmt)); if (incExpr != nullptr) { std::list exprs; std::list incStmts; @@ -424,8 +427,9 @@ std::list ASTStmtExprStmt::Emit2FEStmtImpl() const { // ---------- ASTCStyleCastExprStmt ---------- std::list ASTCStyleCastExprStmt::Emit2FEStmtImpl() const { - CHECK_FATAL(false, "NYI"); + CHECK_FATAL(exprs.front() != nullptr, "child expr must not be nullptr!"); std::list stmts; + exprs.front()->Emit2FEExpr(stmts); return stmts; } diff --git a/src/mplfe/ast_input/src/ast_struct2fe_helper.cpp b/src/mplfe/ast_input/src/ast_struct2fe_helper.cpp index 45a812201afb2d880475255f8765d7ab83336909..5cf50446bf08bd83d25b7320735eff4a670a99da 100644 --- a/src/mplfe/ast_input/src/ast_struct2fe_helper.cpp +++ b/src/mplfe/ast_input/src/ast_struct2fe_helper.cpp @@ -143,46 +143,12 @@ bool ASTGlobalVar2FEHelper::ProcessDeclImpl(MapleAllocator &allocator) { return false; } mirSymbol->SetAttrs(astVar.GetGenericAttrs().ConvertToTypeAttrs()); - PrimType primType = type->GetPrimType(); - if (primType != PTY_ref && primType != PTY_agg && primType != PTY_ptr) { - MIRConst *cst = nullptr; - std::list stmts; - ASTExpr *initExpr = astVar.GetInitExpr(); - if (initExpr == nullptr) { - return true; - } - UniqueFEIRExpr expr; - if (initExpr->GetASTOp() == kASTOpCast) { - ASTExpr *astExpr = static_cast(initExpr)->GetASTExpr(); - expr = astExpr->Emit2FEExpr(stmts); - } else { - expr = initExpr->Emit2FEExpr(stmts); - } - FEIRExprConst *constExpr = static_cast(expr.get()); - switch (primType) { - case PTY_u1: - case PTY_i8: - case PTY_u8: - case PTY_i16: - case PTY_u16: - case PTY_i32: - case PTY_u32: - case PTY_i64: - case PTY_u64: - cst = allocator.GetMemPool()->New(static_cast(constExpr->GetValue().u64), *type); - break; - case PTY_f32: - cst = allocator.GetMemPool()->New(constExpr->GetValue().f32, *type); - break; - case PTY_f64: - cst = allocator.GetMemPool()->New(constExpr->GetValue().f64, *type); - break; - default: - CHECK_FATAL(false, "unsupported type."); - break; - } - mirSymbol->SetKonst(cst); + ASTExpr *initExpr = astVar.GetInitExpr(); + if (initExpr == nullptr) { + return true; } + MIRConst *cst = initExpr->GenerateMIRConst(); + mirSymbol->SetKonst(cst); return true; } @@ -241,8 +207,9 @@ const std::string &ASTFunc2FEHelper::GetSrcFileName() const { void ASTFunc2FEHelper::SolveReturnAndArgTypesImpl(MapleAllocator &allocator) { const std::vector &returnAndArgTypeNames = func.GetTypeDesc(); - retMIRType = returnAndArgTypeNames[0]; - argMIRTypes.insert(argMIRTypes.begin(), returnAndArgTypeNames.begin() + 1, returnAndArgTypeNames.end()); + retMIRType = returnAndArgTypeNames[1]; + // skip funcType and returnType + argMIRTypes.insert(argMIRTypes.begin(), returnAndArgTypeNames.begin() + 2, returnAndArgTypeNames.end()); } std::string ASTFunc2FEHelper::GetMethodNameImpl(bool inMpl, bool full) const { diff --git a/src/mplfe/common/include/feir_builder.h b/src/mplfe/common/include/feir_builder.h index e6d826b1b1b3b0d8330cb79bb20b24521968db50..9e9c598542e641a9895e80f6d08fc42fdd0a2c69 100644 --- a/src/mplfe/common/include/feir_builder.h +++ b/src/mplfe/common/include/feir_builder.h @@ -43,11 +43,12 @@ class FEIRBuilder { bool withType = false); // Expr static UniqueFEIRExpr CreateExprDRead(UniqueFEIRVar srcVar); + static UniqueFEIRExpr CreateExprDReadAggField(UniqueFEIRVar srcVar, FieldID fieldID, MIRType *fieldType); 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); + UniqueFEIRExpr expr, FieldID id = 0); static UniqueFEIRExpr CreateExprTernary(Opcode op, UniqueFEIRType type, UniqueFEIRExpr cExpr, UniqueFEIRExpr tExpr, UniqueFEIRExpr fExpr); static UniqueFEIRExpr CreateExprConstRefNull(); @@ -65,6 +66,8 @@ class FEIRBuilder { static UniqueFEIRExpr CreateExprMathBinary(Opcode op, UniqueFEIRVar var0, UniqueFEIRVar var1); static UniqueFEIRExpr CreateExprMathBinary(Opcode op, UniqueFEIRExpr expr0, UniqueFEIRExpr expr1); static UniqueFEIRExpr CreateExprBinary(Opcode op, UniqueFEIRExpr expr0, UniqueFEIRExpr expr1); + static UniqueFEIRExpr CreateExprBinary(UniqueFEIRType exprType, Opcode op, + UniqueFEIRExpr expr0, UniqueFEIRExpr expr1); static UniqueFEIRExpr CreateExprSExt(UniqueFEIRVar srcVar); static UniqueFEIRExpr CreateExprSExt(UniqueFEIRExpr srcExpr, PrimType dstType); static UniqueFEIRExpr CreateExprZExt(UniqueFEIRVar srcVar); @@ -90,8 +93,7 @@ class FEIRBuilder { UniqueFEIRType argStructTypeNative); // Stmt static UniqueFEIRStmt CreateStmtDAssign(UniqueFEIRVar dstVar, UniqueFEIRExpr srcExpr, bool hasException = false); - static UniqueFEIRStmt CreateStmtDAssign(UniqueFEIRVar dstVar, UniqueFEIRExpr srcExpr, FieldID fieldID, - bool hasException = false); + static UniqueFEIRStmt CreateStmtDAssignAggField(UniqueFEIRVar dstVar, UniqueFEIRExpr srcExpr, FieldID fieldID); static UniqueFEIRStmt CreateStmtGoto(uint32 targetLabelIdx); static UniqueFEIRStmt CreateStmtGoto(const std::string &labelName); static UniqueFEIRStmt CreateStmtCondGoto(uint32 targetLabelIdx, Opcode op, UniqueFEIRExpr expr); diff --git a/src/mplfe/common/include/feir_stmt.h b/src/mplfe/common/include/feir_stmt.h index 6e25f9a2361e6fc166ab60faa24d606f393b10ad..90a56173925b121972ca828ebff751f8212ef01c 100644 --- a/src/mplfe/common/include/feir_stmt.h +++ b/src/mplfe/common/include/feir_stmt.h @@ -1154,7 +1154,7 @@ class FEIRStmtDAssign : public FEIRStmtAssign { void InitTrans4AllVarsImpl() override; std::list GenMIRStmtsImpl(MIRBuilder &mirBuilder) const override; std::unique_ptr expr; - int32 fieldID; + FieldID fieldID; std::string fieldName; }; diff --git a/src/mplfe/common/src/feir_builder.cpp b/src/mplfe/common/src/feir_builder.cpp index 411c00288e12939deaf73246f5ff39f121d494a7..5dc4c416e25659cffc3c7583cbedc32b006a808d 100644 --- a/src/mplfe/common/src/feir_builder.cpp +++ b/src/mplfe/common/src/feir_builder.cpp @@ -96,8 +96,17 @@ UniqueFEIRExpr FEIRBuilder::CreateExprDRead(UniqueFEIRVar srcVar) { return expr; } +UniqueFEIRExpr FEIRBuilder::CreateExprDReadAggField(UniqueFEIRVar srcVar, FieldID fieldID, MIRType *fieldType) { + CHECK_FATAL(srcVar != nullptr && srcVar->GetType()->GetPrimType() == PTY_agg, + "var type must be struct type, %u", srcVar->GetType()->GetPrimType()); + std::unique_ptr expr = std::make_unique(std::move(srcVar)); + expr->SetFieldID(fieldID); + expr->SetFieldType(fieldType); + return expr; +} + UniqueFEIRExpr FEIRBuilder::CreateExprIRead(UniqueFEIRType returnType, UniqueFEIRType ptrType, - FieldID id, UniqueFEIRExpr expr) { + UniqueFEIRExpr expr, FieldID id /* optional parameters */) { UniqueFEIRExpr feirExpr = std::make_unique(std::move(returnType), std::move(ptrType), id, std::move(expr)); return feirExpr; @@ -208,6 +217,11 @@ UniqueFEIRExpr FEIRBuilder::CreateExprMathBinary(Opcode op, UniqueFEIRExpr expr0 return std::make_unique(op, std::move(expr0), std::move(expr1)); } +UniqueFEIRExpr FEIRBuilder::CreateExprBinary(UniqueFEIRType exprType, Opcode op, + UniqueFEIRExpr expr0, UniqueFEIRExpr expr1) { + return std::make_unique(std::move(exprType), op, std::move(expr0), std::move(expr1)); +} + UniqueFEIRExpr FEIRBuilder::CreateExprBinary(Opcode op, UniqueFEIRExpr expr0, UniqueFEIRExpr expr1) { return std::make_unique(op, std::move(expr0), std::move(expr1)); } @@ -317,17 +331,13 @@ UniqueFEIRExpr FEIRBuilder::CreateExprArrayStoreForC(UniqueFEIRExpr argExprArray } UniqueFEIRStmt FEIRBuilder::CreateStmtDAssign(UniqueFEIRVar dstVar, UniqueFEIRExpr srcExpr, bool hasException) { - UniqueFEIRStmt stmt = std::make_unique(std::move(dstVar), std::move(srcExpr)); - FEIRStmtDAssign *ptrStmt = static_cast(stmt.get()); - ptrStmt->SetHasException(hasException); + std::unique_ptr stmt = std::make_unique(std::move(dstVar), std::move(srcExpr)); + stmt->SetHasException(hasException); return stmt; } -UniqueFEIRStmt FEIRBuilder::CreateStmtDAssign(UniqueFEIRVar dstVar, UniqueFEIRExpr srcExpr, FieldID fieldID, - bool hasException) { +UniqueFEIRStmt FEIRBuilder::CreateStmtDAssignAggField(UniqueFEIRVar dstVar, UniqueFEIRExpr srcExpr, FieldID fieldID) { UniqueFEIRStmt stmt = std::make_unique(std::move(dstVar), std::move(srcExpr), fieldID); - auto *ptrStmt = static_cast(stmt.get()); - ptrStmt->SetHasException(hasException); return stmt; } diff --git a/src/mplfe/common/src/feir_stmt.cpp b/src/mplfe/common/src/feir_stmt.cpp index f989f84cfd6f7f633c3c1b137bb1adf72f8bfe58..84b18e70b0aa98cb8879ebb3309fc5a44a294c6e 100644 --- a/src/mplfe/common/src/feir_stmt.cpp +++ b/src/mplfe/common/src/feir_stmt.cpp @@ -2118,16 +2118,20 @@ BaseNode *FEIRExprDRead::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { MIRSymbol *symbol = varSrc->GenerateMIRSymbol(mirBuilder); ASSERT(type != nullptr, "type is nullptr"); AddrofNode *node = mirBuilder.CreateExprDread(*type, *symbol); + FieldID fieldID = this->fieldID; if ((type->GetKind() == MIRTypeKind::kTypeStruct || type->GetKind() == MIRTypeKind::kTypeUnion) && (!fieldName.empty() || (fieldID != 0))) { - FieldID fieldID = this->fieldID; + MIRType *tmpFieldType = nullptr; if (fieldID == 0) { fieldID = FEUtils::GetStructFieldID(mirBuilder, static_cast(type), fieldName); + FieldID tmpID = fieldID; + FieldPair fieldPair = static_cast(type)->TraverseToFieldRef(tmpID); + tmpFieldType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fieldPair.second.first); + } else { + CHECK_NULL_FATAL(fieldType); + tmpFieldType = fieldType; } - FieldID tmpID = fieldID; - FieldPair fieldPair = static_cast(type)->TraverseToFieldRef(tmpID); - MIRType *fieldType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fieldPair.second.first); - node = mirBuilder.CreateExprDread(*fieldType, fieldID, *symbol); + node = mirBuilder.CreateExprDread(*tmpFieldType, fieldID, *symbol); } return node; } @@ -2539,7 +2543,9 @@ FEIRExprBinary::FEIRExprBinary(std::unique_ptr exprType, Opcode argOp, op(argOp) { SetOpnd0(std::move(argOpnd0)); SetOpnd1(std::move(argOpnd1)); - SetExprTypeByOp(); + if (FEManager::GetManager().GetModule().GetSrcLang() != kSrcLangC) { + SetExprTypeByOp(); + } } std::unique_ptr FEIRExprBinary::CloneImpl() const { @@ -3176,9 +3182,9 @@ BaseNode *FEIRExprArrayStoreForC::GenMIRNodeImpl(MIRBuilder &mirBuilder) const { MIRStructType* mirStructType = static_cast(ptrMIRStructType); FEManager::GetMIRBuilder().TraverseToNamedField(*mirStructType, fieldNameIdx, fieldID); } - BaseNode *nodeAddrof; + BaseNode *nodeAddrof = nullptr; if (exprArray->GetKind() == kExprDRead) { - MIRSymbol *mirSymbol = exprArray->GetVarUses().front()->GenerateLocalMIRSymbol(mirBuilder); + MIRSymbol *mirSymbol = exprArray->GetVarUses().front()->GenerateMIRSymbol(mirBuilder); nodeAddrof = mirBuilder.CreateExprAddrof(fieldID, *mirSymbol); } else { nodeAddrof = exprArray->GenMIRNode(mirBuilder);