Skip to content

Commit 39adc8f

Browse files
authored
[NFC] Generalize ArraySections to work for OpenACC in the future (#89639)
OpenACC is going to need an array sections implementation that is a simpler version/more restrictive version of the OpenMP version. This patch moves `OMPArraySectionExpr` to `Expr.h` and renames it `ArraySectionExpr`, then adds an enum to choose between the two. This also fixes a couple of 'drive-by' issues that I discovered on the way, but leaves the OpenACC Sema parts reasonably unimplemented (no semantic analysis implementation), as that will be a followup patch.
1 parent 8dc7db7 commit 39adc8f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+513
-296
lines changed

clang/include/clang-c/Index.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1644,8 +1644,9 @@ enum CXCursorKind {
16441644
CXCursor_ObjCSelfExpr = 146,
16451645

16461646
/** OpenMP 5.0 [2.1.5, Array Section].
1647+
* OpenACC 3.3 [2.7.1, Data Specification for Data Clauses (Sub Arrays)]
16471648
*/
1648-
CXCursor_OMPArraySectionExpr = 147,
1649+
CXCursor_ArraySectionExpr = 147,
16491650

16501651
/** Represents an @available(...) check.
16511652
*/

clang/include/clang/AST/ASTContext.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1127,7 +1127,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
11271127
CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy;
11281128
CanQualType OCLQueueTy, OCLReserveIDTy;
11291129
CanQualType IncompleteMatrixIdxTy;
1130-
CanQualType OMPArraySectionTy, OMPArrayShapingTy, OMPIteratorTy;
1130+
CanQualType ArraySectionTy;
1131+
CanQualType OMPArrayShapingTy, OMPIteratorTy;
11311132
#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
11321133
CanQualType Id##Ty;
11331134
#include "clang/Basic/OpenCLExtensionTypes.def"

clang/include/clang/AST/BuiltinTypes.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ PLACEHOLDER_TYPE(ARCUnbridgedCast, ARCUnbridgedCastTy)
320320
PLACEHOLDER_TYPE(IncompleteMatrixIdx, IncompleteMatrixIdxTy)
321321

322322
// A placeholder type for OpenMP array sections.
323-
PLACEHOLDER_TYPE(OMPArraySection, OMPArraySectionTy)
323+
PLACEHOLDER_TYPE(ArraySection, ArraySectionTy)
324324

325325
// A placeholder type for OpenMP array shaping operation.
326326
PLACEHOLDER_TYPE(OMPArrayShaping, OMPArrayShapingTy)

clang/include/clang/AST/ComputeDependence.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ class DesignatedInitExpr;
9494
class ParenListExpr;
9595
class PseudoObjectExpr;
9696
class AtomicExpr;
97-
class OMPArraySectionExpr;
97+
class ArraySectionExpr;
9898
class OMPArrayShapingExpr;
9999
class OMPIteratorExpr;
100100
class ObjCArrayLiteral;
@@ -189,7 +189,7 @@ ExprDependence computeDependence(ParenListExpr *E);
189189
ExprDependence computeDependence(PseudoObjectExpr *E);
190190
ExprDependence computeDependence(AtomicExpr *E);
191191

192-
ExprDependence computeDependence(OMPArraySectionExpr *E);
192+
ExprDependence computeDependence(ArraySectionExpr *E);
193193
ExprDependence computeDependence(OMPArrayShapingExpr *E);
194194
ExprDependence computeDependence(OMPIteratorExpr *E);
195195

clang/include/clang/AST/Expr.h

Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6610,6 +6610,275 @@ class TypoExpr : public Expr {
66106610

66116611
};
66126612

6613+
/// This class represents BOTH the OpenMP Array Section and OpenACC 'subarray',
6614+
/// with a boolean differentiator.
6615+
/// OpenMP 5.0 [2.1.5, Array Sections].
6616+
/// To specify an array section in an OpenMP construct, array subscript
6617+
/// expressions are extended with the following syntax:
6618+
/// \code
6619+
/// [ lower-bound : length : stride ]
6620+
/// [ lower-bound : length : ]
6621+
/// [ lower-bound : length ]
6622+
/// [ lower-bound : : stride ]
6623+
/// [ lower-bound : : ]
6624+
/// [ lower-bound : ]
6625+
/// [ : length : stride ]
6626+
/// [ : length : ]
6627+
/// [ : length ]
6628+
/// [ : : stride ]
6629+
/// [ : : ]
6630+
/// [ : ]
6631+
/// \endcode
6632+
/// The array section must be a subset of the original array.
6633+
/// Array sections are allowed on multidimensional arrays. Base language array
6634+
/// subscript expressions can be used to specify length-one dimensions of
6635+
/// multidimensional array sections.
6636+
/// Each of the lower-bound, length, and stride expressions if specified must be
6637+
/// an integral type expressions of the base language. When evaluated
6638+
/// they represent a set of integer values as follows:
6639+
/// \code
6640+
/// { lower-bound, lower-bound + stride, lower-bound + 2 * stride,... ,
6641+
/// lower-bound + ((length - 1) * stride) }
6642+
/// \endcode
6643+
/// The lower-bound and length must evaluate to non-negative integers.
6644+
/// The stride must evaluate to a positive integer.
6645+
/// When the size of the array dimension is not known, the length must be
6646+
/// specified explicitly.
6647+
/// When the stride is absent it defaults to 1.
6648+
/// When the length is absent it defaults to ⌈(size − lower-bound)/stride⌉,
6649+
/// where size is the size of the array dimension. When the lower-bound is
6650+
/// absent it defaults to 0.
6651+
///
6652+
///
6653+
/// OpenACC 3.3 [2.7.1 Data Specification in Data Clauses]
6654+
/// In C and C++, a subarray is an array name followed by an extended array
6655+
/// range specification in brackets, with start and length, such as
6656+
///
6657+
/// AA[2:n]
6658+
///
6659+
/// If the lower bound is missing, zero is used. If the length is missing and
6660+
/// the array has known size, the size of the array is used; otherwise the
6661+
/// length is required. The subarray AA[2:n] means elements AA[2], AA[3], . . .
6662+
/// , AA[2+n-1]. In C and C++, a two dimensional array may be declared in at
6663+
/// least four ways:
6664+
///
6665+
/// -Statically-sized array: float AA[100][200];
6666+
/// -Pointer to statically sized rows: typedef float row[200]; row* BB;
6667+
/// -Statically-sized array of pointers: float* CC[200];
6668+
/// -Pointer to pointers: float** DD;
6669+
///
6670+
/// Each dimension may be statically sized, or a pointer to dynamically
6671+
/// allocated memory. Each of these may be included in a data clause using
6672+
/// subarray notation to specify a rectangular array:
6673+
///
6674+
/// -AA[2:n][0:200]
6675+
/// -BB[2:n][0:m]
6676+
/// -CC[2:n][0:m]
6677+
/// -DD[2:n][0:m]
6678+
///
6679+
/// Multidimensional rectangular subarrays in C and C++ may be specified for any
6680+
/// array with any combination of statically-sized or dynamically-allocated
6681+
/// dimensions. For statically sized dimensions, all dimensions except the first
6682+
/// must specify the whole extent to preserve the contiguous data restriction,
6683+
/// discussed below. For dynamically allocated dimensions, the implementation
6684+
/// will allocate pointers in device memory corresponding to the pointers in
6685+
/// local memory and will fill in those pointers as appropriate.
6686+
///
6687+
/// In Fortran, a subarray is an array name followed by a comma-separated list
6688+
/// of range specifications in parentheses, with lower and upper bound
6689+
/// subscripts, such as
6690+
///
6691+
/// arr(1:high,low:100)
6692+
///
6693+
/// If either the lower or upper bounds are missing, the declared or allocated
6694+
/// bounds of the array, if known, are used. All dimensions except the last must
6695+
/// specify the whole extent, to preserve the contiguous data restriction,
6696+
/// discussed below.
6697+
///
6698+
/// Restrictions
6699+
///
6700+
/// -In Fortran, the upper bound for the last dimension of an assumed-size dummy
6701+
/// array must be specified.
6702+
///
6703+
/// -In C and C++, the length for dynamically allocated dimensions of an array
6704+
/// must be explicitly specified.
6705+
///
6706+
/// -In C and C++, modifying pointers in pointer arrays during the data
6707+
/// lifetime, either on the host or on the device, may result in undefined
6708+
/// behavior.
6709+
///
6710+
/// -If a subarray appears in a data clause, the implementation may choose to
6711+
/// allocate memory for only that subarray on the accelerator.
6712+
///
6713+
/// -In Fortran, array pointers may appear, but pointer association is not
6714+
/// preserved in device memory.
6715+
///
6716+
/// -Any array or subarray in a data clause, including Fortran array pointers,
6717+
/// must be a contiguous section of memory, except for dynamic multidimensional
6718+
/// C arrays.
6719+
///
6720+
/// -In C and C++, if a variable or array of composite type appears, all the
6721+
/// data members of the struct or class are allocated and copied, as
6722+
/// appropriate. If a composite member is a pointer type, the data addressed by
6723+
/// that pointer are not implicitly copied.
6724+
///
6725+
/// -In Fortran, if a variable or array of composite type appears, all the
6726+
/// members of that derived type are allocated and copied, as appropriate. If
6727+
/// any member has the allocatable or pointer attribute, the data accessed
6728+
/// through that member are not copied.
6729+
///
6730+
/// -If an expression is used in a subscript or subarray expression in a clause
6731+
/// on a data construct, the same value is used when copying data at the end of
6732+
/// the data region, even if the values of variables in the expression change
6733+
/// during the data region.
6734+
class ArraySectionExpr : public Expr {
6735+
friend class ASTStmtReader;
6736+
friend class ASTStmtWriter;
6737+
6738+
public:
6739+
enum ArraySectionType { OMPArraySection, OpenACCArraySection };
6740+
6741+
private:
6742+
enum {
6743+
BASE,
6744+
LOWER_BOUND,
6745+
LENGTH,
6746+
STRIDE,
6747+
END_EXPR,
6748+
OPENACC_END_EXPR = STRIDE
6749+
};
6750+
6751+
ArraySectionType ASType = OMPArraySection;
6752+
Stmt *SubExprs[END_EXPR] = {nullptr};
6753+
SourceLocation ColonLocFirst;
6754+
SourceLocation ColonLocSecond;
6755+
SourceLocation RBracketLoc;
6756+
6757+
public:
6758+
// Constructor for OMP array sections, which include a 'stride'.
6759+
ArraySectionExpr(Expr *Base, Expr *LowerBound, Expr *Length, Expr *Stride,
6760+
QualType Type, ExprValueKind VK, ExprObjectKind OK,
6761+
SourceLocation ColonLocFirst, SourceLocation ColonLocSecond,
6762+
SourceLocation RBracketLoc)
6763+
: Expr(ArraySectionExprClass, Type, VK, OK), ASType(OMPArraySection),
6764+
ColonLocFirst(ColonLocFirst), ColonLocSecond(ColonLocSecond),
6765+
RBracketLoc(RBracketLoc) {
6766+
setBase(Base);
6767+
setLowerBound(LowerBound);
6768+
setLength(Length);
6769+
setStride(Stride);
6770+
setDependence(computeDependence(this));
6771+
}
6772+
6773+
// Constructor for OpenACC sub-arrays, which do not permit a 'stride'.
6774+
ArraySectionExpr(Expr *Base, Expr *LowerBound, Expr *Length, QualType Type,
6775+
ExprValueKind VK, ExprObjectKind OK, SourceLocation ColonLoc,
6776+
SourceLocation RBracketLoc)
6777+
: Expr(ArraySectionExprClass, Type, VK, OK), ASType(OpenACCArraySection),
6778+
ColonLocFirst(ColonLoc), RBracketLoc(RBracketLoc) {
6779+
setBase(Base);
6780+
setLowerBound(LowerBound);
6781+
setLength(Length);
6782+
setDependence(computeDependence(this));
6783+
}
6784+
6785+
/// Create an empty array section expression.
6786+
explicit ArraySectionExpr(EmptyShell Shell)
6787+
: Expr(ArraySectionExprClass, Shell) {}
6788+
6789+
/// Return original type of the base expression for array section.
6790+
static QualType getBaseOriginalType(const Expr *Base);
6791+
6792+
static bool classof(const Stmt *T) {
6793+
return T->getStmtClass() == ArraySectionExprClass;
6794+
}
6795+
6796+
bool isOMPArraySection() const { return ASType == OMPArraySection; }
6797+
bool isOpenACCArraySection() const { return ASType == OpenACCArraySection; }
6798+
6799+
/// Get base of the array section.
6800+
Expr *getBase() { return cast<Expr>(SubExprs[BASE]); }
6801+
const Expr *getBase() const { return cast<Expr>(SubExprs[BASE]); }
6802+
6803+
/// Get lower bound of array section.
6804+
Expr *getLowerBound() { return cast_or_null<Expr>(SubExprs[LOWER_BOUND]); }
6805+
const Expr *getLowerBound() const {
6806+
return cast_or_null<Expr>(SubExprs[LOWER_BOUND]);
6807+
}
6808+
6809+
/// Get length of array section.
6810+
Expr *getLength() { return cast_or_null<Expr>(SubExprs[LENGTH]); }
6811+
const Expr *getLength() const { return cast_or_null<Expr>(SubExprs[LENGTH]); }
6812+
6813+
/// Get stride of array section.
6814+
Expr *getStride() {
6815+
assert(ASType != OpenACCArraySection &&
6816+
"Stride not valid in OpenACC subarrays");
6817+
return cast_or_null<Expr>(SubExprs[STRIDE]);
6818+
}
6819+
6820+
const Expr *getStride() const {
6821+
assert(ASType != OpenACCArraySection &&
6822+
"Stride not valid in OpenACC subarrays");
6823+
return cast_or_null<Expr>(SubExprs[STRIDE]);
6824+
}
6825+
6826+
SourceLocation getBeginLoc() const LLVM_READONLY {
6827+
return getBase()->getBeginLoc();
6828+
}
6829+
SourceLocation getEndLoc() const LLVM_READONLY { return RBracketLoc; }
6830+
6831+
SourceLocation getColonLocFirst() const { return ColonLocFirst; }
6832+
SourceLocation getColonLocSecond() const {
6833+
assert(ASType != OpenACCArraySection &&
6834+
"second colon for stride not valid in OpenACC subarrays");
6835+
return ColonLocSecond;
6836+
}
6837+
SourceLocation getRBracketLoc() const { return RBracketLoc; }
6838+
6839+
SourceLocation getExprLoc() const LLVM_READONLY {
6840+
return getBase()->getExprLoc();
6841+
}
6842+
6843+
child_range children() {
6844+
return child_range(
6845+
&SubExprs[BASE],
6846+
&SubExprs[ASType == OMPArraySection ? END_EXPR : OPENACC_END_EXPR]);
6847+
}
6848+
6849+
const_child_range children() const {
6850+
return const_child_range(
6851+
&SubExprs[BASE],
6852+
&SubExprs[ASType == OMPArraySection ? END_EXPR : OPENACC_END_EXPR]);
6853+
}
6854+
6855+
private:
6856+
/// Set base of the array section.
6857+
void setBase(Expr *E) { SubExprs[BASE] = E; }
6858+
6859+
/// Set lower bound of the array section.
6860+
void setLowerBound(Expr *E) { SubExprs[LOWER_BOUND] = E; }
6861+
6862+
/// Set length of the array section.
6863+
void setLength(Expr *E) { SubExprs[LENGTH] = E; }
6864+
6865+
/// Set length of the array section.
6866+
void setStride(Expr *E) {
6867+
assert(ASType != OpenACCArraySection &&
6868+
"Stride not valid in OpenACC subarrays");
6869+
SubExprs[STRIDE] = E;
6870+
}
6871+
6872+
void setColonLocFirst(SourceLocation L) { ColonLocFirst = L; }
6873+
6874+
void setColonLocSecond(SourceLocation L) {
6875+
assert(ASType != OpenACCArraySection &&
6876+
"second colon for stride not valid in OpenACC subarrays");
6877+
ColonLocSecond = L;
6878+
}
6879+
void setRBracketLoc(SourceLocation L) { RBracketLoc = L; }
6880+
};
6881+
66136882
/// Frontend produces RecoveryExprs on semantic errors that prevent creating
66146883
/// other well-formed expressions. E.g. when type-checking of a binary operator
66156884
/// fails, we cannot produce a BinaryOperator expression. Instead, we can choose

0 commit comments

Comments
 (0)