Procházet zdrojové kódy

HPCC-10922 Add an option to improve cse for if conditions in child queries

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
Gavin Halliday před 11 roky
rodič
revize
0e68a956bd

+ 2 - 2
ecl/hqlcpp/hqlckey.cpp

@@ -204,7 +204,7 @@ void HqlCppTranslator::buildJoinMatchFunction(BuildCtx & ctx, const char * name,
         bindTableCursor(matchctx, left, "left", no_left, selSeq);
         bindTableCursor(matchctx, right, "right", no_right, selSeq);
 
-        OwnedHqlExpr cseMatch = options.spotCSE ? spotScalarCSE(match) : LINK(match);
+        OwnedHqlExpr cseMatch = options.spotCSE ? spotScalarCSE(match, NULL, queryOptions().spotCseInIfDatasetConditions) : LINK(match);
         buildReturn(matchctx, cseMatch);
     }
 }
@@ -529,7 +529,7 @@ void KeyedJoinInfo::buildIndexReadMatch(BuildCtx & ctx)
         OwnedHqlExpr fileposVar = createVariable("_filepos", fileposExpr->getType());
 
         if (translator.queryOptions().spotCSE)
-            matchExpr.setown(spotScalarCSE(matchExpr));
+            matchExpr.setown(spotScalarCSE(matchExpr, NULL, translator.queryOptions().spotCseInIfDatasetConditions));
 
         translator.associateBlobHelper(matchctx, rawKey, "blobs");
 

+ 3 - 2
ecl/hqlcpp/hqlcpp.cpp

@@ -1577,6 +1577,7 @@ void HqlCppTranslator::cacheOptions()
         DebugOption(options.convertJoinToLookup,"convertJoinToLookup", true),
         DebugOption(options.convertJoinToLookupIfSorted,"convertJoinToLookupIfSorted", false),
         DebugOption(options.spotCSE,"spotCSE", true),
+        DebugOption(options.spotCseInIfDatasetConditions,"spotCseInIfDatasetConditions", false),
         DebugOption(options.optimizeNonEmpty,"optimizeNonEmpty", !targetThor()),                // not sure that it will be conditional resourced correctly for thor
         DebugOption(options.allowVariableRoxieFilenames,"allowVariableRoxieFilenames", false),
         DebugOption(options.foldConstantDatasets,"foldConstantDatasets", true),
