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

[CIR][Dialect] Emit OpenCL kernel metadata #705

Merged
merged 2 commits into from
Jul 10, 2024

Conversation

seven-mile
Copy link
Collaborator

This PR introduces a new attribute OpenCLKernelMetadataAttr to model the OpenCL kernel metadata structurally in CIR, with its corresponding implementations of CodeGen, Lowering and Translation.

The "TypeAttr":$vec_type_hint part is tricky because of the absence of the signless feature of LLVM IR, while SPIR-V requires it. According to the spec, the final LLVM IR should encode signedness with an extra i32 boolean value.

In this PR, the droping logic from CIR's TypeConverter is still used to avoid code duplication when lowering to LLVM dialect. However, the signedness is then restored (still capsuled by a CIR attribute) and dropped again in the translation into LLVM IR.

@seven-mile
Copy link
Collaborator Author

For LLVM metadata that are not included in the LLVM dialect, we have to design our own attributes and passthrough it in the translation according to this thread.

Threrefore, an ideal method would be lowering from CIR attribute to LLVM IR directly. But unfortunatly we cannot access CIR's TypeConverter (produced by prepareTypeConverter) when doing translation. So a workaround of restoring and dropping again is used.

@seven-mile seven-mile changed the title [CIR][Dialect] Emit OpenCL Kernel Metadata [CIR][Dialect] Emit OpenCL kernel metadata Jun 28, 2024
Copy link
Member

@bcardosolopes bcardosolopes left a comment

Choose a reason for hiding this comment

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

In this PR, the droping logic from CIR's TypeConverter is still used to avoid code duplication when lowering to LLVM dialect. However, the signedness is then restored (still capsuled by a CIR attribute) and dropped again in the translation into LLVM IR.

I'm not sure I understand the problem here.

Threrefore, an ideal method would be lowering from CIR attribute to LLVM IR directly. But unfortunatly we cannot access CIR's TypeConverter (produced by prepareTypeConverter) when doing translation. So a workaround of restoring and dropping again is used.

Same here. Can you please describe how VecTypeHintAttrwith works with examples? Perhaps I might suggest a more clean solution.

clang/include/clang/CIR/Dialect/IR/CIRAttrs.td Outdated Show resolved Hide resolved
clang/include/clang/CIR/Dialect/IR/CIRAttrs.td Outdated Show resolved Hide resolved
clang/include/clang/CIR/Dialect/IR/CIRAttrs.td Outdated Show resolved Hide resolved
clang/include/clang/CIR/Dialect/IR/CIRAttrs.td Outdated Show resolved Hide resolved
clang/lib/CIR/CodeGen/CIRGenFunction.cpp Outdated Show resolved Hide resolved
clang/include/clang/CIR/Dialect/IR/CIRAttrs.td Outdated Show resolved Hide resolved
clang/include/clang/CIR/Dialect/IR/CIRAttrs.td Outdated Show resolved Hide resolved
clang/include/clang/CIR/Dialect/IR/CIRAttrs.td Outdated Show resolved Hide resolved
clang/include/clang/CIR/Dialect/IR/CIRAttrs.td Outdated Show resolved Hide resolved
clang/lib/CIR/CodeGen/CIRGenFunction.cpp Outdated Show resolved Hide resolved
@seven-mile
Copy link
Collaborator Author

There are three stages for vec_type_hint here: CIR -[Lowering]-> LLVM dialect -[Translation]-> LLVM IR. This is how it works currently in this PR:

  • In CIR, the IntType carries the signedness information from source code already. e.g. TypeAttr<!cir.s32i>
  • In LLVM dialect, the signedness information must be dropped after the type conversion. TypeAttr<!builtin.i32> (signless)
  • But we immediately restore it then, we replace the type with TypeAttr<!builtin.si32> (signed)
  • When doing translation, we have to provide the extra boolean bit for the signedness information according to the spec. Now we can read the restored signedness information and emit it directly. setMetadata(type: i32, signedness: 1)
  • However, we should drop it again before converting it to the type of LLVM IR (llvm::Type*), as signed integers are not a valid type in LLVM dialect / IR. TypeAttr<!builtin.i32> (signless again)

