clang (LLVM) inline assembly - wiele ograniczeń z bezużytecznymi wyciekami / przeładowaniami
clang / gcc : Niektóre wewnętrzne argumenty składania mogą być spełnione wieloma ograniczeniami, np."rm"
, gdy operand może być zadowolony z rejestru lub lokalizacji pamięci. Przykładowo, mnożenie 64 x 64 = 128 bitów:
__asm__ ("mulq %q3" : "=a" (rl), "=d" (rh) : "%0" (x), "rm" (y) : "cc")
Wygenerowany kod wydaje się wybierać ograniczenie pamięci dla argumentu3
, co byłoby w porządku, gdybyśmy byli zarejestrowani z głodem, aby uniknąć wycieku. Oczywiście jest mniej presji rejestrów na x86-64 niż na IA32. Jednak wygenerowany fragment zespołu (wgszczęk) jest:
movq %rcx, -8(%rbp)
## InlineAsm Start
mulq -8(%rbp)
## InlineAsm End
Wybór ograniczenia pamięci jest bezcelowy! Zmiana ograniczenia na:"r" (y)
jednak (wymuszając rejestr) otrzymujemy:
## InlineAsm Start
mulq %rcx
## InlineAsm End
zgodnie z oczekiwaniami. Wyniki te dotyczą clang / LLVM 3.2 (bieżąca wersja Xcode). Pierwsze pytanie:Dlaczego clang wybrał w tym przypadku mniej efektywne ograniczenie?
Po drugie, istnieje mniej rozpowszechniony, rozdzielony przecinkami,wielokrotne ograniczenie alternatywne składnia:"r,m" (y)
, którypowinien oszacować koszty każdej alternatywy i wybrać ten, który skutkuje mniejszym kopiowaniem. To wydaje się działać,ale clang po prostu wybiera pierwszy - o czym świadczą:"m,r" (y)
Mogłem po prostu upuścić"m"
alternatywne ograniczenia, ale to nie wyraża zakresu możliwych argumentów prawnych. To prowadzi mnie do drugiego pytania:Czy te problemy zostały rozwiązane lub przynajmniej potwierdzone w 3.3? Próbowałem przeglądać archiwa dev LLVM, ale wolałbym poprosić o kilka odpowiedzi, zanim niepotrzebnie ograniczyłbym dalsze ograniczenia lub przystąpiłbym do dyskusji o projekcie itp.