Skip to content

Commit 2d6353e

Browse files
committed
Merge from 'sycl' to 'sycl-web' (#3)
CONFLICT (content): Merge conflict in clang/lib/CodeGen/CGLoopInfo.h CONFLICT (content): Merge conflict in clang/lib/CodeGen/CGLoopInfo.cpp
2 parents 7b13f31 + 68ab67a commit 2d6353e

File tree

15 files changed

+189
-241
lines changed

15 files changed

+189
-241
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1849,6 +1849,18 @@ def SYCLIntelFPGASpeculatedIterations : Attr {
18491849
let Documentation = [SYCLIntelFPGASpeculatedIterationsAttrDocs];
18501850
}
18511851

1852+
def SYCLIntelFPGANofusion : Attr {
1853+
let Spellings = [CXX11<"intel","nofusion">];
1854+
let LangOpts = [SYCLIsDevice, SYCLIsHost];
1855+
let HasCustomTypeTransform = 1;
1856+
let AdditionalMembers = [{
1857+
static const char *getName() {
1858+
return "nofusion";
1859+
}
1860+
}];
1861+
let Documentation = [SYCLIntelFPGANofusionAttrDocs];
1862+
}
1863+
18521864
def IntelFPGALocalNonConstVar : SubsetSubject<Var,
18531865
[{S->hasLocalStorage() &&
18541866
S->getKind() != Decl::ImplicitParam &&

clang/include/clang/Basic/AttrDocs.td

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2435,6 +2435,15 @@ used on the same loop in conjunction with disable_loop_pipelining.
24352435
}];
24362436
}
24372437

