Loop Invariant Code Motion (LICM) in LLVM

HW2
 
 
Frequent
 
Path
 
Loop
Invariant Code Motion
Ze
 
Zhang
Oct
 
1
, 201
8
Loop Invariant Code Motion (LICM)
Move operations whose source
operands do not change within
the loop to the loop preheader
Execute them only 1x per
invocation of the loop
Be careful with memory
operations!
Be careful with ops not executed
every iteration
LICM code exists in LLVM!
/lib/Transforms/Scalar/LICM.cpp
1
for
 
(int
 
i
 
=
 
0;
 
i
 
<
 
n;
 
i++)
 
{
 
x
 
=
 
y
 
+
 
z;
 
a[i]
 
=
 
6
 * 
i
 
+
 
x
 * 
x
;
}
Loop Invariant Code Motion (LICM)
Move operations whose source
operands do not change within
the loop to the loop preheader
Execute them only 1x per
invocation of the loop
Be careful with memory
operations!
Be careful with ops not executed
every iteration
LICM code exists in LLVM!
/lib/Transforms/Scalar/LICM.cpp
2
for
 
(int
 
i
 
=
 
0;
 
i
 
<
 
n;
 
i++)
 
{
 
x
 
=
 
y
 
+
 
z;
 
a[i]
 
=
 
6
 * 
i
 
+
 
x
 * 
x
;
}
x
 
=
 
y
 
+
 
z;
t1
 
=
 
x
 * 
x;
for
 
(int
 
i
 
=
 
0;
 
i
 
<
 
n;
 
i++)
 
{
  
a[i]
 
=
 
6
 * 
i
 
+
 
t1
;
}
Your Assignment: 
Frequent
 
Path
 LICM
r1 = 
&A
r4 = load(
r1
)
r7 = r4 * 3
r3
 
=
 
r3
 
+
 
r5
r2 = r2 + 1
store (r
2
, 
r
1
)
r8
 
=
 
r2
 
+
 
7
store
 
(r3,
 
r8)
 
3
100
1
1
Your Assignment: 
Frequent
 
Path
 LICM
r1 = 
&A
r4 = load(
r1
)
r7 = r4 * 3
r3
 
=
 
r3
 
+
 
r5
r2 = r2 + 1
store (r
2
, 
r
1
)
r8
 
=
 
r2
 
+
 
7
store
 
(r3,
 
r8)
 
4
100
1
1
Cannot perform LICM on load, because
 
of
the
 
store-load
 
dependency
Your Assignment: 
Frequent
 
Path
 LICM
r1 = 
&A
r4 = load(
r1
)
r7 = r4 * 3
r3
 
=
 
r3
 
+
 
r5
r2 = r2 + 1
store (r
2
, 
r
1
)
r8
 
=
 
r2
 
+
 
7
store
 
(r3,
 
r8)
 
5
100
1
1
Cannot perform LICM on load, because
 
of
the
 
store-load
 
dependency
But… profile 
data
 
says that 
the
 
store
 
rarely
happens
Your Assignment: 
Frequent
 
Path
 LICM
r1 = 
&A
r4 = load(
r1
)
r7 = r4 * 3
r3
 
=
 
r3
 
+
 
r5
r2 = r2 + 1
store (r
2
, 
r
1
)
r8
 
=
 
r2
 
+
 
7
store
 
(r3,
 
r8)
 
6
100
1
1
Cannot perform LICM on load, because
 
of
the
 
store-load
 
dependency
But… profile 
data
 
says that 
the
 
store
 
rarely
happens
Frequent
 
Path
 LICM:
1)
Ignore
 infrequent dependence
between loads and stores
Your Assignment: 
Frequent
 
Path
 LICM
r1 = 
&A
r4 = load(
r1
)
r7 = r4 * 3
r3
 
=
 
r3
 
+
 
r5
r2 = r2 + 1
store (r
2
, 
r
1
)
r8
 
=
 
r2
 
+
 
7
store
 
(r3,
 
r8)
 
