Skip to content

Commit 4087b87

Browse files
authored
[RISCV][GISel] Move G_BRJT expansion to legalization (#73711)
Instead of custom selecting a bunch of instructions, we can expand to generic MIR during legalization.
1 parent 4acf935 commit 4087b87

13 files changed

+458
-811
lines changed

llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -581,8 +581,6 @@ static void getOperandsForBranch(Register CondReg, RISCVCC::CondCode &CC,
581581
}
582582

583583
bool RISCVInstructionSelector::select(MachineInstr &MI) {
584-
MachineBasicBlock &MBB = *MI.getParent();
585-
MachineFunction &MF = *MBB.getParent();
586584
MachineIRBuilder MIB(MI);
587585

588586
preISelLower(MI, MIB);
@@ -703,58 +701,6 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
703701
MI.eraseFromParent();
704702
return constrainSelectedInstRegOperands(*Bcc, TII, TRI, RBI);
705703
}
706-
case TargetOpcode::G_BRJT: {
707-
// FIXME: Move to legalization?
708-
const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo();
709-
unsigned EntrySize = MJTI->getEntrySize(MF.getDataLayout());
710-
assert((EntrySize == 4 || (Subtarget->is64Bit() && EntrySize == 8)) &&
711-
"Unsupported jump-table entry size");
712-
assert(
713-
(MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 ||
714-
MJTI->getEntryKind() == MachineJumpTableInfo::EK_Custom32 ||
715-
MJTI->getEntryKind() == MachineJumpTableInfo::EK_BlockAddress) &&
716-
"Unexpected jump-table entry kind");
717-
718-
auto SLL =
719-
MIB.buildInstr(RISCV::SLLI, {&RISCV::GPRRegClass}, {MI.getOperand(2)})
720-
.addImm(Log2_32(EntrySize));
721-
if (!SLL.constrainAllUses(TII, TRI, RBI))
722-
return false;
723-
724-
// TODO: Use SHXADD. Moving to legalization would fix this automatically.
725-
auto ADD = MIB.buildInstr(RISCV::ADD, {&RISCV::GPRRegClass},
726-
{MI.getOperand(0), SLL.getReg(0)});
727-
if (!ADD.constrainAllUses(TII, TRI, RBI))
728-
return false;
729-
730-
unsigned LdOpc = EntrySize == 8 ? RISCV::LD : RISCV::LW;
731-
auto Dest =
732-
MIB.buildInstr(LdOpc, {&RISCV::GPRRegClass}, {ADD.getReg(0)})
733-
.addImm(0)
734-
.addMemOperand(MF.getMachineMemOperand(
735-
MachinePointerInfo::getJumpTable(MF), MachineMemOperand::MOLoad,
736-
EntrySize, Align(MJTI->getEntryAlignment(MF.getDataLayout()))));
737-
if (!Dest.constrainAllUses(TII, TRI, RBI))
738-
return false;
739-
740-
// If the Kind is EK_LabelDifference32, the table stores an offset from
741-
// the location of the table. Add the table address to get an absolute
742-
// address.
743-
if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32) {
744-
Dest = MIB.buildInstr(RISCV::ADD, {&RISCV::GPRRegClass},
745-
{Dest.getReg(0), MI.getOperand(0)});
746-
if (!Dest.constrainAllUses(TII, TRI, RBI))
747-
return false;
748-
}
749-
750-
auto Branch =
751-
MIB.buildInstr(RISCV::PseudoBRIND, {}, {Dest.getReg(0)}).addImm(0);
752-
if (!Branch.constrainAllUses(TII, TRI, RBI))
753-
return false;
754-
755-
MI.eraseFromParent();
756-
return true;
757-
}
758704
case TargetOpcode::G_BRINDIRECT:
759705
MI.setDesc(TII.get(RISCV::PseudoBRIND));
760706
MI.addOperand(MachineOperand::CreateImm(0));

llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
2020
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
2121
#include "llvm/CodeGen/MachineConstantPool.h"
22+
#include "llvm/CodeGen/MachineJumpTableInfo.h"
2223
#include "llvm/CodeGen/MachineMemOperand.h"
2324
#include "llvm/CodeGen/MachineRegisterInfo.h"
2425
#include "llvm/CodeGen/TargetOpcodes.h"
@@ -406,7 +407,7 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
406407

407408
getActionDefinitionsBuilder(G_BRCOND).legalFor({sXLen}).minScalar(0, sXLen);
408409

409-
getActionDefinitionsBuilder(G_BRJT).legalFor({{p0, sXLen}});
410+
getActionDefinitionsBuilder(G_BRJT).customFor({{p0, sXLen}});
410411

411412
getActionDefinitionsBuilder(G_BRINDIRECT).legalFor({p0});
412413

