Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SYCL] Add Intel FPGA force_pow2_depth attribute #1284

Merged
merged 1 commit into from
Mar 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -1850,6 +1850,23 @@ def IntelFPGABankBits : Attr {
}];
}

def IntelFPGAForcePow2Depth : Attr {
let Spellings = [CXX11<"intelfpga","force_pow2_depth">];
let Args = [ExprArgument<"Value">];
let Subjects = SubjectList<[IntelFPGAConstVar, IntelFPGALocalStaticSlaveMemVar,
Field], ErrorDiag>;
let LangOpts = [SYCLIsDevice, SYCLIsHost];
let Documentation = [IntelFPGAForcePow2DepthAttrDocs];
let AdditionalMembers = [{
static unsigned getMinValue() {
return 0;
}
static unsigned getMaxValue() {
return 1;
}
mlychkov marked this conversation as resolved.
Show resolved Hide resolved
}];
}

def Naked : InheritableAttr {
let Spellings = [GCC<"naked">, Declspec<"naked">];
let Subjects = SubjectList<[Function]>;
Expand Down
20 changes: 20 additions & 0 deletions clang/include/clang/Basic/AttrDocs.td
Original file line number Diff line number Diff line change
Expand Up @@ -1935,6 +1935,26 @@ pointer address bits to bank on.
}];
}

def IntelFPGAForcePow2DepthAttrDocs : Documentation {
let Category = DocCatVariable;
let Heading = "force_pow2_depth (IntelFPGA)";
let Content = [{
This attribute may be attached to a variable or struct member declaration and
provides explicit control over the geometry of memory blocks used in a given
memory system.

In the presence of this attribute, the compiler:

1. Will automatically size the memory depth to the next largest power of 2 if
force_pow2_depth is set to 1, and will prefer width-stitching of RAM blocks
over depth-stitching.

2. Will not size the memory to the next largest power of 2 if force_pow2_depth
is set to 0, and will prefer depth-stitching over width-stitching if RAM usage
can be lowered.
}];
}

def SYCLIntelKernelArgsRestrictDocs : Documentation {
let Category = DocCatVariable;
let Heading = "kernel_args_restrict";
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4062,6 +4062,11 @@ void CodeGenModule::generateIntelFPGAAnnotation(
}
if (D->hasAttr<IntelFPGASimpleDualPortAttr>())
Out << "{simple_dual_port:1}";
if (const auto *FP2D = D->getAttr<IntelFPGAForcePow2DepthAttr>()) {
llvm::APSInt FP2DInt =
FP2D->getValue()->EvaluateKnownConstInt(getContext());
Out << '{' << FP2D->getSpelling() << ':' << FP2DInt << '}';
}
}

void CodeGenModule::addGlobalIntelFPGAAnnotation(const VarDecl *VD,
Expand Down
23 changes: 23 additions & 0 deletions clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5215,6 +5215,8 @@ static bool checkIntelFPGARegisterAttrCompatibility(Sema &S, Decl *D,
InCompat = true;
if (checkAttrMutualExclusion<IntelFPGABankBitsAttr>(S, D, Attr))
InCompat = true;
if (checkAttrMutualExclusion<IntelFPGAForcePow2DepthAttr>(S, D, Attr))
InCompat = true;

return InCompat;
}
Expand Down Expand Up @@ -5419,6 +5421,24 @@ static void handleIntelFPGAPrivateCopiesAttr(Sema &S, Decl *D,
D, Attr, Attr.getArgAsExpr(0));
}

static void handleIntelFPGAForcePow2DepthAttr(Sema &S, Decl *D,
const ParsedAttr &Attr) {
if (S.LangOpts.SYCLIsHost)
mlychkov marked this conversation as resolved.
Show resolved Hide resolved
return;

checkForDuplicateAttribute<IntelFPGAForcePow2DepthAttr>(S, D, Attr);

if (checkAttrMutualExclusion<IntelFPGARegisterAttr>(S, D, Attr))
return;

if (!D->hasAttr<IntelFPGAMemoryAttr>())
mlychkov marked this conversation as resolved.
Show resolved Hide resolved
D->addAttr(IntelFPGAMemoryAttr::CreateImplicit(
S.Context, IntelFPGAMemoryAttr::Default));

S.AddOneConstantValueAttr<IntelFPGAForcePow2DepthAttr>(D, Attr,
Attr.getArgAsExpr(0));
}

