LLVM快速入门上手指南

LLVM快速入门上手指南

范吉民

1. 基本概念

LLVM提供了一套相对来说比较简单的方法用以定制编译器的方法。对于想要快速入门的用户来说,可以将LLVM理解成为一个编译框架,只要按照这个框架规定的方式添加自己的内容,就可以实现定制编译器的效果。

LLVM框架使用了三段式的结构,编译驱动器+优化器+后端链接。大概是将源文件翻译成为一个与具体的体系结构无关的中间文件,然后再对中间文件做优化,最后将优化后的中间文件翻译成具体的处理器的指令。

在这里插入图片描述

对编译器的定制,最简单最容易的方式是在优化器处下手,因为其输入输出都是与具体语言无关的,同时也与具体的指令集和处理器无关的。

2. LLVM Pass

LLVM框架提供了一种名叫Pass的机制,能够将用户定义的优化功能通过Pass集成到优化器中,成为优化器的一个命令。只要对生成的中间文件调用opt即可达到简单定制化的效果。

3. 环境搭建

作为一个快速上手指南,本文提供最简单的环境搭建方式,熟悉之后可以下载LLVM源码编译搭建。

sudo apt install clang
sudo apt install llvm
# 如果安装失败,可以尝试替换镜像源,换成国内的源

安装结束后,可以使用以下方式验证安装是否成功。
在这里插入图片描述

4. 编写和构建一个Pass

定制化的功能可以编写一个cpp完成Pass功能,然后将这个cpp编译成为一个.so,最后在调用opt命令时,将生成的pass的.so进行注册。这个过程就是一个完整的自定义的优化的实现过程。Pass的demo代码摘抄自LLVM官网

//Hello.cpp
#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"

#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"

using namespace llvm;

namespace {
struct Hello : public FunctionPass {
  static char ID;
  Hello() : FunctionPass(ID) {}

  bool runOnFunction(Function &F) override {
    errs() << "Hello: ";
    errs().write_escaped(F.getName()) << '\n';
    errs() << "Hello world\n";
    return false;
  }
}; // end of struct Hello
}  // end of anonymous namespace

char Hello::ID = 0;
//注册hello命令
static RegisterPass<Hello> X("hello", "Hello World Pass",
                             false /* Only looks at CFG */,
                             false /* Analysis Pass */);

static RegisterStandardPasses Y(
    PassManagerBuilder::EP_EarlyAsPossible,
    [](const PassManagerBuilder &Builder,
       legacy::PassManagerBase &PM) { PM.add(new Hello()); });

下面将这个Pass的CPP文件编译成为.so,这是在完全不侵入或涉及LLVM源码的前提下实现定制的方法。编译方式如下:

clang -Wl,-znodelete -fno-rtti -fPIC -shared Hello.cpp -o mylib/LLVMHello.so `llvm-config --cxxflags --ldflags --libs`

5. 使用自定义的优化命令-hello

随便编写一个c文件,然后对其进行定制化编译

//main.c
#include <stdio.h>
int adder(int a, int b)
{
	return a+b;
}
int main()
{
	printf("1st LLVM opt pass %d\n",adder(1,2));
	return 0;
}
定制化编译流程:
  1. 使用clang -emit-llvm 将源文件翻译成llvm中间(IR)文件.bc
  2. 使用opt -load 将定制化pass的.so进行加载注册,然后使用定制化的命令即可
  3. 将中间文件.bc转换成为可执行文件(.o)
  4. 将.o链接成为可执行文件
#step 1
clang -emit-llvm -c main.c -o main.bc
#step 2
opt -load mylib/LLVMHello.so -hello main.bc -o main.2.bc -enable-new-pm=0
#step 3
llc main.2.bc -filetype=obj -o main.o
#step 4
clang -o main main.o

在这里插入图片描述

  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值