Hi, I have been analysing the gcc4.4 code due to the way it's handling: 1 extern void f(const char *); 2 extern void g(int); 3 4 #define C(n) case n: f(#n); break 5 6 void g(int n) 7 { 8 switch(n) 9 { 10 C(0); C(1); C(2); C(3); C(4); C(5); C(6); C(7); C(8); C(9); 11 C(10); C(11); C(12); C(13); C(14); C(15); C(16); C(17); C(18); C(19); 12 C(20); C(21); C(22); C(23); C(24); C(25); C(26); C(27); C(28); C(29); 13 14 C(1000); C(1001); C(1002); C(1003); C(1004); C(1005); C(1006); C(1007); C(1008); C(1009); 15 } 16 }
The interesting thing about this is that GCC generates much better code if I do: 1 extern void f(const char *); 2 extern void g(int); 3 4 #define C(n) case n: f(#n); break 5 6 void g(int n) 7 { 8 switch(n) 9 { 10 C(0); C(1); C(2); C(3); C(4); C(5); C(6); C(7); C(8); C(9); 11 C(10); C(11); C(12); C(13); C(14); C(15); C(16); C(17); C(18); C(19); 12 C(20); C(21); C(22); C(23); C(24); C(25); C(26); C(27); C(28); C(29); 13 } 14 switch(n) 15 { 16 C(1000); C(1001); C(1002); C(1003); C(1004); C(1005); C(1006); C(1007); C(1008); C(1009); 17 } 18 } In the first case, it generates a binary tree, and in the second two jump tables. The jump tables solution is much more elegant (at least in our situation), generating less code and being faster. Now, what I am wondering is the reason why GCC doesn't try to cluster the cases trying to find for clusters of contiguous values in the switch. If there is no specific reason then I would implement such pass, which would before expansion split switches according to value clustering, since I find it would be a good code improvement. Currently GCC seems to only use jump table is the range of the switch is not much bigger than its count, which works well in most cases except when you have big switches with clusters of contiguous values (like the first example I sent). Any comments on this would be appreciated. -- PMatos