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