; ModuleID = 'DynamicCost.cpp'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.9.0"
%struct.mach_timebase_info = type { i32, i32 }
%class.DynamicImplementation = type { %class.DynamicInterface, i64 }
%class.DynamicInterface = type { i32 (...)** }
@.str = private unnamed_addr constant [16 x i8] c"Got value %llu\0A\00", align 1
@.str1 = private unnamed_addr constant [37 x i8] c"Execution time dynamic dispatch: %f\0A\00", align 1
@.str2 = private unnamed_addr constant [25 x i8] c"Execution time crtp: %f\0A\00", align 1
@_ZTV21DynamicImplementation = linkonce_odr unnamed_addr constant [4 x i8*] [i8* null, i8* bitcast ({ i8*, i8*, i8* }* @_ZTI21DynamicImplementation to i8*), i8* bitcast (void (%class.DynamicImplementation*, i64)* @_ZN21DynamicImplementation4tickEy to i8*), i8* bitcast (i64 (%class.DynamicImplementation*)* @_ZN21DynamicImplementation8getValueEv to i8*)]
@_ZTVN10__cxxabiv120__si_class_type_infoE = external global i8*
@_ZTS21DynamicImplementation = linkonce_odr constant [24 x i8] c"21DynamicImplementation\00"
@_ZTVN10__cxxabiv117__class_type_infoE = external global i8*
@_ZTS16DynamicInterface = linkonce_odr constant [19 x i8] c"16DynamicInterface\00"
@_ZTI16DynamicInterface = linkonce_odr unnamed_addr constant { i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8** @_ZTVN10__cxxabiv117__class_type_infoE, i64 2) to i8*), i8* getelementptr inbounds ([19 x i8]* @_ZTS16DynamicInterface, i32 0, i32 0) }
@_ZTI21DynamicImplementation = linkonce_odr unnamed_addr constant { i8*, i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8** @_ZTVN10__cxxabiv120__si_class_type_infoE, i64 2) to i8*), i8* getelementptr inbounds ([24 x i8]* @_ZTS21DynamicImplementation, i32 0, i32 0), i8* bitcast ({ i8*, i8* }* @_ZTI16DynamicInterface to i8*) }
define double @_Z16getExecutionTimePFyvE(i64 ()* nocapture %f) ssp uwtable {
%info = alloca %struct.mach_timebase_info, align 4
%1 = call i32 @mach_timebase_info(%struct.mach_timebase_info* %info)
%2 = icmp eq i32 %1, 0
br i1 %2, label %3, label %19
; <label>:3 ; preds = %0
%4 = call i64 @mach_absolute_time()
%5 = call i64 %f()
%6 = call i64 @mach_absolute_time()
%7 = sub i64 %6, %4
%8 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([16 x i8]* @.str, i64 0, i64 0))
%9 = getelementptr inbounds %struct.mach_timebase_info* %info, i64 0, i32 0
%10 = load i32* %9, align 4, !tbaa !0
%11 = zext i32 %10 to i64
%12 = mul i64 %11, %7
%13 = getelementptr inbounds %struct.mach_timebase_info* %info, i64 0, i32 1
%14 = load i32* %13, align 4, !tbaa !0
%15 = zext i32 %14 to i64
%16 = udiv i64 %12, %15
%17 = uitofp i64 %16 to double
%18 = fdiv double %17, 1.000000e+09
br label %19
; <label>:19 ; preds = %0, %3
%.0 = phi double [ %18, %3 ], [ -1.000000e+00, %0 ]
ret double %.0
}
declare i32 @mach_timebase_info(%struct.mach_timebase_info*)
declare i64 @mach_absolute_time()
declare i32 @printf(i8* nocapture, ...) nounwind
define i64 @_Z11run_dynamicv() ssp uwtable {
%obj = alloca %class.DynamicImplementation, align 8
%1 = getelementptr inbounds %class.DynamicImplementation* %obj, i64 0, i32 0, i32 0
store i32 (...)** bitcast (i8** getelementptr inbounds ([4 x i8*]* @_ZTV21DynamicImplementation, i64 0, i64 2) to i32 (...)**), i32 (...)*** %1, align 8, !tbaa !3
%2 = getelementptr inbounds %class.DynamicImplementation* %obj, i64 0, i32 1
store i64 0, i64* %2, align 8, !tbaa !4
%3 = getelementptr inbounds %class.DynamicImplementation* %obj, i64 0, i32 0
%4 = bitcast %class.DynamicImplementation* %obj to void (%class.DynamicInterface*, i64)***
br label %.preheader
.preheader: ; preds = %._crit_edge.thread, %._crit_edge, %0
%indvars.iv3 = phi i32 [ 0, %0 ], [ %indvars.iv.next4, %._crit_edge ], [ %indvars.iv.next47, %._crit_edge.thread ]
%5 = icmp eq i32 %indvars.iv3, 0
br i1 %5, label %._crit_edge.thread, label %.lr.ph
._crit_edge.thread: ; preds = %.preheader
%indvars.iv.next47 = add i32 %indvars.iv3, 1
br label %.preheader
.lr.ph: ; preds = %.lr.ph, %.preheader
%indvars.iv = phi i64 [ 0, %.preheader ], [ %indvars.iv.next, %.lr.ph ]
%6 = load void (%class.DynamicInterface*, i64)*** %4, align 8, !tbaa !3
%7 = load void (%class.DynamicInterface*, i64)** %6, align 8
call void %7(%class.DynamicInterface* %3, i64 %indvars.iv)
%indvars.iv.next = add i64 %indvars.iv, 1
%lftr.wideiv = trunc i64 %indvars.iv.next to i32
%exitcond = icmp eq i32 %lftr.wideiv, %indvars.iv3
br i1 %exitcond, label %._crit_edge, label %.lr.ph
._crit_edge: ; preds = %.lr.ph
%indvars.iv.next4 = add i32 %indvars.iv3, 1
%exitcond5 = icmp eq i32 %indvars.iv.next4, 40000
br i1 %exitcond5, label %8, label %.preheader
; <label>:8 ; preds = %._crit_edge
%9 = load i64* %2, align 8, !tbaa !4
ret i64 %9
}
define linkonce_odr i64 @_ZN21DynamicImplementation8getValueEv(%class.DynamicImplementation* nocapture %this) unnamed_addr nounwind readonly ssp uwtable align 2 {
%1 = getelementptr inbounds %class.DynamicImplementation* %this, i64 0, i32 1
%2 = load i64* %1, align 8, !tbaa !4
ret i64 %2
}
define i64 @_Z8run_crtpv() nounwind readnone ssp uwtable {
br label %.preheader
.preheader: ; preds = %.thread, %3, %0
%indvars.iv9 = phi i32 [ 0, %0 ], [ %indvars.iv.next10, %3 ], [ %indvars.iv.next1011, %.thread ]
%indvars.iv7 = phi i32 [ -2, %0 ], [ %indvars.iv.next8, %3 ], [ %indvars.iv.next813, %.thread ]
%indvars.iv5 = phi i32 [ -1, %0 ], [ %indvars.iv.next6, %3 ], [ %indvars.iv.next612, %.thread ]
%1 = phi i64 [ 0, %0 ], [ %10, %3 ], [ %1, %.thread ]
%2 = icmp eq i32 %indvars.iv9, 0
br i1 %2, label %.thread, label %3
.thread: ; preds = %.preheader
%indvars.iv.next1011 = add i32 %indvars.iv9, 1
%indvars.iv.next612 = add i32 %indvars.iv5, 1
%indvars.iv.next813 = add i32 %indvars.iv7, 1
br label %.preheader
; <label>:3 ; preds = %.preheader
%4 = zext i32 %indvars.iv5 to i64
%5 = zext i32 %indvars.iv7 to i64
%6 = mul i64 %4, %5
%7 = lshr i64 %6, 1
%8 = zext i32 %indvars.iv5 to i64
%9 = add i64 %1, %8
%10 = add i64 %9, %7
%indvars.iv.next10 = add i32 %indvars.iv9, 1
%indvars.iv.next6 = add i32 %indvars.iv5, 1
%indvars.iv.next8 = add i32 %indvars.iv7, 1
%exitcond = icmp eq i32 %indvars.iv.next10, 40000
br i1 %exitcond, label %11, label %.preheader
; <label>:11 ; preds = %3
ret i64 %10
}
define i32 @main() ssp uwtable {
%obj.i = alloca %class.DynamicImplementation, align 8
%info.i1 = alloca %struct.mach_timebase_info, align 4
%info.i = alloca %struct.mach_timebase_info, align 4
%1 = bitcast %struct.mach_timebase_info* %info.i to i8*
call void @llvm.lifetime.start(i64 8, i8* %1)
%2 = call i32 @mach_timebase_info(%struct.mach_timebase_info* %info.i)
%3 = icmp eq i32 %2, 0
br i1 %3, label %4, label %_Z16getExecutionTimePFyvE.exit
; <label>:4 ; preds = %0
%5 = call i64 @mach_absolute_time()
%6 = bitcast %class.DynamicImplementation* %obj.i to i8*
call void @llvm.lifetime.start(i64 16, i8* %6)
%7 = getelementptr inbounds %class.DynamicImplementation* %obj.i, i64 0, i32 0, i32 0
store i32 (...)** bitcast (i8** getelementptr inbounds ([4 x i8*]* @_ZTV21DynamicImplementation, i64 0, i64 2) to i32 (...)**), i32 (...)*** %7, align 8, !tbaa !3
%8 = getelementptr inbounds %class.DynamicImplementation* %obj.i, i64 0, i32 1
store i64 0, i64* %8, align 8, !tbaa !4
%9 = getelementptr inbounds %class.DynamicImplementation* %obj.i, i64 0, i32 0
%10 = bitcast %class.DynamicImplementation* %obj.i to void (%class.DynamicInterface*, i64)***
br label %.preheader.i
.preheader.i: ; preds = %._crit_edge.i, %.preheader.i, %4
%indvars.iv3.i = phi i32 [ 0, %4 ], [ %indvars.iv.next4.i, %._crit_edge.i ], [ 1, %.preheader.i ]
%11 = icmp eq i32 %indvars.iv3.i, 0
br i1 %11, label %.preheader.i, label %.lr.ph.i
.lr.ph.i: ; preds = %.lr.ph.i, %.preheader.i
%indvars.iv.i = phi i64 [ 0, %.preheader.i ], [ %indvars.iv.next.i, %.lr.ph.i ]
%12 = load void (%class.DynamicInterface*, i64)*** %10, align 8, !tbaa !3
%13 = load void (%class.DynamicInterface*, i64)** %12, align 8
call void %13(%class.DynamicInterface* %9, i64 %indvars.iv.i)
%indvars.iv.next.i = add i64 %indvars.iv.i, 1
%lftr.wideiv = trunc i64 %indvars.iv.next.i to i32
%exitcond = icmp eq i32 %lftr.wideiv, %indvars.iv3.i
br i1 %exitcond, label %._crit_edge.i, label %.lr.ph.i
._crit_edge.i: ; preds = %.lr.ph.i
%indvars.iv.next4.i = add i32 %indvars.iv3.i, 1
%exitcond5.i = icmp eq i32 %indvars.iv.next4.i, 40000
br i1 %exitcond5.i, label %_Z11run_dynamicv.exit, label %.preheader.i
_Z11run_dynamicv.exit: ; preds = %._crit_edge.i
call void @llvm.lifetime.end(i64 16, i8* %6)
%14 = call i64 @mach_absolute_time()
%15 = sub i64 %14, %5
%16 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([16 x i8]* @.str, i64 0, i64 0))
%17 = getelementptr inbounds %struct.mach_timebase_info* %info.i, i64 0, i32 0
%18 = load i32* %17, align 4, !tbaa !0
%19 = zext i32 %18 to i64
%20 = mul i64 %19, %15
%21 = getelementptr inbounds %struct.mach_timebase_info* %info.i, i64 0, i32 1
%22 = load i32* %21, align 4, !tbaa !0
%23 = zext i32 %22 to i64
%24 = udiv i64 %20, %23
%25 = uitofp i64 %24 to double
%26 = fdiv double %25, 1.000000e+09
br label %_Z16getExecutionTimePFyvE.exit
_Z16getExecutionTimePFyvE.exit: ; preds = %0, %_Z11run_dynamicv.exit
%.0.i = phi double [ %26, %_Z11run_dynamicv.exit ], [ -1.000000e+00, %0 ]
call void @llvm.lifetime.end(i64 8, i8* %1)
%27 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([37 x i8]* @.str1, i64 0, i64 0), double %.0.i)
%28 = bitcast %struct.mach_timebase_info* %info.i1 to i8*
call void @llvm.lifetime.start(i64 8, i8* %28)
%29 = call i32 @mach_timebase_info(%struct.mach_timebase_info* %info.i1)
%30 = icmp eq i32 %29, 0
br i1 %30, label %31, label %_Z16getExecutionTimePFyvE.exit3
; <label>:31 ; preds = %_Z16getExecutionTimePFyvE.exit
%32 = call i64 @mach_absolute_time()
%33 = call i64 @mach_absolute_time()
%34 = sub i64 %33, %32
%35 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([16 x i8]* @.str, i64 0, i64 0))
%36 = getelementptr inbounds %struct.mach_timebase_info* %info.i1, i64 0, i32 0
%37 = load i32* %36, align 4, !tbaa !0
%38 = zext i32 %37 to i64
%39 = mul i64 %38, %34
%40 = getelementptr inbounds %struct.mach_timebase_info* %info.i1, i64 0, i32 1
%41 = load i32* %40, align 4, !tbaa !0
%42 = zext i32 %41 to i64
%43 = udiv i64 %39, %42
%44 = uitofp i64 %43 to double
%45 = fdiv double %44, 1.000000e+09
br label %_Z16getExecutionTimePFyvE.exit3
_Z16getExecutionTimePFyvE.exit3: ; preds = %_Z16getExecutionTimePFyvE.exit, %31
%.0.i2 = phi double [ %45, %31 ], [ -1.000000e+00, %_Z16getExecutionTimePFyvE.exit ]
call void @llvm.lifetime.end(i64 8, i8* %28)
%46 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([25 x i8]* @.str2, i64 0, i64 0), double %.0.i2)
ret i32 0
}
define linkonce_odr void @_ZN21DynamicImplementation4tickEy(%class.DynamicImplementation* nocapture %this, i64 %n) unnamed_addr nounwind ssp uwtable align 2 {
%1 = getelementptr inbounds %class.DynamicImplementation* %this, i64 0, i32 1
%2 = load i64* %1, align 8, !tbaa !4
%3 = add i64 %2, %n
store i64 %3, i64* %1, align 8, !tbaa !4
ret void
}
declare void @llvm.lifetime.start(i64, i8* nocapture) nounwind
declare void @llvm.lifetime.end(i64, i8* nocapture) nounwind
!0 = metadata !{metadata !"int", metadata !1}
!1 = metadata !{metadata !"omnipotent char", metadata !2}
!2 = metadata !{metadata !"Simple C/C++ TBAA"}
!3 = metadata !{metadata !"vtable pointer", metadata !2}
!4 = metadata !{metadata !"long long", metadata !1}