Skip to content

Commit 739a960

Browse files
authored
[RegAlloc] Don't call always-true ShouldAllocClass (#96296)
Previously, there was at least one virtual function call for every allocated register. The only users of this feature are AMDGPU and RISC-V (RVV), other targets don't use this. To easily identify these cases, change the default functor to nullptr and don't call it for every allocated register.
1 parent c7c6361 commit 739a960

File tree

10 files changed

+37
-27
lines changed

10 files changed

+37
-27
lines changed

llvm/include/llvm/CodeGen/RegAllocCommon.h

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,11 @@ namespace llvm {
1616
class TargetRegisterClass;
1717
class TargetRegisterInfo;
1818

19+
/// Filter function for register classes during regalloc. Default register class
20+
/// filter is nullptr, where all registers should be allocated.
1921
typedef std::function<bool(const TargetRegisterInfo &TRI,
20-
const TargetRegisterClass &RC)> RegClassFilterFunc;
21-
22-
/// Default register class filter function for register allocation. All virtual
23-
/// registers should be allocated.
24-
static inline bool allocateAllRegClasses(const TargetRegisterInfo &,
25-
const TargetRegisterClass &) {
26-
return true;
27-
}
28-
22+
const TargetRegisterClass &RC)>
23+
RegClassFilterFunc;
2924
}
3025

3126
#endif // LLVM_CODEGEN_REGALLOCCOMMON_H

