aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@me.com>2013-06-17 12:37:01 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-07-05 12:46:42 +0200
commit2e4d1ccb18aba13f94670d3d1104839fecf2ab5c (patch)
tree26d6af30dad75339081c43ca165d813d916f1664 /src
parentdefa077c93ccfd128433715b078294df7609afe6 (diff)
Introduce PhysicalRegister and StackSlot Temps.
Change-Id: I8d0b6a1e85fd0c42772f294fd13bc6041d41c81e Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/qml/qml/v4/qv4isel_masm.cpp84
-rw-r--r--src/qml/qml/v4/qv4jsir_p.h4
2 files changed, 85 insertions, 3 deletions
diff --git a/src/qml/qml/v4/qv4isel_masm.cpp b/src/qml/qml/v4/qv4isel_masm.cpp
index c5246684cf..e931f54a0d 100644
--- a/src/qml/qml/v4/qv4isel_masm.cpp
+++ b/src/qml/qml/v4/qv4isel_masm.cpp
@@ -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;
diff --git a/src/qml/qml/v4/qv4jsir_p.h b/src/qml/qml/v4/qv4jsir_p.h
index 05dd6578ca..659d9870b1 100644
--- a/src/qml/qml/v4/qv4jsir_p.h
+++ b/src/qml/qml/v4/qv4jsir_p.h
@@ -340,7 +340,9 @@ struct Temp: Expr {
ScopedFormal,
Local,
ScopedLocal,
- VirtualRegister
+ VirtualRegister,
+ PhysicalRegister,
+ StackSlot
};
unsigned index;