[flang-commits] [flang] [flang] Apply nocapture attribute to dummy arguments (PR #116182)

via flang-commits flang-commits at lists.llvm.org
Mon Nov 18 01:58:35 PST 2024


================
@@ -45,6 +47,25 @@ void FunctionAttrPass::runOnOperation() {
 
   LLVM_DEBUG(llvm::dbgs() << "Func-name:" << func.getSymName() << "\n");
 
+  llvm::StringRef name = func.getSymName();
+  auto deconstructed = fir::NameUniquer::deconstruct(name);
+  bool isFromModule = !deconstructed.second.modules.empty();
+
+  if ((isFromModule || !func.isDeclaration()) &&
+      !fir::hasBindcAttr(func.getOperation())) {
+    llvm::StringRef nocapture = mlir::LLVM::LLVMDialect::getNoCaptureAttrName();
+    mlir::UnitAttr unitAttr = mlir::UnitAttr::get(func.getContext());
+
+    for (auto [index, argType] : llvm::enumerate(func.getArgumentTypes())) {
+      if (mlir::isa<fir::ReferenceType>(argType) &&
+          !fir::isPointerType(argType) &&
----------------
jeanPerier wrote:

What I am pointing out is not the ability to detect or not the the argument is for a Fortran pointer, it is that Fotran Pointers are always passed as the address of a descriptor, and while _the address inside the descriptor_ may be captured because it is the target of a Fortran POINTER, _the address of the descriptor_ cannot  be taken (there is no way to do that in Fortran). The llvm `nocapture` applies to the address that is the function argument, which in this case is the one of the descriptor, not the base address, so it is still correct to add `nocapture` to a `fir.ref<fir.box<fir.ptr<>>`.

Let me use C to illustrate here: when passing a Fortran pointer, the ABI looks like:
```
typedef struct {
  void* base_address;
  // ... more fields
} Descriptor;

void foo(Descriptor* fortran_pointer);
````

Fortran tells you that `fortran_pointer->base_address` may be taken inside foo, but `fortran_pointer` address cannot. As far as I understand llvm.nocapture, it applies to the SSA argument address, not the addresses inside the memory pointed to by the SSA argument address. `Descriptor*` is the C equivalent of `fir.ref<fir.box<>>`. 

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


More information about the flang-commits mailing list