diff --git a/llvm/include/llvm/CodeGen/ReachingDefAnalysis.h b/llvm/include/llvm/CodeGen/ReachingDefAnalysis.h index 3c6ab064e91fe..44127bfdd48e0 100644 --- a/llvm/include/llvm/CodeGen/ReachingDefAnalysis.h +++ b/llvm/include/llvm/CodeGen/ReachingDefAnalysis.h @@ -176,7 +176,7 @@ class ReachingDefAnalysis : public MachineFunctionPass { /// 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. diff --git a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp index 5f0b4a92f3eea..a1c0c21df9127 100644 --- a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp +++ b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp @@ -33,10 +33,6 @@ bool isValidRegUseOf(const MachineOperand &MO, int PhysReg) { 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 @@ MachineInstr *ReachingDefAnalysis::getUniqueReachingMIDef(MachineInstr *MI, 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 @@ ReachingDefAnalysis::isSafeToRemove(MachineInstr *MI, InstSet &Visited, 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 @@ void ReachingDefAnalysis::collectLocalKilledOperands(MachineInstr *MI, }; 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); } } diff --git a/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp b/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp index 92eb2e2cffed4..67cb883329363 100644 --- a/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp +++ b/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp @@ -900,40 +900,53 @@ void ARMLowOverheadLoops::IterationCountDCE(LowOverheadLoop &LoLoop) { 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 @@ void ARMLowOverheadLoops::IterationCountDCE(LowOverheadLoop &LoLoop) { 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 @@ void ARMLowOverheadLoops::Expand(LowOverheadLoop &LoLoop) { 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; }; diff --git a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/it-block-itercount.mir b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/it-block-itercount.mir index 456fe593443ec..d5bc54820182a 100644 --- a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/it-block-itercount.mir +++ b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/it-block-itercount.mir @@ -104,8 +104,6 @@ body: | ; 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 diff --git a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/it-block-mov.mir b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/it-block-mov.mir index bed94f989858b..e5d629c8730c6 100644 --- a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/it-block-mov.mir +++ b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/it-block-mov.mir @@ -45,12 +45,7 @@ body: | ; 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 @@ body: | ; 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 diff --git a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/multiple-do-loops.mir b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/multiple-do-loops.mir index e9ee082479b87..087db2ae509d0 100644 --- a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/multiple-do-loops.mir +++ b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/multiple-do-loops.mir @@ -563,7 +563,6 @@ body: | ; 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 @@ body: | ; 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: diff --git a/llvm/test/CodeGen/Thumb2/mve-postinc-lsr.ll b/llvm/test/CodeGen/Thumb2/mve-postinc-lsr.ll index d74f3bbfb2e0e..13f0243139487 100644 --- a/llvm/test/CodeGen/Thumb2/mve-postinc-lsr.ll +++ b/llvm/test/CodeGen/Thumb2/mve-postinc-lsr.ll @@ -576,15 +576,7 @@ define i32 @arm_nn_mat_mul_core_4x_s8(i32 %row_elements, i32 %offset, i8* %row_b ; CHECK: @ %bb.0: @ %entry ; CHECK-NEXT: .save {r4, r5, r6, r7, r8, r10, lr} ; CHECK-NEXT: push.w {r4, r5, r6, r7, r8, r10, lr} -; CHECK-NEXT: add.w r7, r0, #15 ; CHECK-NEXT: ldr.w r12, [sp, #32] -; CHECK-NEXT: mov.w lr, #1 -; CHECK-NEXT: asrs r6, r7, #31 -; CHECK-NEXT: add.w r4, r7, r6, lsr #28 -; CHECK-NEXT: asrs r5, r4, #4 -; CHECK-NEXT: cmp r5, #1 -; CHECK-NEXT: it gt -; CHECK-NEXT: asrgt.w lr, r4, #4 ; CHECK-NEXT: cmp r0, #1 ; CHECK-NEXT: blt .LBB4_3 ; CHECK-NEXT: @ %bb.1: @ %for.body.preheader