Skip to content

Commit faac67b

Browse files
committed
[RISCV][GISel] Move G_BRJT expansion to legalization
Instead of custom selecting a bunch of instructions, we can expand to generic MIR during legalization.
1 parent 02cbae4 commit faac67b

13 files changed

+463
-809
lines changed

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

Lines changed: 0 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -542,58 +542,6 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
542542
MI.eraseFromParent();
543543
return constrainSelectedInstRegOperands(*Bcc, TII, TRI, RBI);
544544
}
545-
case TargetOpcode::G_BRJT: {
546-
// FIXME: Move to legalization?
547-
const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo();
548-
unsigned EntrySize = MJTI->getEntrySize(MF.getDataLayout());
549-
assert((EntrySize == 4 || (Subtarget->is64Bit() && EntrySize == 8)) &&
550-
"Unsupported jump-table entry size");
551-
assert(
552-
(MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 ||
553-
MJTI->getEntryKind() == MachineJumpTableInfo::EK_Custom32 ||
554-
MJTI->getEntryKind() == MachineJumpTableInfo::EK_BlockAddress) &&
555-
"Unexpected jump-table entry kind");
556-
557-
auto SLL =
558-
MIB.buildInstr(RISCV::SLLI, {&RISCV::GPRRegClass}, {MI.getOperand(2)})
559-
.addImm(Log2_32(EntrySize));
560-
if (!SLL.constrainAllUses(TII, TRI, RBI))
561-
return false;
562-
563-
// TODO: Use SHXADD. Moving to legalization would fix this automatically.
564-
auto ADD = MIB.buildInstr(RISCV::ADD, {&RISCV::GPRRegClass},
565-
{MI.getOperand(0), SLL.getReg(0)});
566-
if (!ADD.constrainAllUses(TII, TRI, RBI))
567-
return false;
568-
569-
unsigned LdOpc = EntrySize == 8 ? RISCV::LD : RISCV::LW;
570-
auto Dest =
571-
MIB.buildInstr(LdOpc, {&RISCV::GPRRegClass}, {ADD.getReg(0)})
572-
.addImm(0)
573-
.addMemOperand(MF.getMachineMemOperand(
574-
MachinePointerInfo::getJumpTable(MF), MachineMemOperand::MOLoad,
575-
EntrySize, Align(MJTI->getEntryAlignment(MF.getDataLayout()))));
576-
if (!Dest.constrainAllUses(TII, TRI, RBI))
577-
return false;
578-
579-
// If the Kind is EK_LabelDifference32, the table stores an offset from
580-
// the location of the table. Add the table address to get an absolute
581-
// address.
582-
if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32) {
583-
Dest = MIB.buildInstr(RISCV::ADD, {&RISCV::GPRRegClass},
584-
{Dest.getReg(0), MI.getOperand(0)});
585-
if (!Dest.constrainAllUses(TII, TRI, RBI))
586-
return false;
587-
}
588-
589-
auto Branch =
590-
MIB.buildInstr(RISCV::PseudoBRIND, {}, {Dest.getReg(0)}).addImm(0);
591-
if (!Branch.constrainAllUses(TII, TRI, RBI))
592-
return false;
593-
594-
MI.eraseFromParent();
595-
return true;
596-
}
597545
case TargetOpcode::G_BRINDIRECT:
598546
MI.setDesc(TII.get(RISCV::PseudoBRIND));
599547
MI.addOperand(MachineOperand::CreateImm(0));

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

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "RISCVSubtarget.h"
1515
#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
1616
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
17+
#include "llvm/CodeGen/MachineJumpTableInfo.h"
1718
#include "llvm/CodeGen/MachineRegisterInfo.h"
1819
#include "llvm/CodeGen/TargetOpcodes.h"
1920
#include "llvm/CodeGen/ValueTypes.h"
@@ -179,7 +180,7 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
179180

180181
getActionDefinitionsBuilder(G_BRCOND).legalFor({sXLen}).minScalar(0, sXLen);
181182

182-
getActionDefinitionsBuilder(G_BRJT).legalFor({{p0, sXLen}});
183+
getActionDefinitionsBuilder(G_BRJT).customFor({{p0, sXLen}});
183184

184185
getActionDefinitionsBuilder(G_BRINDIRECT).legalFor({p0});
185186

