← Back to team overview

zorba-coders team mailing list archive

[Merge] lp:~zorba-coders/zorba/gen-flwor-opt into lp:zorba

 

Markos Zaharioudakis has proposed merging lp:~zorba-coders/zorba/gen-flwor-opt into lp:zorba.

Requested reviews:
  Markos Zaharioudakis (markos-za)

For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/gen-flwor-opt/+merge/87444

general flwor compile-time optimizations
-- 
https://code.launchpad.net/~zorba-coders/zorba/gen-flwor-opt/+merge/87444
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'src/compiler/expression/fo_expr.cpp'
--- src/compiler/expression/fo_expr.cpp	2011-11-23 15:16:51 +0000
+++ src/compiler/expression/fo_expr.cpp	2012-01-04 09:24:32 +0000
@@ -38,7 +38,7 @@
 {
   if (v.begin_visit(*this))
   {
-    accept_children(v); 
+    accept_children(v);
   }
 
   v.end_visit(*this);
@@ -147,6 +147,17 @@
   return theFunction->getName();
 }
 
+void fo_expr::add_arg(expr_t e)
+{
+  theArgs.push_back(e);
+  compute_scripting_kind();
+}
+
+void fo_expr::add_args(const std::vector<expr_t> &args)
+{
+  theArgs.insert(theArgs.end(), args.begin(), args.end());
+  compute_scripting_kind();
+}
 
 void fo_expr::compute_scripting_kind()
 {
@@ -179,7 +190,7 @@
                                  ERROR_PARAMS(ZED(XUST0001_CONCAT)),
                                  ERROR_LOC(theArgs[i]->get_loc()));
         }
