Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, Бабокин Дмитрий, Вы писали:
БД>>Вот пример, который нельзя разбить на несколько циклов: WH>Я просил пример который нельзя оптимизировать. БД>>Блоки 2 и 3 являются циклом с двумя входами.
БД>>А оптимизировать нечего только пока CFG не наполнен реальным кодом. WH>Я всеравно не понимаю как это мешает оптимизатору?
Похоже мы смотрим на это с разных колоколен. Я утверждаю, что циклы, написаные с помощь goto могут быть трудны для анализа. В частности, циклы с несколькими входами (от которых всё-таки не всегда можно избавиться). Чем конкретно они могут осложныть анализ? Пример — алгоритм вычисления счётчиков выполнения каждого линейного участка по вероятносям переходов и счётчику входа в функцию. Что значит осложнять анализ — это значит увеличивать размер самого алгоритма и увеличивать его алгоритмическую сложность.
Почему я не говорю непосредственно о случаях, которые "нельзя оптимизировать"? Потому, что глядя на конкретный пример, человек всегда придумает как его соптимизировать. Вопрос как построить оптимизатор, который будет брать все подобные случаи. Вот тут-то мы и приходим к тому, "как это мешает оптимизатору". Это мешает тем, что обработка такой нестандартной структуры CFG требует более сложных алгоритмов анализа, необходимость которые вызывает сомнение. Учитывая то, что тестировать такие алгоритмов намного сложнее из-за редкости таких порнографичных случаев, получаем плохое покрытие этих алгоритмов в тестовой базе. В то же время, абсолютное большинство кода пишется без использования goto, либо использование goto не приводит нестандартной структуре CFG. Теперь вопрос — стоит ли разработчику компилятора добавлять поддержку оптимизации столь редких случаев и при этом заметно осложняя себе жизнь?
Т.е. ответаты на твои вопросы будут такими.
1. Привести пример, который нельзя оптимизировать - я не утверждаю, что есть примеры которые в принципе нельзя оптимизировать только потому, что были использованиы goto.
2. Как это мешает оптимизатору — это осложныет различные виды анализа, как следствие оптимизатор может просто отказаться от некоторых видов оптимизации, либо провести их не совсем верно.
Здравствуйте, Dmi_3, Вы писали:
D_>Здравствуйте, 0xDEADBEEF, Вы писали:
DEA>> reduction_algo reduce(mn); DEA>> goto start; DEA>> for(;) { DEA>> umul(n1, n2, n2); DEA>> reduce(n2, n1); DEA>> if( *ep & mask ) { DEA>> umul(n1, n2, an); DEA>> start: reduce(n2, n1); DEA>> } DEA>> if( 0 == (mask >>= 1) ) { DEA>> if( --ep < en->data_ ) break; DEA>> mask = 1 << (data::bits-1); DEA>> } DEA>> } rn->>>copy(n2); DEA>>} DEA>>[/c] DEA>>Посему, вопрос: должен ли goto в данном куске кода быть изничтожен, если да, то какие преимущества сие действие принесет.
D_>Я не антифанат goto. Для него тоже есть малюсенький уголок в программировании, но этот пример крайне неудачен и чисто формально преобразуем в более понятный вид без goto:
Ну этот код что-то делает и иногда ему это удается. Так он мне читается. Провернув цикл Вы переместило break; в начало цикла.
Видимо здесь есть некое понятное состояние, с которого этот цикл и начинался. Теперь оно спрятано в середине цикла. Вполне возможно что этим Вы совершенно разрушили читабельность кода. Дело в том, что чисто формальный подход здесь может быть не уместен. Не вдаваясь в работу вообще нельзя доказать что этот цикл когдато закончится.
Здравствуйте, Programador, Вы писали:
D_>>Я не антифанат goto. Для него тоже есть малюсенький уголок в программировании, но этот пример крайне неудачен и чисто формально преобразуем в более понятный вид без goto:
P>Ну этот код что-то делает и иногда ему это удается. Так он мне читается. Провернув цикл Вы переместило break; в начало цикла. P> Видимо здесь есть некое понятное состояние, с которого этот цикл и начинался. Теперь оно спрятано в середине цикла. Вполне возможно что этим Вы совершенно разрушили читабельность кода. Дело в том, что чисто формальный подход здесь может быть не уместен. Не вдаваясь в работу вообще нельзя доказать что этот цикл когдато закончится.