Выполнение выделения памяти компилятором в стеке разных размеров - PullRequest
1 голос
/ 09 февраля 2010

Я создавал свой собственный компилятор, и одна большая его часть - это, очевидно, распределитель регистров, который максимально эффективно сопоставляет временные переменные с машинными регистрами. В архитектуре, такой как 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 байтов.

У меня вопрос: как эффективно распределить переменные в памяти разных размеров?

1 Ответ

1 голос
/ 09 февраля 2010

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

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

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

...