Выполнение компилятором выделения памяти в стеке разного размера

StackOverflow https://stackoverflow.com/questions/2231932

Вопрос

Я создавал свой собственный компилятор, и большая его часть, очевидно, представляет собой распределитель регистров, который максимально эффективно сопоставляет временные переменные с машинными регистрами.В такой архитектуре, как x86, не так много регистров, поэтому существует ряд случаев, когда переменные должны храниться в памяти (стеке).Существуют также переменные, хранящиеся в памяти, поскольку они слишком велики, чтобы поместиться в регистр.

Распределитель регистров фактически вызывается снова для эффективного распределения переменных в памяти, чтобы было использовано как можно больше пространства.Настоящая проблема заключается в том, что нет способа ограничить распределитель регистров размещением двух переменных в памяти рядом друг с другом (так как тогда я могу передать ему большие переменные как несколько меньших переменных) и позволить распределителю перемещать меньшие переменные. так что переменные большего размера могут поместиться, и мне интересно, есть ли какие-либо алгоритмы, позволяющие справиться с этим, иначе мне придется разделить память на разные области, каждая из которых содержит переменные разного размера.

Вот пример, демонстрирующий это:

void f(){
    int32_t a, b;
    //something happens to a and b...
    int64_t c;
    //something happens to c...
}

Здесь необходимо сделать несколько предположений для целей примера... что переменные не оптимизированы, a и b больше не нужны после определения c и что все переменные распределяются в стековую память.Очевидно, я бы хотел, чтобы «c» использовал ту же память, что и «a» и «b», и, следовательно, выделял только 8 байт, однако текущая версия моего компилятора выделяла бы полные 16 байт.

Мой вопрос: как я могу эффективно распределять переменные в памяти разного размера?

Это было полезно?

Решение

Очевидно, что распределитель регистров не является достаточно универсальным для распределения пространства стека, поскольку объединять соседние регистры не имеет смысла — по крайней мере, на x86.

Почему бы не расширить его, чтобы сделать именно это?Или, еще лучше, разделите его или создайте подкласс, чтобы напрямую управлять распределением регистров и стека.

Что касается распределителя стека, то он обычно неэффективен ни по времени выполнения, ни особенно по пространству, чтобы минимизировать стек, используемый в (редком) случае, когда две переменные могут использовать одно и то же распределение из-за непересекающейся области видимости.Операции по выделению и освобождению дополнительного пространства стека при переходе области вряд ли оправдают себя.Даже при самой важной обработке в реальном времени обычно больше интересуют надежность и скорость, чем сокращение нескольких байтов стекового пространства.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top