// File: /workspace/github_cpp_makefile_star2_O2/adamnovak[P]rlcsa/misc/utils.cpp
// Function: unsigned int CSA::setRanks<std::pair<unsigned int, unsigned int>>(std::pair<unsigned int, unsigned int>*, unsigned int*, unsigned int, std::vector<std::pair<unsigned int, unsigned int>, std::allocator<std::pair<unsigned int, unsigned int>>>&, unsigned int, unsigned int)
uint
setRanks(T* pairs, uint* keys, uint n, std::vector<ss_range>& unsorted, uint threads, uint chunk)
{
  uint total = 0;

  #ifdef MULTITHREAD_SUPPORT
  std::vector<ss_range> buffers[threads];
  uint subtotals[threads];
  for(uint i = 0; i < threads; i++) { subtotals[i] = 0; }
  #else
  std::vector<ss_range> next_unsorted;
  #endif

  #pragma omp parallel for schedule(dynamic, chunk)
  for(uint i = 0; i < unsorted.size(); i++)
  {
    #ifdef MULTITHREAD_SUPPORT
    uint thread = omp_get_thread_num();
    #endif
    T* prev = pairs + unsorted[i].first;
    keys[prev->first] = unsorted[i].first;
    T* limit = pairs + unsorted[i].second;
    while(prev < limit)
    {
      T* curr = prev + 1;
      if(curr->second != prev->second)
      {
        ++prev; keys[prev->first] = prev - pairs;
        continue;
      }
      keys[curr->first] = prev - pairs;

      for(++curr; curr <= limit && curr->second == prev->second; ++curr)
      {
        keys[curr->first] = prev - pairs;
      }

      #ifdef MULTITHREAD_SUPPORT
      buffers[thread].push_back(ss_range(prev - pairs, (curr - 1) - pairs));
      subtotals[thread] += curr - prev;
      #else
      next_unsorted.push_back(ss_range(prev - pairs, (curr - 1) - pairs));
      total += curr - prev;
      #endif
      prev = curr; if(prev <= limit) { keys[prev->first] = prev - pairs; }
    }
  }

  #ifdef MULTITHREAD_SUPPORT
  unsorted.clear();
  for(uint i = 0; i < threads; i++)
  {
    unsorted.insert(unsorted.end(), buffers[i].begin(), buffers[i].end());
    total += subtotals[i];
  }
  #else
  unsorted.assign(next_unsorted.begin(), next_unsorted.end());
  #endif

  return total;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %rcx, 0x10(%rsp)
movq %rsi, %r14
xorps %xmm0, %xmm0
leaq 0x20(%rsp), %rax
movaps %xmm0, (%rax)
andq $0x0, 0x10(%rax)
movq %rdi, %r15
negq %r15
pushq $0x8
popq %r8
movq %rdi, 0x48(%rsp)
subq %rdi, %r8
xorl %edi, %edi
xorl %ebp, %ebp
movq %r8, 0x40(%rsp)
movl %edi, %edi
movq 0x10(%rsp), %rcx
movq (%rcx), %rax
movq 0x8(%rcx), %rcx
subq %rax, %rcx
sarq $0x3, %rcx
cmpq %rdi, %rcx
jbe 0x118db
movl (%rax,%rdi,8), %ecx
movq 0x48(%rsp), %rsi
leaq (%rsi,%rcx,8), %r13
movl (%r13), %edx
movl %ecx, (%r14,%rdx,4)
movl 0x4(%rax,%rdi,8), %eax
leaq (%rsi,%rax,8), %rbx
leaq (%r8,%r13), %r12
movq %r13, %rax
cmpq %rbx, %rax
jae 0x118d4
movl 0x8(%rax), %edx
movl 0xc(%rax), %ecx
cmpl 0x4(%rax), %ecx
je 0x11844
leaq (%r15,%r13), %rcx
addq $0x8, %rcx
shrq $0x3, %rcx
movl %ecx, (%r14,%rdx,4)
addq $0x8, %r13
addq $0x8, %rax
addq $0x8, %r12
jmp 0x11812
movl %ebp, 0xc(%rsp)
addq %r15, %r13
shrq $0x3, %r13
movl %r13d, %ecx
movl %r13d, (%r14,%rdx,4)
pushq $0x10
popq %rbp
leaq (%rax,%rbp), %r13
cmpq %rbx, %r13
ja 0x1187d
movl 0x4(%rax,%rbp), %edx
cmpl 0x4(%rax), %edx
jne 0x1187d
movl (%r13), %edx
movl %ecx, (%r14,%rdx,4)
addq $0x8, %rbp
addq $0x8, %r12
jmp 0x11859
movq %rdi, 0x50(%rsp)
movq %r12, %rax
shrq $0x3, %rax
movl %ecx, 0x18(%rsp)
movl %eax, 0x1c(%rsp)
leaq 0x20(%rsp), %rdi
leaq 0x18(%rsp), %rsi
callq 0xac2e
shrq $0x3, %rbp
movl 0xc(%rsp), %eax
addl %ebp, %eax
movl %eax, %ebp
cmpq %rbx, %r13
movq 0x40(%rsp), %r8
movq 0x50(%rsp), %rdi
ja 0x1180b
addq $0x8, %r12
shrq $0x3, %r12
movl (%r13), %eax
movl %r12d, (%r14,%rax,4)
jmp 0x1180b
incl %edi
jmp 0x117d1
movq 0x20(%rsp), %rsi
movq 0x28(%rsp), %rdx
movq 0x10(%rsp), %rdi
callq 0x120d6
leaq 0x20(%rsp), %rdi
callq 0xb30c
movl %ebp, %eax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x1190c
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0xb30c
movq %rbx, %rdi
callq 0x3410
nop