В последнее время я встречал множество функций, в которых gcc генерирует действительно плохой код на x86. Все они соответствуют шаблону:
if (some_condition) {
/* do something really simple and return */
} else {
/* something complex that needs lots of registers */
}
Думайте о простом случае как о чем-то настолько маленьком, что половина или больше работы тратится на выталкивание и извлечение регистров, которые вообще не будут изменены. Если бы я писал asm вручную, я бы сохранил и восстановил регистры сохраненных между вызовами внутри сложного случая и вообще не касался бы указателя стека в простом случае.
Есть ли способ заставить gcc работать с быть немного умнее и сделать это само? Желательно с параметрами командной строки, а не с уродливыми хаками в исходном коде ...
Edit: Чтобы сделать это конкретнее, вот что-то очень похожее на некоторые функции, с которыми я имею дело:
if (buf->pos < buf->end) {
return *buf->pos++;
} else {
/* fill buffer */
}
и еще одна:
if (!initialized) {
/* complex initialization procedure */
}
return &initialized_object;
и еще один:
if (mutex->type == SIMPLE) {
return atomic_swap(&mutex->lock, 1);
} else {
/* deal with ownership, etc. */
}
Edit 2: Я должен был упомянуть для начала: эти функции не могут быть встроены. У них есть внешняя связь, и они являются библиотечным кодом. Разрешение им быть встроенным в приложение приведет к разного рода проблемам.