This is an archive of the discontinued LLVM Phabricator instance.

[mlir][llvm] Use attributes to store access groups.
AbandonedPublic

Authored by gysit on Apr 12 2023, 3:26 AM.

Details

Summary

The revision replaces the existing access group operations by
attributes. The access group operations are currently stored in a
global metadata operation. This solution is problematic when inlining
since the access groups cannot be modified in parallel - the
inliner splits the call graph into strongly connected components and
inlines them in parallel - resulting in possible race conditions.

The revision introduces an access group attribute that uses an
integer identifier to model the semantics of distinct metadata.
A distinct sequence attribute is used to generate the unique
identifiers for a specific function. Having a sequence generator
per function ensures deterministic identifiers can be generated
even if functions are manipulated in parallel.

Example:

llvm.metadata @metadata {

llvm.access_group @group
llvm.return

}

llvm.store %0, %ptr { access_groups = [@metadata::@group] }

translates to:

#sequence = #llvm.distinct_sequence<scope = @foo, state = 1>
#group = #llvm.access_group<id = 0, elem_of = #sequence>

llvm.store %0, %ptr { access_groups = [#group] }

Depends on D148007

Diff Detail

Event Timeline

gysit created this revision.Apr 12 2023, 3:26 AM
Herald added a reviewer: dcaballe. · View Herald Transcript
Herald added a project: Restricted Project. · View Herald Transcript
gysit requested review of this revision.Apr 12 2023, 3:26 AM
zero9178 added inline comments.Apr 12 2023, 4:00 AM
mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
153

Would it maybe be worth commenting that this is threadsafe due to the StorageUniquer using a mutex for mutations? This was non-obvious to me at least (might just be me as well though).

mlir/lib/Target/LLVMIR/LoopAnnotationTranslation.cpp
275–276

nit: could use accessGroups.getAsRange<AccessGroupAttr>() here to avoid the explicit cast below

gysit updated this revision to Diff 512779.Apr 12 2023, 4:48 AM
gysit marked 2 inline comments as done.

Address review comments.

definelicht added inline comments.Apr 12 2023, 7:20 AM
mlir/lib/Target/LLVMIR/LoopAnnotationTranslation.cpp
258

nit: Doesn't DenseMap have contains?

definelicht added inline comments.Apr 12 2023, 7:21 AM
mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h
73

IIUC you are doing a singleton pattern, maybe add a private constructor?

gysit updated this revision to Diff 512839.Apr 12 2023, 8:05 AM
gysit marked an inline comment as done.

Address review comments and actually remove the llvm.access_group operation.

gysit added inline comments.Apr 12 2023, 8:07 AM
mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h
73

using Base::Base; actually inherits the base class constructors. I added a comment to clarify this.

Dinistro added inline comments.Apr 13 2023, 12:21 AM
mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h
73

NIT: Maybe changing the name to something like "DistinctHelperAttr" or "DistinctionAttr" to clarify the role of it might be beneficial.

78

Is there a reason why this constructor is public?

gysit updated this revision to Diff 514949.Apr 19 2023, 7:23 AM
gysit edited the summary of this revision. (Show Details)

Introduce an explicit distinct_sequence attribute.

definelicht added inline comments.Apr 19 2023, 8:23 AM
mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
233–243

It would be cleaner if you could pass in scope and state together instead of first and second separately 🤔 Is it possible to pass parser.parseAttribute<SymbolRefAttr> as a function handle directly instead of wrapping the lambda, and then forward the argument?
You could also consider using std::optional instead of the pair with a bool.

280–286

This would be nice to factor into a function getTopLevelSymbolTable or so. This could even exist on SymbolTable directly 🙂

mlir/lib/Target/LLVMIR/ModuleImport.cpp
518–519

Could it be worth to not construct this attribute if it's not actually used?

Dinistro added inline comments.Apr 19 2023, 11:36 PM
mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h
71
78

nvm, that is required for the infra to work.

mlir/lib/Dialect/LLVMIR/IR/LLVMInterfaces.cpp
112

Can a range not be implicitly casted to an ArrayRef instead of converting it to a vector?

gysit updated this revision to Diff 515234.Apr 20 2023, 12:24 AM
gysit marked 4 inline comments as done.

Address review comments.

gysit added inline comments.Apr 20 2023, 12:26 AM
mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
280–286

I did simplify this code to access the parent module directly using getParentOfType<ModuleOp>. This solution is easier and covers all use cases for now (LLVM dialect is not supposed to support nested builtin module operations). The clean solution for the attribute verification is discussed here https://discourse.llvm.org/t/symbol-user-interface-for-attributes-types/69935.

mlir/lib/Dialect/LLVMIR/IR/LLVMInterfaces.cpp
112

It is necessary unfortunately. I assume since array ref expects a backing memory which is not given for an iterator range.

gysit updated this revision to Diff 516295.Apr 24 2023, 12:50 AM

Minor fixes.

gysit abandoned this revision.Jul 16 2023, 11:30 PM

This problem has been solved differently https://reviews.llvm.org/D155285.