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(); }
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(); } }
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; }
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(); } }