From bbcde65390056b7a54b1f9e48c045f5123de5e63 Mon Sep 17 00:00:00 2001 From: Xu Liangyu Date: Sat, 25 May 2024 01:41:08 +0800 Subject: [PATCH] [LoongArch64] Synchronize with PR#102469. (#102638) --- src/coreclr/jit/lsra.h | 4 +- src/coreclr/jit/lsrabuild.cpp | 2 +- src/coreclr/jit/lsraloongarch64.cpp | 64 ++++++++++++++++++----------- 3 files changed, 43 insertions(+), 27 deletions(-) diff --git a/src/coreclr/jit/lsra.h b/src/coreclr/jit/lsra.h index 082cfe6d10d0e..5206b17884b4e 100644 --- a/src/coreclr/jit/lsra.h +++ b/src/coreclr/jit/lsra.h @@ -2014,11 +2014,11 @@ class LinearScan : public LinearScanInterface void BuildDefs(GenTree* tree, int dstCount, regMaskTP dstCandidates = RBM_NONE); void BuildCallDefs(GenTree* tree, int dstCount, regMaskTP dstCandidates); void BuildKills(GenTree* tree, regMaskTP killMask); -#if defined(TARGET_ARMARCH) || defined(TARGET_RISCV64) +#if defined(TARGET_ARMARCH) || defined(TARGET_RISCV64) || defined(TARGET_LOONGARCH64) void BuildDefWithKills(GenTree* tree, regMaskTP dstCandidates, regMaskTP killMask); #else void BuildDefWithKills(GenTree* tree, int dstCount, regMaskTP dstCandidates, regMaskTP killMask); -#endif // TARGET_ARMARCH || TARGET_RISCV64 +#endif // TARGET_ARMARCH || TARGET_RISCV64 || TARGET_LOONGARCH64 void BuildCallDefsWithKills(GenTree* tree, int dstCount, regMaskTP dstCandidates, regMaskTP killMask); int BuildReturn(GenTree* tree); diff --git a/src/coreclr/jit/lsrabuild.cpp b/src/coreclr/jit/lsrabuild.cpp index a98d972d53c4c..34b7eaa9d3a3d 100644 --- a/src/coreclr/jit/lsrabuild.cpp +++ b/src/coreclr/jit/lsrabuild.cpp @@ -3240,7 +3240,7 @@ void LinearScan::BuildKills(GenTree* tree, regMaskTP killMask) } } -#if defined(TARGET_ARMARCH) || defined(TARGET_RISCV64) +#if defined(TARGET_ARMARCH) || defined(TARGET_RISCV64) || defined(TARGET_LOONGARCH64) //------------------------------------------------------------------------ // BuildDefWithKills: Build one RefTypeDef RefPositions for the given node, diff --git a/src/coreclr/jit/lsraloongarch64.cpp b/src/coreclr/jit/lsraloongarch64.cpp index 5fda31befc69f..42dccded84fb4 100644 --- a/src/coreclr/jit/lsraloongarch64.cpp +++ b/src/coreclr/jit/lsraloongarch64.cpp @@ -130,14 +130,14 @@ int LinearScan::BuildNode(GenTree* tree) srcCount = 0; assert(dstCount == 0); killMask = getKillSetForProfilerHook(); - BuildDefsWithKills(tree, 0, RBM_NONE, killMask); + BuildKills(tree, killMask); break; case GT_START_PREEMPTGC: // This kills GC refs in callee save regs srcCount = 0; assert(dstCount == 0); - BuildDefsWithKills(tree, 0, RBM_NONE, RBM_NONE); + BuildKills(tree, RBM_NONE); break; case GT_CNS_DBL: @@ -170,7 +170,7 @@ int LinearScan::BuildNode(GenTree* tree) case GT_RETURN: srcCount = BuildReturn(tree); killMask = getKillSetForReturn(); - BuildDefsWithKills(tree, 0, RBM_NONE, killMask); + BuildKills(tree, killMask); break; case GT_RETFILT: @@ -267,7 +267,7 @@ int LinearScan::BuildNode(GenTree* tree) srcCount = 1; assert(dstCount == 0); killMask = compiler->compHelperCallKillSet(CORINFO_HELP_STOP_FOR_GC); - BuildDefsWithKills(tree, 0, RBM_NONE, killMask); + BuildKills(tree, killMask); break; case GT_MUL: @@ -679,9 +679,9 @@ int LinearScan::BuildIndir(GenTreeIndir* indirTree) // int LinearScan::BuildCall(GenTreeCall* call) { - bool hasMultiRegRetVal = false; - const ReturnTypeDesc* retTypeDesc = nullptr; - regMaskTP dstCandidates = RBM_NONE; + bool hasMultiRegRetVal = false; + const ReturnTypeDesc* retTypeDesc = nullptr; + regMaskTP singleDstCandidates = RBM_NONE; int srcCount = 0; int dstCount = 0; @@ -745,22 +745,20 @@ int LinearScan::BuildCall(GenTreeCall* call) // Set destination candidates for return value of the call. - if (hasMultiRegRetVal) + if (!hasMultiRegRetVal) { - assert(retTypeDesc != nullptr); - dstCandidates = retTypeDesc->GetABIReturnRegs(call->GetUnmanagedCallConv()); - } - else if (varTypeUsesFloatArgReg(registerType)) - { - dstCandidates = RBM_FLOATRET; - } - else if (registerType == TYP_LONG) - { - dstCandidates = RBM_LNGRET; - } - else - { - dstCandidates = RBM_INTRET; + if (varTypeUsesFloatArgReg(registerType)) + { + singleDstCandidates = RBM_FLOATRET; + } + else if (registerType == TYP_LONG) + { + singleDstCandidates = RBM_LNGRET; + } + else + { + singleDstCandidates = RBM_INTRET; + } } // First, count reg args @@ -872,7 +870,25 @@ int LinearScan::BuildCall(GenTreeCall* call) // Now generate defs and kills. regMaskTP killMask = getKillSetForCall(call); - BuildDefsWithKills(call, dstCount, dstCandidates, killMask); + if (dstCount > 0) + { + if (hasMultiRegRetVal) + { + assert(retTypeDesc != nullptr); + regMaskTP multiDstCandidates = retTypeDesc->GetABIReturnRegs(call->GetUnmanagedCallConv()); + assert(genCountBits(multiDstCandidates) > 0); + BuildCallDefsWithKills(call, dstCount, multiDstCandidates, killMask); + } + else + { + assert(dstCount == 1); + BuildDefWithKills(call, singleDstCandidates, killMask); + } + } + else + { + BuildKills(call, killMask); + } // No args are placed in registers anymore. placedArgRegs = RBM_NONE; @@ -1189,7 +1205,7 @@ int LinearScan::BuildBlockStore(GenTreeBlk* blkNode) buildInternalRegisterUses(); regMaskTP killMask = getKillSetForBlockStore(blkNode); - BuildDefsWithKills(blkNode, 0, RBM_NONE, killMask); + BuildKills(blkNode, killMask); return useCount; }