O0 и отладка

Правила сохранения вычислений, константных выражений, места для хранения и информации об ответах на отладку.

Wave Foundation

модель сохранения

O0 сохраняет вычисления, переменные и поток управления исходного typed IR для целей отладки. Он также сохраняет неиспользуемые результаты и структурно недоступные блоки. Проверка диагностирует неисправность IR и не удаляет блоки и не упрощает операции.

Преобразования, необходимые для генерации машинного языка, выполняются в отдельном подразделе IR. Даже после конвертации соответствие оригиналу ID должно сохраняться. typed IR сохранение не подразумевает однозначное соответствие всех IR операций и машинных инструкций.

Преобразование не выполнено O0

преобразование O0 Эксплуатация
встраивание Поддерживать границы вызовов и функций
Преобразовать Tail-call Поддерживать общую структуру звонков/возвратов
удалить мертвый код Поддерживать неиспользуемые вычисления и недоступные блоки.
Свернуть константы времени выполнения сохранить исходную операцию
Объедините общие расчеты Ведите отдельные расчеты
Повторное использование локального пространства хранения переменных Поддерживайте каждое место хранения
Опустить указатель кадра поддерживать указатель кадра
Автоматическое объединение строк Поддерживать отдельные строковые объекты

Например, операция времени выполнения, которая добавляет две константы, остается сложением, даже если результат не используется. Ветви с постоянными условиями также сохраняют исходную структуру потока управления.

константы времени компиляции

Объявления констант времени компиляции сохраняют как выражение инициализации typed, так и результат вычисления. Это отличается от постоянного свертывания в обычных инструкциях времени выполнения.

В объявлении с выражением инициализации 1 + 2 остается выражение сложения и результат 3. Этот пример иллюстрирует значение выражения, а не декларативную грамматику конкретного исходного языка. Результат можно использовать при построении статических данных и он не заменяет выражение инициализации дополнением во время выполнения.

Также необходимо идентифицировать неиспользуемые и недоступные объявления. Даже если объявления с одинаковыми именами скрывают друг друга, они должны быть разделены ссылкой на объявление имени ID·. При проверке отклоняются сохраненные результаты, которые имеют недопустимые ссылки, циклы зависимостей, недопустимые типы или не соответствуют исходному выражению.

заявление о недостижимом источнике

Предложения после return·break·continue также остаются в несвязном блоке. Из-за этого утверждения не следует изменять предыдущий terminator или создавать новый путь выполнения. Он также диагностирует недопустимые выражения в недоступных предложениях.

Это правило сохранения позволяет исследовать исходную структуру программы. Это не означает, что оператор после terminator действительно будет выполнен.

Сохранился пример IR.

Ниже приведены текущие выходные данные принтера для модуля, прошедшего проверку. Показывает вместе неиспользуемые вычисления, объявления времени компиляции и несвязанные блоки.

module {
  format_version 2
  semantics_version 1
  target "x86_64-whale-linux"
  datalayout { ptr=64, endian=little }

  declare @f0 "preserved": whale () -> void, linkage internal

  fn @preserved() -> void, id @f0 {
  entry:
    %v0: i32 = const i32 1
    %v1: i32 = const i32 2
    %v2: i32 = add i32 %v0, %v1
    %v3: i32 = const_decl "count" add(i32 1, i32 2) => const i32 3
    ret void
  unreachable.cont:
    %v4: i32 = const i32 4
    %v5: i32 = const i32 5
    %v6: i32 = add i32 %v4, %v5
    ret void
  }

}

%v2 остаётся как add, даже если он бесполезен. %v3 — это отдельный const_decl, который сохраняет выражение add(i32 1, i32 2) и результат оценки 3 вместе. Поскольку unreachable.cont не имеет входящего ребра, мы можем проверить добавление %v6 без добавления пути выполнения после ret void.

Проверка сохраняет эти инструкции и блоки. В этом примере показана конфигурация/проверка/вывод IR и не подразумевается, что обеспечивается выполнение native или вывод DWARF.

Информация об источнике и стеке

Интерфейс отладки использует информацию о функции, исходные строки, локальные переменные по умолчанию и информацию о кадре вызова из DWARF 5. Даже при преобразовании в подвыражение должно сохраняться соответствие между информацией о функции/локальной переменной и исходным идентификатором IR.

Профиль AMD64 сохраняет указатель кадра и не использует red zone. Информация о кадре вызова используется для проверки стека и не подразумевает поддержку исключения unwinding. trap завершает выполнение без гарантии деструктора или unwinding.

Пожалуйста, обратитесь к Обзор инструментальной цепочки для получения информации о наличии вывода DWARF и исполнении native. Поведение оптимизаций O1 и выше выходит за рамки данного справочника O0.