Skip to content

Commit ffcad03

Browse files
authored
[SYCL][FPGA] Enable template parameter support for memory attributes (#1113)
This patch introduces template parameter support for the following attributes: * numbanks(N) * bankwidth(N) * bank_bits(b0, b1, ..., bn) * max_replicates(N) * private_copies(N) Signed-off-by: Viktoria Maksimova <[email protected]>
1 parent 38ace4d commit ffcad03

File tree

3 files changed

+196
-2
lines changed

3 files changed

+196
-2
lines changed

clang/lib/Sema/SemaTemplateInstantiateDecl.cpp

100755100644
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,65 @@ static void instantiateDependentAMDGPUWavesPerEUAttr(
506506
S.addAMDGPUWavesPerEUAttr(New, Attr, MinExpr, MaxExpr);
507507
}
508508

509+
static void instantiateIntelFPGABankWidthAttr(
510+
Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
511+
const IntelFPGABankWidthAttr *Attr, Decl *New) {
512+
EnterExpressionEvaluationContext Unevaluated(
513+
S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
514+
ExprResult Result = S.SubstExpr(Attr->getValue(), TemplateArgs);
515+
if (!Result.isInvalid())
516+
return S.AddOneConstantPowerTwoValueAttr<IntelFPGABankWidthAttr>(
517+
New, *Attr, Result.getAs<Expr>());
518+
}
519+
520+
static void instantiateIntelFPGANumBanksAttr(
521+
Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
522+
const IntelFPGANumBanksAttr *Attr, Decl *New) {
523+
EnterExpressionEvaluationContext Unevaluated(
524+
S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
525+
ExprResult Result = S.SubstExpr(Attr->getValue(), TemplateArgs);
526+
if (!Result.isInvalid())
527+
return S.AddOneConstantPowerTwoValueAttr<IntelFPGANumBanksAttr>(
528+
New, *Attr, Result.getAs<Expr>());
529+
}
530+
531+
static void instantiateIntelFPGAPrivateCopiesAttr(
532+
Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
533+
const IntelFPGAPrivateCopiesAttr *Attr, Decl *New) {
534+
EnterExpressionEvaluationContext Unevaluated(
535+
S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
536+
ExprResult Result = S.SubstExpr(Attr->getValue(), TemplateArgs);
537+
if (!Result.isInvalid())
538+
return S.AddOneConstantValueAttr<IntelFPGAPrivateCopiesAttr>(
539+
New, *Attr, Result.getAs<Expr>());
540+
}
541+
542+
static void instantiateIntelFPGAMaxReplicatesAttr(
543+
Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
544+
const IntelFPGAMaxReplicatesAttr *Attr, Decl *New) {
545+
EnterExpressionEvaluationContext Unevaluated(
546+
S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
547+
ExprResult Result = S.SubstExpr(Attr->getValue(), TemplateArgs);
548+
if (!Result.isInvalid())
549+
return S.AddOneConstantValueAttr<IntelFPGAMaxReplicatesAttr>(
550+
New, *Attr, Result.getAs<Expr>());
551+
}
552+
553+
static void instantiateIntelFPGABankBitsAttr(
554+
Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
555+
const IntelFPGABankBitsAttr *Attr, Decl *New) {
556+
EnterExpressionEvaluationContext Unevaluated(
557+
S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
558+
SmallVector<Expr *, 8> Args;
559+
for (auto I : Attr->args()) {
560+
ExprResult Result = S.SubstExpr(I, TemplateArgs);
561+
if (Result.isInvalid())
562+
return;
563+
Args.push_back(Result.getAs<Expr>());
564+
}
565+
S.AddIntelFPGABankBitsAttr(New, *Attr, Args.data(), Args.size());
566+
}
567+
509568
void Sema::InstantiateAttrsForDecl(
510569
const MultiLevelTemplateArgumentList &TemplateArgs, const Decl *Tmpl,
511570
Decl *New, LateInstantiatedAttrVec *LateAttrs,
@@ -614,6 +673,32 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
614673
*AMDGPUFlatWorkGroupSize, New);
615674
}
616675

676+
if (const auto *IntelFPGABankWidth =
677+
dyn_cast<IntelFPGABankWidthAttr>(TmplAttr)) {
678+
instantiateIntelFPGABankWidthAttr(*this, TemplateArgs, IntelFPGABankWidth,
679+
New);
680+
}
681+
if (const auto *IntelFPGANumBanks =
682+
dyn_cast<IntelFPGANumBanksAttr>(TmplAttr)) {
683+
instantiateIntelFPGANumBanksAttr(*this, TemplateArgs, IntelFPGANumBanks,
684+
New);
685+
}
686+
if (const auto *IntelFPGAPrivateCopies =
687+
dyn_cast<IntelFPGAPrivateCopiesAttr>(TmplAttr)) {
688+
instantiateIntelFPGAPrivateCopiesAttr(*this, TemplateArgs,
689+
IntelFPGAPrivateCopies, New);
690+
}
691+
if (const auto *IntelFPGAMaxReplicates =
692+
dyn_cast<IntelFPGAMaxReplicatesAttr>(TmplAttr)) {
693+
instantiateIntelFPGAMaxReplicatesAttr(*this, TemplateArgs,
694+
IntelFPGAMaxReplicates, New);
695+
}
696+
if (const auto *IntelFPGABankBits =
697+
dyn_cast<IntelFPGABankBitsAttr>(TmplAttr)) {
698+
instantiateIntelFPGABankBitsAttr(*this, TemplateArgs, IntelFPGABankBits,
699+
New);
700+
}
701+
617702
// Existing DLL attribute on the instantiation takes precedence.
618703
if (TmplAttr->getKind() == attr::DLLExport ||
619704
TmplAttr->getKind() == attr::DLLImport) {

clang/test/CodeGenSYCL/intel-fpga-local.cpp

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,15 @@
2020
// CHECK-DEVICE: [[ANN_bankbits_bankwidth:@.str.[0-9]*]] = {{.*}}{memory:DEFAULT}{sizeinfo:4,10,2}{bankwidth:16}{numbanks:2}{bank_bits:0}
2121
// CHECK-DEVICE: [[ANN_memory_blockram:@.str.[0-9]*]] = {{.*}}{memory:BLOCK_RAM}{sizeinfo:4}
2222
// CHECK-DEVICE: [[ANN_memory_mlab:@.str.[0-9]*]] = {{.*}}{memory:MLAB}{sizeinfo:4}
23+
// CHECK-DEVICE: [[ANN_private_copies_4:@.str.[0-9]*]] = {{.*}}{memory:DEFAULT}{sizeinfo:4}{private_copies:4}
24+
// CHECK-DEVICE: [[ANN_max_replicates_4:@.str.[0-9]*]] = {{.*}}{max_replicates:4}
2325

2426
// CHECK-BOTH: @llvm.global.annotations
2527
// CHECK-DEVICE-SAME: { i8* addrspacecast (i8 addrspace(1)* bitcast (i32 addrspace(1)* @_ZZ15attrs_on_staticvE15static_numbanks to i8 addrspace(1)*) to i8*)
26-
// CHECK-DEVICE-SAME: [[ANN_numbanks_4]]{{.*}}i32 36
28+
// CHECK-DEVICE-SAME: [[ANN_numbanks_4]]{{.*}}i32 38
2729
// CHECK-DEVICE-SAME: { i8* addrspacecast (i8 addrspace(1)* bitcast (i32 addrspace(1)* @_ZZ15attrs_on_staticvE15static_annotate to i8 addrspace(1)*) to i8*)
2830
// CHECK-HOST-SAME: { i8* bitcast (i32* @_ZZ15attrs_on_staticvE15static_annotate to i8*)
29-
// CHECK-BOTH-SAME: [[ANN_annotate]]{{.*}}i32 40
31+
// CHECK-BOTH-SAME: [[ANN_annotate]]{{.*}}i32 42
3032

3133
// CHECK-HOST-NOT: llvm.var.annotation
3234
// CHECK-HOST-NOT: llvm.ptr.annotation
@@ -175,6 +177,49 @@ void attrs_on_struct() {
175177
// CHECK-HOST-NOT: llvm.var.annotation
176178
// CHECK-HOST-NOT: llvm.ptr.annotation
177179

180+
template <int A, int B>
181+
void attrs_with_template_param() {
182+
// CHECK-DEVICE: %[[TEMPL_NUMBANKS:numbanks[0-9]+]] = bitcast{{.*}}%numbanks
183+
// CHECK-DEVICE: @llvm.var.annotation{{.*}}%[[TEMPL_NUMBANKS]],{{.*}}[[ANN_numbanks_4]]
184+
int numbanks [[intelfpga::numbanks(A)]];
185+
// CHECK-DEVICE: %[[TEMPL_BANKWIDTH:bankwidth[a-z0-9]+]] = bitcast{{.*}}%bankwidth
186+
// CHECK-DEVICE: llvm.var.annotation{{.*}}%[[TEMPL_BANKWIDTH]],{{.*}}[[ANN_bankwidth_4]]
187+
int bankwidth [[intelfpga::bankwidth(A)]];
188+
// CHECK-DEVICE: %[[TEMPL_PRIV_COPIES:priv_copies[0-9]+]] = bitcast{{.*}}%priv_copies
189+
// CHECK-DEVICE: llvm.var.annotation{{.*}}%[[TEMPL_PRIV_COPIES]],{{.*}}[[ANN_private_copies_4]]
190+
int priv_copies [[intelfpga::private_copies(A)]];
191+
// CHECK-DEVICE: %[[TEMPL_MAXREPL:max_repl[0-9]+]] = bitcast{{.*}}%max_repl
192+
// CHECK-DEVICE: llvm.var.annotation{{.*}}%[[TEMPL_MAXREPL]],{{.*}}[[ANN_max_replicates_4]]
193+
int max_repl [[intelfpga::max_replicates(A)]];
194+
// CHECK-DEVICE: %[[TEMPL_BANKBITS:bankbits[0-9]+]] = bitcast{{.*}}%bankbits
195+
// CHECK-DEVICE: @llvm.var.annotation{{.*}}%[[TEMPL_BANKBITS]],{{.*}}[[ANN_bankbits_4_5]]
196+
int bankbits [[intelfpga::bank_bits(A, B)]];
197+
198+
struct templ_on_struct_fields {
199+
int numbanks [[intelfpga::numbanks(A)]] ;
200+
int bankwidth [[intelfpga::bankwidth(A)]];
201+
int privatecopies [[intelfpga::private_copies(A)]];
202+
int maxreplicates [[intelfpga::max_replicates(A)]];
203+
int bankbits [[intelfpga::bank_bits(A, B)]];
204+
} s;
205+
206+
// CHECK-DEVICE: %[[FIELD_NUMBANKS:.*]] = getelementptr inbounds %struct.{{.*}}.templ_on_struct_fields{{.*}}
207+
// CHECK-DEVICE: call i32* @llvm.ptr.annotation.p0i32{{.*}}%[[FIELD_NUMBANKS]]{{.*}}[[ANN_numbanks_4]]
208+
s.numbanks = 0;
209+
// CHECK-DEVICE: %[[FIELD_BANKWIDTH:.*]] = getelementptr inbounds %struct.{{.*}}.templ_on_struct_fields{{.*}}
210+
// CHECK-DEVICE: call i32* @llvm.ptr.annotation.p0i32{{.*}}%[[FIELD_BANKWIDTH]]{{.*}}[[ANN_bankwidth_4]]
211+
s.bankwidth = 0;
212+
// CHECK-DEVICE: %[[FIELD_PRIV_COPIES:.*]] = getelementptr inbounds %struct.{{.*}}.templ_on_struct_fields{{.*}}
213+
// CHECK-DEVICE: call i32* @llvm.ptr.annotation.p0i32{{.*}}%[[FIELD_PRIV_COPIES]]{{.*}}[[ANN_private_copies_4]]
214+
s.privatecopies = 0;
215+
// CHECK-DEVICE: %[[FIELD_MAX_REPLICATES:.*]] = getelementptr inbounds %struct.{{.*}}.templ_on_struct_fields{{.*}}
216+
// CHECK-DEVICE: call i32* @llvm.ptr.annotation.p0i32{{.*}}%[[FIELD_MAX_REPLICATES]]{{.*}}[[ANN_max_replicates_4]]
217+
s.maxreplicates = 0;
218+
// CHECK-DEVICE: %[[FIELD_BANKBITS:.*]] = getelementptr inbounds %struct.{{.*}}.templ_on_struct_fields{{.*}}
219+
// CHECK-DEVICE: call i32* @llvm.ptr.annotation.p0i32{{.*}}%[[FIELD_BANKBITS]]{{.*}}[[ANN_bankbits_4_5]]
220+
s.bankbits = 0;
221+
}
222+
178223
void field_addrspace_cast() {
179224
struct state {
180225
[[intelfpga::numbanks(2)]] int mem[8];
@@ -206,6 +251,7 @@ int main() {
206251
attrs_on_var();
207252
attrs_on_struct();
208253
field_addrspace_cast();
254+
attrs_with_template_param<4,5>();
209255
});
210256
return 0;
211257
}

clang/test/SemaSYCL/intel-fpga-local.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,67 @@ struct foo {
573573
[[intelfpga::bank_bits(2,3)]] unsigned int bankbits[64];
574574
};
575575

576+
//CHECK: FunctionDecl{{.*}}used check_template_parameters
577+
template<int A, int B, int C, int D>
578+
void check_template_parameters() {
579+
//CHECK: VarDecl{{.*}}numbanks
580+
//CHECK-NEXT: IntelFPGAMemoryAttr{{.*}}Implicit
581+
//CHECK-NEXT: IntelFPGANumBanksAttr
582+
//CHECK-NEXT: ConstantExpr
583+
//CHECK-NEXT: SubstNonTypeTemplateParmExpr
584+
//CHECK-NEXT: IntegerLiteral{{.*}}8{{$}}
585+
[[intelfpga::numbanks(C)]] unsigned int numbanks;
586+
587+
//CHECK: VarDecl{{.*}}private_copies
588+
//CHECK: IntelFPGAMemoryAttr{{.*}}Implicit
589+
//CHECK: IntelFPGAPrivateCopiesAttr
590+
//CHECK-NEXT: ConstantExpr
591+
//CHECK-NEXT: SubstNonTypeTemplateParmExpr
592+
//CHECK-NEXT: IntegerLiteral{{.*}}8{{$}}
593+
[[intelfpga::private_copies(C)]] unsigned int private_copies;
594+
595+
//CHECK: VarDecl{{.*}}bank_bits_width
596+
//CHECK: IntelFPGANumBanksAttr{{.*}}Implicit{{$}}
597+
//CHECK-NEXT: IntegerLiteral{{.*}}4{{$}}
598+
//CHECK-NEXT: IntelFPGAMemoryAttr{{.*}}Implicit
599+
//CHECK-NEXT: IntelFPGABankBitsAttr
600+
//CHECK-NEXT: ConstantExpr
601+
//CHECK-NEXT: SubstNonTypeTemplateParmExpr
602+
//CHECK-NEXT: IntegerLiteral{{.*}}2{{$}}
603+
//CHECK-NEXT: ConstantExpr
604+
//CHECK-NEXT: IntegerLiteral{{.*}}3{{$}}
605+
//CHECK: IntelFPGABankWidthAttr
606+
//CHECK-NEXT: ConstantExpr
607+
//CHECK-NEXT: SubstNonTypeTemplateParmExpr
608+
//CHECK-NEXT: IntegerLiteral{{.*}}8{{$}}
609+
[[intelfpga::bank_bits(A,3), intelfpga::bankwidth(C)]]
610+
unsigned int bank_bits_width;
611+
612+
//CHECK: VarDecl{{.*}}max_replicates
613+
//CHECK: IntelFPGAMaxReplicatesAttr
614+
//CHECK: ConstantExpr
615+
//CHECK-NEXT: SubstNonTypeTemplateParmExpr
616+
//CHECK: IntegerLiteral{{.*}}2{{$}}
617+
[[intelfpga::max_replicates(A)]]
618+
unsigned int max_replicates;
619+
620+
//expected-error@+1{{'numbanks' attribute takes one argument}}
621+
[[intelfpga::numbanks(A,B)]]
622+
int numbanks_negative;
623+
624+
//expected-error@+1{{'max_replicates' attribute requires integer constant between 1 and 1048576}}
625+
[[intelfpga::max_replicates(D)]]
626+
[[intelfpga::max_replicates(C)]]
627+
//expected-warning@-1{{attribute 'max_replicates' is already applied}}
628+
unsigned int max_replicates_duplicate;
629+
630+
//expected-error@+3{{'max_replicates' and 'register' attributes are not compatible}}
631+
[[intelfpga::register]]
632+
//expected-note@-1 {{conflicting attribute is here}}
633+
[[intelfpga::max_replicates(C)]]
634+
unsigned int maxrepl_reg;
635+
}
636+
576637
template <typename name, typename Func>
577638
__attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) {
578639
kernelFunc();
@@ -583,6 +644,8 @@ int main() {
583644
check_ast();
584645
diagnostics();
585646
check_gnu_style();
647+
check_template_parameters<2, 4, 8, -1>();
648+
//expected-note@-1 +{{in instantiation of function template specialization}}
586649
});
587650
return 0;
588651
}

0 commit comments

Comments
 (0)