Глядя на документацию LLVM-IR по атрибутам функций , я не смог разобрать, как я могу использовать атрибут функции, чтобы пообещать LLVM, что функция будет alloca
фреймом стека для сам и изменяет этот фрейм стека, но не будет читать или записывать любую другую память. Я думаю, это то, что inaccessiblememonly
означает
, функция может обращаться только к памяти, недоступной для компилируемого модуля
, но я я не уверен. С одной низкоуровневой точки зрения стек доступен везде, поскольку другие функции могут alloca
использовать ту же самую память, но с другой, немного более абстрактной точки зрения, области alloca
'd функции недоступны, кроме как через указатель, возвращаемый функцией alloca
, который в моем случае не будет передан нижестоящим функциям.
Итак, следующее законное использование inaccessiblememonly
игнорирует его очевидную неэффективность по сравнению с версией без стека, которая использует insertvalue
?
define { i64, i32 } @foo ({ i64, i32 } %bar, i32 %baz) inaccessiblememonly {
;; save bar to the stack
%bar-save = alloca { i64, i32 }
store { i64, i32 } %bar, { i64, i32 }* %bar-save
;; overwrite its second field with baz
%bar-second = getelementptr { i64, i32 }, { i64, i32 }* %bar-save, i32 0, i32 1
store i32 %baz, i32* %bar-second
;; return the modified struct
%bar-val = load { i64, i32 }, { i64, i32 }* %bar-save
ret { i64, i32 } %bar-val
}