diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index 7fee192a419f27..9fac57cedb6971 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -751,12 +751,6 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode) // we are storing arg slot number in GT_PUTARG_STK node in lowering phase. unsigned argOffsetOut = treeNode->getArgOffset(); -#ifdef DEBUG - CallArg* callArg = treeNode->gtCall->gtArgs.FindByNode(treeNode); - assert(callArg != nullptr); - DEBUG_ARG_SLOTS_ASSERT(argOffsetOut == (callArg->AbiInfo.SlotNum * TARGET_POINTER_SIZE)); -#endif // DEBUG - // Whether to setup stk arg in incoming or out-going arg area? // Fast tail calls implemented as epilog+jmp = stk arg is setup in incoming arg area. // All other calls - stk arg is setup in out-going arg area. diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index 8622733e75d4c1..acf280007f5fd0 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -2052,26 +2052,6 @@ void CodeGen::genEmitMachineCode() } #endif -#if EMIT_TRACK_STACK_DEPTH && defined(DEBUG_ARG_SLOTS) - // Check our max stack level. Needed for fgAddCodeRef(). - // We need to relax the assert as our estimation won't include code-gen - // stack changes (which we know don't affect fgAddCodeRef()). - // NOTE: after emitEndCodeGen (including here), emitMaxStackDepth is a - // count of DWORD-sized arguments, NOT argument size in bytes. - { - unsigned maxAllowedStackDepth = compiler->fgGetPtrArgCntMax() + // Max number of pointer-sized stack arguments. - compiler->compHndBBtabCount + // Return address for locally-called finallys - genTypeStSz(TYP_LONG) + // longs/doubles may be transferred via stack, etc - (compiler->compTailCallUsed ? 4 : 0); // CORINFO_HELP_TAILCALL args -#if defined(UNIX_X86_ABI) - // Convert maxNestedAlignment to DWORD count before adding to maxAllowedStackDepth. - assert(maxNestedAlignment % sizeof(int) == 0); - maxAllowedStackDepth += maxNestedAlignment / sizeof(int); -#endif - assert(GetEmitter()->emitMaxStackDepth <= maxAllowedStackDepth); - } -#endif // EMIT_TRACK_STACK_DEPTH && DEBUG - *nativeSizeOfCode = codeSize; compiler->info.compNativeCodeSize = (UNATIVE_OFFSET)codeSize; diff --git a/src/coreclr/jit/codegenxarch.cpp b/src/coreclr/jit/codegenxarch.cpp index 326a2be1289f73..a2759bd7e8e660 100644 --- a/src/coreclr/jit/codegenxarch.cpp +++ b/src/coreclr/jit/codegenxarch.cpp @@ -3507,7 +3507,6 @@ void CodeGen::genStructPutArgPush(GenTreePutArgStk* putArgNode) const unsigned byteSize = putArgNode->GetStackByteSize(); assert((byteSize % TARGET_POINTER_SIZE == 0) && ((byteSize < XMM_REGSIZE_BYTES) || layout->HasGCPtr())); const unsigned numSlots = byteSize / TARGET_POINTER_SIZE; - assert(putArgNode->gtNumSlots == numSlots); for (int i = numSlots - 1; i >= 0; --i) { @@ -3557,7 +3556,6 @@ void CodeGen::genStructPutArgPartialRepMovs(GenTreePutArgStk* putArgNode) const unsigned byteSize = putArgNode->GetStackByteSize(); assert(byteSize % TARGET_POINTER_SIZE == 0); const unsigned numSlots = byteSize / TARGET_POINTER_SIZE; - assert(putArgNode->gtNumSlots == numSlots); // No need to disable GC the way COPYOBJ does. Here the refs are copied in atomic operations always. for (unsigned i = 0; i < numSlots;) @@ -5390,7 +5388,7 @@ void CodeGen::genCall(GenTreeCall* call) unsigned size = argNode->AsPutArgStk()->GetStackByteSize(); stackArgBytes += size; #ifdef DEBUG - assert(size == (arg.AbiInfo.NumSlots * TARGET_POINTER_SIZE)); + assert(size == arg.AbiInfo.ByteSize); #ifdef FEATURE_PUT_STRUCT_ARG_STK if (!source->OperIs(GT_FIELD_LIST) && (source->TypeGet() == TYP_STRUCT)) { @@ -5402,7 +5400,7 @@ void CodeGen::genCall(GenTreeCall* call) // Note that on x64/ux this will be handled by unrolling in genStructPutArgUnroll. assert((argBytes == obj->GetLayout()->GetSize()) || obj->Addr()->IsLocalAddrExpr()); #endif // TARGET_X86 - assert((arg.AbiInfo.NumSlots * TARGET_POINTER_SIZE) == argBytes); + assert(arg.AbiInfo.ByteSize == argBytes); } #endif // FEATURE_PUT_STRUCT_ARG_STK #endif // DEBUG @@ -7971,7 +7969,7 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* putArgStk) #ifdef DEBUG CallArg* callArg = putArgStk->gtCall->gtArgs.FindByNode(putArgStk); assert(callArg != nullptr); - assert(argOffset == callArg->AbiInfo.SlotNum * TARGET_POINTER_SIZE); + assert(argOffset == callArg->AbiInfo.ByteOffset); #endif if (data->isContainedIntOrIImmed()) diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index a70f193cd90490..da02f077c1775c 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -1111,93 +1111,10 @@ void CallArgABIInformation::SetByteSize(unsigned byteSize, unsigned byteAlignmen assert(roundedByteSize % byteAlignment == 0); #endif // TARGET_ARM -#if defined(DEBUG_ARG_SLOTS) - if (!compMacOsArm64Abi() && !isStruct) - { - assert(roundedByteSize == GetSlotCount() * TARGET_POINTER_SIZE); - } -#endif ByteSize = roundedByteSize; ByteAlignment = byteAlignment; } -#ifdef DEBUG_ARG_SLOTS -//--------------------------------------------------------------- -// GetSlotCount: Get the number of slots used by this argument. -// -// Returns: -// The number of slots, in terms of registers and whole stack slots. -// -// Remarks: -// Note that a slot may not necessarily be TARGET_POINTER_SIZE in size. -// For example, a SIMD16 may be passed in a single register where this -// function will return 1. -unsigned CallArgABIInformation::GetSlotCount() const -{ - if (IsBackFilled) - { - assert(IsPassedInRegisters()); - assert(NumRegs == 1); - } - else if (GetRegNum() == REG_STK) - { - assert(!IsPassedInRegisters()); - assert(NumRegs == 0); - } - else - { - assert(NumRegs > 0); - } - return NumSlots + NumRegs; -} - -//--------------------------------------------------------------- -// GetSize: Get the size of the argument normalized to TARGET_POINTER_SIZE -// stack slots. -// -// Returns: -// The size of the argument, normalized to TARGET_POINTER_SIZE stack slots. -// -// Remarks: -// Unlike GetSlotCount() this function applies normalization and returns the -// answer in terms of TARGET_POINTER_SIZE slots. -// For example, a SIMD16 argument passed in a single register will return 2 -// on ARM64. -unsigned CallArgABIInformation::GetSize() const -{ - unsigned size = GetSlotCount(); - if (GlobalJitOptions::compFeatureHfa) - { - if (IsHfaRegArg()) - { -#ifdef TARGET_ARM - // We counted the number of regs, but if they are DOUBLE hfa regs we have to double the size. - if (GetHfaType() == TYP_DOUBLE) - { - assert(!IsSplit()); - size <<= 1; - } -#elif defined(TARGET_ARM64) - // We counted the number of regs, but if they are FLOAT hfa regs we have to halve the size, - // or if they are SIMD16 vector hfa regs we have to double the size. - if (GetHfaType() == TYP_FLOAT) - { - // Round up in case of odd HFA count. - size = (size + 1) >> 1; - } -#ifdef FEATURE_SIMD - else if (GetHfaType() == TYP_SIMD16) - { - size <<= 1; - } -#endif // FEATURE_SIMD -#endif // TARGET_ARM64 - } - } - return size; -} -#endif - //--------------------------------------------------------------- // SetMultiRegsNumw: Set the registers for a multi-reg arg using 'sequential' registers. // @@ -1302,7 +1219,7 @@ void CallArg::CheckIsStruct() #ifdef TARGET_ARM if (!isPassedAsPrimitiveType) { - if (node->TypeGet() == TYP_DOUBLE && AbiInfo.NumRegs == 0 && (AbiInfo.NumSlots == 2)) + if (node->TypeGet() == TYP_DOUBLE && AbiInfo.NumRegs == 0 && (AbiInfo.GetStackSlotsNumber() == 2)) { isPassedAsPrimitiveType = true; } @@ -11662,19 +11579,7 @@ void Compiler::gtDispTree(GenTree* tree, else if (tree->OperGet() == GT_PUTARG_STK) { const GenTreePutArgStk* putArg = tree->AsPutArgStk(); -#if !defined(DEBUG_ARG_SLOTS) printf(" (%d stackByteSize), (%d byteOffset)", putArg->GetStackByteSize(), putArg->getArgOffset()); -#else - if (compMacOsArm64Abi()) - { - printf(" (%d stackByteSize), (%d byteOffset)", putArg->GetStackByteSize(), putArg->getArgOffset()); - } - else - { - printf(" (%d slots), (%d stackByteSize), (%d slot), (%d byteOffset)", putArg->gtNumSlots, - putArg->GetStackByteSize(), putArg->gtSlotNum, putArg->getArgOffset()); - } -#endif if (putArg->gtPutArgStkKind != GenTreePutArgStk::Kind::Invalid) { switch (putArg->gtPutArgStkKind) @@ -11700,19 +11605,7 @@ void Compiler::gtDispTree(GenTree* tree, else if (tree->OperGet() == GT_PUTARG_SPLIT) { const GenTreePutArgSplit* putArg = tree->AsPutArgSplit(); -#if !defined(DEBUG_ARG_SLOTS) printf(" (%d stackByteSize), (%d numRegs)", putArg->GetStackByteSize(), putArg->gtNumRegs); -#else - if (compMacOsArm64Abi()) - { - printf(" (%d stackByteSize), (%d numRegs)", putArg->GetStackByteSize(), putArg->gtNumRegs); - } - else - { - printf(" (%d slots), (%d stackByteSize), (%d numRegs)", putArg->gtNumSlots, putArg->GetStackByteSize(), - putArg->gtNumRegs); - } -#endif } #endif // FEATURE_ARG_SPLIT #endif // FEATURE_PUT_STRUCT_ARG_STK @@ -12173,8 +12066,7 @@ void Compiler::gtGetArgMsg(GenTreeCall* call, CallArg* arg, char* bufp, unsigned regNumber firstReg = arg->AbiInfo.GetRegNum(); if (arg->AbiInfo.NumRegs == 1) { - sprintf_s(bufp, bufLength, " %s out+%02x", compRegVarName(firstReg), - arg->AbiInfo.SlotNum * TARGET_POINTER_SIZE); + sprintf_s(bufp, bufLength, " %s out+%02x", compRegVarName(firstReg), arg->AbiInfo.ByteOffset); } else { @@ -12191,7 +12083,7 @@ void Compiler::gtGetArgMsg(GenTreeCall* call, CallArg* arg, char* bufp, unsigned lastReg = genMapIntRegArgNumToRegNum(lastRegNum); } sprintf_s(bufp, bufLength, " %s%c%s out+%02x", compRegVarName(firstReg), separator, - compRegVarName(lastReg), arg->AbiInfo.SlotNum * TARGET_POINTER_SIZE); + compRegVarName(lastReg), arg->AbiInfo.ByteOffset); } return; @@ -12238,8 +12130,7 @@ void Compiler::gtGetLateArgMsg(GenTreeCall* call, CallArg* arg, char* bufp, unsi regNumber firstReg = arg->AbiInfo.GetRegNum(); if (arg->AbiInfo.NumRegs == 1) { - sprintf_s(bufp, bufLength, " %s out+%02x", compRegVarName(firstReg), - arg->AbiInfo.SlotNum * TARGET_POINTER_SIZE); + sprintf_s(bufp, bufLength, " %s out+%02x", compRegVarName(firstReg), arg->AbiInfo.ByteOffset); } else { @@ -12256,7 +12147,7 @@ void Compiler::gtGetLateArgMsg(GenTreeCall* call, CallArg* arg, char* bufp, unsi lastReg = genMapIntRegArgNumToRegNum(lastRegNum); } sprintf_s(bufp, bufLength, " %s%c%s out+%02x", compRegVarName(firstReg), separator, - compRegVarName(lastReg), arg->AbiInfo.SlotNum * TARGET_POINTER_SIZE); + compRegVarName(lastReg), arg->AbiInfo.ByteOffset); } return; diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index c86b995c397594..368f8766442d67 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -4027,10 +4027,6 @@ struct CallArgABIInformation #endif #ifdef TARGET_LOONGARCH64 , StructFloatFieldType() -#endif -#ifdef DEBUG_ARG_SLOTS - , SlotNum(0) - , NumSlots(0) #endif , ArgType(TYP_UNDEF) , IsBackFilled(false) @@ -4075,15 +4071,6 @@ struct CallArgABIInformation // e.g `struct {int a; float b;}` passed by an integer register and a float register. var_types StructFloatFieldType[2]; #endif -#if defined(DEBUG_ARG_SLOTS) - // These fields were used to calculate stack size in stack slots for arguments - // but now they are replaced by precise `m_byteOffset/m_byteSize` because of - // arm64 apple abi requirements. - - // A slot is a pointer sized region in the OutArg area. - unsigned SlotNum; // When an argument is passed in the OutArg area this is the slot number in the OutArg area - unsigned NumSlots; // Count of number of slots that this argument uses -#endif // DEBUG_ARG_SLOTS // The type used to pass this argument. This is generally the original // argument type, but when a struct is passed as a scalar type, this is // that type. Note that if a struct is passed by reference, this will still @@ -4184,13 +4171,6 @@ struct CallArgABIInformation void SetByteSize(unsigned byteSize, unsigned byteAlignment, bool isStruct, bool isFloatHfa); -#if defined(DEBUG_ARG_SLOTS) - // Returns the number of "slots" used, where for this purpose a - // register counts as a slot. - unsigned GetSlotCount() const; - unsigned GetSize() const; -#endif - // Get the number of bytes that this argument is occupying on the stack, // including padding up to the target pointer size for platforms // where a stack argument can't take less. @@ -4202,11 +4182,8 @@ struct CallArgABIInformation void SetMultiRegNums(); // Return number of stack slots that this argument is taking. - // TODO-Cleanup: this function does not align with arm64 apple model, - // delete it. In most cases we just want to know if we it is using stack or not - // but in some cases we are checking if it is a multireg arg, like: - // `numRegs + GetStackSlotsNumber() > 1` that is harder to replace. - // + // This value is not meaningful on macOS arm64 where multiple arguments can + // be passed in the same stack slot. unsigned GetStackSlotsNumber() const { return roundUp(GetStackByteSize(), TARGET_POINTER_SIZE) / TARGET_POINTER_SIZE; @@ -4335,7 +4312,7 @@ class CallArgs void AddedWellKnownArg(WellKnownArg arg); void RemovedWellKnownArg(WellKnownArg arg); regNumber GetCustomRegister(Compiler* comp, CorInfoCallConvExtension cc, WellKnownArg arg); - void SplitArg(CallArg* arg, unsigned numRegs, unsigned numSlots, unsigned* nextSlotNum); + void SplitArg(CallArg* arg, unsigned numRegs, unsigned numSlots); public: CallArgs(); @@ -7216,13 +7193,6 @@ struct GenTreePutArgStk : public GenTreeUnOp #endif public: -#if defined(DEBUG_ARG_SLOTS) - unsigned gtSlotNum; // Slot number of the argument to be passed on stack -#if defined(FEATURE_PUT_STRUCT_ARG_STK) - unsigned gtNumSlots; // Number of slots for the argument to be passed on stack -#endif -#endif - #if defined(UNIX_X86_ABI) unsigned gtPadAlign; // Number of padding slots for stack alignment #endif @@ -7256,12 +7226,6 @@ struct GenTreePutArgStk : public GenTreeUnOp unsigned stackByteOffset, #if defined(FEATURE_PUT_STRUCT_ARG_STK) unsigned stackByteSize, -#endif -#if defined(DEBUG_ARG_SLOTS) - unsigned slotNum, -#if defined(FEATURE_PUT_STRUCT_ARG_STK) - unsigned numSlots, -#endif #endif GenTreeCall* callNode, bool putInIncomingArgArea) @@ -7270,12 +7234,6 @@ struct GenTreePutArgStk : public GenTreeUnOp #if defined(FEATURE_PUT_STRUCT_ARG_STK) , m_byteSize(stackByteSize) #endif -#if defined(DEBUG_ARG_SLOTS) - , gtSlotNum(slotNum) -#if defined(FEATURE_PUT_STRUCT_ARG_STK) - , gtNumSlots(numSlots) -#endif -#endif #if defined(UNIX_X86_ABI) , gtPadAlign(0) #endif @@ -7289,10 +7247,6 @@ struct GenTreePutArgStk : public GenTreeUnOp , gtPutArgStkKind(Kind::Invalid) #endif { - DEBUG_ARG_SLOTS_ASSERT(m_byteOffset == slotNum * TARGET_POINTER_SIZE); -#if defined(FEATURE_PUT_STRUCT_ARG_STK) - DEBUG_ARG_SLOTS_ASSERT(m_byteSize == gtNumSlots * TARGET_POINTER_SIZE); -#endif } GenTree*& Data() @@ -7317,8 +7271,6 @@ struct GenTreePutArgStk : public GenTreeUnOp unsigned getArgOffset() const { - DEBUG_ARG_SLOTS_ASSERT(m_byteOffset / TARGET_POINTER_SIZE == gtSlotNum); - DEBUG_ARG_SLOTS_ASSERT(m_byteOffset % TARGET_POINTER_SIZE == 0); return m_byteOffset; } @@ -7372,12 +7324,6 @@ struct GenTreePutArgSplit : public GenTreePutArgStk unsigned stackByteOffset, #if defined(FEATURE_PUT_STRUCT_ARG_STK) unsigned stackByteSize, -#endif -#if defined(DEBUG_ARG_SLOTS) - unsigned slotNum, -#if defined(FEATURE_PUT_STRUCT_ARG_STK) - unsigned numSlots, -#endif #endif unsigned numRegs, GenTreeCall* callNode, @@ -7388,12 +7334,6 @@ struct GenTreePutArgSplit : public GenTreePutArgStk stackByteOffset, #if defined(FEATURE_PUT_STRUCT_ARG_STK) stackByteSize, -#endif -#if defined(DEBUG_ARG_SLOTS) - slotNum, -#if defined(FEATURE_PUT_STRUCT_ARG_STK) - numSlots, -#endif #endif callNode, putIncomingArgArea) diff --git a/src/coreclr/jit/jit.h b/src/coreclr/jit/jit.h index 46945ed7eae7f1..d4ea7ab0dcb910 100644 --- a/src/coreclr/jit/jit.h +++ b/src/coreclr/jit/jit.h @@ -267,23 +267,6 @@ #define UNIX_LOONGARCH64_ONLY(x) #endif // TARGET_LOONGARCH64 -#if defined(DEBUG) -#define DEBUG_ARG_SLOTS -#endif - -#if defined(DEBUG_ARG_SLOTS) -#define DEBUG_ARG_SLOTS_ARG(x) , x -#define DEBUG_ARG_SLOTS_ONLY(x) x -// On all platforms except Arm64 OSX arguments on the stack are taking -// register size slots. On these platforms we could check that stack slots count -// matches our new byte size calculations. -#define DEBUG_ARG_SLOTS_ASSERT(x) assert(compMacOsArm64Abi() || (x)) -#else -#define DEBUG_ARG_SLOTS_ARG(x) -#define DEBUG_ARG_SLOTS_ONLY(x) -#define DEBUG_ARG_SLOTS_ASSERT(x) -#endif - #if defined(UNIX_AMD64_ABI) || !defined(TARGET_64BIT) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) #define FEATURE_PUT_STRUCT_ARG_STK 1 #endif diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index c7780ffad463fa..16d6111ad812d6 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -1106,20 +1106,14 @@ GenTree* Lowering::NewPutArg(GenTreeCall* call, GenTree* arg, CallArg* callArg, #endif // TARGET_ARM } - const unsigned slotNumber = callArg->AbiInfo.ByteOffset / TARGET_POINTER_SIZE; - DEBUG_ARG_SLOTS_ASSERT(slotNumber == callArg->AbiInfo.SlotNum); - const bool putInIncomingArgArea = call->IsFastTailCall(); - - putArg = new (comp, GT_PUTARG_SPLIT) - GenTreePutArgSplit(arg, callArg->AbiInfo.ByteOffset, -#if defined(DEBUG_ARG_SLOTS) && defined(FEATURE_PUT_STRUCT_ARG_STK) - callArg->AbiInfo.GetStackByteSize(), slotNumber, callArg->AbiInfo.GetStackSlotsNumber(), -#elif defined(DEBUG_ARG_SLOTS) && !defined(FEATURE_PUT_STRUCT_ARG_STK) - slotNumber, -#elif !defined(DEBUG_ARG_SLOTS) && defined(FEATURE_PUT_STRUCT_ARG_STK) - callArg->AbiInfo.GetStackByteSize(), + const unsigned slotNumber = callArg->AbiInfo.ByteOffset / TARGET_POINTER_SIZE; + const bool putInIncomingArgArea = call->IsFastTailCall(); + + putArg = new (comp, GT_PUTARG_SPLIT) GenTreePutArgSplit(arg, callArg->AbiInfo.ByteOffset, +#ifdef FEATURE_PUT_STRUCT_ARG_STK + callArg->AbiInfo.GetStackByteSize(), #endif - callArg->AbiInfo.NumRegs, call, putInIncomingArgArea); + callArg->AbiInfo.NumRegs, call, putInIncomingArgArea); // If struct argument is morphed to GT_FIELD_LIST node(s), // we can know GC info by type of each GT_FIELD_LIST node. // So we skip setting GC Pointer info. @@ -1240,12 +1234,7 @@ GenTree* Lowering::NewPutArg(GenTreeCall* call, GenTree* arg, CallArg* callArg, putArg = new (comp, GT_PUTARG_STK) GenTreePutArgStk(GT_PUTARG_STK, TYP_VOID, arg, callArg->AbiInfo.ByteOffset, -#if defined(DEBUG_ARG_SLOTS) && defined(FEATURE_PUT_STRUCT_ARG_STK) - callArg->AbiInfo.GetStackByteSize(), slotNumber, - callArg->AbiInfo.GetStackSlotsNumber(), -#elif defined(DEBUG_ARG_SLOTS) && !defined(FEATURE_PUT_STRUCT_ARG_STK) - slotNumber, -#elif !defined(DEBUG_ARG_SLOTS) && defined(FEATURE_PUT_STRUCT_ARG_STK) +#ifdef FEATURE_PUT_STRUCT_ARG_STK callArg->AbiInfo.GetStackByteSize(), #endif call, putInIncomingArgArea); @@ -1447,7 +1436,7 @@ void Lowering::LowerArg(GenTreeCall* call, CallArg* callArg, bool late) // For longs, we will replace the GT_LONG with a GT_FIELD_LIST, and put that under a PUTARG_STK. // Although the hi argument needs to be pushed first, that will be handled by the general case, // in which the fields will be reversed. - assert(callArg->AbiInfo.NumSlots == 2); + assert(callArg->AbiInfo.GetStackSlotsNumber() == 2); newArg->SetRegNum(REG_STK); BlockRange().InsertBefore(arg, fieldList, newArg); } diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 4857455f0c42b6..b3d6cf6b57439b 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -648,13 +648,7 @@ void CallArg::Dump(Compiler* comp) } if (AbiInfo.GetStackByteSize() > 0) { -#if defined(DEBUG_ARG_SLOTS) - printf(", numSlots=%u, slotNum=%u, byteSize=%u, byteOffset=%u", AbiInfo.NumSlots, AbiInfo.SlotNum, - AbiInfo.ByteSize, AbiInfo.ByteOffset); -#else printf(", byteSize=%u, byteOffset=%u", AbiInfo.ByteSize, AbiInfo.ByteOffset); - -#endif } printf(", byteAlignment=%u", AbiInfo.ByteAlignment); if (GetLateNode() != nullptr) @@ -710,9 +704,8 @@ void CallArg::Dump(Compiler* comp) // arg - The argument. // numRegs - The number of registers that will be used. // numSlots - The number of stack slots that will be used. -// nextSlotNum - Pointer to current stack slot, used for debugging purposes. // -void CallArgs::SplitArg(CallArg* arg, unsigned numRegs, unsigned numSlots, unsigned* nextSlotNum) +void CallArgs::SplitArg(CallArg* arg, unsigned numRegs, unsigned numSlots) { assert(numRegs > 0); assert(numSlots > 0); @@ -721,19 +714,15 @@ void CallArgs::SplitArg(CallArg* arg, unsigned numRegs, unsigned numSlots, unsig { assert(arg->AbiInfo.IsSplit() == true); assert(arg->AbiInfo.NumRegs == numRegs); - DEBUG_ARG_SLOTS_ONLY(assert(arg->AbiInfo.NumSlots == numSlots);) assert(m_hasStackArgs); } else { arg->AbiInfo.SetSplit(true); - arg->AbiInfo.NumRegs = numRegs; - DEBUG_ARG_SLOTS_ONLY(arg->AbiInfo.NumSlots = numSlots;) + arg->AbiInfo.NumRegs = numRegs; arg->AbiInfo.ByteOffset = 0; m_hasStackArgs = true; } - // TODO-Cleanup: structs are aligned to 8 bytes on arm64 apple, so it would work, but pass the precise size. - *nextSlotNum += numSlots; m_nextStackByteOffset += numSlots * TARGET_POINTER_SIZE; } @@ -1924,7 +1913,6 @@ void CallArgs::AddFinalArgsAndDetermineABIInfo(Compiler* comp, GenTreeCall* call unsigned argIndex = 0; unsigned intArgRegNum = 0; unsigned fltArgRegNum = 0; - unsigned nextSlotNum = INIT_ARG_STACK_SLOT; bool callHasRetBuffArg = HasRetBuffer(); bool callIsVararg = IsVarArgs(); @@ -2969,7 +2957,7 @@ void CallArgs::AddFinalArgsAndDetermineABIInfo(Compiler* comp, GenTreeCall* call (argx->gtOper == GT_COMMA && (argx->gtFlags & GTF_ASG))); unsigned numRegsPartial = MAX_REG_ARG - intArgRegNum; assert((unsigned char)numRegsPartial == numRegsPartial); - SplitArg(&arg, numRegsPartial, size - numRegsPartial, &nextSlotNum); + SplitArg(&arg, numRegsPartial, size - numRegsPartial); } #endif // FEATURE_ARG_SPLIT @@ -3004,20 +2992,7 @@ void CallArgs::AddFinalArgsAndDetermineABIInfo(Compiler* comp, GenTreeCall* call // This is a stack argument m_hasStackArgs = true; arg.AbiInfo.SetRegNum(0, REG_STK); - m_nextStackByteOffset = roundUp(m_nextStackByteOffset, argAlignBytes); - -#ifdef DEBUG_ARG_SLOTS - arg.AbiInfo.NumSlots = size; - - if (!compMacOsArm64Abi()) - { - nextSlotNum = roundUp(nextSlotNum, argAlignBytes / TARGET_POINTER_SIZE); - } - DEBUG_ARG_SLOTS_ASSERT(m_nextStackByteOffset / TARGET_POINTER_SIZE == nextSlotNum); - - arg.AbiInfo.SlotNum = nextSlotNum; - nextSlotNum += size; -#endif + m_nextStackByteOffset = roundUp(m_nextStackByteOffset, argAlignBytes); arg.AbiInfo.ByteOffset = m_nextStackByteOffset; arg.AbiInfo.SetByteSize(byteSize, argAlignBytes, isStructArg, isFloatHfa); @@ -3054,17 +3029,6 @@ void CallArgs::AddFinalArgsAndDetermineABIInfo(Compiler* comp, GenTreeCall* call argIndex++; } // end foreach argument loop -#ifdef DEBUG - -#if defined(DEBUG_ARG_SLOTS) - if (!compMacOsArm64Abi()) - { - assert(AlignUp(m_nextStackByteOffset, TARGET_POINTER_SIZE) == nextSlotNum * REGSIZE_BYTES); - } -#endif - -#endif - #ifdef DEBUG if (VERBOSE) { @@ -3155,8 +3119,6 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* call) { GenTreeFlags flagsSummary = GTF_EMPTY; - DEBUG_ARG_SLOTS_ONLY(unsigned argSlots = 0;) - bool reMorphing = call->gtArgs.AreArgsComplete(); call->gtArgs.AddFinalArgsAndDetermineABIInfo(this, call); @@ -3200,29 +3162,15 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* call) } } - DEBUG_ARG_SLOTS_ONLY(unsigned size = arg.AbiInfo.GetSize();) CORINFO_CLASS_HANDLE copyBlkClass = NO_CLASS_HANDLE; -#if defined(DEBUG_ARG_SLOTS) - if (!compMacOsArm64Abi()) - { - if (arg.AbiInfo.ByteAlignment == 2 * TARGET_POINTER_SIZE) - { - if (argSlots % 2 == 1) - { - argSlots++; - } - } - } -#endif // DEBUG // TODO-ARGS: Review this, is it really necessary to treat them specially here? if (call->gtArgs.IsNonStandard(this, call, &arg) && arg.AbiInfo.IsPassedInRegisters()) { flagsSummary |= argx->gtFlags; continue; } - DEBUG_ARG_SLOTS_ASSERT(size != 0); - DEBUG_ARG_SLOTS_ONLY(argSlots += arg.AbiInfo.GetSlotCount();) + assert(arg.AbiInfo.ByteSize > 0); // For pointers to locals we can skip reporting GC info and also skip // zero initialization. @@ -3273,7 +3221,7 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* call) // First, handle the case where the argument is passed by reference. if (arg.AbiInfo.PassedByRef) { - DEBUG_ARG_SLOTS_ASSERT(size == 1); + assert(arg.AbiInfo.ByteSize == TARGET_POINTER_SIZE); copyBlkClass = objClass; #ifdef UNIX_AMD64_ABI assert(!"Structs are not passed by reference on x64/ux"); @@ -3281,17 +3229,6 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* call) } else // This is passed by value. { -#if defined(TARGET_LOONGARCH64) - // For LoongArch64 the struct {float a; float b;} can be passed by two float registers. - DEBUG_ARG_SLOTS_ASSERT((size == roundupSize / TARGET_POINTER_SIZE) || - ((structBaseType == TYP_STRUCT) && (originalSize == TARGET_POINTER_SIZE) && - (size == 2) && (size == arg.AbiInfo.NumRegs))); -#else - // Check to see if we can transform this into load of a primitive type. - // 'size' must be the number of pointer sized items - DEBUG_ARG_SLOTS_ASSERT(size == roundupSize / TARGET_POINTER_SIZE); -#endif - structSize = originalSize; unsigned passingSize = originalSize; @@ -3331,7 +3268,7 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* call) #ifndef UNIX_AMD64_ABI // On Windows structs are always copied and passed by reference (handled above) unless they are // passed by value in a single register. - assert(size == 1); + assert(arg.AbiInfo.GetStackSlotsNumber() == 1); copyBlkClass = objClass; #else // UNIX_AMD64_ABI // On Unix, structs are always passed by value. @@ -3387,14 +3324,6 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* call) // We have a struct argument that fits into a register, and it is either a power of 2, // or a local. // Change our argument, as needed, into a value of the appropriate type. - CLANG_FORMAT_COMMENT_ANCHOR; -#ifdef TARGET_ARM - DEBUG_ARG_SLOTS_ASSERT((size == 1) || ((structBaseType == TYP_DOUBLE) && (size == 2))); -#else - DEBUG_ARG_SLOTS_ASSERT((size == 1) || (varTypeIsSIMD(structBaseType) && - size == (genTypeSize(structBaseType) / REGSIZE_BYTES))); -#endif - assert((structBaseType != TYP_STRUCT) && (genTypeSize(structBaseType) >= originalSize)); if (argObj->OperIs(GT_OBJ)) @@ -3496,8 +3425,6 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* call) // If the valuetype size is not a multiple of TARGET_POINTER_SIZE, // we must copyblk to a temp before doing the obj to avoid // the obj reading memory past the end of the valuetype - CLANG_FORMAT_COMMENT_ANCHOR; - if (roundupSize > originalSize) { copyBlkClass = objClass; @@ -3573,7 +3500,7 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* call) #ifdef TARGET_ARM else if ((arg.AbiInfo.ArgType == TYP_LONG) || (arg.AbiInfo.ArgType == TYP_DOUBLE)) { - assert((arg.AbiInfo.NumRegs == 2) || (arg.AbiInfo.NumSlots == 2)); + assert((arg.AbiInfo.NumRegs == 2) || (arg.AbiInfo.GetStackSlotsNumber() == 2)); } #endif else diff --git a/src/coreclr/jit/stacklevelsetter.cpp b/src/coreclr/jit/stacklevelsetter.cpp index decbec79de4d40..d139832f93652a 100644 --- a/src/coreclr/jit/stacklevelsetter.cpp +++ b/src/coreclr/jit/stacklevelsetter.cpp @@ -251,7 +251,7 @@ unsigned StackLevelSetter::PopArgumentsFromCall(GenTreeCall* call) GenTreePutArgStk* putArg = node->AsPutArgStk(); #if !FEATURE_FIXED_OUT_ARGS - assert(slotCount == putArg->gtNumSlots); + assert((slotCount * TARGET_POINTER_SIZE) == putArg->GetStackByteSize()); #endif // !FEATURE_FIXED_OUT_ARGS putArgNumSlots.Set(putArg, slotCount);