diff options
author | Ahmed Bougacha <ahmed.bougacha@gmail.com> | 2017-03-19 16:13:00 +0000 |
---|---|---|
committer | Ahmed Bougacha <ahmed.bougacha@gmail.com> | 2017-03-19 16:13:00 +0000 |
commit | 931904d7772b18210d7166ed657176ae91ad11d8 (patch) | |
tree | c15a0c51ee751a03bb25cc92814a3087cefa0dba /llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp | |
parent | 48bcd22ce81dc807a1868ac4838abff06bec3f74 (diff) | |
download | bcm5719-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.cpp | 31 |
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. |