当前位置:网站首页>LLVM系列第二十六章:理解LLVMContext
LLVM系列第二十六章:理解LLVMContext
2022-08-02 14:07:00 【飞翼剑仆】
系列文章目录
LLVM系列第一章:编译LLVM源码
LLVM系列第二章:模块Module
LLVM系列第三章:函数Function
LLVM系列第四章:逻辑代码块Block
LLVM系列第五章:全局变量Global Variable
LLVM系列第六章:函数返回值Return
LLVM系列第七章:函数参数Function Arguments
LLVM系列第八章:算术运算语句Arithmetic Statement
LLVM系列第九章:控制流语句if-else
LLVM系列第十章:控制流语句if-else-phi
LLVM系列第十一章:写一个Hello World
LLVM系列第十二章:写一个简单的词法分析器Lexer
LLVM系列第十三章:写一个简单的语法分析器Parser
LLVM系列第十四章:写一个简单的语义分析器Semantic Analyzer
LLVM系列第十五章:写一个简单的中间代码生成器IR Generator
LLVM系列第十六章:写一个简单的编译器
LLVM系列第十七章:for循环
LLVM系列第十八章:写一个简单的IR处理流程Pass
LLVM系列第十九章:写一个简单的Module Pass
LLVM系列第二十章:写一个简单的Function Pass
LLVM系列第二十一章:写一个简单的Loop Pass
LLVM系列第二十二章:写一个简单的编译时函数调用统计器(Pass)
LLVM系列第二十三章:写一个简单的运行时函数调用统计器(Pass)
LLVM系列第二十四章:用Xcode编译调试LLVM源码
LLVM系列第二十五章:简单统计一下LLVM源码行数
LLVM系列第二十六章:理解LLVMContext
前言
在此,记录下对LLVM源码中LLVMContext这个类的理解,以备查阅。
How
不知您注意到没有,当我们调用LLVM提供的C++ API来生成IR代码时,第一行C++代码就是初始化LLVMContext。如下面这个简单的例子,它创建了一个模块(Module):
// HelloModule.cpp
#include "llvm/IR/Module.h"
#include "llvm/IR/LLVMContext.h"
using namespace llvm;
int main(int argc, char* argv[])
{
LLVMContext context;
Module* module = new Module("HelloModule", context);
module->print(outs(), nullptr);
return 0;
}
main函数的第一行就是初始化context的代码:
LLVMContext context;
注意到,当我们创建一个模块(Module)时,context是其中一个输入参数:
Module* module = new Module("HelloModule", context);
另外,我们还可以利用context创建Type(示例):
IntegerType* int32Type = Type::getInt32Ty(context);
Why
在LLVM API中,context是一个很重要的类,它能让我们在多线程中使用LLVM API。我们可以把它理解为一个黑盒,它包含(并管理)了LLVM中基础的、核心的“全局”数据,如类型(Type)、标准化的常量表等。
这里用到了“黑盒”这个词,是为了表明,API的调用者无需过多地深究context是什么。比如,我们无需深究它是如何实现的,包含了什么数据,作用是什么等各种问题。我们可以简单地把它当做一个“代表”,它代表了LLVM这个“引擎库”。我们只需记住,当一个函数需要context的时候,我们就把它传进去即可。
What
通常来说,LLVM的用户也许不需要知道context是什么,但编程语言的开发者(即编译器的开发者)是需要清楚地知道context是什么的。
Context包含了LLVM在一个线程中正常运行(比如一个编译任务)所需要的数据(即LLVM程序状态数据)。在很久以前,也就是LLVM的老版本中,这些状态数据都是全局数据。后来,它们被一股脑儿打包到了一个名叫“LLVMContext”的对象中,这样,LLVM就能支持在多线程中运行编译任务了。
多线程共享context
虽然context可以在多线程中共享使用,但它不是线程安全的,因为它自己不提供数据同步(如加锁)机制。Context本身以及它所包含的数据都是设计成给一个单独的线程使用的。所以,在多线程中共享使用context,可能会导致竞争、数据不同步等多线程常见问题。
线程独有context
当然,如果每个线程都创建一份自己独有的context,则不会有这些问题了。当每一个线程都有自己独立的一份context时,那命名冲突、类型冲突等问题就不再存在了。比如,某个线程正在处理模块A中的类型“Foo”,而另一个线程正在处理模块B中的类型“Foo”。那这两个类型不会互相干扰,因为它们处于不同的context下。
再举个例子,有这样一个多线程的程序,其中一个线程运行图像处理库(Graphics Library),另一个线程运行音频处理库(Audio Library),而这两个库都调用了LLVM。既然它们都调用了LLVM,为了避免这两个处理任务相互干扰,我们只需让它们各自创建一份context即可。所有在当前context之下创建出来的模块(Module)、类型(Type)、常量(Constant)等数据都属于当前的context。另外,我们还可以利用LLVM提供的工具Verifier(这是一个C++类)进行检查,它能确保一个模块下所有的IR对象都属于同一个模块。
Context融合
一般情况下,每一个线程都应该创建一份自己独有的context,以确保数据安全。但如果要合并两个线程的数据,我们不能直接融合两份context对象为一份context。我们可以做的是,把两份context对象转为IR代码,然后合并IR代码。
总结
本章,我们简单地分析了一下LLVM API中的LLVMContext的作用和用法。
边栏推荐
猜你喜欢
随机推荐
spark on yarn
C语言日记 4 变量
【c】小游戏---五子棋之井字棋雏形
基于ThinkPHP6.0 - 宝塔搭建漫画CMS管理系统源码实测
5.使用RecyclerView优雅的实现瀑布流效果
Handler你真的搞懂了吗?
2. Basic use RecyclerView
数据乱码问题—更改mysql字符编码
DataX 的使用
数据的表示方法和转换(二进制、八进制、十进制、十六进制)
原码、反码、补码和移码
vscode compiles the keil project and burns the program
2.RecyclerView基本使用
spark(standalone,yarn)
VS Code无法安装插件之Unable to install because, the extension '' compatible with current version
drf view component
二级指针,数组指针,指针数组和函数指针
宝塔搭建PHP自适应懒人网址导航源码实测
UIWindow的makeKeyAndVisible不调用rootviewController 的viewDidLoad的问题
加减法运算及其溢出处理