Комментарии 3
Мда. Как мне видится, есть две идеальные крайности. Первая - инструкции расположены линейно в массиве, роль метки для перехода выполняет индекс. Это максимально экономит память на хранении кода, а при трансформации нужно делать коррекцию меток-индексов. Вторая крайность состоит в том, что инструкции хранятся как граф, объект под каждую инструкцию отдельно выделяется на куче, каждая инструкция ссылается на следующую, и интерпретатор идёт по графу. А тут какой-то мутант: инструкции являются отдельными объектами, ссылки на них хранятся в массиве, но ещё есть двусвязный список неких адресов, которые используют хеширование или какие-то генерирующиеся имена, брр. Очень переусложнено.
Вы правы, по сути у меня интерпретация второй крайности. Связный список это же частный случай графа :-) На мой взгляд в компиляторе важнее скорость и мне хотелось изменять список инструкций во время оптимизаций за минимальное время. Поэтому выбрал путь не экономить память
Связные списки и всякое брожение по указателям обычно не очень быстрое.
Для оптимизаций обычно используют Cfg. Там каждый базовый блок храниться в линейном массиве. При модификации Вы спокойно меняете этот массив за линейное время.
А вот для исполнения такая структура подходит плохо. Поэтому перед исполнением разумно разложить код в линейный массив с индексами в качестве адресов. Если не следить за локальностью, это делается довольно просто (только нужно правильное апи билдера сделать).

Почему число это плохой адрес для инструкции?