0% found this document useful (0 votes)
35 views57 pages

LLVM Pass and SSA

The document provides an introduction to writing LLVM passes and understanding Single Static Assignment (SSA) form. It outlines the tools used in the LLVM framework, types of passes, and detailed steps to create a simple LLVM pass. Additionally, it explains the concept of SSA, its definition, and how it improves variable management in programming.

Uploaded by

Naruto Hinata
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
35 views57 pages

LLVM Pass and SSA

The document provides an introduction to writing LLVM passes and understanding Single Static Assignment (SSA) form. It outlines the tools used in the LLVM framework, types of passes, and detailed steps to create a simple LLVM pass. Additionally, it explains the concept of SSA, its definition, and how it improves variable management in programming.

Uploaded by

Naruto Hinata
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 57

How to write a LLVM pass and SSA

Course: Introduction to Program Analysis and Optimization (CS5863)


Instructor: Dr. Jyothi Vedurada
TA: Soumik Kumar Basu
Acknowledgement: Mr. Anilava Kundu
1
Where to Focus ?

FRONT END MIDDLE END BACK END

2
Where to Focus ?

FRONT END MIDDLE END BACK END

3
Where to Focus ?

What are the tools we use in LLVM compilers framework ?

4
Where to Focus ?

What are the tools we use in LLVM compilers framework ?


● Clang
● OPT
● llc
● llvm-as
● llvm-dis

5
Where to Focus ?

What are the tools we use in LLVM compilers framework ?


● Clang
● OPT
● llc
● llvm-as
● llvm-dis

6
OPT is your friend: What does it do ?

file.ll OPT file.ll

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.

add_llvm_library( LLVMHello MODULE


Hello.cpp

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.

add_llvm_library( LLVMHello MODULE


Hello.cpp

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.

add_llvm_library( LLVMHello MODULE


Hello.cpp

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.

add_llvm_library( LLVMHello MODULE


Hello.cpp

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

Q: What is the difference between statically linked


libraries and shared object files ?

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.

add_llvm_library( LLVMHello MODULE


Hello.cpp

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.

add_llvm_library( LLVMHello MODULE


Hello.cpp

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"

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';
return false;
}
}; // end of struct Hello
} // end of anonymous namespace

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) {}

bool runOnFunction(Function &F) override {


errs() << "Hello: ";
errs().write_escaped(F.getName()) << '\n';
return false;
}
}; // end of struct Hello
} // end of anonymous namespace

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) {}

bool runOnFunction(Function &F) override {


errs() << "Hello: ";
errs().write_escaped(F.getName()) << '\n';
return false;
}
}; // end of struct Hello
} // end of anonymous namespace

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) {}

bool runOnFunction(Function &F) override {


errs() << "Hello: ";
errs().write_escaped(F.getName()) << '\n';
return false;
}
}; // end of struct Hello
} // end of anonymous namespace

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) {}

bool runOnFunction(Function &F) override {


errs() << "Hello: ";
errs().write_escaped(F.getName()) << '\n';
return false;
}
}; // end of struct Hello
} // end of anonymous namespace

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) {}

bool runOnFunction(Function &F) override {


errs() << "Hello: ";
errs().write_escaped(F.getName()) << '\n';
return false;
}
}; // end of struct Hello
} // end of anonymous namespace

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) {}

bool runOnFunction(Function &F) override {


errs() << "Hello: ";
errs().write_escaped(F.getName()) << '\n';
return false;
}
}; // end of struct Hello
} // end of anonymous namespace

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

opt -load lib/LLVMHello.so -hello file.ll

29
Running a pass with opt

opt -load lib/LLVMHello.so -hello file.ll

30
Running a pass with opt

opt -load lib/LLVMHello.so -hello file.ll

31
Running a pass with opt

opt -load lib/LLVMHello.so -enable-new-pm=0 -hello file.ll

32
Running a pass with opt

opt -load lib/LLVMHello.so -enable-new-pm=0 -hello file.ll

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.

bool runOnLoop(Loop * L, LPPassManager &LPM){

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:

virtual bool runOnModule(Module&M) {


loopcounter = 0;
for (auto &IT = M.begin, END = M.end(); IT != END; ++IT) {
LoopInfo &LI = getAnalysis<LoopInfo>(*IT);
for (LoopInfo::iterator LIT = LI.begin(), LEND = LI.end(); LIT != LEND; ++LIT) {
handleLoop(*LIT);
}
}

35
Let’s Come to SSA Format

36
What is SSA ?

Single Static Assignment

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

After translation, the SSA form should satisfy the following

conditions for every variable v in the original program.

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

You might also like