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 "PTXMachineFunctionInfo.h" 16 #include "PTXTargetMachine.h" 17 #include "llvm/ADT/StringExtras.h" 18 #include "llvm/CodeGen/SelectionDAGISel.h" 19 #include "llvm/DerivedTypes.h" 20 #include "llvm/Support/Debug.h" 21 #include "llvm/Support/raw_ostream.h" 22 23 using namespace llvm; 24 25 namespace { 26 // PTXDAGToDAGISel - PTX specific code to select PTX machine 27 // instructions for SelectionDAG operations. 28 class PTXDAGToDAGISel : public SelectionDAGISel { 29 public: 30 PTXDAGToDAGISel(PTXTargetMachine &TM, CodeGenOpt::Level OptLevel); 31 32 virtual const char *getPassName() const { 33 return "PTX DAG->DAG Pattern Instruction Selection"; 34 } 35 36 SDNode *Select(SDNode *Node); 37 38 // Complex Pattern Selectors. 39 bool SelectADDRrr(SDValue &Addr, SDValue &R1, SDValue &R2); 40 bool SelectADDRri(SDValue &Addr, SDValue &Base, SDValue &Offset); 41 bool SelectADDRii(SDValue &Addr, SDValue &Base, SDValue &Offset); 42 bool SelectADDRlocal(SDValue &Addr, SDValue &Base, SDValue &Offset); 43 44 // Include the pieces auto'gened from the target description 45 #include "PTXGenDAGISel.inc" 46 47 private: 48 // We need this only because we can't match intruction BRAdp 49 // pattern (PTXbrcond bb:$d, ...) in PTXInstrInfo.td 50 SDNode *SelectBRCOND(SDNode *Node); 51 52 SDNode *SelectREADPARAM(SDNode *Node); 53 SDNode *SelectWRITEPARAM(SDNode *Node); 54 SDNode *SelectFrameIndex(SDNode *Node); 55 56 bool isImm(const SDValue &operand); 57 bool SelectImm(const SDValue &operand, SDValue &imm); 58 59 const PTXSubtarget& getSubtarget() const; 60 }; // class PTXDAGToDAGISel 61 } // namespace 62 63 // createPTXISelDag - This pass converts a legalized DAG into a 64 // PTX-specific DAG, ready for instruction scheduling 65 FunctionPass *llvm::createPTXISelDag(PTXTargetMachine &TM, 66 CodeGenOpt::Level OptLevel) { 67 return new PTXDAGToDAGISel(TM, OptLevel); 68 } 69 70 PTXDAGToDAGISel::PTXDAGToDAGISel(PTXTargetMachine &TM, 71 CodeGenOpt::Level OptLevel) 72 : SelectionDAGISel(TM, OptLevel) {} 73 74 SDNode *PTXDAGToDAGISel::Select(SDNode *Node) { 75 switch (Node->getOpcode()) { 76 case ISD::BRCOND: 77 return SelectBRCOND(Node); 78 case PTXISD::READ_PARAM: 79 return SelectREADPARAM(Node); 80 case PTXISD::WRITE_PARAM: 81 return SelectWRITEPARAM(Node); 82 case ISD::FrameIndex: 83 return SelectFrameIndex(Node); 84 default: 85 return SelectCode(Node); 86 } 87 } 88 89 SDNode *PTXDAGToDAGISel::SelectBRCOND(SDNode *Node) { 90 assert(Node->getNumOperands() >= 3); 91 92 SDValue Chain = Node->getOperand(0); 93 SDValue Pred = Node->getOperand(1); 94 SDValue Target = Node->getOperand(2); // branch target 95 SDValue PredOp = CurDAG->getTargetConstant(PTXPredicate::Normal, MVT::i32); 96 DebugLoc dl = Node->getDebugLoc(); 97 98 assert(Target.getOpcode() == ISD::BasicBlock); 99 assert(Pred.getValueType() == MVT::i1); 100 101 // Emit BRAdp 102 SDValue Ops[] = { Target, Pred, PredOp, Chain }; 103 return CurDAG->getMachineNode(PTX::BRAdp, dl, MVT::Other, Ops, 4); 104 } 105 106 SDNode *PTXDAGToDAGISel::SelectREADPARAM(SDNode *Node) { 107 SDValue Chain = Node->getOperand(0); 108 SDValue Index = Node->getOperand(1); 109 110 int OpCode; 111 112 // Get the type of parameter we are reading 113 EVT VT = Node->getValueType(0); 114 assert(VT.isSimple() && "READ_PARAM only implemented for MVT types"); 115 116 MVT Type = VT.getSimpleVT(); 117 118 if (Type == MVT::i1) 119 OpCode = PTX::READPARAMPRED; 120 else if (Type == MVT::i16) 121 OpCode = PTX::READPARAMI16; 122 else if (Type == MVT::i32) 123 OpCode = PTX::READPARAMI32; 124 else if (Type == MVT::i64) 125 OpCode = PTX::READPARAMI64; 126 else if (Type == MVT::f32) 127 OpCode = PTX::READPARAMF32; 128 else { 129 assert(Type == MVT::f64 && "Unexpected type!"); 130 OpCode = PTX::READPARAMF64; 131 } 132 133 SDValue Pred = CurDAG->getRegister(PTX::NoRegister, MVT::i1); 134 SDValue PredOp = CurDAG->getTargetConstant(PTXPredicate::None, MVT::i32); 135 DebugLoc dl = Node->getDebugLoc(); 136 137 SDValue Ops[] = { Index, Pred, PredOp, Chain }; 138 return CurDAG->getMachineNode(OpCode, dl, VT, Ops, 4); 139 } 140 141 SDNode *PTXDAGToDAGISel::SelectWRITEPARAM(SDNode *Node) { 142 143 SDValue Chain = Node->getOperand(0); 144 SDValue Value = Node->getOperand(1); 145 146 int OpCode; 147 148 //Node->dumpr(CurDAG); 149 150 // Get the type of parameter we are writing 151 EVT VT = Value->getValueType(0); 152 assert(VT.isSimple() && "WRITE_PARAM only implemented for MVT types"); 153 154 MVT Type = VT.getSimpleVT(); 155 156 if (Type == MVT::i1) 157 OpCode = PTX::WRITEPARAMPRED; 158 else if (Type == MVT::i16) 159 OpCode = PTX::WRITEPARAMI16; 160 else if (Type == MVT::i32) 161 OpCode = PTX::WRITEPARAMI32; 162 else if (Type == MVT::i64) 163 OpCode = PTX::WRITEPARAMI64; 164 else if (Type == MVT::f32) 165 OpCode = PTX::WRITEPARAMF32; 166 else if (Type == MVT::f64) 167 OpCode = PTX::WRITEPARAMF64; 168 else 169 llvm_unreachable("Invalid type in SelectWRITEPARAM"); 170 171 SDValue Pred = CurDAG->getRegister(PTX::NoRegister, MVT::i1); 172 SDValue PredOp = CurDAG->getTargetConstant(PTXPredicate::None, MVT::i32); 173 DebugLoc dl = Node->getDebugLoc(); 174 175 SDValue Ops[] = { Value, Pred, PredOp, Chain }; 176 SDNode* Ret = CurDAG->getMachineNode(OpCode, dl, MVT::Other, Ops, 4); 177 178 //dbgs() << "SelectWRITEPARAM produced:\n\t"; 179 //Ret->dumpr(CurDAG); 180 181 return Ret; 182 } 183 184 SDNode *PTXDAGToDAGISel::SelectFrameIndex(SDNode *Node) { 185 int FI = cast<FrameIndexSDNode>(Node)->getIndex(); 186 //dbgs() << "Selecting FrameIndex at index " << FI << "\n"; 187 //SDValue TFI = CurDAG->getTargetFrameIndex(FI, Node->getValueType(0)); 188 189 PTXMachineFunctionInfo *MFI = MF->getInfo<PTXMachineFunctionInfo>(); 190 191 SDValue FrameSymbol = CurDAG->getTargetExternalSymbol(MFI->getFrameSymbol(FI), 192 Node->getValueType(0)); 193 194 return FrameSymbol.getNode(); 195 } 196 197 // Match memory operand of the form [reg+reg] 198 bool PTXDAGToDAGISel::SelectADDRrr(SDValue &Addr, SDValue &R1, SDValue &R2) { 199 if (Addr.getOpcode() != ISD::ADD || Addr.getNumOperands() < 2 || 200 isImm(Addr.getOperand(0)) || isImm(Addr.getOperand(1))) 201 return false; 202 203 assert(Addr.getValueType().isSimple() && "Type must be simple"); 204 205 R1 = Addr; 206 R2 = CurDAG->getTargetConstant(0, Addr.getValueType().getSimpleVT()); 207 208 return true; 209 } 210 211 // Match memory operand of the form [reg], [imm+reg], and [reg+imm] 212 bool PTXDAGToDAGISel::SelectADDRri(SDValue &Addr, SDValue &Base, 213 SDValue &Offset) { 214 // FrameIndex addresses are handled separately 215 //errs() << "SelectADDRri: "; 216 //Addr.getNode()->dumpr(); 217 if (isa<FrameIndexSDNode>(Addr)) { 218 //errs() << "Failure\n"; 219 return false; 220 } 221 222 if (CurDAG->isBaseWithConstantOffset(Addr)) { 223 Base = Addr.getOperand(0); 224 if (isa<FrameIndexSDNode>(Base)) { 225 //errs() << "Failure\n"; 226 return false; 227 } 228 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)); 229 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), MVT::i32); 230 //errs() << "Success\n"; 231 return true; 232 } 233 234 /*if (Addr.getNumOperands() == 1) { 235 Base = Addr; 236 Offset = CurDAG->getTargetConstant(0, Addr.getValueType().getSimpleVT()); 237 errs() << "Success\n"; 238 return true; 239 }*/ 240 241 //errs() << "SelectADDRri fails on: "; 242 //Addr.getNode()->dumpr(); 243 244 if (isImm(Addr)) { 245 //errs() << "Failure\n"; 246 return false; 247 } 248 249 Base = Addr; 250 Offset = CurDAG->getTargetConstant(0, Addr.getValueType().getSimpleVT()); 251 252 //errs() << "Success\n"; 253 return true; 254 255 /*if (Addr.getOpcode() != ISD::ADD) { 256 // let SelectADDRii handle the [imm] case 257 if (isImm(Addr)) 258 return false; 259 // it is [reg] 260 261 assert(Addr.getValueType().isSimple() && "Type must be simple"); 262 Base = Addr; 263 Offset = CurDAG->getTargetConstant(0, Addr.getValueType().getSimpleVT()); 264 265 return true; 266 } 267 268 if (Addr.getNumOperands() < 2) 269 return false; 270 271 // let SelectADDRii handle the [imm+imm] case 272 if (isImm(Addr.getOperand(0)) && isImm(Addr.getOperand(1))) 273 return false; 274 275 // try [reg+imm] and [imm+reg] 276 for (int i = 0; i < 2; i ++) 277 if (SelectImm(Addr.getOperand(1-i), Offset)) { 278 Base = Addr.getOperand(i); 279 return true; 280 } 281 282 // neither [reg+imm] nor [imm+reg] 283 return false;*/ 284 } 285 286 // Match memory operand of the form [imm+imm] and [imm] 287 bool PTXDAGToDAGISel::SelectADDRii(SDValue &Addr, SDValue &Base, 288 SDValue &Offset) { 289 // is [imm+imm]? 290 if (Addr.getOpcode() == ISD::ADD) { 291 return SelectImm(Addr.getOperand(0), Base) && 292 SelectImm(Addr.getOperand(1), Offset); 293 } 294 295 // is [imm]? 296 if (SelectImm(Addr, Base)) { 297 assert(Addr.getValueType().isSimple() && "Type must be simple"); 298 299 Offset = CurDAG->getTargetConstant(0, Addr.getValueType().getSimpleVT()); 300 301 return true; 302 } 303 304 return false; 305 } 306 307 // Match memory operand of the form [reg], [imm+reg], and [reg+imm] 308 bool PTXDAGToDAGISel::SelectADDRlocal(SDValue &Addr, SDValue &Base, 309 SDValue &Offset) { 310 //errs() << "SelectADDRlocal: "; 311 //Addr.getNode()->dumpr(); 312 if (isa<FrameIndexSDNode>(Addr)) { 313 Base = Addr; 314 Offset = CurDAG->getTargetConstant(0, Addr.getValueType().getSimpleVT()); 315 //errs() << "Success\n"; 316 return true; 317 } 318 319 if (CurDAG->isBaseWithConstantOffset(Addr)) { 320 Base = Addr.getOperand(0); 321 if (!isa<FrameIndexSDNode>(Base)) { 322 //errs() << "Failure\n"; 323 return false; 324 } 325 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)); 326 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), MVT::i32); 327 //errs() << "Offset: "; 328 //Offset.getNode()->dumpr(); 329 //errs() << "Success\n"; 330 return true; 331 } 332 333 //errs() << "Failure\n"; 334 return false; 335 } 336 337 bool PTXDAGToDAGISel::isImm(const SDValue &operand) { 338 return ConstantSDNode::classof(operand.getNode()); 339 } 340 341 bool PTXDAGToDAGISel::SelectImm(const SDValue &operand, SDValue &imm) { 342 SDNode *node = operand.getNode(); 343 if (!ConstantSDNode::classof(node)) 344 return false; 345 346 ConstantSDNode *CN = cast<ConstantSDNode>(node); 347 imm = CurDAG->getTargetConstant(*CN->getConstantIntValue(), 348 operand.getValueType()); 349 return true; 350 } 351 352 const PTXSubtarget& PTXDAGToDAGISel::getSubtarget() const 353 { 354 return TM.getSubtarget<PTXSubtarget>(); 355 } 356 357