Pytanie clang (LLVM) wbudowany zespół - wiele ograniczeń z bezużytecznymi rozlewami / przeładowaniami


clang / gcc : Niektóre wbudowane argumenty zespołu mogą być spełnione z wieloma ograniczeniami, np. "rm", gdy operand może być zadowolony z rejestru lub lokalizacji pamięci. Jako przykład: 64 x 64 = 128-bitowe mnożenie:

__asm__ ("mulq %q3" : "=a" (rl), "=d" (rh) : "%0" (x), "rm" (y) : "cc")

Wygenerowany kod wydaje się wybierać ograniczenie pamięci dla argumentu 3, byłoby dobrze, gdybyśmy byli głodzeni, aby uniknąć rozlania. Oczywiście jest mniej nacisku rejestru na x86-64 niż na IA32. Jednak wygenerowany fragment złożenia (przez szczę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. Te wyniki dotyczą programu clang / LLVM 3.2 (bieżące wydanie Xcode). Pierwsze pytanie: Dlaczego klang wybrałby mniej efektywne ograniczenie w tym przypadku?

Po drugie, jest mniej rozpowszechniony, rozdzielany przecinkami, wielokrotne ograniczenie alternatywne składnia:
"r,m" (y), który powinien oszacować koszty każdej alternatywy i wybrać taką, która powoduje mniejsze kopiowanie. Wydaje się działać, ale klang po prostu wybiera pierwszy - o czym świadczą: "m,r" (y)


Mógłbym po prostu upuścić "m" alternatywne ograniczenia, ale nie wyraża to 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 ograniczę ograniczenia lub przyłączę się do dyskusji na temat projektu itp.


11
2018-05-31 05:25


pochodzenie


Czy włączenie optymalizacji ma skutek? - bames53
@ bames53 - brak w ogóle. -O0 .. -O3 wszystkie dają taką samą ekspansję. - Brett Hale
Najlepszym rozwiązaniem dla odpowiedzi jest prawdopodobnie zgłoszenie błędu w narzędziu do śledzenia błędów llvm. - Stephen Canon


Odpowiedzi:


Miałem odpowiedź na cfe-dev (wymień listę programistów z przodu) od jednego z programistów:

LLVM obecnie zawsze rozlewa ograniczenia "rm" w celu uproszczenia   obsługa inline asm w backend (możesz zapytać na llvmdev, jeśli chcesz   Detale). Nie znam żadnych planów, aby to naprawić w najbliższej przyszłości.

Jest to wyraźnie "znany" problem. Jednym z celów clang jest prawidłowe obsłużenie wbudowanej składni gcc, między innymi rozszerzeniami, co robi w tym przypadku - po prostu niezbyt wydajnie. W skrócie, to nie jest błąd per se.


Ponieważ nie jest to błąd, zamierzam kontynuować "r,m" składnia ograniczenia. Uważam, że jest to obecnie najlepszy kompromis. gcc wybierze najlepszy - prawdopodobnie rejestru, gdzie to możliwe - i clang wymusi użycie rejestru, ignorując kolejne opcje po przecinku. Jeśli nic więcej, to nadal zachowuje semantyczna intencja opisu zespołu, tj. opisującego możliwy ograniczenia, nawet jeśli są ignorowane.


Ostatnia uwaga (20130715): Ten konkretny przykład nie będzie kompilowany przy użyciu "r,m" ograniczenie w jednej pozycji - musielibyśmy dostarczyć alternatywne dopasowanie dla każdego, np.

: "=a,a" (rl), "=d,d" (rh) : "%0,0" (x), "r,m" (y)

To jest wymagany dla wielu alternatywnych ograniczeń z GCC. Ale docieramy na terytorium, na którym GCC było znane z pokazywania błędów w przeszłości - niezależnie od tego, czy jest to prawdziwe z tego 4.8.1, Nie wiem. Clang działa bez alternatywy w innych ograniczeniach, które są niezgodne ze składnią GCC, i dlatego należy je uznać za błąd.

Jeśli wydajność jest krytyczna, użyj "r"w przeciwnym razie trzymaj się "rm" i być może klang rozwiąże to w przyszłości, nawet jeśli przyniesie korzyści GCC.


9
2018-06-06 05:17