[clang] [llvm] [Clang][OpenMP] Capture mapped pointers on `target` by reference. (PR #145454)

Abhinav Gaba via cfe-commits cfe-commits at lists.llvm.org
Thu Jun 26 07:22:22 PDT 2025


================
@@ -8811,8 +8829,19 @@ class MappableExprsHandler {
         ++EI;
       }
     }
-    llvm::stable_sort(DeclComponentLists, [](const MapData &LHS,
-                                             const MapData &RHS) {
+    llvm::stable_sort(DeclComponentLists, [VD](const MapData &LHS,
+                                               const MapData &RHS) {
+      // For cases like map(p, p[0], p[0][0]), the shortest map, like map(p)
----------------
abhinavgaba wrote:

Looks like this is not sufficient for cases like `map(sp, sp->x)`. In that case, the problem is that sp->x populates PartialStruct in https://github.com/llvm/llvm-project/blob/90f3147424a36652dae51aa690d9948117f8d906/clang/lib/CodeGen/CGOpenMPRuntime.cpp#L8985-L8990,

And even though initially after going through generateInfoFroCapture, `map(sp)` occupies the top of the map-chain in CurInfo:

```
&sp, &sp, sizeof(sp), TO | PARAM
&sp[0], &sp->x, sizeof(sp->x), TO
```

After, emitCombinedEntry, a new entry gets added for:
```
&sp[0], &sp[0], sizeof(sp[0]), ALLOC | PARAM
```
and all existing entries in CurInfo get the MEMBER_OF(1) bit applied to them.

https://github.com/llvm/llvm-project/blob/90f3147424a36652dae51aa690d9948117f8d906/clang/lib/CodeGen/CGOpenMPRuntime.cpp#L9516

So the final CombinedInfo after emitCombinedEntry and then appending CurInfo to it becomes:

```
&sp[0], &sp[0], sizeof(sp[0]), ALLOC | PARAM
&sp, &sp, sizeof(sp), TO | MEMBER_OF(1)
&sp[0], &sp->x, sizeof(sp->x), TO | MEMBER_OF(1)
```

instead of the desired:

```
&sp, &sp, sizeof(sp), TO | PARAM
&sp[0], &sp[0], sizeof(sp[0]), ALLOC
&sp[0], &sp->x, sizeof(sp->x), TO | MEMBER_OF(2)
```

(Note that this &sp getting MEMBER_OF(1) issue currently exists on target enter data as well.)

Maybe we can split up https://github.com/llvm/llvm-project/blob/90f3147424a36652dae51aa690d9948117f8d906/clang/lib/CodeGen/CGOpenMPRuntime.cpp#L9489-L9491 to first work on is_device_ptr, has_device_addr, and maps on pointers with component-lists of size one, and then subsequently on the remaining component-lists, but I'm not sure if I'm thinking of all the cases there, and if that'll cause issues.

```cpp
// Pseudo code-flow
// Directly pass the original CombinedInfo to the first two
generateInfoForCaptureForIDP/HDA(...&CombinedInfo...)
generateInfoForCaptureForMaps(&CombinedInfo..., /*filter for only component-lists that are single-length and for pointer base decls*/)

// Pass CurInfo to the next two
generateInfoForCaptureForMaps(&CurInfo, &PartialStruct, /*Filter for remining component-lists*/)
emitCombinedEntry(...&CurInfo, &PartialStruct...)
CombinedInfo.append(CurInfo)
```

@alexey-bataev, do you have any suggestions/feedback?

-----
Future Issue:

The problem long-term is that we currently assume that all component-lists for the same VAR should contribute towards a single combined PartialStruct, if any. That should not be the case for cases like:


```
map(to: sp->x, sp->y) map(to: sp->sq->a, sp->sq->b) map(sp)
```

In the above case, we should get two independent "containing-structs" mapped by themselves:

```
&sp, &sp, sizeof(sp), TO | PARAM

// map-chain for the containing-struct sp[0] with base-pointer sp
&sp[0], &sp[0], sizeof(sp[0]), ALLOC /* Can be optimized to not alloc the full struct */
&sp[0], &sp->x, sizeof(sp->x), TO | MEMBER_OF(2)
&sp[0], &sp->y, sizeof(sp->y), TO | MEMBER_OF(2)
&sp, &sp[0], ATTACH

// map-chain for the containing-struct sp->sq[0] with base-pointer sp->sq
&(sp->sq[0]), &(sp->sq[0]), sizeof(sp->sq[0]), ALLOC
&sp->sq[0], &sp->sq->a, sizeof(sp->sq->a), TO | MEMBER_OF(6)
&sp->sq[0], &sp->sq->a, sizeof(sp->sq->a), TO | MEMBER_OF(6)
&sp->sq, &sp->sq[0], ATTACH
```

So we need to loop-over all component-lists, and only process those together that share the same attachable-base-pointer (sp or sp->sq in this case).

So, our second invocation for the "remaining component-lists" would become something like:

```
for (Expr* AttachBasePtr: AttachBasePtrs) {
  MapCombinedInfoTy PerAttachBaseCurInfo;
  StructRangeInfoTy PerAttachBasePartialStruct;

// Pass CurInfo to the next two
generateInfoForCaptureForMaps(&PerAttachBaseCurInfo, &PerAttachBasePartialStruct, /*Filter for every component-list that has AttachBaseptr as its attachable base-pointer*/)
emitCombinedEntry(...&PerAttachBaseCurInfo, &PerAttachBasePartialStruct...)
CombinedInfo.append(CurInfo)
}
```

Alexey, do you foresee any issues with this?

https://github.com/llvm/llvm-project/pull/145454


More information about the cfe-commits mailing list