This is an archive of the discontinued LLVM Phabricator instance.

Add an alternative to LLVMMDNode that will only accept metadata as argument.
Needs RevisionPublic

Authored by deadalnix on Apr 27 2016, 7:19 PM.

Details

Summary

Once we get a set of function that accept metadata only as argument consitently, and deprecate the alternatives, we'll be able to introduce metadata as its own type.

Diff Detail

Event Timeline

deadalnix updated this revision to Diff 55369.Apr 27 2016, 7:19 PM
deadalnix retitled this revision from to Add an alternative to LLVMMDNode that will only accept metadata as argument..
deadalnix updated this object.
deadalnix added a subscriber: llvm-commits.
jyknight edited edge metadata.Apr 27 2016, 7:38 PM

I don't understand this change (maybe the description just needs more context?).

Is the intention to later introduce an LLVMMetadataRef type, and these new functions will use that instead of LLVMValueRef, then? If so, why isn't introducing them with LLVMValueRef now problematic?

@jyknight Historically, Metadata were some kind of Value. But now, Metadata has its own hierarchy. In order to expose this in the C API, we need a transition plan.

The main problem here is that LLVMMDNode accept both metadata and values. Because of this, it is impossible to split the 2 right now. In order to get out of there, I want to go through a deprecation cycle for LLVMMDNode in favor of an alternative that will only accept metadata.

Right now, these metadata are wrapped as value, but passing down anything else than a metadata result in an error. As a result, it is possible to switch to LLVMMetadataRef the method that produce and consume metadata at once in such a way that thing still works with outdated headers.

deadalnix updated this revision to Diff 55372.Apr 27 2016, 8:00 PM
deadalnix edited edge metadata.

Restore function that were uintentianally commented out.

@jyknight Historically, Metadata were some kind of Value. But now, Metadata has its own hierarchy. In order to expose this in the C API, we need a transition plan.

The main problem here is that LLVMMDNode accept both metadata and values. Because of this, it is impossible to split the 2 right now. In order to get out of there, I want to go through a deprecation cycle for LLVMMDNode in favor of an alternative that will only accept metadata.

Right now, these metadata are wrapped as value, but passing down anything else than a metadata result in an error. As a result, it is possible to switch to LLVMMetadataRef the method that produce and consume metadata at once in such a way that thing still works with outdated headers.

Okay, so you're saying that in the future, all of the things that currently say "LLVMValueRef" but are talking about metadata will be changed to say "LLVMMetadataRef", but that it will still work transparently even with old software at that point, because LLVMValueAsMetadata/LLVMGetMDNode will also be changed to return LLVMMetadataRef at the same time.

Changing the types of the functions seems somewhat questionable, but I guess it would work -- as long as people don't fail to call, (or call extraneously/incorrectly!) the new LLVMMetadataAsValue and LLVMValueAsMetadata functions.

But, those functions are really confusing right now, because they're basically no-ops (takes a value and returns the same value!), so I'd kinda expect basically everyone to get their usage wrong in the intervening period.

How many functions would need to be added if you just added LLVMMetadataRef now, along with a new version of every function that operates on metadata disguised as a value, which would operate directly on the metadata instead?

Okay, so you're saying that in the future, all of the things that currently say "LLVMValueRef" but are talking about metadata will be changed to say "LLVMMetadataRef", but that it will still work transparently even with old software at that point, because LLVMValueAsMetadata/LLVMGetMDNode will also be changed to return LLVMMetadataRef at the same time.

Yes.

Changing the types of the functions seems somewhat questionable, but I guess it would work -- as long as people don't fail to call, (or call extraneously/incorrectly!) the new LLVMMetadataAsValue and LLVMValueAsMetadata functions.

These are opaque pointers, so that alright ABIwise. Going through the deprecation of LLVMMDNode will force people to do the right thing or get a runtime error.

But, those functions are really confusing right now, because they're basically no-ops (takes a value and returns the same value!), so I'd kinda expect basically everyone to get their usage wrong in the intervening period.

They aren't noop except LLVMMetadataAsValue, which simply checks that you pass it a metatdata. This one is not strictly necessary at this stage so maybe I can just remove it.

How many functions would need to be added if you just added LLVMMetadataRef now, along with a new version of every function that operates on metadata disguised as a value, which would operate directly on the metadata instead?

13 if I'm not mistaken (including LLVMMDNode, which needs duplication either way).

Wallbraker requested changes to this revision.Apr 28 2016, 2:33 AM
Wallbraker edited edge metadata.

I strongly feel that we should just add new function and then remove the old ones the release after.

You are changing API, we do that in LLVM by adding new functions, then removing the old ones. The fact that the type sizes line up is just a happy coincidence. Doing it your way adds more risks its not certain that you have covered all of the use cases, adding duplicated functions makes sure we get all of them because we are actually using the type system to work for us. And adding new functions also lets us get a clear view of what the new API will look like.

And its not like we are going to have 13 more functions forever, its just for a release.

This revision now requires changes to proceed.Apr 28 2016, 2:33 AM

It means we are breaking everybody's code for no good reason.

deadalnix updated this revision to Diff 55479.Apr 28 2016, 1:43 PM
deadalnix edited edge metadata.

Remove noop function LLVMMetadataAsValue.

deadalnix updated this revision to Diff 55762.May 1 2016, 3:34 PM
deadalnix edited edge metadata.

Use LLVMCreateMDNode as it is more consistent with existing names.

whitequark edited edge metadata.Oct 15 2017, 4:08 AM

Do I understand it correctly that LLVMMetadataRef is going to effectively become a subtype of LLVMValueRef? I.e. it is (and will be, indefinitely) legal to pass an LLVMMetadataRef anywhere you can pass LLVMValueRef, but not vice versa?

Further, do I understand it correctly that the final signatures should look something like:

LLVMMetadataRef LLVMMDString(const char *Str, unsigned SLen)
LLVMMetadataRef LLVMCreateMDNode(LLVMContextRef C, LLVMMetadataRef *Vals, unsigned Count)
LLVMMetadataRef LLVMValueAsMetadata(LLVMValueRef Val)

and so on?

And is it correct that LLVMMDNode function should be deprecated because everywhere else, the taken LLVMValueRef already *must* refer to metadata, but that's not true for LLVMMDNode?

In that case I agree with @deadalnix that we should not deprecate these 13 functions as this is not really a breakage of ABI contract, and it is sufficient to go through a single deprecation cycle removing just the LLVMMDNode function.

This revision now requires changes to proceed.Oct 15 2017, 4:08 AM
whitequark requested changes to this revision.Oct 15 2017, 4:08 AM

I think it's fine to land this but only if we introduce LLVMMetadataRef at the same time, otherwise it becomes nearly impossible to understand for downstream.

Wallbraker resigned from this revision.Aug 9 2018, 3:20 AM