[phc-internals] [phc commit] r1483 - in branches/dataflow/src: optimize process_ir

codesite-noreply at google.com codesite-noreply at google.com
Wed Jul 30 01:28:23 IST 2008


Author: paul.biggar
Date: Tue Jul 29 08:14:04 2008
New Revision: 1483

Modified:
   branches/dataflow/src/optimize/CFG.cpp
   branches/dataflow/src/optimize/CFG.h
   branches/dataflow/src/optimize/Live_variable_analysis.cpp
   branches/dataflow/src/process_ir/fresh.cpp
   branches/dataflow/src/process_ir/fresh.h

Log:
Convert the CFG back into linear statements. It uses the same 
alghorithm as on the saturn branch: we do a depth-first-search over the 
CFG, and return a label, a statement and a goto to the next statement. 
After the traversal, redundant gotos are removed, followed by unused labels.

This hasn't been heavily tested, but its the final step required to 
test the whole lot.


Modified: branches/dataflow/src/optimize/CFG.cpp
==============================================================================
--- branches/dataflow/src/optimize/CFG.cpp	(original)
+++ branches/dataflow/src/optimize/CFG.cpp	Tue Jul 29 08:14:04 2008
@@ -7,6 +7,8 @@

 #include "boost/foreach.hpp"
 #include "boost/graph/graphviz.hpp"
+#include "boost/graph/depth_first_search.hpp"
+#include "boost/graph/visitors.hpp"

 #include "CFG.h"
 #include "process_ast/DOT_unparser.h"
@@ -345,3 +347,114 @@
 		remove_bb (bb);
 	}
 }
+
+// Do a depth first search. For each block, add a label, and a goto to 
the next
+// block(s).
+class Linearizer : public default_dfs_visitor
+{
+public:
+	List<Statement*>* statements;
+	map<vertex_t, LABEL_NAME*> labels;
+	Linearizer()
+	{
+		statements = new List<Statement*>;
+	}
+
+	/* Assign a label for each block. */
+	void initialize_vertex (vertex_t v, const Graph& g)
+	{
+		labels [v] = fresh_label_name ();
+	}
+
+	/* Return a Goto to the next statement. */
+	Goto* get_goto_next (Basic_block* bb, const Graph& g)
+	{
+		vertex_t v = bb->vertex;
+		assert (out_degree (v, g) == 1);
+		vertex_t t = target (*out_edges (v, g).first, g);
+		return new Goto (labels[t]);
+	}
+
+	void discover_vertex (vertex_t v, const Graph& g)
+	{
+		Basic_block* bb = get(vertex_bb_t(), g)[v];
+
+		if (Statement_block* sb = dynamic_cast<Statement_block*> (bb))
+		{
+			statements->push_back (new Label(labels[v]->clone ()));
+			statements->push_back (sb->statement);
+			statements->push_back (get_goto_next (bb, g));
+		}
+
+		else if (dynamic_cast<Entry_block*> (bb))
+			statements->push_back (get_goto_next (bb, g));
+
+		else if (dynamic_cast<Exit_block*> (bb))
+			statements->push_back (new Label(labels[v]->clone ()));
+
+		else if (dynamic_cast<Empty_block*> (bb))
+		{
+			statements->push_back (new Label(labels[v]->clone ()));
+			statements->push_back (get_goto_next (bb, g));
+		}
+		else
+			assert (0); // TODO branches
+	}
+};
+
+class Label_counter : public Visitor
+{
+	map<string, int>* counts;
+public:
+	Label_counter (map<string, int>* c) : counts(c) {}
+
+	void pre_label_name (LABEL_NAME* in)
+	{
+		(*counts)[*in->value]++;
+	}
+};
+
+List<Statement*>*
+CFG::get_linear_statements ()
+{
+	Linearizer linearizer;
+	depth_first_search (bs, visitor (linearizer));
+	List<Statement*>* results = linearizer.statements;
+
+	/* Remove redundant gotos, which would fall-through to their targets
+	 * anyway. */
+	List<Statement*>::iterator i = results->begin ();
+	while (i != results->end ())
+	{
+		Wildcard<LABEL_NAME>* ln = new Wildcard<LABEL_NAME>;
+		Statement* s = *i;
+		Statement* next = *(++i);
+		if (s->match (new Goto (ln))
+			&& next->match (new Label (ln->value)))
+		{
+			i--;
+
+			// Use this form of looping so that the iterator moves to the next
+			// iterm before its invalidated.
+			results->erase (i++);
+		}
+	}
+
+	/* Remove labels that are only used once. */
+	map<string, int> label_counts;
+	(new Label_counter (&label_counts))->visit_statement_list (results);
+
+	i = results->begin ();
+	while (i != results->end ())
+	{
+		Wildcard<LABEL_NAME>* ln = new Wildcard<LABEL_NAME>;
+		if ((*i)->match (new Label (ln))
+			&& label_counts[*ln->value->value] == 1)
+			results->erase (i++);
+		else
+			i++;
+	}
+
+	return results;
+}
+

Modified: branches/dataflow/src/optimize/CFG.h
==============================================================================
--- branches/dataflow/src/optimize/CFG.h	(original)
+++ branches/dataflow/src/optimize/CFG.h	Tue Jul 29 08:14:04 2008
@@ -61,6 +61,7 @@

 	CFG ();
 	void add_statements (List<MIR::Statement*>* statements);
+	List<MIR::Statement*>* get_linear_statements ();

 	// Add the BB to the graph, and update the BB's vertex.
 	vertex_t add_bb (Basic_block* bb);

Modified: branches/dataflow/src/optimize/Live_variable_analysis.cpp
==============================================================================
--- branches/dataflow/src/optimize/Live_variable_analysis.cpp	(original)
+++ branches/dataflow/src/optimize/Live_variable_analysis.cpp	Tue Jul 
29 08:14:04 2008
@@ -42,6 +42,7 @@
 		Dead_code_elimination* dce = new Dead_code_elimination;
 		dce->visit (cfg);
 		cfg->dump_graphviz (s("AFTER DCE"));
+		method->statements = cfg->get_linear_statements ();
 	}
 }


Modified: branches/dataflow/src/process_ir/fresh.cpp
==============================================================================
--- branches/dataflow/src/process_ir/fresh.cpp	(original)
+++ branches/dataflow/src/process_ir/fresh.cpp	Tue Jul 29 08:14:04 2008
@@ -115,9 +115,14 @@

 	Label* fresh_label ()
 	{
+		return new Label (fresh_label_name ());
+	}
+
+	LABEL_NAME* fresh_label_name ()
+	{
 		int suffix = fresh_suffix ();
 		LABEL_NAME* result = new LABEL_NAME (fresh ("L", suffix));
 		result->attrs->set ("phc.fresh.suffix", new Integer (suffix));
-		return new Label (result);
+		return result;
 	}
 }

Modified: branches/dataflow/src/process_ir/fresh.h
==============================================================================
--- branches/dataflow/src/process_ir/fresh.h	(original)
+++ branches/dataflow/src/process_ir/fresh.h	Tue Jul 29 08:14:04 2008
@@ -31,6 +31,7 @@
 {
 	MIR::VARIABLE_NAME* fresh_var_name (string prefix);
 	MIR::Label* fresh_label ();
+	LABEL_NAME* fresh_label_name ();
 	MIR::HT_ITERATOR* fresh_iter ();
 }



More information about the phc-internals mailing list