[llvm] r322325 - PeepholeOpt cleanup/refactor; NFC

Matthias Braun via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 11 14:59:33 PST 2018


Author: matze
Date: Thu Jan 11 14:59:33 2018
New Revision: 322325

URL: http://llvm.org/viewvc/llvm-project?rev=322325&view=rev
Log:
PeepholeOpt cleanup/refactor; NFC

- Less unnecessary use of `auto`
- Add early `using RegSubRegPair(AndIdx) =` to avoid countless
  `TargetInstrInfo::` qualifications.
- Use references instead of pointers where possible.
- Remove unused parameters.
- Rewrite the CopyRewriter class hierarchy:
   - Pull out uncoalescable copy rewriting functionality into
     PeepholeOptimizer class.
   - Use an abstract base class to make it clear that rewriters are
     independent.
- Remove unnecessary \brief in doxygen comments.
- Remove unused constructor and method from ValueTracker.
- Replace UseAdvancedTracking of ValueTracker with DisableAdvCopyOpt use.

Modified:
    llvm/trunk/lib/CodeGen/PeepholeOptimizer.cpp

Modified: llvm/trunk/lib/CodeGen/PeepholeOptimizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PeepholeOptimizer.cpp?rev=322325&r1=322324&r2=322325&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/PeepholeOptimizer.cpp (original)
+++ llvm/trunk/lib/CodeGen/PeepholeOptimizer.cpp Thu Jan 11 14:59:33 2018
@@ -98,6 +98,8 @@
 #include <utility>
 
 using namespace llvm;
+using RegSubRegPair = TargetInstrInfo::RegSubRegPair;
+using RegSubRegPairAndIdx = TargetInstrInfo::RegSubRegPairAndIdx;
 
 #define DEBUG_TYPE "peephole-opt"
 
@@ -110,6 +112,9 @@ static cl::opt<bool>
 DisablePeephole("disable-peephole", cl::Hidden, cl::init(false),
                 cl::desc("Disable the peephole optimizer"));
 
+/// Specifiy whether or not the value tracking looks through
+/// complex instructions. When this is true, the value tracker
+/// bails on everything that is not a copy or a bitcast.
 static cl::opt<bool>
 DisableAdvCopyOpt("disable-adv-copy-opt", cl::Hidden, cl::init(false),
                   cl::desc("Disable advanced copy optimization"));
@@ -132,11 +137,11 @@ static cl::opt<unsigned> MaxRecurrenceCh
              "of commuting operands"));
 
 
-STATISTIC(NumReuse,      "Number of extension results reused");
-STATISTIC(NumCmps,       "Number of compares eliminated");
-STATISTIC(NumImmFold,    "Number of move immediate folded");
-STATISTIC(NumLoadFold,   "Number of loads folded");
-STATISTIC(NumSelects,    "Number of selects optimized");
+STATISTIC(NumReuse, "Number of extension results reused");
+STATISTIC(NumCmps, "Number of compares eliminated");
+STATISTIC(NumImmFold, "Number of move immediate folded");
+STATISTIC(NumLoadFold, "Number of loads folded");
+STATISTIC(NumSelects, "Number of selects optimized");
 STATISTIC(NumUncoalescableCopies, "Number of uncoalescable copies optimized");
 STATISTIC(NumRewrittenCopies, "Number of copies rewritten");
 STATISTIC(NumNAPhysCopies, "Number of non-allocatable physical copies removed");
