gcc向け最適化をしてみた

gccで使えるテクニックの、スレッデッドコードというのが仮想マシンループにとても有効ということで、実装してみたのですが、
普通にswitch caseの方が早いんですが、これは…?



↓こんな感じで実装してます。

#ifdef __GNUC__
#	define XTAL_VM_OPT
#endif

#ifdef XTAL_VM_OPT

#define XTAL_VM_NODEFAULT } goto *label_table[*pc];
#define XTAL_VM_FIRST_CASE(key) Label##key: { 
#define XTAL_VM_CASE(key) } goto *label_table[*pc]; Label##key: {
#define XTAL_VM_SWITCH(x) goto *label_table[x];

#else

#define XTAL_VM_NODEFAULT } goto begin;
#define XTAL_VM_FIRST_CASE(key) case Inst##key::NUMBER: {
#define XTAL_VM_CASE(key) } goto begin; case Inst##key::NUMBER: {
#define XTAL_VM_SWITCH(x) switch(x)

#endif

void VMachineImpl::execute_inner(const inst_t* start){

#ifdef XTAL_VM_OPT

	static void* label_table[] = {
		&&LabelNop,
		&&LabelPushNull,
		&&LabelPushNop,
		&&LabelPushTrue,
		&&LabelPushFalse,
		
		...
	};
#else

#endif

begin:
XTAL_VM_SWITCH(*pc){
	
	XTAL_VM_FIRST_CASE(Nop){ pc += 命令サイズ; }
	XTAL_VM_CASE(PushNull){ push(null); pc += 命令サイズ; }
	XTAL_VM_CASE(PushTrue){ push(true); pc += 命令サイズ; }
	XTAL_VM_CASE(PushFalse){ push(false); pc += 命令サイズ; }
	XTAL_VM_CASE(PushNop){ push(nop); pc += 命令サイズ; }
	
	...

	XTAL_VM_NODEFAULT;
}