The official solution to attach metadata to LLVM IR is to call llvm::Function::setMetadata by manipulating the translation interface. If we are able to deal with TypeAttr<!cir.s32i> directly in translation, we can also emit the signedness bit straightforward, without such a workaround. But the precondition means "CIR's type converter is available for LLVM translation interface", which is not true currently (affects both clang -fclangir and cir-opt). There are no available reference for such usage, I'm not sure if it's a good practice. What do you think?

When designing the attribute, I tend to make it simple in CIR and use conservative (maybe dirty) methods for translation. The flaw resides in the mechanism of LLVM dialect, overall we should not pay for it when designing CIR. So I insist not just adding an redundant signedness bit in the attribute. Another option is to attatch the extra signedness bit to the attribute only when lowering to LLVM dialect. But that requires us to duplicate the attribute (a dedicated OpenCLKernelLLVMMetadataAttr) and also overcomplicate the IR.

As for the expensive overhead of for-loop replacement, nice catch, thanks! TBH immutable-dict-based extra-attrs is not very easy to use, while the semantics of replace make it clearer and easier to review. I can apply better indexing-based (rather than search-based) mutation after we make some progress on the discussion. The actual cost of this method should be to find out the OpenCLKernelMetadataAttr then.

Usually I want to propose a best-efforts conservative approach, to improve the acceptance of potential radical changes in the future. So I'm always open to any cleaner solutions.

Copy link
Member

@bcardosolopes bcardosolopes left a comment

Choose a reason for hiding this comment

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

Thanks for the comprehensive explanation, I have a better understanding of the problem now. Added extra comments w.r.t. of what needs to be done next, keep in mind we should not over design for use cases we don't have, and keep this simple instead.

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp Outdated Show resolved Hide resolved
clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp Outdated Show resolved Hide resolved
@seven-mile
Copy link
Collaborator Author

Updated.

Copy link
Contributor

@jopperm jopperm left a comment

Choose a reason for hiding this comment

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

Approach LGTM!

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVMIR.cpp Outdated Show resolved Hide resolved
clang/lib/CIR/Dialect/IR/CIRAttrs.cpp Outdated Show resolved Hide resolved
clang/lib/CIR/Dialect/IR/CIRAttrs.cpp Outdated Show resolved Hide resolved
clang/lib/CIR/Dialect/IR/CIRAttrs.cpp Outdated Show resolved Hide resolved
Copy link
Member

@bcardosolopes bcardosolopes left a comment

Choose a reason for hiding this comment

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

Thanks for the changes, few more nits

clang/include/clang/CIR/Dialect/IR/CIROpenCLAttrs.td Outdated Show resolved Hide resolved
Copy link
Member

@bcardosolopes bcardosolopes left a comment

Choose a reason for hiding this comment

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

Awesome job, thanks! LGTM

@bcardosolopes bcardosolopes merged commit 2710188 into llvm:main Jul 10, 2024
6 checks passed
bcardosolopes pushed a commit that referenced this pull request Aug 2, 2024
Similar to #705, this PR implements the remaining
`genKernelArgMetadata()` logic.

The attribute `cir.cl.kernel_arg_metadata` is also intentionally placed
in the `cir.func`'s `extra_attrs` rather than `cir.func`'s standard
`arg_attrs` list. Also, the metadata is stored by `Array` with proper
verification on it. See the tablegen doc string for details.

This is in order to
* keep it side-by-side with `cl.kernel_metadata`.
* still emit metadata when kernel has an *empty* arg list (see the test
`kernel-arg-meatadata.cl`).
* avoid horrors of repeating the long name `cir.cl.kernel_arg_metadata`
for `numArgs` times.

Because clangir doesn't support OpenCL built-in types and the `half`
floating point type yet, their changes and test cases are not included.
Corresponding missing feature flag is added.
Hugobros3 pushed a commit to shady-gang/clangir that referenced this pull request Oct 2, 2024
This PR introduces a new attribute `OpenCLKernelMetadataAttr` to model
the OpenCL kernel metadata structurally in CIR, with its corresponding
implementations of CodeGen, Lowering and Translation.

