alloca
выделяет память в локальном фрейме функции.Необходимо создать переменную, адрес которой берется, как в этом примере:
void foo(int* ptr) {
*ptr = 4;
}
int main() {
int value = 0;
foo(&value);
printf("%i\n", value); // 4
}
Если она не встроена foo
, тогда LLVM потребуется инструкция alloca
в main
длясоздать память, которая поддерживает переменную value
.foo
необходимо использовать store
, чтобы поместить 4 по адресу, на который указывает ptr
, а затем main
необходимо использовать load
для загрузки содержимого value
после того, как оно было изменено с помощью foo
.
Компиляторы для языков семейства C обычно предпочитают начинать с использования alloca
для каждой переменной в фрейме функции, а затем позволяют LLVM оптимизировать значения alloca
s для значений SSA.Во многих случаях компилятор может преобразовывать переменные alloca
в значения SSA, как показывает функция ssa2
.Форма SSA может представлять переменные, которые удовлетворяют следующим двум условиям:
- их адреса не заняты
- их размер фиксирован
"Получение адреса переменной - это операция, которой нет в Javascript / Ruby, поэтому вам, возможно, придется разбираться в C, чтобы понять, что это значит.Это очень часто встречается в C и C ++.
«Фиксированный размер» означает, что компилятор заранее знает, сколько памяти ему нужно для конкретной структуры данных.Например, он всегда знает простые числа, но массивы часто имеют переменный размер.Массивы, размер которых неизвестен во время выполнения, могут быть выделены с помощью alloca
или malloc
, а затем вам нужно получить доступ к их содержимому с помощью load
и store
.
Наконец, обратите внимание, чтоваш второй пример не работает: он читает неинициализированное значение, и если вы скомпилируете его с более высокими уровнями оптимизации, вы просто получите ret i32 undef
.