2438+
def SYCLIntelFPGANofusionAttrDocs : Documentation {
2439+
let Category = DocCatVariable;
2440+
let Heading = "intel::nofusion";
2441+
let Content = [{
2442+
This attribute applies to a loop. Indicates that the annotated
2443+
loop should not be fused with any adjacent loop.
2444+
}];
2445+
}
2446+
24382447
def SYCLDeviceIndirectlyCallableDocs : Documentation {
24392448
let Category = DocCatFunction;
24402449
let Heading = "intel::device_indirectly_callable";

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11156,11 +11156,6 @@ def warn_sycl_pass_by_value_deprecated
1115611156
def warn_sycl_pass_by_reference_future
1115711157
: Warning<"Passing of kernel functions by reference is a SYCL 2020 extension">,
1115811158
InGroup<Sycl2017Compat>, ShowInSystemHeader;
11159-
def warn_sycl_attibute_function_raw_ptr
11160-
: Warning<"SYCL 1.2.1 specification does not allow %0 attribute applied "
11161-
"to a function with a raw pointer "
11162-
"%select{return type|parameter type}1">,
11163-
InGroup<SyclStrict>, DefaultError;
1116411159
def warn_sycl_implicit_decl
1116511160
: Warning<"SYCL 1.2.1 specification requires an explicit forward "
1116611161
"declaration for a kernel type name; your program may not "

clang/lib/CodeGen/CGLoopInfo.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,12 @@ MDNode *LoopInfo::createMetadata(
574574
LoopProperties.push_back(MDNode::get(Ctx, Vals));
575575
}
576576

577+
// nofusion attribute corresponds to 'llvm.loop.fusion.disable' metadata
578+
if (Attrs.SYCLNofusionEnable) {
579+
Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.fusion.disable")};
580+
LoopProperties.push_back(MDNode::get(Ctx, Vals));
581+
}
582+
577583
if (Attrs.SYCLSpeculatedIterationsEnable) {
578584
Metadata *Vals[] = {
579585
MDString::get(Ctx, "llvm.loop.intel.speculated.iterations.count"),
@@ -601,7 +607,7 @@ LoopAttributes::LoopAttributes(bool IsParallel)
601607
SYCLSpeculatedIterationsNIterations(0), UnrollCount(0),
602608
UnrollAndJamCount(0), DistributeEnable(LoopAttributes::Unspecified),
603609
PipelineDisabled(false), PipelineInitiationInterval(0),
604-
MustProgress(false) {}
610+
SYCLNofusionEnable(false), MustProgress(false) {}
605611

606612
void LoopAttributes::clear() {
607613
IsParallel = false;
@@ -628,6 +634,7 @@ void LoopAttributes::clear() {
628634
DistributeEnable = LoopAttributes::Unspecified;
629635
PipelineDisabled = false;
630636
PipelineInitiationInterval = 0;
637+
SYCLNofusionEnable = false;
631638
MustProgress = false;
632639
}
633640

@@ -661,7 +668,7 @@ LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs,
661668
Attrs.UnrollEnable == LoopAttributes::Unspecified &&
662669
Attrs.UnrollAndJamEnable == LoopAttributes::Unspecified &&
663670
Attrs.DistributeEnable == LoopAttributes::Unspecified && !StartLoc &&
664-
!EndLoc && !Attrs.MustProgress)
671+
Attrs.SYCLNofusionEnable == false && !EndLoc && !Attrs.MustProgress)
665672
return;
666673

667674
TempLoopID = MDNode::getTemporary(Header->getContext(), None);
@@ -967,6 +974,8 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx,
967974
// For attribute speculated_iterations:
968975
// n - 'llvm.loop.intel.speculated.iterations.count, i32 n' metadata will be
969976
// emitted
977+
// For attribute nofusion:
978+
// 'llvm.loop.fusion.disable' metadata will be emitted
970979
for (const auto *Attr : Attrs) {
971980
const SYCLIntelFPGAIVDepAttr *IntelFPGAIVDep =
972981
dyn_cast<SYCLIntelFPGAIVDepAttr>(Attr);
@@ -983,10 +992,13 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx,
983992
dyn_cast<SYCLIntelFPGAMaxInterleavingAttr>(Attr);
984993
const SYCLIntelFPGASpeculatedIterationsAttr *IntelFPGASpeculatedIterations =
985994
dyn_cast<SYCLIntelFPGASpeculatedIterationsAttr>(Attr);
995+
const SYCLIntelFPGANofusionAttr *IntelFPGANofusion =
996+
dyn_cast<SYCLIntelFPGANofusionAttr>(Attr);
986997

987998
if (!IntelFPGAIVDep && !IntelFPGAII && !IntelFPGAMaxConcurrency &&
988999
!IntelFPGALoopCoalesce && !IntelFPGADisableLoopPipelining &&
989-
!IntelFPGAMaxInterleaving && !IntelFPGASpeculatedIterations)
1000+
!IntelFPGAMaxInterleaving && !IntelFPGASpeculatedIterations &&
1001+
!IntelFPGANofusion)
9901002
continue;
9911003

9921004
if (IntelFPGAIVDep)
@@ -1031,6 +1043,9 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx,
10311043
->getIntegerConstantExpr(Ctx)
10321044
->getSExtValue());
10331045
}
1046+
1047+
if (IntelFPGANofusion)
1048+
setSYCLNofusionEnable();
10341049
}
10351050

10361051
setMustProgress(MustProgress);

clang/lib/CodeGen/CGLoopInfo.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,9 @@ struct LoopAttributes {
150150
/// Value for llvm.loop.pipeline.iicount metadata.
151151
unsigned PipelineInitiationInterval;
152152

153+
/// Flag for llvm.loop.fusion.disable metatdata.
154+
bool SYCLNofusionEnable;
155+
153156
/// Value for whether the loop is required to make progress.
154157
bool MustProgress;
155158
};
@@ -408,6 +411,9 @@ class LoopInfoStack {
408411
StagedAttrs.PipelineInitiationInterval = C;
409412
}
410413

414+
/// Set flag of nofusion for the next loop pushed.
415+
void setSYCLNofusionEnable() { StagedAttrs.SYCLNofusionEnable = true; }
416+
411417
/// Set no progress for the next loop pushed.
412418
void setMustProgress(bool P) { StagedAttrs.MustProgress = P; }
413419

