#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */
struct timeval {
  double tv_usec;
  scalar_t__ tv_sec;
};

/* Variables and functions */
int /*<<< orphan*/ gettimeofday(struct timeval *, int /*<<< orphan*/ *);
double pbc_get_time(void) {
  static struct timeval last_tv, tv;
  static int first = 1;
  static double res = 0;
  if (first) {
    gettimeofday(&last_tv, NULL);
    first = 0;
    return 0;
  } else {
    gettimeofday(&tv, NULL);
    res += tv.tv_sec - last_tv.tv_sec;
    res += (tv.tv_usec - last_tv.tv_usec) / 1000000.0;
    last_tv = tv;
    return res;
  }
}


x86 assembly (clang, -O0):
<pbc_get_time>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
cmpl   $0x0,0x2f09(%rip)
je     114c <pbc_get_time+0x3c>
lea    0x2f0c(%rip),%rdi
xor    %eax,%eax
mov    %eax,%esi
call   1030 <gettimeofday@plt>
movl   $0x0,0x2ee9(%rip)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    11d4 <pbc_get_time+0xc4>
lea    0x2ef5(%rip),%rdi
xor    %eax,%eax
mov    %eax,%esi
call   1030 <gettimeofday@plt>
mov    0x2eed(%rip),%rax
sub    0x2ed6(%rip),%rax
cvtsi2sd %rax,%xmm0
addsd  0x2ee1(%rip),%xmm0
movsd  %xmm0,0x2ed9(%rip)
movsd  0x2ec1(%rip),%xmm0
subsd  0x2ea9(%rip),%xmm0
movsd  0xe69(%rip),%xmm1
divsd  %xmm1,%xmm0
addsd  0x2eb5(%rip),%xmm0
movsd  %xmm0,0x2ead(%rip)
mov    0x2e96(%rip),%rax
mov    %rax,0x2e7f(%rip)
mov    0x2e90(%rip),%rax
mov    %rax,0x2e79(%rip)
movsd  0x2e89(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<pbc_get_time>:
push   %rax
cmpb   $0x0,0x2f38(%rip)
je     1177 <pbc_get_time+0x67>
lea    0x2f1f(%rip),%rdi
xor    %esi,%esi
call   1030 <gettimeofday@plt>
mov    0x2f19(%rip),%rax
sub    0x2f02(%rip),%rax
cvtsi2sd %rax,%xmm1
addsd  0x2f15(%rip),%xmm1
movsd  0x2ef5(%rip),%xmm0
subsd  0x2edd(%rip),%xmm0
divsd  0xea5(%rip),%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x2ef1(%rip)
movups 0x2ed2(%rip),%xmm1
movups %xmm1,0x2ebb(%rip)
pop    %rax
ret
lea    0x2eb2(%rip),%rdi
xor    %esi,%esi
call   1030 <gettimeofday@plt>
movb   $0x1,0x2ec4(%rip)
xorps  %xmm0,%xmm0
pop    %rax
ret

LLVM IR (-O0):
%struct.timeval = type { double, i64 }
@pbc_get_time.last_tv = internal global %struct.timeval zeroinitializer
@pbc_get_time.tv = internal global %struct.timeval zeroinitializer
@pbc_get_time.first = internal global i32 1
@pbc_get_time.res = internal global double 0.000000e+00
define double @pbc_get_time() {
%1 = alloca double
%2 = load i32, i32* @pbc_get_time.first
%3 = icmp ne i32 %2, 0
br i1 %3, label %4, label %6
4: ; preds = %0
%5 = call i32 @gettimeofday(%struct.timeval* @pbc_get_time.last_tv, i32* null)
store i32 0, i32* @pbc_get_time.first
store double 0.000000e+00, double* %1
br label %21
6: ; preds = %0
%7 = call i32 @gettimeofday(%struct.timeval* @pbc_get_time.tv, i32* null)
%8 = load i64, i64* getelementptr inbounds (%struct.timeval, %struct.timeval* @pbc_get_time.tv, i32 0, i32 1)
%9 = load i64, i64* getelementptr inbounds (%struct.timeval, %struct.timeval* @pbc_get_time.last_tv, i32 0, i32 1)
%10 = sub nsw i64 %8, %9
%11 = sitofp i64 %10 to double
%12 = load double, double* @pbc_get_time.res
%13 = fadd double %12, %11
store double %13, double* @pbc_get_time.res
%14 = load double, double* getelementptr inbounds (%struct.timeval, %struct.timeval* @pbc_get_time.tv, i32 0, i32 0)
%15 = load double, double* getelementptr inbounds (%struct.timeval, %struct.timeval* @pbc_get_time.last_tv, i32 0, i32 0)
%16 = fsub double %14, %15
%17 = fdiv double %16, 1.000000e+06
%18 = load double, double* @pbc_get_time.res
%19 = fadd double %18, %17
store double %19, double* @pbc_get_time.res
%20 = load double, double* @pbc_get_time.res
store double %20, double* %1
br label %21
21: ; preds = %6, %4
%22 = load double, double* %1
ret double %22
}

LLVM IR (-O2):
%struct.timeval = type { double, i64 }
@pbc_get_time.last_tv = internal global %struct.timeval zeroinitializer
@pbc_get_time.tv = internal global %struct.timeval zeroinitializer
@pbc_get_time.first = internal unnamed_addr global i1 false
@pbc_get_time.res = internal unnamed_addr global double 0.000000e+00
define double @pbc_get_time() {
%1 = load i1, i1* @pbc_get_time.first
br i1 %1, label %4, label %2
2: ; preds = %0
%3 = tail call i32 @gettimeofday(%struct.timeval* @pbc_get_time.last_tv, i32* null)
store i1 true, i1* @pbc_get_time.first
br label %17
4: ; preds = %0
%5 = tail call i32 @gettimeofday(%struct.timeval* @pbc_get_time.tv, i32* null)
%6 = load i64, i64* getelementptr inbounds (%struct.timeval, %struct.timeval* @pbc_get_time.tv, i64 0, i32 1)
%7 = load i64, i64* getelementptr inbounds (%struct.timeval, %struct.timeval* @pbc_get_time.last_tv, i64 0, i32 1)
%8 = sub nsw i64 %6, %7
%9 = sitofp i64 %8 to double
%10 = load double, double* @pbc_get_time.res
%11 = fadd double %10, %9
%12 = load double, double* getelementptr inbounds (%struct.timeval, %struct.timeval* @pbc_get_time.tv, i64 0, i32 0)
%13 = load double, double* getelementptr inbounds (%struct.timeval, %struct.timeval* @pbc_get_time.last_tv, i64 0, i32 0)
%14 = fsub double %12, %13
%15 = fdiv double %14, 1.000000e+06
%16 = fadd double %11, %15
store double %16, double* @pbc_get_time.res
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 dereferenceable(16) bitcast (%struct.timeval* @pbc_get_time.last_tv to i8*), i8* align 8 dereferenceable(16) bitcast (%struct.timeval* @pbc_get_time.tv to i8*), i64 16, i1 false)
br label %17
17: ; preds = %4, %2
%18 = phi double [ 0.000000e+00, %2 ], [ %16, %4 ]
ret double %18
}