Created
July 16, 2015 21:39
-
-
Save rednaxelafx/cd279ad31c01593073a6 to your computer and use it in GitHub Desktop.
Demo of Clang++'s implementation of C++ static local variable
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
$ clang++ -S -emit-llvm yy.cc |
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
int g_counter = 0; | |
struct Dummy { | |
int value; | |
Dummy(): value(0) { g_counter++; } | |
}; | |
int foo() { | |
static Dummy dummy; | |
return dummy.value++; | |
} | |
int main() { | |
foo(); | |
foo(); | |
return 0; | |
} |
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 = 'yy.cc' | |
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" | |
target triple = "x86_64-apple-macosx10.9.0" | |
%struct.Dummy = type { i32 } | |
@g_counter = global i32 0, align 4 | |
@_ZZ3foovE5dummy = internal global %struct.Dummy zeroinitializer, align 4 | |
@_ZGVZ3foovE5dummy = internal global i64 0 | |
; Function Attrs: ssp uwtable | |
define i32 @_Z3foov() #0 { | |
%1 = alloca i8* | |
%2 = alloca i32 | |
%3 = load atomic i8* bitcast (i64* @_ZGVZ3foovE5dummy to i8*) acquire, align 1 | |
%4 = icmp eq i8 %3, 0 | |
br i1 %4, label %5, label %10 | |
; <label>:5 ; preds = %0 | |
%6 = call i32 @__cxa_guard_acquire(i64* @_ZGVZ3foovE5dummy) #1 | |
%7 = icmp ne i32 %6, 0 | |
br i1 %7, label %8, label %10 | |
; <label>:8 ; preds = %5 | |
invoke void @_ZN5DummyC1Ev(%struct.Dummy* @_ZZ3foovE5dummy) | |
to label %9 unwind label %13 | |
; <label>:9 ; preds = %8 | |
call void @__cxa_guard_release(i64* @_ZGVZ3foovE5dummy) #1 | |
br label %10 | |
; <label>:10 ; preds = %9, %5, %0 | |
%11 = load i32* getelementptr inbounds (%struct.Dummy* @_ZZ3foovE5dummy, i32 0, i32 0), align 4 | |
%12 = add nsw i32 %11, 1 | |
store i32 %12, i32* getelementptr inbounds (%struct.Dummy* @_ZZ3foovE5dummy, i32 0, i32 0), align 4 | |
ret i32 %11 | |
; <label>:13 ; preds = %8 | |
%14 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) | |
cleanup | |
%15 = extractvalue { i8*, i32 } %14, 0 | |
store i8* %15, i8** %1 | |
%16 = extractvalue { i8*, i32 } %14, 1 | |
store i32 %16, i32* %2 | |
call void @__cxa_guard_abort(i64* @_ZGVZ3foovE5dummy) #1 | |
br label %17 | |
; <label>:17 ; preds = %13 | |
%18 = load i8** %1 | |
%19 = load i32* %2 | |
%20 = insertvalue { i8*, i32 } undef, i8* %18, 0 | |
%21 = insertvalue { i8*, i32 } %20, i32 %19, 1 | |
resume { i8*, i32 } %21 | |
} | |
; Function Attrs: nounwind | |
declare i32 @__cxa_guard_acquire(i64*) #1 | |
; Function Attrs: ssp uwtable | |
define linkonce_odr void @_ZN5DummyC1Ev(%struct.Dummy* %this) unnamed_addr #0 align 2 { | |
%1 = alloca %struct.Dummy*, align 8 | |
store %struct.Dummy* %this, %struct.Dummy** %1, align 8 | |
%2 = load %struct.Dummy** %1 | |
call void @_ZN5DummyC2Ev(%struct.Dummy* %2) | |
ret void | |
} | |
declare i32 @__gxx_personality_v0(...) | |
; Function Attrs: nounwind | |
declare void @__cxa_guard_abort(i64*) #1 | |
; Function Attrs: nounwind | |
declare void @__cxa_guard_release(i64*) #1 | |
; Function Attrs: ssp uwtable | |
define i32 @main() #0 { | |
%1 = alloca i32, align 4 | |
store i32 0, i32* %1 | |
%2 = call i32 @_Z3foov() | |
%3 = call i32 @_Z3foov() | |
ret i32 0 | |
} | |
; Function Attrs: nounwind ssp uwtable | |
define linkonce_odr void @_ZN5DummyC2Ev(%struct.Dummy* %this) unnamed_addr #2 align 2 { | |
%1 = alloca %struct.Dummy*, align 8 | |
store %struct.Dummy* %this, %struct.Dummy** %1, align 8 | |
%2 = load %struct.Dummy** %1 | |
%3 = getelementptr inbounds %struct.Dummy* %2, i32 0, i32 0 | |
store i32 0, i32* %3, align 4 | |
%4 = load i32* @g_counter, align 4 | |
%5 = add nsw i32 %4, 1 | |
store i32 %5, i32* @g_counter, align 4 | |
ret void | |
} | |
attributes #0 = { ssp uwtable "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" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } | |
attributes #1 = { nounwind } | |
attributes #2 = { nounwind ssp uwtable "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" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } | |
!llvm.ident = !{!0} | |
!0 = metadata !{metadata !"Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn)"} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment