Skip to content

Instantly share code, notes, and snippets.

@tomoyanonymous
Last active November 11, 2019 08:45
Show Gist options
  • Save tomoyanonymous/fddcf1815dca642dcd3c764148863736 to your computer and use it in GitHub Desktop.
Save tomoyanonymous/fddcf1815dca642dcd3c764148863736 to your computer and use it in GitHub Desktop.
memo: llvm mapping of lambda functions, closures and capture objects in clang++
#include <stdio.h>
int main(){
int a = 540;
float b = 460.1;
auto fun = [&](int x){
putchar(a);
putchar((int)b);
putchar(x);
};
fun(1);
}
; ModuleID = 'closuretest.cpp'
source_filename = "closuretest.cpp"
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.14.0"
%class.anon = type { i32*, float* }
; Function Attrs: noinline norecurse optnone ssp uwtable
define i32 @main() #0 {
%1 = alloca i32, align 4
%2 = alloca float, align 4
%3 = alloca %class.anon, align 8
store i32 540, i32* %1, align 4
store float 0x407CC199A0000000, float* %2, align 4
%4 = getelementptr inbounds %class.anon, %class.anon* %3, i32 0, i32 0
store i32* %1, i32** %4, align 8
%5 = getelementptr inbounds %class.anon, %class.anon* %3, i32 0, i32 1
store float* %2, float** %5, align 8
call void @"_ZZ4mainENK3$_0clEi"(%class.anon* %3, i32 1)
ret i32 0
}
; Function Attrs: noinline optnone ssp uwtable
define internal void @"_ZZ4mainENK3$_0clEi"(%class.anon*, i32) #1 align 2 {
%3 = alloca %class.anon*, align 8
%4 = alloca i32, align 4
store %class.anon* %0, %class.anon** %3, align 8
store i32 %1, i32* %4, align 4
%5 = load %class.anon*, %class.anon** %3, align 8
%6 = getelementptr inbounds %class.anon, %class.anon* %5, i32 0, i32 0
%7 = load i32*, i32** %6, align 8
%8 = load i32, i32* %7, align 4
%9 = call i32 @putchar(i32 %8)
%10 = getelementptr inbounds %class.anon, %class.anon* %5, i32 0, i32 1
%11 = load float*, float** %10, align 8
%12 = load float, float* %11, align 4
%13 = fptosi float %12 to i32
%14 = call i32 @putchar(i32 %13)
%15 = load i32, i32* %4, align 4
%16 = call i32 @putchar(i32 %15)
ret void
}
declare i32 @putchar(i32) #2
attributes #0 = { noinline norecurse optnone ssp uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "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"="penryn" "target-features"="+cx16,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { noinline optnone ssp uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "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"="penryn" "target-features"="+cx16,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
!llvm.module.flags = !{!0, !1, !2}
!llvm.ident = !{!3}
!0 = !{i32 2, !"SDK Version", [2 x i32] [i32 10, i32 14]}
!1 = !{i32 1, !"wchar_size", i32 4}
!2 = !{i32 7, !"PIC Level", i32 2}
!3 = !{!"clang version 8.0.0 (tags/RELEASE_800/final)"}
#include <stdio.h>
int main(){
int a = 540;
float b = 460.1;
char c = 'a';
auto fun = [&](int x){
putchar(a);
putchar((int)b);
putchar(x);
};
auto fun2 = [&](int x){
putchar((int)b);
putchar((int)c);
putchar(x);
};
fun(100);
fun2(200);
}
; ModuleID = 'closuretest.cpp'
source_filename = "closuretest.cpp"
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.14.0"
%class.anon = type { i32*, float* }
%class.anon.0 = type { float*, i8* }
; Function Attrs: noinline norecurse optnone ssp uwtable
define i32 @main() #0 {
;;;;;initialize local variables in main();;;;;
;;;;; int a ;;;;;
%1 = alloca i32, align 4
;;;;; float b ;;;;;
%2 = alloca float, align 4
;;;;; char c ;;;;;
%3 = alloca i8, align 1
;;;;;initialize capture objects of anonymous function;;;;;
%4 = alloca %class.anon, align 8
%5 = alloca %class.anon.0, align 8
;;;;;assigning actual numbers into variables;;;;;
;;;;;int a;;;;;
store i32 540, i32* %1, align 4
;;;;; float b ;;;;;
store float 0x407CC199A0000000, float* %2, align 4
;;;;; char c ;;;;;
store i8 97, i8* %3, align 1
;;;;; store pointer of local variables into capture objects ;;;;;
;;;;;[&a,&b] for first lambda ;;;;
%6 = getelementptr inbounds %class.anon, %class.anon* %4, i32 0, i32 0
store i32* %1, i32** %6, align 8
%7 = getelementptr inbounds %class.anon, %class.anon* %4, i32 0, i32 1
store float* %2, float** %7, align 8
;;;;;[&b,&c] for second lambda ;;;;
%8 = getelementptr inbounds %class.anon.0, %class.anon.0* %5, i32 0, i32 0
store float* %2, float** %8, align 8
%9 = getelementptr inbounds %class.anon.0, %class.anon.0* %5, i32 0, i32 1
store i8* %3, i8** %9, align 8
;;;;call lambda with capture objects ;;;;;
call void @"_ZZ4mainENK3$_0clEi"(%class.anon* %4, i32 100)
call void @"_ZZ4mainENK3$_1clEi"(%class.anon.0* %5, i32 200)
ret i32 0
}
; Function Attrs: noinline optnone ssp uwtable
define internal void @"_ZZ4mainENK3$_0clEi"(%class.anon*, i32) #1 align 2 {
%3 = alloca %class.anon*, align 8
%4 = alloca i32, align 4
store %class.anon* %0, %class.anon** %3, align 8
store i32 %1, i32* %4, align 4
%5 = load %class.anon*, %class.anon** %3, align 8
%6 = getelementptr inbounds %class.anon, %class.anon* %5, i32 0, i32 0
%7 = load i32*, i32** %6, align 8
%8 = load i32, i32* %7, align 4
%9 = call i32 @putchar(i32 %8)
%10 = getelementptr inbounds %class.anon, %class.anon* %5, i32 0, i32 1
%11 = load float*, float** %10, align 8
%12 = load float, float* %11, align 4
%13 = fptosi float %12 to i32
%14 = call i32 @putchar(i32 %13)
%15 = load i32, i32* %4, align 4
%16 = call i32 @putchar(i32 %15)
ret void
}
; Function Attrs: noinline optnone ssp uwtable
define internal void @"_ZZ4mainENK3$_1clEi"(%class.anon.0*, i32) #1 align 2 {
%3 = alloca %class.anon.0*, align 8
%4 = alloca i32, align 4
store %class.anon.0* %0, %class.anon.0** %3, align 8
store i32 %1, i32* %4, align 4
%5 = load %class.anon.0*, %class.anon.0** %3, align 8
%6 = getelementptr inbounds %class.anon.0, %class.anon.0* %5, i32 0, i32 0
%7 = load float*, float** %6, align 8
%8 = load float, float* %7, align 4
%9 = fptosi float %8 to i32
%10 = call i32 @putchar(i32 %9)
%11 = getelementptr inbounds %class.anon.0, %class.anon.0* %5, i32 0, i32 1
%12 = load i8*, i8** %11, align 8
%13 = load i8, i8* %12, align 1
%14 = sext i8 %13 to i32
%15 = call i32 @putchar(i32 %14)
%16 = load i32, i32* %4, align 4
%17 = call i32 @putchar(i32 %16)
ret void
}
declare i32 @putchar(i32) #2
attributes #0 = { noinline norecurse optnone ssp uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "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"="penryn" "target-features"="+cx16,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { noinline optnone ssp uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "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"="penryn" "target-features"="+cx16,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
!llvm.module.flags = !{!0, !1, !2}
!llvm.ident = !{!3}
!0 = !{i32 2, !"SDK Version", [2 x i32] [i32 10, i32 14]}
!1 = !{i32 1, !"wchar_size", i32 4}
!2 = !{i32 7, !"PIC Level", i32 2}
!3 = !{!"clang version 8.0.0 (tags/RELEASE_800/final)"}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment