Регистрация использования и компилятор WASM
Я использую Ubuntu на x86_64. Сначала я генерирую неоптимизированный код WebAssembly из clang. Код WebAssembly компилируется в машинный код, с помощью которого используется
cranelift
как компилирующий бэкенд.
Я делаю простое умножение матриц:
int first[m][n], second[p][q], multiply[m][q];
Вот машинный код для первого цикла из трех циклов
for ( int c = 0 ; c < m ; c++ ){}
создано
wasmtime
. Я нашел много необходимых инструкций, но я не могу найти соглашение о вызовах от кранового подъемника, которое требовало бы этих инструкций.
Мои вопросы в основном связаны с регистром, должен ли компилятор использовать его для получения
c
значение с помощью . Долженesi
значение сохранить? В противном случае, почему бы не использовать его напрямую, чтобы сделатьcmp
. Если да, то почему в1ad
мы используем esi для хранения 0, который изr14d
что из? Кроме того, значение 0 сохраняется вeax
, является ли eax энергонезависимым регистром?В
1b0
, если мы прямоcmp esi, r12d
и установите esi 0 или 1 в зависимости от результатов, нет необходимости в сложных шагах1ba
-1c3
Верно?Если я сгенерирую оптимизированный машинный код из оптимизированной WebAssembly, используя
wasm32-wasi-clang -O2
Я не думаю, что Cranelift сам по себе обеспечивает флаг оптимизации, я нахожу машинный код намного короче, но также трудным для понимания. Есть ли способы помочь мне читать оптимизированный машинный код? И еще, если мой машинный код из неоптимизированного wasm. Согласно анализу, который мы только что провели на этом примере с циклом for, можно ли сказать, что я обнаружил недостатки компилятора wasm, Cranelift?
Спасибо большое за вашу помощь! Я знаю, что код может быть неприятным для чтения, вы можете увеличить страницу, чтобы увидеть картинку.
195: rex mov DWORD PTR [rbx+rdx*1+0xc],eax ;int c = 0, eax preserves 0.
19a: rex mov edx,ecx ; edx = ecx = [rdi+0x60] + 0xffffffc0
19d: rex mov esi,DWORD PTR [rbx+rdx*1+0xc] ; esi = [0xc] = c, get c into register?
1a2: mov r12d,DWORD PTR [rbx+rdx*1+0x38] ; r12d = m
1a7: mov r14d,eax ;r14d = eax = 0
1aa: rex mov eax,esi ; eax = esi = [c] = c [[!!! abuse register, you can directly use esi for cmp, eax remains 0, instead of store eax value 0 in r14d,
;use eax for cmp, and at the end restore eax value 0 by esi (esi = r14d)]
1ad: mov esi,r14d ; esi = r14d = 0;
1b0: cmp eax,r12d ; cmp if eax (c) < r12d (m), if yes, al = 1, otherwise al = 0; {can use esi?? cmp usage ?}
1b3: setl al
1b6: movzx eax,al ; eax = al = 1 (if <) [movzx already uses zero-extension!!]
1ba: and eax,0x1 ; eax = 1 if (if <). [al is low 8 bits, set only supports one byte, Byte Set On Condition (setcc), why not directrly set r12d also has low 8 bit !!!! ]
1bd: mov r12d,eax ; r12d = eax = 1 (if <)
1c0: rex mov eax,esi ;eax = esi = r14d = 0; [restore eax = 0, but why use esi rather than r14d, actually you dont even need to restore eax
;if choose to replace eax with another register in CMP ]
1c3: mov esi,r12d ; esi = r12d = eax = 1 (if <) [!!if directly use esi for CMP, there is no need of mov 12d, eax then mov esi, r12d]
1c6: rex test esi,esi ;if esi=0 jump
1c9: je 2f0 <_wasm_function_3+0x227>