#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 timespec {
  int tv_sec;
  int tv_nsec;
};
struct kdtree {
  int dummy;
};

/* Variables and functions */
int /*<<< orphan*/ CLOCK_MONOTONIC;
int /*<<< orphan*/ clock_gettime(int /*<<< orphan*/, struct timespec *);
int /*<<< orphan*/ exit(int);
int /*<<< orphan*/ kdtree_destroy(struct kdtree *);
int /*<<< orphan*/ kdtree_dump(struct kdtree *);
struct kdtree *kdtree_init(int);
int /*<<< orphan*/ kdtree_insert(struct kdtree *, double *);
int /*<<< orphan*/ kdtree_knn_dump(struct kdtree *);
int /*<<< orphan*/ kdtree_knn_search(struct kdtree *, double *, int);
int /*<<< orphan*/ kdtree_rebuild(struct kdtree *);
double *malloc(int);
int /*<<< orphan*/ printf(char *, ...);
double rd();
int /*<<< orphan*/ srandom(int /*<<< orphan*/);
int /*<<< orphan*/ time(int /*<<< orphan*/ *);
int main(void) {
  int i, j, dim = 2;
  struct timespec start, end;
  struct kdtree *tree = kdtree_init(dim);
  if (tree == NULL) {
    exit(-1);
  }
  double sample1[] = {6.27, 5.50};
  double sample2[] = {1.24, -2.86};
  double sample3[] = {17.05, -12.79};
  double sample4[] = {-6.88, -5.40};
  double sample5[] = {-2.96, -0.50};
  double sample6[] = {7.75, -22.68};
  double sample7[] = {10.80, -5.03};
  double sample8[] = {-4.60, -10.55};
  double sample9[] = {-4.96, 12.61};
  double sample10[] = {1.75, 12.26};
  double sample11[] = {15.31, -13.16};
  double sample12[] = {7.83, 15.70};
  double sample13[] = {14.63, -0.35};
  kdtree_insert(tree, sample1);
  kdtree_insert(tree, sample2);
  kdtree_insert(tree, sample3);
  kdtree_insert(tree, sample4);
  kdtree_insert(tree, sample5);
  kdtree_insert(tree, sample6);
  kdtree_insert(tree, sample7);
  kdtree_insert(tree, sample8);
  kdtree_insert(tree, sample9);
  kdtree_insert(tree, sample10);
  kdtree_insert(tree, sample11);
  kdtree_insert(tree, sample12);
  kdtree_insert(tree, sample13);
  kdtree_rebuild(tree);
  kdtree_dump(tree);
  int k = 3;
  double target[] = {-1, -5};
  kdtree_knn_search(tree, target, k);
  printf("%d nearest neighbors of sample(", k);
  for (i = 0; i < dim; i++) {
    if (i == dim - 1) {
      printf("%.2lf):\n", target[i]);
    } else {
      printf("%.2lf, ", target[i]);
    }
  }
  kdtree_knn_dump(tree);
  kdtree_destroy(tree);
  printf("\n>>> Performance test: kNN search for %d samples\n\n", 1024 * 1024);
  dim = 12;
  tree = kdtree_init(dim);
  if (tree == NULL) {
    exit(-1);
  }
  printf("Add %d nodes...\n", 1024 * 1024);
  srandom(time(NULL));
  clock_gettime(CLOCK_MONOTONIC, &start);
  for (i = 0; i < 1024 * 1024; i++) {
    double *sample = malloc(dim * sizeof(double));
    for (j = 0; j < dim; j++) {
      sample[j] = rd();
    }
    kdtree_insert(tree, sample);
  }
  clock_gettime(CLOCK_MONOTONIC, &end);
  printf("time span: %ldms\n", (end.tv_sec - start.tv_sec) * 1000 +
                                   (end.tv_nsec - start.tv_nsec) / 1000000);
  printf("Build KD tree...\n");
  clock_gettime(CLOCK_MONOTONIC, &start);
  kdtree_rebuild(tree);
  clock_gettime(CLOCK_MONOTONIC, &end);
  printf("time span: %ldms\n", (end.tv_sec - start.tv_sec) * 1000 +
                                   (end.tv_nsec - start.tv_nsec) / 1000000);
  k = 20;
  srandom(time(NULL));
  double *t = malloc(dim * sizeof(double));
  for (i = 0; i < dim; i++) {
    t[i] = rd();
  }
  printf("Search KD tree...\n");
  srandom(time(NULL));
  clock_gettime(CLOCK_MONOTONIC, &start);
  kdtree_knn_search(tree, t, k);
  clock_gettime(CLOCK_MONOTONIC, &end);
  printf("time span: %ldms\n", (end.tv_sec - start.tv_sec) * 1000 +
                                   (end.tv_nsec - start.tv_nsec) / 1000000);
  printf("%d nearest neighbors of sample(", k);
  for (i = 0; i < dim; i++) {
    if (i == dim - 1) {
      printf("%.2lf):\n", t[i]);
    } else {
      printf("%.2lf, ", t[i]);
    }
  }
  kdtree_knn_dump(tree);
  printf("Destroy KD tree...\n");
  srandom(time(NULL));
  clock_gettime(CLOCK_MONOTONIC, &start);
  kdtree_destroy(tree);
  clock_gettime(CLOCK_MONOTONIC, &end);
  printf("time span: %ldms\n", (end.tv_sec - start.tv_sec) * 1000 +
                                   (end.tv_nsec - start.tv_nsec) / 1000000);
  return 0;
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x130,%rsp
movl   $0x0,-0x4(%rbp)
movl   $0x2,-0x10(%rbp)
mov    -0x10(%rbp),%edi
call   1080 <kdtree_init@plt>
mov    %rax,-0x28(%rbp)
cmpq   $0x0,-0x28(%rbp)
jne    121a <main+0x3a>
mov    $0xffffffff,%edi
call   10f0 <exit@plt>
mov    0xddf(%rip),%rax
mov    %rax,-0x40(%rbp)
mov    0xddc(%rip),%rax
mov    %rax,-0x38(%rbp)
mov    0xdd9(%rip),%rax
mov    %rax,-0x50(%rbp)
mov    0xdd6(%rip),%rax
mov    %rax,-0x48(%rbp)
mov    0xdd3(%rip),%rax
mov    %rax,-0x60(%rbp)
mov    0xdd0(%rip),%rax
mov    %rax,-0x58(%rbp)
mov    0xdcd(%rip),%rax
mov    %rax,-0x70(%rbp)
mov    0xdca(%rip),%rax
mov    %rax,-0x68(%rbp)
mov    0xdc7(%rip),%rax
mov    %rax,-0x80(%rbp)
mov    0xdc4(%rip),%rax
mov    %rax,-0x78(%rbp)
mov    0xdc1(%rip),%rax
mov    %rax,-0x90(%rbp)
mov    0xdbb(%rip),%rax
mov    %rax,-0x88(%rbp)
mov    0xdb5(%rip),%rax
mov    %rax,-0xa0(%rbp)
mov    0xdaf(%rip),%rax
mov    %rax,-0x98(%rbp)
mov    0xda9(%rip),%rax
mov    %rax,-0xb0(%rbp)
mov    0xda3(%rip),%rax
mov    %rax,-0xa8(%rbp)
mov    0xd9d(%rip),%rax
mov    %rax,-0xc0(%rbp)
mov    0xd97(%rip),%rax
mov    %rax,-0xb8(%rbp)
mov    0xd91(%rip),%rax
mov    %rax,-0xd0(%rbp)
mov    0xd8b(%rip),%rax
mov    %rax,-0xc8(%rbp)
mov    0xd85(%rip),%rax
mov    %rax,-0xe0(%rbp)
mov    0xd7f(%rip),%rax
mov    %rax,-0xd8(%rbp)
mov    0xd79(%rip),%rax
mov    %rax,-0xf0(%rbp)
mov    0xd73(%rip),%rax
mov    %rax,-0xe8(%rbp)
mov    0xd6d(%rip),%rax
mov    %rax,-0x100(%rbp)
mov    0xd67(%rip),%rax
mov    %rax,-0xf8(%rbp)
mov    -0x28(%rbp),%rdi
lea    -0x40(%rbp),%rsi
call   1100 <kdtree_insert@plt>
mov    -0x28(%rbp),%rdi
lea    -0x50(%rbp),%rsi
call   1100 <kdtree_insert@plt>
mov    -0x28(%rbp),%rdi
lea    -0x60(%rbp),%rsi
call   1100 <kdtree_insert@plt>
mov    -0x28(%rbp),%rdi
lea    -0x70(%rbp),%rsi
call   1100 <kdtree_insert@plt>
mov    -0x28(%rbp),%rdi
lea    -0x80(%rbp),%rsi
call   1100 <kdtree_insert@plt>
mov    -0x28(%rbp),%rdi
lea    -0x90(%rbp),%rsi
call   1100 <kdtree_insert@plt>
mov    -0x28(%rbp),%rdi
lea    -0xa0(%rbp),%rsi
call   1100 <kdtree_insert@plt>
mov    -0x28(%rbp),%rdi
lea    -0xb0(%rbp),%rsi
call   1100 <kdtree_insert@plt>
mov    -0x28(%rbp),%rdi
lea    -0xc0(%rbp),%rsi
call   1100 <kdtree_insert@plt>
mov    -0x28(%rbp),%rdi
lea    -0xd0(%rbp),%rsi
call   1100 <kdtree_insert@plt>
mov    -0x28(%rbp),%rdi
lea    -0xe0(%rbp),%rsi
call   1100 <kdtree_insert@plt>
mov    -0x28(%rbp),%rdi
lea    -0xf0(%rbp),%rsi
call   1100 <kdtree_insert@plt>
mov    -0x28(%rbp),%rdi
lea    -0x100(%rbp),%rsi
call   1100 <kdtree_insert@plt>
mov    -0x28(%rbp),%rdi
call   10d0 <kdtree_rebuild@plt>
mov    -0x28(%rbp),%rdi
call   1030 <kdtree_dump@plt>
movl   $0x3,-0x104(%rbp)
mov    0xc84(%rip),%rax
mov    %rax,-0x120(%rbp)
mov    0xc7e(%rip),%rax
mov    %rax,-0x118(%rbp)
mov    -0x28(%rbp),%rdi
lea    -0x120(%rbp),%rsi
mov    -0x104(%rbp),%edx
call   10a0 <kdtree_knn_search@plt>
mov    -0x104(%rbp),%esi
lea    0xc5c(%rip),%rdi
mov    $0x0,%al
call   1070 <printf@plt>
movl   $0x0,-0x8(%rbp)
mov    -0x8(%rbp),%eax
cmp    -0x10(%rbp),%eax
jge    14fd <main+0x31d>
mov    -0x8(%rbp),%eax
mov    -0x10(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jne    14cf <main+0x2ef>
movslq -0x8(%rbp),%rax
movsd  -0x120(%rbp,%rax,8),%xmm0
ff ff
lea    0xc3d(%rip),%rdi
mov    $0x1,%al
call   1070 <printf@plt>
jmp    14ea <main+0x30a>
movslq -0x8(%rbp),%rax
movsd  -0x120(%rbp,%rax,8),%xmm0
ff ff
lea    0xc26(%rip),%rdi
mov    $0x1,%al
call   1070 <printf@plt>
jmp    14ef <main+0x30f>
mov    -0x8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x8(%rbp)
jmp    1492 <main+0x2b2>
mov    -0x28(%rbp),%rdi
call   10e0 <kdtree_knn_dump@plt>
mov    -0x28(%rbp),%rdi
call   1060 <kdtree_destroy@plt>
lea    0xbfb(%rip),%rdi
mov    $0x100000,%esi
mov    $0x0,%al
call   1070 <printf@plt>
movl   $0xc,-0x10(%rbp)
mov    -0x10(%rbp),%edi
call   1080 <kdtree_init@plt>
mov    %rax,-0x28(%rbp)
cmpq   $0x0,-0x28(%rbp)
jne    154a <main+0x36a>
mov    $0xffffffff,%edi
call   10f0 <exit@plt>
lea    0xbf3(%rip),%rdi
mov    $0x100000,%esi
mov    $0x0,%al
call   1070 <printf@plt>
xor    %eax,%eax
mov    %eax,%edi
call   1090 <time@plt>
mov    %eax,%edi
call   1040 <srandom@plt>
mov    0x2a74(%rip),%rax
mov    (%rax),%edi
lea    -0x18(%rbp),%rsi
call   1050 <clock_gettime@plt>
movl   $0x0,-0x8(%rbp)
cmpl   $0x100000,-0x8(%rbp)
jge    15ff <main+0x41f>
movslq -0x10(%rbp),%rax
shl    $0x3,%rax
mov    %eax,%edi
call   10c0 <malloc@plt>
mov    %rax,-0x128(%rbp)
movl   $0x0,-0xc(%rbp)
mov    -0xc(%rbp),%eax
cmp    -0x10(%rbp),%eax
jge    15e1 <main+0x401>
mov    $0x0,%al
call   10b0 <rd@plt>
mov    -0x128(%rbp),%rax
movslq -0xc(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc(%rbp)
jmp    15b0 <main+0x3d0>
mov    -0x28(%rbp),%rdi
mov    -0x128(%rbp),%rsi
call   1100 <kdtree_insert@plt>
mov    -0x8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x8(%rbp)
jmp    1586 <main+0x3a6>
mov    0x29e2(%rip),%rax
mov    (%rax),%edi
lea    -0x20(%rbp),%rsi
call   1050 <clock_gettime@plt>
mov    -0x20(%rbp),%eax
sub    -0x18(%rbp),%eax
imul   $0x3e8,%eax,%esi
mov    -0x1c(%rbp),%eax
sub    -0x14(%rbp),%eax
mov    $0xf4240,%ecx
cltd
idiv   %ecx
add    %eax,%esi
lea    0xb21(%rip),%rdi
mov    $0x0,%al
call   1070 <printf@plt>
lea    0xb25(%rip),%rdi
mov    $0x0,%al
call   1070 <printf@plt>
mov    0x2998(%rip),%rax
mov    (%rax),%edi
lea    -0x18(%rbp),%rsi
call   1050 <clock_gettime@plt>
mov    -0x28(%rbp),%rdi
call   10d0 <kdtree_rebuild@plt>
mov    0x297d(%rip),%rax
mov    (%rax),%edi
lea    -0x20(%rbp),%rsi
call   1050 <clock_gettime@plt>
mov    -0x20(%rbp),%eax
sub    -0x18(%rbp),%eax
imul   $0x3e8,%eax,%esi
mov    -0x1c(%rbp),%eax
sub    -0x14(%rbp),%eax
mov    $0xf4240,%ecx
cltd
idiv   %ecx
add    %eax,%esi
lea    0xabc(%rip),%rdi
mov    $0x0,%al
call   1070 <printf@plt>
movl   $0x14,-0x104(%rbp)
xor    %eax,%eax
mov    %eax,%edi
call   1090 <time@plt>
mov    %eax,%edi
call   1040 <srandom@plt>
movslq -0x10(%rbp),%rax
shl    $0x3,%rax
mov    %eax,%edi
call   10c0 <malloc@plt>
mov    %rax,-0x130(%rbp)
movl   $0x0,-0x8(%rbp)
mov    -0x8(%rbp),%eax
cmp    -0x10(%rbp),%eax
jge    1708 <main+0x528>
mov    $0x0,%al
call   10b0 <rd@plt>
mov    -0x130(%rbp),%rax
movslq -0x8(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x8(%rbp)
jmp    16d7 <main+0x4f7>
lea    0xa6a(%rip),%rdi
mov    $0x0,%al
call   1070 <printf@plt>
xor    %eax,%eax
mov    %eax,%edi
call   1090 <time@plt>
mov    %eax,%edi
call   1040 <srandom@plt>
mov    0x28bb(%rip),%rax
mov    (%rax),%edi
lea    -0x18(%rbp),%rsi
call   1050 <clock_gettime@plt>
mov    -0x28(%rbp),%rdi
mov    -0x130(%rbp),%rsi
mov    -0x104(%rbp),%edx
call   10a0 <kdtree_knn_search@plt>
mov    0x2893(%rip),%rax
mov    (%rax),%edi
lea    -0x20(%rbp),%rsi
call   1050 <clock_gettime@plt>
mov    -0x20(%rbp),%eax
sub    -0x18(%rbp),%eax
imul   $0x3e8,%eax,%esi
mov    -0x1c(%rbp),%eax
sub    -0x14(%rbp),%eax
mov    $0xf4240,%ecx
cltd
idiv   %ecx
add    %eax,%esi
lea    0x9d2(%rip),%rdi
mov    $0x0,%al
call   1070 <printf@plt>
mov    -0x104(%rbp),%esi
lea    0x949(%rip),%rdi
mov    $0x0,%al
call   1070 <printf@plt>
movl   $0x0,-0x8(%rbp)
mov    -0x8(%rbp),%eax
cmp    -0x10(%rbp),%eax
jge    1816 <main+0x636>
mov    -0x8(%rbp),%eax
mov    -0x10(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jne    17e5 <main+0x605>
mov    -0x130(%rbp),%rax
movslq -0x8(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
lea    0x927(%rip),%rdi
mov    $0x1,%al
call   1070 <printf@plt>
jmp    1803 <main+0x623>
mov    -0x130(%rbp),%rax
movslq -0x8(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
lea    0x90d(%rip),%rdi
mov    $0x1,%al
call   1070 <printf@plt>
jmp    1808 <main+0x628>
mov    -0x8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x8(%rbp)
jmp    17a5 <main+0x5c5>
mov    -0x28(%rbp),%rdi
call   10e0 <kdtree_knn_dump@plt>
lea    0x966(%rip),%rdi
mov    $0x0,%al
call   1070 <printf@plt>
xor    %eax,%eax
mov    %eax,%edi
call   1090 <time@plt>
mov    %eax,%edi
call   1040 <srandom@plt>
mov    0x27a4(%rip),%rax
mov    (%rax),%edi
lea    -0x18(%rbp),%rsi
call   1050 <clock_gettime@plt>
mov    -0x28(%rbp),%rdi
call   1060 <kdtree_destroy@plt>
mov    0x2789(%rip),%rax
mov    (%rax),%edi
lea    -0x20(%rbp),%rsi
call   1050 <clock_gettime@plt>
mov    -0x20(%rbp),%eax
sub    -0x18(%rbp),%eax
imul   $0x3e8,%eax,%esi
mov    -0x1c(%rbp),%eax
sub    -0x14(%rbp),%eax
mov    $0xf4240,%ecx
cltd
idiv   %ecx
add    %eax,%esi
lea    0x8c8(%rip),%rdi
mov    $0x0,%al
call   1070 <printf@plt>
xor    %eax,%eax
add    $0x130,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0xf8,%rsp
mov    $0x2,%edi
call   1090 <kdtree_init@plt>
test   %rax,%rax
je     1866 <main+0x676>
mov    %rax,%rbx
movaps 0xde2(%rip),%xmm0
movaps %xmm0,0xe0(%rsp)
movaps 0xde3(%rip),%xmm0
movaps %xmm0,0xd0(%rsp)
movaps 0xde4(%rip),%xmm0
movaps %xmm0,0xc0(%rsp)
movaps 0xde5(%rip),%xmm0
movaps %xmm0,0xb0(%rsp)
movaps 0xde6(%rip),%xmm0
movaps %xmm0,0xa0(%rsp)
movaps 0xde7(%rip),%xmm0
movaps %xmm0,0x90(%rsp)
movaps 0xde8(%rip),%xmm0
movaps %xmm0,0x80(%rsp)
movaps 0xde9(%rip),%xmm0
movaps %xmm0,0x70(%rsp)
movaps 0xded(%rip),%xmm0
movaps %xmm0,0x60(%rsp)
movaps 0xdf1(%rip),%xmm0
movaps %xmm0,0x50(%rsp)
movaps 0xdf5(%rip),%xmm0
movaps %xmm0,0x40(%rsp)
movaps 0xdf9(%rip),%xmm0
movaps %xmm0,0x30(%rsp)
movaps 0xdfd(%rip),%xmm0
movaps %xmm0,0x20(%rsp)
lea    0xe0(%rsp),%rsi
mov    %rax,%rdi
call   1110 <kdtree_insert@plt>
lea    0xd0(%rsp),%rsi
mov    %rbx,%rdi
call   1110 <kdtree_insert@plt>
lea    0xc0(%rsp),%rsi
mov    %rbx,%rdi
call   1110 <kdtree_insert@plt>
lea    0xb0(%rsp),%rsi
mov    %rbx,%rdi
call   1110 <kdtree_insert@plt>
lea    0xa0(%rsp),%rsi
mov    %rbx,%rdi
call   1110 <kdtree_insert@plt>
lea    0x90(%rsp),%rsi
mov    %rbx,%rdi
call   1110 <kdtree_insert@plt>
lea    0x80(%rsp),%rsi
mov    %rbx,%rdi
call   1110 <kdtree_insert@plt>
lea    0x70(%rsp),%rsi
mov    %rbx,%rdi
call   1110 <kdtree_insert@plt>
lea    0x60(%rsp),%rsi
mov    %rbx,%rdi
call   1110 <kdtree_insert@plt>
lea    0x50(%rsp),%rsi
mov    %rbx,%rdi
call   1110 <kdtree_insert@plt>
lea    0x40(%rsp),%rsi
mov    %rbx,%rdi
call   1110 <kdtree_insert@plt>
lea    0x30(%rsp),%rsi
mov    %rbx,%rdi
call   1110 <kdtree_insert@plt>
lea    0x20(%rsp),%rsi
mov    %rbx,%rdi
call   1110 <kdtree_insert@plt>
mov    %rbx,%rdi
call   10e0 <kdtree_rebuild@plt>
mov    %rbx,%rdi
call   1030 <kdtree_dump@plt>
movaps 0xd33(%rip),%xmm0
movaps %xmm0,0x10(%rsp)
lea    0x10(%rsp),%rsi
mov    %rbx,%rdi
mov    $0x3,%edx
call   10b0 <kdtree_knn_search@plt>
lea    0xd25(%rip),%rdi
mov    $0x3,%esi
xor    %eax,%eax
call   1080 <printf@plt>
movsd  0x10(%rsp),%xmm0
lea    0xd35(%rip),%rdi
mov    $0x1,%al
call   1080 <printf@plt>
movsd  0x18(%rsp),%xmm0
lea    0xd18(%rip),%rdi
mov    $0x1,%al
call   1080 <printf@plt>
mov    %rbx,%rdi
call   10f0 <kdtree_knn_dump@plt>
mov    %rbx,%rdi
call   1070 <kdtree_destroy@plt>
lea    0xd0b(%rip),%rdi
mov    $0x100000,%ebp
mov    $0x100000,%esi
xor    %eax,%eax
call   1080 <printf@plt>
mov    $0xc,%edi
call   1090 <kdtree_init@plt>
test   %rax,%rax
je     1866 <main+0x676>
mov    %rax,%r13
lea    0xd10(%rip),%rdi
mov    $0x100000,%esi
xor    %eax,%eax
call   1080 <printf@plt>
xor    %edi,%edi
call   10a0 <time@plt>
mov    %eax,%edi
call   1040 <srandom@plt>
mov    0x2b93(%rip),%r12
mov    (%r12),%edi
mov    %rsp,%rsi
call   1060 <clock_gettime@plt>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
mov    $0x60,%edi
call   10d0 <malloc@plt>
mov    %rax,%rbx
xor    %eax,%eax
call   10c0 <rd@plt>
movsd  %xmm0,(%rbx)
xor    %eax,%eax
call   10c0 <rd@plt>
movsd  %xmm0,0x8(%rbx)
xor    %eax,%eax
call   10c0 <rd@plt>
movsd  %xmm0,0x10(%rbx)
xor    %eax,%eax
call   10c0 <rd@plt>
movsd  %xmm0,0x18(%rbx)
xor    %eax,%eax
call   10c0 <rd@plt>
movsd  %xmm0,0x20(%rbx)
xor    %eax,%eax
call   10c0 <rd@plt>
movsd  %xmm0,0x28(%rbx)
xor    %eax,%eax
call   10c0 <rd@plt>
movsd  %xmm0,0x30(%rbx)
xor    %eax,%eax
call   10c0 <rd@plt>
movsd  %xmm0,0x38(%rbx)
xor    %eax,%eax
call   10c0 <rd@plt>
movsd  %xmm0,0x40(%rbx)
xor    %eax,%eax
call   10c0 <rd@plt>
movsd  %xmm0,0x48(%rbx)
xor    %eax,%eax
call   10c0 <rd@plt>
movsd  %xmm0,0x50(%rbx)
xor    %eax,%eax
call   10c0 <rd@plt>
movsd  %xmm0,0x58(%rbx)
mov    %r13,%rdi
mov    %rbx,%rsi
call   1110 <kdtree_insert@plt>
add    $0xffffffff,%ebp
jne    1470 <main+0x280>
mov    (%r12),%edi
lea    0x8(%rsp),%r14
mov    %r14,%rsi
call   1060 <clock_gettime@plt>
mov    0x8(%rsp),%eax
mov    0xc(%rsp),%ecx
sub    (%rsp),%eax
sub    0x4(%rsp),%ecx
imul   $0x3e8,%eax,%eax
movslq %ecx,%rcx
imul   $0x431bde83,%rcx,%rsi
mov    %rsi,%rcx
shr    $0x3f,%rcx
shr    $0x20,%rsi
sar    $0x12,%esi
add    %ecx,%esi
add    %eax,%esi
lea    0xbec(%rip),%r15
mov    %r15,%rdi
xor    %eax,%eax
call   1080 <printf@plt>
lea    0xbed(%rip),%rdi
call   1050 <puts@plt>
mov    (%r12),%edi
mov    %rsp,%rbp
mov    %rbp,%rsi
call   1060 <clock_gettime@plt>
mov    %r13,%rdi
call   10e0 <kdtree_rebuild@plt>
mov    (%r12),%edi
mov    %r14,%rsi
call   1060 <clock_gettime@plt>
mov    0x8(%rsp),%eax
mov    0xc(%rsp),%ecx
sub    (%rsp),%eax
sub    0x4(%rsp),%ecx
imul   $0x3e8,%eax,%eax
movslq %ecx,%rcx
imul   $0x431bde83,%rcx,%rsi
mov    %rsi,%rcx
shr    $0x3f,%rcx
shr    $0x20,%rsi
sar    $0x12,%esi
add    %ecx,%esi
add    %eax,%esi
mov    %r15,%rdi
xor    %eax,%eax
call   1080 <printf@plt>
xor    %edi,%edi
call   10a0 <time@plt>
mov    %eax,%edi
call   1040 <srandom@plt>
mov    $0x60,%edi
call   10d0 <malloc@plt>
mov    %rax,%rbx
xor    %eax,%eax
call   10c0 <rd@plt>
movsd  %xmm0,(%rbx)
xor    %eax,%eax
call   10c0 <rd@plt>
movsd  %xmm0,0x8(%rbx)
xor    %eax,%eax
call   10c0 <rd@plt>
movsd  %xmm0,0x10(%rbx)
xor    %eax,%eax
call   10c0 <rd@plt>
movsd  %xmm0,0x18(%rbx)
xor    %eax,%eax
call   10c0 <rd@plt>
movsd  %xmm0,0x20(%rbx)
xor    %eax,%eax
call   10c0 <rd@plt>
movsd  %xmm0,0x28(%rbx)
xor    %eax,%eax
call   10c0 <rd@plt>
movsd  %xmm0,0x30(%rbx)
xor    %eax,%eax
call   10c0 <rd@plt>
movsd  %xmm0,0x38(%rbx)
xor    %eax,%eax
call   10c0 <rd@plt>
movsd  %xmm0,0x40(%rbx)
xor    %eax,%eax
call   10c0 <rd@plt>
movsd  %xmm0,0x48(%rbx)
xor    %eax,%eax
call   10c0 <rd@plt>
movsd  %xmm0,0x50(%rbx)
xor    %eax,%eax
call   10c0 <rd@plt>
movsd  %xmm0,0x58(%rbx)
lea    0xaea(%rip),%rdi
call   1050 <puts@plt>
xor    %edi,%edi
call   10a0 <time@plt>
mov    %eax,%edi
call   1040 <srandom@plt>
mov    (%r12),%edi
mov    %rbp,%rsi
call   1060 <clock_gettime@plt>
mov    %r13,%rdi
mov    %rbx,%rsi
mov    $0x14,%edx
call   10b0 <kdtree_knn_search@plt>
mov    (%r12),%edi
mov    %r14,%rsi
call   1060 <clock_gettime@plt>
mov    0x8(%rsp),%eax
mov    0xc(%rsp),%ecx
sub    (%rsp),%eax
sub    0x4(%rsp),%ecx
imul   $0x3e8,%eax,%eax
movslq %ecx,%rcx
imul   $0x431bde83,%rcx,%rsi
mov    %rsi,%rcx
shr    $0x3f,%rcx
shr    $0x20,%rsi
sar    $0x12,%esi
add    %ecx,%esi
add    %eax,%esi
mov    %r15,%rdi
xor    %eax,%eax
call   1080 <printf@plt>
lea    0x9d5(%rip),%rdi
mov    $0x14,%esi
xor    %eax,%eax
call   1080 <printf@plt>
movsd  (%rbx),%xmm0
lea    0x9e7(%rip),%rbp
mov    %rbp,%rdi
mov    $0x1,%al
call   1080 <printf@plt>
movsd  0x8(%rbx),%xmm0
mov    %rbp,%rdi
mov    $0x1,%al
call   1080 <printf@plt>
movsd  0x10(%rbx),%xmm0
mov    %rbp,%rdi
mov    $0x1,%al
call   1080 <printf@plt>
movsd  0x18(%rbx),%xmm0
mov    %rbp,%rdi
mov    $0x1,%al
call   1080 <printf@plt>
movsd  0x20(%rbx),%xmm0
mov    %rbp,%rdi
mov    $0x1,%al
call   1080 <printf@plt>
movsd  0x28(%rbx),%xmm0
mov    %rbp,%rdi
mov    $0x1,%al
call   1080 <printf@plt>
movsd  0x30(%rbx),%xmm0
mov    %rbp,%rdi
mov    $0x1,%al
call   1080 <printf@plt>
movsd  0x38(%rbx),%xmm0
mov    %rbp,%rdi
mov    $0x1,%al
call   1080 <printf@plt>
movsd  0x40(%rbx),%xmm0
mov    %rbp,%rdi
mov    $0x1,%al
call   1080 <printf@plt>
movsd  0x48(%rbx),%xmm0
mov    %rbp,%rdi
mov    $0x1,%al
call   1080 <printf@plt>
movsd  0x50(%rbx),%xmm0
mov    %rbp,%rdi
mov    $0x1,%al
call   1080 <printf@plt>
movsd  0x58(%rbx),%xmm0
lea    0x932(%rip),%rdi
mov    $0x1,%al
call   1080 <printf@plt>
mov    %r13,%rdi
call   10f0 <kdtree_knn_dump@plt>
lea    0x9a6(%rip),%rdi
call   1050 <puts@plt>
xor    %edi,%edi
call   10a0 <time@plt>
mov    %eax,%edi
call   1040 <srandom@plt>
mov    (%r12),%edi
mov    %rsp,%rsi
call   1060 <clock_gettime@plt>
mov    %r13,%rdi
call   1070 <kdtree_destroy@plt>
mov    (%r12),%edi
mov    %r14,%rsi
call   1060 <clock_gettime@plt>
mov    0x8(%rsp),%eax
mov    0xc(%rsp),%ecx
sub    (%rsp),%eax
sub    0x4(%rsp),%ecx
imul   $0x3e8,%eax,%eax
movslq %ecx,%rcx
imul   $0x431bde83,%rcx,%rsi
mov    %rsi,%rcx
shr    $0x3f,%rcx
shr    $0x20,%rsi
sar    $0x12,%esi
add    %ecx,%esi
add    %eax,%esi
mov    %r15,%rdi
xor    %eax,%eax
call   1080 <printf@plt>
xor    %eax,%eax
add    $0xf8,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret
mov    $0xffffffff,%edi
call   1100 <exit@plt>

LLVM IR (-O0):
%struct.timespec = type { i32, i32 }
%struct.kdtree = type { i32 }
@__const.main.sample1 = [2 x double] [double 0x4019147AE147AE14, double 5.500000e+00]
@__const.main.sample2 = [2 x double] [double 1.240000e+00, double -2.860000e+00]
@__const.main.sample3 = [2 x double] [double 1.705000e+01, double -1.279000e+01]
@__const.main.sample4 = [2 x double] [double -6.880000e+00, double -5.400000e+00]
@__const.main.sample5 = [2 x double] [double -2.960000e+00, double -5.000000e-01]
@__const.main.sample6 = [2 x double] [double 7.750000e+00, double -2.268000e+01]
@__const.main.sample7 = [2 x double] [double 1.080000e+01, double -5.030000e+00]
@__const.main.sample8 = [2 x double] [double -4.600000e+00, double -1.055000e+01]
@__const.main.sample9 = [2 x double] [double -4.960000e+00, double 1.261000e+01]
@__const.main.sample10 = [2 x double] [double 1.750000e+00, double 1.226000e+01]
@__const.main.sample11 = [2 x double] [double 1.531000e+01, double -1.316000e+01]
@__const.main.sample12 = [2 x double] [double 7.830000e+00, double 1.570000e+01]
@__const.main.sample13 = [2 x double] [double 1.463000e+01, double -3.500000e-01]
@__const.main.target = [2 x double] [double -1.000000e+00, double -5.000000e+00]
@.str = [32 x i8] c"%d nearest neighbors of sample(\00"
@.str.1 = [9 x i8] c"%.2lf):\0A\00"
@.str.2 = [8 x i8] c"%.2lf, \00"
@.str.3 = [51 x i8] c"\0A>>> Performance test: kNN search for %d samples\0A\0A\00"
@.str.4 = [17 x i8] c"Add %d nodes...\0A\00"
@CLOCK_MONOTONIC = global i32 0
@.str.5 = [18 x i8] c"time span: %ldms\0A\00"
@.str.6 = [18 x i8] c"Build KD tree...\0A\00"
@.str.7 = [19 x i8] c"Search KD tree...\0A\00"
@.str.8 = [20 x i8] c"Destroy KD tree...\0A\00"
define i32 @main() {
%1 = alloca i32
%2 = alloca i32
%3 = alloca i32
%4 = alloca i32
%5 = alloca %struct.timespec
%6 = alloca %struct.timespec
%7 = alloca %struct.kdtree*
%8 = alloca [2 x double]
%9 = alloca [2 x double]
%10 = alloca [2 x double]
%11 = alloca [2 x double]
%12 = alloca [2 x double]
%13 = alloca [2 x double]
%14 = alloca [2 x double]
%15 = alloca [2 x double]
%16 = alloca [2 x double]
%17 = alloca [2 x double]
%18 = alloca [2 x double]
%19 = alloca [2 x double]
%20 = alloca [2 x double]
%21 = alloca i32
%22 = alloca [2 x double]
%23 = alloca double*
%24 = alloca double*
store i32 0, i32* %1
store i32 2, i32* %4
%25 = load i32, i32* %4
%26 = call %struct.kdtree* @kdtree_init(i32 %25)
store %struct.kdtree* %26, %struct.kdtree** %7
%27 = load %struct.kdtree*, %struct.kdtree** %7
%28 = icmp eq %struct.kdtree* %27, null
br i1 %28, label %29, label %31
29: ; preds = %0
%30 = call i32 @exit(i32 -1)
unreachable
31: ; preds = %0
%32 = bitcast [2 x double]* %8 to i8*
%33 = bitcast [2 x double]* %9 to i8*
%34 = bitcast [2 x double]* %10 to i8*
%35 = bitcast [2 x double]* %11 to i8*
%36 = bitcast [2 x double]* %12 to i8*
%37 = bitcast [2 x double]* %13 to i8*
%38 = bitcast [2 x double]* %14 to i8*
%39 = bitcast [2 x double]* %15 to i8*
%40 = bitcast [2 x double]* %16 to i8*
%41 = bitcast [2 x double]* %17 to i8*
%42 = bitcast [2 x double]* %18 to i8*
%43 = bitcast [2 x double]* %19 to i8*
%44 = bitcast [2 x double]* %20 to i8*
%45 = load %struct.kdtree*, %struct.kdtree** %7
%46 = getelementptr inbounds [2 x double], [2 x double]* %8, i64 0, i64 0
%47 = call i32 @kdtree_insert(%struct.kdtree* %45, double* %46)
%48 = load %struct.kdtree*, %struct.kdtree** %7
%49 = getelementptr inbounds [2 x double], [2 x double]* %9, i64 0, i64 0
%50 = call i32 @kdtree_insert(%struct.kdtree* %48, double* %49)
%51 = load %struct.kdtree*, %struct.kdtree** %7
%52 = getelementptr inbounds [2 x double], [2 x double]* %10, i64 0, i64 0
%53 = call i32 @kdtree_insert(%struct.kdtree* %51, double* %52)
%54 = load %struct.kdtree*, %struct.kdtree** %7
%55 = getelementptr inbounds [2 x double], [2 x double]* %11, i64 0, i64 0
%56 = call i32 @kdtree_insert(%struct.kdtree* %54, double* %55)
%57 = load %struct.kdtree*, %struct.kdtree** %7
%58 = getelementptr inbounds [2 x double], [2 x double]* %12, i64 0, i64 0
%59 = call i32 @kdtree_insert(%struct.kdtree* %57, double* %58)
%60 = load %struct.kdtree*, %struct.kdtree** %7
%61 = getelementptr inbounds [2 x double], [2 x double]* %13, i64 0, i64 0
%62 = call i32 @kdtree_insert(%struct.kdtree* %60, double* %61)
%63 = load %struct.kdtree*, %struct.kdtree** %7
%64 = getelementptr inbounds [2 x double], [2 x double]* %14, i64 0, i64 0
%65 = call i32 @kdtree_insert(%struct.kdtree* %63, double* %64)
%66 = load %struct.kdtree*, %struct.kdtree** %7
%67 = getelementptr inbounds [2 x double], [2 x double]* %15, i64 0, i64 0
%68 = call i32 @kdtree_insert(%struct.kdtree* %66, double* %67)
%69 = load %struct.kdtree*, %struct.kdtree** %7
%70 = getelementptr inbounds [2 x double], [2 x double]* %16, i64 0, i64 0
%71 = call i32 @kdtree_insert(%struct.kdtree* %69, double* %70)
%72 = load %struct.kdtree*, %struct.kdtree** %7
%73 = getelementptr inbounds [2 x double], [2 x double]* %17, i64 0, i64 0
%74 = call i32 @kdtree_insert(%struct.kdtree* %72, double* %73)
%75 = load %struct.kdtree*, %struct.kdtree** %7
%76 = getelementptr inbounds [2 x double], [2 x double]* %18, i64 0, i64 0
%77 = call i32 @kdtree_insert(%struct.kdtree* %75, double* %76)
%78 = load %struct.kdtree*, %struct.kdtree** %7
%79 = getelementptr inbounds [2 x double], [2 x double]* %19, i64 0, i64 0
%80 = call i32 @kdtree_insert(%struct.kdtree* %78, double* %79)
%81 = load %struct.kdtree*, %struct.kdtree** %7
%82 = getelementptr inbounds [2 x double], [2 x double]* %20, i64 0, i64 0
%83 = call i32 @kdtree_insert(%struct.kdtree* %81, double* %82)
%84 = load %struct.kdtree*, %struct.kdtree** %7
%85 = call i32 @kdtree_rebuild(%struct.kdtree* %84)
%86 = load %struct.kdtree*, %struct.kdtree** %7
%87 = call i32 @kdtree_dump(%struct.kdtree* %86)
store i32 3, i32* %21
%88 = bitcast [2 x double]* %22 to i8*
%89 = load %struct.kdtree*, %struct.kdtree** %7
%90 = getelementptr inbounds [2 x double], [2 x double]* %22, i64 0, i64 0
%91 = load i32, i32* %21
%92 = call i32 @kdtree_knn_search(%struct.kdtree* %89, double* %90, i32 %91)
%93 = load i32, i32* %21
%94 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([32 x i8], [32 x i8]* @.str, i64 0, i64 0), i32 %93)
store i32 0, i32* %2
br label %95
95: ; preds = %117, %31
%96 = load i32, i32* %2
%97 = load i32, i32* %4
%98 = icmp slt i32 %96, %97
br i1 %98, label %99, label %120
99: ; preds = %95
%100 = load i32, i32* %2
%101 = load i32, i32* %4
%102 = sub nsw i32 %101, 1
%103 = icmp eq i32 %100, %102
br i1 %103, label %104, label %110
104: ; preds = %99
%105 = load i32, i32* %2
%106 = sext i32 %105 to i64
%107 = getelementptr inbounds [2 x double], [2 x double]* %22, i64 0, i64 %106
%108 = load double, double* %107
%109 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.1, i64 0, i64 0), double %108)
br label %116
110: ; preds = %99
%111 = load i32, i32* %2
%112 = sext i32 %111 to i64
%113 = getelementptr inbounds [2 x double], [2 x double]* %22, i64 0, i64 %112
%114 = load double, double* %113
%115 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.2, i64 0, i64 0), double %114)
br label %116
116: ; preds = %110, %104
br label %117
117: ; preds = %116
%118 = load i32, i32* %2
%119 = add nsw i32 %118, 1
store i32 %119, i32* %2
br label %95
120: ; preds = %95
%121 = load %struct.kdtree*, %struct.kdtree** %7
%122 = call i32 @kdtree_knn_dump(%struct.kdtree* %121)
%123 = load %struct.kdtree*, %struct.kdtree** %7
%124 = call i32 @kdtree_destroy(%struct.kdtree* %123)
%125 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([51 x i8], [51 x i8]* @.str.3, i64 0, i64 0), i32 1048576)
store i32 12, i32* %4
%126 = load i32, i32* %4
%127 = call %struct.kdtree* @kdtree_init(i32 %126)
store %struct.kdtree* %127, %struct.kdtree** %7
%128 = load %struct.kdtree*, %struct.kdtree** %7
%129 = icmp eq %struct.kdtree* %128, null
br i1 %129, label %130, label %132
130: ; preds = %120
%131 = call i32 @exit(i32 -1)
unreachable
132: ; preds = %120
%133 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.4, i64 0, i64 0), i32 1048576)
%134 = call i32 @time(i32* null)
%135 = call i32 @srandom(i32 %134)
%136 = load i32, i32* @CLOCK_MONOTONIC
%137 = call i32 @clock_gettime(i32 %136, %struct.timespec* %5)
store i32 0, i32* %2
br label %138
138: ; preds = %164, %132
%139 = load i32, i32* %2
%140 = icmp slt i32 %139, 1048576
br i1 %140, label %141, label %167
141: ; preds = %138
%142 = load i32, i32* %4
%143 = sext i32 %142 to i64
%144 = mul i64 %143, 8
%145 = trunc i64 %144 to i32
%146 = call double* @malloc(i32 %145)
store double* %146, double** %23
store i32 0, i32* %3
br label %147
147: ; preds = %157, %141
%148 = load i32, i32* %3
%149 = load i32, i32* %4
%150 = icmp slt i32 %148, %149
br i1 %150, label %151, label %160
151: ; preds = %147
%152 = call double (...) @rd()
%153 = load double*, double** %23
%154 = load i32, i32* %3
%155 = sext i32 %154 to i64
%156 = getelementptr inbounds double, double* %153, i64 %155
store double %152, double* %156
br label %157
157: ; preds = %151
%158 = load i32, i32* %3
%159 = add nsw i32 %158, 1
store i32 %159, i32* %3
br label %147
160: ; preds = %147
%161 = load %struct.kdtree*, %struct.kdtree** %7
%162 = load double*, double** %23
%163 = call i32 @kdtree_insert(%struct.kdtree* %161, double* %162)
br label %164
164: ; preds = %160
%165 = load i32, i32* %2
%166 = add nsw i32 %165, 1
store i32 %166, i32* %2
br label %138
167: ; preds = %138
%168 = load i32, i32* @CLOCK_MONOTONIC
%169 = call i32 @clock_gettime(i32 %168, %struct.timespec* %6)
%170 = getelementptr inbounds %struct.timespec, %struct.timespec* %6, i32 0, i32 0
%171 = load i32, i32* %170
%172 = getelementptr inbounds %struct.timespec, %struct.timespec* %5, i32 0, i32 0
%173 = load i32, i32* %172
%174 = sub nsw i32 %171, %173
%175 = mul nsw i32 %174, 1000
%176 = getelementptr inbounds %struct.timespec, %struct.timespec* %6, i32 0, i32 1
%177 = load i32, i32* %176
%178 = getelementptr inbounds %struct.timespec, %struct.timespec* %5, i32 0, i32 1
%179 = load i32, i32* %178
%180 = sub nsw i32 %177, %179
%181 = sdiv i32 %180, 1000000
%182 = add nsw i32 %175, %181
%183 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str.5, i64 0, i64 0), i32 %182)
%184 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str.6, i64 0, i64 0))
%185 = load i32, i32* @CLOCK_MONOTONIC
%186 = call i32 @clock_gettime(i32 %185, %struct.timespec* %5)
%187 = load %struct.kdtree*, %struct.kdtree** %7
%188 = call i32 @kdtree_rebuild(%struct.kdtree* %187)
%189 = load i32, i32* @CLOCK_MONOTONIC
%190 = call i32 @clock_gettime(i32 %189, %struct.timespec* %6)
%191 = getelementptr inbounds %struct.timespec, %struct.timespec* %6, i32 0, i32 0
%192 = load i32, i32* %191
%193 = getelementptr inbounds %struct.timespec, %struct.timespec* %5, i32 0, i32 0
%194 = load i32, i32* %193
%195 = sub nsw i32 %192, %194
%196 = mul nsw i32 %195, 1000
%197 = getelementptr inbounds %struct.timespec, %struct.timespec* %6, i32 0, i32 1
%198 = load i32, i32* %197
%199 = getelementptr inbounds %struct.timespec, %struct.timespec* %5, i32 0, i32 1
%200 = load i32, i32* %199
%201 = sub nsw i32 %198, %200
%202 = sdiv i32 %201, 1000000
%203 = add nsw i32 %196, %202
%204 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str.5, i64 0, i64 0), i32 %203)
store i32 20, i32* %21
%205 = call i32 @time(i32* null)
%206 = call i32 @srandom(i32 %205)
%207 = load i32, i32* %4
%208 = sext i32 %207 to i64
%209 = mul i64 %208, 8
%210 = trunc i64 %209 to i32
%211 = call double* @malloc(i32 %210)
store double* %211, double** %24
store i32 0, i32* %2
br label %212
212: ; preds = %222, %167
%213 = load i32, i32* %2
%214 = load i32, i32* %4
%215 = icmp slt i32 %213, %214
br i1 %215, label %216, label %225
216: ; preds = %212
%217 = call double (...) @rd()
%218 = load double*, double** %24
%219 = load i32, i32* %2
%220 = sext i32 %219 to i64
%221 = getelementptr inbounds double, double* %218, i64 %220
store double %217, double* %221
br label %222
222: ; preds = %216
%223 = load i32, i32* %2
%224 = add nsw i32 %223, 1
store i32 %224, i32* %2
br label %212
225: ; preds = %212
%226 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str.7, i64 0, i64 0))
%227 = call i32 @time(i32* null)
%228 = call i32 @srandom(i32 %227)
%229 = load i32, i32* @CLOCK_MONOTONIC
%230 = call i32 @clock_gettime(i32 %229, %struct.timespec* %5)
%231 = load %struct.kdtree*, %struct.kdtree** %7
%232 = load double*, double** %24
%233 = load i32, i32* %21
%234 = call i32 @kdtree_knn_search(%struct.kdtree* %231, double* %232, i32 %233)
%235 = load i32, i32* @CLOCK_MONOTONIC
%236 = call i32 @clock_gettime(i32 %235, %struct.timespec* %6)
%237 = getelementptr inbounds %struct.timespec, %struct.timespec* %6, i32 0, i32 0
%238 = load i32, i32* %237
%239 = getelementptr inbounds %struct.timespec, %struct.timespec* %5, i32 0, i32 0
%240 = load i32, i32* %239
%241 = sub nsw i32 %238, %240
%242 = mul nsw i32 %241, 1000
%243 = getelementptr inbounds %struct.timespec, %struct.timespec* %6, i32 0, i32 1
%244 = load i32, i32* %243
%245 = getelementptr inbounds %struct.timespec, %struct.timespec* %5, i32 0, i32 1
%246 = load i32, i32* %245
%247 = sub nsw i32 %244, %246
%248 = sdiv i32 %247, 1000000
%249 = add nsw i32 %242, %248
%250 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str.5, i64 0, i64 0), i32 %249)
%251 = load i32, i32* %21
%252 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([32 x i8], [32 x i8]* @.str, i64 0, i64 0), i32 %251)
store i32 0, i32* %2
br label %253
253: ; preds = %277, %225
%254 = load i32, i32* %2
%255 = load i32, i32* %4
%256 = icmp slt i32 %254, %255
br i1 %256, label %257, label %280
257: ; preds = %253
%258 = load i32, i32* %2
%259 = load i32, i32* %4
%260 = sub nsw i32 %259, 1
%261 = icmp eq i32 %258, %260
br i1 %261, label %262, label %269
262: ; preds = %257
%263 = load double*, double** %24
%264 = load i32, i32* %2
%265 = sext i32 %264 to i64
%266 = getelementptr inbounds double, double* %263, i64 %265
%267 = load double, double* %266
%268 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.1, i64 0, i64 0), double %267)
br label %276
269: ; preds = %257
%270 = load double*, double** %24
%271 = load i32, i32* %2
%272 = sext i32 %271 to i64
%273 = getelementptr inbounds double, double* %270, i64 %272
%274 = load double, double* %273
%275 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.2, i64 0, i64 0), double %274)
br label %276
276: ; preds = %269, %262
br label %277
277: ; preds = %276
%278 = load i32, i32* %2
%279 = add nsw i32 %278, 1
store i32 %279, i32* %2
br label %253
280: ; preds = %253
%281 = load %struct.kdtree*, %struct.kdtree** %7
%282 = call i32 @kdtree_knn_dump(%struct.kdtree* %281)
%283 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str.8, i64 0, i64 0))
%284 = call i32 @time(i32* null)
%285 = call i32 @srandom(i32 %284)
%286 = load i32, i32* @CLOCK_MONOTONIC
%287 = call i32 @clock_gettime(i32 %286, %struct.timespec* %5)
%288 = load %struct.kdtree*, %struct.kdtree** %7
%289 = call i32 @kdtree_destroy(%struct.kdtree* %288)
%290 = load i32, i32* @CLOCK_MONOTONIC
%291 = call i32 @clock_gettime(i32 %290, %struct.timespec* %6)
%292 = getelementptr inbounds %struct.timespec, %struct.timespec* %6, i32 0, i32 0
%293 = load i32, i32* %292
%294 = getelementptr inbounds %struct.timespec, %struct.timespec* %5, i32 0, i32 0
%295 = load i32, i32* %294
%296 = sub nsw i32 %293, %295
%297 = mul nsw i32 %296, 1000
%298 = getelementptr inbounds %struct.timespec, %struct.timespec* %6, i32 0, i32 1
%299 = load i32, i32* %298
%300 = getelementptr inbounds %struct.timespec, %struct.timespec* %5, i32 0, i32 1
%301 = load i32, i32* %300
%302 = sub nsw i32 %299, %301
%303 = sdiv i32 %302, 1000000
%304 = add nsw i32 %297, %303
%305 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str.5, i64 0, i64 0), i32 %304)
ret i32 0
}

