diff --git a/src/coreclr/jit/abi.cpp b/src/coreclr/jit/abi.cpp index 4ef6f034dd0f8..b60142a856953 100644 --- a/src/coreclr/jit/abi.cpp +++ b/src/coreclr/jit/abi.cpp @@ -187,6 +187,65 @@ ABIPassingSegment ABIPassingSegment::OnStack(unsigned stackOffset, unsigned offs return segment; } +//----------------------------------------------------------------------------- +// ABIPassingInformation: +// Construct an instance with the specified number of segments allocated in +// the backing storage. +// +// Parameters: +// comp - Compiler instance +// numSegments - Number of segments +// +// Remarks: +// The segments are expected to be filled out by the caller after the +// allocation; they are not zeroed out by the allocation. +// +ABIPassingInformation::ABIPassingInformation(Compiler* comp, unsigned numSegments) +{ + NumSegments = numSegments; + + if (numSegments > 1) + { + Segments = new (comp, CMK_ABI) ABIPassingSegment[numSegments]; + } +} + +//----------------------------------------------------------------------------- +// Segment: +// Access a segment by the specified index. +// +// Parameters: +// index - The index of the segment +// +// Returns: +// Reference to segment. +// +const ABIPassingSegment& ABIPassingInformation::Segment(unsigned index) const +{ + assert(index < NumSegments); + if (NumSegments == 1) + { + return SingleSegment; + } + + return Segments[index]; +} + +//----------------------------------------------------------------------------- +// Segment: +// Access a segment by the specified index. +// +// Parameters: +// index - The index of the segment +// +// Returns: +// Reference to segment. +// +ABIPassingSegment& ABIPassingInformation::Segment(unsigned index) +{ + return const_cast(static_cast(*this).Segment(index)); +} + //----------------------------------------------------------------------------- // HasAnyRegisterSegment: // Check if any part of this value is passed in a register. @@ -198,7 +257,7 @@ bool ABIPassingInformation::HasAnyRegisterSegment() const { for (unsigned i = 0; i < NumSegments; i++) { - if (Segments[i].IsPassedInRegister()) + if (Segment(i).IsPassedInRegister()) { return true; } @@ -217,7 +276,7 @@ bool ABIPassingInformation::HasAnyStackSegment() const { for (unsigned i = 0; i < NumSegments; i++) { - if (Segments[i].IsPassedOnStack()) + if (Segment(i).IsPassedOnStack()) { return true; } @@ -234,7 +293,7 @@ bool ABIPassingInformation::HasAnyStackSegment() const // bool ABIPassingInformation::HasExactlyOneRegisterSegment() const { - return (NumSegments == 1) && Segments[0].IsPassedInRegister(); + return (NumSegments == 1) && Segment(0).IsPassedInRegister(); } //----------------------------------------------------------------------------- @@ -246,7 +305,7 @@ bool ABIPassingInformation::HasExactlyOneRegisterSegment() const // bool ABIPassingInformation::HasExactlyOneStackSegment() const { - return (NumSegments == 1) && Segments[0].IsPassedOnStack(); + return (NumSegments == 1) && Segment(0).IsPassedOnStack(); } //----------------------------------------------------------------------------- @@ -264,10 +323,10 @@ bool ABIPassingInformation::IsSplitAcrossRegistersAndStack() const return false; } - bool isFirstInReg = Segments[0].IsPassedInRegister(); + bool isFirstInReg = Segment(0).IsPassedInRegister(); for (unsigned i = 1; i < NumSegments; i++) { - if (isFirstInReg != Segments[i].IsPassedInRegister()) + if (isFirstInReg != Segment(i).IsPassedInRegister()) { return true; } @@ -288,7 +347,32 @@ bool ABIPassingInformation::IsSplitAcrossRegistersAndStack() const // ABIPassingInformation ABIPassingInformation::FromSegment(Compiler* comp, const ABIPassingSegment& segment) { - return {1, new (comp, CMK_ABI) ABIPassingSegment(segment)}; + ABIPassingInformation info; + info.NumSegments = 1; + info.SingleSegment = segment; + return info; +} + +//----------------------------------------------------------------------------- +// FromSegments: +// Create ABIPassingInformation from two segments. +// +// Parameters: +// comp - Compiler instance +// firstSegment - The first segment that represents the passing information +// secondSegment - The second segment that represents the passing information +// +// Return Value: +// An instance of ABIPassingInformation. +// +ABIPassingInformation ABIPassingInformation::FromSegments(Compiler* comp, + const ABIPassingSegment& firstSegment, + const ABIPassingSegment& secondSegment) +{ + ABIPassingInformation info; + info.NumSegments = 2; + info.Segments = new (comp, CMK_ABI) ABIPassingSegment[2]{firstSegment, secondSegment}; + return info; } #ifdef DEBUG @@ -310,9 +394,9 @@ void ABIPassingInformation::Dump() const printf(" [%u] ", i); } - const ABIPassingSegment& seg = Segments[i]; + const ABIPassingSegment& seg = Segment(i); - if (Segments[i].IsPassedInRegister()) + if (seg.IsPassedInRegister()) { printf("[%02u..%02u) reg %s\n", seg.Offset, seg.Offset + seg.Size, getRegName(seg.GetRegister())); } @@ -418,7 +502,7 @@ ABIPassingInformation SwiftABIClassifier::Classify(Compiler* comp, for (unsigned j = 0; j < elemInfo.NumSegments; j++) { - ABIPassingSegment newSegment = elemInfo.Segments[j]; + ABIPassingSegment newSegment = elemInfo.Segment(j); newSegment.Offset += lowering->offsets[i]; // Adjust the tail size if necessary; the lowered sequence can // pass the tail as a larger type than the tail size. @@ -427,12 +511,10 @@ ABIPassingInformation SwiftABIClassifier::Classify(Compiler* comp, } } - ABIPassingInformation result; - result.NumSegments = static_cast(segments.Height()); - result.Segments = new (comp, CMK_ABI) ABIPassingSegment[result.NumSegments]; + ABIPassingInformation result(comp, static_cast(segments.Height())); for (int i = 0; i < segments.Height(); i++) { - result.Segments[i] = segments.Bottom(i); + result.Segment(i) = segments.Bottom(i); } return result; diff --git a/src/coreclr/jit/abi.h b/src/coreclr/jit/abi.h index 7b8baf1052784..28a37d86e3d70 100644 --- a/src/coreclr/jit/abi.h +++ b/src/coreclr/jit/abi.h @@ -39,6 +39,14 @@ class ABIPassingSegment struct ABIPassingInformation { +private: + union + { + ABIPassingSegment* Segments; + ABIPassingSegment SingleSegment; + }; + +public: // The number of segments used to pass the value. Examples: // - On SysV x64, structs can be passed in two registers, resulting in two // register segments @@ -51,15 +59,18 @@ struct ABIPassingInformation // - On loongarch64/riscv64, structs can be passed in two registers or // can be split out over register and stack, giving // multiple register segments and a struct segment. - unsigned NumSegments; - ABIPassingSegment* Segments; + unsigned NumSegments; - ABIPassingInformation(unsigned numSegments = 0, ABIPassingSegment* segments = nullptr) - : NumSegments(numSegments) - , Segments(segments) + ABIPassingInformation() + : NumSegments(0) { } + ABIPassingInformation(Compiler* comp, unsigned numSegments); + + const ABIPassingSegment& Segment(unsigned index) const; + ABIPassingSegment& Segment(unsigned index); + bool HasAnyRegisterSegment() const; bool HasAnyStackSegment() const; bool HasExactlyOneRegisterSegment() const; @@ -67,6 +78,9 @@ struct ABIPassingInformation bool IsSplitAcrossRegistersAndStack() const; static ABIPassingInformation FromSegment(Compiler* comp, const ABIPassingSegment& segment); + static ABIPassingInformation FromSegments(Compiler* comp, + const ABIPassingSegment& firstSegment, + const ABIPassingSegment& secondSegment); #ifdef WINDOWS_AMD64_ABI static bool GetShadowSpaceCallerOffsetForReg(regNumber reg, int* offset); diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index 080fe514f25e4..4f2adda2d3daa 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -3802,7 +3802,7 @@ void CodeGen::genJmpPlaceVarArgs() const ABIPassingInformation& abiInfo = compiler->lvaGetParameterABIInfo(varNum); for (unsigned i = 0; i < abiInfo.NumSegments; i++) { - const ABIPassingSegment& segment = abiInfo.Segments[i]; + const ABIPassingSegment& segment = abiInfo.Segment(i); if (segment.IsPassedInRegister()) { potentialArgs &= ~segment.GetRegisterMask(); diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index 2a1d7652ac541..da92699b6b235 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -3202,7 +3202,7 @@ void CodeGen::genSpillOrAddRegisterParam(unsigned lclNum, RegGraph* graph) const ABIPassingInformation& abiInfo = compiler->lvaGetParameterABIInfo(paramLclNum); for (unsigned i = 0; i < abiInfo.NumSegments; i++) { - const ABIPassingSegment& seg = abiInfo.Segments[i]; + const ABIPassingSegment& seg = abiInfo.Segment(i); if (!seg.IsPassedInRegister() || ((paramRegs & genRegMask(seg.GetRegister())) == 0)) { continue; @@ -3325,7 +3325,7 @@ void CodeGen::genHomeRegisterParams(regNumber initReg, bool* initRegStillZeroed) const ABIPassingInformation& abiInfo = compiler->lvaGetParameterABIInfo(lclNum); for (unsigned i = 0; i < abiInfo.NumSegments; i++) { - const ABIPassingSegment& seg = abiInfo.Segments[i]; + const ABIPassingSegment& seg = abiInfo.Segment(i); if (seg.IsPassedInRegister() && ((paramRegs & genRegMask(seg.GetRegister())) != 0)) { var_types storeType = genParamStackType(lclDsc, seg); @@ -4373,7 +4373,7 @@ void CodeGen::genHomeSwiftStructParameters(bool handleStack) for (unsigned i = 0; i < abiInfo.NumSegments; i++) { - const ABIPassingSegment& seg = abiInfo.Segments[i]; + const ABIPassingSegment& seg = abiInfo.Segment(i); if (seg.IsPassedOnStack() != handleStack) { continue; @@ -4434,9 +4434,9 @@ void CodeGen::genHomeStackPartOfSplitParameter(regNumber initReg, bool* initRegS JITDUMP("Homing stack part of split parameter V%02u\n", lclNum); assert(abiInfo.NumSegments == 2); - assert(abiInfo.Segments[0].GetRegister() == REG_ARG_LAST); - assert(abiInfo.Segments[1].GetStackOffset() == 0); - const ABIPassingSegment& seg = abiInfo.Segments[1]; + assert(abiInfo.Segment(0).GetRegister() == REG_ARG_LAST); + assert(abiInfo.Segment(1).GetStackOffset() == 0); + const ABIPassingSegment& seg = abiInfo.Segment(1); genHomeStackSegment(lclNum, seg, initReg, initRegStillZeroed); @@ -7514,7 +7514,7 @@ void CodeGen::genJmpPlaceArgs(GenTree* jmp) const ABIPassingInformation& abiInfo = compiler->lvaGetParameterABIInfo(varNum); for (unsigned i = 0; i < abiInfo.NumSegments; i++) { - const ABIPassingSegment& segment = abiInfo.Segments[i]; + const ABIPassingSegment& segment = abiInfo.Segment(i); if (segment.IsPassedOnStack()) { continue; diff --git a/src/coreclr/jit/codegenxarch.cpp b/src/coreclr/jit/codegenxarch.cpp index 25a7fd134a451..e25766249dc65 100644 --- a/src/coreclr/jit/codegenxarch.cpp +++ b/src/coreclr/jit/codegenxarch.cpp @@ -6565,7 +6565,7 @@ void CodeGen::genJmpPlaceVarArgs() const ABIPassingInformation& abiInfo = compiler->lvaGetParameterABIInfo(varNum); for (unsigned i = 0; i < abiInfo.NumSegments; i++) { - const ABIPassingSegment& segment = abiInfo.Segments[i]; + const ABIPassingSegment& segment = abiInfo.Segment(i); if (segment.IsPassedOnStack()) { continue; diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index bf7dc8fb14d7a..687ac114e329f 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -1809,10 +1809,10 @@ void Compiler::lvaClassifyParameterABI() else { assert(abiInfo.NumSegments == 1); - if (abiInfo.Segments[0].IsPassedInRegister()) + if (abiInfo.Segment(0).IsPassedInRegister()) { dsc->lvIsRegArg = true; - dsc->SetArgReg(abiInfo.Segments[0].GetRegister()); + dsc->SetArgReg(abiInfo.Segment(0).GetRegister()); dsc->SetOtherArgReg(REG_NA); } else @@ -1820,13 +1820,13 @@ void Compiler::lvaClassifyParameterABI() dsc->lvIsRegArg = false; dsc->SetArgReg(REG_STK); dsc->SetOtherArgReg(REG_NA); - dsc->SetStackOffset(abiInfo.Segments[0].GetStackOffset()); + dsc->SetStackOffset(abiInfo.Segment(0).GetStackOffset()); } } for (unsigned i = 0; i < abiInfo.NumSegments; i++) { - const ABIPassingSegment& segment = abiInfo.Segments[i]; + const ABIPassingSegment& segment = abiInfo.Segment(i); if (segment.IsPassedInRegister()) { argRegs |= segment.GetRegisterMask(); @@ -1887,7 +1887,7 @@ void Compiler::lvaClassifyParameterABI() for (unsigned i = 0; i < numSegmentsToCompare; i++) { - const ABIPassingSegment& expected = abiInfo.Segments[i]; + const ABIPassingSegment& expected = abiInfo.Segment(i); regNumber reg = REG_NA; if (i == 0) { @@ -1934,19 +1934,19 @@ void Compiler::lvaClassifyParameterABI() if (lvaIsImplicitByRefLocal(lclNum)) { - assert((abiInfo.NumSegments == 1) && (abiInfo.Segments[0].Size == TARGET_POINTER_SIZE)); + assert((abiInfo.NumSegments == 1) && (abiInfo.Segment(0).Size == TARGET_POINTER_SIZE)); } else { for (unsigned i = 0; i < abiInfo.NumSegments; i++) { - const ABIPassingSegment& segment = abiInfo.Segments[i]; + const ABIPassingSegment& segment = abiInfo.Segment(i); assert(segment.Size > 0); assert(segment.Offset + segment.Size <= lvaLclExactSize(lclNum)); if (i > 0) { - assert(segment.Offset > abiInfo.Segments[i - 1].Offset); + assert(segment.Offset > abiInfo.Segment(i - 1).Offset); } for (unsigned j = 0; j < abiInfo.NumSegments; j++) @@ -1956,7 +1956,7 @@ void Compiler::lvaClassifyParameterABI() continue; } - const ABIPassingSegment& otherSegment = abiInfo.Segments[j]; + const ABIPassingSegment& otherSegment = abiInfo.Segment(j); assert((segment.Offset + segment.Size <= otherSegment.Offset) || (segment.Offset >= otherSegment.Offset + otherSegment.Size)); } @@ -6054,7 +6054,7 @@ bool Compiler::lvaGetRelativeOffsetToCallerAllocatedSpaceForParameter(unsigned l for (unsigned i = 0; i < abiInfo.NumSegments; i++) { - const ABIPassingSegment& segment = abiInfo.Segments[i]; + const ABIPassingSegment& segment = abiInfo.Segment(i); if (!segment.IsPassedOnStack()) { #if defined(WINDOWS_AMD64_ABI) diff --git a/src/coreclr/jit/lsrabuild.cpp b/src/coreclr/jit/lsrabuild.cpp index 89fd0433e346b..fddddf61b4101 100644 --- a/src/coreclr/jit/lsrabuild.cpp +++ b/src/coreclr/jit/lsrabuild.cpp @@ -2312,7 +2312,7 @@ void LinearScan::buildIntervals() const ABIPassingInformation& abiInfo = compiler->lvaGetParameterABIInfo(lclNum); for (unsigned i = 0; i < abiInfo.NumSegments; i++) { - const ABIPassingSegment& seg = abiInfo.Segments[i]; + const ABIPassingSegment& seg = abiInfo.Segment(i); if (seg.IsPassedInRegister()) { RegState* regState = genIsValidFloatReg(seg.GetRegister()) ? floatRegState : intRegState; diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 733b429675d09..a41a2485ef7f1 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -4598,8 +4598,8 @@ GenTree* Compiler::fgMorphExpandStackArgForVarArgs(GenTreeLclVarCommon* lclNode) assert(abiInfo.HasExactlyOneStackSegment()); GenTree* argsBaseAddr = gtNewLclvNode(lvaVarargsBaseOfStkArgs, TYP_I_IMPL); - ssize_t offset = (ssize_t)abiInfo.Segments[0].GetStackOffset() - lclNode->GetLclOffs(); - assert(abiInfo.Segments[0].GetStackOffset() == + ssize_t offset = (ssize_t)abiInfo.Segment(0).GetStackOffset() - lclNode->GetLclOffs(); + assert(abiInfo.Segment(0).GetStackOffset() == (varDsc->GetStackOffset() - codeGen->intRegState.rsCalleeRegArgCount * REGSIZE_BYTES)); GenTree* offsetNode = gtNewIconNode(offset, TYP_I_IMPL); GenTree* argAddr = gtNewOperNode(GT_SUB, TYP_I_IMPL, argsBaseAddr, offsetNode); diff --git a/src/coreclr/jit/targetamd64.cpp b/src/coreclr/jit/targetamd64.cpp index 8f3a979d7862b..43c200fdd359b 100644 --- a/src/coreclr/jit/targetamd64.cpp +++ b/src/coreclr/jit/targetamd64.cpp @@ -105,13 +105,12 @@ ABIPassingInformation SysVX64Classifier::Classify(Compiler* comp, { if (varTypeIsStruct(type)) { - info.NumSegments = structDesc.eightByteCount; - info.Segments = new (comp, CMK_ABI) ABIPassingSegment[structDesc.eightByteCount]; + info = ABIPassingInformation(comp, structDesc.eightByteCount); for (unsigned i = 0; i < structDesc.eightByteCount; i++) { regNumber reg = structDesc.IsIntegralSlot(i) ? m_intRegs.Dequeue() : m_floatRegs.Dequeue(); - info.Segments[i] = + info.Segment(i) = ABIPassingSegment::InRegister(reg, structDesc.eightByteOffsets[i], structDesc.eightByteSizes[i]); } } diff --git a/src/coreclr/jit/targetarm.cpp b/src/coreclr/jit/targetarm.cpp index 675fd04230d53..3118621a240e9 100644 --- a/src/coreclr/jit/targetarm.cpp +++ b/src/coreclr/jit/targetarm.cpp @@ -98,14 +98,12 @@ ABIPassingInformation Arm32Classifier::Classify(Compiler* comp, numInRegs = 0; } - ABIPassingInformation info; - info.NumSegments = numInRegs + (anyOnStack ? 1 : 0); - info.Segments = new (comp, CMK_ABI) ABIPassingSegment[info.NumSegments]; + ABIPassingInformation info(comp, numInRegs + (anyOnStack ? 1 : 0)); for (unsigned i = 0; i < numInRegs; i++) { unsigned endOffs = min((i + 1) * 4, size); - info.Segments[i] = + info.Segment(i) = ABIPassingSegment::InRegister(static_cast(static_cast(REG_R0) + m_nextIntReg + i), i * 4, endOffs - (i * 4)); } @@ -114,9 +112,9 @@ ABIPassingInformation Arm32Classifier::Classify(Compiler* comp, if (anyOnStack) { - m_stackArgSize = roundUp(m_stackArgSize, alignment); - unsigned stackSize = size - (numInRegs * 4); - info.Segments[numInRegs] = ABIPassingSegment::OnStack(m_stackArgSize, numInRegs * 4, stackSize); + m_stackArgSize = roundUp(m_stackArgSize, alignment); + unsigned stackSize = size - (numInRegs * 4); + info.Segment(numInRegs) = ABIPassingSegment::OnStack(m_stackArgSize, numInRegs * 4, stackSize); m_stackArgSize += roundUp(stackSize, 4); // As soon as any int arg goes on stack we cannot put anything else in @@ -181,14 +179,12 @@ ABIPassingInformation Arm32Classifier::ClassifyFloat(Compiler* comp, var_types t assert((m_floatRegs & usedRegsMask) == usedRegsMask); m_floatRegs ^= usedRegsMask; - ABIPassingInformation info; - info.NumSegments = numElems; - info.Segments = new (comp, CMK_ABI) ABIPassingSegment[numElems]; - unsigned numRegsPerElem = type == TYP_FLOAT ? 1 : 2; + ABIPassingInformation info(comp, numElems); + unsigned numRegsPerElem = type == TYP_FLOAT ? 1 : 2; for (unsigned i = 0; i < numElems; i++) { regNumber reg = static_cast(static_cast(REG_F0) + startRegIndex + i * numRegsPerElem); - info.Segments[i] = ABIPassingSegment::InRegister(reg, i * genTypeSize(type), genTypeSize(type)); + info.Segment(i) = ABIPassingSegment::InRegister(reg, i * genTypeSize(type), genTypeSize(type)); } return info; diff --git a/src/coreclr/jit/targetarm64.cpp b/src/coreclr/jit/targetarm64.cpp index f95663202456b..5473db7296ec5 100644 --- a/src/coreclr/jit/targetarm64.cpp +++ b/src/coreclr/jit/targetarm64.cpp @@ -76,12 +76,11 @@ ABIPassingInformation Arm64Classifier::Classify(Compiler* comp, ABIPassingInformation info; if (m_floatRegs.Count() >= slots) { - info.NumSegments = slots; - info.Segments = new (comp, CMK_ABI) ABIPassingSegment[slots]; + info = ABIPassingInformation(comp, slots); for (unsigned i = 0; i < slots; i++) { - info.Segments[i] = ABIPassingSegment::InRegister(m_floatRegs.Dequeue(), i * elemSize, elemSize); + info.Segment(i) = ABIPassingSegment::InRegister(m_floatRegs.Dequeue(), i * elemSize, elemSize); } } else @@ -132,11 +131,13 @@ ABIPassingInformation Arm64Classifier::Classify(Compiler* comp, // case. Normally a struct that does not fit in registers will always // be passed on stack. assert(compFeatureArgSplit()); - info.NumSegments = 2; - info.Segments = new (comp, CMK_ABI) ABIPassingSegment[2]; - info.Segments[0] = ABIPassingSegment::InRegister(m_intRegs.Dequeue(), 0, TARGET_POINTER_SIZE); - info.Segments[1] = ABIPassingSegment::OnStack(m_stackArgSize, TARGET_POINTER_SIZE, - structLayout->GetSize() - TARGET_POINTER_SIZE); + info = ABIPassingInformation::FromSegments(comp, + ABIPassingSegment::InRegister(m_intRegs.Dequeue(), 0, + TARGET_POINTER_SIZE), + ABIPassingSegment::OnStack(m_stackArgSize, TARGET_POINTER_SIZE, + structLayout->GetSize() - + TARGET_POINTER_SIZE)); + m_stackArgSize += TARGET_POINTER_SIZE; } else @@ -152,15 +153,14 @@ ABIPassingInformation Arm64Classifier::Classify(Compiler* comp, if (regs->Count() >= slots) { - info.NumSegments = slots; - info.Segments = new (comp, CMK_ABI) ABIPassingSegment[slots]; + info = ABIPassingInformation(comp, slots); unsigned slotSize = min(passedSize, (unsigned)TARGET_POINTER_SIZE); - info.Segments[0] = ABIPassingSegment::InRegister(regs->Dequeue(), 0, slotSize); + info.Segment(0) = ABIPassingSegment::InRegister(regs->Dequeue(), 0, slotSize); if (slots == 2) { assert(varTypeIsStruct(type)); unsigned tailSize = structLayout->GetSize() - slotSize; - info.Segments[1] = ABIPassingSegment::InRegister(regs->Dequeue(), slotSize, tailSize); + info.Segment(1) = ABIPassingSegment::InRegister(regs->Dequeue(), slotSize, tailSize); } } else diff --git a/src/coreclr/jit/targetloongarch64.cpp b/src/coreclr/jit/targetloongarch64.cpp index caab31b18988a..3b8ee6e677cbb 100644 --- a/src/coreclr/jit/targetloongarch64.cpp +++ b/src/coreclr/jit/targetloongarch64.cpp @@ -173,15 +173,14 @@ ABIPassingInformation LoongArch64Classifier::Classify(Compiler* comp, ABIPassingInformation info; if (canPassArgInRegisters) { - info.NumSegments = slots; - info.Segments = new (comp, CMK_ABI) ABIPassingSegment[slots]; + info = ABIPassingInformation(comp, slots); if (argRegTypeInStruct1 != TYP_UNKNOWN) { RegisterQueue* regs = varTypeIsFloating(argRegTypeInStruct1) ? &m_floatRegs : &m_intRegs; assert(regs->Count() > 0); passedSize = genTypeSize(argRegTypeInStruct1); - info.Segments[0] = ABIPassingSegment::InRegister(regs->Dequeue(), 0, passedSize); + info.Segments(0) = ABIPassingSegment::InRegister(regs->Dequeue(), 0, passedSize); if (argRegTypeInStruct2 != TYP_UNKNOWN) { @@ -190,15 +189,15 @@ ABIPassingInformation LoongArch64Classifier::Classify(Compiler* comp, regs = varTypeIsFloating(argRegTypeInStruct2) ? &m_floatRegs : &m_intRegs; assert(regs->Count() > 0); - passedSize = max(passedSize, slotSize); - info.Segments[1] = ABIPassingSegment::InRegister(regs->Dequeue(), passedSize, slotSize); + passedSize = max(passedSize, slotSize); + info.Segment(1) = ABIPassingSegment::InRegister(regs->Dequeue(), passedSize, slotSize); } } else { RegisterQueue* regs = varTypeIsFloating(type) ? &m_floatRegs : &m_intRegs; unsigned slotSize = min(passedSize, (unsigned)TARGET_POINTER_SIZE); - info.Segments[0] = ABIPassingSegment::InRegister(regs->Dequeue(), 0, slotSize); + info.Segment(0) = ABIPassingSegment::InRegister(regs->Dequeue(), 0, slotSize); if (slots == 2) { assert(varTypeIsStruct(type)); @@ -206,13 +205,13 @@ ABIPassingInformation LoongArch64Classifier::Classify(Compiler* comp, unsigned tailSize = passedSize - slotSize; if (m_intRegs.Count() > 0) { - info.Segments[1] = ABIPassingSegment::InRegister(m_intRegs.Dequeue(), slotSize, tailSize); + info.Segment(1) = ABIPassingSegment::InRegister(m_intRegs.Dequeue(), slotSize, tailSize); } else { assert(m_intRegs.Count() == 0); assert(m_stackArgSize == 0); - info.Segments[1] = ABIPassingSegment::OnStack(0, TARGET_POINTER_SIZE, tailSize); + info.Segment(1) = ABIPassingSegment::OnStack(0, TARGET_POINTER_SIZE, tailSize); m_stackArgSize += TARGET_POINTER_SIZE; } } diff --git a/src/coreclr/jit/targetriscv64.cpp b/src/coreclr/jit/targetriscv64.cpp index 4df767d8cbfcc..6adb2b7b91ea1 100644 --- a/src/coreclr/jit/targetriscv64.cpp +++ b/src/coreclr/jit/targetriscv64.cpp @@ -130,9 +130,8 @@ ABIPassingInformation RiscV64Classifier::Classify(Compiler* comp, regNumber firstReg = (isFirstFloat ? m_floatRegs : m_intRegs).Dequeue(); regNumber secondReg = (isSecondFloat ? m_floatRegs : m_intRegs).Dequeue(); - return {2, new (comp, CMK_ABI) - ABIPassingSegment[2]{ABIPassingSegment::InRegister(firstReg, 0, firstSize), - ABIPassingSegment::InRegister(secondReg, offset, secondSize)}}; + return ABIPassingInformation::FromSegments(comp, ABIPassingSegment::InRegister(firstReg, 0, firstSize), + ABIPassingSegment::InRegister(secondReg, offset, secondSize)); } } else @@ -164,7 +163,7 @@ ABIPassingInformation RiscV64Classifier::Classify(Compiler* comp, (m_intRegs.Count() > 0) ? ABIPassingSegment::InRegister(m_intRegs.Dequeue(), TARGET_POINTER_SIZE, tailSize) : passOnStack(TARGET_POINTER_SIZE, tailSize); - return {2, new (comp, CMK_ABI) ABIPassingSegment[2]{head, tail}}; + return ABIPassingInformation::FromSegments(comp, head, tail); } } else