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