LLVM IR (-O2):
%struct.timespec = type { i32, i32 }
%struct.kdtree = type { i32 }
@__const.main.sample1 = [2 x double] [double 0x4019147AE147AE14, double 5.500000e+00]
@__const.main.sample2 = [2 x double] [double 1.240000e+00, double -2.860000e+00]
@__const.main.sample3 = [2 x double] [double 1.705000e+01, double -1.279000e+01]
@__const.main.sample4 = [2 x double] [double -6.880000e+00, double -5.400000e+00]
@__const.main.sample5 = [2 x double] [double -2.960000e+00, double -5.000000e-01]
@__const.main.sample6 = [2 x double] [double 7.750000e+00, double -2.268000e+01]
@__const.main.sample7 = [2 x double] [double 1.080000e+01, double -5.030000e+00]
@__const.main.sample8 = [2 x double] [double -4.600000e+00, double -1.055000e+01]
@__const.main.sample9 = [2 x double] [double -4.960000e+00, double 1.261000e+01]
@__const.main.sample10 = [2 x double] [double 1.750000e+00, double 1.226000e+01]
@__const.main.sample11 = [2 x double] [double 1.531000e+01, double -1.316000e+01]
@__const.main.sample12 = [2 x double] [double 7.830000e+00, double 1.570000e+01]
@__const.main.sample13 = [2 x double] [double 1.463000e+01, double -3.500000e-01]
@__const.main.target = [2 x double] [double -1.000000e+00, double -5.000000e+00]
@.str = [32 x i8] c"%d nearest neighbors of sample(\00"
@.str.1 = [9 x i8] c"%.2lf):\0A\00"
@.str.2 = [8 x i8] c"%.2lf, \00"
@.str.3 = [51 x i8] c"\0A>>> Performance test: kNN search for %d samples\0A\0A\00"
@.str.4 = [17 x i8] c"Add %d nodes...\0A\00"
@CLOCK_MONOTONIC = global i32 0
@.str.5 = [18 x i8] c"time span: %ldms\0A\00"
@str = [17 x i8] c"Build KD tree...\00"
@str.9 = [18 x i8] c"Search KD tree...\00"
@str.10 = [19 x i8] c"Destroy KD tree...\00"
define i32 @main() {
%1 = alloca %struct.timespec
%2 = alloca %struct.timespec
%3 = alloca [2 x double]
%4 = alloca [2 x double]
%5 = alloca [2 x double]
%6 = alloca [2 x double]
%7 = alloca [2 x double]
%8 = alloca [2 x double]
%9 = alloca [2 x double]
%10 = alloca [2 x double]
%11 = alloca [2 x double]
%12 = alloca [2 x double]
%13 = alloca [2 x double]
%14 = alloca [2 x double]
%15 = alloca [2 x double]
%16 = alloca [2 x double]
%17 = bitcast %struct.timespec* %1 to i8*
%18 = bitcast %struct.timespec* %2 to i8*
%19 = tail call %struct.kdtree* @kdtree_init(i32 2)
%20 = icmp eq %struct.kdtree* %19, null
br i1 %20, label %21, label %23
21: ; preds = %0
%22 = tail call i32 @exit(i32 -1)
unreachable
23: ; preds = %0
%24 = bitcast [2 x double]* %3 to i8*
%25 = bitcast [2 x double]* %4 to i8*
%26 = bitcast [2 x double]* %5 to i8*
%27 = bitcast [2 x double]* %6 to i8*
%28 = bitcast [2 x double]* %7 to i8*
%29 = bitcast [2 x double]* %8 to i8*
%30 = bitcast [2 x double]* %9 to i8*
%31 = bitcast [2 x double]* %10 to i8*
%32 = bitcast [2 x double]* %11 to i8*
%33 = bitcast [2 x double]* %12 to i8*
%34 = bitcast [2 x double]* %13 to i8*
%35 = bitcast [2 x double]* %14 to i8*
%36 = bitcast [2 x double]* %15 to i8*
%37 = getelementptr inbounds [2 x double], [2 x double]* %3, i64 0, i64 0
%38 = call i32 @kdtree_insert(%struct.kdtree* %19, double* %37)
%39 = getelementptr inbounds [2 x double], [2 x double]* %4, i64 0, i64 0
%40 = call i32 @kdtree_insert(%struct.kdtree* %19, double* %39)
%41 = getelementptr inbounds [2 x double], [2 x double]* %5, i64 0, i64 0
%42 = call i32 @kdtree_insert(%struct.kdtree* %19, double* %41)
%43 = getelementptr inbounds [2 x double], [2 x double]* %6, i64 0, i64 0
%44 = call i32 @kdtree_insert(%struct.kdtree* %19, double* %43)
%45 = getelementptr inbounds [2 x double], [2 x double]* %7, i64 0, i64 0
%46 = call i32 @kdtree_insert(%struct.kdtree* %19, double* %45)
%47 = getelementptr inbounds [2 x double], [2 x double]* %8, i64 0, i64 0
%48 = call i32 @kdtree_insert(%struct.kdtree* %19, double* %47)
%49 = getelementptr inbounds [2 x double], [2 x double]* %9, i64 0, i64 0
%50 = call i32 @kdtree_insert(%struct.kdtree* %19, double* %49)
%51 = getelementptr inbounds [2 x double], [2 x double]* %10, i64 0, i64 0
%52 = call i32 @kdtree_insert(%struct.kdtree* %19, double* %51)
%53 = getelementptr inbounds [2 x double], [2 x double]* %11, i64 0, i64 0
%54 = call i32 @kdtree_insert(%struct.kdtree* %19, double* %53)
%55 = getelementptr inbounds [2 x double], [2 x double]* %12, i64 0, i64 0
%56 = call i32 @kdtree_insert(%struct.kdtree* %19, double* %55)
%57 = getelementptr inbounds [2 x double], [2 x double]* %13, i64 0, i64 0
%58 = call i32 @kdtree_insert(%struct.kdtree* %19, double* %57)
%59 = getelementptr inbounds [2 x double], [2 x double]* %14, i64 0, i64 0
%60 = call i32 @kdtree_insert(%struct.kdtree* %19, double* %59)
%61 = getelementptr inbounds [2 x double], [2 x double]* %15, i64 0, i64 0
%62 = call i32 @kdtree_insert(%struct.kdtree* %19, double* %61)
%63 = call i32 @kdtree_rebuild(%struct.kdtree* %19)
%64 = call i32 @kdtree_dump(%struct.kdtree* %19)
%65 = bitcast [2 x double]* %16 to i8*
%66 = getelementptr inbounds [2 x double], [2 x double]* %16, i64 0, i64 0
%67 = call i32 @kdtree_knn_search(%struct.kdtree* %19, double* %66, i32 3)
%68 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([32 x i8], [32 x i8]* @.str, i64 0, i64 0), i32 3)
%69 = getelementptr inbounds [2 x double], [2 x double]* %16, i64 0, i64 1
%70 = load double, double* %66
%71 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([8 x i8], [8 x i8]* @.str.2, i64 0, i64 0), double %70)
%72 = load double, double* %69
%73 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([9 x i8], [9 x i8]* @.str.1, i64 0, i64 0), double %72)
%74 = call i32 @kdtree_knn_dump(%struct.kdtree* %19)
%75 = call i32 @kdtree_destroy(%struct.kdtree* %19)
%76 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([51 x i8], [51 x i8]* @.str.3, i64 0, i64 0), i32 1048576)
%77 = call %struct.kdtree* @kdtree_init(i32 12)
%78 = icmp eq %struct.kdtree* %77, null
br i1 %78, label %79, label %81
79: ; preds = %23
%80 = call i32 @exit(i32 -1)
unreachable
81: ; preds = %23
%82 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([17 x i8], [17 x i8]* @.str.4, i64 0, i64 0), i32 1048576)
%83 = call i32 @time(i32* null)
%84 = call i32 @srandom(i32 %83)
%85 = load i32, i32* @CLOCK_MONOTONIC
%86 = call i32 @clock_gettime(i32 %85, %struct.timespec* %1)
br label %87
87: ; preds = %81, %87
%88 = phi i32 [ 0, %81 ], [ %114, %87 ]
%89 = call double* @malloc(i32 96)
%90 = call double (...) @rd()
store double %90, double* %89
%91 = call double (...) @rd()
%92 = getelementptr inbounds double, double* %89, i64 1
store double %91, double* %92
%93 = call double (...) @rd()
%94 = getelementptr inbounds double, double* %89, i64 2
store double %93, double* %94
%95 = call double (...) @rd()
%96 = getelementptr inbounds double, double* %89, i64 3
store double %95, double* %96
%97 = call double (...) @rd()
%98 = getelementptr inbounds double, double* %89, i64 4
store double %97, double* %98
%99 = call double (...) @rd()
%100 = getelementptr inbounds double, double* %89, i64 5
store double %99, double* %100
%101 = call double (...) @rd()
%102 = getelementptr inbounds double, double* %89, i64 6
store double %101, double* %102
%103 = call double (...) @rd()
%104 = getelementptr inbounds double, double* %89, i64 7
store double %103, double* %104
%105 = call double (...) @rd()
%106 = getelementptr inbounds double, double* %89, i64 8
store double %105, double* %106
%107 = call double (...) @rd()
%108 = getelementptr inbounds double, double* %89, i64 9
store double %107, double* %108
%109 = call double (...) @rd()
%110 = getelementptr inbounds double, double* %89, i64 10
store double %109, double* %110
%111 = call double (...) @rd()
%112 = getelementptr inbounds double, double* %89, i64 11
store double %111, double* %112
%113 = call i32 @kdtree_insert(%struct.kdtree* %77, double* %89)
%114 = add nuw nsw i32 %88, 1
%115 = icmp eq i32 %114, 1048576
br i1 %115, label %116, label %87
116: ; preds = %87
%117 = load i32, i32* @CLOCK_MONOTONIC
%118 = call i32 @clock_gettime(i32 %117, %struct.timespec* %2)
%119 = getelementptr inbounds %struct.timespec, %struct.timespec* %2, i64 0, i32 0
%120 = load i32, i32* %119
%121 = getelementptr inbounds %struct.timespec, %struct.timespec* %1, i64 0, i32 0
%122 = load i32, i32* %121
%123 = sub nsw i32 %120, %122
%124 = mul nsw i32 %123, 1000
%125 = getelementptr inbounds %struct.timespec, %struct.timespec* %2, i64 0, i32 1
%126 = load i32, i32* %125
%127 = getelementptr inbounds %struct.timespec, %struct.timespec* %1, i64 0, i32 1
%128 = load i32, i32* %127
%129 = sub nsw i32 %126, %128
%130 = sdiv i32 %129, 1000000
%131 = add nsw i32 %130, %124
%132 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([18 x i8], [18 x i8]* @.str.5, i64 0, i64 0), i32 %131)
%133 = call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([17 x i8], [17 x i8]* @str, i64 0, i64 0))
%134 = load i32, i32* @CLOCK_MONOTONIC
%135 = call i32 @clock_gettime(i32 %134, %struct.timespec* %1)
%136 = call i32 @kdtree_rebuild(%struct.kdtree* %77)
%137 = load i32, i32* @CLOCK_MONOTONIC
%138 = call i32 @clock_gettime(i32 %137, %struct.timespec* %2)
%139 = load i32, i32* %119
%140 = load i32, i32* %121
%141 = sub nsw i32 %139, %140
%142 = mul nsw i32 %141, 1000
%143 = load i32, i32* %125
%144 = load i32, i32* %127
%145 = sub nsw i32 %143, %144
%146 = sdiv i32 %145, 1000000
%147 = add nsw i32 %146, %142
%148 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([18 x i8], [18 x i8]* @.str.5, i64 0, i64 0), i32 %147)
%149 = call i32 @time(i32* null)
%150 = call i32 @srandom(i32 %149)
%151 = call double* @malloc(i32 96)
%152 = call double (...) @rd()
store double %152, double* %151
%153 = call double (...) @rd()
%154 = getelementptr inbounds double, double* %151, i64 1
store double %153, double* %154
%155 = call double (...) @rd()
%156 = getelementptr inbounds double, double* %151, i64 2
store double %155, double* %156
%157 = call double (...) @rd()
%158 = getelementptr inbounds double, double* %151, i64 3
store double %157, double* %158
%159 = call double (...) @rd()
%160 = getelementptr inbounds double, double* %151, i64 4
store double %159, double* %160
%161 = call double (...) @rd()
%162 = getelementptr inbounds double, double* %151, i64 5
store double %161, double* %162
%163 = call double (...) @rd()
%164 = getelementptr inbounds double, double* %151, i64 6
store double %163, double* %164
%165 = call double (...) @rd()
%166 = getelementptr inbounds double, double* %151, i64 7
store double %165, double* %166
%167 = call double (...) @rd()
%168 = getelementptr inbounds double, double* %151, i64 8
store double %167, double* %168
%169 = call double (...) @rd()
%170 = getelementptr inbounds double, double* %151, i64 9
store double %169, double* %170
%171 = call double (...) @rd()
%172 = getelementptr inbounds double, double* %151, i64 10
store double %171, double* %172
%173 = call double (...) @rd()
%174 = getelementptr inbounds double, double* %151, i64 11
store double %173, double* %174
%175 = call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([18 x i8], [18 x i8]* @str.9, i64 0, i64 0))
%176 = call i32 @time(i32* null)
%177 = call i32 @srandom(i32 %176)
%178 = load i32, i32* @CLOCK_MONOTONIC
%179 = call i32 @clock_gettime(i32 %178, %struct.timespec* %1)
%180 = call i32 @kdtree_knn_search(%struct.kdtree* %77, double* %151, i32 20)
%181 = load i32, i32* @CLOCK_MONOTONIC
%182 = call i32 @clock_gettime(i32 %181, %struct.timespec* %2)
%183 = load i32, i32* %119
%184 = load i32, i32* %121
%185 = sub nsw i32 %183, %184
%186 = mul nsw i32 %185, 1000
%187 = load i32, i32* %125
%188 = load i32, i32* %127
%189 = sub nsw i32 %187, %188
%190 = sdiv i32 %189, 1000000
%191 = add nsw i32 %190, %186
%192 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([18 x i8], [18 x i8]* @.str.5, i64 0, i64 0), i32 %191)
%193 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([32 x i8], [32 x i8]* @.str, i64 0, i64 0), i32 20)
%194 = load double, double* %151
%195 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([8 x i8], [8 x i8]* @.str.2, i64 0, i64 0), double %194)
%196 = load double, double* %154
%197 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([8 x i8], [8 x i8]* @.str.2, i64 0, i64 0), double %196)
%198 = load double, double* %156
%199 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([8 x i8], [8 x i8]* @.str.2, i64 0, i64 0), double %198)
%200 = load double, double* %158
%201 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([8 x i8], [8 x i8]* @.str.2, i64 0, i64 0), double %200)
%202 = load double, double* %160
%203 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([8 x i8], [8 x i8]* @.str.2, i64 0, i64 0), double %202)
%204 = load double, double* %162
%205 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([8 x i8], [8 x i8]* @.str.2, i64 0, i64 0), double %204)
%206 = load double, double* %164
%207 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([8 x i8], [8 x i8]* @.str.2, i64 0, i64 0), double %206)
%208 = load double, double* %166
%209 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([8 x i8], [8 x i8]* @.str.2, i64 0, i64 0), double %208)
%210 = load double, double* %168
%211 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([8 x i8], [8 x i8]* @.str.2, i64 0, i64 0), double %210)
%212 = load double, double* %170
%213 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([8 x i8], [8 x i8]* @.str.2, i64 0, i64 0), double %212)
%214 = load double, double* %172
%215 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([8 x i8], [8 x i8]* @.str.2, i64 0, i64 0), double %214)
%216 = load double, double* %174
%217 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([9 x i8], [9 x i8]* @.str.1, i64 0, i64 0), double %216)
%218 = call i32 @kdtree_knn_dump(%struct.kdtree* %77)
%219 = call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([19 x i8], [19 x i8]* @str.10, i64 0, i64 0))
%220 = call i32 @time(i32* null)
%221 = call i32 @srandom(i32 %220)
%222 = load i32, i32* @CLOCK_MONOTONIC
%223 = call i32 @clock_gettime(i32 %222, %struct.timespec* %1)
%224 = call i32 @kdtree_destroy(%struct.kdtree* %77)
%225 = load i32, i32* @CLOCK_MONOTONIC
%226 = call i32 @clock_gettime(i32 %225, %struct.timespec* %2)
%227 = load i32, i32* %119
%228 = load i32, i32* %121
%229 = sub nsw i32 %227, %228
%230 = mul nsw i32 %229, 1000
%231 = load i32, i32* %125
%232 = load i32, i32* %127
%233 = sub nsw i32 %231, %232
%234 = sdiv i32 %233, 1000000
%235 = add nsw i32 %234, %230
%236 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([18 x i8], [18 x i8]* @.str.5, i64 0, i64 0), i32 %235)
ret i32 0
}