apply
に渡されるクロージャはLLVM IR {i64*, i64*}*
として渡されなぜRustはLLVM IRクロージャ環境でi64 *としてクロージャによってキャプチャされたi64を格納しますか?
#[inline(never)]
fn apply<F, A, B>(f: F, x: A) -> B
where F: FnOnce(A) -> B {
f(x)
}
fn main() {
let y: i64 = 1;
let z: i64 = 2;
let f = |x: i64| x + y + z;
print!("{}", apply(f, 42));
}
この単純な例では:
%closure = type { i64*, i64* }
define internal fastcc i64 @apply(%closure* noalias nocapture readonly dereferenceable(16)) unnamed_addr #0 personality i32 (i32, i32, i64, %"8.unwind::libunwind::_Unwind_Exception"*, %"8.unwind::libunwind::_Unwind_Context"*)* @rust_eh_personality {
entry-block:
%1 = getelementptr inbounds %closure, %closure* %0, i64 0, i32 1
%2 = getelementptr inbounds %closure, %closure* %0, i64 0, i32 0
%3 = load i64*, i64** %2, align 8
%4 = load i64*, i64** %1, align 8
%.idx.val.val.i = load i64, i64* %3, align 8, !noalias !1
%.idx1.val.val.i = load i64, i64* %4, align 8, !noalias !1
%5 = add i64 %.idx.val.val.i, 42
%6 = add i64 %5, %.idx1.val.val.i
ret i64 %6
}
(apply
が実際に発生LLVMコードでより複雑な名前を持っている。)
これにより、キャプチャされた各変数に2つの負荷が発生します。 %closure
はなぜapply
{i64, i64}*
になるのですか?{i64, i64}
はなぜですか?
ありがとうございます。私は 'i64'をコピーするのが安価で、安価でない場合は参考にして、' i64'のRustを変更することはできないので、値だけ透過的にコピーすると仮定していました。あなたはこのコードで何らかの形で値と基準の違いを観察できますか? – tibbe