hqlpopt.cpp 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /*##############################################################################
  2. Copyright (C) 2011 HPCC Systems.
  3. All rights reserved. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Affero General Public License as
  5. published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Affero General Public License for more details.
  11. You should have received a copy of the GNU Affero General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ############################################################################## */
  14. #include "jliball.hpp"
  15. #include "hql.hpp"
  16. #include "platform.h"
  17. #include "jlib.hpp"
  18. #include "jexcept.hpp"
  19. #include "jmisc.hpp"
  20. #include "javahash.hpp"
  21. #include "jmd5.hpp"
  22. #include "jfile.hpp"
  23. #include "eclhelper.hpp"
  24. #include "hqlfunc.hpp"
  25. #include "hqlattr.hpp"
  26. #include "hqlcpp.ipp"
  27. #include "hqlpopt.hpp"
  28. //Optimize IF(a,b,c) op x to IF(a,b op x, c OP x)
  29. //But be careful because it uncommons attributes increasing the size of the queries.
  30. static IHqlExpression * peepholeOptimizeCompare(BuildCtx & ctx, IHqlExpression * expr)
  31. {
  32. IHqlExpression * lhs = expr->queryChild(0);
  33. if (ctx.queryMatchExpr(lhs))
  34. return LINK(expr);
  35. IHqlExpression * rhs = expr->queryChild(1);
  36. if (!rhs->isConstant() || (lhs->getOperator() != no_if))
  37. return LINK(expr);
  38. IHqlExpression * ifCond = lhs->queryChild(0);
  39. IHqlExpression * ifTrue = lhs->queryChild(1);
  40. IHqlExpression * ifFalse = lhs->queryChild(2);
  41. assertex(ifFalse);
  42. node_operator op = expr->getOperator();
  43. OwnedHqlExpr newTrue = createValue(op, makeBoolType(), LINK(ifTrue), LINK(rhs));
  44. OwnedHqlExpr newFalse = createValue(op, makeBoolType(), LINK(ifFalse), LINK(rhs));
  45. OwnedHqlExpr newIf = createValue(no_if, makeBoolType(), LINK(ifCond), peepholeOptimize(ctx, newTrue), peepholeOptimize(ctx, newFalse));
  46. return expr->cloneAllAnnotations(newIf);
  47. }
  48. //Optimize search [not] in set(ds, value) to
  49. //[not] exists(ds, value=search); - really need link counts on the expressions, and should be done in the real optimizer
  50. IHqlExpression * peepholeOptimize(BuildCtx & ctx, IHqlExpression * expr)
  51. {
  52. switch (expr->getOperator())
  53. {
  54. case no_eq:
  55. case no_ne:
  56. case no_le:
  57. case no_lt:
  58. case no_ge:
  59. case no_gt:
  60. return peepholeOptimizeCompare(ctx, expr);
  61. case no_and:
  62. case no_or:
  63. case no_not:
  64. {
  65. HqlExprArray args;
  66. bool same = true;
  67. ForEachChild(i, expr)
  68. {
  69. IHqlExpression * cur = expr->queryChild(i);
  70. IHqlExpression * optimized = peepholeOptimize(ctx, expr);
  71. args.append(*optimized);
  72. if (cur != optimized)
  73. same = false;
  74. }
  75. if (!same)
  76. return expr->clone(args);
  77. break;
  78. }
  79. }
  80. return LINK(expr);
  81. }