LLVM学习笔记②

高级结构:
1、模块结构
LLVM程序由模块(Module)组成,每个模块都是源程序的翻译单元,每个模块由函数、全局变量、和符号表项组成。模块可以与LLVM连接器组合在一起,LLVM连接器合并函数(和全局变量)定义,解析前置声明,并合并符号表项。下面是" hello world "模块的一个例子:

; Declare the string constant as a global constant.
@.str = private unnamed_addr constant [13 x i8] c"hello world\0A\00"

; External declaration of the puts function
declare i32 @puts(i8* nocapture) nounwind

; Definition of main function
define i32 @main() {   ; i32()*
  ; Convert [13 x i8]* to i8*...
  %cast210 = getelementptr [13 x i8], [13 x i8]* @.str, i64 0, i64 0

  ; Call puts function to write out the string to stdout.
  call i32 @puts(i8* %cast210)
  ret i32 0
}

; Named metadata
!0 = !{i32 42, null, !"string"}
!foo = !{!0}

以上例子由全局变量.str,外部函数声明putsmain函数定义,一个命名值foo组成。
通常,模块由一系列全局值组成(其中函数和全局变量都是全局值)。全局值由指向内存位置的指针(在本例中是指向char数组的指针,以及指向函数的指针)表示,并具有以下链接类型之一。
连接类型:
在LLVM程序中,所有全局变量和函数都具有以下类型的链接之一:
1、private
具有" private “链接的全局值只能被当前模块中的对象直接访问。特别的,将代码链接到具有private全局值的模块中可能会导致必须重命名private全局值以避免冲突。又因为该符号是模块私有的,所以需要更新所有引用。这不会出现在object file的任何符号表中。
2、internal
类似于private,但该值在object file中显示为本地符号(ELF中为STB_LOCAL)。这对应于C语言中’ static '关键字的概念。
3、available—externally
具有” available_external “链接的全局变量永远不会被存入LLVM模块对应的object file中。从链接器的角度来看,available_external global等同于外部声明。它们的存在是为了允许内联和其他优化在已知全局定义(已知在模块外部)的情况下进行。具有available_external链接的全局变量可以随意丢弃,并允许内联和其他优化。此链接类型只允许在定义中使用,而不允许在声明中使用。
4、linkonce
具有” linkonce "链接的全局变量在链接发生时将与其他同名的全局变量合并。
这可以用来实现某些形式的内联函数、模板或其他代码,这些代码必须在使用它的每个翻译单元中生成,但稍后可能会用更明确的定义覆盖其主体。允许丢弃未引用的linkonce全局变量。请注意,一次链接实际上不允许优化器将函数体内联到调用者中,因为它不知道函数的这个定义是程序中的最终定义,还是会被更强的定义覆盖。要启用内联和其他优化,请使用“linkonce_odr”链接。
5、weak
“weak”链接与“一次链接”链接具有相同的合并语义,只是带有弱链接的未引用全局变量不能被丢弃。这用于C源代码中声明为“weak”的全局变量。
6、common
“common” 链接标识与“weak”链接标识很相似,但“common”链接标识被使用于C中的tentative definition,例如 int X;在全局作用域。带有“common”链接标识的符号以一种与weak symbols相同的方式被合并,但这些符号即使未被引用也不会被删除。 common 符号可能不会有一个明确的section,必须被0值初始化(根据ELF链接规则,0值初始化的符号只通过“.bss section”提供长度占位,但不在文件中占有位置),且不可能被标志为constant。Functions和aliases 不可以带有“common” 链接标识。(因为Functions和aliases不可能被tentative definition)。
7、appending
“appending”链接标识只能用于数组类型的指针全局变量。但两个带有“appending”链接标识的全局变量被链接到一起,这两个全局数组追加合并到一起。 LLVM是类型安全的,相当于当链接.o文件时,让系统链接器将名称相同的“section”附加在一起。
不幸的是,这与.o文件中的任何特性都不匹配,因此它只能用于llvm.global_ctors llvm特别解释的变量。
8、extern_weak
这个链接的语义遵循ELF对象文件模型: extern_weak符号在链接之前是weak的,如果没有链接,符号将变成空,而不是一个未定义的引用。
9、linkonce_odr,weak_odr
有些语言允许合并不同的全局变量,比如两个具有不同语义的函数。
其他语言,如c++,确保只合并等价的全局变量(“one definition rule”-“ODR”)。
这类语言可以使用linkonce_odr和weak_odr链接类型来表示全局变量只会与等价的全局变量合并。这些链接类型在其他方面与它们的非odr版本相同。
10、external
如果没有使用上述标识符,则全局是外部可见的,这意味着它参与链接并可用于解析外部符号引用。

全局变量或函数声明具有external或extern_weak以外的任何链接类型都是非法的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值