This is an archive of the discontinued LLVM Phabricator instance.

[MLIR][OpenMP] Add support for threadprivate directive
ClosedPublic

Authored by peixin on Apr 7 2022, 6:10 PM.

Details

Summary

This supports the threadprivate directive in OpenMP dialect following
the OpenMP 5.1 [2.21.2] standard. Also lowering to LLVM IR using OpenMP
IRBduiler.

Diff Detail

Event Timeline

peixin created this revision.Apr 7 2022, 6:10 PM
Herald added a project: Restricted Project. · View Herald TranscriptApr 7 2022, 6:10 PM
peixin requested review of this revision.Apr 7 2022, 6:10 PM
  1. Do we need a verifier for this?
  2. If yes, then we should add test cases (in invalid.mlir). Also we probably should add a test case to verify the printer in ops.mlir.

In addition to Arnamoy's comments, can we have assembly format based syntax for this? It looks like the following would work -

$sym_addr `:` type($sym_addr) `->` type($res)

In addition to Arnamoy's comments, can we have assembly format based syntax for this? It looks like the following would work -

$sym_addr `:` type($sym_addr) `->` type($res)

Thanks for suggestions. I didn't notice the mlir format has changed. I am fixing the CI fail.

peixin updated this revision to Diff 421433.Apr 8 2022, 12:24 AM
  1. Remove let parser/printer due to update in upstream MLIR.
  2. Replace syn_name() with getSymName() due to update in upstream MLIR.
  3. Add test case in ops.mlir
  1. Do we need a verifier for this?

This operation def is implementation defined. I am not aware of what I should verify currently. The restrictions in OpenMP standard are not suitable to verify here, which should be in semantic analysis. Please let me know if anyone finds what should to verify.

Thanks for the patch. A few comments.

mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
1327

nit: llvm::OpenMPIRBuilder::LocationDescription ompLoc(builder) also works.

1333

Instead of an assert, can we return a graceful error here?

1340

nit: builder.getInt8PtrTy()

1343

[suggestion] Instead of exposing this function and changing the LLVM::ModuleTranslation class, we can use builder.GetInsertBlock()->getModule()->getDataLayout() here.

1344

For size of types, we can use the following to get the type size directly instead of using getTypeStoreSize and getFixedSize.

llvm::ConstantInt *size = Builder.getInt64(datalayout.getTypeSizeInBits(type))
kiranchandramohan accepted this revision.Apr 8 2022, 2:22 AM

LGTM. A few nits. Please wait for @shraiysh and @arnamoy10.

Can you add a note to the Summary saying the following or something similar?
The current implementation uses the OpenMP runtime to provide thread-local storage. We will (in future) provide support for using the TLS feature of the LLVM IR.

mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
896

Nit: This operation takes in the address of a symbol that represents the original variable and returns the address of its thread local storage. All occurrences of threadprivate variables in a parallel region should use the TLS returned by this operation.

898

Nit: refers to the address of the symbol, which is a pointer to the original global variable.

mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
1333

Nit: When the assert is removed, please replace the auto above with a type.

This revision is now accepted and ready to land.Apr 8 2022, 2:22 AM
peixin updated this revision to Diff 421464.Apr 8 2022, 2:33 AM
  1. Fix datalayout related comments.
  2. Fix Operation description.
peixin updated this revision to Diff 421466.Apr 8 2022, 2:36 AM
peixin marked an inline comment as done.
peixin marked 2 inline comments as done.Apr 8 2022, 2:42 AM
peixin added inline comments.
mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
898

Made changes: delete global.

mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
1333

Technically, AllocaOp works also ok here. classic-flang uses for variables in main program for fortran code. Also, OpenMP standard does not mention the variable must be global for fortran. So I add assert instead of reporting the error in verify. What do you think? @kiranchandramohan @shraiysh

1344

getTypeSizeInBits is not correct. It seems it cannot handle some special data type. I followed clang using getTypeStoreSize.

shraiysh added inline comments.Apr 8 2022, 3:05 AM
mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
1333

You can report an error here itself. This error will not be inside verify, instead it will be an error while translating to LLVM IR. That allows using AllocaOp in the dialect, but reports an error only while translating to LLVM IR. Example - here.

1344

I had asked about this in the discord channel and they suggested using getTypeSizeInBits to get the size of a type. Can you please specify for which types it cannot handle?

shraiysh accepted this revision.Apr 8 2022, 5:15 AM
peixin added inline comments.Apr 8 2022, 9:07 AM
mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
1333

That makes sense. Thanks for the advice. Will fix it.

1344

https://github.com/llvm/llvm-project/blob/5562d9b3c006f3e376d98ee7b9f3c6c8608ddbee/llvm/include/llvm/IR/DataLayout.h#L467-L477

For example, returns 5 for i36 gives 40 in bits for i36. Clang uses that, so I use it. Using getTypeStoreSize works ok for all tested fortran data types, so I did not dig too much the difference between using getTypeStoreSize or getTypeSizeInBits. Fortran code doesn't have i36, not sure if c/c++ uses it.

peixin updated this revision to Diff 421679.Apr 8 2022, 8:56 PM

Change assert into error reporting. Remove the auto. Add the test case for the error reporting

@arnamoy10 Is this patch OK to you now?

shraiysh added inline comments.Apr 10 2022, 9:34 PM
mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
1344

Okay thank you.

This revision was automatically updated to reflect the committed changes.