bonjour,

avez-vous une solution pour aider l'optimiseur à faire du "loop unwinding" ?

J'ai code qui avec un "while" fait une recherche dichotomique du nombre de bit qu'il faut pour stocker un certain entier (donc qui calcule floor(log2(n)) ),

et j'aimerais que l'optimiseur me produise un code assembleur dans ce style :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
private static int floorLog2(int i)    //do you see the binary tree? 5 comparisions
    {
        return
        i < 1 << 15 ? i < 1 << 07 ? i < 1 << 03 ? i < 1 << 01 ? i < 1 << 00 ? -1 : 00 :
                                                                i < 1 << 02 ? 01 : 02 :
                                                  i < 1 << 05 ? i < 1 << 04 ? 03 : 04 :
                                                                i < 1 << 06 ? 05 : 06 :
                                    i < 1 << 11 ? i < 1 << 09 ? i < 1 << 08 ? 07 : 08 :
                                                                i < 1 << 10 ? 09 : 10 :
                                                  i < 1 << 13 ? i < 1 << 12 ? 11 : 12 :
                                                                i < 1 << 14 ? 13 : 14 :
                      i < 1 << 23 ? i < 1 << 19 ? i < 1 << 17 ? i < 1 << 16 ? 15 : 16 :
                                                                i < 1 << 18 ? 17 : 18 :
                                                  i < 1 << 21 ? i < 1 << 20 ? 19 : 20 :
                                                                i < 1 << 22 ? 21 : 22 :
                                    i < 1 << 27 ? i < 1 << 25 ? i < 1 << 24 ? 23 : 24 :
                                                                i < 1 << 26 ? 25 : 26 :
                                                  i < 1 << 29 ? i < 1 << 28 ? 27 : 28 :
                                                                i < 1 << 30 ? 29 : 30;
}
mon code :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
 
#include <iostream>
template <typename T> T floor_log_2(T n) {
	T nb_bit_for_type = sizeof(T) * 8;
	T M = nb_bit_for_type/4;
	T d = nb_bit_for_type/2;
	T res = 0;
 
 
	while(M) {
		T tmp = 1 << d;
 
                if (n < tmp) {
			d -= M;
		} else {
		        d += M;
                }
	}
 
	T tmp = 1 << d;
	if (n >= tmp) {
		d += 1;
	}
 
	return d ;
}
 
 
int main() {
	int res;
	res = floor_log_2<unsigned char>(8); // 4
	res = floor_log_2<unsigned char>(3); // 2
	res = floor_log_2<unsigned char>(128); // 8
	res = floor_log_2<unsigned char>(127); // 7
	res = floor_log_2<unsigned char>(17); // 5
	res = floor_log_2<unsigned char>(24); // 5
	res = floor_log_2<unsigned char>(60); // 6
 
	res = floor_log_2<unsigned char>(1); // 1
	res = floor_log_2<unsigned char>(0); // 1 (oui)
	res = floor_log_2<unsigned char>(-1); // 8
 
	return 0;
}
en fait je ne comprends pas bien pourquoi visual 2013 il n'arrive pas à le faire direct (je n'ai pas la dernière version de gcc si quelqu'un voudrait bien regarder ce que ça donne ?)

et avec un template récursif (M et d comme paramètres template ?) ça peut l'aider ?