7
100
1
1
Cannot perform LICM on load, because
 
of
the
 
store-load
 
dependency
But… profile 
data
 
says that 
the
 
store
 
rarely
happens
Frequent
 
Path
 LICM:
1)
Ignore
 infrequent dependence
between loads and stores
2)
Perform LICM on load
Your Assignment: 
Frequent
 
Path
 LICM
r1 = 
&A
r4 = load(
r1
)
r7 = r4 * 3
r3
 
=
 
r3
 
+
 
r5
r2 = r2 + 1
store (r
2
, 
r
1
)
r8
 
=
 
r2
 
+
 
7
store
 
(r3,
 
r8)
 
8
100
1
1
Cannot perform LICM on load, because
 
of
the
 
store-load
 
dependency
But… profile 
data
 
says that 
the
 
store
 
rarely
happens
Frequent
 
Path
 LICM:
1)
Ignore
 infrequent dependence
between loads and stores
2)
Perform LICM on load
3)
Perform LICM on any consumers of
the load that become invariant
Your Assignment: 
Frequent
 
Path
 LICM
r1 = 
&A
r4 = load(
r1
)
r7 = r4 * 3
r3
 
=
 
r3
 
+
 
r5
r2 = r2 + 1
store (r
2
, 
r
1
)
r4 = load(
r1
)
r7 = r4 * 3
r8
 
=
 
r2
 
+
 
7
store
 
(r3,
 
r8)
 
9
100
1
1
Cannot perform LICM on load, because
 
of
the
 
store-load
 
dependency
But… profile 
data
 
says that 
the
 
store
 
rarely
happens
Frequent
 
Path
 LICM:
1)
Ignore
 infrequent dependence
between loads and stores
2)
Perform LICM on load
3)
Perform LICM on any consumers of
the load that become invariant
4)
Insert fix-up code to restore correct
execution
Your Assignment: 
Frequent
 
Path
 LICM
r1 = 
&A
r4 = load(
r1
)
r7 = r4 * 3
r3
 
=
 
r3
 
+
 
r5
r2 = r2 + 1
store (r
2
, 
r
1
)
r4 = load(
r1
)
r7 = r4 * 3
r8
 
=
 
r2
 
+
 
7
store
 
(r3,
 
r8)
 
10
100
1
1
After
 
FPLICM
r1 = 
&A
r4 = load(
r1
)
r7 = r4 * 3
r3
 
=
 
r3
 
+
 
r5
r2 = r2 + 1
store (r
2
, 
r
1
)
r8
 
=
 
r2
 
+
 
7
store
 
(r3,
 
r8)
 
100
1
1
Before
 
FPLICM
Your Assignment: 
Frequent
 
Path
 LICM
11
Identify
 
the
 
frequent
 
path
 
within
 
the
 
loop
 
Find
 
store
 
instructions
 
among
 
all
 
infrequent
 
BBs
 
and
 
their
dependent
 
load
 
instructions
 
in
 
frequent
 
BBs
 
 
destination
 
operand
 
of
 
infrequent
 
store
 
=
 
source
 
operand
 
of
 
frequent
 
load
Hoist
 
the
 
load
 
instruction
 
Hoist
 consumers of the load that become invariant
*
Replicate
 
all
 
hoisted
 
instructions
 
in
 
the
 
infrequent
 
path
LLVM Code of Interest
The following slides present code from the LLVM codebase
that may help you with HW2.
Disclaimers:
Use of this code is by no means required.  There are many
ways to do this assignment.
You are free to use any other code that exists in LLVM 
6.0.1
or that you develop.
Read the documentation/source before asking for help!
http://llvm.org/docs/ProgrammersManual.html#helpful-
hints-for-common-operations
12
Code: Manipulating Basic Blocks
SplitBlock(…) splits a BB at a
specified instr, returns ptr to
new BB that starts with the
instr, connects the BBs with
an unconditional branch
SplitEdge(…) will insert a BB
between two specified BBs
Code found in:
<llvm-src-
root>/include/llvm/Transforms/U
tils/BasicBlockUtils.h
<llvm-src-
root>/lib/Transforms/Utils/Basi
cBlockUtils.cpp
// I is an Instruction*
BasicBlock *BB1 = I->getParent();
BasicBlock *BB3 = 
 
 
SplitBlock
(BB1, I);
BasicBlock *BB2 =
 
SplitEdge
(BB1, BB3);
13
Code: Creating and Inserting
Instructions
Various ways to create & insert
instructions
Hint: Instructions have a
clone() 
member function
See specific instruction
constructors/member
functions in:
<llvm-src-
root>/include/llvm/IR/Instruction
s.h
See general instruction
functions available to all
instructions in:
<llvm-src-
root>/include/llvm/IR/Instruction
.h
// 1) create load, insert at end of
//    specified basic block
LoadInst *LD =
 
new LoadInst(
Val
,
    
“loadflag”,
    
BB1);
// 2) create branch using Create
//    method, insert before BB1’s
//    terminating instruction
Branch::Create(BB1, BB2, flag,
               BB1->getTerminator());
// 3) create a store inst that stores
//    result of LD to some variable
//    (related to next slide)
StoreInst *ST =
 
new StoreInst(LD, var);
//    inserting store into code
ST->insertAfter(LD);
14
Code: Creating Variables
Use AllocaInst to
allocate space on the
function’s stack frame
for a variable
// 1) Create 
a
 variable in the
//    function Entry block
AllocaInst *
Val
 = new AllocaInst(
  
I->getType(),
  
0,
  
Entry->getTerminator()
  
);
// 2) 
store
 
to
 
the
 
variable
StoreInst *ST = new StoreInst(
  
Result
,
  
Val
,
  
Entry->getTerminator()
  
);
15
Important: Maintaining SSA Form
Static 
Single 
Assignment form requires unique destination
registers for each instruction
Replicated
 instructions in your 
infrequent
 
BB
 will write to
different regs compared to the instructions in the
preheader!
Store results of hoisted instrs to stack variables (see prev.
slide)
Make sure AllocaInst’s are in function’s entry BB!
16
Related
 
Files
run.sh
List
 
of
 
commands
 
used
 
in
 
HW2
Project
 
Template
HW2PASS.cpp:
 
Mostly
 
from
 
current
 
LLVM
 
LICM
 
Implementation.
runOnLoop
(…)
         
hoistRegion(…)
             
hoist(…)
Benchmarks
6
 
correctness
 
tests
 
+
 
README
 
(Required)
Only
 
need
 
to
 
hoist
 
the
 
dependent
 
load
 
instructions
Must
 
generate
 
the
 
correct
 
output
 
after
 
applying
 
your
 
FPLICM
 
pass
4
 
performance
 
tests
 
+
 
README
 
(Optional)
Hoist
 
as
 
many
 
instructions
 
as
 
possible
Correctness
 
first,
 
then
 
the
 
performance
17
General Notes Regarding HW2
Start early!
Use
 
the
 
template
 
(Don’t
 
be
 
afraid
 
of
 
it)
Try
 
the
 
bonus
 
part
Running/Debugging
Revisit information from LLVM overview slides
Performance Competition: Generate 
correct
AND
 
fast
 bitcode
18
Slide Note
Embed
Share

Loop Invariant Code Motion (LICM) is a technique used in LLVM to move operations that do not change within a loop outside of the loop, improving performance by executing them only once per loop iteration. This process must be done carefully to handle memory operations and operations that are not executed every iteration.

  • Loop Invariant Code Motion
  • LICM
  • LLVM
  • Performance Optimization

Uploaded on Nov 24, 2024 | 1 Views


Download Presentation

Please find below an Image/Link to download the presentation.

The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author.If you encounter any issues during the download, it is possible that the publisher has removed the file from their server.

You are allowed to download the files provided on this website for personal or commercial use, subject to the condition that they are used lawfully. All files are the property of their respective owners.

