[llvm] 00aa081 - [NFC] Clang format PeepholeOptimizer (#116325)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Nov 17 21:28:51 PST 2024
Author: Akshat Oke
Date: 2024-11-18T10:58:48+05:30
New Revision: 00aa08119aa03ea4722196bc7d0e84a4e2a044c7
URL: https://github.com/llvm/llvm-project/commit/00aa08119aa03ea4722196bc7d0e84a4e2a044c7
DIFF: https://github.com/llvm/llvm-project/commit/00aa08119aa03ea4722196bc7d0e84a4e2a044c7.diff
LOG: [NFC] Clang format PeepholeOptimizer (#116325)
Added:
Modified:
llvm/lib/CodeGen/PeepholeOptimizer.cpp
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/PeepholeOptimizer.cpp b/llvm/lib/CodeGen/PeepholeOptimizer.cpp
index 746ec0fa9da090..12b276f01bf3c2 100644
--- a/llvm/lib/CodeGen/PeepholeOptimizer.cpp
+++ b/llvm/lib/CodeGen/PeepholeOptimizer.cpp
@@ -102,20 +102,19 @@ using RegSubRegPairAndIdx = TargetInstrInfo::RegSubRegPairAndIdx;
#define DEBUG_TYPE "peephole-opt"
// Optimize Extensions
-static cl::opt<bool>
-Aggressive("aggressive-ext-opt", cl::Hidden,
- cl::desc("Aggressive extension optimization"));
+static cl::opt<bool> Aggressive("aggressive-ext-opt", cl::Hidden,
+ cl::desc("Aggressive extension optimization"));
static cl::opt<bool>
-DisablePeephole("disable-peephole", cl::Hidden, cl::init(false),
- cl::desc("Disable the peephole optimizer"));
+ 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"));
+ DisableAdvCopyOpt("disable-adv-copy-opt", cl::Hidden, cl::init(false),
+ cl::desc("Disable advanced copy optimization"));
static cl::opt<bool> DisableNAPhysCopyOpt(
"disable-non-allocatable-phys-copy-opt", cl::Hidden, cl::init(false),
@@ -123,9 +122,9 @@ static cl::opt<bool> DisableNAPhysCopyOpt(
// Limit the number of PHI instructions to process
// in PeepholeOptimizer::getNextSource.
-static cl::opt<unsigned> RewritePHILimit(
- "rewrite-phi-limit", cl::Hidden, cl::init(10),
- cl::desc("Limit the length of PHI chains to lookup"));
+static cl::opt<unsigned>
+ RewritePHILimit("rewrite-phi-limit", cl::Hidden, cl::init(10),
+ cl::desc("Limit the length of PHI chains to lookup"));
// Limit the length of recurrence chain when evaluating the benefit of
// commuting operands.
@@ -134,7 +133,6 @@ static cl::opt<unsigned> MaxRecurrenceChain(
cl::desc("Maximum length of recurrence chain when evaluating the benefit "
"of commuting operands"));
-
STATISTIC(NumReuse, "Number of extension results reused");
STATISTIC(NumCmps, "Number of compares eliminated");
STATISTIC(NumImmFold, "Number of move immediate folded");
@@ -146,338 +144,328 @@ STATISTIC(NumNAPhysCopies, "Number of non-allocatable physical copies removed");
namespace {
- class ValueTrackerResult;
- class RecurrenceInstr;
+class ValueTrackerResult;
+class RecurrenceInstr;
- class PeepholeOptimizer : public MachineFunctionPass,
- private MachineFunction::Delegate {
- const TargetInstrInfo *TII = nullptr;
- const TargetRegisterInfo *TRI = nullptr;
- MachineRegisterInfo *MRI = nullptr;
- MachineDominatorTree *DT = nullptr; // Machine dominator tree
- MachineLoopInfo *MLI = nullptr;
+class PeepholeOptimizer : public MachineFunctionPass,
+ private MachineFunction::Delegate {
+ const TargetInstrInfo *TII = nullptr;
+ const TargetRegisterInfo *TRI = nullptr;
+ MachineRegisterInfo *MRI = nullptr;
+ MachineDominatorTree *DT = nullptr; // Machine dominator tree
+ MachineLoopInfo *MLI = nullptr;
- public:
- static char ID; // Pass identification
+public:
+ static char ID; // Pass identification
- PeepholeOptimizer() : MachineFunctionPass(ID) {
- initializePeepholeOptimizerPass(*PassRegistry::getPassRegistry());
- }
+ PeepholeOptimizer() : MachineFunctionPass(ID) {
+ initializePeepholeOptimizerPass(*PassRegistry::getPassRegistry());
+ }
- bool runOnMachineFunction(MachineFunction &MF) override;
+ bool runOnMachineFunction(MachineFunction &MF) override;
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesCFG();
- MachineFunctionPass::getAnalysisUsage(AU);
- AU.addRequired<MachineLoopInfoWrapperPass>();
- AU.addPreserved<MachineLoopInfoWrapperPass>();
- if (Aggressive) {
- AU.addRequired<MachineDominatorTreeWrapperPass>();
- AU.addPreserved<MachineDominatorTreeWrapperPass>();
- }
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesCFG();
+ MachineFunctionPass::getAnalysisUsage(AU);
+ AU.addRequired<MachineLoopInfoWrapperPass>();
+ AU.addPreserved<MachineLoopInfoWrapperPass>();
+ if (Aggressive) {
+ AU.addRequired<MachineDominatorTreeWrapperPass>();
+ AU.addPreserved<MachineDominatorTreeWrapperPass>();
}
+ }
- MachineFunctionProperties getRequiredProperties() const override {
- return MachineFunctionProperties()
- .set(MachineFunctionProperties::Property::IsSSA);
- }
+ MachineFunctionProperties getRequiredProperties() const override {
+ return MachineFunctionProperties().set(
+ MachineFunctionProperties::Property::IsSSA);
+ }
- /// Track Def -> Use info used for rewriting copies.
- using RewriteMapTy = SmallDenseMap<RegSubRegPair, ValueTrackerResult>;
+ /// Track Def -> Use info used for rewriting copies.
+ using RewriteMapTy = SmallDenseMap<RegSubRegPair, ValueTrackerResult>;
- /// Sequence of instructions that formulate recurrence cycle.
- using RecurrenceCycle = SmallVector<RecurrenceInstr, 4>;
+ /// Sequence of instructions that formulate recurrence cycle.
+ using RecurrenceCycle = SmallVector<RecurrenceInstr, 4>;
- private:
- bool optimizeCmpInstr(MachineInstr &MI);
- bool optimizeExtInstr(MachineInstr &MI, MachineBasicBlock &MBB,
- SmallPtrSetImpl<MachineInstr*> &LocalMIs);
- bool optimizeSelect(MachineInstr &MI,
+private:
+ bool optimizeCmpInstr(MachineInstr &MI);
+ bool optimizeExtInstr(MachineInstr &MI, MachineBasicBlock &MBB,
SmallPtrSetImpl<MachineInstr *> &LocalMIs);
- bool optimizeCondBranch(MachineInstr &MI);
- bool optimizeCoalescableCopy(MachineInstr &MI);
- bool optimizeUncoalescableCopy(MachineInstr &MI,
- SmallPtrSetImpl<MachineInstr *> &LocalMIs);
- bool optimizeRecurrence(MachineInstr &PHI);
- bool findNextSource(RegSubRegPair RegSubReg, RewriteMapTy &RewriteMap);
- bool isMoveImmediate(MachineInstr &MI, SmallSet<Register, 4> &ImmDefRegs,
- DenseMap<Register, MachineInstr *> &ImmDefMIs);
- bool foldImmediate(MachineInstr &MI, SmallSet<Register, 4> &ImmDefRegs,
- DenseMap<Register, MachineInstr *> &ImmDefMIs,
- bool &Deleted);
-
- /// 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
- /// along that operand as well.
- bool findTargetRecurrence(Register Reg,
- const SmallSet<Register, 2> &TargetReg,
- RecurrenceCycle &RC);
-
- /// If copy instruction \p MI is a virtual register copy or a copy of a
- /// constant physical register to a virtual register, track it in the
- /// set CopySrcMIs. 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);
-
- /// Is the register \p Reg a non-allocatable physical register?
- bool isNAPhysCopy(Register Reg);
-
- /// If copy instruction \p MI is a non-allocatable virtual<->physical
- /// register copy, track it in the \p NAPhysToVirtMIs map. If this
- /// 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, DenseMap<Register, MachineInstr *> &NAPhysToVirtMIs);
-
- bool isLoadFoldable(MachineInstr &MI,
- SmallSet<Register, 16> &FoldAsLoadDefCandidates);
-
- /// Check whether \p MI is understood by the register coalescer
- /// but may require some rewriting.
- bool isCoalescableCopy(const MachineInstr &MI) {
- // SubregToRegs are not interesting, because they are already register
- // coalescer friendly.
- return MI.isCopy() || (!DisableAdvCopyOpt &&
- (MI.isRegSequence() || MI.isInsertSubreg() ||
- MI.isExtractSubreg()));
- }
+ bool optimizeSelect(MachineInstr &MI,
+ SmallPtrSetImpl<MachineInstr *> &LocalMIs);
+ bool optimizeCondBranch(MachineInstr &MI);
+ bool optimizeCoalescableCopy(MachineInstr &MI);
+ bool optimizeUncoalescableCopy(MachineInstr &MI,
+ SmallPtrSetImpl<MachineInstr *> &LocalMIs);
+ bool optimizeRecurrence(MachineInstr &PHI);
+ bool findNextSource(RegSubRegPair RegSubReg, RewriteMapTy &RewriteMap);
+ bool isMoveImmediate(MachineInstr &MI, SmallSet<Register, 4> &ImmDefRegs,
+ DenseMap<Register, MachineInstr *> &ImmDefMIs);
+ bool foldImmediate(MachineInstr &MI, SmallSet<Register, 4> &ImmDefRegs,
+ DenseMap<Register, MachineInstr *> &ImmDefMIs,
+ bool &Deleted);
+
+ /// 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
+ /// along that operand as well.
+ bool findTargetRecurrence(Register Reg,
+ const SmallSet<Register, 2> &TargetReg,
+ RecurrenceCycle &RC);
+
+ /// If copy instruction \p MI is a virtual register copy or a copy of a
+ /// constant physical register to a virtual register, track it in the
+ /// set CopySrcMIs. 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);
+
+ /// Is the register \p Reg a non-allocatable physical register?
+ bool isNAPhysCopy(Register Reg);
+
+ /// If copy instruction \p MI is a non-allocatable virtual<->physical
+ /// register copy, track it in the \p NAPhysToVirtMIs map. If this
+ /// 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,
+ DenseMap<Register, MachineInstr *> &NAPhysToVirtMIs);
+
+ bool isLoadFoldable(MachineInstr &MI,
+ SmallSet<Register, 16> &FoldAsLoadDefCandidates);
+
+ /// Check whether \p MI is understood by the register coalescer
+ /// but may require some rewriting.
+ bool isCoalescableCopy(const MachineInstr &MI) {
+ // SubregToRegs are not interesting, because they are already register
+ // coalescer friendly.
+ return MI.isCopy() ||
+ (!DisableAdvCopyOpt && (MI.isRegSequence() || MI.isInsertSubreg() ||
+ MI.isExtractSubreg()));
+ }
- /// Check whether \p MI is a copy like instruction that is
- /// not recognized by the register coalescer.
- bool isUncoalescableCopy(const MachineInstr &MI) {
- return MI.isBitcast() ||
- (!DisableAdvCopyOpt &&
- (MI.isRegSequenceLike() || MI.isInsertSubregLike() ||
- MI.isExtractSubregLike()));
- }
+ /// Check whether \p MI is a copy like instruction that is
+ /// not recognized by the register coalescer.
+ bool isUncoalescableCopy(const MachineInstr &MI) {
+ return MI.isBitcast() || (!DisableAdvCopyOpt && (MI.isRegSequenceLike() ||
+ MI.isInsertSubregLike() ||
+ MI.isExtractSubregLike()));
+ }
- MachineInstr &rewriteSource(MachineInstr &CopyLike,
- RegSubRegPair Def, RewriteMapTy &RewriteMap);
+ MachineInstr &rewriteSource(MachineInstr &CopyLike, RegSubRegPair Def,
+ RewriteMapTy &RewriteMap);
- // Set of copies to virtual registers keyed by source register. Never
- // holds any physreg which requires def tracking.
- DenseMap<RegSubRegPair, MachineInstr *> CopySrcMIs;
+ // Set of copies to virtual registers keyed by source register. Never
+ // holds any physreg which requires def tracking.
+ DenseMap<RegSubRegPair, MachineInstr *> CopySrcMIs;
- // MachineFunction::Delegate implementation. Used to maintain CopySrcMIs.
- void MF_HandleInsertion(MachineInstr &MI) override {
- return;
- }
+ // MachineFunction::Delegate implementation. Used to maintain CopySrcMIs.
+ void MF_HandleInsertion(MachineInstr &MI) override { return; }
- bool getCopySrc(MachineInstr &MI, RegSubRegPair &SrcPair) {
- if (!MI.isCopy())
- return false;
+ bool getCopySrc(MachineInstr &MI, RegSubRegPair &SrcPair) {
+ if (!MI.isCopy())
+ return false;
- Register SrcReg = MI.getOperand(1).getReg();
- unsigned SrcSubReg = MI.getOperand(1).getSubReg();
- if (!SrcReg.isVirtual() && !MRI->isConstantPhysReg(SrcReg))
- return false;
+ Register SrcReg = MI.getOperand(1).getReg();
+ unsigned SrcSubReg = MI.getOperand(1).getSubReg();
+ if (!SrcReg.isVirtual() && !MRI->isConstantPhysReg(SrcReg))
+ return false;
- SrcPair = RegSubRegPair(SrcReg, SrcSubReg);
- return true;
- }
+ SrcPair = RegSubRegPair(SrcReg, SrcSubReg);
+ return true;
+ }
- // If a COPY instruction is to be deleted or changed, we should also remove
- // it from CopySrcMIs.
- void deleteChangedCopy(MachineInstr &MI) {
- RegSubRegPair SrcPair;
- if (!getCopySrc(MI, SrcPair))
- return;
+ // If a COPY instruction is to be deleted or changed, we should also remove
+ // it from CopySrcMIs.
+ void deleteChangedCopy(MachineInstr &MI) {
+ RegSubRegPair SrcPair;
+ if (!getCopySrc(MI, SrcPair))
+ return;
- auto It = CopySrcMIs.find(SrcPair);
- if (It != CopySrcMIs.end() && It->second == &MI)
- CopySrcMIs.erase(It);
- }
+ auto It = CopySrcMIs.find(SrcPair);
+ if (It != CopySrcMIs.end() && It->second == &MI)
+ CopySrcMIs.erase(It);
+ }
- void MF_HandleRemoval(MachineInstr &MI) override {
- deleteChangedCopy(MI);
- }
+ void MF_HandleRemoval(MachineInstr &MI) override { deleteChangedCopy(MI); }
- void MF_HandleChangeDesc(MachineInstr &MI, const MCInstrDesc &TID) override
- {
- deleteChangedCopy(MI);
- }
- };
-
- /// 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
- /// maintained with CommutePair.
- class RecurrenceInstr {
- public:
- using IndexPair = std::pair<unsigned, unsigned>;
-
- RecurrenceInstr(MachineInstr *MI) : MI(MI) {}
- RecurrenceInstr(MachineInstr *MI, unsigned Idx1, unsigned Idx2)
+ void MF_HandleChangeDesc(MachineInstr &MI, const MCInstrDesc &TID) override {
+ deleteChangedCopy(MI);
+ }
+};
+
+/// 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
+/// maintained with CommutePair.
+class RecurrenceInstr {
+public:
+ using IndexPair = std::pair<unsigned, unsigned>;
+
+ RecurrenceInstr(MachineInstr *MI) : MI(MI) {}
+ RecurrenceInstr(MachineInstr *MI, unsigned Idx1, unsigned Idx2)
: MI(MI), CommutePair(std::make_pair(Idx1, Idx2)) {}
- MachineInstr *getMI() const { return MI; }
- std::optional<IndexPair> getCommutePair() const { return CommutePair; }
+ MachineInstr *getMI() const { return MI; }
+ std::optional<IndexPair> getCommutePair() const { return CommutePair; }
- private:
- MachineInstr *MI;
- std::optional<IndexPair> CommutePair;
- };
+private:
+ MachineInstr *MI;
+ std::optional<IndexPair> CommutePair;
+};
- /// 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<RegSubRegPair, 2> RegSrcs;
+/// 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<RegSubRegPair, 2> RegSrcs;
- /// Instruction using the sources in 'RegSrcs'.
- const MachineInstr *Inst = nullptr;
+ /// Instruction using the sources in 'RegSrcs'.
+ const MachineInstr *Inst = nullptr;
- public:
- ValueTrackerResult() = default;
+public:
+ ValueTrackerResult() = default;
- ValueTrackerResult(Register Reg, unsigned SubReg) {
- addSource(Reg, SubReg);
- }
+ ValueTrackerResult(Register Reg, unsigned SubReg) { addSource(Reg, SubReg); }
- bool isValid() const { return getNumSources() > 0; }
+ bool isValid() const { return getNumSources() > 0; }
- void setInst(const MachineInstr *I) { Inst = I; }
- const MachineInstr *getInst() const { return Inst; }
+ void setInst(const MachineInstr *I) { Inst = I; }
+ const MachineInstr *getInst() const { return Inst; }
- void clear() {
- RegSrcs.clear();
- Inst = nullptr;
- }
+ void clear() {
+ RegSrcs.clear();
+ Inst = nullptr;
+ }
- void addSource(Register SrcReg, unsigned SrcSubReg) {
- RegSrcs.push_back(RegSubRegPair(SrcReg, SrcSubReg));
- }
+ void addSource(Register SrcReg, unsigned SrcSubReg) {
+ RegSrcs.push_back(RegSubRegPair(SrcReg, SrcSubReg));
+ }
- void setSource(int Idx, Register SrcReg, unsigned SrcSubReg) {
- assert(Idx < getNumSources() && "Reg pair source out of index");
- RegSrcs[Idx] = RegSubRegPair(SrcReg, SrcSubReg);
- }
+ void setSource(int Idx, Register SrcReg, unsigned SrcSubReg) {
+ assert(Idx < getNumSources() && "Reg pair source out of index");
+ RegSrcs[Idx] = RegSubRegPair(SrcReg, SrcSubReg);
+ }
- int getNumSources() const { return RegSrcs.size(); }
+ int getNumSources() const { return RegSrcs.size(); }
- RegSubRegPair getSrc(int Idx) const {
- return RegSrcs[Idx];
- }
+ RegSubRegPair getSrc(int Idx) const { return RegSrcs[Idx]; }
- Register getSrcReg(int Idx) const {
- assert(Idx < getNumSources() && "Reg source out of index");
- return RegSrcs[Idx].Reg;
- }
+ Register getSrcReg(int Idx) const {
+ assert(Idx < getNumSources() && "Reg source out of index");
+ return RegSrcs[Idx].Reg;
+ }
- unsigned getSrcSubReg(int Idx) const {
- assert(Idx < getNumSources() && "SubReg source out of index");
- return RegSrcs[Idx].SubReg;
- }
+ unsigned getSrcSubReg(int Idx) const {
+ assert(Idx < getNumSources() && "SubReg source out of index");
+ return RegSrcs[Idx].SubReg;
+ }
- bool operator==(const ValueTrackerResult &Other) const {
- if (Other.getInst() != getInst())
- return false;
+ bool operator==(const ValueTrackerResult &Other) const {
+ if (Other.getInst() != getInst())
+ return false;
+
+ if (Other.getNumSources() != getNumSources())
+ return false;
- if (Other.getNumSources() != getNumSources())
+ for (int i = 0, e = Other.getNumSources(); i != e; ++i)
+ if (Other.getSrcReg(i) != getSrcReg(i) ||
+ Other.getSrcSubReg(i) != getSrcSubReg(i))
return false;
+ return true;
+ }
+};
- for (int i = 0, e = Other.getNumSources(); i != e; ++i)
- if (Other.getSrcReg(i) != getSrcReg(i) ||
- Other.getSrcSubReg(i) != getSrcSubReg(i))
- return false;
- return true;
- }
- };
-
- /// Helper class to track the possible sources of a value defined by
- /// a (chain of) copy related instructions.
- /// Given a definition (instruction and definition index), this class
- /// follows the use-def chain to find successive suitable sources.
- /// The given source can be used to rewrite the definition into
- /// def = COPY src.
- ///
- /// For instance, let us consider the following snippet:
- /// v0 =
- /// v2 = INSERT_SUBREG v1, v0, sub0
- /// def = COPY v2.sub0
- ///
- /// Using a ValueTracker for def = COPY v2.sub0 will give the following
- /// suitable sources:
- /// v2.sub0 and v0.
- /// Then, def can be rewritten into def = COPY v0.
- class ValueTracker {
- private:
- /// The current point into the use-def chain.
- const MachineInstr *Def = nullptr;
-
- /// The index of the definition in Def.
- unsigned DefIdx = 0;
-
- /// The sub register index of the definition.
- unsigned DefSubReg;
-
- /// The register where the value can be found.
- Register Reg;
-
- /// MachineRegisterInfo used to perform tracking.
- const MachineRegisterInfo &MRI;
-
- /// Optional TargetInstrInfo used to perform some complex tracking.
- const TargetInstrInfo *TII;
-
- /// Dispatcher to the right underlying implementation of getNextSource.
- ValueTrackerResult getNextSourceImpl();
-
- /// Specialized version of getNextSource for Copy instructions.
- ValueTrackerResult getNextSourceFromCopy();
-
- /// Specialized version of getNextSource for Bitcast instructions.
- ValueTrackerResult getNextSourceFromBitcast();
-
- /// Specialized version of getNextSource for RegSequence instructions.
- ValueTrackerResult getNextSourceFromRegSequence();
-
- /// Specialized version of getNextSource for InsertSubreg instructions.
- ValueTrackerResult getNextSourceFromInsertSubreg();
-
- /// Specialized version of getNextSource for ExtractSubreg instructions.
- ValueTrackerResult getNextSourceFromExtractSubreg();
-
- /// Specialized version of getNextSource for SubregToReg instructions.
- ValueTrackerResult getNextSourceFromSubregToReg();
-
- /// Specialized version of getNextSource for PHI instructions.
- ValueTrackerResult getNextSourceFromPHI();
-
- public:
- /// 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.
- /// 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
- /// know which definition of \p Reg it should track.
- /// Use the next constructor to track a physical register.
- ValueTracker(Register Reg, unsigned DefSubReg,
- const MachineRegisterInfo &MRI,
- const TargetInstrInfo *TII = nullptr)
- : DefSubReg(DefSubReg), Reg(Reg), MRI(MRI), TII(TII) {
- if (!Reg.isPhysical()) {
- Def = MRI.getVRegDef(Reg);
- DefIdx = MRI.def_begin(Reg).getOperandNo();
- }
+/// Helper class to track the possible sources of a value defined by
+/// a (chain of) copy related instructions.
+/// Given a definition (instruction and definition index), this class
+/// follows the use-def chain to find successive suitable sources.
+/// The given source can be used to rewrite the definition into
+/// def = COPY src.
+///
+/// For instance, let us consider the following snippet:
+/// v0 =
+/// v2 = INSERT_SUBREG v1, v0, sub0
+/// def = COPY v2.sub0
+///
+/// Using a ValueTracker for def = COPY v2.sub0 will give the following
+/// suitable sources:
+/// v2.sub0 and v0.
+/// Then, def can be rewritten into def = COPY v0.
+class ValueTracker {
+private:
+ /// The current point into the use-def chain.
+ const MachineInstr *Def = nullptr;
+
+ /// The index of the definition in Def.
+ unsigned DefIdx = 0;
+
+ /// The sub register index of the definition.
+ unsigned DefSubReg;
+
+ /// The register where the value can be found.
+ Register Reg;
+
+ /// MachineRegisterInfo used to perform tracking.
+ const MachineRegisterInfo &MRI;
+
+ /// Optional TargetInstrInfo used to perform some complex tracking.
+ const TargetInstrInfo *TII;
+
+ /// Dispatcher to the right underlying implementation of getNextSource.
+ ValueTrackerResult getNextSourceImpl();
+
+ /// Specialized version of getNextSource for Copy instructions.
+ ValueTrackerResult getNextSourceFromCopy();
+
+ /// Specialized version of getNextSource for Bitcast instructions.
+ ValueTrackerResult getNextSourceFromBitcast();
+
+ /// Specialized version of getNextSource for RegSequence instructions.
+ ValueTrackerResult getNextSourceFromRegSequence();
+
+ /// Specialized version of getNextSource for InsertSubreg instructions.
+ ValueTrackerResult getNextSourceFromInsertSubreg();
+
+ /// Specialized version of getNextSource for ExtractSubreg instructions.
+ ValueTrackerResult getNextSourceFromExtractSubreg();
+
+ /// Specialized version of getNextSource for SubregToReg instructions.
+ ValueTrackerResult getNextSourceFromSubregToReg();
+
+ /// Specialized version of getNextSource for PHI instructions.
+ ValueTrackerResult getNextSourceFromPHI();
+
+public:
+ /// 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.
+ /// 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
+ /// know which definition of \p Reg it should track.
+ /// Use the next constructor to track a physical register.
+ ValueTracker(Register Reg, unsigned DefSubReg, const MachineRegisterInfo &MRI,
+ const TargetInstrInfo *TII = nullptr)
+ : DefSubReg(DefSubReg), Reg(Reg), MRI(MRI), TII(TII) {
+ if (!Reg.isPhysical()) {
+ Def = MRI.getVRegDef(Reg);
+ DefIdx = MRI.def_begin(Reg).getOperandNo();
}
+ }
- /// 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();
- };
+ /// 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();
+};
} // end anonymous namespace
@@ -485,12 +473,12 @@ char PeepholeOptimizer::ID = 0;
char &llvm::PeepholeOptimizerID = PeepholeOptimizer::ID;
-INITIALIZE_PASS_BEGIN(PeepholeOptimizer, DEBUG_TYPE,
- "Peephole Optimizations", false, false)
+INITIALIZE_PASS_BEGIN(PeepholeOptimizer, DEBUG_TYPE, "Peephole Optimizations",
+ false, false)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass)
-INITIALIZE_PASS_END(PeepholeOptimizer, DEBUG_TYPE,
- "Peephole Optimizations", false, false)
+INITIALIZE_PASS_END(PeepholeOptimizer, DEBUG_TYPE, "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
@@ -500,9 +488,9 @@ INITIALIZE_PASS_END(PeepholeOptimizer, DEBUG_TYPE,
/// Do not generate an EXTRACT that is used only in a debug use, as this changes
/// the code. Since this code does not currently share EXTRACTs, just ignore all
/// debug uses.
-bool PeepholeOptimizer::
-optimizeExtInstr(MachineInstr &MI, MachineBasicBlock &MBB,
- SmallPtrSetImpl<MachineInstr*> &LocalMIs) {
+bool PeepholeOptimizer::optimizeExtInstr(
+ MachineInstr &MI, MachineBasicBlock &MBB,
+ SmallPtrSetImpl<MachineInstr *> &LocalMIs) {
Register SrcReg, DstReg;
unsigned SubIdx;
if (!TII->isCoalescableExtInstr(MI, SrcReg, DstReg, SubIdx))
@@ -532,15 +520,15 @@ optimizeExtInstr(MachineInstr &MI, MachineBasicBlock &MBB,
// The source has other uses. See if we can replace the other uses with use of
// the result of the extension.
- SmallPtrSet<MachineBasicBlock*, 4> ReachedBBs;
+ SmallPtrSet<MachineBasicBlock *, 4> ReachedBBs;
for (MachineInstr &UI : MRI->use_nodbg_instructions(DstReg))
ReachedBBs.insert(UI.getParent());
// Uses that are in the same BB of uses of the result of the instruction.
- SmallVector<MachineOperand*, 8> Uses;
+ SmallVector<MachineOperand *, 8> Uses;
// Uses that the result of the instruction can reach.
- SmallVector<MachineOperand*, 8> ExtendedUses;
+ SmallVector<MachineOperand *, 8> ExtendedUses;
bool ExtendLife = true;
for (MachineOperand &UseMO : MRI->use_nodbg_operands(SrcReg)) {
@@ -605,7 +593,7 @@ optimizeExtInstr(MachineInstr &MI, MachineBasicBlock &MBB,
// Now replace all uses.
bool Changed = false;
if (!Uses.empty()) {
- SmallPtrSet<MachineBasicBlock*, 4> PHIBBs;
+ SmallPtrSet<MachineBasicBlock *, 4> PHIBBs;
// Look for PHI uses of the extended result, we don't want to extend the
// liveness of a PHI input. It breaks all kinds of assumptions down
@@ -647,7 +635,7 @@ optimizeExtInstr(MachineInstr &MI, MachineBasicBlock &MBB,
Register NewVR = MRI->createVirtualRegister(RC);
BuildMI(*UseMBB, UseMI, UseMI->getDebugLoc(),
TII->get(TargetOpcode::COPY), NewVR)
- .addReg(DstReg, 0, SubIdx);
+ .addReg(DstReg, 0, SubIdx);
if (UseSrcSubIdx)
UseMO->setSubReg(0);
@@ -685,8 +673,8 @@ bool PeepholeOptimizer::optimizeCmpInstr(MachineInstr &MI) {
}
/// Optimize a select instruction.
-bool PeepholeOptimizer::optimizeSelect(MachineInstr &MI,
- SmallPtrSetImpl<MachineInstr *> &LocalMIs) {
+bool PeepholeOptimizer::optimizeSelect(
+ MachineInstr &MI, SmallPtrSetImpl<MachineInstr *> &LocalMIs) {
unsigned TrueOp = 0;
unsigned FalseOp = 0;
bool Optimizable = false;
@@ -814,10 +802,10 @@ bool PeepholeOptimizer::findNextSource(RegSubRegPair RegSubReg,
/// 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<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);
@@ -849,7 +837,7 @@ namespace {
class Rewriter {
protected:
MachineInstr &CopyLike;
- unsigned CurrentSrcIdx = 0; ///< The index of the source being rewritten.
+ unsigned CurrentSrcIdx = 0; ///< The index of the source being rewritten.
public:
Rewriter(MachineInstr &CopyLike) : CopyLike(CopyLike) {}
virtual ~Rewriter() = default;
@@ -925,7 +913,7 @@ class CopyRewriter : public Rewriter {
/// Helper class to rewrite uncoalescable copy like instructions
/// into new COPY (coalescable friendly) instructions.
class UncoalescableRewriter : public Rewriter {
- unsigned NumDefs; ///< Number of defs in the bitcast.
+ unsigned NumDefs; ///< Number of defs in the bitcast.
public:
UncoalescableRewriter(MachineInstr &MI) : Rewriter(MI) {
@@ -1039,8 +1027,8 @@ class ExtractSubregRewriter : public Rewriter {
if (MOExtractedReg.getSubReg())
return false;
- Src = RegSubRegPair(MOExtractedReg.getReg(),
- 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);
@@ -1281,9 +1269,9 @@ bool PeepholeOptimizer::optimizeCoalescableCopy(MachineInstr &MI) {
/// 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) {
+MachineInstr &PeepholeOptimizer::rewriteSource(MachineInstr &CopyLike,
+ RegSubRegPair Def,
+ RewriteMapTy &RewriteMap) {
assert(!Def.Reg.isPhysical() && "We do not rewrite physical registers");
// Find the new source to use in the COPY rewrite.
@@ -1685,7 +1673,7 @@ bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) {
// To perform this, the following set keeps track of the MIs already seen
// during the scan, if a MI is not in the set, it is assumed to be located
// after. Newly created MIs have to be inserted in the set as well.
- SmallPtrSet<MachineInstr*, 16> LocalMIs;
+ SmallPtrSet<MachineInstr *, 16> LocalMIs;
SmallSet<Register, 4> ImmDefRegs;
DenseMap<Register, MachineInstr *> ImmDefMIs;
SmallSet<Register, 16> FoldAsLoadDefCandidates;
@@ -1702,7 +1690,7 @@ bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) {
bool IsLoopHeader = MLI->isLoopHeader(&MBB);
for (MachineBasicBlock::iterator MII = MBB.begin(), MIE = MBB.end();
- MII != MIE; ) {
+ MII != MIE;) {
MachineInstr *MI = &*MII;
// We may be erasing MI below, increment MII now.
++MII;
@@ -1826,8 +1814,7 @@ bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) {
// foldable uses earlier in the argument list. Since we don't restart
// iteration, we'd miss such cases.
const MCInstrDesc &MIDesc = MI->getDesc();
- for (unsigned i = MIDesc.getNumDefs(); i != MI->getNumOperands();
- ++i) {
+ for (unsigned i = MIDesc.getNumDefs(); i != MI->getNumOperands(); ++i) {
const MachineOperand &MOp = MI->getOperand(i);
if (!MOp.isReg())
continue;
@@ -2038,9 +2025,9 @@ ValueTrackerResult ValueTracker::getNextSourceFromInsertSubreg() {
// Get the TRI and check if the inserted sub-register overlaps with the
// sub-register we are tracking.
const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
- if (!TRI ||
- !(TRI->getSubRegIndexLaneMask(DefSubReg) &
- TRI->getSubRegIndexLaneMask(InsertedReg.SubIdx)).none())
+ if (!TRI || !(TRI->getSubRegIndexLaneMask(DefSubReg) &
+ TRI->getSubRegIndexLaneMask(InsertedReg.SubIdx))
+ .none())
return ValueTrackerResult();
// At this point, the value is available in v0 via the same subreg
// we used for Def.
@@ -2048,8 +2035,8 @@ ValueTrackerResult ValueTracker::getNextSourceFromInsertSubreg() {
}
ValueTrackerResult ValueTracker::getNextSourceFromExtractSubreg() {
- assert((Def->isExtractSubreg() ||
- Def->isExtractSubregLike()) && "Invalid definition");
+ assert((Def->isExtractSubreg() || Def->isExtractSubregLike()) &&
+ "Invalid definition");
// We are looking at:
// Def = EXTRACT_SUBREG v0, sub0
More information about the llvm-commits
mailing list