SlideShare a Scribd company logo

Исключения C++ через призму компиляторных оптимизаций. Роман Русяев ➠ CoreHard Autumn 2019

На дворе 21-й век, непроизводительная реализация обработки C++ исключений на основе setjmp/longjmp уже в прошлом. Современные компиляторы, такие как gcc и clang, используют продвинутую реализацию C++ исключений, называемую zero-cost exception handling. Но насколько действительно это zero-cost? Да, мы платим увеличением размера бинарного файла, а также в случае, когда исключение действительно выбрасывается, запуская процесс stack unwinding, вызывая деструкторы для локальных объектов и т.д. Но теряем ли мы производительность, если исключение не выбрасывается? Появляются ли какие-то ограничения на компиляторные оптимизации? В этом докладе дано описание того, каким образом С++ исключения оказывают влияние на компиляторные оптимизации. Какие оптимизации не могут быть применены в случае, если функция может бросить исключения, а какие оптимизации становится труднее применять. Примеры реализации исключений и компиляторных оптимизаций рассматриваются на базе LLVM. Доклад преследует цель дать людям понимание, когда делать сборку своего приложения с -fno-exceptions имеет смысл, а когда можно наслаждаться всеми прелестями использования C++ исключений, зная, что их код не значительно потерял в производительности по сравнению с кодом, где исключения отключены.

1 of 96
Download to read offline
Исключения C++ через призму
компиляторных оптимизаций
LLVM
Роман Русяев
Samsung R&D
сompilers developer
rusyaev.rm@gmail.com
План доклада
• Введение в реализацию исключений
• Как исключения поддержаны в LLVM
• Влияние исключений на оптимизации компилятора (на
примере LLVM)
2
Цель доклада
Как оптимизирующий компилятор работает с исключениями C++, и
как это может отразиться на производительности ваших
приложений:
• насколько дороги исключения, даже если они не выбрасываются?
3
Цель доклада
Как оптимизирующий компилятор работает с исключениями C++, и
как это может отразиться на производительности ваших
приложений:
• насколько дороги исключения, даже если они не выбрасываются?
• когда лучше исключения не использовать
4
Цель доклада
Как оптимизирующий компилятор работает с исключениями C++, и
как это может отразиться на производительности ваших
приложений:
• насколько дороги исключения, даже если они не выбрасываются?
• когда лучше исключения не использовать
• noexcept везде, где можно
5
noexcept везде, где можно
• const везде, где можно
6
Ad

Recommended

Павел Довгалюк, Обратная отладка
Павел Довгалюк, Обратная отладкаПавел Довгалюк, Обратная отладка
Павел Довгалюк, Обратная отладкаSergey Platonov
 
DI в C++ тонкости и нюансы
DI в C++ тонкости и нюансыDI в C++ тонкости и нюансы
DI в C++ тонкости и нюансыPlatonov Sergey
 
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVMДмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVMSergey Platonov
 
Как мы уменьшили количество ошибок в Unreal Engine с помощью статического ана...
Как мы уменьшили количество ошибок в Unreal Engine с помощью статического ана...Как мы уменьшили количество ошибок в Unreal Engine с помощью статического ана...
Как мы уменьшили количество ошибок в Unreal Engine с помощью статического ана...Platonov Sergey
 
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...Sergey Platonov
 
Юнит-тестирование и Google Mock. Влад Лосев, Google
Юнит-тестирование и Google Mock. Влад Лосев, GoogleЮнит-тестирование и Google Mock. Влад Лосев, Google
Юнит-тестирование и Google Mock. Влад Лосев, Googleyaevents
 
Михаил Давыдов - JavaScript. Базовые знания
Михаил Давыдов - JavaScript. Базовые знанияМихаил Давыдов - JavaScript. Базовые знания
Михаил Давыдов - JavaScript. Базовые знанияYandex
 

More Related Content

What's hot

Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведенияДракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведенияPlatonov Sergey
 
Акторы на C++: стоило ли оно того?
Акторы на C++: стоило ли оно того?Акторы на C++: стоило ли оно того?
Акторы на C++: стоило ли оно того?Yauheni Akhotnikau
 
Основы и применение статического анализа кода при разработке лекция 1
Основы и применение статического анализа кода при разработке лекция 1Основы и применение статического анализа кода при разработке лекция 1
Основы и применение статического анализа кода при разработке лекция 1m2rus
 
Асинхронность и сопрограммы
Асинхронность и сопрограммыАсинхронность и сопрограммы
Асинхронность и сопрограммыPlatonov Sergey
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Sergey Platonov
 
