1 //===-- HexagonISelDAGToDAG.cpp - A dag to dag inst selector for Hexagon --===// 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 Hexagon target. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "Hexagon.h" 15 #include "HexagonISelLowering.h" 16 #include "HexagonTargetMachine.h" 17 #include "llvm/ADT/DenseMap.h" 18 #include "llvm/CodeGen/SelectionDAGISel.h" 19 #include "llvm/IR/Intrinsics.h" 20 #include "llvm/Support/CommandLine.h" 21 #include "llvm/Support/Compiler.h" 22 #include "llvm/Support/Debug.h" 23 using namespace llvm; 24 25 #define DEBUG_TYPE "hexagon-isel" 26 27 static 28 cl::opt<unsigned> 29 MaxNumOfUsesForConstExtenders("ga-max-num-uses-for-constant-extenders", 30 cl::Hidden, cl::init(2), 31 cl::desc("Maximum number of uses of a global address such that we still us a" 32 "constant extended instruction")); 33 34 //===----------------------------------------------------------------------===// 35 // Instruction Selector Implementation 36 //===----------------------------------------------------------------------===// 37 38 namespace llvm { 39 void initializeHexagonDAGToDAGISelPass(PassRegistry&); 40 } 41 42 //===--------------------------------------------------------------------===// 43 /// HexagonDAGToDAGISel - Hexagon specific code to select Hexagon machine 44 /// instructions for SelectionDAG operations. 45 /// 46 namespace { 47 class HexagonDAGToDAGISel : public SelectionDAGISel { 48 /// Subtarget - Keep a pointer to the Hexagon Subtarget around so that we can 49 /// make the right decision when generating code for different targets. 50 const HexagonSubtarget &Subtarget; 51 52 // Keep a reference to HexagonTargetMachine. 53 const HexagonTargetMachine& TM; 54 DenseMap<const GlobalValue *, unsigned> GlobalAddressUseCountMap; 55 public: 56 explicit HexagonDAGToDAGISel(HexagonTargetMachine &targetmachine, 57 CodeGenOpt::Level OptLevel) 58 : SelectionDAGISel(targetmachine, OptLevel), 59 Subtarget(targetmachine.getSubtarget<HexagonSubtarget>()), 60 TM(targetmachine) { 61 initializeHexagonDAGToDAGISelPass(*PassRegistry::getPassRegistry()); 62 } 63 bool hasNumUsesBelowThresGA(SDNode *N) const; 64 65 SDNode *Select(SDNode *N) override; 66 67 // Complex Pattern Selectors. 68 inline bool foldGlobalAddress(SDValue &N, SDValue &R); 69 inline bool foldGlobalAddressGP(SDValue &N, SDValue &R); 70 bool foldGlobalAddressImpl(SDValue &N, SDValue &R, bool ShouldLookForGP); 71 bool SelectADDRri(SDValue& N, SDValue &R1, SDValue &R2); 72 bool SelectADDRriS11_0(SDValue& N, SDValue &R1, SDValue &R2); 73 bool SelectADDRriS11_1(SDValue& N, SDValue &R1, SDValue &R2); 74 bool SelectADDRriS11_2(SDValue& N, SDValue &R1, SDValue &R2); 75 bool SelectMEMriS11_2(SDValue& Addr, SDValue &Base, SDValue &Offset); 76 bool SelectADDRriS11_3(SDValue& N, SDValue &R1, SDValue &R2); 77 bool SelectADDRrr(SDValue &Addr, SDValue &Base, SDValue &Offset); 78 bool SelectADDRriU6_0(SDValue& N, SDValue &R1, SDValue &R2); 79 bool SelectADDRriU6_1(SDValue& N, SDValue &R1, SDValue &R2); 80 bool SelectADDRriU6_2(SDValue& N, SDValue &R1, SDValue &R2); 81 82 const char *getPassName() const override { 83 return "Hexagon DAG->DAG Pattern Instruction Selection"; 84 } 85 86 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for 87 /// inline asm expressions. 88 bool SelectInlineAsmMemoryOperand(const SDValue &Op, 89 char ConstraintCode, 90 std::vector<SDValue> &OutOps) override; 91 bool SelectAddr(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Offset); 92 93 SDNode *SelectLoad(SDNode *N); 94 SDNode *SelectBaseOffsetLoad(LoadSDNode *LD, SDLoc dl); 95 SDNode *SelectIndexedLoad(LoadSDNode *LD, SDLoc dl); 96 SDNode *SelectIndexedLoadZeroExtend64(LoadSDNode *LD, unsigned Opcode, 97 SDLoc dl); 98 SDNode *SelectIndexedLoadSignExtend64(LoadSDNode *LD, unsigned Opcode, 99 SDLoc dl); 100 SDNode *SelectBaseOffsetStore(StoreSDNode *ST, SDLoc dl); 101 SDNode *SelectIndexedStore(StoreSDNode *ST, SDLoc dl); 102 SDNode *SelectStore(SDNode *N); 103 SDNode *SelectSHL(SDNode *N); 104 SDNode *SelectSelect(SDNode *N); 105 SDNode *SelectTruncate(SDNode *N); 106 SDNode *SelectMul(SDNode *N); 107 SDNode *SelectZeroExtend(SDNode *N); 108 SDNode *SelectIntrinsicWOChain(SDNode *N); 109 SDNode *SelectIntrinsicWChain(SDNode *N); 110 SDNode *SelectConstant(SDNode *N); 111 SDNode *SelectConstantFP(SDNode *N); 112 SDNode *SelectAdd(SDNode *N); 113 bool isConstExtProfitable(SDNode *N) const; 114 115 // XformMskToBitPosU5Imm - Returns the bit position which 116 // the single bit 32 bit mask represents. 117 // Used in Clr and Set bit immediate memops. 118 SDValue XformMskToBitPosU5Imm(uint32_t Imm) { 119 int32_t bitPos; 120 bitPos = Log2_32(Imm); 121 assert(bitPos >= 0 && bitPos < 32 && 122 "Constant out of range for 32 BitPos Memops"); 123 return CurDAG->getTargetConstant(bitPos, MVT::i32); 124 } 125 126 // XformMskToBitPosU4Imm - Returns the bit position which the single bit 16 bit 127 // mask represents. Used in Clr and Set bit immediate memops. 128 SDValue XformMskToBitPosU4Imm(uint16_t Imm) { 129 return XformMskToBitPosU5Imm(Imm); 130 } 131 132 // XformMskToBitPosU3Imm - Returns the bit position which the single bit 8 bit 133 // mask represents. Used in Clr and Set bit immediate memops. 134 SDValue XformMskToBitPosU3Imm(uint8_t Imm) { 135 return XformMskToBitPosU5Imm(Imm); 136 } 137 138 // Return true if there is exactly one bit set in V, i.e., if V is one of the 139 // following integers: 2^0, 2^1, ..., 2^31. 140 bool ImmIsSingleBit(uint32_t v) const { 141 uint32_t c = CountPopulation_64(v); 142 // Only return true if we counted 1 bit. 143 return c == 1; 144 } 145 146 // XformM5ToU5Imm - Return a target constant with the specified value, of type 147 // i32 where the negative literal is transformed into a positive literal for 148 // use in -= memops. 149 inline SDValue XformM5ToU5Imm(signed Imm) { 150 assert( (Imm >= -31 && Imm <= -1) && "Constant out of range for Memops"); 151 return CurDAG->getTargetConstant( - Imm, MVT::i32); 152 } 153 154 155 // XformU7ToU7M1Imm - Return a target constant decremented by 1, in range 156 // [1..128], used in cmpb.gtu instructions. 157 inline SDValue XformU7ToU7M1Imm(signed Imm) { 158 assert((Imm >= 1 && Imm <= 128) && "Constant out of range for cmpb op"); 159 return CurDAG->getTargetConstant(Imm - 1, MVT::i8); 160 } 161 162 // XformS8ToS8M1Imm - Return a target constant decremented by 1. 163 inline SDValue XformSToSM1Imm(signed Imm) { 164 return CurDAG->getTargetConstant(Imm - 1, MVT::i32); 165 } 166 167 // XformU8ToU8M1Imm - Return a target constant decremented by 1. 168 inline SDValue XformUToUM1Imm(unsigned Imm) { 169 assert((Imm >= 1) && "Cannot decrement unsigned int less than 1"); 170 return CurDAG->getTargetConstant(Imm - 1, MVT::i32); 171 } 172 173 // Include the pieces autogenerated from the target description. 174 #include "HexagonGenDAGISel.inc" 175 }; 176 } // end anonymous namespace 177 178 179 /// createHexagonISelDag - This pass converts a legalized DAG into a 180 /// Hexagon-specific DAG, ready for instruction scheduling. 181 /// 182 FunctionPass *llvm::createHexagonISelDag(HexagonTargetMachine &TM, 183 CodeGenOpt::Level OptLevel) { 184 return new HexagonDAGToDAGISel(TM, OptLevel); 185 } 186 187 static void initializePassOnce(PassRegistry &Registry) { 188 const char *Name = "Hexagon DAG->DAG Pattern Instruction Selection"; 189 PassInfo *PI = new PassInfo(Name, "hexagon-isel", 190 &SelectionDAGISel::ID, nullptr, false, false); 191 Registry.registerPass(*PI, true); 192 } 193 194 void llvm::initializeHexagonDAGToDAGISelPass(PassRegistry &Registry) { 195 CALL_ONCE_INITIALIZATION(initializePassOnce) 196 } 197 198 199 static bool IsS11_0_Offset(SDNode * S) { 200 ConstantSDNode *N = cast<ConstantSDNode>(S); 201 202 // immS16 predicate - True if the immediate fits in a 16-bit sign extended 203 // field. 204 int64_t v = (int64_t)N->getSExtValue(); 205 return isInt<11>(v); 206 } 207 208 209 static bool IsS11_1_Offset(SDNode * S) { 210 ConstantSDNode *N = cast<ConstantSDNode>(S); 211 212 // immS16 predicate - True if the immediate fits in a 16-bit sign extended 213 // field. 214 int64_t v = (int64_t)N->getSExtValue(); 215 return isShiftedInt<11,1>(v); 216 } 217 218 219 static bool IsS11_2_Offset(SDNode * S) { 220 ConstantSDNode *N = cast<ConstantSDNode>(S); 221 222 // immS16 predicate - True if the immediate fits in a 16-bit sign extended 223 // field. 224 int64_t v = (int64_t)N->getSExtValue(); 225 return isShiftedInt<11,2>(v); 226 } 227 228 229 static bool IsS11_3_Offset(SDNode * S) { 230 ConstantSDNode *N = cast<ConstantSDNode>(S); 231 232 // immS16 predicate - True if the immediate fits in a 16-bit sign extended 233 // field. 234 int64_t v = (int64_t)N->getSExtValue(); 235 return isShiftedInt<11,3>(v); 236 } 237 238 239 static bool IsU6_0_Offset(SDNode * S) { 240 ConstantSDNode *N = cast<ConstantSDNode>(S); 241 242 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended 243 // field. 244 int64_t v = (int64_t)N->getSExtValue(); 245 return isUInt<6>(v); 246 } 247 248 249 static bool IsU6_1_Offset(SDNode * S) { 250 ConstantSDNode *N = cast<ConstantSDNode>(S); 251 252 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended 253 // field. 254 int64_t v = (int64_t)N->getSExtValue(); 255 return isShiftedUInt<6,1>(v); 256 } 257 258 259 static bool IsU6_2_Offset(SDNode * S) { 260 ConstantSDNode *N = cast<ConstantSDNode>(S); 261 262 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended 263 // field. 264 int64_t v = (int64_t)N->getSExtValue(); 265 return isShiftedUInt<6,2>(v); 266 } 267 268 269 // Intrinsics that return a a predicate. 270 static unsigned doesIntrinsicReturnPredicate(unsigned ID) 271 { 272 switch (ID) { 273 default: 274 return 0; 275 case Intrinsic::hexagon_C2_cmpeq: 276 case Intrinsic::hexagon_C2_cmpgt: 277 case Intrinsic::hexagon_C2_cmpgtu: 278 case Intrinsic::hexagon_C2_cmpgtup: 279 case Intrinsic::hexagon_C2_cmpgtp: 280 case Intrinsic::hexagon_C2_cmpeqp: 281 case Intrinsic::hexagon_C2_bitsset: 282 case Intrinsic::hexagon_C2_bitsclr: 283 case Intrinsic::hexagon_C2_cmpeqi: 284 case Intrinsic::hexagon_C2_cmpgti: 285 case Intrinsic::hexagon_C2_cmpgtui: 286 case Intrinsic::hexagon_C2_cmpgei: 287 case Intrinsic::hexagon_C2_cmpgeui: 288 case Intrinsic::hexagon_C2_cmplt: 289 case Intrinsic::hexagon_C2_cmpltu: 290 case Intrinsic::hexagon_C2_bitsclri: 291 case Intrinsic::hexagon_C2_and: 292 case Intrinsic::hexagon_C2_or: 293 case Intrinsic::hexagon_C2_xor: 294 case Intrinsic::hexagon_C2_andn: 295 case Intrinsic::hexagon_C2_not: 296 case Intrinsic::hexagon_C2_orn: 297 case Intrinsic::hexagon_C2_pxfer_map: 298 case Intrinsic::hexagon_C2_any8: 299 case Intrinsic::hexagon_C2_all8: 300 case Intrinsic::hexagon_A2_vcmpbeq: 301 case Intrinsic::hexagon_A2_vcmpbgtu: 302 case Intrinsic::hexagon_A2_vcmpheq: 303 case Intrinsic::hexagon_A2_vcmphgt: 304 case Intrinsic::hexagon_A2_vcmphgtu: 305 case Intrinsic::hexagon_A2_vcmpweq: 306 case Intrinsic::hexagon_A2_vcmpwgt: 307 case Intrinsic::hexagon_A2_vcmpwgtu: 308 case Intrinsic::hexagon_C2_tfrrp: 309 case Intrinsic::hexagon_S2_tstbit_i: 310 case Intrinsic::hexagon_S2_tstbit_r: 311 return 1; 312 } 313 } 314 315 316 // Intrinsics that have predicate operands. 317 static unsigned doesIntrinsicContainPredicate(unsigned ID) 318 { 319 switch (ID) { 320 default: 321 return 0; 322 case Intrinsic::hexagon_C2_tfrpr: 323 return Hexagon::TFR_RsPd; 324 case Intrinsic::hexagon_C2_and: 325 return Hexagon::AND_pp; 326 case Intrinsic::hexagon_C2_xor: 327 return Hexagon::XOR_pp; 328 case Intrinsic::hexagon_C2_or: 329 return Hexagon::OR_pp; 330 case Intrinsic::hexagon_C2_not: 331 return Hexagon::NOT_p; 332 case Intrinsic::hexagon_C2_any8: 333 return Hexagon::ANY_pp; 334 case Intrinsic::hexagon_C2_all8: 335 return Hexagon::ALL_pp; 336 case Intrinsic::hexagon_C2_vitpack: 337 return Hexagon::VITPACK_pp; 338 case Intrinsic::hexagon_C2_mask: 339 return Hexagon::MASK_p; 340 case Intrinsic::hexagon_C2_mux: 341 return Hexagon::MUX_rr; 342 343 // Mapping hexagon_C2_muxir to MUX_pri. This is pretty weird - but 344 // that's how it's mapped in q6protos.h. 345 case Intrinsic::hexagon_C2_muxir: 346 return Hexagon::MUX_ri; 347 348 // Mapping hexagon_C2_muxri to MUX_pir. This is pretty weird - but 349 // that's how it's mapped in q6protos.h. 350 case Intrinsic::hexagon_C2_muxri: 351 return Hexagon::MUX_ir; 352 353 case Intrinsic::hexagon_C2_muxii: 354 return Hexagon::MUX_ii; 355 case Intrinsic::hexagon_C2_vmux: 356 return Hexagon::VMUX_prr64; 357 case Intrinsic::hexagon_S2_valignrb: 358 return Hexagon::VALIGN_rrp; 359 case Intrinsic::hexagon_S2_vsplicerb: 360 return Hexagon::VSPLICE_rrp; 361 } 362 } 363 364 365 static bool OffsetFitsS11(EVT MemType, int64_t Offset) { 366 if (MemType == MVT::i64 && isShiftedInt<11,3>(Offset)) { 367 return true; 368 } 369 if (MemType == MVT::i32 && isShiftedInt<11,2>(Offset)) { 370 return true; 371 } 372 if (MemType == MVT::i16 && isShiftedInt<11,1>(Offset)) { 373 return true; 374 } 375 if (MemType == MVT::i8 && isInt<11>(Offset)) { 376 return true; 377 } 378 return false; 379 } 380 381 382 // 383 // Try to lower loads of GlobalAdresses into base+offset loads. Custom 384 // lowering for GlobalAddress nodes has already turned it into a 385 // CONST32. 386 // 387 SDNode *HexagonDAGToDAGISel::SelectBaseOffsetLoad(LoadSDNode *LD, SDLoc dl) { 388 SDValue Chain = LD->getChain(); 389 SDNode* Const32 = LD->getBasePtr().getNode(); 390 unsigned Opcode = 0; 391 392 if (Const32->getOpcode() == HexagonISD::CONST32 && 393 ISD::isNormalLoad(LD)) { 394 SDValue Base = Const32->getOperand(0); 395 EVT LoadedVT = LD->getMemoryVT(); 396 int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset(); 397 if (Offset != 0 && OffsetFitsS11(LoadedVT, Offset)) { 398 MVT PointerTy = getTargetLowering()->getPointerTy(); 399 const GlobalValue* GV = 400 cast<GlobalAddressSDNode>(Base)->getGlobal(); 401 SDValue TargAddr = 402 CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0); 403 SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set, 404 dl, PointerTy, 405 TargAddr); 406 // Figure out base + offset opcode 407 if (LoadedVT == MVT::i64) Opcode = Hexagon::LDrid_indexed; 408 else if (LoadedVT == MVT::i32) Opcode = Hexagon::LDriw_indexed; 409 else if (LoadedVT == MVT::i16) Opcode = Hexagon::LDrih_indexed; 410 else if (LoadedVT == MVT::i8) Opcode = Hexagon::LDrib_indexed; 411 else llvm_unreachable("unknown memory type"); 412 413 // Build indexed load. 414 SDValue TargetConstOff = CurDAG->getTargetConstant(Offset, PointerTy); 415 SDNode* Result = CurDAG->getMachineNode(Opcode, dl, 416 LD->getValueType(0), 417 MVT::Other, 418 SDValue(NewBase,0), 419 TargetConstOff, 420 Chain); 421 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 422 MemOp[0] = LD->getMemOperand(); 423 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1); 424 ReplaceUses(LD, Result); 425 return Result; 426 } 427 } 428 429 return SelectCode(LD); 430 } 431 432 433 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD, 434 unsigned Opcode, 435 SDLoc dl) 436 { 437 SDValue Chain = LD->getChain(); 438 EVT LoadedVT = LD->getMemoryVT(); 439 SDValue Base = LD->getBasePtr(); 440 SDValue Offset = LD->getOffset(); 441 SDNode *OffsetNode = Offset.getNode(); 442 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue(); 443 SDValue N1 = LD->getOperand(1); 444 SDValue CPTmpN1_0; 445 SDValue CPTmpN1_1; 446 447 if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) && 448 N1.getNode()->getValueType(0) == MVT::i32) { 449 const HexagonInstrInfo *TII = 450 static_cast<const HexagonInstrInfo*>(TM.getInstrInfo()); 451 if (TII->isValidAutoIncImm(LoadedVT, Val)) { 452 SDValue TargetConst = CurDAG->getTargetConstant(Val, MVT::i32); 453 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::i32, 454 MVT::Other, Base, TargetConst, 455 Chain); 456 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl, MVT::i64, 457 SDValue(Result_1, 0)); 458 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 459 MemOp[0] = LD->getMemOperand(); 460 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1); 461 const SDValue Froms[] = { SDValue(LD, 0), 462 SDValue(LD, 1), 463 SDValue(LD, 2) 464 }; 465 const SDValue Tos[] = { SDValue(Result_2, 0), 466 SDValue(Result_1, 1), 467 SDValue(Result_1, 2) 468 }; 469 ReplaceUses(Froms, Tos, 3); 470 return Result_2; 471 } 472 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32); 473 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32); 474 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, 475 MVT::Other, Base, TargetConst0, 476 Chain); 477 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl, 478 MVT::i64, SDValue(Result_1, 0)); 479 SDNode* Result_3 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, 480 MVT::i32, Base, TargetConstVal, 481 SDValue(Result_1, 1)); 482 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 483 MemOp[0] = LD->getMemOperand(); 484 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1); 485 const SDValue Froms[] = { SDValue(LD, 0), 486 SDValue(LD, 1), 487 SDValue(LD, 2) 488 }; 489 const SDValue Tos[] = { SDValue(Result_2, 0), 490 SDValue(Result_3, 0), 491 SDValue(Result_1, 1) 492 }; 493 ReplaceUses(Froms, Tos, 3); 494 return Result_2; 495 } 496 return SelectCode(LD); 497 } 498 499 500 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD, 501 unsigned Opcode, 502 SDLoc dl) 503 { 504 SDValue Chain = LD->getChain(); 505 EVT LoadedVT = LD->getMemoryVT(); 506 SDValue Base = LD->getBasePtr(); 507 SDValue Offset = LD->getOffset(); 508 SDNode *OffsetNode = Offset.getNode(); 509 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue(); 510 SDValue N1 = LD->getOperand(1); 511 SDValue CPTmpN1_0; 512 SDValue CPTmpN1_1; 513 514 if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) && 515 N1.getNode()->getValueType(0) == MVT::i32) { 516 const HexagonInstrInfo *TII = 517 static_cast<const HexagonInstrInfo*>(TM.getInstrInfo()); 518 if (TII->isValidAutoIncImm(LoadedVT, Val)) { 519 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32); 520 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32); 521 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, 522 MVT::i32, MVT::Other, Base, 523 TargetConstVal, Chain); 524 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32, 525 TargetConst0); 526 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl, 527 MVT::i64, MVT::Other, 528 SDValue(Result_2,0), 529 SDValue(Result_1,0)); 530 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 531 MemOp[0] = LD->getMemOperand(); 532 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1); 533 const SDValue Froms[] = { SDValue(LD, 0), 534 SDValue(LD, 1), 535 SDValue(LD, 2) 536 }; 537 const SDValue Tos[] = { SDValue(Result_3, 0), 538 SDValue(Result_1, 1), 539 SDValue(Result_1, 2) 540 }; 541 ReplaceUses(Froms, Tos, 3); 542 return Result_3; 543 } 544 545 // Generate an indirect load. 546 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32); 547 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32); 548 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, 549 MVT::Other, 550 Base, TargetConst0, Chain); 551 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32, 552 TargetConst0); 553 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl, 554 MVT::i64, MVT::Other, 555 SDValue(Result_2,0), 556 SDValue(Result_1,0)); 557 // Add offset to base. 558 SDNode* Result_4 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32, 559 Base, TargetConstVal, 560 SDValue(Result_1, 1)); 561 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 562 MemOp[0] = LD->getMemOperand(); 563 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1); 564 const SDValue Froms[] = { SDValue(LD, 0), 565 SDValue(LD, 1), 566 SDValue(LD, 2) 567 }; 568 const SDValue Tos[] = { SDValue(Result_3, 0), // Load value. 569 SDValue(Result_4, 0), // New address. 570 SDValue(Result_1, 1) 571 }; 572 ReplaceUses(Froms, Tos, 3); 573 return Result_3; 574 } 575 576 return SelectCode(LD); 577 } 578 579 580 SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, SDLoc dl) { 581 SDValue Chain = LD->getChain(); 582 SDValue Base = LD->getBasePtr(); 583 SDValue Offset = LD->getOffset(); 584 SDNode *OffsetNode = Offset.getNode(); 585 // Get the constant value. 586 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue(); 587 EVT LoadedVT = LD->getMemoryVT(); 588 unsigned Opcode = 0; 589 590 // Check for zero ext loads. 591 bool zextval = (LD->getExtensionType() == ISD::ZEXTLOAD); 592 593 // Figure out the opcode. 594 const HexagonInstrInfo *TII = 595 static_cast<const HexagonInstrInfo*>(TM.getInstrInfo()); 596 if (LoadedVT == MVT::i64) { 597 if (TII->isValidAutoIncImm(LoadedVT, Val)) 598 Opcode = Hexagon::POST_LDrid; 599 else 600 Opcode = Hexagon::LDrid; 601 } else if (LoadedVT == MVT::i32) { 602 if (TII->isValidAutoIncImm(LoadedVT, Val)) 603 Opcode = Hexagon::POST_LDriw; 604 else 605 Opcode = Hexagon::LDriw; 606 } else if (LoadedVT == MVT::i16) { 607 if (TII->isValidAutoIncImm(LoadedVT, Val)) 608 Opcode = zextval ? Hexagon::POST_LDriuh : Hexagon::POST_LDrih; 609 else 610 Opcode = zextval ? Hexagon::LDriuh : Hexagon::LDrih; 611 } else if (LoadedVT == MVT::i8) { 612 if (TII->isValidAutoIncImm(LoadedVT, Val)) 613 Opcode = zextval ? Hexagon::POST_LDriub : Hexagon::POST_LDrib; 614 else 615 Opcode = zextval ? Hexagon::LDriub : Hexagon::LDrib; 616 } else 617 llvm_unreachable("unknown memory type"); 618 619 // For zero ext i64 loads, we need to add combine instructions. 620 if (LD->getValueType(0) == MVT::i64 && 621 LD->getExtensionType() == ISD::ZEXTLOAD) { 622 return SelectIndexedLoadZeroExtend64(LD, Opcode, dl); 623 } 624 if (LD->getValueType(0) == MVT::i64 && 625 LD->getExtensionType() == ISD::SEXTLOAD) { 626 // Handle sign ext i64 loads. 627 return SelectIndexedLoadSignExtend64(LD, Opcode, dl); 628 } 629 if (TII->isValidAutoIncImm(LoadedVT, Val)) { 630 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32); 631 SDNode* Result = CurDAG->getMachineNode(Opcode, dl, 632 LD->getValueType(0), 633 MVT::i32, MVT::Other, Base, 634 TargetConstVal, Chain); 635 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 636 MemOp[0] = LD->getMemOperand(); 637 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1); 638 const SDValue Froms[] = { SDValue(LD, 0), 639 SDValue(LD, 1), 640 SDValue(LD, 2) 641 }; 642 const SDValue Tos[] = { SDValue(Result, 0), 643 SDValue(Result, 1), 644 SDValue(Result, 2) 645 }; 646 ReplaceUses(Froms, Tos, 3); 647 return Result; 648 } else { 649 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32); 650 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32); 651 SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl, 652 LD->getValueType(0), 653 MVT::Other, Base, TargetConst0, 654 Chain); 655 SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32, 656 Base, TargetConstVal, 657 SDValue(Result_1, 1)); 658 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 659 MemOp[0] = LD->getMemOperand(); 660 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1); 661 const SDValue Froms[] = { SDValue(LD, 0), 662 SDValue(LD, 1), 663 SDValue(LD, 2) 664 }; 665 const SDValue Tos[] = { SDValue(Result_1, 0), 666 SDValue(Result_2, 0), 667 SDValue(Result_1, 1) 668 }; 669 ReplaceUses(Froms, Tos, 3); 670 return Result_1; 671 } 672 } 673 674 675 SDNode *HexagonDAGToDAGISel::SelectLoad(SDNode *N) { 676 SDNode *result; 677 SDLoc dl(N); 678 LoadSDNode *LD = cast<LoadSDNode>(N); 679 ISD::MemIndexedMode AM = LD->getAddressingMode(); 680 681 // Handle indexed loads. 682 if (AM != ISD::UNINDEXED) { 683 result = SelectIndexedLoad(LD, dl); 684 } else { 685 result = SelectBaseOffsetLoad(LD, dl); 686 } 687 688 return result; 689 } 690 691 692 SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, SDLoc dl) { 693 SDValue Chain = ST->getChain(); 694 SDValue Base = ST->getBasePtr(); 695 SDValue Offset = ST->getOffset(); 696 SDValue Value = ST->getValue(); 697 SDNode *OffsetNode = Offset.getNode(); 698 // Get the constant value. 699 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue(); 700 EVT StoredVT = ST->getMemoryVT(); 701 702 // Offset value must be within representable range 703 // and must have correct alignment properties. 704 const HexagonInstrInfo *TII = 705 static_cast<const HexagonInstrInfo*>(TM.getInstrInfo()); 706 if (TII->isValidAutoIncImm(StoredVT, Val)) { 707 SDValue Ops[] = {Base, CurDAG->getTargetConstant(Val, MVT::i32), Value, 708 Chain}; 709 unsigned Opcode = 0; 710 711 // Figure out the post inc version of opcode. 712 if (StoredVT == MVT::i64) Opcode = Hexagon::POST_STdri; 713 else if (StoredVT == MVT::i32) Opcode = Hexagon::POST_STwri; 714 else if (StoredVT == MVT::i16) Opcode = Hexagon::POST_SThri; 715 else if (StoredVT == MVT::i8) Opcode = Hexagon::POST_STbri; 716 else llvm_unreachable("unknown memory type"); 717 718 // Build post increment store. 719 SDNode* Result = CurDAG->getMachineNode(Opcode, dl, MVT::i32, 720 MVT::Other, Ops); 721 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 722 MemOp[0] = ST->getMemOperand(); 723 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1); 724 725 ReplaceUses(ST, Result); 726 ReplaceUses(SDValue(ST,1), SDValue(Result,1)); 727 return Result; 728 } 729 730 // Note: Order of operands matches the def of instruction: 731 // def STrid : STInst<(outs), (ins MEMri:$addr, DoubleRegs:$src1), ... 732 // and it differs for POST_ST* for instance. 733 SDValue Ops[] = { Base, CurDAG->getTargetConstant(0, MVT::i32), Value, 734 Chain}; 735 unsigned Opcode = 0; 736 737 // Figure out the opcode. 738 if (StoredVT == MVT::i64) Opcode = Hexagon::STrid; 739 else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw_indexed; 740 else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih; 741 else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib; 742 else llvm_unreachable("unknown memory type"); 743 744 // Build regular store. 745 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32); 746 SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops); 747 // Build splitted incriment instruction. 748 SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32, 749 Base, 750 TargetConstVal, 751 SDValue(Result_1, 0)); 752 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 753 MemOp[0] = ST->getMemOperand(); 754 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1); 755 756 ReplaceUses(SDValue(ST,0), SDValue(Result_2,0)); 757 ReplaceUses(SDValue(ST,1), SDValue(Result_1,0)); 758 return Result_2; 759 } 760 761 762 SDNode *HexagonDAGToDAGISel::SelectBaseOffsetStore(StoreSDNode *ST, 763 SDLoc dl) { 764 SDValue Chain = ST->getChain(); 765 SDNode* Const32 = ST->getBasePtr().getNode(); 766 SDValue Value = ST->getValue(); 767 unsigned Opcode = 0; 768 769 // Try to lower stores of GlobalAdresses into indexed stores. Custom 770 // lowering for GlobalAddress nodes has already turned it into a 771 // CONST32. Avoid truncating stores for the moment. Post-inc stores 772 // do the same. Don't think there's a reason for it, so will file a 773 // bug to fix. 774 if ((Const32->getOpcode() == HexagonISD::CONST32) && 775 !(Value.getValueType() == MVT::i64 && ST->isTruncatingStore())) { 776 SDValue Base = Const32->getOperand(0); 777 if (Base.getOpcode() == ISD::TargetGlobalAddress) { 778 EVT StoredVT = ST->getMemoryVT(); 779 int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset(); 780 if (Offset != 0 && OffsetFitsS11(StoredVT, Offset)) { 781 MVT PointerTy = getTargetLowering()->getPointerTy(); 782 const GlobalValue* GV = 783 cast<GlobalAddressSDNode>(Base)->getGlobal(); 784 SDValue TargAddr = 785 CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0); 786 SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set, 787 dl, PointerTy, 788 TargAddr); 789 790 // Figure out base + offset opcode 791 if (StoredVT == MVT::i64) Opcode = Hexagon::STrid_indexed; 792 else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw_indexed; 793 else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih_indexed; 794 else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib_indexed; 795 else llvm_unreachable("unknown memory type"); 796 797 SDValue Ops[] = {SDValue(NewBase,0), 798 CurDAG->getTargetConstant(Offset,PointerTy), 799 Value, Chain}; 800 // build indexed store 801 SDNode* Result = CurDAG->getMachineNode(Opcode, dl, 802 MVT::Other, Ops); 803 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); 804 MemOp[0] = ST->getMemOperand(); 805 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1); 806 ReplaceUses(ST, Result); 807 return Result; 808 } 809 } 810 } 811 812 return SelectCode(ST); 813 } 814 815 816 SDNode *HexagonDAGToDAGISel::SelectStore(SDNode *N) { 817 SDLoc dl(N); 818 StoreSDNode *ST = cast<StoreSDNode>(N); 819 ISD::MemIndexedMode AM = ST->getAddressingMode(); 820 821 // Handle indexed stores. 822 if (AM != ISD::UNINDEXED) { 823 return SelectIndexedStore(ST, dl); 824 } 825 826 return SelectBaseOffsetStore(ST, dl); 827 } 828 829 SDNode *HexagonDAGToDAGISel::SelectMul(SDNode *N) { 830 SDLoc dl(N); 831 832 // 833 // %conv.i = sext i32 %tmp1 to i64 834 // %conv2.i = sext i32 %add to i64 835 // %mul.i = mul nsw i64 %conv2.i, %conv.i 836 // 837 // --- match with the following --- 838 // 839 // %mul.i = mpy (%tmp1, %add) 840 // 841 842 if (N->getValueType(0) == MVT::i64) { 843 // Shifting a i64 signed multiply. 844 SDValue MulOp0 = N->getOperand(0); 845 SDValue MulOp1 = N->getOperand(1); 846 847 SDValue OP0; 848 SDValue OP1; 849 850 // Handle sign_extend and sextload. 851 if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) { 852 SDValue Sext0 = MulOp0.getOperand(0); 853 if (Sext0.getNode()->getValueType(0) != MVT::i32) { 854 return SelectCode(N); 855 } 856 857 OP0 = Sext0; 858 } else if (MulOp0.getOpcode() == ISD::LOAD) { 859 LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode()); 860 if (LD->getMemoryVT() != MVT::i32 || 861 LD->getExtensionType() != ISD::SEXTLOAD || 862 LD->getAddressingMode() != ISD::UNINDEXED) { 863 return SelectCode(N); 864 } 865 866 SDValue Chain = LD->getChain(); 867 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32); 868 OP0 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32, 869 MVT::Other, 870 LD->getBasePtr(), TargetConst0, 871 Chain), 0); 872 } else { 873 return SelectCode(N); 874 } 875 876 // Same goes for the second operand. 877 if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) { 878 SDValue Sext1 = MulOp1.getOperand(0); 879 if (Sext1.getNode()->getValueType(0) != MVT::i32) { 880 return SelectCode(N); 881 } 882 883 OP1 = Sext1; 884 } else if (MulOp1.getOpcode() == ISD::LOAD) { 885 LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode()); 886 if (LD->getMemoryVT() != MVT::i32 || 887 LD->getExtensionType() != ISD::SEXTLOAD || 888 LD->getAddressingMode() != ISD::UNINDEXED) { 889 return SelectCode(N); 890 } 891 892 SDValue Chain = LD->getChain(); 893 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32); 894 OP1 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32, 895 MVT::Other, 896 LD->getBasePtr(), TargetConst0, 897 Chain), 0); 898 } else { 899 return SelectCode(N); 900 } 901 902 // Generate a mpy instruction. 903 SDNode *Result = CurDAG->getMachineNode(Hexagon::MPY64, dl, MVT::i64, 904 OP0, OP1); 905 ReplaceUses(N, Result); 906 return Result; 907 } 908 909 return SelectCode(N); 910 } 911 912 913 SDNode *HexagonDAGToDAGISel::SelectSelect(SDNode *N) { 914 SDLoc dl(N); 915 SDValue N0 = N->getOperand(0); 916 if (N0.getOpcode() == ISD::SETCC) { 917 SDValue N00 = N0.getOperand(0); 918 if (N00.getOpcode() == ISD::SIGN_EXTEND_INREG) { 919 SDValue N000 = N00.getOperand(0); 920 SDValue N001 = N00.getOperand(1); 921 if (cast<VTSDNode>(N001)->getVT() == MVT::i16) { 922 SDValue N01 = N0.getOperand(1); 923 SDValue N02 = N0.getOperand(2); 924 925 // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2, 926 // i16:Other),IntRegs:i32:$src1, SETLT:Other),IntRegs:i32:$src1, 927 // IntRegs:i32:$src2) 928 // Emits: (MAXh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2) 929 // Pattern complexity = 9 cost = 1 size = 0. 930 if (cast<CondCodeSDNode>(N02)->get() == ISD::SETLT) { 931 SDValue N1 = N->getOperand(1); 932 if (N01 == N1) { 933 SDValue N2 = N->getOperand(2); 934 if (N000 == N2 && 935 N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 && 936 N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) { 937 SDNode *SextNode = CurDAG->getMachineNode(Hexagon::SXTH, dl, 938 MVT::i32, N000); 939 SDNode *Result = CurDAG->getMachineNode(Hexagon::MAXw_rr, dl, 940 MVT::i32, 941 SDValue(SextNode, 0), 942 N1); 943 ReplaceUses(N, Result); 944 return Result; 945 } 946 } 947 } 948 949 // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2, 950 // i16:Other), IntRegs:i32:$src1, SETGT:Other), IntRegs:i32:$src1, 951 // IntRegs:i32:$src2) 952 // Emits: (MINh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2) 953 // Pattern complexity = 9 cost = 1 size = 0. 954 if (cast<CondCodeSDNode>(N02)->get() == ISD::SETGT) { 955 SDValue N1 = N->getOperand(1); 956 if (N01 == N1) { 957 SDValue N2 = N->getOperand(2); 958 if (N000 == N2 && 959 N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 && 960 N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) { 961 SDNode *SextNode = CurDAG->getMachineNode(Hexagon::SXTH, dl, 962 MVT::i32, N000); 963 SDNode *Result = CurDAG->getMachineNode(Hexagon::MINw_rr, dl, 964 MVT::i32, 965 SDValue(SextNode, 0), 966 N1); 967 ReplaceUses(N, Result); 968 return Result; 969 } 970 } 971 } 972 } 973 } 974 } 975 976 return SelectCode(N); 977 } 978 979 980 SDNode *HexagonDAGToDAGISel::SelectTruncate(SDNode *N) { 981 SDLoc dl(N); 982 SDValue Shift = N->getOperand(0); 983 984 // 985 // %conv.i = sext i32 %tmp1 to i64 986 // %conv2.i = sext i32 %add to i64 987 // %mul.i = mul nsw i64 %conv2.i, %conv.i 988 // %shr5.i = lshr i64 %mul.i, 32 989 // %conv3.i = trunc i64 %shr5.i to i32 990 // 991 // --- match with the following --- 992 // 993 // %conv3.i = mpy (%tmp1, %add) 994 // 995 // Trunc to i32. 996 if (N->getValueType(0) == MVT::i32) { 997 // Trunc from i64. 998 if (Shift.getNode()->getValueType(0) == MVT::i64) { 999 // Trunc child is logical shift right. 1000 if (Shift.getOpcode() != ISD::SRL) { 1001 return SelectCode(N); 1002 } 1003 1004 SDValue ShiftOp0 = Shift.getOperand(0); 1005 SDValue ShiftOp1 = Shift.getOperand(1); 1006 1007 // Shift by const 32 1008 if (ShiftOp1.getOpcode() != ISD::Constant) { 1009 return SelectCode(N); 1010 } 1011 1012 int32_t ShiftConst = 1013 cast<ConstantSDNode>(ShiftOp1.getNode())->getSExtValue(); 1014 if (ShiftConst != 32) { 1015 return SelectCode(N); 1016 } 1017 1018 // Shifting a i64 signed multiply 1019 SDValue Mul = ShiftOp0; 1020 if (Mul.getOpcode() != ISD::MUL) { 1021 return SelectCode(N); 1022 } 1023 1024 SDValue MulOp0 = Mul.getOperand(0); 1025 SDValue MulOp1 = Mul.getOperand(1); 1026 1027 SDValue OP0; 1028 SDValue OP1; 1029 1030 // Handle sign_extend and sextload 1031 if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) { 1032 SDValue Sext0 = MulOp0.getOperand(0); 1033 if (Sext0.getNode()->getValueType(0) != MVT::i32) { 1034 return SelectCode(N); 1035 } 1036 1037 OP0 = Sext0; 1038 } else if (MulOp0.getOpcode() == ISD::LOAD) { 1039 LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode()); 1040 if (LD->getMemoryVT() != MVT::i32 || 1041 LD->getExtensionType() != ISD::SEXTLOAD || 1042 LD->getAddressingMode() != ISD::UNINDEXED) { 1043 return SelectCode(N); 1044 } 1045 1046 SDValue Chain = LD->getChain(); 1047 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32); 1048 OP0 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32, 1049 MVT::Other, 1050 LD->getBasePtr(), 1051 TargetConst0, Chain), 0); 1052 } else { 1053 return SelectCode(N); 1054 } 1055 1056 // Same goes for the second operand. 1057 if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) { 1058 SDValue Sext1 = MulOp1.getOperand(0); 1059 if (Sext1.getNode()->getValueType(0) != MVT::i32) 1060 return SelectCode(N); 1061 1062 OP1 = Sext1; 1063 } else if (MulOp1.getOpcode() == ISD::LOAD) { 1064 LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode()); 1065 if (LD->getMemoryVT() != MVT::i32 || 1066 LD->getExtensionType() != ISD::SEXTLOAD || 1067 LD->getAddressingMode() != ISD::UNINDEXED) { 1068 return SelectCode(N); 1069 } 1070 1071 SDValue Chain = LD->getChain(); 1072 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32); 1073 OP1 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32, 1074 MVT::Other, 1075 LD->getBasePtr(), 1076 TargetConst0, Chain), 0); 1077 } else { 1078 return SelectCode(N); 1079 } 1080 1081 // Generate a mpy instruction. 1082 SDNode *Result = CurDAG->getMachineNode(Hexagon::MPY, dl, MVT::i32, 1083 OP0, OP1); 1084 ReplaceUses(N, Result); 1085 return Result; 1086 } 1087 } 1088 1089 return SelectCode(N); 1090 } 1091 1092 1093 SDNode *HexagonDAGToDAGISel::SelectSHL(SDNode *N) { 1094 SDLoc dl(N); 1095 if (N->getValueType(0) == MVT::i32) { 1096 SDValue Shl_0 = N->getOperand(0); 1097 SDValue Shl_1 = N->getOperand(1); 1098 // RHS is const. 1099 if (Shl_1.getOpcode() == ISD::Constant) { 1100 if (Shl_0.getOpcode() == ISD::MUL) { 1101 SDValue Mul_0 = Shl_0.getOperand(0); // Val 1102 SDValue Mul_1 = Shl_0.getOperand(1); // Const 1103 // RHS of mul is const. 1104 if (Mul_1.getOpcode() == ISD::Constant) { 1105 int32_t ShlConst = 1106 cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue(); 1107 int32_t MulConst = 1108 cast<ConstantSDNode>(Mul_1.getNode())->getSExtValue(); 1109 int32_t ValConst = MulConst << ShlConst; 1110 SDValue Val = CurDAG->getTargetConstant(ValConst, 1111 MVT::i32); 1112 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Val.getNode())) 1113 if (isInt<9>(CN->getSExtValue())) { 1114 SDNode* Result = 1115 CurDAG->getMachineNode(Hexagon::MPYI_ri, dl, 1116 MVT::i32, Mul_0, Val); 1117 ReplaceUses(N, Result); 1118 return Result; 1119 } 1120 1121 } 1122 } else if (Shl_0.getOpcode() == ISD::SUB) { 1123 SDValue Sub_0 = Shl_0.getOperand(0); // Const 0 1124 SDValue Sub_1 = Shl_0.getOperand(1); // Val 1125 if (Sub_0.getOpcode() == ISD::Constant) { 1126 int32_t SubConst = 1127 cast<ConstantSDNode>(Sub_0.getNode())->getSExtValue(); 1128 if (SubConst == 0) { 1129 if (Sub_1.getOpcode() == ISD::SHL) { 1130 SDValue Shl2_0 = Sub_1.getOperand(0); // Val 1131 SDValue Shl2_1 = Sub_1.getOperand(1); // Const 1132 if (Shl2_1.getOpcode() == ISD::Constant) { 1133 int32_t ShlConst = 1134 cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue(); 1135 int32_t Shl2Const = 1136 cast<ConstantSDNode>(Shl2_1.getNode())->getSExtValue(); 1137 int32_t ValConst = 1 << (ShlConst+Shl2Const); 1138 SDValue Val = CurDAG->getTargetConstant(-ValConst, MVT::i32); 1139 if (ConstantSDNode *CN = 1140 dyn_cast<ConstantSDNode>(Val.getNode())) 1141 if (isInt<9>(CN->getSExtValue())) { 1142 SDNode* Result = 1143 CurDAG->getMachineNode(Hexagon::MPYI_ri, dl, MVT::i32, 1144 Shl2_0, Val); 1145 ReplaceUses(N, Result); 1146 return Result; 1147 } 1148 } 1149 } 1150 } 1151 } 1152 } 1153 } 1154 } 1155 return SelectCode(N); 1156 } 1157 1158 1159 // 1160 // If there is an zero_extend followed an intrinsic in DAG (this means - the 1161 // result of the intrinsic is predicate); convert the zero_extend to 1162 // transfer instruction. 1163 // 1164 // Zero extend -> transfer is lowered here. Otherwise, zero_extend will be 1165 // converted into a MUX as predicate registers defined as 1 bit in the 1166 // compiler. Architecture defines them as 8-bit registers. 1167 // We want to preserve all the lower 8-bits and, not just 1 LSB bit. 1168 // 1169 SDNode *HexagonDAGToDAGISel::SelectZeroExtend(SDNode *N) { 1170 SDLoc dl(N); 1171 SDNode *IsIntrinsic = N->getOperand(0).getNode(); 1172 if ((IsIntrinsic->getOpcode() == ISD::INTRINSIC_WO_CHAIN)) { 1173 unsigned ID = 1174 cast<ConstantSDNode>(IsIntrinsic->getOperand(0))->getZExtValue(); 1175 if (doesIntrinsicReturnPredicate(ID)) { 1176 // Now we need to differentiate target data types. 1177 if (N->getValueType(0) == MVT::i64) { 1178 // Convert the zero_extend to Rs = Pd followed by COMBINE_rr(0,Rs). 1179 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32); 1180 SDNode *Result_1 = CurDAG->getMachineNode(Hexagon::TFR_RsPd, dl, 1181 MVT::i32, 1182 SDValue(IsIntrinsic, 0)); 1183 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, 1184 MVT::i32, 1185 TargetConst0); 1186 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl, 1187 MVT::i64, MVT::Other, 1188 SDValue(Result_2, 0), 1189 SDValue(Result_1, 0)); 1190 ReplaceUses(N, Result_3); 1191 return Result_3; 1192 } 1193 if (N->getValueType(0) == MVT::i32) { 1194 // Convert the zero_extend to Rs = Pd 1195 SDNode* RsPd = CurDAG->getMachineNode(Hexagon::TFR_RsPd, dl, 1196 MVT::i32, 1197 SDValue(IsIntrinsic, 0)); 1198 ReplaceUses(N, RsPd); 1199 return RsPd; 1200 } 1201 llvm_unreachable("Unexpected value type"); 1202 } 1203 } 1204 return SelectCode(N); 1205 } 1206 1207 1208 // 1209 // Checking for intrinsics which have predicate registers as operand(s) 1210 // and lowering to the actual intrinsic. 1211 // 1212 SDNode *HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) { 1213 SDLoc dl(N); 1214 unsigned ID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue(); 1215 unsigned IntrinsicWithPred = doesIntrinsicContainPredicate(ID); 1216 1217 // We are concerned with only those intrinsics that have predicate registers 1218 // as at least one of the operands. 1219 if (IntrinsicWithPred) { 1220 SmallVector<SDValue, 8> Ops; 1221 const HexagonInstrInfo *TII = 1222 static_cast<const HexagonInstrInfo*>(TM.getInstrInfo()); 1223 const MCInstrDesc &MCID = TII->get(IntrinsicWithPred); 1224 const TargetRegisterInfo *TRI = TM.getRegisterInfo(); 1225 1226 // Iterate over all the operands of the intrinsics. 1227 // For PredRegs, do the transfer. 1228 // For Double/Int Regs, just preserve the value 1229 // For immediates, lower it. 1230 for (unsigned i = 1; i < N->getNumOperands(); ++i) { 1231 SDNode *Arg = N->getOperand(i).getNode(); 1232 const TargetRegisterClass *RC = TII->getRegClass(MCID, i, TRI, *MF); 1233 1234 if (RC == &Hexagon::IntRegsRegClass || 1235 RC == &Hexagon::DoubleRegsRegClass) { 1236 Ops.push_back(SDValue(Arg, 0)); 1237 } else if (RC == &Hexagon::PredRegsRegClass) { 1238 // Do the transfer. 1239 SDNode *PdRs = CurDAG->getMachineNode(Hexagon::TFR_PdRs, dl, MVT::i1, 1240 SDValue(Arg, 0)); 1241 Ops.push_back(SDValue(PdRs,0)); 1242 } else if (!RC && (dyn_cast<ConstantSDNode>(Arg) != nullptr)) { 1243 // This is immediate operand. Lower it here making sure that we DO have 1244 // const SDNode for immediate value. 1245 int32_t Val = cast<ConstantSDNode>(Arg)->getSExtValue(); 1246 SDValue SDVal = CurDAG->getTargetConstant(Val, MVT::i32); 1247 Ops.push_back(SDVal); 1248 } else { 1249 llvm_unreachable("Unimplemented"); 1250 } 1251 } 1252 EVT ReturnValueVT = N->getValueType(0); 1253 SDNode *Result = CurDAG->getMachineNode(IntrinsicWithPred, dl, 1254 ReturnValueVT, Ops); 1255 ReplaceUses(N, Result); 1256 return Result; 1257 } 1258 return SelectCode(N); 1259 } 1260 1261 // 1262 // Map floating point constant values. 1263 // 1264 SDNode *HexagonDAGToDAGISel::SelectConstantFP(SDNode *N) { 1265 SDLoc dl(N); 1266 ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N); 1267 APFloat APF = CN->getValueAPF(); 1268 if (N->getValueType(0) == MVT::f32) { 1269 return CurDAG->getMachineNode(Hexagon::TFRI_f, dl, MVT::f32, 1270 CurDAG->getTargetConstantFP(APF.convertToFloat(), MVT::f32)); 1271 } 1272 else if (N->getValueType(0) == MVT::f64) { 1273 return CurDAG->getMachineNode(Hexagon::CONST64_Float_Real, dl, MVT::f64, 1274 CurDAG->getTargetConstantFP(APF.convertToDouble(), MVT::f64)); 1275 } 1276 1277 return SelectCode(N); 1278 } 1279 1280 1281 // 1282 // Map predicate true (encoded as -1 in LLVM) to a XOR. 1283 // 1284 SDNode *HexagonDAGToDAGISel::SelectConstant(SDNode *N) { 1285 SDLoc dl(N); 1286 if (N->getValueType(0) == MVT::i1) { 1287 SDNode* Result; 1288 int32_t Val = cast<ConstantSDNode>(N)->getSExtValue(); 1289 if (Val == -1) { 1290 // Create the IntReg = 1 node. 1291 SDNode* IntRegTFR = 1292 CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32, 1293 CurDAG->getTargetConstant(0, MVT::i32)); 1294 1295 // Pd = IntReg 1296 SDNode* Pd = CurDAG->getMachineNode(Hexagon::TFR_PdRs, dl, MVT::i1, 1297 SDValue(IntRegTFR, 0)); 1298 1299 // not(Pd) 1300 SDNode* NotPd = CurDAG->getMachineNode(Hexagon::NOT_p, dl, MVT::i1, 1301 SDValue(Pd, 0)); 1302 1303 // xor(not(Pd)) 1304 Result = CurDAG->getMachineNode(Hexagon::XOR_pp, dl, MVT::i1, 1305 SDValue(Pd, 0), SDValue(NotPd, 0)); 1306 1307 // We have just built: 1308 // Rs = Pd 1309 // Pd = xor(not(Pd), Pd) 1310 1311 ReplaceUses(N, Result); 1312 return Result; 1313 } 1314 } 1315 1316 return SelectCode(N); 1317 } 1318 1319 1320 // 1321 // Map add followed by a asr -> asr +=. 1322 // 1323 SDNode *HexagonDAGToDAGISel::SelectAdd(SDNode *N) { 1324 SDLoc dl(N); 1325 if (N->getValueType(0) != MVT::i32) { 1326 return SelectCode(N); 1327 } 1328 // Identify nodes of the form: add(asr(...)). 1329 SDNode* Src1 = N->getOperand(0).getNode(); 1330 if (Src1->getOpcode() != ISD::SRA || !Src1->hasOneUse() 1331 || Src1->getValueType(0) != MVT::i32) { 1332 return SelectCode(N); 1333 } 1334 1335 // Build Rd = Rd' + asr(Rs, Rt). The machine constraints will ensure that 1336 // Rd and Rd' are assigned to the same register 1337 SDNode* Result = CurDAG->getMachineNode(Hexagon::ASR_ADD_rr, dl, MVT::i32, 1338 N->getOperand(1), 1339 Src1->getOperand(0), 1340 Src1->getOperand(1)); 1341 ReplaceUses(N, Result); 1342 1343 return Result; 1344 } 1345 1346 1347 SDNode *HexagonDAGToDAGISel::Select(SDNode *N) { 1348 if (N->isMachineOpcode()) { 1349 N->setNodeId(-1); 1350 return nullptr; // Already selected. 1351 } 1352 1353 1354 switch (N->getOpcode()) { 1355 case ISD::Constant: 1356 return SelectConstant(N); 1357 1358 case ISD::ConstantFP: 1359 return SelectConstantFP(N); 1360 1361 case ISD::ADD: 1362 return SelectAdd(N); 1363 1364 case ISD::SHL: 1365 return SelectSHL(N); 1366 1367 case ISD::LOAD: 1368 return SelectLoad(N); 1369 1370 case ISD::STORE: 1371 return SelectStore(N); 1372 1373 case ISD::SELECT: 1374 return SelectSelect(N); 1375 1376 case ISD::TRUNCATE: 1377 return SelectTruncate(N); 1378 1379 case ISD::MUL: 1380 return SelectMul(N); 1381 1382 case ISD::ZERO_EXTEND: 1383 return SelectZeroExtend(N); 1384 1385 case ISD::INTRINSIC_WO_CHAIN: 1386 return SelectIntrinsicWOChain(N); 1387 } 1388 1389 return SelectCode(N); 1390 } 1391 1392 1393 // 1394 // Hexagon_TODO: Five functions for ADDRri?! Surely there must be a better way 1395 // to define these instructions. 1396 // 1397 bool HexagonDAGToDAGISel::SelectADDRri(SDValue& Addr, SDValue &Base, 1398 SDValue &Offset) { 1399 if (Addr.getOpcode() == ISD::TargetExternalSymbol || 1400 Addr.getOpcode() == ISD::TargetGlobalAddress) 1401 return false; // Direct calls. 1402 1403 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 1404 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 1405 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1406 return true; 1407 } 1408 Base = Addr; 1409 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1410 return true; 1411 } 1412 1413 1414 bool HexagonDAGToDAGISel::SelectADDRriS11_0(SDValue& Addr, SDValue &Base, 1415 SDValue &Offset) { 1416 if (Addr.getOpcode() == ISD::TargetExternalSymbol || 1417 Addr.getOpcode() == ISD::TargetGlobalAddress) 1418 return false; // Direct calls. 1419 1420 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 1421 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 1422 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1423 return (IsS11_0_Offset(Offset.getNode())); 1424 } 1425 Base = Addr; 1426 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1427 return (IsS11_0_Offset(Offset.getNode())); 1428 } 1429 1430 1431 bool HexagonDAGToDAGISel::SelectADDRriS11_1(SDValue& Addr, SDValue &Base, 1432 SDValue &Offset) { 1433 if (Addr.getOpcode() == ISD::TargetExternalSymbol || 1434 Addr.getOpcode() == ISD::TargetGlobalAddress) 1435 return false; // Direct calls. 1436 1437 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 1438 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 1439 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1440 return (IsS11_1_Offset(Offset.getNode())); 1441 } 1442 Base = Addr; 1443 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1444 return (IsS11_1_Offset(Offset.getNode())); 1445 } 1446 1447 1448 bool HexagonDAGToDAGISel::SelectADDRriS11_2(SDValue& Addr, SDValue &Base, 1449 SDValue &Offset) { 1450 if (Addr.getOpcode() == ISD::TargetExternalSymbol || 1451 Addr.getOpcode() == ISD::TargetGlobalAddress) 1452 return false; // Direct calls. 1453 1454 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 1455 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 1456 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1457 return (IsS11_2_Offset(Offset.getNode())); 1458 } 1459 Base = Addr; 1460 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1461 return (IsS11_2_Offset(Offset.getNode())); 1462 } 1463 1464 1465 bool HexagonDAGToDAGISel::SelectADDRriU6_0(SDValue& Addr, SDValue &Base, 1466 SDValue &Offset) { 1467 if (Addr.getOpcode() == ISD::TargetExternalSymbol || 1468 Addr.getOpcode() == ISD::TargetGlobalAddress) 1469 return false; // Direct calls. 1470 1471 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 1472 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 1473 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1474 return (IsU6_0_Offset(Offset.getNode())); 1475 } 1476 Base = Addr; 1477 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1478 return (IsU6_0_Offset(Offset.getNode())); 1479 } 1480 1481 1482 bool HexagonDAGToDAGISel::SelectADDRriU6_1(SDValue& Addr, SDValue &Base, 1483 SDValue &Offset) { 1484 if (Addr.getOpcode() == ISD::TargetExternalSymbol || 1485 Addr.getOpcode() == ISD::TargetGlobalAddress) 1486 return false; // Direct calls. 1487 1488 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 1489 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 1490 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1491 return (IsU6_1_Offset(Offset.getNode())); 1492 } 1493 Base = Addr; 1494 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1495 return (IsU6_1_Offset(Offset.getNode())); 1496 } 1497 1498 1499 bool HexagonDAGToDAGISel::SelectADDRriU6_2(SDValue& Addr, SDValue &Base, 1500 SDValue &Offset) { 1501 if (Addr.getOpcode() == ISD::TargetExternalSymbol || 1502 Addr.getOpcode() == ISD::TargetGlobalAddress) 1503 return false; // Direct calls. 1504 1505 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 1506 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 1507 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1508 return (IsU6_2_Offset(Offset.getNode())); 1509 } 1510 Base = Addr; 1511 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1512 return (IsU6_2_Offset(Offset.getNode())); 1513 } 1514 1515 1516 bool HexagonDAGToDAGISel::SelectMEMriS11_2(SDValue& Addr, SDValue &Base, 1517 SDValue &Offset) { 1518 1519 if (Addr.getOpcode() != ISD::ADD) { 1520 return(SelectADDRriS11_2(Addr, Base, Offset)); 1521 } 1522 1523 return SelectADDRriS11_2(Addr, Base, Offset); 1524 } 1525 1526 1527 bool HexagonDAGToDAGISel::SelectADDRriS11_3(SDValue& Addr, SDValue &Base, 1528 SDValue &Offset) { 1529 if (Addr.getOpcode() == ISD::TargetExternalSymbol || 1530 Addr.getOpcode() == ISD::TargetGlobalAddress) 1531 return false; // Direct calls. 1532 1533 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 1534 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 1535 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1536 return (IsS11_3_Offset(Offset.getNode())); 1537 } 1538 Base = Addr; 1539 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1540 return (IsS11_3_Offset(Offset.getNode())); 1541 } 1542 1543 bool HexagonDAGToDAGISel::SelectADDRrr(SDValue &Addr, SDValue &R1, 1544 SDValue &R2) { 1545 if (Addr.getOpcode() == ISD::FrameIndex) return false; 1546 if (Addr.getOpcode() == ISD::TargetExternalSymbol || 1547 Addr.getOpcode() == ISD::TargetGlobalAddress) 1548 return false; // Direct calls. 1549 1550 if (Addr.getOpcode() == ISD::ADD) { 1551 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) 1552 if (isInt<13>(CN->getSExtValue())) 1553 return false; // Let the reg+imm pattern catch this! 1554 R1 = Addr.getOperand(0); 1555 R2 = Addr.getOperand(1); 1556 return true; 1557 } 1558 1559 R1 = Addr; 1560 1561 return true; 1562 } 1563 1564 1565 // Handle generic address case. It is accessed from inlined asm =m constraints, 1566 // which could have any kind of pointer. 1567 bool HexagonDAGToDAGISel::SelectAddr(SDNode *Op, SDValue Addr, 1568 SDValue &Base, SDValue &Offset) { 1569 if (Addr.getOpcode() == ISD::TargetExternalSymbol || 1570 Addr.getOpcode() == ISD::TargetGlobalAddress) 1571 return false; // Direct calls. 1572 1573 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 1574 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 1575 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1576 return true; 1577 } 1578 1579 if (Addr.getOpcode() == ISD::ADD) { 1580 Base = Addr.getOperand(0); 1581 Offset = Addr.getOperand(1); 1582 return true; 1583 } 1584 1585 Base = Addr; 1586 Offset = CurDAG->getTargetConstant(0, MVT::i32); 1587 return true; 1588 } 1589 1590 1591 bool HexagonDAGToDAGISel:: 1592 SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, 1593 std::vector<SDValue> &OutOps) { 1594 SDValue Op0, Op1; 1595 1596 switch (ConstraintCode) { 1597 case 'o': // Offsetable. 1598 case 'v': // Not offsetable. 1599 default: return true; 1600 case 'm': // Memory. 1601 if (!SelectAddr(Op.getNode(), Op, Op0, Op1)) 1602 return true; 1603 break; 1604 } 1605 1606 OutOps.push_back(Op0); 1607 OutOps.push_back(Op1); 1608 return false; 1609 } 1610 1611 bool HexagonDAGToDAGISel::isConstExtProfitable(SDNode *N) const { 1612 unsigned UseCount = 0; 1613 for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) { 1614 UseCount++; 1615 } 1616 1617 return (UseCount <= 1); 1618 1619 } 1620 1621 //===--------------------------------------------------------------------===// 1622 // Return 'true' if use count of the global address is below threshold. 1623 //===--------------------------------------------------------------------===// 1624 bool HexagonDAGToDAGISel::hasNumUsesBelowThresGA(SDNode *N) const { 1625 assert(N->getOpcode() == ISD::TargetGlobalAddress && 1626 "Expecting a target global address"); 1627 1628 // Always try to fold the address. 1629 if (TM.getOptLevel() == CodeGenOpt::Aggressive) 1630 return true; 1631 1632 GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(N); 1633 DenseMap<const GlobalValue *, unsigned>::const_iterator GI = 1634 GlobalAddressUseCountMap.find(GA->getGlobal()); 1635 1636 if (GI == GlobalAddressUseCountMap.end()) 1637 return false; 1638 1639 return GI->second <= MaxNumOfUsesForConstExtenders; 1640 } 1641 1642 //===--------------------------------------------------------------------===// 1643 // Return true if the non-GP-relative global address can be folded. 1644 //===--------------------------------------------------------------------===// 1645 inline bool HexagonDAGToDAGISel::foldGlobalAddress(SDValue &N, SDValue &R) { 1646 return foldGlobalAddressImpl(N, R, false); 1647 } 1648 1649 //===--------------------------------------------------------------------===// 1650 // Return true if the GP-relative global address can be folded. 1651 //===--------------------------------------------------------------------===// 1652 inline bool HexagonDAGToDAGISel::foldGlobalAddressGP(SDValue &N, SDValue &R) { 1653 return foldGlobalAddressImpl(N, R, true); 1654 } 1655 1656 //===--------------------------------------------------------------------===// 1657 // Fold offset of the global address if number of uses are below threshold. 1658 //===--------------------------------------------------------------------===// 1659 bool HexagonDAGToDAGISel::foldGlobalAddressImpl(SDValue &N, SDValue &R, 1660 bool ShouldLookForGP) { 1661 if (N.getOpcode() == ISD::ADD) { 1662 SDValue N0 = N.getOperand(0); 1663 SDValue N1 = N.getOperand(1); 1664 if ((ShouldLookForGP && (N0.getOpcode() == HexagonISD::CONST32_GP)) || 1665 (!ShouldLookForGP && (N0.getOpcode() == HexagonISD::CONST32))) { 1666 ConstantSDNode *Const = dyn_cast<ConstantSDNode>(N1); 1667 GlobalAddressSDNode *GA = 1668 dyn_cast<GlobalAddressSDNode>(N0.getOperand(0)); 1669 1670 if (Const && GA && 1671 (GA->getOpcode() == ISD::TargetGlobalAddress)) { 1672 if ((N0.getOpcode() == HexagonISD::CONST32) && 1673 !hasNumUsesBelowThresGA(GA)) 1674 return false; 1675 R = CurDAG->getTargetGlobalAddress(GA->getGlobal(), 1676 SDLoc(Const), 1677 N.getValueType(), 1678 GA->getOffset() + 1679 (uint64_t)Const->getSExtValue()); 1680 return true; 1681 } 1682 } 1683 } 1684 return false; 1685 } 1686