1 //===- BlackfinISelDAGToDAG.cpp - A dag to dag inst selector for Blackfin -===// 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 Blackfin target. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "Blackfin.h" 15 #include "BlackfinTargetMachine.h" 16 #include "BlackfinRegisterInfo.h" 17 #include "llvm/Intrinsics.h" 18 #include "llvm/CodeGen/SelectionDAGISel.h" 19 #include "llvm/CodeGen/MachineRegisterInfo.h" 20 #include "llvm/Support/Compiler.h" 21 #include "llvm/Support/Debug.h" 22 #include "llvm/Support/ErrorHandling.h" 23 #include "llvm/Support/raw_ostream.h" 24 25 using namespace llvm; 26 27 //===----------------------------------------------------------------------===// 28 // Instruction Selector Implementation 29 //===----------------------------------------------------------------------===// 30 31 //===----------------------------------------------------------------------===// 32 /// BlackfinDAGToDAGISel - Blackfin specific code to select blackfin machine 33 /// instructions for SelectionDAG operations. 34 namespace { 35 class BlackfinDAGToDAGISel : public SelectionDAGISel { 36 /// Subtarget - Keep a pointer to the Blackfin Subtarget around so that we 37 /// can make the right decision when generating code for different targets. 38 //const BlackfinSubtarget &Subtarget; 39 public: 40 BlackfinDAGToDAGISel(BlackfinTargetMachine &TM, CodeGenOpt::Level OptLevel) 41 : SelectionDAGISel(TM, OptLevel) {} 42 43 virtual void PostprocessISelDAG(); 44 45 virtual const char *getPassName() const { 46 return "Blackfin DAG->DAG Pattern Instruction Selection"; 47 } 48 49 // Include the pieces autogenerated from the target description. 50 #include "BlackfinGenDAGISel.inc" 51 52 private: 53 SDNode *Select(SDNode *N); 54 bool SelectADDRspii(SDValue Addr, SDValue &Base, SDValue &Offset); 55 56 // Walk the DAG after instruction selection, fixing register class issues. 57 void FixRegisterClasses(SelectionDAG &DAG); 58 59 const BlackfinInstrInfo &getInstrInfo() { 60 return *static_cast<const BlackfinTargetMachine&>(TM).getInstrInfo(); 61 } 62 const BlackfinRegisterInfo *getRegisterInfo() { 63 return static_cast<const BlackfinTargetMachine&>(TM).getRegisterInfo(); 64 } 65 }; 66 } // end anonymous namespace 67 68 FunctionPass *llvm::createBlackfinISelDag(BlackfinTargetMachine &TM, 69 CodeGenOpt::Level OptLevel) { 70 return new BlackfinDAGToDAGISel(TM, OptLevel); 71 } 72 73 void BlackfinDAGToDAGISel::PostprocessISelDAG() { 74 FixRegisterClasses(*CurDAG); 75 } 76 77 SDNode *BlackfinDAGToDAGISel::Select(SDNode *N) { 78 if (N->isMachineOpcode()) 79 return NULL; // Already selected. 80 81 switch (N->getOpcode()) { 82 default: break; 83 case ISD::FrameIndex: { 84 // Selects to ADDpp FI, 0 which in turn will become ADDimm7 SP, imm or ADDpp 85 // SP, Px 86 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 87 SDValue TFI = CurDAG->getTargetFrameIndex(FI, MVT::i32); 88 return CurDAG->SelectNodeTo(N, BF::ADDpp, MVT::i32, TFI, 89 CurDAG->getTargetConstant(0, MVT::i32)); 90 } 91 } 92 93 return SelectCode(N); 94 } 95 96 bool BlackfinDAGToDAGISel::SelectADDRspii(SDValue Addr, 97 SDValue &Base, 98 SDValue &Offset) { 99 FrameIndexSDNode *FIN = 0; 100 if ((FIN = dyn_cast<FrameIndexSDNode>(Addr))) { 101 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 102 Offset = CurDAG->getTargetConstant(0, MVT::i32); 103 return true; 104 } 105 if (Addr.getOpcode() == ISD::ADD) { 106 ConstantSDNode *CN = 0; 107 if ((FIN = dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) && 108 (CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) && 109 (CN->getSExtValue() % 4 == 0 && CN->getSExtValue() >= 0)) { 110 // Constant positive word offset from frame index 111 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 112 Offset = CurDAG->getTargetConstant(CN->getSExtValue(), MVT::i32); 113 return true; 114 } 115 } 116 return false; 117 } 118 119 static inline bool isCC(const TargetRegisterClass *RC) { 120 return BF::AnyCCRegClass.hasSubClassEq(RC); 121 } 122 123 static inline bool isDCC(const TargetRegisterClass *RC) { 124 return BF::DRegClass.hasSubClassEq(RC) || isCC(RC); 125 } 126 127 static void UpdateNodeOperand(SelectionDAG &DAG, 128 SDNode *N, 129 unsigned Num, 130 SDValue Val) { 131 SmallVector<SDValue, 8> ops(N->op_begin(), N->op_end()); 132 ops[Num] = Val; 133 SDNode *New = DAG.UpdateNodeOperands(N, ops.data(), ops.size()); 134 DAG.ReplaceAllUsesWith(N, New); 135 } 136 137 // After instruction selection, insert COPY_TO_REGCLASS nodes to help in 138 // choosing the proper register classes. 139 void BlackfinDAGToDAGISel::FixRegisterClasses(SelectionDAG &DAG) { 140 const BlackfinInstrInfo &TII = getInstrInfo(); 141 const BlackfinRegisterInfo *TRI = getRegisterInfo(); 142 DAG.AssignTopologicalOrder(); 143 HandleSDNode Dummy(DAG.getRoot()); 144 145 for (SelectionDAG::allnodes_iterator NI = DAG.allnodes_begin(); 146 NI != DAG.allnodes_end(); ++NI) { 147 if (NI->use_empty() || !NI->isMachineOpcode()) 148 continue; 149 const MCInstrDesc &DefMCID = TII.get(NI->getMachineOpcode()); 150 for (SDNode::use_iterator UI = NI->use_begin(); !UI.atEnd(); ++UI) { 151 if (!UI->isMachineOpcode()) 152 continue; 153 154 if (UI.getUse().getResNo() >= DefMCID.getNumDefs()) 155 continue; 156 const TargetRegisterClass *DefRC = 157 TII.getRegClass(DefMCID, UI.getUse().getResNo(), TRI); 158 159 const MCInstrDesc &UseMCID = TII.get(UI->getMachineOpcode()); 160 if (UseMCID.getNumDefs()+UI.getOperandNo() >= UseMCID.getNumOperands()) 161 continue; 162 const TargetRegisterClass *UseRC = 163 TII.getRegClass(UseMCID, UseMCID.getNumDefs()+UI.getOperandNo(), TRI); 164 if (!DefRC || !UseRC) 165 continue; 166 // We cannot copy CC <-> !(CC/D) 167 if ((isCC(DefRC) && !isDCC(UseRC)) || (isCC(UseRC) && !isDCC(DefRC))) { 168 SDNode *Copy = 169 DAG.getMachineNode(TargetOpcode::COPY_TO_REGCLASS, 170 NI->getDebugLoc(), 171 MVT::i32, 172 UI.getUse().get(), 173 DAG.getTargetConstant(BF::DRegClassID, MVT::i32)); 174 UpdateNodeOperand(DAG, *UI, UI.getOperandNo(), SDValue(Copy, 0)); 175 } 176 } 177 } 178 DAG.setRoot(Dummy.getValue()); 179 } 180 181