summaryrefslogtreecommitdiff
path: root/devel/llvm60/files/patch-svn-r322325
diff options
context:
space:
mode:
Diffstat (limited to 'devel/llvm60/files/patch-svn-r322325')
-rw-r--r--devel/llvm60/files/patch-svn-r3223251589
1 files changed, 0 insertions, 1589 deletions
diff --git a/devel/llvm60/files/patch-svn-r322325 b/devel/llvm60/files/patch-svn-r322325
deleted file mode 100644
index 3b0501e37022..000000000000
--- a/devel/llvm60/files/patch-svn-r322325
+++ /dev/null
@@ -1,1589 +0,0 @@
-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.
-+/// \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 @@
- 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 @@
- 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 @@
- /// 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 @@
- /// 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::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 @@
- /// 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 @@
- 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 @@
- // %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::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 @@
- 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 @@
- 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 @@
- // 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 @@
- 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 @@
- }
-
- 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 @@
- // 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 @@
- // 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 @@
- // 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 @@
- // 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 @@
- // 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 @@
- 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 @@
-
- // 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 @@
- 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();