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