LLVM language 參考手冊(譯)(5)

 

垃圾回收器名稱(Garbage Collector Names

每個函數能夠制定一個垃圾回收期的名稱,這個名稱是一個簡單的字符串:html

define void @f() gc "name" { ... }

編譯器聲明瞭這個名字的可能值。指定一個收集器將會致使編譯器會爲了支持這個垃圾回收算法修改它的輸出。前端

前置數據(Prefix Data

前置數據是一種與函數相關的數據,在函數主體以前代碼生成器會立刻發散這種數據。這個特性的目的是爲了讓容許在前端分配語言指定的在指定函數中運行期元數據,而且能夠經過函數指針來得到這個數據的同時這個函數指針仍然是可調用的。對一個給定的函數來訪問這個數據,程序能夠經過bitcast轉換這個函數指針到一個常量類型的指針。這是意味着這個IR符號指向這個前置數據的開始。算法

爲了維持普通函數調用的語義,這個前置數據必須有一個實際格式。具體來講,這必須開始於一段bytes序列,且能夠從中解碼到一段用於該模塊目標的機器指令序列,這個點的傳送控制緊隨這個前綴數據,而不執行任何其餘的可見動做。這就容許內聯器和其餘pass來推論這是一個函數定義語義而不是須要一個前置數據。顯而易見地,這使前置數據的格式高度依賴於目標平臺。後端

前置數據的定義,相似於一個前綴數據類型的全局變量的初始化式。在前置數據和函數主體之間沒有自動填充的數據。若是有填充要求,那麼它必須是前置數據的一部分。數組

這是一個很小的有效前置數據,其對於X86體系結構的值爲144,類型爲i8,則會被編碼爲 nop 指令。安全

define void @f() prefix i8 144 { ... }

通常來講,前置數據能夠跳過元數據經過編碼一個相關的branch指令,就像下面這個例子中的對於X86_64體系有效的前置數據,它的前兩個byte將被編碼jmp.+10dom

%0 = type <{ i8, i8, i8* }>

define void @f() prefix %0 <{ i8 235, i8 8, i8* @md}> { ... }

函數可能只擁有前置數據但沒有主體。這與 available_externally 連接標識有着相同的語義,即數據可能會被優化器使用的不會被髮散到對象文件中。函數

屬性組(Attribute Groups

屬性組是在IR中的對象引用的屬性的集合。他們對於保持 .ll 可讀有着重要意義,由於許都函數會使用相同的屬性集。在退化的狀況下一個 .ll 文件對應着單一的 .c 文件,這個單一的屬性組講捕獲那些用於構建這個文件的重要命令行標識。佈局

一個屬性組是一個模塊層次的對象。要使用一個屬性組,一個對象能夠引用這個屬性組的ID(例如 #37)。一個對象可能引用超過一個屬性組。在這種狀況下來自於不一樣屬性組的屬性會被合併。性能

這裏有一個規定一個函數應該內聯的屬性組的例子,並擁有一個堆棧對齊屬性值爲4,且不使用SSE指令

; Target-independent attributes:
attributes #0 = { alwaysinline alignstack=4 }

; Target-dependent attributes:
attributes #1 = { "no-sse" }

; Function @f has attributes: alwaysinline, alignstack=4, and "no-sse".
define void @f() #0 #1 { ... }

函數屬性(Function Attributes

函數屬性用於函數交流額外信息的。函數屬性被認爲是函數的一部分,而不是函數類型的一部分,因此擁有不一樣函數屬性的函數能夠對應着同一個函數類型。

函數屬性是緊跟在指定的函數類型後的簡單的關鍵字。若是之後須要指定多個函數屬性,那麼使用空格符分隔它們。例如:

define void @f() noinline { ... }
define void @f() alwaysinline { ... }
define void @f() alwaysinline optsize { ... }
define void @f() optsize { ... }
alignstack(<n>)
這個屬性指明瞭,當發散序言和後記,後端應該強制對齊堆棧指針。在括號中指定所但願的對齊屬性,其值必須是2的冪。
alwaysinline
該屬性指明瞭內聯器應該儘量地內聯這個函數到調用者中,而忽略這個調用者有效的內聯闕值。
builtin
這代表,在調用點被調用函數應該被認定爲內建函數,即便該函數的聲明使用了  nobuiltin 屬性。這隻在直接調用了聲明瞭  nobuiltin 屬性的函數的調用地點有效。
cold
該屬性代表了這個函數將不多被調用。在計算邊權重時,被一個cold函數所控制的基本塊也被認爲是cold的,所以將被給予低權重。
inlinehint
該屬性代表,這份源代碼包含一個提示,即內聯函數是可行的(如C / C + +中的「inline」關鍵字)。這僅僅是一個提示,它不對內聯器作出任何要求。
minsize
該屬性建議優化器pass和代碼生成器pass保持函數的代碼長度儘可能的小且犧牲運行時效率來最小化生成的代碼來進行優化。
naked
這個屬性禁止函數的序言/結尾發散。產生的結果是特定於系統的。
nobuiltin
這代表,在調用點被調用函數不被識別爲一個內建函數。 LLVM將保留原來的調用,而不是使用基於內建函數語義等價的代碼替換它,除非調用點使用了  builtin 的屬性。這個屬性對於調用點和函數的聲明和定義都是有效的。、
noduplicate

該屬性代表,函數的調用不能被複制。一個 noduplicate 函數的調用可能被移動到父函數​​,但不能被複制到父函數。

一個包含 noduplicate 函數仍然可能被內聯,條件是該調用沒有被重複內聯。這意味着,該函數具備 internal 連接標識,並只有一個調用點,因此內聯後,原始調用被刪除。

noimplicitfloat
該屬性代表,禁用隱式的浮點指令
noinline
此屬性代表,在任何狀況下,內聯器都不該該內聯該函數。此屬性不能與 alwaysinline 屬性一塊兒使用。
nonlazybind
此屬性代表,抑制函數的延遲綁定符號特性。若是函數在程序啓動時不被調用,那麼程序啓動會耗費額外的啓動時間,但這可能會使函數調用更快。
noredzone
此屬性代表,即便目標平臺指定的ABI一般容許,該屬性指示代碼生成器也不該該使用一個red zone,。
noreturn
此屬性代表,該函數從不正常返回。若是該函數動態返回,這將產生不肯定的運行期行爲,。
nounwind
此屬性代表,該函數從不返回展開的或異常的控制流。若是函數不展開,其運行時的行爲是未定義的。
optnone

此此屬性代表,該函數不能被除了過程間優化 pass 外的任何優化或代碼生成器 pass 優化。這個屬性不能與一塊兒 alwaysinline 屬性使用;這個屬性也與 minsize 屬性和 optsize 屬性不兼容。( minsize 與 optsize 要求優化)

此屬性要求在函數中同時指定該屬性和 noinline 屬性,因此該函數從不內聯到任何調用者。只有具有alwaysinline 屬性的函數才能內聯到這個函數。

optsize
此屬性代表,優化 pass 和代碼生成器 pass 應該保持這個函數的代碼長度較小,不然進行特定的優化,不顯著影響運行期性能的狀況下減小代碼長度。
readnone

對於一個函數,這個屬性代表該函數嚴格基於它的參數計算其結果(或決定展開異常),而不經過解引用任何指針參數或以其餘方式訪問任何調用者可見的可變狀態(如內存,控制寄存器等)。它不經過任何指針參數(包括 byval 參數)寫入和從不改變調用者可見的任何狀態。這意味着它沒法經過調用C + +的異常throw的方法展開異常。

對於一個參數,這個屬性代表,該函數不能解引用指針參數,儘管若是經過其餘指針它能夠讀取或寫入指針參數指向內存(由於調用者可見的是指針的值而不是指針指向的值)。

readonly

對於一個函數,這個屬性代表該函數不經過任何指針參數(包括 byval 參數)或寫其餘方式修改任何調用者函數可見的狀態(如內存,控制寄存器等)。它可能會解引用指針參數和讀取在調用者中設置的狀態。在使用相同的函數集和全局狀態時,一個只讀函數老是返回相同的值(或展開相同的異常)。它沒法經過調用C + +的異常throw的方法展開異常。

上一個參數,這個屬性表示該函數不經過這個指針參數寫的,即便它可能寫入內存的指針指向。

returns_twice
該屬性代表,該函數能夠返回兩次。該C  setjmp 的是這樣一種函數的一個例子。編譯器禁用這些函數的調用者一些優化(如尾調用)。
sanitize_address
該屬性代表,爲函數啓用AddressSanitizer檢查(動態地址安全分析)。
sanitize_memory
該屬性代表,爲函數啓用MemorySanitizer檢查(未初始化內存訪問的動態檢測)
sanitize_thread
該屬性代表,爲函數啓用ThreadSanitizer檢查(動態線程安全性分析)
ssp

該屬性代表,該函數應該發散一個堆棧溢出保護功能。它有一個「canary」形式 —( a random value placed on the stack before the local variables that’s checked upon return from the function to see if it has been overwritten.)。一個啓發式用來肯定一個函數須要的堆棧保護與否。在如下狀況,這個被使用了啓發式將啓用函數保護器:

字符數組比 ssp-buffer-size 大(默認值爲8)。
字符數組的集合比 ssp-buffer-size 大。
調用alloca()的變量長度或常量長度(alloca的參數)大於 ssp-buffer-size 。

被識別爲須要保護的變量將被安排在堆棧,使得對於堆棧保護器它們是連續的。

若是一個函數,它有一個SSP屬性被內聯到一個不具備SSP屬性的函數,而後將獲得的函數將具備一個SSP屬性。

sspreq

該屬性代表,該函數應該發散一個堆棧溢出保護功能。這將覆蓋 ssp 函數屬性。

被識別爲須要保護的變量將被安排在堆棧,使得對於堆棧保護器它們是連續的。具體佈局規則是:

一、大數組和含大數組的結構體(>= sp-buffer-size)是最接近堆棧保護器的。
二、小數組和含小數組的結構體(< sp-buffer-size)是第二接近堆棧保護器的。 

三、採起了它們的地址的變量是第三接近堆棧保護器的

若是一個函數,它有一個 sspreq 屬性被內聯到一個不具備 sspreq 屬性或具備 ssp 或 sspstrong 屬性的函數,那麼獲得的結果函數將具備 sspreq 屬性。

sspstrong

該屬性代表,該函數應該發散一個堆棧溢出保護功能。在肯定函數是否須要的堆棧保護器時,此屬性會使用一個強有力的試探法。強大的啓發式將爲函數啓用保護器:

任何長度和類型的數組
任何長度和類型的數組的集合。
調用了alloca( ) 。
採起了它們的地址的局部變量。

被識別爲須要保護的變量將被安排在堆棧,使得對於堆棧保護器它們是連續的。具體佈局規則是:

一、大數組和含大數組的結構體(>= sp-buffer-size)是最接近堆棧保護器的。 
二、小數組和含小數組的結構體(< sp-buffer-size)是第二接近堆棧保護器的。 

三、採起了它們的地址的變量是第三接近堆棧保護器的

這將覆蓋 ssp 功能屬性。

若是一個函數,它有一個 sspstrong 屬性被內聯到一個不具備 sspstrong 屬性的函數,那麼最後獲得的函數將具備 sspstrong 屬性。

uwtable
該屬性代表,被指定的ABI要求爲這個函數展開表實體,即便咱們能夠代表沒有異常會被這個函數傳遞。。這一般是針對於ELF x86-64 ABI的狀況,可是它能夠爲某些編譯單元被禁用。
相關文章
相關標籤/搜索