hqlcse.ipp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  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. #ifndef __HQLCSE_IPP_
  15. #define __HQLCSE_IPP_
  16. #include "hqlcpp.hpp"
  17. #include "hqlcpp.ipp"
  18. #include "hqltrans.ipp"
  19. //#define NEW_CSE_PROCESSING
  20. //---------------------------------------------------------------------------
  21. class CseSpotterInfo : public NewTransformInfo
  22. {
  23. public:
  24. CseSpotterInfo(IHqlExpression * expr);
  25. bool worthAliasing();
  26. bool worthAliasingOnOwn();
  27. bool useInverseForAlias();
  28. bool isAliased() { return alreadyAliased || treatAsAliased; }
  29. unsigned numRefs;
  30. unsigned numAssociatedRefs;
  31. CseSpotterInfo * inverse;
  32. IHqlExpression * annotatedExpr;
  33. bool alreadyAliased : 1;
  34. bool canAlias : 1;
  35. bool dontTransform : 1;
  36. bool dontTransformSelector : 1;
  37. bool treatAsAliased : 1;
  38. };
  39. class CseSpotter : public NewHqlTransformer
  40. {
  41. typedef NewHqlTransformer PARENT;
  42. public:
  43. CseSpotter();
  44. void analyseAssociated(IHqlExpression * expr, unsigned pass);
  45. bool foundCandidates() const { return spottedCandidate; }
  46. bool createdNewAliases() const { return createdAlias; }
  47. void setInvariantSelector(IHqlExpression * _invariantSelector) { invariantSelector = _invariantSelector; }
  48. void stopTransformation(IHqlExpression * expr);
  49. protected:
  50. virtual void analyseExpr(IHqlExpression * expr);
  51. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  52. inline bool containsPotentialCSE(IHqlExpression * expr);
  53. virtual bool checkPotentialCSE(IHqlExpression * expr, CseSpotterInfo * extra);
  54. virtual ANewTransformInfo * createTransformInfo(IHqlExpression * expr);
  55. virtual IHqlExpression * transform(IHqlExpression * expr);
  56. virtual IHqlExpression * queryAlreadyTransformed(IHqlExpression * expr);
  57. virtual IHqlExpression * queryAlreadyTransformedSelector(IHqlExpression * expr);
  58. inline CseSpotterInfo * queryBodyExtra(IHqlExpression * expr) { return (CseSpotterInfo*)PARENT::queryTransformExtra(expr->queryBody()); }
  59. IHqlExpression * doCreateTransformed(IHqlExpression * expr);
  60. IHqlExpression * createAliasOwn(IHqlExpression * expr, CseSpotterInfo * extra);
  61. protected:
  62. IHqlExpression * invariantSelector;
  63. bool canAlias;
  64. bool isAssociated;
  65. bool spottedCandidate;
  66. bool createLocalAliases;
  67. bool createdAlias;
  68. };
  69. class ConjunctionTransformer : public NewHqlTransformer
  70. {
  71. public:
  72. ConjunctionTransformer();
  73. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  74. };
  75. #ifdef NEW_CSE_PROCESSING
  76. class CseScopeInfo : public NewTransformInfo
  77. {
  78. public:
  79. CseScopeInfo(IHqlExpression * expr) : NewTransformInfo(expr)
  80. {
  81. firstParent = NULL;
  82. commonLocation = NULL;
  83. seq = 0;
  84. hasSharedParent = false;
  85. calcedCommonLocation = false;
  86. isUnconditional = false;
  87. }
  88. void addParent(IHqlExpression * nextParent)
  89. {
  90. // if (firstParent)
  91. // {
  92. // if (nextParent)
  93. // {
  94. // if ((nextParent != firstParent) && !parents.contains(nextParent))
  95. parents.append(nextParent);
  96. // }
  97. // else
  98. // firstParent = NULL;
  99. // }
  100. }
  101. HqlExprArray aliasesToDefine;
  102. // use a pointer for the first match to avoid reallocation for unshared items
  103. IHqlExpression * firstParent;
  104. CseScopeInfo * commonLocation;
  105. PointerArrayOf<IHqlExpression> parents;
  106. unsigned seq;
  107. bool hasSharedParent;
  108. bool calcedCommonLocation;
  109. bool isUnconditional;
  110. };
  111. class CseScopeTransformer : public NewHqlTransformer
  112. {
  113. public:
  114. CseScopeTransformer();
  115. virtual void analyseExpr(IHqlExpression * expr);
  116. bool attachCSEs(IHqlExpression * root);
  117. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  118. protected:
  119. virtual ANewTransformInfo * createTransformInfo(IHqlExpression * expr);
  120. CseScopeInfo * calcCommonLocation(CseScopeInfo * extra);
  121. IHqlExpression * findAliasLocation(CseScopeInfo * extra);
  122. CseScopeInfo * findCommonPath(CseScopeInfo * left, CseScopeInfo * right);
  123. CseScopeInfo * selectParent(CseScopeInfo * info);
  124. inline CseScopeInfo * queryExtra(IHqlExpression * expr) { return (CseScopeInfo*)NewHqlTransformer::queryTransformExtra(expr); }
  125. protected:
  126. CIArrayOf<CseScopeInfo> allCSEs;
  127. IHqlExpression * activeParent;
  128. unsigned seq;
  129. unsigned conditionDepth;
  130. };
  131. #else
  132. //NB: path isn't linked for efficiency.
  133. typedef ICopyArrayOf<IHqlExpression> PathArray;
  134. class CSEentry : public CInterface
  135. {
  136. public:
  137. CSEentry(IHqlExpression * _value, PathArray & _path);
  138. void findCommonPath(PathArray & otherPath);
  139. protected:
  140. void ensurePathValid();
  141. public:
  142. HqlExprAttr value;
  143. PathArray path;
  144. CIArrayOf<CSEentry> dependsOn;
  145. };
  146. class CseScopeInfo : public NewTransformInfo
  147. {
  148. public:
  149. CseScopeInfo(IHqlExpression * expr) : NewTransformInfo(expr) { }
  150. Owned<CSEentry> cseUse;
  151. CIArrayOf<CSEentry> cseDefine;
  152. };
  153. class CseScopeTransformer : public NewHqlTransformer
  154. {
  155. public:
  156. CseScopeTransformer();
  157. virtual void analyseExpr(IHqlExpression * expr);
  158. bool attachCSEs(IHqlExpression * root);
  159. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  160. protected:
  161. virtual ANewTransformInfo * createTransformInfo(IHqlExpression * expr);
  162. inline CseScopeInfo * queryExtra(IHqlExpression * expr) { return (CseScopeInfo*)NewHqlTransformer::queryTransformExtra(expr); }
  163. protected:
  164. CIArrayOf<CSEentry> allCSEs;
  165. PathArray path;
  166. CIArrayOf<CSEentry> activeCSE;
  167. };
  168. #endif
  169. IHqlExpression * spotScalarCSE(IHqlExpression * expr, IHqlExpression * limit = NULL);
  170. void spotScalarCSE(SharedHqlExpr & expr, SharedHqlExpr & associated, IHqlExpression * limit, IHqlExpression * invariantSelector);
  171. void spotScalarCSE(HqlExprArray & exprs, HqlExprArray & associated, IHqlExpression * limit, IHqlExpression * invariantSelector);
  172. //---------------------------------------------------------------------------
  173. class TableInvariantInfo : public NewTransformInfo
  174. {
  175. public:
  176. TableInvariantInfo(IHqlExpression * expr) : NewTransformInfo(expr) { createAlias = false; couldAlias = false; cachedInvariant = false; isInvariant = false; }
  177. bool createAlias;
  178. bool couldAlias;
  179. bool cachedInvariant;
  180. bool isInvariant;
  181. };
  182. class TableInvariantTransformer : public NewHqlTransformer
  183. {
  184. public:
  185. TableInvariantTransformer();
  186. virtual void analyseExpr(IHqlExpression * expr);
  187. virtual ANewTransformInfo * createTransformInfo(IHqlExpression * expr) { return CREATE_NEWTRANSFORMINFO(TableInvariantInfo, expr); }
  188. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  189. protected:
  190. bool isInvariant(IHqlExpression * expr);
  191. bool isTrivialAlias(IHqlExpression * expr);
  192. bool isAlwaysAlias(IHqlExpression * expr);
  193. inline TableInvariantInfo * queryBodyExtra(IHqlExpression * expr) { return (TableInvariantInfo*)NewHqlTransformer::queryTransformExtra(expr->queryBody()); }
  194. protected:
  195. bool canAlias;
  196. };
  197. //---------------------------------------------------------------------------
  198. class GlobalAliasInfo : public NewTransformInfo
  199. {
  200. public:
  201. GlobalAliasInfo(IHqlExpression * expr) : NewTransformInfo(expr) { isOuter = false; numUses = 0; }
  202. bool isOuter;
  203. unsigned numUses;
  204. };
  205. class GlobalAliasTransformer : public NewHqlTransformer
  206. {
  207. public:
  208. GlobalAliasTransformer();
  209. virtual void analyseExpr(IHqlExpression * expr);
  210. virtual ANewTransformInfo * createTransformInfo(IHqlExpression * expr) { return CREATE_NEWTRANSFORMINFO(GlobalAliasInfo, expr); }
  211. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  212. protected:
  213. inline GlobalAliasInfo * queryBodyExtra(IHqlExpression * expr) { return (GlobalAliasInfo*)NewHqlTransformer::queryTransformExtra(expr->queryBody()); }
  214. bool insideGlobal;
  215. };
  216. //---------------------------------------------------------------------------
  217. IHqlExpression * spotTableInvariant(IHqlExpression * expr);
  218. IHqlExpression * spotTableInvariantChildren(IHqlExpression * expr);
  219. IHqlExpression * optimizeActivityAliasReferences(IHqlExpression * expr);
  220. #endif