Deep Dive C# by Sergey Teplyakov
Deep Dive  C# by Sergey TeplyakovDeep Dive  C# by Sergey Teplyakov
Deep Dive C# by Sergey TeplyakovAlex Tumanoff
 
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Platonov Sergey
 
Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++Sergey Platonov
 
Аскетичная разработка браузера
Аскетичная разработка браузераАскетичная разработка браузера
Аскетичная разработка браузераPlatonov Sergey
 
Григорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияГригорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияSergey Platonov
 
Async clinic by by Sergey Teplyakov
Async clinic by by Sergey TeplyakovAsync clinic by by Sergey Teplyakov
Async clinic by by Sergey TeplyakovAlex Tumanoff
 
Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Sergey Platonov
 
Евгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияЕвгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияPlatonov Sergey
 
Михаил Давыдов — JavaScript: Базовые знания
Михаил Давыдов — JavaScript: Базовые знанияМихаил Давыдов — JavaScript: Базовые знания
Михаил Давыдов — JavaScript: Базовые знанияYandex
 
Объектно-ориентированное программирование. Лекция 5 и 6
Объектно-ориентированное программирование. Лекция 5 и 6Объектно-ориентированное программирование. Лекция 5 и 6
Объектно-ориентированное программирование. Лекция 5 и 6Dima Dzuba
 
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...Yandex
 
Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?Yauheni Akhotnikau
 
хитрости выведения типов
хитрости выведения типовхитрости выведения типов
хитрости выведения типовcorehard_by
 

What's hot (20)

TeaVM: dead code elimination and devirtualization
TeaVM: dead code elimination and devirtualizationTeaVM: dead code elimination and devirtualization
TeaVM: dead code elimination and devirtualization
 
C++ exceptions
C++ exceptionsC++ exceptions
C++ exceptions
 
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведенияДракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
 
Акторы на C++: стоило ли оно того?
Акторы на C++: стоило ли оно того?Акторы на C++: стоило ли оно того?
Акторы на C++: стоило ли оно того?
 
Основы и применение статического анализа кода при разработке лекция 1
Основы и применение статического анализа кода при разработке лекция 1Основы и применение статического анализа кода при разработке лекция 1
Основы и применение статического анализа кода при разработке лекция 1
 
Асинхронность и сопрограммы
Асинхронность и сопрограммыАсинхронность и сопрограммы
Асинхронность и сопрограммы
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
 
Deep Dive C# by Sergey Teplyakov
Deep Dive  C# by Sergey TeplyakovDeep Dive  C# by Sergey Teplyakov
Deep Dive C# by Sergey Teplyakov
 
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
 
Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++
 
Аскетичная разработка браузера
Аскетичная разработка браузераАскетичная разработка браузера
Аскетичная разработка браузера
 
Григорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияГригорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизация
 
Async clinic by by Sergey Teplyakov
Async clinic by by Sergey TeplyakovAsync clinic by by Sergey Teplyakov
Async clinic by by Sergey Teplyakov
 
Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++
 
Евгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияЕвгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализация
 
Михаил Давыдов — JavaScript: Базовые знания
Михаил Давыдов — JavaScript: Базовые знанияМихаил Давыдов — JavaScript: Базовые знания
Михаил Давыдов — JavaScript: Базовые знания
 
Объектно-ориентированное программирование. Лекция 5 и 6
Объектно-ориентированное программирование. Лекция 5 и 6Объектно-ориентированное программирование. Лекция 5 и 6
Объектно-ориентированное программирование. Лекция 5 и 6
 
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
 
Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?
 
хитрости выведения типов
хитрости выведения типовхитрости выведения типов
хитрости выведения типов
 

Similar to Исключения C++ через призму компиляторных оптимизаций. Роман Русяев ➠ CoreHard Autumn 2019

Статический анализ кода проектов, построенных на движке Unreal Engine
Статический анализ кода проектов, построенных на движке Unreal EngineСтатический анализ кода проектов, построенных на движке Unreal Engine
Статический анализ кода проектов, построенных на движке Unreal EngineAndrey Karpov
 
Static code analysis of the projects built on Unreal Engine
Static code analysis of the projects built on Unreal EngineStatic code analysis of the projects built on Unreal Engine
Static code analysis of the projects built on Unreal EngineDevGAMM Conference
 
Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Sergey Platonov
 
