Andy Melnikov (nponeccop) wrote,
Andy Melnikov
nponeccop

Лямбда-инкарнация HN0, квазизамыкания и гениальность MSVC2005

Ввиду проблем с ничего не делающими комбинаторами и с разделением программы на HN0 теперь - лямбда-выражения. Ниже - исходный текст и референс-реализация на С++:
// (lambda x y z) ((lambda plusx) * (plusx y) (plusx z)) ((lambda i) + x i)

struct plusx_closure
{
	int x;

	int operator()(int i)
	{
		return x + i;
	}
};

int func(int x, int y, int z)
{
	plusx_closure plusx = { x };
	return plusx(y) * plusx(z);
}
Заметьте, что в данном случае мы имеем дело с ограниченностью С++ как кросс-платформенного ассемблера. Для разделения x мы вынуждены его копировать в промежуточный фрейм стека, несмотря на то что функция теоретически может обращаться x непосредственно в родительском фрейме, как это происходит с вложенными функциями в Паскале. Вот стек и программа в идеальном случае (естественно, если инлайнить невыгодно):
z
y
x
адрес возврата
y|z
адрес возврата
func:
	push [y]
	call plusx_closure::operator()()
	mov R1, R0
	push [z]
	call plusx_closure::operator()()
	mul R0, R1
	ret
plusx_closure::operator()():
	mov R0, [i]
	add R0, [x]
	ret 1
MSVC2005 (v8) в отладочном режиме генерирует 2 полноценных стек-фрейма, а в релизе под х64 он умудрился... всё заинлайнить и скомпилировать func в три команды (2 сложения и одно умножение, спасибо базово-индексной адресации, 3-адресной команде lea и новым calling conventions):
?func@@YAHHHH@Z (int __cdecl func(int,int,int)):
  0000000000000000: 8D 04 11           lea         eax,[rcx+rdx]
  0000000000000003: 41 03 C8           add         ecx,r8d
  0000000000000006: 0F AF C1           imul        eax,ecx
  0000000000000009: C3                 ret
Да, вызов func(1,2,3) он заменяет константой на этапе компиляции. Вы еще сомневаетесь, что мне стоит компилировать в С++?
Tags: compiler design, hn0
Subscribe

  • Post a new comment

    Error

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 5 comments