# HG changeset patch # User Manuele Conti # Date 1356201108 -3600 # Node ID 979af2009d88369e41ca6b1c07439b9f1d85afe5 # Parent d23c660361b1f7a229a25131253aae32e181e9c5 Start to implement constant propagation algorithm. diff -r d23c660361b1 -r 979af2009d88 stage3/constant_folding.cc --- a/stage3/constant_folding.cc Sat Dec 22 19:30:44 2012 +0100 +++ b/stage3/constant_folding.cc Sat Dec 22 19:31:48 2012 +0100 @@ -206,8 +206,25 @@ {SET_NONCONST(dtype, symbol);} \ } - - +/* Meet rules + * - any * T = any + * - any * B = B + * - constant * constant = constant (if equal) + * - constant * constant = B (if not equal) + */ +#define COMPUTE_MEET_SEMILATTICE(dtype, c1, c2, resValue) {\ + if ((c1._##dtype.value != c2._##dtype.value && c2._##dtype.status == symbol_c::cs_const_value && c1._##dtype.status == symbol_c::cs_const_value) ||\ + ( c1._##dtype.status == symbol_c::cs_non_const && c2._##dtype.status == symbol_c::cs_const_value ) ||\ + ( c2._##dtype.status == symbol_c::cs_non_const && c1._##dtype.status == symbol_c::cs_const_value )) {\ + resValue._##dtype.status = symbol_c::cs_non_const;\ + } else {\ + resValue._##dtype.status = symbol_c::cs_const_value;\ + resValue._##dtype.value = c1._##dtype.value;\ + }\ +} + + +static std::map values; /***********************************************************************/ @@ -916,6 +933,37 @@ return NULL; } +/*********************/ +/* B 1.4 - Variables */ +/*********************/ +void *constant_folding_c::visit(symbolic_variable_c *symbol) { + std::string varName; + + varName = convert.toString(symbol->var_name); + if (values.count(varName) > 0) { + symbol->const_value = values[varName]; + } + return NULL; +} + +/**********************/ +/* B 1.5.3 - Programs */ +/**********************/ +void *constant_folding_c::visit(program_declaration_c *symbol) { + symbol_c *var_name; + + values.clear(); /* Clear global map */ + search_var_instance_decl_c search_var_instance_decl(symbol); + function_param_iterator_c fpi(symbol); + while((var_name = fpi.next()) != NULL) { + std::string varName = convert.toString(var_name); + symbol_c *varDecl = search_var_instance_decl.get_decl(var_name); + values[varName] = varDecl->const_value; + } + /* Add all variables declared into Values map and put them to initial value */ + symbol->function_block_body->accept(*this); + return NULL; +} /****************************************/ @@ -1185,3 +1233,60 @@ /* TODO: handle function invocations... */ // void *fill_candidate_datatypes_c::visit(function_invocation_c *symbol) {} + + + + +/*********************************/ +/* B 3.2.1 Assignment Statements */ +/*********************************/ +void *constant_folding_c::visit(assignment_statement_c *symbol) { + std::string varName; + + symbol->r_exp->accept(*this); + symbol->l_exp->const_value = symbol->r_exp->const_value; + varName = convert.toString(symbol->l_exp); + values[varName] = symbol->l_exp->const_value; + return NULL; +} + +/********************************/ +/* B 3.2.3 Selection Statements */ +/********************************/ +void *constant_folding_c::visit(if_statement_c *symbol) { + std::map values_incoming; + std::map values_statement_result; + std::map values_elsestatement_result; + std::map ::iterator itr; + values_incoming = values; /* save incoming status */ + + symbol->statement_list->accept(*this); + values_statement_result = values; + if (NULL != symbol->else_statement_list) { + values = values_incoming; + symbol->else_statement_list->accept(*this); + values_elsestatement_result = values; + } else + values_elsestatement_result = values_incoming; + values.clear(); + itr = values_statement_result.begin(); + for ( ; itr != values_statement_result.end(); ++itr) { + std::string name = itr->first; + symbol_c::const_value_t value; + + if (values_elsestatement_result.count(name) > 0) { + symbol_c::const_value_t c1 = itr->second; + symbol_c::const_value_t c2 = values_elsestatement_result[name]; + COMPUTE_MEET_SEMILATTICE (real64, c1, c2, value); + COMPUTE_MEET_SEMILATTICE (uint64, c1, c2, value); + COMPUTE_MEET_SEMILATTICE ( int64, c1, c2, value); + COMPUTE_MEET_SEMILATTICE ( bool, c1, c2, value); + } else + value = values_statement_result[name]; + values[name] = value; + } + return NULL; +} + + + diff -r d23c660361b1 -r 979af2009d88 stage3/constant_folding.hh --- a/stage3/constant_folding.hh Sat Dec 22 19:30:44 2012 +0100 +++ b/stage3/constant_folding.hh Sat Dec 22 19:31:48 2012 +0100 @@ -43,9 +43,31 @@ #include "../absyntax_utils/absyntax_utils.hh" +class convert_c : public iterator_visitor_c { + std::string text; + +public: + convert_c(symbol_c *symbol = NULL) { + text = ""; + } + + std::string toString(symbol_c *symbol) { + symbol->accept(*this); + return text; + } + + void *visit(identifier_c *symbol) { + text = symbol->value; + return NULL; + } + + void *visit(symbolic_variable_c *symbol) { + symbol->var_name->accept(*this); + return NULL; + } +}; class constant_folding_c : public iterator_visitor_c { - private: search_varfb_instance_type_c *search_varfb_instance_type; int error_count; bool warning_found; @@ -54,6 +76,7 @@ symbol_c *prev_il_instruction; /* the current IL operand being analyzed */ symbol_c *il_operand; + convert_c convert; public: constant_folding_c(symbol_c *symbol = NULL); @@ -86,6 +109,16 @@ /********* **************/ void *visit(fixed_point_c *symbol); + /*********************/ + /* B 1.4 - Variables */ + /*********************/ + void *visit(symbolic_variable_c *symbol); + + /**********************/ + /* B 1.5.3 - Programs */ + /**********************/ + void *visit(program_declaration_c *symbol); + /****************************************/ /* B.2 - Language IL (Instruction List) */ /****************************************/ @@ -178,6 +211,16 @@ void *visit( neg_expression_c *symbol); void *visit( not_expression_c *symbol); //void *visit(function_invocation_c *symbol); /* TODO */ + + /*********************************/ + /* B 3.2.1 Assignment Statements */ + /*********************************/ + void *visit(assignment_statement_c *symbol); + + /********************************/ + /* B 3.2.3 Selection Statements */ + /********************************/ + void *visit(if_statement_c *symbol); };