Skip to content

Commit

Permalink
JIT: Deduplicate CodeGen::genJumpTable (dotnet#99110)
Browse files Browse the repository at this point in the history
Moving same code used across all architectures to common codegen should simplify things
and reduce possibility of future regressions as noted in dotnet#98992.
  • Loading branch information
yurai007 committed Feb 29, 2024
1 parent 0eb3a6f commit 24a9ec6
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 132 deletions.
1 change: 1 addition & 0 deletions src/coreclr/jit/codegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -1260,6 +1260,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
void genCodeForInitBlkLoop(GenTreeBlk* initBlkNode);
void genCodeForInitBlkRepStos(GenTreeBlk* initBlkNode);
void genCodeForInitBlkUnroll(GenTreeBlk* initBlkNode);
unsigned genEmitJumpTable(GenTree* treeNode, bool relativeAddr);
void genJumpTable(GenTree* tree);
void genTableBasedSwitch(GenTree* tree);
#if defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
Expand Down
25 changes: 1 addition & 24 deletions src/coreclr/jit/codegenarm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -647,30 +647,7 @@ void CodeGen::genTableBasedSwitch(GenTree* treeNode)
//
void CodeGen::genJumpTable(GenTree* treeNode)
{
noway_assert(compiler->compCurBB->KindIs(BBJ_SWITCH));
assert(treeNode->OperGet() == GT_JMPTABLE);

unsigned jumpCount = compiler->compCurBB->GetSwitchTargets()->bbsCount;
FlowEdge** jumpTable = compiler->compCurBB->GetSwitchTargets()->bbsDstTab;
unsigned jmpTabBase;

jmpTabBase = GetEmitter()->emitBBTableDataGenBeg(jumpCount, false);

JITDUMP("\n J_M%03u_DS%02u LABEL DWORD\n", compiler->compMethodID, jmpTabBase);

for (unsigned i = 0; i < jumpCount; i++)
{
BasicBlock* target = (*jumpTable)->getDestinationBlock();
jumpTable++;
noway_assert(target->HasFlag(BBF_HAS_LABEL));

JITDUMP(" DD L_M%03u_" FMT_BB "\n", compiler->compMethodID, target->bbNum);

GetEmitter()->emitDataGenData(i, target);
}

GetEmitter()->emitDataGenEnd();

unsigned jmpTabBase = genEmitJumpTable(treeNode, false);
genMov32RelocatableDataLabel(jmpTabBase, treeNode->GetRegNum());

genProduceReg(treeNode);
Expand Down
28 changes: 1 addition & 27 deletions src/coreclr/jit/codegenarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3750,33 +3750,7 @@ void CodeGen::genTableBasedSwitch(GenTree* treeNode)
// emits the table and an instruction to get the address of the first element
void CodeGen::genJumpTable(GenTree* treeNode)
{
noway_assert(compiler->compCurBB->KindIs(BBJ_SWITCH));
assert(treeNode->OperGet() == GT_JMPTABLE);

unsigned jumpCount = compiler->compCurBB->GetSwitchTargets()->bbsCount;
FlowEdge** jumpTable = compiler->compCurBB->GetSwitchTargets()->bbsDstTab;
unsigned jmpTabOffs;
unsigned jmpTabBase;

jmpTabBase = GetEmitter()->emitBBTableDataGenBeg(jumpCount, true);

jmpTabOffs = 0;

JITDUMP("\n J_M%03u_DS%02u LABEL DWORD\n", compiler->compMethodID, jmpTabBase);

for (unsigned i = 0; i < jumpCount; i++)
{
BasicBlock* target = (*jumpTable)->getDestinationBlock();
jumpTable++;
noway_assert(target->HasFlag(BBF_HAS_LABEL));

JITDUMP(" DD L_M%03u_" FMT_BB "\n", compiler->compMethodID, target->bbNum);

GetEmitter()->emitDataGenData(i, target);
};

GetEmitter()->emitDataGenEnd();

unsigned jmpTabBase = genEmitJumpTable(treeNode, true);
// Access to inline data is 'abstracted' by a special type of static member
// (produced by eeFindJitDataOffs) which the emitter recognizes as being a reference
// to constant data, not a real static field.
Expand Down
41 changes: 41 additions & 0 deletions src/coreclr/jit/codegencommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6452,6 +6452,47 @@ void CodeGen::genFnProlog()
#pragma warning(pop)
#endif

//----------------------------------------------------------------------------------
// genEmitJumpTable: emit jump table and return its base offset
//
// Arguments:
// treeNode - the GT_JMPTABLE node
// relativeAddr - if true, references are treated as 4-byte relative addresses,
// otherwise they are absolute pointers
//
// Return Value:
// base offset to jump table
//
// Assumption:
// The current basic block in process ends with a switch statement
//
unsigned CodeGen::genEmitJumpTable(GenTree* treeNode, bool relativeAddr)
{
noway_assert(compiler->compCurBB->KindIs(BBJ_SWITCH));
assert(treeNode->OperGet() == GT_JMPTABLE);

emitter* emit = GetEmitter();
const unsigned jumpCount = compiler->compCurBB->GetSwitchTargets()->bbsCount;
FlowEdge** jumpTable = compiler->compCurBB->GetSwitchTargets()->bbsDstTab;
const unsigned jmpTabBase = emit->emitBBTableDataGenBeg(jumpCount, relativeAddr);

JITDUMP("\n J_M%03u_DS%02u LABEL DWORD\n", compiler->compMethodID, jmpTabBase);

for (unsigned i = 0; i < jumpCount; i++)
{
BasicBlock* target = (*jumpTable)->getDestinationBlock();
jumpTable++;
noway_assert(target->HasFlag(BBF_HAS_LABEL));

JITDUMP(" DD L_M%03u_" FMT_BB "\n", compiler->compMethodID, target->bbNum);

emit->emitDataGenData(i, target);
};

emit->emitDataGenEnd();
return jmpTabBase;
}

//------------------------------------------------------------------------
// getCallTarget - Get the node that evaluates to the call target
//
Expand Down
28 changes: 1 addition & 27 deletions src/coreclr/jit/codegenloongarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2927,33 +2927,7 @@ void CodeGen::genTableBasedSwitch(GenTree* treeNode)
// emits the table and an instruction to get the address of the first element
void CodeGen::genJumpTable(GenTree* treeNode)
{
noway_assert(compiler->compCurBB->KindIs(BBJ_SWITCH));
assert(treeNode->OperGet() == GT_JMPTABLE);

unsigned jumpCount = compiler->compCurBB->GetSwitchTargets()->bbsCount;
FlowEdge** jumpTable = compiler->compCurBB->GetSwitchTargets()->bbsDstTab;
unsigned jmpTabOffs;
unsigned jmpTabBase;

jmpTabBase = GetEmitter()->emitBBTableDataGenBeg(jumpCount, true);

jmpTabOffs = 0;

JITDUMP("\n J_M%03u_DS%02u LABEL DWORD\n", compiler->compMethodID, jmpTabBase);

for (unsigned i = 0; i < jumpCount; i++)
{
BasicBlock* target = (*jumpTable)->getDestinationBlock();
jumpTable++;
noway_assert(target->HasFlag(BBF_HAS_LABEL));

JITDUMP(" DD L_M%03u_" FMT_BB "\n", compiler->compMethodID, target->bbNum);

GetEmitter()->emitDataGenData(i, target);
};

GetEmitter()->emitDataGenEnd();

unsigned jmpTabBase = genEmitJumpTable(treeNode, true);
// Access to inline data is 'abstracted' by a special type of static member
// (produced by eeFindJitDataOffs) which the emitter recognizes as being a reference
// to constant data, not a real static field.
Expand Down
28 changes: 1 addition & 27 deletions src/coreclr/jit/codegenriscv64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2850,33 +2850,7 @@ void CodeGen::genTableBasedSwitch(GenTree* treeNode)
// emits the table and an instruction to get the address of the first element
void CodeGen::genJumpTable(GenTree* treeNode)
{
noway_assert(compiler->compCurBB->KindIs(BBJ_SWITCH));
assert(treeNode->OperGet() == GT_JMPTABLE);

unsigned jumpCount = compiler->compCurBB->GetSwitchTargets()->bbsCount;
FlowEdge** jumpTable = compiler->compCurBB->GetSwitchTargets()->bbsDstTab;
unsigned jmpTabOffs;
unsigned jmpTabBase;

jmpTabBase = GetEmitter()->emitBBTableDataGenBeg(jumpCount, true);

jmpTabOffs = 0;

JITDUMP("\n J_M%03u_DS%02u LABEL DWORD\n", compiler->compMethodID, jmpTabBase);

for (unsigned i = 0; i < jumpCount; i++)
{
BasicBlock* target = (*jumpTable)->getDestinationBlock();
jumpTable++;
noway_assert(target->HasFlag(BBF_HAS_LABEL));

JITDUMP(" DD L_M%03u_" FMT_BB "\n", compiler->compMethodID, target->bbNum);

GetEmitter()->emitDataGenData(i, target);
};

GetEmitter()->emitDataGenEnd();

unsigned jmpTabBase = genEmitJumpTable(treeNode, true);
// Access to inline data is 'abstracted' by a special type of static member
// (produced by eeFindJitDataOffs) which the emitter recognizes as being a reference
// to constant data, not a real static field.
Expand Down
28 changes: 1 addition & 27 deletions src/coreclr/jit/codegenxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4303,33 +4303,7 @@ void CodeGen::genTableBasedSwitch(GenTree* treeNode)
// emits the table and an instruction to get the address of the first element
void CodeGen::genJumpTable(GenTree* treeNode)
{
noway_assert(compiler->compCurBB->KindIs(BBJ_SWITCH));
assert(treeNode->OperGet() == GT_JMPTABLE);

unsigned jumpCount = compiler->compCurBB->GetSwitchTargets()->bbsCount;
FlowEdge** jumpTable = compiler->compCurBB->GetSwitchTargets()->bbsDstTab;
unsigned jmpTabOffs;
unsigned jmpTabBase;

jmpTabBase = GetEmitter()->emitBBTableDataGenBeg(jumpCount, true);

jmpTabOffs = 0;

JITDUMP("\n J_M%03u_DS%02u LABEL DWORD\n", compiler->compMethodID, jmpTabBase);

for (unsigned i = 0; i < jumpCount; i++)
{
BasicBlock* target = (*jumpTable)->getDestinationBlock();
jumpTable++;
noway_assert(target->HasFlag(BBF_HAS_LABEL));

JITDUMP(" DD L_M%03u_" FMT_BB "\n", compiler->compMethodID, target->bbNum);

GetEmitter()->emitDataGenData(i, target);
};

GetEmitter()->emitDataGenEnd();

unsigned jmpTabBase = genEmitJumpTable(treeNode, true);
// Access to inline data is 'abstracted' by a special type of static member
// (produced by eeFindJitDataOffs) which the emitter recognizes as being a reference
// to constant data, not a real static field.
Expand Down

0 comments on commit 24a9ec6

Please sign in to comment.