// File: /workspace/github_cpp_makefile_star2_O3/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 0x6a24
movq %rdi, %rbx
movq 0x30(%rdi), %r14
leaq 0x20(%rdi), %r12
cmpq %r12, %r14
je 0x67af
leaq 0x20(%r14), %rdi
callq 0x8bc0
movq %r14, %rdi
callq 0x54b0
movq %rax, %r14
cmpq %r12, %rax
jne 0x6792
movq 0x30(%rbx), %r14
movq %r14, 0x28(%rsp)
cmpq %r12, %r14
je 0x67db
leaq 0x28(%rsp), %r15
movq %r15, %rdi
callq 0x663c
movq %r14, %rdi
callq 0x54b0
movq %rax, %r14
movq %rax, 0x28(%rsp)
cmpq %r12, %rax
jne 0x67be
movq (%rbx), %r13
movq 0x8(%rbx), %rax
cmpq %rax, %r13
je 0x681c
leaq 0x60(%rbx), %r14
leaq 0x28(%rsp), %r15
movq (%r13), %rcx
movl 0x38(%rcx), %edx
cmpl 0x80(%rcx), %edx
jg 0x6813
movq %rcx, 0x28(%rsp)
movq %r14, %rdi
movq %r15, %rsi
callq 0x888e
movq 0x8(%rbx), %rax
addq $0x8, %r13
cmpq %rax, %r13
jne 0x67f0
movq 0x70(%rbx), %rax
cmpq %rax, 0x90(%rbx)
je 0x6a02
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 0x88(%rbx), %rcx
movq %rax, %rsi
subq 0x78(%rbx), %rsi
movq %rsi, %rdx
sarq $0x3, %rdx
js 0x6873
cmpq $0x40, %rdx
jb 0x688c
movq %rdx, %rsi
shrq $0x6, %rsi
jmp 0x6877
sarq $0x9, %rsi
movq %rsi, %rax
shlq $0x6, %rax
subq %rax, %rdx
shlq $0x3, %rdx
addq (%rcx,%rsi,8), %rdx
movq %rdx, %rax
movq (%rax), %rax
movq %rax, 0x48(%rbx)
movq 0x20(%rsp), %rdi
callq 0x6c14
movq 0x48(%rbx), %rax
movslq 0x38(%rax), %rsi
movq %r14, %rdi
movq %r13, %rdx
callq 0x6c62
movq 0x48(%rbx), %rbp
movq 0x70(%rbp), %r13
leaq 0x60(%rbp), %rax
cmpq %rax, %r13
je 0x6954
movq 0x20(%r13), %r14
movq 0x38(%r14), %rax
leaq 0x28(%r14), %r12
cmpq %r12, %rax
je 0x68e6
cmpq %rbp, 0x20(%rax)
je 0x68e6
movq %rax, %rdi
callq 0x54b0
jmp 0x68d1
cmpq %r12, %rax
je 0x6a44
movslq 0x28(%rax), %rbp
movq (%rsp), %r12
movq 0x8(%rsp), %rdx
subq %r12, %rdx
sarq $0x3, %rdx
imulq %r15, %rdx
cmpq %rbp, %rdx
jbe 0x6a33
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 0x68b8
movslq 0x38(%rbp), %rax
movq (%rsp), %rdx
movq %rdx, %rcx
testq %rax, %rax
movq 0x18(%rsp), %r12
movq %rsp, %r14
leaq 0x28(%rsp), %r13
jle 0x697f
cmpq (%rcx), %rcx
je 0x69e9
addq $0x18, %rcx
decq %rax
jne 0x6971
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 %rbx, %rdi
movq %r13, %rsi
callq 0x6cea
movq %rbx, %rdi
callq 0x667c
movq 0x58(%rsp), %rdi
testq %rdi, %rdi
je 0x69e1
movq 0x68(%rsp), %rsi
subq %rdi, %rsi
callq 0x53e0
movq %r13, %rdi
callq 0x787c
movq %r14, %rdi
callq 0x70c0
movq 0x70(%rbx), %rax
cmpq %rax, 0x90(%rbx)
jne 0x684d
movq 0x30(%rbx), %rbx
cmpq %r12, %rbx
je 0x6a24
leaq 0x20(%rbx), %rdi
callq 0x8bc0
movq %rbx, %rdi
callq 0x54b0
movq %rax, %rbx
cmpq %r12, %rax
jne 0x6a0b
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1f915(%rip), %rdi     # 0x2634f
movq %rbp, %rsi
xorl %eax, %eax
callq 0x55e0
leaq 0x1f725(%rip), %rdi     # 0x26170
leaq 0x1f736(%rip), %rsi     # 0x26188
leaq 0x1f74a(%rip), %rcx     # 0x261a3
movl $0x152, %edx            # imm = 0x152
callq 0x52c0
movq %rax, %rbx
leaq 0x28(%rsp), %rdi
callq 0x709e
jmp 0x6a77
jmp 0x6a74
movq %rax, %rbx
movq %rsp, %rdi
callq 0x70c0
movq %rbx, %rdi
callq 0x56a0
nop