@@ -317,6 +318,62 @@ bool RISCVLegalizerInfo::legalizeShlAshrLshr(
317318
return true;
318319
}
319320

321+
bool RISCVLegalizerInfo::legalizeBRJT(MachineInstr &MI,
322+
MachineIRBuilder &MIRBuilder) const {
323+
MachineRegisterInfo &MRI = *MIRBuilder.getMRI();
324+
auto &MF = *MI.getParent()->getParent();
325+
const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo();
326+
unsigned EntrySize = MJTI->getEntrySize(MF.getDataLayout());
327+
328+
Register PtrReg = MI.getOperand(0).getReg();
329+
LLT PtrTy = MRI.getType(PtrReg);
330+
Register IndexReg = MI.getOperand(2).getReg();
331+
LLT IndexTy = MRI.getType(IndexReg);
332+
333+
MachineInstrBuilder Index;
334+
if (isPowerOf2_32(EntrySize)) {
335+
auto ShiftAmt = MIRBuilder.buildConstant(IndexTy, Log2_32(EntrySize));
336+
Index = MIRBuilder.buildShl(IndexTy, IndexReg, ShiftAmt);
337+
} else
338+
return false;
339+
340+
auto Addr = MIRBuilder.buildPtrAdd(PtrTy, PtrReg, Index);
341+
342+
MachineMemOperand *MMO = MF.getMachineMemOperand(
343+
MachinePointerInfo::getJumpTable(MF), MachineMemOperand::MOLoad,
344+
EntrySize, Align(MJTI->getEntryAlignment(MF.getDataLayout())));
345+
346+
Register TargetReg;
347+
switch (MJTI->getEntryKind()) {
348+
default:
349+
llvm_unreachable("Unexpected jumptable entry kind");
350+
case MachineJumpTableInfo::EK_LabelDifference32: {
351+
// For PIC, the sequence is:
352+
// BRIND(load(Jumptable + index) + RelocBase)
353+
// RelocBase can be JumpTable, GOT or some sort of global base.
354+
auto Load = MIRBuilder.buildLoadInstr(
355+
TargetOpcode::G_LOAD, LLT::scalar(EntrySize * 8), Addr, *MMO);
356+
Load = MIRBuilder.buildSExtOrTrunc(IndexTy, Load);
357+
TargetReg = MIRBuilder.buildPtrAdd(PtrTy, PtrReg, Load).getReg(0);
358+
break;
359+
}
360+
case MachineJumpTableInfo::EK_Custom32: {
361+
auto Load = MIRBuilder.buildLoadInstr(TargetOpcode::G_SEXTLOAD, IndexTy,
362+
Addr, *MMO);
363+
TargetReg = MIRBuilder.buildIntToPtr(PtrTy, Load).getReg(0);
364+
break;
365+
}
366+
case MachineJumpTableInfo::EK_BlockAddress:
367+
TargetReg = MIRBuilder.buildLoad(PtrTy, Addr, *MMO).getReg(0);
368+
break;
369+
}
370+
371+
MIRBuilder.buildBrIndirect(TargetReg);
372+
373+
MI.eraseFromParent();
374+
return true;
375+
}
376+
320377
bool RISCVLegalizerInfo::legalizeCustom(LegalizerHelper &Helper,
321378
MachineInstr &MI) const {
322379
MachineIRBuilder &MIRBuilder = Helper.MIRBuilder;
@@ -357,6 +414,8 @@ bool RISCVLegalizerInfo::legalizeCustom(LegalizerHelper &Helper,
357414
MI.eraseFromParent();
358415
return true;
359416
}
417+
case TargetOpcode::G_BRJT:
418+
return legalizeBRJT(MI, MIRBuilder);
360419
}
361420

362421
llvm_unreachable("expected switch to return");

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class RISCVLegalizerInfo : public LegalizerInfo {
3535
private:
3636
bool legalizeShlAshrLshr(MachineInstr &MI, MachineIRBuilder &MIRBuilder,
3737
GISelChangeObserver &Observer) const;
38+
bool legalizeBRJT(MachineInstr &MI, MachineIRBuilder &MIRBuilder) const;
3839
};
3940
} // end namespace llvm
4041
#endif

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)