<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""># Regarding what change to the standard should be proposed:</div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class="">I think what John is after is to make it undefined behavior to escape a pointer in the constructor of a trivially-copyable class.</div><div style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class="">Or, maybe it can be a bit more limited: you are allowed to escape the pointer, and e.g. use it to detect whether a copy was made — I don’t think *observing* whether a copy was made is necessarily problematic — but *dereferencing* the escaped pointer, i.e. peeking at the data it points to, should be undefined behavior. </div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class="">I.e. the key thing is to make Richard’s example undefined behavior — correct me if I’m wrong.</div><div style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class="">If we had this guarantee, we could mark any trivially-copyable-class-type’d parameters "noalias" and reap the optimization benefits in C and C++ alike.</div><div style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class="">But it would *also* be good, as I believe Hal suggests, to be able to specify attributes on parameters to e.g. guarantee a copy is made. That would provide a very useful side benefit: whenever a user manually forces a copy in this way, they can be assured that any escaped pointer usage is back to being well-defined/supported (since a trivial copy is always guaranteed to be noalias). </div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class="">In other words, whenever you want to still be allowed to escape a pointer in a constructor for class `<span style="font-stretch: normal; line-height: normal; font-family: Menlo;" class="">A</span>` and remain standard-compliant, all you would need to do is change any `<span style="font-stretch: normal; line-height: normal; font-family: Menlo;" class="">f(A a)</span>` to something like `<span style="font-stretch: normal; line-height: normal; font-family: Menlo;" class="">f([[forcecopy]] A a)</span>`. </div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class="">We could also provide an alternative <font face="Menlo" class="">[[maybealias]]</font> attribute which does not force a copy, but does force IRGen to omit the noalias marking, i.e. to be pessimistic.</div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class="">Bottom line any weird cases can still be allowed to be standard compliant, but they would have to address the weirdness of the behavior they desire by explicitly telling the compiler what it can and cannot do, as I believe Hal suggested. </div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class="">This would definitely be a good thing, by a) making weird cases more visible to the eye while b) allowing better optimization of more typical cases.</div><div style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 14px;" class="">--</div><div style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""># Regarding James’ example: </div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class="">This implicates aliasing as well, without ever dealing in escaped pointers — `<span style="font-stretch: normal; line-height: normal; font-family: Menlo;" class="">foo_</span>` is a potential alias of `<span style="font-stretch: normal; line-height: normal; font-family: Menlo;" class="">f</span>` in `<span style="font-stretch: normal; line-height: normal; font-family: Menlo;" class="">CreateFoo()</span>` whenever it is constructed via `<span style="font-stretch: normal; line-height: normal; font-family: Menlo;" class="">foo_(CreateFoo())</span>`. While I don’t think this can affect the noalias status of function parameter types, which John is mainly concerned with, it seems like it should addressed in any solution to the parameter issue since it is so similar.</div><div style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class="">I am not an expert on the particulars of noalias, NRVO, or what the standard currently has to say about this, but the issue seems to be that whenever we modify object data using the returned value of a method like `<span style="font-stretch: normal; line-height: normal; font-family: Menlo;" class="">CreateFoo()</span>`, and allow it to use NRVO to modify the object data indirectly, at its ultimate destination, rather than working on a copy first, there will be potential aliasing problems due to the visibility of <font face="Menlo" class="">this</font> and the sub-object pointers within the method.</div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class="">However I think these issues are apart from the matter of whether the assert should always hold — I think it’s valid for the `<span style="font-family: monospace;" class="">assert(foo_.x == 55);`</span> to sometimes hold and sometimes not, as it could be used to detect whether a copy was made, which could be of interest to the user.</div><div style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class="">So, it seems to me that the compiler needs to either </div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><ol class="MailOutline"><li class="">assume the variable to be “returned” (`Foo <span style="font-stretch: normal; line-height: normal; font-family: Menlo;" class="">f;</span>` in the body of `<span style="font-stretch: normal; line-height: normal; font-family: Menlo;" class="">CreateFoo()</span>`) in such a method is *not* noalias, or </li><li class="">disable NRVO, i.e. force a copy, whenever writing the “returned” value of a class method to data within that class. </li></ol></div><div style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 14px;" class="">I.e. you can do one optimization or the other, but not both.</div><div style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class="">--</div><div style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""># For any struggling to follow the discussion, here is my (limited) understanding of the problem John initially raised:</div><div style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class="">Given a call `<span style="font-stretch: normal; line-height: normal; font-family: Menlo;" class="">f(A(...))</span>` to a function `<span style="font-stretch: normal; line-height: normal; font-family: Menlo;" class="">f(A a)</span>`, in constructing argument `<span style="font-stretch: normal; line-height: normal; font-family: Menlo;" class="">a</span>` the compiler implementation will always begin by building a temporary of the argument object using the constructor call `<span style="font-stretch: normal; line-height: normal; font-family: Menlo;" class="">A(…)</span>`. </div><div style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class="">But then, the C++ standard allows some leeway: If `<span style="font-stretch: normal; line-height: normal; font-family: Menlo;" class="">A</span>` is trivially copyable, the implementation may build zero or more copies of that object before settling on the one to which <span style="font-stretch: normal; line-height: normal; font-family: Menlo;" class="">&a</span> will point. (If `<span style="font-stretch: normal; line-height: normal; font-family: Menlo;" class="">A</span>` is not trivially copyable, it cannot make any such copies, so there is no such leeway.)</div><div style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class="">So, in some implementations `<span style="font-stretch: normal; line-height: normal; font-family: Menlo;" class="">&a</span>` may point to that initial temporary; in others it may point to a copy of that temporary.</div><div style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class="">This flexibility only becomes a problem if the pointer to the initial constructed temporary is allowed to "escape" from its constructor; i.e. if the constructor reveals the object’s `<span style="font-stretch: normal; line-height: normal; font-family: Menlo;" class="">this</span>` pointer, or one if its sub-object pointers, to the outside world, such that other code can depend on that pointer.</div><div style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class="">The standard apparently currently supports using an escaped pointer to a temporary however the user wishes.</div><div style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class="">Unfortunately this support creates a barrier to optimization: should an implementation decide to make *no* copies of the temporary argument object initially constructed via `<span style="font-stretch: normal; line-height: normal; font-family: Menlo;" class="">A(...)</span>`, such that `<span style="font-stretch: normal; line-height: normal; font-family: Menlo;" class="">&a</span>` = the address of the initial temporary, i.e. `<span style="font-stretch: normal; line-height: normal; font-family: Menlo;" class="">&a</span>` = <i class="">the address which might have been escaped during construction of the temporary, in a perfectly standard-compliant way</i>, then the compiler is forced to account for the possibility that the user has obtained `<span style="font-stretch: normal; line-height: normal; font-family: Menlo;" class="">&a</span>` before the function call and might be referring into `<font face="Menlo" class="">a</font>`’s data in the body of `<span style="font-stretch: normal; line-height: normal; font-family: Menlo;" class="">f</span>` under some "alias" (e.g. `<span style="font-stretch: normal; line-height: normal; font-family: Menlo;" class="">p</span>` in Richard’s example).</div><div style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class="">To account for this possibility CodeGen must tread carefully and pessimistically, foregoing optimizations which could be used if only we could guarantee either that:</div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><ol class="MailOutline"><li class="">`<span style="font-stretch: normal; line-height: normal; font-family: Menlo;" class="">a</span>` was "noalias" or </li><li class="">any path by which an alias of `<span style="font-stretch: normal; line-height: normal; font-family: Menlo;" class="">a</span>` arose is not standard-compliant and thus okay to disregard.</li></ol></div><div style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class="">In practice, this means we want to either: </div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><ol class="MailOutline"><li class="">Force to compiler to *always* make a copy when constructing `a`, solely for the purpose of giving `<span style="font-stretch: normal; line-height: normal; font-family: Menlo;" class="">a</span>` a fresh address which nothing else could have possibly seen (though if optimization is the goal, forcing ourselves to make a needless copy seems a step in the wrong direction), or </li><li class="">Guarantee that any path which exposes the address of the temporary (or, at least, which dereferences such an address) is non-standard-compliant, i.e. declare that any "alias" of `a` is by its nature invalid, so that we can safely mark `<span style="font-stretch: normal; line-height: normal; font-family: Menlo;" class="">a</span>` as noalias. </li></ol></div><div style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class="">Option 1 is what clang and other compilers seem to currently be doing, as Richard suggests (and disapproves of), but Option 2 (which I believe is what John is after) seems the most reasonable, since I cannot think of a good reason anyone should need to use the actual data content of that initial temporary. </div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class="">But as suggested above, even if a user *does* have a good reason, and really does want to dereference an escaped pointer while remaining standard compliant, we could just require them to add something like a <font face="Menlo" class="">[[forcecopy]]</font> or <font face="Menlo" class="">[[maybealias]]</font> attribute to the parameter. </div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class="">So, hard to see how anyone would lose with this proposed change.</div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class="">- Dave</div><div class=""><br class=""></div><div><br class=""><blockquote type="cite" class=""><div class="">On Jul 31, 2020, at 7:50 PM, Hal Finkel via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" class="">cfe-dev@lists.llvm.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class="">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" class="">
<div class=""><p class=""><br class="">
</p>
<div class="moz-cite-prefix">On 7/31/20 5:59 PM, James Y Knight
wrote:<br class="">
</div>
<blockquote type="cite" cite="mid:CAA2zVHrPOXHYFK7NmGRd1o8V_=7AZVA=et4AipTOHY5dpwbENA@mail.gmail.com" class="">
<div dir="ltr" class="">This discussion reminds me of an example I ran into
a couple weeks ago, where the execution of the program is
dependent precisely upon whether the ABI calls for the object to
be passed indirectly, or in a register
<div class=""><br class="">
</div>
<div class="">In the case where NVRO is triggered, the class member foo_
is fully-constructed on the first line of CreateFoo (despite
appearing as if that's only constructing a local variable). In
the case where the struct is small enough to fit in a
register, NVRO does not apply, and in that case, foo_ isn't
constructed until after CreateFoo returns.
<div class="">
<div class=""><br class="">
</div>
<div class="">Therefore, I believe it's implementation-defined
whether the following program has undefined behavior.<br class="">
</div>
<div class=""><br class="">
</div>
<div class="">
<div class="">
<div class=""><a href="https://godbolt.org/z/YT9zsz" moz-do-not-send="true" class="">https://godbolt.org/z/YT9zsz</a><br class="">
</div>
<div class=""><br class="">
</div>
<div class=""><font face="monospace" class="">#include <assert.h><br class="">
<br class="">
struct Foo {<br class="">
int x;<br class="">
<b class=""> // assert fails if you comment out these
unused fields!<br class="">
</b> int dummy[4];<br class="">
};<br class="">
<br class="">
struct Bar {<br class="">
Bar() : foo_(CreateFoo()) {}<br class="">
<br class="">
Foo CreateFoo() {<br class="">
Foo f;<br class="">
f.x = 55;<br class="">
assert(foo_.x == 55);<br class="">
return f;<br class="">
}<br class="">
Foo foo_;<br class="">
};<br class="">
<br class="">
int main() {<br class="">
Bar b;<br class="">
}</font><br class="">
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote><p class=""><br class="">
</p><p class="">Looks that way to me too. The example in 11.10.5p2 sort of makes
this point as well (by pointing out that you can directly
initialize a global this way).</p><p class=""> -Hal</p><p class=""><br class="">
</p>
<blockquote type="cite" cite="mid:CAA2zVHrPOXHYFK7NmGRd1o8V_=7AZVA=et4AipTOHY5dpwbENA@mail.gmail.com" class=""><br class="">
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Fri, Jul 31, 2020 at 2:27
PM Hal Finkel via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" moz-do-not-send="true" class="">cfe-dev@lists.llvm.org</a>>
wrote:<br class="">
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div class=""><p class=""><br class="">
</p>
<div class="">On 7/31/20 1:24 PM, Hal Finkel wrote:<br class="">
</div>
<blockquote type="cite" class="">
<div class="">On 7/31/20 12:43 PM, John McCall wrote:<br class="">
</div>
<blockquote type="cite" class="">
<div style="font-family:sans-serif" class="">
<div style="white-space:normal" class=""><p dir="auto" class="">n 31 Jul 2020, at 7:35, Hal Finkel
wrote:</p>
</div>
<div style="white-space:normal" class="">
<blockquote style="border-left:2px solid
rgb(119,119,119);color:rgb(119,119,119);margin:0px
0px 5px;padding-left:5px" class=""><p dir="auto" class="">On 7/29/20 9:00 PM, John McCall via
cfe-dev wrote:</p>
<blockquote style="border-left:2px solid
rgb(153,153,153);color:rgb(153,153,153);margin:0px
0px 5px;padding-left:5px" class=""><p dir="auto" class="">On 29 Jul 2020, at 17:42, Richard
Smith wrote:<br class="">
<br class="">
On Wed, 29 Jul 2020 at 12:52, John McCall <a href="mailto:rjmccall@apple.com" target="_blank" moz-do-not-send="true" class=""><rjmccall@apple.com></a>
wrote:<br class="">
<br class="">
...<br class="">
<br class="">
I think concretely, the escape hatch doesn't
stop things from<br class="">
going wrong,<br class="">
because -- as you note -- even though we
*could* have made a copy,<br class="">
it's<br class="">
observable whether or not we *did* make a
copy. For example:<br class="">
<br class="">
I would say that it’s observable whether the
parameter variable has<br class="">
the same address as the argument. That doesn’t
/have/ to be the same<br class="">
question as whether a copy was performed: we
could consider there to be<br class="">
a formal copy (or series of copies) that
ultimately creates /an/ object<br class="">
at the same address, but it’s not the /same/
object and so pointers<br class="">
to the old object no longer validly pointer to
it. But I guess that<br class="">
would probably violate the lifetime rules,
because it would make accesses<br class="">
through old pointers UB when in fact they
should at worst access a valid<br class="">
object that’s just unrelated to the parameter
object.<br class="">
</p>
</blockquote><p dir="auto" class="">I think that it would be great to be
able to do this, but unfortunately, I think that
the point that you raise here is a key issue.
Whether or not the copy is performed is visible
in the model, and so we can't simply act as
though there was a copy when optimizing. Someone
could easily have code that looks like:<br class="">
<br class="">
Foo DefaultX;<br class="">
<br class="">
...<br class="">
<br class="">
void something(Foo &A, Foo &B) {<br class="">
<br class="">
if (&A == &B) { ... }<br class="">
<br class="">
}<br class="">
<br class="">
void bar(Foo X) { something(X, DefaultX); }</p>
</blockquote>
</div>
<div style="white-space:normal" class=""><p dir="auto" class="">This example isn’t really on point; a
call like <code style="background-color:rgb(247,247,247);border-radius:3px;margin:0px;padding:0px
0.4em" bgcolor="#F7F7F7" class="">bar(DefaultX)</code>
obviously cannot just pass the address of <code style="background-color:rgb(247,247,247);border-radius:3px;margin:0px;padding:0px
0.4em" bgcolor="#F7F7F7" class="">DefaultX</code> as a
by-value argument without first proving a lot of
stuff about how <code style="background-color:rgb(247,247,247);border-radius:3px;margin:0px;padding:0px
0.4em" bgcolor="#F7F7F7" class="">foo</code> uses both
its parameter and <code style="background-color:rgb(247,247,247);border-radius:3px;margin:0px;padding:0px
0.4em" bgcolor="#F7F7F7" class="">DefaultX</code>. I
think <code style="background-color:rgb(247,247,247);border-radius:3px;margin:0px;padding:0px
0.4em" bgcolor="#F7F7F7" class="">noalias</code> is
actually a subset of what would have to be proven
there.</p>
</div>
</div>
</blockquote><p class=""><br class="">
</p><p class="">Yes, I apologize. You're right: my pseudo-code missed
the point. So the record is clear, let me rephrase:</p>
Foo *DefaultX = nullptr;<br class="">
...<br class="">
Foo::Foo() { if (!DefaultX) DefaultX = this; }<br class="">
...<br class="">
void bar(Foo X) { something(X, *DefaultX); }<br class="">
...<br class="">
bar(Foo{});
<p class="">I think that's closer to what we're talking about.<br class="">
</p><p class=""><br class="">
</p>
<blockquote type="cite" class="">
<div style="font-family:sans-serif" class="">
<div style="white-space:normal" class=""><p dir="auto" class="">In general, the standard is clear that
you cannot rely on escaping a pointer to/into a
trivially-copyable pr-value argument prior to the
call and then rely on that pointer pointing into
the corresponding parameter object.
Implementations are <em class="">allowed</em> to introduce
copies. But it does seem like the current wording
would allow you to rely on that pointer pointing
into <em class="">some</em> valid object, at least until
the end of the caller’s full-expression. That
means that, if we don’t guarantee to do an actual
copy of the argument, we cannot make it UB to
access the parameter variable through pointers to
the argument temporary, which is what marking the
parameter as <code style="background-color:rgb(247,247,247);border-radius:3px;margin:0px;padding:0px
0.4em" bgcolor="#F7F7F7" class="">noalias</code> would
do.</p><p dir="auto" class="">So I guess the remaining questions
are:</p>
<ul class="">
<li class="">Is this something we can reasonably change in
the standard?</li>
</ul>
</div>
</div>
</blockquote><p class=""><br class="">
</p><p class="">This is the part that I'm unclear about. What change
would we make? <br class="">
</p><p class=""><br class="">
</p>
</blockquote><p class=""><br class="">
</p><p class="">Also, maybe some extended use of the no_unique_address
attribute would help?<br class="">
</p><p class=""> -Hal</p><p class=""><br class="">
</p>
<blockquote type="cite" class=""><div class=""> <br class="webkit-block-placeholder"></div><p class=""><br class="">
</p>
<blockquote type="cite" class="">
<div style="font-family:sans-serif" class="">
<div style="white-space:normal" class="">
<ul class="">
<li class="">Are we comfortable setting <code style="background-color:rgb(247,247,247);border-radius:3px;margin:0px;padding:0px
0.4em" bgcolor="#F7F7F7" class="">noalias</code> in C
if the only place that would break is with a C++
caller?</li>
</ul>
</div>
</div>
</blockquote><p class=""><br class="">
</p><p class="">Out of curiosity, if you take C in combination with our
statement-expression extension implementation (<a href="https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html" target="_blank" moz-do-not-send="true" class="">https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html</a>),
and notwithstanding the statement in the GCC manual
about returns by value (i.e., the part just before where
it says, "Therefore the this pointer observed by Foo is
not the address of a."), is there any relationship to
this topic?</p><p class="">Thanks again,</p><p class="">Hal<br class="">
</p><p class=""><br class="">
</p>
<blockquote type="cite" class="">
<div style="font-family:sans-serif" class="">
<div style="white-space:normal" class="">
<ul class="">
</ul><p dir="auto" class="">John.</p>
</div>
<div style="white-space:normal" class="">
<blockquote style="border-left:2px solid
rgb(119,119,119);color:rgb(119,119,119);margin:0px
0px 5px;padding-left:5px" class=""><p dir="auto" class="">As Richard's example shows, the code
doesn't need to explicitly compare the addresses
to detect the copy either. Any code that
reads/writes to the objects can do it. A
perhaps-more-realistic example might be:<br class="">
<br class="">
int Cnt = A.RefCnt; ++A.RefCnt; ++B.RefCnt; if
(Cnt + 1 != A.RefCnt) { /* same object case */ }<br class="">
<br class="">
The best suggestion that I have so far is that
we could add an attribute like 'can_copy'
indicating that the optimizer can make a formal
copy of the argument in the callee and use that
instead of the original pointer if that seems
useful. I can certainly imagine a transformation
such as LICM making use of such a thing
(although the cost modeling would probably need
to be fairly conservative).<br class="">
<br class="">
-Hal<br class="">
<br class="">
</p>
<blockquote style="border-left:2px solid
rgb(153,153,153);color:rgb(153,153,153);margin:0px
0px 5px;padding-left:5px" class=""><p dir="auto" class="">...<br class="">
<br class="">
John.<br class="">
<br class="">
<br class="">
_______________________________________________<br class="">
cfe-dev mailing list<br class="">
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank" moz-do-not-send="true" class="">cfe-dev@lists.llvm.org</a><br class="">
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" style="color:rgb(153,153,153)" target="_blank" moz-do-not-send="true" class="">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a></p>
</blockquote><p dir="auto" class="">-- <br class="">
Hal Finkel<br class="">
Lead, Compiler Technology and Programming
Languages<br class="">
Leadership Computing Facility<br class="">
Argonne National Laboratory</p>
</blockquote>
</div>
<div style="white-space:normal" class=""> </div>
</div>
</blockquote>
<pre cols="72" class="">--
Hal Finkel
Lead, Compiler Technology and Programming Languages
Leadership Computing Facility
Argonne National Laboratory</pre>
</blockquote>
<pre cols="72" class="">--
Hal Finkel
Lead, Compiler Technology and Programming Languages
Leadership Computing Facility
Argonne National Laboratory</pre>
</div>
_______________________________________________<br class="">
cfe-dev mailing list<br class="">
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank" moz-do-not-send="true" class="">cfe-dev@lists.llvm.org</a><br class="">
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank" moz-do-not-send="true" class="">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br class="">
</blockquote>
</div>
</blockquote>
<pre class="moz-signature" cols="72">--
Hal Finkel
Lead, Compiler Technology and Programming Languages
Leadership Computing Facility
Argonne National Laboratory</pre>
</div>
_______________________________________________<br class="">cfe-dev mailing list<br class=""><a href="mailto:cfe-dev@lists.llvm.org" class="">cfe-dev@lists.llvm.org</a><br class="">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev<br class=""></div></blockquote></div><br class=""></body></html>