встроенная сборка clang (LLVM) - множество ограничений с бесполезными разливами / перезагрузками
лязг / гкц Некоторые операнды встроенной сборки могут быть удовлетворены несколькими ограничениями, например,"rm"
, когда операнд может быть удовлетворен регистром или ячейкой памяти. Например, умножение 64 x 64 = 128 бит:
__asm__ ("mulq %q3" : "=a" (rl), "=d" (rh) : "%0" (x), "rm" (y) : "cc")
Сгенерированный код появляется, чтобы выбрать ограничение памяти для аргумента3
, что было бы хорошо, если бы мы были зарегистрированы голодать, чтобы избежать разлива. Очевидно, что естьНа x86-64 регистрируется меньшее давление, чем на IA32. Однако сгенерированный фрагмент сборки (лязг) является:
movq %rcx, -8(%rbp)
## InlineAsm Start
mulq -8(%rbp)
## InlineAsm End
Выбирать ограничение памяти явно бессмысленно! Изменение ограничения на:"r" (y)
Однако (форсируя регистр) получаем:
## InlineAsm Start
mulq %rcx
## InlineAsm End
как и ожидалось. Эти результаты относятся к clang / LLVM 3.2 (текущий выпуск Xcode). Первый вопрос:Почему бы Clang выбрать менее эффективное ограничение в этом случае?
Во-вторых, есть менее широко используемые, разделенные запятыми,множественное альтернативное ограничение синтаксис:"r,m" (y)
, которыйдолжен оцените стоимость каждой альтернативы и выберите ту, которая приведет к меньшему количеству копирования. Это похоже на работу,но лязг просто выбирает первый - что подтверждается:"m,r" (y)
Я мог бы просто бросить"m"
альтернативные ограничения, но это нет выразить диапазон возможных юридических операндов. Это подводит меня ко второму вопросу:Были ли эти проблемы решены или хотя бы подтверждены в 3.3? Я'я пробовал просматривать архивы разработчиков LLVM, но яЯ бы предпочел получить ответы на некоторые вопросы, прежде чем излишне ограничивать ограничения или присоединиться к обсуждению проекта и т. д.