From c85223235105808b22d74c879d07b515b8cfdef4 Mon Sep 17 00:00:00 2001 From: William Chen Date: Fri, 13 May 2022 16:00:29 -0700 Subject: [PATCH 1/4] Third lmbc patch to support struct return, icall, alloca, GP. --- .../include/cg/aarch64/aarch64_cgfunc.h | 11 ++ src/mapleall/maple_be/include/cg/cgfunc.h | 9 ++ src/mapleall/maple_be/src/be/lower.cpp | 2 + .../src/cg/aarch64/aarch64_cgfunc.cpp | 124 +++++++++++++----- .../src/cg/aarch64/aarch64_memlayout.cpp | 16 +-- .../src/cg/aarch64/aarch64_proepilog.cpp | 46 +++++-- .../maple_be/src/cg/cg_phasemanager.cpp | 1 + src/mapleall/maple_be/src/cg/cgfunc.cpp | 7 +- src/mapleall/maple_be/src/cg/emit.cpp | 5 + src/mapleall/maple_ir/include/mir_type.h | 17 ++- src/mapleall/maple_ir/src/bin_mpl_export.cpp | 2 +- src/mapleall/maple_ir/src/bin_mpl_import.cpp | 4 +- src/mapleall/maple_ir/src/global_tables.cpp | 4 +- src/mapleall/maple_ir/src/mir_type.cpp | 8 +- src/mapleall/maple_ir/src/parser.cpp | 14 +- src/mapleall/maple_me/src/lmbc_lower.cpp | 25 ++-- src/mapleall/maple_me/src/lmbc_memlayout.cpp | 8 ++ 17 files changed, 227 insertions(+), 76 deletions(-) diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h index 28066b6c37..fd32e9e728 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -483,6 +483,8 @@ class AArch64CGFunc : public CGFunc { void GenerateCleanupCodeForExtEpilog(BB &bb) override; uint32 FloatParamRegRequired(MIRStructType *structType, uint32 &fpSize) override; void AssignLmbcFormalParams() override; + void LmbcGenSaveSpForAlloca() override; + MemOperand *GenLmbcFpMemOperand(int32 offset, uint32 byteSize, PrimType primType); RegOperand *GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType); Operand *GetBaseReg(const AArch64SymbolAlloc &symAlloc); int32 GetBaseOffset(const SymbolAlloc &symAlloc) override; @@ -723,6 +725,14 @@ class AArch64CGFunc : public CGFunc { return lmbcArgInfo->lmbcCallArgNumOfRegs; } + void SetLmbcCallReturnType(MIRType *ty) { + lmbcCallReturnType = ty; + } + + MIRType *GetLmbcCallReturnType() { + return lmbcCallReturnType; + } + private: enum RelationOperator : uint8 { kAND, @@ -790,6 +800,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/cgfunc.h b/src/mapleall/maple_be/include/cg/cgfunc.h index f99eafc57b..019763a051 100644 --- a/src/mapleall/maple_be/include/cg/cgfunc.h +++ b/src/mapleall/maple_be/include/cg/cgfunc.h @@ -152,6 +152,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(); @@ -1097,6 +1098,13 @@ class CGFunc { return useFP; } + void SetGP(MIRSymbol *sym) { + fileGP = sym; + } + MIRSymbol *GetGP() const { + return fileGP; + } + void UpdateAllRegisterVregMapping(MapleMap &newMap); void RegisterVregMapping(regno_t vRegNum, PregIdx pidx) { @@ -1253,6 +1261,7 @@ class CGFunc { int32 lmbcTotalArgs = 0; CGCFG *theCFG = nullptr; uint32 nextSpillLocation = 0; + MIRSymbol *fileGP = nullptr; const MapleString shortFuncName; bool hasAsm = false; diff --git a/src/mapleall/maple_be/src/be/lower.cpp b/src/mapleall/maple_be/src/be/lower.cpp index 757e22ad10..868a258da7 100644 --- a/src/mapleall/maple_be/src/be/lower.cpp +++ b/src/mapleall/maple_be/src/be/lower.cpp @@ -2179,12 +2179,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())); } } 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 6b4b6924d8..e858da117f 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -1920,14 +1920,10 @@ 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, 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); @@ -1940,9 +1936,41 @@ 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 && 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, primType); + 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, primType); + MOperator mOp = PickStInsn(bitlen, primType); + Insn &store = GetCG()->BuildInstruction(mOp, srcOpnd, *memOpnd); + GetCurBB()->AppendInsn(store); + } } void AArch64CGFunc::SelectIassignspoff(PrimType pTy, int32 offset, Operand &opnd) { @@ -1988,7 +2016,7 @@ MIRType *AArch64CGFunc::GetAggTyFromCallSite(StmtNode *stmt) { ++nargs; } if (fn->GetFormalCount() > 0) { - ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fn->GetNthParamTyIdx(nargs)); + ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fn->GetFormalDefVec()[nargs].formalTyIdx); } // would return null if the actual parameter is bogus } else if (stmt->GetOpCode() == OP_icallproto) { @@ -2910,25 +2938,9 @@ Operand *AArch64CGFunc::SelectIreadoff(const BaseNode &parent, IreadoffNode &ire } RegOperand *AArch64CGFunc::GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType) { - MemOperand *memOpnd; - RegOperand *rfp = &GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); - uint32 bitlen = byteSize * kBitsPerByte; - if (offset < 0) { - RegOperand *baseOpnd = &CreateRegisterOperandOfType(PTY_a64); - ImmOperand &immOpnd = CreateImmOperand(offset, k32BitSize, true); - Insn &addInsn = GetCG()->BuildInstruction(MOP_xaddrri12, *baseOpnd, *rfp, immOpnd); - GetCurBB()->AppendInsn(addInsn); - OfstOperand *offsetOpnd = &CreateOfstOpnd(0, k32BitSize); - memOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, bitlen, baseOpnd, - nullptr, offsetOpnd, nullptr); - } else { - OfstOperand *offsetOpnd = &CreateOfstOpnd(offset, k32BitSize); - memOpnd = &GetOrCreateMemOpnd(MemOperand::kAddrModeBOi, bitlen, rfp, - nullptr, offsetOpnd, nullptr); - } - memOpnd->SetStackMem(true); + MemOperand *memOpnd = GenLmbcFpMemOperand(offset, byteSize, primType); 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; @@ -5737,6 +5749,9 @@ Operand *AArch64CGFunc::SelectAlloca(UnaryNode &node, Operand &opnd0) { if (!CGOptions::IsArm64ilp32()) { ASSERT((node.GetPrimType() == PTY_a64), "wrong type"); } + if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + SetHasVLAOrAlloca(true); + } PrimType stype = node.Opnd(0)->GetPrimType(); Operand *resOpnd = &opnd0; if (GetPrimTypeBitSize(stype) < GetPrimTypeBitSize(PTY_u64)) { @@ -6276,6 +6291,22 @@ void AArch64CGFunc::AssignLmbcFormalParams() { } } +void AArch64CGFunc::LmbcGenSaveSpForAlloca() { + if (GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { + return; + } + Operand &spOpnd = GetOrCreatePhysicalRegisterOperand(RSP, k64BitSize, kRegTyInt); + RegOperand &spSaveOpnd = CreateVirtualRegisterOperand(NewVReg(kRegTyInt, kSizeOfPtr)); + Insn &save = GetCG()->BuildInstruction(MOP_xmovrr, spSaveOpnd, spOpnd); + GetFirstBB()->AppendInsn(save); + //save.SetFrameDef(true); + for (auto *retBB : GetExitBBsVec()) { + Insn &restore = GetCG()->BuildInstruction(MOP_xmovrr, spOpnd, spSaveOpnd); + retBB->AppendInsn(restore); + restore.SetFrameDef(true); + } +} + /* if offset < 0, allocation; otherwise, deallocation */ MemOperand &AArch64CGFunc::CreateCallFrameOperand(int32 offset, int32 size) { MemOperand *memOpnd = CreateStackMemOpnd(RSP, offset, size); @@ -8181,7 +8212,15 @@ 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); + } + LmbcSelectParmList(srcOpnds, largeStructRet); } bool callNative = false; if ((fsym->GetName() == "MCC_CallFastNative") || (fsym->GetName() == "MCC_CallFastNativeExt") || @@ -8249,7 +8288,17 @@ 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)*/); + /* 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); } @@ -8366,9 +8415,18 @@ RegOperand &AArch64CGFunc::GetOrCreateSpecialRegisterOperand(PregIdx sregIdx, Pr case kSregFp: reg = RFP; break; - case kSregGp: - reg = RFP; - break; + case kSregGp: { + MIRSymbol *sym = GetGP(); + if (sym == nullptr) { + sym = GetFunction().GetSymTab()->CreateSymbol(kScopeLocal); + std::string strBuf("__file__local__GP"); + sym->SetNameStrIdx(GetMirModule().GetMIRBuilder()->GetOrCreateStringIndex(strBuf)); + 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) { 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 38d7fc815a..d11504b75a 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp @@ -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; } @@ -225,13 +225,13 @@ void AArch64MemLayout::LayoutFormalParams() { } } bool noStackPara = false; - MIRType *ty = mirFunction->GetNthParamType(i); + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(mirFunction->GetFormalDefVec()[i].formalTyIdx); uint32 ptyIdx = ty->GetTypeIndex(); parmLocator.LocateNextParm(*ty, ploc, i == 0, mirFunction); if (ploc.reg0 != kRinvalid) { /* register */ symLoc->SetRegisters(static_cast(ploc.reg0), static_cast(ploc.reg1), static_cast(ploc.reg2), static_cast(ploc.reg3)); - if (mirFunction->GetNthParamAttr(i).GetAttr(ATTR_localrefvar)) { + if (mirFunction->GetFormalDefVec()[i].formalAttrs.GetAttr(ATTR_localrefvar)) { symLoc->SetMemSegment(segRefLocals); SetSegmentSize(*symLoc, segRefLocals, ptyIdx); } else if (!sym->IsPreg()) { @@ -274,7 +274,7 @@ void AArch64MemLayout::LayoutFormalParams() { } else { segArgsStkPassed.SetSize(static_cast(RoundUp(segArgsStkPassed.GetSize(), kSizeOfPtr))); } - if (mirFunction->GetNthParamAttr(i).GetAttr(ATTR_localrefvar)) { + if (mirFunction->GetFormalDefVec()[i].formalAttrs.GetAttr(ATTR_localrefvar)) { SetLocalRegLocInfo(sym->GetStIdx(), *symLoc); AArch64SymbolAlloc *symLoc1 = memAllocator->GetMemPool()->New(); symLoc1->SetMemSegment(segRefLocals); @@ -289,7 +289,7 @@ void AArch64MemLayout::LayoutFormalParams() { } void AArch64MemLayout::LayoutLocalVariables(std::vector &tempVar, std::vector &returnDelays) { - if (be.GetMIRModule().GetFlavor() == kFlavorLmbc && mirFunction->GetFormalCount() == 0) { + if (be.GetMIRModule().GetFlavor() == kFlavorLmbc) { segLocals.SetSize(mirFunction->GetFrameSize() - mirFunction->GetOutParmSize()); return; } @@ -374,7 +374,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)); } @@ -425,7 +425,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); } @@ -442,7 +442,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)); 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 59e44f6e28..4b1b805821 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp @@ -1109,6 +1109,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(); @@ -1242,9 +1245,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.GetMirModule().IsCModule() && cgFunc.GetFunction().GetAttr(FUNCATTR_varargs)) { /* GR/VR save areas are above the callee save area */ @@ -1636,11 +1646,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()) { @@ -1715,9 +1731,17 @@ void AArch64GenProEpilog::GeneratePopRegs() { CHECK_FATAL(*it == RLR, "The second callee saved reg is expected to be RLR"); ++it; - int32 offset = static_cast(cgFunc.GetMemlayout())->RealStackFrameSize() - - (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */) - - cgFunc.GetMemlayout()->SizeOfArgsToStackPass(); + + AArch64MemLayout *memLayout = static_cast(cgFunc.GetMemlayout()); + int32 offset; + if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + offset = static_cast(memLayout->RealStackFrameSize() - + aarchCGFunc.SizeOfCalleeSaved() - memLayout->GetSizeOfLocals()); + } else { + offset = static_cast(cgFunc.GetMemlayout())->RealStackFrameSize() - + (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen) /* for FP/LR */) - + memLayout->SizeOfArgsToStackPass(); + } if (cgFunc.GetMirModule().IsCModule() && cgFunc.GetFunction().GetAttr(FUNCATTR_varargs)) { /* GR/VR save areas are above the callee save area */ @@ -1804,7 +1828,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/cg_phasemanager.cpp b/src/mapleall/maple_be/src/cg/cg_phasemanager.cpp index 3672103dbd..3b186551e6 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 02db554427..2246356046 100644 --- a/src/mapleall/maple_be/src/cg/cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/cgfunc.cpp @@ -1568,14 +1568,14 @@ void CGFunc::CreateLmbcFormalParamInfo() { uint32 offset; uint32 typeSize; MIRFunction &func = GetFunction(); - if (func.GetParamSize() > 0) { + if (func.GetFormalCount() > 0) { int stackOffset = 0; - for (size_t idx = 0; idx < func.GetParamSize(); ++idx) { + for (size_t idx = 0; idx < func.GetFormalCount(); ++idx) { MIRSymbol *sym = func.GetFormal(idx); MIRType *type; TyIdx tyIdx; if (sym) { - tyIdx = func.GetNthParamTyIdx(idx); + tyIdx = func.GetFormalDefVec()[idx].formalTyIdx; type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); } else { FormalDef vec = const_cast(GetBecommon().GetMIRModule().CurFunction())->GetFormalDefAt(idx); @@ -2012,6 +2012,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 cf184a81ed..72a6e37625 100644 --- a/src/mapleall/maple_be/src/cg/emit.cpp +++ b/src/mapleall/maple_be/src/cg/emit.cpp @@ -2133,6 +2133,11 @@ void Emitter::EmitLocalVariable(const CGFunc &cgfunc) { } } } + if (GetCG()->GetCurCGFunc()->GetGP() != nullptr) { + Emit(asmInfo->GetLocal()).Emit("\t").Emit(GetCG()->GetCurCGFunc()->GetGP()->GetName()).Emit("\n"); + Emit(asmInfo->GetComm()).Emit("\t").Emit(GetCG()->GetCurCGFunc()->GetGP()->GetName()); + Emit(", ").Emit(GetCG()->GetMIRModule()->GetGlobalMemSize()).Emit(", ").Emit("8\n"); + } } void Emitter::EmitGlobalVar(const MIRSymbol &globalVar) { diff --git a/src/mapleall/maple_ir/include/mir_type.h b/src/mapleall/maple_ir/include/mir_type.h index d6d32d999b..207d80babc 100644 --- a/src/mapleall/maple_ir/include/mir_type.h +++ b/src/mapleall/maple_ir/include/mir_type.h @@ -1928,11 +1928,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 +1968,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/src/bin_mpl_export.cpp b/src/mapleall/maple_ir/src/bin_mpl_export.cpp index 879e34074d..090c9aac5f 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_export.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_export.cpp @@ -190,7 +190,7 @@ void OutputTypeFunction(const MIRType &ty, BinaryMplExport &mplExport, bool canU mplExport.WriteNum(kBinKindTypeFunction); mplExport.OutputTypeBase(type); mplExport.OutputType(type.GetRetTyIdx(), canUseTypename); - mplExport.WriteNum(type.IsVarargs()); + mplExport.WriteNum(type.funcAttrs.GetAttrFlag()); size_t size = type.GetParamTypeList().size(); mplExport.WriteNum(size); for (size_t i = 0; i < size; ++i) { diff --git a/src/mapleall/maple_ir/src/bin_mpl_import.cpp b/src/mapleall/maple_ir/src/bin_mpl_import.cpp index 0406ce7478..4a1a1b16ae 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_import.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_import.cpp @@ -629,7 +629,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()); @@ -808,7 +808,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()); diff --git a/src/mapleall/maple_ir/src/global_tables.cpp b/src/mapleall/maple_ir/src/global_tables.cpp index c7051c1257..2ee3711760 100644 --- a/src/mapleall/maple_ir/src/global_tables.cpp +++ b/src/mapleall/maple_ir/src/global_tables.cpp @@ -226,7 +226,9 @@ MIRType *TypeTable::GetOrCreateFunctionType(const TyIdx &retTyIdx, const std::ve const std::vector &vecAttrs, bool isVarg, const TypeAttrs &retAttrs) { MIRFuncType funcType(retTyIdx, vecType, vecAttrs, retAttrs); - funcType.SetVarArgs(isVarg); + if (isVarg) { + funcType.SetVarArgs(); + } TyIdx tyIdx = GetOrCreateMIRType(&funcType); ASSERT(tyIdx < typeTable.size(), "index out of range in TypeTable::GetOrCreateFunctionType"); return typeTable.at(tyIdx); diff --git a/src/mapleall/maple_ir/src/mir_type.cpp b/src/mapleall/maple_ir/src/mir_type.cpp index 64ee74b164..08180754b7 100644 --- a/src/mapleall/maple_ir/src/mir_type.cpp +++ b/src/mapleall/maple_ir/src/mir_type.cpp @@ -740,7 +740,9 @@ void MIRFuncType::Dump(int indent, bool dontUseName) const { if (!dontUseName && CheckAndDumpTypeName(nameStrIdx, nameIsLocal)) { return; } - LogInfo::MapleLogger() << "Dump(indent + 1); @@ -751,7 +753,7 @@ void MIRFuncType::Dump(int indent, bool dontUseName) const { LogInfo::MapleLogger() << ","; } } - if (isVarArgs) { + if (IsVarargs()) { LogInfo::MapleLogger() << ", ..."; } LogInfo::MapleLogger() << ") "; @@ -1662,7 +1664,7 @@ bool MIRFuncType::EqualTo(const MIRType &type) const { } const auto &pType = static_cast(type); return (pType.retTyIdx == retTyIdx && pType.paramTypeList == paramTypeList && - pType.isVarArgs == isVarArgs && pType.paramAttrsList == paramAttrsList && + pType.funcAttrs == funcAttrs && pType.paramAttrsList == paramAttrsList && pType.retAttrs == retAttrs); } diff --git a/src/mapleall/maple_ir/src/parser.cpp b/src/mapleall/maple_ir/src/parser.cpp index a12cec390c..0f5c5c91f9 100644 --- a/src/mapleall/maple_ir/src/parser.cpp +++ b/src/mapleall/maple_ir/src/parser.cpp @@ -1298,6 +1298,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 "); @@ -1358,7 +1367,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/src/lmbc_lower.cpp b/src/mapleall/maple_me/src/lmbc_lower.cpp index 925592b455..664cc2cb20 100644 --- a/src/mapleall/maple_me/src/lmbc_lower.cpp +++ b/src/mapleall/maple_me/src/lmbc_lower.cpp @@ -99,17 +99,18 @@ BaseNode *LMBCLowerer::LowerDreadoff(DreadoffNode *dreadoff) { 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 +130,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; } @@ -334,6 +335,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, @@ -419,7 +423,9 @@ MIRFuncType *LMBCLowerer::FuncTypeFromFuncPtrExpr(BaseNode *x) { IreadNode *iread = static_cast(x); MIRPtrType *ptrType = static_cast(iread->GetType()); MIRType *mirType = ptrType->GetPointedType(); - if (mirType->GetKind() == kTypePointer) { + if (mirType->GetKind() == kTypeFunction) { + res = static_cast(mirType); + } else if (mirType->GetKind() == kTypePointer) { res = static_cast(mirType)->GetPointedFuncType(); } break; @@ -569,6 +575,7 @@ BlockNode *LMBCLowerer::LowerBlock(BlockNode *block) { } else { LowerReturn(retNode, newblk); } + break; } case OP_call: case OP_icall: { diff --git a/src/mapleall/maple_me/src/lmbc_memlayout.cpp b/src/mapleall/maple_me/src/lmbc_memlayout.cpp index e740c5d13f..7058c58d28 100644 --- a/src/mapleall/maple_me/src/lmbc_memlayout.cpp +++ b/src/mapleall/maple_me/src/lmbc_memlayout.cpp @@ -25,8 +25,12 @@ #include "lmbc_memlayout.h" #include "mir_symbol.h" + + namespace maple { +constexpr size_t kVarargSaveAreaSize = 192; + uint32 LMBCMemLayout::FindLargestActualArea(StmtNode *stmt, int &maxActualSize) { if (!stmt) { return maxActualSize; @@ -143,6 +147,10 @@ void LMBCMemLayout::LayoutStackFrame(void) { seg_FPbased.size = maplebe::RoundDown(seg_FPbased.size, GetPrimTypeSize(PTY_ptr)); seg_formal.how_alloc.offset = seg_FPbased.size; + if (func->IsVarargs()) { + seg_FPbased.size -= kVarargSaveAreaSize; + } + // allocate the local variables uint32 symtabsize = func->GetSymTab()->GetSymbolTableSize(); for (uint32 i = 0; i < symtabsize; i++) { -- Gitee From 39ab3fee852d652949ddd757bf068b9d83a6e2d6 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Mon, 16 May 2022 16:28:36 -0700 Subject: [PATCH 2/4] When setting ATTR_localrefvar for formals, apart from field inside MIRSymbol, also need to set the formalAttrs field --- build/config/BUILDCONFIG.gn | 1 + src/mapleall/maple_ir/src/mir_function.cpp | 2 ++ src/mapleall/maple_me/src/me_rc_lowering.cpp | 1 + 3 files changed, 4 insertions(+) diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn index 58f11e6829..aa57dd3831 100755 --- a/build/config/BUILDCONFIG.gn +++ b/build/config/BUILDCONFIG.gn @@ -22,6 +22,7 @@ declare_args() { HOST_ARCH = 64 MIR_JAVA = 1 COV_CHECK = 0 + COV = 0 GCONLY = 0 OPT = "O2" TARGET = "" diff --git a/src/mapleall/maple_ir/src/mir_function.cpp b/src/mapleall/maple_ir/src/mir_function.cpp index fa41433771..7d28ea6ae5 100644 --- a/src/mapleall/maple_ir/src/mir_function.cpp +++ b/src/mapleall/maple_ir/src/mir_function.cpp @@ -305,6 +305,8 @@ void MIRFunction::DumpFlavorLoweredThanMmpl() const { ty->Dump(indent); if (symbol != nullptr) { symbol->GetAttrs().DumpAttributes(); + CHECK_FATAL(symbol->GetAttrs() == formalDefVec[i].formalAttrs, + "MIRFunction::Dump(): formal attributes inconsistent"); } else { formalDefVec[i].formalAttrs.DumpAttributes(); } diff --git a/src/mapleall/maple_me/src/me_rc_lowering.cpp b/src/mapleall/maple_me/src/me_rc_lowering.cpp index 48c3980275..463e3f3ce1 100644 --- a/src/mapleall/maple_me/src/me_rc_lowering.cpp +++ b/src/mapleall/maple_me/src/me_rc_lowering.cpp @@ -1144,6 +1144,7 @@ void RCLowering::HandleArguments() { firstBB->InsertMeStmtBefore(firstMeStmt, incCall); } sym->SetLocalRefVar(); + mirFunc->GetFormalDefVec()[i].formalAttrs.SetAttr(ATTR_localrefvar); for (auto *stmt : rets) { std::vector opnds = { argVar }; -- Gitee From 78b22d39acb93093f3d475a7244518861b9ec9d7 Mon Sep 17 00:00:00 2001 From: William Chen Date: Mon, 16 May 2022 17:36:43 -0700 Subject: [PATCH 3/4] Fix bugs --- build/config/BUILDCONFIG.gn | 1 - .../include/cg/aarch64/aarch64_cgfunc.h | 2 +- src/mapleall/maple_be/include/cg/call_conv.h | 9 ++- .../src/cg/aarch64/aarch64_cgfunc.cpp | 57 ++++++++++++++----- .../src/cg/aarch64/aarch64_offset_adjust.cpp | 2 +- src/mapleall/maple_be/src/cg/cgfunc.cpp | 23 ++++++++ src/mapleall/maple_be/src/cg/emit.cpp | 11 ++-- 7 files changed, 81 insertions(+), 24 deletions(-) diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn index aa57dd3831..58f11e6829 100755 --- a/build/config/BUILDCONFIG.gn +++ b/build/config/BUILDCONFIG.gn @@ -22,7 +22,6 @@ declare_args() { HOST_ARCH = 64 MIR_JAVA = 1 COV_CHECK = 0 - COV = 0 GCONLY = 0 OPT = "O2" TARGET = "" 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 fd32e9e728..a3c6c7289c 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -484,7 +484,7 @@ class AArch64CGFunc : public CGFunc { uint32 FloatParamRegRequired(MIRStructType *structType, uint32 &fpSize) override; void AssignLmbcFormalParams() override; void LmbcGenSaveSpForAlloca() override; - MemOperand *GenLmbcFpMemOperand(int32 offset, uint32 byteSize, PrimType primType); + MemOperand *GenLmbcFpMemOperand(int32 offset, uint32 byteSize); RegOperand *GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType); Operand *GetBaseReg(const AArch64SymbolAlloc &symAlloc); int32 GetBaseOffset(const SymbolAlloc &symAlloc) override; diff --git a/src/mapleall/maple_be/include/cg/call_conv.h b/src/mapleall/maple_be/include/cg/call_conv.h index d7a194022c..005fcfc9df 100644 --- a/src/mapleall/maple_be/include/cg/call_conv.h +++ b/src/mapleall/maple_be/include/cg/call_conv.h @@ -64,7 +64,7 @@ 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) {} + fpSize(0), isReturn(false), isPureFloat(false), isOnStack(false), hasRegassign(false) {} ~LmbcFormalParamInfo() = default; @@ -137,6 +137,12 @@ class LmbcFormalParamInfo { void SetIsOnStack() { isOnStack = true; } + bool HasRegassign() { + return hasRegassign; + } + void SetHasRegassign() { + hasRegassign = true; + } private: MIRStructType *type; PrimType primType; @@ -149,6 +155,7 @@ class LmbcFormalParamInfo { bool isReturn; bool isPureFloat = false; bool isOnStack; /* small struct with arrays need to be saved onto stack */ + bool hasRegassign; }; } /* namespace maplebe */ 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 e858da117f..94ed452049 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -1920,7 +1920,7 @@ void AArch64CGFunc::SelectIassignoff(IassignoffNode &stmt) { SelectCopy(memOpnd, destType, srcOpnd, destType); } -MemOperand *AArch64CGFunc::GenLmbcFpMemOperand(int32 offset, uint32 byteSize, PrimType primType) { +MemOperand *AArch64CGFunc::GenLmbcFpMemOperand(int32 offset, uint32 byteSize) { MemOperand *memOpnd; RegOperand *rfp = &GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); uint32 bitlen = byteSize * kBitsPerByte; @@ -1958,7 +1958,7 @@ void AArch64CGFunc::SelectIassignfpoff(IassignFPoffNode &stmt, Operand &opnd) { uint32 bitlen = byteSize * kBitsPerByte; if (isPureFpStruct) { for (int i = 0 ; i < numRegs; ++i) { - MemOperand *memOpnd = GenLmbcFpMemOperand(offset + (i * byteSize), byteSize, primType); + 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); @@ -1966,7 +1966,7 @@ void AArch64CGFunc::SelectIassignfpoff(IassignFPoffNode &stmt, Operand &opnd) { } } else { Operand &srcOpnd = LoadIntoRegister(opnd, primType); - MemOperand *memOpnd = GenLmbcFpMemOperand(offset, byteSize, primType); + MemOperand *memOpnd = GenLmbcFpMemOperand(offset, byteSize); MOperator mOp = PickStInsn(bitlen, primType); Insn &store = GetCG()->BuildInstruction(mOp, srcOpnd, *memOpnd); GetCurBB()->AppendInsn(store); @@ -2938,7 +2938,7 @@ Operand *AArch64CGFunc::SelectIreadoff(const BaseNode &parent, IreadoffNode &ire } RegOperand *AArch64CGFunc::GenLmbcParamLoad(int32 offset, uint32 byteSize, RegType regType, PrimType primType) { - MemOperand *memOpnd = GenLmbcFpMemOperand(offset, byteSize, primType); + MemOperand *memOpnd = GenLmbcFpMemOperand(offset, byteSize); RegOperand *result = &GetOrCreateVirtualRegisterOperand(NewVReg(regType, byteSize)); MOperator mOp = PickLdInsn(byteSize * kBitsPerByte, primType); Insn &load = GetCG()->BuildInstruction(mOp, *result, *memOpnd); @@ -6212,6 +6212,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)) { @@ -6219,6 +6228,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) { @@ -8162,28 +8180,37 @@ void AArch64CGFunc::LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn) MapleVector ®s = GetLmbcCallArgNumOfRegs(); int iCnt = 0; int fCnt = 0; - for (int i = isArgReturn ? 1 : 0; i < args.size(); i++) { + for (int i = isArgReturn ? 1 : 0; i < args.size(); ) { RegType ty = args[i]->GetRegisterType(); PrimType pTy = types[i]; AArch64reg reg; if (args[i]->IsOfIntClass() && (iCnt + regs[i]) <= k8ByteSize) { - reg = static_cast(R0 + iCnt++); - RegOperand *res = &GetOrCreatePhysicalRegisterOperand( - reg, GetPrimTypeSize(pTy) * kBitsPerByte, ty); - SelectCopy(*res, pTy, *args[i], pTy); - srcOpnds->PushOpnd(*res); + for (int regCnt = 0; regCnt < regs[i]; ++regCnt) { + reg = static_cast(R0 + iCnt + regCnt); + RegOperand *res = &GetOrCreatePhysicalRegisterOperand( + reg, GetPrimTypeSize(pTy) * kBitsPerByte, ty); + SelectCopy(*res, pTy, *args[i + regCnt], pTy); + srcOpnds->PushOpnd(*res); + } + iCnt += regs[i]; + i += regs[i]; } else if (!args[i]->IsOfIntClass() && (fCnt + regs[i]) <= k8ByteSize) { - reg = static_cast(V0 + fCnt++); - RegOperand *res = &GetOrCreatePhysicalRegisterOperand( - reg, GetPrimTypeSize(pTy) * kBitsPerByte, ty); - SelectCopy(*res, pTy, *args[i], pTy); - srcOpnds->PushOpnd(*res); + for (int regCnt = 0; regCnt < regs[i]; ++regCnt) { + reg = static_cast(V0 + fCnt + regCnt); + RegOperand *res = &GetOrCreatePhysicalRegisterOperand( + reg, GetPrimTypeSize(pTy) * kBitsPerByte, ty); + SelectCopy(*res, pTy, *args[i + regCnt], pTy); + srcOpnds->PushOpnd(*res); + } + fCnt += regs[i]; + i += regs[i]; } else { int32 pSize = GetPrimTypeSize(pTy); Operand &memOpd = CreateMemOpnd(RSP, offsets[i], pSize); GetCurBB()->AppendInsn( GetCG()->BuildInstruction(PickStInsn(pSize * kBitsPerByte, pTy), *args[i], memOpd)); + i++; } } /* Load x8 if 1st arg is for agg return */ diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp index eaa5726d43..7ef7190645 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_offset_adjust.cpp @@ -50,7 +50,7 @@ void AArch64FPLROffsetAdjustment::AdjustmentOffsetForOpnd(Insn &insn, AArch64CGF if (memBaseReg->GetRegisterNumber() == RFP) { RegOperand &newBaseOpnd = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(stackBaseReg, k64BitSize, kRegTyInt); MemOperand &newMemOpnd = aarchCGFunc.GetOrCreateMemOpnd( - MemOperand::kAddrModeBOi, memOpnd.GetSize(), &newBaseOpnd, memOpnd.GetIndexRegister(), + memOpnd.GetAddrMode(), memOpnd.GetSize(), &newBaseOpnd, memOpnd.GetIndexRegister(), memOpnd.GetOffsetImmediate(), memOpnd.GetSymbol()); insn.SetOperand(i, newMemOpnd); stackBaseOpnd = true; diff --git a/src/mapleall/maple_be/src/cg/cgfunc.cpp b/src/mapleall/maple_be/src/cg/cgfunc.cpp index 2246356046..bcf143a964 100644 --- a/src/mapleall/maple_be/src/cg/cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/cgfunc.cpp @@ -1569,6 +1569,7 @@ void CGFunc::CreateLmbcFormalParamInfo() { uint32 typeSize; MIRFunction &func = GetFunction(); if (func.GetFormalCount() > 0) { + /* Whenever lmbc cannot delete call type info, the prototype is available */ int stackOffset = 0; for (size_t idx = 0; idx < func.GetFormalCount(); ++idx) { MIRSymbol *sym = func.GetFormal(idx); @@ -1633,6 +1634,28 @@ 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); + LmbcFormalParamInfo *info = GetLmbcFormalParamInfo(ireadNode->GetOffset()); + info->SetHasRegassign(); + } + AssignLmbcFormalParams(); } diff --git a/src/mapleall/maple_be/src/cg/emit.cpp b/src/mapleall/maple_be/src/cg/emit.cpp index 72a6e37625..8c6980faec 100644 --- a/src/mapleall/maple_be/src/cg/emit.cpp +++ b/src/mapleall/maple_be/src/cg/emit.cpp @@ -2133,11 +2133,6 @@ void Emitter::EmitLocalVariable(const CGFunc &cgfunc) { } } } - if (GetCG()->GetCurCGFunc()->GetGP() != nullptr) { - Emit(asmInfo->GetLocal()).Emit("\t").Emit(GetCG()->GetCurCGFunc()->GetGP()->GetName()).Emit("\n"); - Emit(asmInfo->GetComm()).Emit("\t").Emit(GetCG()->GetCurCGFunc()->GetGP()->GetName()); - Emit(", ").Emit(GetCG()->GetMIRModule()->GetGlobalMemSize()).Emit(", ").Emit("8\n"); - } } void Emitter::EmitGlobalVar(const MIRSymbol &globalVar) { @@ -2153,6 +2148,12 @@ void Emitter::EmitGlobalVar(const MIRSymbol &globalVar) { } void Emitter::EmitGlobalVars(std::vector> &globalVars) { + if (GetCG()->GetCurCGFunc()->GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc && + GetCG()->GetCurCGFunc()->GetGP() != nullptr) { + Emit(asmInfo->GetLocal()).Emit("\t").Emit(GetCG()->GetCurCGFunc()->GetGP()->GetName()).Emit("\n"); + Emit(asmInfo->GetComm()).Emit("\t").Emit(GetCG()->GetCurCGFunc()->GetGP()->GetName()); + Emit(", ").Emit(GetCG()->GetMIRModule()->GetGlobalMemSize()).Emit(", ").Emit("8\n"); + } /* load globalVars profile */ if (globalVars.empty()) { return; -- Gitee From a9a1370fb2f523f330988d4de17e49cc01416b4a Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Mon, 16 May 2022 20:13:58 -0700 Subject: [PATCH 4/4] remove an added assertion that is being triggered when --quiet is not given --- src/mapleall/maple_ir/src/mir_function.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/mapleall/maple_ir/src/mir_function.cpp b/src/mapleall/maple_ir/src/mir_function.cpp index 7d28ea6ae5..fa41433771 100644 --- a/src/mapleall/maple_ir/src/mir_function.cpp +++ b/src/mapleall/maple_ir/src/mir_function.cpp @@ -305,8 +305,6 @@ void MIRFunction::DumpFlavorLoweredThanMmpl() const { ty->Dump(indent); if (symbol != nullptr) { symbol->GetAttrs().DumpAttributes(); - CHECK_FATAL(symbol->GetAttrs() == formalDefVec[i].formalAttrs, - "MIRFunction::Dump(): formal attributes inconsistent"); } else { formalDefVec[i].formalAttrs.DumpAttributes(); } -- Gitee