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