[Mlir-commits] [mlir] aa00e3e - [mlir][llvm] Support pointer entries in data layout translation

llvmlistbot at llvm.org llvmlistbot at llvm.org
Wed Sep 21 08:16:24 PDT 2022


Author: rkayaith
Date: 2022-09-21T11:16:15-04:00
New Revision: aa00e3e6c107a914a20e118782073f039c785abc

URL: https://github.com/llvm/llvm-project/commit/aa00e3e6c107a914a20e118782073f039c785abc
DIFF: https://github.com/llvm/llvm-project/commit/aa00e3e6c107a914a20e118782073f039c785abc.diff

LOG: [mlir][llvm] Support pointer entries in data layout translation

This adds support for pointer DLTI entries in LLVMIR export, e.g.
```
// translated to: p0:32:64:128
#dlti.dl_entry<!llvm.ptr, dense<[32,64,128]> : vector<3xi32>>
// translated to: p1:32:32:32:64
#dlti.dl_entry<!llvm.ptr<1>, dense<[32,32,32,64]> : vector<4xi32>>
```

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D133434

Added: 
    

Modified: 
    mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.h
    mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp
    mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
    mlir/test/Target/LLVMIR/data-layout.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.h b/mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.h
index ce69a2e583aeb..1f307c2aa7372 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.h
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.h
@@ -535,6 +535,15 @@ Type getScalableVectorType(Type elementType, unsigned numElements);
 /// (aggregates such as struct) or types that don't have a size (such as void).
 llvm::TypeSize getPrimitiveTypeSizeInBits(Type type);
 
+/// The positions of 
diff erent values in the data layout entry for pointers.
+enum class PtrDLEntryPos { Size = 0, Abi = 1, Preferred = 2, Index = 3 };
+
+/// Returns the value that corresponds to named position `pos` from the
+/// data layout entry `attr` assuming it's a dense integer elements attribute.
+/// Returns `None` if `pos` is not present in the entry.
+/// Currently only `PtrDLEntryPos::Index` is optional, and all other positions
+/// may be assumed to be present.
+Optional<unsigned> extractPointerSpecValue(Attribute attr, PtrDLEntryPos pos);
 } // namespace LLVM
 } // namespace mlir
 

diff  --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp
index 3f39a6e07748b..80dcfa84f6937 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp
@@ -229,19 +229,16 @@ LLVMPointerType::verify(function_ref<InFlightDiagnostic()> emitError,
   return success();
 }
 
-namespace {
-/// The positions of 
diff erent values in the data layout entry.
-enum class DLEntryPos { Size = 0, Abi = 1, Preferred = 2, Address = 3 };
-} // namespace
-
 constexpr const static unsigned kDefaultPointerSizeBits = 64;
 constexpr const static unsigned kDefaultPointerAlignment = 8;
 
