aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/CodeGen/MachineSink.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-09-02 21:17:18 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-12-08 17:34:50 +0000
commit06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e (patch)
tree62f873df87c7c675557a179e0c4c83fe9f3087bc /contrib/llvm-project/llvm/lib/CodeGen/MachineSink.cpp
parentcf037972ea8863e2bab7461d77345367d2c1e054 (diff)
parent7fa27ce4a07f19b07799a767fc29416f3b625afb (diff)
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/MachineSink.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/MachineSink.cpp159
1 files changed, 77 insertions, 82 deletions
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/MachineSink.cpp b/contrib/llvm-project/llvm/lib/CodeGen/MachineSink.cpp
index 8429d468254a..8da97dc7e742 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/MachineSink.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/MachineSink.cpp
@@ -115,15 +115,15 @@ STATISTIC(NumPostRACopySink, "Number of copies sunk after RA");
namespace {
class MachineSinking : public MachineFunctionPass {
- const TargetInstrInfo *TII;
- const TargetRegisterInfo *TRI;
- MachineRegisterInfo *MRI; // Machine register information
- MachineDominatorTree *DT; // Machine dominator tree
- MachinePostDominatorTree *PDT; // Machine post dominator tree
- MachineCycleInfo *CI;
- MachineBlockFrequencyInfo *MBFI;
- const MachineBranchProbabilityInfo *MBPI;
- AliasAnalysis *AA;
+ const TargetInstrInfo *TII = nullptr;
+ const TargetRegisterInfo *TRI = nullptr;
+ MachineRegisterInfo *MRI = nullptr; // Machine register information
+ MachineDominatorTree *DT = nullptr; // Machine dominator tree
+ MachinePostDominatorTree *PDT = nullptr; // Machine post dominator tree
+ MachineCycleInfo *CI = nullptr;
+ MachineBlockFrequencyInfo *MBFI = nullptr;
+ const MachineBranchProbabilityInfo *MBPI = nullptr;
+ AliasAnalysis *AA = nullptr;
RegisterClassInfo RegClassInfo;
// Remember which edges have been considered for breaking.
@@ -268,6 +268,44 @@ INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
INITIALIZE_PASS_END(MachineSinking, DEBUG_TYPE,
"Machine code sinking", false, false)
+/// Return true if a target defined block prologue instruction interferes
+/// with a sink candidate.
+static bool blockPrologueInterferes(const MachineBasicBlock *BB,
+ MachineBasicBlock::const_iterator End,
+ const MachineInstr &MI,
+ const TargetRegisterInfo *TRI,
+ const TargetInstrInfo *TII,
+ const MachineRegisterInfo *MRI) {
+ for (MachineBasicBlock::const_iterator PI = BB->getFirstNonPHI(); PI != End;
+ ++PI) {
+ // Only check target defined prologue instructions
+ if (!TII->isBasicBlockPrologue(*PI))
+ continue;
+ for (auto &MO : MI.operands()) {
+ if (!MO.isReg())
+ continue;
+ Register Reg = MO.getReg();
+ if (!Reg)
+ continue;
+ if (MO.isUse()) {
+ if (Reg.isPhysical() && MRI && MRI->isConstantPhysReg(Reg))
+ continue;
+ if (PI->modifiesRegister(Reg, TRI))
+ return true;
+ } else {
+ if (PI->readsRegister(Reg, TRI))
+ return true;
+ // Check for interference with non-dead defs
+ auto *DefOp = PI->findRegisterDefOperand(Reg, false, true, TRI);
+ if (DefOp && !DefOp->isDead())
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
bool MachineSinking::PerformTrivialForwardCoalescing(MachineInstr &MI,
MachineBasicBlock *MBB) {
if (!MI.isCopy())
@@ -331,7 +369,7 @@ bool MachineSinking::AllUsesDominatedByBlock(Register Reg,
// %p = PHI %y, %bb.0, %def, %bb.1
if (all_of(MRI->use_nodbg_operands(Reg), [&](MachineOperand &MO) {
MachineInstr *UseInst = MO.getParent();
- unsigned OpNo = UseInst->getOperandNo(&MO);
+ unsigned OpNo = MO.getOperandNo();
MachineBasicBlock *UseBlock = UseInst->getParent();
return UseBlock == MBB && UseInst->isPHI() &&
UseInst->getOperand(OpNo + 1).getMBB() == DefMBB;
@@ -602,9 +640,7 @@ bool MachineSinking::isWorthBreakingCriticalEdge(MachineInstr &MI,
// MI is cheap, we probably don't want to break the critical edge for it.
// However, if this would allow some definitions of its source operands
// to be sunk then it's probably worth it.
- for (const MachineOperand &MO : MI.operands()) {
- if (!MO.isReg() || !MO.isUse())
- continue;
+ for (const MachineOperand &MO : MI.all_uses()) {
Register Reg = MO.getReg();
if (Reg == 0)
continue;
@@ -806,12 +842,10 @@ bool MachineSinking::isProfitableToSinkTo(Register Reg, MachineInstr &MI,
continue;
if (Reg.isPhysical()) {
- if (MO.isUse() &&
- (MRI->isConstantPhysReg(Reg) || TII->isIgnorableUse(MO)))
- continue;
-
- // Don't handle non-constant and non-ignorable physical register.
- return false;
+ // Don't handle non-constant and non-ignorable physical register uses.
+ if (MO.isUse() && !MRI->isConstantPhysReg(Reg) && !TII->isIgnorableUse(MO))
+ return false;
+ continue;
}
// Users for the defs are all dominated by SuccToSinkTo.
@@ -972,16 +1006,24 @@ MachineSinking::FindSuccToSinkTo(MachineInstr &MI, MachineBasicBlock *MBB,
if (MBB == SuccToSinkTo)
return nullptr;
+ if (!SuccToSinkTo)
+ return nullptr;
+
// It's not safe to sink instructions to EH landing pad. Control flow into
// landing pad is implicitly defined.
- if (SuccToSinkTo && SuccToSinkTo->isEHPad())
+ if (SuccToSinkTo->isEHPad())
return nullptr;
// It ought to be okay to sink instructions into an INLINEASM_BR target, but
// only if we make sure that MI occurs _before_ an INLINEASM_BR instruction in
// the source block (which this code does not yet do). So for now, forbid
// doing so.
- if (SuccToSinkTo && SuccToSinkTo->isInlineAsmBrIndirectTarget())
+ if (SuccToSinkTo->isInlineAsmBrIndirectTarget())
+ return nullptr;
+
+ MachineBasicBlock::const_iterator InsertPos =
+ SuccToSinkTo->SkipPHIsAndLabels(SuccToSinkTo->begin());
+ if (blockPrologueInterferes(SuccToSinkTo, InsertPos, MI, TRI, TII, MRI))
return nullptr;
return SuccToSinkTo;
@@ -1302,45 +1344,6 @@ bool MachineSinking::SinkIntoCycle(MachineCycle *Cycle, MachineInstr &I) {
return true;
}
-/// Return true if a target defined block prologue instruction interferes
-/// with a sink candidate.
-static bool blockPrologueInterferes(MachineBasicBlock *BB,
- MachineBasicBlock::iterator End,
- MachineInstr &MI,
- const TargetRegisterInfo *TRI,
- const TargetInstrInfo *TII,
- const MachineRegisterInfo *MRI) {
- if (BB->begin() == End)
- return false; // no prologue
- for (MachineBasicBlock::iterator PI = BB->getFirstNonPHI(); PI != End; ++PI) {
- // Only check target defined prologue instructions
- if (!TII->isBasicBlockPrologue(*PI))
- continue;
- for (auto &MO : MI.operands()) {
- if (!MO.isReg())
- continue;
- Register Reg = MO.getReg();
- if (!Reg)
- continue;
- if (MO.isUse()) {
- if (Reg.isPhysical() &&
- (TII->isIgnorableUse(MO) || (MRI && MRI->isConstantPhysReg(Reg))))
- continue;
- if (PI->modifiesRegister(Reg, TRI))
- return true;
- } else {
- if (PI->readsRegister(Reg, TRI))
- return true;
- // Check for interference with non-dead defs
- auto *DefOp = PI->findRegisterDefOperand(Reg, false, true, TRI);
- if (DefOp && !DefOp->isDead())
- return true;
- }
- }
- }
- return false;
-}
-
/// SinkInstruction - Determine whether it is safe to sink the specified machine
/// instruction out of its current block into a successor.
bool MachineSinking::SinkInstruction(MachineInstr &MI, bool &SawStore,
@@ -1383,9 +1386,7 @@ bool MachineSinking::SinkInstruction(MachineInstr &MI, bool &SawStore,
// If the instruction to move defines a dead physical register which is live
// when leaving the basic block, don't move it because it could turn into a
// "zombie" define of that preg. E.g., EFLAGS. (<rdar://problem/8030636>)
- for (const MachineOperand &MO : MI.operands()) {
- if (!MO.isReg() || MO.isUse())
- continue;
+ for (const MachineOperand &MO : MI.all_defs()) {
Register Reg = MO.getReg();
if (Reg == 0 || !Reg.isPhysical())
continue;
@@ -1463,8 +1464,8 @@ bool MachineSinking::SinkInstruction(MachineInstr &MI, bool &SawStore,
// Collect debug users of any vreg that this inst defines.
SmallVector<MIRegs, 4> DbgUsersToSink;
- for (auto &MO : MI.operands()) {
- if (!MO.isReg() || !MO.isDef() || !MO.getReg().isVirtual())
+ for (auto &MO : MI.all_defs()) {
+ if (!MO.getReg().isVirtual())
continue;
if (!SeenDbgUsers.count(MO.getReg()))
continue;
@@ -1498,10 +1499,8 @@ bool MachineSinking::SinkInstruction(MachineInstr &MI, bool &SawStore,
// Note that we have to clear the kill flags for any register this instruction
// uses as we may sink over another instruction which currently kills the
// used registers.
- for (MachineOperand &MO : MI.operands()) {
- if (MO.isReg() && MO.isUse())
- RegsToClearKillFlags.insert(MO.getReg()); // Remember to clear kill flags.
- }
+ for (MachineOperand &MO : MI.all_uses())
+ RegsToClearKillFlags.insert(MO.getReg()); // Remember to clear kill flags.
return true;
}
@@ -1517,8 +1516,8 @@ void MachineSinking::SalvageUnsunkDebugUsersOfCopy(
SmallVector<MachineInstr *, 4> DbgDefUsers;
SmallVector<Register, 4> DbgUseRegs;
const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
- for (auto &MO : MI.operands()) {
- if (!MO.isReg() || !MO.isDef() || !MO.getReg().isVirtual())
+ for (auto &MO : MI.all_defs()) {
+ if (!MO.getReg().isVirtual())
continue;
DbgUseRegs.push_back(MO.getReg());
for (auto &User : MRI.use_instructions(MO.getReg())) {
@@ -1700,8 +1699,8 @@ static void updateLiveIn(MachineInstr *MI, MachineBasicBlock *SuccBB,
MachineFunction &MF = *SuccBB->getParent();
const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
for (unsigned DefReg : DefedRegsInCopy)
- for (MCSubRegIterator S(DefReg, TRI, true); S.isValid(); ++S)
- SuccBB->removeLiveIn(*S);
+ for (MCPhysReg S : TRI->subregs_inclusive(DefReg))
+ SuccBB->removeLiveIn(S);
for (auto U : UsedOpsInCopy) {
Register SrcReg = MI->getOperand(U).getReg();
LaneBitmask Mask;
@@ -1793,9 +1792,8 @@ bool PostRAMachineSinking::tryToSinkCopy(MachineBasicBlock &CurBB,
}
// Record debug use of each reg unit.
- for (auto RI = MCRegUnitIterator(MO.getReg(), TRI); RI.isValid();
- ++RI)
- MIUnits[*RI].push_back(MO.getReg());
+ for (MCRegUnit Unit : TRI->regunits(MO.getReg()))
+ MIUnits[Unit].push_back(MO.getReg());
}
}
if (IsValid) {
@@ -1844,12 +1842,9 @@ bool PostRAMachineSinking::tryToSinkCopy(MachineBasicBlock &CurBB,
// recorded which reg units that DBG_VALUEs read, if this instruction
// writes any of those units then the corresponding DBG_VALUEs must sink.
MapVector<MachineInstr *, MIRegs::second_type> DbgValsToSinkMap;
- for (auto &MO : MI.operands()) {
- if (!MO.isReg() || !MO.isDef())
- continue;
-
- for (auto RI = MCRegUnitIterator(MO.getReg(), TRI); RI.isValid(); ++RI) {
- for (const auto &MIRegs : SeenDbgInstrs.lookup(*RI)) {
+ for (auto &MO : MI.all_defs()) {
+ for (MCRegUnit Unit : TRI->regunits(MO.getReg())) {
+ for (const auto &MIRegs : SeenDbgInstrs.lookup(Unit)) {
auto &Regs = DbgValsToSinkMap[MIRegs.first];
for (unsigned Reg : MIRegs.second)
Regs.push_back(Reg);