aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@sifive.com>2024-11-20 13:43:36 -0800
committerGitHub <noreply@github.com>2024-11-20 13:43:36 -0800
commit4087b871c5aa80ae2f5425533eb83d909231caa7 (patch)
tree01b2ca6a1a325b8d8629bd7280fe047892e6a6b8 /llvm/lib
parent4acf935b95778d8625898730edbfe296005b4b49 (diff)
downloadllvm-4087b871c5aa80ae2f5425533eb83d909231caa7.zip
llvm-4087b871c5aa80ae2f5425533eb83d909231caa7.tar.gz
llvm-4087b871c5aa80ae2f5425533eb83d909231caa7.tar.bz2
[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.
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp54
-rw-r--r--llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp60
-rw-r--r--llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h1
3 files changed, 60 insertions, 55 deletions
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index 3c95f01..6ddc447 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
@@ -581,8 +581,6 @@ static void getOperandsForBranch(Register CondReg, RISCVCC::CondCode &CC,
}
bool RISCVInstructionSelector::select(MachineInstr &MI) {
- MachineBasicBlock &MBB = *MI.getParent();
- MachineFunction &MF = *MBB.getParent();
MachineIRBuilder MIB(MI);
preISelLower(MI, MIB);
@@ -703,58 +701,6 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
MI.eraseFromParent();
return constrainSelectedInstRegOperands(*Bcc, TII, TRI, RBI);
}
- case TargetOpcode::G_BRJT: {
- // FIXME: Move to legalization?
- const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo();
- unsigned EntrySize = MJTI->getEntrySize(MF.getDataLayout());
- assert((EntrySize == 4 || (Subtarget->is64Bit() && EntrySize == 8)) &&
- "Unsupported jump-table entry size");
- assert(
- (MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 ||
- MJTI->getEntryKind() == MachineJumpTableInfo::EK_Custom32 ||
- MJTI->getEntryKind() == MachineJumpTableInfo::EK_BlockAddress) &&
- "Unexpected jump-table entry kind");
-
- auto SLL =
- MIB.buildInstr(RISCV::SLLI, {&RISCV::GPRRegClass}, {MI.getOperand(2)})
- .addImm(Log2_32(EntrySize));
- if (!SLL.constrainAllUses(TII, TRI, RBI))
- return false;
-
- // TODO: Use SHXADD. Moving to legalization would fix this automatically.
- auto ADD = MIB.buildInstr(RISCV::ADD, {&RISCV::GPRRegClass},
- {MI.getOperand(0), SLL.getReg(0)});
- if (!ADD.constrainAllUses(TII, TRI, RBI))
- return false;
-
- unsigned LdOpc = EntrySize == 8 ? RISCV::LD : RISCV::LW;
- auto Dest =
- MIB.buildInstr(LdOpc, {&RISCV::GPRRegClass}, {ADD.getReg(0)})
- .addImm(0)
- .addMemOperand(MF.getMachineMemOperand(
- MachinePointerInfo::getJumpTable(MF), MachineMemOperand::MOLoad,
- EntrySize, Align(MJTI->getEntryAlignment(MF.getDataLayout()))));
- if (!Dest.constrainAllUses(TII, TRI, RBI))
- return false;
-
- // If the Kind is EK_LabelDifference32, the table stores an offset from
- // the location of the table. Add the table address to get an absolute
- // address.
- if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32) {
- Dest = MIB.buildInstr(RISCV::ADD, {&RISCV::GPRRegClass},
- {Dest.getReg(0), MI.getOperand(0)});
- if (!Dest.constrainAllUses(TII, TRI, RBI))
- return false;
- }
-
- auto Branch =
- MIB.buildInstr(RISCV::PseudoBRIND, {}, {Dest.getReg(0)}).addImm(0);
- if (!Branch.constrainAllUses(TII, TRI, RBI))
- return false;
-
- MI.eraseFromParent();
- return true;
- }
case TargetOpcode::G_BRINDIRECT:
MI.setDesc(TII.get(RISCV::PseudoBRIND));
MI.addOperand(MachineOperand::CreateImm(0));
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index fe0bf40..b557659 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -19,6 +19,7 @@
#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
#include "llvm/CodeGen/MachineConstantPool.h"
+#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetOpcodes.h"
@@ -406,7 +407,7 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
getActionDefinitionsBuilder(G_BRCOND).legalFor({sXLen}).minScalar(0, sXLen);
- getActionDefinitionsBuilder(G_BRJT).legalFor({{p0, sXLen}});
+ getActionDefinitionsBuilder(G_BRJT).customFor({{p0, sXLen}});
getActionDefinitionsBuilder(G_BRINDIRECT).legalFor({p0});
@@ -687,6 +688,61 @@ bool RISCVLegalizerInfo::legalizeVAStart(MachineInstr &MI,
return true;
}
+bool RISCVLegalizerInfo::legalizeBRJT(MachineInstr &MI,
+ MachineIRBuilder &MIRBuilder) const {
+ MachineRegisterInfo &MRI = *MIRBuilder.getMRI();
+ auto &MF = *MI.getParent()->getParent();
+ const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo();
+ unsigned EntrySize = MJTI->getEntrySize(MF.getDataLayout());
+
+ Register PtrReg = MI.getOperand(0).getReg();
+ LLT PtrTy = MRI.getType(PtrReg);
+ Register IndexReg = MI.getOperand(2).getReg();
+ LLT IndexTy = MRI.getType(IndexReg);
+
+ if (!isPowerOf2_32(EntrySize))
+ return false;
+
+ auto ShiftAmt = MIRBuilder.buildConstant(IndexTy, Log2_32(EntrySize));
+ IndexReg = MIRBuilder.buildShl(IndexTy, IndexReg, ShiftAmt).getReg(0);
+
+ auto Addr = MIRBuilder.buildPtrAdd(PtrTy, PtrReg, IndexReg);
+
+ MachineMemOperand *MMO = MF.getMachineMemOperand(
+ MachinePointerInfo::getJumpTable(MF), MachineMemOperand::MOLoad,
+ EntrySize, Align(MJTI->getEntryAlignment(MF.getDataLayout())));
+
+ Register TargetReg;
+ switch (MJTI->getEntryKind()) {
+ default:
+ return false;
+ case MachineJumpTableInfo::EK_LabelDifference32: {
+ // For PIC, the sequence is:
+ // BRIND(load(Jumptable + index) + RelocBase)
+ // RelocBase can be JumpTable, GOT or some sort of global base.
+ unsigned LoadOpc =
+ STI.is64Bit() ? TargetOpcode::G_SEXTLOAD : TargetOpcode::G_LOAD;
+ auto Load = MIRBuilder.buildLoadInstr(LoadOpc, IndexTy, Addr, *MMO);
+ TargetReg = MIRBuilder.buildPtrAdd(PtrTy, PtrReg, Load).getReg(0);
+ break;
+ }
+ case MachineJumpTableInfo::EK_Custom32: {
+ auto Load = MIRBuilder.buildLoadInstr(TargetOpcode::G_SEXTLOAD, IndexTy,
+ Addr, *MMO);
+ TargetReg = MIRBuilder.buildIntToPtr(PtrTy, Load).getReg(0);
+ break;
+ }
+ case MachineJumpTableInfo::EK_BlockAddress:
+ TargetReg = MIRBuilder.buildLoad(PtrTy, Addr, *MMO).getReg(0);
+ break;
+ }
+
+ MIRBuilder.buildBrIndirect(TargetReg);
+
+ MI.eraseFromParent();
+ return true;
+}
+
bool RISCVLegalizerInfo::shouldBeInConstantPool(const APInt &APImm,
bool ShouldOptForSize) const {
assert(APImm.getBitWidth() == 32 || APImm.getBitWidth() == 64);
@@ -1313,6 +1369,8 @@ bool RISCVLegalizerInfo::legalizeCustom(
MI.eraseFromParent();
return true;
}
+ case TargetOpcode::G_BRJT:
+ return legalizeBRJT(MI, MIRBuilder);
case TargetOpcode::G_VASTART:
return legalizeVAStart(MI, MIRBuilder);
case TargetOpcode::G_VSCALE:
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h
index ae595cf..4451866 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h
@@ -42,6 +42,7 @@ private:
bool legalizeShlAshrLshr(MachineInstr &MI, MachineIRBuilder &MIRBuilder,
GISelChangeObserver &Observer) const;
+ bool legalizeBRJT(MachineInstr &MI, MachineIRBuilder &MIRBuilder) const;
bool legalizeVAStart(MachineInstr &MI, MachineIRBuilder &MIRBuilder) const;
bool legalizeVScale(MachineInstr &MI, MachineIRBuilder &MIB) const;
bool legalizeExt(MachineInstr &MI, MachineIRBuilder &MIRBuilder) const;