diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 19 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp | 20 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.h | 1 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVFrameLowering.cpp | 29 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVFrameLowering.h | 3 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 20 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVInstrInfo.td | 27 | ||||
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp | 14 |
8 files changed, 104 insertions, 29 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 8f47c5b40ba..3a8ad51940d 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -3761,6 +3761,25 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch, } } +bool SelectionDAGISel::isOrEquivalentToAdd(const SDNode *N) const { + assert(N->getOpcode() == ISD::OR && "Unexpected opcode"); + auto *C = dyn_cast<ConstantSDNode>(N->getOperand(1)); + if (!C) + return false; + + // Detect when "or" is used to add an offset to a stack object. + if (auto *FN = dyn_cast<FrameIndexSDNode>(N->getOperand(0))) { + MachineFrameInfo &MFI = MF->getFrameInfo(); + unsigned A = MFI.getObjectAlignment(FN->getIndex()); + assert(isPowerOf2_32(A) && "Unexpected alignment"); + int32_t Off = C->getSExtValue(); + // If the alleged offset fits in the zero bits guaranteed by + // the alignment, then this or is really an add. + return (Off >= 0) && (((A - 1) & Off) == unsigned(Off)); + } + return false; +} + void SelectionDAGISel::CannotYetSelect(SDNode *N) { std::string msg; raw_string_ostream Msg(msg); diff --git a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp index d0cd143a4d4..76a7e77fc38 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp +++ b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp @@ -1421,26 +1421,6 @@ bool HexagonDAGToDAGISel::keepsLowBits(const SDValue &Val, unsigned NumBits, return false; } - -bool HexagonDAGToDAGISel::isOrEquivalentToAdd(const SDNode *N) const { - assert(N->getOpcode() == ISD::OR); - auto *C = dyn_cast<ConstantSDNode>(N->getOperand(1)); - if (!C) - return false; - - // Detect when "or" is used to add an offset to a stack object. - if (auto *FN = dyn_cast<FrameIndexSDNode>(N->getOperand(0))) { - MachineFrameInfo &MFI = MF->getFrameInfo(); - unsigned A = MFI.getObjectAlignment(FN->getIndex()); - assert(isPowerOf2_32(A)); - int32_t Off = C->getSExtValue(); - // If the alleged offset fits in the zero bits guaranteed by - // the alignment, then this or is really an add. - return (Off >= 0) && (((A-1) & Off) == unsigned(Off)); - } - return false; -} - bool HexagonDAGToDAGISel::isAlignedMemNode(const MemSDNode *N) const { return N->getAlignment() >= N->getMemoryVT().getStoreSize(); } diff --git a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.h b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.h index e3e22a39fc1..0028c400786 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.h +++ b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.h @@ -121,7 +121,6 @@ private: void SelectHvxRor(SDNode *N); bool keepsLowBits(const SDValue &Val, unsigned NumBits, SDValue &Src); - bool isOrEquivalentToAdd(const SDNode *N) const; bool isAlignedMemNode(const MemSDNode *N) const; bool isSmallStackStore(const StoreSDNode *N) const; bool isPositiveHalfWord(const SDNode *N) const; diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp index fd3b258e26c..cd18a104631 100644 --- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp @@ -27,3 +27,32 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF, void RISCVFrameLowering::emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const {} + +int RISCVFrameLowering::getFrameIndexReference(const MachineFunction &MF, + int FI, + unsigned &FrameReg) const { + const MachineFrameInfo &MFI = MF.getFrameInfo(); + const TargetRegisterInfo *RI = MF.getSubtarget().getRegisterInfo(); + + // Callee-saved registers should be referenced relative to the stack + // pointer (positive offset), otherwise use the frame pointer (negative + // offset). + const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); + int MinCSFI = 0; + int MaxCSFI = -1; + + int Offset = MFI.getObjectOffset(FI) - getOffsetOfLocalArea() + + MFI.getOffsetAdjustment(); + + if (CSI.size()) { + MinCSFI = CSI[0].getFrameIdx(); + MaxCSFI = CSI[CSI.size() - 1].getFrameIdx(); + } + + FrameReg = RI->getFrameRegister(MF); + if (FI >= MinCSFI && FI <= MaxCSFI) { + FrameReg = RISCV::X2; + Offset += MF.getFrameInfo().getStackSize(); + } + return Offset; +} diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.h b/llvm/lib/Target/RISCV/RISCVFrameLowering.h index 0b2c7a40298..ba093bb83f0 100644 --- a/llvm/lib/Target/RISCV/RISCVFrameLowering.h +++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.h @@ -29,6 +29,9 @@ public: void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override; void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override; + int getFrameIndexReference(const MachineFunction &MF, int FI, + unsigned &FrameReg) const override; + bool hasFP(const MachineFunction &MF) const override; MachineBasicBlock::iterator diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp index 5b038df4ae3..113a45ac7cc 100644 --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -14,6 +14,7 @@ #include "RISCV.h" #include "MCTargetDesc/RISCVMCTargetDesc.h" #include "RISCVTargetMachine.h" +#include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/SelectionDAGISel.h" #include "llvm/Support/Debug.h" #include "llvm/Support/MathExtras.h" @@ -43,6 +44,8 @@ public: void Select(SDNode *Node) override; + bool SelectAddrFI(SDValue Addr, SDValue &Base); + // Include the pieces autogenerated from the target description. #include "RISCVGenDAGISel.inc" }; @@ -76,11 +79,28 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) { return; } } + if (Opcode == ISD::FrameIndex) { + SDLoc DL(Node); + SDValue Imm = CurDAG->getTargetConstant(0, DL, XLenVT); + int FI = dyn_cast<FrameIndexSDNode>(Node)->getIndex(); + EVT VT = Node->getValueType(0); + SDValue TFI = CurDAG->getTargetFrameIndex(FI, VT); + ReplaceNode(Node, CurDAG->getMachineNode(RISCV::ADDI, DL, VT, TFI, Imm)); + return; + } // Select the default instruction. SelectCode(Node); } +bool RISCVDAGToDAGISel::SelectAddrFI(SDValue Addr, SDValue &Base) { + if (auto FIN = dyn_cast<FrameIndexSDNode>(Addr)) { + Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), Subtarget->getXLenVT()); + return true; + } + return false; +} + // This pass converts a legalized DAG into a RISCV-specific DAG, ready // for instruction scheduling. FunctionPass *llvm::createRISCVISelDag(RISCVTargetMachine &TM) { diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td index b37ab31324e..9512435cf2f 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -127,6 +127,10 @@ def ixlenimm : Operand<XLenVT>; // Standalone (codegen-only) immleaf patterns. def simm32 : ImmLeaf<XLenVT, [{return isInt<32>(Imm);}]>; +// Addressing modes. +// Necessary because a frameindex can't be matched directly in a pattern. +def AddrFI : ComplexPattern<iPTR, 1, "SelectAddrFI", [frameindex], []>; + // Extract least significant 12 bits from an immediate value and sign extend // them. def LO12Sext : SDNodeXForm<imm, [{ @@ -347,6 +351,12 @@ class PatGprUimmLog2XLen<SDPatternOperator OpNode, RVInstIShift Inst> : Pat<(OpNode GPR:$rs1, uimmlog2xlen:$shamt), (Inst GPR:$rs1, uimmlog2xlen:$shamt)>; +/// Predicates + +def IsOrAdd: PatFrag<(ops node:$A, node:$B), (or node:$A, node:$B), [{ + return isOrEquivalentToAdd(N); +}]>; + /// Immediates def : Pat<(simm12:$imm), (ADDI X0, simm12:$imm)>; @@ -371,6 +381,13 @@ def : PatGprUimmLog2XLen<srl, SRLI>; def : PatGprGpr<sra, SRA>; def : PatGprUimmLog2XLen<sra, SRAI>; +/// FrameIndex calculations + +def : Pat<(add (i32 AddrFI:$Rs), simm12:$imm12), + (ADDI (i32 AddrFI:$Rs), simm12:$imm12)>; +def : Pat<(IsOrAdd (i32 AddrFI:$Rs), simm12:$imm12), + (ADDI (i32 AddrFI:$Rs), simm12:$imm12)>; + /// Setcc def : PatGprGpr<setlt, SLT>; @@ -451,8 +468,13 @@ def PseudoRET : Pseudo<(outs), (ins), [(RetFlag)]>, multiclass LdPat<PatFrag LoadOp, RVInst Inst> { def : Pat<(LoadOp GPR:$rs1), (Inst GPR:$rs1, 0)>; + def : Pat<(LoadOp AddrFI:$rs1), (Inst AddrFI:$rs1, 0)>; def : Pat<(LoadOp (add GPR:$rs1, simm12:$imm12)), (Inst GPR:$rs1, simm12:$imm12)>; + def : Pat<(LoadOp (add AddrFI:$rs1, simm12:$imm12)), + (Inst AddrFI:$rs1, simm12:$imm12)>; + def : Pat<(LoadOp (IsOrAdd AddrFI:$rs1, simm12:$imm12)), + (Inst AddrFI:$rs1, simm12:$imm12)>; } defm : LdPat<sextloadi8, LB>; @@ -467,8 +489,13 @@ defm : LdPat<zextloadi16, LHU>; multiclass StPat<PatFrag StoreOp, RVInst Inst> { def : Pat<(StoreOp GPR:$rs2, GPR:$rs1), (Inst GPR:$rs2, GPR:$rs1, 0)>; + def : Pat<(StoreOp GPR:$rs2, AddrFI:$rs1), (Inst GPR:$rs2, AddrFI:$rs1, 0)>; def : Pat<(StoreOp GPR:$rs2, (add GPR:$rs1, simm12:$imm12)), (Inst GPR:$rs2, GPR:$rs1, simm12:$imm12)>; + def : Pat<(StoreOp GPR:$rs2, (add AddrFI:$rs1, simm12:$imm12)), + (Inst GPR:$rs2, AddrFI:$rs1, simm12:$imm12)>; + def : Pat<(StoreOp GPR:$rs2, (IsOrAdd AddrFI:$rs1, simm12:$imm12)), + (Inst GPR:$rs2, AddrFI:$rs1, simm12:$imm12)>; } defm : StPat<truncstorei8, SB>; diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp index 75b277531ce..5776a92cab9 100644 --- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp @@ -57,22 +57,20 @@ const uint32_t *RISCVRegisterInfo::getNoPreservedMask() const { void RISCVRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, unsigned FIOperandNum, RegScavenger *RS) const { - // TODO: this implementation is a temporary placeholder which does just - // enough to allow other aspects of code generation to be tested - assert(SPAdj == 0 && "Unexpected non-zero SPAdj value"); MachineInstr &MI = *II; MachineFunction &MF = *MI.getParent()->getParent(); - const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); DebugLoc DL = MI.getDebugLoc(); - unsigned FrameReg = getFrameRegister(MF); int FrameIndex = MI.getOperand(FIOperandNum).getIndex(); - int Offset = TFI->getFrameIndexReference(MF, FrameIndex, FrameReg); - Offset += MI.getOperand(FIOperandNum + 1).getImm(); + unsigned FrameReg; + int Offset = + getFrameLowering(MF)->getFrameIndexReference(MF, FrameIndex, FrameReg) + + MI.getOperand(FIOperandNum + 1).getImm(); - assert(TFI->hasFP(MF) && "eliminateFrameIndex currently requires hasFP"); + assert(MF.getSubtarget().getFrameLowering()->hasFP(MF) && + "eliminateFrameIndex currently requires hasFP"); // Offsets must be directly encoded in a 12-bit immediate field if (!isInt<12>(Offset)) { |