1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtXmlPatterns module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qcommonsequencetypes_p.h"
41#include "qoptimizerblocks_p.h"
42
43#include "qoptimizationpasses_p.h"
44
45QT_BEGIN_NAMESPACE
46
47using namespace QPatternist;
48
49OptimizationPass::List OptimizationPasses::comparisonPasses;
50OptimizationPass::List OptimizationPasses::forPasses;
51OptimizationPass::List OptimizationPasses::ifThenPasses;
52OptimizationPass::List OptimizationPasses::notFN;
53
54void OptimizationPasses::Coordinator::init()
55{
56 static bool isInitialized = false; // STATIC DATA
57
58 if(isInitialized)
59 return;
60
61 isInitialized = true;
62
63 /* Note, below is many of the building blocks re-used in several passes
64 * in order to reduce memory use. Thus, when changing one building block
65 * it potentially affects many passes. */
66
67 /* ****************************************************** */
68 /* Rewrite "count(<expr>) ge 1" into "exists(<expr>)" */
69 OptimizationPass::ExpressionMarker firstFirstChild;
70 firstFirstChild.append(t: 0);
71 firstFirstChild.append(t: 0);
72
73 ExpressionIdentifier::List geOpIDs;
74 const ExpressionIdentifier::Ptr countFN(new ByIDIdentifier(Expression::IDCountFN));
75 geOpIDs.append(t: countFN);
76 geOpIDs.append(t: ExpressionIdentifier::Ptr(new IntegerIdentifier(1)));
77
78 QVector<Expression::ID> geMatcher;
79 geMatcher.append(t: Expression::IDValueComparison);
80 geMatcher.append(t: Expression::IDGeneralComparison);
81
82 const ExpressionIdentifier::Ptr ge(new ComparisonIdentifier(geMatcher,
83 AtomicComparator::OperatorGreaterOrEqual));
84
85 const ExpressionCreator::Ptr existsFN(new ByIDCreator(Expression::IDExistsFN));
86 const OptimizationPass::Ptr geToExists(new OptimizationPass(ge, geOpIDs, firstFirstChild, existsFN));
87 comparisonPasses.append(t: geToExists);
88 /* ****************************************************** */
89
90 /* ****************************************************** */
91 /* Rewrite "count(<expr>) gt 0" into "exists(<expr>)" */
92 ExpressionIdentifier::List countAndIntZero;
93 countAndIntZero.append(t: countFN);
94 const ExpressionIdentifier::Ptr zeroInteger(new IntegerIdentifier(0));
95 countAndIntZero.append(t: zeroInteger);
96
97 const ExpressionIdentifier::Ptr gt(new ComparisonIdentifier(geMatcher,
98 AtomicComparator::OperatorGreaterThan));
99
100 const OptimizationPass::Ptr gtToExists(new OptimizationPass(gt, countAndIntZero,
101 firstFirstChild, existsFN));
102 comparisonPasses.append(t: gtToExists);
103 /* ****************************************************** */
104
105 /* ****************************************************** */
106 /* Rewrite "count(<expr>) ne 0" into "exists(<expr>)" */
107
108 const ExpressionIdentifier::Ptr ne(new ComparisonIdentifier(geMatcher,
109 AtomicComparator::OperatorNotEqual));
110 const OptimizationPass::Ptr neToExists(new OptimizationPass(ne, countAndIntZero, firstFirstChild,
111 existsFN,
112 OptimizationPass::AnyOrder));
113 comparisonPasses.append(t: neToExists);
114 /* ****************************************************** */
115
116 /* ****************************************************** */
117 /* Rewrite "count(<expr>) eq 0" into "empty(<expr>)" */
118 ExpressionIdentifier::List eqOpIDs;
119 eqOpIDs.append(t: countFN);
120 eqOpIDs.append(t: zeroInteger);
121 const ExpressionCreator::Ptr emptyFN(new ByIDCreator(Expression::IDEmptyFN));
122 const ExpressionIdentifier::Ptr eq(new ComparisonIdentifier(geMatcher,
123 AtomicComparator::OperatorEqual));
124 const OptimizationPass::Ptr eqToEmpty(new OptimizationPass(eq, eqOpIDs, firstFirstChild,
125 emptyFN,
126 OptimizationPass::AnyOrder));
127 comparisonPasses.append(t: eqToEmpty);
128
129 /* ****************************************************** */
130
131 /* ****************************************************** */
132 /* Rewrite "for $var in <expr> return $var" into "<expr>" */
133 ExpressionIdentifier::List forOps;
134 OptimizationPass::ExpressionMarker firstChild;
135 firstChild.append(t: 0);
136
137 forOps.append(t: ExpressionIdentifier::Ptr());
138 forOps.append(t: ExpressionIdentifier::Ptr(new ByIDIdentifier(Expression::IDRangeVariableReference)));
139 const OptimizationPass::Ptr simplifyFor(new OptimizationPass(ExpressionIdentifier::Ptr(), forOps,
140 firstChild, ExpressionCreator::Ptr()));
141 forPasses.append(t: simplifyFor);
142 /* ****************************************************** */
143
144 /* ****************************************************** */
145 /* Rewrite "if(<expr>) then true() else false()" to "<expr>" */
146 OptimizationPass::ExpressionMarker marker;
147 marker.append(t: 0);
148
149 ExpressionIdentifier::List opIDs;
150 opIDs.append(t: ExpressionIdentifier::Ptr(new BySequenceTypeIdentifier(
151 CommonSequenceTypes::ExactlyOneBoolean)));
152 opIDs.append(t: ExpressionIdentifier::Ptr(new BooleanIdentifier(true)));
153 opIDs.append(t: ExpressionIdentifier::Ptr(new BooleanIdentifier(false)));
154
155 const OptimizationPass::Ptr pass(new OptimizationPass(ExpressionIdentifier::Ptr(), opIDs, marker));
156 ifThenPasses.append(t: pass);
157 /* ****************************************************** */
158
159 /* ****************************************************** */
160 /* Rewrite "not(exists(X))" into "empty(X)" */
161 ExpressionIdentifier::List idExistsFN;
162 idExistsFN.append(t: ExpressionIdentifier::Ptr(new ByIDIdentifier(Expression::IDExistsFN)));
163
164 notFN.append(t: OptimizationPass::Ptr(new OptimizationPass(ExpressionIdentifier::Ptr(),
165 idExistsFN,
166 firstFirstChild,
167 emptyFN)));
168
169 /* Rewrite "not(empty(X))" into "exists(X)" */
170 ExpressionIdentifier::List idEmptyFN;
171 idEmptyFN.append(t: ExpressionIdentifier::Ptr(new ByIDIdentifier(Expression::IDEmptyFN)));
172
173 notFN.append(t: OptimizationPass::Ptr(new OptimizationPass(ExpressionIdentifier::Ptr(),
174 idEmptyFN,
175 firstFirstChild,
176 existsFN)));
177 /* ****************************************************** */
178}
179
180QT_END_NAMESPACE
181

source code of qtxmlpatterns/src/xmlpatterns/expr/qoptimizationpasses.cpp