Skip to content

Commit cd63792

Browse files
authored
[RISC-V] Optimize switch table (#117048)
* don't temp reg, use sh2add * don't zero-extend for shXadd
1 parent e18042e commit cd63792

File tree

3 files changed

+17
-8
lines changed

3 files changed

+17
-8
lines changed

src/coreclr/jit/codegenriscv64.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2187,16 +2187,25 @@ void CodeGen::genTableBasedSwitch(GenTree* treeNode)
21872187
regNumber idxReg = treeNode->AsOp()->gtOp1->GetRegNum();
21882188
regNumber baseReg = treeNode->AsOp()->gtOp2->GetRegNum();
21892189

2190-
regNumber tmpReg = internalRegisters.GetSingle(treeNode);
2191-
21922190
// load the ip-relative offset (which is relative to start of fgFirstBB)
2193-
GetEmitter()->emitIns_R_R_I(INS_slli, EA_8BYTE, tmpReg, idxReg, 2);
2194-
GetEmitter()->emitIns_R_R_R(INS_add, EA_8BYTE, baseReg, baseReg, tmpReg);
2191+
assert(treeNode->gtGetOp2()->TypeIs(TYP_I_IMPL));
2192+
if (compiler->compOpportunisticallyDependsOn(InstructionSet_Zba))
2193+
{
2194+
emitAttr idxSize = emitTypeSize(treeNode->gtGetOp1());
2195+
instruction sh2add = (idxSize == EA_4BYTE) ? INS_sh2add_uw : INS_sh2add;
2196+
GetEmitter()->emitIns_R_R_R(sh2add, idxSize, baseReg, idxReg, baseReg);
2197+
}
2198+
else
2199+
{
2200+
assert(treeNode->gtGetOp1()->TypeIs(TYP_I_IMPL));
2201+
GetEmitter()->emitIns_R_R_I(INS_slli, EA_8BYTE, idxReg, idxReg, 2);
2202+
GetEmitter()->emitIns_R_R_R(INS_add, EA_8BYTE, baseReg, baseReg, idxReg);
2203+
}
21952204
GetEmitter()->emitIns_R_R_I(INS_lw, EA_4BYTE, baseReg, baseReg, 0);
21962205

21972206
// add it to the absolute address of fgFirstBB
2198-
GetEmitter()->emitIns_R_L(INS_lea, EA_PTRSIZE, compiler->fgFirstBB, tmpReg);
2199-
GetEmitter()->emitIns_R_R_R(INS_add, EA_PTRSIZE, baseReg, baseReg, tmpReg);
2207+
GetEmitter()->emitIns_R_L(INS_lea, EA_PTRSIZE, compiler->fgFirstBB, idxReg);
2208+
GetEmitter()->emitIns_R_R_R(INS_add, EA_PTRSIZE, baseReg, baseReg, idxReg);
22002209

22012210
// jr baseReg
22022211
GetEmitter()->emitIns_R_R_I(INS_jalr, emitActualTypeSize(TYP_I_IMPL), REG_R0, baseReg, 0);

src/coreclr/jit/lower.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1222,7 +1222,8 @@ GenTree* Lowering::LowerSwitch(GenTree* node)
12221222
JITDUMP("Lowering switch " FMT_BB ": using jump table expansion\n", originalSwitchBB->bbNum);
12231223

12241224
#ifdef TARGET_64BIT
1225-
if (tempLclType != TYP_I_IMPL)
1225+
if (RISCV64_ONLY(!comp->compOpportunisticallyDependsOn(InstructionSet_Zba)&&) // shXadd.uw 0-extends index
1226+
tempLclType != TYP_I_IMPL)
12261227
{
12271228
// SWITCH_TABLE expects the switch value (the index into the jump table) to be TYP_I_IMPL.
12281229
// Note that the switch value is unsigned so the cast should be unsigned as well.

src/coreclr/jit/lsrariscv64.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,6 @@ int LinearScan::BuildNode(GenTree* tree)
226226
break;
227227

228228
case GT_SWITCH_TABLE:
229-
buildInternalIntRegisterDefForNode(tree);
230229
srcCount = BuildBinaryUses(tree->AsOp());
231230
assert(dstCount == 0);
232231
break;

0 commit comments

Comments
 (0)