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 case Hexagon::A4_combineir: { 354 ImmX++; 355 int64_t V = MI->getOperand(ImmX).getImm(); 356 if (V == 0 || V == -1) 357 return 10; 358 // Fall through into A2_combinew. 359 LLVM_FALLTHROUGH; 360 } 361 case Hexagon::A2_combinew: 362 return 2; 363 364 case Hexagon::A2_sxtw: 365 return 3; 366 367 case Hexagon::A2_andp: 368 case Hexagon::A2_orp: 369 case Hexagon::A2_xorp: 370 return 1; 371 372 case Hexagon::S2_asl_i_p_or: { 373 unsigned S = MI->getOperand(3).getImm(); 374 if (S == 0 || S == 32) 375 return 10; 376 return -1; 377 } 378 case Hexagon::S2_asl_i_p: 379 case Hexagon::S2_asr_i_p: 380 case Hexagon::S2_lsr_i_p: 381 unsigned S = MI->getOperand(2).getImm(); 382 if (S == 0 || S == 32) 383 return 10; 384 if (S == 16) 385 return 5; 386 if (S == 48) 387 return 7; 388 return -10; 389 } 390 391 return 0; 392 } 393 394 bool HexagonSplitDoubleRegs::isProfitable(const USet &Part, LoopRegMap &IRM) 395 const { 396 unsigned FixedNum = 0, LoopPhiNum = 0; 397 int32_t TotalP = 0; 398 399 for (unsigned DR : Part) { 400 MachineInstr *DefI = MRI->getVRegDef(DR); 401 int32_t P = profit(DefI); 402 if (P == std::numeric_limits<int>::min()) 403 return false; 404 TotalP += P; 405 // Reduce the profitability of splitting induction registers. 406 if (isInduction(DR, IRM)) 407 TotalP -= 30; 408 409 for (auto U = MRI->use_nodbg_begin(DR), W = MRI->use_nodbg_end(); 410 U != W; ++U) { 411 MachineInstr *UseI = U->getParent(); 412 if (isFixedInstr(UseI)) { 413 FixedNum++; 414 // Calculate the cost of generating REG_SEQUENCE instructions. 415 for (auto &Op : UseI->operands()) { 416 if (Op.isReg() && Part.count(Op.getReg())) 417 if (Op.getSubReg()) 418 TotalP -= 2; 419 } 420 continue; 421 } 422 // If a register from this partition is used in a fixed instruction, 423 // and there is also a register in this partition that is used in 424 // a loop phi node, then decrease the splitting profit as this can 425 // confuse the modulo scheduler. 426 if (UseI->isPHI()) { 427 const MachineBasicBlock *PB = UseI->getParent(); 428 const MachineLoop *L = MLI->getLoopFor(PB); 429 if (L && L->getHeader() == PB) 430 LoopPhiNum++; 431 } 432 // Splittable instruction. 433 int32_t P = profit(UseI); 434 if (P == std::numeric_limits<int>::min()) 435 return false; 436 TotalP += P; 437 } 438 } 439 440 if (FixedNum > 0 && LoopPhiNum > 0) 441 TotalP -= 20*LoopPhiNum; 442 443 DEBUG(dbgs() << "Partition profit: " << TotalP << '\n'); 444 return TotalP > 0; 445 } 446 447 void HexagonSplitDoubleRegs::collectIndRegsForLoop(const MachineLoop *L, 448 USet &Rs) { 449 const MachineBasicBlock *HB = L->getHeader(); 450 const MachineBasicBlock *LB = L->getLoopLatch(); 451 if (!HB || !LB) 452 return; 453 454 // Examine the latch branch. Expect it to be a conditional branch to 455 // the header (either "br-cond header" or "br-cond exit; br header"). 456 MachineBasicBlock *TB = nullptr, *FB = nullptr; 457 MachineBasicBlock *TmpLB = const_cast<MachineBasicBlock*>(LB); 458 SmallVector<MachineOperand,2> Cond; 459 bool BadLB = TII->analyzeBranch(*TmpLB, TB, FB, Cond, false); 460 // Only analyzable conditional branches. HII::analyzeBranch will put 461 // the branch opcode as the first element of Cond, and the predicate 462 // operand as the second. 463 if (BadLB || Cond.size() != 2) 464 return; 465 // Only simple jump-conditional (with or without negation). 466 if (!TII->PredOpcodeHasJMP_c(Cond[0].getImm())) 467 return; 468 // Must go to the header. 469 if (TB != HB && FB != HB) 470 return; 471 assert(Cond[1].isReg() && "Unexpected Cond vector from analyzeBranch"); 472 // Expect a predicate register. 473 unsigned PR = Cond[1].getReg(); 474 assert(MRI->getRegClass(PR) == &Hexagon::PredRegsRegClass); 475 476 // Get the registers on which the loop controlling compare instruction 477 // depends. 478 unsigned CmpR1 = 0, CmpR2 = 0; 479 const MachineInstr *CmpI = MRI->getVRegDef(PR); 480 while (CmpI->getOpcode() == Hexagon::C2_not) 481 CmpI = MRI->getVRegDef(CmpI->getOperand(1).getReg()); 482 483 int Mask = 0, Val = 0; 484 bool OkCI = TII->analyzeCompare(*CmpI, CmpR1, CmpR2, Mask, Val); 485 if (!OkCI) 486 return; 487 // Eliminate non-double input registers. 488 if (CmpR1 && MRI->getRegClass(CmpR1) != DoubleRC) 489 CmpR1 = 0; 490 if (CmpR2 && MRI->getRegClass(CmpR2) != DoubleRC) 491 CmpR2 = 0; 492 if (!CmpR1 && !CmpR2) 493 return; 494 495 // Now examine the top of the loop: the phi nodes that could poten- 496 // tially define loop induction registers. The registers defined by 497 // such a phi node would be used in a 64-bit add, which then would 498 // be used in the loop compare instruction. 499 500 // Get the set of all double registers defined by phi nodes in the 501 // loop header. 502 typedef std::vector<unsigned> UVect; 503 UVect DP; 504 for (auto &MI : *HB) { 505 if (!MI.isPHI()) 506 break; 507 const MachineOperand &MD = MI.getOperand(0); 508 unsigned R = MD.getReg(); 509 if (MRI->getRegClass(R) == DoubleRC) 510 DP.push_back(R); 511 } 512 if (DP.empty()) 513 return; 514 515 auto NoIndOp = [this, CmpR1, CmpR2] (unsigned R) -> bool { 516 for (auto I = MRI->use_nodbg_begin(R), E = MRI->use_nodbg_end(); 517 I != E; ++I) { 518 const MachineInstr *UseI = I->getParent(); 519 if (UseI->getOpcode() != Hexagon::A2_addp) 520 continue; 521 // Get the output from the add. If it is one of the inputs to the 522 // loop-controlling compare instruction, then R is likely an induc- 523 // tion register. 524 unsigned T = UseI->getOperand(0).getReg(); 525 if (T == CmpR1 || T == CmpR2) 526 return false; 527 } 528 return true; 529 }; 530 UVect::iterator End = llvm::remove_if(DP, NoIndOp); 531 Rs.insert(DP.begin(), End); 532 Rs.insert(CmpR1); 533 Rs.insert(CmpR2); 534 535 DEBUG({ 536 dbgs() << "For loop at BB#" << HB->getNumber() << " ind regs: "; 537 dump_partition(dbgs(), Rs, *TRI); 538 dbgs() << '\n'; 539 }); 540 } 541 542 void HexagonSplitDoubleRegs::collectIndRegs(LoopRegMap &IRM) { 543 typedef std::vector<MachineLoop*> LoopVector; 544 LoopVector WorkQ; 545 546 for (auto I : *MLI) 547 WorkQ.push_back(I); 548 for (unsigned i = 0; i < WorkQ.size(); ++i) { 549 for (auto I : *WorkQ[i]) 550 WorkQ.push_back(I); 551 } 552 553 USet Rs; 554 for (unsigned i = 0, n = WorkQ.size(); i < n; ++i) { 555 MachineLoop *L = WorkQ[i]; 556 Rs.clear(); 557 collectIndRegsForLoop(L, Rs); 558 if (!Rs.empty()) 559 IRM.insert(std::make_pair(L, Rs)); 560 } 561 } 562 563 void HexagonSplitDoubleRegs::createHalfInstr(unsigned Opc, MachineInstr *MI, 564 const UUPairMap &PairMap, unsigned SubR) { 565 MachineBasicBlock &B = *MI->getParent(); 566 DebugLoc DL = MI->getDebugLoc(); 567 MachineInstr *NewI = BuildMI(B, MI, DL, TII->get(Opc)); 568 569 for (auto &Op : MI->operands()) { 570 if (!Op.isReg()) { 571 NewI->addOperand(Op); 572 continue; 573 } 574 // For register operands, set the subregister. 575 unsigned R = Op.getReg(); 576 unsigned SR = Op.getSubReg(); 577 bool isVirtReg = TargetRegisterInfo::isVirtualRegister(R); 578 bool isKill = Op.isKill(); 579 if (isVirtReg && MRI->getRegClass(R) == DoubleRC) { 580 isKill = false; 581 UUPairMap::const_iterator F = PairMap.find(R); 582 if (F == PairMap.end()) { 583 SR = SubR; 584 } else { 585 const UUPair &P = F->second; 586 R = (SubR == Hexagon::isub_lo) ? P.first : P.second; 587 SR = 0; 588 } 589 } 590 auto CO = MachineOperand::CreateReg(R, Op.isDef(), Op.isImplicit(), isKill, 591 Op.isDead(), Op.isUndef(), Op.isEarlyClobber(), SR, Op.isDebug(), 592 Op.isInternalRead()); 593 NewI->addOperand(CO); 594 } 595 } 596 597 void HexagonSplitDoubleRegs::splitMemRef(MachineInstr *MI, 598 const UUPairMap &PairMap) { 599 bool Load = MI->mayLoad(); 600 unsigned OrigOpc = MI->getOpcode(); 601 bool PostInc = (OrigOpc == Hexagon::L2_loadrd_pi || 602 OrigOpc == Hexagon::S2_storerd_pi); 603 MachineInstr *LowI, *HighI; 604 MachineBasicBlock &B = *MI->getParent(); 605 DebugLoc DL = MI->getDebugLoc(); 606 607 // Index of the base-address-register operand. 608 unsigned AdrX = PostInc ? (Load ? 2 : 1) 609 : (Load ? 1 : 0); 610 MachineOperand &AdrOp = MI->getOperand(AdrX); 611 unsigned RSA = getRegState(AdrOp); 612 MachineOperand &ValOp = Load ? MI->getOperand(0) 613 : (PostInc ? MI->getOperand(3) 614 : MI->getOperand(2)); 615 UUPairMap::const_iterator F = PairMap.find(ValOp.getReg()); 616 assert(F != PairMap.end()); 617 618 if (Load) { 619 const UUPair &P = F->second; 620 int64_t Off = PostInc ? 0 : MI->getOperand(2).getImm(); 621 LowI = BuildMI(B, MI, DL, TII->get(Hexagon::L2_loadri_io), P.first) 622 .addReg(AdrOp.getReg(), RSA & ~RegState::Kill, AdrOp.getSubReg()) 623 .addImm(Off); 624 HighI = BuildMI(B, MI, DL, TII->get(Hexagon::L2_loadri_io), P.second) 625 .addReg(AdrOp.getReg(), RSA & ~RegState::Kill, AdrOp.getSubReg()) 626 .addImm(Off+4); 627 } else { 628 const UUPair &P = F->second; 629 int64_t Off = PostInc ? 0 : MI->getOperand(1).getImm(); 630 LowI = BuildMI(B, MI, DL, TII->get(Hexagon::S2_storeri_io)) 631 .addReg(AdrOp.getReg(), RSA & ~RegState::Kill, AdrOp.getSubReg()) 632 .addImm(Off) 633 .addReg(P.first); 634 HighI = BuildMI(B, MI, DL, TII->get(Hexagon::S2_storeri_io)) 635 .addReg(AdrOp.getReg(), RSA & ~RegState::Kill, AdrOp.getSubReg()) 636 .addImm(Off+4) 637 .addReg(P.second); 638 } 639 640 if (PostInc) { 641 // Create the increment of the address register. 642 int64_t Inc = Load ? MI->getOperand(3).getImm() 643 : MI->getOperand(2).getImm(); 644 MachineOperand &UpdOp = Load ? MI->getOperand(1) : MI->getOperand(0); 645 const TargetRegisterClass *RC = MRI->getRegClass(UpdOp.getReg()); 646 unsigned NewR = MRI->createVirtualRegister(RC); 647 assert(!UpdOp.getSubReg() && "Def operand with subreg"); 648 BuildMI(B, MI, DL, TII->get(Hexagon::A2_addi), NewR) 649 .addReg(AdrOp.getReg(), RSA) 650 .addImm(Inc); 651 MRI->replaceRegWith(UpdOp.getReg(), NewR); 652 // The original instruction will be deleted later. 653 } 654 655 // Generate a new pair of memory-operands. 656 MachineFunction &MF = *B.getParent(); 657 for (auto &MO : MI->memoperands()) { 658 const MachinePointerInfo &Ptr = MO->getPointerInfo(); 659 MachineMemOperand::Flags F = MO->getFlags(); 660 int A = MO->getAlignment(); 661 662 auto *Tmp1 = MF.getMachineMemOperand(Ptr, F, 4/*size*/, A); 663 LowI->addMemOperand(MF, Tmp1); 664 auto *Tmp2 = MF.getMachineMemOperand(Ptr, F, 4/*size*/, std::min(A, 4)); 665 HighI->addMemOperand(MF, Tmp2); 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 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 void HexagonSplitDoubleRegs::splitExt(MachineInstr *MI, 729 const UUPairMap &PairMap) { 730 MachineOperand &Op0 = MI->getOperand(0); 731 MachineOperand &Op1 = MI->getOperand(1); 732 assert(Op0.isReg() && Op1.isReg()); 733 734 MachineBasicBlock &B = *MI->getParent(); 735 DebugLoc DL = MI->getDebugLoc(); 736 UUPairMap::const_iterator F = PairMap.find(Op0.getReg()); 737 assert(F != PairMap.end()); 738 const UUPair &P = F->second; 739 unsigned RS = getRegState(Op1); 740 741 BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), P.first) 742 .addReg(Op1.getReg(), RS & ~RegState::Kill, Op1.getSubReg()); 743 BuildMI(B, MI, DL, TII->get(Hexagon::S2_asr_i_r), P.second) 744 .addReg(Op1.getReg(), RS, Op1.getSubReg()) 745 .addImm(31); 746 } 747 748 void HexagonSplitDoubleRegs::splitShift(MachineInstr *MI, 749 const UUPairMap &PairMap) { 750 using namespace Hexagon; 751 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 766 unsigned Opc = MI->getOpcode(); 767 bool Right = (Opc == S2_lsr_i_p || Opc == S2_asr_i_p); 768 bool Left = !Right; 769 bool Signed = (Opc == S2_asr_i_p); 770 771 MachineBasicBlock &B = *MI->getParent(); 772 DebugLoc DL = MI->getDebugLoc(); 773 unsigned RS = getRegState(Op1); 774 unsigned ShiftOpc = Left ? S2_asl_i_r 775 : (Signed ? S2_asr_i_r : S2_lsr_i_r); 776 unsigned LoSR = isub_lo; 777 unsigned HiSR = isub_hi; 778 779 if (S == 0) { 780 // No shift, subregister copy. 781 BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), LoR) 782 .addReg(Op1.getReg(), RS & ~RegState::Kill, LoSR); 783 BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), HiR) 784 .addReg(Op1.getReg(), RS, HiSR); 785 } else if (S < 32) { 786 const TargetRegisterClass *IntRC = &IntRegsRegClass; 787 unsigned TmpR = MRI->createVirtualRegister(IntRC); 788 // Expansion: 789 // Shift left: DR = shl R, #s 790 // LoR = shl R.lo, #s 791 // TmpR = extractu R.lo, #s, #32-s 792 // HiR = or (TmpR, asl(R.hi, #s)) 793 // Shift right: DR = shr R, #s 794 // HiR = shr R.hi, #s 795 // TmpR = shr R.lo, #s 796 // LoR = insert TmpR, R.hi, #s, #32-s 797 798 // Shift left: 799 // LoR = shl R.lo, #s 800 // Shift right: 801 // TmpR = shr R.lo, #s 802 803 // Make a special case for A2_aslh and A2_asrh (they are predicable as 804 // opposed to S2_asl_i_r/S2_asr_i_r). 805 if (S == 16 && Left) 806 BuildMI(B, MI, DL, TII->get(A2_aslh), LoR) 807 .addReg(Op1.getReg(), RS & ~RegState::Kill, LoSR); 808 else if (S == 16 && Signed) 809 BuildMI(B, MI, DL, TII->get(A2_asrh), TmpR) 810 .addReg(Op1.getReg(), RS & ~RegState::Kill, LoSR); 811 else 812 BuildMI(B, MI, DL, TII->get(ShiftOpc), (Left ? LoR : TmpR)) 813 .addReg(Op1.getReg(), RS & ~RegState::Kill, LoSR) 814 .addImm(S); 815 816 if (Left) { 817 // TmpR = extractu R.lo, #s, #32-s 818 BuildMI(B, MI, DL, TII->get(S2_extractu), TmpR) 819 .addReg(Op1.getReg(), RS & ~RegState::Kill, LoSR) 820 .addImm(S) 821 .addImm(32-S); 822 // HiR = or (TmpR, asl(R.hi, #s)) 823 BuildMI(B, MI, DL, TII->get(S2_asl_i_r_or), HiR) 824 .addReg(TmpR) 825 .addReg(Op1.getReg(), RS, HiSR) 826 .addImm(S); 827 } else { 828 // HiR = shr R.hi, #s 829 BuildMI(B, MI, DL, TII->get(ShiftOpc), HiR) 830 .addReg(Op1.getReg(), RS & ~RegState::Kill, HiSR) 831 .addImm(S); 832 // LoR = insert TmpR, R.hi, #s, #32-s 833 BuildMI(B, MI, DL, TII->get(S2_insert), LoR) 834 .addReg(TmpR) 835 .addReg(Op1.getReg(), RS, HiSR) 836 .addImm(S) 837 .addImm(32-S); 838 } 839 } else if (S == 32) { 840 BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), (Left ? HiR : LoR)) 841 .addReg(Op1.getReg(), RS & ~RegState::Kill, (Left ? LoSR : HiSR)); 842 if (!Signed) 843 BuildMI(B, MI, DL, TII->get(A2_tfrsi), (Left ? LoR : HiR)) 844 .addImm(0); 845 else // Must be right shift. 846 BuildMI(B, MI, DL, TII->get(S2_asr_i_r), HiR) 847 .addReg(Op1.getReg(), RS, HiSR) 848 .addImm(31); 849 } else if (S < 64) { 850 S -= 32; 851 if (S == 16 && Left) 852 BuildMI(B, MI, DL, TII->get(A2_aslh), HiR) 853 .addReg(Op1.getReg(), RS & ~RegState::Kill, LoSR); 854 else if (S == 16 && Signed) 855 BuildMI(B, MI, DL, TII->get(A2_asrh), LoR) 856 .addReg(Op1.getReg(), RS & ~RegState::Kill, HiSR); 857 else 858 BuildMI(B, MI, DL, TII->get(ShiftOpc), (Left ? HiR : LoR)) 859 .addReg(Op1.getReg(), RS & ~RegState::Kill, (Left ? LoSR : HiSR)) 860 .addImm(S); 861 862 if (Signed) 863 BuildMI(B, MI, DL, TII->get(S2_asr_i_r), HiR) 864 .addReg(Op1.getReg(), RS, HiSR) 865 .addImm(31); 866 else 867 BuildMI(B, MI, DL, TII->get(A2_tfrsi), (Left ? LoR : HiR)) 868 .addImm(0); 869 } 870 } 871 872 void HexagonSplitDoubleRegs::splitAslOr(MachineInstr *MI, 873 const UUPairMap &PairMap) { 874 using namespace Hexagon; 875 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 891 MachineBasicBlock &B = *MI->getParent(); 892 DebugLoc DL = MI->getDebugLoc(); 893 unsigned RS1 = getRegState(Op1); 894 unsigned RS2 = getRegState(Op2); 895 const TargetRegisterClass *IntRC = &IntRegsRegClass; 896 897 unsigned LoSR = isub_lo; 898 unsigned HiSR = isub_hi; 899 900 // Op0 = S2_asl_i_p_or Op1, Op2, Op3 901 // means: Op0 = or (Op1, asl(Op2, Op3)) 902 903 // Expansion of 904 // DR = or (R1, asl(R2, #s)) 905 // 906 // LoR = or (R1.lo, asl(R2.lo, #s)) 907 // Tmp1 = extractu R2.lo, #s, #32-s 908 // Tmp2 = or R1.hi, Tmp1 909 // HiR = or (Tmp2, asl(R2.hi, #s)) 910 911 if (S == 0) { 912 // DR = or (R1, asl(R2, #0)) 913 // -> or (R1, R2) 914 // i.e. LoR = or R1.lo, R2.lo 915 // HiR = or R1.hi, R2.hi 916 BuildMI(B, MI, DL, TII->get(A2_or), LoR) 917 .addReg(Op1.getReg(), RS1 & ~RegState::Kill, LoSR) 918 .addReg(Op2.getReg(), RS2 & ~RegState::Kill, LoSR); 919 BuildMI(B, MI, DL, TII->get(A2_or), HiR) 920 .addReg(Op1.getReg(), RS1, HiSR) 921 .addReg(Op2.getReg(), RS2, HiSR); 922 } else if (S < 32) { 923 BuildMI(B, MI, DL, TII->get(S2_asl_i_r_or), LoR) 924 .addReg(Op1.getReg(), RS1 & ~RegState::Kill, LoSR) 925 .addReg(Op2.getReg(), RS2 & ~RegState::Kill, LoSR) 926 .addImm(S); 927 unsigned TmpR1 = MRI->createVirtualRegister(IntRC); 928 BuildMI(B, MI, DL, TII->get(S2_extractu), TmpR1) 929 .addReg(Op2.getReg(), RS2 & ~RegState::Kill, LoSR) 930 .addImm(S) 931 .addImm(32-S); 932 unsigned TmpR2 = MRI->createVirtualRegister(IntRC); 933 BuildMI(B, MI, DL, TII->get(A2_or), TmpR2) 934 .addReg(Op1.getReg(), RS1, HiSR) 935 .addReg(TmpR1); 936 BuildMI(B, MI, DL, TII->get(S2_asl_i_r_or), HiR) 937 .addReg(TmpR2) 938 .addReg(Op2.getReg(), RS2, HiSR) 939 .addImm(S); 940 } else if (S == 32) { 941 // DR = or (R1, asl(R2, #32)) 942 // -> or R1, R2.lo 943 // LoR = R1.lo 944 // HiR = or R1.hi, R2.lo 945 BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), LoR) 946 .addReg(Op1.getReg(), RS1 & ~RegState::Kill, LoSR); 947 BuildMI(B, MI, DL, TII->get(A2_or), HiR) 948 .addReg(Op1.getReg(), RS1, HiSR) 949 .addReg(Op2.getReg(), RS2, LoSR); 950 } else if (S < 64) { 951 // DR = or (R1, asl(R2, #s)) 952 // 953 // LoR = R1:lo 954 // HiR = or (R1:hi, asl(R2:lo, #s-32)) 955 S -= 32; 956 BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), LoR) 957 .addReg(Op1.getReg(), RS1 & ~RegState::Kill, LoSR); 958 BuildMI(B, MI, DL, TII->get(S2_asl_i_r_or), HiR) 959 .addReg(Op1.getReg(), RS1, HiSR) 960 .addReg(Op2.getReg(), RS2, LoSR) 961 .addImm(S); 962 } 963 } 964 965 bool HexagonSplitDoubleRegs::splitInstr(MachineInstr *MI, 966 const UUPairMap &PairMap) { 967 using namespace Hexagon; 968 969 DEBUG(dbgs() << "Splitting: " << *MI); 970 bool Split = false; 971 unsigned Opc = MI->getOpcode(); 972 973 switch (Opc) { 974 case TargetOpcode::PHI: 975 case TargetOpcode::COPY: { 976 unsigned DstR = MI->getOperand(0).getReg(); 977 if (MRI->getRegClass(DstR) == DoubleRC) { 978 createHalfInstr(Opc, MI, PairMap, isub_lo); 979 createHalfInstr(Opc, MI, PairMap, isub_hi); 980 Split = true; 981 } 982 break; 983 } 984 case A2_andp: 985 createHalfInstr(A2_and, MI, PairMap, isub_lo); 986 createHalfInstr(A2_and, MI, PairMap, isub_hi); 987 Split = true; 988 break; 989 case A2_orp: 990 createHalfInstr(A2_or, MI, PairMap, isub_lo); 991 createHalfInstr(A2_or, MI, PairMap, isub_hi); 992 Split = true; 993 break; 994 case A2_xorp: 995 createHalfInstr(A2_xor, MI, PairMap, isub_lo); 996 createHalfInstr(A2_xor, MI, PairMap, isub_hi); 997 Split = true; 998 break; 999 1000 case L2_loadrd_io: 1001 case L2_loadrd_pi: 1002 case S2_storerd_io: 1003 case S2_storerd_pi: 1004 splitMemRef(MI, PairMap); 1005 Split = true; 1006 break; 1007 1008 case A2_tfrpi: 1009 case CONST64: 1010 splitImmediate(MI, PairMap); 1011 Split = true; 1012 break; 1013 1014 case A2_combineii: 1015 case A4_combineir: 1016 case A4_combineii: 1017 case A4_combineri: 1018 case A2_combinew: 1019 splitCombine(MI, PairMap); 1020 Split = true; 1021 break; 1022 1023 case A2_sxtw: 1024 splitExt(MI, PairMap); 1025 Split = true; 1026 break; 1027 1028 case S2_asl_i_p: 1029 case S2_asr_i_p: 1030 case S2_lsr_i_p: 1031 splitShift(MI, PairMap); 1032 Split = true; 1033 break; 1034 1035 case S2_asl_i_p_or: 1036 splitAslOr(MI, PairMap); 1037 Split = true; 1038 break; 1039 1040 default: 1041 llvm_unreachable("Instruction not splitable"); 1042 return false; 1043 } 1044 1045 return Split; 1046 } 1047 1048 void HexagonSplitDoubleRegs::replaceSubregUses(MachineInstr *MI, 1049 const UUPairMap &PairMap) { 1050 for (auto &Op : MI->operands()) { 1051 if (!Op.isReg() || !Op.isUse() || !Op.getSubReg()) 1052 continue; 1053 unsigned R = Op.getReg(); 1054 UUPairMap::const_iterator F = PairMap.find(R); 1055 if (F == PairMap.end()) 1056 continue; 1057 const UUPair &P = F->second; 1058 switch (Op.getSubReg()) { 1059 case Hexagon::isub_lo: 1060 Op.setReg(P.first); 1061 break; 1062 case Hexagon::isub_hi: 1063 Op.setReg(P.second); 1064 break; 1065 } 1066 Op.setSubReg(0); 1067 } 1068 } 1069 1070 void HexagonSplitDoubleRegs::collapseRegPairs(MachineInstr *MI, 1071 const UUPairMap &PairMap) { 1072 MachineBasicBlock &B = *MI->getParent(); 1073 DebugLoc DL = MI->getDebugLoc(); 1074 1075 for (auto &Op : MI->operands()) { 1076 if (!Op.isReg() || !Op.isUse()) 1077 continue; 1078 unsigned R = Op.getReg(); 1079 if (!TargetRegisterInfo::isVirtualRegister(R)) 1080 continue; 1081 if (MRI->getRegClass(R) != DoubleRC || Op.getSubReg()) 1082 continue; 1083 UUPairMap::const_iterator F = PairMap.find(R); 1084 if (F == PairMap.end()) 1085 continue; 1086 const UUPair &Pr = F->second; 1087 unsigned NewDR = MRI->createVirtualRegister(DoubleRC); 1088 BuildMI(B, MI, DL, TII->get(TargetOpcode::REG_SEQUENCE), NewDR) 1089 .addReg(Pr.first) 1090 .addImm(Hexagon::isub_lo) 1091 .addReg(Pr.second) 1092 .addImm(Hexagon::isub_hi); 1093 Op.setReg(NewDR); 1094 } 1095 } 1096 1097 bool HexagonSplitDoubleRegs::splitPartition(const USet &Part) { 1098 const TargetRegisterClass *IntRC = &Hexagon::IntRegsRegClass; 1099 typedef std::set<MachineInstr*> MISet; 1100 bool Changed = false; 1101 1102 DEBUG(dbgs() << "Splitting partition: "; dump_partition(dbgs(), Part, *TRI); 1103 dbgs() << '\n'); 1104 1105 UUPairMap PairMap; 1106 1107 MISet SplitIns; 1108 for (unsigned DR : Part) { 1109 MachineInstr *DefI = MRI->getVRegDef(DR); 1110 SplitIns.insert(DefI); 1111 1112 // Collect all instructions, including fixed ones. We won't split them, 1113 // but we need to visit them again to insert the REG_SEQUENCE instructions. 1114 for (auto U = MRI->use_nodbg_begin(DR), W = MRI->use_nodbg_end(); 1115 U != W; ++U) 1116 SplitIns.insert(U->getParent()); 1117 1118 unsigned LoR = MRI->createVirtualRegister(IntRC); 1119 unsigned HiR = MRI->createVirtualRegister(IntRC); 1120 DEBUG(dbgs() << "Created mapping: " << PrintReg(DR, TRI) << " -> " 1121 << PrintReg(HiR, TRI) << ':' << PrintReg(LoR, TRI) << '\n'); 1122 PairMap.insert(std::make_pair(DR, UUPair(LoR, HiR))); 1123 } 1124 1125 MISet Erase; 1126 for (auto MI : SplitIns) { 1127 if (isFixedInstr(MI)) { 1128 collapseRegPairs(MI, PairMap); 1129 } else { 1130 bool Done = splitInstr(MI, PairMap); 1131 if (Done) 1132 Erase.insert(MI); 1133 Changed |= Done; 1134 } 1135 } 1136 1137 for (unsigned DR : Part) { 1138 // Before erasing "double" instructions, revisit all uses of the double 1139 // registers in this partition, and replace all uses of them with subre- 1140 // gisters, with the corresponding single registers. 1141 MISet Uses; 1142 for (auto U = MRI->use_nodbg_begin(DR), W = MRI->use_nodbg_end(); 1143 U != W; ++U) 1144 Uses.insert(U->getParent()); 1145 for (auto M : Uses) 1146 replaceSubregUses(M, PairMap); 1147 } 1148 1149 for (auto MI : Erase) { 1150 MachineBasicBlock *B = MI->getParent(); 1151 B->erase(MI); 1152 } 1153 1154 return Changed; 1155 } 1156 1157 bool HexagonSplitDoubleRegs::runOnMachineFunction(MachineFunction &MF) { 1158 DEBUG(dbgs() << "Splitting double registers in function: " 1159 << MF.getName() << '\n'); 1160 1161 if (skipFunction(*MF.getFunction())) 1162 return false; 1163 1164 auto &ST = MF.getSubtarget<HexagonSubtarget>(); 1165 TRI = ST.getRegisterInfo(); 1166 TII = ST.getInstrInfo(); 1167 MRI = &MF.getRegInfo(); 1168 MLI = &getAnalysis<MachineLoopInfo>(); 1169 1170 UUSetMap P2Rs; 1171 LoopRegMap IRM; 1172 1173 collectIndRegs(IRM); 1174 partitionRegisters(P2Rs); 1175 1176 DEBUG({ 1177 dbgs() << "Register partitioning: (partition #0 is fixed)\n"; 1178 for (UUSetMap::iterator I = P2Rs.begin(), E = P2Rs.end(); I != E; ++I) { 1179 dbgs() << '#' << I->first << " -> "; 1180 dump_partition(dbgs(), I->second, *TRI); 1181 dbgs() << '\n'; 1182 } 1183 }); 1184 1185 bool Changed = false; 1186 int Limit = MaxHSDR; 1187 1188 for (UUSetMap::iterator I = P2Rs.begin(), E = P2Rs.end(); I != E; ++I) { 1189 if (I->first == 0) 1190 continue; 1191 if (Limit >= 0 && Counter >= Limit) 1192 break; 1193 USet &Part = I->second; 1194 DEBUG(dbgs() << "Calculating profit for partition #" << I->first << '\n'); 1195 if (!isProfitable(Part, IRM)) 1196 continue; 1197 Counter++; 1198 Changed |= splitPartition(Part); 1199 } 1200 1201 return Changed; 1202 } 1203 1204 FunctionPass *llvm::createHexagonSplitDoubleRegs() { 1205 return new HexagonSplitDoubleRegs(); 1206 } 1207