Closed kubo39 closed 9 months ago
Rustのasm!構文を読んでみると、デフォルトでmemory
constraintを付与、かつoptionで NOMEM
を指定することで外すことができるそうです。
https://doc.rust-lang.org/reference/inline-assembly.html#options
LLVM backendではこのような記述があるが、意図が汲めていない。 https://github.com/rust-lang/rust/blob/2f19122f73027219a152e0c2ff35cebab940876c/compiler/rustc_codegen_llvm/src/asm.rs#L268-L273
if !options.contains(InlineAsmOptions::NOMEM) {
// This is actually ignored by LLVM, but it's probably best to keep
// it just in case. LLVM instead uses the ReadOnly/ReadNone
// attributes on the call instruction to optimize.
constraints.push("~{memory}".to_string());
}
コメントありがとうございます、今週ちょっと忙しいのでもしかしたら遅くなるかもしれませんが、追記しておきたいと思います!
Rust and Atomicsのcompiler fenceの説明ではLLVM固有の情報には触れていない: https://marabos.nl/atomics/memory-ordering.html#compiler-fences
ただどうもLLVMは現状compiler fenceをatomic fenceにloweringするようで、これを是正するパッチが出ている(まだ本体には取り込まれていない): https://reviews.llvm.org/D92842
LLVM backendではこのような記述があるが、意図が汲めていない。 https://github.com/rust-lang/rust/blob/2f19122f73027219a152e0c2ff35cebab940876c/compiler/rustc_codegen_llvm/src/asm.rs#L268-L273
すぐ下に説明があった。~{memory}
の有無にかかわらずデフォルトで最適化を許容しないようになっているのだな。
if options.contains(InlineAsmOptions::PURE) {
if options.contains(InlineAsmOptions::NOMEM) {
attrs.push(llvm::MemoryEffects::None.create_attr(self.cx.llcx));
} else if options.contains(InlineAsmOptions::READONLY) {
attrs.push(llvm::MemoryEffects::ReadOnly.create_attr(self.cx.llcx));
}
attrs.push(llvm::AttributeKind::WillReturn.create_attr(self.cx.llcx));
} else if options.contains(InlineAsmOptions::NOMEM) {
attrs.push(llvm::MemoryEffects::InaccessibleMemOnly.create_attr(self.cx.llcx));
} else {
// LLVM doesn't have an attribute to represent ReadOnly + SideEffect
}
attributes::apply_to_callsite(result, llvm::AttributePlace::Function, &{ attrs });
readonly + sideeffectな最適化の組み合わせがLLVMでは提供できなくて、本来可能である最適化ができないっちゅう話かも。かなし~。
結論だけ書くと、LLVMのインラインアセンブラはmemory clobber(~{memory}
)を単に無視します。
かわりにclangやrustcなどの各処理系がいい感じに関数属性を設定(LLVMのインラインアセンブラはLLVM内部的には関数と同じ扱い)することで同等の機能を実現しています。
(ここまでpasopediaに書く必要はあるんだろうか…?)
これは驚きですね!この内容も追記していいですか? (もちろん @kubo39 さんから教えて頂いたということを明記します)
@Totsugekitai 大丈夫です、というかここに書いてることは自由に使ってもらってかまわないですよ。
ありがとうございます🙇
fixed at #18
memory
の説明がないので、どういう意味があるのかよくわかりませんでした!! よくある__asm__ __volatile__("": : :"memory")
を使ってreorderingを抑制(SW barrier)する話とかあるといいと思います!!@Totsugekitai 先生よろしくお願いいたします!