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

可見性模式(Visibility Styles

全部全局變量和函數具備如下的可見性模式之一:html

default」 - Default style
在那些使用ELF object file格式的平臺( targets),默承認見性意味着聲明對於其餘模塊是可見的,而且在可共享庫,意味着這個聲明的實體是可被覆蓋的。在 Darwin平臺,默承認見性意味着聲明對於其餘模塊是可見的。默承認見性與在這種語言中的 「external linkage」 是一致的。
hidden」 - Hidden style
一個對象的帶有hidden可見性的兩個聲明,若是它們是處於一個相同的可共享單元( shared object),那麼它們會被引用到一個相同的對象。一般來講,hidden可見性代表符號不會被放置到動態符號表,因此其餘模塊(可執行程序 或 共享庫)不能夠直接引用這個符號
protected」 - Protected style
在ELF中,protected 可見性代表符號會被放置到動態符號表,但在特定模塊中的這些引用會綁定到一個本地的符號。因此這個符號不能被其餘模塊重寫。

DLL存儲類別(DLL Storage Classes

全部全局變量,函數,別名(Aliases)能夠擁有下面的DLL存儲類別之一:python

dllimport
dllimport」 會致使編譯器經過一個指向到 被DLL導出的指針 的全局指針,來引用一個函數或變量。在微軟windows平臺,這個指針名的格式爲  __imp_ 接上引用的函數或變量的名稱(__imp_函數名)。
dllexport
dllexport」 會致使編譯器提供一個指向 一個在DLL中的指針 的全局變量,因此它能夠被引用到帶有 dllimport 屬性的實體。在微軟windows平臺,這個指針名的格式爲  __imp_ 接上引用的函數或變量的名稱(__imp_函數名)。爲了使編譯器,彙編器和連接器知道某個符號是被外部引用而且防止這個符號被刪除,所以這個存儲類別爲了定義一個dll接口而存在的。

具名類型(Named Types

LLVM IR容許你爲明確類型標識其名稱的別名。這使得閱讀IR更加得容易且使IR更加緊湊(condensed )(實際上這與遞歸類型有關)。一個名字標識的例子以下:windows

%mytype = type { %mytype*, i32 }

你能夠給定對除了「void」任何類型一個名稱。類型名的別名能夠被使用到任何指望 「%mytype」語法的地方。數組

 

注意,這些類型名是構造類型指明的名稱的別名,所以你能夠對同一個類型標識多個名字。這一般會在dumping out一個 .ll文件的時候致使行爲混亂。因爲LLVM IR使用構造類型,因此這個名稱不是這個類型的一部分。當print out LLVM IR,printer會挑選一個名稱替代來同一類型的全部名稱(the printer will pick one name to render all types of a particular shape. 。。。爲相同形狀着色,囧)。這意味着若是你有最終具備相同LLVM 類型的兩個不一樣的源類型在一段代碼中,那麼dumper會打印the 「wrong」 或 unexpected type。這是一個重要的設計點且將不會被改變。函數

全局變量(Global Variables

全局變量在編譯期定義存儲分配範圍而不是運行期。優化

全局變量定義必須被初始化,被放置在一個顯式的section中,且有一個可選的顯式對齊標識。spa

全局變量在其餘的編譯單元也能夠被聲明,但在這種狀況下它們沒有初始化式(initializer)。線程

一個變量可能被定義爲thread_local,,這意味着這個變量不會被其餘線程所共享(每個線程會擁有這個變量的一份單獨的拷貝)。設計

不是全部平臺都支持thread-local變量。可選地,一個TLS模型能夠標識:指針

localdynamic

標識僅用於當前可共享庫的變量

initialexec

標識在模塊中不會被動態加載的變量

localexec

標識在可執行程序中定義且只在可執行程序中使用的變量

這種模型與ELF TLS模型是一致的;詳見ELF Handling For Thread-Local Storage。若是指定的模型不被支持或者有一個更合適的模型可供選擇,平臺可能會選擇一個不一樣TLS模型。
一個變量可能被定義爲一個全局常量,代表其內容從不會被修改(使其可以更好地被優化,容許這個全局數據被放置到可執行程序的只讀section)。注意,須要在運行期被初始化的變量不能被標識爲 constant,由於初始化時有一個到這個變量的存儲操做。
LLVM容許明確全局變量的聲明被標識爲constant,計時這個全局變量的最終定義不是constant。這種能力可使程序得到些微的優化,但這要求這個語言定義保證基於「constantness」的優化對於不包含這個定義的編譯單元是有效的。
做爲SSA值,全局變量定義爲指針值,其做用域是程序中的全部基本塊。全局變量永遠定義爲一個其content所對應的類型的指針由於他們描述一個存儲範圍,全部這些LLVM中的存儲對象被經過這個指針訪問。
全局變量能夠被  unnamed_addr 標識,代表它的地址是沒有意義的,僅僅是指向其內容。一個常量被這樣標識能夠被合併到其餘擁有相同初始化式的常量。注意,一個地址有意義的常量能夠被合併到一個 unnamed_addr 常量,且合併結果變爲一個地址有意義的常量。
一個全局變量可能被聲明駐留在一個平臺指定的編號地址空間。對於支持編號地址空間的平臺,地址空間會影響優化被怎麼處理及使用什麼指令來訪問變量。默認的地址空間是0。地址空間限定符必須放在其餘任何屬性前。
LLVM容許一個明確的section用於指定全局變量。若是目標平臺支持它,他會發散全局變量到這個指定section。

默認下,全局初始化式經過假設被定義在模塊中的全局變量是在全局初始化式以前他們的初始值是不會被修改的。對於可能從外部被訪問的變量,包括帶有「external」連接標識的全局變量 或者 出如今@llvm.used 或者 dll導出的變量,這種猜測也是正確的。這種猜測會被帶有"externally_initialized"的變量抑制。

一個顯式對齊可能被標識於一個全局變量,這個顯示對齊必定是2的次冪。若是對齊屬性標識不存在,或者對齊屬性被設置爲0,那麼這個全局變量的對齊屬性將會被根據目標平臺需求設置。若是一個顯式的對齊屬性被標識,這個全局變量被迫徹底按照這個對齊屬性對齊。若是這個全局變量有一個被分配到的section,目標平臺和優化器不會容許over-align這個全局變量。在這種狀況下,額外的對齊是顯而易見的:例如,代碼可能猜測全局變量被集中放置到他們的section中並嘗試以數組形式遍歷他們,但對齊填充會打破這個遍歷過程。

全局變量一樣能夠擁有一個DLL存儲類別

語法:

[@<GlobalVarName> =] [Linkage] [Visibility] [DLLStorageClass] [ThreadLocal]
                     [AddrSpace] [unnamed_addr] [ExternallyInitialized]
                     <global | constant> <Type>
                     [, section "name"] [, align <Alignment>]

例如,下面定義了一個存儲在編號地址帶有一個初始化式,section和對齊屬性的全局常量。

@G = addrspace(5) constant float 1.0, section "foo", align 4

下面是一個只聲明全局變量的例子

@G = external global i32

下面是一個定義了thread-local的帶有initialexec TLS模型的全局變量

@G = thread_local(initialexec) global i32 0, align 4
相關文章
相關標籤/搜索