static void handleXRayLogArgsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
ParamIdx ArgCount;

Expand Down Expand Up @@ -8018,6 +8038,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_IntelFPGABankBits:
handleIntelFPGABankBitsAttr(S, D, AL);
break;
case ParsedAttr::AT_IntelFPGAForcePow2Depth:
handleIntelFPGAForcePow2DepthAttr(S, D, AL);
break;
case ParsedAttr::AT_SYCLIntelPipeIO:
handleSYCLIntelPipeIOAttr(S, D, AL);
break;
Expand Down
16 changes: 16 additions & 0 deletions clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,17 @@ static void instantiateIntelFPGABankBitsAttr(
S.AddIntelFPGABankBitsAttr(New, *Attr, Args.data(), Args.size());
}

static void instantiateIntelFPGAForcePow2DepthAttr(
Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
const IntelFPGAForcePow2DepthAttr *Attr, Decl *New) {
EnterExpressionEvaluationContext Unevaluated(
S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
ExprResult Result = S.SubstExpr(Attr->getValue(), TemplateArgs);
if (!Result.isInvalid())
S.AddOneConstantValueAttr<IntelFPGAForcePow2DepthAttr>(
New, *Attr, Result.getAs<Expr>());
}

static void instantiateSYCLIntelPipeIOAttr(
Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
const SYCLIntelPipeIOAttr *Attr, Decl *New) {
Expand Down Expand Up @@ -699,6 +710,11 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
instantiateIntelFPGABankBitsAttr(*this, TemplateArgs, IntelFPGABankBits,
New);
}
if (const auto *IntelFPGAForcePow2Depth =
dyn_cast<IntelFPGAForcePow2DepthAttr>(TmplAttr)) {
instantiateIntelFPGAForcePow2DepthAttr(*this, TemplateArgs,
IntelFPGAForcePow2Depth, New);
}
if (const auto *SYCLIntelPipeIO = dyn_cast<SYCLIntelPipeIOAttr>(TmplAttr)) {
instantiateSYCLIntelPipeIOAttr(*this, TemplateArgs, SYCLIntelPipeIO, New);
continue;
Expand Down
30 changes: 25 additions & 5 deletions clang/test/CodeGenSYCL/intel-fpga-local.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
// CHECK-DEVICE: [[ANN_numbanks_4:@.str]] = {{.*}}{memory:DEFAULT}{sizeinfo:4}{numbanks:4}
// CHECK-BOTH: @_ZZ15attrs_on_staticvE15static_annotate = internal{{.*}}constant i32 30, align 4
// CHECK-BOTH: [[ANN_annotate:@.str[.0-9]*]] = {{.*}}foobar
// CHECK-BOTH: @_ZZ15attrs_on_staticvE16static_force_p2d = internal{{.*}}constant i32 40, align 4
// CHECK-DEVICE: [[ANN_force_pow2_depth_0:@.str[.0-9]*]] = {{.*}}{memory:DEFAULT}{sizeinfo:4}{force_pow2_depth:0}
// CHECK-DEVICE: [[ANN_register:@.str.[0-9]*]] = {{.*}}{register:1}
// CHECK-DEVICE: [[ANN_memory_default:@.str.[0-9]*]] = {{.*}}{memory:DEFAULT}{sizeinfo:4}
// CHECK-DEVICE: [[ANN_mlab_sizeinfo_500:@.str.[0-9]*]] = {{.*}}{memory:MLAB}{sizeinfo:4,500}
Expand All @@ -22,22 +24,25 @@
// CHECK-DEVICE: [[ANN_bankbits_bankwidth:@.str.[0-9]*]] = {{.*}}{memory:DEFAULT}{sizeinfo:4,10,2}{bankwidth:16}{numbanks:2}{bank_bits:0}
// CHECK-DEVICE: [[ANN_memory_blockram:@.str.[0-9]*]] = {{.*}}{memory:BLOCK_RAM}{sizeinfo:4}
// CHECK-DEVICE: [[ANN_memory_mlab:@.str.[0-9]*]] = {{.*}}{memory:MLAB}{sizeinfo:4}
// CHECK-DEVICE: [[ANN_force_pow2_depth_1:@.str.[0-9]*]] = {{.*}}{memory:DEFAULT}{sizeinfo:4}{force_pow2_depth:1}
// CHECK-DEVICE: [[ANN_private_copies_4:@.str.[0-9]*]] = {{.*}}{memory:DEFAULT}{sizeinfo:4}{private_copies:4}
// CHECK-DEVICE: [[ANN_max_replicates_4:@.str.[0-9]*]] = {{.*}}{max_replicates:4}

// CHECK-BOTH: @llvm.global.annotations
// CHECK-DEVICE-SAME: { i8* addrspacecast (i8 addrspace(1)* bitcast (i32 addrspace(1)* @_ZZ15attrs_on_staticvE15static_numbanks to i8 addrspace(1)*) to i8*)
// CHECK-DEVICE-SAME: [[ANN_numbanks_4]]{{.*}} i32 39
// CHECK-DEVICE-SAME: [[ANN_numbanks_4]]{{.*}} i32 43
// CHECK-DEVICE-SAME: { i8* addrspacecast (i8 addrspace(1)* bitcast (i32 addrspace(1)* @_ZZ15attrs_on_staticvE15static_annotate to i8 addrspace(1)*) to i8*)
// CHECK-HOST-SAME: { i8* bitcast (i32* @_ZZ15attrs_on_staticvE15static_annotate to i8*)
// CHECK-BOTH-SAME: [[ANN_annotate]]{{.*}} i32 40

// CHECK-BOTH-SAME: [[ANN_annotate]]{{.*}} i32 44
// CHECK-DEVICE-SAME: { i8* addrspacecast (i8 addrspace(1)* bitcast (i32 addrspace(1)* @_ZZ15attrs_on_staticvE16static_force_p2d to i8 addrspace(1)*) to i8*)
// CHECK-DEVICE-SAME: [[ANN_force_pow2_depth_0]]{{.*}} i32 45
// CHECK-HOST-NOT: llvm.var.annotation
// CHECK-HOST-NOT: llvm.ptr.annotation

void attrs_on_static() {
const static int static_numbanks [[intelfpga::numbanks(4)]] = 20;
const static int static_annotate [[clang::annotate("foobar")]] = 30;
const static int static_force_p2d [[intelfpga::force_pow2_depth(0)]] = 40;
}

void attrs_on_var() {
Expand Down Expand Up @@ -105,6 +110,10 @@ void attrs_on_var() {
// CHECK-DEVICE: %[[VAR_BANK_BITS_WIDTH1:bank_bits_width[0-9]+]] = bitcast{{.*}}%bank_bits_width
// CHECK-DEVICE: @llvm.var.annotation{{.*}}%[[VAR_BANK_BITS_WIDTH1]],{{.*}}[[ANN_bankbits_bankwidth]]
[[intelfpga::bank_bits(0), intelfpga::bankwidth(16)]] int bank_bits_width[10][2];
// CHECK-DEVICE: %[[VAR_FP2D:[0-9]+]] = bitcast{{.*}}%force_p2d
// CHECK-DEVICE: %[[VAR_FP2D1:force_p2d[0-9]+]] = bitcast{{.*}}%force_p2d
// CHECK-DEVICE: llvm.var.annotation{{.*}}%[[VAR_FP2D1]],{{.*}}[[ANN_force_pow2_depth_0]]
int force_p2d [[intelfpga::force_pow2_depth(0)]];
}

void attrs_on_struct() {
Expand All @@ -123,6 +132,7 @@ void attrs_on_struct() {
int maxreplicates [[intelfpga::max_replicates(2)]];
int dualport [[intelfpga::simple_dual_port]];
int bankbits [[intelfpga::bank_bits(4, 5)]];
int force_p2d [[intelfpga::force_pow2_depth(1)]];
} s;

// CHECK-DEVICE: %[[FIELD_NUMBANKS:.*]] = getelementptr inbounds %struct.{{.*}}.attrs_on_struct{{.*}}
Expand Down Expand Up @@ -167,12 +177,15 @@ void attrs_on_struct() {
// CHECK-DEVICE: %[[FIELD_BANKBITS:.*]] = getelementptr inbounds %struct.{{.*}}.attrs_on_struct{{.*}}
// CHECK-DEVICE: call i32* @llvm.ptr.annotation.p0i32{{.*}}%[[FIELD_BANKBITS]]{{.*}}[[ANN_bankbits_4_5]]
s.bankbits = 0;
// CHECK-DEVICE: %[[FIELD_FP2D:.*]] = getelementptr inbounds %struct.{{.*}}.attrs_on_struct{{.*}}
// CHECK-DEVICE: call i32* @llvm.ptr.annotation.p0i32{{.*}}%[[FIELD_FP2D]]{{.*}}[[ANN_force_pow2_depth_1]]
s.force_p2d = 0;
}

// CHECK-HOST-NOT: llvm.var.annotation
// CHECK-HOST-NOT: llvm.ptr.annotation

template <int A, int B>
template <int A, int B, int C>
void attrs_with_template_param() {
// CHECK-DEVICE: %[[TEMPL_NUMBANKS:numbanks[0-9]+]] = bitcast{{.*}}%numbanks
// CHECK-DEVICE: @llvm.var.annotation{{.*}}%[[TEMPL_NUMBANKS]],{{.*}}[[ANN_numbanks_4]]
Expand All @@ -189,13 +202,17 @@ void attrs_with_template_param() {
// CHECK-DEVICE: %[[TEMPL_BANKBITS:bankbits[0-9]+]] = bitcast{{.*}}%bankbits
// CHECK-DEVICE: @llvm.var.annotation{{.*}}%[[TEMPL_BANKBITS]],{{.*}}[[ANN_bankbits_4_5]]
int bankbits [[intelfpga::bank_bits(A, B)]];
// CHECK-DEVICE: %[[TEMPL_FP2D:force_p2d[0-9]+]] = bitcast{{.*}}%force_p2d
// CHECK-DEVICE: @llvm.var.annotation{{.*}}%[[TEMPL_FP2D]]{{.*}}[[ANN_force_pow2_depth_1]]
int force_p2d [[intelfpga::force_pow2_depth(C)]];

struct templ_on_struct_fields {
int numbanks [[intelfpga::numbanks(A)]] ;
int bankwidth [[intelfpga::bankwidth(A)]];
int privatecopies [[intelfpga::private_copies(A)]];
int maxreplicates [[intelfpga::max_replicates(A)]];
int bankbits [[intelfpga::bank_bits(A, B)]];
int force_p2d [[intelfpga::force_pow2_depth(C)]];
} s;

// CHECK-DEVICE: %[[FIELD_NUMBANKS:.*]] = getelementptr inbounds %struct.{{.*}}.templ_on_struct_fields{{.*}}
Expand All @@ -213,6 +230,9 @@ void attrs_with_template_param() {
// CHECK-DEVICE: %[[FIELD_BANKBITS:.*]] = getelementptr inbounds %struct.{{.*}}.templ_on_struct_fields{{.*}}
// CHECK-DEVICE: call i32* @llvm.ptr.annotation.p0i32{{.*}}%[[FIELD_BANKBITS]]{{.*}}[[ANN_bankbits_4_5]]
s.bankbits = 0;
// CHECK-DEVICE: %[[FIELD_FP2D:.*]] = getelementptr inbounds %struct.{{.*}}.templ_on_struct_fields{{.*}}
// CHECK-DEVICE: call i32* @llvm.ptr.annotation.p0i32{{.*}}%[[FIELD_FP2D]]{{.*}}[[ANN_force_pow2_depth_1]]
s.force_p2d = 0;
}

void field_addrspace_cast() {
Expand Down Expand Up @@ -246,7 +266,7 @@ int main() {
attrs_on_var();
attrs_on_struct();
field_addrspace_cast();
attrs_with_template_param<4,5>();
attrs_with_template_param<4, 5, 1>();
});
return 0;
}
Loading