Angesichts dieses Codes:
#include <string.h>
int equal4(const char* a, const char* b)
{
return memcmp(a, b, 4) == 0;
}
int less4(const char* a, const char* b)
{
return memcmp(a, b, 4) < 0;
}
GCC 7 auf x86_64 führte eine Optimierung für den ersten Fall ein (Clang macht das schon lange):
mov eax, DWORD PTR [rsi]
cmp DWORD PTR [rdi], eax
sete al
movzx eax, al
Aber der zweite Fall ruft immer noch memcmp()
:
sub rsp, 8
mov edx, 4
call memcmp
add rsp, 8
shr eax, 31
Könnte eine ähnliche Optimierung auf den zweiten Fall angewendet werden? Was ist die beste Montage dafür, und gibt es einen klaren Grund, warum dies nicht getan wird (von GCC oder Clang)?
Sehen Sie es im Compiler Explorer von Godbolt: https://godbolt.org/g/jv8fcf
Was ich interessant finde, ist die beiläufige Missachtung der Ausrichtung; Dies funktioniert möglicherweise mit x86, aber auf anderen CPUs ist die Optimierung möglicherweise nicht gültig.
– Matthias M.
12. Juli 2017 um 15:02 Uhr
@MatthieuM. es muss nur auf der Zielarchitektur gültig sein
– Caleth
12. Juli 2017 um 15:21 Uhr
@Caleth: Stimme zu, aber ich frage mich, in welchem Stadium die Transformation durchgeführt wird. Das heißt, ob gcc in seinem mittleren Ende eine zielspezifische Optimierung verwendet (vielleicht abstrahiert) oder ob es Teil der Absenkung ist.
– Matthias M.
12. Juli 2017 um 16:31 Uhr
@MatthieuM. Sie können es herausfinden, indem Sie mit kompilieren
-fdump-tree-all -fdump-rtl-all
(zusätzlich zu allen anderen Schaltern). Dadurch wird die Zwischendarstellung nach jeder Optimierungsphase in eine Datei im aktuellen Arbeitsverzeichnis abgelegt, die nummeriert ist, damit Sie sie der Reihe nach durchlesen können. (Sie erhalten ungefähr 300 Dateien, wenn Sie dies tun. Die “Baum”-Dumps sind viel einfacher zu lesen als die “RTL”-Dumps. Sie sollten wahrscheinlich die Kapitel “RTL” und “Maschinenbeschreibung” der Internes Handbuch bevor Sie versuchen, die RTL-Dumps zu lesen.)– zol
12. Juli 2017 um 18:05 Uhr