Skip to content

MLIR SROA #15

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 25 commits into from
Closed

MLIR SROA #15

wants to merge 25 commits into from

Conversation

Moxinilian
Copy link

@Moxinilian Moxinilian commented Apr 18, 2023

Implementation of a simple form of generic SROA in MLIR.

Copy link
Collaborator

@gysit gysit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall very nice!

I dropped a lot of comments and will need a second review to get more in depth with some parts of the algorithm. Especially some of the blocking uses handling was a bit confusing. And also the GEP stuff. I think it may make sense to add some more comments for the complicating things.

@Moxinilian Moxinilian marked this pull request as ready for review May 2, 2023 14:41
Returns whether all accesses in this operation to the provided slot are
done in a type-safe manner. To be type-safe, the access must only load
the value in this type as the type of the slot, and without assuming any
context around the slot. For example, a type-safe load must not load
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it misses the inbounds aspect but we can keep it if you prefer the name.

@@ -214,6 +214,13 @@ def SCCP : Pass<"sccp"> {
let constructor = "mlir::createSCCPPass()";
}

def SROA : Pass<"sroa"> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This still needs some polishing :)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tell me if what I wrote is satisfying.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good! Should we also add a pass flag that limits the size of the aggregates we consider for destruction (probably in terms of number of elements?).

@@ -198,6 +200,12 @@ class LLVMStructType

LogicalResult verifyEntries(DataLayoutEntryListRef entries,
Location loc) const;

/// Destructs the struct into its indexed field types.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does "destruct" mean here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's go for destructure.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would explicitly mention which interfaces are SROA-related in the source code

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So it's not super clear where the boundary is. There is "PromotableOpInterface" which is used by both, "TypeSafeOpInterface" which is used by SROA but has nothing SROA-specific to it. Generally I think those interfaces are meant to be used in any setting and happen to be used by mem2reg and SROA.

Comment on lines 24 to 26
/// This is a DAG structure because an operation that must eliminate some of
/// its uses always comes from a request from an operation that must
/// eliminate some of its own uses.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

omg this sentence 😂 Please add some structure to help parsing

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tell me if you prefer the new one.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do I know what's new? 🥲

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blame Torvalds!

Copy link
Collaborator

@Dinistro Dinistro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some NIT comments.

Optional<DenseMap<Attribute, Type>> getDestructedLayout();

/// Returns which type is stored at a given integer index within the struct.
Type getTypeAtIndex(Attribute index);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At a first glance, it seems odd to use an Attribute type for index.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the reason for this is that sometimes indices are not integers but fancy things. For example, if you wanted to use SROA on for example a hashmap dialect, your indices could be anything.

InterfaceMethod<[{
Returns the list of slots for which destruction should be attempted,
specifying in which way the slot should be destructed into subslots. The
subslots are indexed by attributes. This computes the type of the
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: "by integer/index attributes"?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well no, because of what I mentioned above. I don't really know how to word it otherwise :/

may belong to a different allocator. The original slot must still exist
at the end of this call.

The builder is located at the beginning of the block where the slot
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems a bit odd that the insertion point of the builder is part of the precondition.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. This comes from suggestions upstream, though. I don't know if I should try to fight it too much.

InterfaceMethod<[{
Destructures this slot into multiple subslots. The newly generated slots
may belong to a different allocator. The original slot must still exist
at the end of this call.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original slot must still exist at the end of this call.

Does this mean that destroy doesn't destroy the slot?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

destruct destructs the slot but does not destroy it yes :)
I'm changing the name for destructure to make Johannes happy.

@Moxinilian
Copy link
Author

I'm going to squash all this and manually separate it into two different PRs. Feel free to finish the ongoing discussions here and move further comments to the new PRs once they are ready.

@Moxinilian Moxinilian closed this May 16, 2023
definelicht pushed a commit that referenced this pull request Jan 5, 2024
A case for this transformation, https://gcc.godbolt.org/z/nhYcWq1WE
Fold
  mov     w8, llvm#56952
  movk    w8, #15, lsl #16
  ldrb    w0, [x0, x8]
into
  add     x0, x0, 1036288
  ldrb    w0, [x0, 3704]

Only LDRBBroX is supported for the first time.
Fix llvm#71917
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants