-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[mlir][LLVM] Make struct types immutable #116035
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
Open
zero9178
wants to merge
5
commits into
llvm:main
Choose a base branch
from
zero9178:llvm-dialect-immutable-struct
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -73,145 +73,6 @@ DEFINE_TRIVIAL_LLVM_TYPE(LLVMMetadataType, "llvm.metadata"); | |||||
|
||||||
#undef DEFINE_TRIVIAL_LLVM_TYPE | ||||||
|
||||||
//===----------------------------------------------------------------------===// | ||||||
// LLVMStructType. | ||||||
//===----------------------------------------------------------------------===// | ||||||
|
||||||
/// LLVM dialect structure type representing a collection of different-typed | ||||||
/// elements manipulated together. Structured can optionally be packed, meaning | ||||||
/// that their elements immediately follow each other in memory without | ||||||
/// accounting for potential alignment. | ||||||
/// | ||||||
/// Structure types can be identified (named) or literal. Literal structures | ||||||
/// are uniquely represented by the list of types they contain and packedness. | ||||||
/// Literal structure types are immutable after construction. | ||||||
/// | ||||||
/// Identified structures are uniquely represented by their name, a string. They | ||||||
/// have a mutable component, consisting of the list of types they contain, | ||||||
/// the packedness and the opacity bits. Identified structs can be created | ||||||
/// without providing the lists of element types, making them suitable to | ||||||
/// represent recursive, i.e. self-referring, structures. Identified structs | ||||||
/// without body are considered opaque. For such structs, one can set the body. | ||||||
/// Identified structs can be created as intentionally-opaque, implying that the | ||||||
/// caller does not intend to ever set the body (e.g. forward-declarations of | ||||||
/// structs from another module) and wants to disallow further modification of | ||||||
/// the body. For intentionally-opaque structs or non-opaque structs with the | ||||||
/// body, one is not allowed to set another body (however, one can set exactly | ||||||
/// the same body). | ||||||
/// | ||||||
/// Note that the packedness of the struct takes place in uniquing of literal | ||||||
/// structs, but does not in uniquing of identified structs. | ||||||
class LLVMStructType | ||||||
: public Type::TypeBase<LLVMStructType, Type, detail::LLVMStructTypeStorage, | ||||||
DataLayoutTypeInterface::Trait, | ||||||
DestructurableTypeInterface::Trait, | ||||||
TypeTrait::IsMutable> { | ||||||
public: | ||||||
/// Inherit base constructors. | ||||||
using Base::Base; | ||||||
|
||||||
static constexpr StringLiteral name = "llvm.struct"; | ||||||
|
||||||
/// Checks if the given type can be contained in a structure type. | ||||||
static bool isValidElementType(Type type); | ||||||
|
||||||
/// Gets or creates an identified struct with the given name in the provided | ||||||
/// context. Note that unlike llvm::StructType::create, this function will | ||||||
/// _NOT_ rename a struct in case a struct with the same name already exists | ||||||
/// in the context. Instead, it will just return the existing struct, | ||||||
/// similarly to the rest of MLIR type ::get methods. | ||||||
static LLVMStructType getIdentified(MLIRContext *context, StringRef name); | ||||||
static LLVMStructType | ||||||
getIdentifiedChecked(function_ref<InFlightDiagnostic()> emitError, | ||||||
MLIRContext *context, StringRef name); | ||||||
|
||||||
/// Gets a new identified struct with the given body. The body _cannot_ be | ||||||
/// changed later. If a struct with the given name already exists, renames | ||||||
/// the struct by appending a `.` followed by a number to the name. Renaming | ||||||
/// happens even if the existing struct has the same body. | ||||||
static LLVMStructType getNewIdentified(MLIRContext *context, StringRef name, | ||||||
ArrayRef<Type> elements, | ||||||
bool isPacked = false); | ||||||
|
||||||
/// Gets or creates a literal struct with the given body in the provided | ||||||
/// context. | ||||||
static LLVMStructType getLiteral(MLIRContext *context, ArrayRef<Type> types, | ||||||
bool isPacked = false); | ||||||
static LLVMStructType | ||||||
getLiteralChecked(function_ref<InFlightDiagnostic()> emitError, | ||||||
MLIRContext *context, ArrayRef<Type> types, | ||||||
bool isPacked = false); | ||||||
|
||||||
/// Gets or creates an intentionally-opaque identified struct. Such a struct | ||||||
/// cannot have its body set. To create an opaque struct with a mutable body, | ||||||
/// use `getIdentified`. Note that unlike llvm::StructType::create, this | ||||||
/// function will _NOT_ rename a struct in case a struct with the same name | ||||||
/// already exists in the context. Instead, it will just return the existing | ||||||
/// struct, similarly to the rest of MLIR type ::get methods. | ||||||
static LLVMStructType getOpaque(StringRef name, MLIRContext *context); | ||||||
static LLVMStructType | ||||||
getOpaqueChecked(function_ref<InFlightDiagnostic()> emitError, | ||||||
MLIRContext *context, StringRef name); | ||||||
|
||||||
/// Set the body of an identified struct. Returns failure if the body could | ||||||
/// not be set, e.g. if the struct already has a body or if it was marked as | ||||||
/// intentionally opaque. This might happen in a multi-threaded context when a | ||||||
/// different thread modified the struct after it was created. Most callers | ||||||
/// are likely to assert this always succeeds, but it is possible to implement | ||||||
/// a local renaming scheme based on the result of this call. | ||||||
LogicalResult setBody(ArrayRef<Type> types, bool isPacked); | ||||||
|
||||||
/// Checks if a struct is packed. | ||||||
bool isPacked() const; | ||||||
|
||||||
/// Checks if a struct is identified. | ||||||
bool isIdentified() const; | ||||||
|
||||||
/// Checks if a struct is opaque. | ||||||
bool isOpaque(); | ||||||
|
||||||
/// Checks if a struct is initialized. | ||||||
bool isInitialized(); | ||||||
|
||||||
/// Returns the name of an identified struct. | ||||||
StringRef getName(); | ||||||
|
||||||
/// Returns the list of element types contained in a non-opaque struct. | ||||||
ArrayRef<Type> getBody() const; | ||||||
|
||||||
/// Verifies that the type about to be constructed is well-formed. | ||||||
static LogicalResult | ||||||
verifyInvariants(function_ref<InFlightDiagnostic()> emitError, StringRef, | ||||||
bool); | ||||||
static LogicalResult | ||||||
verifyInvariants(function_ref<InFlightDiagnostic()> emitError, | ||||||
ArrayRef<Type> types, bool); | ||||||
using Base::verifyInvariants; | ||||||
|
||||||
/// Hooks for DataLayoutTypeInterface. Should not be called directly. Obtain a | ||||||
/// DataLayout instance and query it instead. | ||||||
llvm::TypeSize getTypeSizeInBits(const DataLayout &dataLayout, | ||||||
DataLayoutEntryListRef params) const; | ||||||
|
||||||
uint64_t getABIAlignment(const DataLayout &dataLayout, | ||||||
DataLayoutEntryListRef params) const; | ||||||
|
||||||
uint64_t getPreferredAlignment(const DataLayout &dataLayout, | ||||||
DataLayoutEntryListRef params) const; | ||||||
|
||||||
bool areCompatible(DataLayoutEntryListRef oldLayout, | ||||||
DataLayoutEntryListRef newLayout) const; | ||||||
|
||||||
LogicalResult verifyEntries(DataLayoutEntryListRef entries, | ||||||
Location loc) const; | ||||||
|
||||||
/// Destructs the struct into its indexed field types. | ||||||
std::optional<DenseMap<Attribute, Type>> getSubelementIndexMap(); | ||||||
|
||||||
/// Returns which type is stored at a given integer index within the struct. | ||||||
Type getTypeAtIndex(Attribute index); | ||||||
}; | ||||||
|
||||||
//===----------------------------------------------------------------------===// | ||||||
// Printing and parsing. | ||||||
//===----------------------------------------------------------------------===// | ||||||
|
@@ -226,8 +87,9 @@ void printType(Type type, AsmPrinter &printer); | |||||
|
||||||
/// Parse any MLIR type or a concise syntax for LLVM types. | ||||||
ParseResult parsePrettyLLVMType(AsmParser &p, Type &type); | ||||||
ParseResult parsePrettyLLVMType(AsmParser &p, SmallVectorImpl<Type> &types); | ||||||
/// Print any MLIR type or a concise syntax for LLVM types. | ||||||
void printPrettyLLVMType(AsmPrinter &p, Type type); | ||||||
void printPrettyLLVMType(AsmPrinter &p, TypeRange type); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
ultra nit: It could make sense to rename to printLLVMTypeList and parseLLVMTypeList above? |
||||||
|
||||||
//===----------------------------------------------------------------------===// | ||||||
// Utility functions. | ||||||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ultra nit: I would spell out