Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions llvm/include/llvm/CodeGen/VirtRegMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,21 @@ class VirtRegMapPrinterPass : public PassInfoMixin<VirtRegMapPrinterPass> {
MachineFunctionAnalysisManager &MFAM);
static bool isRequired() { return true; }
};

class VirtRegRewriterPass : public PassInfoMixin<VirtRegRewriterPass> {
bool ClearVirtRegs = true;

public:
VirtRegRewriterPass(bool ClearVirtRegs = true)
: ClearVirtRegs(ClearVirtRegs) {}
PreservedAnalyses run(MachineFunction &MF,
MachineFunctionAnalysisManager &MFAM);

static bool isRequired() { return true; }

void printPipeline(raw_ostream &OS, function_ref<StringRef(StringRef)>) const;
};

} // end llvm namespace

#endif // LLVM_CODEGEN_VIRTREGMAP_H
2 changes: 1 addition & 1 deletion llvm/include/llvm/InitializePasses.h
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ void initializeUnreachableBlockElimLegacyPassPass(PassRegistry &);
void initializeUnreachableMachineBlockElimLegacyPass(PassRegistry &);
void initializeVerifierLegacyPassPass(PassRegistry &);
void initializeVirtRegMapWrapperLegacyPass(PassRegistry &);
void initializeVirtRegRewriterPass(PassRegistry &);
void initializeVirtRegRewriterLegacyPass(PassRegistry &);
void initializeWasmEHPreparePass(PassRegistry &);
void initializeWinEHPreparePass(PassRegistry &);
void initializeWriteBitcodePassPass(PassRegistry &);
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/Passes/CodeGenPassBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/CodeGen/TwoAddressInstructionPass.h"
#include "llvm/CodeGen/UnreachableBlockElim.h"
#include "llvm/CodeGen/VirtRegMap.h"
#include "llvm/CodeGen/WasmEHPrepare.h"
#include "llvm/CodeGen/WinEHPrepare.h"
#include "llvm/CodeGen/XRayInstrumentation.h"
Expand Down
7 changes: 6 additions & 1 deletion llvm/include/llvm/Passes/MachinePassRegistry.def
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,12 @@ MACHINE_FUNCTION_PASS_WITH_PARAMS(
return parseRegAllocGreedyFilterFunc(*PB, Params);
}, "reg-filter"
)

MACHINE_FUNCTION_PASS_WITH_PARAMS(
"virt-reg-rewriter", "VirtRegRewriterPass",
[](bool ClearVirtRegs) { return VirtRegRewriterPass(ClearVirtRegs); },
parseVirtRegRewriterPassOptions, "no-clear-vregs;clear-vregs")

#undef MACHINE_FUNCTION_PASS_WITH_PARAMS

