Причина, по которой я спрашиваю, заключается в том, что я обдумываю идею динамического создания метода на основе IL-кода существующего метода; манипуляция, которую я хочу выполнить, достаточно проста, когда код оптимизирован, но становится значительно сложнее в неоптимизированном коде из-за дополнительных инструкций, генерируемых компилятором.
РЕДАКТИРОВАТЬ: подробнее о неоптимизациях, которые меня беспокоят...
Давайте рассмотрим следующую реализацию факториала функция:
Код: Выделить всё
static long FactorialRec(int n, long acc)
{
if (n == 0)
return acc;
return FactorialRec(n - 1, acc * n);
}
Интерфейс, созданный с включенной оптимизацией, довольно прост:
Код: Выделить всё
IL_0000: ldarg.0
IL_0001: brtrue.s IL_0005
IL_0003: ldarg.1
IL_0004: ret
IL_0005: ldarg.0
IL_0006: ldc.i4.1
IL_0007: sub
IL_0008: ldarg.1
IL_0009: ldarg.0
IL_000A: conv.i8
IL_000B: mul
IL_000C: call UserQuery.FactorialRec
IL_0011: ret
Код: Выделить всё
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldc.i4.0
IL_0003: ceq
IL_0005: ldc.i4.0
IL_0006: ceq
IL_0008: stloc.1
IL_0009: ldloc.1
IL_000A: brtrue.s IL_0010
IL_000C: ldarg.1
IL_000D: stloc.0
IL_000E: br.s IL_001F
IL_0010: ldarg.0
IL_0011: ldc.i4.1
IL_0012: sub
IL_0013: ldarg.1
IL_0014: ldarg.0
IL_0015: conv.i8
IL_0016: mul
IL_0017: call UserQuery.FactorialRec
IL_001C: stloc.0
IL_001D: br.s IL_001F
IL_001F: ldloc.0
IL_0020: ret
Почему это проблема? Я хочу динамически генерировать метод, включающий оптимизацию хвостового вызова. Оптимизированный метод можно легко изменить, добавив префикс Tail. перед рекурсивным вызовом, поскольку после вызова нет ничего, кроме ret. Но в неоптимизированной версии я не так уверен... результат рекурсивного вызова сохраняется в локальной переменной, затем появляется бесполезная ветвь, которая просто переходит к следующей инструкции, локальная переменная загружается и возвращается. Поэтому у меня нет простого способа проверить, действительно ли рекурсивный вызов является последней инструкцией, поэтому я не могу быть уверен, что можно применить оптимизацию хвостового вызова.
Подробнее здесь: https://stackoverflow.com/questions/968 ... fic-method