Seems reasonable. I'd love to get rid of the intrinsics but... yeah.<div><br></div><div>Thanks Duncan.</div><div><br></div><div>-eric<br><br><div class="gmail_quote">On Wed Nov 12 2014 at 1:00:21 PM Duncan P. N. Exon Smith <<a href="mailto:dexonsmith@apple.com">dexonsmith@apple.com</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">If you don't care about function-local metadata and debug info<br>
intrinsics, skip ahead to the section on assembly syntax in case you<br>
have comments on that.<br>
<br>
> On 2014-Nov-09, at 17:02, Duncan P. N. Exon Smith <<a href="mailto:dexonsmith@apple.com" target="_blank">dexonsmith@apple.com</a>> wrote:<br>
><br>
> 2. No more function-local metadata.<br>
><br>
> AFAICT, function-local metadata is *only* used for indirect<br>
> references to instructions and arguments in `@llvm.dbg.value` and<br>
> `@llvm.dbg.declare` intrinsics. The first argument of the following<br>
> is an example:<br>
><br>
> call void @llvm.dbg.value(metadata !{i32 %val}, metadata !0,<br>
> metadata !1)<br>
><br>
> Note that the debug info people uniformly seem to dislike the status<br>
> quo, since it's awkward to get from a `Value` to the corresponding<br>
> intrinsic.<br>
><br>
> Upgrade path: Instead of using an intrinsic that references a<br>
> function-local value through an `MDNode`, attach metadata to the<br>
> corresponding argument or instruction, or to the terminating<br>
> instruction of the basic block. (This requires new support for<br>
> attaching metadata to function arguments, which I'll have to add for<br>
> debug info anyway.)<br>
<br>
llvm::Argument attachments are hard<br>
==============================<u></u>=====<br>
<br>
I've been looking at prototyping metadata attachments to<br>
`llvm::Argument`, which is key to replacing debug info intrinsics.<br>
<br>
It's a fairly big piece of new IR, and comes with its own subtle<br>
semantic decisions. What do you do with metadata attached to arguments<br>
when you inline a function? If the arguments are remapped to other<br>
instructions (or arguments), they may have metadata of the same kind<br>
attached. Does one win? Which one? Or are they merged? What if the<br>
arguments get remapped to constants? What about when a function is<br>
cloned?<br>
<br>
While the rest of this metadata-is-not-a-value proposal is effectively<br>
NFC, this `Argument` part could introduce problems. If I rewrite debug<br>
info intrinsics as argument attachments and then immediately split<br>
`Metadata` from `Value`, any semantic subtleties will be difficult to<br>
diagnose in the noise of the rest of the changes.<br>
<br>
While I was looking at this as a shortcut to avoid porting<br>
function-local metadata, I think it introduces more points of failure<br>
than problems it solves.<br>
<br>
Limited function-local metadata<br>
------------------------------<u></u>-<br>
<br>
Instead, I propose porting a limited form of function-local metadata,<br>
whose use is severely restricted but covers our current use cases (keep<br>
reading for details). We can defer replacing debug info intrinsics<br>
until the infrastructure has settled down and is stable.<br>
<br>
Assembly syntax<br>
===============<br>
<br>
This is a good time to talk about assembly syntax, since it will<br>
demonstrate what I'm thinking for function-local metadata.<br>
<br>
Assembly syntax is important. It's our view into the IR. If metadata<br>
is typeless (and not a `Value`), that should be reflected in the<br>
assembly syntax.<br>
<br>
Old syntax<br>
----------<br>
<br>
There are four places metadata can be used/reference in the IR.<br>
<br>
1. Operands of `MDNode`.<br>
<br>
!0 = metadata !{metadata !"string", metadata !1, i32* @global)<br>
<br>
Notice that the `@global` argument is not metadata: it's an<br>
`llvm::Constant`. In the new IR, these will be wrapped in a<br>
`ValueAsMetadata` instance.<br>
<br>
2. Operands of `NamedMDNode` (yes, they're different).<br>
<br>
!named = metadata !{metadata !0, metadata !1}<br>
<br>
These operands are always `MDNode`.<br>
<br>
3. Attachments to instructions.<br>
<br>
%inst = load i32* @global, !dbg !0<br>
<br>
Notice that we already skip the `metadata` type here.<br>
<br>
4. Arguments to intrinsics.<br>
<br>
call void @llvm.dbg(metadata !{i32 %inst}, metadata !0)<br>
<br>
The first argument is subtle -- that's a function-local `MDNode`<br>
with `%inst` as its only operand.<br>
<br>
In the new IR, the second operand will be a `MetadataAsValue`<br>
instance that contains a reference to the `MDNode` numbered `!0`.<br>
<br>
New syntax<br>
----------<br>
<br>
Types only make sense when an operand can be an `llvm::Value`. Let's<br>
remove them where they don't make sense.<br>
<br>
I propose the following syntax for the above examples, using a new<br>
keyword, `value`:<br>
<br>
1. Operands of `MDNode`. Drop `metadata`, since metadata doesn't have<br>
types. Use `value` to indicate a wrapped `llvm::Value`.<br>
<br>
!0 = !{!"string", !1, value i32* @global)<br>
<br>
2. Operands of `NamedMDNode`. Drop `metadata`, since metadata doesn't<br>
have types.<br>
<br>
!named = !{!0, !1}<br>
<br>
3. Attachments to instructions. No change!<br>
<br>
%inst = load i32* @global, !dbg !0<br>
<br>
4. Arguments to intrinsics. Keep `metadata`, since here it's wrapped<br>
into an `llvm::Value` (which has a type). Use `value` to indicate a<br>
metadata-wrapped value.<br>
<br>
call void @llvm.dbg(metadata value i32 %inst, metadata !0)<br>
<br>
Notice that the first argument doesn't use an `MDNode` anymore.<br>
<br>
Restrictions on function-local metadata<br>
==============================<u></u>=========<br>
<br>
In the new IR, function-local metadata (say, `LocalValueAsMetadata`)<br>
*cannot* be used as an operand to metadata -- the only legal place for<br>
it is in a `MetadataAsValue` instance. This prevents the additional<br>
complexity from poisoning the rest of the metadata hierarchy.<br>
<br>
Effectively, this restricts function-local metadata to direct operands<br>
of intrinsics.<br>
<br>
</blockquote></div></div>