// File: /workspace/github_c_makefile_star2_O1/jondurbin[P]dre2/src/dre2_parse.c
// Function: dre2_skip_table
void dre2_skip_table( struct dre2 *graph )
{
  int i, j, r;
  int iter, l_iter;
  int matched, complete, total;
  int *swapper, *visited;
  int *reachable, *state, *r_temp;
  struct dre2_node *node;

  // Allocate some memory.
  state = ( int * )malloc( sizeof( int ) * graph->count );
  reachable = ( int * )malloc( sizeof( int ) * graph->count );
  r_temp = ( int * )malloc( sizeof( int ) * graph->count );

  // Initialize some variables.
  i = 0;
  iter = 0;
  total = 0;
  complete = false;

  // Initialize the reachable states to be neighbors of the first node.
  for ( i = 0; i < graph->v[graph->count - 1].p_count; i++ )
  {
    reachable[i] = graph->v[graph->count - 1].p[i];
    if ( reachable[i] == 0 )
    {
      for ( j = 0; j < RANGE; j++ )
        graph->skip_table[j] = 1;
      graph->min_length = 0;
      return;
    }
  }
  l_iter = i;

  visited = ( int * )malloc( sizeof( int ) * graph->count );
  for ( j = 0; j < RANGE; j++ )
    graph->skip_table[j] = 0;

  // Outer loop, runs until the initial node is reachable.
  while ( true )
  {
    if ( l_iter == 0 )
      break;

    total++;
    iter = 0;

    // Iterate through all of the reachable nodes.
    for ( j = 0; j < graph->count; j++ )
    {
      visited[j] = false;
      state[j] = false;
    }
    for ( i = 0; i < l_iter; i++ )
    {
      r = reachable[i];
      node = &graph->v[r];
      if ( total > 1 )
      {

        // Setup the skip table for the current node's chars.
        if ( node->c == DRE2_CHAR_CLASS )
        {
          for ( j = 0; j < RANGE; j++ )
          {
            if ( node->possible[j] && graph->skip_table[j] > total - 1 || graph->skip_table[j] == 0 )
              graph->skip_table[j] = total - 1;
          }
        } else if ( node->c >= 0 )
        {
          if ( graph->skip_table[node->c] > total - 1 || graph->skip_table[node->c] == 0 )
            graph->skip_table[node->c] = total - 1;
        }
      }
      if ( node->c == DRE2_BOL || node->c == DRE2_EOF || node->c == DRE2_EOL )
          total--;


      // Add the current node's parents to the next reachable nodes.
      for ( j = 0; j < node->p_count; j++ )
      {
        if ( !state[node->p[j]] && !visited[node->p[j]] )
          r_temp[iter++] = node->p[j];

        visited[node->p[j]] = true;
        state[node->p[j]] = true;
      }

      // Check if the initial state was reached.
      if ( state[0] == true )
      {
        complete = true;
      }
    }
    
    l_iter = iter;

    // Change the current reachable nodes to the next reachable nodes from above.
    swapper = reachable;
    reachable = r_temp;
    r_temp = swapper;
    if ( complete )
      break;
  }

  // Set remaining character's skip table value.
  for ( i = 0; i < RANGE; i++ )
  {
    if ( graph->skip_table[i] == 0 )
      graph->skip_table[i] = total;
  }

  // Set the min length of the regular expression.
  graph->min_length = total;

  free( reachable );
  free( r_temp );
  free( state );
  free( visited );
  reachable = NULL;
  r_temp = NULL;
  state = NULL;
  visited = NULL;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rdi, %rbx
movslq 0x8(%rdi), %rbp
leaq (,%rbp,4), %r12
movq %r12, %rdi
callq 0x22a0
movq %rax, %r14
movq %r12, %rdi
callq 0x22a0
movq %rax, 0x10(%rsp)
movq %r12, %rdi
callq 0x22a0
movq (%rbx), %rcx
shlq $0x6, %rbp
movq %rcx, 0x18(%rsp)
movslq -0x20(%rcx,%rbp), %rsi
xorl %r15d, %r15d
movl $0x0, %r13d
testq %rsi, %rsi
jle 0x4933
addq 0x18(%rsp), %rbp
movq -0x28(%rbp), %rcx
xorl %r13d, %r13d
movq 0x10(%rsp), %rdi
movl (%rcx,%r13,4), %edx
movl %edx, (%rdi,%r13,4)
testl %edx, %edx
je 0x4ae1
incq %r13
cmpq %r13, %rsi
jne 0x491b
movq %rax, 0x8(%rsp)
movq %r12, %rdi
callq 0x22a0
movq %rax, %r12
leaq 0xc(%rbx), %rdi
movl $0x400, %edx            # imm = 0x400
xorl %esi, %esi
callq 0x2180
testl %r13d, %r13d
je 0x4b14
xorl %r15d, %r15d
movl $0x1, %ebp
movq 0x8(%rsp), %r8
movq 0x10(%rsp), %rax
movq %r8, %r11
movq %rax, %r8
movslq 0x8(%rbx), %rax
testq %rax, %rax
jle 0x49b6
shlq $0x2, %rax
movq %r11, 0x10(%rsp)
movq %r12, %rdi
xorl %esi, %esi
movq %rax, %rdx
movq %rax, 0x20(%rsp)
movq %r8, 0x8(%rsp)
callq 0x2180
movq %r14, %rdi
xorl %esi, %esi
movq 0x20(%rsp), %rdx
callq 0x2180
movq 0x10(%rsp), %r11
movq 0x8(%rsp), %r8
incl %r15d
xorl %eax, %eax
testl %r13d, %r13d
jg 0x49c8
xorl %r13d, %r13d
jmp 0x4acf
movl %r13d, %eax
movq %rax, 0x8(%rsp)
xorl %ecx, %ecx
xorl %edx, %edx
xorl %r13d, %r13d
movq %r8, %rax
movslq (%r8,%rcx,4), %rsi
shlq $0x6, %rsi
addq 0x18(%rsp), %rsi
cmpl $0x2, %r15d
jl 0x4a53
movl (%rsi), %edi
movl $0xfffffffd, %r8d       # imm = 0xFFFFFFFD
cmpq %r8, %rdi
jne 0x4a2e
movq 0x28(%rsi), %rdi
leal -0x1(%r15), %r8d
xorl %r9d, %r9d
cmpl $0x0, (%rdi,%r9,4)
je 0x4a13
cmpl %r15d, 0xc(%rbx,%r9,4)
jge 0x4a1b
cmpl $0x0, 0xc(%rbx,%r9,4)
jne 0x4a20
movl %r8d, 0xc(%rbx,%r9,4)
incq %r9
cmpq $0x100, %r9             # imm = 0x100
jne 0x4a05
jmp 0x4a53
testl %edi, %edi
js 0x4a53
movl 0xc(%rbx,%rdi,4), %r8d
cmpl %r15d, %r8d
setl %r9b
testl %r8d, %r8d
setne %r8b
testb %r8b, %r9b
jne 0x4a53
leal -0x1(%r15), %r8d
movl %r8d, 0xc(%rbx,%rdi,4)
movl (%rsi), %edi
addl $0x12, %edi
cmpl $0xe, %edi
ja 0x4a6c
movl $0x4003, %r8d           # imm = 0x4003
btl %edi, %r8d
jae 0x4a6c
decl %r15d
cmpl $0x0, 0x20(%rsi)
jle 0x4ab0
movq 0x18(%rsi), %rdi
xorl %r8d, %r8d
movl (%rdi,%r8,4), %r9d
movslq %r9d, %r10
cmpl $0x0, (%r14,%r10,4)
jne 0x4a98
cmpl $0x0, (%r12,%r10,4)
jne 0x4a98
movslq %r13d, %r10
incl %r13d
movl %r9d, (%r11,%r10,4)
movslq (%rdi,%r8,4), %r9
movl %ebp, (%r12,%r9,4)
movl %ebp, (%r14,%r9,4)
incq %r8
movslq 0x20(%rsi), %r9
cmpq %r9, %r8
jl 0x4a79
movl (%r14), %esi
cmpl $0x1, %esi
cmovel %esi, %edx
incq %rcx
cmpq 0x8(%rsp), %rcx
movq %rax, %r8
jne 0x49d7
testl %edx, %edx
setne %al
testb %al, %al
jne 0x4b1e
movq %r11, %rax
testl %r13d, %r13d
jne 0x496e
jmp 0x4b1e
xorl %eax, %eax
movaps 0x6656(%rip), %xmm0     # 0xb140
movups %xmm0, 0xc(%rbx,%rax,4)
addq $0x4, %rax
cmpq $0x100, %rax            # imm = 0x100
jne 0x4aea
movl $0x0, 0x40c(%rbx)
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x10(%rsp), %r11
movq 0x8(%rsp), %r8
movq %r8, %r13
xorl %eax, %eax
pxor %xmm0, %xmm0
movdqu 0xc(%rbx,%rax,4), %xmm1
pcmpeqd %xmm0, %xmm1
movd %xmm1, %ecx
testb $0x1, %cl
je 0x4b3f
movl %r15d, 0xc(%rbx,%rax,4)
pextrw $0x2, %xmm1, %ecx
testb $0x1, %cl
je 0x4b4e
movl %r15d, 0x10(%rbx,%rax,4)
pextrw $0x4, %xmm1, %ecx
testb $0x1, %cl
je 0x4b5d
movl %r15d, 0x14(%rbx,%rax,4)
pextrw $0x6, %xmm1, %ecx
testb $0x1, %cl
je 0x4b6c
movl %r15d, 0x18(%rbx,%rax,4)
addq $0x4, %rax
cmpq $0x100, %rax            # imm = 0x100
jne 0x4b27
movl %r15d, 0x40c(%rbx)
movq %r11, %rdi
callq 0x2070
movq %r13, %rdi
callq 0x2070
movq %r14, %rdi
callq 0x2070
movq %r12, %rdi
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x2070