@@ -687,6 +688,61 @@ bool RISCVLegalizerInfo::legalizeVAStart(MachineInstr &MI,
687688
return true;
688689
}
689690

691+
bool RISCVLegalizerInfo::legalizeBRJT(MachineInstr &MI,
692+
MachineIRBuilder &MIRBuilder) const {
693+
MachineRegisterInfo &MRI = *MIRBuilder.getMRI();
694+
auto &MF = *MI.getParent()->getParent();
695+
const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo();
696+
unsigned EntrySize = MJTI->getEntrySize(MF.getDataLayout());
697+
698+
Register PtrReg = MI.getOperand(0).getReg();
699+
LLT PtrTy = MRI.getType(PtrReg);
700+
Register IndexReg = MI.getOperand(2).getReg();
701+
LLT IndexTy = MRI.getType(IndexReg);
702+
703+
if (!isPowerOf2_32(EntrySize))
704+
return false;
705+
706+
auto ShiftAmt = MIRBuilder.buildConstant(IndexTy, Log2_32(EntrySize));
707+
IndexReg = MIRBuilder.buildShl(IndexTy, IndexReg, ShiftAmt).getReg(0);
708+
709+
auto Addr = MIRBuilder.buildPtrAdd(PtrTy, PtrReg, IndexReg);
710+
711+
MachineMemOperand *MMO = MF.getMachineMemOperand(
712+
MachinePointerInfo::getJumpTable(MF), MachineMemOperand::MOLoad,
713+
EntrySize, Align(MJTI->getEntryAlignment(MF.getDataLayout())));
714+
715+
Register TargetReg;
716+
switch (MJTI->getEntryKind()) {
717+
default:
718+
return false;
719+
case MachineJumpTableInfo::EK_LabelDifference32: {
720+
// For PIC, the sequence is:
721+
// BRIND(load(Jumptable + index) + RelocBase)
722+
// RelocBase can be JumpTable, GOT or some sort of global base.
723+
unsigned LoadOpc =
724+
STI.is64Bit() ? TargetOpcode::G_SEXTLOAD : TargetOpcode::G_LOAD;
725+
auto Load = MIRBuilder.buildLoadInstr(LoadOpc, IndexTy, Addr, *MMO);
726+
TargetReg = MIRBuilder.buildPtrAdd(PtrTy, PtrReg, Load).getReg(0);
727+
break;
728+
}
729+
case MachineJumpTableInfo::EK_Custom32: {
730+
auto Load = MIRBuilder.buildLoadInstr(TargetOpcode::G_SEXTLOAD, IndexTy,
731+
Addr, *MMO);
732+
TargetReg = MIRBuilder.buildIntToPtr(PtrTy, Load).getReg(0);
733+
break;
734+
}
735+
case MachineJumpTableInfo::EK_BlockAddress:
736+
TargetReg = MIRBuilder.buildLoad(PtrTy, Addr, *MMO).getReg(0);
737+
break;
738+
}
739+
740+
MIRBuilder.buildBrIndirect(TargetReg);
741+
742+
MI.eraseFromParent();
743+
return true;
744+
}
745+
690746
bool RISCVLegalizerInfo::shouldBeInConstantPool(const APInt &APImm,
691747
bool ShouldOptForSize) const {
692748
assert(APImm.getBitWidth() == 32 || APImm.getBitWidth() == 64);
@@ -1313,6 +1369,8 @@ bool RISCVLegalizerInfo::legalizeCustom(
13131369
MI.eraseFromParent();
13141370
return true;
13151371
}
1372+
case TargetOpcode::G_BRJT:
1373+
return legalizeBRJT(MI, MIRBuilder);
13161374
case TargetOpcode::G_VASTART:
13171375
return legalizeVAStart(MI, MIRBuilder);
13181376
case TargetOpcode::G_VSCALE:

llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class RISCVLegalizerInfo : public LegalizerInfo {
4242
bool legalizeShlAshrLshr(MachineInstr &MI, MachineIRBuilder &MIRBuilder,
4343
GISelChangeObserver &Observer) const;
4444

45+
bool legalizeBRJT(MachineInstr &MI, MachineIRBuilder &MIRBuilder) const;
4546
bool legalizeVAStart(MachineInstr &MI, MachineIRBuilder &MIRBuilder) const;
4647
bool legalizeVScale(MachineInstr &MI, MachineIRBuilder &MIB) const;
4748
bool legalizeExt(MachineInstr &MI, MachineIRBuilder &MIRBuilder) const;

llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/jump-table-brjt-medium-rv64.mir

Lines changed: 0 additions & 160 deletions
This file was deleted.

0 commit comments

Comments
 (0)