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