Skip to content

Commit 1e77635

Browse files
authored
[LoongArch] Add support for getNumberOfRegisters() (#88372)
The `TTI` hooks are used during vectorization for calculating register pressure. The default implementation defined wrong value for register number (all register class are 8 registers). This patch also defines LoongArch's own register classes.
1 parent ff9bc3a commit 1e77635

File tree

3 files changed

+89
-0
lines changed

3 files changed

+89
-0
lines changed

llvm/lib/Target/LoongArch/LoongArchTargetTransformInfo.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,45 @@ TypeSize LoongArchTTIImpl::getRegisterBitWidth(
4040
llvm_unreachable("Unsupported register kind");
4141
}
4242

43+
unsigned LoongArchTTIImpl::getNumberOfRegisters(unsigned ClassID) const {
44+
switch (ClassID) {
45+
case LoongArchRegisterClass::GPRRC:
46+
// 30 = 32 GPRs - r0 (zero register) - r21 (non-allocatable)
47+
return 30;
48+
case LoongArchRegisterClass::FPRRC:
49+
return ST->hasBasicF() ? 32 : 0;
50+
case LoongArchRegisterClass::VRRC:
51+
return ST->hasExtLSX() ? 32 : 0;
52+
}
53+
llvm_unreachable("unknown register class");
54+
}
55+
56+
unsigned LoongArchTTIImpl::getRegisterClassForType(bool Vector,
57+
Type *Ty) const {
58+
if (Vector)
59+
return LoongArchRegisterClass::VRRC;
60+
if (!Ty)
61+
return LoongArchRegisterClass::GPRRC;
62+
63+
Type *ScalarTy = Ty->getScalarType();
64+
if ((ScalarTy->isFloatTy() && ST->hasBasicF()) ||
65+
(ScalarTy->isDoubleTy() && ST->hasBasicD())) {
66+
return LoongArchRegisterClass::FPRRC;
67+
}
68+
69+
return LoongArchRegisterClass::GPRRC;
70+
}
71+
72+
const char *LoongArchTTIImpl::getRegisterClassName(unsigned ClassID) const {
73+
switch (ClassID) {
74+
case LoongArchRegisterClass::GPRRC:
75+
return "LoongArch::GPRRC";
76+
case LoongArchRegisterClass::FPRRC:
77+
return "LoongArch::FPRRC";
78+
case LoongArchRegisterClass::VRRC:
79+
return "LoongArch::VRRC";
80+
}
81+
llvm_unreachable("unknown register class");
82+
}
83+
4384
// TODO: Implement more hooks to provide TTI machinery for LoongArch.

llvm/lib/Target/LoongArch/LoongArchTargetTransformInfo.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class LoongArchTTIImpl : public BasicTTIImplBase<LoongArchTTIImpl> {
2828
typedef TargetTransformInfo TTI;
2929
friend BaseT;
3030

31+
enum LoongArchRegisterClass { GPRRC, FPRRC, VRRC };
3132
const LoongArchSubtarget *ST;
3233
const LoongArchTargetLowering *TLI;
3334

@@ -40,6 +41,9 @@ class LoongArchTTIImpl : public BasicTTIImplBase<LoongArchTTIImpl> {
4041
TLI(ST->getTargetLowering()) {}
4142

4243
TypeSize getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const;
44+
unsigned getNumberOfRegisters(unsigned ClassID) const;
45+
unsigned getRegisterClassForType(bool Vector, Type *Ty = nullptr) const;
46+
const char *getRegisterClassName(unsigned ClassID) const;
4347

4448
// TODO: Implement more hooks to provide TTI machinery for LoongArch.
4549
};
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
; REQUIRES: asserts
2+
; RUN: opt --passes=loop-vectorize --mtriple loongarch64-linux-gnu \
3+
; RUN: --mattr=+lsx -debug-only=loop-vectorize --force-vector-width=1 \
4+
; RUN: -S < %s 2>&1 | FileCheck %s --check-prefix=CHECK-SCALAR
5+
; RUN: opt --passes=loop-vectorize --mtriple loongarch64-linux-gnu \
6+
; RUN: --mattr=+lsx -debug-only=loop-vectorize --force-vector-width=4 \
7+
; RUN: -S < %s 2>&1 | FileCheck %s --check-prefix=CHECK-VECTOR
8+
9+
define void @bar(ptr %A, i32 signext %n) {
10+
; CHECK-LABEL: bar
11+
; CHECK-SCALAR: LV(REG): Found max usage: 2 item
12+
; CHECK-SCALAR-NEXT: LV(REG): RegisterClass: LoongArch::GPRRC, 2 registers
13+
; CHECK-SCALAR-NEXT: LV(REG): RegisterClass: LoongArch::FPRRC, 1 registers
14+
; CHECK-SCALAR-NEXT: LV(REG): Found invariant usage: 1 item
15+
; CHECK-SCALAR-NEXT: LV(REG): RegisterClass: LoongArch::GPRRC, 1 registers
16+
; CHECK-SCALAR-NEXT: LV: The target has 30 registers of LoongArch::GPRRC register class
17+
; CHECK-SCALAR-NEXT: LV: The target has 32 registers of LoongArch::FPRRC register class
18+
; CHECK-VECTOR: LV(REG): Found max usage: 1 item
19+
; CHECK-VECTOR-NEXT: LV(REG): RegisterClass: LoongArch::VRRC, 3 registers
20+
; CHECK-VECTOR-NEXT: LV(REG): Found invariant usage: 1 item
21+
; CHECK-VECTOR-NEXT: LV(REG): RegisterClass: LoongArch::GPRRC, 1 registers
22+
; CHECK-VECTOR-NEXT: LV: The target has 32 registers of LoongArch::VRRC register class
23+
24+
entry:
25+
%cmp4 = icmp sgt i32 %n, 0
26+
br i1 %cmp4, label %for.body.preheader, label %for.cond.cleanup
27+
28+
for.body.preheader: ; preds = %entry
29+
%wide.trip.count = zext nneg i32 %n to i64
30+
br label %for.body
31+
32+
for.cond.cleanup: ; preds = %for.body, %entry
33+
ret void
34+
35+
for.body: ; preds = %for.body.preheader, %for.body
36+
%indvars.iv = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.body ]
37+
%0 = trunc i64 %indvars.iv to i32
38+
%conv = sitofp i32 %0 to float
39+
%arrayidx = getelementptr inbounds float, ptr %A, i64 %indvars.iv
40+
store float %conv, ptr %arrayidx, align 4
41+
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
42+
%exitcond.not = icmp eq i64 %indvars.iv.next, %wide.trip.count
43+
br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
44+
}

0 commit comments

Comments
 (0)