15 Commits

Author SHA1 Message Date
Tobias Gysi
25d942403c
[mlir][llvm] Add invariant intrinsics (#75354)
This commit implements the LLVM IR invariant intrinsics in LLVM dialect.
These intrinsics can be used to mark a program regions in which the
contents of a specific memory object will not change.

The LLVM dialect implementation also implements the
PromotableOpInterface to ensure Mem2Reg & SROA are able to promote
pointers that are marked using the invariant intrinsics.
2023-12-14 14:58:45 +01:00
Billy Zhu
0ab6b20c36
[MLIR] Add DIExpression to LLVM dialect (#72462)
Add initial support for DIExpression in LLVM dialect.

Similar to LLVM IR, DI Expression is encoded as a list of uint64. The
difference is that LLVM IR has helpers for understanding the expression
(e.g. for verification and pretty printing), whereas the current support
added by this PR treats the expression elements as opaque.
2023-11-16 11:32:02 -08:00
Christian Ulmann
4983432f17
[MLIR][LLVM] Remove typed pointers from the LLVM dialect (#71285)
This commit removes the support for typed pointers from the LLVM
dialect. Typed pointers have been deprecated for a while and thus this
removal was announced in a PSA:

https://discourse.llvm.org/t/psa-removal-of-typed-pointers-from-the-llvm-dialect/74502

This change includes:
- Changing the ` LLVMPointerType`
- Removing remaining usages of the builders and the now removed element
type
- Fixing assembly formats that require fully qualified pointer types
- Updating ODS pointer constraints
2023-11-06 15:48:03 +01:00
Markus Böck
c10f8bd6c3 [mlir][LLVM] Add SplitGEP type-consistency pattern
The goal of this pattern is to eliminate all GEPs that have more than two indices by splitting it into multiple GEPs.
The advantage of this change is that the resulting GEPs only ever index into one aggregate at the time. This enables handling sub-aggregates in other patterns and also creates IR with easier to deduce pointer element types.

As a minor note, `getResultPtrElementType` for `GEPOp` was rewritten since it did not properly handle dynamic indices. The way GEPOp is specified, the resulting pointer element type can *always* be deduced from its base type and indices.

Differential Revision: https://reviews.llvm.org/D154692
2023-07-10 10:45:42 +02:00
Markus Böck
56b6b45472 [mlir][LLVM] Use undef operand instead of removing llvm.intr.dbg.value
Jeremy Morse noted in D154451 that LLVM doesn't drop a `dbg.value` when its value is being removed, but rather sets the operand to `undef`. This preserves the debug info and gives allows the debugger to instead inform the user that the variable has been optimized out, rather than not displaying the variable at all.

This patch fixes that mistake done in the previous revision by mirroring that behaviour in MLIR as well.

Differential Revision: https://reviews.llvm.org/D154476
2023-07-06 15:39:41 +02:00
Markus Böck
253f4bfa87 [mlir][LLVM] drop llvm.intr.dbg.value when promoting in SROA or mem2reg
This has previously been done for `llvm.intr.dbg.declare`, which is a common occurrence when the debug info points to the variable through the pointer, but may also occur when the `alloca` itself is a local variable in debug info.

Not doing so prevents `SROA` and `mem2reg` from promoting e.g. an `alloca`. We simply drop the value completetly, since there is no meaninful debug info that can be constructed instead as the pointer value is removed.

Differential Revision: https://reviews.llvm.org/D154451
2023-07-04 17:15:23 +02:00
Théo Degioanni
fb047e4ae1 [mlir][llvm] Type consistency transformations
This revision introduces new rewrites to improve the type consistency of
a program expressed in the LLVM dialect.

Type consistency means that a given opaque pointer is consistently used
assuming the same pointee type, in a best effort basis. The introduced
rewrites modify the program to improve type consistency while preserving
the same semantics. This is useful for two main reasons:

- Transformation passes in the LLVM dialect like SROA or Mem2Reg can
  analyse code better if type information and structure is used in a
  consistent manner. Opaque pointers make this difficult to enforce, but
  type consistency improvements increase the amount of occurences where
  reasonable analysis can pick up on transformable patterns.
- While LLVM IR is not particularly picky about inconsistent type uses,
  it may be of interest to lift LLVM IR into higher level dialects.
  Having more instances of consistent type information would help
  lifting into dialects that do care about consistent types.

In order to detect cases of inconsistent uses, operations returning an
LLVMPointer can implement the GetResultPtrElementType interface, which
allows getting a hint of which type the provided pointer should see its
pointee as, if such hint is available. The provided rewrites will then
use this hint to attempt to modify operations using the pointers so they
use the hinted type when dealing with the pointer.

Two transformations have been implemented in this revision:

- When a load/store uses a struct ptr directly to write to the first
  element of the struct, introduce a GEP to the first element so the
  type structure is preserved.
- When a GEP statically indexes in a pointer with a base type
  inconsistent with the hint, try to find indices using the hint as a
  base type that would result in the same offset, and replace the GEP
  with this indexing.

More transformations are possible and I hope this is only a beginning
for this simplification effort.

Reviewed By: gysit

Differential Revision: https://reviews.llvm.org/D153973
2023-07-03 11:12:39 +02:00
Théo Degioanni
3bd85cf7c2 [mlir][llvm] Add memcpy support for mem2reg/sroa.
This revision introduces SROA and mem2reg support for the family of
memcpy-like intrinsics (memcpy, memcpy.inline and memmove).

The mem2reg implementation transforms memcpys of full types into loads
and store. Memcpy between two promotable slots always disappear.

The SROA implementation transforms memcpys of *entire* aggregate types
into memcpys of all of their fields.

Reviewed By: gysit

Differential Revision: https://reviews.llvm.org/D152898
2023-06-16 08:35:20 +00:00
Théo Degioanni
8404b23acd [mlir][llvm] Add memset support for mem2reg/sroa
This revision introduces support for memset intrinsics in SROA and
mem2reg for the LLVM dialect. This is achieved for SROA by breaking
memsets of aggregates into multiple memsets of scalars, and for mem2reg
by promoting memsets of single integer slots into the value the memset
operation would yield.

The SROA logic supports breaking memsets of static size operating at the
start of a memory slot. The intended most common case is for memsets
covering the entirety of a struct, most often as a way to initialize it
to 0.

The mem2reg logic supports dynamic values and static sizes as input to
promotable memsets. This is achieved by lowering memsets into
`ceil(log_2(n))` LeftShift operations, `ceil(log_2(n))` Or operations
and up to one ZExt operation (for n the byte width of the integer),
computing in registers the integer value the memset would create. Only
byte-aligned integers are supported, more types could easily be added
afterwards.

Reviewed By: gysit

Differential Revision: https://reviews.llvm.org/D152367
2023-06-14 09:17:08 +00:00
Tres Popp
68f58812e3 [mlir] Move casting calls from methods to function calls
The MLIR classes Type/Attribute/Operation/Op/Value support
cast/dyn_cast/isa/dyn_cast_or_null functionality through llvm's doCast
functionality in addition to defining methods with the same name.
This change begins the migration of uses of the method to the
corresponding function call as has been decided as more consistent.

Note that there still exist classes that only define methods directly,
such as AffineExpr, and this does not include work currently to support
a functional cast/isa call.

Context:
- https://mlir.llvm.org/deprecation/ at "Use the free function variants
  for dyn_cast/cast/isa/…"
- Original discussion at https://discourse.llvm.org/t/preferred-casting-style-going-forward/68443

Implementation:
This patch updates all remaining uses of the deprecated functionality in
mlir/. This was done with clang-tidy as described below and further
modifications to GPUBase.td and OpenMPOpsInterfaces.td.

Steps are described per line, as comments are removed by git:
0. Retrieve the change from the following to build clang-tidy with an
   additional check:
   main...tpopp:llvm-project:tidy-cast-check
1. Build clang-tidy
2. Run clang-tidy over your entire codebase while disabling all checks
   and enabling the one relevant one. Run on all header files also.
3. Delete .inc files that were also modified, so the next build rebuilds
   them to a pure state.

```
ninja -C $BUILD_DIR clang-tidy

run-clang-tidy -clang-tidy-binary=$BUILD_DIR/bin/clang-tidy -checks='-*,misc-cast-functions'\
               -header-filter=mlir/ mlir/* -fix

rm -rf $BUILD_DIR/tools/mlir/**/*.inc
```

Differential Revision: https://reviews.llvm.org/D151542
2023-05-26 10:29:55 +02:00
Théo Degioanni
4ed502ef4f [mlir] Add a generic SROA implementation.
This revision introduces a generic implementation of Scalar Replacement
Of Aggregates. In contrast to the implementation in LLVM, this focuses
on the core of SROA: destructuring aggregates. By implementing
interfaces on allocators and accessors, memory allocators can be
destructured into smaller allocators, through the MemorySlot
abstraction.

This pass only works on aggregates that are accessed in a "type-safe"
way, that is within the bounds and respecting the type of a given memory
slot. The destructuring pattern and functions only peel off the first
layer of aggregates and can safely be applied repeatedly. For
convenience, the transformation is also available as a pass that will
apply the pattern repeatedly.

Depends on D149958

Reviewed By: gysit

Differential Revision: https://reviews.llvm.org/D150186
2023-05-22 09:01:09 +00:00
Théo Degioanni
ead8e9d795 [mlir] [mem2reg] Adapt to be pattern-friendly.
This revision modifies the mem2reg interfaces and algorithm to be more
omfortable to use as a pattern. The motivation behind this is that
currently the pattern needs to be applied to the scope op of the region
in which allocators should be promoted. However, a more natural way to
apply the pattern would be to apply it on the allocator directly. This
is not only clearer but easier to parallelize.

This revision changes the mem2reg pattern to operate this way. This
required restraining the interfaces to only mutate IR using
RewriterBase, as the previously used escape hatch is not granular enough
to match on the region that is modified only. This has the unfortunate
cost of preventing batching allocator promotion and making the block
argument adding logic more complex. Because batching no longer made any
sense, I made the internal analyzer/promoter decoupling private again.

This also adds statistics to the mem2reg infrastructure.

Reviewed By: gysit

Differential Revision: https://reviews.llvm.org/D150432
2023-05-16 08:35:13 +00:00
Théo Degioanni
92cc30aca7 Reland "[mlir][mem2reg] Expose algorithm internals."
This patch refactors the Mem2Reg infrastructure. It decouples
analysis from promotion, allowing for more control over the execution of
the logic. It also adjusts the interfaces to be less coupled to mem2reg
and more general. This will be useful for an upcoming revision
introducing generic SROA.

This commit reverts f333977eb20a and relands 91cff8a71872.

The original commit was reverted accidentally due to a misinterpretation
of a bazel build bot failure.

Reviewed By: gysit

Differential Revision: https://reviews.llvm.org/D149825
2023-05-09 09:24:49 +00:00
Tobias Gysi
f333977eb2 Revert "[mlir][mem2reg] Expose algorithm internals."
The commit causes build bot failures due to a missing dependencies:
https://buildkite.com/llvm-project/llvm-main/builds/7036#0187fb40-e4b6-4471-a2a0-2820b71c727b

This reverts commit 91cff8a71872cf49f0c5c9e5510f8065bfefa3c3.
2023-05-08 13:32:41 +00:00
Théo Degioanni
91cff8a718 [mlir][mem2reg] Expose algorithm internals.
This patch refactors the Mem2Reg infrastructure. It decouples
analysis from promotion, allowing for more control over the execution of
the logic. It also adjusts the interfaces to be less coupled to mem2reg
and more general. This will be useful for an upcoming revision
introducing generic SROA.

Reviewed By: gysit

Differential Revision: https://reviews.llvm.org/D149825
2023-05-08 11:48:20 +00:00