Программистский вопрос залу
У меня нет под рукой свежих Си-компиляторов (а если бы и были, то только GCC); кто-нибудь может проверить, умеет ли какой-нибудь компилятор находить в этом коде loop invariants и выносить их из цикла, чтобы в нем не оставалось условных переходов?
extern int f(int, int), g(int, int);
int foo(int en, int d1, int d2) {
int i, s = 0;
for (i = 0; i < 100; i++) {
s += en & 1 ? f(d1, i) : g(d2, i);
s += en & 2 ? f(d1, i+1) : g(d2, i+1);
s += en & 4 ? f(d1, i+2) : g(d2, i+2);
s += en & 8 ? f(d1, i+3) : g(d2, i+3);
...
}
return s;
}Но не по-идиотски, репликацией тела цикла (потому что таких условных операторов может быть много, на все экспоненциально не напасешься - GCC, который у меня, например, реплицирует, если в цикле не более 3 условных операторов, а потом вообще ничего никуда не выносит), а введением дополнительных переменных, наподобиеint d_0 = en & 1 ? d1 : d2;
int d_1 = en & 2 ? d1 : d2;
...
int (*fn_0)(int, int) = en & 1 ? f : g;
int (*fn_1)(int, int) = en & 2 ? f : g;
...
for (i = 0; i < 100; i++) {
s += fn_0(d_0, i);
s += fn_1(d_1, i+1);
...
}
Как бы вы анализировали граф на предмет поиска подобных возможностей?