aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/CodeGen/EarlyIfConversion.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-06-13 19:31:46 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-06-13 19:37:19 +0000
commite8d8bef961a50d4dc22501cde4fb9fb0be1b2532 (patch)
tree94f04805f47bb7c59ae29690d8952b6074fff602 /contrib/llvm-project/llvm/lib/CodeGen/EarlyIfConversion.cpp
parentbb130ff39747b94592cb26d71b7cb097b9a4ea6b (diff)
parentb60736ec1405bb0a8dd40989f67ef4c93da068ab (diff)
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/EarlyIfConversion.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/EarlyIfConversion.cpp106
1 files changed, 98 insertions, 8 deletions
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/EarlyIfConversion.cpp b/contrib/llvm-project/llvm/lib/CodeGen/EarlyIfConversion.cpp
index 96d4efb856c1..cf7d93d6a33a 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/EarlyIfConversion.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/EarlyIfConversion.cpp
@@ -27,6 +27,7 @@
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
+#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/MachineTraceMetrics.h"
#include "llvm/CodeGen/Passes.h"
@@ -264,7 +265,8 @@ bool SSAIfConv::InstrDependenciesAllowIfConv(MachineInstr *I) {
// Remember clobbered regunits.
if (MO.isDef() && Register::isPhysicalRegister(Reg))
- for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units)
+ for (MCRegUnitIterator Units(Reg.asMCReg(), TRI); Units.isValid();
+ ++Units)
ClobberedRegUnits.set(*Units);
if (!MO.readsReg() || !Register::isVirtualRegister(Reg))
@@ -363,7 +365,7 @@ bool SSAIfConv::findInsertionPoint() {
// Keep track of live regunits before the current position.
// Only track RegUnits that are also in ClobberedRegUnits.
LiveRegUnits.clear();
- SmallVector<unsigned, 8> Reads;
+ SmallVector<MCRegister, 8> Reads;
MachineBasicBlock::iterator FirstTerm = Head->getFirstTerminator();
MachineBasicBlock::iterator I = Head->end();
MachineBasicBlock::iterator B = Head->begin();
@@ -385,11 +387,12 @@ bool SSAIfConv::findInsertionPoint() {
continue;
// I clobbers Reg, so it isn't live before I.
if (MO.isDef())
- for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units)
+ for (MCRegUnitIterator Units(Reg.asMCReg(), TRI); Units.isValid();
+ ++Units)
LiveRegUnits.erase(*Units);
// Unless I reads Reg.
if (MO.readsReg())
- Reads.push_back(Reg);
+ Reads.push_back(Reg.asMCReg());
}
// Anything read by I is live before I.
while (!Reads.empty())
@@ -794,6 +797,17 @@ static unsigned adjCycles(unsigned Cyc, int Delta) {
return Cyc + Delta;
}
+namespace {
+/// Helper class to simplify emission of cycle counts into optimization remarks.
+struct Cycles {
+ const char *Key;
+ unsigned Value;
+};
+template <typename Remark> Remark &operator<<(Remark &R, Cycles C) {
+ return R << ore::NV(C.Key, C.Value) << (C.Value == 1 ? " cycle" : " cycles");
+}
+} // anonymous namespace
+
/// Apply cost model and heuristics to the if-conversion in IfConv.
/// Return true if the conversion is a good idea.
///
@@ -814,6 +828,9 @@ bool EarlyIfConverter::shouldConvertIf() {
// Set a somewhat arbitrary limit on the critical path extension we accept.
unsigned CritLimit = SchedModel.MispredictPenalty/2;
+ MachineBasicBlock &MBB = *IfConv.Head;
+ MachineOptimizationRemarkEmitter MORE(*MBB.getParent(), nullptr);
+
// If-conversion only makes sense when there is unexploited ILP. Compute the
// maximum-ILP resource length of the trace after if-conversion. Compare it
// to the shortest critical path.
@@ -825,6 +842,17 @@ bool EarlyIfConverter::shouldConvertIf() {
<< ", minimal critical path " << MinCrit << '\n');
if (ResLength > MinCrit + CritLimit) {
LLVM_DEBUG(dbgs() << "Not enough available ILP.\n");
+ MORE.emit([&]() {
+ MachineOptimizationRemarkMissed R(DEBUG_TYPE, "IfConversion",
+ MBB.findDebugLoc(MBB.back()), &MBB);
+ R << "did not if-convert branch: the resulting critical path ("
+ << Cycles{"ResLength", ResLength}
+ << ") would extend the shorter leg's critical path ("
+ << Cycles{"MinCrit", MinCrit} << ") by more than the threshold of "
+ << Cycles{"CritLimit", CritLimit}
+ << ", which cannot be hidden by available ILP.";
+ return R;
+ });
return false;
}
@@ -839,6 +867,14 @@ bool EarlyIfConverter::shouldConvertIf() {
// Look at all the tail phis, and compute the critical path extension caused
// by inserting select instructions.
MachineTraceMetrics::Trace TailTrace = MinInstr->getTrace(IfConv.Tail);
+ struct CriticalPathInfo {
+ unsigned Extra; // Count of extra cycles that the component adds.
+ unsigned Depth; // Absolute depth of the component in cycles.
+ };
+ CriticalPathInfo Cond{};
+ CriticalPathInfo TBlock{};
+ CriticalPathInfo FBlock{};
+ bool ShouldConvert = true;
for (unsigned i = 0, e = IfConv.PHIs.size(); i != e; ++i) {
SSAIfConv::PHIInfo &PI = IfConv.PHIs[i];
unsigned Slack = TailTrace.getInstrSlack(*PI.PHI);
@@ -850,9 +886,11 @@ bool EarlyIfConverter::shouldConvertIf() {
if (CondDepth > MaxDepth) {
unsigned Extra = CondDepth - MaxDepth;
LLVM_DEBUG(dbgs() << "Condition adds " << Extra << " cycles.\n");
+ if (Extra > Cond.Extra)
+ Cond = {Extra, CondDepth};
if (Extra > CritLimit) {
LLVM_DEBUG(dbgs() << "Exceeds limit of " << CritLimit << '\n');
- return false;
+ ShouldConvert = false;
}
}
@@ -861,9 +899,11 @@ bool EarlyIfConverter::shouldConvertIf() {
if (TDepth > MaxDepth) {
unsigned Extra = TDepth - MaxDepth;
LLVM_DEBUG(dbgs() << "TBB data adds " << Extra << " cycles.\n");
+ if (Extra > TBlock.Extra)
+ TBlock = {Extra, TDepth};
if (Extra > CritLimit) {
LLVM_DEBUG(dbgs() << "Exceeds limit of " << CritLimit << '\n');
- return false;
+ ShouldConvert = false;
}
}
@@ -872,13 +912,63 @@ bool EarlyIfConverter::shouldConvertIf() {
if (FDepth > MaxDepth) {
unsigned Extra = FDepth - MaxDepth;
LLVM_DEBUG(dbgs() << "FBB data adds " << Extra << " cycles.\n");
+ if (Extra > FBlock.Extra)
+ FBlock = {Extra, FDepth};
if (Extra > CritLimit) {
LLVM_DEBUG(dbgs() << "Exceeds limit of " << CritLimit << '\n');
- return false;
+ ShouldConvert = false;
}
}
}
- return true;
+
+ // Organize by "short" and "long" legs, since the diagnostics get confusing
+ // when referring to the "true" and "false" sides of the branch, given that
+ // those don't always correlate with what the user wrote in source-terms.
+ const CriticalPathInfo Short = TBlock.Extra > FBlock.Extra ? FBlock : TBlock;
+ const CriticalPathInfo Long = TBlock.Extra > FBlock.Extra ? TBlock : FBlock;
+
+ if (ShouldConvert) {
+ MORE.emit([&]() {
+ MachineOptimizationRemark R(DEBUG_TYPE, "IfConversion",
+ MBB.back().getDebugLoc(), &MBB);
+ R << "performing if-conversion on branch: the condition adds "
+ << Cycles{"CondCycles", Cond.Extra} << " to the critical path";
+ if (Short.Extra > 0)
+ R << ", and the short leg adds another "
+ << Cycles{"ShortCycles", Short.Extra};
+ if (Long.Extra > 0)
+ R << ", and the long leg adds another "
+ << Cycles{"LongCycles", Long.Extra};
+ R << ", each staying under the threshold of "
+ << Cycles{"CritLimit", CritLimit} << ".";
+ return R;
+ });
+ } else {
+ MORE.emit([&]() {
+ MachineOptimizationRemarkMissed R(DEBUG_TYPE, "IfConversion",
+ MBB.back().getDebugLoc(), &MBB);
+ R << "did not if-convert branch: the condition would add "
+ << Cycles{"CondCycles", Cond.Extra} << " to the critical path";
+ if (Cond.Extra > CritLimit)
+ R << " exceeding the limit of " << Cycles{"CritLimit", CritLimit};
+ if (Short.Extra > 0) {
+ R << ", and the short leg would add another "
+ << Cycles{"ShortCycles", Short.Extra};
+ if (Short.Extra > CritLimit)
+ R << " exceeding the limit of " << Cycles{"CritLimit", CritLimit};
+ }
+ if (Long.Extra > 0) {
+ R << ", and the long leg would add another "
+ << Cycles{"LongCycles", Long.Extra};
+ if (Long.Extra > CritLimit)
+ R << " exceeding the limit of " << Cycles{"CritLimit", CritLimit};
+ }
+ R << ".";
+ return R;
+ });
+ }
+
+ return ShouldConvert;
}
/// Attempt repeated if-conversion on MBB, return true if successful.