merge
authorMario de Sousa <msousa@fe.up.pt>
Thu, 03 Jan 2013 17:04:04 +0000
changeset 785 b08167f156a1
parent 779 2ed03e0e0e41 (current diff)
parent 784 1e1c04ac8dab (diff)
child 786 c370918ca7fb
child 793 268bf4ca5fa1
child 794 d534db26cbd5
merge
--- 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 <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;
+
+	/* 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 <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>::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 <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>::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 <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>::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;
+}
+
+
+
--- 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);
 };
 
--- 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
 
--- 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