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 609947c35ff73ced4339d19344f106a7afb54e68..56018fcd18d42d4dced8681b6ad30ee68dc2b0a5 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -38,7 +38,7 @@ class LmbcArgInfo { MapleVector lmbcCallArgTypes; MapleVector lmbcCallArgOffsets; MapleVector lmbcCallArgNumOfRegs; // # of regs needed to complete struct - uint32 lmbcTotalStkUsed = -1; // remove when explicit addr for large agg is available + uint32 lmbcTotalStkUsed = -1; // TBD: remove when explicit addr for large agg is available }; class AArch64CGFunc : public CGFunc { @@ -102,8 +102,9 @@ class AArch64CGFunc : public CGFunc { return kRFLAG; } - MIRType *LmbcGetAggTyFromCallSite(StmtNode *stmt, std::vector **parmList) const; + MIRType *LmbcGetAggTyFromCallSite(StmtNode *stmt, std::vector **parmList); RegOperand &GetOrCreateResOperand(const BaseNode &parent, PrimType primType); + MIRStructType *GetLmbcStructArgType(BaseNode &stmt, int32 argNo); void IntrinsifyGetAndAddInt(ListOperand &srcOpnds, PrimType pty); void IntrinsifyGetAndSetInt(ListOperand &srcOpnds, PrimType pty); @@ -128,9 +129,8 @@ class AArch64CGFunc : public CGFunc { 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, const Operand *src); - bool LmbcSmallAggForCall(BlkassignoffNode &bNode, const Operand *src, std::vector **parmList); + bool LmbcSmallAggForRet(BaseNode &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; @@ -191,7 +191,8 @@ class AArch64CGFunc : public CGFunc { Operand *SelectIread(const BaseNode &parent, IreadNode &expr, int extraOffset = 0, PrimType finalBitFieldDestType = kPtyInvalid) override; Operand *SelectIreadoff(const BaseNode &parent, IreadoffNode &ireadoff) override; - Operand *SelectIreadfpoff(const BaseNode &parent, IreadFPoffNode &ireadoff) override; + Operand *SelectIreadfpoff(const BaseNode &parent, IreadFPoffNode &ireadoff /*, MIRType &ty, + ListOperand &srcOpnds, AArch64CallConvImpl &parmLocator */) override; Operand *SelectIntConst(MIRIntConst &intConst) override; Operand *HandleFmovImm(PrimType stype, int64 val, MIRConst &mirConst, const BaseNode &parent); Operand *SelectFloatConst(MIRFloatConst &floatConst, const BaseNode &parent) override; @@ -492,8 +493,7 @@ class AArch64CGFunc : public CGFunc { void AssignLmbcFormalParams() override; 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 *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; @@ -870,7 +870,7 @@ class AArch64CGFunc : public CGFunc { void SelectParmListDreadSmallAggregate(const MIRSymbol &sym, MIRType &structType, ListOperand &srcOpnds, int32 offset, AArch64CallConvImpl &parmLocator, FieldID fieldID); - void SelectParmListIreadSmallAggregate(const IreadNode &iread, MIRType &structType, ListOperand &srcOpnds, + void SelectParmListIreadSmallAggregate(BaseNode &iread, MIRType &structType, ListOperand &srcOpnds, int32 offset, AArch64CallConvImpl &parmLocator); void SelectParmListDreadLargeAggregate(const MIRSymbol &sym, MIRType &structType, ListOperand &srcOpnds, @@ -879,12 +879,12 @@ class AArch64CGFunc : public CGFunc { AArch64CallConvImpl &parmLocator, int32 &structCopyOffset, int32 fromOffset); void CreateCallStructMemcpyToParamReg(MIRType &structType, int32 structCopyOffset, AArch64CallConvImpl &parmLocator, ListOperand &srcOpnds); - void SelectParmListForAggregate(BaseNode &argExpr, ListOperand &srcOpnds, AArch64CallConvImpl &parmLocator, - int32 &structCopyOffset); + void SelectParmListForAggregate(BaseNode &parent, BaseNode &argExpr, ListOperand &srcOpnds, + AArch64CallConvImpl &parmLocator, int32 &structCopyOffset, int32 argNo); size_t SelectParmListGetStructReturnSize(StmtNode &naryNode); bool MarkParmListCall(BaseNode &expr); - void SelectParmListPreprocessLargeStruct(BaseNode &argExpr, int32 &structCopyOffset); - void SelectParmListPreprocess(const StmtNode &naryNode, size_t start, std::set &specialArgs); + void SelectParmListPreprocessLargeStruct(BaseNode &parent, BaseNode &argExpr, int32 &structCopyOffset, int32 argNo); + void SelectParmListPreprocess(StmtNode &naryNode, size_t start, std::set &specialArgs); void SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bool isCallNative = false); Operand *SelectClearStackCallParam(const AddrofNode &expr, int64 &offsetValue); void SelectClearStackCallParmList(const StmtNode &naryNode, ListOperand &srcOpnds, diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_ebo.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_ebo.h index a4fc4288b14fb98544088600477767e9c146003c..c23d9ac13fd8f8da261cc0f48013bce9d84ee923 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_ebo.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_ebo.h @@ -83,7 +83,8 @@ class AArch64Ebo : public Ebo { bool SimplifyBothConst(BB &bb, Insn &insn, const ImmOperand &immOperand0, const ImmOperand &immOperand1, uint32 opndSize) const; AArch64CC_t GetReverseCond(const CondOperand &cond) const; - bool CombineLsrAnd(Insn &insn, const OpndInfo &opndInfo, bool is64bits, bool isFp) const; + bool CombineLsrAnd(Insn &insn, const OpndInfo &opndInfo, bool is64bits, bool isFp); + bool CombineExtAnd(Insn &insn, const OpndInfo &opndInfo, bool is64bits, bool isFp, int64 immVal); }; } /* namespace maplebe */ 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 ff08e818524a9bd8890a9a5683f2c6420a02fab9..e5627ecba36db58a1263f9208fbcd2f5c324a4a6 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_phases.def @@ -36,10 +36,10 @@ ADDTARGETPHASE("ico", CGOptions::DoICO()) ADDTARGETPHASE("cfgo", !GetMIRModule()->IsCModule() && CGOptions::DoCFGO()); - if (GetMIRModule()->GetFlavor() != MIRFlavor::kFlavorLmbc) { +if (GetMIRModule()->GetFlavor() != MIRFlavor::kFlavorLmbc) { ADDTARGETPHASE("storeloadopt", CGOptions::DoStoreLoadOpt() && !CGOptions::DoCGSSA()); ADDTARGETPHASE("globalopt", CGOptions::DoGlobalOpt()); - } +} ADDTARGETPHASE("clearrdinfo", (CGOptions::DoStoreLoadOpt()) || CGOptions::DoGlobalOpt()); ADDTARGETPHASE("prepeephole1", CGOptions::DoPrePeephole()); diff --git a/src/mapleall/maple_be/include/cg/cfgo.h b/src/mapleall/maple_be/include/cg/cfgo.h index e7d6e07e146909ece19d90c98b58bc460d3cdc9e..2528f034134bf4beec1861b1cb1756170dfb86e2 100644 --- a/src/mapleall/maple_be/include/cg/cfgo.h +++ b/src/mapleall/maple_be/include/cg/cfgo.h @@ -18,6 +18,14 @@ #include "optimize_common.h" namespace maplebe { + +enum CfgoPhase : maple::uint8 { + CfgoDefault, + CfgoPreRegAlloc, + CfgoPostRegAlloc, + PostCfgo, +}; + class ChainingPattern : public OptimizationPattern { public: explicit ChainingPattern(CGFunc &func) : OptimizationPattern(func) { @@ -63,6 +71,14 @@ class FlipBRPattern : public OptimizationPattern { ~FlipBRPattern() override = default; bool Optimize(BB &curBB) override; + CfgoPhase GetPhase() const { + return phase; + } + void SetPhase(CfgoPhase val) { + phase = val; + } + CfgoPhase phase = CfgoDefault; + protected: void RelocateThrowBB(BB &curBB); }; @@ -120,6 +136,14 @@ class CFGOptimizer : public Optimizer { ~CFGOptimizer() override = default; void InitOptimizePatterns() override; + + CfgoPhase GetPhase() const { + return phase; + } + void SetPhase(CfgoPhase val) { + phase = val; + } + CfgoPhase phase = CfgoDefault; }; MAPLE_FUNC_PHASE_DECLARE_BEGIN(CgCfgo, maplebe::CGFunc) diff --git a/src/mapleall/maple_be/include/cg/cgfunc.h b/src/mapleall/maple_be/include/cg/cgfunc.h index 4a8ee93eb88a16e3faa03544d1b7296961513eae..d1000e190c23d0ddd1ebd5517af5b0e8fc07f67c 100644 --- a/src/mapleall/maple_be/include/cg/cgfunc.h +++ b/src/mapleall/maple_be/include/cg/cgfunc.h @@ -81,6 +81,7 @@ class SpillMemOperandSet { class LiveRange; #endif /* TARGARM32 */ constexpr uint32 kVRegisterNumber = 80; +constexpr uint32 kNumBBOptReturn = 30; class CGFunc { public: enum ShiftDirection : uint8 { @@ -1149,8 +1150,8 @@ class CGFunc { #endif MapleMap vregsToPregsMap; uint32 totalInsns = 0; - int32 structCopySize; - int32 maxParamStackSize; + int32 structCopySize = 0; + int32 maxParamStackSize = 0; static constexpr int kRegIncrStepLen = 80; /* reg number increate step length */ bool hasVLAOrAlloca = false; diff --git a/src/mapleall/maple_be/include/cg/loop.h b/src/mapleall/maple_be/include/cg/loop.h index 658ee83f0433058f14f7fae281f8b11e78a98172..eedf5bc02c154c4bf4797469f1d9b8d1f708be90 100644 --- a/src/mapleall/maple_be/include/cg/loop.h +++ b/src/mapleall/maple_be/include/cg/loop.h @@ -171,7 +171,8 @@ class CGFuncLoops { void CheckOverlappingInnerLoops(const MapleVector &iLoops, const MapleVector &loopMem) const; void CheckLoops() const; - void PrintLoops(const CGFuncLoops &funcLoop) const; + void PrintLoops(const CGFuncLoops &loops) const; + bool IsBBLoopMember(const BB *bb) const; const BB *GetHeader() const { return header; diff --git a/src/mapleall/maple_be/include/cg/reaching.h b/src/mapleall/maple_be/include/cg/reaching.h index 55b4b666fe45fb5bd7fc6c452a788a905e6236b9..13872a91226088af7949555b95e0aeb26e0b87bb 100644 --- a/src/mapleall/maple_be/include/cg/reaching.h +++ b/src/mapleall/maple_be/include/cg/reaching.h @@ -146,6 +146,7 @@ class ReachingDefinition : public AnalysisResult { std::vector memIn; std::vector memOut; const uint32 kMaxBBNum; + uint32 stackSize = 0; private: void Initialize(); void InitDataSize(); 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 d08b9a778c4a37402913f0f72b095a5129e451b0..97ebb9ebe994e91fe3b0a23b0708b556d97b8269 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -161,6 +161,28 @@ bool IsBlkassignForPush(const BlkassignoffNode &bNode) { return spBased; } +MIRStructType *AArch64CGFunc::GetLmbcStructArgType(BaseNode &stmt, int32 argNo) { + MIRType *ty = nullptr; + if (stmt.GetOpCode() == OP_call) { + CallNode &callNode = static_cast(stmt); + MIRFunction *callFunc = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callNode.GetPUIdx()); + if (callFunc->GetFormalCount() < (argNo + 1)) { + return nullptr; /* formals less than actuals */ + } + ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(callFunc->GetFormalDefVec()[argNo].formalTyIdx); + } else if (stmt.GetOpCode() == OP_icallproto) { + IcallNode &icallproto = static_cast(stmt); + MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallproto.GetRetTyIdx()); + MIRFuncType *fType = static_cast(type); + if (fType->GetParamTypeList().size() < (argNo + 1)) { + return nullptr; + } + ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(fType->GetNthParamType(argNo)); + } + CHECK_FATAL(ty && ty->IsStructType(), "lmbc agg arg error"); + return static_cast(ty); +} + RegOperand &AArch64CGFunc::GetOrCreateResOperand(const BaseNode &parent, PrimType primType) { RegOperand *resOpnd = nullptr; if (parent.GetOpCode() == OP_regassign) { @@ -1234,6 +1256,42 @@ void AArch64CGFunc::SelectAsm(AsmNode &node) { } break; } + case OP_addrofoff: { + auto &addrofoffNode = static_cast(*node.Opnd(i)); + Operand *inOpnd = SelectAddrofoff(addrofoffNode, node); + listInputOpnd->PushOpnd(static_cast(*inOpnd)); + PrimType pType = addrofoffNode.GetPrimType(); + listInRegPrefix->stringList.push_back( + static_cast(&CreateStringOperand(GetRegPrefixFromPrimType(pType, inOpnd->GetSize(), str)))); + if (isOutputTempNode) { + rPlusOpnd.emplace_back(std::make_pair(inOpnd, pType)); + } + break; + } + case OP_ireadoff: { + IreadoffNode *ireadoff = static_cast(node.Opnd(i)); + Operand *inOpnd = SelectIreadoff(node, *ireadoff); + listInputOpnd->PushOpnd(static_cast(*inOpnd)); + PrimType pType = ireadoff->GetPrimType(); + listInRegPrefix->stringList.push_back( + static_cast(&CreateStringOperand(GetRegPrefixFromPrimType(pType, inOpnd->GetSize(), str)))); + if (isOutputTempNode) { + rPlusOpnd.emplace_back(std::make_pair(inOpnd, pType)); + } + break; + } + case OP_add: { + BinaryNode *addNode = static_cast(node.Opnd(i)); + Operand *inOpnd = SelectAdd(*addNode, *HandleExpr(*addNode, *addNode->Opnd(0)), *HandleExpr(*addNode, *addNode->Opnd(1)), node); + listInputOpnd->PushOpnd(static_cast(*inOpnd)); + PrimType pType = addNode->GetPrimType(); + listInRegPrefix->stringList.push_back( + static_cast(&CreateStringOperand(GetRegPrefixFromPrimType(pType, inOpnd->GetSize(), str)))); + if (isOutputTempNode) { + rPlusOpnd.emplace_back(std::make_pair(inOpnd, pType)); + } + break; + } case OP_constval: { CHECK_FATAL(!isOutputTempNode, "Unexpect"); auto &constNode = static_cast(*node.Opnd(i)); @@ -1429,6 +1487,14 @@ void AArch64CGFunc::SelectRegassign(RegassignNode &stmt, Operand &opnd0) { prev->SetMOP(MOP_xldrsw); } } +#if 0 + if (lhsSize == PTY_agg && (stmt.Opnd(0)->GetOpCode() == OP_ireadoff || stmt.Opnd(0)->GetOpCode() == OP_ireadfpoff)) { + PregIdx pregIdx = stmt.GetRegIdx(); + if ((-pregIdx) == kSregRetval0) { + return; // Already loaded to correct return registers + } + } +#endif } RegOperand *regOpnd = nullptr; PregIdx pregIdx = stmt.GetRegIdx(); @@ -1987,9 +2053,8 @@ void AArch64CGFunc::SelectIassignfpoff(IassignFPoffNode &stmt, Operand &opnd) { 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() <= k16BitSize, "SelectIassignfpoff invalid agg size"); + 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 > 0) { @@ -2000,8 +2065,8 @@ void AArch64CGFunc::SelectIassignfpoff(IassignFPoffNode &stmt, Operand &opnd) { uint32 byteSize = GetPrimTypeSize(primType); uint32 bitlen = byteSize * kBitsPerByte; if (isPureFpStruct) { - for (uint32 i = 0 ; i < numRegs; ++i) { - MemOperand *memOpnd = GenLmbcFpMemOperand(offset + static_cast(i * byteSize), byteSize); + 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); @@ -2044,8 +2109,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::LmbcGetAggTyFromCallSite(StmtNode *stmt, std::vector **parmList) const { - 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; } @@ -2076,7 +2141,7 @@ MIRType *AArch64CGFunc::LmbcGetAggTyFromCallSite(StmtNode *stmt, std::vector(static_cast(src)->GetRegisterNumber()); @@ -2086,9 +2151,9 @@ bool AArch64CGFunc::LmbcSmallAggForRet(const BlkassignoffNode &bNode, const Oper /* This blkassignoff is for struct return? */ uint32 loadSize; uint32 numRegs = 0; - if (bNode.GetNext()->GetOpCode() == OP_return) { - MIRStructType *ty = static_cast( - GlobalTables::GetTypeTable().GetTypeFromTyIdx(func->GetFuncRetStructTyIdx())); + if (static_cast(bNode).GetNext()->GetOpCode() == OP_return) { + MIRStructType *ty = static_cast(func->GetReturnType()); + uint32 tySize = GetBecommon().GetTypeSize(ty->GetTypeIndex()); uint32 fpregs = FloatParamRegRequired(ty, size); if (fpregs > 0) { /* pure floating point in agg */ @@ -2107,7 +2172,7 @@ bool AArch64CGFunc::LmbcSmallAggForRet(const BlkassignoffNode &bNode, const Oper numRegs = 2; pTy = PTY_i64; size = k4ByteSize; - switch (bNode.blockSize) { + switch (tySize) { case 1: pTy = PTY_i8; break; @@ -2125,7 +2190,7 @@ bool AArch64CGFunc::LmbcSmallAggForRet(const BlkassignoffNode &bNode, const Oper MemOperand &mem = CreateMemOpnd(regno, 0, size * kBitsPerByte); RegOperand *res = &GetOrCreatePhysicalRegisterOperand(R0, loadSize, kRegTyInt); SelectCopy(*res, pTy, mem, pTy); - if (bNode.blockSize > static_cast(k8ByteSize)) { + if (tySize > static_cast(k8ByteSize)) { MemOperand &newMem = CreateMemOpnd(regno, k8ByteSize, size * kBitsPerByte); res = &GetOrCreatePhysicalRegisterOperand(R1, loadSize, kRegTyInt); SelectCopy(*res, pTy, newMem, pTy); @@ -2146,7 +2211,7 @@ bool AArch64CGFunc::LmbcSmallAggForRet(const BlkassignoffNode &bNode, const Oper } /* return true if blkassignoff for return, false otherwise */ -bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, const Operand *src, std::vector **parmList) { +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; @@ -2161,7 +2226,7 @@ bool AArch64CGFunc::LmbcSmallAggForCall(BlkassignoffNode &bNode, const Operand * MemOperand &mem = CreateMemOpnd(regno, s, size * kBitsPerByte); RegOperand *res = &CreateVirtualRegisterOperand(NewVReg(kRegTyFloat, size)); SelectCopy(*res, pTy, mem, pTy); - SetLmbcArgInfo(res, pTy, 0, static_cast(fpregs)); + SetLmbcArgInfo(res, pTy, 0, fpregs); IncLmbcArgsInRegs(kRegTyFloat); } IncLmbcTotalArgs(); @@ -2209,7 +2274,7 @@ uint32 AArch64CGFunc::LmbcFindTotalStkUsed(std::vector *paramList) { CCLocInfo pLoc; for (TyIdx tyIdx : *paramList) { MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); - (void)parmlocator.LocateNextParm(*ty, pLoc); + parmlocator.LocateNextParm(*ty, pLoc); } return 0; } @@ -2225,12 +2290,12 @@ uint32 AArch64CGFunc::LmbcTotalRegsUsed() { uint32 fCnt = 0; for (uint32 i = 0; i < regs.size(); i++) { if (IsPrimitiveInteger(types[i])) { - if ((iCnt + static_cast(regs[i])) <= k8ByteSize) { - iCnt += static_cast(regs[i]); + if ((iCnt + regs[i]) <= k8ByteSize) { + iCnt += regs[i]; }; } else { - if ((fCnt + static_cast(regs[i])) <= k8ByteSize) { - fCnt += static_cast(regs[i]); + if ((fCnt + regs[i]) <= k8ByteSize) { + fCnt += regs[i]; }; } } @@ -2277,7 +2342,7 @@ void AArch64CGFunc::SelectBlkassignoff(BlkassignoffNode &bNode, Operand *src) opndVec.push_back(regResult); /* result */ opndVec.push_back(PrepareMemcpyParamOpnd(offset, *dest)); /* param 0 */ opndVec.push_back(src); /* param 1 */ - opndVec.push_back(PrepareMemcpyParamOpnd(static_cast(static_cast(bNode.blockSize)))); /* param 2 */ + opndVec.push_back(PrepareMemcpyParamOpnd(bNode.blockSize));/* param 2 */ SelectLibCall("memcpy", opndVec, PTY_a64, PTY_a64); } @@ -2287,15 +2352,6 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { uint32 lhsOffset = 0; MIRType *stmtType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(stmt.GetTyIdx()); MIRPtrType *lhsPointerType = static_cast(stmtType); - bool loadToRegs4StructReturn = false; - if (mirModule.CurFunction()->StructReturnedInRegs()) { - MIRSymbol *retSt = mirModule.CurFunction()->GetFormal(0); - if (stmt.Opnd(0)->GetOpCode() == OP_dread) { - DreadNode *dread = static_cast(stmt.Opnd(0)); - MIRSymbol *addrSym = mirModule.CurFunction()->GetLocalOrGlobalSymbol(dread->GetStIdx()); - loadToRegs4StructReturn = (retSt == addrSym); - } - } MIRType *lhsType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(lhsPointerType->GetPointedTyIdx()); if (stmt.GetFieldID() != 0) { MIRStructType *structType = static_cast(lhsType); @@ -2339,91 +2395,6 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { rhsType = structType->GetFieldType(rhsDread->GetFieldID()); rhsOffset = static_cast(GetBecommon().GetFieldOffset(*structType, rhsDread->GetFieldID()).first); } - if (loadToRegs4StructReturn) { - /* generate move to regs for agg return */ - CHECK_FATAL(lhsSize <= k16ByteSize, "SelectAggIassign: illegal struct size"); - AArch64CallConvImpl parmlocator(GetBecommon()); - CCLocInfo pLoc; - parmlocator.LocateNextParm(*lhsType, 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 > 0) { - 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 = (lhsSize <= k8ByteSize) ? kOneRegister : kTwoRegister; - regType = kRegTyInt; - retPty = PTY_u64; - } else { - loadSize = (lhsSize <= k4ByteSize) ? k4ByteSize : k8ByteSize; - numRegs = (lhsSize <= k8ByteSize) ? kOneRegister : kTwoRegister; - regType = kRegTyInt; - retPty = PTY_u32; - } - } - bool parmCopy = IsParamStructCopy(*rhsSymbol); - for (uint32 i = 0; i < numRegs; i++) { - if (parmCopy) { - rhsmemopnd = &LoadStructCopyBase(*rhsSymbol, - (rhsOffset + static_cast(i * (fpParm ? loadSize : k8ByteSize))), - static_cast(loadSize * kBitsPerByte)); - } else { - rhsmemopnd = &GetOrCreateMemOpnd(*rhsSymbol, - (rhsOffset + 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[kFirstReg] = static_cast(pLoc.reg0); - regs[kSecondReg] = static_cast(pLoc.reg1); - regs[kThirdReg] = static_cast(pLoc.reg2); - regs[kFourthReg] = static_cast(pLoc.reg3); - 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; - } - RegOperand &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; - } - RegOperand &dest = GetOrCreatePhysicalRegisterOperand(preg, loadSize * kBitsPerByte, regType); - Insn &pseudo = GetCG()->BuildInstruction(mop3, dest); - GetCurBB()->AppendInsn(pseudo); - } - return; - } rhsAlign = GetBecommon().GetTypeAlign(rhsType->GetTypeIndex()); alignUsed = std::min(lhsAlign, rhsAlign); ASSERT(alignUsed != 0, "expect non-zero"); @@ -2539,42 +2510,6 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { rhsOffset = static_cast(GetBecommon().GetFieldOffset(*rhsStructType, rhsIread->GetFieldID()).first); isRefField = GetBecommon().IsRefField(*rhsStructType, rhsIread->GetFieldID()); } - if (loadToRegs4StructReturn) { - /* generate move to regs. */ - CHECK_FATAL(lhsSize <= k16ByteSize, "SelectAggIassign: illegal struct size"); - RegOperand *result[kTwoRegister]; /* maximum 16 bytes, 2 registers */ - uint32 loadSize; - if (CGOptions::IsBigEndian()) { - loadSize = k8ByteSize; - } else { - loadSize = (lhsSize <= k4ByteSize) ? k4ByteSize : k8ByteSize; - } - uint32 numRegs = (lhsSize <= k8ByteSize) ? kOneRegister : kTwoRegister; - for (uint32 i = 0; i < numRegs; i++) { - OfstOperand *rhsOffOpnd = &GetOrCreateOfstOpnd(rhsOffset + 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); - } - for (uint32 i = 0; i < numRegs; i++) { - AArch64reg preg = (i == 0 ? R0 : R1); - RegOperand &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); - RegOperand &dest = GetOrCreatePhysicalRegisterOperand(preg, loadSize * kBitsPerByte, kRegTyInt); - Insn &pseudo = cg->BuildInstruction(MOP_pseudo_ret_int, dest); - GetCurBB()->AppendInsn(pseudo); - } - return; - } rhsAlign = GetBecommon().GetTypeAlign(rhsType->GetTypeIndex()); alignUsed = std::min(lhsAlign, rhsAlign); ASSERT(alignUsed != 0, "expect non-zero"); @@ -2681,7 +2616,7 @@ void AArch64CGFunc::SelectReturnSendOfStructInRegs(BaseNode *x) { /* generate move to regs for agg return */ AArch64CallConvImpl parmlocator(GetBecommon()); CCLocInfo pLoc; - (void)parmlocator.LocateNextParm(*mirType, pLoc, true, GetBecommon().GetMIRModule().CurFunction()); + 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 */ @@ -3176,9 +3111,20 @@ Operand *AArch64CGFunc::SelectIreadoff(const BaseNode &parent, IreadoffNode &ire auto *baseAddr = ireadoff.Opnd(0); auto *result = &CreateRegisterOperandOfType(primType); auto *addrOpnd = HandleExpr(ireadoff, *baseAddr); - auto &memOpnd = CreateMemOpnd(LoadIntoRegister(*addrOpnd, PTY_a64), offset, bitSize); - auto mop = PickLdInsn(bitSize, primType); - GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mop, *result, memOpnd)); + if (primType == PTY_agg && parent.GetOpCode() == OP_regassign) { + auto &memOpnd = CreateMemOpnd(LoadIntoRegister(*addrOpnd, PTY_a64), offset, bitSize); + auto mop = PickLdInsn(64, PTY_a64); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mop, *result, memOpnd)); + auto ®AssignNode = static_cast(parent); + PregIdx pIdx = regAssignNode.GetRegIdx(); + CHECK_FATAL(IsSpecialPseudoRegister(pIdx), "SelectIreadfpoff of agg"); + LmbcSmallAggForRet(const_cast(parent), addrOpnd); + // result not used + } else { + auto &memOpnd = CreateMemOpnd(LoadIntoRegister(*addrOpnd, PTY_a64), offset, bitSize); + auto mop = PickLdInsn(bitSize, primType); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(mop, *result, memOpnd)); + } return result; } @@ -3203,8 +3149,8 @@ RegOperand *AArch64CGFunc::LmbcStructReturnLoad(int32 offset) { if (numFpRegs > 0) { PrimType pType = (fpSize <= k4ByteSize) ? PTY_f32 : PTY_f64; for (int32 i = (numFpRegs - kOneRegister); i > 0; --i) { - result = GenLmbcParamLoad(offset + (i * static_cast(fpSize)), fpSize, kRegTyFloat, pType); - AArch64reg regNo = static_cast(V0 + static_cast(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); @@ -3216,7 +3162,7 @@ RegOperand *AArch64CGFunc::LmbcStructReturnLoad(int32 offset) { } else if (sz <= k8ByteSize) { result = GenLmbcParamLoad(offset, k8ByteSize, kRegTyInt, PTY_i64); } else if (sz <= k16ByteSize) { - result = GenLmbcParamLoad(offset + k8ByteSizeInt, k8ByteSize, kRegTyInt, PTY_i64); + 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); @@ -3226,15 +3172,17 @@ RegOperand *AArch64CGFunc::LmbcStructReturnLoad(int32 offset) { return result; } -Operand *AArch64CGFunc::SelectIreadfpoff(const BaseNode &parent, IreadFPoffNode &ireadoff) { +Operand *AArch64CGFunc::SelectIreadfpoff(const BaseNode &parent, IreadFPoffNode &ireadoff /*, MIRType &ty, + ListOperand &srcOpnds, AArch64CallConvImpl &parmLocator*/) { int32 offset = ireadoff.GetOffset(); PrimType primType = ireadoff.GetPrimType(); uint32 bytelen = GetPrimTypeSize(primType); - uint32 bitlen = bytelen * kBitsPerByte; RegType regty = GetRegTyFromPrimTy(primType); RegOperand *result = nullptr; if (offset >= 0) { - LmbcFormalParamInfo *info = GetLmbcFormalParamInfo(static_cast(offset)); +#if OLD_LMBC // TBD + uint32 bitlen = bytelen * kBitsPerByte; + LmbcFormalParamInfo *info = GetLmbcFormalParamInfo(offset); if (info->GetPrimType() == PTY_agg) { if (info->IsOnStack()) { result = GenLmbcParamLoad(info->GetOnStackOffset(), GetPrimTypeSize(PTY_a64), kRegTyInt, PTY_a64); @@ -3250,16 +3198,30 @@ Operand *AArch64CGFunc::SelectIreadfpoff(const BaseNode &parent, IreadFPoffNode } else { CHECK_FATAL(primType == info->GetPrimType(), "Incorrect primtype"); CHECK_FATAL(offset == info->GetOffset(), "Incorrect offset"); - if (info->GetRegNO() == 0 || !info->HasRegassign()) { + if (info->GetRegNO() == 0 || info->HasRegassign() == false) { result = GenLmbcParamLoad(offset, bytelen, regty, primType); } else { result = &GetOrCreatePhysicalRegisterOperand(static_cast(info->GetRegNO()), bitlen, regty); } } +#else + CHECK_FATAL(0, "Invalid ireadfpoff offset"); +#endif } else { if (primType == PTY_agg) { - CHECK_FATAL(parent.GetOpCode() == OP_regassign, "SelectIreadfpoff of agg"); - result = LmbcStructReturnLoad(offset); +#if OLD_LMBC // TBD + if (parent.GetOpCode() == OP_call || parent.GetOpCode() == OP_icallproto) { + /* ireadfpoff is now for loading locals under calls. Large agg arg is handled via + SelectParmListPreprocess, Hence only small agg is handled here */ + SelectParmListIreadSmallAggregate(ireadoff, ty, srcOpnds, 0, parmLocator); + } else { +#endif + /* agg return */ + CHECK_FATAL(parent.GetOpCode() == OP_regassign, "SelectIreadfpoff of agg"); + result = LmbcStructReturnLoad(offset); +#if OLD_LMBC // TBD + } +#endif } else { result = GenLmbcParamLoad(offset, bytelen, regty, primType); } @@ -6518,10 +6480,10 @@ void AArch64CGFunc::AssignLmbcFormalParams() { param->SetRegNO(0); } else { param->SetRegNO(intReg); - if (!param->HasRegassign()) { + if (param->HasRegassign() == false) { uint32 bytelen = GetPrimTypeSize(primType); uint32 bitlen = bytelen * kBitsPerByte; - MemOperand *mOpnd = GenLmbcFpMemOperand(static_cast(offset), bytelen); + MemOperand *mOpnd = GenLmbcFpMemOperand(offset, bytelen); RegOperand &src = GetOrCreatePhysicalRegisterOperand(AArch64reg(intReg), bitlen, kRegTyInt); MOperator mOp = PickStInsn(bitlen, primType); Insn &store = GetCG()->BuildInstruction(mOp, src, *mOpnd); @@ -6534,10 +6496,10 @@ void AArch64CGFunc::AssignLmbcFormalParams() { param->SetRegNO(0); } else { param->SetRegNO(fpReg); - if (!param->HasRegassign()) { + if (param->HasRegassign() == false) { uint32 bytelen = GetPrimTypeSize(primType); uint32 bitlen = bytelen * kBitsPerByte; - MemOperand *mOpnd = GenLmbcFpMemOperand(static_cast(offset), bytelen); + MemOperand *mOpnd = GenLmbcFpMemOperand(offset, bytelen); RegOperand &src = GetOrCreatePhysicalRegisterOperand(AArch64reg(fpReg), bitlen, kRegTyFloat); MOperator mOp = PickStInsn(bitlen, primType); Insn &store = GetCG()->BuildInstruction(mOp, src, *mOpnd); @@ -6561,10 +6523,10 @@ void AArch64CGFunc::AssignLmbcFormalParams() { } else { param->SetRegNO(intReg); param->SetIsOnStack(); - param->SetOnStackOffset(((intReg - R0 + fpReg) - V0) * k8ByteSize); + param->SetOnStackOffset((intReg - R0 + fpReg - V0) * k8ByteSize); uint32 bytelen = GetPrimTypeSize(PTY_a64); uint32 bitlen = bytelen * kBitsPerByte; - MemOperand *mOpnd = GenLmbcFpMemOperand(static_cast(param->GetOnStackOffset()), bytelen); + 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); @@ -6623,13 +6585,14 @@ void AArch64CGFunc::AssignLmbcFormalParams() { } void AArch64CGFunc::LmbcGenSaveSpForAlloca() { - if (GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc || !HasVLAOrAlloca()) { + 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); @@ -7484,12 +7447,26 @@ void AArch64CGFunc::SelectParmListDreadSmallAggregate(const MIRSymbol &sym, MIRT } } -void AArch64CGFunc::SelectParmListIreadSmallAggregate(const IreadNode &iread, MIRType &structType, +void AArch64CGFunc::SelectParmListIreadSmallAggregate(BaseNode &iread, MIRType &structType, ListOperand &srcOpnds, int32 offset, AArch64CallConvImpl &parmLocator) { int32 symSize = GetBecommon().GetTypeSize(structType.GetTypeIndex().GetIdx()); - RegOperand *addrOpnd0 = static_cast(HandleExpr(iread, *(iread.Opnd(0)))); - RegOperand *addrOpnd1 = &LoadIntoRegister(*addrOpnd0, iread.Opnd(0)->GetPrimType()); + RegOperand *addrOpnd1; + if (iread.GetOpCode() == OP_iread) { + RegOperand *addrOpnd0 = static_cast(HandleExpr(iread, *(iread.Opnd(0)))); + addrOpnd1 = &LoadIntoRegister(*addrOpnd0, iread.Opnd(0)->GetPrimType()); + } else if (iread.GetOpCode() == OP_ireadfpoff) { + IreadFPoffNode &ireadoff = static_cast(iread); + RegOperand *rfp = &GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); + RegOperand *addrOpnd0 = &CreateRegisterOperandOfType(PTY_a64); + ImmOperand &immOpnd = CreateImmOperand(ireadoff.GetOffset(), k32BitSize, true); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_xaddrri12, *addrOpnd0, *rfp, immOpnd)); + addrOpnd1 = &LoadIntoRegister(*addrOpnd0, PTY_i64); + } else if (iread.GetOpCode() == OP_ireadoff) { + IreadoffNode &ireadoff = static_cast(iread); + RegOperand *addrOpnd0 = static_cast(HandleExpr(ireadoff, *(ireadoff.Opnd(0)))); + addrOpnd1 = &LoadIntoRegister(*addrOpnd0, PTY_i64); + } CCLocInfo ploc; parmLocator.LocateNextParm(structType, ploc); if (ploc.reg0 == 0) { @@ -7862,8 +7839,8 @@ void AArch64CGFunc::CreateCallStructMemcpyToParamReg(MIRType &structType, int32 } } -void AArch64CGFunc::SelectParmListForAggregate(BaseNode &argExpr, ListOperand &srcOpnds, - AArch64CallConvImpl &parmLocator, int32 &structCopyOffset) { +void AArch64CGFunc::SelectParmListForAggregate(BaseNode &parent, BaseNode &argExpr, ListOperand &srcOpnds, + AArch64CallConvImpl &parmLocator, int32 &structCopyOffset, int32 argNo) { uint64 symSize; int32 rhsOffset = 0; if (argExpr.GetOpCode() == OP_dread) { @@ -7911,6 +7888,32 @@ void AArch64CGFunc::SelectParmListForAggregate(BaseNode &argExpr, ListOperand &s } else { SelectParmListIreadLargeAggregate(iread, *ty, srcOpnds, parmLocator, structCopyOffset, rhsOffset); } + } else if (argExpr.GetOpCode() == OP_ireadfpoff) { + IreadFPoffNode &iread = static_cast(argExpr); + MIRStructType *ty = GetLmbcStructArgType(parent, argNo); + if (ty == nullptr) { /* param < arg */ + return; + } + symSize = GetBecommon().GetTypeSize(ty->GetTypeIndex().GetIdx()); + if (symSize <= k16ByteSize) { + SelectParmListIreadSmallAggregate(iread, *ty, srcOpnds, rhsOffset, parmLocator); + } else { + CreateCallStructMemcpyToParamReg(*ty, structCopyOffset, parmLocator, srcOpnds); + structCopyOffset += static_cast(RoundUp(symSize, kSizeOfPtr)); + } + } else if (argExpr.GetOpCode() == OP_ireadoff) { + IreadoffNode &iread = static_cast(argExpr); + MIRStructType *ty = GetLmbcStructArgType(parent, argNo); + if (ty == nullptr) { + return; + } + symSize = GetBecommon().GetTypeSize(ty->GetTypeIndex().GetIdx()); + if (symSize <= k16ByteSize) { + SelectParmListIreadSmallAggregate(iread, *ty, srcOpnds, rhsOffset, parmLocator); + } else { + CreateCallStructMemcpyToParamReg(*ty, structCopyOffset, parmLocator, srcOpnds); + structCopyOffset += static_cast(RoundUp(symSize, kSizeOfPtr)); + } } else { CHECK_FATAL(false, "NYI"); } @@ -7943,8 +7946,7 @@ size_t AArch64CGFunc::SelectParmListGetStructReturnSize(StmtNode &naryNode) { } } else if (naryNode.GetOpCode() == OP_icallproto) { IcallNode &icallProto = static_cast(naryNode); - MIRFuncType *funcTy = static_cast( - GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallProto.GetRetTyIdx())); + 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()); @@ -7954,7 +7956,7 @@ size_t AArch64CGFunc::SelectParmListGetStructReturnSize(StmtNode &naryNode) { return 0; } -void AArch64CGFunc::SelectParmListPreprocessLargeStruct(BaseNode &argExpr, int32 &structCopyOffset) { +void AArch64CGFunc::SelectParmListPreprocessLargeStruct(BaseNode &parent, BaseNode &argExpr, int32 &structCopyOffset, int32 argNo) { uint64 symSize; int32 rhsOffset = 0; if (argExpr.GetOpCode() == OP_dread) { @@ -8001,6 +8003,22 @@ void AArch64CGFunc::SelectParmListPreprocessLargeStruct(BaseNode &argExpr, int32 uint32 numMemOp = static_cast(RoundUp(symSize, kSizeOfPtr) / kSizeOfPtr); structCopyOffset += static_cast(numMemOp * kSizeOfPtr); } + } else if (argExpr.GetOpCode() == OP_ireadfpoff) { + IreadFPoffNode &ireadoff = static_cast(argExpr); + MIRStructType *ty = GetLmbcStructArgType(parent, argNo); + symSize = GetBecommon().GetTypeSize(ty->GetTypeIndex()); + if (symSize > 16 /*kParmMemcpySize*/) { +#if OLD_LMBC // TBD + MemOperand *addrOpnd0 = GenLmbcFpMemOperand(ireadoff.GetOffset(), kSizeOfPtr, RFP); + RegOperand *addrOpnd1 = &LoadIntoRegister(*addrOpnd0, PTY_i64); +#endif + RegOperand *rfp = &GetOrCreatePhysicalRegisterOperand(RFP, k64BitSize, kRegTyInt); + RegOperand *addrOpnd = &CreateRegisterOperandOfType(PTY_a64); + ImmOperand &immOpnd = CreateImmOperand(ireadoff.GetOffset(), k32BitSize, true); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_xaddrri12, *addrOpnd, *rfp, immOpnd)); + CreateCallStructParamMemcpy(nullptr, addrOpnd, static_cast(symSize), structCopyOffset, 0); + structCopyOffset += static_cast(RoundUp(symSize, kSizeOfPtr)); + } } } @@ -8032,7 +8050,7 @@ bool AArch64CGFunc::MarkParmListCall(BaseNode &expr) { return false; } -void AArch64CGFunc::SelectParmListPreprocess(const StmtNode &naryNode, size_t start, std::set &specialArgs) { +void AArch64CGFunc::SelectParmListPreprocess(StmtNode &naryNode, size_t start, std::set &specialArgs) { size_t i = start; int32 structCopyOffset = GetMaxParamStackSize() - GetStructCopySize(); for (; i < naryNode.NumOpnds(); ++i) { @@ -8045,7 +8063,7 @@ void AArch64CGFunc::SelectParmListPreprocess(const StmtNode &naryNode, size_t st if (primType != PTY_agg) { continue; } - SelectParmListPreprocessLargeStruct(*argExpr, structCopyOffset); + SelectParmListPreprocessLargeStruct(naryNode, *argExpr, structCopyOffset, i); } } @@ -8071,8 +8089,7 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo firstArgReturn = callee->IsFirstArgReturn(); } else if (naryNode.GetOpCode() == OP_icallproto) { IcallNode *icallnode = &static_cast(naryNode); - MIRFuncType *funcType = static_cast( - GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallnode->GetRetTyIdx())); + MIRFuncType *funcType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallnode->GetRetTyIdx())); firstArgReturn = funcType->FirstArgReturn(); } BB *curBBrecord = GetCurBB(); @@ -8146,7 +8163,7 @@ void AArch64CGFunc::SelectParmList(StmtNode &naryNode, ListOperand &srcOpnds, bo } /* use alloca */ if (primType == PTY_agg) { - SelectParmListForAggregate(*argExpr, srcOpnds, parmLocator, structCopyOffset); + SelectParmListForAggregate(naryNode, *argExpr, srcOpnds, parmLocator, structCopyOffset, i); continue; } ty = GlobalTables::GetTypeTable().GetTypeTable()[static_cast(primType)]; @@ -8556,56 +8573,6 @@ void AArch64CGFunc::IntrinsifyStringIndexOf(ListOperand &srcOpnds, const MIRSymb SetCurBB(*jointBB); } -/* Lmbc calls have no argument, they are all explicit iassignspoff or - blkassign. Info collected and to be emitted here */ -void AArch64CGFunc::LmbcSelectParmList(ListOperand *srcOpnds, bool isArgReturn) { - if (GetLmbcArgInfo() == nullptr) { - return; /* no arg */ - } - CHECK_FATAL(GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc, "To be called for Lmbc model only"); - MapleVector &args = GetLmbcCallArgs(); - MapleVector &types = GetLmbcCallArgTypes(); - MapleVector &offsets = GetLmbcCallArgOffsets(); - MapleVector ®s = GetLmbcCallArgNumOfRegs(); - int iCnt = 0; - int fCnt = 0; - for (size_t i = isArgReturn ? 1 : 0; i < args.size(); i++) { - RegType ty = args[i]->GetRegisterType(); - PrimType pTy = types[i]; - AArch64reg reg; - if (args[i]->IsOfIntClass() && (iCnt + regs[i]) <= static_cast(k8ByteSize)) { - reg = static_cast(R0 + iCnt++); - RegOperand *res = &GetOrCreatePhysicalRegisterOperand( - reg, GetPrimTypeSize(pTy) * kBitsPerByte, ty); - SelectCopy(*res, pTy, *args[i], pTy); - srcOpnds->PushOpnd(*res); - } else if (!args[i]->IsOfIntClass() && (fCnt + regs[i]) <= static_cast(k8ByteSize)) { - reg = static_cast(V0 + fCnt++); - RegOperand *res = &GetOrCreatePhysicalRegisterOperand( - reg, GetPrimTypeSize(pTy) * kBitsPerByte, ty); - SelectCopy(*res, pTy, *args[i], pTy); - srcOpnds->PushOpnd(*res); - } else { - uint32 pSize = GetPrimTypeSize(pTy); - Operand &memOpd = CreateMemOpnd(RSP, offsets[i], pSize); - GetCurBB()->AppendInsn(GetCG()->BuildInstruction(PickStInsn(pSize * kBitsPerByte, pTy), - *args[i], memOpd)); - } - } - /* Load x8 if 1st arg is for agg return */ - if (isArgReturn) { - AArch64reg reg = static_cast(R8); - RegOperand *res = &GetOrCreatePhysicalRegisterOperand(reg, - GetPrimTypeSize(PTY_a64) * kBitsPerByte, - kRegTyInt); - SelectCopy(*res, PTY_a64, *args[0], PTY_a64); - srcOpnds->PushOpnd(*res); - } - ResetLmbcArgInfo(); /* reset */ - ResetLmbcArgsInRegs(); - ResetLmbcTotalArgs(); -} - void AArch64CGFunc::SelectCall(CallNode &callNode) { MIRFunction *fn = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callNode.GetPUIdx()); MIRSymbol *fsym = GetFunction().GetLocalOrGlobalSymbol(fn->GetStIdx(), false); @@ -8619,18 +8586,14 @@ void AArch64CGFunc::SelectCall(CallNode &callNode) { ListOperand *srcOpnds = CreateListOpnd(*GetFuncScopeAllocator()); if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { SetLmbcCallReturnType(nullptr); - bool largeStructRet = false; if (fn->IsFirstArgReturn()) { - MIRPtrType *ptrTy = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx( - fn->GetFormalDefVec()[0].formalTyIdx)); + 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") || @@ -9551,7 +9514,11 @@ Operand *AArch64CGFunc::GetBaseReg(const AArch64SymbolAlloc &symAlloc) { } if (fsp == nullptr) { - fsp = &GetOrCreatePhysicalRegisterOperand(RFP, kSizeOfPtr * kBitsPerByte, kRegTyInt); + if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { + fsp = &GetOrCreatePhysicalRegisterOperand(RSP, kSizeOfPtr * kBitsPerByte, kRegTyInt); + } else { + fsp = &GetOrCreatePhysicalRegisterOperand(RFP, kSizeOfPtr * kBitsPerByte, kRegTyInt); + } } return fsp; } @@ -9569,20 +9536,32 @@ int32 AArch64CGFunc::GetBaseOffset(const SymbolAlloc &sa) { int32 offset = static_cast(symAlloc->GetOffset()); return offset; } else if (sgKind == kMsArgsRegPassed) { - int32 baseOffset = memLayout->GetSizeOfLocals() + symAlloc->GetOffset() + memLayout->GetSizeOfRefLocals(); + int32 baseOffset; + if (GetCG()->IsLmbc()) { + baseOffset = symAlloc->GetOffset() + memLayout->GetSizeOfRefLocals(); + } else { + baseOffset = memLayout->GetSizeOfLocals() + symAlloc->GetOffset() + + memLayout->GetSizeOfRefLocals(); + } return baseOffset + sizeofFplr; } else if (sgKind == kMsRefLocals) { int32 baseOffset = symAlloc->GetOffset() + memLayout->GetSizeOfLocals(); return baseOffset + sizeofFplr; } else if (sgKind == kMsLocals) { + if (GetCG()->IsLmbc()) { + CHECK_FATAL(false, "invalid lmbc's locals"); + } int32 baseOffset = symAlloc->GetOffset(); return baseOffset + sizeofFplr; } else if (sgKind == kMsSpillReg) { + int32 baseOffset; if (GetCG()->IsLmbc()) { - return symAlloc->GetOffset() + memLayout->SizeOfArgsToStackPass(); + baseOffset = symAlloc->GetOffset() + memLayout->SizeOfArgsRegisterPassed() + + memLayout->GetSizeOfRefLocals(); + } else { + baseOffset = symAlloc->GetOffset() + memLayout->SizeOfArgsRegisterPassed() + + memLayout->GetSizeOfLocals() + memLayout->GetSizeOfRefLocals(); } - int32 baseOffset = symAlloc->GetOffset() + memLayout->SizeOfArgsRegisterPassed() + memLayout->GetSizeOfLocals() + - memLayout->GetSizeOfRefLocals(); return baseOffset + sizeofFplr; } else if (sgKind == kMsArgsToStkPass) { /* this is for callers */ return static_cast(symAlloc->GetOffset()); @@ -10254,9 +10233,11 @@ void AArch64CGFunc::SelectCVaStart(const IntrinsiccallNode &intrnNode) { inReg++; } } +#if OLD_LMBC // TBD if (GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { stkSize += (inReg * k8ByteSize); } +#endif 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 6b704c77cb6251f1006999051ebed5a74c6a8c76..6cbf05629d17833012ee4914951ddd904c6260cc 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 @@ -455,14 +455,18 @@ void GraphColorRegAllocator::CalculatePriority(LiveRange &lr) const { auto *a64CGFunc = static_cast(cgFunc); CG *cg = a64CGFunc->GetCG(); - if (cg->GetRematLevel() >= rematConst && lr.IsRematerializable(*a64CGFunc, rematConst)) { - lr.SetRematLevel(rematConst); - } else if (cg->GetRematLevel() >= rematAddr && lr.IsRematerializable(*a64CGFunc, rematAddr)) { - lr.SetRematLevel(rematAddr); - } else if (cg->GetRematLevel() >= rematDreadLocal && lr.IsRematerializable(*a64CGFunc, rematDreadLocal)) { - lr.SetRematLevel(rematDreadLocal); - } else if (cg->GetRematLevel() >= rematDreadGlobal && lr.IsRematerializable(*a64CGFunc, rematDreadGlobal)) { - lr.SetRematLevel(rematDreadGlobal); + if (cgFunc->GetCG()->IsLmbc()) { + lr.SetRematLevel(rematOff); + } else { + if (cg->GetRematLevel() >= rematConst && lr.IsRematerializable(*a64CGFunc, rematConst)) { + lr.SetRematLevel(rematConst); + } else if (cg->GetRematLevel() >= rematAddr && lr.IsRematerializable(*a64CGFunc, rematAddr)) { + lr.SetRematLevel(rematAddr); + } else if (cg->GetRematLevel() >= rematDreadLocal && lr.IsRematerializable(*a64CGFunc, rematDreadLocal)) { + lr.SetRematLevel(rematDreadLocal); + } else if (cg->GetRematLevel() >= rematDreadGlobal && lr.IsRematerializable(*a64CGFunc, rematDreadGlobal)) { + lr.SetRematLevel(rematDreadGlobal); + } } auto calculatePriorityFunc = [&lr, &bbNum, &numDefs, &numUses, &pri, this] (uint32 bbID) { @@ -4979,7 +4983,7 @@ bool GraphColorRegAllocator::AllocateRegisters() { MarkCalleeSaveRegs(); - if (!seenFP) { + if (seenFP == false) { cgFunc->UnsetSeenFP(); } if (GCRA_DUMP) { 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 003c9eda0cbeb69f29e535fefb147efd6f1624df..1d5b125c948145be545ab53ea5f93ea3e21961d8 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_ebo.cpp @@ -1016,7 +1016,7 @@ bool AArch64Ebo::CombineMultiplyNeg(Insn *insn, OpndInfo *opndInfo, bool is64bit return false; } -bool AArch64Ebo::CombineLsrAnd(Insn &insn, const OpndInfo &opndInfo, bool is64bits, bool isFp) const { +bool AArch64Ebo::CombineLsrAnd(Insn &insn, const OpndInfo &opndInfo, bool is64bits, bool isFp) { if (opndInfo.insn == nullptr) { return false; } @@ -1058,6 +1058,57 @@ bool AArch64Ebo::CombineLsrAnd(Insn &insn, const OpndInfo &opndInfo, bool is64bi return false; } +/* + * extension dest, src0 + * and dest, dest, 0xff or 0xffff + * ===> if extension is >= imm then can eliminate extension + * + * and dst1, src0, imm1 + * and dst2, dst1, imm2 where imm2 is 0xff or 0xffff + * ===> and dst2, src0, imm1 if imm1 <= imm2 + */ +bool AArch64Ebo::CombineExtAnd(Insn &insn, const OpndInfo &opndInfo, bool is64bits, bool isFp, int64 immVal) { + if (isFp || opndInfo.insn == nullptr || !cgFunc->GetMirModule().IsCModule()) { + return false; + } + Insn *prevInsn = opndInfo.insn; + InsnInfo *insnInfo = opndInfo.insnInfo; + if (insnInfo == nullptr) { + return false; + } + CHECK_NULL_FATAL(insnInfo); + MOperator opc1 = prevInsn->GetMachineOpcode(); + if (((immVal == 0xff) && + (opc1 >= MOP_xsxtb32) && (opc1 <= MOP_xuxtw64)) || + ((immVal == 0xffff) && + (opc1 == MOP_xsxth32 || opc1 == MOP_xsxth64 || opc1 == MOP_xsxtw64 || + opc1 == MOP_xsxth32 || opc1 == MOP_xsxtw64))) { + /* don't use register if it was redefined. */ + OpndInfo *opndInfo1 = insnInfo->origOpnd[kInsnSecondOpnd]; + if ((opndInfo1 != nullptr) && opndInfo1->redefined) { + return false; + } + Operand &opnd1 = prevInsn->GetOperand(kInsnSecondOpnd); + insn.SetOperand(kInsnSecondOpnd, opnd1); + return true; + } + if ((immVal == 0xff || immVal == 0xffff) && (opc1 == MOP_wandrri12 || opc1 == MOP_xandrri13)) { + OpndInfo *opndInfo1 = insnInfo->origOpnd[kInsnSecondOpnd]; + if ((opndInfo1 != nullptr) && opndInfo1->redefined) { + return false; + } + int64 prevImmVal = static_cast(prevInsn->GetOperand(kInsnThirdOpnd)).GetValue(); + if (prevImmVal > immVal) { + return false; + } + Operand &opnd1 = prevInsn->GetOperand(kInsnSecondOpnd); + insn.SetOperand(kInsnSecondOpnd, opnd1); + Operand &opnd2 = prevInsn->GetOperand(kInsnThirdOpnd); + insn.SetOperand(kInsnThirdOpnd, opnd2); + } + return false; +} + /* Do some special pattern */ bool AArch64Ebo::SpecialSequence(Insn &insn, const MapleVector &origInfos) { MOperator opCode = insn.GetMachineOpcode(); @@ -1104,10 +1155,12 @@ bool AArch64Ebo::SpecialSequence(Insn &insn, const MapleVector &origI * ===> ldrb x1, [] ===> ldrb x1, [] ===> ldrsb x1, [] ===> no change * mov x1, x1 mov x1, x1 mov x1, x1 */ - case MOP_wandrri12: { + case MOP_wandrri12: + case MOP_xandrri13: { + bool is64Bits = (opCode == MOP_xandrri13); bool doAndOpt = false; if (static_cast(insn.GetOperand(kInsnThirdOpnd)).GetValue() == 0xff) { - doAndOpt = CombineExtensionAndLoad(&insn, origInfos, AND, false); + doAndOpt = CombineExtensionAndLoad(&insn, origInfos, AND, is64Bits); } if (doAndOpt) { return doAndOpt; @@ -1122,29 +1175,12 @@ bool AArch64Ebo::SpecialSequence(Insn &insn, const MapleVector &origI (static_cast(immValue) & (static_cast(immValue) + 1)) == 0) { /* immValue is (1 << n - 1) */ OpndInfo *opndInfo = origInfos.at(kInsnSecondOpnd); - return CombineLsrAnd(insn, *opndInfo, false, false); + return CombineLsrAnd(insn, *opndInfo, is64Bits, false); } - break; - } - case MOP_xandrri13: { - bool doAndOpt = false; - if (static_cast(insn.GetOperand(kInsnThirdOpnd)).GetValue() == 0xff) { - doAndOpt = CombineExtensionAndLoad(&insn, origInfos, AND, true); - } - if (doAndOpt) { - return doAndOpt; - } - /* - * lsr d0, d1, #6 - * and d0, d0, #1 - * ===> ubfx d0, d1, #6, #1 - */ - int64 immValue = static_cast(insn.GetOperand(kInsnThirdOpnd)).GetValue(); - if (!beforeRegAlloc && immValue != 0 && + if (beforeRegAlloc && immValue != 0 && (static_cast(immValue) & (static_cast(immValue) + 1)) == 0) { - /* immValue is (1 << n - 1) */ OpndInfo *opndInfo = origInfos.at(kInsnSecondOpnd); - return CombineLsrAnd(insn, *opndInfo, true, false); + return CombineExtAnd(insn, *opndInfo, is64Bits, false, immValue); } break; } 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 3d0fbd96d688818dfc83ed0844aa5a7e276a5e0f..d9fa8fb2f0db63e9e91f7e40b92b4894dcf1d674 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_memlayout.cpp @@ -58,7 +58,9 @@ uint32 AArch64MemLayout::ComputeStackSpaceRequirementForCall(StmtNode &stmt, in ty = GlobalTables::GetTypeTable().GetTypeTable()[static_cast(opnd->GetPrimType())]; } else { Opcode opndOpcode = opnd->GetOpCode(); - ASSERT(opndOpcode == OP_dread || opndOpcode == OP_iread, "opndOpcode should be OP_dread or OP_iread"); + if (be.GetMIRModule().GetFlavor() != kFlavorLmbc) { + ASSERT(opndOpcode == OP_dread || opndOpcode == OP_iread, "opndOpcode should be OP_dread or OP_iread"); + } if (opndOpcode == OP_dread) { DreadNode *dread = static_cast(opnd); MIRSymbol *sym = be.GetMIRModule().CurFunction()->GetLocalOrGlobalSymbol(dread->GetStIdx()); @@ -72,8 +74,7 @@ uint32 AArch64MemLayout::ComputeStackSpaceRequirementForCall(StmtNode &stmt, in ty = static_cast(ty)->GetFieldType(dread->GetFieldID()); } } - } else { - /* OP_iread */ + } else if (opndOpcode == OP_iread) { IreadNode *iread = static_cast(opnd); ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(iread->GetTyIdx()); ASSERT(ty->GetKind() == kTypePointer, "expect pointer"); @@ -87,6 +88,11 @@ uint32 AArch64MemLayout::ComputeStackSpaceRequirementForCall(StmtNode &stmt, in ty = static_cast(ty)->GetFieldType(iread->GetFieldID()); } } + } else if ((opndOpcode == OP_ireadfpoff || opndOpcode == OP_ireadoff || opndOpcode == OP_dreadoff) && opnd->GetPrimType() == PTY_agg) { + ty = static_cast(cgFunc)->GetLmbcStructArgType(stmt, i); + } + if (ty == nullptr) { /* type mismatch */ + continue; } } CCLocInfo ploc; @@ -190,6 +196,7 @@ void AArch64MemLayout::LayoutVarargParams() { } void AArch64MemLayout::LayoutFormalParams() { +#if OLD_LMBC // TBD bool isLmbc = (be.GetMIRModule().GetFlavor() == kFlavorLmbc); if (isLmbc && mirFunction->GetFormalCount() == 0) { /* @@ -201,6 +208,7 @@ void AArch64MemLayout::LayoutFormalParams() { segArgsRegPassed.SetSize(mirFunction->GetOutParmSize()); return; } +#endif AArch64CallConvImpl parmLocator(be); CCLocInfo ploc; @@ -255,8 +263,10 @@ void AArch64MemLayout::LayoutFormalParams() { segArgsRegPassed.SetSize(static_cast(RoundUp(segArgsRegPassed.GetSize(), align))); symLoc->SetOffset(segArgsRegPassed.GetSize()); segArgsRegPassed.SetSize(segArgsRegPassed.GetSize() + size); +#if OLD_LMBC // TBD } else if (isLmbc) { segArgsRegPassed.SetSize(segArgsRegPassed.GetSize() + k8ByteSize); +#endif } } else { /* stack */ uint32 size; @@ -371,11 +381,15 @@ void AArch64MemLayout::LayoutReturnRef(std::vector &returnDelays, symLoc->SetOffset(segRefLocals.GetSize()); segRefLocals.SetSize(segRefLocals.GetSize() + be.GetTypeSize(tyIdx)); } +#if OLD_LMBC // TBD if (be.GetMIRModule().GetFlavor() == kFlavorLmbc) { segArgsToStkPass.SetSize(mirFunction->GetOutParmSize() + kDivide2 * k8ByteSize); } else { segArgsToStkPass.SetSize(FindLargestActualArea(structCopySize)); } +#else + segArgsToStkPass.SetSize(FindLargestActualArea(structCopySize)); +#endif maxParmStackSize = static_cast(segArgsToStkPass.GetSize()); if (Globals::GetInstance()->GetOptimLevel() == 0) { AssignSpillLocationsToPseudoRegisters(); 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 c305f3acab3929d45aa7a73abba88b9073a28c20..73686edf1c7075c2833e6078d01be02a868d4542 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_proepilog.cpp @@ -344,7 +344,9 @@ void AArch64GenProEpilog::GenStackGuard(BB &bb) { cgFunc.GetCurBB()->AppendInsn(insn); uint64 vArea = 0; - if (cgFunc.GetMirModule().IsCModule() && cgFunc.GetFunction().GetAttr(FUNCATTR_varargs)) { + if (cgFunc.GetMirModule().IsCModule() && + cgFunc.GetFunction().GetAttr(FUNCATTR_varargs) && + cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { AArch64MemLayout *ml = static_cast(cgFunc.GetMemlayout()); if (ml->GetSizeOfGRSaveArea() > 0) { vArea += RoundUp(ml->GetSizeOfGRSaveArea(), kAarch64StackPtrAlignment); @@ -401,7 +403,9 @@ BB &AArch64GenProEpilog::GenStackGuardCheckInsn(BB &bb) { cgFunc.GetCurBB()->AppendInsn(insn); uint64 vArea = 0; - if (cgFunc.GetMirModule().IsCModule() && cgFunc.GetFunction().GetAttr(FUNCATTR_varargs)) { + if (cgFunc.GetMirModule().IsCModule() && + cgFunc.GetFunction().GetAttr(FUNCATTR_varargs) && + cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { AArch64MemLayout *ml = static_cast(cgFunc.GetMemlayout()); if (ml->GetSizeOfGRSaveArea() > 0) { vArea += RoundUp(ml->GetSizeOfGRSaveArea(), kAarch64StackPtrAlignment); @@ -1115,9 +1119,11 @@ void AArch64GenProEpilog::AppendInstructionAllocateCallFrameDebug(AArch64reg reg ipoint = cgFunc.GetCurBB()->GetLastInsn(); cfiOffset = stackFrameSize; (void)InsertCFIDefCfaOffset(cfiOffset, *ipoint); +#if OLD_LMBC //TBD if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { argsToStkPassSize -= (kDivide2 * k8ByteSize); } +#endif ipoint = &CreateAndAppendInstructionForAllocateCallFrame(argsToStkPassSize, reg0, reg1, rty); CHECK_FATAL(ipoint != nullptr, "ipoint should not be nullptr at this point"); cfiOffset = GetOffsetFromCFA(); @@ -1226,7 +1232,7 @@ void AArch64GenProEpilog::GeneratePushRegs() { } else { immOpnd = &aarchCGFunc.CreateImmOperand(argsToStkPassSize, k32BitSize, true); } - if (!isLmbc || cgFunc.SeenFP() || cgFunc.GetFunction().GetAttr(FUNCATTR_varargs)) { + if (isLmbc == false || cgFunc.SeenFP() || cgFunc.GetFunction().GetAttr(FUNCATTR_varargs)) { aarchCGFunc.SelectAdd(fpOpnd, spOpnd, *immOpnd, PTY_u64); } cgFunc.GetCurBB()->GetLastInsn()->SetFrameDef(true); @@ -1256,8 +1262,15 @@ void AArch64GenProEpilog::GeneratePushRegs() { AArch64MemLayout *memLayout = static_cast(cgFunc.GetMemlayout()); int32 offset; if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { - offset = static_cast((memLayout->RealStackFrameSize() - - aarchCGFunc.SizeOfCalleeSaved()) - memLayout->GetSizeOfLocals()); +#if OLD_LMBC // TBD + offset = static_cast(memLayout->RealStackFrameSize() - + aarchCGFunc.SizeOfCalleeSaved() - memLayout->GetSizeOfLocals()); +#else + offset = static_cast(memLayout->RealStackFrameSize() - + (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen)/* FP/LR */) - + memLayout->GetSizeOfLocals() - + memLayout->SizeOfArgsToStackPass()); +#endif } else { offset = static_cast((memLayout->RealStackFrameSize() - (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen))) - memLayout->SizeOfArgsToStackPass()); /* for FP/LR */ @@ -1267,7 +1280,9 @@ void AArch64GenProEpilog::GeneratePushRegs() { offset -= kAarch64StackPtrAlignmentInt; } - if (cgFunc.GetMirModule().IsCModule() && cgFunc.GetFunction().GetAttr(FUNCATTR_varargs)) { + if (cgFunc.GetMirModule().IsCModule() && + cgFunc.GetFunction().GetAttr(FUNCATTR_varargs) && + cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { /* GR/VR save areas are above the callee save area */ AArch64MemLayout *ml = static_cast(cgFunc.GetMemlayout()); auto saveareasize = static_cast(RoundUp(ml->GetSizeOfGRSaveArea(), kSizeOfPtr * k2BitSize) + @@ -1322,18 +1337,22 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { } uint32 dataSizeBits = size * kBitsPerByte; uint32 offset; +#if OLD_LMBC // TBD if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { +#endif offset = static_cast(memlayout->GetGRSaveAreaBaseLoc()); /* SP reference */ if ((memlayout->GetSizeOfGRSaveArea() % kAarch64StackPtrAlignment) > 0) { offset += size; /* End of area should be aligned. Hole between VR and GR area */ } +#if OLD_LMBC // TBD } else { offset = (UINT32_MAX - memlayout->GetSizeOfGRSaveArea()) + 1; /* FP reference */ if ((memlayout->GetSizeOfGRSaveArea() % kAarch64StackPtrAlignment) > 0) { offset -= size; } } - uint32 grSize = (UINT32_MAX - offset) + 1; + uint32 grSize = -offset; +#endif 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++) { @@ -1344,11 +1363,15 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { } } Operand *stackLoc; +#if OLD_LMBC // TBD if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { +#endif stackLoc = &aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); +#if OLD_LMBC // TBD } else { stackLoc = aarchCGFunc.GenLmbcFpMemOperand(offset, size); } +#endif RegOperand ® = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(static_cast(i), k64BitSize, kRegTyInt); Insn &inst = @@ -1357,11 +1380,15 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { offset += size; } if (!CGOptions::UseGeneralRegOnly()) { +#if OLD_LMBC // TBD if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { +#endif offset = static_cast(memlayout->GetVRSaveAreaBaseLoc()); +#if OLD_LMBC // TBD } else { offset = (UINT32_MAX - (memlayout->GetSizeOfVRSaveArea() + grSize)) + 1; } +#endif 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++) { @@ -1372,11 +1399,15 @@ void AArch64GenProEpilog::GeneratePushUnnamedVarargRegs() { } } Operand *stackLoc; +#if OLD_LMBC // TBD if (cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { +#endif stackLoc = &aarchCGFunc.CreateStkTopOpnd(offset + tmpOffset, dataSizeBits); +#if OLD_LMBC // TBD } else { stackLoc = aarchCGFunc.GenLmbcFpMemOperand(offset, size); } +#endif RegOperand ® = aarchCGFunc.GetOrCreatePhysicalRegisterOperand(static_cast(i), k64BitSize, kRegTyFloat); Insn &inst = @@ -1681,10 +1712,14 @@ 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 OLD_LMBC // TBD bool isLmbc = (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc); +#else + bool isLmbc = false; +#endif if (cgFunc.HasVLAOrAlloca() || argsToStkPassSize == 0 || isLmbc) { int lmbcOffset = 0; - if (!isLmbc) { + if (isLmbc == false) { stackFrameSize -= argsToStkPassSize; } else { lmbcOffset = argsToStkPassSize - (kDivide2 * k8ByteSize); @@ -1768,8 +1803,15 @@ void AArch64GenProEpilog::GeneratePopRegs() { AArch64MemLayout *memLayout = static_cast(cgFunc.GetMemlayout()); int32 offset; if (cgFunc.GetMirModule().GetFlavor() == MIRFlavor::kFlavorLmbc) { - offset = static_cast((memLayout->RealStackFrameSize() - - aarchCGFunc.SizeOfCalleeSaved()) - memLayout->GetSizeOfLocals()); +#if OLD_LMBC // TBD + offset = static_cast(memLayout->RealStackFrameSize() - + aarchCGFunc.SizeOfCalleeSaved() - memLayout->GetSizeOfLocals()); +#else + offset = static_cast(memLayout->RealStackFrameSize() - + (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen)/* FP/LR */) - + memLayout->GetSizeOfLocals() - + memLayout->SizeOfArgsToStackPass()); +#endif } else { offset = static_cast((static_cast(cgFunc.GetMemlayout())->RealStackFrameSize() - (aarchCGFunc.SizeOfCalleeSaved() - (kDivide2 * kIntregBytelen))) - /* for FP/LR */ @@ -1780,7 +1822,8 @@ void AArch64GenProEpilog::GeneratePopRegs() { offset -= kAarch64StackPtrAlignmentInt; } - if (cgFunc.GetMirModule().IsCModule() && cgFunc.GetFunction().GetAttr(FUNCATTR_varargs)) { + if (cgFunc.GetMirModule().IsCModule() && cgFunc.GetFunction().GetAttr(FUNCATTR_varargs) && + cgFunc.GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) { /* GR/VR save areas are above the callee save area */ AArch64MemLayout *ml = static_cast(cgFunc.GetMemlayout()); auto saveareasize = static_cast(RoundUp(ml->GetSizeOfGRSaveArea(), kSizeOfPtr * k2BitSize) + diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_prop.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_prop.cpp index 4ad05acfacefd6097410b8694a3650ced23c1a50..4fba8ed8fc420e1b75e4902a3cfd944d2ebcf384 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_prop.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_prop.cpp @@ -1491,6 +1491,9 @@ bool ExtendMovPattern::CheckSrcReg(regno_t srcRegNo, uint32 validNum) { bool ExtendMovPattern::BitNotAffected(const Insn &insn, uint32 validNum) { RegOperand &firstOpnd = static_cast(insn.GetOperand(kInsnFirstOpnd)); + if (firstOpnd.IsPhysicalRegister()) { + return false; + } RegOperand &secondOpnd = static_cast(insn.GetOperand(kInsnSecondOpnd)); regno_t desRegNo = firstOpnd.GetRegisterNumber(); regno_t srcRegNo = secondOpnd.GetRegisterNumber(); 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 d3cdffa29856b121accf8b929c3def17176255ee..66cf39e832d1b52045583af411684f08e7ee9821 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_reaching.cpp @@ -464,6 +464,9 @@ std::vector AArch64ReachingDefinition::FindMemDefBetweenInsn( ASSERT(memOpnd.GetOffsetImmediate() != nullptr, "offset must be a immediate value"); int64 memOffset = memOpnd.GetOffsetImmediate()->GetOffsetValue(); + if (memOffset < 0) { + memOffset = stackSize + memOffset; + } if ((offset == memOffset) || (insn->IsStorePair() && offset == memOffset + GetEachMemSizeOfPair(insn->GetMachineOpcode()))) { defInsnVec.emplace_back(insn); @@ -516,6 +519,9 @@ void AArch64ReachingDefinition::FindMemDefInBB(uint32 offset, BB &bb, InsnSet &d ASSERT(memOpnd.GetOffsetImmediate() != nullptr, "offset must be a immediate value"); int64 memOffset = memOpnd.GetOffsetImmediate()->GetOffsetValue(); + if (memOffset < 0) { + memOffset = stackSize + memOffset; + } if (offset == memOffset) { (void)defInsnSet.insert(insn); break; @@ -1001,6 +1007,9 @@ bool AArch64ReachingDefinition::FindMemUseBetweenInsn(uint32 offset, Insn *start ASSERT(memOpnd.GetIndexRegister() == nullptr, "offset must not be Register for frame MemOperand"); ASSERT(memOpnd.GetOffsetImmediate() != nullptr, "offset must be a immediate value"); int64 memOffset = memOpnd.GetOffsetImmediate()->GetValue(); + if (memOffset < 0) { + memOffset = stackSize + memOffset; + } if (insn->IsStore() || insn->IsPseudoInstruction()) { if (memOffset == offset) { @@ -1050,6 +1059,9 @@ InsnSet AArch64ReachingDefinition::FindDefForMemOpnd(Insn &insn, uint32 indexOrO } ASSERT(memOpnd.GetOffsetImmediate() != nullptr, "offset must be a immediate value"); memOffSet = memOpnd.GetOffsetImmediate()->GetOffsetValue(); + if (memOffSet < 0) { + memOffSet = stackSize + memOffSet; + } } else { memOffSet = indexOrOffset; } @@ -1101,6 +1113,9 @@ InsnSet AArch64ReachingDefinition::FindUseForMemOpnd(Insn &insn, uint8 index, bo ASSERT(memOpnd.GetIndexRegister() == nullptr, "IndexRegister no nullptr"); ASSERT(memOpnd.GetOffsetImmediate() != nullptr, "offset must be a immediate value"); int64 memOffSet = memOpnd.GetOffsetImmediate()->GetOffsetValue(); + if (memOffSet < 0) { + memOffSet = stackSize + memOffSet; + } if (secondMem) { ASSERT(insn.IsStorePair(), "second MemOperand can only be defined in stp insn"); memOffSet += GetEachMemSizeOfPair(insn.GetMachineOpcode()); @@ -1214,6 +1229,9 @@ void AArch64ReachingDefinition::InitInfoForMemOperand(Insn &insn, Operand &opnd, CHECK_FATAL(index == nullptr, "Existing [x29 + index] Memory Address"); ASSERT(memOpnd.GetOffsetImmediate(), "offset must be a immediate value"); int64 offsetVal = memOpnd.GetOffsetImmediate()->GetOffsetValue(); + if (offsetVal < 0) { + offsetVal = stackSize + offsetVal; + } if ((offsetVal % kMemZoomSize) != 0) { SetAnalysisMode(kRDRegAnalysis); } diff --git a/src/mapleall/maple_be/src/cg/cfgo.cpp b/src/mapleall/maple_be/src/cg/cfgo.cpp index 4fce8865a7f01570d5b53cf2dba6570dcdf32de8..651204ccb8d4eb9e86dd6d417164f377df7c4782 100644 --- a/src/mapleall/maple_be/src/cg/cfgo.cpp +++ b/src/mapleall/maple_be/src/cg/cfgo.cpp @@ -42,7 +42,11 @@ void CFGOptimizer::InitOptimizePatterns() { diffPassPatterns.emplace_back(memPool->New(*cgFunc)); } diffPassPatterns.emplace_back(memPool->New(*cgFunc)); - diffPassPatterns.emplace_back(memPool->New(*cgFunc)); + FlipBRPattern *brOpt = memPool->New(*cgFunc); + if (GetPhase() == CfgoPostRegAlloc) { + brOpt->SetPhase(CfgoPostRegAlloc); + } + diffPassPatterns.emplace_back(brOpt); diffPassPatterns.emplace_back(memPool->New(*cgFunc)); diffPassPatterns.emplace_back(memPool->New(*cgFunc)); diffPassPatterns.emplace_back(memPool->New(*cgFunc)); @@ -548,7 +552,13 @@ void FlipBRPattern::RelocateThrowBB(BB &curBB) { * ftBB * targetBB * - * 2. relocate throw BB in RelocateThrowBB() + * loopHeaderBB: loopHeaderBB: + * ... ... + * cond_br loopExit: cond_br loopHeaderBB + * ftBB: ftBB: + * goto loopHeaderBB: goto loopExit + * + * 3. relocate throw BB in RelocateThrowBB() */ bool FlipBRPattern::Optimize(BB &curBB) { if (curBB.GetKind() == BB::kBBIf && !curBB.IsEmpty()) { @@ -648,6 +658,50 @@ bool FlipBRPattern::Optimize(BB &curBB) { ftBB->RemoveInsn(*brInsn); ftBB->SetKind(BB::kBBFallthru); } + } else if (GetPhase() == CfgoPostRegAlloc && ftBB->GetKind() == BB::kBBGoto && + curBB.GetLoop() != nullptr && curBB.GetLoop() == ftBB->GetLoop() && + ftBB->IsSoloGoto() && + ftBB->GetLoop()->GetHeader() == *(ftBB->GetSuccsBegin()) && + curBB.GetLoop()->IsBBLoopMember((curBB.GetSuccs().front() == ftBB) ? + curBB.GetSuccs().back() : curBB.GetSuccs().front()) == false) { + Insn *curBBBranchInsn = nullptr; + for (curBBBranchInsn = curBB.GetLastInsn(); curBBBranchInsn != nullptr; + curBBBranchInsn = curBBBranchInsn->GetPrev()) { + if (curBBBranchInsn->IsBranch()) { + break; + } + } + ASSERT(curBBBranchInsn != nullptr, "FlipBRPattern: curBB has no branch"); + Insn *brInsn = nullptr; + for (brInsn = ftBB->GetLastInsn(); brInsn != nullptr; brInsn = brInsn->GetPrev()) { + if (brInsn->IsGoto()) { + break; + } + } + ASSERT(brInsn != nullptr, "FlipBRPattern: ftBB has no branch"); + uint32 condTargetIdx = curBBBranchInsn->GetJumpTargetIdx(); + LabelOperand &condTarget = static_cast(curBBBranchInsn->GetOperand(condTargetIdx)); + MOperator mOp = curBBBranchInsn->FlipConditionOp(curBBBranchInsn->GetMachineOpcode(), condTargetIdx); + if (mOp == 0) { + return false; + } + uint32 gotoTargetIdx = brInsn->GetJumpTargetIdx(); + LabelOperand &gotoTarget = static_cast(brInsn->GetOperand(gotoTargetIdx)); + curBBBranchInsn->SetMOP(mOp); + curBBBranchInsn->SetOperand(condTargetIdx, gotoTarget); + brInsn->SetOperand(gotoTargetIdx, condTarget); + auto it = ftBB->GetSuccsBegin(); + BB *loopHeadBB = *it; + + curBB.RemoveSuccs(*brBB); + brBB->RemovePreds(curBB); + ftBB->RemoveSuccs(*loopHeadBB); + loopHeadBB->RemovePreds(*ftBB); + + curBB.PushBackSuccs(*loopHeadBB); + loopHeadBB->PushBackPreds(curBB); + ftBB->PushBackSuccs(*brBB); + brBB->PushBackPreds(*ftBB); } else { RelocateThrowBB(curBB); } @@ -848,6 +902,10 @@ bool DuplicateBBPattern::Optimize(BB &curBB) { /* === new pm === */ bool CgCfgo::PhaseRun(maplebe::CGFunc &f) { CFGOptimizer *cfgOptimizer = GetPhaseAllocator()->New(f, *GetPhaseMemPool()); + if (f.IsAfterRegAlloc()) { + (void)GetAnalysisInfoHook()->ForceRunAnalysisPhase, CGFunc>(&CgLoopAnalysis::id, f); + cfgOptimizer->SetPhase(CfgoPostRegAlloc); + } const std::string &funcClass = f.GetFunction().GetBaseClassName(); const std::string &funcName = f.GetFunction().GetBaseFuncName(); const std::string &name = funcClass + funcName; @@ -855,6 +913,9 @@ bool CgCfgo::PhaseRun(maplebe::CGFunc &f) { DotGenerator::GenerateDot("before-cfgo", f, f.GetMirModule()); } cfgOptimizer->Run(name); + if (f.IsAfterRegAlloc()) { + GetAnalysisInfoHook()->ForceEraseAnalysisPhase(f.GetUniqueID(), &CgLoopAnalysis::id); + } if (CFGO_DUMP_NEWPM) { DotGenerator::GenerateDot("after-cfgo", f, f.GetMirModule()); } diff --git a/src/mapleall/maple_be/src/cg/cgbb.cpp b/src/mapleall/maple_be/src/cg/cgbb.cpp index 502983b519e5c61e91cf0bbaa3bf7a1194ec73be..d8b5e862787bc9d5af187b7a01e8273b7eea6fb0 100644 --- a/src/mapleall/maple_be/src/cg/cgbb.cpp +++ b/src/mapleall/maple_be/src/cg/cgbb.cpp @@ -525,6 +525,7 @@ void Bfs::ComputeBlockOrder() { done = true; } else { LogInfo::MapleLogger() << "Error: RA BFS loop " << sortedCnt << " in func " << cgfunc->GetName() << "\n"; + CHECK_FATAL(false, ""); } } sortedCnt = sortedBBs.size(); diff --git a/src/mapleall/maple_be/src/cg/cgfunc.cpp b/src/mapleall/maple_be/src/cg/cgfunc.cpp index 9676b442fd9b7a614aaa6b154047bc2cf35946fe..6529e6a874e315aa279140f5e90e843dc4612a2c 100644 --- a/src/mapleall/maple_be/src/cg/cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/cgfunc.cpp @@ -1565,16 +1565,16 @@ void CGFunc::CreateLmbcFormalParamInfo() { PrimType primType; uint32 offset; uint32 typeSize; - MIRFunction &lmbcFunc = GetFunction(); - if (lmbcFunc.GetFormalCount() > 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 < lmbcFunc.GetFormalCount(); ++idx) { - MIRSymbol *sym = lmbcFunc.GetFormal(idx); + for (size_t idx = 0; idx < func.GetFormalCount(); ++idx) { + MIRSymbol *sym = func.GetFormal(idx); MIRType *type; TyIdx tyIdx; if (sym) { - tyIdx = lmbcFunc.GetFormalDefVec()[idx].formalTyIdx; + tyIdx = func.GetFormalDefVec()[idx].formalTyIdx; type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx); } else { FormalDef vec = const_cast(GetBecommon().GetMIRModule().CurFunction())->GetFormalDefAt(idx); @@ -1587,7 +1587,7 @@ void CGFunc::CreateLmbcFormalParamInfo() { stackOffset += (typeSize + 7) & (-8); LmbcFormalParamInfo *info = GetMemoryPool()->New(primType, offset, typeSize); lmbcParamVec.push_back(info); - if (idx == 0 && lmbcFunc.IsFirstArgReturn()) { + if (idx == 0 && func.IsFirstArgReturn()) { info->SetIsReturn(); } if (type->GetKind() == kTypeStruct) { @@ -1604,7 +1604,7 @@ void CGFunc::CreateLmbcFormalParamInfo() { } } else { /* No aggregate pass by value here */ - for (StmtNode *stmt = lmbcFunc.GetBody()->GetFirst(); stmt != nullptr; stmt = stmt->GetNext()) { + for (StmtNode *stmt = func.GetBody()->GetFirst(); stmt != nullptr; stmt = stmt->GetNext()) { if (stmt == nullptr) { break; } @@ -1637,7 +1637,7 @@ void CGFunc::CreateLmbcFormalParamInfo() { ); /* When a scalar param address is taken, its regassign is not in the 1st block */ - for (StmtNode *stmt = lmbcFunc.GetBody()->GetFirst(); stmt != nullptr; stmt = stmt->GetNext()) { + for (StmtNode *stmt = func.GetBody()->GetFirst(); stmt != nullptr; stmt = stmt->GetNext()) { if (stmt == nullptr) { break; } @@ -1656,8 +1656,7 @@ void CGFunc::CreateLmbcFormalParamInfo() { if (ireadNode->GetOffset() < 0) { continue; } - LmbcFormalParamInfo *info = GetLmbcFormalParamInfo(static_cast(ireadNode->GetOffset())); - ASSERT_NOT_NULL(info); + LmbcFormalParamInfo *info = GetLmbcFormalParamInfo(ireadNode->GetOffset()); info->SetHasRegassign(); } @@ -2033,7 +2032,8 @@ void CGFunc::HandleFunction() { /* select instruction */ GenerateInstruction(); /* merge multi return */ - if (!func.GetModule()->IsCModule() || CGOptions::DoRetMerge() || CGOptions::OptimizeForSize()) { + if (!func.GetModule()->IsCModule() || (func.GetModule()->IsCModule() && (NumBBs() < kNumBBOptReturn)) || + CGOptions::DoRetMerge() || CGOptions::OptimizeForSize()) { MergeReturn(); } if (func.IsJava()) { diff --git a/src/mapleall/maple_be/src/cg/emit.cpp b/src/mapleall/maple_be/src/cg/emit.cpp index f4023e2d37371259b012f7d9d65088be2c4ffc12..7789f53216340b84ed92aa1867d99d6394a7d063 100644 --- a/src/mapleall/maple_be/src/cg/emit.cpp +++ b/src/mapleall/maple_be/src/cg/emit.cpp @@ -2170,9 +2170,9 @@ void Emitter::EmitGlobalVar(const MIRSymbol &globalVar) { void Emitter::EmitGlobalVars(std::vector> &globalVars) { if (GetCG()->IsLmbc() && GetCG()->GetGP() != nullptr) { - (void)Emit(asmInfo->GetLocal()).Emit("\t").Emit(GetCG()->GetGP()->GetName()).Emit("\n"); - (void)Emit(asmInfo->GetComm()).Emit("\t").Emit(GetCG()->GetGP()->GetName()); - (void)Emit(", ").Emit(GetCG()->GetMIRModule()->GetGlobalMemSize()).Emit(", ").Emit("8\n"); + 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()) { diff --git a/src/mapleall/maple_be/src/cg/loop.cpp b/src/mapleall/maple_be/src/cg/loop.cpp index 71fb9e8edb9f3f32f6119ce943ff5228a909479b..d37a7e0dfdc780718f44446d66ef42a777941ea2 100644 --- a/src/mapleall/maple_be/src/cg/loop.cpp +++ b/src/mapleall/maple_be/src/cg/loop.cpp @@ -161,6 +161,10 @@ void CGFuncLoops::PrintLoops(const CGFuncLoops &funcLoop) const { } } +bool CGFuncLoops::IsBBLoopMember(const BB *bb) const { + return (*(std::find(loopMembers.begin(), loopMembers.end(), bb)) == bb); +} + // partial loop body found with formLoop is NOT really needed in down stream // It should be simplied later void LoopFinder::formLoop(BB* headBB, BB* backBB) { diff --git a/src/mapleall/maple_be/src/cg/reaching.cpp b/src/mapleall/maple_be/src/cg/reaching.cpp index 77fa1568452e7b7366b21fe7b95ff5aa4dc2b44a..960d820e34d5d03ffc67e23dd0f8805bb5b02ec3 100644 --- a/src/mapleall/maple_be/src/cg/reaching.cpp +++ b/src/mapleall/maple_be/src/cg/reaching.cpp @@ -778,6 +778,7 @@ void ReachingDefinition::AnalysisStart() { if (!cgFunc->GetFirstBB()) { return; } + stackSize = GetStackSize(); Initialize(); /* Build in/out for function body first. (Except cleanup bb) */ BuildInOutForFuncBody(); diff --git a/src/mapleall/maple_ir/include/bin_mpl_export.h b/src/mapleall/maple_ir/include/bin_mpl_export.h index 918c8e04eb27ba68f311a2074462f156bf0f3bc8..17a00a9b30d4bab4d5fc5840bb674d782d4ad85b 100644 --- a/src/mapleall/maple_ir/include/bin_mpl_export.h +++ b/src/mapleall/maple_ir/include/bin_mpl_export.h @@ -181,6 +181,7 @@ class BinaryMplExport { void ExpandFourBuffSize(); MIRModule &mod; + private: size_t bufI = 0; std::vector buf; std::unordered_map gStrMark; diff --git a/src/mapleall/maple_ir/include/mir_type.h b/src/mapleall/maple_ir/include/mir_type.h index b8724b2d7e1cf41cae6385a0a19ceeebbd8a1e7e..fda53fe94ba64a26c22420e7bf9d1e5bbac7ce19 100644 --- a/src/mapleall/maple_ir/include/mir_type.h +++ b/src/mapleall/maple_ir/include/mir_type.h @@ -1205,14 +1205,6 @@ class MIRStructType : public MIRType { isImported = flag; } - bool IsUsed() const { - return isUsed; - } - - void SetIsUsed(bool flag) { - isUsed = flag; - } - bool IsCPlusPlus() const { return isCPlusPlus; } @@ -1384,7 +1376,6 @@ class MIRStructType : public MIRType { vTableMethods.clear(); iTableMethods.clear(); isImported = false; - isUsed = false; hasVolatileField = false; hasVolatileFieldSet = false; } @@ -1487,7 +1478,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; diff --git a/src/mapleall/maple_ir/src/bin_func_export.cpp b/src/mapleall/maple_ir/src/bin_func_export.cpp index f558db8106d738f0c4c3eec5776f07d04e01bcdc..a3b0190854e3d158bc0ff1f6ab75b720248bb5b9 100644 --- a/src/mapleall/maple_ir/src/bin_func_export.cpp +++ b/src/mapleall/maple_ir/src/bin_func_export.cpp @@ -88,7 +88,7 @@ void BinaryMplExport::OutputLocalSymbol(MIRSymbol *sym) { void BinaryMplExport::OutputPreg(MIRPreg *preg) { if (preg->GetPregNo() < 0) { WriteNum(kBinSpecialReg); - Write(static_cast(-preg->GetPregNo())); + Write(-preg->GetPregNo()); return; } std::unordered_map::iterator it = localPregMark.find(preg); diff --git a/src/mapleall/maple_ir/src/bin_func_import.cpp b/src/mapleall/maple_ir/src/bin_func_import.cpp index 500e426afe6296b8e5280887b8f550339590f7ce..ac89300f606890491402d7cabe75c2c935de21b8 100644 --- a/src/mapleall/maple_ir/src/bin_func_import.cpp +++ b/src/mapleall/maple_ir/src/bin_func_import.cpp @@ -45,13 +45,13 @@ void BinaryMplImport::ImportFuncIdInfo(MIRFunction *func) { func->SetPuidxOrigin(static_cast(ReadNum())); ImportInfoVector(func->GetInfoVector(), func->InfoIsString()); if (mod.GetFlavor() == kFlavorLmbc) { - func->SetFrameSize(static_cast(ReadNum())); + func->SetFrameSize(static_cast(ReadNum())); } } void BinaryMplImport::ImportBaseNode(Opcode &o, PrimType &typ) { - o = static_cast(Read()); - typ = static_cast(Read()); + o = (Opcode)Read(); + typ = (PrimType)Read(); } MIRSymbol *BinaryMplImport::ImportLocalSymbol(MIRFunction *func) { @@ -61,8 +61,8 @@ MIRSymbol *BinaryMplImport::ImportLocalSymbol(MIRFunction *func) { } if (tag < 0) { CHECK_FATAL(static_cast(-tag) < localSymTab.size(), "index out of bounds"); - return localSymTab.at(static_cast(-tag)); - } + return localSymTab.at(-tag); + } CHECK_FATAL(tag == kBinSymbol, "expecting kBinSymbol in ImportLocalSymbol()"); MIRSymbol *sym = func->GetSymTab()->CreateSymbol(kScopeLocal); localSymTab.push_back(sym); @@ -99,11 +99,11 @@ PregIdx BinaryMplImport::ImportPreg(MIRFunction *func) { } if (tag < 0) { CHECK_FATAL(static_cast(-tag) < localPregTab.size(), "index out of bounds"); - return localPregTab.at(static_cast(-tag)); + return localPregTab.at(-tag); } CHECK_FATAL(tag == kBinPreg, "expecting kBinPreg in ImportPreg()"); - PrimType primType = static_cast(Read()); + PrimType primType = (PrimType)Read(); PregIdx pidx = func->GetPregTab()->CreatePreg(primType); localPregTab.push_back(pidx); return pidx; @@ -116,7 +116,7 @@ LabelIdx BinaryMplImport::ImportLabel(MIRFunction *func) { } if (tag < 0) { CHECK_FATAL(static_cast(-tag) < localLabelTab.size(), "index out of bounds"); - return localLabelTab.at(static_cast(-tag)); + return localLabelTab.at(-tag); } CHECK_FATAL(tag == kBinLabel, "kBinLabel expected in ImportLabel()"); @@ -267,8 +267,8 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_floor: case OP_trunc: { TypeCvtNode *typecvtNode = mod.CurFuncCodeMemPool()->New(op, typ); - typecvtNode->SetFromType(static_cast(Read())); - typecvtNode->SetOpnd(ImportExpression(func), kFirstOpnd); + typecvtNode->SetFromType((PrimType)Read()); + typecvtNode->SetOpnd(ImportExpression(func), 0); return typecvtNode; } case OP_retype: { @@ -307,10 +307,10 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { } case OP_depositbits: { DepositbitsNode *dbNode = mod.CurFuncCodeMemPool()->New(op, typ); - dbNode->SetBitsOffset(static_cast(ReadNum())); - dbNode->SetBitsSize(static_cast(ReadNum())); - dbNode->SetOpnd(ImportExpression(func), kFirstOpnd); - dbNode->SetOpnd(ImportExpression(func), kSecondOpnd); + dbNode->SetBitsOffset(ReadNum()); + dbNode->SetBitsSize(ReadNum()); + dbNode->SetOpnd(ImportExpression(func), 0); + dbNode->SetOpnd(ImportExpression(func), 1); return dbNode; } case OP_gcmallocjarray: @@ -353,9 +353,9 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { case OP_cmpl: case OP_cmp: { CompareNode *cmpNode = mod.CurFuncCodeMemPool()->New(op, typ); - cmpNode->SetOpndType(static_cast(Read())); - cmpNode->SetOpnd(ImportExpression(func), kFirstOpnd); - cmpNode->SetOpnd(ImportExpression(func), kSecondOpnd); + cmpNode->SetOpndType((PrimType)Read()); + cmpNode->SetOpnd(ImportExpression(func), 0); + cmpNode->SetOpnd(ImportExpression(func), 1); return cmpNode; } case OP_resolveinterfacefunc: @@ -527,7 +527,7 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { case OP_iassignspoff: case OP_iassignfpoff: { IassignFPoffNode *s = func->GetCodeMemPool()->New(op); - s->SetPrimType(static_cast(Read())); + s->SetPrimType((PrimType)Read()); s->SetOffset(static_cast(ReadNum())); s->SetOpnd(ImportExpression(func), kFirstOpnd); stmt = s; diff --git a/src/mapleall/maple_ir/src/bin_mpl_export.cpp b/src/mapleall/maple_ir/src/bin_mpl_export.cpp index e6f3e25d05ffde2587815e99c82c97316ec223bb..9bc2061fad8fd5b6ef57960bb83b57ad9b4710c1 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_export.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_export.cpp @@ -1110,7 +1110,6 @@ void BinaryMplExport::WriteSymField(uint64 contentIdx) { for (auto sit = GetMIRModule().GetSymbolDefOrder().begin(); sit != GetMIRModule().GetSymbolDefOrder().end(); ++sit) { MIRSymbol *s = GlobalTables::GetGsymTable().GetSymbolFromStidx(sit->Idx()); - ASSERT(s != nullptr, "null ptr check"); // Verify: all wpofake variables should have been deleted from globaltable ASSERT(!(s->IsWpoFakeParm() || s->IsWpoFakeRet()) || s->IsDeleted(), "wpofake var not deleted"); MIRStorageClass storageClass = s->GetStorageClass(); @@ -1242,7 +1241,7 @@ void BinaryMplExport::AppendAt(const std::string &name, int32 offset) { LogInfo::MapleLogger(kLlErr) << "Error while opening the binary file: " << name << '\n'; FATAL(kLncFatal, "Error while creating the binary file: %s\n", name.c_str()); } - int seekRet = fseek(f, static_cast(offset), SEEK_SET); + int seekRet = fseek(f, (long int)offset, SEEK_SET); CHECK_FATAL(seekRet == 0, "Call fseek failed."); size_t size = buf.size(); size_t k = fwrite(&buf[0], sizeof(uint8), size, f); diff --git a/src/mapleall/maple_ir/src/bin_mpl_import.cpp b/src/mapleall/maple_ir/src/bin_mpl_import.cpp index 2294e72594ce9438271e4613b97483cffb4b74a5..114ce2dde0f9de3ab04ae6087132723328fd9395 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_import.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_import.cpp @@ -544,7 +544,7 @@ TyIdx BinaryMplImport::ImportType(bool forPointedType) { CHECK_FATAL(static_cast(-tag) < typTab.size(), "index out of bounds"); return typTab.at(static_cast(-tag)); } - PrimType primType = static_cast(0); + PrimType primType = (PrimType)0; GStrIdx strIdx(0); bool nameIsLocal = false; ImportTypeBase(primType, strIdx, nameIsLocal); @@ -720,7 +720,7 @@ TyIdx BinaryMplImport::ImportTypeNonJava() { CHECK_FATAL(static_cast(-tag) < typTab.size(), "index out of bounds"); return typTab[static_cast(-tag)]; } - PrimType primType = static_cast(0); + PrimType primType = (PrimType)0; GStrIdx strIdx(0); bool nameIsLocal = false; ImportTypeBase(primType, strIdx, nameIsLocal); diff --git a/src/mapleall/maple_ir/src/mir_lower.cpp b/src/mapleall/maple_ir/src/mir_lower.cpp index ce085e6d1a928404aaa0b5245a4ef4bd864a1629..ddb4827535ea71136af9bfa8408a479ff086d43b 100644 --- a/src/mapleall/maple_ir/src/mir_lower.cpp +++ b/src/mapleall/maple_ir/src/mir_lower.cpp @@ -554,7 +554,7 @@ BlockNode *MIRLower::LowerBlock(BlockNode &block) { 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() > k16BitSize) { + if (retType->GetPrimType() == PTY_agg && retType->GetSize() > 16) { funcType->funcAttrs.SetAttr(FUNCATTR_firstarg_return); } } @@ -1093,14 +1093,14 @@ MIRFuncType *MIRLower::FuncTypeFromFuncPtrExpr(BaseNode *x) { res = static_cast(mirType)->GetPointedFuncType(); } if (res == nullptr) { - res = FuncTypeFromFuncPtrExpr(x->Opnd(kNodeFirstOpnd)); + res = FuncTypeFromFuncPtrExpr(x->Opnd(0)); } break; } case OP_select: { - res = FuncTypeFromFuncPtrExpr(x->Opnd(kNodeSecondOpnd)); + res = FuncTypeFromFuncPtrExpr(x->Opnd(1)); if (res == nullptr) { - res = FuncTypeFromFuncPtrExpr(x->Opnd(kNodeThirdOpnd)); + res = FuncTypeFromFuncPtrExpr(x->Opnd(2)); } break; } diff --git a/src/mapleall/maple_me/include/lmbc_memlayout.h b/src/mapleall/maple_me/include/lmbc_memlayout.h index 833b357561f3c46e1a9c3036ae708cacafb64020..83b59ba69ff1596e06c61f8bbe059a5c06220a7a 100644 --- a/src/mapleall/maple_me/include/lmbc_memlayout.h +++ b/src/mapleall/maple_me/include/lmbc_memlayout.h @@ -38,16 +38,9 @@ typedef enum { class MemSegment; // describes where a symbol is allocated -class SymbolAlloc { - public: - SymbolAlloc() : mem_segment(nullptr), offset(0) {} - - ~SymbolAlloc() { - mem_segment = nullptr; - } - - MemSegment *mem_segment; - int32 offset; +struct SymbolAlloc { + MemSegment *mem_segment = nullptr; + int32 offset = 0; }; // class SymbolAlloc // keeps track of the allocation of a memory segment @@ -61,7 +54,6 @@ class MemSegment { MemSegmentKind kind; int32 size; // size is negative if allocated offsets are negative - SymbolAlloc how_alloc; // this segment may be allocated inside another segment }; // class MemSegment class LMBCMemLayout { diff --git a/src/mapleall/maple_me/src/irmap_build.cpp b/src/mapleall/maple_me/src/irmap_build.cpp index 6fd82f8500b46ffef29213cc90a3e19c6d3d9c84..bebf1facb0781f3ff0f4ebf18cb6056e57da7c07 100755 --- a/src/mapleall/maple_me/src/irmap_build.cpp +++ b/src/mapleall/maple_me/src/irmap_build.cpp @@ -808,8 +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 || - op == OP_icallproto || op == OP_icallprotoassigned) + 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); diff --git a/src/mapleall/maple_me/src/irmap_emit.cpp b/src/mapleall/maple_me/src/irmap_emit.cpp index 9cab595c5d0dee9f19b475781d3e71cd674c2683..d6ca21e18941f669c129e71cb0d98b974f888241 100755 --- a/src/mapleall/maple_me/src/irmap_emit.cpp +++ b/src/mapleall/maple_me/src/irmap_emit.cpp @@ -412,8 +412,7 @@ MIRFunction &CallMeStmt::GetTargetFunction() { } StmtNode &CallMeStmt::EmitStmt(SSATab &ssaTab) { - if (GetOp() != OP_icall && GetOp() != OP_icallassigned && - GetOp() != OP_icallproto && GetOp() != OP_icallprotoassigned) { + 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); diff --git a/src/mapleall/maple_me/src/lmbc_lower.cpp b/src/mapleall/maple_me/src/lmbc_lower.cpp index 9ba84151e5eff57ca4ccc42b2f536112195a6cb4..c5913b036e27395eea1046dd4787ad877104f67d 100644 --- a/src/mapleall/maple_me/src/lmbc_lower.cpp +++ b/src/mapleall/maple_me/src/lmbc_lower.cpp @@ -25,8 +25,8 @@ PregIdx LMBCLowerer::GetSpecialRegFromSt(const MIRSymbol *sym) { 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_FPbased) { + SymbolAlloc *symalloc = &memlayout->sym_alloc_table[sym->GetStIndex()]; + if (symalloc->mem_segment->kind == MS_FPbased) { specreg = -kSregFp; } else { CHECK_FATAL(false, "LMBCLowerer::LowerDread: bad memory layout for local variable"); @@ -411,6 +411,53 @@ BlockNode *LMBCLowerer::LowerBlock(BlockNode *block) { } break; } + case OP_call: + case OP_icallproto: { + for (size_t i = 0; i < stmt->NumOpnds(); ++i) { + if (stmt->Opnd(i)->GetPrimType() != PTY_agg) { + stmt->SetOpnd(LowerExpr(stmt->Opnd(i)), i); + } else { + bool paramInPrototype = false; + MIRFuncType *funcType = nullptr; + if (stmt->GetOpCode() == OP_icallproto) { + IcallNode *icallproto = static_cast(stmt); + funcType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(icallproto->GetRetTyIdx())); + paramInPrototype = (i-1) < funcType->GetParamTypeList().size(); + } else { + CallNode *callNode = static_cast(stmt); + MIRFunction *calleeFunc = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callNode->GetPUIdx()); + funcType = calleeFunc->GetMIRFuncType(); + paramInPrototype = i < funcType->GetParamTypeList().size(); + } + if (paramInPrototype) { + stmt->SetOpnd(LowerExpr(stmt->Opnd(i)), i); + } else { // lower to iread so the type can be provided + if (stmt->Opnd(i)->GetOpCode() == OP_iread) { + IreadNode *iread = static_cast(stmt->Opnd(i)); + iread->SetOpnd(LowerExpr(iread->Opnd(0)), 0); + } else if (stmt->Opnd(i)->GetOpCode() == OP_dread) { + AddrofNode *addrof = static_cast(stmt->Opnd(i)); + FieldID fid = addrof->GetFieldID(); + addrof->SetOpCode(OP_addrof); + addrof->SetPrimType(GetExactPtrPrimType()); + addrof->SetFieldID(0); + MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(addrof->GetStIdx()); + MIRPtrType ptrType(symbol->GetTyIdx(), GetExactPtrPrimType()); + ptrType.SetTypeAttrs(symbol->GetAttrs()); + TyIdx addrTyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&ptrType); + if (addrTyIdx == becommon->GetSizeOfTypeSizeTable()) { + MIRType *newType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(addrTyIdx); + becommon->UpdateTypeTable(*newType); + } + IreadNode *newIread = mirModule->CurFuncCodeMemPool()->New(OP_iread, PTY_agg, addrTyIdx, fid, LowerExpr(addrof)); + stmt->SetOpnd(newIread, i); + } + } + } + } + newblk->AddStatement(stmt); + break; + } default: { for (size_t i = 0; i < stmt->NumOpnds(); ++i) { stmt->SetOpnd(LowerExpr(stmt->Opnd(i)), i); diff --git a/src/mapleall/maple_me/src/me_phase_manager.cpp b/src/mapleall/maple_me/src/me_phase_manager.cpp index eef57b0aeb20b698b5d0f7686e3f1778649572d2..a9b5b3e6365f449206096dc6f74aec43c94e218b 100644 --- a/src/mapleall/maple_me/src/me_phase_manager.cpp +++ b/src/mapleall/maple_me/src/me_phase_manager.cpp @@ -149,6 +149,9 @@ bool MeFuncPM::PhaseRun(maple::MIRModule &m) { if (func->GetBody() == nullptr) { continue; } + if (!IsQuiet()) { + LogInfo::MapleLogger() << ">>>> Generating LMBC for Function < " << func->GetName() << " >\n"; + } m.SetCurFunction(func); cgLower.LowerFunc(*func); MemPool *layoutMp = memPoolCtrler.NewMemPool("layout mempool", true); @@ -160,7 +163,7 @@ bool MeFuncPM::PhaseRun(maple::MIRModule &m) { func->SetFrameSize(localMemLayout.StackFrameSize()); memPoolCtrler.DeleteMemPool(layoutMp); } - globalMemLayout.seg_GPbased.size = maplebe::RoundUp(static_cast(globalMemLayout.seg_GPbased.size), GetPrimTypeSize(PTY_ptr)); + globalMemLayout.seg_GPbased.size = maplebe::RoundUp(globalMemLayout.seg_GPbased.size, GetPrimTypeSize(PTY_ptr)); m.SetGlobalMemSize(globalMemLayout.seg_GPbased.size); // output .lmbc BinaryMplt binMplt(m);