From 01fadfad464ccc097452d63d12984b38c1bcabef Mon Sep 17 00:00:00 2001 From: Soumi Manna Date: Mon, 6 Jun 2022 06:46:47 -0700 Subject: [PATCH 01/11] [SYCL][FPGA] Add support for new attribute for loop pipelining This patch adds support for new FPGA attribute called [[intel::fpga_pipeline(N)]] that takes a Boolean parameter. N can be a template parameter or constexpr. If the user didn't provide a parameter, the default value of N would be 1, which implies enable pipelining. This attribute can be applied to loops. Example syntax: // will disable loop pipelining [[intel::fpga_pipeline(0)]] for (int i = 0; i --- clang/include/clang/Basic/Attr.td | 23 +++ clang/include/clang/Basic/AttrDocs.td | 41 ++++++ clang/include/clang/Sema/Sema.h | 7 + clang/lib/CodeGen/CGLoopInfo.cpp | 23 ++- clang/lib/CodeGen/CGLoopInfo.h | 9 ++ clang/lib/Sema/SemaDeclAttr.cpp | 8 ++ clang/lib/Sema/SemaStmtAttr.cpp | 41 ++++++ clang/lib/Sema/SemaTemplateInstantiate.cpp | 9 ++ clang/test/CodeGenSYCL/intel-fpga-loops.cpp | 27 ++++ clang/test/SemaSYCL/intel-fpga-loops.cpp | 151 +++++++++++++++++--- 10 files changed, 322 insertions(+), 17 deletions(-) diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 5bcbb34b7b93e..6dabfe8dc8572 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -2308,6 +2308,23 @@ def : MutualExclusions<[SYCLIntelFPGAIVDep, def : MutualExclusions<[SYCLIntelFPGAMaxConcurrency, SYCLIntelFPGADisableLoopPipelining]>; +def SYCLIntelFpgaPipeline : InheritableAttr { + let Spellings = [CXX11<"intel","fpga_pipeline">]; + let Args = [ExprArgument<"Value", /*optional*/1>]; + let LangOpts = [SYCLIsDevice, SilentlyIgnoreSYCLIsHost]; + let Subjects = SubjectList<[ForStmt, CXXForRangeStmt, WhileStmt, DoStmt], + ErrorDiag, "'for', 'while', and 'do' statements">; + let Documentation = [SYCLIntelFpgaPipelineAttrDocs]; + let IsStmtDependent = 1; +} + +def : MutualExclusions<[SYCLIntelFPGAInitiationInterval, + SYCLIntelFpgaPipeline]>; +def : MutualExclusions<[SYCLIntelFPGAIVDep, + SYCLIntelFpgaPipeline]>; +def : MutualExclusions<[SYCLIntelFPGAMaxConcurrency, + SYCLIntelFpgaPipeline]>; + def SYCLIntelFPGALoopCount : StmtAttr { let Spellings = [CXX11<"intel", "loop_count_min">, CXX11<"intel", "loop_count_max">, @@ -2340,6 +2357,9 @@ def SYCLIntelFPGAMaxInterleaving : StmtAttr { def : MutualExclusions<[SYCLIntelFPGADisableLoopPipelining, SYCLIntelFPGAMaxInterleaving]>; +def : MutualExclusions<[SYCLIntelFpgaPipeline, + SYCLIntelFPGAMaxInterleaving]>; + def SYCLIntelFPGASpeculatedIterations : StmtAttr { let Spellings = [CXX11<"intel", "speculated_iterations">]; let Subjects = SubjectList<[ForStmt, CXXForRangeStmt, WhileStmt, DoStmt], @@ -2352,6 +2372,9 @@ def SYCLIntelFPGASpeculatedIterations : StmtAttr { def : MutualExclusions<[SYCLIntelFPGADisableLoopPipelining, SYCLIntelFPGASpeculatedIterations]>; +def : MutualExclusions<[SYCLIntelFpgaPipeline, + SYCLIntelFPGASpeculatedIterations]>; + def SYCLIntelFPGANofusion : StmtAttr { let Spellings = [CXX11<"intel","nofusion">]; let Subjects = SubjectList<[ForStmt, CXXForRangeStmt, WhileStmt, DoStmt], diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 019fc814496be..cf5128c086fac 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -3291,6 +3291,9 @@ function, or in conjunction with ``max_interleaving``, ``speculated_iterations``, ``max_concurrency``, ``initiation_interval``, or ``ivdep``. +The ``[[intel::disable_loop_pipelining]]`` attribute spelling is a deprecated +synonym for ``[[[intel::fpga_pipeline]]`` and will be removed in the future. + .. code-block:: c++ void foo() { @@ -3303,6 +3306,44 @@ or ``ivdep``. }]; } +def SYCLIntelFpgaPipelineAttrDocs : Documentation { + let Category = DocCatVariable; + let Heading = "intel::fpga_pipeline"; + let Content = [{ +The ``intel::fpga_pipeline(N)`` attribute applies to a loop and it allows users +to disable or enable pipelining iterations of a loop. The attribute optionally +accepts an integer constant expression that is converted to `bool`. A `true` +value enables pipelining while a `false` value disables pipelining. The +optional argument defaults to `true`. This attribute cannot be applied to a +loop in conjunction with the ``max_interleaving``, ``speculated_iterations``, +``max_concurrency``, ``initiation_interval``, or ``ivdep`` attributes. + +.. code-block:: c++ + + // Disable loop pipelining + void bar() { + int a[10]; + [[[intel::fpga_pipeline(0)]] for (int i = 0; i != 10; ++i) a[i] = 0; + } + + // Enable loop pipelining + void foo() { + int var = 0; + [[intel::fpga_pipeline(1)]] for (int i = 0; i < 10; ++i) var++; + } + + void count(int *array, size_t n) { + [[intel::fpga_pipeline(1)]] for (int i = 0; i < n; ++i) array[i] = 0; + } + + template + void func() { + [[intel::fpga_pipeline(A)]] for(;;) { } + } + + }]; +} + def SYCLIntelFPGALoopCountAttrDocs : Documentation { let Category = DocCatVariable; let Heading = "intel::loop_count_min, intel::loop_count_max, intel::loop_count_avg, intel::loop_count"; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 6ba624c6b7c2b..a2ac131a07084 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -2277,6 +2277,13 @@ class Sema final { SYCLIntelFPGALoopCoalesceAttr * BuildSYCLIntelFPGALoopCoalesceAttr(const AttributeCommonInfo &CI, Expr *E); + SYCLIntelFpgaPipelineAttr * + BuildSYCLIntelFPGAPipelineAttr(const AttributeCommonInfo &CI, Expr *E); + + bool checkPipelineAttrArgument(Expr *E, + const SYCLIntelFpgaPipelineAttr *TmpAttr, + ExprResult &Result); + bool CheckQualifiedFunctionForTypeId(QualType T, SourceLocation Loc); bool CheckFunctionReturnType(QualType T, SourceLocation Loc); diff --git a/clang/lib/CodeGen/CGLoopInfo.cpp b/clang/lib/CodeGen/CGLoopInfo.cpp index 714e0b2a0a51b..89d0c83644d54 100644 --- a/clang/lib/CodeGen/CGLoopInfo.cpp +++ b/clang/lib/CodeGen/CGLoopInfo.cpp @@ -611,6 +611,14 @@ MDNode *LoopInfo::createMetadata( llvm::Type::getInt32Ty(Ctx), VC.second))}; LoopProperties.push_back(MDNode::get(Ctx, Vals)); } + + for (auto &FP : Attrs.SYCLIntelFPGANPipelines) { + Metadata *Vals[] = {MDString::get(Ctx, FP.first), + ConstantAsMetadata::get(ConstantInt::get( + llvm::Type::getInt32Ty(Ctx), FP.second))}; + LoopProperties.push_back(MDNode::get(Ctx, Vals)); + } + LoopProperties.insert(LoopProperties.end(), AdditionalLoopProperties.begin(), AdditionalLoopProperties.end()); return createFullUnrollMetadata(Attrs, LoopProperties, HasUserTransforms); @@ -654,6 +662,7 @@ void LoopAttributes::clear() { PipelineDisabled = false; PipelineInitiationInterval = 0; SYCLNofusionEnable = false; + SYCLIntelFPGANPipelines.clear(); MustProgress = false; } @@ -687,7 +696,8 @@ LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs, Attrs.UnrollEnable == LoopAttributes::Unspecified && Attrs.UnrollAndJamEnable == LoopAttributes::Unspecified && Attrs.DistributeEnable == LoopAttributes::Unspecified && !StartLoc && - Attrs.SYCLNofusionEnable == false && !EndLoc && !Attrs.MustProgress) + Attrs.SYCLNofusionEnable == false && + Attrs.SYCLIntelFPGANPipelines.empty() && !EndLoc && !Attrs.MustProgress) return; TempLoopID = MDNode::getTemporary(Header->getContext(), None); @@ -1011,6 +1021,8 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx, // emitted // For attribute nofusion: // 'llvm.loop.fusion.disable' metadata will be emitted + // For attribute fpga_pipeline: + // n - 'llvm.loop.intel.pipelining.enable, i32 n' metadata will be emitted for (const auto *A : Attrs) { if (const auto *IntelFPGAIVDep = dyn_cast(A)) addSYCLIVDepInfo(Header->getContext(), IntelFPGAIVDep->getSafelenValue(), @@ -1075,6 +1087,15 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx, if (isa(A)) setSYCLNofusionEnable(); + + if (const auto *IntelFpgaPipeline = + dyn_cast(A)) { + const auto *CE = cast(IntelFpgaPipeline->getValue()); + Optional ArgVal = CE->getResultAsAPSInt(); + unsigned int Value = ArgVal->getBoolValue() ? 1 : 0; + const char *Var = "llvm.loop.intel.pipelining.enable"; + setSYCLIntelFPGANPipelines(Var, Value); + } } setMustProgress(MustProgress); diff --git a/clang/lib/CodeGen/CGLoopInfo.h b/clang/lib/CodeGen/CGLoopInfo.h index f48cfb248c3cb..14aa12a8544f3 100644 --- a/clang/lib/CodeGen/CGLoopInfo.h +++ b/clang/lib/CodeGen/CGLoopInfo.h @@ -152,6 +152,10 @@ struct LoopAttributes { /// Flag for llvm.loop.fusion.disable metatdata. bool SYCLNofusionEnable; + /// Value for fpga_pipeline variant and metadata. + llvm::SmallVector, 2> + SYCLIntelFPGANPipelines; + /// Value for whether the loop is required to make progress. bool MustProgress; }; @@ -407,6 +411,11 @@ class LoopInfoStack { /// Set flag of nofusion for the next loop pushed. void setSYCLNofusionEnable() { StagedAttrs.SYCLNofusionEnable = true; } + /// Set variant and value of fpga_pipeline for the next loop pushed. + void setSYCLIntelFPGANPipelines(const char *Var, unsigned int Value) { + StagedAttrs.SYCLIntelFPGANPipelines.push_back({Var, Value}); + } + /// Set no progress for the next loop pushed. void setMustProgress(bool P) { StagedAttrs.MustProgress = P; } diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 6340ab94aa3ea..1be01cf8f3906 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -364,6 +364,14 @@ void Sema::CheckDeprecatedSYCLAttributeSpelling(const ParsedAttr &A, Diag(A.getLoc(), diag::ext_sycl_2020_attr_spelling) << A; return; } + + // Deprecate [[intel::disable_loop_pipelining]] attribute spelling in favor + // of the SYCL FPGA attribute spelling [[intel::fpga_pipeline]]. + if (A.hasScope() && A.getScopeName()->isStr("intel") && + A.getAttrName()->isStr("disable_loop_pipelining")) { + DiagnoseDeprecatedAttribute(A, "intel", "fpga_pipeline"); + return; + } } /// Check if IdxExpr is a valid parameter index for a function or diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp index fc70b53b3c8e2..d62f5f3cd8257 100644 --- a/clang/lib/Sema/SemaStmtAttr.cpp +++ b/clang/lib/Sema/SemaStmtAttr.cpp @@ -219,6 +219,44 @@ static Attr *handleSYCLIntelFPGADisableLoopPipeliningAttr(Sema &S, Stmt *, return new (S.Context) SYCLIntelFPGADisableLoopPipeliningAttr(S.Context, A); } +// Handle [[intel:fpga_pipeline]] attribute. +bool Sema::checkPipelineAttrArgument(Expr *E, + const SYCLIntelFpgaPipelineAttr *TmpAttr, + ExprResult &Result) { + llvm::APSInt Value; + // Validate that we have an integer constant expression. + Result = VerifyIntegerConstantExpression(E, &Value); + if (Result.isInvalid()) + return true; + return false; +} + +static Attr *handleSYCLIntelFPGAPipelineAttr(Sema &S, Stmt *, + const ParsedAttr &A) { + // If no attribute argument is specified, set to default value '1'. + Expr *E = A.isArgExpr(0) + ? A.getArgAsExpr(0) + : IntegerLiteral::Create(S.Context, llvm::APInt(32, 1), + S.Context.IntTy, A.getLoc()); + + return S.BuildSYCLIntelFPGAPipelineAttr(A, E); +} + +SYCLIntelFpgaPipelineAttr * +Sema::BuildSYCLIntelFPGAPipelineAttr(const AttributeCommonInfo &A, Expr *E) { + SYCLIntelFpgaPipelineAttr TmpAttr(Context, A, E); + + if (!E->isValueDependent()) { + // Check if the expression is not value dependent. + ExprResult Res; + if (checkPipelineAttrArgument(E, &TmpAttr, Res)) + return nullptr; + E = Res.get(); + } + + return new (Context) SYCLIntelFpgaPipelineAttr(Context, A, E); +} + static bool checkSYCLIntelFPGAIVDepSafeLen(Sema &S, llvm::APSInt &Value, Expr *E) { if (!Value.isStrictlyPositive()) @@ -821,6 +859,7 @@ static void CheckForIncompatibleSYCLLoopAttributes( CheckForDuplicationSYCLLoopAttribute(S, Attrs, false); CheckRedundantSYCLIntelFPGAIVDepAttrs(S, Attrs); CheckForDuplicationSYCLLoopAttribute(S, Attrs); + CheckForDuplicationSYCLLoopAttribute(S, Attrs); } void CheckForIncompatibleUnrollHintAttributes( @@ -966,6 +1005,8 @@ static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const ParsedAttr &A, return handleUnlikely(S, St, A, Range); case ParsedAttr::AT_SYCLIntelFPGANofusion: return handleIntelFPGANofusionAttr(S, St, A); + case ParsedAttr::AT_SYCLIntelFpgaPipeline: + return handleSYCLIntelFPGAPipelineAttr(S, St, A); default: // N.B., ClangAttrEmitter.cpp emits a diagnostic helper that ensures a // declaration attribute is not written on a statement, but this code is diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 39da624efd3a4..fe19d9b43cb1d 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1110,6 +1110,8 @@ namespace { const SYCLIntelFPGASpeculatedIterationsAttr *SI); const SYCLIntelFPGALoopCountAttr * TransformSYCLIntelFPGALoopCountAttr(const SYCLIntelFPGALoopCountAttr *SI); + const SYCLIntelFpgaPipelineAttr * + TransformSYCLIntelFpgaPipelineAttr(const SYCLIntelFpgaPipelineAttr *SI); ExprResult TransformPredefinedExpr(PredefinedExpr *E); ExprResult TransformDeclRefExpr(DeclRefExpr *E); @@ -1601,6 +1603,13 @@ const LoopUnrollHintAttr *TemplateInstantiator::TransformLoopUnrollHintAttr( return getSema().BuildLoopUnrollHintAttr(*LU, TransformedExpr); } +const SYCLIntelFpgaPipelineAttr * +TemplateInstantiator::TransformSYCLIntelFpgaPipelineAttr( + const SYCLIntelFpgaPipelineAttr *PA) { + Expr *TransformedExpr = getDerived().TransformExpr(PA->getValue()).get(); + return getSema().BuildSYCLIntelFPGAPipelineAttr(*PA, TransformedExpr); +} + ExprResult TemplateInstantiator::transformNonTypeTemplateParmRef( NonTypeTemplateParmDecl *parm, SourceLocation loc, diff --git a/clang/test/CodeGenSYCL/intel-fpga-loops.cpp b/clang/test/CodeGenSYCL/intel-fpga-loops.cpp index 44306a2660011..22542ef3b5cf6 100644 --- a/clang/test/CodeGenSYCL/intel-fpga-loops.cpp +++ b/clang/test/CodeGenSYCL/intel-fpga-loops.cpp @@ -20,6 +20,10 @@ // CHECK: br label %for.cond2, !llvm.loop ![[MD_LCA_1:[0-9]+]] // CHECK: br label %for.cond13, !llvm.loop ![[MD_LCA_2:[0-9]+]] // CHECK: br label %for.cond24, !llvm.loop ![[MD_LCA_3:[0-9]+]] +// CHECK: br label %for.cond, !llvm.loop ![[MD_FP:[0-9]+]] +// CHECK: br label %for.cond2, !llvm.loop ![[MD_FP_1:[0-9]+]] +// CHECK: br label %for.cond13, !llvm.loop ![[MD_FP_2:[0-9]+]] +// CHECK: br label %for.cond24, !llvm.loop ![[MD_FP_3:[0-9]+]] void disable_loop_pipelining() { int a[10]; @@ -126,6 +130,7 @@ void speculated_iterations() { a[i] = 0; } +// Add CodeGen tests for FPGA loop attribute: [[intel::fpga_pipeline()]]. template void loop_count_control() { int a[10]; @@ -150,6 +155,27 @@ void loop_count_control() { a[i] = 0; } +template +void fpga_pipeline() { + int a[10]; + // CHECK: ![[MD_FP]] = distinct !{![[MD_FP]], ![[MP]], ![[MD_fpga_pipeline:[0-9]+]]} + // CHECK-NEXT: ![[MD_fpga_pipeline]] = !{!"llvm.loop.intel.pipelining.enable", i32 1} + [[intel::fpga_pipeline(A)]] for (int i = 0; i != 10; ++i) + a[i] = 0; + + // CHECK: ![[MD_FP_1]] = distinct !{![[MD_FP_1]], ![[MP]], ![[MD_fpga_pipeline]]} + [[intel::fpga_pipeline(1)]] for (int i = 0; i != 10; ++i) + a[i] = 0; + + // CHECK: ![[MD_FP_2]] = distinct !{![[MD_FP_2]], ![[MP]], ![[MD_fpga_pipeline]]} + [[intel::fpga_pipeline]] for (int i = 0; i != 10; ++i) + a[i] = 0; + + // CHECK: ![[MD_FP_3]] = distinct !{![[MD_FP_3]], ![[MP]], ![[MD_dlp]]} + [[intel::fpga_pipeline(0)]] for (int i = 0; i != 10; ++i) + a[i] = 0; +} + template __attribute__((sycl_kernel)) void kernel_single_task(const Func &kernelFunc) { kernelFunc(); @@ -165,6 +191,7 @@ int main() { max_interleaving<3, 0>(); speculated_iterations<4, 0>(); loop_count_control<12>(); + fpga_pipeline<1>(); }); return 0; } diff --git a/clang/test/SemaSYCL/intel-fpga-loops.cpp b/clang/test/SemaSYCL/intel-fpga-loops.cpp index 4d7c37d81b1a7..95cddbc8160d9 100644 --- a/clang/test/SemaSYCL/intel-fpga-loops.cpp +++ b/clang/test/SemaSYCL/intel-fpga-loops.cpp @@ -26,6 +26,8 @@ void foo() { [[intel::loop_count_avg(6)]] int l[10]; // expected-error@+1{{'loop_count' attribute cannot be applied to a declaration}} [[intel::loop_count(8)]] int m[10]; + // expected-error@+1{{'fpga_pipeline' attribute cannot be applied to a declaration}} + [[intel::fpga_pipeline(1)]] int n[10]; } // Test for deprecated spelling of Intel FPGA loop attributes @@ -122,13 +124,17 @@ void boo() { // expected-error@+1 {{'loop_count' attribute takes one argument}} [[intel::loop_count(6, 9)]] for (int i = 0; i != 10; ++i) a[i] = 0; + + // expected-error@+1 {{'fpga_pipeline' attribute takes no more than 1 argument}} + [[intel::fpga_pipeline(1, 2)]] for (int i = 0; i != 10; ++i) + a[i] = 0; } // Test for incorrect argument value for Intel FPGA loop attributes void goo() { int a[10]; - // no diagnostics are expected - [[intel::disable_loop_pipelining]] for (int i = 0; i != 10; ++i) + [[intel::disable_loop_pipelining]] for (int i = 0; i != 10; ++i) // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ + // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} a[i] = 0; // no diagnostics are expected [[intel::max_concurrency(0)]] for (int i = 0; i != 10; ++i) @@ -216,6 +222,19 @@ void goo() { // expected-error@+1 {{'loop_count' attribute requires a non-negative integral compile time constant expression}} [[intel::loop_count(-1)]] for (int i = 0; i != 10; ++i) a[i] = 0; + + // no diagnostics are expected + [[intel::fpga_pipeline]] for (int i = 0; i != 10; ++i) + a[i] = 0; + // no diagnostics are expected + [[intel::fpga_pipeline(0)]] for (int i = 0; i != 10; ++i) + a[i] = 0; + // no diagnostics are expected + [[intel::fpga_pipeline(-1)]] for (int i = 0; i != 10; ++i) + a[i] = 0; + // expected-error@+1 {{integral constant expression must have integral or unscoped enumeration type, not 'const char[4]'}} + [[intel::fpga_pipeline("abc")]] for (int i = 0; i != 10; ++i) + a[i] = 0; } // Test for Intel FPGA loop attributes duplication @@ -253,9 +272,11 @@ void zoo() { [[intel::max_concurrency(2)]] [[intel::initiation_interval(2)]] for (int i = 0; i != 10; ++i) a[i] = 0; - [[intel::disable_loop_pipelining]] + [[intel::disable_loop_pipelining]] // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ + // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} // expected-error@+1 {{duplicate Intel FPGA loop attribute 'disable_loop_pipelining'}} - [[intel::disable_loop_pipelining]] for (int i = 0; i != 10; ++i) + [[intel::disable_loop_pipelining]] for (int i = 0; i != 10; ++i) // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ + // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} a[i] = 0; [[intel::loop_coalesce(2)]] // expected-error@+2 {{duplicate Intel FPGA loop attribute 'loop_coalesce'}} @@ -334,46 +355,79 @@ void zoo() { // expected-error@+1{{duplicate Intel FPGA loop attribute 'loop_count'}} [[intel::loop_count(2)]] for (int i = 0; i != 10; ++i) a[i] = 0; + + [[intel::fpga_pipeline(1)]] + // expected-error@+1{{duplicate Intel FPGA loop attribute 'fpga_pipeline'}} + [[intel::fpga_pipeline(1)]] for (int i = 0; i != 10; ++i) + a[i] = 0; } // Test for Intel FPGA loop attributes compatibility void loop_attrs_compatibility() { int a[10]; - // no diagnostics are expected - [[intel::disable_loop_pipelining]] + [[intel::disable_loop_pipelining]] // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ + // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} [[intel::loop_coalesce]] for (int i = 0; i != 10; ++i) a[i] = 0; - // expected-error@+3 {{'max_interleaving' and 'disable_loop_pipelining' attributes are not compatible}} + // expected-error@+4 {{'max_interleaving' and 'disable_loop_pipelining' attributes are not compatible}} // expected-note@+1 {{conflicting attribute is here}} - [[intel::disable_loop_pipelining]] + [[intel::disable_loop_pipelining]] // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ + // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} [[intel::max_interleaving(0)]] for (int i = 0; i != 10; ++i) a[i] = 0; // expected-error@+3 {{'disable_loop_pipelining' and 'speculated_iterations' attributes are not compatible}} // expected-note@+1 {{conflicting attribute is here}} [[intel::speculated_iterations(0)]] - [[intel::disable_loop_pipelining]] for (int i = 0; i != 10; ++i) + [[intel::disable_loop_pipelining]] for (int i = 0; i != 10; ++i) // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ + // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} a[i] = 0; - // expected-error@+3 {{'max_concurrency' and 'disable_loop_pipelining' attributes are not compatible}} + // expected-error@+4 {{'max_concurrency' and 'disable_loop_pipelining' attributes are not compatible}} // expected-note@+1 {{conflicting attribute is here}} - [[intel::disable_loop_pipelining]] + [[intel::disable_loop_pipelining]] // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ + // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} [[intel::max_concurrency(0)]] for (int i = 0; i != 10; ++i) a[i] = 0; // expected-error@+3 {{'disable_loop_pipelining' and 'initiation_interval' attributes are not compatible}} // expected-note@+1 {{conflicting attribute is here}} [[intel::initiation_interval(10)]] - [[intel::disable_loop_pipelining]] for (int i = 0; i != 10; ++i) + [[intel::disable_loop_pipelining]] for (int i = 0; i != 10; ++i) // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ + // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} a[i] = 0; - // expected-error@+3 {{'ivdep' and 'disable_loop_pipelining' attributes are not compatible}} + // expected-error@+4 {{'ivdep' and 'disable_loop_pipelining' attributes are not compatible}} // expected-note@+1 {{conflicting attribute is here}} - [[intel::disable_loop_pipelining]] + [[intel::disable_loop_pipelining]] // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ + // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} [[intel::ivdep]] for (int i = 0; i != 10; ++i) a[i] = 0; + + [[intel::disable_loop_pipelining]] // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ + // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} + [[intel::nofusion]] for (int i = 0; i != 10; ++i) + a[i] = 0; + + [[intel::disable_loop_pipelining]] // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ + // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} + [[intel::loop_count_avg(8)]] + for (int i = 0; i != 10; ++i) + a[i] = 0; + [[intel::loop_count_min(8)]] + for (int i = 0; i != 10; ++i) + a[i] = 0; + [[intel::loop_count_max(8)]] + for (int i = 0; i != 10; ++i) + a[i] = 0; + // no diagnostics are expected - [[intel::disable_loop_pipelining]] + [[intel::fpga_pipeline]] + [[intel::loop_coalesce]] for (int i = 0; i != 10; ++i) + a[i] = 0; + + // no diagnostics are expected + [[intel::fpga_pipeline]] [[intel::nofusion]] for (int i = 0; i != 10; ++i) a[i] = 0; // no diagnostics are expected - [[intel::disable_loop_pipelining]] + [[intel::fpga_pipeline]] [[intel::loop_count_avg(8)]] for (int i = 0; i != 10; ++i) a[i] = 0; @@ -385,6 +439,36 @@ void loop_attrs_compatibility() { a[i] = 0; [[intel::loop_count(8)]] for (int i = 0; i != 10; ++i) a[i] = 0; + + // expected-error@+3 {{'fpga_pipeline' and 'max_concurrency' attributes are not compatible}} + // expected-note@+1 {{conflicting attribute is here}} + [[intel::max_concurrency(2)]] + [[intel::fpga_pipeline(1)]] for (int i = 0; i != 10; ++i) + a[i] = 0; + + // expected-error@+3 {{'fpga_pipeline' and 'initiation_interval' attributes are not compatible}} + // expected-note@+1 {{conflicting attribute is here}} + [[intel::initiation_interval(2)]] + [[intel::fpga_pipeline(1)]] for (int i = 0; i != 10; ++i) + a[i] = 0; + + // expected-error@+3 {{'fpga_pipeline' and 'max_interleaving' attributes are not compatible}} + // expected-note@+1 {{conflicting attribute is here}} + [[intel::max_interleaving(2)]] + [[intel::fpga_pipeline]] for (int i = 0; i != 10; ++i) + a[i] = 0; + + // expected-error@+3 {{'fpga_pipeline' and 'speculated_iterations' attributes are not compatible}} + // expected-note@+1 {{conflicting attribute is here}} + [[intel::speculated_iterations(0)]] + [[intel::fpga_pipeline]] for (int i = 0; i != 10; ++i) + a[i] = 0; + + // expected-error@+3 {{'fpga_pipeline' and 'ivdep' attributes are not compatible}} + // expected-note@+1 {{conflicting attribute is here}} + [[intel::ivdep]] + [[intel::fpga_pipeline]] for (int i = 0; i != 10; ++i) + a[i] = 0; } template @@ -544,6 +628,18 @@ void loop_count_control_dependent() { a[i] = 0; } +template +void fpga_pipeline_dependent() { + int a[10]; + [[intel::fpga_pipeline(C)]] for (int i = 0; i != 10; ++i) + a[i] = 0; + + // expected-error@+2 {{duplicate Intel FPGA loop attribute 'fpga_pipeline'}} + [[intel::fpga_pipeline(A)]] + [[intel::fpga_pipeline(B)]] for (int i = 0; i != 10; ++i) + a[i] = 0; +} + void check_max_concurrency_expression() { int a[10]; // Test that checks expression is not a constant expression. @@ -640,6 +736,22 @@ void check_loop_count_expression() { a[i] = 0; } +void check_loop_fpga_pipeline_expression() { + int a[10]; + + // Test that checks expression is not a constant expression. + int foo; // expected-note {{declared here}} + // expected-error@+2{{expression is not an integral constant expression}} + // expected-note@+1{{read of non-const variable 'foo' is not allowed in a constant expression}} + [[intel::fpga_pipeline(foo + 1)]] for (int i = 0; i != 10; ++i) + a[i] = 0; + + // Test that checks expression is a constant expression. + constexpr int bar = 0; + [[intel::fpga_pipeline(bar + 1)]] for (int i = 0; i != 10; ++i) // OK + a[i] = 0; +} + // Test that checks wrong template instantiation and ensures that the type // is checked properly when instantiating from the template definition. struct S {}; @@ -681,6 +793,11 @@ void check_loop_attr_template_instantiation() { // expected-error@+1 {{integral constant expression must have integral or unscoped enumeration type, not 'float'}} [[intel::loop_count(Ty{})]] for (int i = 0; i != 10; ++i) a[i] = 0; + + // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'S'}} + // expected-error@+1 {{integral constant expression must have integral or unscoped enumeration type, not 'float'}} + [[intel::fpga_pipeline(Ty{})]] for (int i = 0; i != 10; ++i) + a[i] = 0; } int main() { @@ -703,12 +820,14 @@ int main() { speculated_iterations_dependent<1, 8, -3, 0>(); // expected-note{{in instantiation of function template specialization 'speculated_iterations_dependent<1, 8, -3, 0>' requested here}} loop_coalesce_dependent<-1, 4, 0>(); // expected-note{{in instantiation of function template specialization 'loop_coalesce_dependent<-1, 4, 0>' requested here}} loop_count_control_dependent<3, 2, -1>(); // expected-note{{in instantiation of function template specialization 'loop_count_control_dependent<3, 2, -1>' requested here}} + fpga_pipeline_dependent<1, 1, 0>(); check_max_concurrency_expression(); check_max_interleaving_expression(); check_speculated_iterations_expression(); check_loop_coalesce_expression(); check_initiation_interval_expression(); check_loop_count_expression(); + check_loop_fpga_pipeline_expression(); check_loop_attr_template_instantiation(); //expected-note{{in instantiation of function template specialization 'check_loop_attr_template_instantiation' requested here}} check_loop_attr_template_instantiation(); //expected-note{{in instantiation of function template specialization 'check_loop_attr_template_instantiation' requested here}} }); From cc8d0efb35f74f47382e11ad875dc1ecaa33cb13 Mon Sep 17 00:00:00 2001 From: Soumi Manna Date: Mon, 6 Jun 2022 07:27:59 -0700 Subject: [PATCH 02/11] Fix clang format errors Signed-off-by: Soumi Manna --- clang/test/CodeGenSYCL/intel-fpga-loops.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/clang/test/CodeGenSYCL/intel-fpga-loops.cpp b/clang/test/CodeGenSYCL/intel-fpga-loops.cpp index 22542ef3b5cf6..2e31dd2af2a83 100644 --- a/clang/test/CodeGenSYCL/intel-fpga-loops.cpp +++ b/clang/test/CodeGenSYCL/intel-fpga-loops.cpp @@ -161,19 +161,19 @@ void fpga_pipeline() { // CHECK: ![[MD_FP]] = distinct !{![[MD_FP]], ![[MP]], ![[MD_fpga_pipeline:[0-9]+]]} // CHECK-NEXT: ![[MD_fpga_pipeline]] = !{!"llvm.loop.intel.pipelining.enable", i32 1} [[intel::fpga_pipeline(A)]] for (int i = 0; i != 10; ++i) - a[i] = 0; + a[i] = 0; // CHECK: ![[MD_FP_1]] = distinct !{![[MD_FP_1]], ![[MP]], ![[MD_fpga_pipeline]]} [[intel::fpga_pipeline(1)]] for (int i = 0; i != 10; ++i) - a[i] = 0; + a[i] = 0; // CHECK: ![[MD_FP_2]] = distinct !{![[MD_FP_2]], ![[MP]], ![[MD_fpga_pipeline]]} [[intel::fpga_pipeline]] for (int i = 0; i != 10; ++i) - a[i] = 0; + a[i] = 0; // CHECK: ![[MD_FP_3]] = distinct !{![[MD_FP_3]], ![[MP]], ![[MD_dlp]]} [[intel::fpga_pipeline(0)]] for (int i = 0; i != 10; ++i) - a[i] = 0; + a[i] = 0; } template From 7a04b165c5c29f28385a6473e24fbdec933dbf59 Mon Sep 17 00:00:00 2001 From: Soumi Manna Date: Mon, 6 Jun 2022 07:47:00 -0700 Subject: [PATCH 03/11] fix clang formt errors Signed-off-by: Soumi Manna --- clang/test/SemaSYCL/intel-fpga-loops.cpp | 110 ++++++++++------------- 1 file changed, 48 insertions(+), 62 deletions(-) diff --git a/clang/test/SemaSYCL/intel-fpga-loops.cpp b/clang/test/SemaSYCL/intel-fpga-loops.cpp index 95cddbc8160d9..f3476d1ca7c7c 100644 --- a/clang/test/SemaSYCL/intel-fpga-loops.cpp +++ b/clang/test/SemaSYCL/intel-fpga-loops.cpp @@ -127,7 +127,7 @@ void boo() { // expected-error@+1 {{'fpga_pipeline' attribute takes no more than 1 argument}} [[intel::fpga_pipeline(1, 2)]] for (int i = 0; i != 10; ++i) - a[i] = 0; + a[i] = 0; } // Test for incorrect argument value for Intel FPGA loop attributes @@ -135,7 +135,7 @@ void goo() { int a[10]; [[intel::disable_loop_pipelining]] for (int i = 0; i != 10; ++i) // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} - a[i] = 0; + a[i] = 0; // no diagnostics are expected [[intel::max_concurrency(0)]] for (int i = 0; i != 10; ++i) a[i] = 0; @@ -224,17 +224,17 @@ void goo() { a[i] = 0; // no diagnostics are expected - [[intel::fpga_pipeline]] for (int i = 0; i != 10; ++i) - a[i] = 0; + [[intel::fpga_pipeline]] for (int i = 0; i != 10; ++i) + a[i] = 0; // no diagnostics are expected [[intel::fpga_pipeline(0)]] for (int i = 0; i != 10; ++i) - a[i] = 0; + a[i] = 0; // no diagnostics are expected [[intel::fpga_pipeline(-1)]] for (int i = 0; i != 10; ++i) - a[i] = 0; + a[i] = 0; // expected-error@+1 {{integral constant expression must have integral or unscoped enumeration type, not 'const char[4]'}} [[intel::fpga_pipeline("abc")]] for (int i = 0; i != 10; ++i) - a[i] = 0; + a[i] = 0; } // Test for Intel FPGA loop attributes duplication @@ -277,7 +277,7 @@ void zoo() { // expected-error@+1 {{duplicate Intel FPGA loop attribute 'disable_loop_pipelining'}} [[intel::disable_loop_pipelining]] for (int i = 0; i != 10; ++i) // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} - a[i] = 0; + a[i] = 0; [[intel::loop_coalesce(2)]] // expected-error@+2 {{duplicate Intel FPGA loop attribute 'loop_coalesce'}} [[intel::max_interleaving(1)]] @@ -359,7 +359,7 @@ void zoo() { [[intel::fpga_pipeline(1)]] // expected-error@+1{{duplicate Intel FPGA loop attribute 'fpga_pipeline'}} [[intel::fpga_pipeline(1)]] for (int i = 0; i != 10; ++i) - a[i] = 0; + a[i] = 0; } // Test for Intel FPGA loop attributes compatibility @@ -368,69 +368,61 @@ void loop_attrs_compatibility() { [[intel::disable_loop_pipelining]] // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} [[intel::loop_coalesce]] for (int i = 0; i != 10; ++i) - a[i] = 0; + a[i] = 0; // expected-error@+4 {{'max_interleaving' and 'disable_loop_pipelining' attributes are not compatible}} // expected-note@+1 {{conflicting attribute is here}} [[intel::disable_loop_pipelining]] // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} [[intel::max_interleaving(0)]] for (int i = 0; i != 10; ++i) - a[i] = 0; + a[i] = 0; // expected-error@+3 {{'disable_loop_pipelining' and 'speculated_iterations' attributes are not compatible}} // expected-note@+1 {{conflicting attribute is here}} - [[intel::speculated_iterations(0)]] - [[intel::disable_loop_pipelining]] for (int i = 0; i != 10; ++i) // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ - // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} - a[i] = 0; + [[intel::speculated_iterations(0)]] [[intel::disable_loop_pipelining]] for (int i = 0; i != 10; ++i) // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ + // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} + a[i] = 0; // expected-error@+4 {{'max_concurrency' and 'disable_loop_pipelining' attributes are not compatible}} // expected-note@+1 {{conflicting attribute is here}} [[intel::disable_loop_pipelining]] // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} [[intel::max_concurrency(0)]] for (int i = 0; i != 10; ++i) - a[i] = 0; + a[i] = 0; // expected-error@+3 {{'disable_loop_pipelining' and 'initiation_interval' attributes are not compatible}} // expected-note@+1 {{conflicting attribute is here}} - [[intel::initiation_interval(10)]] - [[intel::disable_loop_pipelining]] for (int i = 0; i != 10; ++i) // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ - // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} - a[i] = 0; + [[intel::initiation_interval(10)]] [[intel::disable_loop_pipelining]] for (int i = 0; i != 10; ++i) // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ + // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} + a[i] = 0; // expected-error@+4 {{'ivdep' and 'disable_loop_pipelining' attributes are not compatible}} // expected-note@+1 {{conflicting attribute is here}} [[intel::disable_loop_pipelining]] // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} [[intel::ivdep]] for (int i = 0; i != 10; ++i) - a[i] = 0; + a[i] = 0; [[intel::disable_loop_pipelining]] // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} [[intel::nofusion]] for (int i = 0; i != 10; ++i) - a[i] = 0; + a[i] = 0; [[intel::disable_loop_pipelining]] // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} - [[intel::loop_count_avg(8)]] - for (int i = 0; i != 10; ++i) - a[i] = 0; - [[intel::loop_count_min(8)]] - for (int i = 0; i != 10; ++i) - a[i] = 0; - [[intel::loop_count_max(8)]] - for (int i = 0; i != 10; ++i) - a[i] = 0; + [[intel::loop_count_avg(8)]] for (int i = 0; i != 10; ++i) + a[i] = 0; + [[intel::loop_count_min(8)]] for (int i = 0; i != 10; ++i) + a[i] = 0; + [[intel::loop_count_max(8)]] for (int i = 0; i != 10; ++i) + a[i] = 0; // no diagnostics are expected - [[intel::fpga_pipeline]] - [[intel::loop_coalesce]] for (int i = 0; i != 10; ++i) - a[i] = 0; + [[intel::fpga_pipeline]] [[intel::loop_coalesce]] for (int i = 0; i != 10; ++i) + a[i] = 0; // no diagnostics are expected - [[intel::fpga_pipeline]] - [[intel::nofusion]] for (int i = 0; i != 10; ++i) - a[i] = 0; + [[intel::fpga_pipeline]] [[intel::nofusion]] for (int i = 0; i != 10; ++i) + a[i] = 0; // no diagnostics are expected - [[intel::fpga_pipeline]] - [[intel::loop_count_avg(8)]] + [[intel::fpga_pipeline]] [[intel::loop_count_avg(8)]] for (int i = 0; i != 10; ++i) - a[i] = 0; + a[i] = 0; [[intel::loop_count_min(8)]] for (int i = 0; i != 10; ++i) a[i] = 0; @@ -442,33 +434,28 @@ void loop_attrs_compatibility() { // expected-error@+3 {{'fpga_pipeline' and 'max_concurrency' attributes are not compatible}} // expected-note@+1 {{conflicting attribute is here}} - [[intel::max_concurrency(2)]] - [[intel::fpga_pipeline(1)]] for (int i = 0; i != 10; ++i) - a[i] = 0; + [[intel::max_concurrency(2)]] [[intel::fpga_pipeline(1)]] for (int i = 0; i != 10; ++i) + a[i] = 0; // expected-error@+3 {{'fpga_pipeline' and 'initiation_interval' attributes are not compatible}} // expected-note@+1 {{conflicting attribute is here}} - [[intel::initiation_interval(2)]] - [[intel::fpga_pipeline(1)]] for (int i = 0; i != 10; ++i) - a[i] = 0; + [[intel::initiation_interval(2)]] [[intel::fpga_pipeline(1)]] for (int i = 0; i != 10; ++i) + a[i] = 0; // expected-error@+3 {{'fpga_pipeline' and 'max_interleaving' attributes are not compatible}} // expected-note@+1 {{conflicting attribute is here}} - [[intel::max_interleaving(2)]] - [[intel::fpga_pipeline]] for (int i = 0; i != 10; ++i) - a[i] = 0; + [[intel::max_interleaving(2)]] [[intel::fpga_pipeline]] for (int i = 0; i != 10; ++i) + a[i] = 0; // expected-error@+3 {{'fpga_pipeline' and 'speculated_iterations' attributes are not compatible}} // expected-note@+1 {{conflicting attribute is here}} - [[intel::speculated_iterations(0)]] - [[intel::fpga_pipeline]] for (int i = 0; i != 10; ++i) - a[i] = 0; + [[intel::speculated_iterations(0)]] [[intel::fpga_pipeline]] for (int i = 0; i != 10; ++i) + a[i] = 0; // expected-error@+3 {{'fpga_pipeline' and 'ivdep' attributes are not compatible}} // expected-note@+1 {{conflicting attribute is here}} - [[intel::ivdep]] - [[intel::fpga_pipeline]] for (int i = 0; i != 10; ++i) - a[i] = 0; + [[intel::ivdep]] [[intel::fpga_pipeline]] for (int i = 0; i != 10; ++i) + a[i] = 0; } template @@ -632,12 +619,11 @@ template void fpga_pipeline_dependent() { int a[10]; [[intel::fpga_pipeline(C)]] for (int i = 0; i != 10; ++i) - a[i] = 0; + a[i] = 0; // expected-error@+2 {{duplicate Intel FPGA loop attribute 'fpga_pipeline'}} - [[intel::fpga_pipeline(A)]] - [[intel::fpga_pipeline(B)]] for (int i = 0; i != 10; ++i) - a[i] = 0; + [[intel::fpga_pipeline(A)]] [[intel::fpga_pipeline(B)]] for (int i = 0; i != 10; ++i) + a[i] = 0; } void check_max_concurrency_expression() { @@ -744,12 +730,12 @@ void check_loop_fpga_pipeline_expression() { // expected-error@+2{{expression is not an integral constant expression}} // expected-note@+1{{read of non-const variable 'foo' is not allowed in a constant expression}} [[intel::fpga_pipeline(foo + 1)]] for (int i = 0; i != 10; ++i) - a[i] = 0; + a[i] = 0; // Test that checks expression is a constant expression. constexpr int bar = 0; [[intel::fpga_pipeline(bar + 1)]] for (int i = 0; i != 10; ++i) // OK - a[i] = 0; + a[i] = 0; } // Test that checks wrong template instantiation and ensures that the type @@ -797,7 +783,7 @@ void check_loop_attr_template_instantiation() { // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'S'}} // expected-error@+1 {{integral constant expression must have integral or unscoped enumeration type, not 'float'}} [[intel::fpga_pipeline(Ty{})]] for (int i = 0; i != 10; ++i) - a[i] = 0; + a[i] = 0; } int main() { From 32fbbcf8dcc43849cbf014f979d2aa73c8c46664 Mon Sep 17 00:00:00 2001 From: Soumi Manna Date: Mon, 6 Jun 2022 07:50:34 -0700 Subject: [PATCH 04/11] fix clang formt errors Signed-off-by: Soumi Manna --- clang/test/SemaSYCL/intel-fpga-loops.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/clang/test/SemaSYCL/intel-fpga-loops.cpp b/clang/test/SemaSYCL/intel-fpga-loops.cpp index f3476d1ca7c7c..03d11d935b33e 100644 --- a/clang/test/SemaSYCL/intel-fpga-loops.cpp +++ b/clang/test/SemaSYCL/intel-fpga-loops.cpp @@ -420,9 +420,8 @@ void loop_attrs_compatibility() { [[intel::fpga_pipeline]] [[intel::nofusion]] for (int i = 0; i != 10; ++i) a[i] = 0; // no diagnostics are expected - [[intel::fpga_pipeline]] [[intel::loop_count_avg(8)]] - for (int i = 0; i != 10; ++i) - a[i] = 0; + [[intel::fpga_pipeline]] [[intel::loop_count_avg(8)]] for (int i = 0; i != 10; ++i) + a[i] = 0; [[intel::loop_count_min(8)]] for (int i = 0; i != 10; ++i) a[i] = 0; From 87d0e530cec3a2e66e7a1e68db01b1b6cbb0e3b1 Mon Sep 17 00:00:00 2001 From: Soumi Manna Date: Mon, 6 Jun 2022 08:03:31 -0700 Subject: [PATCH 05/11] Fix Lit tests failures Signed-off-by: Soumi Manna --- clang/test/SemaSYCL/intel-fpga-loops.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/clang/test/SemaSYCL/intel-fpga-loops.cpp b/clang/test/SemaSYCL/intel-fpga-loops.cpp index 03d11d935b33e..f98a1914570f2 100644 --- a/clang/test/SemaSYCL/intel-fpga-loops.cpp +++ b/clang/test/SemaSYCL/intel-fpga-loops.cpp @@ -375,7 +375,7 @@ void loop_attrs_compatibility() { // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} [[intel::max_interleaving(0)]] for (int i = 0; i != 10; ++i) a[i] = 0; - // expected-error@+3 {{'disable_loop_pipelining' and 'speculated_iterations' attributes are not compatible}} + // expected-error@+2 {{'disable_loop_pipelining' and 'speculated_iterations' attributes are not compatible}} // expected-note@+1 {{conflicting attribute is here}} [[intel::speculated_iterations(0)]] [[intel::disable_loop_pipelining]] for (int i = 0; i != 10; ++i) // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} @@ -386,7 +386,7 @@ void loop_attrs_compatibility() { // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} [[intel::max_concurrency(0)]] for (int i = 0; i != 10; ++i) a[i] = 0; - // expected-error@+3 {{'disable_loop_pipelining' and 'initiation_interval' attributes are not compatible}} + // expected-error@+2 {{'disable_loop_pipelining' and 'initiation_interval' attributes are not compatible}} // expected-note@+1 {{conflicting attribute is here}} [[intel::initiation_interval(10)]] [[intel::disable_loop_pipelining]] for (int i = 0; i != 10; ++i) // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} @@ -431,27 +431,27 @@ void loop_attrs_compatibility() { [[intel::loop_count(8)]] for (int i = 0; i != 10; ++i) a[i] = 0; - // expected-error@+3 {{'fpga_pipeline' and 'max_concurrency' attributes are not compatible}} + // expected-error@+2 {{'fpga_pipeline' and 'max_concurrency' attributes are not compatible}} // expected-note@+1 {{conflicting attribute is here}} [[intel::max_concurrency(2)]] [[intel::fpga_pipeline(1)]] for (int i = 0; i != 10; ++i) a[i] = 0; - // expected-error@+3 {{'fpga_pipeline' and 'initiation_interval' attributes are not compatible}} + // expected-error@+2 {{'fpga_pipeline' and 'initiation_interval' attributes are not compatible}} // expected-note@+1 {{conflicting attribute is here}} [[intel::initiation_interval(2)]] [[intel::fpga_pipeline(1)]] for (int i = 0; i != 10; ++i) a[i] = 0; - // expected-error@+3 {{'fpga_pipeline' and 'max_interleaving' attributes are not compatible}} + // expected-error@+2 {{'fpga_pipeline' and 'max_interleaving' attributes are not compatible}} // expected-note@+1 {{conflicting attribute is here}} [[intel::max_interleaving(2)]] [[intel::fpga_pipeline]] for (int i = 0; i != 10; ++i) a[i] = 0; - // expected-error@+3 {{'fpga_pipeline' and 'speculated_iterations' attributes are not compatible}} + // expected-error@+2 {{'fpga_pipeline' and 'speculated_iterations' attributes are not compatible}} // expected-note@+1 {{conflicting attribute is here}} [[intel::speculated_iterations(0)]] [[intel::fpga_pipeline]] for (int i = 0; i != 10; ++i) a[i] = 0; - // expected-error@+3 {{'fpga_pipeline' and 'ivdep' attributes are not compatible}} + // expected-error@+2 {{'fpga_pipeline' and 'ivdep' attributes are not compatible}} // expected-note@+1 {{conflicting attribute is here}} [[intel::ivdep]] [[intel::fpga_pipeline]] for (int i = 0; i != 10; ++i) a[i] = 0; @@ -620,7 +620,7 @@ void fpga_pipeline_dependent() { [[intel::fpga_pipeline(C)]] for (int i = 0; i != 10; ++i) a[i] = 0; - // expected-error@+2 {{duplicate Intel FPGA loop attribute 'fpga_pipeline'}} + // expected-error@+1 {{duplicate Intel FPGA loop attribute 'fpga_pipeline'}} [[intel::fpga_pipeline(A)]] [[intel::fpga_pipeline(B)]] for (int i = 0; i != 10; ++i) a[i] = 0; } From 03aaebe7e8d97e709d00eb02a84b684d11e3d8f9 Mon Sep 17 00:00:00 2001 From: Soumi Manna Date: Tue, 7 Jun 2022 16:36:52 -0700 Subject: [PATCH 06/11] address review comments Signed-off-by: Soumi Manna --- clang/include/clang/Basic/Attr.td | 14 ++-- clang/include/clang/Basic/AttrDocs.td | 21 +++++- clang/include/clang/Sema/Sema.h | 6 +- clang/lib/CodeGen/CGLoopInfo.cpp | 14 ++-- clang/lib/CodeGen/CGLoopInfo.h | 6 +- clang/lib/Sema/SemaStmtAttr.cpp | 25 ++----- clang/lib/Sema/SemaTemplateInstantiate.cpp | 10 +-- clang/test/CodeGenSYCL/intel-fpga-loops.cpp | 21 ++++++ .../test/SemaSYCL/intel-fpga-pipeline-ast.cpp | 72 +++++++++++++++++++ 9 files changed, 141 insertions(+), 48 deletions(-) create mode 100644 clang/test/SemaSYCL/intel-fpga-pipeline-ast.cpp diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 6dabfe8dc8572..8b5e8314b884c 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -2308,22 +2308,22 @@ def : MutualExclusions<[SYCLIntelFPGAIVDep, def : MutualExclusions<[SYCLIntelFPGAMaxConcurrency, SYCLIntelFPGADisableLoopPipelining]>; -def SYCLIntelFpgaPipeline : InheritableAttr { +def SYCLIntelFPGAPipeline : InheritableAttr { let Spellings = [CXX11<"intel","fpga_pipeline">]; let Args = [ExprArgument<"Value", /*optional*/1>]; let LangOpts = [SYCLIsDevice, SilentlyIgnoreSYCLIsHost]; let Subjects = SubjectList<[ForStmt, CXXForRangeStmt, WhileStmt, DoStmt], ErrorDiag, "'for', 'while', and 'do' statements">; - let Documentation = [SYCLIntelFpgaPipelineAttrDocs]; + let Documentation = [SYCLIntelFPGAPipelineAttrDocs]; let IsStmtDependent = 1; } def : MutualExclusions<[SYCLIntelFPGAInitiationInterval, - SYCLIntelFpgaPipeline]>; + SYCLIntelFPGAPipeline]>; def : MutualExclusions<[SYCLIntelFPGAIVDep, - SYCLIntelFpgaPipeline]>; + SYCLIntelFPGAPipeline]>; def : MutualExclusions<[SYCLIntelFPGAMaxConcurrency, - SYCLIntelFpgaPipeline]>; + SYCLIntelFPGAPipeline]>; def SYCLIntelFPGALoopCount : StmtAttr { let Spellings = [CXX11<"intel", "loop_count_min">, @@ -2357,7 +2357,7 @@ def SYCLIntelFPGAMaxInterleaving : StmtAttr { def : MutualExclusions<[SYCLIntelFPGADisableLoopPipelining, SYCLIntelFPGAMaxInterleaving]>; -def : MutualExclusions<[SYCLIntelFpgaPipeline, +def : MutualExclusions<[SYCLIntelFPGAPipeline, SYCLIntelFPGAMaxInterleaving]>; def SYCLIntelFPGASpeculatedIterations : StmtAttr { @@ -2372,7 +2372,7 @@ def SYCLIntelFPGASpeculatedIterations : StmtAttr { def : MutualExclusions<[SYCLIntelFPGADisableLoopPipelining, SYCLIntelFPGASpeculatedIterations]>; -def : MutualExclusions<[SYCLIntelFpgaPipeline, +def : MutualExclusions<[SYCLIntelFPGAPipeline, SYCLIntelFPGASpeculatedIterations]>; def SYCLIntelFPGANofusion : StmtAttr { diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index cf5128c086fac..5c1f8b21292a9 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -3306,7 +3306,7 @@ synonym for ``[[[intel::fpga_pipeline]]`` and will be removed in the future. }]; } -def SYCLIntelFpgaPipelineAttrDocs : Documentation { +def SYCLIntelFPGAPipelineAttrDocs : Documentation { let Category = DocCatVariable; let Heading = "intel::fpga_pipeline"; let Content = [{ @@ -3332,8 +3332,23 @@ loop in conjunction with the ``max_interleaving``, ``speculated_iterations``, [[intel::fpga_pipeline(1)]] for (int i = 0; i < 10; ++i) var++; } - void count(int *array, size_t n) { - [[intel::fpga_pipeline(1)]] for (int i = 0; i < n; ++i) array[i] = 0; + void Array(int *array, size_t n) { + // identical to [[intel::fpga_pipeline(1)]] + [[intel::fpga_pipeline]] for (int i = 0; i < n; ++i) array[i] = 0; + } + + void count () { + int a1[10], int i = 0; + [[intel::fpga_pipeline(1)]] while (i < 10) { + a1[i] += 3; + } + + void check() { + int a = 10; + [[intel::fpga_pipeline(1)]] + do { + a = a + 1; + }while( a < 20 ); } template diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index a2ac131a07084..e8516e5d046d2 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -2277,13 +2277,9 @@ class Sema final { SYCLIntelFPGALoopCoalesceAttr * BuildSYCLIntelFPGALoopCoalesceAttr(const AttributeCommonInfo &CI, Expr *E); - SYCLIntelFpgaPipelineAttr * + SYCLIntelFPGAPipelineAttr * BuildSYCLIntelFPGAPipelineAttr(const AttributeCommonInfo &CI, Expr *E); - bool checkPipelineAttrArgument(Expr *E, - const SYCLIntelFpgaPipelineAttr *TmpAttr, - ExprResult &Result); - bool CheckQualifiedFunctionForTypeId(QualType T, SourceLocation Loc); bool CheckFunctionReturnType(QualType T, SourceLocation Loc); diff --git a/clang/lib/CodeGen/CGLoopInfo.cpp b/clang/lib/CodeGen/CGLoopInfo.cpp index 89d0c83644d54..43b995e72d243 100644 --- a/clang/lib/CodeGen/CGLoopInfo.cpp +++ b/clang/lib/CodeGen/CGLoopInfo.cpp @@ -612,7 +612,7 @@ MDNode *LoopInfo::createMetadata( LoopProperties.push_back(MDNode::get(Ctx, Vals)); } - for (auto &FP : Attrs.SYCLIntelFPGANPipelines) { + for (auto &FP : Attrs.SYCLIntelFPGAPipeline) { Metadata *Vals[] = {MDString::get(Ctx, FP.first), ConstantAsMetadata::get(ConstantInt::get( llvm::Type::getInt32Ty(Ctx), FP.second))}; @@ -662,7 +662,7 @@ void LoopAttributes::clear() { PipelineDisabled = false; PipelineInitiationInterval = 0; SYCLNofusionEnable = false; - SYCLIntelFPGANPipelines.clear(); + SYCLIntelFPGAPipeline.clear(); MustProgress = false; } @@ -697,7 +697,7 @@ LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs, Attrs.UnrollAndJamEnable == LoopAttributes::Unspecified && Attrs.DistributeEnable == LoopAttributes::Unspecified && !StartLoc && Attrs.SYCLNofusionEnable == false && - Attrs.SYCLIntelFPGANPipelines.empty() && !EndLoc && !Attrs.MustProgress) + Attrs.SYCLIntelFPGAPipeline.empty() && !EndLoc && !Attrs.MustProgress) return; TempLoopID = MDNode::getTemporary(Header->getContext(), None); @@ -1088,13 +1088,13 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx, if (isa(A)) setSYCLNofusionEnable(); - if (const auto *IntelFpgaPipeline = - dyn_cast(A)) { - const auto *CE = cast(IntelFpgaPipeline->getValue()); + if (const auto *IntelFPGAPipeline = + dyn_cast(A)) { + const auto *CE = cast(IntelFPGAPipeline->getValue()); Optional ArgVal = CE->getResultAsAPSInt(); unsigned int Value = ArgVal->getBoolValue() ? 1 : 0; const char *Var = "llvm.loop.intel.pipelining.enable"; - setSYCLIntelFPGANPipelines(Var, Value); + setSYCLIntelFPGAPipeline(Var, Value); } } diff --git a/clang/lib/CodeGen/CGLoopInfo.h b/clang/lib/CodeGen/CGLoopInfo.h index 14aa12a8544f3..a0a2ae1f94292 100644 --- a/clang/lib/CodeGen/CGLoopInfo.h +++ b/clang/lib/CodeGen/CGLoopInfo.h @@ -154,7 +154,7 @@ struct LoopAttributes { /// Value for fpga_pipeline variant and metadata. llvm::SmallVector, 2> - SYCLIntelFPGANPipelines; + SYCLIntelFPGAPipeline; /// Value for whether the loop is required to make progress. bool MustProgress; @@ -412,8 +412,8 @@ class LoopInfoStack { void setSYCLNofusionEnable() { StagedAttrs.SYCLNofusionEnable = true; } /// Set variant and value of fpga_pipeline for the next loop pushed. - void setSYCLIntelFPGANPipelines(const char *Var, unsigned int Value) { - StagedAttrs.SYCLIntelFPGANPipelines.push_back({Var, Value}); + void setSYCLIntelFPGAPipeline(const char *Var, unsigned int Value) { + StagedAttrs.SYCLIntelFPGAPipeline.push_back({Var, Value}); } /// Set no progress for the next loop pushed. diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp index d62f5f3cd8257..001890cead8a3 100644 --- a/clang/lib/Sema/SemaStmtAttr.cpp +++ b/clang/lib/Sema/SemaStmtAttr.cpp @@ -220,17 +220,6 @@ static Attr *handleSYCLIntelFPGADisableLoopPipeliningAttr(Sema &S, Stmt *, } // Handle [[intel:fpga_pipeline]] attribute. -bool Sema::checkPipelineAttrArgument(Expr *E, - const SYCLIntelFpgaPipelineAttr *TmpAttr, - ExprResult &Result) { - llvm::APSInt Value; - // Validate that we have an integer constant expression. - Result = VerifyIntegerConstantExpression(E, &Value); - if (Result.isInvalid()) - return true; - return false; -} - static Attr *handleSYCLIntelFPGAPipelineAttr(Sema &S, Stmt *, const ParsedAttr &A) { // If no attribute argument is specified, set to default value '1'. @@ -242,19 +231,19 @@ static Attr *handleSYCLIntelFPGAPipelineAttr(Sema &S, Stmt *, return S.BuildSYCLIntelFPGAPipelineAttr(A, E); } -SYCLIntelFpgaPipelineAttr * +SYCLIntelFPGAPipelineAttr * Sema::BuildSYCLIntelFPGAPipelineAttr(const AttributeCommonInfo &A, Expr *E) { - SYCLIntelFpgaPipelineAttr TmpAttr(Context, A, E); if (!E->isValueDependent()) { // Check if the expression is not value dependent. - ExprResult Res; - if (checkPipelineAttrArgument(E, &TmpAttr, Res)) + llvm::APSInt ArgVal; + ExprResult Res = VerifyIntegerConstantExpression(E, &ArgVal); + if (Res.isInvalid()) return nullptr; E = Res.get(); } - return new (Context) SYCLIntelFpgaPipelineAttr(Context, A, E); + return new (Context) SYCLIntelFPGAPipelineAttr(Context, A, E); } static bool checkSYCLIntelFPGAIVDepSafeLen(Sema &S, llvm::APSInt &Value, @@ -859,7 +848,7 @@ static void CheckForIncompatibleSYCLLoopAttributes( CheckForDuplicationSYCLLoopAttribute(S, Attrs, false); CheckRedundantSYCLIntelFPGAIVDepAttrs(S, Attrs); CheckForDuplicationSYCLLoopAttribute(S, Attrs); - CheckForDuplicationSYCLLoopAttribute(S, Attrs); + CheckForDuplicationSYCLLoopAttribute(S, Attrs); } void CheckForIncompatibleUnrollHintAttributes( @@ -1005,7 +994,7 @@ static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const ParsedAttr &A, return handleUnlikely(S, St, A, Range); case ParsedAttr::AT_SYCLIntelFPGANofusion: return handleIntelFPGANofusionAttr(S, St, A); - case ParsedAttr::AT_SYCLIntelFpgaPipeline: + case ParsedAttr::AT_SYCLIntelFPGAPipeline: return handleSYCLIntelFPGAPipelineAttr(S, St, A); default: // N.B., ClangAttrEmitter.cpp emits a diagnostic helper that ensures a diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index fe19d9b43cb1d..4456dac787da7 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1110,8 +1110,8 @@ namespace { const SYCLIntelFPGASpeculatedIterationsAttr *SI); const SYCLIntelFPGALoopCountAttr * TransformSYCLIntelFPGALoopCountAttr(const SYCLIntelFPGALoopCountAttr *SI); - const SYCLIntelFpgaPipelineAttr * - TransformSYCLIntelFpgaPipelineAttr(const SYCLIntelFpgaPipelineAttr *SI); + const SYCLIntelFPGAPipelineAttr * + TransformSYCLIntelFPGAPipelineAttr(const SYCLIntelFPGAPipelineAttr *SI); ExprResult TransformPredefinedExpr(PredefinedExpr *E); ExprResult TransformDeclRefExpr(DeclRefExpr *E); @@ -1603,9 +1603,9 @@ const LoopUnrollHintAttr *TemplateInstantiator::TransformLoopUnrollHintAttr( return getSema().BuildLoopUnrollHintAttr(*LU, TransformedExpr); } -const SYCLIntelFpgaPipelineAttr * -TemplateInstantiator::TransformSYCLIntelFpgaPipelineAttr( - const SYCLIntelFpgaPipelineAttr *PA) { +const SYCLIntelFPGAPipelineAttr * +TemplateInstantiator::TransformSYCLIntelFPGAPipelineAttr( + const SYCLIntelFPGAPipelineAttr *PA) { Expr *TransformedExpr = getDerived().TransformExpr(PA->getValue()).get(); return getSema().BuildSYCLIntelFPGAPipelineAttr(*PA, TransformedExpr); } diff --git a/clang/test/CodeGenSYCL/intel-fpga-loops.cpp b/clang/test/CodeGenSYCL/intel-fpga-loops.cpp index 2e31dd2af2a83..0d0621be1a096 100644 --- a/clang/test/CodeGenSYCL/intel-fpga-loops.cpp +++ b/clang/test/CodeGenSYCL/intel-fpga-loops.cpp @@ -24,6 +24,9 @@ // CHECK: br label %for.cond2, !llvm.loop ![[MD_FP_1:[0-9]+]] // CHECK: br label %for.cond13, !llvm.loop ![[MD_FP_2:[0-9]+]] // CHECK: br label %for.cond24, !llvm.loop ![[MD_FP_3:[0-9]+]] +// CHECK: br label %while.cond, !llvm.loop ![[MD_FP_4:[0-9]+]] +// CHECK: br i1 %cmp38, label %do.body, label %do.end, !llvm.loop ![[MD_FP_5:[0-9]+]] +// CHECK: br label %for.cond40, !llvm.loop ![[MD_FP_6:[0-9]+]] void disable_loop_pipelining() { int a[10]; @@ -155,6 +158,7 @@ void loop_count_control() { a[i] = 0; } +// Add CodeGen tests for Loop attribute: [[intel::fpga_pipeline()]]. template void fpga_pipeline() { int a[10]; @@ -174,6 +178,23 @@ void fpga_pipeline() { // CHECK: ![[MD_FP_3]] = distinct !{![[MD_FP_3]], ![[MP]], ![[MD_dlp]]} [[intel::fpga_pipeline(0)]] for (int i = 0; i != 10; ++i) a[i] = 0; + + // CHECK: ![[MD_FP_4]] = distinct !{![[MD_FP_4]], ![[MP]], ![[MD_fpga_pipeline]]} + int j = 0; + [[intel::fpga_pipeline]] while (j < 10) { + a[j] += 3; + } + + // CHECK: ![[MD_FP_5]] = distinct !{![[MD_FP_5]], ![[MP]], ![[MD_fpga_pipeline]]} + int b = 10; + [[intel::fpga_pipeline(1)]] + do { + b = b + 1; + }while( b < 20 ); + + // CHECK: ![[MD_FP_6]] = distinct !{![[MD_FP_6]], ![[MD_fpga_pipeline]]} + int c[] = {0, 1, 2, 3, 4, 5}; + [[intel::fpga_pipeline(A)]] for (int n : c) { n *= 2; } } template diff --git a/clang/test/SemaSYCL/intel-fpga-pipeline-ast.cpp b/clang/test/SemaSYCL/intel-fpga-pipeline-ast.cpp new file mode 100644 index 0000000000000..4bc911ee7d05e --- /dev/null +++ b/clang/test/SemaSYCL/intel-fpga-pipeline-ast.cpp @@ -0,0 +1,72 @@ +// RUN: %clang_cc1 -fsycl-is-device -internal-isystem %S/Inputs -fsyntax-only -ast-dump -Wno-sycl-2017-compat -verify %s | FileCheck %s +// expected-no-diagnostics + +// Add AST tests for Loop attribute: [[intel::fpga_pipeline()]]. + +#include "sycl.hpp" + +using namespace cl::sycl; +queue q; + +template +void fpga_pipeline() { + int a1[10], a2[10]; + // CHECK: AttributedStmt + // CHECK-NEXT: SYCLIntelFPGAPipelineAttr + [[intel::fpga_pipeline(A)]] for (int p = 0; p < 10; ++p) { + a1[p] = a2[p] = 0; + } + + // CHECK: AttributedStmt + // CHECK-NEXT: SYCLIntelFPGAPipelineAttr + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 1 + // CHECK-NEXT: IntegerLiteral{{.*}}1{{$}} + int i = 0; + [[intel::fpga_pipeline]] while (i < 10) { + a1[i] += 3; + } + + // CHECK: AttributedStmt + // CHECK-NEXT: SYCLIntelFPGAPipelineAttr + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 1 + // CHECK-NEXT: IntegerLiteral{{.*}}1{{$}} + for (int i = 0; i < 10; ++i) { + [[intel::fpga_pipeline(1)]] for (int j = 0; j < 10; ++j) { + a1[i] += a1[j]; + } + } + + // CHECK: AttributedStmt + // CHECK-NEXT: SYCLIntelFPGAPipelineAttr + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 0 + // CHECK-NEXT: IntegerLiteral{{.*}}0{{$}} + [[intel::fpga_pipeline(0)]] for (int i = 0; i != 10; ++i) + a1[i] = 0; + + // CHECK: AttributedStmt + // CHECK-NEXT: SYCLIntelFPGAPipelineAttr + // CHECK-NEXT: ConstantExpr{{.*}}'int' + // CHECK-NEXT: value: Int 1 + // CHECK-NEXT: IntegerLiteral{{.*}}1{{$}} + int b = 10; + [[intel::fpga_pipeline(1)]] + do { + b = b + 1; + }while( b < 20 ); + + // CHECK: AttributedStmt + // CHECK-NEXT: SYCLIntelFPGAPipelineAttr + int c[] = {0, 1, 2, 3, 4, 5}; + [[intel::fpga_pipeline(A)]] for (int n : c) { n *= 2; } +} + +int main() { + q.submit([&](handler &h) { + h.single_task([]() { fpga_pipeline<1>(); }); + }); + return 0; +} + From 2cd112c481143fe54f60e28f57f22159d1be6e47 Mon Sep 17 00:00:00 2001 From: Soumi Manna Date: Tue, 7 Jun 2022 16:49:20 -0700 Subject: [PATCH 07/11] fix clang format errors Signed-off-by: Soumi Manna --- clang/include/clang/Basic/AttrDocs.td | 7 +++---- clang/test/CodeGenSYCL/intel-fpga-loops.cpp | 15 +++++++-------- .../test/SemaSYCL/intel-fpga-pipeline-ast.cpp | 18 ++++++++---------- 3 files changed, 18 insertions(+), 22 deletions(-) diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 5c1f8b21292a9..40f6b5263da22 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -3345,10 +3345,9 @@ loop in conjunction with the ``max_interleaving``, ``speculated_iterations``, void check() { int a = 10; - [[intel::fpga_pipeline(1)]] - do { - a = a + 1; - }while( a < 20 ); + [[intel::fpga_pipeline(1)]] do { + a = a + 1; + } while (a < 20); } template diff --git a/clang/test/CodeGenSYCL/intel-fpga-loops.cpp b/clang/test/CodeGenSYCL/intel-fpga-loops.cpp index 0d0621be1a096..772bcce908e5e 100644 --- a/clang/test/CodeGenSYCL/intel-fpga-loops.cpp +++ b/clang/test/CodeGenSYCL/intel-fpga-loops.cpp @@ -187,14 +187,13 @@ void fpga_pipeline() { // CHECK: ![[MD_FP_5]] = distinct !{![[MD_FP_5]], ![[MP]], ![[MD_fpga_pipeline]]} int b = 10; - [[intel::fpga_pipeline(1)]] - do { - b = b + 1; - }while( b < 20 ); - - // CHECK: ![[MD_FP_6]] = distinct !{![[MD_FP_6]], ![[MD_fpga_pipeline]]} - int c[] = {0, 1, 2, 3, 4, 5}; - [[intel::fpga_pipeline(A)]] for (int n : c) { n *= 2; } + [[intel::fpga_pipeline(1)]] do { + b = b + 1; + } while (b < 20); + + // CHECK: ![[MD_FP_6]] = distinct !{![[MD_FP_6]], ![[MD_fpga_pipeline]]} + int c[] = {0, 1, 2, 3, 4, 5}; + [[intel::fpga_pipeline(A)]] for (int n : c) { n *= 2; } } template diff --git a/clang/test/SemaSYCL/intel-fpga-pipeline-ast.cpp b/clang/test/SemaSYCL/intel-fpga-pipeline-ast.cpp index 4bc911ee7d05e..e2fecd866891d 100644 --- a/clang/test/SemaSYCL/intel-fpga-pipeline-ast.cpp +++ b/clang/test/SemaSYCL/intel-fpga-pipeline-ast.cpp @@ -33,7 +33,7 @@ void fpga_pipeline() { // CHECK-NEXT: value: Int 1 // CHECK-NEXT: IntegerLiteral{{.*}}1{{$}} for (int i = 0; i < 10; ++i) { - [[intel::fpga_pipeline(1)]] for (int j = 0; j < 10; ++j) { + [[intel::fpga_pipeline(1)]] for (int j = 0; j < 10; ++j) { a1[i] += a1[j]; } } @@ -52,15 +52,14 @@ void fpga_pipeline() { // CHECK-NEXT: value: Int 1 // CHECK-NEXT: IntegerLiteral{{.*}}1{{$}} int b = 10; - [[intel::fpga_pipeline(1)]] - do { - b = b + 1; - }while( b < 20 ); + [[intel::fpga_pipeline(1)]] do { + b = b + 1; + } while (b < 20); - // CHECK: AttributedStmt - // CHECK-NEXT: SYCLIntelFPGAPipelineAttr - int c[] = {0, 1, 2, 3, 4, 5}; - [[intel::fpga_pipeline(A)]] for (int n : c) { n *= 2; } + // CHECK: AttributedStmt + // CHECK-NEXT: SYCLIntelFPGAPipelineAttr + int c[] = {0, 1, 2, 3, 4, 5}; + [[intel::fpga_pipeline(A)]] for (int n : c) { n *= 2; } } int main() { @@ -69,4 +68,3 @@ int main() { }); return 0; } - From 94c2ab51215280e0e10a74a14ccf466e43d65944 Mon Sep 17 00:00:00 2001 From: Soumi Manna Date: Thu, 9 Jun 2022 10:46:50 -0700 Subject: [PATCH 08/11] address review comments Signed-off-by: Soumi Manna --- clang/test/CodeGenSYCL/intel-fpga-loops.cpp | 5 +++ clang/test/SemaSYCL/intel-fpga-loops.cpp | 40 ++++++--------------- 2 files changed, 16 insertions(+), 29 deletions(-) diff --git a/clang/test/CodeGenSYCL/intel-fpga-loops.cpp b/clang/test/CodeGenSYCL/intel-fpga-loops.cpp index 772bcce908e5e..cbdfca71c2de9 100644 --- a/clang/test/CodeGenSYCL/intel-fpga-loops.cpp +++ b/clang/test/CodeGenSYCL/intel-fpga-loops.cpp @@ -27,6 +27,7 @@ // CHECK: br label %while.cond, !llvm.loop ![[MD_FP_4:[0-9]+]] // CHECK: br i1 %cmp38, label %do.body, label %do.end, !llvm.loop ![[MD_FP_5:[0-9]+]] // CHECK: br label %for.cond40, !llvm.loop ![[MD_FP_6:[0-9]+]] +// CHECK: br label %while.cond47, !llvm.loop ![[MD_FP_7:[0-9]+]] void disable_loop_pipelining() { int a[10]; @@ -194,6 +195,10 @@ void fpga_pipeline() { // CHECK: ![[MD_FP_6]] = distinct !{![[MD_FP_6]], ![[MD_fpga_pipeline]]} int c[] = {0, 1, 2, 3, 4, 5}; [[intel::fpga_pipeline(A)]] for (int n : c) { n *= 2; } + + // CHECK: ![[MD_FP_7]] = distinct !{![[MD_FP_7]], ![[MP]], ![[MD_fpga_pipeline]]} + int k = 0; + [[intel::fpga_pipeline(-1)]] while (k < 20) { a[k] += 2; } } template diff --git a/clang/test/SemaSYCL/intel-fpga-loops.cpp b/clang/test/SemaSYCL/intel-fpga-loops.cpp index f98a1914570f2..7bd1500cc7c95 100644 --- a/clang/test/SemaSYCL/intel-fpga-loops.cpp +++ b/clang/test/SemaSYCL/intel-fpga-loops.cpp @@ -133,8 +133,8 @@ void boo() { // Test for incorrect argument value for Intel FPGA loop attributes void goo() { int a[10]; - [[intel::disable_loop_pipelining]] for (int i = 0; i != 10; ++i) // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ - // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} + // no diagnostics are expected + [[intel::fpga_pipeline]] for (int i = 0; i != 10; ++i) a[i] = 0; // no diagnostics are expected [[intel::max_concurrency(0)]] for (int i = 0; i != 10; ++i) @@ -272,11 +272,9 @@ void zoo() { [[intel::max_concurrency(2)]] [[intel::initiation_interval(2)]] for (int i = 0; i != 10; ++i) a[i] = 0; - [[intel::disable_loop_pipelining]] // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ - // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} - // expected-error@+1 {{duplicate Intel FPGA loop attribute 'disable_loop_pipelining'}} - [[intel::disable_loop_pipelining]] for (int i = 0; i != 10; ++i) // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ - // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} + [[intel::fpga_pipeline]] + // expected-error@+1 {{duplicate Intel FPGA loop attribute 'fpga_pipeline'}} + [[intel::fpga_pipeline]] for (int i = 0; i != 10; ++i) a[i] = 0; [[intel::loop_coalesce(2)]] // expected-error@+2 {{duplicate Intel FPGA loop attribute 'loop_coalesce'}} @@ -365,8 +363,7 @@ void zoo() { // Test for Intel FPGA loop attributes compatibility void loop_attrs_compatibility() { int a[10]; - [[intel::disable_loop_pipelining]] // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ - // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} + [[intel::fpga_pipeline]] [[intel::loop_coalesce]] for (int i = 0; i != 10; ++i) a[i] = 0; // expected-error@+4 {{'max_interleaving' and 'disable_loop_pipelining' attributes are not compatible}} @@ -375,10 +372,10 @@ void loop_attrs_compatibility() { // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} [[intel::max_interleaving(0)]] for (int i = 0; i != 10; ++i) a[i] = 0; - // expected-error@+2 {{'disable_loop_pipelining' and 'speculated_iterations' attributes are not compatible}} + + // expected-error@+2 {{'fpga_pipeline' and 'speculated_iterations' attributes are not compatible}} // expected-note@+1 {{conflicting attribute is here}} - [[intel::speculated_iterations(0)]] [[intel::disable_loop_pipelining]] for (int i = 0; i != 10; ++i) // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ - // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} + [[intel::speculated_iterations(0)]] [[intel::fpga_pipeline]] for (int i = 0; i != 10; ++i) a[i] = 0; // expected-error@+4 {{'max_concurrency' and 'disable_loop_pipelining' attributes are not compatible}} // expected-note@+1 {{conflicting attribute is here}} @@ -386,10 +383,9 @@ void loop_attrs_compatibility() { // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} [[intel::max_concurrency(0)]] for (int i = 0; i != 10; ++i) a[i] = 0; - // expected-error@+2 {{'disable_loop_pipelining' and 'initiation_interval' attributes are not compatible}} + // expected-error@+2 {{'fpga_pipeline' and 'initiation_interval' attributes are not compatible}} // expected-note@+1 {{conflicting attribute is here}} - [[intel::initiation_interval(10)]] [[intel::disable_loop_pipelining]] for (int i = 0; i != 10; ++i) // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ - // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} + [[intel::initiation_interval(10)]] [[intel::fpga_pipeline]] for (int i = 0; i != 10; ++i) a[i] = 0; // expected-error@+4 {{'ivdep' and 'disable_loop_pipelining' attributes are not compatible}} // expected-note@+1 {{conflicting attribute is here}} @@ -398,20 +394,6 @@ void loop_attrs_compatibility() { [[intel::ivdep]] for (int i = 0; i != 10; ++i) a[i] = 0; - [[intel::disable_loop_pipelining]] // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ - // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} - [[intel::nofusion]] for (int i = 0; i != 10; ++i) - a[i] = 0; - - [[intel::disable_loop_pipelining]] // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ - // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} - [[intel::loop_count_avg(8)]] for (int i = 0; i != 10; ++i) - a[i] = 0; - [[intel::loop_count_min(8)]] for (int i = 0; i != 10; ++i) - a[i] = 0; - [[intel::loop_count_max(8)]] for (int i = 0; i != 10; ++i) - a[i] = 0; - // no diagnostics are expected [[intel::fpga_pipeline]] [[intel::loop_coalesce]] for (int i = 0; i != 10; ++i) a[i] = 0; From ea278059dd3ec26004eb00a335cf435413f7b8ff Mon Sep 17 00:00:00 2001 From: Soumi Manna Date: Thu, 9 Jun 2022 10:55:26 -0700 Subject: [PATCH 09/11] fix formar errors Signed-off-by: Soumi Manna --- clang/test/SemaSYCL/intel-fpga-loops.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/test/SemaSYCL/intel-fpga-loops.cpp b/clang/test/SemaSYCL/intel-fpga-loops.cpp index 7bd1500cc7c95..075619da0179d 100644 --- a/clang/test/SemaSYCL/intel-fpga-loops.cpp +++ b/clang/test/SemaSYCL/intel-fpga-loops.cpp @@ -363,8 +363,7 @@ void zoo() { // Test for Intel FPGA loop attributes compatibility void loop_attrs_compatibility() { int a[10]; - [[intel::fpga_pipeline]] - [[intel::loop_coalesce]] for (int i = 0; i != 10; ++i) + [[intel::fpga_pipeline]] [[intel::loop_coalesce]] for (int i = 0; i != 10; ++i) a[i] = 0; // expected-error@+4 {{'max_interleaving' and 'disable_loop_pipelining' attributes are not compatible}} // expected-note@+1 {{conflicting attribute is here}} From 004041212063a971db6bfe60cbfdc7c3bab1ff9d Mon Sep 17 00:00:00 2001 From: Soumi Manna Date: Fri, 10 Jun 2022 09:30:55 -0700 Subject: [PATCH 10/11] rempve duplicate tests Signed-off-by: Soumi Manna --- clang/test/SemaSYCL/intel-fpga-loops.cpp | 27 ------------------------ 1 file changed, 27 deletions(-) diff --git a/clang/test/SemaSYCL/intel-fpga-loops.cpp b/clang/test/SemaSYCL/intel-fpga-loops.cpp index 075619da0179d..422464d1d4391 100644 --- a/clang/test/SemaSYCL/intel-fpga-loops.cpp +++ b/clang/test/SemaSYCL/intel-fpga-loops.cpp @@ -353,11 +353,6 @@ void zoo() { // expected-error@+1{{duplicate Intel FPGA loop attribute 'loop_count'}} [[intel::loop_count(2)]] for (int i = 0; i != 10; ++i) a[i] = 0; - - [[intel::fpga_pipeline(1)]] - // expected-error@+1{{duplicate Intel FPGA loop attribute 'fpga_pipeline'}} - [[intel::fpga_pipeline(1)]] for (int i = 0; i != 10; ++i) - a[i] = 0; } // Test for Intel FPGA loop attributes compatibility @@ -376,22 +371,10 @@ void loop_attrs_compatibility() { // expected-note@+1 {{conflicting attribute is here}} [[intel::speculated_iterations(0)]] [[intel::fpga_pipeline]] for (int i = 0; i != 10; ++i) a[i] = 0; - // expected-error@+4 {{'max_concurrency' and 'disable_loop_pipelining' attributes are not compatible}} - // expected-note@+1 {{conflicting attribute is here}} - [[intel::disable_loop_pipelining]] // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ - // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} - [[intel::max_concurrency(0)]] for (int i = 0; i != 10; ++i) - a[i] = 0; // expected-error@+2 {{'fpga_pipeline' and 'initiation_interval' attributes are not compatible}} // expected-note@+1 {{conflicting attribute is here}} [[intel::initiation_interval(10)]] [[intel::fpga_pipeline]] for (int i = 0; i != 10; ++i) a[i] = 0; - // expected-error@+4 {{'ivdep' and 'disable_loop_pipelining' attributes are not compatible}} - // expected-note@+1 {{conflicting attribute is here}} - [[intel::disable_loop_pipelining]] // expected-warning {{attribute 'intel::disable_loop_pipelining' is deprecated}} \ - // expected-note {{did you mean to use 'intel::fpga_pipeline' instead?}} - [[intel::ivdep]] for (int i = 0; i != 10; ++i) - a[i] = 0; // no diagnostics are expected [[intel::fpga_pipeline]] [[intel::loop_coalesce]] for (int i = 0; i != 10; ++i) @@ -417,21 +400,11 @@ void loop_attrs_compatibility() { [[intel::max_concurrency(2)]] [[intel::fpga_pipeline(1)]] for (int i = 0; i != 10; ++i) a[i] = 0; - // expected-error@+2 {{'fpga_pipeline' and 'initiation_interval' attributes are not compatible}} - // expected-note@+1 {{conflicting attribute is here}} - [[intel::initiation_interval(2)]] [[intel::fpga_pipeline(1)]] for (int i = 0; i != 10; ++i) - a[i] = 0; - // expected-error@+2 {{'fpga_pipeline' and 'max_interleaving' attributes are not compatible}} // expected-note@+1 {{conflicting attribute is here}} [[intel::max_interleaving(2)]] [[intel::fpga_pipeline]] for (int i = 0; i != 10; ++i) a[i] = 0; - // expected-error@+2 {{'fpga_pipeline' and 'speculated_iterations' attributes are not compatible}} - // expected-note@+1 {{conflicting attribute is here}} - [[intel::speculated_iterations(0)]] [[intel::fpga_pipeline]] for (int i = 0; i != 10; ++i) - a[i] = 0; - // expected-error@+2 {{'fpga_pipeline' and 'ivdep' attributes are not compatible}} // expected-note@+1 {{conflicting attribute is here}} [[intel::ivdep]] [[intel::fpga_pipeline]] for (int i = 0; i != 10; ++i) From 6191ca1b7f169bbc994946621d99d2d65b3fc0de Mon Sep 17 00:00:00 2001 From: Soumi Manna Date: Fri, 10 Jun 2022 09:35:15 -0700 Subject: [PATCH 11/11] rempve duplicate tests Signed-off-by: Soumi Manna --- clang/test/SemaSYCL/intel-fpga-loops.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/clang/test/SemaSYCL/intel-fpga-loops.cpp b/clang/test/SemaSYCL/intel-fpga-loops.cpp index 422464d1d4391..68c23e66d183c 100644 --- a/clang/test/SemaSYCL/intel-fpga-loops.cpp +++ b/clang/test/SemaSYCL/intel-fpga-loops.cpp @@ -224,9 +224,6 @@ void goo() { a[i] = 0; // no diagnostics are expected - [[intel::fpga_pipeline]] for (int i = 0; i != 10; ++i) - a[i] = 0; - // no diagnostics are expected [[intel::fpga_pipeline(0)]] for (int i = 0; i != 10; ++i) a[i] = 0; // no diagnostics are expected