// File: /workspace/github_cpp_makefile_star2_O2/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)
je 0x73ad
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rdi, %rbx
movq 0x30(%rdi), %r14
leaq 0x20(%rdi), %r12
cmpq %r12, %r14
je 0x73d3
leaq 0x20(%r14), %rdi
callq 0x9ac2
movq %r14, %rdi
callq 0x6500
movq %rax, %r14
jmp 0x73b8
movq 0x30(%rbx), %r15
leaq 0x28(%rsp), %r14
movq %r15, 0x28(%rsp)
cmpq %r12, %r15
je 0x73fb
movq %r14, %rdi
callq 0x7290
movq %r15, %rdi
callq 0x6500
movq %rax, %r15
jmp 0x73dc
movq %r12, (%rsp)
movq (%rbx), %r12
leaq 0x60(%rbx), %r14
leaq 0x28(%rsp), %r15
cmpq 0x8(%rbx), %r12
je 0x7436
movq (%r12), %rax
movl 0x38(%rax), %ecx
cmpl 0x80(%rax), %ecx
jg 0x7430
movq %rax, 0x28(%rsp)
movq %r14, %rdi
movq %r15, %rsi
callq 0x956e
addq $0x8, %r12
jmp 0x740b
leaq 0x70(%rbx), %rax
movq %rax, 0x8(%rsp)
leaq 0x30(%rsp), %r15
leaq 0x10(%rsp), %r12
leaq 0x28(%rsp), %r13
movq 0x90(%rbx), %rax
cmpq 0x70(%rbx), %rax
je 0x7576
movq 0x8(%rsp), %rdi
xorl %esi, %esi
callq 0x9636
movq (%rax), %rax
movq %rax, 0x48(%rbx)
movq %r14, %rdi
callq 0x7842
movq 0x48(%rbx), %rax
movslq 0x38(%rax), %rsi
movq %r12, %rdi
movq %r13, %rdx
callq 0x7860
movq 0x48(%rbx), %rdx
movq 0x70(%rdx), %rbp
leaq 0x60(%rdx), %rax
cmpq %rax, %rbp
je 0x74f1
movq 0x20(%rbp), %rsi
movq 0x38(%rsi), %rdi
addq $0x28, %rsi
callq 0x7051
movq 0x20(%rbp), %rcx
leaq 0x28(%rcx), %rdx
cmpq %rdx, %rax
je 0x759d
addq $0x20, %rcx
movq %rcx, 0x28(%rsp)
movslq 0x28(%rax), %rsi
movq %r12, %rdi
callq 0x78b2
movq %rax, %rdi
movq %r13, %rsi
callq 0x78d0
movq %rbp, %rdi
callq 0x6500
movq %rax, %rbp
movq 0x48(%rbx), %rdx
jmp 0x7495
movl 0x38(%rdx), %eax
movq 0x10(%rsp), %rdx
testl %eax, %eax
movl $0x0, %ecx
cmovlel %ecx, %eax
incq %rax
leaq -0x18(%rdx), %rcx
decq %rax
je 0x751e
leaq 0x18(%rcx), %rsi
cmpq 0x18(%rcx), %rsi
movq %rsi, %rcx
jne 0x750a
jmp 0x7569
andl $0x0, 0x30(%rsp)
andq $0x0, 0x38(%rsp)
movq %r15, 0x40(%rsp)
movq %r15, 0x48(%rsp)
xorps %xmm0, %xmm0
movups %xmm0, 0x30(%r15)
movups %xmm0, 0x20(%r15)
movb $0x0, 0x40(%r15)
movq 0x18(%rsp), %rax
movq %rax, 0x58(%rbx)
movq %rbx, %rdi
movq %r13, %rsi
callq 0x78dc
movq %rbx, %rdi
callq 0x72c8
movq %r13, %rdi
callq 0x7b50
movq %r12, %rdi
callq 0x7b66
jmp 0x744e
movq 0x30(%rbx), %rbx
movq (%rsp), %r14
cmpq %r14, %rbx
je 0x739e
leaq 0x20(%rbx), %rdi
callq 0x9ac2
movq %rbx, %rdi
callq 0x6500
movq %rax, %rbx
jmp 0x757e
leaq 0x1abae(%rip), %rdi     # 0x22152
leaq 0x1abbf(%rip), %rsi     # 0x2216a
leaq 0x1abd3(%rip), %rcx     # 0x22185
movl $0x152, %edx            # imm = 0x152
callq 0x6310
movq %rax, %rbx
leaq 0x28(%rsp), %rdi
callq 0x7b50
jmp 0x75d0
jmp 0x75cd
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x7b66
movq %rbx, %rdi
callq 0x66e0