From 3df7a922f540d9300c00dfab4f01ea3d5c00dcc4 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 001/124] Changes from mplcglmbc8 and mplcglmbc9. --- src/mapleall/maple_be/include/be/lower.h | 2 +- .../include/cg/aarch64/aarch64_cgfunc.h | 30 +- .../include/cg/aarch64/aarch64_phases.def | 2 +- src/mapleall/maple_be/include/cg/call_conv.h | 20 +- src/mapleall/maple_be/include/cg/cg.h | 19 +- src/mapleall/maple_be/include/cg/cgfunc.h | 2 + src/mapleall/maple_be/src/be/lower.cpp | 82 ++- .../maple_be/src/cg/aarch64/aarch64_args.cpp | 4 +- .../src/cg/aarch64/aarch64_call_conv.cpp | 2 +- .../src/cg/aarch64/aarch64_cgfunc.cpp | 547 +++++++++++++++--- .../maple_be/src/cg/aarch64/aarch64_ebo.cpp | 4 +- .../src/cg/aarch64/aarch64_memlayout.cpp | 32 +- .../src/cg/aarch64/aarch64_offset_adjust.cpp | 2 +- .../src/cg/aarch64/aarch64_proepilog.cpp | 87 ++- .../src/cg/aarch64/aarch64_reaching.cpp | 3 +- .../maple_be/src/cg/cg_phasemanager.cpp | 1 + src/mapleall/maple_be/src/cg/cgfunc.cpp | 44 +- src/mapleall/maple_be/src/cg/emit.cpp | 5 + src/mapleall/maple_be/src/cg/memlayout.cpp | 6 +- .../maple_ir/include/bin_mpl_export.h | 28 +- .../maple_ir/include/bin_mpl_import.h | 12 +- .../maple_ir/include/ir_safe_cast_traits.def | 4 +- src/mapleall/maple_ir/include/keywords.def | 1 - src/mapleall/maple_ir/include/mir_builder.h | 2 + src/mapleall/maple_ir/include/mir_function.h | 18 +- src/mapleall/maple_ir/include/mir_lower.h | 1 + src/mapleall/maple_ir/include/mir_nodes.h | 2 +- src/mapleall/maple_ir/include/mir_parser.h | 2 +- src/mapleall/maple_ir/include/mir_symbol.h | 6 +- src/mapleall/maple_ir/include/mir_type.h | 27 +- src/mapleall/maple_ir/include/opcode_info.h | 1 + src/mapleall/maple_ir/include/opcodes.def | 1 + src/mapleall/maple_ir/include/opcodes.h | 4 +- src/mapleall/maple_ir/src/bin_func_export.cpp | 238 ++++---- src/mapleall/maple_ir/src/bin_func_import.cpp | 244 ++++---- src/mapleall/maple_ir/src/bin_mpl_export.cpp | 112 ++-- src/mapleall/maple_ir/src/bin_mpl_import.cpp | 48 +- src/mapleall/maple_ir/src/global_tables.cpp | 4 +- src/mapleall/maple_ir/src/mir_builder.cpp | 24 + src/mapleall/maple_ir/src/mir_function.cpp | 4 +- src/mapleall/maple_ir/src/mir_lower.cpp | 107 ++++ src/mapleall/maple_ir/src/mir_nodes.cpp | 4 +- src/mapleall/maple_ir/src/mir_parser.cpp | 31 +- src/mapleall/maple_ir/src/mir_type.cpp | 8 +- src/mapleall/maple_ir/src/parser.cpp | 18 +- src/mapleall/maple_me/include/lmbc_lower.h | 3 - .../maple_me/include/lmbc_memlayout.h | 59 +- src/mapleall/maple_me/src/alias_class.cpp | 8 +- src/mapleall/maple_me/src/code_factoring.cpp | 4 +- .../src/demand_driven_alias_analysis.cpp | 4 +- src/mapleall/maple_me/src/irmap_build.cpp | 7 +- src/mapleall/maple_me/src/irmap_emit.cpp | 5 +- src/mapleall/maple_me/src/lfo_dep_test.cpp | 2 + src/mapleall/maple_me/src/lmbc_lower.cpp | 258 ++------- src/mapleall/maple_me/src/lmbc_memlayout.cpp | 439 +------------- src/mapleall/maple_me/src/me_cfg.cpp | 2 + src/mapleall/maple_me/src/me_function.cpp | 4 +- .../maple_me/src/me_lower_globals.cpp | 13 +- .../maple_me/src/me_phase_manager.cpp | 7 +- src/mapleall/maple_me/src/me_rc_lowering.cpp | 1 + src/mapleall/maple_me/src/me_rename2preg.cpp | 1 + src/mapleall/maple_me/src/me_side_effect.cpp | 4 +- src/mapleall/maple_me/src/me_stmt_pre.cpp | 4 +- src/mapleall/maple_me/src/pme_emit.cpp | 9 +- src/mapleall/maple_me/src/ssa_devirtual.cpp | 4 +- src/mapleall/maple_me/src/ssa_pre.cpp | 2 + src/mapleall/mpl2mpl/src/constantfold.cpp | 6 +- 67 files changed, 1402 insertions(+), 1289 deletions(-) diff --git a/src/mapleall/maple_be/include/be/lower.h b/src/mapleall/maple_be/include/be/lower.h index 3a6157db2e..98c6e5d786 100644 --- a/src/mapleall/maple_be/include/be/lower.h +++ b/src/mapleall/maple_be/include/be/lower.h @@ -185,7 +185,7 @@ class CGLowerer { void LowerTryCatchBlocks(BlockNode &body); #if TARGARM32 || TARGAARCH64 || TARGRISCV64 - BlockNode *LowerReturnStruct(NaryStmtNode &retNode); + BlockNode *LowerReturnStructUsingFakeParm(NaryStmtNode &retNode); #endif virtual BlockNode *LowerReturn(NaryStmtNode &retNode); void LowerEntry(MIRFunction &func); 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 ab2c80a97a..4c3cf641a1 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -38,6 +38,7 @@ class LmbcArgInfo { MapleVector lmbcCallArgTypes; MapleVector lmbcCallArgOffsets; MapleVector lmbcCallArgNumOfRegs; // # of regs needed to complete struct + uint32 lmbcTotalStkUsed = -1; // TBD: remove when explicit addr for large agg is available }; class AArch64CGFunc : public CGFunc { @@ -101,7 +102,7 @@ class AArch64CGFunc : public CGFunc { return kRFLAG; } - MIRType *GetAggTyFromCallSite(StmtNode *stmt); + MIRType *LmbcGetAggTyFromCallSite(StmtNode *stmt, std::vector **parmList); RegOperand &GetOrCreateResOperand(const BaseNode &parent, PrimType primType); void IntrinsifyGetAndAddInt(ListOperand &srcOpnds, PrimType pty); @@ -125,9 +126,11 @@ class AArch64CGFunc : public CGFunc { bool needLow12 = false); MemOperand *FixLargeMemOpnd(MemOperand &memOpnd, uint32 align); MemOperand *FixLargeMemOpnd(MOperator mOp, MemOperand &memOpnd, uint32 dSize, uint32 opndIdx); + uint32 LmbcFindTotalStkUsed(std::vector* paramList); + uint32 LmbcTotalRegsUsed(); void LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn); bool LmbcSmallAggForRet(BlkassignoffNode &bNode, Operand *src); - bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; void SelectIassignoff(IassignoffNode &stmt) override; @@ -135,6 +138,7 @@ class AArch64CGFunc : public CGFunc { void SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd) override; void SelectBlkassignoff(BlkassignoffNode &bNode, Operand *src) override; void SelectAggIassign(IassignNode &stmt, Operand &lhsAddrOpnd) override; + void SelectReturnSendOfStructInRegs(BaseNode *x) override; void SelectReturn(Operand *opnd0) override; void SelectIgoto(Operand *opnd0) override; void SelectCondGoto(CondGotoNode &stmt, Operand &opnd0, Operand &opnd1) override; @@ -485,7 +489,10 @@ class AArch64CGFunc : public CGFunc { void GenerateCleanupCodeForExtEpilog(BB &bb) override; uint32 FloatParamRegRequired(MIRStructType *structType, uint32 &fpSize) override; void AssignLmbcFormalParams() override; - RegOperand *GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType); + void LmbcGenSaveSpForAlloca() override; + MemOperand *GenLmbcFpMemOperand(int32 offset, uint32 byteSize, AArch64reg base = RFP); + RegOperand *GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType, AArch64reg baseRegno = RFP); + RegOperand *LmbcStructReturnLoad(int32 offset); Operand *GetBaseReg(const AArch64SymbolAlloc &symAlloc); int32 GetBaseOffset(const SymbolAlloc &symAlloc) override; @@ -725,6 +732,22 @@ class AArch64CGFunc : public CGFunc { return lmbcArgInfo->lmbcCallArgNumOfRegs; } + int32 GetLmbcTotalStkUsed() { + return lmbcArgInfo->lmbcTotalStkUsed; + } + + void SetLmbcTotalStkUsed(int32 offset) { + lmbcArgInfo->lmbcTotalStkUsed = offset; + } + + void SetLmbcCallReturnType(MIRType *ty) { + lmbcCallReturnType = ty; + } + + MIRType *GetLmbcCallReturnType() { + return lmbcCallReturnType; + } + private: enum RelationOperator : uint8 { kAND, @@ -792,6 +815,7 @@ class AArch64CGFunc : public CGFunc { regno_t methodHandleVreg = -1; uint32 alignPow = 5; /* function align pow defaults to 5 i.e. 2^5*/ LmbcArgInfo *lmbcArgInfo = nullptr; + MIRType *lmbcCallReturnType = nullptr; void SelectLoadAcquire(Operand &dest, PrimType dtype, Operand &src, PrimType stype, AArch64isa::MemoryOrdering memOrd, bool isDirect); diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def b/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def index a3a74d7b2f..ff08e81852 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def @@ -16,8 +16,8 @@ ADDTARGETPHASE("createstartendlabel", true); ADDTARGETPHASE("buildehfunc", true); ADDTARGETPHASE("handlefunction", true); + ADDTARGETPHASE("moveargs", true); if (GetMIRModule()->GetFlavor() != MIRFlavor::kFlavorLmbc) { - ADDTARGETPHASE("moveargs", true); /* SSA PHASES */ ADDTARGETPHASE("cgssaconstruct", CGOptions::DoCGSSA()); ADDTARGETPHASE("cgcopyprop", CGOptions::DoCGSSA()); diff --git a/src/mapleall/maple_be/include/cg/call_conv.h b/src/mapleall/maple_be/include/cg/call_conv.h index d7a194022c..4310cd986a 100644 --- a/src/mapleall/maple_be/include/cg/call_conv.h +++ b/src/mapleall/maple_be/include/cg/call_conv.h @@ -63,8 +63,8 @@ struct CCLocInfo { class LmbcFormalParamInfo { public: LmbcFormalParamInfo(PrimType pType, uint32 ofst, uint32 sz) : - type(nullptr), primType(pType), offset(ofst), size(sz), regNO(0), vregNO(0), numRegs(0), - fpSize(0), isReturn(false), isPureFloat(false), isOnStack(false) {} + type(nullptr), primType(pType), offset(ofst), onStackOffset(0), size(sz), regNO(0), vregNO(0), numRegs(0), + fpSize(0), isReturn(false), isPureFloat(false), isOnStack(false), hasRegassign(false) {} ~LmbcFormalParamInfo() = default; @@ -86,6 +86,12 @@ class LmbcFormalParamInfo { void SetOffset(uint32 ofs) { offset = ofs; } + uint32 GetOnStackOffset() { + return onStackOffset; + } + void SetOnStackOffset(uint32 ofs) { + onStackOffset = ofs; + } uint32 GetSize() { return size; } @@ -137,10 +143,17 @@ class LmbcFormalParamInfo { void SetIsOnStack() { isOnStack = true; } + bool HasRegassign() { + return hasRegassign; + } + void SetHasRegassign() { + hasRegassign = true; + } private: MIRStructType *type; PrimType primType; uint32 offset; + uint32 onStackOffset; /* stack location if isOnStack */ uint32 size; /* size primtype or struct */ regno_t regNO = 0; /* param reg num or starting reg num if numRegs > 0 */ regno_t vregNO = 0; /* if no explicit regassing from IR, create move from param reg */ @@ -148,7 +161,8 @@ class LmbcFormalParamInfo { uint32 fpSize = 0; /* size of fp param if isPureFloat */ bool isReturn; bool isPureFloat = false; - bool isOnStack; /* small struct with arrays need to be saved onto stack */ + bool isOnStack; /* large struct is passed by a copy on stack */ + bool hasRegassign; }; } /* namespace maplebe */ diff --git a/src/mapleall/maple_be/include/cg/cg.h b/src/mapleall/maple_be/include/cg/cg.h index 093289e42b..e1368acb1d 100644 --- a/src/mapleall/maple_be/include/cg/cg.h +++ b/src/mapleall/maple_be/include/cg/cg.h @@ -121,11 +121,13 @@ class CG { emitter(nullptr), labelOrderCnt(0), cgOption(cgOptions), - instrumentationFunction(nullptr) { + instrumentationFunction(nullptr), + fileGP(nullptr) { const std::string &internalNameLiteral = namemangler::GetInternalNameLiteral(namemangler::kJavaLangObjectStr); GStrIdx strIdxFromName = GlobalTables::GetStrTable().GetStrIdxFromName(internalNameLiteral); isLibcore = (GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdxFromName) != nullptr); DefineDebugTraceFunctions(); + isLmbc = (mirModule->GetFlavor() == MIRFlavor::kFlavorLmbc); } virtual ~CG(); @@ -361,6 +363,10 @@ class CG { return isLibcore; } + bool IsLmbc() const { + return isLmbc; + } + MIRSymbol *GetDebugTraceEnterFunction() { return dbgTraceEnter; } @@ -421,6 +427,13 @@ class CG { /* Object map generation helper */ std::vector GetReferenceOffsets64(const BECommon &beCommon, MIRStructType &structType); + void SetGP(MIRSymbol *sym) { + fileGP = sym; + } + MIRSymbol *GetGP() const { + return fileGP; + } + static bool IsInFuncWrapLabels(MIRFunction *func) { return funcWrapLabels.find(func) != funcWrapLabels.end(); } @@ -449,12 +462,14 @@ class CG { LabelIDOrder labelOrderCnt; static CGFunc *currentCGFunction; /* current cg function being compiled */ CGOptions cgOption; - bool isLibcore; MIRSymbol *instrumentationFunction; MIRSymbol *dbgTraceEnter; MIRSymbol *dbgTraceExit; MIRSymbol *dbgFuncProfile; + MIRSymbol *fileGP; /* for lmbc, one local %GP per file */ static std::map> funcWrapLabels; + bool isLibcore; + bool isLmbc; }; /* class CG */ } /* namespace maplebe */ diff --git a/src/mapleall/maple_be/include/cg/cgfunc.h b/src/mapleall/maple_be/include/cg/cgfunc.h index 20a3f4c7c2..a57bd11299 100644 --- a/src/mapleall/maple_be/include/cg/cgfunc.h +++ b/src/mapleall/maple_be/include/cg/cgfunc.h @@ -160,6 +160,7 @@ class CGFunc { virtual uint32 FloatParamRegRequired(MIRStructType *structType, uint32 &fpSize) = 0; virtual void AssignLmbcFormalParams() = 0; LmbcFormalParamInfo *GetLmbcFormalParamInfo(uint32 offset); + virtual void LmbcGenSaveSpForAlloca() = 0; void GenerateLoc(StmtNode *stmt, unsigned &lastSrcLoc, unsigned &lastMplLoc); int32 GetFreqFromStmt(uint32 stmtId); void GenerateInstruction(); @@ -201,6 +202,7 @@ class CGFunc { virtual void SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd) = 0; virtual void SelectBlkassignoff(BlkassignoffNode &bNode, Operand *src) = 0; virtual void SelectAggIassign(IassignNode &stmt, Operand &lhsAddrOpnd) = 0; + virtual void SelectReturnSendOfStructInRegs(BaseNode *x) = 0; virtual void SelectReturn(Operand *opnd) = 0; virtual void SelectIgoto(Operand *opnd0) = 0; virtual void SelectCondGoto(CondGotoNode &stmt, Operand &opnd0, Operand &opnd1) = 0; diff --git a/src/mapleall/maple_be/src/be/lower.cpp b/src/mapleall/maple_be/src/be/lower.cpp index 43396318c0..40b5d68a5d 100644 --- a/src/mapleall/maple_be/src/be/lower.cpp +++ b/src/mapleall/maple_be/src/be/lower.cpp @@ -121,6 +121,7 @@ void CGLowerer::RegisterExternalLibraryFunctions() { func->AllocSymTab(); MIRSymbol *funcSym = func->GetFuncSymbol(); funcSym->SetStorageClass(kScExtern); + funcSym->SetAppearsInCode(true); /* return type */ MIRType *retTy = GlobalTables::GetTypeTable().GetPrimType(extFnDescrs[i].retType); @@ -876,7 +877,7 @@ void CGLowerer::LowerTypePtr(BaseNode &node) const { #if TARGARM32 || TARGAARCH64 || TARGRISCV64 -BlockNode *CGLowerer::LowerReturnStruct(NaryStmtNode &retNode) { +BlockNode *CGLowerer::LowerReturnStructUsingFakeParm(NaryStmtNode &retNode) { BlockNode *blk = mirModule.CurFuncCodeMemPool()->New(); for (size_t i = 0; i < retNode.GetNopndSize(); ++i) { retNode.SetOpnd(LowerExpr(retNode, *retNode.GetNopndAt(i), *blk), i); @@ -1100,7 +1101,7 @@ void CGLowerer::LowerCallStmt(StmtNode &stmt, StmtNode *&nextStmt, BlockNode &ne return; } - if ((newStmt->GetOpCode() == OP_call) || (newStmt->GetOpCode() == OP_icall)) { + if (newStmt->GetOpCode() == OP_call || newStmt->GetOpCode() == OP_icall || newStmt->GetOpCode() == OP_icallproto) { newStmt = LowerCall(static_cast(*newStmt), nextStmt, newBlk, retty, uselvar); } newStmt->SetSrcPos(stmt.GetSrcPos()); @@ -1171,7 +1172,12 @@ StmtNode *CGLowerer::GenIntrinsiccallNode(const StmtNode &stmt, PUIdx &funcCalle StmtNode *CGLowerer::GenIcallNode(PUIdx &funcCalled, IcallNode &origCall) { StmtNode *newCall = nullptr; - newCall = mirModule.GetMIRBuilder()->CreateStmtIcall(origCall.GetNopnd()); + if (origCall.GetOpCode() == OP_icallassigned) { + newCall = mirModule.GetMIRBuilder()->CreateStmtIcall(origCall.GetNopnd()); + } else { + newCall = mirModule.GetMIRBuilder()->CreateStmtIcallproto(origCall.GetNopnd()); + static_cast(newCall)->SetRetTyIdx(static_cast(origCall).GetRetTyIdx()); + } newCall->SetSrcPos(origCall.GetSrcPos()); CHECK_FATAL(newCall != nullptr, "nullptr is not expected"); funcCalled = kFuncNotFound; @@ -1372,6 +1378,7 @@ BlockNode *CGLowerer::LowerCallAssignedStmt(StmtNode &stmt, bool uselvar) { static_cast(newCall)->SetReturnVec(*p2nRets); break; } + case OP_icallprotoassigned: case OP_icallassigned: { auto &origCall = static_cast(stmt); newCall = GenIcallNode(funcCalled, origCall); @@ -1479,6 +1486,15 @@ bool CGLowerer::LowerStructReturn(BlockNode &newBlk, StmtNode *stmt, (*p2nrets)[0].first = dnodeStmt->GetStIdx(); (*p2nrets)[0].second.SetFieldID(dnodeStmt->GetFieldID()); lvar = true; + // set ATTR_firstarg_return for callee + if (stmt->GetOpCode() == OP_callassigned) { + CallNode *callNode = static_cast(stmt); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callNode->GetPUIdx()); + f->SetFirstArgReturn(); + f->GetMIRFuncType()->SetFirstArgReturn(); + } else { + // for icall, front-end already set ATTR_firstarg_return + } } else { /* struct <= 16 passed in regs lowered into call &foo regassign u64 %1 (regread u64 %%retval0) @@ -1496,13 +1512,19 @@ bool CGLowerer::LowerStructReturn(BlockNode &newBlk, StmtNode *stmt, CallNode *callStmt = mirModule.GetMIRBuilder()->CreateStmtCall(callNode->GetPUIdx(), callNode->GetNopnd()); callStmt->SetSrcPos(callNode->GetSrcPos()); newBlk.AddStatement(callStmt); - } else if (stmt->GetOpCode() == OP_icallassigned) { + } else if (stmt->GetOpCode() == OP_icallassigned || stmt->GetOpCode() == OP_icallprotoassigned) { auto *icallNode = static_cast(stmt); for (size_t i = 0; i < icallNode->GetNopndSize(); ++i) { BaseNode *newOpnd = LowerExpr(*icallNode, *icallNode->GetNopndAt(i), newBlk); icallNode->SetOpnd(newOpnd, i); } - IcallNode *icallStmt = mirModule.GetMIRBuilder()->CreateStmtIcall(icallNode->GetNopnd()); + IcallNode *icallStmt = nullptr; + if (stmt->GetOpCode() == OP_icallassigned) { + icallStmt = mirModule.GetMIRBuilder()->CreateStmtIcall(icallNode->GetNopnd()); + } else { + icallStmt = mirModule.GetMIRBuilder()->CreateStmtIcallproto(icallNode->GetNopnd()); + icallStmt->SetRetTyIdx(icallNode->GetRetTyIdx()); + } icallStmt->SetSrcPos(icallNode->GetSrcPos()); newBlk.AddStatement(icallStmt); } else { @@ -1767,6 +1789,7 @@ void CGLowerer::LowerAssertBoundary(StmtNode &stmt, BlockNode &block, BlockNode CondGotoNode *brFalseNode = mirBuilder->CreateStmtCondGoto(cond, OP_brfalse, labIdx); MIRFunction *printf = mirBuilder->GetOrCreateFunction("printf", TyIdx(PTY_i32)); + printf->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*printf->GetMIRFuncType()); MapleVector argsPrintf(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); uint32 oldTypeTableSize = GlobalTables::GetTypeTable().GetTypeTableSize(); @@ -1842,7 +1865,8 @@ BlockNode *CGLowerer::LowerBlock(BlockNode &block) { break; } case OP_callassigned: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallprotoassigned: { // pass the addr of lvar if this is a struct call assignment bool lvar = false; // nextStmt could be changed by the call to LowerStructReturn @@ -1862,6 +1886,7 @@ BlockNode *CGLowerer::LowerBlock(BlockNode &block) { case OP_intrinsiccall: case OP_call: case OP_icall: + case OP_icallproto: #if TARGARM32 || TARGAARCH64 || TARGRISCV64 || TARGX86_64 // nextStmt could be changed by the call to LowerStructReturn LowerCallStmt(*stmt, nextStmt, *newBlk); @@ -1871,8 +1896,8 @@ BlockNode *CGLowerer::LowerBlock(BlockNode &block) { break; case OP_return: { #if TARGARM32 || TARGAARCH64 || TARGRISCV64 - if (GetCurrentFunc()->IsReturnStruct()) { - newBlk->AppendStatementsFromBlock(*LowerReturnStruct(static_cast(*stmt))); + if (GetCurrentFunc()->IsFirstArgReturn() && stmt->NumOpnds() > 0) { + newBlk->AppendStatementsFromBlock(*LowerReturnStructUsingFakeParm(static_cast(*stmt))); } else { #endif NaryStmtNode *retNode = static_cast(stmt); @@ -1970,7 +1995,9 @@ void CGLowerer::SimplifyBlock(BlockNode &block) { } auto *newFunc = theMIRModule->GetMIRBuilder()->GetOrCreateFunction(asmMap.at(oldFunc->GetName()), callStmt->GetTyIdx()); - newFunc->GetFuncSymbol()->SetStorageClass(kScExtern); + MIRSymbol *funcSym = newFunc->GetFuncSymbol(); + funcSym->SetStorageClass(kScExtern); + funcSym->SetAppearsInCode(true); callStmt->SetPUIdx(newFunc->GetPuidx()); break; } @@ -2080,6 +2107,7 @@ StmtNode *CGLowerer::LowerCall( if (needCheckStore) { MIRFunction *fn = mirModule.GetMIRBuilder()->GetOrCreateFunction("MCC_Reflect_Check_Arraystore", TyIdx(PTY_void)); + fn->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); MapleVector args(mirModule.GetMIRBuilder()->GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -2106,7 +2134,7 @@ StmtNode *CGLowerer::LowerCall( } MIRType *retType = nullptr; - if (callNode.op == OP_icall) { + if (callNode.op == OP_icall || callNode.op == OP_icallproto) { if (retTy == nullptr) { return &callNode; } else { @@ -2152,7 +2180,7 @@ StmtNode *CGLowerer::LowerCall( addrofNode->SetStIdx(dsgnSt->GetStIdx()); addrofNode->SetFieldID(0); - if (callNode.op == OP_icall) { + if (callNode.op == OP_icall || callNode.op == OP_icallproto) { auto ond = callNode.GetNopnd().begin(); newNopnd.emplace_back(*ond); newNopnd.emplace_back(addrofNode); @@ -2174,7 +2202,27 @@ StmtNode *CGLowerer::LowerCall( } void CGLowerer::LowerEntry(MIRFunction &func) { + // determine if needed to insert fake parameter to return struct for current function if (func.IsReturnStruct()) { + MIRType *retType = func.GetReturnType(); +#if TARGAARCH64 + PrimType pty = IsStructElementSame(retType); + if (pty == PTY_f32 || pty == PTY_f64 || IsPrimitiveVector(pty)) { + func.SetStructReturnedInRegs(); + return; + } +#endif + if (retType->GetPrimType() != PTY_agg) { + return; + } + if (retType->GetSize() > k16ByteSize) { + func.SetFirstArgReturn(); + func.GetMIRFuncType()->SetFirstArgReturn(); + } else { + func.SetStructReturnedInRegs(); + } + } + if (func.IsFirstArgReturn() && func.GetReturnType()->GetPrimType() != PTY_void) { MIRSymbol *retSt = func.GetSymTab()->CreateSymbol(kScopeLocal); retSt->SetStorageClass(kScFormal); retSt->SetSKind(kStVar); @@ -2191,12 +2239,14 @@ void CGLowerer::LowerEntry(MIRFunction &func) { auto formal = func.GetFormal(i); formals.emplace_back(formal); } + func.SetFirstArgReturn(); beCommon.AddElementToFuncReturnType(func, func.GetReturnTyIdx()); func.UpdateFuncTypeAndFormalsAndReturnType(formals, TyIdx(PTY_void), true); auto *funcType = func.GetMIRFuncType(); ASSERT(funcType != nullptr, "null ptr check"); + funcType->SetFirstArgReturn(); beCommon.AddTypeSizeAndAlign(funcType->GetTypeIndex(), GetPrimTypeSize(funcType->GetPrimType())); } } @@ -2374,6 +2424,7 @@ MIRFunction *CGLowerer::RegisterFunctionVoidStarToVoid(BuiltinFunctionID id, con func->AllocSymTab(); MIRSymbol *funcSym = func->GetFuncSymbol(); funcSym->SetStorageClass(kScExtern); + funcSym->SetAppearsInCode(true); MIRType *argTy = GlobalTables::GetTypeTable().GetPtr(); MIRSymbol *argSt = func->GetSymTab()->CreateSymbol(kScopeLocal); argSt->SetNameStrIdx(mirBuilder->GetOrCreateStringIndex(paramName)); @@ -2415,6 +2466,7 @@ void CGLowerer::RegisterBuiltIns() { func->AllocSymTab(); MIRSymbol *funcSym = func->GetFuncSymbol(); funcSym->SetStorageClass(kScExtern); + funcSym->SetAppearsInCode(true); /* return type */ MIRType *retTy = desc.GetReturnType(); CHECK_FATAL(retTy != nullptr, "retTy should not be nullptr"); @@ -2570,6 +2622,7 @@ void CGLowerer::ProcessArrayExpr(BaseNode &expr, BlockNode &blkNode) { arrayNode.GetNopndAt(1), lenRegreadNode); CondGotoNode *brFalseNode = mirBuilder->CreateStmtCondGoto(cond, OP_brfalse, labIdx); MIRFunction *fn = mirBuilder->GetOrCreateFunction("MCC_Array_Boundary_Check", TyIdx(PTY_void)); + fn->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); MapleVector args(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -3101,6 +3154,7 @@ BaseNode *CGLowerer::LowerIntrinJavaArrayLength(const BaseNode &parent, Intrinsi MIRFunction *newFunc = mirBuilder->GetOrCreateFunction("MCC_ThrowNullArrayNullPointerException", GlobalTables::GetTypeTable().GetVoid()->GetTypeIndex()); + newFunc->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*newFunc->GetMIRFuncType()); newFunc->AllocSymTab(); MapleVector args(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -3472,6 +3526,7 @@ StmtNode *CGLowerer::LowerIntrinsicRCCall(const IntrinsiccallNode &intrincall) { if (intrinFuncIDs.find(intrinDesc) == intrinFuncIDs.end()) { /* add funcid into map */ MIRFunction *fn = mirBuilder->GetOrCreateFunction(intrinDesc->name, TyIdx(PTY_void)); + fn->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); intrinFuncIDs[intrinDesc] = fn->GetPuidx(); @@ -3500,6 +3555,7 @@ void CGLowerer::LowerArrayStore(const IntrinsiccallNode &intrincall, BlockNode & if (needCheckStore) { MIRFunction *fn = mirBuilder->GetOrCreateFunction("MCC_Reflect_Check_Arraystore", TyIdx(PTY_void)); + fn->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); MapleVector args(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -3589,6 +3645,7 @@ StmtNode *CGLowerer::LowerIntrinsiccall(IntrinsiccallNode &intrincall, BlockNode beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); st->SetFunction(fn); + st->SetAppearsInCode(true); return LowerDefaultIntrinsicCall(intrincall, *st, *fn); } @@ -3659,6 +3716,7 @@ PUIdx CGLowerer::GetBuiltinToUse(BuiltinFunctionID id) const { void CGLowerer::LowerGCMalloc(const BaseNode &node, const GCMallocNode &gcmalloc, BlockNode &blkNode, bool perm) { MIRFunction *func = mirBuilder->GetOrCreateFunction((perm ? "MCC_NewPermanentObject" : "MCC_NewObj_fixed_class"), (TyIdx)(LOWERED_PTR_TYPE)); + func->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*func->GetMIRFuncType()); func->AllocSymTab(); /* Get the classinfo */ @@ -3677,6 +3735,7 @@ void CGLowerer::LowerGCMalloc(const BaseNode &node, const GCMallocNode &gcmalloc if (classSym->GetAttr(ATTR_abstract) || classSym->GetAttr(ATTR_interface)) { MIRFunction *funcSecond = mirBuilder->GetOrCreateFunction("MCC_Reflect_ThrowInstantiationError", (TyIdx)(LOWERED_PTR_TYPE)); + funcSecond->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*funcSecond->GetMIRFuncType()); funcSecond->AllocSymTab(); BaseNode *arg = mirBuilder->CreateExprAddrof(0, *classSym); @@ -3795,6 +3854,7 @@ void CGLowerer::LowerJarrayMalloc(const StmtNode &stmt, const JarrayMallocNode & args.emplace_back(mirBuilder->CreateIntConst(0, PTY_u32)); } MIRFunction *func = mirBuilder->GetOrCreateFunction(funcName, (TyIdx)(LOWERED_PTR_TYPE)); + func->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*func->GetMIRFuncType()); func->AllocSymTab(); CallNode *callAssign = nullptr; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index e0acbe83e7..e3e84d131b 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -38,7 +38,7 @@ void AArch64MoveRegArgs::CollectRegisterArgs(std::map &argsL uint32 start = 0; if (numFormal) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsReturnStruct()) { + if (func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16ByteSize) { start = 1; @@ -436,7 +436,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsReturnStruct()) { + if (func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp index 0be11cdb40..d9fa548174 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp @@ -303,7 +303,7 @@ int32 AArch64CallConvImpl::LocateNextParm(MIRType &mirType, CCLocInfo &pLoc, boo if (isFirst) { MIRFunction *func = tFunc != nullptr ? tFunc : const_cast(beCommon.GetMIRModule().CurFunction()); - if (func->IsReturnStruct()) { + if (func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); size_t size = beCommon.GetTypeSize(tyIdx); if (size == 0) { 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 4fca21c6bb..6e93060f65 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -1410,15 +1410,44 @@ void AArch64CGFunc::SelectAsm(AsmNode &node) { } void AArch64CGFunc::SelectRegassign(RegassignNode &stmt, Operand &opnd0) { + if (GetCG()->IsLmbc()) { + PrimType lhsSize = stmt.GetPrimType(); + PrimType rhsSize = stmt.Opnd(0)->GetPrimType(); + if (lhsSize != rhsSize && stmt.Opnd(0)->GetOpCode() == OP_ireadoff) { + Insn *prev = GetCurBB()->GetLastInsn(); + if (prev->GetMachineOpcode() == MOP_wldrsb || prev->GetMachineOpcode() == MOP_wldrsh) { + opnd0.SetSize(GetPrimTypeBitSize(stmt.GetPrimType())); + prev->SetMOP(prev->GetMachineOpcode() == MOP_wldrsb ? MOP_xldrsb : MOP_xldrsh); + } else if (prev->GetMachineOpcode() == MOP_wldr && stmt.GetPrimType() == PTY_i64) { + opnd0.SetSize(GetPrimTypeBitSize(stmt.GetPrimType())); + prev->SetMOP(MOP_xldrsw); + } + } + } RegOperand *regOpnd = nullptr; PregIdx pregIdx = stmt.GetRegIdx(); if (IsSpecialPseudoRegister(pregIdx)) { - regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, stmt.GetPrimType()); + if (GetCG()->IsLmbc() && stmt.GetPrimType() == PTY_agg) { + if (static_cast(opnd0).IsOfIntClass()) { + regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, PTY_i64); + } else if (opnd0.GetSize() <= k4ByteSize) { + regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, PTY_f32); + } else { + regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, PTY_f64); + } + } else { + regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, stmt.GetPrimType()); + } } else { regOpnd = &GetOrCreateVirtualRegisterOperand(GetVirtualRegNOFromPseudoRegIdx(pregIdx)); } /* look at rhs */ PrimType rhsType = stmt.Opnd(0)->GetPrimType(); + if (GetCG()->IsLmbc() && rhsType == PTY_agg) { + /* This occurs when a call returns a small struct */ + /* The subtree should already taken care of the agg type that is in excess of 8 bytes */ + rhsType = PTY_i64; + } PrimType dtype = rhsType; if (GetPrimTypeBitSize(dtype) < k32BitSize) { ASSERT(IsPrimitiveInteger(dtype), ""); @@ -1440,6 +1469,12 @@ void AArch64CGFunc::SelectRegassign(RegassignNode &stmt, Operand &opnd0) { MIRPreg *preg = GetFunction().GetPregTab()->PregFromPregIdx(pregIdx); uint32 srcBitLength = GetPrimTypeSize(preg->GetPrimType()) * kBitsPerByte; GetCurBB()->AppendInsn(GetCG()->BuildInstruction(PickStInsn(srcBitLength, stype), *regOpnd, *dest)); + } else if (regOpnd->GetRegisterNumber() == R0 || regOpnd->GetRegisterNumber() == R1) { + Insn &pseudo = GetCG()->BuildInstruction(MOP_pseudo_ret_int, *regOpnd); + GetCurBB()->AppendInsn(pseudo); + } else if (regOpnd->GetRegisterNumber() >= V0 && regOpnd->GetRegisterNumber() <= V3) { + Insn &pseudo = GetCG()->BuildInstruction(MOP_pseudo_ret_float, *regOpnd); + GetCurBB()->AppendInsn(pseudo); } } @@ -1919,15 +1954,11 @@ void AArch64CGFunc::SelectIassignoff(IassignoffNode &stmt) { SelectCopy(memOpnd, destType, srcOpnd, destType); } -void AArch64CGFunc::SelectIassignfpoff(IassignFPoffNode &stmt, Operand &opnd) { - int32 offset = stmt.GetOffset(); - PrimType primType = stmt.GetPrimType(); - uint32 bitlen = GetPrimTypeSize(primType) * kBitsPerByte; - - Operand &srcOpnd = LoadIntoRegister(opnd, primType); +MemOperand *AArch64CGFunc::GenLmbcFpMemOperand(int32 offset, uint32 byteSize, AArch64reg baseRegno) { MemOperand *memOpnd; - RegOperand *rfp = &GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); - if (offset < 0) { + RegOperand *rfp = &GetOrCreatePhysicalRegisterOperand(baseRegno, k64BitSize, kRegTyInt); + uint32 bitlen = byteSize * kBitsPerByte; + if (offset < 0 && offset < -256) { RegOperand *baseOpnd = &CreateRegisterOperandOfType(PTY_a64); ImmOperand &immOpnd = CreateImmOperand(offset, k32BitSize, true); Insn &addInsn = GetCG()->BuildInstruction(MOP_xaddrri12, *baseOpnd, *rfp, immOpnd); @@ -1939,11 +1970,45 @@ void AArch64CGFunc::SelectIassignfpoff(IassignFPoffNode &stmt, Operand &opnd) { memOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, bitlen, rfp, nullptr, offsetOpnd, nullptr); } memOpnd->SetStackMem(true); - MOperator mOp = PickStInsn(bitlen, primType); - Insn &store = GetCG()->BuildInstruction(mOp, srcOpnd, *memOpnd); - GetCurBB()->AppendInsn(store); + return memOpnd; } +void AArch64CGFunc::SelectIassignfpoff(IassignFPoffNode &stmt, Operand &opnd) { + int32 offset = stmt.GetOffset(); + PrimType primType = stmt.GetPrimType(); + MIRType *rType = GetLmbcCallReturnType(); + bool isPureFpStruct = false; + uint32 numRegs = 0; + if (rType && rType->GetPrimType() == PTY_agg && opnd.IsRegister() && static_cast(opnd).IsPhysicalRegister()) { + CHECK_FATAL(rType->GetSize() <= 16, "SelectIassignfpoff invalid agg size"); + uint32 fpSize; + numRegs = FloatParamRegRequired(static_cast(rType), fpSize); + if (numRegs) { + primType = (fpSize == k4ByteSize) ? PTY_f32 : PTY_f64; + isPureFpStruct = true; + } + } + uint32 byteSize = GetPrimTypeSize(primType); + uint32 bitlen = byteSize * kBitsPerByte; + if (isPureFpStruct) { + for (int i = 0 ; i < numRegs; ++i) { + MemOperand *memOpnd = GenLmbcFpMemOperand(offset + (i * byteSize), byteSize); + RegOperand &srcOpnd = GetOrCreatePhysicalRegisterOperand(AArch64reg(V0 + i), bitlen, kRegTyFloat); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, srcOpnd, *memOpnd); + GetCurBB()->AppendInsn(store); + } + } else { + Operand &srcOpnd = LoadIntoRegister(opnd, primType); + MemOperand *memOpnd = GenLmbcFpMemOperand(offset, byteSize); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, srcOpnd, *memOpnd); + GetCurBB()->AppendInsn(store); + } +} + +/* Load and assign to a new register. To be moved to the correct call register OR stack + location in LmbcSelectParmList */ void AArch64CGFunc::SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd) { if (GetLmbcArgInfo() == nullptr) { LmbcArgInfo *p = memPool->New(*GetFuncScopeAllocator()); @@ -1970,7 +2035,7 @@ void AArch64CGFunc::SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd } /* Search for CALL/ICALL/ICALLPROTO node, must be called from a blkassignoff node */ -MIRType *AArch64CGFunc::GetAggTyFromCallSite(StmtNode *stmt) { +MIRType *AArch64CGFunc::LmbcGetAggTyFromCallSite(StmtNode *stmt, std::vector **parmList) { for ( ; stmt != nullptr; stmt = stmt->GetNext()) { if (stmt->GetOpCode() == OP_call || stmt->GetOpCode() == OP_icallproto) { break; @@ -1983,25 +2048,20 @@ MIRType *AArch64CGFunc::GetAggTyFromCallSite(StmtNode *stmt) { if (stmt->GetOpCode() == OP_call) { CallNode *callNode = static_cast(stmt); MIRFunction *fn = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callNode->GetPUIdx()); - if (fn->IsReturnStruct()) { - ++nargs; - } if (fn->GetFormalCount() > 0) { - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fn->GetNthParamTyIdx(nargs)); + ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fn->GetFormalDefVec()[nargs].formalTyIdx); } + *parmList = &fn->GetParamTypes(); // would return null if the actual parameter is bogus } else if (stmt->GetOpCode() == OP_icallproto) { IcallNode *icallproto = static_cast(stmt); MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallproto->GetRetTyIdx()); MIRFuncType *fType = static_cast(type); - MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fType->GetRetTyIdx()); - if (retType->GetKind() == kTypeStruct) { - ++nargs; - } ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fType->GetNthParamType(nargs)); + *parmList = &fType->GetParamTypeList(); } else { CHECK_FATAL(stmt->GetOpCode() == OP_icallproto, - "GetAggTyFromCallSite:: unexpected call operator"); + "LmbcGetAggTyFromCallSite:: unexpected call operator"); } return ty; } @@ -2078,11 +2138,11 @@ bool AArch64CGFunc::LmbcSmallAggForRet(BlkassignoffNode &bNode, Operand *src) { } /* return true if blkassignoff for return, false otherwise */ -bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src) { +bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList) { AArch64reg regno = static_cast(static_cast(src)->GetRegisterNumber()); if (IsBlkassignForPush(bNode)) { PrimType pTy = PTY_i64; - MIRStructType *ty = static_cast(GetAggTyFromCallSite(&bNode)); + MIRStructType *ty = static_cast(LmbcGetAggTyFromCallSite(&bNode, parmList)); uint32 size = 0; uint32 fpregs = ty ? FloatParamRegRequired(ty, size) : 0; /* fp size determined */ if (fpregs > 0) { @@ -2093,7 +2153,7 @@ bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src) { MemOperand &mem = CreateMemOpnd(regno, s, size * kBitsPerByte); RegOperand *res = &CreateVirtualRegisterOperand(NewVReg(kRegTyFloat, size)); SelectCopy(*res, pTy, mem, pTy); - SetLmbcArgInfo(res, pTy, bNode.offset + s, fpregs); + SetLmbcArgInfo(res, pTy, 0, fpregs); IncLmbcArgsInRegs(kRegTyFloat); } IncLmbcTotalArgs(); @@ -2134,6 +2194,41 @@ bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src) { return false; } +/* This function is incomplete and may be removed when Lmbc IR is changed + to have the lowerer figures out the address of the large agg to reside */ +uint32 AArch64CGFunc::LmbcFindTotalStkUsed(std::vector *paramList) { + AArch64CallConvImpl parmlocator(GetBecommon()); + CCLocInfo pLoc; + for (TyIdx tyIdx : *paramList) { + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); + parmlocator.LocateNextParm(*ty, pLoc); + } + return 0; +} + +/* All arguments passed as registers */ +uint32 AArch64CGFunc::LmbcTotalRegsUsed() { + if (GetLmbcArgInfo() == nullptr) { + return 0; /* no arg */ + } + MapleVector ®s = GetLmbcCallArgNumOfRegs(); + MapleVector &types = GetLmbcCallArgTypes(); + uint32 iCnt = 0; + uint32 fCnt = 0; + for (uint32 i = 0; i < regs.size(); i++) { + if (IsPrimitiveInteger(types[i])) { + if ((iCnt + regs[i]) <= k8ByteSize) { + iCnt += regs[i]; + }; + } else { + if ((fCnt + regs[i]) <= k8ByteSize) { + fCnt += regs[i]; + }; + } + } + return iCnt + fCnt; +} + /* If blkassignoff for argument, this function loads the agg arguments into virtual registers, disregard if there is sufficient physicall call registers. Argument > 16-bytes are copied to preset space and ptr @@ -2142,29 +2237,40 @@ bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src) { void AArch64CGFunc::SelectBlkassignoff(BlkassignoffNode &bNode, Operand *src) { CHECK_FATAL(src->GetKind() == Operand::kOpdRegister, "blkassign src type not in register"); + std::vector *parmList; if (GetLmbcArgInfo() == nullptr) { LmbcArgInfo *p = memPool->New(*GetFuncScopeAllocator()); SetLmbcArgInfo(p); } if (LmbcSmallAggForRet(bNode, src)) { return; - } else if (LmbcSmallAggForCall(bNode, src)) { + } else if (LmbcSmallAggForCall(bNode, src, &parmList)) { return; } - /* memcpy for agg assign OR large agg for arg/ret */ Operand *dest = HandleExpr(bNode, *bNode.Opnd(0)); RegOperand *regResult = &CreateVirtualRegisterOperand(NewVReg(kRegTyInt, k8ByteSize)); + /* memcpy for agg assign OR large agg for arg/ret */ + int32 offset = bNode.offset; + if (IsBlkassignForPush(bNode)) { + /* large agg for call, addr to be pushed in SelectCall */ + offset = GetLmbcTotalStkUsed(); + if (offset < 0) { + /* length of ALL stack based args for this call, this location is where the + next large agg resides, its addr will then be passed */ + offset = LmbcFindTotalStkUsed(parmList) + LmbcTotalRegsUsed(); + } + SetLmbcTotalStkUsed(offset + bNode.blockSize); /* next use */ + SetLmbcArgInfo(regResult, PTY_i64, 0, 1); /* 1 reg for ptr */ + IncLmbcArgsInRegs(kRegTyInt); + IncLmbcTotalArgs(); + /* copy large agg arg to offset below */ + } std::vector opndVec; opndVec.push_back(regResult); /* result */ - opndVec.push_back(PrepareMemcpyParamOpnd(bNode.offset, *dest));/* param 0 */ + opndVec.push_back(PrepareMemcpyParamOpnd(offset, *dest)); /* param 0 */ opndVec.push_back(src); /* param 1 */ opndVec.push_back(PrepareMemcpyParamOpnd(bNode.blockSize));/* param 2 */ SelectLibCall("memcpy", opndVec, PTY_a64, PTY_a64); - if (IsBlkassignForPush(bNode)) { - SetLmbcArgInfo(static_cast(src), PTY_i64, (int32)bNode.offset, 1); - IncLmbcArgsInRegs(kRegTyInt); - IncLmbcTotalArgs(); - } } void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { @@ -2550,6 +2656,159 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { } } +void AArch64CGFunc::SelectReturnSendOfStructInRegs(BaseNode *x) { + uint32 offset = 0; + if (x->GetOpCode() == OP_dread) { + DreadNode *dread = static_cast(x); + MIRSymbol *sym = GetFunction().GetLocalOrGlobalSymbol(dread->GetStIdx()); + MIRType *mirType = sym->GetType(); + if (dread->GetFieldID() != 0) { + MIRStructType *structType = static_cast(mirType); + mirType = structType->GetFieldType(dread->GetFieldID()); + offset = static_cast(GetBecommon().GetFieldOffset(*structType, dread->GetFieldID()).first); + } + uint32 typeSize = GetBecommon().GetTypeSize(mirType->GetTypeIndex()); + /* generate move to regs for agg return */ + AArch64CallConvImpl parmlocator(GetBecommon()); + CCLocInfo pLoc; + parmlocator.LocateNextParm(*mirType, pLoc, true, GetBecommon().GetMIRModule().CurFunction()); + /* aggregates are 8 byte aligned. */ + Operand *rhsmemopnd = nullptr; + RegOperand *result[kFourRegister]; /* up to 2 int or 4 fp */ + uint32 loadSize; + uint32 numRegs; + RegType regType; + PrimType retPty; + bool fpParm = false; + if (pLoc.numFpPureRegs) { + loadSize = pLoc.fpSize; + numRegs = pLoc.numFpPureRegs; + fpParm = true; + regType = kRegTyFloat; + retPty = (pLoc.fpSize == k4ByteSize) ? PTY_f32 : PTY_f64; + } else { + if (CGOptions::IsBigEndian()) { + loadSize = k8ByteSize; + numRegs = (typeSize <= k8ByteSize) ? kOneRegister : kTwoRegister; + regType = kRegTyInt; + retPty = PTY_u64; + } else { + loadSize = (typeSize <= k4ByteSize) ? k4ByteSize : k8ByteSize; + numRegs = (typeSize <= k8ByteSize) ? kOneRegister : kTwoRegister; + regType = kRegTyInt; + retPty = PTY_u32; + } + } + bool parmCopy = IsParamStructCopy(*sym); + for (uint32 i = 0; i < numRegs; i++) { + if (parmCopy) { + rhsmemopnd = &LoadStructCopyBase(*sym, + (offset + static_cast(i * (fpParm ? loadSize : k8ByteSize))), + static_cast(loadSize * kBitsPerByte)); + } else { + rhsmemopnd = &GetOrCreateMemOpnd(*sym, + (offset + static_cast(i * (fpParm ? loadSize : k8ByteSize))), + (loadSize * kBitsPerByte)); + } + result[i] = &CreateVirtualRegisterOperand(NewVReg(regType, loadSize)); + MOperator mop1 = PickLdInsn(loadSize * kBitsPerByte, retPty); + Insn &ld = GetCG()->BuildInstruction(mop1, *(result[i]), *rhsmemopnd); + GetCurBB()->AppendInsn(ld); + } + AArch64reg regs[kFourRegister]; + regs[0] = static_cast(pLoc.reg0); + regs[1] = static_cast(pLoc.reg1); + regs[2] = static_cast(pLoc.reg2); + regs[3] = static_cast(pLoc.reg3); + RegOperand *dest; + for (uint32 i = 0; i < numRegs; i++) { + AArch64reg preg; + MOperator mop2; + if (fpParm) { + preg = regs[i]; + mop2 = (loadSize == k4ByteSize) ? MOP_xvmovs : MOP_xvmovd; + } else { + preg = (i == 0 ? R0 : R1); + mop2 = (loadSize == k4ByteSize) ? MOP_wmovrr : MOP_xmovrr; + } + dest = &GetOrCreatePhysicalRegisterOperand(preg, (loadSize * kBitsPerByte), regType); + Insn &mov = GetCG()->BuildInstruction(mop2, *dest, *(result[i])); + GetCurBB()->AppendInsn(mov); + } + /* Create artificial dependency to extend the live range */ + for (uint32 i = 0; i < numRegs; i++) { + AArch64reg preg; + MOperator mop3; + if (fpParm) { + preg = regs[i]; + mop3 = MOP_pseudo_ret_float; + } else { + preg = (i == 0 ? R0 : R1); + mop3 = MOP_pseudo_ret_int; + } + dest = &GetOrCreatePhysicalRegisterOperand(preg, loadSize * kBitsPerByte, regType); + Insn &pseudo = GetCG()->BuildInstruction(mop3, *dest); + GetCurBB()->AppendInsn(pseudo); + } + return; + } else if (x->GetOpCode() == OP_iread) { + IreadNode *iread = static_cast(x); + RegOperand *rhsAddrOpnd = static_cast(HandleExpr(*iread, *iread->Opnd(0))); + rhsAddrOpnd = &LoadIntoRegister(*rhsAddrOpnd, iread->Opnd(0)->GetPrimType()); + MIRPtrType *ptrType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread->GetTyIdx())); + MIRType *mirType = static_cast(ptrType->GetPointedType()); + bool isRefField = false; + if (iread->GetFieldID() != 0) { + MIRStructType *structType = static_cast(mirType); + mirType = structType->GetFieldType(iread->GetFieldID()); + offset = static_cast(GetBecommon().GetFieldOffset(*structType, iread->GetFieldID()).first); + isRefField = GetBecommon().IsRefField(*structType, iread->GetFieldID()); + } + uint32 typeSize = GetBecommon().GetTypeSize(mirType->GetTypeIndex()); + /* generate move to regs. */ + RegOperand *result[kTwoRegister]; /* maximum 16 bytes, 2 registers */ + uint32 loadSize; + if (CGOptions::IsBigEndian()) { + loadSize = k8ByteSize; + } else { + loadSize = (typeSize <= k4ByteSize) ? k4ByteSize : k8ByteSize; + } + uint32 numRegs = (typeSize <= k8ByteSize) ? kOneRegister : kTwoRegister; + for (uint32 i = 0; i < numRegs; i++) { + OfstOperand *rhsOffOpnd = &GetOrCreateOfstOpnd(offset + i * loadSize, loadSize * kBitsPerByte); + Operand &rhsmemopnd = GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, loadSize * kBitsPerByte, + rhsAddrOpnd, nullptr, rhsOffOpnd, nullptr); + result[i] = &CreateVirtualRegisterOperand(NewVReg(kRegTyInt, loadSize)); + MOperator mop1 = PickLdInsn(loadSize * kBitsPerByte, PTY_u32); + Insn &ld = GetCG()->BuildInstruction(mop1, *(result[i]), rhsmemopnd); + ld.MarkAsAccessRefField(isRefField); + GetCurBB()->AppendInsn(ld); + } + RegOperand *dest; + for (uint32 i = 0; i < numRegs; i++) { + AArch64reg preg = (i == 0 ? R0 : R1); + dest = &GetOrCreatePhysicalRegisterOperand(preg, loadSize * kBitsPerByte, kRegTyInt); + Insn &mov = GetCG()->BuildInstruction(MOP_xmovrr, *dest, *(result[i])); + GetCurBB()->AppendInsn(mov); + } + /* Create artificial dependency to extend the live range */ + for (uint32 i = 0; i < numRegs; i++) { + AArch64reg preg = (i == 0 ? R0 : R1); + dest = &GetOrCreatePhysicalRegisterOperand(preg, loadSize * kBitsPerByte, kRegTyInt); + Insn &pseudo = cg->BuildInstruction(MOP_pseudo_ret_int, *dest); + GetCurBB()->AppendInsn(pseudo); + } + return; + } else { // dummy return of 0 inserted by front-end at absence of return + ASSERT(x->GetOpCode() == OP_constval, "SelectReturnSendOfStructInRegs: unexpected return operand"); + uint32 typeSize = GetPrimTypeSize(x->GetPrimType()); + RegOperand &dest = GetOrCreatePhysicalRegisterOperand(R0, typeSize * kBitsPerByte, kRegTyInt); + ImmOperand &src = CreateImmOperand(0, k16BitSize, false); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_xmovri32, dest, src)); + return; + } +} + Operand *AArch64CGFunc::SelectDread(const BaseNode &parent, DreadNode &expr) { MIRSymbol *symbol = GetFunction().GetLocalOrGlobalSymbol(expr.GetStIdx()); if (symbol->IsEhIndex()) { @@ -2913,31 +3172,50 @@ Operand *AArch64CGFunc::SelectIreadoff(const BaseNode &parent, IreadoffNode &ire return result; } -RegOperand *AArch64CGFunc::GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType) { - MemOperand *memOpnd; - RegOperand *rfp = &GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); - uint32 bitlen = byteSize * kBitsPerByte; - if (offset < 0) { - RegOperand *baseOpnd = &CreateRegisterOperandOfType(PTY_a64); - ImmOperand &immOpnd = CreateImmOperand(offset, k32BitSize, true); - Insn &addInsn = GetCG()->BuildInstruction(MOP_xaddrri12, *baseOpnd, *rfp, immOpnd); - GetCurBB()->AppendInsn(addInsn); - OfstOperand *offsetOpnd = &CreateOfstOpnd(0, k32BitSize); - memOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, bitlen, baseOpnd, - nullptr, offsetOpnd, nullptr); - } else { - OfstOperand *offsetOpnd = &CreateOfstOpnd(offset, k32BitSize); - memOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, bitlen, rfp, - nullptr, offsetOpnd, nullptr); - } - memOpnd->SetStackMem(true); +RegOperand *AArch64CGFunc::GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType, + AArch64reg baseRegno) { + MemOperand *memOpnd = GenLmbcFpMemOperand(offset, byteSize, baseRegno); RegOperand *result = &GetOrCreateVirtualRegisterOperand(NewVReg(regType, byteSize)); - MOperator mOp = PickLdInsn(bitlen, primType); + MOperator mOp = PickLdInsn(byteSize * kBitsPerByte, primType); Insn &load = GetCG()->BuildInstruction(mOp, *result, *memOpnd); GetCurBB()->AppendInsn(load); return result; } +RegOperand *AArch64CGFunc::LmbcStructReturnLoad(int32 offset) { + RegOperand *result = nullptr; + MIRFunction &func = GetFunction(); + CHECK_FATAL(func.IsReturnStruct(), "LmbcStructReturnLoad: not struct return"); + MIRType *ty = func.GetReturnType(); + uint32 sz = GetBecommon().GetTypeSize(ty->GetTypeIndex()); + uint32 fpSize; + uint32 numFpRegs = FloatParamRegRequired(static_cast(ty), fpSize); + if (numFpRegs > 0) { + PrimType pType = (fpSize <= k4ByteSize) ? PTY_f32 : PTY_f64; + for (int32 i = (numFpRegs - kOneRegister); i > 0; --i) { + result = GenLmbcParamLoad(offset + (i * fpSize), fpSize, kRegTyFloat, pType); + AArch64reg regNo = static_cast(V0 + i); + RegOperand *reg = &GetOrCreatePhysicalRegisterOperand(regNo, fpSize * kBitsPerByte, kRegTyFloat); + SelectCopy(*reg, pType, *result, pType); + Insn &pseudo = GetCG()->BuildInstruction(MOP_pseudo_ret_float, *reg); + GetCurBB()->AppendInsn(pseudo); + } + result = GenLmbcParamLoad(offset, fpSize, kRegTyFloat, pType); + } else if (sz <= k4ByteSize) { + result = GenLmbcParamLoad(offset, k4ByteSize, kRegTyInt, PTY_u32); + } else if (sz <= k8ByteSize) { + result = GenLmbcParamLoad(offset, k8ByteSize, kRegTyInt, PTY_i64); + } else if (sz <= k16ByteSize) { + result = GenLmbcParamLoad(offset + k8ByteSize, k8ByteSize, kRegTyInt, PTY_i64); + RegOperand *r1 = &GetOrCreatePhysicalRegisterOperand(R1, k8ByteSize * kBitsPerByte, kRegTyInt); + SelectCopy(*r1, PTY_i64, *result, PTY_i64); + Insn &pseudo = GetCG()->BuildInstruction(MOP_pseudo_ret_int, *r1); + GetCurBB()->AppendInsn(pseudo); + result = GenLmbcParamLoad(offset, k8ByteSize, kRegTyInt, PTY_i64); + } + return result; +} + Operand *AArch64CGFunc::SelectIreadfpoff(const BaseNode &parent, IreadFPoffNode &ireadoff) { int32 offset = ireadoff.GetOffset(); PrimType primType = ireadoff.GetPrimType(); @@ -2948,19 +3226,32 @@ Operand *AArch64CGFunc::SelectIreadfpoff(const BaseNode &parent, IreadFPoffNode if (offset >= 0) { LmbcFormalParamInfo *info = GetLmbcFormalParamInfo(offset); if (info->GetPrimType() == PTY_agg) { - result = GenLmbcParamLoad(offset, bytelen, regty, primType); + if (info->IsOnStack()) { + result = GenLmbcParamLoad(info->GetOnStackOffset(), GetPrimTypeSize(PTY_a64), kRegTyInt, PTY_a64); + regno_t baseRegno = result->GetRegisterNumber(); + result = GenLmbcParamLoad(offset - info->GetOffset(), bytelen, regty, primType, (AArch64reg)baseRegno); + } else if (primType == PTY_agg) { + CHECK_FATAL(parent.GetOpCode() == OP_regassign, "SelectIreadfpoff of agg"); + result = LmbcStructReturnLoad(offset); + } else { + result = GenLmbcParamLoad(offset, bytelen, regty, primType); + } } else { CHECK_FATAL(primType == info->GetPrimType(), "Incorrect primtype"); CHECK_FATAL(offset == info->GetOffset(), "Incorrect offset"); - if (info->GetRegNO() == 0) { - /* TODO : follow lmbc sp offset for now */ + if (info->GetRegNO() == 0 || info->HasRegassign() == false) { result = GenLmbcParamLoad(offset, bytelen, regty, primType); } else { result = &GetOrCreatePhysicalRegisterOperand((AArch64reg)(info->GetRegNO()), bitlen, regty); } } } else { - result = GenLmbcParamLoad(offset, bytelen, regty, primType); + if (primType == PTY_agg) { + CHECK_FATAL(parent.GetOpCode() == OP_regassign, "SelectIreadfpoff of agg"); + result = LmbcStructReturnLoad(offset); + } else { + result = GenLmbcParamLoad(offset, bytelen, regty, primType); + } } return result; } @@ -5756,6 +6047,9 @@ Operand *AArch64CGFunc::SelectAlloca(UnaryNode &node, Operand &opnd0) { if (!CGOptions::IsArm64ilp32()) { ASSERT((node.GetPrimType() == PTY_a64), "wrong type"); } + if (GetCG()->IsLmbc()) { + SetHasVLAOrAlloca(true); + } PrimType stype = node.Opnd(0)->GetPrimType(); Operand *resOpnd = &opnd0; if (GetPrimTypeBitSize(stype) < GetPrimTypeBitSize(PTY_u64)) { @@ -5771,10 +6065,13 @@ Operand *AArch64CGFunc::SelectAlloca(UnaryNode &node, Operand &opnd0) { SelectShift(aliOp, aliOp, shifOpnd, kShiftLeft, PTY_u64); Operand &spOpnd = GetOrCreatePhysicalRegisterOperand(RSP, k64BitSize, kRegTyInt); SelectSub(spOpnd, spOpnd, aliOp, PTY_u64); - int64 argsToStkpassSize = GetMemlayout()->SizeOfArgsToStackPass(); - if (argsToStkpassSize > 0) { + int64 allocaOffset = GetMemlayout()->SizeOfArgsToStackPass(); + if (GetCG()->IsLmbc()) { + allocaOffset -= kDivide2 * k8ByteSize; + } + if (allocaOffset > 0) { RegOperand &resallo = CreateRegisterOperandOfType(PTY_u64); - SelectAdd(resallo, spOpnd, CreateImmOperand(argsToStkpassSize, k64BitSize, true), PTY_u64); + SelectAdd(resallo, spOpnd, CreateImmOperand(allocaOffset, k64BitSize, true), PTY_u64); return &resallo; } else { return &SelectCopy(spOpnd, PTY_u64, PTY_u64); @@ -6216,6 +6513,15 @@ void AArch64CGFunc::AssignLmbcFormalParams() { param->SetRegNO(0); } else { param->SetRegNO(intReg); + if (param->HasRegassign() == false) { + uint32 bytelen = GetPrimTypeSize(primType); + uint32 bitlen = bytelen * kBitsPerByte; + MemOperand *mOpnd = GenLmbcFpMemOperand(offset, bytelen); + RegOperand &src = GetOrCreatePhysicalRegisterOperand(AArch64reg(intReg), bitlen, kRegTyInt); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, src, *mOpnd); + GetCurBB()->AppendInsn(store); + } intReg++; } } else if (IsPrimitiveFloat(primType)) { @@ -6223,6 +6529,15 @@ void AArch64CGFunc::AssignLmbcFormalParams() { param->SetRegNO(0); } else { param->SetRegNO(fpReg); + if (param->HasRegassign() == false) { + uint32 bytelen = GetPrimTypeSize(primType); + uint32 bitlen = bytelen * kBitsPerByte; + MemOperand *mOpnd = GenLmbcFpMemOperand(offset, bytelen); + RegOperand &src = GetOrCreatePhysicalRegisterOperand(AArch64reg(fpReg), bitlen, kRegTyFloat); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, src, *mOpnd); + GetCurBB()->AppendInsn(store); + } fpReg++; } } else if (primType == PTY_agg) { @@ -6241,6 +6556,14 @@ void AArch64CGFunc::AssignLmbcFormalParams() { } else { param->SetRegNO(intReg); param->SetIsOnStack(); + param->SetOnStackOffset((intReg - R0 + fpReg - V0) * k8ByteSize); + uint32 bytelen = GetPrimTypeSize(PTY_a64); + uint32 bitlen = bytelen * kBitsPerByte; + MemOperand *mOpnd = GenLmbcFpMemOperand(param->GetOnStackOffset(), bytelen); + RegOperand &src = GetOrCreatePhysicalRegisterOperand(AArch64reg(intReg), bitlen, kRegTyInt); + MOperator mOp = PickStInsn(bitlen, PTY_a64); + Insn &store = GetCG()->BuildInstruction(mOp, src, *mOpnd); + GetCurBB()->AppendInsn(store); intReg++; } } else if (param->GetSize() <= k8ByteSize) { @@ -6286,7 +6609,6 @@ void AArch64CGFunc::AssignLmbcFormalParams() { Operand *memOpd = &CreateMemOpnd(RFP, offset + (i * rSize), rSize); GetCurBB()->AppendInsn(GetCG()->BuildInstruction( PickStInsn(rSize * kBitsPerByte, pType), dest, *memOpd)); - param->SetIsOnStack(); } } } else { @@ -6295,6 +6617,22 @@ void AArch64CGFunc::AssignLmbcFormalParams() { } } +void AArch64CGFunc::LmbcGenSaveSpForAlloca() { + if (GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc || HasVLAOrAlloca() == false) { + return; + } + Operand &spOpnd = GetOrCreatePhysicalRegisterOperand(RSP, k64BitSize, kRegTyInt); + RegOperand &spSaveOpnd = CreateVirtualRegisterOperand(NewVReg(kRegTyInt, kSizeOfPtr)); + Insn &save = GetCG()->BuildInstruction(MOP_xmovrr, spSaveOpnd, spOpnd); + GetFirstBB()->AppendInsn(save); + //save.SetFrameDef(true); + for (auto *retBB : GetExitBBsVec()) { + Insn &restore = GetCG()->BuildInstruction(MOP_xmovrr, spOpnd, spSaveOpnd); + retBB->AppendInsn(restore); + restore.SetFrameDef(true); + } +} + /* if offset < 0, allocation; otherwise, deallocation */ MemOperand &AArch64CGFunc::CreateCallFrameOperand(int32 offset, int32 size) { MemOperand *memOpnd = CreateStackMemOpnd(RSP, offset, size); @@ -7579,6 +7917,10 @@ size_t AArch64CGFunc::SelectParmListGetStructReturnSize(StmtNode &naryNode) { CallNode &callNode = static_cast(naryNode); MIRFunction *callFunc = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callNode.GetPUIdx()); TyIdx retIdx = callFunc->GetReturnTyIdx(); + if (callFunc->IsFirstArgReturn()) { + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(callFunc->GetFormalDefVec()[0].formalTyIdx); + return GetBecommon().GetTypeSize(static_cast(ty)->GetPointedTyIdx()); + } size_t retSize = GetBecommon().GetTypeSize(retIdx.GetIdx()); if ((retSize == 0) && callFunc->IsReturnStruct()) { TyIdx tyIdx = callFunc->GetFuncRetStructTyIdx(); @@ -7595,6 +7937,14 @@ size_t AArch64CGFunc::SelectParmListGetStructReturnSize(StmtNode &naryNode) { return GetBecommon().GetTypeSize(sym->GetTyIdx().GetIdx()); } } + } else if (naryNode.GetOpCode() == OP_icallproto) { + IcallNode &icallProto = static_cast(naryNode); + MIRFuncType *funcTy = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallProto.GetRetTyIdx())); + if (funcTy->FirstArgReturn()) { + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcTy->GetNthParamType(0)); + return GetBecommon().GetTypeSize(static_cast(ty)->GetPointedTyIdx()); + } + return GetBecommon().GetTypeSize(funcTy->GetRetTyIdx()); } return 0; } @@ -7702,7 +8052,7 @@ void AArch64CGFunc::SelectParmListPreprocess(const StmtNode &naryNode, size_t st */ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bool isCallNative) { size_t i = 0; - if ((naryNode.GetOpCode() == OP_icall) || isCallNative) { + if (naryNode.GetOpCode() == OP_icall || naryNode.GetOpCode() == OP_icallproto || isCallNative) { i++; } std::set specialArgs; @@ -7729,8 +8079,11 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - auto *callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + MIRFunction *callee = nullptr; + if (dynamic_cast(&naryNode) != nullptr) { + auto calleePuIdx = static_cast(naryNode).GetPUIdx(); + callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } @@ -8252,7 +8605,18 @@ void AArch64CGFunc::SelectCall(CallNode &callNode) { ListOperand *srcOpnds = CreateListOpnd(*GetFuncScopeAllocator()); if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { - LmbcSelectParmList(srcOpnds, fn->IsFirstArgReturn()); + SetLmbcCallReturnType(nullptr); + bool largeStructRet = false; + if (fn->IsFirstArgReturn()) { + MIRPtrType *ptrTy = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(fn->GetFormalDefVec()[0].formalTyIdx)); + MIRType *sTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ptrTy->GetPointedTyIdx()); + largeStructRet = sTy->GetSize() > k16ByteSize; + SetLmbcCallReturnType(sTy); + } else { + MIRType *ty = fn->GetReturnType(); + SetLmbcCallReturnType(ty); + } + LmbcSelectParmList(srcOpnds, largeStructRet); } bool callNative = false; if ((fsym->GetName() == "MCC_CallFastNative") || (fsym->GetName() == "MCC_CallFastNativeExt") || @@ -8328,11 +8692,21 @@ void AArch64CGFunc::SelectCall(CallNode &callNode) { void AArch64CGFunc::SelectIcall(IcallNode &icallNode, Operand &srcOpnd) { ListOperand *srcOpnds = CreateListOpnd(*GetFuncScopeAllocator()); - if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { - LmbcSelectParmList(srcOpnds, false /*fType->GetRetAttrs().GetAttr(ATTR_firstarg_return)*/); - } else { +// if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { +// /* icallproto */ +// MIRType *retTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallNode.GetRetTyIdx()); +// MIRFuncType *funcTy = static_cast(retTy); +// bool largeStructRet = false; +// if (funcTy->FirstArgReturn()) { +// TyIdx idx = funcTy->GetNthParamType(0); +// MIRPtrType *ptrTy = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(idx)); +// MIRType *sTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ptrTy->GetPointedTyIdx()); +// largeStructRet = sTy->GetSize() > k16ByteSize; +// } +// LmbcSelectParmList(srcOpnds, largeStructRet); +// } else { SelectParmList(icallNode, *srcOpnds); - } +// } Operand *fptrOpnd = &srcOpnd; if (fptrOpnd->GetKind() != Operand::kOpdRegister) { @@ -8343,7 +8717,7 @@ void AArch64CGFunc::SelectIcall(IcallNode &icallNode, Operand &srcOpnd) { RegOperand *regOpnd = static_cast(fptrOpnd); Insn &callInsn = GetCG()->BuildInstruction(MOP_xblr, *regOpnd, *srcOpnds); - MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallNode.GetRetTyIdx()); + MIRType *retType = icallNode.GetCallReturnType(); if (retType != nullptr) { callInsn.SetRetSize(static_cast(retType->GetSize())); callInsn.SetIsCallReturnUnsigned(IsUnsignedInteger(retType->GetPrimType())); @@ -8456,9 +8830,18 @@ RegOperand &AArch64CGFunc::GetOrCreateSpecialRegisterOperand(PregIdx sregIdx, Pr case kSregFp: reg = RFP; break; - case kSregGp: - reg = RFP; - break; + case kSregGp: { + MIRSymbol *sym = GetCG()->GetGP(); + if (sym == nullptr) { + sym = GetFunction().GetSymTab()->CreateSymbol(kScopeLocal); + std::string strBuf("__file__local__GP"); + sym->SetNameStrIdx(GetMirModule().GetMIRBuilder()->GetOrCreateStringIndex(strBuf)); + GetCG()->SetGP(sym); + } + RegOperand &result = GetOrCreateVirtualRegisterOperand(NewVReg(kRegTyInt, k8ByteSize)); + SelectAddrof(result, CreateStImmOperand(*sym, 0, 0)); + return result; + } case kSregThrownval: { /* uses x0 == R0 */ ASSERT(uCatch.regNOCatch > 0, "regNOCatch should greater than 0."); if (Globals::GetInstance()->GetOptimLevel() == 0) { @@ -9195,6 +9578,9 @@ int32 AArch64CGFunc::GetBaseOffset(const SymbolAlloc &sa) { int32 baseOffset = symAlloc->GetOffset(); return baseOffset + sizeofFplr; } else if (sgKind == kMsSpillReg) { + if (GetCG()->IsLmbc()) { + return symAlloc->GetOffset() + memLayout->SizeOfArgsToStackPass(); + } int32 baseOffset = symAlloc->GetOffset() + memLayout->SizeOfArgsRegisterPassed() + memLayout->GetSizeOfLocals() + memLayout->GetSizeOfRefLocals(); return baseOffset + sizeofFplr; @@ -9769,16 +10155,21 @@ void AArch64CGFunc::GenCVaStartIntrin(RegOperand &opnd, uint32 stkSize) { Operand &stkOpnd = GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); /* __stack */ - ImmOperand *offsOpnd = &CreateImmOperand(0, k64BitSize, true, kUnAdjustVary); /* isvary reset StackFrameSize */ + ImmOperand *offsOpnd; + if (GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + offsOpnd = &CreateImmOperand(0, k64BitSize, true, kUnAdjustVary); /* isvary reset StackFrameSize */ + } else { + offsOpnd = &CreateImmOperand(0, k64BitSize, true); + } ImmOperand *offsOpnd2 = &CreateImmOperand(stkSize, k64BitSize, false); RegOperand &vReg = CreateVirtualRegisterOperand(NewVReg(kRegTyInt, GetPrimTypeSize(LOWERED_PTR_TYPE))); if (stkSize) { SelectAdd(vReg, *offsOpnd, *offsOpnd2, LOWERED_PTR_TYPE); SelectAdd(vReg, stkOpnd, vReg, LOWERED_PTR_TYPE); } else { - SelectAdd(vReg, stkOpnd, *offsOpnd, LOWERED_PTR_TYPE); + SelectAdd(vReg, stkOpnd, *offsOpnd, LOWERED_PTR_TYPE); /* stack pointer */ } - OfstOperand *offOpnd = &GetOrCreateOfstOpnd(0, k64BitSize); + OfstOperand *offOpnd = &GetOrCreateOfstOpnd(0, k64BitSize); /* va_list ptr */ /* mem operand in va_list struct (lhs) */ MemOperand *strOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, k64BitSize, &opnd, nullptr, offOpnd, static_cast(nullptr)); @@ -9853,13 +10244,19 @@ void AArch64CGFunc::SelectCVaStart(const IntrinsiccallNode &intrnNode) { AArch64CallConvImpl parmLocator(GetBecommon()); CCLocInfo pLoc; uint32 stkSize = 0; + uint32 inReg = 0; for (uint32 i = 0; i < GetFunction().GetFormalCount(); i++) { MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(GetFunction().GetNthParamTyIdx(i)); parmLocator.LocateNextParm(*ty, pLoc); if (pLoc.reg0 == kRinvalid) { /* on stack */ stkSize = static_cast(pLoc.memOffset + pLoc.memSize); + } else { + inReg++; } } + if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + stkSize += (inReg * k8ByteSize); + } if (CGOptions::IsArm64ilp32()) { stkSize = static_cast(RoundUp(stkSize, k8ByteSize)); } else { diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp index 5716509ad6..433aeeee3a 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp @@ -40,8 +40,8 @@ constexpr uint8 insPairsNum = 5; PairMOperator extInsnPairTable[ExtTableSize][insPairsNum] = { /* {origMop, newMop} */ - {{MOP_wldrb, MOP_wldrb}, {MOP_undef, MOP_undef}, {MOP_undef, MOP_undef}, {MOP_undef, MOP_undef}, - {MOP_undef, MOP_undef}}, /* AND */ + {{MOP_wldrb, MOP_wldrb}, {MOP_wldrsh, MOP_wldrb}, {MOP_wldrh, MOP_wldrb}, {MOP_xldrsw, MOP_wldrb}, + {MOP_wldr, MOP_wldrb}}, /* AND */ {{MOP_wldrb, MOP_wldrsb}, {MOP_wldr, MOP_wldrsb}, {MOP_undef, MOP_undef}, {MOP_undef, MOP_undef}, {MOP_undef, MOP_undef}}, /* SXTB */ {{MOP_wldrh, MOP_wldrsh}, {MOP_wldrb, MOP_wldrb}, {MOP_wldrsb, MOP_wldrsb}, {MOP_wldrsh, MOP_wldrsh}, diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp index 5f2b7f37ba..60b7462f22 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp @@ -134,7 +134,7 @@ void AArch64MemLayout::LayoutVarargParams() { if (be.GetMIRModule().IsCModule() && func->GetAttr(FUNCATTR_varargs)) { for (uint32 i = 0; i < func->GetFormalCount(); i++) { if (i == 0) { - if (func->IsReturnStruct()) { + if (func->IsFirstArgReturn() && func->GetReturnType()->GetPrimType() != PTY_void) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (be.GetTypeSize(tyIdx.GetIdx()) <= k16ByteSize) { continue; @@ -198,7 +198,7 @@ void AArch64MemLayout::LayoutFormalParams() { * outparmsize - portion of frame size of current function used by call parameters */ segArgsStkPassed.SetSize(mirFunction->GetOutParmSize()); - segArgsRegPassed.SetSize(mirFunction->GetOutParmSize() + kTwoRegister * k8ByteSize); + segArgsRegPassed.SetSize(mirFunction->GetOutParmSize()); return; } @@ -210,7 +210,7 @@ void AArch64MemLayout::LayoutFormalParams() { AArch64SymbolAlloc *symLoc = memAllocator->GetMemPool()->New(); SetSymAllocInfo(stIndex, *symLoc); if (i == 0) { - if (mirFunction->IsReturnStruct()) { + if (mirFunction->IsFirstArgReturn()) { symLoc->SetMemSegment(GetSegArgsRegPassed()); symLoc->SetOffset(GetSegArgsRegPassed().GetSize()); TyIdx tyIdx = mirFunction->GetFuncRetStructTyIdx(); @@ -224,13 +224,13 @@ void AArch64MemLayout::LayoutFormalParams() { continue; } } - MIRType *ty = mirFunction->GetNthParamType(i); + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(mirFunction->GetFormalDefVec()[i].formalTyIdx); uint32 ptyIdx = ty->GetTypeIndex(); parmLocator.LocateNextParm(*ty, ploc, i == 0, mirFunction); if (ploc.reg0 != kRinvalid) { /* register */ symLoc->SetRegisters(static_cast(ploc.reg0), static_cast(ploc.reg1), static_cast(ploc.reg2), static_cast(ploc.reg3)); - if (mirFunction->GetNthParamAttr(i).GetAttr(ATTR_localrefvar)) { + if (mirFunction->GetFormalDefVec()[i].formalAttrs.GetAttr(ATTR_localrefvar)) { symLoc->SetMemSegment(segRefLocals); SetSegmentSize(*symLoc, segRefLocals, ptyIdx); } else if (!sym->IsPreg()) { @@ -272,7 +272,7 @@ void AArch64MemLayout::LayoutFormalParams() { } else { segArgsStkPassed.SetSize(static_cast(RoundUp(segArgsStkPassed.GetSize(), kSizeOfPtr))); } - if (mirFunction->GetNthParamAttr(i).GetAttr(ATTR_localrefvar)) { + if (mirFunction->GetFormalDefVec()[i].formalAttrs.GetAttr(ATTR_localrefvar)) { SetLocalRegLocInfo(sym->GetStIdx(), *symLoc); AArch64SymbolAlloc *symLoc1 = memAllocator->GetMemPool()->New(); symLoc1->SetMemSegment(segRefLocals); @@ -287,7 +287,7 @@ void AArch64MemLayout::LayoutFormalParams() { } void AArch64MemLayout::LayoutLocalVariables(std::vector &tempVar, std::vector &returnDelays) { - if (be.GetMIRModule().GetFlavor() == kFlavorLmbc && mirFunction->GetFormalCount() == 0) { + if (be.GetMIRModule().GetFlavor() == kFlavorLmbc) { segLocals.SetSize(mirFunction->GetFrameSize() - mirFunction->GetOutParmSize()); return; } @@ -372,7 +372,7 @@ void AArch64MemLayout::LayoutReturnRef(std::vector &returnDelays, segRefLocals.SetSize(segRefLocals.GetSize() + be.GetTypeSize(tyIdx)); } if (be.GetMIRModule().GetFlavor() == kFlavorLmbc) { - segArgsToStkPass.SetSize(mirFunction->GetOutParmSize()); + segArgsToStkPass.SetSize(mirFunction->GetOutParmSize() + kDivide2 * k8ByteSize); } else { segArgsToStkPass.SetSize(FindLargestActualArea(structCopySize)); } @@ -423,7 +423,7 @@ void AArch64MemLayout::LayoutActualParams() { * variables get assigned their respecitve storage, i.e. * CallFrameSize (discounting callee-saved and FP/LR) is known. */ - MIRType *ty = mirFunction->GetNthParamType(i); + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(mirFunction->GetFormalDefVec()[i].formalTyIdx); uint32 ptyIdx = ty->GetTypeIndex(); static_cast(cgFunc)->GetOrCreateMemOpnd(*sym, 0, be.GetTypeAlign(ptyIdx) * kBitsPerByte); } @@ -440,7 +440,7 @@ void AArch64MemLayout::LayoutStackFrame(int32 &structCopySize, int32 &maxParmSta */ if (CGOptions::IsArm64ilp32()) { segArgsRegPassed.SetSize(RoundUp(segArgsRegPassed.GetSize(), k8ByteSize)); - /* we do need this as SP has to be aligned at a 16-bytes bounardy */ + /* we do need this as SP has to be aligned at a 16-bytes bounardy */ segArgsStkPassed.SetSize(RoundUp(segArgsStkPassed.GetSize(), k8ByteSize + k8ByteSize)); } else { segArgsRegPassed.SetSize(RoundUp(segArgsRegPassed.GetSize(), kSizeOfPtr)); @@ -527,11 +527,13 @@ uint64 AArch64MemLayout::StackFrameSize() const { uint64 total = segArgsRegPassed.GetSize() + static_cast(cgFunc)->SizeOfCalleeSaved() + GetSizeOfRefLocals() + locals().GetSize() + GetSizeOfSpillReg(); - if (GetSizeOfGRSaveArea() > 0) { - total += RoundUp(GetSizeOfGRSaveArea(), kAarch64StackPtrAlignment); - } - if (GetSizeOfVRSaveArea() > 0) { - total += RoundUp(GetSizeOfVRSaveArea(), kAarch64StackPtrAlignment); + if (cgFunc->GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + if (GetSizeOfGRSaveArea() > 0) { + total += RoundUp(GetSizeOfGRSaveArea(), kAarch64StackPtrAlignment); + } + if (GetSizeOfVRSaveArea() > 0) { + total += RoundUp(GetSizeOfVRSaveArea(), kAarch64StackPtrAlignment); + } } /* diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp index eaa5726d43..7ef7190645 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp @@ -50,7 +50,7 @@ void AArch64FPLROffsetAdjustment::AdjustmentOffsetForOpnd(Insn &insn, AArch64CGF if (memBaseReg->GetRegisterNumber() == RFP) { RegOperand &newBaseOpnd = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(stackBaseReg, k64BitSize, kRegTyInt); MemOperand &newMemOpnd = aarchCGFunc.GetOrCreateMemOpnd( - MemOperand::kAddrModeBOi, memOpnd.GetSize(), &newBaseOpnd, memOpnd.GetIndexRegister(), + memOpnd.GetAddrMode(), memOpnd.GetSize(), &newBaseOpnd, memOpnd.GetIndexRegister(), memOpnd.GetOffsetImmediate(), memOpnd.GetSymbol()); insn.SetOperand(i, newMemOpnd); stackBaseOpnd = true; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp index 8ea922dac1..09ee411939 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp @@ -1118,6 +1118,9 @@ void AArch64GenProEpilog::AppendInstructionAllocateCallFrameDebug(AArch64reg reg ipoint = cgFunc.GetCurBB()->GetLastInsn(); cfiOffset = stackFrameSize; (void)InsertCFIDefCfaOffset(cfiOffset, *ipoint); + if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + argsToStkPassSize -= (kDivide2 * k8ByteSize); + } ipoint = &CreateAndAppendInstructionForAllocateCallFrame(argsToStkPassSize, reg0, reg1, rty); CHECK_FATAL(ipoint != nullptr, "ipoint should not be nullptr at this point"); cfiOffset = GetOffsetFromCFA(); @@ -1251,9 +1254,16 @@ void AArch64GenProEpilog::GeneratePushRegs() { CHECK_FATAL(*it == RLR, "The second callee saved reg is expected to be RLR"); ++it; - auto offset = static_cast(static_cast(cgFunc.GetMemlayout())->RealStackFrameSize() - - (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */) - - cgFunc.GetMemlayout()->SizeOfArgsToStackPass()); + AArch64MemLayout *memLayout = static_cast(cgFunc.GetMemlayout()); + int32 offset; + if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + offset = static_cast(memLayout->RealStackFrameSize() - + aarchCGFunc.SizeOfCalleeSaved() - memLayout->GetSizeOfLocals()); + } else { + offset = static_cast(memLayout->RealStackFrameSize() - + (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */) - + memLayout->SizeOfArgsToStackPass()); + } if (cgFunc.GetCG()->IsStackProtectorStrong() || cgFunc.GetCG()->IsStackProtectorAll()) { offset -= static_cast(kAarch64StackPtrAlignment); @@ -1313,10 +1323,19 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { size = kSizeOfPtr; } uint32 dataSizeBits = size * kBitsPerByte; - uint32 offset = static_cast(memlayout->GetGRSaveAreaBaseLoc()); - if (memlayout->GetSizeOfGRSaveArea() % kAarch64StackPtrAlignment) { - offset += size; /* End of area should be aligned. Hole between VR and GR area */ + uint32 offset; + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + offset = static_cast(memlayout->GetGRSaveAreaBaseLoc()); /* SP reference */ + if (memlayout->GetSizeOfGRSaveArea() % kAarch64StackPtrAlignment) { + offset += size; /* End of area should be aligned. Hole between VR and GR area */ + } + } else { + offset = -memlayout->GetSizeOfGRSaveArea(); /* FP reference */ + if (memlayout->GetSizeOfGRSaveArea() % kAarch64StackPtrAlignment) { + offset -= size; + } } + uint32 grSize = -offset; uint32 start_regno = k8BitSize - (memlayout->GetSizeOfGRSaveArea() / size); ASSERT(start_regno <= k8BitSize, "Incorrect starting GR regno for GR Save Area"); for (uint32 i = start_regno + static_cast(R0); i < static_cast(R8); i++) { @@ -1326,16 +1345,25 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { tmpOffset += 8U - (dataSizeBits >> 3); } } - Operand &stackloc = aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); + Operand *stackLoc; + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + stackLoc = &aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); + } else { + stackLoc = aarchCGFunc.GenLmbcFpMemOperand(offset, size); + } RegOperand ® = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(static_cast(i), k64BitSize, kRegTyInt); Insn &inst = - currCG->BuildInstruction(aarchCGFunc.PickStInsn(dataSizeBits, PTY_i64), reg, stackloc); + currCG->BuildInstruction(aarchCGFunc.PickStInsn(dataSizeBits, PTY_i64), reg, *stackLoc); cgFunc.GetCurBB()->AppendInsn(inst); offset += size; } if (!CGOptions::UseGeneralRegOnly()) { - offset = static_cast(memlayout->GetVRSaveAreaBaseLoc()); + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + offset = static_cast(memlayout->GetVRSaveAreaBaseLoc()); + } else { + offset = -(memlayout->GetSizeOfVRSaveArea() + grSize); + } start_regno = k8BitSize - (memlayout->GetSizeOfVRSaveArea() / (size * k2BitSize)); ASSERT(start_regno <= k8BitSize, "Incorrect starting GR regno for VR Save Area"); for (uint32 i = start_regno + static_cast(V0); i < static_cast(V8); i++) { @@ -1345,11 +1373,16 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { tmpOffset += 16U - (dataSizeBits >> 3); } } - Operand &stackloc = aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); + Operand *stackLoc; + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + stackLoc = &aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); + } else { + stackLoc = aarchCGFunc.GenLmbcFpMemOperand(offset, size); + } RegOperand ® = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(static_cast(i), k64BitSize, kRegTyFloat); Insn &inst = - currCG->BuildInstruction(aarchCGFunc.PickStInsn(dataSizeBits, PTY_f64), reg, stackloc); + currCG->BuildInstruction(aarchCGFunc.PickStInsn(dataSizeBits, PTY_f64), reg, *stackLoc); cgFunc.GetCurBB()->AppendInsn(inst); offset += (size * k2BitSize); } @@ -1389,7 +1422,8 @@ void AArch64GenProEpilog::GenerateProlog(BB &bb) { } // insert .loc for function - if (currCG->GetCGOptions().WithLoc()) { + if (currCG->GetCGOptions().WithLoc() && + (!currCG->GetMIRModule()->IsCModule() || currCG->GetMIRModule()->IsWithDbgInfo())) { MIRFunction *func = &cgFunc.GetFunction(); MIRSymbol *fSym = GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx()); if (currCG->GetCGOptions().WithSrc()) { @@ -1649,11 +1683,17 @@ void AArch64GenProEpilog::AppendInstructionDeallocateCallFrameDebug(AArch64reg r * ldp/stp's imm should be within -512 and 504; * if ldp's imm > 504, we fall back to the ldp-add version */ - if (cgFunc.HasVLAOrAlloca() || argsToStkPassSize == 0) { - stackFrameSize -= argsToStkPassSize; - if (stackFrameSize > kStpLdpImm64UpperBound) { + bool isLmbc = (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc); + if (cgFunc.HasVLAOrAlloca() || argsToStkPassSize == 0 || isLmbc) { + int lmbcOffset = 0; + if (isLmbc == false) { + stackFrameSize -= argsToStkPassSize; + } else { + lmbcOffset = argsToStkPassSize - (kDivide2 * k8ByteSize); + } + if (stackFrameSize > kStpLdpImm64UpperBound || isLmbc) { Operand *o2; - o2 = aarchCGFunc.CreateStackMemOpnd(RSP, 0, kSizeOfPtr * kBitsPerByte); + o2 = aarchCGFunc.CreateStackMemOpnd(RSP, (isLmbc ? lmbcOffset : 0), kSizeOfPtr * kBitsPerByte); Insn &deallocInsn = currCG->BuildInstruction(mOp, o0, o1, *o2); cgFunc.GetCurBB()->AppendInsn(deallocInsn); if (cgFunc.GenCfi()) { @@ -1728,9 +1768,16 @@ void AArch64GenProEpilog::GeneratePopRegs() { CHECK_FATAL(*it == RLR, "The second callee saved reg is expected to be RLR"); ++it; - int32 offset = static_cast(cgFunc.GetMemlayout())->RealStackFrameSize() - - (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */) - - cgFunc.GetMemlayout()->SizeOfArgsToStackPass(); + AArch64MemLayout *memLayout = static_cast(cgFunc.GetMemlayout()); + int32 offset; + if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + offset = static_cast(memLayout->RealStackFrameSize() - + aarchCGFunc.SizeOfCalleeSaved() - memLayout->GetSizeOfLocals()); + } else { + offset = static_cast(cgFunc.GetMemlayout())->RealStackFrameSize() - + (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */) - + memLayout->SizeOfArgsToStackPass(); + } if (cgFunc.GetCG()->IsStackProtectorStrong() || cgFunc.GetCG()->IsStackProtectorAll()) { offset -= static_cast(kAarch64StackPtrAlignment); @@ -1821,7 +1868,7 @@ void AArch64GenProEpilog::GenerateEpilog(BB &bb) { Operand &spOpnd = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(RSP, k64BitSize, kRegTyInt); Operand &fpOpnd = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(stackBaseReg, k64BitSize, kRegTyInt); - if (cgFunc.HasVLAOrAlloca()) { + if (cgFunc.HasVLAOrAlloca() && cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { aarchCGFunc.SelectCopy(spOpnd, PTY_u64, fpOpnd, PTY_u64); } diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp index 433cc85754..5ca154b1aa 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp @@ -161,8 +161,7 @@ void AArch64ReachingDefinition::AddRetPseudoInsn(BB &bb) { Insn &retInsn = cgFunc->GetCG()->BuildInstruction(MOP_pseudo_ret_int, regOpnd); bb.AppendInsn(retInsn); pseudoInsns.emplace_back(&retInsn); - } else { - ASSERT(regNO == V0, "CG internal error. Return value should be R0 or V0."); + } else if (regNO == V0) { RegOperand ®Opnd = static_cast(cgFunc)->GetOrCreatePhysicalRegisterOperand(regNO, k64BitSize, kRegTyFloat); Insn &retInsn = cgFunc->GetCG()->BuildInstruction(MOP_pseudo_ret_float, regOpnd); diff --git a/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp b/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp index d2ae2c25c9..bf645c15cd 100644 --- a/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp +++ b/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp @@ -160,6 +160,7 @@ void RecursiveMarkUsedStaticSymbol(const BaseNode *baseNode) { break; } case OP_addrof: + case OP_addrofoff: case OP_dread: { const AddrofNode *dreadNode = static_cast(baseNode); MarkUsedStaticSymbol(dreadNode->GetStIdx()); diff --git a/src/mapleall/maple_be/src/cg/cgfunc.cpp b/src/mapleall/maple_be/src/cg/cgfunc.cpp index 0964af1809..4fb7db62c8 100644 --- a/src/mapleall/maple_be/src/cg/cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/cgfunc.cpp @@ -1146,7 +1146,11 @@ void HandleReturn(StmtNode &stmt, CGFunc &cgFunc) { ASSERT(retNode.NumOpnds() <= 1, "NYI return nodes number > 1"); Operand *opnd = nullptr; if (retNode.NumOpnds() != 0) { - opnd = cgFunc.HandleExpr(retNode, *retNode.Opnd(0)); + if (!cgFunc.GetFunction().StructReturnedInRegs()) { + opnd = cgFunc.HandleExpr(retNode, *retNode.Opnd(0)); + } else { + cgFunc.SelectReturnSendOfStructInRegs(retNode.Opnd(0)); + } } cgFunc.SelectReturn(opnd); cgFunc.SetCurBBKind(BB::kBBReturn); @@ -1562,14 +1566,15 @@ void CGFunc::CreateLmbcFormalParamInfo() { uint32 offset; uint32 typeSize; MIRFunction &func = GetFunction(); - if (func.GetParamSize() > 0) { + if (func.GetFormalCount() > 0) { + /* Whenever lmbc cannot delete call type info, the prototype is available */ uint32 stackOffset = 0; - for (size_t idx = 0; idx < func.GetParamSize(); ++idx) { + for (size_t idx = 0; idx < func.GetFormalCount(); ++idx) { MIRSymbol *sym = func.GetFormal(idx); MIRType *type; TyIdx tyIdx; if (sym) { - tyIdx = func.GetNthParamTyIdx(idx); + tyIdx = func.GetFormalDefVec()[idx].formalTyIdx; type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); } else { FormalDef vec = const_cast(GetBecommon().GetMIRModule().CurFunction())->GetFormalDefAt(idx); @@ -1616,6 +1621,9 @@ void CGFunc::CreateLmbcFormalParamInfo() { } IreadFPoffNode *ireadNode = static_cast(operand); primType = ireadNode->GetPrimType(); + if (ireadNode->GetOffset() < 0) { + continue; + } offset = static_cast(ireadNode->GetOffset()); typeSize = GetPrimTypeSize(primType); CHECK_FATAL((offset % k8ByteSize) == 0, ""); /* scalar only, no struct for now */ @@ -1627,6 +1635,31 @@ void CGFunc::CreateLmbcFormalParamInfo() { [] (LmbcFormalParamInfo *x, LmbcFormalParamInfo *y) { return x->GetOffset() < y->GetOffset(); } ); + + /* When a scalar param address is taken, its regassign is not in the 1st block */ + for (StmtNode *stmt = func.GetBody()->GetFirst(); stmt != nullptr; stmt = stmt->GetNext()) { + if (stmt == nullptr) { + break; + } + if (stmt->GetOpCode() == OP_label) { + continue; + } + if (stmt->GetOpCode() != OP_regassign) { + break; + } + RegassignNode *regAssignNode = static_cast(stmt); + BaseNode *operand = regAssignNode->Opnd(0); + if (operand->GetOpCode() != OP_ireadfpoff) { + break; + } + IreadFPoffNode *ireadNode = static_cast(operand); + if (ireadNode->GetOffset() < 0) { + continue; + } + LmbcFormalParamInfo *info = GetLmbcFormalParamInfo(ireadNode->GetOffset()); + info->SetHasRegassign(); + } + AssignLmbcFormalParams(); } @@ -1635,7 +1668,7 @@ void CGFunc::GenerateInstruction() { InitHandleStmtFactory(); StmtNode *secondStmt = HandleFirstStmt(); - CreateLmbcFormalParamInfo(); + //CreateLmbcFormalParamInfo(); /* First Pass: Creates the doubly-linked list of BBs (next,prev) */ volReleaseInsn = nullptr; unsigned lastSrcLoc = 0; @@ -2006,6 +2039,7 @@ void CGFunc::HandleFunction() { ASSERT(exitBBVec.size() <= 1, "there are more than one BB_return in func"); } ProcessExitBBVec(); + LmbcGenSaveSpForAlloca(); if (func.IsJava()) { GenerateCleanupCodeForExtEpilog(*cleanupBB); diff --git a/src/mapleall/maple_be/src/cg/emit.cpp b/src/mapleall/maple_be/src/cg/emit.cpp index 37112f6cfb..bde5d4d383 100644 --- a/src/mapleall/maple_be/src/cg/emit.cpp +++ b/src/mapleall/maple_be/src/cg/emit.cpp @@ -2169,6 +2169,11 @@ void Emitter::EmitGlobalVar(const MIRSymbol &globalVar) { } void Emitter::EmitGlobalVars(std::vector> &globalVars) { + if (GetCG()->IsLmbc() && GetCG()->GetGP() != nullptr) { + Emit(asmInfo->GetLocal()).Emit("\t").Emit(GetCG()->GetGP()->GetName()).Emit("\n"); + Emit(asmInfo->GetComm()).Emit("\t").Emit(GetCG()->GetGP()->GetName()); + Emit(", ").Emit(GetCG()->GetMIRModule()->GetGlobalMemSize()).Emit(", ").Emit("8\n"); + } /* load globalVars profile */ if (globalVars.empty()) { return; diff --git a/src/mapleall/maple_be/src/cg/memlayout.cpp b/src/mapleall/maple_be/src/cg/memlayout.cpp index 57e45e8a2d..1b636207c6 100644 --- a/src/mapleall/maple_be/src/cg/memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/memlayout.cpp @@ -38,7 +38,7 @@ uint32 MemLayout::FindLargestActualArea(int32 &aggCopySize) { uint32 maxCopyStackSize = 0; // Size of aggregate param stack copy requirement for (; stmt != nullptr; stmt = stmt->GetNext()) { Opcode opCode = stmt->GetOpCode(); - if (opCode < OP_call || opCode > OP_xintrinsiccallassigned) { + if ((opCode < OP_call || opCode > OP_xintrinsiccallassigned) && opCode != OP_icallproto) { continue; } if (opCode == OP_intrinsiccallwithtypeassigned || opCode == OP_intrinsiccallwithtype || @@ -54,9 +54,9 @@ uint32 MemLayout::FindLargestActualArea(int32 &aggCopySize) { * if the following check fails, most likely dex has invoke-custom etc * that is not supported yet */ - DCHECK((opCode == OP_call || opCode == OP_icall), "Not lowered to call or icall?"); + DCHECK((opCode == OP_call || opCode == OP_icall || opCode == OP_icallproto), "Not lowered to call or icall?"); int32 copySize; - uint32 size = ComputeStackSpaceRequirementForCall(*stmt, copySize, opCode == OP_icall); + uint32 size = ComputeStackSpaceRequirementForCall(*stmt, copySize, opCode == OP_icall || opCode == OP_icallproto); if (size > maxParamStackSize) { maxParamStackSize = size; } diff --git a/src/mapleall/maple_ir/include/bin_mpl_export.h b/src/mapleall/maple_ir/include/bin_mpl_export.h index 09952cb8c7..f12bec7081 100644 --- a/src/mapleall/maple_ir/include/bin_mpl_export.h +++ b/src/mapleall/maple_ir/include/bin_mpl_export.h @@ -67,8 +67,8 @@ enum : uint8 { kBinEaCgStart = 41, kBinEaStart = 42, kBinNodeBlock = 43, - kBinOpStatement = 44, - kBinOpExpression = 45, +//kBinOpStatement = 44, +//kBinOpExpression = 45, kBinReturnvals = 46, kBinTypeTabStart = 47, kBinSymStart = 48, @@ -76,14 +76,14 @@ enum : uint8 { kBinFuncIdInfoStart = 50, kBinFormalStart = 51, kBinPreg = 52, - kBinPregStart = 53, - kBinLabelStart = 54, + kBinSpecialReg = 53, + kBinLabel = 54, kBinTypenameStart = 55, kBinHeaderStart = 56, kBinAliasMapStart = 57, - kBinKindTypeViaTypename = 58, - kBinKindSymViaSymname = 59, - kBinKindFuncViaSymname = 60, +//kBinKindTypeViaTypename = 58, +//kBinKindSymViaSymname = 59, +//kBinKindFuncViaSymname = 60, kBinFunctionBodyStart = 61, kBinFormalWordsTypeTagged = 62, kBinFormalWordsRefCounted = 63, @@ -103,8 +103,7 @@ class BinaryMplExport { void Export(const std::string &fname, std::unordered_set *dumpFuncSet); void WriteNum(int64 x); void Write(uint8 b); - void OutputType(TyIdx tyIdx, bool canUseTypename); - void OutputTypeViaTypeName(TyIdx tidx) { OutputType(tidx, true); } + void OutputType(TyIdx tyIdx); void WriteFunctionBodyField(uint64 contentIdx, std::unordered_set *dumpFuncSet); void OutputConst(MIRConst *c); void OutputConstBase(const MIRConst &c); @@ -133,12 +132,11 @@ class BinaryMplExport { void OutputInfoVector(const MIRInfoVector &infoVector, const MapleVector &infoVectorIsString); void OutputFuncIdInfo(MIRFunction *func); void OutputLocalSymbol(MIRSymbol *sym); - void OutputLocalSymTab(const MIRFunction *func); - void OutputPregTab(const MIRFunction *func); - void OutputLabelTab(const MIRFunction *func); + void OutputPreg(MIRPreg *preg); + void OutputLabel(LabelIdx lidx); void OutputLocalTypeNameTab(const MIRTypeNameTable *tyNameTab); void OutputFormalsStIdx(MIRFunction *func); - void OutputFuncViaSymName(PUIdx puIdx); + void OutputFuncViaSym(PUIdx puIdx); void OutputExpression(BaseNode *e); void OutputBaseNode(const BaseNode *b); void OutputReturnValues(const CallReturnVector *retv); @@ -182,6 +180,7 @@ class BinaryMplExport { void ExpandFourBuffSize(); MIRModule &mod; + MIRFunction *curFunc = nullptr; size_t bufI = 0; std::vector buf; std::unordered_map gStrMark; @@ -190,6 +189,9 @@ class BinaryMplExport { std::unordered_map uStrMark; std::unordered_map symMark; std::unordered_map typMark; + std::unordered_map localSymMark; + std::unordered_map localPregMark; + std::unordered_map labelMark; friend class UpdateMplt; std::unordered_map callInfoMark; std::map *func2SEMap = nullptr; diff --git a/src/mapleall/maple_ir/include/bin_mpl_import.h b/src/mapleall/maple_ir/include/bin_mpl_import.h index 3697654872..ee7f909f9b 100644 --- a/src/mapleall/maple_ir/include/bin_mpl_import.h +++ b/src/mapleall/maple_ir/include/bin_mpl_import.h @@ -126,15 +126,14 @@ class BinaryMplImport { void ImportInfoVector(MIRInfoVector &infoVector, MapleVector &infoVectorIsString); void ImportLocalTypeNameTable(MIRTypeNameTable *typeNameTab); void ImportFuncIdInfo(MIRFunction *func); - void ImportLocalSymbol(MIRFunction *func); - void ImportLocalSymTab(MIRFunction *func); - void ImportPregTab(const MIRFunction *func); - void ImportLabelTab(MIRFunction *func); + MIRSymbol *ImportLocalSymbol(MIRFunction *func); + PregIdx ImportPreg(MIRFunction *func); + LabelIdx ImportLabel(MIRFunction *func); void ImportFormalsStIdx(MIRFunction *func); void ImportAliasMap(MIRFunction *func); void ImportSrcPos(SrcPosition &pos); void ImportBaseNode(Opcode &o, PrimType &typ); - PUIdx ImportFuncViaSymName(); + PUIdx ImportFuncViaSym(MIRFunction *func); BaseNode *ImportExpression(MIRFunction *func); void ImportReturnValues(MIRFunction *func, CallReturnVector *retv); BlockNode *ImportBlockNode(MIRFunction *fn); @@ -162,6 +161,9 @@ class BinaryMplImport { std::vector typTab; std::vector funcTab; std::vector symTab; + std::vector localSymTab; + std::vector localPregTab; + std::vector localLabelTab; std::vector callInfoTab; std::vector eaCgTab; std::vector methodSymbols; diff --git a/src/mapleall/maple_ir/include/ir_safe_cast_traits.def b/src/mapleall/maple_ir/include/ir_safe_cast_traits.def index 1439b49d57..14ed1a367b 100644 --- a/src/mapleall/maple_ir/include/ir_safe_cast_traits.def +++ b/src/mapleall/maple_ir/include/ir_safe_cast_traits.def @@ -224,7 +224,9 @@ REGISTER_SAFE_CAST(CallNode, from.GetOpCode() == OP_call || from.GetOpCode() == OP_virtualicallassigned || instance_of(from)); REGISTER_SAFE_CAST(IcallNode, from.GetOpCode() == OP_icall || - from.GetOpCode() == OP_icallassigned); + from.GetOpCode() == OP_icallassigned || + from.GetOpCode() == OP_icallproto || + from.GetOpCode() == OP_icallprotoassigned); REGISTER_SAFE_CAST(IntrinsiccallNode, from.GetOpCode() == OP_intrinsiccall || from.GetOpCode() == OP_intrinsiccallwithtype || from.GetOpCode() == OP_xintrinsiccall || diff --git a/src/mapleall/maple_ir/include/keywords.def b/src/mapleall/maple_ir/include/keywords.def index eddff2f80a..51a603eafa 100644 --- a/src/mapleall/maple_ir/include/keywords.def +++ b/src/mapleall/maple_ir/include/keywords.def @@ -55,7 +55,6 @@ // per-function declaration keywords KEYWORD(framesize) KEYWORD(upformalsize) - KEYWORD(outparmsize) KEYWORD(moduleid) KEYWORD(funcsize) KEYWORD(funcid) diff --git a/src/mapleall/maple_ir/include/mir_builder.h b/src/mapleall/maple_ir/include/mir_builder.h index ac3215724e..64f6a2723c 100755 --- a/src/mapleall/maple_ir/include/mir_builder.h +++ b/src/mapleall/maple_ir/include/mir_builder.h @@ -262,6 +262,8 @@ class MIRBuilder { IcallNode *CreateStmtIcall(const MapleVector &args); IcallNode *CreateStmtIcallAssigned(const MapleVector &args, const MIRSymbol &ret); + IcallNode *CreateStmtIcallproto(const MapleVector &args); + IcallNode *CreateStmtIcallprotoAssigned(const MapleVector &args, const MIRSymbol &ret); // For Call, VirtualCall, SuperclassCall, InterfaceCall IntrinsiccallNode *CreateStmtIntrinsicCall(MIRIntrinsicID idx, const MapleVector &arguments, TyIdx tyIdx = TyIdx()); diff --git a/src/mapleall/maple_ir/include/mir_function.h b/src/mapleall/maple_ir/include/mir_function.h index 53ea78d1f3..259eb8fc40 100644 --- a/src/mapleall/maple_ir/include/mir_function.h +++ b/src/mapleall/maple_ir/include/mir_function.h @@ -827,24 +827,24 @@ class MIRFunction { callTimes = times; } - uint16 GetFrameSize() const { + uint32 GetFrameSize() const { return frameSize; } - void SetFrameSize(uint16 size) { + void SetFrameSize(uint32 size) { frameSize = size; } - uint16 GetUpFormalSize() const { + uint32 GetUpFormalSize() const { return upFormalSize; } - void SetUpFormalSize(uint16 size) { + void SetUpFormalSize(uint32 size) { upFormalSize = size; } - uint16 GetOutParmSize() const { + uint32 GetOutParmSize() const { return outParmSize; } - void SetOutParmSize(uint16 size) { + void SetOutParmSize(uint32 size) { outParmSize = size; } @@ -1295,9 +1295,9 @@ class MIRFunction { bool isDirty = false; bool fromMpltInline = false; // Whether this function is imported from mplt_inline file or not. uint8_t layoutType = kLayoutUnused; - uint16 frameSize = 0; - uint16 upFormalSize = 0; - uint16 outParmSize = 0; + uint32 frameSize = 0; + uint32 upFormalSize = 0; + uint32 outParmSize = 0; uint16 moduleID = 0; uint32 funcSize = 0; // size of code in words uint32 tempCount = 0; diff --git a/src/mapleall/maple_ir/include/mir_lower.h b/src/mapleall/maple_ir/include/mir_lower.h index 332a6de89f..be479f65a6 100644 --- a/src/mapleall/maple_ir/include/mir_lower.h +++ b/src/mapleall/maple_ir/include/mir_lower.h @@ -86,6 +86,7 @@ class MIRLower { ForeachelemNode *ExpandArrayMrtForeachelemBlock(ForeachelemNode &node); BlockNode *ExpandArrayMrtBlock(BlockNode &block); void AddArrayMrtMpl(BaseNode &exp, BlockNode &newblk); + MIRFuncType *FuncTypeFromFuncPtrExpr(BaseNode *x); void SetLowerME() { lowerPhase |= kShiftLowerMe; } diff --git a/src/mapleall/maple_ir/include/mir_nodes.h b/src/mapleall/maple_ir/include/mir_nodes.h index 37c7e4225a..01e8815ac2 100755 --- a/src/mapleall/maple_ir/include/mir_nodes.h +++ b/src/mapleall/maple_ir/include/mir_nodes.h @@ -3303,7 +3303,7 @@ class CallNode : public NaryStmtNode { CallReturnVector returnValues; }; -// icall and icallproto +// icall, icallassigned, icallproto and icallprotoassigned class IcallNode : public NaryStmtNode { public: IcallNode(MapleAllocator &allocator, Opcode o) diff --git a/src/mapleall/maple_ir/include/mir_parser.h b/src/mapleall/maple_ir/include/mir_parser.h index c699b107d8..f9b3ff04d0 100755 --- a/src/mapleall/maple_ir/include/mir_parser.h +++ b/src/mapleall/maple_ir/include/mir_parser.h @@ -134,6 +134,7 @@ class MIRParser { bool ParseStmtIcall(StmtNodePtr&); bool ParseStmtIcallassigned(StmtNodePtr&); bool ParseStmtIcallproto(StmtNodePtr&); + bool ParseStmtIcallprotoassigned(StmtNodePtr&); bool ParseStmtIntrinsiccall(StmtNodePtr&, bool isAssigned); bool ParseStmtIntrinsiccall(StmtNodePtr&); bool ParseStmtIntrinsiccallassigned(StmtNodePtr&); @@ -291,7 +292,6 @@ class MIRParser { bool ParseStmtBlockForType(); bool ParseStmtBlockForFrameSize(); bool ParseStmtBlockForUpformalSize(); - bool ParseStmtBlockForOutParmSize(); bool ParseStmtBlockForModuleID(); bool ParseStmtBlockForFuncSize(); bool ParseStmtBlockForFuncID(); diff --git a/src/mapleall/maple_ir/include/mir_symbol.h b/src/mapleall/maple_ir/include/mir_symbol.h index 8d7f837cd4..1d4203b279 100644 --- a/src/mapleall/maple_ir/include/mir_symbol.h +++ b/src/mapleall/maple_ir/include/mir_symbol.h @@ -484,12 +484,11 @@ class MIRSymbol { return false; } switch (storageClass) { - case kScFormal: case kScAuto: return true; case kScPstatic: case kScFstatic: - return value.konst == nullptr; + return value.konst == nullptr && !hasPotentialAssignment; default: return false; } @@ -637,7 +636,8 @@ class MIRLabelTable { LabelIdx CreateLabel() { LabelIdx labelIdx = labelTable.size(); - labelTable.push_back(GStrIdx(0)); // insert dummy global string index for anonymous label + GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(std::to_string(labelIdx)); + labelTable.push_back(strIdx); return labelIdx; } diff --git a/src/mapleall/maple_ir/include/mir_type.h b/src/mapleall/maple_ir/include/mir_type.h index d6d32d999b..83585981e9 100644 --- a/src/mapleall/maple_ir/include/mir_type.h +++ b/src/mapleall/maple_ir/include/mir_type.h @@ -1189,14 +1189,6 @@ class MIRStructType : public MIRType { isImported = flag; } - bool IsUsed() const { - return isUsed; - } - - void SetIsUsed(bool flag) { - isUsed = flag; - } - bool IsCPlusPlus() const { return isCPlusPlus; } @@ -1368,7 +1360,6 @@ class MIRStructType : public MIRType { vTableMethods.clear(); iTableMethods.clear(); isImported = false; - isUsed = false; hasVolatileField = false; hasVolatileFieldSet = false; } @@ -1471,7 +1462,6 @@ class MIRStructType : public MIRType { // implementation functions, For interfaces, they are abstact functions. // Weak indicates the actual definition is in another module. bool isImported = false; - bool isUsed = false; bool isCPlusPlus = false; // empty struct in C++ has size 1 byte mutable bool hasVolatileField = false; // for caching computed value mutable bool hasVolatileFieldSet = false; // if true, just read hasVolatileField; @@ -1928,11 +1918,19 @@ class MIRFuncType : public MIRType { } bool IsVarargs() const { - return isVarArgs; + return funcAttrs.GetAttr(FUNCATTR_varargs); } - void SetVarArgs(bool flag) { - isVarArgs = flag; + void SetVarArgs() { + funcAttrs.SetAttr(FUNCATTR_varargs); + } + + bool FirstArgReturn() const { + return funcAttrs.GetAttr(FUNCATTR_firstarg_return); + } + + void SetFirstArgReturn() { + funcAttrs.SetAttr(FUNCATTR_firstarg_return); } const TypeAttrs &GetRetAttrs() const { @@ -1960,7 +1958,8 @@ class MIRFuncType : public MIRType { std::vector paramTypeList; std::vector paramAttrsList; TypeAttrs retAttrs; - bool isVarArgs = false; + public: + FuncAttrs funcAttrs; }; class MIRTypeByName : public MIRType { diff --git a/src/mapleall/maple_ir/include/opcode_info.h b/src/mapleall/maple_ir/include/opcode_info.h index 814f15b2f2..5a82646b11 100644 --- a/src/mapleall/maple_ir/include/opcode_info.h +++ b/src/mapleall/maple_ir/include/opcode_info.h @@ -117,6 +117,7 @@ class OpcodeTable { bool IsICall(Opcode o) const { ASSERT(o < OP_last, "invalid opcode"); return o == OP_icall || o == OP_icallassigned || + o == OP_icallproto || o == OP_icallprotoassigned || o == OP_virtualicall || o == OP_virtualicallassigned || o == OP_interfaceicall || o == OP_interfaceicallassigned; } diff --git a/src/mapleall/maple_ir/include/opcodes.def b/src/mapleall/maple_ir/include/opcodes.def index 34cfb51c8d..0e842141ed 100755 --- a/src/mapleall/maple_ir/include/opcodes.def +++ b/src/mapleall/maple_ir/include/opcodes.def @@ -221,3 +221,4 @@ OPCODE(iassignspoff, IassignFPoffNode, OPCODEISSTMT, 8) OPCODE(blkassignoff, BlkassignoffNode, OPCODEISSTMT, 8) OPCODE(icallproto, IcallNode, (OPCODEISSTMT | OPCODEISVARSIZE | OPCODEHASSSAUSE | OPCODEHASSSADEF | OPCODEISCALL), 8) + OPCODE(icallprotoassigned, IcallNode, (OPCODEISSTMT | OPCODEISVARSIZE | OPCODEHASSSAUSE | OPCODEHASSSADEF | OPCODEISCALL | OPCODEISCALLASSIGNED), 8) diff --git a/src/mapleall/maple_ir/include/opcodes.h b/src/mapleall/maple_ir/include/opcodes.h index ea4ed2c1c9..b9f5e0f8c5 100644 --- a/src/mapleall/maple_ir/include/opcodes.h +++ b/src/mapleall/maple_ir/include/opcodes.h @@ -50,7 +50,7 @@ inline constexpr bool IsCallAssigned(Opcode code) { code == OP_virtualicallassigned || code == OP_superclasscallassigned || code == OP_interfacecallassigned || code == OP_interfaceicallassigned || code == OP_customcallassigned || code == OP_polymorphiccallassigned || - code == OP_icallassigned || code == OP_intrinsiccallassigned || + code == OP_icallassigned || code == OP_icallprotoassigned || code == OP_intrinsiccallassigned || code == OP_xintrinsiccallassigned || code == OP_intrinsiccallwithtypeassigned); } @@ -113,6 +113,8 @@ constexpr bool IsStmtMustRequire(Opcode opcode) { case OP_polymorphiccallassigned: case OP_icall: case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: case OP_intrinsiccall: case OP_xintrinsiccall: case OP_intrinsiccallassigned: diff --git a/src/mapleall/maple_ir/src/bin_func_export.cpp b/src/mapleall/maple_ir/src/bin_func_export.cpp index 5117ed8ed0..6815c8151d 100644 --- a/src/mapleall/maple_ir/src/bin_func_export.cpp +++ b/src/mapleall/maple_ir/src/bin_func_export.cpp @@ -24,6 +24,10 @@ using namespace std; namespace maple { void BinaryMplExport::OutputInfoVector(const MIRInfoVector &infoVector, const MapleVector &infoVectorIsString) { + if (!mod.IsWithDbgInfo()) { + Write(0); + return; + } WriteNum(infoVector.size()); for (uint32 i = 0; i < infoVector.size(); i++) { OutputStr(infoVector[i].first); @@ -41,98 +45,73 @@ void BinaryMplExport::OutputFuncIdInfo(MIRFunction *func) { WriteNum(func->GetPuidxOrigin()); // the funcid OutputInfoVector(func->GetInfoVector(), func->InfoIsString()); if (mod.GetFlavor() == kFlavorLmbc) { - WriteNum(func->GetUpFormalSize()); WriteNum(func->GetFrameSize()); - WriteNum(func->GetOutParmSize()); } - WriteNum(~kBinFuncIdInfoStart); } void BinaryMplExport::OutputBaseNode(const BaseNode *b) { - WriteNum(b->GetOpCode()); - WriteNum(b->GetPrimType()); + Write(static_cast(b->GetOpCode())); + Write(static_cast(b->GetPrimType())); } void BinaryMplExport::OutputLocalSymbol(MIRSymbol *sym) { - if (sym == nullptr) { - WriteNum(0); + std::unordered_map::iterator it = localSymMark.find(sym); + if (it != localSymMark.end()) { + WriteNum(-(it->second)); return; } + WriteNum(kBinSymbol); - WriteNum(sym->GetStIndex()); // preserve original st index OutputStr(sym->GetNameStrIdx()); WriteNum(sym->GetSKind()); WriteNum(sym->GetStorageClass()); + size_t mark = localSymMark.size(); + localSymMark[sym] = mark; OutputTypeAttrs(sym->GetAttrs()); WriteNum(static_cast(sym->GetIsTmp())); if (sym->GetSKind() == kStVar || sym->GetSKind() == kStFunc) { OutputSrcPos(sym->GetSrcPosition()); } - OutputTypeViaTypeName(sym->GetTyIdx()); + OutputType(sym->GetTyIdx()); if (sym->GetSKind() == kStPreg) { - WriteNum(sym->GetPreg()->GetPregNo()); + OutputPreg(sym->GetPreg()); } else if (sym->GetSKind() == kStConst || sym->GetSKind() == kStVar) { OutputConst(sym->GetKonst()); } else if (sym->GetSKind() == kStFunc) { - OutputFuncViaSymName(sym->GetFunction()->GetPuidx()); - OutputTypeViaTypeName(sym->GetTyIdx()); + OutputFuncViaSym(sym->GetFunction()->GetPuidx()); } else { CHECK_FATAL(false, "should not used"); } } -void BinaryMplExport::OutputLocalSymTab(const MIRFunction *func) { - WriteNum(kBinSymStart); - uint64 outsymSizeIdx = buf.size(); - ExpandFourBuffSize(); /// size of OutSym - int32 size = 0; - - for (uint32 i = 1; i < func->GetSymTab()->GetSymbolTableSize(); i++) { - MIRSymbol *s = func->GetSymTab()->GetSymbolFromStIdx(i); - if (s->IsDeleted()) { - OutputLocalSymbol(nullptr); - } else { - OutputLocalSymbol(s); - } - size++; +void BinaryMplExport::OutputPreg(MIRPreg *preg) { + if (preg->GetPregNo() < 0) { + WriteNum(kBinSpecialReg); + Write(-preg->GetPregNo()); + return; } - - Fixup(outsymSizeIdx, size); - WriteNum(~kBinSymStart); -} - -void BinaryMplExport::OutputPregTab(const MIRFunction *func) { - WriteNum(kBinPregStart); - uint64 outRegSizeIdx = buf.size(); - ExpandFourBuffSize(); /// size of OutReg - int32 size = 0; - - for (uint32 i = 1; i < func->GetPregTab()->Size(); ++i) { - MIRPreg *mirpreg = func->GetPregTab()->PregFromPregIdx(static_cast(i)); - if (mirpreg == nullptr) { - WriteNum(0); - size++; - continue; - } - WriteNum(kBinPreg); - WriteNum(mirpreg->GetPregNo()); - TyIdx tyIdx = (mirpreg->GetMIRType() == nullptr) ? TyIdx(0) : mirpreg->GetMIRType()->GetTypeIndex(); - OutputTypeViaTypeName(tyIdx); - WriteNum(mirpreg->GetPrimType()); - size++; + std::unordered_map::iterator it = localPregMark.find(preg); + if (it != localPregMark.end()) { + WriteNum(-(it->second)); + return; } - Fixup(outRegSizeIdx, size); - WriteNum(~kBinPregStart); + WriteNum(kBinPreg); + Write(static_cast(preg->GetPrimType())); + size_t mark = localPregMark.size(); + localPregMark[preg] = mark; } -void BinaryMplExport::OutputLabelTab(const MIRFunction *func) { - WriteNum(kBinLabelStart); - WriteNum(static_cast(func->GetLabelTab()->Size()-1)); // entry 0 is skipped - for (uint32 i = 1; i < func->GetLabelTab()->Size(); i++) { - OutputStr(func->GetLabelTab()->GetLabelTable()[i]); +void BinaryMplExport::OutputLabel(LabelIdx lidx) { + std::unordered_map::iterator it = labelMark.find(lidx); + if (it != labelMark.end()) { + WriteNum(-(it->second)); + return; } - WriteNum(~kBinLabelStart); + + WriteNum(kBinLabel); + size_t mark = labelMark.size(); + labelMark[lidx] = mark; } void BinaryMplExport::OutputLocalTypeNameTab(const MIRTypeNameTable *typeNameTab) { @@ -140,18 +119,16 @@ void BinaryMplExport::OutputLocalTypeNameTab(const MIRTypeNameTable *typeNameTab WriteNum(static_cast(typeNameTab->Size())); for (std::pair it : typeNameTab->GetGStrIdxToTyIdxMap()) { OutputStr(it.first); - OutputTypeViaTypeName(it.second); + OutputType(it.second); } - WriteNum(~kBinTypenameStart); } void BinaryMplExport::OutputFormalsStIdx(MIRFunction *func) { WriteNum(kBinFormalStart); WriteNum(func->GetFormalDefVec().size()); for (FormalDef formalDef : func->GetFormalDefVec()) { - WriteNum(formalDef.formalSym->GetStIndex()); + OutputLocalSymbol(formalDef.formalSym); } - WriteNum(~kBinFormalStart); } void BinaryMplExport::OutputAliasMap(MapleMap &aliasVarMap) { @@ -160,21 +137,18 @@ void BinaryMplExport::OutputAliasMap(MapleMap &aliasVarMa for (std::pair it : aliasVarMap) { OutputStr(it.first); OutputStr(it.second.memPoolStrIdx); - OutputTypeViaTypeName(it.second.tyIdx); + OutputType(it.second.tyIdx); OutputStr(it.second.sigStrIdx); } - WriteNum(~kBinAliasMapStart); } -void BinaryMplExport::OutputFuncViaSymName(PUIdx puIdx) { +void BinaryMplExport::OutputFuncViaSym(PUIdx puIdx) { MIRFunction *func = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx()); - WriteNum(kBinKindFuncViaSymname); - OutputStr(funcSt->GetNameStrIdx()); + OutputSymbol(funcSt); } void BinaryMplExport::OutputExpression(BaseNode *e) { - WriteNum(kBinOpExpression); OutputBaseNode(e); switch (e->GetOpCode()) { // leaf @@ -190,17 +164,17 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { } case OP_addroflabel: { AddroflabelNode *lNode = static_cast(e); - WriteNum(lNode->GetOffset()); + OutputLabel(lNode->GetOffset()); return; } case OP_addroffunc: { AddroffuncNode *addrNode = static_cast(e); - OutputFuncViaSymName(addrNode->GetPUIdx()); + OutputFuncViaSym(addrNode->GetPUIdx()); return; } case OP_sizeoftype: { SizeoftypeNode *sot = static_cast(e); - OutputTypeViaTypeName(sot->GetTyIdx()); + OutputType(sot->GetTyIdx()); return; } case OP_addrof: @@ -219,24 +193,23 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { } WriteNum(stIdx.Scope()); if (stIdx.Islocal()) { - WriteNum(stIdx.Idx()); // preserve original st index + OutputLocalSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx)); } else { - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(stIdx.Idx()); - WriteNum(kBinKindSymViaSymname); - OutputStr(sym->GetNameStrIdx()); + OutputSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx)); } return; } case OP_regread: { RegreadNode *regreadNode = static_cast(e); - WriteNum(regreadNode->GetRegIdx()); + MIRPreg *preg = curFunc->GetPregTab()->PregFromPregIdx(regreadNode->GetRegIdx()); + OutputPreg(preg); return; } case OP_gcmalloc: case OP_gcpermalloc: case OP_stackmalloc: { GCMallocNode *gcNode = static_cast(e); - OutputTypeViaTypeName(gcNode->GetTyIdx()); + OutputType(gcNode->GetTyIdx()); return; } // unary @@ -245,18 +218,18 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { case OP_floor: case OP_trunc: { TypeCvtNode *typecvtNode = static_cast(e); - WriteNum(typecvtNode->FromType()); + Write(static_cast(typecvtNode->FromType())); break; } case OP_retype: { RetypeNode *retypeNode = static_cast(e); - OutputTypeViaTypeName(retypeNode->GetTyIdx()); + OutputType(retypeNode->GetTyIdx()); break; } case OP_iread: case OP_iaddrof: { IreadNode *irNode = static_cast(e); - OutputTypeViaTypeName(irNode->GetTyIdx()); + OutputType(irNode->GetTyIdx()); WriteNum(irNode->GetFieldID()); break; } @@ -274,20 +247,20 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { case OP_zext: case OP_extractbits: { ExtractbitsNode *extNode = static_cast(e); - WriteNum(extNode->GetBitsOffset()); - WriteNum(extNode->GetBitsSize()); + Write(extNode->GetBitsOffset()); + Write(extNode->GetBitsSize()); break; } case OP_depositbits: { DepositbitsNode *dbNode = static_cast(e); - WriteNum(dbNode->GetBitsOffset()); - WriteNum(dbNode->GetBitsSize()); + Write(dbNode->GetBitsOffset()); + Write(dbNode->GetBitsSize()); break; } case OP_gcmallocjarray: case OP_gcpermallocjarray: { JarrayMallocNode *gcNode = static_cast(e); - OutputTypeViaTypeName(gcNode->GetTyIdx()); + OutputType(gcNode->GetTyIdx()); break; } // binary @@ -320,13 +293,13 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { case OP_cmpl: case OP_cmp: { CompareNode *cmpNode = static_cast(e); - WriteNum(cmpNode->GetOpndType()); + Write(static_cast(cmpNode->GetOpndType())); break; } case OP_resolveinterfacefunc: case OP_resolvevirtualfunc: { ResolveFuncNode *rsNode = static_cast(e); - OutputFuncViaSymName(rsNode->GetPuIdx()); + OutputFuncViaSym(rsNode->GetPuIdx()); break; } // ternary @@ -336,8 +309,8 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { // nary case OP_array: { ArrayNode *arrNode = static_cast(e); - OutputTypeViaTypeName(arrNode->GetTyIdx()); - WriteNum(static_cast(arrNode->GetBoundsCheck())); + OutputType(arrNode->GetTyIdx()); + Write(static_cast(arrNode->GetBoundsCheck())); WriteNum(static_cast(arrNode->NumOpnds())); break; } @@ -350,7 +323,7 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { case OP_intrinsicopwithtype: { IntrinsicopNode *intrnNode = static_cast(e); WriteNum(intrnNode->GetIntrinsic()); - OutputTypeViaTypeName(intrnNode->GetTyIdx()); + OutputType(intrnNode->GetTyIdx()); WriteNum(static_cast(intrnNode->NumOpnds())); break; } @@ -365,6 +338,9 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { static SrcPosition lastOutputSrcPosition; void BinaryMplExport::OutputSrcPos(const SrcPosition &pos) { + if (!mod.IsWithDbgInfo()) { + return; + } if (pos.FileNum() == 0 || pos.LineNum() == 0) { // error case, so output 0 WriteNum(lastOutputSrcPosition.RawData()); WriteNum(lastOutputSrcPosition.LineNum()); @@ -379,9 +355,15 @@ void BinaryMplExport::OutputReturnValues(const CallReturnVector *retv) { WriteNum(kBinReturnvals); WriteNum(static_cast(retv->size())); for (uint32 i = 0; i < retv->size(); i++) { - WriteNum((*retv)[i].first.Idx()); - WriteNum((*retv)[i].second.GetFieldID()); - WriteNum((*retv)[i].second.GetPregIdx()); + RegFieldPair rfp = (*retv)[i].second; + if (rfp.IsReg()) { + MIRPreg *preg = curFunc->GetPregTab()->PregFromPregIdx(rfp.GetPregIdx()); + OutputPreg(preg); + } else { + WriteNum(0); + WriteNum((rfp.GetFieldID())); + OutputLocalSymbol(curFunc->GetLocalOrGlobalSymbol((*retv)[i].first)); + } } } @@ -397,7 +379,6 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { ExpandFourBuffSize(); // place holder, Fixup later for (StmtNode *s = block->GetFirst(); s; s = s->GetNext()) { bool doneWithOpnds = false; - WriteNum(kBinOpStatement); OutputSrcPos(s->GetSrcPos()); WriteNum(s->GetOpCode()); switch (s->GetOpCode()) { @@ -416,36 +397,35 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { } WriteNum(stIdx.Scope()); if (stIdx.Islocal()) { - WriteNum(stIdx.Idx()); // preserve original st index + OutputLocalSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx)); } else { - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(stIdx.Idx()); - WriteNum(kBinKindSymViaSymname); - OutputStr(sym->GetNameStrIdx()); + OutputSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx)); } break; } case OP_regassign: { RegassignNode *rass = static_cast(s); - WriteNum(rass->GetPrimType()); - WriteNum(rass->GetRegIdx()); + Write(static_cast(rass->GetPrimType())); + MIRPreg *preg = curFunc->GetPregTab()->PregFromPregIdx(rass->GetRegIdx()); + OutputPreg(preg); break; } case OP_iassign: { IassignNode *iass = static_cast(s); - OutputTypeViaTypeName(iass->GetTyIdx()); + OutputType(iass->GetTyIdx()); WriteNum(iass->GetFieldID()); break; } case OP_iassignoff: { IassignoffNode *iassoff = static_cast(s); - WriteNum(iassoff->GetPrimType()); + Write(static_cast(iassoff->GetPrimType())); WriteNum(iassoff->GetOffset()); break; } case OP_iassignspoff: case OP_iassignfpoff: { IassignFPoffNode *iassfpoff = static_cast(s); - WriteNum(iassfpoff->GetPrimType()); + Write(static_cast(iassfpoff->GetPrimType())); WriteNum(iassfpoff->GetOffset()); break; } @@ -465,9 +445,9 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { case OP_customcall: case OP_polymorphiccall: { CallNode *callnode = static_cast(s); - OutputFuncViaSymName(callnode->GetPUIdx()); + OutputFuncViaSym(callnode->GetPUIdx()); if (s->GetOpCode() == OP_polymorphiccall) { - OutputTypeViaTypeName(static_cast(callnode)->GetTyIdx()); + OutputType(static_cast(callnode)->GetTyIdx()); } WriteNum(static_cast(s->NumOpnds())); break; @@ -480,15 +460,15 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { case OP_interfaceicallassigned: case OP_customcallassigned: { CallNode *callnode = static_cast(s); - OutputFuncViaSymName(callnode->GetPUIdx()); + OutputFuncViaSym(callnode->GetPUIdx()); OutputReturnValues(&callnode->GetReturnVec()); WriteNum(static_cast(s->NumOpnds())); break; } case OP_polymorphiccallassigned: { CallNode *callnode = static_cast(s); - OutputFuncViaSymName(callnode->GetPUIdx()); - OutputTypeViaTypeName(callnode->GetTyIdx()); + OutputFuncViaSym(callnode->GetPUIdx()); + OutputType(callnode->GetTyIdx()); OutputReturnValues(&callnode->GetReturnVec()); WriteNum(static_cast(s->NumOpnds())); break; @@ -496,13 +476,14 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { case OP_icallproto: case OP_icall: { IcallNode *icallnode = static_cast(s); - OutputTypeViaTypeName(icallnode->GetRetTyIdx()); + OutputType(icallnode->GetRetTyIdx()); WriteNum(static_cast(s->NumOpnds())); break; } + case OP_icallprotoassigned: case OP_icallassigned: { IcallNode *icallnode = static_cast(s); - OutputTypeViaTypeName(icallnode->GetRetTyIdx()); + OutputType(icallnode->GetRetTyIdx()); OutputReturnValues(&icallnode->GetReturnVec()); WriteNum(static_cast(s->NumOpnds())); break; @@ -525,14 +506,14 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { case OP_intrinsiccallwithtype: { IntrinsiccallNode *intrnNode = static_cast(s); WriteNum(intrnNode->GetIntrinsic()); - OutputTypeViaTypeName(intrnNode->GetTyIdx()); + OutputType(intrnNode->GetTyIdx()); WriteNum(static_cast(s->NumOpnds())); break; } case OP_intrinsiccallwithtypeassigned: { IntrinsiccallNode *intrnNode = static_cast(s); WriteNum(intrnNode->GetIntrinsic()); - OutputTypeViaTypeName(intrnNode->GetTyIdx()); + OutputType(intrnNode->GetTyIdx()); OutputReturnValues(&intrnNode->GetReturnVec()); WriteNum(static_cast(s->NumOpnds())); break; @@ -567,28 +548,28 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { } case OP_label: { LabelNode *lNode = static_cast(s); - WriteNum(lNode->GetLabelIdx()); + OutputLabel(lNode->GetLabelIdx()); break; } case OP_goto: case OP_gosub: { GotoNode *gtoNode = static_cast(s); - WriteNum(gtoNode->GetOffset()); + OutputLabel(gtoNode->GetOffset()); break; } case OP_brfalse: case OP_brtrue: { CondGotoNode *cgotoNode = static_cast(s); - WriteNum(cgotoNode->GetOffset()); + OutputLabel(cgotoNode->GetOffset()); break; } case OP_switch: { SwitchNode *swNode = static_cast(s); - WriteNum(swNode->GetDefaultLabel()); + OutputLabel(swNode->GetDefaultLabel()); WriteNum(static_cast(swNode->GetSwitchTable().size())); for (CasePair cpair : swNode->GetSwitchTable()) { WriteNum(cpair.first); - WriteNum(cpair.second); + OutputLabel(cpair.second); } break; } @@ -598,14 +579,14 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { WriteNum(static_cast(rgoto->GetRangeGotoTable().size())); for (SmallCasePair cpair : rgoto->GetRangeGotoTable()) { WriteNum(cpair.first); - WriteNum(cpair.second); + OutputLabel(cpair.second); } break; } case OP_jstry: { JsTryNode *tryNode = static_cast(s); - WriteNum(tryNode->GetCatchOffset()); - WriteNum(tryNode->GetFinallyOffset()); + OutputLabel(tryNode->GetCatchOffset()); + OutputLabel(tryNode->GetFinallyOffset()); break; } case OP_cpptry: @@ -613,7 +594,7 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { TryNode *tryNode = static_cast(s); WriteNum(static_cast(tryNode->GetOffsetsCount())); for (LabelIdx lidx : tryNode->GetOffsets()) { - WriteNum(lidx); + OutputLabel(lidx); } break; } @@ -621,7 +602,7 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { CatchNode *catchNode = static_cast(s); WriteNum(static_cast(catchNode->GetExceptionTyIdxVec().size())); for (TyIdx tidx : catchNode->GetExceptionTyIdxVec()) { - OutputTypeViaTypeName(tidx); + OutputType(tidx); } break; } @@ -678,7 +659,7 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { count = asmNode->gotoLabels.size(); WriteNum(static_cast(count)); for (size_t i = 0; i < count; ++i) { - WriteNum(asmNode->gotoLabels[i]); + OutputLabel(asmNode->gotoLabels[i]); } // the inputs WriteNum(asmNode->NumOpnds()); @@ -713,6 +694,7 @@ void BinaryMplExport::WriteFunctionBodyField(uint64 contentIdx, std::unordered_s if (not2mplt) { for (MIRFunction *func : GetMIRModule().GetFunctionList()) { + curFunc = func; if (func->GetAttr(FUNCATTR_optimized)) { continue; } @@ -733,12 +715,15 @@ void BinaryMplExport::WriteFunctionBodyField(uint64 contentIdx, std::unordered_s continue; } } + localSymMark.clear(); + localSymMark[nullptr] = 0; + localPregMark.clear(); + localPregMark[nullptr] = 0; + labelMark.clear(); + labelMark[0] = 0; OutputFunction(func->GetPuidx()); CHECK_FATAL(func->GetBody() != nullptr, "WriteFunctionBodyField: no function body"); OutputFuncIdInfo(func); - OutputPregTab(func); - OutputLocalSymTab(func); - OutputLabelTab(func); OutputLocalTypeNameTab(func->GetTypeNameTab()); OutputFormalsStIdx(func); if (mod.GetFlavor() < kMmpl) { @@ -752,7 +737,6 @@ void BinaryMplExport::WriteFunctionBodyField(uint64 contentIdx, std::unordered_s Fixup(totalSizeIdx, static_cast(buf.size() - totalSizeIdx)); Fixup(outFunctionBodySizeIdx, size); - WriteNum(~kBinFunctionBodyStart); return; } } // namespace maple diff --git a/src/mapleall/maple_ir/src/bin_func_import.cpp b/src/mapleall/maple_ir/src/bin_func_import.cpp index f54a72bca1..8355bb4c58 100644 --- a/src/mapleall/maple_ir/src/bin_func_import.cpp +++ b/src/mapleall/maple_ir/src/bin_func_import.cpp @@ -47,29 +47,27 @@ void BinaryMplImport::ImportFuncIdInfo(MIRFunction *func) { func->SetPuidxOrigin(static_cast(ReadNum())); ImportInfoVector(func->GetInfoVector(), func->InfoIsString()); if (mod.GetFlavor() == kFlavorLmbc) { - func->SetUpFormalSize(static_cast(ReadNum())); func->SetFrameSize(static_cast(ReadNum())); - func->SetOutParmSize(static_cast(ReadNum())); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinFuncIdInfoStart, "pattern mismatch in ImportFuncIdInfo()"); } void BinaryMplImport::ImportBaseNode(Opcode &o, PrimType &typ) { - o = (Opcode)ReadNum(); - typ = (PrimType)ReadNum(); + o = (Opcode)Read(); + typ = (PrimType)Read(); } -void BinaryMplImport::ImportLocalSymbol(MIRFunction *func) { +MIRSymbol *BinaryMplImport::ImportLocalSymbol(MIRFunction *func) { int64 tag = ReadNum(); if (tag == 0) { - func->GetSymTab()->PushNullSymbol(); - return; + return nullptr; } + if (tag < 0) { + CHECK_FATAL(static_cast(-tag) < localSymTab.size(), "index out of bounds"); + return localSymTab.at(-tag); + } CHECK_FATAL(tag == kBinSymbol, "expecting kBinSymbol in ImportLocalSymbol()"); - auto indx = static_cast(ReadNum()); - CHECK_FATAL(indx == func->GetSymTab()->GetSymbolTableSize(), "inconsistant local stIdx"); MIRSymbol *sym = func->GetSymTab()->CreateSymbol(kScopeLocal); + localSymTab.push_back(sym); sym->SetNameStrIdx(ImportStr()); (void)func->GetSymTab()->AddToStringSymbolMap(*sym); sym->SetSKind((MIRSymKind)ReadNum()); @@ -81,66 +79,52 @@ void BinaryMplImport::ImportLocalSymbol(MIRFunction *func) { } sym->SetTyIdx(ImportType()); if (sym->GetSKind() == kStPreg) { - auto thepregno = static_cast(ReadNum()); - MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx()); - PregIdx pregidx = func->GetPregTab()->EnterPregNo(thepregno, mirType->GetPrimType(), mirType); - MIRPregTable *pregTab = func->GetPregTab(); - MIRPreg *preg = pregTab->PregFromPregIdx(pregidx); - preg->SetPrimType(mirType->GetPrimType()); + PregIdx pregidx = ImportPreg(func); + MIRPreg *preg = func->GetPregTab()->PregFromPregIdx(pregidx); sym->SetPreg(preg); } else if (sym->GetSKind() == kStConst || sym->GetSKind() == kStVar) { sym->SetKonst(ImportConst(func)); } else if (sym->GetSKind() == kStFunc) { - PUIdx puIdx = ImportFuncViaSymName(); - TyIdx tyIdx = ImportType(); - sym->SetTyIdx(tyIdx); + PUIdx puIdx = ImportFuncViaSym(func); sym->SetFunction(GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx)); } + return sym; } -void BinaryMplImport::ImportLocalSymTab(MIRFunction *func) { +PregIdx BinaryMplImport::ImportPreg(MIRFunction *func) { int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinSymStart, "kBinSymStart expected in ImportLocalSymTab()"); - int32 size = ReadInt(); - for (int64 i = 0; i < size; ++i) { - ImportLocalSymbol(func); + if (tag == 0) { + return 0; } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinSymStart, "pattern mismatch in ImportLocalSymTab()"); -} - -void BinaryMplImport::ImportPregTab(const MIRFunction *func) { - int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinPregStart, "kBinPregStart expected in ImportPregTab()"); - int32 size = ReadInt(); - for (int64 i = 0; i < size; ++i) { - int64 nextTag = ReadNum(); - if (nextTag == 0) { - func->GetPregTab()->GetPregTable().push_back(nullptr); - continue; - } - CHECK_FATAL(nextTag == kBinPreg, "expecting kBinPreg in ImportPregTab()"); - auto pregNo = static_cast(ReadNum()); - TyIdx tyIdx = ImportType(); - MIRType *ty = (tyIdx == 0) ? nullptr : GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); - PrimType primType = (PrimType)ReadNum(); - CHECK_FATAL(ty == nullptr || primType == ty->GetPrimType(), "ImportPregTab: inconsistent primitive type"); - (void)func->GetPregTab()->EnterPregNo(pregNo, primType, ty); + if (tag == kBinSpecialReg) { + return -Read(); + } + if (tag < 0) { + CHECK_FATAL(static_cast(-tag) < localPregTab.size(), "index out of bounds"); + return localPregTab.at(-tag); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinPregStart, "pattern mismatch in ImportPregTab()"); + CHECK_FATAL(tag == kBinPreg, "expecting kBinPreg in ImportPreg()"); + + PrimType primType = (PrimType)Read(); + PregIdx pidx = func->GetPregTab()->CreatePreg(primType); + localPregTab.push_back(pidx); + return pidx; } -void BinaryMplImport::ImportLabelTab(MIRFunction *func) { +LabelIdx BinaryMplImport::ImportLabel(MIRFunction *func) { int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinLabelStart, "kBinLabelStart expected in ImportLabelTab()"); - int64 size = ReadNum(); - for (int64 i = 0; i < size; ++i) { - GStrIdx gStrIdx = ImportStr(); - (void)func->GetLabelTab()->AddLabel(gStrIdx); + if (tag == 0) { + return 0; + } + if (tag < 0) { + CHECK_FATAL(static_cast(-tag) < localLabelTab.size(), "index out of bounds"); + return localLabelTab.at(-tag); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinLabelStart, "pattern mismatch in ImportLabelTab()"); + CHECK_FATAL(tag == kBinLabel, "kBinLabel expected in ImportLabel()"); + + LabelIdx lidx = func->GetLabelTab()->CreateLabel(); + localLabelTab.push_back(lidx); + return lidx; } void BinaryMplImport::ImportLocalTypeNameTable(MIRTypeNameTable *typeNameTab) { @@ -152,8 +136,6 @@ void BinaryMplImport::ImportLocalTypeNameTable(MIRTypeNameTable *typeNameTab) { TyIdx tyIdx = ImportType(); typeNameTab->SetGStrIdxToTyIdx(strIdx, tyIdx); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinTypenameStart, "pattern mismatch in ImportTypenametab()"); } void BinaryMplImport::ImportFormalsStIdx(MIRFunction *func) { @@ -161,11 +143,8 @@ void BinaryMplImport::ImportFormalsStIdx(MIRFunction *func) { CHECK_FATAL(tag == kBinFormalStart, "kBinFormalStart expected in ImportFormalsStIdx()"); auto size = ReadNum(); for (int64 i = 0; i < size; ++i) { - uint32 indx = static_cast(ReadNum()); - func->GetFormalDefVec()[static_cast(i)].formalSym = func->GetSymTab()->GetSymbolFromStIdx(indx); + func->GetFormalDefVec()[static_cast(i)].formalSym = ImportLocalSymbol(func); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinFormalStart, "pattern mismatch in ImportFormalsStIdx()"); } void BinaryMplImport::ImportAliasMap(MIRFunction *func) { @@ -180,22 +159,15 @@ void BinaryMplImport::ImportAliasMap(MIRFunction *func) { (void)ImportStr(); // not assigning to mimic parser func->GetAliasVarMap()[strIdx] = aliasvars; } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinAliasMapStart, "pattern mismatch in ImportAliasMap()"); } -PUIdx BinaryMplImport::ImportFuncViaSymName() { - int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinKindFuncViaSymname, "kBinKindFuncViaSymname expected"); - GStrIdx strIdx = ImportStr(); - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx); - MIRFunction *func = sym->GetFunction(); - return func->GetPuidx(); +PUIdx BinaryMplImport::ImportFuncViaSym(MIRFunction *func) { + MIRSymbol *sym = InSymbol(func); + MIRFunction *f = sym->GetFunction(); + return f->GetPuidx(); } BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { - int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinOpExpression, "kBinOpExpression expected"); Opcode op; PrimType typ; ImportBaseNode(op, typ); @@ -215,13 +187,15 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { } case OP_addroflabel: { AddroflabelNode *alabNode = mod.CurFuncCodeMemPool()->New(); - alabNode->SetOffset(static_cast(ReadNum())); + alabNode->SetOffset(ImportLabel(func)); alabNode->SetPrimType(typ); (void)func->GetLabelTab()->addrTakenLabels.insert(alabNode->GetOffset()); return alabNode; } case OP_addroffunc: { - PUIdx puIdx = ImportFuncViaSymName(); + PUIdx puIdx = ImportFuncViaSym(func); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFuncTable()[puIdx]; + f->GetFuncSymbol()->SetAppearsInCode(true); AddroffuncNode *addrNode = mod.CurFuncCodeMemPool()->New(typ, puIdx); return addrNode; } @@ -237,18 +211,18 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { int32 num = static_cast(ReadNum()); StIdx stIdx; stIdx.SetScope(static_cast(ReadNum())); + MIRSymbol *sym = nullptr; if (stIdx.Islocal()) { - stIdx.SetIdx(static_cast(ReadNum())); + sym = ImportLocalSymbol(func); + CHECK_FATAL(sym != nullptr, "null ptr check"); } else { - int32 stag = static_cast(ReadNum()); - CHECK_FATAL(stag == kBinKindSymViaSymname, "kBinKindSymViaSymname expected"); - GStrIdx strIdx = ImportStr(); - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx); + sym = InSymbol(func); + CHECK_FATAL(sym != nullptr, "null ptr check"); if (op == OP_addrof) { sym->SetHasPotentialAssignment(); } - stIdx.SetIdx(sym->GetStIdx().Idx()); } + stIdx.SetIdx(sym->GetStIdx().Idx()); if (op == OP_addrof || op == OP_dread) { AddrofNode *drNode = mod.CurFuncCodeMemPool()->New(op); drNode->SetPrimType(typ); @@ -265,7 +239,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { } case OP_regread: { RegreadNode *regreadNode = mod.CurFuncCodeMemPool()->New(); - regreadNode->SetRegIdx(static_cast(ReadNum())); + regreadNode->SetRegIdx(ImportPreg(func)); regreadNode->SetPrimType(typ); return regreadNode; } @@ -294,7 +268,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_floor: case OP_trunc: { TypeCvtNode *typecvtNode = mod.CurFuncCodeMemPool()->New(op, typ); - typecvtNode->SetFromType((PrimType)ReadNum()); + typecvtNode->SetFromType((PrimType)Read()); typecvtNode->SetOpnd(ImportExpression(func), 0); return typecvtNode; } @@ -327,15 +301,15 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_zext: case OP_extractbits: { ExtractbitsNode *extNode = mod.CurFuncCodeMemPool()->New(op, typ); - extNode->SetBitsOffset(static_cast(ReadNum())); - extNode->SetBitsSize(static_cast(ReadNum())); + extNode->SetBitsOffset(Read()); + extNode->SetBitsSize(Read()); extNode->SetOpnd(ImportExpression(func), 0); return extNode; } case OP_depositbits: { DepositbitsNode *dbNode = mod.CurFuncCodeMemPool()->New(op, typ); - dbNode->SetBitsOffset(static_cast(ReadNum())); - dbNode->SetBitsSize(static_cast(ReadNum())); + dbNode->SetBitsOffset(ReadNum()); + dbNode->SetBitsSize(ReadNum()); dbNode->SetOpnd(ImportExpression(func), 0); dbNode->SetOpnd(ImportExpression(func), 1); return dbNode; @@ -380,7 +354,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_cmpl: case OP_cmp: { CompareNode *cmpNode = mod.CurFuncCodeMemPool()->New(op, typ); - cmpNode->SetOpndType((PrimType)ReadNum()); + cmpNode->SetOpndType((PrimType)Read()); cmpNode->SetOpnd(ImportExpression(func), 0); cmpNode->SetOpnd(ImportExpression(func), 1); return cmpNode; @@ -388,7 +362,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_resolveinterfacefunc: case OP_resolvevirtualfunc: { ResolveFuncNode *rsNode = mod.CurFuncCodeMemPool()->New(op, typ); - rsNode->SetPUIdx(ImportFuncViaSymName()); + rsNode->SetPUIdx(ImportFuncViaSym(func)); rsNode->SetOpnd(ImportExpression(func), 0); rsNode->SetOpnd(ImportExpression(func), 1); return rsNode; @@ -404,7 +378,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { // nary case OP_array: { TyIdx tidx = ImportType(); - auto boundsCheck = static_cast(ReadNum()); + bool boundsCheck = static_cast(Read()); ArrayNode *arrNode = mod.CurFuncCodeMemPool()->New(func->GetCodeMPAllocator(), typ, tidx, boundsCheck); auto n = static_cast(ReadNum()); @@ -437,12 +411,15 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { return intrnNode; } default: - CHECK_FATAL(false, "Unhandled op %d", tag); + CHECK_FATAL(false, "Unhandled op %d", op); break; } } void BinaryMplImport::ImportSrcPos(SrcPosition &pos) { + if (!mod.IsWithDbgInfo()) { + return; + } pos.SetRawData(static_cast(ReadNum())); pos.SetLineNum(static_cast(ReadNum())); } @@ -452,14 +429,16 @@ void BinaryMplImport::ImportReturnValues(MIRFunction *func, CallReturnVector *re CHECK_FATAL(tag == kBinReturnvals, "expecting return values"); auto size = static_cast(ReadNum()); for (uint32 i = 0; i < size; ++i) { - uint32 idx = static_cast(ReadNum()); - FieldID fid = static_cast(ReadNum()); - PregIdx ridx = static_cast(ReadNum()); - retv->push_back(std::make_pair(StIdx(kScopeLocal, idx), RegFieldPair(fid, ridx))); - if (idx == 0) { + RegFieldPair rfp; + rfp.SetPregIdx(ImportPreg(func)); + if (rfp.IsReg()) { + retv->push_back(std::make_pair(StIdx(), rfp)); continue; } - MIRSymbol *lsym = func->GetSymTab()->GetSymbolFromStIdx(idx, false); + rfp.SetFieldID(static_cast(ReadNum())); + MIRSymbol *lsym = ImportLocalSymbol(func); + CHECK_FATAL(lsym != nullptr, "null ptr check"); + retv->push_back(std::make_pair(lsym->GetStIdx(), rfp)); if (lsym->GetName().find("L_STR") == 0) { MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(lsym->GetTyIdx()); CHECK_FATAL(ty->GetKind() == kTypePointer, "Pointer type expected for L_STR prefix"); @@ -480,8 +459,6 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { ImportSrcPos(block->GetSrcPos()); int32 size = ReadInt(); for (int32 k = 0; k < size; ++k) { - tag = ReadNum(); - CHECK_FATAL(tag == kBinOpStatement, "kBinOpStatement expected"); SrcPosition thesrcPosition; ImportSrcPos(thesrcPosition); op = (Opcode)ReadNum(); @@ -496,16 +473,16 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { int32 num = static_cast(ReadNum()); StIdx stIdx; stIdx.SetScope(static_cast(ReadNum())); + MIRSymbol *sym = nullptr; if (stIdx.Islocal()) { - stIdx.SetIdx(static_cast(ReadNum())); + sym = ImportLocalSymbol(func); + CHECK_FATAL(sym != nullptr, "null ptr check"); } else { - int32 stag = static_cast(ReadNum()); - CHECK_FATAL(stag == kBinKindSymViaSymname, "kBinKindSymViaSymname expected"); - GStrIdx strIdx = ImportStr(); - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx); + sym = InSymbol(func); + CHECK_FATAL(sym != nullptr, "null ptr check"); sym->SetHasPotentialAssignment(); - stIdx.SetIdx(sym->GetStIdx().Idx()); } + stIdx.SetIdx(sym->GetStIdx().Idx()); if (op == OP_dassign) { DassignNode *s = func->GetCodeMemPool()->New(); s->SetStIdx(stIdx); @@ -524,8 +501,8 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_regassign: { RegassignNode *s = func->GetCodeMemPool()->New(); - s->SetPrimType((PrimType)ReadNum()); - s->SetRegIdx(static_cast(ReadNum())); + s->SetPrimType((PrimType)Read()); + s->SetRegIdx(ImportPreg(func)); s->SetOpnd(ImportExpression(func), 0); stmt = s; break; @@ -541,7 +518,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_iassignoff: { IassignoffNode *s = func->GetCodeMemPool()->New(); - s->SetPrimType((PrimType)ReadNum()); + s->SetPrimType((PrimType)Read()); s->SetOffset(static_cast(ReadNum())); s->SetOpnd(ImportExpression(func), 0); s->SetOpnd(ImportExpression(func), 1); @@ -551,7 +528,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { case OP_iassignspoff: case OP_iassignfpoff: { IassignFPoffNode *s = func->GetCodeMemPool()->New(op); - s->SetPrimType((PrimType)ReadNum()); + s->SetPrimType((PrimType)Read()); s->SetOffset(static_cast(ReadNum())); s->SetOpnd(ImportExpression(func), 0); stmt = s; @@ -576,7 +553,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { case OP_interfaceicall: case OP_customcall: { CallNode *s = func->GetCodeMemPool()->New(mod, op); - s->SetPUIdx(ImportFuncViaSymName()); + s->SetPUIdx(ImportFuncViaSym(func)); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx()); + f->GetFuncSymbol()->SetAppearsInCode(true); numOpr = static_cast(ReadNum()); s->SetNumOpnds(numOpr); for (int32 i = 0; i < numOpr; ++i) { @@ -593,7 +572,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { case OP_interfaceicallassigned: case OP_customcallassigned: { CallNode *s = func->GetCodeMemPool()->New(mod, op); - s->SetPUIdx(ImportFuncViaSymName()); + s->SetPUIdx(ImportFuncViaSym(func)); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx()); + f->GetFuncSymbol()->SetAppearsInCode(true); ImportReturnValues(func, &s->GetReturnVec()); numOpr = static_cast(ReadNum()); s->SetNumOpnds(numOpr); @@ -609,7 +590,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_polymorphiccall: { CallNode *s = func->GetCodeMemPool()->New(mod, op); - s->SetPUIdx(ImportFuncViaSymName()); + s->SetPUIdx(ImportFuncViaSym(func)); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx()); + f->GetFuncSymbol()->SetAppearsInCode(true); s->SetTyIdx(ImportType()); numOpr = static_cast(ReadNum()); s->SetNumOpnds(numOpr); @@ -621,7 +604,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_polymorphiccallassigned: { CallNode *s = func->GetCodeMemPool()->New(mod, op); - s->SetPUIdx(ImportFuncViaSymName()); + s->SetPUIdx(ImportFuncViaSym(func)); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx()); + f->GetFuncSymbol()->SetAppearsInCode(true); s->SetTyIdx(ImportType()); ImportReturnValues(func, &s->GetReturnVec()); numOpr = static_cast(ReadNum()); @@ -644,6 +629,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { stmt = s; break; } + case OP_icallprotoassigned: case OP_icallassigned: { IcallNode *s = func->GetCodeMemPool()->New(mod, op); s->SetRetTyIdx(ImportType()); @@ -758,32 +744,32 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_label: { LabelNode *s = mod.CurFuncCodeMemPool()->New(); - s->SetLabelIdx(static_cast(ReadNum())); + s->SetLabelIdx(ImportLabel(func)); stmt = s; break; } case OP_goto: case OP_gosub: { GotoNode *s = mod.CurFuncCodeMemPool()->New(op); - s->SetOffset(static_cast(ReadNum())); + s->SetOffset(ImportLabel(func)); stmt = s; break; } case OP_brfalse: case OP_brtrue: { CondGotoNode *s = mod.CurFuncCodeMemPool()->New(op); - s->SetOffset(static_cast(ReadNum())); + s->SetOffset(ImportLabel(func)); s->SetOpnd(ImportExpression(func), 0); stmt = s; break; } case OP_switch: { SwitchNode *s = mod.CurFuncCodeMemPool()->New(mod); - s->SetDefaultLabel(static_cast(ReadNum())); + s->SetDefaultLabel(ImportLabel(func)); auto tagSize = static_cast(ReadNum()); for (uint32 i = 0; i < tagSize; ++i) { int64 casetag = ReadNum(); - LabelIdx lidx(ReadNum()); + LabelIdx lidx = ImportLabel(func); CasePair cpair = std::make_pair(casetag, lidx); s->GetSwitchTable().push_back(cpair); } @@ -797,7 +783,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { uint32 tagSize = static_cast(ReadNum()); for (uint32 i = 0; i < tagSize; ++i) { uint16 casetag = static_cast(ReadNum()); - LabelIdx lidx(ReadNum()); + LabelIdx lidx = ImportLabel(func); s->AddRangeGoto(casetag, lidx); } s->SetOpnd(ImportExpression(func), 0); @@ -806,8 +792,8 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_jstry: { JsTryNode *s = mod.CurFuncCodeMemPool()->New(); - s->SetCatchOffset(static_cast(ReadNum())); - s->SetFinallyOffset(static_cast(ReadNum())); + s->SetCatchOffset(ImportLabel(func)); + s->SetFinallyOffset(ImportLabel(func)); stmt = s; break; } @@ -816,7 +802,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { TryNode *s = mod.CurFuncCodeMemPool()->New(mod); auto numLabels = static_cast(ReadNum()); for (uint32 i = 0; i < numLabels; ++i) { - s->GetOffsets().push_back(ReadNum()); + s->GetOffsets().push_back(ImportLabel(func)); } stmt = s; break; @@ -886,7 +872,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { // the labels count = static_cast(ReadNum()); for (size_t i = 0; i < count; ++i) { - auto lidx = static_cast(ReadNum()); + LabelIdx lidx = ImportLabel(func); s->gotoLabels.push_back(lidx); } // the inputs @@ -926,6 +912,13 @@ void BinaryMplImport::ReadFunctionBodyField() { PUIdx puIdx = ImportFunction(); MIRFunction *fn = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); mod.SetCurFunction(fn); + fn->GetFuncSymbol()->SetAppearsInCode(true); + localSymTab.clear(); + localSymTab.push_back(nullptr); + localPregTab.clear(); + localPregTab.push_back(0); + localLabelTab.clear(); + localLabelTab.push_back(0); fn->AllocSymTab(); fn->AllocPregTab(); @@ -933,9 +926,6 @@ void BinaryMplImport::ReadFunctionBodyField() { fn->AllocLabelTab(); ImportFuncIdInfo(fn); - ImportPregTab(fn); - ImportLocalSymTab(fn); - ImportLabelTab(fn); ImportLocalTypeNameTable(fn->GetTypeNameTab()); ImportFormalsStIdx(fn); if (mod.GetFlavor() < kMmpl) { @@ -944,8 +934,6 @@ void BinaryMplImport::ReadFunctionBodyField() { (void)ImportBlockNode(fn); mod.AddFunction(fn); } - int64 tag = ReadNum(); - CHECK_FATAL(tag == ~kBinFunctionBodyStart, "pattern mismatch in Read FunctionBody"); return; } } // namespace maple diff --git a/src/mapleall/maple_ir/src/bin_mpl_export.cpp b/src/mapleall/maple_ir/src/bin_mpl_export.cpp index 879e34074d..e777db2ba6 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_export.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_export.cpp @@ -26,7 +26,7 @@ namespace { using namespace maple; using OutputConstFactory = FunctionFactory; -using OutputTypeFactory = FunctionFactory; +using OutputTypeFactory = FunctionFactory; void OutputConstInt(const MIRConst &constVal, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindConstInt); @@ -62,7 +62,7 @@ void OutputConstLbl(const MIRConst &constVal, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindConstAddrofLabel); mplExport.OutputConstBase(constVal); const MIRLblConst &lblConst = static_cast(constVal); - mplExport.WriteNum(lblConst.GetValue()); // LabelIdx not needed to output puIdx + mplExport.OutputLabel(lblConst.GetValue()); } void OutputConstStr(const MIRConst &constVal, BinaryMplExport &mplExport) { @@ -141,39 +141,39 @@ static bool InitOutputConstFactory() { return true; } -void OutputTypeScalar(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeScalar(const MIRType &ty, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindTypeScalar); mplExport.OutputTypeBase(ty); } -void OutputTypePointer(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypePointer(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypePointer); mplExport.OutputTypeBase(type); mplExport.OutputTypeAttrs(type.GetTypeAttrs()); - mplExport.OutputType(type.GetPointedTyIdx(), canUseTypename); + mplExport.OutputType(type.GetPointedTyIdx()); } -void OutputTypeByName(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeByName(const MIRType &ty, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindTypeByName); mplExport.OutputTypeBase(ty); } -void OutputTypeFArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeFArray(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeFArray); mplExport.OutputTypeBase(type); - mplExport.OutputType(type.GetElemTyIdx(), canUseTypename); + mplExport.OutputType(type.GetElemTyIdx()); } -void OutputTypeJArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeJArray(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeJarray); mplExport.OutputTypeBase(type); - mplExport.OutputType(type.GetElemTyIdx(), canUseTypename); + mplExport.OutputType(type.GetElemTyIdx()); } -void OutputTypeArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeArray(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeArray); mplExport.OutputTypeBase(type); @@ -181,20 +181,20 @@ void OutputTypeArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseT for (uint16 i = 0; i < type.GetDim(); ++i) { mplExport.WriteNum(type.GetSizeArrayItem(i)); } - mplExport.OutputType(type.GetElemTyIdx(), canUseTypename); + mplExport.OutputType(type.GetElemTyIdx()); mplExport.OutputTypeAttrs(type.GetTypeAttrs()); } -void OutputTypeFunction(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeFunction(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeFunction); mplExport.OutputTypeBase(type); - mplExport.OutputType(type.GetRetTyIdx(), canUseTypename); - mplExport.WriteNum(type.IsVarargs()); + mplExport.OutputType(type.GetRetTyIdx()); + mplExport.WriteNum(type.funcAttrs.GetAttrFlag()); size_t size = type.GetParamTypeList().size(); mplExport.WriteNum(size); for (size_t i = 0; i < size; ++i) { - mplExport.OutputType(type.GetNthParamType(i), canUseTypename); + mplExport.OutputType(type.GetNthParamType(i)); } size = type.GetParamAttrsList().size(); mplExport.WriteNum(size); @@ -203,13 +203,13 @@ void OutputTypeFunction(const MIRType &ty, BinaryMplExport &mplExport, bool canU } } -void OutputTypeParam(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeParam(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeParam); mplExport.OutputTypeBase(type); } -void OutputTypeInstantVector(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeInstantVector(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeInstantVector); mplExport.OutputTypeBase(type); @@ -217,15 +217,15 @@ void OutputTypeInstantVector(const MIRType &ty, BinaryMplExport &mplExport, bool mplExport.OutputTypePairs(type); } -void OutputTypeGenericInstant(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeGenericInstant(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeGenericInstant); mplExport.OutputTypeBase(type); mplExport.OutputTypePairs(type); - mplExport.OutputType(type.GetGenericTyIdx(), canUseTypename); + mplExport.OutputType(type.GetGenericTyIdx()); } -void OutputTypeBitField(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeBitField(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeBitField); mplExport.OutputTypeBase(type); @@ -233,7 +233,7 @@ void OutputTypeBitField(const MIRType &ty, BinaryMplExport &mplExport, bool) { } // for Struct/StructIncomplete/Union -void OutputTypeStruct(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeStruct(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeStruct); mplExport.OutputTypeBase(type); @@ -249,7 +249,7 @@ void OutputTypeStruct(const MIRType &ty, BinaryMplExport &mplExport, bool) { } } -void OutputTypeClass(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeClass(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeClass); mplExport.OutputTypeBase(type); @@ -264,7 +264,7 @@ void OutputTypeClass(const MIRType &ty, BinaryMplExport &mplExport, bool) { } } -void OutputTypeInterface(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeInterface(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeInterface); mplExport.OutputTypeBase(type); @@ -279,7 +279,7 @@ void OutputTypeInterface(const MIRType &ty, BinaryMplExport &mplExport, bool) { } } -void OutputTypeConstString(const MIRType &ty, BinaryMplExport&, bool) { +void OutputTypeConstString(const MIRType &ty, BinaryMplExport&) { ASSERT(false, "Type's kind not yet implemented: %d", ty.GetKind()); (void)ty; } @@ -397,7 +397,7 @@ void BinaryMplExport::DumpBuf(const std::string &name) { void BinaryMplExport::OutputConstBase(const MIRConst &constVal) { WriteNum(constVal.GetKind()); - OutputTypeViaTypeName(constVal.GetType().GetTypeIndex()); + OutputType(constVal.GetType().GetTypeIndex()); } void BinaryMplExport::OutputConst(MIRConst *constVal) { @@ -470,8 +470,8 @@ void BinaryMplExport::OutputPragma(const MIRPragma &p) { WriteNum(p.GetKind()); WriteNum(p.GetVisibility()); OutputStr(p.GetStrIdx()); - OutputType(p.GetTyIdx(), false); - OutputType(p.GetTyIdxEx(), false); + OutputType(p.GetTyIdx()); + OutputType(p.GetTyIdxEx()); WriteNum(p.GetParamNum()); size_t size = p.GetElementVector().size(); WriteNum(size); @@ -488,7 +488,7 @@ void BinaryMplExport::OutputTypeBase(const MIRType &type) { void BinaryMplExport::OutputFieldPair(const FieldPair &fp) { OutputStr(fp.first); // GStrIdx - OutputType(fp.second.first, false); // TyIdx + OutputType(fp.second.first); // TyIdx FieldAttrs fa = fp.second.second; WriteNum(fa.GetAttrFlag()); WriteNum(fa.GetAlignValue()); @@ -511,7 +511,7 @@ void BinaryMplExport::OutputMethodPair(const MethodPair &memPool) { MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(memPool.first.Idx()); CHECK_FATAL(funcSt != nullptr, "Pointer funcSt is nullptr, can't get symbol! Check it!"); WriteAsciiStr(GlobalTables::GetStrTable().GetStringFromStrIdx(funcSt->GetNameStrIdx())); - OutputType(memPool.second.first, false); // TyIdx + OutputType(memPool.second.first); // TyIdx WriteNum(memPool.second.second.GetAttrFlag()); // FuncAttrs } @@ -539,7 +539,7 @@ void BinaryMplExport::OutputStructTypeData(const MIRStructType &type) { void BinaryMplExport::OutputImplementedInterfaces(const std::vector &interfaces) { WriteNum(interfaces.size()); for (const TyIdx &tyIdx : interfaces) { - OutputType(tyIdx, false); + OutputType(tyIdx); } } @@ -571,7 +571,7 @@ void BinaryMplExport::OutputPragmaVec(const std::vector &pragmaVec) } void BinaryMplExport::OutputClassTypeData(const MIRClassType &type) { - OutputType(type.GetParentTyIdx(), false); + OutputType(type.GetParentTyIdx()); OutputImplementedInterfaces(type.GetInterfaceImplemented()); OutputInfoIsString(type.GetInfoIsString()); if (!inIPA) { @@ -601,6 +601,7 @@ void BinaryMplExport::Init() { symMark[nullptr] = 0; funcMark[nullptr] = 0; eaNodeMark[nullptr] = 0; + curFunc = nullptr; for (uint32 pti = static_cast(PTY_begin); pti < static_cast(PTY_end); ++pti) { typMark[GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(pti))] = pti; } @@ -612,7 +613,7 @@ void BinaryMplExport::OutputSymbol(MIRSymbol *sym) { return; } - auto it = symMark.find(sym); + std::unordered_map::iterator it = symMark.find(sym); if (it != symMark.end()) { WriteNum(-(it->second)); return; @@ -645,7 +646,7 @@ void BinaryMplExport::OutputSymbol(MIRSymbol *sym) { if (sym->GetSKind() == kStVar || sym->GetSKind() == kStFunc) { OutputSrcPos(sym->GetSrcPosition()); } - OutputTypeViaTypeName(sym->GetTyIdx()); + OutputType(sym->GetTyIdx()); } void BinaryMplExport::OutputFunction(PUIdx puIdx) { @@ -671,7 +672,7 @@ void BinaryMplExport::OutputFunction(PUIdx puIdx) { MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx()); CHECK_FATAL(funcSt != nullptr, "Pointer funcSt is nullptr, cannot get symbol! Check it!"); OutputSymbol(funcSt); - OutputTypeViaTypeName(func->GetMIRFuncType()->GetTypeIndex()); + OutputType(func->GetMIRFuncType()->GetTypeIndex()); WriteNum(func->GetFuncAttrs().GetAttrFlag()); auto &attributes = func->GetFuncAttrs(); @@ -684,12 +685,12 @@ void BinaryMplExport::OutputFunction(PUIdx puIdx) { } WriteNum(func->GetFlag()); - OutputTypeViaTypeName(func->GetClassTyIdx()); + OutputType(func->GetClassTyIdx()); // output formal parameter information WriteNum(static_cast(func->GetFormalDefVec().size())); for (FormalDef formalDef : func->GetFormalDefVec()) { OutputStr(formalDef.formalStrIdx); - OutputType(formalDef.formalTyIdx, false); + OutputType(formalDef.formalTyIdx); WriteNum(static_cast(formalDef.formalAttrs.GetAttrFlag())); } // store Side Effect for each func @@ -751,15 +752,20 @@ void BinaryMplExport::WriteHeaderField(uint64 contentIdx) { WriteNum(mod.GetID()); if (mod.GetFlavor() == kFlavorLmbc) { WriteNum(mod.GetGlobalMemSize()); + WriteNum(mod.IsWithDbgInfo()); } WriteNum(mod.GetNumFuncs()); WriteAsciiStr(mod.GetEntryFuncName()); OutputInfoVector(mod.GetFileInfo(), mod.GetFileInfoIsString()); - WriteNum(static_cast(mod.GetSrcFileInfo().size())); - for (uint32 i = 0; i < mod.GetSrcFileInfo().size(); i++) { - OutputStr(mod.GetSrcFileInfo()[i].first); - WriteNum(mod.GetSrcFileInfo()[i].second); + if (mod.IsWithDbgInfo()) { + WriteNum(static_cast(mod.GetSrcFileInfo().size())); + for (uint32 i = 0; i < mod.GetSrcFileInfo().size(); i++) { + OutputStr(mod.GetSrcFileInfo()[i].first); + WriteNum(mod.GetSrcFileInfo()[i].second); + } + } else { + Write(0); } WriteNum(static_cast(mod.GetImportFiles().size())); @@ -795,7 +801,7 @@ void BinaryMplExport::WriteTypeField(uint64 contentIdx, bool useClassList) { auto *structType = static_cast(type); // skip imported class/interface and incomplete types if (!structType->IsImported() && !structType->IsIncomplete()) { - OutputType(curTyidx, false); + OutputType(curTyidx); ++size; } } @@ -803,7 +809,7 @@ void BinaryMplExport::WriteTypeField(uint64 contentIdx, bool useClassList) { } else { uint32 idx = GlobalTables::GetTypeTable().lastDefaultTyIdx.GetIdx(); for (idx = idx + 1; idx < GlobalTables::GetTypeTable().GetTypeTableSize(); idx++) { - OutputType(TyIdx(idx), false); + OutputType(TyIdx(idx)); size++; } } @@ -884,7 +890,7 @@ void BinaryMplExport::WriteSeField() { GlobalTables::GetGsymTable().GetSymbolFromStrIdx(GlobalTables::GetStrTable().GetStrIdxFromName(funcStr)); MIRFunction *func = (funcSymbol != nullptr) ? GetMIRModule().GetMIRBuilder()->GetFunctionFromSymbol(*funcSymbol) : nullptr; - OutputType(func->GetReturnTyIdx(), false); + OutputType(func->GetReturnTyIdx()); } ++size; } @@ -1102,7 +1108,7 @@ void BinaryMplExport::WriteSymField(uint64 contentIdx) { MIRSymKind sKind = s->GetSKind(); if (s->IsDeleted() || storageClass == kScUnused || (s->GetIsImported() && !s->GetAppearsInCode()) || - (storageClass == kScExtern && sKind == kStFunc)) { + (sKind == kStFunc && (storageClass == kScExtern || !s->GetAppearsInCode()))) { continue; } OutputSymbol(s); @@ -1213,8 +1219,6 @@ void BinaryMplExport::Export(const std::string &fname, std::unordered_setIsNameIsLocal() && ty->GetNameStrIdx() != GStrIdx(0)) { - WriteNum(kBinKindTypeViaTypename); - OutputStr(ty->GetNameStrIdx()); - return; - } - auto func = CreateProductFunction(ty->GetKind()); if (func != nullptr) { - func(*ty, *this, canUseTypename); + func(*ty, *this); } else { ASSERT(false, "Type's kind not yet implemented: %d", ty->GetKind()); } diff --git a/src/mapleall/maple_ir/src/bin_mpl_import.cpp b/src/mapleall/maple_ir/src/bin_mpl_import.cpp index 50779027df..1f79751ed6 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_import.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_import.cpp @@ -129,11 +129,13 @@ MIRConst *BinaryMplImport::ImportConst(MIRFunction *func) { } case kBinKindConstAddrofFunc: { PUIdx puIdx = ImportFunction(); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFuncTable()[puIdx]; + f->GetFuncSymbol()->SetAppearsInCode(true); mod.SetCurFunction(func); return memPool->New(puIdx, *type); } case kBinKindConstAddrofLabel: { - LabelIdx lidx = static_cast(ReadNum()); + LabelIdx lidx = ImportLabel(func); PUIdx puIdx = func->GetPuidx(); MIRLblConst *lblConst = memPool->New(lidx, puIdx, *type); (void)func->GetLabelTab()->addrTakenLabels.insert(lidx); @@ -541,19 +543,6 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { CHECK_FATAL(static_cast(-tag) < typTab.size(), "index out of bounds"); return typTab.at(static_cast(-tag)); } - if (tag == kBinKindTypeViaTypename) { - GStrIdx typenameStrIdx = ImportStr(); - TyIdx tyIdx = mod.GetTypeNameTab()->GetTyIdxFromGStrIdx(typenameStrIdx); - if (tyIdx != 0) { - typTab.push_back(tyIdx); - return tyIdx; - } - MIRTypeByName ltype(typenameStrIdx); - ltype.SetNameIsLocal(false); - MIRType *type = GlobalTables::GetTypeTable().GetOrCreateMIRTypeNode(ltype); - typTab.push_back(type->GetTypeIndex()); - return type->GetTypeIndex(); - } PrimType primType = (PrimType)0; GStrIdx strIdx(0); bool nameIsLocal = false; @@ -580,13 +569,6 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { } return origType->GetTypeIndex(); } - case kBinKindTypeByName: { - MIRTypeByName type(strIdx); - type.SetNameIsLocal(nameIsLocal); - MIRType *origType = &InsertInTypeTables(type); - typTab.push_back(origType->GetTypeIndex()); - return origType->GetTypeIndex(); - } case kBinKindTypeFArray: { MIRFarrayType type(strIdx); type.SetNameIsLocal(nameIsLocal); @@ -629,7 +611,7 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { size_t idx = typTab.size(); typTab.push_back(TyIdx(0)); type.SetRetTyIdx(ImportType()); - type.SetVarArgs(ReadNum()); + type.funcAttrs.SetAttrFlag(ReadNum()); int64 size = ReadNum(); for (int64 i = 0; i < size; ++i) { type.GetParamTypeList().push_back(ImportType()); @@ -737,19 +719,6 @@ TyIdx BinaryMplImport::ImportTypeNonJava() { CHECK_FATAL(static_cast(-tag) < typTab.size(), "index out of bounds"); return typTab[static_cast(-tag)]; } - if (tag == kBinKindTypeViaTypename) { - GStrIdx typenameStrIdx = ImportStr(); - TyIdx tyIdx = mod.GetTypeNameTab()->GetTyIdxFromGStrIdx(typenameStrIdx); - if (tyIdx != 0) { - typTab.push_back(tyIdx); - return tyIdx; - } - MIRTypeByName ltype(typenameStrIdx); - ltype.SetNameIsLocal(false); - MIRType *type = GlobalTables::GetTypeTable().GetOrCreateMIRTypeNode(ltype); - typTab.push_back(type->GetTypeIndex()); - return type->GetTypeIndex(); - } PrimType primType = (PrimType)0; GStrIdx strIdx(0); bool nameIsLocal = false; @@ -771,12 +740,6 @@ TyIdx BinaryMplImport::ImportTypeNonJava() { GlobalTables::GetTypeTable().CreateMirTypeNodeAt(type, tyIdxUsed, &mod, false, false); return tyIdxUsed; } - case kBinKindTypeByName: { - MIRTypeByName type(strIdx); - type.SetNameIsLocal(nameIsLocal); - GlobalTables::GetTypeTable().CreateMirTypeNodeAt(type, tyIdxUsed, &mod, false, false); - return tyIdxUsed; - } case kBinKindTypeFArray: { MIRFarrayType type(strIdx); type.SetNameIsLocal(nameIsLocal); @@ -808,7 +771,7 @@ TyIdx BinaryMplImport::ImportTypeNonJava() { MIRFuncType type(strIdx); type.SetNameIsLocal(nameIsLocal); type.SetRetTyIdx(ImportTypeNonJava()); - type.SetVarArgs(ReadNum()); + type.funcAttrs.SetAttrFlag(ReadNum()); int64 size = ReadNum(); for (int64 i = 0; i < size; ++i) { type.GetParamTypeList().push_back(ImportTypeNonJava()); @@ -1159,6 +1122,7 @@ void BinaryMplImport::ReadHeaderField() { mod.SetID(static_cast(ReadNum())); if (mod.GetFlavor() == kFlavorLmbc) { mod.SetGlobalMemSize(static_cast(ReadNum())); + mod.SetWithDbgInfo(static_cast(ReadNum())); } mod.SetNumFuncs(static_cast(ReadNum())); std::string inStr; diff --git a/src/mapleall/maple_ir/src/global_tables.cpp b/src/mapleall/maple_ir/src/global_tables.cpp index c7051c1257..2ee3711760 100644 --- a/src/mapleall/maple_ir/src/global_tables.cpp +++ b/src/mapleall/maple_ir/src/global_tables.cpp @@ -226,7 +226,9 @@ MIRType *TypeTable::GetOrCreateFunctionType(const TyIdx &retTyIdx, const std::ve const std::vector &vecAttrs, bool isVarg, const TypeAttrs &retAttrs) { MIRFuncType funcType(retTyIdx, vecType, vecAttrs, retAttrs); - funcType.SetVarArgs(isVarg); + if (isVarg) { + funcType.SetVarArgs(); + } TyIdx tyIdx = GetOrCreateMIRType(&funcType); ASSERT(tyIdx < typeTable.size(), "index out of range in TypeTable::GetOrCreateFunctionType"); return typeTable.at(tyIdx); diff --git a/src/mapleall/maple_ir/src/mir_builder.cpp b/src/mapleall/maple_ir/src/mir_builder.cpp index 20d46306c0..f1aa2583e4 100755 --- a/src/mapleall/maple_ir/src/mir_builder.cpp +++ b/src/mapleall/maple_ir/src/mir_builder.cpp @@ -835,6 +835,13 @@ IcallNode *MIRBuilder::CreateStmtIcall(const MapleVector &args) { return stmt; } +IcallNode *MIRBuilder::CreateStmtIcallproto(const MapleVector &args) { + auto *stmt = GetCurrentFuncCodeMp()->New(*GetCurrentFuncCodeMpAllocator(), OP_icallproto); + ASSERT(stmt != nullptr, "stmt is null"); + stmt->SetOpnds(args); + return stmt; +} + IcallNode *MIRBuilder::CreateStmtIcallAssigned(const MapleVector &args, const MIRSymbol &ret) { auto *stmt = GetCurrentFuncCodeMp()->New(*GetCurrentFuncCodeMpAllocator(), OP_icallassigned); CallReturnVector nrets(GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -852,6 +859,23 @@ IcallNode *MIRBuilder::CreateStmtIcallAssigned(const MapleVector &arg return stmt; } +IcallNode *MIRBuilder::CreateStmtIcallprotoAssigned(const MapleVector &args, const MIRSymbol &ret) { + auto *stmt = GetCurrentFuncCodeMp()->New(*GetCurrentFuncCodeMpAllocator(), OP_icallprotoassigned); + CallReturnVector nrets(GetCurrentFuncCodeMpAllocator()->Adapter()); + CHECK_FATAL((ret.GetStorageClass() == kScAuto || ret.GetStorageClass() == kScFormal || + ret.GetStorageClass() == kScExtern || ret.GetStorageClass() == kScGlobal), + "unknown classtype! check it!"); + nrets.emplace_back(CallReturnPair(ret.GetStIdx(), RegFieldPair(0, 0))); + stmt->SetNumOpnds(args.size()); + stmt->GetNopnd().resize(stmt->GetNumOpnds()); + stmt->SetReturnVec(nrets); + for (size_t i = 0; i < stmt->GetNopndSize(); ++i) { + stmt->SetNOpndAt(i, args.at(i)); + } + stmt->SetRetTyIdx(ret.GetTyIdx()); + return stmt; +} + IntrinsiccallNode *MIRBuilder::CreateStmtIntrinsicCall(MIRIntrinsicID idx, const MapleVector &arguments, TyIdx tyIdx) { auto *stmt = GetCurrentFuncCodeMp()->New( diff --git a/src/mapleall/maple_ir/src/mir_function.cpp b/src/mapleall/maple_ir/src/mir_function.cpp index b90b35f874..8e92309f4a 100644 --- a/src/mapleall/maple_ir/src/mir_function.cpp +++ b/src/mapleall/maple_ir/src/mir_function.cpp @@ -369,10 +369,8 @@ void MIRFunction::Dump(bool withoutBody) { LogInfo::MapleLogger() << " )"; } - if (module->GetFlavor() < kMmpl) { + if (module->GetFlavor() != kMmpl) { DumpFlavorLoweredThanMmpl(); - } else { - LogInfo::MapleLogger() << " () void"; } // codeMemPool is nullptr, means maple_ir has been released for memory's sake diff --git a/src/mapleall/maple_ir/src/mir_lower.cpp b/src/mapleall/maple_ir/src/mir_lower.cpp index 99dbd04c3f..aa5cb0131c 100644 --- a/src/mapleall/maple_ir/src/mir_lower.cpp +++ b/src/mapleall/maple_ir/src/mir_lower.cpp @@ -530,6 +530,19 @@ BlockNode *MIRLower::LowerBlock(BlockNode &block) { case OP_doloop: newBlock->AppendStatementsFromBlock(*LowerDoloopStmt(static_cast(*stmt))); break; + case OP_icallassigned: + case OP_icall: { + if (mirModule.IsCModule()) { + // convert to icallproto/icallprotoassigned + IcallNode *ic = static_cast(stmt); + ic->SetOpCode(stmt->GetOpCode() == OP_icall ? OP_icallproto : OP_icallprotoassigned); + MIRFuncType *funcType = FuncTypeFromFuncPtrExpr(stmt->Opnd(0)); + CHECK_FATAL(funcType != nullptr, "MIRLower::LowerBlock: cannot find prototype for icall"); + ic->SetRetTyIdx(funcType->GetTypeIndex()); + } + newBlock->AddStatement(stmt); + break; + } case OP_block: tmp = LowerBlock(static_cast(*stmt)); newBlock->AppendStatementsFromBlock(*tmp); @@ -985,6 +998,100 @@ void MIRLower::ExpandArrayMrt(MIRFunction &func) { } } +MIRFuncType *MIRLower::FuncTypeFromFuncPtrExpr(BaseNode *x) { + MIRFuncType *res = nullptr; + MIRFunction *func = mirModule.CurFunction(); + switch (x->GetOpCode()) { + case OP_regread: { + RegreadNode *regread = static_cast(x); + MIRPreg *preg = func->GetPregTab()->PregFromPregIdx(regread->GetRegIdx()); + // see if it is promoted from a symbol + if (preg->GetOp() == OP_dread) { + const MIRSymbol *symbol = preg->rematInfo.sym; + MIRType *mirType = symbol->GetType(); + if (preg->fieldID != 0) { + MIRStructType *structty = static_cast(mirType); + FieldPair thepair = structty->TraverseToField(preg->fieldID); + mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); + } + + if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + if (res != nullptr) { + break; + } + } + // check if a formal promoted to preg + for (FormalDef &formalDef : func->GetFormalDefVec()) { + if (!formalDef.formalSym->IsPreg()) { + continue; + } + if (formalDef.formalSym->GetPreg() == preg) { + MIRType *mirType = formalDef.formalSym->GetType(); + if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + break; + } + } + break; + } + case OP_dread: { + DreadNode *dread = static_cast(x); + MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); + MIRType *mirType = symbol->GetType(); + if (dread->GetFieldID() != 0) { + MIRStructType *structty = static_cast(mirType); + FieldPair thepair = structty->TraverseToField(dread->GetFieldID()); + mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); + } + if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + break; + } + case OP_iread: { + IreadNode *iread = static_cast(x); + MIRPtrType *ptrType = static_cast(iread->GetType()); + MIRType *mirType = ptrType->GetPointedType(); + if (mirType->GetKind() == kTypeFunction) { + res = static_cast(mirType); + } else if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + break; + } + case OP_addroffunc: { + AddroffuncNode *addrofFunc = static_cast(x); + PUIdx puIdx = addrofFunc->GetPUIdx(); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); + res = f->GetMIRFuncType(); + break; + } + case OP_retype: { + MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx( + static_cast(x)->GetTyIdx()); + if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + if (res == nullptr) { + res = FuncTypeFromFuncPtrExpr(x->Opnd(0)); + } + break; + } + case OP_select: { + res = FuncTypeFromFuncPtrExpr(x->Opnd(1)); + if (res == nullptr) { + res = FuncTypeFromFuncPtrExpr(x->Opnd(2)); + } + break; + } + default: CHECK_FATAL(false, "LMBCLowerer::FuncTypeFromFuncPtrExpr: NYI"); + } + return res; +} + const std::set MIRLower::kSetArrayHotFunc = {}; bool MIRLower::ShouldOptArrayMrt(const MIRFunction &func) { diff --git a/src/mapleall/maple_ir/src/mir_nodes.cpp b/src/mapleall/maple_ir/src/mir_nodes.cpp index fcb8ab411b..015cc337c8 100755 --- a/src/mapleall/maple_ir/src/mir_nodes.cpp +++ b/src/mapleall/maple_ir/src/mir_nodes.cpp @@ -1199,7 +1199,7 @@ MIRType *IcallNode::GetCallReturnType() { if (op == OP_icall || op == OP_icallassigned) { return GlobalTables::GetTypeTable().GetTypeFromTyIdx(retTyIdx); } - // icallproto + // icallproto or icallprotoassigned MIRFuncType *funcType = static_cast( GlobalTables::GetTypeTable().GetTypeFromTyIdx(retTyIdx)); return GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcType->GetRetTyIdx()); @@ -1224,7 +1224,7 @@ const MIRSymbol *IcallNode::GetCallReturnSymbol(const MIRModule &mod) const { void IcallNode::Dump(int32 indent, bool newline) const { StmtNode::DumpBase(indent); - if (op == OP_icallproto) { + if (op == OP_icallproto || op == OP_icallprotoassigned) { LogInfo::MapleLogger() << " "; GlobalTables::GetTypeTable().GetTypeFromTyIdx(retTyIdx)->Dump(indent + 1); } diff --git a/src/mapleall/maple_ir/src/mir_parser.cpp b/src/mapleall/maple_ir/src/mir_parser.cpp index 22ad419073..1e1c8fac2c 100755 --- a/src/mapleall/maple_ir/src/mir_parser.cpp +++ b/src/mapleall/maple_ir/src/mir_parser.cpp @@ -894,6 +894,7 @@ bool MIRParser::ParseStmtCall(StmtNodePtr &stmt) { callStmt->SetPUIdx(pIdx); MIRFunction *callee = GlobalTables::GetFunctionTable().GetFuncTable()[pIdx]; + callee->GetFuncSymbol()->SetAppearsInCode(true); if (callee->GetName() == "setjmp") { mod.CurFunction()->SetHasSetjmp(); } @@ -930,9 +931,14 @@ bool MIRParser::ParseStmtIcall(StmtNodePtr &stmt, Opcode op) { // . . . // dassign } // icallproto (, , ..., ) + // icallprotoassigned (, , ..., ) { + // dassign + // dassign + // . . . + // dassign } IcallNode *iCallStmt = mod.CurFuncCodeMemPool()->New(mod, op); lexer.NextToken(); - if (op == OP_icallproto) { + if (op == OP_icallproto || op == OP_icallprotoassigned) { TyIdx tyIdx(0); if (!ParseDerivedType(tyIdx)) { Error("error parsing type in ParseStmtIcall for icallproto at "); @@ -946,7 +952,7 @@ bool MIRParser::ParseStmtIcall(StmtNodePtr &stmt, Opcode op) { } iCallStmt->SetNOpnd(opndsVec); iCallStmt->SetNumOpnds(opndsVec.size()); - if (op == OP_icallassigned) { + if (op == OP_icallassigned || op == OP_icallprotoassigned) { CallReturnVector retsVec(mod.CurFuncCodeMemPoolAllocator()->Adapter()); if (!ParseCallReturns(retsVec)) { return false; @@ -970,6 +976,10 @@ bool MIRParser::ParseStmtIcallproto(StmtNodePtr &stmt) { return ParseStmtIcall(stmt, OP_icallproto); } +bool MIRParser::ParseStmtIcallprotoassigned(StmtNodePtr &stmt) { + return ParseStmtIcall(stmt, OP_icallprotoassigned); +} + bool MIRParser::ParseStmtIntrinsiccall(StmtNodePtr &stmt, bool isAssigned) { Opcode o = !isAssigned ? (lexer.GetTokenKind() == TK_intrinsiccall ? OP_intrinsiccall : OP_xintrinsiccall) : (lexer.GetTokenKind() == TK_intrinsiccallassigned ? OP_intrinsiccallassigned @@ -2006,18 +2016,6 @@ bool MIRParser::ParseStmtBlockForUpformalSize() { return true; } -bool MIRParser::ParseStmtBlockForOutParmSize() { - MIRFunction *fn = paramCurrFuncForParseStmtBlock; - lexer.NextToken(); - if (lexer.GetTokenKind() != TK_intconst) { - Error("expect integer after outparmsize but get "); - return false; - } - fn->SetOutParmSize(static_cast(lexer.GetTheIntVal())); - lexer.NextToken(); - return true; -} - bool MIRParser::ParseStmtBlockForModuleID() { MIRFunction *fn = paramCurrFuncForParseStmtBlock; lexer.NextToken(); @@ -3230,7 +3228,8 @@ bool MIRParser::ParseConstAddrLeafExpr(MIRConstPtr &cexpr) { } else if (expr->GetOpCode() == OP_addroffunc) { auto *aof = static_cast(expr); MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(aof->GetPUIdx()); - const MIRSymbol *fName = f->GetFuncSymbol(); + MIRSymbol *fName = f->GetFuncSymbol(); + fName->SetAppearsInCode(true); TyIdx ptyIdx = fName->GetTyIdx(); MIRPtrType ptrType(ptyIdx); ptyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&ptrType); @@ -3404,6 +3403,7 @@ std::map MIRParser::InitFuncPtrMapForPar funcPtrMap[TK_icall] = &MIRParser::ParseStmtIcall; funcPtrMap[TK_icallassigned] = &MIRParser::ParseStmtIcallassigned; funcPtrMap[TK_icallproto] = &MIRParser::ParseStmtIcallproto; + funcPtrMap[TK_icallprotoassigned] = &MIRParser::ParseStmtIcallprotoassigned; funcPtrMap[TK_intrinsiccall] = &MIRParser::ParseStmtIntrinsiccall; funcPtrMap[TK_intrinsiccallassigned] = &MIRParser::ParseStmtIntrinsiccallassigned; funcPtrMap[TK_xintrinsiccall] = &MIRParser::ParseStmtIntrinsiccall; @@ -3464,7 +3464,6 @@ std::map MIRParser::InitFuncPtrMapF funcPtrMap[TK_type] = &MIRParser::ParseStmtBlockForType; funcPtrMap[TK_framesize] = &MIRParser::ParseStmtBlockForFrameSize; funcPtrMap[TK_upformalsize] = &MIRParser::ParseStmtBlockForUpformalSize; - funcPtrMap[TK_outparmsize] = &MIRParser::ParseStmtBlockForOutParmSize; funcPtrMap[TK_moduleid] = &MIRParser::ParseStmtBlockForModuleID; funcPtrMap[TK_funcsize] = &MIRParser::ParseStmtBlockForFuncSize; funcPtrMap[TK_funcid] = &MIRParser::ParseStmtBlockForFuncID; diff --git a/src/mapleall/maple_ir/src/mir_type.cpp b/src/mapleall/maple_ir/src/mir_type.cpp index 64ee74b164..08180754b7 100644 --- a/src/mapleall/maple_ir/src/mir_type.cpp +++ b/src/mapleall/maple_ir/src/mir_type.cpp @@ -740,7 +740,9 @@ void MIRFuncType::Dump(int indent, bool dontUseName) const { if (!dontUseName && CheckAndDumpTypeName(nameStrIdx, nameIsLocal)) { return; } - LogInfo::MapleLogger() << "Dump(indent + 1); @@ -751,7 +753,7 @@ void MIRFuncType::Dump(int indent, bool dontUseName) const { LogInfo::MapleLogger() << ","; } } - if (isVarArgs) { + if (IsVarargs()) { LogInfo::MapleLogger() << ", ..."; } LogInfo::MapleLogger() << ") "; @@ -1662,7 +1664,7 @@ bool MIRFuncType::EqualTo(const MIRType &type) const { } const auto &pType = static_cast(type); return (pType.retTyIdx == retTyIdx && pType.paramTypeList == paramTypeList && - pType.isVarArgs == isVarArgs && pType.paramAttrsList == paramAttrsList && + pType.funcAttrs == funcAttrs && pType.paramAttrsList == paramAttrsList && pType.retAttrs == retAttrs); } diff --git a/src/mapleall/maple_ir/src/parser.cpp b/src/mapleall/maple_ir/src/parser.cpp index fdb586fcb0..808afd5373 100644 --- a/src/mapleall/maple_ir/src/parser.cpp +++ b/src/mapleall/maple_ir/src/parser.cpp @@ -229,9 +229,7 @@ bool MIRParser::ParsePseudoReg(PrimType primType, PregIdx &pRegIdx) { MIRPreg *preg = curfunc->GetPregTab()->PregFromPregIdx(pRegIdx); if (primType != kPtyInvalid) { if (preg->GetPrimType() != primType) { - if ((primType == PTY_ref || primType == PTY_ptr) && - (preg->GetPrimType() == PTY_ref || preg->GetPrimType() == PTY_ptr)) { - ; // PTY_ref and PTY_ptr are compatible with each other + if (IsAddress(preg->GetPrimType()) && IsAddress(primType)) { } else { Error("inconsistent preg primitive type at "); return false; @@ -1299,6 +1297,15 @@ bool MIRParser::ParsePointType(TyIdx &tyIdx) { // in function pointer specification and member function prototypes inside // structs and classes bool MIRParser::ParseFuncType(TyIdx &tyIdx) { + // parse function attributes + FuncAttrs fAttrs; + if (lexer.GetTokenKind() != TK_lparen) { + if (!ParseFuncAttrs(fAttrs)) { + Error("bad function attribute specification in function type at "); + return false; + } + } + // parse parameters if (lexer.GetTokenKind() != TK_lparen) { Error("expect ( parse function type parameters but get "); @@ -1359,7 +1366,10 @@ bool MIRParser::ParseFuncType(TyIdx &tyIdx) { return false; } MIRFuncType functype(retTyIdx, vecTyIdx, vecAttrs, retTypeAttrs); - functype.SetVarArgs(varargs); + functype.funcAttrs = fAttrs; + if (varargs) { + functype.SetVarArgs(); + } tyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&functype); return true; } diff --git a/src/mapleall/maple_me/include/lmbc_lower.h b/src/mapleall/maple_me/include/lmbc_lower.h index 9462204fd7..bbeaabf098 100644 --- a/src/mapleall/maple_me/include/lmbc_lower.h +++ b/src/mapleall/maple_me/include/lmbc_lower.h @@ -40,10 +40,7 @@ class LMBCLowerer { void LowerIassign(IassignNode *, BlockNode *); void LowerAggIassign(IassignNode *, MIRType *type, int32 offset, BlockNode *); void LowerReturn(NaryStmtNode *retNode, BlockNode *newblk); - MIRFuncType *FuncTypeFromFuncPtrExpr(BaseNode *x); - void LowerCall(NaryStmtNode *callNode, BlockNode *newblk); BlockNode *LowerBlock(BlockNode *); - void LoadFormalsAssignedToPregs(); void LowerFunction(); MIRModule *mirModule; diff --git a/src/mapleall/maple_me/include/lmbc_memlayout.h b/src/mapleall/maple_me/include/lmbc_memlayout.h index 7cea863a22..0f2bf5cbea 100644 --- a/src/mapleall/maple_me/include/lmbc_memlayout.h +++ b/src/mapleall/maple_me/include/lmbc_memlayout.h @@ -31,8 +31,8 @@ typedef enum { MS_actual, // for the outgoing parameters MS_local, // for all local variables and temporaries MS_FPbased, // addressed via offset from the frame pointer - MS_SPbased, // addressed via offset from the stack pointer MS_GPbased, // addressed via offset from the global pointer + MS_largeStructActual, // for storing large struct actuals passed by value for ARM CPU } MemSegmentKind; class MemSegment; @@ -64,15 +64,10 @@ class MemSegment { class LMBCMemLayout { public: - uint32 FindLargestActualArea(void); - uint32 FindLargestActualArea(StmtNode *, int &); - LMBCMemLayout(MIRFunction *f, MapleAllocator *mallocator) + LMBCMemLayout(MIRFunction *f, MemSegment *segGP, MapleAllocator *mallocator) : func(f), - seg_upformal(MS_upformal), - seg_formal(MS_formal), - seg_actual(MS_actual), + seg_GPbased(segGP), seg_FPbased(MS_FPbased), - seg_SPbased(MS_SPbased), sym_alloc_table(mallocator->Adapter()) { sym_alloc_table.resize(f->GetSymTab()->GetSymbolTableSize()); } @@ -81,67 +76,25 @@ class LMBCMemLayout { void LayoutStackFrame(void); int32 StackFrameSize(void) const { - return seg_SPbased.size - seg_FPbased.size; - } - - int32 UpformalSize(void) const { - return seg_upformal.size; + return -seg_FPbased.size; } MIRFunction *func; - MemSegment seg_upformal; - MemSegment seg_formal; - MemSegment seg_actual; + MemSegment *seg_GPbased; MemSegment seg_FPbased; - MemSegment seg_SPbased; MapleVector sym_alloc_table; // index is StIdx }; class GlobalMemLayout { public: - GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAllocator *mallocator); + GlobalMemLayout(MIRModule *mod, MapleAllocator *mallocator); ~GlobalMemLayout() {} MemSegment seg_GPbased; MapleVector sym_alloc_table; // index is StIdx - - private: - void FillScalarValueInMap(uint32 startaddress, PrimType pty, MIRConst *c); - void FillTypeValueInMap(uint32 startaddress, MIRType *ty, MIRConst *c); - void FillSymbolValueInMap(const MIRSymbol *sym); - - maplebe::BECommon *be; MIRModule *mirModule; }; -// for specifying how a parameter is passed -struct PLocInfo { - int32 memoffset; - int32 memsize; -}; - -// for processing an incoming or outgoing parameter list -class ParmLocator { - public: - explicit ParmLocator() : parmNum(0), lastMemOffset(0) {} - - ~ParmLocator() {} - - void LocateNextParm(const MIRType *ty, PLocInfo &ploc); - - private: - int32 parmNum; // number of all types of parameters processed so far - int32 lastMemOffset; -}; - -// given the type of the return value, determines the return mechanism -class ReturnMechanism { - public: - ReturnMechanism(const MIRType *retty); - bool fake_first_parm; // whether returning in memory via fake first parameter - PrimType ptype0; // the primitive type stored in retval0 -}; - } /* namespace maple */ #endif /* MAPLEME_INCLUDE_LMBC_MEMLAYOUT_H */ diff --git a/src/mapleall/maple_me/src/alias_class.cpp b/src/mapleall/maple_me/src/alias_class.cpp index 788a9a3540..1a63043e27 100644 --- a/src/mapleall/maple_me/src/alias_class.cpp +++ b/src/mapleall/maple_me/src/alias_class.cpp @@ -1017,7 +1017,9 @@ void AliasClass::ApplyUnionForCopies(StmtNode &stmt) { } case OP_asm: case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { for (uint32 i = 0; i < stmt.NumOpnds(); ++i) { const AliasInfo &ainfo = CreateAliasInfoExpr(*stmt.Opnd(i)); if (stmt.GetOpCode() != OP_asm && i == 0) { @@ -2563,6 +2565,7 @@ void AliasClass::GenericInsertMayDefUse(StmtNode &stmt, BBId bbID) { case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_virtualcall: case OP_virtualicall: case OP_superclasscall: @@ -2570,7 +2573,8 @@ void AliasClass::GenericInsertMayDefUse(StmtNode &stmt, BBId bbID) { case OP_interfaceicall: case OP_customcall: case OP_polymorphiccall: - case OP_icall: { + case OP_icall: + case OP_icallproto: { InsertMayDefUseCall(stmt, bbID, false); return; } diff --git a/src/mapleall/maple_me/src/code_factoring.cpp b/src/mapleall/maple_me/src/code_factoring.cpp index 6cabb59adc..2f40e7b821 100644 --- a/src/mapleall/maple_me/src/code_factoring.cpp +++ b/src/mapleall/maple_me/src/code_factoring.cpp @@ -122,7 +122,9 @@ bool FactoringOptimizer::IsIdenticalStmt(StmtNode *stmt1, StmtNode *stmt2) { break; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { auto *icall1 = static_cast(stmt1); auto *icall2 = static_cast(stmt2); if (icall1->GetRetTyIdx() != icall2->GetRetTyIdx() || diff --git a/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp b/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp index db34036937..50a25a6101 100644 --- a/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp +++ b/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp @@ -641,7 +641,9 @@ void PEGBuilder::BuildPEGNodeInStmt(const StmtNode *stmt) { break; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { BuildPEGNodeInIcall(static_cast(stmt)); break; } diff --git a/src/mapleall/maple_me/src/irmap_build.cpp b/src/mapleall/maple_me/src/irmap_build.cpp index 30a3f075bd..6410f2269a 100755 --- a/src/mapleall/maple_me/src/irmap_build.cpp +++ b/src/mapleall/maple_me/src/irmap_build.cpp @@ -804,7 +804,7 @@ MeStmt *IRMapBuild::BuildCallMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { MeStmt *IRMapBuild::BuildNaryMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { Opcode op = stmt.GetOpCode(); - NaryMeStmt *naryMeStmt = (op == OP_icall || op == OP_icallassigned) + NaryMeStmt *naryMeStmt = (op == OP_icall || op == OP_icallassigned || op == OP_icallproto || op == OP_icallprotoassigned) ? static_cast(irMap->NewInPool(&stmt)) : static_cast(irMap->NewInPool(&stmt)); auto &naryStmtNode = static_cast(stmt); @@ -819,6 +819,9 @@ MeStmt *IRMapBuild::BuildNaryMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { if (propagater) { propagater->PropUpdateChiListDef(*naryMeStmt->GetChiList()); } + if (op == OP_icallproto || op == OP_icallprotoassigned) { + static_cast(naryMeStmt)->SetRetTyIdx(static_cast(stmt).GetRetTyIdx()); + } return naryMeStmt; } @@ -919,6 +922,8 @@ void IRMapBuild::InitMeStmtFactory() { RegisterFactoryFunction(OP_polymorphiccallassigned, &IRMapBuild::BuildCallMeStmt); RegisterFactoryFunction(OP_icall, &IRMapBuild::BuildNaryMeStmt); RegisterFactoryFunction(OP_icallassigned, &IRMapBuild::BuildNaryMeStmt); + RegisterFactoryFunction(OP_icallproto, &IRMapBuild::BuildNaryMeStmt); + RegisterFactoryFunction(OP_icallprotoassigned, &IRMapBuild::BuildNaryMeStmt); RegisterFactoryFunction(OP_intrinsiccall, &IRMapBuild::BuildNaryMeStmt); RegisterFactoryFunction(OP_xintrinsiccall, &IRMapBuild::BuildNaryMeStmt); RegisterFactoryFunction(OP_intrinsiccallwithtype, &IRMapBuild::BuildNaryMeStmt); diff --git a/src/mapleall/maple_me/src/irmap_emit.cpp b/src/mapleall/maple_me/src/irmap_emit.cpp index 824e7c7e53..7fcbd3804b 100755 --- a/src/mapleall/maple_me/src/irmap_emit.cpp +++ b/src/mapleall/maple_me/src/irmap_emit.cpp @@ -412,7 +412,7 @@ MIRFunction &CallMeStmt::GetTargetFunction() { } StmtNode &CallMeStmt::EmitStmt(SSATab &ssaTab) { - if (GetOp() != OP_icall && GetOp() != OP_icallassigned) { + if (GetOp() != OP_icall && GetOp() != OP_icallassigned && GetOp() != OP_icallproto && GetOp() != OP_icallprotoassigned) { auto *callNode = ssaTab.GetModule().CurFunction()->GetCodeMempool()->New(ssaTab.GetModule(), Opcode(GetOp())); callNode->SetPUIdx(puIdx); @@ -496,6 +496,9 @@ StmtNode &IcallMeStmt::EmitStmt(SSATab &ssaTab) { } } } + if (GetOp() == OP_icallproto || GetOp() == OP_icallprotoassigned) { + icallNode->SetRetTyIdx(retTyIdx); + } return *icallNode; } diff --git a/src/mapleall/maple_me/src/lfo_dep_test.cpp b/src/mapleall/maple_me/src/lfo_dep_test.cpp index 19a523e138..ac3340e843 100644 --- a/src/mapleall/maple_me/src/lfo_dep_test.cpp +++ b/src/mapleall/maple_me/src/lfo_dep_test.cpp @@ -66,6 +66,8 @@ void LfoDepInfo::CreateDoloopInfo(BlockNode *block, DoloopInfo *parent) { case OP_callassigned: case OP_icall: case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: case OP_return: case OP_throw: case OP_asm: diff --git a/src/mapleall/maple_me/src/lmbc_lower.cpp b/src/mapleall/maple_me/src/lmbc_lower.cpp index a155b25fa4..f5893447ba 100644 --- a/src/mapleall/maple_me/src/lmbc_lower.cpp +++ b/src/mapleall/maple_me/src/lmbc_lower.cpp @@ -22,16 +22,12 @@ using namespace std; PregIdx LMBCLowerer::GetSpecialRegFromSt(const MIRSymbol *sym) { MIRStorageClass storageClass = sym->GetStorageClass(); PregIdx specreg = 0; - if (storageClass == kScAuto || storageClass == kScFormal) { + if (storageClass == kScAuto) { CHECK(sym->GetStIndex() < memlayout->sym_alloc_table.size(), "index out of range in LMBCLowerer::GetSpecialRegFromSt"); SymbolAlloc symalloc = memlayout->sym_alloc_table[sym->GetStIndex()]; - if (symalloc.mem_segment->kind == MS_upformal || symalloc.mem_segment->kind == MS_formal || - symalloc.mem_segment->kind == MS_FPbased) { + if (symalloc.mem_segment->kind == MS_FPbased) { specreg = -kSregFp; - } else if (symalloc.mem_segment->kind == MS_actual || - symalloc.mem_segment->kind == MS_SPbased) { - specreg = -kSregSp; } else { CHECK_FATAL(false, "LMBCLowerer::LowerDread: bad memory layout for local variable"); } @@ -46,6 +42,7 @@ PregIdx LMBCLowerer::GetSpecialRegFromSt(const MIRSymbol *sym) { BaseNode *LMBCLowerer::LowerAddrof(AddrofNode *expr) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(expr->GetStIdx()); + symbol->ResetIsDeleted(); int32 offset = 0; if (expr->GetFieldID() != 0) { MIRStructType *structty = static_cast(symbol->GetType()); @@ -66,6 +63,7 @@ BaseNode *LMBCLowerer::LowerAddrof(AddrofNode *expr) { BaseNode *LMBCLowerer::LowerDread(AddrofNode *expr) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(expr->GetStIdx()); + symbol->ResetIsDeleted(); PrimType symty = symbol->GetType()->GetPrimType(); int32 offset = 0; if (expr->GetFieldID() != 0) { @@ -96,20 +94,22 @@ BaseNode *LMBCLowerer::LowerDread(AddrofNode *expr) { BaseNode *LMBCLowerer::LowerDreadoff(DreadoffNode *dreadoff) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dreadoff->stIdx); + symbol->ResetIsDeleted(); if (!symbol->LMBCAllocateOffSpecialReg()) { return dreadoff; } + PrimType symty = symbol->GetType()->GetPrimType(); PregIdx spcreg = GetSpecialRegFromSt(symbol); if (spcreg == -kSregFp) { CHECK_FATAL(symbol->IsLocal(), "load from fp non local?"); - IreadFPoffNode *ireadoff = mirBuilder->CreateExprIreadFPoff( - dreadoff->GetPrimType(), memlayout->sym_alloc_table[symbol->GetStIndex()].offset + dreadoff->offset); + IreadFPoffNode *ireadoff = mirBuilder->CreateExprIreadFPoff(symty, + memlayout->sym_alloc_table[symbol->GetStIndex()].offset + dreadoff->offset); return ireadoff; } else { BaseNode *rrn = mirBuilder->CreateExprRegread(LOWERED_PTR_TYPE, spcreg); SymbolAlloc &symalloc = symbol->IsLocal() ? memlayout->sym_alloc_table[symbol->GetStIndex()] : globmemlayout->sym_alloc_table[symbol->GetStIndex()]; - IreadoffNode *ireadoff = mirBuilder->CreateExprIreadoff(dreadoff->GetPrimType(), symalloc.offset + dreadoff->offset, rrn); + IreadoffNode *ireadoff = mirBuilder->CreateExprIreadoff(symty, symalloc.offset + dreadoff->offset, rrn); return ireadoff; } } @@ -129,14 +129,14 @@ static MIRType *GetPointedToType(const MIRPtrType *pointerty) { BaseNode *LMBCLowerer::LowerIread(IreadNode *expr) { int32 offset = 0; + MIRPtrType *ptrType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(expr->GetTyIdx())); + MIRType *type = ptrType->GetPointedType(); if (expr->GetFieldID() != 0) { - MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(expr->GetTyIdx()); - MIRStructType *structty = - static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(type)->GetPointedTyIdx())); + MIRStructType *structty = static_cast(type); offset = becommon->GetFieldOffset(*structty, expr->GetFieldID()).first; + type = structty->GetFieldType(expr->GetFieldID()); } - BaseNode *ireadoff = mirBuilder->CreateExprIreadoff(expr->GetPrimType(), offset, expr->Opnd(0)); + BaseNode *ireadoff = mirBuilder->CreateExprIreadoff(type->GetPrimType(), offset, expr->Opnd(0)); return ireadoff; } @@ -165,6 +165,7 @@ BaseNode *LMBCLowerer::LowerExpr(BaseNode *expr) { return LowerAddrof(static_cast(expr)); case OP_addrofoff: { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(static_cast(expr)->stIdx); + symbol->ResetIsDeleted(); CHECK_FATAL(!symbol->LMBCAllocateOffSpecialReg(), "LMBCLowerer:: illegal addrofoff instruction"); break; @@ -199,6 +200,7 @@ void LMBCLowerer::LowerAggDassign(const DassignNode *dsnode, MIRType *lhsty, // generate lhs address expression BaseNode *lhs = nullptr; MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dsnode->GetStIdx()); + symbol->ResetIsDeleted(); if (!symbol->LMBCAllocateOffSpecialReg()) { lhs = mirBuilder->CreateExprDreadoff(OP_addrofoff, LOWERED_PTR_TYPE, *symbol, offset); } else { @@ -218,6 +220,7 @@ void LMBCLowerer::LowerAggDassign(const DassignNode *dsnode, MIRType *lhsty, void LMBCLowerer::LowerDassign(DassignNode *dsnode, BlockNode *newblk) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dsnode->GetStIdx()); + symbol->ResetIsDeleted(); MIRType *symty = symbol->GetType(); int32 offset = 0; if (dsnode->GetFieldID() != 0) { @@ -259,6 +262,7 @@ void LMBCLowerer::LowerDassign(DassignNode *dsnode, BlockNode *newblk) { void LMBCLowerer::LowerDassignoff(DassignoffNode *dsnode, BlockNode *newblk) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dsnode->stIdx); + symbol->ResetIsDeleted(); CHECK_FATAL(dsnode->Opnd(0)->GetPrimType() != PTY_agg, "LowerDassignoff: agg primitive type NYI"); BaseNode *rhs = LowerExpr(dsnode->Opnd(0)); if (!symbol->LMBCAllocateOffSpecialReg()) { @@ -334,6 +338,9 @@ void LMBCLowerer::LowerIassign(IassignNode *iassign, BlockNode *newblk) { } if (iassign->GetRHS()->GetPrimType() != PTY_agg) { PrimType ptypused = type->GetPrimType(); + if (ptypused == PTY_agg) { + ptypused = iassign->GetRHS()->GetPrimType(); + } IassignoffNode *iassignoff = mirBuilder->CreateStmtIassignoff(ptypused, offset, iassign->addrExpr, @@ -347,15 +354,20 @@ void LMBCLowerer::LowerIassign(IassignNode *iassign, BlockNode *newblk) { // called only if the return has > 1 operand; assume prior lowering already // converted any return of structs to be via fake parameter void LMBCLowerer::LowerReturn(NaryStmtNode *retNode, BlockNode *newblk) { - CHECK_FATAL(retNode->NumOpnds() <= 2, "LMBCLowerer::LowerReturn: more than 2 return values NYI"); - for (int i = 0; i < retNode->NumOpnds(); i++) { - CHECK_FATAL(retNode->Opnd(i)->GetPrimType() != PTY_agg, - "LMBCLowerer::LowerReturn: return of aggregate needs to be handled first"); - // insert regassign for the returned value - BaseNode *rhs = LowerExpr(retNode->Opnd(i)); - RegassignNode *regasgn = mirBuilder->CreateStmtRegassign(rhs->GetPrimType(), - i == 0 ? -kSregRetval0 : -kSregRetval1, - rhs); + if (retNode->Opnd(0)->GetPrimType() != PTY_agg) { + CHECK_FATAL(retNode->NumOpnds() <= 2, "LMBCLowerer::LowerReturn: more than 2 return values NYI"); + for (int i = 0; i < retNode->NumOpnds(); i++) { + // insert regassign for the returned value + PrimType ptyp = retNode->Opnd(i)->GetPrimType(); + BaseNode *rhs = LowerExpr(retNode->Opnd(i)); + RegassignNode *regasgn = mirBuilder->CreateStmtRegassign(ptyp, + i == 0 ? -kSregRetval0 : -kSregRetval1, + rhs); + newblk->AddStatement(regasgn); + } + } else { // handle return of small struct using only %%retval0 + BaseNode *rhs = LowerExpr(retNode->Opnd(0)); + RegassignNode *regasgn = mirBuilder->CreateStmtRegassign(PTY_agg, -kSregRetval0, rhs); newblk->AddStatement(regasgn); } retNode->GetNopnd().clear(); // remove the return operands @@ -363,178 +375,6 @@ void LMBCLowerer::LowerReturn(NaryStmtNode *retNode, BlockNode *newblk) { newblk->AddStatement(retNode); } -MIRFuncType *LMBCLowerer::FuncTypeFromFuncPtrExpr(BaseNode *x) { - MIRFuncType *res = nullptr; - switch (x->GetOpCode()) { - case OP_regread: { - RegreadNode *regread = static_cast(x); - MIRPreg *preg = func->GetPregTab()->PregFromPregIdx(regread->GetRegIdx()); - // see if it is promoted from a symbol - if (preg->GetOp() == OP_dread) { - const MIRSymbol *symbol = preg->rematInfo.sym; - MIRType *mirType = symbol->GetType(); - if (preg->fieldID != 0) { - MIRStructType *structty = static_cast(mirType); - FieldPair thepair = structty->TraverseToField(preg->fieldID); - mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - if (res != nullptr) { - break; - } - } - // check if a formal promoted to preg - for (FormalDef &formalDef : func->GetFormalDefVec()) { - if (!formalDef.formalSym->IsPreg()) { - continue; - } - if (formalDef.formalSym->GetPreg() == preg) { - MIRType *mirType = formalDef.formalSym->GetType(); - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - break; - } - } - break; - } - case OP_dread: { - DreadNode *dread = static_cast(x); - MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); - MIRType *mirType = symbol->GetType(); - if (dread->GetFieldID() != 0) { - MIRStructType *structty = static_cast(mirType); - FieldPair thepair = structty->TraverseToField(dread->GetFieldID()); - mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - break; - } - case OP_iread: { - IreadNode *iread = static_cast(x); - MIRPtrType *ptrType = static_cast(iread->GetType()); - MIRType *mirType = ptrType->GetPointedType(); - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - break; - } - case OP_addroffunc: { - AddroffuncNode *addrofFunc = static_cast(x); - PUIdx puIdx = addrofFunc->GetPUIdx(); - MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); - res = f->GetMIRFuncType(); - break; - } - case OP_retype: { - MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(x)->GetTyIdx()); - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - if (res == nullptr) { - res = FuncTypeFromFuncPtrExpr(x->Opnd(0)); - } - break; - } - case OP_select: { - res = FuncTypeFromFuncPtrExpr(x->Opnd(1)); - if (res == nullptr) { - res = FuncTypeFromFuncPtrExpr(x->Opnd(2)); - } - break; - } - default: CHECK_FATAL(false, "LMBCLowerer::FuncTypeFromFuncPtrExpr: NYI"); - } - return res; -} - -void LMBCLowerer::LowerCall(NaryStmtNode *naryStmt, BlockNode *newblk) { - // go through each parameter - uint32 i = 0; - if (naryStmt->GetOpCode() == OP_icall || naryStmt->GetOpCode() == OP_icallassigned) { - i = 1; - } - ParmLocator parmlocator; - for (; i < naryStmt->NumOpnds(); i++) { - BaseNode *opnd = naryStmt->Opnd(i); - MIRType *ty = nullptr; - // get ty for this parameter - if (opnd->GetPrimType() != PTY_agg) { - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(static_cast(opnd->GetPrimType())); - } else { - Opcode opnd_opcode = opnd->GetOpCode(); - CHECK_FATAL(opnd_opcode == OP_dread || opnd_opcode == OP_iread, ""); - if (opnd_opcode == OP_dread) { - AddrofNode *dread = static_cast(opnd); - MIRSymbol *sym = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx()); - if (dread->GetFieldID() != 0) { - CHECK_FATAL(ty->IsStructType(), ""); - FieldPair thepair = static_cast(ty)->TraverseToField(dread->GetFieldID()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - } else { // OP_iread - IreadNode *iread = static_cast(opnd); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread->GetTyIdx()); - CHECK_FATAL(ty->GetKind() == kTypePointer, ""); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(ty)->GetPointedTyIdx()); - if (iread->GetFieldID() != 0) { - CHECK_FATAL(ty->IsStructType(), ""); - FieldPair thepair = static_cast(ty)->TraverseToField(iread->GetFieldID()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - } - } - PLocInfo ploc; - parmlocator.LocateNextParm(ty, ploc); - if (opnd->GetPrimType() != PTY_agg) { - IassignFPoffNode *iass = mirBuilder->CreateStmtIassignFPoff(OP_iassignspoff, - opnd->GetPrimType(), - ploc.memoffset, - LowerExpr(opnd)); - newblk->AddStatement(iass); - } else { - BlkassignoffNode *bass = - mirModule->CurFuncCodeMemPool()->New(ploc.memoffset, ploc.memsize); - bass->SetAlign(std::min(ty->GetAlign(), 8u)); - bass->SetBOpnd(mirBuilder->CreateExprRegread(LOWERED_PTR_TYPE, -kSregSp), 0); - // the operand is either OP_dread or OP_iread; use its address instead - if (opnd->GetOpCode() == OP_dread) { - opnd->SetOpCode(OP_addrof); - } else { - opnd->SetOpCode(OP_iaddrof); - } - opnd->SetPrimType(LOWERED_PTR_TYPE); - bass->SetBOpnd(LowerExpr(opnd), 1); - newblk->AddStatement(bass); - } - } - BaseNode *opnd0 = nullptr; - if (naryStmt->GetOpCode() == OP_icall || naryStmt->GetOpCode() == OP_icallassigned) { - opnd0 = naryStmt->Opnd(0); - naryStmt->GetNopnd().clear(); // remove the call operands - // convert to OP_icallproto by finding the function prototype and record in stmt - naryStmt->SetOpCode(OP_icallproto); - MIRFuncType *funcType = FuncTypeFromFuncPtrExpr(opnd0); - CHECK_FATAL(funcType != nullptr, "LMBCLowerer::LowerCall: cannot find prototype for icall"); - static_cast(naryStmt)->SetRetTyIdx(funcType->GetTypeIndex()); - // add back the function pointer operand - naryStmt->GetNopnd().push_back(LowerExpr(opnd0)); - naryStmt->SetNumOpnds(1); - } else { - naryStmt->GetNopnd().clear(); // remove the call operands - naryStmt->SetNumOpnds(0); - } - newblk->AddStatement(naryStmt); -} - BlockNode *LMBCLowerer::LowerBlock(BlockNode *block) { BlockNode *newblk = mirModule->CurFuncCodeMemPool()->New(); if (!block->GetFirst()) { @@ -569,10 +409,6 @@ BlockNode *LMBCLowerer::LowerBlock(BlockNode *block) { } else { LowerReturn(retNode, newblk); } - } - case OP_call: - case OP_icall: { - LowerCall(static_cast(stmt), newblk); break; } default: { @@ -587,29 +423,19 @@ BlockNode *LMBCLowerer::LowerBlock(BlockNode *block) { return newblk; } -void LMBCLowerer::LoadFormalsAssignedToPregs() { - // go through each formals - for (int32 i = func->GetFormalDefVec().size()-1; i >= 0; i--) { - MIRSymbol *formalSt = func->GetFormalDefVec()[i].formalSym; - if (formalSt->GetSKind() != kStPreg) { - continue; +void LMBCLowerer::LowerFunction() { + // set extern global vars' isDeleted field; will reset when visited + MapleVector::const_iterator sit = mirModule->GetSymbolDefOrder().begin(); + for (; sit != mirModule->GetSymbolDefOrder().end(); ++sit) { + MIRSymbol *s = GlobalTables::GetGsymTable().GetSymbolFromStidx(sit->Idx()); + if (s->GetSKind() == kStVar && s->GetStorageClass() == kScExtern && !s->HasPotentialAssignment()) { + s->SetIsDeleted(); } - MIRPreg *preg = formalSt->GetPreg(); - uint32 stindex = formalSt->GetStIndex(); - PrimType pty = formalSt->GetType()->GetPrimType(); - IreadFPoffNode *ireadfpoff = mirBuilder->CreateExprIreadFPoff(pty, - memlayout->sym_alloc_table[stindex].offset); - RegassignNode *rass = mirBuilder->CreateStmtRegassign(pty, - func->GetPregTab()->GetPregIdxFromPregno(preg->GetPregNo()), ireadfpoff); - func->GetBody()->InsertFirst(rass); } -} -void LMBCLowerer::LowerFunction() { BlockNode *origbody = func->GetBody(); BlockNode *newbody = LowerBlock(origbody); func->SetBody(newbody); - LoadFormalsAssignedToPregs(); } } // namespace maple diff --git a/src/mapleall/maple_me/src/lmbc_memlayout.cpp b/src/mapleall/maple_me/src/lmbc_memlayout.cpp index e740c5d13f..b32acae493 100644 --- a/src/mapleall/maple_me/src/lmbc_memlayout.cpp +++ b/src/mapleall/maple_me/src/lmbc_memlayout.cpp @@ -13,146 +13,40 @@ * See the MulanPSL - 2.0 for more details. */ -// For each function being compiled, lay out its parameters, return values and -// local variables on its stack frame. This involves determining how parameters -// and return values are passed from analyzing their types. -// -// Allocate all the global variables within the global memory block which is -// addressed via offset from the global pointer GP during execution. Allocate -// this block pointed to by mirModule.globalBlkMap and perform the static -// initializations. +// For each function being compiled, lay out its local variables on its stack +// frame. Allocate all the global variables within the global memory block +// which is addressed via offset from the global pointer GP during execution. +// Allocate this block pointed to by mirModule.globalBlkMap. #include "lmbc_memlayout.h" #include "mir_symbol.h" namespace maple { -uint32 LMBCMemLayout::FindLargestActualArea(StmtNode *stmt, int &maxActualSize) { - if (!stmt) { - return maxActualSize; - } - Opcode opcode = stmt->op; - switch (opcode) { - case OP_block: { - BlockNode *blcknode = static_cast(stmt); - for (StmtNode &s : blcknode->GetStmtNodes()) { - FindLargestActualArea(&s, maxActualSize); - } - break; - } - case OP_if: { - IfStmtNode *ifnode = static_cast(stmt); - FindLargestActualArea(ifnode->GetThenPart(), maxActualSize); - FindLargestActualArea(ifnode->GetElsePart(), maxActualSize); - break; - } - case OP_doloop: { - FindLargestActualArea(static_cast(stmt)->GetDoBody(), maxActualSize); - break; - } - case OP_dowhile: - case OP_while: - FindLargestActualArea(static_cast(stmt)->GetBody(), maxActualSize); - break; - case OP_call: - case OP_icall: - case OP_intrinsiccall: { - ParmLocator parmlocator; // instantiate a parm locator - NaryStmtNode *callstmt = static_cast(stmt); - for (uint32 i = 0; i < callstmt->NumOpnds(); i++) { - BaseNode *opnd = callstmt->Opnd(i); - CHECK_FATAL(opnd->GetPrimType() != PTY_void, ""); - MIRType *ty = nullptr; - if (opnd->GetPrimType() != PTY_agg) { - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(opnd->GetPrimType())); - } else { - Opcode opnd_opcode = opnd->GetOpCode(); - CHECK_FATAL(opnd_opcode == OP_dread || opnd_opcode == OP_iread, ""); - if (opnd_opcode == OP_dread) { - AddrofNode *dread = static_cast(opnd); - MIRSymbol *sym = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx()); - if (dread->GetFieldID() != 0) { - CHECK_FATAL(ty->IsStructType(), "expect struct or class or union"); - FieldPair thepair = - static_cast(ty)->TraverseToField(dread->GetFieldID()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - } else { // OP_iread - IreadNode *iread = static_cast(opnd); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread->GetTyIdx()); - CHECK_FATAL(ty->GetKind() == kTypePointer, ""); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(ty)->GetPointedTyIdx()); - if (iread->GetFieldID() != 0) { - CHECK_FATAL(ty->IsStructType(), "expect struct or class or union"); - FieldPair thepair = - static_cast(ty)->TraverseToField(iread->GetFieldID()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - } - } - PLocInfo ploc; - parmlocator.LocateNextParm(ty, ploc); - maxActualSize = std::max(maxActualSize, ploc.memoffset + ploc.memsize); - maxActualSize = maplebe::RoundUp(maxActualSize, GetPrimTypeSize(PTY_ptr)); - } - break; - } - default: - return maxActualSize; - } - maxActualSize = maplebe::RoundUp(maxActualSize, GetPrimTypeSize(PTY_ptr)); - return maxActualSize; -} - -// go over all outgoing calls in the function body and get the maximum space -// needed for storing the actuals based on the actual parameters and the ABI; -// this assumes that all nesting of statements has been removed, so that all -// the statements are at only one block level -uint32 LMBCMemLayout::FindLargestActualArea(void) { - int32 maxActualSize = 0; - FindLargestActualArea(func->GetBody(), maxActualSize); - return static_cast(maxActualSize); -} +constexpr size_t kVarargSaveAreaSize = 192; void LMBCMemLayout::LayoutStackFrame(void) { - MIRSymbol *sym = nullptr; - // go through formal parameters - ParmLocator parmlocator; // instantiate a parm locator - PLocInfo ploc; - for (uint32 i = 0; i < func->GetFormalDefVec().size(); i++) { - FormalDef formalDef = func->GetFormalDefAt(i); - sym = formalDef.formalSym; - MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(formalDef.formalTyIdx); - parmlocator.LocateNextParm(ty, ploc); - uint32 stindex = sym->GetStIndex(); - // always passed in memory, so allocate in seg_upformal - sym_alloc_table[stindex].mem_segment = &seg_upformal; - seg_upformal.size = maplebe::RoundUp(seg_upformal.size, ty->GetAlign()); - sym_alloc_table[stindex].offset = seg_upformal.size; - seg_upformal.size += ty->GetSize(); - seg_upformal.size = maplebe::RoundUp(seg_upformal.size, GetPrimTypeSize(PTY_ptr)); + if (func->IsVarargs()) { + seg_FPbased.size -= kVarargSaveAreaSize; } - // allocate seg_formal in seg_FPbased - seg_formal.how_alloc.mem_segment = &seg_FPbased; - seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, GetPrimTypeSize(PTY_ptr)); - seg_FPbased.size -= seg_formal.size; - seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, GetPrimTypeSize(PTY_ptr)); - seg_formal.how_alloc.offset = seg_FPbased.size; - // allocate the local variables uint32 symtabsize = func->GetSymTab()->GetSymbolTableSize(); for (uint32 i = 0; i < symtabsize; i++) { - sym = func->GetSymTab()->GetSymbolFromStIdx(i); + MIRSymbol *sym = func->GetSymTab()->GetSymbolFromStIdx(i); if (!sym) { continue; } if (sym->IsDeleted()) { continue; } + if (sym->GetStorageClass() == kScPstatic && sym->LMBCAllocateOffSpecialReg()) { + uint32 stindex = sym->GetStIndex(); + sym_alloc_table[stindex].mem_segment = seg_GPbased; + seg_GPbased->size = maplebe::RoundUp(seg_GPbased->size, sym->GetType()->GetAlign()); + sym_alloc_table[stindex].offset = seg_GPbased->size; + seg_GPbased->size += sym->GetType()->GetSize(); + } if (sym->GetStorageClass() != kScAuto) { continue; } @@ -162,160 +56,10 @@ void LMBCMemLayout::LayoutStackFrame(void) { seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, sym->GetType()->GetAlign()); sym_alloc_table[stindex].offset = seg_FPbased.size; } - seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, GetPrimTypeSize(PTY_ptr)); - - // allocate seg_actual for storing the outgoing parameters; this requires - // going over all outgoing calls and get the maximum space needed for the - // actuals - seg_actual.size = FindLargestActualArea(); - func->SetOutParmSize(seg_actual.size); - - // allocate seg_actual in seg_SPbased - seg_actual.how_alloc.mem_segment = &seg_SPbased; - seg_actual.how_alloc.offset = seg_SPbased.size; - seg_SPbased.size = maplebe::RoundUp(seg_SPbased.size, GetPrimTypeSize(PTY_ptr)); - seg_SPbased.size += seg_actual.size; - seg_SPbased.size = maplebe::RoundUp(seg_SPbased.size, GetPrimTypeSize(PTY_ptr)); -} - -inline uint8 GetU8Const(MIRConst *c) { - MIRIntConst *intconst = static_cast(c); - return static_cast(intconst->GetValue()); -} - -inline uint16 GetU16Const(MIRConst *c) { - MIRIntConst *intconst = static_cast(c); - return static_cast(intconst->GetValue()); -} - -inline uint32 GetU32Const(MIRConst *c) { - MIRIntConst *intconst = static_cast(c); - return static_cast(intconst->GetValue()); -} - -inline uint64 GetU64Const(MIRConst *c) { - MIRIntConst *intconst = static_cast(c); - return static_cast(intconst->GetValue()); -} - -inline uint32 GetF32Const(MIRConst *c) { - MIRFloatConst *floatconst = static_cast(c); - return static_cast(floatconst->GetIntValue()); -} - -inline uint64 GetF64Const(MIRConst *c) { - MIRDoubleConst *doubleconst = static_cast(c); - return static_cast(doubleconst->GetIntValue()); -} - -void GlobalMemLayout::FillScalarValueInMap(uint32 startaddress, PrimType pty, MIRConst *c) { - switch (pty) { - case PTY_u1: - case PTY_u8: - case PTY_i8: { - uint8 *p = &mirModule->GetGlobalBlockMap()[startaddress]; - *p = GetU8Const(c); - break; - } - case PTY_u16: - case PTY_i16: { - uint16 *p = (uint16 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetU16Const(c); - break; - } - case PTY_u32: - case PTY_i32: { - uint32 *p = (uint32 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetU32Const(c); - break; - } - case PTY_u64: - case PTY_i64: { - uint64 *p = (uint64 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetU64Const(c); - break; - } - case PTY_f32: { - uint32 *p = (uint32 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetF32Const(c); - break; - } - case PTY_f64: { - uint64 *p = (uint64 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetF64Const(c); - break; - } - default: - CHECK_FATAL(false, "FillScalarValueInMap: NYI"); - } - return; } -void GlobalMemLayout::FillTypeValueInMap(uint32 startaddress, MIRType *ty, MIRConst *c) { - switch (ty->GetKind()) { - case kTypeScalar: - FillScalarValueInMap(startaddress, ty->GetPrimType(), c); - break; - case kTypeArray: { - MIRArrayType *arraytype = static_cast(ty); - MIRType *elemtype = arraytype->GetElemType(); - int32 elemsize = elemtype->GetSize(); - MIRAggConst *aggconst = static_cast(c); - CHECK_FATAL(aggconst, "FillTypeValueInMap: inconsistent array initialization specification"); - MapleVector &constvec = aggconst->GetConstVec(); - for (MapleVector::iterator it = constvec.begin(); it != constvec.end(); - it++, startaddress += elemsize) { - FillTypeValueInMap(startaddress, elemtype, *it); - } - break; - } - case kTypeStruct: { - MIRStructType *structty = static_cast(ty); - MIRAggConst *aggconst = static_cast(c); - CHECK_FATAL(aggconst, "FillTypeValueInMap: inconsistent struct initialization specification"); - MapleVector &constvec = aggconst->GetConstVec(); - for (uint32 i = 0; i < constvec.size(); i++) { - uint32 fieldID = aggconst->GetFieldIdItem(i); - FieldPair thepair = structty->TraverseToField(fieldID); - MIRType *fieldty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - uint32 offset = be->GetFieldOffset(*structty, fieldID).first; - FillTypeValueInMap(startaddress + offset, fieldty, constvec[i]); - } - break; - } - case kTypeClass: { - MIRClassType *classty = static_cast(ty); - MIRAggConst *aggconst = static_cast(c); - CHECK_FATAL(aggconst, "FillTypeValueInMap: inconsistent class initialization specification"); - MapleVector &constvec = aggconst->GetConstVec(); - for (uint32 i = 0; i < constvec.size(); i++) { - uint32 fieldID = aggconst->GetFieldIdItem(i); - FieldPair thepair = classty->TraverseToField(fieldID); - MIRType *fieldty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - uint32 offset = be->GetFieldOffset(*classty, fieldID).first; - FillTypeValueInMap(startaddress + offset, fieldty, constvec[i]); - } - break; - } - default: - CHECK_FATAL(false, "FillTypeValueInMap: NYI"); - } -} - -void GlobalMemLayout::FillSymbolValueInMap(const MIRSymbol *sym) { - if (sym->GetKonst() == nullptr) { - return; - } - uint32 stindex = sym->GetStIndex(); - CHECK(stindex < sym_alloc_table.size(), - "index out of range in GlobalMemLayout::FillSymbolValueInMap"); - uint32 symaddress = sym_alloc_table[stindex].offset; - FillTypeValueInMap(symaddress, sym->GetType(), sym->GetKonst()); - return; -} - -GlobalMemLayout::GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAllocator *mallocator) : - seg_GPbased(MS_GPbased), sym_alloc_table(mallocator->Adapter()), be(b), mirModule(mod) { +GlobalMemLayout::GlobalMemLayout(MIRModule *mod, MapleAllocator *mallocator) : + seg_GPbased(MS_GPbased), sym_alloc_table(mallocator->Adapter()), mirModule(mod) { uint32 symtabsize = GlobalTables::GetGsymTable().GetSymbolTableSize(); sym_alloc_table.resize(symtabsize); MIRSymbol *sym = nullptr; @@ -329,6 +73,9 @@ GlobalMemLayout::GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAll if (sym->GetStorageClass() != kScGlobal && sym->GetStorageClass() != kScFstatic) { continue; } + if (!sym->LMBCAllocateOffSpecialReg()) { + continue; + } if (sym->GetType()->GetAlign() != curalign) { continue; } @@ -341,152 +88,6 @@ GlobalMemLayout::GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAll } seg_GPbased.size = maplebe::RoundUp(seg_GPbased.size, GetPrimTypeSize(PTY_ptr)); mirModule->SetGlobalMemSize(seg_GPbased.size); - // allocate the memory map for the GP block - mirModule->SetGlobalBlockMap( - static_cast(mirModule->GetMemPool()->Calloc(seg_GPbased.size))); - // perform initialization on globalblkmap - for (uint32 i = 0; i < symtabsize; i++) { - sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(i); - if (!sym) { - continue; - } - if (sym->GetStorageClass() != kScGlobal && sym->GetStorageClass() != kScFstatic) { - continue; - } - } -} - -// LocateNextParm should be called with each parameter in the parameter list -// starting from the beginning, one call per parameter in sequence; it returns -// the information on how each parameter is passed in ploc -void ParmLocator::LocateNextParm(const MIRType *ty, PLocInfo &ploc) { - ploc.memoffset = maplebe::RoundUp(lastMemOffset, 8); - ploc.memsize = ty->GetSize(); - - uint32 rightpad = 0; - parmNum++; - - switch (ty->GetPrimType()) { - case PTY_u1: - case PTY_u8: - case PTY_i8: - case PTY_u16: - case PTY_i16: - rightpad = GetPrimTypeSize(PTY_i32) - ploc.memsize; - break; - case PTY_a32: - case PTY_u32: - case PTY_i32: - case PTY_a64: - case PTY_u64: - case PTY_i64: - case PTY_ptr: - case PTY_ref: -#ifdef DYNAMICLANG - case PTY_simplestr: - case PTY_simpleobj: - case PTY_dynany: - case PTY_dyni32: - case PTY_dynf64: - case PTY_dynstr: - case PTY_dynobj: - case PTY_dynundef: - case PTY_dynbool: - case PTY_dynf32: - case PTY_dynnone: - case PTY_dynnull: -#endif - break; - - case PTY_f32: - rightpad = GetPrimTypeSize(PTY_f64) - ploc.memsize; - break; - case PTY_c64: - case PTY_f64: - case PTY_v2i32: - case PTY_v4i16: - case PTY_v8i8: - case PTY_v2u32: - case PTY_v4u16: - case PTY_v8u8: - case PTY_v2f32: - break; - - case PTY_c128: - case PTY_v2i64: - case PTY_v4i32: - case PTY_v8i16: - case PTY_v16i8: - case PTY_v2u64: - case PTY_v4u32: - case PTY_v8u16: - case PTY_v16u8: - case PTY_v2f64: - case PTY_v4f32: - break; - - case PTY_agg: { - // compute rightpad - int32 paddedSize = maplebe::RoundUp(ploc.memsize, 8); - rightpad = paddedSize - ploc.memsize; - break; - } - default: - CHECK_FATAL(false, "unsupported type"); - } - - lastMemOffset = ploc.memoffset + ploc.memsize + rightpad; - return; -} - -// instantiated with the type of the function return value, it describes how -// the return value is to be passed back to the caller -ReturnMechanism::ReturnMechanism(const MIRType *retty) : fake_first_parm(false) { - switch (retty->GetPrimType()) { - case PTY_u1: - case PTY_u8: - case PTY_i8: - case PTY_u16: - case PTY_i16: - case PTY_a32: - case PTY_u32: - case PTY_i32: - case PTY_a64: - case PTY_u64: - case PTY_i64: - case PTY_f32: - case PTY_f64: -#ifdef DYNAMICLANG - case PTY_simplestr: - case PTY_simpleobj: - case PTY_dynany: - case PTY_dyni32: - case PTY_dynstr: - case PTY_dynobj: -#endif - ptype0 = retty->GetPrimType(); - return; - - case PTY_c64: - case PTY_c128: - fake_first_parm = true; - ptype0 = PTY_a32; - return; - - case PTY_agg: { - uint32 size = retty->GetSize(); - if (size > 4) { - fake_first_parm = true; - ptype0 = PTY_a32; - } else { - ptype0 = PTY_u32; - } - return; - } - - default: - return; - } } } // namespace maple diff --git a/src/mapleall/maple_me/src/me_cfg.cpp b/src/mapleall/maple_me/src/me_cfg.cpp index c1d452d10a..521cb1a944 100644 --- a/src/mapleall/maple_me/src/me_cfg.cpp +++ b/src/mapleall/maple_me/src/me_cfg.cpp @@ -260,6 +260,7 @@ bool MeCFG::FindUse(const StmtNode &stmt, StIdx stIdx) const { case OP_customcall: case OP_polymorphiccall: case OP_icall: + case OP_icallproto: case OP_intrinsiccall: case OP_xintrinsiccall: case OP_intrinsiccallwithtype: @@ -272,6 +273,7 @@ bool MeCFG::FindUse(const StmtNode &stmt, StIdx stIdx) const { case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_intrinsiccallassigned: case OP_xintrinsiccallassigned: case OP_intrinsiccallwithtypeassigned: diff --git a/src/mapleall/maple_me/src/me_function.cpp b/src/mapleall/maple_me/src/me_function.cpp index 05181df796..a62f1a89a3 100755 --- a/src/mapleall/maple_me/src/me_function.cpp +++ b/src/mapleall/maple_me/src/me_function.cpp @@ -303,7 +303,9 @@ void MeFunction::CloneBBMeStmts(BB &srcBB, BB &destBB, std::map(&stmt); newStmt = irmap->NewInPool(static_cast(icallStmt), icallStmt->GetRetTyIdx(), icallStmt->GetStmtID()); diff --git a/src/mapleall/maple_me/src/me_lower_globals.cpp b/src/mapleall/maple_me/src/me_lower_globals.cpp index c14dd5c764..fdf2df8e3f 100644 --- a/src/mapleall/maple_me/src/me_lower_globals.cpp +++ b/src/mapleall/maple_me/src/me_lower_globals.cpp @@ -185,7 +185,12 @@ void MeLowerGlobals::Run() { MeExpr *addroffuncExpr = irMap->CreateAddroffuncMeExpr(callee.GetPuidx()); auto insertpos = callStmt.GetOpnds().begin(); callStmt.InsertOpnds(insertpos, addroffuncExpr); - IcallMeStmt *icallStmt = irMap->NewInPool(stmt.GetOp() == OP_call ? OP_icall : OP_icallassigned); + IcallMeStmt *icallStmt = nullptr; + if (func.GetMIRModule().IsCModule()) { + icallStmt = irMap->NewInPool(stmt.GetOp() == OP_call ? OP_icallproto : OP_icallprotoassigned); + } else { + icallStmt = irMap->NewInPool(stmt.GetOp() == OP_call ? OP_icall : OP_icallassigned); + } icallStmt->SetIsLive(callStmt.GetIsLive()); icallStmt->SetSrcPos(callStmt.GetSrcPosition()); for (MeExpr *o : callStmt.GetOpnds()) { @@ -193,7 +198,11 @@ void MeLowerGlobals::Run() { } icallStmt->GetMuList()->insert(callStmt.GetMuList()->begin(), callStmt.GetMuList()->end()); icallStmt->GetChiList()->insert(callStmt.GetChiList()->begin(), callStmt.GetChiList()->end()); - icallStmt->SetRetTyIdx(callee.GetReturnTyIdx()); + if (func.GetMIRModule().IsCModule()) { + icallStmt->SetRetTyIdx(callee.GetMIRFuncType()->GetTypeIndex()); + } else { + icallStmt->SetRetTyIdx(callee.GetReturnTyIdx()); + } if (stmt.GetOp() != OP_call) { if (callStmt.NeedDecref()) { icallStmt->EnableNeedDecref(); diff --git a/src/mapleall/maple_me/src/me_phase_manager.cpp b/src/mapleall/maple_me/src/me_phase_manager.cpp index 09a1b64e5a..a0b5419a8e 100644 --- a/src/mapleall/maple_me/src/me_phase_manager.cpp +++ b/src/mapleall/maple_me/src/me_phase_manager.cpp @@ -140,8 +140,8 @@ bool MeFuncPM::PhaseRun(maple::MIRModule &m) { } if (genLMBC) { m.SetFlavor(kFlavorLmbc); + GlobalMemLayout globalMemLayout(&m, &m.GetMPAllocator()); maplebe::BECommon beCommon(m); - GlobalMemLayout globalMemLayout(&beCommon, &m, &m.GetMPAllocator()); maplebe::CGLowerer cgLower(m, beCommon, false, false); cgLower.RegisterBuiltIns(); cgLower.RegisterExternalLibraryFunctions(); @@ -153,14 +153,15 @@ bool MeFuncPM::PhaseRun(maple::MIRModule &m) { cgLower.LowerFunc(*func); MemPool *layoutMp = memPoolCtrler.NewMemPool("layout mempool", true); MapleAllocator layoutAlloc(layoutMp); - LMBCMemLayout localMemLayout(func, &layoutAlloc); + LMBCMemLayout localMemLayout(func, &globalMemLayout.seg_GPbased, &layoutAlloc); localMemLayout.LayoutStackFrame(); LMBCLowerer lmbcLowerer(&m, &beCommon, func, &globalMemLayout, &localMemLayout); lmbcLowerer.LowerFunction(); func->SetFrameSize(localMemLayout.StackFrameSize()); - func->SetUpFormalSize(localMemLayout.UpformalSize()); memPoolCtrler.DeleteMemPool(layoutMp); } + globalMemLayout.seg_GPbased.size = maplebe::RoundUp(globalMemLayout.seg_GPbased.size, GetPrimTypeSize(PTY_ptr)); + m.SetGlobalMemSize(globalMemLayout.seg_GPbased.size); // output .lmbc BinaryMplt binMplt(m); std::string modFileName = m.GetFileName(); diff --git a/src/mapleall/maple_me/src/me_rc_lowering.cpp b/src/mapleall/maple_me/src/me_rc_lowering.cpp index 8b3897a1c6..edf6f45509 100644 --- a/src/mapleall/maple_me/src/me_rc_lowering.cpp +++ b/src/mapleall/maple_me/src/me_rc_lowering.cpp @@ -1144,6 +1144,7 @@ void RCLowering::HandleArguments() { firstBB->InsertMeStmtBefore(firstMeStmt, incCall); } sym->SetLocalRefVar(); + mirFunc->GetFormalDefVec()[i].formalAttrs.SetAttr(ATTR_localrefvar); for (auto *stmt : rets) { std::vector opnds = { argVar }; diff --git a/src/mapleall/maple_me/src/me_rename2preg.cpp b/src/mapleall/maple_me/src/me_rename2preg.cpp index 9549dff004..eddc9704b9 100644 --- a/src/mapleall/maple_me/src/me_rename2preg.cpp +++ b/src/mapleall/maple_me/src/me_rename2preg.cpp @@ -317,6 +317,7 @@ void SSARename2Preg::Rename2PregStmt(MeStmt *stmt) { case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_intrinsiccallassigned: case OP_xintrinsiccallassigned: case OP_intrinsiccallwithtypeassigned: { diff --git a/src/mapleall/maple_me/src/me_side_effect.cpp b/src/mapleall/maple_me/src/me_side_effect.cpp index ad493a9e01..2df2f0a2c5 100644 --- a/src/mapleall/maple_me/src/me_side_effect.cpp +++ b/src/mapleall/maple_me/src/me_side_effect.cpp @@ -932,6 +932,7 @@ bool IpaSideEffect::UpdateSideEffectWithStmt(MeStmt &meStmt, case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_superclasscallassigned: case OP_asm: { hasPrivateDef = hasThrException = true; @@ -958,7 +959,8 @@ bool IpaSideEffect::UpdateSideEffectWithStmt(MeStmt &meStmt, case OP_interfaceicall: case OP_customcall: case OP_polymorphiccall: - case OP_icall: { + case OP_icall: + case OP_icallproto: { hasPrivateDef = hasThrException = true; SetHasDef(); for (size_t i = 0; i < meStmt.NumMeStmtOpnds(); ++i) { diff --git a/src/mapleall/maple_me/src/me_stmt_pre.cpp b/src/mapleall/maple_me/src/me_stmt_pre.cpp index 9e2325f142..55888c9bce 100755 --- a/src/mapleall/maple_me/src/me_stmt_pre.cpp +++ b/src/mapleall/maple_me/src/me_stmt_pre.cpp @@ -966,7 +966,9 @@ void MeStmtPre::BuildWorkListBB(BB *bb) { break; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { auto &icallMeStmt = static_cast(stmt); VersionStackChiListUpdate(*icallMeStmt.GetChiList()); break; diff --git a/src/mapleall/maple_me/src/pme_emit.cpp b/src/mapleall/maple_me/src/pme_emit.cpp index 227cb6a761..52e1df6beb 100755 --- a/src/mapleall/maple_me/src/pme_emit.cpp +++ b/src/mapleall/maple_me/src/pme_emit.cpp @@ -485,10 +485,12 @@ StmtNode* PreMeEmitter::EmitPreMeStmt(MeStmt *mestmt, BaseNode *parent) { return callnode; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { IcallMeStmt *icallMeStmt = static_cast (mestmt); IcallNode *icallnode = - codeMP->New(*codeMPAlloc, OP_icallassigned, icallMeStmt->GetRetTyIdx()); + codeMP->New(*codeMPAlloc, OP_icallprotoassigned, icallMeStmt->GetRetTyIdx()); for (uint32 i = 0; i < icallMeStmt->GetOpnds().size(); i++) { icallnode->GetNopnd().push_back(EmitPreMeExpr(icallMeStmt->GetOpnd(i), icallnode)); } @@ -509,6 +511,9 @@ StmtNode* PreMeEmitter::EmitPreMeStmt(MeStmt *mestmt, BaseNode *parent) { icallnode->SetRetTyIdx(TyIdx(preg->GetPrimType())); } } + if (mestmt->GetOp() == OP_icallproto || mestmt->GetOp() == OP_icallprotoassigned) { + icallnode->SetRetTyIdx(icallMeStmt->GetRetTyIdx()); + } icallnode->CopySafeRegionAttr(mestmt->GetStmtAttr()); icallnode->SetOriginalID(mestmt->GetOriginalId()); PreMeStmtExtensionMap[icallnode->GetStmtID()] = pmeExt; diff --git a/src/mapleall/maple_me/src/ssa_devirtual.cpp b/src/mapleall/maple_me/src/ssa_devirtual.cpp index 15a609e427..f46e8e06ce 100644 --- a/src/mapleall/maple_me/src/ssa_devirtual.cpp +++ b/src/mapleall/maple_me/src/ssa_devirtual.cpp @@ -534,7 +534,9 @@ void SSADevirtual::TraversalMeStmt(MeStmt &meStmt) { break; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { auto *icallMeStmt = static_cast(&meStmt); const MapleVector &opnds = icallMeStmt->GetOpnds(); for (size_t i = 0; i < opnds.size(); ++i) { diff --git a/src/mapleall/maple_me/src/ssa_pre.cpp b/src/mapleall/maple_me/src/ssa_pre.cpp index ceff080daa..a082b80b9f 100644 --- a/src/mapleall/maple_me/src/ssa_pre.cpp +++ b/src/mapleall/maple_me/src/ssa_pre.cpp @@ -1666,6 +1666,7 @@ void SSAPre::BuildWorkListStmt(MeStmt &stmt, uint32 seqStmt, bool isRebuilt, MeE case OP_customcall: case OP_polymorphiccall: case OP_icall: + case OP_icallproto: case OP_callassigned: case OP_virtualcallassigned: case OP_virtualicallassigned: @@ -1675,6 +1676,7 @@ void SSAPre::BuildWorkListStmt(MeStmt &stmt, uint32 seqStmt, bool isRebuilt, MeE case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_asm: { auto *naryMeStmt = static_cast(meStmt); const MapleVector &opnds = naryMeStmt->GetOpnds(); diff --git a/src/mapleall/mpl2mpl/src/constantfold.cpp b/src/mapleall/mpl2mpl/src/constantfold.cpp index 860ed2846a..d89d6ef64d 100644 --- a/src/mapleall/mpl2mpl/src/constantfold.cpp +++ b/src/mapleall/mpl2mpl/src/constantfold.cpp @@ -162,6 +162,8 @@ StmtNode *ConstantFold::Simplify(StmtNode *node) { return SimplifyNary(static_cast(node)); case OP_icall: case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: return SimplifyIcall(static_cast(node)); case OP_asm: return SimplifyAsm(static_cast(node)); @@ -2618,8 +2620,8 @@ StmtNode *ConstantFold::SimplifyIcall(IcallNode *node) { AddroffuncNode *addrofNode = static_cast(node->GetNopndAt(0)); CallNode *callNode = mirModule->CurFuncCodeMemPool()->New(*mirModule, - node->GetOpCode() == OP_icall ? OP_call : OP_callassigned); - if (node->GetOpCode() == OP_icallassigned) { + (node->GetOpCode() == OP_icall || node->GetOpCode() == OP_icallproto) ? OP_call : OP_callassigned); + if (node->GetOpCode() == OP_icallassigned || node->GetOpCode() == OP_icallprotoassigned) { callNode->SetReturnVec(node->GetReturnVec()); } callNode->SetPUIdx(addrofNode->GetPUIdx()); -- Gitee From e6fd12fb47a29dc2263b79f1beebd7ded0beba6f Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:44 -0700 Subject: [PATCH 002/124] Fred's Fixed determination logic of when there is fake parameter for returning struct, where x8 is also used to pass the fake parameter --- .../maple_be/src/cg/aarch64/aarch64_args.cpp | 4 ++-- .../src/cg/aarch64/aarch64_call_conv.cpp | 11 ++++++----- .../maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 18 ++++++++++++------ .../src/cg/aarch64/aarch64_memlayout.cpp | 4 ++-- 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index e3e84d131b..cc8b10b6c5 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -38,7 +38,7 @@ void AArch64MoveRegArgs::CollectRegisterArgs(std::map &argsL uint32 start = 0; if (numFormal) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsFirstArgReturn()) { + if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16ByteSize) { start = 1; @@ -436,7 +436,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsFirstArgReturn()) { + if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp index d9fa548174..657b838893 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp @@ -309,18 +309,18 @@ int32 AArch64CallConvImpl::LocateNextParm(MIRType &mirType, CCLocInfo &pLoc, boo if (size == 0) { /* For return struct size 0 there is no return value. */ return 0; - } else if (size > k16ByteSize) { - /* For return struct size > 16 bytes the pointer returns in x8. */ - pLoc.reg0 = R8; - return kSizeOfPtr; } + /* For return struct size > 16 bytes the pointer returns in x8. */ + pLoc.reg0 = R8; + return kSizeOfPtr; +#if 0 /* For return struct size less or equal to 16 bytes, the values * are returned in register pairs. * Check for pure float struct. */ AArch64ArgumentClass classes[kMaxRegCount] = { kAArch64NoClass }; uint32 fpSize; - MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(beCommon.GetFuncReturnType(*func)); + MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); uint32 numRegs = static_cast(ClassifyAggregate(beCommon, *retType, classes, sizeof(classes), fpSize)); if (classes[0] == kAArch64FloatClass) { CHECK_FATAL(numRegs <= kMaxRegCount, "LocateNextParm: illegal number of regs"); @@ -337,6 +337,7 @@ int32 AArch64CallConvImpl::LocateNextParm(MIRType &mirType, CCLocInfo &pLoc, boo } return 0; } +#endif } } uint64 typeSize = beCommon.GetTypeSize(mirType.GetTypeIndex()); 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 6e93060f65..a96b1dd261 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8058,6 +8058,17 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo std::set specialArgs; SelectParmListPreprocess(naryNode, i, specialArgs); bool specialArg = false; + bool firstArgReturn = false; + MIRFunction *callee = nullptr; + if (dynamic_cast(&naryNode) != nullptr) { + auto calleePuIdx = static_cast(naryNode).GetPUIdx(); + callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + firstArgReturn = callee->IsFirstArgReturn(); + } else if (naryNode.GetOpCode() == OP_icallproto) { + IcallNode *icallnode = &static_cast(naryNode); + MIRFuncType *funcType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallnode->GetRetTyIdx())); + firstArgReturn = funcType->FirstArgReturn(); + } BB *curBBrecord = GetCurBB(); BB *tmpBB = nullptr; if (!specialArgs.empty()) { @@ -8079,11 +8090,6 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); - MIRFunction *callee = nullptr; - if (dynamic_cast(&naryNode) != nullptr) { - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); - } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } @@ -8148,7 +8154,7 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo } expRegOpnd = static_cast(opnd); - if ((pnum == 0) && (SelectParmListGetStructReturnSize(naryNode) > k16ByteSize)) { + if ((pnum == 0) && firstArgReturn) { parmLocator.InitCCLocInfo(ploc); ploc.reg0 = R8; } else { diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp index 60b7462f22..bf888d5d3b 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp @@ -210,7 +210,7 @@ void AArch64MemLayout::LayoutFormalParams() { AArch64SymbolAlloc *symLoc = memAllocator->GetMemPool()->New(); SetSymAllocInfo(stIndex, *symLoc); if (i == 0) { - if (mirFunction->IsFirstArgReturn()) { + if (mirFunction->IsReturnStruct() && mirFunction->IsFirstArgReturn()) { symLoc->SetMemSegment(GetSegArgsRegPassed()); symLoc->SetOffset(GetSegArgsRegPassed().GetSize()); TyIdx tyIdx = mirFunction->GetFuncRetStructTyIdx(); @@ -395,7 +395,7 @@ void AArch64MemLayout::LayoutReturnRef(std::vector &returnDelays, void AArch64MemLayout::LayoutActualParams() { for (size_t i = 0; i < mirFunction->GetFormalCount(); ++i) { if (i == 0) { - if (mirFunction->IsReturnStruct()) { + if (mirFunction->IsReturnStruct() && mirFunction->IsFirstArgReturn()) { continue; } } -- Gitee From 61920a521a6dd1ca832f3e305d64ed4591ee8521 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:53:00 -0700 Subject: [PATCH 003/124] Remove unneeded fp def. Turn on tailcall. no unneeded pro/epilog. --- .../maple_be/include/cg/aarch64/aarch64_color_ra.h | 1 + src/mapleall/maple_be/include/cg/cgfunc.h | 9 +++++++++ .../maple_be/src/cg/aarch64/aarch64_color_ra.cpp | 6 ++++++ .../maple_be/src/cg/aarch64/aarch64_proepilog.cpp | 7 +++---- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h index 491d59453f..d0588c51c4 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h @@ -1519,6 +1519,7 @@ class GraphColorRegAllocator : public RegAllocator { #endif bool hasSpill = false; bool doMultiPass = false; + bool seenFP = false; }; class CallerSavePre: public CGPre { diff --git a/src/mapleall/maple_be/include/cg/cgfunc.h b/src/mapleall/maple_be/include/cg/cgfunc.h index a57bd11299..f79c4216df 100644 --- a/src/mapleall/maple_be/include/cg/cgfunc.h +++ b/src/mapleall/maple_be/include/cg/cgfunc.h @@ -1107,6 +1107,14 @@ class CGFunc { return useFP; } + void UnsetSeenFP() { + seenFP = false; + } + + bool SeenFP() const { + return seenFP; + } + void UpdateAllRegisterVregMapping(MapleMap &newMap); void RegisterVregMapping(regno_t vRegNum, PregIdx pidx) { @@ -1276,6 +1284,7 @@ class CGFunc { const MapleString shortFuncName; bool hasAsm = false; bool useFP = true; + bool seenFP = true; /* save stack protect kinds which can trigger stack protect */ uint8 stackProtectInfo = 0; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp index d1c6fb4a5d..d6cef630f0 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp @@ -3626,6 +3626,9 @@ RegOperand *GraphColorRegAllocator::GetReplaceOpnd(Insn &insn, const Operand &op auto ®Opnd = static_cast(opnd); uint32 vregNO = regOpnd.GetRegisterNumber(); + if (vregNO == RFP) { + seenFP = true; + } RegType regType = regOpnd.GetRegisterType(); if (vregNO < kAllRegNum) { return nullptr; @@ -4993,6 +4996,9 @@ bool GraphColorRegAllocator::AllocateRegisters() { MarkCalleeSaveRegs(); + if (seenFP == false) { + cgFunc->UnsetSeenFP(); + } if (GCRA_DUMP) { cgFunc->DumpCGIR(); } diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp index 09ee411939..7e6a33f401 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp @@ -185,9 +185,6 @@ void AArch64GenProEpilog::TailCallBBOpt(BB &bb, MapleSet &callInsns, BB & * Return value: true if function do not need Prologue/Epilogue. false otherwise. */ bool AArch64GenProEpilog::TailCallOpt() { - if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { - return false; - } /* Count how many call insns in the whole function. */ uint32 nCount = 0; bool hasGetStackClass = false; @@ -1229,7 +1226,9 @@ void AArch64GenProEpilog::GeneratePushRegs() { } else { immOpnd = &aarchCGFunc.CreateImmOperand(argsToStkPassSize, k32BitSize, true); } - aarchCGFunc.SelectAdd(fpOpnd, spOpnd, *immOpnd, PTY_u64); + if (isLmbc == false || cgFunc.SeenFP() || cgFunc.GetFunction().GetAttr(FUNCATTR_varargs)) { + aarchCGFunc.SelectAdd(fpOpnd, spOpnd, *immOpnd, PTY_u64); + } cgFunc.GetCurBB()->GetLastInsn()->SetFrameDef(true); if (cgFunc.GenCfi()) { cgFunc.GetCurBB()->AppendInsn(aarchCGFunc.CreateCfiDefCfaInsn(stackBaseReg, -- Gitee From a820271c494b1d3811d7264f3f5a59e40de283e2 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:53:14 -0700 Subject: [PATCH 004/124] Fred's Set firstarg_return attribute in the new funcAttrs field in MIRFuncType --- src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp | 3 +++ src/mapleall/maple_ir/src/mir_lower.cpp | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp b/src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp index 3a77948b15..63c34ea154 100644 --- a/src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp +++ b/src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp @@ -278,6 +278,9 @@ bool ASTFunc2FEHelper::ProcessDeclImpl(MapleAllocator &allocator) { ENCChecker::InsertBoundaryInAtts(attrs, func.GetBoundaryInfo()); mirMethodPair.second.second = attrs; mirFunc->SetFuncAttrs(attrs); + if (firstArgRet) { + mirFunc->GetMIRFuncType()->funcAttrs.SetAttr(FUNCATTR_firstarg_return); + } func.ClearGenericAttrsContentMap(); return true; } diff --git a/src/mapleall/maple_ir/src/mir_lower.cpp b/src/mapleall/maple_ir/src/mir_lower.cpp index aa5cb0131c..9b8c3f8d92 100644 --- a/src/mapleall/maple_ir/src/mir_lower.cpp +++ b/src/mapleall/maple_ir/src/mir_lower.cpp @@ -539,6 +539,10 @@ BlockNode *MIRLower::LowerBlock(BlockNode &block) { MIRFuncType *funcType = FuncTypeFromFuncPtrExpr(stmt->Opnd(0)); CHECK_FATAL(funcType != nullptr, "MIRLower::LowerBlock: cannot find prototype for icall"); ic->SetRetTyIdx(funcType->GetTypeIndex()); + MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcType->GetRetTyIdx()); + if (retType->GetPrimType() == PTY_agg && retType->GetSize() > 16) { + funcType->funcAttrs.SetAttr(FUNCATTR_firstarg_return); + } } newBlock->AddStatement(stmt); break; -- Gitee From 82c3c6110d4b10d09737193ef1013311e2b1adef Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 005/124] Changes from mplcglmbc8 and mplcglmbc9. --- src/mapleall/maple_be/include/be/lower.h | 2 +- .../include/cg/aarch64/aarch64_cgfunc.h | 30 +- .../include/cg/aarch64/aarch64_phases.def | 2 +- src/mapleall/maple_be/include/cg/call_conv.h | 20 +- src/mapleall/maple_be/include/cg/cg.h | 19 +- src/mapleall/maple_be/include/cg/cgfunc.h | 2 + src/mapleall/maple_be/src/be/lower.cpp | 82 ++- .../maple_be/src/cg/aarch64/aarch64_args.cpp | 4 +- .../src/cg/aarch64/aarch64_call_conv.cpp | 2 +- .../src/cg/aarch64/aarch64_cgfunc.cpp | 547 +++++++++++++++--- .../maple_be/src/cg/aarch64/aarch64_ebo.cpp | 4 +- .../src/cg/aarch64/aarch64_memlayout.cpp | 32 +- .../src/cg/aarch64/aarch64_offset_adjust.cpp | 2 +- .../src/cg/aarch64/aarch64_proepilog.cpp | 87 ++- .../src/cg/aarch64/aarch64_reaching.cpp | 3 +- .../maple_be/src/cg/cg_phasemanager.cpp | 1 + src/mapleall/maple_be/src/cg/cgfunc.cpp | 44 +- src/mapleall/maple_be/src/cg/emit.cpp | 5 + src/mapleall/maple_be/src/cg/memlayout.cpp | 6 +- .../maple_ir/include/bin_mpl_export.h | 28 +- .../maple_ir/include/bin_mpl_import.h | 12 +- .../maple_ir/include/ir_safe_cast_traits.def | 4 +- src/mapleall/maple_ir/include/keywords.def | 1 - src/mapleall/maple_ir/include/mir_builder.h | 2 + src/mapleall/maple_ir/include/mir_function.h | 18 +- src/mapleall/maple_ir/include/mir_lower.h | 1 + src/mapleall/maple_ir/include/mir_nodes.h | 2 +- src/mapleall/maple_ir/include/mir_parser.h | 2 +- src/mapleall/maple_ir/include/mir_symbol.h | 6 +- src/mapleall/maple_ir/include/mir_type.h | 27 +- src/mapleall/maple_ir/include/opcode_info.h | 1 + src/mapleall/maple_ir/include/opcodes.def | 1 + src/mapleall/maple_ir/include/opcodes.h | 4 +- src/mapleall/maple_ir/src/bin_func_export.cpp | 239 ++++---- src/mapleall/maple_ir/src/bin_func_import.cpp | 248 ++++---- src/mapleall/maple_ir/src/bin_mpl_export.cpp | 112 ++-- src/mapleall/maple_ir/src/bin_mpl_import.cpp | 48 +- src/mapleall/maple_ir/src/global_tables.cpp | 4 +- src/mapleall/maple_ir/src/mir_builder.cpp | 24 + src/mapleall/maple_ir/src/mir_function.cpp | 4 +- src/mapleall/maple_ir/src/mir_lower.cpp | 107 ++++ src/mapleall/maple_ir/src/mir_nodes.cpp | 4 +- src/mapleall/maple_ir/src/mir_parser.cpp | 31 +- src/mapleall/maple_ir/src/mir_type.cpp | 8 +- src/mapleall/maple_ir/src/parser.cpp | 18 +- src/mapleall/maple_me/include/lmbc_lower.h | 3 - .../maple_me/include/lmbc_memlayout.h | 59 +- src/mapleall/maple_me/src/alias_class.cpp | 8 +- src/mapleall/maple_me/src/code_factoring.cpp | 4 +- .../src/demand_driven_alias_analysis.cpp | 4 +- src/mapleall/maple_me/src/irmap_build.cpp | 7 +- src/mapleall/maple_me/src/irmap_emit.cpp | 5 +- src/mapleall/maple_me/src/lfo_dep_test.cpp | 2 + src/mapleall/maple_me/src/lmbc_lower.cpp | 258 ++------- src/mapleall/maple_me/src/lmbc_memlayout.cpp | 439 +------------- src/mapleall/maple_me/src/me_cfg.cpp | 2 + src/mapleall/maple_me/src/me_function.cpp | 4 +- .../maple_me/src/me_lower_globals.cpp | 13 +- .../maple_me/src/me_phase_manager.cpp | 7 +- src/mapleall/maple_me/src/me_rc_lowering.cpp | 1 + src/mapleall/maple_me/src/me_rename2preg.cpp | 1 + src/mapleall/maple_me/src/me_side_effect.cpp | 4 +- src/mapleall/maple_me/src/me_stmt_pre.cpp | 4 +- src/mapleall/maple_me/src/pme_emit.cpp | 9 +- src/mapleall/maple_me/src/ssa_devirtual.cpp | 4 +- src/mapleall/maple_me/src/ssa_pre.cpp | 2 + src/mapleall/mpl2mpl/src/constantfold.cpp | 6 +- 67 files changed, 1402 insertions(+), 1294 deletions(-) diff --git a/src/mapleall/maple_be/include/be/lower.h b/src/mapleall/maple_be/include/be/lower.h index f4b41219ea..ea7754a84f 100644 --- a/src/mapleall/maple_be/include/be/lower.h +++ b/src/mapleall/maple_be/include/be/lower.h @@ -187,7 +187,7 @@ class CGLowerer { void LowerTryCatchBlocks(BlockNode &body); #if TARGARM32 || TARGAARCH64 || TARGRISCV64 - BlockNode *LowerReturnStruct(NaryStmtNode &retNode); + BlockNode *LowerReturnStructUsingFakeParm(NaryStmtNode &retNode); #endif virtual BlockNode *LowerReturn(NaryStmtNode &retNode); void LowerEntry(MIRFunction &func); 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 809c8a3e14..0ab23d6f9d 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -38,6 +38,7 @@ class LmbcArgInfo { MapleVector lmbcCallArgTypes; MapleVector lmbcCallArgOffsets; MapleVector lmbcCallArgNumOfRegs; // # of regs needed to complete struct + uint32 lmbcTotalStkUsed = -1; // TBD: remove when explicit addr for large agg is available }; class AArch64CGFunc : public CGFunc { @@ -101,7 +102,7 @@ class AArch64CGFunc : public CGFunc { return kRFLAG; } - MIRType *GetAggTyFromCallSite(StmtNode *stmt); + MIRType *LmbcGetAggTyFromCallSite(StmtNode *stmt, std::vector **parmList); RegOperand &GetOrCreateResOperand(const BaseNode &parent, PrimType primType); void IntrinsifyGetAndAddInt(ListOperand &srcOpnds, PrimType pty); @@ -125,9 +126,11 @@ class AArch64CGFunc : public CGFunc { bool needLow12 = false); MemOperand *FixLargeMemOpnd(MemOperand &memOpnd, uint32 align); MemOperand *FixLargeMemOpnd(MOperator mOp, MemOperand &memOpnd, uint32 dSize, uint32 opndIdx); + uint32 LmbcFindTotalStkUsed(std::vector* paramList); + uint32 LmbcTotalRegsUsed(); void LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn); bool LmbcSmallAggForRet(BlkassignoffNode &bNode, Operand *src); - bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; void SelectIassignoff(IassignoffNode &stmt) override; @@ -135,6 +138,7 @@ class AArch64CGFunc : public CGFunc { void SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd) override; void SelectBlkassignoff(BlkassignoffNode &bNode, Operand *src) override; void SelectAggIassign(IassignNode &stmt, Operand &lhsAddrOpnd) override; + void SelectReturnSendOfStructInRegs(BaseNode *x) override; void SelectReturn(Operand *opnd0) override; void SelectIgoto(Operand *opnd0) override; void SelectCondGoto(CondGotoNode &stmt, Operand &opnd0, Operand &opnd1) override; @@ -486,7 +490,10 @@ class AArch64CGFunc : public CGFunc { void GenerateCleanupCodeForExtEpilog(BB &bb) override; uint32 FloatParamRegRequired(MIRStructType *structType, uint32 &fpSize) override; void AssignLmbcFormalParams() override; - RegOperand *GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType); + void LmbcGenSaveSpForAlloca() override; + MemOperand *GenLmbcFpMemOperand(int32 offset, uint32 byteSize, AArch64reg base = RFP); + RegOperand *GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType, AArch64reg baseRegno = RFP); + RegOperand *LmbcStructReturnLoad(int32 offset); Operand *GetBaseReg(const AArch64SymbolAlloc &symAlloc); int32 GetBaseOffset(const SymbolAlloc &symAlloc) override; @@ -726,6 +733,22 @@ class AArch64CGFunc : public CGFunc { return lmbcArgInfo->lmbcCallArgNumOfRegs; } + int32 GetLmbcTotalStkUsed() { + return lmbcArgInfo->lmbcTotalStkUsed; + } + + void SetLmbcTotalStkUsed(int32 offset) { + lmbcArgInfo->lmbcTotalStkUsed = offset; + } + + void SetLmbcCallReturnType(MIRType *ty) { + lmbcCallReturnType = ty; + } + + MIRType *GetLmbcCallReturnType() { + return lmbcCallReturnType; + } + private: enum RelationOperator : uint8 { kAND, @@ -793,6 +816,7 @@ class AArch64CGFunc : public CGFunc { regno_t methodHandleVreg = -1; uint32 alignPow = 5; /* function align pow defaults to 5 i.e. 2^5*/ LmbcArgInfo *lmbcArgInfo = nullptr; + MIRType *lmbcCallReturnType = nullptr; void SelectLoadAcquire(Operand &dest, PrimType dtype, Operand &src, PrimType stype, AArch64isa::MemoryOrdering memOrd, bool isDirect); diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def b/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def index a3a74d7b2f..ff08e81852 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def @@ -16,8 +16,8 @@ ADDTARGETPHASE("createstartendlabel", true); ADDTARGETPHASE("buildehfunc", true); ADDTARGETPHASE("handlefunction", true); + ADDTARGETPHASE("moveargs", true); if (GetMIRModule()->GetFlavor() != MIRFlavor::kFlavorLmbc) { - ADDTARGETPHASE("moveargs", true); /* SSA PHASES */ ADDTARGETPHASE("cgssaconstruct", CGOptions::DoCGSSA()); ADDTARGETPHASE("cgcopyprop", CGOptions::DoCGSSA()); diff --git a/src/mapleall/maple_be/include/cg/call_conv.h b/src/mapleall/maple_be/include/cg/call_conv.h index d7a194022c..4310cd986a 100644 --- a/src/mapleall/maple_be/include/cg/call_conv.h +++ b/src/mapleall/maple_be/include/cg/call_conv.h @@ -63,8 +63,8 @@ struct CCLocInfo { class LmbcFormalParamInfo { public: LmbcFormalParamInfo(PrimType pType, uint32 ofst, uint32 sz) : - type(nullptr), primType(pType), offset(ofst), size(sz), regNO(0), vregNO(0), numRegs(0), - fpSize(0), isReturn(false), isPureFloat(false), isOnStack(false) {} + type(nullptr), primType(pType), offset(ofst), onStackOffset(0), size(sz), regNO(0), vregNO(0), numRegs(0), + fpSize(0), isReturn(false), isPureFloat(false), isOnStack(false), hasRegassign(false) {} ~LmbcFormalParamInfo() = default; @@ -86,6 +86,12 @@ class LmbcFormalParamInfo { void SetOffset(uint32 ofs) { offset = ofs; } + uint32 GetOnStackOffset() { + return onStackOffset; + } + void SetOnStackOffset(uint32 ofs) { + onStackOffset = ofs; + } uint32 GetSize() { return size; } @@ -137,10 +143,17 @@ class LmbcFormalParamInfo { void SetIsOnStack() { isOnStack = true; } + bool HasRegassign() { + return hasRegassign; + } + void SetHasRegassign() { + hasRegassign = true; + } private: MIRStructType *type; PrimType primType; uint32 offset; + uint32 onStackOffset; /* stack location if isOnStack */ uint32 size; /* size primtype or struct */ regno_t regNO = 0; /* param reg num or starting reg num if numRegs > 0 */ regno_t vregNO = 0; /* if no explicit regassing from IR, create move from param reg */ @@ -148,7 +161,8 @@ class LmbcFormalParamInfo { uint32 fpSize = 0; /* size of fp param if isPureFloat */ bool isReturn; bool isPureFloat = false; - bool isOnStack; /* small struct with arrays need to be saved onto stack */ + bool isOnStack; /* large struct is passed by a copy on stack */ + bool hasRegassign; }; } /* namespace maplebe */ diff --git a/src/mapleall/maple_be/include/cg/cg.h b/src/mapleall/maple_be/include/cg/cg.h index 093289e42b..e1368acb1d 100644 --- a/src/mapleall/maple_be/include/cg/cg.h +++ b/src/mapleall/maple_be/include/cg/cg.h @@ -121,11 +121,13 @@ class CG { emitter(nullptr), labelOrderCnt(0), cgOption(cgOptions), - instrumentationFunction(nullptr) { + instrumentationFunction(nullptr), + fileGP(nullptr) { const std::string &internalNameLiteral = namemangler::GetInternalNameLiteral(namemangler::kJavaLangObjectStr); GStrIdx strIdxFromName = GlobalTables::GetStrTable().GetStrIdxFromName(internalNameLiteral); isLibcore = (GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdxFromName) != nullptr); DefineDebugTraceFunctions(); + isLmbc = (mirModule->GetFlavor() == MIRFlavor::kFlavorLmbc); } virtual ~CG(); @@ -361,6 +363,10 @@ class CG { return isLibcore; } + bool IsLmbc() const { + return isLmbc; + } + MIRSymbol *GetDebugTraceEnterFunction() { return dbgTraceEnter; } @@ -421,6 +427,13 @@ class CG { /* Object map generation helper */ std::vector GetReferenceOffsets64(const BECommon &beCommon, MIRStructType &structType); + void SetGP(MIRSymbol *sym) { + fileGP = sym; + } + MIRSymbol *GetGP() const { + return fileGP; + } + static bool IsInFuncWrapLabels(MIRFunction *func) { return funcWrapLabels.find(func) != funcWrapLabels.end(); } @@ -449,12 +462,14 @@ class CG { LabelIDOrder labelOrderCnt; static CGFunc *currentCGFunction; /* current cg function being compiled */ CGOptions cgOption; - bool isLibcore; MIRSymbol *instrumentationFunction; MIRSymbol *dbgTraceEnter; MIRSymbol *dbgTraceExit; MIRSymbol *dbgFuncProfile; + MIRSymbol *fileGP; /* for lmbc, one local %GP per file */ static std::map> funcWrapLabels; + bool isLibcore; + bool isLmbc; }; /* class CG */ } /* namespace maplebe */ diff --git a/src/mapleall/maple_be/include/cg/cgfunc.h b/src/mapleall/maple_be/include/cg/cgfunc.h index 20a3f4c7c2..a57bd11299 100644 --- a/src/mapleall/maple_be/include/cg/cgfunc.h +++ b/src/mapleall/maple_be/include/cg/cgfunc.h @@ -160,6 +160,7 @@ class CGFunc { virtual uint32 FloatParamRegRequired(MIRStructType *structType, uint32 &fpSize) = 0; virtual void AssignLmbcFormalParams() = 0; LmbcFormalParamInfo *GetLmbcFormalParamInfo(uint32 offset); + virtual void LmbcGenSaveSpForAlloca() = 0; void GenerateLoc(StmtNode *stmt, unsigned &lastSrcLoc, unsigned &lastMplLoc); int32 GetFreqFromStmt(uint32 stmtId); void GenerateInstruction(); @@ -201,6 +202,7 @@ class CGFunc { virtual void SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd) = 0; virtual void SelectBlkassignoff(BlkassignoffNode &bNode, Operand *src) = 0; virtual void SelectAggIassign(IassignNode &stmt, Operand &lhsAddrOpnd) = 0; + virtual void SelectReturnSendOfStructInRegs(BaseNode *x) = 0; virtual void SelectReturn(Operand *opnd) = 0; virtual void SelectIgoto(Operand *opnd0) = 0; virtual void SelectCondGoto(CondGotoNode &stmt, Operand &opnd0, Operand &opnd1) = 0; diff --git a/src/mapleall/maple_be/src/be/lower.cpp b/src/mapleall/maple_be/src/be/lower.cpp index 0f413042e6..fd103c1572 100644 --- a/src/mapleall/maple_be/src/be/lower.cpp +++ b/src/mapleall/maple_be/src/be/lower.cpp @@ -121,6 +121,7 @@ void CGLowerer::RegisterExternalLibraryFunctions() { func->AllocSymTab(); MIRSymbol *funcSym = func->GetFuncSymbol(); funcSym->SetStorageClass(kScExtern); + funcSym->SetAppearsInCode(true); /* return type */ MIRType *retTy = GlobalTables::GetTypeTable().GetPrimType(extFnDescrs[i].retType); @@ -876,7 +877,7 @@ void CGLowerer::LowerTypePtr(BaseNode &node) const { #if TARGARM32 || TARGAARCH64 || TARGRISCV64 -BlockNode *CGLowerer::LowerReturnStruct(NaryStmtNode &retNode) { +BlockNode *CGLowerer::LowerReturnStructUsingFakeParm(NaryStmtNode &retNode) { BlockNode *blk = mirModule.CurFuncCodeMemPool()->New(); for (size_t i = 0; i < retNode.GetNopndSize(); ++i) { retNode.SetOpnd(LowerExpr(retNode, *retNode.GetNopndAt(i), *blk), i); @@ -1101,7 +1102,7 @@ void CGLowerer::LowerCallStmt(StmtNode &stmt, StmtNode *&nextStmt, BlockNode &ne return; } - if ((newStmt->GetOpCode() == OP_call) || (newStmt->GetOpCode() == OP_icall)) { + if (newStmt->GetOpCode() == OP_call || newStmt->GetOpCode() == OP_icall || newStmt->GetOpCode() == OP_icallproto) { newStmt = LowerCall(static_cast(*newStmt), nextStmt, newBlk, retty, uselvar); } newStmt->SetSrcPos(stmt.GetSrcPos()); @@ -1172,7 +1173,12 @@ StmtNode *CGLowerer::GenIntrinsiccallNode(const StmtNode &stmt, PUIdx &funcCalle StmtNode *CGLowerer::GenIcallNode(PUIdx &funcCalled, IcallNode &origCall) { StmtNode *newCall = nullptr; - newCall = mirModule.GetMIRBuilder()->CreateStmtIcall(origCall.GetNopnd()); + if (origCall.GetOpCode() == OP_icallassigned) { + newCall = mirModule.GetMIRBuilder()->CreateStmtIcall(origCall.GetNopnd()); + } else { + newCall = mirModule.GetMIRBuilder()->CreateStmtIcallproto(origCall.GetNopnd()); + static_cast(newCall)->SetRetTyIdx(static_cast(origCall).GetRetTyIdx()); + } newCall->SetSrcPos(origCall.GetSrcPos()); CHECK_FATAL(newCall != nullptr, "nullptr is not expected"); funcCalled = kFuncNotFound; @@ -1373,6 +1379,7 @@ BlockNode *CGLowerer::LowerCallAssignedStmt(StmtNode &stmt, bool uselvar) { static_cast(newCall)->SetReturnVec(*p2nRets); break; } + case OP_icallprotoassigned: case OP_icallassigned: { auto &origCall = static_cast(stmt); newCall = GenIcallNode(funcCalled, origCall); @@ -1480,6 +1487,15 @@ bool CGLowerer::LowerStructReturn(BlockNode &newBlk, StmtNode *stmt, (*p2nrets)[0].first = dnodeStmt->GetStIdx(); (*p2nrets)[0].second.SetFieldID(dnodeStmt->GetFieldID()); lvar = true; + // set ATTR_firstarg_return for callee + if (stmt->GetOpCode() == OP_callassigned) { + CallNode *callNode = static_cast(stmt); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callNode->GetPUIdx()); + f->SetFirstArgReturn(); + f->GetMIRFuncType()->SetFirstArgReturn(); + } else { + // for icall, front-end already set ATTR_firstarg_return + } } else { /* struct <= 16 passed in regs lowered into call &foo regassign u64 %1 (regread u64 %%retval0) @@ -1497,13 +1513,19 @@ bool CGLowerer::LowerStructReturn(BlockNode &newBlk, StmtNode *stmt, CallNode *callStmt = mirModule.GetMIRBuilder()->CreateStmtCall(callNode->GetPUIdx(), callNode->GetNopnd()); callStmt->SetSrcPos(callNode->GetSrcPos()); newBlk.AddStatement(callStmt); - } else if (stmt->GetOpCode() == OP_icallassigned) { + } else if (stmt->GetOpCode() == OP_icallassigned || stmt->GetOpCode() == OP_icallprotoassigned) { auto *icallNode = static_cast(stmt); for (size_t i = 0; i < icallNode->GetNopndSize(); ++i) { BaseNode *newOpnd = LowerExpr(*icallNode, *icallNode->GetNopndAt(i), newBlk); icallNode->SetOpnd(newOpnd, i); } - IcallNode *icallStmt = mirModule.GetMIRBuilder()->CreateStmtIcall(icallNode->GetNopnd()); + IcallNode *icallStmt = nullptr; + if (stmt->GetOpCode() == OP_icallassigned) { + icallStmt = mirModule.GetMIRBuilder()->CreateStmtIcall(icallNode->GetNopnd()); + } else { + icallStmt = mirModule.GetMIRBuilder()->CreateStmtIcallproto(icallNode->GetNopnd()); + icallStmt->SetRetTyIdx(icallNode->GetRetTyIdx()); + } icallStmt->SetSrcPos(icallNode->GetSrcPos()); newBlk.AddStatement(icallStmt); } else { @@ -1768,6 +1790,7 @@ void CGLowerer::LowerAssertBoundary(StmtNode &stmt, BlockNode &block, BlockNode CondGotoNode *brFalseNode = mirBuilder->CreateStmtCondGoto(cond, OP_brfalse, labIdx); MIRFunction *printf = mirBuilder->GetOrCreateFunction("printf", TyIdx(PTY_i32)); + printf->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*printf->GetMIRFuncType()); MapleVector argsPrintf(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); uint32 oldTypeTableSize = GlobalTables::GetTypeTable().GetTypeTableSize(); @@ -1843,7 +1866,8 @@ BlockNode *CGLowerer::LowerBlock(BlockNode &block) { break; } case OP_callassigned: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallprotoassigned: { // pass the addr of lvar if this is a struct call assignment bool lvar = false; // nextStmt could be changed by the call to LowerStructReturn @@ -1863,6 +1887,7 @@ BlockNode *CGLowerer::LowerBlock(BlockNode &block) { case OP_intrinsiccall: case OP_call: case OP_icall: + case OP_icallproto: #if TARGARM32 || TARGAARCH64 || TARGRISCV64 || TARGX86_64 // nextStmt could be changed by the call to LowerStructReturn LowerCallStmt(*stmt, nextStmt, *newBlk); @@ -1872,8 +1897,8 @@ BlockNode *CGLowerer::LowerBlock(BlockNode &block) { break; case OP_return: { #if TARGARM32 || TARGAARCH64 || TARGRISCV64 - if (GetCurrentFunc()->IsReturnStruct()) { - newBlk->AppendStatementsFromBlock(*LowerReturnStruct(static_cast(*stmt))); + if (GetCurrentFunc()->IsFirstArgReturn() && stmt->NumOpnds() > 0) { + newBlk->AppendStatementsFromBlock(*LowerReturnStructUsingFakeParm(static_cast(*stmt))); } else { #endif NaryStmtNode *retNode = static_cast(stmt); @@ -1971,7 +1996,9 @@ void CGLowerer::SimplifyBlock(BlockNode &block) { } auto *newFunc = theMIRModule->GetMIRBuilder()->GetOrCreateFunction(asmMap.at(oldFunc->GetName()), callStmt->GetTyIdx()); - newFunc->GetFuncSymbol()->SetStorageClass(kScExtern); + MIRSymbol *funcSym = newFunc->GetFuncSymbol(); + funcSym->SetStorageClass(kScExtern); + funcSym->SetAppearsInCode(true); callStmt->SetPUIdx(newFunc->GetPuidx()); break; } @@ -2081,6 +2108,7 @@ StmtNode *CGLowerer::LowerCall( if (needCheckStore) { MIRFunction *fn = mirModule.GetMIRBuilder()->GetOrCreateFunction("MCC_Reflect_Check_Arraystore", TyIdx(PTY_void)); + fn->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); MapleVector args(mirModule.GetMIRBuilder()->GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -2107,7 +2135,7 @@ StmtNode *CGLowerer::LowerCall( } MIRType *retType = nullptr; - if (callNode.op == OP_icall) { + if (callNode.op == OP_icall || callNode.op == OP_icallproto) { if (retTy == nullptr) { return &callNode; } else { @@ -2153,7 +2181,7 @@ StmtNode *CGLowerer::LowerCall( addrofNode->SetStIdx(dsgnSt->GetStIdx()); addrofNode->SetFieldID(0); - if (callNode.op == OP_icall) { + if (callNode.op == OP_icall || callNode.op == OP_icallproto) { auto ond = callNode.GetNopnd().begin(); newNopnd.emplace_back(*ond); newNopnd.emplace_back(addrofNode); @@ -2175,7 +2203,27 @@ StmtNode *CGLowerer::LowerCall( } void CGLowerer::LowerEntry(MIRFunction &func) { + // determine if needed to insert fake parameter to return struct for current function if (func.IsReturnStruct()) { + MIRType *retType = func.GetReturnType(); +#if TARGAARCH64 + PrimType pty = IsStructElementSame(retType); + if (pty == PTY_f32 || pty == PTY_f64 || IsPrimitiveVector(pty)) { + func.SetStructReturnedInRegs(); + return; + } +#endif + if (retType->GetPrimType() != PTY_agg) { + return; + } + if (retType->GetSize() > k16ByteSize) { + func.SetFirstArgReturn(); + func.GetMIRFuncType()->SetFirstArgReturn(); + } else { + func.SetStructReturnedInRegs(); + } + } + if (func.IsFirstArgReturn() && func.GetReturnType()->GetPrimType() != PTY_void) { MIRSymbol *retSt = func.GetSymTab()->CreateSymbol(kScopeLocal); retSt->SetStorageClass(kScFormal); retSt->SetSKind(kStVar); @@ -2192,12 +2240,14 @@ void CGLowerer::LowerEntry(MIRFunction &func) { auto formal = func.GetFormal(i); formals.emplace_back(formal); } + func.SetFirstArgReturn(); beCommon.AddElementToFuncReturnType(func, func.GetReturnTyIdx()); func.UpdateFuncTypeAndFormalsAndReturnType(formals, TyIdx(PTY_void), true); auto *funcType = func.GetMIRFuncType(); ASSERT(funcType != nullptr, "null ptr check"); + funcType->SetFirstArgReturn(); beCommon.AddTypeSizeAndAlign(funcType->GetTypeIndex(), GetPrimTypeSize(funcType->GetPrimType())); } } @@ -2375,6 +2425,7 @@ MIRFunction *CGLowerer::RegisterFunctionVoidStarToVoid(BuiltinFunctionID id, con func->AllocSymTab(); MIRSymbol *funcSym = func->GetFuncSymbol(); funcSym->SetStorageClass(kScExtern); + funcSym->SetAppearsInCode(true); MIRType *argTy = GlobalTables::GetTypeTable().GetPtr(); MIRSymbol *argSt = func->GetSymTab()->CreateSymbol(kScopeLocal); argSt->SetNameStrIdx(mirBuilder->GetOrCreateStringIndex(paramName)); @@ -2416,6 +2467,7 @@ void CGLowerer::RegisterBuiltIns() { func->AllocSymTab(); MIRSymbol *funcSym = func->GetFuncSymbol(); funcSym->SetStorageClass(kScExtern); + funcSym->SetAppearsInCode(true); /* return type */ MIRType *retTy = desc.GetReturnType(); CHECK_FATAL(retTy != nullptr, "retTy should not be nullptr"); @@ -2571,6 +2623,7 @@ void CGLowerer::ProcessArrayExpr(BaseNode &expr, BlockNode &blkNode) { arrayNode.GetNopndAt(1), lenRegreadNode); CondGotoNode *brFalseNode = mirBuilder->CreateStmtCondGoto(cond, OP_brfalse, labIdx); MIRFunction *fn = mirBuilder->GetOrCreateFunction("MCC_Array_Boundary_Check", TyIdx(PTY_void)); + fn->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); MapleVector args(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -3102,6 +3155,7 @@ BaseNode *CGLowerer::LowerIntrinJavaArrayLength(const BaseNode &parent, Intrinsi MIRFunction *newFunc = mirBuilder->GetOrCreateFunction("MCC_ThrowNullArrayNullPointerException", GlobalTables::GetTypeTable().GetVoid()->GetTypeIndex()); + newFunc->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*newFunc->GetMIRFuncType()); newFunc->AllocSymTab(); MapleVector args(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -3473,6 +3527,7 @@ StmtNode *CGLowerer::LowerIntrinsicRCCall(const IntrinsiccallNode &intrincall) { if (intrinFuncIDs.find(intrinDesc) == intrinFuncIDs.end()) { /* add funcid into map */ MIRFunction *fn = mirBuilder->GetOrCreateFunction(intrinDesc->name, TyIdx(PTY_void)); + fn->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); intrinFuncIDs[intrinDesc] = fn->GetPuidx(); @@ -3501,6 +3556,7 @@ void CGLowerer::LowerArrayStore(const IntrinsiccallNode &intrincall, BlockNode & if (needCheckStore) { MIRFunction *fn = mirBuilder->GetOrCreateFunction("MCC_Reflect_Check_Arraystore", TyIdx(PTY_void)); + fn->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); MapleVector args(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -3590,6 +3646,7 @@ StmtNode *CGLowerer::LowerIntrinsiccall(IntrinsiccallNode &intrincall, BlockNode beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); st->SetFunction(fn); + st->SetAppearsInCode(true); return LowerDefaultIntrinsicCall(intrincall, *st, *fn); } @@ -3660,6 +3717,7 @@ PUIdx CGLowerer::GetBuiltinToUse(BuiltinFunctionID id) const { void CGLowerer::LowerGCMalloc(const BaseNode &node, const GCMallocNode &gcmalloc, BlockNode &blkNode, bool perm) { MIRFunction *func = mirBuilder->GetOrCreateFunction((perm ? "MCC_NewPermanentObject" : "MCC_NewObj_fixed_class"), (TyIdx)(LOWERED_PTR_TYPE)); + func->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*func->GetMIRFuncType()); func->AllocSymTab(); /* Get the classinfo */ @@ -3678,6 +3736,7 @@ void CGLowerer::LowerGCMalloc(const BaseNode &node, const GCMallocNode &gcmalloc if (classSym->GetAttr(ATTR_abstract) || classSym->GetAttr(ATTR_interface)) { MIRFunction *funcSecond = mirBuilder->GetOrCreateFunction("MCC_Reflect_ThrowInstantiationError", (TyIdx)(LOWERED_PTR_TYPE)); + funcSecond->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*funcSecond->GetMIRFuncType()); funcSecond->AllocSymTab(); BaseNode *arg = mirBuilder->CreateExprAddrof(0, *classSym); @@ -3796,6 +3855,7 @@ void CGLowerer::LowerJarrayMalloc(const StmtNode &stmt, const JarrayMallocNode & args.emplace_back(mirBuilder->CreateIntConst(0, PTY_u32)); } MIRFunction *func = mirBuilder->GetOrCreateFunction(funcName, (TyIdx)(LOWERED_PTR_TYPE)); + func->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*func->GetMIRFuncType()); func->AllocSymTab(); CallNode *callAssign = nullptr; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index e0acbe83e7..e3e84d131b 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -38,7 +38,7 @@ void AArch64MoveRegArgs::CollectRegisterArgs(std::map &argsL uint32 start = 0; if (numFormal) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsReturnStruct()) { + if (func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16ByteSize) { start = 1; @@ -436,7 +436,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsReturnStruct()) { + if (func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp index 97be7d13a6..6591367dff 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp @@ -300,7 +300,7 @@ int32 AArch64CallConvImpl::LocateNextParm(MIRType &mirType, CCLocInfo &pLoc, boo if (isFirst) { MIRFunction *func = tFunc != nullptr ? tFunc : const_cast(beCommon.GetMIRModule().CurFunction()); - if (func->IsReturnStruct()) { + if (func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); size_t size = beCommon.GetTypeSize(tyIdx); if (size == 0) { 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 79616fc979..57de84100d 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -1411,15 +1411,44 @@ void AArch64CGFunc::SelectAsm(AsmNode &node) { } void AArch64CGFunc::SelectRegassign(RegassignNode &stmt, Operand &opnd0) { + if (GetCG()->IsLmbc()) { + PrimType lhsSize = stmt.GetPrimType(); + PrimType rhsSize = stmt.Opnd(0)->GetPrimType(); + if (lhsSize != rhsSize && stmt.Opnd(0)->GetOpCode() == OP_ireadoff) { + Insn *prev = GetCurBB()->GetLastInsn(); + if (prev->GetMachineOpcode() == MOP_wldrsb || prev->GetMachineOpcode() == MOP_wldrsh) { + opnd0.SetSize(GetPrimTypeBitSize(stmt.GetPrimType())); + prev->SetMOP(prev->GetMachineOpcode() == MOP_wldrsb ? MOP_xldrsb : MOP_xldrsh); + } else if (prev->GetMachineOpcode() == MOP_wldr && stmt.GetPrimType() == PTY_i64) { + opnd0.SetSize(GetPrimTypeBitSize(stmt.GetPrimType())); + prev->SetMOP(MOP_xldrsw); + } + } + } RegOperand *regOpnd = nullptr; PregIdx pregIdx = stmt.GetRegIdx(); if (IsSpecialPseudoRegister(pregIdx)) { - regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, stmt.GetPrimType()); + if (GetCG()->IsLmbc() && stmt.GetPrimType() == PTY_agg) { + if (static_cast(opnd0).IsOfIntClass()) { + regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, PTY_i64); + } else if (opnd0.GetSize() <= k4ByteSize) { + regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, PTY_f32); + } else { + regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, PTY_f64); + } + } else { + regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, stmt.GetPrimType()); + } } else { regOpnd = &GetOrCreateVirtualRegisterOperand(GetVirtualRegNOFromPseudoRegIdx(pregIdx)); } /* look at rhs */ PrimType rhsType = stmt.Opnd(0)->GetPrimType(); + if (GetCG()->IsLmbc() && rhsType == PTY_agg) { + /* This occurs when a call returns a small struct */ + /* The subtree should already taken care of the agg type that is in excess of 8 bytes */ + rhsType = PTY_i64; + } PrimType dtype = rhsType; if (GetPrimTypeBitSize(dtype) < k32BitSize) { ASSERT(IsPrimitiveInteger(dtype), ""); @@ -1441,6 +1470,12 @@ void AArch64CGFunc::SelectRegassign(RegassignNode &stmt, Operand &opnd0) { MIRPreg *preg = GetFunction().GetPregTab()->PregFromPregIdx(pregIdx); uint32 srcBitLength = GetPrimTypeSize(preg->GetPrimType()) * kBitsPerByte; GetCurBB()->AppendInsn(GetCG()->BuildInstruction(PickStInsn(srcBitLength, stype), *regOpnd, *dest)); + } else if (regOpnd->GetRegisterNumber() == R0 || regOpnd->GetRegisterNumber() == R1) { + Insn &pseudo = GetCG()->BuildInstruction(MOP_pseudo_ret_int, *regOpnd); + GetCurBB()->AppendInsn(pseudo); + } else if (regOpnd->GetRegisterNumber() >= V0 && regOpnd->GetRegisterNumber() <= V3) { + Insn &pseudo = GetCG()->BuildInstruction(MOP_pseudo_ret_float, *regOpnd); + GetCurBB()->AppendInsn(pseudo); } } @@ -1922,15 +1957,11 @@ void AArch64CGFunc::SelectIassignoff(IassignoffNode &stmt) { SelectCopy(memOpnd, destType, srcOpnd, destType); } -void AArch64CGFunc::SelectIassignfpoff(IassignFPoffNode &stmt, Operand &opnd) { - int32 offset = stmt.GetOffset(); - PrimType primType = stmt.GetPrimType(); - uint32 bitlen = GetPrimTypeSize(primType) * kBitsPerByte; - - Operand &srcOpnd = LoadIntoRegister(opnd, primType); +MemOperand *AArch64CGFunc::GenLmbcFpMemOperand(int32 offset, uint32 byteSize, AArch64reg baseRegno) { MemOperand *memOpnd; - RegOperand *rfp = &GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); - if (offset < 0) { + RegOperand *rfp = &GetOrCreatePhysicalRegisterOperand(baseRegno, k64BitSize, kRegTyInt); + uint32 bitlen = byteSize * kBitsPerByte; + if (offset < 0 && offset < -256) { RegOperand *baseOpnd = &CreateRegisterOperandOfType(PTY_a64); ImmOperand &immOpnd = CreateImmOperand(offset, k32BitSize, true); Insn &addInsn = GetCG()->BuildInstruction(MOP_xaddrri12, *baseOpnd, *rfp, immOpnd); @@ -1942,11 +1973,45 @@ void AArch64CGFunc::SelectIassignfpoff(IassignFPoffNode &stmt, Operand &opnd) { memOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, bitlen, rfp, nullptr, offsetOpnd, nullptr); } memOpnd->SetStackMem(true); - MOperator mOp = PickStInsn(bitlen, primType); - Insn &store = GetCG()->BuildInstruction(mOp, srcOpnd, *memOpnd); - GetCurBB()->AppendInsn(store); + return memOpnd; } +void AArch64CGFunc::SelectIassignfpoff(IassignFPoffNode &stmt, Operand &opnd) { + int32 offset = stmt.GetOffset(); + PrimType primType = stmt.GetPrimType(); + MIRType *rType = GetLmbcCallReturnType(); + bool isPureFpStruct = false; + uint32 numRegs = 0; + if (rType && rType->GetPrimType() == PTY_agg && opnd.IsRegister() && static_cast(opnd).IsPhysicalRegister()) { + CHECK_FATAL(rType->GetSize() <= 16, "SelectIassignfpoff invalid agg size"); + uint32 fpSize; + numRegs = FloatParamRegRequired(static_cast(rType), fpSize); + if (numRegs) { + primType = (fpSize == k4ByteSize) ? PTY_f32 : PTY_f64; + isPureFpStruct = true; + } + } + uint32 byteSize = GetPrimTypeSize(primType); + uint32 bitlen = byteSize * kBitsPerByte; + if (isPureFpStruct) { + for (int i = 0 ; i < numRegs; ++i) { + MemOperand *memOpnd = GenLmbcFpMemOperand(offset + (i * byteSize), byteSize); + RegOperand &srcOpnd = GetOrCreatePhysicalRegisterOperand(AArch64reg(V0 + i), bitlen, kRegTyFloat); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, srcOpnd, *memOpnd); + GetCurBB()->AppendInsn(store); + } + } else { + Operand &srcOpnd = LoadIntoRegister(opnd, primType); + MemOperand *memOpnd = GenLmbcFpMemOperand(offset, byteSize); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, srcOpnd, *memOpnd); + GetCurBB()->AppendInsn(store); + } +} + +/* Load and assign to a new register. To be moved to the correct call register OR stack + location in LmbcSelectParmList */ void AArch64CGFunc::SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd) { if (GetLmbcArgInfo() == nullptr) { LmbcArgInfo *p = memPool->New(*GetFuncScopeAllocator()); @@ -1973,7 +2038,7 @@ void AArch64CGFunc::SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd } /* Search for CALL/ICALL/ICALLPROTO node, must be called from a blkassignoff node */ -MIRType *AArch64CGFunc::GetAggTyFromCallSite(StmtNode *stmt) { +MIRType *AArch64CGFunc::LmbcGetAggTyFromCallSite(StmtNode *stmt, std::vector **parmList) { for ( ; stmt != nullptr; stmt = stmt->GetNext()) { if (stmt->GetOpCode() == OP_call || stmt->GetOpCode() == OP_icallproto) { break; @@ -1986,25 +2051,20 @@ MIRType *AArch64CGFunc::GetAggTyFromCallSite(StmtNode *stmt) { if (stmt->GetOpCode() == OP_call) { CallNode *callNode = static_cast(stmt); MIRFunction *fn = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callNode->GetPUIdx()); - if (fn->IsReturnStruct()) { - ++nargs; - } if (fn->GetFormalCount() > 0) { - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fn->GetNthParamTyIdx(nargs)); + ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fn->GetFormalDefVec()[nargs].formalTyIdx); } + *parmList = &fn->GetParamTypes(); // would return null if the actual parameter is bogus } else if (stmt->GetOpCode() == OP_icallproto) { IcallNode *icallproto = static_cast(stmt); MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallproto->GetRetTyIdx()); MIRFuncType *fType = static_cast(type); - MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fType->GetRetTyIdx()); - if (retType->GetKind() == kTypeStruct) { - ++nargs; - } ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fType->GetNthParamType(nargs)); + *parmList = &fType->GetParamTypeList(); } else { CHECK_FATAL(stmt->GetOpCode() == OP_icallproto, - "GetAggTyFromCallSite:: unexpected call operator"); + "LmbcGetAggTyFromCallSite:: unexpected call operator"); } return ty; } @@ -2081,11 +2141,11 @@ bool AArch64CGFunc::LmbcSmallAggForRet(BlkassignoffNode &bNode, Operand *src) { } /* return true if blkassignoff for return, false otherwise */ -bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src) { +bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList) { AArch64reg regno = static_cast(static_cast(src)->GetRegisterNumber()); if (IsBlkassignForPush(bNode)) { PrimType pTy = PTY_i64; - MIRStructType *ty = static_cast(GetAggTyFromCallSite(&bNode)); + MIRStructType *ty = static_cast(LmbcGetAggTyFromCallSite(&bNode, parmList)); uint32 size = 0; uint32 fpregs = ty ? FloatParamRegRequired(ty, size) : 0; /* fp size determined */ if (fpregs > 0) { @@ -2096,7 +2156,7 @@ bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src) { MemOperand &mem = CreateMemOpnd(regno, s, size * kBitsPerByte); RegOperand *res = &CreateVirtualRegisterOperand(NewVReg(kRegTyFloat, size)); SelectCopy(*res, pTy, mem, pTy); - SetLmbcArgInfo(res, pTy, bNode.offset + s, fpregs); + SetLmbcArgInfo(res, pTy, 0, fpregs); IncLmbcArgsInRegs(kRegTyFloat); } IncLmbcTotalArgs(); @@ -2137,6 +2197,41 @@ bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src) { return false; } +/* This function is incomplete and may be removed when Lmbc IR is changed + to have the lowerer figures out the address of the large agg to reside */ +uint32 AArch64CGFunc::LmbcFindTotalStkUsed(std::vector *paramList) { + AArch64CallConvImpl parmlocator(GetBecommon()); + CCLocInfo pLoc; + for (TyIdx tyIdx : *paramList) { + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); + parmlocator.LocateNextParm(*ty, pLoc); + } + return 0; +} + +/* All arguments passed as registers */ +uint32 AArch64CGFunc::LmbcTotalRegsUsed() { + if (GetLmbcArgInfo() == nullptr) { + return 0; /* no arg */ + } + MapleVector ®s = GetLmbcCallArgNumOfRegs(); + MapleVector &types = GetLmbcCallArgTypes(); + uint32 iCnt = 0; + uint32 fCnt = 0; + for (uint32 i = 0; i < regs.size(); i++) { + if (IsPrimitiveInteger(types[i])) { + if ((iCnt + regs[i]) <= k8ByteSize) { + iCnt += regs[i]; + }; + } else { + if ((fCnt + regs[i]) <= k8ByteSize) { + fCnt += regs[i]; + }; + } + } + return iCnt + fCnt; +} + /* If blkassignoff for argument, this function loads the agg arguments into virtual registers, disregard if there is sufficient physicall call registers. Argument > 16-bytes are copied to preset space and ptr @@ -2145,29 +2240,40 @@ bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src) { void AArch64CGFunc::SelectBlkassignoff(BlkassignoffNode &bNode, Operand *src) { CHECK_FATAL(src->GetKind() == Operand::kOpdRegister, "blkassign src type not in register"); + std::vector *parmList; if (GetLmbcArgInfo() == nullptr) { LmbcArgInfo *p = memPool->New(*GetFuncScopeAllocator()); SetLmbcArgInfo(p); } if (LmbcSmallAggForRet(bNode, src)) { return; - } else if (LmbcSmallAggForCall(bNode, src)) { + } else if (LmbcSmallAggForCall(bNode, src, &parmList)) { return; } - /* memcpy for agg assign OR large agg for arg/ret */ Operand *dest = HandleExpr(bNode, *bNode.Opnd(0)); RegOperand *regResult = &CreateVirtualRegisterOperand(NewVReg(kRegTyInt, k8ByteSize)); + /* memcpy for agg assign OR large agg for arg/ret */ + int32 offset = bNode.offset; + if (IsBlkassignForPush(bNode)) { + /* large agg for call, addr to be pushed in SelectCall */ + offset = GetLmbcTotalStkUsed(); + if (offset < 0) { + /* length of ALL stack based args for this call, this location is where the + next large agg resides, its addr will then be passed */ + offset = LmbcFindTotalStkUsed(parmList) + LmbcTotalRegsUsed(); + } + SetLmbcTotalStkUsed(offset + bNode.blockSize); /* next use */ + SetLmbcArgInfo(regResult, PTY_i64, 0, 1); /* 1 reg for ptr */ + IncLmbcArgsInRegs(kRegTyInt); + IncLmbcTotalArgs(); + /* copy large agg arg to offset below */ + } std::vector opndVec; opndVec.push_back(regResult); /* result */ - opndVec.push_back(PrepareMemcpyParamOpnd(bNode.offset, *dest));/* param 0 */ + opndVec.push_back(PrepareMemcpyParamOpnd(offset, *dest)); /* param 0 */ opndVec.push_back(src); /* param 1 */ opndVec.push_back(PrepareMemcpyParamOpnd(bNode.blockSize));/* param 2 */ SelectLibCall("memcpy", opndVec, PTY_a64, PTY_a64); - if (IsBlkassignForPush(bNode)) { - SetLmbcArgInfo(static_cast(src), PTY_i64, (int32)bNode.offset, 1); - IncLmbcArgsInRegs(kRegTyInt); - IncLmbcTotalArgs(); - } } void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { @@ -2554,6 +2660,159 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { } } +void AArch64CGFunc::SelectReturnSendOfStructInRegs(BaseNode *x) { + uint32 offset = 0; + if (x->GetOpCode() == OP_dread) { + DreadNode *dread = static_cast(x); + MIRSymbol *sym = GetFunction().GetLocalOrGlobalSymbol(dread->GetStIdx()); + MIRType *mirType = sym->GetType(); + if (dread->GetFieldID() != 0) { + MIRStructType *structType = static_cast(mirType); + mirType = structType->GetFieldType(dread->GetFieldID()); + offset = static_cast(GetBecommon().GetFieldOffset(*structType, dread->GetFieldID()).first); + } + uint32 typeSize = GetBecommon().GetTypeSize(mirType->GetTypeIndex()); + /* generate move to regs for agg return */ + AArch64CallConvImpl parmlocator(GetBecommon()); + CCLocInfo pLoc; + parmlocator.LocateNextParm(*mirType, pLoc, true, GetBecommon().GetMIRModule().CurFunction()); + /* aggregates are 8 byte aligned. */ + Operand *rhsmemopnd = nullptr; + RegOperand *result[kFourRegister]; /* up to 2 int or 4 fp */ + uint32 loadSize; + uint32 numRegs; + RegType regType; + PrimType retPty; + bool fpParm = false; + if (pLoc.numFpPureRegs) { + loadSize = pLoc.fpSize; + numRegs = pLoc.numFpPureRegs; + fpParm = true; + regType = kRegTyFloat; + retPty = (pLoc.fpSize == k4ByteSize) ? PTY_f32 : PTY_f64; + } else { + if (CGOptions::IsBigEndian()) { + loadSize = k8ByteSize; + numRegs = (typeSize <= k8ByteSize) ? kOneRegister : kTwoRegister; + regType = kRegTyInt; + retPty = PTY_u64; + } else { + loadSize = (typeSize <= k4ByteSize) ? k4ByteSize : k8ByteSize; + numRegs = (typeSize <= k8ByteSize) ? kOneRegister : kTwoRegister; + regType = kRegTyInt; + retPty = PTY_u32; + } + } + bool parmCopy = IsParamStructCopy(*sym); + for (uint32 i = 0; i < numRegs; i++) { + if (parmCopy) { + rhsmemopnd = &LoadStructCopyBase(*sym, + (offset + static_cast(i * (fpParm ? loadSize : k8ByteSize))), + static_cast(loadSize * kBitsPerByte)); + } else { + rhsmemopnd = &GetOrCreateMemOpnd(*sym, + (offset + static_cast(i * (fpParm ? loadSize : k8ByteSize))), + (loadSize * kBitsPerByte)); + } + result[i] = &CreateVirtualRegisterOperand(NewVReg(regType, loadSize)); + MOperator mop1 = PickLdInsn(loadSize * kBitsPerByte, retPty); + Insn &ld = GetCG()->BuildInstruction(mop1, *(result[i]), *rhsmemopnd); + GetCurBB()->AppendInsn(ld); + } + AArch64reg regs[kFourRegister]; + regs[0] = static_cast(pLoc.reg0); + regs[1] = static_cast(pLoc.reg1); + regs[2] = static_cast(pLoc.reg2); + regs[3] = static_cast(pLoc.reg3); + RegOperand *dest; + for (uint32 i = 0; i < numRegs; i++) { + AArch64reg preg; + MOperator mop2; + if (fpParm) { + preg = regs[i]; + mop2 = (loadSize == k4ByteSize) ? MOP_xvmovs : MOP_xvmovd; + } else { + preg = (i == 0 ? R0 : R1); + mop2 = (loadSize == k4ByteSize) ? MOP_wmovrr : MOP_xmovrr; + } + dest = &GetOrCreatePhysicalRegisterOperand(preg, (loadSize * kBitsPerByte), regType); + Insn &mov = GetCG()->BuildInstruction(mop2, *dest, *(result[i])); + GetCurBB()->AppendInsn(mov); + } + /* Create artificial dependency to extend the live range */ + for (uint32 i = 0; i < numRegs; i++) { + AArch64reg preg; + MOperator mop3; + if (fpParm) { + preg = regs[i]; + mop3 = MOP_pseudo_ret_float; + } else { + preg = (i == 0 ? R0 : R1); + mop3 = MOP_pseudo_ret_int; + } + dest = &GetOrCreatePhysicalRegisterOperand(preg, loadSize * kBitsPerByte, regType); + Insn &pseudo = GetCG()->BuildInstruction(mop3, *dest); + GetCurBB()->AppendInsn(pseudo); + } + return; + } else if (x->GetOpCode() == OP_iread) { + IreadNode *iread = static_cast(x); + RegOperand *rhsAddrOpnd = static_cast(HandleExpr(*iread, *iread->Opnd(0))); + rhsAddrOpnd = &LoadIntoRegister(*rhsAddrOpnd, iread->Opnd(0)->GetPrimType()); + MIRPtrType *ptrType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread->GetTyIdx())); + MIRType *mirType = static_cast(ptrType->GetPointedType()); + bool isRefField = false; + if (iread->GetFieldID() != 0) { + MIRStructType *structType = static_cast(mirType); + mirType = structType->GetFieldType(iread->GetFieldID()); + offset = static_cast(GetBecommon().GetFieldOffset(*structType, iread->GetFieldID()).first); + isRefField = GetBecommon().IsRefField(*structType, iread->GetFieldID()); + } + uint32 typeSize = GetBecommon().GetTypeSize(mirType->GetTypeIndex()); + /* generate move to regs. */ + RegOperand *result[kTwoRegister]; /* maximum 16 bytes, 2 registers */ + uint32 loadSize; + if (CGOptions::IsBigEndian()) { + loadSize = k8ByteSize; + } else { + loadSize = (typeSize <= k4ByteSize) ? k4ByteSize : k8ByteSize; + } + uint32 numRegs = (typeSize <= k8ByteSize) ? kOneRegister : kTwoRegister; + for (uint32 i = 0; i < numRegs; i++) { + OfstOperand *rhsOffOpnd = &GetOrCreateOfstOpnd(offset + i * loadSize, loadSize * kBitsPerByte); + Operand &rhsmemopnd = GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, loadSize * kBitsPerByte, + rhsAddrOpnd, nullptr, rhsOffOpnd, nullptr); + result[i] = &CreateVirtualRegisterOperand(NewVReg(kRegTyInt, loadSize)); + MOperator mop1 = PickLdInsn(loadSize * kBitsPerByte, PTY_u32); + Insn &ld = GetCG()->BuildInstruction(mop1, *(result[i]), rhsmemopnd); + ld.MarkAsAccessRefField(isRefField); + GetCurBB()->AppendInsn(ld); + } + RegOperand *dest; + for (uint32 i = 0; i < numRegs; i++) { + AArch64reg preg = (i == 0 ? R0 : R1); + dest = &GetOrCreatePhysicalRegisterOperand(preg, loadSize * kBitsPerByte, kRegTyInt); + Insn &mov = GetCG()->BuildInstruction(MOP_xmovrr, *dest, *(result[i])); + GetCurBB()->AppendInsn(mov); + } + /* Create artificial dependency to extend the live range */ + for (uint32 i = 0; i < numRegs; i++) { + AArch64reg preg = (i == 0 ? R0 : R1); + dest = &GetOrCreatePhysicalRegisterOperand(preg, loadSize * kBitsPerByte, kRegTyInt); + Insn &pseudo = cg->BuildInstruction(MOP_pseudo_ret_int, *dest); + GetCurBB()->AppendInsn(pseudo); + } + return; + } else { // dummy return of 0 inserted by front-end at absence of return + ASSERT(x->GetOpCode() == OP_constval, "SelectReturnSendOfStructInRegs: unexpected return operand"); + uint32 typeSize = GetPrimTypeSize(x->GetPrimType()); + RegOperand &dest = GetOrCreatePhysicalRegisterOperand(R0, typeSize * kBitsPerByte, kRegTyInt); + ImmOperand &src = CreateImmOperand(0, k16BitSize, false); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_xmovri32, dest, src)); + return; + } +} + Operand *AArch64CGFunc::SelectDread(const BaseNode &parent, DreadNode &expr) { MIRSymbol *symbol = GetFunction().GetLocalOrGlobalSymbol(expr.GetStIdx()); if (symbol->IsEhIndex()) { @@ -2917,31 +3176,50 @@ Operand *AArch64CGFunc::SelectIreadoff(const BaseNode &parent, IreadoffNode &ire return result; } -RegOperand *AArch64CGFunc::GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType) { - MemOperand *memOpnd; - RegOperand *rfp = &GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); - uint32 bitlen = byteSize * kBitsPerByte; - if (offset < 0) { - RegOperand *baseOpnd = &CreateRegisterOperandOfType(PTY_a64); - ImmOperand &immOpnd = CreateImmOperand(offset, k32BitSize, true); - Insn &addInsn = GetCG()->BuildInstruction(MOP_xaddrri12, *baseOpnd, *rfp, immOpnd); - GetCurBB()->AppendInsn(addInsn); - OfstOperand *offsetOpnd = &CreateOfstOpnd(0, k32BitSize); - memOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, bitlen, baseOpnd, - nullptr, offsetOpnd, nullptr); - } else { - OfstOperand *offsetOpnd = &CreateOfstOpnd(offset, k32BitSize); - memOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, bitlen, rfp, - nullptr, offsetOpnd, nullptr); - } - memOpnd->SetStackMem(true); +RegOperand *AArch64CGFunc::GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType, + AArch64reg baseRegno) { + MemOperand *memOpnd = GenLmbcFpMemOperand(offset, byteSize, baseRegno); RegOperand *result = &GetOrCreateVirtualRegisterOperand(NewVReg(regType, byteSize)); - MOperator mOp = PickLdInsn(bitlen, primType); + MOperator mOp = PickLdInsn(byteSize * kBitsPerByte, primType); Insn &load = GetCG()->BuildInstruction(mOp, *result, *memOpnd); GetCurBB()->AppendInsn(load); return result; } +RegOperand *AArch64CGFunc::LmbcStructReturnLoad(int32 offset) { + RegOperand *result = nullptr; + MIRFunction &func = GetFunction(); + CHECK_FATAL(func.IsReturnStruct(), "LmbcStructReturnLoad: not struct return"); + MIRType *ty = func.GetReturnType(); + uint32 sz = GetBecommon().GetTypeSize(ty->GetTypeIndex()); + uint32 fpSize; + uint32 numFpRegs = FloatParamRegRequired(static_cast(ty), fpSize); + if (numFpRegs > 0) { + PrimType pType = (fpSize <= k4ByteSize) ? PTY_f32 : PTY_f64; + for (int32 i = (numFpRegs - kOneRegister); i > 0; --i) { + result = GenLmbcParamLoad(offset + (i * fpSize), fpSize, kRegTyFloat, pType); + AArch64reg regNo = static_cast(V0 + i); + RegOperand *reg = &GetOrCreatePhysicalRegisterOperand(regNo, fpSize * kBitsPerByte, kRegTyFloat); + SelectCopy(*reg, pType, *result, pType); + Insn &pseudo = GetCG()->BuildInstruction(MOP_pseudo_ret_float, *reg); + GetCurBB()->AppendInsn(pseudo); + } + result = GenLmbcParamLoad(offset, fpSize, kRegTyFloat, pType); + } else if (sz <= k4ByteSize) { + result = GenLmbcParamLoad(offset, k4ByteSize, kRegTyInt, PTY_u32); + } else if (sz <= k8ByteSize) { + result = GenLmbcParamLoad(offset, k8ByteSize, kRegTyInt, PTY_i64); + } else if (sz <= k16ByteSize) { + result = GenLmbcParamLoad(offset + k8ByteSize, k8ByteSize, kRegTyInt, PTY_i64); + RegOperand *r1 = &GetOrCreatePhysicalRegisterOperand(R1, k8ByteSize * kBitsPerByte, kRegTyInt); + SelectCopy(*r1, PTY_i64, *result, PTY_i64); + Insn &pseudo = GetCG()->BuildInstruction(MOP_pseudo_ret_int, *r1); + GetCurBB()->AppendInsn(pseudo); + result = GenLmbcParamLoad(offset, k8ByteSize, kRegTyInt, PTY_i64); + } + return result; +} + Operand *AArch64CGFunc::SelectIreadfpoff(const BaseNode &parent, IreadFPoffNode &ireadoff) { int32 offset = ireadoff.GetOffset(); PrimType primType = ireadoff.GetPrimType(); @@ -2952,19 +3230,32 @@ Operand *AArch64CGFunc::SelectIreadfpoff(const BaseNode &parent, IreadFPoffNode if (offset >= 0) { LmbcFormalParamInfo *info = GetLmbcFormalParamInfo(offset); if (info->GetPrimType() == PTY_agg) { - result = GenLmbcParamLoad(offset, bytelen, regty, primType); + if (info->IsOnStack()) { + result = GenLmbcParamLoad(info->GetOnStackOffset(), GetPrimTypeSize(PTY_a64), kRegTyInt, PTY_a64); + regno_t baseRegno = result->GetRegisterNumber(); + result = GenLmbcParamLoad(offset - info->GetOffset(), bytelen, regty, primType, (AArch64reg)baseRegno); + } else if (primType == PTY_agg) { + CHECK_FATAL(parent.GetOpCode() == OP_regassign, "SelectIreadfpoff of agg"); + result = LmbcStructReturnLoad(offset); + } else { + result = GenLmbcParamLoad(offset, bytelen, regty, primType); + } } else { CHECK_FATAL(primType == info->GetPrimType(), "Incorrect primtype"); CHECK_FATAL(offset == info->GetOffset(), "Incorrect offset"); - if (info->GetRegNO() == 0) { - /* TODO : follow lmbc sp offset for now */ + if (info->GetRegNO() == 0 || info->HasRegassign() == false) { result = GenLmbcParamLoad(offset, bytelen, regty, primType); } else { result = &GetOrCreatePhysicalRegisterOperand((AArch64reg)(info->GetRegNO()), bitlen, regty); } } } else { - result = GenLmbcParamLoad(offset, bytelen, regty, primType); + if (primType == PTY_agg) { + CHECK_FATAL(parent.GetOpCode() == OP_regassign, "SelectIreadfpoff of agg"); + result = LmbcStructReturnLoad(offset); + } else { + result = GenLmbcParamLoad(offset, bytelen, regty, primType); + } } return result; } @@ -5761,6 +6052,9 @@ Operand *AArch64CGFunc::SelectAlloca(UnaryNode &node, Operand &opnd0) { if (!CGOptions::IsArm64ilp32()) { ASSERT((node.GetPrimType() == PTY_a64), "wrong type"); } + if (GetCG()->IsLmbc()) { + SetHasVLAOrAlloca(true); + } PrimType stype = node.Opnd(0)->GetPrimType(); Operand *resOpnd = &opnd0; if (GetPrimTypeBitSize(stype) < GetPrimTypeBitSize(PTY_u64)) { @@ -5776,10 +6070,13 @@ Operand *AArch64CGFunc::SelectAlloca(UnaryNode &node, Operand &opnd0) { SelectShift(aliOp, aliOp, shifOpnd, kShiftLeft, PTY_u64); Operand &spOpnd = GetOrCreatePhysicalRegisterOperand(RSP, k64BitSize, kRegTyInt); SelectSub(spOpnd, spOpnd, aliOp, PTY_u64); - int64 argsToStkpassSize = GetMemlayout()->SizeOfArgsToStackPass(); - if (argsToStkpassSize > 0) { + int64 allocaOffset = GetMemlayout()->SizeOfArgsToStackPass(); + if (GetCG()->IsLmbc()) { + allocaOffset -= kDivide2 * k8ByteSize; + } + if (allocaOffset > 0) { RegOperand &resallo = CreateRegisterOperandOfType(PTY_u64); - SelectAdd(resallo, spOpnd, CreateImmOperand(argsToStkpassSize, k64BitSize, true), PTY_u64); + SelectAdd(resallo, spOpnd, CreateImmOperand(allocaOffset, k64BitSize, true), PTY_u64); return &resallo; } else { return &SelectCopy(spOpnd, PTY_u64, PTY_u64); @@ -6221,6 +6518,15 @@ void AArch64CGFunc::AssignLmbcFormalParams() { param->SetRegNO(0); } else { param->SetRegNO(intReg); + if (param->HasRegassign() == false) { + uint32 bytelen = GetPrimTypeSize(primType); + uint32 bitlen = bytelen * kBitsPerByte; + MemOperand *mOpnd = GenLmbcFpMemOperand(offset, bytelen); + RegOperand &src = GetOrCreatePhysicalRegisterOperand(AArch64reg(intReg), bitlen, kRegTyInt); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, src, *mOpnd); + GetCurBB()->AppendInsn(store); + } intReg++; } } else if (IsPrimitiveFloat(primType)) { @@ -6228,6 +6534,15 @@ void AArch64CGFunc::AssignLmbcFormalParams() { param->SetRegNO(0); } else { param->SetRegNO(fpReg); + if (param->HasRegassign() == false) { + uint32 bytelen = GetPrimTypeSize(primType); + uint32 bitlen = bytelen * kBitsPerByte; + MemOperand *mOpnd = GenLmbcFpMemOperand(offset, bytelen); + RegOperand &src = GetOrCreatePhysicalRegisterOperand(AArch64reg(fpReg), bitlen, kRegTyFloat); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, src, *mOpnd); + GetCurBB()->AppendInsn(store); + } fpReg++; } } else if (primType == PTY_agg) { @@ -6246,6 +6561,14 @@ void AArch64CGFunc::AssignLmbcFormalParams() { } else { param->SetRegNO(intReg); param->SetIsOnStack(); + param->SetOnStackOffset((intReg - R0 + fpReg - V0) * k8ByteSize); + uint32 bytelen = GetPrimTypeSize(PTY_a64); + uint32 bitlen = bytelen * kBitsPerByte; + MemOperand *mOpnd = GenLmbcFpMemOperand(param->GetOnStackOffset(), bytelen); + RegOperand &src = GetOrCreatePhysicalRegisterOperand(AArch64reg(intReg), bitlen, kRegTyInt); + MOperator mOp = PickStInsn(bitlen, PTY_a64); + Insn &store = GetCG()->BuildInstruction(mOp, src, *mOpnd); + GetCurBB()->AppendInsn(store); intReg++; } } else if (param->GetSize() <= k8ByteSize) { @@ -6291,7 +6614,6 @@ void AArch64CGFunc::AssignLmbcFormalParams() { Operand *memOpd = &CreateMemOpnd(RFP, offset + (i * rSize), rSize); GetCurBB()->AppendInsn(GetCG()->BuildInstruction( PickStInsn(rSize * kBitsPerByte, pType), dest, *memOpd)); - param->SetIsOnStack(); } } } else { @@ -6300,6 +6622,22 @@ void AArch64CGFunc::AssignLmbcFormalParams() { } } +void AArch64CGFunc::LmbcGenSaveSpForAlloca() { + if (GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc || HasVLAOrAlloca() == false) { + return; + } + Operand &spOpnd = GetOrCreatePhysicalRegisterOperand(RSP, k64BitSize, kRegTyInt); + RegOperand &spSaveOpnd = CreateVirtualRegisterOperand(NewVReg(kRegTyInt, kSizeOfPtr)); + Insn &save = GetCG()->BuildInstruction(MOP_xmovrr, spSaveOpnd, spOpnd); + GetFirstBB()->AppendInsn(save); + //save.SetFrameDef(true); + for (auto *retBB : GetExitBBsVec()) { + Insn &restore = GetCG()->BuildInstruction(MOP_xmovrr, spOpnd, spSaveOpnd); + retBB->AppendInsn(restore); + restore.SetFrameDef(true); + } +} + /* if offset < 0, allocation; otherwise, deallocation */ MemOperand &AArch64CGFunc::CreateCallFrameOperand(int32 offset, int32 size) { MemOperand *memOpnd = CreateStackMemOpnd(RSP, offset, size); @@ -7585,6 +7923,10 @@ size_t AArch64CGFunc::SelectParmListGetStructReturnSize(StmtNode &naryNode) { CallNode &callNode = static_cast(naryNode); MIRFunction *callFunc = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callNode.GetPUIdx()); TyIdx retIdx = callFunc->GetReturnTyIdx(); + if (callFunc->IsFirstArgReturn()) { + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(callFunc->GetFormalDefVec()[0].formalTyIdx); + return GetBecommon().GetTypeSize(static_cast(ty)->GetPointedTyIdx()); + } size_t retSize = GetBecommon().GetTypeSize(retIdx.GetIdx()); if ((retSize == 0) && callFunc->IsReturnStruct()) { TyIdx tyIdx = callFunc->GetFuncRetStructTyIdx(); @@ -7601,6 +7943,14 @@ size_t AArch64CGFunc::SelectParmListGetStructReturnSize(StmtNode &naryNode) { return GetBecommon().GetTypeSize(sym->GetTyIdx().GetIdx()); } } + } else if (naryNode.GetOpCode() == OP_icallproto) { + IcallNode &icallProto = static_cast(naryNode); + MIRFuncType *funcTy = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallProto.GetRetTyIdx())); + if (funcTy->FirstArgReturn()) { + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcTy->GetNthParamType(0)); + return GetBecommon().GetTypeSize(static_cast(ty)->GetPointedTyIdx()); + } + return GetBecommon().GetTypeSize(funcTy->GetRetTyIdx()); } return 0; } @@ -7708,7 +8058,7 @@ void AArch64CGFunc::SelectParmListPreprocess(const StmtNode &naryNode, size_t st */ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bool isCallNative) { size_t i = 0; - if ((naryNode.GetOpCode() == OP_icall) || isCallNative) { + if (naryNode.GetOpCode() == OP_icall || naryNode.GetOpCode() == OP_icallproto || isCallNative) { i++; } std::set specialArgs; @@ -7735,8 +8085,11 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - auto *callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + MIRFunction *callee = nullptr; + if (dynamic_cast(&naryNode) != nullptr) { + auto calleePuIdx = static_cast(naryNode).GetPUIdx(); + callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } @@ -8259,7 +8612,18 @@ void AArch64CGFunc::SelectCall(CallNode &callNode) { ListOperand *srcOpnds = CreateListOpnd(*GetFuncScopeAllocator()); if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { - LmbcSelectParmList(srcOpnds, fn->IsFirstArgReturn()); + SetLmbcCallReturnType(nullptr); + bool largeStructRet = false; + if (fn->IsFirstArgReturn()) { + MIRPtrType *ptrTy = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(fn->GetFormalDefVec()[0].formalTyIdx)); + MIRType *sTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ptrTy->GetPointedTyIdx()); + largeStructRet = sTy->GetSize() > k16ByteSize; + SetLmbcCallReturnType(sTy); + } else { + MIRType *ty = fn->GetReturnType(); + SetLmbcCallReturnType(ty); + } + LmbcSelectParmList(srcOpnds, largeStructRet); } bool callNative = false; if ((fsym->GetName() == "MCC_CallFastNative") || (fsym->GetName() == "MCC_CallFastNativeExt") || @@ -8335,11 +8699,21 @@ void AArch64CGFunc::SelectCall(CallNode &callNode) { void AArch64CGFunc::SelectIcall(IcallNode &icallNode, Operand &srcOpnd) { ListOperand *srcOpnds = CreateListOpnd(*GetFuncScopeAllocator()); - if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { - LmbcSelectParmList(srcOpnds, false /*fType->GetRetAttrs().GetAttr(ATTR_firstarg_return)*/); - } else { +// if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { +// /* icallproto */ +// MIRType *retTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallNode.GetRetTyIdx()); +// MIRFuncType *funcTy = static_cast(retTy); +// bool largeStructRet = false; +// if (funcTy->FirstArgReturn()) { +// TyIdx idx = funcTy->GetNthParamType(0); +// MIRPtrType *ptrTy = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(idx)); +// MIRType *sTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ptrTy->GetPointedTyIdx()); +// largeStructRet = sTy->GetSize() > k16ByteSize; +// } +// LmbcSelectParmList(srcOpnds, largeStructRet); +// } else { SelectParmList(icallNode, *srcOpnds); - } +// } Operand *fptrOpnd = &srcOpnd; if (fptrOpnd->GetKind() != Operand::kOpdRegister) { @@ -8350,7 +8724,7 @@ void AArch64CGFunc::SelectIcall(IcallNode &icallNode, Operand &srcOpnd) { RegOperand *regOpnd = static_cast(fptrOpnd); Insn &callInsn = GetCG()->BuildInstruction(MOP_xblr, *regOpnd, *srcOpnds); - MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallNode.GetRetTyIdx()); + MIRType *retType = icallNode.GetCallReturnType(); if (retType != nullptr) { callInsn.SetRetSize(static_cast(retType->GetSize())); callInsn.SetIsCallReturnUnsigned(IsUnsignedInteger(retType->GetPrimType())); @@ -8463,9 +8837,18 @@ RegOperand &AArch64CGFunc::GetOrCreateSpecialRegisterOperand(PregIdx sregIdx, Pr case kSregFp: reg = RFP; break; - case kSregGp: - reg = RFP; - break; + case kSregGp: { + MIRSymbol *sym = GetCG()->GetGP(); + if (sym == nullptr) { + sym = GetFunction().GetSymTab()->CreateSymbol(kScopeLocal); + std::string strBuf("__file__local__GP"); + sym->SetNameStrIdx(GetMirModule().GetMIRBuilder()->GetOrCreateStringIndex(strBuf)); + GetCG()->SetGP(sym); + } + RegOperand &result = GetOrCreateVirtualRegisterOperand(NewVReg(kRegTyInt, k8ByteSize)); + SelectAddrof(result, CreateStImmOperand(*sym, 0, 0)); + return result; + } case kSregThrownval: { /* uses x0 == R0 */ ASSERT(uCatch.regNOCatch > 0, "regNOCatch should greater than 0."); if (Globals::GetInstance()->GetOptimLevel() == 0) { @@ -9202,6 +9585,9 @@ int32 AArch64CGFunc::GetBaseOffset(const SymbolAlloc &sa) { int32 baseOffset = symAlloc->GetOffset(); return baseOffset + sizeofFplr; } else if (sgKind == kMsSpillReg) { + if (GetCG()->IsLmbc()) { + return symAlloc->GetOffset() + memLayout->SizeOfArgsToStackPass(); + } int32 baseOffset = symAlloc->GetOffset() + memLayout->SizeOfArgsRegisterPassed() + memLayout->GetSizeOfLocals() + memLayout->GetSizeOfRefLocals(); return baseOffset + sizeofFplr; @@ -9776,16 +10162,21 @@ void AArch64CGFunc::GenCVaStartIntrin(RegOperand &opnd, uint32 stkSize) { Operand &stkOpnd = GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); /* __stack */ - ImmOperand *offsOpnd = &CreateImmOperand(0, k64BitSize, true, kUnAdjustVary); /* isvary reset StackFrameSize */ + ImmOperand *offsOpnd; + if (GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + offsOpnd = &CreateImmOperand(0, k64BitSize, true, kUnAdjustVary); /* isvary reset StackFrameSize */ + } else { + offsOpnd = &CreateImmOperand(0, k64BitSize, true); + } ImmOperand *offsOpnd2 = &CreateImmOperand(stkSize, k64BitSize, false); RegOperand &vReg = CreateVirtualRegisterOperand(NewVReg(kRegTyInt, GetPrimTypeSize(LOWERED_PTR_TYPE))); if (stkSize) { SelectAdd(vReg, *offsOpnd, *offsOpnd2, LOWERED_PTR_TYPE); SelectAdd(vReg, stkOpnd, vReg, LOWERED_PTR_TYPE); } else { - SelectAdd(vReg, stkOpnd, *offsOpnd, LOWERED_PTR_TYPE); + SelectAdd(vReg, stkOpnd, *offsOpnd, LOWERED_PTR_TYPE); /* stack pointer */ } - OfstOperand *offOpnd = &GetOrCreateOfstOpnd(0, k64BitSize); + OfstOperand *offOpnd = &GetOrCreateOfstOpnd(0, k64BitSize); /* va_list ptr */ /* mem operand in va_list struct (lhs) */ MemOperand *strOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, k64BitSize, &opnd, nullptr, offOpnd, static_cast(nullptr)); @@ -9860,13 +10251,19 @@ void AArch64CGFunc::SelectCVaStart(const IntrinsiccallNode &intrnNode) { AArch64CallConvImpl parmLocator(GetBecommon()); CCLocInfo pLoc; uint32 stkSize = 0; + uint32 inReg = 0; for (uint32 i = 0; i < GetFunction().GetFormalCount(); i++) { MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(GetFunction().GetNthParamTyIdx(i)); parmLocator.LocateNextParm(*ty, pLoc); if (pLoc.reg0 == kRinvalid) { /* on stack */ stkSize = static_cast(pLoc.memOffset + pLoc.memSize); + } else { + inReg++; } } + if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + stkSize += (inReg * k8ByteSize); + } if (CGOptions::IsArm64ilp32()) { stkSize = static_cast(RoundUp(stkSize, k8ByteSize)); } else { diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp index 5716509ad6..433aeeee3a 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp @@ -40,8 +40,8 @@ constexpr uint8 insPairsNum = 5; PairMOperator extInsnPairTable[ExtTableSize][insPairsNum] = { /* {origMop, newMop} */ - {{MOP_wldrb, MOP_wldrb}, {MOP_undef, MOP_undef}, {MOP_undef, MOP_undef}, {MOP_undef, MOP_undef}, - {MOP_undef, MOP_undef}}, /* AND */ + {{MOP_wldrb, MOP_wldrb}, {MOP_wldrsh, MOP_wldrb}, {MOP_wldrh, MOP_wldrb}, {MOP_xldrsw, MOP_wldrb}, + {MOP_wldr, MOP_wldrb}}, /* AND */ {{MOP_wldrb, MOP_wldrsb}, {MOP_wldr, MOP_wldrsb}, {MOP_undef, MOP_undef}, {MOP_undef, MOP_undef}, {MOP_undef, MOP_undef}}, /* SXTB */ {{MOP_wldrh, MOP_wldrsh}, {MOP_wldrb, MOP_wldrb}, {MOP_wldrsb, MOP_wldrsb}, {MOP_wldrsh, MOP_wldrsh}, diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp index e9acbeefcc..71f57d89ea 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp @@ -134,7 +134,7 @@ void AArch64MemLayout::LayoutVarargParams() { if (be.GetMIRModule().IsCModule() && func->GetAttr(FUNCATTR_varargs)) { for (uint32 i = 0; i < func->GetFormalCount(); i++) { if (i == 0) { - if (func->IsReturnStruct()) { + if (func->IsFirstArgReturn() && func->GetReturnType()->GetPrimType() != PTY_void) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (be.GetTypeSize(tyIdx.GetIdx()) <= k16ByteSize) { continue; @@ -198,7 +198,7 @@ void AArch64MemLayout::LayoutFormalParams() { * outparmsize - portion of frame size of current function used by call parameters */ segArgsStkPassed.SetSize(mirFunction->GetOutParmSize()); - segArgsRegPassed.SetSize(mirFunction->GetOutParmSize() + kTwoRegister * k8ByteSize); + segArgsRegPassed.SetSize(mirFunction->GetOutParmSize()); return; } @@ -210,7 +210,7 @@ void AArch64MemLayout::LayoutFormalParams() { AArch64SymbolAlloc *symLoc = memAllocator->GetMemPool()->New(); SetSymAllocInfo(stIndex, *symLoc); if (i == 0) { - if (mirFunction->IsReturnStruct()) { + if (mirFunction->IsFirstArgReturn()) { symLoc->SetMemSegment(GetSegArgsRegPassed()); symLoc->SetOffset(GetSegArgsRegPassed().GetSize()); TyIdx tyIdx = mirFunction->GetFuncRetStructTyIdx(); @@ -224,13 +224,13 @@ void AArch64MemLayout::LayoutFormalParams() { continue; } } - MIRType *ty = mirFunction->GetNthParamType(i); + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(mirFunction->GetFormalDefVec()[i].formalTyIdx); uint32 ptyIdx = ty->GetTypeIndex(); parmLocator.LocateNextParm(*ty, ploc, i == 0, mirFunction); if (ploc.reg0 != kRinvalid) { /* register */ symLoc->SetRegisters(static_cast(ploc.reg0), static_cast(ploc.reg1), static_cast(ploc.reg2), static_cast(ploc.reg3)); - if (mirFunction->GetNthParamAttr(i).GetAttr(ATTR_localrefvar)) { + if (mirFunction->GetFormalDefVec()[i].formalAttrs.GetAttr(ATTR_localrefvar)) { symLoc->SetMemSegment(segRefLocals); SetSegmentSize(*symLoc, segRefLocals, ptyIdx); } else if (!sym->IsPreg()) { @@ -272,7 +272,7 @@ void AArch64MemLayout::LayoutFormalParams() { } else { segArgsStkPassed.SetSize(static_cast(RoundUp(segArgsStkPassed.GetSize(), kSizeOfPtr))); } - if (mirFunction->GetNthParamAttr(i).GetAttr(ATTR_localrefvar)) { + if (mirFunction->GetFormalDefVec()[i].formalAttrs.GetAttr(ATTR_localrefvar)) { SetLocalRegLocInfo(sym->GetStIdx(), *symLoc); AArch64SymbolAlloc *symLoc1 = memAllocator->GetMemPool()->New(); symLoc1->SetMemSegment(segRefLocals); @@ -287,7 +287,7 @@ void AArch64MemLayout::LayoutFormalParams() { } void AArch64MemLayout::LayoutLocalVariables(std::vector &tempVar, std::vector &returnDelays) { - if (be.GetMIRModule().GetFlavor() == kFlavorLmbc && mirFunction->GetFormalCount() == 0) { + if (be.GetMIRModule().GetFlavor() == kFlavorLmbc) { segLocals.SetSize(mirFunction->GetFrameSize() - mirFunction->GetOutParmSize()); return; } @@ -372,7 +372,7 @@ void AArch64MemLayout::LayoutReturnRef(std::vector &returnDelays, segRefLocals.SetSize(segRefLocals.GetSize() + be.GetTypeSize(tyIdx)); } if (be.GetMIRModule().GetFlavor() == kFlavorLmbc) { - segArgsToStkPass.SetSize(mirFunction->GetOutParmSize()); + segArgsToStkPass.SetSize(mirFunction->GetOutParmSize() + kDivide2 * k8ByteSize); } else { segArgsToStkPass.SetSize(FindLargestActualArea(structCopySize)); } @@ -423,7 +423,7 @@ void AArch64MemLayout::LayoutActualParams() { * variables get assigned their respecitve storage, i.e. * CallFrameSize (discounting callee-saved and FP/LR) is known. */ - MIRType *ty = mirFunction->GetNthParamType(i); + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(mirFunction->GetFormalDefVec()[i].formalTyIdx); uint32 ptyIdx = ty->GetTypeIndex(); static_cast(cgFunc)->GetOrCreateMemOpnd(*sym, 0, be.GetTypeAlign(ptyIdx) * kBitsPerByte); } @@ -440,7 +440,7 @@ void AArch64MemLayout::LayoutStackFrame(int32 &structCopySize, int32 &maxParmSta */ if (CGOptions::IsArm64ilp32()) { segArgsRegPassed.SetSize(RoundUp(segArgsRegPassed.GetSize(), k8ByteSize)); - /* we do need this as SP has to be aligned at a 16-bytes bounardy */ + /* we do need this as SP has to be aligned at a 16-bytes bounardy */ segArgsStkPassed.SetSize(RoundUp(segArgsStkPassed.GetSize(), k8ByteSize + k8ByteSize)); } else { segArgsRegPassed.SetSize(RoundUp(segArgsRegPassed.GetSize(), kSizeOfPtr)); @@ -527,11 +527,13 @@ uint64 AArch64MemLayout::StackFrameSize() const { uint64 total = segArgsRegPassed.GetSize() + static_cast(cgFunc)->SizeOfCalleeSaved() + GetSizeOfRefLocals() + locals().GetSize() + GetSizeOfSpillReg(); - if (GetSizeOfGRSaveArea() > 0) { - total += RoundUp(GetSizeOfGRSaveArea(), kAarch64StackPtrAlignment); - } - if (GetSizeOfVRSaveArea() > 0) { - total += RoundUp(GetSizeOfVRSaveArea(), kAarch64StackPtrAlignment); + if (cgFunc->GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + if (GetSizeOfGRSaveArea() > 0) { + total += RoundUp(GetSizeOfGRSaveArea(), kAarch64StackPtrAlignment); + } + if (GetSizeOfVRSaveArea() > 0) { + total += RoundUp(GetSizeOfVRSaveArea(), kAarch64StackPtrAlignment); + } } /* diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp index eaa5726d43..7ef7190645 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp @@ -50,7 +50,7 @@ void AArch64FPLROffsetAdjustment::AdjustmentOffsetForOpnd(Insn &insn, AArch64CGF if (memBaseReg->GetRegisterNumber() == RFP) { RegOperand &newBaseOpnd = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(stackBaseReg, k64BitSize, kRegTyInt); MemOperand &newMemOpnd = aarchCGFunc.GetOrCreateMemOpnd( - MemOperand::kAddrModeBOi, memOpnd.GetSize(), &newBaseOpnd, memOpnd.GetIndexRegister(), + memOpnd.GetAddrMode(), memOpnd.GetSize(), &newBaseOpnd, memOpnd.GetIndexRegister(), memOpnd.GetOffsetImmediate(), memOpnd.GetSymbol()); insn.SetOperand(i, newMemOpnd); stackBaseOpnd = true; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp index efa8b3087b..0c2322d055 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp @@ -1118,6 +1118,9 @@ void AArch64GenProEpilog::AppendInstructionAllocateCallFrameDebug(AArch64reg reg ipoint = cgFunc.GetCurBB()->GetLastInsn(); cfiOffset = stackFrameSize; (void)InsertCFIDefCfaOffset(cfiOffset, *ipoint); + if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + argsToStkPassSize -= (kDivide2 * k8ByteSize); + } ipoint = &CreateAndAppendInstructionForAllocateCallFrame(argsToStkPassSize, reg0, reg1, rty); CHECK_FATAL(ipoint != nullptr, "ipoint should not be nullptr at this point"); cfiOffset = GetOffsetFromCFA(); @@ -1251,9 +1254,16 @@ void AArch64GenProEpilog::GeneratePushRegs() { CHECK_FATAL(*it == RLR, "The second callee saved reg is expected to be RLR"); ++it; - auto offset = static_cast((static_cast(cgFunc.GetMemlayout())->RealStackFrameSize() - - (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */)) - - cgFunc.GetMemlayout()->SizeOfArgsToStackPass()); + AArch64MemLayout *memLayout = static_cast(cgFunc.GetMemlayout()); + int32 offset; + if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + offset = static_cast(memLayout->RealStackFrameSize() - + aarchCGFunc.SizeOfCalleeSaved() - memLayout->GetSizeOfLocals()); + } else { + offset = static_cast(memLayout->RealStackFrameSize() - + (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */) - + memLayout->SizeOfArgsToStackPass()); + } if (cgFunc.GetCG()->IsStackProtectorStrong() || cgFunc.GetCG()->IsStackProtectorAll()) { offset -= static_cast(kAarch64StackPtrAlignment); @@ -1313,10 +1323,19 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { size = kSizeOfPtr; } uint32 dataSizeBits = size * kBitsPerByte; - uint32 offset = static_cast(memlayout->GetGRSaveAreaBaseLoc()); - if (memlayout->GetSizeOfGRSaveArea() % kAarch64StackPtrAlignment) { - offset += size; /* End of area should be aligned. Hole between VR and GR area */ + uint32 offset; + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + offset = static_cast(memlayout->GetGRSaveAreaBaseLoc()); /* SP reference */ + if (memlayout->GetSizeOfGRSaveArea() % kAarch64StackPtrAlignment) { + offset += size; /* End of area should be aligned. Hole between VR and GR area */ + } + } else { + offset = -memlayout->GetSizeOfGRSaveArea(); /* FP reference */ + if (memlayout->GetSizeOfGRSaveArea() % kAarch64StackPtrAlignment) { + offset -= size; + } } + uint32 grSize = -offset; uint32 start_regno = k8BitSize - (memlayout->GetSizeOfGRSaveArea() / size); ASSERT(start_regno <= k8BitSize, "Incorrect starting GR regno for GR Save Area"); for (uint32 i = start_regno + static_cast(R0); i < static_cast(R8); i++) { @@ -1326,16 +1345,25 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { tmpOffset += 8U - (dataSizeBits >> 3); } } - Operand &stackloc = aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); + Operand *stackLoc; + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + stackLoc = &aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); + } else { + stackLoc = aarchCGFunc.GenLmbcFpMemOperand(offset, size); + } RegOperand ® = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(static_cast(i), k64BitSize, kRegTyInt); Insn &inst = - currCG->BuildInstruction(aarchCGFunc.PickStInsn(dataSizeBits, PTY_i64), reg, stackloc); + currCG->BuildInstruction(aarchCGFunc.PickStInsn(dataSizeBits, PTY_i64), reg, *stackLoc); cgFunc.GetCurBB()->AppendInsn(inst); offset += size; } if (!CGOptions::UseGeneralRegOnly()) { - offset = static_cast(memlayout->GetVRSaveAreaBaseLoc()); + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + offset = static_cast(memlayout->GetVRSaveAreaBaseLoc()); + } else { + offset = -(memlayout->GetSizeOfVRSaveArea() + grSize); + } start_regno = k8BitSize - (memlayout->GetSizeOfVRSaveArea() / (size * k2BitSize)); ASSERT(start_regno <= k8BitSize, "Incorrect starting GR regno for VR Save Area"); for (uint32 i = start_regno + static_cast(V0); i < static_cast(V8); i++) { @@ -1345,11 +1373,16 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { tmpOffset += 16U - (dataSizeBits >> 3); } } - Operand &stackloc = aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); + Operand *stackLoc; + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + stackLoc = &aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); + } else { + stackLoc = aarchCGFunc.GenLmbcFpMemOperand(offset, size); + } RegOperand ® = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(static_cast(i), k64BitSize, kRegTyFloat); Insn &inst = - currCG->BuildInstruction(aarchCGFunc.PickStInsn(dataSizeBits, PTY_f64), reg, stackloc); + currCG->BuildInstruction(aarchCGFunc.PickStInsn(dataSizeBits, PTY_f64), reg, *stackLoc); cgFunc.GetCurBB()->AppendInsn(inst); offset += (size * k2BitSize); } @@ -1389,7 +1422,8 @@ void AArch64GenProEpilog::GenerateProlog(BB &bb) { } // insert .loc for function - if (currCG->GetCGOptions().WithLoc()) { + if (currCG->GetCGOptions().WithLoc() && + (!currCG->GetMIRModule()->IsCModule() || currCG->GetMIRModule()->IsWithDbgInfo())) { MIRFunction *func = &cgFunc.GetFunction(); MIRSymbol *fSym = GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx()); if (currCG->GetCGOptions().WithSrc()) { @@ -1649,11 +1683,17 @@ void AArch64GenProEpilog::AppendInstructionDeallocateCallFrameDebug(AArch64reg r * ldp/stp's imm should be within -512 and 504; * if ldp's imm > 504, we fall back to the ldp-add version */ - if (cgFunc.HasVLAOrAlloca() || argsToStkPassSize == 0) { - stackFrameSize -= argsToStkPassSize; - if (stackFrameSize > kStpLdpImm64UpperBound) { + bool isLmbc = (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc); + if (cgFunc.HasVLAOrAlloca() || argsToStkPassSize == 0 || isLmbc) { + int lmbcOffset = 0; + if (isLmbc == false) { + stackFrameSize -= argsToStkPassSize; + } else { + lmbcOffset = argsToStkPassSize - (kDivide2 * k8ByteSize); + } + if (stackFrameSize > kStpLdpImm64UpperBound || isLmbc) { Operand *o2; - o2 = aarchCGFunc.CreateStackMemOpnd(RSP, 0, kSizeOfPtr * kBitsPerByte); + o2 = aarchCGFunc.CreateStackMemOpnd(RSP, (isLmbc ? lmbcOffset : 0), kSizeOfPtr * kBitsPerByte); Insn &deallocInsn = currCG->BuildInstruction(mOp, o0, o1, *o2); cgFunc.GetCurBB()->AppendInsn(deallocInsn); if (cgFunc.GenCfi()) { @@ -1728,9 +1768,16 @@ void AArch64GenProEpilog::GeneratePopRegs() { CHECK_FATAL(*it == RLR, "The second callee saved reg is expected to be RLR"); ++it; - int32 offset = static_cast((static_cast(cgFunc.GetMemlayout())->RealStackFrameSize() - - (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */)) - - cgFunc.GetMemlayout()->SizeOfArgsToStackPass()); + AArch64MemLayout *memLayout = static_cast(cgFunc.GetMemlayout()); + int32 offset; + if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + offset = static_cast(memLayout->RealStackFrameSize() - + aarchCGFunc.SizeOfCalleeSaved() - memLayout->GetSizeOfLocals()); + } else { + offset = static_cast(cgFunc.GetMemlayout())->RealStackFrameSize() - + (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */) - + memLayout->SizeOfArgsToStackPass(); + } if (cgFunc.GetCG()->IsStackProtectorStrong() || cgFunc.GetCG()->IsStackProtectorAll()) { offset -= static_cast(kAarch64StackPtrAlignment); @@ -1821,7 +1868,7 @@ void AArch64GenProEpilog::GenerateEpilog(BB &bb) { Operand &spOpnd = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(RSP, k64BitSize, kRegTyInt); Operand &fpOpnd = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(stackBaseReg, k64BitSize, kRegTyInt); - if (cgFunc.HasVLAOrAlloca()) { + if (cgFunc.HasVLAOrAlloca() && cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { aarchCGFunc.SelectCopy(spOpnd, PTY_u64, fpOpnd, PTY_u64); } diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp index 433cc85754..5ca154b1aa 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp @@ -161,8 +161,7 @@ void AArch64ReachingDefinition::AddRetPseudoInsn(BB &bb) { Insn &retInsn = cgFunc->GetCG()->BuildInstruction(MOP_pseudo_ret_int, regOpnd); bb.AppendInsn(retInsn); pseudoInsns.emplace_back(&retInsn); - } else { - ASSERT(regNO == V0, "CG internal error. Return value should be R0 or V0."); + } else if (regNO == V0) { RegOperand ®Opnd = static_cast(cgFunc)->GetOrCreatePhysicalRegisterOperand(regNO, k64BitSize, kRegTyFloat); Insn &retInsn = cgFunc->GetCG()->BuildInstruction(MOP_pseudo_ret_float, regOpnd); diff --git a/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp b/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp index d2ae2c25c9..bf645c15cd 100644 --- a/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp +++ b/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp @@ -160,6 +160,7 @@ void RecursiveMarkUsedStaticSymbol(const BaseNode *baseNode) { break; } case OP_addrof: + case OP_addrofoff: case OP_dread: { const AddrofNode *dreadNode = static_cast(baseNode); MarkUsedStaticSymbol(dreadNode->GetStIdx()); diff --git a/src/mapleall/maple_be/src/cg/cgfunc.cpp b/src/mapleall/maple_be/src/cg/cgfunc.cpp index 85826cde0e..511cae715e 100644 --- a/src/mapleall/maple_be/src/cg/cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/cgfunc.cpp @@ -1148,7 +1148,11 @@ void HandleReturn(StmtNode &stmt, CGFunc &cgFunc) { ASSERT(retNode.NumOpnds() <= 1, "NYI return nodes number > 1"); Operand *opnd = nullptr; if (retNode.NumOpnds() != 0) { - opnd = cgFunc.HandleExpr(retNode, *retNode.Opnd(0)); + if (!cgFunc.GetFunction().StructReturnedInRegs()) { + opnd = cgFunc.HandleExpr(retNode, *retNode.Opnd(0)); + } else { + cgFunc.SelectReturnSendOfStructInRegs(retNode.Opnd(0)); + } } cgFunc.SelectReturn(opnd); cgFunc.SetCurBBKind(BB::kBBReturn); @@ -1564,14 +1568,15 @@ void CGFunc::CreateLmbcFormalParamInfo() { uint32 offset; uint32 typeSize; MIRFunction &func = GetFunction(); - if (func.GetParamSize() > 0) { + if (func.GetFormalCount() > 0) { + /* Whenever lmbc cannot delete call type info, the prototype is available */ uint32 stackOffset = 0; - for (size_t idx = 0; idx < func.GetParamSize(); ++idx) { + for (size_t idx = 0; idx < func.GetFormalCount(); ++idx) { MIRSymbol *sym = func.GetFormal(idx); MIRType *type; TyIdx tyIdx; if (sym) { - tyIdx = func.GetNthParamTyIdx(idx); + tyIdx = func.GetFormalDefVec()[idx].formalTyIdx; type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); } else { FormalDef vec = const_cast(GetBecommon().GetMIRModule().CurFunction())->GetFormalDefAt(idx); @@ -1618,6 +1623,9 @@ void CGFunc::CreateLmbcFormalParamInfo() { } IreadFPoffNode *ireadNode = static_cast(operand); primType = ireadNode->GetPrimType(); + if (ireadNode->GetOffset() < 0) { + continue; + } offset = static_cast(ireadNode->GetOffset()); typeSize = GetPrimTypeSize(primType); CHECK_FATAL((offset % k8ByteSize) == 0, ""); /* scalar only, no struct for now */ @@ -1629,6 +1637,31 @@ void CGFunc::CreateLmbcFormalParamInfo() { [] (LmbcFormalParamInfo *x, LmbcFormalParamInfo *y) { return x->GetOffset() < y->GetOffset(); } ); + + /* When a scalar param address is taken, its regassign is not in the 1st block */ + for (StmtNode *stmt = func.GetBody()->GetFirst(); stmt != nullptr; stmt = stmt->GetNext()) { + if (stmt == nullptr) { + break; + } + if (stmt->GetOpCode() == OP_label) { + continue; + } + if (stmt->GetOpCode() != OP_regassign) { + break; + } + RegassignNode *regAssignNode = static_cast(stmt); + BaseNode *operand = regAssignNode->Opnd(0); + if (operand->GetOpCode() != OP_ireadfpoff) { + break; + } + IreadFPoffNode *ireadNode = static_cast(operand); + if (ireadNode->GetOffset() < 0) { + continue; + } + LmbcFormalParamInfo *info = GetLmbcFormalParamInfo(ireadNode->GetOffset()); + info->SetHasRegassign(); + } + AssignLmbcFormalParams(); } @@ -1637,7 +1670,7 @@ void CGFunc::GenerateInstruction() { InitHandleStmtFactory(); StmtNode *secondStmt = HandleFirstStmt(); - CreateLmbcFormalParamInfo(); + //CreateLmbcFormalParamInfo(); /* First Pass: Creates the doubly-linked list of BBs (next,prev) */ volReleaseInsn = nullptr; unsigned lastSrcLoc = 0; @@ -2009,6 +2042,7 @@ void CGFunc::HandleFunction() { ASSERT(exitBBVec.size() <= 1, "there are more than one BB_return in func"); } ProcessExitBBVec(); + LmbcGenSaveSpForAlloca(); if (func.IsJava()) { GenerateCleanupCodeForExtEpilog(*cleanupBB); diff --git a/src/mapleall/maple_be/src/cg/emit.cpp b/src/mapleall/maple_be/src/cg/emit.cpp index 896d0a297b..6e28d7bee5 100644 --- a/src/mapleall/maple_be/src/cg/emit.cpp +++ b/src/mapleall/maple_be/src/cg/emit.cpp @@ -2170,6 +2170,11 @@ void Emitter::EmitGlobalVar(const MIRSymbol &globalVar) { } void Emitter::EmitGlobalVars(std::vector> &globalVars) { + if (GetCG()->IsLmbc() && GetCG()->GetGP() != nullptr) { + Emit(asmInfo->GetLocal()).Emit("\t").Emit(GetCG()->GetGP()->GetName()).Emit("\n"); + Emit(asmInfo->GetComm()).Emit("\t").Emit(GetCG()->GetGP()->GetName()); + Emit(", ").Emit(GetCG()->GetMIRModule()->GetGlobalMemSize()).Emit(", ").Emit("8\n"); + } /* load globalVars profile */ if (globalVars.empty()) { return; diff --git a/src/mapleall/maple_be/src/cg/memlayout.cpp b/src/mapleall/maple_be/src/cg/memlayout.cpp index 57e45e8a2d..1b636207c6 100644 --- a/src/mapleall/maple_be/src/cg/memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/memlayout.cpp @@ -38,7 +38,7 @@ uint32 MemLayout::FindLargestActualArea(int32 &aggCopySize) { uint32 maxCopyStackSize = 0; // Size of aggregate param stack copy requirement for (; stmt != nullptr; stmt = stmt->GetNext()) { Opcode opCode = stmt->GetOpCode(); - if (opCode < OP_call || opCode > OP_xintrinsiccallassigned) { + if ((opCode < OP_call || opCode > OP_xintrinsiccallassigned) && opCode != OP_icallproto) { continue; } if (opCode == OP_intrinsiccallwithtypeassigned || opCode == OP_intrinsiccallwithtype || @@ -54,9 +54,9 @@ uint32 MemLayout::FindLargestActualArea(int32 &aggCopySize) { * if the following check fails, most likely dex has invoke-custom etc * that is not supported yet */ - DCHECK((opCode == OP_call || opCode == OP_icall), "Not lowered to call or icall?"); + DCHECK((opCode == OP_call || opCode == OP_icall || opCode == OP_icallproto), "Not lowered to call or icall?"); int32 copySize; - uint32 size = ComputeStackSpaceRequirementForCall(*stmt, copySize, opCode == OP_icall); + uint32 size = ComputeStackSpaceRequirementForCall(*stmt, copySize, opCode == OP_icall || opCode == OP_icallproto); if (size > maxParamStackSize) { maxParamStackSize = size; } diff --git a/src/mapleall/maple_ir/include/bin_mpl_export.h b/src/mapleall/maple_ir/include/bin_mpl_export.h index 09952cb8c7..f12bec7081 100644 --- a/src/mapleall/maple_ir/include/bin_mpl_export.h +++ b/src/mapleall/maple_ir/include/bin_mpl_export.h @@ -67,8 +67,8 @@ enum : uint8 { kBinEaCgStart = 41, kBinEaStart = 42, kBinNodeBlock = 43, - kBinOpStatement = 44, - kBinOpExpression = 45, +//kBinOpStatement = 44, +//kBinOpExpression = 45, kBinReturnvals = 46, kBinTypeTabStart = 47, kBinSymStart = 48, @@ -76,14 +76,14 @@ enum : uint8 { kBinFuncIdInfoStart = 50, kBinFormalStart = 51, kBinPreg = 52, - kBinPregStart = 53, - kBinLabelStart = 54, + kBinSpecialReg = 53, + kBinLabel = 54, kBinTypenameStart = 55, kBinHeaderStart = 56, kBinAliasMapStart = 57, - kBinKindTypeViaTypename = 58, - kBinKindSymViaSymname = 59, - kBinKindFuncViaSymname = 60, +//kBinKindTypeViaTypename = 58, +//kBinKindSymViaSymname = 59, +//kBinKindFuncViaSymname = 60, kBinFunctionBodyStart = 61, kBinFormalWordsTypeTagged = 62, kBinFormalWordsRefCounted = 63, @@ -103,8 +103,7 @@ class BinaryMplExport { void Export(const std::string &fname, std::unordered_set *dumpFuncSet); void WriteNum(int64 x); void Write(uint8 b); - void OutputType(TyIdx tyIdx, bool canUseTypename); - void OutputTypeViaTypeName(TyIdx tidx) { OutputType(tidx, true); } + void OutputType(TyIdx tyIdx); void WriteFunctionBodyField(uint64 contentIdx, std::unordered_set *dumpFuncSet); void OutputConst(MIRConst *c); void OutputConstBase(const MIRConst &c); @@ -133,12 +132,11 @@ class BinaryMplExport { void OutputInfoVector(const MIRInfoVector &infoVector, const MapleVector &infoVectorIsString); void OutputFuncIdInfo(MIRFunction *func); void OutputLocalSymbol(MIRSymbol *sym); - void OutputLocalSymTab(const MIRFunction *func); - void OutputPregTab(const MIRFunction *func); - void OutputLabelTab(const MIRFunction *func); + void OutputPreg(MIRPreg *preg); + void OutputLabel(LabelIdx lidx); void OutputLocalTypeNameTab(const MIRTypeNameTable *tyNameTab); void OutputFormalsStIdx(MIRFunction *func); - void OutputFuncViaSymName(PUIdx puIdx); + void OutputFuncViaSym(PUIdx puIdx); void OutputExpression(BaseNode *e); void OutputBaseNode(const BaseNode *b); void OutputReturnValues(const CallReturnVector *retv); @@ -182,6 +180,7 @@ class BinaryMplExport { void ExpandFourBuffSize(); MIRModule &mod; + MIRFunction *curFunc = nullptr; size_t bufI = 0; std::vector buf; std::unordered_map gStrMark; @@ -190,6 +189,9 @@ class BinaryMplExport { std::unordered_map uStrMark; std::unordered_map symMark; std::unordered_map typMark; + std::unordered_map localSymMark; + std::unordered_map localPregMark; + std::unordered_map labelMark; friend class UpdateMplt; std::unordered_map callInfoMark; std::map *func2SEMap = nullptr; diff --git a/src/mapleall/maple_ir/include/bin_mpl_import.h b/src/mapleall/maple_ir/include/bin_mpl_import.h index 3697654872..ee7f909f9b 100644 --- a/src/mapleall/maple_ir/include/bin_mpl_import.h +++ b/src/mapleall/maple_ir/include/bin_mpl_import.h @@ -126,15 +126,14 @@ class BinaryMplImport { void ImportInfoVector(MIRInfoVector &infoVector, MapleVector &infoVectorIsString); void ImportLocalTypeNameTable(MIRTypeNameTable *typeNameTab); void ImportFuncIdInfo(MIRFunction *func); - void ImportLocalSymbol(MIRFunction *func); - void ImportLocalSymTab(MIRFunction *func); - void ImportPregTab(const MIRFunction *func); - void ImportLabelTab(MIRFunction *func); + MIRSymbol *ImportLocalSymbol(MIRFunction *func); + PregIdx ImportPreg(MIRFunction *func); + LabelIdx ImportLabel(MIRFunction *func); void ImportFormalsStIdx(MIRFunction *func); void ImportAliasMap(MIRFunction *func); void ImportSrcPos(SrcPosition &pos); void ImportBaseNode(Opcode &o, PrimType &typ); - PUIdx ImportFuncViaSymName(); + PUIdx ImportFuncViaSym(MIRFunction *func); BaseNode *ImportExpression(MIRFunction *func); void ImportReturnValues(MIRFunction *func, CallReturnVector *retv); BlockNode *ImportBlockNode(MIRFunction *fn); @@ -162,6 +161,9 @@ class BinaryMplImport { std::vector typTab; std::vector funcTab; std::vector symTab; + std::vector localSymTab; + std::vector localPregTab; + std::vector localLabelTab; std::vector callInfoTab; std::vector eaCgTab; std::vector methodSymbols; diff --git a/src/mapleall/maple_ir/include/ir_safe_cast_traits.def b/src/mapleall/maple_ir/include/ir_safe_cast_traits.def index 1439b49d57..14ed1a367b 100644 --- a/src/mapleall/maple_ir/include/ir_safe_cast_traits.def +++ b/src/mapleall/maple_ir/include/ir_safe_cast_traits.def @@ -224,7 +224,9 @@ REGISTER_SAFE_CAST(CallNode, from.GetOpCode() == OP_call || from.GetOpCode() == OP_virtualicallassigned || instance_of(from)); REGISTER_SAFE_CAST(IcallNode, from.GetOpCode() == OP_icall || - from.GetOpCode() == OP_icallassigned); + from.GetOpCode() == OP_icallassigned || + from.GetOpCode() == OP_icallproto || + from.GetOpCode() == OP_icallprotoassigned); REGISTER_SAFE_CAST(IntrinsiccallNode, from.GetOpCode() == OP_intrinsiccall || from.GetOpCode() == OP_intrinsiccallwithtype || from.GetOpCode() == OP_xintrinsiccall || diff --git a/src/mapleall/maple_ir/include/keywords.def b/src/mapleall/maple_ir/include/keywords.def index eddff2f80a..51a603eafa 100644 --- a/src/mapleall/maple_ir/include/keywords.def +++ b/src/mapleall/maple_ir/include/keywords.def @@ -55,7 +55,6 @@ // per-function declaration keywords KEYWORD(framesize) KEYWORD(upformalsize) - KEYWORD(outparmsize) KEYWORD(moduleid) KEYWORD(funcsize) KEYWORD(funcid) diff --git a/src/mapleall/maple_ir/include/mir_builder.h b/src/mapleall/maple_ir/include/mir_builder.h index ac3215724e..64f6a2723c 100755 --- a/src/mapleall/maple_ir/include/mir_builder.h +++ b/src/mapleall/maple_ir/include/mir_builder.h @@ -262,6 +262,8 @@ class MIRBuilder { IcallNode *CreateStmtIcall(const MapleVector &args); IcallNode *CreateStmtIcallAssigned(const MapleVector &args, const MIRSymbol &ret); + IcallNode *CreateStmtIcallproto(const MapleVector &args); + IcallNode *CreateStmtIcallprotoAssigned(const MapleVector &args, const MIRSymbol &ret); // For Call, VirtualCall, SuperclassCall, InterfaceCall IntrinsiccallNode *CreateStmtIntrinsicCall(MIRIntrinsicID idx, const MapleVector &arguments, TyIdx tyIdx = TyIdx()); diff --git a/src/mapleall/maple_ir/include/mir_function.h b/src/mapleall/maple_ir/include/mir_function.h index 0fa62fdac2..5329d87548 100644 --- a/src/mapleall/maple_ir/include/mir_function.h +++ b/src/mapleall/maple_ir/include/mir_function.h @@ -830,24 +830,24 @@ class MIRFunction { callTimes = times; } - uint16 GetFrameSize() const { + uint32 GetFrameSize() const { return frameSize; } - void SetFrameSize(uint16 size) { + void SetFrameSize(uint32 size) { frameSize = size; } - uint16 GetUpFormalSize() const { + uint32 GetUpFormalSize() const { return upFormalSize; } - void SetUpFormalSize(uint16 size) { + void SetUpFormalSize(uint32 size) { upFormalSize = size; } - uint16 GetOutParmSize() const { + uint32 GetOutParmSize() const { return outParmSize; } - void SetOutParmSize(uint16 size) { + void SetOutParmSize(uint32 size) { outParmSize = size; } @@ -1298,9 +1298,9 @@ class MIRFunction { bool isDirty = false; bool fromMpltInline = false; // Whether this function is imported from mplt_inline file or not. uint8_t layoutType = kLayoutUnused; - uint16 frameSize = 0; - uint16 upFormalSize = 0; - uint16 outParmSize = 0; + uint32 frameSize = 0; + uint32 upFormalSize = 0; + uint32 outParmSize = 0; uint16 moduleID = 0; uint32 funcSize = 0; // size of code in words uint32 tempCount = 0; diff --git a/src/mapleall/maple_ir/include/mir_lower.h b/src/mapleall/maple_ir/include/mir_lower.h index 332a6de89f..be479f65a6 100644 --- a/src/mapleall/maple_ir/include/mir_lower.h +++ b/src/mapleall/maple_ir/include/mir_lower.h @@ -86,6 +86,7 @@ class MIRLower { ForeachelemNode *ExpandArrayMrtForeachelemBlock(ForeachelemNode &node); BlockNode *ExpandArrayMrtBlock(BlockNode &block); void AddArrayMrtMpl(BaseNode &exp, BlockNode &newblk); + MIRFuncType *FuncTypeFromFuncPtrExpr(BaseNode *x); void SetLowerME() { lowerPhase |= kShiftLowerMe; } diff --git a/src/mapleall/maple_ir/include/mir_nodes.h b/src/mapleall/maple_ir/include/mir_nodes.h index 0ebf07beff..3481c75c60 100755 --- a/src/mapleall/maple_ir/include/mir_nodes.h +++ b/src/mapleall/maple_ir/include/mir_nodes.h @@ -3304,7 +3304,7 @@ class CallNode : public NaryStmtNode { CallReturnVector returnValues; }; -// icall and icallproto +// icall, icallassigned, icallproto and icallprotoassigned class IcallNode : public NaryStmtNode { public: IcallNode(MapleAllocator &allocator, Opcode o) diff --git a/src/mapleall/maple_ir/include/mir_parser.h b/src/mapleall/maple_ir/include/mir_parser.h index 10d1dd028a..b49370d0ff 100755 --- a/src/mapleall/maple_ir/include/mir_parser.h +++ b/src/mapleall/maple_ir/include/mir_parser.h @@ -134,6 +134,7 @@ class MIRParser { bool ParseStmtIcall(StmtNodePtr&); bool ParseStmtIcallassigned(StmtNodePtr&); bool ParseStmtIcallproto(StmtNodePtr&); + bool ParseStmtIcallprotoassigned(StmtNodePtr&); bool ParseStmtIntrinsiccall(StmtNodePtr&, bool isAssigned); bool ParseStmtIntrinsiccall(StmtNodePtr&); bool ParseStmtIntrinsiccallassigned(StmtNodePtr&); @@ -291,7 +292,6 @@ class MIRParser { bool ParseStmtBlockForType(); bool ParseStmtBlockForFrameSize(); bool ParseStmtBlockForUpformalSize(); - bool ParseStmtBlockForOutParmSize(); bool ParseStmtBlockForModuleID(); bool ParseStmtBlockForFuncSize(); bool ParseStmtBlockForFuncID(); diff --git a/src/mapleall/maple_ir/include/mir_symbol.h b/src/mapleall/maple_ir/include/mir_symbol.h index 2f4e37c80b..4291a0c24b 100644 --- a/src/mapleall/maple_ir/include/mir_symbol.h +++ b/src/mapleall/maple_ir/include/mir_symbol.h @@ -484,12 +484,11 @@ class MIRSymbol { return false; } switch (storageClass) { - case kScFormal: case kScAuto: return true; case kScPstatic: case kScFstatic: - return value.konst == nullptr; + return value.konst == nullptr && !hasPotentialAssignment; default: return false; } @@ -638,7 +637,8 @@ class MIRLabelTable { LabelIdx CreateLabel() { LabelIdx labelIdx = labelTable.size(); - labelTable.push_back(GStrIdx(0)); // insert dummy global string index for anonymous label + GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(std::to_string(labelIdx)); + labelTable.push_back(strIdx); return labelIdx; } diff --git a/src/mapleall/maple_ir/include/mir_type.h b/src/mapleall/maple_ir/include/mir_type.h index d6d32d999b..83585981e9 100644 --- a/src/mapleall/maple_ir/include/mir_type.h +++ b/src/mapleall/maple_ir/include/mir_type.h @@ -1189,14 +1189,6 @@ class MIRStructType : public MIRType { isImported = flag; } - bool IsUsed() const { - return isUsed; - } - - void SetIsUsed(bool flag) { - isUsed = flag; - } - bool IsCPlusPlus() const { return isCPlusPlus; } @@ -1368,7 +1360,6 @@ class MIRStructType : public MIRType { vTableMethods.clear(); iTableMethods.clear(); isImported = false; - isUsed = false; hasVolatileField = false; hasVolatileFieldSet = false; } @@ -1471,7 +1462,6 @@ class MIRStructType : public MIRType { // implementation functions, For interfaces, they are abstact functions. // Weak indicates the actual definition is in another module. bool isImported = false; - bool isUsed = false; bool isCPlusPlus = false; // empty struct in C++ has size 1 byte mutable bool hasVolatileField = false; // for caching computed value mutable bool hasVolatileFieldSet = false; // if true, just read hasVolatileField; @@ -1928,11 +1918,19 @@ class MIRFuncType : public MIRType { } bool IsVarargs() const { - return isVarArgs; + return funcAttrs.GetAttr(FUNCATTR_varargs); } - void SetVarArgs(bool flag) { - isVarArgs = flag; + void SetVarArgs() { + funcAttrs.SetAttr(FUNCATTR_varargs); + } + + bool FirstArgReturn() const { + return funcAttrs.GetAttr(FUNCATTR_firstarg_return); + } + + void SetFirstArgReturn() { + funcAttrs.SetAttr(FUNCATTR_firstarg_return); } const TypeAttrs &GetRetAttrs() const { @@ -1960,7 +1958,8 @@ class MIRFuncType : public MIRType { std::vector paramTypeList; std::vector paramAttrsList; TypeAttrs retAttrs; - bool isVarArgs = false; + public: + FuncAttrs funcAttrs; }; class MIRTypeByName : public MIRType { diff --git a/src/mapleall/maple_ir/include/opcode_info.h b/src/mapleall/maple_ir/include/opcode_info.h index 814f15b2f2..5a82646b11 100644 --- a/src/mapleall/maple_ir/include/opcode_info.h +++ b/src/mapleall/maple_ir/include/opcode_info.h @@ -117,6 +117,7 @@ class OpcodeTable { bool IsICall(Opcode o) const { ASSERT(o < OP_last, "invalid opcode"); return o == OP_icall || o == OP_icallassigned || + o == OP_icallproto || o == OP_icallprotoassigned || o == OP_virtualicall || o == OP_virtualicallassigned || o == OP_interfaceicall || o == OP_interfaceicallassigned; } diff --git a/src/mapleall/maple_ir/include/opcodes.def b/src/mapleall/maple_ir/include/opcodes.def index 34cfb51c8d..0e842141ed 100755 --- a/src/mapleall/maple_ir/include/opcodes.def +++ b/src/mapleall/maple_ir/include/opcodes.def @@ -221,3 +221,4 @@ OPCODE(iassignspoff, IassignFPoffNode, OPCODEISSTMT, 8) OPCODE(blkassignoff, BlkassignoffNode, OPCODEISSTMT, 8) OPCODE(icallproto, IcallNode, (OPCODEISSTMT | OPCODEISVARSIZE | OPCODEHASSSAUSE | OPCODEHASSSADEF | OPCODEISCALL), 8) + OPCODE(icallprotoassigned, IcallNode, (OPCODEISSTMT | OPCODEISVARSIZE | OPCODEHASSSAUSE | OPCODEHASSSADEF | OPCODEISCALL | OPCODEISCALLASSIGNED), 8) diff --git a/src/mapleall/maple_ir/include/opcodes.h b/src/mapleall/maple_ir/include/opcodes.h index ea4ed2c1c9..b9f5e0f8c5 100644 --- a/src/mapleall/maple_ir/include/opcodes.h +++ b/src/mapleall/maple_ir/include/opcodes.h @@ -50,7 +50,7 @@ inline constexpr bool IsCallAssigned(Opcode code) { code == OP_virtualicallassigned || code == OP_superclasscallassigned || code == OP_interfacecallassigned || code == OP_interfaceicallassigned || code == OP_customcallassigned || code == OP_polymorphiccallassigned || - code == OP_icallassigned || code == OP_intrinsiccallassigned || + code == OP_icallassigned || code == OP_icallprotoassigned || code == OP_intrinsiccallassigned || code == OP_xintrinsiccallassigned || code == OP_intrinsiccallwithtypeassigned); } @@ -113,6 +113,8 @@ constexpr bool IsStmtMustRequire(Opcode opcode) { case OP_polymorphiccallassigned: case OP_icall: case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: case OP_intrinsiccall: case OP_xintrinsiccall: case OP_intrinsiccallassigned: diff --git a/src/mapleall/maple_ir/src/bin_func_export.cpp b/src/mapleall/maple_ir/src/bin_func_export.cpp index 263ef34c80..6815c8151d 100644 --- a/src/mapleall/maple_ir/src/bin_func_export.cpp +++ b/src/mapleall/maple_ir/src/bin_func_export.cpp @@ -24,6 +24,10 @@ using namespace std; namespace maple { void BinaryMplExport::OutputInfoVector(const MIRInfoVector &infoVector, const MapleVector &infoVectorIsString) { + if (!mod.IsWithDbgInfo()) { + Write(0); + return; + } WriteNum(infoVector.size()); for (uint32 i = 0; i < infoVector.size(); i++) { OutputStr(infoVector[i].first); @@ -41,99 +45,73 @@ void BinaryMplExport::OutputFuncIdInfo(MIRFunction *func) { WriteNum(func->GetPuidxOrigin()); // the funcid OutputInfoVector(func->GetInfoVector(), func->InfoIsString()); if (mod.GetFlavor() == kFlavorLmbc) { - WriteNum(func->GetUpFormalSize()); WriteNum(func->GetFrameSize()); - WriteNum(func->GetOutParmSize()); } - WriteNum(~kBinFuncIdInfoStart); } void BinaryMplExport::OutputBaseNode(const BaseNode *b) { - WriteNum(b->GetOpCode()); - WriteNum(b->GetPrimType()); + Write(static_cast(b->GetOpCode())); + Write(static_cast(b->GetPrimType())); } void BinaryMplExport::OutputLocalSymbol(MIRSymbol *sym) { - if (sym == nullptr) { - WriteNum(0); + std::unordered_map::iterator it = localSymMark.find(sym); + if (it != localSymMark.end()) { + WriteNum(-(it->second)); return; } + WriteNum(kBinSymbol); - WriteNum(sym->GetStIndex()); // preserve original st index OutputStr(sym->GetNameStrIdx()); WriteNum(sym->GetSKind()); WriteNum(sym->GetStorageClass()); + size_t mark = localSymMark.size(); + localSymMark[sym] = mark; OutputTypeAttrs(sym->GetAttrs()); WriteNum(static_cast(sym->GetIsTmp())); if (sym->GetSKind() == kStVar || sym->GetSKind() == kStFunc) { OutputSrcPos(sym->GetSrcPosition()); } - OutputTypeViaTypeName(sym->GetTyIdx()); + OutputType(sym->GetTyIdx()); if (sym->GetSKind() == kStPreg) { - WriteNum(sym->GetPreg()->GetPregNo()); + OutputPreg(sym->GetPreg()); } else if (sym->GetSKind() == kStConst || sym->GetSKind() == kStVar) { OutputConst(sym->GetKonst()); } else if (sym->GetSKind() == kStFunc) { - OutputFuncViaSymName(sym->GetFunction()->GetPuidx()); - OutputTypeViaTypeName(sym->GetTyIdx()); + OutputFuncViaSym(sym->GetFunction()->GetPuidx()); } else { CHECK_FATAL(false, "should not used"); } } -void BinaryMplExport::OutputLocalSymTab(const MIRFunction *func) { - WriteNum(kBinSymStart); - uint64 outsymSizeIdx = buf.size(); - ExpandFourBuffSize(); /// size of OutSym - int32 size = 0; - - for (uint32 i = 1; i < func->GetSymTab()->GetSymbolTableSize(); i++) { - MIRSymbol *s = func->GetSymTab()->GetSymbolFromStIdx(i); - ASSERT(s != nullptr, "null ptr check"); - if (s->IsDeleted()) { - OutputLocalSymbol(nullptr); - } else { - OutputLocalSymbol(s); - } - size++; +void BinaryMplExport::OutputPreg(MIRPreg *preg) { + if (preg->GetPregNo() < 0) { + WriteNum(kBinSpecialReg); + Write(-preg->GetPregNo()); + return; } - - Fixup(outsymSizeIdx, size); - WriteNum(~kBinSymStart); -} - -void BinaryMplExport::OutputPregTab(const MIRFunction *func) { - WriteNum(kBinPregStart); - uint64 outRegSizeIdx = buf.size(); - ExpandFourBuffSize(); /// size of OutReg - int32 size = 0; - - for (uint32 i = 1; i < func->GetPregTab()->Size(); ++i) { - MIRPreg *mirpreg = func->GetPregTab()->PregFromPregIdx(static_cast(i)); - if (mirpreg == nullptr) { - WriteNum(0); - size++; - continue; - } - WriteNum(kBinPreg); - WriteNum(mirpreg->GetPregNo()); - TyIdx tyIdx = (mirpreg->GetMIRType() == nullptr) ? TyIdx(0) : mirpreg->GetMIRType()->GetTypeIndex(); - OutputTypeViaTypeName(tyIdx); - WriteNum(mirpreg->GetPrimType()); - size++; + std::unordered_map::iterator it = localPregMark.find(preg); + if (it != localPregMark.end()) { + WriteNum(-(it->second)); + return; } - Fixup(outRegSizeIdx, size); - WriteNum(~kBinPregStart); + WriteNum(kBinPreg); + Write(static_cast(preg->GetPrimType())); + size_t mark = localPregMark.size(); + localPregMark[preg] = mark; } -void BinaryMplExport::OutputLabelTab(const MIRFunction *func) { - WriteNum(kBinLabelStart); - WriteNum(static_cast(func->GetLabelTab()->Size()-1)); // entry 0 is skipped - for (uint32 i = 1; i < func->GetLabelTab()->Size(); i++) { - OutputStr(func->GetLabelTab()->GetLabelTable()[i]); +void BinaryMplExport::OutputLabel(LabelIdx lidx) { + std::unordered_map::iterator it = labelMark.find(lidx); + if (it != labelMark.end()) { + WriteNum(-(it->second)); + return; } - WriteNum(~kBinLabelStart); + + WriteNum(kBinLabel); + size_t mark = labelMark.size(); + labelMark[lidx] = mark; } void BinaryMplExport::OutputLocalTypeNameTab(const MIRTypeNameTable *typeNameTab) { @@ -141,18 +119,16 @@ void BinaryMplExport::OutputLocalTypeNameTab(const MIRTypeNameTable *typeNameTab WriteNum(static_cast(typeNameTab->Size())); for (std::pair it : typeNameTab->GetGStrIdxToTyIdxMap()) { OutputStr(it.first); - OutputTypeViaTypeName(it.second); + OutputType(it.second); } - WriteNum(~kBinTypenameStart); } void BinaryMplExport::OutputFormalsStIdx(MIRFunction *func) { WriteNum(kBinFormalStart); WriteNum(func->GetFormalDefVec().size()); for (FormalDef formalDef : func->GetFormalDefVec()) { - WriteNum(formalDef.formalSym->GetStIndex()); + OutputLocalSymbol(formalDef.formalSym); } - WriteNum(~kBinFormalStart); } void BinaryMplExport::OutputAliasMap(MapleMap &aliasVarMap) { @@ -161,21 +137,18 @@ void BinaryMplExport::OutputAliasMap(MapleMap &aliasVarMa for (std::pair it : aliasVarMap) { OutputStr(it.first); OutputStr(it.second.memPoolStrIdx); - OutputTypeViaTypeName(it.second.tyIdx); + OutputType(it.second.tyIdx); OutputStr(it.second.sigStrIdx); } - WriteNum(~kBinAliasMapStart); } -void BinaryMplExport::OutputFuncViaSymName(PUIdx puIdx) { +void BinaryMplExport::OutputFuncViaSym(PUIdx puIdx) { MIRFunction *func = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx()); - WriteNum(kBinKindFuncViaSymname); - OutputStr(funcSt->GetNameStrIdx()); + OutputSymbol(funcSt); } void BinaryMplExport::OutputExpression(BaseNode *e) { - WriteNum(kBinOpExpression); OutputBaseNode(e); switch (e->GetOpCode()) { // leaf @@ -191,17 +164,17 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { } case OP_addroflabel: { AddroflabelNode *lNode = static_cast(e); - WriteNum(lNode->GetOffset()); + OutputLabel(lNode->GetOffset()); return; } case OP_addroffunc: { AddroffuncNode *addrNode = static_cast(e); - OutputFuncViaSymName(addrNode->GetPUIdx()); + OutputFuncViaSym(addrNode->GetPUIdx()); return; } case OP_sizeoftype: { SizeoftypeNode *sot = static_cast(e); - OutputTypeViaTypeName(sot->GetTyIdx()); + OutputType(sot->GetTyIdx()); return; } case OP_addrof: @@ -220,24 +193,23 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { } WriteNum(stIdx.Scope()); if (stIdx.Islocal()) { - WriteNum(stIdx.Idx()); // preserve original st index + OutputLocalSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx)); } else { - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(stIdx.Idx()); - WriteNum(kBinKindSymViaSymname); - OutputStr(sym->GetNameStrIdx()); + OutputSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx)); } return; } case OP_regread: { RegreadNode *regreadNode = static_cast(e); - WriteNum(regreadNode->GetRegIdx()); + MIRPreg *preg = curFunc->GetPregTab()->PregFromPregIdx(regreadNode->GetRegIdx()); + OutputPreg(preg); return; } case OP_gcmalloc: case OP_gcpermalloc: case OP_stackmalloc: { GCMallocNode *gcNode = static_cast(e); - OutputTypeViaTypeName(gcNode->GetTyIdx()); + OutputType(gcNode->GetTyIdx()); return; } // unary @@ -246,18 +218,18 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { case OP_floor: case OP_trunc: { TypeCvtNode *typecvtNode = static_cast(e); - WriteNum(typecvtNode->FromType()); + Write(static_cast(typecvtNode->FromType())); break; } case OP_retype: { RetypeNode *retypeNode = static_cast(e); - OutputTypeViaTypeName(retypeNode->GetTyIdx()); + OutputType(retypeNode->GetTyIdx()); break; } case OP_iread: case OP_iaddrof: { IreadNode *irNode = static_cast(e); - OutputTypeViaTypeName(irNode->GetTyIdx()); + OutputType(irNode->GetTyIdx()); WriteNum(irNode->GetFieldID()); break; } @@ -275,20 +247,20 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { case OP_zext: case OP_extractbits: { ExtractbitsNode *extNode = static_cast(e); - WriteNum(extNode->GetBitsOffset()); - WriteNum(extNode->GetBitsSize()); + Write(extNode->GetBitsOffset()); + Write(extNode->GetBitsSize()); break; } case OP_depositbits: { DepositbitsNode *dbNode = static_cast(e); - WriteNum(dbNode->GetBitsOffset()); - WriteNum(dbNode->GetBitsSize()); + Write(dbNode->GetBitsOffset()); + Write(dbNode->GetBitsSize()); break; } case OP_gcmallocjarray: case OP_gcpermallocjarray: { JarrayMallocNode *gcNode = static_cast(e); - OutputTypeViaTypeName(gcNode->GetTyIdx()); + OutputType(gcNode->GetTyIdx()); break; } // binary @@ -321,13 +293,13 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { case OP_cmpl: case OP_cmp: { CompareNode *cmpNode = static_cast(e); - WriteNum(cmpNode->GetOpndType()); + Write(static_cast(cmpNode->GetOpndType())); break; } case OP_resolveinterfacefunc: case OP_resolvevirtualfunc: { ResolveFuncNode *rsNode = static_cast(e); - OutputFuncViaSymName(rsNode->GetPuIdx()); + OutputFuncViaSym(rsNode->GetPuIdx()); break; } // ternary @@ -337,8 +309,8 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { // nary case OP_array: { ArrayNode *arrNode = static_cast(e); - OutputTypeViaTypeName(arrNode->GetTyIdx()); - WriteNum(static_cast(arrNode->GetBoundsCheck())); + OutputType(arrNode->GetTyIdx()); + Write(static_cast(arrNode->GetBoundsCheck())); WriteNum(static_cast(arrNode->NumOpnds())); break; } @@ -351,7 +323,7 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { case OP_intrinsicopwithtype: { IntrinsicopNode *intrnNode = static_cast(e); WriteNum(intrnNode->GetIntrinsic()); - OutputTypeViaTypeName(intrnNode->GetTyIdx()); + OutputType(intrnNode->GetTyIdx()); WriteNum(static_cast(intrnNode->NumOpnds())); break; } @@ -366,6 +338,9 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { static SrcPosition lastOutputSrcPosition; void BinaryMplExport::OutputSrcPos(const SrcPosition &pos) { + if (!mod.IsWithDbgInfo()) { + return; + } if (pos.FileNum() == 0 || pos.LineNum() == 0) { // error case, so output 0 WriteNum(lastOutputSrcPosition.RawData()); WriteNum(lastOutputSrcPosition.LineNum()); @@ -380,9 +355,15 @@ void BinaryMplExport::OutputReturnValues(const CallReturnVector *retv) { WriteNum(kBinReturnvals); WriteNum(static_cast(retv->size())); for (uint32 i = 0; i < retv->size(); i++) { - WriteNum((*retv)[i].first.Idx()); - WriteNum((*retv)[i].second.GetFieldID()); - WriteNum((*retv)[i].second.GetPregIdx()); + RegFieldPair rfp = (*retv)[i].second; + if (rfp.IsReg()) { + MIRPreg *preg = curFunc->GetPregTab()->PregFromPregIdx(rfp.GetPregIdx()); + OutputPreg(preg); + } else { + WriteNum(0); + WriteNum((rfp.GetFieldID())); + OutputLocalSymbol(curFunc->GetLocalOrGlobalSymbol((*retv)[i].first)); + } } } @@ -398,7 +379,6 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { ExpandFourBuffSize(); // place holder, Fixup later for (StmtNode *s = block->GetFirst(); s; s = s->GetNext()) { bool doneWithOpnds = false; - WriteNum(kBinOpStatement); OutputSrcPos(s->GetSrcPos()); WriteNum(s->GetOpCode()); switch (s->GetOpCode()) { @@ -417,36 +397,35 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { } WriteNum(stIdx.Scope()); if (stIdx.Islocal()) { - WriteNum(stIdx.Idx()); // preserve original st index + OutputLocalSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx)); } else { - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(stIdx.Idx()); - WriteNum(kBinKindSymViaSymname); - OutputStr(sym->GetNameStrIdx()); + OutputSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx)); } break; } case OP_regassign: { RegassignNode *rass = static_cast(s); - WriteNum(rass->GetPrimType()); - WriteNum(rass->GetRegIdx()); + Write(static_cast(rass->GetPrimType())); + MIRPreg *preg = curFunc->GetPregTab()->PregFromPregIdx(rass->GetRegIdx()); + OutputPreg(preg); break; } case OP_iassign: { IassignNode *iass = static_cast(s); - OutputTypeViaTypeName(iass->GetTyIdx()); + OutputType(iass->GetTyIdx()); WriteNum(iass->GetFieldID()); break; } case OP_iassignoff: { IassignoffNode *iassoff = static_cast(s); - WriteNum(iassoff->GetPrimType()); + Write(static_cast(iassoff->GetPrimType())); WriteNum(iassoff->GetOffset()); break; } case OP_iassignspoff: case OP_iassignfpoff: { IassignFPoffNode *iassfpoff = static_cast(s); - WriteNum(iassfpoff->GetPrimType()); + Write(static_cast(iassfpoff->GetPrimType())); WriteNum(iassfpoff->GetOffset()); break; } @@ -466,9 +445,9 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { case OP_customcall: case OP_polymorphiccall: { CallNode *callnode = static_cast(s); - OutputFuncViaSymName(callnode->GetPUIdx()); + OutputFuncViaSym(callnode->GetPUIdx()); if (s->GetOpCode() == OP_polymorphiccall) { - OutputTypeViaTypeName(static_cast(callnode)->GetTyIdx()); + OutputType(static_cast(callnode)->GetTyIdx()); } WriteNum(static_cast(s->NumOpnds())); break; @@ -481,15 +460,15 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { case OP_interfaceicallassigned: case OP_customcallassigned: { CallNode *callnode = static_cast(s); - OutputFuncViaSymName(callnode->GetPUIdx()); + OutputFuncViaSym(callnode->GetPUIdx()); OutputReturnValues(&callnode->GetReturnVec()); WriteNum(static_cast(s->NumOpnds())); break; } case OP_polymorphiccallassigned: { CallNode *callnode = static_cast(s); - OutputFuncViaSymName(callnode->GetPUIdx()); - OutputTypeViaTypeName(callnode->GetTyIdx()); + OutputFuncViaSym(callnode->GetPUIdx()); + OutputType(callnode->GetTyIdx()); OutputReturnValues(&callnode->GetReturnVec()); WriteNum(static_cast(s->NumOpnds())); break; @@ -497,13 +476,14 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { case OP_icallproto: case OP_icall: { IcallNode *icallnode = static_cast(s); - OutputTypeViaTypeName(icallnode->GetRetTyIdx()); + OutputType(icallnode->GetRetTyIdx()); WriteNum(static_cast(s->NumOpnds())); break; } + case OP_icallprotoassigned: case OP_icallassigned: { IcallNode *icallnode = static_cast(s); - OutputTypeViaTypeName(icallnode->GetRetTyIdx()); + OutputType(icallnode->GetRetTyIdx()); OutputReturnValues(&icallnode->GetReturnVec()); WriteNum(static_cast(s->NumOpnds())); break; @@ -526,14 +506,14 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { case OP_intrinsiccallwithtype: { IntrinsiccallNode *intrnNode = static_cast(s); WriteNum(intrnNode->GetIntrinsic()); - OutputTypeViaTypeName(intrnNode->GetTyIdx()); + OutputType(intrnNode->GetTyIdx()); WriteNum(static_cast(s->NumOpnds())); break; } case OP_intrinsiccallwithtypeassigned: { IntrinsiccallNode *intrnNode = static_cast(s); WriteNum(intrnNode->GetIntrinsic()); - OutputTypeViaTypeName(intrnNode->GetTyIdx()); + OutputType(intrnNode->GetTyIdx()); OutputReturnValues(&intrnNode->GetReturnVec()); WriteNum(static_cast(s->NumOpnds())); break; @@ -568,28 +548,28 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { } case OP_label: { LabelNode *lNode = static_cast(s); - WriteNum(lNode->GetLabelIdx()); + OutputLabel(lNode->GetLabelIdx()); break; } case OP_goto: case OP_gosub: { GotoNode *gtoNode = static_cast(s); - WriteNum(gtoNode->GetOffset()); + OutputLabel(gtoNode->GetOffset()); break; } case OP_brfalse: case OP_brtrue: { CondGotoNode *cgotoNode = static_cast(s); - WriteNum(cgotoNode->GetOffset()); + OutputLabel(cgotoNode->GetOffset()); break; } case OP_switch: { SwitchNode *swNode = static_cast(s); - WriteNum(swNode->GetDefaultLabel()); + OutputLabel(swNode->GetDefaultLabel()); WriteNum(static_cast(swNode->GetSwitchTable().size())); for (CasePair cpair : swNode->GetSwitchTable()) { WriteNum(cpair.first); - WriteNum(cpair.second); + OutputLabel(cpair.second); } break; } @@ -599,14 +579,14 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { WriteNum(static_cast(rgoto->GetRangeGotoTable().size())); for (SmallCasePair cpair : rgoto->GetRangeGotoTable()) { WriteNum(cpair.first); - WriteNum(cpair.second); + OutputLabel(cpair.second); } break; } case OP_jstry: { JsTryNode *tryNode = static_cast(s); - WriteNum(tryNode->GetCatchOffset()); - WriteNum(tryNode->GetFinallyOffset()); + OutputLabel(tryNode->GetCatchOffset()); + OutputLabel(tryNode->GetFinallyOffset()); break; } case OP_cpptry: @@ -614,7 +594,7 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { TryNode *tryNode = static_cast(s); WriteNum(static_cast(tryNode->GetOffsetsCount())); for (LabelIdx lidx : tryNode->GetOffsets()) { - WriteNum(lidx); + OutputLabel(lidx); } break; } @@ -622,7 +602,7 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { CatchNode *catchNode = static_cast(s); WriteNum(static_cast(catchNode->GetExceptionTyIdxVec().size())); for (TyIdx tidx : catchNode->GetExceptionTyIdxVec()) { - OutputTypeViaTypeName(tidx); + OutputType(tidx); } break; } @@ -679,7 +659,7 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { count = asmNode->gotoLabels.size(); WriteNum(static_cast(count)); for (size_t i = 0; i < count; ++i) { - WriteNum(asmNode->gotoLabels[i]); + OutputLabel(asmNode->gotoLabels[i]); } // the inputs WriteNum(asmNode->NumOpnds()); @@ -714,6 +694,7 @@ void BinaryMplExport::WriteFunctionBodyField(uint64 contentIdx, std::unordered_s if (not2mplt) { for (MIRFunction *func : GetMIRModule().GetFunctionList()) { + curFunc = func; if (func->GetAttr(FUNCATTR_optimized)) { continue; } @@ -734,12 +715,15 @@ void BinaryMplExport::WriteFunctionBodyField(uint64 contentIdx, std::unordered_s continue; } } + localSymMark.clear(); + localSymMark[nullptr] = 0; + localPregMark.clear(); + localPregMark[nullptr] = 0; + labelMark.clear(); + labelMark[0] = 0; OutputFunction(func->GetPuidx()); CHECK_FATAL(func->GetBody() != nullptr, "WriteFunctionBodyField: no function body"); OutputFuncIdInfo(func); - OutputPregTab(func); - OutputLocalSymTab(func); - OutputLabelTab(func); OutputLocalTypeNameTab(func->GetTypeNameTab()); OutputFormalsStIdx(func); if (mod.GetFlavor() < kMmpl) { @@ -753,7 +737,6 @@ void BinaryMplExport::WriteFunctionBodyField(uint64 contentIdx, std::unordered_s Fixup(totalSizeIdx, static_cast(buf.size() - totalSizeIdx)); Fixup(outFunctionBodySizeIdx, size); - WriteNum(~kBinFunctionBodyStart); return; } } // namespace maple diff --git a/src/mapleall/maple_ir/src/bin_func_import.cpp b/src/mapleall/maple_ir/src/bin_func_import.cpp index 959784554b..b23b6895f4 100644 --- a/src/mapleall/maple_ir/src/bin_func_import.cpp +++ b/src/mapleall/maple_ir/src/bin_func_import.cpp @@ -44,29 +44,27 @@ void BinaryMplImport::ImportFuncIdInfo(MIRFunction *func) { func->SetPuidxOrigin(static_cast(ReadNum())); ImportInfoVector(func->GetInfoVector(), func->InfoIsString()); if (mod.GetFlavor() == kFlavorLmbc) { - func->SetUpFormalSize(static_cast(ReadNum())); func->SetFrameSize(static_cast(ReadNum())); - func->SetOutParmSize(static_cast(ReadNum())); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinFuncIdInfoStart, "pattern mismatch in ImportFuncIdInfo()"); } void BinaryMplImport::ImportBaseNode(Opcode &o, PrimType &typ) { - o = (Opcode)ReadNum(); - typ = (PrimType)ReadNum(); + o = (Opcode)Read(); + typ = (PrimType)Read(); } -void BinaryMplImport::ImportLocalSymbol(MIRFunction *func) { +MIRSymbol *BinaryMplImport::ImportLocalSymbol(MIRFunction *func) { int64 tag = ReadNum(); if (tag == 0) { - func->GetSymTab()->PushNullSymbol(); - return; + return nullptr; } + if (tag < 0) { + CHECK_FATAL(static_cast(-tag) < localSymTab.size(), "index out of bounds"); + return localSymTab.at(-tag); + } CHECK_FATAL(tag == kBinSymbol, "expecting kBinSymbol in ImportLocalSymbol()"); - auto indx = static_cast(ReadNum()); - CHECK_FATAL(indx == func->GetSymTab()->GetSymbolTableSize(), "inconsistant local stIdx"); MIRSymbol *sym = func->GetSymTab()->CreateSymbol(kScopeLocal); + localSymTab.push_back(sym); sym->SetNameStrIdx(ImportStr()); (void)func->GetSymTab()->AddToStringSymbolMap(*sym); sym->SetSKind((MIRSymKind)ReadNum()); @@ -78,66 +76,52 @@ void BinaryMplImport::ImportLocalSymbol(MIRFunction *func) { } sym->SetTyIdx(ImportType()); if (sym->GetSKind() == kStPreg) { - auto thepregno = static_cast(ReadNum()); - MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx()); - PregIdx pregidx = func->GetPregTab()->EnterPregNo(thepregno, mirType->GetPrimType(), mirType); - MIRPregTable *pregTab = func->GetPregTab(); - MIRPreg *preg = pregTab->PregFromPregIdx(pregidx); - preg->SetPrimType(mirType->GetPrimType()); + PregIdx pregidx = ImportPreg(func); + MIRPreg *preg = func->GetPregTab()->PregFromPregIdx(pregidx); sym->SetPreg(preg); } else if (sym->GetSKind() == kStConst || sym->GetSKind() == kStVar) { sym->SetKonst(ImportConst(func)); } else if (sym->GetSKind() == kStFunc) { - PUIdx puIdx = ImportFuncViaSymName(); - TyIdx tyIdx = ImportType(); - sym->SetTyIdx(tyIdx); + PUIdx puIdx = ImportFuncViaSym(func); sym->SetFunction(GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx)); } + return sym; } -void BinaryMplImport::ImportLocalSymTab(MIRFunction *func) { +PregIdx BinaryMplImport::ImportPreg(MIRFunction *func) { int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinSymStart, "kBinSymStart expected in ImportLocalSymTab()"); - int32 size = ReadInt(); - for (int64 i = 0; i < size; ++i) { - ImportLocalSymbol(func); + if (tag == 0) { + return 0; } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinSymStart, "pattern mismatch in ImportLocalSymTab()"); -} - -void BinaryMplImport::ImportPregTab(const MIRFunction *func) { - int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinPregStart, "kBinPregStart expected in ImportPregTab()"); - int32 size = ReadInt(); - for (int64 i = 0; i < size; ++i) { - int64 nextTag = ReadNum(); - if (nextTag == 0) { - func->GetPregTab()->GetPregTable().push_back(nullptr); - continue; - } - CHECK_FATAL(nextTag == kBinPreg, "expecting kBinPreg in ImportPregTab()"); - auto pregNo = static_cast(ReadNum()); - TyIdx tyIdx = ImportType(); - MIRType *ty = (tyIdx == 0) ? nullptr : GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); - PrimType primType = (PrimType)ReadNum(); - CHECK_FATAL(ty == nullptr || primType == ty->GetPrimType(), "ImportPregTab: inconsistent primitive type"); - (void)func->GetPregTab()->EnterPregNo(pregNo, primType, ty); + if (tag == kBinSpecialReg) { + return -Read(); + } + if (tag < 0) { + CHECK_FATAL(static_cast(-tag) < localPregTab.size(), "index out of bounds"); + return localPregTab.at(-tag); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinPregStart, "pattern mismatch in ImportPregTab()"); + CHECK_FATAL(tag == kBinPreg, "expecting kBinPreg in ImportPreg()"); + + PrimType primType = (PrimType)Read(); + PregIdx pidx = func->GetPregTab()->CreatePreg(primType); + localPregTab.push_back(pidx); + return pidx; } -void BinaryMplImport::ImportLabelTab(MIRFunction *func) { +LabelIdx BinaryMplImport::ImportLabel(MIRFunction *func) { int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinLabelStart, "kBinLabelStart expected in ImportLabelTab()"); - int64 size = ReadNum(); - for (int64 i = 0; i < size; ++i) { - GStrIdx gStrIdx = ImportStr(); - (void)func->GetLabelTab()->AddLabel(gStrIdx); + if (tag == 0) { + return 0; + } + if (tag < 0) { + CHECK_FATAL(static_cast(-tag) < localLabelTab.size(), "index out of bounds"); + return localLabelTab.at(-tag); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinLabelStart, "pattern mismatch in ImportLabelTab()"); + CHECK_FATAL(tag == kBinLabel, "kBinLabel expected in ImportLabel()"); + + LabelIdx lidx = func->GetLabelTab()->CreateLabel(); + localLabelTab.push_back(lidx); + return lidx; } void BinaryMplImport::ImportLocalTypeNameTable(MIRTypeNameTable *typeNameTab) { @@ -149,8 +133,6 @@ void BinaryMplImport::ImportLocalTypeNameTable(MIRTypeNameTable *typeNameTab) { TyIdx tyIdx = ImportType(); typeNameTab->SetGStrIdxToTyIdx(strIdx, tyIdx); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinTypenameStart, "pattern mismatch in ImportTypenametab()"); } void BinaryMplImport::ImportFormalsStIdx(MIRFunction *func) { @@ -158,11 +140,8 @@ void BinaryMplImport::ImportFormalsStIdx(MIRFunction *func) { CHECK_FATAL(tag == kBinFormalStart, "kBinFormalStart expected in ImportFormalsStIdx()"); auto size = ReadNum(); for (int64 i = 0; i < size; ++i) { - uint32 indx = static_cast(ReadNum()); - func->GetFormalDefVec()[static_cast(i)].formalSym = func->GetSymTab()->GetSymbolFromStIdx(indx); + func->GetFormalDefVec()[static_cast(i)].formalSym = ImportLocalSymbol(func); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinFormalStart, "pattern mismatch in ImportFormalsStIdx()"); } void BinaryMplImport::ImportAliasMap(MIRFunction *func) { @@ -177,23 +156,15 @@ void BinaryMplImport::ImportAliasMap(MIRFunction *func) { (void)ImportStr(); // not assigning to mimic parser func->GetAliasVarMap()[strIdx] = aliasvars; } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinAliasMapStart, "pattern mismatch in ImportAliasMap()"); } -PUIdx BinaryMplImport::ImportFuncViaSymName() { - int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinKindFuncViaSymname, "kBinKindFuncViaSymname expected"); - GStrIdx strIdx = ImportStr(); - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx); - ASSERT(sym != nullptr, "null ptr check"); - MIRFunction *func = sym->GetFunction(); - return func->GetPuidx(); +PUIdx BinaryMplImport::ImportFuncViaSym(MIRFunction *func) { + MIRSymbol *sym = InSymbol(func); + MIRFunction *f = sym->GetFunction(); + return f->GetPuidx(); } BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { - int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinOpExpression, "kBinOpExpression expected"); Opcode op; PrimType typ; ImportBaseNode(op, typ); @@ -213,13 +184,15 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { } case OP_addroflabel: { AddroflabelNode *alabNode = mod.CurFuncCodeMemPool()->New(); - alabNode->SetOffset(static_cast(ReadNum())); + alabNode->SetOffset(ImportLabel(func)); alabNode->SetPrimType(typ); (void)func->GetLabelTab()->addrTakenLabels.insert(alabNode->GetOffset()); return alabNode; } case OP_addroffunc: { - PUIdx puIdx = ImportFuncViaSymName(); + PUIdx puIdx = ImportFuncViaSym(func); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFuncTable()[puIdx]; + f->GetFuncSymbol()->SetAppearsInCode(true); AddroffuncNode *addrNode = mod.CurFuncCodeMemPool()->New(typ, puIdx); return addrNode; } @@ -235,19 +208,18 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { int32 num = static_cast(ReadNum()); StIdx stIdx; stIdx.SetScope(static_cast(ReadNum())); + MIRSymbol *sym = nullptr; if (stIdx.Islocal()) { - stIdx.SetIdx(static_cast(ReadNum())); + sym = ImportLocalSymbol(func); + CHECK_FATAL(sym != nullptr, "null ptr check"); } else { - int32 stag = static_cast(ReadNum()); - CHECK_FATAL(stag == kBinKindSymViaSymname, "kBinKindSymViaSymname expected"); - GStrIdx strIdx = ImportStr(); - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx); - ASSERT(sym != nullptr, "null ptr check"); + sym = InSymbol(func); + CHECK_FATAL(sym != nullptr, "null ptr check"); if (op == OP_addrof) { sym->SetHasPotentialAssignment(); } - stIdx.SetIdx(sym->GetStIdx().Idx()); } + stIdx.SetIdx(sym->GetStIdx().Idx()); if (op == OP_addrof || op == OP_dread) { AddrofNode *drNode = mod.CurFuncCodeMemPool()->New(op); drNode->SetPrimType(typ); @@ -264,7 +236,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { } case OP_regread: { RegreadNode *regreadNode = mod.CurFuncCodeMemPool()->New(); - regreadNode->SetRegIdx(static_cast(ReadNum())); + regreadNode->SetRegIdx(ImportPreg(func)); regreadNode->SetPrimType(typ); return regreadNode; } @@ -293,7 +265,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_floor: case OP_trunc: { TypeCvtNode *typecvtNode = mod.CurFuncCodeMemPool()->New(op, typ); - typecvtNode->SetFromType((PrimType)ReadNum()); + typecvtNode->SetFromType((PrimType)Read()); typecvtNode->SetOpnd(ImportExpression(func), 0); return typecvtNode; } @@ -326,15 +298,15 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_zext: case OP_extractbits: { ExtractbitsNode *extNode = mod.CurFuncCodeMemPool()->New(op, typ); - extNode->SetBitsOffset(static_cast(ReadNum())); - extNode->SetBitsSize(static_cast(ReadNum())); + extNode->SetBitsOffset(Read()); + extNode->SetBitsSize(Read()); extNode->SetOpnd(ImportExpression(func), 0); return extNode; } case OP_depositbits: { DepositbitsNode *dbNode = mod.CurFuncCodeMemPool()->New(op, typ); - dbNode->SetBitsOffset(static_cast(ReadNum())); - dbNode->SetBitsSize(static_cast(ReadNum())); + dbNode->SetBitsOffset(ReadNum()); + dbNode->SetBitsSize(ReadNum()); dbNode->SetOpnd(ImportExpression(func), 0); dbNode->SetOpnd(ImportExpression(func), 1); return dbNode; @@ -379,7 +351,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_cmpl: case OP_cmp: { CompareNode *cmpNode = mod.CurFuncCodeMemPool()->New(op, typ); - cmpNode->SetOpndType((PrimType)ReadNum()); + cmpNode->SetOpndType((PrimType)Read()); cmpNode->SetOpnd(ImportExpression(func), 0); cmpNode->SetOpnd(ImportExpression(func), 1); return cmpNode; @@ -387,7 +359,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_resolveinterfacefunc: case OP_resolvevirtualfunc: { ResolveFuncNode *rsNode = mod.CurFuncCodeMemPool()->New(op, typ); - rsNode->SetPUIdx(ImportFuncViaSymName()); + rsNode->SetPUIdx(ImportFuncViaSym(func)); rsNode->SetOpnd(ImportExpression(func), 0); rsNode->SetOpnd(ImportExpression(func), 1); return rsNode; @@ -403,7 +375,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { // nary case OP_array: { TyIdx tidx = ImportType(); - auto boundsCheck = static_cast(ReadNum()); + bool boundsCheck = static_cast(Read()); ArrayNode *arrNode = mod.CurFuncCodeMemPool()->New(func->GetCodeMPAllocator(), typ, tidx, boundsCheck); auto n = static_cast(ReadNum()); @@ -436,12 +408,15 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { return intrnNode; } default: - CHECK_FATAL(false, "Unhandled op %d", tag); + CHECK_FATAL(false, "Unhandled op %d", op); break; } } void BinaryMplImport::ImportSrcPos(SrcPosition &pos) { + if (!mod.IsWithDbgInfo()) { + return; + } pos.SetRawData(static_cast(ReadNum())); pos.SetLineNum(static_cast(ReadNum())); } @@ -451,15 +426,16 @@ void BinaryMplImport::ImportReturnValues(MIRFunction *func, CallReturnVector *re CHECK_FATAL(tag == kBinReturnvals, "expecting return values"); auto size = static_cast(ReadNum()); for (uint32 i = 0; i < size; ++i) { - uint32 idx = static_cast(ReadNum()); - FieldID fid = static_cast(ReadNum()); - PregIdx ridx = static_cast(ReadNum()); - retv->push_back(std::make_pair(StIdx(kScopeLocal, idx), RegFieldPair(fid, ridx))); - if (idx == 0) { + RegFieldPair rfp; + rfp.SetPregIdx(ImportPreg(func)); + if (rfp.IsReg()) { + retv->push_back(std::make_pair(StIdx(), rfp)); continue; } - MIRSymbol *lsym = func->GetSymTab()->GetSymbolFromStIdx(idx, false); - ASSERT(lsym != nullptr, "null ptr check"); + rfp.SetFieldID(static_cast(ReadNum())); + MIRSymbol *lsym = ImportLocalSymbol(func); + CHECK_FATAL(lsym != nullptr, "null ptr check"); + retv->push_back(std::make_pair(lsym->GetStIdx(), rfp)); if (lsym->GetName().find("L_STR") == 0) { MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(lsym->GetTyIdx()); CHECK_FATAL(ty->GetKind() == kTypePointer, "Pointer type expected for L_STR prefix"); @@ -480,8 +456,6 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { ImportSrcPos(block->GetSrcPos()); int32 size = ReadInt(); for (int32 k = 0; k < size; ++k) { - tag = ReadNum(); - CHECK_FATAL(tag == kBinOpStatement, "kBinOpStatement expected"); SrcPosition thesrcPosition; ImportSrcPos(thesrcPosition); op = (Opcode)ReadNum(); @@ -496,17 +470,16 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { int32 num = static_cast(ReadNum()); StIdx stIdx; stIdx.SetScope(static_cast(ReadNum())); + MIRSymbol *sym = nullptr; if (stIdx.Islocal()) { - stIdx.SetIdx(static_cast(ReadNum())); + sym = ImportLocalSymbol(func); + CHECK_FATAL(sym != nullptr, "null ptr check"); } else { - int32 stag = static_cast(ReadNum()); - CHECK_FATAL(stag == kBinKindSymViaSymname, "kBinKindSymViaSymname expected"); - GStrIdx strIdx = ImportStr(); - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx); - ASSERT(sym != nullptr, "null ptr check"); + sym = InSymbol(func); + CHECK_FATAL(sym != nullptr, "null ptr check"); sym->SetHasPotentialAssignment(); - stIdx.SetIdx(sym->GetStIdx().Idx()); } + stIdx.SetIdx(sym->GetStIdx().Idx()); if (op == OP_dassign) { DassignNode *s = func->GetCodeMemPool()->New(); s->SetStIdx(stIdx); @@ -525,8 +498,8 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_regassign: { RegassignNode *s = func->GetCodeMemPool()->New(); - s->SetPrimType((PrimType)ReadNum()); - s->SetRegIdx(static_cast(ReadNum())); + s->SetPrimType((PrimType)Read()); + s->SetRegIdx(ImportPreg(func)); s->SetOpnd(ImportExpression(func), 0); stmt = s; break; @@ -542,7 +515,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_iassignoff: { IassignoffNode *s = func->GetCodeMemPool()->New(); - s->SetPrimType((PrimType)ReadNum()); + s->SetPrimType((PrimType)Read()); s->SetOffset(static_cast(ReadNum())); s->SetOpnd(ImportExpression(func), 0); s->SetOpnd(ImportExpression(func), 1); @@ -552,7 +525,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { case OP_iassignspoff: case OP_iassignfpoff: { IassignFPoffNode *s = func->GetCodeMemPool()->New(op); - s->SetPrimType((PrimType)ReadNum()); + s->SetPrimType((PrimType)Read()); s->SetOffset(static_cast(ReadNum())); s->SetOpnd(ImportExpression(func), 0); stmt = s; @@ -577,7 +550,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { case OP_interfaceicall: case OP_customcall: { CallNode *s = func->GetCodeMemPool()->New(mod, op); - s->SetPUIdx(ImportFuncViaSymName()); + s->SetPUIdx(ImportFuncViaSym(func)); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx()); + f->GetFuncSymbol()->SetAppearsInCode(true); numOpr = static_cast(ReadNum()); s->SetNumOpnds(numOpr); for (int32 i = 0; i < numOpr; ++i) { @@ -594,7 +569,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { case OP_interfaceicallassigned: case OP_customcallassigned: { CallNode *s = func->GetCodeMemPool()->New(mod, op); - s->SetPUIdx(ImportFuncViaSymName()); + s->SetPUIdx(ImportFuncViaSym(func)); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx()); + f->GetFuncSymbol()->SetAppearsInCode(true); ImportReturnValues(func, &s->GetReturnVec()); numOpr = static_cast(ReadNum()); s->SetNumOpnds(numOpr); @@ -610,7 +587,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_polymorphiccall: { CallNode *s = func->GetCodeMemPool()->New(mod, op); - s->SetPUIdx(ImportFuncViaSymName()); + s->SetPUIdx(ImportFuncViaSym(func)); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx()); + f->GetFuncSymbol()->SetAppearsInCode(true); s->SetTyIdx(ImportType()); numOpr = static_cast(ReadNum()); s->SetNumOpnds(numOpr); @@ -622,7 +601,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_polymorphiccallassigned: { CallNode *s = func->GetCodeMemPool()->New(mod, op); - s->SetPUIdx(ImportFuncViaSymName()); + s->SetPUIdx(ImportFuncViaSym(func)); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx()); + f->GetFuncSymbol()->SetAppearsInCode(true); s->SetTyIdx(ImportType()); ImportReturnValues(func, &s->GetReturnVec()); numOpr = static_cast(ReadNum()); @@ -645,6 +626,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { stmt = s; break; } + case OP_icallprotoassigned: case OP_icallassigned: { IcallNode *s = func->GetCodeMemPool()->New(mod, op); s->SetRetTyIdx(ImportType()); @@ -759,32 +741,32 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_label: { LabelNode *s = mod.CurFuncCodeMemPool()->New(); - s->SetLabelIdx(static_cast(ReadNum())); + s->SetLabelIdx(ImportLabel(func)); stmt = s; break; } case OP_goto: case OP_gosub: { GotoNode *s = mod.CurFuncCodeMemPool()->New(op); - s->SetOffset(static_cast(ReadNum())); + s->SetOffset(ImportLabel(func)); stmt = s; break; } case OP_brfalse: case OP_brtrue: { CondGotoNode *s = mod.CurFuncCodeMemPool()->New(op); - s->SetOffset(static_cast(ReadNum())); + s->SetOffset(ImportLabel(func)); s->SetOpnd(ImportExpression(func), 0); stmt = s; break; } case OP_switch: { SwitchNode *s = mod.CurFuncCodeMemPool()->New(mod); - s->SetDefaultLabel(static_cast(ReadNum())); + s->SetDefaultLabel(ImportLabel(func)); auto tagSize = static_cast(ReadNum()); for (uint32 i = 0; i < tagSize; ++i) { int64 casetag = ReadNum(); - LabelIdx lidx(ReadNum()); + LabelIdx lidx = ImportLabel(func); CasePair cpair = std::make_pair(casetag, lidx); s->GetSwitchTable().push_back(cpair); } @@ -798,7 +780,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { uint32 tagSize = static_cast(ReadNum()); for (uint32 i = 0; i < tagSize; ++i) { uint16 casetag = static_cast(ReadNum()); - LabelIdx lidx(ReadNum()); + LabelIdx lidx = ImportLabel(func); s->AddRangeGoto(casetag, lidx); } s->SetOpnd(ImportExpression(func), 0); @@ -807,8 +789,8 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_jstry: { JsTryNode *s = mod.CurFuncCodeMemPool()->New(); - s->SetCatchOffset(static_cast(ReadNum())); - s->SetFinallyOffset(static_cast(ReadNum())); + s->SetCatchOffset(ImportLabel(func)); + s->SetFinallyOffset(ImportLabel(func)); stmt = s; break; } @@ -817,7 +799,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { TryNode *s = mod.CurFuncCodeMemPool()->New(mod); auto numLabels = static_cast(ReadNum()); for (uint32 i = 0; i < numLabels; ++i) { - s->GetOffsets().push_back(ReadNum()); + s->GetOffsets().push_back(ImportLabel(func)); } stmt = s; break; @@ -887,7 +869,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { // the labels count = static_cast(ReadNum()); for (size_t i = 0; i < count; ++i) { - auto lidx = static_cast(ReadNum()); + LabelIdx lidx = ImportLabel(func); s->gotoLabels.push_back(lidx); } // the inputs @@ -927,6 +909,13 @@ void BinaryMplImport::ReadFunctionBodyField() { PUIdx puIdx = ImportFunction(); MIRFunction *fn = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); mod.SetCurFunction(fn); + fn->GetFuncSymbol()->SetAppearsInCode(true); + localSymTab.clear(); + localSymTab.push_back(nullptr); + localPregTab.clear(); + localPregTab.push_back(0); + localLabelTab.clear(); + localLabelTab.push_back(0); fn->AllocSymTab(); fn->AllocPregTab(); @@ -934,9 +923,6 @@ void BinaryMplImport::ReadFunctionBodyField() { fn->AllocLabelTab(); ImportFuncIdInfo(fn); - ImportPregTab(fn); - ImportLocalSymTab(fn); - ImportLabelTab(fn); ImportLocalTypeNameTable(fn->GetTypeNameTab()); ImportFormalsStIdx(fn); if (mod.GetFlavor() < kMmpl) { @@ -945,8 +931,6 @@ void BinaryMplImport::ReadFunctionBodyField() { (void)ImportBlockNode(fn); mod.AddFunction(fn); } - int64 tag = ReadNum(); - CHECK_FATAL(tag == ~kBinFunctionBodyStart, "pattern mismatch in Read FunctionBody"); return; } } // namespace maple diff --git a/src/mapleall/maple_ir/src/bin_mpl_export.cpp b/src/mapleall/maple_ir/src/bin_mpl_export.cpp index 0a226f1339..486b7eb24b 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_export.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_export.cpp @@ -26,7 +26,7 @@ namespace { using namespace maple; using OutputConstFactory = FunctionFactory; -using OutputTypeFactory = FunctionFactory; +using OutputTypeFactory = FunctionFactory; void OutputConstInt(const MIRConst &constVal, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindConstInt); @@ -62,7 +62,7 @@ void OutputConstLbl(const MIRConst &constVal, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindConstAddrofLabel); mplExport.OutputConstBase(constVal); const MIRLblConst &lblConst = static_cast(constVal); - mplExport.WriteNum(lblConst.GetValue()); // LabelIdx not needed to output puIdx + mplExport.OutputLabel(lblConst.GetValue()); } void OutputConstStr(const MIRConst &constVal, BinaryMplExport &mplExport) { @@ -141,39 +141,39 @@ static bool InitOutputConstFactory() { return true; } -void OutputTypeScalar(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeScalar(const MIRType &ty, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindTypeScalar); mplExport.OutputTypeBase(ty); } -void OutputTypePointer(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypePointer(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypePointer); mplExport.OutputTypeBase(type); mplExport.OutputTypeAttrs(type.GetTypeAttrs()); - mplExport.OutputType(type.GetPointedTyIdx(), canUseTypename); + mplExport.OutputType(type.GetPointedTyIdx()); } -void OutputTypeByName(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeByName(const MIRType &ty, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindTypeByName); mplExport.OutputTypeBase(ty); } -void OutputTypeFArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeFArray(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeFArray); mplExport.OutputTypeBase(type); - mplExport.OutputType(type.GetElemTyIdx(), canUseTypename); + mplExport.OutputType(type.GetElemTyIdx()); } -void OutputTypeJArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeJArray(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeJarray); mplExport.OutputTypeBase(type); - mplExport.OutputType(type.GetElemTyIdx(), canUseTypename); + mplExport.OutputType(type.GetElemTyIdx()); } -void OutputTypeArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeArray(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeArray); mplExport.OutputTypeBase(type); @@ -181,20 +181,20 @@ void OutputTypeArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseT for (uint16 i = 0; i < type.GetDim(); ++i) { mplExport.WriteNum(type.GetSizeArrayItem(i)); } - mplExport.OutputType(type.GetElemTyIdx(), canUseTypename); + mplExport.OutputType(type.GetElemTyIdx()); mplExport.OutputTypeAttrs(type.GetTypeAttrs()); } -void OutputTypeFunction(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeFunction(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeFunction); mplExport.OutputTypeBase(type); - mplExport.OutputType(type.GetRetTyIdx(), canUseTypename); - mplExport.WriteNum(type.IsVarargs()); + mplExport.OutputType(type.GetRetTyIdx()); + mplExport.WriteNum(type.funcAttrs.GetAttrFlag()); size_t size = type.GetParamTypeList().size(); mplExport.WriteNum(size); for (size_t i = 0; i < size; ++i) { - mplExport.OutputType(type.GetNthParamType(i), canUseTypename); + mplExport.OutputType(type.GetNthParamType(i)); } size = type.GetParamAttrsList().size(); mplExport.WriteNum(size); @@ -203,13 +203,13 @@ void OutputTypeFunction(const MIRType &ty, BinaryMplExport &mplExport, bool canU } } -void OutputTypeParam(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeParam(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeParam); mplExport.OutputTypeBase(type); } -void OutputTypeInstantVector(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeInstantVector(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeInstantVector); mplExport.OutputTypeBase(type); @@ -217,15 +217,15 @@ void OutputTypeInstantVector(const MIRType &ty, BinaryMplExport &mplExport, bool mplExport.OutputTypePairs(type); } -void OutputTypeGenericInstant(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeGenericInstant(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeGenericInstant); mplExport.OutputTypeBase(type); mplExport.OutputTypePairs(type); - mplExport.OutputType(type.GetGenericTyIdx(), canUseTypename); + mplExport.OutputType(type.GetGenericTyIdx()); } -void OutputTypeBitField(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeBitField(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeBitField); mplExport.OutputTypeBase(type); @@ -233,7 +233,7 @@ void OutputTypeBitField(const MIRType &ty, BinaryMplExport &mplExport, bool) { } // for Struct/StructIncomplete/Union -void OutputTypeStruct(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeStruct(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeStruct); mplExport.OutputTypeBase(type); @@ -249,7 +249,7 @@ void OutputTypeStruct(const MIRType &ty, BinaryMplExport &mplExport, bool) { } } -void OutputTypeClass(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeClass(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeClass); mplExport.OutputTypeBase(type); @@ -264,7 +264,7 @@ void OutputTypeClass(const MIRType &ty, BinaryMplExport &mplExport, bool) { } } -void OutputTypeInterface(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeInterface(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeInterface); mplExport.OutputTypeBase(type); @@ -279,7 +279,7 @@ void OutputTypeInterface(const MIRType &ty, BinaryMplExport &mplExport, bool) { } } -void OutputTypeConstString(const MIRType &ty, BinaryMplExport&, bool) { +void OutputTypeConstString(const MIRType &ty, BinaryMplExport&) { ASSERT(false, "Type's kind not yet implemented: %d", ty.GetKind()); (void)ty; } @@ -397,7 +397,7 @@ void BinaryMplExport::DumpBuf(const std::string &name) { void BinaryMplExport::OutputConstBase(const MIRConst &constVal) { WriteNum(constVal.GetKind()); - OutputTypeViaTypeName(constVal.GetType().GetTypeIndex()); + OutputType(constVal.GetType().GetTypeIndex()); } void BinaryMplExport::OutputConst(MIRConst *constVal) { @@ -470,8 +470,8 @@ void BinaryMplExport::OutputPragma(const MIRPragma &p) { WriteNum(p.GetKind()); WriteNum(p.GetVisibility()); OutputStr(p.GetStrIdx()); - OutputType(p.GetTyIdx(), false); - OutputType(p.GetTyIdxEx(), false); + OutputType(p.GetTyIdx()); + OutputType(p.GetTyIdxEx()); WriteNum(p.GetParamNum()); size_t size = p.GetElementVector().size(); WriteNum(size); @@ -488,7 +488,7 @@ void BinaryMplExport::OutputTypeBase(const MIRType &type) { void BinaryMplExport::OutputFieldPair(const FieldPair &fp) { OutputStr(fp.first); // GStrIdx - OutputType(fp.second.first, false); // TyIdx + OutputType(fp.second.first); // TyIdx FieldAttrs fa = fp.second.second; WriteNum(fa.GetAttrFlag()); WriteNum(fa.GetAlignValue()); @@ -511,7 +511,7 @@ void BinaryMplExport::OutputMethodPair(const MethodPair &memPool) { MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(memPool.first.Idx()); CHECK_FATAL(funcSt != nullptr, "Pointer funcSt is nullptr, can't get symbol! Check it!"); WriteAsciiStr(GlobalTables::GetStrTable().GetStringFromStrIdx(funcSt->GetNameStrIdx())); - OutputType(memPool.second.first, false); // TyIdx + OutputType(memPool.second.first); // TyIdx WriteNum(memPool.second.second.GetAttrFlag()); // FuncAttrs } @@ -539,7 +539,7 @@ void BinaryMplExport::OutputStructTypeData(const MIRStructType &type) { void BinaryMplExport::OutputImplementedInterfaces(const std::vector &interfaces) { WriteNum(interfaces.size()); for (const TyIdx &tyIdx : interfaces) { - OutputType(tyIdx, false); + OutputType(tyIdx); } } @@ -571,7 +571,7 @@ void BinaryMplExport::OutputPragmaVec(const std::vector &pragmaVec) } void BinaryMplExport::OutputClassTypeData(const MIRClassType &type) { - OutputType(type.GetParentTyIdx(), false); + OutputType(type.GetParentTyIdx()); OutputImplementedInterfaces(type.GetInterfaceImplemented()); OutputInfoIsString(type.GetInfoIsString()); if (!inIPA) { @@ -601,6 +601,7 @@ void BinaryMplExport::Init() { symMark[nullptr] = 0; funcMark[nullptr] = 0; eaNodeMark[nullptr] = 0; + curFunc = nullptr; for (uint32 pti = static_cast(PTY_begin); pti < static_cast(PTY_end); ++pti) { typMark[GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(pti))] = pti; } @@ -612,7 +613,7 @@ void BinaryMplExport::OutputSymbol(MIRSymbol *sym) { return; } - auto it = symMark.find(sym); + std::unordered_map::iterator it = symMark.find(sym); if (it != symMark.end()) { WriteNum(-(it->second)); return; @@ -645,7 +646,7 @@ void BinaryMplExport::OutputSymbol(MIRSymbol *sym) { if (sym->GetSKind() == kStVar || sym->GetSKind() == kStFunc) { OutputSrcPos(sym->GetSrcPosition()); } - OutputTypeViaTypeName(sym->GetTyIdx()); + OutputType(sym->GetTyIdx()); } void BinaryMplExport::OutputFunction(PUIdx puIdx) { @@ -671,7 +672,7 @@ void BinaryMplExport::OutputFunction(PUIdx puIdx) { MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx()); CHECK_FATAL(funcSt != nullptr, "Pointer funcSt is nullptr, cannot get symbol! Check it!"); OutputSymbol(funcSt); - OutputTypeViaTypeName(func->GetMIRFuncType()->GetTypeIndex()); + OutputType(func->GetMIRFuncType()->GetTypeIndex()); WriteNum(func->GetFuncAttrs().GetAttrFlag()); auto &attributes = func->GetFuncAttrs(); @@ -684,12 +685,12 @@ void BinaryMplExport::OutputFunction(PUIdx puIdx) { } WriteNum(func->GetFlag()); - OutputTypeViaTypeName(func->GetClassTyIdx()); + OutputType(func->GetClassTyIdx()); // output formal parameter information WriteNum(static_cast(func->GetFormalDefVec().size())); for (FormalDef formalDef : func->GetFormalDefVec()) { OutputStr(formalDef.formalStrIdx); - OutputType(formalDef.formalTyIdx, false); + OutputType(formalDef.formalTyIdx); WriteNum(static_cast(formalDef.formalAttrs.GetAttrFlag())); } // store Side Effect for each func @@ -751,15 +752,20 @@ void BinaryMplExport::WriteHeaderField(uint64 contentIdx) { WriteNum(mod.GetID()); if (mod.GetFlavor() == kFlavorLmbc) { WriteNum(mod.GetGlobalMemSize()); + WriteNum(mod.IsWithDbgInfo()); } WriteNum(mod.GetNumFuncs()); WriteAsciiStr(mod.GetEntryFuncName()); OutputInfoVector(mod.GetFileInfo(), mod.GetFileInfoIsString()); - WriteNum(static_cast(mod.GetSrcFileInfo().size())); - for (uint32 i = 0; i < mod.GetSrcFileInfo().size(); i++) { - OutputStr(mod.GetSrcFileInfo()[i].first); - WriteNum(mod.GetSrcFileInfo()[i].second); + if (mod.IsWithDbgInfo()) { + WriteNum(static_cast(mod.GetSrcFileInfo().size())); + for (uint32 i = 0; i < mod.GetSrcFileInfo().size(); i++) { + OutputStr(mod.GetSrcFileInfo()[i].first); + WriteNum(mod.GetSrcFileInfo()[i].second); + } + } else { + Write(0); } WriteNum(static_cast(mod.GetImportFiles().size())); @@ -795,7 +801,7 @@ void BinaryMplExport::WriteTypeField(uint64 contentIdx, bool useClassList) { auto *structType = static_cast(type); // skip imported class/interface and incomplete types if (!structType->IsImported() && !structType->IsIncomplete()) { - OutputType(curTyidx, false); + OutputType(curTyidx); ++size; } } @@ -803,7 +809,7 @@ void BinaryMplExport::WriteTypeField(uint64 contentIdx, bool useClassList) { } else { uint32 idx = GlobalTables::GetTypeTable().lastDefaultTyIdx.GetIdx(); for (idx = idx + 1; idx < GlobalTables::GetTypeTable().GetTypeTableSize(); idx++) { - OutputType(TyIdx(idx), false); + OutputType(TyIdx(idx)); size++; } } @@ -884,7 +890,7 @@ void BinaryMplExport::WriteSeField() { GlobalTables::GetGsymTable().GetSymbolFromStrIdx(GlobalTables::GetStrTable().GetStrIdxFromName(funcStr)); MIRFunction *func = (funcSymbol != nullptr) ? GetMIRModule().GetMIRBuilder()->GetFunctionFromSymbol(*funcSymbol) : nullptr; - OutputType(func->GetReturnTyIdx(), false); + OutputType(func->GetReturnTyIdx()); } ++size; } @@ -1103,7 +1109,7 @@ void BinaryMplExport::WriteSymField(uint64 contentIdx) { MIRSymKind sKind = s->GetSKind(); if (s->IsDeleted() || storageClass == kScUnused || (s->GetIsImported() && !s->GetAppearsInCode()) || - (storageClass == kScExtern && sKind == kStFunc)) { + (sKind == kStFunc && (storageClass == kScExtern || !s->GetAppearsInCode()))) { continue; } OutputSymbol(s); @@ -1214,8 +1220,6 @@ void BinaryMplExport::Export(const std::string &fname, std::unordered_setIsNameIsLocal() && ty->GetNameStrIdx() != GStrIdx(0)) { - WriteNum(kBinKindTypeViaTypename); - OutputStr(ty->GetNameStrIdx()); - return; - } - auto func = CreateProductFunction(ty->GetKind()); if (func != nullptr) { - func(*ty, *this, canUseTypename); + func(*ty, *this); } else { ASSERT(false, "Type's kind not yet implemented: %d", ty->GetKind()); } diff --git a/src/mapleall/maple_ir/src/bin_mpl_import.cpp b/src/mapleall/maple_ir/src/bin_mpl_import.cpp index 50779027df..1f79751ed6 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_import.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_import.cpp @@ -129,11 +129,13 @@ MIRConst *BinaryMplImport::ImportConst(MIRFunction *func) { } case kBinKindConstAddrofFunc: { PUIdx puIdx = ImportFunction(); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFuncTable()[puIdx]; + f->GetFuncSymbol()->SetAppearsInCode(true); mod.SetCurFunction(func); return memPool->New(puIdx, *type); } case kBinKindConstAddrofLabel: { - LabelIdx lidx = static_cast(ReadNum()); + LabelIdx lidx = ImportLabel(func); PUIdx puIdx = func->GetPuidx(); MIRLblConst *lblConst = memPool->New(lidx, puIdx, *type); (void)func->GetLabelTab()->addrTakenLabels.insert(lidx); @@ -541,19 +543,6 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { CHECK_FATAL(static_cast(-tag) < typTab.size(), "index out of bounds"); return typTab.at(static_cast(-tag)); } - if (tag == kBinKindTypeViaTypename) { - GStrIdx typenameStrIdx = ImportStr(); - TyIdx tyIdx = mod.GetTypeNameTab()->GetTyIdxFromGStrIdx(typenameStrIdx); - if (tyIdx != 0) { - typTab.push_back(tyIdx); - return tyIdx; - } - MIRTypeByName ltype(typenameStrIdx); - ltype.SetNameIsLocal(false); - MIRType *type = GlobalTables::GetTypeTable().GetOrCreateMIRTypeNode(ltype); - typTab.push_back(type->GetTypeIndex()); - return type->GetTypeIndex(); - } PrimType primType = (PrimType)0; GStrIdx strIdx(0); bool nameIsLocal = false; @@ -580,13 +569,6 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { } return origType->GetTypeIndex(); } - case kBinKindTypeByName: { - MIRTypeByName type(strIdx); - type.SetNameIsLocal(nameIsLocal); - MIRType *origType = &InsertInTypeTables(type); - typTab.push_back(origType->GetTypeIndex()); - return origType->GetTypeIndex(); - } case kBinKindTypeFArray: { MIRFarrayType type(strIdx); type.SetNameIsLocal(nameIsLocal); @@ -629,7 +611,7 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { size_t idx = typTab.size(); typTab.push_back(TyIdx(0)); type.SetRetTyIdx(ImportType()); - type.SetVarArgs(ReadNum()); + type.funcAttrs.SetAttrFlag(ReadNum()); int64 size = ReadNum(); for (int64 i = 0; i < size; ++i) { type.GetParamTypeList().push_back(ImportType()); @@ -737,19 +719,6 @@ TyIdx BinaryMplImport::ImportTypeNonJava() { CHECK_FATAL(static_cast(-tag) < typTab.size(), "index out of bounds"); return typTab[static_cast(-tag)]; } - if (tag == kBinKindTypeViaTypename) { - GStrIdx typenameStrIdx = ImportStr(); - TyIdx tyIdx = mod.GetTypeNameTab()->GetTyIdxFromGStrIdx(typenameStrIdx); - if (tyIdx != 0) { - typTab.push_back(tyIdx); - return tyIdx; - } - MIRTypeByName ltype(typenameStrIdx); - ltype.SetNameIsLocal(false); - MIRType *type = GlobalTables::GetTypeTable().GetOrCreateMIRTypeNode(ltype); - typTab.push_back(type->GetTypeIndex()); - return type->GetTypeIndex(); - } PrimType primType = (PrimType)0; GStrIdx strIdx(0); bool nameIsLocal = false; @@ -771,12 +740,6 @@ TyIdx BinaryMplImport::ImportTypeNonJava() { GlobalTables::GetTypeTable().CreateMirTypeNodeAt(type, tyIdxUsed, &mod, false, false); return tyIdxUsed; } - case kBinKindTypeByName: { - MIRTypeByName type(strIdx); - type.SetNameIsLocal(nameIsLocal); - GlobalTables::GetTypeTable().CreateMirTypeNodeAt(type, tyIdxUsed, &mod, false, false); - return tyIdxUsed; - } case kBinKindTypeFArray: { MIRFarrayType type(strIdx); type.SetNameIsLocal(nameIsLocal); @@ -808,7 +771,7 @@ TyIdx BinaryMplImport::ImportTypeNonJava() { MIRFuncType type(strIdx); type.SetNameIsLocal(nameIsLocal); type.SetRetTyIdx(ImportTypeNonJava()); - type.SetVarArgs(ReadNum()); + type.funcAttrs.SetAttrFlag(ReadNum()); int64 size = ReadNum(); for (int64 i = 0; i < size; ++i) { type.GetParamTypeList().push_back(ImportTypeNonJava()); @@ -1159,6 +1122,7 @@ void BinaryMplImport::ReadHeaderField() { mod.SetID(static_cast(ReadNum())); if (mod.GetFlavor() == kFlavorLmbc) { mod.SetGlobalMemSize(static_cast(ReadNum())); + mod.SetWithDbgInfo(static_cast(ReadNum())); } mod.SetNumFuncs(static_cast(ReadNum())); std::string inStr; diff --git a/src/mapleall/maple_ir/src/global_tables.cpp b/src/mapleall/maple_ir/src/global_tables.cpp index c43e86b2d5..99851d8ec5 100644 --- a/src/mapleall/maple_ir/src/global_tables.cpp +++ b/src/mapleall/maple_ir/src/global_tables.cpp @@ -224,7 +224,9 @@ MIRType *TypeTable::GetOrCreateFunctionType(const TyIdx &retTyIdx, const std::ve const std::vector &vecAttrs, bool isVarg, const TypeAttrs &retAttrs) { MIRFuncType funcType(retTyIdx, vecType, vecAttrs, retAttrs); - funcType.SetVarArgs(isVarg); + if (isVarg) { + funcType.SetVarArgs(); + } TyIdx tyIdx = GetOrCreateMIRType(&funcType); ASSERT(tyIdx < typeTable.size(), "index out of range in TypeTable::GetOrCreateFunctionType"); return typeTable.at(tyIdx); diff --git a/src/mapleall/maple_ir/src/mir_builder.cpp b/src/mapleall/maple_ir/src/mir_builder.cpp index 5fddd674cb..d4a89bef7d 100755 --- a/src/mapleall/maple_ir/src/mir_builder.cpp +++ b/src/mapleall/maple_ir/src/mir_builder.cpp @@ -836,6 +836,13 @@ IcallNode *MIRBuilder::CreateStmtIcall(const MapleVector &args) { return stmt; } +IcallNode *MIRBuilder::CreateStmtIcallproto(const MapleVector &args) { + auto *stmt = GetCurrentFuncCodeMp()->New(*GetCurrentFuncCodeMpAllocator(), OP_icallproto); + ASSERT(stmt != nullptr, "stmt is null"); + stmt->SetOpnds(args); + return stmt; +} + IcallNode *MIRBuilder::CreateStmtIcallAssigned(const MapleVector &args, const MIRSymbol &ret) { auto *stmt = GetCurrentFuncCodeMp()->New(*GetCurrentFuncCodeMpAllocator(), OP_icallassigned); CallReturnVector nrets(GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -853,6 +860,23 @@ IcallNode *MIRBuilder::CreateStmtIcallAssigned(const MapleVector &arg return stmt; } +IcallNode *MIRBuilder::CreateStmtIcallprotoAssigned(const MapleVector &args, const MIRSymbol &ret) { + auto *stmt = GetCurrentFuncCodeMp()->New(*GetCurrentFuncCodeMpAllocator(), OP_icallprotoassigned); + CallReturnVector nrets(GetCurrentFuncCodeMpAllocator()->Adapter()); + CHECK_FATAL((ret.GetStorageClass() == kScAuto || ret.GetStorageClass() == kScFormal || + ret.GetStorageClass() == kScExtern || ret.GetStorageClass() == kScGlobal), + "unknown classtype! check it!"); + nrets.emplace_back(CallReturnPair(ret.GetStIdx(), RegFieldPair(0, 0))); + stmt->SetNumOpnds(args.size()); + stmt->GetNopnd().resize(stmt->GetNumOpnds()); + stmt->SetReturnVec(nrets); + for (size_t i = 0; i < stmt->GetNopndSize(); ++i) { + stmt->SetNOpndAt(i, args.at(i)); + } + stmt->SetRetTyIdx(ret.GetTyIdx()); + return stmt; +} + IntrinsiccallNode *MIRBuilder::CreateStmtIntrinsicCall(MIRIntrinsicID idx, const MapleVector &arguments, TyIdx tyIdx) { auto *stmt = GetCurrentFuncCodeMp()->New( diff --git a/src/mapleall/maple_ir/src/mir_function.cpp b/src/mapleall/maple_ir/src/mir_function.cpp index 112f5ad6cf..4f217e54c5 100644 --- a/src/mapleall/maple_ir/src/mir_function.cpp +++ b/src/mapleall/maple_ir/src/mir_function.cpp @@ -368,10 +368,8 @@ void MIRFunction::Dump(bool withoutBody) { LogInfo::MapleLogger() << " )"; } - if (module->GetFlavor() < kMmpl) { + if (module->GetFlavor() != kMmpl) { DumpFlavorLoweredThanMmpl(); - } else { - LogInfo::MapleLogger() << " () void"; } // codeMemPool is nullptr, means maple_ir has been released for memory's sake diff --git a/src/mapleall/maple_ir/src/mir_lower.cpp b/src/mapleall/maple_ir/src/mir_lower.cpp index 99dbd04c3f..aa5cb0131c 100644 --- a/src/mapleall/maple_ir/src/mir_lower.cpp +++ b/src/mapleall/maple_ir/src/mir_lower.cpp @@ -530,6 +530,19 @@ BlockNode *MIRLower::LowerBlock(BlockNode &block) { case OP_doloop: newBlock->AppendStatementsFromBlock(*LowerDoloopStmt(static_cast(*stmt))); break; + case OP_icallassigned: + case OP_icall: { + if (mirModule.IsCModule()) { + // convert to icallproto/icallprotoassigned + IcallNode *ic = static_cast(stmt); + ic->SetOpCode(stmt->GetOpCode() == OP_icall ? OP_icallproto : OP_icallprotoassigned); + MIRFuncType *funcType = FuncTypeFromFuncPtrExpr(stmt->Opnd(0)); + CHECK_FATAL(funcType != nullptr, "MIRLower::LowerBlock: cannot find prototype for icall"); + ic->SetRetTyIdx(funcType->GetTypeIndex()); + } + newBlock->AddStatement(stmt); + break; + } case OP_block: tmp = LowerBlock(static_cast(*stmt)); newBlock->AppendStatementsFromBlock(*tmp); @@ -985,6 +998,100 @@ void MIRLower::ExpandArrayMrt(MIRFunction &func) { } } +MIRFuncType *MIRLower::FuncTypeFromFuncPtrExpr(BaseNode *x) { + MIRFuncType *res = nullptr; + MIRFunction *func = mirModule.CurFunction(); + switch (x->GetOpCode()) { + case OP_regread: { + RegreadNode *regread = static_cast(x); + MIRPreg *preg = func->GetPregTab()->PregFromPregIdx(regread->GetRegIdx()); + // see if it is promoted from a symbol + if (preg->GetOp() == OP_dread) { + const MIRSymbol *symbol = preg->rematInfo.sym; + MIRType *mirType = symbol->GetType(); + if (preg->fieldID != 0) { + MIRStructType *structty = static_cast(mirType); + FieldPair thepair = structty->TraverseToField(preg->fieldID); + mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); + } + + if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + if (res != nullptr) { + break; + } + } + // check if a formal promoted to preg + for (FormalDef &formalDef : func->GetFormalDefVec()) { + if (!formalDef.formalSym->IsPreg()) { + continue; + } + if (formalDef.formalSym->GetPreg() == preg) { + MIRType *mirType = formalDef.formalSym->GetType(); + if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + break; + } + } + break; + } + case OP_dread: { + DreadNode *dread = static_cast(x); + MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); + MIRType *mirType = symbol->GetType(); + if (dread->GetFieldID() != 0) { + MIRStructType *structty = static_cast(mirType); + FieldPair thepair = structty->TraverseToField(dread->GetFieldID()); + mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); + } + if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + break; + } + case OP_iread: { + IreadNode *iread = static_cast(x); + MIRPtrType *ptrType = static_cast(iread->GetType()); + MIRType *mirType = ptrType->GetPointedType(); + if (mirType->GetKind() == kTypeFunction) { + res = static_cast(mirType); + } else if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + break; + } + case OP_addroffunc: { + AddroffuncNode *addrofFunc = static_cast(x); + PUIdx puIdx = addrofFunc->GetPUIdx(); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); + res = f->GetMIRFuncType(); + break; + } + case OP_retype: { + MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx( + static_cast(x)->GetTyIdx()); + if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + if (res == nullptr) { + res = FuncTypeFromFuncPtrExpr(x->Opnd(0)); + } + break; + } + case OP_select: { + res = FuncTypeFromFuncPtrExpr(x->Opnd(1)); + if (res == nullptr) { + res = FuncTypeFromFuncPtrExpr(x->Opnd(2)); + } + break; + } + default: CHECK_FATAL(false, "LMBCLowerer::FuncTypeFromFuncPtrExpr: NYI"); + } + return res; +} + const std::set MIRLower::kSetArrayHotFunc = {}; bool MIRLower::ShouldOptArrayMrt(const MIRFunction &func) { diff --git a/src/mapleall/maple_ir/src/mir_nodes.cpp b/src/mapleall/maple_ir/src/mir_nodes.cpp index 510dbd07ca..e86982b764 100755 --- a/src/mapleall/maple_ir/src/mir_nodes.cpp +++ b/src/mapleall/maple_ir/src/mir_nodes.cpp @@ -1201,7 +1201,7 @@ MIRType *IcallNode::GetCallReturnType() { if (op == OP_icall || op == OP_icallassigned) { return GlobalTables::GetTypeTable().GetTypeFromTyIdx(retTyIdx); } - // icallproto + // icallproto or icallprotoassigned MIRFuncType *funcType = static_cast( GlobalTables::GetTypeTable().GetTypeFromTyIdx(retTyIdx)); return GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcType->GetRetTyIdx()); @@ -1226,7 +1226,7 @@ const MIRSymbol *IcallNode::GetCallReturnSymbol(const MIRModule &mod) const { void IcallNode::Dump(int32 indent, bool newline) const { StmtNode::DumpBase(indent); - if (op == OP_icallproto) { + if (op == OP_icallproto || op == OP_icallprotoassigned) { LogInfo::MapleLogger() << " "; GlobalTables::GetTypeTable().GetTypeFromTyIdx(retTyIdx)->Dump(indent + 1); } diff --git a/src/mapleall/maple_ir/src/mir_parser.cpp b/src/mapleall/maple_ir/src/mir_parser.cpp index 9660002e49..b0bbf9080b 100755 --- a/src/mapleall/maple_ir/src/mir_parser.cpp +++ b/src/mapleall/maple_ir/src/mir_parser.cpp @@ -896,6 +896,7 @@ bool MIRParser::ParseStmtCall(StmtNodePtr &stmt) { callStmt->SetPUIdx(pIdx); MIRFunction *callee = GlobalTables::GetFunctionTable().GetFuncTable()[pIdx]; + callee->GetFuncSymbol()->SetAppearsInCode(true); if (callee->GetName() == "setjmp") { mod.CurFunction()->SetHasSetjmp(); } @@ -932,9 +933,14 @@ bool MIRParser::ParseStmtIcall(StmtNodePtr &stmt, Opcode op) { // . . . // dassign } // icallproto (, , ..., ) + // icallprotoassigned (, , ..., ) { + // dassign + // dassign + // . . . + // dassign } IcallNode *iCallStmt = mod.CurFuncCodeMemPool()->New(mod, op); lexer.NextToken(); - if (op == OP_icallproto) { + if (op == OP_icallproto || op == OP_icallprotoassigned) { TyIdx tyIdx(0); if (!ParseDerivedType(tyIdx)) { Error("error parsing type in ParseStmtIcall for icallproto at "); @@ -948,7 +954,7 @@ bool MIRParser::ParseStmtIcall(StmtNodePtr &stmt, Opcode op) { } iCallStmt->SetNOpnd(opndsVec); iCallStmt->SetNumOpnds(opndsVec.size()); - if (op == OP_icallassigned) { + if (op == OP_icallassigned || op == OP_icallprotoassigned) { CallReturnVector retsVec(mod.CurFuncCodeMemPoolAllocator()->Adapter()); if (!ParseCallReturns(retsVec)) { return false; @@ -972,6 +978,10 @@ bool MIRParser::ParseStmtIcallproto(StmtNodePtr &stmt) { return ParseStmtIcall(stmt, OP_icallproto); } +bool MIRParser::ParseStmtIcallprotoassigned(StmtNodePtr &stmt) { + return ParseStmtIcall(stmt, OP_icallprotoassigned); +} + bool MIRParser::ParseStmtIntrinsiccall(StmtNodePtr &stmt, bool isAssigned) { Opcode o = !isAssigned ? (lexer.GetTokenKind() == TK_intrinsiccall ? OP_intrinsiccall : OP_xintrinsiccall) : (lexer.GetTokenKind() == TK_intrinsiccallassigned ? OP_intrinsiccallassigned @@ -2013,18 +2023,6 @@ bool MIRParser::ParseStmtBlockForUpformalSize() { return true; } -bool MIRParser::ParseStmtBlockForOutParmSize() { - MIRFunction *fn = paramCurrFuncForParseStmtBlock; - lexer.NextToken(); - if (lexer.GetTokenKind() != TK_intconst) { - Error("expect integer after outparmsize but get "); - return false; - } - fn->SetOutParmSize(static_cast(lexer.GetTheIntVal())); - lexer.NextToken(); - return true; -} - bool MIRParser::ParseStmtBlockForModuleID() { MIRFunction *fn = paramCurrFuncForParseStmtBlock; lexer.NextToken(); @@ -3241,7 +3239,8 @@ bool MIRParser::ParseConstAddrLeafExpr(MIRConstPtr &cexpr) { } else if (expr->GetOpCode() == OP_addroffunc) { auto *aof = static_cast(expr); MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(aof->GetPUIdx()); - const MIRSymbol *fName = f->GetFuncSymbol(); + MIRSymbol *fName = f->GetFuncSymbol(); + fName->SetAppearsInCode(true); TyIdx ptyIdx = fName->GetTyIdx(); MIRPtrType ptrType(ptyIdx); ptyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&ptrType); @@ -3415,6 +3414,7 @@ std::map MIRParser::InitFuncPtrMapForPar funcPtrMap[TK_icall] = &MIRParser::ParseStmtIcall; funcPtrMap[TK_icallassigned] = &MIRParser::ParseStmtIcallassigned; funcPtrMap[TK_icallproto] = &MIRParser::ParseStmtIcallproto; + funcPtrMap[TK_icallprotoassigned] = &MIRParser::ParseStmtIcallprotoassigned; funcPtrMap[TK_intrinsiccall] = &MIRParser::ParseStmtIntrinsiccall; funcPtrMap[TK_intrinsiccallassigned] = &MIRParser::ParseStmtIntrinsiccallassigned; funcPtrMap[TK_xintrinsiccall] = &MIRParser::ParseStmtIntrinsiccall; @@ -3475,7 +3475,6 @@ std::map MIRParser::InitFuncPtrMapF funcPtrMap[TK_type] = &MIRParser::ParseStmtBlockForType; funcPtrMap[TK_framesize] = &MIRParser::ParseStmtBlockForFrameSize; funcPtrMap[TK_upformalsize] = &MIRParser::ParseStmtBlockForUpformalSize; - funcPtrMap[TK_outparmsize] = &MIRParser::ParseStmtBlockForOutParmSize; funcPtrMap[TK_moduleid] = &MIRParser::ParseStmtBlockForModuleID; funcPtrMap[TK_funcsize] = &MIRParser::ParseStmtBlockForFuncSize; funcPtrMap[TK_funcid] = &MIRParser::ParseStmtBlockForFuncID; diff --git a/src/mapleall/maple_ir/src/mir_type.cpp b/src/mapleall/maple_ir/src/mir_type.cpp index a97663018e..dc39f35704 100644 --- a/src/mapleall/maple_ir/src/mir_type.cpp +++ b/src/mapleall/maple_ir/src/mir_type.cpp @@ -738,7 +738,9 @@ void MIRFuncType::Dump(int indent, bool dontUseName) const { if (!dontUseName && CheckAndDumpTypeName(nameStrIdx, nameIsLocal)) { return; } - LogInfo::MapleLogger() << "Dump(indent + 1); @@ -749,7 +751,7 @@ void MIRFuncType::Dump(int indent, bool dontUseName) const { LogInfo::MapleLogger() << ","; } } - if (isVarArgs) { + if (IsVarargs()) { LogInfo::MapleLogger() << ", ..."; } LogInfo::MapleLogger() << ") "; @@ -1663,7 +1665,7 @@ bool MIRFuncType::EqualTo(const MIRType &type) const { } const auto &pType = static_cast(type); return (pType.retTyIdx == retTyIdx && pType.paramTypeList == paramTypeList && - pType.isVarArgs == isVarArgs && pType.paramAttrsList == paramAttrsList && + pType.funcAttrs == funcAttrs && pType.paramAttrsList == paramAttrsList && pType.retAttrs == retAttrs); } diff --git a/src/mapleall/maple_ir/src/parser.cpp b/src/mapleall/maple_ir/src/parser.cpp index 4587c26fbe..755f120f95 100644 --- a/src/mapleall/maple_ir/src/parser.cpp +++ b/src/mapleall/maple_ir/src/parser.cpp @@ -229,9 +229,7 @@ bool MIRParser::ParsePseudoReg(PrimType primType, PregIdx &pRegIdx) { MIRPreg *preg = curfunc->GetPregTab()->PregFromPregIdx(pRegIdx); if (primType != kPtyInvalid) { if (preg->GetPrimType() != primType) { - if ((primType == PTY_ref || primType == PTY_ptr) && - (preg->GetPrimType() == PTY_ref || preg->GetPrimType() == PTY_ptr)) { - ; // PTY_ref and PTY_ptr are compatible with each other + if (IsAddress(preg->GetPrimType()) && IsAddress(primType)) { } else { Error("inconsistent preg primitive type at "); return false; @@ -1299,6 +1297,15 @@ bool MIRParser::ParsePointType(TyIdx &tyIdx) { // in function pointer specification and member function prototypes inside // structs and classes bool MIRParser::ParseFuncType(TyIdx &tyIdx) { + // parse function attributes + FuncAttrs fAttrs; + if (lexer.GetTokenKind() != TK_lparen) { + if (!ParseFuncAttrs(fAttrs)) { + Error("bad function attribute specification in function type at "); + return false; + } + } + // parse parameters if (lexer.GetTokenKind() != TK_lparen) { Error("expect ( parse function type parameters but get "); @@ -1359,7 +1366,10 @@ bool MIRParser::ParseFuncType(TyIdx &tyIdx) { return false; } MIRFuncType functype(retTyIdx, vecTyIdx, vecAttrs, retTypeAttrs); - functype.SetVarArgs(varargs); + functype.funcAttrs = fAttrs; + if (varargs) { + functype.SetVarArgs(); + } tyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&functype); return true; } diff --git a/src/mapleall/maple_me/include/lmbc_lower.h b/src/mapleall/maple_me/include/lmbc_lower.h index 9462204fd7..bbeaabf098 100644 --- a/src/mapleall/maple_me/include/lmbc_lower.h +++ b/src/mapleall/maple_me/include/lmbc_lower.h @@ -40,10 +40,7 @@ class LMBCLowerer { void LowerIassign(IassignNode *, BlockNode *); void LowerAggIassign(IassignNode *, MIRType *type, int32 offset, BlockNode *); void LowerReturn(NaryStmtNode *retNode, BlockNode *newblk); - MIRFuncType *FuncTypeFromFuncPtrExpr(BaseNode *x); - void LowerCall(NaryStmtNode *callNode, BlockNode *newblk); BlockNode *LowerBlock(BlockNode *); - void LoadFormalsAssignedToPregs(); void LowerFunction(); MIRModule *mirModule; diff --git a/src/mapleall/maple_me/include/lmbc_memlayout.h b/src/mapleall/maple_me/include/lmbc_memlayout.h index 7cea863a22..0f2bf5cbea 100644 --- a/src/mapleall/maple_me/include/lmbc_memlayout.h +++ b/src/mapleall/maple_me/include/lmbc_memlayout.h @@ -31,8 +31,8 @@ typedef enum { MS_actual, // for the outgoing parameters MS_local, // for all local variables and temporaries MS_FPbased, // addressed via offset from the frame pointer - MS_SPbased, // addressed via offset from the stack pointer MS_GPbased, // addressed via offset from the global pointer + MS_largeStructActual, // for storing large struct actuals passed by value for ARM CPU } MemSegmentKind; class MemSegment; @@ -64,15 +64,10 @@ class MemSegment { class LMBCMemLayout { public: - uint32 FindLargestActualArea(void); - uint32 FindLargestActualArea(StmtNode *, int &); - LMBCMemLayout(MIRFunction *f, MapleAllocator *mallocator) + LMBCMemLayout(MIRFunction *f, MemSegment *segGP, MapleAllocator *mallocator) : func(f), - seg_upformal(MS_upformal), - seg_formal(MS_formal), - seg_actual(MS_actual), + seg_GPbased(segGP), seg_FPbased(MS_FPbased), - seg_SPbased(MS_SPbased), sym_alloc_table(mallocator->Adapter()) { sym_alloc_table.resize(f->GetSymTab()->GetSymbolTableSize()); } @@ -81,67 +76,25 @@ class LMBCMemLayout { void LayoutStackFrame(void); int32 StackFrameSize(void) const { - return seg_SPbased.size - seg_FPbased.size; - } - - int32 UpformalSize(void) const { - return seg_upformal.size; + return -seg_FPbased.size; } MIRFunction *func; - MemSegment seg_upformal; - MemSegment seg_formal; - MemSegment seg_actual; + MemSegment *seg_GPbased; MemSegment seg_FPbased; - MemSegment seg_SPbased; MapleVector sym_alloc_table; // index is StIdx }; class GlobalMemLayout { public: - GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAllocator *mallocator); + GlobalMemLayout(MIRModule *mod, MapleAllocator *mallocator); ~GlobalMemLayout() {} MemSegment seg_GPbased; MapleVector sym_alloc_table; // index is StIdx - - private: - void FillScalarValueInMap(uint32 startaddress, PrimType pty, MIRConst *c); - void FillTypeValueInMap(uint32 startaddress, MIRType *ty, MIRConst *c); - void FillSymbolValueInMap(const MIRSymbol *sym); - - maplebe::BECommon *be; MIRModule *mirModule; }; -// for specifying how a parameter is passed -struct PLocInfo { - int32 memoffset; - int32 memsize; -}; - -// for processing an incoming or outgoing parameter list -class ParmLocator { - public: - explicit ParmLocator() : parmNum(0), lastMemOffset(0) {} - - ~ParmLocator() {} - - void LocateNextParm(const MIRType *ty, PLocInfo &ploc); - - private: - int32 parmNum; // number of all types of parameters processed so far - int32 lastMemOffset; -}; - -// given the type of the return value, determines the return mechanism -class ReturnMechanism { - public: - ReturnMechanism(const MIRType *retty); - bool fake_first_parm; // whether returning in memory via fake first parameter - PrimType ptype0; // the primitive type stored in retval0 -}; - } /* namespace maple */ #endif /* MAPLEME_INCLUDE_LMBC_MEMLAYOUT_H */ diff --git a/src/mapleall/maple_me/src/alias_class.cpp b/src/mapleall/maple_me/src/alias_class.cpp index 788a9a3540..1a63043e27 100644 --- a/src/mapleall/maple_me/src/alias_class.cpp +++ b/src/mapleall/maple_me/src/alias_class.cpp @@ -1017,7 +1017,9 @@ void AliasClass::ApplyUnionForCopies(StmtNode &stmt) { } case OP_asm: case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { for (uint32 i = 0; i < stmt.NumOpnds(); ++i) { const AliasInfo &ainfo = CreateAliasInfoExpr(*stmt.Opnd(i)); if (stmt.GetOpCode() != OP_asm && i == 0) { @@ -2563,6 +2565,7 @@ void AliasClass::GenericInsertMayDefUse(StmtNode &stmt, BBId bbID) { case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_virtualcall: case OP_virtualicall: case OP_superclasscall: @@ -2570,7 +2573,8 @@ void AliasClass::GenericInsertMayDefUse(StmtNode &stmt, BBId bbID) { case OP_interfaceicall: case OP_customcall: case OP_polymorphiccall: - case OP_icall: { + case OP_icall: + case OP_icallproto: { InsertMayDefUseCall(stmt, bbID, false); return; } diff --git a/src/mapleall/maple_me/src/code_factoring.cpp b/src/mapleall/maple_me/src/code_factoring.cpp index 6cabb59adc..2f40e7b821 100644 --- a/src/mapleall/maple_me/src/code_factoring.cpp +++ b/src/mapleall/maple_me/src/code_factoring.cpp @@ -122,7 +122,9 @@ bool FactoringOptimizer::IsIdenticalStmt(StmtNode *stmt1, StmtNode *stmt2) { break; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { auto *icall1 = static_cast(stmt1); auto *icall2 = static_cast(stmt2); if (icall1->GetRetTyIdx() != icall2->GetRetTyIdx() || diff --git a/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp b/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp index db34036937..50a25a6101 100644 --- a/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp +++ b/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp @@ -641,7 +641,9 @@ void PEGBuilder::BuildPEGNodeInStmt(const StmtNode *stmt) { break; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { BuildPEGNodeInIcall(static_cast(stmt)); break; } diff --git a/src/mapleall/maple_me/src/irmap_build.cpp b/src/mapleall/maple_me/src/irmap_build.cpp index cd801b7b5b..29afaca89b 100755 --- a/src/mapleall/maple_me/src/irmap_build.cpp +++ b/src/mapleall/maple_me/src/irmap_build.cpp @@ -806,7 +806,7 @@ MeStmt *IRMapBuild::BuildCallMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { MeStmt *IRMapBuild::BuildNaryMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { Opcode op = stmt.GetOpCode(); - NaryMeStmt *naryMeStmt = (op == OP_icall || op == OP_icallassigned) + NaryMeStmt *naryMeStmt = (op == OP_icall || op == OP_icallassigned || op == OP_icallproto || op == OP_icallprotoassigned) ? static_cast(irMap->NewInPool(&stmt)) : static_cast(irMap->NewInPool(&stmt)); auto &naryStmtNode = static_cast(stmt); @@ -821,6 +821,9 @@ MeStmt *IRMapBuild::BuildNaryMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { if (propagater) { propagater->PropUpdateChiListDef(*naryMeStmt->GetChiList()); } + if (op == OP_icallproto || op == OP_icallprotoassigned) { + static_cast(naryMeStmt)->SetRetTyIdx(static_cast(stmt).GetRetTyIdx()); + } return naryMeStmt; } @@ -921,6 +924,8 @@ void IRMapBuild::InitMeStmtFactory() { RegisterFactoryFunction(OP_polymorphiccallassigned, &IRMapBuild::BuildCallMeStmt); RegisterFactoryFunction(OP_icall, &IRMapBuild::BuildNaryMeStmt); RegisterFactoryFunction(OP_icallassigned, &IRMapBuild::BuildNaryMeStmt); + RegisterFactoryFunction(OP_icallproto, &IRMapBuild::BuildNaryMeStmt); + RegisterFactoryFunction(OP_icallprotoassigned, &IRMapBuild::BuildNaryMeStmt); RegisterFactoryFunction(OP_intrinsiccall, &IRMapBuild::BuildNaryMeStmt); RegisterFactoryFunction(OP_xintrinsiccall, &IRMapBuild::BuildNaryMeStmt); RegisterFactoryFunction(OP_intrinsiccallwithtype, &IRMapBuild::BuildNaryMeStmt); diff --git a/src/mapleall/maple_me/src/irmap_emit.cpp b/src/mapleall/maple_me/src/irmap_emit.cpp index 824e7c7e53..7fcbd3804b 100755 --- a/src/mapleall/maple_me/src/irmap_emit.cpp +++ b/src/mapleall/maple_me/src/irmap_emit.cpp @@ -412,7 +412,7 @@ MIRFunction &CallMeStmt::GetTargetFunction() { } StmtNode &CallMeStmt::EmitStmt(SSATab &ssaTab) { - if (GetOp() != OP_icall && GetOp() != OP_icallassigned) { + if (GetOp() != OP_icall && GetOp() != OP_icallassigned && GetOp() != OP_icallproto && GetOp() != OP_icallprotoassigned) { auto *callNode = ssaTab.GetModule().CurFunction()->GetCodeMempool()->New(ssaTab.GetModule(), Opcode(GetOp())); callNode->SetPUIdx(puIdx); @@ -496,6 +496,9 @@ StmtNode &IcallMeStmt::EmitStmt(SSATab &ssaTab) { } } } + if (GetOp() == OP_icallproto || GetOp() == OP_icallprotoassigned) { + icallNode->SetRetTyIdx(retTyIdx); + } return *icallNode; } diff --git a/src/mapleall/maple_me/src/lfo_dep_test.cpp b/src/mapleall/maple_me/src/lfo_dep_test.cpp index 19a523e138..ac3340e843 100644 --- a/src/mapleall/maple_me/src/lfo_dep_test.cpp +++ b/src/mapleall/maple_me/src/lfo_dep_test.cpp @@ -66,6 +66,8 @@ void LfoDepInfo::CreateDoloopInfo(BlockNode *block, DoloopInfo *parent) { case OP_callassigned: case OP_icall: case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: case OP_return: case OP_throw: case OP_asm: diff --git a/src/mapleall/maple_me/src/lmbc_lower.cpp b/src/mapleall/maple_me/src/lmbc_lower.cpp index a155b25fa4..f5893447ba 100644 --- a/src/mapleall/maple_me/src/lmbc_lower.cpp +++ b/src/mapleall/maple_me/src/lmbc_lower.cpp @@ -22,16 +22,12 @@ using namespace std; PregIdx LMBCLowerer::GetSpecialRegFromSt(const MIRSymbol *sym) { MIRStorageClass storageClass = sym->GetStorageClass(); PregIdx specreg = 0; - if (storageClass == kScAuto || storageClass == kScFormal) { + if (storageClass == kScAuto) { CHECK(sym->GetStIndex() < memlayout->sym_alloc_table.size(), "index out of range in LMBCLowerer::GetSpecialRegFromSt"); SymbolAlloc symalloc = memlayout->sym_alloc_table[sym->GetStIndex()]; - if (symalloc.mem_segment->kind == MS_upformal || symalloc.mem_segment->kind == MS_formal || - symalloc.mem_segment->kind == MS_FPbased) { + if (symalloc.mem_segment->kind == MS_FPbased) { specreg = -kSregFp; - } else if (symalloc.mem_segment->kind == MS_actual || - symalloc.mem_segment->kind == MS_SPbased) { - specreg = -kSregSp; } else { CHECK_FATAL(false, "LMBCLowerer::LowerDread: bad memory layout for local variable"); } @@ -46,6 +42,7 @@ PregIdx LMBCLowerer::GetSpecialRegFromSt(const MIRSymbol *sym) { BaseNode *LMBCLowerer::LowerAddrof(AddrofNode *expr) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(expr->GetStIdx()); + symbol->ResetIsDeleted(); int32 offset = 0; if (expr->GetFieldID() != 0) { MIRStructType *structty = static_cast(symbol->GetType()); @@ -66,6 +63,7 @@ BaseNode *LMBCLowerer::LowerAddrof(AddrofNode *expr) { BaseNode *LMBCLowerer::LowerDread(AddrofNode *expr) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(expr->GetStIdx()); + symbol->ResetIsDeleted(); PrimType symty = symbol->GetType()->GetPrimType(); int32 offset = 0; if (expr->GetFieldID() != 0) { @@ -96,20 +94,22 @@ BaseNode *LMBCLowerer::LowerDread(AddrofNode *expr) { BaseNode *LMBCLowerer::LowerDreadoff(DreadoffNode *dreadoff) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dreadoff->stIdx); + symbol->ResetIsDeleted(); if (!symbol->LMBCAllocateOffSpecialReg()) { return dreadoff; } + PrimType symty = symbol->GetType()->GetPrimType(); PregIdx spcreg = GetSpecialRegFromSt(symbol); if (spcreg == -kSregFp) { CHECK_FATAL(symbol->IsLocal(), "load from fp non local?"); - IreadFPoffNode *ireadoff = mirBuilder->CreateExprIreadFPoff( - dreadoff->GetPrimType(), memlayout->sym_alloc_table[symbol->GetStIndex()].offset + dreadoff->offset); + IreadFPoffNode *ireadoff = mirBuilder->CreateExprIreadFPoff(symty, + memlayout->sym_alloc_table[symbol->GetStIndex()].offset + dreadoff->offset); return ireadoff; } else { BaseNode *rrn = mirBuilder->CreateExprRegread(LOWERED_PTR_TYPE, spcreg); SymbolAlloc &symalloc = symbol->IsLocal() ? memlayout->sym_alloc_table[symbol->GetStIndex()] : globmemlayout->sym_alloc_table[symbol->GetStIndex()]; - IreadoffNode *ireadoff = mirBuilder->CreateExprIreadoff(dreadoff->GetPrimType(), symalloc.offset + dreadoff->offset, rrn); + IreadoffNode *ireadoff = mirBuilder->CreateExprIreadoff(symty, symalloc.offset + dreadoff->offset, rrn); return ireadoff; } } @@ -129,14 +129,14 @@ static MIRType *GetPointedToType(const MIRPtrType *pointerty) { BaseNode *LMBCLowerer::LowerIread(IreadNode *expr) { int32 offset = 0; + MIRPtrType *ptrType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(expr->GetTyIdx())); + MIRType *type = ptrType->GetPointedType(); if (expr->GetFieldID() != 0) { - MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(expr->GetTyIdx()); - MIRStructType *structty = - static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(type)->GetPointedTyIdx())); + MIRStructType *structty = static_cast(type); offset = becommon->GetFieldOffset(*structty, expr->GetFieldID()).first; + type = structty->GetFieldType(expr->GetFieldID()); } - BaseNode *ireadoff = mirBuilder->CreateExprIreadoff(expr->GetPrimType(), offset, expr->Opnd(0)); + BaseNode *ireadoff = mirBuilder->CreateExprIreadoff(type->GetPrimType(), offset, expr->Opnd(0)); return ireadoff; } @@ -165,6 +165,7 @@ BaseNode *LMBCLowerer::LowerExpr(BaseNode *expr) { return LowerAddrof(static_cast(expr)); case OP_addrofoff: { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(static_cast(expr)->stIdx); + symbol->ResetIsDeleted(); CHECK_FATAL(!symbol->LMBCAllocateOffSpecialReg(), "LMBCLowerer:: illegal addrofoff instruction"); break; @@ -199,6 +200,7 @@ void LMBCLowerer::LowerAggDassign(const DassignNode *dsnode, MIRType *lhsty, // generate lhs address expression BaseNode *lhs = nullptr; MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dsnode->GetStIdx()); + symbol->ResetIsDeleted(); if (!symbol->LMBCAllocateOffSpecialReg()) { lhs = mirBuilder->CreateExprDreadoff(OP_addrofoff, LOWERED_PTR_TYPE, *symbol, offset); } else { @@ -218,6 +220,7 @@ void LMBCLowerer::LowerAggDassign(const DassignNode *dsnode, MIRType *lhsty, void LMBCLowerer::LowerDassign(DassignNode *dsnode, BlockNode *newblk) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dsnode->GetStIdx()); + symbol->ResetIsDeleted(); MIRType *symty = symbol->GetType(); int32 offset = 0; if (dsnode->GetFieldID() != 0) { @@ -259,6 +262,7 @@ void LMBCLowerer::LowerDassign(DassignNode *dsnode, BlockNode *newblk) { void LMBCLowerer::LowerDassignoff(DassignoffNode *dsnode, BlockNode *newblk) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dsnode->stIdx); + symbol->ResetIsDeleted(); CHECK_FATAL(dsnode->Opnd(0)->GetPrimType() != PTY_agg, "LowerDassignoff: agg primitive type NYI"); BaseNode *rhs = LowerExpr(dsnode->Opnd(0)); if (!symbol->LMBCAllocateOffSpecialReg()) { @@ -334,6 +338,9 @@ void LMBCLowerer::LowerIassign(IassignNode *iassign, BlockNode *newblk) { } if (iassign->GetRHS()->GetPrimType() != PTY_agg) { PrimType ptypused = type->GetPrimType(); + if (ptypused == PTY_agg) { + ptypused = iassign->GetRHS()->GetPrimType(); + } IassignoffNode *iassignoff = mirBuilder->CreateStmtIassignoff(ptypused, offset, iassign->addrExpr, @@ -347,15 +354,20 @@ void LMBCLowerer::LowerIassign(IassignNode *iassign, BlockNode *newblk) { // called only if the return has > 1 operand; assume prior lowering already // converted any return of structs to be via fake parameter void LMBCLowerer::LowerReturn(NaryStmtNode *retNode, BlockNode *newblk) { - CHECK_FATAL(retNode->NumOpnds() <= 2, "LMBCLowerer::LowerReturn: more than 2 return values NYI"); - for (int i = 0; i < retNode->NumOpnds(); i++) { - CHECK_FATAL(retNode->Opnd(i)->GetPrimType() != PTY_agg, - "LMBCLowerer::LowerReturn: return of aggregate needs to be handled first"); - // insert regassign for the returned value - BaseNode *rhs = LowerExpr(retNode->Opnd(i)); - RegassignNode *regasgn = mirBuilder->CreateStmtRegassign(rhs->GetPrimType(), - i == 0 ? -kSregRetval0 : -kSregRetval1, - rhs); + if (retNode->Opnd(0)->GetPrimType() != PTY_agg) { + CHECK_FATAL(retNode->NumOpnds() <= 2, "LMBCLowerer::LowerReturn: more than 2 return values NYI"); + for (int i = 0; i < retNode->NumOpnds(); i++) { + // insert regassign for the returned value + PrimType ptyp = retNode->Opnd(i)->GetPrimType(); + BaseNode *rhs = LowerExpr(retNode->Opnd(i)); + RegassignNode *regasgn = mirBuilder->CreateStmtRegassign(ptyp, + i == 0 ? -kSregRetval0 : -kSregRetval1, + rhs); + newblk->AddStatement(regasgn); + } + } else { // handle return of small struct using only %%retval0 + BaseNode *rhs = LowerExpr(retNode->Opnd(0)); + RegassignNode *regasgn = mirBuilder->CreateStmtRegassign(PTY_agg, -kSregRetval0, rhs); newblk->AddStatement(regasgn); } retNode->GetNopnd().clear(); // remove the return operands @@ -363,178 +375,6 @@ void LMBCLowerer::LowerReturn(NaryStmtNode *retNode, BlockNode *newblk) { newblk->AddStatement(retNode); } -MIRFuncType *LMBCLowerer::FuncTypeFromFuncPtrExpr(BaseNode *x) { - MIRFuncType *res = nullptr; - switch (x->GetOpCode()) { - case OP_regread: { - RegreadNode *regread = static_cast(x); - MIRPreg *preg = func->GetPregTab()->PregFromPregIdx(regread->GetRegIdx()); - // see if it is promoted from a symbol - if (preg->GetOp() == OP_dread) { - const MIRSymbol *symbol = preg->rematInfo.sym; - MIRType *mirType = symbol->GetType(); - if (preg->fieldID != 0) { - MIRStructType *structty = static_cast(mirType); - FieldPair thepair = structty->TraverseToField(preg->fieldID); - mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - if (res != nullptr) { - break; - } - } - // check if a formal promoted to preg - for (FormalDef &formalDef : func->GetFormalDefVec()) { - if (!formalDef.formalSym->IsPreg()) { - continue; - } - if (formalDef.formalSym->GetPreg() == preg) { - MIRType *mirType = formalDef.formalSym->GetType(); - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - break; - } - } - break; - } - case OP_dread: { - DreadNode *dread = static_cast(x); - MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); - MIRType *mirType = symbol->GetType(); - if (dread->GetFieldID() != 0) { - MIRStructType *structty = static_cast(mirType); - FieldPair thepair = structty->TraverseToField(dread->GetFieldID()); - mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - break; - } - case OP_iread: { - IreadNode *iread = static_cast(x); - MIRPtrType *ptrType = static_cast(iread->GetType()); - MIRType *mirType = ptrType->GetPointedType(); - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - break; - } - case OP_addroffunc: { - AddroffuncNode *addrofFunc = static_cast(x); - PUIdx puIdx = addrofFunc->GetPUIdx(); - MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); - res = f->GetMIRFuncType(); - break; - } - case OP_retype: { - MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(x)->GetTyIdx()); - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - if (res == nullptr) { - res = FuncTypeFromFuncPtrExpr(x->Opnd(0)); - } - break; - } - case OP_select: { - res = FuncTypeFromFuncPtrExpr(x->Opnd(1)); - if (res == nullptr) { - res = FuncTypeFromFuncPtrExpr(x->Opnd(2)); - } - break; - } - default: CHECK_FATAL(false, "LMBCLowerer::FuncTypeFromFuncPtrExpr: NYI"); - } - return res; -} - -void LMBCLowerer::LowerCall(NaryStmtNode *naryStmt, BlockNode *newblk) { - // go through each parameter - uint32 i = 0; - if (naryStmt->GetOpCode() == OP_icall || naryStmt->GetOpCode() == OP_icallassigned) { - i = 1; - } - ParmLocator parmlocator; - for (; i < naryStmt->NumOpnds(); i++) { - BaseNode *opnd = naryStmt->Opnd(i); - MIRType *ty = nullptr; - // get ty for this parameter - if (opnd->GetPrimType() != PTY_agg) { - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(static_cast(opnd->GetPrimType())); - } else { - Opcode opnd_opcode = opnd->GetOpCode(); - CHECK_FATAL(opnd_opcode == OP_dread || opnd_opcode == OP_iread, ""); - if (opnd_opcode == OP_dread) { - AddrofNode *dread = static_cast(opnd); - MIRSymbol *sym = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx()); - if (dread->GetFieldID() != 0) { - CHECK_FATAL(ty->IsStructType(), ""); - FieldPair thepair = static_cast(ty)->TraverseToField(dread->GetFieldID()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - } else { // OP_iread - IreadNode *iread = static_cast(opnd); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread->GetTyIdx()); - CHECK_FATAL(ty->GetKind() == kTypePointer, ""); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(ty)->GetPointedTyIdx()); - if (iread->GetFieldID() != 0) { - CHECK_FATAL(ty->IsStructType(), ""); - FieldPair thepair = static_cast(ty)->TraverseToField(iread->GetFieldID()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - } - } - PLocInfo ploc; - parmlocator.LocateNextParm(ty, ploc); - if (opnd->GetPrimType() != PTY_agg) { - IassignFPoffNode *iass = mirBuilder->CreateStmtIassignFPoff(OP_iassignspoff, - opnd->GetPrimType(), - ploc.memoffset, - LowerExpr(opnd)); - newblk->AddStatement(iass); - } else { - BlkassignoffNode *bass = - mirModule->CurFuncCodeMemPool()->New(ploc.memoffset, ploc.memsize); - bass->SetAlign(std::min(ty->GetAlign(), 8u)); - bass->SetBOpnd(mirBuilder->CreateExprRegread(LOWERED_PTR_TYPE, -kSregSp), 0); - // the operand is either OP_dread or OP_iread; use its address instead - if (opnd->GetOpCode() == OP_dread) { - opnd->SetOpCode(OP_addrof); - } else { - opnd->SetOpCode(OP_iaddrof); - } - opnd->SetPrimType(LOWERED_PTR_TYPE); - bass->SetBOpnd(LowerExpr(opnd), 1); - newblk->AddStatement(bass); - } - } - BaseNode *opnd0 = nullptr; - if (naryStmt->GetOpCode() == OP_icall || naryStmt->GetOpCode() == OP_icallassigned) { - opnd0 = naryStmt->Opnd(0); - naryStmt->GetNopnd().clear(); // remove the call operands - // convert to OP_icallproto by finding the function prototype and record in stmt - naryStmt->SetOpCode(OP_icallproto); - MIRFuncType *funcType = FuncTypeFromFuncPtrExpr(opnd0); - CHECK_FATAL(funcType != nullptr, "LMBCLowerer::LowerCall: cannot find prototype for icall"); - static_cast(naryStmt)->SetRetTyIdx(funcType->GetTypeIndex()); - // add back the function pointer operand - naryStmt->GetNopnd().push_back(LowerExpr(opnd0)); - naryStmt->SetNumOpnds(1); - } else { - naryStmt->GetNopnd().clear(); // remove the call operands - naryStmt->SetNumOpnds(0); - } - newblk->AddStatement(naryStmt); -} - BlockNode *LMBCLowerer::LowerBlock(BlockNode *block) { BlockNode *newblk = mirModule->CurFuncCodeMemPool()->New(); if (!block->GetFirst()) { @@ -569,10 +409,6 @@ BlockNode *LMBCLowerer::LowerBlock(BlockNode *block) { } else { LowerReturn(retNode, newblk); } - } - case OP_call: - case OP_icall: { - LowerCall(static_cast(stmt), newblk); break; } default: { @@ -587,29 +423,19 @@ BlockNode *LMBCLowerer::LowerBlock(BlockNode *block) { return newblk; } -void LMBCLowerer::LoadFormalsAssignedToPregs() { - // go through each formals - for (int32 i = func->GetFormalDefVec().size()-1; i >= 0; i--) { - MIRSymbol *formalSt = func->GetFormalDefVec()[i].formalSym; - if (formalSt->GetSKind() != kStPreg) { - continue; +void LMBCLowerer::LowerFunction() { + // set extern global vars' isDeleted field; will reset when visited + MapleVector::const_iterator sit = mirModule->GetSymbolDefOrder().begin(); + for (; sit != mirModule->GetSymbolDefOrder().end(); ++sit) { + MIRSymbol *s = GlobalTables::GetGsymTable().GetSymbolFromStidx(sit->Idx()); + if (s->GetSKind() == kStVar && s->GetStorageClass() == kScExtern && !s->HasPotentialAssignment()) { + s->SetIsDeleted(); } - MIRPreg *preg = formalSt->GetPreg(); - uint32 stindex = formalSt->GetStIndex(); - PrimType pty = formalSt->GetType()->GetPrimType(); - IreadFPoffNode *ireadfpoff = mirBuilder->CreateExprIreadFPoff(pty, - memlayout->sym_alloc_table[stindex].offset); - RegassignNode *rass = mirBuilder->CreateStmtRegassign(pty, - func->GetPregTab()->GetPregIdxFromPregno(preg->GetPregNo()), ireadfpoff); - func->GetBody()->InsertFirst(rass); } -} -void LMBCLowerer::LowerFunction() { BlockNode *origbody = func->GetBody(); BlockNode *newbody = LowerBlock(origbody); func->SetBody(newbody); - LoadFormalsAssignedToPregs(); } } // namespace maple diff --git a/src/mapleall/maple_me/src/lmbc_memlayout.cpp b/src/mapleall/maple_me/src/lmbc_memlayout.cpp index e740c5d13f..b32acae493 100644 --- a/src/mapleall/maple_me/src/lmbc_memlayout.cpp +++ b/src/mapleall/maple_me/src/lmbc_memlayout.cpp @@ -13,146 +13,40 @@ * See the MulanPSL - 2.0 for more details. */ -// For each function being compiled, lay out its parameters, return values and -// local variables on its stack frame. This involves determining how parameters -// and return values are passed from analyzing their types. -// -// Allocate all the global variables within the global memory block which is -// addressed via offset from the global pointer GP during execution. Allocate -// this block pointed to by mirModule.globalBlkMap and perform the static -// initializations. +// For each function being compiled, lay out its local variables on its stack +// frame. Allocate all the global variables within the global memory block +// which is addressed via offset from the global pointer GP during execution. +// Allocate this block pointed to by mirModule.globalBlkMap. #include "lmbc_memlayout.h" #include "mir_symbol.h" namespace maple { -uint32 LMBCMemLayout::FindLargestActualArea(StmtNode *stmt, int &maxActualSize) { - if (!stmt) { - return maxActualSize; - } - Opcode opcode = stmt->op; - switch (opcode) { - case OP_block: { - BlockNode *blcknode = static_cast(stmt); - for (StmtNode &s : blcknode->GetStmtNodes()) { - FindLargestActualArea(&s, maxActualSize); - } - break; - } - case OP_if: { - IfStmtNode *ifnode = static_cast(stmt); - FindLargestActualArea(ifnode->GetThenPart(), maxActualSize); - FindLargestActualArea(ifnode->GetElsePart(), maxActualSize); - break; - } - case OP_doloop: { - FindLargestActualArea(static_cast(stmt)->GetDoBody(), maxActualSize); - break; - } - case OP_dowhile: - case OP_while: - FindLargestActualArea(static_cast(stmt)->GetBody(), maxActualSize); - break; - case OP_call: - case OP_icall: - case OP_intrinsiccall: { - ParmLocator parmlocator; // instantiate a parm locator - NaryStmtNode *callstmt = static_cast(stmt); - for (uint32 i = 0; i < callstmt->NumOpnds(); i++) { - BaseNode *opnd = callstmt->Opnd(i); - CHECK_FATAL(opnd->GetPrimType() != PTY_void, ""); - MIRType *ty = nullptr; - if (opnd->GetPrimType() != PTY_agg) { - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(opnd->GetPrimType())); - } else { - Opcode opnd_opcode = opnd->GetOpCode(); - CHECK_FATAL(opnd_opcode == OP_dread || opnd_opcode == OP_iread, ""); - if (opnd_opcode == OP_dread) { - AddrofNode *dread = static_cast(opnd); - MIRSymbol *sym = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx()); - if (dread->GetFieldID() != 0) { - CHECK_FATAL(ty->IsStructType(), "expect struct or class or union"); - FieldPair thepair = - static_cast(ty)->TraverseToField(dread->GetFieldID()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - } else { // OP_iread - IreadNode *iread = static_cast(opnd); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread->GetTyIdx()); - CHECK_FATAL(ty->GetKind() == kTypePointer, ""); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(ty)->GetPointedTyIdx()); - if (iread->GetFieldID() != 0) { - CHECK_FATAL(ty->IsStructType(), "expect struct or class or union"); - FieldPair thepair = - static_cast(ty)->TraverseToField(iread->GetFieldID()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - } - } - PLocInfo ploc; - parmlocator.LocateNextParm(ty, ploc); - maxActualSize = std::max(maxActualSize, ploc.memoffset + ploc.memsize); - maxActualSize = maplebe::RoundUp(maxActualSize, GetPrimTypeSize(PTY_ptr)); - } - break; - } - default: - return maxActualSize; - } - maxActualSize = maplebe::RoundUp(maxActualSize, GetPrimTypeSize(PTY_ptr)); - return maxActualSize; -} - -// go over all outgoing calls in the function body and get the maximum space -// needed for storing the actuals based on the actual parameters and the ABI; -// this assumes that all nesting of statements has been removed, so that all -// the statements are at only one block level -uint32 LMBCMemLayout::FindLargestActualArea(void) { - int32 maxActualSize = 0; - FindLargestActualArea(func->GetBody(), maxActualSize); - return static_cast(maxActualSize); -} +constexpr size_t kVarargSaveAreaSize = 192; void LMBCMemLayout::LayoutStackFrame(void) { - MIRSymbol *sym = nullptr; - // go through formal parameters - ParmLocator parmlocator; // instantiate a parm locator - PLocInfo ploc; - for (uint32 i = 0; i < func->GetFormalDefVec().size(); i++) { - FormalDef formalDef = func->GetFormalDefAt(i); - sym = formalDef.formalSym; - MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(formalDef.formalTyIdx); - parmlocator.LocateNextParm(ty, ploc); - uint32 stindex = sym->GetStIndex(); - // always passed in memory, so allocate in seg_upformal - sym_alloc_table[stindex].mem_segment = &seg_upformal; - seg_upformal.size = maplebe::RoundUp(seg_upformal.size, ty->GetAlign()); - sym_alloc_table[stindex].offset = seg_upformal.size; - seg_upformal.size += ty->GetSize(); - seg_upformal.size = maplebe::RoundUp(seg_upformal.size, GetPrimTypeSize(PTY_ptr)); + if (func->IsVarargs()) { + seg_FPbased.size -= kVarargSaveAreaSize; } - // allocate seg_formal in seg_FPbased - seg_formal.how_alloc.mem_segment = &seg_FPbased; - seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, GetPrimTypeSize(PTY_ptr)); - seg_FPbased.size -= seg_formal.size; - seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, GetPrimTypeSize(PTY_ptr)); - seg_formal.how_alloc.offset = seg_FPbased.size; - // allocate the local variables uint32 symtabsize = func->GetSymTab()->GetSymbolTableSize(); for (uint32 i = 0; i < symtabsize; i++) { - sym = func->GetSymTab()->GetSymbolFromStIdx(i); + MIRSymbol *sym = func->GetSymTab()->GetSymbolFromStIdx(i); if (!sym) { continue; } if (sym->IsDeleted()) { continue; } + if (sym->GetStorageClass() == kScPstatic && sym->LMBCAllocateOffSpecialReg()) { + uint32 stindex = sym->GetStIndex(); + sym_alloc_table[stindex].mem_segment = seg_GPbased; + seg_GPbased->size = maplebe::RoundUp(seg_GPbased->size, sym->GetType()->GetAlign()); + sym_alloc_table[stindex].offset = seg_GPbased->size; + seg_GPbased->size += sym->GetType()->GetSize(); + } if (sym->GetStorageClass() != kScAuto) { continue; } @@ -162,160 +56,10 @@ void LMBCMemLayout::LayoutStackFrame(void) { seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, sym->GetType()->GetAlign()); sym_alloc_table[stindex].offset = seg_FPbased.size; } - seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, GetPrimTypeSize(PTY_ptr)); - - // allocate seg_actual for storing the outgoing parameters; this requires - // going over all outgoing calls and get the maximum space needed for the - // actuals - seg_actual.size = FindLargestActualArea(); - func->SetOutParmSize(seg_actual.size); - - // allocate seg_actual in seg_SPbased - seg_actual.how_alloc.mem_segment = &seg_SPbased; - seg_actual.how_alloc.offset = seg_SPbased.size; - seg_SPbased.size = maplebe::RoundUp(seg_SPbased.size, GetPrimTypeSize(PTY_ptr)); - seg_SPbased.size += seg_actual.size; - seg_SPbased.size = maplebe::RoundUp(seg_SPbased.size, GetPrimTypeSize(PTY_ptr)); -} - -inline uint8 GetU8Const(MIRConst *c) { - MIRIntConst *intconst = static_cast(c); - return static_cast(intconst->GetValue()); -} - -inline uint16 GetU16Const(MIRConst *c) { - MIRIntConst *intconst = static_cast(c); - return static_cast(intconst->GetValue()); -} - -inline uint32 GetU32Const(MIRConst *c) { - MIRIntConst *intconst = static_cast(c); - return static_cast(intconst->GetValue()); -} - -inline uint64 GetU64Const(MIRConst *c) { - MIRIntConst *intconst = static_cast(c); - return static_cast(intconst->GetValue()); -} - -inline uint32 GetF32Const(MIRConst *c) { - MIRFloatConst *floatconst = static_cast(c); - return static_cast(floatconst->GetIntValue()); -} - -inline uint64 GetF64Const(MIRConst *c) { - MIRDoubleConst *doubleconst = static_cast(c); - return static_cast(doubleconst->GetIntValue()); -} - -void GlobalMemLayout::FillScalarValueInMap(uint32 startaddress, PrimType pty, MIRConst *c) { - switch (pty) { - case PTY_u1: - case PTY_u8: - case PTY_i8: { - uint8 *p = &mirModule->GetGlobalBlockMap()[startaddress]; - *p = GetU8Const(c); - break; - } - case PTY_u16: - case PTY_i16: { - uint16 *p = (uint16 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetU16Const(c); - break; - } - case PTY_u32: - case PTY_i32: { - uint32 *p = (uint32 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetU32Const(c); - break; - } - case PTY_u64: - case PTY_i64: { - uint64 *p = (uint64 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetU64Const(c); - break; - } - case PTY_f32: { - uint32 *p = (uint32 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetF32Const(c); - break; - } - case PTY_f64: { - uint64 *p = (uint64 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetF64Const(c); - break; - } - default: - CHECK_FATAL(false, "FillScalarValueInMap: NYI"); - } - return; } -void GlobalMemLayout::FillTypeValueInMap(uint32 startaddress, MIRType *ty, MIRConst *c) { - switch (ty->GetKind()) { - case kTypeScalar: - FillScalarValueInMap(startaddress, ty->GetPrimType(), c); - break; - case kTypeArray: { - MIRArrayType *arraytype = static_cast(ty); - MIRType *elemtype = arraytype->GetElemType(); - int32 elemsize = elemtype->GetSize(); - MIRAggConst *aggconst = static_cast(c); - CHECK_FATAL(aggconst, "FillTypeValueInMap: inconsistent array initialization specification"); - MapleVector &constvec = aggconst->GetConstVec(); - for (MapleVector::iterator it = constvec.begin(); it != constvec.end(); - it++, startaddress += elemsize) { - FillTypeValueInMap(startaddress, elemtype, *it); - } - break; - } - case kTypeStruct: { - MIRStructType *structty = static_cast(ty); - MIRAggConst *aggconst = static_cast(c); - CHECK_FATAL(aggconst, "FillTypeValueInMap: inconsistent struct initialization specification"); - MapleVector &constvec = aggconst->GetConstVec(); - for (uint32 i = 0; i < constvec.size(); i++) { - uint32 fieldID = aggconst->GetFieldIdItem(i); - FieldPair thepair = structty->TraverseToField(fieldID); - MIRType *fieldty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - uint32 offset = be->GetFieldOffset(*structty, fieldID).first; - FillTypeValueInMap(startaddress + offset, fieldty, constvec[i]); - } - break; - } - case kTypeClass: { - MIRClassType *classty = static_cast(ty); - MIRAggConst *aggconst = static_cast(c); - CHECK_FATAL(aggconst, "FillTypeValueInMap: inconsistent class initialization specification"); - MapleVector &constvec = aggconst->GetConstVec(); - for (uint32 i = 0; i < constvec.size(); i++) { - uint32 fieldID = aggconst->GetFieldIdItem(i); - FieldPair thepair = classty->TraverseToField(fieldID); - MIRType *fieldty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - uint32 offset = be->GetFieldOffset(*classty, fieldID).first; - FillTypeValueInMap(startaddress + offset, fieldty, constvec[i]); - } - break; - } - default: - CHECK_FATAL(false, "FillTypeValueInMap: NYI"); - } -} - -void GlobalMemLayout::FillSymbolValueInMap(const MIRSymbol *sym) { - if (sym->GetKonst() == nullptr) { - return; - } - uint32 stindex = sym->GetStIndex(); - CHECK(stindex < sym_alloc_table.size(), - "index out of range in GlobalMemLayout::FillSymbolValueInMap"); - uint32 symaddress = sym_alloc_table[stindex].offset; - FillTypeValueInMap(symaddress, sym->GetType(), sym->GetKonst()); - return; -} - -GlobalMemLayout::GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAllocator *mallocator) : - seg_GPbased(MS_GPbased), sym_alloc_table(mallocator->Adapter()), be(b), mirModule(mod) { +GlobalMemLayout::GlobalMemLayout(MIRModule *mod, MapleAllocator *mallocator) : + seg_GPbased(MS_GPbased), sym_alloc_table(mallocator->Adapter()), mirModule(mod) { uint32 symtabsize = GlobalTables::GetGsymTable().GetSymbolTableSize(); sym_alloc_table.resize(symtabsize); MIRSymbol *sym = nullptr; @@ -329,6 +73,9 @@ GlobalMemLayout::GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAll if (sym->GetStorageClass() != kScGlobal && sym->GetStorageClass() != kScFstatic) { continue; } + if (!sym->LMBCAllocateOffSpecialReg()) { + continue; + } if (sym->GetType()->GetAlign() != curalign) { continue; } @@ -341,152 +88,6 @@ GlobalMemLayout::GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAll } seg_GPbased.size = maplebe::RoundUp(seg_GPbased.size, GetPrimTypeSize(PTY_ptr)); mirModule->SetGlobalMemSize(seg_GPbased.size); - // allocate the memory map for the GP block - mirModule->SetGlobalBlockMap( - static_cast(mirModule->GetMemPool()->Calloc(seg_GPbased.size))); - // perform initialization on globalblkmap - for (uint32 i = 0; i < symtabsize; i++) { - sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(i); - if (!sym) { - continue; - } - if (sym->GetStorageClass() != kScGlobal && sym->GetStorageClass() != kScFstatic) { - continue; - } - } -} - -// LocateNextParm should be called with each parameter in the parameter list -// starting from the beginning, one call per parameter in sequence; it returns -// the information on how each parameter is passed in ploc -void ParmLocator::LocateNextParm(const MIRType *ty, PLocInfo &ploc) { - ploc.memoffset = maplebe::RoundUp(lastMemOffset, 8); - ploc.memsize = ty->GetSize(); - - uint32 rightpad = 0; - parmNum++; - - switch (ty->GetPrimType()) { - case PTY_u1: - case PTY_u8: - case PTY_i8: - case PTY_u16: - case PTY_i16: - rightpad = GetPrimTypeSize(PTY_i32) - ploc.memsize; - break; - case PTY_a32: - case PTY_u32: - case PTY_i32: - case PTY_a64: - case PTY_u64: - case PTY_i64: - case PTY_ptr: - case PTY_ref: -#ifdef DYNAMICLANG - case PTY_simplestr: - case PTY_simpleobj: - case PTY_dynany: - case PTY_dyni32: - case PTY_dynf64: - case PTY_dynstr: - case PTY_dynobj: - case PTY_dynundef: - case PTY_dynbool: - case PTY_dynf32: - case PTY_dynnone: - case PTY_dynnull: -#endif - break; - - case PTY_f32: - rightpad = GetPrimTypeSize(PTY_f64) - ploc.memsize; - break; - case PTY_c64: - case PTY_f64: - case PTY_v2i32: - case PTY_v4i16: - case PTY_v8i8: - case PTY_v2u32: - case PTY_v4u16: - case PTY_v8u8: - case PTY_v2f32: - break; - - case PTY_c128: - case PTY_v2i64: - case PTY_v4i32: - case PTY_v8i16: - case PTY_v16i8: - case PTY_v2u64: - case PTY_v4u32: - case PTY_v8u16: - case PTY_v16u8: - case PTY_v2f64: - case PTY_v4f32: - break; - - case PTY_agg: { - // compute rightpad - int32 paddedSize = maplebe::RoundUp(ploc.memsize, 8); - rightpad = paddedSize - ploc.memsize; - break; - } - default: - CHECK_FATAL(false, "unsupported type"); - } - - lastMemOffset = ploc.memoffset + ploc.memsize + rightpad; - return; -} - -// instantiated with the type of the function return value, it describes how -// the return value is to be passed back to the caller -ReturnMechanism::ReturnMechanism(const MIRType *retty) : fake_first_parm(false) { - switch (retty->GetPrimType()) { - case PTY_u1: - case PTY_u8: - case PTY_i8: - case PTY_u16: - case PTY_i16: - case PTY_a32: - case PTY_u32: - case PTY_i32: - case PTY_a64: - case PTY_u64: - case PTY_i64: - case PTY_f32: - case PTY_f64: -#ifdef DYNAMICLANG - case PTY_simplestr: - case PTY_simpleobj: - case PTY_dynany: - case PTY_dyni32: - case PTY_dynstr: - case PTY_dynobj: -#endif - ptype0 = retty->GetPrimType(); - return; - - case PTY_c64: - case PTY_c128: - fake_first_parm = true; - ptype0 = PTY_a32; - return; - - case PTY_agg: { - uint32 size = retty->GetSize(); - if (size > 4) { - fake_first_parm = true; - ptype0 = PTY_a32; - } else { - ptype0 = PTY_u32; - } - return; - } - - default: - return; - } } } // namespace maple diff --git a/src/mapleall/maple_me/src/me_cfg.cpp b/src/mapleall/maple_me/src/me_cfg.cpp index c1d452d10a..521cb1a944 100644 --- a/src/mapleall/maple_me/src/me_cfg.cpp +++ b/src/mapleall/maple_me/src/me_cfg.cpp @@ -260,6 +260,7 @@ bool MeCFG::FindUse(const StmtNode &stmt, StIdx stIdx) const { case OP_customcall: case OP_polymorphiccall: case OP_icall: + case OP_icallproto: case OP_intrinsiccall: case OP_xintrinsiccall: case OP_intrinsiccallwithtype: @@ -272,6 +273,7 @@ bool MeCFG::FindUse(const StmtNode &stmt, StIdx stIdx) const { case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_intrinsiccallassigned: case OP_xintrinsiccallassigned: case OP_intrinsiccallwithtypeassigned: diff --git a/src/mapleall/maple_me/src/me_function.cpp b/src/mapleall/maple_me/src/me_function.cpp index 05181df796..a62f1a89a3 100755 --- a/src/mapleall/maple_me/src/me_function.cpp +++ b/src/mapleall/maple_me/src/me_function.cpp @@ -303,7 +303,9 @@ void MeFunction::CloneBBMeStmts(BB &srcBB, BB &destBB, std::map(&stmt); newStmt = irmap->NewInPool(static_cast(icallStmt), icallStmt->GetRetTyIdx(), icallStmt->GetStmtID()); diff --git a/src/mapleall/maple_me/src/me_lower_globals.cpp b/src/mapleall/maple_me/src/me_lower_globals.cpp index c14dd5c764..fdf2df8e3f 100644 --- a/src/mapleall/maple_me/src/me_lower_globals.cpp +++ b/src/mapleall/maple_me/src/me_lower_globals.cpp @@ -185,7 +185,12 @@ void MeLowerGlobals::Run() { MeExpr *addroffuncExpr = irMap->CreateAddroffuncMeExpr(callee.GetPuidx()); auto insertpos = callStmt.GetOpnds().begin(); callStmt.InsertOpnds(insertpos, addroffuncExpr); - IcallMeStmt *icallStmt = irMap->NewInPool(stmt.GetOp() == OP_call ? OP_icall : OP_icallassigned); + IcallMeStmt *icallStmt = nullptr; + if (func.GetMIRModule().IsCModule()) { + icallStmt = irMap->NewInPool(stmt.GetOp() == OP_call ? OP_icallproto : OP_icallprotoassigned); + } else { + icallStmt = irMap->NewInPool(stmt.GetOp() == OP_call ? OP_icall : OP_icallassigned); + } icallStmt->SetIsLive(callStmt.GetIsLive()); icallStmt->SetSrcPos(callStmt.GetSrcPosition()); for (MeExpr *o : callStmt.GetOpnds()) { @@ -193,7 +198,11 @@ void MeLowerGlobals::Run() { } icallStmt->GetMuList()->insert(callStmt.GetMuList()->begin(), callStmt.GetMuList()->end()); icallStmt->GetChiList()->insert(callStmt.GetChiList()->begin(), callStmt.GetChiList()->end()); - icallStmt->SetRetTyIdx(callee.GetReturnTyIdx()); + if (func.GetMIRModule().IsCModule()) { + icallStmt->SetRetTyIdx(callee.GetMIRFuncType()->GetTypeIndex()); + } else { + icallStmt->SetRetTyIdx(callee.GetReturnTyIdx()); + } if (stmt.GetOp() != OP_call) { if (callStmt.NeedDecref()) { icallStmt->EnableNeedDecref(); diff --git a/src/mapleall/maple_me/src/me_phase_manager.cpp b/src/mapleall/maple_me/src/me_phase_manager.cpp index 09a1b64e5a..a0b5419a8e 100644 --- a/src/mapleall/maple_me/src/me_phase_manager.cpp +++ b/src/mapleall/maple_me/src/me_phase_manager.cpp @@ -140,8 +140,8 @@ bool MeFuncPM::PhaseRun(maple::MIRModule &m) { } if (genLMBC) { m.SetFlavor(kFlavorLmbc); + GlobalMemLayout globalMemLayout(&m, &m.GetMPAllocator()); maplebe::BECommon beCommon(m); - GlobalMemLayout globalMemLayout(&beCommon, &m, &m.GetMPAllocator()); maplebe::CGLowerer cgLower(m, beCommon, false, false); cgLower.RegisterBuiltIns(); cgLower.RegisterExternalLibraryFunctions(); @@ -153,14 +153,15 @@ bool MeFuncPM::PhaseRun(maple::MIRModule &m) { cgLower.LowerFunc(*func); MemPool *layoutMp = memPoolCtrler.NewMemPool("layout mempool", true); MapleAllocator layoutAlloc(layoutMp); - LMBCMemLayout localMemLayout(func, &layoutAlloc); + LMBCMemLayout localMemLayout(func, &globalMemLayout.seg_GPbased, &layoutAlloc); localMemLayout.LayoutStackFrame(); LMBCLowerer lmbcLowerer(&m, &beCommon, func, &globalMemLayout, &localMemLayout); lmbcLowerer.LowerFunction(); func->SetFrameSize(localMemLayout.StackFrameSize()); - func->SetUpFormalSize(localMemLayout.UpformalSize()); memPoolCtrler.DeleteMemPool(layoutMp); } + globalMemLayout.seg_GPbased.size = maplebe::RoundUp(globalMemLayout.seg_GPbased.size, GetPrimTypeSize(PTY_ptr)); + m.SetGlobalMemSize(globalMemLayout.seg_GPbased.size); // output .lmbc BinaryMplt binMplt(m); std::string modFileName = m.GetFileName(); diff --git a/src/mapleall/maple_me/src/me_rc_lowering.cpp b/src/mapleall/maple_me/src/me_rc_lowering.cpp index 8b3897a1c6..edf6f45509 100644 --- a/src/mapleall/maple_me/src/me_rc_lowering.cpp +++ b/src/mapleall/maple_me/src/me_rc_lowering.cpp @@ -1144,6 +1144,7 @@ void RCLowering::HandleArguments() { firstBB->InsertMeStmtBefore(firstMeStmt, incCall); } sym->SetLocalRefVar(); + mirFunc->GetFormalDefVec()[i].formalAttrs.SetAttr(ATTR_localrefvar); for (auto *stmt : rets) { std::vector opnds = { argVar }; diff --git a/src/mapleall/maple_me/src/me_rename2preg.cpp b/src/mapleall/maple_me/src/me_rename2preg.cpp index 9549dff004..eddc9704b9 100644 --- a/src/mapleall/maple_me/src/me_rename2preg.cpp +++ b/src/mapleall/maple_me/src/me_rename2preg.cpp @@ -317,6 +317,7 @@ void SSARename2Preg::Rename2PregStmt(MeStmt *stmt) { case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_intrinsiccallassigned: case OP_xintrinsiccallassigned: case OP_intrinsiccallwithtypeassigned: { diff --git a/src/mapleall/maple_me/src/me_side_effect.cpp b/src/mapleall/maple_me/src/me_side_effect.cpp index ad493a9e01..2df2f0a2c5 100644 --- a/src/mapleall/maple_me/src/me_side_effect.cpp +++ b/src/mapleall/maple_me/src/me_side_effect.cpp @@ -932,6 +932,7 @@ bool IpaSideEffect::UpdateSideEffectWithStmt(MeStmt &meStmt, case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_superclasscallassigned: case OP_asm: { hasPrivateDef = hasThrException = true; @@ -958,7 +959,8 @@ bool IpaSideEffect::UpdateSideEffectWithStmt(MeStmt &meStmt, case OP_interfaceicall: case OP_customcall: case OP_polymorphiccall: - case OP_icall: { + case OP_icall: + case OP_icallproto: { hasPrivateDef = hasThrException = true; SetHasDef(); for (size_t i = 0; i < meStmt.NumMeStmtOpnds(); ++i) { diff --git a/src/mapleall/maple_me/src/me_stmt_pre.cpp b/src/mapleall/maple_me/src/me_stmt_pre.cpp index e851282f1b..991d5066e9 100755 --- a/src/mapleall/maple_me/src/me_stmt_pre.cpp +++ b/src/mapleall/maple_me/src/me_stmt_pre.cpp @@ -967,7 +967,9 @@ void MeStmtPre::BuildWorkListBB(BB *bb) { break; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { auto &icallMeStmt = static_cast(stmt); VersionStackChiListUpdate(*icallMeStmt.GetChiList()); break; diff --git a/src/mapleall/maple_me/src/pme_emit.cpp b/src/mapleall/maple_me/src/pme_emit.cpp index 227cb6a761..52e1df6beb 100755 --- a/src/mapleall/maple_me/src/pme_emit.cpp +++ b/src/mapleall/maple_me/src/pme_emit.cpp @@ -485,10 +485,12 @@ StmtNode* PreMeEmitter::EmitPreMeStmt(MeStmt *mestmt, BaseNode *parent) { return callnode; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { IcallMeStmt *icallMeStmt = static_cast (mestmt); IcallNode *icallnode = - codeMP->New(*codeMPAlloc, OP_icallassigned, icallMeStmt->GetRetTyIdx()); + codeMP->New(*codeMPAlloc, OP_icallprotoassigned, icallMeStmt->GetRetTyIdx()); for (uint32 i = 0; i < icallMeStmt->GetOpnds().size(); i++) { icallnode->GetNopnd().push_back(EmitPreMeExpr(icallMeStmt->GetOpnd(i), icallnode)); } @@ -509,6 +511,9 @@ StmtNode* PreMeEmitter::EmitPreMeStmt(MeStmt *mestmt, BaseNode *parent) { icallnode->SetRetTyIdx(TyIdx(preg->GetPrimType())); } } + if (mestmt->GetOp() == OP_icallproto || mestmt->GetOp() == OP_icallprotoassigned) { + icallnode->SetRetTyIdx(icallMeStmt->GetRetTyIdx()); + } icallnode->CopySafeRegionAttr(mestmt->GetStmtAttr()); icallnode->SetOriginalID(mestmt->GetOriginalId()); PreMeStmtExtensionMap[icallnode->GetStmtID()] = pmeExt; diff --git a/src/mapleall/maple_me/src/ssa_devirtual.cpp b/src/mapleall/maple_me/src/ssa_devirtual.cpp index 15a609e427..f46e8e06ce 100644 --- a/src/mapleall/maple_me/src/ssa_devirtual.cpp +++ b/src/mapleall/maple_me/src/ssa_devirtual.cpp @@ -534,7 +534,9 @@ void SSADevirtual::TraversalMeStmt(MeStmt &meStmt) { break; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { auto *icallMeStmt = static_cast(&meStmt); const MapleVector &opnds = icallMeStmt->GetOpnds(); for (size_t i = 0; i < opnds.size(); ++i) { diff --git a/src/mapleall/maple_me/src/ssa_pre.cpp b/src/mapleall/maple_me/src/ssa_pre.cpp index ceff080daa..a082b80b9f 100644 --- a/src/mapleall/maple_me/src/ssa_pre.cpp +++ b/src/mapleall/maple_me/src/ssa_pre.cpp @@ -1666,6 +1666,7 @@ void SSAPre::BuildWorkListStmt(MeStmt &stmt, uint32 seqStmt, bool isRebuilt, MeE case OP_customcall: case OP_polymorphiccall: case OP_icall: + case OP_icallproto: case OP_callassigned: case OP_virtualcallassigned: case OP_virtualicallassigned: @@ -1675,6 +1676,7 @@ void SSAPre::BuildWorkListStmt(MeStmt &stmt, uint32 seqStmt, bool isRebuilt, MeE case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_asm: { auto *naryMeStmt = static_cast(meStmt); const MapleVector &opnds = naryMeStmt->GetOpnds(); diff --git a/src/mapleall/mpl2mpl/src/constantfold.cpp b/src/mapleall/mpl2mpl/src/constantfold.cpp index 860ed2846a..d89d6ef64d 100644 --- a/src/mapleall/mpl2mpl/src/constantfold.cpp +++ b/src/mapleall/mpl2mpl/src/constantfold.cpp @@ -162,6 +162,8 @@ StmtNode *ConstantFold::Simplify(StmtNode *node) { return SimplifyNary(static_cast(node)); case OP_icall: case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: return SimplifyIcall(static_cast(node)); case OP_asm: return SimplifyAsm(static_cast(node)); @@ -2618,8 +2620,8 @@ StmtNode *ConstantFold::SimplifyIcall(IcallNode *node) { AddroffuncNode *addrofNode = static_cast(node->GetNopndAt(0)); CallNode *callNode = mirModule->CurFuncCodeMemPool()->New(*mirModule, - node->GetOpCode() == OP_icall ? OP_call : OP_callassigned); - if (node->GetOpCode() == OP_icallassigned) { + (node->GetOpCode() == OP_icall || node->GetOpCode() == OP_icallproto) ? OP_call : OP_callassigned); + if (node->GetOpCode() == OP_icallassigned || node->GetOpCode() == OP_icallprotoassigned) { callNode->SetReturnVec(node->GetReturnVec()); } callNode->SetPUIdx(addrofNode->GetPUIdx()); -- Gitee From efb9365f0e372feecbfa3b6cdd0ac035e2e9faf9 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:44 -0700 Subject: [PATCH 006/124] Fred's Fixed determination logic of when there is fake parameter for returning struct, where x8 is also used to pass the fake parameter --- .../maple_be/src/cg/aarch64/aarch64_args.cpp | 4 ++-- .../src/cg/aarch64/aarch64_call_conv.cpp | 11 ++++++----- .../maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 18 ++++++++++++------ .../src/cg/aarch64/aarch64_memlayout.cpp | 4 ++-- 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index e3e84d131b..cc8b10b6c5 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -38,7 +38,7 @@ void AArch64MoveRegArgs::CollectRegisterArgs(std::map &argsL uint32 start = 0; if (numFormal) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsFirstArgReturn()) { + if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16ByteSize) { start = 1; @@ -436,7 +436,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsFirstArgReturn()) { + if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp index 6591367dff..47de683479 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp @@ -306,18 +306,18 @@ int32 AArch64CallConvImpl::LocateNextParm(MIRType &mirType, CCLocInfo &pLoc, boo if (size == 0) { /* For return struct size 0 there is no return value. */ return 0; - } else if (size > k16ByteSize) { - /* For return struct size > 16 bytes the pointer returns in x8. */ - pLoc.reg0 = R8; - return kSizeOfPtr; } + /* For return struct size > 16 bytes the pointer returns in x8. */ + pLoc.reg0 = R8; + return kSizeOfPtr; +#if 0 /* For return struct size less or equal to 16 bytes, the values * are returned in register pairs. * Check for pure float struct. */ AArch64ArgumentClass classes[kMaxRegCount] = { kAArch64NoClass }; uint32 fpSize; - MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(beCommon.GetFuncReturnType(*func)); + MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); uint32 numRegs = static_cast(ClassifyAggregate(beCommon, *retType, classes, sizeof(classes), fpSize)); if (classes[0] == kAArch64FloatClass) { CHECK_FATAL(numRegs <= kMaxRegCount, "LocateNextParm: illegal number of regs"); @@ -334,6 +334,7 @@ int32 AArch64CallConvImpl::LocateNextParm(MIRType &mirType, CCLocInfo &pLoc, boo } return 0; } +#endif } } uint64 typeSize = beCommon.GetTypeSize(mirType.GetTypeIndex()); 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 57de84100d..f39833ddfa 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8064,6 +8064,17 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo std::set specialArgs; SelectParmListPreprocess(naryNode, i, specialArgs); bool specialArg = false; + bool firstArgReturn = false; + MIRFunction *callee = nullptr; + if (dynamic_cast(&naryNode) != nullptr) { + auto calleePuIdx = static_cast(naryNode).GetPUIdx(); + callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + firstArgReturn = callee->IsFirstArgReturn(); + } else if (naryNode.GetOpCode() == OP_icallproto) { + IcallNode *icallnode = &static_cast(naryNode); + MIRFuncType *funcType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallnode->GetRetTyIdx())); + firstArgReturn = funcType->FirstArgReturn(); + } BB *curBBrecord = GetCurBB(); BB *tmpBB = nullptr; if (!specialArgs.empty()) { @@ -8085,11 +8096,6 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); - MIRFunction *callee = nullptr; - if (dynamic_cast(&naryNode) != nullptr) { - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); - } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } @@ -8154,7 +8160,7 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo } expRegOpnd = static_cast(opnd); - if ((pnum == 0) && (SelectParmListGetStructReturnSize(naryNode) > k16ByteSize)) { + if ((pnum == 0) && firstArgReturn) { parmLocator.InitCCLocInfo(ploc); ploc.reg0 = R8; } else { diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp index 71f57d89ea..de95e9be33 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp @@ -210,7 +210,7 @@ void AArch64MemLayout::LayoutFormalParams() { AArch64SymbolAlloc *symLoc = memAllocator->GetMemPool()->New(); SetSymAllocInfo(stIndex, *symLoc); if (i == 0) { - if (mirFunction->IsFirstArgReturn()) { + if (mirFunction->IsReturnStruct() && mirFunction->IsFirstArgReturn()) { symLoc->SetMemSegment(GetSegArgsRegPassed()); symLoc->SetOffset(GetSegArgsRegPassed().GetSize()); TyIdx tyIdx = mirFunction->GetFuncRetStructTyIdx(); @@ -395,7 +395,7 @@ void AArch64MemLayout::LayoutReturnRef(std::vector &returnDelays, void AArch64MemLayout::LayoutActualParams() { for (size_t i = 0; i < mirFunction->GetFormalCount(); ++i) { if (i == 0) { - if (mirFunction->IsReturnStruct()) { + if (mirFunction->IsReturnStruct() && mirFunction->IsFirstArgReturn()) { continue; } } -- Gitee From c7e51c02f1ba857a11e4158e857501b1ba2468aa Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:53:00 -0700 Subject: [PATCH 007/124] Remove unneeded fp def. Turn on tailcall. no unneeded pro/epilog. --- .../maple_be/include/cg/aarch64/aarch64_color_ra.h | 1 + src/mapleall/maple_be/include/cg/cgfunc.h | 9 +++++++++ .../maple_be/src/cg/aarch64/aarch64_color_ra.cpp | 6 ++++++ .../maple_be/src/cg/aarch64/aarch64_proepilog.cpp | 7 +++---- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h index 491d59453f..d0588c51c4 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h @@ -1519,6 +1519,7 @@ class GraphColorRegAllocator : public RegAllocator { #endif bool hasSpill = false; bool doMultiPass = false; + bool seenFP = false; }; class CallerSavePre: public CGPre { diff --git a/src/mapleall/maple_be/include/cg/cgfunc.h b/src/mapleall/maple_be/include/cg/cgfunc.h index a57bd11299..f79c4216df 100644 --- a/src/mapleall/maple_be/include/cg/cgfunc.h +++ b/src/mapleall/maple_be/include/cg/cgfunc.h @@ -1107,6 +1107,14 @@ class CGFunc { return useFP; } + void UnsetSeenFP() { + seenFP = false; + } + + bool SeenFP() const { + return seenFP; + } + void UpdateAllRegisterVregMapping(MapleMap &newMap); void RegisterVregMapping(regno_t vRegNum, PregIdx pidx) { @@ -1276,6 +1284,7 @@ class CGFunc { const MapleString shortFuncName; bool hasAsm = false; bool useFP = true; + bool seenFP = true; /* save stack protect kinds which can trigger stack protect */ uint8 stackProtectInfo = 0; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp index 3b878b6c7a..1ed5f1480a 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp @@ -3629,6 +3629,9 @@ RegOperand *GraphColorRegAllocator::GetReplaceOpnd(Insn &insn, const Operand &op auto ®Opnd = static_cast(opnd); uint32 vregNO = regOpnd.GetRegisterNumber(); + if (vregNO == RFP) { + seenFP = true; + } RegType regType = regOpnd.GetRegisterType(); if (vregNO < kAllRegNum) { return nullptr; @@ -4996,6 +4999,9 @@ bool GraphColorRegAllocator::AllocateRegisters() { MarkCalleeSaveRegs(); + if (seenFP == false) { + cgFunc->UnsetSeenFP(); + } if (GCRA_DUMP) { cgFunc->DumpCGIR(); } diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp index 0c2322d055..40cd20362a 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp @@ -185,9 +185,6 @@ void AArch64GenProEpilog::TailCallBBOpt(BB &bb, MapleSet &callInsns, BB & * Return value: true if function do not need Prologue/Epilogue. false otherwise. */ bool AArch64GenProEpilog::TailCallOpt() { - if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { - return false; - } /* Count how many call insns in the whole function. */ uint32 nCount = 0; bool hasGetStackClass = false; @@ -1229,7 +1226,9 @@ void AArch64GenProEpilog::GeneratePushRegs() { } else { immOpnd = &aarchCGFunc.CreateImmOperand(argsToStkPassSize, k32BitSize, true); } - aarchCGFunc.SelectAdd(fpOpnd, spOpnd, *immOpnd, PTY_u64); + if (isLmbc == false || cgFunc.SeenFP() || cgFunc.GetFunction().GetAttr(FUNCATTR_varargs)) { + aarchCGFunc.SelectAdd(fpOpnd, spOpnd, *immOpnd, PTY_u64); + } cgFunc.GetCurBB()->GetLastInsn()->SetFrameDef(true); if (cgFunc.GenCfi()) { cgFunc.GetCurBB()->AppendInsn(aarchCGFunc.CreateCfiDefCfaInsn(stackBaseReg, -- Gitee From f7472e9a2df3cec5b6a7279987da48fc7f3ffd9e Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:53:14 -0700 Subject: [PATCH 008/124] Fred's Set firstarg_return attribute in the new funcAttrs field in MIRFuncType --- src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp | 3 +++ src/mapleall/maple_ir/src/mir_lower.cpp | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp b/src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp index 3a77948b15..63c34ea154 100644 --- a/src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp +++ b/src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp @@ -278,6 +278,9 @@ bool ASTFunc2FEHelper::ProcessDeclImpl(MapleAllocator &allocator) { ENCChecker::InsertBoundaryInAtts(attrs, func.GetBoundaryInfo()); mirMethodPair.second.second = attrs; mirFunc->SetFuncAttrs(attrs); + if (firstArgRet) { + mirFunc->GetMIRFuncType()->funcAttrs.SetAttr(FUNCATTR_firstarg_return); + } func.ClearGenericAttrsContentMap(); return true; } diff --git a/src/mapleall/maple_ir/src/mir_lower.cpp b/src/mapleall/maple_ir/src/mir_lower.cpp index aa5cb0131c..9b8c3f8d92 100644 --- a/src/mapleall/maple_ir/src/mir_lower.cpp +++ b/src/mapleall/maple_ir/src/mir_lower.cpp @@ -539,6 +539,10 @@ BlockNode *MIRLower::LowerBlock(BlockNode &block) { MIRFuncType *funcType = FuncTypeFromFuncPtrExpr(stmt->Opnd(0)); CHECK_FATAL(funcType != nullptr, "MIRLower::LowerBlock: cannot find prototype for icall"); ic->SetRetTyIdx(funcType->GetTypeIndex()); + MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcType->GetRetTyIdx()); + if (retType->GetPrimType() == PTY_agg && retType->GetSize() > 16) { + funcType->funcAttrs.SetAttr(FUNCATTR_firstarg_return); + } } newBlock->AddStatement(stmt); break; -- Gitee From 717b17ca7314ae3ba45be053faed9d51c2b5430e Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 009/124] Changes from mplcglmbc8 and mplcglmbc9. --- src/mapleall/maple_be/include/be/lower.h | 2 +- .../include/cg/aarch64/aarch64_cgfunc.h | 32 +- .../include/cg/aarch64/aarch64_phases.def | 2 +- src/mapleall/maple_be/include/cg/call_conv.h | 22 +- src/mapleall/maple_be/include/cg/cg.h | 19 +- src/mapleall/maple_be/include/cg/cgfunc.h | 2 + src/mapleall/maple_be/src/be/lower.cpp | 82 ++- .../maple_be/src/cg/aarch64/aarch64_args.cpp | 4 +- .../src/cg/aarch64/aarch64_call_conv.cpp | 2 +- .../src/cg/aarch64/aarch64_cgfunc.cpp | 547 +++++++++++++++--- .../maple_be/src/cg/aarch64/aarch64_ebo.cpp | 4 +- .../src/cg/aarch64/aarch64_memlayout.cpp | 32 +- .../src/cg/aarch64/aarch64_offset_adjust.cpp | 2 +- .../src/cg/aarch64/aarch64_proepilog.cpp | 87 ++- .../src/cg/aarch64/aarch64_reaching.cpp | 3 +- .../maple_be/src/cg/cg_phasemanager.cpp | 1 + src/mapleall/maple_be/src/cg/cgfunc.cpp | 44 +- src/mapleall/maple_be/src/cg/emit.cpp | 5 + src/mapleall/maple_be/src/cg/memlayout.cpp | 6 +- .../maple_ir/include/bin_mpl_export.h | 28 +- .../maple_ir/include/bin_mpl_import.h | 12 +- .../maple_ir/include/ir_safe_cast_traits.def | 4 +- src/mapleall/maple_ir/include/keywords.def | 1 - src/mapleall/maple_ir/include/mir_builder.h | 2 + src/mapleall/maple_ir/include/mir_function.h | 18 +- src/mapleall/maple_ir/include/mir_lower.h | 1 + src/mapleall/maple_ir/include/mir_nodes.h | 2 +- src/mapleall/maple_ir/include/mir_parser.h | 2 +- src/mapleall/maple_ir/include/mir_symbol.h | 6 +- src/mapleall/maple_ir/include/mir_type.h | 27 +- src/mapleall/maple_ir/include/opcode_info.h | 1 + src/mapleall/maple_ir/include/opcodes.def | 1 + src/mapleall/maple_ir/include/opcodes.h | 4 +- src/mapleall/maple_ir/src/bin_func_export.cpp | 239 ++++---- src/mapleall/maple_ir/src/bin_func_import.cpp | 248 ++++---- src/mapleall/maple_ir/src/bin_mpl_export.cpp | 112 ++-- src/mapleall/maple_ir/src/bin_mpl_import.cpp | 48 +- src/mapleall/maple_ir/src/global_tables.cpp | 4 +- src/mapleall/maple_ir/src/mir_builder.cpp | 24 + src/mapleall/maple_ir/src/mir_function.cpp | 4 +- src/mapleall/maple_ir/src/mir_lower.cpp | 107 ++++ src/mapleall/maple_ir/src/mir_nodes.cpp | 4 +- src/mapleall/maple_ir/src/mir_parser.cpp | 31 +- src/mapleall/maple_ir/src/mir_type.cpp | 8 +- src/mapleall/maple_ir/src/parser.cpp | 18 +- src/mapleall/maple_me/include/lmbc_lower.h | 3 - .../maple_me/include/lmbc_memlayout.h | 59 +- src/mapleall/maple_me/src/alias_class.cpp | 8 +- src/mapleall/maple_me/src/code_factoring.cpp | 4 +- .../src/demand_driven_alias_analysis.cpp | 4 +- src/mapleall/maple_me/src/irmap_build.cpp | 7 +- src/mapleall/maple_me/src/irmap_emit.cpp | 5 +- src/mapleall/maple_me/src/lfo_dep_test.cpp | 2 + src/mapleall/maple_me/src/lmbc_lower.cpp | 258 ++------- src/mapleall/maple_me/src/lmbc_memlayout.cpp | 439 +------------- src/mapleall/maple_me/src/me_cfg.cpp | 2 + src/mapleall/maple_me/src/me_function.cpp | 4 +- .../maple_me/src/me_lower_globals.cpp | 13 +- .../maple_me/src/me_phase_manager.cpp | 7 +- src/mapleall/maple_me/src/me_rc_lowering.cpp | 1 + src/mapleall/maple_me/src/me_rename2preg.cpp | 1 + src/mapleall/maple_me/src/me_side_effect.cpp | 4 +- src/mapleall/maple_me/src/me_stmt_pre.cpp | 4 +- src/mapleall/maple_me/src/pme_emit.cpp | 9 +- src/mapleall/maple_me/src/ssa_devirtual.cpp | 4 +- src/mapleall/maple_me/src/ssa_pre.cpp | 2 + src/mapleall/mpl2mpl/src/constantfold.cpp | 6 +- 67 files changed, 1404 insertions(+), 1296 deletions(-) diff --git a/src/mapleall/maple_be/include/be/lower.h b/src/mapleall/maple_be/include/be/lower.h index 6da66a3fcf..92c9e840e9 100644 --- a/src/mapleall/maple_be/include/be/lower.h +++ b/src/mapleall/maple_be/include/be/lower.h @@ -187,7 +187,7 @@ class CGLowerer { void LowerTryCatchBlocks(BlockNode &body); #if TARGARM32 || TARGAARCH64 || TARGRISCV64 - BlockNode *LowerReturnStruct(NaryStmtNode &retNode); + BlockNode *LowerReturnStructUsingFakeParm(NaryStmtNode &retNode); #endif virtual BlockNode *LowerReturn(NaryStmtNode &retNode); void LowerEntry(MIRFunction &func); 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 77f94fcacd..c2d555be1a 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -38,6 +38,7 @@ class LmbcArgInfo { MapleVector lmbcCallArgTypes; MapleVector lmbcCallArgOffsets; MapleVector lmbcCallArgNumOfRegs; // # of regs needed to complete struct + uint32 lmbcTotalStkUsed = -1; // TBD: remove when explicit addr for large agg is available }; class AArch64CGFunc : public CGFunc { @@ -101,7 +102,7 @@ class AArch64CGFunc : public CGFunc { return kRFLAG; } - MIRType *GetAggTyFromCallSite(StmtNode *stmt); + MIRType *LmbcGetAggTyFromCallSite(StmtNode *stmt, std::vector **parmList); RegOperand &GetOrCreateResOperand(const BaseNode &parent, PrimType primType); void IntrinsifyGetAndAddInt(ListOperand &srcOpnds, PrimType pty); @@ -125,9 +126,11 @@ class AArch64CGFunc : public CGFunc { bool needLow12 = false); MemOperand *FixLargeMemOpnd(MemOperand &memOpnd, uint32 align); MemOperand *FixLargeMemOpnd(MOperator mOp, MemOperand &memOpnd, uint32 dSize, uint32 opndIdx); + uint32 LmbcFindTotalStkUsed(std::vector* paramList); + uint32 LmbcTotalRegsUsed(); void LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn); - bool LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *src); - bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForRet(BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; void SelectIassignoff(IassignoffNode &stmt) override; @@ -135,6 +138,7 @@ class AArch64CGFunc : public CGFunc { void SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd) override; void SelectBlkassignoff(BlkassignoffNode &bNode, Operand *src) override; void SelectAggIassign(IassignNode &stmt, Operand &lhsAddrOpnd) override; + void SelectReturnSendOfStructInRegs(BaseNode *x) override; void SelectReturn(Operand *opnd0) override; void SelectIgoto(Operand *opnd0) override; void SelectCondGoto(CondGotoNode &stmt, Operand &opnd0, Operand &opnd1) override; @@ -486,7 +490,10 @@ class AArch64CGFunc : public CGFunc { void GenerateCleanupCodeForExtEpilog(BB &bb) override; uint32 FloatParamRegRequired(MIRStructType *structType, uint32 &fpSize) override; void AssignLmbcFormalParams() override; - RegOperand *GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType); + void LmbcGenSaveSpForAlloca() override; + MemOperand *GenLmbcFpMemOperand(int32 offset, uint32 byteSize, AArch64reg base = RFP); + RegOperand *GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType, AArch64reg baseRegno = RFP); + RegOperand *LmbcStructReturnLoad(int32 offset); Operand *GetBaseReg(const AArch64SymbolAlloc &symAlloc); int32 GetBaseOffset(const SymbolAlloc &symAlloc) override; @@ -726,6 +733,22 @@ class AArch64CGFunc : public CGFunc { return lmbcArgInfo->lmbcCallArgNumOfRegs; } + int32 GetLmbcTotalStkUsed() { + return lmbcArgInfo->lmbcTotalStkUsed; + } + + void SetLmbcTotalStkUsed(int32 offset) { + lmbcArgInfo->lmbcTotalStkUsed = offset; + } + + void SetLmbcCallReturnType(MIRType *ty) { + lmbcCallReturnType = ty; + } + + MIRType *GetLmbcCallReturnType() { + return lmbcCallReturnType; + } + private: enum RelationOperator : uint8 { kAND, @@ -793,6 +816,7 @@ class AArch64CGFunc : public CGFunc { regno_t methodHandleVreg = -1; uint32 alignPow = 5; /* function align pow defaults to 5 i.e. 2^5*/ LmbcArgInfo *lmbcArgInfo = nullptr; + MIRType *lmbcCallReturnType = nullptr; void SelectLoadAcquire(Operand &dest, PrimType dtype, Operand &src, PrimType stype, AArch64isa::MemoryOrdering memOrd, bool isDirect); diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def b/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def index a3a74d7b2f..ff08e81852 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def @@ -16,8 +16,8 @@ ADDTARGETPHASE("createstartendlabel", true); ADDTARGETPHASE("buildehfunc", true); ADDTARGETPHASE("handlefunction", true); + ADDTARGETPHASE("moveargs", true); if (GetMIRModule()->GetFlavor() != MIRFlavor::kFlavorLmbc) { - ADDTARGETPHASE("moveargs", true); /* SSA PHASES */ ADDTARGETPHASE("cgssaconstruct", CGOptions::DoCGSSA()); ADDTARGETPHASE("cgcopyprop", CGOptions::DoCGSSA()); diff --git a/src/mapleall/maple_be/include/cg/call_conv.h b/src/mapleall/maple_be/include/cg/call_conv.h index 9cfab98b56..4e33309c3c 100644 --- a/src/mapleall/maple_be/include/cg/call_conv.h +++ b/src/mapleall/maple_be/include/cg/call_conv.h @@ -63,8 +63,8 @@ struct CCLocInfo { class LmbcFormalParamInfo { public: LmbcFormalParamInfo(PrimType pType, uint32 ofst, uint32 sz) : - type(nullptr), primType(pType), offset(ofst), size(sz), regNO(0), vregNO(0), numRegs(0), - fpSize(0), isReturn(false), isPureFloat(false), isOnStack(false) {} + type(nullptr), primType(pType), offset(ofst), onStackOffset(0), size(sz), regNO(0), vregNO(0), numRegs(0), + fpSize(0), isReturn(false), isPureFloat(false), isOnStack(false), hasRegassign(false) {} ~LmbcFormalParamInfo() = default; @@ -86,7 +86,13 @@ class LmbcFormalParamInfo { void SetOffset(uint32 ofs) { offset = ofs; } - uint32 GetSize() const { + uint32 GetOnStackOffset() { + return onStackOffset; + } + void SetOnStackOffset(uint32 ofs) { + onStackOffset = ofs; + } + uint32 GetSize() { return size; } void SetSize(uint32 sz) { @@ -137,10 +143,17 @@ class LmbcFormalParamInfo { void SetIsOnStack() { isOnStack = true; } + bool HasRegassign() { + return hasRegassign; + } + void SetHasRegassign() { + hasRegassign = true; + } private: MIRStructType *type; PrimType primType; uint32 offset; + uint32 onStackOffset; /* stack location if isOnStack */ uint32 size; /* size primtype or struct */ regno_t regNO = 0; /* param reg num or starting reg num if numRegs > 0 */ regno_t vregNO = 0; /* if no explicit regassing from IR, create move from param reg */ @@ -148,7 +161,8 @@ class LmbcFormalParamInfo { uint32 fpSize = 0; /* size of fp param if isPureFloat */ bool isReturn; bool isPureFloat = false; - bool isOnStack; /* small struct with arrays need to be saved onto stack */ + bool isOnStack; /* large struct is passed by a copy on stack */ + bool hasRegassign; }; } /* namespace maplebe */ diff --git a/src/mapleall/maple_be/include/cg/cg.h b/src/mapleall/maple_be/include/cg/cg.h index 093289e42b..e1368acb1d 100644 --- a/src/mapleall/maple_be/include/cg/cg.h +++ b/src/mapleall/maple_be/include/cg/cg.h @@ -121,11 +121,13 @@ class CG { emitter(nullptr), labelOrderCnt(0), cgOption(cgOptions), - instrumentationFunction(nullptr) { + instrumentationFunction(nullptr), + fileGP(nullptr) { const std::string &internalNameLiteral = namemangler::GetInternalNameLiteral(namemangler::kJavaLangObjectStr); GStrIdx strIdxFromName = GlobalTables::GetStrTable().GetStrIdxFromName(internalNameLiteral); isLibcore = (GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdxFromName) != nullptr); DefineDebugTraceFunctions(); + isLmbc = (mirModule->GetFlavor() == MIRFlavor::kFlavorLmbc); } virtual ~CG(); @@ -361,6 +363,10 @@ class CG { return isLibcore; } + bool IsLmbc() const { + return isLmbc; + } + MIRSymbol *GetDebugTraceEnterFunction() { return dbgTraceEnter; } @@ -421,6 +427,13 @@ class CG { /* Object map generation helper */ std::vector GetReferenceOffsets64(const BECommon &beCommon, MIRStructType &structType); + void SetGP(MIRSymbol *sym) { + fileGP = sym; + } + MIRSymbol *GetGP() const { + return fileGP; + } + static bool IsInFuncWrapLabels(MIRFunction *func) { return funcWrapLabels.find(func) != funcWrapLabels.end(); } @@ -449,12 +462,14 @@ class CG { LabelIDOrder labelOrderCnt; static CGFunc *currentCGFunction; /* current cg function being compiled */ CGOptions cgOption; - bool isLibcore; MIRSymbol *instrumentationFunction; MIRSymbol *dbgTraceEnter; MIRSymbol *dbgTraceExit; MIRSymbol *dbgFuncProfile; + MIRSymbol *fileGP; /* for lmbc, one local %GP per file */ static std::map> funcWrapLabels; + bool isLibcore; + bool isLmbc; }; /* class CG */ } /* namespace maplebe */ diff --git a/src/mapleall/maple_be/include/cg/cgfunc.h b/src/mapleall/maple_be/include/cg/cgfunc.h index 92a7d2ec96..bc0a48089e 100644 --- a/src/mapleall/maple_be/include/cg/cgfunc.h +++ b/src/mapleall/maple_be/include/cg/cgfunc.h @@ -160,6 +160,7 @@ class CGFunc { virtual uint32 FloatParamRegRequired(MIRStructType *structType, uint32 &fpSize) = 0; virtual void AssignLmbcFormalParams() = 0; LmbcFormalParamInfo *GetLmbcFormalParamInfo(uint32 offset); + virtual void LmbcGenSaveSpForAlloca() = 0; void GenerateLoc(StmtNode *stmt, unsigned &lastSrcLoc, unsigned &lastMplLoc); int32 GetFreqFromStmt(uint32 stmtId); void GenerateInstruction(); @@ -201,6 +202,7 @@ class CGFunc { virtual void SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd) = 0; virtual void SelectBlkassignoff(BlkassignoffNode &bNode, Operand *src) = 0; virtual void SelectAggIassign(IassignNode &stmt, Operand &lhsAddrOpnd) = 0; + virtual void SelectReturnSendOfStructInRegs(BaseNode *x) = 0; virtual void SelectReturn(Operand *opnd) = 0; virtual void SelectIgoto(Operand *opnd0) = 0; virtual void SelectCondGoto(CondGotoNode &stmt, Operand &opnd0, Operand &opnd1) = 0; diff --git a/src/mapleall/maple_be/src/be/lower.cpp b/src/mapleall/maple_be/src/be/lower.cpp index 4d2583a3e7..cd65e9fa29 100644 --- a/src/mapleall/maple_be/src/be/lower.cpp +++ b/src/mapleall/maple_be/src/be/lower.cpp @@ -121,6 +121,7 @@ void CGLowerer::RegisterExternalLibraryFunctions() { func->AllocSymTab(); MIRSymbol *funcSym = func->GetFuncSymbol(); funcSym->SetStorageClass(kScExtern); + funcSym->SetAppearsInCode(true); /* return type */ MIRType *retTy = GlobalTables::GetTypeTable().GetPrimType(extFnDescrs[i].retType); @@ -876,7 +877,7 @@ void CGLowerer::LowerTypePtr(BaseNode &node) const { #if TARGARM32 || TARGAARCH64 || TARGRISCV64 -BlockNode *CGLowerer::LowerReturnStruct(NaryStmtNode &retNode) { +BlockNode *CGLowerer::LowerReturnStructUsingFakeParm(NaryStmtNode &retNode) { BlockNode *blk = mirModule.CurFuncCodeMemPool()->New(); for (size_t i = 0; i < retNode.GetNopndSize(); ++i) { retNode.SetOpnd(LowerExpr(retNode, *retNode.GetNopndAt(i), *blk), i); @@ -1101,7 +1102,7 @@ void CGLowerer::LowerCallStmt(StmtNode &stmt, StmtNode *&nextStmt, BlockNode &ne return; } - if ((newStmt->GetOpCode() == OP_call) || (newStmt->GetOpCode() == OP_icall)) { + if (newStmt->GetOpCode() == OP_call || newStmt->GetOpCode() == OP_icall || newStmt->GetOpCode() == OP_icallproto) { newStmt = LowerCall(static_cast(*newStmt), nextStmt, newBlk, retty, uselvar); } newStmt->SetSrcPos(stmt.GetSrcPos()); @@ -1172,7 +1173,12 @@ StmtNode *CGLowerer::GenIntrinsiccallNode(const StmtNode &stmt, PUIdx &funcCalle StmtNode *CGLowerer::GenIcallNode(PUIdx &funcCalled, IcallNode &origCall) { StmtNode *newCall = nullptr; - newCall = mirModule.GetMIRBuilder()->CreateStmtIcall(origCall.GetNopnd()); + if (origCall.GetOpCode() == OP_icallassigned) { + newCall = mirModule.GetMIRBuilder()->CreateStmtIcall(origCall.GetNopnd()); + } else { + newCall = mirModule.GetMIRBuilder()->CreateStmtIcallproto(origCall.GetNopnd()); + static_cast(newCall)->SetRetTyIdx(static_cast(origCall).GetRetTyIdx()); + } newCall->SetSrcPos(origCall.GetSrcPos()); CHECK_FATAL(newCall != nullptr, "nullptr is not expected"); funcCalled = kFuncNotFound; @@ -1373,6 +1379,7 @@ BlockNode *CGLowerer::LowerCallAssignedStmt(StmtNode &stmt, bool uselvar) { static_cast(newCall)->SetReturnVec(*p2nRets); break; } + case OP_icallprotoassigned: case OP_icallassigned: { auto &origCall = static_cast(stmt); newCall = GenIcallNode(funcCalled, origCall); @@ -1480,6 +1487,15 @@ bool CGLowerer::LowerStructReturn(BlockNode &newBlk, StmtNode *stmt, (*p2nrets)[0].first = dnodeStmt->GetStIdx(); (*p2nrets)[0].second.SetFieldID(dnodeStmt->GetFieldID()); lvar = true; + // set ATTR_firstarg_return for callee + if (stmt->GetOpCode() == OP_callassigned) { + CallNode *callNode = static_cast(stmt); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callNode->GetPUIdx()); + f->SetFirstArgReturn(); + f->GetMIRFuncType()->SetFirstArgReturn(); + } else { + // for icall, front-end already set ATTR_firstarg_return + } } else { /* struct <= 16 passed in regs lowered into call &foo regassign u64 %1 (regread u64 %%retval0) @@ -1497,13 +1513,19 @@ bool CGLowerer::LowerStructReturn(BlockNode &newBlk, StmtNode *stmt, CallNode *callStmt = mirModule.GetMIRBuilder()->CreateStmtCall(callNode->GetPUIdx(), callNode->GetNopnd()); callStmt->SetSrcPos(callNode->GetSrcPos()); newBlk.AddStatement(callStmt); - } else if (stmt->GetOpCode() == OP_icallassigned) { + } else if (stmt->GetOpCode() == OP_icallassigned || stmt->GetOpCode() == OP_icallprotoassigned) { auto *icallNode = static_cast(stmt); for (size_t i = 0; i < icallNode->GetNopndSize(); ++i) { BaseNode *newOpnd = LowerExpr(*icallNode, *icallNode->GetNopndAt(i), newBlk); icallNode->SetOpnd(newOpnd, i); } - IcallNode *icallStmt = mirModule.GetMIRBuilder()->CreateStmtIcall(icallNode->GetNopnd()); + IcallNode *icallStmt = nullptr; + if (stmt->GetOpCode() == OP_icallassigned) { + icallStmt = mirModule.GetMIRBuilder()->CreateStmtIcall(icallNode->GetNopnd()); + } else { + icallStmt = mirModule.GetMIRBuilder()->CreateStmtIcallproto(icallNode->GetNopnd()); + icallStmt->SetRetTyIdx(icallNode->GetRetTyIdx()); + } icallStmt->SetSrcPos(icallNode->GetSrcPos()); newBlk.AddStatement(icallStmt); } else { @@ -1768,6 +1790,7 @@ void CGLowerer::LowerAssertBoundary(StmtNode &stmt, BlockNode &block, BlockNode CondGotoNode *brFalseNode = mirBuilder->CreateStmtCondGoto(cond, OP_brfalse, labIdx); MIRFunction *printf = mirBuilder->GetOrCreateFunction("printf", TyIdx(PTY_i32)); + printf->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*printf->GetMIRFuncType()); MapleVector argsPrintf(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); uint32 oldTypeTableSize = GlobalTables::GetTypeTable().GetTypeTableSize(); @@ -1843,7 +1866,8 @@ BlockNode *CGLowerer::LowerBlock(BlockNode &block) { break; } case OP_callassigned: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallprotoassigned: { // pass the addr of lvar if this is a struct call assignment bool lvar = false; // nextStmt could be changed by the call to LowerStructReturn @@ -1863,6 +1887,7 @@ BlockNode *CGLowerer::LowerBlock(BlockNode &block) { case OP_intrinsiccall: case OP_call: case OP_icall: + case OP_icallproto: #if TARGARM32 || TARGAARCH64 || TARGRISCV64 || TARGX86_64 // nextStmt could be changed by the call to LowerStructReturn LowerCallStmt(*stmt, nextStmt, *newBlk); @@ -1872,8 +1897,8 @@ BlockNode *CGLowerer::LowerBlock(BlockNode &block) { break; case OP_return: { #if TARGARM32 || TARGAARCH64 || TARGRISCV64 - if (GetCurrentFunc()->IsReturnStruct()) { - newBlk->AppendStatementsFromBlock(*LowerReturnStruct(static_cast(*stmt))); + if (GetCurrentFunc()->IsFirstArgReturn() && stmt->NumOpnds() > 0) { + newBlk->AppendStatementsFromBlock(*LowerReturnStructUsingFakeParm(static_cast(*stmt))); } else { #endif NaryStmtNode *retNode = static_cast(stmt); @@ -1971,7 +1996,9 @@ void CGLowerer::SimplifyBlock(BlockNode &block) { } auto *newFunc = theMIRModule->GetMIRBuilder()->GetOrCreateFunction(asmMap.at(oldFunc->GetName()), callStmt->GetTyIdx()); - newFunc->GetFuncSymbol()->SetStorageClass(kScExtern); + MIRSymbol *funcSym = newFunc->GetFuncSymbol(); + funcSym->SetStorageClass(kScExtern); + funcSym->SetAppearsInCode(true); callStmt->SetPUIdx(newFunc->GetPuidx()); break; } @@ -2081,6 +2108,7 @@ StmtNode *CGLowerer::LowerCall( if (needCheckStore) { MIRFunction *fn = mirModule.GetMIRBuilder()->GetOrCreateFunction("MCC_Reflect_Check_Arraystore", TyIdx(PTY_void)); + fn->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); MapleVector args(mirModule.GetMIRBuilder()->GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -2107,7 +2135,7 @@ StmtNode *CGLowerer::LowerCall( } MIRType *retType = nullptr; - if (callNode.op == OP_icall) { + if (callNode.op == OP_icall || callNode.op == OP_icallproto) { if (retTy == nullptr) { return &callNode; } else { @@ -2153,7 +2181,7 @@ StmtNode *CGLowerer::LowerCall( addrofNode->SetStIdx(dsgnSt->GetStIdx()); addrofNode->SetFieldID(0); - if (callNode.op == OP_icall) { + if (callNode.op == OP_icall || callNode.op == OP_icallproto) { auto ond = callNode.GetNopnd().begin(); newNopnd.emplace_back(*ond); newNopnd.emplace_back(addrofNode); @@ -2175,7 +2203,27 @@ StmtNode *CGLowerer::LowerCall( } void CGLowerer::LowerEntry(MIRFunction &func) { + // determine if needed to insert fake parameter to return struct for current function if (func.IsReturnStruct()) { + MIRType *retType = func.GetReturnType(); +#if TARGAARCH64 + PrimType pty = IsStructElementSame(retType); + if (pty == PTY_f32 || pty == PTY_f64 || IsPrimitiveVector(pty)) { + func.SetStructReturnedInRegs(); + return; + } +#endif + if (retType->GetPrimType() != PTY_agg) { + return; + } + if (retType->GetSize() > k16ByteSize) { + func.SetFirstArgReturn(); + func.GetMIRFuncType()->SetFirstArgReturn(); + } else { + func.SetStructReturnedInRegs(); + } + } + if (func.IsFirstArgReturn() && func.GetReturnType()->GetPrimType() != PTY_void) { MIRSymbol *retSt = func.GetSymTab()->CreateSymbol(kScopeLocal); retSt->SetStorageClass(kScFormal); retSt->SetSKind(kStVar); @@ -2192,12 +2240,14 @@ void CGLowerer::LowerEntry(MIRFunction &func) { auto formal = func.GetFormal(i); formals.emplace_back(formal); } + func.SetFirstArgReturn(); beCommon.AddElementToFuncReturnType(func, func.GetReturnTyIdx()); func.UpdateFuncTypeAndFormalsAndReturnType(formals, TyIdx(PTY_void), true); auto *funcType = func.GetMIRFuncType(); ASSERT(funcType != nullptr, "null ptr check"); + funcType->SetFirstArgReturn(); beCommon.AddTypeSizeAndAlign(funcType->GetTypeIndex(), GetPrimTypeSize(funcType->GetPrimType())); } } @@ -2375,6 +2425,7 @@ MIRFunction *CGLowerer::RegisterFunctionVoidStarToVoid(BuiltinFunctionID id, con func->AllocSymTab(); MIRSymbol *funcSym = func->GetFuncSymbol(); funcSym->SetStorageClass(kScExtern); + funcSym->SetAppearsInCode(true); MIRType *argTy = GlobalTables::GetTypeTable().GetPtr(); MIRSymbol *argSt = func->GetSymTab()->CreateSymbol(kScopeLocal); argSt->SetNameStrIdx(mirBuilder->GetOrCreateStringIndex(paramName)); @@ -2416,6 +2467,7 @@ void CGLowerer::RegisterBuiltIns() { func->AllocSymTab(); MIRSymbol *funcSym = func->GetFuncSymbol(); funcSym->SetStorageClass(kScExtern); + funcSym->SetAppearsInCode(true); /* return type */ MIRType *retTy = desc.GetReturnType(); CHECK_FATAL(retTy != nullptr, "retTy should not be nullptr"); @@ -2571,6 +2623,7 @@ void CGLowerer::ProcessArrayExpr(BaseNode &expr, BlockNode &blkNode) { arrayNode.GetNopndAt(1), lenRegreadNode); CondGotoNode *brFalseNode = mirBuilder->CreateStmtCondGoto(cond, OP_brfalse, labIdx); MIRFunction *fn = mirBuilder->GetOrCreateFunction("MCC_Array_Boundary_Check", TyIdx(PTY_void)); + fn->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); MapleVector args(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -3102,6 +3155,7 @@ BaseNode *CGLowerer::LowerIntrinJavaArrayLength(const BaseNode &parent, Intrinsi MIRFunction *newFunc = mirBuilder->GetOrCreateFunction("MCC_ThrowNullArrayNullPointerException", GlobalTables::GetTypeTable().GetVoid()->GetTypeIndex()); + newFunc->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*newFunc->GetMIRFuncType()); newFunc->AllocSymTab(); MapleVector args(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -3473,6 +3527,7 @@ StmtNode *CGLowerer::LowerIntrinsicRCCall(const IntrinsiccallNode &intrincall) { if (intrinFuncIDs.find(intrinDesc) == intrinFuncIDs.end()) { /* add funcid into map */ MIRFunction *fn = mirBuilder->GetOrCreateFunction(intrinDesc->name, TyIdx(PTY_void)); + fn->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); intrinFuncIDs[intrinDesc] = fn->GetPuidx(); @@ -3501,6 +3556,7 @@ void CGLowerer::LowerArrayStore(const IntrinsiccallNode &intrincall, BlockNode & if (needCheckStore) { MIRFunction *fn = mirBuilder->GetOrCreateFunction("MCC_Reflect_Check_Arraystore", TyIdx(PTY_void)); + fn->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); MapleVector args(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -3590,6 +3646,7 @@ StmtNode *CGLowerer::LowerIntrinsiccall(IntrinsiccallNode &intrincall, BlockNode beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); st->SetFunction(fn); + st->SetAppearsInCode(true); return LowerDefaultIntrinsicCall(intrincall, *st, *fn); } @@ -3660,6 +3717,7 @@ PUIdx CGLowerer::GetBuiltinToUse(BuiltinFunctionID id) const { void CGLowerer::LowerGCMalloc(const BaseNode &node, const GCMallocNode &gcmalloc, BlockNode &blkNode, bool perm) { MIRFunction *func = mirBuilder->GetOrCreateFunction((perm ? "MCC_NewPermanentObject" : "MCC_NewObj_fixed_class"), (TyIdx)(LOWERED_PTR_TYPE)); + func->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*func->GetMIRFuncType()); func->AllocSymTab(); /* Get the classinfo */ @@ -3678,6 +3736,7 @@ void CGLowerer::LowerGCMalloc(const BaseNode &node, const GCMallocNode &gcmalloc if (classSym->GetAttr(ATTR_abstract) || classSym->GetAttr(ATTR_interface)) { MIRFunction *funcSecond = mirBuilder->GetOrCreateFunction("MCC_Reflect_ThrowInstantiationError", (TyIdx)(LOWERED_PTR_TYPE)); + funcSecond->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*funcSecond->GetMIRFuncType()); funcSecond->AllocSymTab(); BaseNode *arg = mirBuilder->CreateExprAddrof(0, *classSym); @@ -3796,6 +3855,7 @@ void CGLowerer::LowerJarrayMalloc(const StmtNode &stmt, const JarrayMallocNode & args.emplace_back(mirBuilder->CreateIntConst(0, PTY_u32)); } MIRFunction *func = mirBuilder->GetOrCreateFunction(funcName, (TyIdx)(LOWERED_PTR_TYPE)); + func->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*func->GetMIRFuncType()); func->AllocSymTab(); CallNode *callAssign = nullptr; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index ab075eb06f..7962d54991 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -38,7 +38,7 @@ void AArch64MoveRegArgs::CollectRegisterArgs(std::map &argsL uint32 start = 0; if (numFormal) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsReturnStruct()) { + if (func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16ByteSize) { start = 1; @@ -436,7 +436,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsReturnStruct()) { + if (func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp index 302e369fa5..b584778b3a 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp @@ -300,7 +300,7 @@ int32 AArch64CallConvImpl::LocateNextParm(MIRType &mirType, CCLocInfo &pLoc, boo if (isFirst) { MIRFunction *func = tFunc != nullptr ? tFunc : const_cast(beCommon.GetMIRModule().CurFunction()); - if (func->IsReturnStruct()) { + if (func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); size_t size = beCommon.GetTypeSize(tyIdx); if (size == 0) { 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 ece8641e4a..e1c70562ba 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -1411,15 +1411,44 @@ void AArch64CGFunc::SelectAsm(AsmNode &node) { } void AArch64CGFunc::SelectRegassign(RegassignNode &stmt, Operand &opnd0) { + if (GetCG()->IsLmbc()) { + PrimType lhsSize = stmt.GetPrimType(); + PrimType rhsSize = stmt.Opnd(0)->GetPrimType(); + if (lhsSize != rhsSize && stmt.Opnd(0)->GetOpCode() == OP_ireadoff) { + Insn *prev = GetCurBB()->GetLastInsn(); + if (prev->GetMachineOpcode() == MOP_wldrsb || prev->GetMachineOpcode() == MOP_wldrsh) { + opnd0.SetSize(GetPrimTypeBitSize(stmt.GetPrimType())); + prev->SetMOP(prev->GetMachineOpcode() == MOP_wldrsb ? MOP_xldrsb : MOP_xldrsh); + } else if (prev->GetMachineOpcode() == MOP_wldr && stmt.GetPrimType() == PTY_i64) { + opnd0.SetSize(GetPrimTypeBitSize(stmt.GetPrimType())); + prev->SetMOP(MOP_xldrsw); + } + } + } RegOperand *regOpnd = nullptr; PregIdx pregIdx = stmt.GetRegIdx(); if (IsSpecialPseudoRegister(pregIdx)) { - regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, stmt.GetPrimType()); + if (GetCG()->IsLmbc() && stmt.GetPrimType() == PTY_agg) { + if (static_cast(opnd0).IsOfIntClass()) { + regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, PTY_i64); + } else if (opnd0.GetSize() <= k4ByteSize) { + regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, PTY_f32); + } else { + regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, PTY_f64); + } + } else { + regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, stmt.GetPrimType()); + } } else { regOpnd = &GetOrCreateVirtualRegisterOperand(GetVirtualRegNOFromPseudoRegIdx(pregIdx)); } /* look at rhs */ PrimType rhsType = stmt.Opnd(0)->GetPrimType(); + if (GetCG()->IsLmbc() && rhsType == PTY_agg) { + /* This occurs when a call returns a small struct */ + /* The subtree should already taken care of the agg type that is in excess of 8 bytes */ + rhsType = PTY_i64; + } PrimType dtype = rhsType; if (GetPrimTypeBitSize(dtype) < k32BitSize) { ASSERT(IsPrimitiveInteger(dtype), ""); @@ -1441,6 +1470,12 @@ void AArch64CGFunc::SelectRegassign(RegassignNode &stmt, Operand &opnd0) { MIRPreg *preg = GetFunction().GetPregTab()->PregFromPregIdx(pregIdx); uint32 srcBitLength = GetPrimTypeSize(preg->GetPrimType()) * kBitsPerByte; GetCurBB()->AppendInsn(GetCG()->BuildInstruction(PickStInsn(srcBitLength, stype), *regOpnd, *dest)); + } else if (regOpnd->GetRegisterNumber() == R0 || regOpnd->GetRegisterNumber() == R1) { + Insn &pseudo = GetCG()->BuildInstruction(MOP_pseudo_ret_int, *regOpnd); + GetCurBB()->AppendInsn(pseudo); + } else if (regOpnd->GetRegisterNumber() >= V0 && regOpnd->GetRegisterNumber() <= V3) { + Insn &pseudo = GetCG()->BuildInstruction(MOP_pseudo_ret_float, *regOpnd); + GetCurBB()->AppendInsn(pseudo); } } @@ -1922,15 +1957,11 @@ void AArch64CGFunc::SelectIassignoff(IassignoffNode &stmt) { SelectCopy(memOpnd, destType, srcOpnd, destType); } -void AArch64CGFunc::SelectIassignfpoff(IassignFPoffNode &stmt, Operand &opnd) { - int32 offset = stmt.GetOffset(); - PrimType primType = stmt.GetPrimType(); - uint32 bitlen = GetPrimTypeSize(primType) * kBitsPerByte; - - Operand &srcOpnd = LoadIntoRegister(opnd, primType); +MemOperand *AArch64CGFunc::GenLmbcFpMemOperand(int32 offset, uint32 byteSize, AArch64reg baseRegno) { MemOperand *memOpnd; - RegOperand *rfp = &GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); - if (offset < 0) { + RegOperand *rfp = &GetOrCreatePhysicalRegisterOperand(baseRegno, k64BitSize, kRegTyInt); + uint32 bitlen = byteSize * kBitsPerByte; + if (offset < 0 && offset < -256) { RegOperand *baseOpnd = &CreateRegisterOperandOfType(PTY_a64); ImmOperand &immOpnd = CreateImmOperand(offset, k32BitSize, true); Insn &addInsn = GetCG()->BuildInstruction(MOP_xaddrri12, *baseOpnd, *rfp, immOpnd); @@ -1942,11 +1973,45 @@ void AArch64CGFunc::SelectIassignfpoff(IassignFPoffNode &stmt, Operand &opnd) { memOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, bitlen, rfp, nullptr, offsetOpnd, nullptr); } memOpnd->SetStackMem(true); - MOperator mOp = PickStInsn(bitlen, primType); - Insn &store = GetCG()->BuildInstruction(mOp, srcOpnd, *memOpnd); - GetCurBB()->AppendInsn(store); + return memOpnd; } +void AArch64CGFunc::SelectIassignfpoff(IassignFPoffNode &stmt, Operand &opnd) { + int32 offset = stmt.GetOffset(); + PrimType primType = stmt.GetPrimType(); + MIRType *rType = GetLmbcCallReturnType(); + bool isPureFpStruct = false; + uint32 numRegs = 0; + if (rType && rType->GetPrimType() == PTY_agg && opnd.IsRegister() && static_cast(opnd).IsPhysicalRegister()) { + CHECK_FATAL(rType->GetSize() <= 16, "SelectIassignfpoff invalid agg size"); + uint32 fpSize; + numRegs = FloatParamRegRequired(static_cast(rType), fpSize); + if (numRegs) { + primType = (fpSize == k4ByteSize) ? PTY_f32 : PTY_f64; + isPureFpStruct = true; + } + } + uint32 byteSize = GetPrimTypeSize(primType); + uint32 bitlen = byteSize * kBitsPerByte; + if (isPureFpStruct) { + for (int i = 0 ; i < numRegs; ++i) { + MemOperand *memOpnd = GenLmbcFpMemOperand(offset + (i * byteSize), byteSize); + RegOperand &srcOpnd = GetOrCreatePhysicalRegisterOperand(AArch64reg(V0 + i), bitlen, kRegTyFloat); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, srcOpnd, *memOpnd); + GetCurBB()->AppendInsn(store); + } + } else { + Operand &srcOpnd = LoadIntoRegister(opnd, primType); + MemOperand *memOpnd = GenLmbcFpMemOperand(offset, byteSize); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, srcOpnd, *memOpnd); + GetCurBB()->AppendInsn(store); + } +} + +/* Load and assign to a new register. To be moved to the correct call register OR stack + location in LmbcSelectParmList */ void AArch64CGFunc::SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd) { if (GetLmbcArgInfo() == nullptr) { LmbcArgInfo *p = memPool->New(*GetFuncScopeAllocator()); @@ -1973,7 +2038,7 @@ void AArch64CGFunc::SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd } /* Search for CALL/ICALL/ICALLPROTO node, must be called from a blkassignoff node */ -MIRType *AArch64CGFunc::GetAggTyFromCallSite(StmtNode *stmt) { +MIRType *AArch64CGFunc::LmbcGetAggTyFromCallSite(StmtNode *stmt, std::vector **parmList) { for ( ; stmt != nullptr; stmt = stmt->GetNext()) { if (stmt->GetOpCode() == OP_call || stmt->GetOpCode() == OP_icallproto) { break; @@ -1986,25 +2051,20 @@ MIRType *AArch64CGFunc::GetAggTyFromCallSite(StmtNode *stmt) { if (stmt->GetOpCode() == OP_call) { CallNode *callNode = static_cast(stmt); MIRFunction *fn = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callNode->GetPUIdx()); - if (fn->IsReturnStruct()) { - ++nargs; - } if (fn->GetFormalCount() > 0) { - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fn->GetNthParamTyIdx(nargs)); + ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fn->GetFormalDefVec()[nargs].formalTyIdx); } + *parmList = &fn->GetParamTypes(); // would return null if the actual parameter is bogus } else if (stmt->GetOpCode() == OP_icallproto) { IcallNode *icallproto = static_cast(stmt); MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallproto->GetRetTyIdx()); MIRFuncType *fType = static_cast(type); - MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fType->GetRetTyIdx()); - if (retType->GetKind() == kTypeStruct) { - ++nargs; - } ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fType->GetNthParamType(nargs)); + *parmList = &fType->GetParamTypeList(); } else { CHECK_FATAL(stmt->GetOpCode() == OP_icallproto, - "GetAggTyFromCallSite:: unexpected call operator"); + "LmbcGetAggTyFromCallSite:: unexpected call operator"); } return ty; } @@ -2081,11 +2141,11 @@ bool AArch64CGFunc::LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *s } /* return true if blkassignoff for return, false otherwise */ -bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src) { +bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList) { AArch64reg regno = static_cast(static_cast(src)->GetRegisterNumber()); if (IsBlkassignForPush(bNode)) { PrimType pTy = PTY_i64; - MIRStructType *ty = static_cast(GetAggTyFromCallSite(&bNode)); + MIRStructType *ty = static_cast(LmbcGetAggTyFromCallSite(&bNode, parmList)); uint32 size = 0; uint32 fpregs = ty ? FloatParamRegRequired(ty, size) : 0; /* fp size determined */ if (fpregs > 0) { @@ -2096,7 +2156,7 @@ bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src) { MemOperand &mem = CreateMemOpnd(regno, s, size * kBitsPerByte); RegOperand *res = &CreateVirtualRegisterOperand(NewVReg(kRegTyFloat, size)); SelectCopy(*res, pTy, mem, pTy); - SetLmbcArgInfo(res, pTy, bNode.offset + s, fpregs); + SetLmbcArgInfo(res, pTy, 0, fpregs); IncLmbcArgsInRegs(kRegTyFloat); } IncLmbcTotalArgs(); @@ -2137,6 +2197,41 @@ bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src) { return false; } +/* This function is incomplete and may be removed when Lmbc IR is changed + to have the lowerer figures out the address of the large agg to reside */ +uint32 AArch64CGFunc::LmbcFindTotalStkUsed(std::vector *paramList) { + AArch64CallConvImpl parmlocator(GetBecommon()); + CCLocInfo pLoc; + for (TyIdx tyIdx : *paramList) { + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); + parmlocator.LocateNextParm(*ty, pLoc); + } + return 0; +} + +/* All arguments passed as registers */ +uint32 AArch64CGFunc::LmbcTotalRegsUsed() { + if (GetLmbcArgInfo() == nullptr) { + return 0; /* no arg */ + } + MapleVector ®s = GetLmbcCallArgNumOfRegs(); + MapleVector &types = GetLmbcCallArgTypes(); + uint32 iCnt = 0; + uint32 fCnt = 0; + for (uint32 i = 0; i < regs.size(); i++) { + if (IsPrimitiveInteger(types[i])) { + if ((iCnt + regs[i]) <= k8ByteSize) { + iCnt += regs[i]; + }; + } else { + if ((fCnt + regs[i]) <= k8ByteSize) { + fCnt += regs[i]; + }; + } + } + return iCnt + fCnt; +} + /* If blkassignoff for argument, this function loads the agg arguments into virtual registers, disregard if there is sufficient physicall call registers. Argument > 16-bytes are copied to preset space and ptr @@ -2145,29 +2240,40 @@ bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src) { void AArch64CGFunc::SelectBlkassignoff(BlkassignoffNode &bNode, Operand *src) { CHECK_FATAL(src->GetKind() == Operand::kOpdRegister, "blkassign src type not in register"); + std::vector *parmList; if (GetLmbcArgInfo() == nullptr) { LmbcArgInfo *p = memPool->New(*GetFuncScopeAllocator()); SetLmbcArgInfo(p); } if (LmbcSmallAggForRet(bNode, src)) { return; - } else if (LmbcSmallAggForCall(bNode, src)) { + } else if (LmbcSmallAggForCall(bNode, src, &parmList)) { return; } - /* memcpy for agg assign OR large agg for arg/ret */ Operand *dest = HandleExpr(bNode, *bNode.Opnd(0)); RegOperand *regResult = &CreateVirtualRegisterOperand(NewVReg(kRegTyInt, k8ByteSize)); + /* memcpy for agg assign OR large agg for arg/ret */ + int32 offset = bNode.offset; + if (IsBlkassignForPush(bNode)) { + /* large agg for call, addr to be pushed in SelectCall */ + offset = GetLmbcTotalStkUsed(); + if (offset < 0) { + /* length of ALL stack based args for this call, this location is where the + next large agg resides, its addr will then be passed */ + offset = LmbcFindTotalStkUsed(parmList) + LmbcTotalRegsUsed(); + } + SetLmbcTotalStkUsed(offset + bNode.blockSize); /* next use */ + SetLmbcArgInfo(regResult, PTY_i64, 0, 1); /* 1 reg for ptr */ + IncLmbcArgsInRegs(kRegTyInt); + IncLmbcTotalArgs(); + /* copy large agg arg to offset below */ + } std::vector opndVec; opndVec.push_back(regResult); /* result */ - opndVec.push_back(PrepareMemcpyParamOpnd(bNode.offset, *dest));/* param 0 */ + opndVec.push_back(PrepareMemcpyParamOpnd(offset, *dest)); /* param 0 */ opndVec.push_back(src); /* param 1 */ opndVec.push_back(PrepareMemcpyParamOpnd(bNode.blockSize));/* param 2 */ SelectLibCall("memcpy", opndVec, PTY_a64, PTY_a64); - if (IsBlkassignForPush(bNode)) { - SetLmbcArgInfo(static_cast(src), PTY_i64, (int32)bNode.offset, 1); - IncLmbcArgsInRegs(kRegTyInt); - IncLmbcTotalArgs(); - } } void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { @@ -2554,6 +2660,159 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { } } +void AArch64CGFunc::SelectReturnSendOfStructInRegs(BaseNode *x) { + uint32 offset = 0; + if (x->GetOpCode() == OP_dread) { + DreadNode *dread = static_cast(x); + MIRSymbol *sym = GetFunction().GetLocalOrGlobalSymbol(dread->GetStIdx()); + MIRType *mirType = sym->GetType(); + if (dread->GetFieldID() != 0) { + MIRStructType *structType = static_cast(mirType); + mirType = structType->GetFieldType(dread->GetFieldID()); + offset = static_cast(GetBecommon().GetFieldOffset(*structType, dread->GetFieldID()).first); + } + uint32 typeSize = GetBecommon().GetTypeSize(mirType->GetTypeIndex()); + /* generate move to regs for agg return */ + AArch64CallConvImpl parmlocator(GetBecommon()); + CCLocInfo pLoc; + parmlocator.LocateNextParm(*mirType, pLoc, true, GetBecommon().GetMIRModule().CurFunction()); + /* aggregates are 8 byte aligned. */ + Operand *rhsmemopnd = nullptr; + RegOperand *result[kFourRegister]; /* up to 2 int or 4 fp */ + uint32 loadSize; + uint32 numRegs; + RegType regType; + PrimType retPty; + bool fpParm = false; + if (pLoc.numFpPureRegs) { + loadSize = pLoc.fpSize; + numRegs = pLoc.numFpPureRegs; + fpParm = true; + regType = kRegTyFloat; + retPty = (pLoc.fpSize == k4ByteSize) ? PTY_f32 : PTY_f64; + } else { + if (CGOptions::IsBigEndian()) { + loadSize = k8ByteSize; + numRegs = (typeSize <= k8ByteSize) ? kOneRegister : kTwoRegister; + regType = kRegTyInt; + retPty = PTY_u64; + } else { + loadSize = (typeSize <= k4ByteSize) ? k4ByteSize : k8ByteSize; + numRegs = (typeSize <= k8ByteSize) ? kOneRegister : kTwoRegister; + regType = kRegTyInt; + retPty = PTY_u32; + } + } + bool parmCopy = IsParamStructCopy(*sym); + for (uint32 i = 0; i < numRegs; i++) { + if (parmCopy) { + rhsmemopnd = &LoadStructCopyBase(*sym, + (offset + static_cast(i * (fpParm ? loadSize : k8ByteSize))), + static_cast(loadSize * kBitsPerByte)); + } else { + rhsmemopnd = &GetOrCreateMemOpnd(*sym, + (offset + static_cast(i * (fpParm ? loadSize : k8ByteSize))), + (loadSize * kBitsPerByte)); + } + result[i] = &CreateVirtualRegisterOperand(NewVReg(regType, loadSize)); + MOperator mop1 = PickLdInsn(loadSize * kBitsPerByte, retPty); + Insn &ld = GetCG()->BuildInstruction(mop1, *(result[i]), *rhsmemopnd); + GetCurBB()->AppendInsn(ld); + } + AArch64reg regs[kFourRegister]; + regs[0] = static_cast(pLoc.reg0); + regs[1] = static_cast(pLoc.reg1); + regs[2] = static_cast(pLoc.reg2); + regs[3] = static_cast(pLoc.reg3); + RegOperand *dest; + for (uint32 i = 0; i < numRegs; i++) { + AArch64reg preg; + MOperator mop2; + if (fpParm) { + preg = regs[i]; + mop2 = (loadSize == k4ByteSize) ? MOP_xvmovs : MOP_xvmovd; + } else { + preg = (i == 0 ? R0 : R1); + mop2 = (loadSize == k4ByteSize) ? MOP_wmovrr : MOP_xmovrr; + } + dest = &GetOrCreatePhysicalRegisterOperand(preg, (loadSize * kBitsPerByte), regType); + Insn &mov = GetCG()->BuildInstruction(mop2, *dest, *(result[i])); + GetCurBB()->AppendInsn(mov); + } + /* Create artificial dependency to extend the live range */ + for (uint32 i = 0; i < numRegs; i++) { + AArch64reg preg; + MOperator mop3; + if (fpParm) { + preg = regs[i]; + mop3 = MOP_pseudo_ret_float; + } else { + preg = (i == 0 ? R0 : R1); + mop3 = MOP_pseudo_ret_int; + } + dest = &GetOrCreatePhysicalRegisterOperand(preg, loadSize * kBitsPerByte, regType); + Insn &pseudo = GetCG()->BuildInstruction(mop3, *dest); + GetCurBB()->AppendInsn(pseudo); + } + return; + } else if (x->GetOpCode() == OP_iread) { + IreadNode *iread = static_cast(x); + RegOperand *rhsAddrOpnd = static_cast(HandleExpr(*iread, *iread->Opnd(0))); + rhsAddrOpnd = &LoadIntoRegister(*rhsAddrOpnd, iread->Opnd(0)->GetPrimType()); + MIRPtrType *ptrType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread->GetTyIdx())); + MIRType *mirType = static_cast(ptrType->GetPointedType()); + bool isRefField = false; + if (iread->GetFieldID() != 0) { + MIRStructType *structType = static_cast(mirType); + mirType = structType->GetFieldType(iread->GetFieldID()); + offset = static_cast(GetBecommon().GetFieldOffset(*structType, iread->GetFieldID()).first); + isRefField = GetBecommon().IsRefField(*structType, iread->GetFieldID()); + } + uint32 typeSize = GetBecommon().GetTypeSize(mirType->GetTypeIndex()); + /* generate move to regs. */ + RegOperand *result[kTwoRegister]; /* maximum 16 bytes, 2 registers */ + uint32 loadSize; + if (CGOptions::IsBigEndian()) { + loadSize = k8ByteSize; + } else { + loadSize = (typeSize <= k4ByteSize) ? k4ByteSize : k8ByteSize; + } + uint32 numRegs = (typeSize <= k8ByteSize) ? kOneRegister : kTwoRegister; + for (uint32 i = 0; i < numRegs; i++) { + OfstOperand *rhsOffOpnd = &GetOrCreateOfstOpnd(offset + i * loadSize, loadSize * kBitsPerByte); + Operand &rhsmemopnd = GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, loadSize * kBitsPerByte, + rhsAddrOpnd, nullptr, rhsOffOpnd, nullptr); + result[i] = &CreateVirtualRegisterOperand(NewVReg(kRegTyInt, loadSize)); + MOperator mop1 = PickLdInsn(loadSize * kBitsPerByte, PTY_u32); + Insn &ld = GetCG()->BuildInstruction(mop1, *(result[i]), rhsmemopnd); + ld.MarkAsAccessRefField(isRefField); + GetCurBB()->AppendInsn(ld); + } + RegOperand *dest; + for (uint32 i = 0; i < numRegs; i++) { + AArch64reg preg = (i == 0 ? R0 : R1); + dest = &GetOrCreatePhysicalRegisterOperand(preg, loadSize * kBitsPerByte, kRegTyInt); + Insn &mov = GetCG()->BuildInstruction(MOP_xmovrr, *dest, *(result[i])); + GetCurBB()->AppendInsn(mov); + } + /* Create artificial dependency to extend the live range */ + for (uint32 i = 0; i < numRegs; i++) { + AArch64reg preg = (i == 0 ? R0 : R1); + dest = &GetOrCreatePhysicalRegisterOperand(preg, loadSize * kBitsPerByte, kRegTyInt); + Insn &pseudo = cg->BuildInstruction(MOP_pseudo_ret_int, *dest); + GetCurBB()->AppendInsn(pseudo); + } + return; + } else { // dummy return of 0 inserted by front-end at absence of return + ASSERT(x->GetOpCode() == OP_constval, "SelectReturnSendOfStructInRegs: unexpected return operand"); + uint32 typeSize = GetPrimTypeSize(x->GetPrimType()); + RegOperand &dest = GetOrCreatePhysicalRegisterOperand(R0, typeSize * kBitsPerByte, kRegTyInt); + ImmOperand &src = CreateImmOperand(0, k16BitSize, false); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_xmovri32, dest, src)); + return; + } +} + Operand *AArch64CGFunc::SelectDread(const BaseNode &parent, DreadNode &expr) { MIRSymbol *symbol = GetFunction().GetLocalOrGlobalSymbol(expr.GetStIdx()); if (symbol->IsEhIndex()) { @@ -2917,31 +3176,50 @@ Operand *AArch64CGFunc::SelectIreadoff(const BaseNode &parent, IreadoffNode &ire return result; } -RegOperand *AArch64CGFunc::GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType) { - MemOperand *memOpnd; - RegOperand *rfp = &GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); - uint32 bitlen = byteSize * kBitsPerByte; - if (offset < 0) { - RegOperand *baseOpnd = &CreateRegisterOperandOfType(PTY_a64); - ImmOperand &immOpnd = CreateImmOperand(offset, k32BitSize, true); - Insn &addInsn = GetCG()->BuildInstruction(MOP_xaddrri12, *baseOpnd, *rfp, immOpnd); - GetCurBB()->AppendInsn(addInsn); - OfstOperand *offsetOpnd = &CreateOfstOpnd(0, k32BitSize); - memOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, bitlen, baseOpnd, - nullptr, offsetOpnd, nullptr); - } else { - OfstOperand *offsetOpnd = &CreateOfstOpnd(offset, k32BitSize); - memOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, bitlen, rfp, - nullptr, offsetOpnd, nullptr); - } - memOpnd->SetStackMem(true); +RegOperand *AArch64CGFunc::GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType, + AArch64reg baseRegno) { + MemOperand *memOpnd = GenLmbcFpMemOperand(offset, byteSize, baseRegno); RegOperand *result = &GetOrCreateVirtualRegisterOperand(NewVReg(regType, byteSize)); - MOperator mOp = PickLdInsn(bitlen, primType); + MOperator mOp = PickLdInsn(byteSize * kBitsPerByte, primType); Insn &load = GetCG()->BuildInstruction(mOp, *result, *memOpnd); GetCurBB()->AppendInsn(load); return result; } +RegOperand *AArch64CGFunc::LmbcStructReturnLoad(int32 offset) { + RegOperand *result = nullptr; + MIRFunction &func = GetFunction(); + CHECK_FATAL(func.IsReturnStruct(), "LmbcStructReturnLoad: not struct return"); + MIRType *ty = func.GetReturnType(); + uint32 sz = GetBecommon().GetTypeSize(ty->GetTypeIndex()); + uint32 fpSize; + uint32 numFpRegs = FloatParamRegRequired(static_cast(ty), fpSize); + if (numFpRegs > 0) { + PrimType pType = (fpSize <= k4ByteSize) ? PTY_f32 : PTY_f64; + for (int32 i = (numFpRegs - kOneRegister); i > 0; --i) { + result = GenLmbcParamLoad(offset + (i * fpSize), fpSize, kRegTyFloat, pType); + AArch64reg regNo = static_cast(V0 + i); + RegOperand *reg = &GetOrCreatePhysicalRegisterOperand(regNo, fpSize * kBitsPerByte, kRegTyFloat); + SelectCopy(*reg, pType, *result, pType); + Insn &pseudo = GetCG()->BuildInstruction(MOP_pseudo_ret_float, *reg); + GetCurBB()->AppendInsn(pseudo); + } + result = GenLmbcParamLoad(offset, fpSize, kRegTyFloat, pType); + } else if (sz <= k4ByteSize) { + result = GenLmbcParamLoad(offset, k4ByteSize, kRegTyInt, PTY_u32); + } else if (sz <= k8ByteSize) { + result = GenLmbcParamLoad(offset, k8ByteSize, kRegTyInt, PTY_i64); + } else if (sz <= k16ByteSize) { + result = GenLmbcParamLoad(offset + k8ByteSize, k8ByteSize, kRegTyInt, PTY_i64); + RegOperand *r1 = &GetOrCreatePhysicalRegisterOperand(R1, k8ByteSize * kBitsPerByte, kRegTyInt); + SelectCopy(*r1, PTY_i64, *result, PTY_i64); + Insn &pseudo = GetCG()->BuildInstruction(MOP_pseudo_ret_int, *r1); + GetCurBB()->AppendInsn(pseudo); + result = GenLmbcParamLoad(offset, k8ByteSize, kRegTyInt, PTY_i64); + } + return result; +} + Operand *AArch64CGFunc::SelectIreadfpoff(const BaseNode &parent, IreadFPoffNode &ireadoff) { int32 offset = ireadoff.GetOffset(); PrimType primType = ireadoff.GetPrimType(); @@ -2952,19 +3230,32 @@ Operand *AArch64CGFunc::SelectIreadfpoff(const BaseNode &parent, IreadFPoffNode if (offset >= 0) { LmbcFormalParamInfo *info = GetLmbcFormalParamInfo(offset); if (info->GetPrimType() == PTY_agg) { - result = GenLmbcParamLoad(offset, bytelen, regty, primType); + if (info->IsOnStack()) { + result = GenLmbcParamLoad(info->GetOnStackOffset(), GetPrimTypeSize(PTY_a64), kRegTyInt, PTY_a64); + regno_t baseRegno = result->GetRegisterNumber(); + result = GenLmbcParamLoad(offset - info->GetOffset(), bytelen, regty, primType, (AArch64reg)baseRegno); + } else if (primType == PTY_agg) { + CHECK_FATAL(parent.GetOpCode() == OP_regassign, "SelectIreadfpoff of agg"); + result = LmbcStructReturnLoad(offset); + } else { + result = GenLmbcParamLoad(offset, bytelen, regty, primType); + } } else { CHECK_FATAL(primType == info->GetPrimType(), "Incorrect primtype"); CHECK_FATAL(offset == info->GetOffset(), "Incorrect offset"); - if (info->GetRegNO() == 0) { - /* TODO : follow lmbc sp offset for now */ + if (info->GetRegNO() == 0 || info->HasRegassign() == false) { result = GenLmbcParamLoad(offset, bytelen, regty, primType); } else { result = &GetOrCreatePhysicalRegisterOperand((AArch64reg)(info->GetRegNO()), bitlen, regty); } } } else { - result = GenLmbcParamLoad(offset, bytelen, regty, primType); + if (primType == PTY_agg) { + CHECK_FATAL(parent.GetOpCode() == OP_regassign, "SelectIreadfpoff of agg"); + result = LmbcStructReturnLoad(offset); + } else { + result = GenLmbcParamLoad(offset, bytelen, regty, primType); + } } return result; } @@ -5761,6 +6052,9 @@ Operand *AArch64CGFunc::SelectAlloca(UnaryNode &node, Operand &opnd0) { if (!CGOptions::IsArm64ilp32()) { ASSERT((node.GetPrimType() == PTY_a64), "wrong type"); } + if (GetCG()->IsLmbc()) { + SetHasVLAOrAlloca(true); + } PrimType stype = node.Opnd(0)->GetPrimType(); Operand *resOpnd = &opnd0; if (GetPrimTypeBitSize(stype) < GetPrimTypeBitSize(PTY_u64)) { @@ -5776,10 +6070,13 @@ Operand *AArch64CGFunc::SelectAlloca(UnaryNode &node, Operand &opnd0) { SelectShift(aliOp, aliOp, shifOpnd, kShiftLeft, PTY_u64); Operand &spOpnd = GetOrCreatePhysicalRegisterOperand(RSP, k64BitSize, kRegTyInt); SelectSub(spOpnd, spOpnd, aliOp, PTY_u64); - int64 argsToStkpassSize = GetMemlayout()->SizeOfArgsToStackPass(); - if (argsToStkpassSize > 0) { + int64 allocaOffset = GetMemlayout()->SizeOfArgsToStackPass(); + if (GetCG()->IsLmbc()) { + allocaOffset -= kDivide2 * k8ByteSize; + } + if (allocaOffset > 0) { RegOperand &resallo = CreateRegisterOperandOfType(PTY_u64); - SelectAdd(resallo, spOpnd, CreateImmOperand(argsToStkpassSize, k64BitSize, true), PTY_u64); + SelectAdd(resallo, spOpnd, CreateImmOperand(allocaOffset, k64BitSize, true), PTY_u64); return &resallo; } else { return &SelectCopy(spOpnd, PTY_u64, PTY_u64); @@ -6221,6 +6518,15 @@ void AArch64CGFunc::AssignLmbcFormalParams() { param->SetRegNO(0); } else { param->SetRegNO(intReg); + if (param->HasRegassign() == false) { + uint32 bytelen = GetPrimTypeSize(primType); + uint32 bitlen = bytelen * kBitsPerByte; + MemOperand *mOpnd = GenLmbcFpMemOperand(offset, bytelen); + RegOperand &src = GetOrCreatePhysicalRegisterOperand(AArch64reg(intReg), bitlen, kRegTyInt); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, src, *mOpnd); + GetCurBB()->AppendInsn(store); + } intReg++; } } else if (IsPrimitiveFloat(primType)) { @@ -6228,6 +6534,15 @@ void AArch64CGFunc::AssignLmbcFormalParams() { param->SetRegNO(0); } else { param->SetRegNO(fpReg); + if (param->HasRegassign() == false) { + uint32 bytelen = GetPrimTypeSize(primType); + uint32 bitlen = bytelen * kBitsPerByte; + MemOperand *mOpnd = GenLmbcFpMemOperand(offset, bytelen); + RegOperand &src = GetOrCreatePhysicalRegisterOperand(AArch64reg(fpReg), bitlen, kRegTyFloat); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, src, *mOpnd); + GetCurBB()->AppendInsn(store); + } fpReg++; } } else if (primType == PTY_agg) { @@ -6246,6 +6561,14 @@ void AArch64CGFunc::AssignLmbcFormalParams() { } else { param->SetRegNO(intReg); param->SetIsOnStack(); + param->SetOnStackOffset((intReg - R0 + fpReg - V0) * k8ByteSize); + uint32 bytelen = GetPrimTypeSize(PTY_a64); + uint32 bitlen = bytelen * kBitsPerByte; + MemOperand *mOpnd = GenLmbcFpMemOperand(param->GetOnStackOffset(), bytelen); + RegOperand &src = GetOrCreatePhysicalRegisterOperand(AArch64reg(intReg), bitlen, kRegTyInt); + MOperator mOp = PickStInsn(bitlen, PTY_a64); + Insn &store = GetCG()->BuildInstruction(mOp, src, *mOpnd); + GetCurBB()->AppendInsn(store); intReg++; } } else if (param->GetSize() <= k8ByteSize) { @@ -6291,7 +6614,6 @@ void AArch64CGFunc::AssignLmbcFormalParams() { Operand *memOpd = &CreateMemOpnd(RFP, offset + (i * rSize), rSize); GetCurBB()->AppendInsn(GetCG()->BuildInstruction( PickStInsn(rSize * kBitsPerByte, pType), dest, *memOpd)); - param->SetIsOnStack(); } } } else { @@ -6300,6 +6622,22 @@ void AArch64CGFunc::AssignLmbcFormalParams() { } } +void AArch64CGFunc::LmbcGenSaveSpForAlloca() { + if (GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc || HasVLAOrAlloca() == false) { + return; + } + Operand &spOpnd = GetOrCreatePhysicalRegisterOperand(RSP, k64BitSize, kRegTyInt); + RegOperand &spSaveOpnd = CreateVirtualRegisterOperand(NewVReg(kRegTyInt, kSizeOfPtr)); + Insn &save = GetCG()->BuildInstruction(MOP_xmovrr, spSaveOpnd, spOpnd); + GetFirstBB()->AppendInsn(save); + //save.SetFrameDef(true); + for (auto *retBB : GetExitBBsVec()) { + Insn &restore = GetCG()->BuildInstruction(MOP_xmovrr, spOpnd, spSaveOpnd); + retBB->AppendInsn(restore); + restore.SetFrameDef(true); + } +} + /* if offset < 0, allocation; otherwise, deallocation */ MemOperand &AArch64CGFunc::CreateCallFrameOperand(int32 offset, int32 size) { MemOperand *memOpnd = CreateStackMemOpnd(RSP, offset, size); @@ -7585,6 +7923,10 @@ size_t AArch64CGFunc::SelectParmListGetStructReturnSize(StmtNode &naryNode) { CallNode &callNode = static_cast(naryNode); MIRFunction *callFunc = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callNode.GetPUIdx()); TyIdx retIdx = callFunc->GetReturnTyIdx(); + if (callFunc->IsFirstArgReturn()) { + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(callFunc->GetFormalDefVec()[0].formalTyIdx); + return GetBecommon().GetTypeSize(static_cast(ty)->GetPointedTyIdx()); + } size_t retSize = GetBecommon().GetTypeSize(retIdx.GetIdx()); if ((retSize == 0) && callFunc->IsReturnStruct()) { TyIdx tyIdx = callFunc->GetFuncRetStructTyIdx(); @@ -7601,6 +7943,14 @@ size_t AArch64CGFunc::SelectParmListGetStructReturnSize(StmtNode &naryNode) { return GetBecommon().GetTypeSize(sym->GetTyIdx().GetIdx()); } } + } else if (naryNode.GetOpCode() == OP_icallproto) { + IcallNode &icallProto = static_cast(naryNode); + MIRFuncType *funcTy = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallProto.GetRetTyIdx())); + if (funcTy->FirstArgReturn()) { + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcTy->GetNthParamType(0)); + return GetBecommon().GetTypeSize(static_cast(ty)->GetPointedTyIdx()); + } + return GetBecommon().GetTypeSize(funcTy->GetRetTyIdx()); } return 0; } @@ -7708,7 +8058,7 @@ void AArch64CGFunc::SelectParmListPreprocess(const StmtNode &naryNode, size_t st */ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bool isCallNative) { size_t i = 0; - if ((naryNode.GetOpCode() == OP_icall) || isCallNative) { + if (naryNode.GetOpCode() == OP_icall || naryNode.GetOpCode() == OP_icallproto || isCallNative) { i++; } std::set specialArgs; @@ -7735,8 +8085,11 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - auto *callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + MIRFunction *callee = nullptr; + if (dynamic_cast(&naryNode) != nullptr) { + auto calleePuIdx = static_cast(naryNode).GetPUIdx(); + callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } @@ -8259,7 +8612,18 @@ void AArch64CGFunc::SelectCall(CallNode &callNode) { ListOperand *srcOpnds = CreateListOpnd(*GetFuncScopeAllocator()); if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { - LmbcSelectParmList(srcOpnds, fn->IsFirstArgReturn()); + SetLmbcCallReturnType(nullptr); + bool largeStructRet = false; + if (fn->IsFirstArgReturn()) { + MIRPtrType *ptrTy = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(fn->GetFormalDefVec()[0].formalTyIdx)); + MIRType *sTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ptrTy->GetPointedTyIdx()); + largeStructRet = sTy->GetSize() > k16ByteSize; + SetLmbcCallReturnType(sTy); + } else { + MIRType *ty = fn->GetReturnType(); + SetLmbcCallReturnType(ty); + } + LmbcSelectParmList(srcOpnds, largeStructRet); } bool callNative = false; if ((fsym->GetName() == "MCC_CallFastNative") || (fsym->GetName() == "MCC_CallFastNativeExt") || @@ -8335,11 +8699,21 @@ void AArch64CGFunc::SelectCall(CallNode &callNode) { void AArch64CGFunc::SelectIcall(IcallNode &icallNode, Operand &srcOpnd) { ListOperand *srcOpnds = CreateListOpnd(*GetFuncScopeAllocator()); - if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { - LmbcSelectParmList(srcOpnds, false /*fType->GetRetAttrs().GetAttr(ATTR_firstarg_return)*/); - } else { +// if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { +// /* icallproto */ +// MIRType *retTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallNode.GetRetTyIdx()); +// MIRFuncType *funcTy = static_cast(retTy); +// bool largeStructRet = false; +// if (funcTy->FirstArgReturn()) { +// TyIdx idx = funcTy->GetNthParamType(0); +// MIRPtrType *ptrTy = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(idx)); +// MIRType *sTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ptrTy->GetPointedTyIdx()); +// largeStructRet = sTy->GetSize() > k16ByteSize; +// } +// LmbcSelectParmList(srcOpnds, largeStructRet); +// } else { SelectParmList(icallNode, *srcOpnds); - } +// } Operand *fptrOpnd = &srcOpnd; if (fptrOpnd->GetKind() != Operand::kOpdRegister) { @@ -8350,7 +8724,7 @@ void AArch64CGFunc::SelectIcall(IcallNode &icallNode, Operand &srcOpnd) { RegOperand *regOpnd = static_cast(fptrOpnd); Insn &callInsn = GetCG()->BuildInstruction(MOP_xblr, *regOpnd, *srcOpnds); - MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallNode.GetRetTyIdx()); + MIRType *retType = icallNode.GetCallReturnType(); if (retType != nullptr) { callInsn.SetRetSize(static_cast(retType->GetSize())); callInsn.SetIsCallReturnUnsigned(IsUnsignedInteger(retType->GetPrimType())); @@ -8463,9 +8837,18 @@ RegOperand &AArch64CGFunc::GetOrCreateSpecialRegisterOperand(PregIdx sregIdx, Pr case kSregFp: reg = RFP; break; - case kSregGp: - reg = RFP; - break; + case kSregGp: { + MIRSymbol *sym = GetCG()->GetGP(); + if (sym == nullptr) { + sym = GetFunction().GetSymTab()->CreateSymbol(kScopeLocal); + std::string strBuf("__file__local__GP"); + sym->SetNameStrIdx(GetMirModule().GetMIRBuilder()->GetOrCreateStringIndex(strBuf)); + GetCG()->SetGP(sym); + } + RegOperand &result = GetOrCreateVirtualRegisterOperand(NewVReg(kRegTyInt, k8ByteSize)); + SelectAddrof(result, CreateStImmOperand(*sym, 0, 0)); + return result; + } case kSregThrownval: { /* uses x0 == R0 */ ASSERT(uCatch.regNOCatch > 0, "regNOCatch should greater than 0."); if (Globals::GetInstance()->GetOptimLevel() == 0) { @@ -9202,6 +9585,9 @@ int32 AArch64CGFunc::GetBaseOffset(const SymbolAlloc &sa) { int32 baseOffset = symAlloc->GetOffset(); return baseOffset + sizeofFplr; } else if (sgKind == kMsSpillReg) { + if (GetCG()->IsLmbc()) { + return symAlloc->GetOffset() + memLayout->SizeOfArgsToStackPass(); + } int32 baseOffset = symAlloc->GetOffset() + memLayout->SizeOfArgsRegisterPassed() + memLayout->GetSizeOfLocals() + memLayout->GetSizeOfRefLocals(); return baseOffset + sizeofFplr; @@ -9776,16 +10162,21 @@ void AArch64CGFunc::GenCVaStartIntrin(RegOperand &opnd, uint32 stkSize) { Operand &stkOpnd = GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); /* __stack */ - ImmOperand *offsOpnd = &CreateImmOperand(0, k64BitSize, true, kUnAdjustVary); /* isvary reset StackFrameSize */ + ImmOperand *offsOpnd; + if (GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + offsOpnd = &CreateImmOperand(0, k64BitSize, true, kUnAdjustVary); /* isvary reset StackFrameSize */ + } else { + offsOpnd = &CreateImmOperand(0, k64BitSize, true); + } ImmOperand *offsOpnd2 = &CreateImmOperand(stkSize, k64BitSize, false); RegOperand &vReg = CreateVirtualRegisterOperand(NewVReg(kRegTyInt, GetPrimTypeSize(LOWERED_PTR_TYPE))); if (stkSize) { SelectAdd(vReg, *offsOpnd, *offsOpnd2, LOWERED_PTR_TYPE); SelectAdd(vReg, stkOpnd, vReg, LOWERED_PTR_TYPE); } else { - SelectAdd(vReg, stkOpnd, *offsOpnd, LOWERED_PTR_TYPE); + SelectAdd(vReg, stkOpnd, *offsOpnd, LOWERED_PTR_TYPE); /* stack pointer */ } - OfstOperand *offOpnd = &GetOrCreateOfstOpnd(0, k64BitSize); + OfstOperand *offOpnd = &GetOrCreateOfstOpnd(0, k64BitSize); /* va_list ptr */ /* mem operand in va_list struct (lhs) */ MemOperand *strOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, k64BitSize, &opnd, nullptr, offOpnd, static_cast(nullptr)); @@ -9860,13 +10251,19 @@ void AArch64CGFunc::SelectCVaStart(const IntrinsiccallNode &intrnNode) { AArch64CallConvImpl parmLocator(GetBecommon()); CCLocInfo pLoc; uint32 stkSize = 0; + uint32 inReg = 0; for (uint32 i = 0; i < GetFunction().GetFormalCount(); i++) { MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(GetFunction().GetNthParamTyIdx(i)); parmLocator.LocateNextParm(*ty, pLoc); if (pLoc.reg0 == kRinvalid) { /* on stack */ stkSize = static_cast(pLoc.memOffset + pLoc.memSize); + } else { + inReg++; } } + if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + stkSize += (inReg * k8ByteSize); + } if (CGOptions::IsArm64ilp32()) { stkSize = static_cast(RoundUp(stkSize, k8ByteSize)); } else { diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp index 5716509ad6..433aeeee3a 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp @@ -40,8 +40,8 @@ constexpr uint8 insPairsNum = 5; PairMOperator extInsnPairTable[ExtTableSize][insPairsNum] = { /* {origMop, newMop} */ - {{MOP_wldrb, MOP_wldrb}, {MOP_undef, MOP_undef}, {MOP_undef, MOP_undef}, {MOP_undef, MOP_undef}, - {MOP_undef, MOP_undef}}, /* AND */ + {{MOP_wldrb, MOP_wldrb}, {MOP_wldrsh, MOP_wldrb}, {MOP_wldrh, MOP_wldrb}, {MOP_xldrsw, MOP_wldrb}, + {MOP_wldr, MOP_wldrb}}, /* AND */ {{MOP_wldrb, MOP_wldrsb}, {MOP_wldr, MOP_wldrsb}, {MOP_undef, MOP_undef}, {MOP_undef, MOP_undef}, {MOP_undef, MOP_undef}}, /* SXTB */ {{MOP_wldrh, MOP_wldrsh}, {MOP_wldrb, MOP_wldrb}, {MOP_wldrsb, MOP_wldrsb}, {MOP_wldrsh, MOP_wldrsh}, diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp index e9acbeefcc..71f57d89ea 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp @@ -134,7 +134,7 @@ void AArch64MemLayout::LayoutVarargParams() { if (be.GetMIRModule().IsCModule() && func->GetAttr(FUNCATTR_varargs)) { for (uint32 i = 0; i < func->GetFormalCount(); i++) { if (i == 0) { - if (func->IsReturnStruct()) { + if (func->IsFirstArgReturn() && func->GetReturnType()->GetPrimType() != PTY_void) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (be.GetTypeSize(tyIdx.GetIdx()) <= k16ByteSize) { continue; @@ -198,7 +198,7 @@ void AArch64MemLayout::LayoutFormalParams() { * outparmsize - portion of frame size of current function used by call parameters */ segArgsStkPassed.SetSize(mirFunction->GetOutParmSize()); - segArgsRegPassed.SetSize(mirFunction->GetOutParmSize() + kTwoRegister * k8ByteSize); + segArgsRegPassed.SetSize(mirFunction->GetOutParmSize()); return; } @@ -210,7 +210,7 @@ void AArch64MemLayout::LayoutFormalParams() { AArch64SymbolAlloc *symLoc = memAllocator->GetMemPool()->New(); SetSymAllocInfo(stIndex, *symLoc); if (i == 0) { - if (mirFunction->IsReturnStruct()) { + if (mirFunction->IsFirstArgReturn()) { symLoc->SetMemSegment(GetSegArgsRegPassed()); symLoc->SetOffset(GetSegArgsRegPassed().GetSize()); TyIdx tyIdx = mirFunction->GetFuncRetStructTyIdx(); @@ -224,13 +224,13 @@ void AArch64MemLayout::LayoutFormalParams() { continue; } } - MIRType *ty = mirFunction->GetNthParamType(i); + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(mirFunction->GetFormalDefVec()[i].formalTyIdx); uint32 ptyIdx = ty->GetTypeIndex(); parmLocator.LocateNextParm(*ty, ploc, i == 0, mirFunction); if (ploc.reg0 != kRinvalid) { /* register */ symLoc->SetRegisters(static_cast(ploc.reg0), static_cast(ploc.reg1), static_cast(ploc.reg2), static_cast(ploc.reg3)); - if (mirFunction->GetNthParamAttr(i).GetAttr(ATTR_localrefvar)) { + if (mirFunction->GetFormalDefVec()[i].formalAttrs.GetAttr(ATTR_localrefvar)) { symLoc->SetMemSegment(segRefLocals); SetSegmentSize(*symLoc, segRefLocals, ptyIdx); } else if (!sym->IsPreg()) { @@ -272,7 +272,7 @@ void AArch64MemLayout::LayoutFormalParams() { } else { segArgsStkPassed.SetSize(static_cast(RoundUp(segArgsStkPassed.GetSize(), kSizeOfPtr))); } - if (mirFunction->GetNthParamAttr(i).GetAttr(ATTR_localrefvar)) { + if (mirFunction->GetFormalDefVec()[i].formalAttrs.GetAttr(ATTR_localrefvar)) { SetLocalRegLocInfo(sym->GetStIdx(), *symLoc); AArch64SymbolAlloc *symLoc1 = memAllocator->GetMemPool()->New(); symLoc1->SetMemSegment(segRefLocals); @@ -287,7 +287,7 @@ void AArch64MemLayout::LayoutFormalParams() { } void AArch64MemLayout::LayoutLocalVariables(std::vector &tempVar, std::vector &returnDelays) { - if (be.GetMIRModule().GetFlavor() == kFlavorLmbc && mirFunction->GetFormalCount() == 0) { + if (be.GetMIRModule().GetFlavor() == kFlavorLmbc) { segLocals.SetSize(mirFunction->GetFrameSize() - mirFunction->GetOutParmSize()); return; } @@ -372,7 +372,7 @@ void AArch64MemLayout::LayoutReturnRef(std::vector &returnDelays, segRefLocals.SetSize(segRefLocals.GetSize() + be.GetTypeSize(tyIdx)); } if (be.GetMIRModule().GetFlavor() == kFlavorLmbc) { - segArgsToStkPass.SetSize(mirFunction->GetOutParmSize()); + segArgsToStkPass.SetSize(mirFunction->GetOutParmSize() + kDivide2 * k8ByteSize); } else { segArgsToStkPass.SetSize(FindLargestActualArea(structCopySize)); } @@ -423,7 +423,7 @@ void AArch64MemLayout::LayoutActualParams() { * variables get assigned their respecitve storage, i.e. * CallFrameSize (discounting callee-saved and FP/LR) is known. */ - MIRType *ty = mirFunction->GetNthParamType(i); + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(mirFunction->GetFormalDefVec()[i].formalTyIdx); uint32 ptyIdx = ty->GetTypeIndex(); static_cast(cgFunc)->GetOrCreateMemOpnd(*sym, 0, be.GetTypeAlign(ptyIdx) * kBitsPerByte); } @@ -440,7 +440,7 @@ void AArch64MemLayout::LayoutStackFrame(int32 &structCopySize, int32 &maxParmSta */ if (CGOptions::IsArm64ilp32()) { segArgsRegPassed.SetSize(RoundUp(segArgsRegPassed.GetSize(), k8ByteSize)); - /* we do need this as SP has to be aligned at a 16-bytes bounardy */ + /* we do need this as SP has to be aligned at a 16-bytes bounardy */ segArgsStkPassed.SetSize(RoundUp(segArgsStkPassed.GetSize(), k8ByteSize + k8ByteSize)); } else { segArgsRegPassed.SetSize(RoundUp(segArgsRegPassed.GetSize(), kSizeOfPtr)); @@ -527,11 +527,13 @@ uint64 AArch64MemLayout::StackFrameSize() const { uint64 total = segArgsRegPassed.GetSize() + static_cast(cgFunc)->SizeOfCalleeSaved() + GetSizeOfRefLocals() + locals().GetSize() + GetSizeOfSpillReg(); - if (GetSizeOfGRSaveArea() > 0) { - total += RoundUp(GetSizeOfGRSaveArea(), kAarch64StackPtrAlignment); - } - if (GetSizeOfVRSaveArea() > 0) { - total += RoundUp(GetSizeOfVRSaveArea(), kAarch64StackPtrAlignment); + if (cgFunc->GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + if (GetSizeOfGRSaveArea() > 0) { + total += RoundUp(GetSizeOfGRSaveArea(), kAarch64StackPtrAlignment); + } + if (GetSizeOfVRSaveArea() > 0) { + total += RoundUp(GetSizeOfVRSaveArea(), kAarch64StackPtrAlignment); + } } /* diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp index eaa5726d43..7ef7190645 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp @@ -50,7 +50,7 @@ void AArch64FPLROffsetAdjustment::AdjustmentOffsetForOpnd(Insn &insn, AArch64CGF if (memBaseReg->GetRegisterNumber() == RFP) { RegOperand &newBaseOpnd = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(stackBaseReg, k64BitSize, kRegTyInt); MemOperand &newMemOpnd = aarchCGFunc.GetOrCreateMemOpnd( - MemOperand::kAddrModeBOi, memOpnd.GetSize(), &newBaseOpnd, memOpnd.GetIndexRegister(), + memOpnd.GetAddrMode(), memOpnd.GetSize(), &newBaseOpnd, memOpnd.GetIndexRegister(), memOpnd.GetOffsetImmediate(), memOpnd.GetSymbol()); insn.SetOperand(i, newMemOpnd); stackBaseOpnd = true; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp index efa8b3087b..0c2322d055 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp @@ -1118,6 +1118,9 @@ void AArch64GenProEpilog::AppendInstructionAllocateCallFrameDebug(AArch64reg reg ipoint = cgFunc.GetCurBB()->GetLastInsn(); cfiOffset = stackFrameSize; (void)InsertCFIDefCfaOffset(cfiOffset, *ipoint); + if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + argsToStkPassSize -= (kDivide2 * k8ByteSize); + } ipoint = &CreateAndAppendInstructionForAllocateCallFrame(argsToStkPassSize, reg0, reg1, rty); CHECK_FATAL(ipoint != nullptr, "ipoint should not be nullptr at this point"); cfiOffset = GetOffsetFromCFA(); @@ -1251,9 +1254,16 @@ void AArch64GenProEpilog::GeneratePushRegs() { CHECK_FATAL(*it == RLR, "The second callee saved reg is expected to be RLR"); ++it; - auto offset = static_cast((static_cast(cgFunc.GetMemlayout())->RealStackFrameSize() - - (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */)) - - cgFunc.GetMemlayout()->SizeOfArgsToStackPass()); + AArch64MemLayout *memLayout = static_cast(cgFunc.GetMemlayout()); + int32 offset; + if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + offset = static_cast(memLayout->RealStackFrameSize() - + aarchCGFunc.SizeOfCalleeSaved() - memLayout->GetSizeOfLocals()); + } else { + offset = static_cast(memLayout->RealStackFrameSize() - + (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */) - + memLayout->SizeOfArgsToStackPass()); + } if (cgFunc.GetCG()->IsStackProtectorStrong() || cgFunc.GetCG()->IsStackProtectorAll()) { offset -= static_cast(kAarch64StackPtrAlignment); @@ -1313,10 +1323,19 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { size = kSizeOfPtr; } uint32 dataSizeBits = size * kBitsPerByte; - uint32 offset = static_cast(memlayout->GetGRSaveAreaBaseLoc()); - if (memlayout->GetSizeOfGRSaveArea() % kAarch64StackPtrAlignment) { - offset += size; /* End of area should be aligned. Hole between VR and GR area */ + uint32 offset; + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + offset = static_cast(memlayout->GetGRSaveAreaBaseLoc()); /* SP reference */ + if (memlayout->GetSizeOfGRSaveArea() % kAarch64StackPtrAlignment) { + offset += size; /* End of area should be aligned. Hole between VR and GR area */ + } + } else { + offset = -memlayout->GetSizeOfGRSaveArea(); /* FP reference */ + if (memlayout->GetSizeOfGRSaveArea() % kAarch64StackPtrAlignment) { + offset -= size; + } } + uint32 grSize = -offset; uint32 start_regno = k8BitSize - (memlayout->GetSizeOfGRSaveArea() / size); ASSERT(start_regno <= k8BitSize, "Incorrect starting GR regno for GR Save Area"); for (uint32 i = start_regno + static_cast(R0); i < static_cast(R8); i++) { @@ -1326,16 +1345,25 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { tmpOffset += 8U - (dataSizeBits >> 3); } } - Operand &stackloc = aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); + Operand *stackLoc; + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + stackLoc = &aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); + } else { + stackLoc = aarchCGFunc.GenLmbcFpMemOperand(offset, size); + } RegOperand ® = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(static_cast(i), k64BitSize, kRegTyInt); Insn &inst = - currCG->BuildInstruction(aarchCGFunc.PickStInsn(dataSizeBits, PTY_i64), reg, stackloc); + currCG->BuildInstruction(aarchCGFunc.PickStInsn(dataSizeBits, PTY_i64), reg, *stackLoc); cgFunc.GetCurBB()->AppendInsn(inst); offset += size; } if (!CGOptions::UseGeneralRegOnly()) { - offset = static_cast(memlayout->GetVRSaveAreaBaseLoc()); + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + offset = static_cast(memlayout->GetVRSaveAreaBaseLoc()); + } else { + offset = -(memlayout->GetSizeOfVRSaveArea() + grSize); + } start_regno = k8BitSize - (memlayout->GetSizeOfVRSaveArea() / (size * k2BitSize)); ASSERT(start_regno <= k8BitSize, "Incorrect starting GR regno for VR Save Area"); for (uint32 i = start_regno + static_cast(V0); i < static_cast(V8); i++) { @@ -1345,11 +1373,16 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { tmpOffset += 16U - (dataSizeBits >> 3); } } - Operand &stackloc = aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); + Operand *stackLoc; + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + stackLoc = &aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); + } else { + stackLoc = aarchCGFunc.GenLmbcFpMemOperand(offset, size); + } RegOperand ® = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(static_cast(i), k64BitSize, kRegTyFloat); Insn &inst = - currCG->BuildInstruction(aarchCGFunc.PickStInsn(dataSizeBits, PTY_f64), reg, stackloc); + currCG->BuildInstruction(aarchCGFunc.PickStInsn(dataSizeBits, PTY_f64), reg, *stackLoc); cgFunc.GetCurBB()->AppendInsn(inst); offset += (size * k2BitSize); } @@ -1389,7 +1422,8 @@ void AArch64GenProEpilog::GenerateProlog(BB &bb) { } // insert .loc for function - if (currCG->GetCGOptions().WithLoc()) { + if (currCG->GetCGOptions().WithLoc() && + (!currCG->GetMIRModule()->IsCModule() || currCG->GetMIRModule()->IsWithDbgInfo())) { MIRFunction *func = &cgFunc.GetFunction(); MIRSymbol *fSym = GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx()); if (currCG->GetCGOptions().WithSrc()) { @@ -1649,11 +1683,17 @@ void AArch64GenProEpilog::AppendInstructionDeallocateCallFrameDebug(AArch64reg r * ldp/stp's imm should be within -512 and 504; * if ldp's imm > 504, we fall back to the ldp-add version */ - if (cgFunc.HasVLAOrAlloca() || argsToStkPassSize == 0) { - stackFrameSize -= argsToStkPassSize; - if (stackFrameSize > kStpLdpImm64UpperBound) { + bool isLmbc = (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc); + if (cgFunc.HasVLAOrAlloca() || argsToStkPassSize == 0 || isLmbc) { + int lmbcOffset = 0; + if (isLmbc == false) { + stackFrameSize -= argsToStkPassSize; + } else { + lmbcOffset = argsToStkPassSize - (kDivide2 * k8ByteSize); + } + if (stackFrameSize > kStpLdpImm64UpperBound || isLmbc) { Operand *o2; - o2 = aarchCGFunc.CreateStackMemOpnd(RSP, 0, kSizeOfPtr * kBitsPerByte); + o2 = aarchCGFunc.CreateStackMemOpnd(RSP, (isLmbc ? lmbcOffset : 0), kSizeOfPtr * kBitsPerByte); Insn &deallocInsn = currCG->BuildInstruction(mOp, o0, o1, *o2); cgFunc.GetCurBB()->AppendInsn(deallocInsn); if (cgFunc.GenCfi()) { @@ -1728,9 +1768,16 @@ void AArch64GenProEpilog::GeneratePopRegs() { CHECK_FATAL(*it == RLR, "The second callee saved reg is expected to be RLR"); ++it; - int32 offset = static_cast((static_cast(cgFunc.GetMemlayout())->RealStackFrameSize() - - (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */)) - - cgFunc.GetMemlayout()->SizeOfArgsToStackPass()); + AArch64MemLayout *memLayout = static_cast(cgFunc.GetMemlayout()); + int32 offset; + if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + offset = static_cast(memLayout->RealStackFrameSize() - + aarchCGFunc.SizeOfCalleeSaved() - memLayout->GetSizeOfLocals()); + } else { + offset = static_cast(cgFunc.GetMemlayout())->RealStackFrameSize() - + (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */) - + memLayout->SizeOfArgsToStackPass(); + } if (cgFunc.GetCG()->IsStackProtectorStrong() || cgFunc.GetCG()->IsStackProtectorAll()) { offset -= static_cast(kAarch64StackPtrAlignment); @@ -1821,7 +1868,7 @@ void AArch64GenProEpilog::GenerateEpilog(BB &bb) { Operand &spOpnd = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(RSP, k64BitSize, kRegTyInt); Operand &fpOpnd = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(stackBaseReg, k64BitSize, kRegTyInt); - if (cgFunc.HasVLAOrAlloca()) { + if (cgFunc.HasVLAOrAlloca() && cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { aarchCGFunc.SelectCopy(spOpnd, PTY_u64, fpOpnd, PTY_u64); } diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp index 433cc85754..5ca154b1aa 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp @@ -161,8 +161,7 @@ void AArch64ReachingDefinition::AddRetPseudoInsn(BB &bb) { Insn &retInsn = cgFunc->GetCG()->BuildInstruction(MOP_pseudo_ret_int, regOpnd); bb.AppendInsn(retInsn); pseudoInsns.emplace_back(&retInsn); - } else { - ASSERT(regNO == V0, "CG internal error. Return value should be R0 or V0."); + } else if (regNO == V0) { RegOperand ®Opnd = static_cast(cgFunc)->GetOrCreatePhysicalRegisterOperand(regNO, k64BitSize, kRegTyFloat); Insn &retInsn = cgFunc->GetCG()->BuildInstruction(MOP_pseudo_ret_float, regOpnd); diff --git a/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp b/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp index d2ae2c25c9..bf645c15cd 100644 --- a/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp +++ b/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp @@ -160,6 +160,7 @@ void RecursiveMarkUsedStaticSymbol(const BaseNode *baseNode) { break; } case OP_addrof: + case OP_addrofoff: case OP_dread: { const AddrofNode *dreadNode = static_cast(baseNode); MarkUsedStaticSymbol(dreadNode->GetStIdx()); diff --git a/src/mapleall/maple_be/src/cg/cgfunc.cpp b/src/mapleall/maple_be/src/cg/cgfunc.cpp index f6075c05dd..5e35444b07 100644 --- a/src/mapleall/maple_be/src/cg/cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/cgfunc.cpp @@ -1148,7 +1148,11 @@ void HandleReturn(StmtNode &stmt, CGFunc &cgFunc) { ASSERT(retNode.NumOpnds() <= 1, "NYI return nodes number > 1"); Operand *opnd = nullptr; if (retNode.NumOpnds() != 0) { - opnd = cgFunc.HandleExpr(retNode, *retNode.Opnd(0)); + if (!cgFunc.GetFunction().StructReturnedInRegs()) { + opnd = cgFunc.HandleExpr(retNode, *retNode.Opnd(0)); + } else { + cgFunc.SelectReturnSendOfStructInRegs(retNode.Opnd(0)); + } } cgFunc.SelectReturn(opnd); cgFunc.SetCurBBKind(BB::kBBReturn); @@ -1564,14 +1568,15 @@ void CGFunc::CreateLmbcFormalParamInfo() { uint32 offset; uint32 typeSize; MIRFunction &func = GetFunction(); - if (func.GetParamSize() > 0) { + if (func.GetFormalCount() > 0) { + /* Whenever lmbc cannot delete call type info, the prototype is available */ uint32 stackOffset = 0; - for (size_t idx = 0; idx < func.GetParamSize(); ++idx) { + for (size_t idx = 0; idx < func.GetFormalCount(); ++idx) { MIRSymbol *sym = func.GetFormal(idx); MIRType *type; TyIdx tyIdx; if (sym) { - tyIdx = func.GetNthParamTyIdx(idx); + tyIdx = func.GetFormalDefVec()[idx].formalTyIdx; type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); } else { FormalDef vec = const_cast(GetBecommon().GetMIRModule().CurFunction())->GetFormalDefAt(idx); @@ -1618,6 +1623,9 @@ void CGFunc::CreateLmbcFormalParamInfo() { } IreadFPoffNode *ireadNode = static_cast(operand); primType = ireadNode->GetPrimType(); + if (ireadNode->GetOffset() < 0) { + continue; + } offset = static_cast(ireadNode->GetOffset()); typeSize = GetPrimTypeSize(primType); CHECK_FATAL((offset % k8ByteSize) == 0, ""); /* scalar only, no struct for now */ @@ -1629,6 +1637,31 @@ void CGFunc::CreateLmbcFormalParamInfo() { [] (LmbcFormalParamInfo *x, LmbcFormalParamInfo *y) { return x->GetOffset() < y->GetOffset(); } ); + + /* When a scalar param address is taken, its regassign is not in the 1st block */ + for (StmtNode *stmt = func.GetBody()->GetFirst(); stmt != nullptr; stmt = stmt->GetNext()) { + if (stmt == nullptr) { + break; + } + if (stmt->GetOpCode() == OP_label) { + continue; + } + if (stmt->GetOpCode() != OP_regassign) { + break; + } + RegassignNode *regAssignNode = static_cast(stmt); + BaseNode *operand = regAssignNode->Opnd(0); + if (operand->GetOpCode() != OP_ireadfpoff) { + break; + } + IreadFPoffNode *ireadNode = static_cast(operand); + if (ireadNode->GetOffset() < 0) { + continue; + } + LmbcFormalParamInfo *info = GetLmbcFormalParamInfo(ireadNode->GetOffset()); + info->SetHasRegassign(); + } + AssignLmbcFormalParams(); } @@ -1637,7 +1670,7 @@ void CGFunc::GenerateInstruction() { InitHandleStmtFactory(); StmtNode *secondStmt = HandleFirstStmt(); - CreateLmbcFormalParamInfo(); + //CreateLmbcFormalParamInfo(); /* First Pass: Creates the doubly-linked list of BBs (next,prev) */ volReleaseInsn = nullptr; unsigned lastSrcLoc = 0; @@ -2009,6 +2042,7 @@ void CGFunc::HandleFunction() { ASSERT(exitBBVec.size() <= 1, "there are more than one BB_return in func"); } ProcessExitBBVec(); + LmbcGenSaveSpForAlloca(); if (func.IsJava()) { GenerateCleanupCodeForExtEpilog(*cleanupBB); diff --git a/src/mapleall/maple_be/src/cg/emit.cpp b/src/mapleall/maple_be/src/cg/emit.cpp index 896d0a297b..6e28d7bee5 100644 --- a/src/mapleall/maple_be/src/cg/emit.cpp +++ b/src/mapleall/maple_be/src/cg/emit.cpp @@ -2170,6 +2170,11 @@ void Emitter::EmitGlobalVar(const MIRSymbol &globalVar) { } void Emitter::EmitGlobalVars(std::vector> &globalVars) { + if (GetCG()->IsLmbc() && GetCG()->GetGP() != nullptr) { + Emit(asmInfo->GetLocal()).Emit("\t").Emit(GetCG()->GetGP()->GetName()).Emit("\n"); + Emit(asmInfo->GetComm()).Emit("\t").Emit(GetCG()->GetGP()->GetName()); + Emit(", ").Emit(GetCG()->GetMIRModule()->GetGlobalMemSize()).Emit(", ").Emit("8\n"); + } /* load globalVars profile */ if (globalVars.empty()) { return; diff --git a/src/mapleall/maple_be/src/cg/memlayout.cpp b/src/mapleall/maple_be/src/cg/memlayout.cpp index 57e45e8a2d..1b636207c6 100644 --- a/src/mapleall/maple_be/src/cg/memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/memlayout.cpp @@ -38,7 +38,7 @@ uint32 MemLayout::FindLargestActualArea(int32 &aggCopySize) { uint32 maxCopyStackSize = 0; // Size of aggregate param stack copy requirement for (; stmt != nullptr; stmt = stmt->GetNext()) { Opcode opCode = stmt->GetOpCode(); - if (opCode < OP_call || opCode > OP_xintrinsiccallassigned) { + if ((opCode < OP_call || opCode > OP_xintrinsiccallassigned) && opCode != OP_icallproto) { continue; } if (opCode == OP_intrinsiccallwithtypeassigned || opCode == OP_intrinsiccallwithtype || @@ -54,9 +54,9 @@ uint32 MemLayout::FindLargestActualArea(int32 &aggCopySize) { * if the following check fails, most likely dex has invoke-custom etc * that is not supported yet */ - DCHECK((opCode == OP_call || opCode == OP_icall), "Not lowered to call or icall?"); + DCHECK((opCode == OP_call || opCode == OP_icall || opCode == OP_icallproto), "Not lowered to call or icall?"); int32 copySize; - uint32 size = ComputeStackSpaceRequirementForCall(*stmt, copySize, opCode == OP_icall); + uint32 size = ComputeStackSpaceRequirementForCall(*stmt, copySize, opCode == OP_icall || opCode == OP_icallproto); if (size > maxParamStackSize) { maxParamStackSize = size; } diff --git a/src/mapleall/maple_ir/include/bin_mpl_export.h b/src/mapleall/maple_ir/include/bin_mpl_export.h index 09952cb8c7..f12bec7081 100644 --- a/src/mapleall/maple_ir/include/bin_mpl_export.h +++ b/src/mapleall/maple_ir/include/bin_mpl_export.h @@ -67,8 +67,8 @@ enum : uint8 { kBinEaCgStart = 41, kBinEaStart = 42, kBinNodeBlock = 43, - kBinOpStatement = 44, - kBinOpExpression = 45, +//kBinOpStatement = 44, +//kBinOpExpression = 45, kBinReturnvals = 46, kBinTypeTabStart = 47, kBinSymStart = 48, @@ -76,14 +76,14 @@ enum : uint8 { kBinFuncIdInfoStart = 50, kBinFormalStart = 51, kBinPreg = 52, - kBinPregStart = 53, - kBinLabelStart = 54, + kBinSpecialReg = 53, + kBinLabel = 54, kBinTypenameStart = 55, kBinHeaderStart = 56, kBinAliasMapStart = 57, - kBinKindTypeViaTypename = 58, - kBinKindSymViaSymname = 59, - kBinKindFuncViaSymname = 60, +//kBinKindTypeViaTypename = 58, +//kBinKindSymViaSymname = 59, +//kBinKindFuncViaSymname = 60, kBinFunctionBodyStart = 61, kBinFormalWordsTypeTagged = 62, kBinFormalWordsRefCounted = 63, @@ -103,8 +103,7 @@ class BinaryMplExport { void Export(const std::string &fname, std::unordered_set *dumpFuncSet); void WriteNum(int64 x); void Write(uint8 b); - void OutputType(TyIdx tyIdx, bool canUseTypename); - void OutputTypeViaTypeName(TyIdx tidx) { OutputType(tidx, true); } + void OutputType(TyIdx tyIdx); void WriteFunctionBodyField(uint64 contentIdx, std::unordered_set *dumpFuncSet); void OutputConst(MIRConst *c); void OutputConstBase(const MIRConst &c); @@ -133,12 +132,11 @@ class BinaryMplExport { void OutputInfoVector(const MIRInfoVector &infoVector, const MapleVector &infoVectorIsString); void OutputFuncIdInfo(MIRFunction *func); void OutputLocalSymbol(MIRSymbol *sym); - void OutputLocalSymTab(const MIRFunction *func); - void OutputPregTab(const MIRFunction *func); - void OutputLabelTab(const MIRFunction *func); + void OutputPreg(MIRPreg *preg); + void OutputLabel(LabelIdx lidx); void OutputLocalTypeNameTab(const MIRTypeNameTable *tyNameTab); void OutputFormalsStIdx(MIRFunction *func); - void OutputFuncViaSymName(PUIdx puIdx); + void OutputFuncViaSym(PUIdx puIdx); void OutputExpression(BaseNode *e); void OutputBaseNode(const BaseNode *b); void OutputReturnValues(const CallReturnVector *retv); @@ -182,6 +180,7 @@ class BinaryMplExport { void ExpandFourBuffSize(); MIRModule &mod; + MIRFunction *curFunc = nullptr; size_t bufI = 0; std::vector buf; std::unordered_map gStrMark; @@ -190,6 +189,9 @@ class BinaryMplExport { std::unordered_map uStrMark; std::unordered_map symMark; std::unordered_map typMark; + std::unordered_map localSymMark; + std::unordered_map localPregMark; + std::unordered_map labelMark; friend class UpdateMplt; std::unordered_map callInfoMark; std::map *func2SEMap = nullptr; diff --git a/src/mapleall/maple_ir/include/bin_mpl_import.h b/src/mapleall/maple_ir/include/bin_mpl_import.h index 3697654872..ee7f909f9b 100644 --- a/src/mapleall/maple_ir/include/bin_mpl_import.h +++ b/src/mapleall/maple_ir/include/bin_mpl_import.h @@ -126,15 +126,14 @@ class BinaryMplImport { void ImportInfoVector(MIRInfoVector &infoVector, MapleVector &infoVectorIsString); void ImportLocalTypeNameTable(MIRTypeNameTable *typeNameTab); void ImportFuncIdInfo(MIRFunction *func); - void ImportLocalSymbol(MIRFunction *func); - void ImportLocalSymTab(MIRFunction *func); - void ImportPregTab(const MIRFunction *func); - void ImportLabelTab(MIRFunction *func); + MIRSymbol *ImportLocalSymbol(MIRFunction *func); + PregIdx ImportPreg(MIRFunction *func); + LabelIdx ImportLabel(MIRFunction *func); void ImportFormalsStIdx(MIRFunction *func); void ImportAliasMap(MIRFunction *func); void ImportSrcPos(SrcPosition &pos); void ImportBaseNode(Opcode &o, PrimType &typ); - PUIdx ImportFuncViaSymName(); + PUIdx ImportFuncViaSym(MIRFunction *func); BaseNode *ImportExpression(MIRFunction *func); void ImportReturnValues(MIRFunction *func, CallReturnVector *retv); BlockNode *ImportBlockNode(MIRFunction *fn); @@ -162,6 +161,9 @@ class BinaryMplImport { std::vector typTab; std::vector funcTab; std::vector symTab; + std::vector localSymTab; + std::vector localPregTab; + std::vector localLabelTab; std::vector callInfoTab; std::vector eaCgTab; std::vector methodSymbols; diff --git a/src/mapleall/maple_ir/include/ir_safe_cast_traits.def b/src/mapleall/maple_ir/include/ir_safe_cast_traits.def index 1439b49d57..14ed1a367b 100644 --- a/src/mapleall/maple_ir/include/ir_safe_cast_traits.def +++ b/src/mapleall/maple_ir/include/ir_safe_cast_traits.def @@ -224,7 +224,9 @@ REGISTER_SAFE_CAST(CallNode, from.GetOpCode() == OP_call || from.GetOpCode() == OP_virtualicallassigned || instance_of(from)); REGISTER_SAFE_CAST(IcallNode, from.GetOpCode() == OP_icall || - from.GetOpCode() == OP_icallassigned); + from.GetOpCode() == OP_icallassigned || + from.GetOpCode() == OP_icallproto || + from.GetOpCode() == OP_icallprotoassigned); REGISTER_SAFE_CAST(IntrinsiccallNode, from.GetOpCode() == OP_intrinsiccall || from.GetOpCode() == OP_intrinsiccallwithtype || from.GetOpCode() == OP_xintrinsiccall || diff --git a/src/mapleall/maple_ir/include/keywords.def b/src/mapleall/maple_ir/include/keywords.def index eddff2f80a..51a603eafa 100644 --- a/src/mapleall/maple_ir/include/keywords.def +++ b/src/mapleall/maple_ir/include/keywords.def @@ -55,7 +55,6 @@ // per-function declaration keywords KEYWORD(framesize) KEYWORD(upformalsize) - KEYWORD(outparmsize) KEYWORD(moduleid) KEYWORD(funcsize) KEYWORD(funcid) diff --git a/src/mapleall/maple_ir/include/mir_builder.h b/src/mapleall/maple_ir/include/mir_builder.h index ac3215724e..64f6a2723c 100755 --- a/src/mapleall/maple_ir/include/mir_builder.h +++ b/src/mapleall/maple_ir/include/mir_builder.h @@ -262,6 +262,8 @@ class MIRBuilder { IcallNode *CreateStmtIcall(const MapleVector &args); IcallNode *CreateStmtIcallAssigned(const MapleVector &args, const MIRSymbol &ret); + IcallNode *CreateStmtIcallproto(const MapleVector &args); + IcallNode *CreateStmtIcallprotoAssigned(const MapleVector &args, const MIRSymbol &ret); // For Call, VirtualCall, SuperclassCall, InterfaceCall IntrinsiccallNode *CreateStmtIntrinsicCall(MIRIntrinsicID idx, const MapleVector &arguments, TyIdx tyIdx = TyIdx()); diff --git a/src/mapleall/maple_ir/include/mir_function.h b/src/mapleall/maple_ir/include/mir_function.h index 0fa62fdac2..5329d87548 100644 --- a/src/mapleall/maple_ir/include/mir_function.h +++ b/src/mapleall/maple_ir/include/mir_function.h @@ -830,24 +830,24 @@ class MIRFunction { callTimes = times; } - uint16 GetFrameSize() const { + uint32 GetFrameSize() const { return frameSize; } - void SetFrameSize(uint16 size) { + void SetFrameSize(uint32 size) { frameSize = size; } - uint16 GetUpFormalSize() const { + uint32 GetUpFormalSize() const { return upFormalSize; } - void SetUpFormalSize(uint16 size) { + void SetUpFormalSize(uint32 size) { upFormalSize = size; } - uint16 GetOutParmSize() const { + uint32 GetOutParmSize() const { return outParmSize; } - void SetOutParmSize(uint16 size) { + void SetOutParmSize(uint32 size) { outParmSize = size; } @@ -1298,9 +1298,9 @@ class MIRFunction { bool isDirty = false; bool fromMpltInline = false; // Whether this function is imported from mplt_inline file or not. uint8_t layoutType = kLayoutUnused; - uint16 frameSize = 0; - uint16 upFormalSize = 0; - uint16 outParmSize = 0; + uint32 frameSize = 0; + uint32 upFormalSize = 0; + uint32 outParmSize = 0; uint16 moduleID = 0; uint32 funcSize = 0; // size of code in words uint32 tempCount = 0; diff --git a/src/mapleall/maple_ir/include/mir_lower.h b/src/mapleall/maple_ir/include/mir_lower.h index 332a6de89f..be479f65a6 100644 --- a/src/mapleall/maple_ir/include/mir_lower.h +++ b/src/mapleall/maple_ir/include/mir_lower.h @@ -86,6 +86,7 @@ class MIRLower { ForeachelemNode *ExpandArrayMrtForeachelemBlock(ForeachelemNode &node); BlockNode *ExpandArrayMrtBlock(BlockNode &block); void AddArrayMrtMpl(BaseNode &exp, BlockNode &newblk); + MIRFuncType *FuncTypeFromFuncPtrExpr(BaseNode *x); void SetLowerME() { lowerPhase |= kShiftLowerMe; } diff --git a/src/mapleall/maple_ir/include/mir_nodes.h b/src/mapleall/maple_ir/include/mir_nodes.h index 0ebf07beff..3481c75c60 100755 --- a/src/mapleall/maple_ir/include/mir_nodes.h +++ b/src/mapleall/maple_ir/include/mir_nodes.h @@ -3304,7 +3304,7 @@ class CallNode : public NaryStmtNode { CallReturnVector returnValues; }; -// icall and icallproto +// icall, icallassigned, icallproto and icallprotoassigned class IcallNode : public NaryStmtNode { public: IcallNode(MapleAllocator &allocator, Opcode o) diff --git a/src/mapleall/maple_ir/include/mir_parser.h b/src/mapleall/maple_ir/include/mir_parser.h index 10d1dd028a..b49370d0ff 100755 --- a/src/mapleall/maple_ir/include/mir_parser.h +++ b/src/mapleall/maple_ir/include/mir_parser.h @@ -134,6 +134,7 @@ class MIRParser { bool ParseStmtIcall(StmtNodePtr&); bool ParseStmtIcallassigned(StmtNodePtr&); bool ParseStmtIcallproto(StmtNodePtr&); + bool ParseStmtIcallprotoassigned(StmtNodePtr&); bool ParseStmtIntrinsiccall(StmtNodePtr&, bool isAssigned); bool ParseStmtIntrinsiccall(StmtNodePtr&); bool ParseStmtIntrinsiccallassigned(StmtNodePtr&); @@ -291,7 +292,6 @@ class MIRParser { bool ParseStmtBlockForType(); bool ParseStmtBlockForFrameSize(); bool ParseStmtBlockForUpformalSize(); - bool ParseStmtBlockForOutParmSize(); bool ParseStmtBlockForModuleID(); bool ParseStmtBlockForFuncSize(); bool ParseStmtBlockForFuncID(); diff --git a/src/mapleall/maple_ir/include/mir_symbol.h b/src/mapleall/maple_ir/include/mir_symbol.h index 2f4e37c80b..4291a0c24b 100644 --- a/src/mapleall/maple_ir/include/mir_symbol.h +++ b/src/mapleall/maple_ir/include/mir_symbol.h @@ -484,12 +484,11 @@ class MIRSymbol { return false; } switch (storageClass) { - case kScFormal: case kScAuto: return true; case kScPstatic: case kScFstatic: - return value.konst == nullptr; + return value.konst == nullptr && !hasPotentialAssignment; default: return false; } @@ -638,7 +637,8 @@ class MIRLabelTable { LabelIdx CreateLabel() { LabelIdx labelIdx = labelTable.size(); - labelTable.push_back(GStrIdx(0)); // insert dummy global string index for anonymous label + GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(std::to_string(labelIdx)); + labelTable.push_back(strIdx); return labelIdx; } diff --git a/src/mapleall/maple_ir/include/mir_type.h b/src/mapleall/maple_ir/include/mir_type.h index d6d32d999b..83585981e9 100644 --- a/src/mapleall/maple_ir/include/mir_type.h +++ b/src/mapleall/maple_ir/include/mir_type.h @@ -1189,14 +1189,6 @@ class MIRStructType : public MIRType { isImported = flag; } - bool IsUsed() const { - return isUsed; - } - - void SetIsUsed(bool flag) { - isUsed = flag; - } - bool IsCPlusPlus() const { return isCPlusPlus; } @@ -1368,7 +1360,6 @@ class MIRStructType : public MIRType { vTableMethods.clear(); iTableMethods.clear(); isImported = false; - isUsed = false; hasVolatileField = false; hasVolatileFieldSet = false; } @@ -1471,7 +1462,6 @@ class MIRStructType : public MIRType { // implementation functions, For interfaces, they are abstact functions. // Weak indicates the actual definition is in another module. bool isImported = false; - bool isUsed = false; bool isCPlusPlus = false; // empty struct in C++ has size 1 byte mutable bool hasVolatileField = false; // for caching computed value mutable bool hasVolatileFieldSet = false; // if true, just read hasVolatileField; @@ -1928,11 +1918,19 @@ class MIRFuncType : public MIRType { } bool IsVarargs() const { - return isVarArgs; + return funcAttrs.GetAttr(FUNCATTR_varargs); } - void SetVarArgs(bool flag) { - isVarArgs = flag; + void SetVarArgs() { + funcAttrs.SetAttr(FUNCATTR_varargs); + } + + bool FirstArgReturn() const { + return funcAttrs.GetAttr(FUNCATTR_firstarg_return); + } + + void SetFirstArgReturn() { + funcAttrs.SetAttr(FUNCATTR_firstarg_return); } const TypeAttrs &GetRetAttrs() const { @@ -1960,7 +1958,8 @@ class MIRFuncType : public MIRType { std::vector paramTypeList; std::vector paramAttrsList; TypeAttrs retAttrs; - bool isVarArgs = false; + public: + FuncAttrs funcAttrs; }; class MIRTypeByName : public MIRType { diff --git a/src/mapleall/maple_ir/include/opcode_info.h b/src/mapleall/maple_ir/include/opcode_info.h index 814f15b2f2..5a82646b11 100644 --- a/src/mapleall/maple_ir/include/opcode_info.h +++ b/src/mapleall/maple_ir/include/opcode_info.h @@ -117,6 +117,7 @@ class OpcodeTable { bool IsICall(Opcode o) const { ASSERT(o < OP_last, "invalid opcode"); return o == OP_icall || o == OP_icallassigned || + o == OP_icallproto || o == OP_icallprotoassigned || o == OP_virtualicall || o == OP_virtualicallassigned || o == OP_interfaceicall || o == OP_interfaceicallassigned; } diff --git a/src/mapleall/maple_ir/include/opcodes.def b/src/mapleall/maple_ir/include/opcodes.def index 34cfb51c8d..0e842141ed 100755 --- a/src/mapleall/maple_ir/include/opcodes.def +++ b/src/mapleall/maple_ir/include/opcodes.def @@ -221,3 +221,4 @@ OPCODE(iassignspoff, IassignFPoffNode, OPCODEISSTMT, 8) OPCODE(blkassignoff, BlkassignoffNode, OPCODEISSTMT, 8) OPCODE(icallproto, IcallNode, (OPCODEISSTMT | OPCODEISVARSIZE | OPCODEHASSSAUSE | OPCODEHASSSADEF | OPCODEISCALL), 8) + OPCODE(icallprotoassigned, IcallNode, (OPCODEISSTMT | OPCODEISVARSIZE | OPCODEHASSSAUSE | OPCODEHASSSADEF | OPCODEISCALL | OPCODEISCALLASSIGNED), 8) diff --git a/src/mapleall/maple_ir/include/opcodes.h b/src/mapleall/maple_ir/include/opcodes.h index ea4ed2c1c9..b9f5e0f8c5 100644 --- a/src/mapleall/maple_ir/include/opcodes.h +++ b/src/mapleall/maple_ir/include/opcodes.h @@ -50,7 +50,7 @@ inline constexpr bool IsCallAssigned(Opcode code) { code == OP_virtualicallassigned || code == OP_superclasscallassigned || code == OP_interfacecallassigned || code == OP_interfaceicallassigned || code == OP_customcallassigned || code == OP_polymorphiccallassigned || - code == OP_icallassigned || code == OP_intrinsiccallassigned || + code == OP_icallassigned || code == OP_icallprotoassigned || code == OP_intrinsiccallassigned || code == OP_xintrinsiccallassigned || code == OP_intrinsiccallwithtypeassigned); } @@ -113,6 +113,8 @@ constexpr bool IsStmtMustRequire(Opcode opcode) { case OP_polymorphiccallassigned: case OP_icall: case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: case OP_intrinsiccall: case OP_xintrinsiccall: case OP_intrinsiccallassigned: diff --git a/src/mapleall/maple_ir/src/bin_func_export.cpp b/src/mapleall/maple_ir/src/bin_func_export.cpp index 263ef34c80..6815c8151d 100644 --- a/src/mapleall/maple_ir/src/bin_func_export.cpp +++ b/src/mapleall/maple_ir/src/bin_func_export.cpp @@ -24,6 +24,10 @@ using namespace std; namespace maple { void BinaryMplExport::OutputInfoVector(const MIRInfoVector &infoVector, const MapleVector &infoVectorIsString) { + if (!mod.IsWithDbgInfo()) { + Write(0); + return; + } WriteNum(infoVector.size()); for (uint32 i = 0; i < infoVector.size(); i++) { OutputStr(infoVector[i].first); @@ -41,99 +45,73 @@ void BinaryMplExport::OutputFuncIdInfo(MIRFunction *func) { WriteNum(func->GetPuidxOrigin()); // the funcid OutputInfoVector(func->GetInfoVector(), func->InfoIsString()); if (mod.GetFlavor() == kFlavorLmbc) { - WriteNum(func->GetUpFormalSize()); WriteNum(func->GetFrameSize()); - WriteNum(func->GetOutParmSize()); } - WriteNum(~kBinFuncIdInfoStart); } void BinaryMplExport::OutputBaseNode(const BaseNode *b) { - WriteNum(b->GetOpCode()); - WriteNum(b->GetPrimType()); + Write(static_cast(b->GetOpCode())); + Write(static_cast(b->GetPrimType())); } void BinaryMplExport::OutputLocalSymbol(MIRSymbol *sym) { - if (sym == nullptr) { - WriteNum(0); + std::unordered_map::iterator it = localSymMark.find(sym); + if (it != localSymMark.end()) { + WriteNum(-(it->second)); return; } + WriteNum(kBinSymbol); - WriteNum(sym->GetStIndex()); // preserve original st index OutputStr(sym->GetNameStrIdx()); WriteNum(sym->GetSKind()); WriteNum(sym->GetStorageClass()); + size_t mark = localSymMark.size(); + localSymMark[sym] = mark; OutputTypeAttrs(sym->GetAttrs()); WriteNum(static_cast(sym->GetIsTmp())); if (sym->GetSKind() == kStVar || sym->GetSKind() == kStFunc) { OutputSrcPos(sym->GetSrcPosition()); } - OutputTypeViaTypeName(sym->GetTyIdx()); + OutputType(sym->GetTyIdx()); if (sym->GetSKind() == kStPreg) { - WriteNum(sym->GetPreg()->GetPregNo()); + OutputPreg(sym->GetPreg()); } else if (sym->GetSKind() == kStConst || sym->GetSKind() == kStVar) { OutputConst(sym->GetKonst()); } else if (sym->GetSKind() == kStFunc) { - OutputFuncViaSymName(sym->GetFunction()->GetPuidx()); - OutputTypeViaTypeName(sym->GetTyIdx()); + OutputFuncViaSym(sym->GetFunction()->GetPuidx()); } else { CHECK_FATAL(false, "should not used"); } } -void BinaryMplExport::OutputLocalSymTab(const MIRFunction *func) { - WriteNum(kBinSymStart); - uint64 outsymSizeIdx = buf.size(); - ExpandFourBuffSize(); /// size of OutSym - int32 size = 0; - - for (uint32 i = 1; i < func->GetSymTab()->GetSymbolTableSize(); i++) { - MIRSymbol *s = func->GetSymTab()->GetSymbolFromStIdx(i); - ASSERT(s != nullptr, "null ptr check"); - if (s->IsDeleted()) { - OutputLocalSymbol(nullptr); - } else { - OutputLocalSymbol(s); - } - size++; +void BinaryMplExport::OutputPreg(MIRPreg *preg) { + if (preg->GetPregNo() < 0) { + WriteNum(kBinSpecialReg); + Write(-preg->GetPregNo()); + return; } - - Fixup(outsymSizeIdx, size); - WriteNum(~kBinSymStart); -} - -void BinaryMplExport::OutputPregTab(const MIRFunction *func) { - WriteNum(kBinPregStart); - uint64 outRegSizeIdx = buf.size(); - ExpandFourBuffSize(); /// size of OutReg - int32 size = 0; - - for (uint32 i = 1; i < func->GetPregTab()->Size(); ++i) { - MIRPreg *mirpreg = func->GetPregTab()->PregFromPregIdx(static_cast(i)); - if (mirpreg == nullptr) { - WriteNum(0); - size++; - continue; - } - WriteNum(kBinPreg); - WriteNum(mirpreg->GetPregNo()); - TyIdx tyIdx = (mirpreg->GetMIRType() == nullptr) ? TyIdx(0) : mirpreg->GetMIRType()->GetTypeIndex(); - OutputTypeViaTypeName(tyIdx); - WriteNum(mirpreg->GetPrimType()); - size++; + std::unordered_map::iterator it = localPregMark.find(preg); + if (it != localPregMark.end()) { + WriteNum(-(it->second)); + return; } - Fixup(outRegSizeIdx, size); - WriteNum(~kBinPregStart); + WriteNum(kBinPreg); + Write(static_cast(preg->GetPrimType())); + size_t mark = localPregMark.size(); + localPregMark[preg] = mark; } -void BinaryMplExport::OutputLabelTab(const MIRFunction *func) { - WriteNum(kBinLabelStart); - WriteNum(static_cast(func->GetLabelTab()->Size()-1)); // entry 0 is skipped - for (uint32 i = 1; i < func->GetLabelTab()->Size(); i++) { - OutputStr(func->GetLabelTab()->GetLabelTable()[i]); +void BinaryMplExport::OutputLabel(LabelIdx lidx) { + std::unordered_map::iterator it = labelMark.find(lidx); + if (it != labelMark.end()) { + WriteNum(-(it->second)); + return; } - WriteNum(~kBinLabelStart); + + WriteNum(kBinLabel); + size_t mark = labelMark.size(); + labelMark[lidx] = mark; } void BinaryMplExport::OutputLocalTypeNameTab(const MIRTypeNameTable *typeNameTab) { @@ -141,18 +119,16 @@ void BinaryMplExport::OutputLocalTypeNameTab(const MIRTypeNameTable *typeNameTab WriteNum(static_cast(typeNameTab->Size())); for (std::pair it : typeNameTab->GetGStrIdxToTyIdxMap()) { OutputStr(it.first); - OutputTypeViaTypeName(it.second); + OutputType(it.second); } - WriteNum(~kBinTypenameStart); } void BinaryMplExport::OutputFormalsStIdx(MIRFunction *func) { WriteNum(kBinFormalStart); WriteNum(func->GetFormalDefVec().size()); for (FormalDef formalDef : func->GetFormalDefVec()) { - WriteNum(formalDef.formalSym->GetStIndex()); + OutputLocalSymbol(formalDef.formalSym); } - WriteNum(~kBinFormalStart); } void BinaryMplExport::OutputAliasMap(MapleMap &aliasVarMap) { @@ -161,21 +137,18 @@ void BinaryMplExport::OutputAliasMap(MapleMap &aliasVarMa for (std::pair it : aliasVarMap) { OutputStr(it.first); OutputStr(it.second.memPoolStrIdx); - OutputTypeViaTypeName(it.second.tyIdx); + OutputType(it.second.tyIdx); OutputStr(it.second.sigStrIdx); } - WriteNum(~kBinAliasMapStart); } -void BinaryMplExport::OutputFuncViaSymName(PUIdx puIdx) { +void BinaryMplExport::OutputFuncViaSym(PUIdx puIdx) { MIRFunction *func = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx()); - WriteNum(kBinKindFuncViaSymname); - OutputStr(funcSt->GetNameStrIdx()); + OutputSymbol(funcSt); } void BinaryMplExport::OutputExpression(BaseNode *e) { - WriteNum(kBinOpExpression); OutputBaseNode(e); switch (e->GetOpCode()) { // leaf @@ -191,17 +164,17 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { } case OP_addroflabel: { AddroflabelNode *lNode = static_cast(e); - WriteNum(lNode->GetOffset()); + OutputLabel(lNode->GetOffset()); return; } case OP_addroffunc: { AddroffuncNode *addrNode = static_cast(e); - OutputFuncViaSymName(addrNode->GetPUIdx()); + OutputFuncViaSym(addrNode->GetPUIdx()); return; } case OP_sizeoftype: { SizeoftypeNode *sot = static_cast(e); - OutputTypeViaTypeName(sot->GetTyIdx()); + OutputType(sot->GetTyIdx()); return; } case OP_addrof: @@ -220,24 +193,23 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { } WriteNum(stIdx.Scope()); if (stIdx.Islocal()) { - WriteNum(stIdx.Idx()); // preserve original st index + OutputLocalSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx)); } else { - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(stIdx.Idx()); - WriteNum(kBinKindSymViaSymname); - OutputStr(sym->GetNameStrIdx()); + OutputSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx)); } return; } case OP_regread: { RegreadNode *regreadNode = static_cast(e); - WriteNum(regreadNode->GetRegIdx()); + MIRPreg *preg = curFunc->GetPregTab()->PregFromPregIdx(regreadNode->GetRegIdx()); + OutputPreg(preg); return; } case OP_gcmalloc: case OP_gcpermalloc: case OP_stackmalloc: { GCMallocNode *gcNode = static_cast(e); - OutputTypeViaTypeName(gcNode->GetTyIdx()); + OutputType(gcNode->GetTyIdx()); return; } // unary @@ -246,18 +218,18 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { case OP_floor: case OP_trunc: { TypeCvtNode *typecvtNode = static_cast(e); - WriteNum(typecvtNode->FromType()); + Write(static_cast(typecvtNode->FromType())); break; } case OP_retype: { RetypeNode *retypeNode = static_cast(e); - OutputTypeViaTypeName(retypeNode->GetTyIdx()); + OutputType(retypeNode->GetTyIdx()); break; } case OP_iread: case OP_iaddrof: { IreadNode *irNode = static_cast(e); - OutputTypeViaTypeName(irNode->GetTyIdx()); + OutputType(irNode->GetTyIdx()); WriteNum(irNode->GetFieldID()); break; } @@ -275,20 +247,20 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { case OP_zext: case OP_extractbits: { ExtractbitsNode *extNode = static_cast(e); - WriteNum(extNode->GetBitsOffset()); - WriteNum(extNode->GetBitsSize()); + Write(extNode->GetBitsOffset()); + Write(extNode->GetBitsSize()); break; } case OP_depositbits: { DepositbitsNode *dbNode = static_cast(e); - WriteNum(dbNode->GetBitsOffset()); - WriteNum(dbNode->GetBitsSize()); + Write(dbNode->GetBitsOffset()); + Write(dbNode->GetBitsSize()); break; } case OP_gcmallocjarray: case OP_gcpermallocjarray: { JarrayMallocNode *gcNode = static_cast(e); - OutputTypeViaTypeName(gcNode->GetTyIdx()); + OutputType(gcNode->GetTyIdx()); break; } // binary @@ -321,13 +293,13 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { case OP_cmpl: case OP_cmp: { CompareNode *cmpNode = static_cast(e); - WriteNum(cmpNode->GetOpndType()); + Write(static_cast(cmpNode->GetOpndType())); break; } case OP_resolveinterfacefunc: case OP_resolvevirtualfunc: { ResolveFuncNode *rsNode = static_cast(e); - OutputFuncViaSymName(rsNode->GetPuIdx()); + OutputFuncViaSym(rsNode->GetPuIdx()); break; } // ternary @@ -337,8 +309,8 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { // nary case OP_array: { ArrayNode *arrNode = static_cast(e); - OutputTypeViaTypeName(arrNode->GetTyIdx()); - WriteNum(static_cast(arrNode->GetBoundsCheck())); + OutputType(arrNode->GetTyIdx()); + Write(static_cast(arrNode->GetBoundsCheck())); WriteNum(static_cast(arrNode->NumOpnds())); break; } @@ -351,7 +323,7 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { case OP_intrinsicopwithtype: { IntrinsicopNode *intrnNode = static_cast(e); WriteNum(intrnNode->GetIntrinsic()); - OutputTypeViaTypeName(intrnNode->GetTyIdx()); + OutputType(intrnNode->GetTyIdx()); WriteNum(static_cast(intrnNode->NumOpnds())); break; } @@ -366,6 +338,9 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { static SrcPosition lastOutputSrcPosition; void BinaryMplExport::OutputSrcPos(const SrcPosition &pos) { + if (!mod.IsWithDbgInfo()) { + return; + } if (pos.FileNum() == 0 || pos.LineNum() == 0) { // error case, so output 0 WriteNum(lastOutputSrcPosition.RawData()); WriteNum(lastOutputSrcPosition.LineNum()); @@ -380,9 +355,15 @@ void BinaryMplExport::OutputReturnValues(const CallReturnVector *retv) { WriteNum(kBinReturnvals); WriteNum(static_cast(retv->size())); for (uint32 i = 0; i < retv->size(); i++) { - WriteNum((*retv)[i].first.Idx()); - WriteNum((*retv)[i].second.GetFieldID()); - WriteNum((*retv)[i].second.GetPregIdx()); + RegFieldPair rfp = (*retv)[i].second; + if (rfp.IsReg()) { + MIRPreg *preg = curFunc->GetPregTab()->PregFromPregIdx(rfp.GetPregIdx()); + OutputPreg(preg); + } else { + WriteNum(0); + WriteNum((rfp.GetFieldID())); + OutputLocalSymbol(curFunc->GetLocalOrGlobalSymbol((*retv)[i].first)); + } } } @@ -398,7 +379,6 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { ExpandFourBuffSize(); // place holder, Fixup later for (StmtNode *s = block->GetFirst(); s; s = s->GetNext()) { bool doneWithOpnds = false; - WriteNum(kBinOpStatement); OutputSrcPos(s->GetSrcPos()); WriteNum(s->GetOpCode()); switch (s->GetOpCode()) { @@ -417,36 +397,35 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { } WriteNum(stIdx.Scope()); if (stIdx.Islocal()) { - WriteNum(stIdx.Idx()); // preserve original st index + OutputLocalSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx)); } else { - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(stIdx.Idx()); - WriteNum(kBinKindSymViaSymname); - OutputStr(sym->GetNameStrIdx()); + OutputSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx)); } break; } case OP_regassign: { RegassignNode *rass = static_cast(s); - WriteNum(rass->GetPrimType()); - WriteNum(rass->GetRegIdx()); + Write(static_cast(rass->GetPrimType())); + MIRPreg *preg = curFunc->GetPregTab()->PregFromPregIdx(rass->GetRegIdx()); + OutputPreg(preg); break; } case OP_iassign: { IassignNode *iass = static_cast(s); - OutputTypeViaTypeName(iass->GetTyIdx()); + OutputType(iass->GetTyIdx()); WriteNum(iass->GetFieldID()); break; } case OP_iassignoff: { IassignoffNode *iassoff = static_cast(s); - WriteNum(iassoff->GetPrimType()); + Write(static_cast(iassoff->GetPrimType())); WriteNum(iassoff->GetOffset()); break; } case OP_iassignspoff: case OP_iassignfpoff: { IassignFPoffNode *iassfpoff = static_cast(s); - WriteNum(iassfpoff->GetPrimType()); + Write(static_cast(iassfpoff->GetPrimType())); WriteNum(iassfpoff->GetOffset()); break; } @@ -466,9 +445,9 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { case OP_customcall: case OP_polymorphiccall: { CallNode *callnode = static_cast(s); - OutputFuncViaSymName(callnode->GetPUIdx()); + OutputFuncViaSym(callnode->GetPUIdx()); if (s->GetOpCode() == OP_polymorphiccall) { - OutputTypeViaTypeName(static_cast(callnode)->GetTyIdx()); + OutputType(static_cast(callnode)->GetTyIdx()); } WriteNum(static_cast(s->NumOpnds())); break; @@ -481,15 +460,15 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { case OP_interfaceicallassigned: case OP_customcallassigned: { CallNode *callnode = static_cast(s); - OutputFuncViaSymName(callnode->GetPUIdx()); + OutputFuncViaSym(callnode->GetPUIdx()); OutputReturnValues(&callnode->GetReturnVec()); WriteNum(static_cast(s->NumOpnds())); break; } case OP_polymorphiccallassigned: { CallNode *callnode = static_cast(s); - OutputFuncViaSymName(callnode->GetPUIdx()); - OutputTypeViaTypeName(callnode->GetTyIdx()); + OutputFuncViaSym(callnode->GetPUIdx()); + OutputType(callnode->GetTyIdx()); OutputReturnValues(&callnode->GetReturnVec()); WriteNum(static_cast(s->NumOpnds())); break; @@ -497,13 +476,14 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { case OP_icallproto: case OP_icall: { IcallNode *icallnode = static_cast(s); - OutputTypeViaTypeName(icallnode->GetRetTyIdx()); + OutputType(icallnode->GetRetTyIdx()); WriteNum(static_cast(s->NumOpnds())); break; } + case OP_icallprotoassigned: case OP_icallassigned: { IcallNode *icallnode = static_cast(s); - OutputTypeViaTypeName(icallnode->GetRetTyIdx()); + OutputType(icallnode->GetRetTyIdx()); OutputReturnValues(&icallnode->GetReturnVec()); WriteNum(static_cast(s->NumOpnds())); break; @@ -526,14 +506,14 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { case OP_intrinsiccallwithtype: { IntrinsiccallNode *intrnNode = static_cast(s); WriteNum(intrnNode->GetIntrinsic()); - OutputTypeViaTypeName(intrnNode->GetTyIdx()); + OutputType(intrnNode->GetTyIdx()); WriteNum(static_cast(s->NumOpnds())); break; } case OP_intrinsiccallwithtypeassigned: { IntrinsiccallNode *intrnNode = static_cast(s); WriteNum(intrnNode->GetIntrinsic()); - OutputTypeViaTypeName(intrnNode->GetTyIdx()); + OutputType(intrnNode->GetTyIdx()); OutputReturnValues(&intrnNode->GetReturnVec()); WriteNum(static_cast(s->NumOpnds())); break; @@ -568,28 +548,28 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { } case OP_label: { LabelNode *lNode = static_cast(s); - WriteNum(lNode->GetLabelIdx()); + OutputLabel(lNode->GetLabelIdx()); break; } case OP_goto: case OP_gosub: { GotoNode *gtoNode = static_cast(s); - WriteNum(gtoNode->GetOffset()); + OutputLabel(gtoNode->GetOffset()); break; } case OP_brfalse: case OP_brtrue: { CondGotoNode *cgotoNode = static_cast(s); - WriteNum(cgotoNode->GetOffset()); + OutputLabel(cgotoNode->GetOffset()); break; } case OP_switch: { SwitchNode *swNode = static_cast(s); - WriteNum(swNode->GetDefaultLabel()); + OutputLabel(swNode->GetDefaultLabel()); WriteNum(static_cast(swNode->GetSwitchTable().size())); for (CasePair cpair : swNode->GetSwitchTable()) { WriteNum(cpair.first); - WriteNum(cpair.second); + OutputLabel(cpair.second); } break; } @@ -599,14 +579,14 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { WriteNum(static_cast(rgoto->GetRangeGotoTable().size())); for (SmallCasePair cpair : rgoto->GetRangeGotoTable()) { WriteNum(cpair.first); - WriteNum(cpair.second); + OutputLabel(cpair.second); } break; } case OP_jstry: { JsTryNode *tryNode = static_cast(s); - WriteNum(tryNode->GetCatchOffset()); - WriteNum(tryNode->GetFinallyOffset()); + OutputLabel(tryNode->GetCatchOffset()); + OutputLabel(tryNode->GetFinallyOffset()); break; } case OP_cpptry: @@ -614,7 +594,7 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { TryNode *tryNode = static_cast(s); WriteNum(static_cast(tryNode->GetOffsetsCount())); for (LabelIdx lidx : tryNode->GetOffsets()) { - WriteNum(lidx); + OutputLabel(lidx); } break; } @@ -622,7 +602,7 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { CatchNode *catchNode = static_cast(s); WriteNum(static_cast(catchNode->GetExceptionTyIdxVec().size())); for (TyIdx tidx : catchNode->GetExceptionTyIdxVec()) { - OutputTypeViaTypeName(tidx); + OutputType(tidx); } break; } @@ -679,7 +659,7 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { count = asmNode->gotoLabels.size(); WriteNum(static_cast(count)); for (size_t i = 0; i < count; ++i) { - WriteNum(asmNode->gotoLabels[i]); + OutputLabel(asmNode->gotoLabels[i]); } // the inputs WriteNum(asmNode->NumOpnds()); @@ -714,6 +694,7 @@ void BinaryMplExport::WriteFunctionBodyField(uint64 contentIdx, std::unordered_s if (not2mplt) { for (MIRFunction *func : GetMIRModule().GetFunctionList()) { + curFunc = func; if (func->GetAttr(FUNCATTR_optimized)) { continue; } @@ -734,12 +715,15 @@ void BinaryMplExport::WriteFunctionBodyField(uint64 contentIdx, std::unordered_s continue; } } + localSymMark.clear(); + localSymMark[nullptr] = 0; + localPregMark.clear(); + localPregMark[nullptr] = 0; + labelMark.clear(); + labelMark[0] = 0; OutputFunction(func->GetPuidx()); CHECK_FATAL(func->GetBody() != nullptr, "WriteFunctionBodyField: no function body"); OutputFuncIdInfo(func); - OutputPregTab(func); - OutputLocalSymTab(func); - OutputLabelTab(func); OutputLocalTypeNameTab(func->GetTypeNameTab()); OutputFormalsStIdx(func); if (mod.GetFlavor() < kMmpl) { @@ -753,7 +737,6 @@ void BinaryMplExport::WriteFunctionBodyField(uint64 contentIdx, std::unordered_s Fixup(totalSizeIdx, static_cast(buf.size() - totalSizeIdx)); Fixup(outFunctionBodySizeIdx, size); - WriteNum(~kBinFunctionBodyStart); return; } } // namespace maple diff --git a/src/mapleall/maple_ir/src/bin_func_import.cpp b/src/mapleall/maple_ir/src/bin_func_import.cpp index 959784554b..b23b6895f4 100644 --- a/src/mapleall/maple_ir/src/bin_func_import.cpp +++ b/src/mapleall/maple_ir/src/bin_func_import.cpp @@ -44,29 +44,27 @@ void BinaryMplImport::ImportFuncIdInfo(MIRFunction *func) { func->SetPuidxOrigin(static_cast(ReadNum())); ImportInfoVector(func->GetInfoVector(), func->InfoIsString()); if (mod.GetFlavor() == kFlavorLmbc) { - func->SetUpFormalSize(static_cast(ReadNum())); func->SetFrameSize(static_cast(ReadNum())); - func->SetOutParmSize(static_cast(ReadNum())); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinFuncIdInfoStart, "pattern mismatch in ImportFuncIdInfo()"); } void BinaryMplImport::ImportBaseNode(Opcode &o, PrimType &typ) { - o = (Opcode)ReadNum(); - typ = (PrimType)ReadNum(); + o = (Opcode)Read(); + typ = (PrimType)Read(); } -void BinaryMplImport::ImportLocalSymbol(MIRFunction *func) { +MIRSymbol *BinaryMplImport::ImportLocalSymbol(MIRFunction *func) { int64 tag = ReadNum(); if (tag == 0) { - func->GetSymTab()->PushNullSymbol(); - return; + return nullptr; } + if (tag < 0) { + CHECK_FATAL(static_cast(-tag) < localSymTab.size(), "index out of bounds"); + return localSymTab.at(-tag); + } CHECK_FATAL(tag == kBinSymbol, "expecting kBinSymbol in ImportLocalSymbol()"); - auto indx = static_cast(ReadNum()); - CHECK_FATAL(indx == func->GetSymTab()->GetSymbolTableSize(), "inconsistant local stIdx"); MIRSymbol *sym = func->GetSymTab()->CreateSymbol(kScopeLocal); + localSymTab.push_back(sym); sym->SetNameStrIdx(ImportStr()); (void)func->GetSymTab()->AddToStringSymbolMap(*sym); sym->SetSKind((MIRSymKind)ReadNum()); @@ -78,66 +76,52 @@ void BinaryMplImport::ImportLocalSymbol(MIRFunction *func) { } sym->SetTyIdx(ImportType()); if (sym->GetSKind() == kStPreg) { - auto thepregno = static_cast(ReadNum()); - MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx()); - PregIdx pregidx = func->GetPregTab()->EnterPregNo(thepregno, mirType->GetPrimType(), mirType); - MIRPregTable *pregTab = func->GetPregTab(); - MIRPreg *preg = pregTab->PregFromPregIdx(pregidx); - preg->SetPrimType(mirType->GetPrimType()); + PregIdx pregidx = ImportPreg(func); + MIRPreg *preg = func->GetPregTab()->PregFromPregIdx(pregidx); sym->SetPreg(preg); } else if (sym->GetSKind() == kStConst || sym->GetSKind() == kStVar) { sym->SetKonst(ImportConst(func)); } else if (sym->GetSKind() == kStFunc) { - PUIdx puIdx = ImportFuncViaSymName(); - TyIdx tyIdx = ImportType(); - sym->SetTyIdx(tyIdx); + PUIdx puIdx = ImportFuncViaSym(func); sym->SetFunction(GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx)); } + return sym; } -void BinaryMplImport::ImportLocalSymTab(MIRFunction *func) { +PregIdx BinaryMplImport::ImportPreg(MIRFunction *func) { int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinSymStart, "kBinSymStart expected in ImportLocalSymTab()"); - int32 size = ReadInt(); - for (int64 i = 0; i < size; ++i) { - ImportLocalSymbol(func); + if (tag == 0) { + return 0; } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinSymStart, "pattern mismatch in ImportLocalSymTab()"); -} - -void BinaryMplImport::ImportPregTab(const MIRFunction *func) { - int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinPregStart, "kBinPregStart expected in ImportPregTab()"); - int32 size = ReadInt(); - for (int64 i = 0; i < size; ++i) { - int64 nextTag = ReadNum(); - if (nextTag == 0) { - func->GetPregTab()->GetPregTable().push_back(nullptr); - continue; - } - CHECK_FATAL(nextTag == kBinPreg, "expecting kBinPreg in ImportPregTab()"); - auto pregNo = static_cast(ReadNum()); - TyIdx tyIdx = ImportType(); - MIRType *ty = (tyIdx == 0) ? nullptr : GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); - PrimType primType = (PrimType)ReadNum(); - CHECK_FATAL(ty == nullptr || primType == ty->GetPrimType(), "ImportPregTab: inconsistent primitive type"); - (void)func->GetPregTab()->EnterPregNo(pregNo, primType, ty); + if (tag == kBinSpecialReg) { + return -Read(); + } + if (tag < 0) { + CHECK_FATAL(static_cast(-tag) < localPregTab.size(), "index out of bounds"); + return localPregTab.at(-tag); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinPregStart, "pattern mismatch in ImportPregTab()"); + CHECK_FATAL(tag == kBinPreg, "expecting kBinPreg in ImportPreg()"); + + PrimType primType = (PrimType)Read(); + PregIdx pidx = func->GetPregTab()->CreatePreg(primType); + localPregTab.push_back(pidx); + return pidx; } -void BinaryMplImport::ImportLabelTab(MIRFunction *func) { +LabelIdx BinaryMplImport::ImportLabel(MIRFunction *func) { int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinLabelStart, "kBinLabelStart expected in ImportLabelTab()"); - int64 size = ReadNum(); - for (int64 i = 0; i < size; ++i) { - GStrIdx gStrIdx = ImportStr(); - (void)func->GetLabelTab()->AddLabel(gStrIdx); + if (tag == 0) { + return 0; + } + if (tag < 0) { + CHECK_FATAL(static_cast(-tag) < localLabelTab.size(), "index out of bounds"); + return localLabelTab.at(-tag); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinLabelStart, "pattern mismatch in ImportLabelTab()"); + CHECK_FATAL(tag == kBinLabel, "kBinLabel expected in ImportLabel()"); + + LabelIdx lidx = func->GetLabelTab()->CreateLabel(); + localLabelTab.push_back(lidx); + return lidx; } void BinaryMplImport::ImportLocalTypeNameTable(MIRTypeNameTable *typeNameTab) { @@ -149,8 +133,6 @@ void BinaryMplImport::ImportLocalTypeNameTable(MIRTypeNameTable *typeNameTab) { TyIdx tyIdx = ImportType(); typeNameTab->SetGStrIdxToTyIdx(strIdx, tyIdx); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinTypenameStart, "pattern mismatch in ImportTypenametab()"); } void BinaryMplImport::ImportFormalsStIdx(MIRFunction *func) { @@ -158,11 +140,8 @@ void BinaryMplImport::ImportFormalsStIdx(MIRFunction *func) { CHECK_FATAL(tag == kBinFormalStart, "kBinFormalStart expected in ImportFormalsStIdx()"); auto size = ReadNum(); for (int64 i = 0; i < size; ++i) { - uint32 indx = static_cast(ReadNum()); - func->GetFormalDefVec()[static_cast(i)].formalSym = func->GetSymTab()->GetSymbolFromStIdx(indx); + func->GetFormalDefVec()[static_cast(i)].formalSym = ImportLocalSymbol(func); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinFormalStart, "pattern mismatch in ImportFormalsStIdx()"); } void BinaryMplImport::ImportAliasMap(MIRFunction *func) { @@ -177,23 +156,15 @@ void BinaryMplImport::ImportAliasMap(MIRFunction *func) { (void)ImportStr(); // not assigning to mimic parser func->GetAliasVarMap()[strIdx] = aliasvars; } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinAliasMapStart, "pattern mismatch in ImportAliasMap()"); } -PUIdx BinaryMplImport::ImportFuncViaSymName() { - int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinKindFuncViaSymname, "kBinKindFuncViaSymname expected"); - GStrIdx strIdx = ImportStr(); - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx); - ASSERT(sym != nullptr, "null ptr check"); - MIRFunction *func = sym->GetFunction(); - return func->GetPuidx(); +PUIdx BinaryMplImport::ImportFuncViaSym(MIRFunction *func) { + MIRSymbol *sym = InSymbol(func); + MIRFunction *f = sym->GetFunction(); + return f->GetPuidx(); } BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { - int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinOpExpression, "kBinOpExpression expected"); Opcode op; PrimType typ; ImportBaseNode(op, typ); @@ -213,13 +184,15 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { } case OP_addroflabel: { AddroflabelNode *alabNode = mod.CurFuncCodeMemPool()->New(); - alabNode->SetOffset(static_cast(ReadNum())); + alabNode->SetOffset(ImportLabel(func)); alabNode->SetPrimType(typ); (void)func->GetLabelTab()->addrTakenLabels.insert(alabNode->GetOffset()); return alabNode; } case OP_addroffunc: { - PUIdx puIdx = ImportFuncViaSymName(); + PUIdx puIdx = ImportFuncViaSym(func); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFuncTable()[puIdx]; + f->GetFuncSymbol()->SetAppearsInCode(true); AddroffuncNode *addrNode = mod.CurFuncCodeMemPool()->New(typ, puIdx); return addrNode; } @@ -235,19 +208,18 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { int32 num = static_cast(ReadNum()); StIdx stIdx; stIdx.SetScope(static_cast(ReadNum())); + MIRSymbol *sym = nullptr; if (stIdx.Islocal()) { - stIdx.SetIdx(static_cast(ReadNum())); + sym = ImportLocalSymbol(func); + CHECK_FATAL(sym != nullptr, "null ptr check"); } else { - int32 stag = static_cast(ReadNum()); - CHECK_FATAL(stag == kBinKindSymViaSymname, "kBinKindSymViaSymname expected"); - GStrIdx strIdx = ImportStr(); - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx); - ASSERT(sym != nullptr, "null ptr check"); + sym = InSymbol(func); + CHECK_FATAL(sym != nullptr, "null ptr check"); if (op == OP_addrof) { sym->SetHasPotentialAssignment(); } - stIdx.SetIdx(sym->GetStIdx().Idx()); } + stIdx.SetIdx(sym->GetStIdx().Idx()); if (op == OP_addrof || op == OP_dread) { AddrofNode *drNode = mod.CurFuncCodeMemPool()->New(op); drNode->SetPrimType(typ); @@ -264,7 +236,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { } case OP_regread: { RegreadNode *regreadNode = mod.CurFuncCodeMemPool()->New(); - regreadNode->SetRegIdx(static_cast(ReadNum())); + regreadNode->SetRegIdx(ImportPreg(func)); regreadNode->SetPrimType(typ); return regreadNode; } @@ -293,7 +265,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_floor: case OP_trunc: { TypeCvtNode *typecvtNode = mod.CurFuncCodeMemPool()->New(op, typ); - typecvtNode->SetFromType((PrimType)ReadNum()); + typecvtNode->SetFromType((PrimType)Read()); typecvtNode->SetOpnd(ImportExpression(func), 0); return typecvtNode; } @@ -326,15 +298,15 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_zext: case OP_extractbits: { ExtractbitsNode *extNode = mod.CurFuncCodeMemPool()->New(op, typ); - extNode->SetBitsOffset(static_cast(ReadNum())); - extNode->SetBitsSize(static_cast(ReadNum())); + extNode->SetBitsOffset(Read()); + extNode->SetBitsSize(Read()); extNode->SetOpnd(ImportExpression(func), 0); return extNode; } case OP_depositbits: { DepositbitsNode *dbNode = mod.CurFuncCodeMemPool()->New(op, typ); - dbNode->SetBitsOffset(static_cast(ReadNum())); - dbNode->SetBitsSize(static_cast(ReadNum())); + dbNode->SetBitsOffset(ReadNum()); + dbNode->SetBitsSize(ReadNum()); dbNode->SetOpnd(ImportExpression(func), 0); dbNode->SetOpnd(ImportExpression(func), 1); return dbNode; @@ -379,7 +351,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_cmpl: case OP_cmp: { CompareNode *cmpNode = mod.CurFuncCodeMemPool()->New(op, typ); - cmpNode->SetOpndType((PrimType)ReadNum()); + cmpNode->SetOpndType((PrimType)Read()); cmpNode->SetOpnd(ImportExpression(func), 0); cmpNode->SetOpnd(ImportExpression(func), 1); return cmpNode; @@ -387,7 +359,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_resolveinterfacefunc: case OP_resolvevirtualfunc: { ResolveFuncNode *rsNode = mod.CurFuncCodeMemPool()->New(op, typ); - rsNode->SetPUIdx(ImportFuncViaSymName()); + rsNode->SetPUIdx(ImportFuncViaSym(func)); rsNode->SetOpnd(ImportExpression(func), 0); rsNode->SetOpnd(ImportExpression(func), 1); return rsNode; @@ -403,7 +375,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { // nary case OP_array: { TyIdx tidx = ImportType(); - auto boundsCheck = static_cast(ReadNum()); + bool boundsCheck = static_cast(Read()); ArrayNode *arrNode = mod.CurFuncCodeMemPool()->New(func->GetCodeMPAllocator(), typ, tidx, boundsCheck); auto n = static_cast(ReadNum()); @@ -436,12 +408,15 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { return intrnNode; } default: - CHECK_FATAL(false, "Unhandled op %d", tag); + CHECK_FATAL(false, "Unhandled op %d", op); break; } } void BinaryMplImport::ImportSrcPos(SrcPosition &pos) { + if (!mod.IsWithDbgInfo()) { + return; + } pos.SetRawData(static_cast(ReadNum())); pos.SetLineNum(static_cast(ReadNum())); } @@ -451,15 +426,16 @@ void BinaryMplImport::ImportReturnValues(MIRFunction *func, CallReturnVector *re CHECK_FATAL(tag == kBinReturnvals, "expecting return values"); auto size = static_cast(ReadNum()); for (uint32 i = 0; i < size; ++i) { - uint32 idx = static_cast(ReadNum()); - FieldID fid = static_cast(ReadNum()); - PregIdx ridx = static_cast(ReadNum()); - retv->push_back(std::make_pair(StIdx(kScopeLocal, idx), RegFieldPair(fid, ridx))); - if (idx == 0) { + RegFieldPair rfp; + rfp.SetPregIdx(ImportPreg(func)); + if (rfp.IsReg()) { + retv->push_back(std::make_pair(StIdx(), rfp)); continue; } - MIRSymbol *lsym = func->GetSymTab()->GetSymbolFromStIdx(idx, false); - ASSERT(lsym != nullptr, "null ptr check"); + rfp.SetFieldID(static_cast(ReadNum())); + MIRSymbol *lsym = ImportLocalSymbol(func); + CHECK_FATAL(lsym != nullptr, "null ptr check"); + retv->push_back(std::make_pair(lsym->GetStIdx(), rfp)); if (lsym->GetName().find("L_STR") == 0) { MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(lsym->GetTyIdx()); CHECK_FATAL(ty->GetKind() == kTypePointer, "Pointer type expected for L_STR prefix"); @@ -480,8 +456,6 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { ImportSrcPos(block->GetSrcPos()); int32 size = ReadInt(); for (int32 k = 0; k < size; ++k) { - tag = ReadNum(); - CHECK_FATAL(tag == kBinOpStatement, "kBinOpStatement expected"); SrcPosition thesrcPosition; ImportSrcPos(thesrcPosition); op = (Opcode)ReadNum(); @@ -496,17 +470,16 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { int32 num = static_cast(ReadNum()); StIdx stIdx; stIdx.SetScope(static_cast(ReadNum())); + MIRSymbol *sym = nullptr; if (stIdx.Islocal()) { - stIdx.SetIdx(static_cast(ReadNum())); + sym = ImportLocalSymbol(func); + CHECK_FATAL(sym != nullptr, "null ptr check"); } else { - int32 stag = static_cast(ReadNum()); - CHECK_FATAL(stag == kBinKindSymViaSymname, "kBinKindSymViaSymname expected"); - GStrIdx strIdx = ImportStr(); - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx); - ASSERT(sym != nullptr, "null ptr check"); + sym = InSymbol(func); + CHECK_FATAL(sym != nullptr, "null ptr check"); sym->SetHasPotentialAssignment(); - stIdx.SetIdx(sym->GetStIdx().Idx()); } + stIdx.SetIdx(sym->GetStIdx().Idx()); if (op == OP_dassign) { DassignNode *s = func->GetCodeMemPool()->New(); s->SetStIdx(stIdx); @@ -525,8 +498,8 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_regassign: { RegassignNode *s = func->GetCodeMemPool()->New(); - s->SetPrimType((PrimType)ReadNum()); - s->SetRegIdx(static_cast(ReadNum())); + s->SetPrimType((PrimType)Read()); + s->SetRegIdx(ImportPreg(func)); s->SetOpnd(ImportExpression(func), 0); stmt = s; break; @@ -542,7 +515,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_iassignoff: { IassignoffNode *s = func->GetCodeMemPool()->New(); - s->SetPrimType((PrimType)ReadNum()); + s->SetPrimType((PrimType)Read()); s->SetOffset(static_cast(ReadNum())); s->SetOpnd(ImportExpression(func), 0); s->SetOpnd(ImportExpression(func), 1); @@ -552,7 +525,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { case OP_iassignspoff: case OP_iassignfpoff: { IassignFPoffNode *s = func->GetCodeMemPool()->New(op); - s->SetPrimType((PrimType)ReadNum()); + s->SetPrimType((PrimType)Read()); s->SetOffset(static_cast(ReadNum())); s->SetOpnd(ImportExpression(func), 0); stmt = s; @@ -577,7 +550,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { case OP_interfaceicall: case OP_customcall: { CallNode *s = func->GetCodeMemPool()->New(mod, op); - s->SetPUIdx(ImportFuncViaSymName()); + s->SetPUIdx(ImportFuncViaSym(func)); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx()); + f->GetFuncSymbol()->SetAppearsInCode(true); numOpr = static_cast(ReadNum()); s->SetNumOpnds(numOpr); for (int32 i = 0; i < numOpr; ++i) { @@ -594,7 +569,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { case OP_interfaceicallassigned: case OP_customcallassigned: { CallNode *s = func->GetCodeMemPool()->New(mod, op); - s->SetPUIdx(ImportFuncViaSymName()); + s->SetPUIdx(ImportFuncViaSym(func)); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx()); + f->GetFuncSymbol()->SetAppearsInCode(true); ImportReturnValues(func, &s->GetReturnVec()); numOpr = static_cast(ReadNum()); s->SetNumOpnds(numOpr); @@ -610,7 +587,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_polymorphiccall: { CallNode *s = func->GetCodeMemPool()->New(mod, op); - s->SetPUIdx(ImportFuncViaSymName()); + s->SetPUIdx(ImportFuncViaSym(func)); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx()); + f->GetFuncSymbol()->SetAppearsInCode(true); s->SetTyIdx(ImportType()); numOpr = static_cast(ReadNum()); s->SetNumOpnds(numOpr); @@ -622,7 +601,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_polymorphiccallassigned: { CallNode *s = func->GetCodeMemPool()->New(mod, op); - s->SetPUIdx(ImportFuncViaSymName()); + s->SetPUIdx(ImportFuncViaSym(func)); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx()); + f->GetFuncSymbol()->SetAppearsInCode(true); s->SetTyIdx(ImportType()); ImportReturnValues(func, &s->GetReturnVec()); numOpr = static_cast(ReadNum()); @@ -645,6 +626,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { stmt = s; break; } + case OP_icallprotoassigned: case OP_icallassigned: { IcallNode *s = func->GetCodeMemPool()->New(mod, op); s->SetRetTyIdx(ImportType()); @@ -759,32 +741,32 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_label: { LabelNode *s = mod.CurFuncCodeMemPool()->New(); - s->SetLabelIdx(static_cast(ReadNum())); + s->SetLabelIdx(ImportLabel(func)); stmt = s; break; } case OP_goto: case OP_gosub: { GotoNode *s = mod.CurFuncCodeMemPool()->New(op); - s->SetOffset(static_cast(ReadNum())); + s->SetOffset(ImportLabel(func)); stmt = s; break; } case OP_brfalse: case OP_brtrue: { CondGotoNode *s = mod.CurFuncCodeMemPool()->New(op); - s->SetOffset(static_cast(ReadNum())); + s->SetOffset(ImportLabel(func)); s->SetOpnd(ImportExpression(func), 0); stmt = s; break; } case OP_switch: { SwitchNode *s = mod.CurFuncCodeMemPool()->New(mod); - s->SetDefaultLabel(static_cast(ReadNum())); + s->SetDefaultLabel(ImportLabel(func)); auto tagSize = static_cast(ReadNum()); for (uint32 i = 0; i < tagSize; ++i) { int64 casetag = ReadNum(); - LabelIdx lidx(ReadNum()); + LabelIdx lidx = ImportLabel(func); CasePair cpair = std::make_pair(casetag, lidx); s->GetSwitchTable().push_back(cpair); } @@ -798,7 +780,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { uint32 tagSize = static_cast(ReadNum()); for (uint32 i = 0; i < tagSize; ++i) { uint16 casetag = static_cast(ReadNum()); - LabelIdx lidx(ReadNum()); + LabelIdx lidx = ImportLabel(func); s->AddRangeGoto(casetag, lidx); } s->SetOpnd(ImportExpression(func), 0); @@ -807,8 +789,8 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_jstry: { JsTryNode *s = mod.CurFuncCodeMemPool()->New(); - s->SetCatchOffset(static_cast(ReadNum())); - s->SetFinallyOffset(static_cast(ReadNum())); + s->SetCatchOffset(ImportLabel(func)); + s->SetFinallyOffset(ImportLabel(func)); stmt = s; break; } @@ -817,7 +799,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { TryNode *s = mod.CurFuncCodeMemPool()->New(mod); auto numLabels = static_cast(ReadNum()); for (uint32 i = 0; i < numLabels; ++i) { - s->GetOffsets().push_back(ReadNum()); + s->GetOffsets().push_back(ImportLabel(func)); } stmt = s; break; @@ -887,7 +869,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { // the labels count = static_cast(ReadNum()); for (size_t i = 0; i < count; ++i) { - auto lidx = static_cast(ReadNum()); + LabelIdx lidx = ImportLabel(func); s->gotoLabels.push_back(lidx); } // the inputs @@ -927,6 +909,13 @@ void BinaryMplImport::ReadFunctionBodyField() { PUIdx puIdx = ImportFunction(); MIRFunction *fn = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); mod.SetCurFunction(fn); + fn->GetFuncSymbol()->SetAppearsInCode(true); + localSymTab.clear(); + localSymTab.push_back(nullptr); + localPregTab.clear(); + localPregTab.push_back(0); + localLabelTab.clear(); + localLabelTab.push_back(0); fn->AllocSymTab(); fn->AllocPregTab(); @@ -934,9 +923,6 @@ void BinaryMplImport::ReadFunctionBodyField() { fn->AllocLabelTab(); ImportFuncIdInfo(fn); - ImportPregTab(fn); - ImportLocalSymTab(fn); - ImportLabelTab(fn); ImportLocalTypeNameTable(fn->GetTypeNameTab()); ImportFormalsStIdx(fn); if (mod.GetFlavor() < kMmpl) { @@ -945,8 +931,6 @@ void BinaryMplImport::ReadFunctionBodyField() { (void)ImportBlockNode(fn); mod.AddFunction(fn); } - int64 tag = ReadNum(); - CHECK_FATAL(tag == ~kBinFunctionBodyStart, "pattern mismatch in Read FunctionBody"); return; } } // namespace maple diff --git a/src/mapleall/maple_ir/src/bin_mpl_export.cpp b/src/mapleall/maple_ir/src/bin_mpl_export.cpp index 0a226f1339..486b7eb24b 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_export.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_export.cpp @@ -26,7 +26,7 @@ namespace { using namespace maple; using OutputConstFactory = FunctionFactory; -using OutputTypeFactory = FunctionFactory; +using OutputTypeFactory = FunctionFactory; void OutputConstInt(const MIRConst &constVal, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindConstInt); @@ -62,7 +62,7 @@ void OutputConstLbl(const MIRConst &constVal, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindConstAddrofLabel); mplExport.OutputConstBase(constVal); const MIRLblConst &lblConst = static_cast(constVal); - mplExport.WriteNum(lblConst.GetValue()); // LabelIdx not needed to output puIdx + mplExport.OutputLabel(lblConst.GetValue()); } void OutputConstStr(const MIRConst &constVal, BinaryMplExport &mplExport) { @@ -141,39 +141,39 @@ static bool InitOutputConstFactory() { return true; } -void OutputTypeScalar(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeScalar(const MIRType &ty, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindTypeScalar); mplExport.OutputTypeBase(ty); } -void OutputTypePointer(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypePointer(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypePointer); mplExport.OutputTypeBase(type); mplExport.OutputTypeAttrs(type.GetTypeAttrs()); - mplExport.OutputType(type.GetPointedTyIdx(), canUseTypename); + mplExport.OutputType(type.GetPointedTyIdx()); } -void OutputTypeByName(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeByName(const MIRType &ty, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindTypeByName); mplExport.OutputTypeBase(ty); } -void OutputTypeFArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeFArray(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeFArray); mplExport.OutputTypeBase(type); - mplExport.OutputType(type.GetElemTyIdx(), canUseTypename); + mplExport.OutputType(type.GetElemTyIdx()); } -void OutputTypeJArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeJArray(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeJarray); mplExport.OutputTypeBase(type); - mplExport.OutputType(type.GetElemTyIdx(), canUseTypename); + mplExport.OutputType(type.GetElemTyIdx()); } -void OutputTypeArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeArray(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeArray); mplExport.OutputTypeBase(type); @@ -181,20 +181,20 @@ void OutputTypeArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseT for (uint16 i = 0; i < type.GetDim(); ++i) { mplExport.WriteNum(type.GetSizeArrayItem(i)); } - mplExport.OutputType(type.GetElemTyIdx(), canUseTypename); + mplExport.OutputType(type.GetElemTyIdx()); mplExport.OutputTypeAttrs(type.GetTypeAttrs()); } -void OutputTypeFunction(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeFunction(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeFunction); mplExport.OutputTypeBase(type); - mplExport.OutputType(type.GetRetTyIdx(), canUseTypename); - mplExport.WriteNum(type.IsVarargs()); + mplExport.OutputType(type.GetRetTyIdx()); + mplExport.WriteNum(type.funcAttrs.GetAttrFlag()); size_t size = type.GetParamTypeList().size(); mplExport.WriteNum(size); for (size_t i = 0; i < size; ++i) { - mplExport.OutputType(type.GetNthParamType(i), canUseTypename); + mplExport.OutputType(type.GetNthParamType(i)); } size = type.GetParamAttrsList().size(); mplExport.WriteNum(size); @@ -203,13 +203,13 @@ void OutputTypeFunction(const MIRType &ty, BinaryMplExport &mplExport, bool canU } } -void OutputTypeParam(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeParam(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeParam); mplExport.OutputTypeBase(type); } -void OutputTypeInstantVector(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeInstantVector(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeInstantVector); mplExport.OutputTypeBase(type); @@ -217,15 +217,15 @@ void OutputTypeInstantVector(const MIRType &ty, BinaryMplExport &mplExport, bool mplExport.OutputTypePairs(type); } -void OutputTypeGenericInstant(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeGenericInstant(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeGenericInstant); mplExport.OutputTypeBase(type); mplExport.OutputTypePairs(type); - mplExport.OutputType(type.GetGenericTyIdx(), canUseTypename); + mplExport.OutputType(type.GetGenericTyIdx()); } -void OutputTypeBitField(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeBitField(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeBitField); mplExport.OutputTypeBase(type); @@ -233,7 +233,7 @@ void OutputTypeBitField(const MIRType &ty, BinaryMplExport &mplExport, bool) { } // for Struct/StructIncomplete/Union -void OutputTypeStruct(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeStruct(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeStruct); mplExport.OutputTypeBase(type); @@ -249,7 +249,7 @@ void OutputTypeStruct(const MIRType &ty, BinaryMplExport &mplExport, bool) { } } -void OutputTypeClass(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeClass(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeClass); mplExport.OutputTypeBase(type); @@ -264,7 +264,7 @@ void OutputTypeClass(const MIRType &ty, BinaryMplExport &mplExport, bool) { } } -void OutputTypeInterface(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeInterface(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeInterface); mplExport.OutputTypeBase(type); @@ -279,7 +279,7 @@ void OutputTypeInterface(const MIRType &ty, BinaryMplExport &mplExport, bool) { } } -void OutputTypeConstString(const MIRType &ty, BinaryMplExport&, bool) { +void OutputTypeConstString(const MIRType &ty, BinaryMplExport&) { ASSERT(false, "Type's kind not yet implemented: %d", ty.GetKind()); (void)ty; } @@ -397,7 +397,7 @@ void BinaryMplExport::DumpBuf(const std::string &name) { void BinaryMplExport::OutputConstBase(const MIRConst &constVal) { WriteNum(constVal.GetKind()); - OutputTypeViaTypeName(constVal.GetType().GetTypeIndex()); + OutputType(constVal.GetType().GetTypeIndex()); } void BinaryMplExport::OutputConst(MIRConst *constVal) { @@ -470,8 +470,8 @@ void BinaryMplExport::OutputPragma(const MIRPragma &p) { WriteNum(p.GetKind()); WriteNum(p.GetVisibility()); OutputStr(p.GetStrIdx()); - OutputType(p.GetTyIdx(), false); - OutputType(p.GetTyIdxEx(), false); + OutputType(p.GetTyIdx()); + OutputType(p.GetTyIdxEx()); WriteNum(p.GetParamNum()); size_t size = p.GetElementVector().size(); WriteNum(size); @@ -488,7 +488,7 @@ void BinaryMplExport::OutputTypeBase(const MIRType &type) { void BinaryMplExport::OutputFieldPair(const FieldPair &fp) { OutputStr(fp.first); // GStrIdx - OutputType(fp.second.first, false); // TyIdx + OutputType(fp.second.first); // TyIdx FieldAttrs fa = fp.second.second; WriteNum(fa.GetAttrFlag()); WriteNum(fa.GetAlignValue()); @@ -511,7 +511,7 @@ void BinaryMplExport::OutputMethodPair(const MethodPair &memPool) { MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(memPool.first.Idx()); CHECK_FATAL(funcSt != nullptr, "Pointer funcSt is nullptr, can't get symbol! Check it!"); WriteAsciiStr(GlobalTables::GetStrTable().GetStringFromStrIdx(funcSt->GetNameStrIdx())); - OutputType(memPool.second.first, false); // TyIdx + OutputType(memPool.second.first); // TyIdx WriteNum(memPool.second.second.GetAttrFlag()); // FuncAttrs } @@ -539,7 +539,7 @@ void BinaryMplExport::OutputStructTypeData(const MIRStructType &type) { void BinaryMplExport::OutputImplementedInterfaces(const std::vector &interfaces) { WriteNum(interfaces.size()); for (const TyIdx &tyIdx : interfaces) { - OutputType(tyIdx, false); + OutputType(tyIdx); } } @@ -571,7 +571,7 @@ void BinaryMplExport::OutputPragmaVec(const std::vector &pragmaVec) } void BinaryMplExport::OutputClassTypeData(const MIRClassType &type) { - OutputType(type.GetParentTyIdx(), false); + OutputType(type.GetParentTyIdx()); OutputImplementedInterfaces(type.GetInterfaceImplemented()); OutputInfoIsString(type.GetInfoIsString()); if (!inIPA) { @@ -601,6 +601,7 @@ void BinaryMplExport::Init() { symMark[nullptr] = 0; funcMark[nullptr] = 0; eaNodeMark[nullptr] = 0; + curFunc = nullptr; for (uint32 pti = static_cast(PTY_begin); pti < static_cast(PTY_end); ++pti) { typMark[GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(pti))] = pti; } @@ -612,7 +613,7 @@ void BinaryMplExport::OutputSymbol(MIRSymbol *sym) { return; } - auto it = symMark.find(sym); + std::unordered_map::iterator it = symMark.find(sym); if (it != symMark.end()) { WriteNum(-(it->second)); return; @@ -645,7 +646,7 @@ void BinaryMplExport::OutputSymbol(MIRSymbol *sym) { if (sym->GetSKind() == kStVar || sym->GetSKind() == kStFunc) { OutputSrcPos(sym->GetSrcPosition()); } - OutputTypeViaTypeName(sym->GetTyIdx()); + OutputType(sym->GetTyIdx()); } void BinaryMplExport::OutputFunction(PUIdx puIdx) { @@ -671,7 +672,7 @@ void BinaryMplExport::OutputFunction(PUIdx puIdx) { MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx()); CHECK_FATAL(funcSt != nullptr, "Pointer funcSt is nullptr, cannot get symbol! Check it!"); OutputSymbol(funcSt); - OutputTypeViaTypeName(func->GetMIRFuncType()->GetTypeIndex()); + OutputType(func->GetMIRFuncType()->GetTypeIndex()); WriteNum(func->GetFuncAttrs().GetAttrFlag()); auto &attributes = func->GetFuncAttrs(); @@ -684,12 +685,12 @@ void BinaryMplExport::OutputFunction(PUIdx puIdx) { } WriteNum(func->GetFlag()); - OutputTypeViaTypeName(func->GetClassTyIdx()); + OutputType(func->GetClassTyIdx()); // output formal parameter information WriteNum(static_cast(func->GetFormalDefVec().size())); for (FormalDef formalDef : func->GetFormalDefVec()) { OutputStr(formalDef.formalStrIdx); - OutputType(formalDef.formalTyIdx, false); + OutputType(formalDef.formalTyIdx); WriteNum(static_cast(formalDef.formalAttrs.GetAttrFlag())); } // store Side Effect for each func @@ -751,15 +752,20 @@ void BinaryMplExport::WriteHeaderField(uint64 contentIdx) { WriteNum(mod.GetID()); if (mod.GetFlavor() == kFlavorLmbc) { WriteNum(mod.GetGlobalMemSize()); + WriteNum(mod.IsWithDbgInfo()); } WriteNum(mod.GetNumFuncs()); WriteAsciiStr(mod.GetEntryFuncName()); OutputInfoVector(mod.GetFileInfo(), mod.GetFileInfoIsString()); - WriteNum(static_cast(mod.GetSrcFileInfo().size())); - for (uint32 i = 0; i < mod.GetSrcFileInfo().size(); i++) { - OutputStr(mod.GetSrcFileInfo()[i].first); - WriteNum(mod.GetSrcFileInfo()[i].second); + if (mod.IsWithDbgInfo()) { + WriteNum(static_cast(mod.GetSrcFileInfo().size())); + for (uint32 i = 0; i < mod.GetSrcFileInfo().size(); i++) { + OutputStr(mod.GetSrcFileInfo()[i].first); + WriteNum(mod.GetSrcFileInfo()[i].second); + } + } else { + Write(0); } WriteNum(static_cast(mod.GetImportFiles().size())); @@ -795,7 +801,7 @@ void BinaryMplExport::WriteTypeField(uint64 contentIdx, bool useClassList) { auto *structType = static_cast(type); // skip imported class/interface and incomplete types if (!structType->IsImported() && !structType->IsIncomplete()) { - OutputType(curTyidx, false); + OutputType(curTyidx); ++size; } } @@ -803,7 +809,7 @@ void BinaryMplExport::WriteTypeField(uint64 contentIdx, bool useClassList) { } else { uint32 idx = GlobalTables::GetTypeTable().lastDefaultTyIdx.GetIdx(); for (idx = idx + 1; idx < GlobalTables::GetTypeTable().GetTypeTableSize(); idx++) { - OutputType(TyIdx(idx), false); + OutputType(TyIdx(idx)); size++; } } @@ -884,7 +890,7 @@ void BinaryMplExport::WriteSeField() { GlobalTables::GetGsymTable().GetSymbolFromStrIdx(GlobalTables::GetStrTable().GetStrIdxFromName(funcStr)); MIRFunction *func = (funcSymbol != nullptr) ? GetMIRModule().GetMIRBuilder()->GetFunctionFromSymbol(*funcSymbol) : nullptr; - OutputType(func->GetReturnTyIdx(), false); + OutputType(func->GetReturnTyIdx()); } ++size; } @@ -1103,7 +1109,7 @@ void BinaryMplExport::WriteSymField(uint64 contentIdx) { MIRSymKind sKind = s->GetSKind(); if (s->IsDeleted() || storageClass == kScUnused || (s->GetIsImported() && !s->GetAppearsInCode()) || - (storageClass == kScExtern && sKind == kStFunc)) { + (sKind == kStFunc && (storageClass == kScExtern || !s->GetAppearsInCode()))) { continue; } OutputSymbol(s); @@ -1214,8 +1220,6 @@ void BinaryMplExport::Export(const std::string &fname, std::unordered_setIsNameIsLocal() && ty->GetNameStrIdx() != GStrIdx(0)) { - WriteNum(kBinKindTypeViaTypename); - OutputStr(ty->GetNameStrIdx()); - return; - } - auto func = CreateProductFunction(ty->GetKind()); if (func != nullptr) { - func(*ty, *this, canUseTypename); + func(*ty, *this); } else { ASSERT(false, "Type's kind not yet implemented: %d", ty->GetKind()); } diff --git a/src/mapleall/maple_ir/src/bin_mpl_import.cpp b/src/mapleall/maple_ir/src/bin_mpl_import.cpp index 50779027df..1f79751ed6 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_import.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_import.cpp @@ -129,11 +129,13 @@ MIRConst *BinaryMplImport::ImportConst(MIRFunction *func) { } case kBinKindConstAddrofFunc: { PUIdx puIdx = ImportFunction(); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFuncTable()[puIdx]; + f->GetFuncSymbol()->SetAppearsInCode(true); mod.SetCurFunction(func); return memPool->New(puIdx, *type); } case kBinKindConstAddrofLabel: { - LabelIdx lidx = static_cast(ReadNum()); + LabelIdx lidx = ImportLabel(func); PUIdx puIdx = func->GetPuidx(); MIRLblConst *lblConst = memPool->New(lidx, puIdx, *type); (void)func->GetLabelTab()->addrTakenLabels.insert(lidx); @@ -541,19 +543,6 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { CHECK_FATAL(static_cast(-tag) < typTab.size(), "index out of bounds"); return typTab.at(static_cast(-tag)); } - if (tag == kBinKindTypeViaTypename) { - GStrIdx typenameStrIdx = ImportStr(); - TyIdx tyIdx = mod.GetTypeNameTab()->GetTyIdxFromGStrIdx(typenameStrIdx); - if (tyIdx != 0) { - typTab.push_back(tyIdx); - return tyIdx; - } - MIRTypeByName ltype(typenameStrIdx); - ltype.SetNameIsLocal(false); - MIRType *type = GlobalTables::GetTypeTable().GetOrCreateMIRTypeNode(ltype); - typTab.push_back(type->GetTypeIndex()); - return type->GetTypeIndex(); - } PrimType primType = (PrimType)0; GStrIdx strIdx(0); bool nameIsLocal = false; @@ -580,13 +569,6 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { } return origType->GetTypeIndex(); } - case kBinKindTypeByName: { - MIRTypeByName type(strIdx); - type.SetNameIsLocal(nameIsLocal); - MIRType *origType = &InsertInTypeTables(type); - typTab.push_back(origType->GetTypeIndex()); - return origType->GetTypeIndex(); - } case kBinKindTypeFArray: { MIRFarrayType type(strIdx); type.SetNameIsLocal(nameIsLocal); @@ -629,7 +611,7 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { size_t idx = typTab.size(); typTab.push_back(TyIdx(0)); type.SetRetTyIdx(ImportType()); - type.SetVarArgs(ReadNum()); + type.funcAttrs.SetAttrFlag(ReadNum()); int64 size = ReadNum(); for (int64 i = 0; i < size; ++i) { type.GetParamTypeList().push_back(ImportType()); @@ -737,19 +719,6 @@ TyIdx BinaryMplImport::ImportTypeNonJava() { CHECK_FATAL(static_cast(-tag) < typTab.size(), "index out of bounds"); return typTab[static_cast(-tag)]; } - if (tag == kBinKindTypeViaTypename) { - GStrIdx typenameStrIdx = ImportStr(); - TyIdx tyIdx = mod.GetTypeNameTab()->GetTyIdxFromGStrIdx(typenameStrIdx); - if (tyIdx != 0) { - typTab.push_back(tyIdx); - return tyIdx; - } - MIRTypeByName ltype(typenameStrIdx); - ltype.SetNameIsLocal(false); - MIRType *type = GlobalTables::GetTypeTable().GetOrCreateMIRTypeNode(ltype); - typTab.push_back(type->GetTypeIndex()); - return type->GetTypeIndex(); - } PrimType primType = (PrimType)0; GStrIdx strIdx(0); bool nameIsLocal = false; @@ -771,12 +740,6 @@ TyIdx BinaryMplImport::ImportTypeNonJava() { GlobalTables::GetTypeTable().CreateMirTypeNodeAt(type, tyIdxUsed, &mod, false, false); return tyIdxUsed; } - case kBinKindTypeByName: { - MIRTypeByName type(strIdx); - type.SetNameIsLocal(nameIsLocal); - GlobalTables::GetTypeTable().CreateMirTypeNodeAt(type, tyIdxUsed, &mod, false, false); - return tyIdxUsed; - } case kBinKindTypeFArray: { MIRFarrayType type(strIdx); type.SetNameIsLocal(nameIsLocal); @@ -808,7 +771,7 @@ TyIdx BinaryMplImport::ImportTypeNonJava() { MIRFuncType type(strIdx); type.SetNameIsLocal(nameIsLocal); type.SetRetTyIdx(ImportTypeNonJava()); - type.SetVarArgs(ReadNum()); + type.funcAttrs.SetAttrFlag(ReadNum()); int64 size = ReadNum(); for (int64 i = 0; i < size; ++i) { type.GetParamTypeList().push_back(ImportTypeNonJava()); @@ -1159,6 +1122,7 @@ void BinaryMplImport::ReadHeaderField() { mod.SetID(static_cast(ReadNum())); if (mod.GetFlavor() == kFlavorLmbc) { mod.SetGlobalMemSize(static_cast(ReadNum())); + mod.SetWithDbgInfo(static_cast(ReadNum())); } mod.SetNumFuncs(static_cast(ReadNum())); std::string inStr; diff --git a/src/mapleall/maple_ir/src/global_tables.cpp b/src/mapleall/maple_ir/src/global_tables.cpp index c43e86b2d5..99851d8ec5 100644 --- a/src/mapleall/maple_ir/src/global_tables.cpp +++ b/src/mapleall/maple_ir/src/global_tables.cpp @@ -224,7 +224,9 @@ MIRType *TypeTable::GetOrCreateFunctionType(const TyIdx &retTyIdx, const std::ve const std::vector &vecAttrs, bool isVarg, const TypeAttrs &retAttrs) { MIRFuncType funcType(retTyIdx, vecType, vecAttrs, retAttrs); - funcType.SetVarArgs(isVarg); + if (isVarg) { + funcType.SetVarArgs(); + } TyIdx tyIdx = GetOrCreateMIRType(&funcType); ASSERT(tyIdx < typeTable.size(), "index out of range in TypeTable::GetOrCreateFunctionType"); return typeTable.at(tyIdx); diff --git a/src/mapleall/maple_ir/src/mir_builder.cpp b/src/mapleall/maple_ir/src/mir_builder.cpp index 5fddd674cb..d4a89bef7d 100755 --- a/src/mapleall/maple_ir/src/mir_builder.cpp +++ b/src/mapleall/maple_ir/src/mir_builder.cpp @@ -836,6 +836,13 @@ IcallNode *MIRBuilder::CreateStmtIcall(const MapleVector &args) { return stmt; } +IcallNode *MIRBuilder::CreateStmtIcallproto(const MapleVector &args) { + auto *stmt = GetCurrentFuncCodeMp()->New(*GetCurrentFuncCodeMpAllocator(), OP_icallproto); + ASSERT(stmt != nullptr, "stmt is null"); + stmt->SetOpnds(args); + return stmt; +} + IcallNode *MIRBuilder::CreateStmtIcallAssigned(const MapleVector &args, const MIRSymbol &ret) { auto *stmt = GetCurrentFuncCodeMp()->New(*GetCurrentFuncCodeMpAllocator(), OP_icallassigned); CallReturnVector nrets(GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -853,6 +860,23 @@ IcallNode *MIRBuilder::CreateStmtIcallAssigned(const MapleVector &arg return stmt; } +IcallNode *MIRBuilder::CreateStmtIcallprotoAssigned(const MapleVector &args, const MIRSymbol &ret) { + auto *stmt = GetCurrentFuncCodeMp()->New(*GetCurrentFuncCodeMpAllocator(), OP_icallprotoassigned); + CallReturnVector nrets(GetCurrentFuncCodeMpAllocator()->Adapter()); + CHECK_FATAL((ret.GetStorageClass() == kScAuto || ret.GetStorageClass() == kScFormal || + ret.GetStorageClass() == kScExtern || ret.GetStorageClass() == kScGlobal), + "unknown classtype! check it!"); + nrets.emplace_back(CallReturnPair(ret.GetStIdx(), RegFieldPair(0, 0))); + stmt->SetNumOpnds(args.size()); + stmt->GetNopnd().resize(stmt->GetNumOpnds()); + stmt->SetReturnVec(nrets); + for (size_t i = 0; i < stmt->GetNopndSize(); ++i) { + stmt->SetNOpndAt(i, args.at(i)); + } + stmt->SetRetTyIdx(ret.GetTyIdx()); + return stmt; +} + IntrinsiccallNode *MIRBuilder::CreateStmtIntrinsicCall(MIRIntrinsicID idx, const MapleVector &arguments, TyIdx tyIdx) { auto *stmt = GetCurrentFuncCodeMp()->New( diff --git a/src/mapleall/maple_ir/src/mir_function.cpp b/src/mapleall/maple_ir/src/mir_function.cpp index 112f5ad6cf..4f217e54c5 100644 --- a/src/mapleall/maple_ir/src/mir_function.cpp +++ b/src/mapleall/maple_ir/src/mir_function.cpp @@ -368,10 +368,8 @@ void MIRFunction::Dump(bool withoutBody) { LogInfo::MapleLogger() << " )"; } - if (module->GetFlavor() < kMmpl) { + if (module->GetFlavor() != kMmpl) { DumpFlavorLoweredThanMmpl(); - } else { - LogInfo::MapleLogger() << " () void"; } // codeMemPool is nullptr, means maple_ir has been released for memory's sake diff --git a/src/mapleall/maple_ir/src/mir_lower.cpp b/src/mapleall/maple_ir/src/mir_lower.cpp index 99dbd04c3f..aa5cb0131c 100644 --- a/src/mapleall/maple_ir/src/mir_lower.cpp +++ b/src/mapleall/maple_ir/src/mir_lower.cpp @@ -530,6 +530,19 @@ BlockNode *MIRLower::LowerBlock(BlockNode &block) { case OP_doloop: newBlock->AppendStatementsFromBlock(*LowerDoloopStmt(static_cast(*stmt))); break; + case OP_icallassigned: + case OP_icall: { + if (mirModule.IsCModule()) { + // convert to icallproto/icallprotoassigned + IcallNode *ic = static_cast(stmt); + ic->SetOpCode(stmt->GetOpCode() == OP_icall ? OP_icallproto : OP_icallprotoassigned); + MIRFuncType *funcType = FuncTypeFromFuncPtrExpr(stmt->Opnd(0)); + CHECK_FATAL(funcType != nullptr, "MIRLower::LowerBlock: cannot find prototype for icall"); + ic->SetRetTyIdx(funcType->GetTypeIndex()); + } + newBlock->AddStatement(stmt); + break; + } case OP_block: tmp = LowerBlock(static_cast(*stmt)); newBlock->AppendStatementsFromBlock(*tmp); @@ -985,6 +998,100 @@ void MIRLower::ExpandArrayMrt(MIRFunction &func) { } } +MIRFuncType *MIRLower::FuncTypeFromFuncPtrExpr(BaseNode *x) { + MIRFuncType *res = nullptr; + MIRFunction *func = mirModule.CurFunction(); + switch (x->GetOpCode()) { + case OP_regread: { + RegreadNode *regread = static_cast(x); + MIRPreg *preg = func->GetPregTab()->PregFromPregIdx(regread->GetRegIdx()); + // see if it is promoted from a symbol + if (preg->GetOp() == OP_dread) { + const MIRSymbol *symbol = preg->rematInfo.sym; + MIRType *mirType = symbol->GetType(); + if (preg->fieldID != 0) { + MIRStructType *structty = static_cast(mirType); + FieldPair thepair = structty->TraverseToField(preg->fieldID); + mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); + } + + if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + if (res != nullptr) { + break; + } + } + // check if a formal promoted to preg + for (FormalDef &formalDef : func->GetFormalDefVec()) { + if (!formalDef.formalSym->IsPreg()) { + continue; + } + if (formalDef.formalSym->GetPreg() == preg) { + MIRType *mirType = formalDef.formalSym->GetType(); + if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + break; + } + } + break; + } + case OP_dread: { + DreadNode *dread = static_cast(x); + MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); + MIRType *mirType = symbol->GetType(); + if (dread->GetFieldID() != 0) { + MIRStructType *structty = static_cast(mirType); + FieldPair thepair = structty->TraverseToField(dread->GetFieldID()); + mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); + } + if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + break; + } + case OP_iread: { + IreadNode *iread = static_cast(x); + MIRPtrType *ptrType = static_cast(iread->GetType()); + MIRType *mirType = ptrType->GetPointedType(); + if (mirType->GetKind() == kTypeFunction) { + res = static_cast(mirType); + } else if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + break; + } + case OP_addroffunc: { + AddroffuncNode *addrofFunc = static_cast(x); + PUIdx puIdx = addrofFunc->GetPUIdx(); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); + res = f->GetMIRFuncType(); + break; + } + case OP_retype: { + MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx( + static_cast(x)->GetTyIdx()); + if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + if (res == nullptr) { + res = FuncTypeFromFuncPtrExpr(x->Opnd(0)); + } + break; + } + case OP_select: { + res = FuncTypeFromFuncPtrExpr(x->Opnd(1)); + if (res == nullptr) { + res = FuncTypeFromFuncPtrExpr(x->Opnd(2)); + } + break; + } + default: CHECK_FATAL(false, "LMBCLowerer::FuncTypeFromFuncPtrExpr: NYI"); + } + return res; +} + const std::set MIRLower::kSetArrayHotFunc = {}; bool MIRLower::ShouldOptArrayMrt(const MIRFunction &func) { diff --git a/src/mapleall/maple_ir/src/mir_nodes.cpp b/src/mapleall/maple_ir/src/mir_nodes.cpp index 510dbd07ca..e86982b764 100755 --- a/src/mapleall/maple_ir/src/mir_nodes.cpp +++ b/src/mapleall/maple_ir/src/mir_nodes.cpp @@ -1201,7 +1201,7 @@ MIRType *IcallNode::GetCallReturnType() { if (op == OP_icall || op == OP_icallassigned) { return GlobalTables::GetTypeTable().GetTypeFromTyIdx(retTyIdx); } - // icallproto + // icallproto or icallprotoassigned MIRFuncType *funcType = static_cast( GlobalTables::GetTypeTable().GetTypeFromTyIdx(retTyIdx)); return GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcType->GetRetTyIdx()); @@ -1226,7 +1226,7 @@ const MIRSymbol *IcallNode::GetCallReturnSymbol(const MIRModule &mod) const { void IcallNode::Dump(int32 indent, bool newline) const { StmtNode::DumpBase(indent); - if (op == OP_icallproto) { + if (op == OP_icallproto || op == OP_icallprotoassigned) { LogInfo::MapleLogger() << " "; GlobalTables::GetTypeTable().GetTypeFromTyIdx(retTyIdx)->Dump(indent + 1); } diff --git a/src/mapleall/maple_ir/src/mir_parser.cpp b/src/mapleall/maple_ir/src/mir_parser.cpp index 9660002e49..b0bbf9080b 100755 --- a/src/mapleall/maple_ir/src/mir_parser.cpp +++ b/src/mapleall/maple_ir/src/mir_parser.cpp @@ -896,6 +896,7 @@ bool MIRParser::ParseStmtCall(StmtNodePtr &stmt) { callStmt->SetPUIdx(pIdx); MIRFunction *callee = GlobalTables::GetFunctionTable().GetFuncTable()[pIdx]; + callee->GetFuncSymbol()->SetAppearsInCode(true); if (callee->GetName() == "setjmp") { mod.CurFunction()->SetHasSetjmp(); } @@ -932,9 +933,14 @@ bool MIRParser::ParseStmtIcall(StmtNodePtr &stmt, Opcode op) { // . . . // dassign } // icallproto (, , ..., ) + // icallprotoassigned (, , ..., ) { + // dassign + // dassign + // . . . + // dassign } IcallNode *iCallStmt = mod.CurFuncCodeMemPool()->New(mod, op); lexer.NextToken(); - if (op == OP_icallproto) { + if (op == OP_icallproto || op == OP_icallprotoassigned) { TyIdx tyIdx(0); if (!ParseDerivedType(tyIdx)) { Error("error parsing type in ParseStmtIcall for icallproto at "); @@ -948,7 +954,7 @@ bool MIRParser::ParseStmtIcall(StmtNodePtr &stmt, Opcode op) { } iCallStmt->SetNOpnd(opndsVec); iCallStmt->SetNumOpnds(opndsVec.size()); - if (op == OP_icallassigned) { + if (op == OP_icallassigned || op == OP_icallprotoassigned) { CallReturnVector retsVec(mod.CurFuncCodeMemPoolAllocator()->Adapter()); if (!ParseCallReturns(retsVec)) { return false; @@ -972,6 +978,10 @@ bool MIRParser::ParseStmtIcallproto(StmtNodePtr &stmt) { return ParseStmtIcall(stmt, OP_icallproto); } +bool MIRParser::ParseStmtIcallprotoassigned(StmtNodePtr &stmt) { + return ParseStmtIcall(stmt, OP_icallprotoassigned); +} + bool MIRParser::ParseStmtIntrinsiccall(StmtNodePtr &stmt, bool isAssigned) { Opcode o = !isAssigned ? (lexer.GetTokenKind() == TK_intrinsiccall ? OP_intrinsiccall : OP_xintrinsiccall) : (lexer.GetTokenKind() == TK_intrinsiccallassigned ? OP_intrinsiccallassigned @@ -2013,18 +2023,6 @@ bool MIRParser::ParseStmtBlockForUpformalSize() { return true; } -bool MIRParser::ParseStmtBlockForOutParmSize() { - MIRFunction *fn = paramCurrFuncForParseStmtBlock; - lexer.NextToken(); - if (lexer.GetTokenKind() != TK_intconst) { - Error("expect integer after outparmsize but get "); - return false; - } - fn->SetOutParmSize(static_cast(lexer.GetTheIntVal())); - lexer.NextToken(); - return true; -} - bool MIRParser::ParseStmtBlockForModuleID() { MIRFunction *fn = paramCurrFuncForParseStmtBlock; lexer.NextToken(); @@ -3241,7 +3239,8 @@ bool MIRParser::ParseConstAddrLeafExpr(MIRConstPtr &cexpr) { } else if (expr->GetOpCode() == OP_addroffunc) { auto *aof = static_cast(expr); MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(aof->GetPUIdx()); - const MIRSymbol *fName = f->GetFuncSymbol(); + MIRSymbol *fName = f->GetFuncSymbol(); + fName->SetAppearsInCode(true); TyIdx ptyIdx = fName->GetTyIdx(); MIRPtrType ptrType(ptyIdx); ptyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&ptrType); @@ -3415,6 +3414,7 @@ std::map MIRParser::InitFuncPtrMapForPar funcPtrMap[TK_icall] = &MIRParser::ParseStmtIcall; funcPtrMap[TK_icallassigned] = &MIRParser::ParseStmtIcallassigned; funcPtrMap[TK_icallproto] = &MIRParser::ParseStmtIcallproto; + funcPtrMap[TK_icallprotoassigned] = &MIRParser::ParseStmtIcallprotoassigned; funcPtrMap[TK_intrinsiccall] = &MIRParser::ParseStmtIntrinsiccall; funcPtrMap[TK_intrinsiccallassigned] = &MIRParser::ParseStmtIntrinsiccallassigned; funcPtrMap[TK_xintrinsiccall] = &MIRParser::ParseStmtIntrinsiccall; @@ -3475,7 +3475,6 @@ std::map MIRParser::InitFuncPtrMapF funcPtrMap[TK_type] = &MIRParser::ParseStmtBlockForType; funcPtrMap[TK_framesize] = &MIRParser::ParseStmtBlockForFrameSize; funcPtrMap[TK_upformalsize] = &MIRParser::ParseStmtBlockForUpformalSize; - funcPtrMap[TK_outparmsize] = &MIRParser::ParseStmtBlockForOutParmSize; funcPtrMap[TK_moduleid] = &MIRParser::ParseStmtBlockForModuleID; funcPtrMap[TK_funcsize] = &MIRParser::ParseStmtBlockForFuncSize; funcPtrMap[TK_funcid] = &MIRParser::ParseStmtBlockForFuncID; diff --git a/src/mapleall/maple_ir/src/mir_type.cpp b/src/mapleall/maple_ir/src/mir_type.cpp index a97663018e..dc39f35704 100644 --- a/src/mapleall/maple_ir/src/mir_type.cpp +++ b/src/mapleall/maple_ir/src/mir_type.cpp @@ -738,7 +738,9 @@ void MIRFuncType::Dump(int indent, bool dontUseName) const { if (!dontUseName && CheckAndDumpTypeName(nameStrIdx, nameIsLocal)) { return; } - LogInfo::MapleLogger() << "Dump(indent + 1); @@ -749,7 +751,7 @@ void MIRFuncType::Dump(int indent, bool dontUseName) const { LogInfo::MapleLogger() << ","; } } - if (isVarArgs) { + if (IsVarargs()) { LogInfo::MapleLogger() << ", ..."; } LogInfo::MapleLogger() << ") "; @@ -1663,7 +1665,7 @@ bool MIRFuncType::EqualTo(const MIRType &type) const { } const auto &pType = static_cast(type); return (pType.retTyIdx == retTyIdx && pType.paramTypeList == paramTypeList && - pType.isVarArgs == isVarArgs && pType.paramAttrsList == paramAttrsList && + pType.funcAttrs == funcAttrs && pType.paramAttrsList == paramAttrsList && pType.retAttrs == retAttrs); } diff --git a/src/mapleall/maple_ir/src/parser.cpp b/src/mapleall/maple_ir/src/parser.cpp index 4587c26fbe..755f120f95 100644 --- a/src/mapleall/maple_ir/src/parser.cpp +++ b/src/mapleall/maple_ir/src/parser.cpp @@ -229,9 +229,7 @@ bool MIRParser::ParsePseudoReg(PrimType primType, PregIdx &pRegIdx) { MIRPreg *preg = curfunc->GetPregTab()->PregFromPregIdx(pRegIdx); if (primType != kPtyInvalid) { if (preg->GetPrimType() != primType) { - if ((primType == PTY_ref || primType == PTY_ptr) && - (preg->GetPrimType() == PTY_ref || preg->GetPrimType() == PTY_ptr)) { - ; // PTY_ref and PTY_ptr are compatible with each other + if (IsAddress(preg->GetPrimType()) && IsAddress(primType)) { } else { Error("inconsistent preg primitive type at "); return false; @@ -1299,6 +1297,15 @@ bool MIRParser::ParsePointType(TyIdx &tyIdx) { // in function pointer specification and member function prototypes inside // structs and classes bool MIRParser::ParseFuncType(TyIdx &tyIdx) { + // parse function attributes + FuncAttrs fAttrs; + if (lexer.GetTokenKind() != TK_lparen) { + if (!ParseFuncAttrs(fAttrs)) { + Error("bad function attribute specification in function type at "); + return false; + } + } + // parse parameters if (lexer.GetTokenKind() != TK_lparen) { Error("expect ( parse function type parameters but get "); @@ -1359,7 +1366,10 @@ bool MIRParser::ParseFuncType(TyIdx &tyIdx) { return false; } MIRFuncType functype(retTyIdx, vecTyIdx, vecAttrs, retTypeAttrs); - functype.SetVarArgs(varargs); + functype.funcAttrs = fAttrs; + if (varargs) { + functype.SetVarArgs(); + } tyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&functype); return true; } diff --git a/src/mapleall/maple_me/include/lmbc_lower.h b/src/mapleall/maple_me/include/lmbc_lower.h index 9462204fd7..bbeaabf098 100644 --- a/src/mapleall/maple_me/include/lmbc_lower.h +++ b/src/mapleall/maple_me/include/lmbc_lower.h @@ -40,10 +40,7 @@ class LMBCLowerer { void LowerIassign(IassignNode *, BlockNode *); void LowerAggIassign(IassignNode *, MIRType *type, int32 offset, BlockNode *); void LowerReturn(NaryStmtNode *retNode, BlockNode *newblk); - MIRFuncType *FuncTypeFromFuncPtrExpr(BaseNode *x); - void LowerCall(NaryStmtNode *callNode, BlockNode *newblk); BlockNode *LowerBlock(BlockNode *); - void LoadFormalsAssignedToPregs(); void LowerFunction(); MIRModule *mirModule; diff --git a/src/mapleall/maple_me/include/lmbc_memlayout.h b/src/mapleall/maple_me/include/lmbc_memlayout.h index 7cea863a22..0f2bf5cbea 100644 --- a/src/mapleall/maple_me/include/lmbc_memlayout.h +++ b/src/mapleall/maple_me/include/lmbc_memlayout.h @@ -31,8 +31,8 @@ typedef enum { MS_actual, // for the outgoing parameters MS_local, // for all local variables and temporaries MS_FPbased, // addressed via offset from the frame pointer - MS_SPbased, // addressed via offset from the stack pointer MS_GPbased, // addressed via offset from the global pointer + MS_largeStructActual, // for storing large struct actuals passed by value for ARM CPU } MemSegmentKind; class MemSegment; @@ -64,15 +64,10 @@ class MemSegment { class LMBCMemLayout { public: - uint32 FindLargestActualArea(void); - uint32 FindLargestActualArea(StmtNode *, int &); - LMBCMemLayout(MIRFunction *f, MapleAllocator *mallocator) + LMBCMemLayout(MIRFunction *f, MemSegment *segGP, MapleAllocator *mallocator) : func(f), - seg_upformal(MS_upformal), - seg_formal(MS_formal), - seg_actual(MS_actual), + seg_GPbased(segGP), seg_FPbased(MS_FPbased), - seg_SPbased(MS_SPbased), sym_alloc_table(mallocator->Adapter()) { sym_alloc_table.resize(f->GetSymTab()->GetSymbolTableSize()); } @@ -81,67 +76,25 @@ class LMBCMemLayout { void LayoutStackFrame(void); int32 StackFrameSize(void) const { - return seg_SPbased.size - seg_FPbased.size; - } - - int32 UpformalSize(void) const { - return seg_upformal.size; + return -seg_FPbased.size; } MIRFunction *func; - MemSegment seg_upformal; - MemSegment seg_formal; - MemSegment seg_actual; + MemSegment *seg_GPbased; MemSegment seg_FPbased; - MemSegment seg_SPbased; MapleVector sym_alloc_table; // index is StIdx }; class GlobalMemLayout { public: - GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAllocator *mallocator); + GlobalMemLayout(MIRModule *mod, MapleAllocator *mallocator); ~GlobalMemLayout() {} MemSegment seg_GPbased; MapleVector sym_alloc_table; // index is StIdx - - private: - void FillScalarValueInMap(uint32 startaddress, PrimType pty, MIRConst *c); - void FillTypeValueInMap(uint32 startaddress, MIRType *ty, MIRConst *c); - void FillSymbolValueInMap(const MIRSymbol *sym); - - maplebe::BECommon *be; MIRModule *mirModule; }; -// for specifying how a parameter is passed -struct PLocInfo { - int32 memoffset; - int32 memsize; -}; - -// for processing an incoming or outgoing parameter list -class ParmLocator { - public: - explicit ParmLocator() : parmNum(0), lastMemOffset(0) {} - - ~ParmLocator() {} - - void LocateNextParm(const MIRType *ty, PLocInfo &ploc); - - private: - int32 parmNum; // number of all types of parameters processed so far - int32 lastMemOffset; -}; - -// given the type of the return value, determines the return mechanism -class ReturnMechanism { - public: - ReturnMechanism(const MIRType *retty); - bool fake_first_parm; // whether returning in memory via fake first parameter - PrimType ptype0; // the primitive type stored in retval0 -}; - } /* namespace maple */ #endif /* MAPLEME_INCLUDE_LMBC_MEMLAYOUT_H */ diff --git a/src/mapleall/maple_me/src/alias_class.cpp b/src/mapleall/maple_me/src/alias_class.cpp index 788a9a3540..1a63043e27 100644 --- a/src/mapleall/maple_me/src/alias_class.cpp +++ b/src/mapleall/maple_me/src/alias_class.cpp @@ -1017,7 +1017,9 @@ void AliasClass::ApplyUnionForCopies(StmtNode &stmt) { } case OP_asm: case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { for (uint32 i = 0; i < stmt.NumOpnds(); ++i) { const AliasInfo &ainfo = CreateAliasInfoExpr(*stmt.Opnd(i)); if (stmt.GetOpCode() != OP_asm && i == 0) { @@ -2563,6 +2565,7 @@ void AliasClass::GenericInsertMayDefUse(StmtNode &stmt, BBId bbID) { case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_virtualcall: case OP_virtualicall: case OP_superclasscall: @@ -2570,7 +2573,8 @@ void AliasClass::GenericInsertMayDefUse(StmtNode &stmt, BBId bbID) { case OP_interfaceicall: case OP_customcall: case OP_polymorphiccall: - case OP_icall: { + case OP_icall: + case OP_icallproto: { InsertMayDefUseCall(stmt, bbID, false); return; } diff --git a/src/mapleall/maple_me/src/code_factoring.cpp b/src/mapleall/maple_me/src/code_factoring.cpp index 6cabb59adc..2f40e7b821 100644 --- a/src/mapleall/maple_me/src/code_factoring.cpp +++ b/src/mapleall/maple_me/src/code_factoring.cpp @@ -122,7 +122,9 @@ bool FactoringOptimizer::IsIdenticalStmt(StmtNode *stmt1, StmtNode *stmt2) { break; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { auto *icall1 = static_cast(stmt1); auto *icall2 = static_cast(stmt2); if (icall1->GetRetTyIdx() != icall2->GetRetTyIdx() || diff --git a/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp b/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp index db34036937..50a25a6101 100644 --- a/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp +++ b/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp @@ -641,7 +641,9 @@ void PEGBuilder::BuildPEGNodeInStmt(const StmtNode *stmt) { break; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { BuildPEGNodeInIcall(static_cast(stmt)); break; } diff --git a/src/mapleall/maple_me/src/irmap_build.cpp b/src/mapleall/maple_me/src/irmap_build.cpp index cd801b7b5b..29afaca89b 100755 --- a/src/mapleall/maple_me/src/irmap_build.cpp +++ b/src/mapleall/maple_me/src/irmap_build.cpp @@ -806,7 +806,7 @@ MeStmt *IRMapBuild::BuildCallMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { MeStmt *IRMapBuild::BuildNaryMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { Opcode op = stmt.GetOpCode(); - NaryMeStmt *naryMeStmt = (op == OP_icall || op == OP_icallassigned) + NaryMeStmt *naryMeStmt = (op == OP_icall || op == OP_icallassigned || op == OP_icallproto || op == OP_icallprotoassigned) ? static_cast(irMap->NewInPool(&stmt)) : static_cast(irMap->NewInPool(&stmt)); auto &naryStmtNode = static_cast(stmt); @@ -821,6 +821,9 @@ MeStmt *IRMapBuild::BuildNaryMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { if (propagater) { propagater->PropUpdateChiListDef(*naryMeStmt->GetChiList()); } + if (op == OP_icallproto || op == OP_icallprotoassigned) { + static_cast(naryMeStmt)->SetRetTyIdx(static_cast(stmt).GetRetTyIdx()); + } return naryMeStmt; } @@ -921,6 +924,8 @@ void IRMapBuild::InitMeStmtFactory() { RegisterFactoryFunction(OP_polymorphiccallassigned, &IRMapBuild::BuildCallMeStmt); RegisterFactoryFunction(OP_icall, &IRMapBuild::BuildNaryMeStmt); RegisterFactoryFunction(OP_icallassigned, &IRMapBuild::BuildNaryMeStmt); + RegisterFactoryFunction(OP_icallproto, &IRMapBuild::BuildNaryMeStmt); + RegisterFactoryFunction(OP_icallprotoassigned, &IRMapBuild::BuildNaryMeStmt); RegisterFactoryFunction(OP_intrinsiccall, &IRMapBuild::BuildNaryMeStmt); RegisterFactoryFunction(OP_xintrinsiccall, &IRMapBuild::BuildNaryMeStmt); RegisterFactoryFunction(OP_intrinsiccallwithtype, &IRMapBuild::BuildNaryMeStmt); diff --git a/src/mapleall/maple_me/src/irmap_emit.cpp b/src/mapleall/maple_me/src/irmap_emit.cpp index 824e7c7e53..7fcbd3804b 100755 --- a/src/mapleall/maple_me/src/irmap_emit.cpp +++ b/src/mapleall/maple_me/src/irmap_emit.cpp @@ -412,7 +412,7 @@ MIRFunction &CallMeStmt::GetTargetFunction() { } StmtNode &CallMeStmt::EmitStmt(SSATab &ssaTab) { - if (GetOp() != OP_icall && GetOp() != OP_icallassigned) { + if (GetOp() != OP_icall && GetOp() != OP_icallassigned && GetOp() != OP_icallproto && GetOp() != OP_icallprotoassigned) { auto *callNode = ssaTab.GetModule().CurFunction()->GetCodeMempool()->New(ssaTab.GetModule(), Opcode(GetOp())); callNode->SetPUIdx(puIdx); @@ -496,6 +496,9 @@ StmtNode &IcallMeStmt::EmitStmt(SSATab &ssaTab) { } } } + if (GetOp() == OP_icallproto || GetOp() == OP_icallprotoassigned) { + icallNode->SetRetTyIdx(retTyIdx); + } return *icallNode; } diff --git a/src/mapleall/maple_me/src/lfo_dep_test.cpp b/src/mapleall/maple_me/src/lfo_dep_test.cpp index 19a523e138..ac3340e843 100644 --- a/src/mapleall/maple_me/src/lfo_dep_test.cpp +++ b/src/mapleall/maple_me/src/lfo_dep_test.cpp @@ -66,6 +66,8 @@ void LfoDepInfo::CreateDoloopInfo(BlockNode *block, DoloopInfo *parent) { case OP_callassigned: case OP_icall: case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: case OP_return: case OP_throw: case OP_asm: diff --git a/src/mapleall/maple_me/src/lmbc_lower.cpp b/src/mapleall/maple_me/src/lmbc_lower.cpp index a155b25fa4..f5893447ba 100644 --- a/src/mapleall/maple_me/src/lmbc_lower.cpp +++ b/src/mapleall/maple_me/src/lmbc_lower.cpp @@ -22,16 +22,12 @@ using namespace std; PregIdx LMBCLowerer::GetSpecialRegFromSt(const MIRSymbol *sym) { MIRStorageClass storageClass = sym->GetStorageClass(); PregIdx specreg = 0; - if (storageClass == kScAuto || storageClass == kScFormal) { + if (storageClass == kScAuto) { CHECK(sym->GetStIndex() < memlayout->sym_alloc_table.size(), "index out of range in LMBCLowerer::GetSpecialRegFromSt"); SymbolAlloc symalloc = memlayout->sym_alloc_table[sym->GetStIndex()]; - if (symalloc.mem_segment->kind == MS_upformal || symalloc.mem_segment->kind == MS_formal || - symalloc.mem_segment->kind == MS_FPbased) { + if (symalloc.mem_segment->kind == MS_FPbased) { specreg = -kSregFp; - } else if (symalloc.mem_segment->kind == MS_actual || - symalloc.mem_segment->kind == MS_SPbased) { - specreg = -kSregSp; } else { CHECK_FATAL(false, "LMBCLowerer::LowerDread: bad memory layout for local variable"); } @@ -46,6 +42,7 @@ PregIdx LMBCLowerer::GetSpecialRegFromSt(const MIRSymbol *sym) { BaseNode *LMBCLowerer::LowerAddrof(AddrofNode *expr) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(expr->GetStIdx()); + symbol->ResetIsDeleted(); int32 offset = 0; if (expr->GetFieldID() != 0) { MIRStructType *structty = static_cast(symbol->GetType()); @@ -66,6 +63,7 @@ BaseNode *LMBCLowerer::LowerAddrof(AddrofNode *expr) { BaseNode *LMBCLowerer::LowerDread(AddrofNode *expr) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(expr->GetStIdx()); + symbol->ResetIsDeleted(); PrimType symty = symbol->GetType()->GetPrimType(); int32 offset = 0; if (expr->GetFieldID() != 0) { @@ -96,20 +94,22 @@ BaseNode *LMBCLowerer::LowerDread(AddrofNode *expr) { BaseNode *LMBCLowerer::LowerDreadoff(DreadoffNode *dreadoff) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dreadoff->stIdx); + symbol->ResetIsDeleted(); if (!symbol->LMBCAllocateOffSpecialReg()) { return dreadoff; } + PrimType symty = symbol->GetType()->GetPrimType(); PregIdx spcreg = GetSpecialRegFromSt(symbol); if (spcreg == -kSregFp) { CHECK_FATAL(symbol->IsLocal(), "load from fp non local?"); - IreadFPoffNode *ireadoff = mirBuilder->CreateExprIreadFPoff( - dreadoff->GetPrimType(), memlayout->sym_alloc_table[symbol->GetStIndex()].offset + dreadoff->offset); + IreadFPoffNode *ireadoff = mirBuilder->CreateExprIreadFPoff(symty, + memlayout->sym_alloc_table[symbol->GetStIndex()].offset + dreadoff->offset); return ireadoff; } else { BaseNode *rrn = mirBuilder->CreateExprRegread(LOWERED_PTR_TYPE, spcreg); SymbolAlloc &symalloc = symbol->IsLocal() ? memlayout->sym_alloc_table[symbol->GetStIndex()] : globmemlayout->sym_alloc_table[symbol->GetStIndex()]; - IreadoffNode *ireadoff = mirBuilder->CreateExprIreadoff(dreadoff->GetPrimType(), symalloc.offset + dreadoff->offset, rrn); + IreadoffNode *ireadoff = mirBuilder->CreateExprIreadoff(symty, symalloc.offset + dreadoff->offset, rrn); return ireadoff; } } @@ -129,14 +129,14 @@ static MIRType *GetPointedToType(const MIRPtrType *pointerty) { BaseNode *LMBCLowerer::LowerIread(IreadNode *expr) { int32 offset = 0; + MIRPtrType *ptrType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(expr->GetTyIdx())); + MIRType *type = ptrType->GetPointedType(); if (expr->GetFieldID() != 0) { - MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(expr->GetTyIdx()); - MIRStructType *structty = - static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(type)->GetPointedTyIdx())); + MIRStructType *structty = static_cast(type); offset = becommon->GetFieldOffset(*structty, expr->GetFieldID()).first; + type = structty->GetFieldType(expr->GetFieldID()); } - BaseNode *ireadoff = mirBuilder->CreateExprIreadoff(expr->GetPrimType(), offset, expr->Opnd(0)); + BaseNode *ireadoff = mirBuilder->CreateExprIreadoff(type->GetPrimType(), offset, expr->Opnd(0)); return ireadoff; } @@ -165,6 +165,7 @@ BaseNode *LMBCLowerer::LowerExpr(BaseNode *expr) { return LowerAddrof(static_cast(expr)); case OP_addrofoff: { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(static_cast(expr)->stIdx); + symbol->ResetIsDeleted(); CHECK_FATAL(!symbol->LMBCAllocateOffSpecialReg(), "LMBCLowerer:: illegal addrofoff instruction"); break; @@ -199,6 +200,7 @@ void LMBCLowerer::LowerAggDassign(const DassignNode *dsnode, MIRType *lhsty, // generate lhs address expression BaseNode *lhs = nullptr; MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dsnode->GetStIdx()); + symbol->ResetIsDeleted(); if (!symbol->LMBCAllocateOffSpecialReg()) { lhs = mirBuilder->CreateExprDreadoff(OP_addrofoff, LOWERED_PTR_TYPE, *symbol, offset); } else { @@ -218,6 +220,7 @@ void LMBCLowerer::LowerAggDassign(const DassignNode *dsnode, MIRType *lhsty, void LMBCLowerer::LowerDassign(DassignNode *dsnode, BlockNode *newblk) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dsnode->GetStIdx()); + symbol->ResetIsDeleted(); MIRType *symty = symbol->GetType(); int32 offset = 0; if (dsnode->GetFieldID() != 0) { @@ -259,6 +262,7 @@ void LMBCLowerer::LowerDassign(DassignNode *dsnode, BlockNode *newblk) { void LMBCLowerer::LowerDassignoff(DassignoffNode *dsnode, BlockNode *newblk) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dsnode->stIdx); + symbol->ResetIsDeleted(); CHECK_FATAL(dsnode->Opnd(0)->GetPrimType() != PTY_agg, "LowerDassignoff: agg primitive type NYI"); BaseNode *rhs = LowerExpr(dsnode->Opnd(0)); if (!symbol->LMBCAllocateOffSpecialReg()) { @@ -334,6 +338,9 @@ void LMBCLowerer::LowerIassign(IassignNode *iassign, BlockNode *newblk) { } if (iassign->GetRHS()->GetPrimType() != PTY_agg) { PrimType ptypused = type->GetPrimType(); + if (ptypused == PTY_agg) { + ptypused = iassign->GetRHS()->GetPrimType(); + } IassignoffNode *iassignoff = mirBuilder->CreateStmtIassignoff(ptypused, offset, iassign->addrExpr, @@ -347,15 +354,20 @@ void LMBCLowerer::LowerIassign(IassignNode *iassign, BlockNode *newblk) { // called only if the return has > 1 operand; assume prior lowering already // converted any return of structs to be via fake parameter void LMBCLowerer::LowerReturn(NaryStmtNode *retNode, BlockNode *newblk) { - CHECK_FATAL(retNode->NumOpnds() <= 2, "LMBCLowerer::LowerReturn: more than 2 return values NYI"); - for (int i = 0; i < retNode->NumOpnds(); i++) { - CHECK_FATAL(retNode->Opnd(i)->GetPrimType() != PTY_agg, - "LMBCLowerer::LowerReturn: return of aggregate needs to be handled first"); - // insert regassign for the returned value - BaseNode *rhs = LowerExpr(retNode->Opnd(i)); - RegassignNode *regasgn = mirBuilder->CreateStmtRegassign(rhs->GetPrimType(), - i == 0 ? -kSregRetval0 : -kSregRetval1, - rhs); + if (retNode->Opnd(0)->GetPrimType() != PTY_agg) { + CHECK_FATAL(retNode->NumOpnds() <= 2, "LMBCLowerer::LowerReturn: more than 2 return values NYI"); + for (int i = 0; i < retNode->NumOpnds(); i++) { + // insert regassign for the returned value + PrimType ptyp = retNode->Opnd(i)->GetPrimType(); + BaseNode *rhs = LowerExpr(retNode->Opnd(i)); + RegassignNode *regasgn = mirBuilder->CreateStmtRegassign(ptyp, + i == 0 ? -kSregRetval0 : -kSregRetval1, + rhs); + newblk->AddStatement(regasgn); + } + } else { // handle return of small struct using only %%retval0 + BaseNode *rhs = LowerExpr(retNode->Opnd(0)); + RegassignNode *regasgn = mirBuilder->CreateStmtRegassign(PTY_agg, -kSregRetval0, rhs); newblk->AddStatement(regasgn); } retNode->GetNopnd().clear(); // remove the return operands @@ -363,178 +375,6 @@ void LMBCLowerer::LowerReturn(NaryStmtNode *retNode, BlockNode *newblk) { newblk->AddStatement(retNode); } -MIRFuncType *LMBCLowerer::FuncTypeFromFuncPtrExpr(BaseNode *x) { - MIRFuncType *res = nullptr; - switch (x->GetOpCode()) { - case OP_regread: { - RegreadNode *regread = static_cast(x); - MIRPreg *preg = func->GetPregTab()->PregFromPregIdx(regread->GetRegIdx()); - // see if it is promoted from a symbol - if (preg->GetOp() == OP_dread) { - const MIRSymbol *symbol = preg->rematInfo.sym; - MIRType *mirType = symbol->GetType(); - if (preg->fieldID != 0) { - MIRStructType *structty = static_cast(mirType); - FieldPair thepair = structty->TraverseToField(preg->fieldID); - mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - if (res != nullptr) { - break; - } - } - // check if a formal promoted to preg - for (FormalDef &formalDef : func->GetFormalDefVec()) { - if (!formalDef.formalSym->IsPreg()) { - continue; - } - if (formalDef.formalSym->GetPreg() == preg) { - MIRType *mirType = formalDef.formalSym->GetType(); - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - break; - } - } - break; - } - case OP_dread: { - DreadNode *dread = static_cast(x); - MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); - MIRType *mirType = symbol->GetType(); - if (dread->GetFieldID() != 0) { - MIRStructType *structty = static_cast(mirType); - FieldPair thepair = structty->TraverseToField(dread->GetFieldID()); - mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - break; - } - case OP_iread: { - IreadNode *iread = static_cast(x); - MIRPtrType *ptrType = static_cast(iread->GetType()); - MIRType *mirType = ptrType->GetPointedType(); - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - break; - } - case OP_addroffunc: { - AddroffuncNode *addrofFunc = static_cast(x); - PUIdx puIdx = addrofFunc->GetPUIdx(); - MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); - res = f->GetMIRFuncType(); - break; - } - case OP_retype: { - MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(x)->GetTyIdx()); - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - if (res == nullptr) { - res = FuncTypeFromFuncPtrExpr(x->Opnd(0)); - } - break; - } - case OP_select: { - res = FuncTypeFromFuncPtrExpr(x->Opnd(1)); - if (res == nullptr) { - res = FuncTypeFromFuncPtrExpr(x->Opnd(2)); - } - break; - } - default: CHECK_FATAL(false, "LMBCLowerer::FuncTypeFromFuncPtrExpr: NYI"); - } - return res; -} - -void LMBCLowerer::LowerCall(NaryStmtNode *naryStmt, BlockNode *newblk) { - // go through each parameter - uint32 i = 0; - if (naryStmt->GetOpCode() == OP_icall || naryStmt->GetOpCode() == OP_icallassigned) { - i = 1; - } - ParmLocator parmlocator; - for (; i < naryStmt->NumOpnds(); i++) { - BaseNode *opnd = naryStmt->Opnd(i); - MIRType *ty = nullptr; - // get ty for this parameter - if (opnd->GetPrimType() != PTY_agg) { - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(static_cast(opnd->GetPrimType())); - } else { - Opcode opnd_opcode = opnd->GetOpCode(); - CHECK_FATAL(opnd_opcode == OP_dread || opnd_opcode == OP_iread, ""); - if (opnd_opcode == OP_dread) { - AddrofNode *dread = static_cast(opnd); - MIRSymbol *sym = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx()); - if (dread->GetFieldID() != 0) { - CHECK_FATAL(ty->IsStructType(), ""); - FieldPair thepair = static_cast(ty)->TraverseToField(dread->GetFieldID()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - } else { // OP_iread - IreadNode *iread = static_cast(opnd); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread->GetTyIdx()); - CHECK_FATAL(ty->GetKind() == kTypePointer, ""); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(ty)->GetPointedTyIdx()); - if (iread->GetFieldID() != 0) { - CHECK_FATAL(ty->IsStructType(), ""); - FieldPair thepair = static_cast(ty)->TraverseToField(iread->GetFieldID()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - } - } - PLocInfo ploc; - parmlocator.LocateNextParm(ty, ploc); - if (opnd->GetPrimType() != PTY_agg) { - IassignFPoffNode *iass = mirBuilder->CreateStmtIassignFPoff(OP_iassignspoff, - opnd->GetPrimType(), - ploc.memoffset, - LowerExpr(opnd)); - newblk->AddStatement(iass); - } else { - BlkassignoffNode *bass = - mirModule->CurFuncCodeMemPool()->New(ploc.memoffset, ploc.memsize); - bass->SetAlign(std::min(ty->GetAlign(), 8u)); - bass->SetBOpnd(mirBuilder->CreateExprRegread(LOWERED_PTR_TYPE, -kSregSp), 0); - // the operand is either OP_dread or OP_iread; use its address instead - if (opnd->GetOpCode() == OP_dread) { - opnd->SetOpCode(OP_addrof); - } else { - opnd->SetOpCode(OP_iaddrof); - } - opnd->SetPrimType(LOWERED_PTR_TYPE); - bass->SetBOpnd(LowerExpr(opnd), 1); - newblk->AddStatement(bass); - } - } - BaseNode *opnd0 = nullptr; - if (naryStmt->GetOpCode() == OP_icall || naryStmt->GetOpCode() == OP_icallassigned) { - opnd0 = naryStmt->Opnd(0); - naryStmt->GetNopnd().clear(); // remove the call operands - // convert to OP_icallproto by finding the function prototype and record in stmt - naryStmt->SetOpCode(OP_icallproto); - MIRFuncType *funcType = FuncTypeFromFuncPtrExpr(opnd0); - CHECK_FATAL(funcType != nullptr, "LMBCLowerer::LowerCall: cannot find prototype for icall"); - static_cast(naryStmt)->SetRetTyIdx(funcType->GetTypeIndex()); - // add back the function pointer operand - naryStmt->GetNopnd().push_back(LowerExpr(opnd0)); - naryStmt->SetNumOpnds(1); - } else { - naryStmt->GetNopnd().clear(); // remove the call operands - naryStmt->SetNumOpnds(0); - } - newblk->AddStatement(naryStmt); -} - BlockNode *LMBCLowerer::LowerBlock(BlockNode *block) { BlockNode *newblk = mirModule->CurFuncCodeMemPool()->New(); if (!block->GetFirst()) { @@ -569,10 +409,6 @@ BlockNode *LMBCLowerer::LowerBlock(BlockNode *block) { } else { LowerReturn(retNode, newblk); } - } - case OP_call: - case OP_icall: { - LowerCall(static_cast(stmt), newblk); break; } default: { @@ -587,29 +423,19 @@ BlockNode *LMBCLowerer::LowerBlock(BlockNode *block) { return newblk; } -void LMBCLowerer::LoadFormalsAssignedToPregs() { - // go through each formals - for (int32 i = func->GetFormalDefVec().size()-1; i >= 0; i--) { - MIRSymbol *formalSt = func->GetFormalDefVec()[i].formalSym; - if (formalSt->GetSKind() != kStPreg) { - continue; +void LMBCLowerer::LowerFunction() { + // set extern global vars' isDeleted field; will reset when visited + MapleVector::const_iterator sit = mirModule->GetSymbolDefOrder().begin(); + for (; sit != mirModule->GetSymbolDefOrder().end(); ++sit) { + MIRSymbol *s = GlobalTables::GetGsymTable().GetSymbolFromStidx(sit->Idx()); + if (s->GetSKind() == kStVar && s->GetStorageClass() == kScExtern && !s->HasPotentialAssignment()) { + s->SetIsDeleted(); } - MIRPreg *preg = formalSt->GetPreg(); - uint32 stindex = formalSt->GetStIndex(); - PrimType pty = formalSt->GetType()->GetPrimType(); - IreadFPoffNode *ireadfpoff = mirBuilder->CreateExprIreadFPoff(pty, - memlayout->sym_alloc_table[stindex].offset); - RegassignNode *rass = mirBuilder->CreateStmtRegassign(pty, - func->GetPregTab()->GetPregIdxFromPregno(preg->GetPregNo()), ireadfpoff); - func->GetBody()->InsertFirst(rass); } -} -void LMBCLowerer::LowerFunction() { BlockNode *origbody = func->GetBody(); BlockNode *newbody = LowerBlock(origbody); func->SetBody(newbody); - LoadFormalsAssignedToPregs(); } } // namespace maple diff --git a/src/mapleall/maple_me/src/lmbc_memlayout.cpp b/src/mapleall/maple_me/src/lmbc_memlayout.cpp index e740c5d13f..b32acae493 100644 --- a/src/mapleall/maple_me/src/lmbc_memlayout.cpp +++ b/src/mapleall/maple_me/src/lmbc_memlayout.cpp @@ -13,146 +13,40 @@ * See the MulanPSL - 2.0 for more details. */ -// For each function being compiled, lay out its parameters, return values and -// local variables on its stack frame. This involves determining how parameters -// and return values are passed from analyzing their types. -// -// Allocate all the global variables within the global memory block which is -// addressed via offset from the global pointer GP during execution. Allocate -// this block pointed to by mirModule.globalBlkMap and perform the static -// initializations. +// For each function being compiled, lay out its local variables on its stack +// frame. Allocate all the global variables within the global memory block +// which is addressed via offset from the global pointer GP during execution. +// Allocate this block pointed to by mirModule.globalBlkMap. #include "lmbc_memlayout.h" #include "mir_symbol.h" namespace maple { -uint32 LMBCMemLayout::FindLargestActualArea(StmtNode *stmt, int &maxActualSize) { - if (!stmt) { - return maxActualSize; - } - Opcode opcode = stmt->op; - switch (opcode) { - case OP_block: { - BlockNode *blcknode = static_cast(stmt); - for (StmtNode &s : blcknode->GetStmtNodes()) { - FindLargestActualArea(&s, maxActualSize); - } - break; - } - case OP_if: { - IfStmtNode *ifnode = static_cast(stmt); - FindLargestActualArea(ifnode->GetThenPart(), maxActualSize); - FindLargestActualArea(ifnode->GetElsePart(), maxActualSize); - break; - } - case OP_doloop: { - FindLargestActualArea(static_cast(stmt)->GetDoBody(), maxActualSize); - break; - } - case OP_dowhile: - case OP_while: - FindLargestActualArea(static_cast(stmt)->GetBody(), maxActualSize); - break; - case OP_call: - case OP_icall: - case OP_intrinsiccall: { - ParmLocator parmlocator; // instantiate a parm locator - NaryStmtNode *callstmt = static_cast(stmt); - for (uint32 i = 0; i < callstmt->NumOpnds(); i++) { - BaseNode *opnd = callstmt->Opnd(i); - CHECK_FATAL(opnd->GetPrimType() != PTY_void, ""); - MIRType *ty = nullptr; - if (opnd->GetPrimType() != PTY_agg) { - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(opnd->GetPrimType())); - } else { - Opcode opnd_opcode = opnd->GetOpCode(); - CHECK_FATAL(opnd_opcode == OP_dread || opnd_opcode == OP_iread, ""); - if (opnd_opcode == OP_dread) { - AddrofNode *dread = static_cast(opnd); - MIRSymbol *sym = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx()); - if (dread->GetFieldID() != 0) { - CHECK_FATAL(ty->IsStructType(), "expect struct or class or union"); - FieldPair thepair = - static_cast(ty)->TraverseToField(dread->GetFieldID()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - } else { // OP_iread - IreadNode *iread = static_cast(opnd); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread->GetTyIdx()); - CHECK_FATAL(ty->GetKind() == kTypePointer, ""); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(ty)->GetPointedTyIdx()); - if (iread->GetFieldID() != 0) { - CHECK_FATAL(ty->IsStructType(), "expect struct or class or union"); - FieldPair thepair = - static_cast(ty)->TraverseToField(iread->GetFieldID()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - } - } - PLocInfo ploc; - parmlocator.LocateNextParm(ty, ploc); - maxActualSize = std::max(maxActualSize, ploc.memoffset + ploc.memsize); - maxActualSize = maplebe::RoundUp(maxActualSize, GetPrimTypeSize(PTY_ptr)); - } - break; - } - default: - return maxActualSize; - } - maxActualSize = maplebe::RoundUp(maxActualSize, GetPrimTypeSize(PTY_ptr)); - return maxActualSize; -} - -// go over all outgoing calls in the function body and get the maximum space -// needed for storing the actuals based on the actual parameters and the ABI; -// this assumes that all nesting of statements has been removed, so that all -// the statements are at only one block level -uint32 LMBCMemLayout::FindLargestActualArea(void) { - int32 maxActualSize = 0; - FindLargestActualArea(func->GetBody(), maxActualSize); - return static_cast(maxActualSize); -} +constexpr size_t kVarargSaveAreaSize = 192; void LMBCMemLayout::LayoutStackFrame(void) { - MIRSymbol *sym = nullptr; - // go through formal parameters - ParmLocator parmlocator; // instantiate a parm locator - PLocInfo ploc; - for (uint32 i = 0; i < func->GetFormalDefVec().size(); i++) { - FormalDef formalDef = func->GetFormalDefAt(i); - sym = formalDef.formalSym; - MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(formalDef.formalTyIdx); - parmlocator.LocateNextParm(ty, ploc); - uint32 stindex = sym->GetStIndex(); - // always passed in memory, so allocate in seg_upformal - sym_alloc_table[stindex].mem_segment = &seg_upformal; - seg_upformal.size = maplebe::RoundUp(seg_upformal.size, ty->GetAlign()); - sym_alloc_table[stindex].offset = seg_upformal.size; - seg_upformal.size += ty->GetSize(); - seg_upformal.size = maplebe::RoundUp(seg_upformal.size, GetPrimTypeSize(PTY_ptr)); + if (func->IsVarargs()) { + seg_FPbased.size -= kVarargSaveAreaSize; } - // allocate seg_formal in seg_FPbased - seg_formal.how_alloc.mem_segment = &seg_FPbased; - seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, GetPrimTypeSize(PTY_ptr)); - seg_FPbased.size -= seg_formal.size; - seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, GetPrimTypeSize(PTY_ptr)); - seg_formal.how_alloc.offset = seg_FPbased.size; - // allocate the local variables uint32 symtabsize = func->GetSymTab()->GetSymbolTableSize(); for (uint32 i = 0; i < symtabsize; i++) { - sym = func->GetSymTab()->GetSymbolFromStIdx(i); + MIRSymbol *sym = func->GetSymTab()->GetSymbolFromStIdx(i); if (!sym) { continue; } if (sym->IsDeleted()) { continue; } + if (sym->GetStorageClass() == kScPstatic && sym->LMBCAllocateOffSpecialReg()) { + uint32 stindex = sym->GetStIndex(); + sym_alloc_table[stindex].mem_segment = seg_GPbased; + seg_GPbased->size = maplebe::RoundUp(seg_GPbased->size, sym->GetType()->GetAlign()); + sym_alloc_table[stindex].offset = seg_GPbased->size; + seg_GPbased->size += sym->GetType()->GetSize(); + } if (sym->GetStorageClass() != kScAuto) { continue; } @@ -162,160 +56,10 @@ void LMBCMemLayout::LayoutStackFrame(void) { seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, sym->GetType()->GetAlign()); sym_alloc_table[stindex].offset = seg_FPbased.size; } - seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, GetPrimTypeSize(PTY_ptr)); - - // allocate seg_actual for storing the outgoing parameters; this requires - // going over all outgoing calls and get the maximum space needed for the - // actuals - seg_actual.size = FindLargestActualArea(); - func->SetOutParmSize(seg_actual.size); - - // allocate seg_actual in seg_SPbased - seg_actual.how_alloc.mem_segment = &seg_SPbased; - seg_actual.how_alloc.offset = seg_SPbased.size; - seg_SPbased.size = maplebe::RoundUp(seg_SPbased.size, GetPrimTypeSize(PTY_ptr)); - seg_SPbased.size += seg_actual.size; - seg_SPbased.size = maplebe::RoundUp(seg_SPbased.size, GetPrimTypeSize(PTY_ptr)); -} - -inline uint8 GetU8Const(MIRConst *c) { - MIRIntConst *intconst = static_cast(c); - return static_cast(intconst->GetValue()); -} - -inline uint16 GetU16Const(MIRConst *c) { - MIRIntConst *intconst = static_cast(c); - return static_cast(intconst->GetValue()); -} - -inline uint32 GetU32Const(MIRConst *c) { - MIRIntConst *intconst = static_cast(c); - return static_cast(intconst->GetValue()); -} - -inline uint64 GetU64Const(MIRConst *c) { - MIRIntConst *intconst = static_cast(c); - return static_cast(intconst->GetValue()); -} - -inline uint32 GetF32Const(MIRConst *c) { - MIRFloatConst *floatconst = static_cast(c); - return static_cast(floatconst->GetIntValue()); -} - -inline uint64 GetF64Const(MIRConst *c) { - MIRDoubleConst *doubleconst = static_cast(c); - return static_cast(doubleconst->GetIntValue()); -} - -void GlobalMemLayout::FillScalarValueInMap(uint32 startaddress, PrimType pty, MIRConst *c) { - switch (pty) { - case PTY_u1: - case PTY_u8: - case PTY_i8: { - uint8 *p = &mirModule->GetGlobalBlockMap()[startaddress]; - *p = GetU8Const(c); - break; - } - case PTY_u16: - case PTY_i16: { - uint16 *p = (uint16 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetU16Const(c); - break; - } - case PTY_u32: - case PTY_i32: { - uint32 *p = (uint32 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetU32Const(c); - break; - } - case PTY_u64: - case PTY_i64: { - uint64 *p = (uint64 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetU64Const(c); - break; - } - case PTY_f32: { - uint32 *p = (uint32 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetF32Const(c); - break; - } - case PTY_f64: { - uint64 *p = (uint64 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetF64Const(c); - break; - } - default: - CHECK_FATAL(false, "FillScalarValueInMap: NYI"); - } - return; } -void GlobalMemLayout::FillTypeValueInMap(uint32 startaddress, MIRType *ty, MIRConst *c) { - switch (ty->GetKind()) { - case kTypeScalar: - FillScalarValueInMap(startaddress, ty->GetPrimType(), c); - break; - case kTypeArray: { - MIRArrayType *arraytype = static_cast(ty); - MIRType *elemtype = arraytype->GetElemType(); - int32 elemsize = elemtype->GetSize(); - MIRAggConst *aggconst = static_cast(c); - CHECK_FATAL(aggconst, "FillTypeValueInMap: inconsistent array initialization specification"); - MapleVector &constvec = aggconst->GetConstVec(); - for (MapleVector::iterator it = constvec.begin(); it != constvec.end(); - it++, startaddress += elemsize) { - FillTypeValueInMap(startaddress, elemtype, *it); - } - break; - } - case kTypeStruct: { - MIRStructType *structty = static_cast(ty); - MIRAggConst *aggconst = static_cast(c); - CHECK_FATAL(aggconst, "FillTypeValueInMap: inconsistent struct initialization specification"); - MapleVector &constvec = aggconst->GetConstVec(); - for (uint32 i = 0; i < constvec.size(); i++) { - uint32 fieldID = aggconst->GetFieldIdItem(i); - FieldPair thepair = structty->TraverseToField(fieldID); - MIRType *fieldty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - uint32 offset = be->GetFieldOffset(*structty, fieldID).first; - FillTypeValueInMap(startaddress + offset, fieldty, constvec[i]); - } - break; - } - case kTypeClass: { - MIRClassType *classty = static_cast(ty); - MIRAggConst *aggconst = static_cast(c); - CHECK_FATAL(aggconst, "FillTypeValueInMap: inconsistent class initialization specification"); - MapleVector &constvec = aggconst->GetConstVec(); - for (uint32 i = 0; i < constvec.size(); i++) { - uint32 fieldID = aggconst->GetFieldIdItem(i); - FieldPair thepair = classty->TraverseToField(fieldID); - MIRType *fieldty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - uint32 offset = be->GetFieldOffset(*classty, fieldID).first; - FillTypeValueInMap(startaddress + offset, fieldty, constvec[i]); - } - break; - } - default: - CHECK_FATAL(false, "FillTypeValueInMap: NYI"); - } -} - -void GlobalMemLayout::FillSymbolValueInMap(const MIRSymbol *sym) { - if (sym->GetKonst() == nullptr) { - return; - } - uint32 stindex = sym->GetStIndex(); - CHECK(stindex < sym_alloc_table.size(), - "index out of range in GlobalMemLayout::FillSymbolValueInMap"); - uint32 symaddress = sym_alloc_table[stindex].offset; - FillTypeValueInMap(symaddress, sym->GetType(), sym->GetKonst()); - return; -} - -GlobalMemLayout::GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAllocator *mallocator) : - seg_GPbased(MS_GPbased), sym_alloc_table(mallocator->Adapter()), be(b), mirModule(mod) { +GlobalMemLayout::GlobalMemLayout(MIRModule *mod, MapleAllocator *mallocator) : + seg_GPbased(MS_GPbased), sym_alloc_table(mallocator->Adapter()), mirModule(mod) { uint32 symtabsize = GlobalTables::GetGsymTable().GetSymbolTableSize(); sym_alloc_table.resize(symtabsize); MIRSymbol *sym = nullptr; @@ -329,6 +73,9 @@ GlobalMemLayout::GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAll if (sym->GetStorageClass() != kScGlobal && sym->GetStorageClass() != kScFstatic) { continue; } + if (!sym->LMBCAllocateOffSpecialReg()) { + continue; + } if (sym->GetType()->GetAlign() != curalign) { continue; } @@ -341,152 +88,6 @@ GlobalMemLayout::GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAll } seg_GPbased.size = maplebe::RoundUp(seg_GPbased.size, GetPrimTypeSize(PTY_ptr)); mirModule->SetGlobalMemSize(seg_GPbased.size); - // allocate the memory map for the GP block - mirModule->SetGlobalBlockMap( - static_cast(mirModule->GetMemPool()->Calloc(seg_GPbased.size))); - // perform initialization on globalblkmap - for (uint32 i = 0; i < symtabsize; i++) { - sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(i); - if (!sym) { - continue; - } - if (sym->GetStorageClass() != kScGlobal && sym->GetStorageClass() != kScFstatic) { - continue; - } - } -} - -// LocateNextParm should be called with each parameter in the parameter list -// starting from the beginning, one call per parameter in sequence; it returns -// the information on how each parameter is passed in ploc -void ParmLocator::LocateNextParm(const MIRType *ty, PLocInfo &ploc) { - ploc.memoffset = maplebe::RoundUp(lastMemOffset, 8); - ploc.memsize = ty->GetSize(); - - uint32 rightpad = 0; - parmNum++; - - switch (ty->GetPrimType()) { - case PTY_u1: - case PTY_u8: - case PTY_i8: - case PTY_u16: - case PTY_i16: - rightpad = GetPrimTypeSize(PTY_i32) - ploc.memsize; - break; - case PTY_a32: - case PTY_u32: - case PTY_i32: - case PTY_a64: - case PTY_u64: - case PTY_i64: - case PTY_ptr: - case PTY_ref: -#ifdef DYNAMICLANG - case PTY_simplestr: - case PTY_simpleobj: - case PTY_dynany: - case PTY_dyni32: - case PTY_dynf64: - case PTY_dynstr: - case PTY_dynobj: - case PTY_dynundef: - case PTY_dynbool: - case PTY_dynf32: - case PTY_dynnone: - case PTY_dynnull: -#endif - break; - - case PTY_f32: - rightpad = GetPrimTypeSize(PTY_f64) - ploc.memsize; - break; - case PTY_c64: - case PTY_f64: - case PTY_v2i32: - case PTY_v4i16: - case PTY_v8i8: - case PTY_v2u32: - case PTY_v4u16: - case PTY_v8u8: - case PTY_v2f32: - break; - - case PTY_c128: - case PTY_v2i64: - case PTY_v4i32: - case PTY_v8i16: - case PTY_v16i8: - case PTY_v2u64: - case PTY_v4u32: - case PTY_v8u16: - case PTY_v16u8: - case PTY_v2f64: - case PTY_v4f32: - break; - - case PTY_agg: { - // compute rightpad - int32 paddedSize = maplebe::RoundUp(ploc.memsize, 8); - rightpad = paddedSize - ploc.memsize; - break; - } - default: - CHECK_FATAL(false, "unsupported type"); - } - - lastMemOffset = ploc.memoffset + ploc.memsize + rightpad; - return; -} - -// instantiated with the type of the function return value, it describes how -// the return value is to be passed back to the caller -ReturnMechanism::ReturnMechanism(const MIRType *retty) : fake_first_parm(false) { - switch (retty->GetPrimType()) { - case PTY_u1: - case PTY_u8: - case PTY_i8: - case PTY_u16: - case PTY_i16: - case PTY_a32: - case PTY_u32: - case PTY_i32: - case PTY_a64: - case PTY_u64: - case PTY_i64: - case PTY_f32: - case PTY_f64: -#ifdef DYNAMICLANG - case PTY_simplestr: - case PTY_simpleobj: - case PTY_dynany: - case PTY_dyni32: - case PTY_dynstr: - case PTY_dynobj: -#endif - ptype0 = retty->GetPrimType(); - return; - - case PTY_c64: - case PTY_c128: - fake_first_parm = true; - ptype0 = PTY_a32; - return; - - case PTY_agg: { - uint32 size = retty->GetSize(); - if (size > 4) { - fake_first_parm = true; - ptype0 = PTY_a32; - } else { - ptype0 = PTY_u32; - } - return; - } - - default: - return; - } } } // namespace maple diff --git a/src/mapleall/maple_me/src/me_cfg.cpp b/src/mapleall/maple_me/src/me_cfg.cpp index c1d452d10a..521cb1a944 100644 --- a/src/mapleall/maple_me/src/me_cfg.cpp +++ b/src/mapleall/maple_me/src/me_cfg.cpp @@ -260,6 +260,7 @@ bool MeCFG::FindUse(const StmtNode &stmt, StIdx stIdx) const { case OP_customcall: case OP_polymorphiccall: case OP_icall: + case OP_icallproto: case OP_intrinsiccall: case OP_xintrinsiccall: case OP_intrinsiccallwithtype: @@ -272,6 +273,7 @@ bool MeCFG::FindUse(const StmtNode &stmt, StIdx stIdx) const { case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_intrinsiccallassigned: case OP_xintrinsiccallassigned: case OP_intrinsiccallwithtypeassigned: diff --git a/src/mapleall/maple_me/src/me_function.cpp b/src/mapleall/maple_me/src/me_function.cpp index 05181df796..a62f1a89a3 100755 --- a/src/mapleall/maple_me/src/me_function.cpp +++ b/src/mapleall/maple_me/src/me_function.cpp @@ -303,7 +303,9 @@ void MeFunction::CloneBBMeStmts(BB &srcBB, BB &destBB, std::map(&stmt); newStmt = irmap->NewInPool(static_cast(icallStmt), icallStmt->GetRetTyIdx(), icallStmt->GetStmtID()); diff --git a/src/mapleall/maple_me/src/me_lower_globals.cpp b/src/mapleall/maple_me/src/me_lower_globals.cpp index c14dd5c764..fdf2df8e3f 100644 --- a/src/mapleall/maple_me/src/me_lower_globals.cpp +++ b/src/mapleall/maple_me/src/me_lower_globals.cpp @@ -185,7 +185,12 @@ void MeLowerGlobals::Run() { MeExpr *addroffuncExpr = irMap->CreateAddroffuncMeExpr(callee.GetPuidx()); auto insertpos = callStmt.GetOpnds().begin(); callStmt.InsertOpnds(insertpos, addroffuncExpr); - IcallMeStmt *icallStmt = irMap->NewInPool(stmt.GetOp() == OP_call ? OP_icall : OP_icallassigned); + IcallMeStmt *icallStmt = nullptr; + if (func.GetMIRModule().IsCModule()) { + icallStmt = irMap->NewInPool(stmt.GetOp() == OP_call ? OP_icallproto : OP_icallprotoassigned); + } else { + icallStmt = irMap->NewInPool(stmt.GetOp() == OP_call ? OP_icall : OP_icallassigned); + } icallStmt->SetIsLive(callStmt.GetIsLive()); icallStmt->SetSrcPos(callStmt.GetSrcPosition()); for (MeExpr *o : callStmt.GetOpnds()) { @@ -193,7 +198,11 @@ void MeLowerGlobals::Run() { } icallStmt->GetMuList()->insert(callStmt.GetMuList()->begin(), callStmt.GetMuList()->end()); icallStmt->GetChiList()->insert(callStmt.GetChiList()->begin(), callStmt.GetChiList()->end()); - icallStmt->SetRetTyIdx(callee.GetReturnTyIdx()); + if (func.GetMIRModule().IsCModule()) { + icallStmt->SetRetTyIdx(callee.GetMIRFuncType()->GetTypeIndex()); + } else { + icallStmt->SetRetTyIdx(callee.GetReturnTyIdx()); + } if (stmt.GetOp() != OP_call) { if (callStmt.NeedDecref()) { icallStmt->EnableNeedDecref(); diff --git a/src/mapleall/maple_me/src/me_phase_manager.cpp b/src/mapleall/maple_me/src/me_phase_manager.cpp index 09a1b64e5a..a0b5419a8e 100644 --- a/src/mapleall/maple_me/src/me_phase_manager.cpp +++ b/src/mapleall/maple_me/src/me_phase_manager.cpp @@ -140,8 +140,8 @@ bool MeFuncPM::PhaseRun(maple::MIRModule &m) { } if (genLMBC) { m.SetFlavor(kFlavorLmbc); + GlobalMemLayout globalMemLayout(&m, &m.GetMPAllocator()); maplebe::BECommon beCommon(m); - GlobalMemLayout globalMemLayout(&beCommon, &m, &m.GetMPAllocator()); maplebe::CGLowerer cgLower(m, beCommon, false, false); cgLower.RegisterBuiltIns(); cgLower.RegisterExternalLibraryFunctions(); @@ -153,14 +153,15 @@ bool MeFuncPM::PhaseRun(maple::MIRModule &m) { cgLower.LowerFunc(*func); MemPool *layoutMp = memPoolCtrler.NewMemPool("layout mempool", true); MapleAllocator layoutAlloc(layoutMp); - LMBCMemLayout localMemLayout(func, &layoutAlloc); + LMBCMemLayout localMemLayout(func, &globalMemLayout.seg_GPbased, &layoutAlloc); localMemLayout.LayoutStackFrame(); LMBCLowerer lmbcLowerer(&m, &beCommon, func, &globalMemLayout, &localMemLayout); lmbcLowerer.LowerFunction(); func->SetFrameSize(localMemLayout.StackFrameSize()); - func->SetUpFormalSize(localMemLayout.UpformalSize()); memPoolCtrler.DeleteMemPool(layoutMp); } + globalMemLayout.seg_GPbased.size = maplebe::RoundUp(globalMemLayout.seg_GPbased.size, GetPrimTypeSize(PTY_ptr)); + m.SetGlobalMemSize(globalMemLayout.seg_GPbased.size); // output .lmbc BinaryMplt binMplt(m); std::string modFileName = m.GetFileName(); diff --git a/src/mapleall/maple_me/src/me_rc_lowering.cpp b/src/mapleall/maple_me/src/me_rc_lowering.cpp index 8b3897a1c6..edf6f45509 100644 --- a/src/mapleall/maple_me/src/me_rc_lowering.cpp +++ b/src/mapleall/maple_me/src/me_rc_lowering.cpp @@ -1144,6 +1144,7 @@ void RCLowering::HandleArguments() { firstBB->InsertMeStmtBefore(firstMeStmt, incCall); } sym->SetLocalRefVar(); + mirFunc->GetFormalDefVec()[i].formalAttrs.SetAttr(ATTR_localrefvar); for (auto *stmt : rets) { std::vector opnds = { argVar }; diff --git a/src/mapleall/maple_me/src/me_rename2preg.cpp b/src/mapleall/maple_me/src/me_rename2preg.cpp index 9549dff004..eddc9704b9 100644 --- a/src/mapleall/maple_me/src/me_rename2preg.cpp +++ b/src/mapleall/maple_me/src/me_rename2preg.cpp @@ -317,6 +317,7 @@ void SSARename2Preg::Rename2PregStmt(MeStmt *stmt) { case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_intrinsiccallassigned: case OP_xintrinsiccallassigned: case OP_intrinsiccallwithtypeassigned: { diff --git a/src/mapleall/maple_me/src/me_side_effect.cpp b/src/mapleall/maple_me/src/me_side_effect.cpp index ad493a9e01..2df2f0a2c5 100644 --- a/src/mapleall/maple_me/src/me_side_effect.cpp +++ b/src/mapleall/maple_me/src/me_side_effect.cpp @@ -932,6 +932,7 @@ bool IpaSideEffect::UpdateSideEffectWithStmt(MeStmt &meStmt, case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_superclasscallassigned: case OP_asm: { hasPrivateDef = hasThrException = true; @@ -958,7 +959,8 @@ bool IpaSideEffect::UpdateSideEffectWithStmt(MeStmt &meStmt, case OP_interfaceicall: case OP_customcall: case OP_polymorphiccall: - case OP_icall: { + case OP_icall: + case OP_icallproto: { hasPrivateDef = hasThrException = true; SetHasDef(); for (size_t i = 0; i < meStmt.NumMeStmtOpnds(); ++i) { diff --git a/src/mapleall/maple_me/src/me_stmt_pre.cpp b/src/mapleall/maple_me/src/me_stmt_pre.cpp index e851282f1b..991d5066e9 100755 --- a/src/mapleall/maple_me/src/me_stmt_pre.cpp +++ b/src/mapleall/maple_me/src/me_stmt_pre.cpp @@ -967,7 +967,9 @@ void MeStmtPre::BuildWorkListBB(BB *bb) { break; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { auto &icallMeStmt = static_cast(stmt); VersionStackChiListUpdate(*icallMeStmt.GetChiList()); break; diff --git a/src/mapleall/maple_me/src/pme_emit.cpp b/src/mapleall/maple_me/src/pme_emit.cpp index 227cb6a761..52e1df6beb 100755 --- a/src/mapleall/maple_me/src/pme_emit.cpp +++ b/src/mapleall/maple_me/src/pme_emit.cpp @@ -485,10 +485,12 @@ StmtNode* PreMeEmitter::EmitPreMeStmt(MeStmt *mestmt, BaseNode *parent) { return callnode; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { IcallMeStmt *icallMeStmt = static_cast (mestmt); IcallNode *icallnode = - codeMP->New(*codeMPAlloc, OP_icallassigned, icallMeStmt->GetRetTyIdx()); + codeMP->New(*codeMPAlloc, OP_icallprotoassigned, icallMeStmt->GetRetTyIdx()); for (uint32 i = 0; i < icallMeStmt->GetOpnds().size(); i++) { icallnode->GetNopnd().push_back(EmitPreMeExpr(icallMeStmt->GetOpnd(i), icallnode)); } @@ -509,6 +511,9 @@ StmtNode* PreMeEmitter::EmitPreMeStmt(MeStmt *mestmt, BaseNode *parent) { icallnode->SetRetTyIdx(TyIdx(preg->GetPrimType())); } } + if (mestmt->GetOp() == OP_icallproto || mestmt->GetOp() == OP_icallprotoassigned) { + icallnode->SetRetTyIdx(icallMeStmt->GetRetTyIdx()); + } icallnode->CopySafeRegionAttr(mestmt->GetStmtAttr()); icallnode->SetOriginalID(mestmt->GetOriginalId()); PreMeStmtExtensionMap[icallnode->GetStmtID()] = pmeExt; diff --git a/src/mapleall/maple_me/src/ssa_devirtual.cpp b/src/mapleall/maple_me/src/ssa_devirtual.cpp index 15a609e427..f46e8e06ce 100644 --- a/src/mapleall/maple_me/src/ssa_devirtual.cpp +++ b/src/mapleall/maple_me/src/ssa_devirtual.cpp @@ -534,7 +534,9 @@ void SSADevirtual::TraversalMeStmt(MeStmt &meStmt) { break; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { auto *icallMeStmt = static_cast(&meStmt); const MapleVector &opnds = icallMeStmt->GetOpnds(); for (size_t i = 0; i < opnds.size(); ++i) { diff --git a/src/mapleall/maple_me/src/ssa_pre.cpp b/src/mapleall/maple_me/src/ssa_pre.cpp index ceff080daa..a082b80b9f 100644 --- a/src/mapleall/maple_me/src/ssa_pre.cpp +++ b/src/mapleall/maple_me/src/ssa_pre.cpp @@ -1666,6 +1666,7 @@ void SSAPre::BuildWorkListStmt(MeStmt &stmt, uint32 seqStmt, bool isRebuilt, MeE case OP_customcall: case OP_polymorphiccall: case OP_icall: + case OP_icallproto: case OP_callassigned: case OP_virtualcallassigned: case OP_virtualicallassigned: @@ -1675,6 +1676,7 @@ void SSAPre::BuildWorkListStmt(MeStmt &stmt, uint32 seqStmt, bool isRebuilt, MeE case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_asm: { auto *naryMeStmt = static_cast(meStmt); const MapleVector &opnds = naryMeStmt->GetOpnds(); diff --git a/src/mapleall/mpl2mpl/src/constantfold.cpp b/src/mapleall/mpl2mpl/src/constantfold.cpp index 860ed2846a..d89d6ef64d 100644 --- a/src/mapleall/mpl2mpl/src/constantfold.cpp +++ b/src/mapleall/mpl2mpl/src/constantfold.cpp @@ -162,6 +162,8 @@ StmtNode *ConstantFold::Simplify(StmtNode *node) { return SimplifyNary(static_cast(node)); case OP_icall: case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: return SimplifyIcall(static_cast(node)); case OP_asm: return SimplifyAsm(static_cast(node)); @@ -2618,8 +2620,8 @@ StmtNode *ConstantFold::SimplifyIcall(IcallNode *node) { AddroffuncNode *addrofNode = static_cast(node->GetNopndAt(0)); CallNode *callNode = mirModule->CurFuncCodeMemPool()->New(*mirModule, - node->GetOpCode() == OP_icall ? OP_call : OP_callassigned); - if (node->GetOpCode() == OP_icallassigned) { + (node->GetOpCode() == OP_icall || node->GetOpCode() == OP_icallproto) ? OP_call : OP_callassigned); + if (node->GetOpCode() == OP_icallassigned || node->GetOpCode() == OP_icallprotoassigned) { callNode->SetReturnVec(node->GetReturnVec()); } callNode->SetPUIdx(addrofNode->GetPUIdx()); -- Gitee From da1d5c0a753932d1cf80105d4f623c951cb73303 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:44 -0700 Subject: [PATCH 010/124] Fred's Fixed determination logic of when there is fake parameter for returning struct, where x8 is also used to pass the fake parameter --- .../maple_be/src/cg/aarch64/aarch64_args.cpp | 4 ++-- .../src/cg/aarch64/aarch64_call_conv.cpp | 11 ++++++----- .../maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 18 ++++++++++++------ .../src/cg/aarch64/aarch64_memlayout.cpp | 4 ++-- 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 7962d54991..0ff53f6e5b 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -38,7 +38,7 @@ void AArch64MoveRegArgs::CollectRegisterArgs(std::map &argsL uint32 start = 0; if (numFormal) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsFirstArgReturn()) { + if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16ByteSize) { start = 1; @@ -436,7 +436,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsFirstArgReturn()) { + if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp index b584778b3a..d58374306e 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp @@ -306,18 +306,18 @@ int32 AArch64CallConvImpl::LocateNextParm(MIRType &mirType, CCLocInfo &pLoc, boo if (size == 0) { /* For return struct size 0 there is no return value. */ return 0; - } else if (size > k16ByteSize) { - /* For return struct size > 16 bytes the pointer returns in x8. */ - pLoc.reg0 = R8; - return kSizeOfPtr; } + /* For return struct size > 16 bytes the pointer returns in x8. */ + pLoc.reg0 = R8; + return kSizeOfPtr; +#if 0 /* For return struct size less or equal to 16 bytes, the values * are returned in register pairs. * Check for pure float struct. */ AArch64ArgumentClass classes[kMaxRegCount] = { kAArch64NoClass }; uint32 fpSize; - MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(beCommon.GetFuncReturnType(*func)); + MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); uint32 numRegs = static_cast(ClassifyAggregate(beCommon, *retType, classes, sizeof(classes), fpSize)); if (classes[0] == kAArch64FloatClass) { CHECK_FATAL(numRegs <= kMaxRegCount, "LocateNextParm: illegal number of regs"); @@ -334,6 +334,7 @@ int32 AArch64CallConvImpl::LocateNextParm(MIRType &mirType, CCLocInfo &pLoc, boo } return 0; } +#endif } } uint64 typeSize = beCommon.GetTypeSize(mirType.GetTypeIndex()); 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 e1c70562ba..7925a66361 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8064,6 +8064,17 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo std::set specialArgs; SelectParmListPreprocess(naryNode, i, specialArgs); bool specialArg = false; + bool firstArgReturn = false; + MIRFunction *callee = nullptr; + if (dynamic_cast(&naryNode) != nullptr) { + auto calleePuIdx = static_cast(naryNode).GetPUIdx(); + callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + firstArgReturn = callee->IsFirstArgReturn(); + } else if (naryNode.GetOpCode() == OP_icallproto) { + IcallNode *icallnode = &static_cast(naryNode); + MIRFuncType *funcType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallnode->GetRetTyIdx())); + firstArgReturn = funcType->FirstArgReturn(); + } BB *curBBrecord = GetCurBB(); BB *tmpBB = nullptr; if (!specialArgs.empty()) { @@ -8085,11 +8096,6 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); - MIRFunction *callee = nullptr; - if (dynamic_cast(&naryNode) != nullptr) { - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); - } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } @@ -8154,7 +8160,7 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo } expRegOpnd = static_cast(opnd); - if ((pnum == 0) && (SelectParmListGetStructReturnSize(naryNode) > k16ByteSize)) { + if ((pnum == 0) && firstArgReturn) { parmLocator.InitCCLocInfo(ploc); ploc.reg0 = R8; } else { diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp index 71f57d89ea..de95e9be33 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp @@ -210,7 +210,7 @@ void AArch64MemLayout::LayoutFormalParams() { AArch64SymbolAlloc *symLoc = memAllocator->GetMemPool()->New(); SetSymAllocInfo(stIndex, *symLoc); if (i == 0) { - if (mirFunction->IsFirstArgReturn()) { + if (mirFunction->IsReturnStruct() && mirFunction->IsFirstArgReturn()) { symLoc->SetMemSegment(GetSegArgsRegPassed()); symLoc->SetOffset(GetSegArgsRegPassed().GetSize()); TyIdx tyIdx = mirFunction->GetFuncRetStructTyIdx(); @@ -395,7 +395,7 @@ void AArch64MemLayout::LayoutReturnRef(std::vector &returnDelays, void AArch64MemLayout::LayoutActualParams() { for (size_t i = 0; i < mirFunction->GetFormalCount(); ++i) { if (i == 0) { - if (mirFunction->IsReturnStruct()) { + if (mirFunction->IsReturnStruct() && mirFunction->IsFirstArgReturn()) { continue; } } -- Gitee From 0df7c095097c47815db8a148b411002a57f04264 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:53:00 -0700 Subject: [PATCH 011/124] Remove unneeded fp def. Turn on tailcall. no unneeded pro/epilog. --- .../maple_be/include/cg/aarch64/aarch64_color_ra.h | 1 + src/mapleall/maple_be/include/cg/cgfunc.h | 9 +++++++++ .../maple_be/src/cg/aarch64/aarch64_color_ra.cpp | 6 ++++++ .../maple_be/src/cg/aarch64/aarch64_proepilog.cpp | 7 +++---- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h index 491d59453f..d0588c51c4 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h @@ -1519,6 +1519,7 @@ class GraphColorRegAllocator : public RegAllocator { #endif bool hasSpill = false; bool doMultiPass = false; + bool seenFP = false; }; class CallerSavePre: public CGPre { diff --git a/src/mapleall/maple_be/include/cg/cgfunc.h b/src/mapleall/maple_be/include/cg/cgfunc.h index bc0a48089e..ca10190aad 100644 --- a/src/mapleall/maple_be/include/cg/cgfunc.h +++ b/src/mapleall/maple_be/include/cg/cgfunc.h @@ -1107,6 +1107,14 @@ class CGFunc { return useFP; } + void UnsetSeenFP() { + seenFP = false; + } + + bool SeenFP() const { + return seenFP; + } + void UpdateAllRegisterVregMapping(MapleMap &newMap); void RegisterVregMapping(regno_t vRegNum, PregIdx pidx) { @@ -1276,6 +1284,7 @@ class CGFunc { const MapleString shortFuncName; bool hasAsm = false; bool useFP = true; + bool seenFP = true; /* save stack protect kinds which can trigger stack protect */ uint8 stackProtectInfo = 0; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp index 3b878b6c7a..1ed5f1480a 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp @@ -3629,6 +3629,9 @@ RegOperand *GraphColorRegAllocator::GetReplaceOpnd(Insn &insn, const Operand &op auto ®Opnd = static_cast(opnd); uint32 vregNO = regOpnd.GetRegisterNumber(); + if (vregNO == RFP) { + seenFP = true; + } RegType regType = regOpnd.GetRegisterType(); if (vregNO < kAllRegNum) { return nullptr; @@ -4996,6 +4999,9 @@ bool GraphColorRegAllocator::AllocateRegisters() { MarkCalleeSaveRegs(); + if (seenFP == false) { + cgFunc->UnsetSeenFP(); + } if (GCRA_DUMP) { cgFunc->DumpCGIR(); } diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp index 0c2322d055..40cd20362a 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp @@ -185,9 +185,6 @@ void AArch64GenProEpilog::TailCallBBOpt(BB &bb, MapleSet &callInsns, BB & * Return value: true if function do not need Prologue/Epilogue. false otherwise. */ bool AArch64GenProEpilog::TailCallOpt() { - if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { - return false; - } /* Count how many call insns in the whole function. */ uint32 nCount = 0; bool hasGetStackClass = false; @@ -1229,7 +1226,9 @@ void AArch64GenProEpilog::GeneratePushRegs() { } else { immOpnd = &aarchCGFunc.CreateImmOperand(argsToStkPassSize, k32BitSize, true); } - aarchCGFunc.SelectAdd(fpOpnd, spOpnd, *immOpnd, PTY_u64); + if (isLmbc == false || cgFunc.SeenFP() || cgFunc.GetFunction().GetAttr(FUNCATTR_varargs)) { + aarchCGFunc.SelectAdd(fpOpnd, spOpnd, *immOpnd, PTY_u64); + } cgFunc.GetCurBB()->GetLastInsn()->SetFrameDef(true); if (cgFunc.GenCfi()) { cgFunc.GetCurBB()->AppendInsn(aarchCGFunc.CreateCfiDefCfaInsn(stackBaseReg, -- Gitee From 4d7678e7d650ba65782d6aa5151b98ef825913cc Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:53:14 -0700 Subject: [PATCH 012/124] Fred's Set firstarg_return attribute in the new funcAttrs field in MIRFuncType --- src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp | 3 +++ src/mapleall/maple_ir/src/mir_lower.cpp | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp b/src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp index 3a77948b15..63c34ea154 100644 --- a/src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp +++ b/src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp @@ -278,6 +278,9 @@ bool ASTFunc2FEHelper::ProcessDeclImpl(MapleAllocator &allocator) { ENCChecker::InsertBoundaryInAtts(attrs, func.GetBoundaryInfo()); mirMethodPair.second.second = attrs; mirFunc->SetFuncAttrs(attrs); + if (firstArgRet) { + mirFunc->GetMIRFuncType()->funcAttrs.SetAttr(FUNCATTR_firstarg_return); + } func.ClearGenericAttrsContentMap(); return true; } diff --git a/src/mapleall/maple_ir/src/mir_lower.cpp b/src/mapleall/maple_ir/src/mir_lower.cpp index aa5cb0131c..9b8c3f8d92 100644 --- a/src/mapleall/maple_ir/src/mir_lower.cpp +++ b/src/mapleall/maple_ir/src/mir_lower.cpp @@ -539,6 +539,10 @@ BlockNode *MIRLower::LowerBlock(BlockNode &block) { MIRFuncType *funcType = FuncTypeFromFuncPtrExpr(stmt->Opnd(0)); CHECK_FATAL(funcType != nullptr, "MIRLower::LowerBlock: cannot find prototype for icall"); ic->SetRetTyIdx(funcType->GetTypeIndex()); + MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcType->GetRetTyIdx()); + if (retType->GetPrimType() == PTY_agg && retType->GetSize() > 16) { + funcType->funcAttrs.SetAttr(FUNCATTR_firstarg_return); + } } newBlock->AddStatement(stmt); break; -- Gitee From 4a1ce18f5ea5a0e436b2d7ee03d3f63713a545ea Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 15 Jun 2022 16:18:04 -0700 Subject: [PATCH 013/124] Fix accessing localrefvar in memlayout by qualifying with language --- src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h | 2 +- src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 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 c2d555be1a..11386076cd 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -129,7 +129,7 @@ class AArch64CGFunc : public CGFunc { uint32 LmbcFindTotalStkUsed(std::vector* paramList); uint32 LmbcTotalRegsUsed(); void LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn); - bool LmbcSmallAggForRet(BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *src); bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp index de95e9be33..97bfc6ef52 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp @@ -230,7 +230,7 @@ void AArch64MemLayout::LayoutFormalParams() { if (ploc.reg0 != kRinvalid) { /* register */ symLoc->SetRegisters(static_cast(ploc.reg0), static_cast(ploc.reg1), static_cast(ploc.reg2), static_cast(ploc.reg3)); - if (mirFunction->GetFormalDefVec()[i].formalAttrs.GetAttr(ATTR_localrefvar)) { + if (!cgFunc->GetMirModule().IsCModule() && mirFunction->GetNthParamAttr(i).GetAttr(ATTR_localrefvar)) { symLoc->SetMemSegment(segRefLocals); SetSegmentSize(*symLoc, segRefLocals, ptyIdx); } else if (!sym->IsPreg()) { @@ -272,7 +272,7 @@ void AArch64MemLayout::LayoutFormalParams() { } else { segArgsStkPassed.SetSize(static_cast(RoundUp(segArgsStkPassed.GetSize(), kSizeOfPtr))); } - if (mirFunction->GetFormalDefVec()[i].formalAttrs.GetAttr(ATTR_localrefvar)) { + if (!cgFunc->GetMirModule().IsCModule() && mirFunction->GetNthParamAttr(i).GetAttr(ATTR_localrefvar)) { SetLocalRegLocInfo(sym->GetStIdx(), *symLoc); AArch64SymbolAlloc *symLoc1 = memAllocator->GetMemPool()->New(); symLoc1->SetMemSegment(segRefLocals); -- Gitee From 860cb5c0fbd44c885daee964bd5f5a581dc28195 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Thu, 16 Jun 2022 10:44:59 -0700 Subject: [PATCH 014/124] Set appearsInCode and puidxOrigin fields in newly cloned functions --- src/mapleall/maple_ipa/src/ipa_clone.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mapleall/maple_ipa/src/ipa_clone.cpp b/src/mapleall/maple_ipa/src/ipa_clone.cpp index 26aee0aaf6..ac04f15497 100644 --- a/src/mapleall/maple_ipa/src/ipa_clone.cpp +++ b/src/mapleall/maple_ipa/src/ipa_clone.cpp @@ -107,6 +107,8 @@ MIRFunction *IpaClone::IpaCloneFunction(MIRFunction &originalFunction, const std newFunc->SetSrcPosition(originalFunction.GetSrcPosition()); newFunc->SetFuncAttrs(originalFunction.GetFuncAttrs()); newFunc->SetBaseClassFuncNames(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fullName)); + newFunc->GetFuncSymbol()->SetAppearsInCode(true); + newFunc->SetPuidxOrigin(newFunc->GetPuidx()); if (originalFunction.GetBody() != nullptr) { CopyFuncInfo(originalFunction, *newFunc); newFunc->SetBody( @@ -135,6 +137,8 @@ MIRFunction *IpaClone::IpaCloneFunctionWithFreq(MIRFunction &originalFunction, newFunc->SetSrcPosition(originalFunction.GetSrcPosition()); newFunc->SetFuncAttrs(originalFunction.GetFuncAttrs()); newFunc->SetBaseClassFuncNames(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fullName)); + newFunc->GetFuncSymbol()->SetAppearsInCode(true); + newFunc->SetPuidxOrigin(newFunc->GetPuidx()); GcovFuncInfo *origProfData = originalFunction.GetFuncProfData(); auto *moduleMp = mirBuilder.GetMirModule().GetMemPool(); GcovFuncInfo *newProfData = moduleMp->New(&mirBuilder.GetMirModule().GetMPAllocator(), -- Gitee From 285d77d523474afbe60442f42b3b12b655fa527c Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 015/124] Changes from mplcglmbc8 and mplcglmbc9. --- src/mapleall/maple_be/include/be/lower.h | 2 +- .../include/cg/aarch64/aarch64_cgfunc.h | 32 +- .../include/cg/aarch64/aarch64_phases.def | 2 +- src/mapleall/maple_be/include/cg/call_conv.h | 22 +- src/mapleall/maple_be/include/cg/cg.h | 19 +- src/mapleall/maple_be/include/cg/cgfunc.h | 2 + src/mapleall/maple_be/src/be/lower.cpp | 82 ++- .../maple_be/src/cg/aarch64/aarch64_args.cpp | 4 +- .../src/cg/aarch64/aarch64_call_conv.cpp | 2 +- .../src/cg/aarch64/aarch64_cgfunc.cpp | 547 +++++++++++++++--- .../maple_be/src/cg/aarch64/aarch64_ebo.cpp | 4 +- .../src/cg/aarch64/aarch64_memlayout.cpp | 32 +- .../src/cg/aarch64/aarch64_offset_adjust.cpp | 2 +- .../src/cg/aarch64/aarch64_proepilog.cpp | 87 ++- .../src/cg/aarch64/aarch64_reaching.cpp | 3 +- .../maple_be/src/cg/cg_phasemanager.cpp | 1 + src/mapleall/maple_be/src/cg/cgfunc.cpp | 44 +- src/mapleall/maple_be/src/cg/emit.cpp | 5 + src/mapleall/maple_be/src/cg/memlayout.cpp | 6 +- .../maple_ir/include/bin_mpl_export.h | 28 +- .../maple_ir/include/bin_mpl_import.h | 12 +- .../maple_ir/include/ir_safe_cast_traits.def | 4 +- src/mapleall/maple_ir/include/keywords.def | 1 - src/mapleall/maple_ir/include/mir_builder.h | 2 + src/mapleall/maple_ir/include/mir_function.h | 18 +- src/mapleall/maple_ir/include/mir_lower.h | 1 + src/mapleall/maple_ir/include/mir_nodes.h | 2 +- src/mapleall/maple_ir/include/mir_parser.h | 2 +- src/mapleall/maple_ir/include/mir_symbol.h | 6 +- src/mapleall/maple_ir/include/mir_type.h | 27 +- src/mapleall/maple_ir/include/opcode_info.h | 1 + src/mapleall/maple_ir/include/opcodes.def | 1 + src/mapleall/maple_ir/include/opcodes.h | 4 +- src/mapleall/maple_ir/src/bin_func_export.cpp | 239 ++++---- src/mapleall/maple_ir/src/bin_func_import.cpp | 248 ++++---- src/mapleall/maple_ir/src/bin_mpl_export.cpp | 112 ++-- src/mapleall/maple_ir/src/bin_mpl_import.cpp | 48 +- src/mapleall/maple_ir/src/global_tables.cpp | 4 +- src/mapleall/maple_ir/src/mir_builder.cpp | 24 + src/mapleall/maple_ir/src/mir_function.cpp | 4 +- src/mapleall/maple_ir/src/mir_lower.cpp | 107 ++++ src/mapleall/maple_ir/src/mir_nodes.cpp | 4 +- src/mapleall/maple_ir/src/mir_parser.cpp | 31 +- src/mapleall/maple_ir/src/mir_type.cpp | 8 +- src/mapleall/maple_ir/src/parser.cpp | 18 +- src/mapleall/maple_me/include/lmbc_lower.h | 3 - .../maple_me/include/lmbc_memlayout.h | 59 +- src/mapleall/maple_me/src/alias_class.cpp | 8 +- src/mapleall/maple_me/src/code_factoring.cpp | 4 +- .../src/demand_driven_alias_analysis.cpp | 4 +- src/mapleall/maple_me/src/irmap_build.cpp | 7 +- src/mapleall/maple_me/src/irmap_emit.cpp | 5 +- src/mapleall/maple_me/src/lfo_dep_test.cpp | 2 + src/mapleall/maple_me/src/lmbc_lower.cpp | 258 ++------- src/mapleall/maple_me/src/lmbc_memlayout.cpp | 439 +------------- src/mapleall/maple_me/src/me_cfg.cpp | 2 + src/mapleall/maple_me/src/me_function.cpp | 4 +- .../maple_me/src/me_lower_globals.cpp | 13 +- .../maple_me/src/me_phase_manager.cpp | 7 +- src/mapleall/maple_me/src/me_rc_lowering.cpp | 1 + src/mapleall/maple_me/src/me_rename2preg.cpp | 1 + src/mapleall/maple_me/src/me_side_effect.cpp | 4 +- src/mapleall/maple_me/src/me_stmt_pre.cpp | 4 +- src/mapleall/maple_me/src/pme_emit.cpp | 9 +- src/mapleall/maple_me/src/ssa_devirtual.cpp | 4 +- src/mapleall/maple_me/src/ssa_pre.cpp | 2 + src/mapleall/mpl2mpl/src/constantfold.cpp | 6 +- 67 files changed, 1404 insertions(+), 1296 deletions(-) diff --git a/src/mapleall/maple_be/include/be/lower.h b/src/mapleall/maple_be/include/be/lower.h index 6da66a3fcf..92c9e840e9 100644 --- a/src/mapleall/maple_be/include/be/lower.h +++ b/src/mapleall/maple_be/include/be/lower.h @@ -187,7 +187,7 @@ class CGLowerer { void LowerTryCatchBlocks(BlockNode &body); #if TARGARM32 || TARGAARCH64 || TARGRISCV64 - BlockNode *LowerReturnStruct(NaryStmtNode &retNode); + BlockNode *LowerReturnStructUsingFakeParm(NaryStmtNode &retNode); #endif virtual BlockNode *LowerReturn(NaryStmtNode &retNode); void LowerEntry(MIRFunction &func); 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 4c5a86a2fe..0bb9d7d2d0 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -38,6 +38,7 @@ class LmbcArgInfo { MapleVector lmbcCallArgTypes; MapleVector lmbcCallArgOffsets; MapleVector lmbcCallArgNumOfRegs; // # of regs needed to complete struct + uint32 lmbcTotalStkUsed = -1; // TBD: remove when explicit addr for large agg is available }; class AArch64CGFunc : public CGFunc { @@ -101,7 +102,7 @@ class AArch64CGFunc : public CGFunc { return kRFLAG; } - MIRType *GetAggTyFromCallSite(StmtNode *stmt); + MIRType *LmbcGetAggTyFromCallSite(StmtNode *stmt, std::vector **parmList); RegOperand &GetOrCreateResOperand(const BaseNode &parent, PrimType primType); void IntrinsifyGetAndAddInt(ListOperand &srcOpnds, PrimType pty); @@ -125,9 +126,11 @@ class AArch64CGFunc : public CGFunc { bool needLow12 = false); MemOperand *FixLargeMemOpnd(MemOperand &memOpnd, uint32 align); MemOperand *FixLargeMemOpnd(MOperator mOp, MemOperand &memOpnd, uint32 dSize, uint32 opndIdx); + uint32 LmbcFindTotalStkUsed(std::vector* paramList); + uint32 LmbcTotalRegsUsed(); void LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn); - bool LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *src); - bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForRet(BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; void SelectIassignoff(IassignoffNode &stmt) override; @@ -135,6 +138,7 @@ class AArch64CGFunc : public CGFunc { void SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd) override; void SelectBlkassignoff(BlkassignoffNode &bNode, Operand *src) override; void SelectAggIassign(IassignNode &stmt, Operand &lhsAddrOpnd) override; + void SelectReturnSendOfStructInRegs(BaseNode *x) override; void SelectReturn(Operand *opnd0) override; void SelectIgoto(Operand *opnd0) override; void SelectCondGoto(CondGotoNode &stmt, Operand &opnd0, Operand &opnd1) override; @@ -486,7 +490,10 @@ class AArch64CGFunc : public CGFunc { void GenerateCleanupCodeForExtEpilog(BB &bb) override; uint32 FloatParamRegRequired(MIRStructType *structType, uint32 &fpSize) override; void AssignLmbcFormalParams() override; - RegOperand *GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType); + void LmbcGenSaveSpForAlloca() override; + MemOperand *GenLmbcFpMemOperand(int32 offset, uint32 byteSize, AArch64reg base = RFP); + RegOperand *GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType, AArch64reg baseRegno = RFP); + RegOperand *LmbcStructReturnLoad(int32 offset); Operand *GetBaseReg(const AArch64SymbolAlloc &symAlloc); int32 GetBaseOffset(const SymbolAlloc &symAlloc) override; @@ -732,6 +739,22 @@ class AArch64CGFunc : public CGFunc { RegOperand &GetZeroOpnd(uint32 size) override; + int32 GetLmbcTotalStkUsed() { + return lmbcArgInfo->lmbcTotalStkUsed; + } + + void SetLmbcTotalStkUsed(int32 offset) { + lmbcArgInfo->lmbcTotalStkUsed = offset; + } + + void SetLmbcCallReturnType(MIRType *ty) { + lmbcCallReturnType = ty; + } + + MIRType *GetLmbcCallReturnType() { + return lmbcCallReturnType; + } + private: enum RelationOperator : uint8 { kAND, @@ -799,6 +822,7 @@ class AArch64CGFunc : public CGFunc { regno_t methodHandleVreg = -1; uint32 alignPow = 5; /* function align pow defaults to 5 i.e. 2^5*/ LmbcArgInfo *lmbcArgInfo = nullptr; + MIRType *lmbcCallReturnType = nullptr; void SelectLoadAcquire(Operand &dest, PrimType dtype, Operand &src, PrimType stype, AArch64isa::MemoryOrdering memOrd, bool isDirect); diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def b/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def index a3a74d7b2f..ff08e81852 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def @@ -16,8 +16,8 @@ ADDTARGETPHASE("createstartendlabel", true); ADDTARGETPHASE("buildehfunc", true); ADDTARGETPHASE("handlefunction", true); + ADDTARGETPHASE("moveargs", true); if (GetMIRModule()->GetFlavor() != MIRFlavor::kFlavorLmbc) { - ADDTARGETPHASE("moveargs", true); /* SSA PHASES */ ADDTARGETPHASE("cgssaconstruct", CGOptions::DoCGSSA()); ADDTARGETPHASE("cgcopyprop", CGOptions::DoCGSSA()); diff --git a/src/mapleall/maple_be/include/cg/call_conv.h b/src/mapleall/maple_be/include/cg/call_conv.h index 9cfab98b56..4e33309c3c 100644 --- a/src/mapleall/maple_be/include/cg/call_conv.h +++ b/src/mapleall/maple_be/include/cg/call_conv.h @@ -63,8 +63,8 @@ struct CCLocInfo { class LmbcFormalParamInfo { public: LmbcFormalParamInfo(PrimType pType, uint32 ofst, uint32 sz) : - type(nullptr), primType(pType), offset(ofst), size(sz), regNO(0), vregNO(0), numRegs(0), - fpSize(0), isReturn(false), isPureFloat(false), isOnStack(false) {} + type(nullptr), primType(pType), offset(ofst), onStackOffset(0), size(sz), regNO(0), vregNO(0), numRegs(0), + fpSize(0), isReturn(false), isPureFloat(false), isOnStack(false), hasRegassign(false) {} ~LmbcFormalParamInfo() = default; @@ -86,7 +86,13 @@ class LmbcFormalParamInfo { void SetOffset(uint32 ofs) { offset = ofs; } - uint32 GetSize() const { + uint32 GetOnStackOffset() { + return onStackOffset; + } + void SetOnStackOffset(uint32 ofs) { + onStackOffset = ofs; + } + uint32 GetSize() { return size; } void SetSize(uint32 sz) { @@ -137,10 +143,17 @@ class LmbcFormalParamInfo { void SetIsOnStack() { isOnStack = true; } + bool HasRegassign() { + return hasRegassign; + } + void SetHasRegassign() { + hasRegassign = true; + } private: MIRStructType *type; PrimType primType; uint32 offset; + uint32 onStackOffset; /* stack location if isOnStack */ uint32 size; /* size primtype or struct */ regno_t regNO = 0; /* param reg num or starting reg num if numRegs > 0 */ regno_t vregNO = 0; /* if no explicit regassing from IR, create move from param reg */ @@ -148,7 +161,8 @@ class LmbcFormalParamInfo { uint32 fpSize = 0; /* size of fp param if isPureFloat */ bool isReturn; bool isPureFloat = false; - bool isOnStack; /* small struct with arrays need to be saved onto stack */ + bool isOnStack; /* large struct is passed by a copy on stack */ + bool hasRegassign; }; } /* namespace maplebe */ diff --git a/src/mapleall/maple_be/include/cg/cg.h b/src/mapleall/maple_be/include/cg/cg.h index 093289e42b..e1368acb1d 100644 --- a/src/mapleall/maple_be/include/cg/cg.h +++ b/src/mapleall/maple_be/include/cg/cg.h @@ -121,11 +121,13 @@ class CG { emitter(nullptr), labelOrderCnt(0), cgOption(cgOptions), - instrumentationFunction(nullptr) { + instrumentationFunction(nullptr), + fileGP(nullptr) { const std::string &internalNameLiteral = namemangler::GetInternalNameLiteral(namemangler::kJavaLangObjectStr); GStrIdx strIdxFromName = GlobalTables::GetStrTable().GetStrIdxFromName(internalNameLiteral); isLibcore = (GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdxFromName) != nullptr); DefineDebugTraceFunctions(); + isLmbc = (mirModule->GetFlavor() == MIRFlavor::kFlavorLmbc); } virtual ~CG(); @@ -361,6 +363,10 @@ class CG { return isLibcore; } + bool IsLmbc() const { + return isLmbc; + } + MIRSymbol *GetDebugTraceEnterFunction() { return dbgTraceEnter; } @@ -421,6 +427,13 @@ class CG { /* Object map generation helper */ std::vector GetReferenceOffsets64(const BECommon &beCommon, MIRStructType &structType); + void SetGP(MIRSymbol *sym) { + fileGP = sym; + } + MIRSymbol *GetGP() const { + return fileGP; + } + static bool IsInFuncWrapLabels(MIRFunction *func) { return funcWrapLabels.find(func) != funcWrapLabels.end(); } @@ -449,12 +462,14 @@ class CG { LabelIDOrder labelOrderCnt; static CGFunc *currentCGFunction; /* current cg function being compiled */ CGOptions cgOption; - bool isLibcore; MIRSymbol *instrumentationFunction; MIRSymbol *dbgTraceEnter; MIRSymbol *dbgTraceExit; MIRSymbol *dbgFuncProfile; + MIRSymbol *fileGP; /* for lmbc, one local %GP per file */ static std::map> funcWrapLabels; + bool isLibcore; + bool isLmbc; }; /* class CG */ } /* namespace maplebe */ diff --git a/src/mapleall/maple_be/include/cg/cgfunc.h b/src/mapleall/maple_be/include/cg/cgfunc.h index 92a7d2ec96..bc0a48089e 100644 --- a/src/mapleall/maple_be/include/cg/cgfunc.h +++ b/src/mapleall/maple_be/include/cg/cgfunc.h @@ -160,6 +160,7 @@ class CGFunc { virtual uint32 FloatParamRegRequired(MIRStructType *structType, uint32 &fpSize) = 0; virtual void AssignLmbcFormalParams() = 0; LmbcFormalParamInfo *GetLmbcFormalParamInfo(uint32 offset); + virtual void LmbcGenSaveSpForAlloca() = 0; void GenerateLoc(StmtNode *stmt, unsigned &lastSrcLoc, unsigned &lastMplLoc); int32 GetFreqFromStmt(uint32 stmtId); void GenerateInstruction(); @@ -201,6 +202,7 @@ class CGFunc { virtual void SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd) = 0; virtual void SelectBlkassignoff(BlkassignoffNode &bNode, Operand *src) = 0; virtual void SelectAggIassign(IassignNode &stmt, Operand &lhsAddrOpnd) = 0; + virtual void SelectReturnSendOfStructInRegs(BaseNode *x) = 0; virtual void SelectReturn(Operand *opnd) = 0; virtual void SelectIgoto(Operand *opnd0) = 0; virtual void SelectCondGoto(CondGotoNode &stmt, Operand &opnd0, Operand &opnd1) = 0; diff --git a/src/mapleall/maple_be/src/be/lower.cpp b/src/mapleall/maple_be/src/be/lower.cpp index d16ff4231b..25b233f423 100644 --- a/src/mapleall/maple_be/src/be/lower.cpp +++ b/src/mapleall/maple_be/src/be/lower.cpp @@ -121,6 +121,7 @@ void CGLowerer::RegisterExternalLibraryFunctions() { func->AllocSymTab(); MIRSymbol *funcSym = func->GetFuncSymbol(); funcSym->SetStorageClass(kScExtern); + funcSym->SetAppearsInCode(true); /* return type */ MIRType *retTy = GlobalTables::GetTypeTable().GetPrimType(extFnDescrs[i].retType); @@ -878,7 +879,7 @@ void CGLowerer::LowerTypePtr(BaseNode &node) const { #if TARGARM32 || TARGAARCH64 || TARGRISCV64 -BlockNode *CGLowerer::LowerReturnStruct(NaryStmtNode &retNode) { +BlockNode *CGLowerer::LowerReturnStructUsingFakeParm(NaryStmtNode &retNode) { BlockNode *blk = mirModule.CurFuncCodeMemPool()->New(); for (size_t i = 0; i < retNode.GetNopndSize(); ++i) { retNode.SetOpnd(LowerExpr(retNode, *retNode.GetNopndAt(i), *blk), i); @@ -1103,7 +1104,7 @@ void CGLowerer::LowerCallStmt(StmtNode &stmt, StmtNode *&nextStmt, BlockNode &ne return; } - if ((newStmt->GetOpCode() == OP_call) || (newStmt->GetOpCode() == OP_icall)) { + if (newStmt->GetOpCode() == OP_call || newStmt->GetOpCode() == OP_icall || newStmt->GetOpCode() == OP_icallproto) { newStmt = LowerCall(static_cast(*newStmt), nextStmt, newBlk, retty, uselvar); } newStmt->SetSrcPos(stmt.GetSrcPos()); @@ -1174,7 +1175,12 @@ StmtNode *CGLowerer::GenIntrinsiccallNode(const StmtNode &stmt, PUIdx &funcCalle StmtNode *CGLowerer::GenIcallNode(PUIdx &funcCalled, IcallNode &origCall) { StmtNode *newCall = nullptr; - newCall = mirModule.GetMIRBuilder()->CreateStmtIcall(origCall.GetNopnd()); + if (origCall.GetOpCode() == OP_icallassigned) { + newCall = mirModule.GetMIRBuilder()->CreateStmtIcall(origCall.GetNopnd()); + } else { + newCall = mirModule.GetMIRBuilder()->CreateStmtIcallproto(origCall.GetNopnd()); + static_cast(newCall)->SetRetTyIdx(static_cast(origCall).GetRetTyIdx()); + } newCall->SetSrcPos(origCall.GetSrcPos()); CHECK_FATAL(newCall != nullptr, "nullptr is not expected"); funcCalled = kFuncNotFound; @@ -1375,6 +1381,7 @@ BlockNode *CGLowerer::LowerCallAssignedStmt(StmtNode &stmt, bool uselvar) { static_cast(newCall)->SetReturnVec(*p2nRets); break; } + case OP_icallprotoassigned: case OP_icallassigned: { auto &origCall = static_cast(stmt); newCall = GenIcallNode(funcCalled, origCall); @@ -1482,6 +1489,15 @@ bool CGLowerer::LowerStructReturn(BlockNode &newBlk, StmtNode *stmt, (*p2nrets)[0].first = dnodeStmt->GetStIdx(); (*p2nrets)[0].second.SetFieldID(dnodeStmt->GetFieldID()); lvar = true; + // set ATTR_firstarg_return for callee + if (stmt->GetOpCode() == OP_callassigned) { + CallNode *callNode = static_cast(stmt); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callNode->GetPUIdx()); + f->SetFirstArgReturn(); + f->GetMIRFuncType()->SetFirstArgReturn(); + } else { + // for icall, front-end already set ATTR_firstarg_return + } } else { /* struct <= 16 passed in regs lowered into call &foo regassign u64 %1 (regread u64 %%retval0) @@ -1499,13 +1515,19 @@ bool CGLowerer::LowerStructReturn(BlockNode &newBlk, StmtNode *stmt, CallNode *callStmt = mirModule.GetMIRBuilder()->CreateStmtCall(callNode->GetPUIdx(), callNode->GetNopnd()); callStmt->SetSrcPos(callNode->GetSrcPos()); newBlk.AddStatement(callStmt); - } else if (stmt->GetOpCode() == OP_icallassigned) { + } else if (stmt->GetOpCode() == OP_icallassigned || stmt->GetOpCode() == OP_icallprotoassigned) { auto *icallNode = static_cast(stmt); for (size_t i = 0; i < icallNode->GetNopndSize(); ++i) { BaseNode *newOpnd = LowerExpr(*icallNode, *icallNode->GetNopndAt(i), newBlk); icallNode->SetOpnd(newOpnd, i); } - IcallNode *icallStmt = mirModule.GetMIRBuilder()->CreateStmtIcall(icallNode->GetNopnd()); + IcallNode *icallStmt = nullptr; + if (stmt->GetOpCode() == OP_icallassigned) { + icallStmt = mirModule.GetMIRBuilder()->CreateStmtIcall(icallNode->GetNopnd()); + } else { + icallStmt = mirModule.GetMIRBuilder()->CreateStmtIcallproto(icallNode->GetNopnd()); + icallStmt->SetRetTyIdx(icallNode->GetRetTyIdx()); + } icallStmt->SetSrcPos(icallNode->GetSrcPos()); newBlk.AddStatement(icallStmt); } else { @@ -1770,6 +1792,7 @@ void CGLowerer::LowerAssertBoundary(StmtNode &stmt, BlockNode &block, BlockNode CondGotoNode *brFalseNode = mirBuilder->CreateStmtCondGoto(cond, OP_brfalse, labIdx); MIRFunction *printf = mirBuilder->GetOrCreateFunction("printf", TyIdx(PTY_i32)); + printf->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*printf->GetMIRFuncType()); MapleVector argsPrintf(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); uint32 oldTypeTableSize = GlobalTables::GetTypeTable().GetTypeTableSize(); @@ -1845,7 +1868,8 @@ BlockNode *CGLowerer::LowerBlock(BlockNode &block) { break; } case OP_callassigned: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallprotoassigned: { // pass the addr of lvar if this is a struct call assignment bool lvar = false; // nextStmt could be changed by the call to LowerStructReturn @@ -1865,6 +1889,7 @@ BlockNode *CGLowerer::LowerBlock(BlockNode &block) { case OP_intrinsiccall: case OP_call: case OP_icall: + case OP_icallproto: #if TARGARM32 || TARGAARCH64 || TARGRISCV64 || TARGX86_64 // nextStmt could be changed by the call to LowerStructReturn LowerCallStmt(*stmt, nextStmt, *newBlk); @@ -1874,8 +1899,8 @@ BlockNode *CGLowerer::LowerBlock(BlockNode &block) { break; case OP_return: { #if TARGARM32 || TARGAARCH64 || TARGRISCV64 - if (GetCurrentFunc()->IsReturnStruct()) { - newBlk->AppendStatementsFromBlock(*LowerReturnStruct(static_cast(*stmt))); + if (GetCurrentFunc()->IsFirstArgReturn() && stmt->NumOpnds() > 0) { + newBlk->AppendStatementsFromBlock(*LowerReturnStructUsingFakeParm(static_cast(*stmt))); } else { #endif NaryStmtNode *retNode = static_cast(stmt); @@ -1973,7 +1998,9 @@ void CGLowerer::SimplifyBlock(BlockNode &block) { } auto *newFunc = theMIRModule->GetMIRBuilder()->GetOrCreateFunction(asmMap.at(oldFunc->GetName()), callStmt->GetTyIdx()); - newFunc->GetFuncSymbol()->SetStorageClass(kScExtern); + MIRSymbol *funcSym = newFunc->GetFuncSymbol(); + funcSym->SetStorageClass(kScExtern); + funcSym->SetAppearsInCode(true); callStmt->SetPUIdx(newFunc->GetPuidx()); break; } @@ -2083,6 +2110,7 @@ StmtNode *CGLowerer::LowerCall( if (needCheckStore) { MIRFunction *fn = mirModule.GetMIRBuilder()->GetOrCreateFunction("MCC_Reflect_Check_Arraystore", TyIdx(PTY_void)); + fn->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); MapleVector args(mirModule.GetMIRBuilder()->GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -2109,7 +2137,7 @@ StmtNode *CGLowerer::LowerCall( } MIRType *retType = nullptr; - if (callNode.op == OP_icall) { + if (callNode.op == OP_icall || callNode.op == OP_icallproto) { if (retTy == nullptr) { return &callNode; } else { @@ -2155,7 +2183,7 @@ StmtNode *CGLowerer::LowerCall( addrofNode->SetStIdx(dsgnSt->GetStIdx()); addrofNode->SetFieldID(0); - if (callNode.op == OP_icall) { + if (callNode.op == OP_icall || callNode.op == OP_icallproto) { auto ond = callNode.GetNopnd().begin(); newNopnd.emplace_back(*ond); newNopnd.emplace_back(addrofNode); @@ -2177,7 +2205,27 @@ StmtNode *CGLowerer::LowerCall( } void CGLowerer::LowerEntry(MIRFunction &func) { + // determine if needed to insert fake parameter to return struct for current function if (func.IsReturnStruct()) { + MIRType *retType = func.GetReturnType(); +#if TARGAARCH64 + PrimType pty = IsStructElementSame(retType); + if (pty == PTY_f32 || pty == PTY_f64 || IsPrimitiveVector(pty)) { + func.SetStructReturnedInRegs(); + return; + } +#endif + if (retType->GetPrimType() != PTY_agg) { + return; + } + if (retType->GetSize() > k16ByteSize) { + func.SetFirstArgReturn(); + func.GetMIRFuncType()->SetFirstArgReturn(); + } else { + func.SetStructReturnedInRegs(); + } + } + if (func.IsFirstArgReturn() && func.GetReturnType()->GetPrimType() != PTY_void) { MIRSymbol *retSt = func.GetSymTab()->CreateSymbol(kScopeLocal); retSt->SetStorageClass(kScFormal); retSt->SetSKind(kStVar); @@ -2194,12 +2242,14 @@ void CGLowerer::LowerEntry(MIRFunction &func) { auto formal = func.GetFormal(i); formals.emplace_back(formal); } + func.SetFirstArgReturn(); beCommon.AddElementToFuncReturnType(func, func.GetReturnTyIdx()); func.UpdateFuncTypeAndFormalsAndReturnType(formals, TyIdx(PTY_void), true); auto *funcType = func.GetMIRFuncType(); ASSERT(funcType != nullptr, "null ptr check"); + funcType->SetFirstArgReturn(); beCommon.AddTypeSizeAndAlign(funcType->GetTypeIndex(), GetPrimTypeSize(funcType->GetPrimType())); } } @@ -2377,6 +2427,7 @@ MIRFunction *CGLowerer::RegisterFunctionVoidStarToVoid(BuiltinFunctionID id, con func->AllocSymTab(); MIRSymbol *funcSym = func->GetFuncSymbol(); funcSym->SetStorageClass(kScExtern); + funcSym->SetAppearsInCode(true); MIRType *argTy = GlobalTables::GetTypeTable().GetPtr(); MIRSymbol *argSt = func->GetSymTab()->CreateSymbol(kScopeLocal); argSt->SetNameStrIdx(mirBuilder->GetOrCreateStringIndex(paramName)); @@ -2418,6 +2469,7 @@ void CGLowerer::RegisterBuiltIns() { func->AllocSymTab(); MIRSymbol *funcSym = func->GetFuncSymbol(); funcSym->SetStorageClass(kScExtern); + funcSym->SetAppearsInCode(true); /* return type */ MIRType *retTy = desc.GetReturnType(); CHECK_FATAL(retTy != nullptr, "retTy should not be nullptr"); @@ -2573,6 +2625,7 @@ void CGLowerer::ProcessArrayExpr(BaseNode &expr, BlockNode &blkNode) { arrayNode.GetNopndAt(1), lenRegreadNode); CondGotoNode *brFalseNode = mirBuilder->CreateStmtCondGoto(cond, OP_brfalse, labIdx); MIRFunction *fn = mirBuilder->GetOrCreateFunction("MCC_Array_Boundary_Check", TyIdx(PTY_void)); + fn->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); MapleVector args(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -3104,6 +3157,7 @@ BaseNode *CGLowerer::LowerIntrinJavaArrayLength(const BaseNode &parent, Intrinsi MIRFunction *newFunc = mirBuilder->GetOrCreateFunction("MCC_ThrowNullArrayNullPointerException", GlobalTables::GetTypeTable().GetVoid()->GetTypeIndex()); + newFunc->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*newFunc->GetMIRFuncType()); newFunc->AllocSymTab(); MapleVector args(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -3475,6 +3529,7 @@ StmtNode *CGLowerer::LowerIntrinsicRCCall(const IntrinsiccallNode &intrincall) { if (intrinFuncIDs.find(intrinDesc) == intrinFuncIDs.end()) { /* add funcid into map */ MIRFunction *fn = mirBuilder->GetOrCreateFunction(intrinDesc->name, TyIdx(PTY_void)); + fn->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); intrinFuncIDs[intrinDesc] = fn->GetPuidx(); @@ -3503,6 +3558,7 @@ void CGLowerer::LowerArrayStore(const IntrinsiccallNode &intrincall, BlockNode & if (needCheckStore) { MIRFunction *fn = mirBuilder->GetOrCreateFunction("MCC_Reflect_Check_Arraystore", TyIdx(PTY_void)); + fn->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); MapleVector args(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -3592,6 +3648,7 @@ StmtNode *CGLowerer::LowerIntrinsiccall(IntrinsiccallNode &intrincall, BlockNode beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); st->SetFunction(fn); + st->SetAppearsInCode(true); return LowerDefaultIntrinsicCall(intrincall, *st, *fn); } @@ -3662,6 +3719,7 @@ PUIdx CGLowerer::GetBuiltinToUse(BuiltinFunctionID id) const { void CGLowerer::LowerGCMalloc(const BaseNode &node, const GCMallocNode &gcmalloc, BlockNode &blkNode, bool perm) { MIRFunction *func = mirBuilder->GetOrCreateFunction((perm ? "MCC_NewPermanentObject" : "MCC_NewObj_fixed_class"), (TyIdx)(LOWERED_PTR_TYPE)); + func->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*func->GetMIRFuncType()); func->AllocSymTab(); /* Get the classinfo */ @@ -3680,6 +3738,7 @@ void CGLowerer::LowerGCMalloc(const BaseNode &node, const GCMallocNode &gcmalloc if (classSym->GetAttr(ATTR_abstract) || classSym->GetAttr(ATTR_interface)) { MIRFunction *funcSecond = mirBuilder->GetOrCreateFunction("MCC_Reflect_ThrowInstantiationError", (TyIdx)(LOWERED_PTR_TYPE)); + funcSecond->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*funcSecond->GetMIRFuncType()); funcSecond->AllocSymTab(); BaseNode *arg = mirBuilder->CreateExprAddrof(0, *classSym); @@ -3798,6 +3857,7 @@ void CGLowerer::LowerJarrayMalloc(const StmtNode &stmt, const JarrayMallocNode & args.emplace_back(mirBuilder->CreateIntConst(0, PTY_u32)); } MIRFunction *func = mirBuilder->GetOrCreateFunction(funcName, (TyIdx)(LOWERED_PTR_TYPE)); + func->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*func->GetMIRFuncType()); func->AllocSymTab(); CallNode *callAssign = nullptr; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index ab075eb06f..7962d54991 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -38,7 +38,7 @@ void AArch64MoveRegArgs::CollectRegisterArgs(std::map &argsL uint32 start = 0; if (numFormal) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsReturnStruct()) { + if (func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16ByteSize) { start = 1; @@ -436,7 +436,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsReturnStruct()) { + if (func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp index 8df391c8c6..5a355837d1 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp @@ -300,7 +300,7 @@ int32 AArch64CallConvImpl::LocateNextParm(MIRType &mirType, CCLocInfo &pLoc, boo if (isFirst) { MIRFunction *func = tFunc != nullptr ? tFunc : const_cast(beCommon.GetMIRModule().CurFunction()); - if (func->IsReturnStruct()) { + if (func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); size_t size = beCommon.GetTypeSize(tyIdx); if (size == 0) { 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 0b2fd7ea04..555e7548c0 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -1411,15 +1411,44 @@ void AArch64CGFunc::SelectAsm(AsmNode &node) { } void AArch64CGFunc::SelectRegassign(RegassignNode &stmt, Operand &opnd0) { + if (GetCG()->IsLmbc()) { + PrimType lhsSize = stmt.GetPrimType(); + PrimType rhsSize = stmt.Opnd(0)->GetPrimType(); + if (lhsSize != rhsSize && stmt.Opnd(0)->GetOpCode() == OP_ireadoff) { + Insn *prev = GetCurBB()->GetLastInsn(); + if (prev->GetMachineOpcode() == MOP_wldrsb || prev->GetMachineOpcode() == MOP_wldrsh) { + opnd0.SetSize(GetPrimTypeBitSize(stmt.GetPrimType())); + prev->SetMOP(prev->GetMachineOpcode() == MOP_wldrsb ? MOP_xldrsb : MOP_xldrsh); + } else if (prev->GetMachineOpcode() == MOP_wldr && stmt.GetPrimType() == PTY_i64) { + opnd0.SetSize(GetPrimTypeBitSize(stmt.GetPrimType())); + prev->SetMOP(MOP_xldrsw); + } + } + } RegOperand *regOpnd = nullptr; PregIdx pregIdx = stmt.GetRegIdx(); if (IsSpecialPseudoRegister(pregIdx)) { - regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, stmt.GetPrimType()); + if (GetCG()->IsLmbc() && stmt.GetPrimType() == PTY_agg) { + if (static_cast(opnd0).IsOfIntClass()) { + regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, PTY_i64); + } else if (opnd0.GetSize() <= k4ByteSize) { + regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, PTY_f32); + } else { + regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, PTY_f64); + } + } else { + regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, stmt.GetPrimType()); + } } else { regOpnd = &GetOrCreateVirtualRegisterOperand(GetVirtualRegNOFromPseudoRegIdx(pregIdx)); } /* look at rhs */ PrimType rhsType = stmt.Opnd(0)->GetPrimType(); + if (GetCG()->IsLmbc() && rhsType == PTY_agg) { + /* This occurs when a call returns a small struct */ + /* The subtree should already taken care of the agg type that is in excess of 8 bytes */ + rhsType = PTY_i64; + } PrimType dtype = rhsType; if (GetPrimTypeBitSize(dtype) < k32BitSize) { ASSERT(IsPrimitiveInteger(dtype), ""); @@ -1441,6 +1470,12 @@ void AArch64CGFunc::SelectRegassign(RegassignNode &stmt, Operand &opnd0) { MIRPreg *preg = GetFunction().GetPregTab()->PregFromPregIdx(pregIdx); uint32 srcBitLength = GetPrimTypeSize(preg->GetPrimType()) * kBitsPerByte; GetCurBB()->AppendInsn(GetCG()->BuildInstruction(PickStInsn(srcBitLength, stype), *regOpnd, *dest)); + } else if (regOpnd->GetRegisterNumber() == R0 || regOpnd->GetRegisterNumber() == R1) { + Insn &pseudo = GetCG()->BuildInstruction(MOP_pseudo_ret_int, *regOpnd); + GetCurBB()->AppendInsn(pseudo); + } else if (regOpnd->GetRegisterNumber() >= V0 && regOpnd->GetRegisterNumber() <= V3) { + Insn &pseudo = GetCG()->BuildInstruction(MOP_pseudo_ret_float, *regOpnd); + GetCurBB()->AppendInsn(pseudo); } } @@ -1922,15 +1957,11 @@ void AArch64CGFunc::SelectIassignoff(IassignoffNode &stmt) { SelectCopy(memOpnd, destType, srcOpnd, destType); } -void AArch64CGFunc::SelectIassignfpoff(IassignFPoffNode &stmt, Operand &opnd) { - int32 offset = stmt.GetOffset(); - PrimType primType = stmt.GetPrimType(); - uint32 bitlen = GetPrimTypeSize(primType) * kBitsPerByte; - - Operand &srcOpnd = LoadIntoRegister(opnd, primType); +MemOperand *AArch64CGFunc::GenLmbcFpMemOperand(int32 offset, uint32 byteSize, AArch64reg baseRegno) { MemOperand *memOpnd; - RegOperand *rfp = &GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); - if (offset < 0) { + RegOperand *rfp = &GetOrCreatePhysicalRegisterOperand(baseRegno, k64BitSize, kRegTyInt); + uint32 bitlen = byteSize * kBitsPerByte; + if (offset < 0 && offset < -256) { RegOperand *baseOpnd = &CreateRegisterOperandOfType(PTY_a64); ImmOperand &immOpnd = CreateImmOperand(offset, k32BitSize, true); Insn &addInsn = GetCG()->BuildInstruction(MOP_xaddrri12, *baseOpnd, *rfp, immOpnd); @@ -1942,11 +1973,45 @@ void AArch64CGFunc::SelectIassignfpoff(IassignFPoffNode &stmt, Operand &opnd) { memOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, bitlen, rfp, nullptr, offsetOpnd, nullptr); } memOpnd->SetStackMem(true); - MOperator mOp = PickStInsn(bitlen, primType); - Insn &store = GetCG()->BuildInstruction(mOp, srcOpnd, *memOpnd); - GetCurBB()->AppendInsn(store); + return memOpnd; +} + +void AArch64CGFunc::SelectIassignfpoff(IassignFPoffNode &stmt, Operand &opnd) { + int32 offset = stmt.GetOffset(); + PrimType primType = stmt.GetPrimType(); + MIRType *rType = GetLmbcCallReturnType(); + bool isPureFpStruct = false; + uint32 numRegs = 0; + if (rType && rType->GetPrimType() == PTY_agg && opnd.IsRegister() && static_cast(opnd).IsPhysicalRegister()) { + CHECK_FATAL(rType->GetSize() <= 16, "SelectIassignfpoff invalid agg size"); + uint32 fpSize; + numRegs = FloatParamRegRequired(static_cast(rType), fpSize); + if (numRegs) { + primType = (fpSize == k4ByteSize) ? PTY_f32 : PTY_f64; + isPureFpStruct = true; + } + } + uint32 byteSize = GetPrimTypeSize(primType); + uint32 bitlen = byteSize * kBitsPerByte; + if (isPureFpStruct) { + for (int i = 0 ; i < numRegs; ++i) { + MemOperand *memOpnd = GenLmbcFpMemOperand(offset + (i * byteSize), byteSize); + RegOperand &srcOpnd = GetOrCreatePhysicalRegisterOperand(AArch64reg(V0 + i), bitlen, kRegTyFloat); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, srcOpnd, *memOpnd); + GetCurBB()->AppendInsn(store); + } + } else { + Operand &srcOpnd = LoadIntoRegister(opnd, primType); + MemOperand *memOpnd = GenLmbcFpMemOperand(offset, byteSize); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, srcOpnd, *memOpnd); + GetCurBB()->AppendInsn(store); + } } +/* Load and assign to a new register. To be moved to the correct call register OR stack + location in LmbcSelectParmList */ void AArch64CGFunc::SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd) { if (GetLmbcArgInfo() == nullptr) { LmbcArgInfo *p = memPool->New(*GetFuncScopeAllocator()); @@ -1973,7 +2038,7 @@ void AArch64CGFunc::SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd } /* Search for CALL/ICALL/ICALLPROTO node, must be called from a blkassignoff node */ -MIRType *AArch64CGFunc::GetAggTyFromCallSite(StmtNode *stmt) { +MIRType *AArch64CGFunc::LmbcGetAggTyFromCallSite(StmtNode *stmt, std::vector **parmList) { for ( ; stmt != nullptr; stmt = stmt->GetNext()) { if (stmt->GetOpCode() == OP_call || stmt->GetOpCode() == OP_icallproto) { break; @@ -1986,25 +2051,20 @@ MIRType *AArch64CGFunc::GetAggTyFromCallSite(StmtNode *stmt) { if (stmt->GetOpCode() == OP_call) { CallNode *callNode = static_cast(stmt); MIRFunction *fn = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callNode->GetPUIdx()); - if (fn->IsReturnStruct()) { - ++nargs; - } if (fn->GetFormalCount() > 0) { - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fn->GetNthParamTyIdx(nargs)); + ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fn->GetFormalDefVec()[nargs].formalTyIdx); } + *parmList = &fn->GetParamTypes(); // would return null if the actual parameter is bogus } else if (stmt->GetOpCode() == OP_icallproto) { IcallNode *icallproto = static_cast(stmt); MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallproto->GetRetTyIdx()); MIRFuncType *fType = static_cast(type); - MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fType->GetRetTyIdx()); - if (retType->GetKind() == kTypeStruct) { - ++nargs; - } ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fType->GetNthParamType(nargs)); + *parmList = &fType->GetParamTypeList(); } else { CHECK_FATAL(stmt->GetOpCode() == OP_icallproto, - "GetAggTyFromCallSite:: unexpected call operator"); + "LmbcGetAggTyFromCallSite:: unexpected call operator"); } return ty; } @@ -2081,11 +2141,11 @@ bool AArch64CGFunc::LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *s } /* return true if blkassignoff for return, false otherwise */ -bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src) { +bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList) { AArch64reg regno = static_cast(static_cast(src)->GetRegisterNumber()); if (IsBlkassignForPush(bNode)) { PrimType pTy = PTY_i64; - MIRStructType *ty = static_cast(GetAggTyFromCallSite(&bNode)); + MIRStructType *ty = static_cast(LmbcGetAggTyFromCallSite(&bNode, parmList)); uint32 size = 0; uint32 fpregs = ty ? FloatParamRegRequired(ty, size) : 0; /* fp size determined */ if (fpregs > 0) { @@ -2096,7 +2156,7 @@ bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src) { MemOperand &mem = CreateMemOpnd(regno, s, size * kBitsPerByte); RegOperand *res = &CreateVirtualRegisterOperand(NewVReg(kRegTyFloat, size)); SelectCopy(*res, pTy, mem, pTy); - SetLmbcArgInfo(res, pTy, bNode.offset + s, static_cast(fpregs)); + SetLmbcArgInfo(res, pTy, 0, fpregs); IncLmbcArgsInRegs(kRegTyFloat); } IncLmbcTotalArgs(); @@ -2137,6 +2197,41 @@ bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src) { return false; } +/* This function is incomplete and may be removed when Lmbc IR is changed + to have the lowerer figures out the address of the large agg to reside */ +uint32 AArch64CGFunc::LmbcFindTotalStkUsed(std::vector *paramList) { + AArch64CallConvImpl parmlocator(GetBecommon()); + CCLocInfo pLoc; + for (TyIdx tyIdx : *paramList) { + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); + parmlocator.LocateNextParm(*ty, pLoc); + } + return 0; +} + +/* All arguments passed as registers */ +uint32 AArch64CGFunc::LmbcTotalRegsUsed() { + if (GetLmbcArgInfo() == nullptr) { + return 0; /* no arg */ + } + MapleVector ®s = GetLmbcCallArgNumOfRegs(); + MapleVector &types = GetLmbcCallArgTypes(); + uint32 iCnt = 0; + uint32 fCnt = 0; + for (uint32 i = 0; i < regs.size(); i++) { + if (IsPrimitiveInteger(types[i])) { + if ((iCnt + regs[i]) <= k8ByteSize) { + iCnt += regs[i]; + }; + } else { + if ((fCnt + regs[i]) <= k8ByteSize) { + fCnt += regs[i]; + }; + } + } + return iCnt + fCnt; +} + /* If blkassignoff for argument, this function loads the agg arguments into virtual registers, disregard if there is sufficient physicall call registers. Argument > 16-bytes are copied to preset space and ptr @@ -2145,29 +2240,40 @@ bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src) { void AArch64CGFunc::SelectBlkassignoff(BlkassignoffNode &bNode, Operand *src) { CHECK_FATAL(src->GetKind() == Operand::kOpdRegister, "blkassign src type not in register"); + std::vector *parmList; if (GetLmbcArgInfo() == nullptr) { LmbcArgInfo *p = memPool->New(*GetFuncScopeAllocator()); SetLmbcArgInfo(p); } if (LmbcSmallAggForRet(bNode, src)) { return; - } else if (LmbcSmallAggForCall(bNode, src)) { + } else if (LmbcSmallAggForCall(bNode, src, &parmList)) { return; } - /* memcpy for agg assign OR large agg for arg/ret */ Operand *dest = HandleExpr(bNode, *bNode.Opnd(0)); RegOperand *regResult = &CreateVirtualRegisterOperand(NewVReg(kRegTyInt, k8ByteSize)); + /* memcpy for agg assign OR large agg for arg/ret */ + int32 offset = bNode.offset; + if (IsBlkassignForPush(bNode)) { + /* large agg for call, addr to be pushed in SelectCall */ + offset = GetLmbcTotalStkUsed(); + if (offset < 0) { + /* length of ALL stack based args for this call, this location is where the + next large agg resides, its addr will then be passed */ + offset = LmbcFindTotalStkUsed(parmList) + LmbcTotalRegsUsed(); + } + SetLmbcTotalStkUsed(offset + bNode.blockSize); /* next use */ + SetLmbcArgInfo(regResult, PTY_i64, 0, 1); /* 1 reg for ptr */ + IncLmbcArgsInRegs(kRegTyInt); + IncLmbcTotalArgs(); + /* copy large agg arg to offset below */ + } std::vector opndVec; opndVec.push_back(regResult); /* result */ - opndVec.push_back(PrepareMemcpyParamOpnd(bNode.offset, *dest));/* param 0 */ + opndVec.push_back(PrepareMemcpyParamOpnd(offset, *dest)); /* param 0 */ opndVec.push_back(src); /* param 1 */ opndVec.push_back(PrepareMemcpyParamOpnd(bNode.blockSize));/* param 2 */ SelectLibCall("memcpy", opndVec, PTY_a64, PTY_a64); - if (IsBlkassignForPush(bNode)) { - SetLmbcArgInfo(static_cast(src), PTY_i64, (int32)bNode.offset, 1); - IncLmbcArgsInRegs(kRegTyInt); - IncLmbcTotalArgs(); - } } void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { @@ -2554,6 +2660,159 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { } } +void AArch64CGFunc::SelectReturnSendOfStructInRegs(BaseNode *x) { + uint32 offset = 0; + if (x->GetOpCode() == OP_dread) { + DreadNode *dread = static_cast(x); + MIRSymbol *sym = GetFunction().GetLocalOrGlobalSymbol(dread->GetStIdx()); + MIRType *mirType = sym->GetType(); + if (dread->GetFieldID() != 0) { + MIRStructType *structType = static_cast(mirType); + mirType = structType->GetFieldType(dread->GetFieldID()); + offset = static_cast(GetBecommon().GetFieldOffset(*structType, dread->GetFieldID()).first); + } + uint32 typeSize = GetBecommon().GetTypeSize(mirType->GetTypeIndex()); + /* generate move to regs for agg return */ + AArch64CallConvImpl parmlocator(GetBecommon()); + CCLocInfo pLoc; + parmlocator.LocateNextParm(*mirType, pLoc, true, GetBecommon().GetMIRModule().CurFunction()); + /* aggregates are 8 byte aligned. */ + Operand *rhsmemopnd = nullptr; + RegOperand *result[kFourRegister]; /* up to 2 int or 4 fp */ + uint32 loadSize; + uint32 numRegs; + RegType regType; + PrimType retPty; + bool fpParm = false; + if (pLoc.numFpPureRegs) { + loadSize = pLoc.fpSize; + numRegs = pLoc.numFpPureRegs; + fpParm = true; + regType = kRegTyFloat; + retPty = (pLoc.fpSize == k4ByteSize) ? PTY_f32 : PTY_f64; + } else { + if (CGOptions::IsBigEndian()) { + loadSize = k8ByteSize; + numRegs = (typeSize <= k8ByteSize) ? kOneRegister : kTwoRegister; + regType = kRegTyInt; + retPty = PTY_u64; + } else { + loadSize = (typeSize <= k4ByteSize) ? k4ByteSize : k8ByteSize; + numRegs = (typeSize <= k8ByteSize) ? kOneRegister : kTwoRegister; + regType = kRegTyInt; + retPty = PTY_u32; + } + } + bool parmCopy = IsParamStructCopy(*sym); + for (uint32 i = 0; i < numRegs; i++) { + if (parmCopy) { + rhsmemopnd = &LoadStructCopyBase(*sym, + (offset + static_cast(i * (fpParm ? loadSize : k8ByteSize))), + static_cast(loadSize * kBitsPerByte)); + } else { + rhsmemopnd = &GetOrCreateMemOpnd(*sym, + (offset + static_cast(i * (fpParm ? loadSize : k8ByteSize))), + (loadSize * kBitsPerByte)); + } + result[i] = &CreateVirtualRegisterOperand(NewVReg(regType, loadSize)); + MOperator mop1 = PickLdInsn(loadSize * kBitsPerByte, retPty); + Insn &ld = GetCG()->BuildInstruction(mop1, *(result[i]), *rhsmemopnd); + GetCurBB()->AppendInsn(ld); + } + AArch64reg regs[kFourRegister]; + regs[0] = static_cast(pLoc.reg0); + regs[1] = static_cast(pLoc.reg1); + regs[2] = static_cast(pLoc.reg2); + regs[3] = static_cast(pLoc.reg3); + RegOperand *dest; + for (uint32 i = 0; i < numRegs; i++) { + AArch64reg preg; + MOperator mop2; + if (fpParm) { + preg = regs[i]; + mop2 = (loadSize == k4ByteSize) ? MOP_xvmovs : MOP_xvmovd; + } else { + preg = (i == 0 ? R0 : R1); + mop2 = (loadSize == k4ByteSize) ? MOP_wmovrr : MOP_xmovrr; + } + dest = &GetOrCreatePhysicalRegisterOperand(preg, (loadSize * kBitsPerByte), regType); + Insn &mov = GetCG()->BuildInstruction(mop2, *dest, *(result[i])); + GetCurBB()->AppendInsn(mov); + } + /* Create artificial dependency to extend the live range */ + for (uint32 i = 0; i < numRegs; i++) { + AArch64reg preg; + MOperator mop3; + if (fpParm) { + preg = regs[i]; + mop3 = MOP_pseudo_ret_float; + } else { + preg = (i == 0 ? R0 : R1); + mop3 = MOP_pseudo_ret_int; + } + dest = &GetOrCreatePhysicalRegisterOperand(preg, loadSize * kBitsPerByte, regType); + Insn &pseudo = GetCG()->BuildInstruction(mop3, *dest); + GetCurBB()->AppendInsn(pseudo); + } + return; + } else if (x->GetOpCode() == OP_iread) { + IreadNode *iread = static_cast(x); + RegOperand *rhsAddrOpnd = static_cast(HandleExpr(*iread, *iread->Opnd(0))); + rhsAddrOpnd = &LoadIntoRegister(*rhsAddrOpnd, iread->Opnd(0)->GetPrimType()); + MIRPtrType *ptrType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread->GetTyIdx())); + MIRType *mirType = static_cast(ptrType->GetPointedType()); + bool isRefField = false; + if (iread->GetFieldID() != 0) { + MIRStructType *structType = static_cast(mirType); + mirType = structType->GetFieldType(iread->GetFieldID()); + offset = static_cast(GetBecommon().GetFieldOffset(*structType, iread->GetFieldID()).first); + isRefField = GetBecommon().IsRefField(*structType, iread->GetFieldID()); + } + uint32 typeSize = GetBecommon().GetTypeSize(mirType->GetTypeIndex()); + /* generate move to regs. */ + RegOperand *result[kTwoRegister]; /* maximum 16 bytes, 2 registers */ + uint32 loadSize; + if (CGOptions::IsBigEndian()) { + loadSize = k8ByteSize; + } else { + loadSize = (typeSize <= k4ByteSize) ? k4ByteSize : k8ByteSize; + } + uint32 numRegs = (typeSize <= k8ByteSize) ? kOneRegister : kTwoRegister; + for (uint32 i = 0; i < numRegs; i++) { + OfstOperand *rhsOffOpnd = &GetOrCreateOfstOpnd(offset + i * loadSize, loadSize * kBitsPerByte); + Operand &rhsmemopnd = GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, loadSize * kBitsPerByte, + rhsAddrOpnd, nullptr, rhsOffOpnd, nullptr); + result[i] = &CreateVirtualRegisterOperand(NewVReg(kRegTyInt, loadSize)); + MOperator mop1 = PickLdInsn(loadSize * kBitsPerByte, PTY_u32); + Insn &ld = GetCG()->BuildInstruction(mop1, *(result[i]), rhsmemopnd); + ld.MarkAsAccessRefField(isRefField); + GetCurBB()->AppendInsn(ld); + } + RegOperand *dest; + for (uint32 i = 0; i < numRegs; i++) { + AArch64reg preg = (i == 0 ? R0 : R1); + dest = &GetOrCreatePhysicalRegisterOperand(preg, loadSize * kBitsPerByte, kRegTyInt); + Insn &mov = GetCG()->BuildInstruction(MOP_xmovrr, *dest, *(result[i])); + GetCurBB()->AppendInsn(mov); + } + /* Create artificial dependency to extend the live range */ + for (uint32 i = 0; i < numRegs; i++) { + AArch64reg preg = (i == 0 ? R0 : R1); + dest = &GetOrCreatePhysicalRegisterOperand(preg, loadSize * kBitsPerByte, kRegTyInt); + Insn &pseudo = cg->BuildInstruction(MOP_pseudo_ret_int, *dest); + GetCurBB()->AppendInsn(pseudo); + } + return; + } else { // dummy return of 0 inserted by front-end at absence of return + ASSERT(x->GetOpCode() == OP_constval, "SelectReturnSendOfStructInRegs: unexpected return operand"); + uint32 typeSize = GetPrimTypeSize(x->GetPrimType()); + RegOperand &dest = GetOrCreatePhysicalRegisterOperand(R0, typeSize * kBitsPerByte, kRegTyInt); + ImmOperand &src = CreateImmOperand(0, k16BitSize, false); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_xmovri32, dest, src)); + return; + } +} + Operand *AArch64CGFunc::SelectDread(const BaseNode &parent, DreadNode &expr) { MIRSymbol *symbol = GetFunction().GetLocalOrGlobalSymbol(expr.GetStIdx()); if (symbol->IsEhIndex()) { @@ -2917,31 +3176,50 @@ Operand *AArch64CGFunc::SelectIreadoff(const BaseNode &parent, IreadoffNode &ire return result; } -RegOperand *AArch64CGFunc::GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType) { - MemOperand *memOpnd; - RegOperand *rfp = &GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); - uint32 bitlen = byteSize * kBitsPerByte; - if (offset < 0) { - RegOperand *baseOpnd = &CreateRegisterOperandOfType(PTY_a64); - ImmOperand &immOpnd = CreateImmOperand(offset, k32BitSize, true); - Insn &addInsn = GetCG()->BuildInstruction(MOP_xaddrri12, *baseOpnd, *rfp, immOpnd); - GetCurBB()->AppendInsn(addInsn); - OfstOperand *offsetOpnd = &CreateOfstOpnd(0, k32BitSize); - memOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, bitlen, baseOpnd, - nullptr, offsetOpnd, nullptr); - } else { - OfstOperand *offsetOpnd = &CreateOfstOpnd(offset, k32BitSize); - memOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, bitlen, rfp, - nullptr, offsetOpnd, nullptr); - } - memOpnd->SetStackMem(true); +RegOperand *AArch64CGFunc::GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType, + AArch64reg baseRegno) { + MemOperand *memOpnd = GenLmbcFpMemOperand(offset, byteSize, baseRegno); RegOperand *result = &GetOrCreateVirtualRegisterOperand(NewVReg(regType, byteSize)); - MOperator mOp = PickLdInsn(bitlen, primType); + MOperator mOp = PickLdInsn(byteSize * kBitsPerByte, primType); Insn &load = GetCG()->BuildInstruction(mOp, *result, *memOpnd); GetCurBB()->AppendInsn(load); return result; } +RegOperand *AArch64CGFunc::LmbcStructReturnLoad(int32 offset) { + RegOperand *result = nullptr; + MIRFunction &func = GetFunction(); + CHECK_FATAL(func.IsReturnStruct(), "LmbcStructReturnLoad: not struct return"); + MIRType *ty = func.GetReturnType(); + uint32 sz = GetBecommon().GetTypeSize(ty->GetTypeIndex()); + uint32 fpSize; + uint32 numFpRegs = FloatParamRegRequired(static_cast(ty), fpSize); + if (numFpRegs > 0) { + PrimType pType = (fpSize <= k4ByteSize) ? PTY_f32 : PTY_f64; + for (int32 i = (numFpRegs - kOneRegister); i > 0; --i) { + result = GenLmbcParamLoad(offset + (i * fpSize), fpSize, kRegTyFloat, pType); + AArch64reg regNo = static_cast(V0 + i); + RegOperand *reg = &GetOrCreatePhysicalRegisterOperand(regNo, fpSize * kBitsPerByte, kRegTyFloat); + SelectCopy(*reg, pType, *result, pType); + Insn &pseudo = GetCG()->BuildInstruction(MOP_pseudo_ret_float, *reg); + GetCurBB()->AppendInsn(pseudo); + } + result = GenLmbcParamLoad(offset, fpSize, kRegTyFloat, pType); + } else if (sz <= k4ByteSize) { + result = GenLmbcParamLoad(offset, k4ByteSize, kRegTyInt, PTY_u32); + } else if (sz <= k8ByteSize) { + result = GenLmbcParamLoad(offset, k8ByteSize, kRegTyInt, PTY_i64); + } else if (sz <= k16ByteSize) { + result = GenLmbcParamLoad(offset + k8ByteSize, k8ByteSize, kRegTyInt, PTY_i64); + RegOperand *r1 = &GetOrCreatePhysicalRegisterOperand(R1, k8ByteSize * kBitsPerByte, kRegTyInt); + SelectCopy(*r1, PTY_i64, *result, PTY_i64); + Insn &pseudo = GetCG()->BuildInstruction(MOP_pseudo_ret_int, *r1); + GetCurBB()->AppendInsn(pseudo); + result = GenLmbcParamLoad(offset, k8ByteSize, kRegTyInt, PTY_i64); + } + return result; +} + Operand *AArch64CGFunc::SelectIreadfpoff(const BaseNode &parent, IreadFPoffNode &ireadoff) { int32 offset = ireadoff.GetOffset(); PrimType primType = ireadoff.GetPrimType(); @@ -2952,19 +3230,32 @@ Operand *AArch64CGFunc::SelectIreadfpoff(const BaseNode &parent, IreadFPoffNode if (offset >= 0) { LmbcFormalParamInfo *info = GetLmbcFormalParamInfo(offset); if (info->GetPrimType() == PTY_agg) { - result = GenLmbcParamLoad(offset, bytelen, regty, primType); + if (info->IsOnStack()) { + result = GenLmbcParamLoad(info->GetOnStackOffset(), GetPrimTypeSize(PTY_a64), kRegTyInt, PTY_a64); + regno_t baseRegno = result->GetRegisterNumber(); + result = GenLmbcParamLoad(offset - info->GetOffset(), bytelen, regty, primType, (AArch64reg)baseRegno); + } else if (primType == PTY_agg) { + CHECK_FATAL(parent.GetOpCode() == OP_regassign, "SelectIreadfpoff of agg"); + result = LmbcStructReturnLoad(offset); + } else { + result = GenLmbcParamLoad(offset, bytelen, regty, primType); + } } else { CHECK_FATAL(primType == info->GetPrimType(), "Incorrect primtype"); CHECK_FATAL(offset == info->GetOffset(), "Incorrect offset"); - if (info->GetRegNO() == 0) { - /* TODO : follow lmbc sp offset for now */ + if (info->GetRegNO() == 0 || info->HasRegassign() == false) { result = GenLmbcParamLoad(offset, bytelen, regty, primType); } else { result = &GetOrCreatePhysicalRegisterOperand((AArch64reg)(info->GetRegNO()), bitlen, regty); } } } else { - result = GenLmbcParamLoad(offset, bytelen, regty, primType); + if (primType == PTY_agg) { + CHECK_FATAL(parent.GetOpCode() == OP_regassign, "SelectIreadfpoff of agg"); + result = LmbcStructReturnLoad(offset); + } else { + result = GenLmbcParamLoad(offset, bytelen, regty, primType); + } } return result; } @@ -5761,6 +6052,9 @@ Operand *AArch64CGFunc::SelectAlloca(UnaryNode &node, Operand &opnd0) { if (!CGOptions::IsArm64ilp32()) { ASSERT((node.GetPrimType() == PTY_a64), "wrong type"); } + if (GetCG()->IsLmbc()) { + SetHasVLAOrAlloca(true); + } PrimType stype = node.Opnd(0)->GetPrimType(); Operand *resOpnd = &opnd0; if (GetPrimTypeBitSize(stype) < GetPrimTypeBitSize(PTY_u64)) { @@ -5776,10 +6070,13 @@ Operand *AArch64CGFunc::SelectAlloca(UnaryNode &node, Operand &opnd0) { SelectShift(aliOp, aliOp, shifOpnd, kShiftLeft, PTY_u64); Operand &spOpnd = GetOrCreatePhysicalRegisterOperand(RSP, k64BitSize, kRegTyInt); SelectSub(spOpnd, spOpnd, aliOp, PTY_u64); - int64 argsToStkpassSize = GetMemlayout()->SizeOfArgsToStackPass(); - if (argsToStkpassSize > 0) { + int64 allocaOffset = GetMemlayout()->SizeOfArgsToStackPass(); + if (GetCG()->IsLmbc()) { + allocaOffset -= kDivide2 * k8ByteSize; + } + if (allocaOffset > 0) { RegOperand &resallo = CreateRegisterOperandOfType(PTY_u64); - SelectAdd(resallo, spOpnd, CreateImmOperand(argsToStkpassSize, k64BitSize, true), PTY_u64); + SelectAdd(resallo, spOpnd, CreateImmOperand(allocaOffset, k64BitSize, true), PTY_u64); return &resallo; } else { return &SelectCopy(spOpnd, PTY_u64, PTY_u64); @@ -6221,6 +6518,15 @@ void AArch64CGFunc::AssignLmbcFormalParams() { param->SetRegNO(0); } else { param->SetRegNO(intReg); + if (param->HasRegassign() == false) { + uint32 bytelen = GetPrimTypeSize(primType); + uint32 bitlen = bytelen * kBitsPerByte; + MemOperand *mOpnd = GenLmbcFpMemOperand(offset, bytelen); + RegOperand &src = GetOrCreatePhysicalRegisterOperand(AArch64reg(intReg), bitlen, kRegTyInt); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, src, *mOpnd); + GetCurBB()->AppendInsn(store); + } intReg++; } } else if (IsPrimitiveFloat(primType)) { @@ -6228,6 +6534,15 @@ void AArch64CGFunc::AssignLmbcFormalParams() { param->SetRegNO(0); } else { param->SetRegNO(fpReg); + if (param->HasRegassign() == false) { + uint32 bytelen = GetPrimTypeSize(primType); + uint32 bitlen = bytelen * kBitsPerByte; + MemOperand *mOpnd = GenLmbcFpMemOperand(offset, bytelen); + RegOperand &src = GetOrCreatePhysicalRegisterOperand(AArch64reg(fpReg), bitlen, kRegTyFloat); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, src, *mOpnd); + GetCurBB()->AppendInsn(store); + } fpReg++; } } else if (primType == PTY_agg) { @@ -6246,6 +6561,14 @@ void AArch64CGFunc::AssignLmbcFormalParams() { } else { param->SetRegNO(intReg); param->SetIsOnStack(); + param->SetOnStackOffset((intReg - R0 + fpReg - V0) * k8ByteSize); + uint32 bytelen = GetPrimTypeSize(PTY_a64); + uint32 bitlen = bytelen * kBitsPerByte; + MemOperand *mOpnd = GenLmbcFpMemOperand(param->GetOnStackOffset(), bytelen); + RegOperand &src = GetOrCreatePhysicalRegisterOperand(AArch64reg(intReg), bitlen, kRegTyInt); + MOperator mOp = PickStInsn(bitlen, PTY_a64); + Insn &store = GetCG()->BuildInstruction(mOp, src, *mOpnd); + GetCurBB()->AppendInsn(store); intReg++; } } else if (param->GetSize() <= k8ByteSize) { @@ -6291,7 +6614,6 @@ void AArch64CGFunc::AssignLmbcFormalParams() { Operand *memOpd = &CreateMemOpnd(RFP, offset + (i * rSize), rSize); GetCurBB()->AppendInsn(GetCG()->BuildInstruction( PickStInsn(rSize * kBitsPerByte, pType), dest, *memOpd)); - param->SetIsOnStack(); } } } else { @@ -6300,6 +6622,22 @@ void AArch64CGFunc::AssignLmbcFormalParams() { } } +void AArch64CGFunc::LmbcGenSaveSpForAlloca() { + if (GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc || HasVLAOrAlloca() == false) { + return; + } + Operand &spOpnd = GetOrCreatePhysicalRegisterOperand(RSP, k64BitSize, kRegTyInt); + RegOperand &spSaveOpnd = CreateVirtualRegisterOperand(NewVReg(kRegTyInt, kSizeOfPtr)); + Insn &save = GetCG()->BuildInstruction(MOP_xmovrr, spSaveOpnd, spOpnd); + GetFirstBB()->AppendInsn(save); + //save.SetFrameDef(true); + for (auto *retBB : GetExitBBsVec()) { + Insn &restore = GetCG()->BuildInstruction(MOP_xmovrr, spOpnd, spSaveOpnd); + retBB->AppendInsn(restore); + restore.SetFrameDef(true); + } +} + /* if offset < 0, allocation; otherwise, deallocation */ MemOperand &AArch64CGFunc::CreateCallFrameOperand(int32 offset, int32 size) { MemOperand *memOpnd = CreateStackMemOpnd(RSP, offset, size); @@ -7585,6 +7923,10 @@ size_t AArch64CGFunc::SelectParmListGetStructReturnSize(StmtNode &naryNode) { CallNode &callNode = static_cast(naryNode); MIRFunction *callFunc = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callNode.GetPUIdx()); TyIdx retIdx = callFunc->GetReturnTyIdx(); + if (callFunc->IsFirstArgReturn()) { + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(callFunc->GetFormalDefVec()[0].formalTyIdx); + return GetBecommon().GetTypeSize(static_cast(ty)->GetPointedTyIdx()); + } size_t retSize = GetBecommon().GetTypeSize(retIdx.GetIdx()); if ((retSize == 0) && callFunc->IsReturnStruct()) { TyIdx tyIdx = callFunc->GetFuncRetStructTyIdx(); @@ -7601,6 +7943,14 @@ size_t AArch64CGFunc::SelectParmListGetStructReturnSize(StmtNode &naryNode) { return GetBecommon().GetTypeSize(sym->GetTyIdx().GetIdx()); } } + } else if (naryNode.GetOpCode() == OP_icallproto) { + IcallNode &icallProto = static_cast(naryNode); + MIRFuncType *funcTy = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallProto.GetRetTyIdx())); + if (funcTy->FirstArgReturn()) { + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcTy->GetNthParamType(0)); + return GetBecommon().GetTypeSize(static_cast(ty)->GetPointedTyIdx()); + } + return GetBecommon().GetTypeSize(funcTy->GetRetTyIdx()); } return 0; } @@ -7708,7 +8058,7 @@ void AArch64CGFunc::SelectParmListPreprocess(const StmtNode &naryNode, size_t st */ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bool isCallNative) { size_t i = 0; - if ((naryNode.GetOpCode() == OP_icall) || isCallNative) { + if (naryNode.GetOpCode() == OP_icall || naryNode.GetOpCode() == OP_icallproto || isCallNative) { i++; } std::set specialArgs; @@ -7735,8 +8085,11 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - auto *callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + MIRFunction *callee = nullptr; + if (dynamic_cast(&naryNode) != nullptr) { + auto calleePuIdx = static_cast(naryNode).GetPUIdx(); + callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } @@ -8259,7 +8612,18 @@ void AArch64CGFunc::SelectCall(CallNode &callNode) { ListOperand *srcOpnds = CreateListOpnd(*GetFuncScopeAllocator()); if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { - LmbcSelectParmList(srcOpnds, fn->IsFirstArgReturn()); + SetLmbcCallReturnType(nullptr); + bool largeStructRet = false; + if (fn->IsFirstArgReturn()) { + MIRPtrType *ptrTy = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(fn->GetFormalDefVec()[0].formalTyIdx)); + MIRType *sTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ptrTy->GetPointedTyIdx()); + largeStructRet = sTy->GetSize() > k16ByteSize; + SetLmbcCallReturnType(sTy); + } else { + MIRType *ty = fn->GetReturnType(); + SetLmbcCallReturnType(ty); + } + LmbcSelectParmList(srcOpnds, largeStructRet); } bool callNative = false; if ((fsym->GetName() == "MCC_CallFastNative") || (fsym->GetName() == "MCC_CallFastNativeExt") || @@ -8335,11 +8699,21 @@ void AArch64CGFunc::SelectCall(CallNode &callNode) { void AArch64CGFunc::SelectIcall(IcallNode &icallNode, Operand &srcOpnd) { ListOperand *srcOpnds = CreateListOpnd(*GetFuncScopeAllocator()); - if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { - LmbcSelectParmList(srcOpnds, false /*fType->GetRetAttrs().GetAttr(ATTR_firstarg_return)*/); - } else { +// if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { +// /* icallproto */ +// MIRType *retTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallNode.GetRetTyIdx()); +// MIRFuncType *funcTy = static_cast(retTy); +// bool largeStructRet = false; +// if (funcTy->FirstArgReturn()) { +// TyIdx idx = funcTy->GetNthParamType(0); +// MIRPtrType *ptrTy = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(idx)); +// MIRType *sTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ptrTy->GetPointedTyIdx()); +// largeStructRet = sTy->GetSize() > k16ByteSize; +// } +// LmbcSelectParmList(srcOpnds, largeStructRet); +// } else { SelectParmList(icallNode, *srcOpnds); - } +// } Operand *fptrOpnd = &srcOpnd; if (fptrOpnd->GetKind() != Operand::kOpdRegister) { @@ -8350,7 +8724,7 @@ void AArch64CGFunc::SelectIcall(IcallNode &icallNode, Operand &srcOpnd) { RegOperand *regOpnd = static_cast(fptrOpnd); Insn &callInsn = GetCG()->BuildInstruction(MOP_xblr, *regOpnd, *srcOpnds); - MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallNode.GetRetTyIdx()); + MIRType *retType = icallNode.GetCallReturnType(); if (retType != nullptr) { callInsn.SetRetSize(static_cast(retType->GetSize())); callInsn.SetIsCallReturnUnsigned(IsUnsignedInteger(retType->GetPrimType())); @@ -8463,9 +8837,18 @@ RegOperand &AArch64CGFunc::GetOrCreateSpecialRegisterOperand(PregIdx sregIdx, Pr case kSregFp: reg = RFP; break; - case kSregGp: - reg = RFP; - break; + case kSregGp: { + MIRSymbol *sym = GetCG()->GetGP(); + if (sym == nullptr) { + sym = GetFunction().GetSymTab()->CreateSymbol(kScopeLocal); + std::string strBuf("__file__local__GP"); + sym->SetNameStrIdx(GetMirModule().GetMIRBuilder()->GetOrCreateStringIndex(strBuf)); + GetCG()->SetGP(sym); + } + RegOperand &result = GetOrCreateVirtualRegisterOperand(NewVReg(kRegTyInt, k8ByteSize)); + SelectAddrof(result, CreateStImmOperand(*sym, 0, 0)); + return result; + } case kSregThrownval: { /* uses x0 == R0 */ ASSERT(uCatch.regNOCatch > 0, "regNOCatch should greater than 0."); if (Globals::GetInstance()->GetOptimLevel() == 0) { @@ -9202,6 +9585,9 @@ int32 AArch64CGFunc::GetBaseOffset(const SymbolAlloc &sa) { int32 baseOffset = symAlloc->GetOffset(); return baseOffset + sizeofFplr; } else if (sgKind == kMsSpillReg) { + if (GetCG()->IsLmbc()) { + return symAlloc->GetOffset() + memLayout->SizeOfArgsToStackPass(); + } int32 baseOffset = symAlloc->GetOffset() + memLayout->SizeOfArgsRegisterPassed() + memLayout->GetSizeOfLocals() + memLayout->GetSizeOfRefLocals(); return baseOffset + sizeofFplr; @@ -9776,16 +10162,21 @@ void AArch64CGFunc::GenCVaStartIntrin(RegOperand &opnd, uint32 stkSize) { Operand &stkOpnd = GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); /* __stack */ - ImmOperand *offsOpnd = &CreateImmOperand(0, k64BitSize, true, kUnAdjustVary); /* isvary reset StackFrameSize */ + ImmOperand *offsOpnd; + if (GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + offsOpnd = &CreateImmOperand(0, k64BitSize, true, kUnAdjustVary); /* isvary reset StackFrameSize */ + } else { + offsOpnd = &CreateImmOperand(0, k64BitSize, true); + } ImmOperand *offsOpnd2 = &CreateImmOperand(stkSize, k64BitSize, false); RegOperand &vReg = CreateVirtualRegisterOperand(NewVReg(kRegTyInt, GetPrimTypeSize(LOWERED_PTR_TYPE))); if (stkSize) { SelectAdd(vReg, *offsOpnd, *offsOpnd2, LOWERED_PTR_TYPE); SelectAdd(vReg, stkOpnd, vReg, LOWERED_PTR_TYPE); } else { - SelectAdd(vReg, stkOpnd, *offsOpnd, LOWERED_PTR_TYPE); + SelectAdd(vReg, stkOpnd, *offsOpnd, LOWERED_PTR_TYPE); /* stack pointer */ } - OfstOperand *offOpnd = &GetOrCreateOfstOpnd(0, k64BitSize); + OfstOperand *offOpnd = &GetOrCreateOfstOpnd(0, k64BitSize); /* va_list ptr */ /* mem operand in va_list struct (lhs) */ MemOperand *strOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, k64BitSize, &opnd, nullptr, offOpnd, static_cast(nullptr)); @@ -9860,13 +10251,19 @@ void AArch64CGFunc::SelectCVaStart(const IntrinsiccallNode &intrnNode) { AArch64CallConvImpl parmLocator(GetBecommon()); CCLocInfo pLoc; uint32 stkSize = 0; + uint32 inReg = 0; for (uint32 i = 0; i < GetFunction().GetFormalCount(); i++) { MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(GetFunction().GetNthParamTyIdx(i)); parmLocator.LocateNextParm(*ty, pLoc); if (pLoc.reg0 == kRinvalid) { /* on stack */ stkSize = static_cast(pLoc.memOffset + pLoc.memSize); + } else { + inReg++; } } + if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + stkSize += (inReg * k8ByteSize); + } if (CGOptions::IsArm64ilp32()) { stkSize = static_cast(RoundUp(stkSize, k8ByteSize)); } else { diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp index 17d0bcdde9..4acfbd9e96 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp @@ -40,8 +40,8 @@ constexpr uint8 insPairsNum = 5; PairMOperator extInsnPairTable[ExtTableSize][insPairsNum] = { /* {origMop, newMop} */ - {{MOP_wldrb, MOP_wldrb}, {MOP_undef, MOP_undef}, {MOP_undef, MOP_undef}, {MOP_undef, MOP_undef}, - {MOP_undef, MOP_undef}}, /* AND */ + {{MOP_wldrb, MOP_wldrb}, {MOP_wldrsh, MOP_wldrb}, {MOP_wldrh, MOP_wldrb}, {MOP_xldrsw, MOP_wldrb}, + {MOP_wldr, MOP_wldrb}}, /* AND */ {{MOP_wldrb, MOP_wldrsb}, {MOP_wldr, MOP_wldrsb}, {MOP_undef, MOP_undef}, {MOP_undef, MOP_undef}, {MOP_undef, MOP_undef}}, /* SXTB */ {{MOP_wldrh, MOP_wldrsh}, {MOP_wldrb, MOP_wldrb}, {MOP_wldrsb, MOP_wldrsb}, {MOP_wldrsh, MOP_wldrsh}, diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp index e9acbeefcc..71f57d89ea 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp @@ -134,7 +134,7 @@ void AArch64MemLayout::LayoutVarargParams() { if (be.GetMIRModule().IsCModule() && func->GetAttr(FUNCATTR_varargs)) { for (uint32 i = 0; i < func->GetFormalCount(); i++) { if (i == 0) { - if (func->IsReturnStruct()) { + if (func->IsFirstArgReturn() && func->GetReturnType()->GetPrimType() != PTY_void) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (be.GetTypeSize(tyIdx.GetIdx()) <= k16ByteSize) { continue; @@ -198,7 +198,7 @@ void AArch64MemLayout::LayoutFormalParams() { * outparmsize - portion of frame size of current function used by call parameters */ segArgsStkPassed.SetSize(mirFunction->GetOutParmSize()); - segArgsRegPassed.SetSize(mirFunction->GetOutParmSize() + kTwoRegister * k8ByteSize); + segArgsRegPassed.SetSize(mirFunction->GetOutParmSize()); return; } @@ -210,7 +210,7 @@ void AArch64MemLayout::LayoutFormalParams() { AArch64SymbolAlloc *symLoc = memAllocator->GetMemPool()->New(); SetSymAllocInfo(stIndex, *symLoc); if (i == 0) { - if (mirFunction->IsReturnStruct()) { + if (mirFunction->IsFirstArgReturn()) { symLoc->SetMemSegment(GetSegArgsRegPassed()); symLoc->SetOffset(GetSegArgsRegPassed().GetSize()); TyIdx tyIdx = mirFunction->GetFuncRetStructTyIdx(); @@ -224,13 +224,13 @@ void AArch64MemLayout::LayoutFormalParams() { continue; } } - MIRType *ty = mirFunction->GetNthParamType(i); + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(mirFunction->GetFormalDefVec()[i].formalTyIdx); uint32 ptyIdx = ty->GetTypeIndex(); parmLocator.LocateNextParm(*ty, ploc, i == 0, mirFunction); if (ploc.reg0 != kRinvalid) { /* register */ symLoc->SetRegisters(static_cast(ploc.reg0), static_cast(ploc.reg1), static_cast(ploc.reg2), static_cast(ploc.reg3)); - if (mirFunction->GetNthParamAttr(i).GetAttr(ATTR_localrefvar)) { + if (mirFunction->GetFormalDefVec()[i].formalAttrs.GetAttr(ATTR_localrefvar)) { symLoc->SetMemSegment(segRefLocals); SetSegmentSize(*symLoc, segRefLocals, ptyIdx); } else if (!sym->IsPreg()) { @@ -272,7 +272,7 @@ void AArch64MemLayout::LayoutFormalParams() { } else { segArgsStkPassed.SetSize(static_cast(RoundUp(segArgsStkPassed.GetSize(), kSizeOfPtr))); } - if (mirFunction->GetNthParamAttr(i).GetAttr(ATTR_localrefvar)) { + if (mirFunction->GetFormalDefVec()[i].formalAttrs.GetAttr(ATTR_localrefvar)) { SetLocalRegLocInfo(sym->GetStIdx(), *symLoc); AArch64SymbolAlloc *symLoc1 = memAllocator->GetMemPool()->New(); symLoc1->SetMemSegment(segRefLocals); @@ -287,7 +287,7 @@ void AArch64MemLayout::LayoutFormalParams() { } void AArch64MemLayout::LayoutLocalVariables(std::vector &tempVar, std::vector &returnDelays) { - if (be.GetMIRModule().GetFlavor() == kFlavorLmbc && mirFunction->GetFormalCount() == 0) { + if (be.GetMIRModule().GetFlavor() == kFlavorLmbc) { segLocals.SetSize(mirFunction->GetFrameSize() - mirFunction->GetOutParmSize()); return; } @@ -372,7 +372,7 @@ void AArch64MemLayout::LayoutReturnRef(std::vector &returnDelays, segRefLocals.SetSize(segRefLocals.GetSize() + be.GetTypeSize(tyIdx)); } if (be.GetMIRModule().GetFlavor() == kFlavorLmbc) { - segArgsToStkPass.SetSize(mirFunction->GetOutParmSize()); + segArgsToStkPass.SetSize(mirFunction->GetOutParmSize() + kDivide2 * k8ByteSize); } else { segArgsToStkPass.SetSize(FindLargestActualArea(structCopySize)); } @@ -423,7 +423,7 @@ void AArch64MemLayout::LayoutActualParams() { * variables get assigned their respecitve storage, i.e. * CallFrameSize (discounting callee-saved and FP/LR) is known. */ - MIRType *ty = mirFunction->GetNthParamType(i); + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(mirFunction->GetFormalDefVec()[i].formalTyIdx); uint32 ptyIdx = ty->GetTypeIndex(); static_cast(cgFunc)->GetOrCreateMemOpnd(*sym, 0, be.GetTypeAlign(ptyIdx) * kBitsPerByte); } @@ -440,7 +440,7 @@ void AArch64MemLayout::LayoutStackFrame(int32 &structCopySize, int32 &maxParmSta */ if (CGOptions::IsArm64ilp32()) { segArgsRegPassed.SetSize(RoundUp(segArgsRegPassed.GetSize(), k8ByteSize)); - /* we do need this as SP has to be aligned at a 16-bytes bounardy */ + /* we do need this as SP has to be aligned at a 16-bytes bounardy */ segArgsStkPassed.SetSize(RoundUp(segArgsStkPassed.GetSize(), k8ByteSize + k8ByteSize)); } else { segArgsRegPassed.SetSize(RoundUp(segArgsRegPassed.GetSize(), kSizeOfPtr)); @@ -527,11 +527,13 @@ uint64 AArch64MemLayout::StackFrameSize() const { uint64 total = segArgsRegPassed.GetSize() + static_cast(cgFunc)->SizeOfCalleeSaved() + GetSizeOfRefLocals() + locals().GetSize() + GetSizeOfSpillReg(); - if (GetSizeOfGRSaveArea() > 0) { - total += RoundUp(GetSizeOfGRSaveArea(), kAarch64StackPtrAlignment); - } - if (GetSizeOfVRSaveArea() > 0) { - total += RoundUp(GetSizeOfVRSaveArea(), kAarch64StackPtrAlignment); + if (cgFunc->GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + if (GetSizeOfGRSaveArea() > 0) { + total += RoundUp(GetSizeOfGRSaveArea(), kAarch64StackPtrAlignment); + } + if (GetSizeOfVRSaveArea() > 0) { + total += RoundUp(GetSizeOfVRSaveArea(), kAarch64StackPtrAlignment); + } } /* diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp index eaa5726d43..7ef7190645 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp @@ -50,7 +50,7 @@ void AArch64FPLROffsetAdjustment::AdjustmentOffsetForOpnd(Insn &insn, AArch64CGF if (memBaseReg->GetRegisterNumber() == RFP) { RegOperand &newBaseOpnd = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(stackBaseReg, k64BitSize, kRegTyInt); MemOperand &newMemOpnd = aarchCGFunc.GetOrCreateMemOpnd( - MemOperand::kAddrModeBOi, memOpnd.GetSize(), &newBaseOpnd, memOpnd.GetIndexRegister(), + memOpnd.GetAddrMode(), memOpnd.GetSize(), &newBaseOpnd, memOpnd.GetIndexRegister(), memOpnd.GetOffsetImmediate(), memOpnd.GetSymbol()); insn.SetOperand(i, newMemOpnd); stackBaseOpnd = true; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp index 109cc5087a..4fd65cebdd 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp @@ -1118,6 +1118,9 @@ void AArch64GenProEpilog::AppendInstructionAllocateCallFrameDebug(AArch64reg reg ipoint = cgFunc.GetCurBB()->GetLastInsn(); cfiOffset = stackFrameSize; (void)InsertCFIDefCfaOffset(cfiOffset, *ipoint); + if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + argsToStkPassSize -= (kDivide2 * k8ByteSize); + } ipoint = &CreateAndAppendInstructionForAllocateCallFrame(argsToStkPassSize, reg0, reg1, rty); CHECK_FATAL(ipoint != nullptr, "ipoint should not be nullptr at this point"); cfiOffset = GetOffsetFromCFA(); @@ -1251,9 +1254,16 @@ void AArch64GenProEpilog::GeneratePushRegs() { CHECK_FATAL(*it == RLR, "The second callee saved reg is expected to be RLR"); ++it; - auto offset = static_cast((static_cast(cgFunc.GetMemlayout())->RealStackFrameSize() - - (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */)) - - cgFunc.GetMemlayout()->SizeOfArgsToStackPass()); + AArch64MemLayout *memLayout = static_cast(cgFunc.GetMemlayout()); + int32 offset; + if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + offset = static_cast(memLayout->RealStackFrameSize() - + aarchCGFunc.SizeOfCalleeSaved() - memLayout->GetSizeOfLocals()); + } else { + offset = static_cast(memLayout->RealStackFrameSize() - + (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */) - + memLayout->SizeOfArgsToStackPass()); + } if (cgFunc.GetCG()->IsStackProtectorStrong() || cgFunc.GetCG()->IsStackProtectorAll()) { offset -= kAarch64StackPtrAlignment; @@ -1313,10 +1323,19 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { size = kSizeOfPtr; } uint32 dataSizeBits = size * kBitsPerByte; - uint32 offset = static_cast(memlayout->GetGRSaveAreaBaseLoc()); - if (memlayout->GetSizeOfGRSaveArea() % kAarch64StackPtrAlignment) { - offset += size; /* End of area should be aligned. Hole between VR and GR area */ + uint32 offset; + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + offset = static_cast(memlayout->GetGRSaveAreaBaseLoc()); /* SP reference */ + if (memlayout->GetSizeOfGRSaveArea() % kAarch64StackPtrAlignment) { + offset += size; /* End of area should be aligned. Hole between VR and GR area */ + } + } else { + offset = -memlayout->GetSizeOfGRSaveArea(); /* FP reference */ + if (memlayout->GetSizeOfGRSaveArea() % kAarch64StackPtrAlignment) { + offset -= size; + } } + uint32 grSize = -offset; uint32 start_regno = k8BitSize - (memlayout->GetSizeOfGRSaveArea() / size); ASSERT(start_regno <= k8BitSize, "Incorrect starting GR regno for GR Save Area"); for (uint32 i = start_regno + static_cast(R0); i < static_cast(R8); i++) { @@ -1326,16 +1345,25 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { tmpOffset += 8U - (dataSizeBits >> 3); } } - Operand &stackloc = aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); + Operand *stackLoc; + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + stackLoc = &aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); + } else { + stackLoc = aarchCGFunc.GenLmbcFpMemOperand(offset, size); + } RegOperand ® = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(static_cast(i), k64BitSize, kRegTyInt); Insn &inst = - currCG->BuildInstruction(aarchCGFunc.PickStInsn(dataSizeBits, PTY_i64), reg, stackloc); + currCG->BuildInstruction(aarchCGFunc.PickStInsn(dataSizeBits, PTY_i64), reg, *stackLoc); cgFunc.GetCurBB()->AppendInsn(inst); offset += size; } if (!CGOptions::UseGeneralRegOnly()) { - offset = static_cast(memlayout->GetVRSaveAreaBaseLoc()); + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + offset = static_cast(memlayout->GetVRSaveAreaBaseLoc()); + } else { + offset = -(memlayout->GetSizeOfVRSaveArea() + grSize); + } start_regno = k8BitSize - (memlayout->GetSizeOfVRSaveArea() / (size * k2BitSize)); ASSERT(start_regno <= k8BitSize, "Incorrect starting GR regno for VR Save Area"); for (uint32 i = start_regno + static_cast(V0); i < static_cast(V8); i++) { @@ -1345,11 +1373,16 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { tmpOffset += 16U - (dataSizeBits >> 3); } } - Operand &stackloc = aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); + Operand *stackLoc; + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + stackLoc = &aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); + } else { + stackLoc = aarchCGFunc.GenLmbcFpMemOperand(offset, size); + } RegOperand ® = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(static_cast(i), k64BitSize, kRegTyFloat); Insn &inst = - currCG->BuildInstruction(aarchCGFunc.PickStInsn(dataSizeBits, PTY_f64), reg, stackloc); + currCG->BuildInstruction(aarchCGFunc.PickStInsn(dataSizeBits, PTY_f64), reg, *stackLoc); cgFunc.GetCurBB()->AppendInsn(inst); offset += (size * k2BitSize); } @@ -1389,7 +1422,8 @@ void AArch64GenProEpilog::GenerateProlog(BB &bb) { } // insert .loc for function - if (currCG->GetCGOptions().WithLoc()) { + if (currCG->GetCGOptions().WithLoc() && + (!currCG->GetMIRModule()->IsCModule() || currCG->GetMIRModule()->IsWithDbgInfo())) { MIRFunction *func = &cgFunc.GetFunction(); MIRSymbol *fSym = GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx()); if (currCG->GetCGOptions().WithSrc()) { @@ -1649,11 +1683,17 @@ void AArch64GenProEpilog::AppendInstructionDeallocateCallFrameDebug(AArch64reg r * ldp/stp's imm should be within -512 and 504; * if ldp's imm > 504, we fall back to the ldp-add version */ - if (cgFunc.HasVLAOrAlloca() || argsToStkPassSize == 0) { - stackFrameSize -= argsToStkPassSize; - if (stackFrameSize > kStpLdpImm64UpperBound) { + bool isLmbc = (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc); + if (cgFunc.HasVLAOrAlloca() || argsToStkPassSize == 0 || isLmbc) { + int lmbcOffset = 0; + if (isLmbc == false) { + stackFrameSize -= argsToStkPassSize; + } else { + lmbcOffset = argsToStkPassSize - (kDivide2 * k8ByteSize); + } + if (stackFrameSize > kStpLdpImm64UpperBound || isLmbc) { Operand *o2; - o2 = aarchCGFunc.CreateStackMemOpnd(RSP, 0, kSizeOfPtr * kBitsPerByte); + o2 = aarchCGFunc.CreateStackMemOpnd(RSP, (isLmbc ? lmbcOffset : 0), kSizeOfPtr * kBitsPerByte); Insn &deallocInsn = currCG->BuildInstruction(mOp, o0, o1, *o2); cgFunc.GetCurBB()->AppendInsn(deallocInsn); if (cgFunc.GenCfi()) { @@ -1728,9 +1768,16 @@ void AArch64GenProEpilog::GeneratePopRegs() { CHECK_FATAL(*it == RLR, "The second callee saved reg is expected to be RLR"); ++it; - int32 offset = static_cast((static_cast(cgFunc.GetMemlayout())->RealStackFrameSize() - - (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */)) - - cgFunc.GetMemlayout()->SizeOfArgsToStackPass()); + AArch64MemLayout *memLayout = static_cast(cgFunc.GetMemlayout()); + int32 offset; + if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + offset = static_cast(memLayout->RealStackFrameSize() - + aarchCGFunc.SizeOfCalleeSaved() - memLayout->GetSizeOfLocals()); + } else { + offset = static_cast(cgFunc.GetMemlayout())->RealStackFrameSize() - + (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */) - + memLayout->SizeOfArgsToStackPass(); + } if (cgFunc.GetCG()->IsStackProtectorStrong() || cgFunc.GetCG()->IsStackProtectorAll()) { offset -= kAarch64StackPtrAlignment; @@ -1821,7 +1868,7 @@ void AArch64GenProEpilog::GenerateEpilog(BB &bb) { Operand &spOpnd = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(RSP, k64BitSize, kRegTyInt); Operand &fpOpnd = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(stackBaseReg, k64BitSize, kRegTyInt); - if (cgFunc.HasVLAOrAlloca()) { + if (cgFunc.HasVLAOrAlloca() && cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { aarchCGFunc.SelectCopy(spOpnd, PTY_u64, fpOpnd, PTY_u64); } diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp index 433cc85754..5ca154b1aa 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp @@ -161,8 +161,7 @@ void AArch64ReachingDefinition::AddRetPseudoInsn(BB &bb) { Insn &retInsn = cgFunc->GetCG()->BuildInstruction(MOP_pseudo_ret_int, regOpnd); bb.AppendInsn(retInsn); pseudoInsns.emplace_back(&retInsn); - } else { - ASSERT(regNO == V0, "CG internal error. Return value should be R0 or V0."); + } else if (regNO == V0) { RegOperand ®Opnd = static_cast(cgFunc)->GetOrCreatePhysicalRegisterOperand(regNO, k64BitSize, kRegTyFloat); Insn &retInsn = cgFunc->GetCG()->BuildInstruction(MOP_pseudo_ret_float, regOpnd); diff --git a/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp b/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp index d2ae2c25c9..bf645c15cd 100644 --- a/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp +++ b/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp @@ -160,6 +160,7 @@ void RecursiveMarkUsedStaticSymbol(const BaseNode *baseNode) { break; } case OP_addrof: + case OP_addrofoff: case OP_dread: { const AddrofNode *dreadNode = static_cast(baseNode); MarkUsedStaticSymbol(dreadNode->GetStIdx()); diff --git a/src/mapleall/maple_be/src/cg/cgfunc.cpp b/src/mapleall/maple_be/src/cg/cgfunc.cpp index f6075c05dd..5e35444b07 100644 --- a/src/mapleall/maple_be/src/cg/cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/cgfunc.cpp @@ -1148,7 +1148,11 @@ void HandleReturn(StmtNode &stmt, CGFunc &cgFunc) { ASSERT(retNode.NumOpnds() <= 1, "NYI return nodes number > 1"); Operand *opnd = nullptr; if (retNode.NumOpnds() != 0) { - opnd = cgFunc.HandleExpr(retNode, *retNode.Opnd(0)); + if (!cgFunc.GetFunction().StructReturnedInRegs()) { + opnd = cgFunc.HandleExpr(retNode, *retNode.Opnd(0)); + } else { + cgFunc.SelectReturnSendOfStructInRegs(retNode.Opnd(0)); + } } cgFunc.SelectReturn(opnd); cgFunc.SetCurBBKind(BB::kBBReturn); @@ -1564,14 +1568,15 @@ void CGFunc::CreateLmbcFormalParamInfo() { uint32 offset; uint32 typeSize; MIRFunction &func = GetFunction(); - if (func.GetParamSize() > 0) { + if (func.GetFormalCount() > 0) { + /* Whenever lmbc cannot delete call type info, the prototype is available */ uint32 stackOffset = 0; - for (size_t idx = 0; idx < func.GetParamSize(); ++idx) { + for (size_t idx = 0; idx < func.GetFormalCount(); ++idx) { MIRSymbol *sym = func.GetFormal(idx); MIRType *type; TyIdx tyIdx; if (sym) { - tyIdx = func.GetNthParamTyIdx(idx); + tyIdx = func.GetFormalDefVec()[idx].formalTyIdx; type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); } else { FormalDef vec = const_cast(GetBecommon().GetMIRModule().CurFunction())->GetFormalDefAt(idx); @@ -1618,6 +1623,9 @@ void CGFunc::CreateLmbcFormalParamInfo() { } IreadFPoffNode *ireadNode = static_cast(operand); primType = ireadNode->GetPrimType(); + if (ireadNode->GetOffset() < 0) { + continue; + } offset = static_cast(ireadNode->GetOffset()); typeSize = GetPrimTypeSize(primType); CHECK_FATAL((offset % k8ByteSize) == 0, ""); /* scalar only, no struct for now */ @@ -1629,6 +1637,31 @@ void CGFunc::CreateLmbcFormalParamInfo() { [] (LmbcFormalParamInfo *x, LmbcFormalParamInfo *y) { return x->GetOffset() < y->GetOffset(); } ); + + /* When a scalar param address is taken, its regassign is not in the 1st block */ + for (StmtNode *stmt = func.GetBody()->GetFirst(); stmt != nullptr; stmt = stmt->GetNext()) { + if (stmt == nullptr) { + break; + } + if (stmt->GetOpCode() == OP_label) { + continue; + } + if (stmt->GetOpCode() != OP_regassign) { + break; + } + RegassignNode *regAssignNode = static_cast(stmt); + BaseNode *operand = regAssignNode->Opnd(0); + if (operand->GetOpCode() != OP_ireadfpoff) { + break; + } + IreadFPoffNode *ireadNode = static_cast(operand); + if (ireadNode->GetOffset() < 0) { + continue; + } + LmbcFormalParamInfo *info = GetLmbcFormalParamInfo(ireadNode->GetOffset()); + info->SetHasRegassign(); + } + AssignLmbcFormalParams(); } @@ -1637,7 +1670,7 @@ void CGFunc::GenerateInstruction() { InitHandleStmtFactory(); StmtNode *secondStmt = HandleFirstStmt(); - CreateLmbcFormalParamInfo(); + //CreateLmbcFormalParamInfo(); /* First Pass: Creates the doubly-linked list of BBs (next,prev) */ volReleaseInsn = nullptr; unsigned lastSrcLoc = 0; @@ -2009,6 +2042,7 @@ void CGFunc::HandleFunction() { ASSERT(exitBBVec.size() <= 1, "there are more than one BB_return in func"); } ProcessExitBBVec(); + LmbcGenSaveSpForAlloca(); if (func.IsJava()) { GenerateCleanupCodeForExtEpilog(*cleanupBB); diff --git a/src/mapleall/maple_be/src/cg/emit.cpp b/src/mapleall/maple_be/src/cg/emit.cpp index 93961a791c..3268bff23a 100644 --- a/src/mapleall/maple_be/src/cg/emit.cpp +++ b/src/mapleall/maple_be/src/cg/emit.cpp @@ -2170,6 +2170,11 @@ void Emitter::EmitGlobalVar(const MIRSymbol &globalVar) { } void Emitter::EmitGlobalVars(std::vector> &globalVars) { + if (GetCG()->IsLmbc() && GetCG()->GetGP() != nullptr) { + Emit(asmInfo->GetLocal()).Emit("\t").Emit(GetCG()->GetGP()->GetName()).Emit("\n"); + Emit(asmInfo->GetComm()).Emit("\t").Emit(GetCG()->GetGP()->GetName()); + Emit(", ").Emit(GetCG()->GetMIRModule()->GetGlobalMemSize()).Emit(", ").Emit("8\n"); + } /* load globalVars profile */ if (globalVars.empty()) { return; diff --git a/src/mapleall/maple_be/src/cg/memlayout.cpp b/src/mapleall/maple_be/src/cg/memlayout.cpp index 57e45e8a2d..1b636207c6 100644 --- a/src/mapleall/maple_be/src/cg/memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/memlayout.cpp @@ -38,7 +38,7 @@ uint32 MemLayout::FindLargestActualArea(int32 &aggCopySize) { uint32 maxCopyStackSize = 0; // Size of aggregate param stack copy requirement for (; stmt != nullptr; stmt = stmt->GetNext()) { Opcode opCode = stmt->GetOpCode(); - if (opCode < OP_call || opCode > OP_xintrinsiccallassigned) { + if ((opCode < OP_call || opCode > OP_xintrinsiccallassigned) && opCode != OP_icallproto) { continue; } if (opCode == OP_intrinsiccallwithtypeassigned || opCode == OP_intrinsiccallwithtype || @@ -54,9 +54,9 @@ uint32 MemLayout::FindLargestActualArea(int32 &aggCopySize) { * if the following check fails, most likely dex has invoke-custom etc * that is not supported yet */ - DCHECK((opCode == OP_call || opCode == OP_icall), "Not lowered to call or icall?"); + DCHECK((opCode == OP_call || opCode == OP_icall || opCode == OP_icallproto), "Not lowered to call or icall?"); int32 copySize; - uint32 size = ComputeStackSpaceRequirementForCall(*stmt, copySize, opCode == OP_icall); + uint32 size = ComputeStackSpaceRequirementForCall(*stmt, copySize, opCode == OP_icall || opCode == OP_icallproto); if (size > maxParamStackSize) { maxParamStackSize = size; } diff --git a/src/mapleall/maple_ir/include/bin_mpl_export.h b/src/mapleall/maple_ir/include/bin_mpl_export.h index 09952cb8c7..f12bec7081 100644 --- a/src/mapleall/maple_ir/include/bin_mpl_export.h +++ b/src/mapleall/maple_ir/include/bin_mpl_export.h @@ -67,8 +67,8 @@ enum : uint8 { kBinEaCgStart = 41, kBinEaStart = 42, kBinNodeBlock = 43, - kBinOpStatement = 44, - kBinOpExpression = 45, +//kBinOpStatement = 44, +//kBinOpExpression = 45, kBinReturnvals = 46, kBinTypeTabStart = 47, kBinSymStart = 48, @@ -76,14 +76,14 @@ enum : uint8 { kBinFuncIdInfoStart = 50, kBinFormalStart = 51, kBinPreg = 52, - kBinPregStart = 53, - kBinLabelStart = 54, + kBinSpecialReg = 53, + kBinLabel = 54, kBinTypenameStart = 55, kBinHeaderStart = 56, kBinAliasMapStart = 57, - kBinKindTypeViaTypename = 58, - kBinKindSymViaSymname = 59, - kBinKindFuncViaSymname = 60, +//kBinKindTypeViaTypename = 58, +//kBinKindSymViaSymname = 59, +//kBinKindFuncViaSymname = 60, kBinFunctionBodyStart = 61, kBinFormalWordsTypeTagged = 62, kBinFormalWordsRefCounted = 63, @@ -103,8 +103,7 @@ class BinaryMplExport { void Export(const std::string &fname, std::unordered_set *dumpFuncSet); void WriteNum(int64 x); void Write(uint8 b); - void OutputType(TyIdx tyIdx, bool canUseTypename); - void OutputTypeViaTypeName(TyIdx tidx) { OutputType(tidx, true); } + void OutputType(TyIdx tyIdx); void WriteFunctionBodyField(uint64 contentIdx, std::unordered_set *dumpFuncSet); void OutputConst(MIRConst *c); void OutputConstBase(const MIRConst &c); @@ -133,12 +132,11 @@ class BinaryMplExport { void OutputInfoVector(const MIRInfoVector &infoVector, const MapleVector &infoVectorIsString); void OutputFuncIdInfo(MIRFunction *func); void OutputLocalSymbol(MIRSymbol *sym); - void OutputLocalSymTab(const MIRFunction *func); - void OutputPregTab(const MIRFunction *func); - void OutputLabelTab(const MIRFunction *func); + void OutputPreg(MIRPreg *preg); + void OutputLabel(LabelIdx lidx); void OutputLocalTypeNameTab(const MIRTypeNameTable *tyNameTab); void OutputFormalsStIdx(MIRFunction *func); - void OutputFuncViaSymName(PUIdx puIdx); + void OutputFuncViaSym(PUIdx puIdx); void OutputExpression(BaseNode *e); void OutputBaseNode(const BaseNode *b); void OutputReturnValues(const CallReturnVector *retv); @@ -182,6 +180,7 @@ class BinaryMplExport { void ExpandFourBuffSize(); MIRModule &mod; + MIRFunction *curFunc = nullptr; size_t bufI = 0; std::vector buf; std::unordered_map gStrMark; @@ -190,6 +189,9 @@ class BinaryMplExport { std::unordered_map uStrMark; std::unordered_map symMark; std::unordered_map typMark; + std::unordered_map localSymMark; + std::unordered_map localPregMark; + std::unordered_map labelMark; friend class UpdateMplt; std::unordered_map callInfoMark; std::map *func2SEMap = nullptr; diff --git a/src/mapleall/maple_ir/include/bin_mpl_import.h b/src/mapleall/maple_ir/include/bin_mpl_import.h index 3697654872..ee7f909f9b 100644 --- a/src/mapleall/maple_ir/include/bin_mpl_import.h +++ b/src/mapleall/maple_ir/include/bin_mpl_import.h @@ -126,15 +126,14 @@ class BinaryMplImport { void ImportInfoVector(MIRInfoVector &infoVector, MapleVector &infoVectorIsString); void ImportLocalTypeNameTable(MIRTypeNameTable *typeNameTab); void ImportFuncIdInfo(MIRFunction *func); - void ImportLocalSymbol(MIRFunction *func); - void ImportLocalSymTab(MIRFunction *func); - void ImportPregTab(const MIRFunction *func); - void ImportLabelTab(MIRFunction *func); + MIRSymbol *ImportLocalSymbol(MIRFunction *func); + PregIdx ImportPreg(MIRFunction *func); + LabelIdx ImportLabel(MIRFunction *func); void ImportFormalsStIdx(MIRFunction *func); void ImportAliasMap(MIRFunction *func); void ImportSrcPos(SrcPosition &pos); void ImportBaseNode(Opcode &o, PrimType &typ); - PUIdx ImportFuncViaSymName(); + PUIdx ImportFuncViaSym(MIRFunction *func); BaseNode *ImportExpression(MIRFunction *func); void ImportReturnValues(MIRFunction *func, CallReturnVector *retv); BlockNode *ImportBlockNode(MIRFunction *fn); @@ -162,6 +161,9 @@ class BinaryMplImport { std::vector typTab; std::vector funcTab; std::vector symTab; + std::vector localSymTab; + std::vector localPregTab; + std::vector localLabelTab; std::vector callInfoTab; std::vector eaCgTab; std::vector methodSymbols; diff --git a/src/mapleall/maple_ir/include/ir_safe_cast_traits.def b/src/mapleall/maple_ir/include/ir_safe_cast_traits.def index 1439b49d57..14ed1a367b 100644 --- a/src/mapleall/maple_ir/include/ir_safe_cast_traits.def +++ b/src/mapleall/maple_ir/include/ir_safe_cast_traits.def @@ -224,7 +224,9 @@ REGISTER_SAFE_CAST(CallNode, from.GetOpCode() == OP_call || from.GetOpCode() == OP_virtualicallassigned || instance_of(from)); REGISTER_SAFE_CAST(IcallNode, from.GetOpCode() == OP_icall || - from.GetOpCode() == OP_icallassigned); + from.GetOpCode() == OP_icallassigned || + from.GetOpCode() == OP_icallproto || + from.GetOpCode() == OP_icallprotoassigned); REGISTER_SAFE_CAST(IntrinsiccallNode, from.GetOpCode() == OP_intrinsiccall || from.GetOpCode() == OP_intrinsiccallwithtype || from.GetOpCode() == OP_xintrinsiccall || diff --git a/src/mapleall/maple_ir/include/keywords.def b/src/mapleall/maple_ir/include/keywords.def index eddff2f80a..51a603eafa 100644 --- a/src/mapleall/maple_ir/include/keywords.def +++ b/src/mapleall/maple_ir/include/keywords.def @@ -55,7 +55,6 @@ // per-function declaration keywords KEYWORD(framesize) KEYWORD(upformalsize) - KEYWORD(outparmsize) KEYWORD(moduleid) KEYWORD(funcsize) KEYWORD(funcid) diff --git a/src/mapleall/maple_ir/include/mir_builder.h b/src/mapleall/maple_ir/include/mir_builder.h index 5c38b7da10..9f3a5455bc 100755 --- a/src/mapleall/maple_ir/include/mir_builder.h +++ b/src/mapleall/maple_ir/include/mir_builder.h @@ -262,6 +262,8 @@ class MIRBuilder { IcallNode *CreateStmtIcall(const MapleVector &args); IcallNode *CreateStmtIcallAssigned(const MapleVector &args, const MIRSymbol &ret); + IcallNode *CreateStmtIcallproto(const MapleVector &args); + IcallNode *CreateStmtIcallprotoAssigned(const MapleVector &args, const MIRSymbol &ret); // For Call, VirtualCall, SuperclassCall, InterfaceCall IntrinsiccallNode *CreateStmtIntrinsicCall(MIRIntrinsicID idx, const MapleVector &arguments, TyIdx tyIdx = TyIdx()); diff --git a/src/mapleall/maple_ir/include/mir_function.h b/src/mapleall/maple_ir/include/mir_function.h index b3a4a5e4f8..96fdab5cea 100644 --- a/src/mapleall/maple_ir/include/mir_function.h +++ b/src/mapleall/maple_ir/include/mir_function.h @@ -830,24 +830,24 @@ class MIRFunction { callTimes = times; } - uint16 GetFrameSize() const { + uint32 GetFrameSize() const { return frameSize; } - void SetFrameSize(uint16 size) { + void SetFrameSize(uint32 size) { frameSize = size; } - uint16 GetUpFormalSize() const { + uint32 GetUpFormalSize() const { return upFormalSize; } - void SetUpFormalSize(uint16 size) { + void SetUpFormalSize(uint32 size) { upFormalSize = size; } - uint16 GetOutParmSize() const { + uint32 GetOutParmSize() const { return outParmSize; } - void SetOutParmSize(uint16 size) { + void SetOutParmSize(uint32 size) { outParmSize = size; } @@ -1298,9 +1298,9 @@ class MIRFunction { bool isDirty = false; bool fromMpltInline = false; // Whether this function is imported from mplt_inline file or not. uint8_t layoutType = kLayoutUnused; - uint16 frameSize = 0; - uint16 upFormalSize = 0; - uint16 outParmSize = 0; + uint32 frameSize = 0; + uint32 upFormalSize = 0; + uint32 outParmSize = 0; uint16 moduleID = 0; uint32 funcSize = 0; // size of code in words uint32 tempCount = 0; diff --git a/src/mapleall/maple_ir/include/mir_lower.h b/src/mapleall/maple_ir/include/mir_lower.h index 332a6de89f..be479f65a6 100644 --- a/src/mapleall/maple_ir/include/mir_lower.h +++ b/src/mapleall/maple_ir/include/mir_lower.h @@ -86,6 +86,7 @@ class MIRLower { ForeachelemNode *ExpandArrayMrtForeachelemBlock(ForeachelemNode &node); BlockNode *ExpandArrayMrtBlock(BlockNode &block); void AddArrayMrtMpl(BaseNode &exp, BlockNode &newblk); + MIRFuncType *FuncTypeFromFuncPtrExpr(BaseNode *x); void SetLowerME() { lowerPhase |= kShiftLowerMe; } diff --git a/src/mapleall/maple_ir/include/mir_nodes.h b/src/mapleall/maple_ir/include/mir_nodes.h index 7864fd412b..3e5524df39 100755 --- a/src/mapleall/maple_ir/include/mir_nodes.h +++ b/src/mapleall/maple_ir/include/mir_nodes.h @@ -3304,7 +3304,7 @@ class CallNode : public NaryStmtNode { CallReturnVector returnValues; }; -// icall and icallproto +// icall, icallassigned, icallproto and icallprotoassigned class IcallNode : public NaryStmtNode { public: IcallNode(MapleAllocator &allocator, Opcode o) diff --git a/src/mapleall/maple_ir/include/mir_parser.h b/src/mapleall/maple_ir/include/mir_parser.h index 10d1dd028a..b49370d0ff 100755 --- a/src/mapleall/maple_ir/include/mir_parser.h +++ b/src/mapleall/maple_ir/include/mir_parser.h @@ -134,6 +134,7 @@ class MIRParser { bool ParseStmtIcall(StmtNodePtr&); bool ParseStmtIcallassigned(StmtNodePtr&); bool ParseStmtIcallproto(StmtNodePtr&); + bool ParseStmtIcallprotoassigned(StmtNodePtr&); bool ParseStmtIntrinsiccall(StmtNodePtr&, bool isAssigned); bool ParseStmtIntrinsiccall(StmtNodePtr&); bool ParseStmtIntrinsiccallassigned(StmtNodePtr&); @@ -291,7 +292,6 @@ class MIRParser { bool ParseStmtBlockForType(); bool ParseStmtBlockForFrameSize(); bool ParseStmtBlockForUpformalSize(); - bool ParseStmtBlockForOutParmSize(); bool ParseStmtBlockForModuleID(); bool ParseStmtBlockForFuncSize(); bool ParseStmtBlockForFuncID(); diff --git a/src/mapleall/maple_ir/include/mir_symbol.h b/src/mapleall/maple_ir/include/mir_symbol.h index 0d1d127dbe..357242d0e2 100644 --- a/src/mapleall/maple_ir/include/mir_symbol.h +++ b/src/mapleall/maple_ir/include/mir_symbol.h @@ -484,12 +484,11 @@ class MIRSymbol { return false; } switch (storageClass) { - case kScFormal: case kScAuto: return true; case kScPstatic: case kScFstatic: - return value.konst == nullptr; + return value.konst == nullptr && !hasPotentialAssignment; default: return false; } @@ -638,7 +637,8 @@ class MIRLabelTable { LabelIdx CreateLabel() { LabelIdx labelIdx = labelTable.size(); - labelTable.push_back(GStrIdx(0)); // insert dummy global string index for anonymous label + GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(std::to_string(labelIdx)); + labelTable.push_back(strIdx); return labelIdx; } diff --git a/src/mapleall/maple_ir/include/mir_type.h b/src/mapleall/maple_ir/include/mir_type.h index c5245d568c..197e7d3ca2 100644 --- a/src/mapleall/maple_ir/include/mir_type.h +++ b/src/mapleall/maple_ir/include/mir_type.h @@ -1189,14 +1189,6 @@ class MIRStructType : public MIRType { isImported = flag; } - bool IsUsed() const { - return isUsed; - } - - void SetIsUsed(bool flag) { - isUsed = flag; - } - bool IsCPlusPlus() const { return isCPlusPlus; } @@ -1368,7 +1360,6 @@ class MIRStructType : public MIRType { vTableMethods.clear(); iTableMethods.clear(); isImported = false; - isUsed = false; hasVolatileField = false; hasVolatileFieldSet = false; } @@ -1471,7 +1462,6 @@ class MIRStructType : public MIRType { // implementation functions, For interfaces, they are abstact functions. // Weak indicates the actual definition is in another module. bool isImported = false; - bool isUsed = false; bool isCPlusPlus = false; // empty struct in C++ has size 1 byte mutable bool hasVolatileField = false; // for caching computed value mutable bool hasVolatileFieldSet = false; // if true, just read hasVolatileField; @@ -1928,11 +1918,19 @@ class MIRFuncType : public MIRType { } bool IsVarargs() const { - return isVarArgs; + return funcAttrs.GetAttr(FUNCATTR_varargs); } - void SetVarArgs(bool flag) { - isVarArgs = flag; + void SetVarArgs() { + funcAttrs.SetAttr(FUNCATTR_varargs); + } + + bool FirstArgReturn() const { + return funcAttrs.GetAttr(FUNCATTR_firstarg_return); + } + + void SetFirstArgReturn() { + funcAttrs.SetAttr(FUNCATTR_firstarg_return); } const TypeAttrs &GetRetAttrs() const { @@ -1960,7 +1958,8 @@ class MIRFuncType : public MIRType { std::vector paramTypeList; std::vector paramAttrsList; TypeAttrs retAttrs; - bool isVarArgs = false; + public: + FuncAttrs funcAttrs; }; class MIRTypeByName : public MIRType { diff --git a/src/mapleall/maple_ir/include/opcode_info.h b/src/mapleall/maple_ir/include/opcode_info.h index 814f15b2f2..5a82646b11 100644 --- a/src/mapleall/maple_ir/include/opcode_info.h +++ b/src/mapleall/maple_ir/include/opcode_info.h @@ -117,6 +117,7 @@ class OpcodeTable { bool IsICall(Opcode o) const { ASSERT(o < OP_last, "invalid opcode"); return o == OP_icall || o == OP_icallassigned || + o == OP_icallproto || o == OP_icallprotoassigned || o == OP_virtualicall || o == OP_virtualicallassigned || o == OP_interfaceicall || o == OP_interfaceicallassigned; } diff --git a/src/mapleall/maple_ir/include/opcodes.def b/src/mapleall/maple_ir/include/opcodes.def index 34cfb51c8d..0e842141ed 100755 --- a/src/mapleall/maple_ir/include/opcodes.def +++ b/src/mapleall/maple_ir/include/opcodes.def @@ -221,3 +221,4 @@ OPCODE(iassignspoff, IassignFPoffNode, OPCODEISSTMT, 8) OPCODE(blkassignoff, BlkassignoffNode, OPCODEISSTMT, 8) OPCODE(icallproto, IcallNode, (OPCODEISSTMT | OPCODEISVARSIZE | OPCODEHASSSAUSE | OPCODEHASSSADEF | OPCODEISCALL), 8) + OPCODE(icallprotoassigned, IcallNode, (OPCODEISSTMT | OPCODEISVARSIZE | OPCODEHASSSAUSE | OPCODEHASSSADEF | OPCODEISCALL | OPCODEISCALLASSIGNED), 8) diff --git a/src/mapleall/maple_ir/include/opcodes.h b/src/mapleall/maple_ir/include/opcodes.h index ea4ed2c1c9..b9f5e0f8c5 100644 --- a/src/mapleall/maple_ir/include/opcodes.h +++ b/src/mapleall/maple_ir/include/opcodes.h @@ -50,7 +50,7 @@ inline constexpr bool IsCallAssigned(Opcode code) { code == OP_virtualicallassigned || code == OP_superclasscallassigned || code == OP_interfacecallassigned || code == OP_interfaceicallassigned || code == OP_customcallassigned || code == OP_polymorphiccallassigned || - code == OP_icallassigned || code == OP_intrinsiccallassigned || + code == OP_icallassigned || code == OP_icallprotoassigned || code == OP_intrinsiccallassigned || code == OP_xintrinsiccallassigned || code == OP_intrinsiccallwithtypeassigned); } @@ -113,6 +113,8 @@ constexpr bool IsStmtMustRequire(Opcode opcode) { case OP_polymorphiccallassigned: case OP_icall: case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: case OP_intrinsiccall: case OP_xintrinsiccall: case OP_intrinsiccallassigned: diff --git a/src/mapleall/maple_ir/src/bin_func_export.cpp b/src/mapleall/maple_ir/src/bin_func_export.cpp index 263ef34c80..6815c8151d 100644 --- a/src/mapleall/maple_ir/src/bin_func_export.cpp +++ b/src/mapleall/maple_ir/src/bin_func_export.cpp @@ -24,6 +24,10 @@ using namespace std; namespace maple { void BinaryMplExport::OutputInfoVector(const MIRInfoVector &infoVector, const MapleVector &infoVectorIsString) { + if (!mod.IsWithDbgInfo()) { + Write(0); + return; + } WriteNum(infoVector.size()); for (uint32 i = 0; i < infoVector.size(); i++) { OutputStr(infoVector[i].first); @@ -41,99 +45,73 @@ void BinaryMplExport::OutputFuncIdInfo(MIRFunction *func) { WriteNum(func->GetPuidxOrigin()); // the funcid OutputInfoVector(func->GetInfoVector(), func->InfoIsString()); if (mod.GetFlavor() == kFlavorLmbc) { - WriteNum(func->GetUpFormalSize()); WriteNum(func->GetFrameSize()); - WriteNum(func->GetOutParmSize()); } - WriteNum(~kBinFuncIdInfoStart); } void BinaryMplExport::OutputBaseNode(const BaseNode *b) { - WriteNum(b->GetOpCode()); - WriteNum(b->GetPrimType()); + Write(static_cast(b->GetOpCode())); + Write(static_cast(b->GetPrimType())); } void BinaryMplExport::OutputLocalSymbol(MIRSymbol *sym) { - if (sym == nullptr) { - WriteNum(0); + std::unordered_map::iterator it = localSymMark.find(sym); + if (it != localSymMark.end()) { + WriteNum(-(it->second)); return; } + WriteNum(kBinSymbol); - WriteNum(sym->GetStIndex()); // preserve original st index OutputStr(sym->GetNameStrIdx()); WriteNum(sym->GetSKind()); WriteNum(sym->GetStorageClass()); + size_t mark = localSymMark.size(); + localSymMark[sym] = mark; OutputTypeAttrs(sym->GetAttrs()); WriteNum(static_cast(sym->GetIsTmp())); if (sym->GetSKind() == kStVar || sym->GetSKind() == kStFunc) { OutputSrcPos(sym->GetSrcPosition()); } - OutputTypeViaTypeName(sym->GetTyIdx()); + OutputType(sym->GetTyIdx()); if (sym->GetSKind() == kStPreg) { - WriteNum(sym->GetPreg()->GetPregNo()); + OutputPreg(sym->GetPreg()); } else if (sym->GetSKind() == kStConst || sym->GetSKind() == kStVar) { OutputConst(sym->GetKonst()); } else if (sym->GetSKind() == kStFunc) { - OutputFuncViaSymName(sym->GetFunction()->GetPuidx()); - OutputTypeViaTypeName(sym->GetTyIdx()); + OutputFuncViaSym(sym->GetFunction()->GetPuidx()); } else { CHECK_FATAL(false, "should not used"); } } -void BinaryMplExport::OutputLocalSymTab(const MIRFunction *func) { - WriteNum(kBinSymStart); - uint64 outsymSizeIdx = buf.size(); - ExpandFourBuffSize(); /// size of OutSym - int32 size = 0; - - for (uint32 i = 1; i < func->GetSymTab()->GetSymbolTableSize(); i++) { - MIRSymbol *s = func->GetSymTab()->GetSymbolFromStIdx(i); - ASSERT(s != nullptr, "null ptr check"); - if (s->IsDeleted()) { - OutputLocalSymbol(nullptr); - } else { - OutputLocalSymbol(s); - } - size++; +void BinaryMplExport::OutputPreg(MIRPreg *preg) { + if (preg->GetPregNo() < 0) { + WriteNum(kBinSpecialReg); + Write(-preg->GetPregNo()); + return; } - - Fixup(outsymSizeIdx, size); - WriteNum(~kBinSymStart); -} - -void BinaryMplExport::OutputPregTab(const MIRFunction *func) { - WriteNum(kBinPregStart); - uint64 outRegSizeIdx = buf.size(); - ExpandFourBuffSize(); /// size of OutReg - int32 size = 0; - - for (uint32 i = 1; i < func->GetPregTab()->Size(); ++i) { - MIRPreg *mirpreg = func->GetPregTab()->PregFromPregIdx(static_cast(i)); - if (mirpreg == nullptr) { - WriteNum(0); - size++; - continue; - } - WriteNum(kBinPreg); - WriteNum(mirpreg->GetPregNo()); - TyIdx tyIdx = (mirpreg->GetMIRType() == nullptr) ? TyIdx(0) : mirpreg->GetMIRType()->GetTypeIndex(); - OutputTypeViaTypeName(tyIdx); - WriteNum(mirpreg->GetPrimType()); - size++; + std::unordered_map::iterator it = localPregMark.find(preg); + if (it != localPregMark.end()) { + WriteNum(-(it->second)); + return; } - Fixup(outRegSizeIdx, size); - WriteNum(~kBinPregStart); + WriteNum(kBinPreg); + Write(static_cast(preg->GetPrimType())); + size_t mark = localPregMark.size(); + localPregMark[preg] = mark; } -void BinaryMplExport::OutputLabelTab(const MIRFunction *func) { - WriteNum(kBinLabelStart); - WriteNum(static_cast(func->GetLabelTab()->Size()-1)); // entry 0 is skipped - for (uint32 i = 1; i < func->GetLabelTab()->Size(); i++) { - OutputStr(func->GetLabelTab()->GetLabelTable()[i]); +void BinaryMplExport::OutputLabel(LabelIdx lidx) { + std::unordered_map::iterator it = labelMark.find(lidx); + if (it != labelMark.end()) { + WriteNum(-(it->second)); + return; } - WriteNum(~kBinLabelStart); + + WriteNum(kBinLabel); + size_t mark = labelMark.size(); + labelMark[lidx] = mark; } void BinaryMplExport::OutputLocalTypeNameTab(const MIRTypeNameTable *typeNameTab) { @@ -141,18 +119,16 @@ void BinaryMplExport::OutputLocalTypeNameTab(const MIRTypeNameTable *typeNameTab WriteNum(static_cast(typeNameTab->Size())); for (std::pair it : typeNameTab->GetGStrIdxToTyIdxMap()) { OutputStr(it.first); - OutputTypeViaTypeName(it.second); + OutputType(it.second); } - WriteNum(~kBinTypenameStart); } void BinaryMplExport::OutputFormalsStIdx(MIRFunction *func) { WriteNum(kBinFormalStart); WriteNum(func->GetFormalDefVec().size()); for (FormalDef formalDef : func->GetFormalDefVec()) { - WriteNum(formalDef.formalSym->GetStIndex()); + OutputLocalSymbol(formalDef.formalSym); } - WriteNum(~kBinFormalStart); } void BinaryMplExport::OutputAliasMap(MapleMap &aliasVarMap) { @@ -161,21 +137,18 @@ void BinaryMplExport::OutputAliasMap(MapleMap &aliasVarMa for (std::pair it : aliasVarMap) { OutputStr(it.first); OutputStr(it.second.memPoolStrIdx); - OutputTypeViaTypeName(it.second.tyIdx); + OutputType(it.second.tyIdx); OutputStr(it.second.sigStrIdx); } - WriteNum(~kBinAliasMapStart); } -void BinaryMplExport::OutputFuncViaSymName(PUIdx puIdx) { +void BinaryMplExport::OutputFuncViaSym(PUIdx puIdx) { MIRFunction *func = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx()); - WriteNum(kBinKindFuncViaSymname); - OutputStr(funcSt->GetNameStrIdx()); + OutputSymbol(funcSt); } void BinaryMplExport::OutputExpression(BaseNode *e) { - WriteNum(kBinOpExpression); OutputBaseNode(e); switch (e->GetOpCode()) { // leaf @@ -191,17 +164,17 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { } case OP_addroflabel: { AddroflabelNode *lNode = static_cast(e); - WriteNum(lNode->GetOffset()); + OutputLabel(lNode->GetOffset()); return; } case OP_addroffunc: { AddroffuncNode *addrNode = static_cast(e); - OutputFuncViaSymName(addrNode->GetPUIdx()); + OutputFuncViaSym(addrNode->GetPUIdx()); return; } case OP_sizeoftype: { SizeoftypeNode *sot = static_cast(e); - OutputTypeViaTypeName(sot->GetTyIdx()); + OutputType(sot->GetTyIdx()); return; } case OP_addrof: @@ -220,24 +193,23 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { } WriteNum(stIdx.Scope()); if (stIdx.Islocal()) { - WriteNum(stIdx.Idx()); // preserve original st index + OutputLocalSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx)); } else { - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(stIdx.Idx()); - WriteNum(kBinKindSymViaSymname); - OutputStr(sym->GetNameStrIdx()); + OutputSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx)); } return; } case OP_regread: { RegreadNode *regreadNode = static_cast(e); - WriteNum(regreadNode->GetRegIdx()); + MIRPreg *preg = curFunc->GetPregTab()->PregFromPregIdx(regreadNode->GetRegIdx()); + OutputPreg(preg); return; } case OP_gcmalloc: case OP_gcpermalloc: case OP_stackmalloc: { GCMallocNode *gcNode = static_cast(e); - OutputTypeViaTypeName(gcNode->GetTyIdx()); + OutputType(gcNode->GetTyIdx()); return; } // unary @@ -246,18 +218,18 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { case OP_floor: case OP_trunc: { TypeCvtNode *typecvtNode = static_cast(e); - WriteNum(typecvtNode->FromType()); + Write(static_cast(typecvtNode->FromType())); break; } case OP_retype: { RetypeNode *retypeNode = static_cast(e); - OutputTypeViaTypeName(retypeNode->GetTyIdx()); + OutputType(retypeNode->GetTyIdx()); break; } case OP_iread: case OP_iaddrof: { IreadNode *irNode = static_cast(e); - OutputTypeViaTypeName(irNode->GetTyIdx()); + OutputType(irNode->GetTyIdx()); WriteNum(irNode->GetFieldID()); break; } @@ -275,20 +247,20 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { case OP_zext: case OP_extractbits: { ExtractbitsNode *extNode = static_cast(e); - WriteNum(extNode->GetBitsOffset()); - WriteNum(extNode->GetBitsSize()); + Write(extNode->GetBitsOffset()); + Write(extNode->GetBitsSize()); break; } case OP_depositbits: { DepositbitsNode *dbNode = static_cast(e); - WriteNum(dbNode->GetBitsOffset()); - WriteNum(dbNode->GetBitsSize()); + Write(dbNode->GetBitsOffset()); + Write(dbNode->GetBitsSize()); break; } case OP_gcmallocjarray: case OP_gcpermallocjarray: { JarrayMallocNode *gcNode = static_cast(e); - OutputTypeViaTypeName(gcNode->GetTyIdx()); + OutputType(gcNode->GetTyIdx()); break; } // binary @@ -321,13 +293,13 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { case OP_cmpl: case OP_cmp: { CompareNode *cmpNode = static_cast(e); - WriteNum(cmpNode->GetOpndType()); + Write(static_cast(cmpNode->GetOpndType())); break; } case OP_resolveinterfacefunc: case OP_resolvevirtualfunc: { ResolveFuncNode *rsNode = static_cast(e); - OutputFuncViaSymName(rsNode->GetPuIdx()); + OutputFuncViaSym(rsNode->GetPuIdx()); break; } // ternary @@ -337,8 +309,8 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { // nary case OP_array: { ArrayNode *arrNode = static_cast(e); - OutputTypeViaTypeName(arrNode->GetTyIdx()); - WriteNum(static_cast(arrNode->GetBoundsCheck())); + OutputType(arrNode->GetTyIdx()); + Write(static_cast(arrNode->GetBoundsCheck())); WriteNum(static_cast(arrNode->NumOpnds())); break; } @@ -351,7 +323,7 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { case OP_intrinsicopwithtype: { IntrinsicopNode *intrnNode = static_cast(e); WriteNum(intrnNode->GetIntrinsic()); - OutputTypeViaTypeName(intrnNode->GetTyIdx()); + OutputType(intrnNode->GetTyIdx()); WriteNum(static_cast(intrnNode->NumOpnds())); break; } @@ -366,6 +338,9 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { static SrcPosition lastOutputSrcPosition; void BinaryMplExport::OutputSrcPos(const SrcPosition &pos) { + if (!mod.IsWithDbgInfo()) { + return; + } if (pos.FileNum() == 0 || pos.LineNum() == 0) { // error case, so output 0 WriteNum(lastOutputSrcPosition.RawData()); WriteNum(lastOutputSrcPosition.LineNum()); @@ -380,9 +355,15 @@ void BinaryMplExport::OutputReturnValues(const CallReturnVector *retv) { WriteNum(kBinReturnvals); WriteNum(static_cast(retv->size())); for (uint32 i = 0; i < retv->size(); i++) { - WriteNum((*retv)[i].first.Idx()); - WriteNum((*retv)[i].second.GetFieldID()); - WriteNum((*retv)[i].second.GetPregIdx()); + RegFieldPair rfp = (*retv)[i].second; + if (rfp.IsReg()) { + MIRPreg *preg = curFunc->GetPregTab()->PregFromPregIdx(rfp.GetPregIdx()); + OutputPreg(preg); + } else { + WriteNum(0); + WriteNum((rfp.GetFieldID())); + OutputLocalSymbol(curFunc->GetLocalOrGlobalSymbol((*retv)[i].first)); + } } } @@ -398,7 +379,6 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { ExpandFourBuffSize(); // place holder, Fixup later for (StmtNode *s = block->GetFirst(); s; s = s->GetNext()) { bool doneWithOpnds = false; - WriteNum(kBinOpStatement); OutputSrcPos(s->GetSrcPos()); WriteNum(s->GetOpCode()); switch (s->GetOpCode()) { @@ -417,36 +397,35 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { } WriteNum(stIdx.Scope()); if (stIdx.Islocal()) { - WriteNum(stIdx.Idx()); // preserve original st index + OutputLocalSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx)); } else { - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(stIdx.Idx()); - WriteNum(kBinKindSymViaSymname); - OutputStr(sym->GetNameStrIdx()); + OutputSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx)); } break; } case OP_regassign: { RegassignNode *rass = static_cast(s); - WriteNum(rass->GetPrimType()); - WriteNum(rass->GetRegIdx()); + Write(static_cast(rass->GetPrimType())); + MIRPreg *preg = curFunc->GetPregTab()->PregFromPregIdx(rass->GetRegIdx()); + OutputPreg(preg); break; } case OP_iassign: { IassignNode *iass = static_cast(s); - OutputTypeViaTypeName(iass->GetTyIdx()); + OutputType(iass->GetTyIdx()); WriteNum(iass->GetFieldID()); break; } case OP_iassignoff: { IassignoffNode *iassoff = static_cast(s); - WriteNum(iassoff->GetPrimType()); + Write(static_cast(iassoff->GetPrimType())); WriteNum(iassoff->GetOffset()); break; } case OP_iassignspoff: case OP_iassignfpoff: { IassignFPoffNode *iassfpoff = static_cast(s); - WriteNum(iassfpoff->GetPrimType()); + Write(static_cast(iassfpoff->GetPrimType())); WriteNum(iassfpoff->GetOffset()); break; } @@ -466,9 +445,9 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { case OP_customcall: case OP_polymorphiccall: { CallNode *callnode = static_cast(s); - OutputFuncViaSymName(callnode->GetPUIdx()); + OutputFuncViaSym(callnode->GetPUIdx()); if (s->GetOpCode() == OP_polymorphiccall) { - OutputTypeViaTypeName(static_cast(callnode)->GetTyIdx()); + OutputType(static_cast(callnode)->GetTyIdx()); } WriteNum(static_cast(s->NumOpnds())); break; @@ -481,15 +460,15 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { case OP_interfaceicallassigned: case OP_customcallassigned: { CallNode *callnode = static_cast(s); - OutputFuncViaSymName(callnode->GetPUIdx()); + OutputFuncViaSym(callnode->GetPUIdx()); OutputReturnValues(&callnode->GetReturnVec()); WriteNum(static_cast(s->NumOpnds())); break; } case OP_polymorphiccallassigned: { CallNode *callnode = static_cast(s); - OutputFuncViaSymName(callnode->GetPUIdx()); - OutputTypeViaTypeName(callnode->GetTyIdx()); + OutputFuncViaSym(callnode->GetPUIdx()); + OutputType(callnode->GetTyIdx()); OutputReturnValues(&callnode->GetReturnVec()); WriteNum(static_cast(s->NumOpnds())); break; @@ -497,13 +476,14 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { case OP_icallproto: case OP_icall: { IcallNode *icallnode = static_cast(s); - OutputTypeViaTypeName(icallnode->GetRetTyIdx()); + OutputType(icallnode->GetRetTyIdx()); WriteNum(static_cast(s->NumOpnds())); break; } + case OP_icallprotoassigned: case OP_icallassigned: { IcallNode *icallnode = static_cast(s); - OutputTypeViaTypeName(icallnode->GetRetTyIdx()); + OutputType(icallnode->GetRetTyIdx()); OutputReturnValues(&icallnode->GetReturnVec()); WriteNum(static_cast(s->NumOpnds())); break; @@ -526,14 +506,14 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { case OP_intrinsiccallwithtype: { IntrinsiccallNode *intrnNode = static_cast(s); WriteNum(intrnNode->GetIntrinsic()); - OutputTypeViaTypeName(intrnNode->GetTyIdx()); + OutputType(intrnNode->GetTyIdx()); WriteNum(static_cast(s->NumOpnds())); break; } case OP_intrinsiccallwithtypeassigned: { IntrinsiccallNode *intrnNode = static_cast(s); WriteNum(intrnNode->GetIntrinsic()); - OutputTypeViaTypeName(intrnNode->GetTyIdx()); + OutputType(intrnNode->GetTyIdx()); OutputReturnValues(&intrnNode->GetReturnVec()); WriteNum(static_cast(s->NumOpnds())); break; @@ -568,28 +548,28 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { } case OP_label: { LabelNode *lNode = static_cast(s); - WriteNum(lNode->GetLabelIdx()); + OutputLabel(lNode->GetLabelIdx()); break; } case OP_goto: case OP_gosub: { GotoNode *gtoNode = static_cast(s); - WriteNum(gtoNode->GetOffset()); + OutputLabel(gtoNode->GetOffset()); break; } case OP_brfalse: case OP_brtrue: { CondGotoNode *cgotoNode = static_cast(s); - WriteNum(cgotoNode->GetOffset()); + OutputLabel(cgotoNode->GetOffset()); break; } case OP_switch: { SwitchNode *swNode = static_cast(s); - WriteNum(swNode->GetDefaultLabel()); + OutputLabel(swNode->GetDefaultLabel()); WriteNum(static_cast(swNode->GetSwitchTable().size())); for (CasePair cpair : swNode->GetSwitchTable()) { WriteNum(cpair.first); - WriteNum(cpair.second); + OutputLabel(cpair.second); } break; } @@ -599,14 +579,14 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { WriteNum(static_cast(rgoto->GetRangeGotoTable().size())); for (SmallCasePair cpair : rgoto->GetRangeGotoTable()) { WriteNum(cpair.first); - WriteNum(cpair.second); + OutputLabel(cpair.second); } break; } case OP_jstry: { JsTryNode *tryNode = static_cast(s); - WriteNum(tryNode->GetCatchOffset()); - WriteNum(tryNode->GetFinallyOffset()); + OutputLabel(tryNode->GetCatchOffset()); + OutputLabel(tryNode->GetFinallyOffset()); break; } case OP_cpptry: @@ -614,7 +594,7 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { TryNode *tryNode = static_cast(s); WriteNum(static_cast(tryNode->GetOffsetsCount())); for (LabelIdx lidx : tryNode->GetOffsets()) { - WriteNum(lidx); + OutputLabel(lidx); } break; } @@ -622,7 +602,7 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { CatchNode *catchNode = static_cast(s); WriteNum(static_cast(catchNode->GetExceptionTyIdxVec().size())); for (TyIdx tidx : catchNode->GetExceptionTyIdxVec()) { - OutputTypeViaTypeName(tidx); + OutputType(tidx); } break; } @@ -679,7 +659,7 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { count = asmNode->gotoLabels.size(); WriteNum(static_cast(count)); for (size_t i = 0; i < count; ++i) { - WriteNum(asmNode->gotoLabels[i]); + OutputLabel(asmNode->gotoLabels[i]); } // the inputs WriteNum(asmNode->NumOpnds()); @@ -714,6 +694,7 @@ void BinaryMplExport::WriteFunctionBodyField(uint64 contentIdx, std::unordered_s if (not2mplt) { for (MIRFunction *func : GetMIRModule().GetFunctionList()) { + curFunc = func; if (func->GetAttr(FUNCATTR_optimized)) { continue; } @@ -734,12 +715,15 @@ void BinaryMplExport::WriteFunctionBodyField(uint64 contentIdx, std::unordered_s continue; } } + localSymMark.clear(); + localSymMark[nullptr] = 0; + localPregMark.clear(); + localPregMark[nullptr] = 0; + labelMark.clear(); + labelMark[0] = 0; OutputFunction(func->GetPuidx()); CHECK_FATAL(func->GetBody() != nullptr, "WriteFunctionBodyField: no function body"); OutputFuncIdInfo(func); - OutputPregTab(func); - OutputLocalSymTab(func); - OutputLabelTab(func); OutputLocalTypeNameTab(func->GetTypeNameTab()); OutputFormalsStIdx(func); if (mod.GetFlavor() < kMmpl) { @@ -753,7 +737,6 @@ void BinaryMplExport::WriteFunctionBodyField(uint64 contentIdx, std::unordered_s Fixup(totalSizeIdx, static_cast(buf.size() - totalSizeIdx)); Fixup(outFunctionBodySizeIdx, size); - WriteNum(~kBinFunctionBodyStart); return; } } // namespace maple diff --git a/src/mapleall/maple_ir/src/bin_func_import.cpp b/src/mapleall/maple_ir/src/bin_func_import.cpp index 959784554b..b23b6895f4 100644 --- a/src/mapleall/maple_ir/src/bin_func_import.cpp +++ b/src/mapleall/maple_ir/src/bin_func_import.cpp @@ -44,29 +44,27 @@ void BinaryMplImport::ImportFuncIdInfo(MIRFunction *func) { func->SetPuidxOrigin(static_cast(ReadNum())); ImportInfoVector(func->GetInfoVector(), func->InfoIsString()); if (mod.GetFlavor() == kFlavorLmbc) { - func->SetUpFormalSize(static_cast(ReadNum())); func->SetFrameSize(static_cast(ReadNum())); - func->SetOutParmSize(static_cast(ReadNum())); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinFuncIdInfoStart, "pattern mismatch in ImportFuncIdInfo()"); } void BinaryMplImport::ImportBaseNode(Opcode &o, PrimType &typ) { - o = (Opcode)ReadNum(); - typ = (PrimType)ReadNum(); + o = (Opcode)Read(); + typ = (PrimType)Read(); } -void BinaryMplImport::ImportLocalSymbol(MIRFunction *func) { +MIRSymbol *BinaryMplImport::ImportLocalSymbol(MIRFunction *func) { int64 tag = ReadNum(); if (tag == 0) { - func->GetSymTab()->PushNullSymbol(); - return; + return nullptr; } + if (tag < 0) { + CHECK_FATAL(static_cast(-tag) < localSymTab.size(), "index out of bounds"); + return localSymTab.at(-tag); + } CHECK_FATAL(tag == kBinSymbol, "expecting kBinSymbol in ImportLocalSymbol()"); - auto indx = static_cast(ReadNum()); - CHECK_FATAL(indx == func->GetSymTab()->GetSymbolTableSize(), "inconsistant local stIdx"); MIRSymbol *sym = func->GetSymTab()->CreateSymbol(kScopeLocal); + localSymTab.push_back(sym); sym->SetNameStrIdx(ImportStr()); (void)func->GetSymTab()->AddToStringSymbolMap(*sym); sym->SetSKind((MIRSymKind)ReadNum()); @@ -78,66 +76,52 @@ void BinaryMplImport::ImportLocalSymbol(MIRFunction *func) { } sym->SetTyIdx(ImportType()); if (sym->GetSKind() == kStPreg) { - auto thepregno = static_cast(ReadNum()); - MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx()); - PregIdx pregidx = func->GetPregTab()->EnterPregNo(thepregno, mirType->GetPrimType(), mirType); - MIRPregTable *pregTab = func->GetPregTab(); - MIRPreg *preg = pregTab->PregFromPregIdx(pregidx); - preg->SetPrimType(mirType->GetPrimType()); + PregIdx pregidx = ImportPreg(func); + MIRPreg *preg = func->GetPregTab()->PregFromPregIdx(pregidx); sym->SetPreg(preg); } else if (sym->GetSKind() == kStConst || sym->GetSKind() == kStVar) { sym->SetKonst(ImportConst(func)); } else if (sym->GetSKind() == kStFunc) { - PUIdx puIdx = ImportFuncViaSymName(); - TyIdx tyIdx = ImportType(); - sym->SetTyIdx(tyIdx); + PUIdx puIdx = ImportFuncViaSym(func); sym->SetFunction(GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx)); } + return sym; } -void BinaryMplImport::ImportLocalSymTab(MIRFunction *func) { +PregIdx BinaryMplImport::ImportPreg(MIRFunction *func) { int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinSymStart, "kBinSymStart expected in ImportLocalSymTab()"); - int32 size = ReadInt(); - for (int64 i = 0; i < size; ++i) { - ImportLocalSymbol(func); + if (tag == 0) { + return 0; } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinSymStart, "pattern mismatch in ImportLocalSymTab()"); -} - -void BinaryMplImport::ImportPregTab(const MIRFunction *func) { - int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinPregStart, "kBinPregStart expected in ImportPregTab()"); - int32 size = ReadInt(); - for (int64 i = 0; i < size; ++i) { - int64 nextTag = ReadNum(); - if (nextTag == 0) { - func->GetPregTab()->GetPregTable().push_back(nullptr); - continue; - } - CHECK_FATAL(nextTag == kBinPreg, "expecting kBinPreg in ImportPregTab()"); - auto pregNo = static_cast(ReadNum()); - TyIdx tyIdx = ImportType(); - MIRType *ty = (tyIdx == 0) ? nullptr : GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); - PrimType primType = (PrimType)ReadNum(); - CHECK_FATAL(ty == nullptr || primType == ty->GetPrimType(), "ImportPregTab: inconsistent primitive type"); - (void)func->GetPregTab()->EnterPregNo(pregNo, primType, ty); + if (tag == kBinSpecialReg) { + return -Read(); + } + if (tag < 0) { + CHECK_FATAL(static_cast(-tag) < localPregTab.size(), "index out of bounds"); + return localPregTab.at(-tag); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinPregStart, "pattern mismatch in ImportPregTab()"); + CHECK_FATAL(tag == kBinPreg, "expecting kBinPreg in ImportPreg()"); + + PrimType primType = (PrimType)Read(); + PregIdx pidx = func->GetPregTab()->CreatePreg(primType); + localPregTab.push_back(pidx); + return pidx; } -void BinaryMplImport::ImportLabelTab(MIRFunction *func) { +LabelIdx BinaryMplImport::ImportLabel(MIRFunction *func) { int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinLabelStart, "kBinLabelStart expected in ImportLabelTab()"); - int64 size = ReadNum(); - for (int64 i = 0; i < size; ++i) { - GStrIdx gStrIdx = ImportStr(); - (void)func->GetLabelTab()->AddLabel(gStrIdx); + if (tag == 0) { + return 0; + } + if (tag < 0) { + CHECK_FATAL(static_cast(-tag) < localLabelTab.size(), "index out of bounds"); + return localLabelTab.at(-tag); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinLabelStart, "pattern mismatch in ImportLabelTab()"); + CHECK_FATAL(tag == kBinLabel, "kBinLabel expected in ImportLabel()"); + + LabelIdx lidx = func->GetLabelTab()->CreateLabel(); + localLabelTab.push_back(lidx); + return lidx; } void BinaryMplImport::ImportLocalTypeNameTable(MIRTypeNameTable *typeNameTab) { @@ -149,8 +133,6 @@ void BinaryMplImport::ImportLocalTypeNameTable(MIRTypeNameTable *typeNameTab) { TyIdx tyIdx = ImportType(); typeNameTab->SetGStrIdxToTyIdx(strIdx, tyIdx); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinTypenameStart, "pattern mismatch in ImportTypenametab()"); } void BinaryMplImport::ImportFormalsStIdx(MIRFunction *func) { @@ -158,11 +140,8 @@ void BinaryMplImport::ImportFormalsStIdx(MIRFunction *func) { CHECK_FATAL(tag == kBinFormalStart, "kBinFormalStart expected in ImportFormalsStIdx()"); auto size = ReadNum(); for (int64 i = 0; i < size; ++i) { - uint32 indx = static_cast(ReadNum()); - func->GetFormalDefVec()[static_cast(i)].formalSym = func->GetSymTab()->GetSymbolFromStIdx(indx); + func->GetFormalDefVec()[static_cast(i)].formalSym = ImportLocalSymbol(func); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinFormalStart, "pattern mismatch in ImportFormalsStIdx()"); } void BinaryMplImport::ImportAliasMap(MIRFunction *func) { @@ -177,23 +156,15 @@ void BinaryMplImport::ImportAliasMap(MIRFunction *func) { (void)ImportStr(); // not assigning to mimic parser func->GetAliasVarMap()[strIdx] = aliasvars; } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinAliasMapStart, "pattern mismatch in ImportAliasMap()"); } -PUIdx BinaryMplImport::ImportFuncViaSymName() { - int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinKindFuncViaSymname, "kBinKindFuncViaSymname expected"); - GStrIdx strIdx = ImportStr(); - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx); - ASSERT(sym != nullptr, "null ptr check"); - MIRFunction *func = sym->GetFunction(); - return func->GetPuidx(); +PUIdx BinaryMplImport::ImportFuncViaSym(MIRFunction *func) { + MIRSymbol *sym = InSymbol(func); + MIRFunction *f = sym->GetFunction(); + return f->GetPuidx(); } BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { - int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinOpExpression, "kBinOpExpression expected"); Opcode op; PrimType typ; ImportBaseNode(op, typ); @@ -213,13 +184,15 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { } case OP_addroflabel: { AddroflabelNode *alabNode = mod.CurFuncCodeMemPool()->New(); - alabNode->SetOffset(static_cast(ReadNum())); + alabNode->SetOffset(ImportLabel(func)); alabNode->SetPrimType(typ); (void)func->GetLabelTab()->addrTakenLabels.insert(alabNode->GetOffset()); return alabNode; } case OP_addroffunc: { - PUIdx puIdx = ImportFuncViaSymName(); + PUIdx puIdx = ImportFuncViaSym(func); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFuncTable()[puIdx]; + f->GetFuncSymbol()->SetAppearsInCode(true); AddroffuncNode *addrNode = mod.CurFuncCodeMemPool()->New(typ, puIdx); return addrNode; } @@ -235,19 +208,18 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { int32 num = static_cast(ReadNum()); StIdx stIdx; stIdx.SetScope(static_cast(ReadNum())); + MIRSymbol *sym = nullptr; if (stIdx.Islocal()) { - stIdx.SetIdx(static_cast(ReadNum())); + sym = ImportLocalSymbol(func); + CHECK_FATAL(sym != nullptr, "null ptr check"); } else { - int32 stag = static_cast(ReadNum()); - CHECK_FATAL(stag == kBinKindSymViaSymname, "kBinKindSymViaSymname expected"); - GStrIdx strIdx = ImportStr(); - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx); - ASSERT(sym != nullptr, "null ptr check"); + sym = InSymbol(func); + CHECK_FATAL(sym != nullptr, "null ptr check"); if (op == OP_addrof) { sym->SetHasPotentialAssignment(); } - stIdx.SetIdx(sym->GetStIdx().Idx()); } + stIdx.SetIdx(sym->GetStIdx().Idx()); if (op == OP_addrof || op == OP_dread) { AddrofNode *drNode = mod.CurFuncCodeMemPool()->New(op); drNode->SetPrimType(typ); @@ -264,7 +236,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { } case OP_regread: { RegreadNode *regreadNode = mod.CurFuncCodeMemPool()->New(); - regreadNode->SetRegIdx(static_cast(ReadNum())); + regreadNode->SetRegIdx(ImportPreg(func)); regreadNode->SetPrimType(typ); return regreadNode; } @@ -293,7 +265,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_floor: case OP_trunc: { TypeCvtNode *typecvtNode = mod.CurFuncCodeMemPool()->New(op, typ); - typecvtNode->SetFromType((PrimType)ReadNum()); + typecvtNode->SetFromType((PrimType)Read()); typecvtNode->SetOpnd(ImportExpression(func), 0); return typecvtNode; } @@ -326,15 +298,15 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_zext: case OP_extractbits: { ExtractbitsNode *extNode = mod.CurFuncCodeMemPool()->New(op, typ); - extNode->SetBitsOffset(static_cast(ReadNum())); - extNode->SetBitsSize(static_cast(ReadNum())); + extNode->SetBitsOffset(Read()); + extNode->SetBitsSize(Read()); extNode->SetOpnd(ImportExpression(func), 0); return extNode; } case OP_depositbits: { DepositbitsNode *dbNode = mod.CurFuncCodeMemPool()->New(op, typ); - dbNode->SetBitsOffset(static_cast(ReadNum())); - dbNode->SetBitsSize(static_cast(ReadNum())); + dbNode->SetBitsOffset(ReadNum()); + dbNode->SetBitsSize(ReadNum()); dbNode->SetOpnd(ImportExpression(func), 0); dbNode->SetOpnd(ImportExpression(func), 1); return dbNode; @@ -379,7 +351,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_cmpl: case OP_cmp: { CompareNode *cmpNode = mod.CurFuncCodeMemPool()->New(op, typ); - cmpNode->SetOpndType((PrimType)ReadNum()); + cmpNode->SetOpndType((PrimType)Read()); cmpNode->SetOpnd(ImportExpression(func), 0); cmpNode->SetOpnd(ImportExpression(func), 1); return cmpNode; @@ -387,7 +359,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_resolveinterfacefunc: case OP_resolvevirtualfunc: { ResolveFuncNode *rsNode = mod.CurFuncCodeMemPool()->New(op, typ); - rsNode->SetPUIdx(ImportFuncViaSymName()); + rsNode->SetPUIdx(ImportFuncViaSym(func)); rsNode->SetOpnd(ImportExpression(func), 0); rsNode->SetOpnd(ImportExpression(func), 1); return rsNode; @@ -403,7 +375,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { // nary case OP_array: { TyIdx tidx = ImportType(); - auto boundsCheck = static_cast(ReadNum()); + bool boundsCheck = static_cast(Read()); ArrayNode *arrNode = mod.CurFuncCodeMemPool()->New(func->GetCodeMPAllocator(), typ, tidx, boundsCheck); auto n = static_cast(ReadNum()); @@ -436,12 +408,15 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { return intrnNode; } default: - CHECK_FATAL(false, "Unhandled op %d", tag); + CHECK_FATAL(false, "Unhandled op %d", op); break; } } void BinaryMplImport::ImportSrcPos(SrcPosition &pos) { + if (!mod.IsWithDbgInfo()) { + return; + } pos.SetRawData(static_cast(ReadNum())); pos.SetLineNum(static_cast(ReadNum())); } @@ -451,15 +426,16 @@ void BinaryMplImport::ImportReturnValues(MIRFunction *func, CallReturnVector *re CHECK_FATAL(tag == kBinReturnvals, "expecting return values"); auto size = static_cast(ReadNum()); for (uint32 i = 0; i < size; ++i) { - uint32 idx = static_cast(ReadNum()); - FieldID fid = static_cast(ReadNum()); - PregIdx ridx = static_cast(ReadNum()); - retv->push_back(std::make_pair(StIdx(kScopeLocal, idx), RegFieldPair(fid, ridx))); - if (idx == 0) { + RegFieldPair rfp; + rfp.SetPregIdx(ImportPreg(func)); + if (rfp.IsReg()) { + retv->push_back(std::make_pair(StIdx(), rfp)); continue; } - MIRSymbol *lsym = func->GetSymTab()->GetSymbolFromStIdx(idx, false); - ASSERT(lsym != nullptr, "null ptr check"); + rfp.SetFieldID(static_cast(ReadNum())); + MIRSymbol *lsym = ImportLocalSymbol(func); + CHECK_FATAL(lsym != nullptr, "null ptr check"); + retv->push_back(std::make_pair(lsym->GetStIdx(), rfp)); if (lsym->GetName().find("L_STR") == 0) { MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(lsym->GetTyIdx()); CHECK_FATAL(ty->GetKind() == kTypePointer, "Pointer type expected for L_STR prefix"); @@ -480,8 +456,6 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { ImportSrcPos(block->GetSrcPos()); int32 size = ReadInt(); for (int32 k = 0; k < size; ++k) { - tag = ReadNum(); - CHECK_FATAL(tag == kBinOpStatement, "kBinOpStatement expected"); SrcPosition thesrcPosition; ImportSrcPos(thesrcPosition); op = (Opcode)ReadNum(); @@ -496,17 +470,16 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { int32 num = static_cast(ReadNum()); StIdx stIdx; stIdx.SetScope(static_cast(ReadNum())); + MIRSymbol *sym = nullptr; if (stIdx.Islocal()) { - stIdx.SetIdx(static_cast(ReadNum())); + sym = ImportLocalSymbol(func); + CHECK_FATAL(sym != nullptr, "null ptr check"); } else { - int32 stag = static_cast(ReadNum()); - CHECK_FATAL(stag == kBinKindSymViaSymname, "kBinKindSymViaSymname expected"); - GStrIdx strIdx = ImportStr(); - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx); - ASSERT(sym != nullptr, "null ptr check"); + sym = InSymbol(func); + CHECK_FATAL(sym != nullptr, "null ptr check"); sym->SetHasPotentialAssignment(); - stIdx.SetIdx(sym->GetStIdx().Idx()); } + stIdx.SetIdx(sym->GetStIdx().Idx()); if (op == OP_dassign) { DassignNode *s = func->GetCodeMemPool()->New(); s->SetStIdx(stIdx); @@ -525,8 +498,8 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_regassign: { RegassignNode *s = func->GetCodeMemPool()->New(); - s->SetPrimType((PrimType)ReadNum()); - s->SetRegIdx(static_cast(ReadNum())); + s->SetPrimType((PrimType)Read()); + s->SetRegIdx(ImportPreg(func)); s->SetOpnd(ImportExpression(func), 0); stmt = s; break; @@ -542,7 +515,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_iassignoff: { IassignoffNode *s = func->GetCodeMemPool()->New(); - s->SetPrimType((PrimType)ReadNum()); + s->SetPrimType((PrimType)Read()); s->SetOffset(static_cast(ReadNum())); s->SetOpnd(ImportExpression(func), 0); s->SetOpnd(ImportExpression(func), 1); @@ -552,7 +525,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { case OP_iassignspoff: case OP_iassignfpoff: { IassignFPoffNode *s = func->GetCodeMemPool()->New(op); - s->SetPrimType((PrimType)ReadNum()); + s->SetPrimType((PrimType)Read()); s->SetOffset(static_cast(ReadNum())); s->SetOpnd(ImportExpression(func), 0); stmt = s; @@ -577,7 +550,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { case OP_interfaceicall: case OP_customcall: { CallNode *s = func->GetCodeMemPool()->New(mod, op); - s->SetPUIdx(ImportFuncViaSymName()); + s->SetPUIdx(ImportFuncViaSym(func)); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx()); + f->GetFuncSymbol()->SetAppearsInCode(true); numOpr = static_cast(ReadNum()); s->SetNumOpnds(numOpr); for (int32 i = 0; i < numOpr; ++i) { @@ -594,7 +569,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { case OP_interfaceicallassigned: case OP_customcallassigned: { CallNode *s = func->GetCodeMemPool()->New(mod, op); - s->SetPUIdx(ImportFuncViaSymName()); + s->SetPUIdx(ImportFuncViaSym(func)); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx()); + f->GetFuncSymbol()->SetAppearsInCode(true); ImportReturnValues(func, &s->GetReturnVec()); numOpr = static_cast(ReadNum()); s->SetNumOpnds(numOpr); @@ -610,7 +587,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_polymorphiccall: { CallNode *s = func->GetCodeMemPool()->New(mod, op); - s->SetPUIdx(ImportFuncViaSymName()); + s->SetPUIdx(ImportFuncViaSym(func)); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx()); + f->GetFuncSymbol()->SetAppearsInCode(true); s->SetTyIdx(ImportType()); numOpr = static_cast(ReadNum()); s->SetNumOpnds(numOpr); @@ -622,7 +601,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_polymorphiccallassigned: { CallNode *s = func->GetCodeMemPool()->New(mod, op); - s->SetPUIdx(ImportFuncViaSymName()); + s->SetPUIdx(ImportFuncViaSym(func)); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx()); + f->GetFuncSymbol()->SetAppearsInCode(true); s->SetTyIdx(ImportType()); ImportReturnValues(func, &s->GetReturnVec()); numOpr = static_cast(ReadNum()); @@ -645,6 +626,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { stmt = s; break; } + case OP_icallprotoassigned: case OP_icallassigned: { IcallNode *s = func->GetCodeMemPool()->New(mod, op); s->SetRetTyIdx(ImportType()); @@ -759,32 +741,32 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_label: { LabelNode *s = mod.CurFuncCodeMemPool()->New(); - s->SetLabelIdx(static_cast(ReadNum())); + s->SetLabelIdx(ImportLabel(func)); stmt = s; break; } case OP_goto: case OP_gosub: { GotoNode *s = mod.CurFuncCodeMemPool()->New(op); - s->SetOffset(static_cast(ReadNum())); + s->SetOffset(ImportLabel(func)); stmt = s; break; } case OP_brfalse: case OP_brtrue: { CondGotoNode *s = mod.CurFuncCodeMemPool()->New(op); - s->SetOffset(static_cast(ReadNum())); + s->SetOffset(ImportLabel(func)); s->SetOpnd(ImportExpression(func), 0); stmt = s; break; } case OP_switch: { SwitchNode *s = mod.CurFuncCodeMemPool()->New(mod); - s->SetDefaultLabel(static_cast(ReadNum())); + s->SetDefaultLabel(ImportLabel(func)); auto tagSize = static_cast(ReadNum()); for (uint32 i = 0; i < tagSize; ++i) { int64 casetag = ReadNum(); - LabelIdx lidx(ReadNum()); + LabelIdx lidx = ImportLabel(func); CasePair cpair = std::make_pair(casetag, lidx); s->GetSwitchTable().push_back(cpair); } @@ -798,7 +780,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { uint32 tagSize = static_cast(ReadNum()); for (uint32 i = 0; i < tagSize; ++i) { uint16 casetag = static_cast(ReadNum()); - LabelIdx lidx(ReadNum()); + LabelIdx lidx = ImportLabel(func); s->AddRangeGoto(casetag, lidx); } s->SetOpnd(ImportExpression(func), 0); @@ -807,8 +789,8 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_jstry: { JsTryNode *s = mod.CurFuncCodeMemPool()->New(); - s->SetCatchOffset(static_cast(ReadNum())); - s->SetFinallyOffset(static_cast(ReadNum())); + s->SetCatchOffset(ImportLabel(func)); + s->SetFinallyOffset(ImportLabel(func)); stmt = s; break; } @@ -817,7 +799,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { TryNode *s = mod.CurFuncCodeMemPool()->New(mod); auto numLabels = static_cast(ReadNum()); for (uint32 i = 0; i < numLabels; ++i) { - s->GetOffsets().push_back(ReadNum()); + s->GetOffsets().push_back(ImportLabel(func)); } stmt = s; break; @@ -887,7 +869,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { // the labels count = static_cast(ReadNum()); for (size_t i = 0; i < count; ++i) { - auto lidx = static_cast(ReadNum()); + LabelIdx lidx = ImportLabel(func); s->gotoLabels.push_back(lidx); } // the inputs @@ -927,6 +909,13 @@ void BinaryMplImport::ReadFunctionBodyField() { PUIdx puIdx = ImportFunction(); MIRFunction *fn = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); mod.SetCurFunction(fn); + fn->GetFuncSymbol()->SetAppearsInCode(true); + localSymTab.clear(); + localSymTab.push_back(nullptr); + localPregTab.clear(); + localPregTab.push_back(0); + localLabelTab.clear(); + localLabelTab.push_back(0); fn->AllocSymTab(); fn->AllocPregTab(); @@ -934,9 +923,6 @@ void BinaryMplImport::ReadFunctionBodyField() { fn->AllocLabelTab(); ImportFuncIdInfo(fn); - ImportPregTab(fn); - ImportLocalSymTab(fn); - ImportLabelTab(fn); ImportLocalTypeNameTable(fn->GetTypeNameTab()); ImportFormalsStIdx(fn); if (mod.GetFlavor() < kMmpl) { @@ -945,8 +931,6 @@ void BinaryMplImport::ReadFunctionBodyField() { (void)ImportBlockNode(fn); mod.AddFunction(fn); } - int64 tag = ReadNum(); - CHECK_FATAL(tag == ~kBinFunctionBodyStart, "pattern mismatch in Read FunctionBody"); return; } } // namespace maple diff --git a/src/mapleall/maple_ir/src/bin_mpl_export.cpp b/src/mapleall/maple_ir/src/bin_mpl_export.cpp index 0a226f1339..486b7eb24b 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_export.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_export.cpp @@ -26,7 +26,7 @@ namespace { using namespace maple; using OutputConstFactory = FunctionFactory; -using OutputTypeFactory = FunctionFactory; +using OutputTypeFactory = FunctionFactory; void OutputConstInt(const MIRConst &constVal, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindConstInt); @@ -62,7 +62,7 @@ void OutputConstLbl(const MIRConst &constVal, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindConstAddrofLabel); mplExport.OutputConstBase(constVal); const MIRLblConst &lblConst = static_cast(constVal); - mplExport.WriteNum(lblConst.GetValue()); // LabelIdx not needed to output puIdx + mplExport.OutputLabel(lblConst.GetValue()); } void OutputConstStr(const MIRConst &constVal, BinaryMplExport &mplExport) { @@ -141,39 +141,39 @@ static bool InitOutputConstFactory() { return true; } -void OutputTypeScalar(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeScalar(const MIRType &ty, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindTypeScalar); mplExport.OutputTypeBase(ty); } -void OutputTypePointer(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypePointer(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypePointer); mplExport.OutputTypeBase(type); mplExport.OutputTypeAttrs(type.GetTypeAttrs()); - mplExport.OutputType(type.GetPointedTyIdx(), canUseTypename); + mplExport.OutputType(type.GetPointedTyIdx()); } -void OutputTypeByName(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeByName(const MIRType &ty, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindTypeByName); mplExport.OutputTypeBase(ty); } -void OutputTypeFArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeFArray(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeFArray); mplExport.OutputTypeBase(type); - mplExport.OutputType(type.GetElemTyIdx(), canUseTypename); + mplExport.OutputType(type.GetElemTyIdx()); } -void OutputTypeJArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeJArray(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeJarray); mplExport.OutputTypeBase(type); - mplExport.OutputType(type.GetElemTyIdx(), canUseTypename); + mplExport.OutputType(type.GetElemTyIdx()); } -void OutputTypeArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeArray(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeArray); mplExport.OutputTypeBase(type); @@ -181,20 +181,20 @@ void OutputTypeArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseT for (uint16 i = 0; i < type.GetDim(); ++i) { mplExport.WriteNum(type.GetSizeArrayItem(i)); } - mplExport.OutputType(type.GetElemTyIdx(), canUseTypename); + mplExport.OutputType(type.GetElemTyIdx()); mplExport.OutputTypeAttrs(type.GetTypeAttrs()); } -void OutputTypeFunction(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeFunction(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeFunction); mplExport.OutputTypeBase(type); - mplExport.OutputType(type.GetRetTyIdx(), canUseTypename); - mplExport.WriteNum(type.IsVarargs()); + mplExport.OutputType(type.GetRetTyIdx()); + mplExport.WriteNum(type.funcAttrs.GetAttrFlag()); size_t size = type.GetParamTypeList().size(); mplExport.WriteNum(size); for (size_t i = 0; i < size; ++i) { - mplExport.OutputType(type.GetNthParamType(i), canUseTypename); + mplExport.OutputType(type.GetNthParamType(i)); } size = type.GetParamAttrsList().size(); mplExport.WriteNum(size); @@ -203,13 +203,13 @@ void OutputTypeFunction(const MIRType &ty, BinaryMplExport &mplExport, bool canU } } -void OutputTypeParam(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeParam(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeParam); mplExport.OutputTypeBase(type); } -void OutputTypeInstantVector(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeInstantVector(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeInstantVector); mplExport.OutputTypeBase(type); @@ -217,15 +217,15 @@ void OutputTypeInstantVector(const MIRType &ty, BinaryMplExport &mplExport, bool mplExport.OutputTypePairs(type); } -void OutputTypeGenericInstant(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeGenericInstant(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeGenericInstant); mplExport.OutputTypeBase(type); mplExport.OutputTypePairs(type); - mplExport.OutputType(type.GetGenericTyIdx(), canUseTypename); + mplExport.OutputType(type.GetGenericTyIdx()); } -void OutputTypeBitField(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeBitField(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeBitField); mplExport.OutputTypeBase(type); @@ -233,7 +233,7 @@ void OutputTypeBitField(const MIRType &ty, BinaryMplExport &mplExport, bool) { } // for Struct/StructIncomplete/Union -void OutputTypeStruct(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeStruct(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeStruct); mplExport.OutputTypeBase(type); @@ -249,7 +249,7 @@ void OutputTypeStruct(const MIRType &ty, BinaryMplExport &mplExport, bool) { } } -void OutputTypeClass(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeClass(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeClass); mplExport.OutputTypeBase(type); @@ -264,7 +264,7 @@ void OutputTypeClass(const MIRType &ty, BinaryMplExport &mplExport, bool) { } } -void OutputTypeInterface(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeInterface(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeInterface); mplExport.OutputTypeBase(type); @@ -279,7 +279,7 @@ void OutputTypeInterface(const MIRType &ty, BinaryMplExport &mplExport, bool) { } } -void OutputTypeConstString(const MIRType &ty, BinaryMplExport&, bool) { +void OutputTypeConstString(const MIRType &ty, BinaryMplExport&) { ASSERT(false, "Type's kind not yet implemented: %d", ty.GetKind()); (void)ty; } @@ -397,7 +397,7 @@ void BinaryMplExport::DumpBuf(const std::string &name) { void BinaryMplExport::OutputConstBase(const MIRConst &constVal) { WriteNum(constVal.GetKind()); - OutputTypeViaTypeName(constVal.GetType().GetTypeIndex()); + OutputType(constVal.GetType().GetTypeIndex()); } void BinaryMplExport::OutputConst(MIRConst *constVal) { @@ -470,8 +470,8 @@ void BinaryMplExport::OutputPragma(const MIRPragma &p) { WriteNum(p.GetKind()); WriteNum(p.GetVisibility()); OutputStr(p.GetStrIdx()); - OutputType(p.GetTyIdx(), false); - OutputType(p.GetTyIdxEx(), false); + OutputType(p.GetTyIdx()); + OutputType(p.GetTyIdxEx()); WriteNum(p.GetParamNum()); size_t size = p.GetElementVector().size(); WriteNum(size); @@ -488,7 +488,7 @@ void BinaryMplExport::OutputTypeBase(const MIRType &type) { void BinaryMplExport::OutputFieldPair(const FieldPair &fp) { OutputStr(fp.first); // GStrIdx - OutputType(fp.second.first, false); // TyIdx + OutputType(fp.second.first); // TyIdx FieldAttrs fa = fp.second.second; WriteNum(fa.GetAttrFlag()); WriteNum(fa.GetAlignValue()); @@ -511,7 +511,7 @@ void BinaryMplExport::OutputMethodPair(const MethodPair &memPool) { MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(memPool.first.Idx()); CHECK_FATAL(funcSt != nullptr, "Pointer funcSt is nullptr, can't get symbol! Check it!"); WriteAsciiStr(GlobalTables::GetStrTable().GetStringFromStrIdx(funcSt->GetNameStrIdx())); - OutputType(memPool.second.first, false); // TyIdx + OutputType(memPool.second.first); // TyIdx WriteNum(memPool.second.second.GetAttrFlag()); // FuncAttrs } @@ -539,7 +539,7 @@ void BinaryMplExport::OutputStructTypeData(const MIRStructType &type) { void BinaryMplExport::OutputImplementedInterfaces(const std::vector &interfaces) { WriteNum(interfaces.size()); for (const TyIdx &tyIdx : interfaces) { - OutputType(tyIdx, false); + OutputType(tyIdx); } } @@ -571,7 +571,7 @@ void BinaryMplExport::OutputPragmaVec(const std::vector &pragmaVec) } void BinaryMplExport::OutputClassTypeData(const MIRClassType &type) { - OutputType(type.GetParentTyIdx(), false); + OutputType(type.GetParentTyIdx()); OutputImplementedInterfaces(type.GetInterfaceImplemented()); OutputInfoIsString(type.GetInfoIsString()); if (!inIPA) { @@ -601,6 +601,7 @@ void BinaryMplExport::Init() { symMark[nullptr] = 0; funcMark[nullptr] = 0; eaNodeMark[nullptr] = 0; + curFunc = nullptr; for (uint32 pti = static_cast(PTY_begin); pti < static_cast(PTY_end); ++pti) { typMark[GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(pti))] = pti; } @@ -612,7 +613,7 @@ void BinaryMplExport::OutputSymbol(MIRSymbol *sym) { return; } - auto it = symMark.find(sym); + std::unordered_map::iterator it = symMark.find(sym); if (it != symMark.end()) { WriteNum(-(it->second)); return; @@ -645,7 +646,7 @@ void BinaryMplExport::OutputSymbol(MIRSymbol *sym) { if (sym->GetSKind() == kStVar || sym->GetSKind() == kStFunc) { OutputSrcPos(sym->GetSrcPosition()); } - OutputTypeViaTypeName(sym->GetTyIdx()); + OutputType(sym->GetTyIdx()); } void BinaryMplExport::OutputFunction(PUIdx puIdx) { @@ -671,7 +672,7 @@ void BinaryMplExport::OutputFunction(PUIdx puIdx) { MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx()); CHECK_FATAL(funcSt != nullptr, "Pointer funcSt is nullptr, cannot get symbol! Check it!"); OutputSymbol(funcSt); - OutputTypeViaTypeName(func->GetMIRFuncType()->GetTypeIndex()); + OutputType(func->GetMIRFuncType()->GetTypeIndex()); WriteNum(func->GetFuncAttrs().GetAttrFlag()); auto &attributes = func->GetFuncAttrs(); @@ -684,12 +685,12 @@ void BinaryMplExport::OutputFunction(PUIdx puIdx) { } WriteNum(func->GetFlag()); - OutputTypeViaTypeName(func->GetClassTyIdx()); + OutputType(func->GetClassTyIdx()); // output formal parameter information WriteNum(static_cast(func->GetFormalDefVec().size())); for (FormalDef formalDef : func->GetFormalDefVec()) { OutputStr(formalDef.formalStrIdx); - OutputType(formalDef.formalTyIdx, false); + OutputType(formalDef.formalTyIdx); WriteNum(static_cast(formalDef.formalAttrs.GetAttrFlag())); } // store Side Effect for each func @@ -751,15 +752,20 @@ void BinaryMplExport::WriteHeaderField(uint64 contentIdx) { WriteNum(mod.GetID()); if (mod.GetFlavor() == kFlavorLmbc) { WriteNum(mod.GetGlobalMemSize()); + WriteNum(mod.IsWithDbgInfo()); } WriteNum(mod.GetNumFuncs()); WriteAsciiStr(mod.GetEntryFuncName()); OutputInfoVector(mod.GetFileInfo(), mod.GetFileInfoIsString()); - WriteNum(static_cast(mod.GetSrcFileInfo().size())); - for (uint32 i = 0; i < mod.GetSrcFileInfo().size(); i++) { - OutputStr(mod.GetSrcFileInfo()[i].first); - WriteNum(mod.GetSrcFileInfo()[i].second); + if (mod.IsWithDbgInfo()) { + WriteNum(static_cast(mod.GetSrcFileInfo().size())); + for (uint32 i = 0; i < mod.GetSrcFileInfo().size(); i++) { + OutputStr(mod.GetSrcFileInfo()[i].first); + WriteNum(mod.GetSrcFileInfo()[i].second); + } + } else { + Write(0); } WriteNum(static_cast(mod.GetImportFiles().size())); @@ -795,7 +801,7 @@ void BinaryMplExport::WriteTypeField(uint64 contentIdx, bool useClassList) { auto *structType = static_cast(type); // skip imported class/interface and incomplete types if (!structType->IsImported() && !structType->IsIncomplete()) { - OutputType(curTyidx, false); + OutputType(curTyidx); ++size; } } @@ -803,7 +809,7 @@ void BinaryMplExport::WriteTypeField(uint64 contentIdx, bool useClassList) { } else { uint32 idx = GlobalTables::GetTypeTable().lastDefaultTyIdx.GetIdx(); for (idx = idx + 1; idx < GlobalTables::GetTypeTable().GetTypeTableSize(); idx++) { - OutputType(TyIdx(idx), false); + OutputType(TyIdx(idx)); size++; } } @@ -884,7 +890,7 @@ void BinaryMplExport::WriteSeField() { GlobalTables::GetGsymTable().GetSymbolFromStrIdx(GlobalTables::GetStrTable().GetStrIdxFromName(funcStr)); MIRFunction *func = (funcSymbol != nullptr) ? GetMIRModule().GetMIRBuilder()->GetFunctionFromSymbol(*funcSymbol) : nullptr; - OutputType(func->GetReturnTyIdx(), false); + OutputType(func->GetReturnTyIdx()); } ++size; } @@ -1103,7 +1109,7 @@ void BinaryMplExport::WriteSymField(uint64 contentIdx) { MIRSymKind sKind = s->GetSKind(); if (s->IsDeleted() || storageClass == kScUnused || (s->GetIsImported() && !s->GetAppearsInCode()) || - (storageClass == kScExtern && sKind == kStFunc)) { + (sKind == kStFunc && (storageClass == kScExtern || !s->GetAppearsInCode()))) { continue; } OutputSymbol(s); @@ -1214,8 +1220,6 @@ void BinaryMplExport::Export(const std::string &fname, std::unordered_setIsNameIsLocal() && ty->GetNameStrIdx() != GStrIdx(0)) { - WriteNum(kBinKindTypeViaTypename); - OutputStr(ty->GetNameStrIdx()); - return; - } - auto func = CreateProductFunction(ty->GetKind()); if (func != nullptr) { - func(*ty, *this, canUseTypename); + func(*ty, *this); } else { ASSERT(false, "Type's kind not yet implemented: %d", ty->GetKind()); } diff --git a/src/mapleall/maple_ir/src/bin_mpl_import.cpp b/src/mapleall/maple_ir/src/bin_mpl_import.cpp index 50779027df..1f79751ed6 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_import.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_import.cpp @@ -129,11 +129,13 @@ MIRConst *BinaryMplImport::ImportConst(MIRFunction *func) { } case kBinKindConstAddrofFunc: { PUIdx puIdx = ImportFunction(); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFuncTable()[puIdx]; + f->GetFuncSymbol()->SetAppearsInCode(true); mod.SetCurFunction(func); return memPool->New(puIdx, *type); } case kBinKindConstAddrofLabel: { - LabelIdx lidx = static_cast(ReadNum()); + LabelIdx lidx = ImportLabel(func); PUIdx puIdx = func->GetPuidx(); MIRLblConst *lblConst = memPool->New(lidx, puIdx, *type); (void)func->GetLabelTab()->addrTakenLabels.insert(lidx); @@ -541,19 +543,6 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { CHECK_FATAL(static_cast(-tag) < typTab.size(), "index out of bounds"); return typTab.at(static_cast(-tag)); } - if (tag == kBinKindTypeViaTypename) { - GStrIdx typenameStrIdx = ImportStr(); - TyIdx tyIdx = mod.GetTypeNameTab()->GetTyIdxFromGStrIdx(typenameStrIdx); - if (tyIdx != 0) { - typTab.push_back(tyIdx); - return tyIdx; - } - MIRTypeByName ltype(typenameStrIdx); - ltype.SetNameIsLocal(false); - MIRType *type = GlobalTables::GetTypeTable().GetOrCreateMIRTypeNode(ltype); - typTab.push_back(type->GetTypeIndex()); - return type->GetTypeIndex(); - } PrimType primType = (PrimType)0; GStrIdx strIdx(0); bool nameIsLocal = false; @@ -580,13 +569,6 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { } return origType->GetTypeIndex(); } - case kBinKindTypeByName: { - MIRTypeByName type(strIdx); - type.SetNameIsLocal(nameIsLocal); - MIRType *origType = &InsertInTypeTables(type); - typTab.push_back(origType->GetTypeIndex()); - return origType->GetTypeIndex(); - } case kBinKindTypeFArray: { MIRFarrayType type(strIdx); type.SetNameIsLocal(nameIsLocal); @@ -629,7 +611,7 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { size_t idx = typTab.size(); typTab.push_back(TyIdx(0)); type.SetRetTyIdx(ImportType()); - type.SetVarArgs(ReadNum()); + type.funcAttrs.SetAttrFlag(ReadNum()); int64 size = ReadNum(); for (int64 i = 0; i < size; ++i) { type.GetParamTypeList().push_back(ImportType()); @@ -737,19 +719,6 @@ TyIdx BinaryMplImport::ImportTypeNonJava() { CHECK_FATAL(static_cast(-tag) < typTab.size(), "index out of bounds"); return typTab[static_cast(-tag)]; } - if (tag == kBinKindTypeViaTypename) { - GStrIdx typenameStrIdx = ImportStr(); - TyIdx tyIdx = mod.GetTypeNameTab()->GetTyIdxFromGStrIdx(typenameStrIdx); - if (tyIdx != 0) { - typTab.push_back(tyIdx); - return tyIdx; - } - MIRTypeByName ltype(typenameStrIdx); - ltype.SetNameIsLocal(false); - MIRType *type = GlobalTables::GetTypeTable().GetOrCreateMIRTypeNode(ltype); - typTab.push_back(type->GetTypeIndex()); - return type->GetTypeIndex(); - } PrimType primType = (PrimType)0; GStrIdx strIdx(0); bool nameIsLocal = false; @@ -771,12 +740,6 @@ TyIdx BinaryMplImport::ImportTypeNonJava() { GlobalTables::GetTypeTable().CreateMirTypeNodeAt(type, tyIdxUsed, &mod, false, false); return tyIdxUsed; } - case kBinKindTypeByName: { - MIRTypeByName type(strIdx); - type.SetNameIsLocal(nameIsLocal); - GlobalTables::GetTypeTable().CreateMirTypeNodeAt(type, tyIdxUsed, &mod, false, false); - return tyIdxUsed; - } case kBinKindTypeFArray: { MIRFarrayType type(strIdx); type.SetNameIsLocal(nameIsLocal); @@ -808,7 +771,7 @@ TyIdx BinaryMplImport::ImportTypeNonJava() { MIRFuncType type(strIdx); type.SetNameIsLocal(nameIsLocal); type.SetRetTyIdx(ImportTypeNonJava()); - type.SetVarArgs(ReadNum()); + type.funcAttrs.SetAttrFlag(ReadNum()); int64 size = ReadNum(); for (int64 i = 0; i < size; ++i) { type.GetParamTypeList().push_back(ImportTypeNonJava()); @@ -1159,6 +1122,7 @@ void BinaryMplImport::ReadHeaderField() { mod.SetID(static_cast(ReadNum())); if (mod.GetFlavor() == kFlavorLmbc) { mod.SetGlobalMemSize(static_cast(ReadNum())); + mod.SetWithDbgInfo(static_cast(ReadNum())); } mod.SetNumFuncs(static_cast(ReadNum())); std::string inStr; diff --git a/src/mapleall/maple_ir/src/global_tables.cpp b/src/mapleall/maple_ir/src/global_tables.cpp index c43e86b2d5..99851d8ec5 100644 --- a/src/mapleall/maple_ir/src/global_tables.cpp +++ b/src/mapleall/maple_ir/src/global_tables.cpp @@ -224,7 +224,9 @@ MIRType *TypeTable::GetOrCreateFunctionType(const TyIdx &retTyIdx, const std::ve const std::vector &vecAttrs, bool isVarg, const TypeAttrs &retAttrs) { MIRFuncType funcType(retTyIdx, vecType, vecAttrs, retAttrs); - funcType.SetVarArgs(isVarg); + if (isVarg) { + funcType.SetVarArgs(); + } TyIdx tyIdx = GetOrCreateMIRType(&funcType); ASSERT(tyIdx < typeTable.size(), "index out of range in TypeTable::GetOrCreateFunctionType"); return typeTable.at(tyIdx); diff --git a/src/mapleall/maple_ir/src/mir_builder.cpp b/src/mapleall/maple_ir/src/mir_builder.cpp index 8a22af5f12..d9be6b0a0d 100755 --- a/src/mapleall/maple_ir/src/mir_builder.cpp +++ b/src/mapleall/maple_ir/src/mir_builder.cpp @@ -836,6 +836,13 @@ IcallNode *MIRBuilder::CreateStmtIcall(const MapleVector &args) { return stmt; } +IcallNode *MIRBuilder::CreateStmtIcallproto(const MapleVector &args) { + auto *stmt = GetCurrentFuncCodeMp()->New(*GetCurrentFuncCodeMpAllocator(), OP_icallproto); + ASSERT(stmt != nullptr, "stmt is null"); + stmt->SetOpnds(args); + return stmt; +} + IcallNode *MIRBuilder::CreateStmtIcallAssigned(const MapleVector &args, const MIRSymbol &ret) { auto *stmt = GetCurrentFuncCodeMp()->New(*GetCurrentFuncCodeMpAllocator(), OP_icallassigned); CallReturnVector nrets(GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -853,6 +860,23 @@ IcallNode *MIRBuilder::CreateStmtIcallAssigned(const MapleVector &arg return stmt; } +IcallNode *MIRBuilder::CreateStmtIcallprotoAssigned(const MapleVector &args, const MIRSymbol &ret) { + auto *stmt = GetCurrentFuncCodeMp()->New(*GetCurrentFuncCodeMpAllocator(), OP_icallprotoassigned); + CallReturnVector nrets(GetCurrentFuncCodeMpAllocator()->Adapter()); + CHECK_FATAL((ret.GetStorageClass() == kScAuto || ret.GetStorageClass() == kScFormal || + ret.GetStorageClass() == kScExtern || ret.GetStorageClass() == kScGlobal), + "unknown classtype! check it!"); + nrets.emplace_back(CallReturnPair(ret.GetStIdx(), RegFieldPair(0, 0))); + stmt->SetNumOpnds(args.size()); + stmt->GetNopnd().resize(stmt->GetNumOpnds()); + stmt->SetReturnVec(nrets); + for (size_t i = 0; i < stmt->GetNopndSize(); ++i) { + stmt->SetNOpndAt(i, args.at(i)); + } + stmt->SetRetTyIdx(ret.GetTyIdx()); + return stmt; +} + IntrinsiccallNode *MIRBuilder::CreateStmtIntrinsicCall(MIRIntrinsicID idx, const MapleVector &arguments, TyIdx tyIdx) { auto *stmt = GetCurrentFuncCodeMp()->New( diff --git a/src/mapleall/maple_ir/src/mir_function.cpp b/src/mapleall/maple_ir/src/mir_function.cpp index 112f5ad6cf..4f217e54c5 100644 --- a/src/mapleall/maple_ir/src/mir_function.cpp +++ b/src/mapleall/maple_ir/src/mir_function.cpp @@ -368,10 +368,8 @@ void MIRFunction::Dump(bool withoutBody) { LogInfo::MapleLogger() << " )"; } - if (module->GetFlavor() < kMmpl) { + if (module->GetFlavor() != kMmpl) { DumpFlavorLoweredThanMmpl(); - } else { - LogInfo::MapleLogger() << " () void"; } // codeMemPool is nullptr, means maple_ir has been released for memory's sake diff --git a/src/mapleall/maple_ir/src/mir_lower.cpp b/src/mapleall/maple_ir/src/mir_lower.cpp index 99dbd04c3f..aa5cb0131c 100644 --- a/src/mapleall/maple_ir/src/mir_lower.cpp +++ b/src/mapleall/maple_ir/src/mir_lower.cpp @@ -530,6 +530,19 @@ BlockNode *MIRLower::LowerBlock(BlockNode &block) { case OP_doloop: newBlock->AppendStatementsFromBlock(*LowerDoloopStmt(static_cast(*stmt))); break; + case OP_icallassigned: + case OP_icall: { + if (mirModule.IsCModule()) { + // convert to icallproto/icallprotoassigned + IcallNode *ic = static_cast(stmt); + ic->SetOpCode(stmt->GetOpCode() == OP_icall ? OP_icallproto : OP_icallprotoassigned); + MIRFuncType *funcType = FuncTypeFromFuncPtrExpr(stmt->Opnd(0)); + CHECK_FATAL(funcType != nullptr, "MIRLower::LowerBlock: cannot find prototype for icall"); + ic->SetRetTyIdx(funcType->GetTypeIndex()); + } + newBlock->AddStatement(stmt); + break; + } case OP_block: tmp = LowerBlock(static_cast(*stmt)); newBlock->AppendStatementsFromBlock(*tmp); @@ -985,6 +998,100 @@ void MIRLower::ExpandArrayMrt(MIRFunction &func) { } } +MIRFuncType *MIRLower::FuncTypeFromFuncPtrExpr(BaseNode *x) { + MIRFuncType *res = nullptr; + MIRFunction *func = mirModule.CurFunction(); + switch (x->GetOpCode()) { + case OP_regread: { + RegreadNode *regread = static_cast(x); + MIRPreg *preg = func->GetPregTab()->PregFromPregIdx(regread->GetRegIdx()); + // see if it is promoted from a symbol + if (preg->GetOp() == OP_dread) { + const MIRSymbol *symbol = preg->rematInfo.sym; + MIRType *mirType = symbol->GetType(); + if (preg->fieldID != 0) { + MIRStructType *structty = static_cast(mirType); + FieldPair thepair = structty->TraverseToField(preg->fieldID); + mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); + } + + if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + if (res != nullptr) { + break; + } + } + // check if a formal promoted to preg + for (FormalDef &formalDef : func->GetFormalDefVec()) { + if (!formalDef.formalSym->IsPreg()) { + continue; + } + if (formalDef.formalSym->GetPreg() == preg) { + MIRType *mirType = formalDef.formalSym->GetType(); + if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + break; + } + } + break; + } + case OP_dread: { + DreadNode *dread = static_cast(x); + MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); + MIRType *mirType = symbol->GetType(); + if (dread->GetFieldID() != 0) { + MIRStructType *structty = static_cast(mirType); + FieldPair thepair = structty->TraverseToField(dread->GetFieldID()); + mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); + } + if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + break; + } + case OP_iread: { + IreadNode *iread = static_cast(x); + MIRPtrType *ptrType = static_cast(iread->GetType()); + MIRType *mirType = ptrType->GetPointedType(); + if (mirType->GetKind() == kTypeFunction) { + res = static_cast(mirType); + } else if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + break; + } + case OP_addroffunc: { + AddroffuncNode *addrofFunc = static_cast(x); + PUIdx puIdx = addrofFunc->GetPUIdx(); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); + res = f->GetMIRFuncType(); + break; + } + case OP_retype: { + MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx( + static_cast(x)->GetTyIdx()); + if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + if (res == nullptr) { + res = FuncTypeFromFuncPtrExpr(x->Opnd(0)); + } + break; + } + case OP_select: { + res = FuncTypeFromFuncPtrExpr(x->Opnd(1)); + if (res == nullptr) { + res = FuncTypeFromFuncPtrExpr(x->Opnd(2)); + } + break; + } + default: CHECK_FATAL(false, "LMBCLowerer::FuncTypeFromFuncPtrExpr: NYI"); + } + return res; +} + const std::set MIRLower::kSetArrayHotFunc = {}; bool MIRLower::ShouldOptArrayMrt(const MIRFunction &func) { diff --git a/src/mapleall/maple_ir/src/mir_nodes.cpp b/src/mapleall/maple_ir/src/mir_nodes.cpp index 510dbd07ca..e86982b764 100755 --- a/src/mapleall/maple_ir/src/mir_nodes.cpp +++ b/src/mapleall/maple_ir/src/mir_nodes.cpp @@ -1201,7 +1201,7 @@ MIRType *IcallNode::GetCallReturnType() { if (op == OP_icall || op == OP_icallassigned) { return GlobalTables::GetTypeTable().GetTypeFromTyIdx(retTyIdx); } - // icallproto + // icallproto or icallprotoassigned MIRFuncType *funcType = static_cast( GlobalTables::GetTypeTable().GetTypeFromTyIdx(retTyIdx)); return GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcType->GetRetTyIdx()); @@ -1226,7 +1226,7 @@ const MIRSymbol *IcallNode::GetCallReturnSymbol(const MIRModule &mod) const { void IcallNode::Dump(int32 indent, bool newline) const { StmtNode::DumpBase(indent); - if (op == OP_icallproto) { + if (op == OP_icallproto || op == OP_icallprotoassigned) { LogInfo::MapleLogger() << " "; GlobalTables::GetTypeTable().GetTypeFromTyIdx(retTyIdx)->Dump(indent + 1); } diff --git a/src/mapleall/maple_ir/src/mir_parser.cpp b/src/mapleall/maple_ir/src/mir_parser.cpp index 9660002e49..b0bbf9080b 100755 --- a/src/mapleall/maple_ir/src/mir_parser.cpp +++ b/src/mapleall/maple_ir/src/mir_parser.cpp @@ -896,6 +896,7 @@ bool MIRParser::ParseStmtCall(StmtNodePtr &stmt) { callStmt->SetPUIdx(pIdx); MIRFunction *callee = GlobalTables::GetFunctionTable().GetFuncTable()[pIdx]; + callee->GetFuncSymbol()->SetAppearsInCode(true); if (callee->GetName() == "setjmp") { mod.CurFunction()->SetHasSetjmp(); } @@ -932,9 +933,14 @@ bool MIRParser::ParseStmtIcall(StmtNodePtr &stmt, Opcode op) { // . . . // dassign } // icallproto (, , ..., ) + // icallprotoassigned (, , ..., ) { + // dassign + // dassign + // . . . + // dassign } IcallNode *iCallStmt = mod.CurFuncCodeMemPool()->New(mod, op); lexer.NextToken(); - if (op == OP_icallproto) { + if (op == OP_icallproto || op == OP_icallprotoassigned) { TyIdx tyIdx(0); if (!ParseDerivedType(tyIdx)) { Error("error parsing type in ParseStmtIcall for icallproto at "); @@ -948,7 +954,7 @@ bool MIRParser::ParseStmtIcall(StmtNodePtr &stmt, Opcode op) { } iCallStmt->SetNOpnd(opndsVec); iCallStmt->SetNumOpnds(opndsVec.size()); - if (op == OP_icallassigned) { + if (op == OP_icallassigned || op == OP_icallprotoassigned) { CallReturnVector retsVec(mod.CurFuncCodeMemPoolAllocator()->Adapter()); if (!ParseCallReturns(retsVec)) { return false; @@ -972,6 +978,10 @@ bool MIRParser::ParseStmtIcallproto(StmtNodePtr &stmt) { return ParseStmtIcall(stmt, OP_icallproto); } +bool MIRParser::ParseStmtIcallprotoassigned(StmtNodePtr &stmt) { + return ParseStmtIcall(stmt, OP_icallprotoassigned); +} + bool MIRParser::ParseStmtIntrinsiccall(StmtNodePtr &stmt, bool isAssigned) { Opcode o = !isAssigned ? (lexer.GetTokenKind() == TK_intrinsiccall ? OP_intrinsiccall : OP_xintrinsiccall) : (lexer.GetTokenKind() == TK_intrinsiccallassigned ? OP_intrinsiccallassigned @@ -2013,18 +2023,6 @@ bool MIRParser::ParseStmtBlockForUpformalSize() { return true; } -bool MIRParser::ParseStmtBlockForOutParmSize() { - MIRFunction *fn = paramCurrFuncForParseStmtBlock; - lexer.NextToken(); - if (lexer.GetTokenKind() != TK_intconst) { - Error("expect integer after outparmsize but get "); - return false; - } - fn->SetOutParmSize(static_cast(lexer.GetTheIntVal())); - lexer.NextToken(); - return true; -} - bool MIRParser::ParseStmtBlockForModuleID() { MIRFunction *fn = paramCurrFuncForParseStmtBlock; lexer.NextToken(); @@ -3241,7 +3239,8 @@ bool MIRParser::ParseConstAddrLeafExpr(MIRConstPtr &cexpr) { } else if (expr->GetOpCode() == OP_addroffunc) { auto *aof = static_cast(expr); MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(aof->GetPUIdx()); - const MIRSymbol *fName = f->GetFuncSymbol(); + MIRSymbol *fName = f->GetFuncSymbol(); + fName->SetAppearsInCode(true); TyIdx ptyIdx = fName->GetTyIdx(); MIRPtrType ptrType(ptyIdx); ptyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&ptrType); @@ -3415,6 +3414,7 @@ std::map MIRParser::InitFuncPtrMapForPar funcPtrMap[TK_icall] = &MIRParser::ParseStmtIcall; funcPtrMap[TK_icallassigned] = &MIRParser::ParseStmtIcallassigned; funcPtrMap[TK_icallproto] = &MIRParser::ParseStmtIcallproto; + funcPtrMap[TK_icallprotoassigned] = &MIRParser::ParseStmtIcallprotoassigned; funcPtrMap[TK_intrinsiccall] = &MIRParser::ParseStmtIntrinsiccall; funcPtrMap[TK_intrinsiccallassigned] = &MIRParser::ParseStmtIntrinsiccallassigned; funcPtrMap[TK_xintrinsiccall] = &MIRParser::ParseStmtIntrinsiccall; @@ -3475,7 +3475,6 @@ std::map MIRParser::InitFuncPtrMapF funcPtrMap[TK_type] = &MIRParser::ParseStmtBlockForType; funcPtrMap[TK_framesize] = &MIRParser::ParseStmtBlockForFrameSize; funcPtrMap[TK_upformalsize] = &MIRParser::ParseStmtBlockForUpformalSize; - funcPtrMap[TK_outparmsize] = &MIRParser::ParseStmtBlockForOutParmSize; funcPtrMap[TK_moduleid] = &MIRParser::ParseStmtBlockForModuleID; funcPtrMap[TK_funcsize] = &MIRParser::ParseStmtBlockForFuncSize; funcPtrMap[TK_funcid] = &MIRParser::ParseStmtBlockForFuncID; diff --git a/src/mapleall/maple_ir/src/mir_type.cpp b/src/mapleall/maple_ir/src/mir_type.cpp index c8915d18c5..c3019f23bd 100644 --- a/src/mapleall/maple_ir/src/mir_type.cpp +++ b/src/mapleall/maple_ir/src/mir_type.cpp @@ -738,7 +738,9 @@ void MIRFuncType::Dump(int indent, bool dontUseName) const { if (!dontUseName && CheckAndDumpTypeName(nameStrIdx, nameIsLocal)) { return; } - LogInfo::MapleLogger() << "Dump(indent + 1); @@ -749,7 +751,7 @@ void MIRFuncType::Dump(int indent, bool dontUseName) const { LogInfo::MapleLogger() << ","; } } - if (isVarArgs) { + if (IsVarargs()) { LogInfo::MapleLogger() << ", ..."; } LogInfo::MapleLogger() << ") "; @@ -1663,7 +1665,7 @@ bool MIRFuncType::EqualTo(const MIRType &type) const { } const auto &pType = static_cast(type); return (pType.retTyIdx == retTyIdx && pType.paramTypeList == paramTypeList && - pType.isVarArgs == isVarArgs && pType.paramAttrsList == paramAttrsList && + pType.funcAttrs == funcAttrs && pType.paramAttrsList == paramAttrsList && pType.retAttrs == retAttrs); } diff --git a/src/mapleall/maple_ir/src/parser.cpp b/src/mapleall/maple_ir/src/parser.cpp index 4587c26fbe..755f120f95 100644 --- a/src/mapleall/maple_ir/src/parser.cpp +++ b/src/mapleall/maple_ir/src/parser.cpp @@ -229,9 +229,7 @@ bool MIRParser::ParsePseudoReg(PrimType primType, PregIdx &pRegIdx) { MIRPreg *preg = curfunc->GetPregTab()->PregFromPregIdx(pRegIdx); if (primType != kPtyInvalid) { if (preg->GetPrimType() != primType) { - if ((primType == PTY_ref || primType == PTY_ptr) && - (preg->GetPrimType() == PTY_ref || preg->GetPrimType() == PTY_ptr)) { - ; // PTY_ref and PTY_ptr are compatible with each other + if (IsAddress(preg->GetPrimType()) && IsAddress(primType)) { } else { Error("inconsistent preg primitive type at "); return false; @@ -1299,6 +1297,15 @@ bool MIRParser::ParsePointType(TyIdx &tyIdx) { // in function pointer specification and member function prototypes inside // structs and classes bool MIRParser::ParseFuncType(TyIdx &tyIdx) { + // parse function attributes + FuncAttrs fAttrs; + if (lexer.GetTokenKind() != TK_lparen) { + if (!ParseFuncAttrs(fAttrs)) { + Error("bad function attribute specification in function type at "); + return false; + } + } + // parse parameters if (lexer.GetTokenKind() != TK_lparen) { Error("expect ( parse function type parameters but get "); @@ -1359,7 +1366,10 @@ bool MIRParser::ParseFuncType(TyIdx &tyIdx) { return false; } MIRFuncType functype(retTyIdx, vecTyIdx, vecAttrs, retTypeAttrs); - functype.SetVarArgs(varargs); + functype.funcAttrs = fAttrs; + if (varargs) { + functype.SetVarArgs(); + } tyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&functype); return true; } diff --git a/src/mapleall/maple_me/include/lmbc_lower.h b/src/mapleall/maple_me/include/lmbc_lower.h index 9462204fd7..bbeaabf098 100644 --- a/src/mapleall/maple_me/include/lmbc_lower.h +++ b/src/mapleall/maple_me/include/lmbc_lower.h @@ -40,10 +40,7 @@ class LMBCLowerer { void LowerIassign(IassignNode *, BlockNode *); void LowerAggIassign(IassignNode *, MIRType *type, int32 offset, BlockNode *); void LowerReturn(NaryStmtNode *retNode, BlockNode *newblk); - MIRFuncType *FuncTypeFromFuncPtrExpr(BaseNode *x); - void LowerCall(NaryStmtNode *callNode, BlockNode *newblk); BlockNode *LowerBlock(BlockNode *); - void LoadFormalsAssignedToPregs(); void LowerFunction(); MIRModule *mirModule; diff --git a/src/mapleall/maple_me/include/lmbc_memlayout.h b/src/mapleall/maple_me/include/lmbc_memlayout.h index 7cea863a22..0f2bf5cbea 100644 --- a/src/mapleall/maple_me/include/lmbc_memlayout.h +++ b/src/mapleall/maple_me/include/lmbc_memlayout.h @@ -31,8 +31,8 @@ typedef enum { MS_actual, // for the outgoing parameters MS_local, // for all local variables and temporaries MS_FPbased, // addressed via offset from the frame pointer - MS_SPbased, // addressed via offset from the stack pointer MS_GPbased, // addressed via offset from the global pointer + MS_largeStructActual, // for storing large struct actuals passed by value for ARM CPU } MemSegmentKind; class MemSegment; @@ -64,15 +64,10 @@ class MemSegment { class LMBCMemLayout { public: - uint32 FindLargestActualArea(void); - uint32 FindLargestActualArea(StmtNode *, int &); - LMBCMemLayout(MIRFunction *f, MapleAllocator *mallocator) + LMBCMemLayout(MIRFunction *f, MemSegment *segGP, MapleAllocator *mallocator) : func(f), - seg_upformal(MS_upformal), - seg_formal(MS_formal), - seg_actual(MS_actual), + seg_GPbased(segGP), seg_FPbased(MS_FPbased), - seg_SPbased(MS_SPbased), sym_alloc_table(mallocator->Adapter()) { sym_alloc_table.resize(f->GetSymTab()->GetSymbolTableSize()); } @@ -81,67 +76,25 @@ class LMBCMemLayout { void LayoutStackFrame(void); int32 StackFrameSize(void) const { - return seg_SPbased.size - seg_FPbased.size; - } - - int32 UpformalSize(void) const { - return seg_upformal.size; + return -seg_FPbased.size; } MIRFunction *func; - MemSegment seg_upformal; - MemSegment seg_formal; - MemSegment seg_actual; + MemSegment *seg_GPbased; MemSegment seg_FPbased; - MemSegment seg_SPbased; MapleVector sym_alloc_table; // index is StIdx }; class GlobalMemLayout { public: - GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAllocator *mallocator); + GlobalMemLayout(MIRModule *mod, MapleAllocator *mallocator); ~GlobalMemLayout() {} MemSegment seg_GPbased; MapleVector sym_alloc_table; // index is StIdx - - private: - void FillScalarValueInMap(uint32 startaddress, PrimType pty, MIRConst *c); - void FillTypeValueInMap(uint32 startaddress, MIRType *ty, MIRConst *c); - void FillSymbolValueInMap(const MIRSymbol *sym); - - maplebe::BECommon *be; MIRModule *mirModule; }; -// for specifying how a parameter is passed -struct PLocInfo { - int32 memoffset; - int32 memsize; -}; - -// for processing an incoming or outgoing parameter list -class ParmLocator { - public: - explicit ParmLocator() : parmNum(0), lastMemOffset(0) {} - - ~ParmLocator() {} - - void LocateNextParm(const MIRType *ty, PLocInfo &ploc); - - private: - int32 parmNum; // number of all types of parameters processed so far - int32 lastMemOffset; -}; - -// given the type of the return value, determines the return mechanism -class ReturnMechanism { - public: - ReturnMechanism(const MIRType *retty); - bool fake_first_parm; // whether returning in memory via fake first parameter - PrimType ptype0; // the primitive type stored in retval0 -}; - } /* namespace maple */ #endif /* MAPLEME_INCLUDE_LMBC_MEMLAYOUT_H */ diff --git a/src/mapleall/maple_me/src/alias_class.cpp b/src/mapleall/maple_me/src/alias_class.cpp index 368effe2b9..6be86e59fa 100644 --- a/src/mapleall/maple_me/src/alias_class.cpp +++ b/src/mapleall/maple_me/src/alias_class.cpp @@ -1018,7 +1018,9 @@ void AliasClass::ApplyUnionForCopies(StmtNode &stmt) { } case OP_asm: case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { for (uint32 i = 0; i < stmt.NumOpnds(); ++i) { const AliasInfo &ainfo = CreateAliasInfoExpr(*stmt.Opnd(i)); if (stmt.GetOpCode() != OP_asm && i == 0) { @@ -2569,6 +2571,7 @@ void AliasClass::GenericInsertMayDefUse(StmtNode &stmt, BBId bbID) { case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_virtualcall: case OP_virtualicall: case OP_superclasscall: @@ -2576,7 +2579,8 @@ void AliasClass::GenericInsertMayDefUse(StmtNode &stmt, BBId bbID) { case OP_interfaceicall: case OP_customcall: case OP_polymorphiccall: - case OP_icall: { + case OP_icall: + case OP_icallproto: { InsertMayDefUseCall(stmt, bbID, false); return; } diff --git a/src/mapleall/maple_me/src/code_factoring.cpp b/src/mapleall/maple_me/src/code_factoring.cpp index 6cabb59adc..2f40e7b821 100644 --- a/src/mapleall/maple_me/src/code_factoring.cpp +++ b/src/mapleall/maple_me/src/code_factoring.cpp @@ -122,7 +122,9 @@ bool FactoringOptimizer::IsIdenticalStmt(StmtNode *stmt1, StmtNode *stmt2) { break; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { auto *icall1 = static_cast(stmt1); auto *icall2 = static_cast(stmt2); if (icall1->GetRetTyIdx() != icall2->GetRetTyIdx() || diff --git a/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp b/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp index 2bb97532a6..ba545a5991 100644 --- a/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp +++ b/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp @@ -642,7 +642,9 @@ void PEGBuilder::BuildPEGNodeInStmt(const StmtNode *stmt) { break; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { BuildPEGNodeInIcall(static_cast(stmt)); break; } diff --git a/src/mapleall/maple_me/src/irmap_build.cpp b/src/mapleall/maple_me/src/irmap_build.cpp index 92eece9fa0..b6d96b6726 100755 --- a/src/mapleall/maple_me/src/irmap_build.cpp +++ b/src/mapleall/maple_me/src/irmap_build.cpp @@ -808,7 +808,7 @@ MeStmt *IRMapBuild::BuildCallMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { MeStmt *IRMapBuild::BuildNaryMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { Opcode op = stmt.GetOpCode(); - NaryMeStmt *naryMeStmt = (op == OP_icall || op == OP_icallassigned) + NaryMeStmt *naryMeStmt = (op == OP_icall || op == OP_icallassigned || op == OP_icallproto || op == OP_icallprotoassigned) ? static_cast(irMap->NewInPool(&stmt)) : static_cast(irMap->NewInPool(&stmt)); auto &naryStmtNode = static_cast(stmt); @@ -823,6 +823,9 @@ MeStmt *IRMapBuild::BuildNaryMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { if (propagater) { propagater->PropUpdateChiListDef(*naryMeStmt->GetChiList()); } + if (op == OP_icallproto || op == OP_icallprotoassigned) { + static_cast(naryMeStmt)->SetRetTyIdx(static_cast(stmt).GetRetTyIdx()); + } return naryMeStmt; } @@ -923,6 +926,8 @@ void IRMapBuild::InitMeStmtFactory() { RegisterFactoryFunction(OP_polymorphiccallassigned, &IRMapBuild::BuildCallMeStmt); RegisterFactoryFunction(OP_icall, &IRMapBuild::BuildNaryMeStmt); RegisterFactoryFunction(OP_icallassigned, &IRMapBuild::BuildNaryMeStmt); + RegisterFactoryFunction(OP_icallproto, &IRMapBuild::BuildNaryMeStmt); + RegisterFactoryFunction(OP_icallprotoassigned, &IRMapBuild::BuildNaryMeStmt); RegisterFactoryFunction(OP_intrinsiccall, &IRMapBuild::BuildNaryMeStmt); RegisterFactoryFunction(OP_xintrinsiccall, &IRMapBuild::BuildNaryMeStmt); RegisterFactoryFunction(OP_intrinsiccallwithtype, &IRMapBuild::BuildNaryMeStmt); diff --git a/src/mapleall/maple_me/src/irmap_emit.cpp b/src/mapleall/maple_me/src/irmap_emit.cpp index 1f5f45518c..f6d7b046d8 100755 --- a/src/mapleall/maple_me/src/irmap_emit.cpp +++ b/src/mapleall/maple_me/src/irmap_emit.cpp @@ -412,7 +412,7 @@ MIRFunction &CallMeStmt::GetTargetFunction() { } StmtNode &CallMeStmt::EmitStmt(SSATab &ssaTab) { - if (GetOp() != OP_icall && GetOp() != OP_icallassigned) { + if (GetOp() != OP_icall && GetOp() != OP_icallassigned && GetOp() != OP_icallproto && GetOp() != OP_icallprotoassigned) { auto *callNode = ssaTab.GetModule().CurFunction()->GetCodeMempool()->New(ssaTab.GetModule(), Opcode(GetOp())); callNode->SetPUIdx(puIdx); @@ -497,6 +497,9 @@ StmtNode &IcallMeStmt::EmitStmt(SSATab &ssaTab) { } } } + if (GetOp() == OP_icallproto || GetOp() == OP_icallprotoassigned) { + icallNode->SetRetTyIdx(retTyIdx); + } return *icallNode; } diff --git a/src/mapleall/maple_me/src/lfo_dep_test.cpp b/src/mapleall/maple_me/src/lfo_dep_test.cpp index b1273a8fc3..33f19ee452 100644 --- a/src/mapleall/maple_me/src/lfo_dep_test.cpp +++ b/src/mapleall/maple_me/src/lfo_dep_test.cpp @@ -66,6 +66,8 @@ void LfoDepInfo::CreateDoloopInfo(BlockNode *block, DoloopInfo *parent) { case OP_callassigned: case OP_icall: case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: case OP_return: case OP_throw: case OP_asm: diff --git a/src/mapleall/maple_me/src/lmbc_lower.cpp b/src/mapleall/maple_me/src/lmbc_lower.cpp index a155b25fa4..f5893447ba 100644 --- a/src/mapleall/maple_me/src/lmbc_lower.cpp +++ b/src/mapleall/maple_me/src/lmbc_lower.cpp @@ -22,16 +22,12 @@ using namespace std; PregIdx LMBCLowerer::GetSpecialRegFromSt(const MIRSymbol *sym) { MIRStorageClass storageClass = sym->GetStorageClass(); PregIdx specreg = 0; - if (storageClass == kScAuto || storageClass == kScFormal) { + if (storageClass == kScAuto) { CHECK(sym->GetStIndex() < memlayout->sym_alloc_table.size(), "index out of range in LMBCLowerer::GetSpecialRegFromSt"); SymbolAlloc symalloc = memlayout->sym_alloc_table[sym->GetStIndex()]; - if (symalloc.mem_segment->kind == MS_upformal || symalloc.mem_segment->kind == MS_formal || - symalloc.mem_segment->kind == MS_FPbased) { + if (symalloc.mem_segment->kind == MS_FPbased) { specreg = -kSregFp; - } else if (symalloc.mem_segment->kind == MS_actual || - symalloc.mem_segment->kind == MS_SPbased) { - specreg = -kSregSp; } else { CHECK_FATAL(false, "LMBCLowerer::LowerDread: bad memory layout for local variable"); } @@ -46,6 +42,7 @@ PregIdx LMBCLowerer::GetSpecialRegFromSt(const MIRSymbol *sym) { BaseNode *LMBCLowerer::LowerAddrof(AddrofNode *expr) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(expr->GetStIdx()); + symbol->ResetIsDeleted(); int32 offset = 0; if (expr->GetFieldID() != 0) { MIRStructType *structty = static_cast(symbol->GetType()); @@ -66,6 +63,7 @@ BaseNode *LMBCLowerer::LowerAddrof(AddrofNode *expr) { BaseNode *LMBCLowerer::LowerDread(AddrofNode *expr) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(expr->GetStIdx()); + symbol->ResetIsDeleted(); PrimType symty = symbol->GetType()->GetPrimType(); int32 offset = 0; if (expr->GetFieldID() != 0) { @@ -96,20 +94,22 @@ BaseNode *LMBCLowerer::LowerDread(AddrofNode *expr) { BaseNode *LMBCLowerer::LowerDreadoff(DreadoffNode *dreadoff) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dreadoff->stIdx); + symbol->ResetIsDeleted(); if (!symbol->LMBCAllocateOffSpecialReg()) { return dreadoff; } + PrimType symty = symbol->GetType()->GetPrimType(); PregIdx spcreg = GetSpecialRegFromSt(symbol); if (spcreg == -kSregFp) { CHECK_FATAL(symbol->IsLocal(), "load from fp non local?"); - IreadFPoffNode *ireadoff = mirBuilder->CreateExprIreadFPoff( - dreadoff->GetPrimType(), memlayout->sym_alloc_table[symbol->GetStIndex()].offset + dreadoff->offset); + IreadFPoffNode *ireadoff = mirBuilder->CreateExprIreadFPoff(symty, + memlayout->sym_alloc_table[symbol->GetStIndex()].offset + dreadoff->offset); return ireadoff; } else { BaseNode *rrn = mirBuilder->CreateExprRegread(LOWERED_PTR_TYPE, spcreg); SymbolAlloc &symalloc = symbol->IsLocal() ? memlayout->sym_alloc_table[symbol->GetStIndex()] : globmemlayout->sym_alloc_table[symbol->GetStIndex()]; - IreadoffNode *ireadoff = mirBuilder->CreateExprIreadoff(dreadoff->GetPrimType(), symalloc.offset + dreadoff->offset, rrn); + IreadoffNode *ireadoff = mirBuilder->CreateExprIreadoff(symty, symalloc.offset + dreadoff->offset, rrn); return ireadoff; } } @@ -129,14 +129,14 @@ static MIRType *GetPointedToType(const MIRPtrType *pointerty) { BaseNode *LMBCLowerer::LowerIread(IreadNode *expr) { int32 offset = 0; + MIRPtrType *ptrType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(expr->GetTyIdx())); + MIRType *type = ptrType->GetPointedType(); if (expr->GetFieldID() != 0) { - MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(expr->GetTyIdx()); - MIRStructType *structty = - static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(type)->GetPointedTyIdx())); + MIRStructType *structty = static_cast(type); offset = becommon->GetFieldOffset(*structty, expr->GetFieldID()).first; + type = structty->GetFieldType(expr->GetFieldID()); } - BaseNode *ireadoff = mirBuilder->CreateExprIreadoff(expr->GetPrimType(), offset, expr->Opnd(0)); + BaseNode *ireadoff = mirBuilder->CreateExprIreadoff(type->GetPrimType(), offset, expr->Opnd(0)); return ireadoff; } @@ -165,6 +165,7 @@ BaseNode *LMBCLowerer::LowerExpr(BaseNode *expr) { return LowerAddrof(static_cast(expr)); case OP_addrofoff: { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(static_cast(expr)->stIdx); + symbol->ResetIsDeleted(); CHECK_FATAL(!symbol->LMBCAllocateOffSpecialReg(), "LMBCLowerer:: illegal addrofoff instruction"); break; @@ -199,6 +200,7 @@ void LMBCLowerer::LowerAggDassign(const DassignNode *dsnode, MIRType *lhsty, // generate lhs address expression BaseNode *lhs = nullptr; MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dsnode->GetStIdx()); + symbol->ResetIsDeleted(); if (!symbol->LMBCAllocateOffSpecialReg()) { lhs = mirBuilder->CreateExprDreadoff(OP_addrofoff, LOWERED_PTR_TYPE, *symbol, offset); } else { @@ -218,6 +220,7 @@ void LMBCLowerer::LowerAggDassign(const DassignNode *dsnode, MIRType *lhsty, void LMBCLowerer::LowerDassign(DassignNode *dsnode, BlockNode *newblk) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dsnode->GetStIdx()); + symbol->ResetIsDeleted(); MIRType *symty = symbol->GetType(); int32 offset = 0; if (dsnode->GetFieldID() != 0) { @@ -259,6 +262,7 @@ void LMBCLowerer::LowerDassign(DassignNode *dsnode, BlockNode *newblk) { void LMBCLowerer::LowerDassignoff(DassignoffNode *dsnode, BlockNode *newblk) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dsnode->stIdx); + symbol->ResetIsDeleted(); CHECK_FATAL(dsnode->Opnd(0)->GetPrimType() != PTY_agg, "LowerDassignoff: agg primitive type NYI"); BaseNode *rhs = LowerExpr(dsnode->Opnd(0)); if (!symbol->LMBCAllocateOffSpecialReg()) { @@ -334,6 +338,9 @@ void LMBCLowerer::LowerIassign(IassignNode *iassign, BlockNode *newblk) { } if (iassign->GetRHS()->GetPrimType() != PTY_agg) { PrimType ptypused = type->GetPrimType(); + if (ptypused == PTY_agg) { + ptypused = iassign->GetRHS()->GetPrimType(); + } IassignoffNode *iassignoff = mirBuilder->CreateStmtIassignoff(ptypused, offset, iassign->addrExpr, @@ -347,15 +354,20 @@ void LMBCLowerer::LowerIassign(IassignNode *iassign, BlockNode *newblk) { // called only if the return has > 1 operand; assume prior lowering already // converted any return of structs to be via fake parameter void LMBCLowerer::LowerReturn(NaryStmtNode *retNode, BlockNode *newblk) { - CHECK_FATAL(retNode->NumOpnds() <= 2, "LMBCLowerer::LowerReturn: more than 2 return values NYI"); - for (int i = 0; i < retNode->NumOpnds(); i++) { - CHECK_FATAL(retNode->Opnd(i)->GetPrimType() != PTY_agg, - "LMBCLowerer::LowerReturn: return of aggregate needs to be handled first"); - // insert regassign for the returned value - BaseNode *rhs = LowerExpr(retNode->Opnd(i)); - RegassignNode *regasgn = mirBuilder->CreateStmtRegassign(rhs->GetPrimType(), - i == 0 ? -kSregRetval0 : -kSregRetval1, - rhs); + if (retNode->Opnd(0)->GetPrimType() != PTY_agg) { + CHECK_FATAL(retNode->NumOpnds() <= 2, "LMBCLowerer::LowerReturn: more than 2 return values NYI"); + for (int i = 0; i < retNode->NumOpnds(); i++) { + // insert regassign for the returned value + PrimType ptyp = retNode->Opnd(i)->GetPrimType(); + BaseNode *rhs = LowerExpr(retNode->Opnd(i)); + RegassignNode *regasgn = mirBuilder->CreateStmtRegassign(ptyp, + i == 0 ? -kSregRetval0 : -kSregRetval1, + rhs); + newblk->AddStatement(regasgn); + } + } else { // handle return of small struct using only %%retval0 + BaseNode *rhs = LowerExpr(retNode->Opnd(0)); + RegassignNode *regasgn = mirBuilder->CreateStmtRegassign(PTY_agg, -kSregRetval0, rhs); newblk->AddStatement(regasgn); } retNode->GetNopnd().clear(); // remove the return operands @@ -363,178 +375,6 @@ void LMBCLowerer::LowerReturn(NaryStmtNode *retNode, BlockNode *newblk) { newblk->AddStatement(retNode); } -MIRFuncType *LMBCLowerer::FuncTypeFromFuncPtrExpr(BaseNode *x) { - MIRFuncType *res = nullptr; - switch (x->GetOpCode()) { - case OP_regread: { - RegreadNode *regread = static_cast(x); - MIRPreg *preg = func->GetPregTab()->PregFromPregIdx(regread->GetRegIdx()); - // see if it is promoted from a symbol - if (preg->GetOp() == OP_dread) { - const MIRSymbol *symbol = preg->rematInfo.sym; - MIRType *mirType = symbol->GetType(); - if (preg->fieldID != 0) { - MIRStructType *structty = static_cast(mirType); - FieldPair thepair = structty->TraverseToField(preg->fieldID); - mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - if (res != nullptr) { - break; - } - } - // check if a formal promoted to preg - for (FormalDef &formalDef : func->GetFormalDefVec()) { - if (!formalDef.formalSym->IsPreg()) { - continue; - } - if (formalDef.formalSym->GetPreg() == preg) { - MIRType *mirType = formalDef.formalSym->GetType(); - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - break; - } - } - break; - } - case OP_dread: { - DreadNode *dread = static_cast(x); - MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); - MIRType *mirType = symbol->GetType(); - if (dread->GetFieldID() != 0) { - MIRStructType *structty = static_cast(mirType); - FieldPair thepair = structty->TraverseToField(dread->GetFieldID()); - mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - break; - } - case OP_iread: { - IreadNode *iread = static_cast(x); - MIRPtrType *ptrType = static_cast(iread->GetType()); - MIRType *mirType = ptrType->GetPointedType(); - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - break; - } - case OP_addroffunc: { - AddroffuncNode *addrofFunc = static_cast(x); - PUIdx puIdx = addrofFunc->GetPUIdx(); - MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); - res = f->GetMIRFuncType(); - break; - } - case OP_retype: { - MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(x)->GetTyIdx()); - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - if (res == nullptr) { - res = FuncTypeFromFuncPtrExpr(x->Opnd(0)); - } - break; - } - case OP_select: { - res = FuncTypeFromFuncPtrExpr(x->Opnd(1)); - if (res == nullptr) { - res = FuncTypeFromFuncPtrExpr(x->Opnd(2)); - } - break; - } - default: CHECK_FATAL(false, "LMBCLowerer::FuncTypeFromFuncPtrExpr: NYI"); - } - return res; -} - -void LMBCLowerer::LowerCall(NaryStmtNode *naryStmt, BlockNode *newblk) { - // go through each parameter - uint32 i = 0; - if (naryStmt->GetOpCode() == OP_icall || naryStmt->GetOpCode() == OP_icallassigned) { - i = 1; - } - ParmLocator parmlocator; - for (; i < naryStmt->NumOpnds(); i++) { - BaseNode *opnd = naryStmt->Opnd(i); - MIRType *ty = nullptr; - // get ty for this parameter - if (opnd->GetPrimType() != PTY_agg) { - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(static_cast(opnd->GetPrimType())); - } else { - Opcode opnd_opcode = opnd->GetOpCode(); - CHECK_FATAL(opnd_opcode == OP_dread || opnd_opcode == OP_iread, ""); - if (opnd_opcode == OP_dread) { - AddrofNode *dread = static_cast(opnd); - MIRSymbol *sym = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx()); - if (dread->GetFieldID() != 0) { - CHECK_FATAL(ty->IsStructType(), ""); - FieldPair thepair = static_cast(ty)->TraverseToField(dread->GetFieldID()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - } else { // OP_iread - IreadNode *iread = static_cast(opnd); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread->GetTyIdx()); - CHECK_FATAL(ty->GetKind() == kTypePointer, ""); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(ty)->GetPointedTyIdx()); - if (iread->GetFieldID() != 0) { - CHECK_FATAL(ty->IsStructType(), ""); - FieldPair thepair = static_cast(ty)->TraverseToField(iread->GetFieldID()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - } - } - PLocInfo ploc; - parmlocator.LocateNextParm(ty, ploc); - if (opnd->GetPrimType() != PTY_agg) { - IassignFPoffNode *iass = mirBuilder->CreateStmtIassignFPoff(OP_iassignspoff, - opnd->GetPrimType(), - ploc.memoffset, - LowerExpr(opnd)); - newblk->AddStatement(iass); - } else { - BlkassignoffNode *bass = - mirModule->CurFuncCodeMemPool()->New(ploc.memoffset, ploc.memsize); - bass->SetAlign(std::min(ty->GetAlign(), 8u)); - bass->SetBOpnd(mirBuilder->CreateExprRegread(LOWERED_PTR_TYPE, -kSregSp), 0); - // the operand is either OP_dread or OP_iread; use its address instead - if (opnd->GetOpCode() == OP_dread) { - opnd->SetOpCode(OP_addrof); - } else { - opnd->SetOpCode(OP_iaddrof); - } - opnd->SetPrimType(LOWERED_PTR_TYPE); - bass->SetBOpnd(LowerExpr(opnd), 1); - newblk->AddStatement(bass); - } - } - BaseNode *opnd0 = nullptr; - if (naryStmt->GetOpCode() == OP_icall || naryStmt->GetOpCode() == OP_icallassigned) { - opnd0 = naryStmt->Opnd(0); - naryStmt->GetNopnd().clear(); // remove the call operands - // convert to OP_icallproto by finding the function prototype and record in stmt - naryStmt->SetOpCode(OP_icallproto); - MIRFuncType *funcType = FuncTypeFromFuncPtrExpr(opnd0); - CHECK_FATAL(funcType != nullptr, "LMBCLowerer::LowerCall: cannot find prototype for icall"); - static_cast(naryStmt)->SetRetTyIdx(funcType->GetTypeIndex()); - // add back the function pointer operand - naryStmt->GetNopnd().push_back(LowerExpr(opnd0)); - naryStmt->SetNumOpnds(1); - } else { - naryStmt->GetNopnd().clear(); // remove the call operands - naryStmt->SetNumOpnds(0); - } - newblk->AddStatement(naryStmt); -} - BlockNode *LMBCLowerer::LowerBlock(BlockNode *block) { BlockNode *newblk = mirModule->CurFuncCodeMemPool()->New(); if (!block->GetFirst()) { @@ -569,10 +409,6 @@ BlockNode *LMBCLowerer::LowerBlock(BlockNode *block) { } else { LowerReturn(retNode, newblk); } - } - case OP_call: - case OP_icall: { - LowerCall(static_cast(stmt), newblk); break; } default: { @@ -587,29 +423,19 @@ BlockNode *LMBCLowerer::LowerBlock(BlockNode *block) { return newblk; } -void LMBCLowerer::LoadFormalsAssignedToPregs() { - // go through each formals - for (int32 i = func->GetFormalDefVec().size()-1; i >= 0; i--) { - MIRSymbol *formalSt = func->GetFormalDefVec()[i].formalSym; - if (formalSt->GetSKind() != kStPreg) { - continue; +void LMBCLowerer::LowerFunction() { + // set extern global vars' isDeleted field; will reset when visited + MapleVector::const_iterator sit = mirModule->GetSymbolDefOrder().begin(); + for (; sit != mirModule->GetSymbolDefOrder().end(); ++sit) { + MIRSymbol *s = GlobalTables::GetGsymTable().GetSymbolFromStidx(sit->Idx()); + if (s->GetSKind() == kStVar && s->GetStorageClass() == kScExtern && !s->HasPotentialAssignment()) { + s->SetIsDeleted(); } - MIRPreg *preg = formalSt->GetPreg(); - uint32 stindex = formalSt->GetStIndex(); - PrimType pty = formalSt->GetType()->GetPrimType(); - IreadFPoffNode *ireadfpoff = mirBuilder->CreateExprIreadFPoff(pty, - memlayout->sym_alloc_table[stindex].offset); - RegassignNode *rass = mirBuilder->CreateStmtRegassign(pty, - func->GetPregTab()->GetPregIdxFromPregno(preg->GetPregNo()), ireadfpoff); - func->GetBody()->InsertFirst(rass); } -} -void LMBCLowerer::LowerFunction() { BlockNode *origbody = func->GetBody(); BlockNode *newbody = LowerBlock(origbody); func->SetBody(newbody); - LoadFormalsAssignedToPregs(); } } // namespace maple diff --git a/src/mapleall/maple_me/src/lmbc_memlayout.cpp b/src/mapleall/maple_me/src/lmbc_memlayout.cpp index e740c5d13f..b32acae493 100644 --- a/src/mapleall/maple_me/src/lmbc_memlayout.cpp +++ b/src/mapleall/maple_me/src/lmbc_memlayout.cpp @@ -13,146 +13,40 @@ * See the MulanPSL - 2.0 for more details. */ -// For each function being compiled, lay out its parameters, return values and -// local variables on its stack frame. This involves determining how parameters -// and return values are passed from analyzing their types. -// -// Allocate all the global variables within the global memory block which is -// addressed via offset from the global pointer GP during execution. Allocate -// this block pointed to by mirModule.globalBlkMap and perform the static -// initializations. +// For each function being compiled, lay out its local variables on its stack +// frame. Allocate all the global variables within the global memory block +// which is addressed via offset from the global pointer GP during execution. +// Allocate this block pointed to by mirModule.globalBlkMap. #include "lmbc_memlayout.h" #include "mir_symbol.h" namespace maple { -uint32 LMBCMemLayout::FindLargestActualArea(StmtNode *stmt, int &maxActualSize) { - if (!stmt) { - return maxActualSize; - } - Opcode opcode = stmt->op; - switch (opcode) { - case OP_block: { - BlockNode *blcknode = static_cast(stmt); - for (StmtNode &s : blcknode->GetStmtNodes()) { - FindLargestActualArea(&s, maxActualSize); - } - break; - } - case OP_if: { - IfStmtNode *ifnode = static_cast(stmt); - FindLargestActualArea(ifnode->GetThenPart(), maxActualSize); - FindLargestActualArea(ifnode->GetElsePart(), maxActualSize); - break; - } - case OP_doloop: { - FindLargestActualArea(static_cast(stmt)->GetDoBody(), maxActualSize); - break; - } - case OP_dowhile: - case OP_while: - FindLargestActualArea(static_cast(stmt)->GetBody(), maxActualSize); - break; - case OP_call: - case OP_icall: - case OP_intrinsiccall: { - ParmLocator parmlocator; // instantiate a parm locator - NaryStmtNode *callstmt = static_cast(stmt); - for (uint32 i = 0; i < callstmt->NumOpnds(); i++) { - BaseNode *opnd = callstmt->Opnd(i); - CHECK_FATAL(opnd->GetPrimType() != PTY_void, ""); - MIRType *ty = nullptr; - if (opnd->GetPrimType() != PTY_agg) { - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(opnd->GetPrimType())); - } else { - Opcode opnd_opcode = opnd->GetOpCode(); - CHECK_FATAL(opnd_opcode == OP_dread || opnd_opcode == OP_iread, ""); - if (opnd_opcode == OP_dread) { - AddrofNode *dread = static_cast(opnd); - MIRSymbol *sym = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx()); - if (dread->GetFieldID() != 0) { - CHECK_FATAL(ty->IsStructType(), "expect struct or class or union"); - FieldPair thepair = - static_cast(ty)->TraverseToField(dread->GetFieldID()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - } else { // OP_iread - IreadNode *iread = static_cast(opnd); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread->GetTyIdx()); - CHECK_FATAL(ty->GetKind() == kTypePointer, ""); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(ty)->GetPointedTyIdx()); - if (iread->GetFieldID() != 0) { - CHECK_FATAL(ty->IsStructType(), "expect struct or class or union"); - FieldPair thepair = - static_cast(ty)->TraverseToField(iread->GetFieldID()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - } - } - PLocInfo ploc; - parmlocator.LocateNextParm(ty, ploc); - maxActualSize = std::max(maxActualSize, ploc.memoffset + ploc.memsize); - maxActualSize = maplebe::RoundUp(maxActualSize, GetPrimTypeSize(PTY_ptr)); - } - break; - } - default: - return maxActualSize; - } - maxActualSize = maplebe::RoundUp(maxActualSize, GetPrimTypeSize(PTY_ptr)); - return maxActualSize; -} - -// go over all outgoing calls in the function body and get the maximum space -// needed for storing the actuals based on the actual parameters and the ABI; -// this assumes that all nesting of statements has been removed, so that all -// the statements are at only one block level -uint32 LMBCMemLayout::FindLargestActualArea(void) { - int32 maxActualSize = 0; - FindLargestActualArea(func->GetBody(), maxActualSize); - return static_cast(maxActualSize); -} +constexpr size_t kVarargSaveAreaSize = 192; void LMBCMemLayout::LayoutStackFrame(void) { - MIRSymbol *sym = nullptr; - // go through formal parameters - ParmLocator parmlocator; // instantiate a parm locator - PLocInfo ploc; - for (uint32 i = 0; i < func->GetFormalDefVec().size(); i++) { - FormalDef formalDef = func->GetFormalDefAt(i); - sym = formalDef.formalSym; - MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(formalDef.formalTyIdx); - parmlocator.LocateNextParm(ty, ploc); - uint32 stindex = sym->GetStIndex(); - // always passed in memory, so allocate in seg_upformal - sym_alloc_table[stindex].mem_segment = &seg_upformal; - seg_upformal.size = maplebe::RoundUp(seg_upformal.size, ty->GetAlign()); - sym_alloc_table[stindex].offset = seg_upformal.size; - seg_upformal.size += ty->GetSize(); - seg_upformal.size = maplebe::RoundUp(seg_upformal.size, GetPrimTypeSize(PTY_ptr)); + if (func->IsVarargs()) { + seg_FPbased.size -= kVarargSaveAreaSize; } - // allocate seg_formal in seg_FPbased - seg_formal.how_alloc.mem_segment = &seg_FPbased; - seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, GetPrimTypeSize(PTY_ptr)); - seg_FPbased.size -= seg_formal.size; - seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, GetPrimTypeSize(PTY_ptr)); - seg_formal.how_alloc.offset = seg_FPbased.size; - // allocate the local variables uint32 symtabsize = func->GetSymTab()->GetSymbolTableSize(); for (uint32 i = 0; i < symtabsize; i++) { - sym = func->GetSymTab()->GetSymbolFromStIdx(i); + MIRSymbol *sym = func->GetSymTab()->GetSymbolFromStIdx(i); if (!sym) { continue; } if (sym->IsDeleted()) { continue; } + if (sym->GetStorageClass() == kScPstatic && sym->LMBCAllocateOffSpecialReg()) { + uint32 stindex = sym->GetStIndex(); + sym_alloc_table[stindex].mem_segment = seg_GPbased; + seg_GPbased->size = maplebe::RoundUp(seg_GPbased->size, sym->GetType()->GetAlign()); + sym_alloc_table[stindex].offset = seg_GPbased->size; + seg_GPbased->size += sym->GetType()->GetSize(); + } if (sym->GetStorageClass() != kScAuto) { continue; } @@ -162,160 +56,10 @@ void LMBCMemLayout::LayoutStackFrame(void) { seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, sym->GetType()->GetAlign()); sym_alloc_table[stindex].offset = seg_FPbased.size; } - seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, GetPrimTypeSize(PTY_ptr)); - - // allocate seg_actual for storing the outgoing parameters; this requires - // going over all outgoing calls and get the maximum space needed for the - // actuals - seg_actual.size = FindLargestActualArea(); - func->SetOutParmSize(seg_actual.size); - - // allocate seg_actual in seg_SPbased - seg_actual.how_alloc.mem_segment = &seg_SPbased; - seg_actual.how_alloc.offset = seg_SPbased.size; - seg_SPbased.size = maplebe::RoundUp(seg_SPbased.size, GetPrimTypeSize(PTY_ptr)); - seg_SPbased.size += seg_actual.size; - seg_SPbased.size = maplebe::RoundUp(seg_SPbased.size, GetPrimTypeSize(PTY_ptr)); -} - -inline uint8 GetU8Const(MIRConst *c) { - MIRIntConst *intconst = static_cast(c); - return static_cast(intconst->GetValue()); -} - -inline uint16 GetU16Const(MIRConst *c) { - MIRIntConst *intconst = static_cast(c); - return static_cast(intconst->GetValue()); -} - -inline uint32 GetU32Const(MIRConst *c) { - MIRIntConst *intconst = static_cast(c); - return static_cast(intconst->GetValue()); -} - -inline uint64 GetU64Const(MIRConst *c) { - MIRIntConst *intconst = static_cast(c); - return static_cast(intconst->GetValue()); -} - -inline uint32 GetF32Const(MIRConst *c) { - MIRFloatConst *floatconst = static_cast(c); - return static_cast(floatconst->GetIntValue()); -} - -inline uint64 GetF64Const(MIRConst *c) { - MIRDoubleConst *doubleconst = static_cast(c); - return static_cast(doubleconst->GetIntValue()); -} - -void GlobalMemLayout::FillScalarValueInMap(uint32 startaddress, PrimType pty, MIRConst *c) { - switch (pty) { - case PTY_u1: - case PTY_u8: - case PTY_i8: { - uint8 *p = &mirModule->GetGlobalBlockMap()[startaddress]; - *p = GetU8Const(c); - break; - } - case PTY_u16: - case PTY_i16: { - uint16 *p = (uint16 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetU16Const(c); - break; - } - case PTY_u32: - case PTY_i32: { - uint32 *p = (uint32 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetU32Const(c); - break; - } - case PTY_u64: - case PTY_i64: { - uint64 *p = (uint64 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetU64Const(c); - break; - } - case PTY_f32: { - uint32 *p = (uint32 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetF32Const(c); - break; - } - case PTY_f64: { - uint64 *p = (uint64 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetF64Const(c); - break; - } - default: - CHECK_FATAL(false, "FillScalarValueInMap: NYI"); - } - return; } -void GlobalMemLayout::FillTypeValueInMap(uint32 startaddress, MIRType *ty, MIRConst *c) { - switch (ty->GetKind()) { - case kTypeScalar: - FillScalarValueInMap(startaddress, ty->GetPrimType(), c); - break; - case kTypeArray: { - MIRArrayType *arraytype = static_cast(ty); - MIRType *elemtype = arraytype->GetElemType(); - int32 elemsize = elemtype->GetSize(); - MIRAggConst *aggconst = static_cast(c); - CHECK_FATAL(aggconst, "FillTypeValueInMap: inconsistent array initialization specification"); - MapleVector &constvec = aggconst->GetConstVec(); - for (MapleVector::iterator it = constvec.begin(); it != constvec.end(); - it++, startaddress += elemsize) { - FillTypeValueInMap(startaddress, elemtype, *it); - } - break; - } - case kTypeStruct: { - MIRStructType *structty = static_cast(ty); - MIRAggConst *aggconst = static_cast(c); - CHECK_FATAL(aggconst, "FillTypeValueInMap: inconsistent struct initialization specification"); - MapleVector &constvec = aggconst->GetConstVec(); - for (uint32 i = 0; i < constvec.size(); i++) { - uint32 fieldID = aggconst->GetFieldIdItem(i); - FieldPair thepair = structty->TraverseToField(fieldID); - MIRType *fieldty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - uint32 offset = be->GetFieldOffset(*structty, fieldID).first; - FillTypeValueInMap(startaddress + offset, fieldty, constvec[i]); - } - break; - } - case kTypeClass: { - MIRClassType *classty = static_cast(ty); - MIRAggConst *aggconst = static_cast(c); - CHECK_FATAL(aggconst, "FillTypeValueInMap: inconsistent class initialization specification"); - MapleVector &constvec = aggconst->GetConstVec(); - for (uint32 i = 0; i < constvec.size(); i++) { - uint32 fieldID = aggconst->GetFieldIdItem(i); - FieldPair thepair = classty->TraverseToField(fieldID); - MIRType *fieldty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - uint32 offset = be->GetFieldOffset(*classty, fieldID).first; - FillTypeValueInMap(startaddress + offset, fieldty, constvec[i]); - } - break; - } - default: - CHECK_FATAL(false, "FillTypeValueInMap: NYI"); - } -} - -void GlobalMemLayout::FillSymbolValueInMap(const MIRSymbol *sym) { - if (sym->GetKonst() == nullptr) { - return; - } - uint32 stindex = sym->GetStIndex(); - CHECK(stindex < sym_alloc_table.size(), - "index out of range in GlobalMemLayout::FillSymbolValueInMap"); - uint32 symaddress = sym_alloc_table[stindex].offset; - FillTypeValueInMap(symaddress, sym->GetType(), sym->GetKonst()); - return; -} - -GlobalMemLayout::GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAllocator *mallocator) : - seg_GPbased(MS_GPbased), sym_alloc_table(mallocator->Adapter()), be(b), mirModule(mod) { +GlobalMemLayout::GlobalMemLayout(MIRModule *mod, MapleAllocator *mallocator) : + seg_GPbased(MS_GPbased), sym_alloc_table(mallocator->Adapter()), mirModule(mod) { uint32 symtabsize = GlobalTables::GetGsymTable().GetSymbolTableSize(); sym_alloc_table.resize(symtabsize); MIRSymbol *sym = nullptr; @@ -329,6 +73,9 @@ GlobalMemLayout::GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAll if (sym->GetStorageClass() != kScGlobal && sym->GetStorageClass() != kScFstatic) { continue; } + if (!sym->LMBCAllocateOffSpecialReg()) { + continue; + } if (sym->GetType()->GetAlign() != curalign) { continue; } @@ -341,152 +88,6 @@ GlobalMemLayout::GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAll } seg_GPbased.size = maplebe::RoundUp(seg_GPbased.size, GetPrimTypeSize(PTY_ptr)); mirModule->SetGlobalMemSize(seg_GPbased.size); - // allocate the memory map for the GP block - mirModule->SetGlobalBlockMap( - static_cast(mirModule->GetMemPool()->Calloc(seg_GPbased.size))); - // perform initialization on globalblkmap - for (uint32 i = 0; i < symtabsize; i++) { - sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(i); - if (!sym) { - continue; - } - if (sym->GetStorageClass() != kScGlobal && sym->GetStorageClass() != kScFstatic) { - continue; - } - } -} - -// LocateNextParm should be called with each parameter in the parameter list -// starting from the beginning, one call per parameter in sequence; it returns -// the information on how each parameter is passed in ploc -void ParmLocator::LocateNextParm(const MIRType *ty, PLocInfo &ploc) { - ploc.memoffset = maplebe::RoundUp(lastMemOffset, 8); - ploc.memsize = ty->GetSize(); - - uint32 rightpad = 0; - parmNum++; - - switch (ty->GetPrimType()) { - case PTY_u1: - case PTY_u8: - case PTY_i8: - case PTY_u16: - case PTY_i16: - rightpad = GetPrimTypeSize(PTY_i32) - ploc.memsize; - break; - case PTY_a32: - case PTY_u32: - case PTY_i32: - case PTY_a64: - case PTY_u64: - case PTY_i64: - case PTY_ptr: - case PTY_ref: -#ifdef DYNAMICLANG - case PTY_simplestr: - case PTY_simpleobj: - case PTY_dynany: - case PTY_dyni32: - case PTY_dynf64: - case PTY_dynstr: - case PTY_dynobj: - case PTY_dynundef: - case PTY_dynbool: - case PTY_dynf32: - case PTY_dynnone: - case PTY_dynnull: -#endif - break; - - case PTY_f32: - rightpad = GetPrimTypeSize(PTY_f64) - ploc.memsize; - break; - case PTY_c64: - case PTY_f64: - case PTY_v2i32: - case PTY_v4i16: - case PTY_v8i8: - case PTY_v2u32: - case PTY_v4u16: - case PTY_v8u8: - case PTY_v2f32: - break; - - case PTY_c128: - case PTY_v2i64: - case PTY_v4i32: - case PTY_v8i16: - case PTY_v16i8: - case PTY_v2u64: - case PTY_v4u32: - case PTY_v8u16: - case PTY_v16u8: - case PTY_v2f64: - case PTY_v4f32: - break; - - case PTY_agg: { - // compute rightpad - int32 paddedSize = maplebe::RoundUp(ploc.memsize, 8); - rightpad = paddedSize - ploc.memsize; - break; - } - default: - CHECK_FATAL(false, "unsupported type"); - } - - lastMemOffset = ploc.memoffset + ploc.memsize + rightpad; - return; -} - -// instantiated with the type of the function return value, it describes how -// the return value is to be passed back to the caller -ReturnMechanism::ReturnMechanism(const MIRType *retty) : fake_first_parm(false) { - switch (retty->GetPrimType()) { - case PTY_u1: - case PTY_u8: - case PTY_i8: - case PTY_u16: - case PTY_i16: - case PTY_a32: - case PTY_u32: - case PTY_i32: - case PTY_a64: - case PTY_u64: - case PTY_i64: - case PTY_f32: - case PTY_f64: -#ifdef DYNAMICLANG - case PTY_simplestr: - case PTY_simpleobj: - case PTY_dynany: - case PTY_dyni32: - case PTY_dynstr: - case PTY_dynobj: -#endif - ptype0 = retty->GetPrimType(); - return; - - case PTY_c64: - case PTY_c128: - fake_first_parm = true; - ptype0 = PTY_a32; - return; - - case PTY_agg: { - uint32 size = retty->GetSize(); - if (size > 4) { - fake_first_parm = true; - ptype0 = PTY_a32; - } else { - ptype0 = PTY_u32; - } - return; - } - - default: - return; - } } } // namespace maple diff --git a/src/mapleall/maple_me/src/me_cfg.cpp b/src/mapleall/maple_me/src/me_cfg.cpp index ad57c5b166..74e2f176c4 100644 --- a/src/mapleall/maple_me/src/me_cfg.cpp +++ b/src/mapleall/maple_me/src/me_cfg.cpp @@ -261,6 +261,7 @@ bool MeCFG::FindUse(const StmtNode &stmt, StIdx stIdx) const { case OP_customcall: case OP_polymorphiccall: case OP_icall: + case OP_icallproto: case OP_intrinsiccall: case OP_xintrinsiccall: case OP_intrinsiccallwithtype: @@ -273,6 +274,7 @@ bool MeCFG::FindUse(const StmtNode &stmt, StIdx stIdx) const { case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_intrinsiccallassigned: case OP_xintrinsiccallassigned: case OP_intrinsiccallwithtypeassigned: diff --git a/src/mapleall/maple_me/src/me_function.cpp b/src/mapleall/maple_me/src/me_function.cpp index 05181df796..a62f1a89a3 100755 --- a/src/mapleall/maple_me/src/me_function.cpp +++ b/src/mapleall/maple_me/src/me_function.cpp @@ -303,7 +303,9 @@ void MeFunction::CloneBBMeStmts(BB &srcBB, BB &destBB, std::map(&stmt); newStmt = irmap->NewInPool(static_cast(icallStmt), icallStmt->GetRetTyIdx(), icallStmt->GetStmtID()); diff --git a/src/mapleall/maple_me/src/me_lower_globals.cpp b/src/mapleall/maple_me/src/me_lower_globals.cpp index c14dd5c764..fdf2df8e3f 100644 --- a/src/mapleall/maple_me/src/me_lower_globals.cpp +++ b/src/mapleall/maple_me/src/me_lower_globals.cpp @@ -185,7 +185,12 @@ void MeLowerGlobals::Run() { MeExpr *addroffuncExpr = irMap->CreateAddroffuncMeExpr(callee.GetPuidx()); auto insertpos = callStmt.GetOpnds().begin(); callStmt.InsertOpnds(insertpos, addroffuncExpr); - IcallMeStmt *icallStmt = irMap->NewInPool(stmt.GetOp() == OP_call ? OP_icall : OP_icallassigned); + IcallMeStmt *icallStmt = nullptr; + if (func.GetMIRModule().IsCModule()) { + icallStmt = irMap->NewInPool(stmt.GetOp() == OP_call ? OP_icallproto : OP_icallprotoassigned); + } else { + icallStmt = irMap->NewInPool(stmt.GetOp() == OP_call ? OP_icall : OP_icallassigned); + } icallStmt->SetIsLive(callStmt.GetIsLive()); icallStmt->SetSrcPos(callStmt.GetSrcPosition()); for (MeExpr *o : callStmt.GetOpnds()) { @@ -193,7 +198,11 @@ void MeLowerGlobals::Run() { } icallStmt->GetMuList()->insert(callStmt.GetMuList()->begin(), callStmt.GetMuList()->end()); icallStmt->GetChiList()->insert(callStmt.GetChiList()->begin(), callStmt.GetChiList()->end()); - icallStmt->SetRetTyIdx(callee.GetReturnTyIdx()); + if (func.GetMIRModule().IsCModule()) { + icallStmt->SetRetTyIdx(callee.GetMIRFuncType()->GetTypeIndex()); + } else { + icallStmt->SetRetTyIdx(callee.GetReturnTyIdx()); + } if (stmt.GetOp() != OP_call) { if (callStmt.NeedDecref()) { icallStmt->EnableNeedDecref(); diff --git a/src/mapleall/maple_me/src/me_phase_manager.cpp b/src/mapleall/maple_me/src/me_phase_manager.cpp index 09a1b64e5a..a0b5419a8e 100644 --- a/src/mapleall/maple_me/src/me_phase_manager.cpp +++ b/src/mapleall/maple_me/src/me_phase_manager.cpp @@ -140,8 +140,8 @@ bool MeFuncPM::PhaseRun(maple::MIRModule &m) { } if (genLMBC) { m.SetFlavor(kFlavorLmbc); + GlobalMemLayout globalMemLayout(&m, &m.GetMPAllocator()); maplebe::BECommon beCommon(m); - GlobalMemLayout globalMemLayout(&beCommon, &m, &m.GetMPAllocator()); maplebe::CGLowerer cgLower(m, beCommon, false, false); cgLower.RegisterBuiltIns(); cgLower.RegisterExternalLibraryFunctions(); @@ -153,14 +153,15 @@ bool MeFuncPM::PhaseRun(maple::MIRModule &m) { cgLower.LowerFunc(*func); MemPool *layoutMp = memPoolCtrler.NewMemPool("layout mempool", true); MapleAllocator layoutAlloc(layoutMp); - LMBCMemLayout localMemLayout(func, &layoutAlloc); + LMBCMemLayout localMemLayout(func, &globalMemLayout.seg_GPbased, &layoutAlloc); localMemLayout.LayoutStackFrame(); LMBCLowerer lmbcLowerer(&m, &beCommon, func, &globalMemLayout, &localMemLayout); lmbcLowerer.LowerFunction(); func->SetFrameSize(localMemLayout.StackFrameSize()); - func->SetUpFormalSize(localMemLayout.UpformalSize()); memPoolCtrler.DeleteMemPool(layoutMp); } + globalMemLayout.seg_GPbased.size = maplebe::RoundUp(globalMemLayout.seg_GPbased.size, GetPrimTypeSize(PTY_ptr)); + m.SetGlobalMemSize(globalMemLayout.seg_GPbased.size); // output .lmbc BinaryMplt binMplt(m); std::string modFileName = m.GetFileName(); diff --git a/src/mapleall/maple_me/src/me_rc_lowering.cpp b/src/mapleall/maple_me/src/me_rc_lowering.cpp index 1c7319e18b..131ebbdd2a 100644 --- a/src/mapleall/maple_me/src/me_rc_lowering.cpp +++ b/src/mapleall/maple_me/src/me_rc_lowering.cpp @@ -1145,6 +1145,7 @@ void RCLowering::HandleArguments() { firstBB->InsertMeStmtBefore(firstMeStmt, incCall); } sym->SetLocalRefVar(); + mirFunc->GetFormalDefVec()[i].formalAttrs.SetAttr(ATTR_localrefvar); for (auto *stmt : rets) { std::vector opnds = { argVar }; diff --git a/src/mapleall/maple_me/src/me_rename2preg.cpp b/src/mapleall/maple_me/src/me_rename2preg.cpp index 9549dff004..eddc9704b9 100644 --- a/src/mapleall/maple_me/src/me_rename2preg.cpp +++ b/src/mapleall/maple_me/src/me_rename2preg.cpp @@ -317,6 +317,7 @@ void SSARename2Preg::Rename2PregStmt(MeStmt *stmt) { case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_intrinsiccallassigned: case OP_xintrinsiccallassigned: case OP_intrinsiccallwithtypeassigned: { diff --git a/src/mapleall/maple_me/src/me_side_effect.cpp b/src/mapleall/maple_me/src/me_side_effect.cpp index 67dea87820..52fcda8516 100644 --- a/src/mapleall/maple_me/src/me_side_effect.cpp +++ b/src/mapleall/maple_me/src/me_side_effect.cpp @@ -933,6 +933,7 @@ bool IpaSideEffect::UpdateSideEffectWithStmt(MeStmt &meStmt, case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_superclasscallassigned: case OP_asm: { hasPrivateDef = hasThrException = true; @@ -959,7 +960,8 @@ bool IpaSideEffect::UpdateSideEffectWithStmt(MeStmt &meStmt, case OP_interfaceicall: case OP_customcall: case OP_polymorphiccall: - case OP_icall: { + case OP_icall: + case OP_icallproto: { hasPrivateDef = hasThrException = true; SetHasDef(); for (size_t i = 0; i < meStmt.NumMeStmtOpnds(); ++i) { diff --git a/src/mapleall/maple_me/src/me_stmt_pre.cpp b/src/mapleall/maple_me/src/me_stmt_pre.cpp index d50e3c5371..3f5d2bff57 100755 --- a/src/mapleall/maple_me/src/me_stmt_pre.cpp +++ b/src/mapleall/maple_me/src/me_stmt_pre.cpp @@ -967,7 +967,9 @@ void MeStmtPre::BuildWorkListBB(BB *bb) { break; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { auto &icallMeStmt = static_cast(stmt); VersionStackChiListUpdate(*icallMeStmt.GetChiList()); break; diff --git a/src/mapleall/maple_me/src/pme_emit.cpp b/src/mapleall/maple_me/src/pme_emit.cpp index 227cb6a761..52e1df6beb 100755 --- a/src/mapleall/maple_me/src/pme_emit.cpp +++ b/src/mapleall/maple_me/src/pme_emit.cpp @@ -485,10 +485,12 @@ StmtNode* PreMeEmitter::EmitPreMeStmt(MeStmt *mestmt, BaseNode *parent) { return callnode; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { IcallMeStmt *icallMeStmt = static_cast (mestmt); IcallNode *icallnode = - codeMP->New(*codeMPAlloc, OP_icallassigned, icallMeStmt->GetRetTyIdx()); + codeMP->New(*codeMPAlloc, OP_icallprotoassigned, icallMeStmt->GetRetTyIdx()); for (uint32 i = 0; i < icallMeStmt->GetOpnds().size(); i++) { icallnode->GetNopnd().push_back(EmitPreMeExpr(icallMeStmt->GetOpnd(i), icallnode)); } @@ -509,6 +511,9 @@ StmtNode* PreMeEmitter::EmitPreMeStmt(MeStmt *mestmt, BaseNode *parent) { icallnode->SetRetTyIdx(TyIdx(preg->GetPrimType())); } } + if (mestmt->GetOp() == OP_icallproto || mestmt->GetOp() == OP_icallprotoassigned) { + icallnode->SetRetTyIdx(icallMeStmt->GetRetTyIdx()); + } icallnode->CopySafeRegionAttr(mestmt->GetStmtAttr()); icallnode->SetOriginalID(mestmt->GetOriginalId()); PreMeStmtExtensionMap[icallnode->GetStmtID()] = pmeExt; diff --git a/src/mapleall/maple_me/src/ssa_devirtual.cpp b/src/mapleall/maple_me/src/ssa_devirtual.cpp index 15a609e427..f46e8e06ce 100644 --- a/src/mapleall/maple_me/src/ssa_devirtual.cpp +++ b/src/mapleall/maple_me/src/ssa_devirtual.cpp @@ -534,7 +534,9 @@ void SSADevirtual::TraversalMeStmt(MeStmt &meStmt) { break; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { auto *icallMeStmt = static_cast(&meStmt); const MapleVector &opnds = icallMeStmt->GetOpnds(); for (size_t i = 0; i < opnds.size(); ++i) { diff --git a/src/mapleall/maple_me/src/ssa_pre.cpp b/src/mapleall/maple_me/src/ssa_pre.cpp index ceff080daa..a082b80b9f 100644 --- a/src/mapleall/maple_me/src/ssa_pre.cpp +++ b/src/mapleall/maple_me/src/ssa_pre.cpp @@ -1666,6 +1666,7 @@ void SSAPre::BuildWorkListStmt(MeStmt &stmt, uint32 seqStmt, bool isRebuilt, MeE case OP_customcall: case OP_polymorphiccall: case OP_icall: + case OP_icallproto: case OP_callassigned: case OP_virtualcallassigned: case OP_virtualicallassigned: @@ -1675,6 +1676,7 @@ void SSAPre::BuildWorkListStmt(MeStmt &stmt, uint32 seqStmt, bool isRebuilt, MeE case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_asm: { auto *naryMeStmt = static_cast(meStmt); const MapleVector &opnds = naryMeStmt->GetOpnds(); diff --git a/src/mapleall/mpl2mpl/src/constantfold.cpp b/src/mapleall/mpl2mpl/src/constantfold.cpp index f84c351bd8..1b296c1de7 100644 --- a/src/mapleall/mpl2mpl/src/constantfold.cpp +++ b/src/mapleall/mpl2mpl/src/constantfold.cpp @@ -162,6 +162,8 @@ StmtNode *ConstantFold::Simplify(StmtNode *node) { return SimplifyNary(static_cast(node)); case OP_icall: case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: return SimplifyIcall(static_cast(node)); case OP_asm: return SimplifyAsm(static_cast(node)); @@ -2628,8 +2630,8 @@ StmtNode *ConstantFold::SimplifyIcall(IcallNode *node) { AddroffuncNode *addrofNode = static_cast(node->GetNopndAt(0)); CallNode *callNode = mirModule->CurFuncCodeMemPool()->New(*mirModule, - node->GetOpCode() == OP_icall ? OP_call : OP_callassigned); - if (node->GetOpCode() == OP_icallassigned) { + (node->GetOpCode() == OP_icall || node->GetOpCode() == OP_icallproto) ? OP_call : OP_callassigned); + if (node->GetOpCode() == OP_icallassigned || node->GetOpCode() == OP_icallprotoassigned) { callNode->SetReturnVec(node->GetReturnVec()); } callNode->SetPUIdx(addrofNode->GetPUIdx()); -- Gitee From 608b72faac835815b357448c6176cb31e86f746d Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:44 -0700 Subject: [PATCH 016/124] Fred's Fixed determination logic of when there is fake parameter for returning struct, where x8 is also used to pass the fake parameter --- .../maple_be/src/cg/aarch64/aarch64_args.cpp | 4 ++-- .../src/cg/aarch64/aarch64_call_conv.cpp | 11 ++++++----- .../maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 18 ++++++++++++------ .../src/cg/aarch64/aarch64_memlayout.cpp | 4 ++-- 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 7962d54991..0ff53f6e5b 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -38,7 +38,7 @@ void AArch64MoveRegArgs::CollectRegisterArgs(std::map &argsL uint32 start = 0; if (numFormal) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsFirstArgReturn()) { + if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16ByteSize) { start = 1; @@ -436,7 +436,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsFirstArgReturn()) { + if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp index 5a355837d1..a838c30d1f 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp @@ -306,18 +306,18 @@ int32 AArch64CallConvImpl::LocateNextParm(MIRType &mirType, CCLocInfo &pLoc, boo if (size == 0) { /* For return struct size 0 there is no return value. */ return 0; - } else if (size > k16ByteSize) { - /* For return struct size > 16 bytes the pointer returns in x8. */ - pLoc.reg0 = R8; - return kSizeOfPtr; } + /* For return struct size > 16 bytes the pointer returns in x8. */ + pLoc.reg0 = R8; + return kSizeOfPtr; +#if 0 /* For return struct size less or equal to 16 bytes, the values * are returned in register pairs. * Check for pure float struct. */ AArch64ArgumentClass classes[kMaxRegCount] = { kAArch64NoClass }; uint32 fpSize; - MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(beCommon.GetFuncReturnType(*func)); + MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); uint32 numRegs = static_cast(ClassifyAggregate(beCommon, *retType, classes, sizeof(classes), fpSize)); if (classes[0] == kAArch64FloatClass) { CHECK_FATAL(numRegs <= kMaxRegCount, "LocateNextParm: illegal number of regs"); @@ -334,6 +334,7 @@ int32 AArch64CallConvImpl::LocateNextParm(MIRType &mirType, CCLocInfo &pLoc, boo } return 0; } +#endif } } uint64 typeSize = beCommon.GetTypeSize(mirType.GetTypeIndex()); 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 555e7548c0..8e6a35037e 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8064,6 +8064,17 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo std::set specialArgs; SelectParmListPreprocess(naryNode, i, specialArgs); bool specialArg = false; + bool firstArgReturn = false; + MIRFunction *callee = nullptr; + if (dynamic_cast(&naryNode) != nullptr) { + auto calleePuIdx = static_cast(naryNode).GetPUIdx(); + callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + firstArgReturn = callee->IsFirstArgReturn(); + } else if (naryNode.GetOpCode() == OP_icallproto) { + IcallNode *icallnode = &static_cast(naryNode); + MIRFuncType *funcType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallnode->GetRetTyIdx())); + firstArgReturn = funcType->FirstArgReturn(); + } BB *curBBrecord = GetCurBB(); BB *tmpBB = nullptr; if (!specialArgs.empty()) { @@ -8085,11 +8096,6 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); - MIRFunction *callee = nullptr; - if (dynamic_cast(&naryNode) != nullptr) { - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); - } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } @@ -8154,7 +8160,7 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo } expRegOpnd = static_cast(opnd); - if ((pnum == 0) && (SelectParmListGetStructReturnSize(naryNode) > k16ByteSize)) { + if ((pnum == 0) && firstArgReturn) { parmLocator.InitCCLocInfo(ploc); ploc.reg0 = R8; } else { diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp index 71f57d89ea..de95e9be33 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp @@ -210,7 +210,7 @@ void AArch64MemLayout::LayoutFormalParams() { AArch64SymbolAlloc *symLoc = memAllocator->GetMemPool()->New(); SetSymAllocInfo(stIndex, *symLoc); if (i == 0) { - if (mirFunction->IsFirstArgReturn()) { + if (mirFunction->IsReturnStruct() && mirFunction->IsFirstArgReturn()) { symLoc->SetMemSegment(GetSegArgsRegPassed()); symLoc->SetOffset(GetSegArgsRegPassed().GetSize()); TyIdx tyIdx = mirFunction->GetFuncRetStructTyIdx(); @@ -395,7 +395,7 @@ void AArch64MemLayout::LayoutReturnRef(std::vector &returnDelays, void AArch64MemLayout::LayoutActualParams() { for (size_t i = 0; i < mirFunction->GetFormalCount(); ++i) { if (i == 0) { - if (mirFunction->IsReturnStruct()) { + if (mirFunction->IsReturnStruct() && mirFunction->IsFirstArgReturn()) { continue; } } -- Gitee From 896d842d68684164e018eae0ca3e1b5336ed580a Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:53:00 -0700 Subject: [PATCH 017/124] Remove unneeded fp def. Turn on tailcall. no unneeded pro/epilog. --- .../maple_be/include/cg/aarch64/aarch64_color_ra.h | 1 + src/mapleall/maple_be/include/cg/cgfunc.h | 9 +++++++++ .../maple_be/src/cg/aarch64/aarch64_color_ra.cpp | 6 ++++++ .../maple_be/src/cg/aarch64/aarch64_proepilog.cpp | 7 +++---- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h index a3df9f6bf3..651cd91674 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h @@ -1519,6 +1519,7 @@ class GraphColorRegAllocator : public RegAllocator { #endif bool hasSpill = false; bool doMultiPass = false; + bool seenFP = false; }; class CallerSavePre: public CGPre { diff --git a/src/mapleall/maple_be/include/cg/cgfunc.h b/src/mapleall/maple_be/include/cg/cgfunc.h index bc0a48089e..ca10190aad 100644 --- a/src/mapleall/maple_be/include/cg/cgfunc.h +++ b/src/mapleall/maple_be/include/cg/cgfunc.h @@ -1107,6 +1107,14 @@ class CGFunc { return useFP; } + void UnsetSeenFP() { + seenFP = false; + } + + bool SeenFP() const { + return seenFP; + } + void UpdateAllRegisterVregMapping(MapleMap &newMap); void RegisterVregMapping(regno_t vRegNum, PregIdx pidx) { @@ -1276,6 +1284,7 @@ class CGFunc { const MapleString shortFuncName; bool hasAsm = false; bool useFP = true; + bool seenFP = true; /* save stack protect kinds which can trigger stack protect */ uint8 stackProtectInfo = 0; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp index 8d63e7d8fb..479dad8658 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp @@ -3608,6 +3608,9 @@ RegOperand *GraphColorRegAllocator::GetReplaceOpnd(Insn &insn, const Operand &op auto ®Opnd = static_cast(opnd); uint32 vregNO = regOpnd.GetRegisterNumber(); + if (vregNO == RFP) { + seenFP = true; + } RegType regType = regOpnd.GetRegisterType(); if (vregNO < kAllRegNum) { return nullptr; @@ -4975,6 +4978,9 @@ bool GraphColorRegAllocator::AllocateRegisters() { MarkCalleeSaveRegs(); + if (seenFP == false) { + cgFunc->UnsetSeenFP(); + } if (GCRA_DUMP) { cgFunc->DumpCGIR(); } diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp index 4fd65cebdd..807279e7f9 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp @@ -185,9 +185,6 @@ void AArch64GenProEpilog::TailCallBBOpt(BB &bb, MapleSet &callInsns, BB & * Return value: true if function do not need Prologue/Epilogue. false otherwise. */ bool AArch64GenProEpilog::TailCallOpt() { - if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { - return false; - } /* Count how many call insns in the whole function. */ uint32 nCount = 0; bool hasGetStackClass = false; @@ -1229,7 +1226,9 @@ void AArch64GenProEpilog::GeneratePushRegs() { } else { immOpnd = &aarchCGFunc.CreateImmOperand(argsToStkPassSize, k32BitSize, true); } - aarchCGFunc.SelectAdd(fpOpnd, spOpnd, *immOpnd, PTY_u64); + if (isLmbc == false || cgFunc.SeenFP() || cgFunc.GetFunction().GetAttr(FUNCATTR_varargs)) { + aarchCGFunc.SelectAdd(fpOpnd, spOpnd, *immOpnd, PTY_u64); + } cgFunc.GetCurBB()->GetLastInsn()->SetFrameDef(true); if (cgFunc.GenCfi()) { cgFunc.GetCurBB()->AppendInsn(aarchCGFunc.CreateCfiDefCfaInsn(stackBaseReg, -- Gitee From 75c9c590cfea6f589be572586fb54ff5e20fdcfe Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:53:14 -0700 Subject: [PATCH 018/124] Fred's Set firstarg_return attribute in the new funcAttrs field in MIRFuncType --- src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp | 3 +++ src/mapleall/maple_ir/src/mir_lower.cpp | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp b/src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp index 3a77948b15..63c34ea154 100644 --- a/src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp +++ b/src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp @@ -278,6 +278,9 @@ bool ASTFunc2FEHelper::ProcessDeclImpl(MapleAllocator &allocator) { ENCChecker::InsertBoundaryInAtts(attrs, func.GetBoundaryInfo()); mirMethodPair.second.second = attrs; mirFunc->SetFuncAttrs(attrs); + if (firstArgRet) { + mirFunc->GetMIRFuncType()->funcAttrs.SetAttr(FUNCATTR_firstarg_return); + } func.ClearGenericAttrsContentMap(); return true; } diff --git a/src/mapleall/maple_ir/src/mir_lower.cpp b/src/mapleall/maple_ir/src/mir_lower.cpp index aa5cb0131c..9b8c3f8d92 100644 --- a/src/mapleall/maple_ir/src/mir_lower.cpp +++ b/src/mapleall/maple_ir/src/mir_lower.cpp @@ -539,6 +539,10 @@ BlockNode *MIRLower::LowerBlock(BlockNode &block) { MIRFuncType *funcType = FuncTypeFromFuncPtrExpr(stmt->Opnd(0)); CHECK_FATAL(funcType != nullptr, "MIRLower::LowerBlock: cannot find prototype for icall"); ic->SetRetTyIdx(funcType->GetTypeIndex()); + MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcType->GetRetTyIdx()); + if (retType->GetPrimType() == PTY_agg && retType->GetSize() > 16) { + funcType->funcAttrs.SetAttr(FUNCATTR_firstarg_return); + } } newBlock->AddStatement(stmt); break; -- Gitee From db171cb05e15b472b86a15ee248c26ad0643ac1b Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 019/124] Changes from mplcglmbc8 and mplcglmbc9. --- src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp | 1 - src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 0ff53f6e5b..78f95013c1 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -436,7 +436,6 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; 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 8e6a35037e..52c098975b 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8096,6 +8096,11 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); + MIRFunction *callee = nullptr; + if (dynamic_cast(&naryNode) != nullptr) { + auto calleePuIdx = static_cast(naryNode).GetPUIdx(); + callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } -- Gitee From cece4278657c22971835399a9c75cc419b6f7913 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:44 -0700 Subject: [PATCH 020/124] Fred's Fixed determination logic of when there is fake parameter for returning struct, where x8 is also used to pass the fake parameter --- src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp | 1 + src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 5 ----- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 78f95013c1..0ff53f6e5b 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -436,6 +436,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); + if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; 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 52c098975b..8e6a35037e 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8096,11 +8096,6 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); - MIRFunction *callee = nullptr; - if (dynamic_cast(&naryNode) != nullptr) { - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); - } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } -- Gitee From a4b170bc9101f9342b61c578404ddd2d3a08c1ee Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 15 Jun 2022 16:18:04 -0700 Subject: [PATCH 021/124] Fix accessing localrefvar in memlayout by qualifying with language --- src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h | 2 +- src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 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 0bb9d7d2d0..8443e04122 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -129,7 +129,7 @@ class AArch64CGFunc : public CGFunc { uint32 LmbcFindTotalStkUsed(std::vector* paramList); uint32 LmbcTotalRegsUsed(); void LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn); - bool LmbcSmallAggForRet(BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *src); bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp index de95e9be33..97bfc6ef52 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp @@ -230,7 +230,7 @@ void AArch64MemLayout::LayoutFormalParams() { if (ploc.reg0 != kRinvalid) { /* register */ symLoc->SetRegisters(static_cast(ploc.reg0), static_cast(ploc.reg1), static_cast(ploc.reg2), static_cast(ploc.reg3)); - if (mirFunction->GetFormalDefVec()[i].formalAttrs.GetAttr(ATTR_localrefvar)) { + if (!cgFunc->GetMirModule().IsCModule() && mirFunction->GetNthParamAttr(i).GetAttr(ATTR_localrefvar)) { symLoc->SetMemSegment(segRefLocals); SetSegmentSize(*symLoc, segRefLocals, ptyIdx); } else if (!sym->IsPreg()) { @@ -272,7 +272,7 @@ void AArch64MemLayout::LayoutFormalParams() { } else { segArgsStkPassed.SetSize(static_cast(RoundUp(segArgsStkPassed.GetSize(), kSizeOfPtr))); } - if (mirFunction->GetFormalDefVec()[i].formalAttrs.GetAttr(ATTR_localrefvar)) { + if (!cgFunc->GetMirModule().IsCModule() && mirFunction->GetNthParamAttr(i).GetAttr(ATTR_localrefvar)) { SetLocalRegLocInfo(sym->GetStIdx(), *symLoc); AArch64SymbolAlloc *symLoc1 = memAllocator->GetMemPool()->New(); symLoc1->SetMemSegment(segRefLocals); -- Gitee From 0bffa5b0318aabec12e27550ff6a37f88fb6c2f6 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Thu, 16 Jun 2022 10:44:59 -0700 Subject: [PATCH 022/124] Set appearsInCode and puidxOrigin fields in newly cloned functions --- src/mapleall/maple_ipa/src/ipa_clone.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mapleall/maple_ipa/src/ipa_clone.cpp b/src/mapleall/maple_ipa/src/ipa_clone.cpp index 26aee0aaf6..ac04f15497 100644 --- a/src/mapleall/maple_ipa/src/ipa_clone.cpp +++ b/src/mapleall/maple_ipa/src/ipa_clone.cpp @@ -107,6 +107,8 @@ MIRFunction *IpaClone::IpaCloneFunction(MIRFunction &originalFunction, const std newFunc->SetSrcPosition(originalFunction.GetSrcPosition()); newFunc->SetFuncAttrs(originalFunction.GetFuncAttrs()); newFunc->SetBaseClassFuncNames(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fullName)); + newFunc->GetFuncSymbol()->SetAppearsInCode(true); + newFunc->SetPuidxOrigin(newFunc->GetPuidx()); if (originalFunction.GetBody() != nullptr) { CopyFuncInfo(originalFunction, *newFunc); newFunc->SetBody( @@ -135,6 +137,8 @@ MIRFunction *IpaClone::IpaCloneFunctionWithFreq(MIRFunction &originalFunction, newFunc->SetSrcPosition(originalFunction.GetSrcPosition()); newFunc->SetFuncAttrs(originalFunction.GetFuncAttrs()); newFunc->SetBaseClassFuncNames(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fullName)); + newFunc->GetFuncSymbol()->SetAppearsInCode(true); + newFunc->SetPuidxOrigin(newFunc->GetPuidx()); GcovFuncInfo *origProfData = originalFunction.GetFuncProfData(); auto *moduleMp = mirBuilder.GetMirModule().GetMemPool(); GcovFuncInfo *newProfData = moduleMp->New(&mirBuilder.GetMirModule().GetMPAllocator(), -- Gitee From 5b46d967ee1462257dabfffdf518bdcafc8cef3a Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Fri, 17 Jun 2022 00:40:20 -0700 Subject: [PATCH 023/124] Fixed a couple of bugs in the last rebase --- .../maple_be/include/cg/aarch64/aarch64_cgfunc.h | 16 ---------------- .../maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 2 +- 2 files changed, 1 insertion(+), 17 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 996dca1c1e..cff33c9d98 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -755,22 +755,6 @@ class AArch64CGFunc : public CGFunc { RegOperand &GetZeroOpnd(uint32 size) override; - int32 GetLmbcTotalStkUsed() { - return lmbcArgInfo->lmbcTotalStkUsed; - } - - void SetLmbcTotalStkUsed(int32 offset) { - lmbcArgInfo->lmbcTotalStkUsed = offset; - } - - void SetLmbcCallReturnType(MIRType *ty) { - lmbcCallReturnType = ty; - } - - MIRType *GetLmbcCallReturnType() { - return lmbcCallReturnType; - } - private: enum RelationOperator : uint8 { kAND, 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 8e6a35037e..0fee295949 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -893,7 +893,7 @@ MemOperand &AArch64CGFunc::ConstraintOffsetToSafeRegion(uint32 bitLen, const Mem } int32 offsetValue = static_cast(memOpnd.GetOffsetImmediate()->GetOffsetValue()); int32 multiplier = (offsetValue / k512BitSize) + static_cast(offsetValue % k512BitSize > k256BitSize); - int32 addMount = multiplier * k512BitSizeInt; + int32 addMount = multiplier * k512BitSize; int32 newOffset = offsetValue - addMount; RegOperand *baseReg = memOpnd.GetBaseRegister(); ImmOperand &immAddMount = CreateImmOperand(addMount, k64BitSize, true); -- Gitee From b68ad41a2057e94fffa9b01ecc02b62f971e0ca4 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Fri, 17 Jun 2022 21:32:32 -0700 Subject: [PATCH 024/124] Fixed bug in importing typeAttrs field of MIRStructType Also, handle the export and import of MIRAddrofConst of local symbols properly. --- src/mapleall/maple_ir/include/bin_mpl_export.h | 2 ++ src/mapleall/maple_ir/src/bin_mpl_export.cpp | 2 +- src/mapleall/maple_ir/src/bin_mpl_import.cpp | 8 ++++---- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/mapleall/maple_ir/include/bin_mpl_export.h b/src/mapleall/maple_ir/include/bin_mpl_export.h index f12bec7081..0d3d6d6457 100644 --- a/src/mapleall/maple_ir/include/bin_mpl_export.h +++ b/src/mapleall/maple_ir/include/bin_mpl_export.h @@ -180,7 +180,9 @@ class BinaryMplExport { void ExpandFourBuffSize(); MIRModule &mod; + public: MIRFunction *curFunc = nullptr; + private: size_t bufI = 0; std::vector buf; std::unordered_map gStrMark; diff --git a/src/mapleall/maple_ir/src/bin_mpl_export.cpp b/src/mapleall/maple_ir/src/bin_mpl_export.cpp index 486b7eb24b..a4c0dca8cc 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_export.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_export.cpp @@ -45,7 +45,7 @@ void OutputConstAddrof(const MIRConst &constVal, BinaryMplExport &mplExport) { if (addrof.GetSymbolIndex().IsGlobal()) { mplExport.OutputSymbol(mplExport.GetMIRModule().CurFunction()->GetLocalOrGlobalSymbol(addrof.GetSymbolIndex())); } else { - mplExport.WriteNum(addrof.GetSymbolIndex().FullIdx()); + mplExport.OutputLocalSymbol(mplExport.curFunc->GetLocalOrGlobalSymbol(addrof.GetSymbolIndex())); } mplExport.WriteNum(addrof.GetFieldID()); mplExport.WriteNum(addrof.GetOffset()); diff --git a/src/mapleall/maple_ir/src/bin_mpl_import.cpp b/src/mapleall/maple_ir/src/bin_mpl_import.cpp index 1f79751ed6..e3ab6f9689 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_import.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_import.cpp @@ -122,10 +122,10 @@ MIRConst *BinaryMplImport::ImportConst(MIRFunction *func) { return memPool->New(sym->GetStIdx(), fi, *exprTy, ofst); } case kBinKindConstAddrofLocal: { - uint32 fullidx = static_cast(ReadNum()); + MIRSymbol *sym = ImportLocalSymbol(func); FieldID fi = static_cast(ReadNum()); int32 ofst = static_cast(ReadNum()); - return memPool->New(StIdx(fullidx), fi, *type, ofst); + return memPool->New(sym->GetStIdx(), fi, *type, ofst); } case kBinKindConstAddrofFunc: { PUIdx puIdx = ImportFunction(); @@ -661,9 +661,9 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { auto kind = static_cast(ReadNum()); MIRStructType type(kind, strIdx); type.SetNameIsLocal(nameIsLocal); - auto &origType = static_cast(InsertInTypeTables(type)); - typTab.push_back(origType.GetTypeIndex()); type.SetTypeAttrs(ImportTypeAttrs()); + MIRStructType &origType = static_cast(InsertInTypeTables(type)); + typTab.push_back(origType.GetTypeIndex()); if (kind != kTypeStructIncomplete) { if (forPointedType) { typeNeedsComplete = &origType; -- Gitee From ece287a737326549b444a000b7933b7de75dc799 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 025/124] Changes from mplcglmbc8 and mplcglmbc9. --- src/mapleall/maple_be/include/be/lower.h | 2 +- .../include/cg/aarch64/aarch64_cgfunc.h | 32 +- .../include/cg/aarch64/aarch64_phases.def | 2 +- src/mapleall/maple_be/include/cg/call_conv.h | 22 +- src/mapleall/maple_be/include/cg/cg.h | 19 +- src/mapleall/maple_be/include/cg/cgfunc.h | 2 + src/mapleall/maple_be/src/be/lower.cpp | 82 ++- .../maple_be/src/cg/aarch64/aarch64_args.cpp | 4 +- .../src/cg/aarch64/aarch64_call_conv.cpp | 2 +- .../src/cg/aarch64/aarch64_cgfunc.cpp | 547 +++++++++++++++--- .../maple_be/src/cg/aarch64/aarch64_ebo.cpp | 4 +- .../src/cg/aarch64/aarch64_memlayout.cpp | 34 +- .../src/cg/aarch64/aarch64_offset_adjust.cpp | 2 +- .../src/cg/aarch64/aarch64_proepilog.cpp | 87 ++- .../src/cg/aarch64/aarch64_reaching.cpp | 3 +- .../maple_be/src/cg/cg_phasemanager.cpp | 1 + src/mapleall/maple_be/src/cg/cgfunc.cpp | 48 +- src/mapleall/maple_be/src/cg/emit.cpp | 5 + src/mapleall/maple_be/src/cg/memlayout.cpp | 6 +- .../maple_ir/include/bin_mpl_export.h | 28 +- .../maple_ir/include/bin_mpl_import.h | 12 +- .../maple_ir/include/ir_safe_cast_traits.def | 4 +- src/mapleall/maple_ir/include/keywords.def | 1 - src/mapleall/maple_ir/include/mir_builder.h | 2 + src/mapleall/maple_ir/include/mir_function.h | 18 +- src/mapleall/maple_ir/include/mir_lower.h | 1 + src/mapleall/maple_ir/include/mir_nodes.h | 2 +- src/mapleall/maple_ir/include/mir_parser.h | 2 +- src/mapleall/maple_ir/include/mir_symbol.h | 6 +- src/mapleall/maple_ir/include/mir_type.h | 27 +- src/mapleall/maple_ir/include/opcode_info.h | 1 + src/mapleall/maple_ir/include/opcodes.def | 1 + src/mapleall/maple_ir/include/opcodes.h | 4 +- src/mapleall/maple_ir/src/bin_func_export.cpp | 239 ++++---- src/mapleall/maple_ir/src/bin_func_import.cpp | 248 ++++---- src/mapleall/maple_ir/src/bin_mpl_export.cpp | 112 ++-- src/mapleall/maple_ir/src/bin_mpl_import.cpp | 48 +- src/mapleall/maple_ir/src/global_tables.cpp | 4 +- src/mapleall/maple_ir/src/mir_builder.cpp | 24 + src/mapleall/maple_ir/src/mir_function.cpp | 4 +- src/mapleall/maple_ir/src/mir_lower.cpp | 107 ++++ src/mapleall/maple_ir/src/mir_nodes.cpp | 4 +- src/mapleall/maple_ir/src/mir_parser.cpp | 31 +- src/mapleall/maple_ir/src/mir_type.cpp | 8 +- src/mapleall/maple_ir/src/parser.cpp | 18 +- src/mapleall/maple_me/include/lmbc_lower.h | 3 - .../maple_me/include/lmbc_memlayout.h | 59 +- src/mapleall/maple_me/src/alias_class.cpp | 8 +- src/mapleall/maple_me/src/code_factoring.cpp | 4 +- .../src/demand_driven_alias_analysis.cpp | 4 +- src/mapleall/maple_me/src/irmap_build.cpp | 7 +- src/mapleall/maple_me/src/irmap_emit.cpp | 5 +- src/mapleall/maple_me/src/lfo_dep_test.cpp | 2 + src/mapleall/maple_me/src/lmbc_lower.cpp | 258 ++------- src/mapleall/maple_me/src/lmbc_memlayout.cpp | 439 +------------- src/mapleall/maple_me/src/me_cfg.cpp | 2 + src/mapleall/maple_me/src/me_function.cpp | 4 +- .../maple_me/src/me_lower_globals.cpp | 13 +- .../maple_me/src/me_phase_manager.cpp | 7 +- src/mapleall/maple_me/src/me_rc_lowering.cpp | 1 + src/mapleall/maple_me/src/me_rename2preg.cpp | 1 + src/mapleall/maple_me/src/me_side_effect.cpp | 4 +- src/mapleall/maple_me/src/me_stmt_pre.cpp | 4 +- src/mapleall/maple_me/src/pme_emit.cpp | 9 +- src/mapleall/maple_me/src/ssa_devirtual.cpp | 4 +- src/mapleall/maple_me/src/ssa_pre.cpp | 2 + src/mapleall/mpl2mpl/src/constantfold.cpp | 6 +- 67 files changed, 1407 insertions(+), 1299 deletions(-) diff --git a/src/mapleall/maple_be/include/be/lower.h b/src/mapleall/maple_be/include/be/lower.h index 6da66a3fcf..92c9e840e9 100644 --- a/src/mapleall/maple_be/include/be/lower.h +++ b/src/mapleall/maple_be/include/be/lower.h @@ -187,7 +187,7 @@ class CGLowerer { void LowerTryCatchBlocks(BlockNode &body); #if TARGARM32 || TARGAARCH64 || TARGRISCV64 - BlockNode *LowerReturnStruct(NaryStmtNode &retNode); + BlockNode *LowerReturnStructUsingFakeParm(NaryStmtNode &retNode); #endif virtual BlockNode *LowerReturn(NaryStmtNode &retNode); void LowerEntry(MIRFunction &func); 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 e0d1497b74..7a6e406263 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -38,6 +38,7 @@ class LmbcArgInfo { MapleVector lmbcCallArgTypes; MapleVector lmbcCallArgOffsets; MapleVector lmbcCallArgNumOfRegs; // # of regs needed to complete struct + uint32 lmbcTotalStkUsed = -1; // TBD: remove when explicit addr for large agg is available }; class AArch64CGFunc : public CGFunc { @@ -101,7 +102,7 @@ class AArch64CGFunc : public CGFunc { return kRFLAG; } - MIRType *GetAggTyFromCallSite(StmtNode *stmt); + MIRType *LmbcGetAggTyFromCallSite(StmtNode *stmt, std::vector **parmList); RegOperand &GetOrCreateResOperand(const BaseNode &parent, PrimType primType); void IntrinsifyGetAndAddInt(ListOperand &srcOpnds, PrimType pty); @@ -125,9 +126,11 @@ class AArch64CGFunc : public CGFunc { bool needLow12 = false); MemOperand *FixLargeMemOpnd(MemOperand &memOpnd, uint32 align); MemOperand *FixLargeMemOpnd(MOperator mOp, MemOperand &memOpnd, uint32 dSize, uint32 opndIdx); + uint32 LmbcFindTotalStkUsed(std::vector* paramList); + uint32 LmbcTotalRegsUsed(); void LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn); - bool LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *src); - bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForRet(BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; void SelectIassignoff(IassignoffNode &stmt) override; @@ -135,6 +138,7 @@ class AArch64CGFunc : public CGFunc { void SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd) override; void SelectBlkassignoff(BlkassignoffNode &bNode, Operand *src) override; void SelectAggIassign(IassignNode &stmt, Operand &lhsAddrOpnd) override; + void SelectReturnSendOfStructInRegs(BaseNode *x) override; void SelectReturn(Operand *opnd0) override; void SelectIgoto(Operand *opnd0) override; void SelectCondGoto(CondGotoNode &stmt, Operand &opnd0, Operand &opnd1) override; @@ -486,7 +490,10 @@ class AArch64CGFunc : public CGFunc { void GenerateCleanupCodeForExtEpilog(BB &bb) override; uint32 FloatParamRegRequired(MIRStructType *structType, uint32 &fpSize) override; void AssignLmbcFormalParams() override; - RegOperand *GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType); + void LmbcGenSaveSpForAlloca() override; + MemOperand *GenLmbcFpMemOperand(int32 offset, uint32 byteSize, AArch64reg base = RFP); + RegOperand *GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType, AArch64reg baseRegno = RFP); + RegOperand *LmbcStructReturnLoad(int32 offset); Operand *GetBaseReg(const AArch64SymbolAlloc &symAlloc); int32 GetBaseOffset(const SymbolAlloc &symAlloc) override; @@ -732,6 +739,22 @@ class AArch64CGFunc : public CGFunc { RegOperand &GetZeroOpnd(uint32 size) override; + int32 GetLmbcTotalStkUsed() { + return lmbcArgInfo->lmbcTotalStkUsed; + } + + void SetLmbcTotalStkUsed(int32 offset) { + lmbcArgInfo->lmbcTotalStkUsed = offset; + } + + void SetLmbcCallReturnType(MIRType *ty) { + lmbcCallReturnType = ty; + } + + MIRType *GetLmbcCallReturnType() { + return lmbcCallReturnType; + } + private: enum RelationOperator : uint8 { kAND, @@ -799,6 +822,7 @@ class AArch64CGFunc : public CGFunc { regno_t methodHandleVreg = -1; uint32 alignPow = 5; /* function align pow defaults to 5 i.e. 2^5*/ LmbcArgInfo *lmbcArgInfo = nullptr; + MIRType *lmbcCallReturnType = nullptr; void SelectLoadAcquire(Operand &dest, PrimType dtype, Operand &src, PrimType stype, AArch64isa::MemoryOrdering memOrd, bool isDirect); diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def b/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def index a3a74d7b2f..ff08e81852 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def @@ -16,8 +16,8 @@ ADDTARGETPHASE("createstartendlabel", true); ADDTARGETPHASE("buildehfunc", true); ADDTARGETPHASE("handlefunction", true); + ADDTARGETPHASE("moveargs", true); if (GetMIRModule()->GetFlavor() != MIRFlavor::kFlavorLmbc) { - ADDTARGETPHASE("moveargs", true); /* SSA PHASES */ ADDTARGETPHASE("cgssaconstruct", CGOptions::DoCGSSA()); ADDTARGETPHASE("cgcopyprop", CGOptions::DoCGSSA()); diff --git a/src/mapleall/maple_be/include/cg/call_conv.h b/src/mapleall/maple_be/include/cg/call_conv.h index 9cfab98b56..4e33309c3c 100644 --- a/src/mapleall/maple_be/include/cg/call_conv.h +++ b/src/mapleall/maple_be/include/cg/call_conv.h @@ -63,8 +63,8 @@ struct CCLocInfo { class LmbcFormalParamInfo { public: LmbcFormalParamInfo(PrimType pType, uint32 ofst, uint32 sz) : - type(nullptr), primType(pType), offset(ofst), size(sz), regNO(0), vregNO(0), numRegs(0), - fpSize(0), isReturn(false), isPureFloat(false), isOnStack(false) {} + type(nullptr), primType(pType), offset(ofst), onStackOffset(0), size(sz), regNO(0), vregNO(0), numRegs(0), + fpSize(0), isReturn(false), isPureFloat(false), isOnStack(false), hasRegassign(false) {} ~LmbcFormalParamInfo() = default; @@ -86,7 +86,13 @@ class LmbcFormalParamInfo { void SetOffset(uint32 ofs) { offset = ofs; } - uint32 GetSize() const { + uint32 GetOnStackOffset() { + return onStackOffset; + } + void SetOnStackOffset(uint32 ofs) { + onStackOffset = ofs; + } + uint32 GetSize() { return size; } void SetSize(uint32 sz) { @@ -137,10 +143,17 @@ class LmbcFormalParamInfo { void SetIsOnStack() { isOnStack = true; } + bool HasRegassign() { + return hasRegassign; + } + void SetHasRegassign() { + hasRegassign = true; + } private: MIRStructType *type; PrimType primType; uint32 offset; + uint32 onStackOffset; /* stack location if isOnStack */ uint32 size; /* size primtype or struct */ regno_t regNO = 0; /* param reg num or starting reg num if numRegs > 0 */ regno_t vregNO = 0; /* if no explicit regassing from IR, create move from param reg */ @@ -148,7 +161,8 @@ class LmbcFormalParamInfo { uint32 fpSize = 0; /* size of fp param if isPureFloat */ bool isReturn; bool isPureFloat = false; - bool isOnStack; /* small struct with arrays need to be saved onto stack */ + bool isOnStack; /* large struct is passed by a copy on stack */ + bool hasRegassign; }; } /* namespace maplebe */ diff --git a/src/mapleall/maple_be/include/cg/cg.h b/src/mapleall/maple_be/include/cg/cg.h index 093289e42b..e1368acb1d 100644 --- a/src/mapleall/maple_be/include/cg/cg.h +++ b/src/mapleall/maple_be/include/cg/cg.h @@ -121,11 +121,13 @@ class CG { emitter(nullptr), labelOrderCnt(0), cgOption(cgOptions), - instrumentationFunction(nullptr) { + instrumentationFunction(nullptr), + fileGP(nullptr) { const std::string &internalNameLiteral = namemangler::GetInternalNameLiteral(namemangler::kJavaLangObjectStr); GStrIdx strIdxFromName = GlobalTables::GetStrTable().GetStrIdxFromName(internalNameLiteral); isLibcore = (GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdxFromName) != nullptr); DefineDebugTraceFunctions(); + isLmbc = (mirModule->GetFlavor() == MIRFlavor::kFlavorLmbc); } virtual ~CG(); @@ -361,6 +363,10 @@ class CG { return isLibcore; } + bool IsLmbc() const { + return isLmbc; + } + MIRSymbol *GetDebugTraceEnterFunction() { return dbgTraceEnter; } @@ -421,6 +427,13 @@ class CG { /* Object map generation helper */ std::vector GetReferenceOffsets64(const BECommon &beCommon, MIRStructType &structType); + void SetGP(MIRSymbol *sym) { + fileGP = sym; + } + MIRSymbol *GetGP() const { + return fileGP; + } + static bool IsInFuncWrapLabels(MIRFunction *func) { return funcWrapLabels.find(func) != funcWrapLabels.end(); } @@ -449,12 +462,14 @@ class CG { LabelIDOrder labelOrderCnt; static CGFunc *currentCGFunction; /* current cg function being compiled */ CGOptions cgOption; - bool isLibcore; MIRSymbol *instrumentationFunction; MIRSymbol *dbgTraceEnter; MIRSymbol *dbgTraceExit; MIRSymbol *dbgFuncProfile; + MIRSymbol *fileGP; /* for lmbc, one local %GP per file */ static std::map> funcWrapLabels; + bool isLibcore; + bool isLmbc; }; /* class CG */ } /* namespace maplebe */ diff --git a/src/mapleall/maple_be/include/cg/cgfunc.h b/src/mapleall/maple_be/include/cg/cgfunc.h index 9623c989e4..0695a784de 100644 --- a/src/mapleall/maple_be/include/cg/cgfunc.h +++ b/src/mapleall/maple_be/include/cg/cgfunc.h @@ -160,6 +160,7 @@ class CGFunc { virtual uint32 FloatParamRegRequired(MIRStructType *structType, uint32 &fpSize) = 0; virtual void AssignLmbcFormalParams() = 0; LmbcFormalParamInfo *GetLmbcFormalParamInfo(uint32 offset); + virtual void LmbcGenSaveSpForAlloca() = 0; void GenerateLoc(StmtNode *stmt, unsigned &lastSrcLoc, unsigned &lastMplLoc); int32 GetFreqFromStmt(uint32 stmtId); void GenerateInstruction(); @@ -201,6 +202,7 @@ class CGFunc { virtual void SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd) = 0; virtual void SelectBlkassignoff(BlkassignoffNode &bNode, Operand *src) = 0; virtual void SelectAggIassign(IassignNode &stmt, Operand &lhsAddrOpnd) = 0; + virtual void SelectReturnSendOfStructInRegs(BaseNode *x) = 0; virtual void SelectReturn(Operand *opnd) = 0; virtual void SelectIgoto(Operand *opnd0) = 0; virtual void SelectCondGoto(CondGotoNode &stmt, Operand &opnd0, Operand &opnd1) = 0; diff --git a/src/mapleall/maple_be/src/be/lower.cpp b/src/mapleall/maple_be/src/be/lower.cpp index 00e1db5bf3..137a5ff3c0 100644 --- a/src/mapleall/maple_be/src/be/lower.cpp +++ b/src/mapleall/maple_be/src/be/lower.cpp @@ -121,6 +121,7 @@ void CGLowerer::RegisterExternalLibraryFunctions() { func->AllocSymTab(); MIRSymbol *funcSym = func->GetFuncSymbol(); funcSym->SetStorageClass(kScExtern); + funcSym->SetAppearsInCode(true); /* return type */ MIRType *retTy = GlobalTables::GetTypeTable().GetPrimType(extFnDescrs[i].retType); @@ -879,7 +880,7 @@ void CGLowerer::LowerTypePtr(BaseNode &node) const { #if TARGARM32 || TARGAARCH64 || TARGRISCV64 -BlockNode *CGLowerer::LowerReturnStruct(NaryStmtNode &retNode) { +BlockNode *CGLowerer::LowerReturnStructUsingFakeParm(NaryStmtNode &retNode) { BlockNode *blk = mirModule.CurFuncCodeMemPool()->New(); for (size_t i = 0; i < retNode.GetNopndSize(); ++i) { retNode.SetOpnd(LowerExpr(retNode, *retNode.GetNopndAt(i), *blk), i); @@ -1104,7 +1105,7 @@ void CGLowerer::LowerCallStmt(StmtNode &stmt, StmtNode *&nextStmt, BlockNode &ne return; } - if ((newStmt->GetOpCode() == OP_call) || (newStmt->GetOpCode() == OP_icall)) { + if (newStmt->GetOpCode() == OP_call || newStmt->GetOpCode() == OP_icall || newStmt->GetOpCode() == OP_icallproto) { newStmt = LowerCall(static_cast(*newStmt), nextStmt, newBlk, retty, uselvar); } newStmt->SetSrcPos(stmt.GetSrcPos()); @@ -1175,7 +1176,12 @@ StmtNode *CGLowerer::GenIntrinsiccallNode(const StmtNode &stmt, PUIdx &funcCalle StmtNode *CGLowerer::GenIcallNode(PUIdx &funcCalled, IcallNode &origCall) { StmtNode *newCall = nullptr; - newCall = mirModule.GetMIRBuilder()->CreateStmtIcall(origCall.GetNopnd()); + if (origCall.GetOpCode() == OP_icallassigned) { + newCall = mirModule.GetMIRBuilder()->CreateStmtIcall(origCall.GetNopnd()); + } else { + newCall = mirModule.GetMIRBuilder()->CreateStmtIcallproto(origCall.GetNopnd()); + static_cast(newCall)->SetRetTyIdx(static_cast(origCall).GetRetTyIdx()); + } newCall->SetSrcPos(origCall.GetSrcPos()); CHECK_FATAL(newCall != nullptr, "nullptr is not expected"); funcCalled = kFuncNotFound; @@ -1377,6 +1383,7 @@ BlockNode *CGLowerer::LowerCallAssignedStmt(StmtNode &stmt, bool uselvar) { static_cast(newCall)->SetReturnVec(*p2nRets); break; } + case OP_icallprotoassigned: case OP_icallassigned: { auto &origCall = static_cast(stmt); newCall = GenIcallNode(funcCalled, origCall); @@ -1484,6 +1491,15 @@ bool CGLowerer::LowerStructReturn(BlockNode &newBlk, StmtNode *stmt, (*p2nrets)[0].first = dnodeStmt->GetStIdx(); (*p2nrets)[0].second.SetFieldID(dnodeStmt->GetFieldID()); lvar = true; + // set ATTR_firstarg_return for callee + if (stmt->GetOpCode() == OP_callassigned) { + CallNode *callNode = static_cast(stmt); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callNode->GetPUIdx()); + f->SetFirstArgReturn(); + f->GetMIRFuncType()->SetFirstArgReturn(); + } else { + // for icall, front-end already set ATTR_firstarg_return + } } else { /* struct <= 16 passed in regs lowered into call &foo regassign u64 %1 (regread u64 %%retval0) @@ -1501,13 +1517,19 @@ bool CGLowerer::LowerStructReturn(BlockNode &newBlk, StmtNode *stmt, CallNode *callStmt = mirModule.GetMIRBuilder()->CreateStmtCall(callNode->GetPUIdx(), callNode->GetNopnd()); callStmt->SetSrcPos(callNode->GetSrcPos()); newBlk.AddStatement(callStmt); - } else if (stmt->GetOpCode() == OP_icallassigned) { + } else if (stmt->GetOpCode() == OP_icallassigned || stmt->GetOpCode() == OP_icallprotoassigned) { auto *icallNode = static_cast(stmt); for (size_t i = 0; i < icallNode->GetNopndSize(); ++i) { BaseNode *newOpnd = LowerExpr(*icallNode, *icallNode->GetNopndAt(i), newBlk); icallNode->SetOpnd(newOpnd, i); } - IcallNode *icallStmt = mirModule.GetMIRBuilder()->CreateStmtIcall(icallNode->GetNopnd()); + IcallNode *icallStmt = nullptr; + if (stmt->GetOpCode() == OP_icallassigned) { + icallStmt = mirModule.GetMIRBuilder()->CreateStmtIcall(icallNode->GetNopnd()); + } else { + icallStmt = mirModule.GetMIRBuilder()->CreateStmtIcallproto(icallNode->GetNopnd()); + icallStmt->SetRetTyIdx(icallNode->GetRetTyIdx()); + } icallStmt->SetSrcPos(icallNode->GetSrcPos()); newBlk.AddStatement(icallStmt); } else { @@ -1773,6 +1795,7 @@ void CGLowerer::LowerAssertBoundary(StmtNode &stmt, BlockNode &block, BlockNode CondGotoNode *brFalseNode = mirBuilder->CreateStmtCondGoto(cond, OP_brfalse, labIdx); MIRFunction *printf = mirBuilder->GetOrCreateFunction("printf", TyIdx(PTY_i32)); + printf->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*printf->GetMIRFuncType()); MapleVector argsPrintf(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); uint32 oldTypeTableSize = GlobalTables::GetTypeTable().GetTypeTableSize(); @@ -1848,7 +1871,8 @@ BlockNode *CGLowerer::LowerBlock(BlockNode &block) { break; } case OP_callassigned: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallprotoassigned: { // pass the addr of lvar if this is a struct call assignment bool lvar = false; // nextStmt could be changed by the call to LowerStructReturn @@ -1868,6 +1892,7 @@ BlockNode *CGLowerer::LowerBlock(BlockNode &block) { case OP_intrinsiccall: case OP_call: case OP_icall: + case OP_icallproto: #if TARGARM32 || TARGAARCH64 || TARGRISCV64 || TARGX86_64 // nextStmt could be changed by the call to LowerStructReturn LowerCallStmt(*stmt, nextStmt, *newBlk); @@ -1877,8 +1902,8 @@ BlockNode *CGLowerer::LowerBlock(BlockNode &block) { break; case OP_return: { #if TARGARM32 || TARGAARCH64 || TARGRISCV64 - if (GetCurrentFunc()->IsReturnStruct()) { - newBlk->AppendStatementsFromBlock(*LowerReturnStruct(static_cast(*stmt))); + if (GetCurrentFunc()->IsFirstArgReturn() && stmt->NumOpnds() > 0) { + newBlk->AppendStatementsFromBlock(*LowerReturnStructUsingFakeParm(static_cast(*stmt))); } else { #endif NaryStmtNode *retNode = static_cast(stmt); @@ -1976,7 +2001,9 @@ void CGLowerer::SimplifyBlock(BlockNode &block) { } auto *newFunc = theMIRModule->GetMIRBuilder()->GetOrCreateFunction(asmMap.at(oldFunc->GetName()), callStmt->GetTyIdx()); - newFunc->GetFuncSymbol()->SetStorageClass(kScExtern); + MIRSymbol *funcSym = newFunc->GetFuncSymbol(); + funcSym->SetStorageClass(kScExtern); + funcSym->SetAppearsInCode(true); callStmt->SetPUIdx(newFunc->GetPuidx()); break; } @@ -2086,6 +2113,7 @@ StmtNode *CGLowerer::LowerCall( if (needCheckStore) { MIRFunction *fn = mirModule.GetMIRBuilder()->GetOrCreateFunction("MCC_Reflect_Check_Arraystore", TyIdx(PTY_void)); + fn->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); MapleVector args(mirModule.GetMIRBuilder()->GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -2112,7 +2140,7 @@ StmtNode *CGLowerer::LowerCall( } MIRType *retType = nullptr; - if (callNode.op == OP_icall) { + if (callNode.op == OP_icall || callNode.op == OP_icallproto) { if (retTy == nullptr) { return &callNode; } else { @@ -2158,7 +2186,7 @@ StmtNode *CGLowerer::LowerCall( addrofNode->SetStIdx(dsgnSt->GetStIdx()); addrofNode->SetFieldID(0); - if (callNode.op == OP_icall) { + if (callNode.op == OP_icall || callNode.op == OP_icallproto) { auto ond = callNode.GetNopnd().begin(); newNopnd.emplace_back(*ond); newNopnd.emplace_back(addrofNode); @@ -2180,7 +2208,27 @@ StmtNode *CGLowerer::LowerCall( } void CGLowerer::LowerEntry(MIRFunction &func) { + // determine if needed to insert fake parameter to return struct for current function if (func.IsReturnStruct()) { + MIRType *retType = func.GetReturnType(); +#if TARGAARCH64 + PrimType pty = IsStructElementSame(retType); + if (pty == PTY_f32 || pty == PTY_f64 || IsPrimitiveVector(pty)) { + func.SetStructReturnedInRegs(); + return; + } +#endif + if (retType->GetPrimType() != PTY_agg) { + return; + } + if (retType->GetSize() > k16ByteSize) { + func.SetFirstArgReturn(); + func.GetMIRFuncType()->SetFirstArgReturn(); + } else { + func.SetStructReturnedInRegs(); + } + } + if (func.IsFirstArgReturn() && func.GetReturnType()->GetPrimType() != PTY_void) { MIRSymbol *retSt = func.GetSymTab()->CreateSymbol(kScopeLocal); retSt->SetStorageClass(kScFormal); retSt->SetSKind(kStVar); @@ -2197,12 +2245,14 @@ void CGLowerer::LowerEntry(MIRFunction &func) { auto formal = func.GetFormal(i); formals.emplace_back(formal); } + func.SetFirstArgReturn(); beCommon.AddElementToFuncReturnType(func, func.GetReturnTyIdx()); func.UpdateFuncTypeAndFormalsAndReturnType(formals, TyIdx(PTY_void), true); auto *funcType = func.GetMIRFuncType(); ASSERT(funcType != nullptr, "null ptr check"); + funcType->SetFirstArgReturn(); beCommon.AddTypeSizeAndAlign(funcType->GetTypeIndex(), GetPrimTypeSize(funcType->GetPrimType())); } } @@ -2380,6 +2430,7 @@ MIRFunction *CGLowerer::RegisterFunctionVoidStarToVoid(BuiltinFunctionID id, con func->AllocSymTab(); MIRSymbol *funcSym = func->GetFuncSymbol(); funcSym->SetStorageClass(kScExtern); + funcSym->SetAppearsInCode(true); MIRType *argTy = GlobalTables::GetTypeTable().GetPtr(); MIRSymbol *argSt = func->GetSymTab()->CreateSymbol(kScopeLocal); argSt->SetNameStrIdx(mirBuilder->GetOrCreateStringIndex(paramName)); @@ -2421,6 +2472,7 @@ void CGLowerer::RegisterBuiltIns() { func->AllocSymTab(); MIRSymbol *funcSym = func->GetFuncSymbol(); funcSym->SetStorageClass(kScExtern); + funcSym->SetAppearsInCode(true); /* return type */ MIRType *retTy = desc.GetReturnType(); CHECK_FATAL(retTy != nullptr, "retTy should not be nullptr"); @@ -2576,6 +2628,7 @@ void CGLowerer::ProcessArrayExpr(BaseNode &expr, BlockNode &blkNode) { arrayNode.GetNopndAt(1), lenRegreadNode); CondGotoNode *brFalseNode = mirBuilder->CreateStmtCondGoto(cond, OP_brfalse, labIdx); MIRFunction *fn = mirBuilder->GetOrCreateFunction("MCC_Array_Boundary_Check", TyIdx(PTY_void)); + fn->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); MapleVector args(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -3107,6 +3160,7 @@ BaseNode *CGLowerer::LowerIntrinJavaArrayLength(const BaseNode &parent, Intrinsi MIRFunction *newFunc = mirBuilder->GetOrCreateFunction("MCC_ThrowNullArrayNullPointerException", GlobalTables::GetTypeTable().GetVoid()->GetTypeIndex()); + newFunc->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*newFunc->GetMIRFuncType()); newFunc->AllocSymTab(); MapleVector args(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -3478,6 +3532,7 @@ StmtNode *CGLowerer::LowerIntrinsicRCCall(const IntrinsiccallNode &intrincall) { if (intrinFuncIDs.find(intrinDesc) == intrinFuncIDs.end()) { /* add funcid into map */ MIRFunction *fn = mirBuilder->GetOrCreateFunction(intrinDesc->name, TyIdx(PTY_void)); + fn->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); intrinFuncIDs[intrinDesc] = fn->GetPuidx(); @@ -3506,6 +3561,7 @@ void CGLowerer::LowerArrayStore(const IntrinsiccallNode &intrincall, BlockNode & if (needCheckStore) { MIRFunction *fn = mirBuilder->GetOrCreateFunction("MCC_Reflect_Check_Arraystore", TyIdx(PTY_void)); + fn->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); MapleVector args(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -3595,6 +3651,7 @@ StmtNode *CGLowerer::LowerIntrinsiccall(IntrinsiccallNode &intrincall, BlockNode beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); st->SetFunction(fn); + st->SetAppearsInCode(true); return LowerDefaultIntrinsicCall(intrincall, *st, *fn); } @@ -3665,6 +3722,7 @@ PUIdx CGLowerer::GetBuiltinToUse(BuiltinFunctionID id) const { void CGLowerer::LowerGCMalloc(const BaseNode &node, const GCMallocNode &gcmalloc, BlockNode &blkNode, bool perm) { MIRFunction *func = mirBuilder->GetOrCreateFunction((perm ? "MCC_NewPermanentObject" : "MCC_NewObj_fixed_class"), (TyIdx)(LOWERED_PTR_TYPE)); + func->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*func->GetMIRFuncType()); func->AllocSymTab(); /* Get the classinfo */ @@ -3683,6 +3741,7 @@ void CGLowerer::LowerGCMalloc(const BaseNode &node, const GCMallocNode &gcmalloc if (classSym->GetAttr(ATTR_abstract) || classSym->GetAttr(ATTR_interface)) { MIRFunction *funcSecond = mirBuilder->GetOrCreateFunction("MCC_Reflect_ThrowInstantiationError", (TyIdx)(LOWERED_PTR_TYPE)); + funcSecond->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*funcSecond->GetMIRFuncType()); funcSecond->AllocSymTab(); BaseNode *arg = mirBuilder->CreateExprAddrof(0, *classSym); @@ -3801,6 +3860,7 @@ void CGLowerer::LowerJarrayMalloc(const StmtNode &stmt, const JarrayMallocNode & args.emplace_back(mirBuilder->CreateIntConst(0, PTY_u32)); } MIRFunction *func = mirBuilder->GetOrCreateFunction(funcName, (TyIdx)(LOWERED_PTR_TYPE)); + func->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*func->GetMIRFuncType()); func->AllocSymTab(); CallNode *callAssign = nullptr; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 46b804c0cb..5869978884 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -38,7 +38,7 @@ void AArch64MoveRegArgs::CollectRegisterArgs(std::map &argsL uint32 start = 0; if (numFormal) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsReturnStruct()) { + if (func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16ByteSize) { start = 1; @@ -439,7 +439,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsReturnStruct()) { + if (func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp index 51fb1a1265..b89e1b4c40 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp @@ -300,7 +300,7 @@ int32 AArch64CallConvImpl::LocateNextParm(MIRType &mirType, CCLocInfo &pLoc, boo if (isFirst) { MIRFunction *func = tFunc != nullptr ? tFunc : const_cast(beCommon.GetMIRModule().CurFunction()); - if (func->IsReturnStruct()) { + if (func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); size_t size = beCommon.GetTypeSize(tyIdx); if (size == 0) { 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 7d015832ca..5da7b66ec2 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -1411,15 +1411,44 @@ void AArch64CGFunc::SelectAsm(AsmNode &node) { } void AArch64CGFunc::SelectRegassign(RegassignNode &stmt, Operand &opnd0) { + if (GetCG()->IsLmbc()) { + PrimType lhsSize = stmt.GetPrimType(); + PrimType rhsSize = stmt.Opnd(0)->GetPrimType(); + if (lhsSize != rhsSize && stmt.Opnd(0)->GetOpCode() == OP_ireadoff) { + Insn *prev = GetCurBB()->GetLastInsn(); + if (prev->GetMachineOpcode() == MOP_wldrsb || prev->GetMachineOpcode() == MOP_wldrsh) { + opnd0.SetSize(GetPrimTypeBitSize(stmt.GetPrimType())); + prev->SetMOP(prev->GetMachineOpcode() == MOP_wldrsb ? MOP_xldrsb : MOP_xldrsh); + } else if (prev->GetMachineOpcode() == MOP_wldr && stmt.GetPrimType() == PTY_i64) { + opnd0.SetSize(GetPrimTypeBitSize(stmt.GetPrimType())); + prev->SetMOP(MOP_xldrsw); + } + } + } RegOperand *regOpnd = nullptr; PregIdx pregIdx = stmt.GetRegIdx(); if (IsSpecialPseudoRegister(pregIdx)) { - regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, stmt.GetPrimType()); + if (GetCG()->IsLmbc() && stmt.GetPrimType() == PTY_agg) { + if (static_cast(opnd0).IsOfIntClass()) { + regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, PTY_i64); + } else if (opnd0.GetSize() <= k4ByteSize) { + regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, PTY_f32); + } else { + regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, PTY_f64); + } + } else { + regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, stmt.GetPrimType()); + } } else { regOpnd = &GetOrCreateVirtualRegisterOperand(GetVirtualRegNOFromPseudoRegIdx(pregIdx)); } /* look at rhs */ PrimType rhsType = stmt.Opnd(0)->GetPrimType(); + if (GetCG()->IsLmbc() && rhsType == PTY_agg) { + /* This occurs when a call returns a small struct */ + /* The subtree should already taken care of the agg type that is in excess of 8 bytes */ + rhsType = PTY_i64; + } PrimType dtype = rhsType; if (GetPrimTypeBitSize(dtype) < k32BitSize) { ASSERT(IsPrimitiveInteger(dtype), ""); @@ -1441,6 +1470,12 @@ void AArch64CGFunc::SelectRegassign(RegassignNode &stmt, Operand &opnd0) { MIRPreg *preg = GetFunction().GetPregTab()->PregFromPregIdx(pregIdx); uint32 srcBitLength = GetPrimTypeSize(preg->GetPrimType()) * kBitsPerByte; GetCurBB()->AppendInsn(GetCG()->BuildInstruction(PickStInsn(srcBitLength, stype), *regOpnd, *dest)); + } else if (regOpnd->GetRegisterNumber() == R0 || regOpnd->GetRegisterNumber() == R1) { + Insn &pseudo = GetCG()->BuildInstruction(MOP_pseudo_ret_int, *regOpnd); + GetCurBB()->AppendInsn(pseudo); + } else if (regOpnd->GetRegisterNumber() >= V0 && regOpnd->GetRegisterNumber() <= V3) { + Insn &pseudo = GetCG()->BuildInstruction(MOP_pseudo_ret_float, *regOpnd); + GetCurBB()->AppendInsn(pseudo); } } @@ -1922,15 +1957,11 @@ void AArch64CGFunc::SelectIassignoff(IassignoffNode &stmt) { SelectCopy(memOpnd, destType, srcOpnd, destType); } -void AArch64CGFunc::SelectIassignfpoff(IassignFPoffNode &stmt, Operand &opnd) { - int32 offset = stmt.GetOffset(); - PrimType primType = stmt.GetPrimType(); - uint32 bitlen = GetPrimTypeSize(primType) * kBitsPerByte; - - Operand &srcOpnd = LoadIntoRegister(opnd, primType); +MemOperand *AArch64CGFunc::GenLmbcFpMemOperand(int32 offset, uint32 byteSize, AArch64reg baseRegno) { MemOperand *memOpnd; - RegOperand *rfp = &GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); - if (offset < 0) { + RegOperand *rfp = &GetOrCreatePhysicalRegisterOperand(baseRegno, k64BitSize, kRegTyInt); + uint32 bitlen = byteSize * kBitsPerByte; + if (offset < 0 && offset < -256) { RegOperand *baseOpnd = &CreateRegisterOperandOfType(PTY_a64); ImmOperand &immOpnd = CreateImmOperand(offset, k32BitSize, true); Insn &addInsn = GetCG()->BuildInstruction(MOP_xaddrri12, *baseOpnd, *rfp, immOpnd); @@ -1942,11 +1973,45 @@ void AArch64CGFunc::SelectIassignfpoff(IassignFPoffNode &stmt, Operand &opnd) { memOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, bitlen, rfp, nullptr, offsetOpnd, nullptr); } memOpnd->SetStackMem(true); - MOperator mOp = PickStInsn(bitlen, primType); - Insn &store = GetCG()->BuildInstruction(mOp, srcOpnd, *memOpnd); - GetCurBB()->AppendInsn(store); + return memOpnd; +} + +void AArch64CGFunc::SelectIassignfpoff(IassignFPoffNode &stmt, Operand &opnd) { + int32 offset = stmt.GetOffset(); + PrimType primType = stmt.GetPrimType(); + MIRType *rType = GetLmbcCallReturnType(); + bool isPureFpStruct = false; + uint32 numRegs = 0; + if (rType && rType->GetPrimType() == PTY_agg && opnd.IsRegister() && static_cast(opnd).IsPhysicalRegister()) { + CHECK_FATAL(rType->GetSize() <= 16, "SelectIassignfpoff invalid agg size"); + uint32 fpSize; + numRegs = FloatParamRegRequired(static_cast(rType), fpSize); + if (numRegs) { + primType = (fpSize == k4ByteSize) ? PTY_f32 : PTY_f64; + isPureFpStruct = true; + } + } + uint32 byteSize = GetPrimTypeSize(primType); + uint32 bitlen = byteSize * kBitsPerByte; + if (isPureFpStruct) { + for (int i = 0 ; i < numRegs; ++i) { + MemOperand *memOpnd = GenLmbcFpMemOperand(offset + (i * byteSize), byteSize); + RegOperand &srcOpnd = GetOrCreatePhysicalRegisterOperand(AArch64reg(V0 + i), bitlen, kRegTyFloat); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, srcOpnd, *memOpnd); + GetCurBB()->AppendInsn(store); + } + } else { + Operand &srcOpnd = LoadIntoRegister(opnd, primType); + MemOperand *memOpnd = GenLmbcFpMemOperand(offset, byteSize); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, srcOpnd, *memOpnd); + GetCurBB()->AppendInsn(store); + } } +/* Load and assign to a new register. To be moved to the correct call register OR stack + location in LmbcSelectParmList */ void AArch64CGFunc::SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd) { if (GetLmbcArgInfo() == nullptr) { LmbcArgInfo *p = memPool->New(*GetFuncScopeAllocator()); @@ -1973,7 +2038,7 @@ void AArch64CGFunc::SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd } /* Search for CALL/ICALL/ICALLPROTO node, must be called from a blkassignoff node */ -MIRType *AArch64CGFunc::GetAggTyFromCallSite(StmtNode *stmt) { +MIRType *AArch64CGFunc::LmbcGetAggTyFromCallSite(StmtNode *stmt, std::vector **parmList) { for ( ; stmt != nullptr; stmt = stmt->GetNext()) { if (stmt->GetOpCode() == OP_call || stmt->GetOpCode() == OP_icallproto) { break; @@ -1986,25 +2051,20 @@ MIRType *AArch64CGFunc::GetAggTyFromCallSite(StmtNode *stmt) { if (stmt->GetOpCode() == OP_call) { CallNode *callNode = static_cast(stmt); MIRFunction *fn = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callNode->GetPUIdx()); - if (fn->IsReturnStruct()) { - ++nargs; - } if (fn->GetFormalCount() > 0) { - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fn->GetNthParamTyIdx(nargs)); + ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fn->GetFormalDefVec()[nargs].formalTyIdx); } + *parmList = &fn->GetParamTypes(); // would return null if the actual parameter is bogus } else if (stmt->GetOpCode() == OP_icallproto) { IcallNode *icallproto = static_cast(stmt); MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallproto->GetRetTyIdx()); MIRFuncType *fType = static_cast(type); - MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fType->GetRetTyIdx()); - if (retType->GetKind() == kTypeStruct) { - ++nargs; - } ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fType->GetNthParamType(nargs)); + *parmList = &fType->GetParamTypeList(); } else { CHECK_FATAL(stmt->GetOpCode() == OP_icallproto, - "GetAggTyFromCallSite:: unexpected call operator"); + "LmbcGetAggTyFromCallSite:: unexpected call operator"); } return ty; } @@ -2080,11 +2140,11 @@ bool AArch64CGFunc::LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *s } /* return true if blkassignoff for return, false otherwise */ -bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src) { +bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList) { AArch64reg regno = static_cast(static_cast(src)->GetRegisterNumber()); if (IsBlkassignForPush(bNode)) { PrimType pTy = PTY_i64; - MIRStructType *ty = static_cast(GetAggTyFromCallSite(&bNode)); + MIRStructType *ty = static_cast(LmbcGetAggTyFromCallSite(&bNode, parmList)); uint32 size = 0; uint32 fpregs = ty ? FloatParamRegRequired(ty, size) : 0; /* fp size determined */ if (fpregs > 0) { @@ -2095,7 +2155,7 @@ bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src) { MemOperand &mem = CreateMemOpnd(regno, s, size * kBitsPerByte); RegOperand *res = &CreateVirtualRegisterOperand(NewVReg(kRegTyFloat, size)); SelectCopy(*res, pTy, mem, pTy); - SetLmbcArgInfo(res, pTy, bNode.offset + s, static_cast(fpregs)); + SetLmbcArgInfo(res, pTy, 0, fpregs); IncLmbcArgsInRegs(kRegTyFloat); } IncLmbcTotalArgs(); @@ -2136,6 +2196,41 @@ bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src) { return false; } +/* This function is incomplete and may be removed when Lmbc IR is changed + to have the lowerer figures out the address of the large agg to reside */ +uint32 AArch64CGFunc::LmbcFindTotalStkUsed(std::vector *paramList) { + AArch64CallConvImpl parmlocator(GetBecommon()); + CCLocInfo pLoc; + for (TyIdx tyIdx : *paramList) { + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); + parmlocator.LocateNextParm(*ty, pLoc); + } + return 0; +} + +/* All arguments passed as registers */ +uint32 AArch64CGFunc::LmbcTotalRegsUsed() { + if (GetLmbcArgInfo() == nullptr) { + return 0; /* no arg */ + } + MapleVector ®s = GetLmbcCallArgNumOfRegs(); + MapleVector &types = GetLmbcCallArgTypes(); + uint32 iCnt = 0; + uint32 fCnt = 0; + for (uint32 i = 0; i < regs.size(); i++) { + if (IsPrimitiveInteger(types[i])) { + if ((iCnt + regs[i]) <= k8ByteSize) { + iCnt += regs[i]; + }; + } else { + if ((fCnt + regs[i]) <= k8ByteSize) { + fCnt += regs[i]; + }; + } + } + return iCnt + fCnt; +} + /* If blkassignoff for argument, this function loads the agg arguments into virtual registers, disregard if there is sufficient physicall call registers. Argument > 16-bytes are copied to preset space and ptr @@ -2144,29 +2239,40 @@ bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src) { void AArch64CGFunc::SelectBlkassignoff(BlkassignoffNode &bNode, Operand *src) { CHECK_FATAL(src->GetKind() == Operand::kOpdRegister, "blkassign src type not in register"); + std::vector *parmList; if (GetLmbcArgInfo() == nullptr) { LmbcArgInfo *p = memPool->New(*GetFuncScopeAllocator()); SetLmbcArgInfo(p); } if (LmbcSmallAggForRet(bNode, src)) { return; - } else if (LmbcSmallAggForCall(bNode, src)) { + } else if (LmbcSmallAggForCall(bNode, src, &parmList)) { return; } - /* memcpy for agg assign OR large agg for arg/ret */ Operand *dest = HandleExpr(bNode, *bNode.Opnd(0)); RegOperand *regResult = &CreateVirtualRegisterOperand(NewVReg(kRegTyInt, k8ByteSize)); + /* memcpy for agg assign OR large agg for arg/ret */ + int32 offset = bNode.offset; + if (IsBlkassignForPush(bNode)) { + /* large agg for call, addr to be pushed in SelectCall */ + offset = GetLmbcTotalStkUsed(); + if (offset < 0) { + /* length of ALL stack based args for this call, this location is where the + next large agg resides, its addr will then be passed */ + offset = LmbcFindTotalStkUsed(parmList) + LmbcTotalRegsUsed(); + } + SetLmbcTotalStkUsed(offset + bNode.blockSize); /* next use */ + SetLmbcArgInfo(regResult, PTY_i64, 0, 1); /* 1 reg for ptr */ + IncLmbcArgsInRegs(kRegTyInt); + IncLmbcTotalArgs(); + /* copy large agg arg to offset below */ + } std::vector opndVec; opndVec.push_back(regResult); /* result */ - opndVec.push_back(PrepareMemcpyParamOpnd(bNode.offset, *dest));/* param 0 */ + opndVec.push_back(PrepareMemcpyParamOpnd(offset, *dest)); /* param 0 */ opndVec.push_back(src); /* param 1 */ opndVec.push_back(PrepareMemcpyParamOpnd(static_cast(static_cast(bNode.blockSize))));/* param 2 */ SelectLibCall("memcpy", opndVec, PTY_a64, PTY_a64); - if (IsBlkassignForPush(bNode)) { - SetLmbcArgInfo(static_cast(src), PTY_i64, (int32)bNode.offset, 1); - IncLmbcArgsInRegs(kRegTyInt); - IncLmbcTotalArgs(); - } } void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { @@ -2553,6 +2659,159 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { } } +void AArch64CGFunc::SelectReturnSendOfStructInRegs(BaseNode *x) { + uint32 offset = 0; + if (x->GetOpCode() == OP_dread) { + DreadNode *dread = static_cast(x); + MIRSymbol *sym = GetFunction().GetLocalOrGlobalSymbol(dread->GetStIdx()); + MIRType *mirType = sym->GetType(); + if (dread->GetFieldID() != 0) { + MIRStructType *structType = static_cast(mirType); + mirType = structType->GetFieldType(dread->GetFieldID()); + offset = static_cast(GetBecommon().GetFieldOffset(*structType, dread->GetFieldID()).first); + } + uint32 typeSize = GetBecommon().GetTypeSize(mirType->GetTypeIndex()); + /* generate move to regs for agg return */ + AArch64CallConvImpl parmlocator(GetBecommon()); + CCLocInfo pLoc; + parmlocator.LocateNextParm(*mirType, pLoc, true, GetBecommon().GetMIRModule().CurFunction()); + /* aggregates are 8 byte aligned. */ + Operand *rhsmemopnd = nullptr; + RegOperand *result[kFourRegister]; /* up to 2 int or 4 fp */ + uint32 loadSize; + uint32 numRegs; + RegType regType; + PrimType retPty; + bool fpParm = false; + if (pLoc.numFpPureRegs) { + loadSize = pLoc.fpSize; + numRegs = pLoc.numFpPureRegs; + fpParm = true; + regType = kRegTyFloat; + retPty = (pLoc.fpSize == k4ByteSize) ? PTY_f32 : PTY_f64; + } else { + if (CGOptions::IsBigEndian()) { + loadSize = k8ByteSize; + numRegs = (typeSize <= k8ByteSize) ? kOneRegister : kTwoRegister; + regType = kRegTyInt; + retPty = PTY_u64; + } else { + loadSize = (typeSize <= k4ByteSize) ? k4ByteSize : k8ByteSize; + numRegs = (typeSize <= k8ByteSize) ? kOneRegister : kTwoRegister; + regType = kRegTyInt; + retPty = PTY_u32; + } + } + bool parmCopy = IsParamStructCopy(*sym); + for (uint32 i = 0; i < numRegs; i++) { + if (parmCopy) { + rhsmemopnd = &LoadStructCopyBase(*sym, + (offset + static_cast(i * (fpParm ? loadSize : k8ByteSize))), + static_cast(loadSize * kBitsPerByte)); + } else { + rhsmemopnd = &GetOrCreateMemOpnd(*sym, + (offset + static_cast(i * (fpParm ? loadSize : k8ByteSize))), + (loadSize * kBitsPerByte)); + } + result[i] = &CreateVirtualRegisterOperand(NewVReg(regType, loadSize)); + MOperator mop1 = PickLdInsn(loadSize * kBitsPerByte, retPty); + Insn &ld = GetCG()->BuildInstruction(mop1, *(result[i]), *rhsmemopnd); + GetCurBB()->AppendInsn(ld); + } + AArch64reg regs[kFourRegister]; + regs[0] = static_cast(pLoc.reg0); + regs[1] = static_cast(pLoc.reg1); + regs[2] = static_cast(pLoc.reg2); + regs[3] = static_cast(pLoc.reg3); + RegOperand *dest; + for (uint32 i = 0; i < numRegs; i++) { + AArch64reg preg; + MOperator mop2; + if (fpParm) { + preg = regs[i]; + mop2 = (loadSize == k4ByteSize) ? MOP_xvmovs : MOP_xvmovd; + } else { + preg = (i == 0 ? R0 : R1); + mop2 = (loadSize == k4ByteSize) ? MOP_wmovrr : MOP_xmovrr; + } + dest = &GetOrCreatePhysicalRegisterOperand(preg, (loadSize * kBitsPerByte), regType); + Insn &mov = GetCG()->BuildInstruction(mop2, *dest, *(result[i])); + GetCurBB()->AppendInsn(mov); + } + /* Create artificial dependency to extend the live range */ + for (uint32 i = 0; i < numRegs; i++) { + AArch64reg preg; + MOperator mop3; + if (fpParm) { + preg = regs[i]; + mop3 = MOP_pseudo_ret_float; + } else { + preg = (i == 0 ? R0 : R1); + mop3 = MOP_pseudo_ret_int; + } + dest = &GetOrCreatePhysicalRegisterOperand(preg, loadSize * kBitsPerByte, regType); + Insn &pseudo = GetCG()->BuildInstruction(mop3, *dest); + GetCurBB()->AppendInsn(pseudo); + } + return; + } else if (x->GetOpCode() == OP_iread) { + IreadNode *iread = static_cast(x); + RegOperand *rhsAddrOpnd = static_cast(HandleExpr(*iread, *iread->Opnd(0))); + rhsAddrOpnd = &LoadIntoRegister(*rhsAddrOpnd, iread->Opnd(0)->GetPrimType()); + MIRPtrType *ptrType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread->GetTyIdx())); + MIRType *mirType = static_cast(ptrType->GetPointedType()); + bool isRefField = false; + if (iread->GetFieldID() != 0) { + MIRStructType *structType = static_cast(mirType); + mirType = structType->GetFieldType(iread->GetFieldID()); + offset = static_cast(GetBecommon().GetFieldOffset(*structType, iread->GetFieldID()).first); + isRefField = GetBecommon().IsRefField(*structType, iread->GetFieldID()); + } + uint32 typeSize = GetBecommon().GetTypeSize(mirType->GetTypeIndex()); + /* generate move to regs. */ + RegOperand *result[kTwoRegister]; /* maximum 16 bytes, 2 registers */ + uint32 loadSize; + if (CGOptions::IsBigEndian()) { + loadSize = k8ByteSize; + } else { + loadSize = (typeSize <= k4ByteSize) ? k4ByteSize : k8ByteSize; + } + uint32 numRegs = (typeSize <= k8ByteSize) ? kOneRegister : kTwoRegister; + for (uint32 i = 0; i < numRegs; i++) { + OfstOperand *rhsOffOpnd = &GetOrCreateOfstOpnd(offset + i * loadSize, loadSize * kBitsPerByte); + Operand &rhsmemopnd = GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, loadSize * kBitsPerByte, + rhsAddrOpnd, nullptr, rhsOffOpnd, nullptr); + result[i] = &CreateVirtualRegisterOperand(NewVReg(kRegTyInt, loadSize)); + MOperator mop1 = PickLdInsn(loadSize * kBitsPerByte, PTY_u32); + Insn &ld = GetCG()->BuildInstruction(mop1, *(result[i]), rhsmemopnd); + ld.MarkAsAccessRefField(isRefField); + GetCurBB()->AppendInsn(ld); + } + RegOperand *dest; + for (uint32 i = 0; i < numRegs; i++) { + AArch64reg preg = (i == 0 ? R0 : R1); + dest = &GetOrCreatePhysicalRegisterOperand(preg, loadSize * kBitsPerByte, kRegTyInt); + Insn &mov = GetCG()->BuildInstruction(MOP_xmovrr, *dest, *(result[i])); + GetCurBB()->AppendInsn(mov); + } + /* Create artificial dependency to extend the live range */ + for (uint32 i = 0; i < numRegs; i++) { + AArch64reg preg = (i == 0 ? R0 : R1); + dest = &GetOrCreatePhysicalRegisterOperand(preg, loadSize * kBitsPerByte, kRegTyInt); + Insn &pseudo = cg->BuildInstruction(MOP_pseudo_ret_int, *dest); + GetCurBB()->AppendInsn(pseudo); + } + return; + } else { // dummy return of 0 inserted by front-end at absence of return + ASSERT(x->GetOpCode() == OP_constval, "SelectReturnSendOfStructInRegs: unexpected return operand"); + uint32 typeSize = GetPrimTypeSize(x->GetPrimType()); + RegOperand &dest = GetOrCreatePhysicalRegisterOperand(R0, typeSize * kBitsPerByte, kRegTyInt); + ImmOperand &src = CreateImmOperand(0, k16BitSize, false); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_xmovri32, dest, src)); + return; + } +} + Operand *AArch64CGFunc::SelectDread(const BaseNode &parent, DreadNode &expr) { MIRSymbol *symbol = GetFunction().GetLocalOrGlobalSymbol(expr.GetStIdx()); if (symbol->IsEhIndex()) { @@ -2916,31 +3175,50 @@ Operand *AArch64CGFunc::SelectIreadoff(const BaseNode &parent, IreadoffNode &ire return result; } -RegOperand *AArch64CGFunc::GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType) { - MemOperand *memOpnd; - RegOperand *rfp = &GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); - uint32 bitlen = byteSize * kBitsPerByte; - if (offset < 0) { - RegOperand *baseOpnd = &CreateRegisterOperandOfType(PTY_a64); - ImmOperand &immOpnd = CreateImmOperand(offset, k32BitSize, true); - Insn &addInsn = GetCG()->BuildInstruction(MOP_xaddrri12, *baseOpnd, *rfp, immOpnd); - GetCurBB()->AppendInsn(addInsn); - OfstOperand *offsetOpnd = &CreateOfstOpnd(0, k32BitSize); - memOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, bitlen, baseOpnd, - nullptr, offsetOpnd, nullptr); - } else { - OfstOperand *offsetOpnd = &CreateOfstOpnd(static_cast(static_cast(offset)), k32BitSize); - memOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, bitlen, rfp, - nullptr, offsetOpnd, nullptr); - } - memOpnd->SetStackMem(true); +RegOperand *AArch64CGFunc::GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType, + AArch64reg baseRegno) { + MemOperand *memOpnd = GenLmbcFpMemOperand(offset, byteSize, baseRegno); RegOperand *result = &GetOrCreateVirtualRegisterOperand(NewVReg(regType, byteSize)); - MOperator mOp = PickLdInsn(bitlen, primType); + MOperator mOp = PickLdInsn(byteSize * kBitsPerByte, primType); Insn &load = GetCG()->BuildInstruction(mOp, *result, *memOpnd); GetCurBB()->AppendInsn(load); return result; } +RegOperand *AArch64CGFunc::LmbcStructReturnLoad(int32 offset) { + RegOperand *result = nullptr; + MIRFunction &func = GetFunction(); + CHECK_FATAL(func.IsReturnStruct(), "LmbcStructReturnLoad: not struct return"); + MIRType *ty = func.GetReturnType(); + uint32 sz = GetBecommon().GetTypeSize(ty->GetTypeIndex()); + uint32 fpSize; + uint32 numFpRegs = FloatParamRegRequired(static_cast(ty), fpSize); + if (numFpRegs > 0) { + PrimType pType = (fpSize <= k4ByteSize) ? PTY_f32 : PTY_f64; + for (int32 i = (numFpRegs - kOneRegister); i > 0; --i) { + result = GenLmbcParamLoad(offset + (i * fpSize), fpSize, kRegTyFloat, pType); + AArch64reg regNo = static_cast(V0 + i); + RegOperand *reg = &GetOrCreatePhysicalRegisterOperand(regNo, fpSize * kBitsPerByte, kRegTyFloat); + SelectCopy(*reg, pType, *result, pType); + Insn &pseudo = GetCG()->BuildInstruction(MOP_pseudo_ret_float, *reg); + GetCurBB()->AppendInsn(pseudo); + } + result = GenLmbcParamLoad(offset, fpSize, kRegTyFloat, pType); + } else if (sz <= k4ByteSize) { + result = GenLmbcParamLoad(offset, k4ByteSize, kRegTyInt, PTY_u32); + } else if (sz <= k8ByteSize) { + result = GenLmbcParamLoad(offset, k8ByteSize, kRegTyInt, PTY_i64); + } else if (sz <= k16ByteSize) { + result = GenLmbcParamLoad(offset + k8ByteSize, k8ByteSize, kRegTyInt, PTY_i64); + RegOperand *r1 = &GetOrCreatePhysicalRegisterOperand(R1, k8ByteSize * kBitsPerByte, kRegTyInt); + SelectCopy(*r1, PTY_i64, *result, PTY_i64); + Insn &pseudo = GetCG()->BuildInstruction(MOP_pseudo_ret_int, *r1); + GetCurBB()->AppendInsn(pseudo); + result = GenLmbcParamLoad(offset, k8ByteSize, kRegTyInt, PTY_i64); + } + return result; +} + Operand *AArch64CGFunc::SelectIreadfpoff(const BaseNode &parent, IreadFPoffNode &ireadoff) { int32 offset = ireadoff.GetOffset(); PrimType primType = ireadoff.GetPrimType(); @@ -2951,19 +3229,32 @@ Operand *AArch64CGFunc::SelectIreadfpoff(const BaseNode &parent, IreadFPoffNode if (offset >= 0) { LmbcFormalParamInfo *info = GetLmbcFormalParamInfo(static_cast(offset)); if (info->GetPrimType() == PTY_agg) { - result = GenLmbcParamLoad(offset, bytelen, regty, primType); + if (info->IsOnStack()) { + result = GenLmbcParamLoad(info->GetOnStackOffset(), GetPrimTypeSize(PTY_a64), kRegTyInt, PTY_a64); + regno_t baseRegno = result->GetRegisterNumber(); + result = GenLmbcParamLoad(offset - info->GetOffset(), bytelen, regty, primType, (AArch64reg)baseRegno); + } else if (primType == PTY_agg) { + CHECK_FATAL(parent.GetOpCode() == OP_regassign, "SelectIreadfpoff of agg"); + result = LmbcStructReturnLoad(offset); + } else { + result = GenLmbcParamLoad(offset, bytelen, regty, primType); + } } else { CHECK_FATAL(primType == info->GetPrimType(), "Incorrect primtype"); CHECK_FATAL(offset == info->GetOffset(), "Incorrect offset"); - if (info->GetRegNO() == 0) { - /* TODO : follow lmbc sp offset for now */ + if (info->GetRegNO() == 0 || info->HasRegassign() == false) { result = GenLmbcParamLoad(offset, bytelen, regty, primType); } else { result = &GetOrCreatePhysicalRegisterOperand((AArch64reg)(info->GetRegNO()), bitlen, regty); } } } else { - result = GenLmbcParamLoad(offset, bytelen, regty, primType); + if (primType == PTY_agg) { + CHECK_FATAL(parent.GetOpCode() == OP_regassign, "SelectIreadfpoff of agg"); + result = LmbcStructReturnLoad(offset); + } else { + result = GenLmbcParamLoad(offset, bytelen, regty, primType); + } } return result; } @@ -5760,6 +6051,9 @@ Operand *AArch64CGFunc::SelectAlloca(UnaryNode &node, Operand &opnd0) { if (!CGOptions::IsArm64ilp32()) { ASSERT((node.GetPrimType() == PTY_a64), "wrong type"); } + if (GetCG()->IsLmbc()) { + SetHasVLAOrAlloca(true); + } PrimType stype = node.Opnd(0)->GetPrimType(); Operand *resOpnd = &opnd0; if (GetPrimTypeBitSize(stype) < GetPrimTypeBitSize(PTY_u64)) { @@ -5775,10 +6069,13 @@ Operand *AArch64CGFunc::SelectAlloca(UnaryNode &node, Operand &opnd0) { SelectShift(aliOp, aliOp, shifOpnd, kShiftLeft, PTY_u64); Operand &spOpnd = GetOrCreatePhysicalRegisterOperand(RSP, k64BitSize, kRegTyInt); SelectSub(spOpnd, spOpnd, aliOp, PTY_u64); - int64 argsToStkpassSize = GetMemlayout()->SizeOfArgsToStackPass(); - if (argsToStkpassSize > 0) { + int64 allocaOffset = GetMemlayout()->SizeOfArgsToStackPass(); + if (GetCG()->IsLmbc()) { + allocaOffset -= kDivide2 * k8ByteSize; + } + if (allocaOffset > 0) { RegOperand &resallo = CreateRegisterOperandOfType(PTY_u64); - SelectAdd(resallo, spOpnd, CreateImmOperand(argsToStkpassSize, k64BitSize, true), PTY_u64); + SelectAdd(resallo, spOpnd, CreateImmOperand(allocaOffset, k64BitSize, true), PTY_u64); return &resallo; } else { return &SelectCopy(spOpnd, PTY_u64, PTY_u64); @@ -6220,6 +6517,15 @@ void AArch64CGFunc::AssignLmbcFormalParams() { param->SetRegNO(0); } else { param->SetRegNO(intReg); + if (param->HasRegassign() == false) { + uint32 bytelen = GetPrimTypeSize(primType); + uint32 bitlen = bytelen * kBitsPerByte; + MemOperand *mOpnd = GenLmbcFpMemOperand(offset, bytelen); + RegOperand &src = GetOrCreatePhysicalRegisterOperand(AArch64reg(intReg), bitlen, kRegTyInt); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, src, *mOpnd); + GetCurBB()->AppendInsn(store); + } intReg++; } } else if (IsPrimitiveFloat(primType)) { @@ -6227,6 +6533,15 @@ void AArch64CGFunc::AssignLmbcFormalParams() { param->SetRegNO(0); } else { param->SetRegNO(fpReg); + if (param->HasRegassign() == false) { + uint32 bytelen = GetPrimTypeSize(primType); + uint32 bitlen = bytelen * kBitsPerByte; + MemOperand *mOpnd = GenLmbcFpMemOperand(offset, bytelen); + RegOperand &src = GetOrCreatePhysicalRegisterOperand(AArch64reg(fpReg), bitlen, kRegTyFloat); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, src, *mOpnd); + GetCurBB()->AppendInsn(store); + } fpReg++; } } else if (primType == PTY_agg) { @@ -6245,6 +6560,14 @@ void AArch64CGFunc::AssignLmbcFormalParams() { } else { param->SetRegNO(intReg); param->SetIsOnStack(); + param->SetOnStackOffset((intReg - R0 + fpReg - V0) * k8ByteSize); + uint32 bytelen = GetPrimTypeSize(PTY_a64); + uint32 bitlen = bytelen * kBitsPerByte; + MemOperand *mOpnd = GenLmbcFpMemOperand(param->GetOnStackOffset(), bytelen); + RegOperand &src = GetOrCreatePhysicalRegisterOperand(AArch64reg(intReg), bitlen, kRegTyInt); + MOperator mOp = PickStInsn(bitlen, PTY_a64); + Insn &store = GetCG()->BuildInstruction(mOp, src, *mOpnd); + GetCurBB()->AppendInsn(store); intReg++; } } else if (param->GetSize() <= k8ByteSize) { @@ -6290,7 +6613,6 @@ void AArch64CGFunc::AssignLmbcFormalParams() { Operand *memOpd = &CreateMemOpnd(RFP, offset + (i * rSize), rSize); GetCurBB()->AppendInsn(GetCG()->BuildInstruction( PickStInsn(rSize * kBitsPerByte, pType), dest, *memOpd)); - param->SetIsOnStack(); } } } else { @@ -6299,6 +6621,22 @@ void AArch64CGFunc::AssignLmbcFormalParams() { } } +void AArch64CGFunc::LmbcGenSaveSpForAlloca() { + if (GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc || HasVLAOrAlloca() == false) { + return; + } + Operand &spOpnd = GetOrCreatePhysicalRegisterOperand(RSP, k64BitSize, kRegTyInt); + RegOperand &spSaveOpnd = CreateVirtualRegisterOperand(NewVReg(kRegTyInt, kSizeOfPtr)); + Insn &save = GetCG()->BuildInstruction(MOP_xmovrr, spSaveOpnd, spOpnd); + GetFirstBB()->AppendInsn(save); + //save.SetFrameDef(true); + for (auto *retBB : GetExitBBsVec()) { + Insn &restore = GetCG()->BuildInstruction(MOP_xmovrr, spOpnd, spSaveOpnd); + retBB->AppendInsn(restore); + restore.SetFrameDef(true); + } +} + /* if offset < 0, allocation; otherwise, deallocation */ MemOperand &AArch64CGFunc::CreateCallFrameOperand(int32 offset, uint32 size) { MemOperand *memOpnd = CreateStackMemOpnd(RSP, offset, size); @@ -7584,6 +7922,10 @@ size_t AArch64CGFunc::SelectParmListGetStructReturnSize(StmtNode &naryNode) { CallNode &callNode = static_cast(naryNode); MIRFunction *callFunc = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callNode.GetPUIdx()); TyIdx retIdx = callFunc->GetReturnTyIdx(); + if (callFunc->IsFirstArgReturn()) { + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(callFunc->GetFormalDefVec()[0].formalTyIdx); + return GetBecommon().GetTypeSize(static_cast(ty)->GetPointedTyIdx()); + } size_t retSize = GetBecommon().GetTypeSize(retIdx.GetIdx()); if ((retSize == 0) && callFunc->IsReturnStruct()) { TyIdx tyIdx = callFunc->GetFuncRetStructTyIdx(); @@ -7600,6 +7942,14 @@ size_t AArch64CGFunc::SelectParmListGetStructReturnSize(StmtNode &naryNode) { return GetBecommon().GetTypeSize(sym->GetTyIdx().GetIdx()); } } + } else if (naryNode.GetOpCode() == OP_icallproto) { + IcallNode &icallProto = static_cast(naryNode); + MIRFuncType *funcTy = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallProto.GetRetTyIdx())); + if (funcTy->FirstArgReturn()) { + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcTy->GetNthParamType(0)); + return GetBecommon().GetTypeSize(static_cast(ty)->GetPointedTyIdx()); + } + return GetBecommon().GetTypeSize(funcTy->GetRetTyIdx()); } return 0; } @@ -7707,7 +8057,7 @@ void AArch64CGFunc::SelectParmListPreprocess(const StmtNode &naryNode, size_t st */ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bool isCallNative) { size_t i = 0; - if ((naryNode.GetOpCode() == OP_icall) || isCallNative) { + if (naryNode.GetOpCode() == OP_icall || naryNode.GetOpCode() == OP_icallproto || isCallNative) { i++; } std::set specialArgs; @@ -7734,8 +8084,11 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - auto *callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + MIRFunction *callee = nullptr; + if (dynamic_cast(&naryNode) != nullptr) { + auto calleePuIdx = static_cast(naryNode).GetPUIdx(); + callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } @@ -8257,7 +8610,18 @@ void AArch64CGFunc::SelectCall(CallNode &callNode) { ListOperand *srcOpnds = CreateListOpnd(*GetFuncScopeAllocator()); if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { - LmbcSelectParmList(srcOpnds, fn->IsFirstArgReturn()); + SetLmbcCallReturnType(nullptr); + bool largeStructRet = false; + if (fn->IsFirstArgReturn()) { + MIRPtrType *ptrTy = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(fn->GetFormalDefVec()[0].formalTyIdx)); + MIRType *sTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ptrTy->GetPointedTyIdx()); + largeStructRet = sTy->GetSize() > k16ByteSize; + SetLmbcCallReturnType(sTy); + } else { + MIRType *ty = fn->GetReturnType(); + SetLmbcCallReturnType(ty); + } + LmbcSelectParmList(srcOpnds, largeStructRet); } bool callNative = false; if ((fsym->GetName() == "MCC_CallFastNative") || (fsym->GetName() == "MCC_CallFastNativeExt") || @@ -8333,11 +8697,21 @@ void AArch64CGFunc::SelectCall(CallNode &callNode) { void AArch64CGFunc::SelectIcall(IcallNode &icallNode, Operand &srcOpnd) { ListOperand *srcOpnds = CreateListOpnd(*GetFuncScopeAllocator()); - if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { - LmbcSelectParmList(srcOpnds, false /*fType->GetRetAttrs().GetAttr(ATTR_firstarg_return)*/); - } else { +// if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { +// /* icallproto */ +// MIRType *retTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallNode.GetRetTyIdx()); +// MIRFuncType *funcTy = static_cast(retTy); +// bool largeStructRet = false; +// if (funcTy->FirstArgReturn()) { +// TyIdx idx = funcTy->GetNthParamType(0); +// MIRPtrType *ptrTy = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(idx)); +// MIRType *sTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ptrTy->GetPointedTyIdx()); +// largeStructRet = sTy->GetSize() > k16ByteSize; +// } +// LmbcSelectParmList(srcOpnds, largeStructRet); +// } else { SelectParmList(icallNode, *srcOpnds); - } +// } Operand *fptrOpnd = &srcOpnd; if (fptrOpnd->GetKind() != Operand::kOpdRegister) { @@ -8348,7 +8722,7 @@ void AArch64CGFunc::SelectIcall(IcallNode &icallNode, Operand &srcOpnd) { RegOperand *regOpnd = static_cast(fptrOpnd); Insn &callInsn = GetCG()->BuildInstruction(MOP_xblr, *regOpnd, *srcOpnds); - MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallNode.GetRetTyIdx()); + MIRType *retType = icallNode.GetCallReturnType(); if (retType != nullptr) { callInsn.SetRetSize(static_cast(retType->GetSize())); callInsn.SetIsCallReturnUnsigned(IsUnsignedInteger(retType->GetPrimType())); @@ -8461,9 +8835,18 @@ RegOperand &AArch64CGFunc::GetOrCreateSpecialRegisterOperand(PregIdx sregIdx, Pr case kSregFp: reg = RFP; break; - case kSregGp: - reg = RFP; - break; + case kSregGp: { + MIRSymbol *sym = GetCG()->GetGP(); + if (sym == nullptr) { + sym = GetFunction().GetSymTab()->CreateSymbol(kScopeLocal); + std::string strBuf("__file__local__GP"); + sym->SetNameStrIdx(GetMirModule().GetMIRBuilder()->GetOrCreateStringIndex(strBuf)); + GetCG()->SetGP(sym); + } + RegOperand &result = GetOrCreateVirtualRegisterOperand(NewVReg(kRegTyInt, k8ByteSize)); + SelectAddrof(result, CreateStImmOperand(*sym, 0, 0)); + return result; + } case kSregThrownval: { /* uses x0 == R0 */ ASSERT(uCatch.regNOCatch > 0, "regNOCatch should greater than 0."); if (Globals::GetInstance()->GetOptimLevel() == 0) { @@ -9200,6 +9583,9 @@ int32 AArch64CGFunc::GetBaseOffset(const SymbolAlloc &sa) { int32 baseOffset = symAlloc->GetOffset(); return baseOffset + sizeofFplr; } else if (sgKind == kMsSpillReg) { + if (GetCG()->IsLmbc()) { + return symAlloc->GetOffset() + memLayout->SizeOfArgsToStackPass(); + } int32 baseOffset = symAlloc->GetOffset() + memLayout->SizeOfArgsRegisterPassed() + memLayout->GetSizeOfLocals() + memLayout->GetSizeOfRefLocals(); return baseOffset + sizeofFplr; @@ -9774,16 +10160,21 @@ void AArch64CGFunc::GenCVaStartIntrin(RegOperand &opnd, uint32 stkSize) { Operand &stkOpnd = GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); /* __stack */ - ImmOperand *offsOpnd = &CreateImmOperand(0, k64BitSize, true, kUnAdjustVary); /* isvary reset StackFrameSize */ + ImmOperand *offsOpnd; + if (GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + offsOpnd = &CreateImmOperand(0, k64BitSize, true, kUnAdjustVary); /* isvary reset StackFrameSize */ + } else { + offsOpnd = &CreateImmOperand(0, k64BitSize, true); + } ImmOperand *offsOpnd2 = &CreateImmOperand(stkSize, k64BitSize, false); RegOperand &vReg = CreateVirtualRegisterOperand(NewVReg(kRegTyInt, GetPrimTypeSize(LOWERED_PTR_TYPE))); if (stkSize) { SelectAdd(vReg, *offsOpnd, *offsOpnd2, LOWERED_PTR_TYPE); SelectAdd(vReg, stkOpnd, vReg, LOWERED_PTR_TYPE); } else { - SelectAdd(vReg, stkOpnd, *offsOpnd, LOWERED_PTR_TYPE); + SelectAdd(vReg, stkOpnd, *offsOpnd, LOWERED_PTR_TYPE); /* stack pointer */ } - OfstOperand *offOpnd = &GetOrCreateOfstOpnd(0, k64BitSize); + OfstOperand *offOpnd = &GetOrCreateOfstOpnd(0, k64BitSize); /* va_list ptr */ /* mem operand in va_list struct (lhs) */ MemOperand *strOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, k64BitSize, &opnd, nullptr, offOpnd, static_cast(nullptr)); @@ -9858,13 +10249,19 @@ void AArch64CGFunc::SelectCVaStart(const IntrinsiccallNode &intrnNode) { AArch64CallConvImpl parmLocator(GetBecommon()); CCLocInfo pLoc; uint32 stkSize = 0; + uint32 inReg = 0; for (uint32 i = 0; i < GetFunction().GetFormalCount(); i++) { MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(GetFunction().GetNthParamTyIdx(i)); parmLocator.LocateNextParm(*ty, pLoc); if (pLoc.reg0 == kRinvalid) { /* on stack */ stkSize = static_cast(pLoc.memOffset + pLoc.memSize); + } else { + inReg++; } } + if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + stkSize += (inReg * k8ByteSize); + } if (CGOptions::IsArm64ilp32()) { stkSize = static_cast(RoundUp(stkSize, k8ByteSize)); } else { diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp index 17d0bcdde9..4acfbd9e96 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp @@ -40,8 +40,8 @@ constexpr uint8 insPairsNum = 5; PairMOperator extInsnPairTable[ExtTableSize][insPairsNum] = { /* {origMop, newMop} */ - {{MOP_wldrb, MOP_wldrb}, {MOP_undef, MOP_undef}, {MOP_undef, MOP_undef}, {MOP_undef, MOP_undef}, - {MOP_undef, MOP_undef}}, /* AND */ + {{MOP_wldrb, MOP_wldrb}, {MOP_wldrsh, MOP_wldrb}, {MOP_wldrh, MOP_wldrb}, {MOP_xldrsw, MOP_wldrb}, + {MOP_wldr, MOP_wldrb}}, /* AND */ {{MOP_wldrb, MOP_wldrsb}, {MOP_wldr, MOP_wldrsb}, {MOP_undef, MOP_undef}, {MOP_undef, MOP_undef}, {MOP_undef, MOP_undef}}, /* SXTB */ {{MOP_wldrh, MOP_wldrsh}, {MOP_wldrb, MOP_wldrb}, {MOP_wldrsb, MOP_wldrsb}, {MOP_wldrsh, MOP_wldrsh}, diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp index cf15d450c9..71f57d89ea 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp @@ -134,7 +134,7 @@ void AArch64MemLayout::LayoutVarargParams() { if (be.GetMIRModule().IsCModule() && func->GetAttr(FUNCATTR_varargs)) { for (uint32 i = 0; i < func->GetFormalCount(); i++) { if (i == 0) { - if (func->IsReturnStruct()) { + if (func->IsFirstArgReturn() && func->GetReturnType()->GetPrimType() != PTY_void) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (be.GetTypeSize(tyIdx.GetIdx()) <= k16ByteSize) { continue; @@ -198,7 +198,7 @@ void AArch64MemLayout::LayoutFormalParams() { * outparmsize - portion of frame size of current function used by call parameters */ segArgsStkPassed.SetSize(mirFunction->GetOutParmSize()); - segArgsRegPassed.SetSize(mirFunction->GetOutParmSize() + kTwoRegister * k8ByteSize); + segArgsRegPassed.SetSize(mirFunction->GetOutParmSize()); return; } @@ -210,7 +210,7 @@ void AArch64MemLayout::LayoutFormalParams() { AArch64SymbolAlloc *symLoc = memAllocator->GetMemPool()->New(); SetSymAllocInfo(stIndex, *symLoc); if (i == 0) { - if (mirFunction->IsReturnStruct()) { + if (mirFunction->IsFirstArgReturn()) { symLoc->SetMemSegment(GetSegArgsRegPassed()); symLoc->SetOffset(GetSegArgsRegPassed().GetSize()); TyIdx tyIdx = mirFunction->GetFuncRetStructTyIdx(); @@ -224,13 +224,13 @@ void AArch64MemLayout::LayoutFormalParams() { continue; } } - MIRType *ty = mirFunction->GetNthParamType(i); + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(mirFunction->GetFormalDefVec()[i].formalTyIdx); uint32 ptyIdx = ty->GetTypeIndex(); parmLocator.LocateNextParm(*ty, ploc, i == 0, mirFunction); if (ploc.reg0 != kRinvalid) { /* register */ symLoc->SetRegisters(static_cast(ploc.reg0), static_cast(ploc.reg1), static_cast(ploc.reg2), static_cast(ploc.reg3)); - if (mirFunction->GetNthParamAttr(i).GetAttr(ATTR_localrefvar)) { + if (mirFunction->GetFormalDefVec()[i].formalAttrs.GetAttr(ATTR_localrefvar)) { symLoc->SetMemSegment(segRefLocals); SetSegmentSize(*symLoc, segRefLocals, ptyIdx); } else if (!sym->IsPreg()) { @@ -272,7 +272,7 @@ void AArch64MemLayout::LayoutFormalParams() { } else { segArgsStkPassed.SetSize(static_cast(RoundUp(segArgsStkPassed.GetSize(), kSizeOfPtr))); } - if (mirFunction->GetNthParamAttr(i).GetAttr(ATTR_localrefvar)) { + if (mirFunction->GetFormalDefVec()[i].formalAttrs.GetAttr(ATTR_localrefvar)) { SetLocalRegLocInfo(sym->GetStIdx(), *symLoc); AArch64SymbolAlloc *symLoc1 = memAllocator->GetMemPool()->New(); symLoc1->SetMemSegment(segRefLocals); @@ -287,8 +287,8 @@ void AArch64MemLayout::LayoutFormalParams() { } void AArch64MemLayout::LayoutLocalVariables(std::vector &tempVar, std::vector &returnDelays) { - if (be.GetMIRModule().GetFlavor() == kFlavorLmbc && mirFunction->GetFormalCount() == 0) { - segLocals.SetSize(static_cast(mirFunction->GetFrameSize() - mirFunction->GetOutParmSize())); + if (be.GetMIRModule().GetFlavor() == kFlavorLmbc) { + segLocals.SetSize(mirFunction->GetFrameSize() - mirFunction->GetOutParmSize()); return; } @@ -372,7 +372,7 @@ void AArch64MemLayout::LayoutReturnRef(std::vector &returnDelays, segRefLocals.SetSize(segRefLocals.GetSize() + be.GetTypeSize(tyIdx)); } if (be.GetMIRModule().GetFlavor() == kFlavorLmbc) { - segArgsToStkPass.SetSize(mirFunction->GetOutParmSize()); + segArgsToStkPass.SetSize(mirFunction->GetOutParmSize() + kDivide2 * k8ByteSize); } else { segArgsToStkPass.SetSize(FindLargestActualArea(structCopySize)); } @@ -423,7 +423,7 @@ void AArch64MemLayout::LayoutActualParams() { * variables get assigned their respecitve storage, i.e. * CallFrameSize (discounting callee-saved and FP/LR) is known. */ - MIRType *ty = mirFunction->GetNthParamType(i); + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(mirFunction->GetFormalDefVec()[i].formalTyIdx); uint32 ptyIdx = ty->GetTypeIndex(); static_cast(cgFunc)->GetOrCreateMemOpnd(*sym, 0, be.GetTypeAlign(ptyIdx) * kBitsPerByte); } @@ -440,7 +440,7 @@ void AArch64MemLayout::LayoutStackFrame(int32 &structCopySize, int32 &maxParmSta */ if (CGOptions::IsArm64ilp32()) { segArgsRegPassed.SetSize(RoundUp(segArgsRegPassed.GetSize(), k8ByteSize)); - /* we do need this as SP has to be aligned at a 16-bytes bounardy */ + /* we do need this as SP has to be aligned at a 16-bytes bounardy */ segArgsStkPassed.SetSize(RoundUp(segArgsStkPassed.GetSize(), k8ByteSize + k8ByteSize)); } else { segArgsRegPassed.SetSize(RoundUp(segArgsRegPassed.GetSize(), kSizeOfPtr)); @@ -527,11 +527,13 @@ uint64 AArch64MemLayout::StackFrameSize() const { uint64 total = segArgsRegPassed.GetSize() + static_cast(cgFunc)->SizeOfCalleeSaved() + GetSizeOfRefLocals() + locals().GetSize() + GetSizeOfSpillReg(); - if (GetSizeOfGRSaveArea() > 0) { - total += RoundUp(GetSizeOfGRSaveArea(), kAarch64StackPtrAlignment); - } - if (GetSizeOfVRSaveArea() > 0) { - total += RoundUp(GetSizeOfVRSaveArea(), kAarch64StackPtrAlignment); + if (cgFunc->GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + if (GetSizeOfGRSaveArea() > 0) { + total += RoundUp(GetSizeOfGRSaveArea(), kAarch64StackPtrAlignment); + } + if (GetSizeOfVRSaveArea() > 0) { + total += RoundUp(GetSizeOfVRSaveArea(), kAarch64StackPtrAlignment); + } } /* diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp index eaa5726d43..7ef7190645 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp @@ -50,7 +50,7 @@ void AArch64FPLROffsetAdjustment::AdjustmentOffsetForOpnd(Insn &insn, AArch64CGF if (memBaseReg->GetRegisterNumber() == RFP) { RegOperand &newBaseOpnd = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(stackBaseReg, k64BitSize, kRegTyInt); MemOperand &newMemOpnd = aarchCGFunc.GetOrCreateMemOpnd( - MemOperand::kAddrModeBOi, memOpnd.GetSize(), &newBaseOpnd, memOpnd.GetIndexRegister(), + memOpnd.GetAddrMode(), memOpnd.GetSize(), &newBaseOpnd, memOpnd.GetIndexRegister(), memOpnd.GetOffsetImmediate(), memOpnd.GetSymbol()); insn.SetOperand(i, newMemOpnd); stackBaseOpnd = true; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp index 109cc5087a..4fd65cebdd 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp @@ -1118,6 +1118,9 @@ void AArch64GenProEpilog::AppendInstructionAllocateCallFrameDebug(AArch64reg reg ipoint = cgFunc.GetCurBB()->GetLastInsn(); cfiOffset = stackFrameSize; (void)InsertCFIDefCfaOffset(cfiOffset, *ipoint); + if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + argsToStkPassSize -= (kDivide2 * k8ByteSize); + } ipoint = &CreateAndAppendInstructionForAllocateCallFrame(argsToStkPassSize, reg0, reg1, rty); CHECK_FATAL(ipoint != nullptr, "ipoint should not be nullptr at this point"); cfiOffset = GetOffsetFromCFA(); @@ -1251,9 +1254,16 @@ void AArch64GenProEpilog::GeneratePushRegs() { CHECK_FATAL(*it == RLR, "The second callee saved reg is expected to be RLR"); ++it; - auto offset = static_cast((static_cast(cgFunc.GetMemlayout())->RealStackFrameSize() - - (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */)) - - cgFunc.GetMemlayout()->SizeOfArgsToStackPass()); + AArch64MemLayout *memLayout = static_cast(cgFunc.GetMemlayout()); + int32 offset; + if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + offset = static_cast(memLayout->RealStackFrameSize() - + aarchCGFunc.SizeOfCalleeSaved() - memLayout->GetSizeOfLocals()); + } else { + offset = static_cast(memLayout->RealStackFrameSize() - + (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */) - + memLayout->SizeOfArgsToStackPass()); + } if (cgFunc.GetCG()->IsStackProtectorStrong() || cgFunc.GetCG()->IsStackProtectorAll()) { offset -= kAarch64StackPtrAlignment; @@ -1313,10 +1323,19 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { size = kSizeOfPtr; } uint32 dataSizeBits = size * kBitsPerByte; - uint32 offset = static_cast(memlayout->GetGRSaveAreaBaseLoc()); - if (memlayout->GetSizeOfGRSaveArea() % kAarch64StackPtrAlignment) { - offset += size; /* End of area should be aligned. Hole between VR and GR area */ + uint32 offset; + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + offset = static_cast(memlayout->GetGRSaveAreaBaseLoc()); /* SP reference */ + if (memlayout->GetSizeOfGRSaveArea() % kAarch64StackPtrAlignment) { + offset += size; /* End of area should be aligned. Hole between VR and GR area */ + } + } else { + offset = -memlayout->GetSizeOfGRSaveArea(); /* FP reference */ + if (memlayout->GetSizeOfGRSaveArea() % kAarch64StackPtrAlignment) { + offset -= size; + } } + uint32 grSize = -offset; uint32 start_regno = k8BitSize - (memlayout->GetSizeOfGRSaveArea() / size); ASSERT(start_regno <= k8BitSize, "Incorrect starting GR regno for GR Save Area"); for (uint32 i = start_regno + static_cast(R0); i < static_cast(R8); i++) { @@ -1326,16 +1345,25 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { tmpOffset += 8U - (dataSizeBits >> 3); } } - Operand &stackloc = aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); + Operand *stackLoc; + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + stackLoc = &aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); + } else { + stackLoc = aarchCGFunc.GenLmbcFpMemOperand(offset, size); + } RegOperand ® = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(static_cast(i), k64BitSize, kRegTyInt); Insn &inst = - currCG->BuildInstruction(aarchCGFunc.PickStInsn(dataSizeBits, PTY_i64), reg, stackloc); + currCG->BuildInstruction(aarchCGFunc.PickStInsn(dataSizeBits, PTY_i64), reg, *stackLoc); cgFunc.GetCurBB()->AppendInsn(inst); offset += size; } if (!CGOptions::UseGeneralRegOnly()) { - offset = static_cast(memlayout->GetVRSaveAreaBaseLoc()); + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + offset = static_cast(memlayout->GetVRSaveAreaBaseLoc()); + } else { + offset = -(memlayout->GetSizeOfVRSaveArea() + grSize); + } start_regno = k8BitSize - (memlayout->GetSizeOfVRSaveArea() / (size * k2BitSize)); ASSERT(start_regno <= k8BitSize, "Incorrect starting GR regno for VR Save Area"); for (uint32 i = start_regno + static_cast(V0); i < static_cast(V8); i++) { @@ -1345,11 +1373,16 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { tmpOffset += 16U - (dataSizeBits >> 3); } } - Operand &stackloc = aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); + Operand *stackLoc; + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + stackLoc = &aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); + } else { + stackLoc = aarchCGFunc.GenLmbcFpMemOperand(offset, size); + } RegOperand ® = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(static_cast(i), k64BitSize, kRegTyFloat); Insn &inst = - currCG->BuildInstruction(aarchCGFunc.PickStInsn(dataSizeBits, PTY_f64), reg, stackloc); + currCG->BuildInstruction(aarchCGFunc.PickStInsn(dataSizeBits, PTY_f64), reg, *stackLoc); cgFunc.GetCurBB()->AppendInsn(inst); offset += (size * k2BitSize); } @@ -1389,7 +1422,8 @@ void AArch64GenProEpilog::GenerateProlog(BB &bb) { } // insert .loc for function - if (currCG->GetCGOptions().WithLoc()) { + if (currCG->GetCGOptions().WithLoc() && + (!currCG->GetMIRModule()->IsCModule() || currCG->GetMIRModule()->IsWithDbgInfo())) { MIRFunction *func = &cgFunc.GetFunction(); MIRSymbol *fSym = GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx()); if (currCG->GetCGOptions().WithSrc()) { @@ -1649,11 +1683,17 @@ void AArch64GenProEpilog::AppendInstructionDeallocateCallFrameDebug(AArch64reg r * ldp/stp's imm should be within -512 and 504; * if ldp's imm > 504, we fall back to the ldp-add version */ - if (cgFunc.HasVLAOrAlloca() || argsToStkPassSize == 0) { - stackFrameSize -= argsToStkPassSize; - if (stackFrameSize > kStpLdpImm64UpperBound) { + bool isLmbc = (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc); + if (cgFunc.HasVLAOrAlloca() || argsToStkPassSize == 0 || isLmbc) { + int lmbcOffset = 0; + if (isLmbc == false) { + stackFrameSize -= argsToStkPassSize; + } else { + lmbcOffset = argsToStkPassSize - (kDivide2 * k8ByteSize); + } + if (stackFrameSize > kStpLdpImm64UpperBound || isLmbc) { Operand *o2; - o2 = aarchCGFunc.CreateStackMemOpnd(RSP, 0, kSizeOfPtr * kBitsPerByte); + o2 = aarchCGFunc.CreateStackMemOpnd(RSP, (isLmbc ? lmbcOffset : 0), kSizeOfPtr * kBitsPerByte); Insn &deallocInsn = currCG->BuildInstruction(mOp, o0, o1, *o2); cgFunc.GetCurBB()->AppendInsn(deallocInsn); if (cgFunc.GenCfi()) { @@ -1728,9 +1768,16 @@ void AArch64GenProEpilog::GeneratePopRegs() { CHECK_FATAL(*it == RLR, "The second callee saved reg is expected to be RLR"); ++it; - int32 offset = static_cast((static_cast(cgFunc.GetMemlayout())->RealStackFrameSize() - - (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */)) - - cgFunc.GetMemlayout()->SizeOfArgsToStackPass()); + AArch64MemLayout *memLayout = static_cast(cgFunc.GetMemlayout()); + int32 offset; + if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + offset = static_cast(memLayout->RealStackFrameSize() - + aarchCGFunc.SizeOfCalleeSaved() - memLayout->GetSizeOfLocals()); + } else { + offset = static_cast(cgFunc.GetMemlayout())->RealStackFrameSize() - + (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */) - + memLayout->SizeOfArgsToStackPass(); + } if (cgFunc.GetCG()->IsStackProtectorStrong() || cgFunc.GetCG()->IsStackProtectorAll()) { offset -= kAarch64StackPtrAlignment; @@ -1821,7 +1868,7 @@ void AArch64GenProEpilog::GenerateEpilog(BB &bb) { Operand &spOpnd = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(RSP, k64BitSize, kRegTyInt); Operand &fpOpnd = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(stackBaseReg, k64BitSize, kRegTyInt); - if (cgFunc.HasVLAOrAlloca()) { + if (cgFunc.HasVLAOrAlloca() && cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { aarchCGFunc.SelectCopy(spOpnd, PTY_u64, fpOpnd, PTY_u64); } diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp index 433cc85754..5ca154b1aa 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp @@ -161,8 +161,7 @@ void AArch64ReachingDefinition::AddRetPseudoInsn(BB &bb) { Insn &retInsn = cgFunc->GetCG()->BuildInstruction(MOP_pseudo_ret_int, regOpnd); bb.AppendInsn(retInsn); pseudoInsns.emplace_back(&retInsn); - } else { - ASSERT(regNO == V0, "CG internal error. Return value should be R0 or V0."); + } else if (regNO == V0) { RegOperand ®Opnd = static_cast(cgFunc)->GetOrCreatePhysicalRegisterOperand(regNO, k64BitSize, kRegTyFloat); Insn &retInsn = cgFunc->GetCG()->BuildInstruction(MOP_pseudo_ret_float, regOpnd); diff --git a/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp b/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp index d2ae2c25c9..bf645c15cd 100644 --- a/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp +++ b/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp @@ -160,6 +160,7 @@ void RecursiveMarkUsedStaticSymbol(const BaseNode *baseNode) { break; } case OP_addrof: + case OP_addrofoff: case OP_dread: { const AddrofNode *dreadNode = static_cast(baseNode); MarkUsedStaticSymbol(dreadNode->GetStIdx()); diff --git a/src/mapleall/maple_be/src/cg/cgfunc.cpp b/src/mapleall/maple_be/src/cg/cgfunc.cpp index c0138e49d0..fa20963392 100644 --- a/src/mapleall/maple_be/src/cg/cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/cgfunc.cpp @@ -1145,7 +1145,11 @@ void HandleReturn(StmtNode &stmt, CGFunc &cgFunc) { ASSERT(retNode.NumOpnds() <= 1, "NYI return nodes number > 1"); Operand *opnd = nullptr; if (retNode.NumOpnds() != 0) { - opnd = cgFunc.HandleExpr(retNode, *retNode.Opnd(0)); + if (!cgFunc.GetFunction().StructReturnedInRegs()) { + opnd = cgFunc.HandleExpr(retNode, *retNode.Opnd(0)); + } else { + cgFunc.SelectReturnSendOfStructInRegs(retNode.Opnd(0)); + } } cgFunc.SelectReturn(opnd); cgFunc.SetCurBBKind(BB::kBBReturn); @@ -1560,15 +1564,16 @@ void CGFunc::CreateLmbcFormalParamInfo() { PrimType primType; uint32 offset; uint32 typeSize; - MIRFunction &mirFunc = GetFunction(); - if (mirFunc.GetParamSize() > 0) { + MIRFunction &func = GetFunction(); + if (func.GetFormalCount() > 0) { + /* Whenever lmbc cannot delete call type info, the prototype is available */ uint32 stackOffset = 0; - for (size_t idx = 0; idx < mirFunc.GetParamSize(); ++idx) { - MIRSymbol *sym = mirFunc.GetFormal(idx); + for (size_t idx = 0; idx < func.GetFormalCount(); ++idx) { + MIRSymbol *sym = func.GetFormal(idx); MIRType *type; TyIdx tyIdx; if (sym) { - tyIdx = mirFunc.GetNthParamTyIdx(idx); + tyIdx = func.GetFormalDefVec()[idx].formalTyIdx; type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); } else { FormalDef vec = const_cast(GetBecommon().GetMIRModule().CurFunction())->GetFormalDefAt(idx); @@ -1615,6 +1620,9 @@ void CGFunc::CreateLmbcFormalParamInfo() { } IreadFPoffNode *ireadNode = static_cast(operand); primType = ireadNode->GetPrimType(); + if (ireadNode->GetOffset() < 0) { + continue; + } offset = static_cast(ireadNode->GetOffset()); typeSize = GetPrimTypeSize(primType); CHECK_FATAL((offset % k8ByteSize) == 0, ""); /* scalar only, no struct for now */ @@ -1626,6 +1634,31 @@ void CGFunc::CreateLmbcFormalParamInfo() { [] (LmbcFormalParamInfo *x, LmbcFormalParamInfo *y) { return x->GetOffset() < y->GetOffset(); } ); + + /* When a scalar param address is taken, its regassign is not in the 1st block */ + for (StmtNode *stmt = func.GetBody()->GetFirst(); stmt != nullptr; stmt = stmt->GetNext()) { + if (stmt == nullptr) { + break; + } + if (stmt->GetOpCode() == OP_label) { + continue; + } + if (stmt->GetOpCode() != OP_regassign) { + break; + } + RegassignNode *regAssignNode = static_cast(stmt); + BaseNode *operand = regAssignNode->Opnd(0); + if (operand->GetOpCode() != OP_ireadfpoff) { + break; + } + IreadFPoffNode *ireadNode = static_cast(operand); + if (ireadNode->GetOffset() < 0) { + continue; + } + LmbcFormalParamInfo *info = GetLmbcFormalParamInfo(ireadNode->GetOffset()); + info->SetHasRegassign(); + } + AssignLmbcFormalParams(); } @@ -1634,7 +1667,7 @@ void CGFunc::GenerateInstruction() { InitHandleStmtFactory(); StmtNode *secondStmt = HandleFirstStmt(); - CreateLmbcFormalParamInfo(); + //CreateLmbcFormalParamInfo(); /* First Pass: Creates the doubly-linked list of BBs (next,prev) */ volReleaseInsn = nullptr; unsigned lastSrcLoc = 0; @@ -2006,6 +2039,7 @@ void CGFunc::HandleFunction() { ASSERT(exitBBVec.size() <= 1, "there are more than one BB_return in func"); } ProcessExitBBVec(); + LmbcGenSaveSpForAlloca(); if (func.IsJava()) { GenerateCleanupCodeForExtEpilog(*cleanupBB); diff --git a/src/mapleall/maple_be/src/cg/emit.cpp b/src/mapleall/maple_be/src/cg/emit.cpp index ffeb569a73..a2c9939e27 100644 --- a/src/mapleall/maple_be/src/cg/emit.cpp +++ b/src/mapleall/maple_be/src/cg/emit.cpp @@ -2170,6 +2170,11 @@ void Emitter::EmitGlobalVar(const MIRSymbol &globalVar) { } void Emitter::EmitGlobalVars(std::vector> &globalVars) { + if (GetCG()->IsLmbc() && GetCG()->GetGP() != nullptr) { + Emit(asmInfo->GetLocal()).Emit("\t").Emit(GetCG()->GetGP()->GetName()).Emit("\n"); + Emit(asmInfo->GetComm()).Emit("\t").Emit(GetCG()->GetGP()->GetName()); + Emit(", ").Emit(GetCG()->GetMIRModule()->GetGlobalMemSize()).Emit(", ").Emit("8\n"); + } /* load globalVars profile */ if (globalVars.empty()) { return; diff --git a/src/mapleall/maple_be/src/cg/memlayout.cpp b/src/mapleall/maple_be/src/cg/memlayout.cpp index 57e45e8a2d..1b636207c6 100644 --- a/src/mapleall/maple_be/src/cg/memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/memlayout.cpp @@ -38,7 +38,7 @@ uint32 MemLayout::FindLargestActualArea(int32 &aggCopySize) { uint32 maxCopyStackSize = 0; // Size of aggregate param stack copy requirement for (; stmt != nullptr; stmt = stmt->GetNext()) { Opcode opCode = stmt->GetOpCode(); - if (opCode < OP_call || opCode > OP_xintrinsiccallassigned) { + if ((opCode < OP_call || opCode > OP_xintrinsiccallassigned) && opCode != OP_icallproto) { continue; } if (opCode == OP_intrinsiccallwithtypeassigned || opCode == OP_intrinsiccallwithtype || @@ -54,9 +54,9 @@ uint32 MemLayout::FindLargestActualArea(int32 &aggCopySize) { * if the following check fails, most likely dex has invoke-custom etc * that is not supported yet */ - DCHECK((opCode == OP_call || opCode == OP_icall), "Not lowered to call or icall?"); + DCHECK((opCode == OP_call || opCode == OP_icall || opCode == OP_icallproto), "Not lowered to call or icall?"); int32 copySize; - uint32 size = ComputeStackSpaceRequirementForCall(*stmt, copySize, opCode == OP_icall); + uint32 size = ComputeStackSpaceRequirementForCall(*stmt, copySize, opCode == OP_icall || opCode == OP_icallproto); if (size > maxParamStackSize) { maxParamStackSize = size; } diff --git a/src/mapleall/maple_ir/include/bin_mpl_export.h b/src/mapleall/maple_ir/include/bin_mpl_export.h index 09952cb8c7..f12bec7081 100644 --- a/src/mapleall/maple_ir/include/bin_mpl_export.h +++ b/src/mapleall/maple_ir/include/bin_mpl_export.h @@ -67,8 +67,8 @@ enum : uint8 { kBinEaCgStart = 41, kBinEaStart = 42, kBinNodeBlock = 43, - kBinOpStatement = 44, - kBinOpExpression = 45, +//kBinOpStatement = 44, +//kBinOpExpression = 45, kBinReturnvals = 46, kBinTypeTabStart = 47, kBinSymStart = 48, @@ -76,14 +76,14 @@ enum : uint8 { kBinFuncIdInfoStart = 50, kBinFormalStart = 51, kBinPreg = 52, - kBinPregStart = 53, - kBinLabelStart = 54, + kBinSpecialReg = 53, + kBinLabel = 54, kBinTypenameStart = 55, kBinHeaderStart = 56, kBinAliasMapStart = 57, - kBinKindTypeViaTypename = 58, - kBinKindSymViaSymname = 59, - kBinKindFuncViaSymname = 60, +//kBinKindTypeViaTypename = 58, +//kBinKindSymViaSymname = 59, +//kBinKindFuncViaSymname = 60, kBinFunctionBodyStart = 61, kBinFormalWordsTypeTagged = 62, kBinFormalWordsRefCounted = 63, @@ -103,8 +103,7 @@ class BinaryMplExport { void Export(const std::string &fname, std::unordered_set *dumpFuncSet); void WriteNum(int64 x); void Write(uint8 b); - void OutputType(TyIdx tyIdx, bool canUseTypename); - void OutputTypeViaTypeName(TyIdx tidx) { OutputType(tidx, true); } + void OutputType(TyIdx tyIdx); void WriteFunctionBodyField(uint64 contentIdx, std::unordered_set *dumpFuncSet); void OutputConst(MIRConst *c); void OutputConstBase(const MIRConst &c); @@ -133,12 +132,11 @@ class BinaryMplExport { void OutputInfoVector(const MIRInfoVector &infoVector, const MapleVector &infoVectorIsString); void OutputFuncIdInfo(MIRFunction *func); void OutputLocalSymbol(MIRSymbol *sym); - void OutputLocalSymTab(const MIRFunction *func); - void OutputPregTab(const MIRFunction *func); - void OutputLabelTab(const MIRFunction *func); + void OutputPreg(MIRPreg *preg); + void OutputLabel(LabelIdx lidx); void OutputLocalTypeNameTab(const MIRTypeNameTable *tyNameTab); void OutputFormalsStIdx(MIRFunction *func); - void OutputFuncViaSymName(PUIdx puIdx); + void OutputFuncViaSym(PUIdx puIdx); void OutputExpression(BaseNode *e); void OutputBaseNode(const BaseNode *b); void OutputReturnValues(const CallReturnVector *retv); @@ -182,6 +180,7 @@ class BinaryMplExport { void ExpandFourBuffSize(); MIRModule &mod; + MIRFunction *curFunc = nullptr; size_t bufI = 0; std::vector buf; std::unordered_map gStrMark; @@ -190,6 +189,9 @@ class BinaryMplExport { std::unordered_map uStrMark; std::unordered_map symMark; std::unordered_map typMark; + std::unordered_map localSymMark; + std::unordered_map localPregMark; + std::unordered_map labelMark; friend class UpdateMplt; std::unordered_map callInfoMark; std::map *func2SEMap = nullptr; diff --git a/src/mapleall/maple_ir/include/bin_mpl_import.h b/src/mapleall/maple_ir/include/bin_mpl_import.h index 3697654872..ee7f909f9b 100644 --- a/src/mapleall/maple_ir/include/bin_mpl_import.h +++ b/src/mapleall/maple_ir/include/bin_mpl_import.h @@ -126,15 +126,14 @@ class BinaryMplImport { void ImportInfoVector(MIRInfoVector &infoVector, MapleVector &infoVectorIsString); void ImportLocalTypeNameTable(MIRTypeNameTable *typeNameTab); void ImportFuncIdInfo(MIRFunction *func); - void ImportLocalSymbol(MIRFunction *func); - void ImportLocalSymTab(MIRFunction *func); - void ImportPregTab(const MIRFunction *func); - void ImportLabelTab(MIRFunction *func); + MIRSymbol *ImportLocalSymbol(MIRFunction *func); + PregIdx ImportPreg(MIRFunction *func); + LabelIdx ImportLabel(MIRFunction *func); void ImportFormalsStIdx(MIRFunction *func); void ImportAliasMap(MIRFunction *func); void ImportSrcPos(SrcPosition &pos); void ImportBaseNode(Opcode &o, PrimType &typ); - PUIdx ImportFuncViaSymName(); + PUIdx ImportFuncViaSym(MIRFunction *func); BaseNode *ImportExpression(MIRFunction *func); void ImportReturnValues(MIRFunction *func, CallReturnVector *retv); BlockNode *ImportBlockNode(MIRFunction *fn); @@ -162,6 +161,9 @@ class BinaryMplImport { std::vector typTab; std::vector funcTab; std::vector symTab; + std::vector localSymTab; + std::vector localPregTab; + std::vector localLabelTab; std::vector callInfoTab; std::vector eaCgTab; std::vector methodSymbols; diff --git a/src/mapleall/maple_ir/include/ir_safe_cast_traits.def b/src/mapleall/maple_ir/include/ir_safe_cast_traits.def index 1439b49d57..14ed1a367b 100644 --- a/src/mapleall/maple_ir/include/ir_safe_cast_traits.def +++ b/src/mapleall/maple_ir/include/ir_safe_cast_traits.def @@ -224,7 +224,9 @@ REGISTER_SAFE_CAST(CallNode, from.GetOpCode() == OP_call || from.GetOpCode() == OP_virtualicallassigned || instance_of(from)); REGISTER_SAFE_CAST(IcallNode, from.GetOpCode() == OP_icall || - from.GetOpCode() == OP_icallassigned); + from.GetOpCode() == OP_icallassigned || + from.GetOpCode() == OP_icallproto || + from.GetOpCode() == OP_icallprotoassigned); REGISTER_SAFE_CAST(IntrinsiccallNode, from.GetOpCode() == OP_intrinsiccall || from.GetOpCode() == OP_intrinsiccallwithtype || from.GetOpCode() == OP_xintrinsiccall || diff --git a/src/mapleall/maple_ir/include/keywords.def b/src/mapleall/maple_ir/include/keywords.def index eddff2f80a..51a603eafa 100644 --- a/src/mapleall/maple_ir/include/keywords.def +++ b/src/mapleall/maple_ir/include/keywords.def @@ -55,7 +55,6 @@ // per-function declaration keywords KEYWORD(framesize) KEYWORD(upformalsize) - KEYWORD(outparmsize) KEYWORD(moduleid) KEYWORD(funcsize) KEYWORD(funcid) diff --git a/src/mapleall/maple_ir/include/mir_builder.h b/src/mapleall/maple_ir/include/mir_builder.h index 5c38b7da10..9f3a5455bc 100755 --- a/src/mapleall/maple_ir/include/mir_builder.h +++ b/src/mapleall/maple_ir/include/mir_builder.h @@ -262,6 +262,8 @@ class MIRBuilder { IcallNode *CreateStmtIcall(const MapleVector &args); IcallNode *CreateStmtIcallAssigned(const MapleVector &args, const MIRSymbol &ret); + IcallNode *CreateStmtIcallproto(const MapleVector &args); + IcallNode *CreateStmtIcallprotoAssigned(const MapleVector &args, const MIRSymbol &ret); // For Call, VirtualCall, SuperclassCall, InterfaceCall IntrinsiccallNode *CreateStmtIntrinsicCall(MIRIntrinsicID idx, const MapleVector &arguments, TyIdx tyIdx = TyIdx()); diff --git a/src/mapleall/maple_ir/include/mir_function.h b/src/mapleall/maple_ir/include/mir_function.h index b3a4a5e4f8..96fdab5cea 100644 --- a/src/mapleall/maple_ir/include/mir_function.h +++ b/src/mapleall/maple_ir/include/mir_function.h @@ -830,24 +830,24 @@ class MIRFunction { callTimes = times; } - uint16 GetFrameSize() const { + uint32 GetFrameSize() const { return frameSize; } - void SetFrameSize(uint16 size) { + void SetFrameSize(uint32 size) { frameSize = size; } - uint16 GetUpFormalSize() const { + uint32 GetUpFormalSize() const { return upFormalSize; } - void SetUpFormalSize(uint16 size) { + void SetUpFormalSize(uint32 size) { upFormalSize = size; } - uint16 GetOutParmSize() const { + uint32 GetOutParmSize() const { return outParmSize; } - void SetOutParmSize(uint16 size) { + void SetOutParmSize(uint32 size) { outParmSize = size; } @@ -1298,9 +1298,9 @@ class MIRFunction { bool isDirty = false; bool fromMpltInline = false; // Whether this function is imported from mplt_inline file or not. uint8_t layoutType = kLayoutUnused; - uint16 frameSize = 0; - uint16 upFormalSize = 0; - uint16 outParmSize = 0; + uint32 frameSize = 0; + uint32 upFormalSize = 0; + uint32 outParmSize = 0; uint16 moduleID = 0; uint32 funcSize = 0; // size of code in words uint32 tempCount = 0; diff --git a/src/mapleall/maple_ir/include/mir_lower.h b/src/mapleall/maple_ir/include/mir_lower.h index 332a6de89f..be479f65a6 100644 --- a/src/mapleall/maple_ir/include/mir_lower.h +++ b/src/mapleall/maple_ir/include/mir_lower.h @@ -86,6 +86,7 @@ class MIRLower { ForeachelemNode *ExpandArrayMrtForeachelemBlock(ForeachelemNode &node); BlockNode *ExpandArrayMrtBlock(BlockNode &block); void AddArrayMrtMpl(BaseNode &exp, BlockNode &newblk); + MIRFuncType *FuncTypeFromFuncPtrExpr(BaseNode *x); void SetLowerME() { lowerPhase |= kShiftLowerMe; } diff --git a/src/mapleall/maple_ir/include/mir_nodes.h b/src/mapleall/maple_ir/include/mir_nodes.h index 7864fd412b..3e5524df39 100755 --- a/src/mapleall/maple_ir/include/mir_nodes.h +++ b/src/mapleall/maple_ir/include/mir_nodes.h @@ -3304,7 +3304,7 @@ class CallNode : public NaryStmtNode { CallReturnVector returnValues; }; -// icall and icallproto +// icall, icallassigned, icallproto and icallprotoassigned class IcallNode : public NaryStmtNode { public: IcallNode(MapleAllocator &allocator, Opcode o) diff --git a/src/mapleall/maple_ir/include/mir_parser.h b/src/mapleall/maple_ir/include/mir_parser.h index 10d1dd028a..b49370d0ff 100755 --- a/src/mapleall/maple_ir/include/mir_parser.h +++ b/src/mapleall/maple_ir/include/mir_parser.h @@ -134,6 +134,7 @@ class MIRParser { bool ParseStmtIcall(StmtNodePtr&); bool ParseStmtIcallassigned(StmtNodePtr&); bool ParseStmtIcallproto(StmtNodePtr&); + bool ParseStmtIcallprotoassigned(StmtNodePtr&); bool ParseStmtIntrinsiccall(StmtNodePtr&, bool isAssigned); bool ParseStmtIntrinsiccall(StmtNodePtr&); bool ParseStmtIntrinsiccallassigned(StmtNodePtr&); @@ -291,7 +292,6 @@ class MIRParser { bool ParseStmtBlockForType(); bool ParseStmtBlockForFrameSize(); bool ParseStmtBlockForUpformalSize(); - bool ParseStmtBlockForOutParmSize(); bool ParseStmtBlockForModuleID(); bool ParseStmtBlockForFuncSize(); bool ParseStmtBlockForFuncID(); diff --git a/src/mapleall/maple_ir/include/mir_symbol.h b/src/mapleall/maple_ir/include/mir_symbol.h index 0d1d127dbe..357242d0e2 100644 --- a/src/mapleall/maple_ir/include/mir_symbol.h +++ b/src/mapleall/maple_ir/include/mir_symbol.h @@ -484,12 +484,11 @@ class MIRSymbol { return false; } switch (storageClass) { - case kScFormal: case kScAuto: return true; case kScPstatic: case kScFstatic: - return value.konst == nullptr; + return value.konst == nullptr && !hasPotentialAssignment; default: return false; } @@ -638,7 +637,8 @@ class MIRLabelTable { LabelIdx CreateLabel() { LabelIdx labelIdx = labelTable.size(); - labelTable.push_back(GStrIdx(0)); // insert dummy global string index for anonymous label + GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(std::to_string(labelIdx)); + labelTable.push_back(strIdx); return labelIdx; } diff --git a/src/mapleall/maple_ir/include/mir_type.h b/src/mapleall/maple_ir/include/mir_type.h index c5245d568c..197e7d3ca2 100644 --- a/src/mapleall/maple_ir/include/mir_type.h +++ b/src/mapleall/maple_ir/include/mir_type.h @@ -1189,14 +1189,6 @@ class MIRStructType : public MIRType { isImported = flag; } - bool IsUsed() const { - return isUsed; - } - - void SetIsUsed(bool flag) { - isUsed = flag; - } - bool IsCPlusPlus() const { return isCPlusPlus; } @@ -1368,7 +1360,6 @@ class MIRStructType : public MIRType { vTableMethods.clear(); iTableMethods.clear(); isImported = false; - isUsed = false; hasVolatileField = false; hasVolatileFieldSet = false; } @@ -1471,7 +1462,6 @@ class MIRStructType : public MIRType { // implementation functions, For interfaces, they are abstact functions. // Weak indicates the actual definition is in another module. bool isImported = false; - bool isUsed = false; bool isCPlusPlus = false; // empty struct in C++ has size 1 byte mutable bool hasVolatileField = false; // for caching computed value mutable bool hasVolatileFieldSet = false; // if true, just read hasVolatileField; @@ -1928,11 +1918,19 @@ class MIRFuncType : public MIRType { } bool IsVarargs() const { - return isVarArgs; + return funcAttrs.GetAttr(FUNCATTR_varargs); } - void SetVarArgs(bool flag) { - isVarArgs = flag; + void SetVarArgs() { + funcAttrs.SetAttr(FUNCATTR_varargs); + } + + bool FirstArgReturn() const { + return funcAttrs.GetAttr(FUNCATTR_firstarg_return); + } + + void SetFirstArgReturn() { + funcAttrs.SetAttr(FUNCATTR_firstarg_return); } const TypeAttrs &GetRetAttrs() const { @@ -1960,7 +1958,8 @@ class MIRFuncType : public MIRType { std::vector paramTypeList; std::vector paramAttrsList; TypeAttrs retAttrs; - bool isVarArgs = false; + public: + FuncAttrs funcAttrs; }; class MIRTypeByName : public MIRType { diff --git a/src/mapleall/maple_ir/include/opcode_info.h b/src/mapleall/maple_ir/include/opcode_info.h index 814f15b2f2..5a82646b11 100644 --- a/src/mapleall/maple_ir/include/opcode_info.h +++ b/src/mapleall/maple_ir/include/opcode_info.h @@ -117,6 +117,7 @@ class OpcodeTable { bool IsICall(Opcode o) const { ASSERT(o < OP_last, "invalid opcode"); return o == OP_icall || o == OP_icallassigned || + o == OP_icallproto || o == OP_icallprotoassigned || o == OP_virtualicall || o == OP_virtualicallassigned || o == OP_interfaceicall || o == OP_interfaceicallassigned; } diff --git a/src/mapleall/maple_ir/include/opcodes.def b/src/mapleall/maple_ir/include/opcodes.def index 34cfb51c8d..0e842141ed 100755 --- a/src/mapleall/maple_ir/include/opcodes.def +++ b/src/mapleall/maple_ir/include/opcodes.def @@ -221,3 +221,4 @@ OPCODE(iassignspoff, IassignFPoffNode, OPCODEISSTMT, 8) OPCODE(blkassignoff, BlkassignoffNode, OPCODEISSTMT, 8) OPCODE(icallproto, IcallNode, (OPCODEISSTMT | OPCODEISVARSIZE | OPCODEHASSSAUSE | OPCODEHASSSADEF | OPCODEISCALL), 8) + OPCODE(icallprotoassigned, IcallNode, (OPCODEISSTMT | OPCODEISVARSIZE | OPCODEHASSSAUSE | OPCODEHASSSADEF | OPCODEISCALL | OPCODEISCALLASSIGNED), 8) diff --git a/src/mapleall/maple_ir/include/opcodes.h b/src/mapleall/maple_ir/include/opcodes.h index ea4ed2c1c9..b9f5e0f8c5 100644 --- a/src/mapleall/maple_ir/include/opcodes.h +++ b/src/mapleall/maple_ir/include/opcodes.h @@ -50,7 +50,7 @@ inline constexpr bool IsCallAssigned(Opcode code) { code == OP_virtualicallassigned || code == OP_superclasscallassigned || code == OP_interfacecallassigned || code == OP_interfaceicallassigned || code == OP_customcallassigned || code == OP_polymorphiccallassigned || - code == OP_icallassigned || code == OP_intrinsiccallassigned || + code == OP_icallassigned || code == OP_icallprotoassigned || code == OP_intrinsiccallassigned || code == OP_xintrinsiccallassigned || code == OP_intrinsiccallwithtypeassigned); } @@ -113,6 +113,8 @@ constexpr bool IsStmtMustRequire(Opcode opcode) { case OP_polymorphiccallassigned: case OP_icall: case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: case OP_intrinsiccall: case OP_xintrinsiccall: case OP_intrinsiccallassigned: diff --git a/src/mapleall/maple_ir/src/bin_func_export.cpp b/src/mapleall/maple_ir/src/bin_func_export.cpp index 263ef34c80..6815c8151d 100644 --- a/src/mapleall/maple_ir/src/bin_func_export.cpp +++ b/src/mapleall/maple_ir/src/bin_func_export.cpp @@ -24,6 +24,10 @@ using namespace std; namespace maple { void BinaryMplExport::OutputInfoVector(const MIRInfoVector &infoVector, const MapleVector &infoVectorIsString) { + if (!mod.IsWithDbgInfo()) { + Write(0); + return; + } WriteNum(infoVector.size()); for (uint32 i = 0; i < infoVector.size(); i++) { OutputStr(infoVector[i].first); @@ -41,99 +45,73 @@ void BinaryMplExport::OutputFuncIdInfo(MIRFunction *func) { WriteNum(func->GetPuidxOrigin()); // the funcid OutputInfoVector(func->GetInfoVector(), func->InfoIsString()); if (mod.GetFlavor() == kFlavorLmbc) { - WriteNum(func->GetUpFormalSize()); WriteNum(func->GetFrameSize()); - WriteNum(func->GetOutParmSize()); } - WriteNum(~kBinFuncIdInfoStart); } void BinaryMplExport::OutputBaseNode(const BaseNode *b) { - WriteNum(b->GetOpCode()); - WriteNum(b->GetPrimType()); + Write(static_cast(b->GetOpCode())); + Write(static_cast(b->GetPrimType())); } void BinaryMplExport::OutputLocalSymbol(MIRSymbol *sym) { - if (sym == nullptr) { - WriteNum(0); + std::unordered_map::iterator it = localSymMark.find(sym); + if (it != localSymMark.end()) { + WriteNum(-(it->second)); return; } + WriteNum(kBinSymbol); - WriteNum(sym->GetStIndex()); // preserve original st index OutputStr(sym->GetNameStrIdx()); WriteNum(sym->GetSKind()); WriteNum(sym->GetStorageClass()); + size_t mark = localSymMark.size(); + localSymMark[sym] = mark; OutputTypeAttrs(sym->GetAttrs()); WriteNum(static_cast(sym->GetIsTmp())); if (sym->GetSKind() == kStVar || sym->GetSKind() == kStFunc) { OutputSrcPos(sym->GetSrcPosition()); } - OutputTypeViaTypeName(sym->GetTyIdx()); + OutputType(sym->GetTyIdx()); if (sym->GetSKind() == kStPreg) { - WriteNum(sym->GetPreg()->GetPregNo()); + OutputPreg(sym->GetPreg()); } else if (sym->GetSKind() == kStConst || sym->GetSKind() == kStVar) { OutputConst(sym->GetKonst()); } else if (sym->GetSKind() == kStFunc) { - OutputFuncViaSymName(sym->GetFunction()->GetPuidx()); - OutputTypeViaTypeName(sym->GetTyIdx()); + OutputFuncViaSym(sym->GetFunction()->GetPuidx()); } else { CHECK_FATAL(false, "should not used"); } } -void BinaryMplExport::OutputLocalSymTab(const MIRFunction *func) { - WriteNum(kBinSymStart); - uint64 outsymSizeIdx = buf.size(); - ExpandFourBuffSize(); /// size of OutSym - int32 size = 0; - - for (uint32 i = 1; i < func->GetSymTab()->GetSymbolTableSize(); i++) { - MIRSymbol *s = func->GetSymTab()->GetSymbolFromStIdx(i); - ASSERT(s != nullptr, "null ptr check"); - if (s->IsDeleted()) { - OutputLocalSymbol(nullptr); - } else { - OutputLocalSymbol(s); - } - size++; +void BinaryMplExport::OutputPreg(MIRPreg *preg) { + if (preg->GetPregNo() < 0) { + WriteNum(kBinSpecialReg); + Write(-preg->GetPregNo()); + return; } - - Fixup(outsymSizeIdx, size); - WriteNum(~kBinSymStart); -} - -void BinaryMplExport::OutputPregTab(const MIRFunction *func) { - WriteNum(kBinPregStart); - uint64 outRegSizeIdx = buf.size(); - ExpandFourBuffSize(); /// size of OutReg - int32 size = 0; - - for (uint32 i = 1; i < func->GetPregTab()->Size(); ++i) { - MIRPreg *mirpreg = func->GetPregTab()->PregFromPregIdx(static_cast(i)); - if (mirpreg == nullptr) { - WriteNum(0); - size++; - continue; - } - WriteNum(kBinPreg); - WriteNum(mirpreg->GetPregNo()); - TyIdx tyIdx = (mirpreg->GetMIRType() == nullptr) ? TyIdx(0) : mirpreg->GetMIRType()->GetTypeIndex(); - OutputTypeViaTypeName(tyIdx); - WriteNum(mirpreg->GetPrimType()); - size++; + std::unordered_map::iterator it = localPregMark.find(preg); + if (it != localPregMark.end()) { + WriteNum(-(it->second)); + return; } - Fixup(outRegSizeIdx, size); - WriteNum(~kBinPregStart); + WriteNum(kBinPreg); + Write(static_cast(preg->GetPrimType())); + size_t mark = localPregMark.size(); + localPregMark[preg] = mark; } -void BinaryMplExport::OutputLabelTab(const MIRFunction *func) { - WriteNum(kBinLabelStart); - WriteNum(static_cast(func->GetLabelTab()->Size()-1)); // entry 0 is skipped - for (uint32 i = 1; i < func->GetLabelTab()->Size(); i++) { - OutputStr(func->GetLabelTab()->GetLabelTable()[i]); +void BinaryMplExport::OutputLabel(LabelIdx lidx) { + std::unordered_map::iterator it = labelMark.find(lidx); + if (it != labelMark.end()) { + WriteNum(-(it->second)); + return; } - WriteNum(~kBinLabelStart); + + WriteNum(kBinLabel); + size_t mark = labelMark.size(); + labelMark[lidx] = mark; } void BinaryMplExport::OutputLocalTypeNameTab(const MIRTypeNameTable *typeNameTab) { @@ -141,18 +119,16 @@ void BinaryMplExport::OutputLocalTypeNameTab(const MIRTypeNameTable *typeNameTab WriteNum(static_cast(typeNameTab->Size())); for (std::pair it : typeNameTab->GetGStrIdxToTyIdxMap()) { OutputStr(it.first); - OutputTypeViaTypeName(it.second); + OutputType(it.second); } - WriteNum(~kBinTypenameStart); } void BinaryMplExport::OutputFormalsStIdx(MIRFunction *func) { WriteNum(kBinFormalStart); WriteNum(func->GetFormalDefVec().size()); for (FormalDef formalDef : func->GetFormalDefVec()) { - WriteNum(formalDef.formalSym->GetStIndex()); + OutputLocalSymbol(formalDef.formalSym); } - WriteNum(~kBinFormalStart); } void BinaryMplExport::OutputAliasMap(MapleMap &aliasVarMap) { @@ -161,21 +137,18 @@ void BinaryMplExport::OutputAliasMap(MapleMap &aliasVarMa for (std::pair it : aliasVarMap) { OutputStr(it.first); OutputStr(it.second.memPoolStrIdx); - OutputTypeViaTypeName(it.second.tyIdx); + OutputType(it.second.tyIdx); OutputStr(it.second.sigStrIdx); } - WriteNum(~kBinAliasMapStart); } -void BinaryMplExport::OutputFuncViaSymName(PUIdx puIdx) { +void BinaryMplExport::OutputFuncViaSym(PUIdx puIdx) { MIRFunction *func = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx()); - WriteNum(kBinKindFuncViaSymname); - OutputStr(funcSt->GetNameStrIdx()); + OutputSymbol(funcSt); } void BinaryMplExport::OutputExpression(BaseNode *e) { - WriteNum(kBinOpExpression); OutputBaseNode(e); switch (e->GetOpCode()) { // leaf @@ -191,17 +164,17 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { } case OP_addroflabel: { AddroflabelNode *lNode = static_cast(e); - WriteNum(lNode->GetOffset()); + OutputLabel(lNode->GetOffset()); return; } case OP_addroffunc: { AddroffuncNode *addrNode = static_cast(e); - OutputFuncViaSymName(addrNode->GetPUIdx()); + OutputFuncViaSym(addrNode->GetPUIdx()); return; } case OP_sizeoftype: { SizeoftypeNode *sot = static_cast(e); - OutputTypeViaTypeName(sot->GetTyIdx()); + OutputType(sot->GetTyIdx()); return; } case OP_addrof: @@ -220,24 +193,23 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { } WriteNum(stIdx.Scope()); if (stIdx.Islocal()) { - WriteNum(stIdx.Idx()); // preserve original st index + OutputLocalSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx)); } else { - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(stIdx.Idx()); - WriteNum(kBinKindSymViaSymname); - OutputStr(sym->GetNameStrIdx()); + OutputSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx)); } return; } case OP_regread: { RegreadNode *regreadNode = static_cast(e); - WriteNum(regreadNode->GetRegIdx()); + MIRPreg *preg = curFunc->GetPregTab()->PregFromPregIdx(regreadNode->GetRegIdx()); + OutputPreg(preg); return; } case OP_gcmalloc: case OP_gcpermalloc: case OP_stackmalloc: { GCMallocNode *gcNode = static_cast(e); - OutputTypeViaTypeName(gcNode->GetTyIdx()); + OutputType(gcNode->GetTyIdx()); return; } // unary @@ -246,18 +218,18 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { case OP_floor: case OP_trunc: { TypeCvtNode *typecvtNode = static_cast(e); - WriteNum(typecvtNode->FromType()); + Write(static_cast(typecvtNode->FromType())); break; } case OP_retype: { RetypeNode *retypeNode = static_cast(e); - OutputTypeViaTypeName(retypeNode->GetTyIdx()); + OutputType(retypeNode->GetTyIdx()); break; } case OP_iread: case OP_iaddrof: { IreadNode *irNode = static_cast(e); - OutputTypeViaTypeName(irNode->GetTyIdx()); + OutputType(irNode->GetTyIdx()); WriteNum(irNode->GetFieldID()); break; } @@ -275,20 +247,20 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { case OP_zext: case OP_extractbits: { ExtractbitsNode *extNode = static_cast(e); - WriteNum(extNode->GetBitsOffset()); - WriteNum(extNode->GetBitsSize()); + Write(extNode->GetBitsOffset()); + Write(extNode->GetBitsSize()); break; } case OP_depositbits: { DepositbitsNode *dbNode = static_cast(e); - WriteNum(dbNode->GetBitsOffset()); - WriteNum(dbNode->GetBitsSize()); + Write(dbNode->GetBitsOffset()); + Write(dbNode->GetBitsSize()); break; } case OP_gcmallocjarray: case OP_gcpermallocjarray: { JarrayMallocNode *gcNode = static_cast(e); - OutputTypeViaTypeName(gcNode->GetTyIdx()); + OutputType(gcNode->GetTyIdx()); break; } // binary @@ -321,13 +293,13 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { case OP_cmpl: case OP_cmp: { CompareNode *cmpNode = static_cast(e); - WriteNum(cmpNode->GetOpndType()); + Write(static_cast(cmpNode->GetOpndType())); break; } case OP_resolveinterfacefunc: case OP_resolvevirtualfunc: { ResolveFuncNode *rsNode = static_cast(e); - OutputFuncViaSymName(rsNode->GetPuIdx()); + OutputFuncViaSym(rsNode->GetPuIdx()); break; } // ternary @@ -337,8 +309,8 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { // nary case OP_array: { ArrayNode *arrNode = static_cast(e); - OutputTypeViaTypeName(arrNode->GetTyIdx()); - WriteNum(static_cast(arrNode->GetBoundsCheck())); + OutputType(arrNode->GetTyIdx()); + Write(static_cast(arrNode->GetBoundsCheck())); WriteNum(static_cast(arrNode->NumOpnds())); break; } @@ -351,7 +323,7 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { case OP_intrinsicopwithtype: { IntrinsicopNode *intrnNode = static_cast(e); WriteNum(intrnNode->GetIntrinsic()); - OutputTypeViaTypeName(intrnNode->GetTyIdx()); + OutputType(intrnNode->GetTyIdx()); WriteNum(static_cast(intrnNode->NumOpnds())); break; } @@ -366,6 +338,9 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { static SrcPosition lastOutputSrcPosition; void BinaryMplExport::OutputSrcPos(const SrcPosition &pos) { + if (!mod.IsWithDbgInfo()) { + return; + } if (pos.FileNum() == 0 || pos.LineNum() == 0) { // error case, so output 0 WriteNum(lastOutputSrcPosition.RawData()); WriteNum(lastOutputSrcPosition.LineNum()); @@ -380,9 +355,15 @@ void BinaryMplExport::OutputReturnValues(const CallReturnVector *retv) { WriteNum(kBinReturnvals); WriteNum(static_cast(retv->size())); for (uint32 i = 0; i < retv->size(); i++) { - WriteNum((*retv)[i].first.Idx()); - WriteNum((*retv)[i].second.GetFieldID()); - WriteNum((*retv)[i].second.GetPregIdx()); + RegFieldPair rfp = (*retv)[i].second; + if (rfp.IsReg()) { + MIRPreg *preg = curFunc->GetPregTab()->PregFromPregIdx(rfp.GetPregIdx()); + OutputPreg(preg); + } else { + WriteNum(0); + WriteNum((rfp.GetFieldID())); + OutputLocalSymbol(curFunc->GetLocalOrGlobalSymbol((*retv)[i].first)); + } } } @@ -398,7 +379,6 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { ExpandFourBuffSize(); // place holder, Fixup later for (StmtNode *s = block->GetFirst(); s; s = s->GetNext()) { bool doneWithOpnds = false; - WriteNum(kBinOpStatement); OutputSrcPos(s->GetSrcPos()); WriteNum(s->GetOpCode()); switch (s->GetOpCode()) { @@ -417,36 +397,35 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { } WriteNum(stIdx.Scope()); if (stIdx.Islocal()) { - WriteNum(stIdx.Idx()); // preserve original st index + OutputLocalSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx)); } else { - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(stIdx.Idx()); - WriteNum(kBinKindSymViaSymname); - OutputStr(sym->GetNameStrIdx()); + OutputSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx)); } break; } case OP_regassign: { RegassignNode *rass = static_cast(s); - WriteNum(rass->GetPrimType()); - WriteNum(rass->GetRegIdx()); + Write(static_cast(rass->GetPrimType())); + MIRPreg *preg = curFunc->GetPregTab()->PregFromPregIdx(rass->GetRegIdx()); + OutputPreg(preg); break; } case OP_iassign: { IassignNode *iass = static_cast(s); - OutputTypeViaTypeName(iass->GetTyIdx()); + OutputType(iass->GetTyIdx()); WriteNum(iass->GetFieldID()); break; } case OP_iassignoff: { IassignoffNode *iassoff = static_cast(s); - WriteNum(iassoff->GetPrimType()); + Write(static_cast(iassoff->GetPrimType())); WriteNum(iassoff->GetOffset()); break; } case OP_iassignspoff: case OP_iassignfpoff: { IassignFPoffNode *iassfpoff = static_cast(s); - WriteNum(iassfpoff->GetPrimType()); + Write(static_cast(iassfpoff->GetPrimType())); WriteNum(iassfpoff->GetOffset()); break; } @@ -466,9 +445,9 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { case OP_customcall: case OP_polymorphiccall: { CallNode *callnode = static_cast(s); - OutputFuncViaSymName(callnode->GetPUIdx()); + OutputFuncViaSym(callnode->GetPUIdx()); if (s->GetOpCode() == OP_polymorphiccall) { - OutputTypeViaTypeName(static_cast(callnode)->GetTyIdx()); + OutputType(static_cast(callnode)->GetTyIdx()); } WriteNum(static_cast(s->NumOpnds())); break; @@ -481,15 +460,15 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { case OP_interfaceicallassigned: case OP_customcallassigned: { CallNode *callnode = static_cast(s); - OutputFuncViaSymName(callnode->GetPUIdx()); + OutputFuncViaSym(callnode->GetPUIdx()); OutputReturnValues(&callnode->GetReturnVec()); WriteNum(static_cast(s->NumOpnds())); break; } case OP_polymorphiccallassigned: { CallNode *callnode = static_cast(s); - OutputFuncViaSymName(callnode->GetPUIdx()); - OutputTypeViaTypeName(callnode->GetTyIdx()); + OutputFuncViaSym(callnode->GetPUIdx()); + OutputType(callnode->GetTyIdx()); OutputReturnValues(&callnode->GetReturnVec()); WriteNum(static_cast(s->NumOpnds())); break; @@ -497,13 +476,14 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { case OP_icallproto: case OP_icall: { IcallNode *icallnode = static_cast(s); - OutputTypeViaTypeName(icallnode->GetRetTyIdx()); + OutputType(icallnode->GetRetTyIdx()); WriteNum(static_cast(s->NumOpnds())); break; } + case OP_icallprotoassigned: case OP_icallassigned: { IcallNode *icallnode = static_cast(s); - OutputTypeViaTypeName(icallnode->GetRetTyIdx()); + OutputType(icallnode->GetRetTyIdx()); OutputReturnValues(&icallnode->GetReturnVec()); WriteNum(static_cast(s->NumOpnds())); break; @@ -526,14 +506,14 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { case OP_intrinsiccallwithtype: { IntrinsiccallNode *intrnNode = static_cast(s); WriteNum(intrnNode->GetIntrinsic()); - OutputTypeViaTypeName(intrnNode->GetTyIdx()); + OutputType(intrnNode->GetTyIdx()); WriteNum(static_cast(s->NumOpnds())); break; } case OP_intrinsiccallwithtypeassigned: { IntrinsiccallNode *intrnNode = static_cast(s); WriteNum(intrnNode->GetIntrinsic()); - OutputTypeViaTypeName(intrnNode->GetTyIdx()); + OutputType(intrnNode->GetTyIdx()); OutputReturnValues(&intrnNode->GetReturnVec()); WriteNum(static_cast(s->NumOpnds())); break; @@ -568,28 +548,28 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { } case OP_label: { LabelNode *lNode = static_cast(s); - WriteNum(lNode->GetLabelIdx()); + OutputLabel(lNode->GetLabelIdx()); break; } case OP_goto: case OP_gosub: { GotoNode *gtoNode = static_cast(s); - WriteNum(gtoNode->GetOffset()); + OutputLabel(gtoNode->GetOffset()); break; } case OP_brfalse: case OP_brtrue: { CondGotoNode *cgotoNode = static_cast(s); - WriteNum(cgotoNode->GetOffset()); + OutputLabel(cgotoNode->GetOffset()); break; } case OP_switch: { SwitchNode *swNode = static_cast(s); - WriteNum(swNode->GetDefaultLabel()); + OutputLabel(swNode->GetDefaultLabel()); WriteNum(static_cast(swNode->GetSwitchTable().size())); for (CasePair cpair : swNode->GetSwitchTable()) { WriteNum(cpair.first); - WriteNum(cpair.second); + OutputLabel(cpair.second); } break; } @@ -599,14 +579,14 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { WriteNum(static_cast(rgoto->GetRangeGotoTable().size())); for (SmallCasePair cpair : rgoto->GetRangeGotoTable()) { WriteNum(cpair.first); - WriteNum(cpair.second); + OutputLabel(cpair.second); } break; } case OP_jstry: { JsTryNode *tryNode = static_cast(s); - WriteNum(tryNode->GetCatchOffset()); - WriteNum(tryNode->GetFinallyOffset()); + OutputLabel(tryNode->GetCatchOffset()); + OutputLabel(tryNode->GetFinallyOffset()); break; } case OP_cpptry: @@ -614,7 +594,7 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { TryNode *tryNode = static_cast(s); WriteNum(static_cast(tryNode->GetOffsetsCount())); for (LabelIdx lidx : tryNode->GetOffsets()) { - WriteNum(lidx); + OutputLabel(lidx); } break; } @@ -622,7 +602,7 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { CatchNode *catchNode = static_cast(s); WriteNum(static_cast(catchNode->GetExceptionTyIdxVec().size())); for (TyIdx tidx : catchNode->GetExceptionTyIdxVec()) { - OutputTypeViaTypeName(tidx); + OutputType(tidx); } break; } @@ -679,7 +659,7 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { count = asmNode->gotoLabels.size(); WriteNum(static_cast(count)); for (size_t i = 0; i < count; ++i) { - WriteNum(asmNode->gotoLabels[i]); + OutputLabel(asmNode->gotoLabels[i]); } // the inputs WriteNum(asmNode->NumOpnds()); @@ -714,6 +694,7 @@ void BinaryMplExport::WriteFunctionBodyField(uint64 contentIdx, std::unordered_s if (not2mplt) { for (MIRFunction *func : GetMIRModule().GetFunctionList()) { + curFunc = func; if (func->GetAttr(FUNCATTR_optimized)) { continue; } @@ -734,12 +715,15 @@ void BinaryMplExport::WriteFunctionBodyField(uint64 contentIdx, std::unordered_s continue; } } + localSymMark.clear(); + localSymMark[nullptr] = 0; + localPregMark.clear(); + localPregMark[nullptr] = 0; + labelMark.clear(); + labelMark[0] = 0; OutputFunction(func->GetPuidx()); CHECK_FATAL(func->GetBody() != nullptr, "WriteFunctionBodyField: no function body"); OutputFuncIdInfo(func); - OutputPregTab(func); - OutputLocalSymTab(func); - OutputLabelTab(func); OutputLocalTypeNameTab(func->GetTypeNameTab()); OutputFormalsStIdx(func); if (mod.GetFlavor() < kMmpl) { @@ -753,7 +737,6 @@ void BinaryMplExport::WriteFunctionBodyField(uint64 contentIdx, std::unordered_s Fixup(totalSizeIdx, static_cast(buf.size() - totalSizeIdx)); Fixup(outFunctionBodySizeIdx, size); - WriteNum(~kBinFunctionBodyStart); return; } } // namespace maple diff --git a/src/mapleall/maple_ir/src/bin_func_import.cpp b/src/mapleall/maple_ir/src/bin_func_import.cpp index 959784554b..b23b6895f4 100644 --- a/src/mapleall/maple_ir/src/bin_func_import.cpp +++ b/src/mapleall/maple_ir/src/bin_func_import.cpp @@ -44,29 +44,27 @@ void BinaryMplImport::ImportFuncIdInfo(MIRFunction *func) { func->SetPuidxOrigin(static_cast(ReadNum())); ImportInfoVector(func->GetInfoVector(), func->InfoIsString()); if (mod.GetFlavor() == kFlavorLmbc) { - func->SetUpFormalSize(static_cast(ReadNum())); func->SetFrameSize(static_cast(ReadNum())); - func->SetOutParmSize(static_cast(ReadNum())); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinFuncIdInfoStart, "pattern mismatch in ImportFuncIdInfo()"); } void BinaryMplImport::ImportBaseNode(Opcode &o, PrimType &typ) { - o = (Opcode)ReadNum(); - typ = (PrimType)ReadNum(); + o = (Opcode)Read(); + typ = (PrimType)Read(); } -void BinaryMplImport::ImportLocalSymbol(MIRFunction *func) { +MIRSymbol *BinaryMplImport::ImportLocalSymbol(MIRFunction *func) { int64 tag = ReadNum(); if (tag == 0) { - func->GetSymTab()->PushNullSymbol(); - return; + return nullptr; } + if (tag < 0) { + CHECK_FATAL(static_cast(-tag) < localSymTab.size(), "index out of bounds"); + return localSymTab.at(-tag); + } CHECK_FATAL(tag == kBinSymbol, "expecting kBinSymbol in ImportLocalSymbol()"); - auto indx = static_cast(ReadNum()); - CHECK_FATAL(indx == func->GetSymTab()->GetSymbolTableSize(), "inconsistant local stIdx"); MIRSymbol *sym = func->GetSymTab()->CreateSymbol(kScopeLocal); + localSymTab.push_back(sym); sym->SetNameStrIdx(ImportStr()); (void)func->GetSymTab()->AddToStringSymbolMap(*sym); sym->SetSKind((MIRSymKind)ReadNum()); @@ -78,66 +76,52 @@ void BinaryMplImport::ImportLocalSymbol(MIRFunction *func) { } sym->SetTyIdx(ImportType()); if (sym->GetSKind() == kStPreg) { - auto thepregno = static_cast(ReadNum()); - MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx()); - PregIdx pregidx = func->GetPregTab()->EnterPregNo(thepregno, mirType->GetPrimType(), mirType); - MIRPregTable *pregTab = func->GetPregTab(); - MIRPreg *preg = pregTab->PregFromPregIdx(pregidx); - preg->SetPrimType(mirType->GetPrimType()); + PregIdx pregidx = ImportPreg(func); + MIRPreg *preg = func->GetPregTab()->PregFromPregIdx(pregidx); sym->SetPreg(preg); } else if (sym->GetSKind() == kStConst || sym->GetSKind() == kStVar) { sym->SetKonst(ImportConst(func)); } else if (sym->GetSKind() == kStFunc) { - PUIdx puIdx = ImportFuncViaSymName(); - TyIdx tyIdx = ImportType(); - sym->SetTyIdx(tyIdx); + PUIdx puIdx = ImportFuncViaSym(func); sym->SetFunction(GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx)); } + return sym; } -void BinaryMplImport::ImportLocalSymTab(MIRFunction *func) { +PregIdx BinaryMplImport::ImportPreg(MIRFunction *func) { int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinSymStart, "kBinSymStart expected in ImportLocalSymTab()"); - int32 size = ReadInt(); - for (int64 i = 0; i < size; ++i) { - ImportLocalSymbol(func); + if (tag == 0) { + return 0; } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinSymStart, "pattern mismatch in ImportLocalSymTab()"); -} - -void BinaryMplImport::ImportPregTab(const MIRFunction *func) { - int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinPregStart, "kBinPregStart expected in ImportPregTab()"); - int32 size = ReadInt(); - for (int64 i = 0; i < size; ++i) { - int64 nextTag = ReadNum(); - if (nextTag == 0) { - func->GetPregTab()->GetPregTable().push_back(nullptr); - continue; - } - CHECK_FATAL(nextTag == kBinPreg, "expecting kBinPreg in ImportPregTab()"); - auto pregNo = static_cast(ReadNum()); - TyIdx tyIdx = ImportType(); - MIRType *ty = (tyIdx == 0) ? nullptr : GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); - PrimType primType = (PrimType)ReadNum(); - CHECK_FATAL(ty == nullptr || primType == ty->GetPrimType(), "ImportPregTab: inconsistent primitive type"); - (void)func->GetPregTab()->EnterPregNo(pregNo, primType, ty); + if (tag == kBinSpecialReg) { + return -Read(); + } + if (tag < 0) { + CHECK_FATAL(static_cast(-tag) < localPregTab.size(), "index out of bounds"); + return localPregTab.at(-tag); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinPregStart, "pattern mismatch in ImportPregTab()"); + CHECK_FATAL(tag == kBinPreg, "expecting kBinPreg in ImportPreg()"); + + PrimType primType = (PrimType)Read(); + PregIdx pidx = func->GetPregTab()->CreatePreg(primType); + localPregTab.push_back(pidx); + return pidx; } -void BinaryMplImport::ImportLabelTab(MIRFunction *func) { +LabelIdx BinaryMplImport::ImportLabel(MIRFunction *func) { int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinLabelStart, "kBinLabelStart expected in ImportLabelTab()"); - int64 size = ReadNum(); - for (int64 i = 0; i < size; ++i) { - GStrIdx gStrIdx = ImportStr(); - (void)func->GetLabelTab()->AddLabel(gStrIdx); + if (tag == 0) { + return 0; + } + if (tag < 0) { + CHECK_FATAL(static_cast(-tag) < localLabelTab.size(), "index out of bounds"); + return localLabelTab.at(-tag); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinLabelStart, "pattern mismatch in ImportLabelTab()"); + CHECK_FATAL(tag == kBinLabel, "kBinLabel expected in ImportLabel()"); + + LabelIdx lidx = func->GetLabelTab()->CreateLabel(); + localLabelTab.push_back(lidx); + return lidx; } void BinaryMplImport::ImportLocalTypeNameTable(MIRTypeNameTable *typeNameTab) { @@ -149,8 +133,6 @@ void BinaryMplImport::ImportLocalTypeNameTable(MIRTypeNameTable *typeNameTab) { TyIdx tyIdx = ImportType(); typeNameTab->SetGStrIdxToTyIdx(strIdx, tyIdx); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinTypenameStart, "pattern mismatch in ImportTypenametab()"); } void BinaryMplImport::ImportFormalsStIdx(MIRFunction *func) { @@ -158,11 +140,8 @@ void BinaryMplImport::ImportFormalsStIdx(MIRFunction *func) { CHECK_FATAL(tag == kBinFormalStart, "kBinFormalStart expected in ImportFormalsStIdx()"); auto size = ReadNum(); for (int64 i = 0; i < size; ++i) { - uint32 indx = static_cast(ReadNum()); - func->GetFormalDefVec()[static_cast(i)].formalSym = func->GetSymTab()->GetSymbolFromStIdx(indx); + func->GetFormalDefVec()[static_cast(i)].formalSym = ImportLocalSymbol(func); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinFormalStart, "pattern mismatch in ImportFormalsStIdx()"); } void BinaryMplImport::ImportAliasMap(MIRFunction *func) { @@ -177,23 +156,15 @@ void BinaryMplImport::ImportAliasMap(MIRFunction *func) { (void)ImportStr(); // not assigning to mimic parser func->GetAliasVarMap()[strIdx] = aliasvars; } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinAliasMapStart, "pattern mismatch in ImportAliasMap()"); } -PUIdx BinaryMplImport::ImportFuncViaSymName() { - int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinKindFuncViaSymname, "kBinKindFuncViaSymname expected"); - GStrIdx strIdx = ImportStr(); - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx); - ASSERT(sym != nullptr, "null ptr check"); - MIRFunction *func = sym->GetFunction(); - return func->GetPuidx(); +PUIdx BinaryMplImport::ImportFuncViaSym(MIRFunction *func) { + MIRSymbol *sym = InSymbol(func); + MIRFunction *f = sym->GetFunction(); + return f->GetPuidx(); } BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { - int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinOpExpression, "kBinOpExpression expected"); Opcode op; PrimType typ; ImportBaseNode(op, typ); @@ -213,13 +184,15 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { } case OP_addroflabel: { AddroflabelNode *alabNode = mod.CurFuncCodeMemPool()->New(); - alabNode->SetOffset(static_cast(ReadNum())); + alabNode->SetOffset(ImportLabel(func)); alabNode->SetPrimType(typ); (void)func->GetLabelTab()->addrTakenLabels.insert(alabNode->GetOffset()); return alabNode; } case OP_addroffunc: { - PUIdx puIdx = ImportFuncViaSymName(); + PUIdx puIdx = ImportFuncViaSym(func); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFuncTable()[puIdx]; + f->GetFuncSymbol()->SetAppearsInCode(true); AddroffuncNode *addrNode = mod.CurFuncCodeMemPool()->New(typ, puIdx); return addrNode; } @@ -235,19 +208,18 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { int32 num = static_cast(ReadNum()); StIdx stIdx; stIdx.SetScope(static_cast(ReadNum())); + MIRSymbol *sym = nullptr; if (stIdx.Islocal()) { - stIdx.SetIdx(static_cast(ReadNum())); + sym = ImportLocalSymbol(func); + CHECK_FATAL(sym != nullptr, "null ptr check"); } else { - int32 stag = static_cast(ReadNum()); - CHECK_FATAL(stag == kBinKindSymViaSymname, "kBinKindSymViaSymname expected"); - GStrIdx strIdx = ImportStr(); - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx); - ASSERT(sym != nullptr, "null ptr check"); + sym = InSymbol(func); + CHECK_FATAL(sym != nullptr, "null ptr check"); if (op == OP_addrof) { sym->SetHasPotentialAssignment(); } - stIdx.SetIdx(sym->GetStIdx().Idx()); } + stIdx.SetIdx(sym->GetStIdx().Idx()); if (op == OP_addrof || op == OP_dread) { AddrofNode *drNode = mod.CurFuncCodeMemPool()->New(op); drNode->SetPrimType(typ); @@ -264,7 +236,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { } case OP_regread: { RegreadNode *regreadNode = mod.CurFuncCodeMemPool()->New(); - regreadNode->SetRegIdx(static_cast(ReadNum())); + regreadNode->SetRegIdx(ImportPreg(func)); regreadNode->SetPrimType(typ); return regreadNode; } @@ -293,7 +265,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_floor: case OP_trunc: { TypeCvtNode *typecvtNode = mod.CurFuncCodeMemPool()->New(op, typ); - typecvtNode->SetFromType((PrimType)ReadNum()); + typecvtNode->SetFromType((PrimType)Read()); typecvtNode->SetOpnd(ImportExpression(func), 0); return typecvtNode; } @@ -326,15 +298,15 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_zext: case OP_extractbits: { ExtractbitsNode *extNode = mod.CurFuncCodeMemPool()->New(op, typ); - extNode->SetBitsOffset(static_cast(ReadNum())); - extNode->SetBitsSize(static_cast(ReadNum())); + extNode->SetBitsOffset(Read()); + extNode->SetBitsSize(Read()); extNode->SetOpnd(ImportExpression(func), 0); return extNode; } case OP_depositbits: { DepositbitsNode *dbNode = mod.CurFuncCodeMemPool()->New(op, typ); - dbNode->SetBitsOffset(static_cast(ReadNum())); - dbNode->SetBitsSize(static_cast(ReadNum())); + dbNode->SetBitsOffset(ReadNum()); + dbNode->SetBitsSize(ReadNum()); dbNode->SetOpnd(ImportExpression(func), 0); dbNode->SetOpnd(ImportExpression(func), 1); return dbNode; @@ -379,7 +351,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_cmpl: case OP_cmp: { CompareNode *cmpNode = mod.CurFuncCodeMemPool()->New(op, typ); - cmpNode->SetOpndType((PrimType)ReadNum()); + cmpNode->SetOpndType((PrimType)Read()); cmpNode->SetOpnd(ImportExpression(func), 0); cmpNode->SetOpnd(ImportExpression(func), 1); return cmpNode; @@ -387,7 +359,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_resolveinterfacefunc: case OP_resolvevirtualfunc: { ResolveFuncNode *rsNode = mod.CurFuncCodeMemPool()->New(op, typ); - rsNode->SetPUIdx(ImportFuncViaSymName()); + rsNode->SetPUIdx(ImportFuncViaSym(func)); rsNode->SetOpnd(ImportExpression(func), 0); rsNode->SetOpnd(ImportExpression(func), 1); return rsNode; @@ -403,7 +375,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { // nary case OP_array: { TyIdx tidx = ImportType(); - auto boundsCheck = static_cast(ReadNum()); + bool boundsCheck = static_cast(Read()); ArrayNode *arrNode = mod.CurFuncCodeMemPool()->New(func->GetCodeMPAllocator(), typ, tidx, boundsCheck); auto n = static_cast(ReadNum()); @@ -436,12 +408,15 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { return intrnNode; } default: - CHECK_FATAL(false, "Unhandled op %d", tag); + CHECK_FATAL(false, "Unhandled op %d", op); break; } } void BinaryMplImport::ImportSrcPos(SrcPosition &pos) { + if (!mod.IsWithDbgInfo()) { + return; + } pos.SetRawData(static_cast(ReadNum())); pos.SetLineNum(static_cast(ReadNum())); } @@ -451,15 +426,16 @@ void BinaryMplImport::ImportReturnValues(MIRFunction *func, CallReturnVector *re CHECK_FATAL(tag == kBinReturnvals, "expecting return values"); auto size = static_cast(ReadNum()); for (uint32 i = 0; i < size; ++i) { - uint32 idx = static_cast(ReadNum()); - FieldID fid = static_cast(ReadNum()); - PregIdx ridx = static_cast(ReadNum()); - retv->push_back(std::make_pair(StIdx(kScopeLocal, idx), RegFieldPair(fid, ridx))); - if (idx == 0) { + RegFieldPair rfp; + rfp.SetPregIdx(ImportPreg(func)); + if (rfp.IsReg()) { + retv->push_back(std::make_pair(StIdx(), rfp)); continue; } - MIRSymbol *lsym = func->GetSymTab()->GetSymbolFromStIdx(idx, false); - ASSERT(lsym != nullptr, "null ptr check"); + rfp.SetFieldID(static_cast(ReadNum())); + MIRSymbol *lsym = ImportLocalSymbol(func); + CHECK_FATAL(lsym != nullptr, "null ptr check"); + retv->push_back(std::make_pair(lsym->GetStIdx(), rfp)); if (lsym->GetName().find("L_STR") == 0) { MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(lsym->GetTyIdx()); CHECK_FATAL(ty->GetKind() == kTypePointer, "Pointer type expected for L_STR prefix"); @@ -480,8 +456,6 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { ImportSrcPos(block->GetSrcPos()); int32 size = ReadInt(); for (int32 k = 0; k < size; ++k) { - tag = ReadNum(); - CHECK_FATAL(tag == kBinOpStatement, "kBinOpStatement expected"); SrcPosition thesrcPosition; ImportSrcPos(thesrcPosition); op = (Opcode)ReadNum(); @@ -496,17 +470,16 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { int32 num = static_cast(ReadNum()); StIdx stIdx; stIdx.SetScope(static_cast(ReadNum())); + MIRSymbol *sym = nullptr; if (stIdx.Islocal()) { - stIdx.SetIdx(static_cast(ReadNum())); + sym = ImportLocalSymbol(func); + CHECK_FATAL(sym != nullptr, "null ptr check"); } else { - int32 stag = static_cast(ReadNum()); - CHECK_FATAL(stag == kBinKindSymViaSymname, "kBinKindSymViaSymname expected"); - GStrIdx strIdx = ImportStr(); - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx); - ASSERT(sym != nullptr, "null ptr check"); + sym = InSymbol(func); + CHECK_FATAL(sym != nullptr, "null ptr check"); sym->SetHasPotentialAssignment(); - stIdx.SetIdx(sym->GetStIdx().Idx()); } + stIdx.SetIdx(sym->GetStIdx().Idx()); if (op == OP_dassign) { DassignNode *s = func->GetCodeMemPool()->New(); s->SetStIdx(stIdx); @@ -525,8 +498,8 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_regassign: { RegassignNode *s = func->GetCodeMemPool()->New(); - s->SetPrimType((PrimType)ReadNum()); - s->SetRegIdx(static_cast(ReadNum())); + s->SetPrimType((PrimType)Read()); + s->SetRegIdx(ImportPreg(func)); s->SetOpnd(ImportExpression(func), 0); stmt = s; break; @@ -542,7 +515,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_iassignoff: { IassignoffNode *s = func->GetCodeMemPool()->New(); - s->SetPrimType((PrimType)ReadNum()); + s->SetPrimType((PrimType)Read()); s->SetOffset(static_cast(ReadNum())); s->SetOpnd(ImportExpression(func), 0); s->SetOpnd(ImportExpression(func), 1); @@ -552,7 +525,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { case OP_iassignspoff: case OP_iassignfpoff: { IassignFPoffNode *s = func->GetCodeMemPool()->New(op); - s->SetPrimType((PrimType)ReadNum()); + s->SetPrimType((PrimType)Read()); s->SetOffset(static_cast(ReadNum())); s->SetOpnd(ImportExpression(func), 0); stmt = s; @@ -577,7 +550,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { case OP_interfaceicall: case OP_customcall: { CallNode *s = func->GetCodeMemPool()->New(mod, op); - s->SetPUIdx(ImportFuncViaSymName()); + s->SetPUIdx(ImportFuncViaSym(func)); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx()); + f->GetFuncSymbol()->SetAppearsInCode(true); numOpr = static_cast(ReadNum()); s->SetNumOpnds(numOpr); for (int32 i = 0; i < numOpr; ++i) { @@ -594,7 +569,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { case OP_interfaceicallassigned: case OP_customcallassigned: { CallNode *s = func->GetCodeMemPool()->New(mod, op); - s->SetPUIdx(ImportFuncViaSymName()); + s->SetPUIdx(ImportFuncViaSym(func)); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx()); + f->GetFuncSymbol()->SetAppearsInCode(true); ImportReturnValues(func, &s->GetReturnVec()); numOpr = static_cast(ReadNum()); s->SetNumOpnds(numOpr); @@ -610,7 +587,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_polymorphiccall: { CallNode *s = func->GetCodeMemPool()->New(mod, op); - s->SetPUIdx(ImportFuncViaSymName()); + s->SetPUIdx(ImportFuncViaSym(func)); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx()); + f->GetFuncSymbol()->SetAppearsInCode(true); s->SetTyIdx(ImportType()); numOpr = static_cast(ReadNum()); s->SetNumOpnds(numOpr); @@ -622,7 +601,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_polymorphiccallassigned: { CallNode *s = func->GetCodeMemPool()->New(mod, op); - s->SetPUIdx(ImportFuncViaSymName()); + s->SetPUIdx(ImportFuncViaSym(func)); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx()); + f->GetFuncSymbol()->SetAppearsInCode(true); s->SetTyIdx(ImportType()); ImportReturnValues(func, &s->GetReturnVec()); numOpr = static_cast(ReadNum()); @@ -645,6 +626,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { stmt = s; break; } + case OP_icallprotoassigned: case OP_icallassigned: { IcallNode *s = func->GetCodeMemPool()->New(mod, op); s->SetRetTyIdx(ImportType()); @@ -759,32 +741,32 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_label: { LabelNode *s = mod.CurFuncCodeMemPool()->New(); - s->SetLabelIdx(static_cast(ReadNum())); + s->SetLabelIdx(ImportLabel(func)); stmt = s; break; } case OP_goto: case OP_gosub: { GotoNode *s = mod.CurFuncCodeMemPool()->New(op); - s->SetOffset(static_cast(ReadNum())); + s->SetOffset(ImportLabel(func)); stmt = s; break; } case OP_brfalse: case OP_brtrue: { CondGotoNode *s = mod.CurFuncCodeMemPool()->New(op); - s->SetOffset(static_cast(ReadNum())); + s->SetOffset(ImportLabel(func)); s->SetOpnd(ImportExpression(func), 0); stmt = s; break; } case OP_switch: { SwitchNode *s = mod.CurFuncCodeMemPool()->New(mod); - s->SetDefaultLabel(static_cast(ReadNum())); + s->SetDefaultLabel(ImportLabel(func)); auto tagSize = static_cast(ReadNum()); for (uint32 i = 0; i < tagSize; ++i) { int64 casetag = ReadNum(); - LabelIdx lidx(ReadNum()); + LabelIdx lidx = ImportLabel(func); CasePair cpair = std::make_pair(casetag, lidx); s->GetSwitchTable().push_back(cpair); } @@ -798,7 +780,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { uint32 tagSize = static_cast(ReadNum()); for (uint32 i = 0; i < tagSize; ++i) { uint16 casetag = static_cast(ReadNum()); - LabelIdx lidx(ReadNum()); + LabelIdx lidx = ImportLabel(func); s->AddRangeGoto(casetag, lidx); } s->SetOpnd(ImportExpression(func), 0); @@ -807,8 +789,8 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_jstry: { JsTryNode *s = mod.CurFuncCodeMemPool()->New(); - s->SetCatchOffset(static_cast(ReadNum())); - s->SetFinallyOffset(static_cast(ReadNum())); + s->SetCatchOffset(ImportLabel(func)); + s->SetFinallyOffset(ImportLabel(func)); stmt = s; break; } @@ -817,7 +799,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { TryNode *s = mod.CurFuncCodeMemPool()->New(mod); auto numLabels = static_cast(ReadNum()); for (uint32 i = 0; i < numLabels; ++i) { - s->GetOffsets().push_back(ReadNum()); + s->GetOffsets().push_back(ImportLabel(func)); } stmt = s; break; @@ -887,7 +869,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { // the labels count = static_cast(ReadNum()); for (size_t i = 0; i < count; ++i) { - auto lidx = static_cast(ReadNum()); + LabelIdx lidx = ImportLabel(func); s->gotoLabels.push_back(lidx); } // the inputs @@ -927,6 +909,13 @@ void BinaryMplImport::ReadFunctionBodyField() { PUIdx puIdx = ImportFunction(); MIRFunction *fn = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); mod.SetCurFunction(fn); + fn->GetFuncSymbol()->SetAppearsInCode(true); + localSymTab.clear(); + localSymTab.push_back(nullptr); + localPregTab.clear(); + localPregTab.push_back(0); + localLabelTab.clear(); + localLabelTab.push_back(0); fn->AllocSymTab(); fn->AllocPregTab(); @@ -934,9 +923,6 @@ void BinaryMplImport::ReadFunctionBodyField() { fn->AllocLabelTab(); ImportFuncIdInfo(fn); - ImportPregTab(fn); - ImportLocalSymTab(fn); - ImportLabelTab(fn); ImportLocalTypeNameTable(fn->GetTypeNameTab()); ImportFormalsStIdx(fn); if (mod.GetFlavor() < kMmpl) { @@ -945,8 +931,6 @@ void BinaryMplImport::ReadFunctionBodyField() { (void)ImportBlockNode(fn); mod.AddFunction(fn); } - int64 tag = ReadNum(); - CHECK_FATAL(tag == ~kBinFunctionBodyStart, "pattern mismatch in Read FunctionBody"); return; } } // namespace maple diff --git a/src/mapleall/maple_ir/src/bin_mpl_export.cpp b/src/mapleall/maple_ir/src/bin_mpl_export.cpp index 21fb6691f9..4359ae9f55 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_export.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_export.cpp @@ -26,7 +26,7 @@ namespace { using namespace maple; using OutputConstFactory = FunctionFactory; -using OutputTypeFactory = FunctionFactory; +using OutputTypeFactory = FunctionFactory; void OutputConstInt(const MIRConst &constVal, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindConstInt); @@ -62,7 +62,7 @@ void OutputConstLbl(const MIRConst &constVal, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindConstAddrofLabel); mplExport.OutputConstBase(constVal); const MIRLblConst &lblConst = static_cast(constVal); - mplExport.WriteNum(lblConst.GetValue()); // LabelIdx not needed to output puIdx + mplExport.OutputLabel(lblConst.GetValue()); } void OutputConstStr(const MIRConst &constVal, BinaryMplExport &mplExport) { @@ -141,39 +141,39 @@ static bool InitOutputConstFactory() { return true; } -void OutputTypeScalar(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeScalar(const MIRType &ty, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindTypeScalar); mplExport.OutputTypeBase(ty); } -void OutputTypePointer(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypePointer(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypePointer); mplExport.OutputTypeBase(type); mplExport.OutputTypeAttrs(type.GetTypeAttrs()); - mplExport.OutputType(type.GetPointedTyIdx(), canUseTypename); + mplExport.OutputType(type.GetPointedTyIdx()); } -void OutputTypeByName(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeByName(const MIRType &ty, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindTypeByName); mplExport.OutputTypeBase(ty); } -void OutputTypeFArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeFArray(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeFArray); mplExport.OutputTypeBase(type); - mplExport.OutputType(type.GetElemTyIdx(), canUseTypename); + mplExport.OutputType(type.GetElemTyIdx()); } -void OutputTypeJArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeJArray(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeJarray); mplExport.OutputTypeBase(type); - mplExport.OutputType(type.GetElemTyIdx(), canUseTypename); + mplExport.OutputType(type.GetElemTyIdx()); } -void OutputTypeArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeArray(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeArray); mplExport.OutputTypeBase(type); @@ -181,20 +181,20 @@ void OutputTypeArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseT for (uint16 i = 0; i < type.GetDim(); ++i) { mplExport.WriteNum(type.GetSizeArrayItem(i)); } - mplExport.OutputType(type.GetElemTyIdx(), canUseTypename); + mplExport.OutputType(type.GetElemTyIdx()); mplExport.OutputTypeAttrs(type.GetTypeAttrs()); } -void OutputTypeFunction(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeFunction(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeFunction); mplExport.OutputTypeBase(type); - mplExport.OutputType(type.GetRetTyIdx(), canUseTypename); - mplExport.WriteNum(type.IsVarargs()); + mplExport.OutputType(type.GetRetTyIdx()); + mplExport.WriteNum(type.funcAttrs.GetAttrFlag()); size_t size = type.GetParamTypeList().size(); mplExport.WriteNum(size); for (size_t i = 0; i < size; ++i) { - mplExport.OutputType(type.GetNthParamType(i), canUseTypename); + mplExport.OutputType(type.GetNthParamType(i)); } size = type.GetParamAttrsList().size(); mplExport.WriteNum(size); @@ -203,13 +203,13 @@ void OutputTypeFunction(const MIRType &ty, BinaryMplExport &mplExport, bool canU } } -void OutputTypeParam(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeParam(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeParam); mplExport.OutputTypeBase(type); } -void OutputTypeInstantVector(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeInstantVector(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeInstantVector); mplExport.OutputTypeBase(type); @@ -217,15 +217,15 @@ void OutputTypeInstantVector(const MIRType &ty, BinaryMplExport &mplExport, bool mplExport.OutputTypePairs(type); } -void OutputTypeGenericInstant(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeGenericInstant(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeGenericInstant); mplExport.OutputTypeBase(type); mplExport.OutputTypePairs(type); - mplExport.OutputType(type.GetGenericTyIdx(), canUseTypename); + mplExport.OutputType(type.GetGenericTyIdx()); } -void OutputTypeBitField(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeBitField(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeBitField); mplExport.OutputTypeBase(type); @@ -233,7 +233,7 @@ void OutputTypeBitField(const MIRType &ty, BinaryMplExport &mplExport, bool) { } // for Struct/StructIncomplete/Union -void OutputTypeStruct(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeStruct(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeStruct); mplExport.OutputTypeBase(type); @@ -249,7 +249,7 @@ void OutputTypeStruct(const MIRType &ty, BinaryMplExport &mplExport, bool) { } } -void OutputTypeClass(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeClass(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeClass); mplExport.OutputTypeBase(type); @@ -264,7 +264,7 @@ void OutputTypeClass(const MIRType &ty, BinaryMplExport &mplExport, bool) { } } -void OutputTypeInterface(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeInterface(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeInterface); mplExport.OutputTypeBase(type); @@ -279,7 +279,7 @@ void OutputTypeInterface(const MIRType &ty, BinaryMplExport &mplExport, bool) { } } -void OutputTypeConstString(const MIRType &ty, BinaryMplExport&, bool) { +void OutputTypeConstString(const MIRType &ty, BinaryMplExport&) { ASSERT(false, "Type's kind not yet implemented: %d", ty.GetKind()); (void)ty; } @@ -397,7 +397,7 @@ void BinaryMplExport::DumpBuf(const std::string &name) { void BinaryMplExport::OutputConstBase(const MIRConst &constVal) { WriteNum(constVal.GetKind()); - OutputTypeViaTypeName(constVal.GetType().GetTypeIndex()); + OutputType(constVal.GetType().GetTypeIndex()); } void BinaryMplExport::OutputConst(MIRConst *constVal) { @@ -470,8 +470,8 @@ void BinaryMplExport::OutputPragma(const MIRPragma &p) { WriteNum(p.GetKind()); WriteNum(p.GetVisibility()); OutputStr(p.GetStrIdx()); - OutputType(p.GetTyIdx(), false); - OutputType(p.GetTyIdxEx(), false); + OutputType(p.GetTyIdx()); + OutputType(p.GetTyIdxEx()); WriteNum(p.GetParamNum()); size_t size = p.GetElementVector().size(); WriteNum(size); @@ -488,7 +488,7 @@ void BinaryMplExport::OutputTypeBase(const MIRType &type) { void BinaryMplExport::OutputFieldPair(const FieldPair &fp) { OutputStr(fp.first); // GStrIdx - OutputType(fp.second.first, false); // TyIdx + OutputType(fp.second.first); // TyIdx FieldAttrs fa = fp.second.second; WriteNum(fa.GetAttrFlag()); WriteNum(fa.GetAlignValue()); @@ -511,7 +511,7 @@ void BinaryMplExport::OutputMethodPair(const MethodPair &memPool) { MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(memPool.first.Idx()); CHECK_FATAL(funcSt != nullptr, "Pointer funcSt is nullptr, can't get symbol! Check it!"); WriteAsciiStr(GlobalTables::GetStrTable().GetStringFromStrIdx(funcSt->GetNameStrIdx())); - OutputType(memPool.second.first, false); // TyIdx + OutputType(memPool.second.first); // TyIdx WriteNum(memPool.second.second.GetAttrFlag()); // FuncAttrs } @@ -539,7 +539,7 @@ void BinaryMplExport::OutputStructTypeData(const MIRStructType &type) { void BinaryMplExport::OutputImplementedInterfaces(const std::vector &interfaces) { WriteNum(interfaces.size()); for (const TyIdx &tyIdx : interfaces) { - OutputType(tyIdx, false); + OutputType(tyIdx); } } @@ -571,7 +571,7 @@ void BinaryMplExport::OutputPragmaVec(const std::vector &pragmaVec) } void BinaryMplExport::OutputClassTypeData(const MIRClassType &type) { - OutputType(type.GetParentTyIdx(), false); + OutputType(type.GetParentTyIdx()); OutputImplementedInterfaces(type.GetInterfaceImplemented()); OutputInfoIsString(type.GetInfoIsString()); if (!inIPA) { @@ -601,6 +601,7 @@ void BinaryMplExport::Init() { symMark[nullptr] = 0; funcMark[nullptr] = 0; eaNodeMark[nullptr] = 0; + curFunc = nullptr; for (uint32 pti = static_cast(PTY_begin); pti < static_cast(PTY_end); ++pti) { typMark[GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(pti))] = pti; } @@ -612,7 +613,7 @@ void BinaryMplExport::OutputSymbol(MIRSymbol *sym) { return; } - auto it = symMark.find(sym); + std::unordered_map::iterator it = symMark.find(sym); if (it != symMark.end()) { WriteNum(-(it->second)); return; @@ -645,7 +646,7 @@ void BinaryMplExport::OutputSymbol(MIRSymbol *sym) { if (sym->GetSKind() == kStVar || sym->GetSKind() == kStFunc) { OutputSrcPos(sym->GetSrcPosition()); } - OutputTypeViaTypeName(sym->GetTyIdx()); + OutputType(sym->GetTyIdx()); } void BinaryMplExport::OutputFunction(PUIdx puIdx) { @@ -671,7 +672,7 @@ void BinaryMplExport::OutputFunction(PUIdx puIdx) { MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx()); CHECK_FATAL(funcSt != nullptr, "Pointer funcSt is nullptr, cannot get symbol! Check it!"); OutputSymbol(funcSt); - OutputTypeViaTypeName(func->GetMIRFuncType()->GetTypeIndex()); + OutputType(func->GetMIRFuncType()->GetTypeIndex()); WriteNum(func->GetFuncAttrs().GetAttrFlag()); auto &attributes = func->GetFuncAttrs(); @@ -684,12 +685,12 @@ void BinaryMplExport::OutputFunction(PUIdx puIdx) { } WriteNum(func->GetFlag()); - OutputTypeViaTypeName(func->GetClassTyIdx()); + OutputType(func->GetClassTyIdx()); // output formal parameter information WriteNum(static_cast(func->GetFormalDefVec().size())); for (FormalDef formalDef : func->GetFormalDefVec()) { OutputStr(formalDef.formalStrIdx); - OutputType(formalDef.formalTyIdx, false); + OutputType(formalDef.formalTyIdx); WriteNum(static_cast(formalDef.formalAttrs.GetAttrFlag())); } // store Side Effect for each func @@ -751,15 +752,20 @@ void BinaryMplExport::WriteHeaderField(uint64 contentIdx) { WriteNum(mod.GetID()); if (mod.GetFlavor() == kFlavorLmbc) { WriteNum(mod.GetGlobalMemSize()); + WriteNum(mod.IsWithDbgInfo()); } WriteNum(mod.GetNumFuncs()); WriteAsciiStr(mod.GetEntryFuncName()); OutputInfoVector(mod.GetFileInfo(), mod.GetFileInfoIsString()); - WriteNum(static_cast(mod.GetSrcFileInfo().size())); - for (uint32 i = 0; i < mod.GetSrcFileInfo().size(); i++) { - OutputStr(mod.GetSrcFileInfo()[i].first); - WriteNum(mod.GetSrcFileInfo()[i].second); + if (mod.IsWithDbgInfo()) { + WriteNum(static_cast(mod.GetSrcFileInfo().size())); + for (uint32 i = 0; i < mod.GetSrcFileInfo().size(); i++) { + OutputStr(mod.GetSrcFileInfo()[i].first); + WriteNum(mod.GetSrcFileInfo()[i].second); + } + } else { + Write(0); } WriteNum(static_cast(mod.GetImportFiles().size())); @@ -795,7 +801,7 @@ void BinaryMplExport::WriteTypeField(uint64 contentIdx, bool useClassList) { auto *structType = static_cast(type); // skip imported class/interface and incomplete types if (!structType->IsImported() && !structType->IsIncomplete()) { - OutputType(curTyidx, false); + OutputType(curTyidx); ++size; } } @@ -803,7 +809,7 @@ void BinaryMplExport::WriteTypeField(uint64 contentIdx, bool useClassList) { } else { uint32 idx = GlobalTables::GetTypeTable().lastDefaultTyIdx.GetIdx(); for (idx = idx + 1; idx < GlobalTables::GetTypeTable().GetTypeTableSize(); idx++) { - OutputType(TyIdx(idx), false); + OutputType(TyIdx(idx)); size++; } } @@ -884,7 +890,7 @@ void BinaryMplExport::WriteSeField() { GlobalTables::GetGsymTable().GetSymbolFromStrIdx(GlobalTables::GetStrTable().GetStrIdxFromName(funcStr)); MIRFunction *func = (funcSymbol != nullptr) ? GetMIRModule().GetMIRBuilder()->GetFunctionFromSymbol(*funcSymbol) : nullptr; - OutputType(func->GetReturnTyIdx(), false); + OutputType(func->GetReturnTyIdx()); } ++size; } @@ -1103,7 +1109,7 @@ void BinaryMplExport::WriteSymField(uint64 contentIdx) { MIRSymKind sKind = s->GetSKind(); if (s->IsDeleted() || storageClass == kScUnused || (s->GetIsImported() && !s->GetAppearsInCode()) || - (storageClass == kScExtern && sKind == kStFunc)) { + (sKind == kStFunc && (storageClass == kScExtern || !s->GetAppearsInCode()))) { continue; } OutputSymbol(s); @@ -1214,8 +1220,6 @@ void BinaryMplExport::Export(const std::string &fname, std::unordered_setIsNameIsLocal() && ty->GetNameStrIdx() != GStrIdx(0)) { - WriteNum(kBinKindTypeViaTypename); - OutputStr(ty->GetNameStrIdx()); - return; - } - auto func = CreateProductFunction(ty->GetKind()); if (func != nullptr) { - func(*ty, *this, canUseTypename); + func(*ty, *this); } else { ASSERT(false, "Type's kind not yet implemented: %d", ty->GetKind()); } diff --git a/src/mapleall/maple_ir/src/bin_mpl_import.cpp b/src/mapleall/maple_ir/src/bin_mpl_import.cpp index 50779027df..1f79751ed6 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_import.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_import.cpp @@ -129,11 +129,13 @@ MIRConst *BinaryMplImport::ImportConst(MIRFunction *func) { } case kBinKindConstAddrofFunc: { PUIdx puIdx = ImportFunction(); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFuncTable()[puIdx]; + f->GetFuncSymbol()->SetAppearsInCode(true); mod.SetCurFunction(func); return memPool->New(puIdx, *type); } case kBinKindConstAddrofLabel: { - LabelIdx lidx = static_cast(ReadNum()); + LabelIdx lidx = ImportLabel(func); PUIdx puIdx = func->GetPuidx(); MIRLblConst *lblConst = memPool->New(lidx, puIdx, *type); (void)func->GetLabelTab()->addrTakenLabels.insert(lidx); @@ -541,19 +543,6 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { CHECK_FATAL(static_cast(-tag) < typTab.size(), "index out of bounds"); return typTab.at(static_cast(-tag)); } - if (tag == kBinKindTypeViaTypename) { - GStrIdx typenameStrIdx = ImportStr(); - TyIdx tyIdx = mod.GetTypeNameTab()->GetTyIdxFromGStrIdx(typenameStrIdx); - if (tyIdx != 0) { - typTab.push_back(tyIdx); - return tyIdx; - } - MIRTypeByName ltype(typenameStrIdx); - ltype.SetNameIsLocal(false); - MIRType *type = GlobalTables::GetTypeTable().GetOrCreateMIRTypeNode(ltype); - typTab.push_back(type->GetTypeIndex()); - return type->GetTypeIndex(); - } PrimType primType = (PrimType)0; GStrIdx strIdx(0); bool nameIsLocal = false; @@ -580,13 +569,6 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { } return origType->GetTypeIndex(); } - case kBinKindTypeByName: { - MIRTypeByName type(strIdx); - type.SetNameIsLocal(nameIsLocal); - MIRType *origType = &InsertInTypeTables(type); - typTab.push_back(origType->GetTypeIndex()); - return origType->GetTypeIndex(); - } case kBinKindTypeFArray: { MIRFarrayType type(strIdx); type.SetNameIsLocal(nameIsLocal); @@ -629,7 +611,7 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { size_t idx = typTab.size(); typTab.push_back(TyIdx(0)); type.SetRetTyIdx(ImportType()); - type.SetVarArgs(ReadNum()); + type.funcAttrs.SetAttrFlag(ReadNum()); int64 size = ReadNum(); for (int64 i = 0; i < size; ++i) { type.GetParamTypeList().push_back(ImportType()); @@ -737,19 +719,6 @@ TyIdx BinaryMplImport::ImportTypeNonJava() { CHECK_FATAL(static_cast(-tag) < typTab.size(), "index out of bounds"); return typTab[static_cast(-tag)]; } - if (tag == kBinKindTypeViaTypename) { - GStrIdx typenameStrIdx = ImportStr(); - TyIdx tyIdx = mod.GetTypeNameTab()->GetTyIdxFromGStrIdx(typenameStrIdx); - if (tyIdx != 0) { - typTab.push_back(tyIdx); - return tyIdx; - } - MIRTypeByName ltype(typenameStrIdx); - ltype.SetNameIsLocal(false); - MIRType *type = GlobalTables::GetTypeTable().GetOrCreateMIRTypeNode(ltype); - typTab.push_back(type->GetTypeIndex()); - return type->GetTypeIndex(); - } PrimType primType = (PrimType)0; GStrIdx strIdx(0); bool nameIsLocal = false; @@ -771,12 +740,6 @@ TyIdx BinaryMplImport::ImportTypeNonJava() { GlobalTables::GetTypeTable().CreateMirTypeNodeAt(type, tyIdxUsed, &mod, false, false); return tyIdxUsed; } - case kBinKindTypeByName: { - MIRTypeByName type(strIdx); - type.SetNameIsLocal(nameIsLocal); - GlobalTables::GetTypeTable().CreateMirTypeNodeAt(type, tyIdxUsed, &mod, false, false); - return tyIdxUsed; - } case kBinKindTypeFArray: { MIRFarrayType type(strIdx); type.SetNameIsLocal(nameIsLocal); @@ -808,7 +771,7 @@ TyIdx BinaryMplImport::ImportTypeNonJava() { MIRFuncType type(strIdx); type.SetNameIsLocal(nameIsLocal); type.SetRetTyIdx(ImportTypeNonJava()); - type.SetVarArgs(ReadNum()); + type.funcAttrs.SetAttrFlag(ReadNum()); int64 size = ReadNum(); for (int64 i = 0; i < size; ++i) { type.GetParamTypeList().push_back(ImportTypeNonJava()); @@ -1159,6 +1122,7 @@ void BinaryMplImport::ReadHeaderField() { mod.SetID(static_cast(ReadNum())); if (mod.GetFlavor() == kFlavorLmbc) { mod.SetGlobalMemSize(static_cast(ReadNum())); + mod.SetWithDbgInfo(static_cast(ReadNum())); } mod.SetNumFuncs(static_cast(ReadNum())); std::string inStr; diff --git a/src/mapleall/maple_ir/src/global_tables.cpp b/src/mapleall/maple_ir/src/global_tables.cpp index c43e86b2d5..99851d8ec5 100644 --- a/src/mapleall/maple_ir/src/global_tables.cpp +++ b/src/mapleall/maple_ir/src/global_tables.cpp @@ -224,7 +224,9 @@ MIRType *TypeTable::GetOrCreateFunctionType(const TyIdx &retTyIdx, const std::ve const std::vector &vecAttrs, bool isVarg, const TypeAttrs &retAttrs) { MIRFuncType funcType(retTyIdx, vecType, vecAttrs, retAttrs); - funcType.SetVarArgs(isVarg); + if (isVarg) { + funcType.SetVarArgs(); + } TyIdx tyIdx = GetOrCreateMIRType(&funcType); ASSERT(tyIdx < typeTable.size(), "index out of range in TypeTable::GetOrCreateFunctionType"); return typeTable.at(tyIdx); diff --git a/src/mapleall/maple_ir/src/mir_builder.cpp b/src/mapleall/maple_ir/src/mir_builder.cpp index 9e57d1514f..965b2a83c6 100755 --- a/src/mapleall/maple_ir/src/mir_builder.cpp +++ b/src/mapleall/maple_ir/src/mir_builder.cpp @@ -836,6 +836,13 @@ IcallNode *MIRBuilder::CreateStmtIcall(const MapleVector &args) { return stmt; } +IcallNode *MIRBuilder::CreateStmtIcallproto(const MapleVector &args) { + auto *stmt = GetCurrentFuncCodeMp()->New(*GetCurrentFuncCodeMpAllocator(), OP_icallproto); + ASSERT(stmt != nullptr, "stmt is null"); + stmt->SetOpnds(args); + return stmt; +} + IcallNode *MIRBuilder::CreateStmtIcallAssigned(const MapleVector &args, const MIRSymbol &ret) { auto *stmt = GetCurrentFuncCodeMp()->New(*GetCurrentFuncCodeMpAllocator(), OP_icallassigned); CallReturnVector nrets(GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -853,6 +860,23 @@ IcallNode *MIRBuilder::CreateStmtIcallAssigned(const MapleVector &arg return stmt; } +IcallNode *MIRBuilder::CreateStmtIcallprotoAssigned(const MapleVector &args, const MIRSymbol &ret) { + auto *stmt = GetCurrentFuncCodeMp()->New(*GetCurrentFuncCodeMpAllocator(), OP_icallprotoassigned); + CallReturnVector nrets(GetCurrentFuncCodeMpAllocator()->Adapter()); + CHECK_FATAL((ret.GetStorageClass() == kScAuto || ret.GetStorageClass() == kScFormal || + ret.GetStorageClass() == kScExtern || ret.GetStorageClass() == kScGlobal), + "unknown classtype! check it!"); + nrets.emplace_back(CallReturnPair(ret.GetStIdx(), RegFieldPair(0, 0))); + stmt->SetNumOpnds(args.size()); + stmt->GetNopnd().resize(stmt->GetNumOpnds()); + stmt->SetReturnVec(nrets); + for (size_t i = 0; i < stmt->GetNopndSize(); ++i) { + stmt->SetNOpndAt(i, args.at(i)); + } + stmt->SetRetTyIdx(ret.GetTyIdx()); + return stmt; +} + IntrinsiccallNode *MIRBuilder::CreateStmtIntrinsicCall(MIRIntrinsicID idx, const MapleVector &arguments, TyIdx tyIdx) { auto *stmt = GetCurrentFuncCodeMp()->New( diff --git a/src/mapleall/maple_ir/src/mir_function.cpp b/src/mapleall/maple_ir/src/mir_function.cpp index 112f5ad6cf..4f217e54c5 100644 --- a/src/mapleall/maple_ir/src/mir_function.cpp +++ b/src/mapleall/maple_ir/src/mir_function.cpp @@ -368,10 +368,8 @@ void MIRFunction::Dump(bool withoutBody) { LogInfo::MapleLogger() << " )"; } - if (module->GetFlavor() < kMmpl) { + if (module->GetFlavor() != kMmpl) { DumpFlavorLoweredThanMmpl(); - } else { - LogInfo::MapleLogger() << " () void"; } // codeMemPool is nullptr, means maple_ir has been released for memory's sake diff --git a/src/mapleall/maple_ir/src/mir_lower.cpp b/src/mapleall/maple_ir/src/mir_lower.cpp index 401ce4a641..36d572f057 100644 --- a/src/mapleall/maple_ir/src/mir_lower.cpp +++ b/src/mapleall/maple_ir/src/mir_lower.cpp @@ -544,6 +544,19 @@ BlockNode *MIRLower::LowerBlock(BlockNode &block) { case OP_doloop: newBlock->AppendStatementsFromBlock(*LowerDoloopStmt(static_cast(*stmt))); break; + case OP_icallassigned: + case OP_icall: { + if (mirModule.IsCModule()) { + // convert to icallproto/icallprotoassigned + IcallNode *ic = static_cast(stmt); + ic->SetOpCode(stmt->GetOpCode() == OP_icall ? OP_icallproto : OP_icallprotoassigned); + MIRFuncType *funcType = FuncTypeFromFuncPtrExpr(stmt->Opnd(0)); + CHECK_FATAL(funcType != nullptr, "MIRLower::LowerBlock: cannot find prototype for icall"); + ic->SetRetTyIdx(funcType->GetTypeIndex()); + } + newBlock->AddStatement(stmt); + break; + } case OP_block: tmp = LowerBlock(static_cast(*stmt)); newBlock->AppendStatementsFromBlock(*tmp); @@ -999,6 +1012,100 @@ void MIRLower::ExpandArrayMrt(MIRFunction &func) { } } +MIRFuncType *MIRLower::FuncTypeFromFuncPtrExpr(BaseNode *x) { + MIRFuncType *res = nullptr; + MIRFunction *func = mirModule.CurFunction(); + switch (x->GetOpCode()) { + case OP_regread: { + RegreadNode *regread = static_cast(x); + MIRPreg *preg = func->GetPregTab()->PregFromPregIdx(regread->GetRegIdx()); + // see if it is promoted from a symbol + if (preg->GetOp() == OP_dread) { + const MIRSymbol *symbol = preg->rematInfo.sym; + MIRType *mirType = symbol->GetType(); + if (preg->fieldID != 0) { + MIRStructType *structty = static_cast(mirType); + FieldPair thepair = structty->TraverseToField(preg->fieldID); + mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); + } + + if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + if (res != nullptr) { + break; + } + } + // check if a formal promoted to preg + for (FormalDef &formalDef : func->GetFormalDefVec()) { + if (!formalDef.formalSym->IsPreg()) { + continue; + } + if (formalDef.formalSym->GetPreg() == preg) { + MIRType *mirType = formalDef.formalSym->GetType(); + if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + break; + } + } + break; + } + case OP_dread: { + DreadNode *dread = static_cast(x); + MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); + MIRType *mirType = symbol->GetType(); + if (dread->GetFieldID() != 0) { + MIRStructType *structty = static_cast(mirType); + FieldPair thepair = structty->TraverseToField(dread->GetFieldID()); + mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); + } + if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + break; + } + case OP_iread: { + IreadNode *iread = static_cast(x); + MIRPtrType *ptrType = static_cast(iread->GetType()); + MIRType *mirType = ptrType->GetPointedType(); + if (mirType->GetKind() == kTypeFunction) { + res = static_cast(mirType); + } else if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + break; + } + case OP_addroffunc: { + AddroffuncNode *addrofFunc = static_cast(x); + PUIdx puIdx = addrofFunc->GetPUIdx(); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); + res = f->GetMIRFuncType(); + break; + } + case OP_retype: { + MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx( + static_cast(x)->GetTyIdx()); + if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + if (res == nullptr) { + res = FuncTypeFromFuncPtrExpr(x->Opnd(0)); + } + break; + } + case OP_select: { + res = FuncTypeFromFuncPtrExpr(x->Opnd(1)); + if (res == nullptr) { + res = FuncTypeFromFuncPtrExpr(x->Opnd(2)); + } + break; + } + default: CHECK_FATAL(false, "LMBCLowerer::FuncTypeFromFuncPtrExpr: NYI"); + } + return res; +} + const std::set MIRLower::kSetArrayHotFunc = {}; bool MIRLower::ShouldOptArrayMrt(const MIRFunction &func) { diff --git a/src/mapleall/maple_ir/src/mir_nodes.cpp b/src/mapleall/maple_ir/src/mir_nodes.cpp index 50a2ab2df7..a42998b1f2 100755 --- a/src/mapleall/maple_ir/src/mir_nodes.cpp +++ b/src/mapleall/maple_ir/src/mir_nodes.cpp @@ -1201,7 +1201,7 @@ MIRType *IcallNode::GetCallReturnType() { if (op == OP_icall || op == OP_icallassigned) { return GlobalTables::GetTypeTable().GetTypeFromTyIdx(retTyIdx); } - // icallproto + // icallproto or icallprotoassigned MIRFuncType *funcType = static_cast( GlobalTables::GetTypeTable().GetTypeFromTyIdx(retTyIdx)); return GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcType->GetRetTyIdx()); @@ -1226,7 +1226,7 @@ const MIRSymbol *IcallNode::GetCallReturnSymbol(const MIRModule &mod) const { void IcallNode::Dump(int32 indent, bool newline) const { StmtNode::DumpBase(indent); - if (op == OP_icallproto) { + if (op == OP_icallproto || op == OP_icallprotoassigned) { LogInfo::MapleLogger() << " "; GlobalTables::GetTypeTable().GetTypeFromTyIdx(retTyIdx)->Dump(indent + 1); } diff --git a/src/mapleall/maple_ir/src/mir_parser.cpp b/src/mapleall/maple_ir/src/mir_parser.cpp index 9660002e49..b0bbf9080b 100755 --- a/src/mapleall/maple_ir/src/mir_parser.cpp +++ b/src/mapleall/maple_ir/src/mir_parser.cpp @@ -896,6 +896,7 @@ bool MIRParser::ParseStmtCall(StmtNodePtr &stmt) { callStmt->SetPUIdx(pIdx); MIRFunction *callee = GlobalTables::GetFunctionTable().GetFuncTable()[pIdx]; + callee->GetFuncSymbol()->SetAppearsInCode(true); if (callee->GetName() == "setjmp") { mod.CurFunction()->SetHasSetjmp(); } @@ -932,9 +933,14 @@ bool MIRParser::ParseStmtIcall(StmtNodePtr &stmt, Opcode op) { // . . . // dassign } // icallproto (, , ..., ) + // icallprotoassigned (, , ..., ) { + // dassign + // dassign + // . . . + // dassign } IcallNode *iCallStmt = mod.CurFuncCodeMemPool()->New(mod, op); lexer.NextToken(); - if (op == OP_icallproto) { + if (op == OP_icallproto || op == OP_icallprotoassigned) { TyIdx tyIdx(0); if (!ParseDerivedType(tyIdx)) { Error("error parsing type in ParseStmtIcall for icallproto at "); @@ -948,7 +954,7 @@ bool MIRParser::ParseStmtIcall(StmtNodePtr &stmt, Opcode op) { } iCallStmt->SetNOpnd(opndsVec); iCallStmt->SetNumOpnds(opndsVec.size()); - if (op == OP_icallassigned) { + if (op == OP_icallassigned || op == OP_icallprotoassigned) { CallReturnVector retsVec(mod.CurFuncCodeMemPoolAllocator()->Adapter()); if (!ParseCallReturns(retsVec)) { return false; @@ -972,6 +978,10 @@ bool MIRParser::ParseStmtIcallproto(StmtNodePtr &stmt) { return ParseStmtIcall(stmt, OP_icallproto); } +bool MIRParser::ParseStmtIcallprotoassigned(StmtNodePtr &stmt) { + return ParseStmtIcall(stmt, OP_icallprotoassigned); +} + bool MIRParser::ParseStmtIntrinsiccall(StmtNodePtr &stmt, bool isAssigned) { Opcode o = !isAssigned ? (lexer.GetTokenKind() == TK_intrinsiccall ? OP_intrinsiccall : OP_xintrinsiccall) : (lexer.GetTokenKind() == TK_intrinsiccallassigned ? OP_intrinsiccallassigned @@ -2013,18 +2023,6 @@ bool MIRParser::ParseStmtBlockForUpformalSize() { return true; } -bool MIRParser::ParseStmtBlockForOutParmSize() { - MIRFunction *fn = paramCurrFuncForParseStmtBlock; - lexer.NextToken(); - if (lexer.GetTokenKind() != TK_intconst) { - Error("expect integer after outparmsize but get "); - return false; - } - fn->SetOutParmSize(static_cast(lexer.GetTheIntVal())); - lexer.NextToken(); - return true; -} - bool MIRParser::ParseStmtBlockForModuleID() { MIRFunction *fn = paramCurrFuncForParseStmtBlock; lexer.NextToken(); @@ -3241,7 +3239,8 @@ bool MIRParser::ParseConstAddrLeafExpr(MIRConstPtr &cexpr) { } else if (expr->GetOpCode() == OP_addroffunc) { auto *aof = static_cast(expr); MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(aof->GetPUIdx()); - const MIRSymbol *fName = f->GetFuncSymbol(); + MIRSymbol *fName = f->GetFuncSymbol(); + fName->SetAppearsInCode(true); TyIdx ptyIdx = fName->GetTyIdx(); MIRPtrType ptrType(ptyIdx); ptyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&ptrType); @@ -3415,6 +3414,7 @@ std::map MIRParser::InitFuncPtrMapForPar funcPtrMap[TK_icall] = &MIRParser::ParseStmtIcall; funcPtrMap[TK_icallassigned] = &MIRParser::ParseStmtIcallassigned; funcPtrMap[TK_icallproto] = &MIRParser::ParseStmtIcallproto; + funcPtrMap[TK_icallprotoassigned] = &MIRParser::ParseStmtIcallprotoassigned; funcPtrMap[TK_intrinsiccall] = &MIRParser::ParseStmtIntrinsiccall; funcPtrMap[TK_intrinsiccallassigned] = &MIRParser::ParseStmtIntrinsiccallassigned; funcPtrMap[TK_xintrinsiccall] = &MIRParser::ParseStmtIntrinsiccall; @@ -3475,7 +3475,6 @@ std::map MIRParser::InitFuncPtrMapF funcPtrMap[TK_type] = &MIRParser::ParseStmtBlockForType; funcPtrMap[TK_framesize] = &MIRParser::ParseStmtBlockForFrameSize; funcPtrMap[TK_upformalsize] = &MIRParser::ParseStmtBlockForUpformalSize; - funcPtrMap[TK_outparmsize] = &MIRParser::ParseStmtBlockForOutParmSize; funcPtrMap[TK_moduleid] = &MIRParser::ParseStmtBlockForModuleID; funcPtrMap[TK_funcsize] = &MIRParser::ParseStmtBlockForFuncSize; funcPtrMap[TK_funcid] = &MIRParser::ParseStmtBlockForFuncID; diff --git a/src/mapleall/maple_ir/src/mir_type.cpp b/src/mapleall/maple_ir/src/mir_type.cpp index 0c9ff37468..6dac1d09d5 100644 --- a/src/mapleall/maple_ir/src/mir_type.cpp +++ b/src/mapleall/maple_ir/src/mir_type.cpp @@ -738,7 +738,9 @@ void MIRFuncType::Dump(int indent, bool dontUseName) const { if (!dontUseName && CheckAndDumpTypeName(nameStrIdx, nameIsLocal)) { return; } - LogInfo::MapleLogger() << "Dump(indent + 1); @@ -749,7 +751,7 @@ void MIRFuncType::Dump(int indent, bool dontUseName) const { LogInfo::MapleLogger() << ","; } } - if (isVarArgs) { + if (IsVarargs()) { LogInfo::MapleLogger() << ", ..."; } LogInfo::MapleLogger() << ") "; @@ -1663,7 +1665,7 @@ bool MIRFuncType::EqualTo(const MIRType &type) const { } const auto &pType = static_cast(type); return (pType.retTyIdx == retTyIdx && pType.paramTypeList == paramTypeList && - pType.isVarArgs == isVarArgs && pType.paramAttrsList == paramAttrsList && + pType.funcAttrs == funcAttrs && pType.paramAttrsList == paramAttrsList && pType.retAttrs == retAttrs); } diff --git a/src/mapleall/maple_ir/src/parser.cpp b/src/mapleall/maple_ir/src/parser.cpp index db50916351..e8c9178367 100644 --- a/src/mapleall/maple_ir/src/parser.cpp +++ b/src/mapleall/maple_ir/src/parser.cpp @@ -229,9 +229,7 @@ bool MIRParser::ParsePseudoReg(PrimType primType, PregIdx &pRegIdx) { MIRPreg *preg = curfunc->GetPregTab()->PregFromPregIdx(pRegIdx); if (primType != kPtyInvalid) { if (preg->GetPrimType() != primType) { - if ((primType == PTY_ref || primType == PTY_ptr) && - (preg->GetPrimType() == PTY_ref || preg->GetPrimType() == PTY_ptr)) { - ; // PTY_ref and PTY_ptr are compatible with each other + if (IsAddress(preg->GetPrimType()) && IsAddress(primType)) { } else { Error("inconsistent preg primitive type at "); return false; @@ -1299,6 +1297,15 @@ bool MIRParser::ParsePointType(TyIdx &tyIdx) { // in function pointer specification and member function prototypes inside // structs and classes bool MIRParser::ParseFuncType(TyIdx &tyIdx) { + // parse function attributes + FuncAttrs fAttrs; + if (lexer.GetTokenKind() != TK_lparen) { + if (!ParseFuncAttrs(fAttrs)) { + Error("bad function attribute specification in function type at "); + return false; + } + } + // parse parameters if (lexer.GetTokenKind() != TK_lparen) { Error("expect ( parse function type parameters but get "); @@ -1359,7 +1366,10 @@ bool MIRParser::ParseFuncType(TyIdx &tyIdx) { return false; } MIRFuncType functype(retTyIdx, vecTyIdx, vecAttrs, retTypeAttrs); - functype.SetVarArgs(varargs); + functype.funcAttrs = fAttrs; + if (varargs) { + functype.SetVarArgs(); + } tyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&functype); return true; } diff --git a/src/mapleall/maple_me/include/lmbc_lower.h b/src/mapleall/maple_me/include/lmbc_lower.h index 9462204fd7..bbeaabf098 100644 --- a/src/mapleall/maple_me/include/lmbc_lower.h +++ b/src/mapleall/maple_me/include/lmbc_lower.h @@ -40,10 +40,7 @@ class LMBCLowerer { void LowerIassign(IassignNode *, BlockNode *); void LowerAggIassign(IassignNode *, MIRType *type, int32 offset, BlockNode *); void LowerReturn(NaryStmtNode *retNode, BlockNode *newblk); - MIRFuncType *FuncTypeFromFuncPtrExpr(BaseNode *x); - void LowerCall(NaryStmtNode *callNode, BlockNode *newblk); BlockNode *LowerBlock(BlockNode *); - void LoadFormalsAssignedToPregs(); void LowerFunction(); MIRModule *mirModule; diff --git a/src/mapleall/maple_me/include/lmbc_memlayout.h b/src/mapleall/maple_me/include/lmbc_memlayout.h index 7cea863a22..0f2bf5cbea 100644 --- a/src/mapleall/maple_me/include/lmbc_memlayout.h +++ b/src/mapleall/maple_me/include/lmbc_memlayout.h @@ -31,8 +31,8 @@ typedef enum { MS_actual, // for the outgoing parameters MS_local, // for all local variables and temporaries MS_FPbased, // addressed via offset from the frame pointer - MS_SPbased, // addressed via offset from the stack pointer MS_GPbased, // addressed via offset from the global pointer + MS_largeStructActual, // for storing large struct actuals passed by value for ARM CPU } MemSegmentKind; class MemSegment; @@ -64,15 +64,10 @@ class MemSegment { class LMBCMemLayout { public: - uint32 FindLargestActualArea(void); - uint32 FindLargestActualArea(StmtNode *, int &); - LMBCMemLayout(MIRFunction *f, MapleAllocator *mallocator) + LMBCMemLayout(MIRFunction *f, MemSegment *segGP, MapleAllocator *mallocator) : func(f), - seg_upformal(MS_upformal), - seg_formal(MS_formal), - seg_actual(MS_actual), + seg_GPbased(segGP), seg_FPbased(MS_FPbased), - seg_SPbased(MS_SPbased), sym_alloc_table(mallocator->Adapter()) { sym_alloc_table.resize(f->GetSymTab()->GetSymbolTableSize()); } @@ -81,67 +76,25 @@ class LMBCMemLayout { void LayoutStackFrame(void); int32 StackFrameSize(void) const { - return seg_SPbased.size - seg_FPbased.size; - } - - int32 UpformalSize(void) const { - return seg_upformal.size; + return -seg_FPbased.size; } MIRFunction *func; - MemSegment seg_upformal; - MemSegment seg_formal; - MemSegment seg_actual; + MemSegment *seg_GPbased; MemSegment seg_FPbased; - MemSegment seg_SPbased; MapleVector sym_alloc_table; // index is StIdx }; class GlobalMemLayout { public: - GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAllocator *mallocator); + GlobalMemLayout(MIRModule *mod, MapleAllocator *mallocator); ~GlobalMemLayout() {} MemSegment seg_GPbased; MapleVector sym_alloc_table; // index is StIdx - - private: - void FillScalarValueInMap(uint32 startaddress, PrimType pty, MIRConst *c); - void FillTypeValueInMap(uint32 startaddress, MIRType *ty, MIRConst *c); - void FillSymbolValueInMap(const MIRSymbol *sym); - - maplebe::BECommon *be; MIRModule *mirModule; }; -// for specifying how a parameter is passed -struct PLocInfo { - int32 memoffset; - int32 memsize; -}; - -// for processing an incoming or outgoing parameter list -class ParmLocator { - public: - explicit ParmLocator() : parmNum(0), lastMemOffset(0) {} - - ~ParmLocator() {} - - void LocateNextParm(const MIRType *ty, PLocInfo &ploc); - - private: - int32 parmNum; // number of all types of parameters processed so far - int32 lastMemOffset; -}; - -// given the type of the return value, determines the return mechanism -class ReturnMechanism { - public: - ReturnMechanism(const MIRType *retty); - bool fake_first_parm; // whether returning in memory via fake first parameter - PrimType ptype0; // the primitive type stored in retval0 -}; - } /* namespace maple */ #endif /* MAPLEME_INCLUDE_LMBC_MEMLAYOUT_H */ diff --git a/src/mapleall/maple_me/src/alias_class.cpp b/src/mapleall/maple_me/src/alias_class.cpp index 368effe2b9..6be86e59fa 100644 --- a/src/mapleall/maple_me/src/alias_class.cpp +++ b/src/mapleall/maple_me/src/alias_class.cpp @@ -1018,7 +1018,9 @@ void AliasClass::ApplyUnionForCopies(StmtNode &stmt) { } case OP_asm: case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { for (uint32 i = 0; i < stmt.NumOpnds(); ++i) { const AliasInfo &ainfo = CreateAliasInfoExpr(*stmt.Opnd(i)); if (stmt.GetOpCode() != OP_asm && i == 0) { @@ -2569,6 +2571,7 @@ void AliasClass::GenericInsertMayDefUse(StmtNode &stmt, BBId bbID) { case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_virtualcall: case OP_virtualicall: case OP_superclasscall: @@ -2576,7 +2579,8 @@ void AliasClass::GenericInsertMayDefUse(StmtNode &stmt, BBId bbID) { case OP_interfaceicall: case OP_customcall: case OP_polymorphiccall: - case OP_icall: { + case OP_icall: + case OP_icallproto: { InsertMayDefUseCall(stmt, bbID, false); return; } diff --git a/src/mapleall/maple_me/src/code_factoring.cpp b/src/mapleall/maple_me/src/code_factoring.cpp index 175cead017..21f3103b3a 100644 --- a/src/mapleall/maple_me/src/code_factoring.cpp +++ b/src/mapleall/maple_me/src/code_factoring.cpp @@ -126,7 +126,9 @@ bool FactoringOptimizer::IsIdenticalStmt(StmtNode *stmt1, StmtNode *stmt2) { break; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { auto *icall1 = static_cast(stmt1); auto *icall2 = static_cast(stmt2); if (icall1->GetRetTyIdx() != icall2->GetRetTyIdx() || diff --git a/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp b/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp index 2bb97532a6..ba545a5991 100644 --- a/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp +++ b/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp @@ -642,7 +642,9 @@ void PEGBuilder::BuildPEGNodeInStmt(const StmtNode *stmt) { break; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { BuildPEGNodeInIcall(static_cast(stmt)); break; } diff --git a/src/mapleall/maple_me/src/irmap_build.cpp b/src/mapleall/maple_me/src/irmap_build.cpp index 92eece9fa0..b6d96b6726 100755 --- a/src/mapleall/maple_me/src/irmap_build.cpp +++ b/src/mapleall/maple_me/src/irmap_build.cpp @@ -808,7 +808,7 @@ MeStmt *IRMapBuild::BuildCallMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { MeStmt *IRMapBuild::BuildNaryMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { Opcode op = stmt.GetOpCode(); - NaryMeStmt *naryMeStmt = (op == OP_icall || op == OP_icallassigned) + NaryMeStmt *naryMeStmt = (op == OP_icall || op == OP_icallassigned || op == OP_icallproto || op == OP_icallprotoassigned) ? static_cast(irMap->NewInPool(&stmt)) : static_cast(irMap->NewInPool(&stmt)); auto &naryStmtNode = static_cast(stmt); @@ -823,6 +823,9 @@ MeStmt *IRMapBuild::BuildNaryMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { if (propagater) { propagater->PropUpdateChiListDef(*naryMeStmt->GetChiList()); } + if (op == OP_icallproto || op == OP_icallprotoassigned) { + static_cast(naryMeStmt)->SetRetTyIdx(static_cast(stmt).GetRetTyIdx()); + } return naryMeStmt; } @@ -923,6 +926,8 @@ void IRMapBuild::InitMeStmtFactory() { RegisterFactoryFunction(OP_polymorphiccallassigned, &IRMapBuild::BuildCallMeStmt); RegisterFactoryFunction(OP_icall, &IRMapBuild::BuildNaryMeStmt); RegisterFactoryFunction(OP_icallassigned, &IRMapBuild::BuildNaryMeStmt); + RegisterFactoryFunction(OP_icallproto, &IRMapBuild::BuildNaryMeStmt); + RegisterFactoryFunction(OP_icallprotoassigned, &IRMapBuild::BuildNaryMeStmt); RegisterFactoryFunction(OP_intrinsiccall, &IRMapBuild::BuildNaryMeStmt); RegisterFactoryFunction(OP_xintrinsiccall, &IRMapBuild::BuildNaryMeStmt); RegisterFactoryFunction(OP_intrinsiccallwithtype, &IRMapBuild::BuildNaryMeStmt); diff --git a/src/mapleall/maple_me/src/irmap_emit.cpp b/src/mapleall/maple_me/src/irmap_emit.cpp index 1f5f45518c..f6d7b046d8 100755 --- a/src/mapleall/maple_me/src/irmap_emit.cpp +++ b/src/mapleall/maple_me/src/irmap_emit.cpp @@ -412,7 +412,7 @@ MIRFunction &CallMeStmt::GetTargetFunction() { } StmtNode &CallMeStmt::EmitStmt(SSATab &ssaTab) { - if (GetOp() != OP_icall && GetOp() != OP_icallassigned) { + if (GetOp() != OP_icall && GetOp() != OP_icallassigned && GetOp() != OP_icallproto && GetOp() != OP_icallprotoassigned) { auto *callNode = ssaTab.GetModule().CurFunction()->GetCodeMempool()->New(ssaTab.GetModule(), Opcode(GetOp())); callNode->SetPUIdx(puIdx); @@ -497,6 +497,9 @@ StmtNode &IcallMeStmt::EmitStmt(SSATab &ssaTab) { } } } + if (GetOp() == OP_icallproto || GetOp() == OP_icallprotoassigned) { + icallNode->SetRetTyIdx(retTyIdx); + } return *icallNode; } diff --git a/src/mapleall/maple_me/src/lfo_dep_test.cpp b/src/mapleall/maple_me/src/lfo_dep_test.cpp index b1273a8fc3..33f19ee452 100644 --- a/src/mapleall/maple_me/src/lfo_dep_test.cpp +++ b/src/mapleall/maple_me/src/lfo_dep_test.cpp @@ -66,6 +66,8 @@ void LfoDepInfo::CreateDoloopInfo(BlockNode *block, DoloopInfo *parent) { case OP_callassigned: case OP_icall: case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: case OP_return: case OP_throw: case OP_asm: diff --git a/src/mapleall/maple_me/src/lmbc_lower.cpp b/src/mapleall/maple_me/src/lmbc_lower.cpp index a155b25fa4..f5893447ba 100644 --- a/src/mapleall/maple_me/src/lmbc_lower.cpp +++ b/src/mapleall/maple_me/src/lmbc_lower.cpp @@ -22,16 +22,12 @@ using namespace std; PregIdx LMBCLowerer::GetSpecialRegFromSt(const MIRSymbol *sym) { MIRStorageClass storageClass = sym->GetStorageClass(); PregIdx specreg = 0; - if (storageClass == kScAuto || storageClass == kScFormal) { + if (storageClass == kScAuto) { CHECK(sym->GetStIndex() < memlayout->sym_alloc_table.size(), "index out of range in LMBCLowerer::GetSpecialRegFromSt"); SymbolAlloc symalloc = memlayout->sym_alloc_table[sym->GetStIndex()]; - if (symalloc.mem_segment->kind == MS_upformal || symalloc.mem_segment->kind == MS_formal || - symalloc.mem_segment->kind == MS_FPbased) { + if (symalloc.mem_segment->kind == MS_FPbased) { specreg = -kSregFp; - } else if (symalloc.mem_segment->kind == MS_actual || - symalloc.mem_segment->kind == MS_SPbased) { - specreg = -kSregSp; } else { CHECK_FATAL(false, "LMBCLowerer::LowerDread: bad memory layout for local variable"); } @@ -46,6 +42,7 @@ PregIdx LMBCLowerer::GetSpecialRegFromSt(const MIRSymbol *sym) { BaseNode *LMBCLowerer::LowerAddrof(AddrofNode *expr) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(expr->GetStIdx()); + symbol->ResetIsDeleted(); int32 offset = 0; if (expr->GetFieldID() != 0) { MIRStructType *structty = static_cast(symbol->GetType()); @@ -66,6 +63,7 @@ BaseNode *LMBCLowerer::LowerAddrof(AddrofNode *expr) { BaseNode *LMBCLowerer::LowerDread(AddrofNode *expr) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(expr->GetStIdx()); + symbol->ResetIsDeleted(); PrimType symty = symbol->GetType()->GetPrimType(); int32 offset = 0; if (expr->GetFieldID() != 0) { @@ -96,20 +94,22 @@ BaseNode *LMBCLowerer::LowerDread(AddrofNode *expr) { BaseNode *LMBCLowerer::LowerDreadoff(DreadoffNode *dreadoff) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dreadoff->stIdx); + symbol->ResetIsDeleted(); if (!symbol->LMBCAllocateOffSpecialReg()) { return dreadoff; } + PrimType symty = symbol->GetType()->GetPrimType(); PregIdx spcreg = GetSpecialRegFromSt(symbol); if (spcreg == -kSregFp) { CHECK_FATAL(symbol->IsLocal(), "load from fp non local?"); - IreadFPoffNode *ireadoff = mirBuilder->CreateExprIreadFPoff( - dreadoff->GetPrimType(), memlayout->sym_alloc_table[symbol->GetStIndex()].offset + dreadoff->offset); + IreadFPoffNode *ireadoff = mirBuilder->CreateExprIreadFPoff(symty, + memlayout->sym_alloc_table[symbol->GetStIndex()].offset + dreadoff->offset); return ireadoff; } else { BaseNode *rrn = mirBuilder->CreateExprRegread(LOWERED_PTR_TYPE, spcreg); SymbolAlloc &symalloc = symbol->IsLocal() ? memlayout->sym_alloc_table[symbol->GetStIndex()] : globmemlayout->sym_alloc_table[symbol->GetStIndex()]; - IreadoffNode *ireadoff = mirBuilder->CreateExprIreadoff(dreadoff->GetPrimType(), symalloc.offset + dreadoff->offset, rrn); + IreadoffNode *ireadoff = mirBuilder->CreateExprIreadoff(symty, symalloc.offset + dreadoff->offset, rrn); return ireadoff; } } @@ -129,14 +129,14 @@ static MIRType *GetPointedToType(const MIRPtrType *pointerty) { BaseNode *LMBCLowerer::LowerIread(IreadNode *expr) { int32 offset = 0; + MIRPtrType *ptrType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(expr->GetTyIdx())); + MIRType *type = ptrType->GetPointedType(); if (expr->GetFieldID() != 0) { - MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(expr->GetTyIdx()); - MIRStructType *structty = - static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(type)->GetPointedTyIdx())); + MIRStructType *structty = static_cast(type); offset = becommon->GetFieldOffset(*structty, expr->GetFieldID()).first; + type = structty->GetFieldType(expr->GetFieldID()); } - BaseNode *ireadoff = mirBuilder->CreateExprIreadoff(expr->GetPrimType(), offset, expr->Opnd(0)); + BaseNode *ireadoff = mirBuilder->CreateExprIreadoff(type->GetPrimType(), offset, expr->Opnd(0)); return ireadoff; } @@ -165,6 +165,7 @@ BaseNode *LMBCLowerer::LowerExpr(BaseNode *expr) { return LowerAddrof(static_cast(expr)); case OP_addrofoff: { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(static_cast(expr)->stIdx); + symbol->ResetIsDeleted(); CHECK_FATAL(!symbol->LMBCAllocateOffSpecialReg(), "LMBCLowerer:: illegal addrofoff instruction"); break; @@ -199,6 +200,7 @@ void LMBCLowerer::LowerAggDassign(const DassignNode *dsnode, MIRType *lhsty, // generate lhs address expression BaseNode *lhs = nullptr; MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dsnode->GetStIdx()); + symbol->ResetIsDeleted(); if (!symbol->LMBCAllocateOffSpecialReg()) { lhs = mirBuilder->CreateExprDreadoff(OP_addrofoff, LOWERED_PTR_TYPE, *symbol, offset); } else { @@ -218,6 +220,7 @@ void LMBCLowerer::LowerAggDassign(const DassignNode *dsnode, MIRType *lhsty, void LMBCLowerer::LowerDassign(DassignNode *dsnode, BlockNode *newblk) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dsnode->GetStIdx()); + symbol->ResetIsDeleted(); MIRType *symty = symbol->GetType(); int32 offset = 0; if (dsnode->GetFieldID() != 0) { @@ -259,6 +262,7 @@ void LMBCLowerer::LowerDassign(DassignNode *dsnode, BlockNode *newblk) { void LMBCLowerer::LowerDassignoff(DassignoffNode *dsnode, BlockNode *newblk) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dsnode->stIdx); + symbol->ResetIsDeleted(); CHECK_FATAL(dsnode->Opnd(0)->GetPrimType() != PTY_agg, "LowerDassignoff: agg primitive type NYI"); BaseNode *rhs = LowerExpr(dsnode->Opnd(0)); if (!symbol->LMBCAllocateOffSpecialReg()) { @@ -334,6 +338,9 @@ void LMBCLowerer::LowerIassign(IassignNode *iassign, BlockNode *newblk) { } if (iassign->GetRHS()->GetPrimType() != PTY_agg) { PrimType ptypused = type->GetPrimType(); + if (ptypused == PTY_agg) { + ptypused = iassign->GetRHS()->GetPrimType(); + } IassignoffNode *iassignoff = mirBuilder->CreateStmtIassignoff(ptypused, offset, iassign->addrExpr, @@ -347,15 +354,20 @@ void LMBCLowerer::LowerIassign(IassignNode *iassign, BlockNode *newblk) { // called only if the return has > 1 operand; assume prior lowering already // converted any return of structs to be via fake parameter void LMBCLowerer::LowerReturn(NaryStmtNode *retNode, BlockNode *newblk) { - CHECK_FATAL(retNode->NumOpnds() <= 2, "LMBCLowerer::LowerReturn: more than 2 return values NYI"); - for (int i = 0; i < retNode->NumOpnds(); i++) { - CHECK_FATAL(retNode->Opnd(i)->GetPrimType() != PTY_agg, - "LMBCLowerer::LowerReturn: return of aggregate needs to be handled first"); - // insert regassign for the returned value - BaseNode *rhs = LowerExpr(retNode->Opnd(i)); - RegassignNode *regasgn = mirBuilder->CreateStmtRegassign(rhs->GetPrimType(), - i == 0 ? -kSregRetval0 : -kSregRetval1, - rhs); + if (retNode->Opnd(0)->GetPrimType() != PTY_agg) { + CHECK_FATAL(retNode->NumOpnds() <= 2, "LMBCLowerer::LowerReturn: more than 2 return values NYI"); + for (int i = 0; i < retNode->NumOpnds(); i++) { + // insert regassign for the returned value + PrimType ptyp = retNode->Opnd(i)->GetPrimType(); + BaseNode *rhs = LowerExpr(retNode->Opnd(i)); + RegassignNode *regasgn = mirBuilder->CreateStmtRegassign(ptyp, + i == 0 ? -kSregRetval0 : -kSregRetval1, + rhs); + newblk->AddStatement(regasgn); + } + } else { // handle return of small struct using only %%retval0 + BaseNode *rhs = LowerExpr(retNode->Opnd(0)); + RegassignNode *regasgn = mirBuilder->CreateStmtRegassign(PTY_agg, -kSregRetval0, rhs); newblk->AddStatement(regasgn); } retNode->GetNopnd().clear(); // remove the return operands @@ -363,178 +375,6 @@ void LMBCLowerer::LowerReturn(NaryStmtNode *retNode, BlockNode *newblk) { newblk->AddStatement(retNode); } -MIRFuncType *LMBCLowerer::FuncTypeFromFuncPtrExpr(BaseNode *x) { - MIRFuncType *res = nullptr; - switch (x->GetOpCode()) { - case OP_regread: { - RegreadNode *regread = static_cast(x); - MIRPreg *preg = func->GetPregTab()->PregFromPregIdx(regread->GetRegIdx()); - // see if it is promoted from a symbol - if (preg->GetOp() == OP_dread) { - const MIRSymbol *symbol = preg->rematInfo.sym; - MIRType *mirType = symbol->GetType(); - if (preg->fieldID != 0) { - MIRStructType *structty = static_cast(mirType); - FieldPair thepair = structty->TraverseToField(preg->fieldID); - mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - if (res != nullptr) { - break; - } - } - // check if a formal promoted to preg - for (FormalDef &formalDef : func->GetFormalDefVec()) { - if (!formalDef.formalSym->IsPreg()) { - continue; - } - if (formalDef.formalSym->GetPreg() == preg) { - MIRType *mirType = formalDef.formalSym->GetType(); - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - break; - } - } - break; - } - case OP_dread: { - DreadNode *dread = static_cast(x); - MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); - MIRType *mirType = symbol->GetType(); - if (dread->GetFieldID() != 0) { - MIRStructType *structty = static_cast(mirType); - FieldPair thepair = structty->TraverseToField(dread->GetFieldID()); - mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - break; - } - case OP_iread: { - IreadNode *iread = static_cast(x); - MIRPtrType *ptrType = static_cast(iread->GetType()); - MIRType *mirType = ptrType->GetPointedType(); - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - break; - } - case OP_addroffunc: { - AddroffuncNode *addrofFunc = static_cast(x); - PUIdx puIdx = addrofFunc->GetPUIdx(); - MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); - res = f->GetMIRFuncType(); - break; - } - case OP_retype: { - MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(x)->GetTyIdx()); - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - if (res == nullptr) { - res = FuncTypeFromFuncPtrExpr(x->Opnd(0)); - } - break; - } - case OP_select: { - res = FuncTypeFromFuncPtrExpr(x->Opnd(1)); - if (res == nullptr) { - res = FuncTypeFromFuncPtrExpr(x->Opnd(2)); - } - break; - } - default: CHECK_FATAL(false, "LMBCLowerer::FuncTypeFromFuncPtrExpr: NYI"); - } - return res; -} - -void LMBCLowerer::LowerCall(NaryStmtNode *naryStmt, BlockNode *newblk) { - // go through each parameter - uint32 i = 0; - if (naryStmt->GetOpCode() == OP_icall || naryStmt->GetOpCode() == OP_icallassigned) { - i = 1; - } - ParmLocator parmlocator; - for (; i < naryStmt->NumOpnds(); i++) { - BaseNode *opnd = naryStmt->Opnd(i); - MIRType *ty = nullptr; - // get ty for this parameter - if (opnd->GetPrimType() != PTY_agg) { - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(static_cast(opnd->GetPrimType())); - } else { - Opcode opnd_opcode = opnd->GetOpCode(); - CHECK_FATAL(opnd_opcode == OP_dread || opnd_opcode == OP_iread, ""); - if (opnd_opcode == OP_dread) { - AddrofNode *dread = static_cast(opnd); - MIRSymbol *sym = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx()); - if (dread->GetFieldID() != 0) { - CHECK_FATAL(ty->IsStructType(), ""); - FieldPair thepair = static_cast(ty)->TraverseToField(dread->GetFieldID()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - } else { // OP_iread - IreadNode *iread = static_cast(opnd); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread->GetTyIdx()); - CHECK_FATAL(ty->GetKind() == kTypePointer, ""); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(ty)->GetPointedTyIdx()); - if (iread->GetFieldID() != 0) { - CHECK_FATAL(ty->IsStructType(), ""); - FieldPair thepair = static_cast(ty)->TraverseToField(iread->GetFieldID()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - } - } - PLocInfo ploc; - parmlocator.LocateNextParm(ty, ploc); - if (opnd->GetPrimType() != PTY_agg) { - IassignFPoffNode *iass = mirBuilder->CreateStmtIassignFPoff(OP_iassignspoff, - opnd->GetPrimType(), - ploc.memoffset, - LowerExpr(opnd)); - newblk->AddStatement(iass); - } else { - BlkassignoffNode *bass = - mirModule->CurFuncCodeMemPool()->New(ploc.memoffset, ploc.memsize); - bass->SetAlign(std::min(ty->GetAlign(), 8u)); - bass->SetBOpnd(mirBuilder->CreateExprRegread(LOWERED_PTR_TYPE, -kSregSp), 0); - // the operand is either OP_dread or OP_iread; use its address instead - if (opnd->GetOpCode() == OP_dread) { - opnd->SetOpCode(OP_addrof); - } else { - opnd->SetOpCode(OP_iaddrof); - } - opnd->SetPrimType(LOWERED_PTR_TYPE); - bass->SetBOpnd(LowerExpr(opnd), 1); - newblk->AddStatement(bass); - } - } - BaseNode *opnd0 = nullptr; - if (naryStmt->GetOpCode() == OP_icall || naryStmt->GetOpCode() == OP_icallassigned) { - opnd0 = naryStmt->Opnd(0); - naryStmt->GetNopnd().clear(); // remove the call operands - // convert to OP_icallproto by finding the function prototype and record in stmt - naryStmt->SetOpCode(OP_icallproto); - MIRFuncType *funcType = FuncTypeFromFuncPtrExpr(opnd0); - CHECK_FATAL(funcType != nullptr, "LMBCLowerer::LowerCall: cannot find prototype for icall"); - static_cast(naryStmt)->SetRetTyIdx(funcType->GetTypeIndex()); - // add back the function pointer operand - naryStmt->GetNopnd().push_back(LowerExpr(opnd0)); - naryStmt->SetNumOpnds(1); - } else { - naryStmt->GetNopnd().clear(); // remove the call operands - naryStmt->SetNumOpnds(0); - } - newblk->AddStatement(naryStmt); -} - BlockNode *LMBCLowerer::LowerBlock(BlockNode *block) { BlockNode *newblk = mirModule->CurFuncCodeMemPool()->New(); if (!block->GetFirst()) { @@ -569,10 +409,6 @@ BlockNode *LMBCLowerer::LowerBlock(BlockNode *block) { } else { LowerReturn(retNode, newblk); } - } - case OP_call: - case OP_icall: { - LowerCall(static_cast(stmt), newblk); break; } default: { @@ -587,29 +423,19 @@ BlockNode *LMBCLowerer::LowerBlock(BlockNode *block) { return newblk; } -void LMBCLowerer::LoadFormalsAssignedToPregs() { - // go through each formals - for (int32 i = func->GetFormalDefVec().size()-1; i >= 0; i--) { - MIRSymbol *formalSt = func->GetFormalDefVec()[i].formalSym; - if (formalSt->GetSKind() != kStPreg) { - continue; +void LMBCLowerer::LowerFunction() { + // set extern global vars' isDeleted field; will reset when visited + MapleVector::const_iterator sit = mirModule->GetSymbolDefOrder().begin(); + for (; sit != mirModule->GetSymbolDefOrder().end(); ++sit) { + MIRSymbol *s = GlobalTables::GetGsymTable().GetSymbolFromStidx(sit->Idx()); + if (s->GetSKind() == kStVar && s->GetStorageClass() == kScExtern && !s->HasPotentialAssignment()) { + s->SetIsDeleted(); } - MIRPreg *preg = formalSt->GetPreg(); - uint32 stindex = formalSt->GetStIndex(); - PrimType pty = formalSt->GetType()->GetPrimType(); - IreadFPoffNode *ireadfpoff = mirBuilder->CreateExprIreadFPoff(pty, - memlayout->sym_alloc_table[stindex].offset); - RegassignNode *rass = mirBuilder->CreateStmtRegassign(pty, - func->GetPregTab()->GetPregIdxFromPregno(preg->GetPregNo()), ireadfpoff); - func->GetBody()->InsertFirst(rass); } -} -void LMBCLowerer::LowerFunction() { BlockNode *origbody = func->GetBody(); BlockNode *newbody = LowerBlock(origbody); func->SetBody(newbody); - LoadFormalsAssignedToPregs(); } } // namespace maple diff --git a/src/mapleall/maple_me/src/lmbc_memlayout.cpp b/src/mapleall/maple_me/src/lmbc_memlayout.cpp index e740c5d13f..b32acae493 100644 --- a/src/mapleall/maple_me/src/lmbc_memlayout.cpp +++ b/src/mapleall/maple_me/src/lmbc_memlayout.cpp @@ -13,146 +13,40 @@ * See the MulanPSL - 2.0 for more details. */ -// For each function being compiled, lay out its parameters, return values and -// local variables on its stack frame. This involves determining how parameters -// and return values are passed from analyzing their types. -// -// Allocate all the global variables within the global memory block which is -// addressed via offset from the global pointer GP during execution. Allocate -// this block pointed to by mirModule.globalBlkMap and perform the static -// initializations. +// For each function being compiled, lay out its local variables on its stack +// frame. Allocate all the global variables within the global memory block +// which is addressed via offset from the global pointer GP during execution. +// Allocate this block pointed to by mirModule.globalBlkMap. #include "lmbc_memlayout.h" #include "mir_symbol.h" namespace maple { -uint32 LMBCMemLayout::FindLargestActualArea(StmtNode *stmt, int &maxActualSize) { - if (!stmt) { - return maxActualSize; - } - Opcode opcode = stmt->op; - switch (opcode) { - case OP_block: { - BlockNode *blcknode = static_cast(stmt); - for (StmtNode &s : blcknode->GetStmtNodes()) { - FindLargestActualArea(&s, maxActualSize); - } - break; - } - case OP_if: { - IfStmtNode *ifnode = static_cast(stmt); - FindLargestActualArea(ifnode->GetThenPart(), maxActualSize); - FindLargestActualArea(ifnode->GetElsePart(), maxActualSize); - break; - } - case OP_doloop: { - FindLargestActualArea(static_cast(stmt)->GetDoBody(), maxActualSize); - break; - } - case OP_dowhile: - case OP_while: - FindLargestActualArea(static_cast(stmt)->GetBody(), maxActualSize); - break; - case OP_call: - case OP_icall: - case OP_intrinsiccall: { - ParmLocator parmlocator; // instantiate a parm locator - NaryStmtNode *callstmt = static_cast(stmt); - for (uint32 i = 0; i < callstmt->NumOpnds(); i++) { - BaseNode *opnd = callstmt->Opnd(i); - CHECK_FATAL(opnd->GetPrimType() != PTY_void, ""); - MIRType *ty = nullptr; - if (opnd->GetPrimType() != PTY_agg) { - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(opnd->GetPrimType())); - } else { - Opcode opnd_opcode = opnd->GetOpCode(); - CHECK_FATAL(opnd_opcode == OP_dread || opnd_opcode == OP_iread, ""); - if (opnd_opcode == OP_dread) { - AddrofNode *dread = static_cast(opnd); - MIRSymbol *sym = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx()); - if (dread->GetFieldID() != 0) { - CHECK_FATAL(ty->IsStructType(), "expect struct or class or union"); - FieldPair thepair = - static_cast(ty)->TraverseToField(dread->GetFieldID()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - } else { // OP_iread - IreadNode *iread = static_cast(opnd); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread->GetTyIdx()); - CHECK_FATAL(ty->GetKind() == kTypePointer, ""); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(ty)->GetPointedTyIdx()); - if (iread->GetFieldID() != 0) { - CHECK_FATAL(ty->IsStructType(), "expect struct or class or union"); - FieldPair thepair = - static_cast(ty)->TraverseToField(iread->GetFieldID()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - } - } - PLocInfo ploc; - parmlocator.LocateNextParm(ty, ploc); - maxActualSize = std::max(maxActualSize, ploc.memoffset + ploc.memsize); - maxActualSize = maplebe::RoundUp(maxActualSize, GetPrimTypeSize(PTY_ptr)); - } - break; - } - default: - return maxActualSize; - } - maxActualSize = maplebe::RoundUp(maxActualSize, GetPrimTypeSize(PTY_ptr)); - return maxActualSize; -} - -// go over all outgoing calls in the function body and get the maximum space -// needed for storing the actuals based on the actual parameters and the ABI; -// this assumes that all nesting of statements has been removed, so that all -// the statements are at only one block level -uint32 LMBCMemLayout::FindLargestActualArea(void) { - int32 maxActualSize = 0; - FindLargestActualArea(func->GetBody(), maxActualSize); - return static_cast(maxActualSize); -} +constexpr size_t kVarargSaveAreaSize = 192; void LMBCMemLayout::LayoutStackFrame(void) { - MIRSymbol *sym = nullptr; - // go through formal parameters - ParmLocator parmlocator; // instantiate a parm locator - PLocInfo ploc; - for (uint32 i = 0; i < func->GetFormalDefVec().size(); i++) { - FormalDef formalDef = func->GetFormalDefAt(i); - sym = formalDef.formalSym; - MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(formalDef.formalTyIdx); - parmlocator.LocateNextParm(ty, ploc); - uint32 stindex = sym->GetStIndex(); - // always passed in memory, so allocate in seg_upformal - sym_alloc_table[stindex].mem_segment = &seg_upformal; - seg_upformal.size = maplebe::RoundUp(seg_upformal.size, ty->GetAlign()); - sym_alloc_table[stindex].offset = seg_upformal.size; - seg_upformal.size += ty->GetSize(); - seg_upformal.size = maplebe::RoundUp(seg_upformal.size, GetPrimTypeSize(PTY_ptr)); + if (func->IsVarargs()) { + seg_FPbased.size -= kVarargSaveAreaSize; } - // allocate seg_formal in seg_FPbased - seg_formal.how_alloc.mem_segment = &seg_FPbased; - seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, GetPrimTypeSize(PTY_ptr)); - seg_FPbased.size -= seg_formal.size; - seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, GetPrimTypeSize(PTY_ptr)); - seg_formal.how_alloc.offset = seg_FPbased.size; - // allocate the local variables uint32 symtabsize = func->GetSymTab()->GetSymbolTableSize(); for (uint32 i = 0; i < symtabsize; i++) { - sym = func->GetSymTab()->GetSymbolFromStIdx(i); + MIRSymbol *sym = func->GetSymTab()->GetSymbolFromStIdx(i); if (!sym) { continue; } if (sym->IsDeleted()) { continue; } + if (sym->GetStorageClass() == kScPstatic && sym->LMBCAllocateOffSpecialReg()) { + uint32 stindex = sym->GetStIndex(); + sym_alloc_table[stindex].mem_segment = seg_GPbased; + seg_GPbased->size = maplebe::RoundUp(seg_GPbased->size, sym->GetType()->GetAlign()); + sym_alloc_table[stindex].offset = seg_GPbased->size; + seg_GPbased->size += sym->GetType()->GetSize(); + } if (sym->GetStorageClass() != kScAuto) { continue; } @@ -162,160 +56,10 @@ void LMBCMemLayout::LayoutStackFrame(void) { seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, sym->GetType()->GetAlign()); sym_alloc_table[stindex].offset = seg_FPbased.size; } - seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, GetPrimTypeSize(PTY_ptr)); - - // allocate seg_actual for storing the outgoing parameters; this requires - // going over all outgoing calls and get the maximum space needed for the - // actuals - seg_actual.size = FindLargestActualArea(); - func->SetOutParmSize(seg_actual.size); - - // allocate seg_actual in seg_SPbased - seg_actual.how_alloc.mem_segment = &seg_SPbased; - seg_actual.how_alloc.offset = seg_SPbased.size; - seg_SPbased.size = maplebe::RoundUp(seg_SPbased.size, GetPrimTypeSize(PTY_ptr)); - seg_SPbased.size += seg_actual.size; - seg_SPbased.size = maplebe::RoundUp(seg_SPbased.size, GetPrimTypeSize(PTY_ptr)); -} - -inline uint8 GetU8Const(MIRConst *c) { - MIRIntConst *intconst = static_cast(c); - return static_cast(intconst->GetValue()); -} - -inline uint16 GetU16Const(MIRConst *c) { - MIRIntConst *intconst = static_cast(c); - return static_cast(intconst->GetValue()); -} - -inline uint32 GetU32Const(MIRConst *c) { - MIRIntConst *intconst = static_cast(c); - return static_cast(intconst->GetValue()); -} - -inline uint64 GetU64Const(MIRConst *c) { - MIRIntConst *intconst = static_cast(c); - return static_cast(intconst->GetValue()); -} - -inline uint32 GetF32Const(MIRConst *c) { - MIRFloatConst *floatconst = static_cast(c); - return static_cast(floatconst->GetIntValue()); -} - -inline uint64 GetF64Const(MIRConst *c) { - MIRDoubleConst *doubleconst = static_cast(c); - return static_cast(doubleconst->GetIntValue()); -} - -void GlobalMemLayout::FillScalarValueInMap(uint32 startaddress, PrimType pty, MIRConst *c) { - switch (pty) { - case PTY_u1: - case PTY_u8: - case PTY_i8: { - uint8 *p = &mirModule->GetGlobalBlockMap()[startaddress]; - *p = GetU8Const(c); - break; - } - case PTY_u16: - case PTY_i16: { - uint16 *p = (uint16 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetU16Const(c); - break; - } - case PTY_u32: - case PTY_i32: { - uint32 *p = (uint32 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetU32Const(c); - break; - } - case PTY_u64: - case PTY_i64: { - uint64 *p = (uint64 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetU64Const(c); - break; - } - case PTY_f32: { - uint32 *p = (uint32 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetF32Const(c); - break; - } - case PTY_f64: { - uint64 *p = (uint64 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetF64Const(c); - break; - } - default: - CHECK_FATAL(false, "FillScalarValueInMap: NYI"); - } - return; } -void GlobalMemLayout::FillTypeValueInMap(uint32 startaddress, MIRType *ty, MIRConst *c) { - switch (ty->GetKind()) { - case kTypeScalar: - FillScalarValueInMap(startaddress, ty->GetPrimType(), c); - break; - case kTypeArray: { - MIRArrayType *arraytype = static_cast(ty); - MIRType *elemtype = arraytype->GetElemType(); - int32 elemsize = elemtype->GetSize(); - MIRAggConst *aggconst = static_cast(c); - CHECK_FATAL(aggconst, "FillTypeValueInMap: inconsistent array initialization specification"); - MapleVector &constvec = aggconst->GetConstVec(); - for (MapleVector::iterator it = constvec.begin(); it != constvec.end(); - it++, startaddress += elemsize) { - FillTypeValueInMap(startaddress, elemtype, *it); - } - break; - } - case kTypeStruct: { - MIRStructType *structty = static_cast(ty); - MIRAggConst *aggconst = static_cast(c); - CHECK_FATAL(aggconst, "FillTypeValueInMap: inconsistent struct initialization specification"); - MapleVector &constvec = aggconst->GetConstVec(); - for (uint32 i = 0; i < constvec.size(); i++) { - uint32 fieldID = aggconst->GetFieldIdItem(i); - FieldPair thepair = structty->TraverseToField(fieldID); - MIRType *fieldty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - uint32 offset = be->GetFieldOffset(*structty, fieldID).first; - FillTypeValueInMap(startaddress + offset, fieldty, constvec[i]); - } - break; - } - case kTypeClass: { - MIRClassType *classty = static_cast(ty); - MIRAggConst *aggconst = static_cast(c); - CHECK_FATAL(aggconst, "FillTypeValueInMap: inconsistent class initialization specification"); - MapleVector &constvec = aggconst->GetConstVec(); - for (uint32 i = 0; i < constvec.size(); i++) { - uint32 fieldID = aggconst->GetFieldIdItem(i); - FieldPair thepair = classty->TraverseToField(fieldID); - MIRType *fieldty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - uint32 offset = be->GetFieldOffset(*classty, fieldID).first; - FillTypeValueInMap(startaddress + offset, fieldty, constvec[i]); - } - break; - } - default: - CHECK_FATAL(false, "FillTypeValueInMap: NYI"); - } -} - -void GlobalMemLayout::FillSymbolValueInMap(const MIRSymbol *sym) { - if (sym->GetKonst() == nullptr) { - return; - } - uint32 stindex = sym->GetStIndex(); - CHECK(stindex < sym_alloc_table.size(), - "index out of range in GlobalMemLayout::FillSymbolValueInMap"); - uint32 symaddress = sym_alloc_table[stindex].offset; - FillTypeValueInMap(symaddress, sym->GetType(), sym->GetKonst()); - return; -} - -GlobalMemLayout::GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAllocator *mallocator) : - seg_GPbased(MS_GPbased), sym_alloc_table(mallocator->Adapter()), be(b), mirModule(mod) { +GlobalMemLayout::GlobalMemLayout(MIRModule *mod, MapleAllocator *mallocator) : + seg_GPbased(MS_GPbased), sym_alloc_table(mallocator->Adapter()), mirModule(mod) { uint32 symtabsize = GlobalTables::GetGsymTable().GetSymbolTableSize(); sym_alloc_table.resize(symtabsize); MIRSymbol *sym = nullptr; @@ -329,6 +73,9 @@ GlobalMemLayout::GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAll if (sym->GetStorageClass() != kScGlobal && sym->GetStorageClass() != kScFstatic) { continue; } + if (!sym->LMBCAllocateOffSpecialReg()) { + continue; + } if (sym->GetType()->GetAlign() != curalign) { continue; } @@ -341,152 +88,6 @@ GlobalMemLayout::GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAll } seg_GPbased.size = maplebe::RoundUp(seg_GPbased.size, GetPrimTypeSize(PTY_ptr)); mirModule->SetGlobalMemSize(seg_GPbased.size); - // allocate the memory map for the GP block - mirModule->SetGlobalBlockMap( - static_cast(mirModule->GetMemPool()->Calloc(seg_GPbased.size))); - // perform initialization on globalblkmap - for (uint32 i = 0; i < symtabsize; i++) { - sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(i); - if (!sym) { - continue; - } - if (sym->GetStorageClass() != kScGlobal && sym->GetStorageClass() != kScFstatic) { - continue; - } - } -} - -// LocateNextParm should be called with each parameter in the parameter list -// starting from the beginning, one call per parameter in sequence; it returns -// the information on how each parameter is passed in ploc -void ParmLocator::LocateNextParm(const MIRType *ty, PLocInfo &ploc) { - ploc.memoffset = maplebe::RoundUp(lastMemOffset, 8); - ploc.memsize = ty->GetSize(); - - uint32 rightpad = 0; - parmNum++; - - switch (ty->GetPrimType()) { - case PTY_u1: - case PTY_u8: - case PTY_i8: - case PTY_u16: - case PTY_i16: - rightpad = GetPrimTypeSize(PTY_i32) - ploc.memsize; - break; - case PTY_a32: - case PTY_u32: - case PTY_i32: - case PTY_a64: - case PTY_u64: - case PTY_i64: - case PTY_ptr: - case PTY_ref: -#ifdef DYNAMICLANG - case PTY_simplestr: - case PTY_simpleobj: - case PTY_dynany: - case PTY_dyni32: - case PTY_dynf64: - case PTY_dynstr: - case PTY_dynobj: - case PTY_dynundef: - case PTY_dynbool: - case PTY_dynf32: - case PTY_dynnone: - case PTY_dynnull: -#endif - break; - - case PTY_f32: - rightpad = GetPrimTypeSize(PTY_f64) - ploc.memsize; - break; - case PTY_c64: - case PTY_f64: - case PTY_v2i32: - case PTY_v4i16: - case PTY_v8i8: - case PTY_v2u32: - case PTY_v4u16: - case PTY_v8u8: - case PTY_v2f32: - break; - - case PTY_c128: - case PTY_v2i64: - case PTY_v4i32: - case PTY_v8i16: - case PTY_v16i8: - case PTY_v2u64: - case PTY_v4u32: - case PTY_v8u16: - case PTY_v16u8: - case PTY_v2f64: - case PTY_v4f32: - break; - - case PTY_agg: { - // compute rightpad - int32 paddedSize = maplebe::RoundUp(ploc.memsize, 8); - rightpad = paddedSize - ploc.memsize; - break; - } - default: - CHECK_FATAL(false, "unsupported type"); - } - - lastMemOffset = ploc.memoffset + ploc.memsize + rightpad; - return; -} - -// instantiated with the type of the function return value, it describes how -// the return value is to be passed back to the caller -ReturnMechanism::ReturnMechanism(const MIRType *retty) : fake_first_parm(false) { - switch (retty->GetPrimType()) { - case PTY_u1: - case PTY_u8: - case PTY_i8: - case PTY_u16: - case PTY_i16: - case PTY_a32: - case PTY_u32: - case PTY_i32: - case PTY_a64: - case PTY_u64: - case PTY_i64: - case PTY_f32: - case PTY_f64: -#ifdef DYNAMICLANG - case PTY_simplestr: - case PTY_simpleobj: - case PTY_dynany: - case PTY_dyni32: - case PTY_dynstr: - case PTY_dynobj: -#endif - ptype0 = retty->GetPrimType(); - return; - - case PTY_c64: - case PTY_c128: - fake_first_parm = true; - ptype0 = PTY_a32; - return; - - case PTY_agg: { - uint32 size = retty->GetSize(); - if (size > 4) { - fake_first_parm = true; - ptype0 = PTY_a32; - } else { - ptype0 = PTY_u32; - } - return; - } - - default: - return; - } } } // namespace maple diff --git a/src/mapleall/maple_me/src/me_cfg.cpp b/src/mapleall/maple_me/src/me_cfg.cpp index ad57c5b166..74e2f176c4 100644 --- a/src/mapleall/maple_me/src/me_cfg.cpp +++ b/src/mapleall/maple_me/src/me_cfg.cpp @@ -261,6 +261,7 @@ bool MeCFG::FindUse(const StmtNode &stmt, StIdx stIdx) const { case OP_customcall: case OP_polymorphiccall: case OP_icall: + case OP_icallproto: case OP_intrinsiccall: case OP_xintrinsiccall: case OP_intrinsiccallwithtype: @@ -273,6 +274,7 @@ bool MeCFG::FindUse(const StmtNode &stmt, StIdx stIdx) const { case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_intrinsiccallassigned: case OP_xintrinsiccallassigned: case OP_intrinsiccallwithtypeassigned: diff --git a/src/mapleall/maple_me/src/me_function.cpp b/src/mapleall/maple_me/src/me_function.cpp index 05181df796..a62f1a89a3 100755 --- a/src/mapleall/maple_me/src/me_function.cpp +++ b/src/mapleall/maple_me/src/me_function.cpp @@ -303,7 +303,9 @@ void MeFunction::CloneBBMeStmts(BB &srcBB, BB &destBB, std::map(&stmt); newStmt = irmap->NewInPool(static_cast(icallStmt), icallStmt->GetRetTyIdx(), icallStmt->GetStmtID()); diff --git a/src/mapleall/maple_me/src/me_lower_globals.cpp b/src/mapleall/maple_me/src/me_lower_globals.cpp index c14dd5c764..fdf2df8e3f 100644 --- a/src/mapleall/maple_me/src/me_lower_globals.cpp +++ b/src/mapleall/maple_me/src/me_lower_globals.cpp @@ -185,7 +185,12 @@ void MeLowerGlobals::Run() { MeExpr *addroffuncExpr = irMap->CreateAddroffuncMeExpr(callee.GetPuidx()); auto insertpos = callStmt.GetOpnds().begin(); callStmt.InsertOpnds(insertpos, addroffuncExpr); - IcallMeStmt *icallStmt = irMap->NewInPool(stmt.GetOp() == OP_call ? OP_icall : OP_icallassigned); + IcallMeStmt *icallStmt = nullptr; + if (func.GetMIRModule().IsCModule()) { + icallStmt = irMap->NewInPool(stmt.GetOp() == OP_call ? OP_icallproto : OP_icallprotoassigned); + } else { + icallStmt = irMap->NewInPool(stmt.GetOp() == OP_call ? OP_icall : OP_icallassigned); + } icallStmt->SetIsLive(callStmt.GetIsLive()); icallStmt->SetSrcPos(callStmt.GetSrcPosition()); for (MeExpr *o : callStmt.GetOpnds()) { @@ -193,7 +198,11 @@ void MeLowerGlobals::Run() { } icallStmt->GetMuList()->insert(callStmt.GetMuList()->begin(), callStmt.GetMuList()->end()); icallStmt->GetChiList()->insert(callStmt.GetChiList()->begin(), callStmt.GetChiList()->end()); - icallStmt->SetRetTyIdx(callee.GetReturnTyIdx()); + if (func.GetMIRModule().IsCModule()) { + icallStmt->SetRetTyIdx(callee.GetMIRFuncType()->GetTypeIndex()); + } else { + icallStmt->SetRetTyIdx(callee.GetReturnTyIdx()); + } if (stmt.GetOp() != OP_call) { if (callStmt.NeedDecref()) { icallStmt->EnableNeedDecref(); diff --git a/src/mapleall/maple_me/src/me_phase_manager.cpp b/src/mapleall/maple_me/src/me_phase_manager.cpp index 09a1b64e5a..a0b5419a8e 100644 --- a/src/mapleall/maple_me/src/me_phase_manager.cpp +++ b/src/mapleall/maple_me/src/me_phase_manager.cpp @@ -140,8 +140,8 @@ bool MeFuncPM::PhaseRun(maple::MIRModule &m) { } if (genLMBC) { m.SetFlavor(kFlavorLmbc); + GlobalMemLayout globalMemLayout(&m, &m.GetMPAllocator()); maplebe::BECommon beCommon(m); - GlobalMemLayout globalMemLayout(&beCommon, &m, &m.GetMPAllocator()); maplebe::CGLowerer cgLower(m, beCommon, false, false); cgLower.RegisterBuiltIns(); cgLower.RegisterExternalLibraryFunctions(); @@ -153,14 +153,15 @@ bool MeFuncPM::PhaseRun(maple::MIRModule &m) { cgLower.LowerFunc(*func); MemPool *layoutMp = memPoolCtrler.NewMemPool("layout mempool", true); MapleAllocator layoutAlloc(layoutMp); - LMBCMemLayout localMemLayout(func, &layoutAlloc); + LMBCMemLayout localMemLayout(func, &globalMemLayout.seg_GPbased, &layoutAlloc); localMemLayout.LayoutStackFrame(); LMBCLowerer lmbcLowerer(&m, &beCommon, func, &globalMemLayout, &localMemLayout); lmbcLowerer.LowerFunction(); func->SetFrameSize(localMemLayout.StackFrameSize()); - func->SetUpFormalSize(localMemLayout.UpformalSize()); memPoolCtrler.DeleteMemPool(layoutMp); } + globalMemLayout.seg_GPbased.size = maplebe::RoundUp(globalMemLayout.seg_GPbased.size, GetPrimTypeSize(PTY_ptr)); + m.SetGlobalMemSize(globalMemLayout.seg_GPbased.size); // output .lmbc BinaryMplt binMplt(m); std::string modFileName = m.GetFileName(); diff --git a/src/mapleall/maple_me/src/me_rc_lowering.cpp b/src/mapleall/maple_me/src/me_rc_lowering.cpp index 1c7319e18b..131ebbdd2a 100644 --- a/src/mapleall/maple_me/src/me_rc_lowering.cpp +++ b/src/mapleall/maple_me/src/me_rc_lowering.cpp @@ -1145,6 +1145,7 @@ void RCLowering::HandleArguments() { firstBB->InsertMeStmtBefore(firstMeStmt, incCall); } sym->SetLocalRefVar(); + mirFunc->GetFormalDefVec()[i].formalAttrs.SetAttr(ATTR_localrefvar); for (auto *stmt : rets) { std::vector opnds = { argVar }; diff --git a/src/mapleall/maple_me/src/me_rename2preg.cpp b/src/mapleall/maple_me/src/me_rename2preg.cpp index 9549dff004..eddc9704b9 100644 --- a/src/mapleall/maple_me/src/me_rename2preg.cpp +++ b/src/mapleall/maple_me/src/me_rename2preg.cpp @@ -317,6 +317,7 @@ void SSARename2Preg::Rename2PregStmt(MeStmt *stmt) { case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_intrinsiccallassigned: case OP_xintrinsiccallassigned: case OP_intrinsiccallwithtypeassigned: { diff --git a/src/mapleall/maple_me/src/me_side_effect.cpp b/src/mapleall/maple_me/src/me_side_effect.cpp index 67dea87820..52fcda8516 100644 --- a/src/mapleall/maple_me/src/me_side_effect.cpp +++ b/src/mapleall/maple_me/src/me_side_effect.cpp @@ -933,6 +933,7 @@ bool IpaSideEffect::UpdateSideEffectWithStmt(MeStmt &meStmt, case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_superclasscallassigned: case OP_asm: { hasPrivateDef = hasThrException = true; @@ -959,7 +960,8 @@ bool IpaSideEffect::UpdateSideEffectWithStmt(MeStmt &meStmt, case OP_interfaceicall: case OP_customcall: case OP_polymorphiccall: - case OP_icall: { + case OP_icall: + case OP_icallproto: { hasPrivateDef = hasThrException = true; SetHasDef(); for (size_t i = 0; i < meStmt.NumMeStmtOpnds(); ++i) { diff --git a/src/mapleall/maple_me/src/me_stmt_pre.cpp b/src/mapleall/maple_me/src/me_stmt_pre.cpp index d50e3c5371..3f5d2bff57 100755 --- a/src/mapleall/maple_me/src/me_stmt_pre.cpp +++ b/src/mapleall/maple_me/src/me_stmt_pre.cpp @@ -967,7 +967,9 @@ void MeStmtPre::BuildWorkListBB(BB *bb) { break; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { auto &icallMeStmt = static_cast(stmt); VersionStackChiListUpdate(*icallMeStmt.GetChiList()); break; diff --git a/src/mapleall/maple_me/src/pme_emit.cpp b/src/mapleall/maple_me/src/pme_emit.cpp index 227cb6a761..52e1df6beb 100755 --- a/src/mapleall/maple_me/src/pme_emit.cpp +++ b/src/mapleall/maple_me/src/pme_emit.cpp @@ -485,10 +485,12 @@ StmtNode* PreMeEmitter::EmitPreMeStmt(MeStmt *mestmt, BaseNode *parent) { return callnode; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { IcallMeStmt *icallMeStmt = static_cast (mestmt); IcallNode *icallnode = - codeMP->New(*codeMPAlloc, OP_icallassigned, icallMeStmt->GetRetTyIdx()); + codeMP->New(*codeMPAlloc, OP_icallprotoassigned, icallMeStmt->GetRetTyIdx()); for (uint32 i = 0; i < icallMeStmt->GetOpnds().size(); i++) { icallnode->GetNopnd().push_back(EmitPreMeExpr(icallMeStmt->GetOpnd(i), icallnode)); } @@ -509,6 +511,9 @@ StmtNode* PreMeEmitter::EmitPreMeStmt(MeStmt *mestmt, BaseNode *parent) { icallnode->SetRetTyIdx(TyIdx(preg->GetPrimType())); } } + if (mestmt->GetOp() == OP_icallproto || mestmt->GetOp() == OP_icallprotoassigned) { + icallnode->SetRetTyIdx(icallMeStmt->GetRetTyIdx()); + } icallnode->CopySafeRegionAttr(mestmt->GetStmtAttr()); icallnode->SetOriginalID(mestmt->GetOriginalId()); PreMeStmtExtensionMap[icallnode->GetStmtID()] = pmeExt; diff --git a/src/mapleall/maple_me/src/ssa_devirtual.cpp b/src/mapleall/maple_me/src/ssa_devirtual.cpp index 15a609e427..f46e8e06ce 100644 --- a/src/mapleall/maple_me/src/ssa_devirtual.cpp +++ b/src/mapleall/maple_me/src/ssa_devirtual.cpp @@ -534,7 +534,9 @@ void SSADevirtual::TraversalMeStmt(MeStmt &meStmt) { break; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { auto *icallMeStmt = static_cast(&meStmt); const MapleVector &opnds = icallMeStmt->GetOpnds(); for (size_t i = 0; i < opnds.size(); ++i) { diff --git a/src/mapleall/maple_me/src/ssa_pre.cpp b/src/mapleall/maple_me/src/ssa_pre.cpp index ceff080daa..a082b80b9f 100644 --- a/src/mapleall/maple_me/src/ssa_pre.cpp +++ b/src/mapleall/maple_me/src/ssa_pre.cpp @@ -1666,6 +1666,7 @@ void SSAPre::BuildWorkListStmt(MeStmt &stmt, uint32 seqStmt, bool isRebuilt, MeE case OP_customcall: case OP_polymorphiccall: case OP_icall: + case OP_icallproto: case OP_callassigned: case OP_virtualcallassigned: case OP_virtualicallassigned: @@ -1675,6 +1676,7 @@ void SSAPre::BuildWorkListStmt(MeStmt &stmt, uint32 seqStmt, bool isRebuilt, MeE case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_asm: { auto *naryMeStmt = static_cast(meStmt); const MapleVector &opnds = naryMeStmt->GetOpnds(); diff --git a/src/mapleall/mpl2mpl/src/constantfold.cpp b/src/mapleall/mpl2mpl/src/constantfold.cpp index f84c351bd8..1b296c1de7 100644 --- a/src/mapleall/mpl2mpl/src/constantfold.cpp +++ b/src/mapleall/mpl2mpl/src/constantfold.cpp @@ -162,6 +162,8 @@ StmtNode *ConstantFold::Simplify(StmtNode *node) { return SimplifyNary(static_cast(node)); case OP_icall: case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: return SimplifyIcall(static_cast(node)); case OP_asm: return SimplifyAsm(static_cast(node)); @@ -2628,8 +2630,8 @@ StmtNode *ConstantFold::SimplifyIcall(IcallNode *node) { AddroffuncNode *addrofNode = static_cast(node->GetNopndAt(0)); CallNode *callNode = mirModule->CurFuncCodeMemPool()->New(*mirModule, - node->GetOpCode() == OP_icall ? OP_call : OP_callassigned); - if (node->GetOpCode() == OP_icallassigned) { + (node->GetOpCode() == OP_icall || node->GetOpCode() == OP_icallproto) ? OP_call : OP_callassigned); + if (node->GetOpCode() == OP_icallassigned || node->GetOpCode() == OP_icallprotoassigned) { callNode->SetReturnVec(node->GetReturnVec()); } callNode->SetPUIdx(addrofNode->GetPUIdx()); -- Gitee From 61d05270fe7198db09ee4dfe75fb276b9e497fea Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:44 -0700 Subject: [PATCH 026/124] Fred's Fixed determination logic of when there is fake parameter for returning struct, where x8 is also used to pass the fake parameter --- .../maple_be/src/cg/aarch64/aarch64_args.cpp | 4 ++-- .../src/cg/aarch64/aarch64_call_conv.cpp | 11 ++++++----- .../maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 18 ++++++++++++------ .../src/cg/aarch64/aarch64_memlayout.cpp | 4 ++-- 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 5869978884..b44841c018 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -38,7 +38,7 @@ void AArch64MoveRegArgs::CollectRegisterArgs(std::map &argsL uint32 start = 0; if (numFormal) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsFirstArgReturn()) { + if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16ByteSize) { start = 1; @@ -439,7 +439,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsFirstArgReturn()) { + if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp index b89e1b4c40..bc9e1cb471 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp @@ -306,18 +306,18 @@ int32 AArch64CallConvImpl::LocateNextParm(MIRType &mirType, CCLocInfo &pLoc, boo if (size == 0) { /* For return struct size 0 there is no return value. */ return 0; - } else if (size > k16ByteSize) { - /* For return struct size > 16 bytes the pointer returns in x8. */ - pLoc.reg0 = R8; - return kSizeOfPtr; } + /* For return struct size > 16 bytes the pointer returns in x8. */ + pLoc.reg0 = R8; + return kSizeOfPtr; +#if 0 /* For return struct size less or equal to 16 bytes, the values * are returned in register pairs. * Check for pure float struct. */ AArch64ArgumentClass classes[kMaxRegCount] = { kAArch64NoClass }; uint32 fpSize; - MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(beCommon.GetFuncReturnType(*func)); + MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); uint32 numRegs = static_cast(ClassifyAggregate(beCommon, *retType, classes, sizeof(classes), fpSize)); if (classes[0] == kAArch64FloatClass) { CHECK_FATAL(numRegs <= kMaxRegCount, "LocateNextParm: illegal number of regs"); @@ -334,6 +334,7 @@ int32 AArch64CallConvImpl::LocateNextParm(MIRType &mirType, CCLocInfo &pLoc, boo } return 0; } +#endif } } uint64 typeSize = beCommon.GetTypeSize(mirType.GetTypeIndex()); 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 5da7b66ec2..66ea632b29 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8063,6 +8063,17 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo std::set specialArgs; SelectParmListPreprocess(naryNode, i, specialArgs); bool specialArg = false; + bool firstArgReturn = false; + MIRFunction *callee = nullptr; + if (dynamic_cast(&naryNode) != nullptr) { + auto calleePuIdx = static_cast(naryNode).GetPUIdx(); + callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + firstArgReturn = callee->IsFirstArgReturn(); + } else if (naryNode.GetOpCode() == OP_icallproto) { + IcallNode *icallnode = &static_cast(naryNode); + MIRFuncType *funcType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallnode->GetRetTyIdx())); + firstArgReturn = funcType->FirstArgReturn(); + } BB *curBBrecord = GetCurBB(); BB *tmpBB = nullptr; if (!specialArgs.empty()) { @@ -8084,11 +8095,6 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); - MIRFunction *callee = nullptr; - if (dynamic_cast(&naryNode) != nullptr) { - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); - } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } @@ -8153,7 +8159,7 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo } expRegOpnd = static_cast(opnd); - if ((pnum == 0) && (SelectParmListGetStructReturnSize(naryNode) > k16ByteSize)) { + if ((pnum == 0) && firstArgReturn) { parmLocator.InitCCLocInfo(ploc); ploc.reg0 = R8; } else { diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp index 71f57d89ea..de95e9be33 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp @@ -210,7 +210,7 @@ void AArch64MemLayout::LayoutFormalParams() { AArch64SymbolAlloc *symLoc = memAllocator->GetMemPool()->New(); SetSymAllocInfo(stIndex, *symLoc); if (i == 0) { - if (mirFunction->IsFirstArgReturn()) { + if (mirFunction->IsReturnStruct() && mirFunction->IsFirstArgReturn()) { symLoc->SetMemSegment(GetSegArgsRegPassed()); symLoc->SetOffset(GetSegArgsRegPassed().GetSize()); TyIdx tyIdx = mirFunction->GetFuncRetStructTyIdx(); @@ -395,7 +395,7 @@ void AArch64MemLayout::LayoutReturnRef(std::vector &returnDelays, void AArch64MemLayout::LayoutActualParams() { for (size_t i = 0; i < mirFunction->GetFormalCount(); ++i) { if (i == 0) { - if (mirFunction->IsReturnStruct()) { + if (mirFunction->IsReturnStruct() && mirFunction->IsFirstArgReturn()) { continue; } } -- Gitee From d0d8a63bd8d76c4a20221c3be852b3c100851f97 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:53:00 -0700 Subject: [PATCH 027/124] Remove unneeded fp def. Turn on tailcall. no unneeded pro/epilog. --- .../maple_be/include/cg/aarch64/aarch64_color_ra.h | 1 + src/mapleall/maple_be/include/cg/cgfunc.h | 9 +++++++++ .../maple_be/src/cg/aarch64/aarch64_color_ra.cpp | 6 ++++++ .../maple_be/src/cg/aarch64/aarch64_proepilog.cpp | 7 +++---- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h index a3df9f6bf3..651cd91674 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h @@ -1519,6 +1519,7 @@ class GraphColorRegAllocator : public RegAllocator { #endif bool hasSpill = false; bool doMultiPass = false; + bool seenFP = false; }; class CallerSavePre: public CGPre { diff --git a/src/mapleall/maple_be/include/cg/cgfunc.h b/src/mapleall/maple_be/include/cg/cgfunc.h index 0695a784de..a664565276 100644 --- a/src/mapleall/maple_be/include/cg/cgfunc.h +++ b/src/mapleall/maple_be/include/cg/cgfunc.h @@ -1107,6 +1107,14 @@ class CGFunc { return useFP; } + void UnsetSeenFP() { + seenFP = false; + } + + bool SeenFP() const { + return seenFP; + } + void UpdateAllRegisterVregMapping(MapleMap &newMap); void RegisterVregMapping(regno_t vRegNum, PregIdx pidx) { @@ -1276,6 +1284,7 @@ class CGFunc { const MapleString shortFuncName; bool hasAsm = false; bool useFP = true; + bool seenFP = true; /* save stack protect kinds which can trigger stack protect */ uint8 stackProtectInfo = 0; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp index 8d63e7d8fb..479dad8658 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp @@ -3608,6 +3608,9 @@ RegOperand *GraphColorRegAllocator::GetReplaceOpnd(Insn &insn, const Operand &op auto ®Opnd = static_cast(opnd); uint32 vregNO = regOpnd.GetRegisterNumber(); + if (vregNO == RFP) { + seenFP = true; + } RegType regType = regOpnd.GetRegisterType(); if (vregNO < kAllRegNum) { return nullptr; @@ -4975,6 +4978,9 @@ bool GraphColorRegAllocator::AllocateRegisters() { MarkCalleeSaveRegs(); + if (seenFP == false) { + cgFunc->UnsetSeenFP(); + } if (GCRA_DUMP) { cgFunc->DumpCGIR(); } diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp index 4fd65cebdd..807279e7f9 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp @@ -185,9 +185,6 @@ void AArch64GenProEpilog::TailCallBBOpt(BB &bb, MapleSet &callInsns, BB & * Return value: true if function do not need Prologue/Epilogue. false otherwise. */ bool AArch64GenProEpilog::TailCallOpt() { - if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { - return false; - } /* Count how many call insns in the whole function. */ uint32 nCount = 0; bool hasGetStackClass = false; @@ -1229,7 +1226,9 @@ void AArch64GenProEpilog::GeneratePushRegs() { } else { immOpnd = &aarchCGFunc.CreateImmOperand(argsToStkPassSize, k32BitSize, true); } - aarchCGFunc.SelectAdd(fpOpnd, spOpnd, *immOpnd, PTY_u64); + if (isLmbc == false || cgFunc.SeenFP() || cgFunc.GetFunction().GetAttr(FUNCATTR_varargs)) { + aarchCGFunc.SelectAdd(fpOpnd, spOpnd, *immOpnd, PTY_u64); + } cgFunc.GetCurBB()->GetLastInsn()->SetFrameDef(true); if (cgFunc.GenCfi()) { cgFunc.GetCurBB()->AppendInsn(aarchCGFunc.CreateCfiDefCfaInsn(stackBaseReg, -- Gitee From e1d402820dd3bc949cc393b01f067e50fcfcc503 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:53:14 -0700 Subject: [PATCH 028/124] Fred's Set firstarg_return attribute in the new funcAttrs field in MIRFuncType --- src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp | 3 +++ src/mapleall/maple_ir/src/mir_lower.cpp | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp b/src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp index 3a77948b15..63c34ea154 100644 --- a/src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp +++ b/src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp @@ -278,6 +278,9 @@ bool ASTFunc2FEHelper::ProcessDeclImpl(MapleAllocator &allocator) { ENCChecker::InsertBoundaryInAtts(attrs, func.GetBoundaryInfo()); mirMethodPair.second.second = attrs; mirFunc->SetFuncAttrs(attrs); + if (firstArgRet) { + mirFunc->GetMIRFuncType()->funcAttrs.SetAttr(FUNCATTR_firstarg_return); + } func.ClearGenericAttrsContentMap(); return true; } diff --git a/src/mapleall/maple_ir/src/mir_lower.cpp b/src/mapleall/maple_ir/src/mir_lower.cpp index 36d572f057..c19a5856b2 100644 --- a/src/mapleall/maple_ir/src/mir_lower.cpp +++ b/src/mapleall/maple_ir/src/mir_lower.cpp @@ -553,6 +553,10 @@ BlockNode *MIRLower::LowerBlock(BlockNode &block) { MIRFuncType *funcType = FuncTypeFromFuncPtrExpr(stmt->Opnd(0)); CHECK_FATAL(funcType != nullptr, "MIRLower::LowerBlock: cannot find prototype for icall"); ic->SetRetTyIdx(funcType->GetTypeIndex()); + MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcType->GetRetTyIdx()); + if (retType->GetPrimType() == PTY_agg && retType->GetSize() > 16) { + funcType->funcAttrs.SetAttr(FUNCATTR_firstarg_return); + } } newBlock->AddStatement(stmt); break; -- Gitee From 003b92c2975b7b01d1838be3fc9a565d64b06439 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 029/124] Changes from mplcglmbc8 and mplcglmbc9. --- src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp | 1 - src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index b44841c018..941c117c58 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -439,7 +439,6 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; 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 66ea632b29..482636ee0f 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8095,6 +8095,11 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); + MIRFunction *callee = nullptr; + if (dynamic_cast(&naryNode) != nullptr) { + auto calleePuIdx = static_cast(naryNode).GetPUIdx(); + callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } -- Gitee From ce4c354239f9e1e36bdfdf959558ef74899e8572 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:44 -0700 Subject: [PATCH 030/124] Fred's Fixed determination logic of when there is fake parameter for returning struct, where x8 is also used to pass the fake parameter --- src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp | 1 + src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 5 ----- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 941c117c58..b44841c018 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -439,6 +439,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); + if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; 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 482636ee0f..66ea632b29 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8095,11 +8095,6 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); - MIRFunction *callee = nullptr; - if (dynamic_cast(&naryNode) != nullptr) { - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); - } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } -- Gitee From de9b19d940cbcec5760ffd46e6fe22e40276719a Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 15 Jun 2022 16:18:04 -0700 Subject: [PATCH 031/124] Fix accessing localrefvar in memlayout by qualifying with language --- src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h | 2 +- src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 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 7a6e406263..bec9fa8267 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -129,7 +129,7 @@ class AArch64CGFunc : public CGFunc { uint32 LmbcFindTotalStkUsed(std::vector* paramList); uint32 LmbcTotalRegsUsed(); void LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn); - bool LmbcSmallAggForRet(BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *src); bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp index de95e9be33..97bfc6ef52 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp @@ -230,7 +230,7 @@ void AArch64MemLayout::LayoutFormalParams() { if (ploc.reg0 != kRinvalid) { /* register */ symLoc->SetRegisters(static_cast(ploc.reg0), static_cast(ploc.reg1), static_cast(ploc.reg2), static_cast(ploc.reg3)); - if (mirFunction->GetFormalDefVec()[i].formalAttrs.GetAttr(ATTR_localrefvar)) { + if (!cgFunc->GetMirModule().IsCModule() && mirFunction->GetNthParamAttr(i).GetAttr(ATTR_localrefvar)) { symLoc->SetMemSegment(segRefLocals); SetSegmentSize(*symLoc, segRefLocals, ptyIdx); } else if (!sym->IsPreg()) { @@ -272,7 +272,7 @@ void AArch64MemLayout::LayoutFormalParams() { } else { segArgsStkPassed.SetSize(static_cast(RoundUp(segArgsStkPassed.GetSize(), kSizeOfPtr))); } - if (mirFunction->GetFormalDefVec()[i].formalAttrs.GetAttr(ATTR_localrefvar)) { + if (!cgFunc->GetMirModule().IsCModule() && mirFunction->GetNthParamAttr(i).GetAttr(ATTR_localrefvar)) { SetLocalRegLocInfo(sym->GetStIdx(), *symLoc); AArch64SymbolAlloc *symLoc1 = memAllocator->GetMemPool()->New(); symLoc1->SetMemSegment(segRefLocals); -- Gitee From 6e6f74aae892adb75c950a2f3b17e5e821364703 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Thu, 16 Jun 2022 10:44:59 -0700 Subject: [PATCH 032/124] Set appearsInCode and puidxOrigin fields in newly cloned functions --- src/mapleall/maple_ipa/src/ipa_clone.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mapleall/maple_ipa/src/ipa_clone.cpp b/src/mapleall/maple_ipa/src/ipa_clone.cpp index 51fa34198c..3f03c26d86 100644 --- a/src/mapleall/maple_ipa/src/ipa_clone.cpp +++ b/src/mapleall/maple_ipa/src/ipa_clone.cpp @@ -107,6 +107,8 @@ MIRFunction *IpaClone::IpaCloneFunction(MIRFunction &originalFunction, const std newFunc->SetSrcPosition(originalFunction.GetSrcPosition()); newFunc->SetFuncAttrs(originalFunction.GetFuncAttrs()); newFunc->SetBaseClassFuncNames(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fullName)); + newFunc->GetFuncSymbol()->SetAppearsInCode(true); + newFunc->SetPuidxOrigin(newFunc->GetPuidx()); if (originalFunction.GetBody() != nullptr) { CopyFuncInfo(originalFunction, *newFunc); newFunc->SetBody( @@ -135,6 +137,8 @@ MIRFunction *IpaClone::IpaCloneFunctionWithFreq(MIRFunction &originalFunction, newFunc->SetSrcPosition(originalFunction.GetSrcPosition()); newFunc->SetFuncAttrs(originalFunction.GetFuncAttrs()); newFunc->SetBaseClassFuncNames(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fullName)); + newFunc->GetFuncSymbol()->SetAppearsInCode(true); + newFunc->SetPuidxOrigin(newFunc->GetPuidx()); GcovFuncInfo *origProfData = originalFunction.GetFuncProfData(); auto *moduleMp = mirBuilder.GetMirModule().GetMemPool(); GcovFuncInfo *newProfData = moduleMp->New(&mirBuilder.GetMirModule().GetMPAllocator(), -- Gitee From b913d8891374a791a97274603a919715c5702894 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 033/124] Changes from mplcglmbc8 and mplcglmbc9. --- src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h | 2 +- src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 2 +- 2 files changed, 2 insertions(+), 2 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 bec9fa8267..7a6e406263 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -129,7 +129,7 @@ class AArch64CGFunc : public CGFunc { uint32 LmbcFindTotalStkUsed(std::vector* paramList); uint32 LmbcTotalRegsUsed(); void LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn); - bool LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForRet(BlkassignoffNode &bNode, Operand *src); bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; 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 66ea632b29..179c07b518 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -2271,7 +2271,7 @@ void AArch64CGFunc::SelectBlkassignoff(BlkassignoffNode &bNode, Operand *src) opndVec.push_back(regResult); /* result */ opndVec.push_back(PrepareMemcpyParamOpnd(offset, *dest)); /* param 0 */ opndVec.push_back(src); /* param 1 */ - opndVec.push_back(PrepareMemcpyParamOpnd(static_cast(static_cast(bNode.blockSize))));/* param 2 */ + opndVec.push_back(PrepareMemcpyParamOpnd(bNode.blockSize));/* param 2 */ SelectLibCall("memcpy", opndVec, PTY_a64, PTY_a64); } -- Gitee From 9c57e9dfd87ccd2de5bf4f5ba8ea16db554e5ba0 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 15 Jun 2022 16:18:04 -0700 Subject: [PATCH 034/124] Fix accessing localrefvar in memlayout by qualifying with language --- src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 7a6e406263..bec9fa8267 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -129,7 +129,7 @@ class AArch64CGFunc : public CGFunc { uint32 LmbcFindTotalStkUsed(std::vector* paramList); uint32 LmbcTotalRegsUsed(); void LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn); - bool LmbcSmallAggForRet(BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *src); bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; -- Gitee From 915517e45f5eed26e7a85074ceb5aa1f129b9eb2 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Fri, 17 Jun 2022 00:40:20 -0700 Subject: [PATCH 035/124] Fixed a couple of bugs in the last rebase --- .../maple_be/include/cg/aarch64/aarch64_cgfunc.h | 16 ---------------- .../maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 2 +- 2 files changed, 1 insertion(+), 17 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 bec9fa8267..84ba1fb370 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -739,22 +739,6 @@ class AArch64CGFunc : public CGFunc { RegOperand &GetZeroOpnd(uint32 size) override; - int32 GetLmbcTotalStkUsed() { - return lmbcArgInfo->lmbcTotalStkUsed; - } - - void SetLmbcTotalStkUsed(int32 offset) { - lmbcArgInfo->lmbcTotalStkUsed = offset; - } - - void SetLmbcCallReturnType(MIRType *ty) { - lmbcCallReturnType = ty; - } - - MIRType *GetLmbcCallReturnType() { - return lmbcCallReturnType; - } - private: enum RelationOperator : uint8 { kAND, 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 179c07b518..4ac23faa22 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -893,7 +893,7 @@ MemOperand &AArch64CGFunc::ConstraintOffsetToSafeRegion(uint32 bitLen, const Mem } int32 offsetValue = static_cast(memOpnd.GetOffsetImmediate()->GetOffsetValue()); int32 multiplier = (offsetValue / k512BitSize) + static_cast(offsetValue % k512BitSize > k256BitSize); - int32 addMount = multiplier * k512BitSizeInt; + int32 addMount = multiplier * k512BitSize; int32 newOffset = offsetValue - addMount; RegOperand *baseReg = memOpnd.GetBaseRegister(); ImmOperand &immAddMount = CreateImmOperand(addMount, k64BitSize, true); -- Gitee From 19942b7631f2d6db72de7956727487daaa0b1cb6 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Fri, 17 Jun 2022 21:32:32 -0700 Subject: [PATCH 036/124] Fixed bug in importing typeAttrs field of MIRStructType Also, handle the export and import of MIRAddrofConst of local symbols properly. --- src/mapleall/maple_ir/include/bin_mpl_export.h | 2 ++ src/mapleall/maple_ir/src/bin_mpl_export.cpp | 2 +- src/mapleall/maple_ir/src/bin_mpl_import.cpp | 8 ++++---- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/mapleall/maple_ir/include/bin_mpl_export.h b/src/mapleall/maple_ir/include/bin_mpl_export.h index f12bec7081..0d3d6d6457 100644 --- a/src/mapleall/maple_ir/include/bin_mpl_export.h +++ b/src/mapleall/maple_ir/include/bin_mpl_export.h @@ -180,7 +180,9 @@ class BinaryMplExport { void ExpandFourBuffSize(); MIRModule &mod; + public: MIRFunction *curFunc = nullptr; + private: size_t bufI = 0; std::vector buf; std::unordered_map gStrMark; diff --git a/src/mapleall/maple_ir/src/bin_mpl_export.cpp b/src/mapleall/maple_ir/src/bin_mpl_export.cpp index 4359ae9f55..72e7d11858 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_export.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_export.cpp @@ -45,7 +45,7 @@ void OutputConstAddrof(const MIRConst &constVal, BinaryMplExport &mplExport) { if (addrof.GetSymbolIndex().IsGlobal()) { mplExport.OutputSymbol(mplExport.GetMIRModule().CurFunction()->GetLocalOrGlobalSymbol(addrof.GetSymbolIndex())); } else { - mplExport.WriteNum(addrof.GetSymbolIndex().FullIdx()); + mplExport.OutputLocalSymbol(mplExport.curFunc->GetLocalOrGlobalSymbol(addrof.GetSymbolIndex())); } mplExport.WriteNum(addrof.GetFieldID()); mplExport.WriteNum(addrof.GetOffset()); diff --git a/src/mapleall/maple_ir/src/bin_mpl_import.cpp b/src/mapleall/maple_ir/src/bin_mpl_import.cpp index 1f79751ed6..e3ab6f9689 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_import.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_import.cpp @@ -122,10 +122,10 @@ MIRConst *BinaryMplImport::ImportConst(MIRFunction *func) { return memPool->New(sym->GetStIdx(), fi, *exprTy, ofst); } case kBinKindConstAddrofLocal: { - uint32 fullidx = static_cast(ReadNum()); + MIRSymbol *sym = ImportLocalSymbol(func); FieldID fi = static_cast(ReadNum()); int32 ofst = static_cast(ReadNum()); - return memPool->New(StIdx(fullidx), fi, *type, ofst); + return memPool->New(sym->GetStIdx(), fi, *type, ofst); } case kBinKindConstAddrofFunc: { PUIdx puIdx = ImportFunction(); @@ -661,9 +661,9 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { auto kind = static_cast(ReadNum()); MIRStructType type(kind, strIdx); type.SetNameIsLocal(nameIsLocal); - auto &origType = static_cast(InsertInTypeTables(type)); - typTab.push_back(origType.GetTypeIndex()); type.SetTypeAttrs(ImportTypeAttrs()); + MIRStructType &origType = static_cast(InsertInTypeTables(type)); + typTab.push_back(origType.GetTypeIndex()); if (kind != kTypeStructIncomplete) { if (forPointedType) { typeNeedsComplete = &origType; -- Gitee From b56aae88c1909dd4cfd3d80edb4ed7f9e933eacd Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Sun, 19 Jun 2022 22:40:51 -0700 Subject: [PATCH 037/124] Rebasing edits --- .../maple_be/include/cg/aarch64/aarch64_cgfunc.h | 15 +++++++++++++++ src/mapleall/maple_be/src/cg/cgfunc.cpp | 4 ++-- 2 files changed, 17 insertions(+), 2 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 84ba1fb370..2487ba1971 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -733,6 +733,21 @@ class AArch64CGFunc : public CGFunc { return lmbcArgInfo->lmbcCallArgNumOfRegs; } + int32 GetLmbcTotalStkUsed() { + return lmbcArgInfo->lmbcTotalStkUsed; + } + + void SetLmbcTotalStkUsed(int32 offset) { + lmbcArgInfo->lmbcTotalStkUsed = offset; + } + + void SetLmbcCallReturnType(MIRType *ty) { + lmbcCallReturnType = ty; + } + + MIRType *GetLmbcCallReturnType() { + return lmbcCallReturnType; + } bool IsSPOrFP(const RegOperand &opnd) const override; bool IsReturnReg(const RegOperand &opnd) const override; bool IsSaveReg(const RegOperand ®, MIRType &mirType, BECommon &cgBeCommon) const override; diff --git a/src/mapleall/maple_be/src/cg/cgfunc.cpp b/src/mapleall/maple_be/src/cg/cgfunc.cpp index fa20963392..f2cfa576b7 100644 --- a/src/mapleall/maple_be/src/cg/cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/cgfunc.cpp @@ -1586,7 +1586,7 @@ void CGFunc::CreateLmbcFormalParamInfo() { stackOffset += (typeSize + 7) & (-8); LmbcFormalParamInfo *info = GetMemoryPool()->New(primType, offset, typeSize); lmbcParamVec.push_back(info); - if (idx == 0 && mirFunc.IsFirstArgReturn()) { + if (idx == 0 && func.IsFirstArgReturn()) { info->SetIsReturn(); } if (type->GetKind() == kTypeStruct) { @@ -1603,7 +1603,7 @@ void CGFunc::CreateLmbcFormalParamInfo() { } } else { /* No aggregate pass by value here */ - for (StmtNode *stmt = mirFunc.GetBody()->GetFirst(); stmt != nullptr; stmt = stmt->GetNext()) { + for (StmtNode *stmt = func.GetBody()->GetFirst(); stmt != nullptr; stmt = stmt->GetNext()) { if (stmt == nullptr) { break; } -- Gitee From 032a16024ccf6f2ce3f217b745a776f3ae987f2b Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Mon, 20 Jun 2022 16:33:25 -0700 Subject: [PATCH 038/124] Set isFirst in calling LocateNextParm() so it knows to check for use of x8 to pass the first parameter --- src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp index 5ca154b1aa..b5788eb167 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp @@ -30,7 +30,7 @@ void AArch64ReachingDefinition::InitStartGen() { CCLocInfo pLoc; for (uint32 i = 0; i < cgFunc->GetFunction().GetFormalCount(); ++i) { MIRType *type = cgFunc->GetFunction().GetNthParamType(i); - parmLocator.LocateNextParm(*type, pLoc); + parmLocator.LocateNextParm(*type, pLoc, i == 0, &cgFunc->GetFunction()); if (pLoc.reg0 == 0) { /* If is a large frame, parameter addressing mode is based vreg:Vra. */ continue; -- Gitee From dd2554340c8f568fe568a0feae5c977ad056a432 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 039/124] Changes from mplcglmbc8 and mplcglmbc9. --- src/mapleall/maple_be/include/be/lower.h | 2 +- .../include/cg/aarch64/aarch64_cgfunc.h | 32 +- .../include/cg/aarch64/aarch64_phases.def | 2 +- src/mapleall/maple_be/include/cg/call_conv.h | 22 +- src/mapleall/maple_be/include/cg/cg.h | 19 +- src/mapleall/maple_be/include/cg/cgfunc.h | 2 + src/mapleall/maple_be/src/be/lower.cpp | 82 ++- .../maple_be/src/cg/aarch64/aarch64_args.cpp | 4 +- .../src/cg/aarch64/aarch64_call_conv.cpp | 2 +- .../src/cg/aarch64/aarch64_cgfunc.cpp | 547 +++++++++++++++--- .../maple_be/src/cg/aarch64/aarch64_ebo.cpp | 4 +- .../src/cg/aarch64/aarch64_memlayout.cpp | 34 +- .../src/cg/aarch64/aarch64_offset_adjust.cpp | 2 +- .../src/cg/aarch64/aarch64_proepilog.cpp | 87 ++- .../src/cg/aarch64/aarch64_reaching.cpp | 3 +- .../maple_be/src/cg/cg_phasemanager.cpp | 1 + src/mapleall/maple_be/src/cg/cgfunc.cpp | 48 +- src/mapleall/maple_be/src/cg/emit.cpp | 5 + src/mapleall/maple_be/src/cg/memlayout.cpp | 6 +- .../maple_ir/include/bin_mpl_export.h | 28 +- .../maple_ir/include/bin_mpl_import.h | 12 +- .../maple_ir/include/ir_safe_cast_traits.def | 4 +- src/mapleall/maple_ir/include/keywords.def | 1 - src/mapleall/maple_ir/include/mir_builder.h | 2 + src/mapleall/maple_ir/include/mir_function.h | 18 +- src/mapleall/maple_ir/include/mir_lower.h | 1 + src/mapleall/maple_ir/include/mir_nodes.h | 2 +- src/mapleall/maple_ir/include/mir_parser.h | 2 +- src/mapleall/maple_ir/include/mir_symbol.h | 6 +- src/mapleall/maple_ir/include/mir_type.h | 27 +- src/mapleall/maple_ir/include/opcode_info.h | 1 + src/mapleall/maple_ir/include/opcodes.def | 1 + src/mapleall/maple_ir/include/opcodes.h | 4 +- src/mapleall/maple_ir/src/bin_func_export.cpp | 239 ++++---- src/mapleall/maple_ir/src/bin_func_import.cpp | 248 ++++---- src/mapleall/maple_ir/src/bin_mpl_export.cpp | 112 ++-- src/mapleall/maple_ir/src/bin_mpl_import.cpp | 48 +- src/mapleall/maple_ir/src/global_tables.cpp | 4 +- src/mapleall/maple_ir/src/mir_builder.cpp | 24 + src/mapleall/maple_ir/src/mir_function.cpp | 4 +- src/mapleall/maple_ir/src/mir_lower.cpp | 107 ++++ src/mapleall/maple_ir/src/mir_nodes.cpp | 4 +- src/mapleall/maple_ir/src/mir_parser.cpp | 31 +- src/mapleall/maple_ir/src/mir_type.cpp | 8 +- src/mapleall/maple_ir/src/parser.cpp | 18 +- src/mapleall/maple_me/include/lmbc_lower.h | 3 - .../maple_me/include/lmbc_memlayout.h | 64 +- src/mapleall/maple_me/src/alias_class.cpp | 8 +- src/mapleall/maple_me/src/code_factoring.cpp | 4 +- .../src/demand_driven_alias_analysis.cpp | 4 +- src/mapleall/maple_me/src/irmap_build.cpp | 7 +- src/mapleall/maple_me/src/irmap_emit.cpp | 5 +- src/mapleall/maple_me/src/lfo_dep_test.cpp | 2 + src/mapleall/maple_me/src/lmbc_lower.cpp | 258 ++------- src/mapleall/maple_me/src/lmbc_memlayout.cpp | 439 +------------- src/mapleall/maple_me/src/me_cfg.cpp | 2 + src/mapleall/maple_me/src/me_function.cpp | 4 +- .../maple_me/src/me_lower_globals.cpp | 13 +- .../maple_me/src/me_phase_manager.cpp | 7 +- src/mapleall/maple_me/src/me_rc_lowering.cpp | 1 + src/mapleall/maple_me/src/me_rename2preg.cpp | 1 + src/mapleall/maple_me/src/me_side_effect.cpp | 4 +- src/mapleall/maple_me/src/me_stmt_pre.cpp | 4 +- src/mapleall/maple_me/src/pme_emit.cpp | 9 +- src/mapleall/maple_me/src/ssa_devirtual.cpp | 4 +- src/mapleall/maple_me/src/ssa_pre.cpp | 2 + src/mapleall/mpl2mpl/src/constantfold.cpp | 6 +- 67 files changed, 1408 insertions(+), 1303 deletions(-) diff --git a/src/mapleall/maple_be/include/be/lower.h b/src/mapleall/maple_be/include/be/lower.h index 6da66a3fcf..92c9e840e9 100644 --- a/src/mapleall/maple_be/include/be/lower.h +++ b/src/mapleall/maple_be/include/be/lower.h @@ -187,7 +187,7 @@ class CGLowerer { void LowerTryCatchBlocks(BlockNode &body); #if TARGARM32 || TARGAARCH64 || TARGRISCV64 - BlockNode *LowerReturnStruct(NaryStmtNode &retNode); + BlockNode *LowerReturnStructUsingFakeParm(NaryStmtNode &retNode); #endif virtual BlockNode *LowerReturn(NaryStmtNode &retNode); void LowerEntry(MIRFunction &func); 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 e0d1497b74..7a6e406263 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -38,6 +38,7 @@ class LmbcArgInfo { MapleVector lmbcCallArgTypes; MapleVector lmbcCallArgOffsets; MapleVector lmbcCallArgNumOfRegs; // # of regs needed to complete struct + uint32 lmbcTotalStkUsed = -1; // TBD: remove when explicit addr for large agg is available }; class AArch64CGFunc : public CGFunc { @@ -101,7 +102,7 @@ class AArch64CGFunc : public CGFunc { return kRFLAG; } - MIRType *GetAggTyFromCallSite(StmtNode *stmt); + MIRType *LmbcGetAggTyFromCallSite(StmtNode *stmt, std::vector **parmList); RegOperand &GetOrCreateResOperand(const BaseNode &parent, PrimType primType); void IntrinsifyGetAndAddInt(ListOperand &srcOpnds, PrimType pty); @@ -125,9 +126,11 @@ class AArch64CGFunc : public CGFunc { bool needLow12 = false); MemOperand *FixLargeMemOpnd(MemOperand &memOpnd, uint32 align); MemOperand *FixLargeMemOpnd(MOperator mOp, MemOperand &memOpnd, uint32 dSize, uint32 opndIdx); + uint32 LmbcFindTotalStkUsed(std::vector* paramList); + uint32 LmbcTotalRegsUsed(); void LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn); - bool LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *src); - bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForRet(BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; void SelectIassignoff(IassignoffNode &stmt) override; @@ -135,6 +138,7 @@ class AArch64CGFunc : public CGFunc { void SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd) override; void SelectBlkassignoff(BlkassignoffNode &bNode, Operand *src) override; void SelectAggIassign(IassignNode &stmt, Operand &lhsAddrOpnd) override; + void SelectReturnSendOfStructInRegs(BaseNode *x) override; void SelectReturn(Operand *opnd0) override; void SelectIgoto(Operand *opnd0) override; void SelectCondGoto(CondGotoNode &stmt, Operand &opnd0, Operand &opnd1) override; @@ -486,7 +490,10 @@ class AArch64CGFunc : public CGFunc { void GenerateCleanupCodeForExtEpilog(BB &bb) override; uint32 FloatParamRegRequired(MIRStructType *structType, uint32 &fpSize) override; void AssignLmbcFormalParams() override; - RegOperand *GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType); + void LmbcGenSaveSpForAlloca() override; + MemOperand *GenLmbcFpMemOperand(int32 offset, uint32 byteSize, AArch64reg base = RFP); + RegOperand *GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType, AArch64reg baseRegno = RFP); + RegOperand *LmbcStructReturnLoad(int32 offset); Operand *GetBaseReg(const AArch64SymbolAlloc &symAlloc); int32 GetBaseOffset(const SymbolAlloc &symAlloc) override; @@ -732,6 +739,22 @@ class AArch64CGFunc : public CGFunc { RegOperand &GetZeroOpnd(uint32 size) override; + int32 GetLmbcTotalStkUsed() { + return lmbcArgInfo->lmbcTotalStkUsed; + } + + void SetLmbcTotalStkUsed(int32 offset) { + lmbcArgInfo->lmbcTotalStkUsed = offset; + } + + void SetLmbcCallReturnType(MIRType *ty) { + lmbcCallReturnType = ty; + } + + MIRType *GetLmbcCallReturnType() { + return lmbcCallReturnType; + } + private: enum RelationOperator : uint8 { kAND, @@ -799,6 +822,7 @@ class AArch64CGFunc : public CGFunc { regno_t methodHandleVreg = -1; uint32 alignPow = 5; /* function align pow defaults to 5 i.e. 2^5*/ LmbcArgInfo *lmbcArgInfo = nullptr; + MIRType *lmbcCallReturnType = nullptr; void SelectLoadAcquire(Operand &dest, PrimType dtype, Operand &src, PrimType stype, AArch64isa::MemoryOrdering memOrd, bool isDirect); diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def b/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def index a3a74d7b2f..ff08e81852 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def @@ -16,8 +16,8 @@ ADDTARGETPHASE("createstartendlabel", true); ADDTARGETPHASE("buildehfunc", true); ADDTARGETPHASE("handlefunction", true); + ADDTARGETPHASE("moveargs", true); if (GetMIRModule()->GetFlavor() != MIRFlavor::kFlavorLmbc) { - ADDTARGETPHASE("moveargs", true); /* SSA PHASES */ ADDTARGETPHASE("cgssaconstruct", CGOptions::DoCGSSA()); ADDTARGETPHASE("cgcopyprop", CGOptions::DoCGSSA()); diff --git a/src/mapleall/maple_be/include/cg/call_conv.h b/src/mapleall/maple_be/include/cg/call_conv.h index 9cfab98b56..4e33309c3c 100644 --- a/src/mapleall/maple_be/include/cg/call_conv.h +++ b/src/mapleall/maple_be/include/cg/call_conv.h @@ -63,8 +63,8 @@ struct CCLocInfo { class LmbcFormalParamInfo { public: LmbcFormalParamInfo(PrimType pType, uint32 ofst, uint32 sz) : - type(nullptr), primType(pType), offset(ofst), size(sz), regNO(0), vregNO(0), numRegs(0), - fpSize(0), isReturn(false), isPureFloat(false), isOnStack(false) {} + type(nullptr), primType(pType), offset(ofst), onStackOffset(0), size(sz), regNO(0), vregNO(0), numRegs(0), + fpSize(0), isReturn(false), isPureFloat(false), isOnStack(false), hasRegassign(false) {} ~LmbcFormalParamInfo() = default; @@ -86,7 +86,13 @@ class LmbcFormalParamInfo { void SetOffset(uint32 ofs) { offset = ofs; } - uint32 GetSize() const { + uint32 GetOnStackOffset() { + return onStackOffset; + } + void SetOnStackOffset(uint32 ofs) { + onStackOffset = ofs; + } + uint32 GetSize() { return size; } void SetSize(uint32 sz) { @@ -137,10 +143,17 @@ class LmbcFormalParamInfo { void SetIsOnStack() { isOnStack = true; } + bool HasRegassign() { + return hasRegassign; + } + void SetHasRegassign() { + hasRegassign = true; + } private: MIRStructType *type; PrimType primType; uint32 offset; + uint32 onStackOffset; /* stack location if isOnStack */ uint32 size; /* size primtype or struct */ regno_t regNO = 0; /* param reg num or starting reg num if numRegs > 0 */ regno_t vregNO = 0; /* if no explicit regassing from IR, create move from param reg */ @@ -148,7 +161,8 @@ class LmbcFormalParamInfo { uint32 fpSize = 0; /* size of fp param if isPureFloat */ bool isReturn; bool isPureFloat = false; - bool isOnStack; /* small struct with arrays need to be saved onto stack */ + bool isOnStack; /* large struct is passed by a copy on stack */ + bool hasRegassign; }; } /* namespace maplebe */ diff --git a/src/mapleall/maple_be/include/cg/cg.h b/src/mapleall/maple_be/include/cg/cg.h index 093289e42b..e1368acb1d 100644 --- a/src/mapleall/maple_be/include/cg/cg.h +++ b/src/mapleall/maple_be/include/cg/cg.h @@ -121,11 +121,13 @@ class CG { emitter(nullptr), labelOrderCnt(0), cgOption(cgOptions), - instrumentationFunction(nullptr) { + instrumentationFunction(nullptr), + fileGP(nullptr) { const std::string &internalNameLiteral = namemangler::GetInternalNameLiteral(namemangler::kJavaLangObjectStr); GStrIdx strIdxFromName = GlobalTables::GetStrTable().GetStrIdxFromName(internalNameLiteral); isLibcore = (GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdxFromName) != nullptr); DefineDebugTraceFunctions(); + isLmbc = (mirModule->GetFlavor() == MIRFlavor::kFlavorLmbc); } virtual ~CG(); @@ -361,6 +363,10 @@ class CG { return isLibcore; } + bool IsLmbc() const { + return isLmbc; + } + MIRSymbol *GetDebugTraceEnterFunction() { return dbgTraceEnter; } @@ -421,6 +427,13 @@ class CG { /* Object map generation helper */ std::vector GetReferenceOffsets64(const BECommon &beCommon, MIRStructType &structType); + void SetGP(MIRSymbol *sym) { + fileGP = sym; + } + MIRSymbol *GetGP() const { + return fileGP; + } + static bool IsInFuncWrapLabels(MIRFunction *func) { return funcWrapLabels.find(func) != funcWrapLabels.end(); } @@ -449,12 +462,14 @@ class CG { LabelIDOrder labelOrderCnt; static CGFunc *currentCGFunction; /* current cg function being compiled */ CGOptions cgOption; - bool isLibcore; MIRSymbol *instrumentationFunction; MIRSymbol *dbgTraceEnter; MIRSymbol *dbgTraceExit; MIRSymbol *dbgFuncProfile; + MIRSymbol *fileGP; /* for lmbc, one local %GP per file */ static std::map> funcWrapLabels; + bool isLibcore; + bool isLmbc; }; /* class CG */ } /* namespace maplebe */ diff --git a/src/mapleall/maple_be/include/cg/cgfunc.h b/src/mapleall/maple_be/include/cg/cgfunc.h index 9623c989e4..0695a784de 100644 --- a/src/mapleall/maple_be/include/cg/cgfunc.h +++ b/src/mapleall/maple_be/include/cg/cgfunc.h @@ -160,6 +160,7 @@ class CGFunc { virtual uint32 FloatParamRegRequired(MIRStructType *structType, uint32 &fpSize) = 0; virtual void AssignLmbcFormalParams() = 0; LmbcFormalParamInfo *GetLmbcFormalParamInfo(uint32 offset); + virtual void LmbcGenSaveSpForAlloca() = 0; void GenerateLoc(StmtNode *stmt, unsigned &lastSrcLoc, unsigned &lastMplLoc); int32 GetFreqFromStmt(uint32 stmtId); void GenerateInstruction(); @@ -201,6 +202,7 @@ class CGFunc { virtual void SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd) = 0; virtual void SelectBlkassignoff(BlkassignoffNode &bNode, Operand *src) = 0; virtual void SelectAggIassign(IassignNode &stmt, Operand &lhsAddrOpnd) = 0; + virtual void SelectReturnSendOfStructInRegs(BaseNode *x) = 0; virtual void SelectReturn(Operand *opnd) = 0; virtual void SelectIgoto(Operand *opnd0) = 0; virtual void SelectCondGoto(CondGotoNode &stmt, Operand &opnd0, Operand &opnd1) = 0; diff --git a/src/mapleall/maple_be/src/be/lower.cpp b/src/mapleall/maple_be/src/be/lower.cpp index 00e1db5bf3..137a5ff3c0 100644 --- a/src/mapleall/maple_be/src/be/lower.cpp +++ b/src/mapleall/maple_be/src/be/lower.cpp @@ -121,6 +121,7 @@ void CGLowerer::RegisterExternalLibraryFunctions() { func->AllocSymTab(); MIRSymbol *funcSym = func->GetFuncSymbol(); funcSym->SetStorageClass(kScExtern); + funcSym->SetAppearsInCode(true); /* return type */ MIRType *retTy = GlobalTables::GetTypeTable().GetPrimType(extFnDescrs[i].retType); @@ -879,7 +880,7 @@ void CGLowerer::LowerTypePtr(BaseNode &node) const { #if TARGARM32 || TARGAARCH64 || TARGRISCV64 -BlockNode *CGLowerer::LowerReturnStruct(NaryStmtNode &retNode) { +BlockNode *CGLowerer::LowerReturnStructUsingFakeParm(NaryStmtNode &retNode) { BlockNode *blk = mirModule.CurFuncCodeMemPool()->New(); for (size_t i = 0; i < retNode.GetNopndSize(); ++i) { retNode.SetOpnd(LowerExpr(retNode, *retNode.GetNopndAt(i), *blk), i); @@ -1104,7 +1105,7 @@ void CGLowerer::LowerCallStmt(StmtNode &stmt, StmtNode *&nextStmt, BlockNode &ne return; } - if ((newStmt->GetOpCode() == OP_call) || (newStmt->GetOpCode() == OP_icall)) { + if (newStmt->GetOpCode() == OP_call || newStmt->GetOpCode() == OP_icall || newStmt->GetOpCode() == OP_icallproto) { newStmt = LowerCall(static_cast(*newStmt), nextStmt, newBlk, retty, uselvar); } newStmt->SetSrcPos(stmt.GetSrcPos()); @@ -1175,7 +1176,12 @@ StmtNode *CGLowerer::GenIntrinsiccallNode(const StmtNode &stmt, PUIdx &funcCalle StmtNode *CGLowerer::GenIcallNode(PUIdx &funcCalled, IcallNode &origCall) { StmtNode *newCall = nullptr; - newCall = mirModule.GetMIRBuilder()->CreateStmtIcall(origCall.GetNopnd()); + if (origCall.GetOpCode() == OP_icallassigned) { + newCall = mirModule.GetMIRBuilder()->CreateStmtIcall(origCall.GetNopnd()); + } else { + newCall = mirModule.GetMIRBuilder()->CreateStmtIcallproto(origCall.GetNopnd()); + static_cast(newCall)->SetRetTyIdx(static_cast(origCall).GetRetTyIdx()); + } newCall->SetSrcPos(origCall.GetSrcPos()); CHECK_FATAL(newCall != nullptr, "nullptr is not expected"); funcCalled = kFuncNotFound; @@ -1377,6 +1383,7 @@ BlockNode *CGLowerer::LowerCallAssignedStmt(StmtNode &stmt, bool uselvar) { static_cast(newCall)->SetReturnVec(*p2nRets); break; } + case OP_icallprotoassigned: case OP_icallassigned: { auto &origCall = static_cast(stmt); newCall = GenIcallNode(funcCalled, origCall); @@ -1484,6 +1491,15 @@ bool CGLowerer::LowerStructReturn(BlockNode &newBlk, StmtNode *stmt, (*p2nrets)[0].first = dnodeStmt->GetStIdx(); (*p2nrets)[0].second.SetFieldID(dnodeStmt->GetFieldID()); lvar = true; + // set ATTR_firstarg_return for callee + if (stmt->GetOpCode() == OP_callassigned) { + CallNode *callNode = static_cast(stmt); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callNode->GetPUIdx()); + f->SetFirstArgReturn(); + f->GetMIRFuncType()->SetFirstArgReturn(); + } else { + // for icall, front-end already set ATTR_firstarg_return + } } else { /* struct <= 16 passed in regs lowered into call &foo regassign u64 %1 (regread u64 %%retval0) @@ -1501,13 +1517,19 @@ bool CGLowerer::LowerStructReturn(BlockNode &newBlk, StmtNode *stmt, CallNode *callStmt = mirModule.GetMIRBuilder()->CreateStmtCall(callNode->GetPUIdx(), callNode->GetNopnd()); callStmt->SetSrcPos(callNode->GetSrcPos()); newBlk.AddStatement(callStmt); - } else if (stmt->GetOpCode() == OP_icallassigned) { + } else if (stmt->GetOpCode() == OP_icallassigned || stmt->GetOpCode() == OP_icallprotoassigned) { auto *icallNode = static_cast(stmt); for (size_t i = 0; i < icallNode->GetNopndSize(); ++i) { BaseNode *newOpnd = LowerExpr(*icallNode, *icallNode->GetNopndAt(i), newBlk); icallNode->SetOpnd(newOpnd, i); } - IcallNode *icallStmt = mirModule.GetMIRBuilder()->CreateStmtIcall(icallNode->GetNopnd()); + IcallNode *icallStmt = nullptr; + if (stmt->GetOpCode() == OP_icallassigned) { + icallStmt = mirModule.GetMIRBuilder()->CreateStmtIcall(icallNode->GetNopnd()); + } else { + icallStmt = mirModule.GetMIRBuilder()->CreateStmtIcallproto(icallNode->GetNopnd()); + icallStmt->SetRetTyIdx(icallNode->GetRetTyIdx()); + } icallStmt->SetSrcPos(icallNode->GetSrcPos()); newBlk.AddStatement(icallStmt); } else { @@ -1773,6 +1795,7 @@ void CGLowerer::LowerAssertBoundary(StmtNode &stmt, BlockNode &block, BlockNode CondGotoNode *brFalseNode = mirBuilder->CreateStmtCondGoto(cond, OP_brfalse, labIdx); MIRFunction *printf = mirBuilder->GetOrCreateFunction("printf", TyIdx(PTY_i32)); + printf->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*printf->GetMIRFuncType()); MapleVector argsPrintf(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); uint32 oldTypeTableSize = GlobalTables::GetTypeTable().GetTypeTableSize(); @@ -1848,7 +1871,8 @@ BlockNode *CGLowerer::LowerBlock(BlockNode &block) { break; } case OP_callassigned: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallprotoassigned: { // pass the addr of lvar if this is a struct call assignment bool lvar = false; // nextStmt could be changed by the call to LowerStructReturn @@ -1868,6 +1892,7 @@ BlockNode *CGLowerer::LowerBlock(BlockNode &block) { case OP_intrinsiccall: case OP_call: case OP_icall: + case OP_icallproto: #if TARGARM32 || TARGAARCH64 || TARGRISCV64 || TARGX86_64 // nextStmt could be changed by the call to LowerStructReturn LowerCallStmt(*stmt, nextStmt, *newBlk); @@ -1877,8 +1902,8 @@ BlockNode *CGLowerer::LowerBlock(BlockNode &block) { break; case OP_return: { #if TARGARM32 || TARGAARCH64 || TARGRISCV64 - if (GetCurrentFunc()->IsReturnStruct()) { - newBlk->AppendStatementsFromBlock(*LowerReturnStruct(static_cast(*stmt))); + if (GetCurrentFunc()->IsFirstArgReturn() && stmt->NumOpnds() > 0) { + newBlk->AppendStatementsFromBlock(*LowerReturnStructUsingFakeParm(static_cast(*stmt))); } else { #endif NaryStmtNode *retNode = static_cast(stmt); @@ -1976,7 +2001,9 @@ void CGLowerer::SimplifyBlock(BlockNode &block) { } auto *newFunc = theMIRModule->GetMIRBuilder()->GetOrCreateFunction(asmMap.at(oldFunc->GetName()), callStmt->GetTyIdx()); - newFunc->GetFuncSymbol()->SetStorageClass(kScExtern); + MIRSymbol *funcSym = newFunc->GetFuncSymbol(); + funcSym->SetStorageClass(kScExtern); + funcSym->SetAppearsInCode(true); callStmt->SetPUIdx(newFunc->GetPuidx()); break; } @@ -2086,6 +2113,7 @@ StmtNode *CGLowerer::LowerCall( if (needCheckStore) { MIRFunction *fn = mirModule.GetMIRBuilder()->GetOrCreateFunction("MCC_Reflect_Check_Arraystore", TyIdx(PTY_void)); + fn->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); MapleVector args(mirModule.GetMIRBuilder()->GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -2112,7 +2140,7 @@ StmtNode *CGLowerer::LowerCall( } MIRType *retType = nullptr; - if (callNode.op == OP_icall) { + if (callNode.op == OP_icall || callNode.op == OP_icallproto) { if (retTy == nullptr) { return &callNode; } else { @@ -2158,7 +2186,7 @@ StmtNode *CGLowerer::LowerCall( addrofNode->SetStIdx(dsgnSt->GetStIdx()); addrofNode->SetFieldID(0); - if (callNode.op == OP_icall) { + if (callNode.op == OP_icall || callNode.op == OP_icallproto) { auto ond = callNode.GetNopnd().begin(); newNopnd.emplace_back(*ond); newNopnd.emplace_back(addrofNode); @@ -2180,7 +2208,27 @@ StmtNode *CGLowerer::LowerCall( } void CGLowerer::LowerEntry(MIRFunction &func) { + // determine if needed to insert fake parameter to return struct for current function if (func.IsReturnStruct()) { + MIRType *retType = func.GetReturnType(); +#if TARGAARCH64 + PrimType pty = IsStructElementSame(retType); + if (pty == PTY_f32 || pty == PTY_f64 || IsPrimitiveVector(pty)) { + func.SetStructReturnedInRegs(); + return; + } +#endif + if (retType->GetPrimType() != PTY_agg) { + return; + } + if (retType->GetSize() > k16ByteSize) { + func.SetFirstArgReturn(); + func.GetMIRFuncType()->SetFirstArgReturn(); + } else { + func.SetStructReturnedInRegs(); + } + } + if (func.IsFirstArgReturn() && func.GetReturnType()->GetPrimType() != PTY_void) { MIRSymbol *retSt = func.GetSymTab()->CreateSymbol(kScopeLocal); retSt->SetStorageClass(kScFormal); retSt->SetSKind(kStVar); @@ -2197,12 +2245,14 @@ void CGLowerer::LowerEntry(MIRFunction &func) { auto formal = func.GetFormal(i); formals.emplace_back(formal); } + func.SetFirstArgReturn(); beCommon.AddElementToFuncReturnType(func, func.GetReturnTyIdx()); func.UpdateFuncTypeAndFormalsAndReturnType(formals, TyIdx(PTY_void), true); auto *funcType = func.GetMIRFuncType(); ASSERT(funcType != nullptr, "null ptr check"); + funcType->SetFirstArgReturn(); beCommon.AddTypeSizeAndAlign(funcType->GetTypeIndex(), GetPrimTypeSize(funcType->GetPrimType())); } } @@ -2380,6 +2430,7 @@ MIRFunction *CGLowerer::RegisterFunctionVoidStarToVoid(BuiltinFunctionID id, con func->AllocSymTab(); MIRSymbol *funcSym = func->GetFuncSymbol(); funcSym->SetStorageClass(kScExtern); + funcSym->SetAppearsInCode(true); MIRType *argTy = GlobalTables::GetTypeTable().GetPtr(); MIRSymbol *argSt = func->GetSymTab()->CreateSymbol(kScopeLocal); argSt->SetNameStrIdx(mirBuilder->GetOrCreateStringIndex(paramName)); @@ -2421,6 +2472,7 @@ void CGLowerer::RegisterBuiltIns() { func->AllocSymTab(); MIRSymbol *funcSym = func->GetFuncSymbol(); funcSym->SetStorageClass(kScExtern); + funcSym->SetAppearsInCode(true); /* return type */ MIRType *retTy = desc.GetReturnType(); CHECK_FATAL(retTy != nullptr, "retTy should not be nullptr"); @@ -2576,6 +2628,7 @@ void CGLowerer::ProcessArrayExpr(BaseNode &expr, BlockNode &blkNode) { arrayNode.GetNopndAt(1), lenRegreadNode); CondGotoNode *brFalseNode = mirBuilder->CreateStmtCondGoto(cond, OP_brfalse, labIdx); MIRFunction *fn = mirBuilder->GetOrCreateFunction("MCC_Array_Boundary_Check", TyIdx(PTY_void)); + fn->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); MapleVector args(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -3107,6 +3160,7 @@ BaseNode *CGLowerer::LowerIntrinJavaArrayLength(const BaseNode &parent, Intrinsi MIRFunction *newFunc = mirBuilder->GetOrCreateFunction("MCC_ThrowNullArrayNullPointerException", GlobalTables::GetTypeTable().GetVoid()->GetTypeIndex()); + newFunc->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*newFunc->GetMIRFuncType()); newFunc->AllocSymTab(); MapleVector args(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -3478,6 +3532,7 @@ StmtNode *CGLowerer::LowerIntrinsicRCCall(const IntrinsiccallNode &intrincall) { if (intrinFuncIDs.find(intrinDesc) == intrinFuncIDs.end()) { /* add funcid into map */ MIRFunction *fn = mirBuilder->GetOrCreateFunction(intrinDesc->name, TyIdx(PTY_void)); + fn->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); intrinFuncIDs[intrinDesc] = fn->GetPuidx(); @@ -3506,6 +3561,7 @@ void CGLowerer::LowerArrayStore(const IntrinsiccallNode &intrincall, BlockNode & if (needCheckStore) { MIRFunction *fn = mirBuilder->GetOrCreateFunction("MCC_Reflect_Check_Arraystore", TyIdx(PTY_void)); + fn->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); MapleVector args(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -3595,6 +3651,7 @@ StmtNode *CGLowerer::LowerIntrinsiccall(IntrinsiccallNode &intrincall, BlockNode beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); st->SetFunction(fn); + st->SetAppearsInCode(true); return LowerDefaultIntrinsicCall(intrincall, *st, *fn); } @@ -3665,6 +3722,7 @@ PUIdx CGLowerer::GetBuiltinToUse(BuiltinFunctionID id) const { void CGLowerer::LowerGCMalloc(const BaseNode &node, const GCMallocNode &gcmalloc, BlockNode &blkNode, bool perm) { MIRFunction *func = mirBuilder->GetOrCreateFunction((perm ? "MCC_NewPermanentObject" : "MCC_NewObj_fixed_class"), (TyIdx)(LOWERED_PTR_TYPE)); + func->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*func->GetMIRFuncType()); func->AllocSymTab(); /* Get the classinfo */ @@ -3683,6 +3741,7 @@ void CGLowerer::LowerGCMalloc(const BaseNode &node, const GCMallocNode &gcmalloc if (classSym->GetAttr(ATTR_abstract) || classSym->GetAttr(ATTR_interface)) { MIRFunction *funcSecond = mirBuilder->GetOrCreateFunction("MCC_Reflect_ThrowInstantiationError", (TyIdx)(LOWERED_PTR_TYPE)); + funcSecond->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*funcSecond->GetMIRFuncType()); funcSecond->AllocSymTab(); BaseNode *arg = mirBuilder->CreateExprAddrof(0, *classSym); @@ -3801,6 +3860,7 @@ void CGLowerer::LowerJarrayMalloc(const StmtNode &stmt, const JarrayMallocNode & args.emplace_back(mirBuilder->CreateIntConst(0, PTY_u32)); } MIRFunction *func = mirBuilder->GetOrCreateFunction(funcName, (TyIdx)(LOWERED_PTR_TYPE)); + func->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*func->GetMIRFuncType()); func->AllocSymTab(); CallNode *callAssign = nullptr; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 46b804c0cb..5869978884 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -38,7 +38,7 @@ void AArch64MoveRegArgs::CollectRegisterArgs(std::map &argsL uint32 start = 0; if (numFormal) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsReturnStruct()) { + if (func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16ByteSize) { start = 1; @@ -439,7 +439,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsReturnStruct()) { + if (func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp index 51fb1a1265..b89e1b4c40 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp @@ -300,7 +300,7 @@ int32 AArch64CallConvImpl::LocateNextParm(MIRType &mirType, CCLocInfo &pLoc, boo if (isFirst) { MIRFunction *func = tFunc != nullptr ? tFunc : const_cast(beCommon.GetMIRModule().CurFunction()); - if (func->IsReturnStruct()) { + if (func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); size_t size = beCommon.GetTypeSize(tyIdx); if (size == 0) { 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 7d015832ca..5da7b66ec2 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -1411,15 +1411,44 @@ void AArch64CGFunc::SelectAsm(AsmNode &node) { } void AArch64CGFunc::SelectRegassign(RegassignNode &stmt, Operand &opnd0) { + if (GetCG()->IsLmbc()) { + PrimType lhsSize = stmt.GetPrimType(); + PrimType rhsSize = stmt.Opnd(0)->GetPrimType(); + if (lhsSize != rhsSize && stmt.Opnd(0)->GetOpCode() == OP_ireadoff) { + Insn *prev = GetCurBB()->GetLastInsn(); + if (prev->GetMachineOpcode() == MOP_wldrsb || prev->GetMachineOpcode() == MOP_wldrsh) { + opnd0.SetSize(GetPrimTypeBitSize(stmt.GetPrimType())); + prev->SetMOP(prev->GetMachineOpcode() == MOP_wldrsb ? MOP_xldrsb : MOP_xldrsh); + } else if (prev->GetMachineOpcode() == MOP_wldr && stmt.GetPrimType() == PTY_i64) { + opnd0.SetSize(GetPrimTypeBitSize(stmt.GetPrimType())); + prev->SetMOP(MOP_xldrsw); + } + } + } RegOperand *regOpnd = nullptr; PregIdx pregIdx = stmt.GetRegIdx(); if (IsSpecialPseudoRegister(pregIdx)) { - regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, stmt.GetPrimType()); + if (GetCG()->IsLmbc() && stmt.GetPrimType() == PTY_agg) { + if (static_cast(opnd0).IsOfIntClass()) { + regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, PTY_i64); + } else if (opnd0.GetSize() <= k4ByteSize) { + regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, PTY_f32); + } else { + regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, PTY_f64); + } + } else { + regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, stmt.GetPrimType()); + } } else { regOpnd = &GetOrCreateVirtualRegisterOperand(GetVirtualRegNOFromPseudoRegIdx(pregIdx)); } /* look at rhs */ PrimType rhsType = stmt.Opnd(0)->GetPrimType(); + if (GetCG()->IsLmbc() && rhsType == PTY_agg) { + /* This occurs when a call returns a small struct */ + /* The subtree should already taken care of the agg type that is in excess of 8 bytes */ + rhsType = PTY_i64; + } PrimType dtype = rhsType; if (GetPrimTypeBitSize(dtype) < k32BitSize) { ASSERT(IsPrimitiveInteger(dtype), ""); @@ -1441,6 +1470,12 @@ void AArch64CGFunc::SelectRegassign(RegassignNode &stmt, Operand &opnd0) { MIRPreg *preg = GetFunction().GetPregTab()->PregFromPregIdx(pregIdx); uint32 srcBitLength = GetPrimTypeSize(preg->GetPrimType()) * kBitsPerByte; GetCurBB()->AppendInsn(GetCG()->BuildInstruction(PickStInsn(srcBitLength, stype), *regOpnd, *dest)); + } else if (regOpnd->GetRegisterNumber() == R0 || regOpnd->GetRegisterNumber() == R1) { + Insn &pseudo = GetCG()->BuildInstruction(MOP_pseudo_ret_int, *regOpnd); + GetCurBB()->AppendInsn(pseudo); + } else if (regOpnd->GetRegisterNumber() >= V0 && regOpnd->GetRegisterNumber() <= V3) { + Insn &pseudo = GetCG()->BuildInstruction(MOP_pseudo_ret_float, *regOpnd); + GetCurBB()->AppendInsn(pseudo); } } @@ -1922,15 +1957,11 @@ void AArch64CGFunc::SelectIassignoff(IassignoffNode &stmt) { SelectCopy(memOpnd, destType, srcOpnd, destType); } -void AArch64CGFunc::SelectIassignfpoff(IassignFPoffNode &stmt, Operand &opnd) { - int32 offset = stmt.GetOffset(); - PrimType primType = stmt.GetPrimType(); - uint32 bitlen = GetPrimTypeSize(primType) * kBitsPerByte; - - Operand &srcOpnd = LoadIntoRegister(opnd, primType); +MemOperand *AArch64CGFunc::GenLmbcFpMemOperand(int32 offset, uint32 byteSize, AArch64reg baseRegno) { MemOperand *memOpnd; - RegOperand *rfp = &GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); - if (offset < 0) { + RegOperand *rfp = &GetOrCreatePhysicalRegisterOperand(baseRegno, k64BitSize, kRegTyInt); + uint32 bitlen = byteSize * kBitsPerByte; + if (offset < 0 && offset < -256) { RegOperand *baseOpnd = &CreateRegisterOperandOfType(PTY_a64); ImmOperand &immOpnd = CreateImmOperand(offset, k32BitSize, true); Insn &addInsn = GetCG()->BuildInstruction(MOP_xaddrri12, *baseOpnd, *rfp, immOpnd); @@ -1942,11 +1973,45 @@ void AArch64CGFunc::SelectIassignfpoff(IassignFPoffNode &stmt, Operand &opnd) { memOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, bitlen, rfp, nullptr, offsetOpnd, nullptr); } memOpnd->SetStackMem(true); - MOperator mOp = PickStInsn(bitlen, primType); - Insn &store = GetCG()->BuildInstruction(mOp, srcOpnd, *memOpnd); - GetCurBB()->AppendInsn(store); + return memOpnd; +} + +void AArch64CGFunc::SelectIassignfpoff(IassignFPoffNode &stmt, Operand &opnd) { + int32 offset = stmt.GetOffset(); + PrimType primType = stmt.GetPrimType(); + MIRType *rType = GetLmbcCallReturnType(); + bool isPureFpStruct = false; + uint32 numRegs = 0; + if (rType && rType->GetPrimType() == PTY_agg && opnd.IsRegister() && static_cast(opnd).IsPhysicalRegister()) { + CHECK_FATAL(rType->GetSize() <= 16, "SelectIassignfpoff invalid agg size"); + uint32 fpSize; + numRegs = FloatParamRegRequired(static_cast(rType), fpSize); + if (numRegs) { + primType = (fpSize == k4ByteSize) ? PTY_f32 : PTY_f64; + isPureFpStruct = true; + } + } + uint32 byteSize = GetPrimTypeSize(primType); + uint32 bitlen = byteSize * kBitsPerByte; + if (isPureFpStruct) { + for (int i = 0 ; i < numRegs; ++i) { + MemOperand *memOpnd = GenLmbcFpMemOperand(offset + (i * byteSize), byteSize); + RegOperand &srcOpnd = GetOrCreatePhysicalRegisterOperand(AArch64reg(V0 + i), bitlen, kRegTyFloat); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, srcOpnd, *memOpnd); + GetCurBB()->AppendInsn(store); + } + } else { + Operand &srcOpnd = LoadIntoRegister(opnd, primType); + MemOperand *memOpnd = GenLmbcFpMemOperand(offset, byteSize); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, srcOpnd, *memOpnd); + GetCurBB()->AppendInsn(store); + } } +/* Load and assign to a new register. To be moved to the correct call register OR stack + location in LmbcSelectParmList */ void AArch64CGFunc::SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd) { if (GetLmbcArgInfo() == nullptr) { LmbcArgInfo *p = memPool->New(*GetFuncScopeAllocator()); @@ -1973,7 +2038,7 @@ void AArch64CGFunc::SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd } /* Search for CALL/ICALL/ICALLPROTO node, must be called from a blkassignoff node */ -MIRType *AArch64CGFunc::GetAggTyFromCallSite(StmtNode *stmt) { +MIRType *AArch64CGFunc::LmbcGetAggTyFromCallSite(StmtNode *stmt, std::vector **parmList) { for ( ; stmt != nullptr; stmt = stmt->GetNext()) { if (stmt->GetOpCode() == OP_call || stmt->GetOpCode() == OP_icallproto) { break; @@ -1986,25 +2051,20 @@ MIRType *AArch64CGFunc::GetAggTyFromCallSite(StmtNode *stmt) { if (stmt->GetOpCode() == OP_call) { CallNode *callNode = static_cast(stmt); MIRFunction *fn = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callNode->GetPUIdx()); - if (fn->IsReturnStruct()) { - ++nargs; - } if (fn->GetFormalCount() > 0) { - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fn->GetNthParamTyIdx(nargs)); + ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fn->GetFormalDefVec()[nargs].formalTyIdx); } + *parmList = &fn->GetParamTypes(); // would return null if the actual parameter is bogus } else if (stmt->GetOpCode() == OP_icallproto) { IcallNode *icallproto = static_cast(stmt); MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallproto->GetRetTyIdx()); MIRFuncType *fType = static_cast(type); - MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fType->GetRetTyIdx()); - if (retType->GetKind() == kTypeStruct) { - ++nargs; - } ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fType->GetNthParamType(nargs)); + *parmList = &fType->GetParamTypeList(); } else { CHECK_FATAL(stmt->GetOpCode() == OP_icallproto, - "GetAggTyFromCallSite:: unexpected call operator"); + "LmbcGetAggTyFromCallSite:: unexpected call operator"); } return ty; } @@ -2080,11 +2140,11 @@ bool AArch64CGFunc::LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *s } /* return true if blkassignoff for return, false otherwise */ -bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src) { +bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList) { AArch64reg regno = static_cast(static_cast(src)->GetRegisterNumber()); if (IsBlkassignForPush(bNode)) { PrimType pTy = PTY_i64; - MIRStructType *ty = static_cast(GetAggTyFromCallSite(&bNode)); + MIRStructType *ty = static_cast(LmbcGetAggTyFromCallSite(&bNode, parmList)); uint32 size = 0; uint32 fpregs = ty ? FloatParamRegRequired(ty, size) : 0; /* fp size determined */ if (fpregs > 0) { @@ -2095,7 +2155,7 @@ bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src) { MemOperand &mem = CreateMemOpnd(regno, s, size * kBitsPerByte); RegOperand *res = &CreateVirtualRegisterOperand(NewVReg(kRegTyFloat, size)); SelectCopy(*res, pTy, mem, pTy); - SetLmbcArgInfo(res, pTy, bNode.offset + s, static_cast(fpregs)); + SetLmbcArgInfo(res, pTy, 0, fpregs); IncLmbcArgsInRegs(kRegTyFloat); } IncLmbcTotalArgs(); @@ -2136,6 +2196,41 @@ bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src) { return false; } +/* This function is incomplete and may be removed when Lmbc IR is changed + to have the lowerer figures out the address of the large agg to reside */ +uint32 AArch64CGFunc::LmbcFindTotalStkUsed(std::vector *paramList) { + AArch64CallConvImpl parmlocator(GetBecommon()); + CCLocInfo pLoc; + for (TyIdx tyIdx : *paramList) { + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); + parmlocator.LocateNextParm(*ty, pLoc); + } + return 0; +} + +/* All arguments passed as registers */ +uint32 AArch64CGFunc::LmbcTotalRegsUsed() { + if (GetLmbcArgInfo() == nullptr) { + return 0; /* no arg */ + } + MapleVector ®s = GetLmbcCallArgNumOfRegs(); + MapleVector &types = GetLmbcCallArgTypes(); + uint32 iCnt = 0; + uint32 fCnt = 0; + for (uint32 i = 0; i < regs.size(); i++) { + if (IsPrimitiveInteger(types[i])) { + if ((iCnt + regs[i]) <= k8ByteSize) { + iCnt += regs[i]; + }; + } else { + if ((fCnt + regs[i]) <= k8ByteSize) { + fCnt += regs[i]; + }; + } + } + return iCnt + fCnt; +} + /* If blkassignoff for argument, this function loads the agg arguments into virtual registers, disregard if there is sufficient physicall call registers. Argument > 16-bytes are copied to preset space and ptr @@ -2144,29 +2239,40 @@ bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src) { void AArch64CGFunc::SelectBlkassignoff(BlkassignoffNode &bNode, Operand *src) { CHECK_FATAL(src->GetKind() == Operand::kOpdRegister, "blkassign src type not in register"); + std::vector *parmList; if (GetLmbcArgInfo() == nullptr) { LmbcArgInfo *p = memPool->New(*GetFuncScopeAllocator()); SetLmbcArgInfo(p); } if (LmbcSmallAggForRet(bNode, src)) { return; - } else if (LmbcSmallAggForCall(bNode, src)) { + } else if (LmbcSmallAggForCall(bNode, src, &parmList)) { return; } - /* memcpy for agg assign OR large agg for arg/ret */ Operand *dest = HandleExpr(bNode, *bNode.Opnd(0)); RegOperand *regResult = &CreateVirtualRegisterOperand(NewVReg(kRegTyInt, k8ByteSize)); + /* memcpy for agg assign OR large agg for arg/ret */ + int32 offset = bNode.offset; + if (IsBlkassignForPush(bNode)) { + /* large agg for call, addr to be pushed in SelectCall */ + offset = GetLmbcTotalStkUsed(); + if (offset < 0) { + /* length of ALL stack based args for this call, this location is where the + next large agg resides, its addr will then be passed */ + offset = LmbcFindTotalStkUsed(parmList) + LmbcTotalRegsUsed(); + } + SetLmbcTotalStkUsed(offset + bNode.blockSize); /* next use */ + SetLmbcArgInfo(regResult, PTY_i64, 0, 1); /* 1 reg for ptr */ + IncLmbcArgsInRegs(kRegTyInt); + IncLmbcTotalArgs(); + /* copy large agg arg to offset below */ + } std::vector opndVec; opndVec.push_back(regResult); /* result */ - opndVec.push_back(PrepareMemcpyParamOpnd(bNode.offset, *dest));/* param 0 */ + opndVec.push_back(PrepareMemcpyParamOpnd(offset, *dest)); /* param 0 */ opndVec.push_back(src); /* param 1 */ opndVec.push_back(PrepareMemcpyParamOpnd(static_cast(static_cast(bNode.blockSize))));/* param 2 */ SelectLibCall("memcpy", opndVec, PTY_a64, PTY_a64); - if (IsBlkassignForPush(bNode)) { - SetLmbcArgInfo(static_cast(src), PTY_i64, (int32)bNode.offset, 1); - IncLmbcArgsInRegs(kRegTyInt); - IncLmbcTotalArgs(); - } } void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { @@ -2553,6 +2659,159 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { } } +void AArch64CGFunc::SelectReturnSendOfStructInRegs(BaseNode *x) { + uint32 offset = 0; + if (x->GetOpCode() == OP_dread) { + DreadNode *dread = static_cast(x); + MIRSymbol *sym = GetFunction().GetLocalOrGlobalSymbol(dread->GetStIdx()); + MIRType *mirType = sym->GetType(); + if (dread->GetFieldID() != 0) { + MIRStructType *structType = static_cast(mirType); + mirType = structType->GetFieldType(dread->GetFieldID()); + offset = static_cast(GetBecommon().GetFieldOffset(*structType, dread->GetFieldID()).first); + } + uint32 typeSize = GetBecommon().GetTypeSize(mirType->GetTypeIndex()); + /* generate move to regs for agg return */ + AArch64CallConvImpl parmlocator(GetBecommon()); + CCLocInfo pLoc; + parmlocator.LocateNextParm(*mirType, pLoc, true, GetBecommon().GetMIRModule().CurFunction()); + /* aggregates are 8 byte aligned. */ + Operand *rhsmemopnd = nullptr; + RegOperand *result[kFourRegister]; /* up to 2 int or 4 fp */ + uint32 loadSize; + uint32 numRegs; + RegType regType; + PrimType retPty; + bool fpParm = false; + if (pLoc.numFpPureRegs) { + loadSize = pLoc.fpSize; + numRegs = pLoc.numFpPureRegs; + fpParm = true; + regType = kRegTyFloat; + retPty = (pLoc.fpSize == k4ByteSize) ? PTY_f32 : PTY_f64; + } else { + if (CGOptions::IsBigEndian()) { + loadSize = k8ByteSize; + numRegs = (typeSize <= k8ByteSize) ? kOneRegister : kTwoRegister; + regType = kRegTyInt; + retPty = PTY_u64; + } else { + loadSize = (typeSize <= k4ByteSize) ? k4ByteSize : k8ByteSize; + numRegs = (typeSize <= k8ByteSize) ? kOneRegister : kTwoRegister; + regType = kRegTyInt; + retPty = PTY_u32; + } + } + bool parmCopy = IsParamStructCopy(*sym); + for (uint32 i = 0; i < numRegs; i++) { + if (parmCopy) { + rhsmemopnd = &LoadStructCopyBase(*sym, + (offset + static_cast(i * (fpParm ? loadSize : k8ByteSize))), + static_cast(loadSize * kBitsPerByte)); + } else { + rhsmemopnd = &GetOrCreateMemOpnd(*sym, + (offset + static_cast(i * (fpParm ? loadSize : k8ByteSize))), + (loadSize * kBitsPerByte)); + } + result[i] = &CreateVirtualRegisterOperand(NewVReg(regType, loadSize)); + MOperator mop1 = PickLdInsn(loadSize * kBitsPerByte, retPty); + Insn &ld = GetCG()->BuildInstruction(mop1, *(result[i]), *rhsmemopnd); + GetCurBB()->AppendInsn(ld); + } + AArch64reg regs[kFourRegister]; + regs[0] = static_cast(pLoc.reg0); + regs[1] = static_cast(pLoc.reg1); + regs[2] = static_cast(pLoc.reg2); + regs[3] = static_cast(pLoc.reg3); + RegOperand *dest; + for (uint32 i = 0; i < numRegs; i++) { + AArch64reg preg; + MOperator mop2; + if (fpParm) { + preg = regs[i]; + mop2 = (loadSize == k4ByteSize) ? MOP_xvmovs : MOP_xvmovd; + } else { + preg = (i == 0 ? R0 : R1); + mop2 = (loadSize == k4ByteSize) ? MOP_wmovrr : MOP_xmovrr; + } + dest = &GetOrCreatePhysicalRegisterOperand(preg, (loadSize * kBitsPerByte), regType); + Insn &mov = GetCG()->BuildInstruction(mop2, *dest, *(result[i])); + GetCurBB()->AppendInsn(mov); + } + /* Create artificial dependency to extend the live range */ + for (uint32 i = 0; i < numRegs; i++) { + AArch64reg preg; + MOperator mop3; + if (fpParm) { + preg = regs[i]; + mop3 = MOP_pseudo_ret_float; + } else { + preg = (i == 0 ? R0 : R1); + mop3 = MOP_pseudo_ret_int; + } + dest = &GetOrCreatePhysicalRegisterOperand(preg, loadSize * kBitsPerByte, regType); + Insn &pseudo = GetCG()->BuildInstruction(mop3, *dest); + GetCurBB()->AppendInsn(pseudo); + } + return; + } else if (x->GetOpCode() == OP_iread) { + IreadNode *iread = static_cast(x); + RegOperand *rhsAddrOpnd = static_cast(HandleExpr(*iread, *iread->Opnd(0))); + rhsAddrOpnd = &LoadIntoRegister(*rhsAddrOpnd, iread->Opnd(0)->GetPrimType()); + MIRPtrType *ptrType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread->GetTyIdx())); + MIRType *mirType = static_cast(ptrType->GetPointedType()); + bool isRefField = false; + if (iread->GetFieldID() != 0) { + MIRStructType *structType = static_cast(mirType); + mirType = structType->GetFieldType(iread->GetFieldID()); + offset = static_cast(GetBecommon().GetFieldOffset(*structType, iread->GetFieldID()).first); + isRefField = GetBecommon().IsRefField(*structType, iread->GetFieldID()); + } + uint32 typeSize = GetBecommon().GetTypeSize(mirType->GetTypeIndex()); + /* generate move to regs. */ + RegOperand *result[kTwoRegister]; /* maximum 16 bytes, 2 registers */ + uint32 loadSize; + if (CGOptions::IsBigEndian()) { + loadSize = k8ByteSize; + } else { + loadSize = (typeSize <= k4ByteSize) ? k4ByteSize : k8ByteSize; + } + uint32 numRegs = (typeSize <= k8ByteSize) ? kOneRegister : kTwoRegister; + for (uint32 i = 0; i < numRegs; i++) { + OfstOperand *rhsOffOpnd = &GetOrCreateOfstOpnd(offset + i * loadSize, loadSize * kBitsPerByte); + Operand &rhsmemopnd = GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, loadSize * kBitsPerByte, + rhsAddrOpnd, nullptr, rhsOffOpnd, nullptr); + result[i] = &CreateVirtualRegisterOperand(NewVReg(kRegTyInt, loadSize)); + MOperator mop1 = PickLdInsn(loadSize * kBitsPerByte, PTY_u32); + Insn &ld = GetCG()->BuildInstruction(mop1, *(result[i]), rhsmemopnd); + ld.MarkAsAccessRefField(isRefField); + GetCurBB()->AppendInsn(ld); + } + RegOperand *dest; + for (uint32 i = 0; i < numRegs; i++) { + AArch64reg preg = (i == 0 ? R0 : R1); + dest = &GetOrCreatePhysicalRegisterOperand(preg, loadSize * kBitsPerByte, kRegTyInt); + Insn &mov = GetCG()->BuildInstruction(MOP_xmovrr, *dest, *(result[i])); + GetCurBB()->AppendInsn(mov); + } + /* Create artificial dependency to extend the live range */ + for (uint32 i = 0; i < numRegs; i++) { + AArch64reg preg = (i == 0 ? R0 : R1); + dest = &GetOrCreatePhysicalRegisterOperand(preg, loadSize * kBitsPerByte, kRegTyInt); + Insn &pseudo = cg->BuildInstruction(MOP_pseudo_ret_int, *dest); + GetCurBB()->AppendInsn(pseudo); + } + return; + } else { // dummy return of 0 inserted by front-end at absence of return + ASSERT(x->GetOpCode() == OP_constval, "SelectReturnSendOfStructInRegs: unexpected return operand"); + uint32 typeSize = GetPrimTypeSize(x->GetPrimType()); + RegOperand &dest = GetOrCreatePhysicalRegisterOperand(R0, typeSize * kBitsPerByte, kRegTyInt); + ImmOperand &src = CreateImmOperand(0, k16BitSize, false); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_xmovri32, dest, src)); + return; + } +} + Operand *AArch64CGFunc::SelectDread(const BaseNode &parent, DreadNode &expr) { MIRSymbol *symbol = GetFunction().GetLocalOrGlobalSymbol(expr.GetStIdx()); if (symbol->IsEhIndex()) { @@ -2916,31 +3175,50 @@ Operand *AArch64CGFunc::SelectIreadoff(const BaseNode &parent, IreadoffNode &ire return result; } -RegOperand *AArch64CGFunc::GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType) { - MemOperand *memOpnd; - RegOperand *rfp = &GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); - uint32 bitlen = byteSize * kBitsPerByte; - if (offset < 0) { - RegOperand *baseOpnd = &CreateRegisterOperandOfType(PTY_a64); - ImmOperand &immOpnd = CreateImmOperand(offset, k32BitSize, true); - Insn &addInsn = GetCG()->BuildInstruction(MOP_xaddrri12, *baseOpnd, *rfp, immOpnd); - GetCurBB()->AppendInsn(addInsn); - OfstOperand *offsetOpnd = &CreateOfstOpnd(0, k32BitSize); - memOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, bitlen, baseOpnd, - nullptr, offsetOpnd, nullptr); - } else { - OfstOperand *offsetOpnd = &CreateOfstOpnd(static_cast(static_cast(offset)), k32BitSize); - memOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, bitlen, rfp, - nullptr, offsetOpnd, nullptr); - } - memOpnd->SetStackMem(true); +RegOperand *AArch64CGFunc::GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType, + AArch64reg baseRegno) { + MemOperand *memOpnd = GenLmbcFpMemOperand(offset, byteSize, baseRegno); RegOperand *result = &GetOrCreateVirtualRegisterOperand(NewVReg(regType, byteSize)); - MOperator mOp = PickLdInsn(bitlen, primType); + MOperator mOp = PickLdInsn(byteSize * kBitsPerByte, primType); Insn &load = GetCG()->BuildInstruction(mOp, *result, *memOpnd); GetCurBB()->AppendInsn(load); return result; } +RegOperand *AArch64CGFunc::LmbcStructReturnLoad(int32 offset) { + RegOperand *result = nullptr; + MIRFunction &func = GetFunction(); + CHECK_FATAL(func.IsReturnStruct(), "LmbcStructReturnLoad: not struct return"); + MIRType *ty = func.GetReturnType(); + uint32 sz = GetBecommon().GetTypeSize(ty->GetTypeIndex()); + uint32 fpSize; + uint32 numFpRegs = FloatParamRegRequired(static_cast(ty), fpSize); + if (numFpRegs > 0) { + PrimType pType = (fpSize <= k4ByteSize) ? PTY_f32 : PTY_f64; + for (int32 i = (numFpRegs - kOneRegister); i > 0; --i) { + result = GenLmbcParamLoad(offset + (i * fpSize), fpSize, kRegTyFloat, pType); + AArch64reg regNo = static_cast(V0 + i); + RegOperand *reg = &GetOrCreatePhysicalRegisterOperand(regNo, fpSize * kBitsPerByte, kRegTyFloat); + SelectCopy(*reg, pType, *result, pType); + Insn &pseudo = GetCG()->BuildInstruction(MOP_pseudo_ret_float, *reg); + GetCurBB()->AppendInsn(pseudo); + } + result = GenLmbcParamLoad(offset, fpSize, kRegTyFloat, pType); + } else if (sz <= k4ByteSize) { + result = GenLmbcParamLoad(offset, k4ByteSize, kRegTyInt, PTY_u32); + } else if (sz <= k8ByteSize) { + result = GenLmbcParamLoad(offset, k8ByteSize, kRegTyInt, PTY_i64); + } else if (sz <= k16ByteSize) { + result = GenLmbcParamLoad(offset + k8ByteSize, k8ByteSize, kRegTyInt, PTY_i64); + RegOperand *r1 = &GetOrCreatePhysicalRegisterOperand(R1, k8ByteSize * kBitsPerByte, kRegTyInt); + SelectCopy(*r1, PTY_i64, *result, PTY_i64); + Insn &pseudo = GetCG()->BuildInstruction(MOP_pseudo_ret_int, *r1); + GetCurBB()->AppendInsn(pseudo); + result = GenLmbcParamLoad(offset, k8ByteSize, kRegTyInt, PTY_i64); + } + return result; +} + Operand *AArch64CGFunc::SelectIreadfpoff(const BaseNode &parent, IreadFPoffNode &ireadoff) { int32 offset = ireadoff.GetOffset(); PrimType primType = ireadoff.GetPrimType(); @@ -2951,19 +3229,32 @@ Operand *AArch64CGFunc::SelectIreadfpoff(const BaseNode &parent, IreadFPoffNode if (offset >= 0) { LmbcFormalParamInfo *info = GetLmbcFormalParamInfo(static_cast(offset)); if (info->GetPrimType() == PTY_agg) { - result = GenLmbcParamLoad(offset, bytelen, regty, primType); + if (info->IsOnStack()) { + result = GenLmbcParamLoad(info->GetOnStackOffset(), GetPrimTypeSize(PTY_a64), kRegTyInt, PTY_a64); + regno_t baseRegno = result->GetRegisterNumber(); + result = GenLmbcParamLoad(offset - info->GetOffset(), bytelen, regty, primType, (AArch64reg)baseRegno); + } else if (primType == PTY_agg) { + CHECK_FATAL(parent.GetOpCode() == OP_regassign, "SelectIreadfpoff of agg"); + result = LmbcStructReturnLoad(offset); + } else { + result = GenLmbcParamLoad(offset, bytelen, regty, primType); + } } else { CHECK_FATAL(primType == info->GetPrimType(), "Incorrect primtype"); CHECK_FATAL(offset == info->GetOffset(), "Incorrect offset"); - if (info->GetRegNO() == 0) { - /* TODO : follow lmbc sp offset for now */ + if (info->GetRegNO() == 0 || info->HasRegassign() == false) { result = GenLmbcParamLoad(offset, bytelen, regty, primType); } else { result = &GetOrCreatePhysicalRegisterOperand((AArch64reg)(info->GetRegNO()), bitlen, regty); } } } else { - result = GenLmbcParamLoad(offset, bytelen, regty, primType); + if (primType == PTY_agg) { + CHECK_FATAL(parent.GetOpCode() == OP_regassign, "SelectIreadfpoff of agg"); + result = LmbcStructReturnLoad(offset); + } else { + result = GenLmbcParamLoad(offset, bytelen, regty, primType); + } } return result; } @@ -5760,6 +6051,9 @@ Operand *AArch64CGFunc::SelectAlloca(UnaryNode &node, Operand &opnd0) { if (!CGOptions::IsArm64ilp32()) { ASSERT((node.GetPrimType() == PTY_a64), "wrong type"); } + if (GetCG()->IsLmbc()) { + SetHasVLAOrAlloca(true); + } PrimType stype = node.Opnd(0)->GetPrimType(); Operand *resOpnd = &opnd0; if (GetPrimTypeBitSize(stype) < GetPrimTypeBitSize(PTY_u64)) { @@ -5775,10 +6069,13 @@ Operand *AArch64CGFunc::SelectAlloca(UnaryNode &node, Operand &opnd0) { SelectShift(aliOp, aliOp, shifOpnd, kShiftLeft, PTY_u64); Operand &spOpnd = GetOrCreatePhysicalRegisterOperand(RSP, k64BitSize, kRegTyInt); SelectSub(spOpnd, spOpnd, aliOp, PTY_u64); - int64 argsToStkpassSize = GetMemlayout()->SizeOfArgsToStackPass(); - if (argsToStkpassSize > 0) { + int64 allocaOffset = GetMemlayout()->SizeOfArgsToStackPass(); + if (GetCG()->IsLmbc()) { + allocaOffset -= kDivide2 * k8ByteSize; + } + if (allocaOffset > 0) { RegOperand &resallo = CreateRegisterOperandOfType(PTY_u64); - SelectAdd(resallo, spOpnd, CreateImmOperand(argsToStkpassSize, k64BitSize, true), PTY_u64); + SelectAdd(resallo, spOpnd, CreateImmOperand(allocaOffset, k64BitSize, true), PTY_u64); return &resallo; } else { return &SelectCopy(spOpnd, PTY_u64, PTY_u64); @@ -6220,6 +6517,15 @@ void AArch64CGFunc::AssignLmbcFormalParams() { param->SetRegNO(0); } else { param->SetRegNO(intReg); + if (param->HasRegassign() == false) { + uint32 bytelen = GetPrimTypeSize(primType); + uint32 bitlen = bytelen * kBitsPerByte; + MemOperand *mOpnd = GenLmbcFpMemOperand(offset, bytelen); + RegOperand &src = GetOrCreatePhysicalRegisterOperand(AArch64reg(intReg), bitlen, kRegTyInt); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, src, *mOpnd); + GetCurBB()->AppendInsn(store); + } intReg++; } } else if (IsPrimitiveFloat(primType)) { @@ -6227,6 +6533,15 @@ void AArch64CGFunc::AssignLmbcFormalParams() { param->SetRegNO(0); } else { param->SetRegNO(fpReg); + if (param->HasRegassign() == false) { + uint32 bytelen = GetPrimTypeSize(primType); + uint32 bitlen = bytelen * kBitsPerByte; + MemOperand *mOpnd = GenLmbcFpMemOperand(offset, bytelen); + RegOperand &src = GetOrCreatePhysicalRegisterOperand(AArch64reg(fpReg), bitlen, kRegTyFloat); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, src, *mOpnd); + GetCurBB()->AppendInsn(store); + } fpReg++; } } else if (primType == PTY_agg) { @@ -6245,6 +6560,14 @@ void AArch64CGFunc::AssignLmbcFormalParams() { } else { param->SetRegNO(intReg); param->SetIsOnStack(); + param->SetOnStackOffset((intReg - R0 + fpReg - V0) * k8ByteSize); + uint32 bytelen = GetPrimTypeSize(PTY_a64); + uint32 bitlen = bytelen * kBitsPerByte; + MemOperand *mOpnd = GenLmbcFpMemOperand(param->GetOnStackOffset(), bytelen); + RegOperand &src = GetOrCreatePhysicalRegisterOperand(AArch64reg(intReg), bitlen, kRegTyInt); + MOperator mOp = PickStInsn(bitlen, PTY_a64); + Insn &store = GetCG()->BuildInstruction(mOp, src, *mOpnd); + GetCurBB()->AppendInsn(store); intReg++; } } else if (param->GetSize() <= k8ByteSize) { @@ -6290,7 +6613,6 @@ void AArch64CGFunc::AssignLmbcFormalParams() { Operand *memOpd = &CreateMemOpnd(RFP, offset + (i * rSize), rSize); GetCurBB()->AppendInsn(GetCG()->BuildInstruction( PickStInsn(rSize * kBitsPerByte, pType), dest, *memOpd)); - param->SetIsOnStack(); } } } else { @@ -6299,6 +6621,22 @@ void AArch64CGFunc::AssignLmbcFormalParams() { } } +void AArch64CGFunc::LmbcGenSaveSpForAlloca() { + if (GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc || HasVLAOrAlloca() == false) { + return; + } + Operand &spOpnd = GetOrCreatePhysicalRegisterOperand(RSP, k64BitSize, kRegTyInt); + RegOperand &spSaveOpnd = CreateVirtualRegisterOperand(NewVReg(kRegTyInt, kSizeOfPtr)); + Insn &save = GetCG()->BuildInstruction(MOP_xmovrr, spSaveOpnd, spOpnd); + GetFirstBB()->AppendInsn(save); + //save.SetFrameDef(true); + for (auto *retBB : GetExitBBsVec()) { + Insn &restore = GetCG()->BuildInstruction(MOP_xmovrr, spOpnd, spSaveOpnd); + retBB->AppendInsn(restore); + restore.SetFrameDef(true); + } +} + /* if offset < 0, allocation; otherwise, deallocation */ MemOperand &AArch64CGFunc::CreateCallFrameOperand(int32 offset, uint32 size) { MemOperand *memOpnd = CreateStackMemOpnd(RSP, offset, size); @@ -7584,6 +7922,10 @@ size_t AArch64CGFunc::SelectParmListGetStructReturnSize(StmtNode &naryNode) { CallNode &callNode = static_cast(naryNode); MIRFunction *callFunc = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callNode.GetPUIdx()); TyIdx retIdx = callFunc->GetReturnTyIdx(); + if (callFunc->IsFirstArgReturn()) { + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(callFunc->GetFormalDefVec()[0].formalTyIdx); + return GetBecommon().GetTypeSize(static_cast(ty)->GetPointedTyIdx()); + } size_t retSize = GetBecommon().GetTypeSize(retIdx.GetIdx()); if ((retSize == 0) && callFunc->IsReturnStruct()) { TyIdx tyIdx = callFunc->GetFuncRetStructTyIdx(); @@ -7600,6 +7942,14 @@ size_t AArch64CGFunc::SelectParmListGetStructReturnSize(StmtNode &naryNode) { return GetBecommon().GetTypeSize(sym->GetTyIdx().GetIdx()); } } + } else if (naryNode.GetOpCode() == OP_icallproto) { + IcallNode &icallProto = static_cast(naryNode); + MIRFuncType *funcTy = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallProto.GetRetTyIdx())); + if (funcTy->FirstArgReturn()) { + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcTy->GetNthParamType(0)); + return GetBecommon().GetTypeSize(static_cast(ty)->GetPointedTyIdx()); + } + return GetBecommon().GetTypeSize(funcTy->GetRetTyIdx()); } return 0; } @@ -7707,7 +8057,7 @@ void AArch64CGFunc::SelectParmListPreprocess(const StmtNode &naryNode, size_t st */ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bool isCallNative) { size_t i = 0; - if ((naryNode.GetOpCode() == OP_icall) || isCallNative) { + if (naryNode.GetOpCode() == OP_icall || naryNode.GetOpCode() == OP_icallproto || isCallNative) { i++; } std::set specialArgs; @@ -7734,8 +8084,11 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - auto *callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + MIRFunction *callee = nullptr; + if (dynamic_cast(&naryNode) != nullptr) { + auto calleePuIdx = static_cast(naryNode).GetPUIdx(); + callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } @@ -8257,7 +8610,18 @@ void AArch64CGFunc::SelectCall(CallNode &callNode) { ListOperand *srcOpnds = CreateListOpnd(*GetFuncScopeAllocator()); if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { - LmbcSelectParmList(srcOpnds, fn->IsFirstArgReturn()); + SetLmbcCallReturnType(nullptr); + bool largeStructRet = false; + if (fn->IsFirstArgReturn()) { + MIRPtrType *ptrTy = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(fn->GetFormalDefVec()[0].formalTyIdx)); + MIRType *sTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ptrTy->GetPointedTyIdx()); + largeStructRet = sTy->GetSize() > k16ByteSize; + SetLmbcCallReturnType(sTy); + } else { + MIRType *ty = fn->GetReturnType(); + SetLmbcCallReturnType(ty); + } + LmbcSelectParmList(srcOpnds, largeStructRet); } bool callNative = false; if ((fsym->GetName() == "MCC_CallFastNative") || (fsym->GetName() == "MCC_CallFastNativeExt") || @@ -8333,11 +8697,21 @@ void AArch64CGFunc::SelectCall(CallNode &callNode) { void AArch64CGFunc::SelectIcall(IcallNode &icallNode, Operand &srcOpnd) { ListOperand *srcOpnds = CreateListOpnd(*GetFuncScopeAllocator()); - if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { - LmbcSelectParmList(srcOpnds, false /*fType->GetRetAttrs().GetAttr(ATTR_firstarg_return)*/); - } else { +// if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { +// /* icallproto */ +// MIRType *retTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallNode.GetRetTyIdx()); +// MIRFuncType *funcTy = static_cast(retTy); +// bool largeStructRet = false; +// if (funcTy->FirstArgReturn()) { +// TyIdx idx = funcTy->GetNthParamType(0); +// MIRPtrType *ptrTy = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(idx)); +// MIRType *sTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ptrTy->GetPointedTyIdx()); +// largeStructRet = sTy->GetSize() > k16ByteSize; +// } +// LmbcSelectParmList(srcOpnds, largeStructRet); +// } else { SelectParmList(icallNode, *srcOpnds); - } +// } Operand *fptrOpnd = &srcOpnd; if (fptrOpnd->GetKind() != Operand::kOpdRegister) { @@ -8348,7 +8722,7 @@ void AArch64CGFunc::SelectIcall(IcallNode &icallNode, Operand &srcOpnd) { RegOperand *regOpnd = static_cast(fptrOpnd); Insn &callInsn = GetCG()->BuildInstruction(MOP_xblr, *regOpnd, *srcOpnds); - MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallNode.GetRetTyIdx()); + MIRType *retType = icallNode.GetCallReturnType(); if (retType != nullptr) { callInsn.SetRetSize(static_cast(retType->GetSize())); callInsn.SetIsCallReturnUnsigned(IsUnsignedInteger(retType->GetPrimType())); @@ -8461,9 +8835,18 @@ RegOperand &AArch64CGFunc::GetOrCreateSpecialRegisterOperand(PregIdx sregIdx, Pr case kSregFp: reg = RFP; break; - case kSregGp: - reg = RFP; - break; + case kSregGp: { + MIRSymbol *sym = GetCG()->GetGP(); + if (sym == nullptr) { + sym = GetFunction().GetSymTab()->CreateSymbol(kScopeLocal); + std::string strBuf("__file__local__GP"); + sym->SetNameStrIdx(GetMirModule().GetMIRBuilder()->GetOrCreateStringIndex(strBuf)); + GetCG()->SetGP(sym); + } + RegOperand &result = GetOrCreateVirtualRegisterOperand(NewVReg(kRegTyInt, k8ByteSize)); + SelectAddrof(result, CreateStImmOperand(*sym, 0, 0)); + return result; + } case kSregThrownval: { /* uses x0 == R0 */ ASSERT(uCatch.regNOCatch > 0, "regNOCatch should greater than 0."); if (Globals::GetInstance()->GetOptimLevel() == 0) { @@ -9200,6 +9583,9 @@ int32 AArch64CGFunc::GetBaseOffset(const SymbolAlloc &sa) { int32 baseOffset = symAlloc->GetOffset(); return baseOffset + sizeofFplr; } else if (sgKind == kMsSpillReg) { + if (GetCG()->IsLmbc()) { + return symAlloc->GetOffset() + memLayout->SizeOfArgsToStackPass(); + } int32 baseOffset = symAlloc->GetOffset() + memLayout->SizeOfArgsRegisterPassed() + memLayout->GetSizeOfLocals() + memLayout->GetSizeOfRefLocals(); return baseOffset + sizeofFplr; @@ -9774,16 +10160,21 @@ void AArch64CGFunc::GenCVaStartIntrin(RegOperand &opnd, uint32 stkSize) { Operand &stkOpnd = GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); /* __stack */ - ImmOperand *offsOpnd = &CreateImmOperand(0, k64BitSize, true, kUnAdjustVary); /* isvary reset StackFrameSize */ + ImmOperand *offsOpnd; + if (GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + offsOpnd = &CreateImmOperand(0, k64BitSize, true, kUnAdjustVary); /* isvary reset StackFrameSize */ + } else { + offsOpnd = &CreateImmOperand(0, k64BitSize, true); + } ImmOperand *offsOpnd2 = &CreateImmOperand(stkSize, k64BitSize, false); RegOperand &vReg = CreateVirtualRegisterOperand(NewVReg(kRegTyInt, GetPrimTypeSize(LOWERED_PTR_TYPE))); if (stkSize) { SelectAdd(vReg, *offsOpnd, *offsOpnd2, LOWERED_PTR_TYPE); SelectAdd(vReg, stkOpnd, vReg, LOWERED_PTR_TYPE); } else { - SelectAdd(vReg, stkOpnd, *offsOpnd, LOWERED_PTR_TYPE); + SelectAdd(vReg, stkOpnd, *offsOpnd, LOWERED_PTR_TYPE); /* stack pointer */ } - OfstOperand *offOpnd = &GetOrCreateOfstOpnd(0, k64BitSize); + OfstOperand *offOpnd = &GetOrCreateOfstOpnd(0, k64BitSize); /* va_list ptr */ /* mem operand in va_list struct (lhs) */ MemOperand *strOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, k64BitSize, &opnd, nullptr, offOpnd, static_cast(nullptr)); @@ -9858,13 +10249,19 @@ void AArch64CGFunc::SelectCVaStart(const IntrinsiccallNode &intrnNode) { AArch64CallConvImpl parmLocator(GetBecommon()); CCLocInfo pLoc; uint32 stkSize = 0; + uint32 inReg = 0; for (uint32 i = 0; i < GetFunction().GetFormalCount(); i++) { MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(GetFunction().GetNthParamTyIdx(i)); parmLocator.LocateNextParm(*ty, pLoc); if (pLoc.reg0 == kRinvalid) { /* on stack */ stkSize = static_cast(pLoc.memOffset + pLoc.memSize); + } else { + inReg++; } } + if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + stkSize += (inReg * k8ByteSize); + } if (CGOptions::IsArm64ilp32()) { stkSize = static_cast(RoundUp(stkSize, k8ByteSize)); } else { diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp index 17d0bcdde9..4acfbd9e96 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp @@ -40,8 +40,8 @@ constexpr uint8 insPairsNum = 5; PairMOperator extInsnPairTable[ExtTableSize][insPairsNum] = { /* {origMop, newMop} */ - {{MOP_wldrb, MOP_wldrb}, {MOP_undef, MOP_undef}, {MOP_undef, MOP_undef}, {MOP_undef, MOP_undef}, - {MOP_undef, MOP_undef}}, /* AND */ + {{MOP_wldrb, MOP_wldrb}, {MOP_wldrsh, MOP_wldrb}, {MOP_wldrh, MOP_wldrb}, {MOP_xldrsw, MOP_wldrb}, + {MOP_wldr, MOP_wldrb}}, /* AND */ {{MOP_wldrb, MOP_wldrsb}, {MOP_wldr, MOP_wldrsb}, {MOP_undef, MOP_undef}, {MOP_undef, MOP_undef}, {MOP_undef, MOP_undef}}, /* SXTB */ {{MOP_wldrh, MOP_wldrsh}, {MOP_wldrb, MOP_wldrb}, {MOP_wldrsb, MOP_wldrsb}, {MOP_wldrsh, MOP_wldrsh}, diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp index a58213245c..4184108a22 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp @@ -134,7 +134,7 @@ void AArch64MemLayout::LayoutVarargParams() { if (be.GetMIRModule().IsCModule() && func->GetAttr(FUNCATTR_varargs)) { for (uint32 i = 0; i < func->GetFormalCount(); i++) { if (i == 0) { - if (func->IsReturnStruct()) { + if (func->IsFirstArgReturn() && func->GetReturnType()->GetPrimType() != PTY_void) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (be.GetTypeSize(tyIdx.GetIdx()) <= k16ByteSize) { continue; @@ -198,7 +198,7 @@ void AArch64MemLayout::LayoutFormalParams() { * outparmsize - portion of frame size of current function used by call parameters */ segArgsStkPassed.SetSize(mirFunction->GetOutParmSize()); - segArgsRegPassed.SetSize(mirFunction->GetOutParmSize() + kTwoRegister * k8ByteSize); + segArgsRegPassed.SetSize(mirFunction->GetOutParmSize()); return; } @@ -210,7 +210,7 @@ void AArch64MemLayout::LayoutFormalParams() { AArch64SymbolAlloc *symLoc = memAllocator->GetMemPool()->New(); SetSymAllocInfo(stIndex, *symLoc); if (i == 0) { - if (mirFunction->IsReturnStruct()) { + if (mirFunction->IsFirstArgReturn()) { symLoc->SetMemSegment(GetSegArgsRegPassed()); symLoc->SetOffset(GetSegArgsRegPassed().GetSize()); TyIdx tyIdx = mirFunction->GetFuncRetStructTyIdx(); @@ -224,13 +224,13 @@ void AArch64MemLayout::LayoutFormalParams() { continue; } } - MIRType *ty = mirFunction->GetNthParamType(i); + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(mirFunction->GetFormalDefVec()[i].formalTyIdx); uint32 ptyIdx = ty->GetTypeIndex(); parmLocator.LocateNextParm(*ty, ploc, i == 0, mirFunction); if (ploc.reg0 != kRinvalid) { /* register */ symLoc->SetRegisters(static_cast(ploc.reg0), static_cast(ploc.reg1), static_cast(ploc.reg2), static_cast(ploc.reg3)); - if (mirFunction->GetNthParamAttr(i).GetAttr(ATTR_localrefvar)) { + if (mirFunction->GetFormalDefVec()[i].formalAttrs.GetAttr(ATTR_localrefvar)) { symLoc->SetMemSegment(segRefLocals); SetSegmentSize(*symLoc, segRefLocals, ptyIdx); } else if (!sym->IsPreg()) { @@ -272,7 +272,7 @@ void AArch64MemLayout::LayoutFormalParams() { } else { segArgsStkPassed.SetSize(static_cast(RoundUp(segArgsStkPassed.GetSize(), kSizeOfPtr))); } - if (mirFunction->GetNthParamAttr(i).GetAttr(ATTR_localrefvar)) { + if (mirFunction->GetFormalDefVec()[i].formalAttrs.GetAttr(ATTR_localrefvar)) { SetLocalRegLocInfo(sym->GetStIdx(), *symLoc); AArch64SymbolAlloc *symLoc1 = memAllocator->GetMemPool()->New(); symLoc1->SetMemSegment(segRefLocals); @@ -287,8 +287,8 @@ void AArch64MemLayout::LayoutFormalParams() { } void AArch64MemLayout::LayoutLocalVariables(std::vector &tempVar, std::vector &returnDelays) { - if (be.GetMIRModule().GetFlavor() == kFlavorLmbc && mirFunction->GetFormalCount() == 0) { - segLocals.SetSize(static_cast(mirFunction->GetFrameSize() - mirFunction->GetOutParmSize())); + if (be.GetMIRModule().GetFlavor() == kFlavorLmbc) { + segLocals.SetSize(mirFunction->GetFrameSize() - mirFunction->GetOutParmSize()); return; } @@ -372,7 +372,7 @@ void AArch64MemLayout::LayoutReturnRef(std::vector &returnDelays, segRefLocals.SetSize(segRefLocals.GetSize() + be.GetTypeSize(tyIdx)); } if (be.GetMIRModule().GetFlavor() == kFlavorLmbc) { - segArgsToStkPass.SetSize(mirFunction->GetOutParmSize()); + segArgsToStkPass.SetSize(mirFunction->GetOutParmSize() + kDivide2 * k8ByteSize); } else { segArgsToStkPass.SetSize(FindLargestActualArea(structCopySize)); } @@ -423,7 +423,7 @@ void AArch64MemLayout::LayoutActualParams() { * variables get assigned their respecitve storage, i.e. * CallFrameSize (discounting callee-saved and FP/LR) is known. */ - MIRType *ty = mirFunction->GetNthParamType(i); + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(mirFunction->GetFormalDefVec()[i].formalTyIdx); uint32 ptyIdx = ty->GetTypeIndex(); static_cast(cgFunc)->GetOrCreateMemOpnd(*sym, 0, be.GetTypeAlign(ptyIdx) * kBitsPerByte); } @@ -440,7 +440,7 @@ void AArch64MemLayout::LayoutStackFrame(int32 &structCopySize, int32 &maxParmSta */ if (CGOptions::IsArm64ilp32()) { segArgsRegPassed.SetSize(RoundUp(segArgsRegPassed.GetSize(), k8ByteSize)); - /* we do need this as SP has to be aligned at a 16-bytes bounardy */ + /* we do need this as SP has to be aligned at a 16-bytes bounardy */ segArgsStkPassed.SetSize(RoundUp(segArgsStkPassed.GetSize(), k8ByteSize + k8ByteSize)); } else { segArgsRegPassed.SetSize(RoundUp(segArgsRegPassed.GetSize(), kSizeOfPtr)); @@ -527,11 +527,13 @@ uint64 AArch64MemLayout::StackFrameSize() const { uint64 total = segArgsRegPassed.GetSize() + static_cast(cgFunc)->SizeOfCalleeSaved() + GetSizeOfRefLocals() + locals().GetSize() + GetSizeOfSpillReg(); - if (GetSizeOfGRSaveArea() > 0) { - total += RoundUp(GetSizeOfGRSaveArea(), kAarch64StackPtrAlignment); - } - if (GetSizeOfVRSaveArea() > 0) { - total += RoundUp(GetSizeOfVRSaveArea(), kAarch64StackPtrAlignment); + if (cgFunc->GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + if (GetSizeOfGRSaveArea() > 0) { + total += RoundUp(GetSizeOfGRSaveArea(), kAarch64StackPtrAlignment); + } + if (GetSizeOfVRSaveArea() > 0) { + total += RoundUp(GetSizeOfVRSaveArea(), kAarch64StackPtrAlignment); + } } /* diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp index eaa5726d43..7ef7190645 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp @@ -50,7 +50,7 @@ void AArch64FPLROffsetAdjustment::AdjustmentOffsetForOpnd(Insn &insn, AArch64CGF if (memBaseReg->GetRegisterNumber() == RFP) { RegOperand &newBaseOpnd = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(stackBaseReg, k64BitSize, kRegTyInt); MemOperand &newMemOpnd = aarchCGFunc.GetOrCreateMemOpnd( - MemOperand::kAddrModeBOi, memOpnd.GetSize(), &newBaseOpnd, memOpnd.GetIndexRegister(), + memOpnd.GetAddrMode(), memOpnd.GetSize(), &newBaseOpnd, memOpnd.GetIndexRegister(), memOpnd.GetOffsetImmediate(), memOpnd.GetSymbol()); insn.SetOperand(i, newMemOpnd); stackBaseOpnd = true; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp index 109cc5087a..4fd65cebdd 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp @@ -1118,6 +1118,9 @@ void AArch64GenProEpilog::AppendInstructionAllocateCallFrameDebug(AArch64reg reg ipoint = cgFunc.GetCurBB()->GetLastInsn(); cfiOffset = stackFrameSize; (void)InsertCFIDefCfaOffset(cfiOffset, *ipoint); + if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + argsToStkPassSize -= (kDivide2 * k8ByteSize); + } ipoint = &CreateAndAppendInstructionForAllocateCallFrame(argsToStkPassSize, reg0, reg1, rty); CHECK_FATAL(ipoint != nullptr, "ipoint should not be nullptr at this point"); cfiOffset = GetOffsetFromCFA(); @@ -1251,9 +1254,16 @@ void AArch64GenProEpilog::GeneratePushRegs() { CHECK_FATAL(*it == RLR, "The second callee saved reg is expected to be RLR"); ++it; - auto offset = static_cast((static_cast(cgFunc.GetMemlayout())->RealStackFrameSize() - - (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */)) - - cgFunc.GetMemlayout()->SizeOfArgsToStackPass()); + AArch64MemLayout *memLayout = static_cast(cgFunc.GetMemlayout()); + int32 offset; + if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + offset = static_cast(memLayout->RealStackFrameSize() - + aarchCGFunc.SizeOfCalleeSaved() - memLayout->GetSizeOfLocals()); + } else { + offset = static_cast(memLayout->RealStackFrameSize() - + (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */) - + memLayout->SizeOfArgsToStackPass()); + } if (cgFunc.GetCG()->IsStackProtectorStrong() || cgFunc.GetCG()->IsStackProtectorAll()) { offset -= kAarch64StackPtrAlignment; @@ -1313,10 +1323,19 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { size = kSizeOfPtr; } uint32 dataSizeBits = size * kBitsPerByte; - uint32 offset = static_cast(memlayout->GetGRSaveAreaBaseLoc()); - if (memlayout->GetSizeOfGRSaveArea() % kAarch64StackPtrAlignment) { - offset += size; /* End of area should be aligned. Hole between VR and GR area */ + uint32 offset; + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + offset = static_cast(memlayout->GetGRSaveAreaBaseLoc()); /* SP reference */ + if (memlayout->GetSizeOfGRSaveArea() % kAarch64StackPtrAlignment) { + offset += size; /* End of area should be aligned. Hole between VR and GR area */ + } + } else { + offset = -memlayout->GetSizeOfGRSaveArea(); /* FP reference */ + if (memlayout->GetSizeOfGRSaveArea() % kAarch64StackPtrAlignment) { + offset -= size; + } } + uint32 grSize = -offset; uint32 start_regno = k8BitSize - (memlayout->GetSizeOfGRSaveArea() / size); ASSERT(start_regno <= k8BitSize, "Incorrect starting GR regno for GR Save Area"); for (uint32 i = start_regno + static_cast(R0); i < static_cast(R8); i++) { @@ -1326,16 +1345,25 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { tmpOffset += 8U - (dataSizeBits >> 3); } } - Operand &stackloc = aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); + Operand *stackLoc; + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + stackLoc = &aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); + } else { + stackLoc = aarchCGFunc.GenLmbcFpMemOperand(offset, size); + } RegOperand ® = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(static_cast(i), k64BitSize, kRegTyInt); Insn &inst = - currCG->BuildInstruction(aarchCGFunc.PickStInsn(dataSizeBits, PTY_i64), reg, stackloc); + currCG->BuildInstruction(aarchCGFunc.PickStInsn(dataSizeBits, PTY_i64), reg, *stackLoc); cgFunc.GetCurBB()->AppendInsn(inst); offset += size; } if (!CGOptions::UseGeneralRegOnly()) { - offset = static_cast(memlayout->GetVRSaveAreaBaseLoc()); + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + offset = static_cast(memlayout->GetVRSaveAreaBaseLoc()); + } else { + offset = -(memlayout->GetSizeOfVRSaveArea() + grSize); + } start_regno = k8BitSize - (memlayout->GetSizeOfVRSaveArea() / (size * k2BitSize)); ASSERT(start_regno <= k8BitSize, "Incorrect starting GR regno for VR Save Area"); for (uint32 i = start_regno + static_cast(V0); i < static_cast(V8); i++) { @@ -1345,11 +1373,16 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { tmpOffset += 16U - (dataSizeBits >> 3); } } - Operand &stackloc = aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); + Operand *stackLoc; + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + stackLoc = &aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); + } else { + stackLoc = aarchCGFunc.GenLmbcFpMemOperand(offset, size); + } RegOperand ® = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(static_cast(i), k64BitSize, kRegTyFloat); Insn &inst = - currCG->BuildInstruction(aarchCGFunc.PickStInsn(dataSizeBits, PTY_f64), reg, stackloc); + currCG->BuildInstruction(aarchCGFunc.PickStInsn(dataSizeBits, PTY_f64), reg, *stackLoc); cgFunc.GetCurBB()->AppendInsn(inst); offset += (size * k2BitSize); } @@ -1389,7 +1422,8 @@ void AArch64GenProEpilog::GenerateProlog(BB &bb) { } // insert .loc for function - if (currCG->GetCGOptions().WithLoc()) { + if (currCG->GetCGOptions().WithLoc() && + (!currCG->GetMIRModule()->IsCModule() || currCG->GetMIRModule()->IsWithDbgInfo())) { MIRFunction *func = &cgFunc.GetFunction(); MIRSymbol *fSym = GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx()); if (currCG->GetCGOptions().WithSrc()) { @@ -1649,11 +1683,17 @@ void AArch64GenProEpilog::AppendInstructionDeallocateCallFrameDebug(AArch64reg r * ldp/stp's imm should be within -512 and 504; * if ldp's imm > 504, we fall back to the ldp-add version */ - if (cgFunc.HasVLAOrAlloca() || argsToStkPassSize == 0) { - stackFrameSize -= argsToStkPassSize; - if (stackFrameSize > kStpLdpImm64UpperBound) { + bool isLmbc = (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc); + if (cgFunc.HasVLAOrAlloca() || argsToStkPassSize == 0 || isLmbc) { + int lmbcOffset = 0; + if (isLmbc == false) { + stackFrameSize -= argsToStkPassSize; + } else { + lmbcOffset = argsToStkPassSize - (kDivide2 * k8ByteSize); + } + if (stackFrameSize > kStpLdpImm64UpperBound || isLmbc) { Operand *o2; - o2 = aarchCGFunc.CreateStackMemOpnd(RSP, 0, kSizeOfPtr * kBitsPerByte); + o2 = aarchCGFunc.CreateStackMemOpnd(RSP, (isLmbc ? lmbcOffset : 0), kSizeOfPtr * kBitsPerByte); Insn &deallocInsn = currCG->BuildInstruction(mOp, o0, o1, *o2); cgFunc.GetCurBB()->AppendInsn(deallocInsn); if (cgFunc.GenCfi()) { @@ -1728,9 +1768,16 @@ void AArch64GenProEpilog::GeneratePopRegs() { CHECK_FATAL(*it == RLR, "The second callee saved reg is expected to be RLR"); ++it; - int32 offset = static_cast((static_cast(cgFunc.GetMemlayout())->RealStackFrameSize() - - (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */)) - - cgFunc.GetMemlayout()->SizeOfArgsToStackPass()); + AArch64MemLayout *memLayout = static_cast(cgFunc.GetMemlayout()); + int32 offset; + if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + offset = static_cast(memLayout->RealStackFrameSize() - + aarchCGFunc.SizeOfCalleeSaved() - memLayout->GetSizeOfLocals()); + } else { + offset = static_cast(cgFunc.GetMemlayout())->RealStackFrameSize() - + (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */) - + memLayout->SizeOfArgsToStackPass(); + } if (cgFunc.GetCG()->IsStackProtectorStrong() || cgFunc.GetCG()->IsStackProtectorAll()) { offset -= kAarch64StackPtrAlignment; @@ -1821,7 +1868,7 @@ void AArch64GenProEpilog::GenerateEpilog(BB &bb) { Operand &spOpnd = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(RSP, k64BitSize, kRegTyInt); Operand &fpOpnd = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(stackBaseReg, k64BitSize, kRegTyInt); - if (cgFunc.HasVLAOrAlloca()) { + if (cgFunc.HasVLAOrAlloca() && cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { aarchCGFunc.SelectCopy(spOpnd, PTY_u64, fpOpnd, PTY_u64); } diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp index 433cc85754..5ca154b1aa 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp @@ -161,8 +161,7 @@ void AArch64ReachingDefinition::AddRetPseudoInsn(BB &bb) { Insn &retInsn = cgFunc->GetCG()->BuildInstruction(MOP_pseudo_ret_int, regOpnd); bb.AppendInsn(retInsn); pseudoInsns.emplace_back(&retInsn); - } else { - ASSERT(regNO == V0, "CG internal error. Return value should be R0 or V0."); + } else if (regNO == V0) { RegOperand ®Opnd = static_cast(cgFunc)->GetOrCreatePhysicalRegisterOperand(regNO, k64BitSize, kRegTyFloat); Insn &retInsn = cgFunc->GetCG()->BuildInstruction(MOP_pseudo_ret_float, regOpnd); diff --git a/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp b/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp index d2ae2c25c9..bf645c15cd 100644 --- a/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp +++ b/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp @@ -160,6 +160,7 @@ void RecursiveMarkUsedStaticSymbol(const BaseNode *baseNode) { break; } case OP_addrof: + case OP_addrofoff: case OP_dread: { const AddrofNode *dreadNode = static_cast(baseNode); MarkUsedStaticSymbol(dreadNode->GetStIdx()); diff --git a/src/mapleall/maple_be/src/cg/cgfunc.cpp b/src/mapleall/maple_be/src/cg/cgfunc.cpp index f7a706e43c..6900c49b28 100644 --- a/src/mapleall/maple_be/src/cg/cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/cgfunc.cpp @@ -1145,7 +1145,11 @@ void HandleReturn(StmtNode &stmt, CGFunc &cgFunc) { ASSERT(retNode.NumOpnds() <= 1, "NYI return nodes number > 1"); Operand *opnd = nullptr; if (retNode.NumOpnds() != 0) { - opnd = cgFunc.HandleExpr(retNode, *retNode.Opnd(0)); + if (!cgFunc.GetFunction().StructReturnedInRegs()) { + opnd = cgFunc.HandleExpr(retNode, *retNode.Opnd(0)); + } else { + cgFunc.SelectReturnSendOfStructInRegs(retNode.Opnd(0)); + } } cgFunc.SelectReturn(opnd); cgFunc.SetCurBBKind(BB::kBBReturn); @@ -1561,15 +1565,16 @@ void CGFunc::CreateLmbcFormalParamInfo() { PrimType primType; uint32 offset; uint32 typeSize; - MIRFunction &mirFunc = GetFunction(); - if (mirFunc.GetParamSize() > 0) { + MIRFunction &func = GetFunction(); + if (func.GetFormalCount() > 0) { + /* Whenever lmbc cannot delete call type info, the prototype is available */ uint32 stackOffset = 0; - for (size_t idx = 0; idx < mirFunc.GetParamSize(); ++idx) { - MIRSymbol *sym = mirFunc.GetFormal(idx); + for (size_t idx = 0; idx < func.GetFormalCount(); ++idx) { + MIRSymbol *sym = func.GetFormal(idx); MIRType *type; TyIdx tyIdx; if (sym) { - tyIdx = mirFunc.GetNthParamTyIdx(idx); + tyIdx = func.GetFormalDefVec()[idx].formalTyIdx; type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); } else { FormalDef vec = const_cast(GetBecommon().GetMIRModule().CurFunction())->GetFormalDefAt(idx); @@ -1616,6 +1621,9 @@ void CGFunc::CreateLmbcFormalParamInfo() { } IreadFPoffNode *ireadNode = static_cast(operand); primType = ireadNode->GetPrimType(); + if (ireadNode->GetOffset() < 0) { + continue; + } offset = static_cast(ireadNode->GetOffset()); typeSize = GetPrimTypeSize(primType); CHECK_FATAL((offset % k8ByteSize) == 0, ""); /* scalar only, no struct for now */ @@ -1627,6 +1635,31 @@ void CGFunc::CreateLmbcFormalParamInfo() { [] (LmbcFormalParamInfo *x, LmbcFormalParamInfo *y) { return x->GetOffset() < y->GetOffset(); } ); + + /* When a scalar param address is taken, its regassign is not in the 1st block */ + for (StmtNode *stmt = func.GetBody()->GetFirst(); stmt != nullptr; stmt = stmt->GetNext()) { + if (stmt == nullptr) { + break; + } + if (stmt->GetOpCode() == OP_label) { + continue; + } + if (stmt->GetOpCode() != OP_regassign) { + break; + } + RegassignNode *regAssignNode = static_cast(stmt); + BaseNode *operand = regAssignNode->Opnd(0); + if (operand->GetOpCode() != OP_ireadfpoff) { + break; + } + IreadFPoffNode *ireadNode = static_cast(operand); + if (ireadNode->GetOffset() < 0) { + continue; + } + LmbcFormalParamInfo *info = GetLmbcFormalParamInfo(ireadNode->GetOffset()); + info->SetHasRegassign(); + } + AssignLmbcFormalParams(); } @@ -1635,7 +1668,7 @@ void CGFunc::GenerateInstruction() { InitHandleStmtFactory(); StmtNode *secondStmt = HandleFirstStmt(); - CreateLmbcFormalParamInfo(); + //CreateLmbcFormalParamInfo(); /* First Pass: Creates the doubly-linked list of BBs (next,prev) */ volReleaseInsn = nullptr; unsigned lastSrcLoc = 0; @@ -2007,6 +2040,7 @@ void CGFunc::HandleFunction() { ASSERT(exitBBVec.size() <= 1, "there are more than one BB_return in func"); } ProcessExitBBVec(); + LmbcGenSaveSpForAlloca(); if (func.IsJava()) { GenerateCleanupCodeForExtEpilog(*cleanupBB); diff --git a/src/mapleall/maple_be/src/cg/emit.cpp b/src/mapleall/maple_be/src/cg/emit.cpp index cfe3ccfd7b..97bf901870 100644 --- a/src/mapleall/maple_be/src/cg/emit.cpp +++ b/src/mapleall/maple_be/src/cg/emit.cpp @@ -2170,6 +2170,11 @@ void Emitter::EmitGlobalVar(const MIRSymbol &globalVar) { } void Emitter::EmitGlobalVars(std::vector> &globalVars) { + if (GetCG()->IsLmbc() && GetCG()->GetGP() != nullptr) { + Emit(asmInfo->GetLocal()).Emit("\t").Emit(GetCG()->GetGP()->GetName()).Emit("\n"); + Emit(asmInfo->GetComm()).Emit("\t").Emit(GetCG()->GetGP()->GetName()); + Emit(", ").Emit(GetCG()->GetMIRModule()->GetGlobalMemSize()).Emit(", ").Emit("8\n"); + } /* load globalVars profile */ if (globalVars.empty()) { return; diff --git a/src/mapleall/maple_be/src/cg/memlayout.cpp b/src/mapleall/maple_be/src/cg/memlayout.cpp index 57e45e8a2d..1b636207c6 100644 --- a/src/mapleall/maple_be/src/cg/memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/memlayout.cpp @@ -38,7 +38,7 @@ uint32 MemLayout::FindLargestActualArea(int32 &aggCopySize) { uint32 maxCopyStackSize = 0; // Size of aggregate param stack copy requirement for (; stmt != nullptr; stmt = stmt->GetNext()) { Opcode opCode = stmt->GetOpCode(); - if (opCode < OP_call || opCode > OP_xintrinsiccallassigned) { + if ((opCode < OP_call || opCode > OP_xintrinsiccallassigned) && opCode != OP_icallproto) { continue; } if (opCode == OP_intrinsiccallwithtypeassigned || opCode == OP_intrinsiccallwithtype || @@ -54,9 +54,9 @@ uint32 MemLayout::FindLargestActualArea(int32 &aggCopySize) { * if the following check fails, most likely dex has invoke-custom etc * that is not supported yet */ - DCHECK((opCode == OP_call || opCode == OP_icall), "Not lowered to call or icall?"); + DCHECK((opCode == OP_call || opCode == OP_icall || opCode == OP_icallproto), "Not lowered to call or icall?"); int32 copySize; - uint32 size = ComputeStackSpaceRequirementForCall(*stmt, copySize, opCode == OP_icall); + uint32 size = ComputeStackSpaceRequirementForCall(*stmt, copySize, opCode == OP_icall || opCode == OP_icallproto); if (size > maxParamStackSize) { maxParamStackSize = size; } diff --git a/src/mapleall/maple_ir/include/bin_mpl_export.h b/src/mapleall/maple_ir/include/bin_mpl_export.h index 09952cb8c7..f12bec7081 100644 --- a/src/mapleall/maple_ir/include/bin_mpl_export.h +++ b/src/mapleall/maple_ir/include/bin_mpl_export.h @@ -67,8 +67,8 @@ enum : uint8 { kBinEaCgStart = 41, kBinEaStart = 42, kBinNodeBlock = 43, - kBinOpStatement = 44, - kBinOpExpression = 45, +//kBinOpStatement = 44, +//kBinOpExpression = 45, kBinReturnvals = 46, kBinTypeTabStart = 47, kBinSymStart = 48, @@ -76,14 +76,14 @@ enum : uint8 { kBinFuncIdInfoStart = 50, kBinFormalStart = 51, kBinPreg = 52, - kBinPregStart = 53, - kBinLabelStart = 54, + kBinSpecialReg = 53, + kBinLabel = 54, kBinTypenameStart = 55, kBinHeaderStart = 56, kBinAliasMapStart = 57, - kBinKindTypeViaTypename = 58, - kBinKindSymViaSymname = 59, - kBinKindFuncViaSymname = 60, +//kBinKindTypeViaTypename = 58, +//kBinKindSymViaSymname = 59, +//kBinKindFuncViaSymname = 60, kBinFunctionBodyStart = 61, kBinFormalWordsTypeTagged = 62, kBinFormalWordsRefCounted = 63, @@ -103,8 +103,7 @@ class BinaryMplExport { void Export(const std::string &fname, std::unordered_set *dumpFuncSet); void WriteNum(int64 x); void Write(uint8 b); - void OutputType(TyIdx tyIdx, bool canUseTypename); - void OutputTypeViaTypeName(TyIdx tidx) { OutputType(tidx, true); } + void OutputType(TyIdx tyIdx); void WriteFunctionBodyField(uint64 contentIdx, std::unordered_set *dumpFuncSet); void OutputConst(MIRConst *c); void OutputConstBase(const MIRConst &c); @@ -133,12 +132,11 @@ class BinaryMplExport { void OutputInfoVector(const MIRInfoVector &infoVector, const MapleVector &infoVectorIsString); void OutputFuncIdInfo(MIRFunction *func); void OutputLocalSymbol(MIRSymbol *sym); - void OutputLocalSymTab(const MIRFunction *func); - void OutputPregTab(const MIRFunction *func); - void OutputLabelTab(const MIRFunction *func); + void OutputPreg(MIRPreg *preg); + void OutputLabel(LabelIdx lidx); void OutputLocalTypeNameTab(const MIRTypeNameTable *tyNameTab); void OutputFormalsStIdx(MIRFunction *func); - void OutputFuncViaSymName(PUIdx puIdx); + void OutputFuncViaSym(PUIdx puIdx); void OutputExpression(BaseNode *e); void OutputBaseNode(const BaseNode *b); void OutputReturnValues(const CallReturnVector *retv); @@ -182,6 +180,7 @@ class BinaryMplExport { void ExpandFourBuffSize(); MIRModule &mod; + MIRFunction *curFunc = nullptr; size_t bufI = 0; std::vector buf; std::unordered_map gStrMark; @@ -190,6 +189,9 @@ class BinaryMplExport { std::unordered_map uStrMark; std::unordered_map symMark; std::unordered_map typMark; + std::unordered_map localSymMark; + std::unordered_map localPregMark; + std::unordered_map labelMark; friend class UpdateMplt; std::unordered_map callInfoMark; std::map *func2SEMap = nullptr; diff --git a/src/mapleall/maple_ir/include/bin_mpl_import.h b/src/mapleall/maple_ir/include/bin_mpl_import.h index 3697654872..ee7f909f9b 100644 --- a/src/mapleall/maple_ir/include/bin_mpl_import.h +++ b/src/mapleall/maple_ir/include/bin_mpl_import.h @@ -126,15 +126,14 @@ class BinaryMplImport { void ImportInfoVector(MIRInfoVector &infoVector, MapleVector &infoVectorIsString); void ImportLocalTypeNameTable(MIRTypeNameTable *typeNameTab); void ImportFuncIdInfo(MIRFunction *func); - void ImportLocalSymbol(MIRFunction *func); - void ImportLocalSymTab(MIRFunction *func); - void ImportPregTab(const MIRFunction *func); - void ImportLabelTab(MIRFunction *func); + MIRSymbol *ImportLocalSymbol(MIRFunction *func); + PregIdx ImportPreg(MIRFunction *func); + LabelIdx ImportLabel(MIRFunction *func); void ImportFormalsStIdx(MIRFunction *func); void ImportAliasMap(MIRFunction *func); void ImportSrcPos(SrcPosition &pos); void ImportBaseNode(Opcode &o, PrimType &typ); - PUIdx ImportFuncViaSymName(); + PUIdx ImportFuncViaSym(MIRFunction *func); BaseNode *ImportExpression(MIRFunction *func); void ImportReturnValues(MIRFunction *func, CallReturnVector *retv); BlockNode *ImportBlockNode(MIRFunction *fn); @@ -162,6 +161,9 @@ class BinaryMplImport { std::vector typTab; std::vector funcTab; std::vector symTab; + std::vector localSymTab; + std::vector localPregTab; + std::vector localLabelTab; std::vector callInfoTab; std::vector eaCgTab; std::vector methodSymbols; diff --git a/src/mapleall/maple_ir/include/ir_safe_cast_traits.def b/src/mapleall/maple_ir/include/ir_safe_cast_traits.def index 1439b49d57..14ed1a367b 100644 --- a/src/mapleall/maple_ir/include/ir_safe_cast_traits.def +++ b/src/mapleall/maple_ir/include/ir_safe_cast_traits.def @@ -224,7 +224,9 @@ REGISTER_SAFE_CAST(CallNode, from.GetOpCode() == OP_call || from.GetOpCode() == OP_virtualicallassigned || instance_of(from)); REGISTER_SAFE_CAST(IcallNode, from.GetOpCode() == OP_icall || - from.GetOpCode() == OP_icallassigned); + from.GetOpCode() == OP_icallassigned || + from.GetOpCode() == OP_icallproto || + from.GetOpCode() == OP_icallprotoassigned); REGISTER_SAFE_CAST(IntrinsiccallNode, from.GetOpCode() == OP_intrinsiccall || from.GetOpCode() == OP_intrinsiccallwithtype || from.GetOpCode() == OP_xintrinsiccall || diff --git a/src/mapleall/maple_ir/include/keywords.def b/src/mapleall/maple_ir/include/keywords.def index eddff2f80a..51a603eafa 100644 --- a/src/mapleall/maple_ir/include/keywords.def +++ b/src/mapleall/maple_ir/include/keywords.def @@ -55,7 +55,6 @@ // per-function declaration keywords KEYWORD(framesize) KEYWORD(upformalsize) - KEYWORD(outparmsize) KEYWORD(moduleid) KEYWORD(funcsize) KEYWORD(funcid) diff --git a/src/mapleall/maple_ir/include/mir_builder.h b/src/mapleall/maple_ir/include/mir_builder.h index 5c38b7da10..9f3a5455bc 100755 --- a/src/mapleall/maple_ir/include/mir_builder.h +++ b/src/mapleall/maple_ir/include/mir_builder.h @@ -262,6 +262,8 @@ class MIRBuilder { IcallNode *CreateStmtIcall(const MapleVector &args); IcallNode *CreateStmtIcallAssigned(const MapleVector &args, const MIRSymbol &ret); + IcallNode *CreateStmtIcallproto(const MapleVector &args); + IcallNode *CreateStmtIcallprotoAssigned(const MapleVector &args, const MIRSymbol &ret); // For Call, VirtualCall, SuperclassCall, InterfaceCall IntrinsiccallNode *CreateStmtIntrinsicCall(MIRIntrinsicID idx, const MapleVector &arguments, TyIdx tyIdx = TyIdx()); diff --git a/src/mapleall/maple_ir/include/mir_function.h b/src/mapleall/maple_ir/include/mir_function.h index b3a4a5e4f8..96fdab5cea 100644 --- a/src/mapleall/maple_ir/include/mir_function.h +++ b/src/mapleall/maple_ir/include/mir_function.h @@ -830,24 +830,24 @@ class MIRFunction { callTimes = times; } - uint16 GetFrameSize() const { + uint32 GetFrameSize() const { return frameSize; } - void SetFrameSize(uint16 size) { + void SetFrameSize(uint32 size) { frameSize = size; } - uint16 GetUpFormalSize() const { + uint32 GetUpFormalSize() const { return upFormalSize; } - void SetUpFormalSize(uint16 size) { + void SetUpFormalSize(uint32 size) { upFormalSize = size; } - uint16 GetOutParmSize() const { + uint32 GetOutParmSize() const { return outParmSize; } - void SetOutParmSize(uint16 size) { + void SetOutParmSize(uint32 size) { outParmSize = size; } @@ -1298,9 +1298,9 @@ class MIRFunction { bool isDirty = false; bool fromMpltInline = false; // Whether this function is imported from mplt_inline file or not. uint8_t layoutType = kLayoutUnused; - uint16 frameSize = 0; - uint16 upFormalSize = 0; - uint16 outParmSize = 0; + uint32 frameSize = 0; + uint32 upFormalSize = 0; + uint32 outParmSize = 0; uint16 moduleID = 0; uint32 funcSize = 0; // size of code in words uint32 tempCount = 0; diff --git a/src/mapleall/maple_ir/include/mir_lower.h b/src/mapleall/maple_ir/include/mir_lower.h index 332a6de89f..be479f65a6 100644 --- a/src/mapleall/maple_ir/include/mir_lower.h +++ b/src/mapleall/maple_ir/include/mir_lower.h @@ -86,6 +86,7 @@ class MIRLower { ForeachelemNode *ExpandArrayMrtForeachelemBlock(ForeachelemNode &node); BlockNode *ExpandArrayMrtBlock(BlockNode &block); void AddArrayMrtMpl(BaseNode &exp, BlockNode &newblk); + MIRFuncType *FuncTypeFromFuncPtrExpr(BaseNode *x); void SetLowerME() { lowerPhase |= kShiftLowerMe; } diff --git a/src/mapleall/maple_ir/include/mir_nodes.h b/src/mapleall/maple_ir/include/mir_nodes.h index 7864fd412b..3e5524df39 100755 --- a/src/mapleall/maple_ir/include/mir_nodes.h +++ b/src/mapleall/maple_ir/include/mir_nodes.h @@ -3304,7 +3304,7 @@ class CallNode : public NaryStmtNode { CallReturnVector returnValues; }; -// icall and icallproto +// icall, icallassigned, icallproto and icallprotoassigned class IcallNode : public NaryStmtNode { public: IcallNode(MapleAllocator &allocator, Opcode o) diff --git a/src/mapleall/maple_ir/include/mir_parser.h b/src/mapleall/maple_ir/include/mir_parser.h index 10d1dd028a..b49370d0ff 100755 --- a/src/mapleall/maple_ir/include/mir_parser.h +++ b/src/mapleall/maple_ir/include/mir_parser.h @@ -134,6 +134,7 @@ class MIRParser { bool ParseStmtIcall(StmtNodePtr&); bool ParseStmtIcallassigned(StmtNodePtr&); bool ParseStmtIcallproto(StmtNodePtr&); + bool ParseStmtIcallprotoassigned(StmtNodePtr&); bool ParseStmtIntrinsiccall(StmtNodePtr&, bool isAssigned); bool ParseStmtIntrinsiccall(StmtNodePtr&); bool ParseStmtIntrinsiccallassigned(StmtNodePtr&); @@ -291,7 +292,6 @@ class MIRParser { bool ParseStmtBlockForType(); bool ParseStmtBlockForFrameSize(); bool ParseStmtBlockForUpformalSize(); - bool ParseStmtBlockForOutParmSize(); bool ParseStmtBlockForModuleID(); bool ParseStmtBlockForFuncSize(); bool ParseStmtBlockForFuncID(); diff --git a/src/mapleall/maple_ir/include/mir_symbol.h b/src/mapleall/maple_ir/include/mir_symbol.h index 0d1d127dbe..357242d0e2 100644 --- a/src/mapleall/maple_ir/include/mir_symbol.h +++ b/src/mapleall/maple_ir/include/mir_symbol.h @@ -484,12 +484,11 @@ class MIRSymbol { return false; } switch (storageClass) { - case kScFormal: case kScAuto: return true; case kScPstatic: case kScFstatic: - return value.konst == nullptr; + return value.konst == nullptr && !hasPotentialAssignment; default: return false; } @@ -638,7 +637,8 @@ class MIRLabelTable { LabelIdx CreateLabel() { LabelIdx labelIdx = labelTable.size(); - labelTable.push_back(GStrIdx(0)); // insert dummy global string index for anonymous label + GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(std::to_string(labelIdx)); + labelTable.push_back(strIdx); return labelIdx; } diff --git a/src/mapleall/maple_ir/include/mir_type.h b/src/mapleall/maple_ir/include/mir_type.h index c5245d568c..197e7d3ca2 100644 --- a/src/mapleall/maple_ir/include/mir_type.h +++ b/src/mapleall/maple_ir/include/mir_type.h @@ -1189,14 +1189,6 @@ class MIRStructType : public MIRType { isImported = flag; } - bool IsUsed() const { - return isUsed; - } - - void SetIsUsed(bool flag) { - isUsed = flag; - } - bool IsCPlusPlus() const { return isCPlusPlus; } @@ -1368,7 +1360,6 @@ class MIRStructType : public MIRType { vTableMethods.clear(); iTableMethods.clear(); isImported = false; - isUsed = false; hasVolatileField = false; hasVolatileFieldSet = false; } @@ -1471,7 +1462,6 @@ class MIRStructType : public MIRType { // implementation functions, For interfaces, they are abstact functions. // Weak indicates the actual definition is in another module. bool isImported = false; - bool isUsed = false; bool isCPlusPlus = false; // empty struct in C++ has size 1 byte mutable bool hasVolatileField = false; // for caching computed value mutable bool hasVolatileFieldSet = false; // if true, just read hasVolatileField; @@ -1928,11 +1918,19 @@ class MIRFuncType : public MIRType { } bool IsVarargs() const { - return isVarArgs; + return funcAttrs.GetAttr(FUNCATTR_varargs); } - void SetVarArgs(bool flag) { - isVarArgs = flag; + void SetVarArgs() { + funcAttrs.SetAttr(FUNCATTR_varargs); + } + + bool FirstArgReturn() const { + return funcAttrs.GetAttr(FUNCATTR_firstarg_return); + } + + void SetFirstArgReturn() { + funcAttrs.SetAttr(FUNCATTR_firstarg_return); } const TypeAttrs &GetRetAttrs() const { @@ -1960,7 +1958,8 @@ class MIRFuncType : public MIRType { std::vector paramTypeList; std::vector paramAttrsList; TypeAttrs retAttrs; - bool isVarArgs = false; + public: + FuncAttrs funcAttrs; }; class MIRTypeByName : public MIRType { diff --git a/src/mapleall/maple_ir/include/opcode_info.h b/src/mapleall/maple_ir/include/opcode_info.h index 814f15b2f2..5a82646b11 100644 --- a/src/mapleall/maple_ir/include/opcode_info.h +++ b/src/mapleall/maple_ir/include/opcode_info.h @@ -117,6 +117,7 @@ class OpcodeTable { bool IsICall(Opcode o) const { ASSERT(o < OP_last, "invalid opcode"); return o == OP_icall || o == OP_icallassigned || + o == OP_icallproto || o == OP_icallprotoassigned || o == OP_virtualicall || o == OP_virtualicallassigned || o == OP_interfaceicall || o == OP_interfaceicallassigned; } diff --git a/src/mapleall/maple_ir/include/opcodes.def b/src/mapleall/maple_ir/include/opcodes.def index 34cfb51c8d..0e842141ed 100755 --- a/src/mapleall/maple_ir/include/opcodes.def +++ b/src/mapleall/maple_ir/include/opcodes.def @@ -221,3 +221,4 @@ OPCODE(iassignspoff, IassignFPoffNode, OPCODEISSTMT, 8) OPCODE(blkassignoff, BlkassignoffNode, OPCODEISSTMT, 8) OPCODE(icallproto, IcallNode, (OPCODEISSTMT | OPCODEISVARSIZE | OPCODEHASSSAUSE | OPCODEHASSSADEF | OPCODEISCALL), 8) + OPCODE(icallprotoassigned, IcallNode, (OPCODEISSTMT | OPCODEISVARSIZE | OPCODEHASSSAUSE | OPCODEHASSSADEF | OPCODEISCALL | OPCODEISCALLASSIGNED), 8) diff --git a/src/mapleall/maple_ir/include/opcodes.h b/src/mapleall/maple_ir/include/opcodes.h index ea4ed2c1c9..b9f5e0f8c5 100644 --- a/src/mapleall/maple_ir/include/opcodes.h +++ b/src/mapleall/maple_ir/include/opcodes.h @@ -50,7 +50,7 @@ inline constexpr bool IsCallAssigned(Opcode code) { code == OP_virtualicallassigned || code == OP_superclasscallassigned || code == OP_interfacecallassigned || code == OP_interfaceicallassigned || code == OP_customcallassigned || code == OP_polymorphiccallassigned || - code == OP_icallassigned || code == OP_intrinsiccallassigned || + code == OP_icallassigned || code == OP_icallprotoassigned || code == OP_intrinsiccallassigned || code == OP_xintrinsiccallassigned || code == OP_intrinsiccallwithtypeassigned); } @@ -113,6 +113,8 @@ constexpr bool IsStmtMustRequire(Opcode opcode) { case OP_polymorphiccallassigned: case OP_icall: case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: case OP_intrinsiccall: case OP_xintrinsiccall: case OP_intrinsiccallassigned: diff --git a/src/mapleall/maple_ir/src/bin_func_export.cpp b/src/mapleall/maple_ir/src/bin_func_export.cpp index 263ef34c80..6815c8151d 100644 --- a/src/mapleall/maple_ir/src/bin_func_export.cpp +++ b/src/mapleall/maple_ir/src/bin_func_export.cpp @@ -24,6 +24,10 @@ using namespace std; namespace maple { void BinaryMplExport::OutputInfoVector(const MIRInfoVector &infoVector, const MapleVector &infoVectorIsString) { + if (!mod.IsWithDbgInfo()) { + Write(0); + return; + } WriteNum(infoVector.size()); for (uint32 i = 0; i < infoVector.size(); i++) { OutputStr(infoVector[i].first); @@ -41,99 +45,73 @@ void BinaryMplExport::OutputFuncIdInfo(MIRFunction *func) { WriteNum(func->GetPuidxOrigin()); // the funcid OutputInfoVector(func->GetInfoVector(), func->InfoIsString()); if (mod.GetFlavor() == kFlavorLmbc) { - WriteNum(func->GetUpFormalSize()); WriteNum(func->GetFrameSize()); - WriteNum(func->GetOutParmSize()); } - WriteNum(~kBinFuncIdInfoStart); } void BinaryMplExport::OutputBaseNode(const BaseNode *b) { - WriteNum(b->GetOpCode()); - WriteNum(b->GetPrimType()); + Write(static_cast(b->GetOpCode())); + Write(static_cast(b->GetPrimType())); } void BinaryMplExport::OutputLocalSymbol(MIRSymbol *sym) { - if (sym == nullptr) { - WriteNum(0); + std::unordered_map::iterator it = localSymMark.find(sym); + if (it != localSymMark.end()) { + WriteNum(-(it->second)); return; } + WriteNum(kBinSymbol); - WriteNum(sym->GetStIndex()); // preserve original st index OutputStr(sym->GetNameStrIdx()); WriteNum(sym->GetSKind()); WriteNum(sym->GetStorageClass()); + size_t mark = localSymMark.size(); + localSymMark[sym] = mark; OutputTypeAttrs(sym->GetAttrs()); WriteNum(static_cast(sym->GetIsTmp())); if (sym->GetSKind() == kStVar || sym->GetSKind() == kStFunc) { OutputSrcPos(sym->GetSrcPosition()); } - OutputTypeViaTypeName(sym->GetTyIdx()); + OutputType(sym->GetTyIdx()); if (sym->GetSKind() == kStPreg) { - WriteNum(sym->GetPreg()->GetPregNo()); + OutputPreg(sym->GetPreg()); } else if (sym->GetSKind() == kStConst || sym->GetSKind() == kStVar) { OutputConst(sym->GetKonst()); } else if (sym->GetSKind() == kStFunc) { - OutputFuncViaSymName(sym->GetFunction()->GetPuidx()); - OutputTypeViaTypeName(sym->GetTyIdx()); + OutputFuncViaSym(sym->GetFunction()->GetPuidx()); } else { CHECK_FATAL(false, "should not used"); } } -void BinaryMplExport::OutputLocalSymTab(const MIRFunction *func) { - WriteNum(kBinSymStart); - uint64 outsymSizeIdx = buf.size(); - ExpandFourBuffSize(); /// size of OutSym - int32 size = 0; - - for (uint32 i = 1; i < func->GetSymTab()->GetSymbolTableSize(); i++) { - MIRSymbol *s = func->GetSymTab()->GetSymbolFromStIdx(i); - ASSERT(s != nullptr, "null ptr check"); - if (s->IsDeleted()) { - OutputLocalSymbol(nullptr); - } else { - OutputLocalSymbol(s); - } - size++; +void BinaryMplExport::OutputPreg(MIRPreg *preg) { + if (preg->GetPregNo() < 0) { + WriteNum(kBinSpecialReg); + Write(-preg->GetPregNo()); + return; } - - Fixup(outsymSizeIdx, size); - WriteNum(~kBinSymStart); -} - -void BinaryMplExport::OutputPregTab(const MIRFunction *func) { - WriteNum(kBinPregStart); - uint64 outRegSizeIdx = buf.size(); - ExpandFourBuffSize(); /// size of OutReg - int32 size = 0; - - for (uint32 i = 1; i < func->GetPregTab()->Size(); ++i) { - MIRPreg *mirpreg = func->GetPregTab()->PregFromPregIdx(static_cast(i)); - if (mirpreg == nullptr) { - WriteNum(0); - size++; - continue; - } - WriteNum(kBinPreg); - WriteNum(mirpreg->GetPregNo()); - TyIdx tyIdx = (mirpreg->GetMIRType() == nullptr) ? TyIdx(0) : mirpreg->GetMIRType()->GetTypeIndex(); - OutputTypeViaTypeName(tyIdx); - WriteNum(mirpreg->GetPrimType()); - size++; + std::unordered_map::iterator it = localPregMark.find(preg); + if (it != localPregMark.end()) { + WriteNum(-(it->second)); + return; } - Fixup(outRegSizeIdx, size); - WriteNum(~kBinPregStart); + WriteNum(kBinPreg); + Write(static_cast(preg->GetPrimType())); + size_t mark = localPregMark.size(); + localPregMark[preg] = mark; } -void BinaryMplExport::OutputLabelTab(const MIRFunction *func) { - WriteNum(kBinLabelStart); - WriteNum(static_cast(func->GetLabelTab()->Size()-1)); // entry 0 is skipped - for (uint32 i = 1; i < func->GetLabelTab()->Size(); i++) { - OutputStr(func->GetLabelTab()->GetLabelTable()[i]); +void BinaryMplExport::OutputLabel(LabelIdx lidx) { + std::unordered_map::iterator it = labelMark.find(lidx); + if (it != labelMark.end()) { + WriteNum(-(it->second)); + return; } - WriteNum(~kBinLabelStart); + + WriteNum(kBinLabel); + size_t mark = labelMark.size(); + labelMark[lidx] = mark; } void BinaryMplExport::OutputLocalTypeNameTab(const MIRTypeNameTable *typeNameTab) { @@ -141,18 +119,16 @@ void BinaryMplExport::OutputLocalTypeNameTab(const MIRTypeNameTable *typeNameTab WriteNum(static_cast(typeNameTab->Size())); for (std::pair it : typeNameTab->GetGStrIdxToTyIdxMap()) { OutputStr(it.first); - OutputTypeViaTypeName(it.second); + OutputType(it.second); } - WriteNum(~kBinTypenameStart); } void BinaryMplExport::OutputFormalsStIdx(MIRFunction *func) { WriteNum(kBinFormalStart); WriteNum(func->GetFormalDefVec().size()); for (FormalDef formalDef : func->GetFormalDefVec()) { - WriteNum(formalDef.formalSym->GetStIndex()); + OutputLocalSymbol(formalDef.formalSym); } - WriteNum(~kBinFormalStart); } void BinaryMplExport::OutputAliasMap(MapleMap &aliasVarMap) { @@ -161,21 +137,18 @@ void BinaryMplExport::OutputAliasMap(MapleMap &aliasVarMa for (std::pair it : aliasVarMap) { OutputStr(it.first); OutputStr(it.second.memPoolStrIdx); - OutputTypeViaTypeName(it.second.tyIdx); + OutputType(it.second.tyIdx); OutputStr(it.second.sigStrIdx); } - WriteNum(~kBinAliasMapStart); } -void BinaryMplExport::OutputFuncViaSymName(PUIdx puIdx) { +void BinaryMplExport::OutputFuncViaSym(PUIdx puIdx) { MIRFunction *func = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx()); - WriteNum(kBinKindFuncViaSymname); - OutputStr(funcSt->GetNameStrIdx()); + OutputSymbol(funcSt); } void BinaryMplExport::OutputExpression(BaseNode *e) { - WriteNum(kBinOpExpression); OutputBaseNode(e); switch (e->GetOpCode()) { // leaf @@ -191,17 +164,17 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { } case OP_addroflabel: { AddroflabelNode *lNode = static_cast(e); - WriteNum(lNode->GetOffset()); + OutputLabel(lNode->GetOffset()); return; } case OP_addroffunc: { AddroffuncNode *addrNode = static_cast(e); - OutputFuncViaSymName(addrNode->GetPUIdx()); + OutputFuncViaSym(addrNode->GetPUIdx()); return; } case OP_sizeoftype: { SizeoftypeNode *sot = static_cast(e); - OutputTypeViaTypeName(sot->GetTyIdx()); + OutputType(sot->GetTyIdx()); return; } case OP_addrof: @@ -220,24 +193,23 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { } WriteNum(stIdx.Scope()); if (stIdx.Islocal()) { - WriteNum(stIdx.Idx()); // preserve original st index + OutputLocalSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx)); } else { - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(stIdx.Idx()); - WriteNum(kBinKindSymViaSymname); - OutputStr(sym->GetNameStrIdx()); + OutputSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx)); } return; } case OP_regread: { RegreadNode *regreadNode = static_cast(e); - WriteNum(regreadNode->GetRegIdx()); + MIRPreg *preg = curFunc->GetPregTab()->PregFromPregIdx(regreadNode->GetRegIdx()); + OutputPreg(preg); return; } case OP_gcmalloc: case OP_gcpermalloc: case OP_stackmalloc: { GCMallocNode *gcNode = static_cast(e); - OutputTypeViaTypeName(gcNode->GetTyIdx()); + OutputType(gcNode->GetTyIdx()); return; } // unary @@ -246,18 +218,18 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { case OP_floor: case OP_trunc: { TypeCvtNode *typecvtNode = static_cast(e); - WriteNum(typecvtNode->FromType()); + Write(static_cast(typecvtNode->FromType())); break; } case OP_retype: { RetypeNode *retypeNode = static_cast(e); - OutputTypeViaTypeName(retypeNode->GetTyIdx()); + OutputType(retypeNode->GetTyIdx()); break; } case OP_iread: case OP_iaddrof: { IreadNode *irNode = static_cast(e); - OutputTypeViaTypeName(irNode->GetTyIdx()); + OutputType(irNode->GetTyIdx()); WriteNum(irNode->GetFieldID()); break; } @@ -275,20 +247,20 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { case OP_zext: case OP_extractbits: { ExtractbitsNode *extNode = static_cast(e); - WriteNum(extNode->GetBitsOffset()); - WriteNum(extNode->GetBitsSize()); + Write(extNode->GetBitsOffset()); + Write(extNode->GetBitsSize()); break; } case OP_depositbits: { DepositbitsNode *dbNode = static_cast(e); - WriteNum(dbNode->GetBitsOffset()); - WriteNum(dbNode->GetBitsSize()); + Write(dbNode->GetBitsOffset()); + Write(dbNode->GetBitsSize()); break; } case OP_gcmallocjarray: case OP_gcpermallocjarray: { JarrayMallocNode *gcNode = static_cast(e); - OutputTypeViaTypeName(gcNode->GetTyIdx()); + OutputType(gcNode->GetTyIdx()); break; } // binary @@ -321,13 +293,13 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { case OP_cmpl: case OP_cmp: { CompareNode *cmpNode = static_cast(e); - WriteNum(cmpNode->GetOpndType()); + Write(static_cast(cmpNode->GetOpndType())); break; } case OP_resolveinterfacefunc: case OP_resolvevirtualfunc: { ResolveFuncNode *rsNode = static_cast(e); - OutputFuncViaSymName(rsNode->GetPuIdx()); + OutputFuncViaSym(rsNode->GetPuIdx()); break; } // ternary @@ -337,8 +309,8 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { // nary case OP_array: { ArrayNode *arrNode = static_cast(e); - OutputTypeViaTypeName(arrNode->GetTyIdx()); - WriteNum(static_cast(arrNode->GetBoundsCheck())); + OutputType(arrNode->GetTyIdx()); + Write(static_cast(arrNode->GetBoundsCheck())); WriteNum(static_cast(arrNode->NumOpnds())); break; } @@ -351,7 +323,7 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { case OP_intrinsicopwithtype: { IntrinsicopNode *intrnNode = static_cast(e); WriteNum(intrnNode->GetIntrinsic()); - OutputTypeViaTypeName(intrnNode->GetTyIdx()); + OutputType(intrnNode->GetTyIdx()); WriteNum(static_cast(intrnNode->NumOpnds())); break; } @@ -366,6 +338,9 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { static SrcPosition lastOutputSrcPosition; void BinaryMplExport::OutputSrcPos(const SrcPosition &pos) { + if (!mod.IsWithDbgInfo()) { + return; + } if (pos.FileNum() == 0 || pos.LineNum() == 0) { // error case, so output 0 WriteNum(lastOutputSrcPosition.RawData()); WriteNum(lastOutputSrcPosition.LineNum()); @@ -380,9 +355,15 @@ void BinaryMplExport::OutputReturnValues(const CallReturnVector *retv) { WriteNum(kBinReturnvals); WriteNum(static_cast(retv->size())); for (uint32 i = 0; i < retv->size(); i++) { - WriteNum((*retv)[i].first.Idx()); - WriteNum((*retv)[i].second.GetFieldID()); - WriteNum((*retv)[i].second.GetPregIdx()); + RegFieldPair rfp = (*retv)[i].second; + if (rfp.IsReg()) { + MIRPreg *preg = curFunc->GetPregTab()->PregFromPregIdx(rfp.GetPregIdx()); + OutputPreg(preg); + } else { + WriteNum(0); + WriteNum((rfp.GetFieldID())); + OutputLocalSymbol(curFunc->GetLocalOrGlobalSymbol((*retv)[i].first)); + } } } @@ -398,7 +379,6 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { ExpandFourBuffSize(); // place holder, Fixup later for (StmtNode *s = block->GetFirst(); s; s = s->GetNext()) { bool doneWithOpnds = false; - WriteNum(kBinOpStatement); OutputSrcPos(s->GetSrcPos()); WriteNum(s->GetOpCode()); switch (s->GetOpCode()) { @@ -417,36 +397,35 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { } WriteNum(stIdx.Scope()); if (stIdx.Islocal()) { - WriteNum(stIdx.Idx()); // preserve original st index + OutputLocalSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx)); } else { - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(stIdx.Idx()); - WriteNum(kBinKindSymViaSymname); - OutputStr(sym->GetNameStrIdx()); + OutputSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx)); } break; } case OP_regassign: { RegassignNode *rass = static_cast(s); - WriteNum(rass->GetPrimType()); - WriteNum(rass->GetRegIdx()); + Write(static_cast(rass->GetPrimType())); + MIRPreg *preg = curFunc->GetPregTab()->PregFromPregIdx(rass->GetRegIdx()); + OutputPreg(preg); break; } case OP_iassign: { IassignNode *iass = static_cast(s); - OutputTypeViaTypeName(iass->GetTyIdx()); + OutputType(iass->GetTyIdx()); WriteNum(iass->GetFieldID()); break; } case OP_iassignoff: { IassignoffNode *iassoff = static_cast(s); - WriteNum(iassoff->GetPrimType()); + Write(static_cast(iassoff->GetPrimType())); WriteNum(iassoff->GetOffset()); break; } case OP_iassignspoff: case OP_iassignfpoff: { IassignFPoffNode *iassfpoff = static_cast(s); - WriteNum(iassfpoff->GetPrimType()); + Write(static_cast(iassfpoff->GetPrimType())); WriteNum(iassfpoff->GetOffset()); break; } @@ -466,9 +445,9 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { case OP_customcall: case OP_polymorphiccall: { CallNode *callnode = static_cast(s); - OutputFuncViaSymName(callnode->GetPUIdx()); + OutputFuncViaSym(callnode->GetPUIdx()); if (s->GetOpCode() == OP_polymorphiccall) { - OutputTypeViaTypeName(static_cast(callnode)->GetTyIdx()); + OutputType(static_cast(callnode)->GetTyIdx()); } WriteNum(static_cast(s->NumOpnds())); break; @@ -481,15 +460,15 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { case OP_interfaceicallassigned: case OP_customcallassigned: { CallNode *callnode = static_cast(s); - OutputFuncViaSymName(callnode->GetPUIdx()); + OutputFuncViaSym(callnode->GetPUIdx()); OutputReturnValues(&callnode->GetReturnVec()); WriteNum(static_cast(s->NumOpnds())); break; } case OP_polymorphiccallassigned: { CallNode *callnode = static_cast(s); - OutputFuncViaSymName(callnode->GetPUIdx()); - OutputTypeViaTypeName(callnode->GetTyIdx()); + OutputFuncViaSym(callnode->GetPUIdx()); + OutputType(callnode->GetTyIdx()); OutputReturnValues(&callnode->GetReturnVec()); WriteNum(static_cast(s->NumOpnds())); break; @@ -497,13 +476,14 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { case OP_icallproto: case OP_icall: { IcallNode *icallnode = static_cast(s); - OutputTypeViaTypeName(icallnode->GetRetTyIdx()); + OutputType(icallnode->GetRetTyIdx()); WriteNum(static_cast(s->NumOpnds())); break; } + case OP_icallprotoassigned: case OP_icallassigned: { IcallNode *icallnode = static_cast(s); - OutputTypeViaTypeName(icallnode->GetRetTyIdx()); + OutputType(icallnode->GetRetTyIdx()); OutputReturnValues(&icallnode->GetReturnVec()); WriteNum(static_cast(s->NumOpnds())); break; @@ -526,14 +506,14 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { case OP_intrinsiccallwithtype: { IntrinsiccallNode *intrnNode = static_cast(s); WriteNum(intrnNode->GetIntrinsic()); - OutputTypeViaTypeName(intrnNode->GetTyIdx()); + OutputType(intrnNode->GetTyIdx()); WriteNum(static_cast(s->NumOpnds())); break; } case OP_intrinsiccallwithtypeassigned: { IntrinsiccallNode *intrnNode = static_cast(s); WriteNum(intrnNode->GetIntrinsic()); - OutputTypeViaTypeName(intrnNode->GetTyIdx()); + OutputType(intrnNode->GetTyIdx()); OutputReturnValues(&intrnNode->GetReturnVec()); WriteNum(static_cast(s->NumOpnds())); break; @@ -568,28 +548,28 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { } case OP_label: { LabelNode *lNode = static_cast(s); - WriteNum(lNode->GetLabelIdx()); + OutputLabel(lNode->GetLabelIdx()); break; } case OP_goto: case OP_gosub: { GotoNode *gtoNode = static_cast(s); - WriteNum(gtoNode->GetOffset()); + OutputLabel(gtoNode->GetOffset()); break; } case OP_brfalse: case OP_brtrue: { CondGotoNode *cgotoNode = static_cast(s); - WriteNum(cgotoNode->GetOffset()); + OutputLabel(cgotoNode->GetOffset()); break; } case OP_switch: { SwitchNode *swNode = static_cast(s); - WriteNum(swNode->GetDefaultLabel()); + OutputLabel(swNode->GetDefaultLabel()); WriteNum(static_cast(swNode->GetSwitchTable().size())); for (CasePair cpair : swNode->GetSwitchTable()) { WriteNum(cpair.first); - WriteNum(cpair.second); + OutputLabel(cpair.second); } break; } @@ -599,14 +579,14 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { WriteNum(static_cast(rgoto->GetRangeGotoTable().size())); for (SmallCasePair cpair : rgoto->GetRangeGotoTable()) { WriteNum(cpair.first); - WriteNum(cpair.second); + OutputLabel(cpair.second); } break; } case OP_jstry: { JsTryNode *tryNode = static_cast(s); - WriteNum(tryNode->GetCatchOffset()); - WriteNum(tryNode->GetFinallyOffset()); + OutputLabel(tryNode->GetCatchOffset()); + OutputLabel(tryNode->GetFinallyOffset()); break; } case OP_cpptry: @@ -614,7 +594,7 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { TryNode *tryNode = static_cast(s); WriteNum(static_cast(tryNode->GetOffsetsCount())); for (LabelIdx lidx : tryNode->GetOffsets()) { - WriteNum(lidx); + OutputLabel(lidx); } break; } @@ -622,7 +602,7 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { CatchNode *catchNode = static_cast(s); WriteNum(static_cast(catchNode->GetExceptionTyIdxVec().size())); for (TyIdx tidx : catchNode->GetExceptionTyIdxVec()) { - OutputTypeViaTypeName(tidx); + OutputType(tidx); } break; } @@ -679,7 +659,7 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { count = asmNode->gotoLabels.size(); WriteNum(static_cast(count)); for (size_t i = 0; i < count; ++i) { - WriteNum(asmNode->gotoLabels[i]); + OutputLabel(asmNode->gotoLabels[i]); } // the inputs WriteNum(asmNode->NumOpnds()); @@ -714,6 +694,7 @@ void BinaryMplExport::WriteFunctionBodyField(uint64 contentIdx, std::unordered_s if (not2mplt) { for (MIRFunction *func : GetMIRModule().GetFunctionList()) { + curFunc = func; if (func->GetAttr(FUNCATTR_optimized)) { continue; } @@ -734,12 +715,15 @@ void BinaryMplExport::WriteFunctionBodyField(uint64 contentIdx, std::unordered_s continue; } } + localSymMark.clear(); + localSymMark[nullptr] = 0; + localPregMark.clear(); + localPregMark[nullptr] = 0; + labelMark.clear(); + labelMark[0] = 0; OutputFunction(func->GetPuidx()); CHECK_FATAL(func->GetBody() != nullptr, "WriteFunctionBodyField: no function body"); OutputFuncIdInfo(func); - OutputPregTab(func); - OutputLocalSymTab(func); - OutputLabelTab(func); OutputLocalTypeNameTab(func->GetTypeNameTab()); OutputFormalsStIdx(func); if (mod.GetFlavor() < kMmpl) { @@ -753,7 +737,6 @@ void BinaryMplExport::WriteFunctionBodyField(uint64 contentIdx, std::unordered_s Fixup(totalSizeIdx, static_cast(buf.size() - totalSizeIdx)); Fixup(outFunctionBodySizeIdx, size); - WriteNum(~kBinFunctionBodyStart); return; } } // namespace maple diff --git a/src/mapleall/maple_ir/src/bin_func_import.cpp b/src/mapleall/maple_ir/src/bin_func_import.cpp index 959784554b..b23b6895f4 100644 --- a/src/mapleall/maple_ir/src/bin_func_import.cpp +++ b/src/mapleall/maple_ir/src/bin_func_import.cpp @@ -44,29 +44,27 @@ void BinaryMplImport::ImportFuncIdInfo(MIRFunction *func) { func->SetPuidxOrigin(static_cast(ReadNum())); ImportInfoVector(func->GetInfoVector(), func->InfoIsString()); if (mod.GetFlavor() == kFlavorLmbc) { - func->SetUpFormalSize(static_cast(ReadNum())); func->SetFrameSize(static_cast(ReadNum())); - func->SetOutParmSize(static_cast(ReadNum())); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinFuncIdInfoStart, "pattern mismatch in ImportFuncIdInfo()"); } void BinaryMplImport::ImportBaseNode(Opcode &o, PrimType &typ) { - o = (Opcode)ReadNum(); - typ = (PrimType)ReadNum(); + o = (Opcode)Read(); + typ = (PrimType)Read(); } -void BinaryMplImport::ImportLocalSymbol(MIRFunction *func) { +MIRSymbol *BinaryMplImport::ImportLocalSymbol(MIRFunction *func) { int64 tag = ReadNum(); if (tag == 0) { - func->GetSymTab()->PushNullSymbol(); - return; + return nullptr; } + if (tag < 0) { + CHECK_FATAL(static_cast(-tag) < localSymTab.size(), "index out of bounds"); + return localSymTab.at(-tag); + } CHECK_FATAL(tag == kBinSymbol, "expecting kBinSymbol in ImportLocalSymbol()"); - auto indx = static_cast(ReadNum()); - CHECK_FATAL(indx == func->GetSymTab()->GetSymbolTableSize(), "inconsistant local stIdx"); MIRSymbol *sym = func->GetSymTab()->CreateSymbol(kScopeLocal); + localSymTab.push_back(sym); sym->SetNameStrIdx(ImportStr()); (void)func->GetSymTab()->AddToStringSymbolMap(*sym); sym->SetSKind((MIRSymKind)ReadNum()); @@ -78,66 +76,52 @@ void BinaryMplImport::ImportLocalSymbol(MIRFunction *func) { } sym->SetTyIdx(ImportType()); if (sym->GetSKind() == kStPreg) { - auto thepregno = static_cast(ReadNum()); - MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx()); - PregIdx pregidx = func->GetPregTab()->EnterPregNo(thepregno, mirType->GetPrimType(), mirType); - MIRPregTable *pregTab = func->GetPregTab(); - MIRPreg *preg = pregTab->PregFromPregIdx(pregidx); - preg->SetPrimType(mirType->GetPrimType()); + PregIdx pregidx = ImportPreg(func); + MIRPreg *preg = func->GetPregTab()->PregFromPregIdx(pregidx); sym->SetPreg(preg); } else if (sym->GetSKind() == kStConst || sym->GetSKind() == kStVar) { sym->SetKonst(ImportConst(func)); } else if (sym->GetSKind() == kStFunc) { - PUIdx puIdx = ImportFuncViaSymName(); - TyIdx tyIdx = ImportType(); - sym->SetTyIdx(tyIdx); + PUIdx puIdx = ImportFuncViaSym(func); sym->SetFunction(GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx)); } + return sym; } -void BinaryMplImport::ImportLocalSymTab(MIRFunction *func) { +PregIdx BinaryMplImport::ImportPreg(MIRFunction *func) { int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinSymStart, "kBinSymStart expected in ImportLocalSymTab()"); - int32 size = ReadInt(); - for (int64 i = 0; i < size; ++i) { - ImportLocalSymbol(func); + if (tag == 0) { + return 0; } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinSymStart, "pattern mismatch in ImportLocalSymTab()"); -} - -void BinaryMplImport::ImportPregTab(const MIRFunction *func) { - int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinPregStart, "kBinPregStart expected in ImportPregTab()"); - int32 size = ReadInt(); - for (int64 i = 0; i < size; ++i) { - int64 nextTag = ReadNum(); - if (nextTag == 0) { - func->GetPregTab()->GetPregTable().push_back(nullptr); - continue; - } - CHECK_FATAL(nextTag == kBinPreg, "expecting kBinPreg in ImportPregTab()"); - auto pregNo = static_cast(ReadNum()); - TyIdx tyIdx = ImportType(); - MIRType *ty = (tyIdx == 0) ? nullptr : GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); - PrimType primType = (PrimType)ReadNum(); - CHECK_FATAL(ty == nullptr || primType == ty->GetPrimType(), "ImportPregTab: inconsistent primitive type"); - (void)func->GetPregTab()->EnterPregNo(pregNo, primType, ty); + if (tag == kBinSpecialReg) { + return -Read(); + } + if (tag < 0) { + CHECK_FATAL(static_cast(-tag) < localPregTab.size(), "index out of bounds"); + return localPregTab.at(-tag); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinPregStart, "pattern mismatch in ImportPregTab()"); + CHECK_FATAL(tag == kBinPreg, "expecting kBinPreg in ImportPreg()"); + + PrimType primType = (PrimType)Read(); + PregIdx pidx = func->GetPregTab()->CreatePreg(primType); + localPregTab.push_back(pidx); + return pidx; } -void BinaryMplImport::ImportLabelTab(MIRFunction *func) { +LabelIdx BinaryMplImport::ImportLabel(MIRFunction *func) { int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinLabelStart, "kBinLabelStart expected in ImportLabelTab()"); - int64 size = ReadNum(); - for (int64 i = 0; i < size; ++i) { - GStrIdx gStrIdx = ImportStr(); - (void)func->GetLabelTab()->AddLabel(gStrIdx); + if (tag == 0) { + return 0; + } + if (tag < 0) { + CHECK_FATAL(static_cast(-tag) < localLabelTab.size(), "index out of bounds"); + return localLabelTab.at(-tag); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinLabelStart, "pattern mismatch in ImportLabelTab()"); + CHECK_FATAL(tag == kBinLabel, "kBinLabel expected in ImportLabel()"); + + LabelIdx lidx = func->GetLabelTab()->CreateLabel(); + localLabelTab.push_back(lidx); + return lidx; } void BinaryMplImport::ImportLocalTypeNameTable(MIRTypeNameTable *typeNameTab) { @@ -149,8 +133,6 @@ void BinaryMplImport::ImportLocalTypeNameTable(MIRTypeNameTable *typeNameTab) { TyIdx tyIdx = ImportType(); typeNameTab->SetGStrIdxToTyIdx(strIdx, tyIdx); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinTypenameStart, "pattern mismatch in ImportTypenametab()"); } void BinaryMplImport::ImportFormalsStIdx(MIRFunction *func) { @@ -158,11 +140,8 @@ void BinaryMplImport::ImportFormalsStIdx(MIRFunction *func) { CHECK_FATAL(tag == kBinFormalStart, "kBinFormalStart expected in ImportFormalsStIdx()"); auto size = ReadNum(); for (int64 i = 0; i < size; ++i) { - uint32 indx = static_cast(ReadNum()); - func->GetFormalDefVec()[static_cast(i)].formalSym = func->GetSymTab()->GetSymbolFromStIdx(indx); + func->GetFormalDefVec()[static_cast(i)].formalSym = ImportLocalSymbol(func); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinFormalStart, "pattern mismatch in ImportFormalsStIdx()"); } void BinaryMplImport::ImportAliasMap(MIRFunction *func) { @@ -177,23 +156,15 @@ void BinaryMplImport::ImportAliasMap(MIRFunction *func) { (void)ImportStr(); // not assigning to mimic parser func->GetAliasVarMap()[strIdx] = aliasvars; } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinAliasMapStart, "pattern mismatch in ImportAliasMap()"); } -PUIdx BinaryMplImport::ImportFuncViaSymName() { - int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinKindFuncViaSymname, "kBinKindFuncViaSymname expected"); - GStrIdx strIdx = ImportStr(); - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx); - ASSERT(sym != nullptr, "null ptr check"); - MIRFunction *func = sym->GetFunction(); - return func->GetPuidx(); +PUIdx BinaryMplImport::ImportFuncViaSym(MIRFunction *func) { + MIRSymbol *sym = InSymbol(func); + MIRFunction *f = sym->GetFunction(); + return f->GetPuidx(); } BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { - int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinOpExpression, "kBinOpExpression expected"); Opcode op; PrimType typ; ImportBaseNode(op, typ); @@ -213,13 +184,15 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { } case OP_addroflabel: { AddroflabelNode *alabNode = mod.CurFuncCodeMemPool()->New(); - alabNode->SetOffset(static_cast(ReadNum())); + alabNode->SetOffset(ImportLabel(func)); alabNode->SetPrimType(typ); (void)func->GetLabelTab()->addrTakenLabels.insert(alabNode->GetOffset()); return alabNode; } case OP_addroffunc: { - PUIdx puIdx = ImportFuncViaSymName(); + PUIdx puIdx = ImportFuncViaSym(func); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFuncTable()[puIdx]; + f->GetFuncSymbol()->SetAppearsInCode(true); AddroffuncNode *addrNode = mod.CurFuncCodeMemPool()->New(typ, puIdx); return addrNode; } @@ -235,19 +208,18 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { int32 num = static_cast(ReadNum()); StIdx stIdx; stIdx.SetScope(static_cast(ReadNum())); + MIRSymbol *sym = nullptr; if (stIdx.Islocal()) { - stIdx.SetIdx(static_cast(ReadNum())); + sym = ImportLocalSymbol(func); + CHECK_FATAL(sym != nullptr, "null ptr check"); } else { - int32 stag = static_cast(ReadNum()); - CHECK_FATAL(stag == kBinKindSymViaSymname, "kBinKindSymViaSymname expected"); - GStrIdx strIdx = ImportStr(); - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx); - ASSERT(sym != nullptr, "null ptr check"); + sym = InSymbol(func); + CHECK_FATAL(sym != nullptr, "null ptr check"); if (op == OP_addrof) { sym->SetHasPotentialAssignment(); } - stIdx.SetIdx(sym->GetStIdx().Idx()); } + stIdx.SetIdx(sym->GetStIdx().Idx()); if (op == OP_addrof || op == OP_dread) { AddrofNode *drNode = mod.CurFuncCodeMemPool()->New(op); drNode->SetPrimType(typ); @@ -264,7 +236,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { } case OP_regread: { RegreadNode *regreadNode = mod.CurFuncCodeMemPool()->New(); - regreadNode->SetRegIdx(static_cast(ReadNum())); + regreadNode->SetRegIdx(ImportPreg(func)); regreadNode->SetPrimType(typ); return regreadNode; } @@ -293,7 +265,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_floor: case OP_trunc: { TypeCvtNode *typecvtNode = mod.CurFuncCodeMemPool()->New(op, typ); - typecvtNode->SetFromType((PrimType)ReadNum()); + typecvtNode->SetFromType((PrimType)Read()); typecvtNode->SetOpnd(ImportExpression(func), 0); return typecvtNode; } @@ -326,15 +298,15 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_zext: case OP_extractbits: { ExtractbitsNode *extNode = mod.CurFuncCodeMemPool()->New(op, typ); - extNode->SetBitsOffset(static_cast(ReadNum())); - extNode->SetBitsSize(static_cast(ReadNum())); + extNode->SetBitsOffset(Read()); + extNode->SetBitsSize(Read()); extNode->SetOpnd(ImportExpression(func), 0); return extNode; } case OP_depositbits: { DepositbitsNode *dbNode = mod.CurFuncCodeMemPool()->New(op, typ); - dbNode->SetBitsOffset(static_cast(ReadNum())); - dbNode->SetBitsSize(static_cast(ReadNum())); + dbNode->SetBitsOffset(ReadNum()); + dbNode->SetBitsSize(ReadNum()); dbNode->SetOpnd(ImportExpression(func), 0); dbNode->SetOpnd(ImportExpression(func), 1); return dbNode; @@ -379,7 +351,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_cmpl: case OP_cmp: { CompareNode *cmpNode = mod.CurFuncCodeMemPool()->New(op, typ); - cmpNode->SetOpndType((PrimType)ReadNum()); + cmpNode->SetOpndType((PrimType)Read()); cmpNode->SetOpnd(ImportExpression(func), 0); cmpNode->SetOpnd(ImportExpression(func), 1); return cmpNode; @@ -387,7 +359,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_resolveinterfacefunc: case OP_resolvevirtualfunc: { ResolveFuncNode *rsNode = mod.CurFuncCodeMemPool()->New(op, typ); - rsNode->SetPUIdx(ImportFuncViaSymName()); + rsNode->SetPUIdx(ImportFuncViaSym(func)); rsNode->SetOpnd(ImportExpression(func), 0); rsNode->SetOpnd(ImportExpression(func), 1); return rsNode; @@ -403,7 +375,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { // nary case OP_array: { TyIdx tidx = ImportType(); - auto boundsCheck = static_cast(ReadNum()); + bool boundsCheck = static_cast(Read()); ArrayNode *arrNode = mod.CurFuncCodeMemPool()->New(func->GetCodeMPAllocator(), typ, tidx, boundsCheck); auto n = static_cast(ReadNum()); @@ -436,12 +408,15 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { return intrnNode; } default: - CHECK_FATAL(false, "Unhandled op %d", tag); + CHECK_FATAL(false, "Unhandled op %d", op); break; } } void BinaryMplImport::ImportSrcPos(SrcPosition &pos) { + if (!mod.IsWithDbgInfo()) { + return; + } pos.SetRawData(static_cast(ReadNum())); pos.SetLineNum(static_cast(ReadNum())); } @@ -451,15 +426,16 @@ void BinaryMplImport::ImportReturnValues(MIRFunction *func, CallReturnVector *re CHECK_FATAL(tag == kBinReturnvals, "expecting return values"); auto size = static_cast(ReadNum()); for (uint32 i = 0; i < size; ++i) { - uint32 idx = static_cast(ReadNum()); - FieldID fid = static_cast(ReadNum()); - PregIdx ridx = static_cast(ReadNum()); - retv->push_back(std::make_pair(StIdx(kScopeLocal, idx), RegFieldPair(fid, ridx))); - if (idx == 0) { + RegFieldPair rfp; + rfp.SetPregIdx(ImportPreg(func)); + if (rfp.IsReg()) { + retv->push_back(std::make_pair(StIdx(), rfp)); continue; } - MIRSymbol *lsym = func->GetSymTab()->GetSymbolFromStIdx(idx, false); - ASSERT(lsym != nullptr, "null ptr check"); + rfp.SetFieldID(static_cast(ReadNum())); + MIRSymbol *lsym = ImportLocalSymbol(func); + CHECK_FATAL(lsym != nullptr, "null ptr check"); + retv->push_back(std::make_pair(lsym->GetStIdx(), rfp)); if (lsym->GetName().find("L_STR") == 0) { MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(lsym->GetTyIdx()); CHECK_FATAL(ty->GetKind() == kTypePointer, "Pointer type expected for L_STR prefix"); @@ -480,8 +456,6 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { ImportSrcPos(block->GetSrcPos()); int32 size = ReadInt(); for (int32 k = 0; k < size; ++k) { - tag = ReadNum(); - CHECK_FATAL(tag == kBinOpStatement, "kBinOpStatement expected"); SrcPosition thesrcPosition; ImportSrcPos(thesrcPosition); op = (Opcode)ReadNum(); @@ -496,17 +470,16 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { int32 num = static_cast(ReadNum()); StIdx stIdx; stIdx.SetScope(static_cast(ReadNum())); + MIRSymbol *sym = nullptr; if (stIdx.Islocal()) { - stIdx.SetIdx(static_cast(ReadNum())); + sym = ImportLocalSymbol(func); + CHECK_FATAL(sym != nullptr, "null ptr check"); } else { - int32 stag = static_cast(ReadNum()); - CHECK_FATAL(stag == kBinKindSymViaSymname, "kBinKindSymViaSymname expected"); - GStrIdx strIdx = ImportStr(); - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx); - ASSERT(sym != nullptr, "null ptr check"); + sym = InSymbol(func); + CHECK_FATAL(sym != nullptr, "null ptr check"); sym->SetHasPotentialAssignment(); - stIdx.SetIdx(sym->GetStIdx().Idx()); } + stIdx.SetIdx(sym->GetStIdx().Idx()); if (op == OP_dassign) { DassignNode *s = func->GetCodeMemPool()->New(); s->SetStIdx(stIdx); @@ -525,8 +498,8 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_regassign: { RegassignNode *s = func->GetCodeMemPool()->New(); - s->SetPrimType((PrimType)ReadNum()); - s->SetRegIdx(static_cast(ReadNum())); + s->SetPrimType((PrimType)Read()); + s->SetRegIdx(ImportPreg(func)); s->SetOpnd(ImportExpression(func), 0); stmt = s; break; @@ -542,7 +515,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_iassignoff: { IassignoffNode *s = func->GetCodeMemPool()->New(); - s->SetPrimType((PrimType)ReadNum()); + s->SetPrimType((PrimType)Read()); s->SetOffset(static_cast(ReadNum())); s->SetOpnd(ImportExpression(func), 0); s->SetOpnd(ImportExpression(func), 1); @@ -552,7 +525,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { case OP_iassignspoff: case OP_iassignfpoff: { IassignFPoffNode *s = func->GetCodeMemPool()->New(op); - s->SetPrimType((PrimType)ReadNum()); + s->SetPrimType((PrimType)Read()); s->SetOffset(static_cast(ReadNum())); s->SetOpnd(ImportExpression(func), 0); stmt = s; @@ -577,7 +550,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { case OP_interfaceicall: case OP_customcall: { CallNode *s = func->GetCodeMemPool()->New(mod, op); - s->SetPUIdx(ImportFuncViaSymName()); + s->SetPUIdx(ImportFuncViaSym(func)); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx()); + f->GetFuncSymbol()->SetAppearsInCode(true); numOpr = static_cast(ReadNum()); s->SetNumOpnds(numOpr); for (int32 i = 0; i < numOpr; ++i) { @@ -594,7 +569,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { case OP_interfaceicallassigned: case OP_customcallassigned: { CallNode *s = func->GetCodeMemPool()->New(mod, op); - s->SetPUIdx(ImportFuncViaSymName()); + s->SetPUIdx(ImportFuncViaSym(func)); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx()); + f->GetFuncSymbol()->SetAppearsInCode(true); ImportReturnValues(func, &s->GetReturnVec()); numOpr = static_cast(ReadNum()); s->SetNumOpnds(numOpr); @@ -610,7 +587,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_polymorphiccall: { CallNode *s = func->GetCodeMemPool()->New(mod, op); - s->SetPUIdx(ImportFuncViaSymName()); + s->SetPUIdx(ImportFuncViaSym(func)); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx()); + f->GetFuncSymbol()->SetAppearsInCode(true); s->SetTyIdx(ImportType()); numOpr = static_cast(ReadNum()); s->SetNumOpnds(numOpr); @@ -622,7 +601,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_polymorphiccallassigned: { CallNode *s = func->GetCodeMemPool()->New(mod, op); - s->SetPUIdx(ImportFuncViaSymName()); + s->SetPUIdx(ImportFuncViaSym(func)); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx()); + f->GetFuncSymbol()->SetAppearsInCode(true); s->SetTyIdx(ImportType()); ImportReturnValues(func, &s->GetReturnVec()); numOpr = static_cast(ReadNum()); @@ -645,6 +626,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { stmt = s; break; } + case OP_icallprotoassigned: case OP_icallassigned: { IcallNode *s = func->GetCodeMemPool()->New(mod, op); s->SetRetTyIdx(ImportType()); @@ -759,32 +741,32 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_label: { LabelNode *s = mod.CurFuncCodeMemPool()->New(); - s->SetLabelIdx(static_cast(ReadNum())); + s->SetLabelIdx(ImportLabel(func)); stmt = s; break; } case OP_goto: case OP_gosub: { GotoNode *s = mod.CurFuncCodeMemPool()->New(op); - s->SetOffset(static_cast(ReadNum())); + s->SetOffset(ImportLabel(func)); stmt = s; break; } case OP_brfalse: case OP_brtrue: { CondGotoNode *s = mod.CurFuncCodeMemPool()->New(op); - s->SetOffset(static_cast(ReadNum())); + s->SetOffset(ImportLabel(func)); s->SetOpnd(ImportExpression(func), 0); stmt = s; break; } case OP_switch: { SwitchNode *s = mod.CurFuncCodeMemPool()->New(mod); - s->SetDefaultLabel(static_cast(ReadNum())); + s->SetDefaultLabel(ImportLabel(func)); auto tagSize = static_cast(ReadNum()); for (uint32 i = 0; i < tagSize; ++i) { int64 casetag = ReadNum(); - LabelIdx lidx(ReadNum()); + LabelIdx lidx = ImportLabel(func); CasePair cpair = std::make_pair(casetag, lidx); s->GetSwitchTable().push_back(cpair); } @@ -798,7 +780,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { uint32 tagSize = static_cast(ReadNum()); for (uint32 i = 0; i < tagSize; ++i) { uint16 casetag = static_cast(ReadNum()); - LabelIdx lidx(ReadNum()); + LabelIdx lidx = ImportLabel(func); s->AddRangeGoto(casetag, lidx); } s->SetOpnd(ImportExpression(func), 0); @@ -807,8 +789,8 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_jstry: { JsTryNode *s = mod.CurFuncCodeMemPool()->New(); - s->SetCatchOffset(static_cast(ReadNum())); - s->SetFinallyOffset(static_cast(ReadNum())); + s->SetCatchOffset(ImportLabel(func)); + s->SetFinallyOffset(ImportLabel(func)); stmt = s; break; } @@ -817,7 +799,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { TryNode *s = mod.CurFuncCodeMemPool()->New(mod); auto numLabels = static_cast(ReadNum()); for (uint32 i = 0; i < numLabels; ++i) { - s->GetOffsets().push_back(ReadNum()); + s->GetOffsets().push_back(ImportLabel(func)); } stmt = s; break; @@ -887,7 +869,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { // the labels count = static_cast(ReadNum()); for (size_t i = 0; i < count; ++i) { - auto lidx = static_cast(ReadNum()); + LabelIdx lidx = ImportLabel(func); s->gotoLabels.push_back(lidx); } // the inputs @@ -927,6 +909,13 @@ void BinaryMplImport::ReadFunctionBodyField() { PUIdx puIdx = ImportFunction(); MIRFunction *fn = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); mod.SetCurFunction(fn); + fn->GetFuncSymbol()->SetAppearsInCode(true); + localSymTab.clear(); + localSymTab.push_back(nullptr); + localPregTab.clear(); + localPregTab.push_back(0); + localLabelTab.clear(); + localLabelTab.push_back(0); fn->AllocSymTab(); fn->AllocPregTab(); @@ -934,9 +923,6 @@ void BinaryMplImport::ReadFunctionBodyField() { fn->AllocLabelTab(); ImportFuncIdInfo(fn); - ImportPregTab(fn); - ImportLocalSymTab(fn); - ImportLabelTab(fn); ImportLocalTypeNameTable(fn->GetTypeNameTab()); ImportFormalsStIdx(fn); if (mod.GetFlavor() < kMmpl) { @@ -945,8 +931,6 @@ void BinaryMplImport::ReadFunctionBodyField() { (void)ImportBlockNode(fn); mod.AddFunction(fn); } - int64 tag = ReadNum(); - CHECK_FATAL(tag == ~kBinFunctionBodyStart, "pattern mismatch in Read FunctionBody"); return; } } // namespace maple diff --git a/src/mapleall/maple_ir/src/bin_mpl_export.cpp b/src/mapleall/maple_ir/src/bin_mpl_export.cpp index 21fb6691f9..4359ae9f55 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_export.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_export.cpp @@ -26,7 +26,7 @@ namespace { using namespace maple; using OutputConstFactory = FunctionFactory; -using OutputTypeFactory = FunctionFactory; +using OutputTypeFactory = FunctionFactory; void OutputConstInt(const MIRConst &constVal, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindConstInt); @@ -62,7 +62,7 @@ void OutputConstLbl(const MIRConst &constVal, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindConstAddrofLabel); mplExport.OutputConstBase(constVal); const MIRLblConst &lblConst = static_cast(constVal); - mplExport.WriteNum(lblConst.GetValue()); // LabelIdx not needed to output puIdx + mplExport.OutputLabel(lblConst.GetValue()); } void OutputConstStr(const MIRConst &constVal, BinaryMplExport &mplExport) { @@ -141,39 +141,39 @@ static bool InitOutputConstFactory() { return true; } -void OutputTypeScalar(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeScalar(const MIRType &ty, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindTypeScalar); mplExport.OutputTypeBase(ty); } -void OutputTypePointer(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypePointer(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypePointer); mplExport.OutputTypeBase(type); mplExport.OutputTypeAttrs(type.GetTypeAttrs()); - mplExport.OutputType(type.GetPointedTyIdx(), canUseTypename); + mplExport.OutputType(type.GetPointedTyIdx()); } -void OutputTypeByName(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeByName(const MIRType &ty, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindTypeByName); mplExport.OutputTypeBase(ty); } -void OutputTypeFArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeFArray(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeFArray); mplExport.OutputTypeBase(type); - mplExport.OutputType(type.GetElemTyIdx(), canUseTypename); + mplExport.OutputType(type.GetElemTyIdx()); } -void OutputTypeJArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeJArray(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeJarray); mplExport.OutputTypeBase(type); - mplExport.OutputType(type.GetElemTyIdx(), canUseTypename); + mplExport.OutputType(type.GetElemTyIdx()); } -void OutputTypeArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeArray(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeArray); mplExport.OutputTypeBase(type); @@ -181,20 +181,20 @@ void OutputTypeArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseT for (uint16 i = 0; i < type.GetDim(); ++i) { mplExport.WriteNum(type.GetSizeArrayItem(i)); } - mplExport.OutputType(type.GetElemTyIdx(), canUseTypename); + mplExport.OutputType(type.GetElemTyIdx()); mplExport.OutputTypeAttrs(type.GetTypeAttrs()); } -void OutputTypeFunction(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeFunction(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeFunction); mplExport.OutputTypeBase(type); - mplExport.OutputType(type.GetRetTyIdx(), canUseTypename); - mplExport.WriteNum(type.IsVarargs()); + mplExport.OutputType(type.GetRetTyIdx()); + mplExport.WriteNum(type.funcAttrs.GetAttrFlag()); size_t size = type.GetParamTypeList().size(); mplExport.WriteNum(size); for (size_t i = 0; i < size; ++i) { - mplExport.OutputType(type.GetNthParamType(i), canUseTypename); + mplExport.OutputType(type.GetNthParamType(i)); } size = type.GetParamAttrsList().size(); mplExport.WriteNum(size); @@ -203,13 +203,13 @@ void OutputTypeFunction(const MIRType &ty, BinaryMplExport &mplExport, bool canU } } -void OutputTypeParam(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeParam(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeParam); mplExport.OutputTypeBase(type); } -void OutputTypeInstantVector(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeInstantVector(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeInstantVector); mplExport.OutputTypeBase(type); @@ -217,15 +217,15 @@ void OutputTypeInstantVector(const MIRType &ty, BinaryMplExport &mplExport, bool mplExport.OutputTypePairs(type); } -void OutputTypeGenericInstant(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeGenericInstant(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeGenericInstant); mplExport.OutputTypeBase(type); mplExport.OutputTypePairs(type); - mplExport.OutputType(type.GetGenericTyIdx(), canUseTypename); + mplExport.OutputType(type.GetGenericTyIdx()); } -void OutputTypeBitField(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeBitField(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeBitField); mplExport.OutputTypeBase(type); @@ -233,7 +233,7 @@ void OutputTypeBitField(const MIRType &ty, BinaryMplExport &mplExport, bool) { } // for Struct/StructIncomplete/Union -void OutputTypeStruct(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeStruct(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeStruct); mplExport.OutputTypeBase(type); @@ -249,7 +249,7 @@ void OutputTypeStruct(const MIRType &ty, BinaryMplExport &mplExport, bool) { } } -void OutputTypeClass(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeClass(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeClass); mplExport.OutputTypeBase(type); @@ -264,7 +264,7 @@ void OutputTypeClass(const MIRType &ty, BinaryMplExport &mplExport, bool) { } } -void OutputTypeInterface(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeInterface(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeInterface); mplExport.OutputTypeBase(type); @@ -279,7 +279,7 @@ void OutputTypeInterface(const MIRType &ty, BinaryMplExport &mplExport, bool) { } } -void OutputTypeConstString(const MIRType &ty, BinaryMplExport&, bool) { +void OutputTypeConstString(const MIRType &ty, BinaryMplExport&) { ASSERT(false, "Type's kind not yet implemented: %d", ty.GetKind()); (void)ty; } @@ -397,7 +397,7 @@ void BinaryMplExport::DumpBuf(const std::string &name) { void BinaryMplExport::OutputConstBase(const MIRConst &constVal) { WriteNum(constVal.GetKind()); - OutputTypeViaTypeName(constVal.GetType().GetTypeIndex()); + OutputType(constVal.GetType().GetTypeIndex()); } void BinaryMplExport::OutputConst(MIRConst *constVal) { @@ -470,8 +470,8 @@ void BinaryMplExport::OutputPragma(const MIRPragma &p) { WriteNum(p.GetKind()); WriteNum(p.GetVisibility()); OutputStr(p.GetStrIdx()); - OutputType(p.GetTyIdx(), false); - OutputType(p.GetTyIdxEx(), false); + OutputType(p.GetTyIdx()); + OutputType(p.GetTyIdxEx()); WriteNum(p.GetParamNum()); size_t size = p.GetElementVector().size(); WriteNum(size); @@ -488,7 +488,7 @@ void BinaryMplExport::OutputTypeBase(const MIRType &type) { void BinaryMplExport::OutputFieldPair(const FieldPair &fp) { OutputStr(fp.first); // GStrIdx - OutputType(fp.second.first, false); // TyIdx + OutputType(fp.second.first); // TyIdx FieldAttrs fa = fp.second.second; WriteNum(fa.GetAttrFlag()); WriteNum(fa.GetAlignValue()); @@ -511,7 +511,7 @@ void BinaryMplExport::OutputMethodPair(const MethodPair &memPool) { MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(memPool.first.Idx()); CHECK_FATAL(funcSt != nullptr, "Pointer funcSt is nullptr, can't get symbol! Check it!"); WriteAsciiStr(GlobalTables::GetStrTable().GetStringFromStrIdx(funcSt->GetNameStrIdx())); - OutputType(memPool.second.first, false); // TyIdx + OutputType(memPool.second.first); // TyIdx WriteNum(memPool.second.second.GetAttrFlag()); // FuncAttrs } @@ -539,7 +539,7 @@ void BinaryMplExport::OutputStructTypeData(const MIRStructType &type) { void BinaryMplExport::OutputImplementedInterfaces(const std::vector &interfaces) { WriteNum(interfaces.size()); for (const TyIdx &tyIdx : interfaces) { - OutputType(tyIdx, false); + OutputType(tyIdx); } } @@ -571,7 +571,7 @@ void BinaryMplExport::OutputPragmaVec(const std::vector &pragmaVec) } void BinaryMplExport::OutputClassTypeData(const MIRClassType &type) { - OutputType(type.GetParentTyIdx(), false); + OutputType(type.GetParentTyIdx()); OutputImplementedInterfaces(type.GetInterfaceImplemented()); OutputInfoIsString(type.GetInfoIsString()); if (!inIPA) { @@ -601,6 +601,7 @@ void BinaryMplExport::Init() { symMark[nullptr] = 0; funcMark[nullptr] = 0; eaNodeMark[nullptr] = 0; + curFunc = nullptr; for (uint32 pti = static_cast(PTY_begin); pti < static_cast(PTY_end); ++pti) { typMark[GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(pti))] = pti; } @@ -612,7 +613,7 @@ void BinaryMplExport::OutputSymbol(MIRSymbol *sym) { return; } - auto it = symMark.find(sym); + std::unordered_map::iterator it = symMark.find(sym); if (it != symMark.end()) { WriteNum(-(it->second)); return; @@ -645,7 +646,7 @@ void BinaryMplExport::OutputSymbol(MIRSymbol *sym) { if (sym->GetSKind() == kStVar || sym->GetSKind() == kStFunc) { OutputSrcPos(sym->GetSrcPosition()); } - OutputTypeViaTypeName(sym->GetTyIdx()); + OutputType(sym->GetTyIdx()); } void BinaryMplExport::OutputFunction(PUIdx puIdx) { @@ -671,7 +672,7 @@ void BinaryMplExport::OutputFunction(PUIdx puIdx) { MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx()); CHECK_FATAL(funcSt != nullptr, "Pointer funcSt is nullptr, cannot get symbol! Check it!"); OutputSymbol(funcSt); - OutputTypeViaTypeName(func->GetMIRFuncType()->GetTypeIndex()); + OutputType(func->GetMIRFuncType()->GetTypeIndex()); WriteNum(func->GetFuncAttrs().GetAttrFlag()); auto &attributes = func->GetFuncAttrs(); @@ -684,12 +685,12 @@ void BinaryMplExport::OutputFunction(PUIdx puIdx) { } WriteNum(func->GetFlag()); - OutputTypeViaTypeName(func->GetClassTyIdx()); + OutputType(func->GetClassTyIdx()); // output formal parameter information WriteNum(static_cast(func->GetFormalDefVec().size())); for (FormalDef formalDef : func->GetFormalDefVec()) { OutputStr(formalDef.formalStrIdx); - OutputType(formalDef.formalTyIdx, false); + OutputType(formalDef.formalTyIdx); WriteNum(static_cast(formalDef.formalAttrs.GetAttrFlag())); } // store Side Effect for each func @@ -751,15 +752,20 @@ void BinaryMplExport::WriteHeaderField(uint64 contentIdx) { WriteNum(mod.GetID()); if (mod.GetFlavor() == kFlavorLmbc) { WriteNum(mod.GetGlobalMemSize()); + WriteNum(mod.IsWithDbgInfo()); } WriteNum(mod.GetNumFuncs()); WriteAsciiStr(mod.GetEntryFuncName()); OutputInfoVector(mod.GetFileInfo(), mod.GetFileInfoIsString()); - WriteNum(static_cast(mod.GetSrcFileInfo().size())); - for (uint32 i = 0; i < mod.GetSrcFileInfo().size(); i++) { - OutputStr(mod.GetSrcFileInfo()[i].first); - WriteNum(mod.GetSrcFileInfo()[i].second); + if (mod.IsWithDbgInfo()) { + WriteNum(static_cast(mod.GetSrcFileInfo().size())); + for (uint32 i = 0; i < mod.GetSrcFileInfo().size(); i++) { + OutputStr(mod.GetSrcFileInfo()[i].first); + WriteNum(mod.GetSrcFileInfo()[i].second); + } + } else { + Write(0); } WriteNum(static_cast(mod.GetImportFiles().size())); @@ -795,7 +801,7 @@ void BinaryMplExport::WriteTypeField(uint64 contentIdx, bool useClassList) { auto *structType = static_cast(type); // skip imported class/interface and incomplete types if (!structType->IsImported() && !structType->IsIncomplete()) { - OutputType(curTyidx, false); + OutputType(curTyidx); ++size; } } @@ -803,7 +809,7 @@ void BinaryMplExport::WriteTypeField(uint64 contentIdx, bool useClassList) { } else { uint32 idx = GlobalTables::GetTypeTable().lastDefaultTyIdx.GetIdx(); for (idx = idx + 1; idx < GlobalTables::GetTypeTable().GetTypeTableSize(); idx++) { - OutputType(TyIdx(idx), false); + OutputType(TyIdx(idx)); size++; } } @@ -884,7 +890,7 @@ void BinaryMplExport::WriteSeField() { GlobalTables::GetGsymTable().GetSymbolFromStrIdx(GlobalTables::GetStrTable().GetStrIdxFromName(funcStr)); MIRFunction *func = (funcSymbol != nullptr) ? GetMIRModule().GetMIRBuilder()->GetFunctionFromSymbol(*funcSymbol) : nullptr; - OutputType(func->GetReturnTyIdx(), false); + OutputType(func->GetReturnTyIdx()); } ++size; } @@ -1103,7 +1109,7 @@ void BinaryMplExport::WriteSymField(uint64 contentIdx) { MIRSymKind sKind = s->GetSKind(); if (s->IsDeleted() || storageClass == kScUnused || (s->GetIsImported() && !s->GetAppearsInCode()) || - (storageClass == kScExtern && sKind == kStFunc)) { + (sKind == kStFunc && (storageClass == kScExtern || !s->GetAppearsInCode()))) { continue; } OutputSymbol(s); @@ -1214,8 +1220,6 @@ void BinaryMplExport::Export(const std::string &fname, std::unordered_setIsNameIsLocal() && ty->GetNameStrIdx() != GStrIdx(0)) { - WriteNum(kBinKindTypeViaTypename); - OutputStr(ty->GetNameStrIdx()); - return; - } - auto func = CreateProductFunction(ty->GetKind()); if (func != nullptr) { - func(*ty, *this, canUseTypename); + func(*ty, *this); } else { ASSERT(false, "Type's kind not yet implemented: %d", ty->GetKind()); } diff --git a/src/mapleall/maple_ir/src/bin_mpl_import.cpp b/src/mapleall/maple_ir/src/bin_mpl_import.cpp index 50779027df..1f79751ed6 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_import.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_import.cpp @@ -129,11 +129,13 @@ MIRConst *BinaryMplImport::ImportConst(MIRFunction *func) { } case kBinKindConstAddrofFunc: { PUIdx puIdx = ImportFunction(); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFuncTable()[puIdx]; + f->GetFuncSymbol()->SetAppearsInCode(true); mod.SetCurFunction(func); return memPool->New(puIdx, *type); } case kBinKindConstAddrofLabel: { - LabelIdx lidx = static_cast(ReadNum()); + LabelIdx lidx = ImportLabel(func); PUIdx puIdx = func->GetPuidx(); MIRLblConst *lblConst = memPool->New(lidx, puIdx, *type); (void)func->GetLabelTab()->addrTakenLabels.insert(lidx); @@ -541,19 +543,6 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { CHECK_FATAL(static_cast(-tag) < typTab.size(), "index out of bounds"); return typTab.at(static_cast(-tag)); } - if (tag == kBinKindTypeViaTypename) { - GStrIdx typenameStrIdx = ImportStr(); - TyIdx tyIdx = mod.GetTypeNameTab()->GetTyIdxFromGStrIdx(typenameStrIdx); - if (tyIdx != 0) { - typTab.push_back(tyIdx); - return tyIdx; - } - MIRTypeByName ltype(typenameStrIdx); - ltype.SetNameIsLocal(false); - MIRType *type = GlobalTables::GetTypeTable().GetOrCreateMIRTypeNode(ltype); - typTab.push_back(type->GetTypeIndex()); - return type->GetTypeIndex(); - } PrimType primType = (PrimType)0; GStrIdx strIdx(0); bool nameIsLocal = false; @@ -580,13 +569,6 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { } return origType->GetTypeIndex(); } - case kBinKindTypeByName: { - MIRTypeByName type(strIdx); - type.SetNameIsLocal(nameIsLocal); - MIRType *origType = &InsertInTypeTables(type); - typTab.push_back(origType->GetTypeIndex()); - return origType->GetTypeIndex(); - } case kBinKindTypeFArray: { MIRFarrayType type(strIdx); type.SetNameIsLocal(nameIsLocal); @@ -629,7 +611,7 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { size_t idx = typTab.size(); typTab.push_back(TyIdx(0)); type.SetRetTyIdx(ImportType()); - type.SetVarArgs(ReadNum()); + type.funcAttrs.SetAttrFlag(ReadNum()); int64 size = ReadNum(); for (int64 i = 0; i < size; ++i) { type.GetParamTypeList().push_back(ImportType()); @@ -737,19 +719,6 @@ TyIdx BinaryMplImport::ImportTypeNonJava() { CHECK_FATAL(static_cast(-tag) < typTab.size(), "index out of bounds"); return typTab[static_cast(-tag)]; } - if (tag == kBinKindTypeViaTypename) { - GStrIdx typenameStrIdx = ImportStr(); - TyIdx tyIdx = mod.GetTypeNameTab()->GetTyIdxFromGStrIdx(typenameStrIdx); - if (tyIdx != 0) { - typTab.push_back(tyIdx); - return tyIdx; - } - MIRTypeByName ltype(typenameStrIdx); - ltype.SetNameIsLocal(false); - MIRType *type = GlobalTables::GetTypeTable().GetOrCreateMIRTypeNode(ltype); - typTab.push_back(type->GetTypeIndex()); - return type->GetTypeIndex(); - } PrimType primType = (PrimType)0; GStrIdx strIdx(0); bool nameIsLocal = false; @@ -771,12 +740,6 @@ TyIdx BinaryMplImport::ImportTypeNonJava() { GlobalTables::GetTypeTable().CreateMirTypeNodeAt(type, tyIdxUsed, &mod, false, false); return tyIdxUsed; } - case kBinKindTypeByName: { - MIRTypeByName type(strIdx); - type.SetNameIsLocal(nameIsLocal); - GlobalTables::GetTypeTable().CreateMirTypeNodeAt(type, tyIdxUsed, &mod, false, false); - return tyIdxUsed; - } case kBinKindTypeFArray: { MIRFarrayType type(strIdx); type.SetNameIsLocal(nameIsLocal); @@ -808,7 +771,7 @@ TyIdx BinaryMplImport::ImportTypeNonJava() { MIRFuncType type(strIdx); type.SetNameIsLocal(nameIsLocal); type.SetRetTyIdx(ImportTypeNonJava()); - type.SetVarArgs(ReadNum()); + type.funcAttrs.SetAttrFlag(ReadNum()); int64 size = ReadNum(); for (int64 i = 0; i < size; ++i) { type.GetParamTypeList().push_back(ImportTypeNonJava()); @@ -1159,6 +1122,7 @@ void BinaryMplImport::ReadHeaderField() { mod.SetID(static_cast(ReadNum())); if (mod.GetFlavor() == kFlavorLmbc) { mod.SetGlobalMemSize(static_cast(ReadNum())); + mod.SetWithDbgInfo(static_cast(ReadNum())); } mod.SetNumFuncs(static_cast(ReadNum())); std::string inStr; diff --git a/src/mapleall/maple_ir/src/global_tables.cpp b/src/mapleall/maple_ir/src/global_tables.cpp index c43e86b2d5..99851d8ec5 100644 --- a/src/mapleall/maple_ir/src/global_tables.cpp +++ b/src/mapleall/maple_ir/src/global_tables.cpp @@ -224,7 +224,9 @@ MIRType *TypeTable::GetOrCreateFunctionType(const TyIdx &retTyIdx, const std::ve const std::vector &vecAttrs, bool isVarg, const TypeAttrs &retAttrs) { MIRFuncType funcType(retTyIdx, vecType, vecAttrs, retAttrs); - funcType.SetVarArgs(isVarg); + if (isVarg) { + funcType.SetVarArgs(); + } TyIdx tyIdx = GetOrCreateMIRType(&funcType); ASSERT(tyIdx < typeTable.size(), "index out of range in TypeTable::GetOrCreateFunctionType"); return typeTable.at(tyIdx); diff --git a/src/mapleall/maple_ir/src/mir_builder.cpp b/src/mapleall/maple_ir/src/mir_builder.cpp index 9e57d1514f..965b2a83c6 100755 --- a/src/mapleall/maple_ir/src/mir_builder.cpp +++ b/src/mapleall/maple_ir/src/mir_builder.cpp @@ -836,6 +836,13 @@ IcallNode *MIRBuilder::CreateStmtIcall(const MapleVector &args) { return stmt; } +IcallNode *MIRBuilder::CreateStmtIcallproto(const MapleVector &args) { + auto *stmt = GetCurrentFuncCodeMp()->New(*GetCurrentFuncCodeMpAllocator(), OP_icallproto); + ASSERT(stmt != nullptr, "stmt is null"); + stmt->SetOpnds(args); + return stmt; +} + IcallNode *MIRBuilder::CreateStmtIcallAssigned(const MapleVector &args, const MIRSymbol &ret) { auto *stmt = GetCurrentFuncCodeMp()->New(*GetCurrentFuncCodeMpAllocator(), OP_icallassigned); CallReturnVector nrets(GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -853,6 +860,23 @@ IcallNode *MIRBuilder::CreateStmtIcallAssigned(const MapleVector &arg return stmt; } +IcallNode *MIRBuilder::CreateStmtIcallprotoAssigned(const MapleVector &args, const MIRSymbol &ret) { + auto *stmt = GetCurrentFuncCodeMp()->New(*GetCurrentFuncCodeMpAllocator(), OP_icallprotoassigned); + CallReturnVector nrets(GetCurrentFuncCodeMpAllocator()->Adapter()); + CHECK_FATAL((ret.GetStorageClass() == kScAuto || ret.GetStorageClass() == kScFormal || + ret.GetStorageClass() == kScExtern || ret.GetStorageClass() == kScGlobal), + "unknown classtype! check it!"); + nrets.emplace_back(CallReturnPair(ret.GetStIdx(), RegFieldPair(0, 0))); + stmt->SetNumOpnds(args.size()); + stmt->GetNopnd().resize(stmt->GetNumOpnds()); + stmt->SetReturnVec(nrets); + for (size_t i = 0; i < stmt->GetNopndSize(); ++i) { + stmt->SetNOpndAt(i, args.at(i)); + } + stmt->SetRetTyIdx(ret.GetTyIdx()); + return stmt; +} + IntrinsiccallNode *MIRBuilder::CreateStmtIntrinsicCall(MIRIntrinsicID idx, const MapleVector &arguments, TyIdx tyIdx) { auto *stmt = GetCurrentFuncCodeMp()->New( diff --git a/src/mapleall/maple_ir/src/mir_function.cpp b/src/mapleall/maple_ir/src/mir_function.cpp index 112f5ad6cf..4f217e54c5 100644 --- a/src/mapleall/maple_ir/src/mir_function.cpp +++ b/src/mapleall/maple_ir/src/mir_function.cpp @@ -368,10 +368,8 @@ void MIRFunction::Dump(bool withoutBody) { LogInfo::MapleLogger() << " )"; } - if (module->GetFlavor() < kMmpl) { + if (module->GetFlavor() != kMmpl) { DumpFlavorLoweredThanMmpl(); - } else { - LogInfo::MapleLogger() << " () void"; } // codeMemPool is nullptr, means maple_ir has been released for memory's sake diff --git a/src/mapleall/maple_ir/src/mir_lower.cpp b/src/mapleall/maple_ir/src/mir_lower.cpp index 401ce4a641..36d572f057 100644 --- a/src/mapleall/maple_ir/src/mir_lower.cpp +++ b/src/mapleall/maple_ir/src/mir_lower.cpp @@ -544,6 +544,19 @@ BlockNode *MIRLower::LowerBlock(BlockNode &block) { case OP_doloop: newBlock->AppendStatementsFromBlock(*LowerDoloopStmt(static_cast(*stmt))); break; + case OP_icallassigned: + case OP_icall: { + if (mirModule.IsCModule()) { + // convert to icallproto/icallprotoassigned + IcallNode *ic = static_cast(stmt); + ic->SetOpCode(stmt->GetOpCode() == OP_icall ? OP_icallproto : OP_icallprotoassigned); + MIRFuncType *funcType = FuncTypeFromFuncPtrExpr(stmt->Opnd(0)); + CHECK_FATAL(funcType != nullptr, "MIRLower::LowerBlock: cannot find prototype for icall"); + ic->SetRetTyIdx(funcType->GetTypeIndex()); + } + newBlock->AddStatement(stmt); + break; + } case OP_block: tmp = LowerBlock(static_cast(*stmt)); newBlock->AppendStatementsFromBlock(*tmp); @@ -999,6 +1012,100 @@ void MIRLower::ExpandArrayMrt(MIRFunction &func) { } } +MIRFuncType *MIRLower::FuncTypeFromFuncPtrExpr(BaseNode *x) { + MIRFuncType *res = nullptr; + MIRFunction *func = mirModule.CurFunction(); + switch (x->GetOpCode()) { + case OP_regread: { + RegreadNode *regread = static_cast(x); + MIRPreg *preg = func->GetPregTab()->PregFromPregIdx(regread->GetRegIdx()); + // see if it is promoted from a symbol + if (preg->GetOp() == OP_dread) { + const MIRSymbol *symbol = preg->rematInfo.sym; + MIRType *mirType = symbol->GetType(); + if (preg->fieldID != 0) { + MIRStructType *structty = static_cast(mirType); + FieldPair thepair = structty->TraverseToField(preg->fieldID); + mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); + } + + if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + if (res != nullptr) { + break; + } + } + // check if a formal promoted to preg + for (FormalDef &formalDef : func->GetFormalDefVec()) { + if (!formalDef.formalSym->IsPreg()) { + continue; + } + if (formalDef.formalSym->GetPreg() == preg) { + MIRType *mirType = formalDef.formalSym->GetType(); + if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + break; + } + } + break; + } + case OP_dread: { + DreadNode *dread = static_cast(x); + MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); + MIRType *mirType = symbol->GetType(); + if (dread->GetFieldID() != 0) { + MIRStructType *structty = static_cast(mirType); + FieldPair thepair = structty->TraverseToField(dread->GetFieldID()); + mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); + } + if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + break; + } + case OP_iread: { + IreadNode *iread = static_cast(x); + MIRPtrType *ptrType = static_cast(iread->GetType()); + MIRType *mirType = ptrType->GetPointedType(); + if (mirType->GetKind() == kTypeFunction) { + res = static_cast(mirType); + } else if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + break; + } + case OP_addroffunc: { + AddroffuncNode *addrofFunc = static_cast(x); + PUIdx puIdx = addrofFunc->GetPUIdx(); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); + res = f->GetMIRFuncType(); + break; + } + case OP_retype: { + MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx( + static_cast(x)->GetTyIdx()); + if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + if (res == nullptr) { + res = FuncTypeFromFuncPtrExpr(x->Opnd(0)); + } + break; + } + case OP_select: { + res = FuncTypeFromFuncPtrExpr(x->Opnd(1)); + if (res == nullptr) { + res = FuncTypeFromFuncPtrExpr(x->Opnd(2)); + } + break; + } + default: CHECK_FATAL(false, "LMBCLowerer::FuncTypeFromFuncPtrExpr: NYI"); + } + return res; +} + const std::set MIRLower::kSetArrayHotFunc = {}; bool MIRLower::ShouldOptArrayMrt(const MIRFunction &func) { diff --git a/src/mapleall/maple_ir/src/mir_nodes.cpp b/src/mapleall/maple_ir/src/mir_nodes.cpp index 50a2ab2df7..a42998b1f2 100755 --- a/src/mapleall/maple_ir/src/mir_nodes.cpp +++ b/src/mapleall/maple_ir/src/mir_nodes.cpp @@ -1201,7 +1201,7 @@ MIRType *IcallNode::GetCallReturnType() { if (op == OP_icall || op == OP_icallassigned) { return GlobalTables::GetTypeTable().GetTypeFromTyIdx(retTyIdx); } - // icallproto + // icallproto or icallprotoassigned MIRFuncType *funcType = static_cast( GlobalTables::GetTypeTable().GetTypeFromTyIdx(retTyIdx)); return GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcType->GetRetTyIdx()); @@ -1226,7 +1226,7 @@ const MIRSymbol *IcallNode::GetCallReturnSymbol(const MIRModule &mod) const { void IcallNode::Dump(int32 indent, bool newline) const { StmtNode::DumpBase(indent); - if (op == OP_icallproto) { + if (op == OP_icallproto || op == OP_icallprotoassigned) { LogInfo::MapleLogger() << " "; GlobalTables::GetTypeTable().GetTypeFromTyIdx(retTyIdx)->Dump(indent + 1); } diff --git a/src/mapleall/maple_ir/src/mir_parser.cpp b/src/mapleall/maple_ir/src/mir_parser.cpp index 9660002e49..b0bbf9080b 100755 --- a/src/mapleall/maple_ir/src/mir_parser.cpp +++ b/src/mapleall/maple_ir/src/mir_parser.cpp @@ -896,6 +896,7 @@ bool MIRParser::ParseStmtCall(StmtNodePtr &stmt) { callStmt->SetPUIdx(pIdx); MIRFunction *callee = GlobalTables::GetFunctionTable().GetFuncTable()[pIdx]; + callee->GetFuncSymbol()->SetAppearsInCode(true); if (callee->GetName() == "setjmp") { mod.CurFunction()->SetHasSetjmp(); } @@ -932,9 +933,14 @@ bool MIRParser::ParseStmtIcall(StmtNodePtr &stmt, Opcode op) { // . . . // dassign } // icallproto (, , ..., ) + // icallprotoassigned (, , ..., ) { + // dassign + // dassign + // . . . + // dassign } IcallNode *iCallStmt = mod.CurFuncCodeMemPool()->New(mod, op); lexer.NextToken(); - if (op == OP_icallproto) { + if (op == OP_icallproto || op == OP_icallprotoassigned) { TyIdx tyIdx(0); if (!ParseDerivedType(tyIdx)) { Error("error parsing type in ParseStmtIcall for icallproto at "); @@ -948,7 +954,7 @@ bool MIRParser::ParseStmtIcall(StmtNodePtr &stmt, Opcode op) { } iCallStmt->SetNOpnd(opndsVec); iCallStmt->SetNumOpnds(opndsVec.size()); - if (op == OP_icallassigned) { + if (op == OP_icallassigned || op == OP_icallprotoassigned) { CallReturnVector retsVec(mod.CurFuncCodeMemPoolAllocator()->Adapter()); if (!ParseCallReturns(retsVec)) { return false; @@ -972,6 +978,10 @@ bool MIRParser::ParseStmtIcallproto(StmtNodePtr &stmt) { return ParseStmtIcall(stmt, OP_icallproto); } +bool MIRParser::ParseStmtIcallprotoassigned(StmtNodePtr &stmt) { + return ParseStmtIcall(stmt, OP_icallprotoassigned); +} + bool MIRParser::ParseStmtIntrinsiccall(StmtNodePtr &stmt, bool isAssigned) { Opcode o = !isAssigned ? (lexer.GetTokenKind() == TK_intrinsiccall ? OP_intrinsiccall : OP_xintrinsiccall) : (lexer.GetTokenKind() == TK_intrinsiccallassigned ? OP_intrinsiccallassigned @@ -2013,18 +2023,6 @@ bool MIRParser::ParseStmtBlockForUpformalSize() { return true; } -bool MIRParser::ParseStmtBlockForOutParmSize() { - MIRFunction *fn = paramCurrFuncForParseStmtBlock; - lexer.NextToken(); - if (lexer.GetTokenKind() != TK_intconst) { - Error("expect integer after outparmsize but get "); - return false; - } - fn->SetOutParmSize(static_cast(lexer.GetTheIntVal())); - lexer.NextToken(); - return true; -} - bool MIRParser::ParseStmtBlockForModuleID() { MIRFunction *fn = paramCurrFuncForParseStmtBlock; lexer.NextToken(); @@ -3241,7 +3239,8 @@ bool MIRParser::ParseConstAddrLeafExpr(MIRConstPtr &cexpr) { } else if (expr->GetOpCode() == OP_addroffunc) { auto *aof = static_cast(expr); MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(aof->GetPUIdx()); - const MIRSymbol *fName = f->GetFuncSymbol(); + MIRSymbol *fName = f->GetFuncSymbol(); + fName->SetAppearsInCode(true); TyIdx ptyIdx = fName->GetTyIdx(); MIRPtrType ptrType(ptyIdx); ptyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&ptrType); @@ -3415,6 +3414,7 @@ std::map MIRParser::InitFuncPtrMapForPar funcPtrMap[TK_icall] = &MIRParser::ParseStmtIcall; funcPtrMap[TK_icallassigned] = &MIRParser::ParseStmtIcallassigned; funcPtrMap[TK_icallproto] = &MIRParser::ParseStmtIcallproto; + funcPtrMap[TK_icallprotoassigned] = &MIRParser::ParseStmtIcallprotoassigned; funcPtrMap[TK_intrinsiccall] = &MIRParser::ParseStmtIntrinsiccall; funcPtrMap[TK_intrinsiccallassigned] = &MIRParser::ParseStmtIntrinsiccallassigned; funcPtrMap[TK_xintrinsiccall] = &MIRParser::ParseStmtIntrinsiccall; @@ -3475,7 +3475,6 @@ std::map MIRParser::InitFuncPtrMapF funcPtrMap[TK_type] = &MIRParser::ParseStmtBlockForType; funcPtrMap[TK_framesize] = &MIRParser::ParseStmtBlockForFrameSize; funcPtrMap[TK_upformalsize] = &MIRParser::ParseStmtBlockForUpformalSize; - funcPtrMap[TK_outparmsize] = &MIRParser::ParseStmtBlockForOutParmSize; funcPtrMap[TK_moduleid] = &MIRParser::ParseStmtBlockForModuleID; funcPtrMap[TK_funcsize] = &MIRParser::ParseStmtBlockForFuncSize; funcPtrMap[TK_funcid] = &MIRParser::ParseStmtBlockForFuncID; diff --git a/src/mapleall/maple_ir/src/mir_type.cpp b/src/mapleall/maple_ir/src/mir_type.cpp index 0c9ff37468..6dac1d09d5 100644 --- a/src/mapleall/maple_ir/src/mir_type.cpp +++ b/src/mapleall/maple_ir/src/mir_type.cpp @@ -738,7 +738,9 @@ void MIRFuncType::Dump(int indent, bool dontUseName) const { if (!dontUseName && CheckAndDumpTypeName(nameStrIdx, nameIsLocal)) { return; } - LogInfo::MapleLogger() << "Dump(indent + 1); @@ -749,7 +751,7 @@ void MIRFuncType::Dump(int indent, bool dontUseName) const { LogInfo::MapleLogger() << ","; } } - if (isVarArgs) { + if (IsVarargs()) { LogInfo::MapleLogger() << ", ..."; } LogInfo::MapleLogger() << ") "; @@ -1663,7 +1665,7 @@ bool MIRFuncType::EqualTo(const MIRType &type) const { } const auto &pType = static_cast(type); return (pType.retTyIdx == retTyIdx && pType.paramTypeList == paramTypeList && - pType.isVarArgs == isVarArgs && pType.paramAttrsList == paramAttrsList && + pType.funcAttrs == funcAttrs && pType.paramAttrsList == paramAttrsList && pType.retAttrs == retAttrs); } diff --git a/src/mapleall/maple_ir/src/parser.cpp b/src/mapleall/maple_ir/src/parser.cpp index db50916351..e8c9178367 100644 --- a/src/mapleall/maple_ir/src/parser.cpp +++ b/src/mapleall/maple_ir/src/parser.cpp @@ -229,9 +229,7 @@ bool MIRParser::ParsePseudoReg(PrimType primType, PregIdx &pRegIdx) { MIRPreg *preg = curfunc->GetPregTab()->PregFromPregIdx(pRegIdx); if (primType != kPtyInvalid) { if (preg->GetPrimType() != primType) { - if ((primType == PTY_ref || primType == PTY_ptr) && - (preg->GetPrimType() == PTY_ref || preg->GetPrimType() == PTY_ptr)) { - ; // PTY_ref and PTY_ptr are compatible with each other + if (IsAddress(preg->GetPrimType()) && IsAddress(primType)) { } else { Error("inconsistent preg primitive type at "); return false; @@ -1299,6 +1297,15 @@ bool MIRParser::ParsePointType(TyIdx &tyIdx) { // in function pointer specification and member function prototypes inside // structs and classes bool MIRParser::ParseFuncType(TyIdx &tyIdx) { + // parse function attributes + FuncAttrs fAttrs; + if (lexer.GetTokenKind() != TK_lparen) { + if (!ParseFuncAttrs(fAttrs)) { + Error("bad function attribute specification in function type at "); + return false; + } + } + // parse parameters if (lexer.GetTokenKind() != TK_lparen) { Error("expect ( parse function type parameters but get "); @@ -1359,7 +1366,10 @@ bool MIRParser::ParseFuncType(TyIdx &tyIdx) { return false; } MIRFuncType functype(retTyIdx, vecTyIdx, vecAttrs, retTypeAttrs); - functype.SetVarArgs(varargs); + functype.funcAttrs = fAttrs; + if (varargs) { + functype.SetVarArgs(); + } tyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&functype); return true; } diff --git a/src/mapleall/maple_me/include/lmbc_lower.h b/src/mapleall/maple_me/include/lmbc_lower.h index 9462204fd7..bbeaabf098 100644 --- a/src/mapleall/maple_me/include/lmbc_lower.h +++ b/src/mapleall/maple_me/include/lmbc_lower.h @@ -40,10 +40,7 @@ class LMBCLowerer { void LowerIassign(IassignNode *, BlockNode *); void LowerAggIassign(IassignNode *, MIRType *type, int32 offset, BlockNode *); void LowerReturn(NaryStmtNode *retNode, BlockNode *newblk); - MIRFuncType *FuncTypeFromFuncPtrExpr(BaseNode *x); - void LowerCall(NaryStmtNode *callNode, BlockNode *newblk); BlockNode *LowerBlock(BlockNode *); - void LoadFormalsAssignedToPregs(); void LowerFunction(); MIRModule *mirModule; diff --git a/src/mapleall/maple_me/include/lmbc_memlayout.h b/src/mapleall/maple_me/include/lmbc_memlayout.h index 68253bb226..833b357561 100644 --- a/src/mapleall/maple_me/include/lmbc_memlayout.h +++ b/src/mapleall/maple_me/include/lmbc_memlayout.h @@ -31,8 +31,8 @@ typedef enum { MS_actual, // for the outgoing parameters MS_local, // for all local variables and temporaries MS_FPbased, // addressed via offset from the frame pointer - MS_SPbased, // addressed via offset from the stack pointer MS_GPbased, // addressed via offset from the global pointer + MS_largeStructActual, // for storing large struct actuals passed by value for ARM CPU } MemSegmentKind; class MemSegment; @@ -66,15 +66,10 @@ class MemSegment { class LMBCMemLayout { public: - uint32 FindLargestActualArea(void); - uint32 FindLargestActualArea(StmtNode *, int &); - LMBCMemLayout(MIRFunction *f, MapleAllocator *mallocator) + LMBCMemLayout(MIRFunction *f, MemSegment *segGP, MapleAllocator *mallocator) : func(f), - seg_upformal(MS_upformal), - seg_formal(MS_formal), - seg_actual(MS_actual), + seg_GPbased(segGP), seg_FPbased(MS_FPbased), - seg_SPbased(MS_SPbased), sym_alloc_table(mallocator->Adapter()) { sym_alloc_table.resize(f->GetSymTab()->GetSymbolTableSize()); } @@ -85,70 +80,25 @@ class LMBCMemLayout { void LayoutStackFrame(void); int32 StackFrameSize(void) const { - return seg_SPbased.size - seg_FPbased.size; - } - - int32 UpformalSize(void) const { - return seg_upformal.size; + return -seg_FPbased.size; } MIRFunction *func; - MemSegment seg_upformal; - MemSegment seg_formal; - MemSegment seg_actual; + MemSegment *seg_GPbased; MemSegment seg_FPbased; - MemSegment seg_SPbased; MapleVector sym_alloc_table; // index is StIdx }; class GlobalMemLayout { public: - GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAllocator *mallocator); - ~GlobalMemLayout() { - be = nullptr; - mirModule = nullptr; - } + GlobalMemLayout(MIRModule *mod, MapleAllocator *mallocator); + ~GlobalMemLayout() {} MemSegment seg_GPbased; MapleVector sym_alloc_table; // index is StIdx - - private: - void FillScalarValueInMap(uint32 startaddress, PrimType pty, MIRConst *c); - void FillTypeValueInMap(uint32 startaddress, MIRType *ty, MIRConst *c); - void FillSymbolValueInMap(const MIRSymbol *sym); - - maplebe::BECommon *be; MIRModule *mirModule; }; -// for specifying how a parameter is passed -struct PLocInfo { - int32 memoffset; - int32 memsize; -}; - -// for processing an incoming or outgoing parameter list -class ParmLocator { - public: - explicit ParmLocator() : parmNum(0), lastMemOffset(0) {} - - ~ParmLocator() {} - - void LocateNextParm(const MIRType *ty, PLocInfo &ploc); - - private: - int32 parmNum; // number of all types of parameters processed so far - int32 lastMemOffset; -}; - -// given the type of the return value, determines the return mechanism -class ReturnMechanism { - public: - ReturnMechanism(const MIRType *retty); - bool fake_first_parm; // whether returning in memory via fake first parameter - PrimType ptype0; // the primitive type stored in retval0 -}; - } /* namespace maple */ #endif /* MAPLEME_INCLUDE_LMBC_MEMLAYOUT_H */ diff --git a/src/mapleall/maple_me/src/alias_class.cpp b/src/mapleall/maple_me/src/alias_class.cpp index 368effe2b9..6be86e59fa 100644 --- a/src/mapleall/maple_me/src/alias_class.cpp +++ b/src/mapleall/maple_me/src/alias_class.cpp @@ -1018,7 +1018,9 @@ void AliasClass::ApplyUnionForCopies(StmtNode &stmt) { } case OP_asm: case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { for (uint32 i = 0; i < stmt.NumOpnds(); ++i) { const AliasInfo &ainfo = CreateAliasInfoExpr(*stmt.Opnd(i)); if (stmt.GetOpCode() != OP_asm && i == 0) { @@ -2569,6 +2571,7 @@ void AliasClass::GenericInsertMayDefUse(StmtNode &stmt, BBId bbID) { case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_virtualcall: case OP_virtualicall: case OP_superclasscall: @@ -2576,7 +2579,8 @@ void AliasClass::GenericInsertMayDefUse(StmtNode &stmt, BBId bbID) { case OP_interfaceicall: case OP_customcall: case OP_polymorphiccall: - case OP_icall: { + case OP_icall: + case OP_icallproto: { InsertMayDefUseCall(stmt, bbID, false); return; } diff --git a/src/mapleall/maple_me/src/code_factoring.cpp b/src/mapleall/maple_me/src/code_factoring.cpp index 175cead017..21f3103b3a 100644 --- a/src/mapleall/maple_me/src/code_factoring.cpp +++ b/src/mapleall/maple_me/src/code_factoring.cpp @@ -126,7 +126,9 @@ bool FactoringOptimizer::IsIdenticalStmt(StmtNode *stmt1, StmtNode *stmt2) { break; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { auto *icall1 = static_cast(stmt1); auto *icall2 = static_cast(stmt2); if (icall1->GetRetTyIdx() != icall2->GetRetTyIdx() || diff --git a/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp b/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp index 2bb97532a6..ba545a5991 100644 --- a/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp +++ b/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp @@ -642,7 +642,9 @@ void PEGBuilder::BuildPEGNodeInStmt(const StmtNode *stmt) { break; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { BuildPEGNodeInIcall(static_cast(stmt)); break; } diff --git a/src/mapleall/maple_me/src/irmap_build.cpp b/src/mapleall/maple_me/src/irmap_build.cpp index 92eece9fa0..b6d96b6726 100755 --- a/src/mapleall/maple_me/src/irmap_build.cpp +++ b/src/mapleall/maple_me/src/irmap_build.cpp @@ -808,7 +808,7 @@ MeStmt *IRMapBuild::BuildCallMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { MeStmt *IRMapBuild::BuildNaryMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { Opcode op = stmt.GetOpCode(); - NaryMeStmt *naryMeStmt = (op == OP_icall || op == OP_icallassigned) + NaryMeStmt *naryMeStmt = (op == OP_icall || op == OP_icallassigned || op == OP_icallproto || op == OP_icallprotoassigned) ? static_cast(irMap->NewInPool(&stmt)) : static_cast(irMap->NewInPool(&stmt)); auto &naryStmtNode = static_cast(stmt); @@ -823,6 +823,9 @@ MeStmt *IRMapBuild::BuildNaryMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { if (propagater) { propagater->PropUpdateChiListDef(*naryMeStmt->GetChiList()); } + if (op == OP_icallproto || op == OP_icallprotoassigned) { + static_cast(naryMeStmt)->SetRetTyIdx(static_cast(stmt).GetRetTyIdx()); + } return naryMeStmt; } @@ -923,6 +926,8 @@ void IRMapBuild::InitMeStmtFactory() { RegisterFactoryFunction(OP_polymorphiccallassigned, &IRMapBuild::BuildCallMeStmt); RegisterFactoryFunction(OP_icall, &IRMapBuild::BuildNaryMeStmt); RegisterFactoryFunction(OP_icallassigned, &IRMapBuild::BuildNaryMeStmt); + RegisterFactoryFunction(OP_icallproto, &IRMapBuild::BuildNaryMeStmt); + RegisterFactoryFunction(OP_icallprotoassigned, &IRMapBuild::BuildNaryMeStmt); RegisterFactoryFunction(OP_intrinsiccall, &IRMapBuild::BuildNaryMeStmt); RegisterFactoryFunction(OP_xintrinsiccall, &IRMapBuild::BuildNaryMeStmt); RegisterFactoryFunction(OP_intrinsiccallwithtype, &IRMapBuild::BuildNaryMeStmt); diff --git a/src/mapleall/maple_me/src/irmap_emit.cpp b/src/mapleall/maple_me/src/irmap_emit.cpp index 1f5f45518c..f6d7b046d8 100755 --- a/src/mapleall/maple_me/src/irmap_emit.cpp +++ b/src/mapleall/maple_me/src/irmap_emit.cpp @@ -412,7 +412,7 @@ MIRFunction &CallMeStmt::GetTargetFunction() { } StmtNode &CallMeStmt::EmitStmt(SSATab &ssaTab) { - if (GetOp() != OP_icall && GetOp() != OP_icallassigned) { + if (GetOp() != OP_icall && GetOp() != OP_icallassigned && GetOp() != OP_icallproto && GetOp() != OP_icallprotoassigned) { auto *callNode = ssaTab.GetModule().CurFunction()->GetCodeMempool()->New(ssaTab.GetModule(), Opcode(GetOp())); callNode->SetPUIdx(puIdx); @@ -497,6 +497,9 @@ StmtNode &IcallMeStmt::EmitStmt(SSATab &ssaTab) { } } } + if (GetOp() == OP_icallproto || GetOp() == OP_icallprotoassigned) { + icallNode->SetRetTyIdx(retTyIdx); + } return *icallNode; } diff --git a/src/mapleall/maple_me/src/lfo_dep_test.cpp b/src/mapleall/maple_me/src/lfo_dep_test.cpp index b1273a8fc3..33f19ee452 100644 --- a/src/mapleall/maple_me/src/lfo_dep_test.cpp +++ b/src/mapleall/maple_me/src/lfo_dep_test.cpp @@ -66,6 +66,8 @@ void LfoDepInfo::CreateDoloopInfo(BlockNode *block, DoloopInfo *parent) { case OP_callassigned: case OP_icall: case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: case OP_return: case OP_throw: case OP_asm: diff --git a/src/mapleall/maple_me/src/lmbc_lower.cpp b/src/mapleall/maple_me/src/lmbc_lower.cpp index a155b25fa4..f5893447ba 100644 --- a/src/mapleall/maple_me/src/lmbc_lower.cpp +++ b/src/mapleall/maple_me/src/lmbc_lower.cpp @@ -22,16 +22,12 @@ using namespace std; PregIdx LMBCLowerer::GetSpecialRegFromSt(const MIRSymbol *sym) { MIRStorageClass storageClass = sym->GetStorageClass(); PregIdx specreg = 0; - if (storageClass == kScAuto || storageClass == kScFormal) { + if (storageClass == kScAuto) { CHECK(sym->GetStIndex() < memlayout->sym_alloc_table.size(), "index out of range in LMBCLowerer::GetSpecialRegFromSt"); SymbolAlloc symalloc = memlayout->sym_alloc_table[sym->GetStIndex()]; - if (symalloc.mem_segment->kind == MS_upformal || symalloc.mem_segment->kind == MS_formal || - symalloc.mem_segment->kind == MS_FPbased) { + if (symalloc.mem_segment->kind == MS_FPbased) { specreg = -kSregFp; - } else if (symalloc.mem_segment->kind == MS_actual || - symalloc.mem_segment->kind == MS_SPbased) { - specreg = -kSregSp; } else { CHECK_FATAL(false, "LMBCLowerer::LowerDread: bad memory layout for local variable"); } @@ -46,6 +42,7 @@ PregIdx LMBCLowerer::GetSpecialRegFromSt(const MIRSymbol *sym) { BaseNode *LMBCLowerer::LowerAddrof(AddrofNode *expr) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(expr->GetStIdx()); + symbol->ResetIsDeleted(); int32 offset = 0; if (expr->GetFieldID() != 0) { MIRStructType *structty = static_cast(symbol->GetType()); @@ -66,6 +63,7 @@ BaseNode *LMBCLowerer::LowerAddrof(AddrofNode *expr) { BaseNode *LMBCLowerer::LowerDread(AddrofNode *expr) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(expr->GetStIdx()); + symbol->ResetIsDeleted(); PrimType symty = symbol->GetType()->GetPrimType(); int32 offset = 0; if (expr->GetFieldID() != 0) { @@ -96,20 +94,22 @@ BaseNode *LMBCLowerer::LowerDread(AddrofNode *expr) { BaseNode *LMBCLowerer::LowerDreadoff(DreadoffNode *dreadoff) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dreadoff->stIdx); + symbol->ResetIsDeleted(); if (!symbol->LMBCAllocateOffSpecialReg()) { return dreadoff; } + PrimType symty = symbol->GetType()->GetPrimType(); PregIdx spcreg = GetSpecialRegFromSt(symbol); if (spcreg == -kSregFp) { CHECK_FATAL(symbol->IsLocal(), "load from fp non local?"); - IreadFPoffNode *ireadoff = mirBuilder->CreateExprIreadFPoff( - dreadoff->GetPrimType(), memlayout->sym_alloc_table[symbol->GetStIndex()].offset + dreadoff->offset); + IreadFPoffNode *ireadoff = mirBuilder->CreateExprIreadFPoff(symty, + memlayout->sym_alloc_table[symbol->GetStIndex()].offset + dreadoff->offset); return ireadoff; } else { BaseNode *rrn = mirBuilder->CreateExprRegread(LOWERED_PTR_TYPE, spcreg); SymbolAlloc &symalloc = symbol->IsLocal() ? memlayout->sym_alloc_table[symbol->GetStIndex()] : globmemlayout->sym_alloc_table[symbol->GetStIndex()]; - IreadoffNode *ireadoff = mirBuilder->CreateExprIreadoff(dreadoff->GetPrimType(), symalloc.offset + dreadoff->offset, rrn); + IreadoffNode *ireadoff = mirBuilder->CreateExprIreadoff(symty, symalloc.offset + dreadoff->offset, rrn); return ireadoff; } } @@ -129,14 +129,14 @@ static MIRType *GetPointedToType(const MIRPtrType *pointerty) { BaseNode *LMBCLowerer::LowerIread(IreadNode *expr) { int32 offset = 0; + MIRPtrType *ptrType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(expr->GetTyIdx())); + MIRType *type = ptrType->GetPointedType(); if (expr->GetFieldID() != 0) { - MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(expr->GetTyIdx()); - MIRStructType *structty = - static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(type)->GetPointedTyIdx())); + MIRStructType *structty = static_cast(type); offset = becommon->GetFieldOffset(*structty, expr->GetFieldID()).first; + type = structty->GetFieldType(expr->GetFieldID()); } - BaseNode *ireadoff = mirBuilder->CreateExprIreadoff(expr->GetPrimType(), offset, expr->Opnd(0)); + BaseNode *ireadoff = mirBuilder->CreateExprIreadoff(type->GetPrimType(), offset, expr->Opnd(0)); return ireadoff; } @@ -165,6 +165,7 @@ BaseNode *LMBCLowerer::LowerExpr(BaseNode *expr) { return LowerAddrof(static_cast(expr)); case OP_addrofoff: { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(static_cast(expr)->stIdx); + symbol->ResetIsDeleted(); CHECK_FATAL(!symbol->LMBCAllocateOffSpecialReg(), "LMBCLowerer:: illegal addrofoff instruction"); break; @@ -199,6 +200,7 @@ void LMBCLowerer::LowerAggDassign(const DassignNode *dsnode, MIRType *lhsty, // generate lhs address expression BaseNode *lhs = nullptr; MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dsnode->GetStIdx()); + symbol->ResetIsDeleted(); if (!symbol->LMBCAllocateOffSpecialReg()) { lhs = mirBuilder->CreateExprDreadoff(OP_addrofoff, LOWERED_PTR_TYPE, *symbol, offset); } else { @@ -218,6 +220,7 @@ void LMBCLowerer::LowerAggDassign(const DassignNode *dsnode, MIRType *lhsty, void LMBCLowerer::LowerDassign(DassignNode *dsnode, BlockNode *newblk) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dsnode->GetStIdx()); + symbol->ResetIsDeleted(); MIRType *symty = symbol->GetType(); int32 offset = 0; if (dsnode->GetFieldID() != 0) { @@ -259,6 +262,7 @@ void LMBCLowerer::LowerDassign(DassignNode *dsnode, BlockNode *newblk) { void LMBCLowerer::LowerDassignoff(DassignoffNode *dsnode, BlockNode *newblk) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dsnode->stIdx); + symbol->ResetIsDeleted(); CHECK_FATAL(dsnode->Opnd(0)->GetPrimType() != PTY_agg, "LowerDassignoff: agg primitive type NYI"); BaseNode *rhs = LowerExpr(dsnode->Opnd(0)); if (!symbol->LMBCAllocateOffSpecialReg()) { @@ -334,6 +338,9 @@ void LMBCLowerer::LowerIassign(IassignNode *iassign, BlockNode *newblk) { } if (iassign->GetRHS()->GetPrimType() != PTY_agg) { PrimType ptypused = type->GetPrimType(); + if (ptypused == PTY_agg) { + ptypused = iassign->GetRHS()->GetPrimType(); + } IassignoffNode *iassignoff = mirBuilder->CreateStmtIassignoff(ptypused, offset, iassign->addrExpr, @@ -347,15 +354,20 @@ void LMBCLowerer::LowerIassign(IassignNode *iassign, BlockNode *newblk) { // called only if the return has > 1 operand; assume prior lowering already // converted any return of structs to be via fake parameter void LMBCLowerer::LowerReturn(NaryStmtNode *retNode, BlockNode *newblk) { - CHECK_FATAL(retNode->NumOpnds() <= 2, "LMBCLowerer::LowerReturn: more than 2 return values NYI"); - for (int i = 0; i < retNode->NumOpnds(); i++) { - CHECK_FATAL(retNode->Opnd(i)->GetPrimType() != PTY_agg, - "LMBCLowerer::LowerReturn: return of aggregate needs to be handled first"); - // insert regassign for the returned value - BaseNode *rhs = LowerExpr(retNode->Opnd(i)); - RegassignNode *regasgn = mirBuilder->CreateStmtRegassign(rhs->GetPrimType(), - i == 0 ? -kSregRetval0 : -kSregRetval1, - rhs); + if (retNode->Opnd(0)->GetPrimType() != PTY_agg) { + CHECK_FATAL(retNode->NumOpnds() <= 2, "LMBCLowerer::LowerReturn: more than 2 return values NYI"); + for (int i = 0; i < retNode->NumOpnds(); i++) { + // insert regassign for the returned value + PrimType ptyp = retNode->Opnd(i)->GetPrimType(); + BaseNode *rhs = LowerExpr(retNode->Opnd(i)); + RegassignNode *regasgn = mirBuilder->CreateStmtRegassign(ptyp, + i == 0 ? -kSregRetval0 : -kSregRetval1, + rhs); + newblk->AddStatement(regasgn); + } + } else { // handle return of small struct using only %%retval0 + BaseNode *rhs = LowerExpr(retNode->Opnd(0)); + RegassignNode *regasgn = mirBuilder->CreateStmtRegassign(PTY_agg, -kSregRetval0, rhs); newblk->AddStatement(regasgn); } retNode->GetNopnd().clear(); // remove the return operands @@ -363,178 +375,6 @@ void LMBCLowerer::LowerReturn(NaryStmtNode *retNode, BlockNode *newblk) { newblk->AddStatement(retNode); } -MIRFuncType *LMBCLowerer::FuncTypeFromFuncPtrExpr(BaseNode *x) { - MIRFuncType *res = nullptr; - switch (x->GetOpCode()) { - case OP_regread: { - RegreadNode *regread = static_cast(x); - MIRPreg *preg = func->GetPregTab()->PregFromPregIdx(regread->GetRegIdx()); - // see if it is promoted from a symbol - if (preg->GetOp() == OP_dread) { - const MIRSymbol *symbol = preg->rematInfo.sym; - MIRType *mirType = symbol->GetType(); - if (preg->fieldID != 0) { - MIRStructType *structty = static_cast(mirType); - FieldPair thepair = structty->TraverseToField(preg->fieldID); - mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - if (res != nullptr) { - break; - } - } - // check if a formal promoted to preg - for (FormalDef &formalDef : func->GetFormalDefVec()) { - if (!formalDef.formalSym->IsPreg()) { - continue; - } - if (formalDef.formalSym->GetPreg() == preg) { - MIRType *mirType = formalDef.formalSym->GetType(); - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - break; - } - } - break; - } - case OP_dread: { - DreadNode *dread = static_cast(x); - MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); - MIRType *mirType = symbol->GetType(); - if (dread->GetFieldID() != 0) { - MIRStructType *structty = static_cast(mirType); - FieldPair thepair = structty->TraverseToField(dread->GetFieldID()); - mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - break; - } - case OP_iread: { - IreadNode *iread = static_cast(x); - MIRPtrType *ptrType = static_cast(iread->GetType()); - MIRType *mirType = ptrType->GetPointedType(); - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - break; - } - case OP_addroffunc: { - AddroffuncNode *addrofFunc = static_cast(x); - PUIdx puIdx = addrofFunc->GetPUIdx(); - MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); - res = f->GetMIRFuncType(); - break; - } - case OP_retype: { - MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(x)->GetTyIdx()); - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - if (res == nullptr) { - res = FuncTypeFromFuncPtrExpr(x->Opnd(0)); - } - break; - } - case OP_select: { - res = FuncTypeFromFuncPtrExpr(x->Opnd(1)); - if (res == nullptr) { - res = FuncTypeFromFuncPtrExpr(x->Opnd(2)); - } - break; - } - default: CHECK_FATAL(false, "LMBCLowerer::FuncTypeFromFuncPtrExpr: NYI"); - } - return res; -} - -void LMBCLowerer::LowerCall(NaryStmtNode *naryStmt, BlockNode *newblk) { - // go through each parameter - uint32 i = 0; - if (naryStmt->GetOpCode() == OP_icall || naryStmt->GetOpCode() == OP_icallassigned) { - i = 1; - } - ParmLocator parmlocator; - for (; i < naryStmt->NumOpnds(); i++) { - BaseNode *opnd = naryStmt->Opnd(i); - MIRType *ty = nullptr; - // get ty for this parameter - if (opnd->GetPrimType() != PTY_agg) { - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(static_cast(opnd->GetPrimType())); - } else { - Opcode opnd_opcode = opnd->GetOpCode(); - CHECK_FATAL(opnd_opcode == OP_dread || opnd_opcode == OP_iread, ""); - if (opnd_opcode == OP_dread) { - AddrofNode *dread = static_cast(opnd); - MIRSymbol *sym = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx()); - if (dread->GetFieldID() != 0) { - CHECK_FATAL(ty->IsStructType(), ""); - FieldPair thepair = static_cast(ty)->TraverseToField(dread->GetFieldID()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - } else { // OP_iread - IreadNode *iread = static_cast(opnd); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread->GetTyIdx()); - CHECK_FATAL(ty->GetKind() == kTypePointer, ""); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(ty)->GetPointedTyIdx()); - if (iread->GetFieldID() != 0) { - CHECK_FATAL(ty->IsStructType(), ""); - FieldPair thepair = static_cast(ty)->TraverseToField(iread->GetFieldID()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - } - } - PLocInfo ploc; - parmlocator.LocateNextParm(ty, ploc); - if (opnd->GetPrimType() != PTY_agg) { - IassignFPoffNode *iass = mirBuilder->CreateStmtIassignFPoff(OP_iassignspoff, - opnd->GetPrimType(), - ploc.memoffset, - LowerExpr(opnd)); - newblk->AddStatement(iass); - } else { - BlkassignoffNode *bass = - mirModule->CurFuncCodeMemPool()->New(ploc.memoffset, ploc.memsize); - bass->SetAlign(std::min(ty->GetAlign(), 8u)); - bass->SetBOpnd(mirBuilder->CreateExprRegread(LOWERED_PTR_TYPE, -kSregSp), 0); - // the operand is either OP_dread or OP_iread; use its address instead - if (opnd->GetOpCode() == OP_dread) { - opnd->SetOpCode(OP_addrof); - } else { - opnd->SetOpCode(OP_iaddrof); - } - opnd->SetPrimType(LOWERED_PTR_TYPE); - bass->SetBOpnd(LowerExpr(opnd), 1); - newblk->AddStatement(bass); - } - } - BaseNode *opnd0 = nullptr; - if (naryStmt->GetOpCode() == OP_icall || naryStmt->GetOpCode() == OP_icallassigned) { - opnd0 = naryStmt->Opnd(0); - naryStmt->GetNopnd().clear(); // remove the call operands - // convert to OP_icallproto by finding the function prototype and record in stmt - naryStmt->SetOpCode(OP_icallproto); - MIRFuncType *funcType = FuncTypeFromFuncPtrExpr(opnd0); - CHECK_FATAL(funcType != nullptr, "LMBCLowerer::LowerCall: cannot find prototype for icall"); - static_cast(naryStmt)->SetRetTyIdx(funcType->GetTypeIndex()); - // add back the function pointer operand - naryStmt->GetNopnd().push_back(LowerExpr(opnd0)); - naryStmt->SetNumOpnds(1); - } else { - naryStmt->GetNopnd().clear(); // remove the call operands - naryStmt->SetNumOpnds(0); - } - newblk->AddStatement(naryStmt); -} - BlockNode *LMBCLowerer::LowerBlock(BlockNode *block) { BlockNode *newblk = mirModule->CurFuncCodeMemPool()->New(); if (!block->GetFirst()) { @@ -569,10 +409,6 @@ BlockNode *LMBCLowerer::LowerBlock(BlockNode *block) { } else { LowerReturn(retNode, newblk); } - } - case OP_call: - case OP_icall: { - LowerCall(static_cast(stmt), newblk); break; } default: { @@ -587,29 +423,19 @@ BlockNode *LMBCLowerer::LowerBlock(BlockNode *block) { return newblk; } -void LMBCLowerer::LoadFormalsAssignedToPregs() { - // go through each formals - for (int32 i = func->GetFormalDefVec().size()-1; i >= 0; i--) { - MIRSymbol *formalSt = func->GetFormalDefVec()[i].formalSym; - if (formalSt->GetSKind() != kStPreg) { - continue; +void LMBCLowerer::LowerFunction() { + // set extern global vars' isDeleted field; will reset when visited + MapleVector::const_iterator sit = mirModule->GetSymbolDefOrder().begin(); + for (; sit != mirModule->GetSymbolDefOrder().end(); ++sit) { + MIRSymbol *s = GlobalTables::GetGsymTable().GetSymbolFromStidx(sit->Idx()); + if (s->GetSKind() == kStVar && s->GetStorageClass() == kScExtern && !s->HasPotentialAssignment()) { + s->SetIsDeleted(); } - MIRPreg *preg = formalSt->GetPreg(); - uint32 stindex = formalSt->GetStIndex(); - PrimType pty = formalSt->GetType()->GetPrimType(); - IreadFPoffNode *ireadfpoff = mirBuilder->CreateExprIreadFPoff(pty, - memlayout->sym_alloc_table[stindex].offset); - RegassignNode *rass = mirBuilder->CreateStmtRegassign(pty, - func->GetPregTab()->GetPregIdxFromPregno(preg->GetPregNo()), ireadfpoff); - func->GetBody()->InsertFirst(rass); } -} -void LMBCLowerer::LowerFunction() { BlockNode *origbody = func->GetBody(); BlockNode *newbody = LowerBlock(origbody); func->SetBody(newbody); - LoadFormalsAssignedToPregs(); } } // namespace maple diff --git a/src/mapleall/maple_me/src/lmbc_memlayout.cpp b/src/mapleall/maple_me/src/lmbc_memlayout.cpp index e740c5d13f..b32acae493 100644 --- a/src/mapleall/maple_me/src/lmbc_memlayout.cpp +++ b/src/mapleall/maple_me/src/lmbc_memlayout.cpp @@ -13,146 +13,40 @@ * See the MulanPSL - 2.0 for more details. */ -// For each function being compiled, lay out its parameters, return values and -// local variables on its stack frame. This involves determining how parameters -// and return values are passed from analyzing their types. -// -// Allocate all the global variables within the global memory block which is -// addressed via offset from the global pointer GP during execution. Allocate -// this block pointed to by mirModule.globalBlkMap and perform the static -// initializations. +// For each function being compiled, lay out its local variables on its stack +// frame. Allocate all the global variables within the global memory block +// which is addressed via offset from the global pointer GP during execution. +// Allocate this block pointed to by mirModule.globalBlkMap. #include "lmbc_memlayout.h" #include "mir_symbol.h" namespace maple { -uint32 LMBCMemLayout::FindLargestActualArea(StmtNode *stmt, int &maxActualSize) { - if (!stmt) { - return maxActualSize; - } - Opcode opcode = stmt->op; - switch (opcode) { - case OP_block: { - BlockNode *blcknode = static_cast(stmt); - for (StmtNode &s : blcknode->GetStmtNodes()) { - FindLargestActualArea(&s, maxActualSize); - } - break; - } - case OP_if: { - IfStmtNode *ifnode = static_cast(stmt); - FindLargestActualArea(ifnode->GetThenPart(), maxActualSize); - FindLargestActualArea(ifnode->GetElsePart(), maxActualSize); - break; - } - case OP_doloop: { - FindLargestActualArea(static_cast(stmt)->GetDoBody(), maxActualSize); - break; - } - case OP_dowhile: - case OP_while: - FindLargestActualArea(static_cast(stmt)->GetBody(), maxActualSize); - break; - case OP_call: - case OP_icall: - case OP_intrinsiccall: { - ParmLocator parmlocator; // instantiate a parm locator - NaryStmtNode *callstmt = static_cast(stmt); - for (uint32 i = 0; i < callstmt->NumOpnds(); i++) { - BaseNode *opnd = callstmt->Opnd(i); - CHECK_FATAL(opnd->GetPrimType() != PTY_void, ""); - MIRType *ty = nullptr; - if (opnd->GetPrimType() != PTY_agg) { - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(opnd->GetPrimType())); - } else { - Opcode opnd_opcode = opnd->GetOpCode(); - CHECK_FATAL(opnd_opcode == OP_dread || opnd_opcode == OP_iread, ""); - if (opnd_opcode == OP_dread) { - AddrofNode *dread = static_cast(opnd); - MIRSymbol *sym = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx()); - if (dread->GetFieldID() != 0) { - CHECK_FATAL(ty->IsStructType(), "expect struct or class or union"); - FieldPair thepair = - static_cast(ty)->TraverseToField(dread->GetFieldID()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - } else { // OP_iread - IreadNode *iread = static_cast(opnd); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread->GetTyIdx()); - CHECK_FATAL(ty->GetKind() == kTypePointer, ""); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(ty)->GetPointedTyIdx()); - if (iread->GetFieldID() != 0) { - CHECK_FATAL(ty->IsStructType(), "expect struct or class or union"); - FieldPair thepair = - static_cast(ty)->TraverseToField(iread->GetFieldID()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - } - } - PLocInfo ploc; - parmlocator.LocateNextParm(ty, ploc); - maxActualSize = std::max(maxActualSize, ploc.memoffset + ploc.memsize); - maxActualSize = maplebe::RoundUp(maxActualSize, GetPrimTypeSize(PTY_ptr)); - } - break; - } - default: - return maxActualSize; - } - maxActualSize = maplebe::RoundUp(maxActualSize, GetPrimTypeSize(PTY_ptr)); - return maxActualSize; -} - -// go over all outgoing calls in the function body and get the maximum space -// needed for storing the actuals based on the actual parameters and the ABI; -// this assumes that all nesting of statements has been removed, so that all -// the statements are at only one block level -uint32 LMBCMemLayout::FindLargestActualArea(void) { - int32 maxActualSize = 0; - FindLargestActualArea(func->GetBody(), maxActualSize); - return static_cast(maxActualSize); -} +constexpr size_t kVarargSaveAreaSize = 192; void LMBCMemLayout::LayoutStackFrame(void) { - MIRSymbol *sym = nullptr; - // go through formal parameters - ParmLocator parmlocator; // instantiate a parm locator - PLocInfo ploc; - for (uint32 i = 0; i < func->GetFormalDefVec().size(); i++) { - FormalDef formalDef = func->GetFormalDefAt(i); - sym = formalDef.formalSym; - MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(formalDef.formalTyIdx); - parmlocator.LocateNextParm(ty, ploc); - uint32 stindex = sym->GetStIndex(); - // always passed in memory, so allocate in seg_upformal - sym_alloc_table[stindex].mem_segment = &seg_upformal; - seg_upformal.size = maplebe::RoundUp(seg_upformal.size, ty->GetAlign()); - sym_alloc_table[stindex].offset = seg_upformal.size; - seg_upformal.size += ty->GetSize(); - seg_upformal.size = maplebe::RoundUp(seg_upformal.size, GetPrimTypeSize(PTY_ptr)); + if (func->IsVarargs()) { + seg_FPbased.size -= kVarargSaveAreaSize; } - // allocate seg_formal in seg_FPbased - seg_formal.how_alloc.mem_segment = &seg_FPbased; - seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, GetPrimTypeSize(PTY_ptr)); - seg_FPbased.size -= seg_formal.size; - seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, GetPrimTypeSize(PTY_ptr)); - seg_formal.how_alloc.offset = seg_FPbased.size; - // allocate the local variables uint32 symtabsize = func->GetSymTab()->GetSymbolTableSize(); for (uint32 i = 0; i < symtabsize; i++) { - sym = func->GetSymTab()->GetSymbolFromStIdx(i); + MIRSymbol *sym = func->GetSymTab()->GetSymbolFromStIdx(i); if (!sym) { continue; } if (sym->IsDeleted()) { continue; } + if (sym->GetStorageClass() == kScPstatic && sym->LMBCAllocateOffSpecialReg()) { + uint32 stindex = sym->GetStIndex(); + sym_alloc_table[stindex].mem_segment = seg_GPbased; + seg_GPbased->size = maplebe::RoundUp(seg_GPbased->size, sym->GetType()->GetAlign()); + sym_alloc_table[stindex].offset = seg_GPbased->size; + seg_GPbased->size += sym->GetType()->GetSize(); + } if (sym->GetStorageClass() != kScAuto) { continue; } @@ -162,160 +56,10 @@ void LMBCMemLayout::LayoutStackFrame(void) { seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, sym->GetType()->GetAlign()); sym_alloc_table[stindex].offset = seg_FPbased.size; } - seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, GetPrimTypeSize(PTY_ptr)); - - // allocate seg_actual for storing the outgoing parameters; this requires - // going over all outgoing calls and get the maximum space needed for the - // actuals - seg_actual.size = FindLargestActualArea(); - func->SetOutParmSize(seg_actual.size); - - // allocate seg_actual in seg_SPbased - seg_actual.how_alloc.mem_segment = &seg_SPbased; - seg_actual.how_alloc.offset = seg_SPbased.size; - seg_SPbased.size = maplebe::RoundUp(seg_SPbased.size, GetPrimTypeSize(PTY_ptr)); - seg_SPbased.size += seg_actual.size; - seg_SPbased.size = maplebe::RoundUp(seg_SPbased.size, GetPrimTypeSize(PTY_ptr)); -} - -inline uint8 GetU8Const(MIRConst *c) { - MIRIntConst *intconst = static_cast(c); - return static_cast(intconst->GetValue()); -} - -inline uint16 GetU16Const(MIRConst *c) { - MIRIntConst *intconst = static_cast(c); - return static_cast(intconst->GetValue()); -} - -inline uint32 GetU32Const(MIRConst *c) { - MIRIntConst *intconst = static_cast(c); - return static_cast(intconst->GetValue()); -} - -inline uint64 GetU64Const(MIRConst *c) { - MIRIntConst *intconst = static_cast(c); - return static_cast(intconst->GetValue()); -} - -inline uint32 GetF32Const(MIRConst *c) { - MIRFloatConst *floatconst = static_cast(c); - return static_cast(floatconst->GetIntValue()); -} - -inline uint64 GetF64Const(MIRConst *c) { - MIRDoubleConst *doubleconst = static_cast(c); - return static_cast(doubleconst->GetIntValue()); -} - -void GlobalMemLayout::FillScalarValueInMap(uint32 startaddress, PrimType pty, MIRConst *c) { - switch (pty) { - case PTY_u1: - case PTY_u8: - case PTY_i8: { - uint8 *p = &mirModule->GetGlobalBlockMap()[startaddress]; - *p = GetU8Const(c); - break; - } - case PTY_u16: - case PTY_i16: { - uint16 *p = (uint16 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetU16Const(c); - break; - } - case PTY_u32: - case PTY_i32: { - uint32 *p = (uint32 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetU32Const(c); - break; - } - case PTY_u64: - case PTY_i64: { - uint64 *p = (uint64 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetU64Const(c); - break; - } - case PTY_f32: { - uint32 *p = (uint32 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetF32Const(c); - break; - } - case PTY_f64: { - uint64 *p = (uint64 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetF64Const(c); - break; - } - default: - CHECK_FATAL(false, "FillScalarValueInMap: NYI"); - } - return; } -void GlobalMemLayout::FillTypeValueInMap(uint32 startaddress, MIRType *ty, MIRConst *c) { - switch (ty->GetKind()) { - case kTypeScalar: - FillScalarValueInMap(startaddress, ty->GetPrimType(), c); - break; - case kTypeArray: { - MIRArrayType *arraytype = static_cast(ty); - MIRType *elemtype = arraytype->GetElemType(); - int32 elemsize = elemtype->GetSize(); - MIRAggConst *aggconst = static_cast(c); - CHECK_FATAL(aggconst, "FillTypeValueInMap: inconsistent array initialization specification"); - MapleVector &constvec = aggconst->GetConstVec(); - for (MapleVector::iterator it = constvec.begin(); it != constvec.end(); - it++, startaddress += elemsize) { - FillTypeValueInMap(startaddress, elemtype, *it); - } - break; - } - case kTypeStruct: { - MIRStructType *structty = static_cast(ty); - MIRAggConst *aggconst = static_cast(c); - CHECK_FATAL(aggconst, "FillTypeValueInMap: inconsistent struct initialization specification"); - MapleVector &constvec = aggconst->GetConstVec(); - for (uint32 i = 0; i < constvec.size(); i++) { - uint32 fieldID = aggconst->GetFieldIdItem(i); - FieldPair thepair = structty->TraverseToField(fieldID); - MIRType *fieldty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - uint32 offset = be->GetFieldOffset(*structty, fieldID).first; - FillTypeValueInMap(startaddress + offset, fieldty, constvec[i]); - } - break; - } - case kTypeClass: { - MIRClassType *classty = static_cast(ty); - MIRAggConst *aggconst = static_cast(c); - CHECK_FATAL(aggconst, "FillTypeValueInMap: inconsistent class initialization specification"); - MapleVector &constvec = aggconst->GetConstVec(); - for (uint32 i = 0; i < constvec.size(); i++) { - uint32 fieldID = aggconst->GetFieldIdItem(i); - FieldPair thepair = classty->TraverseToField(fieldID); - MIRType *fieldty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - uint32 offset = be->GetFieldOffset(*classty, fieldID).first; - FillTypeValueInMap(startaddress + offset, fieldty, constvec[i]); - } - break; - } - default: - CHECK_FATAL(false, "FillTypeValueInMap: NYI"); - } -} - -void GlobalMemLayout::FillSymbolValueInMap(const MIRSymbol *sym) { - if (sym->GetKonst() == nullptr) { - return; - } - uint32 stindex = sym->GetStIndex(); - CHECK(stindex < sym_alloc_table.size(), - "index out of range in GlobalMemLayout::FillSymbolValueInMap"); - uint32 symaddress = sym_alloc_table[stindex].offset; - FillTypeValueInMap(symaddress, sym->GetType(), sym->GetKonst()); - return; -} - -GlobalMemLayout::GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAllocator *mallocator) : - seg_GPbased(MS_GPbased), sym_alloc_table(mallocator->Adapter()), be(b), mirModule(mod) { +GlobalMemLayout::GlobalMemLayout(MIRModule *mod, MapleAllocator *mallocator) : + seg_GPbased(MS_GPbased), sym_alloc_table(mallocator->Adapter()), mirModule(mod) { uint32 symtabsize = GlobalTables::GetGsymTable().GetSymbolTableSize(); sym_alloc_table.resize(symtabsize); MIRSymbol *sym = nullptr; @@ -329,6 +73,9 @@ GlobalMemLayout::GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAll if (sym->GetStorageClass() != kScGlobal && sym->GetStorageClass() != kScFstatic) { continue; } + if (!sym->LMBCAllocateOffSpecialReg()) { + continue; + } if (sym->GetType()->GetAlign() != curalign) { continue; } @@ -341,152 +88,6 @@ GlobalMemLayout::GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAll } seg_GPbased.size = maplebe::RoundUp(seg_GPbased.size, GetPrimTypeSize(PTY_ptr)); mirModule->SetGlobalMemSize(seg_GPbased.size); - // allocate the memory map for the GP block - mirModule->SetGlobalBlockMap( - static_cast(mirModule->GetMemPool()->Calloc(seg_GPbased.size))); - // perform initialization on globalblkmap - for (uint32 i = 0; i < symtabsize; i++) { - sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(i); - if (!sym) { - continue; - } - if (sym->GetStorageClass() != kScGlobal && sym->GetStorageClass() != kScFstatic) { - continue; - } - } -} - -// LocateNextParm should be called with each parameter in the parameter list -// starting from the beginning, one call per parameter in sequence; it returns -// the information on how each parameter is passed in ploc -void ParmLocator::LocateNextParm(const MIRType *ty, PLocInfo &ploc) { - ploc.memoffset = maplebe::RoundUp(lastMemOffset, 8); - ploc.memsize = ty->GetSize(); - - uint32 rightpad = 0; - parmNum++; - - switch (ty->GetPrimType()) { - case PTY_u1: - case PTY_u8: - case PTY_i8: - case PTY_u16: - case PTY_i16: - rightpad = GetPrimTypeSize(PTY_i32) - ploc.memsize; - break; - case PTY_a32: - case PTY_u32: - case PTY_i32: - case PTY_a64: - case PTY_u64: - case PTY_i64: - case PTY_ptr: - case PTY_ref: -#ifdef DYNAMICLANG - case PTY_simplestr: - case PTY_simpleobj: - case PTY_dynany: - case PTY_dyni32: - case PTY_dynf64: - case PTY_dynstr: - case PTY_dynobj: - case PTY_dynundef: - case PTY_dynbool: - case PTY_dynf32: - case PTY_dynnone: - case PTY_dynnull: -#endif - break; - - case PTY_f32: - rightpad = GetPrimTypeSize(PTY_f64) - ploc.memsize; - break; - case PTY_c64: - case PTY_f64: - case PTY_v2i32: - case PTY_v4i16: - case PTY_v8i8: - case PTY_v2u32: - case PTY_v4u16: - case PTY_v8u8: - case PTY_v2f32: - break; - - case PTY_c128: - case PTY_v2i64: - case PTY_v4i32: - case PTY_v8i16: - case PTY_v16i8: - case PTY_v2u64: - case PTY_v4u32: - case PTY_v8u16: - case PTY_v16u8: - case PTY_v2f64: - case PTY_v4f32: - break; - - case PTY_agg: { - // compute rightpad - int32 paddedSize = maplebe::RoundUp(ploc.memsize, 8); - rightpad = paddedSize - ploc.memsize; - break; - } - default: - CHECK_FATAL(false, "unsupported type"); - } - - lastMemOffset = ploc.memoffset + ploc.memsize + rightpad; - return; -} - -// instantiated with the type of the function return value, it describes how -// the return value is to be passed back to the caller -ReturnMechanism::ReturnMechanism(const MIRType *retty) : fake_first_parm(false) { - switch (retty->GetPrimType()) { - case PTY_u1: - case PTY_u8: - case PTY_i8: - case PTY_u16: - case PTY_i16: - case PTY_a32: - case PTY_u32: - case PTY_i32: - case PTY_a64: - case PTY_u64: - case PTY_i64: - case PTY_f32: - case PTY_f64: -#ifdef DYNAMICLANG - case PTY_simplestr: - case PTY_simpleobj: - case PTY_dynany: - case PTY_dyni32: - case PTY_dynstr: - case PTY_dynobj: -#endif - ptype0 = retty->GetPrimType(); - return; - - case PTY_c64: - case PTY_c128: - fake_first_parm = true; - ptype0 = PTY_a32; - return; - - case PTY_agg: { - uint32 size = retty->GetSize(); - if (size > 4) { - fake_first_parm = true; - ptype0 = PTY_a32; - } else { - ptype0 = PTY_u32; - } - return; - } - - default: - return; - } } } // namespace maple diff --git a/src/mapleall/maple_me/src/me_cfg.cpp b/src/mapleall/maple_me/src/me_cfg.cpp index ad57c5b166..74e2f176c4 100644 --- a/src/mapleall/maple_me/src/me_cfg.cpp +++ b/src/mapleall/maple_me/src/me_cfg.cpp @@ -261,6 +261,7 @@ bool MeCFG::FindUse(const StmtNode &stmt, StIdx stIdx) const { case OP_customcall: case OP_polymorphiccall: case OP_icall: + case OP_icallproto: case OP_intrinsiccall: case OP_xintrinsiccall: case OP_intrinsiccallwithtype: @@ -273,6 +274,7 @@ bool MeCFG::FindUse(const StmtNode &stmt, StIdx stIdx) const { case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_intrinsiccallassigned: case OP_xintrinsiccallassigned: case OP_intrinsiccallwithtypeassigned: diff --git a/src/mapleall/maple_me/src/me_function.cpp b/src/mapleall/maple_me/src/me_function.cpp index 05181df796..a62f1a89a3 100755 --- a/src/mapleall/maple_me/src/me_function.cpp +++ b/src/mapleall/maple_me/src/me_function.cpp @@ -303,7 +303,9 @@ void MeFunction::CloneBBMeStmts(BB &srcBB, BB &destBB, std::map(&stmt); newStmt = irmap->NewInPool(static_cast(icallStmt), icallStmt->GetRetTyIdx(), icallStmt->GetStmtID()); diff --git a/src/mapleall/maple_me/src/me_lower_globals.cpp b/src/mapleall/maple_me/src/me_lower_globals.cpp index c14dd5c764..fdf2df8e3f 100644 --- a/src/mapleall/maple_me/src/me_lower_globals.cpp +++ b/src/mapleall/maple_me/src/me_lower_globals.cpp @@ -185,7 +185,12 @@ void MeLowerGlobals::Run() { MeExpr *addroffuncExpr = irMap->CreateAddroffuncMeExpr(callee.GetPuidx()); auto insertpos = callStmt.GetOpnds().begin(); callStmt.InsertOpnds(insertpos, addroffuncExpr); - IcallMeStmt *icallStmt = irMap->NewInPool(stmt.GetOp() == OP_call ? OP_icall : OP_icallassigned); + IcallMeStmt *icallStmt = nullptr; + if (func.GetMIRModule().IsCModule()) { + icallStmt = irMap->NewInPool(stmt.GetOp() == OP_call ? OP_icallproto : OP_icallprotoassigned); + } else { + icallStmt = irMap->NewInPool(stmt.GetOp() == OP_call ? OP_icall : OP_icallassigned); + } icallStmt->SetIsLive(callStmt.GetIsLive()); icallStmt->SetSrcPos(callStmt.GetSrcPosition()); for (MeExpr *o : callStmt.GetOpnds()) { @@ -193,7 +198,11 @@ void MeLowerGlobals::Run() { } icallStmt->GetMuList()->insert(callStmt.GetMuList()->begin(), callStmt.GetMuList()->end()); icallStmt->GetChiList()->insert(callStmt.GetChiList()->begin(), callStmt.GetChiList()->end()); - icallStmt->SetRetTyIdx(callee.GetReturnTyIdx()); + if (func.GetMIRModule().IsCModule()) { + icallStmt->SetRetTyIdx(callee.GetMIRFuncType()->GetTypeIndex()); + } else { + icallStmt->SetRetTyIdx(callee.GetReturnTyIdx()); + } if (stmt.GetOp() != OP_call) { if (callStmt.NeedDecref()) { icallStmt->EnableNeedDecref(); diff --git a/src/mapleall/maple_me/src/me_phase_manager.cpp b/src/mapleall/maple_me/src/me_phase_manager.cpp index 09a1b64e5a..a0b5419a8e 100644 --- a/src/mapleall/maple_me/src/me_phase_manager.cpp +++ b/src/mapleall/maple_me/src/me_phase_manager.cpp @@ -140,8 +140,8 @@ bool MeFuncPM::PhaseRun(maple::MIRModule &m) { } if (genLMBC) { m.SetFlavor(kFlavorLmbc); + GlobalMemLayout globalMemLayout(&m, &m.GetMPAllocator()); maplebe::BECommon beCommon(m); - GlobalMemLayout globalMemLayout(&beCommon, &m, &m.GetMPAllocator()); maplebe::CGLowerer cgLower(m, beCommon, false, false); cgLower.RegisterBuiltIns(); cgLower.RegisterExternalLibraryFunctions(); @@ -153,14 +153,15 @@ bool MeFuncPM::PhaseRun(maple::MIRModule &m) { cgLower.LowerFunc(*func); MemPool *layoutMp = memPoolCtrler.NewMemPool("layout mempool", true); MapleAllocator layoutAlloc(layoutMp); - LMBCMemLayout localMemLayout(func, &layoutAlloc); + LMBCMemLayout localMemLayout(func, &globalMemLayout.seg_GPbased, &layoutAlloc); localMemLayout.LayoutStackFrame(); LMBCLowerer lmbcLowerer(&m, &beCommon, func, &globalMemLayout, &localMemLayout); lmbcLowerer.LowerFunction(); func->SetFrameSize(localMemLayout.StackFrameSize()); - func->SetUpFormalSize(localMemLayout.UpformalSize()); memPoolCtrler.DeleteMemPool(layoutMp); } + globalMemLayout.seg_GPbased.size = maplebe::RoundUp(globalMemLayout.seg_GPbased.size, GetPrimTypeSize(PTY_ptr)); + m.SetGlobalMemSize(globalMemLayout.seg_GPbased.size); // output .lmbc BinaryMplt binMplt(m); std::string modFileName = m.GetFileName(); diff --git a/src/mapleall/maple_me/src/me_rc_lowering.cpp b/src/mapleall/maple_me/src/me_rc_lowering.cpp index 1c7319e18b..131ebbdd2a 100644 --- a/src/mapleall/maple_me/src/me_rc_lowering.cpp +++ b/src/mapleall/maple_me/src/me_rc_lowering.cpp @@ -1145,6 +1145,7 @@ void RCLowering::HandleArguments() { firstBB->InsertMeStmtBefore(firstMeStmt, incCall); } sym->SetLocalRefVar(); + mirFunc->GetFormalDefVec()[i].formalAttrs.SetAttr(ATTR_localrefvar); for (auto *stmt : rets) { std::vector opnds = { argVar }; diff --git a/src/mapleall/maple_me/src/me_rename2preg.cpp b/src/mapleall/maple_me/src/me_rename2preg.cpp index 9549dff004..eddc9704b9 100644 --- a/src/mapleall/maple_me/src/me_rename2preg.cpp +++ b/src/mapleall/maple_me/src/me_rename2preg.cpp @@ -317,6 +317,7 @@ void SSARename2Preg::Rename2PregStmt(MeStmt *stmt) { case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_intrinsiccallassigned: case OP_xintrinsiccallassigned: case OP_intrinsiccallwithtypeassigned: { diff --git a/src/mapleall/maple_me/src/me_side_effect.cpp b/src/mapleall/maple_me/src/me_side_effect.cpp index 67dea87820..52fcda8516 100644 --- a/src/mapleall/maple_me/src/me_side_effect.cpp +++ b/src/mapleall/maple_me/src/me_side_effect.cpp @@ -933,6 +933,7 @@ bool IpaSideEffect::UpdateSideEffectWithStmt(MeStmt &meStmt, case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_superclasscallassigned: case OP_asm: { hasPrivateDef = hasThrException = true; @@ -959,7 +960,8 @@ bool IpaSideEffect::UpdateSideEffectWithStmt(MeStmt &meStmt, case OP_interfaceicall: case OP_customcall: case OP_polymorphiccall: - case OP_icall: { + case OP_icall: + case OP_icallproto: { hasPrivateDef = hasThrException = true; SetHasDef(); for (size_t i = 0; i < meStmt.NumMeStmtOpnds(); ++i) { diff --git a/src/mapleall/maple_me/src/me_stmt_pre.cpp b/src/mapleall/maple_me/src/me_stmt_pre.cpp index d50e3c5371..3f5d2bff57 100755 --- a/src/mapleall/maple_me/src/me_stmt_pre.cpp +++ b/src/mapleall/maple_me/src/me_stmt_pre.cpp @@ -967,7 +967,9 @@ void MeStmtPre::BuildWorkListBB(BB *bb) { break; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { auto &icallMeStmt = static_cast(stmt); VersionStackChiListUpdate(*icallMeStmt.GetChiList()); break; diff --git a/src/mapleall/maple_me/src/pme_emit.cpp b/src/mapleall/maple_me/src/pme_emit.cpp index 227cb6a761..52e1df6beb 100755 --- a/src/mapleall/maple_me/src/pme_emit.cpp +++ b/src/mapleall/maple_me/src/pme_emit.cpp @@ -485,10 +485,12 @@ StmtNode* PreMeEmitter::EmitPreMeStmt(MeStmt *mestmt, BaseNode *parent) { return callnode; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { IcallMeStmt *icallMeStmt = static_cast (mestmt); IcallNode *icallnode = - codeMP->New(*codeMPAlloc, OP_icallassigned, icallMeStmt->GetRetTyIdx()); + codeMP->New(*codeMPAlloc, OP_icallprotoassigned, icallMeStmt->GetRetTyIdx()); for (uint32 i = 0; i < icallMeStmt->GetOpnds().size(); i++) { icallnode->GetNopnd().push_back(EmitPreMeExpr(icallMeStmt->GetOpnd(i), icallnode)); } @@ -509,6 +511,9 @@ StmtNode* PreMeEmitter::EmitPreMeStmt(MeStmt *mestmt, BaseNode *parent) { icallnode->SetRetTyIdx(TyIdx(preg->GetPrimType())); } } + if (mestmt->GetOp() == OP_icallproto || mestmt->GetOp() == OP_icallprotoassigned) { + icallnode->SetRetTyIdx(icallMeStmt->GetRetTyIdx()); + } icallnode->CopySafeRegionAttr(mestmt->GetStmtAttr()); icallnode->SetOriginalID(mestmt->GetOriginalId()); PreMeStmtExtensionMap[icallnode->GetStmtID()] = pmeExt; diff --git a/src/mapleall/maple_me/src/ssa_devirtual.cpp b/src/mapleall/maple_me/src/ssa_devirtual.cpp index 15a609e427..f46e8e06ce 100644 --- a/src/mapleall/maple_me/src/ssa_devirtual.cpp +++ b/src/mapleall/maple_me/src/ssa_devirtual.cpp @@ -534,7 +534,9 @@ void SSADevirtual::TraversalMeStmt(MeStmt &meStmt) { break; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { auto *icallMeStmt = static_cast(&meStmt); const MapleVector &opnds = icallMeStmt->GetOpnds(); for (size_t i = 0; i < opnds.size(); ++i) { diff --git a/src/mapleall/maple_me/src/ssa_pre.cpp b/src/mapleall/maple_me/src/ssa_pre.cpp index ceff080daa..a082b80b9f 100644 --- a/src/mapleall/maple_me/src/ssa_pre.cpp +++ b/src/mapleall/maple_me/src/ssa_pre.cpp @@ -1666,6 +1666,7 @@ void SSAPre::BuildWorkListStmt(MeStmt &stmt, uint32 seqStmt, bool isRebuilt, MeE case OP_customcall: case OP_polymorphiccall: case OP_icall: + case OP_icallproto: case OP_callassigned: case OP_virtualcallassigned: case OP_virtualicallassigned: @@ -1675,6 +1676,7 @@ void SSAPre::BuildWorkListStmt(MeStmt &stmt, uint32 seqStmt, bool isRebuilt, MeE case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_asm: { auto *naryMeStmt = static_cast(meStmt); const MapleVector &opnds = naryMeStmt->GetOpnds(); diff --git a/src/mapleall/mpl2mpl/src/constantfold.cpp b/src/mapleall/mpl2mpl/src/constantfold.cpp index f84c351bd8..1b296c1de7 100644 --- a/src/mapleall/mpl2mpl/src/constantfold.cpp +++ b/src/mapleall/mpl2mpl/src/constantfold.cpp @@ -162,6 +162,8 @@ StmtNode *ConstantFold::Simplify(StmtNode *node) { return SimplifyNary(static_cast(node)); case OP_icall: case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: return SimplifyIcall(static_cast(node)); case OP_asm: return SimplifyAsm(static_cast(node)); @@ -2628,8 +2630,8 @@ StmtNode *ConstantFold::SimplifyIcall(IcallNode *node) { AddroffuncNode *addrofNode = static_cast(node->GetNopndAt(0)); CallNode *callNode = mirModule->CurFuncCodeMemPool()->New(*mirModule, - node->GetOpCode() == OP_icall ? OP_call : OP_callassigned); - if (node->GetOpCode() == OP_icallassigned) { + (node->GetOpCode() == OP_icall || node->GetOpCode() == OP_icallproto) ? OP_call : OP_callassigned); + if (node->GetOpCode() == OP_icallassigned || node->GetOpCode() == OP_icallprotoassigned) { callNode->SetReturnVec(node->GetReturnVec()); } callNode->SetPUIdx(addrofNode->GetPUIdx()); -- Gitee From 0daa14bcd2ce61d84c420c43ebdeeef51e9b9917 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:44 -0700 Subject: [PATCH 040/124] Fred's Fixed determination logic of when there is fake parameter for returning struct, where x8 is also used to pass the fake parameter --- .../maple_be/src/cg/aarch64/aarch64_args.cpp | 4 ++-- .../src/cg/aarch64/aarch64_call_conv.cpp | 11 ++++++----- .../maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 18 ++++++++++++------ .../src/cg/aarch64/aarch64_memlayout.cpp | 4 ++-- 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 5869978884..b44841c018 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -38,7 +38,7 @@ void AArch64MoveRegArgs::CollectRegisterArgs(std::map &argsL uint32 start = 0; if (numFormal) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsFirstArgReturn()) { + if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16ByteSize) { start = 1; @@ -439,7 +439,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsFirstArgReturn()) { + if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp index b89e1b4c40..bc9e1cb471 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp @@ -306,18 +306,18 @@ int32 AArch64CallConvImpl::LocateNextParm(MIRType &mirType, CCLocInfo &pLoc, boo if (size == 0) { /* For return struct size 0 there is no return value. */ return 0; - } else if (size > k16ByteSize) { - /* For return struct size > 16 bytes the pointer returns in x8. */ - pLoc.reg0 = R8; - return kSizeOfPtr; } + /* For return struct size > 16 bytes the pointer returns in x8. */ + pLoc.reg0 = R8; + return kSizeOfPtr; +#if 0 /* For return struct size less or equal to 16 bytes, the values * are returned in register pairs. * Check for pure float struct. */ AArch64ArgumentClass classes[kMaxRegCount] = { kAArch64NoClass }; uint32 fpSize; - MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(beCommon.GetFuncReturnType(*func)); + MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); uint32 numRegs = static_cast(ClassifyAggregate(beCommon, *retType, classes, sizeof(classes), fpSize)); if (classes[0] == kAArch64FloatClass) { CHECK_FATAL(numRegs <= kMaxRegCount, "LocateNextParm: illegal number of regs"); @@ -334,6 +334,7 @@ int32 AArch64CallConvImpl::LocateNextParm(MIRType &mirType, CCLocInfo &pLoc, boo } return 0; } +#endif } } uint64 typeSize = beCommon.GetTypeSize(mirType.GetTypeIndex()); 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 5da7b66ec2..66ea632b29 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8063,6 +8063,17 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo std::set specialArgs; SelectParmListPreprocess(naryNode, i, specialArgs); bool specialArg = false; + bool firstArgReturn = false; + MIRFunction *callee = nullptr; + if (dynamic_cast(&naryNode) != nullptr) { + auto calleePuIdx = static_cast(naryNode).GetPUIdx(); + callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + firstArgReturn = callee->IsFirstArgReturn(); + } else if (naryNode.GetOpCode() == OP_icallproto) { + IcallNode *icallnode = &static_cast(naryNode); + MIRFuncType *funcType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallnode->GetRetTyIdx())); + firstArgReturn = funcType->FirstArgReturn(); + } BB *curBBrecord = GetCurBB(); BB *tmpBB = nullptr; if (!specialArgs.empty()) { @@ -8084,11 +8095,6 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); - MIRFunction *callee = nullptr; - if (dynamic_cast(&naryNode) != nullptr) { - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); - } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } @@ -8153,7 +8159,7 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo } expRegOpnd = static_cast(opnd); - if ((pnum == 0) && (SelectParmListGetStructReturnSize(naryNode) > k16ByteSize)) { + if ((pnum == 0) && firstArgReturn) { parmLocator.InitCCLocInfo(ploc); ploc.reg0 = R8; } else { diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp index 4184108a22..5a839e9af4 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp @@ -210,7 +210,7 @@ void AArch64MemLayout::LayoutFormalParams() { AArch64SymbolAlloc *symLoc = memAllocator->GetMemPool()->New(); SetSymAllocInfo(stIndex, *symLoc); if (i == 0) { - if (mirFunction->IsFirstArgReturn()) { + if (mirFunction->IsReturnStruct() && mirFunction->IsFirstArgReturn()) { symLoc->SetMemSegment(GetSegArgsRegPassed()); symLoc->SetOffset(GetSegArgsRegPassed().GetSize()); TyIdx tyIdx = mirFunction->GetFuncRetStructTyIdx(); @@ -395,7 +395,7 @@ void AArch64MemLayout::LayoutReturnRef(std::vector &returnDelays, void AArch64MemLayout::LayoutActualParams() { for (size_t i = 0; i < mirFunction->GetFormalCount(); ++i) { if (i == 0) { - if (mirFunction->IsReturnStruct()) { + if (mirFunction->IsReturnStruct() && mirFunction->IsFirstArgReturn()) { continue; } } -- Gitee From 56843de8a6b5bff4aea45596b59e2c9ed8ecc350 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:53:00 -0700 Subject: [PATCH 041/124] Remove unneeded fp def. Turn on tailcall. no unneeded pro/epilog. --- .../maple_be/include/cg/aarch64/aarch64_color_ra.h | 1 + src/mapleall/maple_be/include/cg/cgfunc.h | 9 +++++++++ .../maple_be/src/cg/aarch64/aarch64_color_ra.cpp | 6 ++++++ .../maple_be/src/cg/aarch64/aarch64_proepilog.cpp | 7 +++---- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h index a3df9f6bf3..651cd91674 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h @@ -1519,6 +1519,7 @@ class GraphColorRegAllocator : public RegAllocator { #endif bool hasSpill = false; bool doMultiPass = false; + bool seenFP = false; }; class CallerSavePre: public CGPre { diff --git a/src/mapleall/maple_be/include/cg/cgfunc.h b/src/mapleall/maple_be/include/cg/cgfunc.h index 0695a784de..a664565276 100644 --- a/src/mapleall/maple_be/include/cg/cgfunc.h +++ b/src/mapleall/maple_be/include/cg/cgfunc.h @@ -1107,6 +1107,14 @@ class CGFunc { return useFP; } + void UnsetSeenFP() { + seenFP = false; + } + + bool SeenFP() const { + return seenFP; + } + void UpdateAllRegisterVregMapping(MapleMap &newMap); void RegisterVregMapping(regno_t vRegNum, PregIdx pidx) { @@ -1276,6 +1284,7 @@ class CGFunc { const MapleString shortFuncName; bool hasAsm = false; bool useFP = true; + bool seenFP = true; /* save stack protect kinds which can trigger stack protect */ uint8 stackProtectInfo = 0; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp index 8d63e7d8fb..479dad8658 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp @@ -3608,6 +3608,9 @@ RegOperand *GraphColorRegAllocator::GetReplaceOpnd(Insn &insn, const Operand &op auto ®Opnd = static_cast(opnd); uint32 vregNO = regOpnd.GetRegisterNumber(); + if (vregNO == RFP) { + seenFP = true; + } RegType regType = regOpnd.GetRegisterType(); if (vregNO < kAllRegNum) { return nullptr; @@ -4975,6 +4978,9 @@ bool GraphColorRegAllocator::AllocateRegisters() { MarkCalleeSaveRegs(); + if (seenFP == false) { + cgFunc->UnsetSeenFP(); + } if (GCRA_DUMP) { cgFunc->DumpCGIR(); } diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp index 4fd65cebdd..807279e7f9 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp @@ -185,9 +185,6 @@ void AArch64GenProEpilog::TailCallBBOpt(BB &bb, MapleSet &callInsns, BB & * Return value: true if function do not need Prologue/Epilogue. false otherwise. */ bool AArch64GenProEpilog::TailCallOpt() { - if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { - return false; - } /* Count how many call insns in the whole function. */ uint32 nCount = 0; bool hasGetStackClass = false; @@ -1229,7 +1226,9 @@ void AArch64GenProEpilog::GeneratePushRegs() { } else { immOpnd = &aarchCGFunc.CreateImmOperand(argsToStkPassSize, k32BitSize, true); } - aarchCGFunc.SelectAdd(fpOpnd, spOpnd, *immOpnd, PTY_u64); + if (isLmbc == false || cgFunc.SeenFP() || cgFunc.GetFunction().GetAttr(FUNCATTR_varargs)) { + aarchCGFunc.SelectAdd(fpOpnd, spOpnd, *immOpnd, PTY_u64); + } cgFunc.GetCurBB()->GetLastInsn()->SetFrameDef(true); if (cgFunc.GenCfi()) { cgFunc.GetCurBB()->AppendInsn(aarchCGFunc.CreateCfiDefCfaInsn(stackBaseReg, -- Gitee From 498fb5ca844703b79c4301628e9721cee966b199 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:53:14 -0700 Subject: [PATCH 042/124] Fred's Set firstarg_return attribute in the new funcAttrs field in MIRFuncType --- src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp | 3 +++ src/mapleall/maple_ir/src/mir_lower.cpp | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp b/src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp index 67b9df418d..f26d6c8da7 100644 --- a/src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp +++ b/src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp @@ -281,6 +281,9 @@ bool ASTFunc2FEHelper::ProcessDeclImpl(MapleAllocator &allocator) { ENCChecker::InsertBoundaryInAtts(attrs, func.GetBoundaryInfo()); mirMethodPair.second.second = attrs; mirFunc->SetFuncAttrs(attrs); + if (firstArgRet) { + mirFunc->GetMIRFuncType()->funcAttrs.SetAttr(FUNCATTR_firstarg_return); + } func.ClearGenericAttrsContentMap(); return true; } diff --git a/src/mapleall/maple_ir/src/mir_lower.cpp b/src/mapleall/maple_ir/src/mir_lower.cpp index 36d572f057..c19a5856b2 100644 --- a/src/mapleall/maple_ir/src/mir_lower.cpp +++ b/src/mapleall/maple_ir/src/mir_lower.cpp @@ -553,6 +553,10 @@ BlockNode *MIRLower::LowerBlock(BlockNode &block) { MIRFuncType *funcType = FuncTypeFromFuncPtrExpr(stmt->Opnd(0)); CHECK_FATAL(funcType != nullptr, "MIRLower::LowerBlock: cannot find prototype for icall"); ic->SetRetTyIdx(funcType->GetTypeIndex()); + MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcType->GetRetTyIdx()); + if (retType->GetPrimType() == PTY_agg && retType->GetSize() > 16) { + funcType->funcAttrs.SetAttr(FUNCATTR_firstarg_return); + } } newBlock->AddStatement(stmt); break; -- Gitee From f3578533962f8355ea4c8ce60247f42348e95e17 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 043/124] Changes from mplcglmbc8 and mplcglmbc9. --- src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp | 1 - src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index b44841c018..941c117c58 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -439,7 +439,6 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; 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 66ea632b29..482636ee0f 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8095,6 +8095,11 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); + MIRFunction *callee = nullptr; + if (dynamic_cast(&naryNode) != nullptr) { + auto calleePuIdx = static_cast(naryNode).GetPUIdx(); + callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } -- Gitee From f34a4772122b5710e9f0f86e1038dfd70ff96256 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:44 -0700 Subject: [PATCH 044/124] Fred's Fixed determination logic of when there is fake parameter for returning struct, where x8 is also used to pass the fake parameter --- src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp | 1 + src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 5 ----- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 941c117c58..b44841c018 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -439,6 +439,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); + if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; 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 482636ee0f..66ea632b29 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8095,11 +8095,6 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); - MIRFunction *callee = nullptr; - if (dynamic_cast(&naryNode) != nullptr) { - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); - } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } -- Gitee From 229c8676988b3cab959bcedbde7bd00e313e6947 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 15 Jun 2022 16:18:04 -0700 Subject: [PATCH 045/124] Fix accessing localrefvar in memlayout by qualifying with language --- src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h | 2 +- src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 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 7a6e406263..bec9fa8267 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -129,7 +129,7 @@ class AArch64CGFunc : public CGFunc { uint32 LmbcFindTotalStkUsed(std::vector* paramList); uint32 LmbcTotalRegsUsed(); void LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn); - bool LmbcSmallAggForRet(BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *src); bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp index 5a839e9af4..e7d4432330 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp @@ -230,7 +230,7 @@ void AArch64MemLayout::LayoutFormalParams() { if (ploc.reg0 != kRinvalid) { /* register */ symLoc->SetRegisters(static_cast(ploc.reg0), static_cast(ploc.reg1), static_cast(ploc.reg2), static_cast(ploc.reg3)); - if (mirFunction->GetFormalDefVec()[i].formalAttrs.GetAttr(ATTR_localrefvar)) { + if (!cgFunc->GetMirModule().IsCModule() && mirFunction->GetNthParamAttr(i).GetAttr(ATTR_localrefvar)) { symLoc->SetMemSegment(segRefLocals); SetSegmentSize(*symLoc, segRefLocals, ptyIdx); } else if (!sym->IsPreg()) { @@ -272,7 +272,7 @@ void AArch64MemLayout::LayoutFormalParams() { } else { segArgsStkPassed.SetSize(static_cast(RoundUp(segArgsStkPassed.GetSize(), kSizeOfPtr))); } - if (mirFunction->GetFormalDefVec()[i].formalAttrs.GetAttr(ATTR_localrefvar)) { + if (!cgFunc->GetMirModule().IsCModule() && mirFunction->GetNthParamAttr(i).GetAttr(ATTR_localrefvar)) { SetLocalRegLocInfo(sym->GetStIdx(), *symLoc); AArch64SymbolAlloc *symLoc1 = memAllocator->GetMemPool()->New(); symLoc1->SetMemSegment(segRefLocals); -- Gitee From d7be8265d507d8f450d304d46cae7730daecf668 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Thu, 16 Jun 2022 10:44:59 -0700 Subject: [PATCH 046/124] Set appearsInCode and puidxOrigin fields in newly cloned functions --- src/mapleall/maple_ipa/src/ipa_clone.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mapleall/maple_ipa/src/ipa_clone.cpp b/src/mapleall/maple_ipa/src/ipa_clone.cpp index 51fa34198c..3f03c26d86 100644 --- a/src/mapleall/maple_ipa/src/ipa_clone.cpp +++ b/src/mapleall/maple_ipa/src/ipa_clone.cpp @@ -107,6 +107,8 @@ MIRFunction *IpaClone::IpaCloneFunction(MIRFunction &originalFunction, const std newFunc->SetSrcPosition(originalFunction.GetSrcPosition()); newFunc->SetFuncAttrs(originalFunction.GetFuncAttrs()); newFunc->SetBaseClassFuncNames(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fullName)); + newFunc->GetFuncSymbol()->SetAppearsInCode(true); + newFunc->SetPuidxOrigin(newFunc->GetPuidx()); if (originalFunction.GetBody() != nullptr) { CopyFuncInfo(originalFunction, *newFunc); newFunc->SetBody( @@ -135,6 +137,8 @@ MIRFunction *IpaClone::IpaCloneFunctionWithFreq(MIRFunction &originalFunction, newFunc->SetSrcPosition(originalFunction.GetSrcPosition()); newFunc->SetFuncAttrs(originalFunction.GetFuncAttrs()); newFunc->SetBaseClassFuncNames(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fullName)); + newFunc->GetFuncSymbol()->SetAppearsInCode(true); + newFunc->SetPuidxOrigin(newFunc->GetPuidx()); GcovFuncInfo *origProfData = originalFunction.GetFuncProfData(); auto *moduleMp = mirBuilder.GetMirModule().GetMemPool(); GcovFuncInfo *newProfData = moduleMp->New(&mirBuilder.GetMirModule().GetMPAllocator(), -- Gitee From d91c7673444d6500e95534d526cb81112167a86c Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 047/124] Changes from mplcglmbc8 and mplcglmbc9. --- src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h | 2 +- src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 2 +- 2 files changed, 2 insertions(+), 2 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 bec9fa8267..7a6e406263 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -129,7 +129,7 @@ class AArch64CGFunc : public CGFunc { uint32 LmbcFindTotalStkUsed(std::vector* paramList); uint32 LmbcTotalRegsUsed(); void LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn); - bool LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForRet(BlkassignoffNode &bNode, Operand *src); bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; 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 66ea632b29..179c07b518 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -2271,7 +2271,7 @@ void AArch64CGFunc::SelectBlkassignoff(BlkassignoffNode &bNode, Operand *src) opndVec.push_back(regResult); /* result */ opndVec.push_back(PrepareMemcpyParamOpnd(offset, *dest)); /* param 0 */ opndVec.push_back(src); /* param 1 */ - opndVec.push_back(PrepareMemcpyParamOpnd(static_cast(static_cast(bNode.blockSize))));/* param 2 */ + opndVec.push_back(PrepareMemcpyParamOpnd(bNode.blockSize));/* param 2 */ SelectLibCall("memcpy", opndVec, PTY_a64, PTY_a64); } -- Gitee From d7f0ecb2754c67d2cdf2536130973fc3c78adb32 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 15 Jun 2022 16:18:04 -0700 Subject: [PATCH 048/124] Fix accessing localrefvar in memlayout by qualifying with language --- src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 7a6e406263..bec9fa8267 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -129,7 +129,7 @@ class AArch64CGFunc : public CGFunc { uint32 LmbcFindTotalStkUsed(std::vector* paramList); uint32 LmbcTotalRegsUsed(); void LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn); - bool LmbcSmallAggForRet(BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *src); bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; -- Gitee From d8239aa322b6ae068fe25d8326ae906aaee3444d Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Fri, 17 Jun 2022 00:40:20 -0700 Subject: [PATCH 049/124] Fixed a couple of bugs in the last rebase --- .../maple_be/include/cg/aarch64/aarch64_cgfunc.h | 16 ---------------- .../maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 2 +- 2 files changed, 1 insertion(+), 17 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 bec9fa8267..84ba1fb370 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -739,22 +739,6 @@ class AArch64CGFunc : public CGFunc { RegOperand &GetZeroOpnd(uint32 size) override; - int32 GetLmbcTotalStkUsed() { - return lmbcArgInfo->lmbcTotalStkUsed; - } - - void SetLmbcTotalStkUsed(int32 offset) { - lmbcArgInfo->lmbcTotalStkUsed = offset; - } - - void SetLmbcCallReturnType(MIRType *ty) { - lmbcCallReturnType = ty; - } - - MIRType *GetLmbcCallReturnType() { - return lmbcCallReturnType; - } - private: enum RelationOperator : uint8 { kAND, 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 179c07b518..4ac23faa22 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -893,7 +893,7 @@ MemOperand &AArch64CGFunc::ConstraintOffsetToSafeRegion(uint32 bitLen, const Mem } int32 offsetValue = static_cast(memOpnd.GetOffsetImmediate()->GetOffsetValue()); int32 multiplier = (offsetValue / k512BitSize) + static_cast(offsetValue % k512BitSize > k256BitSize); - int32 addMount = multiplier * k512BitSizeInt; + int32 addMount = multiplier * k512BitSize; int32 newOffset = offsetValue - addMount; RegOperand *baseReg = memOpnd.GetBaseRegister(); ImmOperand &immAddMount = CreateImmOperand(addMount, k64BitSize, true); -- Gitee From 68df97a699efaba1acb1e087dee3213394aca243 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Fri, 17 Jun 2022 21:32:32 -0700 Subject: [PATCH 050/124] Fixed bug in importing typeAttrs field of MIRStructType Also, handle the export and import of MIRAddrofConst of local symbols properly. --- src/mapleall/maple_ir/include/bin_mpl_export.h | 2 ++ src/mapleall/maple_ir/src/bin_mpl_export.cpp | 2 +- src/mapleall/maple_ir/src/bin_mpl_import.cpp | 8 ++++---- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/mapleall/maple_ir/include/bin_mpl_export.h b/src/mapleall/maple_ir/include/bin_mpl_export.h index f12bec7081..0d3d6d6457 100644 --- a/src/mapleall/maple_ir/include/bin_mpl_export.h +++ b/src/mapleall/maple_ir/include/bin_mpl_export.h @@ -180,7 +180,9 @@ class BinaryMplExport { void ExpandFourBuffSize(); MIRModule &mod; + public: MIRFunction *curFunc = nullptr; + private: size_t bufI = 0; std::vector buf; std::unordered_map gStrMark; diff --git a/src/mapleall/maple_ir/src/bin_mpl_export.cpp b/src/mapleall/maple_ir/src/bin_mpl_export.cpp index 4359ae9f55..72e7d11858 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_export.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_export.cpp @@ -45,7 +45,7 @@ void OutputConstAddrof(const MIRConst &constVal, BinaryMplExport &mplExport) { if (addrof.GetSymbolIndex().IsGlobal()) { mplExport.OutputSymbol(mplExport.GetMIRModule().CurFunction()->GetLocalOrGlobalSymbol(addrof.GetSymbolIndex())); } else { - mplExport.WriteNum(addrof.GetSymbolIndex().FullIdx()); + mplExport.OutputLocalSymbol(mplExport.curFunc->GetLocalOrGlobalSymbol(addrof.GetSymbolIndex())); } mplExport.WriteNum(addrof.GetFieldID()); mplExport.WriteNum(addrof.GetOffset()); diff --git a/src/mapleall/maple_ir/src/bin_mpl_import.cpp b/src/mapleall/maple_ir/src/bin_mpl_import.cpp index 1f79751ed6..e3ab6f9689 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_import.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_import.cpp @@ -122,10 +122,10 @@ MIRConst *BinaryMplImport::ImportConst(MIRFunction *func) { return memPool->New(sym->GetStIdx(), fi, *exprTy, ofst); } case kBinKindConstAddrofLocal: { - uint32 fullidx = static_cast(ReadNum()); + MIRSymbol *sym = ImportLocalSymbol(func); FieldID fi = static_cast(ReadNum()); int32 ofst = static_cast(ReadNum()); - return memPool->New(StIdx(fullidx), fi, *type, ofst); + return memPool->New(sym->GetStIdx(), fi, *type, ofst); } case kBinKindConstAddrofFunc: { PUIdx puIdx = ImportFunction(); @@ -661,9 +661,9 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { auto kind = static_cast(ReadNum()); MIRStructType type(kind, strIdx); type.SetNameIsLocal(nameIsLocal); - auto &origType = static_cast(InsertInTypeTables(type)); - typTab.push_back(origType.GetTypeIndex()); type.SetTypeAttrs(ImportTypeAttrs()); + MIRStructType &origType = static_cast(InsertInTypeTables(type)); + typTab.push_back(origType.GetTypeIndex()); if (kind != kTypeStructIncomplete) { if (forPointedType) { typeNeedsComplete = &origType; -- Gitee From 69e609eaf4243176acb289f4f795b1e430590da4 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Sun, 19 Jun 2022 22:40:51 -0700 Subject: [PATCH 051/124] Rebasing edits --- .../maple_be/include/cg/aarch64/aarch64_cgfunc.h | 15 +++++++++++++++ src/mapleall/maple_be/src/cg/cgfunc.cpp | 4 ++-- 2 files changed, 17 insertions(+), 2 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 84ba1fb370..2487ba1971 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -733,6 +733,21 @@ class AArch64CGFunc : public CGFunc { return lmbcArgInfo->lmbcCallArgNumOfRegs; } + int32 GetLmbcTotalStkUsed() { + return lmbcArgInfo->lmbcTotalStkUsed; + } + + void SetLmbcTotalStkUsed(int32 offset) { + lmbcArgInfo->lmbcTotalStkUsed = offset; + } + + void SetLmbcCallReturnType(MIRType *ty) { + lmbcCallReturnType = ty; + } + + MIRType *GetLmbcCallReturnType() { + return lmbcCallReturnType; + } bool IsSPOrFP(const RegOperand &opnd) const override; bool IsReturnReg(const RegOperand &opnd) const override; bool IsSaveReg(const RegOperand ®, MIRType &mirType, BECommon &cgBeCommon) const override; diff --git a/src/mapleall/maple_be/src/cg/cgfunc.cpp b/src/mapleall/maple_be/src/cg/cgfunc.cpp index 6900c49b28..286e3dd90a 100644 --- a/src/mapleall/maple_be/src/cg/cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/cgfunc.cpp @@ -1587,7 +1587,7 @@ void CGFunc::CreateLmbcFormalParamInfo() { stackOffset += (typeSize + 7) & (-8); LmbcFormalParamInfo *info = GetMemoryPool()->New(primType, offset, typeSize); lmbcParamVec.push_back(info); - if (idx == 0 && mirFunc.IsFirstArgReturn()) { + if (idx == 0 && func.IsFirstArgReturn()) { info->SetIsReturn(); } if (type->GetKind() == kTypeStruct) { @@ -1604,7 +1604,7 @@ void CGFunc::CreateLmbcFormalParamInfo() { } } else { /* No aggregate pass by value here */ - for (StmtNode *stmt = mirFunc.GetBody()->GetFirst(); stmt != nullptr; stmt = stmt->GetNext()) { + for (StmtNode *stmt = func.GetBody()->GetFirst(); stmt != nullptr; stmt = stmt->GetNext()) { if (stmt == nullptr) { break; } -- Gitee From 332558e89d1c039b44d869d511f87a10ff7792d7 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 052/124] Changes from mplcglmbc8 and mplcglmbc9. --- .../maple_be/include/cg/aarch64/aarch64_cgfunc.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) 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 2487ba1971..866e33b980 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -754,6 +754,22 @@ class AArch64CGFunc : public CGFunc { RegOperand &GetZeroOpnd(uint32 size) override; + int32 GetLmbcTotalStkUsed() { + return lmbcArgInfo->lmbcTotalStkUsed; + } + + void SetLmbcTotalStkUsed(int32 offset) { + lmbcArgInfo->lmbcTotalStkUsed = offset; + } + + void SetLmbcCallReturnType(MIRType *ty) { + lmbcCallReturnType = ty; + } + + MIRType *GetLmbcCallReturnType() { + return lmbcCallReturnType; + } + private: enum RelationOperator : uint8 { kAND, -- Gitee From 45f8823ebdf9ca1d547426b38ab08e962edeeec0 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 053/124] Changes from mplcglmbc8 and mplcglmbc9. --- src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp | 1 - src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index b44841c018..941c117c58 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -439,7 +439,6 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; 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 4ac23faa22..342120d0a1 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8095,6 +8095,11 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); + MIRFunction *callee = nullptr; + if (dynamic_cast(&naryNode) != nullptr) { + auto calleePuIdx = static_cast(naryNode).GetPUIdx(); + callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } -- Gitee From b9cf8ea2921704592236fd7761edcb567fd6e4a6 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:44 -0700 Subject: [PATCH 054/124] Fred's Fixed determination logic of when there is fake parameter for returning struct, where x8 is also used to pass the fake parameter --- src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp | 1 + src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 5 ----- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 941c117c58..b44841c018 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -439,6 +439,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); + if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; 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 342120d0a1..4ac23faa22 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8095,11 +8095,6 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); - MIRFunction *callee = nullptr; - if (dynamic_cast(&naryNode) != nullptr) { - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); - } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } -- Gitee From 9e96619babb82bd7d5a92ab85b90a54a173eeb59 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 055/124] Changes from mplcglmbc8 and mplcglmbc9. --- .../maple_be/include/cg/aarch64/aarch64_cgfunc.h | 16 ---------------- 1 file changed, 16 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 866e33b980..2487ba1971 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -754,22 +754,6 @@ class AArch64CGFunc : public CGFunc { RegOperand &GetZeroOpnd(uint32 size) override; - int32 GetLmbcTotalStkUsed() { - return lmbcArgInfo->lmbcTotalStkUsed; - } - - void SetLmbcTotalStkUsed(int32 offset) { - lmbcArgInfo->lmbcTotalStkUsed = offset; - } - - void SetLmbcCallReturnType(MIRType *ty) { - lmbcCallReturnType = ty; - } - - MIRType *GetLmbcCallReturnType() { - return lmbcCallReturnType; - } - private: enum RelationOperator : uint8 { kAND, -- Gitee From 0ca2527910c3ab4585ce0b73d271b4d67a9c88d1 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Mon, 20 Jun 2022 16:33:25 -0700 Subject: [PATCH 056/124] Set isFirst in calling LocateNextParm() so it knows to check for use of x8 to pass the first parameter --- src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp index 5ca154b1aa..b5788eb167 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp @@ -30,7 +30,7 @@ void AArch64ReachingDefinition::InitStartGen() { CCLocInfo pLoc; for (uint32 i = 0; i < cgFunc->GetFunction().GetFormalCount(); ++i) { MIRType *type = cgFunc->GetFunction().GetNthParamType(i); - parmLocator.LocateNextParm(*type, pLoc); + parmLocator.LocateNextParm(*type, pLoc, i == 0, &cgFunc->GetFunction()); if (pLoc.reg0 == 0) { /* If is a large frame, parameter addressing mode is based vreg:Vra. */ continue; -- Gitee From 3b50255dd94323ae9b4641de9b201c9dee53d934 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 057/124] Changes from mplcglmbc8 and mplcglmbc9. --- src/mapleall/maple_be/include/be/lower.h | 2 +- .../include/cg/aarch64/aarch64_cgfunc.h | 32 +- .../include/cg/aarch64/aarch64_phases.def | 2 +- src/mapleall/maple_be/include/cg/call_conv.h | 22 +- src/mapleall/maple_be/include/cg/cg.h | 19 +- src/mapleall/maple_be/include/cg/cgfunc.h | 2 + src/mapleall/maple_be/src/be/lower.cpp | 82 ++- .../maple_be/src/cg/aarch64/aarch64_args.cpp | 4 +- .../src/cg/aarch64/aarch64_call_conv.cpp | 2 +- .../src/cg/aarch64/aarch64_cgfunc.cpp | 547 +++++++++++++++--- .../maple_be/src/cg/aarch64/aarch64_ebo.cpp | 4 +- .../src/cg/aarch64/aarch64_memlayout.cpp | 34 +- .../src/cg/aarch64/aarch64_offset_adjust.cpp | 2 +- .../src/cg/aarch64/aarch64_proepilog.cpp | 87 ++- .../src/cg/aarch64/aarch64_reaching.cpp | 3 +- .../maple_be/src/cg/cg_phasemanager.cpp | 1 + src/mapleall/maple_be/src/cg/cgfunc.cpp | 48 +- src/mapleall/maple_be/src/cg/emit.cpp | 5 + src/mapleall/maple_be/src/cg/memlayout.cpp | 6 +- .../maple_ir/include/bin_mpl_export.h | 28 +- .../maple_ir/include/bin_mpl_import.h | 12 +- .../maple_ir/include/ir_safe_cast_traits.def | 4 +- src/mapleall/maple_ir/include/keywords.def | 1 - src/mapleall/maple_ir/include/mir_builder.h | 2 + src/mapleall/maple_ir/include/mir_function.h | 18 +- src/mapleall/maple_ir/include/mir_lower.h | 1 + src/mapleall/maple_ir/include/mir_nodes.h | 2 +- src/mapleall/maple_ir/include/mir_parser.h | 2 +- src/mapleall/maple_ir/include/mir_symbol.h | 6 +- src/mapleall/maple_ir/include/mir_type.h | 27 +- src/mapleall/maple_ir/include/opcode_info.h | 1 + src/mapleall/maple_ir/include/opcodes.def | 1 + src/mapleall/maple_ir/include/opcodes.h | 4 +- src/mapleall/maple_ir/src/bin_func_export.cpp | 239 ++++---- src/mapleall/maple_ir/src/bin_func_import.cpp | 248 ++++---- src/mapleall/maple_ir/src/bin_mpl_export.cpp | 112 ++-- src/mapleall/maple_ir/src/bin_mpl_import.cpp | 52 +- src/mapleall/maple_ir/src/global_tables.cpp | 4 +- src/mapleall/maple_ir/src/mir_builder.cpp | 24 + src/mapleall/maple_ir/src/mir_function.cpp | 4 +- src/mapleall/maple_ir/src/mir_lower.cpp | 107 ++++ src/mapleall/maple_ir/src/mir_nodes.cpp | 4 +- src/mapleall/maple_ir/src/mir_parser.cpp | 31 +- src/mapleall/maple_ir/src/mir_type.cpp | 8 +- src/mapleall/maple_ir/src/parser.cpp | 18 +- src/mapleall/maple_me/include/lmbc_lower.h | 3 - .../maple_me/include/lmbc_memlayout.h | 64 +- src/mapleall/maple_me/src/alias_class.cpp | 8 +- src/mapleall/maple_me/src/code_factoring.cpp | 4 +- .../src/demand_driven_alias_analysis.cpp | 4 +- src/mapleall/maple_me/src/irmap_build.cpp | 7 +- src/mapleall/maple_me/src/irmap_emit.cpp | 5 +- src/mapleall/maple_me/src/lfo_dep_test.cpp | 2 + src/mapleall/maple_me/src/lmbc_lower.cpp | 258 ++------- src/mapleall/maple_me/src/lmbc_memlayout.cpp | 439 +------------- src/mapleall/maple_me/src/me_cfg.cpp | 2 + src/mapleall/maple_me/src/me_function.cpp | 4 +- .../maple_me/src/me_lower_globals.cpp | 13 +- .../maple_me/src/me_phase_manager.cpp | 7 +- src/mapleall/maple_me/src/me_rc_lowering.cpp | 1 + src/mapleall/maple_me/src/me_rename2preg.cpp | 1 + src/mapleall/maple_me/src/me_side_effect.cpp | 4 +- src/mapleall/maple_me/src/me_stmt_pre.cpp | 4 +- src/mapleall/maple_me/src/pme_emit.cpp | 9 +- src/mapleall/maple_me/src/ssa_devirtual.cpp | 4 +- src/mapleall/maple_me/src/ssa_pre.cpp | 2 + src/mapleall/mpl2mpl/src/constantfold.cpp | 6 +- 67 files changed, 1410 insertions(+), 1305 deletions(-) diff --git a/src/mapleall/maple_be/include/be/lower.h b/src/mapleall/maple_be/include/be/lower.h index 8ef9689766..7c5dcad73c 100644 --- a/src/mapleall/maple_be/include/be/lower.h +++ b/src/mapleall/maple_be/include/be/lower.h @@ -188,7 +188,7 @@ class CGLowerer { void LowerTryCatchBlocks(BlockNode &body); #if TARGARM32 || TARGAARCH64 || TARGRISCV64 - BlockNode *LowerReturnStruct(NaryStmtNode &retNode); + BlockNode *LowerReturnStructUsingFakeParm(NaryStmtNode &retNode); #endif virtual BlockNode *LowerReturn(NaryStmtNode &retNode); void LowerEntry(MIRFunction &func); 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 96bc53c720..53478d0f99 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -38,6 +38,7 @@ class LmbcArgInfo { MapleVector lmbcCallArgTypes; MapleVector lmbcCallArgOffsets; MapleVector lmbcCallArgNumOfRegs; // # of regs needed to complete struct + uint32 lmbcTotalStkUsed = -1; // TBD: remove when explicit addr for large agg is available }; class AArch64CGFunc : public CGFunc { @@ -101,7 +102,7 @@ class AArch64CGFunc : public CGFunc { return kRFLAG; } - MIRType *GetAggTyFromCallSite(StmtNode *stmt); + MIRType *LmbcGetAggTyFromCallSite(StmtNode *stmt, std::vector **parmList); RegOperand &GetOrCreateResOperand(const BaseNode &parent, PrimType primType); void IntrinsifyGetAndAddInt(ListOperand &srcOpnds, PrimType pty); @@ -125,9 +126,11 @@ class AArch64CGFunc : public CGFunc { bool needLow12 = false); MemOperand *FixLargeMemOpnd(MemOperand &memOpnd, uint32 align); MemOperand *FixLargeMemOpnd(MOperator mOp, MemOperand &memOpnd, uint32 dSize, uint32 opndIdx); + uint32 LmbcFindTotalStkUsed(std::vector* paramList); + uint32 LmbcTotalRegsUsed(); void LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn); - bool LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *src); - bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForRet(BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; void SelectIassignoff(IassignoffNode &stmt) override; @@ -135,6 +138,7 @@ class AArch64CGFunc : public CGFunc { void SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd) override; void SelectBlkassignoff(BlkassignoffNode &bNode, Operand *src) override; void SelectAggIassign(IassignNode &stmt, Operand &lhsAddrOpnd) override; + void SelectReturnSendOfStructInRegs(BaseNode *x) override; void SelectReturn(Operand *opnd0) override; void SelectIgoto(Operand *opnd0) override; void SelectCondGoto(CondGotoNode &stmt, Operand &opnd0, Operand &opnd1) override; @@ -486,7 +490,10 @@ class AArch64CGFunc : public CGFunc { void GenerateCleanupCodeForExtEpilog(BB &bb) override; uint32 FloatParamRegRequired(MIRStructType *structType, uint32 &fpSize) override; void AssignLmbcFormalParams() override; - RegOperand *GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType); + void LmbcGenSaveSpForAlloca() override; + MemOperand *GenLmbcFpMemOperand(int32 offset, uint32 byteSize, AArch64reg base = RFP); + RegOperand *GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType, AArch64reg baseRegno = RFP); + RegOperand *LmbcStructReturnLoad(int32 offset); Operand *GetBaseReg(const AArch64SymbolAlloc &symAlloc); int32 GetBaseOffset(const SymbolAlloc &symAlloc) override; @@ -731,6 +738,22 @@ class AArch64CGFunc : public CGFunc { RegOperand &GetZeroOpnd(uint32 size) override; + int32 GetLmbcTotalStkUsed() { + return lmbcArgInfo->lmbcTotalStkUsed; + } + + void SetLmbcTotalStkUsed(int32 offset) { + lmbcArgInfo->lmbcTotalStkUsed = offset; + } + + void SetLmbcCallReturnType(MIRType *ty) { + lmbcCallReturnType = ty; + } + + MIRType *GetLmbcCallReturnType() { + return lmbcCallReturnType; + } + private: enum RelationOperator : uint8 { kAND, @@ -798,6 +821,7 @@ class AArch64CGFunc : public CGFunc { regno_t methodHandleVreg = -1; uint32 alignPow = 5; /* function align pow defaults to 5 i.e. 2^5*/ LmbcArgInfo *lmbcArgInfo = nullptr; + MIRType *lmbcCallReturnType = nullptr; void SelectLoadAcquire(Operand &dest, PrimType dtype, Operand &src, PrimType stype, AArch64isa::MemoryOrdering memOrd, bool isDirect); diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def b/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def index a3a74d7b2f..ff08e81852 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def @@ -16,8 +16,8 @@ ADDTARGETPHASE("createstartendlabel", true); ADDTARGETPHASE("buildehfunc", true); ADDTARGETPHASE("handlefunction", true); + ADDTARGETPHASE("moveargs", true); if (GetMIRModule()->GetFlavor() != MIRFlavor::kFlavorLmbc) { - ADDTARGETPHASE("moveargs", true); /* SSA PHASES */ ADDTARGETPHASE("cgssaconstruct", CGOptions::DoCGSSA()); ADDTARGETPHASE("cgcopyprop", CGOptions::DoCGSSA()); diff --git a/src/mapleall/maple_be/include/cg/call_conv.h b/src/mapleall/maple_be/include/cg/call_conv.h index 9cfab98b56..4e33309c3c 100644 --- a/src/mapleall/maple_be/include/cg/call_conv.h +++ b/src/mapleall/maple_be/include/cg/call_conv.h @@ -63,8 +63,8 @@ struct CCLocInfo { class LmbcFormalParamInfo { public: LmbcFormalParamInfo(PrimType pType, uint32 ofst, uint32 sz) : - type(nullptr), primType(pType), offset(ofst), size(sz), regNO(0), vregNO(0), numRegs(0), - fpSize(0), isReturn(false), isPureFloat(false), isOnStack(false) {} + type(nullptr), primType(pType), offset(ofst), onStackOffset(0), size(sz), regNO(0), vregNO(0), numRegs(0), + fpSize(0), isReturn(false), isPureFloat(false), isOnStack(false), hasRegassign(false) {} ~LmbcFormalParamInfo() = default; @@ -86,7 +86,13 @@ class LmbcFormalParamInfo { void SetOffset(uint32 ofs) { offset = ofs; } - uint32 GetSize() const { + uint32 GetOnStackOffset() { + return onStackOffset; + } + void SetOnStackOffset(uint32 ofs) { + onStackOffset = ofs; + } + uint32 GetSize() { return size; } void SetSize(uint32 sz) { @@ -137,10 +143,17 @@ class LmbcFormalParamInfo { void SetIsOnStack() { isOnStack = true; } + bool HasRegassign() { + return hasRegassign; + } + void SetHasRegassign() { + hasRegassign = true; + } private: MIRStructType *type; PrimType primType; uint32 offset; + uint32 onStackOffset; /* stack location if isOnStack */ uint32 size; /* size primtype or struct */ regno_t regNO = 0; /* param reg num or starting reg num if numRegs > 0 */ regno_t vregNO = 0; /* if no explicit regassing from IR, create move from param reg */ @@ -148,7 +161,8 @@ class LmbcFormalParamInfo { uint32 fpSize = 0; /* size of fp param if isPureFloat */ bool isReturn; bool isPureFloat = false; - bool isOnStack; /* small struct with arrays need to be saved onto stack */ + bool isOnStack; /* large struct is passed by a copy on stack */ + bool hasRegassign; }; } /* namespace maplebe */ diff --git a/src/mapleall/maple_be/include/cg/cg.h b/src/mapleall/maple_be/include/cg/cg.h index 093289e42b..e1368acb1d 100644 --- a/src/mapleall/maple_be/include/cg/cg.h +++ b/src/mapleall/maple_be/include/cg/cg.h @@ -121,11 +121,13 @@ class CG { emitter(nullptr), labelOrderCnt(0), cgOption(cgOptions), - instrumentationFunction(nullptr) { + instrumentationFunction(nullptr), + fileGP(nullptr) { const std::string &internalNameLiteral = namemangler::GetInternalNameLiteral(namemangler::kJavaLangObjectStr); GStrIdx strIdxFromName = GlobalTables::GetStrTable().GetStrIdxFromName(internalNameLiteral); isLibcore = (GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdxFromName) != nullptr); DefineDebugTraceFunctions(); + isLmbc = (mirModule->GetFlavor() == MIRFlavor::kFlavorLmbc); } virtual ~CG(); @@ -361,6 +363,10 @@ class CG { return isLibcore; } + bool IsLmbc() const { + return isLmbc; + } + MIRSymbol *GetDebugTraceEnterFunction() { return dbgTraceEnter; } @@ -421,6 +427,13 @@ class CG { /* Object map generation helper */ std::vector GetReferenceOffsets64(const BECommon &beCommon, MIRStructType &structType); + void SetGP(MIRSymbol *sym) { + fileGP = sym; + } + MIRSymbol *GetGP() const { + return fileGP; + } + static bool IsInFuncWrapLabels(MIRFunction *func) { return funcWrapLabels.find(func) != funcWrapLabels.end(); } @@ -449,12 +462,14 @@ class CG { LabelIDOrder labelOrderCnt; static CGFunc *currentCGFunction; /* current cg function being compiled */ CGOptions cgOption; - bool isLibcore; MIRSymbol *instrumentationFunction; MIRSymbol *dbgTraceEnter; MIRSymbol *dbgTraceExit; MIRSymbol *dbgFuncProfile; + MIRSymbol *fileGP; /* for lmbc, one local %GP per file */ static std::map> funcWrapLabels; + bool isLibcore; + bool isLmbc; }; /* class CG */ } /* namespace maplebe */ diff --git a/src/mapleall/maple_be/include/cg/cgfunc.h b/src/mapleall/maple_be/include/cg/cgfunc.h index 9623c989e4..0695a784de 100644 --- a/src/mapleall/maple_be/include/cg/cgfunc.h +++ b/src/mapleall/maple_be/include/cg/cgfunc.h @@ -160,6 +160,7 @@ class CGFunc { virtual uint32 FloatParamRegRequired(MIRStructType *structType, uint32 &fpSize) = 0; virtual void AssignLmbcFormalParams() = 0; LmbcFormalParamInfo *GetLmbcFormalParamInfo(uint32 offset); + virtual void LmbcGenSaveSpForAlloca() = 0; void GenerateLoc(StmtNode *stmt, unsigned &lastSrcLoc, unsigned &lastMplLoc); int32 GetFreqFromStmt(uint32 stmtId); void GenerateInstruction(); @@ -201,6 +202,7 @@ class CGFunc { virtual void SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd) = 0; virtual void SelectBlkassignoff(BlkassignoffNode &bNode, Operand *src) = 0; virtual void SelectAggIassign(IassignNode &stmt, Operand &lhsAddrOpnd) = 0; + virtual void SelectReturnSendOfStructInRegs(BaseNode *x) = 0; virtual void SelectReturn(Operand *opnd) = 0; virtual void SelectIgoto(Operand *opnd0) = 0; virtual void SelectCondGoto(CondGotoNode &stmt, Operand &opnd0, Operand &opnd1) = 0; diff --git a/src/mapleall/maple_be/src/be/lower.cpp b/src/mapleall/maple_be/src/be/lower.cpp index 146ec61a56..72d832477d 100644 --- a/src/mapleall/maple_be/src/be/lower.cpp +++ b/src/mapleall/maple_be/src/be/lower.cpp @@ -121,6 +121,7 @@ void CGLowerer::RegisterExternalLibraryFunctions() { func->AllocSymTab(); MIRSymbol *funcSym = func->GetFuncSymbol(); funcSym->SetStorageClass(kScExtern); + funcSym->SetAppearsInCode(true); /* return type */ MIRType *retTy = GlobalTables::GetTypeTable().GetPrimType(extFnDescrs[i].retType); @@ -875,7 +876,7 @@ void CGLowerer::LowerTypePtr(BaseNode &node) const { #if TARGARM32 || TARGAARCH64 || TARGRISCV64 -BlockNode *CGLowerer::LowerReturnStruct(NaryStmtNode &retNode) { +BlockNode *CGLowerer::LowerReturnStructUsingFakeParm(NaryStmtNode &retNode) { BlockNode *blk = mirModule.CurFuncCodeMemPool()->New(); for (size_t i = 0; i < retNode.GetNopndSize(); ++i) { retNode.SetOpnd(LowerExpr(retNode, *retNode.GetNopndAt(i), *blk), i); @@ -1100,7 +1101,7 @@ void CGLowerer::LowerCallStmt(StmtNode &stmt, StmtNode *&nextStmt, BlockNode &ne return; } - if ((newStmt->GetOpCode() == OP_call) || (newStmt->GetOpCode() == OP_icall)) { + if (newStmt->GetOpCode() == OP_call || newStmt->GetOpCode() == OP_icall || newStmt->GetOpCode() == OP_icallproto) { newStmt = LowerCall(static_cast(*newStmt), nextStmt, newBlk, retty, uselvar); } newStmt->SetSrcPos(stmt.GetSrcPos()); @@ -1171,7 +1172,12 @@ StmtNode *CGLowerer::GenIntrinsiccallNode(const StmtNode &stmt, PUIdx &funcCalle StmtNode *CGLowerer::GenIcallNode(PUIdx &funcCalled, IcallNode &origCall) { StmtNode *newCall = nullptr; - newCall = mirModule.GetMIRBuilder()->CreateStmtIcall(origCall.GetNopnd()); + if (origCall.GetOpCode() == OP_icallassigned) { + newCall = mirModule.GetMIRBuilder()->CreateStmtIcall(origCall.GetNopnd()); + } else { + newCall = mirModule.GetMIRBuilder()->CreateStmtIcallproto(origCall.GetNopnd()); + static_cast(newCall)->SetRetTyIdx(static_cast(origCall).GetRetTyIdx()); + } newCall->SetSrcPos(origCall.GetSrcPos()); CHECK_FATAL(newCall != nullptr, "nullptr is not expected"); funcCalled = kFuncNotFound; @@ -1373,6 +1379,7 @@ BlockNode *CGLowerer::LowerCallAssignedStmt(StmtNode &stmt, bool uselvar) { static_cast(newCall)->SetReturnVec(*p2nRets); break; } + case OP_icallprotoassigned: case OP_icallassigned: { auto &origCall = static_cast(stmt); newCall = GenIcallNode(funcCalled, origCall); @@ -1480,6 +1487,15 @@ bool CGLowerer::LowerStructReturn(BlockNode &newBlk, StmtNode *stmt, (*p2nrets)[0].first = dnodeStmt->GetStIdx(); (*p2nrets)[0].second.SetFieldID(dnodeStmt->GetFieldID()); lvar = true; + // set ATTR_firstarg_return for callee + if (stmt->GetOpCode() == OP_callassigned) { + CallNode *callNode = static_cast(stmt); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callNode->GetPUIdx()); + f->SetFirstArgReturn(); + f->GetMIRFuncType()->SetFirstArgReturn(); + } else { + // for icall, front-end already set ATTR_firstarg_return + } } else { /* struct <= 16 passed in regs lowered into call &foo regassign u64 %1 (regread u64 %%retval0) @@ -1497,13 +1513,19 @@ bool CGLowerer::LowerStructReturn(BlockNode &newBlk, StmtNode *stmt, CallNode *callStmt = mirModule.GetMIRBuilder()->CreateStmtCall(callNode->GetPUIdx(), callNode->GetNopnd()); callStmt->SetSrcPos(callNode->GetSrcPos()); newBlk.AddStatement(callStmt); - } else if (stmt->GetOpCode() == OP_icallassigned) { + } else if (stmt->GetOpCode() == OP_icallassigned || stmt->GetOpCode() == OP_icallprotoassigned) { auto *icallNode = static_cast(stmt); for (size_t i = 0; i < icallNode->GetNopndSize(); ++i) { BaseNode *newOpnd = LowerExpr(*icallNode, *icallNode->GetNopndAt(i), newBlk); icallNode->SetOpnd(newOpnd, i); } - IcallNode *icallStmt = mirModule.GetMIRBuilder()->CreateStmtIcall(icallNode->GetNopnd()); + IcallNode *icallStmt = nullptr; + if (stmt->GetOpCode() == OP_icallassigned) { + icallStmt = mirModule.GetMIRBuilder()->CreateStmtIcall(icallNode->GetNopnd()); + } else { + icallStmt = mirModule.GetMIRBuilder()->CreateStmtIcallproto(icallNode->GetNopnd()); + icallStmt->SetRetTyIdx(icallNode->GetRetTyIdx()); + } icallStmt->SetSrcPos(icallNode->GetSrcPos()); newBlk.AddStatement(icallStmt); } else { @@ -1769,6 +1791,7 @@ void CGLowerer::LowerAssertBoundary(StmtNode &stmt, BlockNode &block, BlockNode CondGotoNode *brFalseNode = mirBuilder->CreateStmtCondGoto(cond, OP_brfalse, labIdx); MIRFunction *printf = mirBuilder->GetOrCreateFunction("printf", TyIdx(PTY_i32)); + printf->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*printf->GetMIRFuncType()); MapleVector argsPrintf(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); uint32 oldTypeTableSize = GlobalTables::GetTypeTable().GetTypeTableSize(); @@ -1843,7 +1866,8 @@ BlockNode *CGLowerer::LowerBlock(BlockNode &block) { break; } case OP_callassigned: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallprotoassigned: { // pass the addr of lvar if this is a struct call assignment bool lvar = false; // nextStmt could be changed by the call to LowerStructReturn @@ -1863,6 +1887,7 @@ BlockNode *CGLowerer::LowerBlock(BlockNode &block) { case OP_intrinsiccall: case OP_call: case OP_icall: + case OP_icallproto: #if TARGARM32 || TARGAARCH64 || TARGRISCV64 || TARGX86_64 // nextStmt could be changed by the call to LowerStructReturn LowerCallStmt(*stmt, nextStmt, *newBlk); @@ -1872,8 +1897,8 @@ BlockNode *CGLowerer::LowerBlock(BlockNode &block) { break; case OP_return: { #if TARGARM32 || TARGAARCH64 || TARGRISCV64 - if (GetCurrentFunc()->IsReturnStruct()) { - newBlk->AppendStatementsFromBlock(*LowerReturnStruct(static_cast(*stmt))); + if (GetCurrentFunc()->IsFirstArgReturn() && stmt->NumOpnds() > 0) { + newBlk->AppendStatementsFromBlock(*LowerReturnStructUsingFakeParm(static_cast(*stmt))); } else { #endif NaryStmtNode *retNode = static_cast(stmt); @@ -1971,7 +1996,9 @@ void CGLowerer::SimplifyBlock(BlockNode &block) { } auto *newFunc = theMIRModule->GetMIRBuilder()->GetOrCreateFunction(asmMap.at(oldFunc->GetName()), callStmt->GetTyIdx()); - newFunc->GetFuncSymbol()->SetStorageClass(kScExtern); + MIRSymbol *funcSym = newFunc->GetFuncSymbol(); + funcSym->SetStorageClass(kScExtern); + funcSym->SetAppearsInCode(true); callStmt->SetPUIdx(newFunc->GetPuidx()); break; } @@ -2081,6 +2108,7 @@ StmtNode *CGLowerer::LowerCall( if (needCheckStore) { MIRFunction *fn = mirModule.GetMIRBuilder()->GetOrCreateFunction("MCC_Reflect_Check_Arraystore", TyIdx(PTY_void)); + fn->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); MapleVector args(mirModule.GetMIRBuilder()->GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -2107,7 +2135,7 @@ StmtNode *CGLowerer::LowerCall( } MIRType *retType = nullptr; - if (callNode.op == OP_icall) { + if (callNode.op == OP_icall || callNode.op == OP_icallproto) { if (retTy == nullptr) { return &callNode; } else { @@ -2153,7 +2181,7 @@ StmtNode *CGLowerer::LowerCall( addrofNode->SetStIdx(dsgnSt->GetStIdx()); addrofNode->SetFieldID(0); - if (callNode.op == OP_icall) { + if (callNode.op == OP_icall || callNode.op == OP_icallproto) { auto ond = callNode.GetNopnd().begin(); newNopnd.emplace_back(*ond); newNopnd.emplace_back(addrofNode); @@ -2175,7 +2203,27 @@ StmtNode *CGLowerer::LowerCall( } void CGLowerer::LowerEntry(MIRFunction &func) { + // determine if needed to insert fake parameter to return struct for current function if (func.IsReturnStruct()) { + MIRType *retType = func.GetReturnType(); +#if TARGAARCH64 + PrimType pty = IsStructElementSame(retType); + if (pty == PTY_f32 || pty == PTY_f64 || IsPrimitiveVector(pty)) { + func.SetStructReturnedInRegs(); + return; + } +#endif + if (retType->GetPrimType() != PTY_agg) { + return; + } + if (retType->GetSize() > k16ByteSize) { + func.SetFirstArgReturn(); + func.GetMIRFuncType()->SetFirstArgReturn(); + } else { + func.SetStructReturnedInRegs(); + } + } + if (func.IsFirstArgReturn() && func.GetReturnType()->GetPrimType() != PTY_void) { MIRSymbol *retSt = func.GetSymTab()->CreateSymbol(kScopeLocal); retSt->SetStorageClass(kScFormal); retSt->SetSKind(kStVar); @@ -2192,12 +2240,14 @@ void CGLowerer::LowerEntry(MIRFunction &func) { auto formal = func.GetFormal(i); formals.emplace_back(formal); } + func.SetFirstArgReturn(); beCommon.AddElementToFuncReturnType(func, func.GetReturnTyIdx()); func.UpdateFuncTypeAndFormalsAndReturnType(formals, TyIdx(PTY_void), true); auto *funcType = func.GetMIRFuncType(); ASSERT(funcType != nullptr, "null ptr check"); + funcType->SetFirstArgReturn(); beCommon.AddTypeSizeAndAlign(funcType->GetTypeIndex(), GetPrimTypeSize(funcType->GetPrimType())); } } @@ -2375,6 +2425,7 @@ MIRFunction *CGLowerer::RegisterFunctionVoidStarToVoid(BuiltinFunctionID id, con func->AllocSymTab(); MIRSymbol *funcSym = func->GetFuncSymbol(); funcSym->SetStorageClass(kScExtern); + funcSym->SetAppearsInCode(true); MIRType *argTy = GlobalTables::GetTypeTable().GetPtr(); MIRSymbol *argSt = func->GetSymTab()->CreateSymbol(kScopeLocal); argSt->SetNameStrIdx(mirBuilder->GetOrCreateStringIndex(paramName)); @@ -2416,6 +2467,7 @@ void CGLowerer::RegisterBuiltIns() { func->AllocSymTab(); MIRSymbol *funcSym = func->GetFuncSymbol(); funcSym->SetStorageClass(kScExtern); + funcSym->SetAppearsInCode(true); /* return type */ MIRType *retTy = desc.GetReturnType(); CHECK_FATAL(retTy != nullptr, "retTy should not be nullptr"); @@ -2571,6 +2623,7 @@ void CGLowerer::ProcessArrayExpr(BaseNode &expr, BlockNode &blkNode) { arrayNode.GetNopndAt(1), lenRegreadNode); CondGotoNode *brFalseNode = mirBuilder->CreateStmtCondGoto(cond, OP_brfalse, labIdx); MIRFunction *fn = mirBuilder->GetOrCreateFunction("MCC_Array_Boundary_Check", TyIdx(PTY_void)); + fn->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); MapleVector args(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -3102,6 +3155,7 @@ BaseNode *CGLowerer::LowerIntrinJavaArrayLength(const BaseNode &parent, Intrinsi MIRFunction *newFunc = mirBuilder->GetOrCreateFunction("MCC_ThrowNullArrayNullPointerException", GlobalTables::GetTypeTable().GetVoid()->GetTypeIndex()); + newFunc->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*newFunc->GetMIRFuncType()); newFunc->AllocSymTab(); MapleVector args(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -3473,6 +3527,7 @@ StmtNode *CGLowerer::LowerIntrinsicRCCall(const IntrinsiccallNode &intrincall) { if (intrinFuncIDs.find(intrinDesc) == intrinFuncIDs.end()) { /* add funcid into map */ MIRFunction *fn = mirBuilder->GetOrCreateFunction(intrinDesc->name, TyIdx(PTY_void)); + fn->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); intrinFuncIDs[intrinDesc] = fn->GetPuidx(); @@ -3501,6 +3556,7 @@ void CGLowerer::LowerArrayStore(const IntrinsiccallNode &intrincall, BlockNode & if (needCheckStore) { MIRFunction *fn = mirBuilder->GetOrCreateFunction("MCC_Reflect_Check_Arraystore", TyIdx(PTY_void)); + fn->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); MapleVector args(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -3590,6 +3646,7 @@ StmtNode *CGLowerer::LowerIntrinsiccall(IntrinsiccallNode &intrincall, BlockNode beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); st->SetFunction(fn); + st->SetAppearsInCode(true); return LowerDefaultIntrinsicCall(intrincall, *st, *fn); } @@ -3660,6 +3717,7 @@ PUIdx CGLowerer::GetBuiltinToUse(BuiltinFunctionID id) const { void CGLowerer::LowerGCMalloc(const BaseNode &node, const GCMallocNode &gcmalloc, BlockNode &blkNode, bool perm) { MIRFunction *func = mirBuilder->GetOrCreateFunction((perm ? "MCC_NewPermanentObject" : "MCC_NewObj_fixed_class"), (TyIdx)(LOWERED_PTR_TYPE)); + func->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*func->GetMIRFuncType()); func->AllocSymTab(); /* Get the classinfo */ @@ -3678,6 +3736,7 @@ void CGLowerer::LowerGCMalloc(const BaseNode &node, const GCMallocNode &gcmalloc if (classSym->GetAttr(ATTR_abstract) || classSym->GetAttr(ATTR_interface)) { MIRFunction *funcSecond = mirBuilder->GetOrCreateFunction("MCC_Reflect_ThrowInstantiationError", (TyIdx)(LOWERED_PTR_TYPE)); + funcSecond->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*funcSecond->GetMIRFuncType()); funcSecond->AllocSymTab(); BaseNode *arg = mirBuilder->CreateExprAddrof(0, *classSym); @@ -3796,6 +3855,7 @@ void CGLowerer::LowerJarrayMalloc(const StmtNode &stmt, const JarrayMallocNode & args.emplace_back(mirBuilder->CreateIntConst(0, PTY_u32)); } MIRFunction *func = mirBuilder->GetOrCreateFunction(funcName, (TyIdx)(LOWERED_PTR_TYPE)); + func->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*func->GetMIRFuncType()); func->AllocSymTab(); CallNode *callAssign = nullptr; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 4258f5a06f..ea2b40db14 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -38,7 +38,7 @@ void AArch64MoveRegArgs::CollectRegisterArgs(std::map &argsL uint32 start = 0; if (numFormal) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsReturnStruct()) { + if (func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16ByteSize) { start = 1; @@ -439,7 +439,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsReturnStruct()) { + if (func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp index 51fb1a1265..b89e1b4c40 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp @@ -300,7 +300,7 @@ int32 AArch64CallConvImpl::LocateNextParm(MIRType &mirType, CCLocInfo &pLoc, boo if (isFirst) { MIRFunction *func = tFunc != nullptr ? tFunc : const_cast(beCommon.GetMIRModule().CurFunction()); - if (func->IsReturnStruct()) { + if (func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); size_t size = beCommon.GetTypeSize(tyIdx); if (size == 0) { 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 3950a75128..d5e3e9f531 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -1411,15 +1411,44 @@ void AArch64CGFunc::SelectAsm(AsmNode &node) { } void AArch64CGFunc::SelectRegassign(RegassignNode &stmt, Operand &opnd0) { + if (GetCG()->IsLmbc()) { + PrimType lhsSize = stmt.GetPrimType(); + PrimType rhsSize = stmt.Opnd(0)->GetPrimType(); + if (lhsSize != rhsSize && stmt.Opnd(0)->GetOpCode() == OP_ireadoff) { + Insn *prev = GetCurBB()->GetLastInsn(); + if (prev->GetMachineOpcode() == MOP_wldrsb || prev->GetMachineOpcode() == MOP_wldrsh) { + opnd0.SetSize(GetPrimTypeBitSize(stmt.GetPrimType())); + prev->SetMOP(prev->GetMachineOpcode() == MOP_wldrsb ? MOP_xldrsb : MOP_xldrsh); + } else if (prev->GetMachineOpcode() == MOP_wldr && stmt.GetPrimType() == PTY_i64) { + opnd0.SetSize(GetPrimTypeBitSize(stmt.GetPrimType())); + prev->SetMOP(MOP_xldrsw); + } + } + } RegOperand *regOpnd = nullptr; PregIdx pregIdx = stmt.GetRegIdx(); if (IsSpecialPseudoRegister(pregIdx)) { - regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, stmt.GetPrimType()); + if (GetCG()->IsLmbc() && stmt.GetPrimType() == PTY_agg) { + if (static_cast(opnd0).IsOfIntClass()) { + regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, PTY_i64); + } else if (opnd0.GetSize() <= k4ByteSize) { + regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, PTY_f32); + } else { + regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, PTY_f64); + } + } else { + regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, stmt.GetPrimType()); + } } else { regOpnd = &GetOrCreateVirtualRegisterOperand(GetVirtualRegNOFromPseudoRegIdx(pregIdx)); } /* look at rhs */ PrimType rhsType = stmt.Opnd(0)->GetPrimType(); + if (GetCG()->IsLmbc() && rhsType == PTY_agg) { + /* This occurs when a call returns a small struct */ + /* The subtree should already taken care of the agg type that is in excess of 8 bytes */ + rhsType = PTY_i64; + } PrimType dtype = rhsType; if (GetPrimTypeBitSize(dtype) < k32BitSize) { ASSERT(IsPrimitiveInteger(dtype), ""); @@ -1441,6 +1470,12 @@ void AArch64CGFunc::SelectRegassign(RegassignNode &stmt, Operand &opnd0) { MIRPreg *preg = GetFunction().GetPregTab()->PregFromPregIdx(pregIdx); uint32 srcBitLength = GetPrimTypeSize(preg->GetPrimType()) * kBitsPerByte; GetCurBB()->AppendInsn(GetCG()->BuildInstruction(PickStInsn(srcBitLength, stype), *regOpnd, *dest)); + } else if (regOpnd->GetRegisterNumber() == R0 || regOpnd->GetRegisterNumber() == R1) { + Insn &pseudo = GetCG()->BuildInstruction(MOP_pseudo_ret_int, *regOpnd); + GetCurBB()->AppendInsn(pseudo); + } else if (regOpnd->GetRegisterNumber() >= V0 && regOpnd->GetRegisterNumber() <= V3) { + Insn &pseudo = GetCG()->BuildInstruction(MOP_pseudo_ret_float, *regOpnd); + GetCurBB()->AppendInsn(pseudo); } } @@ -1922,15 +1957,11 @@ void AArch64CGFunc::SelectIassignoff(IassignoffNode &stmt) { SelectCopy(memOpnd, destType, srcOpnd, destType); } -void AArch64CGFunc::SelectIassignfpoff(IassignFPoffNode &stmt, Operand &opnd) { - int32 offset = stmt.GetOffset(); - PrimType primType = stmt.GetPrimType(); - uint32 bitlen = GetPrimTypeSize(primType) * kBitsPerByte; - - Operand &srcOpnd = LoadIntoRegister(opnd, primType); +MemOperand *AArch64CGFunc::GenLmbcFpMemOperand(int32 offset, uint32 byteSize, AArch64reg baseRegno) { MemOperand *memOpnd; - RegOperand *rfp = &GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); - if (offset < 0) { + RegOperand *rfp = &GetOrCreatePhysicalRegisterOperand(baseRegno, k64BitSize, kRegTyInt); + uint32 bitlen = byteSize * kBitsPerByte; + if (offset < 0 && offset < -256) { RegOperand *baseOpnd = &CreateRegisterOperandOfType(PTY_a64); ImmOperand &immOpnd = CreateImmOperand(offset, k32BitSize, true); Insn &addInsn = GetCG()->BuildInstruction(MOP_xaddrri12, *baseOpnd, *rfp, immOpnd); @@ -1942,11 +1973,45 @@ void AArch64CGFunc::SelectIassignfpoff(IassignFPoffNode &stmt, Operand &opnd) { memOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, bitlen, rfp, nullptr, offsetOpnd, nullptr); } memOpnd->SetStackMem(true); - MOperator mOp = PickStInsn(bitlen, primType); - Insn &store = GetCG()->BuildInstruction(mOp, srcOpnd, *memOpnd); - GetCurBB()->AppendInsn(store); + return memOpnd; +} + +void AArch64CGFunc::SelectIassignfpoff(IassignFPoffNode &stmt, Operand &opnd) { + int32 offset = stmt.GetOffset(); + PrimType primType = stmt.GetPrimType(); + MIRType *rType = GetLmbcCallReturnType(); + bool isPureFpStruct = false; + uint32 numRegs = 0; + if (rType && rType->GetPrimType() == PTY_agg && opnd.IsRegister() && static_cast(opnd).IsPhysicalRegister()) { + CHECK_FATAL(rType->GetSize() <= 16, "SelectIassignfpoff invalid agg size"); + uint32 fpSize; + numRegs = FloatParamRegRequired(static_cast(rType), fpSize); + if (numRegs) { + primType = (fpSize == k4ByteSize) ? PTY_f32 : PTY_f64; + isPureFpStruct = true; + } + } + uint32 byteSize = GetPrimTypeSize(primType); + uint32 bitlen = byteSize * kBitsPerByte; + if (isPureFpStruct) { + for (int i = 0 ; i < numRegs; ++i) { + MemOperand *memOpnd = GenLmbcFpMemOperand(offset + (i * byteSize), byteSize); + RegOperand &srcOpnd = GetOrCreatePhysicalRegisterOperand(AArch64reg(V0 + i), bitlen, kRegTyFloat); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, srcOpnd, *memOpnd); + GetCurBB()->AppendInsn(store); + } + } else { + Operand &srcOpnd = LoadIntoRegister(opnd, primType); + MemOperand *memOpnd = GenLmbcFpMemOperand(offset, byteSize); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, srcOpnd, *memOpnd); + GetCurBB()->AppendInsn(store); + } } +/* Load and assign to a new register. To be moved to the correct call register OR stack + location in LmbcSelectParmList */ void AArch64CGFunc::SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd) { if (GetLmbcArgInfo() == nullptr) { LmbcArgInfo *p = memPool->New(*GetFuncScopeAllocator()); @@ -1973,7 +2038,7 @@ void AArch64CGFunc::SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd } /* Search for CALL/ICALL/ICALLPROTO node, must be called from a blkassignoff node */ -MIRType *AArch64CGFunc::GetAggTyFromCallSite(StmtNode *stmt) { +MIRType *AArch64CGFunc::LmbcGetAggTyFromCallSite(StmtNode *stmt, std::vector **parmList) { for ( ; stmt != nullptr; stmt = stmt->GetNext()) { if (stmt->GetOpCode() == OP_call || stmt->GetOpCode() == OP_icallproto) { break; @@ -1986,25 +2051,20 @@ MIRType *AArch64CGFunc::GetAggTyFromCallSite(StmtNode *stmt) { if (stmt->GetOpCode() == OP_call) { CallNode *callNode = static_cast(stmt); MIRFunction *fn = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callNode->GetPUIdx()); - if (fn->IsReturnStruct()) { - ++nargs; - } if (fn->GetFormalCount() > 0) { - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fn->GetNthParamTyIdx(nargs)); + ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fn->GetFormalDefVec()[nargs].formalTyIdx); } + *parmList = &fn->GetParamTypes(); // would return null if the actual parameter is bogus } else if (stmt->GetOpCode() == OP_icallproto) { IcallNode *icallproto = static_cast(stmt); MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallproto->GetRetTyIdx()); MIRFuncType *fType = static_cast(type); - MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fType->GetRetTyIdx()); - if (retType->GetKind() == kTypeStruct) { - ++nargs; - } ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fType->GetNthParamType(nargs)); + *parmList = &fType->GetParamTypeList(); } else { CHECK_FATAL(stmt->GetOpCode() == OP_icallproto, - "GetAggTyFromCallSite:: unexpected call operator"); + "LmbcGetAggTyFromCallSite:: unexpected call operator"); } return ty; } @@ -2080,11 +2140,11 @@ bool AArch64CGFunc::LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *s } /* return true if blkassignoff for return, false otherwise */ -bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src) { +bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList) { AArch64reg regno = static_cast(static_cast(src)->GetRegisterNumber()); if (IsBlkassignForPush(bNode)) { PrimType pTy = PTY_i64; - MIRStructType *ty = static_cast(GetAggTyFromCallSite(&bNode)); + MIRStructType *ty = static_cast(LmbcGetAggTyFromCallSite(&bNode, parmList)); uint32 size = 0; uint32 fpregs = ty ? FloatParamRegRequired(ty, size) : 0; /* fp size determined */ if (fpregs > 0) { @@ -2095,7 +2155,7 @@ bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src) { MemOperand &mem = CreateMemOpnd(regno, s, size * kBitsPerByte); RegOperand *res = &CreateVirtualRegisterOperand(NewVReg(kRegTyFloat, size)); SelectCopy(*res, pTy, mem, pTy); - SetLmbcArgInfo(res, pTy, bNode.offset + s, static_cast(fpregs)); + SetLmbcArgInfo(res, pTy, 0, fpregs); IncLmbcArgsInRegs(kRegTyFloat); } IncLmbcTotalArgs(); @@ -2136,6 +2196,41 @@ bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src) { return false; } +/* This function is incomplete and may be removed when Lmbc IR is changed + to have the lowerer figures out the address of the large agg to reside */ +uint32 AArch64CGFunc::LmbcFindTotalStkUsed(std::vector *paramList) { + AArch64CallConvImpl parmlocator(GetBecommon()); + CCLocInfo pLoc; + for (TyIdx tyIdx : *paramList) { + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); + parmlocator.LocateNextParm(*ty, pLoc); + } + return 0; +} + +/* All arguments passed as registers */ +uint32 AArch64CGFunc::LmbcTotalRegsUsed() { + if (GetLmbcArgInfo() == nullptr) { + return 0; /* no arg */ + } + MapleVector ®s = GetLmbcCallArgNumOfRegs(); + MapleVector &types = GetLmbcCallArgTypes(); + uint32 iCnt = 0; + uint32 fCnt = 0; + for (uint32 i = 0; i < regs.size(); i++) { + if (IsPrimitiveInteger(types[i])) { + if ((iCnt + regs[i]) <= k8ByteSize) { + iCnt += regs[i]; + }; + } else { + if ((fCnt + regs[i]) <= k8ByteSize) { + fCnt += regs[i]; + }; + } + } + return iCnt + fCnt; +} + /* If blkassignoff for argument, this function loads the agg arguments into virtual registers, disregard if there is sufficient physicall call registers. Argument > 16-bytes are copied to preset space and ptr @@ -2144,29 +2239,40 @@ bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src) { void AArch64CGFunc::SelectBlkassignoff(BlkassignoffNode &bNode, Operand *src) { CHECK_FATAL(src->GetKind() == Operand::kOpdRegister, "blkassign src type not in register"); + std::vector *parmList; if (GetLmbcArgInfo() == nullptr) { LmbcArgInfo *p = memPool->New(*GetFuncScopeAllocator()); SetLmbcArgInfo(p); } if (LmbcSmallAggForRet(bNode, src)) { return; - } else if (LmbcSmallAggForCall(bNode, src)) { + } else if (LmbcSmallAggForCall(bNode, src, &parmList)) { return; } - /* memcpy for agg assign OR large agg for arg/ret */ Operand *dest = HandleExpr(bNode, *bNode.Opnd(0)); RegOperand *regResult = &CreateVirtualRegisterOperand(NewVReg(kRegTyInt, k8ByteSize)); + /* memcpy for agg assign OR large agg for arg/ret */ + int32 offset = bNode.offset; + if (IsBlkassignForPush(bNode)) { + /* large agg for call, addr to be pushed in SelectCall */ + offset = GetLmbcTotalStkUsed(); + if (offset < 0) { + /* length of ALL stack based args for this call, this location is where the + next large agg resides, its addr will then be passed */ + offset = LmbcFindTotalStkUsed(parmList) + LmbcTotalRegsUsed(); + } + SetLmbcTotalStkUsed(offset + bNode.blockSize); /* next use */ + SetLmbcArgInfo(regResult, PTY_i64, 0, 1); /* 1 reg for ptr */ + IncLmbcArgsInRegs(kRegTyInt); + IncLmbcTotalArgs(); + /* copy large agg arg to offset below */ + } std::vector opndVec; opndVec.push_back(regResult); /* result */ - opndVec.push_back(PrepareMemcpyParamOpnd(bNode.offset, *dest)); /* param 0 */ + opndVec.push_back(PrepareMemcpyParamOpnd(offset, *dest)); /* param 0 */ opndVec.push_back(src); /* param 1 */ opndVec.push_back(PrepareMemcpyParamOpnd(static_cast(static_cast(bNode.blockSize)))); /* param 2 */ SelectLibCall("memcpy", opndVec, PTY_a64, PTY_a64); - if (IsBlkassignForPush(bNode)) { - SetLmbcArgInfo(static_cast(src), PTY_i64, (int32)bNode.offset, 1); - IncLmbcArgsInRegs(kRegTyInt); - IncLmbcTotalArgs(); - } } void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { @@ -2553,6 +2659,159 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { } } +void AArch64CGFunc::SelectReturnSendOfStructInRegs(BaseNode *x) { + uint32 offset = 0; + if (x->GetOpCode() == OP_dread) { + DreadNode *dread = static_cast(x); + MIRSymbol *sym = GetFunction().GetLocalOrGlobalSymbol(dread->GetStIdx()); + MIRType *mirType = sym->GetType(); + if (dread->GetFieldID() != 0) { + MIRStructType *structType = static_cast(mirType); + mirType = structType->GetFieldType(dread->GetFieldID()); + offset = static_cast(GetBecommon().GetFieldOffset(*structType, dread->GetFieldID()).first); + } + uint32 typeSize = GetBecommon().GetTypeSize(mirType->GetTypeIndex()); + /* generate move to regs for agg return */ + AArch64CallConvImpl parmlocator(GetBecommon()); + CCLocInfo pLoc; + parmlocator.LocateNextParm(*mirType, pLoc, true, GetBecommon().GetMIRModule().CurFunction()); + /* aggregates are 8 byte aligned. */ + Operand *rhsmemopnd = nullptr; + RegOperand *result[kFourRegister]; /* up to 2 int or 4 fp */ + uint32 loadSize; + uint32 numRegs; + RegType regType; + PrimType retPty; + bool fpParm = false; + if (pLoc.numFpPureRegs) { + loadSize = pLoc.fpSize; + numRegs = pLoc.numFpPureRegs; + fpParm = true; + regType = kRegTyFloat; + retPty = (pLoc.fpSize == k4ByteSize) ? PTY_f32 : PTY_f64; + } else { + if (CGOptions::IsBigEndian()) { + loadSize = k8ByteSize; + numRegs = (typeSize <= k8ByteSize) ? kOneRegister : kTwoRegister; + regType = kRegTyInt; + retPty = PTY_u64; + } else { + loadSize = (typeSize <= k4ByteSize) ? k4ByteSize : k8ByteSize; + numRegs = (typeSize <= k8ByteSize) ? kOneRegister : kTwoRegister; + regType = kRegTyInt; + retPty = PTY_u32; + } + } + bool parmCopy = IsParamStructCopy(*sym); + for (uint32 i = 0; i < numRegs; i++) { + if (parmCopy) { + rhsmemopnd = &LoadStructCopyBase(*sym, + (offset + static_cast(i * (fpParm ? loadSize : k8ByteSize))), + static_cast(loadSize * kBitsPerByte)); + } else { + rhsmemopnd = &GetOrCreateMemOpnd(*sym, + (offset + static_cast(i * (fpParm ? loadSize : k8ByteSize))), + (loadSize * kBitsPerByte)); + } + result[i] = &CreateVirtualRegisterOperand(NewVReg(regType, loadSize)); + MOperator mop1 = PickLdInsn(loadSize * kBitsPerByte, retPty); + Insn &ld = GetCG()->BuildInstruction(mop1, *(result[i]), *rhsmemopnd); + GetCurBB()->AppendInsn(ld); + } + AArch64reg regs[kFourRegister]; + regs[0] = static_cast(pLoc.reg0); + regs[1] = static_cast(pLoc.reg1); + regs[2] = static_cast(pLoc.reg2); + regs[3] = static_cast(pLoc.reg3); + RegOperand *dest; + for (uint32 i = 0; i < numRegs; i++) { + AArch64reg preg; + MOperator mop2; + if (fpParm) { + preg = regs[i]; + mop2 = (loadSize == k4ByteSize) ? MOP_xvmovs : MOP_xvmovd; + } else { + preg = (i == 0 ? R0 : R1); + mop2 = (loadSize == k4ByteSize) ? MOP_wmovrr : MOP_xmovrr; + } + dest = &GetOrCreatePhysicalRegisterOperand(preg, (loadSize * kBitsPerByte), regType); + Insn &mov = GetCG()->BuildInstruction(mop2, *dest, *(result[i])); + GetCurBB()->AppendInsn(mov); + } + /* Create artificial dependency to extend the live range */ + for (uint32 i = 0; i < numRegs; i++) { + AArch64reg preg; + MOperator mop3; + if (fpParm) { + preg = regs[i]; + mop3 = MOP_pseudo_ret_float; + } else { + preg = (i == 0 ? R0 : R1); + mop3 = MOP_pseudo_ret_int; + } + dest = &GetOrCreatePhysicalRegisterOperand(preg, loadSize * kBitsPerByte, regType); + Insn &pseudo = GetCG()->BuildInstruction(mop3, *dest); + GetCurBB()->AppendInsn(pseudo); + } + return; + } else if (x->GetOpCode() == OP_iread) { + IreadNode *iread = static_cast(x); + RegOperand *rhsAddrOpnd = static_cast(HandleExpr(*iread, *iread->Opnd(0))); + rhsAddrOpnd = &LoadIntoRegister(*rhsAddrOpnd, iread->Opnd(0)->GetPrimType()); + MIRPtrType *ptrType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread->GetTyIdx())); + MIRType *mirType = static_cast(ptrType->GetPointedType()); + bool isRefField = false; + if (iread->GetFieldID() != 0) { + MIRStructType *structType = static_cast(mirType); + mirType = structType->GetFieldType(iread->GetFieldID()); + offset = static_cast(GetBecommon().GetFieldOffset(*structType, iread->GetFieldID()).first); + isRefField = GetBecommon().IsRefField(*structType, iread->GetFieldID()); + } + uint32 typeSize = GetBecommon().GetTypeSize(mirType->GetTypeIndex()); + /* generate move to regs. */ + RegOperand *result[kTwoRegister]; /* maximum 16 bytes, 2 registers */ + uint32 loadSize; + if (CGOptions::IsBigEndian()) { + loadSize = k8ByteSize; + } else { + loadSize = (typeSize <= k4ByteSize) ? k4ByteSize : k8ByteSize; + } + uint32 numRegs = (typeSize <= k8ByteSize) ? kOneRegister : kTwoRegister; + for (uint32 i = 0; i < numRegs; i++) { + OfstOperand *rhsOffOpnd = &GetOrCreateOfstOpnd(offset + i * loadSize, loadSize * kBitsPerByte); + Operand &rhsmemopnd = GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, loadSize * kBitsPerByte, + rhsAddrOpnd, nullptr, rhsOffOpnd, nullptr); + result[i] = &CreateVirtualRegisterOperand(NewVReg(kRegTyInt, loadSize)); + MOperator mop1 = PickLdInsn(loadSize * kBitsPerByte, PTY_u32); + Insn &ld = GetCG()->BuildInstruction(mop1, *(result[i]), rhsmemopnd); + ld.MarkAsAccessRefField(isRefField); + GetCurBB()->AppendInsn(ld); + } + RegOperand *dest; + for (uint32 i = 0; i < numRegs; i++) { + AArch64reg preg = (i == 0 ? R0 : R1); + dest = &GetOrCreatePhysicalRegisterOperand(preg, loadSize * kBitsPerByte, kRegTyInt); + Insn &mov = GetCG()->BuildInstruction(MOP_xmovrr, *dest, *(result[i])); + GetCurBB()->AppendInsn(mov); + } + /* Create artificial dependency to extend the live range */ + for (uint32 i = 0; i < numRegs; i++) { + AArch64reg preg = (i == 0 ? R0 : R1); + dest = &GetOrCreatePhysicalRegisterOperand(preg, loadSize * kBitsPerByte, kRegTyInt); + Insn &pseudo = cg->BuildInstruction(MOP_pseudo_ret_int, *dest); + GetCurBB()->AppendInsn(pseudo); + } + return; + } else { // dummy return of 0 inserted by front-end at absence of return + ASSERT(x->GetOpCode() == OP_constval, "SelectReturnSendOfStructInRegs: unexpected return operand"); + uint32 typeSize = GetPrimTypeSize(x->GetPrimType()); + RegOperand &dest = GetOrCreatePhysicalRegisterOperand(R0, typeSize * kBitsPerByte, kRegTyInt); + ImmOperand &src = CreateImmOperand(0, k16BitSize, false); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_xmovri32, dest, src)); + return; + } +} + Operand *AArch64CGFunc::SelectDread(const BaseNode &parent, DreadNode &expr) { MIRSymbol *symbol = GetFunction().GetLocalOrGlobalSymbol(expr.GetStIdx()); if (symbol->IsEhIndex()) { @@ -2916,31 +3175,50 @@ Operand *AArch64CGFunc::SelectIreadoff(const BaseNode &parent, IreadoffNode &ire return result; } -RegOperand *AArch64CGFunc::GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType) { - MemOperand *memOpnd; - RegOperand *rfp = &GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); - uint32 bitlen = byteSize * kBitsPerByte; - if (offset < 0) { - RegOperand *baseOpnd = &CreateRegisterOperandOfType(PTY_a64); - ImmOperand &immOpnd = CreateImmOperand(offset, k32BitSize, true); - Insn &addInsn = GetCG()->BuildInstruction(MOP_xaddrri12, *baseOpnd, *rfp, immOpnd); - GetCurBB()->AppendInsn(addInsn); - OfstOperand *offsetOpnd = &CreateOfstOpnd(0, k32BitSize); - memOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, bitlen, baseOpnd, - nullptr, offsetOpnd, nullptr); - } else { - OfstOperand *offsetOpnd = &CreateOfstOpnd(static_cast(static_cast(offset)), k32BitSize); - memOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, bitlen, rfp, - nullptr, offsetOpnd, nullptr); - } - memOpnd->SetStackMem(true); +RegOperand *AArch64CGFunc::GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType, + AArch64reg baseRegno) { + MemOperand *memOpnd = GenLmbcFpMemOperand(offset, byteSize, baseRegno); RegOperand *result = &GetOrCreateVirtualRegisterOperand(NewVReg(regType, byteSize)); - MOperator mOp = PickLdInsn(bitlen, primType); + MOperator mOp = PickLdInsn(byteSize * kBitsPerByte, primType); Insn &load = GetCG()->BuildInstruction(mOp, *result, *memOpnd); GetCurBB()->AppendInsn(load); return result; } +RegOperand *AArch64CGFunc::LmbcStructReturnLoad(int32 offset) { + RegOperand *result = nullptr; + MIRFunction &func = GetFunction(); + CHECK_FATAL(func.IsReturnStruct(), "LmbcStructReturnLoad: not struct return"); + MIRType *ty = func.GetReturnType(); + uint32 sz = GetBecommon().GetTypeSize(ty->GetTypeIndex()); + uint32 fpSize; + uint32 numFpRegs = FloatParamRegRequired(static_cast(ty), fpSize); + if (numFpRegs > 0) { + PrimType pType = (fpSize <= k4ByteSize) ? PTY_f32 : PTY_f64; + for (int32 i = (numFpRegs - kOneRegister); i > 0; --i) { + result = GenLmbcParamLoad(offset + (i * fpSize), fpSize, kRegTyFloat, pType); + AArch64reg regNo = static_cast(V0 + i); + RegOperand *reg = &GetOrCreatePhysicalRegisterOperand(regNo, fpSize * kBitsPerByte, kRegTyFloat); + SelectCopy(*reg, pType, *result, pType); + Insn &pseudo = GetCG()->BuildInstruction(MOP_pseudo_ret_float, *reg); + GetCurBB()->AppendInsn(pseudo); + } + result = GenLmbcParamLoad(offset, fpSize, kRegTyFloat, pType); + } else if (sz <= k4ByteSize) { + result = GenLmbcParamLoad(offset, k4ByteSize, kRegTyInt, PTY_u32); + } else if (sz <= k8ByteSize) { + result = GenLmbcParamLoad(offset, k8ByteSize, kRegTyInt, PTY_i64); + } else if (sz <= k16ByteSize) { + result = GenLmbcParamLoad(offset + k8ByteSize, k8ByteSize, kRegTyInt, PTY_i64); + RegOperand *r1 = &GetOrCreatePhysicalRegisterOperand(R1, k8ByteSize * kBitsPerByte, kRegTyInt); + SelectCopy(*r1, PTY_i64, *result, PTY_i64); + Insn &pseudo = GetCG()->BuildInstruction(MOP_pseudo_ret_int, *r1); + GetCurBB()->AppendInsn(pseudo); + result = GenLmbcParamLoad(offset, k8ByteSize, kRegTyInt, PTY_i64); + } + return result; +} + Operand *AArch64CGFunc::SelectIreadfpoff(const BaseNode &parent, IreadFPoffNode &ireadoff) { int32 offset = ireadoff.GetOffset(); PrimType primType = ireadoff.GetPrimType(); @@ -2951,19 +3229,32 @@ Operand *AArch64CGFunc::SelectIreadfpoff(const BaseNode &parent, IreadFPoffNode if (offset >= 0) { LmbcFormalParamInfo *info = GetLmbcFormalParamInfo(static_cast(offset)); if (info->GetPrimType() == PTY_agg) { - result = GenLmbcParamLoad(offset, bytelen, regty, primType); + if (info->IsOnStack()) { + result = GenLmbcParamLoad(info->GetOnStackOffset(), GetPrimTypeSize(PTY_a64), kRegTyInt, PTY_a64); + regno_t baseRegno = result->GetRegisterNumber(); + result = GenLmbcParamLoad(offset - info->GetOffset(), bytelen, regty, primType, (AArch64reg)baseRegno); + } else if (primType == PTY_agg) { + CHECK_FATAL(parent.GetOpCode() == OP_regassign, "SelectIreadfpoff of agg"); + result = LmbcStructReturnLoad(offset); + } else { + result = GenLmbcParamLoad(offset, bytelen, regty, primType); + } } else { CHECK_FATAL(primType == info->GetPrimType(), "Incorrect primtype"); CHECK_FATAL(offset == info->GetOffset(), "Incorrect offset"); - if (info->GetRegNO() == 0) { - /* TODO : follow lmbc sp offset for now */ + if (info->GetRegNO() == 0 || info->HasRegassign() == false) { result = GenLmbcParamLoad(offset, bytelen, regty, primType); } else { result = &GetOrCreatePhysicalRegisterOperand((AArch64reg)(info->GetRegNO()), bitlen, regty); } } } else { - result = GenLmbcParamLoad(offset, bytelen, regty, primType); + if (primType == PTY_agg) { + CHECK_FATAL(parent.GetOpCode() == OP_regassign, "SelectIreadfpoff of agg"); + result = LmbcStructReturnLoad(offset); + } else { + result = GenLmbcParamLoad(offset, bytelen, regty, primType); + } } return result; } @@ -5759,6 +6050,9 @@ Operand *AArch64CGFunc::SelectAlloca(UnaryNode &node, Operand &opnd0) { if (!CGOptions::IsArm64ilp32()) { ASSERT((node.GetPrimType() == PTY_a64), "wrong type"); } + if (GetCG()->IsLmbc()) { + SetHasVLAOrAlloca(true); + } PrimType stype = node.Opnd(0)->GetPrimType(); Operand *resOpnd = &opnd0; if (GetPrimTypeBitSize(stype) < GetPrimTypeBitSize(PTY_u64)) { @@ -5774,10 +6068,13 @@ Operand *AArch64CGFunc::SelectAlloca(UnaryNode &node, Operand &opnd0) { SelectShift(aliOp, aliOp, shifOpnd, kShiftLeft, PTY_u64); Operand &spOpnd = GetOrCreatePhysicalRegisterOperand(RSP, k64BitSize, kRegTyInt); SelectSub(spOpnd, spOpnd, aliOp, PTY_u64); - int64 argsToStkpassSize = GetMemlayout()->SizeOfArgsToStackPass(); - if (argsToStkpassSize > 0) { + int64 allocaOffset = GetMemlayout()->SizeOfArgsToStackPass(); + if (GetCG()->IsLmbc()) { + allocaOffset -= kDivide2 * k8ByteSize; + } + if (allocaOffset > 0) { RegOperand &resallo = CreateRegisterOperandOfType(PTY_u64); - SelectAdd(resallo, spOpnd, CreateImmOperand(argsToStkpassSize, k64BitSize, true), PTY_u64); + SelectAdd(resallo, spOpnd, CreateImmOperand(allocaOffset, k64BitSize, true), PTY_u64); return &resallo; } else { return &SelectCopy(spOpnd, PTY_u64, PTY_u64); @@ -6219,6 +6516,15 @@ void AArch64CGFunc::AssignLmbcFormalParams() { param->SetRegNO(0); } else { param->SetRegNO(intReg); + if (param->HasRegassign() == false) { + uint32 bytelen = GetPrimTypeSize(primType); + uint32 bitlen = bytelen * kBitsPerByte; + MemOperand *mOpnd = GenLmbcFpMemOperand(offset, bytelen); + RegOperand &src = GetOrCreatePhysicalRegisterOperand(AArch64reg(intReg), bitlen, kRegTyInt); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, src, *mOpnd); + GetCurBB()->AppendInsn(store); + } intReg++; } } else if (IsPrimitiveFloat(primType)) { @@ -6226,6 +6532,15 @@ void AArch64CGFunc::AssignLmbcFormalParams() { param->SetRegNO(0); } else { param->SetRegNO(fpReg); + if (param->HasRegassign() == false) { + uint32 bytelen = GetPrimTypeSize(primType); + uint32 bitlen = bytelen * kBitsPerByte; + MemOperand *mOpnd = GenLmbcFpMemOperand(offset, bytelen); + RegOperand &src = GetOrCreatePhysicalRegisterOperand(AArch64reg(fpReg), bitlen, kRegTyFloat); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, src, *mOpnd); + GetCurBB()->AppendInsn(store); + } fpReg++; } } else if (primType == PTY_agg) { @@ -6244,6 +6559,14 @@ void AArch64CGFunc::AssignLmbcFormalParams() { } else { param->SetRegNO(intReg); param->SetIsOnStack(); + param->SetOnStackOffset((intReg - R0 + fpReg - V0) * k8ByteSize); + uint32 bytelen = GetPrimTypeSize(PTY_a64); + uint32 bitlen = bytelen * kBitsPerByte; + MemOperand *mOpnd = GenLmbcFpMemOperand(param->GetOnStackOffset(), bytelen); + RegOperand &src = GetOrCreatePhysicalRegisterOperand(AArch64reg(intReg), bitlen, kRegTyInt); + MOperator mOp = PickStInsn(bitlen, PTY_a64); + Insn &store = GetCG()->BuildInstruction(mOp, src, *mOpnd); + GetCurBB()->AppendInsn(store); intReg++; } } else if (param->GetSize() <= k8ByteSize) { @@ -6289,7 +6612,6 @@ void AArch64CGFunc::AssignLmbcFormalParams() { Operand *memOpd = &CreateMemOpnd(RFP, offset + (i * rSize), rSize); GetCurBB()->AppendInsn(GetCG()->BuildInstruction( PickStInsn(rSize * kBitsPerByte, pType), dest, *memOpd)); - param->SetIsOnStack(); } } } else { @@ -6298,6 +6620,22 @@ void AArch64CGFunc::AssignLmbcFormalParams() { } } +void AArch64CGFunc::LmbcGenSaveSpForAlloca() { + if (GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc || HasVLAOrAlloca() == false) { + return; + } + Operand &spOpnd = GetOrCreatePhysicalRegisterOperand(RSP, k64BitSize, kRegTyInt); + RegOperand &spSaveOpnd = CreateVirtualRegisterOperand(NewVReg(kRegTyInt, kSizeOfPtr)); + Insn &save = GetCG()->BuildInstruction(MOP_xmovrr, spSaveOpnd, spOpnd); + GetFirstBB()->AppendInsn(save); + //save.SetFrameDef(true); + for (auto *retBB : GetExitBBsVec()) { + Insn &restore = GetCG()->BuildInstruction(MOP_xmovrr, spOpnd, spSaveOpnd); + retBB->AppendInsn(restore); + restore.SetFrameDef(true); + } +} + /* if offset < 0, allocation; otherwise, deallocation */ MemOperand &AArch64CGFunc::CreateCallFrameOperand(int32 offset, uint32 size) { MemOperand *memOpnd = CreateStackMemOpnd(RSP, offset, size); @@ -7583,6 +7921,10 @@ size_t AArch64CGFunc::SelectParmListGetStructReturnSize(StmtNode &naryNode) { CallNode &callNode = static_cast(naryNode); MIRFunction *callFunc = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callNode.GetPUIdx()); TyIdx retIdx = callFunc->GetReturnTyIdx(); + if (callFunc->IsFirstArgReturn()) { + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(callFunc->GetFormalDefVec()[0].formalTyIdx); + return GetBecommon().GetTypeSize(static_cast(ty)->GetPointedTyIdx()); + } size_t retSize = GetBecommon().GetTypeSize(retIdx.GetIdx()); if ((retSize == 0) && callFunc->IsReturnStruct()) { TyIdx tyIdx = callFunc->GetFuncRetStructTyIdx(); @@ -7599,6 +7941,14 @@ size_t AArch64CGFunc::SelectParmListGetStructReturnSize(StmtNode &naryNode) { return GetBecommon().GetTypeSize(sym->GetTyIdx().GetIdx()); } } + } else if (naryNode.GetOpCode() == OP_icallproto) { + IcallNode &icallProto = static_cast(naryNode); + MIRFuncType *funcTy = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallProto.GetRetTyIdx())); + if (funcTy->FirstArgReturn()) { + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcTy->GetNthParamType(0)); + return GetBecommon().GetTypeSize(static_cast(ty)->GetPointedTyIdx()); + } + return GetBecommon().GetTypeSize(funcTy->GetRetTyIdx()); } return 0; } @@ -7706,7 +8056,7 @@ void AArch64CGFunc::SelectParmListPreprocess(const StmtNode &naryNode, size_t st */ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bool isCallNative) { size_t i = 0; - if ((naryNode.GetOpCode() == OP_icall) || isCallNative) { + if (naryNode.GetOpCode() == OP_icall || naryNode.GetOpCode() == OP_icallproto || isCallNative) { i++; } std::set specialArgs; @@ -7733,8 +8083,11 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - auto *callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + MIRFunction *callee = nullptr; + if (dynamic_cast(&naryNode) != nullptr) { + auto calleePuIdx = static_cast(naryNode).GetPUIdx(); + callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } @@ -8256,7 +8609,18 @@ void AArch64CGFunc::SelectCall(CallNode &callNode) { ListOperand *srcOpnds = CreateListOpnd(*GetFuncScopeAllocator()); if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { - LmbcSelectParmList(srcOpnds, fn->IsFirstArgReturn()); + SetLmbcCallReturnType(nullptr); + bool largeStructRet = false; + if (fn->IsFirstArgReturn()) { + MIRPtrType *ptrTy = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(fn->GetFormalDefVec()[0].formalTyIdx)); + MIRType *sTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ptrTy->GetPointedTyIdx()); + largeStructRet = sTy->GetSize() > k16ByteSize; + SetLmbcCallReturnType(sTy); + } else { + MIRType *ty = fn->GetReturnType(); + SetLmbcCallReturnType(ty); + } + LmbcSelectParmList(srcOpnds, largeStructRet); } bool callNative = false; if ((fsym->GetName() == "MCC_CallFastNative") || (fsym->GetName() == "MCC_CallFastNativeExt") || @@ -8332,11 +8696,21 @@ void AArch64CGFunc::SelectCall(CallNode &callNode) { void AArch64CGFunc::SelectIcall(IcallNode &icallNode, Operand &srcOpnd) { ListOperand *srcOpnds = CreateListOpnd(*GetFuncScopeAllocator()); - if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { - LmbcSelectParmList(srcOpnds, false); /*fType->GetRetAttrs().GetAttr(ATTR_firstarg_return)*/ - } else { +// if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { +// /* icallproto */ +// MIRType *retTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallNode.GetRetTyIdx()); +// MIRFuncType *funcTy = static_cast(retTy); +// bool largeStructRet = false; +// if (funcTy->FirstArgReturn()) { +// TyIdx idx = funcTy->GetNthParamType(0); +// MIRPtrType *ptrTy = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(idx)); +// MIRType *sTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ptrTy->GetPointedTyIdx()); +// largeStructRet = sTy->GetSize() > k16ByteSize; +// } +// LmbcSelectParmList(srcOpnds, largeStructRet); +// } else { SelectParmList(icallNode, *srcOpnds); - } +// } Operand *fptrOpnd = &srcOpnd; if (fptrOpnd->GetKind() != Operand::kOpdRegister) { @@ -8347,7 +8721,7 @@ void AArch64CGFunc::SelectIcall(IcallNode &icallNode, Operand &srcOpnd) { RegOperand *regOpnd = static_cast(fptrOpnd); Insn &callInsn = GetCG()->BuildInstruction(MOP_xblr, *regOpnd, *srcOpnds); - MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallNode.GetRetTyIdx()); + MIRType *retType = icallNode.GetCallReturnType(); if (retType != nullptr) { callInsn.SetRetSize(static_cast(retType->GetSize())); callInsn.SetIsCallReturnUnsigned(IsUnsignedInteger(retType->GetPrimType())); @@ -8460,9 +8834,18 @@ RegOperand &AArch64CGFunc::GetOrCreateSpecialRegisterOperand(PregIdx sregIdx, Pr case kSregFp: reg = RFP; break; - case kSregGp: - reg = RFP; - break; + case kSregGp: { + MIRSymbol *sym = GetCG()->GetGP(); + if (sym == nullptr) { + sym = GetFunction().GetSymTab()->CreateSymbol(kScopeLocal); + std::string strBuf("__file__local__GP"); + sym->SetNameStrIdx(GetMirModule().GetMIRBuilder()->GetOrCreateStringIndex(strBuf)); + GetCG()->SetGP(sym); + } + RegOperand &result = GetOrCreateVirtualRegisterOperand(NewVReg(kRegTyInt, k8ByteSize)); + SelectAddrof(result, CreateStImmOperand(*sym, 0, 0)); + return result; + } case kSregThrownval: { /* uses x0 == R0 */ ASSERT(uCatch.regNOCatch > 0, "regNOCatch should greater than 0."); if (Globals::GetInstance()->GetOptimLevel() == 0) { @@ -9199,6 +9582,9 @@ int32 AArch64CGFunc::GetBaseOffset(const SymbolAlloc &sa) { int32 baseOffset = symAlloc->GetOffset(); return baseOffset + sizeofFplr; } else if (sgKind == kMsSpillReg) { + if (GetCG()->IsLmbc()) { + return symAlloc->GetOffset() + memLayout->SizeOfArgsToStackPass(); + } int32 baseOffset = symAlloc->GetOffset() + memLayout->SizeOfArgsRegisterPassed() + memLayout->GetSizeOfLocals() + memLayout->GetSizeOfRefLocals(); return baseOffset + sizeofFplr; @@ -9773,16 +10159,21 @@ void AArch64CGFunc::GenCVaStartIntrin(RegOperand &opnd, uint32 stkSize) { Operand &stkOpnd = GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); /* __stack */ - ImmOperand *offsOpnd = &CreateImmOperand(0, k64BitSize, true, kUnAdjustVary); /* isvary reset StackFrameSize */ + ImmOperand *offsOpnd; + if (GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + offsOpnd = &CreateImmOperand(0, k64BitSize, true, kUnAdjustVary); /* isvary reset StackFrameSize */ + } else { + offsOpnd = &CreateImmOperand(0, k64BitSize, true); + } ImmOperand *offsOpnd2 = &CreateImmOperand(stkSize, k64BitSize, false); RegOperand &vReg = CreateVirtualRegisterOperand(NewVReg(kRegTyInt, GetPrimTypeSize(LOWERED_PTR_TYPE))); if (stkSize) { SelectAdd(vReg, *offsOpnd, *offsOpnd2, LOWERED_PTR_TYPE); SelectAdd(vReg, stkOpnd, vReg, LOWERED_PTR_TYPE); } else { - SelectAdd(vReg, stkOpnd, *offsOpnd, LOWERED_PTR_TYPE); + SelectAdd(vReg, stkOpnd, *offsOpnd, LOWERED_PTR_TYPE); /* stack pointer */ } - OfstOperand *offOpnd = &GetOrCreateOfstOpnd(0, k64BitSize); + OfstOperand *offOpnd = &GetOrCreateOfstOpnd(0, k64BitSize); /* va_list ptr */ /* mem operand in va_list struct (lhs) */ MemOperand *strOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, k64BitSize, &opnd, nullptr, offOpnd, static_cast(nullptr)); @@ -9857,13 +10248,19 @@ void AArch64CGFunc::SelectCVaStart(const IntrinsiccallNode &intrnNode) { AArch64CallConvImpl parmLocator(GetBecommon()); CCLocInfo pLoc; uint32 stkSize = 0; + uint32 inReg = 0; for (uint32 i = 0; i < GetFunction().GetFormalCount(); i++) { MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(GetFunction().GetNthParamTyIdx(i)); parmLocator.LocateNextParm(*ty, pLoc); if (pLoc.reg0 == kRinvalid) { /* on stack */ stkSize = static_cast(pLoc.memOffset + pLoc.memSize); + } else { + inReg++; } } + if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + stkSize += (inReg * k8ByteSize); + } if (CGOptions::IsArm64ilp32()) { stkSize = static_cast(RoundUp(stkSize, k8ByteSize)); } else { diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp index 37d650a738..fa2de4d440 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp @@ -40,8 +40,8 @@ constexpr uint8 insPairsNum = 5; PairMOperator extInsnPairTable[ExtTableSize][insPairsNum] = { /* {origMop, newMop} */ - {{MOP_wldrb, MOP_wldrb}, {MOP_undef, MOP_undef}, {MOP_undef, MOP_undef}, {MOP_undef, MOP_undef}, - {MOP_undef, MOP_undef}}, /* AND */ + {{MOP_wldrb, MOP_wldrb}, {MOP_wldrsh, MOP_wldrb}, {MOP_wldrh, MOP_wldrb}, {MOP_xldrsw, MOP_wldrb}, + {MOP_wldr, MOP_wldrb}}, /* AND */ {{MOP_wldrb, MOP_wldrsb}, {MOP_wldr, MOP_wldrsb}, {MOP_undef, MOP_undef}, {MOP_undef, MOP_undef}, {MOP_undef, MOP_undef}}, /* SXTB */ {{MOP_wldrh, MOP_wldrsh}, {MOP_wldrb, MOP_wldrb}, {MOP_wldrsb, MOP_wldrsb}, {MOP_wldrsh, MOP_wldrsh}, diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp index a58213245c..4184108a22 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp @@ -134,7 +134,7 @@ void AArch64MemLayout::LayoutVarargParams() { if (be.GetMIRModule().IsCModule() && func->GetAttr(FUNCATTR_varargs)) { for (uint32 i = 0; i < func->GetFormalCount(); i++) { if (i == 0) { - if (func->IsReturnStruct()) { + if (func->IsFirstArgReturn() && func->GetReturnType()->GetPrimType() != PTY_void) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (be.GetTypeSize(tyIdx.GetIdx()) <= k16ByteSize) { continue; @@ -198,7 +198,7 @@ void AArch64MemLayout::LayoutFormalParams() { * outparmsize - portion of frame size of current function used by call parameters */ segArgsStkPassed.SetSize(mirFunction->GetOutParmSize()); - segArgsRegPassed.SetSize(mirFunction->GetOutParmSize() + kTwoRegister * k8ByteSize); + segArgsRegPassed.SetSize(mirFunction->GetOutParmSize()); return; } @@ -210,7 +210,7 @@ void AArch64MemLayout::LayoutFormalParams() { AArch64SymbolAlloc *symLoc = memAllocator->GetMemPool()->New(); SetSymAllocInfo(stIndex, *symLoc); if (i == 0) { - if (mirFunction->IsReturnStruct()) { + if (mirFunction->IsFirstArgReturn()) { symLoc->SetMemSegment(GetSegArgsRegPassed()); symLoc->SetOffset(GetSegArgsRegPassed().GetSize()); TyIdx tyIdx = mirFunction->GetFuncRetStructTyIdx(); @@ -224,13 +224,13 @@ void AArch64MemLayout::LayoutFormalParams() { continue; } } - MIRType *ty = mirFunction->GetNthParamType(i); + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(mirFunction->GetFormalDefVec()[i].formalTyIdx); uint32 ptyIdx = ty->GetTypeIndex(); parmLocator.LocateNextParm(*ty, ploc, i == 0, mirFunction); if (ploc.reg0 != kRinvalid) { /* register */ symLoc->SetRegisters(static_cast(ploc.reg0), static_cast(ploc.reg1), static_cast(ploc.reg2), static_cast(ploc.reg3)); - if (mirFunction->GetNthParamAttr(i).GetAttr(ATTR_localrefvar)) { + if (mirFunction->GetFormalDefVec()[i].formalAttrs.GetAttr(ATTR_localrefvar)) { symLoc->SetMemSegment(segRefLocals); SetSegmentSize(*symLoc, segRefLocals, ptyIdx); } else if (!sym->IsPreg()) { @@ -272,7 +272,7 @@ void AArch64MemLayout::LayoutFormalParams() { } else { segArgsStkPassed.SetSize(static_cast(RoundUp(segArgsStkPassed.GetSize(), kSizeOfPtr))); } - if (mirFunction->GetNthParamAttr(i).GetAttr(ATTR_localrefvar)) { + if (mirFunction->GetFormalDefVec()[i].formalAttrs.GetAttr(ATTR_localrefvar)) { SetLocalRegLocInfo(sym->GetStIdx(), *symLoc); AArch64SymbolAlloc *symLoc1 = memAllocator->GetMemPool()->New(); symLoc1->SetMemSegment(segRefLocals); @@ -287,8 +287,8 @@ void AArch64MemLayout::LayoutFormalParams() { } void AArch64MemLayout::LayoutLocalVariables(std::vector &tempVar, std::vector &returnDelays) { - if (be.GetMIRModule().GetFlavor() == kFlavorLmbc && mirFunction->GetFormalCount() == 0) { - segLocals.SetSize(static_cast(mirFunction->GetFrameSize() - mirFunction->GetOutParmSize())); + if (be.GetMIRModule().GetFlavor() == kFlavorLmbc) { + segLocals.SetSize(mirFunction->GetFrameSize() - mirFunction->GetOutParmSize()); return; } @@ -372,7 +372,7 @@ void AArch64MemLayout::LayoutReturnRef(std::vector &returnDelays, segRefLocals.SetSize(segRefLocals.GetSize() + be.GetTypeSize(tyIdx)); } if (be.GetMIRModule().GetFlavor() == kFlavorLmbc) { - segArgsToStkPass.SetSize(mirFunction->GetOutParmSize()); + segArgsToStkPass.SetSize(mirFunction->GetOutParmSize() + kDivide2 * k8ByteSize); } else { segArgsToStkPass.SetSize(FindLargestActualArea(structCopySize)); } @@ -423,7 +423,7 @@ void AArch64MemLayout::LayoutActualParams() { * variables get assigned their respecitve storage, i.e. * CallFrameSize (discounting callee-saved and FP/LR) is known. */ - MIRType *ty = mirFunction->GetNthParamType(i); + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(mirFunction->GetFormalDefVec()[i].formalTyIdx); uint32 ptyIdx = ty->GetTypeIndex(); static_cast(cgFunc)->GetOrCreateMemOpnd(*sym, 0, be.GetTypeAlign(ptyIdx) * kBitsPerByte); } @@ -440,7 +440,7 @@ void AArch64MemLayout::LayoutStackFrame(int32 &structCopySize, int32 &maxParmSta */ if (CGOptions::IsArm64ilp32()) { segArgsRegPassed.SetSize(RoundUp(segArgsRegPassed.GetSize(), k8ByteSize)); - /* we do need this as SP has to be aligned at a 16-bytes bounardy */ + /* we do need this as SP has to be aligned at a 16-bytes bounardy */ segArgsStkPassed.SetSize(RoundUp(segArgsStkPassed.GetSize(), k8ByteSize + k8ByteSize)); } else { segArgsRegPassed.SetSize(RoundUp(segArgsRegPassed.GetSize(), kSizeOfPtr)); @@ -527,11 +527,13 @@ uint64 AArch64MemLayout::StackFrameSize() const { uint64 total = segArgsRegPassed.GetSize() + static_cast(cgFunc)->SizeOfCalleeSaved() + GetSizeOfRefLocals() + locals().GetSize() + GetSizeOfSpillReg(); - if (GetSizeOfGRSaveArea() > 0) { - total += RoundUp(GetSizeOfGRSaveArea(), kAarch64StackPtrAlignment); - } - if (GetSizeOfVRSaveArea() > 0) { - total += RoundUp(GetSizeOfVRSaveArea(), kAarch64StackPtrAlignment); + if (cgFunc->GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + if (GetSizeOfGRSaveArea() > 0) { + total += RoundUp(GetSizeOfGRSaveArea(), kAarch64StackPtrAlignment); + } + if (GetSizeOfVRSaveArea() > 0) { + total += RoundUp(GetSizeOfVRSaveArea(), kAarch64StackPtrAlignment); + } } /* diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp index eaa5726d43..7ef7190645 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp @@ -50,7 +50,7 @@ void AArch64FPLROffsetAdjustment::AdjustmentOffsetForOpnd(Insn &insn, AArch64CGF if (memBaseReg->GetRegisterNumber() == RFP) { RegOperand &newBaseOpnd = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(stackBaseReg, k64BitSize, kRegTyInt); MemOperand &newMemOpnd = aarchCGFunc.GetOrCreateMemOpnd( - MemOperand::kAddrModeBOi, memOpnd.GetSize(), &newBaseOpnd, memOpnd.GetIndexRegister(), + memOpnd.GetAddrMode(), memOpnd.GetSize(), &newBaseOpnd, memOpnd.GetIndexRegister(), memOpnd.GetOffsetImmediate(), memOpnd.GetSymbol()); insn.SetOperand(i, newMemOpnd); stackBaseOpnd = true; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp index 8ffd169126..30b0dcf206 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp @@ -1118,6 +1118,9 @@ void AArch64GenProEpilog::AppendInstructionAllocateCallFrameDebug(AArch64reg reg ipoint = cgFunc.GetCurBB()->GetLastInsn(); cfiOffset = stackFrameSize; (void)InsertCFIDefCfaOffset(cfiOffset, *ipoint); + if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + argsToStkPassSize -= (kDivide2 * k8ByteSize); + } ipoint = &CreateAndAppendInstructionForAllocateCallFrame(argsToStkPassSize, reg0, reg1, rty); CHECK_FATAL(ipoint != nullptr, "ipoint should not be nullptr at this point"); cfiOffset = GetOffsetFromCFA(); @@ -1251,9 +1254,16 @@ void AArch64GenProEpilog::GeneratePushRegs() { CHECK_FATAL(*it == RLR, "The second callee saved reg is expected to be RLR"); ++it; - auto offset = static_cast((static_cast(cgFunc.GetMemlayout())->RealStackFrameSize() - - (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */)) - - cgFunc.GetMemlayout()->SizeOfArgsToStackPass()); + AArch64MemLayout *memLayout = static_cast(cgFunc.GetMemlayout()); + int32 offset; + if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + offset = static_cast(memLayout->RealStackFrameSize() - + aarchCGFunc.SizeOfCalleeSaved() - memLayout->GetSizeOfLocals()); + } else { + offset = static_cast(memLayout->RealStackFrameSize() - + (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */) - + memLayout->SizeOfArgsToStackPass()); + } if (cgFunc.GetCG()->IsStackProtectorStrong() || cgFunc.GetCG()->IsStackProtectorAll()) { offset -= kAarch64StackPtrAlignment; @@ -1313,10 +1323,19 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { size = kSizeOfPtr; } uint32 dataSizeBits = size * kBitsPerByte; - uint32 offset = static_cast(memlayout->GetGRSaveAreaBaseLoc()); - if (memlayout->GetSizeOfGRSaveArea() % kAarch64StackPtrAlignment) { - offset += size; /* End of area should be aligned. Hole between VR and GR area */ + uint32 offset; + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + offset = static_cast(memlayout->GetGRSaveAreaBaseLoc()); /* SP reference */ + if (memlayout->GetSizeOfGRSaveArea() % kAarch64StackPtrAlignment) { + offset += size; /* End of area should be aligned. Hole between VR and GR area */ + } + } else { + offset = -memlayout->GetSizeOfGRSaveArea(); /* FP reference */ + if (memlayout->GetSizeOfGRSaveArea() % kAarch64StackPtrAlignment) { + offset -= size; + } } + uint32 grSize = -offset; uint32 start_regno = k8BitSize - (memlayout->GetSizeOfGRSaveArea() / size); ASSERT(start_regno <= k8BitSize, "Incorrect starting GR regno for GR Save Area"); for (uint32 i = start_regno + static_cast(R0); i < static_cast(R8); i++) { @@ -1326,16 +1345,25 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { tmpOffset += 8U - (dataSizeBits >> 3); } } - Operand &stackloc = aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); + Operand *stackLoc; + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + stackLoc = &aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); + } else { + stackLoc = aarchCGFunc.GenLmbcFpMemOperand(offset, size); + } RegOperand ® = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(static_cast(i), k64BitSize, kRegTyInt); Insn &inst = - currCG->BuildInstruction(aarchCGFunc.PickStInsn(dataSizeBits, PTY_i64), reg, stackloc); + currCG->BuildInstruction(aarchCGFunc.PickStInsn(dataSizeBits, PTY_i64), reg, *stackLoc); cgFunc.GetCurBB()->AppendInsn(inst); offset += size; } if (!CGOptions::UseGeneralRegOnly()) { - offset = static_cast(memlayout->GetVRSaveAreaBaseLoc()); + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + offset = static_cast(memlayout->GetVRSaveAreaBaseLoc()); + } else { + offset = -(memlayout->GetSizeOfVRSaveArea() + grSize); + } start_regno = k8BitSize - (memlayout->GetSizeOfVRSaveArea() / (size * k2BitSize)); ASSERT(start_regno <= k8BitSize, "Incorrect starting GR regno for VR Save Area"); for (uint32 i = start_regno + static_cast(V0); i < static_cast(V8); i++) { @@ -1345,11 +1373,16 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { tmpOffset += 16U - (dataSizeBits >> 3); } } - Operand &stackloc = aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); + Operand *stackLoc; + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + stackLoc = &aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); + } else { + stackLoc = aarchCGFunc.GenLmbcFpMemOperand(offset, size); + } RegOperand ® = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(static_cast(i), k64BitSize, kRegTyFloat); Insn &inst = - currCG->BuildInstruction(aarchCGFunc.PickStInsn(dataSizeBits, PTY_f64), reg, stackloc); + currCG->BuildInstruction(aarchCGFunc.PickStInsn(dataSizeBits, PTY_f64), reg, *stackLoc); cgFunc.GetCurBB()->AppendInsn(inst); offset += (size * k2BitSize); } @@ -1389,7 +1422,8 @@ void AArch64GenProEpilog::GenerateProlog(BB &bb) { } // insert .loc for function - if (currCG->GetCGOptions().WithLoc()) { + if (currCG->GetCGOptions().WithLoc() && + (!currCG->GetMIRModule()->IsCModule() || currCG->GetMIRModule()->IsWithDbgInfo())) { MIRFunction *func = &cgFunc.GetFunction(); MIRSymbol *fSym = GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx()); if (currCG->GetCGOptions().WithSrc()) { @@ -1649,11 +1683,17 @@ void AArch64GenProEpilog::AppendInstructionDeallocateCallFrameDebug(AArch64reg r * ldp/stp's imm should be within -512 and 504; * if ldp's imm > 504, we fall back to the ldp-add version */ - if (cgFunc.HasVLAOrAlloca() || argsToStkPassSize == 0) { - stackFrameSize -= argsToStkPassSize; - if (stackFrameSize > kStpLdpImm64UpperBound) { + bool isLmbc = (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc); + if (cgFunc.HasVLAOrAlloca() || argsToStkPassSize == 0 || isLmbc) { + int lmbcOffset = 0; + if (isLmbc == false) { + stackFrameSize -= argsToStkPassSize; + } else { + lmbcOffset = argsToStkPassSize - (kDivide2 * k8ByteSize); + } + if (stackFrameSize > kStpLdpImm64UpperBound || isLmbc) { Operand *o2; - o2 = aarchCGFunc.CreateStackMemOpnd(RSP, 0, kSizeOfPtr * kBitsPerByte); + o2 = aarchCGFunc.CreateStackMemOpnd(RSP, (isLmbc ? lmbcOffset : 0), kSizeOfPtr * kBitsPerByte); Insn &deallocInsn = currCG->BuildInstruction(mOp, o0, o1, *o2); cgFunc.GetCurBB()->AppendInsn(deallocInsn); if (cgFunc.GenCfi()) { @@ -1728,9 +1768,16 @@ void AArch64GenProEpilog::GeneratePopRegs() { CHECK_FATAL(*it == RLR, "The second callee saved reg is expected to be RLR"); ++it; - int32 offset = static_cast((static_cast(cgFunc.GetMemlayout())->RealStackFrameSize() - - (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */)) - - cgFunc.GetMemlayout()->SizeOfArgsToStackPass()); + AArch64MemLayout *memLayout = static_cast(cgFunc.GetMemlayout()); + int32 offset; + if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + offset = static_cast(memLayout->RealStackFrameSize() - + aarchCGFunc.SizeOfCalleeSaved() - memLayout->GetSizeOfLocals()); + } else { + offset = static_cast(cgFunc.GetMemlayout())->RealStackFrameSize() - + (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */) - + memLayout->SizeOfArgsToStackPass(); + } if (cgFunc.GetCG()->IsStackProtectorStrong() || cgFunc.GetCG()->IsStackProtectorAll()) { offset -= kAarch64StackPtrAlignment; @@ -1821,7 +1868,7 @@ void AArch64GenProEpilog::GenerateEpilog(BB &bb) { Operand &spOpnd = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(RSP, k64BitSize, kRegTyInt); Operand &fpOpnd = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(stackBaseReg, k64BitSize, kRegTyInt); - if (cgFunc.HasVLAOrAlloca()) { + if (cgFunc.HasVLAOrAlloca() && cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { aarchCGFunc.SelectCopy(spOpnd, PTY_u64, fpOpnd, PTY_u64); } diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp index 433cc85754..5ca154b1aa 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp @@ -161,8 +161,7 @@ void AArch64ReachingDefinition::AddRetPseudoInsn(BB &bb) { Insn &retInsn = cgFunc->GetCG()->BuildInstruction(MOP_pseudo_ret_int, regOpnd); bb.AppendInsn(retInsn); pseudoInsns.emplace_back(&retInsn); - } else { - ASSERT(regNO == V0, "CG internal error. Return value should be R0 or V0."); + } else if (regNO == V0) { RegOperand ®Opnd = static_cast(cgFunc)->GetOrCreatePhysicalRegisterOperand(regNO, k64BitSize, kRegTyFloat); Insn &retInsn = cgFunc->GetCG()->BuildInstruction(MOP_pseudo_ret_float, regOpnd); diff --git a/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp b/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp index d2ae2c25c9..bf645c15cd 100644 --- a/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp +++ b/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp @@ -160,6 +160,7 @@ void RecursiveMarkUsedStaticSymbol(const BaseNode *baseNode) { break; } case OP_addrof: + case OP_addrofoff: case OP_dread: { const AddrofNode *dreadNode = static_cast(baseNode); MarkUsedStaticSymbol(dreadNode->GetStIdx()); diff --git a/src/mapleall/maple_be/src/cg/cgfunc.cpp b/src/mapleall/maple_be/src/cg/cgfunc.cpp index 50ecb583a7..b520229206 100644 --- a/src/mapleall/maple_be/src/cg/cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/cgfunc.cpp @@ -1145,7 +1145,11 @@ void HandleReturn(StmtNode &stmt, CGFunc &cgFunc) { ASSERT(retNode.NumOpnds() <= 1, "NYI return nodes number > 1"); Operand *opnd = nullptr; if (retNode.NumOpnds() != 0) { - opnd = cgFunc.HandleExpr(retNode, *retNode.Opnd(0)); + if (!cgFunc.GetFunction().StructReturnedInRegs()) { + opnd = cgFunc.HandleExpr(retNode, *retNode.Opnd(0)); + } else { + cgFunc.SelectReturnSendOfStructInRegs(retNode.Opnd(0)); + } } cgFunc.SelectReturn(opnd); cgFunc.SetCurBBKind(BB::kBBReturn); @@ -1561,15 +1565,16 @@ void CGFunc::CreateLmbcFormalParamInfo() { PrimType primType; uint32 offset; uint32 typeSize; - MIRFunction &mirFunc = GetFunction(); - if (mirFunc.GetParamSize() > 0) { + MIRFunction &func = GetFunction(); + if (func.GetFormalCount() > 0) { + /* Whenever lmbc cannot delete call type info, the prototype is available */ uint32 stackOffset = 0; - for (size_t idx = 0; idx < mirFunc.GetParamSize(); ++idx) { - MIRSymbol *sym = mirFunc.GetFormal(idx); + for (size_t idx = 0; idx < func.GetFormalCount(); ++idx) { + MIRSymbol *sym = func.GetFormal(idx); MIRType *type; TyIdx tyIdx; if (sym) { - tyIdx = mirFunc.GetNthParamTyIdx(idx); + tyIdx = func.GetFormalDefVec()[idx].formalTyIdx; type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); } else { FormalDef vec = const_cast(GetBecommon().GetMIRModule().CurFunction())->GetFormalDefAt(idx); @@ -1616,6 +1621,9 @@ void CGFunc::CreateLmbcFormalParamInfo() { } IreadFPoffNode *ireadNode = static_cast(operand); primType = ireadNode->GetPrimType(); + if (ireadNode->GetOffset() < 0) { + continue; + } offset = static_cast(ireadNode->GetOffset()); typeSize = GetPrimTypeSize(primType); CHECK_FATAL((offset % k8ByteSize) == 0, ""); /* scalar only, no struct for now */ @@ -1627,6 +1635,31 @@ void CGFunc::CreateLmbcFormalParamInfo() { [] (LmbcFormalParamInfo *x, LmbcFormalParamInfo *y) { return x->GetOffset() < y->GetOffset(); } ); + + /* When a scalar param address is taken, its regassign is not in the 1st block */ + for (StmtNode *stmt = func.GetBody()->GetFirst(); stmt != nullptr; stmt = stmt->GetNext()) { + if (stmt == nullptr) { + break; + } + if (stmt->GetOpCode() == OP_label) { + continue; + } + if (stmt->GetOpCode() != OP_regassign) { + break; + } + RegassignNode *regAssignNode = static_cast(stmt); + BaseNode *operand = regAssignNode->Opnd(0); + if (operand->GetOpCode() != OP_ireadfpoff) { + break; + } + IreadFPoffNode *ireadNode = static_cast(operand); + if (ireadNode->GetOffset() < 0) { + continue; + } + LmbcFormalParamInfo *info = GetLmbcFormalParamInfo(ireadNode->GetOffset()); + info->SetHasRegassign(); + } + AssignLmbcFormalParams(); } @@ -1635,7 +1668,7 @@ void CGFunc::GenerateInstruction() { InitHandleStmtFactory(); StmtNode *secondStmt = HandleFirstStmt(); - CreateLmbcFormalParamInfo(); + //CreateLmbcFormalParamInfo(); /* First Pass: Creates the doubly-linked list of BBs (next,prev) */ volReleaseInsn = nullptr; unsigned lastSrcLoc = 0; @@ -2007,6 +2040,7 @@ void CGFunc::HandleFunction() { ASSERT(exitBBVec.size() <= 1, "there are more than one BB_return in func"); } ProcessExitBBVec(); + LmbcGenSaveSpForAlloca(); if (func.IsJava()) { GenerateCleanupCodeForExtEpilog(*cleanupBB); diff --git a/src/mapleall/maple_be/src/cg/emit.cpp b/src/mapleall/maple_be/src/cg/emit.cpp index cfe3ccfd7b..97bf901870 100644 --- a/src/mapleall/maple_be/src/cg/emit.cpp +++ b/src/mapleall/maple_be/src/cg/emit.cpp @@ -2170,6 +2170,11 @@ void Emitter::EmitGlobalVar(const MIRSymbol &globalVar) { } void Emitter::EmitGlobalVars(std::vector> &globalVars) { + if (GetCG()->IsLmbc() && GetCG()->GetGP() != nullptr) { + Emit(asmInfo->GetLocal()).Emit("\t").Emit(GetCG()->GetGP()->GetName()).Emit("\n"); + Emit(asmInfo->GetComm()).Emit("\t").Emit(GetCG()->GetGP()->GetName()); + Emit(", ").Emit(GetCG()->GetMIRModule()->GetGlobalMemSize()).Emit(", ").Emit("8\n"); + } /* load globalVars profile */ if (globalVars.empty()) { return; diff --git a/src/mapleall/maple_be/src/cg/memlayout.cpp b/src/mapleall/maple_be/src/cg/memlayout.cpp index 57e45e8a2d..1b636207c6 100644 --- a/src/mapleall/maple_be/src/cg/memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/memlayout.cpp @@ -38,7 +38,7 @@ uint32 MemLayout::FindLargestActualArea(int32 &aggCopySize) { uint32 maxCopyStackSize = 0; // Size of aggregate param stack copy requirement for (; stmt != nullptr; stmt = stmt->GetNext()) { Opcode opCode = stmt->GetOpCode(); - if (opCode < OP_call || opCode > OP_xintrinsiccallassigned) { + if ((opCode < OP_call || opCode > OP_xintrinsiccallassigned) && opCode != OP_icallproto) { continue; } if (opCode == OP_intrinsiccallwithtypeassigned || opCode == OP_intrinsiccallwithtype || @@ -54,9 +54,9 @@ uint32 MemLayout::FindLargestActualArea(int32 &aggCopySize) { * if the following check fails, most likely dex has invoke-custom etc * that is not supported yet */ - DCHECK((opCode == OP_call || opCode == OP_icall), "Not lowered to call or icall?"); + DCHECK((opCode == OP_call || opCode == OP_icall || opCode == OP_icallproto), "Not lowered to call or icall?"); int32 copySize; - uint32 size = ComputeStackSpaceRequirementForCall(*stmt, copySize, opCode == OP_icall); + uint32 size = ComputeStackSpaceRequirementForCall(*stmt, copySize, opCode == OP_icall || opCode == OP_icallproto); if (size > maxParamStackSize) { maxParamStackSize = size; } diff --git a/src/mapleall/maple_ir/include/bin_mpl_export.h b/src/mapleall/maple_ir/include/bin_mpl_export.h index 09952cb8c7..f12bec7081 100644 --- a/src/mapleall/maple_ir/include/bin_mpl_export.h +++ b/src/mapleall/maple_ir/include/bin_mpl_export.h @@ -67,8 +67,8 @@ enum : uint8 { kBinEaCgStart = 41, kBinEaStart = 42, kBinNodeBlock = 43, - kBinOpStatement = 44, - kBinOpExpression = 45, +//kBinOpStatement = 44, +//kBinOpExpression = 45, kBinReturnvals = 46, kBinTypeTabStart = 47, kBinSymStart = 48, @@ -76,14 +76,14 @@ enum : uint8 { kBinFuncIdInfoStart = 50, kBinFormalStart = 51, kBinPreg = 52, - kBinPregStart = 53, - kBinLabelStart = 54, + kBinSpecialReg = 53, + kBinLabel = 54, kBinTypenameStart = 55, kBinHeaderStart = 56, kBinAliasMapStart = 57, - kBinKindTypeViaTypename = 58, - kBinKindSymViaSymname = 59, - kBinKindFuncViaSymname = 60, +//kBinKindTypeViaTypename = 58, +//kBinKindSymViaSymname = 59, +//kBinKindFuncViaSymname = 60, kBinFunctionBodyStart = 61, kBinFormalWordsTypeTagged = 62, kBinFormalWordsRefCounted = 63, @@ -103,8 +103,7 @@ class BinaryMplExport { void Export(const std::string &fname, std::unordered_set *dumpFuncSet); void WriteNum(int64 x); void Write(uint8 b); - void OutputType(TyIdx tyIdx, bool canUseTypename); - void OutputTypeViaTypeName(TyIdx tidx) { OutputType(tidx, true); } + void OutputType(TyIdx tyIdx); void WriteFunctionBodyField(uint64 contentIdx, std::unordered_set *dumpFuncSet); void OutputConst(MIRConst *c); void OutputConstBase(const MIRConst &c); @@ -133,12 +132,11 @@ class BinaryMplExport { void OutputInfoVector(const MIRInfoVector &infoVector, const MapleVector &infoVectorIsString); void OutputFuncIdInfo(MIRFunction *func); void OutputLocalSymbol(MIRSymbol *sym); - void OutputLocalSymTab(const MIRFunction *func); - void OutputPregTab(const MIRFunction *func); - void OutputLabelTab(const MIRFunction *func); + void OutputPreg(MIRPreg *preg); + void OutputLabel(LabelIdx lidx); void OutputLocalTypeNameTab(const MIRTypeNameTable *tyNameTab); void OutputFormalsStIdx(MIRFunction *func); - void OutputFuncViaSymName(PUIdx puIdx); + void OutputFuncViaSym(PUIdx puIdx); void OutputExpression(BaseNode *e); void OutputBaseNode(const BaseNode *b); void OutputReturnValues(const CallReturnVector *retv); @@ -182,6 +180,7 @@ class BinaryMplExport { void ExpandFourBuffSize(); MIRModule &mod; + MIRFunction *curFunc = nullptr; size_t bufI = 0; std::vector buf; std::unordered_map gStrMark; @@ -190,6 +189,9 @@ class BinaryMplExport { std::unordered_map uStrMark; std::unordered_map symMark; std::unordered_map typMark; + std::unordered_map localSymMark; + std::unordered_map localPregMark; + std::unordered_map labelMark; friend class UpdateMplt; std::unordered_map callInfoMark; std::map *func2SEMap = nullptr; diff --git a/src/mapleall/maple_ir/include/bin_mpl_import.h b/src/mapleall/maple_ir/include/bin_mpl_import.h index 3697654872..ee7f909f9b 100644 --- a/src/mapleall/maple_ir/include/bin_mpl_import.h +++ b/src/mapleall/maple_ir/include/bin_mpl_import.h @@ -126,15 +126,14 @@ class BinaryMplImport { void ImportInfoVector(MIRInfoVector &infoVector, MapleVector &infoVectorIsString); void ImportLocalTypeNameTable(MIRTypeNameTable *typeNameTab); void ImportFuncIdInfo(MIRFunction *func); - void ImportLocalSymbol(MIRFunction *func); - void ImportLocalSymTab(MIRFunction *func); - void ImportPregTab(const MIRFunction *func); - void ImportLabelTab(MIRFunction *func); + MIRSymbol *ImportLocalSymbol(MIRFunction *func); + PregIdx ImportPreg(MIRFunction *func); + LabelIdx ImportLabel(MIRFunction *func); void ImportFormalsStIdx(MIRFunction *func); void ImportAliasMap(MIRFunction *func); void ImportSrcPos(SrcPosition &pos); void ImportBaseNode(Opcode &o, PrimType &typ); - PUIdx ImportFuncViaSymName(); + PUIdx ImportFuncViaSym(MIRFunction *func); BaseNode *ImportExpression(MIRFunction *func); void ImportReturnValues(MIRFunction *func, CallReturnVector *retv); BlockNode *ImportBlockNode(MIRFunction *fn); @@ -162,6 +161,9 @@ class BinaryMplImport { std::vector typTab; std::vector funcTab; std::vector symTab; + std::vector localSymTab; + std::vector localPregTab; + std::vector localLabelTab; std::vector callInfoTab; std::vector eaCgTab; std::vector methodSymbols; diff --git a/src/mapleall/maple_ir/include/ir_safe_cast_traits.def b/src/mapleall/maple_ir/include/ir_safe_cast_traits.def index 1439b49d57..14ed1a367b 100644 --- a/src/mapleall/maple_ir/include/ir_safe_cast_traits.def +++ b/src/mapleall/maple_ir/include/ir_safe_cast_traits.def @@ -224,7 +224,9 @@ REGISTER_SAFE_CAST(CallNode, from.GetOpCode() == OP_call || from.GetOpCode() == OP_virtualicallassigned || instance_of(from)); REGISTER_SAFE_CAST(IcallNode, from.GetOpCode() == OP_icall || - from.GetOpCode() == OP_icallassigned); + from.GetOpCode() == OP_icallassigned || + from.GetOpCode() == OP_icallproto || + from.GetOpCode() == OP_icallprotoassigned); REGISTER_SAFE_CAST(IntrinsiccallNode, from.GetOpCode() == OP_intrinsiccall || from.GetOpCode() == OP_intrinsiccallwithtype || from.GetOpCode() == OP_xintrinsiccall || diff --git a/src/mapleall/maple_ir/include/keywords.def b/src/mapleall/maple_ir/include/keywords.def index eddff2f80a..51a603eafa 100644 --- a/src/mapleall/maple_ir/include/keywords.def +++ b/src/mapleall/maple_ir/include/keywords.def @@ -55,7 +55,6 @@ // per-function declaration keywords KEYWORD(framesize) KEYWORD(upformalsize) - KEYWORD(outparmsize) KEYWORD(moduleid) KEYWORD(funcsize) KEYWORD(funcid) diff --git a/src/mapleall/maple_ir/include/mir_builder.h b/src/mapleall/maple_ir/include/mir_builder.h index 5e6efdf9ff..b7d42cb431 100755 --- a/src/mapleall/maple_ir/include/mir_builder.h +++ b/src/mapleall/maple_ir/include/mir_builder.h @@ -262,6 +262,8 @@ class MIRBuilder { IcallNode *CreateStmtIcall(const MapleVector &args); IcallNode *CreateStmtIcallAssigned(const MapleVector &args, const MIRSymbol &ret); + IcallNode *CreateStmtIcallproto(const MapleVector &args); + IcallNode *CreateStmtIcallprotoAssigned(const MapleVector &args, const MIRSymbol &ret); // For Call, VirtualCall, SuperclassCall, InterfaceCall IntrinsiccallNode *CreateStmtIntrinsicCall(MIRIntrinsicID idx, const MapleVector &arguments, TyIdx tyIdx = TyIdx()); diff --git a/src/mapleall/maple_ir/include/mir_function.h b/src/mapleall/maple_ir/include/mir_function.h index 256efff6d7..7832995ca4 100644 --- a/src/mapleall/maple_ir/include/mir_function.h +++ b/src/mapleall/maple_ir/include/mir_function.h @@ -830,24 +830,24 @@ class MIRFunction { callTimes = times; } - uint16 GetFrameSize() const { + uint32 GetFrameSize() const { return frameSize; } - void SetFrameSize(uint16 size) { + void SetFrameSize(uint32 size) { frameSize = size; } - uint16 GetUpFormalSize() const { + uint32 GetUpFormalSize() const { return upFormalSize; } - void SetUpFormalSize(uint16 size) { + void SetUpFormalSize(uint32 size) { upFormalSize = size; } - uint16 GetOutParmSize() const { + uint32 GetOutParmSize() const { return outParmSize; } - void SetOutParmSize(uint16 size) { + void SetOutParmSize(uint32 size) { outParmSize = size; } @@ -1298,9 +1298,9 @@ class MIRFunction { bool isDirty = false; bool fromMpltInline = false; // Whether this function is imported from mplt_inline file or not. uint8_t layoutType = kLayoutUnused; - uint16 frameSize = 0; - uint16 upFormalSize = 0; - uint16 outParmSize = 0; + uint32 frameSize = 0; + uint32 upFormalSize = 0; + uint32 outParmSize = 0; uint16 moduleID = 0; uint32 funcSize = 0; // size of code in words uint32 tempCount = 0; diff --git a/src/mapleall/maple_ir/include/mir_lower.h b/src/mapleall/maple_ir/include/mir_lower.h index 332a6de89f..be479f65a6 100644 --- a/src/mapleall/maple_ir/include/mir_lower.h +++ b/src/mapleall/maple_ir/include/mir_lower.h @@ -86,6 +86,7 @@ class MIRLower { ForeachelemNode *ExpandArrayMrtForeachelemBlock(ForeachelemNode &node); BlockNode *ExpandArrayMrtBlock(BlockNode &block); void AddArrayMrtMpl(BaseNode &exp, BlockNode &newblk); + MIRFuncType *FuncTypeFromFuncPtrExpr(BaseNode *x); void SetLowerME() { lowerPhase |= kShiftLowerMe; } diff --git a/src/mapleall/maple_ir/include/mir_nodes.h b/src/mapleall/maple_ir/include/mir_nodes.h index 987aee44f6..98cb801afb 100755 --- a/src/mapleall/maple_ir/include/mir_nodes.h +++ b/src/mapleall/maple_ir/include/mir_nodes.h @@ -3304,7 +3304,7 @@ class CallNode : public NaryStmtNode { CallReturnVector returnValues; }; -// icall and icallproto +// icall, icallassigned, icallproto and icallprotoassigned class IcallNode : public NaryStmtNode { public: IcallNode(MapleAllocator &allocator, Opcode o) diff --git a/src/mapleall/maple_ir/include/mir_parser.h b/src/mapleall/maple_ir/include/mir_parser.h index 10d1dd028a..b49370d0ff 100755 --- a/src/mapleall/maple_ir/include/mir_parser.h +++ b/src/mapleall/maple_ir/include/mir_parser.h @@ -134,6 +134,7 @@ class MIRParser { bool ParseStmtIcall(StmtNodePtr&); bool ParseStmtIcallassigned(StmtNodePtr&); bool ParseStmtIcallproto(StmtNodePtr&); + bool ParseStmtIcallprotoassigned(StmtNodePtr&); bool ParseStmtIntrinsiccall(StmtNodePtr&, bool isAssigned); bool ParseStmtIntrinsiccall(StmtNodePtr&); bool ParseStmtIntrinsiccallassigned(StmtNodePtr&); @@ -291,7 +292,6 @@ class MIRParser { bool ParseStmtBlockForType(); bool ParseStmtBlockForFrameSize(); bool ParseStmtBlockForUpformalSize(); - bool ParseStmtBlockForOutParmSize(); bool ParseStmtBlockForModuleID(); bool ParseStmtBlockForFuncSize(); bool ParseStmtBlockForFuncID(); diff --git a/src/mapleall/maple_ir/include/mir_symbol.h b/src/mapleall/maple_ir/include/mir_symbol.h index 0d1d127dbe..357242d0e2 100644 --- a/src/mapleall/maple_ir/include/mir_symbol.h +++ b/src/mapleall/maple_ir/include/mir_symbol.h @@ -484,12 +484,11 @@ class MIRSymbol { return false; } switch (storageClass) { - case kScFormal: case kScAuto: return true; case kScPstatic: case kScFstatic: - return value.konst == nullptr; + return value.konst == nullptr && !hasPotentialAssignment; default: return false; } @@ -638,7 +637,8 @@ class MIRLabelTable { LabelIdx CreateLabel() { LabelIdx labelIdx = labelTable.size(); - labelTable.push_back(GStrIdx(0)); // insert dummy global string index for anonymous label + GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(std::to_string(labelIdx)); + labelTable.push_back(strIdx); return labelIdx; } diff --git a/src/mapleall/maple_ir/include/mir_type.h b/src/mapleall/maple_ir/include/mir_type.h index c5245d568c..197e7d3ca2 100644 --- a/src/mapleall/maple_ir/include/mir_type.h +++ b/src/mapleall/maple_ir/include/mir_type.h @@ -1189,14 +1189,6 @@ class MIRStructType : public MIRType { isImported = flag; } - bool IsUsed() const { - return isUsed; - } - - void SetIsUsed(bool flag) { - isUsed = flag; - } - bool IsCPlusPlus() const { return isCPlusPlus; } @@ -1368,7 +1360,6 @@ class MIRStructType : public MIRType { vTableMethods.clear(); iTableMethods.clear(); isImported = false; - isUsed = false; hasVolatileField = false; hasVolatileFieldSet = false; } @@ -1471,7 +1462,6 @@ class MIRStructType : public MIRType { // implementation functions, For interfaces, they are abstact functions. // Weak indicates the actual definition is in another module. bool isImported = false; - bool isUsed = false; bool isCPlusPlus = false; // empty struct in C++ has size 1 byte mutable bool hasVolatileField = false; // for caching computed value mutable bool hasVolatileFieldSet = false; // if true, just read hasVolatileField; @@ -1928,11 +1918,19 @@ class MIRFuncType : public MIRType { } bool IsVarargs() const { - return isVarArgs; + return funcAttrs.GetAttr(FUNCATTR_varargs); } - void SetVarArgs(bool flag) { - isVarArgs = flag; + void SetVarArgs() { + funcAttrs.SetAttr(FUNCATTR_varargs); + } + + bool FirstArgReturn() const { + return funcAttrs.GetAttr(FUNCATTR_firstarg_return); + } + + void SetFirstArgReturn() { + funcAttrs.SetAttr(FUNCATTR_firstarg_return); } const TypeAttrs &GetRetAttrs() const { @@ -1960,7 +1958,8 @@ class MIRFuncType : public MIRType { std::vector paramTypeList; std::vector paramAttrsList; TypeAttrs retAttrs; - bool isVarArgs = false; + public: + FuncAttrs funcAttrs; }; class MIRTypeByName : public MIRType { diff --git a/src/mapleall/maple_ir/include/opcode_info.h b/src/mapleall/maple_ir/include/opcode_info.h index 814f15b2f2..5a82646b11 100644 --- a/src/mapleall/maple_ir/include/opcode_info.h +++ b/src/mapleall/maple_ir/include/opcode_info.h @@ -117,6 +117,7 @@ class OpcodeTable { bool IsICall(Opcode o) const { ASSERT(o < OP_last, "invalid opcode"); return o == OP_icall || o == OP_icallassigned || + o == OP_icallproto || o == OP_icallprotoassigned || o == OP_virtualicall || o == OP_virtualicallassigned || o == OP_interfaceicall || o == OP_interfaceicallassigned; } diff --git a/src/mapleall/maple_ir/include/opcodes.def b/src/mapleall/maple_ir/include/opcodes.def index 34cfb51c8d..0e842141ed 100755 --- a/src/mapleall/maple_ir/include/opcodes.def +++ b/src/mapleall/maple_ir/include/opcodes.def @@ -221,3 +221,4 @@ OPCODE(iassignspoff, IassignFPoffNode, OPCODEISSTMT, 8) OPCODE(blkassignoff, BlkassignoffNode, OPCODEISSTMT, 8) OPCODE(icallproto, IcallNode, (OPCODEISSTMT | OPCODEISVARSIZE | OPCODEHASSSAUSE | OPCODEHASSSADEF | OPCODEISCALL), 8) + OPCODE(icallprotoassigned, IcallNode, (OPCODEISSTMT | OPCODEISVARSIZE | OPCODEHASSSAUSE | OPCODEHASSSADEF | OPCODEISCALL | OPCODEISCALLASSIGNED), 8) diff --git a/src/mapleall/maple_ir/include/opcodes.h b/src/mapleall/maple_ir/include/opcodes.h index ea4ed2c1c9..b9f5e0f8c5 100644 --- a/src/mapleall/maple_ir/include/opcodes.h +++ b/src/mapleall/maple_ir/include/opcodes.h @@ -50,7 +50,7 @@ inline constexpr bool IsCallAssigned(Opcode code) { code == OP_virtualicallassigned || code == OP_superclasscallassigned || code == OP_interfacecallassigned || code == OP_interfaceicallassigned || code == OP_customcallassigned || code == OP_polymorphiccallassigned || - code == OP_icallassigned || code == OP_intrinsiccallassigned || + code == OP_icallassigned || code == OP_icallprotoassigned || code == OP_intrinsiccallassigned || code == OP_xintrinsiccallassigned || code == OP_intrinsiccallwithtypeassigned); } @@ -113,6 +113,8 @@ constexpr bool IsStmtMustRequire(Opcode opcode) { case OP_polymorphiccallassigned: case OP_icall: case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: case OP_intrinsiccall: case OP_xintrinsiccall: case OP_intrinsiccallassigned: diff --git a/src/mapleall/maple_ir/src/bin_func_export.cpp b/src/mapleall/maple_ir/src/bin_func_export.cpp index 263ef34c80..6815c8151d 100644 --- a/src/mapleall/maple_ir/src/bin_func_export.cpp +++ b/src/mapleall/maple_ir/src/bin_func_export.cpp @@ -24,6 +24,10 @@ using namespace std; namespace maple { void BinaryMplExport::OutputInfoVector(const MIRInfoVector &infoVector, const MapleVector &infoVectorIsString) { + if (!mod.IsWithDbgInfo()) { + Write(0); + return; + } WriteNum(infoVector.size()); for (uint32 i = 0; i < infoVector.size(); i++) { OutputStr(infoVector[i].first); @@ -41,99 +45,73 @@ void BinaryMplExport::OutputFuncIdInfo(MIRFunction *func) { WriteNum(func->GetPuidxOrigin()); // the funcid OutputInfoVector(func->GetInfoVector(), func->InfoIsString()); if (mod.GetFlavor() == kFlavorLmbc) { - WriteNum(func->GetUpFormalSize()); WriteNum(func->GetFrameSize()); - WriteNum(func->GetOutParmSize()); } - WriteNum(~kBinFuncIdInfoStart); } void BinaryMplExport::OutputBaseNode(const BaseNode *b) { - WriteNum(b->GetOpCode()); - WriteNum(b->GetPrimType()); + Write(static_cast(b->GetOpCode())); + Write(static_cast(b->GetPrimType())); } void BinaryMplExport::OutputLocalSymbol(MIRSymbol *sym) { - if (sym == nullptr) { - WriteNum(0); + std::unordered_map::iterator it = localSymMark.find(sym); + if (it != localSymMark.end()) { + WriteNum(-(it->second)); return; } + WriteNum(kBinSymbol); - WriteNum(sym->GetStIndex()); // preserve original st index OutputStr(sym->GetNameStrIdx()); WriteNum(sym->GetSKind()); WriteNum(sym->GetStorageClass()); + size_t mark = localSymMark.size(); + localSymMark[sym] = mark; OutputTypeAttrs(sym->GetAttrs()); WriteNum(static_cast(sym->GetIsTmp())); if (sym->GetSKind() == kStVar || sym->GetSKind() == kStFunc) { OutputSrcPos(sym->GetSrcPosition()); } - OutputTypeViaTypeName(sym->GetTyIdx()); + OutputType(sym->GetTyIdx()); if (sym->GetSKind() == kStPreg) { - WriteNum(sym->GetPreg()->GetPregNo()); + OutputPreg(sym->GetPreg()); } else if (sym->GetSKind() == kStConst || sym->GetSKind() == kStVar) { OutputConst(sym->GetKonst()); } else if (sym->GetSKind() == kStFunc) { - OutputFuncViaSymName(sym->GetFunction()->GetPuidx()); - OutputTypeViaTypeName(sym->GetTyIdx()); + OutputFuncViaSym(sym->GetFunction()->GetPuidx()); } else { CHECK_FATAL(false, "should not used"); } } -void BinaryMplExport::OutputLocalSymTab(const MIRFunction *func) { - WriteNum(kBinSymStart); - uint64 outsymSizeIdx = buf.size(); - ExpandFourBuffSize(); /// size of OutSym - int32 size = 0; - - for (uint32 i = 1; i < func->GetSymTab()->GetSymbolTableSize(); i++) { - MIRSymbol *s = func->GetSymTab()->GetSymbolFromStIdx(i); - ASSERT(s != nullptr, "null ptr check"); - if (s->IsDeleted()) { - OutputLocalSymbol(nullptr); - } else { - OutputLocalSymbol(s); - } - size++; +void BinaryMplExport::OutputPreg(MIRPreg *preg) { + if (preg->GetPregNo() < 0) { + WriteNum(kBinSpecialReg); + Write(-preg->GetPregNo()); + return; } - - Fixup(outsymSizeIdx, size); - WriteNum(~kBinSymStart); -} - -void BinaryMplExport::OutputPregTab(const MIRFunction *func) { - WriteNum(kBinPregStart); - uint64 outRegSizeIdx = buf.size(); - ExpandFourBuffSize(); /// size of OutReg - int32 size = 0; - - for (uint32 i = 1; i < func->GetPregTab()->Size(); ++i) { - MIRPreg *mirpreg = func->GetPregTab()->PregFromPregIdx(static_cast(i)); - if (mirpreg == nullptr) { - WriteNum(0); - size++; - continue; - } - WriteNum(kBinPreg); - WriteNum(mirpreg->GetPregNo()); - TyIdx tyIdx = (mirpreg->GetMIRType() == nullptr) ? TyIdx(0) : mirpreg->GetMIRType()->GetTypeIndex(); - OutputTypeViaTypeName(tyIdx); - WriteNum(mirpreg->GetPrimType()); - size++; + std::unordered_map::iterator it = localPregMark.find(preg); + if (it != localPregMark.end()) { + WriteNum(-(it->second)); + return; } - Fixup(outRegSizeIdx, size); - WriteNum(~kBinPregStart); + WriteNum(kBinPreg); + Write(static_cast(preg->GetPrimType())); + size_t mark = localPregMark.size(); + localPregMark[preg] = mark; } -void BinaryMplExport::OutputLabelTab(const MIRFunction *func) { - WriteNum(kBinLabelStart); - WriteNum(static_cast(func->GetLabelTab()->Size()-1)); // entry 0 is skipped - for (uint32 i = 1; i < func->GetLabelTab()->Size(); i++) { - OutputStr(func->GetLabelTab()->GetLabelTable()[i]); +void BinaryMplExport::OutputLabel(LabelIdx lidx) { + std::unordered_map::iterator it = labelMark.find(lidx); + if (it != labelMark.end()) { + WriteNum(-(it->second)); + return; } - WriteNum(~kBinLabelStart); + + WriteNum(kBinLabel); + size_t mark = labelMark.size(); + labelMark[lidx] = mark; } void BinaryMplExport::OutputLocalTypeNameTab(const MIRTypeNameTable *typeNameTab) { @@ -141,18 +119,16 @@ void BinaryMplExport::OutputLocalTypeNameTab(const MIRTypeNameTable *typeNameTab WriteNum(static_cast(typeNameTab->Size())); for (std::pair it : typeNameTab->GetGStrIdxToTyIdxMap()) { OutputStr(it.first); - OutputTypeViaTypeName(it.second); + OutputType(it.second); } - WriteNum(~kBinTypenameStart); } void BinaryMplExport::OutputFormalsStIdx(MIRFunction *func) { WriteNum(kBinFormalStart); WriteNum(func->GetFormalDefVec().size()); for (FormalDef formalDef : func->GetFormalDefVec()) { - WriteNum(formalDef.formalSym->GetStIndex()); + OutputLocalSymbol(formalDef.formalSym); } - WriteNum(~kBinFormalStart); } void BinaryMplExport::OutputAliasMap(MapleMap &aliasVarMap) { @@ -161,21 +137,18 @@ void BinaryMplExport::OutputAliasMap(MapleMap &aliasVarMa for (std::pair it : aliasVarMap) { OutputStr(it.first); OutputStr(it.second.memPoolStrIdx); - OutputTypeViaTypeName(it.second.tyIdx); + OutputType(it.second.tyIdx); OutputStr(it.second.sigStrIdx); } - WriteNum(~kBinAliasMapStart); } -void BinaryMplExport::OutputFuncViaSymName(PUIdx puIdx) { +void BinaryMplExport::OutputFuncViaSym(PUIdx puIdx) { MIRFunction *func = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx()); - WriteNum(kBinKindFuncViaSymname); - OutputStr(funcSt->GetNameStrIdx()); + OutputSymbol(funcSt); } void BinaryMplExport::OutputExpression(BaseNode *e) { - WriteNum(kBinOpExpression); OutputBaseNode(e); switch (e->GetOpCode()) { // leaf @@ -191,17 +164,17 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { } case OP_addroflabel: { AddroflabelNode *lNode = static_cast(e); - WriteNum(lNode->GetOffset()); + OutputLabel(lNode->GetOffset()); return; } case OP_addroffunc: { AddroffuncNode *addrNode = static_cast(e); - OutputFuncViaSymName(addrNode->GetPUIdx()); + OutputFuncViaSym(addrNode->GetPUIdx()); return; } case OP_sizeoftype: { SizeoftypeNode *sot = static_cast(e); - OutputTypeViaTypeName(sot->GetTyIdx()); + OutputType(sot->GetTyIdx()); return; } case OP_addrof: @@ -220,24 +193,23 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { } WriteNum(stIdx.Scope()); if (stIdx.Islocal()) { - WriteNum(stIdx.Idx()); // preserve original st index + OutputLocalSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx)); } else { - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(stIdx.Idx()); - WriteNum(kBinKindSymViaSymname); - OutputStr(sym->GetNameStrIdx()); + OutputSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx)); } return; } case OP_regread: { RegreadNode *regreadNode = static_cast(e); - WriteNum(regreadNode->GetRegIdx()); + MIRPreg *preg = curFunc->GetPregTab()->PregFromPregIdx(regreadNode->GetRegIdx()); + OutputPreg(preg); return; } case OP_gcmalloc: case OP_gcpermalloc: case OP_stackmalloc: { GCMallocNode *gcNode = static_cast(e); - OutputTypeViaTypeName(gcNode->GetTyIdx()); + OutputType(gcNode->GetTyIdx()); return; } // unary @@ -246,18 +218,18 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { case OP_floor: case OP_trunc: { TypeCvtNode *typecvtNode = static_cast(e); - WriteNum(typecvtNode->FromType()); + Write(static_cast(typecvtNode->FromType())); break; } case OP_retype: { RetypeNode *retypeNode = static_cast(e); - OutputTypeViaTypeName(retypeNode->GetTyIdx()); + OutputType(retypeNode->GetTyIdx()); break; } case OP_iread: case OP_iaddrof: { IreadNode *irNode = static_cast(e); - OutputTypeViaTypeName(irNode->GetTyIdx()); + OutputType(irNode->GetTyIdx()); WriteNum(irNode->GetFieldID()); break; } @@ -275,20 +247,20 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { case OP_zext: case OP_extractbits: { ExtractbitsNode *extNode = static_cast(e); - WriteNum(extNode->GetBitsOffset()); - WriteNum(extNode->GetBitsSize()); + Write(extNode->GetBitsOffset()); + Write(extNode->GetBitsSize()); break; } case OP_depositbits: { DepositbitsNode *dbNode = static_cast(e); - WriteNum(dbNode->GetBitsOffset()); - WriteNum(dbNode->GetBitsSize()); + Write(dbNode->GetBitsOffset()); + Write(dbNode->GetBitsSize()); break; } case OP_gcmallocjarray: case OP_gcpermallocjarray: { JarrayMallocNode *gcNode = static_cast(e); - OutputTypeViaTypeName(gcNode->GetTyIdx()); + OutputType(gcNode->GetTyIdx()); break; } // binary @@ -321,13 +293,13 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { case OP_cmpl: case OP_cmp: { CompareNode *cmpNode = static_cast(e); - WriteNum(cmpNode->GetOpndType()); + Write(static_cast(cmpNode->GetOpndType())); break; } case OP_resolveinterfacefunc: case OP_resolvevirtualfunc: { ResolveFuncNode *rsNode = static_cast(e); - OutputFuncViaSymName(rsNode->GetPuIdx()); + OutputFuncViaSym(rsNode->GetPuIdx()); break; } // ternary @@ -337,8 +309,8 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { // nary case OP_array: { ArrayNode *arrNode = static_cast(e); - OutputTypeViaTypeName(arrNode->GetTyIdx()); - WriteNum(static_cast(arrNode->GetBoundsCheck())); + OutputType(arrNode->GetTyIdx()); + Write(static_cast(arrNode->GetBoundsCheck())); WriteNum(static_cast(arrNode->NumOpnds())); break; } @@ -351,7 +323,7 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { case OP_intrinsicopwithtype: { IntrinsicopNode *intrnNode = static_cast(e); WriteNum(intrnNode->GetIntrinsic()); - OutputTypeViaTypeName(intrnNode->GetTyIdx()); + OutputType(intrnNode->GetTyIdx()); WriteNum(static_cast(intrnNode->NumOpnds())); break; } @@ -366,6 +338,9 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { static SrcPosition lastOutputSrcPosition; void BinaryMplExport::OutputSrcPos(const SrcPosition &pos) { + if (!mod.IsWithDbgInfo()) { + return; + } if (pos.FileNum() == 0 || pos.LineNum() == 0) { // error case, so output 0 WriteNum(lastOutputSrcPosition.RawData()); WriteNum(lastOutputSrcPosition.LineNum()); @@ -380,9 +355,15 @@ void BinaryMplExport::OutputReturnValues(const CallReturnVector *retv) { WriteNum(kBinReturnvals); WriteNum(static_cast(retv->size())); for (uint32 i = 0; i < retv->size(); i++) { - WriteNum((*retv)[i].first.Idx()); - WriteNum((*retv)[i].second.GetFieldID()); - WriteNum((*retv)[i].second.GetPregIdx()); + RegFieldPair rfp = (*retv)[i].second; + if (rfp.IsReg()) { + MIRPreg *preg = curFunc->GetPregTab()->PregFromPregIdx(rfp.GetPregIdx()); + OutputPreg(preg); + } else { + WriteNum(0); + WriteNum((rfp.GetFieldID())); + OutputLocalSymbol(curFunc->GetLocalOrGlobalSymbol((*retv)[i].first)); + } } } @@ -398,7 +379,6 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { ExpandFourBuffSize(); // place holder, Fixup later for (StmtNode *s = block->GetFirst(); s; s = s->GetNext()) { bool doneWithOpnds = false; - WriteNum(kBinOpStatement); OutputSrcPos(s->GetSrcPos()); WriteNum(s->GetOpCode()); switch (s->GetOpCode()) { @@ -417,36 +397,35 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { } WriteNum(stIdx.Scope()); if (stIdx.Islocal()) { - WriteNum(stIdx.Idx()); // preserve original st index + OutputLocalSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx)); } else { - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(stIdx.Idx()); - WriteNum(kBinKindSymViaSymname); - OutputStr(sym->GetNameStrIdx()); + OutputSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx)); } break; } case OP_regassign: { RegassignNode *rass = static_cast(s); - WriteNum(rass->GetPrimType()); - WriteNum(rass->GetRegIdx()); + Write(static_cast(rass->GetPrimType())); + MIRPreg *preg = curFunc->GetPregTab()->PregFromPregIdx(rass->GetRegIdx()); + OutputPreg(preg); break; } case OP_iassign: { IassignNode *iass = static_cast(s); - OutputTypeViaTypeName(iass->GetTyIdx()); + OutputType(iass->GetTyIdx()); WriteNum(iass->GetFieldID()); break; } case OP_iassignoff: { IassignoffNode *iassoff = static_cast(s); - WriteNum(iassoff->GetPrimType()); + Write(static_cast(iassoff->GetPrimType())); WriteNum(iassoff->GetOffset()); break; } case OP_iassignspoff: case OP_iassignfpoff: { IassignFPoffNode *iassfpoff = static_cast(s); - WriteNum(iassfpoff->GetPrimType()); + Write(static_cast(iassfpoff->GetPrimType())); WriteNum(iassfpoff->GetOffset()); break; } @@ -466,9 +445,9 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { case OP_customcall: case OP_polymorphiccall: { CallNode *callnode = static_cast(s); - OutputFuncViaSymName(callnode->GetPUIdx()); + OutputFuncViaSym(callnode->GetPUIdx()); if (s->GetOpCode() == OP_polymorphiccall) { - OutputTypeViaTypeName(static_cast(callnode)->GetTyIdx()); + OutputType(static_cast(callnode)->GetTyIdx()); } WriteNum(static_cast(s->NumOpnds())); break; @@ -481,15 +460,15 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { case OP_interfaceicallassigned: case OP_customcallassigned: { CallNode *callnode = static_cast(s); - OutputFuncViaSymName(callnode->GetPUIdx()); + OutputFuncViaSym(callnode->GetPUIdx()); OutputReturnValues(&callnode->GetReturnVec()); WriteNum(static_cast(s->NumOpnds())); break; } case OP_polymorphiccallassigned: { CallNode *callnode = static_cast(s); - OutputFuncViaSymName(callnode->GetPUIdx()); - OutputTypeViaTypeName(callnode->GetTyIdx()); + OutputFuncViaSym(callnode->GetPUIdx()); + OutputType(callnode->GetTyIdx()); OutputReturnValues(&callnode->GetReturnVec()); WriteNum(static_cast(s->NumOpnds())); break; @@ -497,13 +476,14 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { case OP_icallproto: case OP_icall: { IcallNode *icallnode = static_cast(s); - OutputTypeViaTypeName(icallnode->GetRetTyIdx()); + OutputType(icallnode->GetRetTyIdx()); WriteNum(static_cast(s->NumOpnds())); break; } + case OP_icallprotoassigned: case OP_icallassigned: { IcallNode *icallnode = static_cast(s); - OutputTypeViaTypeName(icallnode->GetRetTyIdx()); + OutputType(icallnode->GetRetTyIdx()); OutputReturnValues(&icallnode->GetReturnVec()); WriteNum(static_cast(s->NumOpnds())); break; @@ -526,14 +506,14 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { case OP_intrinsiccallwithtype: { IntrinsiccallNode *intrnNode = static_cast(s); WriteNum(intrnNode->GetIntrinsic()); - OutputTypeViaTypeName(intrnNode->GetTyIdx()); + OutputType(intrnNode->GetTyIdx()); WriteNum(static_cast(s->NumOpnds())); break; } case OP_intrinsiccallwithtypeassigned: { IntrinsiccallNode *intrnNode = static_cast(s); WriteNum(intrnNode->GetIntrinsic()); - OutputTypeViaTypeName(intrnNode->GetTyIdx()); + OutputType(intrnNode->GetTyIdx()); OutputReturnValues(&intrnNode->GetReturnVec()); WriteNum(static_cast(s->NumOpnds())); break; @@ -568,28 +548,28 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { } case OP_label: { LabelNode *lNode = static_cast(s); - WriteNum(lNode->GetLabelIdx()); + OutputLabel(lNode->GetLabelIdx()); break; } case OP_goto: case OP_gosub: { GotoNode *gtoNode = static_cast(s); - WriteNum(gtoNode->GetOffset()); + OutputLabel(gtoNode->GetOffset()); break; } case OP_brfalse: case OP_brtrue: { CondGotoNode *cgotoNode = static_cast(s); - WriteNum(cgotoNode->GetOffset()); + OutputLabel(cgotoNode->GetOffset()); break; } case OP_switch: { SwitchNode *swNode = static_cast(s); - WriteNum(swNode->GetDefaultLabel()); + OutputLabel(swNode->GetDefaultLabel()); WriteNum(static_cast(swNode->GetSwitchTable().size())); for (CasePair cpair : swNode->GetSwitchTable()) { WriteNum(cpair.first); - WriteNum(cpair.second); + OutputLabel(cpair.second); } break; } @@ -599,14 +579,14 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { WriteNum(static_cast(rgoto->GetRangeGotoTable().size())); for (SmallCasePair cpair : rgoto->GetRangeGotoTable()) { WriteNum(cpair.first); - WriteNum(cpair.second); + OutputLabel(cpair.second); } break; } case OP_jstry: { JsTryNode *tryNode = static_cast(s); - WriteNum(tryNode->GetCatchOffset()); - WriteNum(tryNode->GetFinallyOffset()); + OutputLabel(tryNode->GetCatchOffset()); + OutputLabel(tryNode->GetFinallyOffset()); break; } case OP_cpptry: @@ -614,7 +594,7 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { TryNode *tryNode = static_cast(s); WriteNum(static_cast(tryNode->GetOffsetsCount())); for (LabelIdx lidx : tryNode->GetOffsets()) { - WriteNum(lidx); + OutputLabel(lidx); } break; } @@ -622,7 +602,7 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { CatchNode *catchNode = static_cast(s); WriteNum(static_cast(catchNode->GetExceptionTyIdxVec().size())); for (TyIdx tidx : catchNode->GetExceptionTyIdxVec()) { - OutputTypeViaTypeName(tidx); + OutputType(tidx); } break; } @@ -679,7 +659,7 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { count = asmNode->gotoLabels.size(); WriteNum(static_cast(count)); for (size_t i = 0; i < count; ++i) { - WriteNum(asmNode->gotoLabels[i]); + OutputLabel(asmNode->gotoLabels[i]); } // the inputs WriteNum(asmNode->NumOpnds()); @@ -714,6 +694,7 @@ void BinaryMplExport::WriteFunctionBodyField(uint64 contentIdx, std::unordered_s if (not2mplt) { for (MIRFunction *func : GetMIRModule().GetFunctionList()) { + curFunc = func; if (func->GetAttr(FUNCATTR_optimized)) { continue; } @@ -734,12 +715,15 @@ void BinaryMplExport::WriteFunctionBodyField(uint64 contentIdx, std::unordered_s continue; } } + localSymMark.clear(); + localSymMark[nullptr] = 0; + localPregMark.clear(); + localPregMark[nullptr] = 0; + labelMark.clear(); + labelMark[0] = 0; OutputFunction(func->GetPuidx()); CHECK_FATAL(func->GetBody() != nullptr, "WriteFunctionBodyField: no function body"); OutputFuncIdInfo(func); - OutputPregTab(func); - OutputLocalSymTab(func); - OutputLabelTab(func); OutputLocalTypeNameTab(func->GetTypeNameTab()); OutputFormalsStIdx(func); if (mod.GetFlavor() < kMmpl) { @@ -753,7 +737,6 @@ void BinaryMplExport::WriteFunctionBodyField(uint64 contentIdx, std::unordered_s Fixup(totalSizeIdx, static_cast(buf.size() - totalSizeIdx)); Fixup(outFunctionBodySizeIdx, size); - WriteNum(~kBinFunctionBodyStart); return; } } // namespace maple diff --git a/src/mapleall/maple_ir/src/bin_func_import.cpp b/src/mapleall/maple_ir/src/bin_func_import.cpp index d16feb4d4a..1903cc5f80 100644 --- a/src/mapleall/maple_ir/src/bin_func_import.cpp +++ b/src/mapleall/maple_ir/src/bin_func_import.cpp @@ -44,29 +44,27 @@ void BinaryMplImport::ImportFuncIdInfo(MIRFunction *func) { func->SetPuidxOrigin(static_cast(ReadNum())); ImportInfoVector(func->GetInfoVector(), func->InfoIsString()); if (mod.GetFlavor() == kFlavorLmbc) { - func->SetUpFormalSize(static_cast(ReadNum())); func->SetFrameSize(static_cast(ReadNum())); - func->SetOutParmSize(static_cast(ReadNum())); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinFuncIdInfoStart, "pattern mismatch in ImportFuncIdInfo()"); } void BinaryMplImport::ImportBaseNode(Opcode &o, PrimType &typ) { - o = static_cast(ReadNum()); - typ = static_cast(ReadNum()); + o = (Opcode)Read(); + typ = (PrimType)Read(); } -void BinaryMplImport::ImportLocalSymbol(MIRFunction *func) { +MIRSymbol *BinaryMplImport::ImportLocalSymbol(MIRFunction *func) { int64 tag = ReadNum(); if (tag == 0) { - func->GetSymTab()->PushNullSymbol(); - return; + return nullptr; } + if (tag < 0) { + CHECK_FATAL(static_cast(-tag) < localSymTab.size(), "index out of bounds"); + return localSymTab.at(-tag); + } CHECK_FATAL(tag == kBinSymbol, "expecting kBinSymbol in ImportLocalSymbol()"); - auto indx = static_cast(ReadNum()); - CHECK_FATAL(indx == func->GetSymTab()->GetSymbolTableSize(), "inconsistant local stIdx"); MIRSymbol *sym = func->GetSymTab()->CreateSymbol(kScopeLocal); + localSymTab.push_back(sym); sym->SetNameStrIdx(ImportStr()); (void)func->GetSymTab()->AddToStringSymbolMap(*sym); sym->SetSKind(static_cast(ReadNum())); @@ -78,66 +76,52 @@ void BinaryMplImport::ImportLocalSymbol(MIRFunction *func) { } sym->SetTyIdx(ImportType()); if (sym->GetSKind() == kStPreg) { - auto thepregno = static_cast(ReadNum()); - MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx()); - PregIdx pregidx = func->GetPregTab()->EnterPregNo(thepregno, mirType->GetPrimType(), mirType); - MIRPregTable *pregTab = func->GetPregTab(); - MIRPreg *preg = pregTab->PregFromPregIdx(pregidx); - preg->SetPrimType(mirType->GetPrimType()); + PregIdx pregidx = ImportPreg(func); + MIRPreg *preg = func->GetPregTab()->PregFromPregIdx(pregidx); sym->SetPreg(preg); } else if (sym->GetSKind() == kStConst || sym->GetSKind() == kStVar) { sym->SetKonst(ImportConst(func)); } else if (sym->GetSKind() == kStFunc) { - PUIdx puIdx = ImportFuncViaSymName(); - TyIdx tyIdx = ImportType(); - sym->SetTyIdx(tyIdx); + PUIdx puIdx = ImportFuncViaSym(func); sym->SetFunction(GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx)); } + return sym; } -void BinaryMplImport::ImportLocalSymTab(MIRFunction *func) { +PregIdx BinaryMplImport::ImportPreg(MIRFunction *func) { int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinSymStart, "kBinSymStart expected in ImportLocalSymTab()"); - int32 size = ReadInt(); - for (int64 i = 0; i < size; ++i) { - ImportLocalSymbol(func); + if (tag == 0) { + return 0; } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinSymStart, "pattern mismatch in ImportLocalSymTab()"); -} - -void BinaryMplImport::ImportPregTab(const MIRFunction *func) { - int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinPregStart, "kBinPregStart expected in ImportPregTab()"); - int32 size = ReadInt(); - for (int64 i = 0; i < size; ++i) { - int64 nextTag = ReadNum(); - if (nextTag == 0) { - func->GetPregTab()->GetPregTable().push_back(nullptr); - continue; - } - CHECK_FATAL(nextTag == kBinPreg, "expecting kBinPreg in ImportPregTab()"); - auto pregNo = static_cast(ReadNum()); - TyIdx tyIdx = ImportType(); - MIRType *ty = (tyIdx == 0) ? nullptr : GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); - PrimType primType = static_cast(ReadNum()); - CHECK_FATAL(ty == nullptr || primType == ty->GetPrimType(), "ImportPregTab: inconsistent primitive type"); - (void)func->GetPregTab()->EnterPregNo(pregNo, primType, ty); + if (tag == kBinSpecialReg) { + return -Read(); + } + if (tag < 0) { + CHECK_FATAL(static_cast(-tag) < localPregTab.size(), "index out of bounds"); + return localPregTab.at(-tag); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinPregStart, "pattern mismatch in ImportPregTab()"); + CHECK_FATAL(tag == kBinPreg, "expecting kBinPreg in ImportPreg()"); + + PrimType primType = (PrimType)Read(); + PregIdx pidx = func->GetPregTab()->CreatePreg(primType); + localPregTab.push_back(pidx); + return pidx; } -void BinaryMplImport::ImportLabelTab(MIRFunction *func) { +LabelIdx BinaryMplImport::ImportLabel(MIRFunction *func) { int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinLabelStart, "kBinLabelStart expected in ImportLabelTab()"); - int64 size = ReadNum(); - for (int64 i = 0; i < size; ++i) { - GStrIdx gStrIdx = ImportStr(); - (void)func->GetLabelTab()->AddLabel(gStrIdx); + if (tag == 0) { + return 0; + } + if (tag < 0) { + CHECK_FATAL(static_cast(-tag) < localLabelTab.size(), "index out of bounds"); + return localLabelTab.at(-tag); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinLabelStart, "pattern mismatch in ImportLabelTab()"); + CHECK_FATAL(tag == kBinLabel, "kBinLabel expected in ImportLabel()"); + + LabelIdx lidx = func->GetLabelTab()->CreateLabel(); + localLabelTab.push_back(lidx); + return lidx; } void BinaryMplImport::ImportLocalTypeNameTable(MIRTypeNameTable *typeNameTab) { @@ -149,8 +133,6 @@ void BinaryMplImport::ImportLocalTypeNameTable(MIRTypeNameTable *typeNameTab) { TyIdx tyIdx = ImportType(); typeNameTab->SetGStrIdxToTyIdx(strIdx, tyIdx); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinTypenameStart, "pattern mismatch in ImportTypenametab()"); } void BinaryMplImport::ImportFormalsStIdx(MIRFunction *func) { @@ -158,11 +140,8 @@ void BinaryMplImport::ImportFormalsStIdx(MIRFunction *func) { CHECK_FATAL(tag == kBinFormalStart, "kBinFormalStart expected in ImportFormalsStIdx()"); auto size = ReadNum(); for (int64 i = 0; i < size; ++i) { - uint32 indx = static_cast(ReadNum()); - func->GetFormalDefVec()[static_cast(i)].formalSym = func->GetSymTab()->GetSymbolFromStIdx(indx); + func->GetFormalDefVec()[static_cast(i)].formalSym = ImportLocalSymbol(func); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinFormalStart, "pattern mismatch in ImportFormalsStIdx()"); } void BinaryMplImport::ImportAliasMap(MIRFunction *func) { @@ -177,23 +156,15 @@ void BinaryMplImport::ImportAliasMap(MIRFunction *func) { (void)ImportStr(); // not assigning to mimic parser func->GetAliasVarMap()[strIdx] = aliasvars; } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinAliasMapStart, "pattern mismatch in ImportAliasMap()"); } -PUIdx BinaryMplImport::ImportFuncViaSymName() { - int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinKindFuncViaSymname, "kBinKindFuncViaSymname expected"); - GStrIdx strIdx = ImportStr(); - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx); - ASSERT(sym != nullptr, "null ptr check"); - MIRFunction *func = sym->GetFunction(); - return func->GetPuidx(); +PUIdx BinaryMplImport::ImportFuncViaSym(MIRFunction *func) { + MIRSymbol *sym = InSymbol(func); + MIRFunction *f = sym->GetFunction(); + return f->GetPuidx(); } BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { - int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinOpExpression, "kBinOpExpression expected"); Opcode op; PrimType typ; ImportBaseNode(op, typ); @@ -213,13 +184,15 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { } case OP_addroflabel: { AddroflabelNode *alabNode = mod.CurFuncCodeMemPool()->New(); - alabNode->SetOffset(static_cast(ReadNum())); + alabNode->SetOffset(ImportLabel(func)); alabNode->SetPrimType(typ); (void)func->GetLabelTab()->addrTakenLabels.insert(alabNode->GetOffset()); return alabNode; } case OP_addroffunc: { - PUIdx puIdx = ImportFuncViaSymName(); + PUIdx puIdx = ImportFuncViaSym(func); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFuncTable()[puIdx]; + f->GetFuncSymbol()->SetAppearsInCode(true); AddroffuncNode *addrNode = mod.CurFuncCodeMemPool()->New(typ, puIdx); return addrNode; } @@ -235,19 +208,18 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { int32 num = static_cast(ReadNum()); StIdx stIdx; stIdx.SetScope(static_cast(ReadNum())); + MIRSymbol *sym = nullptr; if (stIdx.Islocal()) { - stIdx.SetIdx(static_cast(ReadNum())); + sym = ImportLocalSymbol(func); + CHECK_FATAL(sym != nullptr, "null ptr check"); } else { - int32 stag = static_cast(ReadNum()); - CHECK_FATAL(stag == kBinKindSymViaSymname, "kBinKindSymViaSymname expected"); - GStrIdx strIdx = ImportStr(); - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx); - ASSERT(sym != nullptr, "null ptr check"); + sym = InSymbol(func); + CHECK_FATAL(sym != nullptr, "null ptr check"); if (op == OP_addrof) { sym->SetHasPotentialAssignment(); } - stIdx.SetIdx(sym->GetStIdx().Idx()); } + stIdx.SetIdx(sym->GetStIdx().Idx()); if (op == OP_addrof || op == OP_dread) { AddrofNode *drNode = mod.CurFuncCodeMemPool()->New(op); drNode->SetPrimType(typ); @@ -264,7 +236,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { } case OP_regread: { RegreadNode *regreadNode = mod.CurFuncCodeMemPool()->New(); - regreadNode->SetRegIdx(static_cast(ReadNum())); + regreadNode->SetRegIdx(ImportPreg(func)); regreadNode->SetPrimType(typ); return regreadNode; } @@ -293,7 +265,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_floor: case OP_trunc: { TypeCvtNode *typecvtNode = mod.CurFuncCodeMemPool()->New(op, typ); - typecvtNode->SetFromType(static_cast(ReadNum())); + typecvtNode->SetFromType((PrimType)Read()); typecvtNode->SetOpnd(ImportExpression(func), 0); return typecvtNode; } @@ -326,15 +298,15 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_zext: case OP_extractbits: { ExtractbitsNode *extNode = mod.CurFuncCodeMemPool()->New(op, typ); - extNode->SetBitsOffset(static_cast(ReadNum())); - extNode->SetBitsSize(static_cast(ReadNum())); + extNode->SetBitsOffset(Read()); + extNode->SetBitsSize(Read()); extNode->SetOpnd(ImportExpression(func), 0); return extNode; } case OP_depositbits: { DepositbitsNode *dbNode = mod.CurFuncCodeMemPool()->New(op, typ); - dbNode->SetBitsOffset(static_cast(ReadNum())); - dbNode->SetBitsSize(static_cast(ReadNum())); + dbNode->SetBitsOffset(ReadNum()); + dbNode->SetBitsSize(ReadNum()); dbNode->SetOpnd(ImportExpression(func), 0); dbNode->SetOpnd(ImportExpression(func), 1); return dbNode; @@ -379,7 +351,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_cmpl: case OP_cmp: { CompareNode *cmpNode = mod.CurFuncCodeMemPool()->New(op, typ); - cmpNode->SetOpndType(static_cast(ReadNum())); + cmpNode->SetOpndType((PrimType)Read()); cmpNode->SetOpnd(ImportExpression(func), 0); cmpNode->SetOpnd(ImportExpression(func), 1); return cmpNode; @@ -387,7 +359,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_resolveinterfacefunc: case OP_resolvevirtualfunc: { ResolveFuncNode *rsNode = mod.CurFuncCodeMemPool()->New(op, typ); - rsNode->SetPUIdx(ImportFuncViaSymName()); + rsNode->SetPUIdx(ImportFuncViaSym(func)); rsNode->SetOpnd(ImportExpression(func), 0); rsNode->SetOpnd(ImportExpression(func), 1); return rsNode; @@ -403,7 +375,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { // nary case OP_array: { TyIdx tidx = ImportType(); - auto boundsCheck = static_cast(ReadNum()); + bool boundsCheck = static_cast(Read()); ArrayNode *arrNode = mod.CurFuncCodeMemPool()->New(func->GetCodeMPAllocator(), typ, tidx, boundsCheck); auto n = static_cast(ReadNum()); @@ -436,12 +408,15 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { return intrnNode; } default: - CHECK_FATAL(false, "Unhandled op %d", tag); + CHECK_FATAL(false, "Unhandled op %d", op); break; } } void BinaryMplImport::ImportSrcPos(SrcPosition &pos) { + if (!mod.IsWithDbgInfo()) { + return; + } pos.SetRawData(static_cast(ReadNum())); pos.SetLineNum(static_cast(ReadNum())); } @@ -451,15 +426,16 @@ void BinaryMplImport::ImportReturnValues(MIRFunction *func, CallReturnVector *re CHECK_FATAL(tag == kBinReturnvals, "expecting return values"); auto size = static_cast(ReadNum()); for (uint32 i = 0; i < size; ++i) { - uint32 idx = static_cast(ReadNum()); - FieldID fid = static_cast(ReadNum()); - PregIdx ridx = static_cast(ReadNum()); - retv->push_back(std::make_pair(StIdx(kScopeLocal, idx), RegFieldPair(fid, ridx))); - if (idx == 0) { + RegFieldPair rfp; + rfp.SetPregIdx(ImportPreg(func)); + if (rfp.IsReg()) { + retv->push_back(std::make_pair(StIdx(), rfp)); continue; } - MIRSymbol *lsym = func->GetSymTab()->GetSymbolFromStIdx(idx, false); - ASSERT(lsym != nullptr, "null ptr check"); + rfp.SetFieldID(static_cast(ReadNum())); + MIRSymbol *lsym = ImportLocalSymbol(func); + CHECK_FATAL(lsym != nullptr, "null ptr check"); + retv->push_back(std::make_pair(lsym->GetStIdx(), rfp)); if (lsym->GetName().find("L_STR") == 0) { MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(lsym->GetTyIdx()); CHECK_FATAL(ty->GetKind() == kTypePointer, "Pointer type expected for L_STR prefix"); @@ -480,8 +456,6 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { ImportSrcPos(block->GetSrcPos()); int32 size = ReadInt(); for (int32 k = 0; k < size; ++k) { - tag = ReadNum(); - CHECK_FATAL(tag == kBinOpStatement, "kBinOpStatement expected"); SrcPosition thesrcPosition; ImportSrcPos(thesrcPosition); op = static_cast(ReadNum()); @@ -496,17 +470,16 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { int32 num = static_cast(ReadNum()); StIdx stIdx; stIdx.SetScope(static_cast(ReadNum())); + MIRSymbol *sym = nullptr; if (stIdx.Islocal()) { - stIdx.SetIdx(static_cast(ReadNum())); + sym = ImportLocalSymbol(func); + CHECK_FATAL(sym != nullptr, "null ptr check"); } else { - int32 stag = static_cast(ReadNum()); - CHECK_FATAL(stag == kBinKindSymViaSymname, "kBinKindSymViaSymname expected"); - GStrIdx strIdx = ImportStr(); - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx); - ASSERT(sym != nullptr, "null ptr check"); + sym = InSymbol(func); + CHECK_FATAL(sym != nullptr, "null ptr check"); sym->SetHasPotentialAssignment(); - stIdx.SetIdx(sym->GetStIdx().Idx()); } + stIdx.SetIdx(sym->GetStIdx().Idx()); if (op == OP_dassign) { DassignNode *s = func->GetCodeMemPool()->New(); s->SetStIdx(stIdx); @@ -525,8 +498,8 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_regassign: { RegassignNode *s = func->GetCodeMemPool()->New(); - s->SetPrimType(static_cast(ReadNum())); - s->SetRegIdx(static_cast(ReadNum())); + s->SetPrimType((PrimType)Read()); + s->SetRegIdx(ImportPreg(func)); s->SetOpnd(ImportExpression(func), 0); stmt = s; break; @@ -542,7 +515,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_iassignoff: { IassignoffNode *s = func->GetCodeMemPool()->New(); - s->SetPrimType((PrimType)ReadNum()); + s->SetPrimType((PrimType)Read()); s->SetOffset(static_cast(ReadNum())); s->SetOpnd(ImportExpression(func), 0); s->SetOpnd(ImportExpression(func), 1); @@ -552,7 +525,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { case OP_iassignspoff: case OP_iassignfpoff: { IassignFPoffNode *s = func->GetCodeMemPool()->New(op); - s->SetPrimType((PrimType)ReadNum()); + s->SetPrimType((PrimType)Read()); s->SetOffset(static_cast(ReadNum())); s->SetOpnd(ImportExpression(func), 0); stmt = s; @@ -577,7 +550,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { case OP_interfaceicall: case OP_customcall: { CallNode *s = func->GetCodeMemPool()->New(mod, op); - s->SetPUIdx(ImportFuncViaSymName()); + s->SetPUIdx(ImportFuncViaSym(func)); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx()); + f->GetFuncSymbol()->SetAppearsInCode(true); numOpr = static_cast(ReadNum()); s->SetNumOpnds(numOpr); for (int32 i = 0; i < numOpr; ++i) { @@ -594,7 +569,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { case OP_interfaceicallassigned: case OP_customcallassigned: { CallNode *s = func->GetCodeMemPool()->New(mod, op); - s->SetPUIdx(ImportFuncViaSymName()); + s->SetPUIdx(ImportFuncViaSym(func)); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx()); + f->GetFuncSymbol()->SetAppearsInCode(true); ImportReturnValues(func, &s->GetReturnVec()); numOpr = static_cast(ReadNum()); s->SetNumOpnds(numOpr); @@ -610,7 +587,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_polymorphiccall: { CallNode *s = func->GetCodeMemPool()->New(mod, op); - s->SetPUIdx(ImportFuncViaSymName()); + s->SetPUIdx(ImportFuncViaSym(func)); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx()); + f->GetFuncSymbol()->SetAppearsInCode(true); s->SetTyIdx(ImportType()); numOpr = static_cast(ReadNum()); s->SetNumOpnds(numOpr); @@ -622,7 +601,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_polymorphiccallassigned: { CallNode *s = func->GetCodeMemPool()->New(mod, op); - s->SetPUIdx(ImportFuncViaSymName()); + s->SetPUIdx(ImportFuncViaSym(func)); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx()); + f->GetFuncSymbol()->SetAppearsInCode(true); s->SetTyIdx(ImportType()); ImportReturnValues(func, &s->GetReturnVec()); numOpr = static_cast(ReadNum()); @@ -645,6 +626,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { stmt = s; break; } + case OP_icallprotoassigned: case OP_icallassigned: { IcallNode *s = func->GetCodeMemPool()->New(mod, op); s->SetRetTyIdx(ImportType()); @@ -759,32 +741,32 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_label: { LabelNode *s = mod.CurFuncCodeMemPool()->New(); - s->SetLabelIdx(static_cast(ReadNum())); + s->SetLabelIdx(ImportLabel(func)); stmt = s; break; } case OP_goto: case OP_gosub: { GotoNode *s = mod.CurFuncCodeMemPool()->New(op); - s->SetOffset(static_cast(ReadNum())); + s->SetOffset(ImportLabel(func)); stmt = s; break; } case OP_brfalse: case OP_brtrue: { CondGotoNode *s = mod.CurFuncCodeMemPool()->New(op); - s->SetOffset(static_cast(ReadNum())); + s->SetOffset(ImportLabel(func)); s->SetOpnd(ImportExpression(func), 0); stmt = s; break; } case OP_switch: { SwitchNode *s = mod.CurFuncCodeMemPool()->New(mod); - s->SetDefaultLabel(static_cast(ReadNum())); + s->SetDefaultLabel(ImportLabel(func)); auto tagSize = static_cast(ReadNum()); for (uint32 i = 0; i < tagSize; ++i) { int64 casetag = ReadNum(); - LabelIdx lidx(ReadNum()); + LabelIdx lidx = ImportLabel(func); CasePair cpair = std::make_pair(casetag, lidx); s->GetSwitchTable().push_back(cpair); } @@ -798,7 +780,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { uint32 tagSize = static_cast(ReadNum()); for (uint32 i = 0; i < tagSize; ++i) { uint16 casetag = static_cast(ReadNum()); - LabelIdx lidx(ReadNum()); + LabelIdx lidx = ImportLabel(func); s->AddRangeGoto(casetag, lidx); } s->SetOpnd(ImportExpression(func), 0); @@ -807,8 +789,8 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_jstry: { JsTryNode *s = mod.CurFuncCodeMemPool()->New(); - s->SetCatchOffset(static_cast(ReadNum())); - s->SetFinallyOffset(static_cast(ReadNum())); + s->SetCatchOffset(ImportLabel(func)); + s->SetFinallyOffset(ImportLabel(func)); stmt = s; break; } @@ -817,7 +799,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { TryNode *s = mod.CurFuncCodeMemPool()->New(mod); auto numLabels = static_cast(ReadNum()); for (uint32 i = 0; i < numLabels; ++i) { - s->GetOffsets().push_back(ReadNum()); + s->GetOffsets().push_back(ImportLabel(func)); } stmt = s; break; @@ -887,7 +869,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { // the labels count = static_cast(ReadNum()); for (size_t i = 0; i < count; ++i) { - auto lidx = static_cast(ReadNum()); + LabelIdx lidx = ImportLabel(func); s->gotoLabels.push_back(lidx); } // the inputs @@ -927,6 +909,13 @@ void BinaryMplImport::ReadFunctionBodyField() { PUIdx puIdx = ImportFunction(); MIRFunction *fn = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); mod.SetCurFunction(fn); + fn->GetFuncSymbol()->SetAppearsInCode(true); + localSymTab.clear(); + localSymTab.push_back(nullptr); + localPregTab.clear(); + localPregTab.push_back(0); + localLabelTab.clear(); + localLabelTab.push_back(0); fn->AllocSymTab(); fn->AllocPregTab(); @@ -934,9 +923,6 @@ void BinaryMplImport::ReadFunctionBodyField() { fn->AllocLabelTab(); ImportFuncIdInfo(fn); - ImportPregTab(fn); - ImportLocalSymTab(fn); - ImportLabelTab(fn); ImportLocalTypeNameTable(fn->GetTypeNameTab()); ImportFormalsStIdx(fn); if (mod.GetFlavor() < kMmpl) { @@ -945,8 +931,6 @@ void BinaryMplImport::ReadFunctionBodyField() { (void)ImportBlockNode(fn); mod.AddFunction(fn); } - int64 tag = ReadNum(); - CHECK_FATAL(tag == ~kBinFunctionBodyStart, "pattern mismatch in Read FunctionBody"); return; } } // namespace maple diff --git a/src/mapleall/maple_ir/src/bin_mpl_export.cpp b/src/mapleall/maple_ir/src/bin_mpl_export.cpp index c6d58fdd8c..d406b89cdd 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_export.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_export.cpp @@ -26,7 +26,7 @@ namespace { using namespace maple; using OutputConstFactory = FunctionFactory; -using OutputTypeFactory = FunctionFactory; +using OutputTypeFactory = FunctionFactory; void OutputConstInt(const MIRConst &constVal, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindConstInt); @@ -62,7 +62,7 @@ void OutputConstLbl(const MIRConst &constVal, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindConstAddrofLabel); mplExport.OutputConstBase(constVal); const MIRLblConst &lblConst = static_cast(constVal); - mplExport.WriteNum(lblConst.GetValue()); // LabelIdx not needed to output puIdx + mplExport.OutputLabel(lblConst.GetValue()); } void OutputConstStr(const MIRConst &constVal, BinaryMplExport &mplExport) { @@ -141,39 +141,39 @@ static bool InitOutputConstFactory() { return true; } -void OutputTypeScalar(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeScalar(const MIRType &ty, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindTypeScalar); mplExport.OutputTypeBase(ty); } -void OutputTypePointer(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypePointer(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypePointer); mplExport.OutputTypeBase(type); mplExport.OutputTypeAttrs(type.GetTypeAttrs()); - mplExport.OutputType(type.GetPointedTyIdx(), canUseTypename); + mplExport.OutputType(type.GetPointedTyIdx()); } -void OutputTypeByName(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeByName(const MIRType &ty, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindTypeByName); mplExport.OutputTypeBase(ty); } -void OutputTypeFArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeFArray(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeFArray); mplExport.OutputTypeBase(type); - mplExport.OutputType(type.GetElemTyIdx(), canUseTypename); + mplExport.OutputType(type.GetElemTyIdx()); } -void OutputTypeJArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeJArray(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeJarray); mplExport.OutputTypeBase(type); - mplExport.OutputType(type.GetElemTyIdx(), canUseTypename); + mplExport.OutputType(type.GetElemTyIdx()); } -void OutputTypeArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeArray(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeArray); mplExport.OutputTypeBase(type); @@ -181,20 +181,20 @@ void OutputTypeArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseT for (uint16 i = 0; i < type.GetDim(); ++i) { mplExport.WriteNum(type.GetSizeArrayItem(i)); } - mplExport.OutputType(type.GetElemTyIdx(), canUseTypename); + mplExport.OutputType(type.GetElemTyIdx()); mplExport.OutputTypeAttrs(type.GetTypeAttrs()); } -void OutputTypeFunction(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeFunction(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeFunction); mplExport.OutputTypeBase(type); - mplExport.OutputType(type.GetRetTyIdx(), canUseTypename); - mplExport.WriteNum(type.IsVarargs()); + mplExport.OutputType(type.GetRetTyIdx()); + mplExport.WriteNum(type.funcAttrs.GetAttrFlag()); size_t size = type.GetParamTypeList().size(); mplExport.WriteNum(size); for (size_t i = 0; i < size; ++i) { - mplExport.OutputType(type.GetNthParamType(i), canUseTypename); + mplExport.OutputType(type.GetNthParamType(i)); } size = type.GetParamAttrsList().size(); mplExport.WriteNum(size); @@ -203,13 +203,13 @@ void OutputTypeFunction(const MIRType &ty, BinaryMplExport &mplExport, bool canU } } -void OutputTypeParam(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeParam(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeParam); mplExport.OutputTypeBase(type); } -void OutputTypeInstantVector(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeInstantVector(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeInstantVector); mplExport.OutputTypeBase(type); @@ -217,15 +217,15 @@ void OutputTypeInstantVector(const MIRType &ty, BinaryMplExport &mplExport, bool mplExport.OutputTypePairs(type); } -void OutputTypeGenericInstant(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeGenericInstant(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeGenericInstant); mplExport.OutputTypeBase(type); mplExport.OutputTypePairs(type); - mplExport.OutputType(type.GetGenericTyIdx(), canUseTypename); + mplExport.OutputType(type.GetGenericTyIdx()); } -void OutputTypeBitField(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeBitField(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeBitField); mplExport.OutputTypeBase(type); @@ -233,7 +233,7 @@ void OutputTypeBitField(const MIRType &ty, BinaryMplExport &mplExport, bool) { } // for Struct/StructIncomplete/Union -void OutputTypeStruct(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeStruct(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeStruct); mplExport.OutputTypeBase(type); @@ -249,7 +249,7 @@ void OutputTypeStruct(const MIRType &ty, BinaryMplExport &mplExport, bool) { } } -void OutputTypeClass(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeClass(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeClass); mplExport.OutputTypeBase(type); @@ -264,7 +264,7 @@ void OutputTypeClass(const MIRType &ty, BinaryMplExport &mplExport, bool) { } } -void OutputTypeInterface(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeInterface(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeInterface); mplExport.OutputTypeBase(type); @@ -279,7 +279,7 @@ void OutputTypeInterface(const MIRType &ty, BinaryMplExport &mplExport, bool) { } } -void OutputTypeConstString(const MIRType &ty, BinaryMplExport&, bool) { +void OutputTypeConstString(const MIRType &ty, BinaryMplExport&) { ASSERT(false, "Type's kind not yet implemented: %d", ty.GetKind()); (void)ty; } @@ -397,7 +397,7 @@ void BinaryMplExport::DumpBuf(const std::string &name) { void BinaryMplExport::OutputConstBase(const MIRConst &constVal) { WriteNum(constVal.GetKind()); - OutputTypeViaTypeName(constVal.GetType().GetTypeIndex()); + OutputType(constVal.GetType().GetTypeIndex()); } void BinaryMplExport::OutputConst(MIRConst *constVal) { @@ -470,8 +470,8 @@ void BinaryMplExport::OutputPragma(const MIRPragma &p) { WriteNum(p.GetKind()); WriteNum(p.GetVisibility()); OutputStr(p.GetStrIdx()); - OutputType(p.GetTyIdx(), false); - OutputType(p.GetTyIdxEx(), false); + OutputType(p.GetTyIdx()); + OutputType(p.GetTyIdxEx()); WriteNum(p.GetParamNum()); size_t size = p.GetElementVector().size(); WriteNum(size); @@ -488,7 +488,7 @@ void BinaryMplExport::OutputTypeBase(const MIRType &type) { void BinaryMplExport::OutputFieldPair(const FieldPair &fp) { OutputStr(fp.first); // GStrIdx - OutputType(fp.second.first, false); // TyIdx + OutputType(fp.second.first); // TyIdx FieldAttrs fa = fp.second.second; WriteNum(fa.GetAttrFlag()); WriteNum(fa.GetAlignValue()); @@ -511,7 +511,7 @@ void BinaryMplExport::OutputMethodPair(const MethodPair &memPool) { MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(memPool.first.Idx()); CHECK_FATAL(funcSt != nullptr, "Pointer funcSt is nullptr, can't get symbol! Check it!"); WriteAsciiStr(GlobalTables::GetStrTable().GetStringFromStrIdx(funcSt->GetNameStrIdx())); - OutputType(memPool.second.first, false); // TyIdx + OutputType(memPool.second.first); // TyIdx WriteNum(memPool.second.second.GetAttrFlag()); // FuncAttrs } @@ -539,7 +539,7 @@ void BinaryMplExport::OutputStructTypeData(const MIRStructType &type) { void BinaryMplExport::OutputImplementedInterfaces(const std::vector &interfaces) { WriteNum(interfaces.size()); for (const TyIdx &tyIdx : interfaces) { - OutputType(tyIdx, false); + OutputType(tyIdx); } } @@ -571,7 +571,7 @@ void BinaryMplExport::OutputPragmaVec(const std::vector &pragmaVec) } void BinaryMplExport::OutputClassTypeData(const MIRClassType &type) { - OutputType(type.GetParentTyIdx(), false); + OutputType(type.GetParentTyIdx()); OutputImplementedInterfaces(type.GetInterfaceImplemented()); OutputInfoIsString(type.GetInfoIsString()); if (!inIPA) { @@ -601,6 +601,7 @@ void BinaryMplExport::Init() { symMark[nullptr] = 0; funcMark[nullptr] = 0; eaNodeMark[nullptr] = 0; + curFunc = nullptr; for (uint32 pti = static_cast(PTY_begin); pti < static_cast(PTY_end); ++pti) { typMark[GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(pti))] = pti; } @@ -612,7 +613,7 @@ void BinaryMplExport::OutputSymbol(MIRSymbol *sym) { return; } - auto it = symMark.find(sym); + std::unordered_map::iterator it = symMark.find(sym); if (it != symMark.end()) { WriteNum(-(it->second)); return; @@ -645,7 +646,7 @@ void BinaryMplExport::OutputSymbol(MIRSymbol *sym) { if (sym->GetSKind() == kStVar || sym->GetSKind() == kStFunc) { OutputSrcPos(sym->GetSrcPosition()); } - OutputTypeViaTypeName(sym->GetTyIdx()); + OutputType(sym->GetTyIdx()); } void BinaryMplExport::OutputFunction(PUIdx puIdx) { @@ -671,7 +672,7 @@ void BinaryMplExport::OutputFunction(PUIdx puIdx) { MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx()); CHECK_FATAL(funcSt != nullptr, "Pointer funcSt is nullptr, cannot get symbol! Check it!"); OutputSymbol(funcSt); - OutputTypeViaTypeName(func->GetMIRFuncType()->GetTypeIndex()); + OutputType(func->GetMIRFuncType()->GetTypeIndex()); WriteNum(func->GetFuncAttrs().GetAttrFlag()); auto &attributes = func->GetFuncAttrs(); @@ -684,12 +685,12 @@ void BinaryMplExport::OutputFunction(PUIdx puIdx) { } WriteNum(func->GetFlag()); - OutputTypeViaTypeName(func->GetClassTyIdx()); + OutputType(func->GetClassTyIdx()); // output formal parameter information WriteNum(static_cast(func->GetFormalDefVec().size())); for (FormalDef formalDef : func->GetFormalDefVec()) { OutputStr(formalDef.formalStrIdx); - OutputType(formalDef.formalTyIdx, false); + OutputType(formalDef.formalTyIdx); WriteNum(static_cast(formalDef.formalAttrs.GetAttrFlag())); } // store Side Effect for each func @@ -751,15 +752,20 @@ void BinaryMplExport::WriteHeaderField(uint64 contentIdx) { WriteNum(mod.GetID()); if (mod.GetFlavor() == kFlavorLmbc) { WriteNum(mod.GetGlobalMemSize()); + WriteNum(mod.IsWithDbgInfo()); } WriteNum(mod.GetNumFuncs()); WriteAsciiStr(mod.GetEntryFuncName()); OutputInfoVector(mod.GetFileInfo(), mod.GetFileInfoIsString()); - WriteNum(static_cast(mod.GetSrcFileInfo().size())); - for (uint32 i = 0; i < mod.GetSrcFileInfo().size(); i++) { - OutputStr(mod.GetSrcFileInfo()[i].first); - WriteNum(mod.GetSrcFileInfo()[i].second); + if (mod.IsWithDbgInfo()) { + WriteNum(static_cast(mod.GetSrcFileInfo().size())); + for (uint32 i = 0; i < mod.GetSrcFileInfo().size(); i++) { + OutputStr(mod.GetSrcFileInfo()[i].first); + WriteNum(mod.GetSrcFileInfo()[i].second); + } + } else { + Write(0); } WriteNum(static_cast(mod.GetImportFiles().size())); @@ -795,7 +801,7 @@ void BinaryMplExport::WriteTypeField(uint64 contentIdx, bool useClassList) { auto *structType = static_cast(type); // skip imported class/interface and incomplete types if (!structType->IsImported() && !structType->IsIncomplete()) { - OutputType(curTyidx, false); + OutputType(curTyidx); ++size; } } @@ -803,7 +809,7 @@ void BinaryMplExport::WriteTypeField(uint64 contentIdx, bool useClassList) { } else { uint32 idx = GlobalTables::GetTypeTable().lastDefaultTyIdx.GetIdx(); for (idx = idx + 1; idx < GlobalTables::GetTypeTable().GetTypeTableSize(); idx++) { - OutputType(TyIdx(idx), false); + OutputType(TyIdx(idx)); size++; } } @@ -884,7 +890,7 @@ void BinaryMplExport::WriteSeField() { GlobalTables::GetGsymTable().GetSymbolFromStrIdx(GlobalTables::GetStrTable().GetStrIdxFromName(funcStr)); MIRFunction *func = (funcSymbol != nullptr) ? GetMIRModule().GetMIRBuilder()->GetFunctionFromSymbol(*funcSymbol) : nullptr; - OutputType(func->GetReturnTyIdx(), false); + OutputType(func->GetReturnTyIdx()); } ++size; } @@ -1103,7 +1109,7 @@ void BinaryMplExport::WriteSymField(uint64 contentIdx) { MIRSymKind sKind = s->GetSKind(); if (s->IsDeleted() || storageClass == kScUnused || (s->GetIsImported() && !s->GetAppearsInCode()) || - (storageClass == kScExtern && sKind == kStFunc)) { + (sKind == kStFunc && (storageClass == kScExtern || !s->GetAppearsInCode()))) { continue; } OutputSymbol(s); @@ -1214,8 +1220,6 @@ void BinaryMplExport::Export(const std::string &fname, std::unordered_setIsNameIsLocal() && ty->GetNameStrIdx() != GStrIdx(0)) { - WriteNum(kBinKindTypeViaTypename); - OutputStr(ty->GetNameStrIdx()); - return; - } - auto func = CreateProductFunction(ty->GetKind()); if (func != nullptr) { - func(*ty, *this, canUseTypename); + func(*ty, *this); } else { ASSERT(false, "Type's kind not yet implemented: %d", ty->GetKind()); } diff --git a/src/mapleall/maple_ir/src/bin_mpl_import.cpp b/src/mapleall/maple_ir/src/bin_mpl_import.cpp index 049ada30f3..375c84ca02 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_import.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_import.cpp @@ -129,11 +129,13 @@ MIRConst *BinaryMplImport::ImportConst(MIRFunction *func) { } case kBinKindConstAddrofFunc: { PUIdx puIdx = ImportFunction(); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFuncTable()[puIdx]; + f->GetFuncSymbol()->SetAppearsInCode(true); mod.SetCurFunction(func); return memPool->New(puIdx, *type); } case kBinKindConstAddrofLabel: { - LabelIdx lidx = static_cast(ReadNum()); + LabelIdx lidx = ImportLabel(func); PUIdx puIdx = func->GetPuidx(); MIRLblConst *lblConst = memPool->New(lidx, puIdx, *type); (void)func->GetLabelTab()->addrTakenLabels.insert(lidx); @@ -541,20 +543,7 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { CHECK_FATAL(static_cast(-tag) < typTab.size(), "index out of bounds"); return typTab.at(static_cast(-tag)); } - if (tag == kBinKindTypeViaTypename) { - GStrIdx typenameStrIdx = ImportStr(); - TyIdx tyIdx = mod.GetTypeNameTab()->GetTyIdxFromGStrIdx(typenameStrIdx); - if (tyIdx != 0) { - typTab.push_back(tyIdx); - return tyIdx; - } - MIRTypeByName ltype(typenameStrIdx); - ltype.SetNameIsLocal(false); - MIRType *type = GlobalTables::GetTypeTable().GetOrCreateMIRTypeNode(ltype); - typTab.push_back(type->GetTypeIndex()); - return type->GetTypeIndex(); - } - PrimType primType = static_cast(0); + PrimType primType = (PrimType)0; GStrIdx strIdx(0); bool nameIsLocal = false; ImportTypeBase(primType, strIdx, nameIsLocal); @@ -580,13 +569,6 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { } return origType->GetTypeIndex(); } - case kBinKindTypeByName: { - MIRTypeByName type(strIdx); - type.SetNameIsLocal(nameIsLocal); - MIRType *origType = &InsertInTypeTables(type); - typTab.push_back(origType->GetTypeIndex()); - return origType->GetTypeIndex(); - } case kBinKindTypeFArray: { MIRFarrayType type(strIdx); type.SetNameIsLocal(nameIsLocal); @@ -629,7 +611,7 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { size_t idx = typTab.size(); typTab.push_back(TyIdx(0)); type.SetRetTyIdx(ImportType()); - type.SetVarArgs(ReadNum()); + type.funcAttrs.SetAttrFlag(ReadNum()); int64 size = ReadNum(); for (int64 i = 0; i < size; ++i) { type.GetParamTypeList().push_back(ImportType()); @@ -737,20 +719,7 @@ TyIdx BinaryMplImport::ImportTypeNonJava() { CHECK_FATAL(static_cast(-tag) < typTab.size(), "index out of bounds"); return typTab[static_cast(-tag)]; } - if (tag == kBinKindTypeViaTypename) { - GStrIdx typenameStrIdx = ImportStr(); - TyIdx tyIdx = mod.GetTypeNameTab()->GetTyIdxFromGStrIdx(typenameStrIdx); - if (tyIdx != 0) { - typTab.push_back(tyIdx); - return tyIdx; - } - MIRTypeByName ltype(typenameStrIdx); - ltype.SetNameIsLocal(false); - MIRType *type = GlobalTables::GetTypeTable().GetOrCreateMIRTypeNode(ltype); - typTab.push_back(type->GetTypeIndex()); - return type->GetTypeIndex(); - } - PrimType primType = static_cast(0); + PrimType primType = (PrimType)0; GStrIdx strIdx(0); bool nameIsLocal = false; ImportTypeBase(primType, strIdx, nameIsLocal); @@ -771,12 +740,6 @@ TyIdx BinaryMplImport::ImportTypeNonJava() { GlobalTables::GetTypeTable().CreateMirTypeNodeAt(type, tyIdxUsed, &mod, false, false); return tyIdxUsed; } - case kBinKindTypeByName: { - MIRTypeByName type(strIdx); - type.SetNameIsLocal(nameIsLocal); - GlobalTables::GetTypeTable().CreateMirTypeNodeAt(type, tyIdxUsed, &mod, false, false); - return tyIdxUsed; - } case kBinKindTypeFArray: { MIRFarrayType type(strIdx); type.SetNameIsLocal(nameIsLocal); @@ -808,7 +771,7 @@ TyIdx BinaryMplImport::ImportTypeNonJava() { MIRFuncType type(strIdx); type.SetNameIsLocal(nameIsLocal); type.SetRetTyIdx(ImportTypeNonJava()); - type.SetVarArgs(ReadNum()); + type.funcAttrs.SetAttrFlag(ReadNum()); int64 size = ReadNum(); for (int64 i = 0; i < size; ++i) { type.GetParamTypeList().push_back(ImportTypeNonJava()); @@ -1159,6 +1122,7 @@ void BinaryMplImport::ReadHeaderField() { mod.SetID(static_cast(ReadNum())); if (mod.GetFlavor() == kFlavorLmbc) { mod.SetGlobalMemSize(static_cast(ReadNum())); + mod.SetWithDbgInfo(static_cast(ReadNum())); } mod.SetNumFuncs(static_cast(ReadNum())); std::string inStr; diff --git a/src/mapleall/maple_ir/src/global_tables.cpp b/src/mapleall/maple_ir/src/global_tables.cpp index a50d6c46a5..631288a2ea 100644 --- a/src/mapleall/maple_ir/src/global_tables.cpp +++ b/src/mapleall/maple_ir/src/global_tables.cpp @@ -224,7 +224,9 @@ MIRType *TypeTable::GetOrCreateFunctionType(const TyIdx &retTyIdx, const std::ve const std::vector &vecAttrs, bool isVarg, const TypeAttrs &retAttrs) { MIRFuncType funcType(retTyIdx, vecType, vecAttrs, retAttrs); - funcType.SetVarArgs(isVarg); + if (isVarg) { + funcType.SetVarArgs(); + } TyIdx tyIdx = GetOrCreateMIRType(&funcType); ASSERT(tyIdx < typeTable.size(), "index out of range in TypeTable::GetOrCreateFunctionType"); return typeTable.at(tyIdx); diff --git a/src/mapleall/maple_ir/src/mir_builder.cpp b/src/mapleall/maple_ir/src/mir_builder.cpp index 9e57d1514f..965b2a83c6 100755 --- a/src/mapleall/maple_ir/src/mir_builder.cpp +++ b/src/mapleall/maple_ir/src/mir_builder.cpp @@ -836,6 +836,13 @@ IcallNode *MIRBuilder::CreateStmtIcall(const MapleVector &args) { return stmt; } +IcallNode *MIRBuilder::CreateStmtIcallproto(const MapleVector &args) { + auto *stmt = GetCurrentFuncCodeMp()->New(*GetCurrentFuncCodeMpAllocator(), OP_icallproto); + ASSERT(stmt != nullptr, "stmt is null"); + stmt->SetOpnds(args); + return stmt; +} + IcallNode *MIRBuilder::CreateStmtIcallAssigned(const MapleVector &args, const MIRSymbol &ret) { auto *stmt = GetCurrentFuncCodeMp()->New(*GetCurrentFuncCodeMpAllocator(), OP_icallassigned); CallReturnVector nrets(GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -853,6 +860,23 @@ IcallNode *MIRBuilder::CreateStmtIcallAssigned(const MapleVector &arg return stmt; } +IcallNode *MIRBuilder::CreateStmtIcallprotoAssigned(const MapleVector &args, const MIRSymbol &ret) { + auto *stmt = GetCurrentFuncCodeMp()->New(*GetCurrentFuncCodeMpAllocator(), OP_icallprotoassigned); + CallReturnVector nrets(GetCurrentFuncCodeMpAllocator()->Adapter()); + CHECK_FATAL((ret.GetStorageClass() == kScAuto || ret.GetStorageClass() == kScFormal || + ret.GetStorageClass() == kScExtern || ret.GetStorageClass() == kScGlobal), + "unknown classtype! check it!"); + nrets.emplace_back(CallReturnPair(ret.GetStIdx(), RegFieldPair(0, 0))); + stmt->SetNumOpnds(args.size()); + stmt->GetNopnd().resize(stmt->GetNumOpnds()); + stmt->SetReturnVec(nrets); + for (size_t i = 0; i < stmt->GetNopndSize(); ++i) { + stmt->SetNOpndAt(i, args.at(i)); + } + stmt->SetRetTyIdx(ret.GetTyIdx()); + return stmt; +} + IntrinsiccallNode *MIRBuilder::CreateStmtIntrinsicCall(MIRIntrinsicID idx, const MapleVector &arguments, TyIdx tyIdx) { auto *stmt = GetCurrentFuncCodeMp()->New( diff --git a/src/mapleall/maple_ir/src/mir_function.cpp b/src/mapleall/maple_ir/src/mir_function.cpp index 112f5ad6cf..4f217e54c5 100644 --- a/src/mapleall/maple_ir/src/mir_function.cpp +++ b/src/mapleall/maple_ir/src/mir_function.cpp @@ -368,10 +368,8 @@ void MIRFunction::Dump(bool withoutBody) { LogInfo::MapleLogger() << " )"; } - if (module->GetFlavor() < kMmpl) { + if (module->GetFlavor() != kMmpl) { DumpFlavorLoweredThanMmpl(); - } else { - LogInfo::MapleLogger() << " () void"; } // codeMemPool is nullptr, means maple_ir has been released for memory's sake diff --git a/src/mapleall/maple_ir/src/mir_lower.cpp b/src/mapleall/maple_ir/src/mir_lower.cpp index 25cd280a07..8ea87d7d5f 100644 --- a/src/mapleall/maple_ir/src/mir_lower.cpp +++ b/src/mapleall/maple_ir/src/mir_lower.cpp @@ -544,6 +544,19 @@ BlockNode *MIRLower::LowerBlock(BlockNode &block) { case OP_doloop: newBlock->AppendStatementsFromBlock(*LowerDoloopStmt(static_cast(*stmt))); break; + case OP_icallassigned: + case OP_icall: { + if (mirModule.IsCModule()) { + // convert to icallproto/icallprotoassigned + IcallNode *ic = static_cast(stmt); + ic->SetOpCode(stmt->GetOpCode() == OP_icall ? OP_icallproto : OP_icallprotoassigned); + MIRFuncType *funcType = FuncTypeFromFuncPtrExpr(stmt->Opnd(0)); + CHECK_FATAL(funcType != nullptr, "MIRLower::LowerBlock: cannot find prototype for icall"); + ic->SetRetTyIdx(funcType->GetTypeIndex()); + } + newBlock->AddStatement(stmt); + break; + } case OP_block: tmp = LowerBlock(static_cast(*stmt)); newBlock->AppendStatementsFromBlock(*tmp); @@ -999,6 +1012,100 @@ void MIRLower::ExpandArrayMrt(MIRFunction &func) { } } +MIRFuncType *MIRLower::FuncTypeFromFuncPtrExpr(BaseNode *x) { + MIRFuncType *res = nullptr; + MIRFunction *func = mirModule.CurFunction(); + switch (x->GetOpCode()) { + case OP_regread: { + RegreadNode *regread = static_cast(x); + MIRPreg *preg = func->GetPregTab()->PregFromPregIdx(regread->GetRegIdx()); + // see if it is promoted from a symbol + if (preg->GetOp() == OP_dread) { + const MIRSymbol *symbol = preg->rematInfo.sym; + MIRType *mirType = symbol->GetType(); + if (preg->fieldID != 0) { + MIRStructType *structty = static_cast(mirType); + FieldPair thepair = structty->TraverseToField(preg->fieldID); + mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); + } + + if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + if (res != nullptr) { + break; + } + } + // check if a formal promoted to preg + for (FormalDef &formalDef : func->GetFormalDefVec()) { + if (!formalDef.formalSym->IsPreg()) { + continue; + } + if (formalDef.formalSym->GetPreg() == preg) { + MIRType *mirType = formalDef.formalSym->GetType(); + if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + break; + } + } + break; + } + case OP_dread: { + DreadNode *dread = static_cast(x); + MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); + MIRType *mirType = symbol->GetType(); + if (dread->GetFieldID() != 0) { + MIRStructType *structty = static_cast(mirType); + FieldPair thepair = structty->TraverseToField(dread->GetFieldID()); + mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); + } + if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + break; + } + case OP_iread: { + IreadNode *iread = static_cast(x); + MIRPtrType *ptrType = static_cast(iread->GetType()); + MIRType *mirType = ptrType->GetPointedType(); + if (mirType->GetKind() == kTypeFunction) { + res = static_cast(mirType); + } else if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + break; + } + case OP_addroffunc: { + AddroffuncNode *addrofFunc = static_cast(x); + PUIdx puIdx = addrofFunc->GetPUIdx(); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); + res = f->GetMIRFuncType(); + break; + } + case OP_retype: { + MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx( + static_cast(x)->GetTyIdx()); + if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + if (res == nullptr) { + res = FuncTypeFromFuncPtrExpr(x->Opnd(0)); + } + break; + } + case OP_select: { + res = FuncTypeFromFuncPtrExpr(x->Opnd(1)); + if (res == nullptr) { + res = FuncTypeFromFuncPtrExpr(x->Opnd(2)); + } + break; + } + default: CHECK_FATAL(false, "LMBCLowerer::FuncTypeFromFuncPtrExpr: NYI"); + } + return res; +} + const std::set MIRLower::kSetArrayHotFunc = {}; bool MIRLower::ShouldOptArrayMrt(const MIRFunction &func) { diff --git a/src/mapleall/maple_ir/src/mir_nodes.cpp b/src/mapleall/maple_ir/src/mir_nodes.cpp index 2cbc57b314..b969cc91ea 100755 --- a/src/mapleall/maple_ir/src/mir_nodes.cpp +++ b/src/mapleall/maple_ir/src/mir_nodes.cpp @@ -1203,7 +1203,7 @@ MIRType *IcallNode::GetCallReturnType() { if (op == OP_icall || op == OP_icallassigned) { return GlobalTables::GetTypeTable().GetTypeFromTyIdx(retTyIdx); } - // icallproto + // icallproto or icallprotoassigned MIRFuncType *funcType = static_cast( GlobalTables::GetTypeTable().GetTypeFromTyIdx(retTyIdx)); return GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcType->GetRetTyIdx()); @@ -1228,7 +1228,7 @@ const MIRSymbol *IcallNode::GetCallReturnSymbol(const MIRModule &mod) const { void IcallNode::Dump(int32 indent, bool newline) const { StmtNode::DumpBase(indent); - if (op == OP_icallproto) { + if (op == OP_icallproto || op == OP_icallprotoassigned) { LogInfo::MapleLogger() << " "; GlobalTables::GetTypeTable().GetTypeFromTyIdx(retTyIdx)->Dump(indent + 1); } diff --git a/src/mapleall/maple_ir/src/mir_parser.cpp b/src/mapleall/maple_ir/src/mir_parser.cpp index bae4762801..eada04a7b9 100755 --- a/src/mapleall/maple_ir/src/mir_parser.cpp +++ b/src/mapleall/maple_ir/src/mir_parser.cpp @@ -896,6 +896,7 @@ bool MIRParser::ParseStmtCall(StmtNodePtr &stmt) { callStmt->SetPUIdx(pIdx); MIRFunction *callee = GlobalTables::GetFunctionTable().GetFuncTable()[pIdx]; + callee->GetFuncSymbol()->SetAppearsInCode(true); if (callee->GetName() == "setjmp") { mod.CurFunction()->SetHasSetjmp(); } @@ -932,9 +933,14 @@ bool MIRParser::ParseStmtIcall(StmtNodePtr &stmt, Opcode op) { // . . . // dassign } // icallproto (, , ..., ) + // icallprotoassigned (, , ..., ) { + // dassign + // dassign + // . . . + // dassign } IcallNode *iCallStmt = mod.CurFuncCodeMemPool()->New(mod, op); lexer.NextToken(); - if (op == OP_icallproto) { + if (op == OP_icallproto || op == OP_icallprotoassigned) { TyIdx tyIdx(0); if (!ParseDerivedType(tyIdx)) { Error("error parsing type in ParseStmtIcall for icallproto at "); @@ -948,7 +954,7 @@ bool MIRParser::ParseStmtIcall(StmtNodePtr &stmt, Opcode op) { } iCallStmt->SetNOpnd(opndsVec); iCallStmt->SetNumOpnds(opndsVec.size()); - if (op == OP_icallassigned) { + if (op == OP_icallassigned || op == OP_icallprotoassigned) { CallReturnVector retsVec(mod.CurFuncCodeMemPoolAllocator()->Adapter()); if (!ParseCallReturns(retsVec)) { return false; @@ -972,6 +978,10 @@ bool MIRParser::ParseStmtIcallproto(StmtNodePtr &stmt) { return ParseStmtIcall(stmt, OP_icallproto); } +bool MIRParser::ParseStmtIcallprotoassigned(StmtNodePtr &stmt) { + return ParseStmtIcall(stmt, OP_icallprotoassigned); +} + bool MIRParser::ParseStmtIntrinsiccall(StmtNodePtr &stmt, bool isAssigned) { Opcode o = !isAssigned ? (lexer.GetTokenKind() == TK_intrinsiccall ? OP_intrinsiccall : OP_xintrinsiccall) : (lexer.GetTokenKind() == TK_intrinsiccallassigned ? OP_intrinsiccallassigned @@ -2013,18 +2023,6 @@ bool MIRParser::ParseStmtBlockForUpformalSize() { return true; } -bool MIRParser::ParseStmtBlockForOutParmSize() { - MIRFunction *fn = paramCurrFuncForParseStmtBlock; - lexer.NextToken(); - if (lexer.GetTokenKind() != TK_intconst) { - Error("expect integer after outparmsize but get "); - return false; - } - fn->SetOutParmSize(static_cast(lexer.GetTheIntVal())); - lexer.NextToken(); - return true; -} - bool MIRParser::ParseStmtBlockForModuleID() { MIRFunction *fn = paramCurrFuncForParseStmtBlock; lexer.NextToken(); @@ -3241,7 +3239,8 @@ bool MIRParser::ParseConstAddrLeafExpr(MIRConstPtr &cexpr) { } else if (expr->GetOpCode() == OP_addroffunc) { auto *aof = static_cast(expr); MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(aof->GetPUIdx()); - const MIRSymbol *fName = f->GetFuncSymbol(); + MIRSymbol *fName = f->GetFuncSymbol(); + fName->SetAppearsInCode(true); TyIdx ptyIdx = fName->GetTyIdx(); MIRPtrType ptrType(ptyIdx); ptyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&ptrType); @@ -3415,6 +3414,7 @@ std::map MIRParser::InitFuncPtrMapForPar funcPtrMap[TK_icall] = &MIRParser::ParseStmtIcall; funcPtrMap[TK_icallassigned] = &MIRParser::ParseStmtIcallassigned; funcPtrMap[TK_icallproto] = &MIRParser::ParseStmtIcallproto; + funcPtrMap[TK_icallprotoassigned] = &MIRParser::ParseStmtIcallprotoassigned; funcPtrMap[TK_intrinsiccall] = &MIRParser::ParseStmtIntrinsiccall; funcPtrMap[TK_intrinsiccallassigned] = &MIRParser::ParseStmtIntrinsiccallassigned; funcPtrMap[TK_xintrinsiccall] = &MIRParser::ParseStmtIntrinsiccall; @@ -3475,7 +3475,6 @@ std::map MIRParser::InitFuncPtrMapF funcPtrMap[TK_type] = &MIRParser::ParseStmtBlockForType; funcPtrMap[TK_framesize] = &MIRParser::ParseStmtBlockForFrameSize; funcPtrMap[TK_upformalsize] = &MIRParser::ParseStmtBlockForUpformalSize; - funcPtrMap[TK_outparmsize] = &MIRParser::ParseStmtBlockForOutParmSize; funcPtrMap[TK_moduleid] = &MIRParser::ParseStmtBlockForModuleID; funcPtrMap[TK_funcsize] = &MIRParser::ParseStmtBlockForFuncSize; funcPtrMap[TK_funcid] = &MIRParser::ParseStmtBlockForFuncID; diff --git a/src/mapleall/maple_ir/src/mir_type.cpp b/src/mapleall/maple_ir/src/mir_type.cpp index 0c9ff37468..6dac1d09d5 100644 --- a/src/mapleall/maple_ir/src/mir_type.cpp +++ b/src/mapleall/maple_ir/src/mir_type.cpp @@ -738,7 +738,9 @@ void MIRFuncType::Dump(int indent, bool dontUseName) const { if (!dontUseName && CheckAndDumpTypeName(nameStrIdx, nameIsLocal)) { return; } - LogInfo::MapleLogger() << "Dump(indent + 1); @@ -749,7 +751,7 @@ void MIRFuncType::Dump(int indent, bool dontUseName) const { LogInfo::MapleLogger() << ","; } } - if (isVarArgs) { + if (IsVarargs()) { LogInfo::MapleLogger() << ", ..."; } LogInfo::MapleLogger() << ") "; @@ -1663,7 +1665,7 @@ bool MIRFuncType::EqualTo(const MIRType &type) const { } const auto &pType = static_cast(type); return (pType.retTyIdx == retTyIdx && pType.paramTypeList == paramTypeList && - pType.isVarArgs == isVarArgs && pType.paramAttrsList == paramAttrsList && + pType.funcAttrs == funcAttrs && pType.paramAttrsList == paramAttrsList && pType.retAttrs == retAttrs); } diff --git a/src/mapleall/maple_ir/src/parser.cpp b/src/mapleall/maple_ir/src/parser.cpp index db50916351..e8c9178367 100644 --- a/src/mapleall/maple_ir/src/parser.cpp +++ b/src/mapleall/maple_ir/src/parser.cpp @@ -229,9 +229,7 @@ bool MIRParser::ParsePseudoReg(PrimType primType, PregIdx &pRegIdx) { MIRPreg *preg = curfunc->GetPregTab()->PregFromPregIdx(pRegIdx); if (primType != kPtyInvalid) { if (preg->GetPrimType() != primType) { - if ((primType == PTY_ref || primType == PTY_ptr) && - (preg->GetPrimType() == PTY_ref || preg->GetPrimType() == PTY_ptr)) { - ; // PTY_ref and PTY_ptr are compatible with each other + if (IsAddress(preg->GetPrimType()) && IsAddress(primType)) { } else { Error("inconsistent preg primitive type at "); return false; @@ -1299,6 +1297,15 @@ bool MIRParser::ParsePointType(TyIdx &tyIdx) { // in function pointer specification and member function prototypes inside // structs and classes bool MIRParser::ParseFuncType(TyIdx &tyIdx) { + // parse function attributes + FuncAttrs fAttrs; + if (lexer.GetTokenKind() != TK_lparen) { + if (!ParseFuncAttrs(fAttrs)) { + Error("bad function attribute specification in function type at "); + return false; + } + } + // parse parameters if (lexer.GetTokenKind() != TK_lparen) { Error("expect ( parse function type parameters but get "); @@ -1359,7 +1366,10 @@ bool MIRParser::ParseFuncType(TyIdx &tyIdx) { return false; } MIRFuncType functype(retTyIdx, vecTyIdx, vecAttrs, retTypeAttrs); - functype.SetVarArgs(varargs); + functype.funcAttrs = fAttrs; + if (varargs) { + functype.SetVarArgs(); + } tyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&functype); return true; } diff --git a/src/mapleall/maple_me/include/lmbc_lower.h b/src/mapleall/maple_me/include/lmbc_lower.h index 9462204fd7..bbeaabf098 100644 --- a/src/mapleall/maple_me/include/lmbc_lower.h +++ b/src/mapleall/maple_me/include/lmbc_lower.h @@ -40,10 +40,7 @@ class LMBCLowerer { void LowerIassign(IassignNode *, BlockNode *); void LowerAggIassign(IassignNode *, MIRType *type, int32 offset, BlockNode *); void LowerReturn(NaryStmtNode *retNode, BlockNode *newblk); - MIRFuncType *FuncTypeFromFuncPtrExpr(BaseNode *x); - void LowerCall(NaryStmtNode *callNode, BlockNode *newblk); BlockNode *LowerBlock(BlockNode *); - void LoadFormalsAssignedToPregs(); void LowerFunction(); MIRModule *mirModule; diff --git a/src/mapleall/maple_me/include/lmbc_memlayout.h b/src/mapleall/maple_me/include/lmbc_memlayout.h index 68253bb226..833b357561 100644 --- a/src/mapleall/maple_me/include/lmbc_memlayout.h +++ b/src/mapleall/maple_me/include/lmbc_memlayout.h @@ -31,8 +31,8 @@ typedef enum { MS_actual, // for the outgoing parameters MS_local, // for all local variables and temporaries MS_FPbased, // addressed via offset from the frame pointer - MS_SPbased, // addressed via offset from the stack pointer MS_GPbased, // addressed via offset from the global pointer + MS_largeStructActual, // for storing large struct actuals passed by value for ARM CPU } MemSegmentKind; class MemSegment; @@ -66,15 +66,10 @@ class MemSegment { class LMBCMemLayout { public: - uint32 FindLargestActualArea(void); - uint32 FindLargestActualArea(StmtNode *, int &); - LMBCMemLayout(MIRFunction *f, MapleAllocator *mallocator) + LMBCMemLayout(MIRFunction *f, MemSegment *segGP, MapleAllocator *mallocator) : func(f), - seg_upformal(MS_upformal), - seg_formal(MS_formal), - seg_actual(MS_actual), + seg_GPbased(segGP), seg_FPbased(MS_FPbased), - seg_SPbased(MS_SPbased), sym_alloc_table(mallocator->Adapter()) { sym_alloc_table.resize(f->GetSymTab()->GetSymbolTableSize()); } @@ -85,70 +80,25 @@ class LMBCMemLayout { void LayoutStackFrame(void); int32 StackFrameSize(void) const { - return seg_SPbased.size - seg_FPbased.size; - } - - int32 UpformalSize(void) const { - return seg_upformal.size; + return -seg_FPbased.size; } MIRFunction *func; - MemSegment seg_upformal; - MemSegment seg_formal; - MemSegment seg_actual; + MemSegment *seg_GPbased; MemSegment seg_FPbased; - MemSegment seg_SPbased; MapleVector sym_alloc_table; // index is StIdx }; class GlobalMemLayout { public: - GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAllocator *mallocator); - ~GlobalMemLayout() { - be = nullptr; - mirModule = nullptr; - } + GlobalMemLayout(MIRModule *mod, MapleAllocator *mallocator); + ~GlobalMemLayout() {} MemSegment seg_GPbased; MapleVector sym_alloc_table; // index is StIdx - - private: - void FillScalarValueInMap(uint32 startaddress, PrimType pty, MIRConst *c); - void FillTypeValueInMap(uint32 startaddress, MIRType *ty, MIRConst *c); - void FillSymbolValueInMap(const MIRSymbol *sym); - - maplebe::BECommon *be; MIRModule *mirModule; }; -// for specifying how a parameter is passed -struct PLocInfo { - int32 memoffset; - int32 memsize; -}; - -// for processing an incoming or outgoing parameter list -class ParmLocator { - public: - explicit ParmLocator() : parmNum(0), lastMemOffset(0) {} - - ~ParmLocator() {} - - void LocateNextParm(const MIRType *ty, PLocInfo &ploc); - - private: - int32 parmNum; // number of all types of parameters processed so far - int32 lastMemOffset; -}; - -// given the type of the return value, determines the return mechanism -class ReturnMechanism { - public: - ReturnMechanism(const MIRType *retty); - bool fake_first_parm; // whether returning in memory via fake first parameter - PrimType ptype0; // the primitive type stored in retval0 -}; - } /* namespace maple */ #endif /* MAPLEME_INCLUDE_LMBC_MEMLAYOUT_H */ diff --git a/src/mapleall/maple_me/src/alias_class.cpp b/src/mapleall/maple_me/src/alias_class.cpp index c4ef286887..41af97d454 100644 --- a/src/mapleall/maple_me/src/alias_class.cpp +++ b/src/mapleall/maple_me/src/alias_class.cpp @@ -1018,7 +1018,9 @@ void AliasClass::ApplyUnionForCopies(StmtNode &stmt) { } case OP_asm: case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { for (uint32 i = 0; i < stmt.NumOpnds(); ++i) { const AliasInfo &ainfo = CreateAliasInfoExpr(*stmt.Opnd(i)); if (stmt.GetOpCode() != OP_asm && i == 0) { @@ -2569,6 +2571,7 @@ void AliasClass::GenericInsertMayDefUse(StmtNode &stmt, BBId bbID) { case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_virtualcall: case OP_virtualicall: case OP_superclasscall: @@ -2576,7 +2579,8 @@ void AliasClass::GenericInsertMayDefUse(StmtNode &stmt, BBId bbID) { case OP_interfaceicall: case OP_customcall: case OP_polymorphiccall: - case OP_icall: { + case OP_icall: + case OP_icallproto: { InsertMayDefUseCall(stmt, bbID, false); return; } diff --git a/src/mapleall/maple_me/src/code_factoring.cpp b/src/mapleall/maple_me/src/code_factoring.cpp index 175cead017..21f3103b3a 100644 --- a/src/mapleall/maple_me/src/code_factoring.cpp +++ b/src/mapleall/maple_me/src/code_factoring.cpp @@ -126,7 +126,9 @@ bool FactoringOptimizer::IsIdenticalStmt(StmtNode *stmt1, StmtNode *stmt2) { break; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { auto *icall1 = static_cast(stmt1); auto *icall2 = static_cast(stmt2); if (icall1->GetRetTyIdx() != icall2->GetRetTyIdx() || diff --git a/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp b/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp index 2bb97532a6..ba545a5991 100644 --- a/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp +++ b/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp @@ -642,7 +642,9 @@ void PEGBuilder::BuildPEGNodeInStmt(const StmtNode *stmt) { break; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { BuildPEGNodeInIcall(static_cast(stmt)); break; } diff --git a/src/mapleall/maple_me/src/irmap_build.cpp b/src/mapleall/maple_me/src/irmap_build.cpp index 92eece9fa0..b6d96b6726 100755 --- a/src/mapleall/maple_me/src/irmap_build.cpp +++ b/src/mapleall/maple_me/src/irmap_build.cpp @@ -808,7 +808,7 @@ MeStmt *IRMapBuild::BuildCallMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { MeStmt *IRMapBuild::BuildNaryMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { Opcode op = stmt.GetOpCode(); - NaryMeStmt *naryMeStmt = (op == OP_icall || op == OP_icallassigned) + NaryMeStmt *naryMeStmt = (op == OP_icall || op == OP_icallassigned || op == OP_icallproto || op == OP_icallprotoassigned) ? static_cast(irMap->NewInPool(&stmt)) : static_cast(irMap->NewInPool(&stmt)); auto &naryStmtNode = static_cast(stmt); @@ -823,6 +823,9 @@ MeStmt *IRMapBuild::BuildNaryMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { if (propagater) { propagater->PropUpdateChiListDef(*naryMeStmt->GetChiList()); } + if (op == OP_icallproto || op == OP_icallprotoassigned) { + static_cast(naryMeStmt)->SetRetTyIdx(static_cast(stmt).GetRetTyIdx()); + } return naryMeStmt; } @@ -923,6 +926,8 @@ void IRMapBuild::InitMeStmtFactory() { RegisterFactoryFunction(OP_polymorphiccallassigned, &IRMapBuild::BuildCallMeStmt); RegisterFactoryFunction(OP_icall, &IRMapBuild::BuildNaryMeStmt); RegisterFactoryFunction(OP_icallassigned, &IRMapBuild::BuildNaryMeStmt); + RegisterFactoryFunction(OP_icallproto, &IRMapBuild::BuildNaryMeStmt); + RegisterFactoryFunction(OP_icallprotoassigned, &IRMapBuild::BuildNaryMeStmt); RegisterFactoryFunction(OP_intrinsiccall, &IRMapBuild::BuildNaryMeStmt); RegisterFactoryFunction(OP_xintrinsiccall, &IRMapBuild::BuildNaryMeStmt); RegisterFactoryFunction(OP_intrinsiccallwithtype, &IRMapBuild::BuildNaryMeStmt); diff --git a/src/mapleall/maple_me/src/irmap_emit.cpp b/src/mapleall/maple_me/src/irmap_emit.cpp index 1f5f45518c..f6d7b046d8 100755 --- a/src/mapleall/maple_me/src/irmap_emit.cpp +++ b/src/mapleall/maple_me/src/irmap_emit.cpp @@ -412,7 +412,7 @@ MIRFunction &CallMeStmt::GetTargetFunction() { } StmtNode &CallMeStmt::EmitStmt(SSATab &ssaTab) { - if (GetOp() != OP_icall && GetOp() != OP_icallassigned) { + if (GetOp() != OP_icall && GetOp() != OP_icallassigned && GetOp() != OP_icallproto && GetOp() != OP_icallprotoassigned) { auto *callNode = ssaTab.GetModule().CurFunction()->GetCodeMempool()->New(ssaTab.GetModule(), Opcode(GetOp())); callNode->SetPUIdx(puIdx); @@ -497,6 +497,9 @@ StmtNode &IcallMeStmt::EmitStmt(SSATab &ssaTab) { } } } + if (GetOp() == OP_icallproto || GetOp() == OP_icallprotoassigned) { + icallNode->SetRetTyIdx(retTyIdx); + } return *icallNode; } diff --git a/src/mapleall/maple_me/src/lfo_dep_test.cpp b/src/mapleall/maple_me/src/lfo_dep_test.cpp index b1273a8fc3..33f19ee452 100644 --- a/src/mapleall/maple_me/src/lfo_dep_test.cpp +++ b/src/mapleall/maple_me/src/lfo_dep_test.cpp @@ -66,6 +66,8 @@ void LfoDepInfo::CreateDoloopInfo(BlockNode *block, DoloopInfo *parent) { case OP_callassigned: case OP_icall: case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: case OP_return: case OP_throw: case OP_asm: diff --git a/src/mapleall/maple_me/src/lmbc_lower.cpp b/src/mapleall/maple_me/src/lmbc_lower.cpp index a155b25fa4..f5893447ba 100644 --- a/src/mapleall/maple_me/src/lmbc_lower.cpp +++ b/src/mapleall/maple_me/src/lmbc_lower.cpp @@ -22,16 +22,12 @@ using namespace std; PregIdx LMBCLowerer::GetSpecialRegFromSt(const MIRSymbol *sym) { MIRStorageClass storageClass = sym->GetStorageClass(); PregIdx specreg = 0; - if (storageClass == kScAuto || storageClass == kScFormal) { + if (storageClass == kScAuto) { CHECK(sym->GetStIndex() < memlayout->sym_alloc_table.size(), "index out of range in LMBCLowerer::GetSpecialRegFromSt"); SymbolAlloc symalloc = memlayout->sym_alloc_table[sym->GetStIndex()]; - if (symalloc.mem_segment->kind == MS_upformal || symalloc.mem_segment->kind == MS_formal || - symalloc.mem_segment->kind == MS_FPbased) { + if (symalloc.mem_segment->kind == MS_FPbased) { specreg = -kSregFp; - } else if (symalloc.mem_segment->kind == MS_actual || - symalloc.mem_segment->kind == MS_SPbased) { - specreg = -kSregSp; } else { CHECK_FATAL(false, "LMBCLowerer::LowerDread: bad memory layout for local variable"); } @@ -46,6 +42,7 @@ PregIdx LMBCLowerer::GetSpecialRegFromSt(const MIRSymbol *sym) { BaseNode *LMBCLowerer::LowerAddrof(AddrofNode *expr) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(expr->GetStIdx()); + symbol->ResetIsDeleted(); int32 offset = 0; if (expr->GetFieldID() != 0) { MIRStructType *structty = static_cast(symbol->GetType()); @@ -66,6 +63,7 @@ BaseNode *LMBCLowerer::LowerAddrof(AddrofNode *expr) { BaseNode *LMBCLowerer::LowerDread(AddrofNode *expr) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(expr->GetStIdx()); + symbol->ResetIsDeleted(); PrimType symty = symbol->GetType()->GetPrimType(); int32 offset = 0; if (expr->GetFieldID() != 0) { @@ -96,20 +94,22 @@ BaseNode *LMBCLowerer::LowerDread(AddrofNode *expr) { BaseNode *LMBCLowerer::LowerDreadoff(DreadoffNode *dreadoff) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dreadoff->stIdx); + symbol->ResetIsDeleted(); if (!symbol->LMBCAllocateOffSpecialReg()) { return dreadoff; } + PrimType symty = symbol->GetType()->GetPrimType(); PregIdx spcreg = GetSpecialRegFromSt(symbol); if (spcreg == -kSregFp) { CHECK_FATAL(symbol->IsLocal(), "load from fp non local?"); - IreadFPoffNode *ireadoff = mirBuilder->CreateExprIreadFPoff( - dreadoff->GetPrimType(), memlayout->sym_alloc_table[symbol->GetStIndex()].offset + dreadoff->offset); + IreadFPoffNode *ireadoff = mirBuilder->CreateExprIreadFPoff(symty, + memlayout->sym_alloc_table[symbol->GetStIndex()].offset + dreadoff->offset); return ireadoff; } else { BaseNode *rrn = mirBuilder->CreateExprRegread(LOWERED_PTR_TYPE, spcreg); SymbolAlloc &symalloc = symbol->IsLocal() ? memlayout->sym_alloc_table[symbol->GetStIndex()] : globmemlayout->sym_alloc_table[symbol->GetStIndex()]; - IreadoffNode *ireadoff = mirBuilder->CreateExprIreadoff(dreadoff->GetPrimType(), symalloc.offset + dreadoff->offset, rrn); + IreadoffNode *ireadoff = mirBuilder->CreateExprIreadoff(symty, symalloc.offset + dreadoff->offset, rrn); return ireadoff; } } @@ -129,14 +129,14 @@ static MIRType *GetPointedToType(const MIRPtrType *pointerty) { BaseNode *LMBCLowerer::LowerIread(IreadNode *expr) { int32 offset = 0; + MIRPtrType *ptrType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(expr->GetTyIdx())); + MIRType *type = ptrType->GetPointedType(); if (expr->GetFieldID() != 0) { - MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(expr->GetTyIdx()); - MIRStructType *structty = - static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(type)->GetPointedTyIdx())); + MIRStructType *structty = static_cast(type); offset = becommon->GetFieldOffset(*structty, expr->GetFieldID()).first; + type = structty->GetFieldType(expr->GetFieldID()); } - BaseNode *ireadoff = mirBuilder->CreateExprIreadoff(expr->GetPrimType(), offset, expr->Opnd(0)); + BaseNode *ireadoff = mirBuilder->CreateExprIreadoff(type->GetPrimType(), offset, expr->Opnd(0)); return ireadoff; } @@ -165,6 +165,7 @@ BaseNode *LMBCLowerer::LowerExpr(BaseNode *expr) { return LowerAddrof(static_cast(expr)); case OP_addrofoff: { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(static_cast(expr)->stIdx); + symbol->ResetIsDeleted(); CHECK_FATAL(!symbol->LMBCAllocateOffSpecialReg(), "LMBCLowerer:: illegal addrofoff instruction"); break; @@ -199,6 +200,7 @@ void LMBCLowerer::LowerAggDassign(const DassignNode *dsnode, MIRType *lhsty, // generate lhs address expression BaseNode *lhs = nullptr; MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dsnode->GetStIdx()); + symbol->ResetIsDeleted(); if (!symbol->LMBCAllocateOffSpecialReg()) { lhs = mirBuilder->CreateExprDreadoff(OP_addrofoff, LOWERED_PTR_TYPE, *symbol, offset); } else { @@ -218,6 +220,7 @@ void LMBCLowerer::LowerAggDassign(const DassignNode *dsnode, MIRType *lhsty, void LMBCLowerer::LowerDassign(DassignNode *dsnode, BlockNode *newblk) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dsnode->GetStIdx()); + symbol->ResetIsDeleted(); MIRType *symty = symbol->GetType(); int32 offset = 0; if (dsnode->GetFieldID() != 0) { @@ -259,6 +262,7 @@ void LMBCLowerer::LowerDassign(DassignNode *dsnode, BlockNode *newblk) { void LMBCLowerer::LowerDassignoff(DassignoffNode *dsnode, BlockNode *newblk) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dsnode->stIdx); + symbol->ResetIsDeleted(); CHECK_FATAL(dsnode->Opnd(0)->GetPrimType() != PTY_agg, "LowerDassignoff: agg primitive type NYI"); BaseNode *rhs = LowerExpr(dsnode->Opnd(0)); if (!symbol->LMBCAllocateOffSpecialReg()) { @@ -334,6 +338,9 @@ void LMBCLowerer::LowerIassign(IassignNode *iassign, BlockNode *newblk) { } if (iassign->GetRHS()->GetPrimType() != PTY_agg) { PrimType ptypused = type->GetPrimType(); + if (ptypused == PTY_agg) { + ptypused = iassign->GetRHS()->GetPrimType(); + } IassignoffNode *iassignoff = mirBuilder->CreateStmtIassignoff(ptypused, offset, iassign->addrExpr, @@ -347,15 +354,20 @@ void LMBCLowerer::LowerIassign(IassignNode *iassign, BlockNode *newblk) { // called only if the return has > 1 operand; assume prior lowering already // converted any return of structs to be via fake parameter void LMBCLowerer::LowerReturn(NaryStmtNode *retNode, BlockNode *newblk) { - CHECK_FATAL(retNode->NumOpnds() <= 2, "LMBCLowerer::LowerReturn: more than 2 return values NYI"); - for (int i = 0; i < retNode->NumOpnds(); i++) { - CHECK_FATAL(retNode->Opnd(i)->GetPrimType() != PTY_agg, - "LMBCLowerer::LowerReturn: return of aggregate needs to be handled first"); - // insert regassign for the returned value - BaseNode *rhs = LowerExpr(retNode->Opnd(i)); - RegassignNode *regasgn = mirBuilder->CreateStmtRegassign(rhs->GetPrimType(), - i == 0 ? -kSregRetval0 : -kSregRetval1, - rhs); + if (retNode->Opnd(0)->GetPrimType() != PTY_agg) { + CHECK_FATAL(retNode->NumOpnds() <= 2, "LMBCLowerer::LowerReturn: more than 2 return values NYI"); + for (int i = 0; i < retNode->NumOpnds(); i++) { + // insert regassign for the returned value + PrimType ptyp = retNode->Opnd(i)->GetPrimType(); + BaseNode *rhs = LowerExpr(retNode->Opnd(i)); + RegassignNode *regasgn = mirBuilder->CreateStmtRegassign(ptyp, + i == 0 ? -kSregRetval0 : -kSregRetval1, + rhs); + newblk->AddStatement(regasgn); + } + } else { // handle return of small struct using only %%retval0 + BaseNode *rhs = LowerExpr(retNode->Opnd(0)); + RegassignNode *regasgn = mirBuilder->CreateStmtRegassign(PTY_agg, -kSregRetval0, rhs); newblk->AddStatement(regasgn); } retNode->GetNopnd().clear(); // remove the return operands @@ -363,178 +375,6 @@ void LMBCLowerer::LowerReturn(NaryStmtNode *retNode, BlockNode *newblk) { newblk->AddStatement(retNode); } -MIRFuncType *LMBCLowerer::FuncTypeFromFuncPtrExpr(BaseNode *x) { - MIRFuncType *res = nullptr; - switch (x->GetOpCode()) { - case OP_regread: { - RegreadNode *regread = static_cast(x); - MIRPreg *preg = func->GetPregTab()->PregFromPregIdx(regread->GetRegIdx()); - // see if it is promoted from a symbol - if (preg->GetOp() == OP_dread) { - const MIRSymbol *symbol = preg->rematInfo.sym; - MIRType *mirType = symbol->GetType(); - if (preg->fieldID != 0) { - MIRStructType *structty = static_cast(mirType); - FieldPair thepair = structty->TraverseToField(preg->fieldID); - mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - if (res != nullptr) { - break; - } - } - // check if a formal promoted to preg - for (FormalDef &formalDef : func->GetFormalDefVec()) { - if (!formalDef.formalSym->IsPreg()) { - continue; - } - if (formalDef.formalSym->GetPreg() == preg) { - MIRType *mirType = formalDef.formalSym->GetType(); - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - break; - } - } - break; - } - case OP_dread: { - DreadNode *dread = static_cast(x); - MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); - MIRType *mirType = symbol->GetType(); - if (dread->GetFieldID() != 0) { - MIRStructType *structty = static_cast(mirType); - FieldPair thepair = structty->TraverseToField(dread->GetFieldID()); - mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - break; - } - case OP_iread: { - IreadNode *iread = static_cast(x); - MIRPtrType *ptrType = static_cast(iread->GetType()); - MIRType *mirType = ptrType->GetPointedType(); - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - break; - } - case OP_addroffunc: { - AddroffuncNode *addrofFunc = static_cast(x); - PUIdx puIdx = addrofFunc->GetPUIdx(); - MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); - res = f->GetMIRFuncType(); - break; - } - case OP_retype: { - MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(x)->GetTyIdx()); - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - if (res == nullptr) { - res = FuncTypeFromFuncPtrExpr(x->Opnd(0)); - } - break; - } - case OP_select: { - res = FuncTypeFromFuncPtrExpr(x->Opnd(1)); - if (res == nullptr) { - res = FuncTypeFromFuncPtrExpr(x->Opnd(2)); - } - break; - } - default: CHECK_FATAL(false, "LMBCLowerer::FuncTypeFromFuncPtrExpr: NYI"); - } - return res; -} - -void LMBCLowerer::LowerCall(NaryStmtNode *naryStmt, BlockNode *newblk) { - // go through each parameter - uint32 i = 0; - if (naryStmt->GetOpCode() == OP_icall || naryStmt->GetOpCode() == OP_icallassigned) { - i = 1; - } - ParmLocator parmlocator; - for (; i < naryStmt->NumOpnds(); i++) { - BaseNode *opnd = naryStmt->Opnd(i); - MIRType *ty = nullptr; - // get ty for this parameter - if (opnd->GetPrimType() != PTY_agg) { - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(static_cast(opnd->GetPrimType())); - } else { - Opcode opnd_opcode = opnd->GetOpCode(); - CHECK_FATAL(opnd_opcode == OP_dread || opnd_opcode == OP_iread, ""); - if (opnd_opcode == OP_dread) { - AddrofNode *dread = static_cast(opnd); - MIRSymbol *sym = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx()); - if (dread->GetFieldID() != 0) { - CHECK_FATAL(ty->IsStructType(), ""); - FieldPair thepair = static_cast(ty)->TraverseToField(dread->GetFieldID()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - } else { // OP_iread - IreadNode *iread = static_cast(opnd); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread->GetTyIdx()); - CHECK_FATAL(ty->GetKind() == kTypePointer, ""); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(ty)->GetPointedTyIdx()); - if (iread->GetFieldID() != 0) { - CHECK_FATAL(ty->IsStructType(), ""); - FieldPair thepair = static_cast(ty)->TraverseToField(iread->GetFieldID()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - } - } - PLocInfo ploc; - parmlocator.LocateNextParm(ty, ploc); - if (opnd->GetPrimType() != PTY_agg) { - IassignFPoffNode *iass = mirBuilder->CreateStmtIassignFPoff(OP_iassignspoff, - opnd->GetPrimType(), - ploc.memoffset, - LowerExpr(opnd)); - newblk->AddStatement(iass); - } else { - BlkassignoffNode *bass = - mirModule->CurFuncCodeMemPool()->New(ploc.memoffset, ploc.memsize); - bass->SetAlign(std::min(ty->GetAlign(), 8u)); - bass->SetBOpnd(mirBuilder->CreateExprRegread(LOWERED_PTR_TYPE, -kSregSp), 0); - // the operand is either OP_dread or OP_iread; use its address instead - if (opnd->GetOpCode() == OP_dread) { - opnd->SetOpCode(OP_addrof); - } else { - opnd->SetOpCode(OP_iaddrof); - } - opnd->SetPrimType(LOWERED_PTR_TYPE); - bass->SetBOpnd(LowerExpr(opnd), 1); - newblk->AddStatement(bass); - } - } - BaseNode *opnd0 = nullptr; - if (naryStmt->GetOpCode() == OP_icall || naryStmt->GetOpCode() == OP_icallassigned) { - opnd0 = naryStmt->Opnd(0); - naryStmt->GetNopnd().clear(); // remove the call operands - // convert to OP_icallproto by finding the function prototype and record in stmt - naryStmt->SetOpCode(OP_icallproto); - MIRFuncType *funcType = FuncTypeFromFuncPtrExpr(opnd0); - CHECK_FATAL(funcType != nullptr, "LMBCLowerer::LowerCall: cannot find prototype for icall"); - static_cast(naryStmt)->SetRetTyIdx(funcType->GetTypeIndex()); - // add back the function pointer operand - naryStmt->GetNopnd().push_back(LowerExpr(opnd0)); - naryStmt->SetNumOpnds(1); - } else { - naryStmt->GetNopnd().clear(); // remove the call operands - naryStmt->SetNumOpnds(0); - } - newblk->AddStatement(naryStmt); -} - BlockNode *LMBCLowerer::LowerBlock(BlockNode *block) { BlockNode *newblk = mirModule->CurFuncCodeMemPool()->New(); if (!block->GetFirst()) { @@ -569,10 +409,6 @@ BlockNode *LMBCLowerer::LowerBlock(BlockNode *block) { } else { LowerReturn(retNode, newblk); } - } - case OP_call: - case OP_icall: { - LowerCall(static_cast(stmt), newblk); break; } default: { @@ -587,29 +423,19 @@ BlockNode *LMBCLowerer::LowerBlock(BlockNode *block) { return newblk; } -void LMBCLowerer::LoadFormalsAssignedToPregs() { - // go through each formals - for (int32 i = func->GetFormalDefVec().size()-1; i >= 0; i--) { - MIRSymbol *formalSt = func->GetFormalDefVec()[i].formalSym; - if (formalSt->GetSKind() != kStPreg) { - continue; +void LMBCLowerer::LowerFunction() { + // set extern global vars' isDeleted field; will reset when visited + MapleVector::const_iterator sit = mirModule->GetSymbolDefOrder().begin(); + for (; sit != mirModule->GetSymbolDefOrder().end(); ++sit) { + MIRSymbol *s = GlobalTables::GetGsymTable().GetSymbolFromStidx(sit->Idx()); + if (s->GetSKind() == kStVar && s->GetStorageClass() == kScExtern && !s->HasPotentialAssignment()) { + s->SetIsDeleted(); } - MIRPreg *preg = formalSt->GetPreg(); - uint32 stindex = formalSt->GetStIndex(); - PrimType pty = formalSt->GetType()->GetPrimType(); - IreadFPoffNode *ireadfpoff = mirBuilder->CreateExprIreadFPoff(pty, - memlayout->sym_alloc_table[stindex].offset); - RegassignNode *rass = mirBuilder->CreateStmtRegassign(pty, - func->GetPregTab()->GetPregIdxFromPregno(preg->GetPregNo()), ireadfpoff); - func->GetBody()->InsertFirst(rass); } -} -void LMBCLowerer::LowerFunction() { BlockNode *origbody = func->GetBody(); BlockNode *newbody = LowerBlock(origbody); func->SetBody(newbody); - LoadFormalsAssignedToPregs(); } } // namespace maple diff --git a/src/mapleall/maple_me/src/lmbc_memlayout.cpp b/src/mapleall/maple_me/src/lmbc_memlayout.cpp index d7c2a097eb..b32acae493 100644 --- a/src/mapleall/maple_me/src/lmbc_memlayout.cpp +++ b/src/mapleall/maple_me/src/lmbc_memlayout.cpp @@ -13,146 +13,40 @@ * See the MulanPSL - 2.0 for more details. */ -// For each function being compiled, lay out its parameters, return values and -// local variables on its stack frame. This involves determining how parameters -// and return values are passed from analyzing their types. -// -// Allocate all the global variables within the global memory block which is -// addressed via offset from the global pointer GP during execution. Allocate -// this block pointed to by mirModule.globalBlkMap and perform the static -// initializations. +// For each function being compiled, lay out its local variables on its stack +// frame. Allocate all the global variables within the global memory block +// which is addressed via offset from the global pointer GP during execution. +// Allocate this block pointed to by mirModule.globalBlkMap. #include "lmbc_memlayout.h" #include "mir_symbol.h" namespace maple { -uint32 LMBCMemLayout::FindLargestActualArea(StmtNode *stmt, int &maxActualSize) { - if (!stmt) { - return maxActualSize; - } - Opcode opcode = stmt->op; - switch (opcode) { - case OP_block: { - BlockNode *blcknode = static_cast(stmt); - for (StmtNode &s : blcknode->GetStmtNodes()) { - FindLargestActualArea(&s, maxActualSize); - } - break; - } - case OP_if: { - IfStmtNode *ifnode = static_cast(stmt); - FindLargestActualArea(ifnode->GetThenPart(), maxActualSize); - FindLargestActualArea(ifnode->GetElsePart(), maxActualSize); - break; - } - case OP_doloop: { - FindLargestActualArea(static_cast(stmt)->GetDoBody(), maxActualSize); - break; - } - case OP_dowhile: - case OP_while: - FindLargestActualArea(static_cast(stmt)->GetBody(), maxActualSize); - break; - case OP_call: - case OP_icall: - case OP_intrinsiccall: { - ParmLocator parmlocator; // instantiate a parm locator - NaryStmtNode *callstmt = static_cast(stmt); - for (uint32 i = 0; i < callstmt->NumOpnds(); i++) { - BaseNode *opnd = callstmt->Opnd(i); - CHECK_FATAL(opnd->GetPrimType() != PTY_void, ""); - MIRType *ty = nullptr; - if (opnd->GetPrimType() != PTY_agg) { - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(opnd->GetPrimType())); - } else { - Opcode opnd_opcode = opnd->GetOpCode(); - CHECK_FATAL(opnd_opcode == OP_dread || opnd_opcode == OP_iread, ""); - if (opnd_opcode == OP_dread) { - AddrofNode *dread = static_cast(opnd); - MIRSymbol *sym = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx()); - if (dread->GetFieldID() != 0) { - CHECK_FATAL(ty->IsStructType(), "expect struct or class or union"); - FieldPair thepair = - static_cast(ty)->TraverseToField(dread->GetFieldID()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - } else { // OP_iread - IreadNode *iread = static_cast(opnd); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread->GetTyIdx()); - CHECK_FATAL(ty->GetKind() == kTypePointer, ""); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(ty)->GetPointedTyIdx()); - if (iread->GetFieldID() != 0) { - CHECK_FATAL(ty->IsStructType(), "expect struct or class or union"); - FieldPair thepair = - static_cast(ty)->TraverseToField(iread->GetFieldID()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - } - } - PLocInfo ploc; - parmlocator.LocateNextParm(ty, ploc); - maxActualSize = std::max(maxActualSize, ploc.memoffset + ploc.memsize); - maxActualSize = maplebe::RoundUp(maxActualSize, GetPrimTypeSize(PTY_ptr)); - } - break; - } - default: - return maxActualSize; - } - maxActualSize = maplebe::RoundUp(maxActualSize, GetPrimTypeSize(PTY_ptr)); - return maxActualSize; -} - -// go over all outgoing calls in the function body and get the maximum space -// needed for storing the actuals based on the actual parameters and the ABI; -// this assumes that all nesting of statements has been removed, so that all -// the statements are at only one block level -uint32 LMBCMemLayout::FindLargestActualArea(void) { - int32 maxActualSize = 0; - FindLargestActualArea(func->GetBody(), maxActualSize); - return static_cast(maxActualSize); -} +constexpr size_t kVarargSaveAreaSize = 192; void LMBCMemLayout::LayoutStackFrame(void) { - MIRSymbol *sym = nullptr; - // go through formal parameters - ParmLocator parmlocator; // instantiate a parm locator - PLocInfo ploc; - for (uint32 i = 0; i < func->GetFormalDefVec().size(); i++) { - FormalDef formalDef = func->GetFormalDefAt(i); - sym = formalDef.formalSym; - MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(formalDef.formalTyIdx); - parmlocator.LocateNextParm(ty, ploc); - uint32 stindex = sym->GetStIndex(); - // always passed in memory, so allocate in seg_upformal - sym_alloc_table[stindex].mem_segment = &seg_upformal; - seg_upformal.size = maplebe::RoundUp(seg_upformal.size, ty->GetAlign()); - sym_alloc_table[stindex].offset = seg_upformal.size; - seg_upformal.size += ty->GetSize(); - seg_upformal.size = maplebe::RoundUp(seg_upformal.size, GetPrimTypeSize(PTY_ptr)); + if (func->IsVarargs()) { + seg_FPbased.size -= kVarargSaveAreaSize; } - // allocate seg_formal in seg_FPbased - seg_formal.how_alloc.mem_segment = &seg_FPbased; - seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, GetPrimTypeSize(PTY_ptr)); - seg_FPbased.size -= seg_formal.size; - seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, GetPrimTypeSize(PTY_ptr)); - seg_formal.how_alloc.offset = seg_FPbased.size; - // allocate the local variables uint32 symtabsize = func->GetSymTab()->GetSymbolTableSize(); for (uint32 i = 0; i < symtabsize; i++) { - sym = func->GetSymTab()->GetSymbolFromStIdx(i); + MIRSymbol *sym = func->GetSymTab()->GetSymbolFromStIdx(i); if (!sym) { continue; } if (sym->IsDeleted()) { continue; } + if (sym->GetStorageClass() == kScPstatic && sym->LMBCAllocateOffSpecialReg()) { + uint32 stindex = sym->GetStIndex(); + sym_alloc_table[stindex].mem_segment = seg_GPbased; + seg_GPbased->size = maplebe::RoundUp(seg_GPbased->size, sym->GetType()->GetAlign()); + sym_alloc_table[stindex].offset = seg_GPbased->size; + seg_GPbased->size += sym->GetType()->GetSize(); + } if (sym->GetStorageClass() != kScAuto) { continue; } @@ -162,160 +56,10 @@ void LMBCMemLayout::LayoutStackFrame(void) { seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, sym->GetType()->GetAlign()); sym_alloc_table[stindex].offset = seg_FPbased.size; } - seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, GetPrimTypeSize(PTY_ptr)); - - // allocate seg_actual for storing the outgoing parameters; this requires - // going over all outgoing calls and get the maximum space needed for the - // actuals - seg_actual.size = FindLargestActualArea(); - func->SetOutParmSize(seg_actual.size); - - // allocate seg_actual in seg_SPbased - seg_actual.how_alloc.mem_segment = &seg_SPbased; - seg_actual.how_alloc.offset = seg_SPbased.size; - seg_SPbased.size = maplebe::RoundUp(seg_SPbased.size, GetPrimTypeSize(PTY_ptr)); - seg_SPbased.size += seg_actual.size; - seg_SPbased.size = maplebe::RoundUp(seg_SPbased.size, GetPrimTypeSize(PTY_ptr)); -} - -inline uint8 GetU8Const(MIRConst *c) { - MIRIntConst *intconst = static_cast(c); - return static_cast(intconst->GetValue()); -} - -inline uint16 GetU16Const(MIRConst *c) { - MIRIntConst *intconst = static_cast(c); - return static_cast(intconst->GetValue()); -} - -inline uint32 GetU32Const(MIRConst *c) { - MIRIntConst *intconst = static_cast(c); - return static_cast(intconst->GetValue()); -} - -inline uint64 GetU64Const(MIRConst *c) { - MIRIntConst *intconst = static_cast(c); - return static_cast(intconst->GetValue()); -} - -inline uint32 GetF32Const(MIRConst *c) { - MIRFloatConst *floatconst = static_cast(c); - return static_cast(floatconst->GetIntValue()); -} - -inline uint64 GetF64Const(MIRConst *c) { - MIRDoubleConst *doubleconst = static_cast(c); - return static_cast(doubleconst->GetIntValue()); -} - -void GlobalMemLayout::FillScalarValueInMap(uint32 startaddress, PrimType pty, MIRConst *c) { - switch (pty) { - case PTY_u1: - case PTY_u8: - case PTY_i8: { - uint8 *p = &mirModule->GetGlobalBlockMap()[startaddress]; - *p = GetU8Const(c); - break; - } - case PTY_u16: - case PTY_i16: { - uint16 *p = (uint16 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetU16Const(c); - break; - } - case PTY_u32: - case PTY_i32: { - uint32 *p = (uint32 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetU32Const(c); - break; - } - case PTY_u64: - case PTY_i64: { - uint64 *p = (uint64 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetU64Const(c); - break; - } - case PTY_f32: { - uint32 *p = (uint32 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetF32Const(c); - break; - } - case PTY_f64: { - uint64 *p = (uint64 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetF64Const(c); - break; - } - default: - CHECK_FATAL(false, "FillScalarValueInMap: NYI"); - } - return; } -void GlobalMemLayout::FillTypeValueInMap(uint32 startaddress, MIRType *ty, MIRConst *c) { - switch (ty->GetKind()) { - case kTypeScalar: - FillScalarValueInMap(startaddress, ty->GetPrimType(), c); - break; - case kTypeArray: { - MIRArrayType *arraytype = static_cast(ty); - MIRType *elemtype = arraytype->GetElemType(); - int32 elemsize = elemtype->GetSize(); - MIRAggConst *aggconst = static_cast(c); - CHECK_FATAL(aggconst, "FillTypeValueInMap: inconsistent array initialization specification"); - MapleVector &constvec = aggconst->GetConstVec(); - for (MapleVector::iterator it = constvec.begin(); it != constvec.end(); - ++it, startaddress += elemsize) { - FillTypeValueInMap(startaddress, elemtype, *it); - } - break; - } - case kTypeStruct: { - MIRStructType *structty = static_cast(ty); - MIRAggConst *aggconst = static_cast(c); - CHECK_FATAL(aggconst, "FillTypeValueInMap: inconsistent struct initialization specification"); - MapleVector &constvec = aggconst->GetConstVec(); - for (uint32 i = 0; i < constvec.size(); i++) { - uint32 fieldID = aggconst->GetFieldIdItem(i); - FieldPair thepair = structty->TraverseToField(fieldID); - MIRType *fieldty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - uint32 offset = be->GetFieldOffset(*structty, fieldID).first; - FillTypeValueInMap(startaddress + offset, fieldty, constvec[i]); - } - break; - } - case kTypeClass: { - MIRClassType *classty = static_cast(ty); - MIRAggConst *aggconst = static_cast(c); - CHECK_FATAL(aggconst, "FillTypeValueInMap: inconsistent class initialization specification"); - MapleVector &constvec = aggconst->GetConstVec(); - for (uint32 i = 0; i < constvec.size(); i++) { - uint32 fieldID = aggconst->GetFieldIdItem(i); - FieldPair thepair = classty->TraverseToField(fieldID); - MIRType *fieldty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - uint32 offset = be->GetFieldOffset(*classty, fieldID).first; - FillTypeValueInMap(startaddress + offset, fieldty, constvec[i]); - } - break; - } - default: - CHECK_FATAL(false, "FillTypeValueInMap: NYI"); - } -} - -void GlobalMemLayout::FillSymbolValueInMap(const MIRSymbol *sym) { - if (sym->GetKonst() == nullptr) { - return; - } - uint32 stindex = sym->GetStIndex(); - CHECK(stindex < sym_alloc_table.size(), - "index out of range in GlobalMemLayout::FillSymbolValueInMap"); - uint32 symaddress = sym_alloc_table[stindex].offset; - FillTypeValueInMap(symaddress, sym->GetType(), sym->GetKonst()); - return; -} - -GlobalMemLayout::GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAllocator *mallocator) : - seg_GPbased(MS_GPbased), sym_alloc_table(mallocator->Adapter()), be(b), mirModule(mod) { +GlobalMemLayout::GlobalMemLayout(MIRModule *mod, MapleAllocator *mallocator) : + seg_GPbased(MS_GPbased), sym_alloc_table(mallocator->Adapter()), mirModule(mod) { uint32 symtabsize = GlobalTables::GetGsymTable().GetSymbolTableSize(); sym_alloc_table.resize(symtabsize); MIRSymbol *sym = nullptr; @@ -329,6 +73,9 @@ GlobalMemLayout::GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAll if (sym->GetStorageClass() != kScGlobal && sym->GetStorageClass() != kScFstatic) { continue; } + if (!sym->LMBCAllocateOffSpecialReg()) { + continue; + } if (sym->GetType()->GetAlign() != curalign) { continue; } @@ -341,152 +88,6 @@ GlobalMemLayout::GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAll } seg_GPbased.size = maplebe::RoundUp(seg_GPbased.size, GetPrimTypeSize(PTY_ptr)); mirModule->SetGlobalMemSize(seg_GPbased.size); - // allocate the memory map for the GP block - mirModule->SetGlobalBlockMap( - static_cast(mirModule->GetMemPool()->Calloc(seg_GPbased.size))); - // perform initialization on globalblkmap - for (uint32 i = 0; i < symtabsize; i++) { - sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(i); - if (!sym) { - continue; - } - if (sym->GetStorageClass() != kScGlobal && sym->GetStorageClass() != kScFstatic) { - continue; - } - } -} - -// LocateNextParm should be called with each parameter in the parameter list -// starting from the beginning, one call per parameter in sequence; it returns -// the information on how each parameter is passed in ploc -void ParmLocator::LocateNextParm(const MIRType *ty, PLocInfo &ploc) { - ploc.memoffset = maplebe::RoundUp(lastMemOffset, 8); - ploc.memsize = ty->GetSize(); - - uint32 rightpad = 0; - parmNum++; - - switch (ty->GetPrimType()) { - case PTY_u1: - case PTY_u8: - case PTY_i8: - case PTY_u16: - case PTY_i16: - rightpad = GetPrimTypeSize(PTY_i32) - ploc.memsize; - break; - case PTY_a32: - case PTY_u32: - case PTY_i32: - case PTY_a64: - case PTY_u64: - case PTY_i64: - case PTY_ptr: - case PTY_ref: -#ifdef DYNAMICLANG - case PTY_simplestr: - case PTY_simpleobj: - case PTY_dynany: - case PTY_dyni32: - case PTY_dynf64: - case PTY_dynstr: - case PTY_dynobj: - case PTY_dynundef: - case PTY_dynbool: - case PTY_dynf32: - case PTY_dynnone: - case PTY_dynnull: -#endif - break; - - case PTY_f32: - rightpad = GetPrimTypeSize(PTY_f64) - ploc.memsize; - break; - case PTY_c64: - case PTY_f64: - case PTY_v2i32: - case PTY_v4i16: - case PTY_v8i8: - case PTY_v2u32: - case PTY_v4u16: - case PTY_v8u8: - case PTY_v2f32: - break; - - case PTY_c128: - case PTY_v2i64: - case PTY_v4i32: - case PTY_v8i16: - case PTY_v16i8: - case PTY_v2u64: - case PTY_v4u32: - case PTY_v8u16: - case PTY_v16u8: - case PTY_v2f64: - case PTY_v4f32: - break; - - case PTY_agg: { - // compute rightpad - int32 paddedSize = maplebe::RoundUp(ploc.memsize, 8); - rightpad = paddedSize - ploc.memsize; - break; - } - default: - CHECK_FATAL(false, "unsupported type"); - } - - lastMemOffset = ploc.memoffset + ploc.memsize + rightpad; - return; -} - -// instantiated with the type of the function return value, it describes how -// the return value is to be passed back to the caller -ReturnMechanism::ReturnMechanism(const MIRType *retty) : fake_first_parm(false) { - switch (retty->GetPrimType()) { - case PTY_u1: - case PTY_u8: - case PTY_i8: - case PTY_u16: - case PTY_i16: - case PTY_a32: - case PTY_u32: - case PTY_i32: - case PTY_a64: - case PTY_u64: - case PTY_i64: - case PTY_f32: - case PTY_f64: -#ifdef DYNAMICLANG - case PTY_simplestr: - case PTY_simpleobj: - case PTY_dynany: - case PTY_dyni32: - case PTY_dynstr: - case PTY_dynobj: -#endif - ptype0 = retty->GetPrimType(); - return; - - case PTY_c64: - case PTY_c128: - fake_first_parm = true; - ptype0 = PTY_a32; - return; - - case PTY_agg: { - uint32 size = retty->GetSize(); - if (size > 4) { - fake_first_parm = true; - ptype0 = PTY_a32; - } else { - ptype0 = PTY_u32; - } - return; - } - - default: - return; - } } } // namespace maple diff --git a/src/mapleall/maple_me/src/me_cfg.cpp b/src/mapleall/maple_me/src/me_cfg.cpp index ad57c5b166..74e2f176c4 100644 --- a/src/mapleall/maple_me/src/me_cfg.cpp +++ b/src/mapleall/maple_me/src/me_cfg.cpp @@ -261,6 +261,7 @@ bool MeCFG::FindUse(const StmtNode &stmt, StIdx stIdx) const { case OP_customcall: case OP_polymorphiccall: case OP_icall: + case OP_icallproto: case OP_intrinsiccall: case OP_xintrinsiccall: case OP_intrinsiccallwithtype: @@ -273,6 +274,7 @@ bool MeCFG::FindUse(const StmtNode &stmt, StIdx stIdx) const { case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_intrinsiccallassigned: case OP_xintrinsiccallassigned: case OP_intrinsiccallwithtypeassigned: diff --git a/src/mapleall/maple_me/src/me_function.cpp b/src/mapleall/maple_me/src/me_function.cpp index 05181df796..a62f1a89a3 100755 --- a/src/mapleall/maple_me/src/me_function.cpp +++ b/src/mapleall/maple_me/src/me_function.cpp @@ -303,7 +303,9 @@ void MeFunction::CloneBBMeStmts(BB &srcBB, BB &destBB, std::map(&stmt); newStmt = irmap->NewInPool(static_cast(icallStmt), icallStmt->GetRetTyIdx(), icallStmt->GetStmtID()); diff --git a/src/mapleall/maple_me/src/me_lower_globals.cpp b/src/mapleall/maple_me/src/me_lower_globals.cpp index c14dd5c764..fdf2df8e3f 100644 --- a/src/mapleall/maple_me/src/me_lower_globals.cpp +++ b/src/mapleall/maple_me/src/me_lower_globals.cpp @@ -185,7 +185,12 @@ void MeLowerGlobals::Run() { MeExpr *addroffuncExpr = irMap->CreateAddroffuncMeExpr(callee.GetPuidx()); auto insertpos = callStmt.GetOpnds().begin(); callStmt.InsertOpnds(insertpos, addroffuncExpr); - IcallMeStmt *icallStmt = irMap->NewInPool(stmt.GetOp() == OP_call ? OP_icall : OP_icallassigned); + IcallMeStmt *icallStmt = nullptr; + if (func.GetMIRModule().IsCModule()) { + icallStmt = irMap->NewInPool(stmt.GetOp() == OP_call ? OP_icallproto : OP_icallprotoassigned); + } else { + icallStmt = irMap->NewInPool(stmt.GetOp() == OP_call ? OP_icall : OP_icallassigned); + } icallStmt->SetIsLive(callStmt.GetIsLive()); icallStmt->SetSrcPos(callStmt.GetSrcPosition()); for (MeExpr *o : callStmt.GetOpnds()) { @@ -193,7 +198,11 @@ void MeLowerGlobals::Run() { } icallStmt->GetMuList()->insert(callStmt.GetMuList()->begin(), callStmt.GetMuList()->end()); icallStmt->GetChiList()->insert(callStmt.GetChiList()->begin(), callStmt.GetChiList()->end()); - icallStmt->SetRetTyIdx(callee.GetReturnTyIdx()); + if (func.GetMIRModule().IsCModule()) { + icallStmt->SetRetTyIdx(callee.GetMIRFuncType()->GetTypeIndex()); + } else { + icallStmt->SetRetTyIdx(callee.GetReturnTyIdx()); + } if (stmt.GetOp() != OP_call) { if (callStmt.NeedDecref()) { icallStmt->EnableNeedDecref(); diff --git a/src/mapleall/maple_me/src/me_phase_manager.cpp b/src/mapleall/maple_me/src/me_phase_manager.cpp index 09a1b64e5a..a0b5419a8e 100644 --- a/src/mapleall/maple_me/src/me_phase_manager.cpp +++ b/src/mapleall/maple_me/src/me_phase_manager.cpp @@ -140,8 +140,8 @@ bool MeFuncPM::PhaseRun(maple::MIRModule &m) { } if (genLMBC) { m.SetFlavor(kFlavorLmbc); + GlobalMemLayout globalMemLayout(&m, &m.GetMPAllocator()); maplebe::BECommon beCommon(m); - GlobalMemLayout globalMemLayout(&beCommon, &m, &m.GetMPAllocator()); maplebe::CGLowerer cgLower(m, beCommon, false, false); cgLower.RegisterBuiltIns(); cgLower.RegisterExternalLibraryFunctions(); @@ -153,14 +153,15 @@ bool MeFuncPM::PhaseRun(maple::MIRModule &m) { cgLower.LowerFunc(*func); MemPool *layoutMp = memPoolCtrler.NewMemPool("layout mempool", true); MapleAllocator layoutAlloc(layoutMp); - LMBCMemLayout localMemLayout(func, &layoutAlloc); + LMBCMemLayout localMemLayout(func, &globalMemLayout.seg_GPbased, &layoutAlloc); localMemLayout.LayoutStackFrame(); LMBCLowerer lmbcLowerer(&m, &beCommon, func, &globalMemLayout, &localMemLayout); lmbcLowerer.LowerFunction(); func->SetFrameSize(localMemLayout.StackFrameSize()); - func->SetUpFormalSize(localMemLayout.UpformalSize()); memPoolCtrler.DeleteMemPool(layoutMp); } + globalMemLayout.seg_GPbased.size = maplebe::RoundUp(globalMemLayout.seg_GPbased.size, GetPrimTypeSize(PTY_ptr)); + m.SetGlobalMemSize(globalMemLayout.seg_GPbased.size); // output .lmbc BinaryMplt binMplt(m); std::string modFileName = m.GetFileName(); diff --git a/src/mapleall/maple_me/src/me_rc_lowering.cpp b/src/mapleall/maple_me/src/me_rc_lowering.cpp index 1c7319e18b..131ebbdd2a 100644 --- a/src/mapleall/maple_me/src/me_rc_lowering.cpp +++ b/src/mapleall/maple_me/src/me_rc_lowering.cpp @@ -1145,6 +1145,7 @@ void RCLowering::HandleArguments() { firstBB->InsertMeStmtBefore(firstMeStmt, incCall); } sym->SetLocalRefVar(); + mirFunc->GetFormalDefVec()[i].formalAttrs.SetAttr(ATTR_localrefvar); for (auto *stmt : rets) { std::vector opnds = { argVar }; diff --git a/src/mapleall/maple_me/src/me_rename2preg.cpp b/src/mapleall/maple_me/src/me_rename2preg.cpp index 9549dff004..eddc9704b9 100644 --- a/src/mapleall/maple_me/src/me_rename2preg.cpp +++ b/src/mapleall/maple_me/src/me_rename2preg.cpp @@ -317,6 +317,7 @@ void SSARename2Preg::Rename2PregStmt(MeStmt *stmt) { case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_intrinsiccallassigned: case OP_xintrinsiccallassigned: case OP_intrinsiccallwithtypeassigned: { diff --git a/src/mapleall/maple_me/src/me_side_effect.cpp b/src/mapleall/maple_me/src/me_side_effect.cpp index 67dea87820..52fcda8516 100644 --- a/src/mapleall/maple_me/src/me_side_effect.cpp +++ b/src/mapleall/maple_me/src/me_side_effect.cpp @@ -933,6 +933,7 @@ bool IpaSideEffect::UpdateSideEffectWithStmt(MeStmt &meStmt, case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_superclasscallassigned: case OP_asm: { hasPrivateDef = hasThrException = true; @@ -959,7 +960,8 @@ bool IpaSideEffect::UpdateSideEffectWithStmt(MeStmt &meStmt, case OP_interfaceicall: case OP_customcall: case OP_polymorphiccall: - case OP_icall: { + case OP_icall: + case OP_icallproto: { hasPrivateDef = hasThrException = true; SetHasDef(); for (size_t i = 0; i < meStmt.NumMeStmtOpnds(); ++i) { diff --git a/src/mapleall/maple_me/src/me_stmt_pre.cpp b/src/mapleall/maple_me/src/me_stmt_pre.cpp index d50e3c5371..3f5d2bff57 100755 --- a/src/mapleall/maple_me/src/me_stmt_pre.cpp +++ b/src/mapleall/maple_me/src/me_stmt_pre.cpp @@ -967,7 +967,9 @@ void MeStmtPre::BuildWorkListBB(BB *bb) { break; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { auto &icallMeStmt = static_cast(stmt); VersionStackChiListUpdate(*icallMeStmt.GetChiList()); break; diff --git a/src/mapleall/maple_me/src/pme_emit.cpp b/src/mapleall/maple_me/src/pme_emit.cpp index 227cb6a761..52e1df6beb 100755 --- a/src/mapleall/maple_me/src/pme_emit.cpp +++ b/src/mapleall/maple_me/src/pme_emit.cpp @@ -485,10 +485,12 @@ StmtNode* PreMeEmitter::EmitPreMeStmt(MeStmt *mestmt, BaseNode *parent) { return callnode; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { IcallMeStmt *icallMeStmt = static_cast (mestmt); IcallNode *icallnode = - codeMP->New(*codeMPAlloc, OP_icallassigned, icallMeStmt->GetRetTyIdx()); + codeMP->New(*codeMPAlloc, OP_icallprotoassigned, icallMeStmt->GetRetTyIdx()); for (uint32 i = 0; i < icallMeStmt->GetOpnds().size(); i++) { icallnode->GetNopnd().push_back(EmitPreMeExpr(icallMeStmt->GetOpnd(i), icallnode)); } @@ -509,6 +511,9 @@ StmtNode* PreMeEmitter::EmitPreMeStmt(MeStmt *mestmt, BaseNode *parent) { icallnode->SetRetTyIdx(TyIdx(preg->GetPrimType())); } } + if (mestmt->GetOp() == OP_icallproto || mestmt->GetOp() == OP_icallprotoassigned) { + icallnode->SetRetTyIdx(icallMeStmt->GetRetTyIdx()); + } icallnode->CopySafeRegionAttr(mestmt->GetStmtAttr()); icallnode->SetOriginalID(mestmt->GetOriginalId()); PreMeStmtExtensionMap[icallnode->GetStmtID()] = pmeExt; diff --git a/src/mapleall/maple_me/src/ssa_devirtual.cpp b/src/mapleall/maple_me/src/ssa_devirtual.cpp index 15a609e427..f46e8e06ce 100644 --- a/src/mapleall/maple_me/src/ssa_devirtual.cpp +++ b/src/mapleall/maple_me/src/ssa_devirtual.cpp @@ -534,7 +534,9 @@ void SSADevirtual::TraversalMeStmt(MeStmt &meStmt) { break; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { auto *icallMeStmt = static_cast(&meStmt); const MapleVector &opnds = icallMeStmt->GetOpnds(); for (size_t i = 0; i < opnds.size(); ++i) { diff --git a/src/mapleall/maple_me/src/ssa_pre.cpp b/src/mapleall/maple_me/src/ssa_pre.cpp index ceff080daa..a082b80b9f 100644 --- a/src/mapleall/maple_me/src/ssa_pre.cpp +++ b/src/mapleall/maple_me/src/ssa_pre.cpp @@ -1666,6 +1666,7 @@ void SSAPre::BuildWorkListStmt(MeStmt &stmt, uint32 seqStmt, bool isRebuilt, MeE case OP_customcall: case OP_polymorphiccall: case OP_icall: + case OP_icallproto: case OP_callassigned: case OP_virtualcallassigned: case OP_virtualicallassigned: @@ -1675,6 +1676,7 @@ void SSAPre::BuildWorkListStmt(MeStmt &stmt, uint32 seqStmt, bool isRebuilt, MeE case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_asm: { auto *naryMeStmt = static_cast(meStmt); const MapleVector &opnds = naryMeStmt->GetOpnds(); diff --git a/src/mapleall/mpl2mpl/src/constantfold.cpp b/src/mapleall/mpl2mpl/src/constantfold.cpp index f84c351bd8..1b296c1de7 100644 --- a/src/mapleall/mpl2mpl/src/constantfold.cpp +++ b/src/mapleall/mpl2mpl/src/constantfold.cpp @@ -162,6 +162,8 @@ StmtNode *ConstantFold::Simplify(StmtNode *node) { return SimplifyNary(static_cast(node)); case OP_icall: case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: return SimplifyIcall(static_cast(node)); case OP_asm: return SimplifyAsm(static_cast(node)); @@ -2628,8 +2630,8 @@ StmtNode *ConstantFold::SimplifyIcall(IcallNode *node) { AddroffuncNode *addrofNode = static_cast(node->GetNopndAt(0)); CallNode *callNode = mirModule->CurFuncCodeMemPool()->New(*mirModule, - node->GetOpCode() == OP_icall ? OP_call : OP_callassigned); - if (node->GetOpCode() == OP_icallassigned) { + (node->GetOpCode() == OP_icall || node->GetOpCode() == OP_icallproto) ? OP_call : OP_callassigned); + if (node->GetOpCode() == OP_icallassigned || node->GetOpCode() == OP_icallprotoassigned) { callNode->SetReturnVec(node->GetReturnVec()); } callNode->SetPUIdx(addrofNode->GetPUIdx()); -- Gitee From 69e5f7d1b9665ad05d32b39f948d9898d3b2bef7 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:44 -0700 Subject: [PATCH 058/124] Fred's Fixed determination logic of when there is fake parameter for returning struct, where x8 is also used to pass the fake parameter --- .../maple_be/src/cg/aarch64/aarch64_args.cpp | 4 ++-- .../src/cg/aarch64/aarch64_call_conv.cpp | 11 ++++++----- .../maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 18 ++++++++++++------ .../src/cg/aarch64/aarch64_memlayout.cpp | 4 ++-- 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index ea2b40db14..f5e0c6e394 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -38,7 +38,7 @@ void AArch64MoveRegArgs::CollectRegisterArgs(std::map &argsL uint32 start = 0; if (numFormal) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsFirstArgReturn()) { + if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16ByteSize) { start = 1; @@ -439,7 +439,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsFirstArgReturn()) { + if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp index b89e1b4c40..bc9e1cb471 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp @@ -306,18 +306,18 @@ int32 AArch64CallConvImpl::LocateNextParm(MIRType &mirType, CCLocInfo &pLoc, boo if (size == 0) { /* For return struct size 0 there is no return value. */ return 0; - } else if (size > k16ByteSize) { - /* For return struct size > 16 bytes the pointer returns in x8. */ - pLoc.reg0 = R8; - return kSizeOfPtr; } + /* For return struct size > 16 bytes the pointer returns in x8. */ + pLoc.reg0 = R8; + return kSizeOfPtr; +#if 0 /* For return struct size less or equal to 16 bytes, the values * are returned in register pairs. * Check for pure float struct. */ AArch64ArgumentClass classes[kMaxRegCount] = { kAArch64NoClass }; uint32 fpSize; - MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(beCommon.GetFuncReturnType(*func)); + MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); uint32 numRegs = static_cast(ClassifyAggregate(beCommon, *retType, classes, sizeof(classes), fpSize)); if (classes[0] == kAArch64FloatClass) { CHECK_FATAL(numRegs <= kMaxRegCount, "LocateNextParm: illegal number of regs"); @@ -334,6 +334,7 @@ int32 AArch64CallConvImpl::LocateNextParm(MIRType &mirType, CCLocInfo &pLoc, boo } return 0; } +#endif } } uint64 typeSize = beCommon.GetTypeSize(mirType.GetTypeIndex()); 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 d5e3e9f531..250cf47d4f 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8062,6 +8062,17 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo std::set specialArgs; SelectParmListPreprocess(naryNode, i, specialArgs); bool specialArg = false; + bool firstArgReturn = false; + MIRFunction *callee = nullptr; + if (dynamic_cast(&naryNode) != nullptr) { + auto calleePuIdx = static_cast(naryNode).GetPUIdx(); + callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + firstArgReturn = callee->IsFirstArgReturn(); + } else if (naryNode.GetOpCode() == OP_icallproto) { + IcallNode *icallnode = &static_cast(naryNode); + MIRFuncType *funcType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallnode->GetRetTyIdx())); + firstArgReturn = funcType->FirstArgReturn(); + } BB *curBBrecord = GetCurBB(); BB *tmpBB = nullptr; if (!specialArgs.empty()) { @@ -8083,11 +8094,6 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); - MIRFunction *callee = nullptr; - if (dynamic_cast(&naryNode) != nullptr) { - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); - } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } @@ -8152,7 +8158,7 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo } expRegOpnd = static_cast(opnd); - if ((pnum == 0) && (SelectParmListGetStructReturnSize(naryNode) > k16ByteSize)) { + if ((pnum == 0) && firstArgReturn) { parmLocator.InitCCLocInfo(ploc); ploc.reg0 = R8; } else { diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp index 4184108a22..5a839e9af4 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp @@ -210,7 +210,7 @@ void AArch64MemLayout::LayoutFormalParams() { AArch64SymbolAlloc *symLoc = memAllocator->GetMemPool()->New(); SetSymAllocInfo(stIndex, *symLoc); if (i == 0) { - if (mirFunction->IsFirstArgReturn()) { + if (mirFunction->IsReturnStruct() && mirFunction->IsFirstArgReturn()) { symLoc->SetMemSegment(GetSegArgsRegPassed()); symLoc->SetOffset(GetSegArgsRegPassed().GetSize()); TyIdx tyIdx = mirFunction->GetFuncRetStructTyIdx(); @@ -395,7 +395,7 @@ void AArch64MemLayout::LayoutReturnRef(std::vector &returnDelays, void AArch64MemLayout::LayoutActualParams() { for (size_t i = 0; i < mirFunction->GetFormalCount(); ++i) { if (i == 0) { - if (mirFunction->IsReturnStruct()) { + if (mirFunction->IsReturnStruct() && mirFunction->IsFirstArgReturn()) { continue; } } -- Gitee From 1b55c64146de28c518ec00982d369271128bcea7 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:53:00 -0700 Subject: [PATCH 059/124] Remove unneeded fp def. Turn on tailcall. no unneeded pro/epilog. --- .../maple_be/include/cg/aarch64/aarch64_color_ra.h | 1 + src/mapleall/maple_be/include/cg/cgfunc.h | 9 +++++++++ .../maple_be/src/cg/aarch64/aarch64_color_ra.cpp | 6 ++++++ .../maple_be/src/cg/aarch64/aarch64_proepilog.cpp | 7 +++---- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h index a3df9f6bf3..651cd91674 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h @@ -1519,6 +1519,7 @@ class GraphColorRegAllocator : public RegAllocator { #endif bool hasSpill = false; bool doMultiPass = false; + bool seenFP = false; }; class CallerSavePre: public CGPre { diff --git a/src/mapleall/maple_be/include/cg/cgfunc.h b/src/mapleall/maple_be/include/cg/cgfunc.h index 0695a784de..a664565276 100644 --- a/src/mapleall/maple_be/include/cg/cgfunc.h +++ b/src/mapleall/maple_be/include/cg/cgfunc.h @@ -1107,6 +1107,14 @@ class CGFunc { return useFP; } + void UnsetSeenFP() { + seenFP = false; + } + + bool SeenFP() const { + return seenFP; + } + void UpdateAllRegisterVregMapping(MapleMap &newMap); void RegisterVregMapping(regno_t vRegNum, PregIdx pidx) { @@ -1276,6 +1284,7 @@ class CGFunc { const MapleString shortFuncName; bool hasAsm = false; bool useFP = true; + bool seenFP = true; /* save stack protect kinds which can trigger stack protect */ uint8 stackProtectInfo = 0; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp index 75a5d0fab5..b77161f548 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp @@ -3609,6 +3609,9 @@ RegOperand *GraphColorRegAllocator::GetReplaceOpnd(Insn &insn, const Operand &op auto ®Opnd = static_cast(opnd); uint32 vregNO = regOpnd.GetRegisterNumber(); + if (vregNO == RFP) { + seenFP = true; + } RegType regType = regOpnd.GetRegisterType(); if (vregNO < kAllRegNum) { return nullptr; @@ -4976,6 +4979,9 @@ bool GraphColorRegAllocator::AllocateRegisters() { MarkCalleeSaveRegs(); + if (seenFP == false) { + cgFunc->UnsetSeenFP(); + } if (GCRA_DUMP) { cgFunc->DumpCGIR(); } diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp index 30b0dcf206..e447eb9d7b 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp @@ -185,9 +185,6 @@ void AArch64GenProEpilog::TailCallBBOpt(BB &bb, MapleSet &callInsns, BB & * Return value: true if function do not need Prologue/Epilogue. false otherwise. */ bool AArch64GenProEpilog::TailCallOpt() { - if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { - return false; - } /* Count how many call insns in the whole function. */ uint32 nCount = 0; bool hasGetStackClass = false; @@ -1229,7 +1226,9 @@ void AArch64GenProEpilog::GeneratePushRegs() { } else { immOpnd = &aarchCGFunc.CreateImmOperand(argsToStkPassSize, k32BitSize, true); } - aarchCGFunc.SelectAdd(fpOpnd, spOpnd, *immOpnd, PTY_u64); + if (isLmbc == false || cgFunc.SeenFP() || cgFunc.GetFunction().GetAttr(FUNCATTR_varargs)) { + aarchCGFunc.SelectAdd(fpOpnd, spOpnd, *immOpnd, PTY_u64); + } cgFunc.GetCurBB()->GetLastInsn()->SetFrameDef(true); if (cgFunc.GenCfi()) { cgFunc.GetCurBB()->AppendInsn(aarchCGFunc.CreateCfiDefCfaInsn(stackBaseReg, -- Gitee From 9af3173e06872187ea999966ef6e5d341d8c9729 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:53:14 -0700 Subject: [PATCH 060/124] Fred's Set firstarg_return attribute in the new funcAttrs field in MIRFuncType --- src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp | 3 +++ src/mapleall/maple_ir/src/mir_lower.cpp | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp b/src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp index 67b9df418d..f26d6c8da7 100644 --- a/src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp +++ b/src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp @@ -281,6 +281,9 @@ bool ASTFunc2FEHelper::ProcessDeclImpl(MapleAllocator &allocator) { ENCChecker::InsertBoundaryInAtts(attrs, func.GetBoundaryInfo()); mirMethodPair.second.second = attrs; mirFunc->SetFuncAttrs(attrs); + if (firstArgRet) { + mirFunc->GetMIRFuncType()->funcAttrs.SetAttr(FUNCATTR_firstarg_return); + } func.ClearGenericAttrsContentMap(); return true; } diff --git a/src/mapleall/maple_ir/src/mir_lower.cpp b/src/mapleall/maple_ir/src/mir_lower.cpp index 8ea87d7d5f..53413ee084 100644 --- a/src/mapleall/maple_ir/src/mir_lower.cpp +++ b/src/mapleall/maple_ir/src/mir_lower.cpp @@ -553,6 +553,10 @@ BlockNode *MIRLower::LowerBlock(BlockNode &block) { MIRFuncType *funcType = FuncTypeFromFuncPtrExpr(stmt->Opnd(0)); CHECK_FATAL(funcType != nullptr, "MIRLower::LowerBlock: cannot find prototype for icall"); ic->SetRetTyIdx(funcType->GetTypeIndex()); + MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcType->GetRetTyIdx()); + if (retType->GetPrimType() == PTY_agg && retType->GetSize() > 16) { + funcType->funcAttrs.SetAttr(FUNCATTR_firstarg_return); + } } newBlock->AddStatement(stmt); break; -- Gitee From d8b6c0766691ab5056bf7ae0b50034297385d6bb Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 061/124] Changes from mplcglmbc8 and mplcglmbc9. --- src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp | 1 - src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index f5e0c6e394..2bdc968dd9 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -439,7 +439,6 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; 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 250cf47d4f..35926e2121 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8094,6 +8094,11 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); + MIRFunction *callee = nullptr; + if (dynamic_cast(&naryNode) != nullptr) { + auto calleePuIdx = static_cast(naryNode).GetPUIdx(); + callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } -- Gitee From 151d7450ce7d184e98ed745d9f859b0b00944f35 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:44 -0700 Subject: [PATCH 062/124] Fred's Fixed determination logic of when there is fake parameter for returning struct, where x8 is also used to pass the fake parameter --- src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp | 1 + src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 5 ----- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 2bdc968dd9..f5e0c6e394 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -439,6 +439,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); + if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; 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 35926e2121..250cf47d4f 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8094,11 +8094,6 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); - MIRFunction *callee = nullptr; - if (dynamic_cast(&naryNode) != nullptr) { - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); - } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } -- Gitee From 949bfa6ad2e8cd70bbf5df95f57467a6c663abaa Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 15 Jun 2022 16:18:04 -0700 Subject: [PATCH 063/124] Fix accessing localrefvar in memlayout by qualifying with language --- src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h | 2 +- src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 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 53478d0f99..3820897107 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -129,7 +129,7 @@ class AArch64CGFunc : public CGFunc { uint32 LmbcFindTotalStkUsed(std::vector* paramList); uint32 LmbcTotalRegsUsed(); void LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn); - bool LmbcSmallAggForRet(BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *src); bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp index 5a839e9af4..e7d4432330 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp @@ -230,7 +230,7 @@ void AArch64MemLayout::LayoutFormalParams() { if (ploc.reg0 != kRinvalid) { /* register */ symLoc->SetRegisters(static_cast(ploc.reg0), static_cast(ploc.reg1), static_cast(ploc.reg2), static_cast(ploc.reg3)); - if (mirFunction->GetFormalDefVec()[i].formalAttrs.GetAttr(ATTR_localrefvar)) { + if (!cgFunc->GetMirModule().IsCModule() && mirFunction->GetNthParamAttr(i).GetAttr(ATTR_localrefvar)) { symLoc->SetMemSegment(segRefLocals); SetSegmentSize(*symLoc, segRefLocals, ptyIdx); } else if (!sym->IsPreg()) { @@ -272,7 +272,7 @@ void AArch64MemLayout::LayoutFormalParams() { } else { segArgsStkPassed.SetSize(static_cast(RoundUp(segArgsStkPassed.GetSize(), kSizeOfPtr))); } - if (mirFunction->GetFormalDefVec()[i].formalAttrs.GetAttr(ATTR_localrefvar)) { + if (!cgFunc->GetMirModule().IsCModule() && mirFunction->GetNthParamAttr(i).GetAttr(ATTR_localrefvar)) { SetLocalRegLocInfo(sym->GetStIdx(), *symLoc); AArch64SymbolAlloc *symLoc1 = memAllocator->GetMemPool()->New(); symLoc1->SetMemSegment(segRefLocals); -- Gitee From fa9405504608a708c2f0e1a51a94e2d32012db9c Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Thu, 16 Jun 2022 10:44:59 -0700 Subject: [PATCH 064/124] Set appearsInCode and puidxOrigin fields in newly cloned functions --- src/mapleall/maple_ipa/src/ipa_clone.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mapleall/maple_ipa/src/ipa_clone.cpp b/src/mapleall/maple_ipa/src/ipa_clone.cpp index 7a9b63a0d6..24843a39bd 100644 --- a/src/mapleall/maple_ipa/src/ipa_clone.cpp +++ b/src/mapleall/maple_ipa/src/ipa_clone.cpp @@ -107,6 +107,8 @@ MIRFunction *IpaClone::IpaCloneFunction(MIRFunction &originalFunction, const std newFunc->SetSrcPosition(originalFunction.GetSrcPosition()); newFunc->SetFuncAttrs(originalFunction.GetFuncAttrs()); newFunc->SetBaseClassFuncNames(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fullName)); + newFunc->GetFuncSymbol()->SetAppearsInCode(true); + newFunc->SetPuidxOrigin(newFunc->GetPuidx()); if (originalFunction.GetBody() != nullptr) { CopyFuncInfo(originalFunction, *newFunc); newFunc->SetBody( @@ -135,6 +137,8 @@ MIRFunction *IpaClone::IpaCloneFunctionWithFreq(MIRFunction &originalFunction, newFunc->SetSrcPosition(originalFunction.GetSrcPosition()); newFunc->SetFuncAttrs(originalFunction.GetFuncAttrs()); newFunc->SetBaseClassFuncNames(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fullName)); + newFunc->GetFuncSymbol()->SetAppearsInCode(true); + newFunc->SetPuidxOrigin(newFunc->GetPuidx()); GcovFuncInfo *origProfData = originalFunction.GetFuncProfData(); auto *moduleMp = mirBuilder.GetMirModule().GetMemPool(); GcovFuncInfo *newProfData = moduleMp->New(&mirBuilder.GetMirModule().GetMPAllocator(), -- Gitee From 0eca956561420a43fcd4b91455fce7237fef8cfc Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 065/124] Changes from mplcglmbc8 and mplcglmbc9. --- src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h | 2 +- src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 2 +- 2 files changed, 2 insertions(+), 2 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 3820897107..53478d0f99 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -129,7 +129,7 @@ class AArch64CGFunc : public CGFunc { uint32 LmbcFindTotalStkUsed(std::vector* paramList); uint32 LmbcTotalRegsUsed(); void LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn); - bool LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForRet(BlkassignoffNode &bNode, Operand *src); bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; 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 250cf47d4f..a8f686e243 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -2271,7 +2271,7 @@ void AArch64CGFunc::SelectBlkassignoff(BlkassignoffNode &bNode, Operand *src) opndVec.push_back(regResult); /* result */ opndVec.push_back(PrepareMemcpyParamOpnd(offset, *dest)); /* param 0 */ opndVec.push_back(src); /* param 1 */ - opndVec.push_back(PrepareMemcpyParamOpnd(static_cast(static_cast(bNode.blockSize)))); /* param 2 */ + opndVec.push_back(PrepareMemcpyParamOpnd(bNode.blockSize));/* param 2 */ SelectLibCall("memcpy", opndVec, PTY_a64, PTY_a64); } -- Gitee From 9d05a265b6daf80b90983de2310be0b86495bf0b Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 15 Jun 2022 16:18:04 -0700 Subject: [PATCH 066/124] Fix accessing localrefvar in memlayout by qualifying with language --- src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 53478d0f99..3820897107 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -129,7 +129,7 @@ class AArch64CGFunc : public CGFunc { uint32 LmbcFindTotalStkUsed(std::vector* paramList); uint32 LmbcTotalRegsUsed(); void LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn); - bool LmbcSmallAggForRet(BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *src); bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; -- Gitee From b5537817d584863d6d7135e83a918d14b4d6d74b Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Fri, 17 Jun 2022 00:40:20 -0700 Subject: [PATCH 067/124] Fixed a couple of bugs in the last rebase --- .../maple_be/include/cg/aarch64/aarch64_cgfunc.h | 16 ---------------- .../maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 2 +- 2 files changed, 1 insertion(+), 17 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 3820897107..550f31f130 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -738,22 +738,6 @@ class AArch64CGFunc : public CGFunc { RegOperand &GetZeroOpnd(uint32 size) override; - int32 GetLmbcTotalStkUsed() { - return lmbcArgInfo->lmbcTotalStkUsed; - } - - void SetLmbcTotalStkUsed(int32 offset) { - lmbcArgInfo->lmbcTotalStkUsed = offset; - } - - void SetLmbcCallReturnType(MIRType *ty) { - lmbcCallReturnType = ty; - } - - MIRType *GetLmbcCallReturnType() { - return lmbcCallReturnType; - } - private: enum RelationOperator : uint8 { kAND, 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 a8f686e243..93e583a085 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -893,7 +893,7 @@ MemOperand &AArch64CGFunc::ConstraintOffsetToSafeRegion(uint32 bitLen, const Mem } int32 offsetValue = static_cast(memOpnd.GetOffsetImmediate()->GetOffsetValue()); int32 multiplier = (offsetValue / k512BitSize) + static_cast(offsetValue % k512BitSize > k256BitSize); - int32 addMount = multiplier * k512BitSizeInt; + int32 addMount = multiplier * k512BitSize; int32 newOffset = offsetValue - addMount; RegOperand *baseReg = memOpnd.GetBaseRegister(); ImmOperand &immAddMount = CreateImmOperand(addMount, k64BitSize, true); -- Gitee From a2d0ad07044d45b73f2df83dbe17798c474d0c85 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Fri, 17 Jun 2022 21:32:32 -0700 Subject: [PATCH 068/124] Fixed bug in importing typeAttrs field of MIRStructType Also, handle the export and import of MIRAddrofConst of local symbols properly. --- src/mapleall/maple_ir/include/bin_mpl_export.h | 2 ++ src/mapleall/maple_ir/src/bin_mpl_export.cpp | 2 +- src/mapleall/maple_ir/src/bin_mpl_import.cpp | 8 ++++---- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/mapleall/maple_ir/include/bin_mpl_export.h b/src/mapleall/maple_ir/include/bin_mpl_export.h index f12bec7081..0d3d6d6457 100644 --- a/src/mapleall/maple_ir/include/bin_mpl_export.h +++ b/src/mapleall/maple_ir/include/bin_mpl_export.h @@ -180,7 +180,9 @@ class BinaryMplExport { void ExpandFourBuffSize(); MIRModule &mod; + public: MIRFunction *curFunc = nullptr; + private: size_t bufI = 0; std::vector buf; std::unordered_map gStrMark; diff --git a/src/mapleall/maple_ir/src/bin_mpl_export.cpp b/src/mapleall/maple_ir/src/bin_mpl_export.cpp index d406b89cdd..b28891b8ef 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_export.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_export.cpp @@ -45,7 +45,7 @@ void OutputConstAddrof(const MIRConst &constVal, BinaryMplExport &mplExport) { if (addrof.GetSymbolIndex().IsGlobal()) { mplExport.OutputSymbol(mplExport.GetMIRModule().CurFunction()->GetLocalOrGlobalSymbol(addrof.GetSymbolIndex())); } else { - mplExport.WriteNum(addrof.GetSymbolIndex().FullIdx()); + mplExport.OutputLocalSymbol(mplExport.curFunc->GetLocalOrGlobalSymbol(addrof.GetSymbolIndex())); } mplExport.WriteNum(addrof.GetFieldID()); mplExport.WriteNum(addrof.GetOffset()); diff --git a/src/mapleall/maple_ir/src/bin_mpl_import.cpp b/src/mapleall/maple_ir/src/bin_mpl_import.cpp index 375c84ca02..fe3eb9af27 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_import.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_import.cpp @@ -122,10 +122,10 @@ MIRConst *BinaryMplImport::ImportConst(MIRFunction *func) { return memPool->New(sym->GetStIdx(), fi, *exprTy, ofst); } case kBinKindConstAddrofLocal: { - uint32 fullidx = static_cast(ReadNum()); + MIRSymbol *sym = ImportLocalSymbol(func); FieldID fi = static_cast(ReadNum()); int32 ofst = static_cast(ReadNum()); - return memPool->New(StIdx(fullidx), fi, *type, ofst); + return memPool->New(sym->GetStIdx(), fi, *type, ofst); } case kBinKindConstAddrofFunc: { PUIdx puIdx = ImportFunction(); @@ -661,9 +661,9 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { auto kind = static_cast(ReadNum()); MIRStructType type(kind, strIdx); type.SetNameIsLocal(nameIsLocal); - auto &origType = static_cast(InsertInTypeTables(type)); - typTab.push_back(origType.GetTypeIndex()); type.SetTypeAttrs(ImportTypeAttrs()); + MIRStructType &origType = static_cast(InsertInTypeTables(type)); + typTab.push_back(origType.GetTypeIndex()); if (kind != kTypeStructIncomplete) { if (forPointedType) { typeNeedsComplete = &origType; -- Gitee From 39b30ccf65cc90f3c9647049a547306f63c975de Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Sun, 19 Jun 2022 22:40:51 -0700 Subject: [PATCH 069/124] Rebasing edits --- .../maple_be/include/cg/aarch64/aarch64_cgfunc.h | 15 +++++++++++++++ src/mapleall/maple_be/src/cg/cgfunc.cpp | 4 ++-- 2 files changed, 17 insertions(+), 2 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 550f31f130..3309ccd7b8 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -732,6 +732,21 @@ class AArch64CGFunc : public CGFunc { return lmbcArgInfo->lmbcCallArgNumOfRegs; } + int32 GetLmbcTotalStkUsed() { + return lmbcArgInfo->lmbcTotalStkUsed; + } + + void SetLmbcTotalStkUsed(int32 offset) { + lmbcArgInfo->lmbcTotalStkUsed = offset; + } + + void SetLmbcCallReturnType(MIRType *ty) { + lmbcCallReturnType = ty; + } + + MIRType *GetLmbcCallReturnType() { + return lmbcCallReturnType; + } bool IsSPOrFP(const RegOperand &opnd) const override; bool IsReturnReg(const RegOperand &opnd) const override; bool IsSaveReg(const RegOperand ®, MIRType &mirType, BECommon &cgBeCommon) const override; diff --git a/src/mapleall/maple_be/src/cg/cgfunc.cpp b/src/mapleall/maple_be/src/cg/cgfunc.cpp index b520229206..4dc19935a6 100644 --- a/src/mapleall/maple_be/src/cg/cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/cgfunc.cpp @@ -1587,7 +1587,7 @@ void CGFunc::CreateLmbcFormalParamInfo() { stackOffset += (typeSize + 7) & (-8); LmbcFormalParamInfo *info = GetMemoryPool()->New(primType, offset, typeSize); lmbcParamVec.push_back(info); - if (idx == 0 && mirFunc.IsFirstArgReturn()) { + if (idx == 0 && func.IsFirstArgReturn()) { info->SetIsReturn(); } if (type->GetKind() == kTypeStruct) { @@ -1604,7 +1604,7 @@ void CGFunc::CreateLmbcFormalParamInfo() { } } else { /* No aggregate pass by value here */ - for (StmtNode *stmt = mirFunc.GetBody()->GetFirst(); stmt != nullptr; stmt = stmt->GetNext()) { + for (StmtNode *stmt = func.GetBody()->GetFirst(); stmt != nullptr; stmt = stmt->GetNext()) { if (stmt == nullptr) { break; } -- Gitee From 264f858632b1a30278b8dda0deaae9aa568af5d5 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 070/124] Changes from mplcglmbc8 and mplcglmbc9. --- .../maple_be/include/cg/aarch64/aarch64_cgfunc.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) 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 3309ccd7b8..9ce531cc2a 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -753,6 +753,22 @@ class AArch64CGFunc : public CGFunc { RegOperand &GetZeroOpnd(uint32 size) override; + int32 GetLmbcTotalStkUsed() { + return lmbcArgInfo->lmbcTotalStkUsed; + } + + void SetLmbcTotalStkUsed(int32 offset) { + lmbcArgInfo->lmbcTotalStkUsed = offset; + } + + void SetLmbcCallReturnType(MIRType *ty) { + lmbcCallReturnType = ty; + } + + MIRType *GetLmbcCallReturnType() { + return lmbcCallReturnType; + } + private: enum RelationOperator : uint8 { kAND, -- Gitee From 29f837bdc455c17f23a41ccd773eb1980e05c0c6 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 071/124] Changes from mplcglmbc8 and mplcglmbc9. --- src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp | 1 - src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index f5e0c6e394..2bdc968dd9 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -439,7 +439,6 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; 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 93e583a085..0d31b10ea8 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8094,6 +8094,11 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); + MIRFunction *callee = nullptr; + if (dynamic_cast(&naryNode) != nullptr) { + auto calleePuIdx = static_cast(naryNode).GetPUIdx(); + callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } -- Gitee From 6b96f5fd69204202b4bfc47924b29dcf3eb97960 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:44 -0700 Subject: [PATCH 072/124] Fred's Fixed determination logic of when there is fake parameter for returning struct, where x8 is also used to pass the fake parameter --- src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp | 1 + src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 5 ----- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 2bdc968dd9..f5e0c6e394 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -439,6 +439,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); + if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; 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 0d31b10ea8..93e583a085 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8094,11 +8094,6 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); - MIRFunction *callee = nullptr; - if (dynamic_cast(&naryNode) != nullptr) { - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); - } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } -- Gitee From 327f818b01fd837732ae869b60423691aef07eca Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 073/124] Changes from mplcglmbc8 and mplcglmbc9. --- .../maple_be/include/cg/aarch64/aarch64_cgfunc.h | 16 ---------------- 1 file changed, 16 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 9ce531cc2a..3309ccd7b8 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -753,22 +753,6 @@ class AArch64CGFunc : public CGFunc { RegOperand &GetZeroOpnd(uint32 size) override; - int32 GetLmbcTotalStkUsed() { - return lmbcArgInfo->lmbcTotalStkUsed; - } - - void SetLmbcTotalStkUsed(int32 offset) { - lmbcArgInfo->lmbcTotalStkUsed = offset; - } - - void SetLmbcCallReturnType(MIRType *ty) { - lmbcCallReturnType = ty; - } - - MIRType *GetLmbcCallReturnType() { - return lmbcCallReturnType; - } - private: enum RelationOperator : uint8 { kAND, -- Gitee From 0fab5418c5bd0e3727ede1e7921599e5f533af14 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Mon, 20 Jun 2022 16:33:25 -0700 Subject: [PATCH 074/124] Set isFirst in calling LocateNextParm() so it knows to check for use of x8 to pass the first parameter --- src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp index 5ca154b1aa..b5788eb167 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp @@ -30,7 +30,7 @@ void AArch64ReachingDefinition::InitStartGen() { CCLocInfo pLoc; for (uint32 i = 0; i < cgFunc->GetFunction().GetFormalCount(); ++i) { MIRType *type = cgFunc->GetFunction().GetNthParamType(i); - parmLocator.LocateNextParm(*type, pLoc); + parmLocator.LocateNextParm(*type, pLoc, i == 0, &cgFunc->GetFunction()); if (pLoc.reg0 == 0) { /* If is a large frame, parameter addressing mode is based vreg:Vra. */ continue; -- Gitee From 916cb8c5135b37a02aaba7739fd24adfb5f2952c Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 075/124] Changes from mplcglmbc8 and mplcglmbc9. --- src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp | 1 - src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index f5e0c6e394..2bdc968dd9 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -439,7 +439,6 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; 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 93e583a085..0d31b10ea8 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8094,6 +8094,11 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); + MIRFunction *callee = nullptr; + if (dynamic_cast(&naryNode) != nullptr) { + auto calleePuIdx = static_cast(naryNode).GetPUIdx(); + callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } -- Gitee From c4b76ee6385f0eabfb81f99229553fcd71eb4f7a Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:44 -0700 Subject: [PATCH 076/124] Fred's Fixed determination logic of when there is fake parameter for returning struct, where x8 is also used to pass the fake parameter --- src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp | 1 + src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 5 ----- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 2bdc968dd9..f5e0c6e394 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -439,6 +439,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); + if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; 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 0d31b10ea8..93e583a085 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8094,11 +8094,6 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); - MIRFunction *callee = nullptr; - if (dynamic_cast(&naryNode) != nullptr) { - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); - } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } -- Gitee From 2f4a127ae8ab526f67a93b354cbf89ee67ff7960 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 077/124] Changes from mplcglmbc8 and mplcglmbc9. --- src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 3309ccd7b8..0781c72948 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -129,7 +129,7 @@ class AArch64CGFunc : public CGFunc { uint32 LmbcFindTotalStkUsed(std::vector* paramList); uint32 LmbcTotalRegsUsed(); void LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn); - bool LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForRet(BlkassignoffNode &bNode, Operand *src); bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; -- Gitee From ea32c7306a81148662b8230f515d70e57e8a7b35 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 15 Jun 2022 16:18:04 -0700 Subject: [PATCH 078/124] Fix accessing localrefvar in memlayout by qualifying with language --- src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 0781c72948..3309ccd7b8 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -129,7 +129,7 @@ class AArch64CGFunc : public CGFunc { uint32 LmbcFindTotalStkUsed(std::vector* paramList); uint32 LmbcTotalRegsUsed(); void LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn); - bool LmbcSmallAggForRet(BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *src); bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; -- Gitee From cf02e74699c6f5cbd718635e69abc64d468cf37f Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 079/124] Changes from mplcglmbc8 and mplcglmbc9. --- src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp | 1 - src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index f5e0c6e394..2bdc968dd9 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -439,7 +439,6 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; 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 93e583a085..0d31b10ea8 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8094,6 +8094,11 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); + MIRFunction *callee = nullptr; + if (dynamic_cast(&naryNode) != nullptr) { + auto calleePuIdx = static_cast(naryNode).GetPUIdx(); + callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } -- Gitee From bab5ca0bed5ab6c2fb7176cf626baced479a45cc Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:44 -0700 Subject: [PATCH 080/124] Fred's Fixed determination logic of when there is fake parameter for returning struct, where x8 is also used to pass the fake parameter --- src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp | 1 + src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 5 ----- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 2bdc968dd9..f5e0c6e394 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -439,6 +439,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); + if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; 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 0d31b10ea8..93e583a085 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8094,11 +8094,6 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); - MIRFunction *callee = nullptr; - if (dynamic_cast(&naryNode) != nullptr) { - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); - } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } -- Gitee From ef1dc5d5bc59536c36507ac239cdc140cde78f0b Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Tue, 21 Jun 2022 22:59:19 -0700 Subject: [PATCH 081/124] Fixed a bug in importing a global symbol inside a function which resulted in entering into the local symbol table --- src/mapleall/maple_ir/src/bin_func_import.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mapleall/maple_ir/src/bin_func_import.cpp b/src/mapleall/maple_ir/src/bin_func_import.cpp index 1903cc5f80..e54eea97ca 100644 --- a/src/mapleall/maple_ir/src/bin_func_import.cpp +++ b/src/mapleall/maple_ir/src/bin_func_import.cpp @@ -213,7 +213,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { sym = ImportLocalSymbol(func); CHECK_FATAL(sym != nullptr, "null ptr check"); } else { - sym = InSymbol(func); + sym = InSymbol(nullptr); CHECK_FATAL(sym != nullptr, "null ptr check"); if (op == OP_addrof) { sym->SetHasPotentialAssignment(); @@ -475,7 +475,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { sym = ImportLocalSymbol(func); CHECK_FATAL(sym != nullptr, "null ptr check"); } else { - sym = InSymbol(func); + sym = InSymbol(nullptr); CHECK_FATAL(sym != nullptr, "null ptr check"); sym->SetHasPotentialAssignment(); } -- Gitee From 2c48e499085e0eb214f5ad984de8fcdab3f66c84 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 082/124] Changes from mplcglmbc8 and mplcglmbc9. --- src/mapleall/maple_be/include/be/lower.h | 2 +- .../include/cg/aarch64/aarch64_cgfunc.h | 32 +- .../include/cg/aarch64/aarch64_phases.def | 2 +- src/mapleall/maple_be/include/cg/call_conv.h | 22 +- src/mapleall/maple_be/include/cg/cg.h | 19 +- src/mapleall/maple_be/include/cg/cgfunc.h | 2 + src/mapleall/maple_be/src/be/lower.cpp | 82 ++- .../maple_be/src/cg/aarch64/aarch64_args.cpp | 4 +- .../src/cg/aarch64/aarch64_call_conv.cpp | 2 +- .../src/cg/aarch64/aarch64_cgfunc.cpp | 549 +++++++++++++++--- .../maple_be/src/cg/aarch64/aarch64_ebo.cpp | 4 +- .../src/cg/aarch64/aarch64_memlayout.cpp | 34 +- .../src/cg/aarch64/aarch64_offset_adjust.cpp | 2 +- .../src/cg/aarch64/aarch64_proepilog.cpp | 87 ++- .../src/cg/aarch64/aarch64_reaching.cpp | 3 +- .../maple_be/src/cg/cg_phasemanager.cpp | 1 + src/mapleall/maple_be/src/cg/cgfunc.cpp | 48 +- src/mapleall/maple_be/src/cg/emit.cpp | 5 + src/mapleall/maple_be/src/cg/memlayout.cpp | 6 +- .../maple_ir/include/bin_mpl_export.h | 28 +- .../maple_ir/include/bin_mpl_import.h | 12 +- .../maple_ir/include/ir_safe_cast_traits.def | 4 +- src/mapleall/maple_ir/include/keywords.def | 1 - src/mapleall/maple_ir/include/mir_builder.h | 2 + src/mapleall/maple_ir/include/mir_function.h | 18 +- src/mapleall/maple_ir/include/mir_lower.h | 1 + src/mapleall/maple_ir/include/mir_nodes.h | 2 +- src/mapleall/maple_ir/include/mir_parser.h | 2 +- src/mapleall/maple_ir/include/mir_symbol.h | 6 +- src/mapleall/maple_ir/include/mir_type.h | 27 +- src/mapleall/maple_ir/include/opcode_info.h | 1 + src/mapleall/maple_ir/include/opcodes.def | 1 + src/mapleall/maple_ir/include/opcodes.h | 4 +- src/mapleall/maple_ir/src/bin_func_export.cpp | 239 ++++---- src/mapleall/maple_ir/src/bin_func_import.cpp | 248 ++++---- src/mapleall/maple_ir/src/bin_mpl_export.cpp | 112 ++-- src/mapleall/maple_ir/src/bin_mpl_import.cpp | 52 +- src/mapleall/maple_ir/src/global_tables.cpp | 4 +- src/mapleall/maple_ir/src/mir_builder.cpp | 24 + src/mapleall/maple_ir/src/mir_function.cpp | 4 +- src/mapleall/maple_ir/src/mir_lower.cpp | 107 ++++ src/mapleall/maple_ir/src/mir_nodes.cpp | 4 +- src/mapleall/maple_ir/src/mir_parser.cpp | 31 +- src/mapleall/maple_ir/src/mir_type.cpp | 8 +- src/mapleall/maple_ir/src/parser.cpp | 18 +- src/mapleall/maple_me/include/lmbc_lower.h | 3 - .../maple_me/include/lmbc_memlayout.h | 64 +- src/mapleall/maple_me/src/alias_class.cpp | 8 +- src/mapleall/maple_me/src/code_factoring.cpp | 4 +- .../src/demand_driven_alias_analysis.cpp | 4 +- src/mapleall/maple_me/src/irmap_build.cpp | 7 +- src/mapleall/maple_me/src/irmap_emit.cpp | 5 +- src/mapleall/maple_me/src/lfo_dep_test.cpp | 2 + src/mapleall/maple_me/src/lmbc_lower.cpp | 258 ++------ src/mapleall/maple_me/src/lmbc_memlayout.cpp | 439 +------------- src/mapleall/maple_me/src/me_cfg.cpp | 2 + src/mapleall/maple_me/src/me_function.cpp | 4 +- .../maple_me/src/me_lower_globals.cpp | 13 +- .../maple_me/src/me_phase_manager.cpp | 7 +- src/mapleall/maple_me/src/me_rc_lowering.cpp | 1 + src/mapleall/maple_me/src/me_rename2preg.cpp | 1 + src/mapleall/maple_me/src/me_side_effect.cpp | 4 +- src/mapleall/maple_me/src/me_stmt_pre.cpp | 4 +- src/mapleall/maple_me/src/pme_emit.cpp | 9 +- src/mapleall/maple_me/src/ssa_devirtual.cpp | 4 +- src/mapleall/maple_me/src/ssa_pre.cpp | 2 + src/mapleall/mpl2mpl/src/constantfold.cpp | 6 +- 67 files changed, 1411 insertions(+), 1306 deletions(-) diff --git a/src/mapleall/maple_be/include/be/lower.h b/src/mapleall/maple_be/include/be/lower.h index 2e1431aafb..f78f035d1d 100644 --- a/src/mapleall/maple_be/include/be/lower.h +++ b/src/mapleall/maple_be/include/be/lower.h @@ -188,7 +188,7 @@ class CGLowerer { void LowerTryCatchBlocks(BlockNode &body); #if TARGARM32 || TARGAARCH64 || TARGRISCV64 - BlockNode *LowerReturnStruct(NaryStmtNode &retNode); + BlockNode *LowerReturnStructUsingFakeParm(NaryStmtNode &retNode); #endif BlockNode *LowerReturn(NaryStmtNode &retNode); void LowerEntry(MIRFunction &func); 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 96bc53c720..53478d0f99 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -38,6 +38,7 @@ class LmbcArgInfo { MapleVector lmbcCallArgTypes; MapleVector lmbcCallArgOffsets; MapleVector lmbcCallArgNumOfRegs; // # of regs needed to complete struct + uint32 lmbcTotalStkUsed = -1; // TBD: remove when explicit addr for large agg is available }; class AArch64CGFunc : public CGFunc { @@ -101,7 +102,7 @@ class AArch64CGFunc : public CGFunc { return kRFLAG; } - MIRType *GetAggTyFromCallSite(StmtNode *stmt); + MIRType *LmbcGetAggTyFromCallSite(StmtNode *stmt, std::vector **parmList); RegOperand &GetOrCreateResOperand(const BaseNode &parent, PrimType primType); void IntrinsifyGetAndAddInt(ListOperand &srcOpnds, PrimType pty); @@ -125,9 +126,11 @@ class AArch64CGFunc : public CGFunc { bool needLow12 = false); MemOperand *FixLargeMemOpnd(MemOperand &memOpnd, uint32 align); MemOperand *FixLargeMemOpnd(MOperator mOp, MemOperand &memOpnd, uint32 dSize, uint32 opndIdx); + uint32 LmbcFindTotalStkUsed(std::vector* paramList); + uint32 LmbcTotalRegsUsed(); void LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn); - bool LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *src); - bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForRet(BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; void SelectIassignoff(IassignoffNode &stmt) override; @@ -135,6 +138,7 @@ class AArch64CGFunc : public CGFunc { void SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd) override; void SelectBlkassignoff(BlkassignoffNode &bNode, Operand *src) override; void SelectAggIassign(IassignNode &stmt, Operand &lhsAddrOpnd) override; + void SelectReturnSendOfStructInRegs(BaseNode *x) override; void SelectReturn(Operand *opnd0) override; void SelectIgoto(Operand *opnd0) override; void SelectCondGoto(CondGotoNode &stmt, Operand &opnd0, Operand &opnd1) override; @@ -486,7 +490,10 @@ class AArch64CGFunc : public CGFunc { void GenerateCleanupCodeForExtEpilog(BB &bb) override; uint32 FloatParamRegRequired(MIRStructType *structType, uint32 &fpSize) override; void AssignLmbcFormalParams() override; - RegOperand *GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType); + void LmbcGenSaveSpForAlloca() override; + MemOperand *GenLmbcFpMemOperand(int32 offset, uint32 byteSize, AArch64reg base = RFP); + RegOperand *GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType, AArch64reg baseRegno = RFP); + RegOperand *LmbcStructReturnLoad(int32 offset); Operand *GetBaseReg(const AArch64SymbolAlloc &symAlloc); int32 GetBaseOffset(const SymbolAlloc &symAlloc) override; @@ -731,6 +738,22 @@ class AArch64CGFunc : public CGFunc { RegOperand &GetZeroOpnd(uint32 size) override; + int32 GetLmbcTotalStkUsed() { + return lmbcArgInfo->lmbcTotalStkUsed; + } + + void SetLmbcTotalStkUsed(int32 offset) { + lmbcArgInfo->lmbcTotalStkUsed = offset; + } + + void SetLmbcCallReturnType(MIRType *ty) { + lmbcCallReturnType = ty; + } + + MIRType *GetLmbcCallReturnType() { + return lmbcCallReturnType; + } + private: enum RelationOperator : uint8 { kAND, @@ -798,6 +821,7 @@ class AArch64CGFunc : public CGFunc { regno_t methodHandleVreg = -1; uint32 alignPow = 5; /* function align pow defaults to 5 i.e. 2^5*/ LmbcArgInfo *lmbcArgInfo = nullptr; + MIRType *lmbcCallReturnType = nullptr; void SelectLoadAcquire(Operand &dest, PrimType dtype, Operand &src, PrimType stype, AArch64isa::MemoryOrdering memOrd, bool isDirect); diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def b/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def index a3a74d7b2f..ff08e81852 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def @@ -16,8 +16,8 @@ ADDTARGETPHASE("createstartendlabel", true); ADDTARGETPHASE("buildehfunc", true); ADDTARGETPHASE("handlefunction", true); + ADDTARGETPHASE("moveargs", true); if (GetMIRModule()->GetFlavor() != MIRFlavor::kFlavorLmbc) { - ADDTARGETPHASE("moveargs", true); /* SSA PHASES */ ADDTARGETPHASE("cgssaconstruct", CGOptions::DoCGSSA()); ADDTARGETPHASE("cgcopyprop", CGOptions::DoCGSSA()); diff --git a/src/mapleall/maple_be/include/cg/call_conv.h b/src/mapleall/maple_be/include/cg/call_conv.h index 9cfab98b56..4e33309c3c 100644 --- a/src/mapleall/maple_be/include/cg/call_conv.h +++ b/src/mapleall/maple_be/include/cg/call_conv.h @@ -63,8 +63,8 @@ struct CCLocInfo { class LmbcFormalParamInfo { public: LmbcFormalParamInfo(PrimType pType, uint32 ofst, uint32 sz) : - type(nullptr), primType(pType), offset(ofst), size(sz), regNO(0), vregNO(0), numRegs(0), - fpSize(0), isReturn(false), isPureFloat(false), isOnStack(false) {} + type(nullptr), primType(pType), offset(ofst), onStackOffset(0), size(sz), regNO(0), vregNO(0), numRegs(0), + fpSize(0), isReturn(false), isPureFloat(false), isOnStack(false), hasRegassign(false) {} ~LmbcFormalParamInfo() = default; @@ -86,7 +86,13 @@ class LmbcFormalParamInfo { void SetOffset(uint32 ofs) { offset = ofs; } - uint32 GetSize() const { + uint32 GetOnStackOffset() { + return onStackOffset; + } + void SetOnStackOffset(uint32 ofs) { + onStackOffset = ofs; + } + uint32 GetSize() { return size; } void SetSize(uint32 sz) { @@ -137,10 +143,17 @@ class LmbcFormalParamInfo { void SetIsOnStack() { isOnStack = true; } + bool HasRegassign() { + return hasRegassign; + } + void SetHasRegassign() { + hasRegassign = true; + } private: MIRStructType *type; PrimType primType; uint32 offset; + uint32 onStackOffset; /* stack location if isOnStack */ uint32 size; /* size primtype or struct */ regno_t regNO = 0; /* param reg num or starting reg num if numRegs > 0 */ regno_t vregNO = 0; /* if no explicit regassing from IR, create move from param reg */ @@ -148,7 +161,8 @@ class LmbcFormalParamInfo { uint32 fpSize = 0; /* size of fp param if isPureFloat */ bool isReturn; bool isPureFloat = false; - bool isOnStack; /* small struct with arrays need to be saved onto stack */ + bool isOnStack; /* large struct is passed by a copy on stack */ + bool hasRegassign; }; } /* namespace maplebe */ diff --git a/src/mapleall/maple_be/include/cg/cg.h b/src/mapleall/maple_be/include/cg/cg.h index 093289e42b..e1368acb1d 100644 --- a/src/mapleall/maple_be/include/cg/cg.h +++ b/src/mapleall/maple_be/include/cg/cg.h @@ -121,11 +121,13 @@ class CG { emitter(nullptr), labelOrderCnt(0), cgOption(cgOptions), - instrumentationFunction(nullptr) { + instrumentationFunction(nullptr), + fileGP(nullptr) { const std::string &internalNameLiteral = namemangler::GetInternalNameLiteral(namemangler::kJavaLangObjectStr); GStrIdx strIdxFromName = GlobalTables::GetStrTable().GetStrIdxFromName(internalNameLiteral); isLibcore = (GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdxFromName) != nullptr); DefineDebugTraceFunctions(); + isLmbc = (mirModule->GetFlavor() == MIRFlavor::kFlavorLmbc); } virtual ~CG(); @@ -361,6 +363,10 @@ class CG { return isLibcore; } + bool IsLmbc() const { + return isLmbc; + } + MIRSymbol *GetDebugTraceEnterFunction() { return dbgTraceEnter; } @@ -421,6 +427,13 @@ class CG { /* Object map generation helper */ std::vector GetReferenceOffsets64(const BECommon &beCommon, MIRStructType &structType); + void SetGP(MIRSymbol *sym) { + fileGP = sym; + } + MIRSymbol *GetGP() const { + return fileGP; + } + static bool IsInFuncWrapLabels(MIRFunction *func) { return funcWrapLabels.find(func) != funcWrapLabels.end(); } @@ -449,12 +462,14 @@ class CG { LabelIDOrder labelOrderCnt; static CGFunc *currentCGFunction; /* current cg function being compiled */ CGOptions cgOption; - bool isLibcore; MIRSymbol *instrumentationFunction; MIRSymbol *dbgTraceEnter; MIRSymbol *dbgTraceExit; MIRSymbol *dbgFuncProfile; + MIRSymbol *fileGP; /* for lmbc, one local %GP per file */ static std::map> funcWrapLabels; + bool isLibcore; + bool isLmbc; }; /* class CG */ } /* namespace maplebe */ diff --git a/src/mapleall/maple_be/include/cg/cgfunc.h b/src/mapleall/maple_be/include/cg/cgfunc.h index 9623c989e4..0695a784de 100644 --- a/src/mapleall/maple_be/include/cg/cgfunc.h +++ b/src/mapleall/maple_be/include/cg/cgfunc.h @@ -160,6 +160,7 @@ class CGFunc { virtual uint32 FloatParamRegRequired(MIRStructType *structType, uint32 &fpSize) = 0; virtual void AssignLmbcFormalParams() = 0; LmbcFormalParamInfo *GetLmbcFormalParamInfo(uint32 offset); + virtual void LmbcGenSaveSpForAlloca() = 0; void GenerateLoc(StmtNode *stmt, unsigned &lastSrcLoc, unsigned &lastMplLoc); int32 GetFreqFromStmt(uint32 stmtId); void GenerateInstruction(); @@ -201,6 +202,7 @@ class CGFunc { virtual void SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd) = 0; virtual void SelectBlkassignoff(BlkassignoffNode &bNode, Operand *src) = 0; virtual void SelectAggIassign(IassignNode &stmt, Operand &lhsAddrOpnd) = 0; + virtual void SelectReturnSendOfStructInRegs(BaseNode *x) = 0; virtual void SelectReturn(Operand *opnd) = 0; virtual void SelectIgoto(Operand *opnd0) = 0; virtual void SelectCondGoto(CondGotoNode &stmt, Operand &opnd0, Operand &opnd1) = 0; diff --git a/src/mapleall/maple_be/src/be/lower.cpp b/src/mapleall/maple_be/src/be/lower.cpp index 1e6f26e990..6f1bf6b01e 100644 --- a/src/mapleall/maple_be/src/be/lower.cpp +++ b/src/mapleall/maple_be/src/be/lower.cpp @@ -121,6 +121,7 @@ void CGLowerer::RegisterExternalLibraryFunctions() { func->AllocSymTab(); MIRSymbol *funcSym = func->GetFuncSymbol(); funcSym->SetStorageClass(kScExtern); + funcSym->SetAppearsInCode(true); /* return type */ MIRType *retTy = GlobalTables::GetTypeTable().GetPrimType(extFnDescrs[i].retType); @@ -875,7 +876,7 @@ void CGLowerer::LowerTypePtr(BaseNode &node) const { #if TARGARM32 || TARGAARCH64 || TARGRISCV64 -BlockNode *CGLowerer::LowerReturnStruct(NaryStmtNode &retNode) { +BlockNode *CGLowerer::LowerReturnStructUsingFakeParm(NaryStmtNode &retNode) { BlockNode *blk = mirModule.CurFuncCodeMemPool()->New(); for (size_t i = 0; i < retNode.GetNopndSize(); ++i) { retNode.SetOpnd(LowerExpr(retNode, *retNode.GetNopndAt(i), *blk), i); @@ -1100,7 +1101,7 @@ void CGLowerer::LowerCallStmt(StmtNode &stmt, StmtNode *&nextStmt, BlockNode &ne return; } - if ((newStmt->GetOpCode() == OP_call) || (newStmt->GetOpCode() == OP_icall)) { + if (newStmt->GetOpCode() == OP_call || newStmt->GetOpCode() == OP_icall || newStmt->GetOpCode() == OP_icallproto) { newStmt = LowerCall(static_cast(*newStmt), nextStmt, newBlk, retty, uselvar); } newStmt->SetSrcPos(stmt.GetSrcPos()); @@ -1169,7 +1170,12 @@ StmtNode *CGLowerer::GenIntrinsiccallNode(const StmtNode &stmt, PUIdx &funcCalle StmtNode *CGLowerer::GenIcallNode(PUIdx &funcCalled, IcallNode &origCall) { StmtNode *newCall = nullptr; - newCall = mirModule.GetMIRBuilder()->CreateStmtIcall(origCall.GetNopnd()); + if (origCall.GetOpCode() == OP_icallassigned) { + newCall = mirModule.GetMIRBuilder()->CreateStmtIcall(origCall.GetNopnd()); + } else { + newCall = mirModule.GetMIRBuilder()->CreateStmtIcallproto(origCall.GetNopnd()); + static_cast(newCall)->SetRetTyIdx(static_cast(origCall).GetRetTyIdx()); + } newCall->SetSrcPos(origCall.GetSrcPos()); CHECK_FATAL(newCall != nullptr, "nullptr is not expected"); funcCalled = kFuncNotFound; @@ -1371,6 +1377,7 @@ BlockNode *CGLowerer::LowerCallAssignedStmt(StmtNode &stmt, bool uselvar) { static_cast(newCall)->SetReturnVec(*p2nRets); break; } + case OP_icallprotoassigned: case OP_icallassigned: { auto &origCall = static_cast(stmt); newCall = GenIcallNode(funcCalled, origCall); @@ -1478,6 +1485,15 @@ bool CGLowerer::LowerStructReturn(BlockNode &newBlk, StmtNode *stmt, (*p2nrets)[0].first = dnodeStmt->GetStIdx(); (*p2nrets)[0].second.SetFieldID(dnodeStmt->GetFieldID()); lvar = true; + // set ATTR_firstarg_return for callee + if (stmt->GetOpCode() == OP_callassigned) { + CallNode *callNode = static_cast(stmt); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callNode->GetPUIdx()); + f->SetFirstArgReturn(); + f->GetMIRFuncType()->SetFirstArgReturn(); + } else { + // for icall, front-end already set ATTR_firstarg_return + } } else { /* struct <= 16 passed in regs lowered into call &foo regassign u64 %1 (regread u64 %%retval0) @@ -1495,13 +1511,19 @@ bool CGLowerer::LowerStructReturn(BlockNode &newBlk, StmtNode *stmt, CallNode *callStmt = mirModule.GetMIRBuilder()->CreateStmtCall(callNode->GetPUIdx(), callNode->GetNopnd()); callStmt->SetSrcPos(callNode->GetSrcPos()); newBlk.AddStatement(callStmt); - } else if (stmt->GetOpCode() == OP_icallassigned) { + } else if (stmt->GetOpCode() == OP_icallassigned || stmt->GetOpCode() == OP_icallprotoassigned) { auto *icallNode = static_cast(stmt); for (size_t i = 0; i < icallNode->GetNopndSize(); ++i) { BaseNode *newOpnd = LowerExpr(*icallNode, *icallNode->GetNopndAt(i), newBlk); icallNode->SetOpnd(newOpnd, i); } - IcallNode *icallStmt = mirModule.GetMIRBuilder()->CreateStmtIcall(icallNode->GetNopnd()); + IcallNode *icallStmt = nullptr; + if (stmt->GetOpCode() == OP_icallassigned) { + icallStmt = mirModule.GetMIRBuilder()->CreateStmtIcall(icallNode->GetNopnd()); + } else { + icallStmt = mirModule.GetMIRBuilder()->CreateStmtIcallproto(icallNode->GetNopnd()); + icallStmt->SetRetTyIdx(icallNode->GetRetTyIdx()); + } icallStmt->SetSrcPos(icallNode->GetSrcPos()); newBlk.AddStatement(icallStmt); } else { @@ -1767,6 +1789,7 @@ void CGLowerer::LowerAssertBoundary(StmtNode &stmt, BlockNode &block, BlockNode CondGotoNode *brFalseNode = mirBuilder->CreateStmtCondGoto(cond, OP_brfalse, labIdx); MIRFunction *printf = mirBuilder->GetOrCreateFunction("printf", TyIdx(PTY_i32)); + printf->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*printf->GetMIRFuncType()); MapleVector argsPrintf(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); uint32 oldTypeTableSize = GlobalTables::GetTypeTable().GetTypeTableSize(); @@ -1841,7 +1864,8 @@ BlockNode *CGLowerer::LowerBlock(BlockNode &block) { break; } case OP_callassigned: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallprotoassigned: { // pass the addr of lvar if this is a struct call assignment bool lvar = false; // nextStmt could be changed by the call to LowerStructReturn @@ -1861,6 +1885,7 @@ BlockNode *CGLowerer::LowerBlock(BlockNode &block) { case OP_intrinsiccall: case OP_call: case OP_icall: + case OP_icallproto: #if TARGARM32 || TARGAARCH64 || TARGRISCV64 || TARGX86_64 // nextStmt could be changed by the call to LowerStructReturn LowerCallStmt(*stmt, nextStmt, *newBlk); @@ -1870,8 +1895,8 @@ BlockNode *CGLowerer::LowerBlock(BlockNode &block) { break; case OP_return: { #if TARGARM32 || TARGAARCH64 || TARGRISCV64 - if (GetCurrentFunc()->IsReturnStruct()) { - newBlk->AppendStatementsFromBlock(*LowerReturnStruct(static_cast(*stmt))); + if (GetCurrentFunc()->IsFirstArgReturn() && stmt->NumOpnds() > 0) { + newBlk->AppendStatementsFromBlock(*LowerReturnStructUsingFakeParm(static_cast(*stmt))); } else { #endif NaryStmtNode *retNode = static_cast(stmt); @@ -1969,7 +1994,9 @@ void CGLowerer::SimplifyBlock(BlockNode &block) { } auto *newFunc = theMIRModule->GetMIRBuilder()->GetOrCreateFunction(asmMap.at(oldFunc->GetName()), callStmt->GetTyIdx()); - newFunc->GetFuncSymbol()->SetStorageClass(kScExtern); + MIRSymbol *funcSym = newFunc->GetFuncSymbol(); + funcSym->SetStorageClass(kScExtern); + funcSym->SetAppearsInCode(true); callStmt->SetPUIdx(newFunc->GetPuidx()); break; } @@ -2079,6 +2106,7 @@ StmtNode *CGLowerer::LowerCall( if (needCheckStore) { MIRFunction *fn = mirModule.GetMIRBuilder()->GetOrCreateFunction("MCC_Reflect_Check_Arraystore", TyIdx(PTY_void)); + fn->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); MapleVector args(mirModule.GetMIRBuilder()->GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -2105,7 +2133,7 @@ StmtNode *CGLowerer::LowerCall( } MIRType *retType = nullptr; - if (callNode.op == OP_icall) { + if (callNode.op == OP_icall || callNode.op == OP_icallproto) { if (retTy == nullptr) { return &callNode; } else { @@ -2151,7 +2179,7 @@ StmtNode *CGLowerer::LowerCall( addrofNode->SetStIdx(dsgnSt->GetStIdx()); addrofNode->SetFieldID(0); - if (callNode.op == OP_icall) { + if (callNode.op == OP_icall || callNode.op == OP_icallproto) { auto ond = callNode.GetNopnd().begin(); newNopnd.emplace_back(*ond); newNopnd.emplace_back(addrofNode); @@ -2173,7 +2201,27 @@ StmtNode *CGLowerer::LowerCall( } void CGLowerer::LowerEntry(MIRFunction &func) { + // determine if needed to insert fake parameter to return struct for current function if (func.IsReturnStruct()) { + MIRType *retType = func.GetReturnType(); +#if TARGAARCH64 + PrimType pty = IsStructElementSame(retType); + if (pty == PTY_f32 || pty == PTY_f64 || IsPrimitiveVector(pty)) { + func.SetStructReturnedInRegs(); + return; + } +#endif + if (retType->GetPrimType() != PTY_agg) { + return; + } + if (retType->GetSize() > k16ByteSize) { + func.SetFirstArgReturn(); + func.GetMIRFuncType()->SetFirstArgReturn(); + } else { + func.SetStructReturnedInRegs(); + } + } + if (func.IsFirstArgReturn() && func.GetReturnType()->GetPrimType() != PTY_void) { MIRSymbol *retSt = func.GetSymTab()->CreateSymbol(kScopeLocal); retSt->SetStorageClass(kScFormal); retSt->SetSKind(kStVar); @@ -2190,12 +2238,14 @@ void CGLowerer::LowerEntry(MIRFunction &func) { auto formal = func.GetFormal(i); formals.emplace_back(formal); } + func.SetFirstArgReturn(); beCommon.AddElementToFuncReturnType(func, func.GetReturnTyIdx()); func.UpdateFuncTypeAndFormalsAndReturnType(formals, TyIdx(PTY_void), true); auto *funcType = func.GetMIRFuncType(); ASSERT(funcType != nullptr, "null ptr check"); + funcType->SetFirstArgReturn(); beCommon.AddTypeSizeAndAlign(funcType->GetTypeIndex(), GetPrimTypeSize(funcType->GetPrimType())); } } @@ -2373,6 +2423,7 @@ MIRFunction *CGLowerer::RegisterFunctionVoidStarToVoid(BuiltinFunctionID id, con func->AllocSymTab(); MIRSymbol *funcSym = func->GetFuncSymbol(); funcSym->SetStorageClass(kScExtern); + funcSym->SetAppearsInCode(true); MIRType *argTy = GlobalTables::GetTypeTable().GetPtr(); MIRSymbol *argSt = func->GetSymTab()->CreateSymbol(kScopeLocal); argSt->SetNameStrIdx(mirBuilder->GetOrCreateStringIndex(paramName)); @@ -2414,6 +2465,7 @@ void CGLowerer::RegisterBuiltIns() { func->AllocSymTab(); MIRSymbol *funcSym = func->GetFuncSymbol(); funcSym->SetStorageClass(kScExtern); + funcSym->SetAppearsInCode(true); /* return type */ MIRType *retTy = desc.GetReturnType(); CHECK_FATAL(retTy != nullptr, "retTy should not be nullptr"); @@ -2569,6 +2621,7 @@ void CGLowerer::ProcessArrayExpr(BaseNode &expr, BlockNode &blkNode) { arrayNode.GetNopndAt(1), lenRegreadNode); CondGotoNode *brFalseNode = mirBuilder->CreateStmtCondGoto(cond, OP_brfalse, labIdx); MIRFunction *fn = mirBuilder->GetOrCreateFunction("MCC_Array_Boundary_Check", TyIdx(PTY_void)); + fn->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); MapleVector args(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -3100,6 +3153,7 @@ BaseNode *CGLowerer::LowerIntrinJavaArrayLength(const BaseNode &parent, Intrinsi MIRFunction *newFunc = mirBuilder->GetOrCreateFunction("MCC_ThrowNullArrayNullPointerException", GlobalTables::GetTypeTable().GetVoid()->GetTypeIndex()); + newFunc->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*newFunc->GetMIRFuncType()); newFunc->AllocSymTab(); MapleVector args(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -3471,6 +3525,7 @@ StmtNode *CGLowerer::LowerIntrinsicRCCall(const IntrinsiccallNode &intrincall) { if (intrinFuncIDs.find(intrinDesc) == intrinFuncIDs.end()) { /* add funcid into map */ MIRFunction *fn = mirBuilder->GetOrCreateFunction(intrinDesc->name, TyIdx(PTY_void)); + fn->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); intrinFuncIDs[intrinDesc] = fn->GetPuidx(); @@ -3499,6 +3554,7 @@ void CGLowerer::LowerArrayStore(const IntrinsiccallNode &intrincall, BlockNode & if (needCheckStore) { MIRFunction *fn = mirBuilder->GetOrCreateFunction("MCC_Reflect_Check_Arraystore", TyIdx(PTY_void)); + fn->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); MapleVector args(mirBuilder->GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -3588,6 +3644,7 @@ StmtNode *CGLowerer::LowerIntrinsiccall(IntrinsiccallNode &intrincall, BlockNode beCommon.UpdateTypeTable(*fn->GetMIRFuncType()); fn->AllocSymTab(); st->SetFunction(fn); + st->SetAppearsInCode(true); return LowerDefaultIntrinsicCall(intrincall, *st, *fn); } @@ -3658,6 +3715,7 @@ PUIdx CGLowerer::GetBuiltinToUse(BuiltinFunctionID id) const { void CGLowerer::LowerGCMalloc(const BaseNode &node, const GCMallocNode &gcmalloc, BlockNode &blkNode, bool perm) { MIRFunction *func = mirBuilder->GetOrCreateFunction((perm ? "MCC_NewPermanentObject" : "MCC_NewObj_fixed_class"), (TyIdx)(LOWERED_PTR_TYPE)); + func->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*func->GetMIRFuncType()); func->AllocSymTab(); /* Get the classinfo */ @@ -3676,6 +3734,7 @@ void CGLowerer::LowerGCMalloc(const BaseNode &node, const GCMallocNode &gcmalloc if (classSym->GetAttr(ATTR_abstract) || classSym->GetAttr(ATTR_interface)) { MIRFunction *funcSecond = mirBuilder->GetOrCreateFunction("MCC_Reflect_ThrowInstantiationError", (TyIdx)(LOWERED_PTR_TYPE)); + funcSecond->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*funcSecond->GetMIRFuncType()); funcSecond->AllocSymTab(); BaseNode *arg = mirBuilder->CreateExprAddrof(0, *classSym); @@ -3794,6 +3853,7 @@ void CGLowerer::LowerJarrayMalloc(const StmtNode &stmt, const JarrayMallocNode & args.emplace_back(mirBuilder->CreateIntConst(0, PTY_u32)); } MIRFunction *func = mirBuilder->GetOrCreateFunction(funcName, (TyIdx)(LOWERED_PTR_TYPE)); + func->GetFuncSymbol()->SetAppearsInCode(true); beCommon.UpdateTypeTable(*func->GetMIRFuncType()); func->AllocSymTab(); CallNode *callAssign = nullptr; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 6c396f213e..c03cb48970 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -38,7 +38,7 @@ void AArch64MoveRegArgs::CollectRegisterArgs(std::map &argsL uint32 start = 0; if (numFormal) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsReturnStruct()) { + if (func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16ByteSize) { start = 1; @@ -439,7 +439,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsReturnStruct()) { + if (func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp index 5b2ed3b682..77103c8549 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp @@ -300,7 +300,7 @@ int32 AArch64CallConvImpl::LocateNextParm(MIRType &mirType, CCLocInfo &pLoc, boo if (isFirst) { MIRFunction *func = tFunc != nullptr ? tFunc : const_cast(beCommon.GetMIRModule().CurFunction()); - if (func->IsReturnStruct()) { + if (func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); size_t size = beCommon.GetTypeSize(tyIdx); if (size == 0) { 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 46f0a2d610..34f7c7d46b 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -1411,15 +1411,44 @@ void AArch64CGFunc::SelectAsm(AsmNode &node) { } void AArch64CGFunc::SelectRegassign(RegassignNode &stmt, Operand &opnd0) { + if (GetCG()->IsLmbc()) { + PrimType lhsSize = stmt.GetPrimType(); + PrimType rhsSize = stmt.Opnd(0)->GetPrimType(); + if (lhsSize != rhsSize && stmt.Opnd(0)->GetOpCode() == OP_ireadoff) { + Insn *prev = GetCurBB()->GetLastInsn(); + if (prev->GetMachineOpcode() == MOP_wldrsb || prev->GetMachineOpcode() == MOP_wldrsh) { + opnd0.SetSize(GetPrimTypeBitSize(stmt.GetPrimType())); + prev->SetMOP(prev->GetMachineOpcode() == MOP_wldrsb ? MOP_xldrsb : MOP_xldrsh); + } else if (prev->GetMachineOpcode() == MOP_wldr && stmt.GetPrimType() == PTY_i64) { + opnd0.SetSize(GetPrimTypeBitSize(stmt.GetPrimType())); + prev->SetMOP(MOP_xldrsw); + } + } + } RegOperand *regOpnd = nullptr; PregIdx pregIdx = stmt.GetRegIdx(); if (IsSpecialPseudoRegister(pregIdx)) { - regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, stmt.GetPrimType()); + if (GetCG()->IsLmbc() && stmt.GetPrimType() == PTY_agg) { + if (static_cast(opnd0).IsOfIntClass()) { + regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, PTY_i64); + } else if (opnd0.GetSize() <= k4ByteSize) { + regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, PTY_f32); + } else { + regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, PTY_f64); + } + } else { + regOpnd = &GetOrCreateSpecialRegisterOperand(-pregIdx, stmt.GetPrimType()); + } } else { regOpnd = &GetOrCreateVirtualRegisterOperand(GetVirtualRegNOFromPseudoRegIdx(pregIdx)); } /* look at rhs */ PrimType rhsType = stmt.Opnd(0)->GetPrimType(); + if (GetCG()->IsLmbc() && rhsType == PTY_agg) { + /* This occurs when a call returns a small struct */ + /* The subtree should already taken care of the agg type that is in excess of 8 bytes */ + rhsType = PTY_i64; + } PrimType dtype = rhsType; if (GetPrimTypeBitSize(dtype) < k32BitSize) { ASSERT(IsPrimitiveInteger(dtype), ""); @@ -1441,6 +1470,12 @@ void AArch64CGFunc::SelectRegassign(RegassignNode &stmt, Operand &opnd0) { MIRPreg *preg = GetFunction().GetPregTab()->PregFromPregIdx(pregIdx); uint32 srcBitLength = GetPrimTypeSize(preg->GetPrimType()) * kBitsPerByte; GetCurBB()->AppendInsn(GetCG()->BuildInstruction(PickStInsn(srcBitLength, stype), *regOpnd, *dest)); + } else if (regOpnd->GetRegisterNumber() == R0 || regOpnd->GetRegisterNumber() == R1) { + Insn &pseudo = GetCG()->BuildInstruction(MOP_pseudo_ret_int, *regOpnd); + GetCurBB()->AppendInsn(pseudo); + } else if (regOpnd->GetRegisterNumber() >= V0 && regOpnd->GetRegisterNumber() <= V3) { + Insn &pseudo = GetCG()->BuildInstruction(MOP_pseudo_ret_float, *regOpnd); + GetCurBB()->AppendInsn(pseudo); } } @@ -1922,15 +1957,11 @@ void AArch64CGFunc::SelectIassignoff(IassignoffNode &stmt) { SelectCopy(memOpnd, destType, srcOpnd, destType); } -void AArch64CGFunc::SelectIassignfpoff(IassignFPoffNode &stmt, Operand &opnd) { - int32 offset = stmt.GetOffset(); - PrimType primType = stmt.GetPrimType(); - uint32 bitlen = GetPrimTypeSize(primType) * kBitsPerByte; - - Operand &srcOpnd = LoadIntoRegister(opnd, primType); +MemOperand *AArch64CGFunc::GenLmbcFpMemOperand(int32 offset, uint32 byteSize, AArch64reg baseRegno) { MemOperand *memOpnd; - RegOperand *rfp = &GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); - if (offset < 0) { + RegOperand *rfp = &GetOrCreatePhysicalRegisterOperand(baseRegno, k64BitSize, kRegTyInt); + uint32 bitlen = byteSize * kBitsPerByte; + if (offset < 0 && offset < -256) { RegOperand *baseOpnd = &CreateRegisterOperandOfType(PTY_a64); ImmOperand &immOpnd = CreateImmOperand(offset, k32BitSize, true); Insn &addInsn = GetCG()->BuildInstruction(MOP_xaddrri12, *baseOpnd, *rfp, immOpnd); @@ -1942,11 +1973,45 @@ void AArch64CGFunc::SelectIassignfpoff(IassignFPoffNode &stmt, Operand &opnd) { memOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, bitlen, rfp, nullptr, offsetOpnd, nullptr); } memOpnd->SetStackMem(true); - MOperator mOp = PickStInsn(bitlen, primType); - Insn &store = GetCG()->BuildInstruction(mOp, srcOpnd, *memOpnd); - GetCurBB()->AppendInsn(store); + return memOpnd; +} + +void AArch64CGFunc::SelectIassignfpoff(IassignFPoffNode &stmt, Operand &opnd) { + int32 offset = stmt.GetOffset(); + PrimType primType = stmt.GetPrimType(); + MIRType *rType = GetLmbcCallReturnType(); + bool isPureFpStruct = false; + uint32 numRegs = 0; + if (rType && rType->GetPrimType() == PTY_agg && opnd.IsRegister() && static_cast(opnd).IsPhysicalRegister()) { + CHECK_FATAL(rType->GetSize() <= 16, "SelectIassignfpoff invalid agg size"); + uint32 fpSize; + numRegs = FloatParamRegRequired(static_cast(rType), fpSize); + if (numRegs) { + primType = (fpSize == k4ByteSize) ? PTY_f32 : PTY_f64; + isPureFpStruct = true; + } + } + uint32 byteSize = GetPrimTypeSize(primType); + uint32 bitlen = byteSize * kBitsPerByte; + if (isPureFpStruct) { + for (int i = 0 ; i < numRegs; ++i) { + MemOperand *memOpnd = GenLmbcFpMemOperand(offset + (i * byteSize), byteSize); + RegOperand &srcOpnd = GetOrCreatePhysicalRegisterOperand(AArch64reg(V0 + i), bitlen, kRegTyFloat); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, srcOpnd, *memOpnd); + GetCurBB()->AppendInsn(store); + } + } else { + Operand &srcOpnd = LoadIntoRegister(opnd, primType); + MemOperand *memOpnd = GenLmbcFpMemOperand(offset, byteSize); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, srcOpnd, *memOpnd); + GetCurBB()->AppendInsn(store); + } } +/* Load and assign to a new register. To be moved to the correct call register OR stack + location in LmbcSelectParmList */ void AArch64CGFunc::SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd) { if (GetLmbcArgInfo() == nullptr) { LmbcArgInfo *p = memPool->New(*GetFuncScopeAllocator()); @@ -1973,8 +2038,8 @@ void AArch64CGFunc::SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd } /* Search for CALL/ICALL/ICALLPROTO node, must be called from a blkassignoff node */ -MIRType *AArch64CGFunc::GetAggTyFromCallSite(StmtNode *stmt) { - for (; stmt != nullptr; stmt = stmt->GetNext()) { +MIRType *AArch64CGFunc::LmbcGetAggTyFromCallSite(StmtNode *stmt, std::vector **parmList) { + for ( ; stmt != nullptr; stmt = stmt->GetNext()) { if (stmt->GetOpCode() == OP_call || stmt->GetOpCode() == OP_icallproto) { break; } @@ -1986,25 +2051,20 @@ MIRType *AArch64CGFunc::GetAggTyFromCallSite(StmtNode *stmt) { if (stmt->GetOpCode() == OP_call) { CallNode *callNode = static_cast(stmt); MIRFunction *fn = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callNode->GetPUIdx()); - if (fn->IsReturnStruct()) { - ++nargs; - } if (fn->GetFormalCount() > 0) { - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fn->GetNthParamTyIdx(nargs)); + ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fn->GetFormalDefVec()[nargs].formalTyIdx); } + *parmList = &fn->GetParamTypes(); // would return null if the actual parameter is bogus } else if (stmt->GetOpCode() == OP_icallproto) { IcallNode *icallproto = static_cast(stmt); MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallproto->GetRetTyIdx()); MIRFuncType *fType = static_cast(type); - MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fType->GetRetTyIdx()); - if (retType->GetKind() == kTypeStruct) { - ++nargs; - } ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fType->GetNthParamType(nargs)); + *parmList = &fType->GetParamTypeList(); } else { CHECK_FATAL(stmt->GetOpCode() == OP_icallproto, - "GetAggTyFromCallSite:: unexpected call operator"); + "LmbcGetAggTyFromCallSite:: unexpected call operator"); } return ty; } @@ -2080,11 +2140,11 @@ bool AArch64CGFunc::LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *s } /* return true if blkassignoff for return, false otherwise */ -bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src) { +bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList) { AArch64reg regno = static_cast(static_cast(src)->GetRegisterNumber()); if (IsBlkassignForPush(bNode)) { PrimType pTy = PTY_i64; - MIRStructType *ty = static_cast(GetAggTyFromCallSite(&bNode)); + MIRStructType *ty = static_cast(LmbcGetAggTyFromCallSite(&bNode, parmList)); uint32 size = 0; uint32 fpregs = ty ? FloatParamRegRequired(ty, size) : 0; /* fp size determined */ if (fpregs > 0) { @@ -2095,7 +2155,7 @@ bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src) { MemOperand &mem = CreateMemOpnd(regno, s, size * kBitsPerByte); RegOperand *res = &CreateVirtualRegisterOperand(NewVReg(kRegTyFloat, size)); SelectCopy(*res, pTy, mem, pTy); - SetLmbcArgInfo(res, pTy, bNode.offset + s, static_cast(fpregs)); + SetLmbcArgInfo(res, pTy, 0, fpregs); IncLmbcArgsInRegs(kRegTyFloat); } IncLmbcTotalArgs(); @@ -2136,6 +2196,41 @@ bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src) { return false; } +/* This function is incomplete and may be removed when Lmbc IR is changed + to have the lowerer figures out the address of the large agg to reside */ +uint32 AArch64CGFunc::LmbcFindTotalStkUsed(std::vector *paramList) { + AArch64CallConvImpl parmlocator(GetBecommon()); + CCLocInfo pLoc; + for (TyIdx tyIdx : *paramList) { + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); + parmlocator.LocateNextParm(*ty, pLoc); + } + return 0; +} + +/* All arguments passed as registers */ +uint32 AArch64CGFunc::LmbcTotalRegsUsed() { + if (GetLmbcArgInfo() == nullptr) { + return 0; /* no arg */ + } + MapleVector ®s = GetLmbcCallArgNumOfRegs(); + MapleVector &types = GetLmbcCallArgTypes(); + uint32 iCnt = 0; + uint32 fCnt = 0; + for (uint32 i = 0; i < regs.size(); i++) { + if (IsPrimitiveInteger(types[i])) { + if ((iCnt + regs[i]) <= k8ByteSize) { + iCnt += regs[i]; + }; + } else { + if ((fCnt + regs[i]) <= k8ByteSize) { + fCnt += regs[i]; + }; + } + } + return iCnt + fCnt; +} + /* If blkassignoff for argument, this function loads the agg arguments into virtual registers, disregard if there is sufficient physicall call registers. Argument > 16-bytes are copied to preset space and ptr @@ -2144,29 +2239,40 @@ bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src) { void AArch64CGFunc::SelectBlkassignoff(BlkassignoffNode &bNode, Operand *src) { CHECK_FATAL(src->GetKind() == Operand::kOpdRegister, "blkassign src type not in register"); + std::vector *parmList; if (GetLmbcArgInfo() == nullptr) { LmbcArgInfo *p = memPool->New(*GetFuncScopeAllocator()); SetLmbcArgInfo(p); } if (LmbcSmallAggForRet(bNode, src)) { return; - } else if (LmbcSmallAggForCall(bNode, src)) { + } else if (LmbcSmallAggForCall(bNode, src, &parmList)) { return; } - /* memcpy for agg assign OR large agg for arg/ret */ Operand *dest = HandleExpr(bNode, *bNode.Opnd(0)); RegOperand *regResult = &CreateVirtualRegisterOperand(NewVReg(kRegTyInt, k8ByteSize)); + /* memcpy for agg assign OR large agg for arg/ret */ + int32 offset = bNode.offset; + if (IsBlkassignForPush(bNode)) { + /* large agg for call, addr to be pushed in SelectCall */ + offset = GetLmbcTotalStkUsed(); + if (offset < 0) { + /* length of ALL stack based args for this call, this location is where the + next large agg resides, its addr will then be passed */ + offset = LmbcFindTotalStkUsed(parmList) + LmbcTotalRegsUsed(); + } + SetLmbcTotalStkUsed(offset + bNode.blockSize); /* next use */ + SetLmbcArgInfo(regResult, PTY_i64, 0, 1); /* 1 reg for ptr */ + IncLmbcArgsInRegs(kRegTyInt); + IncLmbcTotalArgs(); + /* copy large agg arg to offset below */ + } std::vector opndVec; opndVec.push_back(regResult); /* result */ - opndVec.push_back(PrepareMemcpyParamOpnd(bNode.offset, *dest)); /* param 0 */ + opndVec.push_back(PrepareMemcpyParamOpnd(offset, *dest)); /* param 0 */ opndVec.push_back(src); /* param 1 */ opndVec.push_back(PrepareMemcpyParamOpnd(static_cast(static_cast(bNode.blockSize)))); /* param 2 */ SelectLibCall("memcpy", opndVec, PTY_a64, PTY_a64); - if (IsBlkassignForPush(bNode)) { - SetLmbcArgInfo(static_cast(src), PTY_i64, (int32)bNode.offset, 1); - IncLmbcArgsInRegs(kRegTyInt); - IncLmbcTotalArgs(); - } } void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { @@ -2553,6 +2659,159 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { } } +void AArch64CGFunc::SelectReturnSendOfStructInRegs(BaseNode *x) { + uint32 offset = 0; + if (x->GetOpCode() == OP_dread) { + DreadNode *dread = static_cast(x); + MIRSymbol *sym = GetFunction().GetLocalOrGlobalSymbol(dread->GetStIdx()); + MIRType *mirType = sym->GetType(); + if (dread->GetFieldID() != 0) { + MIRStructType *structType = static_cast(mirType); + mirType = structType->GetFieldType(dread->GetFieldID()); + offset = static_cast(GetBecommon().GetFieldOffset(*structType, dread->GetFieldID()).first); + } + uint32 typeSize = GetBecommon().GetTypeSize(mirType->GetTypeIndex()); + /* generate move to regs for agg return */ + AArch64CallConvImpl parmlocator(GetBecommon()); + CCLocInfo pLoc; + parmlocator.LocateNextParm(*mirType, pLoc, true, GetBecommon().GetMIRModule().CurFunction()); + /* aggregates are 8 byte aligned. */ + Operand *rhsmemopnd = nullptr; + RegOperand *result[kFourRegister]; /* up to 2 int or 4 fp */ + uint32 loadSize; + uint32 numRegs; + RegType regType; + PrimType retPty; + bool fpParm = false; + if (pLoc.numFpPureRegs) { + loadSize = pLoc.fpSize; + numRegs = pLoc.numFpPureRegs; + fpParm = true; + regType = kRegTyFloat; + retPty = (pLoc.fpSize == k4ByteSize) ? PTY_f32 : PTY_f64; + } else { + if (CGOptions::IsBigEndian()) { + loadSize = k8ByteSize; + numRegs = (typeSize <= k8ByteSize) ? kOneRegister : kTwoRegister; + regType = kRegTyInt; + retPty = PTY_u64; + } else { + loadSize = (typeSize <= k4ByteSize) ? k4ByteSize : k8ByteSize; + numRegs = (typeSize <= k8ByteSize) ? kOneRegister : kTwoRegister; + regType = kRegTyInt; + retPty = PTY_u32; + } + } + bool parmCopy = IsParamStructCopy(*sym); + for (uint32 i = 0; i < numRegs; i++) { + if (parmCopy) { + rhsmemopnd = &LoadStructCopyBase(*sym, + (offset + static_cast(i * (fpParm ? loadSize : k8ByteSize))), + static_cast(loadSize * kBitsPerByte)); + } else { + rhsmemopnd = &GetOrCreateMemOpnd(*sym, + (offset + static_cast(i * (fpParm ? loadSize : k8ByteSize))), + (loadSize * kBitsPerByte)); + } + result[i] = &CreateVirtualRegisterOperand(NewVReg(regType, loadSize)); + MOperator mop1 = PickLdInsn(loadSize * kBitsPerByte, retPty); + Insn &ld = GetCG()->BuildInstruction(mop1, *(result[i]), *rhsmemopnd); + GetCurBB()->AppendInsn(ld); + } + AArch64reg regs[kFourRegister]; + regs[0] = static_cast(pLoc.reg0); + regs[1] = static_cast(pLoc.reg1); + regs[2] = static_cast(pLoc.reg2); + regs[3] = static_cast(pLoc.reg3); + RegOperand *dest; + for (uint32 i = 0; i < numRegs; i++) { + AArch64reg preg; + MOperator mop2; + if (fpParm) { + preg = regs[i]; + mop2 = (loadSize == k4ByteSize) ? MOP_xvmovs : MOP_xvmovd; + } else { + preg = (i == 0 ? R0 : R1); + mop2 = (loadSize == k4ByteSize) ? MOP_wmovrr : MOP_xmovrr; + } + dest = &GetOrCreatePhysicalRegisterOperand(preg, (loadSize * kBitsPerByte), regType); + Insn &mov = GetCG()->BuildInstruction(mop2, *dest, *(result[i])); + GetCurBB()->AppendInsn(mov); + } + /* Create artificial dependency to extend the live range */ + for (uint32 i = 0; i < numRegs; i++) { + AArch64reg preg; + MOperator mop3; + if (fpParm) { + preg = regs[i]; + mop3 = MOP_pseudo_ret_float; + } else { + preg = (i == 0 ? R0 : R1); + mop3 = MOP_pseudo_ret_int; + } + dest = &GetOrCreatePhysicalRegisterOperand(preg, loadSize * kBitsPerByte, regType); + Insn &pseudo = GetCG()->BuildInstruction(mop3, *dest); + GetCurBB()->AppendInsn(pseudo); + } + return; + } else if (x->GetOpCode() == OP_iread) { + IreadNode *iread = static_cast(x); + RegOperand *rhsAddrOpnd = static_cast(HandleExpr(*iread, *iread->Opnd(0))); + rhsAddrOpnd = &LoadIntoRegister(*rhsAddrOpnd, iread->Opnd(0)->GetPrimType()); + MIRPtrType *ptrType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread->GetTyIdx())); + MIRType *mirType = static_cast(ptrType->GetPointedType()); + bool isRefField = false; + if (iread->GetFieldID() != 0) { + MIRStructType *structType = static_cast(mirType); + mirType = structType->GetFieldType(iread->GetFieldID()); + offset = static_cast(GetBecommon().GetFieldOffset(*structType, iread->GetFieldID()).first); + isRefField = GetBecommon().IsRefField(*structType, iread->GetFieldID()); + } + uint32 typeSize = GetBecommon().GetTypeSize(mirType->GetTypeIndex()); + /* generate move to regs. */ + RegOperand *result[kTwoRegister]; /* maximum 16 bytes, 2 registers */ + uint32 loadSize; + if (CGOptions::IsBigEndian()) { + loadSize = k8ByteSize; + } else { + loadSize = (typeSize <= k4ByteSize) ? k4ByteSize : k8ByteSize; + } + uint32 numRegs = (typeSize <= k8ByteSize) ? kOneRegister : kTwoRegister; + for (uint32 i = 0; i < numRegs; i++) { + OfstOperand *rhsOffOpnd = &GetOrCreateOfstOpnd(offset + i * loadSize, loadSize * kBitsPerByte); + Operand &rhsmemopnd = GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, loadSize * kBitsPerByte, + rhsAddrOpnd, nullptr, rhsOffOpnd, nullptr); + result[i] = &CreateVirtualRegisterOperand(NewVReg(kRegTyInt, loadSize)); + MOperator mop1 = PickLdInsn(loadSize * kBitsPerByte, PTY_u32); + Insn &ld = GetCG()->BuildInstruction(mop1, *(result[i]), rhsmemopnd); + ld.MarkAsAccessRefField(isRefField); + GetCurBB()->AppendInsn(ld); + } + RegOperand *dest; + for (uint32 i = 0; i < numRegs; i++) { + AArch64reg preg = (i == 0 ? R0 : R1); + dest = &GetOrCreatePhysicalRegisterOperand(preg, loadSize * kBitsPerByte, kRegTyInt); + Insn &mov = GetCG()->BuildInstruction(MOP_xmovrr, *dest, *(result[i])); + GetCurBB()->AppendInsn(mov); + } + /* Create artificial dependency to extend the live range */ + for (uint32 i = 0; i < numRegs; i++) { + AArch64reg preg = (i == 0 ? R0 : R1); + dest = &GetOrCreatePhysicalRegisterOperand(preg, loadSize * kBitsPerByte, kRegTyInt); + Insn &pseudo = cg->BuildInstruction(MOP_pseudo_ret_int, *dest); + GetCurBB()->AppendInsn(pseudo); + } + return; + } else { // dummy return of 0 inserted by front-end at absence of return + ASSERT(x->GetOpCode() == OP_constval, "SelectReturnSendOfStructInRegs: unexpected return operand"); + uint32 typeSize = GetPrimTypeSize(x->GetPrimType()); + RegOperand &dest = GetOrCreatePhysicalRegisterOperand(R0, typeSize * kBitsPerByte, kRegTyInt); + ImmOperand &src = CreateImmOperand(0, k16BitSize, false); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_xmovri32, dest, src)); + return; + } +} + Operand *AArch64CGFunc::SelectDread(const BaseNode &parent, DreadNode &expr) { MIRSymbol *symbol = GetFunction().GetLocalOrGlobalSymbol(expr.GetStIdx()); if (symbol->IsEhIndex()) { @@ -2916,31 +3175,50 @@ Operand *AArch64CGFunc::SelectIreadoff(const BaseNode &parent, IreadoffNode &ire return result; } -RegOperand *AArch64CGFunc::GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType) { - MemOperand *memOpnd; - RegOperand *rfp = &GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); - uint32 bitlen = byteSize * kBitsPerByte; - if (offset < 0) { - RegOperand *baseOpnd = &CreateRegisterOperandOfType(PTY_a64); - ImmOperand &immOpnd = CreateImmOperand(offset, k32BitSize, true); - Insn &addInsn = GetCG()->BuildInstruction(MOP_xaddrri12, *baseOpnd, *rfp, immOpnd); - GetCurBB()->AppendInsn(addInsn); - OfstOperand *offsetOpnd = &CreateOfstOpnd(0, k32BitSize); - memOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, bitlen, baseOpnd, - nullptr, offsetOpnd, nullptr); - } else { - OfstOperand *offsetOpnd = &CreateOfstOpnd(static_cast(static_cast(offset)), k32BitSize); - memOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, bitlen, rfp, - nullptr, offsetOpnd, nullptr); - } - memOpnd->SetStackMem(true); +RegOperand *AArch64CGFunc::GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType, + AArch64reg baseRegno) { + MemOperand *memOpnd = GenLmbcFpMemOperand(offset, byteSize, baseRegno); RegOperand *result = &GetOrCreateVirtualRegisterOperand(NewVReg(regType, byteSize)); - MOperator mOp = PickLdInsn(bitlen, primType); + MOperator mOp = PickLdInsn(byteSize * kBitsPerByte, primType); Insn &load = GetCG()->BuildInstruction(mOp, *result, *memOpnd); GetCurBB()->AppendInsn(load); return result; } +RegOperand *AArch64CGFunc::LmbcStructReturnLoad(int32 offset) { + RegOperand *result = nullptr; + MIRFunction &func = GetFunction(); + CHECK_FATAL(func.IsReturnStruct(), "LmbcStructReturnLoad: not struct return"); + MIRType *ty = func.GetReturnType(); + uint32 sz = GetBecommon().GetTypeSize(ty->GetTypeIndex()); + uint32 fpSize; + uint32 numFpRegs = FloatParamRegRequired(static_cast(ty), fpSize); + if (numFpRegs > 0) { + PrimType pType = (fpSize <= k4ByteSize) ? PTY_f32 : PTY_f64; + for (int32 i = (numFpRegs - kOneRegister); i > 0; --i) { + result = GenLmbcParamLoad(offset + (i * fpSize), fpSize, kRegTyFloat, pType); + AArch64reg regNo = static_cast(V0 + i); + RegOperand *reg = &GetOrCreatePhysicalRegisterOperand(regNo, fpSize * kBitsPerByte, kRegTyFloat); + SelectCopy(*reg, pType, *result, pType); + Insn &pseudo = GetCG()->BuildInstruction(MOP_pseudo_ret_float, *reg); + GetCurBB()->AppendInsn(pseudo); + } + result = GenLmbcParamLoad(offset, fpSize, kRegTyFloat, pType); + } else if (sz <= k4ByteSize) { + result = GenLmbcParamLoad(offset, k4ByteSize, kRegTyInt, PTY_u32); + } else if (sz <= k8ByteSize) { + result = GenLmbcParamLoad(offset, k8ByteSize, kRegTyInt, PTY_i64); + } else if (sz <= k16ByteSize) { + result = GenLmbcParamLoad(offset + k8ByteSize, k8ByteSize, kRegTyInt, PTY_i64); + RegOperand *r1 = &GetOrCreatePhysicalRegisterOperand(R1, k8ByteSize * kBitsPerByte, kRegTyInt); + SelectCopy(*r1, PTY_i64, *result, PTY_i64); + Insn &pseudo = GetCG()->BuildInstruction(MOP_pseudo_ret_int, *r1); + GetCurBB()->AppendInsn(pseudo); + result = GenLmbcParamLoad(offset, k8ByteSize, kRegTyInt, PTY_i64); + } + return result; +} + Operand *AArch64CGFunc::SelectIreadfpoff(const BaseNode &parent, IreadFPoffNode &ireadoff) { int32 offset = ireadoff.GetOffset(); PrimType primType = ireadoff.GetPrimType(); @@ -2951,19 +3229,32 @@ Operand *AArch64CGFunc::SelectIreadfpoff(const BaseNode &parent, IreadFPoffNode if (offset >= 0) { LmbcFormalParamInfo *info = GetLmbcFormalParamInfo(static_cast(offset)); if (info->GetPrimType() == PTY_agg) { - result = GenLmbcParamLoad(offset, bytelen, regty, primType); + if (info->IsOnStack()) { + result = GenLmbcParamLoad(info->GetOnStackOffset(), GetPrimTypeSize(PTY_a64), kRegTyInt, PTY_a64); + regno_t baseRegno = result->GetRegisterNumber(); + result = GenLmbcParamLoad(offset - info->GetOffset(), bytelen, regty, primType, (AArch64reg)baseRegno); + } else if (primType == PTY_agg) { + CHECK_FATAL(parent.GetOpCode() == OP_regassign, "SelectIreadfpoff of agg"); + result = LmbcStructReturnLoad(offset); + } else { + result = GenLmbcParamLoad(offset, bytelen, regty, primType); + } } else { CHECK_FATAL(primType == info->GetPrimType(), "Incorrect primtype"); CHECK_FATAL(offset == info->GetOffset(), "Incorrect offset"); - if (info->GetRegNO() == 0) { - /* TODO : follow lmbc sp offset for now */ + if (info->GetRegNO() == 0 || info->HasRegassign() == false) { result = GenLmbcParamLoad(offset, bytelen, regty, primType); } else { result = &GetOrCreatePhysicalRegisterOperand((AArch64reg)(info->GetRegNO()), bitlen, regty); } } } else { - result = GenLmbcParamLoad(offset, bytelen, regty, primType); + if (primType == PTY_agg) { + CHECK_FATAL(parent.GetOpCode() == OP_regassign, "SelectIreadfpoff of agg"); + result = LmbcStructReturnLoad(offset); + } else { + result = GenLmbcParamLoad(offset, bytelen, regty, primType); + } } return result; } @@ -5759,6 +6050,9 @@ Operand *AArch64CGFunc::SelectAlloca(UnaryNode &node, Operand &opnd0) { if (!CGOptions::IsArm64ilp32()) { ASSERT((node.GetPrimType() == PTY_a64), "wrong type"); } + if (GetCG()->IsLmbc()) { + SetHasVLAOrAlloca(true); + } PrimType stype = node.Opnd(0)->GetPrimType(); Operand *resOpnd = &opnd0; if (GetPrimTypeBitSize(stype) < GetPrimTypeBitSize(PTY_u64)) { @@ -5774,10 +6068,13 @@ Operand *AArch64CGFunc::SelectAlloca(UnaryNode &node, Operand &opnd0) { SelectShift(aliOp, aliOp, shifOpnd, kShiftLeft, PTY_u64); Operand &spOpnd = GetOrCreatePhysicalRegisterOperand(RSP, k64BitSize, kRegTyInt); SelectSub(spOpnd, spOpnd, aliOp, PTY_u64); - int64 argsToStkpassSize = GetMemlayout()->SizeOfArgsToStackPass(); - if (argsToStkpassSize > 0) { + int64 allocaOffset = GetMemlayout()->SizeOfArgsToStackPass(); + if (GetCG()->IsLmbc()) { + allocaOffset -= kDivide2 * k8ByteSize; + } + if (allocaOffset > 0) { RegOperand &resallo = CreateRegisterOperandOfType(PTY_u64); - SelectAdd(resallo, spOpnd, CreateImmOperand(argsToStkpassSize, k64BitSize, true), PTY_u64); + SelectAdd(resallo, spOpnd, CreateImmOperand(allocaOffset, k64BitSize, true), PTY_u64); return &resallo; } else { return &SelectCopy(spOpnd, PTY_u64, PTY_u64); @@ -6219,6 +6516,15 @@ void AArch64CGFunc::AssignLmbcFormalParams() { param->SetRegNO(0); } else { param->SetRegNO(intReg); + if (param->HasRegassign() == false) { + uint32 bytelen = GetPrimTypeSize(primType); + uint32 bitlen = bytelen * kBitsPerByte; + MemOperand *mOpnd = GenLmbcFpMemOperand(offset, bytelen); + RegOperand &src = GetOrCreatePhysicalRegisterOperand(AArch64reg(intReg), bitlen, kRegTyInt); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, src, *mOpnd); + GetCurBB()->AppendInsn(store); + } intReg++; } } else if (IsPrimitiveFloat(primType)) { @@ -6226,6 +6532,15 @@ void AArch64CGFunc::AssignLmbcFormalParams() { param->SetRegNO(0); } else { param->SetRegNO(fpReg); + if (param->HasRegassign() == false) { + uint32 bytelen = GetPrimTypeSize(primType); + uint32 bitlen = bytelen * kBitsPerByte; + MemOperand *mOpnd = GenLmbcFpMemOperand(offset, bytelen); + RegOperand &src = GetOrCreatePhysicalRegisterOperand(AArch64reg(fpReg), bitlen, kRegTyFloat); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, src, *mOpnd); + GetCurBB()->AppendInsn(store); + } fpReg++; } } else if (primType == PTY_agg) { @@ -6244,6 +6559,14 @@ void AArch64CGFunc::AssignLmbcFormalParams() { } else { param->SetRegNO(intReg); param->SetIsOnStack(); + param->SetOnStackOffset((intReg - R0 + fpReg - V0) * k8ByteSize); + uint32 bytelen = GetPrimTypeSize(PTY_a64); + uint32 bitlen = bytelen * kBitsPerByte; + MemOperand *mOpnd = GenLmbcFpMemOperand(param->GetOnStackOffset(), bytelen); + RegOperand &src = GetOrCreatePhysicalRegisterOperand(AArch64reg(intReg), bitlen, kRegTyInt); + MOperator mOp = PickStInsn(bitlen, PTY_a64); + Insn &store = GetCG()->BuildInstruction(mOp, src, *mOpnd); + GetCurBB()->AppendInsn(store); intReg++; } } else if (param->GetSize() <= k8ByteSize) { @@ -6289,7 +6612,6 @@ void AArch64CGFunc::AssignLmbcFormalParams() { Operand *memOpd = &CreateMemOpnd(RFP, offset + (i * rSize), rSize); GetCurBB()->AppendInsn(GetCG()->BuildInstruction( PickStInsn(rSize * kBitsPerByte, pType), dest, *memOpd)); - param->SetIsOnStack(); } } } else { @@ -6298,6 +6620,22 @@ void AArch64CGFunc::AssignLmbcFormalParams() { } } +void AArch64CGFunc::LmbcGenSaveSpForAlloca() { + if (GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc || HasVLAOrAlloca() == false) { + return; + } + Operand &spOpnd = GetOrCreatePhysicalRegisterOperand(RSP, k64BitSize, kRegTyInt); + RegOperand &spSaveOpnd = CreateVirtualRegisterOperand(NewVReg(kRegTyInt, kSizeOfPtr)); + Insn &save = GetCG()->BuildInstruction(MOP_xmovrr, spSaveOpnd, spOpnd); + GetFirstBB()->AppendInsn(save); + //save.SetFrameDef(true); + for (auto *retBB : GetExitBBsVec()) { + Insn &restore = GetCG()->BuildInstruction(MOP_xmovrr, spOpnd, spSaveOpnd); + retBB->AppendInsn(restore); + restore.SetFrameDef(true); + } +} + /* if offset < 0, allocation; otherwise, deallocation */ MemOperand &AArch64CGFunc::CreateCallFrameOperand(int32 offset, uint32 size) { MemOperand *memOpnd = CreateStackMemOpnd(RSP, offset, size); @@ -7583,6 +7921,10 @@ size_t AArch64CGFunc::SelectParmListGetStructReturnSize(StmtNode &naryNode) { CallNode &callNode = static_cast(naryNode); MIRFunction *callFunc = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callNode.GetPUIdx()); TyIdx retIdx = callFunc->GetReturnTyIdx(); + if (callFunc->IsFirstArgReturn()) { + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(callFunc->GetFormalDefVec()[0].formalTyIdx); + return GetBecommon().GetTypeSize(static_cast(ty)->GetPointedTyIdx()); + } size_t retSize = GetBecommon().GetTypeSize(retIdx.GetIdx()); if ((retSize == 0) && callFunc->IsReturnStruct()) { TyIdx tyIdx = callFunc->GetFuncRetStructTyIdx(); @@ -7599,6 +7941,14 @@ size_t AArch64CGFunc::SelectParmListGetStructReturnSize(StmtNode &naryNode) { return GetBecommon().GetTypeSize(sym->GetTyIdx().GetIdx()); } } + } else if (naryNode.GetOpCode() == OP_icallproto) { + IcallNode &icallProto = static_cast(naryNode); + MIRFuncType *funcTy = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallProto.GetRetTyIdx())); + if (funcTy->FirstArgReturn()) { + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcTy->GetNthParamType(0)); + return GetBecommon().GetTypeSize(static_cast(ty)->GetPointedTyIdx()); + } + return GetBecommon().GetTypeSize(funcTy->GetRetTyIdx()); } return 0; } @@ -7706,7 +8056,7 @@ void AArch64CGFunc::SelectParmListPreprocess(const StmtNode &naryNode, size_t st */ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bool isCallNative) { size_t i = 0; - if ((naryNode.GetOpCode() == OP_icall) || isCallNative) { + if (naryNode.GetOpCode() == OP_icall || naryNode.GetOpCode() == OP_icallproto || isCallNative) { i++; } std::set specialArgs; @@ -7733,8 +8083,11 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - auto *callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + MIRFunction *callee = nullptr; + if (dynamic_cast(&naryNode) != nullptr) { + auto calleePuIdx = static_cast(naryNode).GetPUIdx(); + callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } @@ -8256,7 +8609,18 @@ void AArch64CGFunc::SelectCall(CallNode &callNode) { ListOperand *srcOpnds = CreateListOpnd(*GetFuncScopeAllocator()); if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { - LmbcSelectParmList(srcOpnds, fn->IsFirstArgReturn()); + SetLmbcCallReturnType(nullptr); + bool largeStructRet = false; + if (fn->IsFirstArgReturn()) { + MIRPtrType *ptrTy = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(fn->GetFormalDefVec()[0].formalTyIdx)); + MIRType *sTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ptrTy->GetPointedTyIdx()); + largeStructRet = sTy->GetSize() > k16ByteSize; + SetLmbcCallReturnType(sTy); + } else { + MIRType *ty = fn->GetReturnType(); + SetLmbcCallReturnType(ty); + } + LmbcSelectParmList(srcOpnds, largeStructRet); } bool callNative = false; if ((fsym->GetName() == "MCC_CallFastNative") || (fsym->GetName() == "MCC_CallFastNativeExt") || @@ -8332,11 +8696,21 @@ void AArch64CGFunc::SelectCall(CallNode &callNode) { void AArch64CGFunc::SelectIcall(IcallNode &icallNode, Operand &srcOpnd) { ListOperand *srcOpnds = CreateListOpnd(*GetFuncScopeAllocator()); - if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { - LmbcSelectParmList(srcOpnds, false); /*fType->GetRetAttrs().GetAttr(ATTR_firstarg_return)*/ - } else { +// if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { +// /* icallproto */ +// MIRType *retTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallNode.GetRetTyIdx()); +// MIRFuncType *funcTy = static_cast(retTy); +// bool largeStructRet = false; +// if (funcTy->FirstArgReturn()) { +// TyIdx idx = funcTy->GetNthParamType(0); +// MIRPtrType *ptrTy = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(idx)); +// MIRType *sTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ptrTy->GetPointedTyIdx()); +// largeStructRet = sTy->GetSize() > k16ByteSize; +// } +// LmbcSelectParmList(srcOpnds, largeStructRet); +// } else { SelectParmList(icallNode, *srcOpnds); - } +// } Operand *fptrOpnd = &srcOpnd; if (fptrOpnd->GetKind() != Operand::kOpdRegister) { @@ -8347,7 +8721,7 @@ void AArch64CGFunc::SelectIcall(IcallNode &icallNode, Operand &srcOpnd) { RegOperand *regOpnd = static_cast(fptrOpnd); Insn &callInsn = GetCG()->BuildInstruction(MOP_xblr, *regOpnd, *srcOpnds); - MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallNode.GetRetTyIdx()); + MIRType *retType = icallNode.GetCallReturnType(); if (retType != nullptr) { callInsn.SetRetSize(static_cast(retType->GetSize())); callInsn.SetIsCallReturnUnsigned(IsUnsignedInteger(retType->GetPrimType())); @@ -8460,9 +8834,18 @@ RegOperand &AArch64CGFunc::GetOrCreateSpecialRegisterOperand(PregIdx sregIdx, Pr case kSregFp: reg = RFP; break; - case kSregGp: - reg = RFP; - break; + case kSregGp: { + MIRSymbol *sym = GetCG()->GetGP(); + if (sym == nullptr) { + sym = GetFunction().GetSymTab()->CreateSymbol(kScopeLocal); + std::string strBuf("__file__local__GP"); + sym->SetNameStrIdx(GetMirModule().GetMIRBuilder()->GetOrCreateStringIndex(strBuf)); + GetCG()->SetGP(sym); + } + RegOperand &result = GetOrCreateVirtualRegisterOperand(NewVReg(kRegTyInt, k8ByteSize)); + SelectAddrof(result, CreateStImmOperand(*sym, 0, 0)); + return result; + } case kSregThrownval: { /* uses x0 == R0 */ ASSERT(uCatch.regNOCatch > 0, "regNOCatch should greater than 0."); if (Globals::GetInstance()->GetOptimLevel() == 0) { @@ -9201,6 +9584,9 @@ int32 AArch64CGFunc::GetBaseOffset(const SymbolAlloc &sa) { int32 baseOffset = symAlloc->GetOffset(); return baseOffset + sizeofFplr; } else if (sgKind == kMsSpillReg) { + if (GetCG()->IsLmbc()) { + return symAlloc->GetOffset() + memLayout->SizeOfArgsToStackPass(); + } int32 baseOffset = symAlloc->GetOffset() + memLayout->SizeOfArgsRegisterPassed() + memLayout->GetSizeOfLocals() + memLayout->GetSizeOfRefLocals(); return baseOffset + sizeofFplr; @@ -9775,16 +10161,21 @@ void AArch64CGFunc::GenCVaStartIntrin(RegOperand &opnd, uint32 stkSize) { Operand &stkOpnd = GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); /* __stack */ - ImmOperand *offsOpnd = &CreateImmOperand(0, k64BitSize, true, kUnAdjustVary); /* isvary reset StackFrameSize */ + ImmOperand *offsOpnd; + if (GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + offsOpnd = &CreateImmOperand(0, k64BitSize, true, kUnAdjustVary); /* isvary reset StackFrameSize */ + } else { + offsOpnd = &CreateImmOperand(0, k64BitSize, true); + } ImmOperand *offsOpnd2 = &CreateImmOperand(stkSize, k64BitSize, false); RegOperand &vReg = CreateVirtualRegisterOperand(NewVReg(kRegTyInt, GetPrimTypeSize(LOWERED_PTR_TYPE))); if (stkSize) { SelectAdd(vReg, *offsOpnd, *offsOpnd2, LOWERED_PTR_TYPE); SelectAdd(vReg, stkOpnd, vReg, LOWERED_PTR_TYPE); } else { - SelectAdd(vReg, stkOpnd, *offsOpnd, LOWERED_PTR_TYPE); + SelectAdd(vReg, stkOpnd, *offsOpnd, LOWERED_PTR_TYPE); /* stack pointer */ } - OfstOperand *offOpnd = &GetOrCreateOfstOpnd(0, k64BitSize); + OfstOperand *offOpnd = &GetOrCreateOfstOpnd(0, k64BitSize); /* va_list ptr */ /* mem operand in va_list struct (lhs) */ MemOperand *strOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, k64BitSize, &opnd, nullptr, offOpnd, static_cast(nullptr)); @@ -9859,13 +10250,19 @@ void AArch64CGFunc::SelectCVaStart(const IntrinsiccallNode &intrnNode) { AArch64CallConvImpl parmLocator(GetBecommon()); CCLocInfo pLoc; uint32 stkSize = 0; + uint32 inReg = 0; for (uint32 i = 0; i < GetFunction().GetFormalCount(); i++) { MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(GetFunction().GetNthParamTyIdx(i)); parmLocator.LocateNextParm(*ty, pLoc); if (pLoc.reg0 == kRinvalid) { /* on stack */ stkSize = static_cast(pLoc.memOffset + pLoc.memSize); + } else { + inReg++; } } + if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + stkSize += (inReg * k8ByteSize); + } if (CGOptions::IsArm64ilp32()) { stkSize = static_cast(RoundUp(stkSize, k8ByteSize)); } else { diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp index 8525f3f08f..77f6a2e70f 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp @@ -40,8 +40,8 @@ constexpr uint8 insPairsNum = 5; PairMOperator extInsnPairTable[ExtTableSize][insPairsNum] = { /* {origMop, newMop} */ - {{MOP_wldrb, MOP_wldrb}, {MOP_undef, MOP_undef}, {MOP_undef, MOP_undef}, {MOP_undef, MOP_undef}, - {MOP_undef, MOP_undef}}, /* AND */ + {{MOP_wldrb, MOP_wldrb}, {MOP_wldrsh, MOP_wldrb}, {MOP_wldrh, MOP_wldrb}, {MOP_xldrsw, MOP_wldrb}, + {MOP_wldr, MOP_wldrb}}, /* AND */ {{MOP_wldrb, MOP_wldrsb}, {MOP_wldr, MOP_wldrsb}, {MOP_undef, MOP_undef}, {MOP_undef, MOP_undef}, {MOP_undef, MOP_undef}}, /* SXTB */ {{MOP_wldrh, MOP_wldrsh}, {MOP_wldrb, MOP_wldrb}, {MOP_wldrsb, MOP_wldrsb}, {MOP_wldrsh, MOP_wldrsh}, diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp index a58213245c..4184108a22 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp @@ -134,7 +134,7 @@ void AArch64MemLayout::LayoutVarargParams() { if (be.GetMIRModule().IsCModule() && func->GetAttr(FUNCATTR_varargs)) { for (uint32 i = 0; i < func->GetFormalCount(); i++) { if (i == 0) { - if (func->IsReturnStruct()) { + if (func->IsFirstArgReturn() && func->GetReturnType()->GetPrimType() != PTY_void) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (be.GetTypeSize(tyIdx.GetIdx()) <= k16ByteSize) { continue; @@ -198,7 +198,7 @@ void AArch64MemLayout::LayoutFormalParams() { * outparmsize - portion of frame size of current function used by call parameters */ segArgsStkPassed.SetSize(mirFunction->GetOutParmSize()); - segArgsRegPassed.SetSize(mirFunction->GetOutParmSize() + kTwoRegister * k8ByteSize); + segArgsRegPassed.SetSize(mirFunction->GetOutParmSize()); return; } @@ -210,7 +210,7 @@ void AArch64MemLayout::LayoutFormalParams() { AArch64SymbolAlloc *symLoc = memAllocator->GetMemPool()->New(); SetSymAllocInfo(stIndex, *symLoc); if (i == 0) { - if (mirFunction->IsReturnStruct()) { + if (mirFunction->IsFirstArgReturn()) { symLoc->SetMemSegment(GetSegArgsRegPassed()); symLoc->SetOffset(GetSegArgsRegPassed().GetSize()); TyIdx tyIdx = mirFunction->GetFuncRetStructTyIdx(); @@ -224,13 +224,13 @@ void AArch64MemLayout::LayoutFormalParams() { continue; } } - MIRType *ty = mirFunction->GetNthParamType(i); + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(mirFunction->GetFormalDefVec()[i].formalTyIdx); uint32 ptyIdx = ty->GetTypeIndex(); parmLocator.LocateNextParm(*ty, ploc, i == 0, mirFunction); if (ploc.reg0 != kRinvalid) { /* register */ symLoc->SetRegisters(static_cast(ploc.reg0), static_cast(ploc.reg1), static_cast(ploc.reg2), static_cast(ploc.reg3)); - if (mirFunction->GetNthParamAttr(i).GetAttr(ATTR_localrefvar)) { + if (mirFunction->GetFormalDefVec()[i].formalAttrs.GetAttr(ATTR_localrefvar)) { symLoc->SetMemSegment(segRefLocals); SetSegmentSize(*symLoc, segRefLocals, ptyIdx); } else if (!sym->IsPreg()) { @@ -272,7 +272,7 @@ void AArch64MemLayout::LayoutFormalParams() { } else { segArgsStkPassed.SetSize(static_cast(RoundUp(segArgsStkPassed.GetSize(), kSizeOfPtr))); } - if (mirFunction->GetNthParamAttr(i).GetAttr(ATTR_localrefvar)) { + if (mirFunction->GetFormalDefVec()[i].formalAttrs.GetAttr(ATTR_localrefvar)) { SetLocalRegLocInfo(sym->GetStIdx(), *symLoc); AArch64SymbolAlloc *symLoc1 = memAllocator->GetMemPool()->New(); symLoc1->SetMemSegment(segRefLocals); @@ -287,8 +287,8 @@ void AArch64MemLayout::LayoutFormalParams() { } void AArch64MemLayout::LayoutLocalVariables(std::vector &tempVar, std::vector &returnDelays) { - if (be.GetMIRModule().GetFlavor() == kFlavorLmbc && mirFunction->GetFormalCount() == 0) { - segLocals.SetSize(static_cast(mirFunction->GetFrameSize() - mirFunction->GetOutParmSize())); + if (be.GetMIRModule().GetFlavor() == kFlavorLmbc) { + segLocals.SetSize(mirFunction->GetFrameSize() - mirFunction->GetOutParmSize()); return; } @@ -372,7 +372,7 @@ void AArch64MemLayout::LayoutReturnRef(std::vector &returnDelays, segRefLocals.SetSize(segRefLocals.GetSize() + be.GetTypeSize(tyIdx)); } if (be.GetMIRModule().GetFlavor() == kFlavorLmbc) { - segArgsToStkPass.SetSize(mirFunction->GetOutParmSize()); + segArgsToStkPass.SetSize(mirFunction->GetOutParmSize() + kDivide2 * k8ByteSize); } else { segArgsToStkPass.SetSize(FindLargestActualArea(structCopySize)); } @@ -423,7 +423,7 @@ void AArch64MemLayout::LayoutActualParams() { * variables get assigned their respecitve storage, i.e. * CallFrameSize (discounting callee-saved and FP/LR) is known. */ - MIRType *ty = mirFunction->GetNthParamType(i); + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(mirFunction->GetFormalDefVec()[i].formalTyIdx); uint32 ptyIdx = ty->GetTypeIndex(); static_cast(cgFunc)->GetOrCreateMemOpnd(*sym, 0, be.GetTypeAlign(ptyIdx) * kBitsPerByte); } @@ -440,7 +440,7 @@ void AArch64MemLayout::LayoutStackFrame(int32 &structCopySize, int32 &maxParmSta */ if (CGOptions::IsArm64ilp32()) { segArgsRegPassed.SetSize(RoundUp(segArgsRegPassed.GetSize(), k8ByteSize)); - /* we do need this as SP has to be aligned at a 16-bytes bounardy */ + /* we do need this as SP has to be aligned at a 16-bytes bounardy */ segArgsStkPassed.SetSize(RoundUp(segArgsStkPassed.GetSize(), k8ByteSize + k8ByteSize)); } else { segArgsRegPassed.SetSize(RoundUp(segArgsRegPassed.GetSize(), kSizeOfPtr)); @@ -527,11 +527,13 @@ uint64 AArch64MemLayout::StackFrameSize() const { uint64 total = segArgsRegPassed.GetSize() + static_cast(cgFunc)->SizeOfCalleeSaved() + GetSizeOfRefLocals() + locals().GetSize() + GetSizeOfSpillReg(); - if (GetSizeOfGRSaveArea() > 0) { - total += RoundUp(GetSizeOfGRSaveArea(), kAarch64StackPtrAlignment); - } - if (GetSizeOfVRSaveArea() > 0) { - total += RoundUp(GetSizeOfVRSaveArea(), kAarch64StackPtrAlignment); + if (cgFunc->GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + if (GetSizeOfGRSaveArea() > 0) { + total += RoundUp(GetSizeOfGRSaveArea(), kAarch64StackPtrAlignment); + } + if (GetSizeOfVRSaveArea() > 0) { + total += RoundUp(GetSizeOfVRSaveArea(), kAarch64StackPtrAlignment); + } } /* diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp index 326d730c21..25694d7403 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp @@ -50,7 +50,7 @@ void AArch64FPLROffsetAdjustment::AdjustmentOffsetForOpnd(Insn &insn, AArch64CGF if (memBaseReg->GetRegisterNumber() == RFP) { RegOperand &newBaseOpnd = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(stackBaseReg, k64BitSize, kRegTyInt); MemOperand &newMemOpnd = aarchCGFunc.GetOrCreateMemOpnd( - MemOperand::kAddrModeBOi, memOpnd.GetSize(), &newBaseOpnd, memOpnd.GetIndexRegister(), + memOpnd.GetAddrMode(), memOpnd.GetSize(), &newBaseOpnd, memOpnd.GetIndexRegister(), memOpnd.GetOffsetImmediate(), memOpnd.GetSymbol()); insn.SetOperand(i, newMemOpnd); stackBaseOpnd = true; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp index 7f246272c0..bffcb420c1 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp @@ -1118,6 +1118,9 @@ void AArch64GenProEpilog::AppendInstructionAllocateCallFrameDebug(AArch64reg reg ipoint = cgFunc.GetCurBB()->GetLastInsn(); cfiOffset = stackFrameSize; (void)InsertCFIDefCfaOffset(cfiOffset, *ipoint); + if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + argsToStkPassSize -= (kDivide2 * k8ByteSize); + } ipoint = &CreateAndAppendInstructionForAllocateCallFrame(argsToStkPassSize, reg0, reg1, rty); CHECK_FATAL(ipoint != nullptr, "ipoint should not be nullptr at this point"); cfiOffset = GetOffsetFromCFA(); @@ -1251,9 +1254,16 @@ void AArch64GenProEpilog::GeneratePushRegs() { CHECK_FATAL(*it == RLR, "The second callee saved reg is expected to be RLR"); ++it; - auto offset = static_cast((static_cast(cgFunc.GetMemlayout())->RealStackFrameSize() - - (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */)) - - cgFunc.GetMemlayout()->SizeOfArgsToStackPass()); + AArch64MemLayout *memLayout = static_cast(cgFunc.GetMemlayout()); + int32 offset; + if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + offset = static_cast(memLayout->RealStackFrameSize() - + aarchCGFunc.SizeOfCalleeSaved() - memLayout->GetSizeOfLocals()); + } else { + offset = static_cast(memLayout->RealStackFrameSize() - + (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */) - + memLayout->SizeOfArgsToStackPass()); + } if (cgFunc.GetCG()->IsStackProtectorStrong() || cgFunc.GetCG()->IsStackProtectorAll()) { offset -= kAarch64StackPtrAlignment; @@ -1313,10 +1323,19 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { size = kSizeOfPtr; } uint32 dataSizeBits = size * kBitsPerByte; - uint32 offset = static_cast(memlayout->GetGRSaveAreaBaseLoc()); - if (memlayout->GetSizeOfGRSaveArea() % kAarch64StackPtrAlignment) { - offset += size; /* End of area should be aligned. Hole between VR and GR area */ + uint32 offset; + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + offset = static_cast(memlayout->GetGRSaveAreaBaseLoc()); /* SP reference */ + if (memlayout->GetSizeOfGRSaveArea() % kAarch64StackPtrAlignment) { + offset += size; /* End of area should be aligned. Hole between VR and GR area */ + } + } else { + offset = -memlayout->GetSizeOfGRSaveArea(); /* FP reference */ + if (memlayout->GetSizeOfGRSaveArea() % kAarch64StackPtrAlignment) { + offset -= size; + } } + uint32 grSize = -offset; uint32 start_regno = k8BitSize - (memlayout->GetSizeOfGRSaveArea() / size); ASSERT(start_regno <= k8BitSize, "Incorrect starting GR regno for GR Save Area"); for (uint32 i = start_regno + static_cast(R0); i < static_cast(R8); i++) { @@ -1326,16 +1345,25 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { tmpOffset += 8U - (dataSizeBits >> 3); } } - Operand &stackloc = aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); + Operand *stackLoc; + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + stackLoc = &aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); + } else { + stackLoc = aarchCGFunc.GenLmbcFpMemOperand(offset, size); + } RegOperand ® = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(static_cast(i), k64BitSize, kRegTyInt); Insn &inst = - currCG->BuildInstruction(aarchCGFunc.PickStInsn(dataSizeBits, PTY_i64), reg, stackloc); + currCG->BuildInstruction(aarchCGFunc.PickStInsn(dataSizeBits, PTY_i64), reg, *stackLoc); cgFunc.GetCurBB()->AppendInsn(inst); offset += size; } if (!CGOptions::UseGeneralRegOnly()) { - offset = static_cast(memlayout->GetVRSaveAreaBaseLoc()); + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + offset = static_cast(memlayout->GetVRSaveAreaBaseLoc()); + } else { + offset = -(memlayout->GetSizeOfVRSaveArea() + grSize); + } start_regno = k8BitSize - (memlayout->GetSizeOfVRSaveArea() / (size * k2BitSize)); ASSERT(start_regno <= k8BitSize, "Incorrect starting GR regno for VR Save Area"); for (uint32 i = start_regno + static_cast(V0); i < static_cast(V8); i++) { @@ -1345,11 +1373,16 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { tmpOffset += 16U - (dataSizeBits >> 3); } } - Operand &stackloc = aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); + Operand *stackLoc; + if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + stackLoc = &aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); + } else { + stackLoc = aarchCGFunc.GenLmbcFpMemOperand(offset, size); + } RegOperand ® = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(static_cast(i), k64BitSize, kRegTyFloat); Insn &inst = - currCG->BuildInstruction(aarchCGFunc.PickStInsn(dataSizeBits, PTY_f64), reg, stackloc); + currCG->BuildInstruction(aarchCGFunc.PickStInsn(dataSizeBits, PTY_f64), reg, *stackLoc); cgFunc.GetCurBB()->AppendInsn(inst); offset += (size * k2BitSize); } @@ -1389,7 +1422,8 @@ void AArch64GenProEpilog::GenerateProlog(BB &bb) { } // insert .loc for function - if (currCG->GetCGOptions().WithLoc()) { + if (currCG->GetCGOptions().WithLoc() && + (!currCG->GetMIRModule()->IsCModule() || currCG->GetMIRModule()->IsWithDbgInfo())) { MIRFunction *func = &cgFunc.GetFunction(); MIRSymbol *fSym = GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx()); if (currCG->GetCGOptions().WithSrc()) { @@ -1649,11 +1683,17 @@ void AArch64GenProEpilog::AppendInstructionDeallocateCallFrameDebug(AArch64reg r * ldp/stp's imm should be within -512 and 504; * if ldp's imm > 504, we fall back to the ldp-add version */ - if (cgFunc.HasVLAOrAlloca() || argsToStkPassSize == 0) { - stackFrameSize -= argsToStkPassSize; - if (stackFrameSize > kStpLdpImm64UpperBound) { + bool isLmbc = (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc); + if (cgFunc.HasVLAOrAlloca() || argsToStkPassSize == 0 || isLmbc) { + int lmbcOffset = 0; + if (isLmbc == false) { + stackFrameSize -= argsToStkPassSize; + } else { + lmbcOffset = argsToStkPassSize - (kDivide2 * k8ByteSize); + } + if (stackFrameSize > kStpLdpImm64UpperBound || isLmbc) { Operand *o2; - o2 = aarchCGFunc.CreateStackMemOpnd(RSP, 0, kSizeOfPtr * kBitsPerByte); + o2 = aarchCGFunc.CreateStackMemOpnd(RSP, (isLmbc ? lmbcOffset : 0), kSizeOfPtr * kBitsPerByte); Insn &deallocInsn = currCG->BuildInstruction(mOp, o0, o1, *o2); cgFunc.GetCurBB()->AppendInsn(deallocInsn); if (cgFunc.GenCfi()) { @@ -1728,9 +1768,16 @@ void AArch64GenProEpilog::GeneratePopRegs() { CHECK_FATAL(*it == RLR, "The second callee saved reg is expected to be RLR"); ++it; - int32 offset = static_cast((static_cast(cgFunc.GetMemlayout())->RealStackFrameSize() - - (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */)) - - cgFunc.GetMemlayout()->SizeOfArgsToStackPass()); + AArch64MemLayout *memLayout = static_cast(cgFunc.GetMemlayout()); + int32 offset; + if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + offset = static_cast(memLayout->RealStackFrameSize() - + aarchCGFunc.SizeOfCalleeSaved() - memLayout->GetSizeOfLocals()); + } else { + offset = static_cast(cgFunc.GetMemlayout())->RealStackFrameSize() - + (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */) - + memLayout->SizeOfArgsToStackPass(); + } if (cgFunc.GetCG()->IsStackProtectorStrong() || cgFunc.GetCG()->IsStackProtectorAll()) { offset -= kAarch64StackPtrAlignment; @@ -1821,7 +1868,7 @@ void AArch64GenProEpilog::GenerateEpilog(BB &bb) { Operand &spOpnd = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(RSP, k64BitSize, kRegTyInt); Operand &fpOpnd = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(stackBaseReg, k64BitSize, kRegTyInt); - if (cgFunc.HasVLAOrAlloca()) { + if (cgFunc.HasVLAOrAlloca() && cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { aarchCGFunc.SelectCopy(spOpnd, PTY_u64, fpOpnd, PTY_u64); } diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp index 433cc85754..5ca154b1aa 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp @@ -161,8 +161,7 @@ void AArch64ReachingDefinition::AddRetPseudoInsn(BB &bb) { Insn &retInsn = cgFunc->GetCG()->BuildInstruction(MOP_pseudo_ret_int, regOpnd); bb.AppendInsn(retInsn); pseudoInsns.emplace_back(&retInsn); - } else { - ASSERT(regNO == V0, "CG internal error. Return value should be R0 or V0."); + } else if (regNO == V0) { RegOperand ®Opnd = static_cast(cgFunc)->GetOrCreatePhysicalRegisterOperand(regNO, k64BitSize, kRegTyFloat); Insn &retInsn = cgFunc->GetCG()->BuildInstruction(MOP_pseudo_ret_float, regOpnd); diff --git a/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp b/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp index d2ae2c25c9..bf645c15cd 100644 --- a/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp +++ b/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp @@ -160,6 +160,7 @@ void RecursiveMarkUsedStaticSymbol(const BaseNode *baseNode) { break; } case OP_addrof: + case OP_addrofoff: case OP_dread: { const AddrofNode *dreadNode = static_cast(baseNode); MarkUsedStaticSymbol(dreadNode->GetStIdx()); diff --git a/src/mapleall/maple_be/src/cg/cgfunc.cpp b/src/mapleall/maple_be/src/cg/cgfunc.cpp index 50ecb583a7..b520229206 100644 --- a/src/mapleall/maple_be/src/cg/cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/cgfunc.cpp @@ -1145,7 +1145,11 @@ void HandleReturn(StmtNode &stmt, CGFunc &cgFunc) { ASSERT(retNode.NumOpnds() <= 1, "NYI return nodes number > 1"); Operand *opnd = nullptr; if (retNode.NumOpnds() != 0) { - opnd = cgFunc.HandleExpr(retNode, *retNode.Opnd(0)); + if (!cgFunc.GetFunction().StructReturnedInRegs()) { + opnd = cgFunc.HandleExpr(retNode, *retNode.Opnd(0)); + } else { + cgFunc.SelectReturnSendOfStructInRegs(retNode.Opnd(0)); + } } cgFunc.SelectReturn(opnd); cgFunc.SetCurBBKind(BB::kBBReturn); @@ -1561,15 +1565,16 @@ void CGFunc::CreateLmbcFormalParamInfo() { PrimType primType; uint32 offset; uint32 typeSize; - MIRFunction &mirFunc = GetFunction(); - if (mirFunc.GetParamSize() > 0) { + MIRFunction &func = GetFunction(); + if (func.GetFormalCount() > 0) { + /* Whenever lmbc cannot delete call type info, the prototype is available */ uint32 stackOffset = 0; - for (size_t idx = 0; idx < mirFunc.GetParamSize(); ++idx) { - MIRSymbol *sym = mirFunc.GetFormal(idx); + for (size_t idx = 0; idx < func.GetFormalCount(); ++idx) { + MIRSymbol *sym = func.GetFormal(idx); MIRType *type; TyIdx tyIdx; if (sym) { - tyIdx = mirFunc.GetNthParamTyIdx(idx); + tyIdx = func.GetFormalDefVec()[idx].formalTyIdx; type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); } else { FormalDef vec = const_cast(GetBecommon().GetMIRModule().CurFunction())->GetFormalDefAt(idx); @@ -1616,6 +1621,9 @@ void CGFunc::CreateLmbcFormalParamInfo() { } IreadFPoffNode *ireadNode = static_cast(operand); primType = ireadNode->GetPrimType(); + if (ireadNode->GetOffset() < 0) { + continue; + } offset = static_cast(ireadNode->GetOffset()); typeSize = GetPrimTypeSize(primType); CHECK_FATAL((offset % k8ByteSize) == 0, ""); /* scalar only, no struct for now */ @@ -1627,6 +1635,31 @@ void CGFunc::CreateLmbcFormalParamInfo() { [] (LmbcFormalParamInfo *x, LmbcFormalParamInfo *y) { return x->GetOffset() < y->GetOffset(); } ); + + /* When a scalar param address is taken, its regassign is not in the 1st block */ + for (StmtNode *stmt = func.GetBody()->GetFirst(); stmt != nullptr; stmt = stmt->GetNext()) { + if (stmt == nullptr) { + break; + } + if (stmt->GetOpCode() == OP_label) { + continue; + } + if (stmt->GetOpCode() != OP_regassign) { + break; + } + RegassignNode *regAssignNode = static_cast(stmt); + BaseNode *operand = regAssignNode->Opnd(0); + if (operand->GetOpCode() != OP_ireadfpoff) { + break; + } + IreadFPoffNode *ireadNode = static_cast(operand); + if (ireadNode->GetOffset() < 0) { + continue; + } + LmbcFormalParamInfo *info = GetLmbcFormalParamInfo(ireadNode->GetOffset()); + info->SetHasRegassign(); + } + AssignLmbcFormalParams(); } @@ -1635,7 +1668,7 @@ void CGFunc::GenerateInstruction() { InitHandleStmtFactory(); StmtNode *secondStmt = HandleFirstStmt(); - CreateLmbcFormalParamInfo(); + //CreateLmbcFormalParamInfo(); /* First Pass: Creates the doubly-linked list of BBs (next,prev) */ volReleaseInsn = nullptr; unsigned lastSrcLoc = 0; @@ -2007,6 +2040,7 @@ void CGFunc::HandleFunction() { ASSERT(exitBBVec.size() <= 1, "there are more than one BB_return in func"); } ProcessExitBBVec(); + LmbcGenSaveSpForAlloca(); if (func.IsJava()) { GenerateCleanupCodeForExtEpilog(*cleanupBB); diff --git a/src/mapleall/maple_be/src/cg/emit.cpp b/src/mapleall/maple_be/src/cg/emit.cpp index cfe3ccfd7b..97bf901870 100644 --- a/src/mapleall/maple_be/src/cg/emit.cpp +++ b/src/mapleall/maple_be/src/cg/emit.cpp @@ -2170,6 +2170,11 @@ void Emitter::EmitGlobalVar(const MIRSymbol &globalVar) { } void Emitter::EmitGlobalVars(std::vector> &globalVars) { + if (GetCG()->IsLmbc() && GetCG()->GetGP() != nullptr) { + Emit(asmInfo->GetLocal()).Emit("\t").Emit(GetCG()->GetGP()->GetName()).Emit("\n"); + Emit(asmInfo->GetComm()).Emit("\t").Emit(GetCG()->GetGP()->GetName()); + Emit(", ").Emit(GetCG()->GetMIRModule()->GetGlobalMemSize()).Emit(", ").Emit("8\n"); + } /* load globalVars profile */ if (globalVars.empty()) { return; diff --git a/src/mapleall/maple_be/src/cg/memlayout.cpp b/src/mapleall/maple_be/src/cg/memlayout.cpp index 57e45e8a2d..1b636207c6 100644 --- a/src/mapleall/maple_be/src/cg/memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/memlayout.cpp @@ -38,7 +38,7 @@ uint32 MemLayout::FindLargestActualArea(int32 &aggCopySize) { uint32 maxCopyStackSize = 0; // Size of aggregate param stack copy requirement for (; stmt != nullptr; stmt = stmt->GetNext()) { Opcode opCode = stmt->GetOpCode(); - if (opCode < OP_call || opCode > OP_xintrinsiccallassigned) { + if ((opCode < OP_call || opCode > OP_xintrinsiccallassigned) && opCode != OP_icallproto) { continue; } if (opCode == OP_intrinsiccallwithtypeassigned || opCode == OP_intrinsiccallwithtype || @@ -54,9 +54,9 @@ uint32 MemLayout::FindLargestActualArea(int32 &aggCopySize) { * if the following check fails, most likely dex has invoke-custom etc * that is not supported yet */ - DCHECK((opCode == OP_call || opCode == OP_icall), "Not lowered to call or icall?"); + DCHECK((opCode == OP_call || opCode == OP_icall || opCode == OP_icallproto), "Not lowered to call or icall?"); int32 copySize; - uint32 size = ComputeStackSpaceRequirementForCall(*stmt, copySize, opCode == OP_icall); + uint32 size = ComputeStackSpaceRequirementForCall(*stmt, copySize, opCode == OP_icall || opCode == OP_icallproto); if (size > maxParamStackSize) { maxParamStackSize = size; } diff --git a/src/mapleall/maple_ir/include/bin_mpl_export.h b/src/mapleall/maple_ir/include/bin_mpl_export.h index 09952cb8c7..f12bec7081 100644 --- a/src/mapleall/maple_ir/include/bin_mpl_export.h +++ b/src/mapleall/maple_ir/include/bin_mpl_export.h @@ -67,8 +67,8 @@ enum : uint8 { kBinEaCgStart = 41, kBinEaStart = 42, kBinNodeBlock = 43, - kBinOpStatement = 44, - kBinOpExpression = 45, +//kBinOpStatement = 44, +//kBinOpExpression = 45, kBinReturnvals = 46, kBinTypeTabStart = 47, kBinSymStart = 48, @@ -76,14 +76,14 @@ enum : uint8 { kBinFuncIdInfoStart = 50, kBinFormalStart = 51, kBinPreg = 52, - kBinPregStart = 53, - kBinLabelStart = 54, + kBinSpecialReg = 53, + kBinLabel = 54, kBinTypenameStart = 55, kBinHeaderStart = 56, kBinAliasMapStart = 57, - kBinKindTypeViaTypename = 58, - kBinKindSymViaSymname = 59, - kBinKindFuncViaSymname = 60, +//kBinKindTypeViaTypename = 58, +//kBinKindSymViaSymname = 59, +//kBinKindFuncViaSymname = 60, kBinFunctionBodyStart = 61, kBinFormalWordsTypeTagged = 62, kBinFormalWordsRefCounted = 63, @@ -103,8 +103,7 @@ class BinaryMplExport { void Export(const std::string &fname, std::unordered_set *dumpFuncSet); void WriteNum(int64 x); void Write(uint8 b); - void OutputType(TyIdx tyIdx, bool canUseTypename); - void OutputTypeViaTypeName(TyIdx tidx) { OutputType(tidx, true); } + void OutputType(TyIdx tyIdx); void WriteFunctionBodyField(uint64 contentIdx, std::unordered_set *dumpFuncSet); void OutputConst(MIRConst *c); void OutputConstBase(const MIRConst &c); @@ -133,12 +132,11 @@ class BinaryMplExport { void OutputInfoVector(const MIRInfoVector &infoVector, const MapleVector &infoVectorIsString); void OutputFuncIdInfo(MIRFunction *func); void OutputLocalSymbol(MIRSymbol *sym); - void OutputLocalSymTab(const MIRFunction *func); - void OutputPregTab(const MIRFunction *func); - void OutputLabelTab(const MIRFunction *func); + void OutputPreg(MIRPreg *preg); + void OutputLabel(LabelIdx lidx); void OutputLocalTypeNameTab(const MIRTypeNameTable *tyNameTab); void OutputFormalsStIdx(MIRFunction *func); - void OutputFuncViaSymName(PUIdx puIdx); + void OutputFuncViaSym(PUIdx puIdx); void OutputExpression(BaseNode *e); void OutputBaseNode(const BaseNode *b); void OutputReturnValues(const CallReturnVector *retv); @@ -182,6 +180,7 @@ class BinaryMplExport { void ExpandFourBuffSize(); MIRModule &mod; + MIRFunction *curFunc = nullptr; size_t bufI = 0; std::vector buf; std::unordered_map gStrMark; @@ -190,6 +189,9 @@ class BinaryMplExport { std::unordered_map uStrMark; std::unordered_map symMark; std::unordered_map typMark; + std::unordered_map localSymMark; + std::unordered_map localPregMark; + std::unordered_map labelMark; friend class UpdateMplt; std::unordered_map callInfoMark; std::map *func2SEMap = nullptr; diff --git a/src/mapleall/maple_ir/include/bin_mpl_import.h b/src/mapleall/maple_ir/include/bin_mpl_import.h index 3697654872..ee7f909f9b 100644 --- a/src/mapleall/maple_ir/include/bin_mpl_import.h +++ b/src/mapleall/maple_ir/include/bin_mpl_import.h @@ -126,15 +126,14 @@ class BinaryMplImport { void ImportInfoVector(MIRInfoVector &infoVector, MapleVector &infoVectorIsString); void ImportLocalTypeNameTable(MIRTypeNameTable *typeNameTab); void ImportFuncIdInfo(MIRFunction *func); - void ImportLocalSymbol(MIRFunction *func); - void ImportLocalSymTab(MIRFunction *func); - void ImportPregTab(const MIRFunction *func); - void ImportLabelTab(MIRFunction *func); + MIRSymbol *ImportLocalSymbol(MIRFunction *func); + PregIdx ImportPreg(MIRFunction *func); + LabelIdx ImportLabel(MIRFunction *func); void ImportFormalsStIdx(MIRFunction *func); void ImportAliasMap(MIRFunction *func); void ImportSrcPos(SrcPosition &pos); void ImportBaseNode(Opcode &o, PrimType &typ); - PUIdx ImportFuncViaSymName(); + PUIdx ImportFuncViaSym(MIRFunction *func); BaseNode *ImportExpression(MIRFunction *func); void ImportReturnValues(MIRFunction *func, CallReturnVector *retv); BlockNode *ImportBlockNode(MIRFunction *fn); @@ -162,6 +161,9 @@ class BinaryMplImport { std::vector typTab; std::vector funcTab; std::vector symTab; + std::vector localSymTab; + std::vector localPregTab; + std::vector localLabelTab; std::vector callInfoTab; std::vector eaCgTab; std::vector methodSymbols; diff --git a/src/mapleall/maple_ir/include/ir_safe_cast_traits.def b/src/mapleall/maple_ir/include/ir_safe_cast_traits.def index 1439b49d57..14ed1a367b 100644 --- a/src/mapleall/maple_ir/include/ir_safe_cast_traits.def +++ b/src/mapleall/maple_ir/include/ir_safe_cast_traits.def @@ -224,7 +224,9 @@ REGISTER_SAFE_CAST(CallNode, from.GetOpCode() == OP_call || from.GetOpCode() == OP_virtualicallassigned || instance_of(from)); REGISTER_SAFE_CAST(IcallNode, from.GetOpCode() == OP_icall || - from.GetOpCode() == OP_icallassigned); + from.GetOpCode() == OP_icallassigned || + from.GetOpCode() == OP_icallproto || + from.GetOpCode() == OP_icallprotoassigned); REGISTER_SAFE_CAST(IntrinsiccallNode, from.GetOpCode() == OP_intrinsiccall || from.GetOpCode() == OP_intrinsiccallwithtype || from.GetOpCode() == OP_xintrinsiccall || diff --git a/src/mapleall/maple_ir/include/keywords.def b/src/mapleall/maple_ir/include/keywords.def index eddff2f80a..51a603eafa 100644 --- a/src/mapleall/maple_ir/include/keywords.def +++ b/src/mapleall/maple_ir/include/keywords.def @@ -55,7 +55,6 @@ // per-function declaration keywords KEYWORD(framesize) KEYWORD(upformalsize) - KEYWORD(outparmsize) KEYWORD(moduleid) KEYWORD(funcsize) KEYWORD(funcid) diff --git a/src/mapleall/maple_ir/include/mir_builder.h b/src/mapleall/maple_ir/include/mir_builder.h index 5e6efdf9ff..b7d42cb431 100755 --- a/src/mapleall/maple_ir/include/mir_builder.h +++ b/src/mapleall/maple_ir/include/mir_builder.h @@ -262,6 +262,8 @@ class MIRBuilder { IcallNode *CreateStmtIcall(const MapleVector &args); IcallNode *CreateStmtIcallAssigned(const MapleVector &args, const MIRSymbol &ret); + IcallNode *CreateStmtIcallproto(const MapleVector &args); + IcallNode *CreateStmtIcallprotoAssigned(const MapleVector &args, const MIRSymbol &ret); // For Call, VirtualCall, SuperclassCall, InterfaceCall IntrinsiccallNode *CreateStmtIntrinsicCall(MIRIntrinsicID idx, const MapleVector &arguments, TyIdx tyIdx = TyIdx()); diff --git a/src/mapleall/maple_ir/include/mir_function.h b/src/mapleall/maple_ir/include/mir_function.h index 256efff6d7..7832995ca4 100644 --- a/src/mapleall/maple_ir/include/mir_function.h +++ b/src/mapleall/maple_ir/include/mir_function.h @@ -830,24 +830,24 @@ class MIRFunction { callTimes = times; } - uint16 GetFrameSize() const { + uint32 GetFrameSize() const { return frameSize; } - void SetFrameSize(uint16 size) { + void SetFrameSize(uint32 size) { frameSize = size; } - uint16 GetUpFormalSize() const { + uint32 GetUpFormalSize() const { return upFormalSize; } - void SetUpFormalSize(uint16 size) { + void SetUpFormalSize(uint32 size) { upFormalSize = size; } - uint16 GetOutParmSize() const { + uint32 GetOutParmSize() const { return outParmSize; } - void SetOutParmSize(uint16 size) { + void SetOutParmSize(uint32 size) { outParmSize = size; } @@ -1298,9 +1298,9 @@ class MIRFunction { bool isDirty = false; bool fromMpltInline = false; // Whether this function is imported from mplt_inline file or not. uint8_t layoutType = kLayoutUnused; - uint16 frameSize = 0; - uint16 upFormalSize = 0; - uint16 outParmSize = 0; + uint32 frameSize = 0; + uint32 upFormalSize = 0; + uint32 outParmSize = 0; uint16 moduleID = 0; uint32 funcSize = 0; // size of code in words uint32 tempCount = 0; diff --git a/src/mapleall/maple_ir/include/mir_lower.h b/src/mapleall/maple_ir/include/mir_lower.h index 332a6de89f..be479f65a6 100644 --- a/src/mapleall/maple_ir/include/mir_lower.h +++ b/src/mapleall/maple_ir/include/mir_lower.h @@ -86,6 +86,7 @@ class MIRLower { ForeachelemNode *ExpandArrayMrtForeachelemBlock(ForeachelemNode &node); BlockNode *ExpandArrayMrtBlock(BlockNode &block); void AddArrayMrtMpl(BaseNode &exp, BlockNode &newblk); + MIRFuncType *FuncTypeFromFuncPtrExpr(BaseNode *x); void SetLowerME() { lowerPhase |= kShiftLowerMe; } diff --git a/src/mapleall/maple_ir/include/mir_nodes.h b/src/mapleall/maple_ir/include/mir_nodes.h index 987aee44f6..98cb801afb 100755 --- a/src/mapleall/maple_ir/include/mir_nodes.h +++ b/src/mapleall/maple_ir/include/mir_nodes.h @@ -3304,7 +3304,7 @@ class CallNode : public NaryStmtNode { CallReturnVector returnValues; }; -// icall and icallproto +// icall, icallassigned, icallproto and icallprotoassigned class IcallNode : public NaryStmtNode { public: IcallNode(MapleAllocator &allocator, Opcode o) diff --git a/src/mapleall/maple_ir/include/mir_parser.h b/src/mapleall/maple_ir/include/mir_parser.h index 10d1dd028a..b49370d0ff 100755 --- a/src/mapleall/maple_ir/include/mir_parser.h +++ b/src/mapleall/maple_ir/include/mir_parser.h @@ -134,6 +134,7 @@ class MIRParser { bool ParseStmtIcall(StmtNodePtr&); bool ParseStmtIcallassigned(StmtNodePtr&); bool ParseStmtIcallproto(StmtNodePtr&); + bool ParseStmtIcallprotoassigned(StmtNodePtr&); bool ParseStmtIntrinsiccall(StmtNodePtr&, bool isAssigned); bool ParseStmtIntrinsiccall(StmtNodePtr&); bool ParseStmtIntrinsiccallassigned(StmtNodePtr&); @@ -291,7 +292,6 @@ class MIRParser { bool ParseStmtBlockForType(); bool ParseStmtBlockForFrameSize(); bool ParseStmtBlockForUpformalSize(); - bool ParseStmtBlockForOutParmSize(); bool ParseStmtBlockForModuleID(); bool ParseStmtBlockForFuncSize(); bool ParseStmtBlockForFuncID(); diff --git a/src/mapleall/maple_ir/include/mir_symbol.h b/src/mapleall/maple_ir/include/mir_symbol.h index 0d1d127dbe..357242d0e2 100644 --- a/src/mapleall/maple_ir/include/mir_symbol.h +++ b/src/mapleall/maple_ir/include/mir_symbol.h @@ -484,12 +484,11 @@ class MIRSymbol { return false; } switch (storageClass) { - case kScFormal: case kScAuto: return true; case kScPstatic: case kScFstatic: - return value.konst == nullptr; + return value.konst == nullptr && !hasPotentialAssignment; default: return false; } @@ -638,7 +637,8 @@ class MIRLabelTable { LabelIdx CreateLabel() { LabelIdx labelIdx = labelTable.size(); - labelTable.push_back(GStrIdx(0)); // insert dummy global string index for anonymous label + GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(std::to_string(labelIdx)); + labelTable.push_back(strIdx); return labelIdx; } diff --git a/src/mapleall/maple_ir/include/mir_type.h b/src/mapleall/maple_ir/include/mir_type.h index c5245d568c..197e7d3ca2 100644 --- a/src/mapleall/maple_ir/include/mir_type.h +++ b/src/mapleall/maple_ir/include/mir_type.h @@ -1189,14 +1189,6 @@ class MIRStructType : public MIRType { isImported = flag; } - bool IsUsed() const { - return isUsed; - } - - void SetIsUsed(bool flag) { - isUsed = flag; - } - bool IsCPlusPlus() const { return isCPlusPlus; } @@ -1368,7 +1360,6 @@ class MIRStructType : public MIRType { vTableMethods.clear(); iTableMethods.clear(); isImported = false; - isUsed = false; hasVolatileField = false; hasVolatileFieldSet = false; } @@ -1471,7 +1462,6 @@ class MIRStructType : public MIRType { // implementation functions, For interfaces, they are abstact functions. // Weak indicates the actual definition is in another module. bool isImported = false; - bool isUsed = false; bool isCPlusPlus = false; // empty struct in C++ has size 1 byte mutable bool hasVolatileField = false; // for caching computed value mutable bool hasVolatileFieldSet = false; // if true, just read hasVolatileField; @@ -1928,11 +1918,19 @@ class MIRFuncType : public MIRType { } bool IsVarargs() const { - return isVarArgs; + return funcAttrs.GetAttr(FUNCATTR_varargs); } - void SetVarArgs(bool flag) { - isVarArgs = flag; + void SetVarArgs() { + funcAttrs.SetAttr(FUNCATTR_varargs); + } + + bool FirstArgReturn() const { + return funcAttrs.GetAttr(FUNCATTR_firstarg_return); + } + + void SetFirstArgReturn() { + funcAttrs.SetAttr(FUNCATTR_firstarg_return); } const TypeAttrs &GetRetAttrs() const { @@ -1960,7 +1958,8 @@ class MIRFuncType : public MIRType { std::vector paramTypeList; std::vector paramAttrsList; TypeAttrs retAttrs; - bool isVarArgs = false; + public: + FuncAttrs funcAttrs; }; class MIRTypeByName : public MIRType { diff --git a/src/mapleall/maple_ir/include/opcode_info.h b/src/mapleall/maple_ir/include/opcode_info.h index 814f15b2f2..5a82646b11 100644 --- a/src/mapleall/maple_ir/include/opcode_info.h +++ b/src/mapleall/maple_ir/include/opcode_info.h @@ -117,6 +117,7 @@ class OpcodeTable { bool IsICall(Opcode o) const { ASSERT(o < OP_last, "invalid opcode"); return o == OP_icall || o == OP_icallassigned || + o == OP_icallproto || o == OP_icallprotoassigned || o == OP_virtualicall || o == OP_virtualicallassigned || o == OP_interfaceicall || o == OP_interfaceicallassigned; } diff --git a/src/mapleall/maple_ir/include/opcodes.def b/src/mapleall/maple_ir/include/opcodes.def index 34cfb51c8d..0e842141ed 100755 --- a/src/mapleall/maple_ir/include/opcodes.def +++ b/src/mapleall/maple_ir/include/opcodes.def @@ -221,3 +221,4 @@ OPCODE(iassignspoff, IassignFPoffNode, OPCODEISSTMT, 8) OPCODE(blkassignoff, BlkassignoffNode, OPCODEISSTMT, 8) OPCODE(icallproto, IcallNode, (OPCODEISSTMT | OPCODEISVARSIZE | OPCODEHASSSAUSE | OPCODEHASSSADEF | OPCODEISCALL), 8) + OPCODE(icallprotoassigned, IcallNode, (OPCODEISSTMT | OPCODEISVARSIZE | OPCODEHASSSAUSE | OPCODEHASSSADEF | OPCODEISCALL | OPCODEISCALLASSIGNED), 8) diff --git a/src/mapleall/maple_ir/include/opcodes.h b/src/mapleall/maple_ir/include/opcodes.h index ea4ed2c1c9..b9f5e0f8c5 100644 --- a/src/mapleall/maple_ir/include/opcodes.h +++ b/src/mapleall/maple_ir/include/opcodes.h @@ -50,7 +50,7 @@ inline constexpr bool IsCallAssigned(Opcode code) { code == OP_virtualicallassigned || code == OP_superclasscallassigned || code == OP_interfacecallassigned || code == OP_interfaceicallassigned || code == OP_customcallassigned || code == OP_polymorphiccallassigned || - code == OP_icallassigned || code == OP_intrinsiccallassigned || + code == OP_icallassigned || code == OP_icallprotoassigned || code == OP_intrinsiccallassigned || code == OP_xintrinsiccallassigned || code == OP_intrinsiccallwithtypeassigned); } @@ -113,6 +113,8 @@ constexpr bool IsStmtMustRequire(Opcode opcode) { case OP_polymorphiccallassigned: case OP_icall: case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: case OP_intrinsiccall: case OP_xintrinsiccall: case OP_intrinsiccallassigned: diff --git a/src/mapleall/maple_ir/src/bin_func_export.cpp b/src/mapleall/maple_ir/src/bin_func_export.cpp index 263ef34c80..6815c8151d 100644 --- a/src/mapleall/maple_ir/src/bin_func_export.cpp +++ b/src/mapleall/maple_ir/src/bin_func_export.cpp @@ -24,6 +24,10 @@ using namespace std; namespace maple { void BinaryMplExport::OutputInfoVector(const MIRInfoVector &infoVector, const MapleVector &infoVectorIsString) { + if (!mod.IsWithDbgInfo()) { + Write(0); + return; + } WriteNum(infoVector.size()); for (uint32 i = 0; i < infoVector.size(); i++) { OutputStr(infoVector[i].first); @@ -41,99 +45,73 @@ void BinaryMplExport::OutputFuncIdInfo(MIRFunction *func) { WriteNum(func->GetPuidxOrigin()); // the funcid OutputInfoVector(func->GetInfoVector(), func->InfoIsString()); if (mod.GetFlavor() == kFlavorLmbc) { - WriteNum(func->GetUpFormalSize()); WriteNum(func->GetFrameSize()); - WriteNum(func->GetOutParmSize()); } - WriteNum(~kBinFuncIdInfoStart); } void BinaryMplExport::OutputBaseNode(const BaseNode *b) { - WriteNum(b->GetOpCode()); - WriteNum(b->GetPrimType()); + Write(static_cast(b->GetOpCode())); + Write(static_cast(b->GetPrimType())); } void BinaryMplExport::OutputLocalSymbol(MIRSymbol *sym) { - if (sym == nullptr) { - WriteNum(0); + std::unordered_map::iterator it = localSymMark.find(sym); + if (it != localSymMark.end()) { + WriteNum(-(it->second)); return; } + WriteNum(kBinSymbol); - WriteNum(sym->GetStIndex()); // preserve original st index OutputStr(sym->GetNameStrIdx()); WriteNum(sym->GetSKind()); WriteNum(sym->GetStorageClass()); + size_t mark = localSymMark.size(); + localSymMark[sym] = mark; OutputTypeAttrs(sym->GetAttrs()); WriteNum(static_cast(sym->GetIsTmp())); if (sym->GetSKind() == kStVar || sym->GetSKind() == kStFunc) { OutputSrcPos(sym->GetSrcPosition()); } - OutputTypeViaTypeName(sym->GetTyIdx()); + OutputType(sym->GetTyIdx()); if (sym->GetSKind() == kStPreg) { - WriteNum(sym->GetPreg()->GetPregNo()); + OutputPreg(sym->GetPreg()); } else if (sym->GetSKind() == kStConst || sym->GetSKind() == kStVar) { OutputConst(sym->GetKonst()); } else if (sym->GetSKind() == kStFunc) { - OutputFuncViaSymName(sym->GetFunction()->GetPuidx()); - OutputTypeViaTypeName(sym->GetTyIdx()); + OutputFuncViaSym(sym->GetFunction()->GetPuidx()); } else { CHECK_FATAL(false, "should not used"); } } -void BinaryMplExport::OutputLocalSymTab(const MIRFunction *func) { - WriteNum(kBinSymStart); - uint64 outsymSizeIdx = buf.size(); - ExpandFourBuffSize(); /// size of OutSym - int32 size = 0; - - for (uint32 i = 1; i < func->GetSymTab()->GetSymbolTableSize(); i++) { - MIRSymbol *s = func->GetSymTab()->GetSymbolFromStIdx(i); - ASSERT(s != nullptr, "null ptr check"); - if (s->IsDeleted()) { - OutputLocalSymbol(nullptr); - } else { - OutputLocalSymbol(s); - } - size++; +void BinaryMplExport::OutputPreg(MIRPreg *preg) { + if (preg->GetPregNo() < 0) { + WriteNum(kBinSpecialReg); + Write(-preg->GetPregNo()); + return; } - - Fixup(outsymSizeIdx, size); - WriteNum(~kBinSymStart); -} - -void BinaryMplExport::OutputPregTab(const MIRFunction *func) { - WriteNum(kBinPregStart); - uint64 outRegSizeIdx = buf.size(); - ExpandFourBuffSize(); /// size of OutReg - int32 size = 0; - - for (uint32 i = 1; i < func->GetPregTab()->Size(); ++i) { - MIRPreg *mirpreg = func->GetPregTab()->PregFromPregIdx(static_cast(i)); - if (mirpreg == nullptr) { - WriteNum(0); - size++; - continue; - } - WriteNum(kBinPreg); - WriteNum(mirpreg->GetPregNo()); - TyIdx tyIdx = (mirpreg->GetMIRType() == nullptr) ? TyIdx(0) : mirpreg->GetMIRType()->GetTypeIndex(); - OutputTypeViaTypeName(tyIdx); - WriteNum(mirpreg->GetPrimType()); - size++; + std::unordered_map::iterator it = localPregMark.find(preg); + if (it != localPregMark.end()) { + WriteNum(-(it->second)); + return; } - Fixup(outRegSizeIdx, size); - WriteNum(~kBinPregStart); + WriteNum(kBinPreg); + Write(static_cast(preg->GetPrimType())); + size_t mark = localPregMark.size(); + localPregMark[preg] = mark; } -void BinaryMplExport::OutputLabelTab(const MIRFunction *func) { - WriteNum(kBinLabelStart); - WriteNum(static_cast(func->GetLabelTab()->Size()-1)); // entry 0 is skipped - for (uint32 i = 1; i < func->GetLabelTab()->Size(); i++) { - OutputStr(func->GetLabelTab()->GetLabelTable()[i]); +void BinaryMplExport::OutputLabel(LabelIdx lidx) { + std::unordered_map::iterator it = labelMark.find(lidx); + if (it != labelMark.end()) { + WriteNum(-(it->second)); + return; } - WriteNum(~kBinLabelStart); + + WriteNum(kBinLabel); + size_t mark = labelMark.size(); + labelMark[lidx] = mark; } void BinaryMplExport::OutputLocalTypeNameTab(const MIRTypeNameTable *typeNameTab) { @@ -141,18 +119,16 @@ void BinaryMplExport::OutputLocalTypeNameTab(const MIRTypeNameTable *typeNameTab WriteNum(static_cast(typeNameTab->Size())); for (std::pair it : typeNameTab->GetGStrIdxToTyIdxMap()) { OutputStr(it.first); - OutputTypeViaTypeName(it.second); + OutputType(it.second); } - WriteNum(~kBinTypenameStart); } void BinaryMplExport::OutputFormalsStIdx(MIRFunction *func) { WriteNum(kBinFormalStart); WriteNum(func->GetFormalDefVec().size()); for (FormalDef formalDef : func->GetFormalDefVec()) { - WriteNum(formalDef.formalSym->GetStIndex()); + OutputLocalSymbol(formalDef.formalSym); } - WriteNum(~kBinFormalStart); } void BinaryMplExport::OutputAliasMap(MapleMap &aliasVarMap) { @@ -161,21 +137,18 @@ void BinaryMplExport::OutputAliasMap(MapleMap &aliasVarMa for (std::pair it : aliasVarMap) { OutputStr(it.first); OutputStr(it.second.memPoolStrIdx); - OutputTypeViaTypeName(it.second.tyIdx); + OutputType(it.second.tyIdx); OutputStr(it.second.sigStrIdx); } - WriteNum(~kBinAliasMapStart); } -void BinaryMplExport::OutputFuncViaSymName(PUIdx puIdx) { +void BinaryMplExport::OutputFuncViaSym(PUIdx puIdx) { MIRFunction *func = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx()); - WriteNum(kBinKindFuncViaSymname); - OutputStr(funcSt->GetNameStrIdx()); + OutputSymbol(funcSt); } void BinaryMplExport::OutputExpression(BaseNode *e) { - WriteNum(kBinOpExpression); OutputBaseNode(e); switch (e->GetOpCode()) { // leaf @@ -191,17 +164,17 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { } case OP_addroflabel: { AddroflabelNode *lNode = static_cast(e); - WriteNum(lNode->GetOffset()); + OutputLabel(lNode->GetOffset()); return; } case OP_addroffunc: { AddroffuncNode *addrNode = static_cast(e); - OutputFuncViaSymName(addrNode->GetPUIdx()); + OutputFuncViaSym(addrNode->GetPUIdx()); return; } case OP_sizeoftype: { SizeoftypeNode *sot = static_cast(e); - OutputTypeViaTypeName(sot->GetTyIdx()); + OutputType(sot->GetTyIdx()); return; } case OP_addrof: @@ -220,24 +193,23 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { } WriteNum(stIdx.Scope()); if (stIdx.Islocal()) { - WriteNum(stIdx.Idx()); // preserve original st index + OutputLocalSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx)); } else { - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(stIdx.Idx()); - WriteNum(kBinKindSymViaSymname); - OutputStr(sym->GetNameStrIdx()); + OutputSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx)); } return; } case OP_regread: { RegreadNode *regreadNode = static_cast(e); - WriteNum(regreadNode->GetRegIdx()); + MIRPreg *preg = curFunc->GetPregTab()->PregFromPregIdx(regreadNode->GetRegIdx()); + OutputPreg(preg); return; } case OP_gcmalloc: case OP_gcpermalloc: case OP_stackmalloc: { GCMallocNode *gcNode = static_cast(e); - OutputTypeViaTypeName(gcNode->GetTyIdx()); + OutputType(gcNode->GetTyIdx()); return; } // unary @@ -246,18 +218,18 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { case OP_floor: case OP_trunc: { TypeCvtNode *typecvtNode = static_cast(e); - WriteNum(typecvtNode->FromType()); + Write(static_cast(typecvtNode->FromType())); break; } case OP_retype: { RetypeNode *retypeNode = static_cast(e); - OutputTypeViaTypeName(retypeNode->GetTyIdx()); + OutputType(retypeNode->GetTyIdx()); break; } case OP_iread: case OP_iaddrof: { IreadNode *irNode = static_cast(e); - OutputTypeViaTypeName(irNode->GetTyIdx()); + OutputType(irNode->GetTyIdx()); WriteNum(irNode->GetFieldID()); break; } @@ -275,20 +247,20 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { case OP_zext: case OP_extractbits: { ExtractbitsNode *extNode = static_cast(e); - WriteNum(extNode->GetBitsOffset()); - WriteNum(extNode->GetBitsSize()); + Write(extNode->GetBitsOffset()); + Write(extNode->GetBitsSize()); break; } case OP_depositbits: { DepositbitsNode *dbNode = static_cast(e); - WriteNum(dbNode->GetBitsOffset()); - WriteNum(dbNode->GetBitsSize()); + Write(dbNode->GetBitsOffset()); + Write(dbNode->GetBitsSize()); break; } case OP_gcmallocjarray: case OP_gcpermallocjarray: { JarrayMallocNode *gcNode = static_cast(e); - OutputTypeViaTypeName(gcNode->GetTyIdx()); + OutputType(gcNode->GetTyIdx()); break; } // binary @@ -321,13 +293,13 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { case OP_cmpl: case OP_cmp: { CompareNode *cmpNode = static_cast(e); - WriteNum(cmpNode->GetOpndType()); + Write(static_cast(cmpNode->GetOpndType())); break; } case OP_resolveinterfacefunc: case OP_resolvevirtualfunc: { ResolveFuncNode *rsNode = static_cast(e); - OutputFuncViaSymName(rsNode->GetPuIdx()); + OutputFuncViaSym(rsNode->GetPuIdx()); break; } // ternary @@ -337,8 +309,8 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { // nary case OP_array: { ArrayNode *arrNode = static_cast(e); - OutputTypeViaTypeName(arrNode->GetTyIdx()); - WriteNum(static_cast(arrNode->GetBoundsCheck())); + OutputType(arrNode->GetTyIdx()); + Write(static_cast(arrNode->GetBoundsCheck())); WriteNum(static_cast(arrNode->NumOpnds())); break; } @@ -351,7 +323,7 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { case OP_intrinsicopwithtype: { IntrinsicopNode *intrnNode = static_cast(e); WriteNum(intrnNode->GetIntrinsic()); - OutputTypeViaTypeName(intrnNode->GetTyIdx()); + OutputType(intrnNode->GetTyIdx()); WriteNum(static_cast(intrnNode->NumOpnds())); break; } @@ -366,6 +338,9 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { static SrcPosition lastOutputSrcPosition; void BinaryMplExport::OutputSrcPos(const SrcPosition &pos) { + if (!mod.IsWithDbgInfo()) { + return; + } if (pos.FileNum() == 0 || pos.LineNum() == 0) { // error case, so output 0 WriteNum(lastOutputSrcPosition.RawData()); WriteNum(lastOutputSrcPosition.LineNum()); @@ -380,9 +355,15 @@ void BinaryMplExport::OutputReturnValues(const CallReturnVector *retv) { WriteNum(kBinReturnvals); WriteNum(static_cast(retv->size())); for (uint32 i = 0; i < retv->size(); i++) { - WriteNum((*retv)[i].first.Idx()); - WriteNum((*retv)[i].second.GetFieldID()); - WriteNum((*retv)[i].second.GetPregIdx()); + RegFieldPair rfp = (*retv)[i].second; + if (rfp.IsReg()) { + MIRPreg *preg = curFunc->GetPregTab()->PregFromPregIdx(rfp.GetPregIdx()); + OutputPreg(preg); + } else { + WriteNum(0); + WriteNum((rfp.GetFieldID())); + OutputLocalSymbol(curFunc->GetLocalOrGlobalSymbol((*retv)[i].first)); + } } } @@ -398,7 +379,6 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { ExpandFourBuffSize(); // place holder, Fixup later for (StmtNode *s = block->GetFirst(); s; s = s->GetNext()) { bool doneWithOpnds = false; - WriteNum(kBinOpStatement); OutputSrcPos(s->GetSrcPos()); WriteNum(s->GetOpCode()); switch (s->GetOpCode()) { @@ -417,36 +397,35 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { } WriteNum(stIdx.Scope()); if (stIdx.Islocal()) { - WriteNum(stIdx.Idx()); // preserve original st index + OutputLocalSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx)); } else { - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(stIdx.Idx()); - WriteNum(kBinKindSymViaSymname); - OutputStr(sym->GetNameStrIdx()); + OutputSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx)); } break; } case OP_regassign: { RegassignNode *rass = static_cast(s); - WriteNum(rass->GetPrimType()); - WriteNum(rass->GetRegIdx()); + Write(static_cast(rass->GetPrimType())); + MIRPreg *preg = curFunc->GetPregTab()->PregFromPregIdx(rass->GetRegIdx()); + OutputPreg(preg); break; } case OP_iassign: { IassignNode *iass = static_cast(s); - OutputTypeViaTypeName(iass->GetTyIdx()); + OutputType(iass->GetTyIdx()); WriteNum(iass->GetFieldID()); break; } case OP_iassignoff: { IassignoffNode *iassoff = static_cast(s); - WriteNum(iassoff->GetPrimType()); + Write(static_cast(iassoff->GetPrimType())); WriteNum(iassoff->GetOffset()); break; } case OP_iassignspoff: case OP_iassignfpoff: { IassignFPoffNode *iassfpoff = static_cast(s); - WriteNum(iassfpoff->GetPrimType()); + Write(static_cast(iassfpoff->GetPrimType())); WriteNum(iassfpoff->GetOffset()); break; } @@ -466,9 +445,9 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { case OP_customcall: case OP_polymorphiccall: { CallNode *callnode = static_cast(s); - OutputFuncViaSymName(callnode->GetPUIdx()); + OutputFuncViaSym(callnode->GetPUIdx()); if (s->GetOpCode() == OP_polymorphiccall) { - OutputTypeViaTypeName(static_cast(callnode)->GetTyIdx()); + OutputType(static_cast(callnode)->GetTyIdx()); } WriteNum(static_cast(s->NumOpnds())); break; @@ -481,15 +460,15 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { case OP_interfaceicallassigned: case OP_customcallassigned: { CallNode *callnode = static_cast(s); - OutputFuncViaSymName(callnode->GetPUIdx()); + OutputFuncViaSym(callnode->GetPUIdx()); OutputReturnValues(&callnode->GetReturnVec()); WriteNum(static_cast(s->NumOpnds())); break; } case OP_polymorphiccallassigned: { CallNode *callnode = static_cast(s); - OutputFuncViaSymName(callnode->GetPUIdx()); - OutputTypeViaTypeName(callnode->GetTyIdx()); + OutputFuncViaSym(callnode->GetPUIdx()); + OutputType(callnode->GetTyIdx()); OutputReturnValues(&callnode->GetReturnVec()); WriteNum(static_cast(s->NumOpnds())); break; @@ -497,13 +476,14 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { case OP_icallproto: case OP_icall: { IcallNode *icallnode = static_cast(s); - OutputTypeViaTypeName(icallnode->GetRetTyIdx()); + OutputType(icallnode->GetRetTyIdx()); WriteNum(static_cast(s->NumOpnds())); break; } + case OP_icallprotoassigned: case OP_icallassigned: { IcallNode *icallnode = static_cast(s); - OutputTypeViaTypeName(icallnode->GetRetTyIdx()); + OutputType(icallnode->GetRetTyIdx()); OutputReturnValues(&icallnode->GetReturnVec()); WriteNum(static_cast(s->NumOpnds())); break; @@ -526,14 +506,14 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { case OP_intrinsiccallwithtype: { IntrinsiccallNode *intrnNode = static_cast(s); WriteNum(intrnNode->GetIntrinsic()); - OutputTypeViaTypeName(intrnNode->GetTyIdx()); + OutputType(intrnNode->GetTyIdx()); WriteNum(static_cast(s->NumOpnds())); break; } case OP_intrinsiccallwithtypeassigned: { IntrinsiccallNode *intrnNode = static_cast(s); WriteNum(intrnNode->GetIntrinsic()); - OutputTypeViaTypeName(intrnNode->GetTyIdx()); + OutputType(intrnNode->GetTyIdx()); OutputReturnValues(&intrnNode->GetReturnVec()); WriteNum(static_cast(s->NumOpnds())); break; @@ -568,28 +548,28 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { } case OP_label: { LabelNode *lNode = static_cast(s); - WriteNum(lNode->GetLabelIdx()); + OutputLabel(lNode->GetLabelIdx()); break; } case OP_goto: case OP_gosub: { GotoNode *gtoNode = static_cast(s); - WriteNum(gtoNode->GetOffset()); + OutputLabel(gtoNode->GetOffset()); break; } case OP_brfalse: case OP_brtrue: { CondGotoNode *cgotoNode = static_cast(s); - WriteNum(cgotoNode->GetOffset()); + OutputLabel(cgotoNode->GetOffset()); break; } case OP_switch: { SwitchNode *swNode = static_cast(s); - WriteNum(swNode->GetDefaultLabel()); + OutputLabel(swNode->GetDefaultLabel()); WriteNum(static_cast(swNode->GetSwitchTable().size())); for (CasePair cpair : swNode->GetSwitchTable()) { WriteNum(cpair.first); - WriteNum(cpair.second); + OutputLabel(cpair.second); } break; } @@ -599,14 +579,14 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { WriteNum(static_cast(rgoto->GetRangeGotoTable().size())); for (SmallCasePair cpair : rgoto->GetRangeGotoTable()) { WriteNum(cpair.first); - WriteNum(cpair.second); + OutputLabel(cpair.second); } break; } case OP_jstry: { JsTryNode *tryNode = static_cast(s); - WriteNum(tryNode->GetCatchOffset()); - WriteNum(tryNode->GetFinallyOffset()); + OutputLabel(tryNode->GetCatchOffset()); + OutputLabel(tryNode->GetFinallyOffset()); break; } case OP_cpptry: @@ -614,7 +594,7 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { TryNode *tryNode = static_cast(s); WriteNum(static_cast(tryNode->GetOffsetsCount())); for (LabelIdx lidx : tryNode->GetOffsets()) { - WriteNum(lidx); + OutputLabel(lidx); } break; } @@ -622,7 +602,7 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { CatchNode *catchNode = static_cast(s); WriteNum(static_cast(catchNode->GetExceptionTyIdxVec().size())); for (TyIdx tidx : catchNode->GetExceptionTyIdxVec()) { - OutputTypeViaTypeName(tidx); + OutputType(tidx); } break; } @@ -679,7 +659,7 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { count = asmNode->gotoLabels.size(); WriteNum(static_cast(count)); for (size_t i = 0; i < count; ++i) { - WriteNum(asmNode->gotoLabels[i]); + OutputLabel(asmNode->gotoLabels[i]); } // the inputs WriteNum(asmNode->NumOpnds()); @@ -714,6 +694,7 @@ void BinaryMplExport::WriteFunctionBodyField(uint64 contentIdx, std::unordered_s if (not2mplt) { for (MIRFunction *func : GetMIRModule().GetFunctionList()) { + curFunc = func; if (func->GetAttr(FUNCATTR_optimized)) { continue; } @@ -734,12 +715,15 @@ void BinaryMplExport::WriteFunctionBodyField(uint64 contentIdx, std::unordered_s continue; } } + localSymMark.clear(); + localSymMark[nullptr] = 0; + localPregMark.clear(); + localPregMark[nullptr] = 0; + labelMark.clear(); + labelMark[0] = 0; OutputFunction(func->GetPuidx()); CHECK_FATAL(func->GetBody() != nullptr, "WriteFunctionBodyField: no function body"); OutputFuncIdInfo(func); - OutputPregTab(func); - OutputLocalSymTab(func); - OutputLabelTab(func); OutputLocalTypeNameTab(func->GetTypeNameTab()); OutputFormalsStIdx(func); if (mod.GetFlavor() < kMmpl) { @@ -753,7 +737,6 @@ void BinaryMplExport::WriteFunctionBodyField(uint64 contentIdx, std::unordered_s Fixup(totalSizeIdx, static_cast(buf.size() - totalSizeIdx)); Fixup(outFunctionBodySizeIdx, size); - WriteNum(~kBinFunctionBodyStart); return; } } // namespace maple diff --git a/src/mapleall/maple_ir/src/bin_func_import.cpp b/src/mapleall/maple_ir/src/bin_func_import.cpp index d16feb4d4a..1903cc5f80 100644 --- a/src/mapleall/maple_ir/src/bin_func_import.cpp +++ b/src/mapleall/maple_ir/src/bin_func_import.cpp @@ -44,29 +44,27 @@ void BinaryMplImport::ImportFuncIdInfo(MIRFunction *func) { func->SetPuidxOrigin(static_cast(ReadNum())); ImportInfoVector(func->GetInfoVector(), func->InfoIsString()); if (mod.GetFlavor() == kFlavorLmbc) { - func->SetUpFormalSize(static_cast(ReadNum())); func->SetFrameSize(static_cast(ReadNum())); - func->SetOutParmSize(static_cast(ReadNum())); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinFuncIdInfoStart, "pattern mismatch in ImportFuncIdInfo()"); } void BinaryMplImport::ImportBaseNode(Opcode &o, PrimType &typ) { - o = static_cast(ReadNum()); - typ = static_cast(ReadNum()); + o = (Opcode)Read(); + typ = (PrimType)Read(); } -void BinaryMplImport::ImportLocalSymbol(MIRFunction *func) { +MIRSymbol *BinaryMplImport::ImportLocalSymbol(MIRFunction *func) { int64 tag = ReadNum(); if (tag == 0) { - func->GetSymTab()->PushNullSymbol(); - return; + return nullptr; } + if (tag < 0) { + CHECK_FATAL(static_cast(-tag) < localSymTab.size(), "index out of bounds"); + return localSymTab.at(-tag); + } CHECK_FATAL(tag == kBinSymbol, "expecting kBinSymbol in ImportLocalSymbol()"); - auto indx = static_cast(ReadNum()); - CHECK_FATAL(indx == func->GetSymTab()->GetSymbolTableSize(), "inconsistant local stIdx"); MIRSymbol *sym = func->GetSymTab()->CreateSymbol(kScopeLocal); + localSymTab.push_back(sym); sym->SetNameStrIdx(ImportStr()); (void)func->GetSymTab()->AddToStringSymbolMap(*sym); sym->SetSKind(static_cast(ReadNum())); @@ -78,66 +76,52 @@ void BinaryMplImport::ImportLocalSymbol(MIRFunction *func) { } sym->SetTyIdx(ImportType()); if (sym->GetSKind() == kStPreg) { - auto thepregno = static_cast(ReadNum()); - MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx()); - PregIdx pregidx = func->GetPregTab()->EnterPregNo(thepregno, mirType->GetPrimType(), mirType); - MIRPregTable *pregTab = func->GetPregTab(); - MIRPreg *preg = pregTab->PregFromPregIdx(pregidx); - preg->SetPrimType(mirType->GetPrimType()); + PregIdx pregidx = ImportPreg(func); + MIRPreg *preg = func->GetPregTab()->PregFromPregIdx(pregidx); sym->SetPreg(preg); } else if (sym->GetSKind() == kStConst || sym->GetSKind() == kStVar) { sym->SetKonst(ImportConst(func)); } else if (sym->GetSKind() == kStFunc) { - PUIdx puIdx = ImportFuncViaSymName(); - TyIdx tyIdx = ImportType(); - sym->SetTyIdx(tyIdx); + PUIdx puIdx = ImportFuncViaSym(func); sym->SetFunction(GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx)); } + return sym; } -void BinaryMplImport::ImportLocalSymTab(MIRFunction *func) { +PregIdx BinaryMplImport::ImportPreg(MIRFunction *func) { int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinSymStart, "kBinSymStart expected in ImportLocalSymTab()"); - int32 size = ReadInt(); - for (int64 i = 0; i < size; ++i) { - ImportLocalSymbol(func); + if (tag == 0) { + return 0; } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinSymStart, "pattern mismatch in ImportLocalSymTab()"); -} - -void BinaryMplImport::ImportPregTab(const MIRFunction *func) { - int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinPregStart, "kBinPregStart expected in ImportPregTab()"); - int32 size = ReadInt(); - for (int64 i = 0; i < size; ++i) { - int64 nextTag = ReadNum(); - if (nextTag == 0) { - func->GetPregTab()->GetPregTable().push_back(nullptr); - continue; - } - CHECK_FATAL(nextTag == kBinPreg, "expecting kBinPreg in ImportPregTab()"); - auto pregNo = static_cast(ReadNum()); - TyIdx tyIdx = ImportType(); - MIRType *ty = (tyIdx == 0) ? nullptr : GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); - PrimType primType = static_cast(ReadNum()); - CHECK_FATAL(ty == nullptr || primType == ty->GetPrimType(), "ImportPregTab: inconsistent primitive type"); - (void)func->GetPregTab()->EnterPregNo(pregNo, primType, ty); + if (tag == kBinSpecialReg) { + return -Read(); + } + if (tag < 0) { + CHECK_FATAL(static_cast(-tag) < localPregTab.size(), "index out of bounds"); + return localPregTab.at(-tag); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinPregStart, "pattern mismatch in ImportPregTab()"); + CHECK_FATAL(tag == kBinPreg, "expecting kBinPreg in ImportPreg()"); + + PrimType primType = (PrimType)Read(); + PregIdx pidx = func->GetPregTab()->CreatePreg(primType); + localPregTab.push_back(pidx); + return pidx; } -void BinaryMplImport::ImportLabelTab(MIRFunction *func) { +LabelIdx BinaryMplImport::ImportLabel(MIRFunction *func) { int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinLabelStart, "kBinLabelStart expected in ImportLabelTab()"); - int64 size = ReadNum(); - for (int64 i = 0; i < size; ++i) { - GStrIdx gStrIdx = ImportStr(); - (void)func->GetLabelTab()->AddLabel(gStrIdx); + if (tag == 0) { + return 0; + } + if (tag < 0) { + CHECK_FATAL(static_cast(-tag) < localLabelTab.size(), "index out of bounds"); + return localLabelTab.at(-tag); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinLabelStart, "pattern mismatch in ImportLabelTab()"); + CHECK_FATAL(tag == kBinLabel, "kBinLabel expected in ImportLabel()"); + + LabelIdx lidx = func->GetLabelTab()->CreateLabel(); + localLabelTab.push_back(lidx); + return lidx; } void BinaryMplImport::ImportLocalTypeNameTable(MIRTypeNameTable *typeNameTab) { @@ -149,8 +133,6 @@ void BinaryMplImport::ImportLocalTypeNameTable(MIRTypeNameTable *typeNameTab) { TyIdx tyIdx = ImportType(); typeNameTab->SetGStrIdxToTyIdx(strIdx, tyIdx); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinTypenameStart, "pattern mismatch in ImportTypenametab()"); } void BinaryMplImport::ImportFormalsStIdx(MIRFunction *func) { @@ -158,11 +140,8 @@ void BinaryMplImport::ImportFormalsStIdx(MIRFunction *func) { CHECK_FATAL(tag == kBinFormalStart, "kBinFormalStart expected in ImportFormalsStIdx()"); auto size = ReadNum(); for (int64 i = 0; i < size; ++i) { - uint32 indx = static_cast(ReadNum()); - func->GetFormalDefVec()[static_cast(i)].formalSym = func->GetSymTab()->GetSymbolFromStIdx(indx); + func->GetFormalDefVec()[static_cast(i)].formalSym = ImportLocalSymbol(func); } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinFormalStart, "pattern mismatch in ImportFormalsStIdx()"); } void BinaryMplImport::ImportAliasMap(MIRFunction *func) { @@ -177,23 +156,15 @@ void BinaryMplImport::ImportAliasMap(MIRFunction *func) { (void)ImportStr(); // not assigning to mimic parser func->GetAliasVarMap()[strIdx] = aliasvars; } - tag = ReadNum(); - CHECK_FATAL(tag == ~kBinAliasMapStart, "pattern mismatch in ImportAliasMap()"); } -PUIdx BinaryMplImport::ImportFuncViaSymName() { - int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinKindFuncViaSymname, "kBinKindFuncViaSymname expected"); - GStrIdx strIdx = ImportStr(); - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx); - ASSERT(sym != nullptr, "null ptr check"); - MIRFunction *func = sym->GetFunction(); - return func->GetPuidx(); +PUIdx BinaryMplImport::ImportFuncViaSym(MIRFunction *func) { + MIRSymbol *sym = InSymbol(func); + MIRFunction *f = sym->GetFunction(); + return f->GetPuidx(); } BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { - int64 tag = ReadNum(); - CHECK_FATAL(tag == kBinOpExpression, "kBinOpExpression expected"); Opcode op; PrimType typ; ImportBaseNode(op, typ); @@ -213,13 +184,15 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { } case OP_addroflabel: { AddroflabelNode *alabNode = mod.CurFuncCodeMemPool()->New(); - alabNode->SetOffset(static_cast(ReadNum())); + alabNode->SetOffset(ImportLabel(func)); alabNode->SetPrimType(typ); (void)func->GetLabelTab()->addrTakenLabels.insert(alabNode->GetOffset()); return alabNode; } case OP_addroffunc: { - PUIdx puIdx = ImportFuncViaSymName(); + PUIdx puIdx = ImportFuncViaSym(func); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFuncTable()[puIdx]; + f->GetFuncSymbol()->SetAppearsInCode(true); AddroffuncNode *addrNode = mod.CurFuncCodeMemPool()->New(typ, puIdx); return addrNode; } @@ -235,19 +208,18 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { int32 num = static_cast(ReadNum()); StIdx stIdx; stIdx.SetScope(static_cast(ReadNum())); + MIRSymbol *sym = nullptr; if (stIdx.Islocal()) { - stIdx.SetIdx(static_cast(ReadNum())); + sym = ImportLocalSymbol(func); + CHECK_FATAL(sym != nullptr, "null ptr check"); } else { - int32 stag = static_cast(ReadNum()); - CHECK_FATAL(stag == kBinKindSymViaSymname, "kBinKindSymViaSymname expected"); - GStrIdx strIdx = ImportStr(); - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx); - ASSERT(sym != nullptr, "null ptr check"); + sym = InSymbol(func); + CHECK_FATAL(sym != nullptr, "null ptr check"); if (op == OP_addrof) { sym->SetHasPotentialAssignment(); } - stIdx.SetIdx(sym->GetStIdx().Idx()); } + stIdx.SetIdx(sym->GetStIdx().Idx()); if (op == OP_addrof || op == OP_dread) { AddrofNode *drNode = mod.CurFuncCodeMemPool()->New(op); drNode->SetPrimType(typ); @@ -264,7 +236,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { } case OP_regread: { RegreadNode *regreadNode = mod.CurFuncCodeMemPool()->New(); - regreadNode->SetRegIdx(static_cast(ReadNum())); + regreadNode->SetRegIdx(ImportPreg(func)); regreadNode->SetPrimType(typ); return regreadNode; } @@ -293,7 +265,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_floor: case OP_trunc: { TypeCvtNode *typecvtNode = mod.CurFuncCodeMemPool()->New(op, typ); - typecvtNode->SetFromType(static_cast(ReadNum())); + typecvtNode->SetFromType((PrimType)Read()); typecvtNode->SetOpnd(ImportExpression(func), 0); return typecvtNode; } @@ -326,15 +298,15 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_zext: case OP_extractbits: { ExtractbitsNode *extNode = mod.CurFuncCodeMemPool()->New(op, typ); - extNode->SetBitsOffset(static_cast(ReadNum())); - extNode->SetBitsSize(static_cast(ReadNum())); + extNode->SetBitsOffset(Read()); + extNode->SetBitsSize(Read()); extNode->SetOpnd(ImportExpression(func), 0); return extNode; } case OP_depositbits: { DepositbitsNode *dbNode = mod.CurFuncCodeMemPool()->New(op, typ); - dbNode->SetBitsOffset(static_cast(ReadNum())); - dbNode->SetBitsSize(static_cast(ReadNum())); + dbNode->SetBitsOffset(ReadNum()); + dbNode->SetBitsSize(ReadNum()); dbNode->SetOpnd(ImportExpression(func), 0); dbNode->SetOpnd(ImportExpression(func), 1); return dbNode; @@ -379,7 +351,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_cmpl: case OP_cmp: { CompareNode *cmpNode = mod.CurFuncCodeMemPool()->New(op, typ); - cmpNode->SetOpndType(static_cast(ReadNum())); + cmpNode->SetOpndType((PrimType)Read()); cmpNode->SetOpnd(ImportExpression(func), 0); cmpNode->SetOpnd(ImportExpression(func), 1); return cmpNode; @@ -387,7 +359,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_resolveinterfacefunc: case OP_resolvevirtualfunc: { ResolveFuncNode *rsNode = mod.CurFuncCodeMemPool()->New(op, typ); - rsNode->SetPUIdx(ImportFuncViaSymName()); + rsNode->SetPUIdx(ImportFuncViaSym(func)); rsNode->SetOpnd(ImportExpression(func), 0); rsNode->SetOpnd(ImportExpression(func), 1); return rsNode; @@ -403,7 +375,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { // nary case OP_array: { TyIdx tidx = ImportType(); - auto boundsCheck = static_cast(ReadNum()); + bool boundsCheck = static_cast(Read()); ArrayNode *arrNode = mod.CurFuncCodeMemPool()->New(func->GetCodeMPAllocator(), typ, tidx, boundsCheck); auto n = static_cast(ReadNum()); @@ -436,12 +408,15 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { return intrnNode; } default: - CHECK_FATAL(false, "Unhandled op %d", tag); + CHECK_FATAL(false, "Unhandled op %d", op); break; } } void BinaryMplImport::ImportSrcPos(SrcPosition &pos) { + if (!mod.IsWithDbgInfo()) { + return; + } pos.SetRawData(static_cast(ReadNum())); pos.SetLineNum(static_cast(ReadNum())); } @@ -451,15 +426,16 @@ void BinaryMplImport::ImportReturnValues(MIRFunction *func, CallReturnVector *re CHECK_FATAL(tag == kBinReturnvals, "expecting return values"); auto size = static_cast(ReadNum()); for (uint32 i = 0; i < size; ++i) { - uint32 idx = static_cast(ReadNum()); - FieldID fid = static_cast(ReadNum()); - PregIdx ridx = static_cast(ReadNum()); - retv->push_back(std::make_pair(StIdx(kScopeLocal, idx), RegFieldPair(fid, ridx))); - if (idx == 0) { + RegFieldPair rfp; + rfp.SetPregIdx(ImportPreg(func)); + if (rfp.IsReg()) { + retv->push_back(std::make_pair(StIdx(), rfp)); continue; } - MIRSymbol *lsym = func->GetSymTab()->GetSymbolFromStIdx(idx, false); - ASSERT(lsym != nullptr, "null ptr check"); + rfp.SetFieldID(static_cast(ReadNum())); + MIRSymbol *lsym = ImportLocalSymbol(func); + CHECK_FATAL(lsym != nullptr, "null ptr check"); + retv->push_back(std::make_pair(lsym->GetStIdx(), rfp)); if (lsym->GetName().find("L_STR") == 0) { MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(lsym->GetTyIdx()); CHECK_FATAL(ty->GetKind() == kTypePointer, "Pointer type expected for L_STR prefix"); @@ -480,8 +456,6 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { ImportSrcPos(block->GetSrcPos()); int32 size = ReadInt(); for (int32 k = 0; k < size; ++k) { - tag = ReadNum(); - CHECK_FATAL(tag == kBinOpStatement, "kBinOpStatement expected"); SrcPosition thesrcPosition; ImportSrcPos(thesrcPosition); op = static_cast(ReadNum()); @@ -496,17 +470,16 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { int32 num = static_cast(ReadNum()); StIdx stIdx; stIdx.SetScope(static_cast(ReadNum())); + MIRSymbol *sym = nullptr; if (stIdx.Islocal()) { - stIdx.SetIdx(static_cast(ReadNum())); + sym = ImportLocalSymbol(func); + CHECK_FATAL(sym != nullptr, "null ptr check"); } else { - int32 stag = static_cast(ReadNum()); - CHECK_FATAL(stag == kBinKindSymViaSymname, "kBinKindSymViaSymname expected"); - GStrIdx strIdx = ImportStr(); - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx); - ASSERT(sym != nullptr, "null ptr check"); + sym = InSymbol(func); + CHECK_FATAL(sym != nullptr, "null ptr check"); sym->SetHasPotentialAssignment(); - stIdx.SetIdx(sym->GetStIdx().Idx()); } + stIdx.SetIdx(sym->GetStIdx().Idx()); if (op == OP_dassign) { DassignNode *s = func->GetCodeMemPool()->New(); s->SetStIdx(stIdx); @@ -525,8 +498,8 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_regassign: { RegassignNode *s = func->GetCodeMemPool()->New(); - s->SetPrimType(static_cast(ReadNum())); - s->SetRegIdx(static_cast(ReadNum())); + s->SetPrimType((PrimType)Read()); + s->SetRegIdx(ImportPreg(func)); s->SetOpnd(ImportExpression(func), 0); stmt = s; break; @@ -542,7 +515,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_iassignoff: { IassignoffNode *s = func->GetCodeMemPool()->New(); - s->SetPrimType((PrimType)ReadNum()); + s->SetPrimType((PrimType)Read()); s->SetOffset(static_cast(ReadNum())); s->SetOpnd(ImportExpression(func), 0); s->SetOpnd(ImportExpression(func), 1); @@ -552,7 +525,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { case OP_iassignspoff: case OP_iassignfpoff: { IassignFPoffNode *s = func->GetCodeMemPool()->New(op); - s->SetPrimType((PrimType)ReadNum()); + s->SetPrimType((PrimType)Read()); s->SetOffset(static_cast(ReadNum())); s->SetOpnd(ImportExpression(func), 0); stmt = s; @@ -577,7 +550,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { case OP_interfaceicall: case OP_customcall: { CallNode *s = func->GetCodeMemPool()->New(mod, op); - s->SetPUIdx(ImportFuncViaSymName()); + s->SetPUIdx(ImportFuncViaSym(func)); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx()); + f->GetFuncSymbol()->SetAppearsInCode(true); numOpr = static_cast(ReadNum()); s->SetNumOpnds(numOpr); for (int32 i = 0; i < numOpr; ++i) { @@ -594,7 +569,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { case OP_interfaceicallassigned: case OP_customcallassigned: { CallNode *s = func->GetCodeMemPool()->New(mod, op); - s->SetPUIdx(ImportFuncViaSymName()); + s->SetPUIdx(ImportFuncViaSym(func)); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx()); + f->GetFuncSymbol()->SetAppearsInCode(true); ImportReturnValues(func, &s->GetReturnVec()); numOpr = static_cast(ReadNum()); s->SetNumOpnds(numOpr); @@ -610,7 +587,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_polymorphiccall: { CallNode *s = func->GetCodeMemPool()->New(mod, op); - s->SetPUIdx(ImportFuncViaSymName()); + s->SetPUIdx(ImportFuncViaSym(func)); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx()); + f->GetFuncSymbol()->SetAppearsInCode(true); s->SetTyIdx(ImportType()); numOpr = static_cast(ReadNum()); s->SetNumOpnds(numOpr); @@ -622,7 +601,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_polymorphiccallassigned: { CallNode *s = func->GetCodeMemPool()->New(mod, op); - s->SetPUIdx(ImportFuncViaSymName()); + s->SetPUIdx(ImportFuncViaSym(func)); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx()); + f->GetFuncSymbol()->SetAppearsInCode(true); s->SetTyIdx(ImportType()); ImportReturnValues(func, &s->GetReturnVec()); numOpr = static_cast(ReadNum()); @@ -645,6 +626,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { stmt = s; break; } + case OP_icallprotoassigned: case OP_icallassigned: { IcallNode *s = func->GetCodeMemPool()->New(mod, op); s->SetRetTyIdx(ImportType()); @@ -759,32 +741,32 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_label: { LabelNode *s = mod.CurFuncCodeMemPool()->New(); - s->SetLabelIdx(static_cast(ReadNum())); + s->SetLabelIdx(ImportLabel(func)); stmt = s; break; } case OP_goto: case OP_gosub: { GotoNode *s = mod.CurFuncCodeMemPool()->New(op); - s->SetOffset(static_cast(ReadNum())); + s->SetOffset(ImportLabel(func)); stmt = s; break; } case OP_brfalse: case OP_brtrue: { CondGotoNode *s = mod.CurFuncCodeMemPool()->New(op); - s->SetOffset(static_cast(ReadNum())); + s->SetOffset(ImportLabel(func)); s->SetOpnd(ImportExpression(func), 0); stmt = s; break; } case OP_switch: { SwitchNode *s = mod.CurFuncCodeMemPool()->New(mod); - s->SetDefaultLabel(static_cast(ReadNum())); + s->SetDefaultLabel(ImportLabel(func)); auto tagSize = static_cast(ReadNum()); for (uint32 i = 0; i < tagSize; ++i) { int64 casetag = ReadNum(); - LabelIdx lidx(ReadNum()); + LabelIdx lidx = ImportLabel(func); CasePair cpair = std::make_pair(casetag, lidx); s->GetSwitchTable().push_back(cpair); } @@ -798,7 +780,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { uint32 tagSize = static_cast(ReadNum()); for (uint32 i = 0; i < tagSize; ++i) { uint16 casetag = static_cast(ReadNum()); - LabelIdx lidx(ReadNum()); + LabelIdx lidx = ImportLabel(func); s->AddRangeGoto(casetag, lidx); } s->SetOpnd(ImportExpression(func), 0); @@ -807,8 +789,8 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_jstry: { JsTryNode *s = mod.CurFuncCodeMemPool()->New(); - s->SetCatchOffset(static_cast(ReadNum())); - s->SetFinallyOffset(static_cast(ReadNum())); + s->SetCatchOffset(ImportLabel(func)); + s->SetFinallyOffset(ImportLabel(func)); stmt = s; break; } @@ -817,7 +799,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { TryNode *s = mod.CurFuncCodeMemPool()->New(mod); auto numLabels = static_cast(ReadNum()); for (uint32 i = 0; i < numLabels; ++i) { - s->GetOffsets().push_back(ReadNum()); + s->GetOffsets().push_back(ImportLabel(func)); } stmt = s; break; @@ -887,7 +869,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { // the labels count = static_cast(ReadNum()); for (size_t i = 0; i < count; ++i) { - auto lidx = static_cast(ReadNum()); + LabelIdx lidx = ImportLabel(func); s->gotoLabels.push_back(lidx); } // the inputs @@ -927,6 +909,13 @@ void BinaryMplImport::ReadFunctionBodyField() { PUIdx puIdx = ImportFunction(); MIRFunction *fn = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); mod.SetCurFunction(fn); + fn->GetFuncSymbol()->SetAppearsInCode(true); + localSymTab.clear(); + localSymTab.push_back(nullptr); + localPregTab.clear(); + localPregTab.push_back(0); + localLabelTab.clear(); + localLabelTab.push_back(0); fn->AllocSymTab(); fn->AllocPregTab(); @@ -934,9 +923,6 @@ void BinaryMplImport::ReadFunctionBodyField() { fn->AllocLabelTab(); ImportFuncIdInfo(fn); - ImportPregTab(fn); - ImportLocalSymTab(fn); - ImportLabelTab(fn); ImportLocalTypeNameTable(fn->GetTypeNameTab()); ImportFormalsStIdx(fn); if (mod.GetFlavor() < kMmpl) { @@ -945,8 +931,6 @@ void BinaryMplImport::ReadFunctionBodyField() { (void)ImportBlockNode(fn); mod.AddFunction(fn); } - int64 tag = ReadNum(); - CHECK_FATAL(tag == ~kBinFunctionBodyStart, "pattern mismatch in Read FunctionBody"); return; } } // namespace maple diff --git a/src/mapleall/maple_ir/src/bin_mpl_export.cpp b/src/mapleall/maple_ir/src/bin_mpl_export.cpp index c6d58fdd8c..d406b89cdd 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_export.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_export.cpp @@ -26,7 +26,7 @@ namespace { using namespace maple; using OutputConstFactory = FunctionFactory; -using OutputTypeFactory = FunctionFactory; +using OutputTypeFactory = FunctionFactory; void OutputConstInt(const MIRConst &constVal, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindConstInt); @@ -62,7 +62,7 @@ void OutputConstLbl(const MIRConst &constVal, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindConstAddrofLabel); mplExport.OutputConstBase(constVal); const MIRLblConst &lblConst = static_cast(constVal); - mplExport.WriteNum(lblConst.GetValue()); // LabelIdx not needed to output puIdx + mplExport.OutputLabel(lblConst.GetValue()); } void OutputConstStr(const MIRConst &constVal, BinaryMplExport &mplExport) { @@ -141,39 +141,39 @@ static bool InitOutputConstFactory() { return true; } -void OutputTypeScalar(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeScalar(const MIRType &ty, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindTypeScalar); mplExport.OutputTypeBase(ty); } -void OutputTypePointer(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypePointer(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypePointer); mplExport.OutputTypeBase(type); mplExport.OutputTypeAttrs(type.GetTypeAttrs()); - mplExport.OutputType(type.GetPointedTyIdx(), canUseTypename); + mplExport.OutputType(type.GetPointedTyIdx()); } -void OutputTypeByName(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeByName(const MIRType &ty, BinaryMplExport &mplExport) { mplExport.WriteNum(kBinKindTypeByName); mplExport.OutputTypeBase(ty); } -void OutputTypeFArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeFArray(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeFArray); mplExport.OutputTypeBase(type); - mplExport.OutputType(type.GetElemTyIdx(), canUseTypename); + mplExport.OutputType(type.GetElemTyIdx()); } -void OutputTypeJArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeJArray(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeJarray); mplExport.OutputTypeBase(type); - mplExport.OutputType(type.GetElemTyIdx(), canUseTypename); + mplExport.OutputType(type.GetElemTyIdx()); } -void OutputTypeArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeArray(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeArray); mplExport.OutputTypeBase(type); @@ -181,20 +181,20 @@ void OutputTypeArray(const MIRType &ty, BinaryMplExport &mplExport, bool canUseT for (uint16 i = 0; i < type.GetDim(); ++i) { mplExport.WriteNum(type.GetSizeArrayItem(i)); } - mplExport.OutputType(type.GetElemTyIdx(), canUseTypename); + mplExport.OutputType(type.GetElemTyIdx()); mplExport.OutputTypeAttrs(type.GetTypeAttrs()); } -void OutputTypeFunction(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeFunction(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeFunction); mplExport.OutputTypeBase(type); - mplExport.OutputType(type.GetRetTyIdx(), canUseTypename); - mplExport.WriteNum(type.IsVarargs()); + mplExport.OutputType(type.GetRetTyIdx()); + mplExport.WriteNum(type.funcAttrs.GetAttrFlag()); size_t size = type.GetParamTypeList().size(); mplExport.WriteNum(size); for (size_t i = 0; i < size; ++i) { - mplExport.OutputType(type.GetNthParamType(i), canUseTypename); + mplExport.OutputType(type.GetNthParamType(i)); } size = type.GetParamAttrsList().size(); mplExport.WriteNum(size); @@ -203,13 +203,13 @@ void OutputTypeFunction(const MIRType &ty, BinaryMplExport &mplExport, bool canU } } -void OutputTypeParam(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeParam(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeParam); mplExport.OutputTypeBase(type); } -void OutputTypeInstantVector(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeInstantVector(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeInstantVector); mplExport.OutputTypeBase(type); @@ -217,15 +217,15 @@ void OutputTypeInstantVector(const MIRType &ty, BinaryMplExport &mplExport, bool mplExport.OutputTypePairs(type); } -void OutputTypeGenericInstant(const MIRType &ty, BinaryMplExport &mplExport, bool canUseTypename) { +void OutputTypeGenericInstant(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeGenericInstant); mplExport.OutputTypeBase(type); mplExport.OutputTypePairs(type); - mplExport.OutputType(type.GetGenericTyIdx(), canUseTypename); + mplExport.OutputType(type.GetGenericTyIdx()); } -void OutputTypeBitField(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeBitField(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeBitField); mplExport.OutputTypeBase(type); @@ -233,7 +233,7 @@ void OutputTypeBitField(const MIRType &ty, BinaryMplExport &mplExport, bool) { } // for Struct/StructIncomplete/Union -void OutputTypeStruct(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeStruct(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeStruct); mplExport.OutputTypeBase(type); @@ -249,7 +249,7 @@ void OutputTypeStruct(const MIRType &ty, BinaryMplExport &mplExport, bool) { } } -void OutputTypeClass(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeClass(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeClass); mplExport.OutputTypeBase(type); @@ -264,7 +264,7 @@ void OutputTypeClass(const MIRType &ty, BinaryMplExport &mplExport, bool) { } } -void OutputTypeInterface(const MIRType &ty, BinaryMplExport &mplExport, bool) { +void OutputTypeInterface(const MIRType &ty, BinaryMplExport &mplExport) { const auto &type = static_cast(ty); mplExport.WriteNum(kBinKindTypeInterface); mplExport.OutputTypeBase(type); @@ -279,7 +279,7 @@ void OutputTypeInterface(const MIRType &ty, BinaryMplExport &mplExport, bool) { } } -void OutputTypeConstString(const MIRType &ty, BinaryMplExport&, bool) { +void OutputTypeConstString(const MIRType &ty, BinaryMplExport&) { ASSERT(false, "Type's kind not yet implemented: %d", ty.GetKind()); (void)ty; } @@ -397,7 +397,7 @@ void BinaryMplExport::DumpBuf(const std::string &name) { void BinaryMplExport::OutputConstBase(const MIRConst &constVal) { WriteNum(constVal.GetKind()); - OutputTypeViaTypeName(constVal.GetType().GetTypeIndex()); + OutputType(constVal.GetType().GetTypeIndex()); } void BinaryMplExport::OutputConst(MIRConst *constVal) { @@ -470,8 +470,8 @@ void BinaryMplExport::OutputPragma(const MIRPragma &p) { WriteNum(p.GetKind()); WriteNum(p.GetVisibility()); OutputStr(p.GetStrIdx()); - OutputType(p.GetTyIdx(), false); - OutputType(p.GetTyIdxEx(), false); + OutputType(p.GetTyIdx()); + OutputType(p.GetTyIdxEx()); WriteNum(p.GetParamNum()); size_t size = p.GetElementVector().size(); WriteNum(size); @@ -488,7 +488,7 @@ void BinaryMplExport::OutputTypeBase(const MIRType &type) { void BinaryMplExport::OutputFieldPair(const FieldPair &fp) { OutputStr(fp.first); // GStrIdx - OutputType(fp.second.first, false); // TyIdx + OutputType(fp.second.first); // TyIdx FieldAttrs fa = fp.second.second; WriteNum(fa.GetAttrFlag()); WriteNum(fa.GetAlignValue()); @@ -511,7 +511,7 @@ void BinaryMplExport::OutputMethodPair(const MethodPair &memPool) { MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(memPool.first.Idx()); CHECK_FATAL(funcSt != nullptr, "Pointer funcSt is nullptr, can't get symbol! Check it!"); WriteAsciiStr(GlobalTables::GetStrTable().GetStringFromStrIdx(funcSt->GetNameStrIdx())); - OutputType(memPool.second.first, false); // TyIdx + OutputType(memPool.second.first); // TyIdx WriteNum(memPool.second.second.GetAttrFlag()); // FuncAttrs } @@ -539,7 +539,7 @@ void BinaryMplExport::OutputStructTypeData(const MIRStructType &type) { void BinaryMplExport::OutputImplementedInterfaces(const std::vector &interfaces) { WriteNum(interfaces.size()); for (const TyIdx &tyIdx : interfaces) { - OutputType(tyIdx, false); + OutputType(tyIdx); } } @@ -571,7 +571,7 @@ void BinaryMplExport::OutputPragmaVec(const std::vector &pragmaVec) } void BinaryMplExport::OutputClassTypeData(const MIRClassType &type) { - OutputType(type.GetParentTyIdx(), false); + OutputType(type.GetParentTyIdx()); OutputImplementedInterfaces(type.GetInterfaceImplemented()); OutputInfoIsString(type.GetInfoIsString()); if (!inIPA) { @@ -601,6 +601,7 @@ void BinaryMplExport::Init() { symMark[nullptr] = 0; funcMark[nullptr] = 0; eaNodeMark[nullptr] = 0; + curFunc = nullptr; for (uint32 pti = static_cast(PTY_begin); pti < static_cast(PTY_end); ++pti) { typMark[GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(pti))] = pti; } @@ -612,7 +613,7 @@ void BinaryMplExport::OutputSymbol(MIRSymbol *sym) { return; } - auto it = symMark.find(sym); + std::unordered_map::iterator it = symMark.find(sym); if (it != symMark.end()) { WriteNum(-(it->second)); return; @@ -645,7 +646,7 @@ void BinaryMplExport::OutputSymbol(MIRSymbol *sym) { if (sym->GetSKind() == kStVar || sym->GetSKind() == kStFunc) { OutputSrcPos(sym->GetSrcPosition()); } - OutputTypeViaTypeName(sym->GetTyIdx()); + OutputType(sym->GetTyIdx()); } void BinaryMplExport::OutputFunction(PUIdx puIdx) { @@ -671,7 +672,7 @@ void BinaryMplExport::OutputFunction(PUIdx puIdx) { MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx()); CHECK_FATAL(funcSt != nullptr, "Pointer funcSt is nullptr, cannot get symbol! Check it!"); OutputSymbol(funcSt); - OutputTypeViaTypeName(func->GetMIRFuncType()->GetTypeIndex()); + OutputType(func->GetMIRFuncType()->GetTypeIndex()); WriteNum(func->GetFuncAttrs().GetAttrFlag()); auto &attributes = func->GetFuncAttrs(); @@ -684,12 +685,12 @@ void BinaryMplExport::OutputFunction(PUIdx puIdx) { } WriteNum(func->GetFlag()); - OutputTypeViaTypeName(func->GetClassTyIdx()); + OutputType(func->GetClassTyIdx()); // output formal parameter information WriteNum(static_cast(func->GetFormalDefVec().size())); for (FormalDef formalDef : func->GetFormalDefVec()) { OutputStr(formalDef.formalStrIdx); - OutputType(formalDef.formalTyIdx, false); + OutputType(formalDef.formalTyIdx); WriteNum(static_cast(formalDef.formalAttrs.GetAttrFlag())); } // store Side Effect for each func @@ -751,15 +752,20 @@ void BinaryMplExport::WriteHeaderField(uint64 contentIdx) { WriteNum(mod.GetID()); if (mod.GetFlavor() == kFlavorLmbc) { WriteNum(mod.GetGlobalMemSize()); + WriteNum(mod.IsWithDbgInfo()); } WriteNum(mod.GetNumFuncs()); WriteAsciiStr(mod.GetEntryFuncName()); OutputInfoVector(mod.GetFileInfo(), mod.GetFileInfoIsString()); - WriteNum(static_cast(mod.GetSrcFileInfo().size())); - for (uint32 i = 0; i < mod.GetSrcFileInfo().size(); i++) { - OutputStr(mod.GetSrcFileInfo()[i].first); - WriteNum(mod.GetSrcFileInfo()[i].second); + if (mod.IsWithDbgInfo()) { + WriteNum(static_cast(mod.GetSrcFileInfo().size())); + for (uint32 i = 0; i < mod.GetSrcFileInfo().size(); i++) { + OutputStr(mod.GetSrcFileInfo()[i].first); + WriteNum(mod.GetSrcFileInfo()[i].second); + } + } else { + Write(0); } WriteNum(static_cast(mod.GetImportFiles().size())); @@ -795,7 +801,7 @@ void BinaryMplExport::WriteTypeField(uint64 contentIdx, bool useClassList) { auto *structType = static_cast(type); // skip imported class/interface and incomplete types if (!structType->IsImported() && !structType->IsIncomplete()) { - OutputType(curTyidx, false); + OutputType(curTyidx); ++size; } } @@ -803,7 +809,7 @@ void BinaryMplExport::WriteTypeField(uint64 contentIdx, bool useClassList) { } else { uint32 idx = GlobalTables::GetTypeTable().lastDefaultTyIdx.GetIdx(); for (idx = idx + 1; idx < GlobalTables::GetTypeTable().GetTypeTableSize(); idx++) { - OutputType(TyIdx(idx), false); + OutputType(TyIdx(idx)); size++; } } @@ -884,7 +890,7 @@ void BinaryMplExport::WriteSeField() { GlobalTables::GetGsymTable().GetSymbolFromStrIdx(GlobalTables::GetStrTable().GetStrIdxFromName(funcStr)); MIRFunction *func = (funcSymbol != nullptr) ? GetMIRModule().GetMIRBuilder()->GetFunctionFromSymbol(*funcSymbol) : nullptr; - OutputType(func->GetReturnTyIdx(), false); + OutputType(func->GetReturnTyIdx()); } ++size; } @@ -1103,7 +1109,7 @@ void BinaryMplExport::WriteSymField(uint64 contentIdx) { MIRSymKind sKind = s->GetSKind(); if (s->IsDeleted() || storageClass == kScUnused || (s->GetIsImported() && !s->GetAppearsInCode()) || - (storageClass == kScExtern && sKind == kStFunc)) { + (sKind == kStFunc && (storageClass == kScExtern || !s->GetAppearsInCode()))) { continue; } OutputSymbol(s); @@ -1214,8 +1220,6 @@ void BinaryMplExport::Export(const std::string &fname, std::unordered_setIsNameIsLocal() && ty->GetNameStrIdx() != GStrIdx(0)) { - WriteNum(kBinKindTypeViaTypename); - OutputStr(ty->GetNameStrIdx()); - return; - } - auto func = CreateProductFunction(ty->GetKind()); if (func != nullptr) { - func(*ty, *this, canUseTypename); + func(*ty, *this); } else { ASSERT(false, "Type's kind not yet implemented: %d", ty->GetKind()); } diff --git a/src/mapleall/maple_ir/src/bin_mpl_import.cpp b/src/mapleall/maple_ir/src/bin_mpl_import.cpp index 049ada30f3..375c84ca02 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_import.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_import.cpp @@ -129,11 +129,13 @@ MIRConst *BinaryMplImport::ImportConst(MIRFunction *func) { } case kBinKindConstAddrofFunc: { PUIdx puIdx = ImportFunction(); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFuncTable()[puIdx]; + f->GetFuncSymbol()->SetAppearsInCode(true); mod.SetCurFunction(func); return memPool->New(puIdx, *type); } case kBinKindConstAddrofLabel: { - LabelIdx lidx = static_cast(ReadNum()); + LabelIdx lidx = ImportLabel(func); PUIdx puIdx = func->GetPuidx(); MIRLblConst *lblConst = memPool->New(lidx, puIdx, *type); (void)func->GetLabelTab()->addrTakenLabels.insert(lidx); @@ -541,20 +543,7 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { CHECK_FATAL(static_cast(-tag) < typTab.size(), "index out of bounds"); return typTab.at(static_cast(-tag)); } - if (tag == kBinKindTypeViaTypename) { - GStrIdx typenameStrIdx = ImportStr(); - TyIdx tyIdx = mod.GetTypeNameTab()->GetTyIdxFromGStrIdx(typenameStrIdx); - if (tyIdx != 0) { - typTab.push_back(tyIdx); - return tyIdx; - } - MIRTypeByName ltype(typenameStrIdx); - ltype.SetNameIsLocal(false); - MIRType *type = GlobalTables::GetTypeTable().GetOrCreateMIRTypeNode(ltype); - typTab.push_back(type->GetTypeIndex()); - return type->GetTypeIndex(); - } - PrimType primType = static_cast(0); + PrimType primType = (PrimType)0; GStrIdx strIdx(0); bool nameIsLocal = false; ImportTypeBase(primType, strIdx, nameIsLocal); @@ -580,13 +569,6 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { } return origType->GetTypeIndex(); } - case kBinKindTypeByName: { - MIRTypeByName type(strIdx); - type.SetNameIsLocal(nameIsLocal); - MIRType *origType = &InsertInTypeTables(type); - typTab.push_back(origType->GetTypeIndex()); - return origType->GetTypeIndex(); - } case kBinKindTypeFArray: { MIRFarrayType type(strIdx); type.SetNameIsLocal(nameIsLocal); @@ -629,7 +611,7 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { size_t idx = typTab.size(); typTab.push_back(TyIdx(0)); type.SetRetTyIdx(ImportType()); - type.SetVarArgs(ReadNum()); + type.funcAttrs.SetAttrFlag(ReadNum()); int64 size = ReadNum(); for (int64 i = 0; i < size; ++i) { type.GetParamTypeList().push_back(ImportType()); @@ -737,20 +719,7 @@ TyIdx BinaryMplImport::ImportTypeNonJava() { CHECK_FATAL(static_cast(-tag) < typTab.size(), "index out of bounds"); return typTab[static_cast(-tag)]; } - if (tag == kBinKindTypeViaTypename) { - GStrIdx typenameStrIdx = ImportStr(); - TyIdx tyIdx = mod.GetTypeNameTab()->GetTyIdxFromGStrIdx(typenameStrIdx); - if (tyIdx != 0) { - typTab.push_back(tyIdx); - return tyIdx; - } - MIRTypeByName ltype(typenameStrIdx); - ltype.SetNameIsLocal(false); - MIRType *type = GlobalTables::GetTypeTable().GetOrCreateMIRTypeNode(ltype); - typTab.push_back(type->GetTypeIndex()); - return type->GetTypeIndex(); - } - PrimType primType = static_cast(0); + PrimType primType = (PrimType)0; GStrIdx strIdx(0); bool nameIsLocal = false; ImportTypeBase(primType, strIdx, nameIsLocal); @@ -771,12 +740,6 @@ TyIdx BinaryMplImport::ImportTypeNonJava() { GlobalTables::GetTypeTable().CreateMirTypeNodeAt(type, tyIdxUsed, &mod, false, false); return tyIdxUsed; } - case kBinKindTypeByName: { - MIRTypeByName type(strIdx); - type.SetNameIsLocal(nameIsLocal); - GlobalTables::GetTypeTable().CreateMirTypeNodeAt(type, tyIdxUsed, &mod, false, false); - return tyIdxUsed; - } case kBinKindTypeFArray: { MIRFarrayType type(strIdx); type.SetNameIsLocal(nameIsLocal); @@ -808,7 +771,7 @@ TyIdx BinaryMplImport::ImportTypeNonJava() { MIRFuncType type(strIdx); type.SetNameIsLocal(nameIsLocal); type.SetRetTyIdx(ImportTypeNonJava()); - type.SetVarArgs(ReadNum()); + type.funcAttrs.SetAttrFlag(ReadNum()); int64 size = ReadNum(); for (int64 i = 0; i < size; ++i) { type.GetParamTypeList().push_back(ImportTypeNonJava()); @@ -1159,6 +1122,7 @@ void BinaryMplImport::ReadHeaderField() { mod.SetID(static_cast(ReadNum())); if (mod.GetFlavor() == kFlavorLmbc) { mod.SetGlobalMemSize(static_cast(ReadNum())); + mod.SetWithDbgInfo(static_cast(ReadNum())); } mod.SetNumFuncs(static_cast(ReadNum())); std::string inStr; diff --git a/src/mapleall/maple_ir/src/global_tables.cpp b/src/mapleall/maple_ir/src/global_tables.cpp index a50d6c46a5..631288a2ea 100644 --- a/src/mapleall/maple_ir/src/global_tables.cpp +++ b/src/mapleall/maple_ir/src/global_tables.cpp @@ -224,7 +224,9 @@ MIRType *TypeTable::GetOrCreateFunctionType(const TyIdx &retTyIdx, const std::ve const std::vector &vecAttrs, bool isVarg, const TypeAttrs &retAttrs) { MIRFuncType funcType(retTyIdx, vecType, vecAttrs, retAttrs); - funcType.SetVarArgs(isVarg); + if (isVarg) { + funcType.SetVarArgs(); + } TyIdx tyIdx = GetOrCreateMIRType(&funcType); ASSERT(tyIdx < typeTable.size(), "index out of range in TypeTable::GetOrCreateFunctionType"); return typeTable.at(tyIdx); diff --git a/src/mapleall/maple_ir/src/mir_builder.cpp b/src/mapleall/maple_ir/src/mir_builder.cpp index 9e57d1514f..965b2a83c6 100755 --- a/src/mapleall/maple_ir/src/mir_builder.cpp +++ b/src/mapleall/maple_ir/src/mir_builder.cpp @@ -836,6 +836,13 @@ IcallNode *MIRBuilder::CreateStmtIcall(const MapleVector &args) { return stmt; } +IcallNode *MIRBuilder::CreateStmtIcallproto(const MapleVector &args) { + auto *stmt = GetCurrentFuncCodeMp()->New(*GetCurrentFuncCodeMpAllocator(), OP_icallproto); + ASSERT(stmt != nullptr, "stmt is null"); + stmt->SetOpnds(args); + return stmt; +} + IcallNode *MIRBuilder::CreateStmtIcallAssigned(const MapleVector &args, const MIRSymbol &ret) { auto *stmt = GetCurrentFuncCodeMp()->New(*GetCurrentFuncCodeMpAllocator(), OP_icallassigned); CallReturnVector nrets(GetCurrentFuncCodeMpAllocator()->Adapter()); @@ -853,6 +860,23 @@ IcallNode *MIRBuilder::CreateStmtIcallAssigned(const MapleVector &arg return stmt; } +IcallNode *MIRBuilder::CreateStmtIcallprotoAssigned(const MapleVector &args, const MIRSymbol &ret) { + auto *stmt = GetCurrentFuncCodeMp()->New(*GetCurrentFuncCodeMpAllocator(), OP_icallprotoassigned); + CallReturnVector nrets(GetCurrentFuncCodeMpAllocator()->Adapter()); + CHECK_FATAL((ret.GetStorageClass() == kScAuto || ret.GetStorageClass() == kScFormal || + ret.GetStorageClass() == kScExtern || ret.GetStorageClass() == kScGlobal), + "unknown classtype! check it!"); + nrets.emplace_back(CallReturnPair(ret.GetStIdx(), RegFieldPair(0, 0))); + stmt->SetNumOpnds(args.size()); + stmt->GetNopnd().resize(stmt->GetNumOpnds()); + stmt->SetReturnVec(nrets); + for (size_t i = 0; i < stmt->GetNopndSize(); ++i) { + stmt->SetNOpndAt(i, args.at(i)); + } + stmt->SetRetTyIdx(ret.GetTyIdx()); + return stmt; +} + IntrinsiccallNode *MIRBuilder::CreateStmtIntrinsicCall(MIRIntrinsicID idx, const MapleVector &arguments, TyIdx tyIdx) { auto *stmt = GetCurrentFuncCodeMp()->New( diff --git a/src/mapleall/maple_ir/src/mir_function.cpp b/src/mapleall/maple_ir/src/mir_function.cpp index 112f5ad6cf..4f217e54c5 100644 --- a/src/mapleall/maple_ir/src/mir_function.cpp +++ b/src/mapleall/maple_ir/src/mir_function.cpp @@ -368,10 +368,8 @@ void MIRFunction::Dump(bool withoutBody) { LogInfo::MapleLogger() << " )"; } - if (module->GetFlavor() < kMmpl) { + if (module->GetFlavor() != kMmpl) { DumpFlavorLoweredThanMmpl(); - } else { - LogInfo::MapleLogger() << " () void"; } // codeMemPool is nullptr, means maple_ir has been released for memory's sake diff --git a/src/mapleall/maple_ir/src/mir_lower.cpp b/src/mapleall/maple_ir/src/mir_lower.cpp index 25cd280a07..8ea87d7d5f 100644 --- a/src/mapleall/maple_ir/src/mir_lower.cpp +++ b/src/mapleall/maple_ir/src/mir_lower.cpp @@ -544,6 +544,19 @@ BlockNode *MIRLower::LowerBlock(BlockNode &block) { case OP_doloop: newBlock->AppendStatementsFromBlock(*LowerDoloopStmt(static_cast(*stmt))); break; + case OP_icallassigned: + case OP_icall: { + if (mirModule.IsCModule()) { + // convert to icallproto/icallprotoassigned + IcallNode *ic = static_cast(stmt); + ic->SetOpCode(stmt->GetOpCode() == OP_icall ? OP_icallproto : OP_icallprotoassigned); + MIRFuncType *funcType = FuncTypeFromFuncPtrExpr(stmt->Opnd(0)); + CHECK_FATAL(funcType != nullptr, "MIRLower::LowerBlock: cannot find prototype for icall"); + ic->SetRetTyIdx(funcType->GetTypeIndex()); + } + newBlock->AddStatement(stmt); + break; + } case OP_block: tmp = LowerBlock(static_cast(*stmt)); newBlock->AppendStatementsFromBlock(*tmp); @@ -999,6 +1012,100 @@ void MIRLower::ExpandArrayMrt(MIRFunction &func) { } } +MIRFuncType *MIRLower::FuncTypeFromFuncPtrExpr(BaseNode *x) { + MIRFuncType *res = nullptr; + MIRFunction *func = mirModule.CurFunction(); + switch (x->GetOpCode()) { + case OP_regread: { + RegreadNode *regread = static_cast(x); + MIRPreg *preg = func->GetPregTab()->PregFromPregIdx(regread->GetRegIdx()); + // see if it is promoted from a symbol + if (preg->GetOp() == OP_dread) { + const MIRSymbol *symbol = preg->rematInfo.sym; + MIRType *mirType = symbol->GetType(); + if (preg->fieldID != 0) { + MIRStructType *structty = static_cast(mirType); + FieldPair thepair = structty->TraverseToField(preg->fieldID); + mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); + } + + if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + if (res != nullptr) { + break; + } + } + // check if a formal promoted to preg + for (FormalDef &formalDef : func->GetFormalDefVec()) { + if (!formalDef.formalSym->IsPreg()) { + continue; + } + if (formalDef.formalSym->GetPreg() == preg) { + MIRType *mirType = formalDef.formalSym->GetType(); + if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + break; + } + } + break; + } + case OP_dread: { + DreadNode *dread = static_cast(x); + MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); + MIRType *mirType = symbol->GetType(); + if (dread->GetFieldID() != 0) { + MIRStructType *structty = static_cast(mirType); + FieldPair thepair = structty->TraverseToField(dread->GetFieldID()); + mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); + } + if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + break; + } + case OP_iread: { + IreadNode *iread = static_cast(x); + MIRPtrType *ptrType = static_cast(iread->GetType()); + MIRType *mirType = ptrType->GetPointedType(); + if (mirType->GetKind() == kTypeFunction) { + res = static_cast(mirType); + } else if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + break; + } + case OP_addroffunc: { + AddroffuncNode *addrofFunc = static_cast(x); + PUIdx puIdx = addrofFunc->GetPUIdx(); + MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); + res = f->GetMIRFuncType(); + break; + } + case OP_retype: { + MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx( + static_cast(x)->GetTyIdx()); + if (mirType->GetKind() == kTypePointer) { + res = static_cast(mirType)->GetPointedFuncType(); + } + if (res == nullptr) { + res = FuncTypeFromFuncPtrExpr(x->Opnd(0)); + } + break; + } + case OP_select: { + res = FuncTypeFromFuncPtrExpr(x->Opnd(1)); + if (res == nullptr) { + res = FuncTypeFromFuncPtrExpr(x->Opnd(2)); + } + break; + } + default: CHECK_FATAL(false, "LMBCLowerer::FuncTypeFromFuncPtrExpr: NYI"); + } + return res; +} + const std::set MIRLower::kSetArrayHotFunc = {}; bool MIRLower::ShouldOptArrayMrt(const MIRFunction &func) { diff --git a/src/mapleall/maple_ir/src/mir_nodes.cpp b/src/mapleall/maple_ir/src/mir_nodes.cpp index 2cbc57b314..b969cc91ea 100755 --- a/src/mapleall/maple_ir/src/mir_nodes.cpp +++ b/src/mapleall/maple_ir/src/mir_nodes.cpp @@ -1203,7 +1203,7 @@ MIRType *IcallNode::GetCallReturnType() { if (op == OP_icall || op == OP_icallassigned) { return GlobalTables::GetTypeTable().GetTypeFromTyIdx(retTyIdx); } - // icallproto + // icallproto or icallprotoassigned MIRFuncType *funcType = static_cast( GlobalTables::GetTypeTable().GetTypeFromTyIdx(retTyIdx)); return GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcType->GetRetTyIdx()); @@ -1228,7 +1228,7 @@ const MIRSymbol *IcallNode::GetCallReturnSymbol(const MIRModule &mod) const { void IcallNode::Dump(int32 indent, bool newline) const { StmtNode::DumpBase(indent); - if (op == OP_icallproto) { + if (op == OP_icallproto || op == OP_icallprotoassigned) { LogInfo::MapleLogger() << " "; GlobalTables::GetTypeTable().GetTypeFromTyIdx(retTyIdx)->Dump(indent + 1); } diff --git a/src/mapleall/maple_ir/src/mir_parser.cpp b/src/mapleall/maple_ir/src/mir_parser.cpp index bae4762801..eada04a7b9 100755 --- a/src/mapleall/maple_ir/src/mir_parser.cpp +++ b/src/mapleall/maple_ir/src/mir_parser.cpp @@ -896,6 +896,7 @@ bool MIRParser::ParseStmtCall(StmtNodePtr &stmt) { callStmt->SetPUIdx(pIdx); MIRFunction *callee = GlobalTables::GetFunctionTable().GetFuncTable()[pIdx]; + callee->GetFuncSymbol()->SetAppearsInCode(true); if (callee->GetName() == "setjmp") { mod.CurFunction()->SetHasSetjmp(); } @@ -932,9 +933,14 @@ bool MIRParser::ParseStmtIcall(StmtNodePtr &stmt, Opcode op) { // . . . // dassign } // icallproto (, , ..., ) + // icallprotoassigned (, , ..., ) { + // dassign + // dassign + // . . . + // dassign } IcallNode *iCallStmt = mod.CurFuncCodeMemPool()->New(mod, op); lexer.NextToken(); - if (op == OP_icallproto) { + if (op == OP_icallproto || op == OP_icallprotoassigned) { TyIdx tyIdx(0); if (!ParseDerivedType(tyIdx)) { Error("error parsing type in ParseStmtIcall for icallproto at "); @@ -948,7 +954,7 @@ bool MIRParser::ParseStmtIcall(StmtNodePtr &stmt, Opcode op) { } iCallStmt->SetNOpnd(opndsVec); iCallStmt->SetNumOpnds(opndsVec.size()); - if (op == OP_icallassigned) { + if (op == OP_icallassigned || op == OP_icallprotoassigned) { CallReturnVector retsVec(mod.CurFuncCodeMemPoolAllocator()->Adapter()); if (!ParseCallReturns(retsVec)) { return false; @@ -972,6 +978,10 @@ bool MIRParser::ParseStmtIcallproto(StmtNodePtr &stmt) { return ParseStmtIcall(stmt, OP_icallproto); } +bool MIRParser::ParseStmtIcallprotoassigned(StmtNodePtr &stmt) { + return ParseStmtIcall(stmt, OP_icallprotoassigned); +} + bool MIRParser::ParseStmtIntrinsiccall(StmtNodePtr &stmt, bool isAssigned) { Opcode o = !isAssigned ? (lexer.GetTokenKind() == TK_intrinsiccall ? OP_intrinsiccall : OP_xintrinsiccall) : (lexer.GetTokenKind() == TK_intrinsiccallassigned ? OP_intrinsiccallassigned @@ -2013,18 +2023,6 @@ bool MIRParser::ParseStmtBlockForUpformalSize() { return true; } -bool MIRParser::ParseStmtBlockForOutParmSize() { - MIRFunction *fn = paramCurrFuncForParseStmtBlock; - lexer.NextToken(); - if (lexer.GetTokenKind() != TK_intconst) { - Error("expect integer after outparmsize but get "); - return false; - } - fn->SetOutParmSize(static_cast(lexer.GetTheIntVal())); - lexer.NextToken(); - return true; -} - bool MIRParser::ParseStmtBlockForModuleID() { MIRFunction *fn = paramCurrFuncForParseStmtBlock; lexer.NextToken(); @@ -3241,7 +3239,8 @@ bool MIRParser::ParseConstAddrLeafExpr(MIRConstPtr &cexpr) { } else if (expr->GetOpCode() == OP_addroffunc) { auto *aof = static_cast(expr); MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(aof->GetPUIdx()); - const MIRSymbol *fName = f->GetFuncSymbol(); + MIRSymbol *fName = f->GetFuncSymbol(); + fName->SetAppearsInCode(true); TyIdx ptyIdx = fName->GetTyIdx(); MIRPtrType ptrType(ptyIdx); ptyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&ptrType); @@ -3415,6 +3414,7 @@ std::map MIRParser::InitFuncPtrMapForPar funcPtrMap[TK_icall] = &MIRParser::ParseStmtIcall; funcPtrMap[TK_icallassigned] = &MIRParser::ParseStmtIcallassigned; funcPtrMap[TK_icallproto] = &MIRParser::ParseStmtIcallproto; + funcPtrMap[TK_icallprotoassigned] = &MIRParser::ParseStmtIcallprotoassigned; funcPtrMap[TK_intrinsiccall] = &MIRParser::ParseStmtIntrinsiccall; funcPtrMap[TK_intrinsiccallassigned] = &MIRParser::ParseStmtIntrinsiccallassigned; funcPtrMap[TK_xintrinsiccall] = &MIRParser::ParseStmtIntrinsiccall; @@ -3475,7 +3475,6 @@ std::map MIRParser::InitFuncPtrMapF funcPtrMap[TK_type] = &MIRParser::ParseStmtBlockForType; funcPtrMap[TK_framesize] = &MIRParser::ParseStmtBlockForFrameSize; funcPtrMap[TK_upformalsize] = &MIRParser::ParseStmtBlockForUpformalSize; - funcPtrMap[TK_outparmsize] = &MIRParser::ParseStmtBlockForOutParmSize; funcPtrMap[TK_moduleid] = &MIRParser::ParseStmtBlockForModuleID; funcPtrMap[TK_funcsize] = &MIRParser::ParseStmtBlockForFuncSize; funcPtrMap[TK_funcid] = &MIRParser::ParseStmtBlockForFuncID; diff --git a/src/mapleall/maple_ir/src/mir_type.cpp b/src/mapleall/maple_ir/src/mir_type.cpp index 0c9ff37468..6dac1d09d5 100644 --- a/src/mapleall/maple_ir/src/mir_type.cpp +++ b/src/mapleall/maple_ir/src/mir_type.cpp @@ -738,7 +738,9 @@ void MIRFuncType::Dump(int indent, bool dontUseName) const { if (!dontUseName && CheckAndDumpTypeName(nameStrIdx, nameIsLocal)) { return; } - LogInfo::MapleLogger() << "Dump(indent + 1); @@ -749,7 +751,7 @@ void MIRFuncType::Dump(int indent, bool dontUseName) const { LogInfo::MapleLogger() << ","; } } - if (isVarArgs) { + if (IsVarargs()) { LogInfo::MapleLogger() << ", ..."; } LogInfo::MapleLogger() << ") "; @@ -1663,7 +1665,7 @@ bool MIRFuncType::EqualTo(const MIRType &type) const { } const auto &pType = static_cast(type); return (pType.retTyIdx == retTyIdx && pType.paramTypeList == paramTypeList && - pType.isVarArgs == isVarArgs && pType.paramAttrsList == paramAttrsList && + pType.funcAttrs == funcAttrs && pType.paramAttrsList == paramAttrsList && pType.retAttrs == retAttrs); } diff --git a/src/mapleall/maple_ir/src/parser.cpp b/src/mapleall/maple_ir/src/parser.cpp index db50916351..e8c9178367 100644 --- a/src/mapleall/maple_ir/src/parser.cpp +++ b/src/mapleall/maple_ir/src/parser.cpp @@ -229,9 +229,7 @@ bool MIRParser::ParsePseudoReg(PrimType primType, PregIdx &pRegIdx) { MIRPreg *preg = curfunc->GetPregTab()->PregFromPregIdx(pRegIdx); if (primType != kPtyInvalid) { if (preg->GetPrimType() != primType) { - if ((primType == PTY_ref || primType == PTY_ptr) && - (preg->GetPrimType() == PTY_ref || preg->GetPrimType() == PTY_ptr)) { - ; // PTY_ref and PTY_ptr are compatible with each other + if (IsAddress(preg->GetPrimType()) && IsAddress(primType)) { } else { Error("inconsistent preg primitive type at "); return false; @@ -1299,6 +1297,15 @@ bool MIRParser::ParsePointType(TyIdx &tyIdx) { // in function pointer specification and member function prototypes inside // structs and classes bool MIRParser::ParseFuncType(TyIdx &tyIdx) { + // parse function attributes + FuncAttrs fAttrs; + if (lexer.GetTokenKind() != TK_lparen) { + if (!ParseFuncAttrs(fAttrs)) { + Error("bad function attribute specification in function type at "); + return false; + } + } + // parse parameters if (lexer.GetTokenKind() != TK_lparen) { Error("expect ( parse function type parameters but get "); @@ -1359,7 +1366,10 @@ bool MIRParser::ParseFuncType(TyIdx &tyIdx) { return false; } MIRFuncType functype(retTyIdx, vecTyIdx, vecAttrs, retTypeAttrs); - functype.SetVarArgs(varargs); + functype.funcAttrs = fAttrs; + if (varargs) { + functype.SetVarArgs(); + } tyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&functype); return true; } diff --git a/src/mapleall/maple_me/include/lmbc_lower.h b/src/mapleall/maple_me/include/lmbc_lower.h index 9462204fd7..bbeaabf098 100644 --- a/src/mapleall/maple_me/include/lmbc_lower.h +++ b/src/mapleall/maple_me/include/lmbc_lower.h @@ -40,10 +40,7 @@ class LMBCLowerer { void LowerIassign(IassignNode *, BlockNode *); void LowerAggIassign(IassignNode *, MIRType *type, int32 offset, BlockNode *); void LowerReturn(NaryStmtNode *retNode, BlockNode *newblk); - MIRFuncType *FuncTypeFromFuncPtrExpr(BaseNode *x); - void LowerCall(NaryStmtNode *callNode, BlockNode *newblk); BlockNode *LowerBlock(BlockNode *); - void LoadFormalsAssignedToPregs(); void LowerFunction(); MIRModule *mirModule; diff --git a/src/mapleall/maple_me/include/lmbc_memlayout.h b/src/mapleall/maple_me/include/lmbc_memlayout.h index 68253bb226..833b357561 100644 --- a/src/mapleall/maple_me/include/lmbc_memlayout.h +++ b/src/mapleall/maple_me/include/lmbc_memlayout.h @@ -31,8 +31,8 @@ typedef enum { MS_actual, // for the outgoing parameters MS_local, // for all local variables and temporaries MS_FPbased, // addressed via offset from the frame pointer - MS_SPbased, // addressed via offset from the stack pointer MS_GPbased, // addressed via offset from the global pointer + MS_largeStructActual, // for storing large struct actuals passed by value for ARM CPU } MemSegmentKind; class MemSegment; @@ -66,15 +66,10 @@ class MemSegment { class LMBCMemLayout { public: - uint32 FindLargestActualArea(void); - uint32 FindLargestActualArea(StmtNode *, int &); - LMBCMemLayout(MIRFunction *f, MapleAllocator *mallocator) + LMBCMemLayout(MIRFunction *f, MemSegment *segGP, MapleAllocator *mallocator) : func(f), - seg_upformal(MS_upformal), - seg_formal(MS_formal), - seg_actual(MS_actual), + seg_GPbased(segGP), seg_FPbased(MS_FPbased), - seg_SPbased(MS_SPbased), sym_alloc_table(mallocator->Adapter()) { sym_alloc_table.resize(f->GetSymTab()->GetSymbolTableSize()); } @@ -85,70 +80,25 @@ class LMBCMemLayout { void LayoutStackFrame(void); int32 StackFrameSize(void) const { - return seg_SPbased.size - seg_FPbased.size; - } - - int32 UpformalSize(void) const { - return seg_upformal.size; + return -seg_FPbased.size; } MIRFunction *func; - MemSegment seg_upformal; - MemSegment seg_formal; - MemSegment seg_actual; + MemSegment *seg_GPbased; MemSegment seg_FPbased; - MemSegment seg_SPbased; MapleVector sym_alloc_table; // index is StIdx }; class GlobalMemLayout { public: - GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAllocator *mallocator); - ~GlobalMemLayout() { - be = nullptr; - mirModule = nullptr; - } + GlobalMemLayout(MIRModule *mod, MapleAllocator *mallocator); + ~GlobalMemLayout() {} MemSegment seg_GPbased; MapleVector sym_alloc_table; // index is StIdx - - private: - void FillScalarValueInMap(uint32 startaddress, PrimType pty, MIRConst *c); - void FillTypeValueInMap(uint32 startaddress, MIRType *ty, MIRConst *c); - void FillSymbolValueInMap(const MIRSymbol *sym); - - maplebe::BECommon *be; MIRModule *mirModule; }; -// for specifying how a parameter is passed -struct PLocInfo { - int32 memoffset; - int32 memsize; -}; - -// for processing an incoming or outgoing parameter list -class ParmLocator { - public: - explicit ParmLocator() : parmNum(0), lastMemOffset(0) {} - - ~ParmLocator() {} - - void LocateNextParm(const MIRType *ty, PLocInfo &ploc); - - private: - int32 parmNum; // number of all types of parameters processed so far - int32 lastMemOffset; -}; - -// given the type of the return value, determines the return mechanism -class ReturnMechanism { - public: - ReturnMechanism(const MIRType *retty); - bool fake_first_parm; // whether returning in memory via fake first parameter - PrimType ptype0; // the primitive type stored in retval0 -}; - } /* namespace maple */ #endif /* MAPLEME_INCLUDE_LMBC_MEMLAYOUT_H */ diff --git a/src/mapleall/maple_me/src/alias_class.cpp b/src/mapleall/maple_me/src/alias_class.cpp index c4ef286887..41af97d454 100644 --- a/src/mapleall/maple_me/src/alias_class.cpp +++ b/src/mapleall/maple_me/src/alias_class.cpp @@ -1018,7 +1018,9 @@ void AliasClass::ApplyUnionForCopies(StmtNode &stmt) { } case OP_asm: case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { for (uint32 i = 0; i < stmt.NumOpnds(); ++i) { const AliasInfo &ainfo = CreateAliasInfoExpr(*stmt.Opnd(i)); if (stmt.GetOpCode() != OP_asm && i == 0) { @@ -2569,6 +2571,7 @@ void AliasClass::GenericInsertMayDefUse(StmtNode &stmt, BBId bbID) { case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_virtualcall: case OP_virtualicall: case OP_superclasscall: @@ -2576,7 +2579,8 @@ void AliasClass::GenericInsertMayDefUse(StmtNode &stmt, BBId bbID) { case OP_interfaceicall: case OP_customcall: case OP_polymorphiccall: - case OP_icall: { + case OP_icall: + case OP_icallproto: { InsertMayDefUseCall(stmt, bbID, false); return; } diff --git a/src/mapleall/maple_me/src/code_factoring.cpp b/src/mapleall/maple_me/src/code_factoring.cpp index 175cead017..21f3103b3a 100644 --- a/src/mapleall/maple_me/src/code_factoring.cpp +++ b/src/mapleall/maple_me/src/code_factoring.cpp @@ -126,7 +126,9 @@ bool FactoringOptimizer::IsIdenticalStmt(StmtNode *stmt1, StmtNode *stmt2) { break; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { auto *icall1 = static_cast(stmt1); auto *icall2 = static_cast(stmt2); if (icall1->GetRetTyIdx() != icall2->GetRetTyIdx() || diff --git a/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp b/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp index 2bb97532a6..ba545a5991 100644 --- a/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp +++ b/src/mapleall/maple_me/src/demand_driven_alias_analysis.cpp @@ -642,7 +642,9 @@ void PEGBuilder::BuildPEGNodeInStmt(const StmtNode *stmt) { break; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { BuildPEGNodeInIcall(static_cast(stmt)); break; } diff --git a/src/mapleall/maple_me/src/irmap_build.cpp b/src/mapleall/maple_me/src/irmap_build.cpp index 92eece9fa0..b6d96b6726 100755 --- a/src/mapleall/maple_me/src/irmap_build.cpp +++ b/src/mapleall/maple_me/src/irmap_build.cpp @@ -808,7 +808,7 @@ MeStmt *IRMapBuild::BuildCallMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { MeStmt *IRMapBuild::BuildNaryMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { Opcode op = stmt.GetOpCode(); - NaryMeStmt *naryMeStmt = (op == OP_icall || op == OP_icallassigned) + NaryMeStmt *naryMeStmt = (op == OP_icall || op == OP_icallassigned || op == OP_icallproto || op == OP_icallprotoassigned) ? static_cast(irMap->NewInPool(&stmt)) : static_cast(irMap->NewInPool(&stmt)); auto &naryStmtNode = static_cast(stmt); @@ -823,6 +823,9 @@ MeStmt *IRMapBuild::BuildNaryMeStmt(StmtNode &stmt, AccessSSANodes &ssaPart) { if (propagater) { propagater->PropUpdateChiListDef(*naryMeStmt->GetChiList()); } + if (op == OP_icallproto || op == OP_icallprotoassigned) { + static_cast(naryMeStmt)->SetRetTyIdx(static_cast(stmt).GetRetTyIdx()); + } return naryMeStmt; } @@ -923,6 +926,8 @@ void IRMapBuild::InitMeStmtFactory() { RegisterFactoryFunction(OP_polymorphiccallassigned, &IRMapBuild::BuildCallMeStmt); RegisterFactoryFunction(OP_icall, &IRMapBuild::BuildNaryMeStmt); RegisterFactoryFunction(OP_icallassigned, &IRMapBuild::BuildNaryMeStmt); + RegisterFactoryFunction(OP_icallproto, &IRMapBuild::BuildNaryMeStmt); + RegisterFactoryFunction(OP_icallprotoassigned, &IRMapBuild::BuildNaryMeStmt); RegisterFactoryFunction(OP_intrinsiccall, &IRMapBuild::BuildNaryMeStmt); RegisterFactoryFunction(OP_xintrinsiccall, &IRMapBuild::BuildNaryMeStmt); RegisterFactoryFunction(OP_intrinsiccallwithtype, &IRMapBuild::BuildNaryMeStmt); diff --git a/src/mapleall/maple_me/src/irmap_emit.cpp b/src/mapleall/maple_me/src/irmap_emit.cpp index 1f5f45518c..f6d7b046d8 100755 --- a/src/mapleall/maple_me/src/irmap_emit.cpp +++ b/src/mapleall/maple_me/src/irmap_emit.cpp @@ -412,7 +412,7 @@ MIRFunction &CallMeStmt::GetTargetFunction() { } StmtNode &CallMeStmt::EmitStmt(SSATab &ssaTab) { - if (GetOp() != OP_icall && GetOp() != OP_icallassigned) { + if (GetOp() != OP_icall && GetOp() != OP_icallassigned && GetOp() != OP_icallproto && GetOp() != OP_icallprotoassigned) { auto *callNode = ssaTab.GetModule().CurFunction()->GetCodeMempool()->New(ssaTab.GetModule(), Opcode(GetOp())); callNode->SetPUIdx(puIdx); @@ -497,6 +497,9 @@ StmtNode &IcallMeStmt::EmitStmt(SSATab &ssaTab) { } } } + if (GetOp() == OP_icallproto || GetOp() == OP_icallprotoassigned) { + icallNode->SetRetTyIdx(retTyIdx); + } return *icallNode; } diff --git a/src/mapleall/maple_me/src/lfo_dep_test.cpp b/src/mapleall/maple_me/src/lfo_dep_test.cpp index b1273a8fc3..33f19ee452 100644 --- a/src/mapleall/maple_me/src/lfo_dep_test.cpp +++ b/src/mapleall/maple_me/src/lfo_dep_test.cpp @@ -66,6 +66,8 @@ void LfoDepInfo::CreateDoloopInfo(BlockNode *block, DoloopInfo *parent) { case OP_callassigned: case OP_icall: case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: case OP_return: case OP_throw: case OP_asm: diff --git a/src/mapleall/maple_me/src/lmbc_lower.cpp b/src/mapleall/maple_me/src/lmbc_lower.cpp index a155b25fa4..f5893447ba 100644 --- a/src/mapleall/maple_me/src/lmbc_lower.cpp +++ b/src/mapleall/maple_me/src/lmbc_lower.cpp @@ -22,16 +22,12 @@ using namespace std; PregIdx LMBCLowerer::GetSpecialRegFromSt(const MIRSymbol *sym) { MIRStorageClass storageClass = sym->GetStorageClass(); PregIdx specreg = 0; - if (storageClass == kScAuto || storageClass == kScFormal) { + if (storageClass == kScAuto) { CHECK(sym->GetStIndex() < memlayout->sym_alloc_table.size(), "index out of range in LMBCLowerer::GetSpecialRegFromSt"); SymbolAlloc symalloc = memlayout->sym_alloc_table[sym->GetStIndex()]; - if (symalloc.mem_segment->kind == MS_upformal || symalloc.mem_segment->kind == MS_formal || - symalloc.mem_segment->kind == MS_FPbased) { + if (symalloc.mem_segment->kind == MS_FPbased) { specreg = -kSregFp; - } else if (symalloc.mem_segment->kind == MS_actual || - symalloc.mem_segment->kind == MS_SPbased) { - specreg = -kSregSp; } else { CHECK_FATAL(false, "LMBCLowerer::LowerDread: bad memory layout for local variable"); } @@ -46,6 +42,7 @@ PregIdx LMBCLowerer::GetSpecialRegFromSt(const MIRSymbol *sym) { BaseNode *LMBCLowerer::LowerAddrof(AddrofNode *expr) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(expr->GetStIdx()); + symbol->ResetIsDeleted(); int32 offset = 0; if (expr->GetFieldID() != 0) { MIRStructType *structty = static_cast(symbol->GetType()); @@ -66,6 +63,7 @@ BaseNode *LMBCLowerer::LowerAddrof(AddrofNode *expr) { BaseNode *LMBCLowerer::LowerDread(AddrofNode *expr) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(expr->GetStIdx()); + symbol->ResetIsDeleted(); PrimType symty = symbol->GetType()->GetPrimType(); int32 offset = 0; if (expr->GetFieldID() != 0) { @@ -96,20 +94,22 @@ BaseNode *LMBCLowerer::LowerDread(AddrofNode *expr) { BaseNode *LMBCLowerer::LowerDreadoff(DreadoffNode *dreadoff) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dreadoff->stIdx); + symbol->ResetIsDeleted(); if (!symbol->LMBCAllocateOffSpecialReg()) { return dreadoff; } + PrimType symty = symbol->GetType()->GetPrimType(); PregIdx spcreg = GetSpecialRegFromSt(symbol); if (spcreg == -kSregFp) { CHECK_FATAL(symbol->IsLocal(), "load from fp non local?"); - IreadFPoffNode *ireadoff = mirBuilder->CreateExprIreadFPoff( - dreadoff->GetPrimType(), memlayout->sym_alloc_table[symbol->GetStIndex()].offset + dreadoff->offset); + IreadFPoffNode *ireadoff = mirBuilder->CreateExprIreadFPoff(symty, + memlayout->sym_alloc_table[symbol->GetStIndex()].offset + dreadoff->offset); return ireadoff; } else { BaseNode *rrn = mirBuilder->CreateExprRegread(LOWERED_PTR_TYPE, spcreg); SymbolAlloc &symalloc = symbol->IsLocal() ? memlayout->sym_alloc_table[symbol->GetStIndex()] : globmemlayout->sym_alloc_table[symbol->GetStIndex()]; - IreadoffNode *ireadoff = mirBuilder->CreateExprIreadoff(dreadoff->GetPrimType(), symalloc.offset + dreadoff->offset, rrn); + IreadoffNode *ireadoff = mirBuilder->CreateExprIreadoff(symty, symalloc.offset + dreadoff->offset, rrn); return ireadoff; } } @@ -129,14 +129,14 @@ static MIRType *GetPointedToType(const MIRPtrType *pointerty) { BaseNode *LMBCLowerer::LowerIread(IreadNode *expr) { int32 offset = 0; + MIRPtrType *ptrType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(expr->GetTyIdx())); + MIRType *type = ptrType->GetPointedType(); if (expr->GetFieldID() != 0) { - MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(expr->GetTyIdx()); - MIRStructType *structty = - static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(type)->GetPointedTyIdx())); + MIRStructType *structty = static_cast(type); offset = becommon->GetFieldOffset(*structty, expr->GetFieldID()).first; + type = structty->GetFieldType(expr->GetFieldID()); } - BaseNode *ireadoff = mirBuilder->CreateExprIreadoff(expr->GetPrimType(), offset, expr->Opnd(0)); + BaseNode *ireadoff = mirBuilder->CreateExprIreadoff(type->GetPrimType(), offset, expr->Opnd(0)); return ireadoff; } @@ -165,6 +165,7 @@ BaseNode *LMBCLowerer::LowerExpr(BaseNode *expr) { return LowerAddrof(static_cast(expr)); case OP_addrofoff: { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(static_cast(expr)->stIdx); + symbol->ResetIsDeleted(); CHECK_FATAL(!symbol->LMBCAllocateOffSpecialReg(), "LMBCLowerer:: illegal addrofoff instruction"); break; @@ -199,6 +200,7 @@ void LMBCLowerer::LowerAggDassign(const DassignNode *dsnode, MIRType *lhsty, // generate lhs address expression BaseNode *lhs = nullptr; MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dsnode->GetStIdx()); + symbol->ResetIsDeleted(); if (!symbol->LMBCAllocateOffSpecialReg()) { lhs = mirBuilder->CreateExprDreadoff(OP_addrofoff, LOWERED_PTR_TYPE, *symbol, offset); } else { @@ -218,6 +220,7 @@ void LMBCLowerer::LowerAggDassign(const DassignNode *dsnode, MIRType *lhsty, void LMBCLowerer::LowerDassign(DassignNode *dsnode, BlockNode *newblk) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dsnode->GetStIdx()); + symbol->ResetIsDeleted(); MIRType *symty = symbol->GetType(); int32 offset = 0; if (dsnode->GetFieldID() != 0) { @@ -259,6 +262,7 @@ void LMBCLowerer::LowerDassign(DassignNode *dsnode, BlockNode *newblk) { void LMBCLowerer::LowerDassignoff(DassignoffNode *dsnode, BlockNode *newblk) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dsnode->stIdx); + symbol->ResetIsDeleted(); CHECK_FATAL(dsnode->Opnd(0)->GetPrimType() != PTY_agg, "LowerDassignoff: agg primitive type NYI"); BaseNode *rhs = LowerExpr(dsnode->Opnd(0)); if (!symbol->LMBCAllocateOffSpecialReg()) { @@ -334,6 +338,9 @@ void LMBCLowerer::LowerIassign(IassignNode *iassign, BlockNode *newblk) { } if (iassign->GetRHS()->GetPrimType() != PTY_agg) { PrimType ptypused = type->GetPrimType(); + if (ptypused == PTY_agg) { + ptypused = iassign->GetRHS()->GetPrimType(); + } IassignoffNode *iassignoff = mirBuilder->CreateStmtIassignoff(ptypused, offset, iassign->addrExpr, @@ -347,15 +354,20 @@ void LMBCLowerer::LowerIassign(IassignNode *iassign, BlockNode *newblk) { // called only if the return has > 1 operand; assume prior lowering already // converted any return of structs to be via fake parameter void LMBCLowerer::LowerReturn(NaryStmtNode *retNode, BlockNode *newblk) { - CHECK_FATAL(retNode->NumOpnds() <= 2, "LMBCLowerer::LowerReturn: more than 2 return values NYI"); - for (int i = 0; i < retNode->NumOpnds(); i++) { - CHECK_FATAL(retNode->Opnd(i)->GetPrimType() != PTY_agg, - "LMBCLowerer::LowerReturn: return of aggregate needs to be handled first"); - // insert regassign for the returned value - BaseNode *rhs = LowerExpr(retNode->Opnd(i)); - RegassignNode *regasgn = mirBuilder->CreateStmtRegassign(rhs->GetPrimType(), - i == 0 ? -kSregRetval0 : -kSregRetval1, - rhs); + if (retNode->Opnd(0)->GetPrimType() != PTY_agg) { + CHECK_FATAL(retNode->NumOpnds() <= 2, "LMBCLowerer::LowerReturn: more than 2 return values NYI"); + for (int i = 0; i < retNode->NumOpnds(); i++) { + // insert regassign for the returned value + PrimType ptyp = retNode->Opnd(i)->GetPrimType(); + BaseNode *rhs = LowerExpr(retNode->Opnd(i)); + RegassignNode *regasgn = mirBuilder->CreateStmtRegassign(ptyp, + i == 0 ? -kSregRetval0 : -kSregRetval1, + rhs); + newblk->AddStatement(regasgn); + } + } else { // handle return of small struct using only %%retval0 + BaseNode *rhs = LowerExpr(retNode->Opnd(0)); + RegassignNode *regasgn = mirBuilder->CreateStmtRegassign(PTY_agg, -kSregRetval0, rhs); newblk->AddStatement(regasgn); } retNode->GetNopnd().clear(); // remove the return operands @@ -363,178 +375,6 @@ void LMBCLowerer::LowerReturn(NaryStmtNode *retNode, BlockNode *newblk) { newblk->AddStatement(retNode); } -MIRFuncType *LMBCLowerer::FuncTypeFromFuncPtrExpr(BaseNode *x) { - MIRFuncType *res = nullptr; - switch (x->GetOpCode()) { - case OP_regread: { - RegreadNode *regread = static_cast(x); - MIRPreg *preg = func->GetPregTab()->PregFromPregIdx(regread->GetRegIdx()); - // see if it is promoted from a symbol - if (preg->GetOp() == OP_dread) { - const MIRSymbol *symbol = preg->rematInfo.sym; - MIRType *mirType = symbol->GetType(); - if (preg->fieldID != 0) { - MIRStructType *structty = static_cast(mirType); - FieldPair thepair = structty->TraverseToField(preg->fieldID); - mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - if (res != nullptr) { - break; - } - } - // check if a formal promoted to preg - for (FormalDef &formalDef : func->GetFormalDefVec()) { - if (!formalDef.formalSym->IsPreg()) { - continue; - } - if (formalDef.formalSym->GetPreg() == preg) { - MIRType *mirType = formalDef.formalSym->GetType(); - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - break; - } - } - break; - } - case OP_dread: { - DreadNode *dread = static_cast(x); - MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); - MIRType *mirType = symbol->GetType(); - if (dread->GetFieldID() != 0) { - MIRStructType *structty = static_cast(mirType); - FieldPair thepair = structty->TraverseToField(dread->GetFieldID()); - mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - break; - } - case OP_iread: { - IreadNode *iread = static_cast(x); - MIRPtrType *ptrType = static_cast(iread->GetType()); - MIRType *mirType = ptrType->GetPointedType(); - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - break; - } - case OP_addroffunc: { - AddroffuncNode *addrofFunc = static_cast(x); - PUIdx puIdx = addrofFunc->GetPUIdx(); - MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx); - res = f->GetMIRFuncType(); - break; - } - case OP_retype: { - MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(x)->GetTyIdx()); - if (mirType->GetKind() == kTypePointer) { - res = static_cast(mirType)->GetPointedFuncType(); - } - if (res == nullptr) { - res = FuncTypeFromFuncPtrExpr(x->Opnd(0)); - } - break; - } - case OP_select: { - res = FuncTypeFromFuncPtrExpr(x->Opnd(1)); - if (res == nullptr) { - res = FuncTypeFromFuncPtrExpr(x->Opnd(2)); - } - break; - } - default: CHECK_FATAL(false, "LMBCLowerer::FuncTypeFromFuncPtrExpr: NYI"); - } - return res; -} - -void LMBCLowerer::LowerCall(NaryStmtNode *naryStmt, BlockNode *newblk) { - // go through each parameter - uint32 i = 0; - if (naryStmt->GetOpCode() == OP_icall || naryStmt->GetOpCode() == OP_icallassigned) { - i = 1; - } - ParmLocator parmlocator; - for (; i < naryStmt->NumOpnds(); i++) { - BaseNode *opnd = naryStmt->Opnd(i); - MIRType *ty = nullptr; - // get ty for this parameter - if (opnd->GetPrimType() != PTY_agg) { - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(static_cast(opnd->GetPrimType())); - } else { - Opcode opnd_opcode = opnd->GetOpCode(); - CHECK_FATAL(opnd_opcode == OP_dread || opnd_opcode == OP_iread, ""); - if (opnd_opcode == OP_dread) { - AddrofNode *dread = static_cast(opnd); - MIRSymbol *sym = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx()); - if (dread->GetFieldID() != 0) { - CHECK_FATAL(ty->IsStructType(), ""); - FieldPair thepair = static_cast(ty)->TraverseToField(dread->GetFieldID()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - } else { // OP_iread - IreadNode *iread = static_cast(opnd); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread->GetTyIdx()); - CHECK_FATAL(ty->GetKind() == kTypePointer, ""); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(ty)->GetPointedTyIdx()); - if (iread->GetFieldID() != 0) { - CHECK_FATAL(ty->IsStructType(), ""); - FieldPair thepair = static_cast(ty)->TraverseToField(iread->GetFieldID()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - } - } - PLocInfo ploc; - parmlocator.LocateNextParm(ty, ploc); - if (opnd->GetPrimType() != PTY_agg) { - IassignFPoffNode *iass = mirBuilder->CreateStmtIassignFPoff(OP_iassignspoff, - opnd->GetPrimType(), - ploc.memoffset, - LowerExpr(opnd)); - newblk->AddStatement(iass); - } else { - BlkassignoffNode *bass = - mirModule->CurFuncCodeMemPool()->New(ploc.memoffset, ploc.memsize); - bass->SetAlign(std::min(ty->GetAlign(), 8u)); - bass->SetBOpnd(mirBuilder->CreateExprRegread(LOWERED_PTR_TYPE, -kSregSp), 0); - // the operand is either OP_dread or OP_iread; use its address instead - if (opnd->GetOpCode() == OP_dread) { - opnd->SetOpCode(OP_addrof); - } else { - opnd->SetOpCode(OP_iaddrof); - } - opnd->SetPrimType(LOWERED_PTR_TYPE); - bass->SetBOpnd(LowerExpr(opnd), 1); - newblk->AddStatement(bass); - } - } - BaseNode *opnd0 = nullptr; - if (naryStmt->GetOpCode() == OP_icall || naryStmt->GetOpCode() == OP_icallassigned) { - opnd0 = naryStmt->Opnd(0); - naryStmt->GetNopnd().clear(); // remove the call operands - // convert to OP_icallproto by finding the function prototype and record in stmt - naryStmt->SetOpCode(OP_icallproto); - MIRFuncType *funcType = FuncTypeFromFuncPtrExpr(opnd0); - CHECK_FATAL(funcType != nullptr, "LMBCLowerer::LowerCall: cannot find prototype for icall"); - static_cast(naryStmt)->SetRetTyIdx(funcType->GetTypeIndex()); - // add back the function pointer operand - naryStmt->GetNopnd().push_back(LowerExpr(opnd0)); - naryStmt->SetNumOpnds(1); - } else { - naryStmt->GetNopnd().clear(); // remove the call operands - naryStmt->SetNumOpnds(0); - } - newblk->AddStatement(naryStmt); -} - BlockNode *LMBCLowerer::LowerBlock(BlockNode *block) { BlockNode *newblk = mirModule->CurFuncCodeMemPool()->New(); if (!block->GetFirst()) { @@ -569,10 +409,6 @@ BlockNode *LMBCLowerer::LowerBlock(BlockNode *block) { } else { LowerReturn(retNode, newblk); } - } - case OP_call: - case OP_icall: { - LowerCall(static_cast(stmt), newblk); break; } default: { @@ -587,29 +423,19 @@ BlockNode *LMBCLowerer::LowerBlock(BlockNode *block) { return newblk; } -void LMBCLowerer::LoadFormalsAssignedToPregs() { - // go through each formals - for (int32 i = func->GetFormalDefVec().size()-1; i >= 0; i--) { - MIRSymbol *formalSt = func->GetFormalDefVec()[i].formalSym; - if (formalSt->GetSKind() != kStPreg) { - continue; +void LMBCLowerer::LowerFunction() { + // set extern global vars' isDeleted field; will reset when visited + MapleVector::const_iterator sit = mirModule->GetSymbolDefOrder().begin(); + for (; sit != mirModule->GetSymbolDefOrder().end(); ++sit) { + MIRSymbol *s = GlobalTables::GetGsymTable().GetSymbolFromStidx(sit->Idx()); + if (s->GetSKind() == kStVar && s->GetStorageClass() == kScExtern && !s->HasPotentialAssignment()) { + s->SetIsDeleted(); } - MIRPreg *preg = formalSt->GetPreg(); - uint32 stindex = formalSt->GetStIndex(); - PrimType pty = formalSt->GetType()->GetPrimType(); - IreadFPoffNode *ireadfpoff = mirBuilder->CreateExprIreadFPoff(pty, - memlayout->sym_alloc_table[stindex].offset); - RegassignNode *rass = mirBuilder->CreateStmtRegassign(pty, - func->GetPregTab()->GetPregIdxFromPregno(preg->GetPregNo()), ireadfpoff); - func->GetBody()->InsertFirst(rass); } -} -void LMBCLowerer::LowerFunction() { BlockNode *origbody = func->GetBody(); BlockNode *newbody = LowerBlock(origbody); func->SetBody(newbody); - LoadFormalsAssignedToPregs(); } } // namespace maple diff --git a/src/mapleall/maple_me/src/lmbc_memlayout.cpp b/src/mapleall/maple_me/src/lmbc_memlayout.cpp index d7c2a097eb..b32acae493 100644 --- a/src/mapleall/maple_me/src/lmbc_memlayout.cpp +++ b/src/mapleall/maple_me/src/lmbc_memlayout.cpp @@ -13,146 +13,40 @@ * See the MulanPSL - 2.0 for more details. */ -// For each function being compiled, lay out its parameters, return values and -// local variables on its stack frame. This involves determining how parameters -// and return values are passed from analyzing their types. -// -// Allocate all the global variables within the global memory block which is -// addressed via offset from the global pointer GP during execution. Allocate -// this block pointed to by mirModule.globalBlkMap and perform the static -// initializations. +// For each function being compiled, lay out its local variables on its stack +// frame. Allocate all the global variables within the global memory block +// which is addressed via offset from the global pointer GP during execution. +// Allocate this block pointed to by mirModule.globalBlkMap. #include "lmbc_memlayout.h" #include "mir_symbol.h" namespace maple { -uint32 LMBCMemLayout::FindLargestActualArea(StmtNode *stmt, int &maxActualSize) { - if (!stmt) { - return maxActualSize; - } - Opcode opcode = stmt->op; - switch (opcode) { - case OP_block: { - BlockNode *blcknode = static_cast(stmt); - for (StmtNode &s : blcknode->GetStmtNodes()) { - FindLargestActualArea(&s, maxActualSize); - } - break; - } - case OP_if: { - IfStmtNode *ifnode = static_cast(stmt); - FindLargestActualArea(ifnode->GetThenPart(), maxActualSize); - FindLargestActualArea(ifnode->GetElsePart(), maxActualSize); - break; - } - case OP_doloop: { - FindLargestActualArea(static_cast(stmt)->GetDoBody(), maxActualSize); - break; - } - case OP_dowhile: - case OP_while: - FindLargestActualArea(static_cast(stmt)->GetBody(), maxActualSize); - break; - case OP_call: - case OP_icall: - case OP_intrinsiccall: { - ParmLocator parmlocator; // instantiate a parm locator - NaryStmtNode *callstmt = static_cast(stmt); - for (uint32 i = 0; i < callstmt->NumOpnds(); i++) { - BaseNode *opnd = callstmt->Opnd(i); - CHECK_FATAL(opnd->GetPrimType() != PTY_void, ""); - MIRType *ty = nullptr; - if (opnd->GetPrimType() != PTY_agg) { - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(opnd->GetPrimType())); - } else { - Opcode opnd_opcode = opnd->GetOpCode(); - CHECK_FATAL(opnd_opcode == OP_dread || opnd_opcode == OP_iread, ""); - if (opnd_opcode == OP_dread) { - AddrofNode *dread = static_cast(opnd); - MIRSymbol *sym = func->GetLocalOrGlobalSymbol(dread->GetStIdx()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sym->GetTyIdx()); - if (dread->GetFieldID() != 0) { - CHECK_FATAL(ty->IsStructType(), "expect struct or class or union"); - FieldPair thepair = - static_cast(ty)->TraverseToField(dread->GetFieldID()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - } else { // OP_iread - IreadNode *iread = static_cast(opnd); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread->GetTyIdx()); - CHECK_FATAL(ty->GetKind() == kTypePointer, ""); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx( - static_cast(ty)->GetPointedTyIdx()); - if (iread->GetFieldID() != 0) { - CHECK_FATAL(ty->IsStructType(), "expect struct or class or union"); - FieldPair thepair = - static_cast(ty)->TraverseToField(iread->GetFieldID()); - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - } - } - } - PLocInfo ploc; - parmlocator.LocateNextParm(ty, ploc); - maxActualSize = std::max(maxActualSize, ploc.memoffset + ploc.memsize); - maxActualSize = maplebe::RoundUp(maxActualSize, GetPrimTypeSize(PTY_ptr)); - } - break; - } - default: - return maxActualSize; - } - maxActualSize = maplebe::RoundUp(maxActualSize, GetPrimTypeSize(PTY_ptr)); - return maxActualSize; -} - -// go over all outgoing calls in the function body and get the maximum space -// needed for storing the actuals based on the actual parameters and the ABI; -// this assumes that all nesting of statements has been removed, so that all -// the statements are at only one block level -uint32 LMBCMemLayout::FindLargestActualArea(void) { - int32 maxActualSize = 0; - FindLargestActualArea(func->GetBody(), maxActualSize); - return static_cast(maxActualSize); -} +constexpr size_t kVarargSaveAreaSize = 192; void LMBCMemLayout::LayoutStackFrame(void) { - MIRSymbol *sym = nullptr; - // go through formal parameters - ParmLocator parmlocator; // instantiate a parm locator - PLocInfo ploc; - for (uint32 i = 0; i < func->GetFormalDefVec().size(); i++) { - FormalDef formalDef = func->GetFormalDefAt(i); - sym = formalDef.formalSym; - MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(formalDef.formalTyIdx); - parmlocator.LocateNextParm(ty, ploc); - uint32 stindex = sym->GetStIndex(); - // always passed in memory, so allocate in seg_upformal - sym_alloc_table[stindex].mem_segment = &seg_upformal; - seg_upformal.size = maplebe::RoundUp(seg_upformal.size, ty->GetAlign()); - sym_alloc_table[stindex].offset = seg_upformal.size; - seg_upformal.size += ty->GetSize(); - seg_upformal.size = maplebe::RoundUp(seg_upformal.size, GetPrimTypeSize(PTY_ptr)); + if (func->IsVarargs()) { + seg_FPbased.size -= kVarargSaveAreaSize; } - // allocate seg_formal in seg_FPbased - seg_formal.how_alloc.mem_segment = &seg_FPbased; - seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, GetPrimTypeSize(PTY_ptr)); - seg_FPbased.size -= seg_formal.size; - seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, GetPrimTypeSize(PTY_ptr)); - seg_formal.how_alloc.offset = seg_FPbased.size; - // allocate the local variables uint32 symtabsize = func->GetSymTab()->GetSymbolTableSize(); for (uint32 i = 0; i < symtabsize; i++) { - sym = func->GetSymTab()->GetSymbolFromStIdx(i); + MIRSymbol *sym = func->GetSymTab()->GetSymbolFromStIdx(i); if (!sym) { continue; } if (sym->IsDeleted()) { continue; } + if (sym->GetStorageClass() == kScPstatic && sym->LMBCAllocateOffSpecialReg()) { + uint32 stindex = sym->GetStIndex(); + sym_alloc_table[stindex].mem_segment = seg_GPbased; + seg_GPbased->size = maplebe::RoundUp(seg_GPbased->size, sym->GetType()->GetAlign()); + sym_alloc_table[stindex].offset = seg_GPbased->size; + seg_GPbased->size += sym->GetType()->GetSize(); + } if (sym->GetStorageClass() != kScAuto) { continue; } @@ -162,160 +56,10 @@ void LMBCMemLayout::LayoutStackFrame(void) { seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, sym->GetType()->GetAlign()); sym_alloc_table[stindex].offset = seg_FPbased.size; } - seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, GetPrimTypeSize(PTY_ptr)); - - // allocate seg_actual for storing the outgoing parameters; this requires - // going over all outgoing calls and get the maximum space needed for the - // actuals - seg_actual.size = FindLargestActualArea(); - func->SetOutParmSize(seg_actual.size); - - // allocate seg_actual in seg_SPbased - seg_actual.how_alloc.mem_segment = &seg_SPbased; - seg_actual.how_alloc.offset = seg_SPbased.size; - seg_SPbased.size = maplebe::RoundUp(seg_SPbased.size, GetPrimTypeSize(PTY_ptr)); - seg_SPbased.size += seg_actual.size; - seg_SPbased.size = maplebe::RoundUp(seg_SPbased.size, GetPrimTypeSize(PTY_ptr)); -} - -inline uint8 GetU8Const(MIRConst *c) { - MIRIntConst *intconst = static_cast(c); - return static_cast(intconst->GetValue()); -} - -inline uint16 GetU16Const(MIRConst *c) { - MIRIntConst *intconst = static_cast(c); - return static_cast(intconst->GetValue()); -} - -inline uint32 GetU32Const(MIRConst *c) { - MIRIntConst *intconst = static_cast(c); - return static_cast(intconst->GetValue()); -} - -inline uint64 GetU64Const(MIRConst *c) { - MIRIntConst *intconst = static_cast(c); - return static_cast(intconst->GetValue()); -} - -inline uint32 GetF32Const(MIRConst *c) { - MIRFloatConst *floatconst = static_cast(c); - return static_cast(floatconst->GetIntValue()); -} - -inline uint64 GetF64Const(MIRConst *c) { - MIRDoubleConst *doubleconst = static_cast(c); - return static_cast(doubleconst->GetIntValue()); -} - -void GlobalMemLayout::FillScalarValueInMap(uint32 startaddress, PrimType pty, MIRConst *c) { - switch (pty) { - case PTY_u1: - case PTY_u8: - case PTY_i8: { - uint8 *p = &mirModule->GetGlobalBlockMap()[startaddress]; - *p = GetU8Const(c); - break; - } - case PTY_u16: - case PTY_i16: { - uint16 *p = (uint16 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetU16Const(c); - break; - } - case PTY_u32: - case PTY_i32: { - uint32 *p = (uint32 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetU32Const(c); - break; - } - case PTY_u64: - case PTY_i64: { - uint64 *p = (uint64 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetU64Const(c); - break; - } - case PTY_f32: { - uint32 *p = (uint32 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetF32Const(c); - break; - } - case PTY_f64: { - uint64 *p = (uint64 *)(&mirModule->GetGlobalBlockMap()[startaddress]); - *p = GetF64Const(c); - break; - } - default: - CHECK_FATAL(false, "FillScalarValueInMap: NYI"); - } - return; } -void GlobalMemLayout::FillTypeValueInMap(uint32 startaddress, MIRType *ty, MIRConst *c) { - switch (ty->GetKind()) { - case kTypeScalar: - FillScalarValueInMap(startaddress, ty->GetPrimType(), c); - break; - case kTypeArray: { - MIRArrayType *arraytype = static_cast(ty); - MIRType *elemtype = arraytype->GetElemType(); - int32 elemsize = elemtype->GetSize(); - MIRAggConst *aggconst = static_cast(c); - CHECK_FATAL(aggconst, "FillTypeValueInMap: inconsistent array initialization specification"); - MapleVector &constvec = aggconst->GetConstVec(); - for (MapleVector::iterator it = constvec.begin(); it != constvec.end(); - ++it, startaddress += elemsize) { - FillTypeValueInMap(startaddress, elemtype, *it); - } - break; - } - case kTypeStruct: { - MIRStructType *structty = static_cast(ty); - MIRAggConst *aggconst = static_cast(c); - CHECK_FATAL(aggconst, "FillTypeValueInMap: inconsistent struct initialization specification"); - MapleVector &constvec = aggconst->GetConstVec(); - for (uint32 i = 0; i < constvec.size(); i++) { - uint32 fieldID = aggconst->GetFieldIdItem(i); - FieldPair thepair = structty->TraverseToField(fieldID); - MIRType *fieldty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - uint32 offset = be->GetFieldOffset(*structty, fieldID).first; - FillTypeValueInMap(startaddress + offset, fieldty, constvec[i]); - } - break; - } - case kTypeClass: { - MIRClassType *classty = static_cast(ty); - MIRAggConst *aggconst = static_cast(c); - CHECK_FATAL(aggconst, "FillTypeValueInMap: inconsistent class initialization specification"); - MapleVector &constvec = aggconst->GetConstVec(); - for (uint32 i = 0; i < constvec.size(); i++) { - uint32 fieldID = aggconst->GetFieldIdItem(i); - FieldPair thepair = classty->TraverseToField(fieldID); - MIRType *fieldty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - uint32 offset = be->GetFieldOffset(*classty, fieldID).first; - FillTypeValueInMap(startaddress + offset, fieldty, constvec[i]); - } - break; - } - default: - CHECK_FATAL(false, "FillTypeValueInMap: NYI"); - } -} - -void GlobalMemLayout::FillSymbolValueInMap(const MIRSymbol *sym) { - if (sym->GetKonst() == nullptr) { - return; - } - uint32 stindex = sym->GetStIndex(); - CHECK(stindex < sym_alloc_table.size(), - "index out of range in GlobalMemLayout::FillSymbolValueInMap"); - uint32 symaddress = sym_alloc_table[stindex].offset; - FillTypeValueInMap(symaddress, sym->GetType(), sym->GetKonst()); - return; -} - -GlobalMemLayout::GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAllocator *mallocator) : - seg_GPbased(MS_GPbased), sym_alloc_table(mallocator->Adapter()), be(b), mirModule(mod) { +GlobalMemLayout::GlobalMemLayout(MIRModule *mod, MapleAllocator *mallocator) : + seg_GPbased(MS_GPbased), sym_alloc_table(mallocator->Adapter()), mirModule(mod) { uint32 symtabsize = GlobalTables::GetGsymTable().GetSymbolTableSize(); sym_alloc_table.resize(symtabsize); MIRSymbol *sym = nullptr; @@ -329,6 +73,9 @@ GlobalMemLayout::GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAll if (sym->GetStorageClass() != kScGlobal && sym->GetStorageClass() != kScFstatic) { continue; } + if (!sym->LMBCAllocateOffSpecialReg()) { + continue; + } if (sym->GetType()->GetAlign() != curalign) { continue; } @@ -341,152 +88,6 @@ GlobalMemLayout::GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAll } seg_GPbased.size = maplebe::RoundUp(seg_GPbased.size, GetPrimTypeSize(PTY_ptr)); mirModule->SetGlobalMemSize(seg_GPbased.size); - // allocate the memory map for the GP block - mirModule->SetGlobalBlockMap( - static_cast(mirModule->GetMemPool()->Calloc(seg_GPbased.size))); - // perform initialization on globalblkmap - for (uint32 i = 0; i < symtabsize; i++) { - sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(i); - if (!sym) { - continue; - } - if (sym->GetStorageClass() != kScGlobal && sym->GetStorageClass() != kScFstatic) { - continue; - } - } -} - -// LocateNextParm should be called with each parameter in the parameter list -// starting from the beginning, one call per parameter in sequence; it returns -// the information on how each parameter is passed in ploc -void ParmLocator::LocateNextParm(const MIRType *ty, PLocInfo &ploc) { - ploc.memoffset = maplebe::RoundUp(lastMemOffset, 8); - ploc.memsize = ty->GetSize(); - - uint32 rightpad = 0; - parmNum++; - - switch (ty->GetPrimType()) { - case PTY_u1: - case PTY_u8: - case PTY_i8: - case PTY_u16: - case PTY_i16: - rightpad = GetPrimTypeSize(PTY_i32) - ploc.memsize; - break; - case PTY_a32: - case PTY_u32: - case PTY_i32: - case PTY_a64: - case PTY_u64: - case PTY_i64: - case PTY_ptr: - case PTY_ref: -#ifdef DYNAMICLANG - case PTY_simplestr: - case PTY_simpleobj: - case PTY_dynany: - case PTY_dyni32: - case PTY_dynf64: - case PTY_dynstr: - case PTY_dynobj: - case PTY_dynundef: - case PTY_dynbool: - case PTY_dynf32: - case PTY_dynnone: - case PTY_dynnull: -#endif - break; - - case PTY_f32: - rightpad = GetPrimTypeSize(PTY_f64) - ploc.memsize; - break; - case PTY_c64: - case PTY_f64: - case PTY_v2i32: - case PTY_v4i16: - case PTY_v8i8: - case PTY_v2u32: - case PTY_v4u16: - case PTY_v8u8: - case PTY_v2f32: - break; - - case PTY_c128: - case PTY_v2i64: - case PTY_v4i32: - case PTY_v8i16: - case PTY_v16i8: - case PTY_v2u64: - case PTY_v4u32: - case PTY_v8u16: - case PTY_v16u8: - case PTY_v2f64: - case PTY_v4f32: - break; - - case PTY_agg: { - // compute rightpad - int32 paddedSize = maplebe::RoundUp(ploc.memsize, 8); - rightpad = paddedSize - ploc.memsize; - break; - } - default: - CHECK_FATAL(false, "unsupported type"); - } - - lastMemOffset = ploc.memoffset + ploc.memsize + rightpad; - return; -} - -// instantiated with the type of the function return value, it describes how -// the return value is to be passed back to the caller -ReturnMechanism::ReturnMechanism(const MIRType *retty) : fake_first_parm(false) { - switch (retty->GetPrimType()) { - case PTY_u1: - case PTY_u8: - case PTY_i8: - case PTY_u16: - case PTY_i16: - case PTY_a32: - case PTY_u32: - case PTY_i32: - case PTY_a64: - case PTY_u64: - case PTY_i64: - case PTY_f32: - case PTY_f64: -#ifdef DYNAMICLANG - case PTY_simplestr: - case PTY_simpleobj: - case PTY_dynany: - case PTY_dyni32: - case PTY_dynstr: - case PTY_dynobj: -#endif - ptype0 = retty->GetPrimType(); - return; - - case PTY_c64: - case PTY_c128: - fake_first_parm = true; - ptype0 = PTY_a32; - return; - - case PTY_agg: { - uint32 size = retty->GetSize(); - if (size > 4) { - fake_first_parm = true; - ptype0 = PTY_a32; - } else { - ptype0 = PTY_u32; - } - return; - } - - default: - return; - } } } // namespace maple diff --git a/src/mapleall/maple_me/src/me_cfg.cpp b/src/mapleall/maple_me/src/me_cfg.cpp index ad57c5b166..74e2f176c4 100644 --- a/src/mapleall/maple_me/src/me_cfg.cpp +++ b/src/mapleall/maple_me/src/me_cfg.cpp @@ -261,6 +261,7 @@ bool MeCFG::FindUse(const StmtNode &stmt, StIdx stIdx) const { case OP_customcall: case OP_polymorphiccall: case OP_icall: + case OP_icallproto: case OP_intrinsiccall: case OP_xintrinsiccall: case OP_intrinsiccallwithtype: @@ -273,6 +274,7 @@ bool MeCFG::FindUse(const StmtNode &stmt, StIdx stIdx) const { case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_intrinsiccallassigned: case OP_xintrinsiccallassigned: case OP_intrinsiccallwithtypeassigned: diff --git a/src/mapleall/maple_me/src/me_function.cpp b/src/mapleall/maple_me/src/me_function.cpp index 05181df796..a62f1a89a3 100755 --- a/src/mapleall/maple_me/src/me_function.cpp +++ b/src/mapleall/maple_me/src/me_function.cpp @@ -303,7 +303,9 @@ void MeFunction::CloneBBMeStmts(BB &srcBB, BB &destBB, std::map(&stmt); newStmt = irmap->NewInPool(static_cast(icallStmt), icallStmt->GetRetTyIdx(), icallStmt->GetStmtID()); diff --git a/src/mapleall/maple_me/src/me_lower_globals.cpp b/src/mapleall/maple_me/src/me_lower_globals.cpp index c14dd5c764..fdf2df8e3f 100644 --- a/src/mapleall/maple_me/src/me_lower_globals.cpp +++ b/src/mapleall/maple_me/src/me_lower_globals.cpp @@ -185,7 +185,12 @@ void MeLowerGlobals::Run() { MeExpr *addroffuncExpr = irMap->CreateAddroffuncMeExpr(callee.GetPuidx()); auto insertpos = callStmt.GetOpnds().begin(); callStmt.InsertOpnds(insertpos, addroffuncExpr); - IcallMeStmt *icallStmt = irMap->NewInPool(stmt.GetOp() == OP_call ? OP_icall : OP_icallassigned); + IcallMeStmt *icallStmt = nullptr; + if (func.GetMIRModule().IsCModule()) { + icallStmt = irMap->NewInPool(stmt.GetOp() == OP_call ? OP_icallproto : OP_icallprotoassigned); + } else { + icallStmt = irMap->NewInPool(stmt.GetOp() == OP_call ? OP_icall : OP_icallassigned); + } icallStmt->SetIsLive(callStmt.GetIsLive()); icallStmt->SetSrcPos(callStmt.GetSrcPosition()); for (MeExpr *o : callStmt.GetOpnds()) { @@ -193,7 +198,11 @@ void MeLowerGlobals::Run() { } icallStmt->GetMuList()->insert(callStmt.GetMuList()->begin(), callStmt.GetMuList()->end()); icallStmt->GetChiList()->insert(callStmt.GetChiList()->begin(), callStmt.GetChiList()->end()); - icallStmt->SetRetTyIdx(callee.GetReturnTyIdx()); + if (func.GetMIRModule().IsCModule()) { + icallStmt->SetRetTyIdx(callee.GetMIRFuncType()->GetTypeIndex()); + } else { + icallStmt->SetRetTyIdx(callee.GetReturnTyIdx()); + } if (stmt.GetOp() != OP_call) { if (callStmt.NeedDecref()) { icallStmt->EnableNeedDecref(); diff --git a/src/mapleall/maple_me/src/me_phase_manager.cpp b/src/mapleall/maple_me/src/me_phase_manager.cpp index 09a1b64e5a..a0b5419a8e 100644 --- a/src/mapleall/maple_me/src/me_phase_manager.cpp +++ b/src/mapleall/maple_me/src/me_phase_manager.cpp @@ -140,8 +140,8 @@ bool MeFuncPM::PhaseRun(maple::MIRModule &m) { } if (genLMBC) { m.SetFlavor(kFlavorLmbc); + GlobalMemLayout globalMemLayout(&m, &m.GetMPAllocator()); maplebe::BECommon beCommon(m); - GlobalMemLayout globalMemLayout(&beCommon, &m, &m.GetMPAllocator()); maplebe::CGLowerer cgLower(m, beCommon, false, false); cgLower.RegisterBuiltIns(); cgLower.RegisterExternalLibraryFunctions(); @@ -153,14 +153,15 @@ bool MeFuncPM::PhaseRun(maple::MIRModule &m) { cgLower.LowerFunc(*func); MemPool *layoutMp = memPoolCtrler.NewMemPool("layout mempool", true); MapleAllocator layoutAlloc(layoutMp); - LMBCMemLayout localMemLayout(func, &layoutAlloc); + LMBCMemLayout localMemLayout(func, &globalMemLayout.seg_GPbased, &layoutAlloc); localMemLayout.LayoutStackFrame(); LMBCLowerer lmbcLowerer(&m, &beCommon, func, &globalMemLayout, &localMemLayout); lmbcLowerer.LowerFunction(); func->SetFrameSize(localMemLayout.StackFrameSize()); - func->SetUpFormalSize(localMemLayout.UpformalSize()); memPoolCtrler.DeleteMemPool(layoutMp); } + globalMemLayout.seg_GPbased.size = maplebe::RoundUp(globalMemLayout.seg_GPbased.size, GetPrimTypeSize(PTY_ptr)); + m.SetGlobalMemSize(globalMemLayout.seg_GPbased.size); // output .lmbc BinaryMplt binMplt(m); std::string modFileName = m.GetFileName(); diff --git a/src/mapleall/maple_me/src/me_rc_lowering.cpp b/src/mapleall/maple_me/src/me_rc_lowering.cpp index 1c7319e18b..131ebbdd2a 100644 --- a/src/mapleall/maple_me/src/me_rc_lowering.cpp +++ b/src/mapleall/maple_me/src/me_rc_lowering.cpp @@ -1145,6 +1145,7 @@ void RCLowering::HandleArguments() { firstBB->InsertMeStmtBefore(firstMeStmt, incCall); } sym->SetLocalRefVar(); + mirFunc->GetFormalDefVec()[i].formalAttrs.SetAttr(ATTR_localrefvar); for (auto *stmt : rets) { std::vector opnds = { argVar }; diff --git a/src/mapleall/maple_me/src/me_rename2preg.cpp b/src/mapleall/maple_me/src/me_rename2preg.cpp index 9549dff004..eddc9704b9 100644 --- a/src/mapleall/maple_me/src/me_rename2preg.cpp +++ b/src/mapleall/maple_me/src/me_rename2preg.cpp @@ -317,6 +317,7 @@ void SSARename2Preg::Rename2PregStmt(MeStmt *stmt) { case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_intrinsiccallassigned: case OP_xintrinsiccallassigned: case OP_intrinsiccallwithtypeassigned: { diff --git a/src/mapleall/maple_me/src/me_side_effect.cpp b/src/mapleall/maple_me/src/me_side_effect.cpp index 67dea87820..52fcda8516 100644 --- a/src/mapleall/maple_me/src/me_side_effect.cpp +++ b/src/mapleall/maple_me/src/me_side_effect.cpp @@ -933,6 +933,7 @@ bool IpaSideEffect::UpdateSideEffectWithStmt(MeStmt &meStmt, case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_superclasscallassigned: case OP_asm: { hasPrivateDef = hasThrException = true; @@ -959,7 +960,8 @@ bool IpaSideEffect::UpdateSideEffectWithStmt(MeStmt &meStmt, case OP_interfaceicall: case OP_customcall: case OP_polymorphiccall: - case OP_icall: { + case OP_icall: + case OP_icallproto: { hasPrivateDef = hasThrException = true; SetHasDef(); for (size_t i = 0; i < meStmt.NumMeStmtOpnds(); ++i) { diff --git a/src/mapleall/maple_me/src/me_stmt_pre.cpp b/src/mapleall/maple_me/src/me_stmt_pre.cpp index d50e3c5371..3f5d2bff57 100755 --- a/src/mapleall/maple_me/src/me_stmt_pre.cpp +++ b/src/mapleall/maple_me/src/me_stmt_pre.cpp @@ -967,7 +967,9 @@ void MeStmtPre::BuildWorkListBB(BB *bb) { break; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { auto &icallMeStmt = static_cast(stmt); VersionStackChiListUpdate(*icallMeStmt.GetChiList()); break; diff --git a/src/mapleall/maple_me/src/pme_emit.cpp b/src/mapleall/maple_me/src/pme_emit.cpp index 227cb6a761..52e1df6beb 100755 --- a/src/mapleall/maple_me/src/pme_emit.cpp +++ b/src/mapleall/maple_me/src/pme_emit.cpp @@ -485,10 +485,12 @@ StmtNode* PreMeEmitter::EmitPreMeStmt(MeStmt *mestmt, BaseNode *parent) { return callnode; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { IcallMeStmt *icallMeStmt = static_cast (mestmt); IcallNode *icallnode = - codeMP->New(*codeMPAlloc, OP_icallassigned, icallMeStmt->GetRetTyIdx()); + codeMP->New(*codeMPAlloc, OP_icallprotoassigned, icallMeStmt->GetRetTyIdx()); for (uint32 i = 0; i < icallMeStmt->GetOpnds().size(); i++) { icallnode->GetNopnd().push_back(EmitPreMeExpr(icallMeStmt->GetOpnd(i), icallnode)); } @@ -509,6 +511,9 @@ StmtNode* PreMeEmitter::EmitPreMeStmt(MeStmt *mestmt, BaseNode *parent) { icallnode->SetRetTyIdx(TyIdx(preg->GetPrimType())); } } + if (mestmt->GetOp() == OP_icallproto || mestmt->GetOp() == OP_icallprotoassigned) { + icallnode->SetRetTyIdx(icallMeStmt->GetRetTyIdx()); + } icallnode->CopySafeRegionAttr(mestmt->GetStmtAttr()); icallnode->SetOriginalID(mestmt->GetOriginalId()); PreMeStmtExtensionMap[icallnode->GetStmtID()] = pmeExt; diff --git a/src/mapleall/maple_me/src/ssa_devirtual.cpp b/src/mapleall/maple_me/src/ssa_devirtual.cpp index 15a609e427..f46e8e06ce 100644 --- a/src/mapleall/maple_me/src/ssa_devirtual.cpp +++ b/src/mapleall/maple_me/src/ssa_devirtual.cpp @@ -534,7 +534,9 @@ void SSADevirtual::TraversalMeStmt(MeStmt &meStmt) { break; } case OP_icall: - case OP_icallassigned: { + case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: { auto *icallMeStmt = static_cast(&meStmt); const MapleVector &opnds = icallMeStmt->GetOpnds(); for (size_t i = 0; i < opnds.size(); ++i) { diff --git a/src/mapleall/maple_me/src/ssa_pre.cpp b/src/mapleall/maple_me/src/ssa_pre.cpp index ceff080daa..a082b80b9f 100644 --- a/src/mapleall/maple_me/src/ssa_pre.cpp +++ b/src/mapleall/maple_me/src/ssa_pre.cpp @@ -1666,6 +1666,7 @@ void SSAPre::BuildWorkListStmt(MeStmt &stmt, uint32 seqStmt, bool isRebuilt, MeE case OP_customcall: case OP_polymorphiccall: case OP_icall: + case OP_icallproto: case OP_callassigned: case OP_virtualcallassigned: case OP_virtualicallassigned: @@ -1675,6 +1676,7 @@ void SSAPre::BuildWorkListStmt(MeStmt &stmt, uint32 seqStmt, bool isRebuilt, MeE case OP_customcallassigned: case OP_polymorphiccallassigned: case OP_icallassigned: + case OP_icallprotoassigned: case OP_asm: { auto *naryMeStmt = static_cast(meStmt); const MapleVector &opnds = naryMeStmt->GetOpnds(); diff --git a/src/mapleall/mpl2mpl/src/constantfold.cpp b/src/mapleall/mpl2mpl/src/constantfold.cpp index f84c351bd8..1b296c1de7 100644 --- a/src/mapleall/mpl2mpl/src/constantfold.cpp +++ b/src/mapleall/mpl2mpl/src/constantfold.cpp @@ -162,6 +162,8 @@ StmtNode *ConstantFold::Simplify(StmtNode *node) { return SimplifyNary(static_cast(node)); case OP_icall: case OP_icallassigned: + case OP_icallproto: + case OP_icallprotoassigned: return SimplifyIcall(static_cast(node)); case OP_asm: return SimplifyAsm(static_cast(node)); @@ -2628,8 +2630,8 @@ StmtNode *ConstantFold::SimplifyIcall(IcallNode *node) { AddroffuncNode *addrofNode = static_cast(node->GetNopndAt(0)); CallNode *callNode = mirModule->CurFuncCodeMemPool()->New(*mirModule, - node->GetOpCode() == OP_icall ? OP_call : OP_callassigned); - if (node->GetOpCode() == OP_icallassigned) { + (node->GetOpCode() == OP_icall || node->GetOpCode() == OP_icallproto) ? OP_call : OP_callassigned); + if (node->GetOpCode() == OP_icallassigned || node->GetOpCode() == OP_icallprotoassigned) { callNode->SetReturnVec(node->GetReturnVec()); } callNode->SetPUIdx(addrofNode->GetPUIdx()); -- Gitee From 908d2a85f3fc560fb30a7e557e35f8e9e61fed63 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:44 -0700 Subject: [PATCH 083/124] Fred's Fixed determination logic of when there is fake parameter for returning struct, where x8 is also used to pass the fake parameter --- .../maple_be/src/cg/aarch64/aarch64_args.cpp | 4 ++-- .../src/cg/aarch64/aarch64_call_conv.cpp | 11 ++++++----- .../maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 18 ++++++++++++------ .../src/cg/aarch64/aarch64_memlayout.cpp | 4 ++-- 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index c03cb48970..0a4be4089a 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -38,7 +38,7 @@ void AArch64MoveRegArgs::CollectRegisterArgs(std::map &argsL uint32 start = 0; if (numFormal) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsFirstArgReturn()) { + if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16ByteSize) { start = 1; @@ -439,7 +439,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsFirstArgReturn()) { + if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp index 77103c8549..2fe212434c 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_call_conv.cpp @@ -306,18 +306,18 @@ int32 AArch64CallConvImpl::LocateNextParm(MIRType &mirType, CCLocInfo &pLoc, boo if (size == 0) { /* For return struct size 0 there is no return value. */ return 0; - } else if (size > k16ByteSize) { - /* For return struct size > 16 bytes the pointer returns in x8. */ - pLoc.reg0 = R8; - return kSizeOfPtr; } + /* For return struct size > 16 bytes the pointer returns in x8. */ + pLoc.reg0 = R8; + return kSizeOfPtr; +#if 0 /* For return struct size less or equal to 16 bytes, the values * are returned in register pairs. * Check for pure float struct. */ AArch64ArgumentClass classes[kMaxRegCount] = { kAArch64NoClass }; uint32 fpSize; - MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(beCommon.GetFuncReturnType(*func)); + MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); uint32 numRegs = static_cast(ClassifyAggregate(beCommon, *retType, classes, sizeof(classes), fpSize)); if (classes[0] == kAArch64FloatClass) { CHECK_FATAL(numRegs <= kMaxRegCount, "LocateNextParm: illegal number of regs"); @@ -334,6 +334,7 @@ int32 AArch64CallConvImpl::LocateNextParm(MIRType &mirType, CCLocInfo &pLoc, boo } return 0; } +#endif } } uint64 typeSize = beCommon.GetTypeSize(mirType.GetTypeIndex()); 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 34f7c7d46b..211fc1e041 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8062,6 +8062,17 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo std::set specialArgs; SelectParmListPreprocess(naryNode, i, specialArgs); bool specialArg = false; + bool firstArgReturn = false; + MIRFunction *callee = nullptr; + if (dynamic_cast(&naryNode) != nullptr) { + auto calleePuIdx = static_cast(naryNode).GetPUIdx(); + callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + firstArgReturn = callee->IsFirstArgReturn(); + } else if (naryNode.GetOpCode() == OP_icallproto) { + IcallNode *icallnode = &static_cast(naryNode); + MIRFuncType *funcType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallnode->GetRetTyIdx())); + firstArgReturn = funcType->FirstArgReturn(); + } BB *curBBrecord = GetCurBB(); BB *tmpBB = nullptr; if (!specialArgs.empty()) { @@ -8083,11 +8094,6 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); - MIRFunction *callee = nullptr; - if (dynamic_cast(&naryNode) != nullptr) { - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); - } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } @@ -8152,7 +8158,7 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo } expRegOpnd = static_cast(opnd); - if ((pnum == 0) && (SelectParmListGetStructReturnSize(naryNode) > k16ByteSize)) { + if ((pnum == 0) && firstArgReturn) { parmLocator.InitCCLocInfo(ploc); ploc.reg0 = R8; } else { diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp index 4184108a22..5a839e9af4 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp @@ -210,7 +210,7 @@ void AArch64MemLayout::LayoutFormalParams() { AArch64SymbolAlloc *symLoc = memAllocator->GetMemPool()->New(); SetSymAllocInfo(stIndex, *symLoc); if (i == 0) { - if (mirFunction->IsFirstArgReturn()) { + if (mirFunction->IsReturnStruct() && mirFunction->IsFirstArgReturn()) { symLoc->SetMemSegment(GetSegArgsRegPassed()); symLoc->SetOffset(GetSegArgsRegPassed().GetSize()); TyIdx tyIdx = mirFunction->GetFuncRetStructTyIdx(); @@ -395,7 +395,7 @@ void AArch64MemLayout::LayoutReturnRef(std::vector &returnDelays, void AArch64MemLayout::LayoutActualParams() { for (size_t i = 0; i < mirFunction->GetFormalCount(); ++i) { if (i == 0) { - if (mirFunction->IsReturnStruct()) { + if (mirFunction->IsReturnStruct() && mirFunction->IsFirstArgReturn()) { continue; } } -- Gitee From 9135fd85a6e28224b34f76351f23d412ab4f6c7b Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:53:00 -0700 Subject: [PATCH 084/124] Remove unneeded fp def. Turn on tailcall. no unneeded pro/epilog. --- .../maple_be/include/cg/aarch64/aarch64_color_ra.h | 1 + src/mapleall/maple_be/include/cg/cgfunc.h | 9 +++++++++ .../maple_be/src/cg/aarch64/aarch64_color_ra.cpp | 6 ++++++ .../maple_be/src/cg/aarch64/aarch64_proepilog.cpp | 7 +++---- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h index a3df9f6bf3..651cd91674 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h @@ -1519,6 +1519,7 @@ class GraphColorRegAllocator : public RegAllocator { #endif bool hasSpill = false; bool doMultiPass = false; + bool seenFP = false; }; class CallerSavePre: public CGPre { diff --git a/src/mapleall/maple_be/include/cg/cgfunc.h b/src/mapleall/maple_be/include/cg/cgfunc.h index 0695a784de..a664565276 100644 --- a/src/mapleall/maple_be/include/cg/cgfunc.h +++ b/src/mapleall/maple_be/include/cg/cgfunc.h @@ -1107,6 +1107,14 @@ class CGFunc { return useFP; } + void UnsetSeenFP() { + seenFP = false; + } + + bool SeenFP() const { + return seenFP; + } + void UpdateAllRegisterVregMapping(MapleMap &newMap); void RegisterVregMapping(regno_t vRegNum, PregIdx pidx) { @@ -1276,6 +1284,7 @@ class CGFunc { const MapleString shortFuncName; bool hasAsm = false; bool useFP = true; + bool seenFP = true; /* save stack protect kinds which can trigger stack protect */ uint8 stackProtectInfo = 0; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp index 75a5d0fab5..b77161f548 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp @@ -3609,6 +3609,9 @@ RegOperand *GraphColorRegAllocator::GetReplaceOpnd(Insn &insn, const Operand &op auto ®Opnd = static_cast(opnd); uint32 vregNO = regOpnd.GetRegisterNumber(); + if (vregNO == RFP) { + seenFP = true; + } RegType regType = regOpnd.GetRegisterType(); if (vregNO < kAllRegNum) { return nullptr; @@ -4976,6 +4979,9 @@ bool GraphColorRegAllocator::AllocateRegisters() { MarkCalleeSaveRegs(); + if (seenFP == false) { + cgFunc->UnsetSeenFP(); + } if (GCRA_DUMP) { cgFunc->DumpCGIR(); } diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp index bffcb420c1..455acc86bd 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp @@ -185,9 +185,6 @@ void AArch64GenProEpilog::TailCallBBOpt(BB &bb, MapleSet &callInsns, BB & * Return value: true if function do not need Prologue/Epilogue. false otherwise. */ bool AArch64GenProEpilog::TailCallOpt() { - if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { - return false; - } /* Count how many call insns in the whole function. */ uint32 nCount = 0; bool hasGetStackClass = false; @@ -1229,7 +1226,9 @@ void AArch64GenProEpilog::GeneratePushRegs() { } else { immOpnd = &aarchCGFunc.CreateImmOperand(argsToStkPassSize, k32BitSize, true); } - aarchCGFunc.SelectAdd(fpOpnd, spOpnd, *immOpnd, PTY_u64); + if (isLmbc == false || cgFunc.SeenFP() || cgFunc.GetFunction().GetAttr(FUNCATTR_varargs)) { + aarchCGFunc.SelectAdd(fpOpnd, spOpnd, *immOpnd, PTY_u64); + } cgFunc.GetCurBB()->GetLastInsn()->SetFrameDef(true); if (cgFunc.GenCfi()) { cgFunc.GetCurBB()->AppendInsn(aarchCGFunc.CreateCfiDefCfaInsn(stackBaseReg, -- Gitee From 91b2bfd696a2a6fcce5d36432ec571bc440ede14 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:53:14 -0700 Subject: [PATCH 085/124] Fred's Set firstarg_return attribute in the new funcAttrs field in MIRFuncType --- src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp | 3 +++ src/mapleall/maple_ir/src/mir_lower.cpp | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp b/src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp index ac099f0864..5301c71d10 100644 --- a/src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp +++ b/src/hir2mpl/ast_input/clang/src/ast_struct2fe_helper.cpp @@ -279,6 +279,9 @@ bool ASTFunc2FEHelper::ProcessDeclImpl(MapleAllocator &allocator) { ENCChecker::InsertBoundaryInAtts(attrs, func.GetBoundaryInfo()); mirMethodPair.second.second = attrs; mirFunc->SetFuncAttrs(attrs); + if (firstArgRet) { + mirFunc->GetMIRFuncType()->funcAttrs.SetAttr(FUNCATTR_firstarg_return); + } func.ClearGenericAttrsContentMap(); return true; } diff --git a/src/mapleall/maple_ir/src/mir_lower.cpp b/src/mapleall/maple_ir/src/mir_lower.cpp index 8ea87d7d5f..53413ee084 100644 --- a/src/mapleall/maple_ir/src/mir_lower.cpp +++ b/src/mapleall/maple_ir/src/mir_lower.cpp @@ -553,6 +553,10 @@ BlockNode *MIRLower::LowerBlock(BlockNode &block) { MIRFuncType *funcType = FuncTypeFromFuncPtrExpr(stmt->Opnd(0)); CHECK_FATAL(funcType != nullptr, "MIRLower::LowerBlock: cannot find prototype for icall"); ic->SetRetTyIdx(funcType->GetTypeIndex()); + MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcType->GetRetTyIdx()); + if (retType->GetPrimType() == PTY_agg && retType->GetSize() > 16) { + funcType->funcAttrs.SetAttr(FUNCATTR_firstarg_return); + } } newBlock->AddStatement(stmt); break; -- Gitee From 39b99b4326c403df0288136e217e872ebb73f6e5 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 086/124] Changes from mplcglmbc8 and mplcglmbc9. --- src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp | 1 - src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 0a4be4089a..6bd2a9b78a 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -439,7 +439,6 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; 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 211fc1e041..8d16f8a80d 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8094,6 +8094,11 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); + MIRFunction *callee = nullptr; + if (dynamic_cast(&naryNode) != nullptr) { + auto calleePuIdx = static_cast(naryNode).GetPUIdx(); + callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } -- Gitee From b9168c949c562c359007d309855e8b5ee4897a50 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:44 -0700 Subject: [PATCH 087/124] Fred's Fixed determination logic of when there is fake parameter for returning struct, where x8 is also used to pass the fake parameter --- src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp | 1 + src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 5 ----- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 6bd2a9b78a..0a4be4089a 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -439,6 +439,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); + if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; 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 8d16f8a80d..211fc1e041 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8094,11 +8094,6 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); - MIRFunction *callee = nullptr; - if (dynamic_cast(&naryNode) != nullptr) { - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); - } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } -- Gitee From 1a48f922221fcc1fbe82700b7db7fbe1585cd7f8 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 15 Jun 2022 16:18:04 -0700 Subject: [PATCH 088/124] Fix accessing localrefvar in memlayout by qualifying with language --- src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h | 2 +- src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 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 53478d0f99..3820897107 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -129,7 +129,7 @@ class AArch64CGFunc : public CGFunc { uint32 LmbcFindTotalStkUsed(std::vector* paramList); uint32 LmbcTotalRegsUsed(); void LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn); - bool LmbcSmallAggForRet(BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *src); bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp index 5a839e9af4..e7d4432330 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp @@ -230,7 +230,7 @@ void AArch64MemLayout::LayoutFormalParams() { if (ploc.reg0 != kRinvalid) { /* register */ symLoc->SetRegisters(static_cast(ploc.reg0), static_cast(ploc.reg1), static_cast(ploc.reg2), static_cast(ploc.reg3)); - if (mirFunction->GetFormalDefVec()[i].formalAttrs.GetAttr(ATTR_localrefvar)) { + if (!cgFunc->GetMirModule().IsCModule() && mirFunction->GetNthParamAttr(i).GetAttr(ATTR_localrefvar)) { symLoc->SetMemSegment(segRefLocals); SetSegmentSize(*symLoc, segRefLocals, ptyIdx); } else if (!sym->IsPreg()) { @@ -272,7 +272,7 @@ void AArch64MemLayout::LayoutFormalParams() { } else { segArgsStkPassed.SetSize(static_cast(RoundUp(segArgsStkPassed.GetSize(), kSizeOfPtr))); } - if (mirFunction->GetFormalDefVec()[i].formalAttrs.GetAttr(ATTR_localrefvar)) { + if (!cgFunc->GetMirModule().IsCModule() && mirFunction->GetNthParamAttr(i).GetAttr(ATTR_localrefvar)) { SetLocalRegLocInfo(sym->GetStIdx(), *symLoc); AArch64SymbolAlloc *symLoc1 = memAllocator->GetMemPool()->New(); symLoc1->SetMemSegment(segRefLocals); -- Gitee From 8bd55019ebf25f4ac46d5ebc90a161e725e599a4 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Thu, 16 Jun 2022 10:44:59 -0700 Subject: [PATCH 089/124] Set appearsInCode and puidxOrigin fields in newly cloned functions --- src/mapleall/maple_ipa/src/ipa_clone.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mapleall/maple_ipa/src/ipa_clone.cpp b/src/mapleall/maple_ipa/src/ipa_clone.cpp index 7a9b63a0d6..24843a39bd 100644 --- a/src/mapleall/maple_ipa/src/ipa_clone.cpp +++ b/src/mapleall/maple_ipa/src/ipa_clone.cpp @@ -107,6 +107,8 @@ MIRFunction *IpaClone::IpaCloneFunction(MIRFunction &originalFunction, const std newFunc->SetSrcPosition(originalFunction.GetSrcPosition()); newFunc->SetFuncAttrs(originalFunction.GetFuncAttrs()); newFunc->SetBaseClassFuncNames(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fullName)); + newFunc->GetFuncSymbol()->SetAppearsInCode(true); + newFunc->SetPuidxOrigin(newFunc->GetPuidx()); if (originalFunction.GetBody() != nullptr) { CopyFuncInfo(originalFunction, *newFunc); newFunc->SetBody( @@ -135,6 +137,8 @@ MIRFunction *IpaClone::IpaCloneFunctionWithFreq(MIRFunction &originalFunction, newFunc->SetSrcPosition(originalFunction.GetSrcPosition()); newFunc->SetFuncAttrs(originalFunction.GetFuncAttrs()); newFunc->SetBaseClassFuncNames(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fullName)); + newFunc->GetFuncSymbol()->SetAppearsInCode(true); + newFunc->SetPuidxOrigin(newFunc->GetPuidx()); GcovFuncInfo *origProfData = originalFunction.GetFuncProfData(); auto *moduleMp = mirBuilder.GetMirModule().GetMemPool(); GcovFuncInfo *newProfData = moduleMp->New(&mirBuilder.GetMirModule().GetMPAllocator(), -- Gitee From 2c14d26804cce2d5fbf074cd5a3b50ea3819912d Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 090/124] Changes from mplcglmbc8 and mplcglmbc9. --- src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h | 2 +- src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 2 +- 2 files changed, 2 insertions(+), 2 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 3820897107..53478d0f99 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -129,7 +129,7 @@ class AArch64CGFunc : public CGFunc { uint32 LmbcFindTotalStkUsed(std::vector* paramList); uint32 LmbcTotalRegsUsed(); void LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn); - bool LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForRet(BlkassignoffNode &bNode, Operand *src); bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; 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 211fc1e041..1cc3079086 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -2271,7 +2271,7 @@ void AArch64CGFunc::SelectBlkassignoff(BlkassignoffNode &bNode, Operand *src) opndVec.push_back(regResult); /* result */ opndVec.push_back(PrepareMemcpyParamOpnd(offset, *dest)); /* param 0 */ opndVec.push_back(src); /* param 1 */ - opndVec.push_back(PrepareMemcpyParamOpnd(static_cast(static_cast(bNode.blockSize)))); /* param 2 */ + opndVec.push_back(PrepareMemcpyParamOpnd(bNode.blockSize));/* param 2 */ SelectLibCall("memcpy", opndVec, PTY_a64, PTY_a64); } -- Gitee From bc56d8522622a9fbb217fddb3d028d62deb235af Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 15 Jun 2022 16:18:04 -0700 Subject: [PATCH 091/124] Fix accessing localrefvar in memlayout by qualifying with language --- src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 53478d0f99..3820897107 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -129,7 +129,7 @@ class AArch64CGFunc : public CGFunc { uint32 LmbcFindTotalStkUsed(std::vector* paramList); uint32 LmbcTotalRegsUsed(); void LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn); - bool LmbcSmallAggForRet(BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *src); bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; -- Gitee From 314e08f5c80dc5170cf894e403a3378dc563aecf Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Fri, 17 Jun 2022 00:40:20 -0700 Subject: [PATCH 092/124] Fixed a couple of bugs in the last rebase --- .../maple_be/include/cg/aarch64/aarch64_cgfunc.h | 16 ---------------- .../maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 2 +- 2 files changed, 1 insertion(+), 17 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 3820897107..550f31f130 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -738,22 +738,6 @@ class AArch64CGFunc : public CGFunc { RegOperand &GetZeroOpnd(uint32 size) override; - int32 GetLmbcTotalStkUsed() { - return lmbcArgInfo->lmbcTotalStkUsed; - } - - void SetLmbcTotalStkUsed(int32 offset) { - lmbcArgInfo->lmbcTotalStkUsed = offset; - } - - void SetLmbcCallReturnType(MIRType *ty) { - lmbcCallReturnType = ty; - } - - MIRType *GetLmbcCallReturnType() { - return lmbcCallReturnType; - } - private: enum RelationOperator : uint8 { kAND, 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 1cc3079086..b6adc1cb23 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -893,7 +893,7 @@ MemOperand &AArch64CGFunc::ConstraintOffsetToSafeRegion(uint32 bitLen, const Mem } int32 offsetValue = static_cast(memOpnd.GetOffsetImmediate()->GetOffsetValue()); int32 multiplier = (offsetValue / k512BitSize) + static_cast(offsetValue % k512BitSize > k256BitSize); - int32 addMount = multiplier * k512BitSizeInt; + int32 addMount = multiplier * k512BitSize; int32 newOffset = offsetValue - addMount; RegOperand *baseReg = memOpnd.GetBaseRegister(); ImmOperand &immAddMount = CreateImmOperand(addMount, k64BitSize, true); -- Gitee From 7ba694c5dba34ebac3aa8a71dce449392d3a6b59 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Fri, 17 Jun 2022 21:32:32 -0700 Subject: [PATCH 093/124] Fixed bug in importing typeAttrs field of MIRStructType Also, handle the export and import of MIRAddrofConst of local symbols properly. --- src/mapleall/maple_ir/include/bin_mpl_export.h | 2 ++ src/mapleall/maple_ir/src/bin_mpl_export.cpp | 2 +- src/mapleall/maple_ir/src/bin_mpl_import.cpp | 8 ++++---- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/mapleall/maple_ir/include/bin_mpl_export.h b/src/mapleall/maple_ir/include/bin_mpl_export.h index f12bec7081..0d3d6d6457 100644 --- a/src/mapleall/maple_ir/include/bin_mpl_export.h +++ b/src/mapleall/maple_ir/include/bin_mpl_export.h @@ -180,7 +180,9 @@ class BinaryMplExport { void ExpandFourBuffSize(); MIRModule &mod; + public: MIRFunction *curFunc = nullptr; + private: size_t bufI = 0; std::vector buf; std::unordered_map gStrMark; diff --git a/src/mapleall/maple_ir/src/bin_mpl_export.cpp b/src/mapleall/maple_ir/src/bin_mpl_export.cpp index d406b89cdd..b28891b8ef 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_export.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_export.cpp @@ -45,7 +45,7 @@ void OutputConstAddrof(const MIRConst &constVal, BinaryMplExport &mplExport) { if (addrof.GetSymbolIndex().IsGlobal()) { mplExport.OutputSymbol(mplExport.GetMIRModule().CurFunction()->GetLocalOrGlobalSymbol(addrof.GetSymbolIndex())); } else { - mplExport.WriteNum(addrof.GetSymbolIndex().FullIdx()); + mplExport.OutputLocalSymbol(mplExport.curFunc->GetLocalOrGlobalSymbol(addrof.GetSymbolIndex())); } mplExport.WriteNum(addrof.GetFieldID()); mplExport.WriteNum(addrof.GetOffset()); diff --git a/src/mapleall/maple_ir/src/bin_mpl_import.cpp b/src/mapleall/maple_ir/src/bin_mpl_import.cpp index 375c84ca02..fe3eb9af27 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_import.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_import.cpp @@ -122,10 +122,10 @@ MIRConst *BinaryMplImport::ImportConst(MIRFunction *func) { return memPool->New(sym->GetStIdx(), fi, *exprTy, ofst); } case kBinKindConstAddrofLocal: { - uint32 fullidx = static_cast(ReadNum()); + MIRSymbol *sym = ImportLocalSymbol(func); FieldID fi = static_cast(ReadNum()); int32 ofst = static_cast(ReadNum()); - return memPool->New(StIdx(fullidx), fi, *type, ofst); + return memPool->New(sym->GetStIdx(), fi, *type, ofst); } case kBinKindConstAddrofFunc: { PUIdx puIdx = ImportFunction(); @@ -661,9 +661,9 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { auto kind = static_cast(ReadNum()); MIRStructType type(kind, strIdx); type.SetNameIsLocal(nameIsLocal); - auto &origType = static_cast(InsertInTypeTables(type)); - typTab.push_back(origType.GetTypeIndex()); type.SetTypeAttrs(ImportTypeAttrs()); + MIRStructType &origType = static_cast(InsertInTypeTables(type)); + typTab.push_back(origType.GetTypeIndex()); if (kind != kTypeStructIncomplete) { if (forPointedType) { typeNeedsComplete = &origType; -- Gitee From 210039193ef22d8edab9b40e65dab3d0ccceab70 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Sun, 19 Jun 2022 22:40:51 -0700 Subject: [PATCH 094/124] Rebasing edits --- .../maple_be/include/cg/aarch64/aarch64_cgfunc.h | 15 +++++++++++++++ src/mapleall/maple_be/src/cg/cgfunc.cpp | 4 ++-- 2 files changed, 17 insertions(+), 2 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 550f31f130..3309ccd7b8 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -732,6 +732,21 @@ class AArch64CGFunc : public CGFunc { return lmbcArgInfo->lmbcCallArgNumOfRegs; } + int32 GetLmbcTotalStkUsed() { + return lmbcArgInfo->lmbcTotalStkUsed; + } + + void SetLmbcTotalStkUsed(int32 offset) { + lmbcArgInfo->lmbcTotalStkUsed = offset; + } + + void SetLmbcCallReturnType(MIRType *ty) { + lmbcCallReturnType = ty; + } + + MIRType *GetLmbcCallReturnType() { + return lmbcCallReturnType; + } bool IsSPOrFP(const RegOperand &opnd) const override; bool IsReturnReg(const RegOperand &opnd) const override; bool IsSaveReg(const RegOperand ®, MIRType &mirType, BECommon &cgBeCommon) const override; diff --git a/src/mapleall/maple_be/src/cg/cgfunc.cpp b/src/mapleall/maple_be/src/cg/cgfunc.cpp index b520229206..4dc19935a6 100644 --- a/src/mapleall/maple_be/src/cg/cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/cgfunc.cpp @@ -1587,7 +1587,7 @@ void CGFunc::CreateLmbcFormalParamInfo() { stackOffset += (typeSize + 7) & (-8); LmbcFormalParamInfo *info = GetMemoryPool()->New(primType, offset, typeSize); lmbcParamVec.push_back(info); - if (idx == 0 && mirFunc.IsFirstArgReturn()) { + if (idx == 0 && func.IsFirstArgReturn()) { info->SetIsReturn(); } if (type->GetKind() == kTypeStruct) { @@ -1604,7 +1604,7 @@ void CGFunc::CreateLmbcFormalParamInfo() { } } else { /* No aggregate pass by value here */ - for (StmtNode *stmt = mirFunc.GetBody()->GetFirst(); stmt != nullptr; stmt = stmt->GetNext()) { + for (StmtNode *stmt = func.GetBody()->GetFirst(); stmt != nullptr; stmt = stmt->GetNext()) { if (stmt == nullptr) { break; } -- Gitee From 1e6c2ce999d17b4c8d56f934d140deaac731f077 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 095/124] Changes from mplcglmbc8 and mplcglmbc9. --- .../maple_be/include/cg/aarch64/aarch64_cgfunc.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) 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 3309ccd7b8..9ce531cc2a 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -753,6 +753,22 @@ class AArch64CGFunc : public CGFunc { RegOperand &GetZeroOpnd(uint32 size) override; + int32 GetLmbcTotalStkUsed() { + return lmbcArgInfo->lmbcTotalStkUsed; + } + + void SetLmbcTotalStkUsed(int32 offset) { + lmbcArgInfo->lmbcTotalStkUsed = offset; + } + + void SetLmbcCallReturnType(MIRType *ty) { + lmbcCallReturnType = ty; + } + + MIRType *GetLmbcCallReturnType() { + return lmbcCallReturnType; + } + private: enum RelationOperator : uint8 { kAND, -- Gitee From 1818621bb176320be13f7f23a9dc4284fcf91e70 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 096/124] Changes from mplcglmbc8 and mplcglmbc9. --- src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp | 1 - src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 0a4be4089a..6bd2a9b78a 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -439,7 +439,6 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; 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 b6adc1cb23..963e56d5af 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8094,6 +8094,11 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); + MIRFunction *callee = nullptr; + if (dynamic_cast(&naryNode) != nullptr) { + auto calleePuIdx = static_cast(naryNode).GetPUIdx(); + callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } -- Gitee From 66808af2c6dfde180c5d1fe7c71dce7102e650ca Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:44 -0700 Subject: [PATCH 097/124] Fred's Fixed determination logic of when there is fake parameter for returning struct, where x8 is also used to pass the fake parameter --- src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp | 1 + src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 5 ----- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 6bd2a9b78a..0a4be4089a 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -439,6 +439,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); + if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; 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 963e56d5af..b6adc1cb23 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8094,11 +8094,6 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); - MIRFunction *callee = nullptr; - if (dynamic_cast(&naryNode) != nullptr) { - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); - } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } -- Gitee From 7868867718bdfd34f67b5cec7be0a1682270c4f5 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 098/124] Changes from mplcglmbc8 and mplcglmbc9. --- .../maple_be/include/cg/aarch64/aarch64_cgfunc.h | 16 ---------------- 1 file changed, 16 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 9ce531cc2a..3309ccd7b8 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -753,22 +753,6 @@ class AArch64CGFunc : public CGFunc { RegOperand &GetZeroOpnd(uint32 size) override; - int32 GetLmbcTotalStkUsed() { - return lmbcArgInfo->lmbcTotalStkUsed; - } - - void SetLmbcTotalStkUsed(int32 offset) { - lmbcArgInfo->lmbcTotalStkUsed = offset; - } - - void SetLmbcCallReturnType(MIRType *ty) { - lmbcCallReturnType = ty; - } - - MIRType *GetLmbcCallReturnType() { - return lmbcCallReturnType; - } - private: enum RelationOperator : uint8 { kAND, -- Gitee From a849581eb3a9f63547a9e16abb50a90602d63742 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Mon, 20 Jun 2022 16:33:25 -0700 Subject: [PATCH 099/124] Set isFirst in calling LocateNextParm() so it knows to check for use of x8 to pass the first parameter --- src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp index 5ca154b1aa..b5788eb167 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp @@ -30,7 +30,7 @@ void AArch64ReachingDefinition::InitStartGen() { CCLocInfo pLoc; for (uint32 i = 0; i < cgFunc->GetFunction().GetFormalCount(); ++i) { MIRType *type = cgFunc->GetFunction().GetNthParamType(i); - parmLocator.LocateNextParm(*type, pLoc); + parmLocator.LocateNextParm(*type, pLoc, i == 0, &cgFunc->GetFunction()); if (pLoc.reg0 == 0) { /* If is a large frame, parameter addressing mode is based vreg:Vra. */ continue; -- Gitee From 24c38beffb7e79d53a4ea49de147e93305faed6b Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 100/124] Changes from mplcglmbc8 and mplcglmbc9. --- src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp | 1 - src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 0a4be4089a..6bd2a9b78a 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -439,7 +439,6 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; 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 b6adc1cb23..963e56d5af 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8094,6 +8094,11 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); + MIRFunction *callee = nullptr; + if (dynamic_cast(&naryNode) != nullptr) { + auto calleePuIdx = static_cast(naryNode).GetPUIdx(); + callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } -- Gitee From 0d0a86233ba27611872dc6b7b9b60d64d821a406 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:44 -0700 Subject: [PATCH 101/124] Fred's Fixed determination logic of when there is fake parameter for returning struct, where x8 is also used to pass the fake parameter --- src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp | 1 + src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 5 ----- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 6bd2a9b78a..0a4be4089a 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -439,6 +439,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); + if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; 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 963e56d5af..b6adc1cb23 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8094,11 +8094,6 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); - MIRFunction *callee = nullptr; - if (dynamic_cast(&naryNode) != nullptr) { - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); - } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } -- Gitee From e2816902ae596b550daaaf664debec47a3645f98 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 102/124] Changes from mplcglmbc8 and mplcglmbc9. --- src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 3309ccd7b8..0781c72948 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -129,7 +129,7 @@ class AArch64CGFunc : public CGFunc { uint32 LmbcFindTotalStkUsed(std::vector* paramList); uint32 LmbcTotalRegsUsed(); void LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn); - bool LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForRet(BlkassignoffNode &bNode, Operand *src); bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; -- Gitee From ecd2f28c966a1bcb162536467e3c980978eb14e5 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 15 Jun 2022 16:18:04 -0700 Subject: [PATCH 103/124] Fix accessing localrefvar in memlayout by qualifying with language --- src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 0781c72948..3309ccd7b8 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -129,7 +129,7 @@ class AArch64CGFunc : public CGFunc { uint32 LmbcFindTotalStkUsed(std::vector* paramList); uint32 LmbcTotalRegsUsed(); void LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn); - bool LmbcSmallAggForRet(BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *src); bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; -- Gitee From 5763af85ea9cc8f6f24f03f2bbea7fb1bf46c31b Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 104/124] Changes from mplcglmbc8 and mplcglmbc9. --- src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp | 1 - src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 0a4be4089a..6bd2a9b78a 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -439,7 +439,6 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; 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 b6adc1cb23..963e56d5af 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8094,6 +8094,11 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); + MIRFunction *callee = nullptr; + if (dynamic_cast(&naryNode) != nullptr) { + auto calleePuIdx = static_cast(naryNode).GetPUIdx(); + callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } -- Gitee From 6697035a5192be5e977ddff86f915cfb92019f33 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:44 -0700 Subject: [PATCH 105/124] Fred's Fixed determination logic of when there is fake parameter for returning struct, where x8 is also used to pass the fake parameter --- src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp | 1 + src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 5 ----- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 6bd2a9b78a..0a4be4089a 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -439,6 +439,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); + if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; 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 963e56d5af..b6adc1cb23 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8094,11 +8094,6 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); - MIRFunction *callee = nullptr; - if (dynamic_cast(&naryNode) != nullptr) { - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); - } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } -- Gitee From 678b80a29fa4cbec1bef08ab277173365590b986 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Tue, 21 Jun 2022 22:59:19 -0700 Subject: [PATCH 106/124] Fixed a bug in importing a global symbol inside a function which resulted in entering into the local symbol table --- src/mapleall/maple_ir/src/bin_func_import.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mapleall/maple_ir/src/bin_func_import.cpp b/src/mapleall/maple_ir/src/bin_func_import.cpp index 1903cc5f80..e54eea97ca 100644 --- a/src/mapleall/maple_ir/src/bin_func_import.cpp +++ b/src/mapleall/maple_ir/src/bin_func_import.cpp @@ -213,7 +213,7 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { sym = ImportLocalSymbol(func); CHECK_FATAL(sym != nullptr, "null ptr check"); } else { - sym = InSymbol(func); + sym = InSymbol(nullptr); CHECK_FATAL(sym != nullptr, "null ptr check"); if (op == OP_addrof) { sym->SetHasPotentialAssignment(); @@ -475,7 +475,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { sym = ImportLocalSymbol(func); CHECK_FATAL(sym != nullptr, "null ptr check"); } else { - sym = InSymbol(func); + sym = InSymbol(nullptr); CHECK_FATAL(sym != nullptr, "null ptr check"); sym->SetHasPotentialAssignment(); } -- Gitee From 42265f93668a4f82e498d5ee0ebe6c4dd8cc9c9c Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 107/124] Changes from mplcglmbc8 and mplcglmbc9. --- .../maple_be/include/cg/aarch64/aarch64_cgfunc.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) 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 3309ccd7b8..9ce531cc2a 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -753,6 +753,22 @@ class AArch64CGFunc : public CGFunc { RegOperand &GetZeroOpnd(uint32 size) override; + int32 GetLmbcTotalStkUsed() { + return lmbcArgInfo->lmbcTotalStkUsed; + } + + void SetLmbcTotalStkUsed(int32 offset) { + lmbcArgInfo->lmbcTotalStkUsed = offset; + } + + void SetLmbcCallReturnType(MIRType *ty) { + lmbcCallReturnType = ty; + } + + MIRType *GetLmbcCallReturnType() { + return lmbcCallReturnType; + } + private: enum RelationOperator : uint8 { kAND, -- Gitee From ec58af437cbb1ee4682cf5e72708b8e1048d885c Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 108/124] Changes from mplcglmbc8 and mplcglmbc9. --- src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp | 1 - src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 0a4be4089a..6bd2a9b78a 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -439,7 +439,6 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; 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 b6adc1cb23..963e56d5af 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8094,6 +8094,11 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); + MIRFunction *callee = nullptr; + if (dynamic_cast(&naryNode) != nullptr) { + auto calleePuIdx = static_cast(naryNode).GetPUIdx(); + callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } -- Gitee From 8493dda983ce0ad167ceb9add62b9929067214d9 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:44 -0700 Subject: [PATCH 109/124] Fred's Fixed determination logic of when there is fake parameter for returning struct, where x8 is also used to pass the fake parameter --- src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp | 1 + src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 5 ----- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 6bd2a9b78a..0a4be4089a 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -439,6 +439,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); + if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; 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 963e56d5af..b6adc1cb23 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8094,11 +8094,6 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); - MIRFunction *callee = nullptr; - if (dynamic_cast(&naryNode) != nullptr) { - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); - } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } -- Gitee From c4c293f286177216683122098942abf0c14e58e3 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 110/124] Changes from mplcglmbc8 and mplcglmbc9. --- src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 9ce531cc2a..8460e69a2c 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -129,7 +129,7 @@ class AArch64CGFunc : public CGFunc { uint32 LmbcFindTotalStkUsed(std::vector* paramList); uint32 LmbcTotalRegsUsed(); void LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn); - bool LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForRet(BlkassignoffNode &bNode, Operand *src); bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; -- Gitee From c055609c8a12b32fcedb4bf94256aa7ed01b172d Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 15 Jun 2022 16:18:04 -0700 Subject: [PATCH 111/124] Fix accessing localrefvar in memlayout by qualifying with language --- src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 8460e69a2c..9ce531cc2a 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -129,7 +129,7 @@ class AArch64CGFunc : public CGFunc { uint32 LmbcFindTotalStkUsed(std::vector* paramList); uint32 LmbcTotalRegsUsed(); void LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn); - bool LmbcSmallAggForRet(BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *src); bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; -- Gitee From 617d4116e73fb6c20b908f2dfd70683bfb4fcd53 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Fri, 17 Jun 2022 00:40:20 -0700 Subject: [PATCH 112/124] Fixed a couple of bugs in the last rebase --- .../maple_be/include/cg/aarch64/aarch64_cgfunc.h | 16 ---------------- 1 file changed, 16 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 9ce531cc2a..3309ccd7b8 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -753,22 +753,6 @@ class AArch64CGFunc : public CGFunc { RegOperand &GetZeroOpnd(uint32 size) override; - int32 GetLmbcTotalStkUsed() { - return lmbcArgInfo->lmbcTotalStkUsed; - } - - void SetLmbcTotalStkUsed(int32 offset) { - lmbcArgInfo->lmbcTotalStkUsed = offset; - } - - void SetLmbcCallReturnType(MIRType *ty) { - lmbcCallReturnType = ty; - } - - MIRType *GetLmbcCallReturnType() { - return lmbcCallReturnType; - } - private: enum RelationOperator : uint8 { kAND, -- Gitee From 553075fa12bbaf0bd931fc8a48d4b63cceff1ef0 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 113/124] Changes from mplcglmbc8 and mplcglmbc9. --- .../maple_be/include/cg/aarch64/aarch64_cgfunc.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) 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 3309ccd7b8..9ce531cc2a 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -753,6 +753,22 @@ class AArch64CGFunc : public CGFunc { RegOperand &GetZeroOpnd(uint32 size) override; + int32 GetLmbcTotalStkUsed() { + return lmbcArgInfo->lmbcTotalStkUsed; + } + + void SetLmbcTotalStkUsed(int32 offset) { + lmbcArgInfo->lmbcTotalStkUsed = offset; + } + + void SetLmbcCallReturnType(MIRType *ty) { + lmbcCallReturnType = ty; + } + + MIRType *GetLmbcCallReturnType() { + return lmbcCallReturnType; + } + private: enum RelationOperator : uint8 { kAND, -- Gitee From 421def70f194e2e48af4f71053b21d0cd7858533 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 114/124] Changes from mplcglmbc8 and mplcglmbc9. --- src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp | 1 - src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 0a4be4089a..6bd2a9b78a 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -439,7 +439,6 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; 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 b6adc1cb23..963e56d5af 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8094,6 +8094,11 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); + MIRFunction *callee = nullptr; + if (dynamic_cast(&naryNode) != nullptr) { + auto calleePuIdx = static_cast(naryNode).GetPUIdx(); + callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } -- Gitee From 185047d268bc5eb609ac86970a042de213d55a94 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:44 -0700 Subject: [PATCH 115/124] Fred's Fixed determination logic of when there is fake parameter for returning struct, where x8 is also used to pass the fake parameter --- src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp | 1 + src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 5 ----- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 6bd2a9b78a..0a4be4089a 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -439,6 +439,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); + if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; 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 963e56d5af..b6adc1cb23 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8094,11 +8094,6 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); - MIRFunction *callee = nullptr; - if (dynamic_cast(&naryNode) != nullptr) { - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); - } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } -- Gitee From a9e059f68886802c3fdf9a7d2c6188973fc21d88 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 116/124] Changes from mplcglmbc8 and mplcglmbc9. --- .../maple_be/include/cg/aarch64/aarch64_cgfunc.h | 16 ---------------- 1 file changed, 16 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 9ce531cc2a..3309ccd7b8 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -753,22 +753,6 @@ class AArch64CGFunc : public CGFunc { RegOperand &GetZeroOpnd(uint32 size) override; - int32 GetLmbcTotalStkUsed() { - return lmbcArgInfo->lmbcTotalStkUsed; - } - - void SetLmbcTotalStkUsed(int32 offset) { - lmbcArgInfo->lmbcTotalStkUsed = offset; - } - - void SetLmbcCallReturnType(MIRType *ty) { - lmbcCallReturnType = ty; - } - - MIRType *GetLmbcCallReturnType() { - return lmbcCallReturnType; - } - private: enum RelationOperator : uint8 { kAND, -- Gitee From 28fe50b6c4cd28641242d16d9e4ba079eaa9f82b Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 117/124] Changes from mplcglmbc8 and mplcglmbc9. --- .../maple_be/include/cg/aarch64/aarch64_cgfunc.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) 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 3309ccd7b8..9ce531cc2a 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -753,6 +753,22 @@ class AArch64CGFunc : public CGFunc { RegOperand &GetZeroOpnd(uint32 size) override; + int32 GetLmbcTotalStkUsed() { + return lmbcArgInfo->lmbcTotalStkUsed; + } + + void SetLmbcTotalStkUsed(int32 offset) { + lmbcArgInfo->lmbcTotalStkUsed = offset; + } + + void SetLmbcCallReturnType(MIRType *ty) { + lmbcCallReturnType = ty; + } + + MIRType *GetLmbcCallReturnType() { + return lmbcCallReturnType; + } + private: enum RelationOperator : uint8 { kAND, -- Gitee From 2c229d4bd1a1951f93f0ffa937018610ba81011c Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 118/124] Changes from mplcglmbc8 and mplcglmbc9. --- src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp | 1 - src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 0a4be4089a..6bd2a9b78a 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -439,7 +439,6 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; 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 b6adc1cb23..963e56d5af 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8094,6 +8094,11 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); + MIRFunction *callee = nullptr; + if (dynamic_cast(&naryNode) != nullptr) { + auto calleePuIdx = static_cast(naryNode).GetPUIdx(); + callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } -- Gitee From 68be0192d424fd75f812b9159bd1ae8f8500e733 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:44 -0700 Subject: [PATCH 119/124] Fred's Fixed determination logic of when there is fake parameter for returning struct, where x8 is also used to pass the fake parameter --- src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp | 1 + src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 5 ----- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 6bd2a9b78a..0a4be4089a 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -439,6 +439,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); + if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; 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 963e56d5af..b6adc1cb23 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8094,11 +8094,6 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); - MIRFunction *callee = nullptr; - if (dynamic_cast(&naryNode) != nullptr) { - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); - } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } -- Gitee From 4308922edb377c260f598274af27ff15336356d5 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 120/124] Changes from mplcglmbc8 and mplcglmbc9. --- src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 9ce531cc2a..8460e69a2c 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -129,7 +129,7 @@ class AArch64CGFunc : public CGFunc { uint32 LmbcFindTotalStkUsed(std::vector* paramList); uint32 LmbcTotalRegsUsed(); void LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn); - bool LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForRet(BlkassignoffNode &bNode, Operand *src); bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; -- Gitee From 7138ebf720e854abe2b5e53cb947f535abc72f52 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 15 Jun 2022 16:18:04 -0700 Subject: [PATCH 121/124] Fix accessing localrefvar in memlayout by qualifying with language --- src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 8460e69a2c..9ce531cc2a 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -129,7 +129,7 @@ class AArch64CGFunc : public CGFunc { uint32 LmbcFindTotalStkUsed(std::vector* paramList); uint32 LmbcTotalRegsUsed(); void LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn); - bool LmbcSmallAggForRet(BlkassignoffNode &bNode, Operand *src); + bool LmbcSmallAggForRet(const BlkassignoffNode &bNode, Operand *src); bool LmbcSmallAggForCall(BlkassignoffNode &bNode, Operand *src, std::vector **parmList); void SelectAggDassign(DassignNode &stmt) override; void SelectIassign(IassignNode &stmt) override; -- Gitee From 275b147c809dcad85f966ee5c10269b7ddda15f5 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Fri, 17 Jun 2022 00:40:20 -0700 Subject: [PATCH 122/124] Fixed a couple of bugs in the last rebase --- .../maple_be/include/cg/aarch64/aarch64_cgfunc.h | 16 ---------------- 1 file changed, 16 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 9ce531cc2a..3309ccd7b8 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -753,22 +753,6 @@ class AArch64CGFunc : public CGFunc { RegOperand &GetZeroOpnd(uint32 size) override; - int32 GetLmbcTotalStkUsed() { - return lmbcArgInfo->lmbcTotalStkUsed; - } - - void SetLmbcTotalStkUsed(int32 offset) { - lmbcArgInfo->lmbcTotalStkUsed = offset; - } - - void SetLmbcCallReturnType(MIRType *ty) { - lmbcCallReturnType = ty; - } - - MIRType *GetLmbcCallReturnType() { - return lmbcCallReturnType; - } - private: enum RelationOperator : uint8 { kAND, -- Gitee From ba7232d7de14a2abd38c73ba6a64838c58545c02 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:33 -0700 Subject: [PATCH 123/124] Changes from mplcglmbc8 and mplcglmbc9. --- src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp | 1 - src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 0a4be4089a..6bd2a9b78a 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -439,7 +439,6 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); - if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; 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 b6adc1cb23..963e56d5af 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8094,6 +8094,11 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); + MIRFunction *callee = nullptr; + if (dynamic_cast(&naryNode) != nullptr) { + auto calleePuIdx = static_cast(naryNode).GetPUIdx(); + callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); + } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } -- Gitee From 26b096a05272f08835b4817c8b40690c8eb63404 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 8 Jun 2022 15:52:44 -0700 Subject: [PATCH 124/124] Fred's Fixed determination logic of when there is fake parameter for returning struct, where x8 is also used to pass the fake parameter --- src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp | 1 + src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp | 5 ----- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp index 6bd2a9b78a..0a4be4089a 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_args.cpp @@ -439,6 +439,7 @@ void AArch64MoveRegArgs::MoveVRegisterArgs() { uint32 start = 0; if (formalCount) { MIRFunction *func = const_cast(aarchCGFunc->GetBecommon().GetMIRModule().CurFunction()); + if (func->IsReturnStruct() && func->IsFirstArgReturn()) { TyIdx tyIdx = func->GetFuncRetStructTyIdx(); if (aarchCGFunc->GetBecommon().GetTypeSize(tyIdx) <= k16BitSize) { start = 1; 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 963e56d5af..b6adc1cb23 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -8094,11 +8094,6 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo BaseNode *argExpr = naryNode.Opnd(i); PrimType primType = argExpr->GetPrimType(); ASSERT(primType != PTY_void, "primType should not be void"); - MIRFunction *callee = nullptr; - if (dynamic_cast(&naryNode) != nullptr) { - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); - } if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } -- Gitee