Skip to content

Commit 69361d3

Browse files
committed
[GlobalISel] Add RegBankSelectFast pass
1 parent ea8f3df commit 69361d3

8 files changed

Lines changed: 218 additions & 7 deletions

File tree

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//===- llvm/CodeGen/GlobalISel/RegBankSelectFast.h --------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
///
9+
/// \file
10+
/// This file describes a trivial fast register bank selector for GlobalISel.
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef LLVM_CODEGEN_GLOBALISEL_REGBANKSELECTFAST_H
14+
#define LLVM_CODEGEN_GLOBALISEL_REGBANKSELECTFAST_H
15+
16+
#include "llvm/ADT/StringRef.h"
17+
#include "llvm/CodeGen/MachineFunction.h"
18+
#include "llvm/CodeGen/MachineFunctionPass.h"
19+
#include "llvm/Support/Compiler.h"
20+
21+
namespace llvm {
22+
23+
class LLVM_ABI RegBankSelectFast : public MachineFunctionPass {
24+
public:
25+
static char ID;
26+
27+
RegBankSelectFast() : MachineFunctionPass(ID) {}
28+
29+
StringRef getPassName() const override { return "RegBankSelectFast"; }
30+
31+
void getAnalysisUsage(AnalysisUsage &AU) const override;
32+
33+
MachineFunctionProperties getRequiredProperties() const override {
34+
return MachineFunctionProperties().setIsSSA().setLegalized();
35+
}
36+
37+
MachineFunctionProperties getSetProperties() const override {
38+
return MachineFunctionProperties().setRegBankSelected();
39+
}
40+
41+
bool runOnMachineFunction(MachineFunction &MF) override;
42+
};
43+
44+
} // end namespace llvm
45+
46+
#endif

llvm/include/llvm/InitializePasses.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ LLVM_ABI void
277277
initializeRegAllocPriorityAdvisorAnalysisLegacyPass(PassRegistry &);
278278
LLVM_ABI void initializeRegAllocScoringPass(PassRegistry &);
279279
LLVM_ABI void initializeRegBankSelectPass(PassRegistry &);
280+
LLVM_ABI void initializeRegBankSelectFastPass(PassRegistry &);
280281
LLVM_ABI void initializeRegToMemWrapperPassPass(PassRegistry &);
281282
LLVM_ABI void initializeRegUsageInfoCollectorLegacyPass(PassRegistry &);
282283
LLVM_ABI void initializeRegUsageInfoPropagationLegacyPass(PassRegistry &);

