// File: /workspace/github_cpp_makefile_star2_O1/WShabti-Team[P]WShabtiPict/wshabtilib/api/deriver.cpp
// Function: pictcore::ExclusionDeriver::DeriveExclusions()
void ExclusionDeriver::DeriveExclusions()
{
    // For preview generation we don't invoke the core of the deriver at all
    if( m_task->GetGenerationMode() != Regular ) return;

    DOUT( L"Exclusions:\n" );
    for( auto & exclusion : m_exclusions )
    {
        exclusion.Print();
    }
    DOUT( L"Derivation: Started\n" );

    // Add pointers to referencing exclusions to each parameter
    // for_each(m_exclusions.begin(), m_exclusions.end(), AddExclusionParamBackPtrs);
    for( ExclusionCollection::iterator ie = m_exclusions.begin(); ie != m_exclusions.end(); ++ie )
    {
        AddExclusionParamBackPtrs( ie );
    }

    // Initialize the worklist
    for( vector<Parameter*>::iterator i = m_parameters.begin(); i != m_parameters.end(); ++i )
    {
        if( ( *i )->GetExclusionCount() >= ( *i )->GetValueCount() )
        {
            m_worklist.push_back( &**i );
        }
    }

    while( !m_worklist.empty() )
    {
        DOUT( L"worklist size: " << static_cast<int>( m_worklist.size() ) << L"\n" );
        DOUT( L"excl col size: " << static_cast<int>( m_exclusions.size() ) << L"\n"; )

        m_currentParam = m_worklist[ 0 ];
        m_worklist.pop_front();

        DOUT( L"worklist item: [" << m_currentParam->GetName() << L"]" <<
              L", avg excl size: " << m_currentParam->GetAverageExclusionSize() <<
              L", num excls: " << m_currentParam->GetExclusionCount() <<
              L"\n"; )

        // We need buckets to hold the exclusions pertaining to each value
        vector<list<Exclusion *> > buckets( m_currentParam->GetValueCount() );

        for( ExclIterCollection::iterator ie =  m_currentParam->GetExclusions().begin();
                                          ie != m_currentParam->GetExclusions().end();
                                        ++ie )
        {
            // put ref to each exclusion in appropriate value-relative bucket
            // find this parameter in the exclusion
            Exclusion::iterator iExcl = find_if( ( *ie )->begin(), ( *ie )->end(),
                                                 bind2nd( MatchParameterPointer(), m_currentParam ) );

            // put the exclusion in the right bucket
            assert( iExcl != ( *ie )->end() );
            Exclusion* pExcl = const_cast<Exclusion*>( &**ie );
            buckets.at( iExcl->second ).push_back( pExcl );
        }

        // if all the buckets have something in them
        int n;
        for( n = 0; n < m_currentParam->GetValueCount(); ++n )
        {
            if( buckets[ n ].empty() ) break;
        }

        // if there was an empty bucket, go to the next entry in the worklist
        if( n < m_currentParam->GetValueCount() ) continue;

        // recursively build all cover sets, building up exclusion on other params
        Exclusion exclImplied;
        m_end = buckets.end();
        buildExclusion( exclImplied, buckets.begin() );

        peformDelete();
    }

    DOUT( L"Derivation: Finished\n" );
    DOUT( L"Exclusions:\n" );
    for( auto & exclusion : m_exclusions )
    {
        exclusion.Print();
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movq 0x50(%rdi), %rax
cmpl $0x0, 0x58(%rax)
jne 0x6a3b
movq %rdi, %rbx
movq 0x30(%rdi), %r14
leaq 0x20(%rdi), %r12
cmpq %r12, %r14
je 0x679b
leaq 0x20(%r14), %rdi
callq 0x8cca
movq %r14, %rdi
callq 0x54b0
movq %rax, %r14
cmpq %r12, %rax
jne 0x6782
movq 0x30(%rbx), %r14
movq %r14, 0x28(%rsp)
cmpq %r12, %r14
je 0x67cb
leaq 0x28(%rsp), %r15
movq %r15, %rdi
callq 0x661e
movq %r14, %rdi
callq 0x54b0
movq %rax, %r14
movq %rax, 0x28(%rsp)
cmpq %r12, %rax
jne 0x67ae
movq (%rbx), %r13
cmpq 0x8(%rbx), %r13
je 0x680a
leaq 0x60(%rbx), %r14
leaq 0x28(%rsp), %r15
movq (%r13), %rax
movl 0x38(%rax), %ecx
cmpl 0x80(%rax), %ecx
jg 0x6800
movq (%r13), %rax
movq %rax, 0x28(%rsp)
movq %r14, %rdi
movq %r15, %rsi
callq 0x896e
addq $0x8, %r13
cmpq 0x8(%rbx), %r13
jne 0x67dd
movq 0x70(%rbx), %rax
cmpq %rax, 0x90(%rbx)
je 0x6a19
leaq 0x60(%rbx), %rcx
movq %rcx, 0x20(%rsp)
movq %rsp, %r14
leaq 0x28(%rsp), %r13
movabsq $-0x5555555555555555, %r15 # imm = 0xAAAAAAAAAAAAAAAB
movq %r12, 0x18(%rsp)
movq %rax, %rcx
subq 0x78(%rbx), %rcx
sarq $0x3, %rcx
cmpq $0x40, %rcx
jb 0x6883
movq %rcx, %rax
shrq $0x6, %rax
movabsq $-0x400000000000000, %rdx # imm = 0xFC00000000000000
addq %rax, %rdx
testq %rcx, %rcx
cmovgq %rax, %rdx
movq 0x88(%rbx), %rax
movq %rdx, %rsi
shlq $0x6, %rsi
subq %rsi, %rcx
shlq $0x3, %rcx
addq (%rax,%rdx,8), %rcx
movq %rcx, %rax
movq (%rax), %rax
movq %rax, 0x48(%rbx)
movq 0x20(%rsp), %rdi
callq 0x6c40
movq 0x48(%rbx), %rax
movslq 0x38(%rax), %rsi
movq %r14, %rdi
movq %r13, %rdx
callq 0x6c8e
movq 0x48(%rbx), %rbp
movq 0x70(%rbp), %r13
leaq 0x60(%rbp), %rax
cmpq %rax, %r13
je 0x694b
movq 0x20(%r13), %r14
movq 0x38(%r14), %rax
leaq 0x28(%r14), %r12
cmpq %r12, %rax
je 0x68dd
cmpq %rbp, 0x20(%rax)
je 0x68dd
movq %rax, %rdi
callq 0x54b0
jmp 0x68c8
cmpq %r12, %rax
je 0x6a5b
movslq 0x28(%rax), %rbp
movq (%rsp), %r12
movq 0x8(%rsp), %rdx
subq %r12, %rdx
sarq $0x3, %rdx
imulq %r15, %rdx
cmpq %rbp, %rdx
jbe 0x6a4a
movl $0x18, %edi
callq 0x53c0
addq $0x20, %r14
leaq (,%rbp,2), %rcx
addq %rbp, %rcx
leaq (%r12,%rcx,8), %rbp
movq %r14, 0x10(%rax)
movq %rax, %rdi
movq %rbp, %rsi
callq 0x5080
incq 0x10(%rbp)
movq %r13, %rdi
callq 0x54b0
movq %rax, %r13
movq 0x48(%rbx), %rbp
jmp 0x68af
movslq 0x38(%rbp), %rax
testq %rax, %rax
setg %dl
movq 0x18(%rsp), %r12
movq %rsp, %r14
leaq 0x28(%rsp), %r13
jle 0x6992
movq (%rsp), %rcx
cmpq %rcx, (%rcx)
je 0x698e
leaq -0x1(%rax), %rdx
xorl %esi, %esi
cmpq %rsi, %rdx
je 0x6992
leaq 0x18(%rcx), %rdi
incq %rsi
cmpq 0x18(%rcx), %rdi
movq %rdi, %rcx
jne 0x6973
cmpq %rax, %rsi
setb %dl
testb %dl, %dl
jne 0x6a00
movl $0x0, 0x30(%rsp)
movq $0x0, 0x38(%rsp)
leaq 0x30(%rsp), %rax
movq %rax, 0x40(%rsp)
movq %rax, 0x48(%rsp)
xorps %xmm0, %xmm0
movups %xmm0, 0x30(%rax)
movups %xmm0, 0x20(%rax)
movb $0x0, 0x40(%rax)
movq 0x8(%rsp), %rax
movq %rax, 0x58(%rbx)
movq (%rsp), %rdx
movq %rbx, %rdi
movq %r13, %rsi
callq 0x6d1a
movq %rbx, %rdi
callq 0x665e
movq 0x58(%rsp), %rdi
testq %rdi, %rdi
je 0x69f8
movq 0x68(%rsp), %rsi
subq %rdi, %rsi
callq 0x53e0
movq %r13, %rdi
callq 0x791a
movq %r14, %rdi
callq 0x7104
movq 0x70(%rbx), %rax
cmpq %rax, 0x90(%rbx)
jne 0x683b
movq 0x30(%rbx), %rbx
cmpq %r12, %rbx
je 0x6a3b
leaq 0x20(%rbx), %rdi
callq 0x8cca
movq %rbx, %rdi
callq 0x54b0
movq %rax, %rbx
cmpq %r12, %rax
jne 0x6a22
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1f8fe(%rip), %rdi     # 0x2634f
movq %rbp, %rsi
xorl %eax, %eax
callq 0x55e0
leaq 0x1f70e(%rip), %rdi     # 0x26170
leaq 0x1f71f(%rip), %rsi     # 0x26188
leaq 0x1f733(%rip), %rcx     # 0x261a3
movl $0x152, %edx            # imm = 0x152
callq 0x52c0
movq %rax, %rbx
leaq 0x28(%rsp), %rdi
callq 0x70e2
jmp 0x6a8e
jmp 0x6a8b
movq %rax, %rbx
movq %rsp, %rdi
callq 0x7104
movq %rbx, %rdi
callq 0x56a0