tgoop.com/cxx95/12
Last Update:
#compiler
Как в компиляторе реализуют NRVO? (продолжение)
Во время парсинга у каждого scope функций и их потомков есть три возможных состояния насчет nrvo:
(1) нет переменной-кандидата на nrvo
(2) есть 1 переменная-кандидат на nrvo (хранится ссылка на нее)
(3) кандидатов на nrvo больше 1 -> nrvo запрещен
Когда scope полностью распарсен, он уведомляет scope-родителя о своем nrvo-состоянии. Если после парсинга scope функции оказалось, что nrvo-кандидат ровно один, то оптимизация сработает. Если кандидатов несколько, то nrvo не будет работать.
В C++17 ввели конструкцию if constexpr, и с тех пор вычисление nrvo в некоторых случаях дает субоптимальный результат.
Для такого примера NRVO работает, потому что тело if-а полностью дискардится из-за false вычисленного в compile-time:
template<bool B>Для такого примера NRVO не работает, потому что тело не дискардится, true тоже вычисляется не отходя от кассы
std::string foo() {
std::string y = "y";
std::string x = "x";
if constexpr (1 + 2 == 4) {
return y;
}
return x;
}
template<bool B>А для такого примера NRVO будет работать лишь для некоторых инстанциаций:
std::string foo() {
std::string y = "y";
std::string x = "x";
if constexpr (1 + 2 == 3) {
return y;
}
return x;
}
template<bool B>Так как NRVO вычисляется через анализ scope, а не для отдельных инстанциацию, то Clang-у приходится "неизвестный заранее" результат
std::string foo() {
std::string y = "y";
std::string x = "x";
if constexpr (B) {
return y;
}
return x;
}
if constexpr
обрабатывать как если бы тело не дискардилось. В итоге для foo<true>
код генерируется оптимальный, а для foo<false>
- субоптимальный.https://godbolt.org/z/fMfcYf75W (автор кода - Антон Полухин, 2021 год)
С другой стороны, переписать вычисление NRVO с анализа scope на анализ AST - это прямо гипер сложно, и такие усилия лучше потратить на более полезные вещи. Все-таки NRVO - это не обязательная оптимизация, поэтому никто не парится насчет
if constexpr
.BY C++95
Share with your friend now:
tgoop.com/cxx95/12