#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 */
typedef struct TYPE_4__ TYPE_2__;
typedef struct TYPE_3__ TYPE_1__;

/* Type definitions */
struct timeval {
  double tv_sec;
  double tv_usec;
};
struct TYPE_4__ {
  double tv_sec;
  double tv_usec;
};
struct TYPE_3__ {
  double tv_sec;
  double tv_usec;
};
struct rusage {
  TYPE_2__ ru_stime;
  TYPE_1__ ru_utime;
};
typedef double clock_t;

/* Variables and functions */
double CLOCKS_PER_SEC;
int /*<<< orphan*/ RUSAGE_SELF;
double clock();
int /*<<< orphan*/ getrusage(int /*<<< orphan*/, struct rusage *);
int /*<<< orphan*/ gettimeofday(struct timeval *, int /*<<< orphan*/ *);
void cpu_util(double pcpu[3]) {
  static struct timeval last;
  static clock_t clast;
  static struct rusage rlast;
  struct timeval temp;
  clock_t ctemp;
  struct rusage rtemp;
  double timediff;
  double userdiff;
  double systemdiff;
  if (pcpu == NULL) {
    gettimeofday(&last, NULL);
    clast = clock();
    getrusage(RUSAGE_SELF, &rlast);
    return;
  }
  gettimeofday(&temp, NULL);
  ctemp = clock();
  getrusage(RUSAGE_SELF, &rtemp);
  timediff = ((temp.tv_sec * 1000000.0 + temp.tv_usec) -
              (last.tv_sec * 1000000.0 + last.tv_usec));
  userdiff = ((rtemp.ru_utime.tv_sec * 1000000.0 + rtemp.ru_utime.tv_usec) -
              (rlast.ru_utime.tv_sec * 1000000.0 + rlast.ru_utime.tv_usec));
  systemdiff = ((rtemp.ru_stime.tv_sec * 1000000.0 + rtemp.ru_stime.tv_usec) -
                (rlast.ru_stime.tv_sec * 1000000.0 + rlast.ru_stime.tv_usec));
  pcpu[0] = (((ctemp - clast) * 1000000.0 / CLOCKS_PER_SEC) / timediff) * 100;
  pcpu[1] = (userdiff / timediff) * 100;
  pcpu[2] = (systemdiff / timediff) * 100;
}


