Skip to content

Commit e91cbd4

Browse files
authored
[CodeGen][NPM] Port VirtRegRewriter to NPM (llvm#130564)
1 parent f62f36b commit e91cbd4

13 files changed

+162
-19
lines changed

llvm/include/llvm/CodeGen/VirtRegMap.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,21 @@ class VirtRegMapPrinterPass : public PassInfoMixin<VirtRegMapPrinterPass> {
235235
MachineFunctionAnalysisManager &MFAM);
236236
static bool isRequired() { return true; }
237237
};
238+
239+
class VirtRegRewriterPass : public PassInfoMixin<VirtRegRewriterPass> {
240+
bool ClearVirtRegs = true;
241+
242+
public:
243+
VirtRegRewriterPass(bool ClearVirtRegs = true)
244+
: ClearVirtRegs(ClearVirtRegs) {}
245+
PreservedAnalyses run(MachineFunction &MF,
246+
MachineFunctionAnalysisManager &MFAM);
247+
248+
static bool isRequired() { return true; }
249+
250+
void printPipeline(raw_ostream &OS, function_ref<StringRef(StringRef)>) const;
251+
};
252+
238253
} // end llvm namespace
239254

240255
#endif // LLVM_CODEGEN_VIRTREGMAP_H

llvm/include/llvm/InitializePasses.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ void initializeUnreachableBlockElimLegacyPassPass(PassRegistry &);
319319
void initializeUnreachableMachineBlockElimLegacyPass(PassRegistry &);
320320
void initializeVerifierLegacyPassPass(PassRegistry &);
321321
void initializeVirtRegMapWrapperLegacyPass(PassRegistry &);
322-
void initializeVirtRegRewriterPass(PassRegistry &);
322+
void initializeVirtRegRewriterLegacyPass(PassRegistry &);
323323
void initializeWasmEHPreparePass(PassRegistry &);
324324
void initializeWinEHPreparePass(PassRegistry &);
325325
void initializeWriteBitcodePassPass(PassRegistry &);

llvm/include/llvm/Passes/CodeGenPassBuilder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@
9494
#include "llvm/CodeGen/TargetPassConfig.h"
9595
#include "llvm/CodeGen/TwoAddressInstructionPass.h"
9696
#include "llvm/CodeGen/UnreachableBlockElim.h"
97+
#include "llvm/CodeGen/VirtRegMap.h"
9798
#include "llvm/CodeGen/WasmEHPrepare.h"
9899
#include "llvm/CodeGen/WinEHPrepare.h"
99100
#include "llvm/CodeGen/XRayInstrumentation.h"

llvm/include/llvm/Passes/MachinePassRegistry.def

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,12 @@ MACHINE_FUNCTION_PASS_WITH_PARAMS(
262262
return parseRegAllocGreedyFilterFunc(*PB, Params);
263263
}, "reg-filter"
264264
)
265+
266+
MACHINE_FUNCTION_PASS_WITH_PARAMS(
267+
"virt-reg-rewriter", "VirtRegRewriterPass",
268+
[](bool ClearVirtRegs) { return VirtRegRewriterPass(ClearVirtRegs); },
269+
parseVirtRegRewriterPassOptions, "no-clear-vregs;clear-vregs")
270+
265271
#undef MACHINE_FUNCTION_PASS_WITH_PARAMS
266272

267273
// After a pass is converted to new pass manager, its entry should be moved from
@@ -320,5 +326,4 @@ DUMMY_MACHINE_FUNCTION_PASS("regbankselect", RegBankSelectPass)
320326
DUMMY_MACHINE_FUNCTION_PASS("reset-machine-function", ResetMachineFunctionPass)
321327
DUMMY_MACHINE_FUNCTION_PASS("stackmap-liveness", StackMapLivenessPass)
322328
DUMMY_MACHINE_FUNCTION_PASS("unpack-mi-bundles", UnpackMachineBundlesPass)
323-
DUMMY_MACHINE_FUNCTION_PASS("virtregrewriter", VirtRegRewriterPass)
324329
#undef DUMMY_MACHINE_FUNCTION_PASS

