rsmith added a comment. In D123345#3440935 <https://reviews.llvm.org/D123345#3440935>, @aaron.ballman wrote:
> Any chance you'd be interested in submitting this patch to > http://llvm-compile-time-tracker.com/ (instructions at > http://llvm-compile-time-tracker.com/about.php) so we can have an idea of how > compile times are impacted? (It's not critical, but having some more compile > time performance measurements would be helpful to validate that this actually > saves compile time as expected. Nice idea, done: - Instructions executed while compiling reduced by 0.3-0.6% <http://llvm-compile-time-tracker.com/compare.php?from=f1b0a4fc540f986372f09768c325d505b75b414d&to=c323120bcc8a8b060f7a14d96d93a4c4a5530617&stat=instructions> at `-O0` on C++ benchmarks kimwitu++ and tramp3d-v4. Changes in the noise on other benchmarks and with optimizations enabled. - Code size reduced by 0.51% <http://llvm-compile-time-tracker.com/compare.php?from=f1b0a4fc540f986372f09768c325d505b75b414d&to=c323120bcc8a8b060f7a14d96d93a4c4a5530617&stat=size-text> at `-O0` on those same benchmarks. No change on any others. - Effect on compiler memory usage <http://llvm-compile-time-tracker.com/compare.php?from=f1b0a4fc540f986372f09768c325d505b75b414d&to=c323120bcc8a8b060f7a14d96d93a4c4a5530617&stat=max-rss> appears to be below the noise floor. In D123345#3442809 <https://reviews.llvm.org/D123345#3442809>, @joerg wrote: > The patch contains at least one user visible change that would be quite > surprising: it is no longer possible to intentionally set a break point on > `std::move`. Yeah, I think it's reasonable to support `-fno-builtin-std-move` and the like -- done. The intended model here is to treat these `std::` functions just like how we treat the functions in the global namespace for which we provide built-in semantics, so I think `-fno-builtin` and `-ffreestanding` and the like should all treat these functions the same way they treat `malloc` and `strlen` and such. > Thinking more about it, what about a slightly different implementation > strategy? Provide a compiler built-in `__builtin_std_move`. If it is present, > libc++ can alias it into `namespace std` using regular C++. Much of the > name-matching and argument checking in various places disappears. The check > to skip template instantiation can be done the same way. Over-all, it should > be much less intrusive with the same performance benefits for an > built-in-aware STL. It completely side-steps the question of ignoring the > actual implementation `of std::move` in the source, because there is none. This is an interesting idea, but I don't think it would work out well. As a superficial problem, C++ aliases (eg, `using` declarations) don't let you change the name of a function. More fundamentally, I think this would end up being a lot more complicated: we'd need to implement the rules for how to deduce parameter types and transform them into return types ourselves, we'd need to somehow support `std::forward`'s explicit template argument, and in C++17 and before, it's valid to take the address of `std::move` and co, which would require us to invent a function definition for them in IR generation. This would also be a major deviation from how we treat all other standard library functions for which we have built-in knowledge. ================ Comment at: clang/lib/Sema/SemaExpr.cpp:20282 + if (Context.BuiltinInfo.isInStdNamespace(BuiltinID)) { + // Any use of these other than a direct call is ill-formed as of C++20, + // because they are not addressable functions. In earlier language ---------------- aaron.ballman wrote: > I wonder how often these get passed around as function objects... e.g., > ``` > template <typename Fn> > void func(Fn &&Call); > > int main() { > func(std::move<int>); > } > ``` > (I don't see evidence that this is a common code pattern, but C++ surprises > me often enough that I wonder if this will cause issues.) I expect people will tell us if it this fires a lot... if it does, we can consider making the C++20 error a `DefaultError` `ExtWarn`. ================ Comment at: clang/lib/Sema/SemaInit.cpp:8192-8195 + // We might get back another placeholder expression if we resolved to a + // builtin. + if (!CurInit.isInvalid()) + CurInit = S.CheckPlaceholderExpr(CurInit.get()); ---------------- aaron.ballman wrote: > Do we need to make this call every time we've called > `FixOverloadedFunctionReference()`? I guess I'm not seeing the changes that > necessitated this call (or the one below). We only need to do this in places that assume that the result doesn't have a placeholder type. Specifically, `FixOverloadedFunctionReference` can now take us from an expression whose type is the "overloaded function" builtin type to an expression whose type is the "builtin function" builtin type, after overload resolution picks a specific template specialization, which these places were not prepared for (they thought they'd always get a real function type). In this case, we first build an initialization sequence (for example, for `int &&(*p)(int&) = std::move;`, we'd build this sequence: (1) resolve `std::move` to `std::move<int>`, then (2) decay `std::move<int>` to a function pointer), and then we apply it. If step (1) leaves us with a builtin function, we end up decaying *that* to a pointer, producing `<builtin-function-type>*`, which is an invalid type. The other case is similar: we first build an implicit conversion sequence then apply it and assume it will make sense. Other places that call `FixOverloadedFunctionReference` don't assume that they can blindly perform operations on its result, so they don't need this handling. This never happened before because we never before had a builtin function that both requires overload resolution and uses a placeholder type as the type of a reference to the function. We do the latter here so that we can detect uses of the function that aren't calls, in order to trigger a real instantiation of the body in the rare cases where they're needed. ================ Comment at: clang/test/SemaCXX/builtin-std-move.cpp:12 + + template<typename T> CONSTEXPR T &&move(T &x) { + static_assert(T::moveable, "instantiated move"); // expected-error {{no member named 'moveable' in 'B'}} ---------------- aaron.ballman wrote: > Formatting looks like it's gone wonky in this file. What are you referring to? The lines longer than 80 columns, or something else? FWIW, long lines are common in our `test/` files. Substantially more than half of them go over 80 columns: ``` $ rgrep '.\{81\}' clang/test --files-with-match | wc -l 12481 $ rgrep '.\{81\}' clang/test --files-without-match | wc -l 7194 ``` Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D123345/new/ https://reviews.llvm.org/D123345 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits