Skip to content

Commit a65017e

Browse files
abhinavgabamahesh-attarde
authored andcommitted
[NFC][Clang][OpenMP] Add helper functions/utils for finding/comparing attach base-ptrs. (llvm#155625)
These have been pulled out of the codegen PR llvm#153683, to reduce the size of that PR.
1 parent 3b0b0e9 commit a65017e

File tree

5 files changed

+572
-0
lines changed

5 files changed

+572
-0
lines changed

clang/include/clang/AST/OpenMPClause.h

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5816,6 +5816,12 @@ class OMPClauseMappableExprCommon {
58165816
ValueDecl *getAssociatedDeclaration() const {
58175817
return AssociatedDeclaration;
58185818
}
5819+
5820+
bool operator==(const MappableComponent &Other) const {
5821+
return AssociatedExpressionNonContiguousPr ==
5822+
Other.AssociatedExpressionNonContiguousPr &&
5823+
AssociatedDeclaration == Other.AssociatedDeclaration;
5824+
}
58195825
};
58205826

58215827
// List of components of an expression. This first one is the whole
@@ -5829,6 +5835,95 @@ class OMPClauseMappableExprCommon {
58295835
using MappableExprComponentLists = SmallVector<MappableExprComponentList, 8>;
58305836
using MappableExprComponentListsRef = ArrayRef<MappableExprComponentList>;
58315837

5838+
// Hash function to allow usage as DenseMap keys.
5839+
friend llvm::hash_code hash_value(const MappableComponent &MC) {
5840+
return llvm::hash_combine(MC.getAssociatedExpression(),
5841+
MC.getAssociatedDeclaration(),
5842+
MC.isNonContiguous());
5843+
}
5844+
5845+
public:
5846+
/// Get the type of an element of a ComponentList Expr \p Exp.
5847+
///
5848+
/// For something like the following:
5849+
/// ```c
5850+
/// int *p, **p;
5851+
/// ```
5852+
/// The types for the following Exprs would be:
5853+
/// Expr | Type
5854+
/// ---------|-----------
5855+
/// p | int *
5856+
/// *p | int
5857+
/// p[0] | int
5858+
/// p[0:1] | int
5859+
/// pp | int **
5860+
/// pp[0] | int *
5861+
/// pp[0:1] | int *
5862+
/// Note: this assumes that if \p Exp is an array-section, it is contiguous.
5863+
static QualType getComponentExprElementType(const Expr *Exp);
5864+
5865+
/// Find the attach pointer expression from a list of mappable expression
5866+
/// components.
5867+
///
5868+
/// This function traverses the component list to find the first
5869+
/// expression that has a pointer type, which represents the attach
5870+
/// base pointer expr for the current component-list.
5871+
///
5872+
/// For example, given the following:
5873+
///
5874+
/// ```c
5875+
/// struct S {
5876+
/// int a;
5877+
/// int b[10];
5878+
/// int c[10][10];
5879+
/// int *p;
5880+
/// int **pp;
5881+
/// }
5882+
/// S s, *ps, **pps, *(pas[10]), ***ppps;
5883+
/// int i;
5884+
/// ```
5885+
///
5886+
/// The base-pointers for the following map operands would be:
5887+
/// map list-item | attach base-pointer | attach base-pointer
5888+
/// | for directives except | target_update (if
5889+
/// | target_update | different)
5890+
/// ----------------|-----------------------|---------------------
5891+
/// s | N/A |
5892+
/// s.a | N/A |
5893+
/// s.p | N/A |
5894+
/// ps | N/A |
5895+
/// ps->p | ps |
5896+
/// ps[1] | ps |
5897+
/// *(ps + 1) | ps |
5898+
/// (ps + 1)[1] | ps |
5899+
/// ps[1:10] | ps |
5900+
/// ps->b[10] | ps |
5901+
/// ps->p[10] | ps->p |
5902+
/// ps->c[1][2] | ps |
5903+
/// ps->c[1:2][2] | (error diagnostic) | N/A, TODO: ps
5904+
/// ps->c[1:1][2] | ps | N/A, TODO: ps
5905+
/// pps[1][2] | pps[1] |
5906+
/// pps[1:1][2] | pps[1:1] | N/A, TODO: pps[1:1]
5907+
/// pps[1:i][2] | pps[1:i] | N/A, TODO: pps[1:i]
5908+
/// pps[1:2][2] | (error diagnostic) | N/A
5909+
/// pps[1]->p | pps[1] |
5910+
/// pps[1]->p[10] | pps[1] |
5911+
/// pas[1] | N/A |
5912+
/// pas[1][2] | pas[1] |
5913+
/// ppps[1][2] | ppps[1] |
5914+
/// ppps[1][2][3] | ppps[1][2] |
5915+
/// ppps[1][2:1][3] | ppps[1][2:1] | N/A, TODO: ppps[1][2:1]
5916+
/// ppps[1][2:2][3] | (error diagnostic) | N/A
5917+
/// Returns a pair of the attach pointer expression and its depth in the
5918+
/// component list.
5919+
/// TODO: This may need to be updated to handle ref_ptr/ptee cases for byref
5920+
/// map operands.
5921+
/// TODO: Handle cases for target-update, where the list-item is a
5922+
/// non-contiguous array-section that still has a base-pointer.
5923+
static std::pair<const Expr *, std::optional<size_t>>
5924+
findAttachPtrExpr(MappableExprComponentListRef Components,
5925+
OpenMPDirectiveKind CurDirKind);
5926+
58325927
protected:
58335928
// Return the total number of elements in a list of component lists.
58345929
static unsigned

clang/include/clang/Basic/OpenMPKinds.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,14 @@ bool isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind);
312312
/// otherwise - false.
313313
bool isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind);
314314

