LLVM系列第二章:模块Module

系列文章目录

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系列第二十七章:理解IRBuilder
LLVM系列第二十八章:写一个JIT Hello World
LLVM系列第二十九章:写一个简单的常量加法“消除”工具(Pass)

flex&bison系列



前言

在此记录下用LLVM生成模块(Module)的过程,以备查阅。

开发环境的配置请参考第一章 《LLVM系列第一章:编译LLVM源码》。

简单来说,LLVM中的模块(Module),代表了一块代码。它是一个比较完整独立的代码块,是一个最小的编译单元。需要注意的是,它跟我们平常说的“程序模块”不一样。程序模块是一个更大的集合,包含了很多个编译单元;而LLVM中的模块(Module),我们可以把它初步理解为一个编译单元。

在LLVM IR的基本概念(构件)中,模块是一个组合,它包含了其它更小的基本构件。比如,它可以包含的基本构件有全局变量、函数、数据结构等。

在这一章,我们就用LLVM的API来创建一个最简单的模块。

一、Hello Module

用LLVM创建模块之前,需要首先初始化LLVMContext,然后才能调用LLVM API,代码如下(示例):

// 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;
}

二、编译

用clang++进行编译(示例):

# Set up C++ standard library and header path
export SDKROOT=$(xcrun --sdk macosx --show-sdk-path)

# Compile
clang++ -w -o HelloModule `llvm-config --cxxflags --ldflags --system-libs --libs core` HelloModule.cpp

以上命令会生成一个名为HelloModule的可执行程序。

三、运行

运行HelloModule(示例):

./HelloModule

输出结果如下(示例):

; ModuleID = 'HelloModule'
source_filename = "HelloModule"

四、总结

我们用LLVM提供的C++ API,创建了一个最简单的模块(Module),并打印出了它的IR代码。完整源码示例请参看:
https://github.com/wuzhanglin/llvm-IR-examples

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
可以参考下面的代码示例: ```c++ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IR/Function.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DIBuilder.h" using namespace llvm; namespace { class MyPass : public FunctionPass { public: static char ID; MyPass() : FunctionPass(ID) {} bool runOnFunction(Function &F) override { LLVMContext &Ctx = F.getContext(); Module *M = F.getParent(); // Get the DebugInfoFinder from the module DebugInfoFinder &DIFinder = M->getDebugInfoFinder(); // Get the debug location of the first instruction in the function Instruction *FirstInst = &*F.getEntryBlock().begin(); DebugLoc DL = FirstInst->getDebugLoc(); if (!DL) { // No debug location available return false; } // Get the file name from the debug location StringRef FileName = DL->getFilename(); // Create the new function Type *RetTy = Type::getVoidTy(Ctx); Type *ArgTy = Type::getInt8PtrTy(Ctx); FunctionType *FuncTy = FunctionType::get(RetTy, ArgTy, false); Function *NewFunc = Function::Create(FuncTy, GlobalValue::ExternalLinkage, "myfunc", M); // Create the entry basic block of the new function BasicBlock *BB = BasicBlock::Create(Ctx, "entry", NewFunc); // Insert a return instruction at the end of the basic block IRBuilder<> Builder(BB); Builder.CreateRetVoid(); // Set the debug location for the return instruction DIBuilder DIB(*M); DILocation *DIL = DIB.createFile(FileName, "."); Builder.SetCurrentDebugLocation(DIL->getLine(), 0, DIL); // Return true to indicate that the function was modified return true; } }; char MyPass::ID = 0; static RegisterPass<MyPass> X("mypass", "My custom pass", false, false); } // end anonymous namespace ``` 这个pass会遍历函数中的所有基本块,并在每个基本块的开头插入一个新函数。新函数的参数类型是`i8*`,返回类型是`void`。新函数不做任何操作,只是简单地返回。在创建新函数之后,我们使用`DIBuilder`类创建了一个新的调试位置,然后将该位置与新函数的返回指令相关联。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值