ExpressionPtr BinaryOpExpression::simplifyLogical(AnalysisResultPtr ar) {
  if (m_exp1->is(Expression::KindOfConstantExpression)) {
    ConstantExpressionPtr con =
      dynamic_pointer_cast<ConstantExpression>(m_exp1);
    if (con->isBoolean()) {
      if (con->getBooleanValue()) {
        if (ar->getPhase() >= AnalysisResult::PostOptimize) {
          // true && v (true AND v) => v
          ASSERT(m_exp2->getType()->is(Type::KindOfBoolean));
          if (m_op == T_BOOLEAN_AND || m_op == T_LOGICAL_AND) return m_exp2;
        }
        // true || v (true OR v) => true
        if (m_op == T_BOOLEAN_OR || m_op == T_LOGICAL_OR) {
          return CONSTANT("true");
        }
      } else {
        if (ar->getPhase() >= AnalysisResult::PostOptimize) {
          ASSERT(m_exp2->getType()->is(Type::KindOfBoolean));
          // false || v (false OR v) => v
          if (m_op == T_BOOLEAN_OR || m_op == T_LOGICAL_OR) return m_exp2;
        }
        // false && v (false AND v) => false
        if (m_op == T_BOOLEAN_AND || m_op == T_LOGICAL_AND) {
          return CONSTANT("false");
        }
      }
    }
  }
  if (m_exp2->is(Expression::KindOfConstantExpression)) {
    ConstantExpressionPtr con =
      dynamic_pointer_cast<ConstantExpression>(m_exp2);
    if (con->isBoolean()) {
      if (con->getBooleanValue()) {
        if (ar->getPhase() >= AnalysisResult::PostOptimize) {
          ASSERT(m_exp1->getType()->is(Type::KindOfBoolean));
          // v && true (v AND true) => v
          if (m_op == T_BOOLEAN_AND || m_op == T_LOGICAL_AND) return m_exp1;
        }
        // v || true (v OR true) => true when v does not have effect
        if (m_op == T_BOOLEAN_OR || m_op == T_LOGICAL_OR) {
          if (!m_exp1->hasEffect()) return CONSTANT("true");
        }
      } else {
        if (ar->getPhase() >= AnalysisResult::PostOptimize) {
          ASSERT(m_exp1->getType()->is(Type::KindOfBoolean));
          // v || false (v OR false) => v
          if (m_op == T_BOOLEAN_OR || m_op == T_LOGICAL_OR) return m_exp1;
        }
        // v && false (v AND false) => false when v does not have effect
        if (m_op == T_BOOLEAN_AND || m_op == T_LOGICAL_AND) {
          if (!m_exp1->hasEffect()) return CONSTANT("false");
        }
      }
    }
  }
  return ExpressionPtr();
}
Esempio n. 2
0
bool Option::Load(bool &option, ExpressionPtr value) {
  ConstantExpressionPtr v = dynamic_pointer_cast<ConstantExpression>(value);
  if (!v || !v->isBoolean()) {
    Logger::Error("Line %d: invalid boolean: %s", value->getLocation()->line1,
                  value->getText().c_str());
    return false;
  }
  option = v->getBooleanValue();
  return true;
}
Esempio n. 3
0
StatementPtr IfStatement::postOptimize(AnalysisResultConstPtr ar) {
  // we cannot optimize away the code inside if statement, because
  // there may be a goto that goes into if statement.
  if (hasReachableLabel()) {
    return StatementPtr();
  }

  bool changed = false;
  for (int i = 0; i < m_stmts->getCount(); i++) {
    IfBranchStatementPtr branch =
      dynamic_pointer_cast<IfBranchStatement>((*m_stmts)[i]);
    ExpressionPtr condition = branch->getCondition();
    if (!branch->getStmt() || !branch->getStmt()->hasImpl()) {
      if (!condition ||
          (i == m_stmts->getCount() - 1 &&
           !condition->hasEffect())) {
        // remove else branch without C++ implementation.
        m_stmts->removeElement(i);
        changed = true;
      } else if (condition->is(Expression::KindOfConstantExpression)) {
        ConstantExpressionPtr exp =
          dynamic_pointer_cast<ConstantExpression>(condition);
        // Remove if (false) branch without C++ implementation.
        // if (true) branch without C++ implementation is kept unless
        // it is the last branch. In general we cannot let a if (true)
        // branch short-circuit the rest branches which if removed may
        // cause g++ to complain unreferenced variables.
        if (exp->isBoolean()) {
          if (!exp->getBooleanValue() ||
              (exp->getBooleanValue() && i == m_stmts->getCount() - 1)) {
            m_stmts->removeElement(i);
            changed = true;
            i--;
          }
        }
      }
    }
  }
  if (m_stmts->getCount() == 0) {
    return NULL_STATEMENT();
  } else {
    return changed ? static_pointer_cast<Statement>(shared_from_this())
                   : StatementPtr();
  }
}
Esempio n. 4
0
StatementPtr IfStatement::preOptimize(AnalysisResultPtr ar) {
  if (ar->getPhase() < AnalysisResult::FirstPreOptimize) {
    return StatementPtr();
  }

  bool changed = false;
  int i;
  int j;
  for (i = 0; i < m_stmts->getCount(); i++) {
    IfBranchStatementPtr branch =
      dynamic_pointer_cast<IfBranchStatement>((*m_stmts)[i]);
    ExpressionPtr condition = branch->getCondition();
    if (!condition) {
      StatementPtr stmt = branch->getStmt();
      if (stmt && stmt->is(KindOfIfStatement)) {
        StatementListPtr sub_stmts =
          dynamic_pointer_cast<IfStatement>(stmt)->m_stmts;
        m_stmts->removeElement(i);
        changed = true;
        for (j = 0; j < sub_stmts->getCount(); j++) {
          m_stmts->insertElement((*sub_stmts)[j], i++);
        }
      }
      break;
    } else if (condition->is(Expression::KindOfConstantExpression)) {
      ConstantExpressionPtr exp =
        dynamic_pointer_cast<ConstantExpression>(condition);
      if (exp->isBoolean()) {
        if (exp->getBooleanValue()) {
          // if (true) branch
          for (j = i + 1; j < m_stmts->getCount(); j++) {
            if ((*m_stmts)[j]->hasDecl()) break;
          }
          // no declarations after if (true)
          if (j == m_stmts->getCount()) break;
        } else {
          // if (false) branch
          if (!branch->hasDecl()) {
            m_stmts->removeElement(i);
            changed = true;
            i--;
          }
        }
      }
    }
  }

  if (i == m_stmts->getCount()) return StatementPtr();

  // either else branch or if (true) branch without further declarations

  i++;
  while (i < m_stmts->getCount()) {
    m_stmts->removeElement(i);
    changed = true;
  }

  // if there is only one branch left, return stmt.
  if (m_stmts->getCount() == 1) {
    return dynamic_pointer_cast<IfBranchStatement>((*m_stmts)[0])->getStmt();
  } else if (m_stmts->getCount() == 0) {
    return NULL_STATEMENT();
  } else {
    return changed ? static_pointer_cast<Statement>(shared_from_this())
                   : StatementPtr();
  }
}