В последнее время я столкнулся с множеством функций, где gcc генерирует действительно плохой код на x86. Все они соответствуют шаблону:
if (some_condition) {
/* do something really simple and return */
} else {
/* something complex that needs lots of registers */
}
Подумайте о простом случае как о чем-то таком маленьком, что половина или больше работы тратится на толкание и выскакивание регистров, которые вообще не будут изменены. Если бы я писал asm вручную, я бы сохранил и восстановил регистры с сохраненными перекрестными вызовами внутри сложного случая и вообще не касался указателя стека в простом случае.
Есть ли способ заставить gcc быть немного умнее и сделать это сам? Предпочтительно с параметрами командной строки, а не уродливыми хаками в источнике...
Изменить: Чтобы сделать его конкретным, здесь что-то очень близко к некоторым из функций, с которыми я имею дело:
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. */
}
Изменить 2: Я должен был упомянуть для начала: эти функции не могут быть встроены. У них внешняя связь, и они являются библиотечным кодом. Предоставление им возможности быть встроенным в приложение приведет к возникновению всех проблем.