The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author.

E N D

Presentation Transcript


  1. HW2 Frequent Path Loop Invariant Code Motion Ze Zhang Oct 1, 2018

  2. Loop Invariant Code Motion (LICM) Move operations whose source operands do not change within the loop to the loop preheader Execute them only 1x per invocation of the loop Be careful with memory operations! Be careful with ops not executed every iteration for (int i = 0; i < n; i++) { x = y + z; a[i] = 6 * i + x * x; } LICM code exists in LLVM! /lib/Transforms/Scalar/LICM.cpp 1

  3. Loop Invariant Code Motion (LICM) Move operations whose source operands do not change within the loop to the loop preheader Execute them only 1x per invocation of the loop Be careful with memory operations! Be careful with ops not executed every iteration for (int i = 0; i < n; i++) { x = y + z; a[i] = 6 * i + x * x; } x = y + z; t1 = x * x; for (int i = 0; i < n; i++) { a[i] = 6 * i + t1; } LICM code exists in LLVM! /lib/Transforms/Scalar/LICM.cpp 2

  4. Your Assignment: Frequent Path LICM r1 = &A r4 = load(r1) r7 = r4 * 3 r3 = r3 + r5 1 r2 = r2 + 1 store (r2, r1) 100 1 r8 = r2 + 7 store (r3, r8) 3

  5. Your Assignment: Frequent Path LICM Cannot perform LICM on load, because of the store-load dependency r1 = &A r4 = load(r1) r7 = r4 * 3 r3 = r3 + r5 1 r2 = r2 + 1 store (r2, r1) 100 1 r8 = r2 + 7 store (r3, r8) 4

  6. Your Assignment: Frequent Path LICM Cannot perform LICM on load, because of the store-load dependency r1 = &A But profile data says that the store rarely happens r4 = load(r1) r7 = r4 * 3 r3 = r3 + r5 1 r2 = r2 + 1 store (r2, r1) 100 1 r8 = r2 + 7 store (r3, r8) 5

  7. Your Assignment: Frequent Path LICM Cannot perform LICM on load, because of the store-load dependency r1 = &A But profile data says that the store rarely happens r4 = load(r1) r7 = r4 * 3 r3 = r3 + r5 1 r2 = r2 + 1 store (r2, r1) 100 Frequent Path LICM: 1) Ignore infrequent dependence between loads and stores 1 r8 = r2 + 7 store (r3, r8) 6

  8. Your Assignment: Frequent Path LICM Cannot perform LICM on load, because of the store-load dependency r1 = &A But profile data says that the store rarely happens r4 = load(r1) r7 = r4 * 3 r3 = r3 + r5 1 r2 = r2 + 1 store (r2, r1) 100 Frequent Path LICM: 1) Ignore infrequent dependence between loads and stores 2) Perform LICM on load 1 r8 = r2 + 7 store (r3, r8) 7

  9. Your Assignment: Frequent Path LICM Cannot perform LICM on load, because of the store-load dependency r1 = &A But profile data says that the store rarely happens r4 = load(r1) r7 = r4 * 3 r3 = r3 + r5 1 r2 = r2 + 1 store (r2, r1) 100 Frequent Path LICM: 1) Ignore infrequent dependence between loads and stores 2) Perform LICM on load 3) Perform LICM on any consumers of the load that become invariant 1 r8 = r2 + 7 store (r3, r8) 8

  10. Your Assignment: Frequent Path LICM Cannot perform LICM on load, because of the store-load dependency r1 = &A But profile data says that the store rarely happens r4 = load(r1) r7 = r4 * 3 r3 = r3 + r5 1 r2 = r2 + 1 store (r2, r1) r4 = load(r1) r7 = r4 * 3 100 Frequent Path LICM: 1) Ignore infrequent dependence between loads and stores 2) Perform LICM on load 3) Perform LICM on any consumers of the load that become invariant 4) Insert fix-up code to restore correct execution 1 r8 = r2 + 7 store (r3, r8) 9

  11. Your Assignment: Frequent Path LICM r1 = &A r4 = load(r1) r7 = r4 * 3 r1 = &A r4 = load(r1) r7 = r4 * 3 r3 = r3 + r5 r3 = r3 + r5 1 1 r2 = r2 + 1 store (r2, r1) r4 = load(r1) r7 = r4 * 3 r2 = r2 + 1 store (r2, r1) 100 100 1 1 r8 = r2 + 7 store (r3, r8) r8 = r2 + 7 store (r3, r8) Before FPLICM After FPLICM 10

  12. Your Assignment: Frequent Path LICM Identify the frequent path within the loop Find store instructions among all infrequent BBs and their dependent load instructions in frequent BBs destination operand of infrequent store = source operand of frequent load Hoist the load instruction Hoist consumers of the load that become invariant* Replicate all hoisted instructions in the infrequent path 11

  13. LLVM Code of Interest The following slides present code from the LLVM codebase that may help you with HW2. Disclaimers: Use of this code is by no means required. There are many ways to do this assignment. You are free to use any other code that exists in LLVM 6.0.1 or that you develop. Read the documentation/source before asking for help! http://llvm.org/docs/ProgrammersManual.html#helpful- hints-for-common-operations 12

  14. Code: Manipulating Basic Blocks SplitBlock( ) splits a BB at a specified instr, returns ptr to new BB that starts with the instr, connects the BBs with an unconditional branch // I is an Instruction* BasicBlock *BB1 = I->getParent(); BasicBlock *BB3 = SplitBlock(BB1, I); BasicBlock *BB2 = SplitEdge(BB1, BB3); SplitEdge( ) will insert a BB between two specified BBs Code found in: <llvm-src- root>/include/llvm/Transforms/U tils/BasicBlockUtils.h <llvm-src- root>/lib/Transforms/Utils/Basi cBlockUtils.cpp 13

  15. Code: Creating and Inserting Instructions Various ways to create & insert instructions // 1) create load, insert at end of // specified basic block LoadInst *LD = new LoadInst(Val, loadflag , BB1); Hint: Instructions have a clone() member function // 2) create branch using Create // method, insert before BB1 s // terminating instruction Branch::Create(BB1, BB2, flag, BB1->getTerminator()); See specific instruction constructors/member functions in: <llvm-src- root>/include/llvm/IR/Instruction s.h // 3) create a store inst that stores // result of LD to some variable // (related to next slide) StoreInst *ST = new StoreInst(LD, var); // inserting store into code ST->insertAfter(LD); See general instruction functions available to all instructions in: <llvm-src- root>/include/llvm/IR/Instruction .h 14

  16. Code: Creating Variables // 1) Create a variable in the // function Entry block AllocaInst *Val = new AllocaInst( I->getType(), 0, Entry->getTerminator() ); Use AllocaInst to allocate space on the function s stack frame for a variable // 2) store to the variable StoreInst *ST = new StoreInst( Result, Val, Entry->getTerminator() ); 15

  17. Important: Maintaining SSA Form Static Single Assignment form requires unique destination registers for each instruction Replicated instructions in your infrequent BB will write to different regs compared to the instructions in the preheader! Store results of hoisted instrs to stack variables (see prev. slide) Make sure AllocaInst sare in function s entry BB! 16

  18. Related Files run.sh List of commands used in HW2 Project Template HW2PASS.cpp: Mostly from current LLVM LICM Implementation. runOnLoop( ) hoistRegion( ) hoist( ) Benchmarks 6 correctness tests + README (Required) Only need to hoist the dependent load instructions Must generate the correct output after applying your FPLICM pass 4 performance tests + README (Optional) Hoist as many instructions as possible Correctness first, then the performance 17

  19. General Notes Regarding HW2 Start early! Use the template (Don t be afraid of it) Try the bonus part Running/Debugging Revisit information from LLVM overview slides Performance Competition: Generate correct AND fast bitcode 18

More Related Content

giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#