# HG changeset patch # User Mario de Sousa # Date 1357232644 0 # Node ID b08167f156a11ff3c9aff968406f60f6c84f02d8 # Parent 2ed03e0e0e4152dc748dd5c556121111f0a009db# Parent 1e1c04ac8dabf4c17c1c996266a23ff2f0fd145d merge diff -r 2ed03e0e0e41 -r b08167f156a1 stage3/constant_folding.cc --- a/stage3/constant_folding.cc Fri Dec 28 11:51:24 2012 +0000 +++ b/stage3/constant_folding.cc Thu Jan 03 17:04:04 2013 +0000 @@ -117,13 +117,24 @@ * NOTE 2 * This file does not print out any error messages! * We cannot really print out error messages when we find an overflow. Since each operation - * (symbol in the absract syntax tree for that operation) will have up to 4 constant results, + * (symbol in the abstract syntax tree for that operation) will have up to 4 constant results, * it may happen that some of them overflow, while other do not. * We must wait for data type checking to determine the exact data type of each expression * before we can decide whether or not we should print out an overflow error message. * * For this reason, this visitor merely annotates the abstract syntax tree, and leaves the - * actuall printing of errors for the print_datatype_errors_c class! + * actually printing of errors for the print_datatype_errors_c class! + * + * NOTE 3 + * Constant Folding class is extended with a implementation constant propagation algorithm + * by Mario de Sousa. + * Main idea is not to implement a general constant propagation algorithm but to reinterpret it + * for visitor classes. + * We declared a hash map, it contains a variables list linked with current constant values. + * During expression evaluation we can retrieve a constant value to symbolic variables getting it from the map. + * Also at join source points we use a meet semilattice rules to merge current values between a block + * and adjacent block. + * */ #include "constant_folding.hh" @@ -941,7 +952,7 @@ void *constant_folding_c::visit(symbolic_variable_c *symbol) { std::string varName; - varName = convert.toString(symbol->var_name); + varName = get_var_name_c::get_name(symbol->var_name)->value; if (values.count(varName) > 0) { symbol->const_value = values[varName]; } @@ -958,7 +969,7 @@ 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); + std::string varName = get_var_name_c::get_name(var_name)->value; symbol_c *varDecl = search_var_instance_decl.get_decl(var_name); values[varName] = varDecl->const_value; } @@ -1247,8 +1258,9 @@ symbol->r_exp->accept(*this); symbol->l_exp->const_value = symbol->r_exp->const_value; - varName = convert.toString(symbol->l_exp); + varName = get_var_name_c::get_name(symbol->l_exp)->value; values[varName] = symbol->l_exp->const_value; + return NULL; } @@ -1260,8 +1272,13 @@ std::map values_statement_result; std::map values_elsestatement_result; std::map ::iterator itr; + + /* Optimize dead code */ + symbol->expression->accept(*this); + if (VALID_CVALUE(bool, symbol->expression) && GET_CVALUE(bool, symbol->expression) == false) + return NULL; + values_incoming = values; /* save incoming status */ - symbol->statement_list->accept(*this); values_statement_result = values; if (NULL != symbol->else_statement_list) { @@ -1287,8 +1304,122 @@ value = values_statement_result[name]; values[name] = value; } - return NULL; -} - - - + + return NULL; +} + +/********************************/ +/* B 3.2.4 Iteration Statements */ +/********************************/ +void *constant_folding_c::visit(for_statement_c *symbol) { + std::map values_incoming; + std::map values_statement_result; + std::map ::iterator itr; + std::string varName; + + values_incoming = values; /* save incoming status */ + symbol->beg_expression->accept(*this); + symbol->end_expression->accept(*this); + varName = get_var_name_c::get_name(symbol->control_variable)->value; + values[varName] = symbol->beg_expression->const_value; + + /* Optimize dead code */ + if (VALID_CVALUE(int64, symbol->beg_expression) && VALID_CVALUE(int64, symbol->end_expression) && + GET_CVALUE(int64, symbol->beg_expression) > GET_CVALUE(int64, symbol->end_expression)) + return NULL; + + symbol->statement_list->accept(*this); + values_statement_result = values; + 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_incoming.count(name) > 0) { + symbol_c::const_value_t c1 = itr->second; + symbol_c::const_value_t c2 = values_incoming[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; +} + +void *constant_folding_c::visit(while_statement_c *symbol) { + std::map values_incoming; + std::map values_statement_result; + std::map ::iterator itr; + + /* Optimize dead code */ + symbol->expression->accept(*this); + if (VALID_CVALUE(bool, symbol->expression) && GET_CVALUE(bool, symbol->expression) == false) + return NULL; + + values_incoming = values; /* save incoming status */ + symbol->statement_list->accept(*this); + values_statement_result = values; + 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_incoming.count(name) > 0) { + symbol_c::const_value_t c1 = itr->second; + symbol_c::const_value_t c2 = values_incoming[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; +} + +void *constant_folding_c::visit(repeat_statement_c *symbol) { + std::map values_incoming; + std::map values_statement_result; + std::map ::iterator itr; + + /* Optimize dead code */ + symbol->expression->accept(*this); + if (VALID_CVALUE(bool, symbol->expression) && GET_CVALUE(bool, symbol->expression) == false) + return NULL; + + values_incoming = values; /* save incoming status */ + symbol->statement_list->accept(*this); + values_statement_result = values; + 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_incoming.count(name) > 0) { + symbol_c::const_value_t c1 = itr->second; + symbol_c::const_value_t c2 = values_incoming[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 2ed03e0e0e41 -r b08167f156a1 stage3/constant_folding.hh --- a/stage3/constant_folding.hh Fri Dec 28 11:51:24 2012 +0000 +++ b/stage3/constant_folding.hh Thu Jan 03 17:04:04 2013 +0000 @@ -30,7 +30,7 @@ * */ -/* Determine the data type of an constant expression. +/* Determine the value of an constant expression. * A reference to the relevant type definition is returned. * * For example: @@ -43,30 +43,6 @@ #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 { search_varfb_instance_type_c *search_varfb_instance_type; int error_count; @@ -76,7 +52,6 @@ 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); @@ -222,5 +197,12 @@ /* B 3.2.3 Selection Statements */ /********************************/ void *visit(if_statement_c *symbol); + + /********************************/ + /* B 3.2.4 Iteration Statements */ + /********************************/ + void *visit(for_statement_c *symbol); + void *visit(while_statement_c *symbol); + void *visit(repeat_statement_c *symbol); }; diff -r 2ed03e0e0e41 -r b08167f156a1 stage4/generate_c/Makefile.am --- a/stage4/generate_c/Makefile.am Fri Dec 28 11:51:24 2012 +0000 +++ b/stage4/generate_c/Makefile.am Thu Jan 03 17:04:04 2013 +0000 @@ -6,5 +6,5 @@ libstage4_c_a_LIBADD = ../stage4.o -libstage4_c_a_cppflags = -I../../../absyntax +libstage4_c_a_CPPFLAGS = -I../../../absyntax diff -r 2ed03e0e0e41 -r b08167f156a1 stage4/generate_iec/Makefile.am --- a/stage4/generate_iec/Makefile.am Fri Dec 28 11:51:24 2012 +0000 +++ b/stage4/generate_iec/Makefile.am Thu Jan 03 17:04:04 2013 +0000 @@ -6,5 +6,5 @@ libstage4_iec_a_LIBADD = ../stage4.o -libstage4_iec_a_cppflags = -I../../../absyntax +libstage4_iec_a_CPPFLAGS = -I../../../absyntax