1 //===-- MipsISelDAGToDAG.cpp - A Dag to Dag Inst Selector for Mips --------===// 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 MIPS target. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "MipsISelDAGToDAG.h" 14 #include "Mips.h" 15 #include "MipsMachineFunction.h" 16 #include "llvm/CodeGen/MachineConstantPool.h" 17 #include "llvm/CodeGen/MachineFrameInfo.h" 18 #include "llvm/CodeGen/MachineFunction.h" 19 #include "llvm/CodeGen/SelectionDAG.h" 20 #include "llvm/CodeGen/SelectionDAGNodes.h" 21 #include "llvm/CodeGen/StackProtector.h" 22 #include "llvm/IR/Instructions.h" 23 #include "llvm/IR/Type.h" 24 #include "llvm/Support/Debug.h" 25 #include "llvm/Support/ErrorHandling.h" 26 #include "llvm/Support/KnownBits.h" 27 #include "llvm/Support/raw_ostream.h" 28 using namespace llvm; 29 30 #define DEBUG_TYPE "mips-isel" 31 #define PASS_NAME "MIPS DAG->DAG Pattern Instruction Selection" 32 33 //===----------------------------------------------------------------------===// 34 // Instruction Selector Implementation 35 //===----------------------------------------------------------------------===// 36 37 //===----------------------------------------------------------------------===// 38 // MipsDAGToDAGISel - MIPS specific code to select MIPS machine 39 // instructions for SelectionDAG operations. 40 //===----------------------------------------------------------------------===// 41 42 void MipsDAGToDAGISelLegacy::getAnalysisUsage(AnalysisUsage &AU) const { 43 // There are multiple MipsDAGToDAGISel instances added to the pass pipeline. 44 // We need to preserve StackProtector for the next one. 45 AU.addPreserved<StackProtector>(); 46 SelectionDAGISelLegacy::getAnalysisUsage(AU); 47 } 48 49 bool MipsDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) { 50 Subtarget = &MF.getSubtarget<MipsSubtarget>(); 51 bool Ret = SelectionDAGISel::runOnMachineFunction(MF); 52 53 processFunctionAfterISel(MF); 54 55 return Ret; 56 } 57 58 /// getGlobalBaseReg - Output the instructions required to put the 59 /// GOT address into a register. 60 SDNode *MipsDAGToDAGISel::getGlobalBaseReg() { 61 Register GlobalBaseReg = MF->getInfo<MipsFunctionInfo>()->getGlobalBaseReg(*MF); 62 return CurDAG->getRegister(GlobalBaseReg, getTargetLowering()->getPointerTy( 63 CurDAG->getDataLayout())) 64 .getNode(); 65 } 66 67 /// ComplexPattern used on MipsInstrInfo 68 /// Used on Mips Load/Store instructions 69 bool MipsDAGToDAGISel::selectAddrRegImm(SDValue Addr, SDValue &Base, 70 SDValue &Offset) const { 71 llvm_unreachable("Unimplemented function."); 72 return false; 73 } 74 75 bool MipsDAGToDAGISel::selectAddrDefault(SDValue Addr, SDValue &Base, 76 SDValue &Offset) const { 77 llvm_unreachable("Unimplemented function."); 78 return false; 79 } 80 81 bool MipsDAGToDAGISel::selectIntAddr(SDValue Addr, SDValue &Base, 82 SDValue &Offset) const { 83 llvm_unreachable("Unimplemented function."); 84 return false; 85 } 86 87 bool MipsDAGToDAGISel::selectIntAddr11MM(SDValue Addr, SDValue &Base, 88 SDValue &Offset) const { 89 llvm_unreachable("Unimplemented function."); 90 return false; 91 } 92 93 bool MipsDAGToDAGISel::selectIntAddr12MM(SDValue Addr, SDValue &Base, 94 SDValue &Offset) const { 95 llvm_unreachable("Unimplemented function."); 96 return false; 97 } 98 99 bool MipsDAGToDAGISel::selectIntAddr16MM(SDValue Addr, SDValue &Base, 100 SDValue &Offset) const { 101 llvm_unreachable("Unimplemented function."); 102 return false; 103 } 104 105 bool MipsDAGToDAGISel::selectIntAddrLSL2MM(SDValue Addr, SDValue &Base, 106 SDValue &Offset) const { 107 llvm_unreachable("Unimplemented function."); 108 return false; 109 } 110 111 bool MipsDAGToDAGISel::selectIntAddrSImm10(SDValue Addr, SDValue &Base, 112 SDValue &Offset) const { 113 llvm_unreachable("Unimplemented function."); 114 return false; 115 } 116 117 bool MipsDAGToDAGISel::selectIntAddrSImm10Lsl1(SDValue Addr, SDValue &Base, 118 SDValue &Offset) const { 119 llvm_unreachable("Unimplemented function."); 120 return false; 121 } 122 123 bool MipsDAGToDAGISel::selectIntAddrSImm10Lsl2(SDValue Addr, SDValue &Base, 124 SDValue &Offset) const { 125 llvm_unreachable("Unimplemented function."); 126 return false; 127 } 128 129 bool MipsDAGToDAGISel::selectIntAddrSImm10Lsl3(SDValue Addr, SDValue &Base, 130 SDValue &Offset) const { 131 llvm_unreachable("Unimplemented function."); 132 return false; 133 } 134 135 bool MipsDAGToDAGISel::selectAddr16(SDValue Addr, SDValue &Base, 136 SDValue &Offset) { 137 llvm_unreachable("Unimplemented function."); 138 return false; 139 } 140 141 bool MipsDAGToDAGISel::selectAddr16SP(SDValue Addr, SDValue &Base, 142 SDValue &Offset) { 143 llvm_unreachable("Unimplemented function."); 144 return false; 145 } 146 147 bool MipsDAGToDAGISel::selectVSplat(SDNode *N, APInt &Imm, 148 unsigned MinSizeInBits) const { 149 llvm_unreachable("Unimplemented function."); 150 return false; 151 } 152 153 bool MipsDAGToDAGISel::selectVSplatCommon(SDValue N, SDValue &Imm, bool Signed, 154 unsigned ImmBitSize) const { 155 llvm_unreachable("Unimplemented function."); 156 } 157 158 bool MipsDAGToDAGISel::selectVSplatUimmPow2(SDValue N, SDValue &Imm) const { 159 llvm_unreachable("Unimplemented function."); 160 return false; 161 } 162 163 bool MipsDAGToDAGISel::selectVSplatUimmInvPow2(SDValue N, SDValue &Imm) const { 164 llvm_unreachable("Unimplemented function."); 165 return false; 166 } 167 168 bool MipsDAGToDAGISel::selectVSplatMaskL(SDValue N, SDValue &Imm) const { 169 llvm_unreachable("Unimplemented function."); 170 return false; 171 } 172 173 bool MipsDAGToDAGISel::selectVSplatMaskR(SDValue N, SDValue &Imm) const { 174 llvm_unreachable("Unimplemented function."); 175 return false; 176 } 177 178 bool MipsDAGToDAGISel::selectVSplatImmEq1(SDValue N) const { 179 llvm_unreachable("Unimplemented function."); 180 } 181 182 /// Convert vector addition with vector subtraction if that allows to encode 183 /// constant as an immediate and thus avoid extra 'ldi' instruction. 184 /// add X, <-1, -1...> --> sub X, <1, 1...> 185 bool MipsDAGToDAGISel::selectVecAddAsVecSubIfProfitable(SDNode *Node) { 186 assert(Node->getOpcode() == ISD::ADD && "Should only get 'add' here."); 187 188 EVT VT = Node->getValueType(0); 189 assert(VT.isVector() && "Should only be called for vectors."); 190 191 SDValue X = Node->getOperand(0); 192 SDValue C = Node->getOperand(1); 193 194 auto *BVN = dyn_cast<BuildVectorSDNode>(C); 195 if (!BVN) 196 return false; 197 198 APInt SplatValue, SplatUndef; 199 unsigned SplatBitSize; 200 bool HasAnyUndefs; 201 202 if (!BVN->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs, 203 8, !Subtarget->isLittle())) 204 return false; 205 206 auto IsInlineConstant = [](const APInt &Imm) { return Imm.isIntN(5); }; 207 208 if (IsInlineConstant(SplatValue)) 209 return false; // Can already be encoded as an immediate. 210 211 APInt NegSplatValue = 0 - SplatValue; 212 if (!IsInlineConstant(NegSplatValue)) 213 return false; // Even if we negate it it won't help. 214 215 SDLoc DL(Node); 216 217 SDValue NegC = CurDAG->FoldConstantArithmetic( 218 ISD::SUB, DL, VT, {CurDAG->getConstant(0, DL, VT), C}); 219 assert(NegC && "Constant-folding failed!"); 220 SDValue NewNode = CurDAG->getNode(ISD::SUB, DL, VT, X, NegC); 221 222 ReplaceNode(Node, NewNode.getNode()); 223 SelectCode(NewNode.getNode()); 224 return true; 225 } 226 227 /// Select instructions not customized! Used for 228 /// expanded, promoted and normal instructions 229 void MipsDAGToDAGISel::Select(SDNode *Node) { 230 unsigned Opcode = Node->getOpcode(); 231 232 // If we have a custom node, we already have selected! 233 if (Node->isMachineOpcode()) { 234 LLVM_DEBUG(errs() << "== "; Node->dump(CurDAG); errs() << "\n"); 235 Node->setNodeId(-1); 236 return; 237 } 238 239 // See if subclasses can handle this node. 240 if (trySelect(Node)) 241 return; 242 243 switch(Opcode) { 244 default: break; 245 246 case ISD::ADD: 247 if (Node->getSimpleValueType(0).isVector() && 248 selectVecAddAsVecSubIfProfitable(Node)) 249 return; 250 break; 251 252 // Get target GOT address. 253 case ISD::GLOBAL_OFFSET_TABLE: 254 ReplaceNode(Node, getGlobalBaseReg()); 255 return; 256 257 #ifndef NDEBUG 258 case ISD::LOAD: 259 case ISD::STORE: 260 assert((Subtarget->systemSupportsUnalignedAccess() || 261 cast<MemSDNode>(Node)->getAlign() >= 262 cast<MemSDNode>(Node)->getMemoryVT().getStoreSize()) && 263 "Unexpected unaligned loads/stores."); 264 break; 265 #endif 266 } 267 268 // Select the default instruction 269 SelectCode(Node); 270 } 271 272 bool MipsDAGToDAGISel::SelectInlineAsmMemoryOperand( 273 const SDValue &Op, InlineAsm::ConstraintCode ConstraintID, 274 std::vector<SDValue> &OutOps) { 275 // All memory constraints can at least accept raw pointers. 276 switch(ConstraintID) { 277 default: 278 llvm_unreachable("Unexpected asm memory constraint"); 279 case InlineAsm::ConstraintCode::m: 280 case InlineAsm::ConstraintCode::R: 281 case InlineAsm::ConstraintCode::ZC: 282 OutOps.push_back(Op); 283 return false; 284 } 285 return true; 286 } 287 288 bool MipsDAGToDAGISel::isUnneededShiftMask(SDNode *N, 289 unsigned ShAmtBits) const { 290 assert(N->getOpcode() == ISD::AND && "Unexpected opcode"); 291 292 const APInt &RHS = N->getConstantOperandAPInt(1); 293 if (RHS.countr_one() >= ShAmtBits) { 294 LLVM_DEBUG( 295 dbgs() 296 << DEBUG_TYPE 297 << " Need optimize 'and & shl/srl/sra' and operand value bits is " 298 << RHS.countr_one() << "\n"); 299 return true; 300 } 301 302 KnownBits Known = CurDAG->computeKnownBits(N->getOperand(0)); 303 return (Known.Zero | RHS).countr_one() >= ShAmtBits; 304 } 305 306 char MipsDAGToDAGISelLegacy::ID = 0; 307 308 MipsDAGToDAGISelLegacy::MipsDAGToDAGISelLegacy( 309 std::unique_ptr<SelectionDAGISel> S) 310 : SelectionDAGISelLegacy(ID, std::move(S)) {} 311 312 INITIALIZE_PASS(MipsDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) 313