---
title: 编译入门那些事儿（6）：LLVM Metadata System-官方技术文章-鲲鹏社区
description: 本文主要向大家介绍LLVM Metadata System背景、组成、使用场景以及存储。
keywords: LLVM,编译入门那些,事儿,Metadata,System,官方技术文章,鲲鹏社区,背景介绍
url: https://www.hikunpeng.com/developer/techArticles/20230920-7?envFlag=1
section: (其他)
---

# 编译入门那些事儿（6）：LLVM Metadata System-官方技术文章-鲲鹏社区

URL: https://www.hikunpeng.com/developer/techArticles/20230920-7?envFlag=1
描述: 本文主要向大家介绍LLVM Metadata System背景、组成、使用场景以及存储。
关键词: LLVM,编译入门那些,事儿,Metadata,System,官方技术文章,鲲鹏社区,背景介绍

官方技术文章 [了解详情](https://www.hikunpeng.com/zh/developer/techArticles)

编译入门那些事儿（6）：LLVM Metadata System

编译入门那些事儿（6）：LLVM Metadata System

实战经验

发表于 2023/08/30

0

## Metadata 背景介绍

由于 LLVM IR Opcode 的表达能力有限，为了将额外的信息传递给优化器和代码生成器，LLVM 通常有三个解决方法，分别是 Attribute、Metadata 和 Intrinsic。如下图所示，三种方法各有优劣，使用哪种方法取决于需要传递的信息量。

Metadata 根据命名可知，代表元数据，它没有类型，也不是直接表示值，是用于描述 LLVM IR 的元数据格式。可以用来存储关于 LLVM IR 中各种实体（如：函数、变量、指令等）的附加信息，例如调试信息、优化提示、源代码位置等。

## Metadata 组成

所有的 Metadata 都会用一个感叹号 ! 定义。在 LLVM 中 Metadata 的子类有四个：DistinctMDOperandPlaceholder、MDNode、MDString 和 ValueAsMetadata，Metadata 常见的组成可以是如下几种形态：

（1）DistinctMDOperandPlaceholder 是一个占位符，为了解决前置引用问题，在 Operand 创建后可以用 RAUW 函数替换，使用场景较少。

（2）MDNode 是一种复合的类型，可以随意组合各种 Metadata，比如：!{!"BiShengCompiler", i32 666666}。

（3）MDString 可以表示字符串，比如：!"BiShengCompiler"。

（4）ValueAsMetadata 是可以将 Value 类转化成 Metadata，通常会把 constant 类转为 Metadata，比如：i32 666666。

## Metadata 使用场景

上一节我们知道了 Metadata 的组成元素，本节主要讲如何应用到 IR 中。

（1）作为函数的参数，比如：

```
call void @llvm.dbg.value(metadata !24, metadata !25, metadata !26)
```

（2）作为指令参数，比如：

```
%indvar.next = add i64 %indvar, 1, !dbg !21
```

（3）作为函数或者变量的参数，比如：

```
declare !dbg !22 void @f1()
define void @f2() !dbg !22 {
  ret void
}
@g1 = global i32 0, !dbg !22
@g2 = external global i32, !dbg !22
```

（4）Named Metadata，它是 Metadata 的集合，可以在 Module 的符号表中查找，比如：

```
!foo = !{!4, !3}
```

## Metadata 存储

Metadata 在 IR 中存储的时候可能会有关键字限定，比如如下两个写法就会有很大的差异：

```
!0 = !{ !"test\00", i32 10}
```

```
!0 = distinct !{!"test\00", i32 10}
```

Metadata 的存储可分为如下三种模式：

（1）uniqued：顾名思义，表示 Metadata 唯一，在 Metadata 中不会显式打印，如果和其它的 Metadata 相同，会被合并。例如：已经有 !0 = !{ !"test\00", i32 10}，需要再生成一个类似于 !1 = !{ !"test\00", i32 10} 的 Metadata 时，不会直接生成 !1，而是把使用 !1 的地方改成使用 !0。

（2）distinct：与 uniqued 相反，表示不唯一，不能和其他相同的合并，即上例中会生成新的 !1。

（3）temporary：表示临时存在，为了解决前置引用的问题，比如构建如下的 Metadata：

## Metadata 总结与应用

LLVM Metadata 是 LLVM IR 中非常重要的一部分，它提供了丰富的信息，帮助开发人员更好地理解和优化 LLVM IR，因此 LLVM Metadata 在编译器中被广泛使用，特别是在调试和优化方面。常见的场景有：

（1）调试：可以保存源代码位置、变量名、类型等信息，用于调试器或其他工具的调试。

（2）优化：可以保存代码结构、数据流等信息，用于优化器的优化。

（3）其他：可以保存任何与 LLVM IR 相关的信息，例如源代码注释、版本信息等。

## 参考

1.https://llvm.org/docs/LangRef.html#range-metadata [了解详情](https://llvm.org/docs/LangRef.html#range-metadata)

本页内容
