参考资料:https://zhuanlan.zhihu.com/p/450602843
一、安装并测试
默认安装:sudo apt-get install clang llvm
查看安装:clang --version && llvm-config --version
查看位置:whereis clang && whereis llvm-config
自定义安装:数字17为安装的版本【安装参考】
下载安装:wget https://apt.llvm.org/llvm.sh && chmod +x llvm.sh && sudo ./llvm.sh 17
查看安装:clang-17 --version && llvm-config-17 --version
查看位置:whereis clang-17 && whereis llvm-config-17
软链接:sudo cd /usr/bin && ln -s clang-17 clang && ln -s clang++17 clang++ && ln -s llvm-config-17 llvm-config
常用命令
-
clang/clang++
clang hello.c -o a.out
clang -emit-llvm -S hello.c -o hello.ll
clang++ hello.cpp -o a.out
clang++ -emit-llvm -S hello.cpp -o hello.ll
-
llvm-as/llvm-dis
llvm-as hello.ll -o hello.bc
llvm-dis hello.bc -o hello.ll
-
llc/lli
llc hello.ll -o hello.s
lli hello.ll
-
可以设置软链接来使用(可选)
ln -s clang-17 clang
ln -s clang++17 clang++
ln -s llvm-config-17 llvm-config
二、执行测试样例
hello.c
#include <stdio.h>
int main()
{
int c = 1 + 2;
printf("hello word! calculate(1+2)=%d", c);
return 0;
}
clang -emit-llvm -S hello.c -o hello.ll
user@user:~/test01$ cat hello.ll
; ModuleID = 'hello.c'
source_filename = "hello.c"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-gnu"
@.str = private unnamed_addr constant [30 x i8] c"hello word! calculate(1+2)=%d\00", align 1
; Function Attrs: noinline nounwind optnone uwtable
define dso_local i32 @main() #0 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
store i32 0, i32* %1, align 4
store i32 3, i32* %2, align 4
%3 = load i32, i32* %2, align 4
%4 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([30 x i8], [30 x i8]* @.str, i64 0, i64 0), i32 %3)
ret i32 0
}
declare dso_local i32 @printf(i8*, ...) #1
attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
!llvm.module.flags = !{!0}
!llvm.ident = !{!1}
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{!"clang version 10.0.0-4ubuntu1 "}
llc hello.ll -o hello.s
wangsp@wangsp:~/test01$ cat hello.s
.text
.file "hello.c"
.globl main # -- Begin function main
.p2align 4, 0x90
.type main,@function
main: # @main
.cfi_startproc
# %bb.0:
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
subq $16, %rsp
movl $0, -8(%rbp)
movl $3, -4(%rbp)
movl -4(%rbp), %esi
movabsq $.L.str, %rdi
movb $0, %al
callq printf
xorl %eax, %eax
addq $16, %rsp
popq %rbp
.cfi_def_cfa %rsp, 8
retq
.Lfunc_end0:
.size main, .Lfunc_end0-main
.cfi_endproc
# -- End function
.type .L.str,@object # @.str
.section .rodata.str1.1,"aMS",@progbits,1
.L.str:
.asciz "hello word! calculate(1+2)=%d"
.size .L.str, 30
.ident "clang version 10.0.0-4ubuntu1 "
.section ".note.GNU-stack","",@progbits
三、第一个Module
创建Module需要用到 LLVMContext 和 Module 这两个类。
引入头文件和命名空间并创建LLVMContext和Module
#include <cstdio>
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
using namespace llvm;
static std::unique_ptr<LLVMContext> TheContext;
static std::unique_ptr<Module> TheModule;
static void InitializeModule() {
TheContext = std::make_unique<LLVMContext>();
TheModule = std::make_unique<Module>("first modlue", *TheContext);
}
int main(int argc, char* argv[]) {
InitializeModule();
TheModule->print(errs(), nullptr);
return 0;
}
clang++ module.cpp `llvm-config --cxxflags --ldflags --system-libs --libs core` -fno-rtti -o toy.out
./toy.out
; ModuleID = 'first modlue'
source_filename = "first modlue"