<p>I'm designing a language that has move semantics similar to C++. To make it more efficient and to prevent the need for explicit moves I want to automatically promote copies to moves if the compiler can prove that the copied-from object is not used anymore after the copy:</p>
<pre><code>function f() {
    var a = [1, 2, 3]; // Dynamic array
    var b = a;         // Copy is promoted to a move
    // Some more code which does not use or reference a
}
</code></pre>
<p>So in this example it would not be the backend that optimizes the copy away but the frontend that generates a call to the move constructor instead of the copy constructor. This can make a big difference in performance, i.e. if the definitions of the constructors are in another translation unit.</p>
<p>I assume that C++ does not allow compilers to make this code transformation because it can change the semantics of the program in possibly unpredictable ways. Now my question is, are there any idioms or sane programs that rely on the copy constructor being called in this example? Or in other words, what am I leaving on the table when implementing this transformation?</p>
<p>As an aside, this transformation is somewhat similar to copy elision, so if C++ allows copy constructors to be elided elsewhere, why not here?</p>

<optimization><c++>
Automatic copy to move promotion
CC BY-SA 4.0
2023-07-02T13:44:10.747Z
I'm not sure what the question is here. Is it about how/when to perform the elision, why C++ doesn't, or whether code relies on the fact that it doesn't?
Bbrk24
CC BY-SA 4.0
2023-07-02T13:46:34.503Z
Swift's standard collection types are copy-on-write -- a semantic copy doesn't perform a literal copy until you mutate one or the other -- and from what I've seen that's generally the behavior people want. At the very least I've never seen any complaints about it.
Bbrk24
CC BY-SA 4.0
2023-07-02T13:52:54.540Z
@Bbrk24 The question is if there are any design patterns that would not work if the descriped transformation is performed. Or in other words if the transformation is "safe" as long as the compiler can prove that the copied from object will never be used after the copy. I assume that there may be some problems with it, because C++ does not allow the transformation. Also I don't want COW semantics in the language because it comes with other problems if you allow pointers to objects which swift does not afaik.
chrysante
<p>This was going to be comment but it was too long. So its probably not a complete answer.</p>
<p>I think the main problem is that it potentially creates aliasing and lifetime confusion.</p>
<pre><code>function f() {
    var a = [1, 2, 3]; // Dynamic array
    var b = a;         // Copy is promoted to a move
    // Some more code which does not use or reference a
}
</code></pre>
<p>We would expect <code>a</code> to be available and modifiable after <code>b=a</code>.
You say you only want to promote this to a move if <code>a</code> is not used.
But if that is the case what is the purpose of <code>b</code>?
The compiler is already free to treat <code>b</code> as just a name for the same variable and re-use it if it wants to. No move required.
<code>b</code> only has a different name for the programmers benefit to indicate a change in use.</p>
<p>Things can get more complex if you have more variables:</p>
<pre><code>    var a = [1, 2, 3]; // Dynamic array
    var c = a;         // I am copy
    var b = a;         // promoted to a move
    
</code></pre>
<p>Now the costs of the two <em>pseudo</em> assignments are different.</p>
<p>The C++ rules probably include an aim to keep things predictable.
Other languages may have different priorities.</p>
<p>Subsequent modification to the code can produce other subtle changes like this.</p>
<p>If you add copy on write semantics things could become even more confusing.</p>

CC BY-SA 4.0
2023-07-03T12:34:43.883Z
2023-07-03T12:34:43.883Z
Bruce Adams
CC BY-SA 4.0
2023-07-03T16:40:58.180Z
I agree, after thinking about it some more I also came to the conclusion that the alias analysis needs to be way too strict or would be too hard to perform to be useful, on top of making things too unpredictable for the user.
chrysante
# Automatic copy to move promotion
Posted by: username_0 on 2023-07-02
I'm designing a language that has move semantics similar to C++. To make it more efficient and to prevent the need for explicit moves I want to automatically promote copies to moves if the compiler can prove that the copied-from object is not used anymore after the copy:
function f() {
    var a = [1, 2, 3]; // Dynamic array
    var b = a;         // Copy is promoted to a move
    // Some more code which does not use or reference a
}

So in this example it would not be the backend that optimizes the copy away but the frontend that generates a call to the move constructor instead of the copy constructor. This can make a big difference in performance, i.e. if the definitions of the constructors are in another translation unit.
I assume that C++ does not allow compilers to make this code transformation because it can change the semantics of the program in possibly unpredictable ways. Now my question is, are there any idioms or sane programs that rely on the copy constructor being called in this example? Or in other words, what am I leaving on the table when implementing this transformation?
As an aside, this transformation is somewhat similar to copy elision, so if C++ allows copy constructors to be elided elsewhere, why not here?
**Tags:** optimization c++
> **Comments:**
> **username_1**: I'm not sure what the question is here. Is it about how/when to perform the elision, why C++ doesn't, or whether code relies on the fact that it doesn't?  
> **username_1**: Swift's standard collection types are copy-on-write -- a semantic copy doesn't perform a literal copy until you mutate one or the other -- and from what I've seen that's generally the behavior people want. At the very least I've never seen any complaints about it.  
> **username_0**: @Bbrk24 The question is if there are any design patterns that would not work if the descriped transformation is performed. Or in other words if the transformation is "safe" as long as the compiler can prove that the copied from object will never be used after the copy. I assume that there may be some problems with it, because C++ does not allow the transformation. Also I don't want COW semantics in the language because it comes with other problems if you allow pointers to objects which swift does not afaik.  
---
## 1 answers
### Answer by username_2 on 2023-07-03. Score: 3 | Accepted answer
This was going to be comment but it was too long. So its probably not a complete answer.
I think the main problem is that it potentially creates aliasing and lifetime confusion.
function f() {
    var a = [1, 2, 3]; // Dynamic array
    var b = a;         // Copy is promoted to a move
    // Some more code which does not use or reference a
}

We would expect a to be available and modifiable after b=a.
You say you only want to promote this to a move if a is not used.
But if that is the case what is the purpose of b?
The compiler is already free to treat b as just a name for the same variable and re-use it if it wants to. No move required.
b only has a different name for the programmers benefit to indicate a change in use.
Things can get more complex if you have more variables:
    var a = [1, 2, 3]; // Dynamic array
    var c = a;         // I am copy
    var b = a;         // promoted to a move
    

Now the costs of the two pseudo assignments are different.
The C++ rules probably include an aim to keep things predictable.
Other languages may have different priorities.
Subsequent modification to the code can produce other subtle changes like this.
If you add copy on write semantics things could become even more confusing.
> **Comments:**
> **username_0** (2023-07-03): I agree, after thinking about it some more I also came to the conclusion that the alias analysis needs to be way too strict or would be too hard to perform to be useful, on top of making things too unpredictable for the user.  
---
