CXX95 Telegram 89
#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



tgoop.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


Share with your friend now:
tgoop.com/cxx95/89

View MORE
Open in Telegram


Telegram News

Date: |

The optimal dimension of the avatar on Telegram is 512px by 512px, and it’s recommended to use PNG format to deliver an unpixelated avatar. Public channels are public to the internet, regardless of whether or not they are subscribed. A public channel is displayed in search results and has a short address (link). Telegram message that reads: "Bear Market Screaming Therapy Group. You are only allowed to send screaming voice notes. Everything else = BAN. Text pics, videos, stickers, gif = BAN. Anything other than screaming = BAN. You think you are smart = BAN. For crypto enthusiasts, there was the “gm” app, a self-described “meme app” which only allowed users to greet each other with “gm,” or “good morning,” a common acronym thrown around on Crypto Twitter and Discord. But the gm app was shut down back in September after a hacker reportedly gained access to user data. The main design elements of your Telegram channel include a name, bio (brief description), and avatar. Your bio should be:
from us


Telegram C++95
FROM American