Add unreachable BasicBlock removal.
authorErik Verbruggen <erik.verbruggen@me.com>
Mon, 6 May 2013 09:06:16 +0000 (11:06 +0200)
committerLars Knoll <lars.knoll@digia.com>
Mon, 6 May 2013 12:49:51 +0000 (14:49 +0200)
This is band-aid to prevent CompressTemps crashing when trying to
allocate a stack slot for temps that are unreachable (or rephrased: they
are never live).

Change-Id: I021f319b07dd6f50553bb270aa40b0bcb48af4b6
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
src/qml/qml/v4/qv4codegen.cpp

index 2b796b3..b3a14a7 100644 (file)
@@ -223,7 +223,7 @@ void removeDeadAssignments(V4IR::Function *function)
     foreach (V4IR::BasicBlock *bb, function->basicBlocks) {
         QVector<V4IR::Stmt *> &statements = bb->statements;
         for (int i = 0; i < statements.size(); ) {
-//            qout<<"removeDeadAssignments: considering ";statements.at(i)->dump(qout);qout<<"\n";qout.flush();
+            qout<<"removeDeadAssignments: considering ";statements.at(i)->dump(qout);qout<<"\n";qout.flush();
             if (isDeadAssignment(statements.at(i), localCount)) {
                 statements.at(i)->destroyData();
                 statements.remove(i);
@@ -233,6 +233,26 @@ void removeDeadAssignments(V4IR::Function *function)
     }
 }
 
+void removeUnreachableBlocks(V4IR::Function *function)
+{
+    // TODO: change this to use a worklist.
+    // FIXME: actually, use SSA and then re-implement it.
+
+    for (int i = 1, ei = function->basicBlocks.size(); i != ei; ++i) {
+        V4IR::BasicBlock *bb = function->basicBlocks[i];
+        if (bb->in.isEmpty()) {
+            function->basicBlocks.remove(i);
+            foreach (V4IR::BasicBlock *outBB, bb->out) {
+                int idx = outBB->in.indexOf(bb);
+                if (idx != -1)
+                    outBB->in.remove(idx);
+            }
+            removeUnreachableBlocks(function);
+            return;
+        }
+    }
+}
+
 class ConstantPropagation: public V4IR::StmtVisitor, public V4IR::ExprVisitor
 {
     struct Value {
@@ -460,7 +480,7 @@ private:
     int thisTemp;
 };
 
-#undef DEBUG_TEMP_COMPRESSION
+#define DEBUG_TEMP_COMPRESSION
 #ifdef DEBUG_TEMP_COMPRESSION
 #  define DBTC(x) x
 #else // !DEBUG_TEMP_COMPRESSION
@@ -484,6 +504,7 @@ public:
                 for (int i = _localCount, ei = liveOut.size(); i < ei; ++i) {
                     if (liveOut.at(i) && !pinned.contains(i)) {
                         pinned.append(i);
+                        DBTC(qDebug() << "Pinning:";)
                         add(i - _localCount, _nextFree);
                     }
                 }
@@ -2428,8 +2449,10 @@ void Codegen::linearize(V4IR::Function *function)
     liveness(function);
 #endif
 
-    if (qgetenv("NO_OPT").isEmpty())
+    if (qgetenv("NO_OPT").isEmpty()) {
         removeDeadAssignments(function);
+        removeUnreachableBlocks(function);
+    }
 
     static bool showCode = !qgetenv("SHOW_CODE").isNull();
     if (showCode) {