[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