llvm/lib/CodeGen/GlobalISel/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ add_llvm_component_library(LLVMGlobalISel
2828
MachineFloatingPointPredicateUtils.cpp
2929
MachineIRBuilder.cpp
3030
RegBankSelect.cpp
31+
RegBankSelectFast.cpp
3132
Utils.cpp
3233

3334
ADDITIONAL_HEADER_DIRS

llvm/lib/CodeGen/GlobalISel/GlobalISel.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ void llvm::initializeGlobalISel(PassRegistry &Registry) {
2020
initializeLoadStoreOptPass(Registry);
2121
initializeLocalizerPass(Registry);
2222
initializeRegBankSelectPass(Registry);
23+
initializeRegBankSelectFastPass(Registry);
2324
initializeInstructionSelectPass(Registry);
2425
initializeGISelValueTrackingAnalysisLegacyPass(Registry);
2526
initializeGISelCSEAnalysisWrapperPassPass(Registry);
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
//===- llvm/CodeGen/GlobalISel/RegBankSelectFast.cpp ----------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
/// \file
9+
/// This file implements a trivial fast register bank selector.
10+
//===----------------------------------------------------------------------===//
11+
12+
#include "llvm/CodeGen/GlobalISel/RegBankSelectFast.h"
13+
#include "llvm/ADT/PostOrderIterator.h"
14+
#include "llvm/ADT/STLExtras.h"
15+
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
16+
#include "llvm/CodeGen/GlobalISel/RegBankSelect.h"
17+
#include "llvm/CodeGen/MachineRegisterInfo.h"
18+
#include "llvm/CodeGen/RegisterBankInfo.h"
19+
#include "llvm/CodeGen/TargetSubtargetInfo.h"
20+
#include "llvm/InitializePasses.h"
21+
#include "llvm/Support/Debug.h"
22+
23+
#define DEBUG_TYPE "regbankselectfast"
24+
25+
using namespace llvm;
26+
27+
namespace {
28+
29+
class FallbackRegBankSelect final : public RegBankSelect {
30+
public:
31+
bool runOnCurrentFunction(MachineFunction &MF) {
32+
init(MF);
33+
return assignRegisterBanks(MF);
34+
}
35+
};
36+
37+
} // end anonymous namespace
38+
39+
char RegBankSelectFast::ID = 0;
40+
INITIALIZE_PASS_BEGIN(RegBankSelectFast, DEBUG_TYPE,
41+
"Fast register bank selection", false, false)
42+
INITIALIZE_PASS_END(RegBankSelectFast, DEBUG_TYPE,
43+
"Fast register bank selection", false, false)
44+
45+
void RegBankSelectFast::getAnalysisUsage(AnalysisUsage &AU) const {
46+
getSelectionDAGFallbackAnalysisUsage(AU);
47+
MachineFunctionPass::getAnalysisUsage(AU);
48+
}
49+
50+
static bool assignInstr(MachineInstr &MI, MachineIRBuilder &MIRBuilder,
51+
const RegisterBankInfo &RBI,
52+
const TargetRegisterInfo &TRI,
53+
MachineRegisterInfo &MRI) {
54+
LLVM_DEBUG(dbgs() << "Assign: " << MI);
55+
56+
const RegisterBankInfo::InstructionMapping &Mapping = RBI.getInstrMapping(MI);
57+
for (unsigned OpIdx = 0, End = Mapping.getNumOperands(); OpIdx != End;
58+
++OpIdx) {
59+
MachineOperand &MO = MI.getOperand(OpIdx);
60+
if (!MO.isReg())
61+
continue;
62+
Register Reg = MO.getReg();
63+
if (!Reg || Reg.isPhysical())
64+
continue;
65+
66+
const RegisterBankInfo::ValueMapping &ValMapping =
67+
Mapping.getOperandMapping(OpIdx);
68+
if (!ValMapping.isValid() || ValMapping.NumBreakDowns != 1 ||
69+
!ValMapping.BreakDown[0].RegBank)
70+
return false;
71+
72+
const RegisterBank *CurrentRB = RBI.getRegBank(Reg, MRI, TRI);
73+
const RegisterBank *DesiredRB = ValMapping.BreakDown[0].RegBank;
74+
// RegBankSelectFast only assigns previously-unbanked regs. If a default
75+
// mapping wants a different bank than one already assigned, fall back to
76+
// full RegBankSelect so it can repair the conflict.
77+
if (CurrentRB && CurrentRB != DesiredRB &&
78+
Mapping.getID() == RegisterBankInfo::DefaultMappingID)
79+
return false;
80+
if (!CurrentRB)
81+
MRI.setRegBank(Reg, *DesiredRB);
82+
}
83+
84+
if (Mapping.getID() != RegisterBankInfo::DefaultMappingID) {
85+
RegisterBankInfo::OperandsMapper OpdMapper(MI, Mapping, MRI);
86+
RBI.applyMapping(MIRBuilder, OpdMapper);
87+
}
88+
89+
return true;
90+
}
91+
92+
bool RegBankSelectFast::runOnMachineFunction(MachineFunction &MF) {
93+
if (MF.getProperties().hasFailedISel())
94+
return false;
95+
96+
const RegisterBankInfo &RBI = *MF.getSubtarget().getRegBankInfo();
97+
const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
98+
99+
MachineRegisterInfo &MRI = MF.getRegInfo();
100+
MachineIRBuilder MIRBuilder(MF);
101+
102+
ReversePostOrderTraversal<MachineFunction *> RPOT(&MF);
103+
for (MachineBasicBlock *MBB : RPOT) {
104+
MIRBuilder.setMBB(*MBB);
105+
SmallVector<MachineInstr *> WorkList(
106+
make_pointer_range(reverse(MBB->instrs())));
107+
108+
while (!WorkList.empty()) {
109+
MachineInstr &MI = *WorkList.pop_back_val();
110+
111+
// Ignore target-specific post-isel instructions: they should use proper
112+
// regclasses.
113+
if (isTargetSpecificOpcode(MI.getOpcode()) && !MI.isPreISelOpcode())
114+
continue;
115+
116+
// Ignore inline asm instructions: they should use physical
117+
// registers/regclasses
118+
if (MI.isInlineAsm())
119+
continue;
120+
121+
// Ignore IMPLICIT_DEF which must have a regclass.
122+
if (MI.isImplicitDef())
123+
continue;
124+
125+
if (!assignInstr(MI, MIRBuilder, RBI, TRI, MRI)) {
126+
LLVM_DEBUG(dbgs() << "Falling back to full RegBankSelect for "
127+
<< MF.getName() << " after failing on: " << MI);
128+
FallbackRegBankSelect FallbackRBS;
129+
return FallbackRBS.runOnCurrentFunction(MF);
130+
}
131+
}
132+
}
133+
134+
return true;
135+
}

llvm/lib/Target/AArch64/AArch64TargetMachine.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "llvm/CodeGen/GlobalISel/LoadStoreOpt.h"
3131
#include "llvm/CodeGen/GlobalISel/Localizer.h"
3232
#include "llvm/CodeGen/GlobalISel/RegBankSelect.h"
33+
#include "llvm/CodeGen/GlobalISel/RegBankSelectFast.h"
3334
#include "llvm/CodeGen/MIRParser/MIParser.h"
3435
#include "llvm/CodeGen/MachineScheduler.h"
3536
#include "llvm/CodeGen/Passes.h"
@@ -118,6 +119,11 @@ static cl::opt<bool> EnableAtomicTidy(
118119
" to make use of cmpxchg flow-based information"),
119120
cl::init(true));
120121

122+
static cl::opt<int> UseRegBankSelectFastAtO(
123+
"aarch64-use-regbankselectfast-at-O", cl::Hidden,
124+
cl::desc("Use RegBankSelectFast at or below an opt level (-1 to disable)"),
125+
cl::init(0));
126+
121127
static cl::opt<bool>
122128
EnableEarlyIfConversion("aarch64-enable-early-ifcvt", cl::Hidden,
123129
cl::desc("Run early if-conversion"),
@@ -567,6 +573,8 @@ class AArch64PassConfig : public TargetPassConfig {
567573
if (TM.getOptLevel() != CodeGenOptLevel::None)
568574
substitutePass(&PostRASchedulerID, &PostMachineSchedulerID);
569575
setEnableSinkAndFold(EnableSinkFold);
576+
UseRegBankSelectFast =
577+
static_cast<int>(TM.getOptLevel()) <= UseRegBankSelectFastAtO;
570578
}
571579

572580
AArch64TargetMachine &getAArch64TargetMachine() const {
@@ -595,6 +603,9 @@ class AArch64PassConfig : public TargetPassConfig {
595603
bool addRegAssignAndRewriteOptimized() override;
596604

597605
std::unique_ptr<CSEConfigBase> getCSEConfig() const override;
606+
607+
private:
608+
bool UseRegBankSelectFast = false;
598609
};
599610

600611
} // end anonymous namespace
@@ -784,7 +795,10 @@ void AArch64PassConfig::addPreRegBankSelect() {
784795
}
785796

786797
bool AArch64PassConfig::addRegBankSelect() {
787-
addPass(new RegBankSelect());
798+
if (UseRegBankSelectFast)
799+
addPass(new RegBankSelectFast());
800+
else
801+
addPass(new RegBankSelect());
788802
return false;
789803
}
790804

llvm/test/CodeGen/AArch64/GlobalISel/gisel-commandline-option.ll

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
; RUN: llc -mtriple=aarch64-- -debug-pass=Structure %s -o /dev/null 2>&1 \
22
; RUN: --debugify-and-strip-all-safe=0 \
33
; RUN: -verify-machineinstrs=0 -O0 \
4-
; RUN: | FileCheck %s --check-prefixes=ENABLED,FALLBACK
4+
; RUN: | FileCheck %s --check-prefixes=ENABLED,ENABLED-O0,FALLBACK
55

66
; RUN: llc -mtriple=aarch64-- -debug-pass=Structure %s -o /dev/null 2>&1 \
77
; RUN: --debugify-and-strip-all-safe=0 \
88
; RUN: -verify-machineinstrs -O0 \
9-
; RUN: | FileCheck %s --check-prefixes=ENABLED,FALLBACK,VERIFY,VERIFY-O0
9+
; RUN: | FileCheck %s --check-prefixes=ENABLED,ENABLED-O0,FALLBACK,VERIFY,VERIFY-O0
1010

1111
; RUN: llc -mtriple=aarch64-- -debug-pass=Structure %s -o /dev/null 2>&1 \
1212
; RUN: --debugify-and-strip-all-safe=0 \
1313
; RUN: -verify-machineinstrs=0 -O0 -aarch64-enable-global-isel-at-O=0 -global-isel-abort=1 \
14-
; RUN: | FileCheck %s --check-prefixes=ENABLED,NOFALLBACK
14+
; RUN: | FileCheck %s --check-prefixes=ENABLED,ENABLED-O0,NOFALLBACK
1515

1616
; RUN: llc -mtriple=aarch64-- -debug-pass=Structure %s -o /dev/null 2>&1 \
1717
; RUN: --debugify-and-strip-all-safe=0 \
1818
; RUN: -verify-machineinstrs=0 -O0 -aarch64-enable-global-isel-at-O=0 -global-isel-abort=2 \
19-
; RUN: | FileCheck %s --check-prefixes=ENABLED,FALLBACK
19+
; RUN: | FileCheck %s --check-prefixes=ENABLED,ENABLED-O0,FALLBACK
2020

2121
; RUN: llc -mtriple=aarch64-- -debug-pass=Structure %s -o /dev/null 2>&1 \
2222
; RUN: --debugify-and-strip-all-safe=0 \
@@ -52,6 +52,16 @@
5252
; RUN: -debug-pass=Structure %s -o /dev/null 2>&1 -verify-machineinstrs=0 \
5353
; RUN: | FileCheck %s --check-prefix DISABLED
5454

55+
; RUN: llc -mtriple=aarch64-- -debug-pass=Structure %s -o /dev/null 2>&1 \
56+
; RUN: --debugify-and-strip-all-safe=0 \
57+
; RUN: -verify-machineinstrs=0 -O0 -aarch64-use-regbankselectfast-at-O=-1 \
58+
; RUN: | FileCheck %s --check-prefix=FORCE-RBS
59+
60+
; RUN: llc -mtriple=aarch64-- -debug-pass=Structure %s -o /dev/null 2>&1 \
61+
; RUN: --debugify-and-strip-all-safe=0 \
62+
; RUN: -verify-machineinstrs=0 -global-isel -O1 -aarch64-use-regbankselectfast-at-O=1 \
63+
; RUN: | FileCheck %s --check-prefix NOFALLBACK --check-prefix FAST-RBS-O1
64+
5565
; ENABLED: Safe Stack instrumentation pass
5666

5767
; ENABLED-O1: Basic Alias Analysis (stateless AA impl)
@@ -69,7 +79,10 @@
6979
; ENABLED-O1-NEXT: Analysis containing CSE Info
7080
; ENABLED: Legalizer
7181
; VERIFY-NEXT: Verify generated machine code
72-
; ENABLED: RegBankSelect
82+
; ENABLED-O0: RegBankSelectFast
83+
; ENABLED-O1: RegBankSelect{{$}}
84+
; FORCE-RBS: RegBankSelect{{$}}
85+
; FAST-RBS-O1: RegBankSelectFast
7386
; VERIFY-NEXT: Verify generated machine code
7487
; ENABLED-NEXT: Analysis for ComputingKnownBits
7588
; ENABLED-O1-NEXT: Lazy Branch Probability Analysis

llvm/test/CodeGen/AArch64/O0-pipeline.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
; CHECK-NEXT: Analysis for ComputingKnownBits
4141
; CHECK-NEXT: Legalizer
4242
; CHECK-NEXT: AArch64PostLegalizerLowering
43-
; CHECK-NEXT: RegBankSelect
43+
; CHECK-NEXT: RegBankSelectFast
4444
; CHECK-NEXT: Analysis for ComputingKnownBits
4545
; CHECK-NEXT: InstructionSelect
4646
; CHECK-NEXT: ResetMachineFunction

0 commit comments

Comments
 (0)