clang/lib/Parse/ParseStmt.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2582,7 +2582,8 @@ bool Parser::ParseSYCLLoopAttributes(ParsedAttributes &Attrs) {
25822582
Attrs.begin()->getKind() != ParsedAttr::AT_SYCLIntelFPGAMaxInterleaving &&
25832583
Attrs.begin()->getKind() !=
25842584
ParsedAttr::AT_SYCLIntelFPGASpeculatedIterations &&
2585-
Attrs.begin()->getKind() != ParsedAttr::AT_LoopUnrollHint)
2585+
Attrs.begin()->getKind() != ParsedAttr::AT_LoopUnrollHint &&
2586+
Attrs.begin()->getKind() != ParsedAttr::AT_SYCLIntelFPGANofusion)
25862587
return true;
25872588

25882589
bool IsIntelFPGAAttribute = (Attrs.begin()->getKind() != ParsedAttr::AT_LoopUnrollHint);

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4587,15 +4587,6 @@ static void handleSYCLDeviceAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
45874587
S.Diag(AL.getLoc(), diag::err_sycl_attibute_cannot_be_applied_here) << AL;
45884588
return;
45894589
}
4590-
if (FD->getReturnType()->isPointerType()) {
4591-
S.Diag(AL.getLoc(), diag::warn_sycl_attibute_function_raw_ptr)
4592-
<< AL << 0 /* function with a raw pointer return type */;
4593-
}
4594-
for (const ParmVarDecl *Param : FD->parameters())
4595-
if (Param->getType()->isPointerType()) {
4596-
S.Diag(AL.getLoc(), diag::warn_sycl_attibute_function_raw_ptr)
4597-
<< AL << 1 /* function with a raw pointer parameter type */;
4598-
}
45994590

46004591
handleSimpleAttribute<SYCLDeviceAttr>(S, D, AL);
46014592
}

clang/lib/Sema/SemaStmtAttr.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,19 @@ static Attr *handleIntelFPGAIVDepAttr(Sema &S, const ParsedAttr &A) {
317317
NumArgs == 2 ? A.getArgAsExpr(1) : nullptr);
318318
}
319319

320+
static Attr *handleIntelFPGANofusionAttr(Sema &S, const ParsedAttr &A) {
321+
if (S.LangOpts.SYCLIsHost)
322+
return nullptr;
323+
324+
unsigned NumArgs = A.getNumArgs();
325+
if (NumArgs > 0) {
326+
S.Diag(A.getLoc(), diag::warn_attribute_too_many_arguments) << A << 0;
327+
return nullptr;
328+
}
329+
330+
return new (S.Context) SYCLIntelFPGANofusionAttr(S.Context, A);
331+
}
332+
320333
static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const ParsedAttr &A,
321334
SourceRange) {
322335
IdentifierLoc *PragmaNameLoc = A.getArgAsIdent(0);
@@ -675,6 +688,8 @@ static void CheckForIncompatibleSYCLLoopAttributes(
675688
S, Attrs, Range);
676689

677690
CheckRedundantSYCLIntelFPGAIVDepAttrs(S, Attrs);
691+
CheckForDuplicationSYCLLoopAttribute<SYCLIntelFPGANofusionAttr>(S, Attrs,
692+
Range);
678693
}
679694

