void LogicalGraphCreator::createGraphActivity(IHqlExpression * expr) { LogicalGraphInfo * extra = queryExtra(expr); if (extra->globalId && !inSubQuery()) { extra->id = extra->globalId; return; } //First generate children... //MORE: may want to do inputs first and dependents afterwards. IAtom * dependencyKind = dependencyAtom; unsigned first = getFirstActivityArgument(expr); unsigned last = first + getNumActivityArguments(expr); node_operator op = expr->getOperator(); HqlExprArray inputs, dependents; bool defaultInputs = true; switch (op) { case no_setresult: case no_map: last = first; dependencyKind = NULL; break; case no_select: if (!isNewSelector(expr)) { last = first; } break; case no_addfiles: expandUnnamedFunnel(inputs, expr->queryBody()); defaultInputs = false; break; case no_colon: { if (!isWorkflowExpanded(expr)) defaultInputs = false; gatherWorkflowActivities(expr, dependents); inputs.append(*LINK(expr->queryChild(0))); defaultInputs = false; break; } case no_forcelocal: case no_forcenolocal: case no_allnodes: case no_thisnode: { IHqlExpression * child = expr->queryChild(0); createSubGraphActivity(child); addDependent(dependents, child); defaultInputs = false; break; } } if (defaultInputs) { ForEachChild(i, expr) { IHqlExpression * cur = expr->queryChild(i); if ((i >= first && i < last) && !cur->isAttribute()) inputs.append(*LINK(cur)); else if (includeChildInDependents(expr, i)) gatherGraphActivities(cur, dependents); } }
void CseSpotter::analyseExpr(IHqlExpression * expr) { CseSpotterInfo * extra = queryBodyExtra(expr); if (!extra->annotatedExpr && expr->isAnnotation()) extra->annotatedExpr = expr; if (isAssociated) extra->numAssociatedRefs++; node_operator op = expr->getOperator(); #ifdef OPTIMIZE_INVERSE if (getInverseOp(op) != no_none) { OwnedHqlExpr inverse = getInverse(expr); CseSpotterInfo * inverseExtra = queryBodyExtra(inverse); extra->inverse = inverseExtra; inverseExtra->inverse = extra; } #endif if (op == no_alias) { queryBodyExtra(expr->queryChild(0))->alreadyAliased = true; extra->alreadyAliased = true; } switch (op) { case no_assign: case no_transform: case no_newtransform: case no_range: case no_rangefrom: if (expr->isConstant()) return; break; case no_constant: return; } if (extra->numRefs++ != 0) { if (op == no_alias) return; if (!spottedCandidate && extra->worthAliasing()) spottedCandidate = true; if (canCreateTemporary(expr)) return; //Ugly! This is here as a temporary hack to stop branches of maps being commoned up and always //evaluated. The alias spotting and generation really needs to take conditionality into account.... if (op == no_mapto) return; } if (!containsPotentialCSE(expr)) return; if (canAlias && !expr->isDataset()) extra->canAlias = true; bool savedCanAlias = canAlias; 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. unsigned first = getFirstActivityArgument(expr); unsigned num = getNumActivityArguments(expr); HqlExprArray children; bool defaultCanAlias = canAlias; ForEachChild(i, expr) { IHqlExpression * cur = expr->queryChild(i); if (i >= first && i < first+num) canAlias = defaultCanAlias; else canAlias = false; analyseExpr(cur); }