Feedback Thread: DIP 1040--Copying, Moving, and Forwarding--Community Review Round 1

Walter Bright newshound2 at digitalmars.com
Mon Mar 8 10:21:37 UTC 2021


On 3/6/2021 12:28 PM, deadalnix wrote:
> First, very good proposal (in fact, I sent something very similar to Andrei, 
> Walter and Atila in 2019, and I hope this had some influence over this 
> proposal). For completeness, I will paste this email at the end of this reply.
> 
> It cover some subtle but important point, notably:
>   - The argument is invalid after this move, and is not destructed.
>   - Moving an EMO means that the responsibility for destruction of that value 
> moves along with it.
> 
> This is something I stressed out at the time, because it has profound 
> consequences at the ABI level. It is unfortunate that this design goal - while 
> achieved - has dropped from the rationale. To stress out how important it is, 
> let me contrast with C++.
> 
> In C++, the caller remains in charge of the destruction of an object. This means 
> that structs that are not trivially destructible, movable or copyable need to be 
> passed by reference. This introduce many indirections in the generated code, 
> but, worse, adds a ton of pressure on the alias analysis, which will prevent the 
> optimizer to do its job properly.

> The second downside is that structs always need to have a "null" state. They 
> need to remain destructible, even after the callee move the object. This forces 
> the callee to do extra work in order to set the moved object into a null state 
> and extra work from the caller to check for the null state during destruction. A 
> concrete example of this is for instance that a lock which locks a mutex in its 
> constructor and unlocks it in its destructor now must check for the mutex being 
> nulled in its destruction, introducing an unecessary branch in all path that 
> unlock the mutex.
> 
> These are serious downside in the C++ way, and this proposal should make it 
> explicit in its rationale that both problems must be avoided:
>   - Ability to pass non POD as value even at the ABI level.
>   - Ability to have movable structs without a "null" state.

Ok, good idea, although to be clear this is implicit in the Description.

> Another aspect of the proposal that needs improvement is the "Last Use" section. 
> the description of this last use is incomplete - and maybe doesn't adopt the 
> right approach, because listing all scenarii is always going to be a challenge. 
> One such scenario is the case of divergent branches:
> 
> S s;
> if (...) {
>      // Even though it is
>      fun(s);
> } else {
>      // ...
> }
> 
> The way to cover all base is to go for a fixed point analysis. A fixed point 
> analysis approach would go ass follow: define a state for all local variable, 
> then follow the control flow updating the state of said variable. When a merge 
> happen in the control flow, verify that both both path through which you arrive 
> at the merge point have a different state, then apply a fix and reprocess 
> affected branches of the control flow, up to the point all merge point are 
> consistent - you reached a fixed point.

That's exactly how the @live analysis is currently implemented. I didn't know it 
was called a fixed point analysis.

The downside of this is the data flow analysis in @live is a bit expensive. 
Perhaps the DIP should allow for the DFA being optional, and assume worst case 
(i.e. never last use) for an initial implementation.


> Adopting such an approach will ensure the behavior is not only defined for 
> current control flow constructs, but also whatever might come up in the future. 
> In the pasted email, I go over in more detail about what a fixed point analysis 
> could look like for this. While it is likely not formal enough to make it into 
> the DIP as this, it makes for a good starting point, IMO.

The idea with DFA is to not think in terms of if, while, foreach, etc. But to 
think instead of flow as nodes connected by edges. In other words, replace all 
the structured code with goto's. Anything that can be lowered to gotos will then 
work naturally.

Andrei and I have discussed "last use" optimizations for over a decade :-) but I 
always balked because it needed DFA.

Thanks for reposting the email. It's full of good information.


More information about the Digitalmars-d mailing list