[llvm] f2942b9 - [CodeGen] NFC: Move isDead to MachineInstr (#123531)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 23 12:54:32 PST 2025
Author: Jeffrey Byrnes
Date: 2025-01-23T12:54:29-08:00
New Revision: f2942b90778670d9ad974d025c779fc96afa737c
URL: https://github.com/llvm/llvm-project/commit/f2942b90778670d9ad974d025c779fc96afa737c
DIFF: https://github.com/llvm/llvm-project/commit/f2942b90778670d9ad974d025c779fc96afa737c.diff
LOG: [CodeGen] NFC: Move isDead to MachineInstr (#123531)
Provide isDead interface for access to ad-hoc isDead queries.
LivePhysRegs is optional: if not provided, pessimistically check
deadness of a single MI without doing the LivePhysReg walk; if provided
it is assumed to be at the position of MI.
Added:
Modified:
llvm/include/llvm/CodeGen/MachineInstr.h
llvm/lib/CodeGen/DeadMachineInstructionElim.cpp
llvm/lib/CodeGen/MachineInstr.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h
index 109aac44b86623..102b1eb07358e4 100644
--- a/llvm/include/llvm/CodeGen/MachineInstr.h
+++ b/llvm/include/llvm/CodeGen/MachineInstr.h
@@ -46,6 +46,7 @@ class BatchAAResults;
template <typename T> class ArrayRef;
class DIExpression;
class DILocalVariable;
+class LiveRegUnits;
class MachineBasicBlock;
class MachineFunction;
class MachineRegisterInfo;
@@ -1744,6 +1745,18 @@ class MachineInstr
/// defined registers were dead.
bool wouldBeTriviallyDead() const;
+ /// Check whether an MI is dead. If \p LivePhysRegs is provided, it is assumed
+ /// to be at the position of MI and will be used to check the Liveness of
+ /// physical register defs. If \p LivePhysRegs is not provided, this will
+ /// pessimistically assume any PhysReg def is live.
+ /// For trivially dead instructions (i.e. those without hard to model effects
+ /// / wouldBeTriviallyDead), this checks deadness by analyzing defs of the
+ /// MachineInstr. If the instruction wouldBeTriviallyDead, and all the defs
+ /// either have dead flags or have no uses, then the instruction is said to be
+ /// dead.
+ bool isDead(const MachineRegisterInfo &MRI,
+ LiveRegUnits *LivePhysRegs = nullptr) const;
+
/// Returns true if this instruction's memory access aliases the memory
/// access of Other.
//
diff --git a/llvm/lib/CodeGen/DeadMachineInstructionElim.cpp b/llvm/lib/CodeGen/DeadMachineInstructionElim.cpp
index 2f17c04487de7c..836a912a5e9835 100644
--- a/llvm/lib/CodeGen/DeadMachineInstructionElim.cpp
+++ b/llvm/lib/CodeGen/DeadMachineInstructionElim.cpp
@@ -38,7 +38,6 @@ class DeadMachineInstructionElimImpl {
bool runImpl(MachineFunction &MF);
private:
- bool isDead(const MachineInstr *MI) const;
bool eliminateDeadMI(MachineFunction &MF);
};
@@ -79,47 +78,6 @@ char &llvm::DeadMachineInstructionElimID = DeadMachineInstructionElim::ID;
INITIALIZE_PASS(DeadMachineInstructionElim, DEBUG_TYPE,
"Remove dead machine instructions", false, false)
-bool DeadMachineInstructionElimImpl::isDead(const MachineInstr *MI) const {
- // Instructions without side-effects are dead iff they only define dead regs.
- // This function is hot and this loop returns early in the common case,
- // so only perform additional checks before this if absolutely necessary.
- for (const MachineOperand &MO : MI->all_defs()) {
- Register Reg = MO.getReg();
- if (Reg.isPhysical()) {
- // Don't delete live physreg defs, or any reserved register defs.
- if (!LivePhysRegs.available(Reg) || MRI->isReserved(Reg))
- return false;
- } else {
- if (MO.isDead()) {
-#ifndef NDEBUG
- // Basic check on the register. All of them should be 'undef'.
- for (auto &U : MRI->use_nodbg_operands(Reg))
- assert(U.isUndef() && "'Undef' use on a 'dead' register is found!");
-#endif
- continue;
- }
- for (const MachineInstr &Use : MRI->use_nodbg_instructions(Reg)) {
- if (&Use != MI)
- // This def has a non-debug use. Don't delete the instruction!
- return false;
- }
- }
- }
-
- // Technically speaking inline asm without side effects and no defs can still
- // be deleted. But there is so much bad inline asm code out there, we should
- // let them be.
- if (MI->isInlineAsm())
- return false;
-
- // FIXME: See issue #105950 for why LIFETIME markers are considered dead here.
- if (MI->isLifetimeMarker())
- return true;
-
- // If there are no defs with uses, the instruction might be dead.
- return MI->wouldBeTriviallyDead();
-}
-
bool DeadMachineInstructionElimImpl::runImpl(MachineFunction &MF) {
MRI = &MF.getRegInfo();
@@ -146,7 +104,7 @@ bool DeadMachineInstructionElimImpl::eliminateDeadMI(MachineFunction &MF) {
// liveness as we go.
for (MachineInstr &MI : make_early_inc_range(reverse(*MBB))) {
// If the instruction is dead, delete it!
- if (isDead(&MI)) {
+ if (MI.isDead(*MRI, &LivePhysRegs)) {
LLVM_DEBUG(dbgs() << "DeadMachineInstructionElim: DELETING: " << MI);
// It is possible that some DBG_VALUE instructions refer to this
// instruction. They will be deleted in the live debug variable
@@ -156,11 +114,9 @@ bool DeadMachineInstructionElimImpl::eliminateDeadMI(MachineFunction &MF) {
++NumDeletes;
continue;
}
-
LivePhysRegs.stepBackward(MI);
}
}
-
LivePhysRegs.clear();
return AnyChanges;
}
diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp
index 8c2fab18a24ca0..0f7f525fa479e8 100644
--- a/llvm/lib/CodeGen/MachineInstr.cpp
+++ b/llvm/lib/CodeGen/MachineInstr.cpp
@@ -18,6 +18,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/MemoryLocation.h"
+#include "llvm/CodeGen/LiveRegUnits.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
@@ -1350,6 +1351,43 @@ bool MachineInstr::wouldBeTriviallyDead() const {
return isPHI() || isSafeToMove(SawStore);
}
+bool MachineInstr::isDead(const MachineRegisterInfo &MRI,
+ LiveRegUnits *LivePhysRegs) const {
+ // Technically speaking inline asm without side effects and no defs can still
+ // be deleted. But there is so much bad inline asm code out there, we should
+ // let them be.
+ if (isInlineAsm())
+ return false;
+
+ // If we suspect this instruction may have some side-effects, then we say
+ // this instruction cannot be dead.
+ // FIXME: See issue #105950 for why LIFETIME markers are considered dead here.
+ if (!isLifetimeMarker() && !wouldBeTriviallyDead())
+ return false;
+
+ // Instructions without side-effects are dead iff they only define dead regs.
+ // This function is hot and this loop returns early in the common case,
+ // so only perform additional checks before this if absolutely necessary.
+ for (const MachineOperand &MO : all_defs()) {
+ Register Reg = MO.getReg();
+ if (Reg.isPhysical()) {
+ // Don't delete live physreg defs, or any reserved register defs.
+ if (!LivePhysRegs || !LivePhysRegs->available(Reg) || MRI.isReserved(Reg))
+ return false;
+ } else {
+ if (MO.isDead())
+ continue;
+ for (const MachineInstr &Use : MRI.use_nodbg_instructions(Reg)) {
+ if (&Use != this)
+ // This def has a non-debug use. Don't delete the instruction!
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
static bool MemOperandsHaveAlias(const MachineFrameInfo &MFI,
BatchAAResults *AA, bool UseTBAA,
const MachineMemOperand *MMOa,
More information about the llvm-commits
mailing list