Path: blob/main/examples/notebooks/Visualize ControlFlow.ipynb
1154 views
Kernel: Python 3
In [1]:
Build a simple function with a for loop that sum the first N integer, where N is the argument.
In [2]:
In [3]:
Out[3]:
i32 (i32)
In [4]:
Out[4]:
declare i32 @"count_number"(i32 %"N")
In [5]:
Initialize variable ct and out with 0
In [6]:
Out[6]:
define i32 @"count_number"(i32 %"N")
{
entry:
%"out" = alloca i32
%"ct" = alloca i32
store i32 0, i32* %"out"
store i32 0, i32* %"ct"
}
Populate loop header
In [7]:
Out[7]:
define i32 @"count_number"(i32 %"N")
{
entry:
%"out" = alloca i32
%"ct" = alloca i32
store i32 0, i32* %"out"
store i32 0, i32* %"ct"
br label %"loop.header"
loop.header:
%".6" = load i32, i32* %"ct"
%".7" = icmp slt i32 %".6", %"N"
br i1 %".7", label %"loop.body", label %"loop.end"
loop.body:
loop.end:
}
Populate loop body
In [8]:
Out[8]:
define i32 @"count_number"(i32 %"N")
{
entry:
%"out" = alloca i32
%"ct" = alloca i32
store i32 0, i32* %"out"
store i32 0, i32* %"ct"
br label %"loop.header"
loop.header:
%".6" = load i32, i32* %"ct"
%".7" = icmp slt i32 %".6", %"N"
br i1 %".7", label %"loop.body", label %"loop.end"
loop.body:
%".9" = load i32, i32* %"out"
%".10" = load i32, i32* %"ct"
%".11" = add i32 %".9", %".10"
store i32 %".11", i32* %"out"
%".13" = load i32, i32* %"ct"
%".14" = add i32 %".13", 1
store i32 %".14", i32* %"ct"
br label %"loop.header"
loop.end:
}
Populate loop end
In [9]:
Out[9]:
define i32 @"count_number"(i32 %"N")
{
entry:
%"out" = alloca i32
%"ct" = alloca i32
store i32 0, i32* %"out"
store i32 0, i32* %"ct"
br label %"loop.header"
loop.header:
%".6" = load i32, i32* %"ct"
%".7" = icmp slt i32 %".6", %"N"
br i1 %".7", label %"loop.body", label %"loop.end"
loop.body:
%".9" = load i32, i32* %"out"
%".10" = load i32, i32* %"ct"
%".11" = add i32 %".9", %".10"
store i32 %".11", i32* %"out"
%".13" = load i32, i32* %"ct"
%".14" = add i32 %".13", 1
store i32 %".14", i32* %"ct"
br label %"loop.header"
loop.end:
%".17" = load i32, i32* %"out"
ret i32 %".17"
}
Visualize CFG
In [10]:
Out[10]:
Optimize the function
In [ ]:
; ModuleID = '<string>'
target triple = "unknown-unknown-unknown"
; Function Attrs: norecurse nounwind readnone
define i32 @count_number(i32 %N) #0 {
entry:
%.71 = icmp sgt i32 %N, 0
br i1 %.71, label %loop.body.preheader, label %loop.end
loop.body.preheader: ; preds = %entry
%0 = add i32 %N, -1
%1 = zext i32 %0 to i33
%2 = add i32 %N, -2
%3 = zext i32 %2 to i33
%4 = mul i33 %1, %3
%5 = lshr i33 %4, 1
%6 = trunc i33 %5 to i32
%7 = add i32 %6, %N
%8 = add i32 %7, -1
br label %loop.end
loop.end: ; preds = %loop.body.preheader, %entry
%out.0.lcssa = phi i32 [ 0, %entry ], [ %8, %loop.body.preheader ]
ret i32 %out.0.lcssa
}
attributes #0 = { norecurse nounwind readnone }
View optimized CFG
In [12]:
Out[12]:
Notice LLVM has optimized the looping away.