summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/RegisterCoalescer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/RegisterCoalescer.cpp')
-rw-r--r--llvm/lib/CodeGen/RegisterCoalescer.cpp100
1 files changed, 50 insertions, 50 deletions
diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp
index ab1215974fc5..e49885b6ad96 100644
--- a/llvm/lib/CodeGen/RegisterCoalescer.cpp
+++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp
@@ -116,7 +116,7 @@ static cl::opt<unsigned> LargeIntervalFreqThreshold(
cl::desc("For a large interval, if it is coalesed with other live "
"intervals many times more than the threshold, stop its "
"coalescing to control the compile time. "),
- cl::init(100));
+ cl::init(256));
namespace {
@@ -153,12 +153,6 @@ namespace {
using DbgValueLoc = std::pair<SlotIndex, MachineInstr*>;
DenseMap<Register, std::vector<DbgValueLoc>> DbgVRegToValues;
- /// VRegs may be repeatedly coalesced, and have many DBG_VALUEs attached.
- /// To avoid repeatedly merging sets of DbgValueLocs, instead record
- /// which vregs have been coalesced, and where to. This map is from
- /// vreg => {set of vregs merged in}.
- DenseMap<Register, SmallVector<Register, 4>> DbgMergedVRegNums;
-
/// A LaneMask to remember on which subregister live ranges we need to call
/// shrinkToUses() later.
LaneBitmask ShrinkMask;
@@ -404,14 +398,14 @@ char RegisterCoalescer::ID = 0;
char &llvm::RegisterCoalescerID = RegisterCoalescer::ID;
-INITIALIZE_PASS_BEGIN(RegisterCoalescer, "simple-register-coalescing",
- "Simple Register Coalescing", false, false)
+INITIALIZE_PASS_BEGIN(RegisterCoalescer, "register-coalescer",
+ "Register Coalescer", false, false)
INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
-INITIALIZE_PASS_END(RegisterCoalescer, "simple-register-coalescing",
- "Simple Register Coalescing", false, false)
+INITIALIZE_PASS_END(RegisterCoalescer, "register-coalescer",
+ "Register Coalescer", false, false)
[[nodiscard]] static bool isMoveInstr(const TargetRegisterInfo &tri,
const MachineInstr *MI, Register &Src,
@@ -1257,8 +1251,8 @@ bool RegisterCoalescer::removePartialRedundancy(const CoalescerPair &CP,
static bool definesFullReg(const MachineInstr &MI, Register Reg) {
assert(!Reg.isPhysical() && "This code cannot handle physreg aliasing");
- for (const MachineOperand &Op : MI.operands()) {
- if (!Op.isReg() || !Op.isDef() || Op.getReg() != Reg)
+ for (const MachineOperand &Op : MI.all_defs()) {
+ if (Op.getReg() != Reg)
continue;
// Return true if we define the full register or don't care about the value
// inside other subregisters.
@@ -1502,11 +1496,18 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
LLVM_DEBUG(dbgs()
<< "Removing undefined SubRange "
<< PrintLaneMask(SR.LaneMask) << " : " << SR << "\n");
- // VNI is in ValNo - remove any segments in this SubRange that have this ValNo
+
if (VNInfo *RmValNo = SR.getVNInfoAt(CurrIdx.getRegSlot())) {
+ // VNI is in ValNo - remove any segments in this SubRange that have
+ // this ValNo
SR.removeValNo(RmValNo);
- UpdatedSubRanges = true;
}
+
+ // We may not have a defined value at this point, but still need to
+ // clear out any empty subranges tentatively created by
+ // updateRegDefUses. The original subrange def may have only undefed
+ // some lanes.
+ UpdatedSubRanges = true;
} else {
// We know that this lane is defined by this instruction,
// but at this point it may be empty because it is not used by
@@ -1545,9 +1546,8 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
// no live-ranges would have been created for ECX.
// Fix that!
SlotIndex NewMIIdx = LIS->getInstructionIndex(NewMI);
- for (MCRegUnitIterator Units(NewMI.getOperand(0).getReg(), TRI);
- Units.isValid(); ++Units)
- if (LiveRange *LR = LIS->getCachedRegUnit(*Units))
+ for (MCRegUnit Unit : TRI->regunits(NewMI.getOperand(0).getReg()))
+ if (LiveRange *LR = LIS->getCachedRegUnit(Unit))
LR->createDeadDef(NewMIIdx.getRegSlot(), LIS->getVNInfoAllocator());
}
@@ -1561,8 +1561,8 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
SlotIndex NewMIIdx = LIS->getInstructionIndex(NewMI);
for (unsigned i = 0, e = NewMIImplDefs.size(); i != e; ++i) {
MCRegister Reg = NewMIImplDefs[i];
- for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units)
- if (LiveRange *LR = LIS->getCachedRegUnit(*Units))
+ for (MCRegUnit Unit : TRI->regunits(Reg))
+ if (LiveRange *LR = LIS->getCachedRegUnit(Unit))
LR->createDeadDef(NewMIIdx.getRegSlot(), LIS->getVNInfoAllocator());
}
@@ -1713,8 +1713,8 @@ MachineInstr *RegisterCoalescer::eliminateUndefCopy(MachineInstr *CopyMI) {
// is still part of the function (but about to be erased), mark all
// defs of DstReg in it as <undef>, so that shrinkToUses would
// ignore them.
- for (MachineOperand &MO : CopyMI->operands())
- if (MO.isReg() && MO.isDef() && MO.getReg() == DstReg)
+ for (MachineOperand &MO : CopyMI->all_defs())
+ if (MO.getReg() == DstReg)
MO.setIsUndef(true);
LIS->shrinkToUses(&DstLI);
@@ -2164,14 +2164,14 @@ bool RegisterCoalescer::joinReservedPhysReg(CoalescerPair &CP) {
// Deny any overlapping intervals. This depends on all the reserved
// register live ranges to look like dead defs.
if (!MRI->isConstantPhysReg(DstReg)) {
- for (MCRegUnitIterator UI(DstReg, TRI); UI.isValid(); ++UI) {
+ for (MCRegUnit Unit : TRI->regunits(DstReg)) {
// Abort if not all the regunits are reserved.
- for (MCRegUnitRootIterator RI(*UI, TRI); RI.isValid(); ++RI) {
+ for (MCRegUnitRootIterator RI(Unit, TRI); RI.isValid(); ++RI) {
if (!MRI->isReserved(*RI))
return false;
}
- if (RHS.overlaps(LIS->getRegUnit(*UI))) {
- LLVM_DEBUG(dbgs() << "\t\tInterference: " << printRegUnit(*UI, TRI)
+ if (RHS.overlaps(LIS->getRegUnit(Unit))) {
+ LLVM_DEBUG(dbgs() << "\t\tInterference: " << printRegUnit(Unit, TRI)
<< '\n');
return false;
}
@@ -2202,6 +2202,7 @@ bool RegisterCoalescer::joinReservedPhysReg(CoalescerPair &CP) {
// ...
// use %physreg_x
CopyMI = MRI->getVRegDef(SrcReg);
+ deleteInstr(CopyMI);
} else {
// VReg is copied into physreg:
// %y = def
@@ -2246,15 +2247,15 @@ bool RegisterCoalescer::joinReservedPhysReg(CoalescerPair &CP) {
<< printReg(DstReg, TRI) << " at " << CopyRegIdx << "\n");
LIS->removePhysRegDefAt(DstReg.asMCReg(), CopyRegIdx);
+ deleteInstr(CopyMI);
+
// Create a new dead def at the new def location.
- for (MCRegUnitIterator UI(DstReg, TRI); UI.isValid(); ++UI) {
- LiveRange &LR = LIS->getRegUnit(*UI);
+ for (MCRegUnit Unit : TRI->regunits(DstReg)) {
+ LiveRange &LR = LIS->getRegUnit(Unit);
LR.createDeadDef(DestRegIdx, LIS->getVNInfoAllocator());
}
}
- deleteInstr(CopyMI);
-
// We don't track kills for reserved registers.
MRI->clearKillFlags(CP.getSrcReg());
@@ -2569,8 +2570,8 @@ public:
LaneBitmask JoinVals::computeWriteLanes(const MachineInstr *DefMI, bool &Redef)
const {
LaneBitmask L;
- for (const MachineOperand &MO : DefMI->operands()) {
- if (!MO.isReg() || MO.getReg() != Reg || !MO.isDef())
+ for (const MachineOperand &MO : DefMI->all_defs()) {
+ if (MO.getReg() != Reg)
continue;
L |= TRI->getSubRegIndexLaneMask(
TRI->composeSubRegIndices(SubIdx, MO.getSubReg()));
@@ -2786,13 +2787,22 @@ JoinVals::analyzeValue(unsigned ValNo, JoinVals &Other) {
//
// When it happens, treat that IMPLICIT_DEF as a normal value, and don't try
// to erase the IMPLICIT_DEF instruction.
- if (DefMI &&
- DefMI->getParent() != Indexes->getMBBFromIndex(V.OtherVNI->def)) {
+ MachineBasicBlock *OtherMBB = Indexes->getMBBFromIndex(V.OtherVNI->def);
+ if (DefMI && DefMI->getParent() != OtherMBB) {
LLVM_DEBUG(dbgs() << "IMPLICIT_DEF defined at " << V.OtherVNI->def
<< " extends into "
<< printMBBReference(*DefMI->getParent())
<< ", keeping it.\n");
OtherV.ErasableImplicitDef = false;
+ } else if (OtherMBB->hasEHPadSuccessor()) {
+ // If OtherV is defined in a basic block that has EH pad successors then
+ // we get the same problem not just if OtherV is live beyond its basic
+ // block, but beyond the last call instruction in its basic block. Handle
+ // this case conservatively.
+ LLVM_DEBUG(
+ dbgs() << "IMPLICIT_DEF defined at " << V.OtherVNI->def
+ << " may be live into EH pad successors, keeping it.\n");
+ OtherV.ErasableImplicitDef = false;
} else {
// We deferred clearing these lanes in case we needed to save them
OtherV.ValidLanes &= ~OtherV.WriteLanes;
@@ -2952,7 +2962,7 @@ void JoinVals::computeAssignment(unsigned ValNo, JoinVals &Other) {
// its lanes.
if (OtherV.ErasableImplicitDef &&
TrackSubRegLiveness &&
- (OtherV.WriteLanes & ~V.ValidLanes).any()) {
+ (OtherV.ValidLanes & ~V.ValidLanes).any()) {
LLVM_DEBUG(dbgs() << "Cannot erase implicit_def with missing values\n");
OtherV.ErasableImplicitDef = false;
@@ -3029,8 +3039,8 @@ bool JoinVals::usesLanes(const MachineInstr &MI, Register Reg, unsigned SubIdx,
LaneBitmask Lanes) const {
if (MI.isDebugOrPseudoInstr())
return false;
- for (const MachineOperand &MO : MI.operands()) {
- if (!MO.isReg() || MO.isDef() || MO.getReg() != Reg)
+ for (const MachineOperand &MO : MI.all_uses()) {
+ if (MO.getReg() != Reg)
continue;
if (!MO.readsReg())
continue;
@@ -3759,18 +3769,9 @@ void RegisterCoalescer::checkMergingChangesDbgValues(CoalescerPair &CP,
checkMergingChangesDbgValuesImpl(Reg, LHS, RHS, RHSVals);
};
- // Scan for potentially unsound DBG_VALUEs: examine first the register number
- // Reg, and then any other vregs that may have been merged into it.
- auto PerformScan = [this](Register Reg, std::function<void(Register)> Func) {
- Func(Reg);
- if (DbgMergedVRegNums.count(Reg))
- for (Register X : DbgMergedVRegNums[Reg])
- Func(X);
- };
-
// Scan for unsound updates of both the source and destination register.
- PerformScan(CP.getSrcReg(), ScanForSrcReg);
- PerformScan(CP.getDstReg(), ScanForDstReg);
+ ScanForSrcReg(CP.getSrcReg());
+ ScanForDstReg(CP.getDstReg());
}
void RegisterCoalescer::checkMergingChangesDbgValuesImpl(Register Reg,
@@ -4099,7 +4100,7 @@ void RegisterCoalescer::releaseMemory() {
}
bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) {
- LLVM_DEBUG(dbgs() << "********** SIMPLE REGISTER COALESCING **********\n"
+ LLVM_DEBUG(dbgs() << "********** REGISTER COALESCER **********\n"
<< "********** Function: " << fn.getName() << '\n');
// Variables changed between a setjmp and a longjump can have undefined value
@@ -4151,7 +4152,6 @@ bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) {
MF->verify(this, "Before register coalescing");
DbgVRegToValues.clear();
- DbgMergedVRegNums.clear();
buildVRegToDbgValueMap(fn);
RegClassInfo.runOnMachineFunction(fn);