[PATCH] D72542: [Flang] add a band-aid to support the creation of mutually recursive types when lowering to LLVM IR
Eric Schweitz via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 10 14:35:52 PST 2020
schweitz created this revision.
schweitz added reviewers: ftynse, rriddle, mehdi_amini.
schweitz added a project: Flang.
Herald added a reviewer: jdoerfert.
Herald added subscribers: llvm-commits, lucyrfox, mgester, arpith-jacob, nicolasvasilache, antiagainst, shauheen, burmako, jpienaar.
Herald added a project: LLVM.
This is a temporary implementation to support Flang. The LLVM-IR parser will need to be extended in some way to support recursive types. The exact approach here is still a work-in-progress.
Unfortunately, this won't pass roundtrip testing yet. Adding a comment to the test file as a reminder.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D72542
Files:
mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.h
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
mlir/test/Dialect/LLVMIR/roundtrip.mlir
Index: mlir/test/Dialect/LLVMIR/roundtrip.mlir
===================================================================
--- mlir/test/Dialect/LLVMIR/roundtrip.mlir
+++ mlir/test/Dialect/LLVMIR/roundtrip.mlir
@@ -218,3 +218,6 @@
%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* }">)
Index: mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
===================================================================
--- mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -1641,6 +1641,35 @@
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(), [=] {
Index: mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.h
===================================================================
--- mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.h
+++ mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.h
@@ -138,6 +138,43 @@
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;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D72542.237435.patch
Type: text/x-patch
Size: 4364 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200110/5a6be845/attachment.bin>
More information about the llvm-commits
mailing list