<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none;"><!-- P {margin-top:0;margin-bottom:0;} --></style>
</head>
<body dir="ltr">
<div id="divtagdefaultwrapper" style="font-size:12pt;color:#000000;font-family:Calibri,Helvetica,sans-serif;" dir="ltr">
<p style="margin-top:0;margin-bottom:0"></p>
<div>== Introduction ==<br>
<br>
During the work that Anastasia has been doing on enabling OpenCL C++, <br>
points have been raised about the state of address space support in <br>
Clang. Currently, this support is rather ad-hoc. The representation of <br>
address spaces in qualifiers and the lowering of Clang address spaces <br>
to their LLVM counterparts are sound, but the behavioral semantics of <br>
address spaces given by the Embedded C TR are not really sufficient to <br>
model address space behaviors for arbitrary target architectures.<br>
<br>
Here are some of the reviews in which this has come up:<br>
 * https://reviews.llvm.org/D58346<br>
 * https://reviews.llvm.org/D57464<br>
<br>
Many address space semantics are locked behind the OpenCL language <br>
option, even though those semantics would likely be applicable to <br>
non-OpenCL cases as well. This means that, when not using any <br>
particular address space-using language dialect, the address space <br>
semantics are far too loosely defined. When using address spaces <br>
outside of the ones defined in LangAS (the 'target' address spaces), <br>
you can convert between any two address spaces explicitly, even though <br>
this might not make sense on a particular target. There is no way for a <br>
target to define which address spaces are compatible with each other.<br>
<br>
Technically, this behavior is in accordance with the Embedded-C TR <br>
(explicitly converting between all address spaces is allowed, but <br>
undefined if they aren't compatible), but I do not believe this <br>
behavior is meaningful. If a target's address spaces are disjoint, <br>
there is no reason to let a user convert between them, even with a <br>
cast.<br>
<br>
In order to make the support for address spaces more complete, general <br>
and also useful for targets with a need to define more specific rules <br>
for their address spaces, a generalization of the conversion semantics <br>
for address spaces is needed.<br>
<br>
== Current implementation ==<br>
<br>
Currently, address space compatibility is defined in terms of <br>
superspaces. An address space can encompass others, in which case it <br>
would be considered a superset/superspace of the other address spaces.<br>
<br>
Given two address spaces, Super and Sub, where Super is a superspace of <br>
Sub, then it is valid to implicitly convert a `Sub T*` to a `Super T*`, <br>
as all pointers to Sub are encompassed by pointers to Super. It is not <br>
necessarily safe to implicitly convert in the other direction. Also, an <br>
address space is a superspace of itself. <br>
<br>
This is currently implemented in Qualifiers::isAddressSpaceSupersetOf. <br>
The OpenCL __generic address space is the superspace of all other <br>
address spaces except for the OpenCL __constant address space. This <br>
method is used when checking pointer compatibility during assignment <br>
(and other forms of initialization).<br>
<br>
Explicitly converting (casting) between two address spaces is permitted <br>
if either of them is a superspace of the other. This is implemented in <br>
Qualifiers::isAddressSpaceOverlapping. This check is only done in <br>
OpenCL mode; when using address spaces in regular C, explicit <br>
conversion is always permitted.<br>
<br>
== Issues ==<br>
<br>
The problem with modeling the address space conversion semantics on <br>
superspaces and subspaces is that these two concepts are orthogonal. A <br>
target or language could have address spaces which 'overlap' in some <br>
way, yet disallow implicit or explicit conversion between them. It <br>
could also have address spaces which do not overlap, but for which <br>
explicit or implicit conversion is permitted. <br>
<br>
== Suggestion ==<br>
<br>
The suggestion in this RFC to improve the way targets and languages in <br>
Clang can express the semantics of address space conversions is to add <br>
a mechanism to ASTContext and TargetInfo which lets us query if a <br>
conversion from one address space to another address space is either:<br>
<br>
 * invalid<br>
 * valid implicitly<br>
 * valid explicitly<br>
<br>
A suggestion for the interface on ASTContext would be<br>
<br>
  bool isAddressSpaceConvertible(LangAS From, LangAS To, bool Explicit)<br>
<br>
The method would initially consult any language address space <br>
conversion rules (such as conversion rules in OpenCL), and if no such <br>
rules apply, proceed to fall back on a TargetInfo hook.<br>
<br>
The TargetInfo hook would have the same format as the ASTContext <br>
method, but would return the validity of the conversion for the <br>
particular compilation target. The default behavior of this hook would <br>
be that all implicit address space conversions are disallowed, and all <br>
explicit conversions are permitted.<br>
<br>
(An alternative setup here would be that the ASTContext method queries <br>
the TargetInfo directly, and have the language semantics be defined in <br>
the TargetInfo base method instead. This would let targets override <br>
language semantics. I don't know if this is necessary, or desirable.)<br>
<br>
It's important to point out that implicit validity should imply the<br>
explicit one. If a call to this ASTContext method is made as below, and<br>
returns true:<br>
  Ctx.isAddressSpaceConvertible(From, To, false)<br>
then the following should also return true:<br>
  Ctx.isAddressSpaceConvertible(From, To, true)<br>
<br>
If it did not, then `To T* p = from_ptr` would be permitted, but<br>
`To T* p = (To T*)from_ptr` would not be, which is rather<br>
counterintuitive.<br>
<br>
== Necessary work == <br>
<br>
The steps to implement this RFC should be as follows:<br>
<br>
* A patch which adds the aforementioned methods to ASTContext and <br>
TargetInfo, and defines the necessary semantics for the default and <br>
language-specific conversions in them.<br>
<br>
* A patch which replaces the currently used methods for address space <br>
compatibility mentioned earlier (isAddressSpaceSupersetOf, <br>
isAddressSpaceOverlapping) with calls to the new methods in ASTContext. <br>
<br>
There are some other users of these methods, such as <br>
Qualifiers::compatiblyIncludes, but it's not entirely clear how to <br>
update these as a Qualifiers does not have access to ASTContext.<br>
<br>
* Possibly a patch to remove the old address space compatibility <br>
methods, if it can be determined that they are no longer needed.<br>
<br>
</div>
Thank you for reading!<br>
<p></p>
</div>
</body>
</html>