Вообще-то да. Но нет никакой гарантии, и места, где это сделает компилятор, вероятно, редки.
То, что большинство компиляторов делают без проблем, это вывод неизменных вычислений из цикла, например если ваше состояние
if (a<b) ....
когда цикл не влияет на a и b, сравнение будет выполнено один раз перед циклом.
Это означает, что если компилятор может определить, что условие не изменяется, тест будет дешевым, и прогнозирование перехода будет предсказано. Это, в свою очередь, означает, что сам тест стоит один цикл или вообще никакого цикла (на самом деле).
В каких случаях будет полезно разделение цикла?
а) очень узкая петля, где 1 цикл - это значительные затраты
б) весь цикл с обеими частями не помещается в кэш кода
Теперь компилятор может делать только предположения о кеше кода и обычно может упорядочить код таким образом, чтобы одна ветвь соответствовала кешу.
Без какого-либо тестирования я буду ожидать a) единственный случай, когда такая оптимизация будет применена, потому что это не всегда лучший выбор:
В каких случаях разбиение цикла будет плохим?
Когда разделение цикла увеличивает размер кода за пределами кэша кода, вы получите значительный удар. Теперь это влияет только на вас, если сам цикл вызывается в другом цикле, но компилятор обычно не может определить это.
[править]
Я не смог заставить VC9 разделить следующий цикл (один из немногих случаев, когда это могло бы быть полезно)
extern volatile int vflag = 0;
int foo(int count)
{
int sum = 0;
int flag = vflag;
for(int i=0; i<count; ++i)
{
if (flag)
sum += i;
else
sum -= i;
}
return sum;
}
[редактировать 2]
обратите внимание, что с int flag = true;
вторая ветвь оптимизируется. (и нет, const здесь не имеет значения;))
Что это значит? Либо это не поддерживает, это не имеет значения, ро мой анализ неверен ;-)
Как правило, я бы сказал, что это оптимизация, которая полезна лишь в очень немногих случаях и может быть легко выполнена вручную в большинстве сценариев.