Skip to content

Commit 0a7e5fd

Browse files
GlobalISel/MachineIRBuilder: Construct DstOp with VRegAttrs
Allow construction of DstOp with VRegAttrs. Also allow construction with register class or bank and LLT. Intended to be used in lowering code for reg-bank-select where new registers need to have both register bank and LLT. Add support for new type of DstOp in CSEMIRBuilder.
1 parent 0af6c30 commit 0a7e5fd

File tree

7 files changed

+121
-21
lines changed

7 files changed

+121
-21
lines changed

llvm/include/llvm/CodeGen/GlobalISel/CSEInfo.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
1818
#include "llvm/CodeGen/GlobalISel/GISelWorkList.h"
1919
#include "llvm/CodeGen/MachineFunctionPass.h"
20+
#include "llvm/CodeGen/MachineRegisterInfo.h"
2021
#include "llvm/Support/Allocator.h"
2122
#include "llvm/Support/CodeGen.h"
2223

@@ -177,6 +178,8 @@ class GISelInstProfileBuilder {
177178
const GISelInstProfileBuilder &addNodeIDOpcode(unsigned Opc) const;
178179
const GISelInstProfileBuilder &addNodeIDRegType(const LLT Ty) const;
179180
const GISelInstProfileBuilder &addNodeIDRegType(const Register) const;
181+
const GISelInstProfileBuilder &
182+
addNodeIDRegType(MachineRegisterInfo::VRegAttrs) const;
180183

181184
const GISelInstProfileBuilder &
182185
addNodeIDRegType(const TargetRegisterClass *RC) const;

llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,20 @@ class DstOp {
7272
LLT LLTTy;
7373
Register Reg;
7474
const TargetRegisterClass *RC;
75+
MachineRegisterInfo::VRegAttrs Attrs;
7576
};
7677

7778
public:
78-
enum class DstType { Ty_LLT, Ty_Reg, Ty_RC };
79+
enum class DstType { Ty_LLT, Ty_Reg, Ty_RC, Ty_VRegAttrs };
7980
DstOp(unsigned R) : Reg(R), Ty(DstType::Ty_Reg) {}
8081
DstOp(Register R) : Reg(R), Ty(DstType::Ty_Reg) {}
8182
DstOp(const MachineOperand &Op) : Reg(Op.getReg()), Ty(DstType::Ty_Reg) {}
8283
DstOp(const LLT T) : LLTTy(T), Ty(DstType::Ty_LLT) {}
8384
DstOp(const TargetRegisterClass *TRC) : RC(TRC), Ty(DstType::Ty_RC) {}
85+
DstOp(MachineRegisterInfo::VRegAttrs Attrs)
86+
: Attrs(Attrs), Ty(DstType::Ty_VRegAttrs) {}
87+
DstOp(RegClassOrRegBank RCOrRB, LLT Ty)
88+
: Attrs({RCOrRB, Ty}), Ty(DstType::Ty_VRegAttrs) {}
8489

8590
void addDefToMIB(MachineRegisterInfo &MRI, MachineInstrBuilder &MIB) const {
8691
switch (Ty) {
@@ -93,6 +98,9 @@ class DstOp {
9398
case DstType::Ty_RC:
9499
MIB.addDef(MRI.createVirtualRegister(RC));
95100
break;
101+
case DstType::Ty_VRegAttrs:
102+
MIB.addDef(MRI.createVirtualRegister(Attrs));
103+
break;
96104
}
97105
}
98106

@@ -104,6 +112,8 @@ class DstOp {
104112
return LLTTy;
105113
case DstType::Ty_Reg:
106114
return MRI.getType(Reg);
115+
case DstType::Ty_VRegAttrs:
116+
return Attrs.Ty;
107117
}
108118
llvm_unreachable("Unrecognised DstOp::DstType enum");
109119
}
@@ -114,12 +124,13 @@ class DstOp {
114124
}
115125

116126
const TargetRegisterClass *getRegClass() const {
117-
switch (Ty) {
118-
case DstType::Ty_RC:
119-
return RC;
120-
default:
121-
llvm_unreachable("Not a RC Operand");
122-
}
127+
assert(Ty == DstType::Ty_RC && "Not a RC Operand");
128+
return RC;
129+
}
130+
131+
MachineRegisterInfo::VRegAttrs getVRegAttrs() const {
132+
assert(Ty == DstType::Ty_VRegAttrs && "Not a VRegAttrs Operand");
133+
return Attrs;
123134
}
124135

125136
DstType getDstOpKind() const { return Ty; }

llvm/include/llvm/CodeGen/MachineRegisterInfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -754,7 +754,7 @@ class MachineRegisterInfo {
754754
/// Returns register class or bank and low level type of \p Reg. Always safe
755755
/// to use. Special values are returned when \p Reg does not have some of the
756756
/// attributes.
757-
VRegAttrs getVRegAttrs(Register Reg) {
757+
VRegAttrs getVRegAttrs(Register Reg) const {
758758
return {getRegClassOrRegBank(Reg), getType(Reg)};
759759
}
760760

llvm/lib/CodeGen/GlobalISel/CSEInfo.cpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,20 @@ GISelInstProfileBuilder::addNodeIDRegType(const RegisterBank *RB) const {
356356
return *this;
357357
}
358358

359+
const GISelInstProfileBuilder &GISelInstProfileBuilder::addNodeIDRegType(
360+
MachineRegisterInfo::VRegAttrs Attrs) const {
361+
addNodeIDRegType(Attrs.Ty);
362+
363+
const RegClassOrRegBank &RCOrRB = Attrs.RCOrRB;
364+
if (RCOrRB) {
365+
if (const auto *RB = dyn_cast_if_present<const RegisterBank *>(RCOrRB))
366+
addNodeIDRegType(RB);
367+
else
368+
addNodeIDRegType(dyn_cast<const TargetRegisterClass *>(RCOrRB));
369+
}
370+
return *this;
371+
}
372+
359373
const GISelInstProfileBuilder &
360374
GISelInstProfileBuilder::addNodeIDImmediate(int64_t Imm) const {
361375
ID.AddInteger(Imm);
@@ -389,17 +403,7 @@ GISelInstProfileBuilder::addNodeIDFlag(unsigned Flag) const {
389403

390404
const GISelInstProfileBuilder &
391405
GISelInstProfileBuilder::addNodeIDReg(Register Reg) const {
392-
LLT Ty = MRI.getType(Reg);
393-
if (Ty.isValid())
394-
addNodeIDRegType(Ty);
395-
396-
if (const RegClassOrRegBank &RCOrRB = MRI.getRegClassOrRegBank(Reg)) {
397-
if (const auto *RB = dyn_cast_if_present<const RegisterBank *>(RCOrRB))
398-
addNodeIDRegType(RB);
399-
else if (const auto *RC =
400-
dyn_cast_if_present<const TargetRegisterClass *>(RCOrRB))
401-
addNodeIDRegType(RC);
402-
}
406+
addNodeIDRegType(MRI.getVRegAttrs(Reg));
403407
return *this;
404408
}
405409

llvm/lib/CodeGen/GlobalISel/CSEMIRBuilder.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,18 +73,24 @@ bool CSEMIRBuilder::canPerformCSEForOpc(unsigned Opc) const {
7373
void CSEMIRBuilder::profileDstOp(const DstOp &Op,
7474
GISelInstProfileBuilder &B) const {
7575
switch (Op.getDstOpKind()) {
76-
case DstOp::DstType::Ty_RC:
76+
case DstOp::DstType::Ty_RC: {
7777
B.addNodeIDRegType(Op.getRegClass());
7878
break;
79+
}
7980
case DstOp::DstType::Ty_Reg: {
8081
// Regs can have LLT&(RB|RC). If those exist, profile them as well.
8182
B.addNodeIDReg(Op.getReg());
8283
break;
8384
}
84-
default:
85+
case DstOp::DstType::Ty_LLT: {
8586
B.addNodeIDRegType(Op.getLLTTy(*getMRI()));
8687
break;
8788
}
89+
case DstOp::DstType::Ty_VRegAttrs: {
90+
B.addNodeIDRegType(Op.getVRegAttrs());
91+
break;
92+
}
93+
}
8894
}
8995

9096
void CSEMIRBuilder::profileSrcOp(const SrcOp &Op,

llvm/unittests/Target/AMDGPU/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@ set(LLVM_LINK_COMPONENTS
1111
CodeGen
1212
CodeGenTypes
1313
Core
14+
GlobalISel
1415
MC
1516
Support
1617
TargetParser
1718
)
1819

1920
add_llvm_target_unittest(AMDGPUTests
2021
AMDGPUUnitTests.cpp
22+
CSETest.cpp
2123
DwarfRegMappings.cpp
2224
ExecMayBeModifiedBeforeAnyUse.cpp
2325
PALMetadata.cpp
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
//===- llvm/unittests/Target/AMDGPU/CSETest.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+
9+
#include "AMDGPUTargetMachine.h"
10+
#include "AMDGPUUnitTests.h"
11+
#include "llvm/CodeGen/GlobalISel/CSEInfo.h"
12+
#include "llvm/CodeGen/GlobalISel/CSEMIRBuilder.h"
13+
#include "gtest/gtest.h"
14+
15+
using namespace llvm;
16+
17+
TEST(AMDGPU, TestCSEForRegisterClassOrBankAndLLT) {
18+
auto TM = createAMDGPUTargetMachine("amdgcn-amd-", "gfx1100", "");
19+
if (!TM)
20+
GTEST_SKIP();
21+
22+
GCNSubtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()),
23+
std::string(TM->getTargetFeatureString()), *TM);
24+
25+
LLVMContext Ctx;
26+
Module Mod("Module", Ctx);
27+
Mod.setDataLayout(TM->createDataLayout());
28+
29+
auto *Type = FunctionType::get(Type::getVoidTy(Ctx), false);
30+
auto *F = Function::Create(Type, GlobalValue::ExternalLinkage, "Test", &Mod);
31+
32+
MachineModuleInfo MMI(TM.get());
33+
auto MF =
34+
std::make_unique<MachineFunction>(*F, *TM, ST, MMI.getContext(), 42);
35+
auto *BB = MF->CreateMachineBasicBlock();
36+
MF->push_back(BB);
37+
38+
MachineIRBuilder B(*MF);
39+
B.setMBB(*BB);
40+
41+
LLT S32{LLT::scalar(32)};
42+
Register R0 = B.buildCopy(S32, Register(AMDGPU::SGPR0)).getReg(0);
43+
Register R1 = B.buildCopy(S32, Register(AMDGPU::SGPR1)).getReg(0);
44+
45+
GISelCSEInfo CSEInfo;
46+
CSEInfo.setCSEConfig(std::make_unique<CSEConfigFull>());
47+
CSEInfo.analyze(*MF);
48+
B.setCSEInfo(&CSEInfo);
49+
CSEMIRBuilder CSEB(B.getState());
50+
CSEB.setInsertPt(B.getMBB(), B.getInsertPt());
51+
52+
const RegisterBankInfo &RBI = *MF->getSubtarget().getRegBankInfo();
53+
54+
const TargetRegisterClass *SgprRC = &AMDGPU::SReg_32RegClass;
55+
const RegisterBank *SgprRB = &RBI.getRegBank(AMDGPU::SGPRRegBankID);
56+
MachineRegisterInfo::VRegAttrs SgprRCS32 = {SgprRC, S32};
57+
MachineRegisterInfo::VRegAttrs SgprRBS32 = {SgprRB, S32};
58+
59+
auto AddLLT = CSEB.buildAdd(S32, R0, R1);
60+
auto AddRCLLT = CSEB.buildInstr(AMDGPU::G_ADD, {SgprRCS32}, {R0, R1});
61+
auto AddRBLLT = CSEB.buildInstr(AMDGPU::G_ADD, {{SgprRB, S32}}, {R0, R1});
62+
63+
EXPECT_NE(AddLLT, AddRCLLT);
64+
EXPECT_NE(AddLLT, AddRBLLT);
65+
EXPECT_NE(AddRCLLT, AddRBLLT);
66+
67+
auto AddLLT_CSE = CSEB.buildAdd(S32, R0, R1);
68+
auto AddRCLLT_CSE = CSEB.buildInstr(AMDGPU::G_ADD, {{SgprRC, S32}}, {R0, R1});
69+
auto AddRBLLT_CSE = CSEB.buildInstr(AMDGPU::G_ADD, {SgprRBS32}, {R0, R1});
70+
71+
EXPECT_EQ(AddLLT, AddLLT_CSE);
72+
EXPECT_EQ(AddRCLLT, AddRCLLT_CSE);
73+
EXPECT_EQ(AddRBLLT, AddRBLLT_CSE);
74+
}

0 commit comments

Comments
 (0)