Add optimize_full qmake config option

This patch adds a new config option to qmake to enable full optimization
where it makes sense. This currently is supported on all gcc like
compilers by exchanging -O2 for -O3.

In qtbase it is used to enable full optimizations on qtcore and qtgui
and in a later patch can be used to replace similar existing logic in
QtWebKit's WTF and JavaScriptCore modules.

This fixes a performance regression from gcc 4.7 to 4.8 in the software
renderer.

An aliasing error in qregion.cpp which was exposed by more aggresive
optimization has been solved as well.

Change-Id: Ic2c6c41b79cb3846212b40e7bcc11ff492beb27f
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@digia.com>
This commit is contained in:
Allan Sandfeld Jensen 2014-02-14 13:57:35 +01:00 committed by The Qt Project
parent 2df1a6c4c9
commit cd652500af
7 changed files with 32 additions and 29 deletions

View File

@ -15,7 +15,7 @@ QMAKE_CC = gcc
QMAKE_LINK_C = $$QMAKE_CC
QMAKE_LINK_C_SHLIB = $$QMAKE_CC
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -O2 -g
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_OPTIMIZE -g
QMAKE_CXX = g++

View File

@ -31,11 +31,14 @@
# you can use the manual test in tests/manual/mkspecs.
#
QMAKE_CFLAGS_OPTIMIZE = -O2
QMAKE_CFLAGS_OPTIMIZE_FULL = -O3
QMAKE_CFLAGS += -pipe
QMAKE_CFLAGS_DEPS += -M
QMAKE_CFLAGS_WARN_ON += -Wall -W
QMAKE_CFLAGS_WARN_OFF += -w
QMAKE_CFLAGS_RELEASE += -O2
QMAKE_CFLAGS_RELEASE += $$QMAKE_CFLAGS_OPTIMIZE
QMAKE_CFLAGS_DEBUG += -g
QMAKE_CFLAGS_SHLIB += -fPIC
QMAKE_CFLAGS_STATIC_LIB += -fPIC

View File

