1 //===--- HexagonSplitDouble.cpp -------------------------------------------===// 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 #define DEBUG_TYPE "hsdr" 11 12 #include "HexagonRegisterInfo.h" 13 #include "HexagonTargetMachine.h" 14 15 #include "llvm/CodeGen/MachineFunction.h" 16 #include "llvm/CodeGen/MachineFunctionPass.h" 17 #include "llvm/CodeGen/MachineInstrBuilder.h" 18 #include "llvm/CodeGen/MachineLoopInfo.h" 19 #include "llvm/CodeGen/MachineRegisterInfo.h" 20 #include "llvm/Pass.h" 21 #include "llvm/Support/CommandLine.h" 22 #include "llvm/Support/Debug.h" 23 #include "llvm/Support/raw_ostream.h" 24 #include "llvm/Target/TargetRegisterInfo.h" 25 26 #include <map> 27 #include <set> 28 #include <vector> 29 30 using namespace llvm; 31 32 namespace llvm { 33 FunctionPass *createHexagonSplitDoubleRegs(); 34 void initializeHexagonSplitDoubleRegsPass(PassRegistry&); 35 } 36 37 namespace { 38 static cl::opt<int> MaxHSDR("max-hsdr", cl::Hidden, cl::init(-1), 39 cl::desc("Maximum number of split partitions")); 40 static cl::opt<bool> MemRefsFixed("hsdr-no-mem", cl::Hidden, cl::init(true), 41 cl::desc("Do not split loads or stores")); 42 43 class HexagonSplitDoubleRegs : public MachineFunctionPass { 44 public: 45 static char ID; 46 HexagonSplitDoubleRegs() : MachineFunctionPass(ID), TRI(nullptr), 47 TII(nullptr) { 48 initializeHexagonSplitDoubleRegsPass(*PassRegistry::getPassRegistry()); 49 } 50 StringRef getPassName() const override { 51 return "Hexagon Split Double Registers"; 52 } 53 void getAnalysisUsage(AnalysisUsage &AU) const override { 54 AU.addRequired<MachineLoopInfo>(); 55 AU.addPreserved<MachineLoopInfo>(); 56 MachineFunctionPass::getAnalysisUsage(AU); 57 } 58 bool runOnMachineFunction(MachineFunction &MF) override; 59 60 private: 61 static const TargetRegisterClass *const DoubleRC; 62 63 const HexagonRegisterInfo *TRI; 64 const HexagonInstrInfo *TII; 65 const MachineLoopInfo *MLI; 66 MachineRegisterInfo *MRI; 67 68 typedef std::set<unsigned> USet; 69 typedef std::map<unsigned,USet> UUSetMap; 70 typedef std::pair<unsigned,unsigned> UUPair; 71 typedef std::map<unsigned,UUPair> UUPairMap; 72 typedef std::map<const MachineLoop*,USet> LoopRegMap; 73 74 bool isInduction(unsigned Reg, LoopRegMap &IRM) const; 75 bool isVolatileInstr(const MachineInstr *MI) const; 76 bool isFixedInstr(const MachineInstr *MI) const; 77 void partitionRegisters(UUSetMap &P2Rs); 78 int32_t profit(const MachineInstr *MI) const; 79 bool isProfitable(const USet &Part, LoopRegMap &IRM) const; 80 81 void collectIndRegsForLoop(const MachineLoop *L, USet &Rs); 82 void collectIndRegs(LoopRegMap &IRM); 83 84 void createHalfInstr(unsigned Opc, MachineInstr *MI, 85 const UUPairMap &PairMap, unsigned SubR); 86 void splitMemRef(MachineInstr *MI, const UUPairMap &PairMap); 87 void splitImmediate(MachineInstr *MI, const UUPairMap &PairMap); 88 void splitCombine(MachineInstr *MI, const UUPairMap &PairMap); 89 void splitExt(MachineInstr *MI, const UUPairMap &PairMap); 90 void splitShift(MachineInstr *MI, const UUPairMap &PairMap); 91 void splitAslOr(MachineInstr *MI, const UUPairMap &PairMap); 92 bool splitInstr(MachineInstr *MI, const UUPairMap &PairMap); 93 void replaceSubregUses(MachineInstr *MI, const UUPairMap &PairMap); 94 void collapseRegPairs(MachineInstr *MI, const UUPairMap &PairMap); 95 bool splitPartition(const USet &Part); 96 97 static int Counter; 98 static void dump_partition(raw_ostream&, const USet&, 99 const TargetRegisterInfo&); 100 }; 101 char HexagonSplitDoubleRegs::ID; 102 int HexagonSplitDoubleRegs::Counter = 0; 103 const TargetRegisterClass *const HexagonSplitDoubleRegs::DoubleRC 104 = &Hexagon::DoubleRegsRegClass; 105 } 106 107 INITIALIZE_PASS(HexagonSplitDoubleRegs, "hexagon-split-double", 108 "Hexagon Split Double Registers", false, false) 109 110 111 void HexagonSplitDoubleRegs::dump_partition(raw_ostream &os, 112 const USet &Part, const TargetRegisterInfo &TRI) { 113 dbgs() << '{'; 114 for (auto I : Part) 115 dbgs() << ' ' << PrintReg(I, &TRI); 116 dbgs() << " }"; 117 } 118 119 120 bool HexagonSplitDoubleRegs::isInduction(unsigned Reg, LoopRegMap &IRM) const { 121 for (auto I : IRM) { 122 const USet &Rs = I.second; 123 if (Rs.find(Reg) != Rs.end()) 124 return true; 125 } 126 return false; 127 } 128 129 130 bool HexagonSplitDoubleRegs::isVolatileInstr(const MachineInstr *MI) const { 131 for (auto &I : MI->memoperands()) 132 if (I->isVolatile()) 133 return true; 134 return false; 135 } 136 137 138 bool HexagonSplitDoubleRegs::isFixedInstr(const MachineInstr *MI) const { 139 if (MI->mayLoad() || MI->mayStore()) 140 if (MemRefsFixed || isVolatileInstr(MI)) 141 return true; 142 if (MI->isDebugValue()) 143 return false; 144 145 unsigned Opc = MI->getOpcode(); 146 switch (Opc) { 147 default: 148 return true; 149 150 case TargetOpcode::PHI: 151 case TargetOpcode::COPY: 152 break; 153 154 case Hexagon::L2_loadrd_io: 155 // Not handling stack stores (only reg-based addresses). 156 if (MI->getOperand(1).isReg()) 157 break; 158 return true; 159 case Hexagon::S2_storerd_io: 160 // Not handling stack stores (only reg-based addresses). 161 if (MI->getOperand(0).isReg()) 162 break; 163 return true; 164 case Hexagon::L2_loadrd_pi: 165 case Hexagon::S2_storerd_pi: 166 167 case Hexagon::A2_tfrpi: 168 case Hexagon::A2_combineii: 169 case Hexagon::A4_combineir: 170 case Hexagon::A4_combineii: 171 case Hexagon::A4_combineri: 172 case Hexagon::A2_combinew: 173 case Hexagon::CONST64: 174 175 case Hexagon::A2_sxtw: 176 177 case Hexagon::A2_andp: 178 case Hexagon::A2_orp: 179 case Hexagon::A2_xorp: 180 case Hexagon::S2_asl_i_p_or: 181 case Hexagon::S2_asl_i_p: 182 case Hexagon::S2_asr_i_p: 183 case Hexagon::S2_lsr_i_p: 184 break; 185 } 186 187 for (auto &Op : MI->operands()) { 188 if (!Op.isReg()) 189 continue; 190 unsigned R = Op.getReg(); 191 if (!TargetRegisterInfo::isVirtualRegister(R)) 192 return true; 193 } 194 return false; 195 } 196 197 198 void HexagonSplitDoubleRegs::partitionRegisters(UUSetMap &P2Rs) { 199 typedef std::map<unsigned,unsigned> UUMap; 200 typedef std::vector<unsigned> UVect; 201 202 unsigned NumRegs = MRI->getNumVirtRegs(); 203 BitVector DoubleRegs(NumRegs); 204 for (unsigned i = 0; i < NumRegs; ++i) { 205 unsigned R = TargetRegisterInfo::index2VirtReg(i); 206 if (MRI->getRegClass(R) == DoubleRC) 207 DoubleRegs.set(i); 208 } 209 210 BitVector FixedRegs(NumRegs); 211 for (int x = DoubleRegs.find_first(); x >= 0; x = DoubleRegs.find_next(x)) { 212 unsigned R = TargetRegisterInfo::index2VirtReg(x); 213 MachineInstr *DefI = MRI->getVRegDef(R); 214 // In some cases a register may exist, but never be defined or used. 215 // It should never appear anywhere, but mark it as "fixed", just to be 216 // safe. 217 if (!DefI || isFixedInstr(DefI)) 218 FixedRegs.set(x); 219 } 220 221 UUSetMap AssocMap; 222 for (int x = DoubleRegs.find_first(); x >= 0; x = DoubleRegs.find_next(x)) { 223 if (FixedRegs[x]) 224 continue; 225 unsigned R = TargetRegisterInfo::index2VirtReg(x); 226 DEBUG(dbgs() << PrintReg(R, TRI) << " ~~"); 227 USet &Asc = AssocMap[R]; 228 for (auto U = MRI->use_nodbg_begin(R), Z = MRI->use_nodbg_end(); 229 U != Z; ++U) { 230 MachineOperand &Op = *U; 231 MachineInstr *UseI = Op.getParent(); 232 if (isFixedInstr(UseI)) 233 continue; 234 for (unsigned i = 0, n = UseI->getNumOperands(); i < n; ++i) { 235 MachineOperand &MO = UseI->getOperand(i); 236 // Skip non-registers or registers with subregisters. 237 if (&MO == &Op || !MO.isReg() || MO.getSubReg()) 238 continue; 239 unsigned T = MO.getReg(); 240 if (!TargetRegisterInfo::isVirtualRegister(T)) { 241 FixedRegs.set(x); 242 continue; 243 } 244 if (MRI->getRegClass(T) != DoubleRC) 245 continue; 246 unsigned u = TargetRegisterInfo::virtReg2Index(T); 247 if (FixedRegs[u]) 248 continue; 249 DEBUG(dbgs() << ' ' << PrintReg(T, TRI)); 250 Asc.insert(T); 251 // Make it symmetric. 252 AssocMap[T].insert(R); 253 } 254 } 255 DEBUG(dbgs() << '\n'); 256 } 257 258 UUMap R2P; 259 unsigned NextP = 1; 260 USet Visited; 261 for (int x = DoubleRegs.find_first(); x >= 0; x = DoubleRegs.find_next(x)) { 262 unsigned R = TargetRegisterInfo::index2VirtReg(x); 263 if (Visited.count(R)) 264 continue; 265 // Create a new partition for R. 266 unsigned ThisP = FixedRegs[x] ? 0 : NextP++; 267 UVect WorkQ; 268 WorkQ.push_back(R); 269 for (unsigned i = 0; i < WorkQ.size(); ++i) { 270 unsigned T = WorkQ[i]; 271 if (Visited.count(T)) 272 continue; 273 R2P[T] = ThisP; 274 Visited.insert(T); 275 // Add all registers associated with T. 276 USet &Asc = AssocMap[T]; 277 for (USet::iterator J = Asc.begin(), F = Asc.end(); J != F; ++J) 278 WorkQ.push_back(*J); 279 } 280 } 281 282 for (auto I : R2P) 283 P2Rs[I.second].insert(I.first); 284 } 285 286 287 static inline int32_t profitImm(unsigned Lo, unsigned Hi) { 288 int32_t P = 0; 289 bool LoZ1 = false, HiZ1 = false; 290 if (Lo == 0 || Lo == 0xFFFFFFFF) 291 P += 10, LoZ1 = true; 292 if (Hi == 0 || Hi == 0xFFFFFFFF) 293 P += 10, HiZ1 = true; 294 if (!LoZ1 && !HiZ1 && Lo == Hi) 295 P += 3; 296 return P; 297 } 298 299 300 int32_t HexagonSplitDoubleRegs::profit(const MachineInstr *MI) const { 301 unsigned ImmX = 0; 302 unsigned Opc = MI->getOpcode(); 303 switch (Opc) { 304 case TargetOpcode::PHI: 305 for (const auto &Op : MI->operands()) 306 if (!Op.getSubReg()) 307 return 0; 308 return 10; 309 case TargetOpcode::COPY: 310 if (MI->getOperand(1).getSubReg() != 0) 311 return 10; 312 return 0; 313 314 case Hexagon::L2_loadrd_io: 315 case Hexagon::S2_storerd_io: 316 return -1; 317 case Hexagon::L2_loadrd_pi: 318 case Hexagon::S2_storerd_pi: 319 return 2; 320 321 case Hexagon::A2_tfrpi: 322 case Hexagon::CONST64: { 323 uint64_t D = MI->getOperand(1).getImm(); 324 unsigned Lo = D & 0xFFFFFFFFULL; 325 unsigned Hi = D >> 32; 326 return profitImm(Lo, Hi); 327 } 328 case Hexagon::A2_combineii: 329 case Hexagon::A4_combineii: 330 return profitImm(MI->getOperand(1).getImm(), 331 MI->getOperand(2).getImm()); 332 case Hexagon::A4_combineri: 333 ImmX++; 334 case Hexagon::A4_combineir: { 335 ImmX++; 336 int64_t V = MI->getOperand(ImmX).getImm(); 337 if (V == 0 || V == -1) 338 return 10; 339 // Fall through into A2_combinew. 340 LLVM_FALLTHROUGH; 341 } 342 case Hexagon::A2_combinew: 343 return 2; 344 345 case Hexagon::A2_sxtw: 346 return 3; 347 348 case Hexagon::A2_andp: 349 case Hexagon::A2_orp: 350 case Hexagon::A2_xorp: 351 return 1; 352 353 case Hexagon::S2_asl_i_p_or: { 354 unsigned S = MI->getOperand(3).getImm(); 355 if (S == 0 || S == 32) 356 return 10; 357 return -1; 358 } 359 case Hexagon::S2_asl_i_p: 360 case Hexagon::S2_asr_i_p: 361 case Hexagon::S2_lsr_i_p: 362 unsigned S = MI->getOperand(2).getImm(); 363 if (S == 0 || S == 32) 364 return 10; 365 if (S == 16) 366 return 5; 367 if (S == 48) 368 return 7; 369 return -10; 370 } 371 372 return 0; 373 } 374 375 376 bool HexagonSplitDoubleRegs::isProfitable(const USet &Part, LoopRegMap &IRM) 377 const { 378 unsigned FixedNum = 0, SplitNum = 0, LoopPhiNum = 0; 379 int32_t TotalP = 0; 380 381 for (unsigned DR : Part) { 382 MachineInstr *DefI = MRI->getVRegDef(DR); 383 int32_t P = profit(DefI); 384 if (P == INT_MIN) 385 return false; 386 TotalP += P; 387 // Reduce the profitability of splitting induction registers. 388 if (isInduction(DR, IRM)) 389 TotalP -= 30; 390 391 for (auto U = MRI->use_nodbg_begin(DR), W = MRI->use_nodbg_end(); 392 U != W; ++U) { 393 MachineInstr *UseI = U->getParent(); 394 if (isFixedInstr(UseI)) { 395 FixedNum++; 396 // Calculate the cost of generating REG_SEQUENCE instructions. 397 for (auto &Op : UseI->operands()) { 398 if (Op.isReg() && Part.count(Op.getReg())) 399 if (Op.getSubReg()) 400 TotalP -= 2; 401 } 402 continue; 403 } 404 // If a register from this partition is used in a fixed instruction, 405 // and there is also a register in this partition that is used in 406 // a loop phi node, then decrease the splitting profit as this can 407 // confuse the modulo scheduler. 408 if (UseI->isPHI()) { 409 const MachineBasicBlock *PB = UseI->getParent(); 410 const MachineLoop *L = MLI->getLoopFor(PB); 411 if (L && L->getHeader() == PB) 412 LoopPhiNum++; 413 } 414 // Splittable instruction. 415 SplitNum++; 416 int32_t P = profit(UseI); 417 if (P == INT_MIN) 418 return false; 419 TotalP += P; 420 } 421 } 422 423 if (FixedNum > 0 && LoopPhiNum > 0) 424 TotalP -= 20*LoopPhiNum; 425 426 DEBUG(dbgs() << "Partition profit: " << TotalP << '\n'); 427 return TotalP > 0; 428 } 429 430 431 void HexagonSplitDoubleRegs::collectIndRegsForLoop(const MachineLoop *L, 432 USet &Rs) { 433 const MachineBasicBlock *HB = L->getHeader(); 434 const MachineBasicBlock *LB = L->getLoopLatch(); 435 if (!HB || !LB) 436 return; 437 438 // Examine the latch branch. Expect it to be a conditional branch to 439 // the header (either "br-cond header" or "br-cond exit; br header"). 440 MachineBasicBlock *TB = 0, *FB = 0; 441 MachineBasicBlock *TmpLB = const_cast<MachineBasicBlock*>(LB); 442 SmallVector<MachineOperand,2> Cond; 443 bool BadLB = TII->analyzeBranch(*TmpLB, TB, FB, Cond, false); 444 // Only analyzable conditional branches. HII::analyzeBranch will put 445 // the branch opcode as the first element of Cond, and the predicate 446 // operand as the second. 447 if (BadLB || Cond.size() != 2) 448 return; 449 // Only simple jump-conditional (with or without negation). 450 if (!TII->PredOpcodeHasJMP_c(Cond[0].getImm())) 451 return; 452 // Must go to the header. 453 if (TB != HB && FB != HB) 454 return; 455 assert(Cond[1].isReg() && "Unexpected Cond vector from analyzeBranch"); 456 // Expect a predicate register. 457 unsigned PR = Cond[1].getReg(); 458 assert(MRI->getRegClass(PR) == &Hexagon::PredRegsRegClass); 459 460 // Get the registers on which the loop controlling compare instruction 461 // depends. 462 unsigned CmpR1 = 0, CmpR2 = 0; 463 const MachineInstr *CmpI = MRI->getVRegDef(PR); 464 while (CmpI->getOpcode() == Hexagon::C2_not) 465 CmpI = MRI->getVRegDef(CmpI->getOperand(1).getReg()); 466 467 int Mask = 0, Val = 0; 468 bool OkCI = TII->analyzeCompare(*CmpI, CmpR1, CmpR2, Mask, Val); 469 if (!OkCI) 470 return; 471 // Eliminate non-double input registers. 472 if (CmpR1 && MRI->getRegClass(CmpR1) != DoubleRC) 473 CmpR1 = 0; 474 if (CmpR2 && MRI->getRegClass(CmpR2) != DoubleRC) 475 CmpR2 = 0; 476 if (!CmpR1 && !CmpR2) 477 return; 478 479 // Now examine the top of the loop: the phi nodes that could poten- 480 // tially define loop induction registers. The registers defined by 481 // such a phi node would be used in a 64-bit add, which then would 482 // be used in the loop compare instruction. 483 484 // Get the set of all double registers defined by phi nodes in the 485 // loop header. 486 typedef std::vector<unsigned> UVect; 487 UVect DP; 488 for (auto &MI : *HB) { 489 if (!MI.isPHI()) 490 break; 491 const MachineOperand &MD = MI.getOperand(0); 492 unsigned R = MD.getReg(); 493 if (MRI->getRegClass(R) == DoubleRC) 494 DP.push_back(R); 495 } 496 if (DP.empty()) 497 return; 498 499 auto NoIndOp = [this, CmpR1, CmpR2] (unsigned R) -> bool { 500 for (auto I = MRI->use_nodbg_begin(R), E = MRI->use_nodbg_end(); 501 I != E; ++I) { 502 const MachineInstr *UseI = I->getParent(); 503 if (UseI->getOpcode() != Hexagon::A2_addp) 504 continue; 505 // Get the output from the add. If it is one of the inputs to the 506 // loop-controlling compare instruction, then R is likely an induc- 507 // tion register. 508 unsigned T = UseI->getOperand(0).getReg(); 509 if (T == CmpR1 || T == CmpR2) 510 return false; 511 } 512 return true; 513 }; 514 UVect::iterator End = remove_if(DP, NoIndOp); 515 Rs.insert(DP.begin(), End); 516 Rs.insert(CmpR1); 517 Rs.insert(CmpR2); 518 519 DEBUG({ 520 dbgs() << "For loop at BB#" << HB->getNumber() << " ind regs: "; 521 dump_partition(dbgs(), Rs, *TRI); 522 dbgs() << '\n'; 523 }); 524 } 525 526 527 void HexagonSplitDoubleRegs::collectIndRegs(LoopRegMap &IRM) { 528 typedef std::vector<MachineLoop*> LoopVector; 529 LoopVector WorkQ; 530 531 for (auto I : *MLI) 532 WorkQ.push_back(I); 533 for (unsigned i = 0; i < WorkQ.size(); ++i) { 534 for (auto I : *WorkQ[i]) 535 WorkQ.push_back(I); 536 } 537 538 USet Rs; 539 for (unsigned i = 0, n = WorkQ.size(); i < n; ++i) { 540 MachineLoop *L = WorkQ[i]; 541 Rs.clear(); 542 collectIndRegsForLoop(L, Rs); 543 if (!Rs.empty()) 544 IRM.insert(std::make_pair(L, Rs)); 545 } 546 } 547 548 549 void HexagonSplitDoubleRegs::createHalfInstr(unsigned Opc, MachineInstr *MI, 550 const UUPairMap &PairMap, unsigned SubR) { 551 MachineBasicBlock &B = *MI->getParent(); 552 DebugLoc DL = MI->getDebugLoc(); 553 MachineInstr *NewI = BuildMI(B, MI, DL, TII->get(Opc)); 554 555 for (auto &Op : MI->operands()) { 556 if (!Op.isReg()) { 557 NewI->addOperand(Op); 558 continue; 559 } 560 // For register operands, set the subregister. 561 unsigned R = Op.getReg(); 562 unsigned SR = Op.getSubReg(); 563 bool isVirtReg = TargetRegisterInfo::isVirtualRegister(R); 564 bool isKill = Op.isKill(); 565 if (isVirtReg && MRI->getRegClass(R) == DoubleRC) { 566 isKill = false; 567 UUPairMap::const_iterator F = PairMap.find(R); 568 if (F == PairMap.end()) { 569 SR = SubR; 570 } else { 571 const UUPair &P = F->second; 572 R = (SubR == Hexagon::isub_lo) ? P.first : P.second; 573 SR = 0; 574 } 575 } 576 auto CO = MachineOperand::CreateReg(R, Op.isDef(), Op.isImplicit(), isKill, 577 Op.isDead(), Op.isUndef(), Op.isEarlyClobber(), SR, Op.isDebug(), 578 Op.isInternalRead()); 579 NewI->addOperand(CO); 580 } 581 } 582 583 584 void HexagonSplitDoubleRegs::splitMemRef(MachineInstr *MI, 585 const UUPairMap &PairMap) { 586 bool Load = MI->mayLoad(); 587 unsigned OrigOpc = MI->getOpcode(); 588 bool PostInc = (OrigOpc == Hexagon::L2_loadrd_pi || 589 OrigOpc == Hexagon::S2_storerd_pi); 590 MachineInstr *LowI, *HighI; 591 MachineBasicBlock &B = *MI->getParent(); 592 DebugLoc DL = MI->getDebugLoc(); 593 594 // Index of the base-address-register operand. 595 unsigned AdrX = PostInc ? (Load ? 2 : 1) 596 : (Load ? 1 : 0); 597 MachineOperand &AdrOp = MI->getOperand(AdrX); 598 unsigned RSA = getRegState(AdrOp); 599 MachineOperand &ValOp = Load ? MI->getOperand(0) 600 : (PostInc ? MI->getOperand(3) 601 : MI->getOperand(2)); 602 UUPairMap::const_iterator F = PairMap.find(ValOp.getReg()); 603 assert(F != PairMap.end()); 604 605 if (Load) { 606 const UUPair &P = F->second; 607 int64_t Off = PostInc ? 0 : MI->getOperand(2).getImm(); 608 LowI = BuildMI(B, MI, DL, TII->get(Hexagon::L2_loadri_io), P.first) 609 .addReg(AdrOp.getReg(), RSA & ~RegState::Kill, AdrOp.getSubReg()) 610 .addImm(Off); 611 HighI = BuildMI(B, MI, DL, TII->get(Hexagon::L2_loadri_io), P.second) 612 .addReg(AdrOp.getReg(), RSA & ~RegState::Kill, AdrOp.getSubReg()) 613 .addImm(Off+4); 614 } else { 615 const UUPair &P = F->second; 616 int64_t Off = PostInc ? 0 : MI->getOperand(1).getImm(); 617 LowI = BuildMI(B, MI, DL, TII->get(Hexagon::S2_storeri_io)) 618 .addReg(AdrOp.getReg(), RSA & ~RegState::Kill, AdrOp.getSubReg()) 619 .addImm(Off) 620 .addReg(P.first); 621 HighI = BuildMI(B, MI, DL, TII->get(Hexagon::S2_storeri_io)) 622 .addReg(AdrOp.getReg(), RSA & ~RegState::Kill, AdrOp.getSubReg()) 623 .addImm(Off+4) 624 .addReg(P.second); 625 } 626 627 if (PostInc) { 628 // Create the increment of the address register. 629 int64_t Inc = Load ? MI->getOperand(3).getImm() 630 : MI->getOperand(2).getImm(); 631 MachineOperand &UpdOp = Load ? MI->getOperand(1) : MI->getOperand(0); 632 const TargetRegisterClass *RC = MRI->getRegClass(UpdOp.getReg()); 633 unsigned NewR = MRI->createVirtualRegister(RC); 634 assert(!UpdOp.getSubReg() && "Def operand with subreg"); 635 BuildMI(B, MI, DL, TII->get(Hexagon::A2_addi), NewR) 636 .addReg(AdrOp.getReg(), RSA) 637 .addImm(Inc); 638 MRI->replaceRegWith(UpdOp.getReg(), NewR); 639 // The original instruction will be deleted later. 640 } 641 642 // Generate a new pair of memory-operands. 643 MachineFunction &MF = *B.getParent(); 644 for (auto &MO : MI->memoperands()) { 645 const MachinePointerInfo &Ptr = MO->getPointerInfo(); 646 MachineMemOperand::Flags F = MO->getFlags(); 647 int A = MO->getAlignment(); 648 649 auto *Tmp1 = MF.getMachineMemOperand(Ptr, F, 4/*size*/, A); 650 LowI->addMemOperand(MF, Tmp1); 651 auto *Tmp2 = MF.getMachineMemOperand(Ptr, F, 4/*size*/, std::min(A, 4)); 652 HighI->addMemOperand(MF, Tmp2); 653 } 654 } 655 656 657 void HexagonSplitDoubleRegs::splitImmediate(MachineInstr *MI, 658 const UUPairMap &PairMap) { 659 MachineOperand &Op0 = MI->getOperand(0); 660 MachineOperand &Op1 = MI->getOperand(1); 661 assert(Op0.isReg() && Op1.isImm()); 662 uint64_t V = Op1.getImm(); 663 664 MachineBasicBlock &B = *MI->getParent(); 665 DebugLoc DL = MI->getDebugLoc(); 666 UUPairMap::const_iterator F = PairMap.find(Op0.getReg()); 667 assert(F != PairMap.end()); 668 const UUPair &P = F->second; 669 670 // The operand to A2_tfrsi can only have 32 significant bits. Immediate 671 // values in MachineOperand are stored as 64-bit integers, and so the 672 // value -1 may be represented either as 64-bit -1, or 4294967295. Both 673 // will have the 32 higher bits truncated in the end, but -1 will remain 674 // as -1, while the latter may appear to be a large unsigned value 675 // requiring a constant extender. The casting to int32_t will select the 676 // former representation. (The same reasoning applies to all 32-bit 677 // values.) 678 BuildMI(B, MI, DL, TII->get(Hexagon::A2_tfrsi), P.first) 679 .addImm(int32_t(V & 0xFFFFFFFFULL)); 680 BuildMI(B, MI, DL, TII->get(Hexagon::A2_tfrsi), P.second) 681 .addImm(int32_t(V >> 32)); 682 } 683 684 685 void HexagonSplitDoubleRegs::splitCombine(MachineInstr *MI, 686 const UUPairMap &PairMap) { 687 MachineOperand &Op0 = MI->getOperand(0); 688 MachineOperand &Op1 = MI->getOperand(1); 689 MachineOperand &Op2 = MI->getOperand(2); 690 assert(Op0.isReg()); 691 692 MachineBasicBlock &B = *MI->getParent(); 693 DebugLoc DL = MI->getDebugLoc(); 694 UUPairMap::const_iterator F = PairMap.find(Op0.getReg()); 695 assert(F != PairMap.end()); 696 const UUPair &P = F->second; 697 698 if (Op1.isImm()) { 699 BuildMI(B, MI, DL, TII->get(Hexagon::A2_tfrsi), P.second) 700 .addImm(Op1.getImm()); 701 } else if (Op1.isReg()) { 702 BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), P.second) 703 .addReg(Op1.getReg(), getRegState(Op1), Op1.getSubReg()); 704 } else 705 llvm_unreachable("Unexpected operand"); 706 707 if (Op2.isImm()) { 708 BuildMI(B, MI, DL, TII->get(Hexagon::A2_tfrsi), P.first) 709 .addImm(Op2.getImm()); 710 } else if (Op2.isReg()) { 711 BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), P.first) 712 .addReg(Op2.getReg(), getRegState(Op2), Op2.getSubReg()); 713 } else 714 llvm_unreachable("Unexpected operand"); 715 } 716 717 718 void HexagonSplitDoubleRegs::splitExt(MachineInstr *MI, 719 const UUPairMap &PairMap) { 720 MachineOperand &Op0 = MI->getOperand(0); 721 MachineOperand &Op1 = MI->getOperand(1); 722 assert(Op0.isReg() && Op1.isReg()); 723 724 MachineBasicBlock &B = *MI->getParent(); 725 DebugLoc DL = MI->getDebugLoc(); 726 UUPairMap::const_iterator F = PairMap.find(Op0.getReg()); 727 assert(F != PairMap.end()); 728 const UUPair &P = F->second; 729 unsigned RS = getRegState(Op1); 730 731 BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), P.first) 732 .addReg(Op1.getReg(), RS & ~RegState::Kill, Op1.getSubReg()); 733 BuildMI(B, MI, DL, TII->get(Hexagon::S2_asr_i_r), P.second) 734 .addReg(Op1.getReg(), RS, Op1.getSubReg()) 735 .addImm(31); 736 } 737 738 739 void HexagonSplitDoubleRegs::splitShift(MachineInstr *MI, 740 const UUPairMap &PairMap) { 741 MachineOperand &Op0 = MI->getOperand(0); 742 MachineOperand &Op1 = MI->getOperand(1); 743 MachineOperand &Op2 = MI->getOperand(2); 744 assert(Op0.isReg() && Op1.isReg() && Op2.isImm()); 745 int64_t Sh64 = Op2.getImm(); 746 assert(Sh64 >= 0 && Sh64 < 64); 747 unsigned S = Sh64; 748 749 UUPairMap::const_iterator F = PairMap.find(Op0.getReg()); 750 assert(F != PairMap.end()); 751 const UUPair &P = F->second; 752 unsigned LoR = P.first; 753 unsigned HiR = P.second; 754 using namespace Hexagon; 755 756 unsigned Opc = MI->getOpcode(); 757 bool Right = (Opc == S2_lsr_i_p || Opc == S2_asr_i_p); 758 bool Left = !Right; 759 bool Signed = (Opc == S2_asr_i_p); 760 761 MachineBasicBlock &B = *MI->getParent(); 762 DebugLoc DL = MI->getDebugLoc(); 763 unsigned RS = getRegState(Op1); 764 unsigned ShiftOpc = Left ? S2_asl_i_r 765 : (Signed ? S2_asr_i_r : S2_lsr_i_r); 766 unsigned LoSR = isub_lo; 767 unsigned HiSR = isub_hi; 768 769 if (S == 0) { 770 // No shift, subregister copy. 771 BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), LoR) 772 .addReg(Op1.getReg(), RS & ~RegState::Kill, LoSR); 773 BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), HiR) 774 .addReg(Op1.getReg(), RS, HiSR); 775 } else if (S < 32) { 776 const TargetRegisterClass *IntRC = &IntRegsRegClass; 777 unsigned TmpR = MRI->createVirtualRegister(IntRC); 778 // Expansion: 779 // Shift left: DR = shl R, #s 780 // LoR = shl R.lo, #s 781 // TmpR = extractu R.lo, #s, #32-s 782 // HiR = or (TmpR, asl(R.hi, #s)) 783 // Shift right: DR = shr R, #s 784 // HiR = shr R.hi, #s 785 // TmpR = shr R.lo, #s 786 // LoR = insert TmpR, R.hi, #s, #32-s 787 788 // Shift left: 789 // LoR = shl R.lo, #s 790 // Shift right: 791 // TmpR = shr R.lo, #s 792 793 // Make a special case for A2_aslh and A2_asrh (they are predicable as 794 // opposed to S2_asl_i_r/S2_asr_i_r). 795 if (S == 16 && Left) 796 BuildMI(B, MI, DL, TII->get(A2_aslh), LoR) 797 .addReg(Op1.getReg(), RS & ~RegState::Kill, LoSR); 798 else if (S == 16 && Signed) 799 BuildMI(B, MI, DL, TII->get(A2_asrh), TmpR) 800 .addReg(Op1.getReg(), RS & ~RegState::Kill, LoSR); 801 else 802 BuildMI(B, MI, DL, TII->get(ShiftOpc), (Left ? LoR : TmpR)) 803 .addReg(Op1.getReg(), RS & ~RegState::Kill, LoSR) 804 .addImm(S); 805 806 if (Left) { 807 // TmpR = extractu R.lo, #s, #32-s 808 BuildMI(B, MI, DL, TII->get(S2_extractu), TmpR) 809 .addReg(Op1.getReg(), RS & ~RegState::Kill, LoSR) 810 .addImm(S) 811 .addImm(32-S); 812 // HiR = or (TmpR, asl(R.hi, #s)) 813 BuildMI(B, MI, DL, TII->get(S2_asl_i_r_or), HiR) 814 .addReg(TmpR) 815 .addReg(Op1.getReg(), RS, HiSR) 816 .addImm(S); 817 } else { 818 // HiR = shr R.hi, #s 819 BuildMI(B, MI, DL, TII->get(ShiftOpc), HiR) 820 .addReg(Op1.getReg(), RS & ~RegState::Kill, HiSR) 821 .addImm(S); 822 // LoR = insert TmpR, R.hi, #s, #32-s 823 BuildMI(B, MI, DL, TII->get(S2_insert), LoR) 824 .addReg(TmpR) 825 .addReg(Op1.getReg(), RS, HiSR) 826 .addImm(S) 827 .addImm(32-S); 828 } 829 } else if (S == 32) { 830 BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), (Left ? HiR : LoR)) 831 .addReg(Op1.getReg(), RS & ~RegState::Kill, (Left ? LoSR : HiSR)); 832 if (!Signed) 833 BuildMI(B, MI, DL, TII->get(A2_tfrsi), (Left ? LoR : HiR)) 834 .addImm(0); 835 else // Must be right shift. 836 BuildMI(B, MI, DL, TII->get(S2_asr_i_r), HiR) 837 .addReg(Op1.getReg(), RS, HiSR) 838 .addImm(31); 839 } else if (S < 64) { 840 S -= 32; 841 if (S == 16 && Left) 842 BuildMI(B, MI, DL, TII->get(A2_aslh), HiR) 843 .addReg(Op1.getReg(), RS & ~RegState::Kill, LoSR); 844 else if (S == 16 && Signed) 845 BuildMI(B, MI, DL, TII->get(A2_asrh), LoR) 846 .addReg(Op1.getReg(), RS & ~RegState::Kill, HiSR); 847 else 848 BuildMI(B, MI, DL, TII->get(ShiftOpc), (Left ? HiR : LoR)) 849 .addReg(Op1.getReg(), RS & ~RegState::Kill, (Left ? LoSR : HiSR)) 850 .addImm(S); 851 852 if (Signed) 853 BuildMI(B, MI, DL, TII->get(S2_asr_i_r), HiR) 854 .addReg(Op1.getReg(), RS, HiSR) 855 .addImm(31); 856 else 857 BuildMI(B, MI, DL, TII->get(A2_tfrsi), (Left ? LoR : HiR)) 858 .addImm(0); 859 } 860 } 861 862 863 void HexagonSplitDoubleRegs::splitAslOr(MachineInstr *MI, 864 const UUPairMap &PairMap) { 865 MachineOperand &Op0 = MI->getOperand(0); 866 MachineOperand &Op1 = MI->getOperand(1); 867 MachineOperand &Op2 = MI->getOperand(2); 868 MachineOperand &Op3 = MI->getOperand(3); 869 assert(Op0.isReg() && Op1.isReg() && Op2.isReg() && Op3.isImm()); 870 int64_t Sh64 = Op3.getImm(); 871 assert(Sh64 >= 0 && Sh64 < 64); 872 unsigned S = Sh64; 873 874 UUPairMap::const_iterator F = PairMap.find(Op0.getReg()); 875 assert(F != PairMap.end()); 876 const UUPair &P = F->second; 877 unsigned LoR = P.first; 878 unsigned HiR = P.second; 879 using namespace Hexagon; 880 881 MachineBasicBlock &B = *MI->getParent(); 882 DebugLoc DL = MI->getDebugLoc(); 883 unsigned RS1 = getRegState(Op1); 884 unsigned RS2 = getRegState(Op2); 885 const TargetRegisterClass *IntRC = &IntRegsRegClass; 886 887 unsigned LoSR = isub_lo; 888 unsigned HiSR = isub_hi; 889 890 // Op0 = S2_asl_i_p_or Op1, Op2, Op3 891 // means: Op0 = or (Op1, asl(Op2, Op3)) 892 893 // Expansion of 894 // DR = or (R1, asl(R2, #s)) 895 // 896 // LoR = or (R1.lo, asl(R2.lo, #s)) 897 // Tmp1 = extractu R2.lo, #s, #32-s 898 // Tmp2 = or R1.hi, Tmp1 899 // HiR = or (Tmp2, asl(R2.hi, #s)) 900 901 if (S == 0) { 902 // DR = or (R1, asl(R2, #0)) 903 // -> or (R1, R2) 904 // i.e. LoR = or R1.lo, R2.lo 905 // HiR = or R1.hi, R2.hi 906 BuildMI(B, MI, DL, TII->get(A2_or), LoR) 907 .addReg(Op1.getReg(), RS1 & ~RegState::Kill, LoSR) 908 .addReg(Op2.getReg(), RS2 & ~RegState::Kill, LoSR); 909 BuildMI(B, MI, DL, TII->get(A2_or), HiR) 910 .addReg(Op1.getReg(), RS1, HiSR) 911 .addReg(Op2.getReg(), RS2, HiSR); 912 } else if (S < 32) { 913 BuildMI(B, MI, DL, TII->get(S2_asl_i_r_or), LoR) 914 .addReg(Op1.getReg(), RS1 & ~RegState::Kill, LoSR) 915 .addReg(Op2.getReg(), RS2 & ~RegState::Kill, LoSR) 916 .addImm(S); 917 unsigned TmpR1 = MRI->createVirtualRegister(IntRC); 918 BuildMI(B, MI, DL, TII->get(S2_extractu), TmpR1) 919 .addReg(Op2.getReg(), RS2 & ~RegState::Kill, LoSR) 920 .addImm(S) 921 .addImm(32-S); 922 unsigned TmpR2 = MRI->createVirtualRegister(IntRC); 923 BuildMI(B, MI, DL, TII->get(A2_or), TmpR2) 924 .addReg(Op1.getReg(), RS1, HiSR) 925 .addReg(TmpR1); 926 BuildMI(B, MI, DL, TII->get(S2_asl_i_r_or), HiR) 927 .addReg(TmpR2) 928 .addReg(Op2.getReg(), RS2, HiSR) 929 .addImm(S); 930 } else if (S == 32) { 931 // DR = or (R1, asl(R2, #32)) 932 // -> or R1, R2.lo 933 // LoR = R1.lo 934 // HiR = or R1.hi, R2.lo 935 BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), LoR) 936 .addReg(Op1.getReg(), RS1 & ~RegState::Kill, LoSR); 937 BuildMI(B, MI, DL, TII->get(A2_or), HiR) 938 .addReg(Op1.getReg(), RS1, HiSR) 939 .addReg(Op2.getReg(), RS2, LoSR); 940 } else if (S < 64) { 941 // DR = or (R1, asl(R2, #s)) 942 // 943 // LoR = R1:lo 944 // HiR = or (R1:hi, asl(R2:lo, #s-32)) 945 S -= 32; 946 BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), LoR) 947 .addReg(Op1.getReg(), RS1 & ~RegState::Kill, LoSR); 948 BuildMI(B, MI, DL, TII->get(S2_asl_i_r_or), HiR) 949 .addReg(Op1.getReg(), RS1, HiSR) 950 .addReg(Op2.getReg(), RS2, LoSR) 951 .addImm(S); 952 } 953 } 954 955 956 bool HexagonSplitDoubleRegs::splitInstr(MachineInstr *MI, 957 const UUPairMap &PairMap) { 958 DEBUG(dbgs() << "Splitting: " << *MI); 959 bool Split = false; 960 unsigned Opc = MI->getOpcode(); 961 using namespace Hexagon; 962 963 switch (Opc) { 964 case TargetOpcode::PHI: 965 case TargetOpcode::COPY: { 966 unsigned DstR = MI->getOperand(0).getReg(); 967 if (MRI->getRegClass(DstR) == DoubleRC) { 968 createHalfInstr(Opc, MI, PairMap, isub_lo); 969 createHalfInstr(Opc, MI, PairMap, isub_hi); 970 Split = true; 971 } 972 break; 973 } 974 case A2_andp: 975 createHalfInstr(A2_and, MI, PairMap, isub_lo); 976 createHalfInstr(A2_and, MI, PairMap, isub_hi); 977 Split = true; 978 break; 979 case A2_orp: 980 createHalfInstr(A2_or, MI, PairMap, isub_lo); 981 createHalfInstr(A2_or, MI, PairMap, isub_hi); 982 Split = true; 983 break; 984 case A2_xorp: 985 createHalfInstr(A2_xor, MI, PairMap, isub_lo); 986 createHalfInstr(A2_xor, MI, PairMap, isub_hi); 987 Split = true; 988 break; 989 990 case L2_loadrd_io: 991 case L2_loadrd_pi: 992 case S2_storerd_io: 993 case S2_storerd_pi: 994 splitMemRef(MI, PairMap); 995 Split = true; 996 break; 997 998 case A2_tfrpi: 999 case CONST64: 1000 splitImmediate(MI, PairMap); 1001 Split = true; 1002 break; 1003 1004 case A2_combineii: 1005 case A4_combineir: 1006 case A4_combineii: 1007 case A4_combineri: 1008 case A2_combinew: 1009 splitCombine(MI, PairMap); 1010 Split = true; 1011 break; 1012 1013 case A2_sxtw: 1014 splitExt(MI, PairMap); 1015 Split = true; 1016 break; 1017 1018 case S2_asl_i_p: 1019 case S2_asr_i_p: 1020 case S2_lsr_i_p: 1021 splitShift(MI, PairMap); 1022 Split = true; 1023 break; 1024 1025 case S2_asl_i_p_or: 1026 splitAslOr(MI, PairMap); 1027 Split = true; 1028 break; 1029 1030 default: 1031 llvm_unreachable("Instruction not splitable"); 1032 return false; 1033 } 1034 1035 return Split; 1036 } 1037 1038 1039 void HexagonSplitDoubleRegs::replaceSubregUses(MachineInstr *MI, 1040 const UUPairMap &PairMap) { 1041 for (auto &Op : MI->operands()) { 1042 if (!Op.isReg() || !Op.isUse() || !Op.getSubReg()) 1043 continue; 1044 unsigned R = Op.getReg(); 1045 UUPairMap::const_iterator F = PairMap.find(R); 1046 if (F == PairMap.end()) 1047 continue; 1048 const UUPair &P = F->second; 1049 switch (Op.getSubReg()) { 1050 case Hexagon::isub_lo: 1051 Op.setReg(P.first); 1052 break; 1053 case Hexagon::isub_hi: 1054 Op.setReg(P.second); 1055 break; 1056 } 1057 Op.setSubReg(0); 1058 } 1059 } 1060 1061 1062 void HexagonSplitDoubleRegs::collapseRegPairs(MachineInstr *MI, 1063 const UUPairMap &PairMap) { 1064 MachineBasicBlock &B = *MI->getParent(); 1065 DebugLoc DL = MI->getDebugLoc(); 1066 1067 for (auto &Op : MI->operands()) { 1068 if (!Op.isReg() || !Op.isUse()) 1069 continue; 1070 unsigned R = Op.getReg(); 1071 if (!TargetRegisterInfo::isVirtualRegister(R)) 1072 continue; 1073 if (MRI->getRegClass(R) != DoubleRC || Op.getSubReg()) 1074 continue; 1075 UUPairMap::const_iterator F = PairMap.find(R); 1076 if (F == PairMap.end()) 1077 continue; 1078 const UUPair &Pr = F->second; 1079 unsigned NewDR = MRI->createVirtualRegister(DoubleRC); 1080 BuildMI(B, MI, DL, TII->get(TargetOpcode::REG_SEQUENCE), NewDR) 1081 .addReg(Pr.first) 1082 .addImm(Hexagon::isub_lo) 1083 .addReg(Pr.second) 1084 .addImm(Hexagon::isub_hi); 1085 Op.setReg(NewDR); 1086 } 1087 } 1088 1089 1090 bool HexagonSplitDoubleRegs::splitPartition(const USet &Part) { 1091 const TargetRegisterClass *IntRC = &Hexagon::IntRegsRegClass; 1092 typedef std::set<MachineInstr*> MISet; 1093 bool Changed = false; 1094 1095 DEBUG(dbgs() << "Splitting partition: "; dump_partition(dbgs(), Part, *TRI); 1096 dbgs() << '\n'); 1097 1098 UUPairMap PairMap; 1099 1100 MISet SplitIns; 1101 for (unsigned DR : Part) { 1102 MachineInstr *DefI = MRI->getVRegDef(DR); 1103 SplitIns.insert(DefI); 1104 1105 // Collect all instructions, including fixed ones. We won't split them, 1106 // but we need to visit them again to insert the REG_SEQUENCE instructions. 1107 for (auto U = MRI->use_nodbg_begin(DR), W = MRI->use_nodbg_end(); 1108 U != W; ++U) 1109 SplitIns.insert(U->getParent()); 1110 1111 unsigned LoR = MRI->createVirtualRegister(IntRC); 1112 unsigned HiR = MRI->createVirtualRegister(IntRC); 1113 DEBUG(dbgs() << "Created mapping: " << PrintReg(DR, TRI) << " -> " 1114 << PrintReg(HiR, TRI) << ':' << PrintReg(LoR, TRI) << '\n'); 1115 PairMap.insert(std::make_pair(DR, UUPair(LoR, HiR))); 1116 } 1117 1118 MISet Erase; 1119 for (auto MI : SplitIns) { 1120 if (isFixedInstr(MI)) { 1121 collapseRegPairs(MI, PairMap); 1122 } else { 1123 bool Done = splitInstr(MI, PairMap); 1124 if (Done) 1125 Erase.insert(MI); 1126 Changed |= Done; 1127 } 1128 } 1129 1130 for (unsigned DR : Part) { 1131 // Before erasing "double" instructions, revisit all uses of the double 1132 // registers in this partition, and replace all uses of them with subre- 1133 // gisters, with the corresponding single registers. 1134 MISet Uses; 1135 for (auto U = MRI->use_nodbg_begin(DR), W = MRI->use_nodbg_end(); 1136 U != W; ++U) 1137 Uses.insert(U->getParent()); 1138 for (auto M : Uses) 1139 replaceSubregUses(M, PairMap); 1140 } 1141 1142 for (auto MI : Erase) { 1143 MachineBasicBlock *B = MI->getParent(); 1144 B->erase(MI); 1145 } 1146 1147 return Changed; 1148 } 1149 1150 1151 bool HexagonSplitDoubleRegs::runOnMachineFunction(MachineFunction &MF) { 1152 DEBUG(dbgs() << "Splitting double registers in function: " 1153 << MF.getName() << '\n'); 1154 1155 if (skipFunction(*MF.getFunction())) 1156 return false; 1157 1158 auto &ST = MF.getSubtarget<HexagonSubtarget>(); 1159 TRI = ST.getRegisterInfo(); 1160 TII = ST.getInstrInfo(); 1161 MRI = &MF.getRegInfo(); 1162 MLI = &getAnalysis<MachineLoopInfo>(); 1163 1164 UUSetMap P2Rs; 1165 LoopRegMap IRM; 1166 1167 collectIndRegs(IRM); 1168 partitionRegisters(P2Rs); 1169 1170 DEBUG({ 1171 dbgs() << "Register partitioning: (partition #0 is fixed)\n"; 1172 for (UUSetMap::iterator I = P2Rs.begin(), E = P2Rs.end(); I != E; ++I) { 1173 dbgs() << '#' << I->first << " -> "; 1174 dump_partition(dbgs(), I->second, *TRI); 1175 dbgs() << '\n'; 1176 } 1177 }); 1178 1179 bool Changed = false; 1180 int Limit = MaxHSDR; 1181 1182 for (UUSetMap::iterator I = P2Rs.begin(), E = P2Rs.end(); I != E; ++I) { 1183 if (I->first == 0) 1184 continue; 1185 if (Limit >= 0 && Counter >= Limit) 1186 break; 1187 USet &Part = I->second; 1188 DEBUG(dbgs() << "Calculating profit for partition #" << I->first << '\n'); 1189 if (!isProfitable(Part, IRM)) 1190 continue; 1191 Counter++; 1192 Changed |= splitPartition(Part); 1193 } 1194 1195 return Changed; 1196 } 1197 1198 FunctionPass *llvm::createHexagonSplitDoubleRegs() { 1199 return new HexagonSplitDoubleRegs(); 1200 } 1201