~zorba-coders/zorba/image-module-head

« back to all changes in this revision

Viewing changes to src/compiler/rewriter/rules/flwor_rules.cpp

  • Committer: Zorba Build Bot
  • Author(s): markos_za at yahoo
  • Date: 2012-10-30 14:06:18 UTC
  • mfrom: (10900.1.83 markos-scratch)
  • Revision ID: chillery+buildbot@lambda.nu-20121030140618-xu5d1beo3vpo5ylk
fix annotations of merged AND exprs + slight optimization of the MergeFLWOR rule Approved: Markos Zaharioudakis

Show diffs side-by-side

added added

removed removed

Lines of Context:
88
88
  Replace all references to theVarExpr inside the root expr of a given rCtx
89
89
  with theSubstExpr
90
90
******************************************************************************/
91
 
class SubstVars : public PrePostRewriteRule
 
91
class SubstVars : public RewriteRule
92
92
{
93
93
protected:
94
94
  var_expr           * theVarExpr;
95
95
  expr               * theSubstExpr;
96
 
  std::vector<expr*>   thePath;
 
96
  //std::vector<expr*>   thePath;
97
97
 
98
98
public:
99
99
  SubstVars(var_expr* var, expr* subst)
100
100
    :
101
 
    PrePostRewriteRule(RewriteRule::SubstVars, "SubstVars"),
 
101
    RewriteRule(RewriteRule::SubstVars, "SubstVars"),
102
102
    theVarExpr(var),
103
103
    theSubstExpr(subst)
104
104
  {
105
105
  }
106
106
 
107
 
protected:
108
 
  expr* rewritePre(expr* node, RewriterContext& rCtx);
109
 
  expr* rewritePost(expr* node, RewriterContext& rCtx);
 
107
  expr* apply(RewriterContext& rCtx, expr* node, bool& modified);
110
108
};
111
109
 
112
110
 
113
 
RULE_REWRITE_PRE(SubstVars)
114
 
{
115
 
  thePath.push_back(node);
116
 
 
117
 
  if (node == theVarExpr)
118
 
  {
119
 
    std::vector<expr*>::iterator ite = thePath.begin();
120
 
    std::vector<expr*>::iterator end = thePath.end();
121
 
    for (; ite != end; ++ite)
122
 
    {
123
 
      expr::FreeVars& vars = (*ite)->getFreeVars();
124
 
      vars.erase(theVarExpr);
125
 
      vars.insert(theSubstExpr->getFreeVars().begin(),
126
 
                  theSubstExpr->getFreeVars().end());
127
 
    }
128
 
 
129
 
    return theSubstExpr;
130
 
  }
131
 
  else
132
 
  {
133
 
    return NULL;
134
 
  }
135
 
}
136
 
 
137
 
 
138
 
RULE_REWRITE_POST(SubstVars)
139
 
