Skip to content

Commit 295c13d

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 295c13d

File tree

7 files changed

+127
-15
lines changed

7 files changed

+127
-15
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: 20 additions & 1 deletion
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
}
@@ -122,6 +132,15 @@ class DstOp {
122132
}
123133
}
124134

135+
MachineRegisterInfo::VRegAttrs getVRegAttrs() const {
136+
switch (Ty) {
137+
case DstType::Ty_VRegAttrs:
138+
return Attrs;
139+
default:
140+
llvm_unreachable("Not a VRegAttrs Operand");
141+
}
142+
}
143+
125144
DstType getDstOpKind() const { return Ty; }
126145

127146
private:

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: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,23 @@ GISelInstProfileBuilder::addNodeIDRegType(const RegisterBank *RB) const {
356356
return *this;
357357
}
358358

359+
const GISelInstProfileBuilder &GISelInstProfileBuilder::addNodeIDRegType(
360+
MachineRegisterInfo::VRegAttrs Attrs) const {
361+
LLT Ty = Attrs.Ty;
362+
if (Ty.isValid())
363+
addNodeIDRegType(Ty);
364+
365+
const RegClassOrRegBank &RCOrRB = Attrs.RCOrRB;
366+
if (RCOrRB) {
367+
if (const auto *RB = dyn_cast_if_present<const RegisterBank *>(RCOrRB))
368+
addNodeIDRegType(RB);
369+
else if (const auto *RC =
370+
dyn_cast_if_present<const TargetRegisterClass *>(RCOrRB))
371+
addNodeIDRegType(RC);
372+
}
373+
return *this;
374+
}
375+
359376
const GISelInstProfileBuilder &
360377
GISelInstProfileBuilder::addNodeIDImmediate(int64_t Imm) const {
361378
ID.AddInteger(Imm);
@@ -389,17 +406,7 @@ GISelInstProfileBuilder::addNodeIDFlag(unsigned Flag) const {
389406

390407
const GISelInstProfileBuilder &
391408
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-
}
409+
addNodeIDRegType(MRI.getVRegAttrs(Reg));
403410
return *this;
404411
}
405412

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

0 commit comments

Comments
 (0)