1 //=== A15SDOptimizerPass.cpp - Optimize DPR and SPR register accesses on A15==// 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 // The Cortex-A15 processor employs a tracking scheme in its register renaming 11 // in order to process each instruction's micro-ops speculatively and 12 // out-of-order with appropriate forwarding. The ARM architecture allows VFP 13 // instructions to read and write 32-bit S-registers. Each S-register 14 // corresponds to one half (upper or lower) of an overlaid 64-bit D-register. 15 // 16 // There are several instruction patterns which can be used to provide this 17 // capability which can provide higher performance than other, potentially more 18 // direct patterns, specifically around when one micro-op reads a D-register 19 // operand that has recently been written as one or more S-register results. 20 // 21 // This file defines a pre-regalloc pass which looks for SPR producers which 22 // are going to be used by a DPR (or QPR) consumers and creates the more 23 // optimized access pattern. 24 // 25 //===----------------------------------------------------------------------===// 26 27 #define DEBUG_TYPE "a15-sd-optimizer" 28 #include "ARM.h" 29 #include "ARMBaseInstrInfo.h" 30 #include "ARMISelLowering.h" 31 #include "ARMSubtarget.h" 32 #include "ARMTargetMachine.h" 33 #include "llvm/ADT/SmallPtrSet.h" 34 #include "llvm/ADT/Statistic.h" 35 #include "llvm/CodeGen/MachineFunctionPass.h" 36 #include "llvm/CodeGen/MachineInstr.h" 37 #include "llvm/CodeGen/MachineInstrBuilder.h" 38 #include "llvm/CodeGen/MachineRegisterInfo.h" 39 #include "llvm/Support/CommandLine.h" 40 #include "llvm/Support/Debug.h" 41 #include "llvm/Support/raw_ostream.h" 42 #include "llvm/Target/TargetRegisterInfo.h" 43 #include <set> 44 45 using namespace llvm; 46 47 namespace { 48 struct A15SDOptimizer : public MachineFunctionPass { 49 static char ID; 50 A15SDOptimizer() : MachineFunctionPass(ID) {} 51 52 virtual bool runOnMachineFunction(MachineFunction &Fn); 53 54 virtual const char *getPassName() const { 55 return "ARM A15 S->D optimizer"; 56 } 57 58 private: 59 const ARMBaseInstrInfo *TII; 60 const TargetRegisterInfo *TRI; 61 MachineRegisterInfo *MRI; 62 63 bool runOnInstruction(MachineInstr *MI); 64 65 // 66 // Instruction builder helpers 67 // 68 unsigned createDupLane(MachineBasicBlock &MBB, 69 MachineBasicBlock::iterator InsertBefore, 70 DebugLoc DL, 71 unsigned Reg, unsigned Lane, 72 bool QPR=false); 73 74 unsigned createExtractSubreg(MachineBasicBlock &MBB, 75 MachineBasicBlock::iterator InsertBefore, 76 DebugLoc DL, 77 unsigned DReg, unsigned Lane, 78 const TargetRegisterClass *TRC); 79 80 unsigned createVExt(MachineBasicBlock &MBB, 81 MachineBasicBlock::iterator InsertBefore, 82 DebugLoc DL, 83 unsigned Ssub0, unsigned Ssub1); 84 85 unsigned createRegSequence(MachineBasicBlock &MBB, 86 MachineBasicBlock::iterator InsertBefore, 87 DebugLoc DL, 88 unsigned Reg1, unsigned Reg2); 89 90 unsigned createInsertSubreg(MachineBasicBlock &MBB, 91 MachineBasicBlock::iterator InsertBefore, 92 DebugLoc DL, unsigned DReg, unsigned Lane, 93 unsigned ToInsert); 94 95 unsigned createImplicitDef(MachineBasicBlock &MBB, 96 MachineBasicBlock::iterator InsertBefore, 97 DebugLoc DL); 98 99 // 100 // Various property checkers 101 // 102 bool usesRegClass(MachineOperand &MO, const TargetRegisterClass *TRC); 103 bool hasPartialWrite(MachineInstr *MI); 104 SmallVector<unsigned, 8> getReadDPRs(MachineInstr *MI); 105 unsigned getDPRLaneFromSPR(unsigned SReg); 106 107 // 108 // Methods used for getting the definitions of partial registers 109 // 110 111 MachineInstr *elideCopies(MachineInstr *MI); 112 void elideCopiesAndPHIs(MachineInstr *MI, 113 SmallVectorImpl<MachineInstr*> &Outs); 114 115 // 116 // Pattern optimization methods 117 // 118 unsigned optimizeAllLanesPattern(MachineInstr *MI, unsigned Reg); 119 unsigned optimizeSDPattern(MachineInstr *MI); 120 unsigned getPrefSPRLane(unsigned SReg); 121 122 // 123 // Sanitizing method - used to make sure if don't leave dead code around. 124 // 125 void eraseInstrWithNoUses(MachineInstr *MI); 126 127 // 128 // A map used to track the changes done by this pass. 129 // 130 std::map<MachineInstr*, unsigned> Replacements; 131 std::set<MachineInstr *> DeadInstr; 132 }; 133 char A15SDOptimizer::ID = 0; 134 } // end anonymous namespace 135 136 // Returns true if this is a use of a SPR register. 137 bool A15SDOptimizer::usesRegClass(MachineOperand &MO, 138 const TargetRegisterClass *TRC) { 139 if (!MO.isReg()) 140 return false; 141 unsigned Reg = MO.getReg(); 142 143 if (TargetRegisterInfo::isVirtualRegister(Reg)) 144 return MRI->getRegClass(Reg)->hasSuperClassEq(TRC); 145 else 146 return TRC->contains(Reg); 147 } 148 149 unsigned A15SDOptimizer::getDPRLaneFromSPR(unsigned SReg) { 150 unsigned DReg = TRI->getMatchingSuperReg(SReg, ARM::ssub_1, 151 &ARM::DPRRegClass); 152 if (DReg != ARM::NoRegister) return ARM::ssub_1; 153 return ARM::ssub_0; 154 } 155 156 // Get the subreg type that is most likely to be coalesced 157 // for an SPR register that will be used in VDUP32d pseudo. 158 unsigned A15SDOptimizer::getPrefSPRLane(unsigned SReg) { 159 if (!TRI->isVirtualRegister(SReg)) 160 return getDPRLaneFromSPR(SReg); 161 162 MachineInstr *MI = MRI->getVRegDef(SReg); 163 if (!MI) return ARM::ssub_0; 164 MachineOperand *MO = MI->findRegisterDefOperand(SReg); 165 166 assert(MO->isReg() && "Non-register operand found!"); 167 if (!MO) return ARM::ssub_0; 168 169 if (MI->isCopy() && usesRegClass(MI->getOperand(1), 170 &ARM::SPRRegClass)) { 171 SReg = MI->getOperand(1).getReg(); 172 } 173 174 if (TargetRegisterInfo::isVirtualRegister(SReg)) { 175 if (MO->getSubReg() == ARM::ssub_1) return ARM::ssub_1; 176 return ARM::ssub_0; 177 } 178 return getDPRLaneFromSPR(SReg); 179 } 180 181 // MI is known to be dead. Figure out what instructions 182 // are also made dead by this and mark them for removal. 183 void A15SDOptimizer::eraseInstrWithNoUses(MachineInstr *MI) { 184 SmallVector<MachineInstr *, 8> Front; 185 DeadInstr.insert(MI); 186 187 DEBUG(dbgs() << "Deleting base instruction " << *MI << "\n"); 188 Front.push_back(MI); 189 190 while (Front.size() != 0) { 191 MI = Front.back(); 192 Front.pop_back(); 193 194 // MI is already known to be dead. We need to see 195 // if other instructions can also be removed. 196 for (unsigned int i = 0; i < MI->getNumOperands(); ++i) { 197 MachineOperand &MO = MI->getOperand(i); 198 if ((!MO.isReg()) || (!MO.isUse())) 199 continue; 200 unsigned Reg = MO.getReg(); 201 if (!TRI->isVirtualRegister(Reg)) 202 continue; 203 MachineOperand *Op = MI->findRegisterDefOperand(Reg); 204 205 if (!Op) 206 continue; 207 208 MachineInstr *Def = Op->getParent(); 209 210 // We don't need to do anything if we have already marked 211 // this instruction as being dead. 212 if (DeadInstr.find(Def) != DeadInstr.end()) 213 continue; 214 215 // Check if all the uses of this instruction are marked as 216 // dead. If so, we can also mark this instruction as being 217 // dead. 218 bool IsDead = true; 219 for (unsigned int j = 0; j < Def->getNumOperands(); ++j) { 220 MachineOperand &MODef = Def->getOperand(j); 221 if ((!MODef.isReg()) || (!MODef.isDef())) 222 continue; 223 unsigned DefReg = MODef.getReg(); 224 if (!TRI->isVirtualRegister(DefReg)) { 225 IsDead = false; 226 break; 227 } 228 for (MachineRegisterInfo::use_iterator II = MRI->use_begin(Reg), 229 EE = MRI->use_end(); 230 II != EE; ++II) { 231 // We don't care about self references. 232 if (&*II == Def) 233 continue; 234 if (DeadInstr.find(&*II) == DeadInstr.end()) { 235 IsDead = false; 236 break; 237 } 238 } 239 } 240 241 if (!IsDead) continue; 242 243 DEBUG(dbgs() << "Deleting instruction " << *Def << "\n"); 244 DeadInstr.insert(Def); 245 } 246 } 247 } 248 249 // Creates the more optimized patterns and generally does all the code 250 // transformations in this pass. 251 unsigned A15SDOptimizer::optimizeSDPattern(MachineInstr *MI) { 252 if (MI->isCopy()) { 253 return optimizeAllLanesPattern(MI, MI->getOperand(1).getReg()); 254 } 255 256 if (MI->isInsertSubreg()) { 257 unsigned DPRReg = MI->getOperand(1).getReg(); 258 unsigned SPRReg = MI->getOperand(2).getReg(); 259 260 if (TRI->isVirtualRegister(DPRReg) && TRI->isVirtualRegister(SPRReg)) { 261 MachineInstr *DPRMI = MRI->getVRegDef(MI->getOperand(1).getReg()); 262 MachineInstr *SPRMI = MRI->getVRegDef(MI->getOperand(2).getReg()); 263 264 if (DPRMI && SPRMI) { 265 // See if the first operand of this insert_subreg is IMPLICIT_DEF 266 MachineInstr *ECDef = elideCopies(DPRMI); 267 if (ECDef != 0 && ECDef->isImplicitDef()) { 268 // Another corner case - if we're inserting something that is purely 269 // a subreg copy of a DPR, just use that DPR. 270 271 MachineInstr *EC = elideCopies(SPRMI); 272 // Is it a subreg copy of ssub_0? 273 if (EC && EC->isCopy() && 274 EC->getOperand(1).getSubReg() == ARM::ssub_0) { 275 DEBUG(dbgs() << "Found a subreg copy: " << *SPRMI); 276 277 // Find the thing we're subreg copying out of - is it of the same 278 // regclass as DPRMI? (i.e. a DPR or QPR). 279 unsigned FullReg = SPRMI->getOperand(1).getReg(); 280 const TargetRegisterClass *TRC = 281 MRI->getRegClass(MI->getOperand(1).getReg()); 282 if (TRC->hasSuperClassEq(MRI->getRegClass(FullReg))) { 283 DEBUG(dbgs() << "Subreg copy is compatible - returning "); 284 DEBUG(dbgs() << PrintReg(FullReg) << "\n"); 285 eraseInstrWithNoUses(MI); 286 return FullReg; 287 } 288 } 289 290 return optimizeAllLanesPattern(MI, MI->getOperand(2).getReg()); 291 } 292 } 293 } 294 return optimizeAllLanesPattern(MI, MI->getOperand(0).getReg()); 295 } 296 297 if (MI->isRegSequence() && usesRegClass(MI->getOperand(1), 298 &ARM::SPRRegClass)) { 299 // See if all bar one of the operands are IMPLICIT_DEF and insert the 300 // optimizer pattern accordingly. 301 unsigned NumImplicit = 0, NumTotal = 0; 302 unsigned NonImplicitReg = ~0U; 303 304 for (unsigned I = 1; I < MI->getNumExplicitOperands(); ++I) { 305 if (!MI->getOperand(I).isReg()) 306 continue; 307 ++NumTotal; 308 unsigned OpReg = MI->getOperand(I).getReg(); 309 310 if (!TRI->isVirtualRegister(OpReg)) 311 break; 312 313 MachineInstr *Def = MRI->getVRegDef(OpReg); 314 if (!Def) 315 break; 316 if (Def->isImplicitDef()) 317 ++NumImplicit; 318 else 319 NonImplicitReg = MI->getOperand(I).getReg(); 320 } 321 322 if (NumImplicit == NumTotal - 1) 323 return optimizeAllLanesPattern(MI, NonImplicitReg); 324 else 325 return optimizeAllLanesPattern(MI, MI->getOperand(0).getReg()); 326 } 327 328 assert(0 && "Unhandled update pattern!"); 329 return 0; 330 } 331 332 // Return true if this MachineInstr inserts a scalar (SPR) value into 333 // a D or Q register. 334 bool A15SDOptimizer::hasPartialWrite(MachineInstr *MI) { 335 // The only way we can do a partial register update is through a COPY, 336 // INSERT_SUBREG or REG_SEQUENCE. 337 if (MI->isCopy() && usesRegClass(MI->getOperand(1), &ARM::SPRRegClass)) 338 return true; 339 340 if (MI->isInsertSubreg() && usesRegClass(MI->getOperand(2), 341 &ARM::SPRRegClass)) 342 return true; 343 344 if (MI->isRegSequence() && usesRegClass(MI->getOperand(1), &ARM::SPRRegClass)) 345 return true; 346 347 return false; 348 } 349 350 // Looks through full copies to get the instruction that defines the input 351 // operand for MI. 352 MachineInstr *A15SDOptimizer::elideCopies(MachineInstr *MI) { 353 if (!MI->isFullCopy()) 354 return MI; 355 if (!TRI->isVirtualRegister(MI->getOperand(1).getReg())) 356 return NULL; 357 MachineInstr *Def = MRI->getVRegDef(MI->getOperand(1).getReg()); 358 if (!Def) 359 return NULL; 360 return elideCopies(Def); 361 } 362 363 // Look through full copies and PHIs to get the set of non-copy MachineInstrs 364 // that can produce MI. 365 void A15SDOptimizer::elideCopiesAndPHIs(MachineInstr *MI, 366 SmallVectorImpl<MachineInstr*> &Outs) { 367 // Looking through PHIs may create loops so we need to track what 368 // instructions we have visited before. 369 std::set<MachineInstr *> Reached; 370 SmallVector<MachineInstr *, 8> Front; 371 Front.push_back(MI); 372 while (Front.size() != 0) { 373 MI = Front.back(); 374 Front.pop_back(); 375 376 // If we have already explored this MachineInstr, ignore it. 377 if (Reached.find(MI) != Reached.end()) 378 continue; 379 Reached.insert(MI); 380 if (MI->isPHI()) { 381 for (unsigned I = 1, E = MI->getNumOperands(); I != E; I += 2) { 382 unsigned Reg = MI->getOperand(I).getReg(); 383 if (!TRI->isVirtualRegister(Reg)) { 384 continue; 385 } 386 MachineInstr *NewMI = MRI->getVRegDef(Reg); 387 if (!NewMI) 388 continue; 389 Front.push_back(NewMI); 390 } 391 } else if (MI->isFullCopy()) { 392 if (!TRI->isVirtualRegister(MI->getOperand(1).getReg())) 393 continue; 394 MachineInstr *NewMI = MRI->getVRegDef(MI->getOperand(1).getReg()); 395 if (!NewMI) 396 continue; 397 Front.push_back(NewMI); 398 } else { 399 DEBUG(dbgs() << "Found partial copy" << *MI <<"\n"); 400 Outs.push_back(MI); 401 } 402 } 403 } 404 405 // Return the DPR virtual registers that are read by this machine instruction 406 // (if any). 407 SmallVector<unsigned, 8> A15SDOptimizer::getReadDPRs(MachineInstr *MI) { 408 if (MI->isCopyLike() || MI->isInsertSubreg() || MI->isRegSequence() || 409 MI->isKill()) 410 return SmallVector<unsigned, 8>(); 411 412 SmallVector<unsigned, 8> Defs; 413 for (unsigned i = 0; i < MI->getNumOperands(); ++i) { 414 MachineOperand &MO = MI->getOperand(i); 415 416 if (!MO.isReg() || !MO.isUse()) 417 continue; 418 if (!usesRegClass(MO, &ARM::DPRRegClass) && 419 !usesRegClass(MO, &ARM::QPRRegClass)) 420 continue; 421 422 Defs.push_back(MO.getReg()); 423 } 424 return Defs; 425 } 426 427 // Creates a DPR register from an SPR one by using a VDUP. 428 unsigned 429 A15SDOptimizer::createDupLane(MachineBasicBlock &MBB, 430 MachineBasicBlock::iterator InsertBefore, 431 DebugLoc DL, 432 unsigned Reg, unsigned Lane, bool QPR) { 433 unsigned Out = MRI->createVirtualRegister(QPR ? &ARM::QPRRegClass : 434 &ARM::DPRRegClass); 435 AddDefaultPred(BuildMI(MBB, 436 InsertBefore, 437 DL, 438 TII->get(QPR ? ARM::VDUPLN32q : ARM::VDUPLN32d), 439 Out) 440 .addReg(Reg) 441 .addImm(Lane)); 442 443 return Out; 444 } 445 446 // Creates a SPR register from a DPR by copying the value in lane 0. 447 unsigned 448 A15SDOptimizer::createExtractSubreg(MachineBasicBlock &MBB, 449 MachineBasicBlock::iterator InsertBefore, 450 DebugLoc DL, 451 unsigned DReg, unsigned Lane, 452 const TargetRegisterClass *TRC) { 453 unsigned Out = MRI->createVirtualRegister(TRC); 454 BuildMI(MBB, 455 InsertBefore, 456 DL, 457 TII->get(TargetOpcode::COPY), Out) 458 .addReg(DReg, 0, Lane); 459 460 return Out; 461 } 462 463 // Takes two SPR registers and creates a DPR by using a REG_SEQUENCE. 464 unsigned 465 A15SDOptimizer::createRegSequence(MachineBasicBlock &MBB, 466 MachineBasicBlock::iterator InsertBefore, 467 DebugLoc DL, 468 unsigned Reg1, unsigned Reg2) { 469 unsigned Out = MRI->createVirtualRegister(&ARM::QPRRegClass); 470 BuildMI(MBB, 471 InsertBefore, 472 DL, 473 TII->get(TargetOpcode::REG_SEQUENCE), Out) 474 .addReg(Reg1) 475 .addImm(ARM::dsub_0) 476 .addReg(Reg2) 477 .addImm(ARM::dsub_1); 478 return Out; 479 } 480 481 // Takes two DPR registers that have previously been VDUPed (Ssub0 and Ssub1) 482 // and merges them into one DPR register. 483 unsigned 484 A15SDOptimizer::createVExt(MachineBasicBlock &MBB, 485 MachineBasicBlock::iterator InsertBefore, 486 DebugLoc DL, 487 unsigned Ssub0, unsigned Ssub1) { 488 unsigned Out = MRI->createVirtualRegister(&ARM::DPRRegClass); 489 AddDefaultPred(BuildMI(MBB, 490 InsertBefore, 491 DL, 492 TII->get(ARM::VEXTd32), Out) 493 .addReg(Ssub0) 494 .addReg(Ssub1) 495 .addImm(1)); 496 return Out; 497 } 498 499 unsigned 500 A15SDOptimizer::createInsertSubreg(MachineBasicBlock &MBB, 501 MachineBasicBlock::iterator InsertBefore, 502 DebugLoc DL, unsigned DReg, unsigned Lane, 503 unsigned ToInsert) { 504 unsigned Out = MRI->createVirtualRegister(&ARM::DPR_VFP2RegClass); 505 BuildMI(MBB, 506 InsertBefore, 507 DL, 508 TII->get(TargetOpcode::INSERT_SUBREG), Out) 509 .addReg(DReg) 510 .addReg(ToInsert) 511 .addImm(Lane); 512 513 return Out; 514 } 515 516 unsigned 517 A15SDOptimizer::createImplicitDef(MachineBasicBlock &MBB, 518 MachineBasicBlock::iterator InsertBefore, 519 DebugLoc DL) { 520 unsigned Out = MRI->createVirtualRegister(&ARM::DPRRegClass); 521 BuildMI(MBB, 522 InsertBefore, 523 DL, 524 TII->get(TargetOpcode::IMPLICIT_DEF), Out); 525 return Out; 526 } 527 528 // This function inserts instructions in order to optimize interactions between 529 // SPR registers and DPR/QPR registers. It does so by performing VDUPs on all 530 // lanes, and the using VEXT instructions to recompose the result. 531 unsigned 532 A15SDOptimizer::optimizeAllLanesPattern(MachineInstr *MI, unsigned Reg) { 533 MachineBasicBlock::iterator InsertPt(MI); 534 DebugLoc DL = MI->getDebugLoc(); 535 MachineBasicBlock &MBB = *MI->getParent(); 536 InsertPt++; 537 unsigned Out; 538 539 if (MRI->getRegClass(Reg)->hasSuperClassEq(&ARM::QPRRegClass)) { 540 unsigned DSub0 = createExtractSubreg(MBB, InsertPt, DL, Reg, 541 ARM::dsub_0, &ARM::DPRRegClass); 542 unsigned DSub1 = createExtractSubreg(MBB, InsertPt, DL, Reg, 543 ARM::dsub_1, &ARM::DPRRegClass); 544 545 unsigned Out1 = createDupLane(MBB, InsertPt, DL, DSub0, 0); 546 unsigned Out2 = createDupLane(MBB, InsertPt, DL, DSub0, 1); 547 Out = createVExt(MBB, InsertPt, DL, Out1, Out2); 548 549 unsigned Out3 = createDupLane(MBB, InsertPt, DL, DSub1, 0); 550 unsigned Out4 = createDupLane(MBB, InsertPt, DL, DSub1, 1); 551 Out2 = createVExt(MBB, InsertPt, DL, Out3, Out4); 552 553 Out = createRegSequence(MBB, InsertPt, DL, Out, Out2); 554 555 } else if (MRI->getRegClass(Reg)->hasSuperClassEq(&ARM::DPRRegClass)) { 556 unsigned Out1 = createDupLane(MBB, InsertPt, DL, Reg, 0); 557 unsigned Out2 = createDupLane(MBB, InsertPt, DL, Reg, 1); 558 Out = createVExt(MBB, InsertPt, DL, Out1, Out2); 559 560 } else { 561 assert(MRI->getRegClass(Reg)->hasSuperClassEq(&ARM::SPRRegClass) && 562 "Found unexpected regclass!"); 563 564 unsigned PrefLane = getPrefSPRLane(Reg); 565 unsigned Lane; 566 switch (PrefLane) { 567 case ARM::ssub_0: Lane = 0; break; 568 case ARM::ssub_1: Lane = 1; break; 569 default: llvm_unreachable("Unknown preferred lane!"); 570 } 571 572 bool UsesQPR = usesRegClass(MI->getOperand(0), &ARM::QPRRegClass); 573 574 Out = createImplicitDef(MBB, InsertPt, DL); 575 Out = createInsertSubreg(MBB, InsertPt, DL, Out, PrefLane, Reg); 576 Out = createDupLane(MBB, InsertPt, DL, Out, Lane, UsesQPR); 577 eraseInstrWithNoUses(MI); 578 } 579 return Out; 580 } 581 582 bool A15SDOptimizer::runOnInstruction(MachineInstr *MI) { 583 // We look for instructions that write S registers that are then read as 584 // D/Q registers. These can only be caused by COPY, INSERT_SUBREG and 585 // REG_SEQUENCE pseudos that insert an SPR value into a DPR register or 586 // merge two SPR values to form a DPR register. In order avoid false 587 // positives we make sure that there is an SPR producer so we look past 588 // COPY and PHI nodes to find it. 589 // 590 // The best code pattern for when an SPR producer is going to be used by a 591 // DPR or QPR consumer depends on whether the other lanes of the 592 // corresponding DPR/QPR are currently defined. 593 // 594 // We can handle these efficiently, depending on the type of 595 // pseudo-instruction that is producing the pattern 596 // 597 // * COPY: * VDUP all lanes and merge the results together 598 // using VEXTs. 599 // 600 // * INSERT_SUBREG: * If the SPR value was originally in another DPR/QPR 601 // lane, and the other lane(s) of the DPR/QPR register 602 // that we are inserting in are undefined, use the 603 // original DPR/QPR value. 604 // * Otherwise, fall back on the same stategy as COPY. 605 // 606 // * REG_SEQUENCE: * If all except one of the input operands are 607 // IMPLICIT_DEFs, insert the VDUP pattern for just the 608 // defined input operand 609 // * Otherwise, fall back on the same stategy as COPY. 610 // 611 612 // First, get all the reads of D-registers done by this instruction. 613 SmallVector<unsigned, 8> Defs = getReadDPRs(MI); 614 bool Modified = false; 615 616 for (SmallVectorImpl<unsigned>::iterator I = Defs.begin(), E = Defs.end(); 617 I != E; ++I) { 618 // Follow the def-use chain for this DPR through COPYs, and also through 619 // PHIs (which are essentially multi-way COPYs). It is because of PHIs that 620 // we can end up with multiple defs of this DPR. 621 622 SmallVector<MachineInstr *, 8> DefSrcs; 623 if (!TRI->isVirtualRegister(*I)) 624 continue; 625 MachineInstr *Def = MRI->getVRegDef(*I); 626 if (!Def) 627 continue; 628 629 elideCopiesAndPHIs(Def, DefSrcs); 630 631 for (SmallVectorImpl<MachineInstr *>::iterator II = DefSrcs.begin(), 632 EE = DefSrcs.end(); II != EE; ++II) { 633 MachineInstr *MI = *II; 634 635 // If we've already analyzed and replaced this operand, don't do 636 // anything. 637 if (Replacements.find(MI) != Replacements.end()) 638 continue; 639 640 // Now, work out if the instruction causes a SPR->DPR dependency. 641 if (!hasPartialWrite(MI)) 642 continue; 643 644 // Collect all the uses of this MI's DPR def for updating later. 645 SmallVector<MachineOperand*, 8> Uses; 646 unsigned DPRDefReg = MI->getOperand(0).getReg(); 647 for (MachineRegisterInfo::use_iterator I = MRI->use_begin(DPRDefReg), 648 E = MRI->use_end(); I != E; ++I) 649 Uses.push_back(&I.getOperand()); 650 651 // We can optimize this. 652 unsigned NewReg = optimizeSDPattern(MI); 653 654 if (NewReg != 0) { 655 Modified = true; 656 for (SmallVectorImpl<MachineOperand *>::const_iterator I = Uses.begin(), 657 E = Uses.end(); I != E; ++I) { 658 // Make sure to constrain the register class of the new register to 659 // match what we're replacing. Otherwise we can optimize a DPR_VFP2 660 // reference into a plain DPR, and that will end poorly. NewReg is 661 // always virtual here, so there will always be a matching subclass 662 // to find. 663 MRI->constrainRegClass(NewReg, MRI->getRegClass((*I)->getReg())); 664 665 DEBUG(dbgs() << "Replacing operand " 666 << **I << " with " 667 << PrintReg(NewReg) << "\n"); 668 (*I)->substVirtReg(NewReg, 0, *TRI); 669 } 670 } 671 Replacements[MI] = NewReg; 672 } 673 } 674 return Modified; 675 } 676 677 bool A15SDOptimizer::runOnMachineFunction(MachineFunction &Fn) { 678 TII = static_cast<const ARMBaseInstrInfo*>(Fn.getTarget().getInstrInfo()); 679 TRI = Fn.getTarget().getRegisterInfo(); 680 MRI = &Fn.getRegInfo(); 681 bool Modified = false; 682 683 DEBUG(dbgs() << "Running on function " << Fn.getName()<< "\n"); 684 685 DeadInstr.clear(); 686 Replacements.clear(); 687 688 for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E; 689 ++MFI) { 690 691 for (MachineBasicBlock::iterator MI = MFI->begin(), ME = MFI->end(); 692 MI != ME;) { 693 Modified |= runOnInstruction(MI++); 694 } 695 696 } 697 698 for (std::set<MachineInstr *>::iterator I = DeadInstr.begin(), 699 E = DeadInstr.end(); 700 I != E; ++I) { 701 (*I)->eraseFromParent(); 702 } 703 704 return Modified; 705 } 706 707 FunctionPass *llvm::createA15SDOptimizerPass() { 708 return new A15SDOptimizer(); 709 } 710