// After a pass is converted to new pass manager, its entry should be moved from
Expand Down Expand Up @@ -319,5 +325,4 @@ DUMMY_MACHINE_FUNCTION_PASS("reset-machine-function", ResetMachineFunctionPass)
DUMMY_MACHINE_FUNCTION_PASS("shrink-wrap", ShrinkWrapPass)
DUMMY_MACHINE_FUNCTION_PASS("stackmap-liveness", StackMapLivenessPass)
DUMMY_MACHINE_FUNCTION_PASS("unpack-mi-bundles", UnpackMachineBundlesPass)
DUMMY_MACHINE_FUNCTION_PASS("virtregrewriter", VirtRegRewriterPass)
#undef DUMMY_MACHINE_FUNCTION_PASS
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/CodeGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
initializeUnreachableBlockElimLegacyPassPass(Registry);
initializeUnreachableMachineBlockElimLegacyPass(Registry);
initializeVirtRegMapWrapperLegacyPass(Registry);
initializeVirtRegRewriterPass(Registry);
initializeVirtRegRewriterLegacyPass(Registry);
initializeWasmEHPreparePass(Registry);
initializeWinEHPreparePass(Registry);
initializeXRayInstrumentationLegacyPass(Registry);
Expand Down
85 changes: 69 additions & 16 deletions llvm/lib/CodeGen/VirtRegMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ VirtRegMap VirtRegMapAnalysis::run(MachineFunction &MF,
//
namespace {

class VirtRegRewriter : public MachineFunctionPass {
class VirtRegRewriter {
MachineFunction *MF = nullptr;
const TargetRegisterInfo *TRI = nullptr;
const TargetInstrInfo *TII = nullptr;
Expand All @@ -223,9 +223,21 @@ class VirtRegRewriter : public MachineFunctionPass {

public:
static char ID;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unused ID here causes a build failure

VirtRegRewriter(bool ClearVirtRegs_ = true) :
MachineFunctionPass(ID),
ClearVirtRegs(ClearVirtRegs_) {}
VirtRegRewriter(bool ClearVirtRegs, SlotIndexes *Indexes, LiveIntervals *LIS,
LiveRegMatrix *LRM, VirtRegMap *VRM,
LiveDebugVariables *DebugVars)
: Indexes(Indexes), LIS(LIS), LRM(LRM), VRM(VRM), DebugVars(DebugVars),
ClearVirtRegs(ClearVirtRegs) {}

bool run(MachineFunction &);
};

class VirtRegRewriterLegacy : public MachineFunctionPass {
public:
static char ID;
bool ClearVirtRegs;
VirtRegRewriterLegacy(bool ClearVirtRegs = true)
: MachineFunctionPass(ID), ClearVirtRegs(ClearVirtRegs) {}

void getAnalysisUsage(AnalysisUsage &AU) const override;

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

} // end anonymous namespace

char VirtRegRewriter::ID = 0;
char VirtRegRewriterLegacy::ID = 0;

char &llvm::VirtRegRewriterID = VirtRegRewriter::ID;
char &llvm::VirtRegRewriterID = VirtRegRewriterLegacy::ID;

INITIALIZE_PASS_BEGIN(VirtRegRewriter, "virtregrewriter",
INITIALIZE_PASS_BEGIN(VirtRegRewriterLegacy, "virtregrewriter",
"Virtual Register Rewriter", false, false)
INITIALIZE_PASS_DEPENDENCY(SlotIndexesWrapperPass)
INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
INITIALIZE_PASS_DEPENDENCY(LiveDebugVariablesWrapperLegacy)
INITIALIZE_PASS_DEPENDENCY(LiveRegMatrixWrapperLegacy)
INITIALIZE_PASS_DEPENDENCY(LiveStacksWrapperLegacy)
INITIALIZE_PASS_DEPENDENCY(VirtRegMapWrapperLegacy)
INITIALIZE_PASS_END(VirtRegRewriter, "virtregrewriter",
INITIALIZE_PASS_END(VirtRegRewriterLegacy, "virtregrewriter",
"Virtual Register Rewriter", false, false)

void VirtRegRewriter::getAnalysisUsage(AnalysisUsage &AU) const {
void VirtRegRewriterLegacy::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesCFG();
AU.addRequired<LiveIntervalsWrapperPass>();
AU.addPreserved<LiveIntervalsWrapperPass>();
Expand All @@ -276,16 +288,50 @@ void VirtRegRewriter::getAnalysisUsage(AnalysisUsage &AU) const {
MachineFunctionPass::getAnalysisUsage(AU);
}

bool VirtRegRewriter::runOnMachineFunction(MachineFunction &fn) {
bool VirtRegRewriterLegacy::runOnMachineFunction(MachineFunction &MF) {
VirtRegMap &VRM = getAnalysis<VirtRegMapWrapperLegacy>().getVRM();
LiveIntervals &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
LiveRegMatrix &LRM = getAnalysis<LiveRegMatrixWrapperLegacy>().getLRM();
SlotIndexes &Indexes = getAnalysis<SlotIndexesWrapperPass>().getSI();
LiveDebugVariables &DebugVars =
getAnalysis<LiveDebugVariablesWrapperLegacy>().getLDV();

VirtRegRewriter R(ClearVirtRegs, &Indexes, &LIS, &LRM, &VRM, &DebugVars);
return R.run(MF);
}

PreservedAnalyses
VirtRegRewriterPass::run(MachineFunction &MF,
MachineFunctionAnalysisManager &MFAM) {
VirtRegMap &VRM = MFAM.getResult<VirtRegMapAnalysis>(MF);
LiveIntervals &LIS = MFAM.getResult<LiveIntervalsAnalysis>(MF);
LiveRegMatrix &LRM = MFAM.getResult<LiveRegMatrixAnalysis>(MF);
SlotIndexes &Indexes = MFAM.getResult<SlotIndexesAnalysis>(MF);
LiveDebugVariables &DebugVars =
MFAM.getResult<LiveDebugVariablesAnalysis>(MF);

VirtRegRewriter R(ClearVirtRegs, &Indexes, &LIS, &LRM, &VRM, &DebugVars);
if (!R.run(MF))
return PreservedAnalyses::all();

auto PA = getMachineFunctionPassPreservedAnalyses();
PA.preserveSet<CFGAnalyses>();
PA.preserve<LiveIntervalsAnalysis>();
PA.preserve<SlotIndexesAnalysis>();
PA.preserve<LiveStacksAnalysis>();
// LiveDebugVariables is preserved by default, so clear it
// if this VRegRewriter is the last one in the pipeline.
if (ClearVirtRegs)
PA.abandon<LiveDebugVariablesAnalysis>();
return PA;
}

bool VirtRegRewriter::run(MachineFunction &fn) {
MF = &fn;
TRI = MF->getSubtarget().getRegisterInfo();
TII = MF->getSubtarget().getInstrInfo();
MRI = &MF->getRegInfo();
Indexes = &getAnalysis<SlotIndexesWrapperPass>().getSI();
LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
LRM = &getAnalysis<LiveRegMatrixWrapperLegacy>().getLRM();
VRM = &getAnalysis<VirtRegMapWrapperLegacy>().getVRM();
DebugVars = &getAnalysis<LiveDebugVariablesWrapperLegacy>().getLDV();

LLVM_DEBUG(dbgs() << "********** REWRITE VIRTUAL REGISTERS **********\n"
<< "********** Function: " << MF->getName() << '\n');
LLVM_DEBUG(VRM->dump());
Expand Down Expand Up @@ -726,6 +772,13 @@ void VirtRegRewriter::rewrite() {
RewriteRegs.clear();
}

void VirtRegRewriterPass::printPipeline(
raw_ostream &OS, function_ref<StringRef(StringRef)>) const {
OS << "virt-reg-rewriter";
if (!ClearVirtRegs)
OS << "<no-clear-vregs>";
}

FunctionPass *llvm::createVirtRegRewriter(bool ClearVirtRegs) {
return new VirtRegRewriter(ClearVirtRegs);
return new VirtRegRewriterLegacy(ClearVirtRegs);
}
13 changes: 13 additions & 0 deletions llvm/lib/Passes/PassBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1502,6 +1502,19 @@ Expected<bool> parseMachineBlockPlacementPassOptions(StringRef Params) {
inconvertibleErrorCode());
}
return AllowTailMerge;
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extra semicolon here causes a build failure

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

on it


Expected<bool> parseVirtRegRewriterPassOptions(StringRef Params) {
bool ClearVirtRegs = true;
if (!Params.empty()) {
ClearVirtRegs = !Params.consume_front("no-");
if (Params != "clear-vregs")
return make_error<StringError>(
formatv("invalid VirtRegRewriter pass parameter '{0}' ", Params)
.str(),
inconvertibleErrorCode());
}
return ClearVirtRegs;
}

} // namespace
Expand Down
46 changes: 46 additions & 0 deletions llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2160,6 +2160,52 @@ void AMDGPUCodeGenPassBuilder::addMachineSSAOptimization(
addPass(SIShrinkInstructionsPass());
}



Error AMDGPUCodeGenPassBuilder::addRegAssignmentOptimized(
AddMachinePass &addPass) const {
// TODO: Check --regalloc-npm option

addPass(GCNPreRALongBranchRegPass());

addPass(RAGreedyPass({onlyAllocateSGPRs, "sgpr"}));

// Commit allocated register changes. This is mostly necessary because too
// many things rely on the use lists of the physical registers, such as the
// verifier. This is only necessary with allocators which use LiveIntervals,
// since FastRegAlloc does the replacements itself.
addPass(VirtRegRewriterPass(false));

// At this point, the sgpr-regalloc has been done and it is good to have the
// stack slot coloring to try to optimize the SGPR spill stack indices before
// attempting the custom SGPR spill lowering.
addPass(StackSlotColoringPass());

// Equivalent of PEI for SGPRs.
addPass(SILowerSGPRSpillsPass());

// To Allocate wwm registers used in whole quad mode operations (for shaders).
addPass(SIPreAllocateWWMRegsPass());

// For allocating other wwm register operands.
// addRegAlloc<RAGreedyPass>(addPass, RegAllocPhase::WWM);
addPass(RAGreedyPass({onlyAllocateWWMRegs, "wwm"}));
addPass(SILowerWWMCopiesPass());
addPass(VirtRegRewriterPass(false));
addPass(AMDGPUReserveWWMRegsPass());

// For allocating per-thread VGPRs.
// addRegAlloc<RAGreedyPass>(addPass, RegAllocPhase::VGPR);
addPass(RAGreedyPass({onlyAllocateVGPRs, "vgpr"}));


addPreRewrite(addPass);
addPass(VirtRegRewriterPass(true));

// TODO: addPass(AMDGPUMarkLastScratchLoadPass());
return Error::success();
}

void AMDGPUCodeGenPassBuilder::addPostRegAlloc(AddMachinePass &addPass) const {
addPass(SIFixVGPRCopiesPass());
if (TM.getOptLevel() > CodeGenOptLevel::None)
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ class AMDGPUCodeGenPassBuilder
void addMachineSSAOptimization(AddMachinePass &) const;
void addPostRegAlloc(AddMachinePass &) const;
void addPreEmitPass(AddMachinePass &) const;
Error addRegAssignmentOptimized(AddMachinePass &) const;

/// Check if a pass is enabled given \p Opt option. The option always
/// overrides defaults if explicitly used. Otherwise its default will be used
Expand Down
2 changes: 2 additions & 0 deletions llvm/test/CodeGen/AMDGPU/alloc-aligned-tuples-gfx90a.mir
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# RUN: llc -mtriple=amdgcn -mcpu=gfx90a -start-before=greedy,0 -stop-after=virtregrewriter,2 -verify-machineinstrs -o - %s | FileCheck --check-prefixes=GCN,GFX90A %s

# 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
# Using the unaligned vector tuples are OK as long as they aren't used
# in a real instruction.

Expand Down
2 changes: 2 additions & 0 deletions llvm/test/CodeGen/AMDGPU/fold-restore-undef-use.mir
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# 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

# 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

# Check that we don't generate *** Bad machine code: Instruction loads
# from dead spill slot ***

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
# RUN: -start-before=greedy,0 -stop-after=virtregrewriter,0 -pass-remarks='.*' -pass-remarks-output=%t.yaml -o /dev/null %s
# RUN: FileCheck %s < %t.yaml

# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 \
# RUN: -passes='greedy<sgpr>,virt-reg-rewriter<no-clear-vregs>' -pass-remarks='.*' -pass-remarks-output=%t.yaml -o /dev/null %s
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# RUN: -passes='greedy<sgpr>,virt-reg-rewriter<no-clear-vregs>' -pass-remarks='.*' -pass-remarks-output=%t.yaml -o /dev/null %s
# RUN: -passes='greedy<sgpr>,virt-reg-rewriter<no-clear-vregs>' -pass-remarks='.*' -pass-remarks-output=%t.yaml -filetype=null %s

# RUN: FileCheck %s < %t.yaml

# CHECK: Name: SpillReloadCopies
# CHECK-NEXT: Function: func
# CHECK-NEXT: Args:
Expand Down
1 change: 1 addition & 0 deletions llvm/test/CodeGen/X86/pr30821.mir
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# RUN: llc -x mir < %s -run-pass=greedy,virtregrewriter,stack-slot-coloring | FileCheck %s
# RUN: llc -x mir < %s -passes=greedy,virt-reg-rewriter,stack-slot-coloring | FileCheck %s
--- |
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
Expand Down