[Scummvm-cvs-logs] SF.net SVN: scummvm:[41450] tools/branches/gsoc2009-decompiler/decompiler

kjdf at users.sourceforge.net kjdf at users.sourceforge.net
Thu Jun 11 16:50:06 CEST 2009


Revision: 41450
          http://scummvm.svn.sourceforge.net/scummvm/?rev=41450&view=rev
Author:   kjdf
Date:     2009-06-11 14:50:05 +0000 (Thu, 11 Jun 2009)

Log Message:
-----------
decompiler: removing jumps to jumps and resulting dead code

Modified Paths:
--------------
    tools/branches/gsoc2009-decompiler/decompiler/cfg.h
    tools/branches/gsoc2009-decompiler/decompiler/decompiler.cc
    tools/branches/gsoc2009-decompiler/decompiler/decompiler.rb

Modified: tools/branches/gsoc2009-decompiler/decompiler/cfg.h
===================================================================
--- tools/branches/gsoc2009-decompiler/decompiler/cfg.h	2009-06-11 12:02:19 UTC (rev 41449)
+++ tools/branches/gsoc2009-decompiler/decompiler/cfg.h	2009-06-11 14:50:05 UTC (rev 41450)
@@ -15,12 +15,23 @@
 
 
 struct Node {
+
 	uint32 _id;
 	static uint32 _g_id;
 	vector<Node*> _in, _out;
+
 	Node() {
 		_id = _g_id++;
 	}
+
+	void removeInEdge(Node *from) {
+		for (vector<Node*>::iterator it = _in.begin(); it != _in.end(); it++)
+			if (*it == from) {
+				_in.erase(it);
+				return;
+			}
+	}
+
 	virtual ~Node() {
 	};
 };
@@ -82,14 +93,14 @@
 	}
 
 	BasicBlock *blockByStart(index_t idx) {
-		for (index_t i = 0; i < _blocks.size(); i++)
+		for (uint32 i = 0; i < _blocks.size(); i++)
 			if (_blocks[i]->_start == idx)
 				return _blocks[i];
 		return 0;
 	}
 
 	BasicBlock *blockByEnd(index_t idx) {
-		for (index_t i = 0; i < _blocks.size(); i++)
+		for (uint32 i = 0; i < _blocks.size(); i++)
 			if (_blocks[i]->_end == idx)
 				return _blocks[i];
 		return 0;
@@ -100,6 +111,50 @@
 		to->_in.push_back(from);
 	}
 
+	void removeJumpsToJumps() {
+		for (bool changed = true; changed; ) {
+			changed = false;
+			for (uint32 i = 0; i < _blocks.size(); i++)
+				for (uint32 j = 0; j < _blocks[i]->_out.size(); j++) {
+					BasicBlock *bbout = (BasicBlock*) _blocks[i]->_out[j];
+					Jump *jump = dynamic_cast<Jump*>(_script[bbout->_start]);
+					if (jump && !dynamic_cast<CondJump*>(jump)) {
+						changed = true;
+						BasicBlock *newtgt = blockByStart(_script.index(jump->target()));
+						bbout->removeInEdge(_blocks[i]);
+						newtgt->_in.push_back(_blocks[i]);
+						_blocks[i]->_out[j] = newtgt;
+					}
+				}
+		}
+	}
+
+	// TODO
+	// after this _blocks[i]->_id == i no longer holds
+	// also it won't work for more than one graph so we need a better way
+	// (move to _blocks being a list and map<id,Block*> for quick access?)
+	void removeDeadBlocks() {
+		set<uint32> visited;
+		vector<uint32> stack;
+		visited.insert(0);
+		stack.push_back(0);
+		while (!stack.empty()) {
+			uint32 id = stack.back();
+			stack.pop_back();
+			Node *node = _blocks[id];
+			for (uint32 i = 0; i < node->_out.size(); i++)
+				if (visited.find(node->_out[i]->_id) == visited.end()) {
+					visited.insert(node->_out[i]->_id);
+					stack.push_back(node->_out[i]->_id);
+				}
+		}
+		for (vector<BasicBlock*>::iterator it = _blocks.begin(); it != _blocks.end(); )
+			if (visited.find((*it)->_id) == visited.end())
+				it = _blocks.erase(it);
+			else
+				it++;
+	}
+
 	CFG(Script &script) : _script(script) {
 		Jump *j;
 		set<address_t> targets;

Modified: tools/branches/gsoc2009-decompiler/decompiler/decompiler.cc
===================================================================
--- tools/branches/gsoc2009-decompiler/decompiler/decompiler.cc	2009-06-11 12:02:19 UTC (rev 41449)
+++ tools/branches/gsoc2009-decompiler/decompiler/decompiler.cc	2009-06-11 14:50:05 UTC (rev 41450)
@@ -38,6 +38,8 @@
 			script.print(i);
 	if (g_blocks)
 		cfg->printBasicBlocks();
+	cfg->removeJumpsToJumps();
+	cfg->removeDeadBlocks();
 	if (g_graph)
 		cfg->printDot();
 	return 0;

Modified: tools/branches/gsoc2009-decompiler/decompiler/decompiler.rb
===================================================================
--- tools/branches/gsoc2009-decompiler/decompiler/decompiler.rb	2009-06-11 12:02:19 UTC (rev 41449)
+++ tools/branches/gsoc2009-decompiler/decompiler/decompiler.rb	2009-06-11 14:50:05 UTC (rev 41450)
@@ -3,7 +3,7 @@
 require 'getoptlong'
 require 'tempfile'
 
-$image_viewer = 'eog'
+$image_viewer = 'eog -n'
 
 def usage
    puts "decompiler.rb [--graph] file.dmp"
@@ -12,7 +12,7 @@
 def graph filename
    tmpfile = Tempfile.new 'decompiler'
    system "./decompiler -graph #{filename} | dot -T svg -o #{tmpfile.path}"
-   `#{$image_viewer} #{tmpfile.path}`
+   system `#{$image_viewer} #{tmpfile.path}`
 end
 
 


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list