LLVM系列第五章:全局变量Global Variable

LLVM系列第五章:全局变量Global Variable,第1张

系列文章目录

LLVM系列第一章:编译LLVM源码
LLVM系列第二章:模块Module
LLVM系列第三章:函数Function
LLVM系列第四章:逻辑代码块Block
LLVM系列第五章:全局变量Global Variable
LLVM系列第十一章:写一个Hello World
LLVM系列第十二章:写一个简单的词法分析器Lexer
LLVM系列第十三章:写一个简单的语法分析器Parser
LLVM系列第十四章:写一个简单的语义分析器Semantic Analyzer
LLVM系列第十五章:写一个简单的中间代码生成器IR Generator
LLVM系列第十六章:写一个简单的编译器


本文目录
  • 系列文章目录
  • 前言
  • 一、Hello Global Variable
  • 二、编译
  • 三、运行
  • 四、总结


前言

在此记录下用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

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1499076.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-25
下一篇 2022-06-25

发表评论

登录后才能评论

评论列表(0条)

保存