標籤:

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 |