x86 assembly (clang, -O0):
<cpu_util>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    %rdi,-0x8(%rbp)
cmpq   $0x0,-0x8(%rbp)
jne    1180 <cpu_util+0x50>
lea    0x2ef2(%rip),%rdi
xor    %eax,%eax
mov    %eax,%esi
call   1040 <gettimeofday@plt>
mov    $0x0,%al
call   1030 <clock@plt>
movsd  %xmm0,0x2eea(%rip)
mov    0x2e6b(%rip),%rax
mov    (%rax),%edi
lea    0x2ee2(%rip),%rsi
call   1050 <getrusage@plt>
jmp    12ef <cpu_util+0x1bf>
lea    -0x18(%rbp),%rdi
xor    %eax,%eax
mov    %eax,%esi
call   1040 <gettimeofday@plt>
mov    $0x0,%al
call   1030 <clock@plt>
movsd  %xmm0,-0x20(%rbp)
mov    0x2e38(%rip),%rax
mov    (%rax),%edi
lea    -0x40(%rbp),%rsi
call   1050 <getrusage@plt>
movsd  -0x18(%rbp),%xmm0
movsd  -0x10(%rbp),%xmm1
movsd  0xe4b(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  0x2e73(%rip),%xmm1
movsd  0x2e73(%rip),%xmm2
movsd  0xe2b(%rip),%xmm3
mulsd  %xmm3,%xmm1
addsd  %xmm2,%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x30(%rbp),%xmm0
movsd  -0x28(%rbp),%xmm1
movsd  0xe08(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  0x2e58(%rip),%xmm1
movsd  0x2e58(%rip),%xmm2
movsd  0xde8(%rip),%xmm3
mulsd  %xmm3,%xmm1
addsd  %xmm2,%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x40(%rbp),%xmm0
movsd  -0x38(%rbp),%xmm1
movsd  0xdc5(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  0x2e05(%rip),%xmm1
movsd  0x2e05(%rip),%xmm2
movsd  0xda5(%rip),%xmm3
mulsd  %xmm3,%xmm1
addsd  %xmm2,%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x20(%rbp),%xmm0
subsd  0x2dcf(%rip),%xmm0
movsd  0xd7f(%rip),%xmm1
mulsd  %xmm1,%xmm0
mov    0x2d54(%rip),%rax
divsd  (%rax),%xmm0
divsd  -0x48(%rbp),%xmm0
movsd  0xd5b(%rip),%xmm1
mulsd  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movsd  %xmm0,(%rax)
movsd  -0x50(%rbp),%xmm0
divsd  -0x48(%rbp),%xmm0
movsd  0xd3d(%rip),%xmm1
mulsd  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movsd  %xmm0,0x8(%rax)
movsd  -0x58(%rbp),%xmm0
divsd  -0x48(%rbp),%xmm0
movsd  0xd1e(%rip),%xmm1
mulsd  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movsd  %xmm0,0x10(%rax)
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<cpu_util>:
push   %rbx
sub    $0x40,%rsp
test   %rdi,%rdi
je     1239 <cpu_util+0x109>
mov    %rdi,%rbx
lea    0x10(%rsp),%rdi
xor    %esi,%esi
call   1040 <gettimeofday@plt>
xor    %eax,%eax
call   1030 <clock@plt>
movsd  %xmm0,0x8(%rsp)
mov    0x2e77(%rip),%rax
mov    (%rax),%edi
lea    0x20(%rsp),%rsi
call   1050 <getrusage@plt>
movsd  0xe8b(%rip),%xmm2
movsd  0x10(%rsp),%xmm0
mulsd  %xmm2,%xmm0
addsd  0x18(%rsp),%xmm0
movsd  0x2eb3(%rip),%xmm1
mulsd  %xmm2,%xmm1
addsd  0x2eaf(%rip),%xmm1
subsd  %xmm1,%xmm0
movupd 0x30(%rsp),%xmm1
movupd 0x2ebd(%rip),%xmm3
movhpd 0x20(%rsp),%xmm1
movsd  0x38(%rsp),%xmm4
movhpd 0x28(%rsp),%xmm4
movapd 0xe4b(%rip),%xmm5
mulpd  %xmm5,%xmm1
addpd  %xmm4,%xmm1
movhpd 0x2e83(%rip),%xmm3
movsd  0x2e93(%rip),%xmm4
movhpd 0x2e7b(%rip),%xmm4
mulpd  %xmm5,%xmm3
addpd  %xmm4,%xmm3
subpd  %xmm3,%xmm1
movsd  0x8(%rsp),%xmm3
subsd  0x2e51(%rip),%xmm3
mulsd  %xmm2,%xmm3
mov    0x2dde(%rip),%rax
divsd  (%rax),%xmm3
divsd  %xmm0,%xmm3
mulsd  0xdee(%rip),%xmm3
movsd  %xmm3,(%rbx)
unpcklpd %xmm0,%xmm0
divpd  %xmm0,%xmm1
mulpd  0xdf2(%rip),%xmm1
movupd %xmm1,0x8(%rbx)
add    $0x40,%rsp
pop    %rbx
ret
lea    0x2e00(%rip),%rdi
xor    %esi,%esi
call   1040 <gettimeofday@plt>
xor    %eax,%eax
call   1030 <clock@plt>
movsd  %xmm0,0x2dfa(%rip)
mov    0x2d7b(%rip),%rax
mov    (%rax),%edi
lea    0x2df2(%rip),%rsi
add    $0x40,%rsp
pop    %rbx
jmp    1050 <getrusage@plt>

LLVM IR (-O0):
%struct.timeval = type { double, double }
%struct.rusage = type { %struct.TYPE_4__, %struct.TYPE_3__ }
%struct.TYPE_4__ = type { double, double }
%struct.TYPE_3__ = type { double, double }
@cpu_util.last = internal global %struct.timeval zeroinitializer
@cpu_util.clast = internal global double 0.000000e+00
@cpu_util.rlast = internal global %struct.rusage zeroinitializer
@RUSAGE_SELF = global i32 0
@CLOCKS_PER_SEC = global double 0.000000e+00
define void @cpu_util(double* %0) {
%2 = alloca double*
%3 = alloca %struct.timeval
%4 = alloca double
%5 = alloca %struct.rusage
%6 = alloca double
%7 = alloca double
%8 = alloca double
store double* %0, double** %2
%9 = load double*, double** %2
%10 = icmp eq double* %9, null
br i1 %10, label %11, label %16
11: ; preds = %1
%12 = call i32 @gettimeofday(%struct.timeval* @cpu_util.last, i32* null)
%13 = call double (...) @clock()
store double %13, double* @cpu_util.clast
%14 = load i32, i32* @RUSAGE_SELF
%15 = call i32 @getrusage(i32 %14, %struct.rusage* @cpu_util.rlast)
br label %75
16: ; preds = %1
%17 = call i32 @gettimeofday(%struct.timeval* %3, i32* null)
%18 = call double (...) @clock()
store double %18, double* %4
%19 = load i32, i32* @RUSAGE_SELF
%20 = call i32 @getrusage(i32 %19, %struct.rusage* %5)
%21 = getelementptr inbounds %struct.timeval, %struct.timeval* %3, i32 0, i32 0
%22 = load double, double* %21
%23 = getelementptr inbounds %struct.timeval, %struct.timeval* %3, i32 0, i32 1
%24 = load double, double* %23
%25 = call double @llvm.fmuladd.f64(double %22, double 1.000000e+06, double %24)
%26 = load double, double* getelementptr inbounds (%struct.timeval, %struct.timeval* @cpu_util.last, i32 0, i32 0)
%27 = load double, double* getelementptr inbounds (%struct.timeval, %struct.timeval* @cpu_util.last, i32 0, i32 1)
%28 = call double @llvm.fmuladd.f64(double %26, double 1.000000e+06, double %27)
%29 = fsub double %25, %28
store double %29, double* %6
%30 = getelementptr inbounds %struct.rusage, %struct.rusage* %5, i32 0, i32 1
%31 = getelementptr inbounds %struct.TYPE_3__, %struct.TYPE_3__* %30, i32 0, i32 0
%32 = load double, double* %31
%33 = getelementptr inbounds %struct.rusage, %struct.rusage* %5, i32 0, i32 1
%34 = getelementptr inbounds %struct.TYPE_3__, %struct.TYPE_3__* %33, i32 0, i32 1
%35 = load double, double* %34
%36 = call double @llvm.fmuladd.f64(double %32, double 1.000000e+06, double %35)
%37 = load double, double* getelementptr inbounds (%struct.rusage, %struct.rusage* @cpu_util.rlast, i32 0, i32 1, i32 0)
%38 = load double, double* getelementptr inbounds (%struct.rusage, %struct.rusage* @cpu_util.rlast, i32 0, i32 1, i32 1)
%39 = call double @llvm.fmuladd.f64(double %37, double 1.000000e+06, double %38)
%40 = fsub double %36, %39
store double %40, double* %7
%41 = getelementptr inbounds %struct.rusage, %struct.rusage* %5, i32 0, i32 0
%42 = getelementptr inbounds %struct.TYPE_4__, %struct.TYPE_4__* %41, i32 0, i32 0
%43 = load double, double* %42
%44 = getelementptr inbounds %struct.rusage, %struct.rusage* %5, i32 0, i32 0
%45 = getelementptr inbounds %struct.TYPE_4__, %struct.TYPE_4__* %44, i32 0, i32 1
%46 = load double, double* %45
%47 = call double @llvm.fmuladd.f64(double %43, double 1.000000e+06, double %46)
%48 = load double, double* getelementptr inbounds (%struct.rusage, %struct.rusage* @cpu_util.rlast, i32 0, i32 0, i32 0)
%49 = load double, double* getelementptr inbounds (%struct.rusage, %struct.rusage* @cpu_util.rlast, i32 0, i32 0, i32 1)
%50 = call double @llvm.fmuladd.f64(double %48, double 1.000000e+06, double %49)
%51 = fsub double %47, %50
store double %51, double* %8
%52 = load double, double* %4
%53 = load double, double* @cpu_util.clast
%54 = fsub double %52, %53
%55 = fmul double %54, 1.000000e+06
%56 = load double, double* @CLOCKS_PER_SEC
%57 = fdiv double %55, %56
%58 = load double, double* %6
%59 = fdiv double %57, %58
%60 = fmul double %59, 1.000000e+02
%61 = load double*, double** %2
%62 = getelementptr inbounds double, double* %61, i64 0
store double %60, double* %62
%63 = load double, double* %7
%64 = load double, double* %6
%65 = fdiv double %63, %64
%66 = fmul double %65, 1.000000e+02
%67 = load double*, double** %2
%68 = getelementptr inbounds double, double* %67, i64 1
store double %66, double* %68
%69 = load double, double* %8
%70 = load double, double* %6
%71 = fdiv double %69, %70
%72 = fmul double %71, 1.000000e+02
%73 = load double*, double** %2
%74 = getelementptr inbounds double, double* %73, i64 2
store double %72, double* %74
br label %75
75: ; preds = %16, %11
ret void
}

LLVM IR (-O2):
%struct.timeval = type { double, double }
%struct.rusage = type { %struct.TYPE_4__, %struct.TYPE_3__ }
%struct.TYPE_4__ = type { double, double }
%struct.TYPE_3__ = type { double, double }
@cpu_util.last = internal global %struct.timeval zeroinitializer
@cpu_util.clast = internal unnamed_addr global double 0.000000e+00
@cpu_util.rlast = internal global %struct.rusage zeroinitializer
@RUSAGE_SELF = global i32 0
@CLOCKS_PER_SEC = global double 0.000000e+00
define void @cpu_util(double* writeonly %0) {
%2 = alloca %struct.timeval
%3 = alloca %struct.rusage
%4 = bitcast %struct.timeval* %2 to i8*
%5 = bitcast %struct.rusage* %3 to i8*
%6 = icmp eq double* %0, null
br i1 %6, label %7, label %12
7: ; preds = %1
%8 = tail call i32 @gettimeofday(%struct.timeval* @cpu_util.last, i32* null)
%9 = tail call double (...) @clock()
store double %9, double* @cpu_util.clast
%10 = load i32, i32* @RUSAGE_SELF
%11 = tail call i32 @getrusage(i32 %10, %struct.rusage* @cpu_util.rlast)
br label %61
12: ; preds = %1
%13 = call i32 @gettimeofday(%struct.timeval* %2, i32* null)
%14 = tail call double (...) @clock()
%15 = load i32, i32* @RUSAGE_SELF
%16 = call i32 @getrusage(i32 %15, %struct.rusage* %3)
%17 = getelementptr inbounds %struct.timeval, %struct.timeval* %2, i64 0, i32 0
%18 = load double, double* %17
%19 = getelementptr inbounds %struct.timeval, %struct.timeval* %2, i64 0, i32 1
%20 = load double, double* %19
%21 = call double @llvm.fmuladd.f64(double %18, double 1.000000e+06, double %20)
%22 = load double, double* getelementptr inbounds (%struct.timeval, %struct.timeval* @cpu_util.last, i64 0, i32 0)
%23 = load double, double* getelementptr inbounds (%struct.timeval, %struct.timeval* @cpu_util.last, i64 0, i32 1)
%24 = call double @llvm.fmuladd.f64(double %22, double 1.000000e+06, double %23)
%25 = fsub double %21, %24
%26 = getelementptr inbounds %struct.rusage, %struct.rusage* %3, i64 0, i32 1, i32 0
%27 = bitcast double* %26 to <2 x double>*
%28 = load <2 x double>, <2 x double>* %27
%29 = getelementptr inbounds %struct.rusage, %struct.rusage* %3, i64 0, i32 1, i32 1
%30 = load double, double* %29
%31 = load <2 x double>, <2 x double>* bitcast (double* getelementptr inbounds (%struct.rusage, %struct.rusage* @cpu_util.rlast, i64 0, i32 1, i32 0) to <2 x double>*)
%32 = load double, double* getelementptr inbounds (%struct.rusage, %struct.rusage* @cpu_util.rlast, i64 0, i32 1, i32 1)
%33 = getelementptr inbounds %struct.rusage, %struct.rusage* %3, i64 0, i32 0, i32 0
%34 = load double, double* %33
%35 = getelementptr inbounds %struct.rusage, %struct.rusage* %3, i64 0, i32 0, i32 1
%36 = load double, double* %35
%37 = insertelement <2 x double> %28, double %34, i64 1
%38 = insertelement <2 x double> poison, double %30, i64 0
%39 = insertelement <2 x double> %38, double %36, i64 1
%40 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %37, <2 x double> <double 1.000000e+06, double 1.000000e+06>, <2 x double> %39)
%41 = load double, double* getelementptr inbounds (%struct.rusage, %struct.rusage* @cpu_util.rlast, i64 0, i32 0, i32 0)
%42 = load double, double* getelementptr inbounds (%struct.rusage, %struct.rusage* @cpu_util.rlast, i64 0, i32 0, i32 1)
%43 = insertelement <2 x double> %31, double %41, i64 1
%44 = insertelement <2 x double> poison, double %32, i64 0
%45 = insertelement <2 x double> %44, double %42, i64 1
%46 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %43, <2 x double> <double 1.000000e+06, double 1.000000e+06>, <2 x double> %45)
%47 = fsub <2 x double> %40, %46
%48 = load double, double* @cpu_util.clast
%49 = fsub double %14, %48
%50 = fmul double %49, 1.000000e+06
%51 = load double, double* @CLOCKS_PER_SEC
%52 = fdiv double %50, %51
%53 = fdiv double %52, %25
%54 = fmul double %53, 1.000000e+02
store double %54, double* %0
%55 = getelementptr inbounds double, double* %0, i64 1
%56 = insertelement <2 x double> poison, double %25, i64 0
%57 = shufflevector <2 x double> %56, <2 x double> poison, <2 x i32> zeroinitializer
%58 = fdiv <2 x double> %47, %57
%59 = fmul <2 x double> %58, <double 1.000000e+02, double 1.000000e+02>
%60 = bitcast double* %55 to <2 x double>*
store <2 x double> %59, <2 x double>* %60
br label %61
61: ; preds = %12, %7
ret void
}