В общем, нет.
Например, в Haskell общей оптимизацией является анализ строгости, который позволяет компилятору определять, какие переменные всегда находятся в нормальном для головы виде и, следовательно, могут быть принудительно + встроены без изменения семантики программы. Это невозможно с LLVM.
Объяснение: В Haskell функция (Int, Int) -> Int
более или менее эквивалентна типу в C:
typedef int (*returns_int)();
struct pair { returns_int first, second};
typedef struct pair *(*returns_pair)();
int function(returns_pair arg);
Компилятор может проанализировать function
и определить, что он всегда вычисляет свой аргумент и всегда извлекает содержимое, превращая функцию в следующее:
int function(int x, int y); // note that it takes *two* arguments now
Это намного выше возможностей LLVM. Возможно, в будущем, с некоторой действительно тяжелой межпроцедурной оптимизацией ... но, по правде говоря, этого не произойдет в обозримом будущем.
Пример 2: Существуют виртуальные машины Java, которые могут преобразовывать вызовы виртуальных функций в прямые вызовы функций. Однако это не то, что может сделать LLVM - потому что это преобразование должно динамически отменяться, если загружен другой класс, который реализует тот же интерфейс.
Как правило, при компиляции программы в LLVM вы теряете большую часть семантической информации об исходной программе. Байт-код LLVM способен представлять любой код, но его система типов довольно ограничена - и выбор системы типов влияет на то, какие оптимизации вы можете сделать.