Telegram Group & Telegram Channel
#compiler

Почему constexpr в компиляторах C++ развивается не в ту сторону 🤨

1.5 года назад была написана статья "Дизайн и эволюция constexpr в C++". Там описывается эволюция возможностей constexpr (его вычисление происходит прямо в компиляторе). Потом эту статью перевели на английский PVS-Studio и даже упомянули в твиттере Standard C++ 😀

Вычисление constexpr-выражений исторически связано с алгоритмом под названием constant folding (wikipedia). Алгоритмы этого рода работают на уровне AST (Abstract Syntax Tree), и изначально были нужны для вычисления простейших выражений с целыми числами. В коде выражение 4 + 5 * 6 выглядит в AST примерно так:
+
├── 4
└── *
├── 5
└── 6
Поэтому легко написать рекурсивный алгоритм по вычислению этого добра, и потом итеративно добавлять возможности.

Вот так обычно вычисляются constexpr-выражения компилятором:
1️⃣ Компилятор сейчас строит AST из исходника на C++.
2️⃣ Встречается выражение, которое нужно вычислить "здесь и сейчас", наподобии такого:
template<int N> class Kek { /* ... */ };
// ...
using Kek34 = Kek<4+5*6>; // точное значение аргумента мне запили!
3️⃣ Компилятор вычисляет constexpr-выражение на основе текущего AST, и сразу использует результаты для продолжения построения AST.
4️⃣ Полностью готовый AST переводится в "модуль" LLVM IR (это байткод - промежуточное представление перед переводом в ассемблер).

Проблема в том, что constexpr становится вездесущим и поддерживать его все сложнее и сложнее. Например, до сих пор нет нормального constexpr std::vector<T>, хотя его должны были сделать еще 4 года назад. Также исправлять баги constexpr реально очень трудно - требуется куча времени, чтобы вникнуть в код. Это своеобразный интерпретатор С++ на AST.

Хватит это терпеть! Подумал кое-кто, и сейчас делает... всё тот же интерпретатор C++ внутри Clang на основе принципиально нового байткода: ConstantInterpreter (статья от авторов).
Эта штука намного быстрее, чем алгоритмы на AST, но не решает главной проблемы - все равное создается ненужный интерпретатор C++!

Я предложил сделать аутсорс constexpr-вычислений на реальное вычисление на процессоре: тема на форуме clang.

Когда мы собираем "модуль" LLVM IR, мы можем запросить выполнение какого-то кода в формате LLVM IR с использованием данных этого модуля (на процессоре текущего компьютера). Лучше всего это видно на примере этих штук:
1️⃣ Туториал по созданию своего языка программирования с LLVM - раздел 3.5.
2️⃣ Программа lli для выполнения LLVM IR.
3️⃣ clang-repl - вообще балдёжная программа, натуральный интерпретатор C++.

Вот так мог бы вычислять constexpr-выражения компилятор:
1️⃣ Компилятор строит AST, одновременно держится выделенный "модуль" LLVM IR.
2️⃣ Каждое constexpr-выражение вычисляется с использованием этого выделенного "модуля" на процессоре компьютера. В этот модуль пихались бы все данные, нужные этому выражению. В общем, выражение выполняется как в clang-repl
3️⃣ Полностью готовый AST переводится в новый "модуль" LLVM IR.

И можно выкинуть огромные куски кода для вычисления выражений там на AST.

Конечно, ничего из этого не вышло. Мейнтейнеры компилятора немедленно забросали меня говном за такую харамную идею. Я просто не стал разбирать по частям всё ими написанное, чтобы не вступать в бесполезный спор, настолько безапеляционные были ответы.

Основная мантра с их стороны была про проблемы с cross-compilation (когда программу собирают под другую платформу). Видимо, есть на свете такие платформы, что там 4+5*6 равняется не не 34, а чему-то еще.

Таким образом, теперь можно понять, почему constexpr в C++ медленно развивается, и возможно никогда не станет полноценным (потому что интерпретировать C++ на AST - плохая идея).
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔7👍5👎3🔥1😢1🖕1



group-telegram.com/cxx95/89
Create:
Last Update:

#compiler

Почему constexpr в компиляторах C++ развивается не в ту сторону 🤨

1.5 года назад была написана статья "Дизайн и эволюция constexpr в C++". Там описывается эволюция возможностей constexpr (его вычисление происходит прямо в компиляторе). Потом эту статью перевели на английский PVS-Studio и даже упомянули в твиттере Standard C++ 😀

