Jest taki kod:
typedef unsigned long N;
// Tutaj wcześniejsza część kodu.
N k_0 = E_asm_I_bsr( num_0->digits[ e_0 ] );
if( n_0 )
{ N k = E_asm_I_bsr( n_0 );
n_0 <<= k_1 - k;
n_0 |= num_0->digits[ e_0 ] >> ( sizeof(N) * 8 - ( k_1 - k ));
if( n_0 < n_1 )
{ j = 1;
n_0 <<= j;
n_0 |= num_0->digits[ e_0 ] >> ( sizeof(N) * 8 - j );
}else
j = 0;
n_0 -= n_1;
if( n_0 & ( (N)~0 << j ))
{ if( !num_mod->digits_n )
{ if( !E_mem_Q_blk_I_prepend( &num_mod->digits, 1 ))
{ E_math_bignum_W( num_mod );
return ~0;
}
num_mod->digits_n++;
num_mod->digits[0] = 0;
}
num_mod->digits[0] |= n_0 >> j;
}
if(j)
{ if( n_0 & j )
{ if( k_0 != sizeof(N) * 8 - j )
k_0 = sizeof(N) * 8 - j;
num_0->digits[ e_0 ] |= (N)1 << k_0;
}else if( ~k_0 ) // Ma być ten warunek czy nie?
num_0->digits[ e_0 ] &= ((N)1 << ( sizeof(N) * 8 - j )) - 1;
}
}
if( !~k_0 )
{ n_0 = 0;
div = 0;
goto Cont;
}
// Tutaj dalsza część kodu.
Cont:
Funkcja E_asm_I_bsr
oblicza pozycję najbardziej znaczącego ustawionego bitu w liczbie. Oblicza za pomocą instrukcji BSR
asemblera maszyny x86, jednak z tą różnicą, że jeśli nie ma ustawionego żadnego bitu, to wynik jest zdefiniowany i wynosi ~0UL
czyli -1UL
.
W linii 5. obliczam k_0
dla wartości num_0->digits[ e_0 ]
z tablicy.
W linii 34. maskuję tę wartość num_0->digits[ e_0 ]
do jej mniej znaczącego fragmentu.
Ale w linii 33. jest warunek: jeśli k_0
wynosi ~0UL
czyli num_0->digits[ e_0 ]
wynosi 0, to nie maskuj tej wartości num_0->digits[ e_0 ]
, ponieważ i tak jest już zerem, więc nie ma co maskować.
Teoretycznie kompilator wygeneruje dla tego warunku z linii 33. skok warunkowy po sprawdzeniu, czy k_0
jest równe ~0UL
.
Możliwe są dwa przypadki:
- warunek z linii 33. jest
Wtedy nie zostaną wykonane instrukcje odczytu i przypisania do pamięci, które mogłyby być kosztowne. Ale zawsze musi być wykonany skok warunkowy ponad tymi instrukcjami. - warunku z linii 33. nie ma
Wtedy nie potrzeba wykonywać być może kosztownego skoku warunkowego, ale zawsze konieczny jest odczyt i zapis do pamięci.
To jest fragment funkcji usługowej i nie wiem, w jakich przypadkach wartość num_0->digits[ e_0 ]
będzie zerem lub nie.