当前位置:网站首页>LLVM系列第五章:全局变量Global Variable
LLVM系列第五章:全局变量Global Variable
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创建全局变量(Global Variable)的过程,以备查阅。
开发环境的配置请参考第一章 《LLVM系列第一章:编译LLVM源码》。
全局变量(Global Variable)是在一个模块(Module)之内全局可见的变量,也就是说模块内所有的函数都能用它。
LLVM提供了Module::getOrInsertGlobal()函数来创建全局变量,以及Module::getNamedGlobal()来找到一个全局变量。创建全局变量之后,我们可以配置它的属性,如链接类型、内存对齐模型等。
全局变量在链接的时候,到底是指向同一个全局变量,还是多个不同的全局变量,是由链接类型决定的。这里说的“多个不同的全局变量”,意思是其名称相同,但是有“多个分身”,“分身”之间互不影响。
链接类型 | 用途 |
---|---|
ExternalLinkage | 模块外部可见的函数 |
AvailableExternallyLinkage | 只在查询而非代码生成的时候外部可见 |
LinkOnceAnyLinkage | 函数在链接(或内连inline)的时候仅保存一份实现 |
LinkOnceODRLinkage | 同上,但有些链接属性可以用类似的属性替换 |
WeakAnyLinkage | 函数在链接的时候仅保存一份实现(弱链接) |
WeakODRLinkage | 同上,但有些链接属性可以用类似的属性替换 |
AppendingLinkage | 这是特殊的链接类型,只适用于全局数组 |
InternalLinkage | 链接时若发现有重命的静态函数,则进行重命名 |
PrivateLinkage | 只做内部链接,但不会添加到符号表中 |
ExternalWeakLinkage | 外部弱链接 |
CommonLinkage | 由编译器(链接器)自动选择链接类型 |
更详细的说明,请参考LLVM官方文档:Linkage Types。
在这一章中,我们就用LLVM提供的这些工具来创建一个全局变量。
一、Hello Global Variable
用LLVM创建全局变量代码如下(示例):
// HelloGlobalVariable.cpp
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
using namespace llvm;
int main(int argc, char* argv[])
{
LLVMContext context;
IRBuilder<> builder(context);
// Create a module
Module* module = new Module("HelloModule", context);
// Add a global variable
module->getOrInsertGlobal("helloGlobalVariable", Type::getInt32Ty(context));
GlobalVariable* globalVariable = module->getNamedGlobal("helloGlobalVariable");
globalVariable->setLinkage(GlobalValue::CommonLinkage);
globalVariable->setAlignment(MaybeAlign(4));
// Add a function
Type* voidType = Type::getVoidTy(context);
FunctionType* functionType = FunctionType::get(voidType, false);
Function* function = Function::Create(functionType, GlobalValue::ExternalLinkage, "HelloFunction", module);
// Create a block
BasicBlock* block = BasicBlock::Create(context, "entry", function);
builder.SetInsertPoint(block);
// Print the IR
verifyFunction(*function);
module->print(outs(), nullptr);
return 0;
}
二、编译
用clang++进行编译(示例):
# Set up C++ standard library and header path
export SDKROOT=$(xcrun --sdk macosx --show-sdk-path)
# Compile
clang++ -w -o HelloGlobalVariable `llvm-config --cxxflags --ldflags --system-libs --libs core` HelloGlobalVariable.cpp
以上命令会生成一个名为HelloGlobalVariable的可执行程序。
三、运行
运行HelloGlobalVariable(示例):
./HelloGlobalVariable
输出结果如下(示例):
; ModuleID = 'HelloModule'
source_filename = "HelloModule"
@helloGlobalVariable = common global i32, align 4
define void @HelloFunction() {
entry:
}
四、总结
我们用LLVM提供的C++ API,创建了一个全局变量(Global Variable),并打印出了它的IR代码。完整源码示例请参看:
https://github.com/wuzhanglin/llvm-IR-examples
边栏推荐
猜你喜欢
随机推荐
MySQL知识总结 (十一) MySql 日志,数据备份,数据恢复
不可不知的反汇编相关知识
Redis持久化机制
C语言一级指针(补)
MySQL知识总结 (九) 用户与用户权限管理
getUserProfile接口不显示用户性别和地区
LLVM系列第二十六章:理解LLVMContext
6.如何使用CardView制作卡片布局效果
PHP版本切换:5.x到7.3
Tornado framework routing system introduction and (IOloop.current().start()) start source code analysis
C语言——一级指针初识
无人驾驶综述:摘要
关于Flink
存储系统Cache(知识点+例题)
C语言日记 7 输入/输出格式控制
原码、补码、反码
LLVM系列第十九章:写一个简单的Module Pass
It is not allowed to subscribe with a(n) xxx multiple times.Please create a fresh instance of xxx
关于spark
uniCloud 未能获取当前用户信息:30205 | 当前用户为匿名身份