void ExpressionList::optimize(AnalysisResultConstPtr ar) { bool changed = false; size_t i = m_exps.size(); if (m_kind != ListKindParam) { size_t skip = m_kind == ListKindLeft ? 0 : i - 1; while (i--) { if (i != skip) { ExpressionPtr &e = m_exps[i]; if (!e || e->getContainedEffects() == NoEffect) { removeElement(i); changed = true; } else if (e->is(KindOfExpressionList)) { ExpressionListPtr el(static_pointer_cast<ExpressionList>(e)); removeElement(i); for (size_t j = el->getCount(); j--; ) { insertElement((*el)[j], i); } changed = true; } else if (e->getLocalEffects() == NoEffect) { e = e->unneeded(); // changed already handled by unneeded } } } if (m_exps.size() == 1) { m_kind = ListKindWrapped; } else if (m_kind == ListKindLeft && m_exps[0]->isScalar()) { ExpressionPtr e = m_exps[0]; removeElement(0); addElement(e); m_kind = ListKindWrapped; } } else { if (hasContext(UnsetContext) && ar->getPhase() >= AnalysisResult::PostOptimize) { while (i--) { ExpressionPtr &e = m_exps[i]; if (e->is(Expression::KindOfSimpleVariable)) { SimpleVariablePtr var = dynamic_pointer_cast<SimpleVariable>(e); if (var->checkUnused()) { const std::string &name = var->getName(); VariableTablePtr variables = getScope()->getVariables(); if (!variables->isNeeded(name)) { removeElement(i); changed = true; } } } } } } if (changed) { getScope()->addUpdates(BlockScope::UseKindCaller); } }
bool Expression::CheckNeeded(ExpressionPtr variable, ExpressionPtr value) { // if the value may involve object, consider the variable as "needed" // so that objects are not destructed prematurely. bool needed = true; if (value) needed = CheckNeededRHS(value); if (variable->is(Expression::KindOfSimpleVariable)) { auto var = dynamic_pointer_cast<SimpleVariable>(variable); const std::string &name = var->getName(); VariableTablePtr variables = var->getScope()->getVariables(); if (needed) { variables->addNeeded(name); } else { needed = variables->isNeeded(name); } } return needed; }
void ExpressionList::optimize(AnalysisResultConstPtr ar) { bool changed = false; size_t i = m_exps.size(); if (m_kind != ListKindParam) { size_t skip = m_kind == ListKindLeft ? 0 : i - 1; while (i--) { if (i != skip) { ExpressionPtr &e = m_exps[i]; if (!e || (e->getContainedEffects() == NoEffect && !e->isNoRemove())) { removeElement(i); changed = true; } else if (e->is(KindOfExpressionList)) { ExpressionListPtr el(static_pointer_cast<ExpressionList>(e)); removeElement(i); for (size_t j = el->getCount(); j--; ) { insertElement((*el)[j], i); } changed = true; } else if (e->getLocalEffects() == NoEffect) { e = e->unneeded(); // changed already handled by unneeded } } } if (m_exps.size() == 1) { // don't convert an exp-list with type assertions to // a ListKindWrapped if (!isNoRemove()) { m_kind = ListKindWrapped; } } else if (m_kind == ListKindLeft && m_exps[0]->isScalar()) { ExpressionPtr e = m_exps[0]; removeElement(0); addElement(e); m_kind = ListKindWrapped; } } else { bool isUnset = hasContext(UnsetContext) && // This used to be gated on ar->getPhase() >= PostOptimize false; int isGlobal = -1; while (i--) { ExpressionPtr &e = m_exps[i]; if (isUnset) { if (e->is(Expression::KindOfSimpleVariable)) { SimpleVariablePtr var = dynamic_pointer_cast<SimpleVariable>(e); if (var->checkUnused()) { const std::string &name = var->getName(); VariableTablePtr variables = getScope()->getVariables(); if (!variables->isNeeded(name)) { removeElement(i); changed = true; } } } } else { bool global = e && (e->getContext() & Declaration) == Declaration; if (isGlobal < 0) { isGlobal = global; } else { always_assert(isGlobal == global); } if (isGlobal && e->isScalar()) { removeElement(i); changed = true; } } } } if (changed) { getScope()->addUpdates(BlockScope::UseKindCaller); } }