@@ -11406,7 +11407,7 @@ void HqlCppTranslator::doBuildUserFunctionReturn(BuildCtx & ctx, ITypeInfo * typ
             //optimize the way that cses are spotted to minimise unnecessary calculations
             OwnedHqlExpr branches = createComma(LINK(value->queryChild(1)), LINK(value->queryChild(2)));
             OwnedHqlExpr cond = LINK(value->queryChild(0));
-            spotScalarCSE(cond, branches, NULL, NULL);
+            spotScalarCSE(cond, branches, NULL, NULL, queryOptions().spotCseInIfDatasetConditions);
             BuildCtx subctx(ctx);
             IHqlStmt * stmt = buildFilterViaExpr(subctx, cond);
             doBuildUserFunctionReturn(subctx, type, branches->queryChild(0));
@@ -11416,7 +11417,7 @@ void HqlCppTranslator::doBuildUserFunctionReturn(BuildCtx & ctx, ITypeInfo * typ
         }
     default:
         {
-            OwnedHqlExpr optimized = spotScalarCSE(value);
+            OwnedHqlExpr optimized = spotScalarCSE(value, NULL, queryOptions().spotCseInIfDatasetConditions);
             if (value->isAction())
                 buildStmt(ctx, value);
             else

+ 1 - 0
ecl/hqlcpp/hqlcpp.ipp

@@ -598,6 +598,7 @@ struct HqlCppOptions
     bool                convertJoinToLookup;
     bool                convertJoinToLookupIfSorted;
     bool                spotCSE;
+    bool                spotCseInIfDatasetConditions;
     bool                noAllToLookupConversion;
     bool                optimizeNonEmpty;
     bool                allowVariableRoxieFilenames;

+ 3 - 3
ecl/hqlcpp/hqlcppds.cpp

@@ -829,7 +829,7 @@ void HqlCppTranslator::doBuildAssignAggregateLoop(BuildCtx & ctx, const CHqlBoun
         }
     case no_sum:
         {
-            OwnedHqlExpr cseArg = options.spotCSE ? spotScalarCSE(arg) : LINK(arg);
+            OwnedHqlExpr cseArg = options.spotCSE ? spotScalarCSE(arg, NULL, queryOptions().spotCseInIfDatasetConditions) : LINK(arg);
             buildIncrementAssign(loopctx, target, cseArg);
             break;
         }
@@ -839,7 +839,7 @@ void HqlCppTranslator::doBuildAssignAggregateLoop(BuildCtx & ctx, const CHqlBoun
             BuildCtx maxctx(loopctx);
             OwnedHqlExpr resultExpr = target.getTranslatedExpr();
 
-            OwnedHqlExpr cseArg = options.spotCSE ? spotScalarCSE(arg) : LINK(arg);
+            OwnedHqlExpr cseArg = options.spotCSE ? spotScalarCSE(arg, NULL, queryOptions().spotCseInIfDatasetConditions) : LINK(arg);
             OwnedHqlExpr simpleArg = buildSimplifyExpr(loopctx, cseArg);
             OwnedHqlExpr test = createBoolExpr((op == no_min) ? no_lt : no_gt, LINK(simpleArg), LINK(resultExpr));
             if (doneFirstVar)
@@ -3282,7 +3282,7 @@ void HqlCppTranslator::buildDatasetAssignJoin(BuildCtx & ctx, IHqlCppDatasetBuil
     BoundRow * rightCursor = buildDatasetIterate(rightIterCtx, right, false);
     bindTableCursor(rightIterCtx, right, rightCursor->queryBound(), no_right, selSeq);
 
-    OwnedHqlExpr cseCond = options.spotCSE ? spotScalarCSE(cond) : LINK(cond);
+    OwnedHqlExpr cseCond = options.spotCSE ? spotScalarCSE(cond, NULL, queryOptions().spotCseInIfDatasetConditions) : LINK(cond);
     buildFilter(rightIterCtx, cseCond);
     if (!expr->hasAttribute(leftonlyAtom))
     {

+ 9 - 9
ecl/hqlcpp/hqlcse.cpp

@@ -207,8 +207,8 @@ bool CseSpotterInfo::useInverseForAlias()
 
 
 static HqlTransformerInfo cseSpotterInfo("CseSpotter");
-CseSpotter::CseSpotter() 
-: NewHqlTransformer(cseSpotterInfo)
+CseSpotter::CseSpotter(bool _spotCseInIfDatasetConditions)
+: NewHqlTransformer(cseSpotterInfo), spotCseInIfDatasetConditions(_spotCseInIfDatasetConditions)
 {
     canAlias = true;
     isAssociated = false;
@@ -288,7 +288,7 @@ void CseSpotter::analyseExpr(IHqlExpression * expr)
         extra->canAlias = true;
 
     bool savedCanAlias = canAlias;
-    if (expr->isDataset() && (op != no_select))// && (op != no_if))
+    if (expr->isDataset() && (op != no_select) && (!spotCseInIfDatasetConditions || (op != no_if)))
     {
         //There is little point looking for CSEs within dataset expressions, because only a very small
         //minority which would correctly cse, and it can cause lots of problems - e.g., join conditions.
@@ -1113,7 +1113,7 @@ ANewTransformInfo * CseScopeTransformer::createTransformInfo(IHqlExpression * ex
 #endif
 
 
-IHqlExpression * spotScalarCSE(IHqlExpression * expr, IHqlExpression * limit)
+IHqlExpression * spotScalarCSE(IHqlExpression * expr, IHqlExpression * limit, bool spotCseInIfDatasetConditions)
 {
     if (expr->isConstant())
         return LINK(expr);
@@ -1130,7 +1130,7 @@ IHqlExpression * spotScalarCSE(IHqlExpression * expr, IHqlExpression * limit)
     bool addedAliases = false;
     //First spot the aliases - so that restructuring the ands doesn't lose any existing aliases.
     {
-        CseSpotter spotter;
+        CseSpotter spotter(spotCseInIfDatasetConditions);
         spotter.analyse(transformed, 0);
         if (spotter.foundCandidates())
         {
@@ -1167,9 +1167,9 @@ IHqlExpression * spotScalarCSE(IHqlExpression * expr, IHqlExpression * limit)
 }
 
 
-void spotScalarCSE(SharedHqlExpr & expr, SharedHqlExpr & associated, IHqlExpression * limit, IHqlExpression * invariantSelector)
+void spotScalarCSE(SharedHqlExpr & expr, SharedHqlExpr & associated, IHqlExpression * limit, IHqlExpression * invariantSelector, bool spotCseInIfDatasetConditions)
 {
-    CseSpotter spotter;
+    CseSpotter spotter(spotCseInIfDatasetConditions);
     spotter.analyse(expr, 0);
     if (associated)
         spotter.analyseAssociated(associated, 0);
@@ -1184,9 +1184,9 @@ void spotScalarCSE(SharedHqlExpr & expr, SharedHqlExpr & associated, IHqlExpress
 }
 
 
-void spotScalarCSE(HqlExprArray & exprs, HqlExprArray & associated, IHqlExpression * limit, IHqlExpression * invariantSelector)
+void spotScalarCSE(HqlExprArray & exprs, HqlExprArray & associated, IHqlExpression * limit, IHqlExpression * invariantSelector, bool spotCseInIfDatasetConditions)
 {
-    CseSpotter spotter;
+    CseSpotter spotter(spotCseInIfDatasetConditions);
     spotter.analyseArray(exprs, 0);
     ForEachItemIn(ia, associated)
         spotter.analyseAssociated(&associated.item(ia), 0);

+ 5 - 4
ecl/hqlcpp/hqlcse.ipp

@@ -52,7 +52,7 @@ class CseSpotter : public NewHqlTransformer
 {
     typedef NewHqlTransformer PARENT;
 public:
-    CseSpotter();
+    CseSpotter(bool _spotCseInIfDatasetConditions);
 
     void analyseAssociated(IHqlExpression * expr, unsigned pass);
     bool foundCandidates() const                            { return spottedCandidate; }
@@ -84,6 +84,7 @@ protected:
     bool spottedCandidate;
     bool createLocalAliases;
     bool createdAlias;
+    bool spotCseInIfDatasetConditions;
 };
 
 class ConjunctionTransformer : public NewHqlTransformer
@@ -212,9 +213,9 @@ protected:
 #endif
 
 
-IHqlExpression * spotScalarCSE(IHqlExpression * expr, IHqlExpression * limit = NULL);
-void spotScalarCSE(SharedHqlExpr & expr, SharedHqlExpr & associated, IHqlExpression * limit, IHqlExpression * invariantSelector);
-void spotScalarCSE(HqlExprArray & exprs, HqlExprArray & associated, IHqlExpression * limit, IHqlExpression * invariantSelector);
+IHqlExpression * spotScalarCSE(IHqlExpression * expr, IHqlExpression * limit, bool spotCseInIfDatasetConditions);
+void spotScalarCSE(SharedHqlExpr & expr, SharedHqlExpr & associated, IHqlExpression * limit, IHqlExpression * invariantSelector, bool spotCseInIfDatasetConditions);
+void spotScalarCSE(HqlExprArray & exprs, HqlExprArray & associated, IHqlExpression * limit, IHqlExpression * invariantSelector, bool spotCseInIfDatasetConditions);
 
 //---------------------------------------------------------------------------
 

+ 14 - 14
ecl/hqlcpp/hqlhtcpp.cpp

@@ -1331,7 +1331,7 @@ void HqlCppTranslator::filterExpandAssignments(BuildCtx & ctx, TransformBuilder
     LinkedHqlExpr expr = rawExpr;
 
     if (options.spotCSE)
-        expr.setown(spotScalarCSE(expr));
+        expr.setown(spotScalarCSE(expr, NULL, queryOptions().spotCseInIfDatasetConditions));
     traceExpression("transform cse", expr);
 
 //  expandAliases(ctx, expr);
@@ -3116,7 +3116,7 @@ void HqlCppTranslator::doBuildFunction(BuildCtx & ctx, ITypeInfo * type, const c
     {
         LinkedHqlExpr cseValue = value;
         if (options.spotCSE)
-            cseValue.setown(spotScalarCSE(cseValue));
+            cseValue.setown(spotScalarCSE(cseValue, NULL, queryOptions().spotCseInIfDatasetConditions));
 
         BuildCtx funcctx(ctx);
         if (false)
@@ -5042,7 +5042,7 @@ void HqlCppTranslator::buildSetResultInfo(BuildCtx & ctx, IHqlExpression * origi
     {
         LinkedHqlExpr cseValue = castValue;
         if (options.spotCSE)
-            cseValue.setown(spotScalarCSE(cseValue));
+            cseValue.setown(spotScalarCSE(cseValue, NULL, queryOptions().spotCseInIfDatasetConditions));
 
         if ((retType == type_set) && isComplexSet(resultType, false) && castValue->getOperator() == no_list && !isNullList(castValue))
         {
@@ -12198,7 +12198,7 @@ void HqlCppTranslator::buildProcessTransformFunction(BuildCtx & ctx, IHqlExpress
         //self won't clash, so can generate efficient code.
         //Perform cse on both transforms
         OwnedHqlExpr comma = createComma(LINK(transformRow), LINK(transformRight));
-        comma.setown(spotScalarCSE(comma));
+        comma.setown(spotScalarCSE(comma, NULL, queryOptions().spotCseInIfDatasetConditions));
         if (comma->getOperator() == no_alias_scope)
             comma.set(comma->queryChild(0));
 
@@ -13884,7 +13884,7 @@ ABoundActivity * HqlCppTranslator::doBuildActivityFirstN(BuildCtx & ctx, IHqlExp
     funcctx.addQuotedCompound("virtual __int64 getLimit()");
     OwnedHqlExpr newLimit = ensurePositiveOrZeroInt64(limit);
     if (options.spotCSE)
-        newLimit.setown(spotScalarCSE(newLimit));
+        newLimit.setown(spotScalarCSE(newLimit, NULL, queryOptions().spotCseInIfDatasetConditions));
     buildReturn(funcctx, newLimit);
 
     if (queryRealChild(expr, 2))
@@ -14555,7 +14555,7 @@ ABoundActivity * HqlCppTranslator::doBuildActivityProject(BuildCtx & ctx, IHqlEx
             case no_filter:
                 {
                     LinkedHqlExpr invariant;
-                    OwnedHqlExpr cond = extractFilterConditions(invariant, dataset, normalized, false);
+                    OwnedHqlExpr cond = extractFilterConditions(invariant, dataset, normalized, false, false);
                     //A dataset invariant filter is only worth combining if the engine supports a filtered project operation.
                     if (!options.supportFilterProject && invariant)
                     {
@@ -14778,7 +14778,7 @@ ABoundActivity * HqlCppTranslator::doBuildActivityExecuteWhen(BuildCtx & ctx, IH
 
 //---------------------------------------------------------------------------
 
-IHqlExpression * extractFilterConditions(HqlExprAttr & invariant, IHqlExpression * expr, IHqlExpression * dataset, bool spotCSE)
+IHqlExpression * extractFilterConditions(HqlExprAttr & invariant, IHqlExpression * expr, IHqlExpression * dataset, bool spotCSE, bool spotCseInIfDatasetConditions)
 {
     unsigned num = expr->numChildren();
     assertex(num > 1);
@@ -14795,7 +14795,7 @@ IHqlExpression * extractFilterConditions(HqlExprAttr & invariant, IHqlExpression
         return NULL;
 
     if (spotCSE)
-        cond.setown(spotScalarCSE(cond));
+        cond.setown(spotScalarCSE(cond, NULL, spotCseInIfDatasetConditions));
 
     HqlExprArray tests;
     cond->unwindList(tests, no_and);
@@ -14829,7 +14829,7 @@ ABoundActivity * HqlCppTranslator::doBuildActivityFilter(BuildCtx & ctx, IHqlExp
     buildInstancePrefix(instance);
 
     HqlExprAttr invariant;
-    OwnedHqlExpr cond = extractFilterConditions(invariant, expr, dataset, options.spotCSE);
+    OwnedHqlExpr cond = extractFilterConditions(invariant, expr, dataset, options.spotCSE, queryOptions().spotCseInIfDatasetConditions);
 
     //Base class returns true, so only generate if no non-invariant conditions
     if (cond)
@@ -14868,7 +14868,7 @@ ABoundActivity * HqlCppTranslator::doBuildActivityFilterGroup(BuildCtx & ctx, IH
 
     HqlExprAttr invariant;
     OwnedHqlExpr left = createSelector(no_left, dataset, selSeq);
-    OwnedHqlExpr cond = extractFilterConditions(invariant, expr, left, options.spotCSE);
+    OwnedHqlExpr cond = extractFilterConditions(invariant, expr, left, options.spotCSE, options.spotCseInIfDatasetConditions);
 
     //Base class returns true, so only generate if no non-invariant conditions
     if (cond)
@@ -15204,7 +15204,7 @@ ABoundActivity * HqlCppTranslator::doBuildActivityCatch(BuildCtx & ctx, IHqlExpr
         BuildCtx isMatchCtx(instance->startctx);
         isMatchCtx.addQuotedCompound("virtual bool isMatch(IException * except)");
         associateLocalFailure(isMatchCtx, "except");
-        OwnedHqlExpr cseFilter = spotScalarCSE(filter);
+        OwnedHqlExpr cseFilter = spotScalarCSE(filter, NULL, queryOptions().spotCseInIfDatasetConditions);
         buildReturn(isMatchCtx, cseFilter, queryBoolType());
     }
 
@@ -15642,7 +15642,7 @@ ABoundActivity * HqlCppTranslator::doBuildActivityIf(BuildCtx & ctx, IHqlExpress
     }
 
 
-    OwnedHqlExpr cseCond = options.spotCSE ? spotScalarCSE(cond) : LINK(cond);
+    OwnedHqlExpr cseCond = options.spotCSE ? spotScalarCSE(cond, NULL, queryOptions().spotCseInIfDatasetConditions) : LINK(cond);
     bool isChild = (insideChildOrLoopGraph(ctx) || insideRemoteGraph(ctx) || insideLibrary());
     IHqlExpression * activeGraph = queryActiveSubGraph(ctx)->graphTag;
 
@@ -15763,7 +15763,7 @@ ABoundActivity * HqlCppTranslator::doBuildActivityChoose(BuildCtx & ctx, IHqlExp
     funcctx.addQuotedCompound("virtual unsigned getBranch()");
     OwnedHqlExpr fullCond(foldHqlExpression(cond));
     if (options.spotCSE)
-        fullCond.setown(spotScalarCSE(fullCond));
+        fullCond.setown(spotScalarCSE(fullCond, NULL, queryOptions().spotCseInIfDatasetConditions));
     buildReturn(funcctx, fullCond);
 
     StringBuffer label;
@@ -15856,7 +15856,7 @@ ABoundActivity * HqlCppTranslator::doBuildActivityCase(BuildCtx & ctx, IHqlExpre
     OwnedHqlExpr fullCond = createValue(op, LINK(unsignedType), args);
     fullCond.setown(foldHqlExpression(fullCond));
     if (options.spotCSE)
-        fullCond.setown(spotScalarCSE(fullCond));
+        fullCond.setown(spotScalarCSE(fullCond, NULL, queryOptions().spotCseInIfDatasetConditions));
     buildReturn(funcctx, fullCond);
 
     bool graphIndependent = isGraphIndependent(fullCond, activeGraph);

+ 1 - 1
ecl/hqlcpp/hqlhtcpp.ipp

@@ -295,7 +295,7 @@ protected:
     bool            matchedDataset;
 };
 
-IHqlExpression * extractFilterConditions(HqlExprAttr & invariant, IHqlExpression * expr, IHqlExpression * dataset, bool spotCSE);
+IHqlExpression * extractFilterConditions(HqlExprAttr & invariant, IHqlExpression * expr, IHqlExpression * dataset, bool spotCSE, bool spotCseInIfDatasetConditions);
 bool isLibraryScope(IHqlExpression * expr);
 extern IHqlExpression * constantMemberMarkerExpr;
 

+ 1 - 1
ecl/hqlcpp/hqliter.cpp

@@ -149,7 +149,7 @@ void TransformSequenceBuilder::buildSequence(BuildCtx & ctx, BuildCtx * declarec
             if (translator.queryOptions().foldFilter)
                 test.setown(foldScopedHqlExpression(expr->queryChild(0)->queryNormalizedSelector(), test));
             if (translator.queryOptions().spotCSE)
-                test.setown(spotScalarCSE(test));
+                test.setown(spotScalarCSE(test, NULL, translator.queryOptions().spotCseInIfDatasetConditions));
             translator.buildFilteredReturn(ctx, test, failedFilterValue);
         }
         break;

+ 1 - 1
ecl/hqlcpp/hqlnlp.cpp

@@ -259,7 +259,7 @@ void NlpParseContext::buildValidators(HqlCppTranslator & translator, BuildCtx &
             validctx.associateExpr(activeValidateMarkerExpr, activeValidateMarkerExpr);
             translator.bindTableCursor(validctx, queryNlpParsePseudoTable(), queryNlpParsePseudoTable());
             if (translator.queryOptions().spotCSE)
-                validateExpr.setown(spotScalarCSE(validateExpr));
+                validateExpr.setown(spotScalarCSE(validateExpr, NULL, translator.queryOptions().spotCseInIfDatasetConditions));
             translator.buildReturn(validctx, validateExpr);
             translator.endNestedClass();
 

+ 1 - 1
ecl/hqlcpp/hqlresource.cpp

@@ -2971,7 +2971,7 @@ void EclResourcer::deriveUsageCounts(IHqlExpression * expr)
             else
             {
                 LinkedHqlExpr invariant;
-                OwnedHqlExpr cond = extractFilterConditions(invariant, expr, expr->queryNormalizedSelector(), false);
+                OwnedHqlExpr cond = extractFilterConditions(invariant, expr, expr->queryNormalizedSelector(), false, false);
                 if (invariant)
                     info->isConditionalFilter = true;
             }

+ 2 - 2
ecl/hqlcpp/hqlsource.cpp

@@ -1372,7 +1372,7 @@ void SourceBuilder::buildTransformElements(BuildCtx & ctx, IHqlExpression * expr
                         test.setown(foldScopedHqlExpression(ds->queryNormalizedSelector(), test));
 
                     if (translator.options.spotCSE)
-                        test.setown(spotScalarCSE(test, ds));
+                        test.setown(spotScalarCSE(test, ds, translator.queryOptions().spotCseInIfDatasetConditions));
 
                     if (!returnIfFilterFails)
                         translator.buildFilter(ctx, test);
@@ -4733,7 +4733,7 @@ void MonitorExtractor::spotSegmentCSE(BuildCtx & ctx)
     HqlExprArray associated;
     IHqlExpression * selector = tableExpr->queryNormalizedSelector();
     translator.traceExpressions("before seg spot", conditions);
-    spotScalarCSE(conditions, associated, NULL, selector);
+    spotScalarCSE(conditions, associated, NULL, selector, translator.queryOptions().spotCseInIfDatasetConditions);
     translator.traceExpressions("after seg spot", conditions);
 
     unsigned curCond = 0;