4 ms·
But that means the caller also has some proofs to do, if a counter example is found or nothing can be proven the caller also has to do a copy, and that's with n
by temac 5y ago
But that means the caller also has some proofs to do, if a counter example is found or nothing can be proven the caller also has to do a copy, and that's with no guarantee the callee won't do another one...
So not really an optimization anymore.
- Negitivefrags 5y agoYou say "proofs" but, as I said, this is already something the compiler keeps track of. The caller is required to do a copy as the ABI is right now so if you can't do this optimisation it's only as bad as it was before. Yes, there is a case where this creates one extra copy. The case where you a) give away a mutable pointer to a variable before calling another function, and b) the called function modifies it's own argument and then c) that function then doesn't use that object as the argument for another function it calls. That's the only case where it generates an extra copy, and I'm going to go out on a limb and say that I'm almost cirtain that this will reduce sigificantly more copies that it creates.
- comex 5y agoEven if the called function (call it B) does use the object as an argument for another function it calls (call it C), B could end up having to perform another copy for that call, if B also takes a pointer to the variable at some point and lets it escape. Or a pointer to any part of the variable. And it’s not limited to mutable pointers. Sure, if the variable itself is marked const, then it’s UB to modify it. But const local variables are rare in most codebases, in my experience. If on the other hand you pass the address of a non-const variable as a function argument, even if the type of the argument is a const pointer, the function can legally cast away the const and write to the pointer. Still, I agree that this would probably eliminate more copies than it creates. But I don't think it would eliminate or create very many copies. In my experience, approximately nobody writes code that passes structs by value in the first place.
- derefr 5y agoYou know what this would mostly affect? Code that passes longs or doubles by value, when compiled for 32-bit architectures (like many modern ARM microcontrollers still are.) Something doesn’t have to be a struct to be larger than a machine register.
- derefr 5y agoAlso, FYI (sibling post because my first one is already locked): this isn't about what the programmer tells the compiler. It's about what the compiler can infer on its own, through dataflow analysis. "const", as a qualifier, isn't novel information about a variable for the compiler — compilers already know whether a variable is used mutably or not, just like they know when and where a variable has its last access and goes dead. "const" is an instruction to the compiler that if it finds, by its own independent analysis, that the variable cannot be const in that context, then the program is invalid and compilation should error out. As such, "const" only even has a meaning, if the compiler already independently knows which declared variables are or are not const "in practice." That information is what would be used to decide whether to do the copy. > B could end up having to perform another copy for that call At worst, that's no worse than what happens under the current ABI, where A passes data by value to B, which passes it by value to C. (Do also remember, as I said in another comment, that ABIs/calling conventions are only "about" functions with external linkage. Functions with "static" linkage do whatever the compiler likes; as do their callers.) I think, in the specific situation you're describing, there's also prelink-time cross-unit optimizations that can be done here to eliminate redundant copies even further — but that's getting close to just expecting C to do Rust-like ownership analysis, so I wouldn't claim that to be practical in any production compiler in the near future.