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