From 779a8a028f53f16234b41e5252b805304788b989 Mon Sep 17 00:00:00 2001 From: Sam Parker Date: Wed, 30 Sep 2020 09:36:57 +0100 Subject: [PATCH] [ARM][LowOverheadLoops] TryRemove helper. Make a helper function that wraps around RDA::isSafeToRemove and utilises the existing DCE IT block checks. --- llvm/lib/CodeGen/ReachingDefAnalysis.cpp | 3 + llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp | 126 +++++++++++++++------------- 2 files changed, 71 insertions(+), 58 deletions(-) diff --git a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp index 63989bd..e94e547 100644 --- a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp +++ b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp @@ -635,6 +635,9 @@ void ReachingDefAnalysis::collectKilledOperands(MachineInstr *MI, InstSet &Dead) const { Dead.insert(MI); auto IsDead = [this, &Dead](MachineInstr *Def, int PhysReg) { + if (mayHaveSideEffects(*Def)) + return false; + unsigned LiveDefs = 0; for (auto &MO : Def->operands()) { if (!isValidRegDef(MO)) diff --git a/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp b/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp index 72e772e..f5fbe26 100644 --- a/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp +++ b/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp @@ -505,8 +505,6 @@ namespace { void Expand(LowOverheadLoop &LoLoop); - void DCE(MachineInstr *MI, SmallPtrSetImpl &ToRemove); - void IterationCountDCE(LowOverheadLoop &LoLoop); }; } @@ -521,6 +519,72 @@ std::map BasicBlocks; + for (auto *Dead : Killed) + BasicBlocks.insert(Dead->getParent()); + + // Collect IT blocks in all affected basic blocks. + std::map> ITBlocks; + for (auto *MBB : BasicBlocks) { + for (auto &IT : *MBB) { + if (IT.getOpcode() != ARM::t2IT) + continue; + RDA.getReachingLocalUses(&IT, ARM::ITSTATE, ITBlocks[&IT]); + } + } + + // If we're removing all of the instructions within an IT block, then + // also remove the IT instruction. + SmallPtrSet ModifiedITs; + SmallPtrSet RemoveITs; + for (auto *Dead : Killed) { + if (MachineOperand *MO = Dead->findRegisterUseOperand(ARM::ITSTATE)) { + MachineInstr *IT = RDA.getMIOperand(Dead, *MO); + RemoveITs.insert(IT); + auto &CurrentBlock = ITBlocks[IT]; + CurrentBlock.erase(Dead); + if (CurrentBlock.empty()) + ModifiedITs.erase(IT); + else + ModifiedITs.insert(IT); + } + } + if (!ModifiedITs.empty()) + return false; + Killed.insert(RemoveITs.begin(), RemoveITs.end()); + return true; + }; + + SmallPtrSet Uses; + if (!RDA.isSafeToRemove(MI, Uses, Ignore)) + return false; + + if (WontCorruptITs(Uses, RDA)) { + ToRemove.insert(Uses.begin(), Uses.end()); + LLVM_DEBUG(dbgs() << "ARM Loops: Able to remove: " << *MI + << " - can also remove:\n"; + for (auto *Use : Uses) + dbgs() << " - " << *Use); + + SmallPtrSet Killed; + RDA.collectKilledOperands(MI, Killed); + if (WontCorruptITs(Killed, RDA)) { + ToRemove.insert(Killed.begin(), Killed.end()); + LLVM_DEBUG(for (auto *Dead : Killed) + dbgs() << " - " << *Dead); + } + return true; + } + return false; +} + bool LowOverheadLoop::ValidateTailPredicate(MachineInstr *StartInsertPt) { if (!StartInsertPt) return false; @@ -669,7 +733,7 @@ bool LowOverheadLoop::ValidateTailPredicate(MachineInstr *StartInsertPt) { Ignore.insert(VCTPs.begin(), VCTPs.end()); - if (RDA.isSafeToRemove(Def, ElementChain, Ignore)) { + if (TryRemove(Def, RDA, ElementChain, Ignore)) { bool FoundSub = false; for (auto *MI : ElementChain) { @@ -683,10 +747,6 @@ bool LowOverheadLoop::ValidateTailPredicate(MachineInstr *StartInsertPt) { } else return false; } - - LLVM_DEBUG(dbgs() << "ARM Loops: Will remove element count chain:\n"; - for (auto *MI : ElementChain) - dbgs() << " - " << *MI); ToRemove.insert(ElementChain.begin(), ElementChain.end()); } } @@ -1300,52 +1360,6 @@ void ARMLowOverheadLoops::RevertLoopEnd(MachineInstr *MI, bool SkipCmp) const { MI->eraseFromParent(); } -void ARMLowOverheadLoops::DCE(MachineInstr *MI, - SmallPtrSetImpl &ToRemove) { - // Collect the dead code and the MBBs in which they reside. - SmallPtrSet Killed; - RDA->collectKilledOperands(MI, Killed); - SmallPtrSet BasicBlocks; - for (auto *Dead : Killed) - BasicBlocks.insert(Dead->getParent()); - - // Collect IT blocks in all affected basic blocks. - std::map> ITBlocks; - for (auto *MBB : BasicBlocks) { - for (auto &IT : *MBB) { - if (IT.getOpcode() != ARM::t2IT) - continue; - RDA->getReachingLocalUses(&IT, ARM::ITSTATE, ITBlocks[&IT]); - } - } - - // If we're removing all of the instructions within an IT block, then - // also remove the IT instruction. - SmallPtrSet ModifiedITs; - for (auto *Dead : Killed) { - if (MachineOperand *MO = Dead->findRegisterUseOperand(ARM::ITSTATE)) { - MachineInstr *IT = RDA->getMIOperand(Dead, *MO); - auto &CurrentBlock = ITBlocks[IT]; - CurrentBlock.erase(Dead); - if (CurrentBlock.empty()) - ModifiedITs.erase(IT); - else - ModifiedITs.insert(IT); - } - } - - // Delete the killed instructions only if we don't have any IT blocks that - // need to be modified because we need to fixup the mask. - // TODO: Handle cases where IT blocks are modified. - if (ModifiedITs.empty()) { - LLVM_DEBUG(dbgs() << "ARM Loops: Will remove iteration count:\n"; - for (auto *MI : Killed) - dbgs() << " - " << *MI); - ToRemove.insert(Killed.begin(), Killed.end()); - } else - LLVM_DEBUG(dbgs() << "ARM Loops: Would need to modify IT block(s).\n"); -} - // Perform dead code elimation on the loop iteration count setup expression. // If we are tail-predicating, the number of elements to be processed is the // operand of the VCTP instruction in the vector body, see getCount(), which is @@ -1385,11 +1399,7 @@ void ARMLowOverheadLoops::IterationCountDCE(LowOverheadLoop &LoLoop) { // Collect and remove the users of iteration count. SmallPtrSet Killed = { LoLoop.Start, LoLoop.Dec, LoLoop.End, LoLoop.InsertPt }; - SmallPtrSet Remove; - if (RDA->isSafeToRemove(Def, Remove, Killed)) { - LoLoop.ToRemove.insert(Remove.begin(), Remove.end()); - DCE(Def, LoLoop.ToRemove); - } else + if (!TryRemove(Def, *RDA, LoLoop.ToRemove, Killed)) LLVM_DEBUG(dbgs() << "ARM Loops: Unsafe to remove loop iteration count.\n"); } -- 2.7.4