From ac0b2814c34959ebaa8f054db019bd287fdff54d Mon Sep 17 00:00:00 2001 From: paperchalice Date: Tue, 9 Jul 2024 10:50:43 +0800 Subject: [PATCH] [CodeGen][NewPM] Port `LiveVariables` to new pass manager (#97880) - Port `LiveVariables` to new pass manager. - Convert to `LiveVariablesWrapperPass` in legacy pass manager. --- llvm/include/llvm/CodeGen/LiveVariables.h | 69 +++++++++++++++---- llvm/include/llvm/InitializePasses.h | 2 +- .../llvm/Passes/MachinePassRegistry.def | 14 ++-- llvm/lib/CodeGen/CodeGen.cpp | 2 +- llvm/lib/CodeGen/LiveIntervals.cpp | 2 +- llvm/lib/CodeGen/LiveVariables.cpp | 66 +++++++++++++----- llvm/lib/CodeGen/MachineBasicBlock.cpp | 3 +- llvm/lib/CodeGen/MachineVerifier.cpp | 5 +- llvm/lib/CodeGen/PHIElimination.cpp | 9 +-- .../lib/CodeGen/TwoAddressInstructionPass.cpp | 7 +- llvm/lib/Passes/PassBuilder.cpp | 1 + llvm/lib/Target/AMDGPU/SILowerControlFlow.cpp | 3 +- .../Target/AMDGPU/SIOptimizeVGPRLiveRange.cpp | 8 +-- llvm/lib/Target/PowerPC/PPCMIPeephole.cpp | 8 +-- llvm/test/CodeGen/X86/live-vars.ll | 27 ++++++++ llvm/unittests/MI/LiveIntervalTest.cpp | 68 +++++++++--------- 16 files changed, 202 insertions(+), 92 deletions(-) create mode 100644 llvm/test/CodeGen/X86/live-vars.ll diff --git a/llvm/include/llvm/CodeGen/LiveVariables.h b/llvm/include/llvm/CodeGen/LiveVariables.h index 5d7f9ff3053cad..b73850bb757ec3 100644 --- a/llvm/include/llvm/CodeGen/LiveVariables.h +++ b/llvm/include/llvm/CodeGen/LiveVariables.h @@ -35,6 +35,7 @@ #include "llvm/ADT/SparseBitVector.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachinePassManager.h" #include "llvm/CodeGen/TargetRegisterInfo.h" #include "llvm/InitializePasses.h" #include "llvm/PassRegistry.h" @@ -44,13 +45,10 @@ namespace llvm { class MachineBasicBlock; class MachineRegisterInfo; -class LiveVariables : public MachineFunctionPass { -public: - static char ID; // Pass identification, replacement for typeid - LiveVariables() : MachineFunctionPass(ID) { - initializeLiveVariablesPass(*PassRegistry::getPassRegistry()); - } +class LiveVariables { + friend class LiveVariablesWrapperPass; +public: /// VarInfo - This represents the regions where a virtual register is live in /// the program. We represent this with three different pieces of /// information: the set of blocks in which the instruction is live @@ -109,6 +107,8 @@ class LiveVariables : public MachineFunctionPass { bool isLiveIn(const MachineBasicBlock &MBB, Register Reg, MachineRegisterInfo &MRI); + void print(raw_ostream &OS) const; + void dump() const; }; @@ -141,6 +141,11 @@ class LiveVariables : public MachineFunctionPass { // current basic block. DenseMap DistanceMap; + // For legacy pass. + LiveVariables() = default; + + void analyze(MachineFunction &MF); + /// HandlePhysRegKill - Add kills of Reg and its sub-registers to the /// uses. Pay special attention to the sub-register uses which may come below /// the last use of the whole register. @@ -174,9 +179,11 @@ class LiveVariables : public MachineFunctionPass { unsigned NumRegs); void runOnBlock(MachineBasicBlock *MBB, unsigned NumRegs); + public: + LiveVariables(MachineFunction &MF); - bool runOnMachineFunction(MachineFunction &MF) override; + void print(raw_ostream &OS) const; //===--------------------------------------------------------------------===// // API to update live variable information @@ -258,12 +265,6 @@ class LiveVariables : public MachineFunctionPass { return true; } - void getAnalysisUsage(AnalysisUsage &AU) const override; - - void releaseMemory() override { - VirtRegInfo.clear(); - } - /// getVarInfo - Return the VarInfo structure for the specified VIRTUAL /// register. VarInfo &getVarInfo(Register Reg); @@ -300,6 +301,48 @@ class LiveVariables : public MachineFunctionPass { std::vector> &LiveInSets); }; +class LiveVariablesAnalysis : public AnalysisInfoMixin { + friend AnalysisInfoMixin; + static AnalysisKey Key; + +public: + using Result = LiveVariables; + Result run(MachineFunction &MF, MachineFunctionAnalysisManager &); +}; + +class LiveVariablesPrinterPass + : public PassInfoMixin { + raw_ostream &OS; + +public: + explicit LiveVariablesPrinterPass(raw_ostream &OS) : OS(OS) {} + PreservedAnalyses run(MachineFunction &MF, + MachineFunctionAnalysisManager &MFAM); + static bool isRequired() { return true; } +}; + +class LiveVariablesWrapperPass : public MachineFunctionPass { + LiveVariables LV; + +public: + static char ID; // Pass identification, replacement for typeid + + LiveVariablesWrapperPass() : MachineFunctionPass(ID) { + initializeLiveVariablesWrapperPassPass(*PassRegistry::getPassRegistry()); + } + + bool runOnMachineFunction(MachineFunction &MF) override { + LV.analyze(MF); + return false; + } + + void getAnalysisUsage(AnalysisUsage &AU) const override; + + void releaseMemory() override { LV.VirtRegInfo.clear(); } + + LiveVariables &getLV() { return LV; } +}; + } // End llvm namespace #endif diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index 9d96e0f25ec1ea..0e798e4fd2e1f5 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -155,7 +155,7 @@ void initializeLiveIntervalsPass(PassRegistry&); void initializeLiveRangeShrinkPass(PassRegistry&); void initializeLiveRegMatrixPass(PassRegistry&); void initializeLiveStacksPass(PassRegistry&); -void initializeLiveVariablesPass(PassRegistry &); +void initializeLiveVariablesWrapperPassPass(PassRegistry &); void initializeLoadStoreOptPass(PassRegistry &); void initializeLoadStoreVectorizerLegacyPassPass(PassRegistry&); void initializeLocalStackSlotPassPass(PassRegistry&); diff --git a/llvm/include/llvm/Passes/MachinePassRegistry.def b/llvm/include/llvm/Passes/MachinePassRegistry.def index 95c618f743d2a0..2f838e0d4b3aeb 100644 --- a/llvm/include/llvm/Passes/MachinePassRegistry.def +++ b/llvm/include/llvm/Passes/MachinePassRegistry.def @@ -89,6 +89,12 @@ LOOP_PASS("loop-reduce", LoopStrengthReducePass()) #ifndef MACHINE_FUNCTION_ANALYSIS #define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) #endif +// LiveVariables currently requires pure SSA form. +// FIXME: Once TwoAddressInstruction pass no longer uses kill flags, +// LiveVariables can be removed completely, and LiveIntervals can be directly +// computed. (We still either need to regenerate kill flags after regalloc, or +// preferably fix the scavenger to not depend on them). +MACHINE_FUNCTION_ANALYSIS("live-vars", LiveVariablesAnalysis()) MACHINE_FUNCTION_ANALYSIS("machine-branch-prob", MachineBranchProbabilityAnalysis()) MACHINE_FUNCTION_ANALYSIS("machine-dom-tree", MachineDominatorTreeAnalysis()) @@ -96,13 +102,6 @@ MACHINE_FUNCTION_ANALYSIS("machine-loops", MachineLoopAnalysis()) MACHINE_FUNCTION_ANALYSIS("machine-post-dom-tree", MachinePostDominatorTreeAnalysis()) MACHINE_FUNCTION_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis(PIC)) -// LiveVariables currently requires pure SSA form. -// FIXME: Once TwoAddressInstruction pass no longer uses kill flags, -// LiveVariables can be removed completely, and LiveIntervals can be directly -// computed. (We still either need to regenerate kill flags after regalloc, or -// preferably fix the scavenger to not depend on them). -// MACHINE_FUNCTION_ANALYSIS("live-vars", LiveVariablesAnalysis()) - // MACHINE_FUNCTION_ANALYSIS("live-stacks", LiveStacksPass()) // MACHINE_FUNCTION_ANALYSIS("slot-indexes", SlotIndexesAnalysis()) // MACHINE_FUNCTION_ANALYSIS("edge-bundles", EdgeBundlesAnalysis()) @@ -133,6 +132,7 @@ MACHINE_FUNCTION_PASS("finalize-isel", FinalizeISelPass()) MACHINE_FUNCTION_PASS("localstackalloc", LocalStackSlotAllocationPass()) MACHINE_FUNCTION_PASS("no-op-machine-function", NoOpMachineFunctionPass()) MACHINE_FUNCTION_PASS("print", PrintMIRPass()) +MACHINE_FUNCTION_PASS("print", LiveVariablesPrinterPass(dbgs())) MACHINE_FUNCTION_PASS("print", MachineBranchProbabilityPrinterPass(dbgs())) MACHINE_FUNCTION_PASS("print", diff --git a/llvm/lib/CodeGen/CodeGen.cpp b/llvm/lib/CodeGen/CodeGen.cpp index 35e27519378f25..2680f2458cc14d 100644 --- a/llvm/lib/CodeGen/CodeGen.cpp +++ b/llvm/lib/CodeGen/CodeGen.cpp @@ -63,7 +63,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) { initializeLiveIntervalsPass(Registry); initializeLiveRangeShrinkPass(Registry); initializeLiveStacksPass(Registry); - initializeLiveVariablesPass(Registry); + initializeLiveVariablesWrapperPassPass(Registry); initializeLocalStackSlotPassPass(Registry); initializeLowerGlobalDtorsLegacyPassPass(Registry); initializeLowerIntrinsicsPass(Registry); diff --git a/llvm/lib/CodeGen/LiveIntervals.cpp b/llvm/lib/CodeGen/LiveIntervals.cpp index f9162b444e03d8..0fc878a53172aa 100644 --- a/llvm/lib/CodeGen/LiveIntervals.cpp +++ b/llvm/lib/CodeGen/LiveIntervals.cpp @@ -85,7 +85,7 @@ cl::opt UseSegmentSetForPhysRegs( void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); - AU.addPreserved(); + AU.addPreserved(); AU.addPreservedID(MachineLoopInfoID); AU.addRequiredTransitiveID(MachineDominatorsID); AU.addPreservedID(MachineDominatorsID); diff --git a/llvm/lib/CodeGen/LiveVariables.cpp b/llvm/lib/CodeGen/LiveVariables.cpp index f44db575a92506..f17d60dc22dda9 100644 --- a/llvm/lib/CodeGen/LiveVariables.cpp +++ b/llvm/lib/CodeGen/LiveVariables.cpp @@ -41,21 +41,49 @@ #include using namespace llvm; -char LiveVariables::ID = 0; -char &llvm::LiveVariablesID = LiveVariables::ID; -INITIALIZE_PASS_BEGIN(LiveVariables, "livevars", - "Live Variable Analysis", false, false) -INITIALIZE_PASS_DEPENDENCY(UnreachableMachineBlockElim) -INITIALIZE_PASS_END(LiveVariables, "livevars", - "Live Variable Analysis", false, false) +AnalysisKey LiveVariablesAnalysis::Key; + +LiveVariablesAnalysis::Result +LiveVariablesAnalysis::run(MachineFunction &MF, + MachineFunctionAnalysisManager &) { + return Result(MF); +} + +PreservedAnalyses +LiveVariablesPrinterPass::run(MachineFunction &MF, + MachineFunctionAnalysisManager &MFAM) { + OS << "Live variables in machine function: " << MF.getName() << '\n'; + MFAM.getResult(MF).print(OS); + return PreservedAnalyses::all(); +} +char LiveVariablesWrapperPass::ID = 0; +char &llvm::LiveVariablesID = LiveVariablesWrapperPass::ID; +INITIALIZE_PASS_BEGIN(LiveVariablesWrapperPass, "livevars", + "Live Variable Analysis", false, false) +INITIALIZE_PASS_DEPENDENCY(UnreachableMachineBlockElim) +INITIALIZE_PASS_END(LiveVariablesWrapperPass, "livevars", + "Live Variable Analysis", false, false) -void LiveVariables::getAnalysisUsage(AnalysisUsage &AU) const { +void LiveVariablesWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequiredID(UnreachableMachineBlockElimID); AU.setPreservesAll(); MachineFunctionPass::getAnalysisUsage(AU); } +LiveVariables::LiveVariables(MachineFunction &MF) + : MF(&MF), MRI(&MF.getRegInfo()), TRI(MF.getSubtarget().getRegisterInfo()) { + analyze(MF); +} + +void LiveVariables::print(raw_ostream &OS) const { + for (size_t I = 0, E = VirtRegInfo.size(); I != E; ++I) { + const Register Reg = Register::index2VirtReg(I); + OS << "Virtual register '%" << I << "':\n"; + VirtRegInfo[Reg].print(OS); + } +} + MachineInstr * LiveVariables::VarInfo::findKill(const MachineBasicBlock *MBB) const { for (MachineInstr *MI : Kills) @@ -64,20 +92,22 @@ LiveVariables::VarInfo::findKill(const MachineBasicBlock *MBB) const { return nullptr; } -#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) -LLVM_DUMP_METHOD void LiveVariables::VarInfo::dump() const { - dbgs() << " Alive in blocks: "; +void LiveVariables::VarInfo::print(raw_ostream &OS) const { + OS << " Alive in blocks: "; for (unsigned AB : AliveBlocks) - dbgs() << AB << ", "; - dbgs() << "\n Killed by:"; + OS << AB << ", "; + OS << "\n Killed by:"; if (Kills.empty()) - dbgs() << " No instructions.\n"; + OS << " No instructions.\n\n"; else { for (unsigned i = 0, e = Kills.size(); i != e; ++i) - dbgs() << "\n #" << i << ": " << *Kills[i]; - dbgs() << "\n"; + OS << "\n #" << i << ": " << *Kills[i]; + OS << "\n"; } } + +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) +LLVM_DUMP_METHOD void LiveVariables::VarInfo::dump() const { print(dbgs()); } #endif /// getVarInfo - Get (possibly creating) a VarInfo object for the given vreg. @@ -595,7 +625,7 @@ void LiveVariables::runOnBlock(MachineBasicBlock *MBB, unsigned NumRegs) { HandlePhysRegDef(i, nullptr, Defs); } -bool LiveVariables::runOnMachineFunction(MachineFunction &mf) { +void LiveVariables::analyze(MachineFunction &mf) { MF = &mf; MRI = &mf.getRegInfo(); TRI = MF->getSubtarget().getRegisterInfo(); @@ -649,8 +679,6 @@ bool LiveVariables::runOnMachineFunction(MachineFunction &mf) { PhysRegDef.clear(); PhysRegUse.clear(); PHIVarInfo.clear(); - - return false; } void LiveVariables::recomputeForSingleDefVirtReg(Register Reg) { diff --git a/llvm/lib/CodeGen/MachineBasicBlock.cpp b/llvm/lib/CodeGen/MachineBasicBlock.cpp index b5c3e1625f1aca..82c833ed97f590 100644 --- a/llvm/lib/CodeGen/MachineBasicBlock.cpp +++ b/llvm/lib/CodeGen/MachineBasicBlock.cpp @@ -1171,7 +1171,8 @@ MachineBasicBlock *MachineBasicBlock::SplitCriticalEdge( // On some targets like Mips, branches may kill virtual registers. Make sure // that LiveVariables is properly updated after updateTerminator replaces the // terminators. - LiveVariables *LV = P.getAnalysisIfAvailable(); + auto *LVWrapper = P.getAnalysisIfAvailable(); + LiveVariables *LV = LVWrapper ? &LVWrapper->getLV() : nullptr; // Collect a list of virtual registers killed by the terminators. SmallVector KilledRegs; diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp index 0c8a0f2b24a1ee..612631acb578ed 100644 --- a/llvm/lib/CodeGen/MachineVerifier.cpp +++ b/llvm/lib/CodeGen/MachineVerifier.cpp @@ -314,7 +314,7 @@ namespace { void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addUsedIfAvailable(); - AU.addUsedIfAvailable(); + AU.addUsedIfAvailable(); AU.addUsedIfAvailable(); AU.addUsedIfAvailable(); AU.setPreservesAll(); @@ -430,8 +430,9 @@ unsigned MachineVerifier::verify(const MachineFunction &MF) { if (PASS) { LiveInts = PASS->getAnalysisIfAvailable(); // We don't want to verify LiveVariables if LiveIntervals is available. + auto *LVWrapper = PASS->getAnalysisIfAvailable(); if (!LiveInts) - LiveVars = PASS->getAnalysisIfAvailable(); + LiveVars = LVWrapper ? &LVWrapper->getLV() : nullptr; LiveStks = PASS->getAnalysisIfAvailable(); Indexes = PASS->getAnalysisIfAvailable(); } diff --git a/llvm/lib/CodeGen/PHIElimination.cpp b/llvm/lib/CodeGen/PHIElimination.cpp index e5c4c71ad8132a..df51ddad9c2aea 100644 --- a/llvm/lib/CodeGen/PHIElimination.cpp +++ b/llvm/lib/CodeGen/PHIElimination.cpp @@ -131,13 +131,13 @@ char& llvm::PHIEliminationID = PHIElimination::ID; INITIALIZE_PASS_BEGIN(PHIElimination, DEBUG_TYPE, "Eliminate PHI nodes for register allocation", false, false) -INITIALIZE_PASS_DEPENDENCY(LiveVariables) +INITIALIZE_PASS_DEPENDENCY(LiveVariablesWrapperPass) INITIALIZE_PASS_END(PHIElimination, DEBUG_TYPE, "Eliminate PHI nodes for register allocation", false, false) void PHIElimination::getAnalysisUsage(AnalysisUsage &AU) const { - AU.addUsedIfAvailable(); - AU.addPreserved(); + AU.addUsedIfAvailable(); + AU.addPreserved(); AU.addPreserved(); AU.addPreserved(); AU.addPreserved(); @@ -147,7 +147,8 @@ void PHIElimination::getAnalysisUsage(AnalysisUsage &AU) const { bool PHIElimination::runOnMachineFunction(MachineFunction &MF) { MRI = &MF.getRegInfo(); - LV = getAnalysisIfAvailable(); + auto *LVWrapper = getAnalysisIfAvailable(); + LV = LVWrapper ? &LVWrapper->getLV() : nullptr; LIS = getAnalysisIfAvailable(); bool Changed = false; diff --git a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp index b9b2841e7c9ee4..bf6d694280aa17 100644 --- a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -195,8 +195,8 @@ class TwoAddressInstructionPass : public MachineFunctionPass { void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesCFG(); AU.addUsedIfAvailable(); - AU.addUsedIfAvailable(); - AU.addPreserved(); + AU.addUsedIfAvailable(); + AU.addPreserved(); AU.addPreserved(); AU.addPreserved(); AU.addPreservedID(MachineLoopInfoID); @@ -1762,7 +1762,8 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &Func) { TII = MF->getSubtarget().getInstrInfo(); TRI = MF->getSubtarget().getRegisterInfo(); InstrItins = MF->getSubtarget().getInstrItineraryData(); - LV = getAnalysisIfAvailable(); + auto *LVWrapper = getAnalysisIfAvailable(); + LV = LVWrapper ? &LVWrapper->getLV() : nullptr; LIS = getAnalysisIfAvailable(); if (auto *AAPass = getAnalysisIfAvailable()) AA = &AAPass->getAAResults(); diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index 6afcf35eb98696..4185eac5bc7ad5 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -90,6 +90,7 @@ #include "llvm/CodeGen/InterleavedAccess.h" #include "llvm/CodeGen/InterleavedLoadCombine.h" #include "llvm/CodeGen/JMCInstrumenter.h" +#include "llvm/CodeGen/LiveVariables.h" #include "llvm/CodeGen/LocalStackSlotAllocation.h" #include "llvm/CodeGen/LowerEmuTLS.h" #include "llvm/CodeGen/MIRPrinter.h" diff --git a/llvm/lib/Target/AMDGPU/SILowerControlFlow.cpp b/llvm/lib/Target/AMDGPU/SILowerControlFlow.cpp index 75a1575f2180ea..ec70099309e66c 100644 --- a/llvm/lib/Target/AMDGPU/SILowerControlFlow.cpp +++ b/llvm/lib/Target/AMDGPU/SILowerControlFlow.cpp @@ -763,7 +763,8 @@ bool SILowerControlFlow::runOnMachineFunction(MachineFunction &MF) { // This doesn't actually need LiveIntervals, but we can preserve them. LIS = getAnalysisIfAvailable(); // This doesn't actually need LiveVariables, but we can preserve them. - LV = getAnalysisIfAvailable(); + auto *LVWrapper = getAnalysisIfAvailable(); + LV = LVWrapper ? &LVWrapper->getLV() : nullptr; auto *MDTWrapper = getAnalysisIfAvailable(); MDT = MDTWrapper ? &MDTWrapper->getDomTree() : nullptr; MRI = &MF.getRegInfo(); diff --git a/llvm/lib/Target/AMDGPU/SIOptimizeVGPRLiveRange.cpp b/llvm/lib/Target/AMDGPU/SIOptimizeVGPRLiveRange.cpp index 1e0d1369f09d5b..50f536c532afc7 100644 --- a/llvm/lib/Target/AMDGPU/SIOptimizeVGPRLiveRange.cpp +++ b/llvm/lib/Target/AMDGPU/SIOptimizeVGPRLiveRange.cpp @@ -147,10 +147,10 @@ class SIOptimizeVGPRLiveRange : public MachineFunctionPass { } void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.addRequired(); + AU.addRequired(); AU.addRequired(); AU.addRequired(); - AU.addPreserved(); + AU.addPreserved(); AU.addPreserved(); AU.addPreserved(); MachineFunctionPass::getAnalysisUsage(AU); @@ -620,7 +620,7 @@ INITIALIZE_PASS_BEGIN(SIOptimizeVGPRLiveRange, DEBUG_TYPE, "SI Optimize VGPR LiveRange", false, false) INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass) -INITIALIZE_PASS_DEPENDENCY(LiveVariables) +INITIALIZE_PASS_DEPENDENCY(LiveVariablesWrapperPass) INITIALIZE_PASS_END(SIOptimizeVGPRLiveRange, DEBUG_TYPE, "SI Optimize VGPR LiveRange", false, false) @@ -637,7 +637,7 @@ bool SIOptimizeVGPRLiveRange::runOnMachineFunction(MachineFunction &MF) { TRI = &TII->getRegisterInfo(); MDT = &getAnalysis().getDomTree(); Loops = &getAnalysis().getLI(); - LV = &getAnalysis(); + LV = &getAnalysis().getLV(); MRI = &MF.getRegInfo(); if (skipFunction(MF.getFunction())) diff --git a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp index 0b515c9f798fe9..fa29ccbdf4c1fe 100644 --- a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp +++ b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp @@ -155,11 +155,11 @@ struct PPCMIPeephole : public MachineFunctionPass { public: void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.addRequired(); + AU.addRequired(); AU.addRequired(); AU.addRequired(); AU.addRequired(); - AU.addPreserved(); + AU.addPreserved(); AU.addPreserved(); AU.addPreserved(); AU.addPreserved(); @@ -203,7 +203,7 @@ void PPCMIPeephole::initialize(MachineFunction &MFParm) { MDT = &getAnalysis().getDomTree(); MPDT = &getAnalysis().getPostDomTree(); MBFI = &getAnalysis(); - LV = &getAnalysis(); + LV = &getAnalysis().getLV(); EntryFreq = MBFI->getEntryFreq(); TII = MF->getSubtarget().getInstrInfo(); RegsToUpdate.clear(); @@ -2034,7 +2034,7 @@ INITIALIZE_PASS_BEGIN(PPCMIPeephole, DEBUG_TYPE, INITIALIZE_PASS_DEPENDENCY(MachineBlockFrequencyInfo) INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTreeWrapperPass) -INITIALIZE_PASS_DEPENDENCY(LiveVariables) +INITIALIZE_PASS_DEPENDENCY(LiveVariablesWrapperPass) INITIALIZE_PASS_END(PPCMIPeephole, DEBUG_TYPE, "PowerPC MI Peephole Optimization", false, false) diff --git a/llvm/test/CodeGen/X86/live-vars.ll b/llvm/test/CodeGen/X86/live-vars.ll new file mode 100644 index 00000000000000..aa2448989059b3 --- /dev/null +++ b/llvm/test/CodeGen/X86/live-vars.ll @@ -0,0 +1,27 @@ +; RUN: llc -enable-new-pm -mtriple=x86_64-unknown -stop-after=x86-isel %s -o - | llc -passes='print' -x mir 2>&1 | FileCheck %s + +define i32 @foo(i32 noundef %0) local_unnamed_addr { + %2 = icmp eq i32 %0, 0 + br i1 %2, label %13, label %3 + +3: ; preds = %1 + %4 = add i32 %0, -1 + %5 = zext i32 %4 to i33 + %6 = add i32 %0, -2 + %7 = zext i32 %6 to i33 + %8 = mul i33 %5, %7 + %9 = lshr i33 %8, 1 + %10 = trunc i33 %9 to i32 + %11 = add i32 %10, %0 + %12 = add i32 %11, -1 + br label %13 + +13: ; preds = %3, %1 + %14 = phi i32 [ 0, %1 ], [ %12, %3 ] + ret i32 %14 +} + +; CHECK: Live variables in machine function: foo +; CHECK: Virtual register '%0': +; CHECK: Alive in blocks: +; CHECK: Killed by: No instructions. diff --git a/llvm/unittests/MI/LiveIntervalTest.cpp b/llvm/unittests/MI/LiveIntervalTest.cpp index 9623d9f58543f4..2ed25ec479601d 100644 --- a/llvm/unittests/MI/LiveIntervalTest.cpp +++ b/llvm/unittests/MI/LiveIntervalTest.cpp @@ -235,8 +235,8 @@ body: | } static void liveVariablesTest(StringRef MIRFunc, - TestPassT::TestFx T, - bool ShouldPass = true) { + TestPassT::TestFx T, + bool ShouldPass = true) { SmallString<160> S; StringRef MIRString = (Twine(R"MIR( --- @@ -248,7 +248,7 @@ tracksRegLiveness: true body: | bb.0: )MIR") + Twine(MIRFunc) + Twine("...\n")).toNullTerminatedStringRef(S); - doTest(MIRString, T, ShouldPass); + doTest(MIRString, T, ShouldPass); } } // End of anonymous namespace. @@ -812,43 +812,49 @@ TEST(LiveIntervalTest, LiveThroughSegments) { } TEST(LiveVariablesTest, recomputeForSingleDefVirtReg_handle_undef1) { - liveVariablesTest(R"MIR( + liveVariablesTest( + R"MIR( %0 = IMPLICIT_DEF S_NOP 0, implicit %0 S_NOP 0, implicit undef %0 -)MIR", [](MachineFunction &MF, LiveVariables &LV) { - auto &FirstNop = getMI(MF, 1, 0); - auto &SecondNop = getMI(MF, 2, 0); - EXPECT_TRUE(FirstNop.getOperand(1).isKill()); - EXPECT_FALSE(SecondNop.getOperand(1).isKill()); - - Register R = Register::index2VirtReg(0); - LV.recomputeForSingleDefVirtReg(R); - - EXPECT_TRUE(FirstNop.getOperand(1).isKill()); - EXPECT_FALSE(SecondNop.getOperand(1).isKill()); - }); +)MIR", + [](MachineFunction &MF, LiveVariablesWrapperPass &LVWrapper) { + auto &LV = LVWrapper.getLV(); + auto &FirstNop = getMI(MF, 1, 0); + auto &SecondNop = getMI(MF, 2, 0); + EXPECT_TRUE(FirstNop.getOperand(1).isKill()); + EXPECT_FALSE(SecondNop.getOperand(1).isKill()); + + Register R = Register::index2VirtReg(0); + LV.recomputeForSingleDefVirtReg(R); + + EXPECT_TRUE(FirstNop.getOperand(1).isKill()); + EXPECT_FALSE(SecondNop.getOperand(1).isKill()); + }); } TEST(LiveVariablesTest, recomputeForSingleDefVirtReg_handle_undef2) { - liveVariablesTest(R"MIR( + liveVariablesTest( + R"MIR( %0 = IMPLICIT_DEF S_NOP 0, implicit %0 S_NOP 0, implicit undef %0, implicit %0 -)MIR", [](MachineFunction &MF, LiveVariables &LV) { - auto &FirstNop = getMI(MF, 1, 0); - auto &SecondNop = getMI(MF, 2, 0); - EXPECT_FALSE(FirstNop.getOperand(1).isKill()); - EXPECT_FALSE(SecondNop.getOperand(1).isKill()); - EXPECT_TRUE(SecondNop.getOperand(2).isKill()); - - Register R = Register::index2VirtReg(0); - LV.recomputeForSingleDefVirtReg(R); - - EXPECT_FALSE(FirstNop.getOperand(1).isKill()); - EXPECT_FALSE(SecondNop.getOperand(1).isKill()); - EXPECT_TRUE(SecondNop.getOperand(2).isKill()); - }); +)MIR", + [](MachineFunction &MF, LiveVariablesWrapperPass &LVWrapper) { + auto &LV = LVWrapper.getLV(); + auto &FirstNop = getMI(MF, 1, 0); + auto &SecondNop = getMI(MF, 2, 0); + EXPECT_FALSE(FirstNop.getOperand(1).isKill()); + EXPECT_FALSE(SecondNop.getOperand(1).isKill()); + EXPECT_TRUE(SecondNop.getOperand(2).isKill()); + + Register R = Register::index2VirtReg(0); + LV.recomputeForSingleDefVirtReg(R); + + EXPECT_FALSE(FirstNop.getOperand(1).isKill()); + EXPECT_FALSE(SecondNop.getOperand(1).isKill()); + EXPECT_TRUE(SecondNop.getOperand(2).isKill()); + }); } int main(int argc, char **argv) {