LLVM IR 语法简介(一)

本文介绍了LLVM IR的基本概念,包括其标识符的命名规则、模块结构及链接类型的详细解析,并通过一个Hello World示例展示了如何使用LLVM IR。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 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]* @.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的时候使用的。




05-13
### 关于 LLVM IR 的教程和文档 LLVM 提供了丰富的官方文档来帮助开发者理解和使用其内部机制,其中包括关于 LLVM 中间表示(IR)的部分。这些资源不仅涵盖了基础概念,还提供了深入的技术细节[^1]。 #### 官方文档 LLVM 官网提供了套完整的文档集合,其中包含了针对 LLVM IR 的详细介绍。可以通过访问官网的 “Documentation” 部分找到相关内容。具体来说,“LangRef” 是份非常重要的参考资料,它详尽描述了 LLVM IR语法结构及其语义[^1]。 #### 教程实例 除了理论性的文档外,《Kaleidoscope》系列教程是个非常好的实践指南。该教程逐步引导读者实现个名为“万花筒”的简单编程语言编译器,在此过程中展示了如何生成有效的 LLVM IR 并对其进行优化处理[^2]。此外还有中文翻译版本可供参考学习[^3]。 以下是创建基本加法操作并将其转换成 LLVM IR 的 Python 示例代码: ```python import llvmlite.ir as llvm_ir # Define the module and function types. module = llvm_ir.Module() func_type = llvm_ir.FunctionType(llvm_ir.IntType(32), [llvm_ir.IntType(32), llvm_ir.IntType(32)]) # Create a function named 'add'. function = llvm_ir.Function(module, func_type, name="add") # Add arguments with names for readability. a, b = function.args a.name = "a" b.name = "b" # Build the body of the add function using an IRBuilder instance. block = function.append_basic_block(name="entry") builder = llvm_ir.IRBuilder(block) result = builder.add(a, b, name="sum") # Perform addition operation. # Return result from this block. builder.ret(result) print(str(module)) # Print generated LLVM IR code. ``` 这段脚本利用 `llvmlite` 库定义了个接受两个整数参数返回它们之和的功能函数,并打印出了对应的 LLVM IR 表达形式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值