1 //===-- VEISelDAGToDAG.cpp - A dag to dag inst selector for VE ------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines an instruction selector for the VE target. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "VETargetMachine.h" 14 #include "llvm/CodeGen/MachineRegisterInfo.h" 15 #include "llvm/CodeGen/SelectionDAGISel.h" 16 #include "llvm/IR/Intrinsics.h" 17 #include "llvm/Support/Debug.h" 18 #include "llvm/Support/ErrorHandling.h" 19 #include "llvm/Support/raw_ostream.h" 20 using namespace llvm; 21 22 //===----------------------------------------------------------------------===// 23 // Instruction Selector Implementation 24 //===----------------------------------------------------------------------===// 25 26 //===--------------------------------------------------------------------===// 27 /// VEDAGToDAGISel - VE specific code to select VE machine 28 /// instructions for SelectionDAG operations. 29 /// 30 namespace { 31 class VEDAGToDAGISel : public SelectionDAGISel { 32 /// Subtarget - Keep a pointer to the VE Subtarget around so that we can 33 /// make the right decision when generating code for different targets. 34 const VESubtarget *Subtarget; 35 36 public: 37 explicit VEDAGToDAGISel(VETargetMachine &tm) : SelectionDAGISel(tm) {} 38 39 bool runOnMachineFunction(MachineFunction &MF) override { 40 Subtarget = &MF.getSubtarget<VESubtarget>(); 41 return SelectionDAGISel::runOnMachineFunction(MF); 42 } 43 44 void Select(SDNode *N) override; 45 46 // Complex Pattern Selectors. 47 bool SelectADDRrr(SDValue N, SDValue &R1, SDValue &R2); 48 bool SelectADDRri(SDValue N, SDValue &Base, SDValue &Offset); 49 50 StringRef getPassName() const override { 51 return "VE DAG->DAG Pattern Instruction Selection"; 52 } 53 54 // Include the pieces autogenerated from the target description. 55 #include "VEGenDAGISel.inc" 56 }; 57 } // end anonymous namespace 58 59 bool VEDAGToDAGISel::SelectADDRrr(SDValue Addr, SDValue &R1, SDValue &R2) { 60 if (Addr.getOpcode() == ISD::FrameIndex) 61 return false; 62 if (Addr.getOpcode() == ISD::TargetExternalSymbol || 63 Addr.getOpcode() == ISD::TargetGlobalAddress || 64 Addr.getOpcode() == ISD::TargetGlobalTLSAddress) 65 return false; // direct calls. 66 67 if (Addr.getOpcode() == ISD::ADD) { 68 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) 69 if (isInt<13>(CN->getSExtValue())) 70 return false; // Let the reg+imm pattern catch this! 71 if (Addr.getOperand(0).getOpcode() == VEISD::Lo || 72 Addr.getOperand(1).getOpcode() == VEISD::Lo) 73 return false; // Let the reg+imm pattern catch this! 74 R1 = Addr.getOperand(0); 75 R2 = Addr.getOperand(1); 76 return true; 77 } 78 79 return false; // Let the reg+imm pattern catch this! 80 } 81 82 bool VEDAGToDAGISel::SelectADDRri(SDValue Addr, SDValue &Base, 83 SDValue &Offset) { 84 auto AddrTy = Addr->getValueType(0); 85 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 86 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), AddrTy); 87 Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32); 88 return true; 89 } 90 if (Addr.getOpcode() == ISD::TargetExternalSymbol || 91 Addr.getOpcode() == ISD::TargetGlobalAddress || 92 Addr.getOpcode() == ISD::TargetGlobalTLSAddress) 93 return false; // direct calls. 94 95 if (CurDAG->isBaseWithConstantOffset(Addr)) { 96 ConstantSDNode *CN = cast<ConstantSDNode>(Addr.getOperand(1)); 97 if (isInt<13>(CN->getSExtValue())) { 98 if (FrameIndexSDNode *FIN = 99 dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) { 100 // Constant offset from frame ref. 101 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), AddrTy); 102 } else { 103 Base = Addr.getOperand(0); 104 } 105 Offset = 106 CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), MVT::i32); 107 return true; 108 } 109 } 110 Base = Addr; 111 Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32); 112 return true; 113 } 114 115 void VEDAGToDAGISel::Select(SDNode *N) { 116 SDLoc dl(N); 117 if (N->isMachineOpcode()) { 118 N->setNodeId(-1); 119 return; // Already selected. 120 } 121 122 SelectCode(N); 123 } 124 125 /// createVEISelDag - This pass converts a legalized DAG into a 126 /// VE-specific DAG, ready for instruction scheduling. 127 /// 128 FunctionPass *llvm::createVEISelDag(VETargetMachine &TM) { 129 return new VEDAGToDAGISel(TM); 130 } 131