Clang (LLVM) Inline-Assembly - Mehrere Einschränkungen mit unnötigen Verschüttungen / Nachladungen
clang / gcc : Einige Inline-Assembly-Operanden können mit mehreren Einschränkungen erfüllt werden, z."rm"
, wenn ein Operand mit einem Register oder einer Speicherstelle zufrieden sein kann. Zum Beispiel multipliziert das 64 x 64 = 128 Bit:
__asm__ ("mulq %q3" : "=a" (rl), "=d" (rh) : "%0" (x), "rm" (y) : "cc")
Der generierte Code scheint eine Speicherbeschränkung für das Argument auszuwählen3
, was in Ordnung wäre, wenn wir ausgehungert registriert würden, um ein Verschütten zu vermeiden. Offensichtlich gibt es auf x86-64 weniger Registerdruck als auf IA32. Das Assembly - Snippet wurde jedoch generiert (vonklapperte) ist:
movq %rcx, -8(%rbp)
## InlineAsm Start
mulq -8(%rbp)
## InlineAsm End
Die Auswahl einer Speicherbeschränkung ist eindeutig sinnlos! Ändern der Einschränkung in:"r" (y)
Wir erhalten jedoch (indem wir ein Register erzwingen):
## InlineAsm Start
mulq %rcx
## InlineAsm End
wie erwartet. Diese Ergebnisse beziehen sich auf clang / LLVM 3.2 (aktuelle Xcode-Version). Die erste Frage:Warum sollte clang in diesem Fall die weniger effiziente Einschränkung auswählen?
Zweitens gibt es die weniger verbreiteten, durch Kommas getrennten,mehrfache alternative Beschränkung Syntax:"r,m" (y)
, welchesollte Bewerten Sie die Kosten für jede Alternative und wählen Sie die aus, die zu weniger Kopien führt. Dies scheint zu funktionieren,aber clang wählt einfach den ersten aus - wie belegt durch:"m,r" (y)
Ich könnte das einfach fallen lassen"m"
alternative Einschränkungen, aber dies drückt nicht den Bereich möglicher zulässiger Operanden aus. Dies bringt mich zur zweiten Frage:Wurden diese Probleme in 3.3 behoben oder zumindest bestätigt? Ich habe versucht, in LLVM-Entwicklungsarchiven nachzuschlagen, aber ich möchte lieber einige Antworten einholen, bevor ich Einschränkungen unnötig weiter einschränke oder an Projektdiskussionen usw. teilnehme.