LLVM语言参考手册之标识符、类型与常量

参考网站:LLVM语言参考手册

摘要

      LLVM是基于静态单赋值(SSA)的表示形式。之所以为单赋值,每个名字在SSA中仅被赋值一次。它可提供类型安全性,低级操作,灵活性并能清晰地表示“所有”高级语言的功能。它是在LLVM编译策略的所有阶段中使用的通用代码表示形式。
      LLVM代码表示以三种不同的形式来使用:作为内存中的编译器IR作为磁盘上的位代码表示(适用于即时编译器的快速加载)以及作为人类可读的程序集语言表示。这使LLVM可以为有效的编译器转换和分析提供强大的中间表示,同时提供调试和可视化转换的自然方法。LLVM的三种不同形式都是等效的。

1 标识符

两种基本类型:全局和本地。全局标识符(函数、全局变量)用’@‘字符开头;本地标识符(寄存器名称、类型)用’%'字符开头。
此外,还有三种不同的标识符格式:

  1. 命名值以带有前缀的字符串表示。例如%foo,@DivisionByZero, %a.really.long.identifier。实际使用的正则表达式为“ [%@][-a-zA-Z . ] [ − a − z A − Z ._][-a-zA-Z .][azAZ._0-9]*”。在名称中需要其他字符的标识符可以用引号引起来。可以使用"\xx"wherexx是十六进制字符的ASCII码对特殊字符进行转义。这样,任何字符都可以用在名称值中,甚至可以用引号引起来。该"\01"前缀可用于全局值以抑制重整。
  2. 未命名的值以带有前缀的无符号数字表示。例如%12,@2,%44。
  3. 常量。

LLVM要求值以前缀开头有两个原因:编译器无需担心带有保留字的名称冲突,并且将来可以扩展保留字的集合而不会带来任何损失。此外,未命名的标识符使编译器可以快速提出一个临时变量,而不必避免符号表冲突。

LLVM中的保留字与其他语言中的保留字非常相似。有一些关键字用于不同的操作码(“,add”,“ bitcast,”ret等),原始类型名称(“,void”,“i32等等”)等。这些保留字不能与变量名冲突,因为它们都不以前缀字符(’%‘或’@’)开头。

2 类型

LLVM类型系统是中间表示形式的最重要特征之一。类型化使许多优化可以直接在中间表示上执行,而不必在转换之前对另一方面进行额外的分析。
https://img-blog.csdnimg.cn/20210308155613550.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyMzA4NzQx,size_16,color_FFFFFF,t_70

2.1 空类型(void type)

不代表任何值且没有大小

2.2 函数类型(function type)

由返回类型和形参类型列表组成。

2.3 first class type

该类型的值是唯一可以通过指令生成的值。

2.3.1 single value types

(1) integer type:为所需的整数类型指定任意位宽度
examples:
i32 表示一个32位整数
i1942652表示一个超过1百万的超级大整数

(2) floating-point types

TypeDescription
half16-bit floating-point value
bfloat16-bit “brain” floating-point value (7-bit significand). Provides the same number of exponent bits as float, so that it matches its dynamic range, but with greatly reduced precision. Used in Intel’s AVX-512 BF16 extensions and Arm’s ARMv8.6-A extensions, among others.
float32-bit floating-point value
double64-bit floating-point value
fp128128-bit floating-point value (113-bit significand)
x86_fp8080-bit floating-point value (X87)
ppc_fp128128-bit floating-point value (two 64-bits)

(3) x86_mmx type:表示保存在x86机器上的MMX寄存器中的值。

x86_mmx

(4) pointer type:用于指定内存位置,指针用于引用内存中的对象

<type>*

examples:
[4 x i32]* 指的是指向4个i32值的数组的指针

(5) 向量类型(vector type)
向量类型是表示元素向量的简单派生类型
Syntax:

< <# elements> x <elementtype> >          ; Fixed-length vector
< vscale x <# elements> x <elementtype> > ; Scalable vector

examples:
<4 x i32>表示4个32位整数值向量
<vscale x 4 x i32>表示4个32位整数值的倍数的向量

2.3.2 label type

表示代码标签
Syntax:

label
2.3.3 token type

若一个值与一条指令相关,但该值的所有用法均无法掩盖该指令,即可使用token type。
Syntax:

