LLVM IR 语法简介(一)

来源:互联网 发布:ftp上传工具 for mac 编辑:程序博客网 时间:2024/05/18 20:49

LLVM IR 被设计为一种轻量级,底层的语言用来描述各种上层的语言,对于不同的语言,都可以归纳为同一种IR的格式。


标示符:

LLVM的标识符分为全局标识符和局部标识符。 全局标识符以'@'开头,局部标识符以'%'为开头。

1. 命名过的数值会被标识为一个带有前缀的字符串,类似于%foo, @DivisionByZoo.具体的语法是:

[%@][a-zA-Z$._][a-zA-z$._0-9]*
   特殊字符可以使用反斜杠'\xx'的形式标示。

2. 未命名过的数值(临时变量之类)采用数字加前缀的方式,类似于%12,@2

3. 临时变量的数字是逐个递增的

4. 注释以';'为开头,直到该行结束


模块结构:

LLVM的程序是有模块组合而成的。每个模块包含函数,全局变量和符号表入口。模块也有可能被LLVM链接器绑定在一起。

; 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 functiondeclare i32 @puts(i8* nocapture) nounwind; Definition of main functiondefine i32 @main() {   ; i32()*  ; Convert [13 x i8]* to i8  *...  %cast210 = getelementptr [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!1 = metadata !{i32 42}!foo = !{!1, null}
这是官方文档上hello world的示例

这个例子中,有一个全局变量.str,一个脘部函数puts,一个函数定义main,和一个命名的元数据foo。

一般来讲,模块是由一些列的全局数据组成的(包括函数和数值),LLVM使用一个指向内存地址的指针来标识。


链接类型:

所有的全局数据都需要声明一种链接方式。下面是几种常见的链接类型:

private: 只可在当前模块内被访问。由于是模块的私有变量,不会出现在符号表中。

internal:于private类似,表示C中的'static'

available_externally: 可以被用来实现内联和优化,以便被模块之外调用。 只能用于定义,不能用于声明。

linkonce: 当做链接操作时,定义为linkonce的数据会和其他模块中定义为linkonce的数据合并,可以被用作内联函数,模板或其他需要RTTI的地方。如果一个被定义为  linkonce的数据从没被引用过,那么它是被允许被丢弃的。

weak:与linkonce类似,但是如果数据为被引用过,也不会被丢弃。

common:与weak类似,用于C中的临时变量。

external: 如果没有显式的定义任何一种链接类型,就采用external为默认类型。这种类型表明它是模块外部可见和使用的。

dllimport/dllexport:  制作dll的时候使用的。




原创粉丝点击