Mercurial > hg > CbC > CbC_llvm
comparison lib/Target/MSP430/MSP430ISelDAGToDAG.cpp @ 120:1172e4bd9c6f
update 4.0.0
author | mir3636 |
---|---|
date | Fri, 25 Nov 2016 19:14:25 +0900 |
parents | afa8332a0e37 |
children | 803732b1fca8 |
comparison
equal
deleted
inserted
replaced
101:34baf5011add | 120:1172e4bd9c6f |
---|---|
22 #include "llvm/IR/CallingConv.h" | 22 #include "llvm/IR/CallingConv.h" |
23 #include "llvm/IR/Constants.h" | 23 #include "llvm/IR/Constants.h" |
24 #include "llvm/IR/DerivedTypes.h" | 24 #include "llvm/IR/DerivedTypes.h" |
25 #include "llvm/IR/Function.h" | 25 #include "llvm/IR/Function.h" |
26 #include "llvm/IR/Intrinsics.h" | 26 #include "llvm/IR/Intrinsics.h" |
27 #include "llvm/Support/Compiler.h" | |
28 #include "llvm/Support/Debug.h" | 27 #include "llvm/Support/Debug.h" |
29 #include "llvm/Support/ErrorHandling.h" | 28 #include "llvm/Support/ErrorHandling.h" |
30 #include "llvm/Support/raw_ostream.h" | 29 #include "llvm/Support/raw_ostream.h" |
31 #include "llvm/Target/TargetLowering.h" | 30 #include "llvm/Target/TargetLowering.h" |
32 using namespace llvm; | 31 using namespace llvm; |
94 class MSP430DAGToDAGISel : public SelectionDAGISel { | 93 class MSP430DAGToDAGISel : public SelectionDAGISel { |
95 public: | 94 public: |
96 MSP430DAGToDAGISel(MSP430TargetMachine &TM, CodeGenOpt::Level OptLevel) | 95 MSP430DAGToDAGISel(MSP430TargetMachine &TM, CodeGenOpt::Level OptLevel) |
97 : SelectionDAGISel(TM, OptLevel) {} | 96 : SelectionDAGISel(TM, OptLevel) {} |
98 | 97 |
99 const char *getPassName() const override { | 98 StringRef getPassName() const override { |
100 return "MSP430 DAG->DAG Pattern Instruction Selection"; | 99 return "MSP430 DAG->DAG Pattern Instruction Selection"; |
101 } | 100 } |
102 | 101 |
103 bool MatchAddress(SDValue N, MSP430ISelAddressMode &AM); | 102 bool MatchAddress(SDValue N, MSP430ISelAddressMode &AM); |
104 bool MatchWrapper(SDValue N, MSP430ISelAddressMode &AM); | 103 bool MatchWrapper(SDValue N, MSP430ISelAddressMode &AM); |
109 | 108 |
110 // Include the pieces autogenerated from the target description. | 109 // Include the pieces autogenerated from the target description. |
111 #include "MSP430GenDAGISel.inc" | 110 #include "MSP430GenDAGISel.inc" |
112 | 111 |
113 private: | 112 private: |
114 SDNode *Select(SDNode *N) override; | 113 void Select(SDNode *N) override; |
115 SDNode *SelectIndexedLoad(SDNode *Op); | 114 bool tryIndexedLoad(SDNode *Op); |
116 SDNode *SelectIndexedBinOp(SDNode *Op, SDValue N1, SDValue N2, | 115 bool tryIndexedBinOp(SDNode *Op, SDValue N1, SDValue N2, unsigned Opc8, |
117 unsigned Opc8, unsigned Opc16); | 116 unsigned Opc16); |
118 | 117 |
119 bool SelectAddr(SDValue Addr, SDValue &Base, SDValue &Disp); | 118 bool SelectAddr(SDValue Addr, SDValue &Base, SDValue &Disp); |
120 }; | 119 }; |
121 } // end anonymous namespace | 120 } // end anonymous namespace |
122 | 121 |
322 } | 321 } |
323 | 322 |
324 return true; | 323 return true; |
325 } | 324 } |
326 | 325 |
327 SDNode *MSP430DAGToDAGISel::SelectIndexedLoad(SDNode *N) { | 326 bool MSP430DAGToDAGISel::tryIndexedLoad(SDNode *N) { |
328 LoadSDNode *LD = cast<LoadSDNode>(N); | 327 LoadSDNode *LD = cast<LoadSDNode>(N); |
329 if (!isValidIndexedLoad(LD)) | 328 if (!isValidIndexedLoad(LD)) |
330 return nullptr; | 329 return false; |
331 | 330 |
332 MVT VT = LD->getMemoryVT().getSimpleVT(); | 331 MVT VT = LD->getMemoryVT().getSimpleVT(); |
333 | 332 |
334 unsigned Opcode = 0; | 333 unsigned Opcode = 0; |
335 switch (VT.SimpleTy) { | 334 switch (VT.SimpleTy) { |
338 break; | 337 break; |
339 case MVT::i16: | 338 case MVT::i16: |
340 Opcode = MSP430::MOV16rm_POST; | 339 Opcode = MSP430::MOV16rm_POST; |
341 break; | 340 break; |
342 default: | 341 default: |
343 return nullptr; | 342 return false; |
344 } | 343 } |
345 | 344 |
346 return CurDAG->getMachineNode(Opcode, SDLoc(N), | 345 ReplaceNode(N, |
347 VT, MVT::i16, MVT::Other, | 346 CurDAG->getMachineNode(Opcode, SDLoc(N), VT, MVT::i16, MVT::Other, |
348 LD->getBasePtr(), LD->getChain()); | 347 LD->getBasePtr(), LD->getChain())); |
349 } | 348 return true; |
350 | 349 } |
351 SDNode *MSP430DAGToDAGISel::SelectIndexedBinOp(SDNode *Op, | 350 |
352 SDValue N1, SDValue N2, | 351 bool MSP430DAGToDAGISel::tryIndexedBinOp(SDNode *Op, SDValue N1, SDValue N2, |
353 unsigned Opc8, unsigned Opc16) { | 352 unsigned Opc8, unsigned Opc16) { |
354 if (N1.getOpcode() == ISD::LOAD && | 353 if (N1.getOpcode() == ISD::LOAD && |
355 N1.hasOneUse() && | 354 N1.hasOneUse() && |
356 IsLegalToFold(N1, Op, Op, OptLevel)) { | 355 IsLegalToFold(N1, Op, Op, OptLevel)) { |
357 LoadSDNode *LD = cast<LoadSDNode>(N1); | 356 LoadSDNode *LD = cast<LoadSDNode>(N1); |
358 if (!isValidIndexedLoad(LD)) | 357 if (!isValidIndexedLoad(LD)) |
359 return nullptr; | 358 return false; |
360 | 359 |
361 MVT VT = LD->getMemoryVT().getSimpleVT(); | 360 MVT VT = LD->getMemoryVT().getSimpleVT(); |
362 unsigned Opc = (VT == MVT::i16 ? Opc16 : Opc8); | 361 unsigned Opc = (VT == MVT::i16 ? Opc16 : Opc8); |
363 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1); | 362 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1); |
364 MemRefs0[0] = cast<MemSDNode>(N1)->getMemOperand(); | 363 MemRefs0[0] = cast<MemSDNode>(N1)->getMemOperand(); |
368 cast<MachineSDNode>(ResNode)->setMemRefs(MemRefs0, MemRefs0 + 1); | 367 cast<MachineSDNode>(ResNode)->setMemRefs(MemRefs0, MemRefs0 + 1); |
369 // Transfer chain. | 368 // Transfer chain. |
370 ReplaceUses(SDValue(N1.getNode(), 2), SDValue(ResNode, 2)); | 369 ReplaceUses(SDValue(N1.getNode(), 2), SDValue(ResNode, 2)); |
371 // Transfer writeback. | 370 // Transfer writeback. |
372 ReplaceUses(SDValue(N1.getNode(), 1), SDValue(ResNode, 1)); | 371 ReplaceUses(SDValue(N1.getNode(), 1), SDValue(ResNode, 1)); |
373 return ResNode; | 372 return true; |
374 } | 373 } |
375 | 374 |
376 return nullptr; | 375 return false; |
377 } | 376 } |
378 | 377 |
379 | 378 |
380 SDNode *MSP430DAGToDAGISel::Select(SDNode *Node) { | 379 void MSP430DAGToDAGISel::Select(SDNode *Node) { |
381 SDLoc dl(Node); | 380 SDLoc dl(Node); |
382 | 381 |
383 // Dump information about the Node being selected | 382 // Dump information about the Node being selected |
384 DEBUG(errs() << "Selecting: "); | 383 DEBUG(errs() << "Selecting: "); |
385 DEBUG(Node->dump(CurDAG)); | 384 DEBUG(Node->dump(CurDAG)); |
389 if (Node->isMachineOpcode()) { | 388 if (Node->isMachineOpcode()) { |
390 DEBUG(errs() << "== "; | 389 DEBUG(errs() << "== "; |
391 Node->dump(CurDAG); | 390 Node->dump(CurDAG); |
392 errs() << "\n"); | 391 errs() << "\n"); |
393 Node->setNodeId(-1); | 392 Node->setNodeId(-1); |
394 return nullptr; | 393 return; |
395 } | 394 } |
396 | 395 |
397 // Few custom selection stuff. | 396 // Few custom selection stuff. |
398 switch (Node->getOpcode()) { | 397 switch (Node->getOpcode()) { |
399 default: break; | 398 default: break; |
400 case ISD::FrameIndex: { | 399 case ISD::FrameIndex: { |
401 assert(Node->getValueType(0) == MVT::i16); | 400 assert(Node->getValueType(0) == MVT::i16); |
402 int FI = cast<FrameIndexSDNode>(Node)->getIndex(); | 401 int FI = cast<FrameIndexSDNode>(Node)->getIndex(); |
403 SDValue TFI = CurDAG->getTargetFrameIndex(FI, MVT::i16); | 402 SDValue TFI = CurDAG->getTargetFrameIndex(FI, MVT::i16); |
404 if (Node->hasOneUse()) | 403 if (Node->hasOneUse()) { |
405 return CurDAG->SelectNodeTo(Node, MSP430::ADD16ri, MVT::i16, TFI, | 404 CurDAG->SelectNodeTo(Node, MSP430::ADD16ri, MVT::i16, TFI, |
406 CurDAG->getTargetConstant(0, dl, MVT::i16)); | 405 CurDAG->getTargetConstant(0, dl, MVT::i16)); |
407 return CurDAG->getMachineNode(MSP430::ADD16ri, dl, MVT::i16, TFI, | 406 return; |
408 CurDAG->getTargetConstant(0, dl, MVT::i16)); | 407 } |
408 ReplaceNode(Node, CurDAG->getMachineNode( | |
409 MSP430::ADD16ri, dl, MVT::i16, TFI, | |
410 CurDAG->getTargetConstant(0, dl, MVT::i16))); | |
411 return; | |
409 } | 412 } |
410 case ISD::LOAD: | 413 case ISD::LOAD: |
411 if (SDNode *ResNode = SelectIndexedLoad(Node)) | 414 if (tryIndexedLoad(Node)) |
412 return ResNode; | 415 return; |
413 // Other cases are autogenerated. | 416 // Other cases are autogenerated. |
414 break; | 417 break; |
415 case ISD::ADD: | 418 case ISD::ADD: |
416 if (SDNode *ResNode = | 419 if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1), |
417 SelectIndexedBinOp(Node, | 420 MSP430::ADD8rm_POST, MSP430::ADD16rm_POST)) |
418 Node->getOperand(0), Node->getOperand(1), | 421 return; |
419 MSP430::ADD8rm_POST, MSP430::ADD16rm_POST)) | 422 else if (tryIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), |
420 return ResNode; | 423 MSP430::ADD8rm_POST, MSP430::ADD16rm_POST)) |
421 else if (SDNode *ResNode = | 424 return; |
422 SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), | |
423 MSP430::ADD8rm_POST, MSP430::ADD16rm_POST)) | |
424 return ResNode; | |
425 | 425 |
426 // Other cases are autogenerated. | 426 // Other cases are autogenerated. |
427 break; | 427 break; |
428 case ISD::SUB: | 428 case ISD::SUB: |
429 if (SDNode *ResNode = | 429 if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1), |
430 SelectIndexedBinOp(Node, | 430 MSP430::SUB8rm_POST, MSP430::SUB16rm_POST)) |
431 Node->getOperand(0), Node->getOperand(1), | 431 return; |
432 MSP430::SUB8rm_POST, MSP430::SUB16rm_POST)) | |
433 return ResNode; | |
434 | 432 |
435 // Other cases are autogenerated. | 433 // Other cases are autogenerated. |
436 break; | 434 break; |
437 case ISD::AND: | 435 case ISD::AND: |
438 if (SDNode *ResNode = | 436 if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1), |
439 SelectIndexedBinOp(Node, | 437 MSP430::AND8rm_POST, MSP430::AND16rm_POST)) |
440 Node->getOperand(0), Node->getOperand(1), | 438 return; |
441 MSP430::AND8rm_POST, MSP430::AND16rm_POST)) | 439 else if (tryIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), |
442 return ResNode; | 440 MSP430::AND8rm_POST, MSP430::AND16rm_POST)) |
443 else if (SDNode *ResNode = | 441 return; |
444 SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), | |
445 MSP430::AND8rm_POST, MSP430::AND16rm_POST)) | |
446 return ResNode; | |
447 | 442 |
448 // Other cases are autogenerated. | 443 // Other cases are autogenerated. |
449 break; | 444 break; |
450 case ISD::OR: | 445 case ISD::OR: |
451 if (SDNode *ResNode = | 446 if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1), |
452 SelectIndexedBinOp(Node, | 447 MSP430::OR8rm_POST, MSP430::OR16rm_POST)) |
453 Node->getOperand(0), Node->getOperand(1), | 448 return; |
454 MSP430::OR8rm_POST, MSP430::OR16rm_POST)) | 449 else if (tryIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), |
455 return ResNode; | 450 MSP430::OR8rm_POST, MSP430::OR16rm_POST)) |
456 else if (SDNode *ResNode = | 451 return; |
457 SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), | |
458 MSP430::OR8rm_POST, MSP430::OR16rm_POST)) | |
459 return ResNode; | |
460 | 452 |
461 // Other cases are autogenerated. | 453 // Other cases are autogenerated. |
462 break; | 454 break; |
463 case ISD::XOR: | 455 case ISD::XOR: |
464 if (SDNode *ResNode = | 456 if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1), |
465 SelectIndexedBinOp(Node, | 457 MSP430::XOR8rm_POST, MSP430::XOR16rm_POST)) |
466 Node->getOperand(0), Node->getOperand(1), | 458 return; |
467 MSP430::XOR8rm_POST, MSP430::XOR16rm_POST)) | 459 else if (tryIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), |
468 return ResNode; | 460 MSP430::XOR8rm_POST, MSP430::XOR16rm_POST)) |
469 else if (SDNode *ResNode = | 461 return; |
470 SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), | |
471 MSP430::XOR8rm_POST, MSP430::XOR16rm_POST)) | |
472 return ResNode; | |
473 | 462 |
474 // Other cases are autogenerated. | 463 // Other cases are autogenerated. |
475 break; | 464 break; |
476 } | 465 } |
477 | 466 |
478 // Select the default instruction | 467 // Select the default instruction |
479 SDNode *ResNode = SelectCode(Node); | 468 SelectCode(Node); |
480 | 469 } |
481 DEBUG(errs() << "=> "); | |
482 if (ResNode == nullptr || ResNode == Node) | |
483 DEBUG(Node->dump(CurDAG)); | |
484 else | |
485 DEBUG(ResNode->dump(CurDAG)); | |
486 DEBUG(errs() << "\n"); | |
487 | |
488 return ResNode; | |
489 } |