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

[NNNN] Target Extension Types for Inline SPIR-V and Decorated Types #105

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
130 changes: 130 additions & 0 deletions proposals/nnnn-inline-spirv-and-decorated-types.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
<!-- {% raw %} -->

# Target Extension Types for Inline SPIR-V and Decorated Types

* Proposal: [NNNN](NNNN-filename.md)
* Author(s): [Cassandra Beckley](https://github.com/cassiebeckley)
* Status: **Design In Progress**

## Introduction

In this proposal, we define the `spirv.inline.Type` and `spirv.DecoratedType`
target extension types for the SPIR-V backend.

## Motivation

We would like to implement `SpirvType` and `SpirvOpaqueType` from [Inline
SPIR-V (HLSL proposal 0011)](https://github.com/microsoft/hlsl-specs/blob/main/proposals/0011-inline-spirv.md#types)
in the SPIR-V backend. These allow users to create arbitrary `OpType`
instructions, and use them like any other HLSL type. Using these types, a
vendor creating a new extension can expose it to users by creating a header
file without needing to modify the compiler.

Additionally, we need a way to represent types with SPIR-V decorations in LLVM
IR.

## Proposed solution

### SpirvType

To represent `vk::SpirvType` and `vk::SpirvOpaqueType` in LLVM IR, we will add
three new target extension types:

* `spirv.inline.Type`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you looked into how the size and alignment information can be encoded? How do you get TargetExtType::getLayoutType() to return the right value?

https://llvm.org/doxygen/classllvm_1_1TargetExtType.html#ae473a097292848f10f82f0961245e012

Are we okay with it returning void? It seems like the information comes from getTargetTypeInfo in Type.cpp. Will you be able to set this properly? Do we need optional integer arguments that have the size and alignment?

If we do have the size and alignment, what is the layout type?

Also, which properties should be set?

* `spirv.inline.IntegralConstant`
* `spirv.inline.Literal`
Comment on lines +33 to +35
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason we need inline in the name? I think it could be removed in all of the types.


`IntegralConstant` and `Literal` are used to encode arguments to `Type`, and
may not be used outside that context. They are necessary because target
extension types must have all type arguments precede all integer arguments,
whereas SPIR-V type instructions may have an arbitrary number of type,
immediate literal, and constant id operands in any order.

#### `spirv.inline.Type`

```
target("spirv.inline.Type", operands..., opcode)
```

`opcode` is an integer literal representing the opcode of the `OpType`
instruction to be generated. `operands` represents a list of type arguments
encoding the operands of the `OpType` instruction. Each operand must be one of:

* A type argument, which will be lowered to the id of the lowered SPIR-V type
* A `spirv.inline.IntegralConstant`, which will be lowered to the id of an
`OpConstant` instruction
* A `spirv.inline.Literal`, which will be lowered to an immediate literal value

#### `spirv.inline.IntegralConstant`

```
target("spirv.inline.IntegralConstant", integral_type, value)
```

`integral_type` is the type argument for the `OpConstant` instruction to be
generated, and `value` is its literal integer value.

#### `spirv.inline.Literal`

```
target("spirv.inline.Literal", value)
```

`value` is a `spirv.inline.IntegralConstant` type which represents the literal
integer value to be generated.

#### Example

Here's an example of using these types to represent an array of images:

```
%type_2d_image = type target("spirv.Image", float, 1, 2, 0, 0, 1, 0)
%integral_constant_28 = type target("spirv.inline.IntegralConstant", i32, 28)
%integral_constant_4 = type target("spirv.inline.IntegralConstant", i32, 4)
%ArrayTex2D = type target("spirv.inline.Type", %type_2d_image, %integral_constant_4, 28)
```

### Type decorations
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should mention that this is related to the decoration attribute in inline spir-v, which can only be applied to types and member variables. Talk about how that attribute will be translated into something of this type. I believe this has alternative solutions that we discussed. The might be worth mentioning in the alternative solutions seciton.

Lastly, you need to consider all versions of the decoration, decorateId and decorateString? Do we want multiple versions? Use the IngralConstant, Literal, and some other String class?

Sorry, I should have mentioned these variants when I asked you to include the decorations in this design.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also I had not noticed int_spv_assign_decoration in https://github.com/llvm/llvm-project/blob/main/llvm/docs/SPIRVUsage.rst#target-intrinsics. We should explain why we are not using it, if we decide not to use it. If it does work for us, then that could be a better solution.


In order to represent types with SPIR-V decorations added, we define a new
`spirv.DecoratedType` target extension type.

```
target("spirv.DecoratedType", type, decoration)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some decorations have operands. This might need to be more general.

```

`type` is any valid LLVM IR type, and `decoration` is the integer value of the
decoration, as defined in Section [3.20. Decoration](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#_decoration)
of the SPIR-V Specification. This will create a unique SPIR-V type with the
specified `OpDecoration`.
Comment on lines +98 to +99
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would call out more explicitly this does not add a decoration to the id for type. In must create a new type with a new id.


<!--
## Detailed design

_The detailed design is not required until the feature is under review._

This section should grow into a full specification that will provide enough
information for someone who isn't the proposal author to implement the feature.
It should also serve as the basis for documentation for the feature. Each
feature will need different levels of detail here, but some common things to
think through are:

* Is there any potential for changed behavior?
* Will this expose new interfaces that will have support burden?
* How will this proposal be tested?
* Does this require additional hardware/software/human resources?
* What documentation should be updated or authored?

## Alternatives considered (Optional)

If alternative solutions were considered, please provide a brief overview. This
section can also be populated based on conversations that occur during
reviewing.

## Acknowledgments (Optional)

Take a moment to acknowledge the contributions of people other than the author
and sponsor.
-->

<!-- {% endraw %} -->