680695
void CheckForIncompatibleUnrollHintAttributes(
@@ -803,6 +818,8 @@ static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const ParsedAttr &A,
803818
return handleLikely(S, St, A, Range);
804819
case ParsedAttr::AT_Unlikely:
805820
return handleUnlikely(S, St, A, Range);
821+
case ParsedAttr::AT_SYCLIntelFPGANofusion:
822+
return handleIntelFPGANofusionAttr(S, A);
806823
default:
807824
// if we're here, then we parsed a known attribute, but didn't recognize
808825
// it as a statement attribute => it is declaration attribute
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// RUN: %clang_cc1 -triple spir64-unknown-unknown-sycldevice -disable-llvm-passes -fsycl -fsycl-is-device -internal-isystem %S/Inputs -emit-llvm %s -o - | FileCheck %s
2+
3+
#include "sycl.hpp"
4+
5+
using namespace cl::sycl;
6+
queue q;
7+
8+
void nofusion() {
9+
int a[10];
10+
11+
int i = 0;
12+
[[intel::nofusion]] while (i < 10) {
13+
// CHECK: br label {{.*}}, !llvm.loop ![[MD_NF_1:.*]]
14+
a[i] += 2;
15+
}
16+
17+
[[intel::nofusion]] do {
18+
// CHECK: br i1 %{{.*}}, !llvm.loop ![[MD_NF_2:.*]]
19+
a[i] += 3;
20+
}
21+
while (i < 10)
22+
;
23+
24+
[[intel::nofusion]] for (int i = 0; i < 10; ++i) {
25+
// CHECK: br label %{{.*}}, !llvm.loop ![[MD_NF_3:.*]]
26+
for (int j = 0; j < 10; ++j) {
27+
// CHECK-NOT: br label %{{.*}}, !llvm.loop !{{.*}}
28+
a[i] += a[j];
29+
}
30+
}
31+
32+
int k;
33+
[[intel::nofusion]] for (auto k : a) {
34+
// CHECK: br label %{{.*}}, !llvm.loop ![[MD_NF_5:.*]]
35+
k += 4;
36+
}
37+
38+
[[intel::nofusion]] for (int i = 0; i < 10; ++i) {
39+
// CHECK: br label %{{.*}}, !llvm.loop ![[MD_NF_6:.*]]
40+
a[i] += 5;
41+
}
42+
43+
for (int i = 0; i < 10; ++i) {
44+
// CHECK-NOT: br label %{{.*}}, !llvm.loop !{{.*}}
45+
[[intel::nofusion]] for (int j = 0; j < 10; ++j) {
46+
// CHECK: br label %{{.*}}, !llvm.loop ![[MD_NF_8:.*]]
47+
a[i] += a[j];
48+
}
49+
}
50+
}
51+
52+
int main() {
53+
q.submit([&](handler &h) {
54+
h.single_task<class kernel_function>([]() { nofusion(); });
55+
});
56+
return 0;
57+
}
58+
59+
// CHECK: ![[MD_NF_1]] = distinct !{![[MD_NF_1]], ![[MD_Nofusion:[0-9]+]]}
60+
// CHECK: ![[MD_Nofusion]] = !{!"llvm.loop.fusion.disable"}
61+
// CHECK: ![[MD_NF_2]] = distinct !{![[MD_NF_2]], ![[MD_Nofusion]]}
62+
// CHECK: ![[MD_NF_3]] = distinct !{![[MD_NF_3]], ![[MD_Nofusion]]}
63+
// CHECK: ![[MD_NF_5]] = distinct !{![[MD_NF_5]], ![[MD_Nofusion]]}
64+
// CHECK: ![[MD_NF_6]] = distinct !{![[MD_NF_6]], ![[MD_Nofusion]]}
65+
// CHECK: ![[MD_NF_8]] = distinct !{![[MD_NF_8]], ![[MD_Nofusion]]}

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ void foo() {
2525
[[intel::max_interleaving(4)]] int i[10];
2626
// expected-error@+1 {{intelfpga loop attributes must be applied to for, while, or do statements}}
2727
[[intel::speculated_iterations(6)]] int j[10];
28+
// expected-error@+1 {{intelfpga loop attributes must be applied to for, while, or do statements}}
29+
[[intel::nofusion]] int k[10];
2830
}
2931

3032
// Test for deprecated spelling of Intel FPGA loop attributes
@@ -114,6 +116,9 @@ void boo() {
114116
// expected-warning@+1 {{'speculated_iterations' attribute takes no more than 1 argument - attribute ignored}}
115117
[[intel::speculated_iterations(1, 2)]] for (int i = 0; i != 10; ++i)
116118
a[i] = 0;
119+
// expected-warning@+1 {{'nofusion' attribute takes no more than 0 arguments - attribute ignored}}
120+
[[intel::nofusion(0)]] for (int i = 0; i != 10; ++i)
121+
a[i] = 0;
117122
}
118123

119124
// Test for incorrect argument value for Intel FPGA loop attributes
@@ -187,6 +192,10 @@ void goo() {
187192
// no diagnostics are expected
188193
[[intel::ivdep(2, s.ptr)]] for (int i = 0; i != 10; ++i)
189194
s.ptr[i] = 0;
195+
196+
// no diagnostics are expected
197+
[[intel::nofusion]] for (int i = 0; i != 10; ++i)
198+
a[i] = 0;
190199
}
191200

192201
// Test for Intel FPGA loop attributes duplication
@@ -290,6 +299,11 @@ void zoo() {
290299
// expected-note@+1 {{previous attribute is here}}
291300
[[intel::ivdep(a, 3)]] for (int i = 0; i != 10; ++i)
292301
a[i] = 0;
302+
303+
[[intel::nofusion]]
304+
// expected-error@-1 {{duplicate Intel FPGA loop attribute 'nofusion'}}
305+
[[intel::nofusion]] for (int i = 0; i != 10; ++i)
306+
a[i] = 0;
293307
}
294308

295309
// Test for Intel FPGA loop attributes compatibility
@@ -319,6 +333,10 @@ void loop_attrs_compatibility() {
319333
[[intel::disable_loop_pipelining]]
320334
[[intel::ivdep]] for (int i = 0; i != 10; ++i)
321335
a[i] = 0;
336+
// no diagnostics are expected
337+
[[intel::disable_loop_pipelining]]
338+
[[intel::nofusion]] for (int i = 0; i != 10; ++i)
339+
a[i] = 0;
322340
}
323341

324342
template<int A, int B, int C>
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// RUN: %clang_cc1 -fsycl -fsycl-is-device -internal-isystem %S/Inputs -fsyntax-only -ast-dump -Wno-sycl-2017-compat -verify %s | FileCheck %s
2+
// expected-no-diagnostics
3+
4+
#include "sycl.hpp"
5+
6+
using namespace cl::sycl;
7+
queue q;
8+
9+
void nofusion() {
10+
int a1[10], a2[10];
11+
12+
// CHECK: AttributedStmt
13+
// CHECK-NEXT: SYCLIntelFPGANofusionAttr {{.*}}
14+
[[intel::nofusion]] for (int p = 0; p < 10; ++p) {
15+
a1[p] = a2[p] = 0;
16+
}
17+
18+
// CHECK: AttributedStmt
19+
// CHECK-NEXT: SYCLIntelFPGANofusionAttr {{.*}}
20+
int i = 0;
21+
[[intel::nofusion]] while (i < 10) {
22+
a1[i] += 3;
23+
}
24+
25+
// CHECK: AttributedStmt
26+
// CHECK-NEXT: SYCLIntelFPGANofusionAttr {{.*}}
27+
for (int i = 0; i < 10; ++i) {
28+
[[intel::nofusion]] for (int j = 0; j < 10; ++j) {
29+
a1[i] += a1[j];
30+
}
31+
}
32+
}
33+
34+
int main() {
35+
q.submit([&](handler &h) {
36+
h.single_task<class kernel_function>([]() { nofusion(); });
37+
});
38+
return 0;
39+
}

clang/test/SemaSYCL/restrict-recursion3.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ using myFuncDef = int(int, int);
1616

1717
typedef __typeof__(sizeof(int)) size_t;
1818

19-
// expected-warning@+1 {{SYCL 1.2.1 specification does not allow 'sycl_device' attribute applied to a function with a raw pointer return type}}
2019
SYCL_EXTERNAL
2120
void *operator new(size_t);
2221

clang/test/SemaSYCL/restrict-recursion4.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ using myFuncDef = int(int, int);
1818

1919
typedef __typeof__(sizeof(int)) size_t;
2020

21-
// expected-warning@+1 {{SYCL 1.2.1 specification does not allow 'sycl_device' attribute applied to a function with a raw pointer return type}}
2221
SYCL_EXTERNAL
2322
void *operator new(size_t);
2423

0 commit comments

Comments
 (0)