-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[RISCV][GISel] Move G_BRJT expansion to legalization #73711
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
faac67b
2f83efb
fd463cf
e67d2dd
33200b5
868efa3
f98a828
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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: | ||
topperc marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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: { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we treat EK_Custom32 differently from EK_BlockAddress here, but didn't have to in instruction selection? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. EK_BlockAddress stores a pointer to the basic block target using a full pointer worth of bits. EK_Custom32 is an RV64 size optimization for the small code model where we assume that the 64 bit pointer is in +/-2GB so fits in 32 bits. Since its 32 bits it's type doesn't match p0(64 bits) so we have to sign extend it and convert it. In instruction selection, EK_BlockAddress used LW on rv32 and LD on rv64. EK_Custom32 used LW. We distinguished based on the EntrySize. |
||
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(); | ||
topperc marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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: | ||
|
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can all of this except the Custom32 case go into the generic legalizer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the EK_LabelDifference32 case might not be generic either. SelectionDAG calls a virtual function
getPICJumpTableRelocBase
.From LegalizeDAG.cpp
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For that kind of case I think we could just introduce a global isel variant of the same hook. It still saves a lot of common boilerplate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we take this patch as is and I'll work on a refactoring into the legalizer as a follow up?