Поддержка Java 8 в Excelsior JET
Поддержка Java 8 в Excelsior JET Поддержка Java 8 в Excelsior JET
Поддержка Java 8 в Excelsior JET Nikita Lipsky
 
Принципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioПринципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioAndrey Karpov
 
Как мы учились чинить самолеты в воздухе / Евгений Коломеец (Virtuozzo)
Как мы учились чинить самолеты в воздухе / Евгений Коломеец (Virtuozzo)Как мы учились чинить самолеты в воздухе / Евгений Коломеец (Virtuozzo)
Как мы учились чинить самолеты в воздухе / Евгений Коломеец (Virtuozzo)Ontico
 
Tech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVMTech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVMTech Talks @NSU
 
Как приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVMКак приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVMTech Talks @NSU
 
Контейнер сервисов
Контейнер сервисовКонтейнер сервисов
Контейнер сервисовRuslan Hanov
 
200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя:опыт статического анализа исходного кода200 open source проектов спустя:опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кодаPositive Hack Days
 
200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кода200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кодаAndrey Karpov
 
Статический анализ и написание качественного кода на C/C++ для встраиваемых с...
Статический анализ и написание качественного кода на C/C++ для встраиваемых с...Статический анализ и написание качественного кода на C/C++ для встраиваемых с...
Статический анализ и написание качественного кода на C/C++ для встраиваемых с...Andrey Karpov
 
Что могут статические анализаторы, чего не могут программисты и тестировщики
Что могут статические анализаторы, чего не могут программисты и тестировщикиЧто могут статические анализаторы, чего не могут программисты и тестировщики
Что могут статические анализаторы, чего не могут программисты и тестировщикиAndrey Karpov
 
Построение компилятора на базе LLVM — Павел Сычев
 Построение компилятора на базе LLVM — Павел Сычев Построение компилятора на базе LLVM — Павел Сычев
Построение компилятора на базе LLVM — Павел СычевYandex
 
ekbpy'2012 - Михаил Коробов - Python 3
ekbpy'2012 - Михаил Коробов - Python 3ekbpy'2012 - Михаил Коробов - Python 3
ekbpy'2012 - Михаил Коробов - Python 3it-people
 
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...Alexey Paznikov
 
Java 8 Support at the JVM Level
Java 8 Support at the JVM LevelJava 8 Support at the JVM Level
Java 8 Support at the JVM LevelNikita Lipsky
 
Статические анализаторы кода как DevSecOps решение
Статические анализаторы кода как DevSecOps решениеСтатические анализаторы кода как DevSecOps решение
Статические анализаторы кода как DevSecOps решениеAndrey Karpov
 
Сверхоптимизация кода на Python
Сверхоптимизация кода на PythonСверхоптимизация кода на Python
Сверхоптимизация кода на Pythonru_Parallels
 

Similar to Исключения C++ через призму компиляторных оптимизаций. Роман Русяев ➠ CoreHard Autumn 2019 (20)

Статический анализ кода проектов, построенных на движке Unreal Engine
Статический анализ кода проектов, построенных на движке Unreal EngineСтатический анализ кода проектов, построенных на движке Unreal Engine
Статический анализ кода проектов, построенных на движке Unreal Engine
 
Static code analysis of the projects built on Unreal Engine
Static code analysis of the projects built on Unreal EngineStatic code analysis of the projects built on Unreal Engine
Static code analysis of the projects built on Unreal Engine
 
Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++
 
Поддержка Java 8 в Excelsior JET
Поддержка Java 8 в Excelsior JET Поддержка Java 8 в Excelsior JET
Поддержка Java 8 в Excelsior JET
 
Принципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioПринципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-Studio
 
Как мы учились чинить самолеты в воздухе / Евгений Коломеец (Virtuozzo)
Как мы учились чинить самолеты в воздухе / Евгений Коломеец (Virtuozzo)Как мы учились чинить самолеты в воздухе / Евгений Коломеец (Virtuozzo)
Как мы учились чинить самолеты в воздухе / Евгений Коломеец (Virtuozzo)
 
Tech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVMTech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVM
 
Как приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVMКак приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVM
 
Контейнер сервисов
Контейнер сервисовКонтейнер сервисов
Контейнер сервисов
 
200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя:опыт статического анализа исходного кода200 open source проектов спустя:опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кода
 
200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кода200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кода
 
Статический анализ и написание качественного кода на C/C++ для встраиваемых с...
Статический анализ и написание качественного кода на C/C++ для встраиваемых с...Статический анализ и написание качественного кода на C/C++ для встраиваемых с...
Статический анализ и написание качественного кода на C/C++ для встраиваемых с...
 
