c3a4ec5d0b
As the comment says, Haswell is a nice divider and is a good optimization target. I'm using -march=core-avx2 instead of -march=haswell because the latter form was only added to GCC 4.9 but we still support 4.7 and that has support for AVX2. This commit changes the AVX2-optimized code in QtGui to Haswell- optimized instead. That means, for example, that qdrawhelper_avx2.cpp can now use the FMA instructions. Change-Id: If025d476890745368955fffd153129c1716ba006 Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
194 lines
7.0 KiB
Plaintext
194 lines
7.0 KiB
Plaintext
#
|
|
# W A R N I N G
|
|
# -------------
|
|
#
|
|
# This file is not part of the Qt API. It exists purely as an
|
|
# implementation detail. It may change from version to version
|
|
# without notice, or even be removed.
|
|
#
|
|
# We mean it.
|
|
#
|
|
|
|
# Get the SIMD flags
|
|
load(qt_build_config)
|
|
|
|
# Set QT_CPU_FEATURES for convenience
|
|
QT_CPU_FEATURES = $$eval(QT_CPU_FEATURES.$$QT_ARCH)
|
|
|
|
#
|
|
# Set up compilers for SIMD (SSE/AVX, NEON etc)
|
|
#
|
|
defineTest(addSimdCompiler) {
|
|
name = $$1
|
|
upname = $$upper($$name)
|
|
headers_var = $${upname}_HEADERS
|
|
sources_var = $${upname}_SOURCES
|
|
csources_var = $${upname}_C_SOURCES
|
|
asm_var = $${upname}_ASM
|
|
|
|
CONFIG($$1) {
|
|
cflags = $$eval(QMAKE_CFLAGS_$${upname})
|
|
ltcg: cflags += $$QMAKE_CFLAGS_DISABLE_LTCG
|
|
contains(QT_CPU_FEATURES, $$name) {
|
|
# Default compiler settings include this feature, so just add to SOURCES
|
|
SOURCES += $$eval($$sources_var)
|
|
export(SOURCES)
|
|
} else {
|
|
# We need special compiler flags
|
|
|
|
# Split C and C++ sources
|
|
$$csources_var = $$find($$sources_var, ".*\\.c$")
|
|
$$sources_var -= $$eval($$csources_var)
|
|
export($$csources_var)
|
|
export($$sources_var)
|
|
|
|
# Add C++ compiler
|
|
$${name}_compiler.commands = $$QMAKE_CXX -c $(CXXFLAGS) $$cflags $(INCPATH) ${QMAKE_FILE_IN}
|
|
msvc: $${name}_compiler.commands += -Fo${QMAKE_FILE_OUT}
|
|
else: $${name}_compiler.commands += -o ${QMAKE_FILE_OUT}
|
|
|
|
$${name}_compiler.dependency_type = TYPE_C
|
|
$${name}_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)}
|
|
$${name}_compiler.input = $$sources_var
|
|
$${name}_compiler.variable_out = OBJECTS
|
|
$${name}_compiler.name = compiling[$${name}] ${QMAKE_FILE_IN}
|
|
silent: $${name}_compiler.commands = @echo compiling[$${name}] ${QMAKE_FILE_IN} && $$eval($${name}_compiler.commands)
|
|
QMAKE_EXTRA_COMPILERS += $${name}_compiler
|
|
|
|
export($${name}_compiler.commands)
|
|
export($${name}_compiler.dependency_type)
|
|
export($${name}_compiler.output)
|
|
export($${name}_compiler.input)
|
|
export($${name}_compiler.variable_out)
|
|
export($${name}_compiler.name)
|
|
|
|
# Add a C compiler
|
|
$${name}_c_compiler.commands = $$QMAKE_CC -c $(CFLAGS) $$cflags $(INCPATH) ${QMAKE_FILE_IN}
|
|
msvc: $${name}_c_compiler.commands += -Fo${QMAKE_FILE_OUT}
|
|
else: $${name}_c_compiler.commands += -o ${QMAKE_FILE_OUT}
|
|
|
|
$${name}_c_compiler.dependency_type = TYPE_C
|
|
$${name}_c_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)}
|
|
$${name}_c_compiler.input = $$csources_var
|
|
$${name}_c_compiler.variable_out = OBJECTS
|
|
$${name}_c_compiler.name = compiling[$${name}] ${QMAKE_FILE_IN}
|
|
silent: $${name}_c_compiler.commands = @echo compiling[$${name}] ${QMAKE_FILE_IN} && $$eval($${name}_c_compiler.commands)
|
|
QMAKE_EXTRA_COMPILERS += $${name}_c_compiler
|
|
|
|
export($${name}_c_compiler.commands)
|
|
export($${name}_c_compiler.dependency_type)
|
|
export($${name}_c_compiler.output)
|
|
export($${name}_c_compiler.input)
|
|
export($${name}_c_compiler.variable_out)
|
|
export($${name}_c_compiler.name)
|
|
}
|
|
|
|
# We always need an assembler (need to run the C compiler and without precompiled headers)
|
|
msvc {
|
|
# Don't know how to run MSVC's assembler...
|
|
!isEmpty($$asm_var): error("Sorry, not implemented: assembling $$upname for MSVC.")
|
|
} else: false {
|
|
# This is just for the IDE
|
|
SOURCES += $$eval($$asm_var)
|
|
export(SOURCES)
|
|
} else {
|
|
$${name}_assembler.commands = $$QMAKE_CC -c $(CFLAGS)
|
|
!contains(QT_CPU_FEATURES, $${name}): $${name}_assembler.commands += $$cflags
|
|
clang:no_clang_integrated_as: $${name}_assembler.commands += -fno-integrated-as
|
|
$${name}_assembler.commands += $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
|
|
$${name}_assembler.dependency_type = TYPE_C
|
|
$${name}_assembler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)}
|
|
$${name}_assembler.input = $$asm_var
|
|
$${name}_assembler.variable_out = OBJECTS
|
|
$${name}_assembler.name = assembling[$${name}] ${QMAKE_FILE_IN}
|
|
silent: $${name}_assembler.commands = @echo assembling[$${name}] ${QMAKE_FILE_IN} && $$eval($${name}_assembler.commands)
|
|
QMAKE_EXTRA_COMPILERS += $${name}_assembler
|
|
|
|
export($${name}_assembler.commands)
|
|
export($${name}_assembler.dependency_type)
|
|
export($${name}_assembler.output)
|
|
export($${name}_assembler.input)
|
|
export($${name}_assembler.variable_out)
|
|
export($${name}_assembler.name)
|
|
}
|
|
|
|
HEADERS += $$eval($$headers_var)
|
|
export(HEADERS)
|
|
export(QMAKE_EXTRA_COMPILERS)
|
|
}
|
|
}
|
|
addSimdCompiler(sse2)
|
|
addSimdCompiler(sse3)
|
|
addSimdCompiler(ssse3)
|
|
addSimdCompiler(sse4_1)
|
|
addSimdCompiler(sse4_2)
|
|
addSimdCompiler(aesni)
|
|
addSimdCompiler(shani)
|
|
addSimdCompiler(avx)
|
|
addSimdCompiler(avx2)
|
|
addSimdCompiler(avx512f)
|
|
addSimdCompiler(avx512cd)
|
|
addSimdCompiler(avx512er)
|
|
addSimdCompiler(avx512pf)
|
|
addSimdCompiler(avx512dq)
|
|
addSimdCompiler(avx512bw)
|
|
addSimdCompiler(avx512vl)
|
|
addSimdCompiler(avx512ifma)
|
|
addSimdCompiler(avx512vbmi)
|
|
addSimdCompiler(f16c)
|
|
addSimdCompiler(rdrnd)
|
|
addSimdCompiler(neon)
|
|
addSimdCompiler(mips_dsp)
|
|
addSimdCompiler(mips_dspr2)
|
|
|
|
# Haswell sub-architecture
|
|
defineTest(addSimdArch) {
|
|
name = arch_$$1
|
|
dependencies = $$2
|
|
upname = $$upper($$name)
|
|
|
|
cpu_features_missing =
|
|
for(part, dependencies) {
|
|
!contains(QT_CPU_FEATURES, $$part): cpu_features_missing = 1
|
|
}
|
|
|
|
CONFIG += $$name
|
|
isEmpty(cpu_features_missing): QT_CPU_FEATURES += $$name
|
|
|
|
export(QT_CPU_FEATURES)
|
|
export(CONFIG)
|
|
addSimdCompiler($$name)
|
|
}
|
|
|
|
isEmpty(QMAKE_CFLAGS_ARCH_HASWELL): QMAKE_CFLAGS_ARCH_HASWELL = $$QMAKE_CFLAGS_AVX2
|
|
avx2: addSimdArch(haswell, avx2 bmi bmi2 f16c fma lzcnt popcnt)
|
|
|
|
# Follow the Intel compiler's lead and define profiles of AVX512 instructions
|
|
defineTest(addAvx512Profile) {
|
|
name = $$1
|
|
dependencies = $$2
|
|
upname = $$upper($$name)
|
|
varname = QMAKE_CFLAGS_$$upname
|
|
|
|
cpu_features_missing =
|
|
cflags = $$QMAKE_CFLAGS_ARCH_HASWELL $$QMAKE_CFLAGS_AVX512F
|
|
for(part, dependencies) {
|
|
!CONFIG($$part): return() # Profile isn't supported by the compiler
|
|
|
|
uppart = $$upper($$part)
|
|
cflags *= $$eval(QMAKE_CFLAGS_$${uppart})
|
|
!contains(QT_CPU_FEATURES, $$uppart): cpu_features_missing += $$uppart
|
|
}
|
|
|
|
CONFIG += $$name
|
|
isEmpty(cpu_features_missing): QT_CPU_FEATURES += $$name
|
|
$$varname = $$cflags
|
|
|
|
export(QT_CPU_FEATURES)
|
|
export(CONFIG)
|
|
export($$varname)
|
|
addSimdCompiler($$name)
|
|
}
|
|
addAvx512Profile(avx512common, avx512cd)
|
|
addAvx512Profile(avx512core, avx512cd avx512bw avx512dq avx512vl)
|