The `"TypeAttr":$vec_type_hint` part is tricky because of the absence of
the signless feature of LLVM IR, while SPIR-V requires it. According to
the spec, the final LLVM IR should encode signedness with an extra `i32`
boolean value.

In this PR, the droping logic from CIR's `TypeConverter` is still used
to avoid code duplication when lowering to LLVM dialect. However, the
signedness is then restored (still capsuled by a CIR attribute) and
dropped again in the translation into LLVM IR.
Hugobros3 pushed a commit to shady-gang/clangir that referenced this pull request Oct 2, 2024
Similar to llvm#705, this PR implements the remaining
`genKernelArgMetadata()` logic.

The attribute `cir.cl.kernel_arg_metadata` is also intentionally placed
in the `cir.func`'s `extra_attrs` rather than `cir.func`'s standard
`arg_attrs` list. Also, the metadata is stored by `Array` with proper
verification on it. See the tablegen doc string for details.

This is in order to
* keep it side-by-side with `cl.kernel_metadata`.
* still emit metadata when kernel has an *empty* arg list (see the test
`kernel-arg-meatadata.cl`).
* avoid horrors of repeating the long name `cir.cl.kernel_arg_metadata`
for `numArgs` times.

Because clangir doesn't support OpenCL built-in types and the `half`
floating point type yet, their changes and test cases are not included.
Corresponding missing feature flag is added.
smeenai pushed a commit to smeenai/clangir that referenced this pull request Oct 9, 2024
This PR introduces a new attribute `OpenCLKernelMetadataAttr` to model
the OpenCL kernel metadata structurally in CIR, with its corresponding
implementations of CodeGen, Lowering and Translation.

The `"TypeAttr":$vec_type_hint` part is tricky because of the absence of
the signless feature of LLVM IR, while SPIR-V requires it. According to
the spec, the final LLVM IR should encode signedness with an extra `i32`
boolean value.

In this PR, the droping logic from CIR's `TypeConverter` is still used
to avoid code duplication when lowering to LLVM dialect. However, the
signedness is then restored (still capsuled by a CIR attribute) and
dropped again in the translation into LLVM IR.
smeenai pushed a commit to smeenai/clangir that referenced this pull request Oct 9, 2024
Similar to llvm#705, this PR implements the remaining
`genKernelArgMetadata()` logic.

The attribute `cir.cl.kernel_arg_metadata` is also intentionally placed
in the `cir.func`'s `extra_attrs` rather than `cir.func`'s standard
`arg_attrs` list. Also, the metadata is stored by `Array` with proper
verification on it. See the tablegen doc string for details.

This is in order to
* keep it side-by-side with `cl.kernel_metadata`.
* still emit metadata when kernel has an *empty* arg list (see the test
`kernel-arg-meatadata.cl`).
* avoid horrors of repeating the long name `cir.cl.kernel_arg_metadata`
for `numArgs` times.

Because clangir doesn't support OpenCL built-in types and the `half`
floating point type yet, their changes and test cases are not included.
Corresponding missing feature flag is added.
smeenai pushed a commit to smeenai/clangir that referenced this pull request Oct 9, 2024
This PR introduces a new attribute `OpenCLKernelMetadataAttr` to model
the OpenCL kernel metadata structurally in CIR, with its corresponding
implementations of CodeGen, Lowering and Translation.

The `"TypeAttr":$vec_type_hint` part is tricky because of the absence of
the signless feature of LLVM IR, while SPIR-V requires it. According to
the spec, the final LLVM IR should encode signedness with an extra `i32`
boolean value.

In this PR, the droping logic from CIR's `TypeConverter` is still used
to avoid code duplication when lowering to LLVM dialect. However, the
signedness is then restored (still capsuled by a CIR attribute) and
dropped again in the translation into LLVM IR.
smeenai pushed a commit to smeenai/clangir that referenced this pull request Oct 9, 2024
Similar to llvm#705, this PR implements the remaining
`genKernelArgMetadata()` logic.

