zorba-coders team mailing list archive
-
zorba-coders team
-
Mailing list archive
-
Message #15518
[Merge] lp:~zorba-coders/zorba/markos-scratch into lp:zorba
Markos Zaharioudakis has proposed merging lp:~zorba-coders/zorba/markos-scratch into lp:zorba.
Commit message:
Optimized the MarkExpr and EliminateFlworVariables rules of the optimizer
Requested reviews:
Markos Zaharioudakis (markos-za)
For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/markos-scratch/+merge/130833
Optimized the MarkExpr and EliminateFlworVariables rules of the optimizer
--
https://code.launchpad.net/~zorba-coders/zorba/markos-scratch/+merge/130833
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'ChangeLog'
--- ChangeLog 2012-10-20 21:29:37 +0000
+++ ChangeLog 2012-10-22 15:15:32 +0000
@@ -6,6 +6,7 @@
New Features:
Optimizations:
+ * Optimized the MarkExpr and EliminateFlworVariables rules of the optimizer
Bug Fixes/Other Changes:
* Fixed mustCopyInputNodes() method of no-copy, and jsoniq functions.
=== modified file 'src/compiler/expression/expr.cpp'
--- src/compiler/expression/expr.cpp 2012-10-10 13:05:50 +0000
+++ src/compiler/expression/expr.cpp 2012-10-22 15:15:32 +0000
@@ -334,6 +334,8 @@
{
assert(type->get_quantifier() == TypeConstants::QUANT_ONE ||
type->get_quantifier() == TypeConstants::QUANT_QUESTION);
+
+ setNonDiscardable(ANNOTATION_TRUE_FIXED);
}
@@ -362,6 +364,7 @@
theCheckPrime(check_prime),
theQName(qname)
{
+ setNonDiscardable(ANNOTATION_TRUE_FIXED);
}
@@ -385,6 +388,8 @@
assert(TypeOps::is_subtype(sctx->get_typemanager(),
*type,
*GENV_TYPESYSTEM.ANY_ATOMIC_TYPE_STAR));
+
+ setNonDiscardable(ANNOTATION_TRUE_FIXED);
}
@@ -494,6 +499,9 @@
theCopyInputNodes(copyNodes)
{
compute_scripting_kind();
+
+ setUnfoldable(ANNOTATION_TRUE_FIXED);
+ setConstructsNodes(ANNOTATION_TRUE_FIXED);
}
@@ -530,7 +538,12 @@
{
compute_scripting_kind();
+ // Node constructors are unfoldable because if a node constructor is inside
+ // a loop, then it will create a different xml tree every time it is invoked,
+ // even if the constructor itself is "constant" (i.e. does not reference any
+ // varialbes)
setUnfoldable(ANNOTATION_TRUE_FIXED);
+ setConstructsNodes(ANNOTATION_TRUE_FIXED);
}
@@ -553,6 +566,7 @@
compute_scripting_kind();
setUnfoldable(ANNOTATION_TRUE_FIXED);
+ setConstructsNodes(ANNOTATION_TRUE_FIXED);
}
@@ -600,6 +614,7 @@
compute_scripting_kind();
setUnfoldable(ANNOTATION_TRUE_FIXED);
+ setConstructsNodes(ANNOTATION_TRUE_FIXED);
}
@@ -658,6 +673,7 @@
compute_scripting_kind();
setUnfoldable(ANNOTATION_TRUE_FIXED);
+ setConstructsNodes(ANNOTATION_TRUE_FIXED);
}
@@ -690,6 +706,7 @@
compute_scripting_kind();
setUnfoldable(ANNOTATION_TRUE_FIXED);
+ setConstructsNodes(ANNOTATION_TRUE_FIXED);
}
=== modified file 'src/compiler/expression/expr_base.cpp'
--- src/compiler/expression/expr_base.cpp 2012-10-20 21:29:37 +0000
+++ src/compiler/expression/expr_base.cpp 2012-10-22 15:15:32 +0000
@@ -122,6 +122,19 @@
/*******************************************************************************
********************************************************************************/
+expr::expr()
+ :
+ theCCB(NULL),
+ theSctx(NULL),
+ theUDF(NULL),
+ theFlags1(0)
+{
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
expr::expr(
CompilerCB* ccb,
static_context* sctx,
@@ -142,6 +155,8 @@
// This is the default. The constructors for certain exprs set different values.
setNonDiscardable(ANNOTATION_FALSE);
setUnfoldable(ANNOTATION_FALSE);
+ setConstructsNodes(ANNOTATION_FALSE);
+ setDereferencesNodes(ANNOTATION_FALSE);
}
=== modified file 'src/compiler/expression/expr_base.h'
--- src/compiler/expression/expr_base.h 2012-10-20 21:29:37 +0000
+++ src/compiler/expression/expr_base.h 2012-10-22 15:15:32 +0000
@@ -17,6 +17,8 @@
#ifndef ZORBA_COMPILER_EXPR_BASE
#define ZORBA_COMPILER_EXPR_BASE
+#include <map>
+
#include <zorba/config.h>
#include "common/shared_types.h"
@@ -27,7 +29,7 @@
#include "functions/function_consts.h"
-#include "types/typeimpl.h"
+//#include "types/typeimpl.h"
#include "context/static_context_consts.h"
@@ -135,7 +137,7 @@
typedef substitution_t::iterator subst_iter_t;
- typedef std::set<const var_expr *> FreeVars;
+ typedef std::set<var_expr *> FreeVars;
typedef enum
{
@@ -205,7 +207,7 @@
protected:
expr(CompilerCB*, static_context*, user_function*, const QueryLoc&, expr_kind_t);
- expr() : theCCB(NULL), theSctx(NULL), theUDF(NULL), theFlags1(0) {}
+ expr();
public:
virtual ~expr();
=== modified file 'src/compiler/expression/expr_iter.cpp'
--- src/compiler/expression/expr_iter.cpp 2012-10-08 12:09:36 +0000
+++ src/compiler/expression/expr_iter.cpp 2012-10-22 15:15:32 +0000
@@ -40,7 +40,7 @@
#define EXPR_ITER_BEGIN() switch (theState) { case 0:
-#define EXPR_ITER_END() theCurrentChild = expr::iter_done; }
+#define EXPR_ITER_END() theIsDone = true; }
#define EXPR_ITER_NEXT(subExprHandle) \
do \
@@ -48,10 +48,7 @@
theState = __LINE__; \
theCurrentChild = reinterpret_cast<expr**>(&(subExprHandle)); \
\
- if ((subExprHandle) != NULL) \
- { \
- return; \
- } \
+ return; \
\
case __LINE__:; \
\
@@ -64,10 +61,7 @@
theState = __LINE__; \
theCurrentChild = (subExprHandleP); \
\
- if (*(subExprHandleP) != NULL) \
- { \
- return; \
- } \
+ return; \
\
case __LINE__:; \
\
@@ -79,7 +73,8 @@
:
theExpr(e),
theCurrentChild(NULL),
- theState(0)
+ theState(0),
+ theIsDone(false)
{
#ifndef ZORBA_NO_FULL_TEXT
if (e->get_expr_kind() == ft_expr_kind)
@@ -210,12 +205,14 @@
case relpath_expr_kind:
{
- relpath_expr* pathExpr = static_cast<relpath_expr*>(theExpr);
-
EXPR_ITER_BEGIN();
- theArgsIter = pathExpr->theSteps.begin();
- theArgsEnd = pathExpr->theSteps.end();
+ {
+ relpath_expr* pathExpr = static_cast<relpath_expr*>(theExpr);
+ theArgsIter = pathExpr->theSteps.begin();
+ theArgsEnd = pathExpr->theSteps.end();
+ }
+
for (; theArgsIter != theArgsEnd; ++theArgsIter)
{
EXPR_ITER_NEXT(*theArgsIter);
@@ -239,15 +236,13 @@
case match_expr_kind:
{
- EXPR_ITER_BEGIN();
- EXPR_ITER_END();
+ theIsDone = true;
break;
}
case var_expr_kind:
{
- EXPR_ITER_BEGIN();
- EXPR_ITER_END();
+ theIsDone = true;
break;
}
@@ -265,8 +260,7 @@
case const_expr_kind:
{
- EXPR_ITER_BEGIN();
- EXPR_ITER_END();
+ theIsDone = true;
break;
}
@@ -323,7 +317,8 @@
EXPR_ITER_BEGIN();
- EXPR_ITER_NEXT(docExpr->theContent);
+ if (docExpr->theContent)
+ EXPR_ITER_NEXT(docExpr->theContent);
EXPR_ITER_END();
break;
@@ -336,8 +331,12 @@
EXPR_ITER_BEGIN();
EXPR_ITER_NEXT(elemExpr->theQNameExpr);
- EXPR_ITER_NEXT(elemExpr->theAttrs);
- EXPR_ITER_NEXT(elemExpr->theContent);
+
+ if (elemExpr->theAttrs)
+ EXPR_ITER_NEXT(elemExpr->theAttrs);
+
+ if (elemExpr->theContent)
+ EXPR_ITER_NEXT(elemExpr->theContent);
EXPR_ITER_END();
break;
@@ -350,7 +349,9 @@
EXPR_ITER_BEGIN();
EXPR_ITER_NEXT(attrExpr->theQNameExpr);
- EXPR_ITER_NEXT(attrExpr->theValueExpr);
+
+ if (attrExpr->theValueExpr)
+ EXPR_ITER_NEXT(attrExpr->theValueExpr);
EXPR_ITER_END();
break;
@@ -388,7 +389,8 @@
EXPR_ITER_BEGIN();
- EXPR_ITER_NEXT(e->theContentExpr);
+ if (e->theContentExpr)
+ EXPR_ITER_NEXT(e->theContentExpr);
EXPR_ITER_END();
break;
@@ -400,7 +402,8 @@
EXPR_ITER_BEGIN();
- EXPR_ITER_NEXT(e->theContentExpr);
+ if (e->theContentExpr)
+ EXPR_ITER_NEXT(e->theContentExpr);
EXPR_ITER_END();
break;
@@ -638,8 +641,12 @@
case var_decl_expr_kind:
{
var_decl_expr* varDeclExpr = static_cast<var_decl_expr*>(theExpr);
+
EXPR_ITER_BEGIN();
- EXPR_ITER_NEXT(varDeclExpr->theInitExpr);
+
+ if (varDeclExpr->theInitExpr)
+ EXPR_ITER_NEXT(varDeclExpr->theInitExpr);
+
EXPR_ITER_END();
break;
}
@@ -655,8 +662,7 @@
case flowctl_expr_kind:
{
- EXPR_ITER_BEGIN();
- EXPR_ITER_END();
+ theIsDone = true;
break;
}
@@ -709,10 +715,12 @@
theFTSelectionExprsEnd = theFTSelectionExprs.end();
for (; theFTSelectionExprsIter != theFTSelectionExprsEnd; ++theFTSelectionExprsIter)
{
- EXPR_ITER_NEXT2(*theFTSelectionExprsIter);
+ if (**theFTSelectionExprsIter)
+ EXPR_ITER_NEXT2(*theFTSelectionExprsIter);
}
- EXPR_ITER_NEXT(ftExpr->ftignore_);
+ if (ftExpr->ftignore_)
+ EXPR_ITER_NEXT(ftExpr->ftignore_);
EXPR_ITER_END();
break;
=== modified file 'src/compiler/expression/expr_iter.h'
--- src/compiler/expression/expr_iter.h 2012-09-19 21:16:15 +0000
+++ src/compiler/expression/expr_iter.h 2012-10-22 15:15:32 +0000
@@ -37,9 +37,10 @@
expr ** theCurrentChild;
int theState;
+ bool theIsDone;
- std::vector<expr*>::iterator theArgsIter;
- std::vector<expr*>::iterator theArgsEnd;
+ std::vector<expr*>::iterator theArgsIter;
+ std::vector<expr*>::iterator theArgsEnd;
flwor_expr::clause_list_t::iterator theClausesIter;
flwor_expr::clause_list_t::iterator theClausesBegin;
@@ -68,7 +69,7 @@
expr** operator*() const { return (theCurrentChild); }
- bool done() const { return theCurrentChild == expr::iter_done; }
+ bool done() const { return theIsDone; }
private:
// comparisson forbidden; use done()
=== modified file 'src/compiler/expression/flwor_expr.cpp'
--- src/compiler/expression/flwor_expr.cpp 2012-10-10 13:05:50 +0000
+++ src/compiler/expression/flwor_expr.cpp 2012-10-22 15:15:32 +0000
@@ -1093,53 +1093,97 @@
}
-/*******************************************************************************
- Put in the given vector the var_exprs for the variables defined by this flwor
- expr.
-********************************************************************************/
-void flwor_expr::get_vars_defined(std::vector<var_expr*>& varExprs) const
+/*****************************************************************************
+ Returns a set containing all the variables defined by the clauses of this
+ flwor expr.
+******************************************************************************/
+void flwor_expr::get_vars(expr::FreeVars& vars) const
{
- csize numClauses = theClauses.size();
+ csize numClauses = num_clauses();
for (csize i = 0; i < numClauses; ++i)
{
- const flwor_clause* c = theClauses[i];
-
- if (c->get_kind() == flwor_clause::for_clause)
- {
- const for_clause* fc = static_cast<const for_clause *>(c);
-
- varExprs.push_back(fc->get_var());
-
- if (fc->get_pos_var())
- varExprs.push_back(fc->get_pos_var());
- }
- else if (c->get_kind() == flwor_clause::let_clause)
- {
- const let_clause* lc = static_cast<const let_clause *>(c);
-
- varExprs.push_back(lc->get_var());
- }
- else if (c->get_kind() == flwor_clause::window_clause)
- {
- const window_clause* wc = static_cast<const window_clause *>(c);
-
- varExprs.push_back(wc->get_var());
-
- const flwor_wincond* startCond = wc->get_win_start();
- const flwor_wincond* stopCond = wc->get_win_stop();
- const flwor_wincond::vars& startVars = startCond->get_out_vars();
- const flwor_wincond::vars& stopVars = stopCond->get_out_vars();
-
- if (startVars.posvar) varExprs.push_back(startVars.posvar);
- if (startVars.curr) varExprs.push_back(startVars.curr);
- if (startVars.prev) varExprs.push_back(startVars.prev);
- if (startVars.next) varExprs.push_back(startVars.next);
-
- if (stopVars.posvar) varExprs.push_back(stopVars.posvar);
- if (stopVars.curr) varExprs.push_back(stopVars.curr);
- if (stopVars.prev) varExprs.push_back(stopVars.prev);
- if (stopVars.next) varExprs.push_back(stopVars.next);
+ const flwor_clause& c = *get_clause(i);
+
+ switch (c.get_kind())
+ {
+ case flwor_clause::for_clause:
+ {
+ const for_clause* fc = static_cast<const for_clause *>(&c);
+
+ vars.insert(fc->get_var());
+
+ if (fc->get_pos_var() != NULL)
+ vars.insert(fc->get_pos_var());
+
+ break;
+ }
+ case flwor_clause::let_clause:
+ {
+ const let_clause* lc = static_cast<const let_clause *>(&c);
+ vars.insert(lc->get_var());
+ break;
+ }
+ case flwor_clause::window_clause:
+ {
+ const window_clause* wc = static_cast<const window_clause *>(&c);
+
+ vars.insert(wc->get_var());
+
+ if (wc->get_win_start() != NULL)
+ {
+ const flwor_wincond* cond = wc->get_win_start();
+ const flwor_wincond::vars& condvars = cond->get_out_vars();
+
+ if (condvars.posvar != NULL) vars.insert(condvars.posvar);
+ if (condvars.curr != NULL) vars.insert(condvars.curr);
+ if (condvars.prev != NULL) vars.insert(condvars.prev);
+ if (condvars.next != NULL) vars.insert(condvars.next);
+ }
+
+ if (wc->get_win_stop() != NULL)
+ {
+ const flwor_wincond* cond = wc->get_win_stop();
+ const flwor_wincond::vars& condvars = cond->get_out_vars();
+
+ if (condvars.posvar != NULL) vars.insert(condvars.posvar);
+ if (condvars.curr != NULL) vars.insert(condvars.curr);
+ if (condvars.prev != NULL) vars.insert(condvars.prev);
+ if (condvars.next != NULL) vars.insert(condvars.next);
+ }
+
+ break;
+ }
+ case flwor_clause::group_clause:
+ {
+ const group_clause* gc = static_cast<const group_clause *>(&c);
+
+ flwor_clause::rebind_list_t::const_iterator ite = gc->beginGroupVars();
+ flwor_clause::rebind_list_t::const_iterator end = gc->endGroupVars();
+
+ for (; ite != end; ++ite)
+ {
+ vars.insert((*ite).second);
+ }
+
+ ite = gc->beginNonGroupVars();
+ end = gc->endNonGroupVars();
+
+ for (; ite != end; ++ite)
+ {
+ vars.insert((*ite).second);
+ }
+
+ break;
+ }
+ case flwor_clause::count_clause:
+ {
+ const count_clause* cc = static_cast<const count_clause *>(&c);
+ vars.insert(cc->get_var());
+ break;
+ }
+ default:
+ break;
}
}
}
=== modified file 'src/compiler/expression/flwor_expr.h'
--- src/compiler/expression/flwor_expr.h 2012-10-16 13:08:12 +0000
+++ src/compiler/expression/flwor_expr.h 2012-10-22 15:15:32 +0000
@@ -722,7 +722,7 @@
long defines_variable(const var_expr* v) const;
- void get_vars_defined(std::vector<var_expr*>& varExprs) const;
+ void get_vars(expr::FreeVars& vars) const;
// The following 5 methods are for the simple flwor only. They should be
// removed eventually.
=== modified file 'src/compiler/expression/update_exprs.cpp'
--- src/compiler/expression/update_exprs.cpp 2012-10-09 14:06:08 +0000
+++ src/compiler/expression/update_exprs.cpp 2012-10-22 15:15:32 +0000
@@ -52,6 +52,8 @@
theSourceExpr(sourceExpr)
{
compute_scripting_kind();
+
+ setUnfoldable(ANNOTATION_TRUE_FIXED);
}
=== modified file 'src/compiler/rewriter/rules/flwor_rules.cpp'
--- src/compiler/rewriter/rules/flwor_rules.cpp 2012-10-20 21:29:37 +0000
+++ src/compiler/rewriter/rules/flwor_rules.cpp 2012-10-22 15:15:32 +0000
@@ -40,13 +40,14 @@
namespace zorba
{
-static void
-collect_flw_vars(const flwor_expr&, expr::FreeVars&);
-
static bool is_trivial_expr(const expr*);
static bool
-safe_to_fold_single_use(var_expr*, TypeConstants::quantifier_t, const flwor_expr&);
+safe_to_fold_single_use(
+ var_expr*,
+ TypeConstants::quantifier_t,
+ const flwor_expr&,
+ const std::vector<const expr*>&);
static bool
var_in_try_or_loop(const var_expr*, const expr*, bool, bool, bool&);
@@ -89,12 +90,12 @@
class SubstVars : public PrePostRewriteRule
{
protected:
- const var_expr * theVarExpr;
+ var_expr * theVarExpr;
expr * theSubstExpr;
std::vector<expr*> thePath;
public:
- SubstVars(const var_expr* var, expr* subst)
+ SubstVars(var_expr* var, expr* subst)
:
PrePostRewriteRule(RewriteRule::SubstVars, "SubstVars"),
theVarExpr(var),
@@ -146,7 +147,7 @@
expr* subst_vars(
const RewriterContext& rCtx0,
expr* root,
- const var_expr* var,
+ var_expr* var,
expr* subst)
{
RewriterContext rCtx(rCtx0.getCompilerCB(),
@@ -242,7 +243,7 @@
const expr::FreeVars& whereVars = whereExpr->getFreeVars();
if (myVars.empty())
- collect_flw_vars(flwor, myVars);
+ flwor.get_vars(myVars);
expr::FreeVars diff;
std::set_intersection(myVars.begin(),
@@ -252,7 +253,7 @@
std::inserter(diff, diff.begin()));
if (diff.empty())
{
- flwor.remove_where_clause();
+ flwor.remove_clause(i);
if_expr* ifExpr = rCtx.theEM->
create_if_expr(sctx,
@@ -294,7 +295,7 @@
for(; ite != end; ++ite)
{
var_expr* var = ite->second;
- int uses = expr_tools::count_variable_uses(&flwor, var, 2);
+ int uses = expr_tools::count_variable_uses(&flwor, var, 1, NULL);
if (uses == 0 && !ite->first->isNonDiscardable())
{
@@ -313,10 +314,10 @@
var_expr* var = fc->get_var();
TypeConstants::quantifier_t domainQuant = domainType->get_quantifier();
ulong domainCount = domainType->max_card();
- const var_expr* pvar = fc->get_pos_var();
+ var_expr* pvar = fc->get_pos_var();
if (pvar != NULL &&
- expr_tools::count_variable_uses(&flwor, pvar, 1) == 0)
+ expr_tools::count_variable_uses(&flwor, pvar, 1, NULL) == 0)
{
fc->set_pos_var(NULL);
pvar = NULL;
@@ -367,7 +368,8 @@
}
}
- int uses = expr_tools::count_variable_uses(&flwor, var, 2);
+ std::vector<const expr*> refpath(16);
+ int uses = expr_tools::count_variable_uses(&flwor, var, 2, &refpath);
if (uses > 1 &&
is_trivial_expr(domainExpr) &&
@@ -381,7 +383,7 @@
(domainQuant == TypeConstants::QUANT_ONE || i == numClauses -1) &&
((is_trivial_expr(domainExpr) &&
domainQuant == TypeConstants::QUANT_ONE) ||
- safe_to_fold_single_use(var, domainQuant, flwor)))
+ safe_to_fold_single_use(var, domainQuant, flwor, refpath)))
{
subst_vars(rCtx, node, var, domainExpr);
substitute = true;
@@ -416,7 +418,8 @@
if (domainExpr->is_sequential())
continue;
- int uses = expr_tools::count_variable_uses(&flwor, var, 2);
+ std::vector<const expr*> refpath(16);
+ int uses = expr_tools::count_variable_uses(&flwor, var, 2, &refpath);
if (uses > 1 && is_trivial_expr(domainExpr))
{
@@ -425,7 +428,7 @@
}
else if (uses == 1 &&
(is_trivial_expr(domainExpr) ||
- safe_to_fold_single_use(var, TypeConstants::QUANT_ONE, flwor)))
+ safe_to_fold_single_use(var, TypeConstants::QUANT_ONE, flwor, refpath)))
{
subst_vars(rCtx, node, var, domainExpr);
substitute = true;
@@ -606,100 +609,6 @@
}
-/*****************************************************************************
- Returns a set containing all the variables defined by the clauses of a flwor
- expr.
-******************************************************************************/
-static void collect_flw_vars(const flwor_expr& flwor, expr::FreeVars& vars)
-{
- for (csize i = 0; i < flwor.num_clauses(); ++i)
- {
- const flwor_clause& c = *flwor.get_clause(i);
-
- switch (c.get_kind())
- {
- case flwor_clause::for_clause:
- {
- const for_clause* fc = static_cast<const for_clause *>(&c);
-
- vars.insert(fc->get_var());
-
- if (fc->get_pos_var() != NULL)
- vars.insert(fc->get_pos_var());
-
- break;
- }
- case flwor_clause::let_clause:
- {
- const let_clause* lc = static_cast<const let_clause *>(&c);
- vars.insert(lc->get_var());
- break;
- }
- case flwor_clause::window_clause:
- {
- const window_clause* wc = static_cast<const window_clause *>(&c);
-
- vars.insert(wc->get_var());
-
- if (wc->get_win_start() != NULL)
- {
- const flwor_wincond* cond = wc->get_win_start();
- const flwor_wincond::vars& condvars = cond->get_out_vars();
-
- if (condvars.posvar != NULL) vars.insert(condvars.posvar);
- if (condvars.curr != NULL) vars.insert(condvars.curr);
- if (condvars.prev != NULL) vars.insert(condvars.prev);
- if (condvars.next != NULL) vars.insert(condvars.next);
- }
-
- if (wc->get_win_stop() != NULL)
- {
- const flwor_wincond* cond = wc->get_win_stop();
- const flwor_wincond::vars& condvars = cond->get_out_vars();
-
- if (condvars.posvar != NULL) vars.insert(condvars.posvar);
- if (condvars.curr != NULL) vars.insert(condvars.curr);
- if (condvars.prev != NULL) vars.insert(condvars.prev);
- if (condvars.next != NULL) vars.insert(condvars.next);
- }
-
- break;
- }
- case flwor_clause::group_clause:
- {
- const group_clause* gc = static_cast<const group_clause *>(&c);
-
- flwor_clause::rebind_list_t::const_iterator ite = gc->beginGroupVars();
- flwor_clause::rebind_list_t::const_iterator end = gc->endGroupVars();
-
- for (; ite != end; ++ite)
- {
- vars.insert((*ite).second);
- }
-
- ite = gc->beginNonGroupVars();
- end = gc->endNonGroupVars();
-
- for (; ite != end; ++ite)
- {
- vars.insert((*ite).second);
- }
-
- break;
- }
- case flwor_clause::count_clause:
- {
- const count_clause* cc = static_cast<const count_clause *>(&c);
- vars.insert(cc->get_var());
- break;
- }
- default:
- break;
- }
- }
-}
-
-
/******************************************************************************
******************************************************************************/
@@ -749,7 +658,8 @@
static bool safe_to_fold_single_use(
var_expr* var,
TypeConstants::quantifier_t varQuant,
- const flwor_expr& flwor)
+ const flwor_expr& flwor,
+ const std::vector<const expr*>& refpath)
{
TypeManager* tm = var->get_type_manager();
@@ -758,9 +668,6 @@
bool declared = false;
expr* referencingExpr = NULL;
-
- //bool hasNodeConstr = var->get_domain_expr()->contains_node_construction();
-
csize numClauses = flwor.num_clauses();
for (csize i = 0; i < numClauses && referencingExpr == NULL; ++i)
@@ -789,7 +696,7 @@
return false;
// If X is referenced in the current FOR clause .....
- if (expr_tools::count_variable_uses(domExpr, var, 1) == 1)
+ if (std::find(refpath.begin(), refpath.end(), domExpr) != refpath.end())
{
referencingExpr = domExpr;
break;
@@ -815,7 +722,7 @@
assert(varQuant == TypeConstants::QUANT_ONE);
- if (expr_tools::count_variable_uses(clause->get_expr(), var, 1) == 1)
+ if (std::find(refpath.begin(), refpath.end(), clause->get_expr()) != refpath.end())
{
referencingExpr = clause->get_expr();
break;
@@ -837,7 +744,7 @@
for (; ite != end; ++ite)
{
- if (expr_tools::count_variable_uses(*ite, var, 1) == 1)
+ if (std::find(refpath.begin(), refpath.end(), *ite) != refpath.end())
{
referencingExpr = *ite;
break;
@@ -861,7 +768,7 @@
for (; ite != end; ++ite)
{
expr* inputExpr = ite->first;
- if (expr_tools::count_variable_uses(inputExpr, var, 1) == 1)
+ if (std::find(refpath.begin(), refpath.end(), inputExpr) != refpath.end())
{
referencingExpr = inputExpr;
break;
@@ -874,7 +781,7 @@
for (; ite != end; ++ite)
{
expr* inputExpr = ite->first;
- if (expr_tools::count_variable_uses(inputExpr, var, 1) == 1)
+ if (std::find(refpath.begin(), refpath.end(), inputExpr) != refpath.end())
{
referencingExpr = inputExpr;
break;
@@ -900,7 +807,7 @@
if (domExpr->is_sequential())
return false;
- if (expr_tools::count_variable_uses(domExpr, var, 1) == 1)
+ if (std::find(refpath.begin(), refpath.end(), domExpr) != refpath.end())
{
referencingExpr = domExpr;
break;
@@ -909,13 +816,13 @@
if (domExpr->get_return_type()->max_card() > 1)
return false;
- if (expr_tools::count_variable_uses(startExpr, var, 1) == 1)
+ if (std::find(refpath.begin(), refpath.end(), startExpr) != refpath.end())
{
referencingExpr = domExpr;
break;
}
- if (expr_tools::count_variable_uses(stopExpr, var, 1) == 1)
+ if (std::find(refpath.begin(), refpath.end(), stopExpr) != refpath.end())
{
referencingExpr = domExpr;
break;
@@ -945,7 +852,7 @@
if (retExpr->is_sequential())
return false;
- if (expr_tools::count_variable_uses(retExpr, var, 1) == 1)
+ if (std::find(refpath.begin(), refpath.end(), retExpr) != refpath.end())
{
if (varQuant != TypeConstants::QUANT_ONE)
{
@@ -1435,7 +1342,7 @@
expr* arg = andExpr->get_arg(i);
if (is_positional_pred(flwor, clausePos, arg, posVar, posExpr, compKind) &&
- expr_tools::count_variable_uses(flwor, posVar, 2) <= 1)
+ expr_tools::count_variable_uses(flwor, posVar, 2, NULL) <= 1)
{
rewrite_positional_pred(rCtx, flwor, posVar, posExpr, compKind);
@@ -1457,7 +1364,7 @@
else
{
if (is_positional_pred(flwor, clausePos, whereExpr, posVar, posExpr, compKind) &&
- expr_tools::count_variable_uses(flwor, posVar, 2) <= 1)
+ expr_tools::count_variable_uses(flwor, posVar, 2, NULL) <= 1)
{
rewrite_positional_pred(rCtx, flwor, posVar, posExpr, compKind);
=== modified file 'src/compiler/rewriter/rules/fold_rules.cpp'
--- src/compiler/rewriter/rules/fold_rules.cpp 2012-10-20 21:29:37 +0000
+++ src/compiler/rewriter/rules/fold_rules.cpp 2012-10-22 15:15:32 +0000
@@ -236,194 +236,75 @@
iter.next();
}
- // Certain exprs are nondiscardable independently from their children.
- if (saveNonDiscardable != ANNOTATION_TRUE_FIXED)
- {
- if (node->is_sequential())
- {
- curNonDiscardable = ANNOTATION_TRUE_FIXED;
- }
- else
- {
- switch (node->get_expr_kind())
- {
- case fo_expr_kind:
- {
- fo_expr* fo = static_cast<fo_expr *>(node);
- function* f = fo->get_func();
-
- bool isErrorFunc = (dynamic_cast<const fn_error*>(f) != NULL);
-
- if (f->getKind() == FunctionConsts::FN_TRACE_2 ||
- isErrorFunc)
+ if (node->is_sequential())
+ {
+ curNonDiscardable = ANNOTATION_TRUE_FIXED;
+ curUnfoldable = ANNOTATION_TRUE_FIXED;
+ }
+ else
+ {
+ switch (node->get_expr_kind())
+ {
+ case fo_expr_kind:
+ {
+ fo_expr* fo = static_cast<fo_expr *>(node);
+ function* f = fo->get_func();
+
+ if (!f->isUdf())
+ {
+ if (FunctionConsts::FN_ERROR_0 <= f->getKind() &&
+ f->getKind() <= FunctionConsts::FN_TRACE_2)
{
curNonDiscardable = ANNOTATION_TRUE_FIXED;
- }
-
- break;
- }
-
- case cast_expr_kind:
- case treat_expr_kind:
- case promote_expr_kind:
- {
- curNonDiscardable = ANNOTATION_TRUE_FIXED;
- break;
- }
-
- default:
- {
- break;
- }
- }
- }
- }
-
- // Certain exprs are unfoldable independently from their children
- if (saveUnfoldable != ANNOTATION_TRUE_FIXED)
- {
- if (node->is_sequential())
- {
- curUnfoldable = ANNOTATION_TRUE_FIXED;
- }
- else
- {
- switch (node->get_expr_kind())
- {
- case fo_expr_kind:
- {
- fo_expr* fo = static_cast<fo_expr *>(node);
- function* f = fo->get_func();
-
- if (f->isUdf() && theIsLocal)
- {
- curUnfoldable = saveUnfoldable;
- }
- else
- {
- bool isErrorFunc = (dynamic_cast<const fn_error*>(f) != NULL);
-
- // Do not fold functions that always require access to the dynamic context,
- // or may need to access the implicit timezone (which is also in the dynamic
- // constext).
- if (isErrorFunc ||
- f->accessesDynCtx() ||
- maybe_needs_implicit_timezone(fo) ||
- !f->isDeterministic())
- {
- curUnfoldable = ANNOTATION_TRUE_FIXED;
- }
- }
-
- break;
- }
-
- case var_expr_kind:
- {
- var_expr::var_kind varKind = static_cast<var_expr *>(node)->get_kind();
-
- if (varKind == var_expr::prolog_var || varKind == var_expr::local_var)
curUnfoldable = ANNOTATION_TRUE_FIXED;
-
- break;
- }
-
- // Node constructors are unfoldable because if a node constructor is inside
- // a loop, then it will create a different xml tree every time it is invoked,
- // even if the constructor itself is "constant" (i.e. does not reference any
- // varialbes)
- case elem_expr_kind:
- case attr_expr_kind:
- case text_expr_kind:
- case pi_expr_kind:
- case doc_expr_kind:
- {
- curUnfoldable = ANNOTATION_TRUE_FIXED;
- break;
- }
-
- case delete_expr_kind:
- case insert_expr_kind:
- case rename_expr_kind:
- case replace_expr_kind:
- {
- curUnfoldable = ANNOTATION_TRUE_FIXED;
- break;
- }
-
- default:
- {
- break;
- }
- }
- }
- }
-
- if (saveDereferencesNodes != ANNOTATION_TRUE_FIXED)
- {
- switch (node->get_expr_kind())
- {
- case fo_expr_kind:
- {
- fo_expr* fo = static_cast<fo_expr *>(node);
- function* f = fo->get_func();
-
- if (!f->isUdf())
- {
- if (f->getKind() == FunctionConsts::FN_ZORBA_REF_NODE_BY_REFERENCE_1)
+ }
+ else if (f->getKind() == FunctionConsts::FN_ZORBA_REF_NODE_BY_REFERENCE_1)
+ {
curDereferencesNodes = ANNOTATION_TRUE;
+ }
+
+ // Do not fold functions that always require access to the dynamic context,
+ // or may need to access the implicit timezone (which is also in the dynamic
+ // constext).
+ if (saveUnfoldable != ANNOTATION_TRUE_FIXED &&
+ (f->accessesDynCtx() ||
+ maybe_needs_implicit_timezone(fo) ||
+ !f->isDeterministic()))
+ {
+ curUnfoldable = ANNOTATION_TRUE_FIXED;
+ }
}
else if (theIsLocal)
{
+ curUnfoldable = saveUnfoldable;
curDereferencesNodes = saveDereferencesNodes;
- }
- else if (static_cast<user_function*>(f)->dereferencesNodes())
- {
- curDereferencesNodes = ANNOTATION_TRUE;
- }
-
- break;
- }
-
- default:
- {
- break;
- }
- }
- }
-
- if (saveConstructsNodes != ANNOTATION_TRUE_FIXED)
- {
- switch (node->get_expr_kind())
- {
- case fo_expr_kind:
- {
- fo_expr* fo = static_cast<fo_expr *>(node);
- function* f = fo->get_func();
-
- if (f->isUdf() && theIsLocal)
- {
curConstructsNodes = saveConstructsNodes;
}
else
{
- if (f->isUdf() &&
- static_cast<user_function*>(f)->constructsNodes())
+ if (saveUnfoldable != ANNOTATION_TRUE_FIXED &&
+ (f->accessesDynCtx() || !f->isDeterministic()))
{
+ curUnfoldable = ANNOTATION_TRUE_FIXED;
+ }
+
+ if (static_cast<user_function*>(f)->dereferencesNodes())
+ curDereferencesNodes = ANNOTATION_TRUE;
+
+ if (static_cast<user_function*>(f)->constructsNodes())
curConstructsNodes = ANNOTATION_TRUE;
- }
}
break;
}
- case elem_expr_kind:
- case attr_expr_kind:
- case text_expr_kind:
- case pi_expr_kind:
- case doc_expr_kind:
+ case var_expr_kind:
{
- curConstructsNodes = ANNOTATION_TRUE_FIXED;
+ var_expr::var_kind varKind = static_cast<var_expr *>(node)->get_kind();
+
+ if (varKind == var_expr::prolog_var || varKind == var_expr::local_var)
+ curUnfoldable = ANNOTATION_TRUE_FIXED;
+
break;
}
@@ -493,7 +374,7 @@
fkind == FunctionConsts::FN_MIN_2 ||
fkind == FunctionConsts::FN_MAX_1 ||
fkind == FunctionConsts::FN_MAX_2)
- && TypeOps::maybe_date_time(tm, *TypeOps::prime_type(tm, *type0))) );
+ && TypeOps::maybe_date_time(tm, *type0)) );
}
=== modified file 'src/compiler/rewriter/tools/expr_tools.cpp'
--- src/compiler/rewriter/tools/expr_tools.cpp 2012-10-08 12:09:36 +0000
+++ src/compiler/rewriter/tools/expr_tools.cpp 2012-10-22 15:15:32 +0000
@@ -48,10 +48,11 @@
/*******************************************************************************
********************************************************************************/
-bool count_variable_uses_rec(
+bool count_var_uses_rec(
const expr* e,
const var_expr* var,
int limit,
+ std::vector<const expr*>* path,
int& count)
{
if (limit > 0 && count >= limit)
@@ -59,6 +60,11 @@
return false;
}
+ if (path && count == 0)
+ {
+ path->push_back(e);
+ }
+
if (e == var)
{
++count;
@@ -69,21 +75,29 @@
{
const if_expr* ifExpr = static_cast<const if_expr*>(e);
+ if (!count_var_uses_rec(ifExpr->get_cond_expr(), var, limit, path, count))
+ {
+ assert(count > 0);
+ return false;
+ }
+
int thenCount = 0;
+ std::vector<const expr*>* thenPath = (count == 0 ? path : NULL);
+
+ if (!count_var_uses_rec(ifExpr->get_then_expr(), var, limit, thenPath, thenCount))
+ {
+ count = thenCount;
+ assert(count > 0);
+ return false;
+ }
+
int elseCount = 0;
-
- if (!count_variable_uses_rec(ifExpr->get_cond_expr(), var, limit, count))
- return false;
-
- if (!count_variable_uses_rec(ifExpr->get_then_expr(), var, limit, thenCount))
- {
- count = thenCount;
- return false;
- }
-
- if (!count_variable_uses_rec(ifExpr->get_else_expr(), var, limit, elseCount))
+ std::vector<const expr*>* elsePath = (count == 0 ? path : NULL);
+
+ if (!count_var_uses_rec(ifExpr->get_else_expr(), var, limit, elsePath, elseCount))
{
count = elseCount;
+ assert(count > 0);
return false;
}
@@ -94,13 +108,21 @@
ExprConstIterator iter(e);
while (!iter.done())
{
- if (!count_variable_uses_rec(iter.get_expr(), var, limit, count))
+ if (!count_var_uses_rec(iter.get_expr(), var, limit, path, count))
+ {
+ assert(count > 0);
return false;
+ }
iter.next();
}
}
+ if (path && count == 0)
+ {
+ path->pop_back();
+ }
+
return true;
}
@@ -108,11 +130,15 @@
/*******************************************************************************
********************************************************************************/
-int count_variable_uses(const expr* root, const var_expr* var, int limit = 0)
+int count_variable_uses(
+ const expr* root,
+ const var_expr* var,
+ int limit,
+ std::vector<const expr*>* path)
{
int count = 0;
- count_variable_uses_rec(root, var, limit, count);
+ count_var_uses_rec(root, var, limit, path, count);
return count;
}
=== modified file 'src/compiler/rewriter/tools/expr_tools.h'
--- src/compiler/rewriter/tools/expr_tools.h 2012-10-08 12:09:36 +0000
+++ src/compiler/rewriter/tools/expr_tools.h 2012-10-22 15:15:32 +0000
@@ -46,7 +46,11 @@
namespace expr_tools
{
-int count_variable_uses(const expr* root, const var_expr* var, int limit);
+int count_variable_uses(
+ const expr* root,
+ const var_expr* var,
+ int limit,
+ std::vector<const expr*>* path);
/*******************************************************************************
=== modified file 'src/compiler/translator/translator.cpp'
--- src/compiler/translator/translator.cpp 2012-10-10 13:05:50 +0000
+++ src/compiler/translator/translator.cpp 2012-10-22 15:15:32 +0000
@@ -9926,12 +9926,12 @@
var_expr* posVar = dotClause->get_pos_var();
var_expr* dotVar = dotClause->get_var();
- if (expr_tools::count_variable_uses(predExpr, posVar, 1) == 0 &&
- expr_tools::count_variable_uses(predExpr, dotVar, 1) == 0)
+ if (expr_tools::count_variable_uses(predExpr, posVar, 1, NULL) == 0 &&
+ expr_tools::count_variable_uses(predExpr, dotVar, 1, NULL) == 0)
{
flworExpr->remove_clause(2);
- if (expr_tools::count_variable_uses(predExpr, sizeVar, 1) == 0)
+ if (expr_tools::count_variable_uses(predExpr, sizeVar, 1, NULL) == 0)
{
expr* sourceExpr = sourceClause->get_expr();
=== modified file 'src/compiler/xqddf/value_index.cpp'
--- src/compiler/xqddf/value_index.cpp 2012-10-10 13:05:50 +0000
+++ src/compiler/xqddf/value_index.cpp 2012-10-22 15:15:32 +0000
@@ -284,7 +284,7 @@
if (var)
dotVar = var->getVar();
- std::vector<var_expr*> varExprs;
+ expr::FreeVars varExprs;
// Check constraints on the domain expr
analyzeExprInternal(getDomainExpr(),
@@ -365,7 +365,7 @@
expr* e,
std::vector<store::Item*>& sourceNames,
std::vector<expr*>& sourceExprs,
- std::vector<var_expr*>& varExprs,
+ FreeVars& varExprs,
expr* dotVar)
{
if (e->get_expr_kind() == fo_expr_kind)
@@ -411,12 +411,12 @@
ZORBA_ASSERT(varExpr->get_kind() == var_expr::local_var);
- varExprs.push_back(varExpr);
+ varExprs.insert(varExpr);
}
else if (e->get_expr_kind() == flwor_expr_kind ||
e->get_expr_kind() == gflwor_expr_kind)
{
- static_cast<const flwor_expr*>(e)->get_vars_defined(varExprs);
+ static_cast<const flwor_expr*>(e)->get_vars(varExprs);
}
else if (e->get_expr_kind() == var_expr_kind)
{
@@ -427,7 +427,7 @@
}
if (e != getDomainVariable() &&
- std::find(varExprs.begin(), varExprs.end(), e) == varExprs.end())
+ varExprs.find(static_cast<var_expr*>(e)) == varExprs.end())
{
RAISE_ERROR(zerr::ZDST0031_INDEX_HAS_FREE_VARS, e->get_loc(),
ERROR_PARAMS(theName->getStringValue()));
=== modified file 'src/compiler/xqddf/value_index.h'
--- src/compiler/xqddf/value_index.h 2012-09-19 21:16:15 +0000
+++ src/compiler/xqddf/value_index.h 2012-10-22 15:15:32 +0000
@@ -234,6 +234,8 @@
********************************************************************************/
class IndexDecl : public SimpleRCObject
{
+ typedef std::set<var_expr *> FreeVars;
+
public:
typedef enum
{
@@ -355,7 +357,7 @@
const store::Item* getSourceName(csize i) const { return theSourceNames[i]; }
- expr* getDomainSourceExpr(csize i) const { return theDomainSourceExprs[i]; }
+ const expr* getDomainSourceExpr(csize i) const { return theDomainSourceExprs[i]; }
void analyze(CompilerCB* ccb);
@@ -370,9 +372,9 @@
private:
void analyzeExprInternal(
expr* e,
- std::vector</*const */store::Item*>& sourceNames,
+ std::vector<store::Item*>& sourceNames,
std::vector<expr*>& sourceExprs,
- std::vector<var_expr*>& varExprs,
+ FreeVars& varExprs,
expr* dotVar);
};
=== modified file 'src/runtime/full_text/ft_token_matcher.cpp'
--- src/runtime/full_text/ft_token_matcher.cpp 2012-09-19 21:16:15 +0000
+++ src/runtime/full_text/ft_token_matcher.cpp 2012-10-22 15:15:32 +0000
@@ -23,6 +23,8 @@
#include "util/cxx_util.h"
#include "util/stl_util.h"
+#include "system/globalenv.h"
+
#include "ft_stop_words_set.h"
#include "ft_token_matcher.h"
#include "ft_util.h"
=== modified file 'src/runtime/full_text/ftcontains_visitor.cpp'
--- src/runtime/full_text/ftcontains_visitor.cpp 2012-09-19 21:16:15 +0000
+++ src/runtime/full_text/ftcontains_visitor.cpp 2012-10-22 15:15:32 +0000
@@ -24,6 +24,9 @@
#include "compiler/parser/query_loc.h"
#include "diagnostics/xquery_diagnostics.h"
#include "store/api/store.h"
+
+#include "system/globalenv.h"
+
#include "util/cxx_util.h"
#include "util/indent.h"
#include "util/stl_util.h"
=== modified file 'src/runtime/full_text/thesauri/wn_thesaurus.cpp'
--- src/runtime/full_text/thesauri/wn_thesaurus.cpp 2012-09-19 21:16:15 +0000
+++ src/runtime/full_text/thesauri/wn_thesaurus.cpp 2012-10-22 15:15:32 +0000
@@ -37,6 +37,8 @@
#include "diagnostics/xquery_diagnostics.h"
#include "zorbautils/locale.h"
+#include "system/globalenv.h"
+
#include "decode_base128.h"
#include "wn_db_segment.h"
#include "wn_synset.h"
=== modified file 'src/runtime/full_text/thesauri/xqftts_thesaurus.cpp'
--- src/runtime/full_text/thesauri/xqftts_thesaurus.cpp 2012-09-19 21:16:15 +0000
+++ src/runtime/full_text/thesauri/xqftts_thesaurus.cpp 2012-10-22 15:15:32 +0000
@@ -34,6 +34,8 @@
#include "diagnostics/xquery_diagnostics.h"
#include "diagnostics/dict.h"
+#include "system/globalenv.h"
+
#include "xqftts_thesaurus.h"
using namespace std;
Follow ups