Prevent repeated instantiations of some qRegisterNormalizedMetaType<>s [1/N] (QtGui)

Create macros that wrap the magic developed in
7d63efc16f65f98c657caa90e0d7e9b72a879ade and apply it to all
Q_DECLARE_METATYPE invocations that show up in Clang -ftime-trace for
a PCH'ed QtGui build.

Effects on compile times:

Clang 10 -ftme-trace:

  $ ClangBuildAnalyzer --analyze qtgui-before.trace  | head -n6
  Analyzing build trace from 'qtgui-before.trace'...
  **** Time summary:
  Compilation (523 times):
    Parsing (frontend):          628.3 s
    Codegen & opts (backend):    304.5 s

  $ ClangBuildAnalyzer --analyze qtgui-after.trace  | head -n6
  Analyzing build trace from 'qtgui-after.trace'...
  **** Time summary:
  Compilation (523 times):
    Parsing (frontend):          546.0 s
    Codegen & opts (backend):    304.4 s

GCC 11 time (bash builtin):

before:

  $ time for ((i=0; i < 3; ++i)) do touch src/gui/painting/qpolygon.h ; ninja libQt6Gui.so; done

  real    4m13,539s
  user    49m24,416s
  sys     3m18,177s

after:

  $ time for ((i=0; i < 3; ++i)) do touch src/gui/painting/qpolygon.h ; ninja libQt6Gui.so; done

  real    3m55,697s
  user    45m19,941s
  sys     3m7,370s

Task-number: QTBUG-97601
Pick-to: 6.3
Change-Id: Ia8e37a58937568a7ed21cfeb4b27274deca4d53b
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
Marc Mutz 2022-01-18 17:38:48 +01:00
parent 4440387b85
commit f29566c5a4
33 changed files with 82 additions and 33 deletions

View File

@ -177,6 +177,8 @@ Cpp.ignoredirectives += \
Q_CLASSINFO \ Q_CLASSINFO \
Q_DECLARE_INTERFACE \ Q_DECLARE_INTERFACE \
Q_DECLARE_METATYPE \ Q_DECLARE_METATYPE \
QT_DECL_METATYPE_EXTERN \
QT_IMPL_METATYPE_EXTERN \
Q_DECLARE_OPERATORS_FOR_FLAGS \ Q_DECLARE_OPERATORS_FOR_FLAGS \
Q_DECLARE_PRIVATE \ Q_DECLARE_PRIVATE \
Q_DECLARE_PRIVATE_D \ Q_DECLARE_PRIVATE_D \

View File

