Skip to content

Commit 9380281

Browse files
authored
[NewPM][CodeGen] Port VirtRegMap to NPM (#109936)
1 parent 83c6e2f commit 9380281

15 files changed

+227
-167
lines changed

llvm/include/llvm/CodeGen/VirtRegMap.h

Lines changed: 171 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "llvm/CodeGen/MachineFunctionPass.h"
2121
#include "llvm/CodeGen/TargetRegisterInfo.h"
2222
#include "llvm/CodeGen/TileShapeInfo.h"
23+
#include "llvm/IR/PassManager.h"
2324
#include "llvm/Pass.h"
2425
#include <cassert>
2526

@@ -30,171 +31,210 @@ class MachineRegisterInfo;
3031
class raw_ostream;
3132
class TargetInstrInfo;
3233

33-
class VirtRegMap : public MachineFunctionPass {
34-
MachineRegisterInfo *MRI = nullptr;
35-
const TargetInstrInfo *TII = nullptr;
36-
const TargetRegisterInfo *TRI = nullptr;
37-
MachineFunction *MF = nullptr;
38-
39-
/// Virt2PhysMap - This is a virtual to physical register
40-
/// mapping. Each virtual register is required to have an entry in
41-
/// it; even spilled virtual registers (the register mapped to a
42-
/// spilled register is the temporary used to load it from the
43-
/// stack).
44-
IndexedMap<MCRegister, VirtReg2IndexFunctor> Virt2PhysMap;
34+
class VirtRegMap {
35+
MachineRegisterInfo *MRI = nullptr;
36+
const TargetInstrInfo *TII = nullptr;
37+
const TargetRegisterInfo *TRI = nullptr;
38+
MachineFunction *MF = nullptr;
39+
40+
/// Virt2PhysMap - This is a virtual to physical register
41+
/// mapping. Each virtual register is required to have an entry in
42+
/// it; even spilled virtual registers (the register mapped to a
43+
/// spilled register is the temporary used to load it from the
44+
/// stack).
45+
IndexedMap<MCRegister, VirtReg2IndexFunctor> Virt2PhysMap;
46+
47+
/// Virt2StackSlotMap - This is virtual register to stack slot
48+
/// mapping. Each spilled virtual register has an entry in it
49+
/// which corresponds to the stack slot this register is spilled
50+
/// at.
51+
IndexedMap<int, VirtReg2IndexFunctor> Virt2StackSlotMap;
52+
53+
/// Virt2SplitMap - This is virtual register to splitted virtual register
54+
/// mapping.
55+
IndexedMap<Register, VirtReg2IndexFunctor> Virt2SplitMap;
56+
57+
/// Virt2ShapeMap - For X86 AMX register whose register is bound shape
58+
/// information.
59+
DenseMap<Register, ShapeT> Virt2ShapeMap;
60+
61+
/// createSpillSlot - Allocate a spill slot for RC from MFI.
62+
unsigned createSpillSlot(const TargetRegisterClass *RC);
63+
64+
public:
65+
static constexpr int NO_STACK_SLOT = INT_MAX;
66+
67+
VirtRegMap() : Virt2StackSlotMap(NO_STACK_SLOT) {}
68+
VirtRegMap(const VirtRegMap &) = delete;
69+
VirtRegMap &operator=(const VirtRegMap &) = delete;
70+
VirtRegMap(VirtRegMap &&) = default;
71+
72+
void init(MachineFunction &MF);
73+
74+
MachineFunction &getMachineFunction() const {
75+
assert(MF && "getMachineFunction called before runOnMachineFunction");
76+
return *MF;
77+
}
4578

46-
/// Virt2StackSlotMap - This is virtual register to stack slot
47-
/// mapping. Each spilled virtual register has an entry in it
48-
/// which corresponds to the stack slot this register is spilled
49-
/// at.
50-
IndexedMap<int, VirtReg2IndexFunctor> Virt2StackSlotMap;
79+
MachineRegisterInfo &getRegInfo() const { return *MRI; }
80+
const TargetRegisterInfo &getTargetRegInfo() const { return *TRI; }
5181

52-
/// Virt2SplitMap - This is virtual register to splitted virtual register
53-
/// mapping.
54-
IndexedMap<Register, VirtReg2IndexFunctor> Virt2SplitMap;
82+
void grow();
5583

56-
/// Virt2ShapeMap - For X86 AMX register whose register is bound shape
57-
/// information.
58-
DenseMap<Register, ShapeT> Virt2ShapeMap;
84+
/// returns true if the specified virtual register is
85+
/// mapped to a physical register
86+
bool hasPhys(Register virtReg) const { return getPhys(virtReg).isValid(); }
5987

60-
/// createSpillSlot - Allocate a spill slot for RC from MFI.
61-
unsigned createSpillSlot(const TargetRegisterClass *RC);
88+
/// returns the physical register mapped to the specified
89+
/// virtual register
90+
MCRegister getPhys(Register virtReg) const {
91+
assert(virtReg.isVirtual());
92+
return Virt2PhysMap[virtReg];
93+
}
6294

63-
public:
64-
static char ID;
95+
/// creates a mapping for the specified virtual register to
96+
/// the specified physical register
97+
void assignVirt2Phys(Register virtReg, MCPhysReg physReg);
6598

66-
static constexpr int NO_STACK_SLOT = INT_MAX;
99+
bool isShapeMapEmpty() const { return Virt2ShapeMap.empty(); }
67100

68-
VirtRegMap() : MachineFunctionPass(ID), Virt2StackSlotMap(NO_STACK_SLOT) {}
69-
VirtRegMap(const VirtRegMap &) = delete;
70-
VirtRegMap &operator=(const VirtRegMap &) = delete;
101+
bool hasShape(Register virtReg) const {
102+
return Virt2ShapeMap.contains(virtReg);
103+
}
71104

72-
bool runOnMachineFunction(MachineFunction &MF) override;
105+
ShapeT getShape(Register virtReg) const {
106+
assert(virtReg.isVirtual());
107+
return Virt2ShapeMap.lookup(virtReg);
108+
}
73109

74-
void getAnalysisUsage(AnalysisUsage &AU) const override {
75-
AU.setPreservesAll();
76-
MachineFunctionPass::getAnalysisUsage(AU);
77-
}
110+
void assignVirt2Shape(Register virtReg, ShapeT shape) {
111+
Virt2ShapeMap[virtReg] = shape;
112+
}
78113

79-
MachineFunction &getMachineFunction() const {
80-
assert(MF && "getMachineFunction called before runOnMachineFunction");
81-
return *MF;
82-
}
114+
/// clears the specified virtual register's, physical
115+
/// register mapping
116+
void clearVirt(Register virtReg) {
117+
assert(virtReg.isVirtual());
118+
assert(Virt2PhysMap[virtReg] &&
119+
"attempt to clear a not assigned virtual register");
120+
Virt2PhysMap[virtReg] = MCRegister();
121+
}
83122

84-
MachineRegisterInfo &getRegInfo() const { return *MRI; }
85-
const TargetRegisterInfo &getTargetRegInfo() const { return *TRI; }
123+
/// clears all virtual to physical register mappings
124+
void clearAllVirt() {
125+
Virt2PhysMap.clear();
126+
grow();
127+
}
86128

87-
void grow();
129+
/// returns true if VirtReg is assigned to its preferred physreg.
130+
bool hasPreferredPhys(Register VirtReg) const;
88131

89-
/// returns true if the specified virtual register is
90-
/// mapped to a physical register
91-
bool hasPhys(Register virtReg) const { return getPhys(virtReg).isValid(); }
132+
/// returns true if VirtReg has a known preferred register.
133+
/// This returns false if VirtReg has a preference that is a virtual
134+
/// register that hasn't been assigned yet.
135+
bool hasKnownPreference(Register VirtReg) const;
92136

93-
/// returns the physical register mapped to the specified
94-
/// virtual register
95-
MCRegister getPhys(Register virtReg) const {
96-
assert(virtReg.isVirtual());
97-
return Virt2PhysMap[virtReg];
137+
/// records virtReg is a split live interval from SReg.
138+
void setIsSplitFromReg(Register virtReg, Register SReg) {
139+
Virt2SplitMap[virtReg] = SReg;
140+
if (hasShape(SReg)) {
141+
Virt2ShapeMap[virtReg] = getShape(SReg);
98142
}
143+
}
99144

100-
/// creates a mapping for the specified virtual register to
101-
/// the specified physical register
102-
void assignVirt2Phys(Register virtReg, MCPhysReg physReg);
145+
/// returns the live interval virtReg is split from.
146+
Register getPreSplitReg(Register virtReg) const {
147+
return Virt2SplitMap[virtReg];
148+
}
103149

104-
bool isShapeMapEmpty() const { return Virt2ShapeMap.empty(); }
150+
/// getOriginal - Return the original virtual register that VirtReg descends
151+
/// from through splitting.
152+
/// A register that was not created by splitting is its own original.
153+
/// This operation is idempotent.
154+
Register getOriginal(Register VirtReg) const {
155+
Register Orig = getPreSplitReg(VirtReg);
156+
return Orig ? Orig : VirtReg;
157+
}
105158

106-
bool hasShape(Register virtReg) const {
107-
return Virt2ShapeMap.contains(virtReg);
108-
}
159+
/// returns true if the specified virtual register is not
160+
/// mapped to a stack slot or rematerialized.
161+
bool isAssignedReg(Register virtReg) const {
162+
if (getStackSlot(virtReg) == NO_STACK_SLOT)
163+
return true;
164+
// Split register can be assigned a physical register as well as a
165+
// stack slot or remat id.
166+
return (Virt2SplitMap[virtReg] && Virt2PhysMap[virtReg]);
167+
}
109168

110-
ShapeT getShape(Register virtReg) const {
111-
assert(virtReg.isVirtual());
112-
return Virt2ShapeMap.lookup(virtReg);
113-
}
169+
/// returns the stack slot mapped to the specified virtual
170+
/// register
171+
int getStackSlot(Register virtReg) const {
172+
assert(virtReg.isVirtual());
173+
return Virt2StackSlotMap[virtReg];
174+
}
114175

115-
void assignVirt2Shape(Register virtReg, ShapeT shape) {
116-
Virt2ShapeMap[virtReg] = shape;
117-
}
176+
/// create a mapping for the specifed virtual register to
177+
/// the next available stack slot
178+
int assignVirt2StackSlot(Register virtReg);
118179

119-
/// clears the specified virtual register's, physical
120-
/// register mapping
121-
void clearVirt(Register virtReg) {
122-
assert(virtReg.isVirtual());
123-
assert(Virt2PhysMap[virtReg] &&
124-
"attempt to clear a not assigned virtual register");
125-
Virt2PhysMap[virtReg] = MCRegister();
126-
}
180+
/// create a mapping for the specified virtual register to
181+
/// the specified stack slot
182+
void assignVirt2StackSlot(Register virtReg, int SS);
127183

128-
/// clears all virtual to physical register mappings
129-
void clearAllVirt() {
130-
Virt2PhysMap.clear();
131-
grow();
132-
}
184+
void print(raw_ostream &OS, const Module *M = nullptr) const;
185+
void dump() const;
186+
};
133187

134-
/// returns true if VirtReg is assigned to its preferred physreg.
135-
bool hasPreferredPhys(Register VirtReg) const;
188+
inline raw_ostream &operator<<(raw_ostream &OS, const VirtRegMap &VRM) {
189+
VRM.print(OS);
190+
return OS;
191+
}
136192

137-
/// returns true if VirtReg has a known preferred register.
138-
/// This returns false if VirtReg has a preference that is a virtual
139-
/// register that hasn't been assigned yet.
140-
bool hasKnownPreference(Register VirtReg) const;
193+
class VirtRegMapWrapperLegacy : public MachineFunctionPass {
194+
VirtRegMap VRM;
141195

142-
/// records virtReg is a split live interval from SReg.
143-
void setIsSplitFromReg(Register virtReg, Register SReg) {
144-
Virt2SplitMap[virtReg] = SReg;
145-
if (hasShape(SReg)) {
146-
Virt2ShapeMap[virtReg] = getShape(SReg);
147-
}
148-
}
196+
public:
197+
static char ID;
149198

150-
/// returns the live interval virtReg is split from.
151-
Register getPreSplitReg(Register virtReg) const {
152-
return Virt2SplitMap[virtReg];
153-
}
199+
VirtRegMapWrapperLegacy() : MachineFunctionPass(ID) {}
154200

155-
/// getOriginal - Return the original virtual register that VirtReg descends
156-
/// from through splitting.
157-
/// A register that was not created by splitting is its own original.
158-
/// This operation is idempotent.
159-
Register getOriginal(Register VirtReg) const {
160-
Register Orig = getPreSplitReg(VirtReg);
161-
return Orig ? Orig : VirtReg;
162-
}
201+
void print(raw_ostream &OS, const Module *M = nullptr) const override {
202+
VRM.print(OS, M);
203+
}
163204

164-
/// returns true if the specified virtual register is not
165-
/// mapped to a stack slot or rematerialized.
166-
bool isAssignedReg(Register virtReg) const {
167-
if (getStackSlot(virtReg) == NO_STACK_SLOT)
168-
return true;
169-
// Split register can be assigned a physical register as well as a
170-
// stack slot or remat id.
171-
return (Virt2SplitMap[virtReg] && Virt2PhysMap[virtReg]);
172-
}
205+
VirtRegMap &getVRM() { return VRM; }
206+
const VirtRegMap &getVRM() const { return VRM; }
173207

174-
/// returns the stack slot mapped to the specified virtual
175-
/// register
176-
int getStackSlot(Register virtReg) const {
177-
assert(virtReg.isVirtual());
178-
return Virt2StackSlotMap[virtReg];
179-
}
208+
bool runOnMachineFunction(MachineFunction &MF) override {
209+
VRM.init(MF);
210+
return false;
211+
}
180212

181-
/// create a mapping for the specifed virtual register to
182-
/// the next available stack slot
183-
int assignVirt2StackSlot(Register virtReg);
213+
void getAnalysisUsage(AnalysisUsage &AU) const override {
214+
AU.setPreservesAll();
215+
MachineFunctionPass::getAnalysisUsage(AU);
216+
}
217+
};
184218

185-
/// create a mapping for the specified virtual register to
186-
/// the specified stack slot
187-
void assignVirt2StackSlot(Register virtReg, int SS);
219+
class VirtRegMapAnalysis : public AnalysisInfoMixin<VirtRegMapAnalysis> {
220+
friend AnalysisInfoMixin<VirtRegMapAnalysis>;
221+
static AnalysisKey Key;
188222

189-
void print(raw_ostream &OS, const Module* M = nullptr) const override;
190-
void dump() const;
191-
};
223+
public:
224+
using Result = VirtRegMap;
192225

193-
inline raw_ostream &operator<<(raw_ostream &OS, const VirtRegMap &VRM) {
194-
VRM.print(OS);
195-
return OS;
196-
}
226+
VirtRegMap run(MachineFunction &MF, MachineFunctionAnalysisManager &MAM);
227+
};
228+
229+
class VirtRegMapPrinterPass : public PassInfoMixin<VirtRegMapPrinterPass> {
230+
raw_ostream &OS;
197231

232+
public:
233+
explicit VirtRegMapPrinterPass(raw_ostream &OS) : OS(OS) {}
234+
PreservedAnalyses run(MachineFunction &MF,
235+
MachineFunctionAnalysisManager &MFAM);
236+
static bool isRequired() { return true; }
237+
};
198238
} // end llvm namespace
199239

200240
#endif // LLVM_CODEGEN_VIRTREGMAP_H

llvm/include/llvm/InitializePasses.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ void initializeUnpackMachineBundlesPass(PassRegistry &);
315315
void initializeUnreachableBlockElimLegacyPassPass(PassRegistry &);
316316
void initializeUnreachableMachineBlockElimPass(PassRegistry &);
317317
void initializeVerifierLegacyPassPass(PassRegistry &);
318-
void initializeVirtRegMapPass(PassRegistry &);
318+
void initializeVirtRegMapWrapperLegacyPass(PassRegistry &);
319319
void initializeVirtRegRewriterPass(PassRegistry &);
320320
void initializeWasmEHPreparePass(PassRegistry &);
321321
void initializeWinEHPreparePass(PassRegistry &);

llvm/include/llvm/Passes/MachinePassRegistry.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ MACHINE_FUNCTION_ANALYSIS("machine-post-dom-tree",
109109
MACHINE_FUNCTION_ANALYSIS("machine-trace-metrics", MachineTraceMetricsAnalysis())
110110
MACHINE_FUNCTION_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis(PIC))
111111
MACHINE_FUNCTION_ANALYSIS("slot-indexes", SlotIndexesAnalysis())
112+
MACHINE_FUNCTION_ANALYSIS("virtregmap", VirtRegMapAnalysis())
112113
// MACHINE_FUNCTION_ANALYSIS("live-stacks", LiveStacksPass())
113114
// MACHINE_FUNCTION_ANALYSIS("edge-bundles", EdgeBundlesAnalysis())
114115
// MACHINE_FUNCTION_ANALYSIS("lazy-machine-bfi",
@@ -150,6 +151,7 @@ MACHINE_FUNCTION_PASS("print<machine-loops>", MachineLoopPrinterPass(dbgs()))
150151
MACHINE_FUNCTION_PASS("print<machine-post-dom-tree>",
151152
MachinePostDominatorTreePrinterPass(dbgs()))
152153
MACHINE_FUNCTION_PASS("print<slot-indexes>", SlotIndexesPrinterPass(dbgs()))
154+
MACHINE_FUNCTION_PASS("print<virtregmap>", VirtRegMapPrinterPass(dbgs()))
153155
MACHINE_FUNCTION_PASS("require-all-machine-function-properties",
154156
RequireAllMachineFunctionPropertiesPass())
155157
MACHINE_FUNCTION_PASS("stack-coloring", StackColoringPass())

llvm/lib/CodeGen/CodeGen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
138138
initializeUnpackMachineBundlesPass(Registry);
139139
initializeUnreachableBlockElimLegacyPassPass(Registry);
140140
initializeUnreachableMachineBlockElimPass(Registry);
141-
initializeVirtRegMapPass(Registry);
141+
initializeVirtRegMapWrapperLegacyPass(Registry);
142142
initializeVirtRegRewriterPass(Registry);
143143
initializeWasmEHPreparePass(Registry);
144144
initializeWinEHPreparePass(Registry);

0 commit comments

Comments
 (0)