llvm memcpy的本質?
llvm內部的指令llvm.memcpy 在最後的二進位程序中,是調用了msvcp庫里的memcpy么。如果是這樣,為什麼不直接使用memcpy
LLVM的 @llvm.memcpy 是一個intrinsic function,在優化的過程中LLVM有可能對它做很多有趣的分析和優化,例如說可以利用它的特性來影響對周圍其它代碼的優化;可以把它內聯展開(然後最終代碼里就沒有對memcpy的調用了),或者是發現它只是用來繞過C的strict-aliasing要求於是把它徹底優化掉,或者實在不行了才生成對外部的C runtime library的memcpy()函數的調用。
memcpy是一個非常常用的、影響編譯器對內存訪問分析的函數,所以LLVM為它聲明了一個intrinsic來讓編譯器能知道並利用其特殊的屬性,例如說它對alias analysis的影響等。如果最終生成了對CRT中的memcpy()的調用,那最終是哪個CRT實現(msvcrt、glibc等)被鏈接進來就會用哪個實際的memcpy()的實現。
順帶一提,LLVM針對intrinsified library call可以做很多很多有趣的事情。例如說,它可以把某些memmove()調用轉化為memcpy(),可以把某些strcpy()、strncpy()調用轉化為memcpy(),可以把某些printf()變成puts(),等等。
把俺在評論區舉的例子貼上來:這個例子:void foo(char src[8], char dst[8]) {
memcpy(dst, src, 8);
}
LLVM可以為x86-64編譯成這樣:
mov rax, qword ptr [rdi]
mov qword ptr [rsi], rax
ret
下面這個例子:
void foo(char src[32], char dst[32]) {
memcpy(dst, src, 32);
}
LLVM可以為比較新的x86-64編譯為AVX2版:
vmovups ymm0, ymmword ptr [rdi]
vmovups ymmword ptr [rsi], ymm0
vzeroupper
ret
嗯。
不妨去實現幾個malloc,等到臉被打腫了的時候就明白了
建議參考 Minimum alignment of allocation across platforms
表示代碼需要拷貝一段內存
除了顯式的memcpy結構體的賦值也可以表示為memcpy結構體的初始化也可以表示為memset至於最終的代碼什麼樣 取決於目標機器/環境
比如已知拷貝長度很短 那麼幾條ld/st就可以了推薦閱讀:
※LLVM國內的開發者需要Social一下嗎?
※怎麼將二進位代碼轉換為中間代碼(IR)呢?
※如何理解LLVM的PassManager系統的實現?
※為什麼很多語言的JIT實現最後會失敗,主要的技術原因和難點有哪些?
※llvm的reg2mem pass做了哪些事情?
TAG:LLVM |