-/// Returns the value that corresponds to named position `pos` from the
-/// attribute `attr` assuming it's a dense integer elements attribute.
-static unsigned extractPointerSpecValue(Attribute attr, DLEntryPos pos) {
-  return attr.cast<DenseIntElementsAttr>()
-      .getValues<unsigned>()[static_cast<unsigned>(pos)];
+Optional<unsigned> mlir::LLVM::extractPointerSpecValue(Attribute attr,
+                                                       PtrDLEntryPos pos) {
+  auto spec = attr.cast<DenseIntElementsAttr>();
+  auto idx = static_cast<unsigned>(pos);
+  if (idx >= spec.size())
+    return None;
+  return spec.getValues<unsigned>()[idx];
 }
 
 /// Returns the part of the data layout entry that corresponds to `pos` for the
@@ -250,7 +247,7 @@ static unsigned extractPointerSpecValue(Attribute attr, DLEntryPos pos) {
 /// do not provide a custom one, for other address spaces returns None.
 static Optional<unsigned>
 getPointerDataLayoutEntry(DataLayoutEntryListRef params, LLVMPointerType type,
-                          DLEntryPos pos) {
+                          PtrDLEntryPos pos) {
   // First, look for the entry for the pointer in the current address space.
   Attribute currentEntry;
   for (DataLayoutEntryInterface entry : params) {
@@ -263,15 +260,15 @@ getPointerDataLayoutEntry(DataLayoutEntryListRef params, LLVMPointerType type,
     }
   }
   if (currentEntry) {
-    return extractPointerSpecValue(currentEntry, pos) /
-           (pos == DLEntryPos::Size ? 1 : kBitsInByte);
+    return *extractPointerSpecValue(currentEntry, pos) /
+           (pos == PtrDLEntryPos::Size ? 1 : kBitsInByte);
   }
 
   // If not found, and this is the pointer to the default memory space, assume
   // 64-bit pointers.
   if (type.getAddressSpace() == 0) {
-    return pos == DLEntryPos::Size ? kDefaultPointerSizeBits
-                                   : kDefaultPointerAlignment;
+    return pos == PtrDLEntryPos::Size ? kDefaultPointerSizeBits
+                                      : kDefaultPointerAlignment;
   }
 
   return llvm::None;
@@ -281,7 +278,7 @@ unsigned
 LLVMPointerType::getTypeSizeInBits(const DataLayout &dataLayout,
                                    DataLayoutEntryListRef params) const {
   if (Optional<unsigned> size =
-          getPointerDataLayoutEntry(params, *this, DLEntryPos::Size))
+          getPointerDataLayoutEntry(params, *this, PtrDLEntryPos::Size))
     return *size;
 
   // For other memory spaces, use the size of the pointer to the default memory
@@ -294,7 +291,7 @@ LLVMPointerType::getTypeSizeInBits(const DataLayout &dataLayout,
 unsigned LLVMPointerType::getABIAlignment(const DataLayout &dataLayout,
                                           DataLayoutEntryListRef params) const {
   if (Optional<unsigned> alignment =
-          getPointerDataLayoutEntry(params, *this, DLEntryPos::Abi))
+          getPointerDataLayoutEntry(params, *this, PtrDLEntryPos::Abi))
     return *alignment;
 
   if (isOpaque())
@@ -306,7 +303,7 @@ unsigned
 LLVMPointerType::getPreferredAlignment(const DataLayout &dataLayout,
                                        DataLayoutEntryListRef params) const {
   if (Optional<unsigned> alignment =
-          getPointerDataLayoutEntry(params, *this, DLEntryPos::Preferred))
+          getPointerDataLayoutEntry(params, *this, PtrDLEntryPos::Preferred))
     return *alignment;
 
   if (isOpaque())
@@ -339,13 +336,13 @@ bool LLVMPointerType::areCompatible(DataLayoutEntryListRef oldLayout,
       });
     }
     if (it != oldLayout.end()) {
-      size = extractPointerSpecValue(*it, DLEntryPos::Size);
-      abi = extractPointerSpecValue(*it, DLEntryPos::Abi);
+      size = *extractPointerSpecValue(*it, PtrDLEntryPos::Size);
+      abi = *extractPointerSpecValue(*it, PtrDLEntryPos::Abi);
     }
 
     Attribute newSpec = newEntry.getValue().cast<DenseIntElementsAttr>();
-    unsigned newSize = extractPointerSpecValue(newSpec, DLEntryPos::Size);
-    unsigned newAbi = extractPointerSpecValue(newSpec, DLEntryPos::Abi);
+    unsigned newSize = *extractPointerSpecValue(newSpec, PtrDLEntryPos::Size);
+    unsigned newAbi = *extractPointerSpecValue(newSpec, PtrDLEntryPos::Abi);
     if (size != newSize || abi < newAbi || abi % newAbi != 0)
       return false;
   }
@@ -369,8 +366,8 @@ LogicalResult LLVMPointerType::verifyEntries(DataLayoutEntryListRef entries,
       return emitError(loc) << "unexpected layout attribute for pointer to "
                             << key.getElementType();
     }
-    if (extractPointerSpecValue(values, DLEntryPos::Abi) >
-        extractPointerSpecValue(values, DLEntryPos::Preferred)) {
+    if (extractPointerSpecValue(values, PtrDLEntryPos::Abi) >
+        extractPointerSpecValue(values, PtrDLEntryPos::Preferred)) {
       return emitError(loc) << "preferred alignment is expected to be at least "
                                "as large as ABI alignment";
     }

diff  --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index 07054a9cacb33..15036116e8abc 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -52,8 +52,8 @@ using namespace mlir::LLVM::detail;
 #include "mlir/Dialect/LLVMIR/LLVMConversionEnumsToLLVM.inc"
 
 /// Translates the given data layout spec attribute to the LLVM IR data layout.
-/// Only integer, float and endianness entries are currently supported.
-FailureOr<llvm::DataLayout>
+/// Only integer, float, pointer and endianness entries are currently supported.
+static FailureOr<llvm::DataLayout>
 translateDataLayout(DataLayoutSpecInterface attribute,
                     const DataLayout &dataLayout,
                     Optional<Location> loc = llvm::None) {
@@ -80,8 +80,8 @@ translateDataLayout(DataLayoutSpecInterface attribute,
   }
 
   // Go through the list of entries to check which types are explicitly
-  // specified in entries. Don't use the entries directly though but query the
-  // data from the layout.
+  // specified in entries. Where possible, data layout queries are used instead
+  // of directly inspecting the entries.
   for (DataLayoutEntryInterface entry : attribute.getEntries()) {
     auto type = entry.getKey().dyn_cast<Type>();
     if (!type)
@@ -89,32 +89,47 @@ translateDataLayout(DataLayoutSpecInterface attribute,
     // Data layout for the index type is irrelevant at this point.
     if (type.isa<IndexType>())
       continue;
-    FailureOr<std::string> prefix =
-        llvm::TypeSwitch<Type, FailureOr<std::string>>(type)
-            .Case<IntegerType>(
-                [loc](IntegerType integerType) -> FailureOr<std::string> {
-                  if (integerType.getSignedness() == IntegerType::Signless)
-                    return std::string("i");
-                  emitError(*loc)
-                      << "unsupported data layout for non-signless integer "
-                      << integerType;
-                  return failure();
-                })
-            .Case<Float16Type, Float32Type, Float64Type, Float80Type,
-                  Float128Type>([](Type) { return std::string("f"); })
-            .Default([loc](Type type) -> FailureOr<std::string> {
-              emitError(*loc) << "unsupported type in data layout: " << type;
-              return failure();
+    layoutStream << "-";
+    LogicalResult result =
+        llvm::TypeSwitch<Type, LogicalResult>(type)
+            .Case<IntegerType, Float16Type, Float32Type, Float64Type,
+                  Float80Type, Float128Type>([&](Type type) -> LogicalResult {
+              if (auto intType = type.dyn_cast<IntegerType>()) {
+                if (intType.getSignedness() != IntegerType::Signless)
+                  return emitError(*loc)
+                         << "unsupported data layout for non-signless integer "
+                         << intType;
+                layoutStream << "i";
+              } else {
+                layoutStream << "f";
+              }
+              unsigned size = dataLayout.getTypeSizeInBits(type);
+              unsigned abi = dataLayout.getTypeABIAlignment(type) * 8u;
+              unsigned preferred =
+                  dataLayout.getTypePreferredAlignment(type) * 8u;
+              layoutStream << size << ":" << abi;
+              if (abi != preferred)
+                layoutStream << ":" << preferred;
+              return success();
+            })
+            .Case([&](LLVMPointerType ptrType) {
+              layoutStream << "p" << ptrType.getAddressSpace() << ":";
+              unsigned size = dataLayout.getTypeSizeInBits(type);
+              unsigned abi = dataLayout.getTypeABIAlignment(type) * 8u;
+              unsigned preferred =
+                  dataLayout.getTypePreferredAlignment(type) * 8u;
+              layoutStream << size << ":" << abi << ":" << preferred;
+              if (Optional<unsigned> index = extractPointerSpecValue(
+                      entry.getValue(), PtrDLEntryPos::Index))
+                layoutStream << ":" << *index;
+              return success();
+            })
+            .Default([loc](Type type) {
+              return emitError(*loc)
+                     << "unsupported type in data layout: " << type;
             });
-    if (failed(prefix))
+    if (failed(result))
       return failure();
-
-    unsigned size = dataLayout.getTypeSizeInBits(type);
-    unsigned abi = dataLayout.getTypeABIAlignment(type) * 8u;
-    unsigned preferred = dataLayout.getTypePreferredAlignment(type) * 8u;
-    layoutStream << "-" << *prefix << size << ":" << abi;
-    if (abi != preferred)
-      layoutStream << ":" << preferred;
   }
   layoutStream.flush();
   StringRef layoutSpec(llvmDataLayout);

diff  --git a/mlir/test/Target/LLVMIR/data-layout.mlir b/mlir/test/Target/LLVMIR/data-layout.mlir
index ba8960f38b8d2..5840bcf700dd2 100644
--- a/mlir/test/Target/LLVMIR/data-layout.mlir
+++ b/mlir/test/Target/LLVMIR/data-layout.mlir
@@ -4,11 +4,15 @@
 // CHECK: E-
 // CHECK: i64:64:128
 // CHECK: f80:128:256
+// CHECK: p0:32:64:128
+// CHECK: p1:32:32:32:64
 module attributes {dlti.dl_spec = #dlti.dl_spec<
 #dlti.dl_entry<"dlti.endianness", "big">,
 #dlti.dl_entry<index, 64>,
 #dlti.dl_entry<i64, dense<[64,128]> : vector<2xi32>>,
-#dlti.dl_entry<f80, dense<[128,256]> : vector<2xi32>>
+#dlti.dl_entry<f80, dense<[128,256]> : vector<2xi32>>,
+#dlti.dl_entry<!llvm.ptr, dense<[32,64,128]> : vector<3xi32>>,
+#dlti.dl_entry<!llvm.ptr<1>, dense<[32,32,32,64]> : vector<4xi32>>
 >} {
   llvm.func @foo() {
     llvm.return


        


More information about the Mlir-commits mailing list