Index: llvm/include/llvm/CodeGen/ReachingDefAnalysis.h =================================================================== --- llvm/include/llvm/CodeGen/ReachingDefAnalysis.h +++ llvm/include/llvm/CodeGen/ReachingDefAnalysis.h @@ -176,7 +176,7 @@ /// Assuming MI is dead, recursively search the incoming operands which are /// killed by MI and collect those that would become dead. - void collectLocalKilledOperands(MachineInstr *MI, InstSet &Dead) const; + void collectKilledOperands(MachineInstr *MI, InstSet &Dead) const; /// Return whether removing this instruction will have no effect on the /// program, returning the redundant use-def chain. Index: llvm/lib/CodeGen/ReachingDefAnalysis.cpp =================================================================== --- llvm/lib/CodeGen/ReachingDefAnalysis.cpp +++ llvm/lib/CodeGen/ReachingDefAnalysis.cpp @@ -33,10 +33,6 @@ return isValidRegUse(MO) && MO.getReg() == PhysReg; } -bool isKilledRegUse(const MachineOperand &MO) { - return isValidRegUse(MO) && MO.isKill(); -} - bool isValidRegDef(const MachineOperand &MO) { return isValidReg(MO) && MO.isDef(); } @@ -353,7 +349,7 @@ int PhysReg) const { // If there's a local def before MI, return it. MachineInstr *LocalDef = getReachingLocalMIDef(MI, PhysReg); - if (InstIds.lookup(LocalDef) < InstIds.lookup(MI)) + if (LocalDef && InstIds.lookup(LocalDef) < InstIds.lookup(MI)) return LocalDef; SmallPtrSet VisitedBBs; @@ -544,8 +540,8 @@ return true; } -void ReachingDefAnalysis::collectLocalKilledOperands(MachineInstr *MI, - InstSet &Dead) const { +void ReachingDefAnalysis::collectKilledOperands(MachineInstr *MI, + InstSet &Dead) const { Dead.insert(MI); auto IsDead = [this, &Dead](MachineInstr *Def, int PhysReg) { unsigned LiveDefs = 0; @@ -568,11 +564,11 @@ }; for (auto &MO : MI->operands()) { - if (!isKilledRegUse(MO)) + if (!isValidRegUse(MO)) continue; - if (MachineInstr *Def = getReachingLocalMIDef(MI, MO.getReg())) + if (MachineInstr *Def = getMIOperand(MI, MO)) if (IsDead(Def, MO.getReg())) - collectLocalKilledOperands(Def, Dead); + collectKilledOperands(Def, Dead); } } Index: llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp =================================================================== --- llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp +++ llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp @@ -900,40 +900,53 @@ if (!LoLoop.IsTailPredicationLegal()) return; + LLVM_DEBUG(dbgs() << "ARM Loops: Trying DCE on loop iteration count.\n"); + MachineInstr *Def = RDA->getMIOperand(LoLoop.Start, 0); - if (!Def) + if (!Def) { + LLVM_DEBUG(dbgs() << "ARM Loops: Couldn't find iteration count.\n"); + return; + } + + // 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()); + else { + LLVM_DEBUG(dbgs() << "ARM Loops: Unsafe to remove loop iteration count.\n"); return; + } - // Collect IT blocks. + // Collect the dead code and the MBBs in which they reside. + RDA->collectKilledOperands(Def, Killed); + SmallPtrSet BasicBlocks; + for (auto *MI : Killed) + BasicBlocks.insert(MI->getParent()); + + // Collect IT blocks in all affected basic blocks. std::map> ITBlocks; - std::map Predicates; - MachineInstr *IT = nullptr; - for (auto &MI : *Def->getParent()) { - if (MI.getOpcode() == ARM::t2IT) - IT = &MI; - else if (TII->getPredicate(MI) != ARMCC::AL) { - ITBlocks[IT].insert(&MI); - Predicates[&MI] = IT; + for (auto *MBB : BasicBlocks) { + for (auto &MI : *MBB) { + if (MI.getOpcode() != ARM::t2IT) + continue; + RDA->getReachingLocalUses(&MI, ARM::ITSTATE, ITBlocks[&MI]); } } // If we're removing all of the instructions within an IT block, then // also remove the IT instruction. SmallPtrSet ModifiedITs; - SmallPtrSet DeadITs; - SmallPtrSet Killed; - RDA->collectLocalKilledOperands(Def, Killed); for (auto *MI : Killed) { - if (!Predicates.count(MI)) - continue; - - MachineInstr *IT = Predicates[MI]; - auto &CurrentBlock = ITBlocks[IT]; - CurrentBlock.erase(MI); - ModifiedITs.insert(IT); - if (CurrentBlock.empty()) { - DeadITs.insert(IT); - ModifiedITs.erase(IT); + if (MachineOperand *MO = MI->findRegisterUseOperand(ARM::ITSTATE)) { + MachineInstr *IT = RDA->getMIOperand(MI, *MO); + auto &CurrentBlock = ITBlocks[IT]; + CurrentBlock.erase(MI); + if (CurrentBlock.empty()) + ModifiedITs.erase(IT); + else + ModifiedITs.insert(IT); } } @@ -945,14 +958,8 @@ for (auto *MI : Killed) dbgs() << " - " << *MI); LoLoop.ToRemove.insert(Killed.begin(), Killed.end()); - } - - // Collect and remove the users of iteration count. - SmallPtrSet Ignore = { LoLoop.Start, LoLoop.Dec, - LoLoop.End, LoLoop.InsertPt }; - SmallPtrSet Remove; - if (RDA->isSafeToRemove(Def, Remove, Ignore)) - LoLoop.ToRemove.insert(Remove.begin(), Remove.end()); + } else + LLVM_DEBUG(dbgs() << "ARM Loops: Would need to modify IT block(s).\n"); } MachineInstr* ARMLowOverheadLoops::ExpandLoopStart(LowOverheadLoop &LoLoop) { @@ -1076,8 +1083,8 @@ MIB.add(End->getOperand(0)); MIB.add(End->getOperand(1)); LLVM_DEBUG(dbgs() << "ARM Loops: Inserted LE: " << *MIB); - LoLoop.Dec->eraseFromParent(); - End->eraseFromParent(); + LoLoop.ToRemove.insert(LoLoop.Dec); + LoLoop.ToRemove.insert(End); return &*MIB; }; Index: llvm/test/CodeGen/Thumb2/LowOverheadLoops/it-block-itercount.mir =================================================================== --- llvm/test/CodeGen/Thumb2/LowOverheadLoops/it-block-itercount.mir +++ llvm/test/CodeGen/Thumb2/LowOverheadLoops/it-block-itercount.mir @@ -104,8 +104,6 @@ ; CHECK: frame-setup CFI_INSTRUCTION offset $lr, -4 ; CHECK: frame-setup CFI_INSTRUCTION offset $r7, -8 ; CHECK: renamable $r3, dead $cpsr = tLSLri killed renamable $r2, 1, 14 /* CC::al */, $noreg - ; CHECK: dead renamable $r12 = t2MOVi 4, 14 /* CC::al */, $noreg, $noreg - ; CHECK: tCMPi8 renamable $r3, 4, 14 /* CC::al */, $noreg, implicit-def dead $cpsr ; CHECK: renamable $r2 = tLEApcrel %const.0, 14 /* CC::al */, $noreg ; CHECK: renamable $q0 = MVE_VLDRWU32 killed renamable $r2, 0, 0, $noreg :: (load 16 from constant-pool) ; CHECK: $lr = MVE_DLSTP_32 killed renamable $r3 Index: llvm/test/CodeGen/Thumb2/LowOverheadLoops/it-block-mov.mir =================================================================== --- llvm/test/CodeGen/Thumb2/LowOverheadLoops/it-block-mov.mir +++ llvm/test/CodeGen/Thumb2/LowOverheadLoops/it-block-mov.mir @@ -45,12 +45,7 @@ ; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 8 ; CHECK: frame-setup CFI_INSTRUCTION offset $lr, -4 ; CHECK: frame-setup CFI_INSTRUCTION offset $r4, -8 - ; CHECK: tCMPi8 renamable $r1, 4, 14 /* CC::al */, $noreg, implicit-def $cpsr - ; CHECK: renamable $r3 = t2MOVi 4, 14 /* CC::al */, $noreg, $noreg - ; CHECK: t2IT 11, 8, implicit-def $itstate - ; CHECK: dead $r3 = tMOVr renamable $r1, 11 /* CC::lt */, killed $cpsr, implicit killed renamable $r3, implicit killed $itstate ; CHECK: tCMPi8 renamable $r1, 2, 14 /* CC::al */, $noreg, implicit-def $cpsr - ; CHECK: renamable $r12 = t2MOVi 4, 14 /* CC::al */, $noreg, $noreg ; CHECK: tBcc %bb.2, 2 /* CC::hs */, killed $cpsr ; CHECK: bb.1: ; CHECK: liveins: $r2 @@ -59,15 +54,8 @@ ; CHECK: tPOP_RET 14 /* CC::al */, $noreg, def $r4, def $pc ; CHECK: bb.2: ; CHECK: successors: %bb.3(0x80000000) - ; CHECK: liveins: $r0, $r1, $r2, $r12 - ; CHECK: renamable $r4, dead $cpsr = tMOVi8 1, 14 /* CC::al */, $noreg - ; CHECK: tCMPi8 renamable $r1, 4, 14 /* CC::al */, $noreg, implicit-def $cpsr - ; CHECK: t2IT 11, 8, implicit-def $itstate - ; CHECK: $r12 = tMOVr renamable $r1, 11 /* CC::lt */, killed $cpsr, implicit killed renamable $r12, implicit killed $itstate - ; CHECK: renamable $r3 = t2SUBrr renamable $r1, killed renamable $r12, 14 /* CC::al */, $noreg, $noreg - ; CHECK: renamable $r3, dead $cpsr = tADDi8 killed renamable $r3, 3, 14 /* CC::al */, $noreg + ; CHECK: liveins: $r0, $r1, $r2 ; CHECK: $r12 = tMOVr $r1, 14 /* CC::al */, $noreg - ; CHECK: dead renamable $r4 = nuw nsw t2ADDrs killed renamable $r4, killed renamable $r3, 19, 14 /* CC::al */, $noreg, $noreg ; CHECK: renamable $q0 = MVE_VMOVimmi32 0, 0, $noreg, undef renamable $q0 ; CHECK: $r3 = tMOVr $r0, 14 /* CC::al */, $noreg ; CHECK: $lr = MVE_DLSTP_32 killed renamable $r12 Index: llvm/test/CodeGen/Thumb2/LowOverheadLoops/multiple-do-loops.mir =================================================================== --- llvm/test/CodeGen/Thumb2/LowOverheadLoops/multiple-do-loops.mir +++ llvm/test/CodeGen/Thumb2/LowOverheadLoops/multiple-do-loops.mir @@ -563,7 +563,6 @@ ; CHECK: early-clobber $sp = frame-setup t2STR_PRE killed $r8, $sp, -4, 14 /* CC::al */, $noreg ; CHECK: frame-setup CFI_INSTRUCTION offset $r8, -24 ; CHECK: renamable $r6, dead $cpsr = tMOVi8 0, 14 /* CC::al */, $noreg - ; CHECK: dead renamable $r12 = t2MOVi 1, 14 /* CC::al */, $noreg, $noreg ; CHECK: t2CMPrs killed renamable $r6, renamable $r3, 11, 14 /* CC::al */, $noreg, implicit-def $cpsr ; CHECK: tBcc %bb.3, 0 /* CC::eq */, killed $cpsr ; CHECK: bb.1.vector.ph: @@ -801,7 +800,6 @@ ; CHECK: successors: %bb.6(0x30000000), %bb.4(0x50000000) ; CHECK: liveins: $r0, $r1, $r2, $r3 ; CHECK: renamable $r6, dead $cpsr = tMOVi8 0, 14 /* CC::al */, $noreg - ; CHECK: dead renamable $r8 = t2MOVi 1, 14 /* CC::al */, $noreg, $noreg ; CHECK: t2CMPrs killed renamable $r6, renamable $r3, 11, 14 /* CC::al */, $noreg, implicit-def $cpsr ; CHECK: tBcc %bb.6, 0 /* CC::eq */, killed $cpsr ; CHECK: bb.4.vector.ph66: