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