Skip to content
This repository has been archived by the owner on Apr 23, 2021. It is now read-only.

Identified structs #209

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions include/mlir/Dialect/LLVMIR/LLVMDialect.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,43 @@ class LLVMType : public mlir::Type::TypeBase<LLVMType, mlir::Type,
static LLVMType getVectorTy(LLVMType elementType, unsigned numElements);
static LLVMType getVoidTy(LLVMDialect *dialect);

// Creation and setting of LLVM's identified struct types
static LLVMType createStructTy(LLVMDialect *dialect,
ArrayRef<LLVMType> elements,
Optional<StringRef> name,
bool isPacked = false);
static LLVMType createStructTy(LLVMDialect *dialect,
Optional<StringRef> name) {
SmallVector<LLVMType, 1> elements;
return createStructTy(dialect, elements, name);
}
static LLVMType createStructTy(ArrayRef<LLVMType> elements,
Optional<StringRef> name,
bool isPacked = false) {
assert(!elements.empty() &&
"This method may not be invoked with an empty list");
LLVMType ele0 = elements.front();
return createStructTy(&ele0.getDialect(), elements, name, isPacked);
}
template <typename... Args>
static typename std::enable_if_t<llvm::are_base_of<LLVMType, Args...>::value,
LLVMType>
createStructTy(StringRef name, LLVMType elt1, Args... elts) {
SmallVector<LLVMType, 8> fields({elt1, elts...});
Optional<StringRef> opt_name(name);
return createStructTy(&elt1.getDialect(), fields, opt_name);
}
static LLVMType setStructTyBody(LLVMType structType,
ArrayRef<LLVMType> elements,
bool isPacked = false);
template <typename... Args>
static typename std::enable_if_t<llvm::are_base_of<LLVMType, Args...>::value,
LLVMType>
setStructTyBody(LLVMType structType, LLVMType elt1, Args... elts) {
SmallVector<LLVMType, 8> fields({elt1, elts...});
return setStructTyBody(structType, fields);
}

private:
friend LLVMDialect;

Expand Down
29 changes: 29 additions & 0 deletions lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1433,6 +1433,35 @@ LLVMType LLVMType::getStructTy(LLVMDialect *dialect,
isPacked);
});
}
inline static SmallVector<llvm::Type *, 8>
toUnderlyingTypes(ArrayRef<LLVMType> elements) {
SmallVector<llvm::Type *, 8> llvmElements;
for (auto elt : elements)
llvmElements.push_back(elt.getUnderlyingType());
return llvmElements;
}
LLVMType LLVMType::createStructTy(LLVMDialect *dialect,
ArrayRef<LLVMType> elements,
Optional<StringRef> name, bool isPacked) {
StringRef sr = name.hasValue() ? *name : "";
SmallVector<llvm::Type *, 8> llvmElements(toUnderlyingTypes(elements));
return getLocked(dialect, [=] {
auto *rv = llvm::StructType::create(dialect->getLLVMContext(), sr);
if (!llvmElements.empty())
rv->setBody(llvmElements, isPacked);
return rv;
});
}
LLVMType LLVMType::setStructTyBody(LLVMType structType,
ArrayRef<LLVMType> elements, bool isPacked) {
llvm::StructType *st =
llvm::cast<llvm::StructType>(structType.getUnderlyingType());
SmallVector<llvm::Type *, 8> llvmElements(toUnderlyingTypes(elements));
return getLocked(&structType.getDialect(), [=] {
st->setBody(llvmElements, isPacked);
return st;
});
}
LLVMType LLVMType::getVectorTy(LLVMType elementType, unsigned numElements) {
// Lock access to the dialect as this may modify the LLVM context.
return getLocked(&elementType.getDialect(), [=] {
Expand Down
3 changes: 3 additions & 0 deletions test/Dialect/LLVMIR/roundtrip.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -205,3 +205,6 @@ func @null() {
%1 = llvm.mlir.null : !llvm<"{void(i32, void()*)*, i64}*">
llvm.return
}

// XXXCHECK: llvm.func @recursive_type(!llvm<"%a = type { %a* }">)
//llvm.func @recursive_type(!llvm<"%a = type { %a* }">)