Skip to content

Commit 56a1c30

Browse files
committed
[RISCV] Split regalloc between RVV and other
Enable this flow by -riscv-split-regalloc=1 (default disable), and could designate specific allocator to RVV by -riscv-rvv-regalloc=<fast|basic|greedy> It uses the RegClass filter function to decide which regclass need to be processed. This patch is pre-requirement for supporting PostRA vsetvl insertion pass.
1 parent 865f54e commit 56a1c30

File tree

1 file changed

+108
-0
lines changed

1 file changed

+108
-0
lines changed

llvm/lib/Target/RISCV/RISCVTargetMachine.cpp

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "llvm/CodeGen/MIRParser/MIParser.h"
2828
#include "llvm/CodeGen/MIRYamlMapping.h"
2929
#include "llvm/CodeGen/Passes.h"
30+
#include "llvm/CodeGen/RegAllocRegistry.h"
3031
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
3132
#include "llvm/CodeGen/TargetPassConfig.h"
3233
#include "llvm/InitializePasses.h"
@@ -89,6 +90,11 @@ static cl::opt<bool>
8990
cl::desc("Enable the loop data prefetch pass"),
9091
cl::init(true));
9192

93+
static cl::opt<bool>
94+
EnableSplitRegAlloc("riscv-split-regalloc", cl::Hidden,
95+
cl::desc("Enable Split RegisterAlloc for RVV"),
96+
cl::init(false));
97+
9298
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() {
9399
RegisterTargetMachine<RISCVTargetMachine> X(getTheRISCV32Target());
94100
RegisterTargetMachine<RISCVTargetMachine> Y(getTheRISCV64Target());
@@ -253,6 +259,76 @@ bool RISCVTargetMachine::isNoopAddrSpaceCast(unsigned SrcAS,
253259
}
254260

255261
namespace {
262+
263+
class RVVRegisterRegAlloc : public RegisterRegAllocBase<RVVRegisterRegAlloc> {
264+
public:
265+
RVVRegisterRegAlloc(const char *N, const char *D, FunctionPassCtor C)
266+
: RegisterRegAllocBase(N, D, C) {}
267+
};
268+
269+
static bool onlyAllocateRVVReg(const TargetRegisterInfo &TRI,
270+
const TargetRegisterClass &RC) {
271+
return RISCV::VRRegClass.hasSubClassEq(&RC) ||
272+
RISCV::VRM2RegClass.hasSubClassEq(&RC) ||
273+
RISCV::VRM4RegClass.hasSubClassEq(&RC) ||
274+
RISCV::VRM8RegClass.hasSubClassEq(&RC) ||
275+
RISCV::VRN2M1RegClass.hasSubClassEq(&RC) ||
276+
RISCV::VRN2M2RegClass.hasSubClassEq(&RC) ||
277+
RISCV::VRN2M4RegClass.hasSubClassEq(&RC) ||
278+
RISCV::VRN3M1RegClass.hasSubClassEq(&RC) ||
279+
RISCV::VRN3M2RegClass.hasSubClassEq(&RC) ||
280+
RISCV::VRN4M1RegClass.hasSubClassEq(&RC) ||
281+
RISCV::VRN4M2RegClass.hasSubClassEq(&RC) ||
282+
RISCV::VRN5M1RegClass.hasSubClassEq(&RC) ||
283+
RISCV::VRN6M1RegClass.hasSubClassEq(&RC) ||
284+
RISCV::VRN7M1RegClass.hasSubClassEq(&RC) ||
285+
RISCV::VRN8M1RegClass.hasSubClassEq(&RC);
286+
}
287+
288+
static FunctionPass *useDefaultRegisterAllocator() { return nullptr; }
289+
290+
static llvm::once_flag InitializeDefaultRVVRegisterAllocatorFlag;
291+
292+
/// -riscv-rvv-regalloc=<fast|basic|greedy> command line option.
293+
/// This option could designate the rvv register allocator only.
294+
/// For example: -riscv-rvv-regalloc=basic
295+
static cl::opt<RVVRegisterRegAlloc::FunctionPassCtor, false,
296+
RegisterPassParser<RVVRegisterRegAlloc>>
297+
RVVRegAlloc("riscv-rvv-regalloc", cl::Hidden,
298+
cl::init(&useDefaultRegisterAllocator),
299+
cl::desc("Register allocator to use for RVV register."));
300+
301+
static void initializeDefaultRVVRegisterAllocatorOnce() {
302+
RegisterRegAlloc::FunctionPassCtor Ctor = RVVRegisterRegAlloc::getDefault();
303+
304+
if (!Ctor) {
305+
Ctor = RVVRegAlloc;
306+
RVVRegisterRegAlloc::setDefault(RVVRegAlloc);
307+
}
308+
}
309+
310+
static FunctionPass *createBasicRVVRegisterAllocator() {
311+
return createBasicRegisterAllocator(onlyAllocateRVVReg);
312+
}
313+
314+
static FunctionPass *createGreedyRVVRegisterAllocator() {
315+
return createGreedyRegisterAllocator(onlyAllocateRVVReg);
316+
}
317+
318+
static FunctionPass *createFastRVVRegisterAllocator() {
319+
return createFastRegisterAllocator(onlyAllocateRVVReg, false);
320+
}
321+
322+
static RVVRegisterRegAlloc basicRegAllocRVVReg("basic",
323+
"basic register allocator",
324+
createBasicRVVRegisterAllocator);
325+
static RVVRegisterRegAlloc
326+
greedyRegAllocRVVReg("greedy", "greedy register allocator",
327+
createGreedyRVVRegisterAllocator);
328+
329+
static RVVRegisterRegAlloc fastRegAllocRVVReg("fast", "fast register allocator",
330+
createFastRVVRegisterAllocator);
331+
256332
class RISCVPassConfig : public TargetPassConfig {
257333
public:
258334
RISCVPassConfig(RISCVTargetMachine &TM, PassManagerBase &PM)
@@ -301,6 +377,9 @@ class RISCVPassConfig : public TargetPassConfig {
301377
void addPreEmitPass2() override;
302378
void addPreSched2() override;
303379
void addMachineSSAOptimization() override;
380+
FunctionPass *createRVVRegAllocPass(bool Optimized);
381+
bool addRegAssignAndRewriteFast() override;
382+
bool addRegAssignAndRewriteOptimized() override;
304383
void addPreRegAlloc() override;
305384
void addPostRegAlloc() override;
306385
void addOptimizedRegAlloc() override;
@@ -312,6 +391,35 @@ TargetPassConfig *RISCVTargetMachine::createPassConfig(PassManagerBase &PM) {
312391
return new RISCVPassConfig(*this, PM);
313392
}
314393

394+
FunctionPass *RISCVPassConfig::createRVVRegAllocPass(bool Optimized) {
395+
// Initialize the global default.
396+
llvm::call_once(InitializeDefaultRVVRegisterAllocatorFlag,
397+
initializeDefaultRVVRegisterAllocatorOnce);
398+
399+
RegisterRegAlloc::FunctionPassCtor Ctor = RVVRegisterRegAlloc::getDefault();
400+
if (Ctor != useDefaultRegisterAllocator)
401+
return Ctor();
402+
403+
if (Optimized)
404+
return createGreedyRVVRegisterAllocator();
405+
406+
return createFastRVVRegisterAllocator();
407+
}
408+
409+
bool RISCVPassConfig::addRegAssignAndRewriteFast() {
410+
if (EnableSplitRegAlloc)
411+
addPass(createRVVRegAllocPass(false));
412+
return TargetPassConfig::addRegAssignAndRewriteFast();
413+
}
414+
415+
bool RISCVPassConfig::addRegAssignAndRewriteOptimized() {
416+
if (EnableSplitRegAlloc) {
417+
addPass(createRVVRegAllocPass(true));
418+
addPass(createVirtRegRewriter(false));
419+
}
420+
return TargetPassConfig::addRegAssignAndRewriteOptimized();
421+
}
422+
315423
void RISCVPassConfig::addIRPasses() {
316424
addPass(createAtomicExpandPass());
317425

0 commit comments

Comments
 (0)