svn commit: r470040 - in head/devel/llvm60: . files

Brooks Davis brooks at FreeBSD.org
Tue May 15 17:50:21 UTC 2018


Author: brooks
Date: Tue May 15 17:50:19 2018
New Revision: 470040
URL: https://svnweb.freebsd.org/changeset/ports/470040

Log:
  Merge r322325 from upstream.  This allows devel/godot to build in a
  reasionable abount of time:
  
  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.
  
  PR:		228261
  Reported by:	FreeBSD at ShaneWare.Biz

Added:
  head/devel/llvm60/files/patch-svn-r322325   (contents, props changed)
Modified:
  head/devel/llvm60/Makefile

Modified: head/devel/llvm60/Makefile
==============================================================================
--- head/devel/llvm60/Makefile	Tue May 15 17:39:15 2018	(r470039)
+++ head/devel/llvm60/Makefile	Tue May 15 17:50:19 2018	(r470040)
@@ -2,7 +2,7 @@
 
 PORTNAME=	llvm
 DISTVERSION=	6.0.0
-PORTREVISION=	3
+PORTREVISION=	4
 CATEGORIES=	devel lang
 MASTER_SITES=	http://${PRE_}releases.llvm.org/${LLVM_RELEASE}/${RCDIR}
 PKGNAMESUFFIX=	${LLVM_SUFFIX}

Added: head/devel/llvm60/files/patch-svn-r322325
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/devel/llvm60/files/patch-svn-r322325	Tue May 15 17:50:19 2018	(r470040)
@@ -0,0 +1,1589 @@
+r322325:
+
+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.
+
+--- lib/CodeGen/PeepholeOptimizer.cpp.orig
++++ lib/CodeGen/PeepholeOptimizer.cpp
+@@ -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 @@
+ 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 @@
+              "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 @@
+   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 @@
+       }
+     }
+ 
+-    /// \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 @@
+     /// 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 @@
+     /// 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 @@
+               (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 @@
+     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 @@
+     }
+ 
+     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 @@
+     /// 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 @@
+     /// 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 &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 @@
+ /// 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 @@
+   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 @@
+       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 @@
+       // 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 @@
+ /// 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 @@
+ }
+ 
+ /// 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 @@
+ /// 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 @@
+       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 @@
+ 
+       // 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 @@
+       // 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 @@
+ /// 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 @@
+   /// 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 @@
+     }
+ 
+     // 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 @@
+   /// 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 @@
+   }
+ };
+ 
+-/// \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 @@
+   }
+ };
+ 
+-/// \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 @@
+   ///
+   /// 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 @@
+         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 @@
+ 
+ } // 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.

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-ports-all mailing list