Подтвердить что ты не робот

Будет ли компилятор оптимизировать партию malloc/free или new/delete в alloca

Есть ли какой-либо зрелый компилятор C/С++, способный оптимизировать malloc/free (или new/delete) пара info alloca? Другими словами, конвертировать из памяти на основе кучи в стек (только для некоторых ограниченных случаев).

Эта оптимизация может быть разрешена только для пары malloc/free, когда обе функции находятся в одной и той же функции (или даже в том же блоке {}), и free вызывается каждый раз, когда вызывается malloc. Кроме того, давайте считать, что указатель на malloced память не сохраняется в некоторой глобальной переменной.

Итак, будет ли GCC/LLVM + clang/Intel Compiler преобразовать такой блок кода:

{
   char *carray;
   carray = malloc(100);          // or malloc(N)
   // some string-like work with carray
   free(carray);
}

в

{
    char*carray;
    carray = alloca(100);  // or if(N<const1) carray=alloca(N);else carray=malloc(N)
    // the same work
    // nothing                       // or if(N>=const1) free(carray)
}

Это преобразование может быть не очень полезно для каждой программы, но я думаю, что может быть какая-то специальная опция компилятора.

PS (update1) Мы можем ограничить наше обсуждение только случаями, когда компилятор знает, что malloc и free - из libc (stdlib)

4b9b3361

Ответ 1

В общем, никакой компилятор не выполняет эту оптимизацию. Это хорошо, потому что эта вещь может быть потенциально очень вредной: помните, что стек обычно очень ограничен по размеру. Если компилятор оптимизировал malloc + free в alloca, наблюдаемое поведение кода изменилось: для некоторых входов оно не сработало бы с malloc + free, но оно было бы с alloca (потому что пространство стека исчерпалось). Поэтому эта оптимизация небезопасна (и не соответствует стандарту, поскольку она изменяет наблюдаемое поведение), а компиляторы даже не пытаются ее выполнить.

Тем не менее, в некоторых особых случаях компилятор мог его выполнить, но компилятор, о котором я знаю, не знает.

Оптимизация, выполняемая LLVM и упомянутая в комментариях, - это другое дело, она оптимизирует только malloc, которые сравниваются только с нулем, а затем free д.

Ответ 2

Там отключен LLVM, называемый poolalloc, который делает эту оптимизацию. Он поддерживается как часть SAFECode и не находится в дистрибутиве LLVM основной линии.

Это описано в Крисе Лэттнере PhD thesis и в этот документ PLDI. Код здесь.

Ответ 3

Технически компиляторы могут оптимизировать что угодно, если они следуют правилу As-If.
Таким образом, оптимизация распределения кучи для распределения стека будет возможна, но для компилятора необходимо быть достаточно интеллектуальным, чтобы исследовать использование и определить, что изменение распределения в стек не повлияет на наблюдаемое поведение программы.

Мне не известно о компиляторе, который делает это.