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