llvm/lib/CodeGen/CodeGen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
142142
initializeUnreachableBlockElimLegacyPassPass(Registry);
143143
initializeUnreachableMachineBlockElimLegacyPass(Registry);
144144
initializeVirtRegMapWrapperLegacyPass(Registry);
145-
initializeVirtRegRewriterPass(Registry);
145+
initializeVirtRegRewriterLegacyPass(Registry);
146146
initializeWasmEHPreparePass(Registry);
147147
initializeWinEHPreparePass(Registry);
148148
initializeXRayInstrumentationLegacyPass(Registry);

llvm/lib/CodeGen/VirtRegMap.cpp

Lines changed: 69 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ VirtRegMap VirtRegMapAnalysis::run(MachineFunction &MF,
197197
//
198198
namespace {
199199

200-
class VirtRegRewriter : public MachineFunctionPass {
200+
class VirtRegRewriter {
201201
MachineFunction *MF = nullptr;
202202
const TargetRegisterInfo *TRI = nullptr;
203203
const TargetInstrInfo *TII = nullptr;
@@ -223,9 +223,21 @@ class VirtRegRewriter : public MachineFunctionPass {
223223

224224
public:
225225
static char ID;
226-
VirtRegRewriter(bool ClearVirtRegs_ = true) :
227-
MachineFunctionPass(ID),
228-
ClearVirtRegs(ClearVirtRegs_) {}
226+
VirtRegRewriter(bool ClearVirtRegs, SlotIndexes *Indexes, LiveIntervals *LIS,
227+
LiveRegMatrix *LRM, VirtRegMap *VRM,
228+
LiveDebugVariables *DebugVars)
229+
: Indexes(Indexes), LIS(LIS), LRM(LRM), VRM(VRM), DebugVars(DebugVars),
230+
ClearVirtRegs(ClearVirtRegs) {}
231+
232+
bool run(MachineFunction &);
233+
};
234+
235+
class VirtRegRewriterLegacy : public MachineFunctionPass {
236+
public:
237+
static char ID;
238+
bool ClearVirtRegs;
239+
VirtRegRewriterLegacy(bool ClearVirtRegs = true)
240+
: MachineFunctionPass(ID), ClearVirtRegs(ClearVirtRegs) {}
229241

230242
void getAnalysisUsage(AnalysisUsage &AU) const override;
231243

@@ -243,22 +255,22 @@ class VirtRegRewriter : public MachineFunctionPass {
243255

244256
} // end anonymous namespace
245257

246-
char VirtRegRewriter::ID = 0;
258+
char VirtRegRewriterLegacy::ID = 0;
247259

248-
char &llvm::VirtRegRewriterID = VirtRegRewriter::ID;
260+
char &llvm::VirtRegRewriterID = VirtRegRewriterLegacy::ID;
249261

250-
INITIALIZE_PASS_BEGIN(VirtRegRewriter, "virtregrewriter",
262+
INITIALIZE_PASS_BEGIN(VirtRegRewriterLegacy, "virtregrewriter",
251263
"Virtual Register Rewriter", false, false)
252264
INITIALIZE_PASS_DEPENDENCY(SlotIndexesWrapperPass)
253265
INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
254266
INITIALIZE_PASS_DEPENDENCY(LiveDebugVariablesWrapperLegacy)
255267
INITIALIZE_PASS_DEPENDENCY(LiveRegMatrixWrapperLegacy)
256268
INITIALIZE_PASS_DEPENDENCY(LiveStacksWrapperLegacy)
257269
INITIALIZE_PASS_DEPENDENCY(VirtRegMapWrapperLegacy)
258-
INITIALIZE_PASS_END(VirtRegRewriter, "virtregrewriter",
270+
INITIALIZE_PASS_END(VirtRegRewriterLegacy, "virtregrewriter",
259271
"Virtual Register Rewriter", false, false)
260272

261-
void VirtRegRewriter::getAnalysisUsage(AnalysisUsage &AU) const {
273+
void VirtRegRewriterLegacy::getAnalysisUsage(AnalysisUsage &AU) const {
262274
AU.setPreservesCFG();
263275
AU.addRequired<LiveIntervalsWrapperPass>();
264276
AU.addPreserved<LiveIntervalsWrapperPass>();
@@ -276,16 +288,50 @@ void VirtRegRewriter::getAnalysisUsage(AnalysisUsage &AU) const {
276288
MachineFunctionPass::getAnalysisUsage(AU);
277289
}
278290

279-
bool VirtRegRewriter::runOnMachineFunction(MachineFunction &fn) {
291+
bool VirtRegRewriterLegacy::runOnMachineFunction(MachineFunction &MF) {
292+
VirtRegMap &VRM = getAnalysis<VirtRegMapWrapperLegacy>().getVRM();
293+
LiveIntervals &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
294+
LiveRegMatrix &LRM = getAnalysis<LiveRegMatrixWrapperLegacy>().getLRM();
295+
SlotIndexes &Indexes = getAnalysis<SlotIndexesWrapperPass>().getSI();
296+
LiveDebugVariables &DebugVars =
297+
getAnalysis<LiveDebugVariablesWrapperLegacy>().getLDV();
298+
299+
VirtRegRewriter R(ClearVirtRegs, &Indexes, &LIS, &LRM, &VRM, &DebugVars);
300+
return R.run(MF);
301+
}
302+
303+
PreservedAnalyses
304+
VirtRegRewriterPass::run(MachineFunction &MF,
305+
MachineFunctionAnalysisManager &MFAM) {
306+
VirtRegMap &VRM = MFAM.getResult<VirtRegMapAnalysis>(MF);
307+
LiveIntervals &LIS = MFAM.getResult<LiveIntervalsAnalysis>(MF);
308+
LiveRegMatrix &LRM = MFAM.getResult<LiveRegMatrixAnalysis>(MF);
309+
SlotIndexes &Indexes = MFAM.getResult<SlotIndexesAnalysis>(MF);
310+
LiveDebugVariables &DebugVars =
311+
MFAM.getResult<LiveDebugVariablesAnalysis>(MF);
312+
313+
VirtRegRewriter R(ClearVirtRegs, &Indexes, &LIS, &LRM, &VRM, &DebugVars);
314+
if (!R.run(MF))
315+
return PreservedAnalyses::all();
316+
317+
auto PA = getMachineFunctionPassPreservedAnalyses();
318+
PA.preserveSet<CFGAnalyses>();
319+
PA.preserve<LiveIntervalsAnalysis>();
320+
PA.preserve<SlotIndexesAnalysis>();
321+
PA.preserve<LiveStacksAnalysis>();
322+
// LiveDebugVariables is preserved by default, so clear it
323+
// if this VRegRewriter is the last one in the pipeline.
324+
if (ClearVirtRegs)
325+
PA.abandon<LiveDebugVariablesAnalysis>();
326+
return PA;
327+
}
328+
329+
bool VirtRegRewriter::run(MachineFunction &fn) {
280330
MF = &fn;
281331
TRI = MF->getSubtarget().getRegisterInfo();
282332
TII = MF->getSubtarget().getInstrInfo();
283333
MRI = &MF->getRegInfo();
284-
Indexes = &getAnalysis<SlotIndexesWrapperPass>().getSI();
285-
LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
286-
LRM = &getAnalysis<LiveRegMatrixWrapperLegacy>().getLRM();
287-
VRM = &getAnalysis<VirtRegMapWrapperLegacy>().getVRM();
288-
DebugVars = &getAnalysis<LiveDebugVariablesWrapperLegacy>().getLDV();
334+
289335
LLVM_DEBUG(dbgs() << "********** REWRITE VIRTUAL REGISTERS **********\n"
290336
<< "********** Function: " << MF->getName() << '\n');
291337
LLVM_DEBUG(VRM->dump());
@@ -726,6 +772,13 @@ void VirtRegRewriter::rewrite() {
726772
RewriteRegs.clear();
727773
}
728774

775+
void VirtRegRewriterPass::printPipeline(
776+
raw_ostream &OS, function_ref<StringRef(StringRef)>) const {
777+
OS << "virt-reg-rewriter";
778+
if (!ClearVirtRegs)
779+
OS << "<no-clear-vregs>";
780+
}
781+
729782
FunctionPass *llvm::createVirtRegRewriter(bool ClearVirtRegs) {
730-
return new VirtRegRewriter(ClearVirtRegs);
783+
return new VirtRegRewriterLegacy(ClearVirtRegs);
731784
}

llvm/lib/Passes/PassBuilder.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1505,6 +1505,19 @@ Expected<bool> parseMachineBlockPlacementPassOptions(StringRef Params) {
15051505
inconvertibleErrorCode());
15061506
}
15071507
return AllowTailMerge;
1508+
};
1509+
1510+
Expected<bool> parseVirtRegRewriterPassOptions(StringRef Params) {
1511+
bool ClearVirtRegs = true;
1512+
if (!Params.empty()) {
1513+
ClearVirtRegs = !Params.consume_front("no-");
1514+
if (Params != "clear-vregs")
1515+
return make_error<StringError>(
1516+
formatv("invalid VirtRegRewriter pass parameter '{0}' ", Params)
1517+
.str(),
1518+
inconvertibleErrorCode());
1519+
}
1520+
return ClearVirtRegs;
15081521
}
15091522

15101523
} // namespace

llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2160,6 +2160,52 @@ void AMDGPUCodeGenPassBuilder::addMachineSSAOptimization(
21602160
addPass(SIShrinkInstructionsPass());
21612161
}
21622162

2163+
2164+
2165+
Error AMDGPUCodeGenPassBuilder::addRegAssignmentOptimized(
2166+
AddMachinePass &addPass) const {
2167+
// TODO: Check --regalloc-npm option
2168+
2169+
addPass(GCNPreRALongBranchRegPass());
2170+
2171+
addPass(RAGreedyPass({onlyAllocateSGPRs, "sgpr"}));
2172+
2173+
// Commit allocated register changes. This is mostly necessary because too
2174+
// many things rely on the use lists of the physical registers, such as the
2175+
// verifier. This is only necessary with allocators which use LiveIntervals,
2176+
// since FastRegAlloc does the replacements itself.
2177+
addPass(VirtRegRewriterPass(false));
2178+
2179+
// At this point, the sgpr-regalloc has been done and it is good to have the
2180+
// stack slot coloring to try to optimize the SGPR spill stack indices before
2181+
// attempting the custom SGPR spill lowering.
2182+
addPass(StackSlotColoringPass());
2183+
2184+
// Equivalent of PEI for SGPRs.
2185+
addPass(SILowerSGPRSpillsPass());
2186+
2187+
// To Allocate wwm registers used in whole quad mode operations (for shaders).
2188+
addPass(SIPreAllocateWWMRegsPass());
2189+
2190+
// For allocating other wwm register operands.
2191+
// addRegAlloc<RAGreedyPass>(addPass, RegAllocPhase::WWM);
2192+
addPass(RAGreedyPass({onlyAllocateWWMRegs, "wwm"}));
2193+
addPass(SILowerWWMCopiesPass());
2194+
addPass(VirtRegRewriterPass(false));
2195+
addPass(AMDGPUReserveWWMRegsPass());
2196+
2197+
// For allocating per-thread VGPRs.
2198+
// addRegAlloc<RAGreedyPass>(addPass, RegAllocPhase::VGPR);
2199+
addPass(RAGreedyPass({onlyAllocateVGPRs, "vgpr"}));
2200+
2201+
2202+
addPreRewrite(addPass);
2203+
addPass(VirtRegRewriterPass(true));
2204+
2205+
// TODO: addPass(AMDGPUMarkLastScratchLoadPass());
2206+
return Error::success();
2207+
}
2208+
21632209
void AMDGPUCodeGenPassBuilder::addPostRegAlloc(AddMachinePass &addPass) const {
21642210
addPass(SIFixVGPRCopiesPass());
21652211
if (TM.getOptLevel() > CodeGenOptLevel::None)

llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ class AMDGPUCodeGenPassBuilder
181181
void addMachineSSAOptimization(AddMachinePass &) const;
182182
void addPostRegAlloc(AddMachinePass &) const;
183183
void addPreEmitPass(AddMachinePass &) const;
184+
Error addRegAssignmentOptimized(AddMachinePass &) const;
184185

185186
/// Check if a pass is enabled given \p Opt option. The option always
186187
/// overrides defaults if explicitly used. Otherwise its default will be used

llvm/test/CodeGen/AMDGPU/alloc-aligned-tuples-gfx90a.mir

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
# RUN: llc -mtriple=amdgcn -mcpu=gfx90a -start-before=greedy,0 -stop-after=virtregrewriter,2 -verify-machineinstrs -o - %s | FileCheck --check-prefixes=GCN,GFX90A %s
2+
3+
# RUN: llc -enable-new-pm -mtriple=amdgcn -mcpu=gfx90a -passes='greedy<sgpr>,virt-reg-rewriter<no-clear-vregs>,stack-slot-coloring,si-lower-sgpr-spills,si-pre-allocate-wwm-regs,greedy<wwm>,si-lower-wwm-copies,virt-reg-rewriter<no-clear-vregs>,amdgpu-reserve-wwm-regs,greedy<vgpr>,amdgpu-nsa-reassign,virt-reg-rewriter' -o - %s | FileCheck --check-prefixes=GCN,GFX90A %s
24
# Using the unaligned vector tuples are OK as long as they aren't used
35
# in a real instruction.
46

llvm/test/CodeGen/AMDGPU/fold-restore-undef-use.mir

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
22
# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx90a -stress-regalloc=4 -verify-regalloc -start-before=greedy,0 -stop-after=virtregrewriter,0 %s -o - | FileCheck %s
33

4+
# RUN: llc -enable-new-pm -mtriple=amdgcn-amd-amdhsa -mcpu=gfx90a -stress-regalloc=4 -verify-regalloc -passes="greedy<sgpr>,virt-reg-rewriter<no-clear-vregs>" %s -o - | FileCheck %s
5+
46
# Check that we don't generate *** Bad machine code: Instruction loads
57
# from dead spill slot ***
68

llvm/test/CodeGen/AMDGPU/greedy-remark-crash-unassigned-reg.mir

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
# RUN: -start-before=greedy,0 -stop-after=virtregrewriter,0 -pass-remarks='.*' -pass-remarks-output=%t.yaml -o /dev/null %s
33
# RUN: FileCheck %s < %t.yaml
44

5+
# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 \
6+
# RUN: -passes='greedy<sgpr>,virt-reg-rewriter<no-clear-vregs>' -pass-remarks='.*' -pass-remarks-output=%t.yaml -o /dev/null %s
7+
# RUN: FileCheck %s < %t.yaml
8+
59
# CHECK: Name: SpillReloadCopies
610
# CHECK-NEXT: Function: func
711
# CHECK-NEXT: Args:

llvm/test/CodeGen/X86/pr30821.mir

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# RUN: llc -x mir < %s -run-pass=greedy,virtregrewriter,stack-slot-coloring | FileCheck %s
2+
# RUN: llc -x mir < %s -passes=greedy,virt-reg-rewriter,stack-slot-coloring | FileCheck %s
23
--- |
34
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
45
target triple = "x86_64-unknown-linux-gnu"

0 commit comments

Comments
 (0)