forked from OSchip/llvm-project
[RISCV] Reduce scalar load/store isel patterns to a single ComplexPattern. NFCI
Previously we had 3 different isel patterns for every scalar load store instruction. This reduces them to a single ComplexPattern that returns the Base and Offset. Or an offset of 0 if there was no offset identified I've done a similar thing for the 2 isel patterns that match add/or with FrameIndex and immediate. Using the offset of 0, I was also able to remove the custom handler for FrameIndex. Happy to split that to another patch. We might be able to enhance in the future to remove the post-isel peephole or the special handling for ADD with constant added by D126576. A nice side effect is that this removes nearly 3000 bytes from the isel table. Differential Revision: https://reviews.llvm.org/D126932
This commit is contained in:
parent
3a252806f4
commit
4402852002
|
@ -691,13 +691,6 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
|
|||
ReplaceNode(Node, selectImm(CurDAG, DL, VT, Imm, *Subtarget));
|
||||
return;
|
||||
}
|
||||
case ISD::FrameIndex: {
|
||||
SDValue Imm = CurDAG->getTargetConstant(0, DL, XLenVT);
|
||||
int FI = cast<FrameIndexSDNode>(Node)->getIndex();
|
||||
SDValue TFI = CurDAG->getTargetFrameIndex(FI, VT);
|
||||
ReplaceNode(Node, CurDAG->getMachineNode(RISCV::ADDI, DL, VT, TFI, Imm));
|
||||
return;
|
||||
}
|
||||
case ISD::ADD: {
|
||||
// Try to select ADD + immediate used as memory addresses to
|
||||
// (ADDI (ADD X, Imm-Lo12), Lo12) if it will allow the ADDI to be removed by
|
||||
|
@ -1861,11 +1854,31 @@ bool RISCVDAGToDAGISel::SelectInlineAsmMemoryOperand(
|
|||
return true;
|
||||
}
|
||||
|
||||
bool RISCVDAGToDAGISel::SelectAddrFI(SDValue Addr, SDValue &Base) {
|
||||
// Select a frame index and an optional immediate offset from an ADD or OR.
|
||||
bool RISCVDAGToDAGISel::SelectFrameAddrRegImm(SDValue Addr, SDValue &Base,
|
||||
SDValue &Offset) {
|
||||
if (auto *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
|
||||
Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), Subtarget->getXLenVT());
|
||||
Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), Subtarget->getXLenVT());
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: Use SelectionDAG::isBaseWithConstantOffset.
|
||||
if (Addr.getOpcode() == ISD::ADD ||
|
||||
(Addr.getOpcode() == ISD::OR && isOrEquivalentToAdd(Addr.getNode()))) {
|
||||
if (auto *FIN = dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) {
|
||||
if (auto *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
|
||||
if (isInt<12>(CN->getSExtValue())) {
|
||||
Base = CurDAG->getTargetFrameIndex(FIN->getIndex(),
|
||||
Subtarget->getXLenVT());
|
||||
Offset = CurDAG->getTargetConstant(CN->getSExtValue(), SDLoc(Addr),
|
||||
Subtarget->getXLenVT());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1879,6 +1892,38 @@ bool RISCVDAGToDAGISel::SelectBaseAddr(SDValue Addr, SDValue &Base) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool RISCVDAGToDAGISel::SelectAddrRegImm(SDValue Addr, SDValue &Base,
|
||||
SDValue &Offset) {
|
||||
if (Addr.getOpcode() == ISD::ADD) {
|
||||
if (auto *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
|
||||
if (isInt<12>(CN->getSExtValue())) {
|
||||
SelectBaseAddr(Addr.getOperand(0), Base);
|
||||
Offset = CurDAG->getTargetConstant(CN->getSExtValue(), SDLoc(Addr),
|
||||
Subtarget->getXLenVT());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (Addr.getOpcode() == ISD::OR) {
|
||||
// We might be able to treat this OR as an ADD.
|
||||
// TODO: Use SelectionDAG::isBaseWithConstantOffset.
|
||||
if (auto *FIN = dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) {
|
||||
if (auto *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
|
||||
if (isInt<12>(CN->getSExtValue()) &&
|
||||
isOrEquivalentToAdd(Addr.getNode())) {
|
||||
Base = CurDAG->getTargetFrameIndex(FIN->getIndex(),
|
||||
Subtarget->getXLenVT());
|
||||
Offset = CurDAG->getTargetConstant(CN->getSExtValue(), SDLoc(Addr),
|
||||
Subtarget->getXLenVT());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), Subtarget->getXLenVT());
|
||||
return SelectBaseAddr(Addr, Base);
|
||||
}
|
||||
|
||||
bool RISCVDAGToDAGISel::selectShiftMask(SDValue N, unsigned ShiftWidth,
|
||||
SDValue &ShAmt) {
|
||||
// Shift instructions on RISCV only read the lower 5 or 6 bits of the shift
|
||||
|
|
|
@ -45,8 +45,9 @@ public:
|
|||
bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID,
|
||||
std::vector<SDValue> &OutOps) override;
|
||||
|
||||
bool SelectAddrFI(SDValue Addr, SDValue &Base);
|
||||
bool SelectFrameAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset);
|
||||
bool SelectBaseAddr(SDValue Addr, SDValue &Base);
|
||||
bool SelectAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset);
|
||||
|
||||
bool selectShiftMask(SDValue N, unsigned ShiftWidth, SDValue &ShAmt);
|
||||
bool selectShiftMaskXLen(SDValue N, SDValue &ShAmt) {
|
||||
|
|
|
@ -367,8 +367,10 @@ def uimm6gt32 : ImmLeaf<XLenVT, [{
|
|||
|
||||
// Addressing modes.
|
||||
// Necessary because a frameindex can't be matched directly in a pattern.
|
||||
def AddrFI : ComplexPattern<iPTR, 1, "SelectAddrFI">;
|
||||
def FrameAddrRegImm : ComplexPattern<iPTR, 2, "SelectFrameAddrRegImm",
|
||||
[frameindex, or, add]>;
|
||||
def BaseAddr : ComplexPattern<iPTR, 1, "SelectBaseAddr">;
|
||||
def AddrRegImm : ComplexPattern<iPTR, 2, "SelectAddrRegImm">;
|
||||
|
||||
// Return the negation of an immediate value.
|
||||
def NegImm : SDNodeXForm<imm, [{
|
||||
|
@ -1115,9 +1117,6 @@ class PatGprUimmLog2XLen<SDPatternOperator OpNode, RVInstIShift Inst>
|
|||
|
||||
/// Predicates
|
||||
|
||||
def IsOrAdd: PatFrag<(ops node:$A, node:$B), (or node:$A, node:$B), [{
|
||||
return isOrEquivalentToAdd(N);
|
||||
}]>;
|
||||
def assertsexti32 : PatFrag<(ops node:$src), (assertsext node:$src), [{
|
||||
return cast<VTSDNode>(N->getOperand(1))->getVT().bitsLE(MVT::i32);
|
||||
}]>;
|
||||
|
@ -1205,10 +1204,8 @@ def PseudoAddTPRel : Pseudo<(outs GPR:$rd),
|
|||
|
||||
/// FrameIndex calculations
|
||||
|
||||
def : Pat<(add (XLenVT AddrFI:$Rs), simm12:$imm12),
|
||||
(ADDI (XLenVT AddrFI:$Rs), simm12:$imm12)>;
|
||||
def : Pat<(IsOrAdd (XLenVT AddrFI:$Rs), simm12:$imm12),
|
||||
(ADDI (XLenVT AddrFI:$Rs), simm12:$imm12)>;
|
||||
def : Pat<(FrameAddrRegImm GPR:$rs1, simm12:$imm12),
|
||||
(ADDI GPR:$rs1, simm12:$imm12)>;
|
||||
|
||||
/// Setcc
|
||||
|
||||
|
@ -1397,11 +1394,8 @@ def PseudoZEXT_W : Pseudo<(outs GPR:$rd), (ins GPR:$rs), [], "zext.w", "$rd, $rs
|
|||
/// Loads
|
||||
|
||||
multiclass LdPat<PatFrag LoadOp, RVInst Inst, ValueType vt = XLenVT> {
|
||||
def : Pat<(vt (LoadOp BaseAddr:$rs1)), (Inst BaseAddr:$rs1, 0)>;
|
||||
def : Pat<(vt (LoadOp (add BaseAddr:$rs1, simm12:$imm12))),
|
||||
(Inst BaseAddr:$rs1, simm12:$imm12)>;
|
||||
def : Pat<(vt (LoadOp (IsOrAdd AddrFI:$rs1, simm12:$imm12))),
|
||||
(Inst AddrFI:$rs1, simm12:$imm12)>;
|
||||
def : Pat<(vt (LoadOp (AddrRegImm GPR:$rs1, simm12:$imm12))),
|
||||
(Inst GPR:$rs1, simm12:$imm12)>;
|
||||
}
|
||||
|
||||
defm : LdPat<sextloadi8, LB>;
|
||||
|
@ -1416,12 +1410,8 @@ defm : LdPat<zextloadi16, LHU>;
|
|||
|
||||
multiclass StPat<PatFrag StoreOp, RVInst Inst, RegisterClass StTy,
|
||||
ValueType vt> {
|
||||
def : Pat<(StoreOp (vt StTy:$rs2), BaseAddr:$rs1),
|
||||
(Inst StTy:$rs2, BaseAddr:$rs1, 0)>;
|
||||
def : Pat<(StoreOp (vt StTy:$rs2), (add BaseAddr:$rs1, simm12:$imm12)),
|
||||
(Inst StTy:$rs2, BaseAddr:$rs1, simm12:$imm12)>;
|
||||
def : Pat<(StoreOp (vt StTy:$rs2), (IsOrAdd AddrFI:$rs1, simm12:$imm12)),
|
||||
(Inst StTy:$rs2, AddrFI:$rs1, simm12:$imm12)>;
|
||||
def : Pat<(StoreOp (vt StTy:$rs2), (AddrRegImm GPR:$rs1, simm12:$imm12)),
|
||||
(Inst StTy:$rs2, GPR:$rs1, simm12:$imm12)>;
|
||||
}
|
||||
|
||||
defm : StPat<truncstorei8, SB, GPR, XLenVT>;
|
||||
|
|
|
@ -45,12 +45,8 @@ multiclass AMO_rr_aq_rl<bits<5> funct5, bits<3> funct3, string opcodestr> {
|
|||
|
||||
multiclass AtomicStPat<PatFrag StoreOp, RVInst Inst, RegisterClass StTy,
|
||||
ValueType vt = XLenVT> {
|
||||
def : Pat<(StoreOp BaseAddr:$rs1, (vt StTy:$rs2)),
|
||||
(Inst StTy:$rs2, BaseAddr:$rs1, 0)>;
|
||||
def : Pat<(StoreOp (add BaseAddr:$rs1, simm12:$imm12), (vt StTy:$rs2)),
|
||||
(Inst StTy:$rs2, BaseAddr:$rs1, simm12:$imm12)>;
|
||||
def : Pat<(StoreOp (IsOrAdd AddrFI:$rs1, simm12:$imm12), (vt StTy:$rs2)),
|
||||
(Inst StTy:$rs2, AddrFI:$rs1, simm12:$imm12)>;
|
||||
def : Pat<(StoreOp (AddrRegImm GPR:$rs1, simm12:$imm12), (vt StTy:$rs2)),
|
||||
(Inst StTy:$rs2, GPR:$rs1, simm12:$imm12)>;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
Loading…
Reference in New Issue