@ -38,6 +38,15 @@ force_debug_info {
QMAKE_LFLAGS_RELEASE = $$QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO
}
optimize_full {
!isEmpty(QMAKE_CFLAGS_OPTIMIZE):!isEmpty(QMAKE_CFLAGS_OPTIMIZE_FULL) {
QMAKE_CFLAGS_RELEASE -= $$QMAKE_CFLAGS_OPTIMIZE
QMAKE_CXXFLAGS_RELEASE -= $$QMAKE_CFLAGS_OPTIMIZE
QMAKE_CFLAGS_RELEASE += $$QMAKE_CFLAGS_OPTIMIZE_FULL
QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_OPTIMIZE_FULL
}
}
debug {
QMAKE_CFLAGS += $$QMAKE_CFLAGS_DEBUG
QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_DEBUG

View File

@ -11,6 +11,8 @@ DEFINES += QT_NO_USING_NAMESPACE
win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x67000000
irix-cc*:QMAKE_CXXFLAGS += -no_prelink -ptused
CONFIG += optimize_full
# otherwise mingw headers do not declare common functions like putenv
mingw:QMAKE_CXXFLAGS_CXX11 = -std=gnu++0x

View File

@ -30,7 +30,7 @@ testcocoon {
mac:!ios: LIBS_PRIVATE += -framework Cocoa
CONFIG += simd
CONFIG += simd optimize_full
include(accessible/accessible.pri)
include(kernel/kernel.pri)

View File

@ -39,20 +39,6 @@
**
****************************************************************************/
#if defined(__OPTIMIZE__) && !defined(__INTEL_COMPILER) && defined(__GNUC__) \
&& (__GNUC__ * 100 + __GNUC_MINOR__ * 10 + __GNUC_PATCHLEVEL__ >= 440)
// GCC 4.4 supports #pragma GCC optimize and #pragma GCC target
# if (__GNUC__ * 100 + __GNUC_MINOR__ * 10 + __GNUC_PATCHLEVEL__ < 473)
// From GCC 4.7.3 onwards, GCC optimize can result in gcc bailing out with OOM
# pragma GCC optimize "O3"
# endif
# if defined(__i386__) && defined(__SSE2__) && !defined(__SSE2_MATH__)
# pragma GCC target "fpmath=sse"
# endif
#endif
#include <qglobal.h>
#ifdef Q_OS_IOS
// We don't build the NEON drawhelpers as they are implemented partly

View File

@ -3528,7 +3528,7 @@ static QRegionPrivate *PolygonRegion(const QPoint *Pts, int Count, int rule)
QPoint *pts; /* output buffer */
EdgeTableEntry *pPrevAET; /* ptr to previous AET */
EdgeTable ET; /* header node for ET */
EdgeTableEntry AET; /* header node for AET */
EdgeTableEntry *AET; /* header node for AET */
EdgeTableEntry *pETEs; /* EdgeTableEntries pool */
ScanLineListBlock SLLBlock; /* header for scanlinelist */
int fixWAET = false;
@ -3567,8 +3567,9 @@ static QRegionPrivate *PolygonRegion(const QPoint *Pts, int Count, int rule)
region->vectorize();
AET = new EdgeTableEntry;
pts = FirstPtBlock.pts;
CreateETandAET(Count, Pts, &ET, &AET, pETEs, &SLLBlock);
CreateETandAET(Count, Pts, &ET, AET, pETEs, &SLLBlock);
pSLL = ET.scanlines.next;
curPtBlock = &FirstPtBlock;
@ -3579,6 +3580,7 @@ static QRegionPrivate *PolygonRegion(const QPoint *Pts, int Count, int rule)
#ifndef QT_NO_DEBUG
qWarning("QRegion: creating region from big polygon failed...!");
#endif
delete AET;
delete region;
return 0;
}
@ -3596,11 +3598,11 @@ static QRegionPrivate *PolygonRegion(const QPoint *Pts, int Count, int rule)
* get to the next edge.
*/
if (pSLL && y == pSLL->scanline) {
loadAET(&AET, pSLL->edgelist);
loadAET(AET, pSLL->edgelist);
pSLL = pSLL->next;
}
pPrevAET = &AET;
pAET = AET.next;
pPrevAET = AET;
pAET = AET->next;
/*
* for each active edge
@ -3626,7 +3628,7 @@ static QRegionPrivate *PolygonRegion(const QPoint *Pts, int Count, int rule)
}
EVALUATEEDGEEVENODD(pAET, pPrevAET, y)
}
InsertionSort(&AET);
InsertionSort(AET);
}
} else {
/*
@ -3638,12 +3640,12 @@ static QRegionPrivate *PolygonRegion(const QPoint *Pts, int Count, int rule)
* get to the next edge.
*/
if (pSLL && y == pSLL->scanline) {
loadAET(&AET, pSLL->edgelist);
computeWAET(&AET);
loadAET(AET, pSLL->edgelist);
computeWAET(AET);
pSLL = pSLL->next;
}
pPrevAET = &AET;
pAET = AET.next;
pPrevAET = AET;
pAET = AET->next;
pWETE = pAET;
/*
@ -3681,8 +3683,8 @@ static QRegionPrivate *PolygonRegion(const QPoint *Pts, int Count, int rule)
* recompute the winding active edge table if
* we just resorted or have exited an edge.
*/
if (InsertionSort(&AET) || fixWAET) {
computeWAET(&AET);
if (InsertionSort(AET) || fixWAET) {
computeWAET(AET);
fixWAET = false;
}
}
@ -3706,6 +3708,7 @@ static QRegionPrivate *PolygonRegion(const QPoint *Pts, int Count, int rule)
free(curPtBlock);
curPtBlock = tmpPtBlock;
}
delete AET;
free(pETEs);
return region;
}