Example #1
0
extern  signed_32       NumValues( select_list *list, signed_32 hi ) {
/********************************************************************/

    signed_32           cases;

    cases = 0;
    while( list != NULL ) {
        if( SelCompare( list->high, hi ) > 0 ) break;
        cases += list->high - list->low + 1;
        list = list->next;
    }
    return( cases );
}
Example #2
0
signed_32       NumValues( select_list *list, signed_32 hi )
/**********************************************************/
{
    signed_32           cases;

    cases = 0;
    for( ; list != NULL; list = list->next ) {
        if( SelCompare( list->high, hi ) > 0 ) {
            break;
        }
        cases += list->high - list->low + 1;
    }
    return( cases );
}
Example #3
0
static  void    DoBinarySearch( an node, select_list *list, type_def *tipe,
                               int lo, int hi, label_handle other,
                               signed_32 lobound, signed_32 hibound,
                               bool have_lobound, bool have_hibound )
/*************************************************************************/
{
    int                 num;
    int                 mid;
    select_list         *mid_list;
    an                  cmp;
    label_handle        lt;

    mid = lo + ( hi - lo ) / 2;
    mid_list = list;
    for( num = mid; num > 0; --num ) {
        mid_list = mid_list->next;
    }
    if( lo == hi ) {
        if( have_lobound && lobound == mid_list->low
         && have_hibound && hibound == mid_list->high ) {
             BGControl( O_GOTO, NULL, mid_list->label );
             return;
        } else if( mid_list->low == mid_list->high ) {
            cmp = BGCompare( O_EQ, BGDuplicate( node ),
                             BGInteger( mid_list->low, tipe ), NULL, tipe );
            BGControl( O_IF_TRUE, cmp, mid_list->label );
            BGControl( O_GOTO, NULL, other );
            return;
        }
    }
    if( hi == mid + 1 && mid_list->next->low == mid_list->next->high ) {
        /* a linear sequence for three different non-sequential cases where
           c1<c2<c3, looks like:
        if( a == c3 ) goto l3;
        if( a == c2 ) goto l2;
        if( a != c1 ) goto default;
        l1: ...

           a binary sequence for these three cases looks like:
        if( a < c2 goto lt;    \
        if( a <= c2 ) goto l2; /only one cmp ins on x86
        if( a == c3 ) goto l3;
        goto default;
        lt:
        if ( a != c1 ) goto default;
        l1: ...

        Advantage of the linear search:
        * 3 goto's instead of 5, resulting in smaller code.
        Advantage of the binary search:
        * Execution time for all the cases is more balanced. which one is
          really faster depends a lot on the CPU's branch prediction and
          other things that are very hard to measure here.

        Using a linear search here for <= 3 cases to save on code size
        with negligible performance loss or gain.
        */
        mid_list = mid_list->next;
        cmp = BGCompare( O_EQ, BGDuplicate( node ),
                         BGInteger( mid_list->low, tipe ), NULL, tipe );
        BGControl( O_IF_TRUE, cmp, mid_list->label );
        /* Because we only compared for equality, it is only possible to
           decrease the upper bound if it was already set and equal to
           the value we are comparing to. Otherwise the incoming value
           may still be higher, where the inner call may produce an
           unconditional O_GOTO to a specific case label!
        */
        if( have_hibound && hibound == mid_list->low )
            hibound--;
        DoBinarySearch( node, list, tipe, lo, mid, other,
                        lobound, hibound, have_lobound, have_hibound );
        return;
    }
    lt = AskForNewLabel();
    if( !have_lobound || SelCompare( lobound, mid_list->low ) < 0 ) {
        if( have_hibound && SelCompare( hibound, mid_list->low ) < 0 ) {
            BGControl( O_GOTO, NULL, lt );
        } else {
            cmp = BGCompare( O_LT, BGDuplicate( node ),
                             BGInteger( mid_list->low, tipe ), NULL, tipe );
            BGControl( O_IF_TRUE, cmp, lt );
        }
    }
    if( !have_lobound || SelCompare( lobound, mid_list->high ) <= 0 ) {
        if( have_hibound && SelCompare( hibound, mid_list->high ) <= 0 ) {
            BGControl( O_GOTO, NULL, mid_list->label );
        } else {
            cmp = BGCompare( O_LE, BGDuplicate( node ),
                             BGInteger( mid_list->high, tipe ), NULL, tipe );
            BGControl( O_IF_TRUE, cmp, mid_list->label );
        }
    }
    if( mid < hi ) {
        DoBinarySearch( node, list, tipe, mid+1, hi, other,
                        mid_list->high+1, hibound, true, have_hibound );
    } else if( other != NULL ) {
        BGControl( O_GOTO, NULL, other );
    }
    BGControl( O_LABEL, NULL, lt );
    if( lo < mid ) {
        DoBinarySearch( node, list, tipe, lo, mid-1, other,
                        lobound, mid_list->low-1, have_lobound, true );
    } else if( other != NULL ) {
        BGControl( O_GOTO, NULL, other );
    }
}
Example #4
0
static  bool            NodeLess( void *s1, void *s2 )
/****************************************************/
{
    return( SelCompare( ((select_list *)s1)->low, ((select_list *)s2)->low ) < 0 );
}