Что могут статические анализаторы, чего не могут программисты и тестировщики
Что могут статические анализаторы, чего не могут программисты и тестировщикиЧто могут статические анализаторы, чего не могут программисты и тестировщики
Что могут статические анализаторы, чего не могут программисты и тестировщики
 
Delegates and events in C#
Delegates and events in C#Delegates and events in C#
Delegates and events in C#
 
Построение компилятора на базе LLVM — Павел Сычев
 Построение компилятора на базе LLVM — Павел Сычев Построение компилятора на базе LLVM — Павел Сычев
Построение компилятора на базе LLVM — Павел Сычев
 
ekbpy'2012 - Михаил Коробов - Python 3
ekbpy'2012 - Михаил Коробов - Python 3ekbpy'2012 - Михаил Коробов - Python 3
ekbpy'2012 - Михаил Коробов - Python 3
 
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
 
Java 8 Support at the JVM Level
Java 8 Support at the JVM LevelJava 8 Support at the JVM Level
Java 8 Support at the JVM Level
 
Статические анализаторы кода как DevSecOps решение
Статические анализаторы кода как DevSecOps решениеСтатические анализаторы кода как DevSecOps решение
Статические анализаторы кода как DevSecOps решение
 
Сверхоптимизация кода на Python
Сверхоптимизация кода на PythonСверхоптимизация кода на Python
Сверхоптимизация кода на Python
 

More from corehard_by

C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...corehard_by
 
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...corehard_by
 
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений ОхотниковC++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотниковcorehard_by
 
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр ТитовC++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титовcorehard_by
 
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...corehard_by
 
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья ШишковC++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишковcorehard_by
 
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...corehard_by
 
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...corehard_by
 
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...corehard_by
 
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...corehard_by
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...corehard_by
 
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...corehard_by
 
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел ФилоновC++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филоновcorehard_by
 
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan ČukićC++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukićcorehard_by
 
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia KazakovaC++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakovacorehard_by
 
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон ПолухинC++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухинcorehard_by
 
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...corehard_by
 
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019corehard_by
 
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019corehard_by
 
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019corehard_by
 

More from corehard_by (20)

C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
 
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
 
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений ОхотниковC++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
 
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр ТитовC++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
 
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
 
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья ШишковC++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
 
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
 
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
 
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
 
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
 
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
 
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел ФилоновC++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
 
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan ČukićC++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
 
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia KazakovaC++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
 
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон ПолухинC++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
 
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
 
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
 
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
 
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
 

