Skip to content

Commit 4d6e93e

Browse files
committed
Initial support for OmpSs-2 array section form
* Tag OSSArraySection as ColonForm ':' or not ';'. ArraySubscripts are tagged as ':' but this is not used * Reworked a bit CodeGen data structures Closes llvm#5
1 parent 58448e3 commit 4d6e93e

17 files changed

+290
-117
lines changed

clang/include/clang/AST/ExprOmpSs.h

+49-26
Original file line numberDiff line numberDiff line change
@@ -17,66 +17,86 @@
1717
#include "clang/AST/ASTContext.h"
1818

1919
namespace clang {
20-
/// OmpSs 4.0 [2.4, Array Sections].
21-
/// To specify an array section in an OmpSs construct, array subscript
20+
/// OmpSs-2 Array Sections.
21+
/// To specify an array section in an OmpSs-2 construct, array subscript
2222
/// expressions are extended with the following syntax:
2323
/// \code
24-
/// [ lower-bound : length ]
25-
/// [ lower-bound : ]
26-
/// [ : length ]
27-
/// [ : ]
24+
/// depend(in : [ lower-bound : length ])
25+
/// depend(in : [ lower-bound : ])
26+
/// depend(in : [ : length ])
27+
/// depend(in : [ : ])
28+
///
29+
/// in([ lower-bound ; length ])
30+
/// in([ lower-bound ; ])
31+
/// in([ ; length ])
32+
/// in([ ; ])
33+
///
34+
/// in([ lower-bound : upper-bound ])
35+
/// in([ lower-bound : ])
36+
/// in([ : upper-bound ])
37+
/// in([ : ])
38+
///
2839
/// \endcode
2940
/// The array section must be a subset of the original array.
3041
/// Array sections are allowed on multidimensional arrays. Base language array
3142
/// subscript expressions can be used to specify length-one dimensions of
3243
/// multidimensional array sections.
33-
/// The lower-bound and length are integral type expressions. When evaluated
34-
/// they represent a set of integer values as follows:
44+
/// The lower-bound, upper-bound and length are integral type expressions.
45+
/// When evaluated they represent a set of integer values as follows:
3546
/// \code
3647
/// { lower-bound, lower-bound + 1, lower-bound + 2,... , lower-bound + length -
3748
/// 1 }
49+
///
50+
/// { lower-bound, lower-bound + 1, lower-bound + 2,... , upper-bound }
3851
/// \endcode
39-
/// The lower-bound and length must evaluate to non-negative integers.
40-
/// When the size of the array dimension is not known, the length must be
41-
/// specified explicitly.
52+
/// The lower-bound, upper-bound and length must evaluate to non-negative integers.
53+
/// When the size of the array dimension is not known, the length/upper-bound
54+
/// must be specified explicitly.
4255
/// When the length is absent, it defaults to the size of the array dimension
4356
/// minus the lower-bound.
57+
/// When the upper-bound is absent, it defaults to the size of the
58+
/// array dimension - 1
4459
/// When the lower-bound is absent it defaults to 0.
4560
class OSSArraySectionExpr : public Expr {
46-
enum { BASE, LOWER_BOUND, LENGTH, END_EXPR };
61+
enum { BASE, LOWER_BOUND, LENGTH_UPPER, END_EXPR };
4762
Stmt *SubExprs[END_EXPR];
4863
SourceLocation ColonLoc;
4964
SourceLocation RBracketLoc;
65+
bool ColonForm;
5066

5167
public:
52-
OSSArraySectionExpr(Expr *Base, Expr *LowerBound, Expr *Length, QualType Type,
68+
OSSArraySectionExpr(Expr *Base, Expr *LowerBound, Expr *LengthUpper, QualType Type,
5369
ExprValueKind VK, ExprObjectKind OK,
54-
SourceLocation ColonLoc, SourceLocation RBracketLoc)
70+
SourceLocation ColonLoc, SourceLocation RBracketLoc,
71+
bool ColonForm)
5572
: Expr(
5673
OSSArraySectionExprClass, Type, VK, OK,
5774
Base->isTypeDependent() ||
5875
(LowerBound && LowerBound->isTypeDependent()) ||
59-
(Length && Length->isTypeDependent()),
76+
(LengthUpper && LengthUpper->isTypeDependent()),
6077
Base->isValueDependent() ||
6178
(LowerBound && LowerBound->isValueDependent()) ||
62-
(Length && Length->isValueDependent()),
79+
(LengthUpper && LengthUpper->isValueDependent()),
6380
Base->isInstantiationDependent() ||
6481
(LowerBound && LowerBound->isInstantiationDependent()) ||
65-
(Length && Length->isInstantiationDependent()),
82+
(LengthUpper && LengthUpper->isInstantiationDependent()),
6683
Base->containsUnexpandedParameterPack() ||
6784
(LowerBound && LowerBound->containsUnexpandedParameterPack()) ||
68-
(Length && Length->containsUnexpandedParameterPack())),
69-
ColonLoc(ColonLoc), RBracketLoc(RBracketLoc) {
85+
(LengthUpper && LengthUpper->containsUnexpandedParameterPack())),
86+
ColonLoc(ColonLoc), RBracketLoc(RBracketLoc), ColonForm(ColonForm) {
7087
SubExprs[BASE] = Base;
7188
SubExprs[LOWER_BOUND] = LowerBound;
72-
SubExprs[LENGTH] = Length;
89+
SubExprs[LENGTH_UPPER] = LengthUpper;
7390
}
7491

7592
/// Create an empty array section expression.
7693
explicit OSSArraySectionExpr(EmptyShell Shell)
7794
: Expr(OSSArraySectionExprClass, Shell) {}
7895

79-
/// An array section can be written only as Base[LowerBound:Length].
96+
/// An array section can be written as:
97+
/// Base[LowerBound : Length]
98+
/// Base[LowerBound ; Length]
99+
/// Base[LowerBound : UpperBound]
80100

81101
/// Get base of the array section.
82102
Expr *getBase() { return cast<Expr>(SubExprs[BASE]); }
@@ -95,11 +115,14 @@ class OSSArraySectionExpr : public Expr {
95115
/// Set lower bound of the array section.
96116
void setLowerBound(Expr *E) { SubExprs[LOWER_BOUND] = E; }
97117

98-
/// Get length of array section.
99-
Expr *getLength() { return cast_or_null<Expr>(SubExprs[LENGTH]); }
100-
const Expr *getLength() const { return cast_or_null<Expr>(SubExprs[LENGTH]); }
101-
/// Set length of the array section.
102-
void setLength(Expr *E) { SubExprs[LENGTH] = E; }
118+
/// Get length or upper-bound of array section.
119+
Expr *getLengthUpper() { return cast_or_null<Expr>(SubExprs[LENGTH_UPPER]); }
120+
const Expr *getLengthUpper() const { return cast_or_null<Expr>(SubExprs[LENGTH_UPPER]); }
121+
/// Set length or upper-bound of the array section.
122+
void setLengthUpper(Expr *E) { SubExprs[LENGTH_UPPER] = E; }
123+
124+
// Get section form ';' or ':'
125+
bool isColonForm() const { return ColonForm; }
103126

104127
SourceLocation getBeginLoc() const LLVM_READONLY {
105128
return getBase()->getBeginLoc();

clang/include/clang/Basic/DiagnosticSemaKinds.td

+2
Original file line numberDiff line numberDiff line change
@@ -9920,6 +9920,8 @@ def err_oss_section_length_undefined : Error<
99209920
"section length is unspecified and cannot be inferred because subscripted value is %select{not an array|an array of unknown bound}0">;
99219921
def err_oss_section_only_one_pointer_level : Error<
99229922
"pointer types only allow one-level array sections">;
9923+
def err_oss_section_invalid_form : Error<
9924+
"array section form is not valid in 'depend' clause">;
99239925
def err_oss_typecheck_shaping_base_no_ptr_or_array: Error<
99249926
"shaping expression base is not a pointer or array">;
99259927
def err_oss_shape_incomplete_type : Error<

clang/include/clang/Sema/Sema.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -4557,7 +4557,8 @@ class Sema {
45574557
// OmpSs
45584558
ExprResult ActOnOSSArraySectionExpr(Expr *Base, SourceLocation LBLoc,
45594559
Expr *LowerBound, SourceLocation ColonLoc,
4560-
Expr *Length, SourceLocation RBLoc);
4560+
Expr *LengthUpper, SourceLocation RBLoc,
4561+
bool ColonForm = true);
45614562
ExprResult ActOnOSSArrayShapingExpr(Expr *Base, ArrayRef<Expr *> Shapes,
45624563
SourceLocation LBLoc,
45634564
SourceLocation RBLoc);

clang/lib/AST/StmtPrinter.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -1457,9 +1457,9 @@ void StmtPrinter::VisitOSSArraySectionExpr(OSSArraySectionExpr *Node) {
14571457
if (Node->getLowerBound())
14581458
PrintExpr(Node->getLowerBound());
14591459
if (Node->getColonLoc().isValid()) {
1460-
OS << ":";
1461-
if (Node->getLength())
1462-
PrintExpr(Node->getLength());
1460+
OS << (Node->isColonForm() ? ":" : ";");
1461+
if (Node->getLengthUpper())
1462+
PrintExpr(Node->getLengthUpper());
14631463
}
14641464
OS << "]";
14651465
}

clang/lib/CodeGen/CGOmpSsRuntime.cpp

+39-24
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ namespace {
4040
class OSSDependVisitor
4141
: public ConstStmtVisitor<OSSDependVisitor, void> {
4242
CodeGenFunction &CGF;
43+
bool OSSSyntax;
4344

4445
llvm::Type *OSSArgTy;
4546

@@ -51,8 +52,8 @@ class OSSDependVisitor
5152

5253
public:
5354

54-
OSSDependVisitor(CodeGenFunction &CGF)
55-
: CGF(CGF),
55+
OSSDependVisitor(CodeGenFunction &CGF, bool OSSSyntax)
56+
: CGF(CGF), OSSSyntax(OSSSyntax),
5657
OSSArgTy(CGF.ConvertType(CGF.getContext().LongTy))
5758
{}
5859

@@ -191,21 +192,35 @@ class OSSDependVisitor
191192
Idx = llvm::ConstantInt::getSigned(OSSArgTy, 0);
192193
Idx = CGF.Builder.CreateSExt(Idx, OSSArgTy);
193194

194-
const Expr *Size = ASE->getLength();
195-
if (Size) {
196-
IdxEnd = CGF.EmitScalarExpr(Size);
195+
const Expr *LengthUpper = ASE->getLengthUpper();
196+
bool ColonForm = ASE->isColonForm();
197+
if (LengthUpper &&
198+
(!OSSSyntax || (OSSSyntax && !ColonForm))) {
199+
// depend(in: array[ : length])
200+
// in(array[ ; length])
201+
IdxEnd = CGF.EmitScalarExpr(LengthUpper);
197202
IdxEnd = CGF.Builder.CreateSExt(IdxEnd, OSSArgTy);
198203
IdxEnd = CGF.Builder.CreateAdd(Idx, IdxEnd);
204+
} else if (LengthUpper
205+
&& (OSSSyntax && ColonForm)) {
206+
// in(array[ : upper])
207+
IdxEnd = CGF.EmitScalarExpr(LengthUpper);
208+
IdxEnd = CGF.Builder.CreateSExt(IdxEnd, OSSArgTy);
209+
IdxEnd = CGF.Builder.CreateAdd(llvm::ConstantInt::getSigned(OSSArgTy, 1), IdxEnd);
199210
} else if (ASE->getColonLoc().isInvalid()) {
200-
assert(!Size);
211+
assert(!LengthUpper);
201212
// OSSArraySection without ':' are regular array subscripts
202213
IdxEnd = CGF.Builder.CreateAdd(Idx, llvm::ConstantInt::getSigned(OSSArgTy, 1));
203214
} else {
204-
// array[lower : ] -> [lower, dimsize)
205215

206216
// OpenMP 5.0 2.1.5
217+
// depend(in: array[lower : ]) -> [lower, dimsize)
207218
// When the length is absent it defaults to ⌈(size - lowerbound)∕stride⌉,
208219
// where size is the size of the array dimension.
220+
//
221+
// OmpSs-2
222+
// in(array[lower ; ]) -> [lower, dimsize)
223+
// in(array[lower : ]) -> [lower, dimsize)
209224
QualType BaseOriginalTy =
210225
OSSArraySectionExpr::getBaseOriginalType(ASE->getBase());
211226

@@ -225,8 +240,8 @@ class OSSDependVisitor
225240
Ends.push_back(IdxEnd);
226241
// If we see a Pointer we must to add one dimension and done
227242
if (TmpE->IgnoreParenImpCasts()->getType()->isPointerType()) {
228-
assert(Size && "Sema should have forbidden unspecified sizes in pointers");
229-
Dims.push_back(CGF.Builder.CreateSExt(CGF.EmitScalarExpr(Size), OSSArgTy));
243+
assert(LengthUpper && "Sema should have forbidden unspecified sizes in pointers");
244+
Dims.push_back(CGF.Builder.CreateSExt(CGF.EmitScalarExpr(LengthUpper), OSSArgTy));
230245
break;
231246
}
232247
}
@@ -385,14 +400,14 @@ static void EmitDSA(StringRef Name, CodeGenFunction &CGF, const Expr *E,
385400
TaskInfo.emplace_back(Basename, DsaData);
386401
}
387402

388-
static void EmitDependency(StringRef Name, CodeGenFunction &CGF, const Expr *E,
403+
static void EmitDependency(StringRef Name, CodeGenFunction &CGF, const OSSDepDataTy &Dep,
389404
SmallVectorImpl<llvm::OperandBundleDef> &TaskInfo) {
390405

391406
// C long -> LLVM long
392407
llvm::Type *OSSArgTy = CGF.ConvertType(CGF.getContext().LongTy);
393408

394-
OSSDependVisitor DepVisitor(CGF);
395-
DepVisitor.Visit(E);
409+
OSSDependVisitor DepVisitor(CGF, Dep.OSSSyntax);
410+
DepVisitor.Visit(Dep.E);
396411

397412
SmallVector<llvm::Value*, 4> DepData;
398413

@@ -515,23 +530,23 @@ void CGOmpSsRuntime::emitTaskCall(CodeGenFunction &CGF,
515530
for (const Expr *E : Data.DSAs.Firstprivates) {
516531
EmitDSA("QUAL.OSS.FIRSTPRIVATE", CGF, E, TaskInfo);
517532
}
518-
for (const Expr *E : Data.Deps.Ins) {
519-
EmitDependency("QUAL.OSS.DEP.IN", CGF, E, TaskInfo);
533+
for (const OSSDepDataTy &Dep : Data.Deps.Ins) {
534+
EmitDependency("QUAL.OSS.DEP.IN", CGF, Dep, TaskInfo);
520535
}
521-
for (const Expr *E : Data.Deps.Outs) {
522-
EmitDependency("QUAL.OSS.DEP.OUT", CGF, E, TaskInfo);
536+
for (const OSSDepDataTy &Dep : Data.Deps.Outs) {
537+
EmitDependency("QUAL.OSS.DEP.OUT", CGF, Dep, TaskInfo);
523538
}
524-
for (const Expr *E : Data.Deps.Inouts) {
525-
EmitDependency("QUAL.OSS.DEP.INOUT", CGF, E, TaskInfo);
539+
for (const OSSDepDataTy &Dep : Data.Deps.Inouts) {
540+
EmitDependency("QUAL.OSS.DEP.INOUT", CGF, Dep, TaskInfo);
526541
}
527-
for (const Expr *E : Data.Deps.WeakIns) {
528-
EmitDependency("QUAL.OSS.DEP.WEAKIN", CGF, E, TaskInfo);
542+
for (const OSSDepDataTy &Dep : Data.Deps.WeakIns) {
543+
EmitDependency("QUAL.OSS.DEP.WEAKIN", CGF, Dep, TaskInfo);
529544
}
530-
for (const Expr *E : Data.Deps.WeakOuts) {
531-
EmitDependency("QUAL.OSS.DEP.WEAKOUT", CGF, E, TaskInfo);
545+
for (const OSSDepDataTy &Dep : Data.Deps.WeakOuts) {
546+
EmitDependency("QUAL.OSS.DEP.WEAKOUT", CGF, Dep, TaskInfo);
532547
}
533-
for (const Expr *E : Data.Deps.WeakInouts) {
534-
EmitDependency("QUAL.OSS.DEP.WEAKINOUT", CGF, E, TaskInfo);
548+
for (const OSSDepDataTy &Dep : Data.Deps.WeakInouts) {
549+
EmitDependency("QUAL.OSS.DEP.WEAKINOUT", CGF, Dep, TaskInfo);
535550
}
536551
if (Data.If)
537552
TaskInfo.emplace_back("QUAL.OSS.IF", CGF.EvaluateExprAsBool(Data.If));

clang/lib/CodeGen/CGOmpSsRuntime.h

+15-10
Original file line numberDiff line numberDiff line change
@@ -32,24 +32,29 @@ class Address;
3232
class CodeGenFunction;
3333
class CodeGenModule;
3434

35-
struct OSSDSADataTy final {
35+
struct OSSTaskDSADataTy final {
3636
SmallVector<const Expr *, 4> Shareds;
3737
SmallVector<const Expr *, 4> Privates;
3838
SmallVector<const Expr *, 4> Firstprivates;
3939
};
4040

41-
struct OSSDepDataTy final {
42-
SmallVector<const Expr *, 4> WeakIns;
43-
SmallVector<const Expr *, 4> WeakOuts;
44-
SmallVector<const Expr *, 4> WeakInouts;
45-
SmallVector<const Expr *, 4> Ins;
46-
SmallVector<const Expr *, 4> Outs;
47-
SmallVector<const Expr *, 4> Inouts;
41+
struct OSSDepDataTy {
42+
bool OSSSyntax;
43+
const Expr *E;
44+
};
45+
46+
struct OSSTaskDepDataTy final {
47+
SmallVector<OSSDepDataTy, 4> WeakIns;
48+
SmallVector<OSSDepDataTy, 4> WeakOuts;
49+
SmallVector<OSSDepDataTy, 4> WeakInouts;
50+
SmallVector<OSSDepDataTy, 4> Ins;
51+
SmallVector<OSSDepDataTy, 4> Outs;
52+
SmallVector<OSSDepDataTy, 4> Inouts;
4853
};
4954

5055
struct OSSTaskDataTy final {
51-
OSSDSADataTy DSAs;
52-
OSSDepDataTy Deps;
56+
OSSTaskDSADataTy DSAs;
57+
OSSTaskDepDataTy Deps;
5358
const Expr *If = nullptr;
5459
const Expr *Final = nullptr;
5560
};

clang/lib/CodeGen/CGStmtOmpSs.cpp

+8-8
Original file line numberDiff line numberDiff line change
@@ -44,36 +44,36 @@ static void AddDSAData(const OSSTaskDirective &S, SmallVectorImpl<const Expr *>
4444
}
4545
}
4646

47-
static void AddDSAData(const OSSTaskDirective &S, OSSDSADataTy &DSAs) {
47+
static void AddDSAData(const OSSTaskDirective &S, OSSTaskDSADataTy &DSAs) {
4848
AddDSAData<OSSSharedClause>(S, DSAs.Shareds);
4949
AddDSAData<OSSPrivateClause>(S, DSAs.Privates);
5050
AddDSAData<OSSFirstprivateClause>(S, DSAs.Firstprivates);
5151
};
5252

53-
static void AddDepData(const OSSTaskDirective &S, OSSDepDataTy &Deps) {
53+
static void AddDepData(const OSSTaskDirective &S, OSSTaskDepDataTy &Deps) {
5454
for (const auto *C : S.getClausesOfKind<OSSDependClause>()) {
5555
ArrayRef<OmpSsDependClauseKind> DepKinds = C->getDependencyKind();
5656
if (DepKinds.size() == 2) {
5757
for (const Expr *Ref : C->varlists()) {
5858
if (DepKinds[0] == OSSC_DEPEND_in
5959
|| DepKinds[1] == OSSC_DEPEND_in)
60-
Deps.WeakIns.push_back(Ref);
60+
Deps.WeakIns.push_back({C->isOSSSyntax(), Ref});
6161
if (DepKinds[0] == OSSC_DEPEND_out
6262
|| DepKinds[1] == OSSC_DEPEND_out)
63-
Deps.WeakOuts.push_back(Ref);
63+
Deps.WeakOuts.push_back({C->isOSSSyntax(), Ref});
6464
if (DepKinds[0] == OSSC_DEPEND_inout
6565
|| DepKinds[1] == OSSC_DEPEND_inout)
66-
Deps.WeakInouts.push_back(Ref);
66+
Deps.WeakInouts.push_back({C->isOSSSyntax(), Ref});
6767
}
6868
}
6969
else {
7070
for (const Expr *Ref : C->varlists()) {
7171
if (DepKinds[0] == OSSC_DEPEND_in)
72-
Deps.Ins.push_back(Ref);
72+
Deps.Ins.push_back({C->isOSSSyntax(), Ref});
7373
if (DepKinds[0] == OSSC_DEPEND_out)
74-
Deps.Outs.push_back(Ref);
74+
Deps.Outs.push_back({C->isOSSSyntax(), Ref});
7575
if (DepKinds[0] == OSSC_DEPEND_inout)
76-
Deps.Inouts.push_back(Ref);
76+
Deps.Inouts.push_back({C->isOSSSyntax(), Ref});
7777
}
7878
}
7979
}

0 commit comments

Comments
 (0)