
In this course you are going to learn about converting high level programming constructs into LLVM IR by using LLVM APIs. This is a practical class about LLVM programming. After learning this class, you will be able to write your own compiler by using LLVM infrastructure.
This course has two prerequisites. Firstly, basic C/C++ programming skills is required. You must be familiar with the follwing knowledge, such as variables, functions, pointers, etc. Secondly, basic compiler principle concepts is recommended. It will be helpull if you know the follwing concepts, such as parser, basic blocks, SSA, etc.
All the source code will be discussed and developed in this course is presented in this github url. Before we dive into llvm programming, let's review the core compoents of compiler architecture.
In general, compiler will translate source files into an executable file in three phases.
On phase one, the compiler frontend reads the soure file and produce ir file.
On phase two, the compiler middleend reads the ir and emit the optimized ir.
On phase three, the compile reads the ir produced by the middleend and produce an executable file.
From this compiler architecture diagram we can see that there are lots of stuff to do to implement a compiler. By using LLVM libraries, things become simplified.
The LLVM Project is a collection of modular and reusable compiler and toolchain technologies. By using LLVM, compiler developer only need to modify their frontend to emit llvm ir. We can reuse llvm middleend and llvm backend. Finally we can get a high quality executable file produced by LLVM tools.
In next section we will setup develop environment to program with LLVM. Thanks for watching.
In this lecture we are goning to setup llvm develop environment.
Firstly you need to install linux operating system on your machine. I use ubuntu 22, other linux distribution will go. Secondly, install clang and clang++ by using command sudo apt-get install clang-14. Lastly, install llvm by using command sudo apt-get install llvm-14.
This slide lists the most important llvm tools we will use in this course. The usage of each tool is well documented in this url.
Let's try these tools. We will going to mkdir llvm-ir-builder to create our project directory. Then cd llvm-ir-builder, mkdir examples and cd examples. Type touch hello.c; vim hello.c.
Let's write the classical hello world code. Let's compile and run the code.Type clang hello.c -o hello.out; ./hello.out . 'hello world!' is printed, nice and simple.
We can use clang with emit-llvm flag to produce llvm assmbly. type clang -emit-llvm hello.c -S -o hello.ll. This is the contents of llvm assmbly. We use lli to run hello.ll.
We can use llvm-as to produce on-disk bitcode representation. llvm-as hello.ll -o hello.bc. We can use lli hello.bc to run the code.
We can use llvm-dis to generate human readable form. llvm-dis hello.bc -o hello.ll.
We can use llc to generate assembly. type llc hello.bc -o hello.s.
We can use gcc to compile hello.s into an executable file. type gcc hello.s -o hello.native; ./hello.native.
Now we are farmiliar with some llvm tools, in next lecture we will create our first module by using llvm apis.
Explore the LLVM type system, map C types to LLVM types, and use a builder to create int, float, array, struct, and pointer types; emit these types with globals.
Explore llvm arithmetic instructions by defining global integers and floats, loading them, and applying add, sub, mul, and div operations.
Explore LVM bitwise instructions and learn to emit bitwise values by building a function, including load global, offsets, and shifts—unsigned left, arithmetic right, and logical right.
Learn how to emit LLVM IR compare instructions, including i32 and u32 comparisons, signed and unsigned, plus floating point comparisons, by building and testing emit functions.
Learn to emit llvm ir for an if-else in a c-like main function by building basic blocks, performing i32 comparisons, and using branches to set and return a result.
Learn how to use the LLVM API to emit a switch statement, building a control flow graph with five blocks, handling case one, case two, and a default.
Learn to implement a while loop in LLVM IR by building condition and body blocks, handling loads and stores of globals, and computing a running sum.
Learn how functions are defined and invoked in LLVM IR, including prototypes for printf and sum, building function bodies and main calls, emitting calls, and returning values.
Master arrays in llvm ir by walking through a swept array example, emitting ir, and handling function prototypes, get element addresses, loads, stores, and calls.
In this course you are going to learn about converting high level programming constructs into LLVM IR by using LLVM APIs. This is a practical class about LLVM programming. After learning this class, you will be able to write your own compiler by using LLVM infrastructure.
This course has two prerequisites. Firstly, basic C/C++ programming skills is required. You must be familiar with the follwing knowledge, such as variables, functions, pointers, etc. Secondly, basic compiler principle concepts is recommended. It will be helpull if you know the follwing concepts, such as parser, basic blocks, SSA, etc.
All the source code will be discussed and developed in this course is presented in this github url. Before we dive into llvm programming, let's review the core compoents of compiler architecture.
In general, compiler will translate source files into an executable file in three phases.
On phase one, the compiler frontend reads the soure file and produce ir file.
On phase two, the compiler middleend reads the ir and emit the optimized ir.
On phase three, the compile reads the ir produced by the middleend and produce an executable file.
From this compiler architecture diagram we can see that there are lots of stuff to do to implement a compiler. By using LLVM libraries, things become simplified.
The LLVM Project is a collection of modular and reusable compiler and toolchain technologies. By using LLVM, compiler developer only need to modify their frontend to emit llvm ir. We can reuse llvm middleend and llvm backend. Finally we can get a high quality executable file produced by LLVM tools.