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;
-- Mailing list: https://launchpad.net/~zorba-coders Post to : zorba-coders@lists.launchpad.net Unsubscribe : https://launchpad.net/~zorba-coders More help : https://help.launchpad.net/ListHelp