@ -44,6 +44,8 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
QT_IMPL_METATYPE_EXTERN(qfloat16)
/*! /*!
\class qfloat16 \class qfloat16
\keyword 16-bit Floating Point Support \keyword 16-bit Floating Point Support

View File

@ -367,7 +367,7 @@ inline auto qHypot(qfloat16 x, qfloat16 y, qfloat16 z)
QT_END_NAMESPACE QT_END_NAMESPACE
Q_DECLARE_METATYPE(qfloat16) QT_DECL_METATYPE_EXTERN(qfloat16, Q_CORE_EXPORT)
namespace std { namespace std {
template<> template<>

View File

@ -46,6 +46,8 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
QT_IMPL_METATYPE_EXTERN(QFileInfo)
QString QFileInfoPrivate::getFileName(QAbstractFileEngine::FileName name) const QString QFileInfoPrivate::getFileName(QAbstractFileEngine::FileName name) const
{ {
if (cache_enabled && !fileNames[(int)name].isNull()) if (cache_enabled && !fileNames[(int)name].isNull())

View File

@ -212,6 +212,6 @@ Q_CORE_EXPORT QDebug operator<<(QDebug, const QFileInfo &);
QT_END_NAMESPACE QT_END_NAMESPACE
Q_DECLARE_METATYPE(QFileInfo) QT_DECL_METATYPE_EXTERN(QFileInfo, Q_CORE_EXPORT)
#endif // QFILEINFO_H #endif // QFILEINFO_H

View File

@ -44,6 +44,8 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
QT_IMPL_METATYPE_EXTERN(QStorageInfo)
/*! /*!
\class QStorageInfo \class QStorageInfo
\inmodule QtCore \inmodule QtCore

View File

@ -120,6 +120,6 @@ Q_CORE_EXPORT QDebug operator<<(QDebug debug, const QStorageInfo &);
QT_END_NAMESPACE QT_END_NAMESPACE
Q_DECLARE_METATYPE(QStorageInfo) QT_DECL_METATYPE_EXTERN(QStorageInfo, Q_CORE_EXPORT)
#endif // QSTORAGEINFO_H #endif // QSTORAGEINFO_H

View File

@ -60,8 +60,7 @@ QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcCheckIndex, "qt.core.qabstractitemmodel.checkindex") Q_LOGGING_CATEGORY(lcCheckIndex, "qt.core.qabstractitemmodel.checkindex")
int qRegisterNormalizedMetaType_QList_QModelIndex(const QByteArray &name) QT_IMPL_METATYPE_EXTERN(QModelIndexList)
{ return qRegisterNormalizedMetaTypeImplementation<QList<QModelIndex>>(name); }
QPersistentModelIndexData *QPersistentModelIndexData::create(const QModelIndex &index) QPersistentModelIndexData *QPersistentModelIndexData::create(const QModelIndex &index)
{ {

View File

@ -537,12 +537,8 @@ inline Qt::ItemFlags QModelIndex::flags() const
inline size_t qHash(const QModelIndex &index, size_t seed = 0) noexcept inline size_t qHash(const QModelIndex &index, size_t seed = 0) noexcept
{ return size_t((size_t(index.row()) << 4) + size_t(index.column()) + index.internalId()) ^ seed; } { return size_t((size_t(index.row()) << 4) + size_t(index.column()) + index.internalId()) ^ seed; }
Q_CORE_EXPORT int qRegisterNormalizedMetaType_QList_QModelIndex(const QByteArray &name);
template <> inline int qRegisterNormalizedMetaType<QList<QModelIndex>>(const QByteArray &name)
{ return qRegisterNormalizedMetaType_QList_QModelIndex(name); }
QT_END_NAMESPACE QT_END_NAMESPACE
Q_DECLARE_METATYPE(QModelIndexList) QT_DECL_METATYPE_EXTERN(QModelIndexList, Q_CORE_EXPORT)
#endif // QABSTRACTITEMMODEL_H #endif // QABSTRACTITEMMODEL_H

View File

@ -50,6 +50,9 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
QT_IMPL_METATYPE_EXTERN(QItemSelectionRange)
QT_IMPL_METATYPE_EXTERN(QItemSelection)
/*! /*!
\class QItemSelectionRange \class QItemSelectionRange
\inmodule QtCore \inmodule QtCore

View File

@ -238,7 +238,7 @@ Q_CORE_EXPORT QDebug operator<<(QDebug, const QItemSelectionRange &);
QT_END_NAMESPACE QT_END_NAMESPACE
Q_DECLARE_METATYPE(QItemSelectionRange) QT_DECL_METATYPE_EXTERN(QItemSelectionRange, Q_CORE_EXPORT)
Q_DECLARE_METATYPE(QItemSelection) QT_DECL_METATYPE_EXTERN(QItemSelection, Q_CORE_EXPORT)
#endif // QITEMSELECTIONMODEL_H #endif // QITEMSELECTIONMODEL_H

View File

@ -43,6 +43,8 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
QT_IMPL_METATYPE_EXTERN(QDeadlineTimer)
namespace { namespace {
class TimeReference class TimeReference
{ {

View File

@ -224,6 +224,6 @@ Q_DECLARE_SHARED(QDeadlineTimer)
QT_END_NAMESPACE QT_END_NAMESPACE
Q_DECLARE_METATYPE(QDeadlineTimer) QT_DECL_METATYPE_EXTERN(QDeadlineTimer, Q_CORE_EXPORT)
#endif // QDEADLINETIMER_H #endif // QDEADLINETIMER_H

View File

@ -97,6 +97,7 @@ QT_BEGIN_NAMESPACE
#define NS(x) QT_PREPEND_NAMESPACE(x) #define NS(x) QT_PREPEND_NAMESPACE(x)
QT_IMPL_METATYPE_EXTERN_TAGGED(QtMetaTypePrivate::QPairVariantInterfaceImpl, QPairVariantInterfaceImpl)
namespace { namespace {
struct DefinedTypesFilter { struct DefinedTypesFilter {

View File

@ -1257,19 +1257,36 @@ int qRegisterNormalizedMetaTypeImplementation(const QT_PREPEND_NAMESPACE(QByteAr
// This primary template calls the -Implementation, like all other specialisations should. // This primary template calls the -Implementation, like all other specialisations should.
// But the split allows to // But the split allows to
// - in a header: // - in a header:
// - declare, but not define, a specialization of this template // - define a specialization of this template calling an out-of-line function
// - add an explicit instantiation declaration (extern template ...) // (QT_DECL_METATYPE_EXTERN{,_TAGGED})
// - in the .cpp file: // - in the .cpp file:
// - define the specialization to call the -Implementation // - define the out-of-line wrapper to call the -Implementation
// - add an explicit instantiation definition // (QT_IMPL_METATYPE_EXTERN{,_TAGGED})
// This prevents the compiler from taking the leeway for inline functions in // The _TAGGED variants let you choose a tag (must be a C identifier) to disambiguate
// [temp.explicit]/13 Note 4 // the out-of-line function; the non-_TAGGED variants use the passed class name as tag.
template <typename T> template <typename T>
int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName) int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName)
{ {
return qRegisterNormalizedMetaTypeImplementation<T>(normalizedTypeName); return qRegisterNormalizedMetaTypeImplementation<T>(normalizedTypeName);
} }
#define QT_DECL_METATYPE_EXTERN_TAGGED(TYPE, TAG, EXPORT) \
QT_BEGIN_NAMESPACE \
EXPORT int qRegisterNormalizedMetaType_ ## TAG (const QByteArray &); \
template <> inline int qRegisterNormalizedMetaType< TYPE >(const QByteArray &name) \
{ return qRegisterNormalizedMetaType_ ## TAG (name); } \
QT_END_NAMESPACE \
Q_DECLARE_METATYPE(TYPE) \
/* end */
#define QT_IMPL_METATYPE_EXTERN_TAGGED(TYPE, TAG) \
int qRegisterNormalizedMetaType_ ## TAG (const QByteArray &name) \
{ return qRegisterNormalizedMetaTypeImplementation< TYPE >(name); } \
/* end */
#define QT_DECL_METATYPE_EXTERN(TYPE, EXPORT) \
QT_DECL_METATYPE_EXTERN_TAGGED(TYPE, TYPE, EXPORT)
#define QT_IMPL_METATYPE_EXTERN(TYPE) \
QT_IMPL_METATYPE_EXTERN_TAGGED(TYPE, TYPE)
template <typename T> template <typename T>
int qRegisterMetaType(const char *typeName) int qRegisterMetaType(const char *typeName)
{ {
@ -2521,6 +2538,7 @@ constexpr const QtPrivate::QMetaTypeInterface *const qt_incomplete_metaTypeArray
QT_END_NAMESPACE QT_END_NAMESPACE
Q_DECLARE_METATYPE(QtMetaTypePrivate::QPairVariantInterfaceImpl) QT_DECL_METATYPE_EXTERN_TAGGED(QtMetaTypePrivate::QPairVariantInterfaceImpl,
QPairVariantInterfaceImpl, Q_CORE_EXPORT)
#endif // QMETATYPE_H #endif // QMETATYPE_H

View File

@ -58,6 +58,9 @@ QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcSocketNotifierDeprecation) Q_DECLARE_LOGGING_CATEGORY(lcSocketNotifierDeprecation)
Q_LOGGING_CATEGORY(lcSocketNotifierDeprecation, "qt.core.socketnotifier_deprecation"); Q_LOGGING_CATEGORY(lcSocketNotifierDeprecation, "qt.core.socketnotifier_deprecation");
QT_IMPL_METATYPE_EXTERN_TAGGED(QSocketNotifier::Type, QSocketNotifier_Type)
QT_IMPL_METATYPE_EXTERN(QSocketDescriptor)
class QSocketNotifierPrivate : public QObjectPrivate class QSocketNotifierPrivate : public QObjectPrivate
{ {
Q_DECLARE_PUBLIC(QSocketNotifier) Q_DECLARE_PUBLIC(QSocketNotifier)

View File

@ -137,7 +137,8 @@ private:
}; };
QT_END_NAMESPACE QT_END_NAMESPACE
Q_DECLARE_METATYPE(QSocketNotifier::Type)
Q_DECLARE_METATYPE(QSocketDescriptor) QT_DECL_METATYPE_EXTERN_TAGGED(QSocketNotifier::Type, QSocketNotifier_Type, Q_CORE_EXPORT)
QT_DECL_METATYPE_EXTERN(QSocketDescriptor, Q_CORE_EXPORT)
#endif // QSOCKETNOTIFIER_H #endif // QSOCKETNOTIFIER_H

View File

@ -46,6 +46,8 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
QT_IMPL_METATYPE_EXTERN(QCborTag)
#include <cborerrorstrings.c> #include <cborerrorstrings.c>
/*! /*!

View File

@ -151,7 +151,7 @@ enum class QCborNegativeInteger : quint64 {};
QT_END_NAMESPACE QT_END_NAMESPACE
Q_DECLARE_METATYPE(QCborTag) QT_DECL_METATYPE_EXTERN(QCborTag, Q_CORE_EXPORT)
// To avoid changing namespace we need to reinstate defines, even though our .cpp // To avoid changing namespace we need to reinstate defines, even though our .cpp
// will then have to remove them again. // will then have to remove them again.

View File

@ -57,6 +57,9 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
QT_IMPL_METATYPE_EXTERN(QVersionNumber)
QT_IMPL_METATYPE_EXTERN(QTypeRevision)
/*! /*!
\class QVersionNumber \class QVersionNumber
\inmodule QtCore \inmodule QtCore

View File

@ -494,7 +494,7 @@ Q_CORE_EXPORT QDebug operator<<(QDebug, const QTypeRevision &revision);
QT_END_NAMESPACE QT_END_NAMESPACE
Q_DECLARE_METATYPE(QVersionNumber) QT_DECL_METATYPE_EXTERN(QVersionNumber, Q_CORE_EXPORT)
Q_DECLARE_METATYPE(QTypeRevision) QT_DECL_METATYPE_EXTERN(QTypeRevision, Q_CORE_EXPORT)
#endif // QVERSIONNUMBER_H #endif // QVERSIONNUMBER_H

View File

@ -53,6 +53,8 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
QT_IMPL_METATYPE_EXTERN(QDBusError)
static constexpr const auto errorMessages = qOffsetStringArray( static constexpr const auto errorMessages = qOffsetStringArray(
"NoError", "NoError",
"other", "other",

View File

@ -140,7 +140,7 @@ Q_DBUS_EXPORT QDebug operator<<(QDebug, const QDBusError &);
QT_END_NAMESPACE QT_END_NAMESPACE
Q_DECLARE_METATYPE(QDBusError) QT_DECL_METATYPE_EXTERN(QDBusError, Q_DBUS_EXPORT)
#else #else
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class Q_DBUS_EXPORT QDBusError {}; // dummy class for moc class Q_DBUS_EXPORT QDBusError {}; // dummy class for moc

View File

@ -44,6 +44,10 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
QT_IMPL_METATYPE_EXTERN(QDBusVariant)
QT_IMPL_METATYPE_EXTERN(QDBusObjectPath)
QT_IMPL_METATYPE_EXTERN(QDBusSignature)
void QDBusObjectPath::doCheck() void QDBusObjectPath::doCheck()
{ {
if (!QDBusUtil::isValidObjectPath(m_path)) { if (!QDBusUtil::isValidObjectPath(m_path)) {

View File

@ -189,9 +189,9 @@ inline bool operator==(const QDBusVariant &v1, const QDBusVariant &v2)
QT_END_NAMESPACE QT_END_NAMESPACE
Q_DECLARE_METATYPE(QDBusVariant) QT_DECL_METATYPE_EXTERN(QDBusVariant, Q_DBUS_EXPORT)
Q_DECLARE_METATYPE(QDBusObjectPath) QT_DECL_METATYPE_EXTERN(QDBusObjectPath, Q_DBUS_EXPORT)
Q_DECLARE_METATYPE(QDBusSignature) QT_DECL_METATYPE_EXTERN(QDBusSignature, Q_DBUS_EXPORT)
#endif // QT_NO_DBUS #endif // QT_NO_DBUS
#endif #endif

View File

@ -56,6 +56,8 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
QT_IMPL_METATYPE_EXTERN(QDBusMessage)
static_assert(QDBusMessage::InvalidMessage == DBUS_MESSAGE_TYPE_INVALID); static_assert(QDBusMessage::InvalidMessage == DBUS_MESSAGE_TYPE_INVALID);
static_assert(QDBusMessage::MethodCallMessage == DBUS_MESSAGE_TYPE_METHOD_CALL); static_assert(QDBusMessage::MethodCallMessage == DBUS_MESSAGE_TYPE_METHOD_CALL);
static_assert(QDBusMessage::ReplyMessage == DBUS_MESSAGE_TYPE_METHOD_RETURN); static_assert(QDBusMessage::ReplyMessage == DBUS_MESSAGE_TYPE_METHOD_RETURN);

View File

@ -131,7 +131,7 @@ Q_DBUS_EXPORT QDebug operator<<(QDebug, const QDBusMessage &);
QT_END_NAMESPACE QT_END_NAMESPACE
Q_DECLARE_METATYPE(QDBusMessage) QT_DECL_METATYPE_EXTERN(QDBusMessage, Q_DBUS_EXPORT)
#else #else
class Q_DBUS_EXPORT QDBusMessage {}; // dummy class for moc class Q_DBUS_EXPORT QDBusMessage {}; // dummy class for moc

View File

@ -48,6 +48,8 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_DBUS #ifndef QT_NO_DBUS
QT_IMPL_METATYPE_EXTERN(QDBusUnixFileDescriptor)
/*! /*!
\class QDBusUnixFileDescriptor \class QDBusUnixFileDescriptor
\inmodule QtDBus \inmodule QtDBus

View File

@ -85,7 +85,7 @@ Q_DECLARE_SHARED(QDBusUnixFileDescriptor)
QT_END_NAMESPACE QT_END_NAMESPACE
Q_DECLARE_METATYPE(QDBusUnixFileDescriptor) QT_DECL_METATYPE_EXTERN(QDBusUnixFileDescriptor, Q_DBUS_EXPORT)
#endif // QT_NO_DBUS #endif // QT_NO_DBUS
#endif // QDBUSUNIXFILEDESCRIPTOR_H #endif // QDBUSUNIXFILEDESCRIPTOR_H

View File

@ -44,6 +44,7 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
QT_IMPL_METATYPE_EXTERN_TAGGED(QSurface*, QSurface_ptr)
/*! /*!
\class QSurface \class QSurface

View File

@ -96,6 +96,6 @@ protected:
QT_END_NAMESPACE QT_END_NAMESPACE
Q_DECLARE_METATYPE(QSurface*) QT_DECL_METATYPE_EXTERN_TAGGED(QSurface*, QSurface_ptr, Q_GUI_EXPORT)
#endif //QSURFACE_H #endif //QSURFACE_H

View File

@ -43,6 +43,8 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
QT_IMPL_METATYPE_EXTERN_TAGGED(QTextOption::Tab, QTextOption_Tab)
struct QTextOptionPrivate struct QTextOptionPrivate
{ {
QList<QTextOption::Tab> tabStops; QList<QTextOption::Tab> tabStops;

View File

@ -151,6 +151,6 @@ inline void QTextOption::setTabStopDistance(qreal atabStop)
QT_END_NAMESPACE QT_END_NAMESPACE
Q_DECLARE_METATYPE( QTextOption::Tab ) QT_DECL_METATYPE_EXTERN_TAGGED(QTextOption::Tab, QTextOption_Tab, Q_GUI_EXPORT)
#endif // QTEXTOPTION_H #endif // QTEXTOPTION_H