Писання LLVM Pass Documentation: Словник і шаблони для компіляторних інженерів
Посібник з написання чіткої документації LLVM pass — словник опису pass, повідомлення про намір, перетворення проти аналізу, вимоги і шаблони документації для інженерів компіляторів.
Для чого LLVM Pass документація важко написати
Документація LLVM pass має репутацію короткої до нерозуміння, або багатослівної в неправильних місцях. Інженери, які пишуть нові оптимізації, часто документують реалізацію ретельно, а намір майже взагалі не документують. Читачів документації, які можуть намагатися зрозуміти, чи безпечно запускати прохід на їх IR, або в якому порядку його планувати, залишають для зворотного проектування інтенції з реалізації.
Добра документація з LLVM відповідає на чотири запитання, перш ніж читач дійде до реалізації:
- ** Що робить цей прохід? ** (Опис перетворення або аналізу у одному реченні)
- ** Коли слід запустити? ** (Передумовні умови і вимоги до замовлення)
- ** Що зберігається? ** (Які аналізи залишаються чинними після проходження)
- ** Чи є якісь важливі обмеження або припущення? ** (Крайові випадки і відомі проблеми)
Словник мовлення
Опис перетворень
Перетворення змінює IR. У документації щодо перетворення використовується такий словник:
| Verb | Usage |
|---|---|
| transforms | The pass changes the structure of the IR in a significant way |
| replaces | One construct is substituted for another |
| eliminates | A construct is removed (dead code elimination, redundancy elimination) |
| hoists | A computation is moved to an earlier point (earlier in the function, or out of a loop) |
| sinks | A computation is moved to a later point |
| folds | Constant expressions are evaluated at compile time |
| inlines | A call site is replaced with the callee’s body |
| canonicalises | The IR is brought into a standard normalised form |
| lowers | A high-level construct is replaced with a lower-level equivalent |
| decomposes | A complex instruction or pattern is split into simpler parts |
| merges | Multiple constructs are combined into a single one |
| vectorises | Scalar operations are transformed into vector operations |
** Приклад повідомлення про намір за допомогою цього словника: ** “Ця операція піднімає циклічно незмінні завантаження з внутрішніх петель у передзаголовок петлі, виключаючи зайвий доступ до пам’ яті у випадках, коли завантажена адреса і завантажене значення є не зміненими протягом ітерацій петлі.”
Аналітичний опис
Проходження аналізу обчислює інформацію без зміни IR. У документації щодо проходження аналізу використовується такий словник:
| Verb | Usage |
|---|---|
| computes | The pass calculates a property of the IR |
| determines | The pass resolves a question about the IR |
| collects | The pass gathers a set of facts |
| identifies | The pass finds instances of a pattern |
| annotates | The pass adds metadata to IR elements |
| approximates | The pass produces a conservative estimate of a property |
** Приклад твердження про намір: ** “Цей аналіз обчислює множини псевдонімів для всіх інструкцій з вказівниками у функції, що дає консервативне наближення відносин доступу до пам’ яті, які можуть бути запитані наступними перетвореннями.”
Запис описів паролів у стилі LLVM
Описи переходу LLVM в заголовках коду і документації слідують послідовному стилю. Вивчення існуючих проходжень LLVM є найкращим способом калібрування вашого власного написання.
Однозначне резюме
Це з’являється в регістрі проходження, виводі --help і в верхній частині документації класу. Воно має бути:
- Полное предложение
- Точний і конкретний
- Без деталей реалізації
| Weak summary | Strong summary |
|---|---|
| ”Does mem2reg stuff." | "Promotes memory references to register references, eliminating alloca/load/store patterns that are amenable to SSA construction." |
| "Optimises loops." | "Performs loop-invariant code motion, moving computations whose operands do not change across loop iterations into the loop preheader.” |
Вимоги і вимоги
Документувати попередні умови за допомогою « вимагає » і « припускає »:
-
- “Ця передача вимагає, щоб вхідний IR був у формі SSA. Запустіть mem2reg або еквівалентний прохід перед плануванням цього проходу.”*
-
- “Це проходження передбачає, що аргументи функції не мають псевдоніму жодної глобальної змінної. Якщо це припущення може бути порушене, вимикайте пропуск для вражених функцій за допомогою атрибута ‘noalias-args’.”*
Рекомендації щодо збереження
Після запуску перетворення деякі аналізи залишаються чинними, а деякі втрачають чинність. Документуйте це за допомогою « preserves » і « annullates »:
-
- “Це проходження зберігає дерево домінанта, оскільки не змінює графік потоку керування.” *
- “Це проходження анульує результати аналізу псевдонімів, оскільки може ввести нові інструкції, що створюють вказівники.”
-
- “Це проходження не змінює IR, якщо не знайдено відповідних шаблонів; у цьому випадку всі аналізи зберігаються.” *
Документування обмежень і Edge Cases
Обмеження є одним з найважливіших і найбільш підписаних розділів документації про пропуск. Спільні шаблони:
| Situation | Documentation phrase |
|---|---|
| The pass is conservative | ”This pass uses a conservative alias analysis and may fail to eliminate some provably safe patterns.” |
| The pass does not handle a case | ”This pass does not handle indirect calls. Function pointer calls are left unchanged.” |
| A known interaction with another pass | ”Running this pass after [X] may produce suboptimal results; schedule it before [X] for best effect.” |
| A performance cliff | ”The analysis has quadratic worst-case complexity in the number of pointer-producing instructions. For functions with more than 10,000 instructions, consider using the interprocedural alias analysis instead.” |
Документація Шаблони з бази коду LLVM
Вивчіть існуючі описи паролів з коду LLVM як моделі:
- ** InstCombine: ** Об’ єднує інструкції у більш ефективні форми; у описі уважно розрізняють те, що канонізується, і те, що оптимізується.
- ** LICM (Loop Invariant Code Motion): ** Документує особливі умови, за яких обчислення підлягають підняттю.
- ** GVN (глобальна нумерація значень): ** Документує зв’ язок між нумерацією значень і ліквідацією навантаження.
Кожен з цих пропусків має чітке твердження про намір, явні передумови і документовані обмеження. Целюсь на те ж саме.
Приклади LLVM Pass Documentation Sentences
- “Ця операція перетворює комутативні інструкції з суміжними цілими діапазонами регістрів на таблиці пошуку, замінюючи послідовність гілок O(n) з доступом до пам’ яті O(1).”
-
- “Для виконання цього проходу потрібні LoopAnalysis і ScalarEvolution; його не буде виконано у петлях, для яких ScalarEvolution не може обчислити кількість циклів.” *
-
- “Спрощення змінної індукції канонізує всі змінні індукції петлі, починаючи з нуля і збільшуючи на одиницю, спрощуючи наступні векторизацію і розгортання петлі.” *
- *“Цей аналіз консервативно позначає вказівник як « може бути псевдонімом », коли його зв’ язок з псевдонімом не може бути визначено статично; авторам, яким потрібні більш точні результати, слід запитати AliasAnalysis з контекстом на виклик- сайт.” *
-
- “Це проходження анульує аналіз MemorySSA для будь- якої функції, яку воно змінює; наступні проходження, які залежать від MemorySSA, повинні запитати новий аналіз після запуску цього проходження.” *
Стиль і реєстрація нотаток
Документація LLVM використовує нейтральний, безособовий технічний реєстр. Уникайте першої особи (* “Я написав цей пропуск для…” ) і розмовних асиметрій ( “загалом, що це робить…” *).
Найкраще:
- Теперішній час для опису того, що робить пропуск: “Цей пропуск виключає…”
- Умовний для краєвих випадків: * “Якщо кількість поїздок невідома, пропуск пропускає петлю.” *
- Імператив для інструкцій користувачам: “Запустити цей прохід після mem2reg.”
Документацію будуть читати інженери з різних галузей та з різним рівнем володіння англійською мовою. Проста, точна, однозначна англійська краще за все служить їм, ніж ідіома або розмовна проза.