Поворотное развертывание в GCC
Этот вопрос частично является последующим вопросом кGCC 5.1 Развертывание петли.
СогласноДокументация GCCи, как указано в моем ответе на вышеуказанный вопрос, флаги, такие как-funroll-loops
включи«полное удаление петель (то есть полное удаление петель с небольшим постоянным числом итераций)», Поэтому, когда такой флаг активирован, компилятор может выбрать развертывание цикла, если он определит, что это оптимизирует выполнение данного фрагмента кода.
Тем не менее, я заметил в одном из моих проектов, что GCC иногда развертывает циклыхотя соответствующие флаги не были включены, Например, рассмотрим следующий простой фрагмент кода:
int main(int argc, char **argv)
{
int k = 0;
for( k = 0; k < 5; ++k )
{
volatile int temp = k;
}
}
При компиляции с-O1
, цикл разворачивается и следующий код сборки генерируется с любой современной версией GCC:
main:
movl $0, -4(%rsp)
movl $1, -4(%rsp)
movl $2, -4(%rsp)
movl $3, -4(%rsp)
movl $4, -4(%rsp)
movl $0, %eax
ret
Даже при компиляции с дополнительным-fno-unroll-loops -fno-peel-loops
чтобы убедиться, что флагиотключенGCC неожиданно все еще выполняет развертывание цикла в примере, описанном выше.
Это наблюдение приводит меня к следующим тесно связанным вопросам. Почему GCC выполняет развертывание цикла, даже если флаги, соответствующие этому поведению, отключены? Развертывание также контролируется другими флагами, которые могут заставить компилятор развернуть цикл в некоторых случаях, даже если-funroll-loops
выключен? Есть ли способ полностью отключить развертывание цикла в GCC (часть от компиляции с-O0
)?
Интересно, чтолязг здесь компилятор ведет себя ожидаемым образом и, по-видимому, выполняет развертывание только при-funroll-loops
включен, и не в других случаях.
Заранее спасибо, любые дополнительные идеи по этому вопросу будет принята с благодарностью!