Hi, Ken Raeburn <raeb...@raeburn.org> skribis:
> * Don't use addresses of code labels with LLVM, even if the compiler > supports them. At least with the version of LLVM GCC on my Mac ("gcc > version 4.2.1 (Based on Apple Inc. build 5658) (LLVM build > 2336.1.00)"), Damn, what compiler is this? It’s not the old GCC 4.2 fork? Is it Clang? GCC with DragonEgg? > the performance seems to be quite poor; "guild compile" was showing > about a 4x penalty in CPU time. (For psyntax-pp.go, it was 10 minutes > of CPU time vs 46 minutes.) Weird, would be good to see what happens. The two options for VM dispatching are:
#include <stdio.h> int vm_jt (const unsigned int *code) { static const void *jump_table[] = { &&op0, &&op1, &&op2 }; register const unsigned int *ip = code; #define NEXT goto *jump_table[*ip++] NEXT; op0: puts ("op0"); return 0; op1: puts ("op1"); NEXT; op2: puts ("op2"); NEXT; } int vm_switch (const unsigned int *code) { register const unsigned int *ip = code; while (1) switch (*ip++) { case 0: puts ("op0"); return 0; case 1: puts ("op1"); break; case 2: puts ("op2"); break; } }
Could you look at the code generated by that compiler for this file? With GCC 4.6.2 at -O2, the dispatch with labels-as-values looks like this: mov -4(%rbx), %eax movq jump_table.2080(,%rax,8), %rax addq $4, %rbx jmp *%rax In the other case it’s a series of comparisons like this: cmpl $2, %eax jne .L14 movl $.LC2, %edi call puts movl (%rbx), %eax addq $4, %rbx cmpl $1, %eax jne .L16 movl $.LC1, %edi call puts jmp .L14 > Later/future versions may do better, so we can update it with > version-number checks, unless we want to build performance tests into > the configure script, which doesn't sound like a great idea to me. Agreed, but OTOH #ifdef __LLVM__ isn’t future-proof. Thanks, Ludo’.