hqlcse.ipp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #ifndef __HQLCSE_IPP_
  14. #define __HQLCSE_IPP_
  15. #include "hqlcpp.hpp"
  16. #include "hqlcpp.ipp"
  17. #include "hqltrans.ipp"
  18. //#define NEW_CSE_PROCESSING
  19. //---------------------------------------------------------------------------
  20. class CseSpotterInfo : public NewTransformInfo
  21. {
  22. public:
  23. CseSpotterInfo(IHqlExpression * expr);
  24. bool worthAliasing();
  25. bool worthAliasingOnOwn();
  26. bool useInverseForAlias();
  27. bool isAliased() { return alreadyAliased || treatAsAliased; }
  28. unsigned numRefs;
  29. unsigned numAssociatedRefs;
  30. CseSpotterInfo * inverse;
  31. IHqlExpression * annotatedExpr;
  32. bool alreadyAliased : 1;
  33. bool canAlias : 1;
  34. bool dontTransform : 1;
  35. bool dontTransformSelector : 1;
  36. bool treatAsAliased : 1;
  37. };
  38. class CseSpotter : public NewHqlTransformer
  39. {
  40. typedef NewHqlTransformer PARENT;
  41. public:
  42. CseSpotter(bool _spotCseInIfDatasetConditions);
  43. void analyseAssociated(IHqlExpression * expr, unsigned pass);
  44. bool foundCandidates() const { return spottedCandidate; }
  45. bool createdNewAliases() const { return createdAlias; }
  46. void setInvariantSelector(IHqlExpression * _invariantSelector) { invariantSelector = _invariantSelector; }
  47. void stopTransformation(IHqlExpression * expr);
  48. protected:
  49. virtual void analyseExpr(IHqlExpression * expr);
  50. virtual IHqlExpression * createTransformed(IHqlExpression * expr);
  51. inline bool containsPotentialCSE(IHqlExpression * expr);
  52. virtual bool checkPotentialCSE(IHqlExpression * expr, CseSpotterInfo * extra);
  53. virtual ANewTransformInfo * createTransformInfo(IHqlExpression * expr);
  54. virtual IHqlExpression * transform(IHqlExpression * expr);
  55. virtual IHqlExpression * queryAlreadyTransformed(IHqlExpression * expr);
  56. virtual IHqlExpression * queryAlreadyTransformedSelector(IHqlExpression * expr);
  57. inline CseSpotterInfo * queryBodyExtra(IHqlExpression * expr) { return (CseSpotterInfo*)PARENT::queryTransformExtra(expr->queryBody()); }
  58. IHqlExpression * doCreateTransformed(IHqlExpression * expr);
  59. IHqlExpression * createAliasOwn(IHqlExpression * expr, CseSpotterInfo * extra);
  60. protected:
  61. IHqlExpression * invariantSelector;
  62. bool canAlias;
  63. bool isAssociated;
  64. bool spottedCandidate;
  65. bool createLocalAliases;
  66. bool createdAlias;
  67. bool spotCseInIfDatasetConditions;
  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, bool spotCseInIfDatasetConditions);
  170. void spotScalarCSE(SharedHqlExpr & expr, SharedHqlExpr & associated, IHqlExpression * limit, IHqlExpression * invariantSelector, bool spotCseInIfDatasetConditions);
  171. void spotScalarCSE(HqlExprArray & exprs, HqlExprArray & associated, IHqlExpression * limit, IHqlExpression * invariantSelector, bool spotCseInIfDatasetConditions);
  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