315+
/// Checks if the specified directive is a map-entering target directive.
316+
/// \param DKind Specified directive.
317+
/// \return true - the directive is a map-entering target directive like
318+
/// 'omp target', 'omp target data', 'omp target enter data',
319+
/// 'omp target parallel', etc. (excludes 'omp target exit data', 'omp target
320+
/// update') otherwise - false.
321+
bool isOpenMPTargetMapEnteringDirective(OpenMPDirectiveKind DKind);
322+
315323
/// Checks if the specified composite/combined directive constitutes a teams
316324
/// directive in the outermost nest. For example
317325
/// 'omp teams distribute' or 'omp teams distribute parallel for'.

clang/lib/AST/OpenMPClause.cpp

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "clang/AST/Attr.h"
1616
#include "clang/AST/Decl.h"
1717
#include "clang/AST/DeclOpenMP.h"
18+
#include "clang/AST/ExprOpenMP.h"
1819
#include "clang/Basic/LLVM.h"
1920
#include "clang/Basic/OpenMPKinds.h"
2021
#include "clang/Basic/TargetInfo.h"
@@ -1159,6 +1160,77 @@ unsigned OMPClauseMappableExprCommon::getUniqueDeclarationsTotalNumber(
11591160
return UniqueDecls.size();
11601161
}
11611162

1163+
QualType
1164+
OMPClauseMappableExprCommon::getComponentExprElementType(const Expr *Exp) {
1165+
assert(!isa<OMPArrayShapingExpr>(Exp) &&
1166+
"Cannot get element-type from array-shaping expr.");
1167+
1168+
// Unless we are handling array-section expressions, including
1169+
// array-subscripts, derefs, we can rely on getType.
1170+
if (!isa<ArraySectionExpr>(Exp))
1171+
return Exp->getType().getNonReferenceType().getCanonicalType();
1172+
1173+
// For array-sections, we need to find the type of one element of
1174+
// the section.
1175+
const auto *OASE = cast<ArraySectionExpr>(Exp);
1176+
1177+
QualType BaseType = ArraySectionExpr::getBaseOriginalType(OASE->getBase());
1178+
1179+
QualType ElemTy;
1180+
if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
1181+
ElemTy = ATy->getElementType();
1182+
else
1183+
ElemTy = BaseType->getPointeeType();
1184+
1185+
ElemTy = ElemTy.getNonReferenceType().getCanonicalType();
1186+
return ElemTy;
1187+
}
1188+
1189+
std::pair<const Expr *, std::optional<size_t>>
1190+
OMPClauseMappableExprCommon::findAttachPtrExpr(
1191+
MappableExprComponentListRef Components, OpenMPDirectiveKind CurDirKind) {
1192+
1193+
// If we only have a single component, we have a map like "map(p)", which
1194+
// cannot have a base-pointer.
1195+
if (Components.size() < 2)
1196+
return {nullptr, std::nullopt};
1197+
1198+
// Only check for non-contiguous sections on target_update, since we can
1199+
// assume array-sections are contiguous on maps on other constructs, even if
1200+
// we are not sure of it at compile-time, like for a[1:x][2].
1201+
if (Components.back().isNonContiguous() && CurDirKind == OMPD_target_update)
1202+
return {nullptr, std::nullopt};
1203+
1204+
// To find the attach base-pointer, we start with the second component,
1205+
// stripping away one component at a time, until we reach a pointer Expr
1206+
// (that is not a binary operator). The first such pointer should be the
1207+
// attach base-pointer for the component list.
1208+
for (auto [I, Component] : llvm::enumerate(Components)) {
1209+
// Skip past the first component.
1210+
if (I == 0)
1211+
continue;
1212+
1213+
const Expr *CurExpr = Component.getAssociatedExpression();
1214+
if (!CurExpr)
1215+
break;
1216+
1217+
// If CurExpr is something like `p + 10`, we need to ignore it, since
1218+
// we are looking for `p`.
1219+
if (isa<BinaryOperator>(CurExpr))
1220+
continue;
1221+
1222+
// Keep going until we reach an Expr of pointer type.
1223+
QualType CurType = getComponentExprElementType(CurExpr);
1224+
if (!CurType->isPointerType())
1225+
continue;
1226+
1227+
// We have found a pointer Expr. This must be the attach pointer.
1228+
return {CurExpr, Components.size() - I};
1229+
}
1230+
1231+
return {nullptr, std::nullopt};
1232+
}
1233+
11621234
OMPMapClause *OMPMapClause::Create(
11631235
const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
11641236
ArrayRef<ValueDecl *> Declarations,

clang/lib/Basic/OpenMPKinds.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,11 @@ bool clang::isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind) {
677677
DKind == OMPD_target_exit_data || DKind == OMPD_target_update;
678678
}
679679

680+
bool clang::isOpenMPTargetMapEnteringDirective(OpenMPDirectiveKind DKind) {
681+
return DKind == OMPD_target_data || DKind == OMPD_target_enter_data ||
682+
isOpenMPTargetExecutionDirective(DKind);
683+
}
684+
680685
bool clang::isOpenMPNestingTeamsDirective(OpenMPDirectiveKind DKind) {
681686
if (DKind == OMPD_teams)
682687
return true;

0 commit comments

Comments
 (0)