[cfe-dev] [RFC] Improved address space conversion semantics for targets and language dialects

Bevin Hansson via cfe-dev cfe-dev at lists.llvm.org
Thu Apr 11 02:26:23 PDT 2019


On 2019-04-01 19:36, Anastasia Stulova wrote:

> There's nothing wrong with the type representation, it's simply that the C/C++ behavior cannot actually be captured with the superspace model. > In the current C/C++ model, the default behavior for address space conversions is that converting between any two address spaces implicitly is > always prohibited, but converting explicitly is always permitted. This cannot be expressed in the superspace model, as there is no way to make > explicit conversion between AS1 and AS2 legal without also either making AS1->AS2 or AS2->AS1 implicitly legal, as  'isAddressSpaceOverlapping' is dependent on 'isAddressSpaceSuperSpaceOf'.


I thought that this is because the address space support is incomplete. At least according to the embedded C report the casts to non-overlapping address spaces should be disallowed. It doesn't clarify however whether it applies to both implicit and explicit cast.

I believe that 'cast' in standardese means 'explicit cast'. I don't think implicit casts are ever referred to as casts, at least in the C standards. The Embedded-C report does make it clear separately that "If a pointer into address space A is assigned to a pointer into a different address space B, a constraint requires that A be a subset of B.", which enshrines the implicit conversion rule.


In order to explicitly cast from an AS A to an AS B without invoking UB, one of the ASes must be a subset of the other (overlapping). Technically, E-C doesn't prohibit explicit casts where the ASes are disjoint (which matches the current 'generic' implementation in Clang), but I'm of the opinion that this is a mistake. There is no reason to allow such casts as they *always* invoke UB.


So, I guess the current C/C++ behavior is according to spec if you think of all of the target ASes as disjoint (cannot implicitly convert, but all explicit conversion is allowed), but if we follow those rules then there is no way for a target to prevent explicit casting between disjoint address spaces, which is pretty bad.



> If it requires hardware or backend support it doesn't really feel like a logical concept any more. The overhead of the runtime checking also sounds a bit scary. I think that if a target or language supports a generic address space, then they can use that for methods if they want to save on the typing overhead. Otherwise I think they'll just have to wait until there is a way to automatically deduce address space qualified member functions at compile time.


I think that the deduction won't help here because we would like the member functions to be called on objects in different address spaces, at least for the general case. And then we end up with truly generic cases where multiple address spaces are to be used with the method on the place of generic. There are multiple ways to solve this problem including duplicating the methods but they don't seem to be ideal. I feel that the address space support for C++ without something like generic address space can't be complete. I will start a separate RFC summarizing my thoughts with a few examples perhaps to avoid diverging the focus of this RFC.

Well, if the deduction lets us expand a template method with a given address space, then it becomes general. It would cause code duplication, but I think it's the only way to get any kind of decent performance out of it. I'm not sure how having to do a target-specific address space check at runtime every time we want to access 'this' will work out.



Thanks!

Anastasia


________________________________
From: Bevin Hansson <bevin.hansson at ericsson.com><mailto:bevin.hansson at ericsson.com>
Sent: 26 March 2019 18:18
To: Anastasia Stulova; clang-dev developer list
Cc: nd
Subject: Re: [RFC] Improved address space conversion semantics for targets and language dialects



> Yes, I believe we might not have any upstream example for this and
> hence current implementation is not complete. However, the current
> approach has some sort of the guidelines on how the ambiguity can
> be resolved that we would need to figure out with the new logic.

> I guess we could use the implicit/explicit conversion for this, however
> it might become more convoluted.

Well, if we do change the interface to model conversion legality instead of superspaces, the functional behavior can be the same as today. We would just call the proper method for checking implicit AS conversion as we call isAddressSpaceSupersetOf today. However, if we decide to change the overload behavior to consider shorter AS conversion paths over longer ones, the intuition might not be as obvious as it would be with the superspace approach.

> I think there might be a little bit of that. For the developers from embedded
> C or OpenCL background this concept is quite familiar. And one advantage
> is that there is some sort of the spec that regulates the logic. I do find your
> logic quite intuitive and for C++  at least we can definitely make bigger
> changes. However, it also helps to build on top of something that already
> works. I am only worried about covering the corner cases enough.

> May be prototyping the solution you are suggesting is a good way forward.

Yes, prototyping it is probably a good idea, at least to get an idea of how it could look in practice.


> But this logic comes from C/C++, generally speaking I can't think of the case
> where implicit conversion would be allowed between the types that won't be
> explicitly convertible. I don't think there is anything OpenCL specific about this.
> I think address space conversion logic is pretty much extending qualifiers in
> C/C++. Do you think there is any use case that needs different logic? Then
> perhaps we will have more work to do because qualifiers might not be the right
> fit for the address spaces with such logic.

There's nothing wrong with the type representation, it's simply that the C/C++ behavior cannot actually be captured with the superspace model. In the current C/C++ model, the default behavior for address space conversions is that converting between any two address spaces implicitly is always prohibited, but converting explicitly is always permitted. This cannot be expressed in the superspace model, as there is no way to make explicit conversion between AS1 and AS2 legal without also either making AS1->AS2 or AS2->AS1 implicitly legal, as 'isAddressSpaceOverlapping' is dependent on 'isAddressSpaceSuperSpaceOf'. This is the reason why the conversion logic in checkAddressSpaceCast is hidden behind the OpenCL option, for example.


> Generic AS would have to be preserved in the LLVM IR too and then it can
> be lowered by the backed. The best solution would be to add some special HW
> support to allow translating address spaces efficiently. However it can be
> emulated by the compiler but then a toolchain should provide some way to
> detect in what specific AS an object in generic AS points to. This can be done
> by adding special intrinsics. However this checks are quite costly. There is some
> help for reducing the overheads of generic address space provided in LLVM already
> in form of a special pass that allows to infer the specific address space where
> applicable.

If it requires hardware or backend support it doesn't really feel like a logical concept any more. The overhead of the runtime checking also sounds a bit scary. I think that if a target or language supports a generic address space, then they can use that for methods if they want to save on the typing overhead. Otherwise I think they'll just have to wait until there is a way to automatically deduce address space qualified member functions at compile time.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20190411/6c4674f9/attachment-0001.html>


More information about the cfe-dev mailing list