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