ExpressionPtr AssignmentExpression::postOptimize(AnalysisResultPtr ar) {
  ar->postOptimize(m_variable);
  ar->postOptimize(m_value);
  if (m_variable->is(Expression::KindOfSimpleVariable)) {
    SimpleVariablePtr var =
      dynamic_pointer_cast<SimpleVariable>(m_variable);
    const std::string &name = var->getName();
    VariableTablePtr variables = ar->getScope()->getVariables();
    if (variables->checkUnused(name)) {
      variables->addUnused(name);
      if (m_value->getContainedEffects() != getContainedEffects()) {
        s_effectsTag++;
      }
      return m_value;
    }
  }
  return ExpressionPtr();
}
bool ExpressionList::optimize(AnalysisResultPtr ar) {
  bool changed = false;
  size_t i = m_exps.size();
  if (m_kind != ListKindParam) {
    if (i--) {
      while (i--) {
        ExpressionPtr &e = m_exps[i];
        if (!e || e->getContainedEffects() == NoEffect) {
          ar->incOptCounter();
          removeElement(i);
          changed = true;
        } else if (e->getLocalEffects() == NoEffect) {
          e = e->unneeded(ar);
          changed = true;
        }
      }
    }
    return changed;
  }

  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);
        const std::string &name = var->getName();
        VariableTablePtr variables = ar->getScope()->getVariables();
        if (variables->checkUnused(name)) {
          removeElement(i);
          changed = true;
        }
      }
    }
  }
  return changed;
}
bool SimpleVariable::checkUnused(AnalysisResultPtr ar) const {
  VariableTablePtr variables = ar->getScope()->getVariables();
  return !m_superGlobal && variables->checkUnused(m_name);
}