MipsSEISelLowering.cpp revision 9367b8d4f254d9e5cccb15334cc1a969c5be0d31
1//===-- MipsSEISelLowering.cpp - MipsSE DAG Lowering Interface --*- C++ -*-===// 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// Subclass of MipsTargetLowering specialized for mips32/64. 11// 12//===----------------------------------------------------------------------===// 13#include "MipsSEISelLowering.h" 14#include "MipsRegisterInfo.h" 15#include "MipsTargetMachine.h" 16#include "llvm/CodeGen/MachineInstrBuilder.h" 17#include "llvm/CodeGen/MachineRegisterInfo.h" 18#include "llvm/Support/CommandLine.h" 19#include "llvm/Target/TargetInstrInfo.h" 20 21using namespace llvm; 22 23static cl::opt<bool> 24EnableMipsTailCalls("enable-mips-tail-calls", cl::Hidden, 25 cl::desc("MIPS: Enable tail calls."), cl::init(false)); 26 27MipsSETargetLowering::MipsSETargetLowering(MipsTargetMachine &TM) 28 : MipsTargetLowering(TM) { 29 // Set up the register classes 30 31 clearRegisterClasses(); 32 33 addRegisterClass(MVT::i32, &Mips::CPURegsRegClass); 34 35 if (HasMips64) 36 addRegisterClass(MVT::i64, &Mips::CPU64RegsRegClass); 37 38 if (Subtarget->hasDSP()) { 39 MVT::SimpleValueType VecTys[2] = {MVT::v2i16, MVT::v4i8}; 40 41 for (unsigned i = 0; i < array_lengthof(VecTys); ++i) { 42 addRegisterClass(VecTys[i], &Mips::DSPRegsRegClass); 43 44 // Expand all builtin opcodes. 45 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc) 46 setOperationAction(Opc, VecTys[i], Expand); 47 48 setOperationAction(ISD::ADD, VecTys[i], Legal); 49 setOperationAction(ISD::SUB, VecTys[i], Legal); 50 setOperationAction(ISD::LOAD, VecTys[i], Legal); 51 setOperationAction(ISD::STORE, VecTys[i], Legal); 52 setOperationAction(ISD::BITCAST, VecTys[i], Legal); 53 } 54 } 55 56 if (Subtarget->hasDSPR2()) 57 setOperationAction(ISD::MUL, MVT::v2i16, Legal); 58 59 if (!TM.Options.UseSoftFloat) { 60 addRegisterClass(MVT::f32, &Mips::FGR32RegClass); 61 62 // When dealing with single precision only, use libcalls 63 if (!Subtarget->isSingleFloat()) { 64 if (HasMips64) 65 addRegisterClass(MVT::f64, &Mips::FGR64RegClass); 66 else 67 addRegisterClass(MVT::f64, &Mips::AFGR64RegClass); 68 } 69 } 70 71 setOperationAction(ISD::SMUL_LOHI, MVT::i32, Custom); 72 setOperationAction(ISD::UMUL_LOHI, MVT::i32, Custom); 73 setOperationAction(ISD::MULHS, MVT::i32, Custom); 74 setOperationAction(ISD::MULHU, MVT::i32, Custom); 75 76 if (HasMips64) { 77 setOperationAction(ISD::MULHS, MVT::i64, Custom); 78 setOperationAction(ISD::MULHU, MVT::i64, Custom); 79 setOperationAction(ISD::MUL, MVT::i64, Custom); 80 } 81 82 setOperationAction(ISD::SDIVREM, MVT::i32, Custom); 83 setOperationAction(ISD::UDIVREM, MVT::i32, Custom); 84 setOperationAction(ISD::SDIVREM, MVT::i64, Custom); 85 setOperationAction(ISD::UDIVREM, MVT::i64, Custom); 86 setOperationAction(ISD::MEMBARRIER, MVT::Other, Custom); 87 setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom); 88 setOperationAction(ISD::LOAD, MVT::i32, Custom); 89 setOperationAction(ISD::STORE, MVT::i32, Custom); 90 91 setTargetDAGCombine(ISD::ADDE); 92 setTargetDAGCombine(ISD::SUBE); 93 94 computeRegisterProperties(); 95} 96 97const MipsTargetLowering * 98llvm::createMipsSETargetLowering(MipsTargetMachine &TM) { 99 return new MipsSETargetLowering(TM); 100} 101 102 103bool 104MipsSETargetLowering::allowsUnalignedMemoryAccesses(EVT VT, bool *Fast) const { 105 MVT::SimpleValueType SVT = VT.getSimpleVT().SimpleTy; 106 107 switch (SVT) { 108 case MVT::i64: 109 case MVT::i32: 110 if (Fast) 111 *Fast = true; 112 return true; 113 default: 114 return false; 115 } 116} 117 118SDValue MipsSETargetLowering::LowerOperation(SDValue Op, 119 SelectionDAG &DAG) const { 120 switch(Op.getOpcode()) { 121 case ISD::SMUL_LOHI: return lowerMulDiv(Op, MipsISD::Mult, true, true, DAG); 122 case ISD::UMUL_LOHI: return lowerMulDiv(Op, MipsISD::Multu, true, true, DAG); 123 case ISD::MULHS: return lowerMulDiv(Op, MipsISD::Mult, false, true, DAG); 124 case ISD::MULHU: return lowerMulDiv(Op, MipsISD::Multu, false, true, DAG); 125 case ISD::MUL: return lowerMulDiv(Op, MipsISD::Mult, true, false, DAG); 126 case ISD::SDIVREM: return lowerMulDiv(Op, MipsISD::DivRem, true, true, DAG); 127 case ISD::UDIVREM: return lowerMulDiv(Op, MipsISD::DivRemU, true, true, DAG); 128 } 129 130 return MipsTargetLowering::LowerOperation(Op, DAG); 131} 132 133// selectMADD - 134// Transforms a subgraph in CurDAG if the following pattern is found: 135// (addc multLo, Lo0), (adde multHi, Hi0), 136// where, 137// multHi/Lo: product of multiplication 138// Lo0: initial value of Lo register 139// Hi0: initial value of Hi register 140// Return true if pattern matching was successful. 141static bool selectMADD(SDNode *ADDENode, SelectionDAG *CurDAG) { 142 // ADDENode's second operand must be a flag output of an ADDC node in order 143 // for the matching to be successful. 144 SDNode *ADDCNode = ADDENode->getOperand(2).getNode(); 145 146 if (ADDCNode->getOpcode() != ISD::ADDC) 147 return false; 148 149 SDValue MultHi = ADDENode->getOperand(0); 150 SDValue MultLo = ADDCNode->getOperand(0); 151 SDNode *MultNode = MultHi.getNode(); 152 unsigned MultOpc = MultHi.getOpcode(); 153 154 // MultHi and MultLo must be generated by the same node, 155 if (MultLo.getNode() != MultNode) 156 return false; 157 158 // and it must be a multiplication. 159 if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI) 160 return false; 161 162 // MultLo amd MultHi must be the first and second output of MultNode 163 // respectively. 164 if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0) 165 return false; 166 167 // Transform this to a MADD only if ADDENode and ADDCNode are the only users 168 // of the values of MultNode, in which case MultNode will be removed in later 169 // phases. 170 // If there exist users other than ADDENode or ADDCNode, this function returns 171 // here, which will result in MultNode being mapped to a single MULT 172 // instruction node rather than a pair of MULT and MADD instructions being 173 // produced. 174 if (!MultHi.hasOneUse() || !MultLo.hasOneUse()) 175 return false; 176 177 DebugLoc DL = ADDENode->getDebugLoc(); 178 179 // Initialize accumulator. 180 SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped, 181 ADDCNode->getOperand(1), 182 ADDENode->getOperand(1)); 183 184 // create MipsMAdd(u) node 185 MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MAddu : MipsISD::MAdd; 186 187 SDValue MAdd = CurDAG->getNode(MultOpc, DL, MVT::Untyped, 188 MultNode->getOperand(0),// Factor 0 189 MultNode->getOperand(1),// Factor 1 190 ACCIn); 191 192 // replace uses of adde and addc here 193 if (!SDValue(ADDCNode, 0).use_empty()) { 194 SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32); 195 SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MAdd, 196 LoIdx); 197 CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDCNode, 0), LoOut); 198 } 199 if (!SDValue(ADDENode, 0).use_empty()) { 200 SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32); 201 SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MAdd, 202 HiIdx); 203 CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDENode, 0), HiOut); 204 } 205 206 return true; 207} 208 209// selectMSUB - 210// Transforms a subgraph in CurDAG if the following pattern is found: 211// (addc Lo0, multLo), (sube Hi0, multHi), 212// where, 213// multHi/Lo: product of multiplication 214// Lo0: initial value of Lo register 215// Hi0: initial value of Hi register 216// Return true if pattern matching was successful. 217static bool selectMSUB(SDNode *SUBENode, SelectionDAG *CurDAG) { 218 // SUBENode's second operand must be a flag output of an SUBC node in order 219 // for the matching to be successful. 220 SDNode *SUBCNode = SUBENode->getOperand(2).getNode(); 221 222 if (SUBCNode->getOpcode() != ISD::SUBC) 223 return false; 224 225 SDValue MultHi = SUBENode->getOperand(1); 226 SDValue MultLo = SUBCNode->getOperand(1); 227 SDNode *MultNode = MultHi.getNode(); 228 unsigned MultOpc = MultHi.getOpcode(); 229 230 // MultHi and MultLo must be generated by the same node, 231 if (MultLo.getNode() != MultNode) 232 return false; 233 234 // and it must be a multiplication. 235 if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI) 236 return false; 237 238 // MultLo amd MultHi must be the first and second output of MultNode 239 // respectively. 240 if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0) 241 return false; 242 243 // Transform this to a MSUB only if SUBENode and SUBCNode are the only users 244 // of the values of MultNode, in which case MultNode will be removed in later 245 // phases. 246 // If there exist users other than SUBENode or SUBCNode, this function returns 247 // here, which will result in MultNode being mapped to a single MULT 248 // instruction node rather than a pair of MULT and MSUB instructions being 249 // produced. 250 if (!MultHi.hasOneUse() || !MultLo.hasOneUse()) 251 return false; 252 253 DebugLoc DL = SUBENode->getDebugLoc(); 254 255 // Initialize accumulator. 256 SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped, 257 SUBCNode->getOperand(0), 258 SUBENode->getOperand(0)); 259 260 // create MipsSub(u) node 261 MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MSubu : MipsISD::MSub; 262 263 SDValue MSub = CurDAG->getNode(MultOpc, DL, MVT::Glue, 264 MultNode->getOperand(0),// Factor 0 265 MultNode->getOperand(1),// Factor 1 266 ACCIn); 267 268 // replace uses of sube and subc here 269 if (!SDValue(SUBCNode, 0).use_empty()) { 270 SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32); 271 SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub, 272 LoIdx); 273 CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBCNode, 0), LoOut); 274 } 275 if (!SDValue(SUBENode, 0).use_empty()) { 276 SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32); 277 SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub, 278 HiIdx); 279 CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBENode, 0), HiOut); 280 } 281 282 return true; 283} 284 285static SDValue performADDECombine(SDNode *N, SelectionDAG &DAG, 286 TargetLowering::DAGCombinerInfo &DCI, 287 const MipsSubtarget *Subtarget) { 288 if (DCI.isBeforeLegalize()) 289 return SDValue(); 290 291 if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 && 292 selectMADD(N, &DAG)) 293 return SDValue(N, 0); 294 295 return SDValue(); 296} 297 298static SDValue performSUBECombine(SDNode *N, SelectionDAG &DAG, 299 TargetLowering::DAGCombinerInfo &DCI, 300 const MipsSubtarget *Subtarget) { 301 if (DCI.isBeforeLegalize()) 302 return SDValue(); 303 304 if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 && 305 selectMSUB(N, &DAG)) 306 return SDValue(N, 0); 307 308 return SDValue(); 309} 310 311SDValue 312MipsSETargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const { 313 SelectionDAG &DAG = DCI.DAG; 314 315 switch (N->getOpcode()) { 316 case ISD::ADDE: 317 return performADDECombine(N, DAG, DCI, Subtarget); 318 case ISD::SUBE: 319 return performSUBECombine(N, DAG, DCI, Subtarget); 320 default: 321 return MipsTargetLowering::PerformDAGCombine(N, DCI); 322 } 323} 324 325MachineBasicBlock * 326MipsSETargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, 327 MachineBasicBlock *BB) const { 328 switch (MI->getOpcode()) { 329 default: 330 return MipsTargetLowering::EmitInstrWithCustomInserter(MI, BB); 331 case Mips::BPOSGE32_PSEUDO: 332 return emitBPOSGE32(MI, BB); 333 } 334} 335 336bool MipsSETargetLowering:: 337isEligibleForTailCallOptimization(const MipsCC &MipsCCInfo, 338 unsigned NextStackOffset, 339 const MipsFunctionInfo& FI) const { 340 if (!EnableMipsTailCalls) 341 return false; 342 343 // Return false if either the callee or caller has a byval argument. 344 if (MipsCCInfo.hasByValArg() || FI.hasByvalArg()) 345 return false; 346 347 // Return true if the callee's argument area is no larger than the 348 // caller's. 349 return NextStackOffset <= FI.getIncomingArgSize(); 350} 351 352void MipsSETargetLowering:: 353getOpndList(SmallVectorImpl<SDValue> &Ops, 354 std::deque< std::pair<unsigned, SDValue> > &RegsToPass, 355 bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage, 356 CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const { 357 // T9 should contain the address of the callee function if 358 // -reloction-model=pic or it is an indirect call. 359 if (IsPICCall || !GlobalOrExternal) { 360 unsigned T9Reg = IsN64 ? Mips::T9_64 : Mips::T9; 361 RegsToPass.push_front(std::make_pair(T9Reg, Callee)); 362 } else 363 Ops.push_back(Callee); 364 365 MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal, 366 InternalLinkage, CLI, Callee, Chain); 367} 368 369SDValue MipsSETargetLowering::lowerMulDiv(SDValue Op, unsigned NewOpc, 370 bool HasLo, bool HasHi, 371 SelectionDAG &DAG) const { 372 EVT Ty = Op.getOperand(0).getValueType(); 373 DebugLoc DL = Op.getDebugLoc(); 374 SDValue Mult = DAG.getNode(NewOpc, DL, MVT::Untyped, 375 Op.getOperand(0), Op.getOperand(1)); 376 SDValue Lo, Hi; 377 378 if (HasLo) 379 Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult, 380 DAG.getConstant(Mips::sub_lo, MVT::i32)); 381 if (HasHi) 382 Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult, 383 DAG.getConstant(Mips::sub_hi, MVT::i32)); 384 385 if (!HasLo || !HasHi) 386 return HasLo ? Lo : Hi; 387 388 SDValue Vals[] = { Lo, Hi }; 389 return DAG.getMergeValues(Vals, 2, DL); 390} 391 392MachineBasicBlock * MipsSETargetLowering:: 393emitBPOSGE32(MachineInstr *MI, MachineBasicBlock *BB) const{ 394 // $bb: 395 // bposge32_pseudo $vr0 396 // => 397 // $bb: 398 // bposge32 $tbb 399 // $fbb: 400 // li $vr2, 0 401 // b $sink 402 // $tbb: 403 // li $vr1, 1 404 // $sink: 405 // $vr0 = phi($vr2, $fbb, $vr1, $tbb) 406 407 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); 408 const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); 409 const TargetRegisterClass *RC = &Mips::CPURegsRegClass; 410 DebugLoc DL = MI->getDebugLoc(); 411 const BasicBlock *LLVM_BB = BB->getBasicBlock(); 412 MachineFunction::iterator It = llvm::next(MachineFunction::iterator(BB)); 413 MachineFunction *F = BB->getParent(); 414 MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB); 415 MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB); 416 MachineBasicBlock *Sink = F->CreateMachineBasicBlock(LLVM_BB); 417 F->insert(It, FBB); 418 F->insert(It, TBB); 419 F->insert(It, Sink); 420 421 // Transfer the remainder of BB and its successor edges to Sink. 422 Sink->splice(Sink->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)), 423 BB->end()); 424 Sink->transferSuccessorsAndUpdatePHIs(BB); 425 426 // Add successors. 427 BB->addSuccessor(FBB); 428 BB->addSuccessor(TBB); 429 FBB->addSuccessor(Sink); 430 TBB->addSuccessor(Sink); 431 432 // Insert the real bposge32 instruction to $BB. 433 BuildMI(BB, DL, TII->get(Mips::BPOSGE32)).addMBB(TBB); 434 435 // Fill $FBB. 436 unsigned VR2 = RegInfo.createVirtualRegister(RC); 437 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), VR2) 438 .addReg(Mips::ZERO).addImm(0); 439 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink); 440 441 // Fill $TBB. 442 unsigned VR1 = RegInfo.createVirtualRegister(RC); 443 BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), VR1) 444 .addReg(Mips::ZERO).addImm(1); 445 446 // Insert phi function to $Sink. 447 BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI), 448 MI->getOperand(0).getReg()) 449 .addReg(VR2).addMBB(FBB).addReg(VR1).addMBB(TBB); 450 451 MI->eraseFromParent(); // The pseudo instruction is gone now. 452 return Sink; 453} 454