token
2.3.4 metadata type

表示嵌入的元数据
Syntax:

metadata
2.3.5 aggregate types

聚合类型是可以包含多个成员类型的派生类型的子集。
(1) array type
数组类型是一个非常简单的派生类型,它在内存中按顺序排列元素。
Syntax:

[<# elements> x <elementtype>]

examples:
[40 x i32]表示40个32位整数值的数组
[3 x [4 x i32]]表示34的32位整数值的数组
[12 x [10 x float]]表示12
10的单精度浮点值数组

(2) structure type
结构类型用于表示内存中数据成员的集合。
Syntax:

%T1 = type { <type list> }     ; Identified normal struct type
%T2 = type <{ <type list> }>   ; Identified packed struct type

若结构是“压缩”结构,这表示结构的对齐是一个字节,并且元素之间没有填充。在非压缩结构中,字段类型之间的填充是按照模块中DataLayout字符串的定义插入的。
examples:
{ i32, i32, i32 }表示3个32位整数值的3倍。
<{ i8, i32 }>表示大小为5字节的压缩结构。

(3) opaque structure type
不透明结构类型用于表示没有指定主体的命名结构类型。
Syntax:

%X = type opaque
%52 = type opaque

3 常量

3.1 简单常量(Simple Constants)
  • Boolean constants:true/false
  • Integer constants:如4
  • Floating-point constants:如3.4
  • Null pointer constants:如null
  • Token constants:如none
3.2 Complex Constants
  • Structure constants:类似于结构类型定义的符号表示,如{i32 4,float 3.8}
  • Array constants:类似于数组类型定义的符号表示,如[i32 5,i32 7]
  • Vector constants:类似于向量类型定义的符号表示,如< i32 42, i32 11, i32 74, i32 100 >
  • Zero initialization:将任何类型的值初始化为零,包括标量和聚合类型
  • Metadata node:没有任何类型的常量元组
3.3 Global Variable and Function Addresses

全局变量和函数的地址总是隐式有效的(链接时间)常量。当使用全局标识符时,这些常量被显式引用,并且总是具有指针类型。

3.4 Undefined Values

字符串“undef”可以在任何需要常量的地方使用,并指示值的用户可能接收到未指定的位模式。Undefined Values可以是任何类型(除了“label”或“void”)并且可以在允许常量的任何地方使用。

3.4 Poison Value

错误操作的结果。

3.5 Well-Defined Values

某个值没有未定义位也没有有毒位,则该值定义良好。若聚合数据或向量的元整定义良好则其也定义良好。

3.6 Addresses of Basic Blocks

“blockaddress”常量计算指定函数中指定基本块的地址,并且始终具有i8*类型。

3.7 DSO Local Equivalent

“dso_local_equivalent”常量表示一个函数,该函数在功能上等价于给定的函数,但总是在当前链接单元中被定义。

3.8 Constant Expressions

常量表达式可将涉及其他常量的表达式用作常量。常量表达式可以是任何first class类型,并且可以涉及任何没有副作用的LLVM操作(例如,不支持load和call)。
一些常量表达式的语法:

  • trunc (CST to TYPE)
  • zext (CST to TYPE)
  • sext (CST to TYPE)
  • fptrunc (CST to TYPE)
  • fpext (CST to TYPE)
  • fptoui (CST to TYPE)
  • fptosi (CST to TYPE)
  • uitofp (CST to TYPE)
  • sitofp (CST to TYPE)
  • ptrtoint (CST to TYPE)
  • inttoptr (CST to TYPE)
  • bitcast (CST to TYPE)
  • addrspacecast (CST to TYPE)
  • getelementptr (TY, CSTPTR, IDX0, IDX1, …), getelementptr inbounds (TY, CSTPTR, IDX0, IDX1, …)
  • select (COND, VAL1, VAL2)
  • icmp COND (VAL1, VAL2)
  • fcmp COND (VAL1, VAL2)
  • extractelement (VAL, IDX)
  • insertelement (VAL, ELT, IDX)
  • shufflevector (VEC1, VEC2, IDXMASK)
  • extractvalue (VAL, IDX0, IDX1, …)
  • insertvalue (VAL, ELT, IDX0, IDX1, …)
  • OPCODE (LHS, RHS)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值