diff options
author | Craig Topper <craig.topper@sifive.com> | 2024-11-20 13:43:36 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-20 13:43:36 -0800 |
commit | 4087b871c5aa80ae2f5425533eb83d909231caa7 (patch) | |
tree | 01b2ca6a1a325b8d8629bd7280fe047892e6a6b8 /llvm/lib | |
parent | 4acf935b95778d8625898730edbfe296005b4b49 (diff) | |
download | llvm-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.cpp | 54 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp | 60 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.h | 1 |
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; |