Start to implement constant propagation algorithm.
authorManuele Conti <conti.ma@alice.it>
Sat, 22 Dec 2012 19:31:48 +0100
changeset 774 979af2009d88
parent 773 d23c660361b1
child 775 0422ee273152
Start to implement constant propagation algorithm.
stage3/constant_folding.cc
stage3/constant_folding.hh
--- 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);
 };