diff options
Diffstat (limited to 'src/xmlpatterns/expr/qoptimizationpasses.cpp')
-rw-r--r-- | src/xmlpatterns/expr/qoptimizationpasses.cpp | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/src/xmlpatterns/expr/qoptimizationpasses.cpp b/src/xmlpatterns/expr/qoptimizationpasses.cpp new file mode 100644 index 0000000..d970483 --- /dev/null +++ b/src/xmlpatterns/expr/qoptimizationpasses.cpp @@ -0,0 +1,182 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcommonsequencetypes_p.h" +#include "qoptimizerblocks_p.h" + +#include "qoptimizationpasses_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +OptimizationPass::List OptimizationPasses::comparisonPasses; +OptimizationPass::List OptimizationPasses::forPasses; +OptimizationPass::List OptimizationPasses::ifThenPasses; +OptimizationPass::List OptimizationPasses::notFN; + +void OptimizationPasses::Coordinator::init() +{ + static bool isInitialized = false; // STATIC DATA + + if(isInitialized) + return; + + isInitialized = true; + + /* Note, below is many of the building blocks re-used in several passes + * in order to reduce memory use. Thus, when changing one building block + * it potentially affects many passes. */ + + /* ****************************************************** */ + /* Rewrite "count(<expr>) ge 1" into "exists(<expr>)" */ + OptimizationPass::ExpressionMarker firstFirstChild; + firstFirstChild.append(0); + firstFirstChild.append(0); + + ExpressionIdentifier::List geOpIDs; + const ExpressionIdentifier::Ptr countFN(new ByIDIdentifier(Expression::IDCountFN)); + geOpIDs.append(countFN); + geOpIDs.append(ExpressionIdentifier::Ptr(new IntegerIdentifier(1))); + + QVector<Expression::ID> geMatcher; + geMatcher.append(Expression::IDValueComparison); + geMatcher.append(Expression::IDGeneralComparison); + + const ExpressionIdentifier::Ptr ge(new ComparisonIdentifier(geMatcher, + AtomicComparator::OperatorGreaterOrEqual)); + + const ExpressionCreator::Ptr existsFN(new ByIDCreator(Expression::IDExistsFN)); + const OptimizationPass::Ptr geToExists(new OptimizationPass(ge, geOpIDs, firstFirstChild, existsFN)); + comparisonPasses.append(geToExists); + /* ****************************************************** */ + + /* ****************************************************** */ + /* Rewrite "count(<expr>) gt 0" into "exists(<expr>)" */ + ExpressionIdentifier::List countAndIntZero; + countAndIntZero.append(countFN); + const ExpressionIdentifier::Ptr zeroInteger(new IntegerIdentifier(0)); + countAndIntZero.append(zeroInteger); + + const ExpressionIdentifier::Ptr gt(new ComparisonIdentifier(geMatcher, + AtomicComparator::OperatorGreaterThan)); + + const OptimizationPass::Ptr gtToExists(new OptimizationPass(gt, countAndIntZero, + firstFirstChild, existsFN)); + comparisonPasses.append(gtToExists); + /* ****************************************************** */ + + /* ****************************************************** */ + /* Rewrite "count(<expr>) ne 0" into "exists(<expr>)" */ + + const ExpressionIdentifier::Ptr ne(new ComparisonIdentifier(geMatcher, + AtomicComparator::OperatorNotEqual)); + const OptimizationPass::Ptr neToExists(new OptimizationPass(ne, countAndIntZero, firstFirstChild, + existsFN, + OptimizationPass::AnyOrder)); + comparisonPasses.append(neToExists); + /* ****************************************************** */ + + /* ****************************************************** */ + /* Rewrite "count(<expr>) eq 0" into "empty(<expr>)" */ + ExpressionIdentifier::List eqOpIDs; + eqOpIDs.append(countFN); + eqOpIDs.append(zeroInteger); + const ExpressionCreator::Ptr emptyFN(new ByIDCreator(Expression::IDEmptyFN)); + const ExpressionIdentifier::Ptr eq(new ComparisonIdentifier(geMatcher, + AtomicComparator::OperatorEqual)); + const OptimizationPass::Ptr eqToEmpty(new OptimizationPass(eq, eqOpIDs, firstFirstChild, + emptyFN, + OptimizationPass::AnyOrder)); + comparisonPasses.append(eqToEmpty); + + /* ****************************************************** */ + + /* ****************************************************** */ + /* Rewrite "for $var in <expr> return $var" into "<expr>" */ + ExpressionIdentifier::List forOps; + OptimizationPass::ExpressionMarker firstChild; + firstChild.append(0); + + forOps.append(ExpressionIdentifier::Ptr()); + forOps.append(ExpressionIdentifier::Ptr(new ByIDIdentifier(Expression::IDRangeVariableReference))); + const OptimizationPass::Ptr simplifyFor(new OptimizationPass(ExpressionIdentifier::Ptr(), forOps, + firstChild, ExpressionCreator::Ptr())); + forPasses.append(simplifyFor); + /* ****************************************************** */ + + /* ****************************************************** */ + /* Rewrite "if(<expr>) then true() else false()" to "<expr>" */ + OptimizationPass::ExpressionMarker marker; + marker.append(0); + + ExpressionIdentifier::List opIDs; + opIDs.append(ExpressionIdentifier::Ptr(new BySequenceTypeIdentifier( + CommonSequenceTypes::ExactlyOneBoolean))); + opIDs.append(ExpressionIdentifier::Ptr(new BooleanIdentifier(true))); + opIDs.append(ExpressionIdentifier::Ptr(new BooleanIdentifier(false))); + + const OptimizationPass::Ptr pass(new OptimizationPass(ExpressionIdentifier::Ptr(), opIDs, marker)); + ifThenPasses.append(pass); + /* ****************************************************** */ + + /* ****************************************************** */ + /* Rewrite "not(exists(X))" into "empty(X)" */ + ExpressionIdentifier::List idExistsFN; + idExistsFN.append(ExpressionIdentifier::Ptr(new ByIDIdentifier(Expression::IDExistsFN))); + + notFN.append(OptimizationPass::Ptr(new OptimizationPass(ExpressionIdentifier::Ptr(), + idExistsFN, + firstFirstChild, + emptyFN))); + + /* Rewrite "not(empty(X))" into "exists(X)" */ + ExpressionIdentifier::List idEmptyFN; + idEmptyFN.append(ExpressionIdentifier::Ptr(new ByIDIdentifier(Expression::IDEmptyFN))); + + notFN.append(OptimizationPass::Ptr(new OptimizationPass(ExpressionIdentifier::Ptr(), + idEmptyFN, + firstFirstChild, + existsFN))); + /* ****************************************************** */ +} + +QT_END_NAMESPACE |