Start to implement constant propagation algorithm.
--- 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 <std::string, symbol_c::const_value_t> 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 <std::string, symbol_c::const_value_t> values_incoming;
+ std::map <std::string, symbol_c::const_value_t> values_statement_result;
+ std::map <std::string, symbol_c::const_value_t> values_elsestatement_result;
+ std::map <std::string, symbol_c::const_value_t>::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;
+}
+
+
+
--- 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);
};