1 //===-- PTXISelDAGToDAG.cpp - A dag to dag inst selector for PTX ----------===// 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 PTX target. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "PTX.h" 15 #include "PTXTargetMachine.h" 16 #include "llvm/CodeGen/SelectionDAGISel.h" 17 #include "llvm/DerivedTypes.h" 18 #include "llvm/Support/Debug.h" 19 #include "llvm/Support/raw_ostream.h" 20 21 using namespace llvm; 22 23 namespace { 24 // PTXDAGToDAGISel - PTX specific code to select PTX machine 25 // instructions for SelectionDAG operations. 26 class PTXDAGToDAGISel : public SelectionDAGISel { 27 public: 28 PTXDAGToDAGISel(PTXTargetMachine &TM, CodeGenOpt::Level OptLevel); 29 30 virtual const char *getPassName() const { 31 return "PTX DAG->DAG Pattern Instruction Selection"; 32 } 33 34 SDNode *Select(SDNode *Node); 35 36 // Complex Pattern Selectors. 37 bool SelectADDRrr(SDValue &Addr, SDValue &R1, SDValue &R2); 38 bool SelectADDRri(SDValue &Addr, SDValue &Base, SDValue &Offset); 39 bool SelectADDRii(SDValue &Addr, SDValue &Base, SDValue &Offset); 40 41 // Include the pieces auto'gened from the target description 42 #include "PTXGenDAGISel.inc" 43 44 private: 45 // We need this only because we can't match intruction BRAdp 46 // pattern (PTXbrcond bb:$d, ...) in PTXInstrInfo.td 47 SDNode *SelectBRCOND(SDNode *Node); 48 49 bool isImm(const SDValue &operand); 50 bool SelectImm(const SDValue &operand, SDValue &imm); 51 52 const PTXSubtarget& getSubtarget() const; 53 }; // class PTXDAGToDAGISel 54 } // namespace 55 56 // createPTXISelDag - This pass converts a legalized DAG into a 57 // PTX-specific DAG, ready for instruction scheduling 58 FunctionPass *llvm::createPTXISelDag(PTXTargetMachine &TM, 59 CodeGenOpt::Level OptLevel) { 60 return new PTXDAGToDAGISel(TM, OptLevel); 61 } 62 63 PTXDAGToDAGISel::PTXDAGToDAGISel(PTXTargetMachine &TM, 64 CodeGenOpt::Level OptLevel) 65 : SelectionDAGISel(TM, OptLevel) {} 66 67 SDNode *PTXDAGToDAGISel::Select(SDNode *Node) { 68 switch (Node->getOpcode()) { 69 case ISD::BRCOND: 70 return SelectBRCOND(Node); 71 default: 72 return SelectCode(Node); 73 } 74 } 75 76 SDNode *PTXDAGToDAGISel::SelectBRCOND(SDNode *Node) { 77 assert(Node->getNumOperands() >= 3); 78 79 SDValue Chain = Node->getOperand(0); 80 SDValue Pred = Node->getOperand(1); 81 SDValue Target = Node->getOperand(2); // branch target 82 SDValue PredOp = CurDAG->getTargetConstant(PTX::PRED_NORMAL, MVT::i32); 83 DebugLoc dl = Node->getDebugLoc(); 84 85 assert(Target.getOpcode() == ISD::BasicBlock); 86 assert(Pred.getValueType() == MVT::i1); 87 88 // Emit BRAdp 89 SDValue Ops[] = { Target, Pred, PredOp, Chain }; 90 return CurDAG->getMachineNode(PTX::BRAdp, dl, MVT::Other, Ops, 4); 91 } 92 93 // Match memory operand of the form [reg+reg] 94 bool PTXDAGToDAGISel::SelectADDRrr(SDValue &Addr, SDValue &R1, SDValue &R2) { 95 if (Addr.getOpcode() != ISD::ADD || Addr.getNumOperands() < 2 || 96 isImm(Addr.getOperand(0)) || isImm(Addr.getOperand(1))) 97 return false; 98 99 assert(Addr.getValueType().isSimple() && "Type must be simple"); 100 101 R1 = Addr; 102 R2 = CurDAG->getTargetConstant(0, Addr.getValueType().getSimpleVT()); 103 104 return true; 105 } 106 107 // Match memory operand of the form [reg], [imm+reg], and [reg+imm] 108 bool PTXDAGToDAGISel::SelectADDRri(SDValue &Addr, SDValue &Base, 109 SDValue &Offset) { 110 if (Addr.getOpcode() != ISD::ADD) { 111 // let SelectADDRii handle the [imm] case 112 if (isImm(Addr)) 113 return false; 114 // it is [reg] 115 116 assert(Addr.getValueType().isSimple() && "Type must be simple"); 117 118 Base = Addr; 119 Offset = CurDAG->getTargetConstant(0, Addr.getValueType().getSimpleVT()); 120 121 return true; 122 } 123 124 if (Addr.getNumOperands() < 2) 125 return false; 126 127 // let SelectADDRii handle the [imm+imm] case 128 if (isImm(Addr.getOperand(0)) && isImm(Addr.getOperand(1))) 129 return false; 130 131 // try [reg+imm] and [imm+reg] 132 for (int i = 0; i < 2; i ++) 133 if (SelectImm(Addr.getOperand(1-i), Offset)) { 134 Base = Addr.getOperand(i); 135 return true; 136 } 137 138 // neither [reg+imm] nor [imm+reg] 139 return false; 140 } 141 142 // Match memory operand of the form [imm+imm] and [imm] 143 bool PTXDAGToDAGISel::SelectADDRii(SDValue &Addr, SDValue &Base, 144 SDValue &Offset) { 145 // is [imm+imm]? 146 if (Addr.getOpcode() == ISD::ADD) { 147 return SelectImm(Addr.getOperand(0), Base) && 148 SelectImm(Addr.getOperand(1), Offset); 149 } 150 151 // is [imm]? 152 if (SelectImm(Addr, Base)) { 153 assert(Addr.getValueType().isSimple() && "Type must be simple"); 154 155 Offset = CurDAG->getTargetConstant(0, Addr.getValueType().getSimpleVT()); 156 157 return true; 158 } 159 160 return false; 161 } 162 163 bool PTXDAGToDAGISel::isImm(const SDValue &operand) { 164 return ConstantSDNode::classof(operand.getNode()); 165 } 166 167 bool PTXDAGToDAGISel::SelectImm(const SDValue &operand, SDValue &imm) { 168 SDNode *node = operand.getNode(); 169 if (!ConstantSDNode::classof(node)) 170 return false; 171 172 ConstantSDNode *CN = cast<ConstantSDNode>(node); 173 imm = CurDAG->getTargetConstant(*CN->getConstantIntValue(), 174 operand.getValueType()); 175 return true; 176 } 177 178 const PTXSubtarget& PTXDAGToDAGISel::getSubtarget() const 179 { 180 return TM.getSubtarget<PTXSubtarget>(); 181 } 182 183