Будет ли компилятор оптимизировать партию 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)
Ответы
Ответ 1
В общем, никакой компилятор не выполняет эту оптимизацию. Это хорошо, потому что эта вещь может быть потенциально очень вредной: помните, что стек обычно очень ограничен по размеру. Если компилятор оптимизировал malloc
+ free
в alloca
, наблюдаемое поведение кода изменилось: для некоторых входов оно не сработало бы с malloc
+ free
, но оно было бы с alloca
(потому что пространство стека исчерпалось). Поэтому эта оптимизация небезопасна (и не соответствует стандарту, поскольку она изменяет наблюдаемое поведение), а компиляторы даже не пытаются ее выполнить.
Тем не менее, в некоторых особых случаях компилятор мог его выполнить, но компилятор, о котором я знаю, не знает.
Оптимизация, выполняемая LLVM и упомянутая в комментариях, - это другое дело, она оптимизирует только malloc
, которые сравниваются только с нулем, а затем free
д.
Ответ 2
Там отключен LLVM, называемый poolalloc, который делает эту оптимизацию. Он поддерживается как часть SAFECode и не находится в дистрибутиве LLVM основной линии.
Это описано в Крисе Лэттнере PhD thesis и в этот документ PLDI. Код здесь.
Ответ 3
Технически компиляторы могут оптимизировать что угодно, если они следуют правилу As-If.
Таким образом, оптимизация распределения кучи для распределения стека будет возможна, но для компилятора необходимо быть достаточно интеллектуальным, чтобы исследовать использование и определить, что изменение распределения в стек не повлияет на наблюдаемое поведение программы.
Мне не известно о компиляторе, который делает это.