LLVM API Documentation

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