From: Hyeongseok Oh Date: Fri, 30 Jun 2017 01:02:43 +0000 (+0900) Subject: [ARM32/RyuJIT] Lowering: enable passing split struct less than 16 bytes X-Git-Tag: submit/tizen/20210909.063632~11030^2~6925^2~297^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1966dc0e8209616027aaf9b4417d5914c23485be;p=platform%2Fupstream%2Fdotnet%2Fruntime.git [ARM32/RyuJIT] Lowering: enable passing split struct less than 16 bytes - Enable passing split struct (less than 16 bytes) in registers and on stack morphing phase Lowering phase - Block at LSRA phase - add NYI_ARM - Print split struct Commit migrated from https://github.com/dotnet/coreclr/commit/049c9d4f5325478d6e4df762424d8d49c7963427 --- diff --git a/src/coreclr/src/jit/gentree.cpp b/src/coreclr/src/jit/gentree.cpp index ace7e13..bf2a873 100644 --- a/src/coreclr/src/jit/gentree.cpp +++ b/src/coreclr/src/jit/gentree.cpp @@ -11342,6 +11342,68 @@ void Compiler::gtGetLateArgMsg( { sprintf_s(bufp, bufLength, "this in %s%c", compRegVarName(argReg), 0); } +#ifdef _TARGET_ARM_ + else if (curArgTabEntry->isSplit) + { + regNumber firstReg = curArgTabEntry->regNum; + unsigned argNum = curArgTabEntry->argNum; + if (listCount == -1) + { + if (curArgTabEntry->numRegs == 1) + { + sprintf_s(bufp, bufLength, "arg%d %s out+%02x%c", argNum, compRegVarName(firstReg), + (curArgTabEntry->slotNum) * TARGET_POINTER_SIZE, 0); + } + else + { + regNumber lastReg = REG_STK; + char separator = (curArgTabEntry->numRegs == 2) ? ',' : '-'; + if (curArgTabEntry->isHfaRegArg) + { + unsigned lastRegNum = genMapFloatRegNumToRegArgNum(firstReg) + curArgTabEntry->numRegs - 1; + lastReg = genMapFloatRegArgNumToRegNum(lastRegNum); + } + else + { + unsigned lastRegNum = genMapIntRegNumToRegArgNum(firstReg) + curArgTabEntry->numRegs - 1; + lastReg = genMapIntRegArgNumToRegNum(lastRegNum); + } + sprintf_s(bufp, bufLength, "arg%d %s%c%s out+%02x%c", argNum, compRegVarName(firstReg), separator, + compRegVarName(lastReg), (curArgTabEntry->slotNum) * TARGET_POINTER_SIZE, 0); + } + } + else + { + unsigned curArgNum = BAD_VAR_NUM; + bool isFloat = curArgTabEntry->isHfaRegArg; + if (isFloat) + { + curArgNum = genMapFloatRegNumToRegArgNum(firstReg) + listCount; + } + else + { + curArgNum = genMapIntRegNumToRegArgNum(firstReg) + listCount; + } + + if (!isFloat && curArgNum < MAX_REG_ARG) + { + regNumber curReg = genMapIntRegArgNumToRegNum(curArgNum); + sprintf_s(bufp, bufLength, "arg%d m%d %s%c", argNum, listCount, compRegVarName(curReg), 0); + } + else if (isFloat && curArgNum < MAX_FLOAT_REG_ARG) + { + regNumber curReg = genMapFloatRegArgNumToRegNum(curArgNum); + sprintf_s(bufp, bufLength, "arg%d m%d %s%c", argNum, listCount, compRegVarName(curReg), 0); + } + else + { + unsigned stackSlot = listCount - curArgTabEntry->numRegs; + sprintf_s(bufp, bufLength, "arg%d m%d out+%s%c", argNum, listCount, stackSlot, 0); + } + } + return; + } +#endif // _TARGET_ARM_ else { #if FEATURE_MULTIREG_ARGS diff --git a/src/coreclr/src/jit/lower.cpp b/src/coreclr/src/jit/lower.cpp index 0479b78..7b95b75 100644 --- a/src/coreclr/src/jit/lower.cpp +++ b/src/coreclr/src/jit/lower.cpp @@ -831,26 +831,56 @@ GenTreePtr Lowering::NewPutArg(GenTreeCall* call, GenTreePtr arg, fgArgTabEntryP // Struct can be split into register(s) and stack on ARM if (info->isSplit) { - if (arg->OperGet() != GT_OBJ) + assert(arg->OperGet() == GT_OBJ || arg->OperGet() == GT_FIELD_LIST); + // TODO: Need to check correctness for FastTailCall + if (call->IsFastTailCall()) { - NYI_ARM("Lowering: Oper for struct argument is not GT_OBJ"); + NYI_ARM("lower: struct argument by fast tail call"); } putArg = new (comp, GT_PUTARG_SPLIT) GenTreePutArgSplit(arg, info->slotNum PUT_STRUCT_ARG_STK_ONLY_ARG(info->numSlots), info->numRegs, info->isHfaRegArg, call->IsFastTailCall(), call); - // Set GC Pointer info + // 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. + // GenTreePutArgSplit* argSplit = putArg->AsPutArgSplit(); - BYTE* gcLayout = new (comp, CMK_Codegen) BYTE[info->numSlots + info->numRegs]; - unsigned numRefs = comp->info.compCompHnd->getClassGClayout(arg->gtObj.gtClass, gcLayout); - argSplit->setGcPointers(numRefs, gcLayout); + if (arg->OperGet() == GT_OBJ) + { + BYTE* gcLayout = nullptr; + unsigned numRefs = 0; + GenTreeObj* argObj = arg->AsObj(); + + if (argObj->IsGCInfoInitialized()) + { + gcLayout = argObj->gtGcPtrs; + numRefs = argObj->GetGcPtrCount(); + } + else + { + // Set GC Pointer info + gcLayout = new (comp, CMK_Codegen) BYTE[info->numSlots + info->numRegs]; + numRefs = comp->info.compCompHnd->getClassGClayout(arg->gtObj.gtClass, gcLayout); + argSplit->setGcPointers(numRefs, gcLayout); + } - // Set type of registers - for (unsigned index = 0; index < info->numRegs; index++) + // Set type of registers + for (unsigned index = 0; index < info->numRegs; index++) + { + var_types regType = comp->getJitGCType(gcLayout[index]); + argSplit->m_regType[index] = regType; + } + } + else { - var_types regType = comp->getJitGCType(gcLayout[index]); - argSplit->m_regType[index] = regType; + GenTreeFieldList* fieldListPtr = arg->AsFieldList(); + for (unsigned index = 0; index < info->numRegs; fieldListPtr = fieldListPtr->Rest(), index++) + { + var_types regType = fieldListPtr->TypeGet(); + argSplit->m_regType[index] = regType; + } } } else diff --git a/src/coreclr/src/jit/lsraarmarch.cpp b/src/coreclr/src/jit/lsraarmarch.cpp index e361478..75dc6e3 100644 --- a/src/coreclr/src/jit/lsraarmarch.cpp +++ b/src/coreclr/src/jit/lsraarmarch.cpp @@ -771,6 +771,11 @@ void Lowering::TreeNodeInfoInitPutArgSplit(GenTreePutArgSplit* argNode, TreeNode } argNode->gtLsraInfo.setDstCandidates(m_lsra, argMask); + if (putArgChild->OperGet() == GT_FIELD_LIST) + { + NYI_ARM("LSRA: Oper for split struct argument is GT_FIELD_LIST"); + } + assert(putArgChild->TypeGet() == TYP_STRUCT); assert(putArgChild->OperGet() == GT_OBJ); // We could use a ldr/str sequence so we need a internal register diff --git a/src/coreclr/src/jit/morph.cpp b/src/coreclr/src/jit/morph.cpp index 588309d..ec169a5 100644 --- a/src/coreclr/src/jit/morph.cpp +++ b/src/coreclr/src/jit/morph.cpp @@ -4769,18 +4769,13 @@ GenTreePtr Compiler::fgMorphMultiregStructArg(GenTreePtr arg, fgArgTabEntryPtr f { if (fgEntryPtr->isHfaRegArg) { - // We cannot handle split struct morphed to GT_FIELD_LIST yet + // We cannot handle HFA split struct morphed to GT_FIELD_LIST yet NYI_ARM("Struct split between float registers and stack"); } else if (fgEntryPtr->numSlots + fgEntryPtr->numRegs > 4) { return arg; } - else - { - // We cannot handle split struct morphed to GT_FIELD_LIST yet - NYI_ARM("Struct split between integer registers and stack"); - } } else if (!fgEntryPtr->isHfaRegArg && fgEntryPtr->numSlots > 4) {