Skip to content

Commit

Permalink
[CodeGen][NewPM] Port LiveIntervals to new pass manager (#98118)
Browse files Browse the repository at this point in the history
- Add `LiveIntervalsAnalysis`.
- Add `LiveIntervalsPrinterPass`.
- Use `LiveIntervalsWrapperPass` in legacy pass manager.
- Use `std::unique_ptr` instead of raw pointer for `LICalc`, so
destructor and default move constructor can handle it correctly.

This would be the last analysis required by `PHIElimination`.
  • Loading branch information
paperchalice authored Jul 10, 2024
1 parent 3e06392 commit abde52a
Show file tree
Hide file tree
Showing 59 changed files with 504 additions and 337 deletions.
84 changes: 71 additions & 13 deletions llvm/include/llvm/CodeGen/LiveIntervals.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@
#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/LiveInterval.h"
#include "llvm/CodeGen/LiveIntervalCalc.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachinePassManager.h"
#include "llvm/CodeGen/SlotIndexes.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/MC/LaneBitmask.h"
Expand All @@ -40,7 +42,6 @@ namespace llvm {
extern cl::opt<bool> UseSegmentSetForPhysRegs;

class BitVector;
class LiveIntervalCalc;
class MachineBlockFrequencyInfo;
class MachineDominatorTree;
class MachineFunction;
Expand All @@ -50,14 +51,17 @@ class raw_ostream;
class TargetInstrInfo;
class VirtRegMap;

class LiveIntervals : public MachineFunctionPass {
class LiveIntervals {
friend class LiveIntervalsAnalysis;
friend class LiveIntervalsWrapperPass;

MachineFunction *MF = nullptr;
MachineRegisterInfo *MRI = nullptr;
const TargetRegisterInfo *TRI = nullptr;
const TargetInstrInfo *TII = nullptr;
SlotIndexes *Indexes = nullptr;
MachineDominatorTree *DomTree = nullptr;
LiveIntervalCalc *LICalc = nullptr;
std::unique_ptr<LiveIntervalCalc> LICalc;

/// Special pool allocator for VNInfo's (LiveInterval val#).
VNInfo::Allocator VNInfoAllocator;
Expand Down Expand Up @@ -93,11 +97,20 @@ class LiveIntervals : public MachineFunctionPass {
/// interference.
SmallVector<LiveRange *, 0> RegUnitRanges;

public:
static char ID;
// Can only be created from pass manager.
LiveIntervals() = default;
LiveIntervals(MachineFunction &MF, SlotIndexes &SI, MachineDominatorTree &DT)
: Indexes(&SI), DomTree(&DT) {
analyze(MF);
}

void analyze(MachineFunction &MF);

LiveIntervals();
~LiveIntervals() override;
void clear();

public:
LiveIntervals(LiveIntervals &&) = default;
~LiveIntervals();

/// Calculate the spill weight to assign to a single instruction.
static float getSpillWeight(bool isDef, bool isUse,
Expand Down Expand Up @@ -279,14 +292,17 @@ class LiveIntervals : public MachineFunctionPass {

VNInfo::Allocator &getVNInfoAllocator() { return VNInfoAllocator; }

void getAnalysisUsage(AnalysisUsage &AU) const override;
void releaseMemory() override;
/// Implement the dump method.
void print(raw_ostream &O) const;
void dump() const;

/// Pass entry point; Calculates LiveIntervals.
bool runOnMachineFunction(MachineFunction &) override;
// For legacy pass to recompute liveness.
void reanalyze(MachineFunction &MF) {
clear();
analyze(MF);
}

/// Implement the dump method.
void print(raw_ostream &O, const Module * = nullptr) const override;
MachineDominatorTree &getDomTree() { return *DomTree; }

/// If LI is confined to a single basic block, return a pointer to that
/// block. If LI is live in to or out of any block, return NULL.
Expand Down Expand Up @@ -480,6 +496,48 @@ class LiveIntervals : public MachineFunctionPass {
class HMEditor;
};

class LiveIntervalsAnalysis : public AnalysisInfoMixin<LiveIntervalsAnalysis> {
friend AnalysisInfoMixin<LiveIntervalsAnalysis>;
static AnalysisKey Key;

public:
using Result = LiveIntervals;
Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM);
};

class LiveIntervalsPrinterPass
: public PassInfoMixin<LiveIntervalsPrinterPass> {
raw_ostream &OS;

public:
explicit LiveIntervalsPrinterPass(raw_ostream &OS) : OS(OS) {}
PreservedAnalyses run(MachineFunction &MF,
MachineFunctionAnalysisManager &MFAM);
static bool isRequired() { return true; }
};

class LiveIntervalsWrapperPass : public MachineFunctionPass {
LiveIntervals LIS;

public:
static char ID;

LiveIntervalsWrapperPass();

void getAnalysisUsage(AnalysisUsage &AU) const override;
void releaseMemory() override { LIS.clear(); }

/// Pass entry point; Calculates LiveIntervals.
bool runOnMachineFunction(MachineFunction &) override;

/// Implement the dump method.
void print(raw_ostream &O, const Module * = nullptr) const override {
LIS.print(O);
}

LiveIntervals &getLIS() { return LIS; }
};

} // end namespace llvm

#endif
2 changes: 1 addition & 1 deletion llvm/include/llvm/InitializePasses.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ void initializeGISelCSEAnalysisWrapperPassPass(PassRegistry &);
void initializeGISelKnownBitsAnalysisPass(PassRegistry &);
void initializeLiveDebugValuesPass(PassRegistry&);
void initializeLiveDebugVariablesPass(PassRegistry&);
void initializeLiveIntervalsPass(PassRegistry&);
void initializeLiveIntervalsWrapperPassPass(PassRegistry &);
void initializeLiveRangeShrinkPass(PassRegistry&);
void initializeLiveRegMatrixPass(PassRegistry&);
void initializeLiveStacksPass(PassRegistry&);
Expand Down
3 changes: 2 additions & 1 deletion llvm/include/llvm/Passes/CodeGenPassBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "llvm/CodeGen/InterleavedAccess.h"
#include "llvm/CodeGen/InterleavedLoadCombine.h"
#include "llvm/CodeGen/JMCInstrumenter.h"
#include "llvm/CodeGen/LiveIntervals.h"
#include "llvm/CodeGen/LocalStackSlotAllocation.h"
#include "llvm/CodeGen/LowerEmuTLS.h"
#include "llvm/CodeGen/MIRPrinter.h"
Expand Down Expand Up @@ -1106,7 +1107,7 @@ void CodeGenPassBuilder<Derived, TargetMachineT>::addOptimizedRegAlloc(

// Eventually, we want to run LiveIntervals before PHI elimination.
if (Opt.EarlyLiveIntervals)
addPass(LiveIntervalsPass());
addPass(RequireAnalysisPass<LiveIntervalsAnalysis, MachineFunction>());

addPass(TwoAddressInstructionPass());
addPass(RegisterCoalescerPass());
Expand Down
3 changes: 2 additions & 1 deletion llvm/include/llvm/Passes/MachinePassRegistry.def
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ LOOP_PASS("loop-reduce", LoopStrengthReducePass())
// 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-intervals", LiveIntervalsAnalysis())
MACHINE_FUNCTION_ANALYSIS("live-vars", LiveVariablesAnalysis())
MACHINE_FUNCTION_ANALYSIS("machine-branch-prob",
MachineBranchProbabilityAnalysis())
Expand Down Expand Up @@ -132,6 +133,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<live-intervals>", LiveIntervalsPrinterPass(dbgs()))
MACHINE_FUNCTION_PASS("print<live-vars>", LiveVariablesPrinterPass(dbgs()))
MACHINE_FUNCTION_PASS("print<machine-branch-prob>",
MachineBranchProbabilityPrinterPass(dbgs()))
Expand Down Expand Up @@ -208,7 +210,6 @@ DUMMY_MACHINE_FUNCTION_PASS("irtranslator", IRTranslatorPass)
DUMMY_MACHINE_FUNCTION_PASS("kcfi", MachineKCFIPass)
DUMMY_MACHINE_FUNCTION_PASS("legalizer", LegalizerPass)
DUMMY_MACHINE_FUNCTION_PASS("livedebugvalues", LiveDebugValuesPass)
DUMMY_MACHINE_FUNCTION_PASS("liveintervals", LiveIntervalsPass)
DUMMY_MACHINE_FUNCTION_PASS("lrshrink", LiveRangeShrinkPass)
DUMMY_MACHINE_FUNCTION_PASS("machine-combiner", MachineCombinerPass)
DUMMY_MACHINE_FUNCTION_PASS("machine-cp", MachineCopyPropagationPass)
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/CodeGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
initializeJMCInstrumenterPass(Registry);
initializeLiveDebugValuesPass(Registry);
initializeLiveDebugVariablesPass(Registry);
initializeLiveIntervalsPass(Registry);
initializeLiveIntervalsWrapperPassPass(Registry);
initializeLiveRangeShrinkPass(Registry);
initializeLiveStacksPass(Registry);
initializeLiveVariablesWrapperPassPass(Registry);
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/CodeGen/InlineSpiller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ class HoistSpillHelper : private LiveRangeEdit::Delegate {
public:
HoistSpillHelper(MachineFunctionPass &pass, MachineFunction &mf,
VirtRegMap &vrm)
: MF(mf), LIS(pass.getAnalysis<LiveIntervals>()),
: MF(mf), LIS(pass.getAnalysis<LiveIntervalsWrapperPass>().getLIS()),
LSS(pass.getAnalysis<LiveStacks>()),
MDT(pass.getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree()),
VRM(vrm), MRI(mf.getRegInfo()), TII(*mf.getSubtarget().getInstrInfo()),
Expand Down Expand Up @@ -188,7 +188,7 @@ class InlineSpiller : public Spiller {
public:
InlineSpiller(MachineFunctionPass &Pass, MachineFunction &MF, VirtRegMap &VRM,
VirtRegAuxInfo &VRAI)
: MF(MF), LIS(Pass.getAnalysis<LiveIntervals>()),
: MF(MF), LIS(Pass.getAnalysis<LiveIntervalsWrapperPass>().getLIS()),
LSS(Pass.getAnalysis<LiveStacks>()),
MDT(Pass.getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree()),
VRM(VRM), MRI(MF.getRegInfo()), TII(*MF.getSubtarget().getInstrInfo()),
Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/CodeGen/LiveDebugVariables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,13 @@ char LiveDebugVariables::ID = 0;
INITIALIZE_PASS_BEGIN(LiveDebugVariables, DEBUG_TYPE,
"Debug Variable Analysis", false, false)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
INITIALIZE_PASS_END(LiveDebugVariables, DEBUG_TYPE,
"Debug Variable Analysis", false, false)

void LiveDebugVariables::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<MachineDominatorTreeWrapperPass>();
AU.addRequiredTransitive<LiveIntervals>();
AU.addRequiredTransitive<LiveIntervalsWrapperPass>();
AU.setPreservesAll();
MachineFunctionPass::getAnalysisUsage(AU);
}
Expand Down Expand Up @@ -1263,7 +1263,7 @@ void LDVImpl::computeIntervals() {
bool LDVImpl::runOnMachineFunction(MachineFunction &mf, bool InstrRef) {
clear();
MF = &mf;
LIS = &pass.getAnalysis<LiveIntervals>();
LIS = &pass.getAnalysis<LiveIntervalsWrapperPass>().getLIS();
TRI = mf.getSubtarget().getRegisterInfo();
LLVM_DEBUG(dbgs() << "********** COMPUTING LIVE DEBUG VARIABLES: "
<< mf.getName() << " **********\n");
Expand Down
61 changes: 43 additions & 18 deletions llvm/lib/CodeGen/LiveIntervals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,39 @@ using namespace llvm;

#define DEBUG_TYPE "regalloc"

char LiveIntervals::ID = 0;
char &llvm::LiveIntervalsID = LiveIntervals::ID;
INITIALIZE_PASS_BEGIN(LiveIntervals, "liveintervals", "Live Interval Analysis",
false, false)
AnalysisKey LiveIntervalsAnalysis::Key;

LiveIntervalsAnalysis::Result
LiveIntervalsAnalysis::run(MachineFunction &MF,
MachineFunctionAnalysisManager &MFAM) {
return Result(MF, MFAM.getResult<SlotIndexesAnalysis>(MF),
MFAM.getResult<MachineDominatorTreeAnalysis>(MF));
}

PreservedAnalyses
LiveIntervalsPrinterPass::run(MachineFunction &MF,
MachineFunctionAnalysisManager &MFAM) {
OS << "Live intervals for machine function: " << MF.getName() << ":\n";
MFAM.getResult<LiveIntervalsAnalysis>(MF).print(OS);
return PreservedAnalyses::all();
}

char LiveIntervalsWrapperPass::ID = 0;
char &llvm::LiveIntervalsID = LiveIntervalsWrapperPass::ID;
INITIALIZE_PASS_BEGIN(LiveIntervalsWrapperPass, "liveintervals",
"Live Interval Analysis", false, false)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(SlotIndexesWrapperPass)
INITIALIZE_PASS_END(LiveIntervals, "liveintervals",
"Live Interval Analysis", false, false)
INITIALIZE_PASS_END(LiveIntervalsWrapperPass, "liveintervals",
"Live Interval Analysis", false, false)

bool LiveIntervalsWrapperPass::runOnMachineFunction(MachineFunction &MF) {
LIS.Indexes = &getAnalysis<SlotIndexesWrapperPass>().getSI();
LIS.DomTree = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
LIS.analyze(MF);
LLVM_DEBUG(dump());
return false;
}

#ifndef NDEBUG
static cl::opt<bool> EnablePrecomputePhysRegs(
Expand All @@ -83,7 +108,7 @@ cl::opt<bool> UseSegmentSetForPhysRegs(

} // end namespace llvm

void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const {
void LiveIntervalsWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesCFG();
AU.addPreserved<LiveVariablesWrapperPass>();
AU.addPreservedID(MachineLoopInfoID);
Expand All @@ -94,13 +119,13 @@ void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const {
MachineFunctionPass::getAnalysisUsage(AU);
}

LiveIntervals::LiveIntervals() : MachineFunctionPass(ID) {
initializeLiveIntervalsPass(*PassRegistry::getPassRegistry());
LiveIntervalsWrapperPass::LiveIntervalsWrapperPass() : MachineFunctionPass(ID) {
initializeLiveIntervalsWrapperPassPass(*PassRegistry::getPassRegistry());
}

LiveIntervals::~LiveIntervals() { delete LICalc; }
LiveIntervals::~LiveIntervals() { clear(); }

void LiveIntervals::releaseMemory() {
void LiveIntervals::clear() {
// Free the live intervals themselves.
for (unsigned i = 0, e = VirtRegIntervals.size(); i != e; ++i)
delete VirtRegIntervals[Register::index2VirtReg(i)];
Expand All @@ -117,16 +142,14 @@ void LiveIntervals::releaseMemory() {
VNInfoAllocator.Reset();
}

bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
void LiveIntervals::analyze(MachineFunction &fn) {
MF = &fn;
MRI = &MF->getRegInfo();
TRI = MF->getSubtarget().getRegisterInfo();
TII = MF->getSubtarget().getInstrInfo();
Indexes = &getAnalysis<SlotIndexesWrapperPass>().getSI();
DomTree = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();

if (!LICalc)
LICalc = new LiveIntervalCalc();
LICalc = std::make_unique<LiveIntervalCalc>();

// Allocate space for all virtual registers.
VirtRegIntervals.resize(MRI->getNumVirtRegs());
Expand All @@ -141,11 +164,9 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
for (unsigned i = 0, e = TRI->getNumRegUnits(); i != e; ++i)
getRegUnit(i);
}
LLVM_DEBUG(dump());
return false;
}

void LiveIntervals::print(raw_ostream &OS, const Module* ) const {
void LiveIntervals::print(raw_ostream &OS) const {
OS << "********** INTERVALS **********\n";

// Dump the regunits.
Expand Down Expand Up @@ -179,6 +200,10 @@ LLVM_DUMP_METHOD void LiveIntervals::dumpInstrs() const {
}
#endif

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void LiveIntervals::dump() const { print(dbgs()); }
#endif

LiveInterval *LiveIntervals::createInterval(Register reg) {
float Weight = reg.isPhysical() ? huge_valf : 0.0F;
return new LiveInterval(reg, Weight);
Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/CodeGen/LiveRegMatrix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ STATISTIC(NumUnassigned , "Number of registers unassigned");
char LiveRegMatrix::ID = 0;
INITIALIZE_PASS_BEGIN(LiveRegMatrix, "liveregmatrix",
"Live Register Matrix", false, false)
INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
INITIALIZE_PASS_DEPENDENCY(VirtRegMap)
INITIALIZE_PASS_END(LiveRegMatrix, "liveregmatrix",
"Live Register Matrix", false, false)
Expand All @@ -47,14 +47,14 @@ LiveRegMatrix::LiveRegMatrix() : MachineFunctionPass(ID) {}

void LiveRegMatrix::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequiredTransitive<LiveIntervals>();
AU.addRequiredTransitive<LiveIntervalsWrapperPass>();
AU.addRequiredTransitive<VirtRegMap>();
MachineFunctionPass::getAnalysisUsage(AU);
}

bool LiveRegMatrix::runOnMachineFunction(MachineFunction &MF) {
TRI = MF.getSubtarget().getRegisterInfo();
LIS = &getAnalysis<LiveIntervals>();
LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
VRM = &getAnalysis<VirtRegMap>();

unsigned NumRegUnits = TRI->getNumRegUnits();
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/CodeGen/MachineBasicBlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1161,7 +1161,8 @@ MachineBasicBlock *MachineBasicBlock::SplitCriticalEdge(
<< " -- " << printMBBReference(*NMBB) << " -- "
<< printMBBReference(*Succ) << '\n');

LiveIntervals *LIS = P.getAnalysisIfAvailable<LiveIntervals>();
auto *LISWrapper = P.getAnalysisIfAvailable<LiveIntervalsWrapperPass>();
LiveIntervals *LIS = LISWrapper ? &LISWrapper->getLIS() : nullptr;
auto *SIWrapper = P.getAnalysisIfAvailable<SlotIndexesWrapperPass>();
SlotIndexes *Indexes = SIWrapper ? &SIWrapper->getSI() : nullptr;
if (LIS)
Expand Down
Loading

0 comments on commit abde52a

Please sign in to comment.