25 #define DEBUG_TYPE "riscv-isel" 38 return "RISCV DAG->DAG Pattern Instruction Selection";
46 void PostprocessISelDAG()
override;
50 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
unsigned ConstraintID,
51 std::vector<SDValue> &OutOps)
override;
56 #include "RISCVGenDAGISel.inc" 59 void doPeepholeLoadStoreADDI();
63 void RISCVDAGToDAGISel::PostprocessISelDAG() {
64 doPeepholeLoadStoreADDI();
76 if (Inst.Opc == RISCV::LUI)
79 Result = CurDAG->
getMachineNode(Inst.Opc, DL, XLenVT, SrcReg, SDImm);
93 Mask = cast<ConstantSDNode>(Node->
getOperand(1))->getZExtValue();
110 MVT XLenVT = Subtarget->getXLenVT();
116 auto ConstNode = cast<ConstantSDNode>(Node);
117 if (VT == XLenVT && ConstNode->isNullValue()) {
118 SDValue New = CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
SDLoc(Node),
120 ReplaceNode(Node, New.
getNode());
123 int64_t Imm = ConstNode->getSExtValue();
131 SDValue Imm = CurDAG->getTargetConstant(0, DL, XLenVT);
132 int FI = cast<FrameIndexSDNode>(Node)->getIndex();
133 SDValue TFI = CurDAG->getTargetFrameIndex(FI, VT);
134 ReplaceNode(Node, CurDAG->getMachineNode(RISCV::ADDI, DL, VT, TFI, Imm));
138 if (!Subtarget->is64Bit())
149 uint64_t ShAmt = cast<ConstantSDNode>(Op1.
getNode())->getZExtValue();
151 if ((Mask | maskTrailingOnes<uint64_t>(ShAmt)) == 0xffffffff) {
153 CurDAG->getTargetConstant(ShAmt,
SDLoc(Node), XLenVT);
154 CurDAG->SelectNodeTo(Node, RISCV::SRLIW, XLenVT, Op0.
getOperand(0),
166 bool RISCVDAGToDAGISel::SelectInlineAsmMemoryOperand(
167 const SDValue &
Op,
unsigned ConstraintID, std::vector<SDValue> &OutOps) {
168 switch (ConstraintID) {
173 OutOps.push_back(Op);
183 if (
auto FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
184 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), Subtarget->getXLenVT());
193 void RISCVDAGToDAGISel::doPeepholeLoadStoreADDI() {
197 while (Position != CurDAG->allnodes_begin()) {
235 if (!isa<ConstantSDNode>(N->
getOperand(OffsetOpIdx)) ||
247 if (
auto Const = dyn_cast<ConstantSDNode>(ImmOperand)) {
248 ImmOperand = CurDAG->getTargetConstant(
250 }
else if (
auto GA = dyn_cast<GlobalAddressSDNode>(ImmOperand)) {
251 ImmOperand = CurDAG->getTargetGlobalAddress(
253 GA->getOffset(), GA->getTargetFlags());
258 LLVM_DEBUG(
dbgs() <<
"Folding add-immediate into mem-op:\nBase: ");
266 CurDAG->UpdateNodeOperands(N, Base.
getOperand(0), ImmOperand,
274 CurDAG->RemoveDeadNode(Base.
getNode());
281 return new RISCVDAGToDAGISel(TM);
static bool isConstantMask(SDNode *Node, uint64_t &Mask)
EVT getValueType() const
Return the ValueType of the referenced return value.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
This class represents lattice values for constants.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
void setNodeId(int Id)
Set unique node id.
SDNode * getNode() const
get the SDNode which holds the desired result
MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s), MachineInstr opcode, and operands.
Position
Position to insert a new instruction relative to an existing instruction.
FunctionPass * createRISCVISelDag(RISCVTargetMachine &TM)
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
This instruction implements an extending load to FP stack slots.
bool isMachineOpcode() const
const SDValue & getOperand(unsigned Num) const
unsigned getMachineOpcode() const
FunctionPass class - This class is used to implement most global optimizations.
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode...
bool use_empty() const
Return true if there are no uses of this node.
void dump() const
Dump this node, for debugging.
Iterator for intrusive lists based on ilist_node.
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
static SDNode * selectImm(SelectionDAG *CurDAG, const SDLoc &DL, int64_t Imm, MVT XLenVT)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Bitwise operators - logical and, logical or, logical xor.
unsigned getOpcode() const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
SDValue getRegister(unsigned Reg, EVT VT)
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Primary interface to the complete machine description for the target machine.
StringRef - Represent a constant reference to a string, i.e.
void generateInstSeq(int64_t Val, bool Is64Bit, InstSeq &Res)
const SDValue & getOperand(unsigned i) const
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...