-
-
Save DerSaidin/3c8ed6c35938a04a34b279b5e4e0265f to your computer and use it in GitHub Desktop.
LLVM Optimization pass breakdown example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
inline int square(int num) { | |
return num*num*num*num*num*num*num*num; | |
} | |
int foo(int n, int num) { | |
int res = 0; | |
for(int i = 0; i < n; i++) | |
res += square(num); | |
return res; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; ModuleID = 'a.ll' | |
source_filename = "a.cc" | |
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | |
target triple = "x86_64-unknown-linux-gnu" | |
$_Z6squarei = comdat any | |
; Function Attrs: uwtable | |
define i32 @_Z3fooii(i32, i32) #0 { | |
%3 = alloca i32, align 4 | |
%4 = alloca i32, align 4 | |
%5 = alloca i32, align 4 | |
%6 = alloca i32, align 4 | |
store i32 %0, i32* %3, align 4, !tbaa !2 | |
store i32 %1, i32* %4, align 4, !tbaa !2 | |
%7 = bitcast i32* %5 to i8* | |
call void @llvm.lifetime.start.p0i8(i64 4, i8* %7) #3 | |
store i32 0, i32* %5, align 4, !tbaa !2 | |
%8 = bitcast i32* %6 to i8* | |
call void @llvm.lifetime.start.p0i8(i64 4, i8* %8) #3 | |
store i32 0, i32* %6, align 4, !tbaa !2 | |
br label %9 | |
; <label>:9: ; preds = %20, %2 | |
%10 = load i32, i32* %6, align 4, !tbaa !2 | |
%11 = load i32, i32* %3, align 4, !tbaa !2 | |
%12 = icmp slt i32 %10, %11 | |
br i1 %12, label %15, label %13 | |
; <label>:13: ; preds = %9 | |
%14 = bitcast i32* %6 to i8* | |
call void @llvm.lifetime.end.p0i8(i64 4, i8* %14) #3 | |
br label %23 | |
; <label>:15: ; preds = %9 | |
%16 = load i32, i32* %4, align 4, !tbaa !2 | |
%17 = call i32 @_Z6squarei(i32 %16) | |
%18 = load i32, i32* %5, align 4, !tbaa !2 | |
%19 = add nsw i32 %18, %17 | |
store i32 %19, i32* %5, align 4, !tbaa !2 | |
br label %20 | |
; <label>:20: ; preds = %15 | |
%21 = load i32, i32* %6, align 4, !tbaa !2 | |
%22 = add nsw i32 %21, 1 | |
store i32 %22, i32* %6, align 4, !tbaa !2 | |
br label %9 | |
; <label>:23: ; preds = %13 | |
%24 = load i32, i32* %5, align 4, !tbaa !2 | |
%25 = bitcast i32* %5 to i8* | |
call void @llvm.lifetime.end.p0i8(i64 4, i8* %25) #3 | |
ret i32 %24 | |
} | |
; Function Attrs: argmemonly nounwind | |
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1 | |
; Function Attrs: inlinehint nounwind uwtable | |
define linkonce_odr i32 @_Z6squarei(i32) #2 comdat { | |
%2 = alloca i32, align 4 | |
store i32 %0, i32* %2, align 4, !tbaa !2 | |
%3 = load i32, i32* %2, align 4, !tbaa !2 | |
%4 = load i32, i32* %2, align 4, !tbaa !2 | |
%5 = mul nsw i32 %3, %4 | |
%6 = load i32, i32* %2, align 4, !tbaa !2 | |
%7 = mul nsw i32 %5, %6 | |
%8 = load i32, i32* %2, align 4, !tbaa !2 | |
%9 = mul nsw i32 %7, %8 | |
%10 = load i32, i32* %2, align 4, !tbaa !2 | |
%11 = mul nsw i32 %9, %10 | |
%12 = load i32, i32* %2, align 4, !tbaa !2 | |
%13 = mul nsw i32 %11, %12 | |
%14 = load i32, i32* %2, align 4, !tbaa !2 | |
%15 = mul nsw i32 %13, %14 | |
%16 = load i32, i32* %2, align 4, !tbaa !2 | |
%17 = mul nsw i32 %15, %16 | |
ret i32 %17 | |
} | |
; Function Attrs: argmemonly nounwind | |
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1 | |
attributes #0 = { uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } | |
attributes #1 = { argmemonly nounwind } | |
attributes #2 = { inlinehint nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } | |
attributes #3 = { nounwind } | |
!llvm.module.flags = !{!0} | |
!llvm.ident = !{!1} | |
!0 = !{i32 1, !"wchar_size", i32 4} | |
!1 = !{!"clang version 5.0.2 (tags/RELEASE_502/final)"} | |
!2 = !{!3, !3, i64 0} | |
!3 = !{!"int", !4, i64 0} | |
!4 = !{!"omnipotent char", !5, i64 0} | |
!5 = !{!"Simple C++ TBAA"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; ModuleID = 'a.ll' | |
source_filename = "a.cc" | |
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | |
target triple = "x86_64-unknown-linux-gnu" | |
$_Z6squarei = comdat any | |
; Function Attrs: uwtable | |
define i32 @_Z3fooii(i32, i32) #0 { | |
br label %3 | |
; <label>:3: ; preds = %9, %2 | |
%.01 = phi i32 [ 0, %2 ], [ %8, %9 ] | |
%.0 = phi i32 [ 0, %2 ], [ %10, %9 ] | |
%4 = icmp slt i32 %.0, %0 | |
br i1 %4, label %6, label %5 | |
; <label>:5: ; preds = %3 | |
br label %11 | |
; <label>:6: ; preds = %3 | |
%7 = call i32 @_Z6squarei(i32 %1) | |
%8 = add nsw i32 %.01, %7 | |
br label %9 | |
; <label>:9: ; preds = %6 | |
%10 = add nsw i32 %.0, 1 | |
br label %3 | |
; <label>:11: ; preds = %5 | |
ret i32 %.01 | |
} | |
; Function Attrs: argmemonly nounwind | |
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1 | |
; Function Attrs: inlinehint nounwind uwtable | |
define linkonce_odr i32 @_Z6squarei(i32) #2 comdat { | |
%2 = mul nsw i32 %0, %0 | |
%3 = mul nsw i32 %2, %0 | |
%4 = mul nsw i32 %3, %0 | |
%5 = mul nsw i32 %4, %0 | |
%6 = mul nsw i32 %5, %0 | |
%7 = mul nsw i32 %6, %0 | |
%8 = mul nsw i32 %7, %0 | |
ret i32 %8 | |
} | |
; Function Attrs: argmemonly nounwind | |
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1 | |
attributes #0 = { uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } | |
attributes #1 = { argmemonly nounwind } | |
attributes #2 = { inlinehint nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } | |
!llvm.module.flags = !{!0} | |
!llvm.ident = !{!1} | |
!0 = !{i32 1, !"wchar_size", i32 4} | |
!1 = !{!"clang version 5.0.2 (tags/RELEASE_502/final)"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; ModuleID = 'a.ll' | |
source_filename = "a.cc" | |
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | |
target triple = "x86_64-unknown-linux-gnu" | |
$_Z6squarei = comdat any | |
; Function Attrs: uwtable | |
define i32 @_Z3fooii(i32, i32) #0 { | |
br label %3 | |
; <label>:3: ; preds = %9, %2 | |
%.01 = phi i32 [ 0, %2 ], [ %8, %9 ] | |
%.0 = phi i32 [ 0, %2 ], [ %10, %9 ] | |
%4 = icmp slt i32 %.0, %0 | |
br i1 %4, label %6, label %5 | |
; <label>:5: ; preds = %3 | |
br label %11 | |
; <label>:6: ; preds = %3 | |
%7 = call i32 @_Z6squarei(i32 %1) | |
%8 = add nsw i32 %7, %.01 | |
br label %9 | |
; <label>:9: ; preds = %6 | |
%10 = add nsw i32 %.0, 1 | |
br label %3 | |
; <label>:11: ; preds = %5 | |
ret i32 %.01 | |
} | |
; Function Attrs: argmemonly nounwind | |
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1 | |
; Function Attrs: inlinehint nounwind uwtable | |
define linkonce_odr i32 @_Z6squarei(i32) #2 comdat { | |
%2 = mul i32 %0, %0 | |
%3 = mul i32 %2, %2 | |
%4 = mul i32 %3, %3 | |
ret i32 %4 | |
} | |
; Function Attrs: argmemonly nounwind | |
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1 | |
attributes #0 = { uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } | |
attributes #1 = { argmemonly nounwind } | |
attributes #2 = { inlinehint nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } | |
!llvm.module.flags = !{!0} | |
!llvm.ident = !{!1} | |
!0 = !{i32 1, !"wchar_size", i32 4} | |
!1 = !{!"clang version 5.0.2 (tags/RELEASE_502/final)"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; ModuleID = 'a.ll' | |
source_filename = "a.cc" | |
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | |
target triple = "x86_64-unknown-linux-gnu" | |
; Function Attrs: uwtable | |
define i32 @_Z3fooii(i32, i32) #0 { | |
br label %3 | |
; <label>:3: ; preds = %11, %2 | |
%.01 = phi i32 [ 0, %2 ], [ %10, %11 ] | |
%.0 = phi i32 [ 0, %2 ], [ %12, %11 ] | |
%4 = icmp slt i32 %.0, %0 | |
br i1 %4, label %6, label %5 | |
; <label>:5: ; preds = %3 | |
br label %13 | |
; <label>:6: ; preds = %3 | |
%7 = mul i32 %1, %1 | |
%8 = mul i32 %7, %7 | |
%9 = mul i32 %8, %8 | |
%10 = add nsw i32 %9, %.01 | |
br label %11 | |
; <label>:11: ; preds = %6 | |
%12 = add nsw i32 %.0, 1 | |
br label %3 | |
; <label>:13: ; preds = %5 | |
ret i32 %.01 | |
} | |
; Function Attrs: argmemonly nounwind | |
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1 | |
; Function Attrs: argmemonly nounwind | |
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1 | |
attributes #0 = { uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } | |
attributes #1 = { argmemonly nounwind } | |
!llvm.module.flags = !{!0} | |
!llvm.ident = !{!1} | |
!0 = !{i32 1, !"wchar_size", i32 4} | |
!1 = !{!"clang version 5.0.2 (tags/RELEASE_502/final)"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; ModuleID = 'a.ll' | |
source_filename = "a.cc" | |
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | |
target triple = "x86_64-unknown-linux-gnu" | |
; Function Attrs: uwtable | |
define i32 @_Z3fooii(i32, i32) #0 { | |
%3 = mul i32 %1, %1 | |
%4 = mul i32 %3, %3 | |
%5 = mul i32 %4, %4 | |
br label %6 | |
; <label>:6: ; preds = %11, %2 | |
%.01 = phi i32 [ 0, %2 ], [ %10, %11 ] | |
%.0 = phi i32 [ 0, %2 ], [ %12, %11 ] | |
%7 = icmp slt i32 %.0, %0 | |
br i1 %7, label %9, label %8 | |
; <label>:8: ; preds = %6 | |
%.01.lcssa = phi i32 [ %.01, %6 ] | |
br label %13 | |
; <label>:9: ; preds = %6 | |
%10 = add nsw i32 %5, %.01 | |
br label %11 | |
; <label>:11: ; preds = %9 | |
%12 = add nsw i32 %.0, 1 | |
br label %6 | |
; <label>:13: ; preds = %8 | |
ret i32 %.01.lcssa | |
} | |
; Function Attrs: argmemonly nounwind | |
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1 | |
; Function Attrs: argmemonly nounwind | |
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1 | |
attributes #0 = { uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } | |
attributes #1 = { argmemonly nounwind } | |
!llvm.module.flags = !{!0} | |
!llvm.ident = !{!1} | |
!0 = !{i32 1, !"wchar_size", i32 4} | |
!1 = !{!"clang version 5.0.2 (tags/RELEASE_502/final)"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; ModuleID = 'a.ll' | |
source_filename = "a.cc" | |
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | |
target triple = "x86_64-unknown-linux-gnu" | |
; Function Attrs: uwtable | |
define i32 @_Z3fooii(i32, i32) #0 { | |
%3 = mul i32 %1, %1 | |
%4 = mul i32 %3, %3 | |
%5 = mul i32 %4, %4 | |
%6 = icmp sgt i32 %0, 0 | |
%smax = select i1 %6, i32 %0, i32 0 | |
br label %7 | |
; <label>:7: ; preds = %2 | |
%8 = mul i32 %5, %smax | |
br label %9 | |
; <label>:9: ; preds = %7 | |
ret i32 %8 | |
} | |
; Function Attrs: argmemonly nounwind | |
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1 | |
; Function Attrs: argmemonly nounwind | |
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1 | |
attributes #0 = { uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } | |
attributes #1 = { argmemonly nounwind } | |
!llvm.module.flags = !{!0} | |
!llvm.ident = !{!1} | |
!0 = !{i32 1, !"wchar_size", i32 4} | |
!1 = !{!"clang version 5.0.2 (tags/RELEASE_502/final)"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; ModuleID = 'a.ll' | |
source_filename = "a.cc" | |
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | |
target triple = "x86_64-unknown-linux-gnu" | |
; Function Attrs: uwtable | |
define i32 @_Z3fooii(i32, i32) #0 { | |
%3 = mul i32 %1, %1 | |
%4 = mul i32 %3, %3 | |
%5 = icmp sgt i32 %0, 0 | |
%smax = select i1 %5, i32 %0, i32 0 | |
%6 = mul i32 %4, %smax | |
%7 = mul i32 %6, %4 | |
ret i32 %7 | |
} | |
; Function Attrs: argmemonly nounwind | |
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1 | |
; Function Attrs: argmemonly nounwind | |
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1 | |
attributes #0 = { uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } | |
attributes #1 = { argmemonly nounwind } | |
!llvm.module.flags = !{!0} | |
!llvm.ident = !{!1} | |
!0 = !{i32 1, !"wchar_size", i32 4} | |
!1 = !{!"clang version 5.0.2 (tags/RELEASE_502/final)"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# Adding "-O1 -Xclang -disable-llvm-passes" is disables optimziations like "-O0", | |
# but doing "-O0" also adds a optnone attribute to each function. | |
# This attribute would tell opt not to optimize each function, which would break this example. | |
clang a.cc -O1 -Xclang -disable-llvm-passes -emit-llvm -S -o a.ll | |
opt -S a.ll -o b0.ll | |
opt -mem2reg -S a.ll -o b1.ll | |
opt -mem2reg -reassociate -S a.ll -o b2.ll | |
opt -mem2reg -reassociate -inline -S a.ll -o b3.ll | |
opt -mem2reg -reassociate -inline -licm -S a.ll -o b4.ll | |
opt -mem2reg -reassociate -inline -licm -indvars -loop-deletion -S a.ll -o b5.ll | |
opt -mem2reg -reassociate -inline -licm -indvars -loop-deletion -simplifycfg -S a.ll -o b6.ll |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment