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 ac099f0864d72b0d137f7ff65bb0006c165b3a9f..5301c71d10e61e2083a89f785ebd9f654c49a434 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_be/include/be/lower.h b/src/mapleall/maple_be/include/be/lower.h index 2e1431aafb73bd4584086c55b01f2ac2cde7ee61..f78f035d1dbbb949bcc173989db68c1e00b57536 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 96bc53c7206620b700ad08a5a1d41580a8bb0d1e..b1bdf336c4ca40831f3a8d6347bc7c8c8cd92f50 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 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; @@ -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; + } + bool IsSPOrFP(const RegOperand &opnd) const override; bool IsReturnReg(const RegOperand &opnd) const override; bool IsSaveReg(const RegOperand ®, MIRType &mirType, BECommon &cgBeCommon) const override; @@ -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_color_ra.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_color_ra.h index a3df9f6bf325fe5bebf72f21ab43ad4b976946cd..651cd9167410dc2cd4076169517fc4419dfc6d54 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/aarch64/aarch64_phases.def b/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def index a3a74d7b2fba78318e5d5cec8bc2673a531035e7..ff08e818524a9bd8890a9a5683f2c6420a02fab9 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 9cfab98b56765a32aa0fbfc46f1334a8bf27d947..4e33309c3cb0bed5616af1dd12d51a8f1adceda7 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 093289e42bb2f0fef39dfe608b3fc285ed5e8494..e1368acb1d885216888b82c680ccaf96b325b211 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 9623c989e45406ec37f10c4027f43a458592ab52..a664565276216e863f4a935d88f1173bb04a0ae0 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; @@ -1105,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) { @@ -1274,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/be/lower.cpp b/src/mapleall/maple_be/src/be/lower.cpp index 1e6f26e990189a2e3246ebf3a27cfa3495507697..6f1bf6b01e9b8e9cb3e444d08351b32a1b9c2aa0 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 6c396f213e262898ce1ffafef008358181200f62..0a4be4089ade7af318114704659a3d6a72e5982a 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->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->IsReturnStruct()) { + 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 5b2ed3b682de77d9fa9e80b08525518eec1572d8..2fe212434c31b6e0e5be8e8bbc04df8829bf77b6 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,24 +300,24 @@ 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) { /* 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 46f0a2d610fa4aa442968c8f69143144c86e99d1..b6adc1cb2310bfa45bae1edcec2a96f625d05383 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); @@ -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)); - std::vector opndVec; - opndVec.push_back(regResult); /* result */ - opndVec.push_back(PrepareMemcpyParamOpnd(bNode.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); + /* memcpy for agg assign OR large agg for arg/ret */ + int32 offset = bNode.offset; if (IsBlkassignForPush(bNode)) { - SetLmbcArgInfo(static_cast(src), PTY_i64, (int32)bNode.offset, 1); + /* 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(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); } 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,12 +8056,23 @@ 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; 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()) { @@ -7733,8 +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"); - auto calleePuIdx = static_cast(naryNode).GetPUIdx(); - auto *callee = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(calleePuIdx); if (callee != nullptr && pnum < callee->GetFormalCount() && callee->GetFormal(pnum) != nullptr) { is64x1vec = callee->GetFormal(pnum)->GetAttr(ATTR_oneelem_simd); } @@ -7799,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 { @@ -8256,7 +8615,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 +8702,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 +8727,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 +8840,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 +9590,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 +10167,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 +10256,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_color_ra.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_color_ra.cpp index 75a5d0fab58bc22d6d3793b29d486d6f8f785ab5..b77161f548b7cb78045a78383b615fe228c7a85a 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_ebo.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp index 8525f3f08ff0605875c81c64e152db2c843fffd4..77f6a2e70f74a3019377ec84b41774dfd84bc4a3 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 a58213245c6d3a481fc0cda9b37d35f33f468141..e7d4432330dbce8810c8b4d4212375ccacf3aa8e 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->IsReturnStruct() && 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 (!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->GetNthParamAttr(i).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); @@ -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)); } @@ -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; } } @@ -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 326d730c21d2b94acf45cc23735f33bbec1384e7..25694d74035fbe8bcb76287665732675460cc9ba 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 7f246272c05159994127bed004489b495b2cbb73..455acc86bda404a18037aa7e20c0db685b71cf89 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; @@ -1118,6 +1115,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(); @@ -1226,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, @@ -1251,9 +1253,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 +1322,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 +1344,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 +1372,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 +1421,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 +1682,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 +1767,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 +1867,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 433cc85754e9cacd716a2b24c8bac1ef5f2ef6a7..b5788eb167580c54b710200207ab17433069f681 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; @@ -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 d2ae2c25c96f061970f1030fdbea46e93e861b76..bf645c15cd0f20f1d4e977781ec07e341d946458 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 50ecb583a7cbc5913935ec256917abaa88cf942a..4dc19935a66f3448fdb5099500f7a6825a35b498 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); @@ -1582,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) { @@ -1599,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; } @@ -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 cfe3ccfd7bc707ed1e901b1e8533c4a46db33c1d..97bf901870a984c343b525764d12f1d1a76d5d81 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 57e45e8a2d78f3e0bcb06372f088dcff6dd0f1ad..1b636207c67336aa08fb752251ed2eeff7cc952c 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_ipa/src/ipa_clone.cpp b/src/mapleall/maple_ipa/src/ipa_clone.cpp index 7a9b63a0d6a621193ee7c49a21b8dc984c91561e..24843a39bdb4ae96bd9a2840c3040626fdefe526 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(), diff --git a/src/mapleall/maple_ir/include/bin_mpl_export.h b/src/mapleall/maple_ir/include/bin_mpl_export.h index 09952cb8c7ed32b36a9a88037ee0c79fa5be66df..0d3d6d6457e4002664be49c502ab4b73a8a6f00b 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,9 @@ class BinaryMplExport { void ExpandFourBuffSize(); MIRModule &mod; + public: + MIRFunction *curFunc = nullptr; + private: size_t bufI = 0; std::vector buf; std::unordered_map gStrMark; @@ -190,6 +191,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 36976548723633a0d5f415deadff511789c54716..ee7f909f9bb91203f9609623b361b2a19ba9baff 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 1439b49d572f3adfbf906aacd1d3f323e5c6ecee..14ed1a367b4ea5f8b738103b6412af97f7ae2988 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 eddff2f80a507e53ce8b7cfecd319c2520543d32..51a603eafae235a6acdc13ca654ab98383dda862 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 5e6efdf9ff85bf9c1e2feac6fb742a79a4b9f29e..b7d42cb431866004559833c8d025db42f96a426c 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 256efff6d7056b0ba283ef8894d8dcfe14d34ff7..7832995ca4132edb30c8a46d35daa0128982a340 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 332a6de89fd527ea48f34f5bc09ae829666a906f..be479f65a61f4e0b9eeb2172a2d1060001ccc664 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 987aee44f68dc2c41e504e42efd4fcf8d5d28dcc..98cb801afb63f86b37bb1a13411eef89d5d1b042 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 10d1dd028a252394b88eb0de3105b964a8d0089c..b49370d0fff9afb7768924cd15c80cc32cd7d0c1 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 0d1d127dbe03e73e781860e26fd3ab5937bce515..357242d0e229d6536543141660c519a8f86d1c45 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 c5245d568c7836bd2336a0fdce288a1bef31e889..197e7d3ca2ec06ee14305fa40775fdb6222e7d54 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 814f15b2f26ed804a09cafd19cdf9e61b7b0b9b2..5a82646b11d295cbece3c26f3b1a8c4c44c1f09c 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 34cfb51c8d11308ece1fbdf08f0616a76146e3ae..0e842141edcdce169dbbb3ac3ffbb357acad5965 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 ea4ed2c1c9395ec13ccabffae749d2dbd3a42a92..b9f5e0f8c5b03cc60b53f30c88963fce5540992a 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 263ef34c80e5768011d0fdb00a059f8dc1d41c93..6815c8151d68d6df3f65454b5e0ff12eafd988c0 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 d16feb4d4a0f69dffbd4a3ea6778aa16a54451ed..e54eea97cacfadf7827ccd03e51f40ee9b71a3bb 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(nullptr); + 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(nullptr); + 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 c6d58fdd8ca822468e20cdd0f6992449cd380646..b28891b8ef87ccef979ab3fe428db46a6a85ea96 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); @@ -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()); @@ -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 049ada30f3b5822e608560f57418e23322f243f2..fe3eb9af27541771746455e25302cf8427f2824d 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_import.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_import.cpp @@ -122,18 +122,20 @@ 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(); + 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()); @@ -679,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; @@ -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 a50d6c46a5fd25a4a1680125edd153e29de94f3d..631288a2ea6c111c47f36a0fca08d8b79fb7b322 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 9e57d1514fd83a054d046e22be92412da8d3f9eb..965b2a83c6d29db6c4c7fcb1fef93128f510cd05 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 112f5ad6cf5a0ab109d3dbc77030884f1b0b89ed..4f217e54c5c94bd008601b10689b552e8044fec6 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 25cd280a075a8a57752950f7189ccc53ab91f277..53413ee084c33851c45e99646a050f339ba91e73 100644 --- a/src/mapleall/maple_ir/src/mir_lower.cpp +++ b/src/mapleall/maple_ir/src/mir_lower.cpp @@ -544,6 +544,23 @@ 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()); + 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; + } case OP_block: tmp = LowerBlock(static_cast(*stmt)); newBlock->AppendStatementsFromBlock(*tmp); @@ -999,6 +1016,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 2cbc57b314900da70dbcd2e9f90cebdebb46542a..b969cc91ea115109b7825e4d77984651651259ca 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 bae4762801f977150b0ad558d13445ce809975f6..eada04a7b9f5cb44c4c5d6422cd7475492f4fc86 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 0c9ff37468aa6ace871f104db8fbf22fb94f7f91..6dac1d09d5cf1646032f66ca817aca80577f6cb2 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 db50916351651af7566e86e2942eb134e8677b25..e8c917836748efcc7c86bb69f4923f898148c190 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 9462204fd71eaa00f23a878d380b47d379eea12e..bbeaabf09873a394016c35f8dbe9b4f49aee20ee 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 68253bb2261b7be9f65ae998b599fe653880443d..833b357561f3c46e1a9c3036ae708cacafb64020 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 c4ef2868878c6e47cb90273f3f0de3569abb922b..41af97d4543913a751490d7c55022bc98e6b2d6c 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 175cead01739d22b7b0a42651e07de5799495aa3..21f3103b3a13824cdaaa7825b871fa91cf4a49f2 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 2bb97532a6bff213017e1a587ef08b39876facbe..ba545a59910fa77f3d31bd6e91fcd8e5f26e9237 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 92eece9fa01fb77304dea43e3f16fc350265fc83..b6d96b6726927b11ce799f8f85f929a15bea7f3b 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 1f5f45518c25ca471880bf81401cd6fcc0dbcb32..f6d7b046d8f1106ed42d3c2e45a6170ce07e4168 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 b1273a8fc3c1f7b0cb0024dd86787c33b4e4fa2b..33f19ee45247877e4abbbd43900b4973f49115a1 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 a155b25fa4b492de58dfd92130569d7fe2d70086..f5893447bad26cb6dc7536ec9eaa58fadab9bb51 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 d7c2a097eb50670c29d525c1db0681969b8e0dae..b32acae493248e3e6674abc570c178908457a699 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 ad57c5b1665001e590dddb43e8c6e22cba25aefa..74e2f176c4aef2fcd885fe42f1fb6dfc728f1b94 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 05181df7968e5330ed30981c6661ddf1094918d4..a62f1a89a38bca501cad7af81b4e920e9b8aa89d 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 c14dd5c76478004e501c81e34085d075ae0a7de5..fdf2df8e3f99b197cb7cf84ea217af9daff72fab 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 09a1b64e5a5f69c382302fb8e0d23f15462ab9b8..a0b5419a8e40471fb60d899466508d92e613c6d0 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 1c7319e18bfc29f13b8a8e80b067f2ddb6db75bb..131ebbdd2a6f0e25e4143c86f9deead60f45bef4 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 9549dff0045f07a826df5f40109875300b4f4d39..eddc9704b9bf9d070ee78af419a8a66c38495593 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 67dea87820c4308e2fa068c5bf2fcb5d90524c79..52fcda8516c9f3033aa76c6f8f661a960d27f23b 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 d50e3c5371fb80fcd7d17032b840388ee2bb067f..3f5d2bff576b3aed2f49e1125ed50977db5fef7c 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 227cb6a761f6297a9ab6c99aa066f9063f7763a8..52e1df6beb4a9bc6c9d1d2676b8cd91fb7b7c05f 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 15a609e42709a778b7a947fc51a9ba0141c22e2d..f46e8e06ce4aa7a0effaa7cb0e1582382c6efc2c 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 ceff080daa2a56a5d5a150e86e80677bed2548a6..a082b80b9f248bccd9191f5c7a715c9c675c17aa 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 f84c351bd85b33eba986519e469bb88a1a1ffdc2..1b296c1de71ffc049a30b8b34a1020a3bc775782 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());