summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp
diff options
context:
space:
mode:
authorAhmed Bougacha <ahmed.bougacha@gmail.com>2017-03-19 16:13:00 +0000
committerAhmed Bougacha <ahmed.bougacha@gmail.com>2017-03-19 16:13:00 +0000
commit931904d7772b18210d7166ed657176ae91ad11d8 (patch)
treec15a0c51ee751a03bb25cc92814a3087cefa0dba /llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp
parent48bcd22ce81dc807a1868ac4838abff06bec3f74 (diff)
downloadbcm5719-llvm-931904d7772b18210d7166ed657176ae91ad11d8.tar.gz
bcm5719-llvm-931904d7772b18210d7166ed657176ae91ad11d8.zip
[GlobalISel] Don't select trivially dead instructions.
Folding instructions when selecting can cause them to become dead. Don't select these dead instructions (if they don't have other side effects, and don't define physical registers). Preserve existing tests by adding COPYs. In some tests, the G_CONSTANT vregs never get constrained to a class: the only use of the vreg was folded into another instruction, so the G_CONSTANT, now dead, never gets selected. llvm-svn: 298224
Diffstat (limited to 'llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp')
-rw-r--r--llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp31
1 files changed, 31 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp b/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp
index 0ca4134a577..c59b200298e 100644
--- a/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp
@@ -48,6 +48,29 @@ void InstructionSelect::getAnalysisUsage(AnalysisUsage &AU) const {
MachineFunctionPass::getAnalysisUsage(AU);
}
+/// Check whether an instruction \p MI is dead: it only defines dead virtual
+/// registers, and doesn't have other side effects.
+static bool isTriviallyDead(const MachineInstr &MI,
+ const MachineRegisterInfo &MRI) {
+ // If we can move an instruction, we can remove it. Otherwise, it has
+ // a side-effect of some sort.
+ bool SawStore = false;
+ if (!MI.isSafeToMove(/*AA=*/nullptr, SawStore))
+ return false;
+
+ // Instructions without side-effects are dead iff they only define dead vregs.
+ for (auto &MO : MI.operands()) {
+ if (!MO.isReg() || !MO.isDef())
+ continue;
+
+ unsigned Reg = MO.getReg();
+ // Keep Debug uses live: we don't want to have an effect on debug info.
+ if (TargetRegisterInfo::isPhysicalRegister(Reg) || !MRI.use_empty(Reg))
+ return false;
+ }
+ return true;
+}
+
bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) {
const MachineRegisterInfo &MRI = MF.getRegInfo();
@@ -119,6 +142,14 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) {
DEBUG(dbgs() << "Selecting: \n " << MI);
+ // We could have folded this instruction away already, making it dead.
+ // If so, erase it.
+ if (isTriviallyDead(MI, MRI)) {
+ DEBUG(dbgs() << "Is dead; erasing.\n");
+ MI.eraseFromParent();
+ continue;
+ }
+
if (!ISel->select(MI)) {
// FIXME: It would be nice to dump all inserted instructions. It's
// not obvious how, esp. considering select() can insert after MI.
OpenPOWER on IntegriCloud