Оптимизация IL для компиляторов JIT
Я разрабатываю компилятор, который испускает IL-код. Важно, чтобы полученный IL был JIT'ом для самых быстрых возможных машинных кодов с помощью компиляторов Mono и Microsoft.NET JIT.
Мои вопросы:
-
Имеет ли смысл оптимизировать шаблоны, например:
'stloc.0; ldloc.0; ret' => 'ret'
'ldc.i4.0; conv.r8' => 'ldc.r8.0'
и такие, или JIT достаточно умны, чтобы позаботиться об этом?
-
Есть ли спецификация со списком оптимизаций, выполняемых компиляторами Microsoft/Mono JIT?
-
Есть ли хорошее понимание с практическими рекомендациями/рекомендациями по оптимизации IL, чтобы компиляторы JIT могли, в свою очередь, генерировать наиболее оптимальный машинный код (по производительности)?
Ответы
Ответ 1
- Два описанных вами шаблона - это простой материал, который JIT фактически получает право (за исключением непримитивных структур). В SSA формальное распространение и устранение мертвых значений очень просто.
- Нет, вам нужно проверить, что может сделать JIT. Изучите литературу компилятора, чтобы узнать, какие стандартные оптимизации можно ожидать. Затем протестируйте их. Два JIT, которые мы сейчас оптимизируем очень мало, и иногда не получают самых простых вещей. Например,
MyStruct s; s.x = 1; s.x = 1;
не оптимизирован RyuJIT. s = s;
тоже. s.x + s.x
загружает x дважды из памяти. Ожидайте немного.
- Вам нужно понять, к чему относятся основные операции машинного кода. Это не слишком сложно. Попробуйте несколько вещей и посмотрите на список демонтажа. Вы быстро почувствуете, как будет выглядеть результат.
Ответ 2
Резервные конверсии и загрузки/хранения - это довольно неизбежный побочный эффект рекурсивного приличного парсера. Вы можете технически избавиться от них с помощью оптимизатора головок. Но не о чем беспокоиться, компиляторы С# и VB.NET тоже генерируют их.
Существующие неудобства .NET/Mono очень хорошо оптимизируют их. Они сосредоточены на оптимизации кода, который действительно имеет значение для скорости выполнения, машинного кода. С очень хорошим преимуществом, что любой, кто пишет компилятор, который генерирует IL, автоматически извлекает выгоду из этих оптимизаций, не делая ничего особенного.
Оптимизации дрожания описаны в этом сообщении.