{
140
 
  thePath.pop_back();
 
111
expr* SubstVars::apply(RewriterContext& rCtx, expr* node, bool& modified)
 
112
{
 
113
  //thePath.push_back(node);
 
114
 
 
115
  ExprIterator iter(node);
 
116
 
 
117
  while (!iter.done())
 
118
  {
 
119
    if (**iter == theVarExpr)
 
120
    {
 
121
#if 0
 
122
      std::vector<expr*>::iterator ite = thePath.begin();
 
123
      std::vector<expr*>::iterator end = thePath.end();
 
124
      for (; ite != end; ++ite)
 
125
      {
 
126
        expr::FreeVars& vars = (*ite)->getFreeVars();
 
127
        vars.erase(theVarExpr);
 
128
        vars.insert(theSubstExpr->getFreeVars().begin(),
 
129
                    theSubstExpr->getFreeVars().end());
 
130
      }
 
131
#endif
 
132
      **iter = theSubstExpr;
 
133
      modified = true;
 
134
    }
 
135
    else
 
136
    {
 
137
      apply(rCtx, **iter, modified);
 
138
    }
 
139
 
 
140
    iter.next();
 
141
  }
 
142
 
 
143
  //thePath.pop_back();
141
144
  return NULL;
142
145
}
143
146
 
1041
1044
          if (condExpr->get_function_kind() == FunctionConsts::OP_AND_N)
1042
1045
          {
1043
1046
            fo_expr* foCondExpr = static_cast<fo_expr*>(condExpr);
1044
 
            foWhereExpr->add_args(foCondExpr->get_args());
 
1047
 
 
1048
            for (csize i = 0; i < foCondExpr->num_args(); ++i)
 
1049
            {
 
1050
              foWhereExpr->add_arg(foCondExpr->get_arg(i));
 
1051
              expr_tools::fix_annotations(foWhereExpr, foCondExpr->get_arg(i));
 
1052
            }
1045
1053
          }
1046
1054
          else
1047
1055
          {
1559
1567
/******************************************************************************
1560
1568
 
1561
1569
*******************************************************************************/
1562
 
RULE_REWRITE_PRE(MergeFLWOR)
 
1570
expr* MergeFLWOR::apply(RewriterContext& rCtx, expr* node, bool& modified)
1563
1571
{
1564
 
  flwor_expr* flwor = dynamic_cast<flwor_expr *>(node);
1565
 
 
1566
 
  if (flwor == NULL)
1567
 
    return NULL;
1568
 
 
1569
 
  bool modified = false;
1570
 
 
1571
 
  // Try to merge an inner flwor that appears in the return clause of the
1572
 
  // outer flwor.
1573
 
  if (flwor->get_return_expr()->get_expr_kind() == flwor_expr_kind &&
1574
 
      !flwor->get_return_expr()->is_sequential())
 
1572
  if (node->get_expr_kind() == flwor_expr_kind ||
 
1573
      node->get_expr_kind() == gflwor_expr_kind)
1575
1574
  {
1576
 
    // TODO: If the return clause is sequential, we can still do the merge,
1577
 
    // but we must keep both the outer and the inner materialize clauses.
1578
 
 
1579
 
    flwor_expr* returnFlwor = static_cast<flwor_expr*>(flwor->get_return_expr());
1580
 
 
1581
 
    // If the outer flwor is not general, and it contains where, groupby, or
1582
 
    // orderby clauses, we cannot merge because for/let clauses cannot appear
1583
 
    // after where, groupby, or orderby clauses,
1584
 
    if (!flwor->is_general())
 
1575
    flwor_expr* flwor = static_cast<flwor_expr *>(node);
 
1576
 
 
1577
    // Try to merge an inner flwor that appears in the return clause of the
 
1578
    // outer flwor.
 
1579
    if (flwor->get_return_expr()->get_expr_kind() == flwor_expr_kind &&
 
1580
        !flwor->get_return_expr()->is_sequential())
1585
1581
    {
1586
 
      csize numClauses = flwor->num_clauses();
 
1582
      // TODO: If the return clause is sequential, we can still do the merge,
 
1583
      // but we must keep both the outer and the inner materialize clauses.
 
1584
 
 
1585
      flwor_expr* returnFlwor = static_cast<flwor_expr*>(flwor->get_return_expr());
 
1586
 
 
1587
      // If the outer flwor is not general, and it contains where, groupby, or
 
1588
      // orderby clauses, we cannot merge because for/let clauses cannot appear
 
1589
      // after where, groupby, or orderby clauses,
 
1590
      if (!flwor->is_general())
 
1591
      {
 
1592
        csize numClauses = flwor->num_clauses();
 
1593
        
 
1594
        for (csize i = 0; i < numClauses; ++i)
 
1595
        {
 
1596
          const flwor_clause* c = flwor->get_clause(i);
 
1597
          
 
1598
          if (c->get_kind() == flwor_clause::where_clause ||
 
1599
              c->get_kind() == flwor_clause::group_clause ||
 
1600
              c->get_kind() == flwor_clause::order_clause)
 
1601
          {
 
1602
            goto next1;
 
1603
          }
 
1604
        }
 
1605
      }
 
1606
      
 
1607
      csize numClauses = returnFlwor->num_clauses();
1587
1608
 
1588
1609
      for (csize i = 0; i < numClauses; ++i)
1589
1610
      {
1590
 
        const flwor_clause* c = flwor->get_clause(i);
1591
 
 
1592
 
        if (c->get_kind() == flwor_clause::where_clause ||
1593
 
            c->get_kind() == flwor_clause::group_clause ||
 
1611
        const flwor_clause* c = returnFlwor->get_clause(i);
 
1612
        
 
1613
        if (c->get_kind() == flwor_clause::group_clause ||
1594
1614
            c->get_kind() == flwor_clause::order_clause)
1595
1615
        {
1596
1616
          goto next1;
1597
1617
        }
1598
1618
      }
1599
 
    }
1600
 
 
1601
 
    csize numClauses = returnFlwor->num_clauses();
1602
 
 
1603
 
    for (csize i = 0; i < numClauses; ++i)
1604
 
    {
1605
 
      const flwor_clause* c = returnFlwor->get_clause(i);
1606
 
 
1607
 
      if (c->get_kind() == flwor_clause::group_clause ||
1608
 
          c->get_kind() == flwor_clause::order_clause)
1609
 
      {
1610
 
        goto next1;
1611
 
      }
1612
 
    }
1613
 
 
1614
 
    for (csize i = 0; i < numClauses; ++i)
1615
 
    {
1616
 
      flwor->add_clause(returnFlwor->get_clause(i));
1617
 
    }
1618
 
 
1619
 
    flwor->set_return_expr(returnFlwor->get_return_expr());
1620
 
 
1621
 
    modified = true;
 
1619
      
 
1620
      for (csize i = 0; i < numClauses; ++i)
 
1621
      {
 
1622
        flwor->add_clause(returnFlwor->get_clause(i));
 
1623
      }
 
1624
      
 
1625
      flwor->set_return_expr(returnFlwor->get_return_expr());
 
1626
      
 
1627
      modified = true;
 
1628
    }
 
1629
    
 
1630
  next1:
 
1631
    
 
1632
    csize numClauses = flwor->num_clauses();
 
1633
    
 
1634
    // Try to merge an inner flwor that appears in a for/let clause of the outer
 
1635
    // flwor.
 
1636
    for (csize i = 0; i < numClauses; ++i)
 
1637
    {
 
1638
      bool merge = false;
 
1639
      flwor_expr* nestedFlwor = NULL;
 
1640
      csize numNestedClauses;
 
1641
      
 
1642
      flwor_clause* c = flwor->get_clause(i);
 
1643
      
 
1644
      if (c->get_kind() == flwor_clause::let_clause)
 
1645
      {
 
1646
        expr* domainExpr = static_cast<let_clause*>(c)->get_expr();
 
1647
        
 
1648
        if (domainExpr->get_expr_kind() == flwor_expr_kind &&
 
1649
            !domainExpr->is_sequential())
 
1650
        {
 
1651
          nestedFlwor = static_cast<flwor_expr*>(domainExpr);
 
1652
          numNestedClauses = nestedFlwor->num_clauses();
 
1653
          merge = true;
 
1654
          
 
1655
          for (csize j = 0; j < numNestedClauses; ++j)
 
1656
          {
 
1657
            flwor_clause* nestedClause = nestedFlwor->get_clause(j);
 
1658
            flwor_clause::ClauseKind nestedClauseKind = nestedClause->get_kind();
 
1659
            
 
1660
            if (nestedClauseKind == flwor_clause::for_clause)
 
1661
            {
 
1662
              xqtref_t nestedDomainType =
 
1663
                static_cast<for_clause*>(nestedClause)->get_expr()->get_return_type();
 
1664
              
 
1665
              if (nestedDomainType->get_quantifier() != TypeConstants::QUANT_ONE)
 
1666
              {
 
1667
                merge = false;
 
1668
                break;
 
1669
              }
 
1670
            }
 
1671
            else if (nestedClauseKind != flwor_clause::let_clause)
 
1672
            {
 
1673
              merge = false;
 
1674
              break;
 
1675
            }
 
1676
          }
 
1677
        }
 
1678
      }
 
1679
      else if (c->get_kind() == flwor_clause::for_clause &&
 
1680
               static_cast<for_clause*>(c)->get_pos_var() == NULL)
 
1681
      {
 
1682
        expr* domainExpr = static_cast<for_clause*>(c)->get_expr();
 
1683
 
 
1684
        if (domainExpr->get_expr_kind() == flwor_expr_kind &&
 
1685
            !domainExpr->is_sequential())
 
1686
        {
 
1687
          nestedFlwor = static_cast<flwor_expr*>(domainExpr);
 
1688
          numNestedClauses = nestedFlwor->num_clauses();
 
1689
          merge = true;
 
1690
 
 
1691
          for (csize j = 0; j < numNestedClauses; ++j)
 
1692
          {
 
1693
            flwor_clause* nestedClause = nestedFlwor->get_clause(j);
 
1694
            flwor_clause::ClauseKind nestedClauseKind = nestedClause->get_kind();
 
1695
            
 
1696
            if (nestedClauseKind != flwor_clause::let_clause &&
 
1697
                nestedClauseKind != flwor_clause::for_clause)
 
1698
            {
 
1699
#if 1
 
1700
              // temp hack until we have an optimized general flwor
 
1701
              if (nestedClauseKind == flwor_clause::where_clause &&
 
1702
                  i == numClauses-1 &&
 
1703
                  flwor->get_where() == NULL &&
 
1704
                  nestedFlwor->get_return_expr()->get_var() != NULL)
 
1705
              {
 
1706
                continue;
 
1707
              }
 
1708
#endif
 
1709
              merge = false;
 
1710
              break;
 
1711
            }
 
1712
          }
 
1713
        }
 
1714
    }
 
1715
      
 
1716
      if (merge)
 
1717
      {
 
1718
        for (csize j = 0; j < numNestedClauses; ++j)
 
1719
        {
 
1720
          flwor_clause* nestedClause = nestedFlwor->get_clause(j);
 
1721
#if 1
 
1722
          if (nestedClause->get_kind() == flwor_clause::where_clause)
 
1723
            flwor->add_clause(i+j+1, nestedClause);
 
1724
          else
 
1725
#endif
 
1726
            flwor->add_clause(i+j, nestedClause);
 
1727
        }
 
1728
        
 
1729
        c->set_expr(nestedFlwor->get_return_expr());
 
1730
        
 
1731
        numClauses += numNestedClauses;
 
1732
        i += numNestedClauses;
 
1733
        
 
1734
        modified = true;
 
1735
      }
 
1736
    }
1622
1737
  }
1623
1738
 
1624
 
 next1:
1625
 
 
1626
 
  csize numClauses = flwor->num_clauses();
1627
 
 
1628
 
  // Try to merge an inner flwor that appears in a for/let clause of the outer
1629
 
  // flwor.
1630
 
  for (csize i = 0; i < numClauses; ++i)
 
1739
  ExprIterator iter(node);
 
1740
 
 
1741
  while (!iter.done())
1631
1742
  {
1632
 
    bool merge = false;
1633
 
    flwor_expr* nestedFlwor = NULL;
1634
 
    csize numNestedClauses;
1635
 
 
1636
 
    flwor_clause* c = flwor->get_clause(i);
1637
 
 
1638
 
    if (c->get_kind() == flwor_clause::let_clause)
1639
 
    {
1640
 
      expr* domainExpr = static_cast<let_clause*>(c)->get_expr();
1641
 
 
1642
 
      if (domainExpr->get_expr_kind() == flwor_expr_kind &&
1643
 
          !domainExpr->is_sequential())
1644
 
      {
1645
 
        nestedFlwor = static_cast<flwor_expr*>(domainExpr);
1646
 
        numNestedClauses = nestedFlwor->num_clauses();
1647
 
        merge = true;
1648
 
 
1649
 
        for (csize j = 0; j < numNestedClauses; ++j)
1650
 
        {
1651
 
          flwor_clause* nestedClause = nestedFlwor->get_clause(j);
1652
 
          flwor_clause::ClauseKind nestedClauseKind = nestedClause->get_kind();
1653
 
 
1654
 
          if (nestedClauseKind == flwor_clause::for_clause)
1655
 
          {
1656
 
            xqtref_t nestedDomainType =
1657
 
            static_cast<for_clause*>(nestedClause)->get_expr()->get_return_type();
1658
 
 
1659
 
            if (nestedDomainType->get_quantifier() != TypeConstants::QUANT_ONE)
1660
 
            {
1661
 
              merge = false;
1662
 
              break;
1663
 
            }
1664
 
          }
1665
 
          else if (nestedClauseKind != flwor_clause::let_clause)
1666
 
          {
1667
 
            merge = false;
1668
 
            break;
1669
 
          }
1670
 
        }
1671
 
      }
1672
 
    }
1673
 
    else if (c->get_kind() == flwor_clause::for_clause &&
1674
 
             static_cast<for_clause*>(c)->get_pos_var() == NULL)
1675
 
    {
1676
 
      expr* domainExpr = static_cast<for_clause*>(c)->get_expr();
1677
 
 
1678
 
      if (domainExpr->get_expr_kind() == flwor_expr_kind &&
1679
 
          !domainExpr->is_sequential())
1680
 
      {
1681
 
        nestedFlwor = static_cast<flwor_expr*>(domainExpr);
1682
 
        numNestedClauses = nestedFlwor->num_clauses();
1683
 
        merge = true;
1684
 
 
1685
 
        for (csize j = 0; j < numNestedClauses; ++j)
1686
 
        {
1687
 
          flwor_clause* nestedClause = nestedFlwor->get_clause(j);
1688
 
          flwor_clause::ClauseKind nestedClauseKind = nestedClause->get_kind();
1689
 
 
1690
 
          if (nestedClauseKind != flwor_clause::let_clause &&
1691
 
              nestedClauseKind != flwor_clause::for_clause)
1692
 
          {
1693
 
#if 1
1694
 
            // temp hack until we have an optimized general flwor
1695
 
            if (nestedClauseKind == flwor_clause::where_clause &&
1696
 
                i == numClauses-1 &&
1697
 
                flwor->get_where() == NULL &&
1698
 
                nestedFlwor->get_return_expr()->get_var() != NULL)
1699
 
            {
1700
 
              continue;
1701
 
            }
1702
 
#endif
1703
 
            merge = false;
1704
 
            break;
1705
 
          }
1706
 
        }
1707
 
      }
1708
 
    }
1709
 
 
1710
 
    if (merge)
1711
 
    {
1712
 
      for (ulong j = 0; j < numNestedClauses; ++j)
1713
 
      {
1714
 
        flwor_clause* nestedClause = nestedFlwor->get_clause(j);
1715
 
#if 1
1716
 
        if (nestedClause->get_kind() == flwor_clause::where_clause)
1717
 
          flwor->add_clause(i+j+1, nestedClause);
1718
 
        else
1719
 
#endif
1720
 
          flwor->add_clause(i+j, nestedClause);
1721
 
      }
1722
 
 
1723
 
      c->set_expr(nestedFlwor->get_return_expr());
1724
 
 
1725
 
      numClauses += numNestedClauses;
1726
 
      i += numNestedClauses;
1727
 
 
1728
 
      modified = true;
1729
 
    }
 
1743
    apply(rCtx, **iter, modified);
 
1744
 
 
1745
    iter.next();
1730
1746
  }
1731
1747
 
1732
 
  return (modified ? node : NULL);
1733
 
}
1734
 
 
1735
 
 
1736
 
/******************************************************************************
1737
 
 
1738
 
*******************************************************************************/
1739
 
RULE_REWRITE_POST(MergeFLWOR)
1740
 
{
1741
1748
  return NULL;
1742
1749
}
1743
1750