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



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. "The result is on this photo: fiery 'greetings' to the invaders," the Security Service of Ukraine wrote alongside a photo showing several military vehicles among plumes of black smoke. Telegram has gained a reputation as the “secure” communications app in the post-Soviet states, but whenever you make choices about your digital security, it’s important to start by asking yourself, “What exactly am I securing? And who am I securing it from?” These questions should inform your decisions about whether you are using the right tool or platform for your digital security needs. Telegram is certainly not the most secure messaging app on the market right now. Its security model requires users to place a great deal of trust in Telegram’s ability to protect user data. For some users, this may be good enough for now. For others, it may be wiser to move to a different platform for certain kinds of high-risk communications. It is unclear who runs the account, although Russia's official Ministry of Foreign Affairs Twitter account promoted the Telegram channel on Saturday and claimed it was operated by "a group of experts & journalists." However, the perpetrators of such frauds are now adopting new methods and technologies to defraud the investors.
from us


Telegram C++95
FROM American