diff options
Diffstat (limited to 'lib/CodeGen/PeepholeOptimizer.cpp')
-rw-r--r-- | lib/CodeGen/PeepholeOptimizer.cpp | 95 |
1 files changed, 57 insertions, 38 deletions
diff --git a/lib/CodeGen/PeepholeOptimizer.cpp b/lib/CodeGen/PeepholeOptimizer.cpp index b13f6b68c420..45078081987a 100644 --- a/lib/CodeGen/PeepholeOptimizer.cpp +++ b/lib/CodeGen/PeepholeOptimizer.cpp @@ -1,4 +1,4 @@ -//===-- PeepholeOptimizer.cpp - Peephole Optimizations --------------------===// +//===- PeepholeOptimizer.cpp - Peephole Optimizations ---------------------===// // // The LLVM Compiler Infrastructure // @@ -67,6 +67,7 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" @@ -74,20 +75,23 @@ #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/CodeGen/Passes.h" +#include "llvm/CodeGen/TargetInstrInfo.h" +#include "llvm/CodeGen/TargetOpcodes.h" +#include "llvm/CodeGen/TargetRegisterInfo.h" +#include "llvm/CodeGen/TargetSubtargetInfo.h" +#include "llvm/MC/LaneBitmask.h" #include "llvm/MC/MCInstrDesc.h" +#include "llvm/Pass.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/Target/TargetSubtargetInfo.h" #include <cassert> #include <cstdint> #include <memory> @@ -170,11 +174,11 @@ namespace { } /// \brief Track Def -> Use info used for rewriting copies. - typedef SmallDenseMap<TargetInstrInfo::RegSubRegPair, ValueTrackerResult> - RewriteMapTy; + using RewriteMapTy = + SmallDenseMap<TargetInstrInfo::RegSubRegPair, ValueTrackerResult>; /// \brief Sequence of instructions that formulate recurrence cycle. - typedef SmallVector<RecurrenceInstr, 4> RecurrenceCycle; + using RecurrenceCycle = SmallVector<RecurrenceInstr, 4>; private: bool optimizeCmpInstr(MachineInstr *MI, MachineBasicBlock *MBB); @@ -195,6 +199,7 @@ namespace { bool foldImmediate(MachineInstr *MI, MachineBasicBlock *MBB, SmallSet<unsigned, 4> &ImmDefRegs, DenseMap<unsigned, MachineInstr*> &ImmDefMIs); + /// \brief Finds recurrence cycles, but only ones that formulated around /// a def operand and a use operand that are tied. If there is a use /// operand commutable with the tied use operand, find recurrence cycle @@ -254,7 +259,7 @@ namespace { /// maintained with CommutePair. class RecurrenceInstr { public: - typedef std::pair<unsigned, unsigned> IndexPair; + using IndexPair = std::pair<unsigned, unsigned>; RecurrenceInstr(MachineInstr *MI) : MI(MI) {} RecurrenceInstr(MachineInstr *MI, unsigned Idx1, unsigned Idx2) @@ -277,11 +282,12 @@ namespace { SmallVector<TargetInstrInfo::RegSubRegPair, 2> RegSrcs; /// Instruction using the sources in 'RegSrcs'. - const MachineInstr *Inst; + const MachineInstr *Inst = nullptr; public: - ValueTrackerResult() : Inst(nullptr) {} - ValueTrackerResult(unsigned Reg, unsigned SubReg) : Inst(nullptr) { + ValueTrackerResult() = default; + + ValueTrackerResult(unsigned Reg, unsigned SubReg) { addSource(Reg, SubReg); } @@ -350,13 +356,17 @@ namespace { class ValueTracker { private: /// The current point into the use-def chain. - const MachineInstr *Def; + const MachineInstr *Def = nullptr; + /// The index of the definition in Def. - unsigned DefIdx; + unsigned DefIdx = 0; + /// The sub register index of the definition. unsigned DefSubReg; + /// 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. @@ -365,8 +375,10 @@ namespace { /// 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. const TargetInstrInfo *TII; @@ -374,22 +386,29 @@ namespace { /// \brief Dispatcher to the right underlying implementation of /// getNextSource. ValueTrackerResult getNextSourceImpl(); + /// \brief Specialized version of getNextSource for Copy instructions. ValueTrackerResult getNextSourceFromCopy(); + /// \brief Specialized version of getNextSource for Bitcast instructions. ValueTrackerResult getNextSourceFromBitcast(); + /// \brief Specialized version of getNextSource for RegSequence /// instructions. ValueTrackerResult getNextSourceFromRegSequence(); + /// \brief Specialized version of getNextSource for InsertSubreg /// instructions. ValueTrackerResult getNextSourceFromInsertSubreg(); + /// \brief Specialized version of getNextSource for ExtractSubreg /// instructions. ValueTrackerResult getNextSourceFromExtractSubreg(); + /// \brief Specialized version of getNextSource for SubregToReg /// instructions. ValueTrackerResult getNextSourceFromSubregToReg(); + /// \brief Specialized version of getNextSource for PHI instructions. ValueTrackerResult getNextSourceFromPHI(); @@ -410,7 +429,7 @@ namespace { const MachineRegisterInfo &MRI, bool UseAdvancedTracking = false, const TargetInstrInfo *TII = nullptr) - : Def(nullptr), DefIdx(0), DefSubReg(DefSubReg), Reg(Reg), + : DefSubReg(DefSubReg), Reg(Reg), UseAdvancedTracking(UseAdvancedTracking), MRI(MRI), TII(TII) { if (!TargetRegisterInfo::isPhysicalRegister(Reg)) { Def = MRI.getVRegDef(Reg); @@ -453,6 +472,7 @@ namespace { } // end anonymous namespace char PeepholeOptimizer::ID = 0; + char &llvm::PeepholeOptimizerID = PeepholeOptimizer::ID; INITIALIZE_PASS_BEGIN(PeepholeOptimizer, DEBUG_TYPE, @@ -659,7 +679,7 @@ bool PeepholeOptimizer::optimizeSelect(MachineInstr *MI, } /// \brief Check if a simpler conditional branch can be -// generated +/// generated bool PeepholeOptimizer::optimizeCondBranch(MachineInstr *MI) { return TII->optimizeCondBranch(*MI); } @@ -805,13 +825,13 @@ class CopyRewriter { protected: /// The copy-like instruction. MachineInstr &CopyLike; + /// The index of the source being rewritten. - unsigned CurrentSrcIdx; + unsigned CurrentSrcIdx = 0; public: - CopyRewriter(MachineInstr &MI) : CopyLike(MI), CurrentSrcIdx(0) {} - - virtual ~CopyRewriter() {} + CopyRewriter(MachineInstr &MI) : CopyLike(MI) {} + virtual ~CopyRewriter() = default; /// \brief Get the next rewritable source (SrcReg, SrcSubReg) and /// the related value that it affects (TrackReg, TrackSubReg). @@ -944,6 +964,7 @@ class UncoalescableRewriter : public CopyRewriter { protected: const TargetInstrInfo &TII; MachineRegisterInfo &MRI; + /// The number of defs in the bitcast unsigned NumDefs; @@ -958,7 +979,6 @@ public: /// 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 { @@ -1205,7 +1225,7 @@ public: } }; -} // end anonymous namespace +} // end anonymous namespace /// \brief Get the appropriated CopyRewriter for \p MI. /// \return A pointer to a dynamically allocated CopyRewriter or nullptr @@ -1433,10 +1453,10 @@ bool PeepholeOptimizer::foldImmediate( // only the first copy is considered. // // e.g. -// %vreg1 = COPY %vreg0 -// %vreg2 = COPY %vreg0:sub1 +// %1 = COPY %0 +// %2 = COPY %0:sub1 // -// Should replace %vreg2 uses with %vreg1:sub1 +// Should replace %2 uses with %1:sub1 bool PeepholeOptimizer::foldRedundantCopy( MachineInstr *MI, SmallSet<unsigned, 4> &CopySrcRegs, DenseMap<unsigned, MachineInstr *> &CopyMIs) { @@ -1496,7 +1516,7 @@ bool PeepholeOptimizer::foldRedundantNAPhysCopy( unsigned DstReg = MI->getOperand(0).getReg(); unsigned SrcReg = MI->getOperand(1).getReg(); if (isNAPhysCopy(SrcReg) && TargetRegisterInfo::isVirtualRegister(DstReg)) { - // %vreg = COPY %PHYSREG + // %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}); @@ -1506,7 +1526,7 @@ bool PeepholeOptimizer::foldRedundantNAPhysCopy( if (!(TargetRegisterInfo::isVirtualRegister(SrcReg) && isNAPhysCopy(DstReg))) return false; - // %PHYSREG = COPY %vreg + // %physreg = COPY %vreg auto PrevCopy = NAPhysToVirtMIs.find(DstReg); if (PrevCopy == NAPhysToVirtMIs.end()) { // We can't remove the copy: there was an intervening clobber of the @@ -1601,16 +1621,16 @@ bool PeepholeOptimizer::findTargetRecurrence( /// from the phi. For example, if there is a recurrence of /// /// LoopHeader: -/// %vreg1 = phi(%vreg0, %vreg100) +/// %1 = phi(%0, %100) /// LoopLatch: -/// %vreg0<def, tied1> = ADD %vreg2<def, tied0>, %vreg1 +/// %0<def, tied1> = ADD %2<def, tied0>, %1 /// -/// , the fact that vreg0 and vreg2 are in the same tied operands set makes +/// , the fact that %0 and %2 are in the same tied operands set makes /// the coalescing of copy instruction generated from the phi in -/// LoopHeader(i.e. %vreg1 = COPY %vreg0) impossible, because %vreg1 and -/// %vreg2 have overlapping live range. This introduces additional move -/// instruction to the final assembly. However, if we commute %vreg2 and -/// %vreg1 of ADD instruction, the redundant move instruction can be +/// LoopHeader(i.e. %1 = COPY %0) impossible, because %1 and +/// %2 have overlapping live range. This introduces additional move +/// instruction to the final assembly. However, if we commute %2 and +/// %1 of ADD instruction, the redundant move instruction can be /// avoided. bool PeepholeOptimizer::optimizeRecurrence(MachineInstr &PHI) { SmallSet<unsigned, 2> TargetRegs; @@ -1642,7 +1662,7 @@ bool PeepholeOptimizer::optimizeRecurrence(MachineInstr &PHI) { } bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) { - if (skipFunction(*MF.getFunction())) + if (skipFunction(MF.getFunction())) return false; DEBUG(dbgs() << "********** PEEPHOLE OPTIMIZER **********\n"); @@ -1676,8 +1696,8 @@ bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) { // Track when a non-allocatable physical register is copied to a virtual // register so that useless moves can be removed. // - // %PHYSREG is the map index; MI is the last valid `%vreg = COPY %PHYSREG` - // without any intervening re-definition of %PHYSREG. + // %physreg is the map index; MI is the last valid `%vreg = COPY %physreg` + // without any intervening re-definition of %physreg. DenseMap<unsigned, MachineInstr *> NAPhysToVirtMIs; // Set of virtual registers that are copied from. @@ -1847,7 +1867,6 @@ bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) { DEBUG(dbgs() << "Encountered load fold barrier on " << *MI << "\n"); FoldAsLoadDefCandidates.clear(); } - } } |