The attribute `cir.cl.kernel_arg_metadata` is also intentionally placed
in the `cir.func`'s `extra_attrs` rather than `cir.func`'s standard
`arg_attrs` list. Also, the metadata is stored by `Array` with proper
verification on it. See the tablegen doc string for details.

This is in order to
* keep it side-by-side with `cl.kernel_metadata`.
* still emit metadata when kernel has an *empty* arg list (see the test
`kernel-arg-meatadata.cl`).
* avoid horrors of repeating the long name `cir.cl.kernel_arg_metadata`
for `numArgs` times.

Because clangir doesn't support OpenCL built-in types and the `half`
floating point type yet, their changes and test cases are not included.
Corresponding missing feature flag is added.
keryell pushed a commit to keryell/clangir that referenced this pull request Oct 19, 2024
This PR introduces a new attribute `OpenCLKernelMetadataAttr` to model
the OpenCL kernel metadata structurally in CIR, with its corresponding
implementations of CodeGen, Lowering and Translation.

The `"TypeAttr":$vec_type_hint` part is tricky because of the absence of
the signless feature of LLVM IR, while SPIR-V requires it. According to
the spec, the final LLVM IR should encode signedness with an extra `i32`
boolean value.

In this PR, the droping logic from CIR's `TypeConverter` is still used
to avoid code duplication when lowering to LLVM dialect. However, the
signedness is then restored (still capsuled by a CIR attribute) and
dropped again in the translation into LLVM IR.
keryell pushed a commit to keryell/clangir that referenced this pull request Oct 19, 2024
Similar to llvm#705, this PR implements the remaining
`genKernelArgMetadata()` logic.

The attribute `cir.cl.kernel_arg_metadata` is also intentionally placed
in the `cir.func`'s `extra_attrs` rather than `cir.func`'s standard
`arg_attrs` list. Also, the metadata is stored by `Array` with proper
verification on it. See the tablegen doc string for details.

This is in order to
* keep it side-by-side with `cl.kernel_metadata`.
* still emit metadata when kernel has an *empty* arg list (see the test
`kernel-arg-meatadata.cl`).
* avoid horrors of repeating the long name `cir.cl.kernel_arg_metadata`
for `numArgs` times.

Because clangir doesn't support OpenCL built-in types and the `half`
floating point type yet, their changes and test cases are not included.
Corresponding missing feature flag is added.
lanza pushed a commit that referenced this pull request Nov 5, 2024
This PR introduces a new attribute `OpenCLKernelMetadataAttr` to model
the OpenCL kernel metadata structurally in CIR, with its corresponding
implementations of CodeGen, Lowering and Translation.

The `"TypeAttr":$vec_type_hint` part is tricky because of the absence of
the signless feature of LLVM IR, while SPIR-V requires it. According to
the spec, the final LLVM IR should encode signedness with an extra `i32`
boolean value.

In this PR, the droping logic from CIR's `TypeConverter` is still used
to avoid code duplication when lowering to LLVM dialect. However, the
signedness is then restored (still capsuled by a CIR attribute) and
dropped again in the translation into LLVM IR.
lanza pushed a commit that referenced this pull request Nov 5, 2024
Similar to #705, this PR implements the remaining
`genKernelArgMetadata()` logic.

The attribute `cir.cl.kernel_arg_metadata` is also intentionally placed
in the `cir.func`'s `extra_attrs` rather than `cir.func`'s standard
`arg_attrs` list. Also, the metadata is stored by `Array` with proper
verification on it. See the tablegen doc string for details.

This is in order to
* keep it side-by-side with `cl.kernel_metadata`.
* still emit metadata when kernel has an *empty* arg list (see the test
`kernel-arg-meatadata.cl`).
* avoid horrors of repeating the long name `cir.cl.kernel_arg_metadata`
for `numArgs` times.

Because clangir doesn't support OpenCL built-in types and the `half`
floating point type yet, their changes and test cases are not included.
Corresponding missing feature flag is added.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants