Skip to content

Add support for self referential metadata#895

Open
aseyboldt wants to merge 3 commits intonumba:mainfrom
aseyboldt:main
Open

Add support for self referential metadata#895
aseyboldt wants to merge 3 commits intonumba:mainfrom
aseyboldt:main

Conversation

@aseyboldt
Copy link

@aseyboldt aseyboldt commented Dec 6, 2022

Metadata definitions that refer to themselves like !0 = { !0 } are allowed by llvm, and used to make some metadata entries globally unique (see for instance https://llvm.org/docs/LangRef.html#noalias-and-alias-scope-metadata). It seems this isn't supported by llvmlite currently.

In this PR I add support for this by adding a new self_ref argument to Model.add_metadata, that will always return a new metadata entry, but prepending self as the first operand. So this only supports references to self as the first entry, I haven't seen any usage in llvm at other locations however.

Update I probably should also mention that I'm still pretty new to llvm, and this proposed API might not actually be the best as a result...

@esc
Copy link
Member

esc commented Dec 7, 2022

@aseyboldt thank you for submitting this PR. I have labelled it as Ready for Review for now. It will hopefully be assigned a reviewer and milestone during the next issue triage meeting on Tuesdays.

@twiecki
Copy link

twiecki commented Dec 21, 2022

@esc Just checking in if a reviewer has been assigned?

@sklam sklam self-assigned this Jan 10, 2023
Copy link
Member

@sklam sklam left a comment

Choose a reason for hiding this comment

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

The situation with self-referential metadata is a bit unclear in LLVM. There are discussion about removing them https://lists.llvm.org/pipermail/llvm-dev/2021-February/148674.html. I'm not sure if the distinct keyword has make this self-referential trick outdated. For now, LLVM still contains code to create self-referential MD. It is done so by first building a metadata node without self-reference then replace the first operand with the self-reference; e.g. https://github.com/llvm/llvm-project/blob/080a07199e8c146a58ef3506cfcbf554eced21fc/llvm/lib/Analysis/LoopInfo.cpp#L1159-L1161.

The patch here adds a self_ref keyword argument to prepend a self-reference to the operands. I think this logic is okay given any self-referential MD node seems to always be just a bag of stuff. I don't think we should overengineer it too much.

Given the code changes here are small, I am ok to accept this patch once the following suggestions are addressed.

Comment on lines +52 to +54
A self referential metadata entry has itself as the first
operand to ensure uniquencess. These references are never
cached.
Copy link
Member

Choose a reason for hiding this comment

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

Can you add few words to relate this to the self_ref argument? e.g. the self_ref creates a self referential metadata by prepending itself to the operands?.

Copy link
Author

Choose a reason for hiding this comment

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

I extended the description.

e.g. an instruction.

A self referential metadata entry has itself as the first
operand to ensure uniquencess. These references are never
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
operand to ensure uniquencess. These references are never
operand to ensure uniqueness. These references are never

Copy link
Author

Choose a reason for hiding this comment

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

fixed

Comment on lines +326 to +335
def test_self_relf_metadata(self):
mod = self.module()
value = mod.add_metadata((), self_ref=True)
self.assert_ir_line('!0 = !{ !0 }', mod)
value2 = mod.add_metadata((value,))
assert value is not value2
self.assert_ir_line('!1 = !{ !0 }', mod)
value3 = mod.add_metadata((), self_ref=True)
self.assert_ir_line('!2 = !{ !2 }', mod)
assert value is not value3
Copy link
Member

Choose a reason for hiding this comment

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

Can you add test for metadata that has other operands?

Copy link
Author

Choose a reason for hiding this comment

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

done

@aseyboldt
Copy link
Author

@sklam Thanks, I added a test and extended the docs a little as you suggested.
I think the test failure is unrelated?

Warning, treated as error:
failed to reach any of the inventories with the following issues:
intersphinx inventory 'https://docs.python.org/3/objects.inv' not fetchable due to <class 'requests.exceptions.ConnectionError'>: ('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer'))
make: *** [Makefile:55: html] Error 2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants