#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 {
  scalar_t__ tv_sec;
  scalar_t__ tv_usec;
};

/* Variables and functions */
int /*<<< orphan*/ gettimeofday(struct timeval *, int /*<<< orphan*/ *);
int /*<<< orphan*/ timersub(struct timeval *, struct timeval *,
                            struct timeval *);
int micro_elapsed_time(struct timeval *timer) {
  static struct timeval lap;
  struct timeval dif;
  gettimeofday(&lap, NULL);
  if (timer->tv_sec > 0 || timer->tv_usec > 0)
    timersub(&lap, timer, &dif);
  else
    dif.tv_sec = dif.tv_usec = 0;
  *timer = lap;
  return (dif.tv_sec * 1000000 + dif.tv_usec);
}


x86 assembly (clang, -O0):
<micro_elapsed_time>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
lea    0x2f05(%rip),%rdi
xor    %eax,%eax
mov    %eax,%esi
call   1030 <gettimeofday@plt>
mov    -0x8(%rbp),%rax
cmpq   $0x0,(%rax)
jg     1159 <micro_elapsed_time+0x39>
mov    -0x8(%rbp),%rax
cmpq   $0x0,0x8(%rax)
jle    1172 <micro_elapsed_time+0x52>
mov    -0x8(%rbp),%rsi
lea    0x2ed4(%rip),%rdi
lea    -0x18(%rbp),%rdx
call   1040 <timersub@plt>
jmp    1182 <micro_elapsed_time+0x62>
movq   $0x0,-0x10(%rbp)
movq   $0x0,-0x18(%rbp)
mov    -0x8(%rbp),%rax
mov    0x2eab(%rip),%rcx
mov    %rcx,(%rax)
mov    0x2ea9(%rip),%rcx
mov    %rcx,0x8(%rax)
imul   $0xf4240,-0x18(%rbp),%rax
add    -0x10(%rbp),%rax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<micro_elapsed_time>:
push   %r14
push   %rbx
sub    $0x18,%rsp
mov    %rdi,%r14
lea    0x2f07(%rip),%rdi
xor    %ebx,%ebx
xor    %esi,%esi
call   1030 <gettimeofday@plt>
cmpq   $0x0,(%r14)
jg     1147 <micro_elapsed_time+0x27>
cmpq   $0x0,0x8(%r14)
jle    1167 <micro_elapsed_time+0x47>
lea    0x2eea(%rip),%rdi
lea    0x8(%rsp),%rdx
mov    %r14,%rsi
call   1040 <timersub@plt>
imul   $0xf4240,0x8(%rsp),%ebx
add    0x10(%rsp),%ebx
movups 0x2eca(%rip),%xmm0
movups %xmm0,(%r14)
mov    %ebx,%eax
add    $0x18,%rsp
pop    %rbx
pop    %r14
ret

LLVM IR (-O0):
%struct.timeval = type { i64, i64 }
@micro_elapsed_time.lap = internal global %struct.timeval zeroinitializer
define i32 @micro_elapsed_time(%struct.timeval* %0) {
%2 = alloca %struct.timeval*
%3 = alloca %struct.timeval
store %struct.timeval* %0, %struct.timeval** %2
%4 = call i32 @gettimeofday(%struct.timeval* @micro_elapsed_time.lap, i32* null)
%5 = load %struct.timeval*, %struct.timeval** %2
%6 = getelementptr inbounds %struct.timeval, %struct.timeval* %5, i32 0, i32 0
%7 = load i64, i64* %6
%8 = icmp sgt i64 %7, 0
br i1 %8, label %14, label %9
9: ; preds = %1
%10 = load %struct.timeval*, %struct.timeval** %2
%11 = getelementptr inbounds %struct.timeval, %struct.timeval* %10, i32 0, i32 1
%12 = load i64, i64* %11
%13 = icmp sgt i64 %12, 0
br i1 %13, label %14, label %17
14: ; preds = %9, %1
%15 = load %struct.timeval*, %struct.timeval** %2
%16 = call i32 @timersub(%struct.timeval* @micro_elapsed_time.lap, %struct.timeval* %15, %struct.timeval* %3)
br label %20
17: ; preds = %9
%18 = getelementptr inbounds %struct.timeval, %struct.timeval* %3, i32 0, i32 1
store i64 0, i64* %18
%19 = getelementptr inbounds %struct.timeval, %struct.timeval* %3, i32 0, i32 0
store i64 0, i64* %19
br label %20
20: ; preds = %17, %14
%21 = load %struct.timeval*, %struct.timeval** %2
%22 = bitcast %struct.timeval* %21 to i8*
%23 = getelementptr inbounds %struct.timeval, %struct.timeval* %3, i32 0, i32 0
%24 = load i64, i64* %23
%25 = mul nsw i64 %24, 1000000
%26 = getelementptr inbounds %struct.timeval, %struct.timeval* %3, i32 0, i32 1
%27 = load i64, i64* %26
%28 = add nsw i64 %25, %27
%29 = trunc i64 %28 to i32
ret i32 %29
}

LLVM IR (-O2):
%struct.timeval = type { i64, i64 }
@micro_elapsed_time.lap = internal global %struct.timeval zeroinitializer
define i32 @micro_elapsed_time(%struct.timeval* %0) {
%2 = alloca %struct.timeval
%3 = bitcast %struct.timeval* %2 to i8*
%4 = tail call i32 @gettimeofday(%struct.timeval* @micro_elapsed_time.lap, i32* null)
%5 = getelementptr inbounds %struct.timeval, %struct.timeval* %0, i64 0, i32 0
%6 = load i64, i64* %5
%7 = icmp sgt i64 %6, 0
br i1 %7, label %12, label %8
8: ; preds = %1
%9 = getelementptr inbounds %struct.timeval, %struct.timeval* %0, i64 0, i32 1
%10 = load i64, i64* %9
%11 = icmp sgt i64 %10, 0
br i1 %11, label %12, label %21
12: ; preds = %8, %1
%13 = call i32 @timersub(%struct.timeval* @micro_elapsed_time.lap, %struct.timeval* %0, %struct.timeval* %2)
%14 = getelementptr inbounds %struct.timeval, %struct.timeval* %2, i64 0, i32 0
%15 = load i64, i64* %14
%16 = getelementptr inbounds %struct.timeval, %struct.timeval* %2, i64 0, i32 1
%17 = load i64, i64* %16
%18 = mul i64 %15, 1000000
%19 = add nsw i64 %18, %17
%20 = trunc i64 %19 to i32
br label %21
21: ; preds = %8, %12
%22 = phi i32 [ %20, %12 ], [ 0, %8 ]
%23 = bitcast %struct.timeval* %0 to i8*
ret i32 %22
}