summaryrefslogtreecommitdiff
path: root/lib/CodeGen/PeepholeOptimizer.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-12-18 20:10:56 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-12-18 20:10:56 +0000
commit044eb2f6afba375a914ac9d8024f8f5142bb912e (patch)
tree1475247dc9f9fe5be155ebd4c9069c75aadf8c20 /lib/CodeGen/PeepholeOptimizer.cpp
parenteb70dddbd77e120e5d490bd8fbe7ff3f8fa81c6b (diff)
Notes
Diffstat (limited to 'lib/CodeGen/PeepholeOptimizer.cpp')
-rw-r--r--lib/CodeGen/PeepholeOptimizer.cpp95
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();
}
-
}
}