Вычисление constexpr-выражений исторически связано с алгоритмом под названием constant folding (wikipedia). Алгоритмы этого рода работают на уровне AST (Abstract Syntax Tree), и изначально были нужны для вычисления простейших выражений с целыми числами. В коде выражение 4 + 5 * 6 выглядит в AST примерно так:

+
├── 4
└── *
├── 5
└── 6
Поэтому легко написать рекурсивный алгоритм по вычислению этого добра, и потом итеративно добавлять возможности.

Вот так обычно вычисляются constexpr-выражения компилятором:
1️⃣ Компилятор сейчас строит AST из исходника на C++.
2️⃣ Встречается выражение, которое нужно вычислить "здесь и сейчас", наподобии такого:
template<int N> class Kek { /* ... */ };
// ...
using Kek34 = Kek<4+5*6>; // точное значение аргумента мне запили!
3️⃣ Компилятор вычисляет constexpr-выражение на основе текущего AST, и сразу использует результаты для продолжения построения AST.
4️⃣ Полностью готовый AST переводится в "модуль" LLVM IR (это байткод - промежуточное представление перед переводом в ассемблер).

Проблема в том, что constexpr становится вездесущим и поддерживать его все сложнее и сложнее. Например, до сих пор нет нормального constexpr std::vector<T>, хотя его должны были сделать еще 4 года назад. Также исправлять баги constexpr реально очень трудно - требуется куча времени, чтобы вникнуть в код. Это своеобразный интерпретатор С++ на AST.

Хватит это терпеть! Подумал кое-кто, и сейчас делает... всё тот же интерпретатор C++ внутри Clang на основе принципиально нового байткода: ConstantInterpreter (статья от авторов).
Эта штука намного быстрее, чем алгоритмы на AST, но не решает главной проблемы - все равное создается ненужный интерпретатор C++!

Я предложил сделать аутсорс constexpr-вычислений на реальное вычисление на процессоре: тема на форуме clang.

Когда мы собираем "модуль" LLVM IR, мы можем запросить выполнение какого-то кода в формате LLVM IR с использованием данных этого модуля (на процессоре текущего компьютера). Лучше всего это видно на примере этих штук:
1️⃣ Туториал по созданию своего языка программирования с LLVM - раздел 3.5.
2️⃣ Программа lli для выполнения LLVM IR.
3️⃣ clang-repl - вообще балдёжная программа, натуральный интерпретатор C++.

Вот так мог бы вычислять constexpr-выражения компилятор:
1️⃣ Компилятор строит AST, одновременно держится выделенный "модуль" LLVM IR.
2️⃣ Каждое constexpr-выражение вычисляется с использованием этого выделенного "модуля" на процессоре компьютера. В этот модуль пихались бы все данные, нужные этому выражению. В общем, выражение выполняется как в clang-repl
3️⃣ Полностью готовый AST переводится в новый "модуль" LLVM IR.

И можно выкинуть огромные куски кода для вычисления выражений там на AST.

Конечно, ничего из этого не вышло. Мейнтейнеры компилятора немедленно забросали меня говном за такую харамную идею. Я просто не стал разбирать по частям всё ими написанное, чтобы не вступать в бесполезный спор, настолько безапеляционные были ответы.

Основная мантра с их стороны была про проблемы с cross-compilation (когда программу собирают под другую платформу). Видимо, есть на свете такие платформы, что там 4+5*6 равняется не не 34, а чему-то еще.

Таким образом, теперь можно понять, почему constexpr в C++ медленно развивается, и возможно никогда не станет полноценным (потому что интерпретировать C++ на AST - плохая идея).

BY C++95


Warning: Undefined variable $i in /var/www/group-telegram/post.php on line 260

Share with your friend now:
group-telegram.com/cxx95/89

View MORE
Open in Telegram


Telegram | DID YOU KNOW?

Date: |

The last couple days have exemplified that uncertainty. On Thursday, news emerged that talks in Turkey between the Russia and Ukraine yielded no positive result. But on Friday, Reuters reported that Russian President Vladimir Putin said there had been some “positive shifts” in talks between the two sides. "Markets were cheering this economic recovery and return to strong economic growth, but the cheers will turn to tears if the inflation outbreak pushes businesses and consumers to the brink of recession," he added. Again, in contrast to Facebook, Google and Twitter, Telegram's founder Pavel Durov runs his company in relative secrecy from Dubai. "There are a lot of things that Telegram could have been doing this whole time. And they know exactly what they are and they've chosen not to do them. That's why I don't trust them," she said. "We as Ukrainians believe that the truth is on our side, whether it's truth that you're proclaiming about the war and everything else, why would you want to hide it?," he said.
from hk


Telegram C++95
FROM American