LLVM Pass and SSA
LLVM Pass and SSA
2
Where to Focus ?
3
Where to Focus ?
4
Where to Focus ?
5
Where to Focus ?
6
OPT is your friend: What does it do ?
7
Types of Passes
How many types of passes are there ?
8
Types of Passes
How many types of passes are there ?
● Loop Pass
● Function Pass
● Module Pass
● Call Graph SCC Pass
● Region Pass
● Machine Pass
9
Types of Passes
How many types of passes are there ?
● Loop Pass
● Function Pass
● Module Pass
● Call Graph SCC Pass
● Region Pass
● Machine Pass
Note: It gives the system more information about what your pass does, and how it can be
combined with other passes
10
How to write an LLVM pass
11
Classwork Question:
Q. Count the number of loops in a LLVM IR file and count the number of basic blocks each loop has.
12
Classwork Question:
Q. Count the number of loops in a LLVM IR file and count the number of basic blocks each loop has.
13
Let’s start with Hello World
step 1: You need to create your own LLVM pass library inside llvm/lib/Transforms. Let’s assume you have created a
folder named “Hello”.
step 2: Create a CMakeLists.txt file inside that folder. Copy the following in the CMakeLists.txt file.
PLUGIN_TOOL
opt
)
14
Let’s start with Hello World
step 1: You need to create your own LLVM pass library inside llvm/lib/Transforms. Let’s assume you have created a
folder named “Hello”.
step 2: Create a CMakeLists.txt file inside that folder. Copy the following in the CMakeLists.txt file.
PLUGIN_TOOL
opt CMake function used in LLVM
)
projects to define and build a
library.
15
Let’s start with Hello World
step 1: You need to create your own LLVM pass library inside llvm/lib/Transforms. Let’s assume you have created a
folder named “Hello”.
step 2: Create a CMakeLists.txt file inside that folder. Copy the following in the CMakeLists.txt file.
PLUGIN_TOOL
opt
)
This is the name given to
the library being created
16
Let’s start with Hello World
step 1: You need to create your own LLVM pass library inside llvm/lib/Transforms. Let’s assume you have created a
folder named “Hello”.
step 2: Create a CMakeLists.txt file inside that folder. Copy the following in the CMakeLists.txt file.
PLUGIN_TOOL
opt It implies that the resulting
)
library will be a loadable
module (shared object) that
can be used with LLVM
tools
17
Quick Question
18
Let’s start with Hello World
step 1: You need to create your own LLVM pass library inside llvm/lib/Transforms. Let’s assume you have created a
folder named “Hello”.
step 2: Create a CMakeLists.txt file inside that folder. Copy the following in the CMakeLists.txt file.
PLUGIN_TOOL
opt
) This specifies the source file
(Hello.cpp) that is used to
build the LLVMHello library.
19
Let’s start with Hello World
step 1: You need to create your own LLVM pass library inside llvm/lib/Transforms. Let’s assume you have created a
folder named “Hello”.
step 2: Create a CMakeLists.txt file inside that folder. Copy the following in the CMakeLists.txt file.
PLUGIN_TOOL
opt
) This specifies that the library
is intended to be used as a
plugin for the LLVM opt tool.
20
Let’s start with Hello World
step 3: add the following line into lib/Transforms/CMakeLists.txt: This command is used to add
add_subdirectory(Hello) another directory (in this case,
"Hello") to the build process.
21
Basic Code Required: Remember Hello.cpp ?
#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/LegacyPassManager.h"
namespace {
struct Hello : public FunctionPass {
static char ID;
Hello() : FunctionPass(ID) {}
char Hello::ID = 0;
static RegisterPass<Hello> X("hello", "Hello World Pass",
false /* Only looks at CFG */,
false /* Analysis Pass */);
22
Basic Code Required: Remember Hello.cpp ?
#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h" Why anonymous namespace
#include "llvm/IR/LegacyPassManager.h" is needed ?
using namespace llvm;
namespace {
struct Hello : public FunctionPass {
static char ID;
Hello() : FunctionPass(ID) {}
char Hello::ID = 0;
static RegisterPass<Hello> X("hello", "Hello World Pass",
false /* Only looks at CFG */,
false /* Analysis Pass */);
23
Basic Code Required: Remember Hello.cpp ?
#include "llvm/Pass.h" Anon. namespace gives an
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
abstraction such that every
function defined within it has
#include "llvm/IR/LegacyPassManager.h"
accessibility and visibility
using namespace llvm; within itself.
namespace {
struct Hello : public FunctionPass {
static char ID;
Hello() : FunctionPass(ID) {}
char Hello::ID = 0;
static RegisterPass<Hello> X("hello", "Hello World Pass",
false /* Only looks at CFG */,
false /* Analysis Pass */);
24
Basic Code Required: Remember Hello.cpp ?
#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
The Hello Pass can get a
unique identifier from the
#include "llvm/IR/LegacyPassManager.h"
Function Pass
using namespace llvm;
namespace {
struct Hello : public FunctionPass {
static char ID;
Hello() : FunctionPass(ID) {}
char Hello::ID = 0;
static RegisterPass<Hello> X("hello", "Hello World Pass",
false /* Only looks at CFG */,
false /* Analysis Pass */);
25
Basic Code Required: Remember Hello.cpp ?
#include "llvm/Pass.h" The runOnFunction method is a
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
virtual function in the
llvm::FunctionPass class, and it
#include "llvm/IR/LegacyPassManager.h"
serves as the entry point for the
using namespace llvm; main logic of your LLVM pass.
namespace {
struct Hello : public FunctionPass {
static char ID;
Hello() : FunctionPass(ID) {}
char Hello::ID = 0;
static RegisterPass<Hello> X("hello", "Hello World Pass",
false /* Only looks at CFG */,
false /* Analysis Pass */);
26
Basic Code Required: Remember Hello.cpp ?
#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
Return False-> indicates it is an
analysis pass, has not changed
#include "llvm/IR/LegacyPassManager.h"
LLVM IR
using namespace llvm;
namespace {
struct Hello : public FunctionPass {
static char ID;
Hello() : FunctionPass(ID) {}
char Hello::ID = 0;
static RegisterPass<Hello> X("hello", "Hello World Pass",
false /* Only looks at CFG */,
false /* Analysis Pass */);
27
Basic Code Required: Remember Hello.cpp ?
#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
Register the pass to the opt tool,
with passname, Pass description,
#include "llvm/IR/LegacyPassManager.h"
bool, bool
using namespace llvm;
namespace {
struct Hello : public FunctionPass {
static char ID;
Hello() : FunctionPass(ID) {}
char Hello::ID = 0;
static RegisterPass<Hello> X("hello", "Hello World Pass",
false /* Only looks at CFG */,
false /* Analysis Pass */);
28
Running a pass with opt
29
Running a pass with opt
30
Running a pass with opt
31
Running a pass with opt
32
Running a pass with opt
33
Remember the classwork ?
Q: Count the number of loops in a LLVM IR file and count the number of basic blocks each loop has.
count++;
for(Loop::block_iterator b = L->block_begin(), e = L->block_end(); b != e; b++)
{
length++;
}
return false;
}
34
Another way of solving the problem:
35
Let’s Come to SSA Format
36
What is SSA ?
37
What is SSA ?
Okay!! But
what does it
Single Static Assignment
mean ?
38
Let’s take an example First
int main()
{
int a = 5;
int b = 6;
int a = a + b;
int b = a - b;
print b;
}
39
Let’s take an example First
int main()
{
int a = 5;
int b = 6; What if You were a compiler ? and
int a = a + b; you were given one instruction at a
int b = a - b; time ?
print b;
}
40
The observation of a compiler :)
The world will be much nicer if every operation assigned to a Unique name.
a1 = 5
int main()
{
int a = 5; b1 = 6
int b = 6;
int a = a + b;
int b = a - b; a2 = a1 + b1
print b;
}
b2 = a2 - b1
print b2
41
The Problem slightly gets trickier at divergent paths
a = 47
a = add a a a = mul a a
print a
42
The Problem slightly gets trickier at divergent paths
a1 = 47
a = add a a a = mul a a
print a
43
The Problem slightly gets trickier at divergent paths
a1 = 47
a2 = add a1 a1 a3 = mul a1 a1
print a
44
The Problem slightly gets trickier at divergent paths
a1 = 47
What should be
places in the last
basic block ?
a2 = add a1 a1 a3 = mul a1 a1
print a
45
The Problem slightly gets trickier at divergent paths
a1 = 47
What should be
places in the last
basic block ?
a2 = add a1 a1 a3 = mul a1 a1
a4 = phi(a2, a3)
print a4
46
SSA Definition
● A program is in SSA form, if each use of a variable is reached by exactly one definition
● Flow control remains the same as in the non-SSA form
● A special merge operator, φ, is used for selection of values in join nodes
● Not every join node needs a φ operator for every variable
● No need for a φ operator, if the same definition of the variable reaches the join node along all incoming edges
● Often, the SSA form is augmented with u-d and d-u chains to facilitate design of faster algorithms
● Translation from SSA to machine code introduces copy operations, which may introduce some inefficiency
47
Source: Lecture Notes, NPTEL, Y N Srikanth
Condition of SSA Format
1. If two non-null paths from nodes X and Y each having a definition of v converge at a node p, then p contains a
trivial φ-function of the form v = φ(v , v , ..., v ), with the number of arguments equal to the in-degree of p.
2. Each appearance of v in the original program or a φ-function in the new program has been replaced by a new
variable vi , leaving the new program in SSA form.
3. Any use of a variable v along any control path in the original program and the corresponding use of vi in the new
program yield the same value for both v and vi .
48
Source: Lecture Notes, NPTEL, Y N Srikanth
Let’s level up the challenge
49
Source: Lecture Notes, NPTEL, Y N Srikanth
Let’s level up the challenge
50
Source: Lecture Notes, NPTEL, Y N Srikanth
How to get rid of phi nodes ?
x1 = 4 x2 = 7
x3 = phi(x1, x2)
print (x3)
51
How to get rid of phi nodes ?
x1 = 4 x2 = 7
x3 = x1 x3 = x2
print (x3)
52
Last Challenge: I promise
53
Source: Lecture Notes, NPTEL, Y N Srikanth
Did you do the following ?
54
Did you do the following ?
55
Did you do the following ?
56
Correct !! phi node removal
Thank You 57