From 4e67e6c36035925c21ed443cb2cad7d37cc13e48 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Wed, 20 Apr 2022 19:11:14 -0700 Subject: [PATCH] Changed the way to mark a function's struct return value is to be loaded to registers Introduced StructReturnedInRegs for MIRFunction's flag field. Use this flag instead of changing the iassign's type field to be the pointed to struct, which is a bad practice because iassign's type must always be a pointer. --- src/mapleall/maple_be/src/be/lower.cpp | 7 ++--- .../src/cg/aarch64/aarch64_cgfunc.cpp | 31 +++++++------------ src/mapleall/maple_ir/include/mir_function.h | 3 ++ src/mapleall/maple_ir/src/mir_function.cpp | 9 ++++++ 4 files changed, 27 insertions(+), 23 deletions(-) diff --git a/src/mapleall/maple_be/src/be/lower.cpp b/src/mapleall/maple_be/src/be/lower.cpp index 6a00d972ce..215b9012eb 100644 --- a/src/mapleall/maple_be/src/be/lower.cpp +++ b/src/mapleall/maple_be/src/be/lower.cpp @@ -837,11 +837,10 @@ BlockNode *CGLowerer::LowerReturnStruct(NaryStmtNode &retNode) { MIRSymbol *retSt = curFunc->GetFormal(0); MIRPtrType *retTy = static_cast(retSt->GetType()); IassignNode *iassign = mirModule.CurFuncCodeMemPool()->New(); - if ((beCommon.GetTypeSize(retTy->GetPointedTyIdx().GetIdx()) > k16ByteSize) || (opnd0->GetPrimType() != PTY_agg)) { - iassign->SetTyIdx(retTy->GetTypeIndex()); - } else { + iassign->SetTyIdx(retTy->GetTypeIndex()); + if ((beCommon.GetTypeSize(retTy->GetPointedTyIdx().GetIdx()) <= k16ByteSize) && (opnd0->GetPrimType() == PTY_agg)) { /* struct goes into register. */ - iassign->SetTyIdx(retTy->GetPointedTyIdx()); + curFunc->SetStructReturnedInRegs(); } iassign->SetFieldID(0); iassign->SetRHS(opnd0); 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 f88b63df39..f99e698b1a 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -1925,16 +1925,15 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { Operand &lhsAddrOpnd = LoadIntoRegister(AddrOpnd, stmt.Opnd(0)->GetPrimType()); uint32 lhsOffset = 0; MIRType *stmtType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(stmt.GetTyIdx()); - MIRSymbol *addrSym = nullptr; - MIRPtrType *lhsPointerType = nullptr; - if (stmtType->GetPrimType() == PTY_agg) { - /* Move into regs */ - AddrofNode &addrofnode = static_cast(stmt.GetAddrExprBase()); - addrSym = mirModule.CurFunction()->GetLocalOrGlobalSymbol(addrofnode.GetStIdx()); - MIRType *addrty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(addrSym->GetTyIdx()); - lhsPointerType = static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(addrty->GetTypeIndex())); - } else { - lhsPointerType = static_cast(stmtType); + 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) { @@ -1979,18 +1978,12 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { rhsType = structType->GetFieldType(rhsDread->GetFieldID()); rhsOffset = static_cast(GetBecommon().GetFieldOffset(*structType, rhsDread->GetFieldID()).first); } - if (stmtType->GetPrimType() == PTY_agg) { + if (loadToRegs4StructReturn) { /* generate move to regs for agg return */ CHECK_FATAL(lhsSize <= k16ByteSize, "SelectAggIassign: illegal struct size"); AArch64CallConvImpl parmlocator(GetBecommon()); CCLocInfo pLoc; - MIRSymbol *retSt = GetBecommon().GetMIRModule().CurFunction()->GetFormal(0); - if (retSt == addrSym) { - /* return value */ - parmlocator.LocateNextParm(*lhsType, pLoc, true, GetBecommon().GetMIRModule().CurFunction()); - } else { - parmlocator.InitCCLocInfo(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 */ @@ -2187,7 +2180,7 @@ void AArch64CGFunc::SelectAggIassign(IassignNode &stmt, Operand &AddrOpnd) { rhsOffset = static_cast(GetBecommon().GetFieldOffset(*rhsStructType, rhsIread->GetFieldID()).first); isRefField = GetBecommon().IsRefField(*rhsStructType, rhsIread->GetFieldID()); } - if (stmtType->GetPrimType() == PTY_agg) { + if (loadToRegs4StructReturn) { /* generate move to regs. */ CHECK_FATAL(lhsSize <= k16ByteSize, "SelectAggIassign: illegal struct size"); RegOperand *result[kTwoRegister]; /* maximum 16 bytes, 2 registers */ diff --git a/src/mapleall/maple_ir/include/mir_function.h b/src/mapleall/maple_ir/include/mir_function.h index 4080108d25..4df1567b10 100644 --- a/src/mapleall/maple_ir/include/mir_function.h +++ b/src/mapleall/maple_ir/include/mir_function.h @@ -416,6 +416,9 @@ class MIRFunction { void SetHasAsm(); bool HasAsm() const; + void SetStructReturnedInRegs(); + bool StructReturnedInRegs() const; + void SetReturnStruct(const MIRType *retType); bool IsEmpty() const; diff --git a/src/mapleall/maple_ir/src/mir_function.cpp b/src/mapleall/maple_ir/src/mir_function.cpp index 75cafccb6b..7c6c48f059 100644 --- a/src/mapleall/maple_ir/src/mir_function.cpp +++ b/src/mapleall/maple_ir/src/mir_function.cpp @@ -32,6 +32,7 @@ enum FuncProp : uint32_t { kFuncPropNeverReturn = 1U << 4, // the function when called never returns kFuncPropHasSetjmp = 1U << 5, // the function contains call to setjmp kFuncPropHasAsm = 1U << 6, // the function has use of inline asm + kFuncPropStructReturnedInRegs = 1U << 7, // the function returns struct in registers }; } // namespace @@ -207,6 +208,14 @@ bool MIRFunction::HasAsm() const { return ((flag & kFuncPropHasAsm) != kTypeflagZero); } +void MIRFunction::SetStructReturnedInRegs() { + flag |= kFuncPropStructReturnedInRegs; +} + +bool MIRFunction::StructReturnedInRegs() const { + return ((flag & kFuncPropStructReturnedInRegs) != kTypeflagZero); +} + void MIRFunction::SetAttrsFromSe(uint8 specialEffect) { // NoPrivateDefEffect if ((specialEffect & kDefEffect) == kDefEffect) { -- Gitee