-        
+
         if (i > 0 && !is_updating() && !is_vacuous() && (argKind & UPDATING_EXPR))
         {
           throw XQUERY_EXCEPTION(err::XUST0001,
@@ -248,7 +259,7 @@
 
 expr_t fo_expr::clone(substitution_t& subst) const
 {
-  if (get_func()->getKind() == 
+  if (get_func()->getKind() ==
       FunctionConsts::ZORBA_STORE_COLLECTIONS_STATIC_DML_COLLECTION_1)
   {
     expr::subst_iter_t i = subst.find(this);

=== modified file 'src/compiler/expression/fo_expr.h'
--- src/compiler/expression/fo_expr.h	2012-01-03 12:10:06 +0000
+++ src/compiler/expression/fo_expr.h	2012-01-04 09:24:32 +0000
@@ -79,11 +79,25 @@
 
   const store::Item* get_fname() const;
 
+<<<<<<< TREE
   csize num_args() const { return theArgs.size(); }
 
   expr* get_arg(csize i) const { return theArgs[i].getp(); }
 
   void set_arg(csize i, expr* e) { theArgs[i] = e; }
+=======
+  ulong num_args() const { return (ulong)theArgs.size(); }
+
+  expr* get_arg(ulong i) const { return theArgs[i].getp(); }
+
+  const std::vector<expr_t>& get_args() const {return theArgs;}
+
+  void set_arg(ulong i, expr* e) { theArgs[i] = e; }
+>>>>>>> MERGE-SOURCE
+
+  void add_arg(expr_t e);
+
+  void add_args(const std::vector<expr_t> &args);
 
   void compute_scripting_kind();
 

=== modified file 'src/compiler/rewriter/rules/flwor_rules.cpp'
--- src/compiler/rewriter/rules/flwor_rules.cpp	2011-09-02 20:43:46 +0000
+++ src/compiler/rewriter/rules/flwor_rules.cpp	2012-01-04 09:24:32 +0000
@@ -173,7 +173,7 @@
   expr* whereExpr;
   if ((whereExpr = flwor.get_where()) != NULL && !flwor.has_sequential_clauses())
   {
-    const expr_tools::var_ptr_set& whereVars = 
+    const expr_tools::var_ptr_set& whereVars =
     expr_tools::get_varset_annotation(whereExpr);
 
     expr_tools::var_ptr_set diff;
@@ -229,7 +229,7 @@
       ulong domainCount = TypeOps::type_max_cnt(tm, *domainType);
       const var_expr* pvar = fc->get_pos_var();
 
-      if (pvar != NULL && 
+      if (pvar != NULL &&
           expr_tools::count_variable_uses(&flwor, pvar, &rCtx, 1) == 0)
       {
         MODIFY(fc->set_pos_var(NULL));
@@ -340,7 +340,7 @@
         let_clause_t save = lc;
         MODIFY(flwor.remove_clause(i));
         const QueryLoc& loc = var->get_loc();
-        var_expr_t fvar = new var_expr(sctx, loc, var_expr::for_var, var->get_name()); 
+        var_expr_t fvar = new var_expr(sctx, loc, var_expr::for_var, var->get_name());
         for_clause_t fc = new for_clause(sctx, loc, fvar, domainExpr);
         flwor.add_clause(i, fc);
 
@@ -376,7 +376,7 @@
 
     if ((whereExpr = flwor.get_where()) != NULL)
     {
-      rchandle<if_expr> ifExpr = 
+      rchandle<if_expr> ifExpr =
       new if_expr(whereExpr->get_sctx(),
                   LOC(whereExpr),
                   whereExpr,
@@ -384,7 +384,7 @@
                   fo_expr::create_seq(whereExpr->get_sctx(),
                                       LOC(whereExpr)));
       fix_if_annotations(ifExpr);
-      
+
       return ifExpr.getp();
     }
 
@@ -406,7 +406,7 @@
   FOR, LET, or WINDOW clauses of a flwor expr.
 ********************************************************************************/
 static void collect_flw_vars(
-    const flwor_expr& flwor, 
+    const flwor_expr& flwor,
     expr_tools::VarSetAnnVal& vars)
 {
   for (uint32_t i = 0; i < flwor.num_clauses(); ++i)
@@ -499,9 +499,9 @@
   Check if it is OK to fold (inline) a FOR/LET var X that we know is referenced
   only once withing its flwor expr.
 
-  For a LET var, varQuant is always QUNAT_ONE. 
+  For a LET var, varQuant is always QUNAT_ONE.
 
-  For a FOR var, varQuant is the quantifier of the type of the domain expr. 
+  For a FOR var, varQuant is the quantifier of the type of the domain expr.
   It can be either QUANT_ONE or QUANT_QUESTION.
 ********************************************************************************/
 static bool safe_to_fold_single_use(
@@ -597,7 +597,7 @@
         if (varQuant != TypeConstants::QUANT_ONE)
         {
           // X is a FOR var which is referenced in the current LET clause, and
-          // whose domain may be the empty sequence. We cannot inline in this 
+          // whose domain may be the empty sequence. We cannot inline in this
           // case.
           return false;
         }
@@ -612,7 +612,7 @@
     }
     else if (kind == flwor_clause::where_clause)
     {
-      if (varQuant == TypeConstants::QUANT_ONE && 
+      if (varQuant == TypeConstants::QUANT_ONE &&
           expr_tools::count_variable_uses(c.get_expr(), var, NULL, 1) == 1)
       {
         referencingExpr = c.get_expr();
@@ -639,7 +639,7 @@
   {
     if (varQuant != TypeConstants::QUANT_ONE)
     {
-      xqtref_t type = 
+      xqtref_t type =
       flwor.get_return_expr()->get_return_type_with_empty_input(var);
 
       if (TypeOps::is_equal(tm,
@@ -661,16 +661,16 @@
   return !var_in_try_block_or_in_loop(var,
                                       referencingExpr,
                                       false,
-                                      hasNodeConstr, 
+                                      hasNodeConstr,
                                       found);
 }
 
 
 /*******************************************************************************
-  Given a variable V and an expression E that references V at most once, return 
+  Given a variable V and an expression E that references V at most once, return
   true if E does indeed reference V and
   (a) the reference occurs inside a for-loop within E, or
-  (b) 
+  (b)
 ********************************************************************************/
 static bool var_in_try_block_or_in_loop(
     const var_expr* v,
@@ -758,7 +758,7 @@
             TypeOps::type_max_cnt(tm, *flc.get_expr()->get_return_type()) >= 2)
         {
           // we assume here that the var will be referenced somewhere in the
-          // remainder of the flwor expr, but this is not necessarily true 
+          // remainder of the flwor expr, but this is not necessarily true
           // ???? TODO
           return true;
         }
@@ -866,38 +866,88 @@
 
   flwor_expr* flwor = dynamic_cast<flwor_expr *>(node);
 
-  if (flwor == NULL || flwor->is_general())
+  if (flwor == NULL)
     return NULL;
 
   bool modified = false;
 
-  if_expr* ifReturnExpr = NULL;
-  expr* elseExpr = NULL;
-  expr_t condExpr;
-  expr_t thenExpr;
+  expr* whereExpr = NULL;
+  if(!flwor->is_general())
+    whereExpr = flwor->get_where();
 
   if (flwor->get_return_expr()->get_expr_kind() == if_expr_kind)
   {
-    ifReturnExpr = static_cast<if_expr*>(flwor->get_return_expr());
-    condExpr = ifReturnExpr->get_cond_expr();
-    thenExpr = ifReturnExpr->get_then_expr();
-    elseExpr = ifReturnExpr->get_else_expr();
-  }
-
-  expr* whereExpr = flwor->get_where();
-
-  // "for $x in ... return if (ce) then te else ()" -->
-  // "for $x in ... where ce return te"
-  if (ifReturnExpr != NULL &&
-      whereExpr == NULL &&
-      !condExpr->is_sequential() &&
-      (elseExpr->is_simple() || elseExpr->is_vacuous()) &&
-      !elseExpr->isNonDiscardable() &&
-      TypeOps::is_empty(tm, *elseExpr->get_return_type()))
-  {
-    flwor->set_where(condExpr);
-    flwor->set_return_expr(thenExpr);
-    modified = true;
+    if_expr* ifReturnExpr = static_cast<if_expr*>(flwor->get_return_expr());
+
+    expr_t condExpr = ifReturnExpr->get_cond_expr();
+    expr_t thenExpr = ifReturnExpr->get_then_expr();
+    expr* elseExpr = ifReturnExpr->get_else_expr();
+
+    expr_t newWhereExpr = condExpr;
+
+    if(!flwor->is_general())
+    {
+
+      if(whereExpr->get_expr_kind() == fo_expr_kind &&
+          static_cast<fo_expr*>(whereExpr)->get_func() ==
+              GET_BUILTIN_FUNCTION(OP_AND_N))
+      {
+        if(condExpr->get_expr_kind() == fo_expr_kind &&
+            static_cast<fo_expr*>(condExpr.getp())->get_func() ==
+                GET_BUILTIN_FUNCTION(OP_AND_N))
+        {
+          newWhereExpr = whereExpr;
+          static_cast<fo_expr*>(newWhereExpr.getp())->add_args(
+              static_cast<fo_expr*>(condExpr.getp())->get_args());
+        }
+        else
+        {
+          newWhereExpr = whereExpr;
+          static_cast<fo_expr*>(newWhereExpr.getp())->add_arg(condExpr);
+        }
+      }
+      else if(condExpr->get_expr_kind() == fo_expr_kind &&
+          static_cast<fo_expr*>(condExpr.getp())->get_func() ==
+              GET_BUILTIN_FUNCTION(OP_AND_N))
+      {
+        newWhereExpr = condExpr;
+        static_cast<fo_expr*>(newWhereExpr.getp())->add_arg(whereExpr);
+      }
+      else
+      {
+
+        newWhereExpr = new fo_expr(whereExpr->get_sctx(),
+                                whereExpr->get_loc(),
+                                GET_BUILTIN_FUNCTION(OP_AND_N),
+                                condExpr,
+                                whereExpr);
+
+      }
+
+    }
+
+
+    // "for $x in ... return if (ce) then te else ()" -->
+    // "for $x in ... where ce return te"
+    if (!condExpr->is_sequential() &&
+        (elseExpr->is_simple() || elseExpr->is_vacuous()) &&
+        !elseExpr->isNonDiscardable() &&
+        TypeOps::is_empty(tm, *elseExpr->get_return_type()))
+    {
+
+      if(flwor->is_general())
+      {
+        flwor->add_where(condExpr);
+      }
+      else
+      {
+        flwor->set_where(newWhereExpr);
+      }
+
+      flwor->set_return_expr(thenExpr);
+      modified = true;
+    }
+
   }
 
   expr_t posExpr;
@@ -909,7 +959,8 @@
   // referenced more than once?
   // TODO: we should be able to apply the rule if all the sequential clauses
   // are before the clause that defines the pos var.
-  if (whereExpr != NULL &&
+  if (!flwor->is_general() &&
+      whereExpr != NULL &&
       ! flwor->has_sequential_clauses() &&
       is_subseq_pred(rCtx, flwor, whereExpr, posVar, posExpr) &&
       expr_tools::count_variable_uses(flwor, posVar, &rCtx, 2) <= 1)
@@ -949,12 +1000,12 @@
 
   (a)  op is eq or =, and
   (b1) posExpr is an integer literal with value >= 1, or
-  (b2) the flwor expr has no sequential clauses and posExpr is an expression 
-       whose type is xs:Integer? and which does not reference the for var 
-       associated with posVar nor any other vars that are defined after that 
+  (b2) the flwor expr has no sequential clauses and posExpr is an expression
+       whose type is xs:Integer? and which does not reference the for var
+       associated with posVar nor any other vars that are defined after that
        for var.
 
-  TODO: (b2) can be relaxed somewhat: it is ok if all the sequential clauses are 
+  TODO: (b2) can be relaxed somewhat: it is ok if all the sequential clauses are
   before the clause that defines the pos var.
 ********************************************************************************/
 static bool is_subseq_pred(
@@ -1043,7 +1094,7 @@
             if (posExprVarIds[i] >= forVarId)
               return false;
           }
-          
+
           return true;
         }
       }
@@ -1096,11 +1147,11 @@
     }
 
     ulong numClauses = returnFlwor->num_clauses();
-    
+
     for (ulong i = 0; i < numClauses; ++i)
     {
       const flwor_clause* c = (*returnFlwor)[i];
-      
+
       if (c->get_kind() == flwor_clause::group_clause ||
           c->get_kind() == flwor_clause::order_clause)
       {
@@ -1133,7 +1184,7 @@
 
     expr* domainExpr = c->get_expr();
 
-    if (domainExpr != NULL && 
+    if (domainExpr != NULL &&
         domainExpr->get_expr_kind() == flwor_expr_kind &&
         !domainExpr->is_sequential())
     {


Follow ups