Skip to content
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

[MLIR] Tablegen Doesn't Copy ArrayRef In Generated Type Storage Class Constructor #63

Closed
zzzDavid opened this issue Apr 15, 2022 · 1 comment
Assignees
Labels
bug Something isn't working

Comments

@zzzDavid
Copy link
Collaborator

zzzDavid commented Apr 15, 2022

This is a weird MLIR tablegen issue I came across when I try to add a hcl.struct type.

The struct tablegen type definition is like this:

def Struct : HeteroCL_Type<"Struct"> {
  let summary = "struct type";
  let mnemonic = "struct";
  let parameters = (ins "ArrayRef<Type>":$elementTypes);
  let printer = [{
    $_printer << "<";
    llvm::interleaveComma(getImpl()->elementTypes, $_printer);
    $_printer << '>';
  }];
  let parser = [{
    if ($_parser.parseLess())
      return Type();
    SmallVector<mlir::Type, 1> elementTypes;
    do {
      mlir::Type elementType;
      if ($_parser.parseType(elementType))
        return nullptr;

      elementTypes.push_back(elementType);
    } while (succeeded($_parser.parseOptionalComma()));

    if ($_parser.parseGreater())
      return Type();
    return get($_ctxt, elementTypes);
  }];
}

As we have parameters, there will be a TypeStorage class generated by tablegen, the constructor of that type storage class looks like this:

  static StructTypeStorage *construct(::mlir::TypeStorageAllocator &allocator, const KeyTy &tblgenKey) {
    auto elementTypes = std::get<0>(tblgenKey);
    // We need: auto elementTypes = allocator.copyInto(std::get<0>(tblgenKey));
    return new (allocator.allocate<StructTypeStorage>()) StructTypeStorage(elementTypes);
  }

The elementTypes is an array member of the storage class: ArrayRef<Type> elementTypes. We need to do an allocator.copyInto when constructing the TypeStorage object (uniquing the type object), or else we get this error:

mlir/include/mlir/IR/TypeSupport.h:128: const mlir::AbstractType& mlir::TypeStorage::getAbstractType(): Assertion `abstractType && "Malformed type storage object." failed.

Segmentation fault.
Aborted
@zzzDavid zzzDavid added the bug Something isn't working label Apr 15, 2022
@zzzDavid zzzDavid added this to the Integration tests milestone Apr 15, 2022
@zzzDavid zzzDavid self-assigned this Apr 15, 2022
@zzzDavid
Copy link
Collaborator Author

It turns out there's a special syntax for ArrayRef: https://github.com/llvm/llvm-project/blob/09c2b7c35af8c4bad39f03e9f60df8bd07323028/mlir/test/lib/Dialect/Test/TestTypeDefs.td#L42

After using this syntax in the tablegen def, everything works fine:

def Struct : HeteroCL_Type<"Struct"> {
  let summary = "struct type";
  let mnemonic = "struct";
  let parameters = (ins ArrayRefParameter<"Type", "elementTypes">:$elementTypes);
  let printer = [{
    $_printer << "<";
    llvm::interleaveComma(getImpl()->elementTypes, $_printer);
    $_printer << '>';
  }];
  let parser = [{
    if ($_parser.parseLess())
      return Type();
    SmallVector<mlir::Type, 1> elementTypes;
    do {
      mlir::Type elementType;
      if ($_parser.parseType(elementType))
        return nullptr;

      elementTypes.push_back(elementType);
    } while (succeeded($_parser.parseOptionalComma()));

    if ($_parser.parseGreater())
      return Type();
    return get($_ctxt, elementTypes);
  }];
}

The more you know 💫

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant