-
Notifications
You must be signed in to change notification settings - Fork 19
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
LLVM Opaque Pointers feature not compatible with named pointers for Qubit and Result #30
Comments
The "target extension type" concept being introduced in https://reviews.llvm.org/D135202 may be of interest to you. It addresses similar needs that have been encountered with SPIR-V. |
First thoughts on this. I wouldn't like seeing: To someone consuming the code, they can't quickly verify the difference between these two pointers were it not for the To the point about replacing |
@nikic Thank for pointing out the target extension type! If I'm understanding it correctly, a target extension type can optionally include type information, but if it doesn't, then it can't be introspected. Is that correct? If so, that does seem to match the intended behavior of |
So you're currently doing something like |
It's been 6 months since the last post on this topic. Any thoughts or recommendations? |
@bettinaheim Updating this issue with our latest thinking, please feel free to ping the working group as well for their visibility. We took some time to discuss trade offs and implementation details on this subject and came to some recommendations that I'll update here. On the working group that's been discussing opaque pointer transition (which I've been part of) we were leaning toward using Target Extension Types introduced in LLVM 16 and setting tools to LLVM 16 as a compatibility version since that is the last version that can be configured to still generate typed pointers. However, after some more thinking, @idavis and I wanted to recommend a different approach: just embrace opaque pointers. Our reasoning follows below. Using Opaque PointersUpgrading to a newer LLVM version that uses opaque pointers without replacing the current typed pointers with a different typed alternative means that LLVM IR from version 14 or before that reads: Pros
Cons
Using a Typed AlternativeAs an alternative, the QIR specification and tooling could be changed to express Qubit and/or Results using a different, non-pointer type that allows for identifying them by type. One such approach explored by the workstream on opaque pointers is using LLVM Target Extension Types (introduced in LLVM 16). This would allow programs to indicate qubits in a target-specific type with unknown size with syntax like: Pros
Cons
Proposal: Embrace Opaque PointersBased on the trade-offs, we propose embracing opaque pointers as a means for upgrade to newer LLVM versions. This does not preclude a later switch to stricter types, and the QIR Alliance workstream can continue to explore those options. It does allow a reasonable upgrade process, backward compatibility, and continued use of off-the-shelf compiler tools. The trade-off of losing access to function agnostic analysis seems reasonable in the short term as no major examples of these kinds of analysis passes have been deployed, so the breaking change should be minimal. From there, the specification updates would be fairly straightforward: instances of In addition, a paragraph or dedicated page can be added to explain the backward compatibility story. Rather than expecting users to pick a version of tools like PyQIR where both typed and opaque pointers are supported, they should simply use the tools that produce the output they require. Since LLVM 18 and 19 can still consume IR and bitcode with typed pointers and automatically convert it to opaque in memory, a user who wishes to just consume QIR should use the latest version of the tools. A user who needs to generate QIR should choose either older or newer versions of their tool based on whether they need to produce typed pointer output or opaque pointer output. This table helps explain the compatibility story:
The only scenario that is not supported is "downgrading" QIR from opaque pointer to typed pointers, which seems like a reasonable compatibility restriction. With this approach, tools like qir-runner that only consume QIR can be updated first with no dependency or breaking while tools like PyQIR can have newer versions released where parsing supports both pointer styles but QIR generation is tied to the version of LLVM (fixes and updates would need to be backported to the older PyQIR version as appropriate). As an example of what the PyQIR changes could look like, see the changes in the swernli/llvm19 working branch. A backend that consumes QIR using PyQIR could then update to the latest LLVM version for that and their other tooling while maintaining compatibility with older clients producing typed pointers. Meanwhile, a given client producing QIR would remain on typed pointers (or provide a configurable switch) until all the consumers they submit to are ready for opaque pointers and then change over to producing only opaque pointer QIR. For the ecosystem, embracing opaque pointers should unlock the ability to use newer LLVM tools with the latest features and fixes without requiring the larger set of changes and development required for a typed alternative. |
The LLVM project has had an ongoing workstream to define behavior for treating all pointers as opaque by default (see Opaque Pointers in the LLVM docs), and the feature is on by default in LLVM 15 with typed pointers being removed in the upcoming LLVM 16. This means the current mechanism used by QIR to identify qubit and result types as distinct from other values via named pointer types will no longer work. For example, the measurement call in the base profile that today looks like this:
would become this:
As noted in the opaque pointers documentation,
This means that type information for pointers is explicitly and intentionally no longer included in the LLVM IR and meant to inserted when the pointer is read from or written to via
load
andstore
instructions. This does not map well to the current design for%Qubit*
and%Result*
which expects that these values are never loaded or stored and are merely identified as distinct by their named types.As a possible design solution going forward, the
%Qubit
and%Result
types could be more formally defined as distinct, sized structs, which would allow them to retain their type information in the IR. Correspondingly, the specifications and profiles would need to updated with this definition and the signatures of all relevant APIs updated to reflect that. A similar effort would need to be undertake for other types currently defined as typed pointers such as the%String*
,%BigInt*
,%Tuple*
, and%Array*
.The text was updated successfully, but these errors were encountered: