Skip to content

Commit 8256e93

Browse files
committed
[NFC][Clang] Add helper functions/utils for finding/comparing attach base-ptrs.
These have been pulled out of the codegen PR #153683, to reduce the size of that PR.
1 parent bb1cb6a commit 8256e93

File tree

5 files changed

+534
-0
lines changed

5 files changed

+534
-0
lines changed

clang/include/clang/AST/OpenMPClause.h

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

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

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

clang/include/clang/Basic/OpenMPKinds.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,14 @@ bool isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind);
301301
/// otherwise - false.
302302
bool isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind);
303303

304+
/// Checks if the specified directive is a map-entering target directive.
305+
/// \param DKind Specified directive.
306+
/// \return true - the directive is a map-entering target directive like
307+
/// 'omp target', 'omp target data', 'omp target enter data',
308+
/// 'omp target parallel', etc. (excludes 'omp target exit data', 'omp target
309+
/// update') otherwise - false.
310+
bool isOpenMPTargetMapEnteringDirective(OpenMPDirectiveKind DKind);
311+
304312
/// Checks if the specified composite/combined directive constitutes a teams
305313
/// directive in the outermost nest. For example
306314
/// 'omp teams distribute' or 'omp teams distribute parallel for'.

clang/lib/AST/OpenMPClause.cpp

Lines changed: 68 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"
@@ -1156,6 +1157,73 @@ unsigned OMPClauseMappableExprCommon::getUniqueDeclarationsTotalNumber(
11561157
return UniqueDecls.size();
11571158
}
11581159

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

clang/lib/Basic/OpenMPKinds.cpp

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

653+
bool clang::isOpenMPTargetMapEnteringDirective(OpenMPDirectiveKind DKind) {
654+
return DKind == OMPD_target_data || DKind == OMPD_target_enter_data ||
655+
isOpenMPTargetExecutionDirective(DKind);
656+
}
657+
653658
bool clang::isOpenMPNestingTeamsDirective(OpenMPDirectiveKind DKind) {
654659
if (DKind == OMPD_teams)
655660
return true;

0 commit comments

Comments
 (0)