Introduce PhysicalRegister and StackSlot Temps.
authorErik Verbruggen <erik.verbruggen@me.com>
Mon, 17 Jun 2013 10:37:01 +0000 (12:37 +0200)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Fri, 5 Jul 2013 10:46:42 +0000 (12:46 +0200)
Change-Id: I8d0b6a1e85fd0c42772f294fd13bc6041d41c81e
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
src/qml/qml/v4/qv4isel_masm.cpp
src/qml/qml/v4/qv4jsir_p.h

index c524668..e931f54 100644 (file)
@@ -63,6 +63,75 @@ using namespace QQmlJS;
 using namespace QQmlJS::MASM;
 using namespace QV4;
 
+namespace {
+class ConvertTemps: protected V4IR::StmtVisitor, protected V4IR::ExprVisitor
+{
+    int _nextFreeStackSlot;
+    QHash<V4IR::Temp, int> _stackSlotForTemp;
+
+    void renumber(V4IR::Temp *t)
+    {
+        if (t->kind != V4IR::Temp::VirtualRegister)
+            return;
+
+        int stackSlot = _stackSlotForTemp.value(*t, -1);
+        if (stackSlot == -1) {
+            stackSlot = _nextFreeStackSlot++;
+            _stackSlotForTemp[*t] = stackSlot;
+        }
+
+        t->kind = V4IR::Temp::StackSlot;
+        t->index = stackSlot;
+    }
+
+public:
+    ConvertTemps()
+        : _nextFreeStackSlot(0)
+    {}
+
+    void toStackSlots(V4IR::Function *function)
+    {
+        _stackSlotForTemp.reserve(function->tempCount);
+
+        foreach (V4IR::BasicBlock *bb, function->basicBlocks)
+            foreach (V4IR::Stmt *s, bb->statements)
+                s->accept(this);
+
+        function->tempCount = _nextFreeStackSlot;
+    }
+
+protected:
+    virtual void visitConst(V4IR::Const *) {}
+    virtual void visitString(V4IR::String *) {}
+    virtual void visitRegExp(V4IR::RegExp *) {}
+    virtual void visitName(V4IR::Name *) {}
+    virtual void visitTemp(V4IR::Temp *e) { renumber(e); }
+    virtual void visitClosure(V4IR::Closure *) {}
+    virtual void visitConvert(V4IR::Convert *e) { e->expr->accept(this); }
+    virtual void visitUnop(V4IR::Unop *e) { e->expr->accept(this); }
+    virtual void visitBinop(V4IR::Binop *e) { e->left->accept(this); e->right->accept(this); }
+    virtual void visitCall(V4IR::Call *e) {
+        e->base->accept(this);
+        for (V4IR::ExprList *it = e->args; it; it = it->next)
+            it->expr->accept(this);
+    }
+    virtual void visitNew(V4IR::New *e) {
+        e->base->accept(this);
+        for (V4IR::ExprList *it = e->args; it; it = it->next)
+            it->expr->accept(this);
+    }
+    virtual void visitSubscript(V4IR::Subscript *e) { e->base->accept(this); e->index->accept(this); }
+    virtual void visitMember(V4IR::Member *e) { e->base->accept(this); }
+    virtual void visitExp(V4IR::Exp *s) { s->expr->accept(this); }
+    virtual void visitMove(V4IR::Move *s) { s->target->accept(this); s->source->accept(this); }
+    virtual void visitJump(V4IR::Jump *) {}
+    virtual void visitCJump(V4IR::CJump *s) { s->cond->accept(this); }
+    virtual void visitRet(V4IR::Ret *s) { s->expr->accept(this); }
+    virtual void visitTry(V4IR::Try *s) { s->exceptionVar->accept(this); }
+    virtual void visitPhi(V4IR::Phi *) { Q_UNREACHABLE(); }
+};
+} // anonymous namespace
+
 /* Platform/Calling convention/Architecture specific section */
 
 #if CPU(X86_64)
@@ -170,7 +239,7 @@ Assembler::Pointer Assembler::loadTempAddress(RegisterID reg, V4IR::Temp *t)
         loadPtr(Address(context, offsetof(CallContext, locals)), reg);
         offset = t->index * sizeof(Value);
     } break;
-    case V4IR::Temp::VirtualRegister: {
+    case V4IR::Temp::StackSlot: {
         assert(t->scope == 0);
         const int arg = _function->maxNumberOfArguments + t->index + 1;
         offset = - sizeof(Value) * (arg + 1);
@@ -563,6 +632,7 @@ InstructionSelection::InstructionSelection(QV4::ExecutionEngine *engine, V4IR::M
     , _function(0)
     , _vmFunction(0)
     , _as(0)
+    , _locals(0)
 {
 }
 
@@ -584,7 +654,17 @@ void InstructionSelection::run(QV4::Function *vmFunction, V4IR::Function *functi
 
     V4IR::Optimizer opt(_function);
     opt.run();
-    opt.convertOutOfSSA();
+    if (opt.isInSSA()) {
+#if CPU(X86_64) && (OS(MAC_OS_X) || OS(LINUX)) && 0
+        // TODO: add a register allocator here.
+#else
+        // No register allocator available for this platform, so:
+        opt.convertOutOfSSA();
+        ConvertTemps().toStackSlots(_function);
+#endif
+    } else {
+        ConvertTemps().toStackSlots(_function);
+    }
 
     int locals = (_function->tempCount + _function->maxNumberOfArguments) + 1;
     locals = (locals + 1) & ~1;
index 05dd657..659d987 100644 (file)
@@ -340,7 +340,9 @@ struct Temp: Expr {
         ScopedFormal,
         Local,
         ScopedLocal,
-        VirtualRegister
+        VirtualRegister,
+        PhysicalRegister,
+        StackSlot
     };
 
     unsigned index;