Moved temp compression to codegen to use for all backends.
authorErik Verbruggen <erik.verbruggen@me.com>
Tue, 12 Mar 2013 11:46:44 +0000 (12:46 +0100)
committerLars Knoll <lars.knoll@digia.com>
Tue, 12 Mar 2013 23:46:57 +0000 (00:46 +0100)
Change-Id: I3afba14741f18782e71210b14d9d091fe0bebc51
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
src/v4/moth/qv4isel_moth.cpp
src/v4/qv4codegen.cpp

index 9c6d185..7684a1b 100644 (file)
@@ -10,164 +10,6 @@ using namespace QQmlJS::Moth;
 
 namespace {
 
-QTextStream qout(stderr, QIODevice::WriteOnly);
-
-//#define DEBUG_TEMP_COMPRESSION
-#ifdef DEBUG_TEMP_COMPRESSION
-#  define DBTC(x) x
-#else // !DEBUG_TEMP_COMPRESSION
-#  define DBTC(x)
-#endif // DEBUG_TEMP_COMPRESSION
-class CompressTemps: public IR::StmtVisitor, IR::ExprVisitor
-{
-public:
-    void run(IR::Function *function)
-    {
-        DBTC(qDebug() << "starting on function" << (*function->name) << "with" << function->tempCount << "temps.";)
-
-        _nextFree = 0;
-        _active.reserve(function->tempCount);
-        _localCount = function->locals.size();
-
-        QVector<int> pinned;
-        foreach (IR::BasicBlock *block, function->basicBlocks) {
-            if (IR::Stmt *last = block->terminator()) {
-                const QBitArray &liveOut = last->d->liveOut;
-                for (int i = _localCount, ei = liveOut.size(); i < ei; ++i) {
-                    if (liveOut.at(i) && !pinned.contains(i)) {
-                        pinned.append(i);
-                        add(i - _localCount, _nextFree);
-                    }
-                }
-            }
-        }
-        _pinnedCount = _nextFree;
-
-        int maxUsed = _nextFree;
-
-        foreach (IR::BasicBlock *block, function->basicBlocks) {
-            DBTC(qDebug("L%d:", block->index));
-
-            for (int i = 0, ei = block->statements.size(); i < ei; ++i ) {
-                _currentStatement = block->statements[i];
-                if (i == 0)
-                    expireOld();
-
-                DBTC(_currentStatement->dump(qout);qout<<endl<<flush;)
-
-                if (_currentStatement->d)
-                    _currentStatement->accept(this);
-            }
-            maxUsed = std::max(maxUsed, _nextFree);
-        }
-        DBTC(qDebug() << "function" << (*function->name) << "uses" << maxUsed << "temps.";)
-        function->tempCount = maxUsed + _localCount;
-    }
-
-protected:
-    virtual void visitConst(IR::Const *) {}
-    virtual void visitString(IR::String *) {}
-    virtual void visitRegExp(IR::RegExp *) {}
-    virtual void visitName(IR::Name *) {}
-    virtual void visitClosure(IR::Closure *) {}
-    virtual void visitUnop(IR::Unop *e) { e->expr->accept(this); }
-    virtual void visitBinop(IR::Binop *e) { e->left->accept(this); e->right->accept(this); }
-    virtual void visitSubscript(IR::Subscript *e) { e->base->accept(this); e->index->accept(this); }
-    virtual void visitMember(IR::Member *e) { e->base->accept(this); }
-    virtual void visitExp(IR::Exp *s) { s->expr->accept(this); }
-    virtual void visitEnter(IR::Enter *) {}
-    virtual void visitLeave(IR::Leave *) {}
-    virtual void visitJump(IR::Jump *) {}
-    virtual void visitCJump(IR::CJump *s) { s->cond->accept(this); }
-    virtual void visitRet(IR::Ret *s) { s->expr->accept(this); }
-    virtual void visitTry(IR::Try *t) { visitTemp(t->exceptionVar); }
-
-    virtual void visitTemp(IR::Temp *e) {
-        if (e->scope) // scoped local
-            return;
-        if (e->index < _localCount) // local or argument
-            return;
-
-        e->index = remap(e->index - _localCount) + _localCount;
-    }
-
-    virtual void visitCall(IR::Call *e) {
-        e->base->accept(this);
-        for (IR::ExprList *it = e->args; it; it = it->next)
-            it->expr->accept(this);
-    }
-
-    virtual void visitNew(IR::New *e) {
-        e->base->accept(this);
-        for (IR::ExprList *it = e->args; it; it = it->next)
-            it->expr->accept(this);
-    }
-
-    virtual void visitMove(IR::Move *s) {
-        s->target->accept(this);
-        s->source->accept(this);
-    }
-
-private:
-    int remap(int tempIndex) {
-        for (ActiveTemps::const_iterator i = _active.begin(), ei = _active.end(); i < ei; ++i) {
-            if (i->first == tempIndex) {
-                DBTC(qDebug() << "    lookup" << (tempIndex + _localCount) << "->" << (i->second + _localCount);)
-                return i->second;
-            }
-        }
-
-        int firstFree = expireOld();
-        add(tempIndex, firstFree);
-        return firstFree;
-    }
-
-    void add(int tempIndex, int firstFree) {
-        if (_nextFree <= firstFree)
-            _nextFree = firstFree + 1;
-        _active.prepend(qMakePair(tempIndex, firstFree));
-        DBTC(qDebug() << "    add" << (tempIndex + _localCount) << "->" << (firstFree+ _localCount);)
-    }
-
-    int expireOld() {
-        Q_ASSERT(_currentStatement->d);
-
-        const QBitArray &liveIn = _currentStatement->d->liveIn;
-        QBitArray inUse(_nextFree);
-        int i = 0;
-        while (i < _active.size()) {
-            const QPair<int, int> &p = _active[i];
-
-            if (p.second < _pinnedCount) {
-                inUse.setBit(p.second);
-                ++i;
-                continue;
-            }
-
-            if (liveIn[p.first + _localCount]) {
-                inUse[p.second] = true;
-                ++i;
-            } else {
-                DBTC(qDebug() << "    remove" << (p.first + _localCount) << "->" << (p.second + _localCount);)
-                _active.remove(i);
-            }
-        }
-        for (int i = 0, ei = inUse.size(); i < ei; ++i)
-            if (!inUse[i])
-                return i;
-        return _nextFree;
-    }
-
-private:
-    typedef QVector<QPair<int, int> > ActiveTemps;
-    ActiveTemps _active;
-    IR::Stmt *_currentStatement;
-    int _localCount;
-    int _nextFree;
-    int _pinnedCount;
-};
-#undef DBTC
-
 inline VM::BinOp aluOpFunction(IR::AluOp op)
 {
     switch (op) {
@@ -273,9 +115,6 @@ void InstructionSelection::run(VM::Function *vmFunction, IR::Function *function)
     qSwap(codeNext, _codeNext);
     qSwap(codeEnd, _codeEnd);
 
-    if (qgetenv("NO_OPT").isEmpty())
-        CompressTemps().run(_function);
-
     int locals = frameSize();
     assert(locals >= 0);
 
index a899f0c..dbccda4 100644 (file)
@@ -458,6 +458,162 @@ private:
     int thisTemp;
 };
 
+#undef DEBUG_TEMP_COMPRESSION
+#ifdef DEBUG_TEMP_COMPRESSION
+#  define DBTC(x) x
+#else // !DEBUG_TEMP_COMPRESSION
+#  define DBTC(x)
+#endif // DEBUG_TEMP_COMPRESSION
+class CompressTemps: public IR::StmtVisitor, IR::ExprVisitor
+{
+public:
+    void run(IR::Function *function)
+    {
+        _nextFree = 0;
+        _active.reserve(function->tempCount);
+        _localCount = function->locals.size();
+
+        DBTC(qDebug() << "starting on function" << (*function->name) << "with" << (function->tempCount - _localCount) << "temps.";)
+
+        QVector<int> pinned;
+        foreach (IR::BasicBlock *block, function->basicBlocks) {
+            if (IR::Stmt *last = block->terminator()) {
+                const QBitArray &liveOut = last->d->liveOut;
+                for (int i = _localCount, ei = liveOut.size(); i < ei; ++i) {
+                    if (liveOut.at(i) && !pinned.contains(i)) {
+                        pinned.append(i);
+                        add(i - _localCount, _nextFree);
+                    }
+                }
+            }
+        }
+        _pinnedCount = _nextFree;
+
+        int maxUsed = _nextFree;
+
+        foreach (IR::BasicBlock *block, function->basicBlocks) {
+            DBTC(qDebug("L%d:", block->index));
+
+            for (int i = 0, ei = block->statements.size(); i < ei; ++i ) {
+                _currentStatement = block->statements[i];
+                if (i == 0)
+                    expireOld();
+
+                DBTC(_currentStatement->dump(qout);qout<<endl<<flush;)
+
+                if (_currentStatement->d)
+                    _currentStatement->accept(this);
+            }
+            maxUsed = std::max(maxUsed, _nextFree);
+        }
+        DBTC(qDebug() << "function" << (*function->name) << "uses" << maxUsed << "temps.";)
+        function->tempCount = maxUsed + _localCount;
+    }
+
+protected:
+    virtual void visitConst(IR::Const *) {}
+    virtual void visitString(IR::String *) {}
+    virtual void visitRegExp(IR::RegExp *) {}
+    virtual void visitName(IR::Name *) {}
+    virtual void visitClosure(IR::Closure *) {}
+    virtual void visitUnop(IR::Unop *e) { e->expr->accept(this); }
+    virtual void visitBinop(IR::Binop *e) { e->left->accept(this); e->right->accept(this); }
+    virtual void visitSubscript(IR::Subscript *e) { e->base->accept(this); e->index->accept(this); }
+    virtual void visitMember(IR::Member *e) { e->base->accept(this); }
+    virtual void visitExp(IR::Exp *s) { s->expr->accept(this); }
+    virtual void visitEnter(IR::Enter *) {}
+    virtual void visitLeave(IR::Leave *) {}
+    virtual void visitJump(IR::Jump *) {}
+    virtual void visitCJump(IR::CJump *s) { s->cond->accept(this); }
+    virtual void visitRet(IR::Ret *s) { s->expr->accept(this); }
+    virtual void visitTry(IR::Try *t) { visitTemp(t->exceptionVar); }
+
+    virtual void visitTemp(IR::Temp *e) {
+        if (e->scope) // scoped local
+            return;
+        if (e->index < _localCount) // local or argument
+            return;
+
+        e->index = remap(e->index - _localCount) + _localCount;
+    }
+
+    virtual void visitCall(IR::Call *e) {
+        e->base->accept(this);
+        for (IR::ExprList *it = e->args; it; it = it->next)
+            it->expr->accept(this);
+    }
+
+    virtual void visitNew(IR::New *e) {
+        e->base->accept(this);
+        for (IR::ExprList *it = e->args; it; it = it->next)
+            it->expr->accept(this);
+    }
+
+    virtual void visitMove(IR::Move *s) {
+        s->target->accept(this);
+        s->source->accept(this);
+    }
+
+private:
+    int remap(int tempIndex) {
+        for (ActiveTemps::const_iterator i = _active.begin(), ei = _active.end(); i < ei; ++i) {
+            if (i->first == tempIndex) {
+                DBTC(qDebug() << "    lookup" << (tempIndex + _localCount) << "->" << (i->second + _localCount);)
+                return i->second;
+            }
+        }
+
+        int firstFree = expireOld();
+        add(tempIndex, firstFree);
+        return firstFree;
+    }
+
+    void add(int tempIndex, int firstFree) {
+        if (_nextFree <= firstFree)
+            _nextFree = firstFree + 1;
+        _active.prepend(qMakePair(tempIndex, firstFree));
+        DBTC(qDebug() << "    add" << (tempIndex + _localCount) << "->" << (firstFree+ _localCount);)
+    }
+
+    int expireOld() {
+        Q_ASSERT(_currentStatement->d);
+
+        const QBitArray &liveIn = _currentStatement->d->liveIn;
+        QBitArray inUse(_nextFree);
+        int i = 0;
+        while (i < _active.size()) {
+            const QPair<int, int> &p = _active[i];
+
+            if (p.second < _pinnedCount) {
+                inUse.setBit(p.second);
+                ++i;
+                continue;
+            }
+
+            if (liveIn[p.first + _localCount]) {
+                inUse[p.second] = true;
+                ++i;
+            } else {
+                DBTC(qDebug() << "    remove" << (p.first + _localCount) << "->" << (p.second + _localCount);)
+                _active.remove(i);
+            }
+        }
+        for (int i = 0, ei = inUse.size(); i < ei; ++i)
+            if (!inUse[i])
+                return i;
+        return _nextFree;
+    }
+
+private:
+    typedef QVector<QPair<int, int> > ActiveTemps;
+    ActiveTemps _active;
+    IR::Stmt *_currentStatement;
+    int _localCount;
+    int _nextFree;
+    int _pinnedCount;
+};
+#undef DBTC
+
 } // end of anonymous namespace
 
 class Codegen::ScanFunctions: Visitor
@@ -2197,6 +2353,10 @@ void Codegen::linearize(IR::Function *function)
         qout << "}" << endl
              << endl;
     }
+
+    //### NOTE: after this pass, the liveness information is not correct anymore!
+    if (qgetenv("NO_OPT").isEmpty())
+        CompressTemps().run(function);
 }
 
 IR::Function *Codegen::defineFunction(const QString &name, AST::Node *ast,