@@ -149,9 +154,9 @@ namespace {
   class PeepholeOptimizer : public MachineFunctionPass {
     const TargetInstrInfo *TII;
     const TargetRegisterInfo *TRI;
-    MachineRegisterInfo   *MRI;
-    MachineDominatorTree  *DT;  // Machine dominator tree
-    MachineLoopInfo       *MLI;
+    MachineRegisterInfo *MRI;
+    MachineDominatorTree *DT;  // Machine dominator tree
+    MachineLoopInfo *MLI;
 
   public:
     static char ID; // Pass identification
@@ -173,31 +178,28 @@ namespace {
       }
     }
 
-    /// \brief Track Def -> Use info used for rewriting copies.
-    using RewriteMapTy =
-        SmallDenseMap<TargetInstrInfo::RegSubRegPair, ValueTrackerResult>;
+    /// Track Def -> Use info used for rewriting copies.
+    using RewriteMapTy = SmallDenseMap<RegSubRegPair, ValueTrackerResult>;
 
-    /// \brief Sequence of instructions that formulate recurrence cycle.
+    /// Sequence of instructions that formulate recurrence cycle.
     using RecurrenceCycle = SmallVector<RecurrenceInstr, 4>;
 
   private:
-    bool optimizeCmpInstr(MachineInstr *MI, MachineBasicBlock *MBB);
-    bool optimizeExtInstr(MachineInstr *MI, MachineBasicBlock *MBB,
+    bool optimizeCmpInstr(MachineInstr &MI);
+    bool optimizeExtInstr(MachineInstr &MI, MachineBasicBlock &MBB,
                           SmallPtrSetImpl<MachineInstr*> &LocalMIs);
-    bool optimizeSelect(MachineInstr *MI,
+    bool optimizeSelect(MachineInstr &MI,
                         SmallPtrSetImpl<MachineInstr *> &LocalMIs);
-    bool optimizeCondBranch(MachineInstr *MI);
-    bool optimizeCoalescableCopy(MachineInstr *MI);
-    bool optimizeUncoalescableCopy(MachineInstr *MI,
+    bool optimizeCondBranch(MachineInstr &MI);
+    bool optimizeCoalescableCopy(MachineInstr &MI);
+    bool optimizeUncoalescableCopy(MachineInstr &MI,
                                    SmallPtrSetImpl<MachineInstr *> &LocalMIs);
     bool optimizeRecurrence(MachineInstr &PHI);
-    bool findNextSource(unsigned Reg, unsigned SubReg,
-                        RewriteMapTy &RewriteMap);
-    bool isMoveImmediate(MachineInstr *MI,
+    bool findNextSource(RegSubRegPair RegSubReg, RewriteMapTy &RewriteMap);
+    bool isMoveImmediate(MachineInstr &MI,
                          SmallSet<unsigned, 4> &ImmDefRegs,
                          DenseMap<unsigned, MachineInstr*> &ImmDefMIs);
-    bool foldImmediate(MachineInstr *MI, MachineBasicBlock *MBB,
-                       SmallSet<unsigned, 4> &ImmDefRegs,
+    bool foldImmediate(MachineInstr &MI, SmallSet<unsigned, 4> &ImmDefRegs,
                        DenseMap<unsigned, MachineInstr*> &ImmDefMIs);
 
     /// \brief Finds recurrence cycles, but only ones that formulated around
@@ -212,11 +214,11 @@ namespace {
     /// the set \p CopySrcRegs and \p CopyMIs. If this virtual register was
     /// previously seen as a copy, replace the uses of this copy with the
     /// previously seen copy's destination register.
-    bool foldRedundantCopy(MachineInstr *MI,
+    bool foldRedundantCopy(MachineInstr &MI,
                            SmallSet<unsigned, 4> &CopySrcRegs,
                            DenseMap<unsigned, MachineInstr *> &CopyMIs);
 
-    /// \brief Is the register \p Reg a non-allocatable physical register?
+    /// Is the register \p Reg a non-allocatable physical register?
     bool isNAPhysCopy(unsigned Reg);
 
     /// \brief If copy instruction \p MI is a non-allocatable virtual<->physical
@@ -224,11 +226,10 @@ namespace {
     /// non-allocatable physical register was previously copied to a virtual
     /// registered and hasn't been clobbered, the virt->phys copy can be
     /// deleted.
-    bool foldRedundantNAPhysCopy(
-        MachineInstr *MI,
+    bool foldRedundantNAPhysCopy(MachineInstr &MI,
         DenseMap<unsigned, MachineInstr *> &NAPhysToVirtMIs);
 
-    bool isLoadFoldable(MachineInstr *MI,
+    bool isLoadFoldable(MachineInstr &MI,
                         SmallSet<unsigned, 16> &FoldAsLoadDefCandidates);
 
     /// \brief Check whether \p MI is understood by the register coalescer
@@ -249,10 +250,13 @@ namespace {
               (MI.isRegSequenceLike() || MI.isInsertSubregLike() ||
                MI.isExtractSubregLike()));
     }
+
+    MachineInstr &rewriteSource(MachineInstr &CopyLike,
+                                RegSubRegPair Def, RewriteMapTy &RewriteMap);
   };
 
-  /// \brief Helper class to hold instructions that are inside recurrence
-  /// cycles. The recurrence cycle is formulated around 1) a def operand and its
+  /// Helper class to hold instructions that are inside recurrence cycles.
+  /// The recurrence cycle is formulated around 1) a def operand and its
   /// tied use operand, or 2) a def operand and a use operand that is commutable
   /// with another use operand which is tied to the def operand. In the latter
   /// case, index of the tied use operand and the commutable use operand are
@@ -273,13 +277,13 @@ namespace {
     Optional<IndexPair> CommutePair;
   };
 
-  /// \brief Helper class to hold a reply for ValueTracker queries. Contains the
-  /// returned sources for a given search and the instructions where the sources
-  /// were tracked from.
+  /// Helper class to hold a reply for ValueTracker queries.
+  /// Contains the returned sources for a given search and the instructions
+  /// where the sources were tracked from.
   class ValueTrackerResult {
   private:
     /// Track all sources found by one ValueTracker query.
-    SmallVector<TargetInstrInfo::RegSubRegPair, 2> RegSrcs;
+    SmallVector<RegSubRegPair, 2> RegSrcs;
 
     /// Instruction using the sources in 'RegSrcs'.
     const MachineInstr *Inst = nullptr;
@@ -302,16 +306,20 @@ namespace {
     }
 
     void addSource(unsigned SrcReg, unsigned SrcSubReg) {
-      RegSrcs.push_back(TargetInstrInfo::RegSubRegPair(SrcReg, SrcSubReg));
+      RegSrcs.push_back(RegSubRegPair(SrcReg, SrcSubReg));
     }
 
     void setSource(int Idx, unsigned SrcReg, unsigned SrcSubReg) {
       assert(Idx < getNumSources() && "Reg pair source out of index");
-      RegSrcs[Idx] = TargetInstrInfo::RegSubRegPair(SrcReg, SrcSubReg);
+      RegSrcs[Idx] = RegSubRegPair(SrcReg, SrcSubReg);
     }
 
     int getNumSources() const { return RegSrcs.size(); }
 
+    RegSubRegPair getSrc(int Idx) const {
+      return RegSrcs[Idx];
+    }
+
     unsigned getSrcReg(int Idx) const {
       assert(Idx < getNumSources() && "Reg source out of index");
       return RegSrcs[Idx].Reg;
@@ -367,59 +375,41 @@ namespace {
     /// The register where the value can be found.
     unsigned Reg;
 
-    /// Specifiy whether or not the value tracking looks through
-    /// complex instructions. When this is false, the value tracker
-    /// bails on everything that is not a copy or a bitcast.
-    ///
-    /// Note: This could have been implemented as a specialized version of
-    /// the ValueTracker class but that would have complicated the code of
-    /// the users of this class.
-    bool UseAdvancedTracking;
-
     /// MachineRegisterInfo used to perform tracking.
     const MachineRegisterInfo &MRI;
 
-    /// Optional TargetInstrInfo used to perform some complex
-    /// tracking.
+    /// Optional TargetInstrInfo used to perform some complex tracking.
     const TargetInstrInfo *TII;
 
-    /// \brief Dispatcher to the right underlying implementation of
-    /// getNextSource.
+    /// Dispatcher to the right underlying implementation of getNextSource.
     ValueTrackerResult getNextSourceImpl();
 
-    /// \brief Specialized version of getNextSource for Copy instructions.
+    /// Specialized version of getNextSource for Copy instructions.
     ValueTrackerResult getNextSourceFromCopy();
 
-    /// \brief Specialized version of getNextSource for Bitcast instructions.
+    /// Specialized version of getNextSource for Bitcast instructions.
     ValueTrackerResult getNextSourceFromBitcast();
 
-    /// \brief Specialized version of getNextSource for RegSequence
-    /// instructions.
+    /// Specialized version of getNextSource for RegSequence instructions.
     ValueTrackerResult getNextSourceFromRegSequence();
 
-    /// \brief Specialized version of getNextSource for InsertSubreg
-    /// instructions.
+    /// Specialized version of getNextSource for InsertSubreg instructions.
     ValueTrackerResult getNextSourceFromInsertSubreg();
 
-    /// \brief Specialized version of getNextSource for ExtractSubreg
-    /// instructions.
+    /// Specialized version of getNextSource for ExtractSubreg instructions.
     ValueTrackerResult getNextSourceFromExtractSubreg();
 
-    /// \brief Specialized version of getNextSource for SubregToReg
-    /// instructions.
+    /// Specialized version of getNextSource for SubregToReg instructions.
     ValueTrackerResult getNextSourceFromSubregToReg();
 
-    /// \brief Specialized version of getNextSource for PHI instructions.
+    /// Specialized version of getNextSource for PHI instructions.
     ValueTrackerResult getNextSourceFromPHI();
 
   public:
-    /// \brief Create a ValueTracker instance for the value defined by \p Reg.
+    /// Create a ValueTracker instance for the value defined by \p Reg.
     /// \p DefSubReg represents the sub register index the value tracker will
     /// track. It does not need to match the sub register index used in the
     /// definition of \p Reg.
-    /// \p UseAdvancedTracking specifies whether or not the value tracker looks
-    /// through complex instructions. By default (false), it handles only copy
-    /// and bitcast instructions.
     /// If \p Reg is a physical register, a value tracker constructed with
     /// this constructor will not find any alternative source.
     /// Indeed, when \p Reg is a physical register that constructor does not
@@ -427,46 +417,20 @@ namespace {
     /// Use the next constructor to track a physical register.
     ValueTracker(unsigned Reg, unsigned DefSubReg,
                  const MachineRegisterInfo &MRI,
-                 bool UseAdvancedTracking = false,
                  const TargetInstrInfo *TII = nullptr)
-        : DefSubReg(DefSubReg), Reg(Reg),
-          UseAdvancedTracking(UseAdvancedTracking), MRI(MRI), TII(TII) {
+        : DefSubReg(DefSubReg), Reg(Reg), MRI(MRI), TII(TII) {
       if (!TargetRegisterInfo::isPhysicalRegister(Reg)) {
         Def = MRI.getVRegDef(Reg);
         DefIdx = MRI.def_begin(Reg).getOperandNo();
       }
     }
 
-    /// \brief Create a ValueTracker instance for the value defined by
-    /// the pair \p MI, \p DefIdx.
-    /// Unlike the other constructor, the value tracker produced by this one
-    /// may be able to find a new source when the definition is a physical
-    /// register.
-    /// This could be useful to rewrite target specific instructions into
-    /// generic copy instructions.
-    ValueTracker(const MachineInstr &MI, unsigned DefIdx, unsigned DefSubReg,
-                 const MachineRegisterInfo &MRI,
-                 bool UseAdvancedTracking = false,
-                 const TargetInstrInfo *TII = nullptr)
-        : Def(&MI), DefIdx(DefIdx), DefSubReg(DefSubReg),
-          UseAdvancedTracking(UseAdvancedTracking), MRI(MRI), TII(TII) {
-      assert(DefIdx < Def->getDesc().getNumDefs() &&
-             Def->getOperand(DefIdx).isReg() && "Invalid definition");
-      Reg = Def->getOperand(DefIdx).getReg();
-    }
-
     /// \brief Following the use-def chain, get the next available source
     /// for the tracked value.
     /// \return A ValueTrackerResult containing a set of registers
     /// and sub registers with tracked values. A ValueTrackerResult with
     /// an empty set of registers means no source was found.
     ValueTrackerResult getNextSource();
-
-    /// \brief Get the last register where the initial value can be found.
-    /// Initially this is the register of the definition.
-    /// Then, after each successful call to getNextSource, this is the
-    /// register of the last source.
-    unsigned getReg() const { return Reg; }
   };
 
 } // end anonymous namespace
@@ -476,11 +440,11 @@ char PeepholeOptimizer::ID = 0;
 char &llvm::PeepholeOptimizerID = PeepholeOptimizer::ID;
 
 INITIALIZE_PASS_BEGIN(PeepholeOptimizer, DEBUG_TYPE,
-                "Peephole Optimizations", false, false)
+                      "Peephole Optimizations", false, false)
 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
 INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
 INITIALIZE_PASS_END(PeepholeOptimizer, DEBUG_TYPE,
-                "Peephole Optimizations", false, false)
+                    "Peephole Optimizations", false, false)
 
 /// If instruction is a copy-like instruction, i.e. it reads a single register
 /// and writes a single register and it does not modify the source, and if the
@@ -491,10 +455,10 @@ INITIALIZE_PASS_END(PeepholeOptimizer, D
 /// the code. Since this code does not currently share EXTRACTs, just ignore all
 /// debug uses.
 bool PeepholeOptimizer::
-optimizeExtInstr(MachineInstr *MI, MachineBasicBlock *MBB,
+optimizeExtInstr(MachineInstr &MI, MachineBasicBlock &MBB,
                  SmallPtrSetImpl<MachineInstr*> &LocalMIs) {
   unsigned SrcReg, DstReg, SubIdx;
-  if (!TII->isCoalescableExtInstr(*MI, SrcReg, DstReg, SubIdx))
+  if (!TII->isCoalescableExtInstr(MI, SrcReg, DstReg, SubIdx))
     return false;
 
   if (TargetRegisterInfo::isPhysicalRegister(DstReg) ||
@@ -535,7 +499,7 @@ optimizeExtInstr(MachineInstr *MI, Machi
   bool ExtendLife = true;
   for (MachineOperand &UseMO : MRI->use_nodbg_operands(SrcReg)) {
     MachineInstr *UseMI = UseMO.getParent();
-    if (UseMI == MI)
+    if (UseMI == &MI)
       continue;
 
     if (UseMI->isPHI()) {
@@ -568,7 +532,7 @@ optimizeExtInstr(MachineInstr *MI, Machi
       continue;
 
     MachineBasicBlock *UseMBB = UseMI->getParent();
-    if (UseMBB == MBB) {
+    if (UseMBB == &MBB) {
       // Local uses that come after the extension.
       if (!LocalMIs.count(UseMI))
         Uses.push_back(&UseMO);
@@ -576,7 +540,7 @@ optimizeExtInstr(MachineInstr *MI, Machi
       // Non-local uses where the result of the extension is used. Always
       // replace these unless it's a PHI.
       Uses.push_back(&UseMO);
-    } else if (Aggressive && DT->dominates(MBB, UseMBB)) {
+    } else if (Aggressive && DT->dominates(&MBB, UseMBB)) {
       // We may want to extend the live range of the extension result in order
       // to replace these uses.
       ExtendedUses.push_back(&UseMO);
@@ -640,19 +604,18 @@ optimizeExtInstr(MachineInstr *MI, Machi
 /// against already sets (or could be modified to set) the same flag as the
 /// compare, then we can remove the comparison and use the flag from the
 /// previous instruction.
-bool PeepholeOptimizer::optimizeCmpInstr(MachineInstr *MI,
-                                         MachineBasicBlock *MBB) {
+bool PeepholeOptimizer::optimizeCmpInstr(MachineInstr &MI) {
   // If this instruction is a comparison against zero and isn't comparing a
   // physical register, we can try to optimize it.
   unsigned SrcReg, SrcReg2;
   int CmpMask, CmpValue;
-  if (!TII->analyzeCompare(*MI, SrcReg, SrcReg2, CmpMask, CmpValue) ||
+  if (!TII->analyzeCompare(MI, SrcReg, SrcReg2, CmpMask, CmpValue) ||
       TargetRegisterInfo::isPhysicalRegister(SrcReg) ||
       (SrcReg2 != 0 && TargetRegisterInfo::isPhysicalRegister(SrcReg2)))
     return false;
 
   // Attempt to optimize the comparison instruction.
-  if (TII->optimizeCompareInstr(*MI, SrcReg, SrcReg2, CmpMask, CmpValue, MRI)) {
+  if (TII->optimizeCompareInstr(MI, SrcReg, SrcReg2, CmpMask, CmpValue, MRI)) {
     ++NumCmps;
     return true;
   }
@@ -661,27 +624,26 @@ bool PeepholeOptimizer::optimizeCmpInstr
 }
 
 /// Optimize a select instruction.
-bool PeepholeOptimizer::optimizeSelect(MachineInstr *MI,
+bool PeepholeOptimizer::optimizeSelect(MachineInstr &MI,
                             SmallPtrSetImpl<MachineInstr *> &LocalMIs) {
   unsigned TrueOp = 0;
   unsigned FalseOp = 0;
   bool Optimizable = false;
   SmallVector<MachineOperand, 4> Cond;
-  if (TII->analyzeSelect(*MI, Cond, TrueOp, FalseOp, Optimizable))
+  if (TII->analyzeSelect(MI, Cond, TrueOp, FalseOp, Optimizable))
     return false;
   if (!Optimizable)
     return false;
-  if (!TII->optimizeSelect(*MI, LocalMIs))
+  if (!TII->optimizeSelect(MI, LocalMIs))
     return false;
-  MI->eraseFromParent();
+  MI.eraseFromParent();
   ++NumSelects;
   return true;
 }
 
-/// \brief Check if a simpler conditional branch can be
-/// generated
-bool PeepholeOptimizer::optimizeCondBranch(MachineInstr *MI) {
-  return TII->optimizeCondBranch(*MI);
+/// Check if a simpler conditional branch can be generated.
+bool PeepholeOptimizer::optimizeCondBranch(MachineInstr &MI) {
+  return TII->optimizeCondBranch(MI);
 }
 
 /// \brief Try to find the next source that share the same register file
@@ -695,30 +657,29 @@ bool PeepholeOptimizer::optimizeCondBran
 /// share the same register file as \p Reg and \p SubReg. The client should
 /// then be capable to rewrite all intermediate PHIs to get the next source.
 /// \return False if no alternative sources are available. True otherwise.
-bool PeepholeOptimizer::findNextSource(unsigned Reg, unsigned SubReg,
+bool PeepholeOptimizer::findNextSource(RegSubRegPair RegSubReg,
                                        RewriteMapTy &RewriteMap) {
   // Do not try to find a new source for a physical register.
   // So far we do not have any motivating example for doing that.
   // Thus, instead of maintaining untested code, we will revisit that if
   // that changes at some point.
+  unsigned Reg = RegSubReg.Reg;
   if (TargetRegisterInfo::isPhysicalRegister(Reg))
     return false;
   const TargetRegisterClass *DefRC = MRI->getRegClass(Reg);
 
-  SmallVector<TargetInstrInfo::RegSubRegPair, 4> SrcToLook;
-  TargetInstrInfo::RegSubRegPair CurSrcPair(Reg, SubReg);
+  SmallVector<RegSubRegPair, 4> SrcToLook;
+  RegSubRegPair CurSrcPair = RegSubReg;
   SrcToLook.push_back(CurSrcPair);
 
   unsigned PHICount = 0;
-  while (!SrcToLook.empty() && PHICount < RewritePHILimit) {
-    TargetInstrInfo::RegSubRegPair Pair = SrcToLook.pop_back_val();
+  do {
+    CurSrcPair = SrcToLook.pop_back_val();
     // As explained above, do not handle physical registers
-    if (TargetRegisterInfo::isPhysicalRegister(Pair.Reg))
+    if (TargetRegisterInfo::isPhysicalRegister(CurSrcPair.Reg))
       return false;
 
-    CurSrcPair = Pair;
-    ValueTracker ValTracker(CurSrcPair.Reg, CurSrcPair.SubReg, *MRI,
-                            !DisableAdvCopyOpt, TII);
+    ValueTracker ValTracker(CurSrcPair.Reg, CurSrcPair.SubReg, *MRI, TII);
 
     // Follow the chain of copies until we find a more suitable source, a phi
     // or have to abort.
@@ -747,14 +708,17 @@ bool PeepholeOptimizer::findNextSource(u
       unsigned NumSrcs = Res.getNumSources();
       if (NumSrcs > 1) {
         PHICount++;
+        if (PHICount >= RewritePHILimit) {
+          DEBUG(dbgs() << "findNextSource: PHI limit reached\n");
+          return false;
+        }
+
         for (unsigned i = 0; i < NumSrcs; ++i)
-          SrcToLook.push_back(TargetInstrInfo::RegSubRegPair(
-              Res.getSrcReg(i), Res.getSrcSubReg(i)));
+          SrcToLook.push_back(Res.getSrc(i));
         break;
       }
 
-      CurSrcPair.Reg = Res.getSrcReg(0);
-      CurSrcPair.SubReg = Res.getSrcSubReg(0);
+      CurSrcPair = Res.getSrc(0);
       // Do not extend the live-ranges of physical registers as they add
       // constraints to the register allocator. Moreover, if we want to extend
       // the live-range of a physical register, unlike SSA virtual register,
@@ -764,7 +728,8 @@ bool PeepholeOptimizer::findNextSource(u
 
       // Keep following the chain if the value isn't any better yet.
       const TargetRegisterClass *SrcRC = MRI->getRegClass(CurSrcPair.Reg);
-      if (!TRI->shouldRewriteCopySrc(DefRC, SubReg, SrcRC, CurSrcPair.SubReg))
+      if (!TRI->shouldRewriteCopySrc(DefRC, RegSubReg.SubReg, SrcRC,
+                                     CurSrcPair.SubReg))
         continue;
 
       // We currently cannot deal with subreg operands on PHI instructions
@@ -775,7 +740,7 @@ bool PeepholeOptimizer::findNextSource(u
       // We found a suitable source, and are done with this chain.
       break;
     }
-  }
+  } while (!SrcToLook.empty());
 
   // If we did not find a more suitable source, there is nothing to optimize.
   return CurSrcPair.Reg != Reg;
@@ -786,54 +751,50 @@ bool PeepholeOptimizer::findNextSource(u
 /// successfully traverse a PHI instruction and find suitable sources coming
 /// from its edges. By inserting a new PHI, we provide a rewritten PHI def
 /// suitable to be used in a new COPY instruction.
-static MachineInstr *
-insertPHI(MachineRegisterInfo *MRI, const TargetInstrInfo *TII,
-          const SmallVectorImpl<TargetInstrInfo::RegSubRegPair> &SrcRegs,
-          MachineInstr *OrigPHI) {
+static MachineInstr &
+insertPHI(MachineRegisterInfo &MRI, const TargetInstrInfo &TII,
+          const SmallVectorImpl<RegSubRegPair> &SrcRegs,
+          MachineInstr &OrigPHI) {
   assert(!SrcRegs.empty() && "No sources to create a PHI instruction?");
 
-  const TargetRegisterClass *NewRC = MRI->getRegClass(SrcRegs[0].Reg);
+  const TargetRegisterClass *NewRC = MRI.getRegClass(SrcRegs[0].Reg);
   // NewRC is only correct if no subregisters are involved. findNextSource()
   // should have rejected those cases already.
   assert(SrcRegs[0].SubReg == 0 && "should not have subreg operand");
-  unsigned NewVR = MRI->createVirtualRegister(NewRC);
-  MachineBasicBlock *MBB = OrigPHI->getParent();
-  MachineInstrBuilder MIB = BuildMI(*MBB, OrigPHI, OrigPHI->getDebugLoc(),
-                                    TII->get(TargetOpcode::PHI), NewVR);
+  unsigned NewVR = MRI.createVirtualRegister(NewRC);
+  MachineBasicBlock *MBB = OrigPHI.getParent();
+  MachineInstrBuilder MIB = BuildMI(*MBB, &OrigPHI, OrigPHI.getDebugLoc(),
+                                    TII.get(TargetOpcode::PHI), NewVR);
 
   unsigned MBBOpIdx = 2;
-  for (auto RegPair : SrcRegs) {
+  for (const RegSubRegPair &RegPair : SrcRegs) {
     MIB.addReg(RegPair.Reg, 0, RegPair.SubReg);
-    MIB.addMBB(OrigPHI->getOperand(MBBOpIdx).getMBB());
+    MIB.addMBB(OrigPHI.getOperand(MBBOpIdx).getMBB());
     // Since we're extended the lifetime of RegPair.Reg, clear the
     // kill flags to account for that and make RegPair.Reg reaches
     // the new PHI.
-    MRI->clearKillFlags(RegPair.Reg);
+    MRI.clearKillFlags(RegPair.Reg);
     MBBOpIdx += 2;
   }
 
-  return MIB;
+  return *MIB;
 }
 
 namespace {
 
-/// \brief Helper class to rewrite the arguments of a copy-like instruction.
-class CopyRewriter {
+/// Interface to query instructions amenable to copy rewriting.
+class Rewriter {
 protected:
-  /// The copy-like instruction.
   MachineInstr &CopyLike;
-
-  /// The index of the source being rewritten.
-  unsigned CurrentSrcIdx = 0;
-
+  unsigned CurrentSrcIdx = 0;   ///< The index of the source being rewritten.
 public:
-  CopyRewriter(MachineInstr &MI) : CopyLike(MI) {}
-  virtual ~CopyRewriter() = default;
+  Rewriter(MachineInstr &CopyLike) : CopyLike(CopyLike) {}
+  virtual ~Rewriter() {}
 
   /// \brief Get the next rewritable source (SrcReg, SrcSubReg) and
-  /// the related value that it affects (TrackReg, TrackSubReg).
+  /// the related value that it affects (DstReg, DstSubReg).
   /// A source is considered rewritable if its register class and the
-  /// register class of the related TrackReg may not be register
+  /// register class of the related DstReg may not be register
   /// coalescer friendly. In other words, given a copy-like instruction
   /// not all the arguments may be returned at rewritable source, since
   /// some arguments are none to be register coalescer friendly.
@@ -848,137 +809,72 @@ public:
   /// the only source this instruction has:
   /// (SrcReg, SrcSubReg) = (src, srcSubIdx).
   /// This source defines the whole definition, i.e.,
-  /// (TrackReg, TrackSubReg) = (dst, dstSubIdx).
+  /// (DstReg, DstSubReg) = (dst, dstSubIdx).
   ///
   /// The second and subsequent calls will return false, as there is only one
   /// rewritable source.
   ///
   /// \return True if a rewritable source has been found, false otherwise.
   /// The output arguments are valid if and only if true is returned.
-  virtual bool getNextRewritableSource(unsigned &SrcReg, unsigned &SrcSubReg,
-                                       unsigned &TrackReg,
-                                       unsigned &TrackSubReg) {
-    // If CurrentSrcIdx == 1, this means this function has already been called
-    // once. CopyLike has one definition and one argument, thus, there is
-    // nothing else to rewrite.
-    if (!CopyLike.isCopy() || CurrentSrcIdx == 1)
+  virtual bool getNextRewritableSource(RegSubRegPair &Src,
+                                       RegSubRegPair &Dst) = 0;
+
+  /// Rewrite the current source with \p NewReg and \p NewSubReg if possible.
+  /// \return True if the rewriting was possible, false otherwise.
+  virtual bool RewriteCurrentSource(unsigned NewReg, unsigned NewSubReg) = 0;
+};
+
+/// Rewriter for COPY instructions.
+class CopyRewriter : public Rewriter {
+public:
+  CopyRewriter(MachineInstr &MI) : Rewriter(MI) {
+    assert(MI.isCopy() && "Expected copy instruction");
+  }
+  virtual ~CopyRewriter() = default;
+
+  bool getNextRewritableSource(RegSubRegPair &Src,
+                               RegSubRegPair &Dst) override {
+    // CurrentSrcIdx > 0 means this function has already been called.
+    if (CurrentSrcIdx > 0)
       return false;
     // This is the first call to getNextRewritableSource.
     // Move the CurrentSrcIdx to remember that we made that call.
     CurrentSrcIdx = 1;
     // The rewritable source is the argument.
     const MachineOperand &MOSrc = CopyLike.getOperand(1);
-    SrcReg = MOSrc.getReg();
-    SrcSubReg = MOSrc.getSubReg();
+    Src = RegSubRegPair(MOSrc.getReg(), MOSrc.getSubReg());
     // What we track are the alternative sources of the definition.
     const MachineOperand &MODef = CopyLike.getOperand(0);
-    TrackReg = MODef.getReg();
-    TrackSubReg = MODef.getSubReg();
+    Dst = RegSubRegPair(MODef.getReg(), MODef.getSubReg());
     return true;
   }
 
-  /// \brief Rewrite the current source with \p NewReg and \p NewSubReg
-  /// if possible.
-  /// \return True if the rewriting was possible, false otherwise.
-  virtual bool RewriteCurrentSource(unsigned NewReg, unsigned NewSubReg) {
-    if (!CopyLike.isCopy() || CurrentSrcIdx != 1)
+  bool RewriteCurrentSource(unsigned NewReg, unsigned NewSubReg) override {
+    if (CurrentSrcIdx != 1)
       return false;
     MachineOperand &MOSrc = CopyLike.getOperand(CurrentSrcIdx);
     MOSrc.setReg(NewReg);
     MOSrc.setSubReg(NewSubReg);
     return true;
   }
-
-  /// \brief Given a \p Def.Reg and Def.SubReg  pair, use \p RewriteMap to find
-  /// the new source to use for rewrite. If \p HandleMultipleSources is true and
-  /// multiple sources for a given \p Def are found along the way, we found a
-  /// PHI instructions that needs to be rewritten.
-  /// TODO: HandleMultipleSources should be removed once we test PHI handling
-  /// with coalescable copies.
-  TargetInstrInfo::RegSubRegPair
-  getNewSource(MachineRegisterInfo *MRI, const TargetInstrInfo *TII,
-               TargetInstrInfo::RegSubRegPair Def,
-               PeepholeOptimizer::RewriteMapTy &RewriteMap,
-               bool HandleMultipleSources = true) {
-    TargetInstrInfo::RegSubRegPair LookupSrc(Def.Reg, Def.SubReg);
-    do {
-      ValueTrackerResult Res = RewriteMap.lookup(LookupSrc);
-      // If there are no entries on the map, LookupSrc is the new source.
-      if (!Res.isValid())
-        return LookupSrc;
-
-      // There's only one source for this definition, keep searching...
-      unsigned NumSrcs = Res.getNumSources();
-      if (NumSrcs == 1) {
-        LookupSrc.Reg = Res.getSrcReg(0);
-        LookupSrc.SubReg = Res.getSrcSubReg(0);
-        continue;
-      }
-
-      // TODO: Remove once multiple srcs w/ coalescable copies are supported.
-      if (!HandleMultipleSources)
-        break;
-
-      // Multiple sources, recurse into each source to find a new source
-      // for it. Then, rewrite the PHI accordingly to its new edges.
-      SmallVector<TargetInstrInfo::RegSubRegPair, 4> NewPHISrcs;
-      for (unsigned i = 0; i < NumSrcs; ++i) {
-        TargetInstrInfo::RegSubRegPair PHISrc(Res.getSrcReg(i),
-                                              Res.getSrcSubReg(i));
-        NewPHISrcs.push_back(
-            getNewSource(MRI, TII, PHISrc, RewriteMap, HandleMultipleSources));
-      }
-
-      // Build the new PHI node and return its def register as the new source.
-      MachineInstr *OrigPHI = const_cast<MachineInstr *>(Res.getInst());
-      MachineInstr *NewPHI = insertPHI(MRI, TII, NewPHISrcs, OrigPHI);
-      DEBUG(dbgs() << "-- getNewSource\n");
-      DEBUG(dbgs() << "   Replacing: " << *OrigPHI);
-      DEBUG(dbgs() << "        With: " << *NewPHI);
-      const MachineOperand &MODef = NewPHI->getOperand(0);
-      return TargetInstrInfo::RegSubRegPair(MODef.getReg(), MODef.getSubReg());
-
-    } while (true);
-
-    return TargetInstrInfo::RegSubRegPair(0, 0);
-  }
-
-  /// \brief Rewrite the source found through \p Def, by using the \p RewriteMap
-  /// and create a new COPY instruction. More info about RewriteMap in
-  /// PeepholeOptimizer::findNextSource. Right now this is only used to handle
-  /// Uncoalescable copies, since they are copy like instructions that aren't
-  /// recognized by the register allocator.
-  virtual MachineInstr *
-  RewriteSource(TargetInstrInfo::RegSubRegPair Def,
-                PeepholeOptimizer::RewriteMapTy &RewriteMap) {
-    return nullptr;
-  }
 };
 
 /// \brief Helper class to rewrite uncoalescable copy like instructions
 /// into new COPY (coalescable friendly) instructions.
-class UncoalescableRewriter : public CopyRewriter {
-protected:
-  const TargetInstrInfo &TII;
-  MachineRegisterInfo   &MRI;
-
-  /// The number of defs in the bitcast
-  unsigned NumDefs;
+class UncoalescableRewriter : public Rewriter {
+  unsigned NumDefs;  ///< Number of defs in the bitcast.
 
 public:
-  UncoalescableRewriter(MachineInstr &MI, const TargetInstrInfo &TII,
-                         MachineRegisterInfo &MRI)
-      : CopyRewriter(MI), TII(TII), MRI(MRI) {
+  UncoalescableRewriter(MachineInstr &MI) : Rewriter(MI) {
     NumDefs = MI.getDesc().getNumDefs();
   }
 
-  /// \brief Get the next rewritable def source (TrackReg, TrackSubReg)
+  /// \see See Rewriter::getNextRewritableSource()
   /// All such sources need to be considered rewritable in order to
   /// rewrite a uncoalescable copy-like instruction. This method return
   /// each definition that must be checked if rewritable.
-  bool getNextRewritableSource(unsigned &SrcReg, unsigned &SrcSubReg,
-                               unsigned &TrackReg,
-                               unsigned &TrackSubReg) override {
+  bool getNextRewritableSource(RegSubRegPair &Src,
+                               RegSubRegPair &Dst) override {
     // Find the next non-dead definition and continue from there.
     if (CurrentSrcIdx == NumDefs)
       return false;
@@ -990,64 +886,27 @@ public:
     }
 
     // What we track are the alternative sources of the definition.
+    Src = RegSubRegPair(0, 0);
     const MachineOperand &MODef = CopyLike.getOperand(CurrentSrcIdx);
-    TrackReg = MODef.getReg();
-    TrackSubReg = MODef.getSubReg();
+    Dst = RegSubRegPair(MODef.getReg(), MODef.getSubReg());
 
     CurrentSrcIdx++;
     return true;
   }
 
-  /// \brief Rewrite the source found through \p Def, by using the \p RewriteMap
-  /// and create a new COPY instruction. More info about RewriteMap in
-  /// PeepholeOptimizer::findNextSource. Right now this is only used to handle
-  /// Uncoalescable copies, since they are copy like instructions that aren't
-  /// recognized by the register allocator.
-  MachineInstr *
-  RewriteSource(TargetInstrInfo::RegSubRegPair Def,
-                PeepholeOptimizer::RewriteMapTy &RewriteMap) override {
-    assert(!TargetRegisterInfo::isPhysicalRegister(Def.Reg) &&
-           "We do not rewrite physical registers");
-
-    // Find the new source to use in the COPY rewrite.
-    TargetInstrInfo::RegSubRegPair NewSrc =
-        getNewSource(&MRI, &TII, Def, RewriteMap);
-
-    // Insert the COPY.
-    const TargetRegisterClass *DefRC = MRI.getRegClass(Def.Reg);
-    unsigned NewVR = MRI.createVirtualRegister(DefRC);
-
-    MachineInstr *NewCopy =
-        BuildMI(*CopyLike.getParent(), &CopyLike, CopyLike.getDebugLoc(),
-                TII.get(TargetOpcode::COPY), NewVR)
-            .addReg(NewSrc.Reg, 0, NewSrc.SubReg);
-
-    NewCopy->getOperand(0).setSubReg(Def.SubReg);
-    if (Def.SubReg)
-      NewCopy->getOperand(0).setIsUndef();
-
-    DEBUG(dbgs() << "-- RewriteSource\n");
-    DEBUG(dbgs() << "   Replacing: " << CopyLike);
-    DEBUG(dbgs() << "        With: " << *NewCopy);
-    MRI.replaceRegWith(Def.Reg, NewVR);
-    MRI.clearKillFlags(NewVR);
-
-    // We extended the lifetime of NewSrc.Reg, clear the kill flags to
-    // account for that.
-    MRI.clearKillFlags(NewSrc.Reg);
-
-    return NewCopy;
+  bool RewriteCurrentSource(unsigned NewReg, unsigned NewSubReg) override {
+    return false;
   }
 };
 
-/// \brief Specialized rewriter for INSERT_SUBREG instruction.
-class InsertSubregRewriter : public CopyRewriter {
+/// Specialized rewriter for INSERT_SUBREG instruction.
+class InsertSubregRewriter : public Rewriter {
 public:
-  InsertSubregRewriter(MachineInstr &MI) : CopyRewriter(MI) {
+  InsertSubregRewriter(MachineInstr &MI) : Rewriter(MI) {
     assert(MI.isInsertSubreg() && "Invalid instruction");
   }
 
-  /// \brief See CopyRewriter::getNextRewritableSource.
+  /// \see See Rewriter::getNextRewritableSource()
   /// Here CopyLike has the following form:
   /// dst = INSERT_SUBREG Src1, Src2.src2SubIdx, subIdx.
   /// Src1 has the same register class has dst, hence, there is
@@ -1055,29 +914,27 @@ public:
   /// Src2.src2SubIdx, may not be register coalescer friendly.
   /// Therefore, the first call to this method returns:
   /// (SrcReg, SrcSubReg) = (Src2, src2SubIdx).
-  /// (TrackReg, TrackSubReg) = (dst, subIdx).
+  /// (DstReg, DstSubReg) = (dst, subIdx).
   ///
   /// Subsequence calls will return false.
-  bool getNextRewritableSource(unsigned &SrcReg, unsigned &SrcSubReg,
-                               unsigned &TrackReg,
-                               unsigned &TrackSubReg) override {
+  bool getNextRewritableSource(RegSubRegPair &Src,
+                               RegSubRegPair &Dst) override {
     // If we already get the only source we can rewrite, return false.
     if (CurrentSrcIdx == 2)
       return false;
     // We are looking at v2 = INSERT_SUBREG v0, v1, sub0.
     CurrentSrcIdx = 2;
     const MachineOperand &MOInsertedReg = CopyLike.getOperand(2);
-    SrcReg = MOInsertedReg.getReg();
-    SrcSubReg = MOInsertedReg.getSubReg();
+    Src = RegSubRegPair(MOInsertedReg.getReg(), MOInsertedReg.getSubReg());
     const MachineOperand &MODef = CopyLike.getOperand(0);
 
     // We want to track something that is compatible with the
     // partial definition.
-    TrackReg = MODef.getReg();
     if (MODef.getSubReg())
       // Bail if we have to compose sub-register indices.
       return false;
-    TrackSubReg = (unsigned)CopyLike.getOperand(3).getImm();
+    Dst = RegSubRegPair(MODef.getReg(),
+                        (unsigned)CopyLike.getOperand(3).getImm());
     return true;
   }
 
@@ -1092,41 +949,39 @@ public:
   }
 };
 
-/// \brief Specialized rewriter for EXTRACT_SUBREG instruction.
-class ExtractSubregRewriter : public CopyRewriter {
+/// Specialized rewriter for EXTRACT_SUBREG instruction.
+class ExtractSubregRewriter : public Rewriter {
   const TargetInstrInfo &TII;
 
 public:
   ExtractSubregRewriter(MachineInstr &MI, const TargetInstrInfo &TII)
-      : CopyRewriter(MI), TII(TII) {
+      : Rewriter(MI), TII(TII) {
     assert(MI.isExtractSubreg() && "Invalid instruction");
   }
 
-  /// \brief See CopyRewriter::getNextRewritableSource.
+  /// \see Rewriter::getNextRewritableSource()
   /// Here CopyLike has the following form:
   /// dst.dstSubIdx = EXTRACT_SUBREG Src, subIdx.
   /// There is only one rewritable source: Src.subIdx,
   /// which defines dst.dstSubIdx.
-  bool getNextRewritableSource(unsigned &SrcReg, unsigned &SrcSubReg,
-                               unsigned &TrackReg,
-                               unsigned &TrackSubReg) override {
+  bool getNextRewritableSource(RegSubRegPair &Src,
+                               RegSubRegPair &Dst) override {
     // If we already get the only source we can rewrite, return false.
     if (CurrentSrcIdx == 1)
       return false;
     // We are looking at v1 = EXTRACT_SUBREG v0, sub0.
     CurrentSrcIdx = 1;
     const MachineOperand &MOExtractedReg = CopyLike.getOperand(1);
-    SrcReg = MOExtractedReg.getReg();
     // If we have to compose sub-register indices, bail out.
     if (MOExtractedReg.getSubReg())
       return false;
 
-    SrcSubReg = CopyLike.getOperand(2).getImm();
+    Src = RegSubRegPair(MOExtractedReg.getReg(),
+                        CopyLike.getOperand(2).getImm());
 
     // We want to track something that is compatible with the definition.
     const MachineOperand &MODef = CopyLike.getOperand(0);
-    TrackReg = MODef.getReg();
-    TrackSubReg = MODef.getSubReg();
+    Dst = RegSubRegPair(MODef.getReg(), MODef.getSubReg());
     return true;
   }
 
@@ -1156,14 +1011,14 @@ public:
   }
 };
 
-/// \brief Specialized rewriter for REG_SEQUENCE instruction.
-class RegSequenceRewriter : public CopyRewriter {
+/// Specialized rewriter for REG_SEQUENCE instruction.
+class RegSequenceRewriter : public Rewriter {
 public:
-  RegSequenceRewriter(MachineInstr &MI) : CopyRewriter(MI) {
+  RegSequenceRewriter(MachineInstr &MI) : Rewriter(MI) {
     assert(MI.isRegSequence() && "Invalid instruction");
   }
 
-  /// \brief See CopyRewriter::getNextRewritableSource.
+  /// \see Rewriter::getNextRewritableSource()
   /// Here CopyLike has the following form:
   /// dst = REG_SEQUENCE Src1.src1SubIdx, subIdx1, Src2.src2SubIdx, subIdx2.
   /// Each call will return a different source, walking all the available
@@ -1171,17 +1026,16 @@ public:
   ///
   /// The first call returns:
   /// (SrcReg, SrcSubReg) = (Src1, src1SubIdx).
-  /// (TrackReg, TrackSubReg) = (dst, subIdx1).
+  /// (DstReg, DstSubReg) = (dst, subIdx1).
   ///
   /// The second call returns:
   /// (SrcReg, SrcSubReg) = (Src2, src2SubIdx).
-  /// (TrackReg, TrackSubReg) = (dst, subIdx2).
+  /// (DstReg, DstSubReg) = (dst, subIdx2).
   ///
   /// And so on, until all the sources have been traversed, then
   /// it returns false.
-  bool getNextRewritableSource(unsigned &SrcReg, unsigned &SrcSubReg,
-                               unsigned &TrackReg,
-                               unsigned &TrackSubReg) override {
+  bool getNextRewritableSource(RegSubRegPair &Src,
+                               RegSubRegPair &Dst) override {
     // We are looking at v0 = REG_SEQUENCE v1, sub1, v2, sub2, etc.
 
     // If this is the first call, move to the first argument.
@@ -1194,17 +1048,17 @@ public:
         return false;
     }
     const MachineOperand &MOInsertedReg = CopyLike.getOperand(CurrentSrcIdx);
-    SrcReg = MOInsertedReg.getReg();
+    Src.Reg = MOInsertedReg.getReg();
     // If we have to compose sub-register indices, bail out.
-    if ((SrcSubReg = MOInsertedReg.getSubReg()))
+    if ((Src.SubReg = MOInsertedReg.getSubReg()))
       return false;
 
     // We want to track something that is compatible with the related
     // partial definition.
-    TrackSubReg = CopyLike.getOperand(CurrentSrcIdx + 1).getImm();
+    Dst.SubReg = CopyLike.getOperand(CurrentSrcIdx + 1).getImm();
 
     const MachineOperand &MODef = CopyLike.getOperand(0);
-    TrackReg = MODef.getReg();
+    Dst.Reg = MODef.getReg();
     // If we have to compose sub-registers, bail.
     return MODef.getSubReg() == 0;
   }
@@ -1224,16 +1078,14 @@ public:
 
 } // end anonymous namespace
 
-/// \brief Get the appropriated CopyRewriter for \p MI.
-/// \return A pointer to a dynamically allocated CopyRewriter or nullptr
-/// if no rewriter works for \p MI.
-static CopyRewriter *getCopyRewriter(MachineInstr &MI,
-                                     const TargetInstrInfo &TII,
-                                     MachineRegisterInfo &MRI) {
+/// Get the appropriated Rewriter for \p MI.
+/// \return A pointer to a dynamically allocated Rewriter or nullptr if no
+/// rewriter works for \p MI.
+static Rewriter *getCopyRewriter(MachineInstr &MI, const TargetInstrInfo &TII) {
   // Handle uncoalescable copy-like instructions.
-  if (MI.isBitcast() || (MI.isRegSequenceLike() || MI.isInsertSubregLike() ||
-                         MI.isExtractSubregLike()))
-    return new UncoalescableRewriter(MI, TII, MRI);
+  if (MI.isBitcast() || MI.isRegSequenceLike() || MI.isInsertSubregLike() ||
+      MI.isExtractSubregLike())
+    return new UncoalescableRewriter(MI);
 
   switch (MI.getOpcode()) {
   default:
@@ -1247,53 +1099,102 @@ static CopyRewriter *getCopyRewriter(Mac
   case TargetOpcode::REG_SEQUENCE:
     return new RegSequenceRewriter(MI);
   }
-  llvm_unreachable(nullptr);
 }
 
-/// \brief Optimize generic copy instructions to avoid cross
-/// register bank copy. The optimization looks through a chain of
-/// copies and tries to find a source that has a compatible register
-/// class.
-/// Two register classes are considered to be compatible if they share
-/// the same register bank.
+/// \brief Given a \p Def.Reg and Def.SubReg  pair, use \p RewriteMap to find
+/// the new source to use for rewrite. If \p HandleMultipleSources is true and
+/// multiple sources for a given \p Def are found along the way, we found a
+/// PHI instructions that needs to be rewritten.
+/// TODO: HandleMultipleSources should be removed once we test PHI handling
+/// with coalescable copies.
+static RegSubRegPair
+getNewSource(MachineRegisterInfo *MRI, const TargetInstrInfo *TII,
+             RegSubRegPair Def,
+             const PeepholeOptimizer::RewriteMapTy &RewriteMap,
+             bool HandleMultipleSources = true) {
+  RegSubRegPair LookupSrc(Def.Reg, Def.SubReg);
+  while (true) {
+    ValueTrackerResult Res = RewriteMap.lookup(LookupSrc);
+    // If there are no entries on the map, LookupSrc is the new source.
+    if (!Res.isValid())
+      return LookupSrc;
+
+    // There's only one source for this definition, keep searching...
+    unsigned NumSrcs = Res.getNumSources();
+    if (NumSrcs == 1) {
+      LookupSrc.Reg = Res.getSrcReg(0);
+      LookupSrc.SubReg = Res.getSrcSubReg(0);
+      continue;
+    }
+
+    // TODO: Remove once multiple srcs w/ coalescable copies are supported.
+    if (!HandleMultipleSources)
+      break;
+
+    // Multiple sources, recurse into each source to find a new source
+    // for it. Then, rewrite the PHI accordingly to its new edges.
+    SmallVector<RegSubRegPair, 4> NewPHISrcs;
+    for (unsigned i = 0; i < NumSrcs; ++i) {
+      RegSubRegPair PHISrc(Res.getSrcReg(i), Res.getSrcSubReg(i));
+      NewPHISrcs.push_back(
+          getNewSource(MRI, TII, PHISrc, RewriteMap, HandleMultipleSources));
+    }
+
+    // Build the new PHI node and return its def register as the new source.
+    MachineInstr &OrigPHI = const_cast<MachineInstr &>(*Res.getInst());
+    MachineInstr &NewPHI = insertPHI(*MRI, *TII, NewPHISrcs, OrigPHI);
+    DEBUG(dbgs() << "-- getNewSource\n");
+    DEBUG(dbgs() << "   Replacing: " << OrigPHI);
+    DEBUG(dbgs() << "        With: " << NewPHI);
+    const MachineOperand &MODef = NewPHI.getOperand(0);
+    return RegSubRegPair(MODef.getReg(), MODef.getSubReg());
+  }
+
+  return RegSubRegPair(0, 0);
+}
+
+/// Optimize generic copy instructions to avoid cross register bank copy.
+/// The optimization looks through a chain of copies and tries to find a source
+/// that has a compatible register class.
+/// Two register classes are considered to be compatible if they share the same
+/// register bank.
 /// New copies issued by this optimization are register allocator
 /// friendly. This optimization does not remove any copy as it may
 /// overconstrain the register allocator, but replaces some operands
 /// when possible.
 /// \pre isCoalescableCopy(*MI) is true.
 /// \return True, when \p MI has been rewritten. False otherwise.
-bool PeepholeOptimizer::optimizeCoalescableCopy(MachineInstr *MI) {
-  assert(MI && isCoalescableCopy(*MI) && "Invalid argument");
-  assert(MI->getDesc().getNumDefs() == 1 &&
+bool PeepholeOptimizer::optimizeCoalescableCopy(MachineInstr &MI) {
+  assert(isCoalescableCopy(MI) && "Invalid argument");
+  assert(MI.getDesc().getNumDefs() == 1 &&
          "Coalescer can understand multiple defs?!");
-  const MachineOperand &MODef = MI->getOperand(0);
+  const MachineOperand &MODef = MI.getOperand(0);
   // Do not rewrite physical definitions.
   if (TargetRegisterInfo::isPhysicalRegister(MODef.getReg()))
     return false;
 
   bool Changed = false;
   // Get the right rewriter for the current copy.
-  std::unique_ptr<CopyRewriter> CpyRewriter(getCopyRewriter(*MI, *TII, *MRI));
+  std::unique_ptr<Rewriter> CpyRewriter(getCopyRewriter(MI, *TII));
   // If none exists, bail out.
   if (!CpyRewriter)
     return false;
   // Rewrite each rewritable source.
-  unsigned SrcReg, SrcSubReg, TrackReg, TrackSubReg;
-  while (CpyRewriter->getNextRewritableSource(SrcReg, SrcSubReg, TrackReg,
-                                              TrackSubReg)) {
+  RegSubRegPair Src;
+  RegSubRegPair TrackPair;
+  while (CpyRewriter->getNextRewritableSource(Src, TrackPair)) {
     // Keep track of PHI nodes and its incoming edges when looking for sources.
     RewriteMapTy RewriteMap;
     // Try to find a more suitable source. If we failed to do so, or get the
     // actual source, move to the next source.
-    if (!findNextSource(TrackReg, TrackSubReg, RewriteMap))
+    if (!findNextSource(TrackPair, RewriteMap))
       continue;
 
     // Get the new source to rewrite. TODO: Only enable handling of multiple
     // sources (PHIs) once we have a motivating example and testcases for it.
-    TargetInstrInfo::RegSubRegPair TrackPair(TrackReg, TrackSubReg);
-    TargetInstrInfo::RegSubRegPair NewSrc = CpyRewriter->getNewSource(
-        MRI, TII, TrackPair, RewriteMap, false /* multiple sources */);
-    if (SrcReg == NewSrc.Reg || NewSrc.Reg == 0)
+    RegSubRegPair NewSrc = getNewSource(MRI, TII, TrackPair, RewriteMap,
+                                        /*HandleMultipleSources=*/false);
+    if (Src.Reg == NewSrc.Reg || NewSrc.Reg == 0)
       continue;
 
     // Rewrite source.
@@ -1312,6 +1213,47 @@ bool PeepholeOptimizer::optimizeCoalesca
   return Changed;
 }
 
+/// \brief Rewrite the source found through \p Def, by using the \p RewriteMap
+/// and create a new COPY instruction. More info about RewriteMap in
+/// PeepholeOptimizer::findNextSource. Right now this is only used to handle
+/// Uncoalescable copies, since they are copy like instructions that aren't
+/// recognized by the register allocator.
+MachineInstr &
+PeepholeOptimizer::rewriteSource(MachineInstr &CopyLike,
+                                 RegSubRegPair Def, RewriteMapTy &RewriteMap) {
+  assert(!TargetRegisterInfo::isPhysicalRegister(Def.Reg) &&
+         "We do not rewrite physical registers");
+
+  // Find the new source to use in the COPY rewrite.
+  RegSubRegPair NewSrc = getNewSource(MRI, TII, Def, RewriteMap);
+
+  // Insert the COPY.
+  const TargetRegisterClass *DefRC = MRI->getRegClass(Def.Reg);
+  unsigned NewVReg = MRI->createVirtualRegister(DefRC);
+
+  MachineInstr *NewCopy =
+      BuildMI(*CopyLike.getParent(), &CopyLike, CopyLike.getDebugLoc(),
+              TII->get(TargetOpcode::COPY), NewVReg)
+          .addReg(NewSrc.Reg, 0, NewSrc.SubReg);
+
+  if (Def.SubReg) {
+    NewCopy->getOperand(0).setSubReg(Def.SubReg);
+    NewCopy->getOperand(0).setIsUndef();
+  }
+
+  DEBUG(dbgs() << "-- RewriteSource\n");
+  DEBUG(dbgs() << "   Replacing: " << CopyLike);
+  DEBUG(dbgs() << "        With: " << *NewCopy);
+  MRI->replaceRegWith(Def.Reg, NewVReg);
+  MRI->clearKillFlags(NewVReg);
+
+  // We extended the lifetime of NewSrc.Reg, clear the kill flags to
+  // account for that.
+  MRI->clearKillFlags(NewSrc.Reg);
+
+  return *NewCopy;
+}
+
 /// \brief Optimize copy-like instructions to create
 /// register coalescer friendly instruction.
 /// The optimization tries to kill-off the \p MI by looking
@@ -1324,48 +1266,40 @@ bool PeepholeOptimizer::optimizeCoalesca
 /// been removed from its parent.
 /// All COPY instructions created, are inserted in \p LocalMIs.
 bool PeepholeOptimizer::optimizeUncoalescableCopy(
-    MachineInstr *MI, SmallPtrSetImpl<MachineInstr *> &LocalMIs) {
-  assert(MI && isUncoalescableCopy(*MI) && "Invalid argument");
-
-  // Check if we can rewrite all the values defined by this instruction.
-  SmallVector<TargetInstrInfo::RegSubRegPair, 4> RewritePairs;
-  // Get the right rewriter for the current copy.
-  std::unique_ptr<CopyRewriter> CpyRewriter(getCopyRewriter(*MI, *TII, *MRI));
-  // If none exists, bail out.
-  if (!CpyRewriter)
-    return false;
+    MachineInstr &MI, SmallPtrSetImpl<MachineInstr *> &LocalMIs) {
+  assert(isUncoalescableCopy(MI) && "Invalid argument");
+  UncoalescableRewriter CpyRewriter(MI);
 
   // Rewrite each rewritable source by generating new COPYs. This works
   // differently from optimizeCoalescableCopy since it first makes sure that all
   // definitions can be rewritten.
   RewriteMapTy RewriteMap;
-  unsigned Reg, SubReg, CopyDefReg, CopyDefSubReg;
-  while (CpyRewriter->getNextRewritableSource(Reg, SubReg, CopyDefReg,
-                                              CopyDefSubReg)) {
+  RegSubRegPair Src;
+  RegSubRegPair Def;
+  SmallVector<RegSubRegPair, 4> RewritePairs;
+  while (CpyRewriter.getNextRewritableSource(Src, Def)) {
     // If a physical register is here, this is probably for a good reason.
     // Do not rewrite that.
-    if (TargetRegisterInfo::isPhysicalRegister(CopyDefReg))
+    if (TargetRegisterInfo::isPhysicalRegister(Def.Reg))
       return false;
 
     // If we do not know how to rewrite this definition, there is no point
     // in trying to kill this instruction.
-    TargetInstrInfo::RegSubRegPair Def(CopyDefReg, CopyDefSubReg);
-    if (!findNextSource(Def.Reg, Def.SubReg, RewriteMap))
+    if (!findNextSource(Def, RewriteMap))
       return false;
 
     RewritePairs.push_back(Def);
   }
 
   // The change is possible for all defs, do it.
-  for (const auto &Def : RewritePairs) {
+  for (const RegSubRegPair &Def : RewritePairs) {
     // Rewrite the "copy" in a way the register coalescer understands.
-    MachineInstr *NewCopy = CpyRewriter->RewriteSource(Def, RewriteMap);
-    assert(NewCopy && "Should be able to always generate a new copy");
-    LocalMIs.insert(NewCopy);
+    MachineInstr &NewCopy = rewriteSource(MI, Def, RewriteMap);
+    LocalMIs.insert(&NewCopy);
   }
 
   // MI is now dead.
-  MI->eraseFromParent();
+  MI.eraseFromParent();
   ++NumUncoalescableCopies;
   return true;
 }
@@ -1374,18 +1308,18 @@ bool PeepholeOptimizer::optimizeUncoales
 /// We only fold loads to virtual registers and the virtual register defined
 /// has a single use.
 bool PeepholeOptimizer::isLoadFoldable(
-    MachineInstr *MI, SmallSet<unsigned, 16> &FoldAsLoadDefCandidates) {
-  if (!MI->canFoldAsLoad() || !MI->mayLoad())
+    MachineInstr &MI, SmallSet<unsigned, 16> &FoldAsLoadDefCandidates) {
+  if (!MI.canFoldAsLoad() || !MI.mayLoad())
     return false;
-  const MCInstrDesc &MCID = MI->getDesc();
+  const MCInstrDesc &MCID = MI.getDesc();
   if (MCID.getNumDefs() != 1)
     return false;
 
-  unsigned Reg = MI->getOperand(0).getReg();
+  unsigned Reg = MI.getOperand(0).getReg();
   // To reduce compilation time, we check MRI->hasOneNonDBGUse when inserting
   // loads. It should be checked when processing uses of the load, since
   // uses can be removed during peephole.
-  if (!MI->getOperand(0).getSubReg() &&
+  if (!MI.getOperand(0).getSubReg() &&
       TargetRegisterInfo::isVirtualRegister(Reg) &&
       MRI->hasOneNonDBGUse(Reg)) {
     FoldAsLoadDefCandidates.insert(Reg);
@@ -1395,16 +1329,16 @@ bool PeepholeOptimizer::isLoadFoldable(
 }
 
 bool PeepholeOptimizer::isMoveImmediate(
-    MachineInstr *MI, SmallSet<unsigned, 4> &ImmDefRegs,
+    MachineInstr &MI, SmallSet<unsigned, 4> &ImmDefRegs,
     DenseMap<unsigned, MachineInstr *> &ImmDefMIs) {
-  const MCInstrDesc &MCID = MI->getDesc();
-  if (!MI->isMoveImmediate())
+  const MCInstrDesc &MCID = MI.getDesc();
+  if (!MI.isMoveImmediate())
     return false;
   if (MCID.getNumDefs() != 1)
     return false;
-  unsigned Reg = MI->getOperand(0).getReg();
+  unsigned Reg = MI.getOperand(0).getReg();
   if (TargetRegisterInfo::isVirtualRegister(Reg)) {
-    ImmDefMIs.insert(std::make_pair(Reg, MI));
+    ImmDefMIs.insert(std::make_pair(Reg, &MI));
     ImmDefRegs.insert(Reg);
     return true;
   }
@@ -1415,11 +1349,11 @@ bool PeepholeOptimizer::isMoveImmediate(
 /// Try folding register operands that are defined by move immediate
 /// instructions, i.e. a trivial constant folding optimization, if
 /// and only if the def and use are in the same BB.
-bool PeepholeOptimizer::foldImmediate(
-    MachineInstr *MI, MachineBasicBlock *MBB, SmallSet<unsigned, 4> &ImmDefRegs,
+bool PeepholeOptimizer::foldImmediate(MachineInstr &MI,
+    SmallSet<unsigned, 4> &ImmDefRegs,
     DenseMap<unsigned, MachineInstr *> &ImmDefMIs) {
-  for (unsigned i = 0, e = MI->getDesc().getNumOperands(); i != e; ++i) {
-    MachineOperand &MO = MI->getOperand(i);
+  for (unsigned i = 0, e = MI.getDesc().getNumOperands(); i != e; ++i) {
+    MachineOperand &MO = MI.getOperand(i);
     if (!MO.isReg() || MO.isDef())
       continue;
     // Ignore dead implicit defs.
@@ -1432,7 +1366,7 @@ bool PeepholeOptimizer::foldImmediate(
       continue;
     DenseMap<unsigned, MachineInstr*>::iterator II = ImmDefMIs.find(Reg);
     assert(II != ImmDefMIs.end() && "couldn't find immediate definition");
-    if (TII->FoldImmediate(*MI, *II->second, Reg, MRI)) {
+    if (TII->FoldImmediate(MI, *II->second, Reg, MRI)) {
       ++NumImmFold;
       return true;
     }
@@ -1454,28 +1388,28 @@ bool PeepholeOptimizer::foldImmediate(
 // %2 = COPY %0:sub1
 //
 // Should replace %2 uses with %1:sub1
-bool PeepholeOptimizer::foldRedundantCopy(
-    MachineInstr *MI, SmallSet<unsigned, 4> &CopySrcRegs,
+bool PeepholeOptimizer::foldRedundantCopy(MachineInstr &MI,
+    SmallSet<unsigned, 4> &CopySrcRegs,
     DenseMap<unsigned, MachineInstr *> &CopyMIs) {
-  assert(MI->isCopy() && "expected a COPY machine instruction");
+  assert(MI.isCopy() && "expected a COPY machine instruction");
 
-  unsigned SrcReg = MI->getOperand(1).getReg();
+  unsigned SrcReg = MI.getOperand(1).getReg();
   if (!TargetRegisterInfo::isVirtualRegister(SrcReg))
     return false;
 
-  unsigned DstReg = MI->getOperand(0).getReg();
+  unsigned DstReg = MI.getOperand(0).getReg();
   if (!TargetRegisterInfo::isVirtualRegister(DstReg))
     return false;
 
   if (CopySrcRegs.insert(SrcReg).second) {
     // First copy of this reg seen.
-    CopyMIs.insert(std::make_pair(SrcReg, MI));
+    CopyMIs.insert(std::make_pair(SrcReg, &MI));
     return false;
   }
 
   MachineInstr *PrevCopy = CopyMIs.find(SrcReg)->second;
 
-  unsigned SrcSubReg = MI->getOperand(1).getSubReg();
+  unsigned SrcSubReg = MI.getOperand(1).getSubReg();
   unsigned PrevSrcSubReg = PrevCopy->getOperand(1).getSubReg();
 
   // Can't replace different subregister extracts.
@@ -1504,19 +1438,19 @@ bool PeepholeOptimizer::isNAPhysCopy(uns
 }
 
 bool PeepholeOptimizer::foldRedundantNAPhysCopy(
-    MachineInstr *MI, DenseMap<unsigned, MachineInstr *> &NAPhysToVirtMIs) {
-  assert(MI->isCopy() && "expected a COPY machine instruction");
+    MachineInstr &MI, DenseMap<unsigned, MachineInstr *> &NAPhysToVirtMIs) {
+  assert(MI.isCopy() && "expected a COPY machine instruction");
 
   if (DisableNAPhysCopyOpt)
     return false;
 
-  unsigned DstReg = MI->getOperand(0).getReg();
-  unsigned SrcReg = MI->getOperand(1).getReg();
+  unsigned DstReg = MI.getOperand(0).getReg();
+  unsigned SrcReg = MI.getOperand(1).getReg();
   if (isNAPhysCopy(SrcReg) && TargetRegisterInfo::isVirtualRegister(DstReg)) {
     // %vreg = COPY %physreg
     // Avoid using a datastructure which can track multiple live non-allocatable
     // phys->virt copies since LLVM doesn't seem to do this.
-    NAPhysToVirtMIs.insert({SrcReg, MI});
+    NAPhysToVirtMIs.insert({SrcReg, &MI});
     return false;
   }
 
@@ -1528,8 +1462,7 @@ bool PeepholeOptimizer::foldRedundantNAP
   if (PrevCopy == NAPhysToVirtMIs.end()) {
     // We can't remove the copy: there was an intervening clobber of the
     // non-allocatable physical register after the copy to virtual.
-    DEBUG(dbgs() << "NAPhysCopy: intervening clobber forbids erasing " << *MI
-                 << '\n');
+    DEBUG(dbgs() << "NAPhysCopy: intervening clobber forbids erasing " << MI);
     return false;
   }
 
@@ -1537,7 +1470,7 @@ bool PeepholeOptimizer::foldRedundantNAP
   if (PrevDstReg == SrcReg) {
     // Remove the virt->phys copy: we saw the virtual register definition, and
     // the non-allocatable physical register's state hasn't changed since then.
-    DEBUG(dbgs() << "NAPhysCopy: erasing " << *MI << '\n');
+    DEBUG(dbgs() << "NAPhysCopy: erasing " << MI);
     ++NumNAPhysCopies;
     return true;
   }
@@ -1546,7 +1479,7 @@ bool PeepholeOptimizer::foldRedundantNAP
   // register get a copy of the non-allocatable physical register, and we only
   // track one such copy. Avoid getting confused by this new non-allocatable
   // physical register definition, and remove it from the tracked copies.
-  DEBUG(dbgs() << "NAPhysCopy: missed opportunity " << *MI << '\n');
+  DEBUG(dbgs() << "NAPhysCopy: missed opportunity " << MI);
   NAPhysToVirtMIs.erase(PrevCopy);
   return false;
 }
@@ -1611,11 +1544,11 @@ bool PeepholeOptimizer::findTargetRecurr
   return false;
 }
 
-/// \brief Phi instructions will eventually be lowered to copy instructions. If
-/// phi is in a loop header, a recurrence may formulated around the source and
-/// destination of the phi. For such case commuting operands of the instructions
-/// in the recurrence may enable coalescing of the copy instruction generated
-/// from the phi. For example, if there is a recurrence of
+/// Phi instructions will eventually be lowered to copy instructions.
+/// If phi is in a loop header, a recurrence may formulated around the source
+/// and destination of the phi. For such case commuting operands of the
+/// instructions in the recurrence may enable coalescing of the copy instruction
+/// generated from the phi. For example, if there is a recurrence of
 ///
 /// LoopHeader:
 ///   %1 = phi(%0, %100)
@@ -1725,27 +1658,25 @@ bool PeepholeOptimizer::runOnMachineFunc
       }
 
       if (!MI->isCopy()) {
-        for (const auto &Op : MI->operands()) {
+        for (const MachineOperand &MO : MI->operands()) {
           // Visit all operands: definitions can be implicit or explicit.
-          if (Op.isReg()) {
-            unsigned Reg = Op.getReg();
-            if (Op.isDef() && isNAPhysCopy(Reg)) {
+          if (MO.isReg()) {
+            unsigned Reg = MO.getReg();
+            if (MO.isDef() && isNAPhysCopy(Reg)) {
               const auto &Def = NAPhysToVirtMIs.find(Reg);
               if (Def != NAPhysToVirtMIs.end()) {
                 // A new definition of the non-allocatable physical register
                 // invalidates previous copies.
-                DEBUG(dbgs() << "NAPhysCopy: invalidating because of " << *MI
-                             << '\n');
+                DEBUG(dbgs() << "NAPhysCopy: invalidating because of " << *MI);
                 NAPhysToVirtMIs.erase(Def);
               }
             }
-          } else if (Op.isRegMask()) {
-            const uint32_t *RegMask = Op.getRegMask();
+          } else if (MO.isRegMask()) {
+            const uint32_t *RegMask = MO.getRegMask();
             for (auto &RegMI : NAPhysToVirtMIs) {
               unsigned Def = RegMI.first;
               if (MachineOperand::clobbersPhysReg(RegMask, Def)) {
-                DEBUG(dbgs() << "NAPhysCopy: invalidating because of " << *MI
-                             << '\n');
+                DEBUG(dbgs() << "NAPhysCopy: invalidating because of " << *MI);
                 NAPhysToVirtMIs.erase(Def);
               }
             }
@@ -1761,58 +1692,57 @@ bool PeepholeOptimizer::runOnMachineFunc
         // don't know what's correct anymore.
         //
         // FIXME: handle explicit asm clobbers.
-        DEBUG(dbgs() << "NAPhysCopy: blowing away all info due to " << *MI
-                     << '\n');
+        DEBUG(dbgs() << "NAPhysCopy: blowing away all info due to " << *MI);
         NAPhysToVirtMIs.clear();
       }
 
       if ((isUncoalescableCopy(*MI) &&
-           optimizeUncoalescableCopy(MI, LocalMIs)) ||
-          (MI->isCompare() && optimizeCmpInstr(MI, &MBB)) ||
-          (MI->isSelect() && optimizeSelect(MI, LocalMIs))) {
+           optimizeUncoalescableCopy(*MI, LocalMIs)) ||
+          (MI->isCompare() && optimizeCmpInstr(*MI)) ||
+          (MI->isSelect() && optimizeSelect(*MI, LocalMIs))) {
         // MI is deleted.
         LocalMIs.erase(MI);
         Changed = true;
         continue;
       }
 
-      if (MI->isConditionalBranch() && optimizeCondBranch(MI)) {
+      if (MI->isConditionalBranch() && optimizeCondBranch(*MI)) {
         Changed = true;
         continue;
       }
 
-      if (isCoalescableCopy(*MI) && optimizeCoalescableCopy(MI)) {
+      if (isCoalescableCopy(*MI) && optimizeCoalescableCopy(*MI)) {
         // MI is just rewritten.
         Changed = true;
         continue;
       }
 
       if (MI->isCopy() &&
-          (foldRedundantCopy(MI, CopySrcRegs, CopySrcMIs) ||
-           foldRedundantNAPhysCopy(MI, NAPhysToVirtMIs))) {
+          (foldRedundantCopy(*MI, CopySrcRegs, CopySrcMIs) ||
+           foldRedundantNAPhysCopy(*MI, NAPhysToVirtMIs))) {
         LocalMIs.erase(MI);
         MI->eraseFromParent();
         Changed = true;
         continue;
       }
 
-      if (isMoveImmediate(MI, ImmDefRegs, ImmDefMIs)) {
+      if (isMoveImmediate(*MI, ImmDefRegs, ImmDefMIs)) {
         SeenMoveImm = true;
       } else {
-        Changed |= optimizeExtInstr(MI, &MBB, LocalMIs);
+        Changed |= optimizeExtInstr(*MI, MBB, LocalMIs);
         // optimizeExtInstr might have created new instructions after MI
         // and before the already incremented MII. Adjust MII so that the
         // next iteration sees the new instructions.
         MII = MI;
         ++MII;
         if (SeenMoveImm)
-          Changed |= foldImmediate(MI, &MBB, ImmDefRegs, ImmDefMIs);
+          Changed |= foldImmediate(*MI, ImmDefRegs, ImmDefMIs);
       }
 
       // Check whether MI is a load candidate for folding into a later
       // instruction. If MI is not a candidate, check whether we can fold an
       // earlier load into MI.
-      if (!isLoadFoldable(MI, FoldAsLoadDefCandidates) &&
+      if (!isLoadFoldable(*MI, FoldAsLoadDefCandidates) &&
           !FoldAsLoadDefCandidates.empty()) {
 
         // We visit each operand even after successfully folding a previous
@@ -1861,7 +1791,7 @@ bool PeepholeOptimizer::runOnMachineFunc
       // the load candidates.  Note: We might be able to fold *into* this
       // instruction, so this needs to be after the folding logic.
       if (MI->isLoadFoldBarrier()) {
-        DEBUG(dbgs() << "Encountered load fold barrier on " << *MI << "\n");
+        DEBUG(dbgs() << "Encountered load fold barrier on " << *MI);
         FoldAsLoadDefCandidates.clear();
       }
     }
@@ -1958,14 +1888,14 @@ ValueTrackerResult ValueTracker::getNext
     // duplicate the code from the generic TII.
     return ValueTrackerResult();
 
-  SmallVector<TargetInstrInfo::RegSubRegPairAndIdx, 8> RegSeqInputRegs;
+  SmallVector<RegSubRegPairAndIdx, 8> RegSeqInputRegs;
   if (!TII->getRegSequenceInputs(*Def, DefIdx, RegSeqInputRegs))
     return ValueTrackerResult();
 
   // We are looking at:
   // Def = REG_SEQUENCE v0, sub0, v1, sub1, ...
   // Check if one of the operand defines the subreg we are interested in.
-  for (auto &RegSeqInput : RegSeqInputRegs) {
+  for (const RegSubRegPairAndIdx &RegSeqInput : RegSeqInputRegs) {
     if (RegSeqInput.SubIdx == DefSubReg) {
       if (RegSeqInput.SubReg)
         // Bail if we have to compose sub registers.
@@ -1996,8 +1926,8 @@ ValueTrackerResult ValueTracker::getNext
     // duplicate the code from the generic TII.
     return ValueTrackerResult();
 
-  TargetInstrInfo::RegSubRegPair BaseReg;
-  TargetInstrInfo::RegSubRegPairAndIdx InsertedReg;
+  RegSubRegPair BaseReg;
+  RegSubRegPairAndIdx InsertedReg;
   if (!TII->getInsertSubregInputs(*Def, DefIdx, BaseReg, InsertedReg))
     return ValueTrackerResult();
 
@@ -2050,7 +1980,7 @@ ValueTrackerResult ValueTracker::getNext
     // duplicate the code from the generic TII.
     return ValueTrackerResult();
 
-  TargetInstrInfo::RegSubRegPairAndIdx ExtractSubregInputReg;
+  RegSubRegPairAndIdx ExtractSubregInputReg;
   if (!TII->getExtractSubregInputs(*Def, DefIdx, ExtractSubregInputReg))
     return ValueTrackerResult();
 
@@ -2083,7 +2013,7 @@ ValueTrackerResult ValueTracker::getNext
                             Def->getOperand(3).getImm());
 }
 
-/// \brief Explore each PHI incoming operand and return its sources
+/// Explore each PHI incoming operand and return its sources.
 ValueTrackerResult ValueTracker::getNextSourceFromPHI() {
   assert(Def->isPHI() && "Invalid definition");
   ValueTrackerResult Res;
@@ -2095,7 +2025,7 @@ ValueTrackerResult ValueTracker::getNext
 
   // Return all register sources for PHI instructions.
   for (unsigned i = 1, e = Def->getNumOperands(); i < e; i += 2) {
-    auto &MO = Def->getOperand(i);
+    const MachineOperand &MO = Def->getOperand(i);
     assert(MO.isReg() && "Invalid PHI instruction");
     // We have no code to deal with undef operands. They shouldn't happen in
     // normal programs anyway.
@@ -2121,7 +2051,7 @@ ValueTrackerResult ValueTracker::getNext
     return getNextSourceFromBitcast();
   // All the remaining cases involve "complex" instructions.
   // Bail if we did not ask for the advanced tracking.
-  if (!UseAdvancedTracking)
+  if (DisableAdvCopyOpt)
     return ValueTrackerResult();
   if (Def->isRegSequence() || Def->isRegSequenceLike())
     return getNextSourceFromRegSequence();




More information about the llvm-commits mailing list