Флаги контроля за встраиванием



Под этим постом было предложение выпустить пост с флагами компилятора, которые контролируют инлайнинг, если вы поактивничаете лайками. Вы хорошо постарались, поэтому мой черёд.



Оговорюсь, что буду вещать про флаги gcc, так как это самый популярный инструмент. Да и в шланге, думаю, будут те же самые флаги, чисто для совместмости и привычного использования. Погнали:



-fno-inline - запрещает какие-либо функции, за исключением тех, которые маркированы атрибутом alwaysinline. Этот режим стоит по дефолту, когда не подрублены оптимизации. И кстати, есть такой атрибут noinline, которым можно пометить отдельную функцию, и это запретит ее встраивать.



-finline-small-functions - разрешает встраивать функции в код их коллера, когда их тело меньше, чем тот код, который генерируется для вызова этих функций. Тогда размер всей программы будет меньше. У компилятора там есть свои эвристики, по которым он принимает решение, достаточно ли маленькая определенная функция. В этом случае компилятор может применить инлайнинг ко всем функциям, даже к тем, которые не помечены ключевым словом inline. Применяется на уровнях оптимизации -O2, -O3, -Os.



-finline-functions - разрешает рассматривать вообще все функции, как кандидатов на встраивание, даже если они не помечены как inline. Опять же компилятор у нас самостоятельный дядя и сам решает, когда и что встроить. Применяется на уровнях оптимизации -O2, -O3, -Os.

Если все вызовы определенной функции встроены и она помечена static, то для нее вообще не генерируется ассемблер.



-findirect-inlining - разрешает встаивать также непрямые вызовы функции, например через указатель на функцию. Опция имеет смысл только, когда подключена хотя бы одна из двух предыдущих опций. Применяется на уровнях оптимизации -O2, -O3, -Os.



-finline-functions-called-once - разрешает рассматривать для встраивания все статические функции, которые лишь однажды вызываются, даже если они не помечены как inline. Если инлайнинг удался, то для функции не генерируется ассемблер. Применяется почти на уровнях оптимизации -O1, -O2, -O3, -Os, но не для -Og.



-finline-limit=n - по дефолту gcc ограничивает размер функций, которые могут быть встроены. Этот флаг позволяет грубо контролировать этот предел. n тут - это размер функции, измеряемый в псевдоинструкциях(знать бы еще что это такое).



-fkeep-inline-functions - оставляет ассемблер для всех встроенных функций. Даже для статических и встроенных во все свои вызовы.



-fpartial-inlining - разрешает встраивание частей функции. Это довольно агрессивная и опасная оптимизация, потому что не совсем понятно, как именно компилятор разбивает функцию на части и решает, какие из них встаивать. Опция имеет смысл только при включенных -finline-functions или -finline-small-functions. Применяется на уровнях оптимизации -O2, -O3, -Os.



Это все основные флаги. Есть еще несколько, но они сложны в описании и понимании, поэтому не буду их упоминать. А в этом списке вроде все логично, понятно и практически применимо.



Optimize your life. Stay cool.



#compiler #optimization #performance