1 //===-- RISCVISelDAGToDAG.cpp - A dag to dag inst selector for RISCV ------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines an instruction selector for the RISCV target. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "RISCV.h" 15 #include "MCTargetDesc/RISCVMCTargetDesc.h" 16 #include "RISCVTargetMachine.h" 17 #include "llvm/CodeGen/MachineFrameInfo.h" 18 #include "llvm/CodeGen/SelectionDAGISel.h" 19 #include "llvm/Support/Debug.h" 20 #include "llvm/Support/MathExtras.h" 21 #include "llvm/Support/raw_ostream.h" 22 using namespace llvm; 23 24 #define DEBUG_TYPE "riscv-isel" 25 26 // RISCV-specific code to select RISCV machine instructions for 27 // SelectionDAG operations. 28 namespace { 29 class RISCVDAGToDAGISel final : public SelectionDAGISel { 30 const RISCVSubtarget *Subtarget; 31 32 public: 33 explicit RISCVDAGToDAGISel(RISCVTargetMachine &TargetMachine) 34 : SelectionDAGISel(TargetMachine) {} 35 36 StringRef getPassName() const override { 37 return "RISCV DAG->DAG Pattern Instruction Selection"; 38 } 39 40 bool runOnMachineFunction(MachineFunction &MF) override { 41 Subtarget = &MF.getSubtarget<RISCVSubtarget>(); 42 return SelectionDAGISel::runOnMachineFunction(MF); 43 } 44 45 void Select(SDNode *Node) override; 46 47 bool SelectAddrFI(SDValue Addr, SDValue &Base); 48 49 // Include the pieces autogenerated from the target description. 50 #include "RISCVGenDAGISel.inc" 51 }; 52 } 53 54 void RISCVDAGToDAGISel::Select(SDNode *Node) { 55 unsigned Opcode = Node->getOpcode(); 56 MVT XLenVT = Subtarget->getXLenVT(); 57 58 // Dump information about the Node being selected. 59 DEBUG(dbgs() << "Selecting: "; Node->dump(CurDAG); dbgs() << "\n"); 60 61 // If we have a custom node, we have already selected 62 if (Node->isMachineOpcode()) { 63 DEBUG(dbgs() << "== "; Node->dump(CurDAG); dbgs() << "\n"); 64 Node->setNodeId(-1); 65 return; 66 } 67 68 // Instruction Selection not handled by the auto-generated tablegen selection 69 // should be handled here. 70 EVT VT = Node->getValueType(0); 71 if (Opcode == ISD::Constant && VT == XLenVT) { 72 auto *ConstNode = cast<ConstantSDNode>(Node); 73 // Materialize zero constants as copies from X0. This allows the coalescer 74 // to propagate these into other instructions. 75 if (ConstNode->isNullValue()) { 76 SDValue New = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), SDLoc(Node), 77 RISCV::X0, XLenVT); 78 ReplaceNode(Node, New.getNode()); 79 return; 80 } 81 } 82 if (Opcode == ISD::FrameIndex) { 83 SDLoc DL(Node); 84 SDValue Imm = CurDAG->getTargetConstant(0, DL, XLenVT); 85 int FI = dyn_cast<FrameIndexSDNode>(Node)->getIndex(); 86 EVT VT = Node->getValueType(0); 87 SDValue TFI = CurDAG->getTargetFrameIndex(FI, VT); 88 ReplaceNode(Node, CurDAG->getMachineNode(RISCV::ADDI, DL, VT, TFI, Imm)); 89 return; 90 } 91 92 // Select the default instruction. 93 SelectCode(Node); 94 } 95 96 bool RISCVDAGToDAGISel::SelectAddrFI(SDValue Addr, SDValue &Base) { 97 if (auto FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 98 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), Subtarget->getXLenVT()); 99 return true; 100 } 101 return false; 102 } 103 104 // This pass converts a legalized DAG into a RISCV-specific DAG, ready 105 // for instruction scheduling. 106 FunctionPass *llvm::createRISCVISelDag(RISCVTargetMachine &TM) { 107 return new RISCVDAGToDAGISel(TM); 108 } 109