llvm/include/llvm/CodeGen/RegAllocFast.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
namespace llvm {
1616

1717
struct RegAllocFastPassOptions {
18-
RegClassFilterFunc Filter = allocateAllRegClasses;
18+
RegClassFilterFunc Filter = nullptr;
1919
StringRef FilterName = "all";
2020
bool ClearVRegs = true;
2121
};

llvm/include/llvm/Passes/PassBuilder.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "llvm/Transforms/IPO/ModuleInliner.h"
2828
#include "llvm/Transforms/Instrumentation.h"
2929
#include "llvm/Transforms/Scalar/LoopPassManager.h"
30+
#include <optional>
3031
#include <vector>
3132

3233
namespace llvm {
@@ -390,7 +391,8 @@ class PassBuilder {
390391
Error parseAAPipeline(AAManager &AA, StringRef PipelineText);
391392

392393
/// Parse RegClassFilterName to get RegClassFilterFunc.
393-
RegClassFilterFunc parseRegAllocFilter(StringRef RegClassFilterName);
394+
std::optional<RegClassFilterFunc>
395+
parseRegAllocFilter(StringRef RegClassFilterName);
394396

395397
/// Print pass names.
396398
void printPassNames(raw_ostream &OS);

llvm/lib/CodeGen/RegAllocBase.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,7 @@ void RegAllocBase::enqueue(const LiveInterval *LI) {
181181
if (VRM->hasPhys(Reg))
182182
return;
183183

184-
const TargetRegisterClass &RC = *MRI->getRegClass(Reg);
185-
if (ShouldAllocateClass(*TRI, RC)) {
184+
if (shouldAllocateRegister(Reg)) {
186185
LLVM_DEBUG(dbgs() << "Enqueuing " << printReg(Reg, TRI) << '\n');
187186
enqueueImpl(LI);
188187
} else {

llvm/lib/CodeGen/RegAllocBase.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#define LLVM_LIB_CODEGEN_REGALLOCBASE_H
3838

3939
#include "llvm/ADT/SmallPtrSet.h"
40+
#include "llvm/CodeGen/MachineRegisterInfo.h"
4041
#include "llvm/CodeGen/RegAllocCommon.h"
4142
#include "llvm/CodeGen/RegisterClassInfo.h"
4243

@@ -68,22 +69,32 @@ class RegAllocBase {
6869
LiveIntervals *LIS = nullptr;
6970
LiveRegMatrix *Matrix = nullptr;
7071
RegisterClassInfo RegClassInfo;
72+
73+
private:
74+
/// Private, callees should go through shouldAllocateRegister
7175
const RegClassFilterFunc ShouldAllocateClass;
7276

77+
protected:
7378
/// Inst which is a def of an original reg and whose defs are already all
7479
/// dead after remat is saved in DeadRemats. The deletion of such inst is
7580
/// postponed till all the allocations are done, so its remat expr is
7681
/// always available for the remat of all the siblings of the original reg.
7782
SmallPtrSet<MachineInstr *, 32> DeadRemats;
7883

79-
RegAllocBase(const RegClassFilterFunc F = allocateAllRegClasses) :
80-
ShouldAllocateClass(F) {}
84+
RegAllocBase(const RegClassFilterFunc F = nullptr) : ShouldAllocateClass(F) {}
8185

8286
virtual ~RegAllocBase() = default;
8387

8488
// A RegAlloc pass should call this before allocatePhysRegs.
8589
void init(VirtRegMap &vrm, LiveIntervals &lis, LiveRegMatrix &mat);
8690

91+
/// Get whether a given register should be allocated
92+
bool shouldAllocateRegister(Register Reg) {
93+
if (!ShouldAllocateClass)
94+
return true;
95+
return ShouldAllocateClass(*TRI, *MRI->getRegClass(Reg));
96+
}
97+
8798
// The top-level driver. The output is a VirtRegMap that us updated with
8899
// physical register assignments.
89100
void allocatePhysRegs();

llvm/lib/CodeGen/RegAllocBasic.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ class RABasic : public MachineFunctionPass,
7474
void LRE_WillShrinkVirtReg(Register) override;
7575

7676
public:
77-
RABasic(const RegClassFilterFunc F = allocateAllRegClasses);
77+
RABasic(const RegClassFilterFunc F = nullptr);
7878

7979
/// Return the pass name.
8080
StringRef getPassName() const override { return "Basic Register Allocator"; }

llvm/lib/CodeGen/RegAllocFast.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ class InstrPosIndexes {
177177

178178
class RegAllocFastImpl {
179179
public:
180-
RegAllocFastImpl(const RegClassFilterFunc F = allocateAllRegClasses,
180+
RegAllocFastImpl(const RegClassFilterFunc F = nullptr,
181181
bool ClearVirtRegs_ = true)
182182
: ShouldAllocateClass(F), StackSlotForVirtReg(-1),
183183
ClearVirtRegs(ClearVirtRegs_) {}
@@ -387,8 +387,7 @@ class RegAllocFast : public MachineFunctionPass {
387387
public:
388388
static char ID;
389389

390-
RegAllocFast(const RegClassFilterFunc F = allocateAllRegClasses,
391-
bool ClearVirtRegs_ = true)
390+
RegAllocFast(const RegClassFilterFunc F = nullptr, bool ClearVirtRegs_ = true)
392391
: MachineFunctionPass(ID), Impl(F, ClearVirtRegs_) {}
393392

394393
bool runOnMachineFunction(MachineFunction &MF) override {
@@ -431,6 +430,8 @@ INITIALIZE_PASS(RegAllocFast, "regallocfast", "Fast Register Allocator", false,
431430

432431
bool RegAllocFastImpl::shouldAllocateRegister(const Register Reg) const {
433432
assert(Reg.isVirtual());
433+
if (!ShouldAllocateClass)
434+
return true;
434435
const TargetRegisterClass &RC = *MRI->getRegClass(Reg);
435436
return ShouldAllocateClass(*TRI, RC);
436437
}

llvm/lib/CodeGen/RegAllocGreedy.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2308,7 +2308,7 @@ void RAGreedy::tryHintRecoloring(const LiveInterval &VirtReg) {
23082308

23092309
// This may be a skipped class
23102310
if (!VRM->hasPhys(Reg)) {
2311-
assert(!ShouldAllocateClass(*TRI, *MRI->getRegClass(Reg)) &&
2311+
assert(!shouldAllocateRegister(Reg) &&
23122312
"We have an unallocated variable which should have been handled");
23132313
continue;
23142314
}
@@ -2698,7 +2698,7 @@ bool RAGreedy::hasVirtRegAlloc() {
26982698
const TargetRegisterClass *RC = MRI->getRegClass(Reg);
26992699
if (!RC)
27002700
continue;
2701-
if (ShouldAllocateClass(*TRI, *RC))
2701+
if (shouldAllocateRegister(Reg))
27022702
return true;
27032703
}
27042704

llvm/lib/CodeGen/RegAllocGreedy.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ class LLVM_LIBRARY_VISIBILITY RAGreedy : public MachineFunctionPass,
281281
bool ReverseLocalAssignment = false;
282282

283283
public:
284-
RAGreedy(const RegClassFilterFunc F = allocateAllRegClasses);
284+
RAGreedy(const RegClassFilterFunc F = nullptr);
285285

286286
/// Return the pass name.
287287
StringRef getPassName() const override { return "Greedy Register Allocator"; }

llvm/lib/Passes/PassBuilder.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,14 +1164,15 @@ parseRegAllocFastPassOptions(PassBuilder &PB, StringRef Params) {
11641164
std::tie(ParamName, Params) = Params.split(';');
11651165

11661166
if (ParamName.consume_front("filter=")) {
1167-
RegClassFilterFunc Filter = PB.parseRegAllocFilter(ParamName);
1167+
std::optional<RegClassFilterFunc> Filter =
1168+
PB.parseRegAllocFilter(ParamName);
11681169
if (!Filter) {
11691170
return make_error<StringError>(
11701171
formatv("invalid regallocfast register filter '{0}' ", ParamName)
11711172
.str(),
11721173
inconvertibleErrorCode());
11731174
}
1174-
Opts.Filter = Filter;
1175+
Opts.Filter = *Filter;
11751176
Opts.FilterName = ParamName;
11761177
continue;
11771178
}
@@ -2161,13 +2162,14 @@ Error PassBuilder::parseAAPipeline(AAManager &AA, StringRef PipelineText) {
21612162
return Error::success();
21622163
}
21632164

2164-
RegClassFilterFunc PassBuilder::parseRegAllocFilter(StringRef FilterName) {
2165+
std::optional<RegClassFilterFunc>
2166+
PassBuilder::parseRegAllocFilter(StringRef FilterName) {
21652167
if (FilterName == "all")
2166-
return allocateAllRegClasses;
2168+
return nullptr;
21672169
for (auto &C : RegClassFilterParsingCallbacks)
21682170
if (auto F = C(FilterName))
21692171
return F;
2170-
return nullptr;
2172+
return std::nullopt;
21712173
}
21722174

21732175
static void printPassName(StringRef PassName, raw_ostream &OS) {

0 commit comments

Comments
 (0)