Исключения C++ через призму компиляторных оптимизаций. Роман Русяев ➠ CoreHard Autumn 2019

  • 1. Исключения C++ через призму компиляторных оптимизаций LLVM Роман Русяев Samsung R&D сompilers developer rusyaev.rm@gmail.com
  • 2. План доклада • Введение в реализацию исключений • Как исключения поддержаны в LLVM • Влияние исключений на оптимизации компилятора (на примере LLVM) 2
  • 3. Цель доклада Как оптимизирующий компилятор работает с исключениями C++, и как это может отразиться на производительности ваших приложений: • насколько дороги исключения, даже если они не выбрасываются? 3
  • 4. Цель доклада Как оптимизирующий компилятор работает с исключениями C++, и как это может отразиться на производительности ваших приложений: • насколько дороги исключения, даже если они не выбрасываются? • когда лучше исключения не использовать 4
  • 5. Цель доклада Как оптимизирующий компилятор работает с исключениями C++, и как это может отразиться на производительности ваших приложений: • насколько дороги исключения, даже если они не выбрасываются? • когда лучше исключения не использовать • noexcept везде, где можно 5
  • 6. noexcept везде, где можно • const везде, где можно 6
  • 7. noexcept везде, где можно • const везде, где можно • Практично ли это? • синтаксический мусор • с появлением семантики перемещения все стало сложнее 7
  • 8. noexcept везде, где можно • const везде, где можно • Практично ли это? • синтаксический мусор • с появлением семантики перемещения все стало сложнее • const – всегда, когда нужно (ссылки, указатели, функции члены etc) 8
  • 9. noexcept везде, где можно • const везде, где можно • Практично ли это? • синтаксический мусор • с появлением семантики перемещения все стало сложнее • const – всегда, когда нужно (ссылки, указатели, функции члены etc) • А что с noexcept? 9
  • 10. Введение в реализацию исключений 10
  • 11. Zero-Cost Exception Handling (0eh) • придуман для IA-64 (Itanium) • спецификация описана в Itanium C++ ABI: https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html 11
  • 12. Zero-Cost Exception Handling (0eh) 12 не выполняется дополнительного кода, если исключение не выбрасывается
  • 13. Терминология • спецификация исключений функции: void foo() noexcept void foo() throw() // deprecated void foo() throw(type1, type2, ...) // deprecated • cleanup • обработчик исключения • stack unwinding 13
  • 14. stack unwinding • stack unwinding: осуществляет вызов деструкторов локальных объектов каждого стекового фрейма, пока не будет найден фрейм с обработчиком исключения, соответствующим объекту брошенного исключения. 14
  • 15. stack unwinding • stack unwinding: осуществляет вызов деструкторов локальных объектов каждого стекового фрейма, пока не будет найден фрейм с обработчиком исключения, соответствующим объекту брошенного исключения. Состоит из 2х этапов: • search phase: поиск обработчика исключения • clean up phase: вызов деструкторов локальных объектов и передача на обработчик исключения 15
  • 16. stack unwinding, cleanup • stack unwinding: осуществляет вызов деструкторов локальных объектов каждого стекового фрейма, пока не будет найден фрейм с обработчиком исключения, соответствующим объекту брошенного исключения. Состоит из 2х этапов: • search phase: поиск обработчика исключения • clean up phase: вызов деструкторов локальных объектов и передача на обработчик исключения • cleanup: выполняет вызовы деструкторов локальных объектов в процессе stack unwinding 16
  • 17. stack unwinding, cleanup, обработчики исключений • stack unwinding: осуществляет вызов деструкторов локальных объектов каждого стекового фрейма, пока не будет найден фрейм с обработчиком исключения, соответствующим объекту брошенного исключения. Состоит из 2х этапов: • search phase: поиск обработчика исключения • clean up phase: вызов деструкторов локальных объектов и передача на обработчик исключения • cleanup: выполняет вызовы деструкторов локальных объектов в процессе stack unwinding • обработчик исключения: код, отвечающий за обработку выброшенного исключения 17
  • 18. std::terminate • исключение не ловится • не соблюден noexcept спецификатор функции • исключение бросается из cleanup • … (еще ~10 случаев) 18
  • 19. Что происходит при бросании исключения? 19 foo phase 1: search … user code C++ runtime code …
  • 20. Что происходит при бросании исключения? 20 foo phase 1: search phase 2: clean up … user code … std::terminate no handler/error C++ runtime code
  • 21. Что происходит при бросании исключения? 21 foo phase 1: search phase 2: clean up … handler/clean up user code … std::terminate no handler/error no handler/error C++ runtime code
  • 22. Что происходит при бросании исключения? 22 foo phase 1: search phase 2: clean up … handler/clean up … user code … std::terminate no handler/error no handler/error C++ runtime code
  • 23. Что происходит при бросании исключения? 23 foo phase 1: search phase 2: clean up … handler/clean up … user code … std::terminate no handler/error no handler/error C++ runtime code
  • 24. Что происходит при бросании исключения? 24 foo phase 1: search phase 2: clean up … handler/clean up … user code … std::terminate no handler/error no handler/error std::terminate функция с noexcept вызывает не noexcept C++ runtime code
  • 26. Введение в LLVM IR • IR (Intermediate Representation) - структура данных или язык, используемые внутри компилятора для отображения исходного языка • Будем использовать урезанный вариант LLVM IR 26
  • 27. Пример инструкций на LLVM IR псевдокоде %val ; обозначение локальной переменной или метки alloca type ; выделить память для объекта типа type call func_name ; вызов функции с именем func_name ret ; инструкция возврата из функции 27
  • 28. Граф потока управления (Control Flow Graph – CFG) BB1 BB2 BB3 BB4 BB5 … … 28
  • 29. Базовый блок (Basic Block) instr1 instr2 … instrN terminator BB2 … … BB2 … 29
  • 30. Поддержка исключений в LLVM: invoke • вызов функции с неявным переходом на участок кода, если бросили исключение invoke foo() 30
  • 31. Поддержка исключений в LLVM: invoke • вызов функции с неявным переходом на участок кода, если бросили исключение invoke foo() to label %1 31
  • 32. Поддержка исключений в LLVM: invoke • вызов функции с неявным переходом на участок кода, если бросили исключение invoke foo() to label %1 unwind label %2 32
  • 33. Поддержка исключений в LLVM: invoke, landing pad • вызов функции с неявным переходом на участок кода, если бросили исключение invoke foo() to label %1 unwind label %2 • участок кода, ответственный за обработку исключения landingpad 33
  • 34. Поддержка исключений в LLVM: invoke, landing pad, resume • вызов функции с неявным переходом на участок кода, если бросили исключение invoke foo() to label %1 unwind label %2 • участок кода, ответственный за обработку исключения landingpad • инструкция, продолжающая раскрутку стека resume 34
  • 35. Влияние исключений на компиляторные оптимизации 35
  • 36. Накладные расходы (с точки зрения оптимизатора) • увеличение размера кода функции за счет создания дополнительного кода для cleanup • усложнение потока управления, появляющегося в результате наличия инструкции invoke 36
  • 38. PruneEH • преобразует инструкции invoke в call • ставит признак nounwind для функций, которые не бросают исключения 38
  • 39. PruneEH void extF() noexcept; struct S { ~S() { extF(); } }; void bar() { extF(); } void foo() { S s; bar(); } 39 void bar() { call extF() ret }
  • 40. PruneEH void extF() noexcept; struct S { ~S() { extF(); } }; void bar() { extF(); } void foo() { S s; bar(); } 40 void bar() { call extF() ret } void foo() { %1 = alloca S invoke bar() to label %4 unwind label %5 … }
  • 41. PruneEH void extF() noexcept; struct S { ~S() { extF(); } }; void bar() { extF(); } void foo() { S s; bar(); } 41 void bar() { call extF() ret } void foo() { %1 = alloca S invoke bar() to label %4 unwind label %5 ; <label>:4: call ~S(%1) ret ; <label>:5: landingpad ; cleanup call ~S(%1) resume }
  • 42. PruneEH void foo() { %1 = alloca S call bar() call ~S(%1) ret } 42 void foo() { %1 = alloca S invoke bar() to label %4 unwind label %5 ; <label>:4: call ~S(%1) ret ; <label>:5: landingpad ; cleanup call ~S(%1) resume }
  • 43. Остальные оптимизации •Simplify the CFG •Global Variable Optimizer •Instruction combining 43
  • 44. Накладные расходы А где побороть не удается? 44
  • 45. Inline void foo() { // foo actions bar(); } void bar() { // bar actions } void foo() { // foo actions // bar actions } 45
  • 46. Inline: эвристики • llvm/Analysis/InlineCost.h • llvm/lib/Analysis/InlineCost.cpp CallAnalyzer::analyzeBlock(…) { … addCost(…); // for each instruction add cost … } 46
  • 47. Inline: эвристики void extF(); struct MyStruct { ~MyStruct() { extF(); } }; void bar() { extF(); } void bar() { call extF() ret } 47
  • 48. Inline: эвристики void extF(); struct MyStruct { ~MyStruct() { extF(); } }; void bar() { extF(); } void foo() { MyStruct obj; bar(); } void bar() { call extF() ret } void foo() { %0 = alloca MyStruct invoke bar() to label %4 unwind label %5 … } 48
  • 49. Inline: эвристики void extF(); struct MyStruct { ~MyStruct() { extF(); } }; void bar() { extF(); } void foo() { MyStruct obj; bar(); } void bar() { call extF() ret } void foo() { %0 = alloca MyStruct invoke bar() to label %4 unwind label %5 ; <label>:4: call ~MyStruct(%0) ret ; <label>:5: landingpad ; cleanup call ~MyStruct(%0) resume } 49
  • 50. Inline: эвристики void foo() { MyStruct obj1; … bar(); … if (…) { MyStruct obj2; bar(); … else { MyStruct obj3; bar(); … bar(); } 50
  • 51. Inline: invoke • все инструкции call без noexcept  invoke • поток управления от новых инструкций invoke  landing pad проинлайненной инструкции invoke 51 invoke f2() f1() lpad … before after
  • 52. Inline: invoke • все инструкции call без noexcept  invoke • поток управления от новых инструкций invoke  landing pad проинлайненной инструкции invoke 52 invoke f2() f1() call f3() f2() lpad … before after
  • 53. Inline: invoke • все инструкции call без noexcept  invoke • поток управления от новых инструкций invoke  landing pad проинлайненной инструкции invoke 53 invoke f2() f1() call f3() f2() lpad … invoke f3() f1() lpad … before after
  • 54. Inline: invoke • все инструкции call без noexcept  invoke • поток управления от новых инструкций invoke  landing pad проинлайненной инструкции invoke void foo() { %0 = alloca MyStruct invoke extF() to label %4 unwind label %6 ; <label>:4: call ~MyStruct(%0) ret ; <label>:6: landingpad call ~MyStruct(%0) resume } 54 void extF(); struct MyStruct { ~MyStruct() { extF(); } }; void bar() { extF(); } void foo() { MyStruct obj; bar(); }
  • 55. Inline: resume void extF(); struct MyStruct { ~MyStruct() { extF(); } }; void bar() { extF(); } void foo() { MyStruct obj; bar(); } void bar() { call extF() ret } void foo() { %0 = alloca MyStruct invoke bar() to label %4 unwind label %5 ; <label>:4: call ~MyStruct(%0) ret ; <label>:5: landingpad ; cleanup call ~MyStruct(%0) resume } 55
  • 56. Inline: resume void extF(); struct MyStruct { ~MyStruct() { extF(); } }; void bar() { MyStruct obj; extF(); } void foo() { MyStruct obj; bar(); } 56
  • 57. Inline: resume void extF(); struct MyStruct { ~MyStruct() { extF(); } }; void bar() { MyStruct obj; extF(); } void foo() { MyStruct obj; bar(); } void bar() { call extF() ret } 57 void bar() { %0 = alloca MyStruct invoke extF() to label %4 unwind label %5 ; <label>:4: call ~MyStruct(%0) ret ; <label>:5: landingpad ; cleanup call ~MyStruct(%0) resume }
  • 58. • Инструкции resume подставляемой функции  на landing pad проинлайненной инструкции invoke 58 Inline: resume invoke f2() f1() f2() lpad1 … before after invoke f3() lpad2 …
  • 59. • Инструкции resume подставляемой функции  на landing pad проинлайненной инструкции invoke 59 Inline: resume invoke f2() f1() f2() lpad1 … invoke f3() f1() lpad2 … before after invoke f3() lpad2 … lpad1
  • 60. Inline: resume void foo() { %1 = alloca MyStruct %2 = alloca MyStruct invoke extF() to label %7 unwind label %5 ; <label>:5: landingpad call ~MyStruct(%1) call ~MyStruct(%2) resume ; <label>:7: call ~MyStruct(%1) call ~MyStruct(%2) } 60 void bar() { %0 = alloca MyStruct invoke extF() to label %4 unwind label %5 ; <label>:4: call ~MyStruct(%0) ret ; <label>:5: landingpad ; cleanup call ~MyStruct(%0) resume }
  • 61. Tail Call void foo() { goto bar_label; } void bar() { bar_label: // bar actions } void foo() { bar(); } void bar() { // bar actions } 61
  • 62. Tail Call Не применима к инструкциям invoke 62
  • 63. Loop Fusion for (int i = 0; i < n; i++) a[i] = ...; for (int j = 0; j < n; j++) b[j] = ...; for (int i = 0; i < n; i++) { a[i] = ...; b[i] = ...; } 63
  • 64. Loop Fusion • Если в цикле есть call, который может бросать исключение, то цикл не рассматривается как кандидат для оптимизации 64
  • 65. LICM (Loop Invariant Code Motion) int y = foo(); int x; for (int i = 0; i < n; i++) { x = y; a[i] = x + ...; } int y = foo(); int x = y; for (int i = 0; i < n; i++) { a[i] = x + ...; } 65
  • 66. LICM (Loop Invariant Code Motion) • не работает для инструкций invoke • не работает для инструкций call, потенциально бросающих исключения 66
  • 67. ADCE (Aggressive Dead Code Elimination) int global; void f () { int i; i = 1; global = 1; global = 2; } 67 int global; void f () { global = 2; }
  • 68. ADCE (Aggressive Dead Code Elimination) bool AggressiveDeadCodeElimination::isAlwaysLive(Instruction &Inst) { if (Inst.isEHPad() || …) { // landing pad … return true; } if (Inst.isTerminator() == false) // invoke is terminator instruction return false; if (isa<BranchInst>(Inst) || isa<SwitchInst>(Inst)) // invoke is not included here return false; return true; } 68
  • 69. Sinking • Переносит инструкции в базовые блоки преемники, чтобы убрать лишнее исполнение инструкций 69 def -> val use val before
  • 70. Sinking • Переносит инструкции в базовые блоки преемники, чтобы убрать лишнее исполнение инструкций 70 def -> val use val before after def -> val use val
  • 71. Sinking 71 bool isSafeToMove(Instruction *Inst, …) { if (… || Inst->mayThrow()) return false; … }
  • 72. Merged Load/Store Motion • Объединяет инструкции записи в память по одному адресу, для уменьшения статического размера кода 72 store addr1 before store addr1
  • 73. Merged Load/Store Motion • Объединяет инструкции записи в память по одному адресу, для уменьшения статического размера кода 73 store addr1 before after store addr1 store addr1
  • 74. Merged Load/Store Motion 74 /// True when instruction is a sink barrier for a store bool MergedLoadStoreMotion::isStoreSinkBarrierInRange(const Instruction &Start, const Instruction &End) { for (const Instruction &Inst : make_range(Start.getIterator(), End.getIterator())) { if (Inst.mayThrow()) return true; } … }
  • 75. GVNHoist • Объединяет инструкции записи в память по одному адресу, для уменьшения статического размера кода и сокращения критического пути 75 load addr1 before load addr1
  • 76. GVNHoist • Объединяет инструкции записи в память по одному адресу, для уменьшения статического размера кода и сокращения критического пути 76 load addr1 before after load addr1 load addr1
  • 77. GVNHoist bool isGuaranteedToTransferExecutionToSuccessor(const Instruction *I) { … // Calls can throw, or contain an infinite loop, or kill the process. If (auto CS = ImmutableCallSite(I)) { // Call sites that throw have implicit non-local control flow. If (!CS.doesNotThrow()) return false; … } 77
  • 78. LICM Loop Versioning • Дублирование циклов с проверкой на пересечение адресов и применение LICM к копии цикла 78 runtime memcheck LOOP LOOP COPY
  • 79. LICM Loop Versioning bool LoopVersioningLICM::instructionSafeForVersioning(Instruction *I) { … // Avoid loops with possiblity of throw if (I->mayThrow()) return false; … } 79
  • 81. Выводы • zero-cost далеко не всегда нулевой, даже если исключение не бросается 81
  • 82. Выводы • zero-cost далеко не всегда нулевой, даже если исключение не бросается: • современные компиляторы имеют специальные оптимизации для обработки исключений 82
  • 83. Выводы • zero-cost далеко не всегда нулевой, даже если исключение не бросается: • современные компиляторы имеют специальные оптимизации для обработки исключений • если вы разрабатываете библиотеку, стоит подумать об отказе от исключений 83
  • 84. Выводы • zero-cost далеко не всегда нулевой, даже если исключение не бросается: • современные компиляторы имеют специальные оптимизации для обработки исключений • если вы разрабатываете библиотеку, стоит подумать об отказе от исключений • noexcept везде, где можно 84
  • 85. Выводы • zero-cost далеко не всегда нулевой, даже если исключение не бросается: • современные компиляторы имеют специальные оптимизации для обработки исключений • если вы разрабатываете библиотеку, стоит подумать об отказе от исключений • noexcept везде, где можно: • аккуратно, т.к. это часть интерфейса 85
  • 86. Q & A Роман Русяев Samsung R&D сompilers developer rusyaev.rm@gmail.com 86
  • 88. setjmp/longjmp (sjlj) • setjmp – запомнить, куда нужно прыгнуть • longjmp – эмулирует throw Очень непроизводительно: • много дополнительных структур данных • много дополнительного выполняемого кода вне зависимости от факта бросания исключения • Нарушение главного принципа C++ - “you only pay for what you use” 88
  • 89. Библиотека поддержки исключений • LLVM: • libcxxabi • libunwind • GCC: • libsupc++ • libgcc 89
  • 90. Библиотека поддержки исключений: throw • _cxa_allocate_exception • __cxa_throw: • _Unwind_RaiseException • … 90
  • 91. Библиотека поддержки исключений: catch • __cxa_begin_catch • __cxa_end_catch 91
  • 92. Что такое LLVM • инфраструктура для разработки компиляторов • компилятор и инструменты, основанные на LLVM IR http://llvm.org 92
  • 93. Введение в LLVM • LLVM IR • множество проектов, использующих инфраструктуру LLVM • компилятор на основе LLVM – clang • LLVM библиотеки (support library, command line library, …) • алгоритмы над LLVM IR (трансформации, оптимизации, …) • инструменты для работы с LLVM IR • … 93
  • 94. Введение в LLVM IR: основные концепции • Модули • Функции • Глобальные переменные • Метаданные • … 94
  • 96. Middle-end • Работает с IR • Выполняет: • анализы • трансформации • оптимизации • Проход компилятора (pass) – выполнение над IR анализа, трансформации или оптимизации 96