aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/MachineSink.cpp
diff options
context:
space:
mode:
authorChen Zheng <czhengsz@cn.ibm.com>2020-09-21 20:33:05 -0400
committerChen Zheng <czhengsz@cn.ibm.com>2020-11-04 23:11:22 -0500
commitf645cea8f63e76f4d1ed291da3f61768cbd6abf4 (patch)
tree614b11455086b6f4083105d9efd3579ed7c15421 /llvm/lib/CodeGen/MachineSink.cpp
parent8dc98897c4af20aeb52f1f19f538c08e55793283 (diff)
downloadllvm-f645cea8f63e76f4d1ed291da3f61768cbd6abf4.zip
llvm-f645cea8f63e76f4d1ed291da3f61768cbd6abf4.tar.gz
llvm-f645cea8f63e76f4d1ed291da3f61768cbd6abf4.tar.bz2
[MachineSink] add more profitable pattern.
Add more profitable sinking patterns if the target bb register pressure is not too high. Reviewed By: qcolombet Differential Revision: https://reviews.llvm.org/D88126
Diffstat (limited to 'llvm/lib/CodeGen/MachineSink.cpp')
-rw-r--r--llvm/lib/CodeGen/MachineSink.cpp79
1 files changed, 72 insertions, 7 deletions
diff --git a/llvm/lib/CodeGen/MachineSink.cpp b/llvm/lib/CodeGen/MachineSink.cpp
index 0c7c1cb..0abdf89 100644
--- a/llvm/lib/CodeGen/MachineSink.cpp
+++ b/llvm/lib/CodeGen/MachineSink.cpp
@@ -34,6 +34,8 @@
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachinePostDominators.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/RegisterClassInfo.h"
+#include "llvm/CodeGen/RegisterPressure.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
@@ -94,6 +96,7 @@ namespace {
MachineBlockFrequencyInfo *MBFI;
const MachineBranchProbabilityInfo *MBPI;
AliasAnalysis *AA;
+ RegisterClassInfo RegClassInfo;
// Remember which edges have been considered for breaking.
SmallSet<std::pair<MachineBasicBlock*, MachineBasicBlock*>, 8>
@@ -133,6 +136,9 @@ namespace {
std::vector<MachineInstr *>>
StoreInstrCache;
+ /// Cached BB's register pressure.
+ std::map<MachineBasicBlock *, std::vector<unsigned>> CachedRegisterPressure;
+
public:
static char ID; // Pass identification
@@ -209,6 +215,8 @@ namespace {
SmallVector<MachineBasicBlock *, 4> &
GetAllSortedSuccessors(MachineInstr &MI, MachineBasicBlock *MBB,
AllSuccsCache &AllSuccessors) const;
+
+ std::vector<unsigned> &getBBRegisterPressure(MachineBasicBlock &MBB);
};
} // end anonymous namespace
@@ -335,6 +343,7 @@ bool MachineSinking::runOnMachineFunction(MachineFunction &MF) {
MBFI = UseBlockFreqInfo ? &getAnalysis<MachineBlockFrequencyInfo>() : nullptr;
MBPI = &getAnalysis<MachineBranchProbabilityInfo>();
AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
+ RegClassInfo.runOnMachineFunction(MF);
bool EverMadeChange = false;
@@ -428,6 +437,8 @@ bool MachineSinking::ProcessBlock(MachineBasicBlock &MBB) {
SeenDbgUsers.clear();
SeenDbgVars.clear();
+ // recalculate the bb register pressure after sinking one BB.
+ CachedRegisterPressure.clear();
return MadeChange;
}
@@ -570,6 +581,42 @@ bool MachineSinking::PostponeSplitCriticalEdge(MachineInstr &MI,
return true;
}
+std::vector<unsigned> &
+MachineSinking::getBBRegisterPressure(MachineBasicBlock &MBB) {
+ // Currently to save compiling time, MBB's register pressure will not change
+ // in one ProcessBlock iteration because of CachedRegisterPressure. but MBB's
+ // register pressure is changed after sinking any instructions into it.
+ // FIXME: need a accurate and cheap register pressure estiminate model here.
+ auto RP = CachedRegisterPressure.find(&MBB);
+ if (RP != CachedRegisterPressure.end())
+ return RP->second;
+
+ RegionPressure Pressure;
+ RegPressureTracker RPTracker(Pressure);
+
+ // Initialize the register pressure tracker.
+ RPTracker.init(MBB.getParent(), &RegClassInfo, nullptr, &MBB, MBB.end(),
+ /*TrackLaneMasks*/ false, /*TrackUntiedDefs=*/true);
+
+ for (MachineBasicBlock::iterator MII = MBB.instr_end(),
+ MIE = MBB.instr_begin();
+ MII != MIE; --MII) {
+ MachineInstr &MI = *std::prev(MII);
+ if (MI.isDebugValue() || MI.isDebugLabel())
+ continue;
+ RegisterOperands RegOpers;
+ RegOpers.collect(MI, *TRI, *MRI, false, false);
+ RPTracker.recedeSkipDebugValues();
+ assert(&*RPTracker.getPos() == &MI && "RPTracker sync error!");
+ RPTracker.recede(RegOpers);
+ }
+
+ RPTracker.closeRegion();
+ auto It = CachedRegisterPressure.insert(
+ std::make_pair(&MBB, RPTracker.getPressure().MaxSetPressure));
+ return It.first->second;
+}
+
/// isProfitableToSinkTo - Return true if it is profitable to sink MI.
bool MachineSinking::isProfitableToSinkTo(Register Reg, MachineInstr &MI,
MachineBasicBlock *MBB,
@@ -614,6 +661,21 @@ bool MachineSinking::isProfitableToSinkTo(Register Reg, MachineInstr &MI,
if (!ML)
return false;
+ auto isRegisterPressureSetExceedLimit = [&](const TargetRegisterClass *RC) {
+ unsigned Weight = TRI->getRegClassWeight(RC).RegWeight;
+ const int *PS = TRI->getRegClassPressureSets(RC);
+ // Get register pressure for block SuccToSinkTo.
+ std::vector<unsigned> BBRegisterPressure =
+ getBBRegisterPressure(*SuccToSinkTo);
+ for (; *PS != -1; PS++)
+ // check if any register pressure set exceeds limit in block SuccToSinkTo
+ // after sinking.
+ if (Weight + BBRegisterPressure[*PS] >=
+ TRI->getRegPressureSetLimit(*MBB->getParent(), *PS))
+ return true;
+ return false;
+ };
+
// If this instruction is inside a loop and sinking this instruction can make
// more registers live range shorten, it is still prifitable.
for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
@@ -645,16 +707,19 @@ bool MachineSinking::isProfitableToSinkTo(Register Reg, MachineInstr &MI,
if (LI->getLoopFor(DefMI->getParent()) != ML ||
(DefMI->isPHI() && LI->isLoopHeader(DefMI->getParent())))
continue;
- // DefMI is inside the loop. Mark it as not profitable as sinking MI will
- // enlarge DefMI live range.
- // FIXME: check the register pressure in block SuccToSinkTo, if it is
- // smaller than the limit after sinking, it is still profitable to sink.
- return false;
+ // The DefMI is defined inside the loop.
+ // If sinking this operand makes some register pressure set exceed limit,
+ // it is not profitable.
+ if (isRegisterPressureSetExceedLimit(MRI->getRegClass(Reg))) {
+ LLVM_DEBUG(dbgs() << "register pressure exceed limit, not profitable.");
+ return false;
+ }
}
}
- // If MI is in loop and all its operands are alive across the whole loop, it
- // is profitable to sink MI.
+ // If MI is in loop and all its operands are alive across the whole loop or if
+ // no operand sinking make register pressure set exceed limit, it is
+ // profitable to sink MI.
return true;
}