aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/MachineCombiner.cpp
diff options
context:
space:
mode:
authorGuozhi Wei <carrot@google.com>2022-07-14 17:04:44 +0000
committerGuozhi Wei <carrot@google.com>2022-07-14 17:08:14 +0000
commit2f11b3a6d7b8083be570f79f4ca18dfb2648eda3 (patch)
tree18d333d01be5b8ee38efae2c95627b6aee22ea2b /llvm/lib/CodeGen/MachineCombiner.cpp
parentf48ce52c4c2de8dc80e1bdd5caebbdb9f9db00ce (diff)
downloadllvm-2f11b3a6d7b8083be570f79f4ca18dfb2648eda3.zip
llvm-2f11b3a6d7b8083be570f79f4ca18dfb2648eda3.tar.gz
llvm-2f11b3a6d7b8083be570f79f4ca18dfb2648eda3.tar.bz2
[MachineCombiner] Don't compute the latency of transient instructions
If an MI will not generate a target instruction, we should not compute its latency. Then we can compute more precise instruction sequence cost, and get better result. Differential Revision: https://reviews.llvm.org/D129615
Diffstat (limited to 'llvm/lib/CodeGen/MachineCombiner.cpp')
-rw-r--r--llvm/lib/CodeGen/MachineCombiner.cpp45
1 files changed, 42 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/MachineCombiner.cpp b/llvm/lib/CodeGen/MachineCombiner.cpp
index 722a709..294a57d 100644
--- a/llvm/lib/CodeGen/MachineCombiner.cpp
+++ b/llvm/lib/CodeGen/MachineCombiner.cpp
@@ -92,6 +92,7 @@ private:
bool doSubstitute(unsigned NewSize, unsigned OldSize, bool OptForSize);
bool combineInstructions(MachineBasicBlock *);
MachineInstr *getOperandDef(const MachineOperand &MO);
+ bool isTransientMI(const MachineInstr *MI);
unsigned getDepth(SmallVectorImpl<MachineInstr *> &InsInstrs,
DenseMap<unsigned, unsigned> &InstrIdxForVirtReg,
MachineTraceMetrics::Trace BlockTrace);
@@ -158,6 +159,43 @@ MachineInstr *MachineCombiner::getOperandDef(const MachineOperand &MO) {
return DefInstr;
}
+/// Return true if MI is unlikely to generate an actual target instruction.
+bool MachineCombiner::isTransientMI(const MachineInstr *MI) {
+ if (!MI->isCopy())
+ return MI->isTransient();
+
+ // If MI is a COPY, check if its src and dst registers can be coalesced.
+ Register Dst = MI->getOperand(0).getReg();
+ Register Src = MI->getOperand(1).getReg();
+
+ if (!MI->isFullCopy()) {
+ // If src RC contains super registers of dst RC, it can also be coalesced.
+ if (MI->getOperand(0).getSubReg() || Src.isPhysical() || Dst.isPhysical())
+ return false;
+
+ auto SrcSub = MI->getOperand(1).getSubReg();
+ auto SrcRC = MRI->getRegClass(Src);
+ auto DstRC = MRI->getRegClass(Dst);
+ return TRI->getMatchingSuperRegClass(SrcRC, DstRC, SrcSub) != nullptr;
+ }
+
+ if (Src.isPhysical() && Dst.isPhysical())
+ return Src == Dst;
+
+ if (Src.isVirtual() && Dst.isVirtual()) {
+ auto SrcRC = MRI->getRegClass(Src);
+ auto DstRC = MRI->getRegClass(Dst);
+ return SrcRC->hasSuperClassEq(DstRC) || SrcRC->hasSubClassEq(DstRC);
+ }
+
+ if (Src.isVirtual())
+ std::swap(Src, Dst);
+
+ // Now Src is physical register, Dst is virtual register.
+ auto DstRC = MRI->getRegClass(Dst);
+ return DstRC->contains(Src);
+}
+
/// Computes depth of instructions in vector \InsInstr.
///
/// \param InsInstrs is a vector of machine instructions
@@ -204,9 +242,10 @@ MachineCombiner::getDepth(SmallVectorImpl<MachineInstr *> &InsInstrs,
MachineInstr *DefInstr = getOperandDef(MO);
if (DefInstr) {
DepthOp = BlockTrace.getInstrCycles(*DefInstr).Depth;
- LatencyOp = TSchedModel.computeOperandLatency(
- DefInstr, DefInstr->findRegisterDefOperandIdx(MO.getReg()),
- InstrPtr, InstrPtr->findRegisterUseOperandIdx(MO.getReg()));
+ if (!isTransientMI(DefInstr))
+ LatencyOp = TSchedModel.computeOperandLatency(
+ DefInstr, DefInstr->findRegisterDefOperandIdx(MO.getReg()),
+ InstrPtr, InstrPtr->findRegisterUseOperandIdx(MO.getReg()));
}
}
IDepth = std::max(IDepth, DepthOp + LatencyOp);