aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@me.com>2013-10-02 14:41:35 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-10-03 07:06:35 +0200
commitf9305f9ffaf8dd443369a156f7f7650de6372265 (patch)
tree1d9c0e1dbe921b2a96d0ffdcd6111aafb093cdde /src
parentc860d1399b4ff5f3a5b1b2630bc33112c88c13e8 (diff)
V4: invert conditions when the true block follows the test.
Change-Id: I5044acd4263b71734e4eb5d7e74b1a4a8414741e Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/masm/assembler/MacroAssembler.h2
-rw-r--r--src/3rdparty/masm/masm-defs.pri1
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h1
-rw-r--r--src/qml/compiler/qv4isel_masm.cpp47
-rw-r--r--src/qml/compiler/qv4isel_masm_p.h5
-rw-r--r--src/qml/compiler/qv4isel_moth.cpp18
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp2
7 files changed, 52 insertions, 24 deletions
diff --git a/src/3rdparty/masm/assembler/MacroAssembler.h b/src/3rdparty/masm/assembler/MacroAssembler.h
index f74680d7fc..0c95bc7ca1 100644
--- a/src/3rdparty/masm/assembler/MacroAssembler.h
+++ b/src/3rdparty/masm/assembler/MacroAssembler.h
@@ -90,7 +90,7 @@ public:
static const double twoToThe32; // This is super useful for some double code.
// Utilities used by the DFG JIT.
-#if ENABLE(DFG_JIT)
+#if ENABLE(DFG_JIT) || ENABLE(DFG_JIT_UTILITY_METHODS)
using MacroAssemblerBase::invert;
static DoubleCondition invert(DoubleCondition cond)
diff --git a/src/3rdparty/masm/masm-defs.pri b/src/3rdparty/masm/masm-defs.pri
index 836ac0c796..ef9f79a42f 100644
--- a/src/3rdparty/masm/masm-defs.pri
+++ b/src/3rdparty/masm/masm-defs.pri
@@ -20,6 +20,7 @@ win*: DEFINES += NOMINMAX
DEFINES += ENABLE_LLINT=0
DEFINES += ENABLE_DFG_JIT=0
+DEFINES += ENABLE_DFG_JIT_UTILITY_METHODS=1
DEFINES += ENABLE_JIT_CONSTANT_BLINDING=0
DEFINES += ENABLE_ASSEMBLER=1
DEFINES += BUILDING_QT__
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index f8ccfff92f..3c28633491 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -438,6 +438,7 @@ union Instr
MOTH_INSTR_HEADER
ptrdiff_t offset;
Param condition;
+ bool invert;
};
struct instr_unop {
MOTH_INSTR_HEADER
diff --git a/src/qml/compiler/qv4isel_masm.cpp b/src/qml/compiler/qv4isel_masm.cpp
index 850dc64b99..5ee539648e 100644
--- a/src/qml/compiler/qv4isel_masm.cpp
+++ b/src/qml/compiler/qv4isel_masm.cpp
@@ -262,6 +262,19 @@ void Assembler::addPatch(DataLabelPtr patch, V4IR::BasicBlock *target)
_labelPatches[target].append(patch);
}
+void Assembler::generateCJumpOnNonZero(RegisterID reg, V4IR::BasicBlock *currentBlock,
+ V4IR::BasicBlock *trueBlock, V4IR::BasicBlock *falseBlock)
+{
+ if (trueBlock == _nextBlock) {
+ Jump target = branch32(Equal, reg, TrustedImm32(0));
+ addPatch(falseBlock, target);
+ } else {
+ Jump target = branch32(NotEqual, reg, TrustedImm32(0));
+ addPatch(trueBlock, target);
+ jumpToBlock(currentBlock, falseBlock);
+ }
+}
+
Assembler::Pointer Assembler::loadTempAddress(RegisterID reg, V4IR::Temp *t)
{
int32_t offset = 0;
@@ -1688,19 +1701,14 @@ void InstructionSelection::visitCJump(V4IR::CJump *s)
testBoolean.link(_as);
}
- Assembler::Jump target = _as->branch32(Assembler::NotEqual, reg, Assembler::TrustedImm32(0));
- _as->addPatch(s->iftrue, target);
- _as->jumpToBlock(_block, s->iffalse);
+ _as->generateCJumpOnNonZero(reg, _block, s->iftrue, s->iffalse);
return;
} else if (V4IR::Const *c = s->cond->asConst()) {
// TODO: SSA optimization for constant condition evaluation should remove this.
// See also visitCJump() in RegAllocInfo.
generateFunctionCall(Assembler::ReturnValueRegister, __qmljs_to_boolean,
Assembler::PointerToValue(c));
- Assembler::Jump target = _as->branch32(Assembler::NotEqual, Assembler::ReturnValueRegister,
- Assembler::TrustedImm32(0));
- _as->addPatch(s->iftrue, target);
- _as->jumpToBlock(_block, s->iffalse);
+ _as->generateCJumpOnNonZero(Assembler::ReturnValueRegister, _block, s->iftrue, s->iffalse);
return;
} else if (V4IR::Binop *b = s->cond->asBinop()) {
if (b->left->type == V4IR::DoubleType && b->right->type == V4IR::DoubleType
@@ -1739,10 +1747,7 @@ void InstructionSelection::visitCJump(V4IR::CJump *s)
Assembler::PointerToValue(b->left),
Assembler::PointerToValue(b->right));
- Assembler::Jump target = _as->branch32(Assembler::NotEqual, Assembler::ReturnValueRegister,
- Assembler::TrustedImm32(0));
- _as->addPatch(s->iftrue, target);
- _as->jumpToBlock(_block, s->iffalse);
+ _as->generateCJumpOnNonZero(Assembler::ReturnValueRegister, _block, s->iftrue, s->iffalse);
return;
}
Q_UNREACHABLE();
@@ -2045,7 +2050,7 @@ void InstructionSelection::doubleBinop(V4IR::AluOp oper, V4IR::Expr *leftSource,
break;
default: {
Q_ASSERT(target->type == V4IR::BoolType);
- Assembler::Jump trueCase = branchDouble(oper, leftSource, rightSource);
+ Assembler::Jump trueCase = branchDouble(false, oper, leftSource, rightSource);
_as->storeBool(false, target);
Assembler::Jump done = _as->jump();
trueCase.link(_as);
@@ -2058,8 +2063,8 @@ void InstructionSelection::doubleBinop(V4IR::AluOp oper, V4IR::Expr *leftSource,
_as->storeDouble(Assembler::FPGpr0, target);
}
-Assembler::Jump InstructionSelection::branchDouble(V4IR::AluOp op, V4IR::Expr *left,
- V4IR::Expr *right)
+Assembler::Jump InstructionSelection::branchDouble(bool invertCondition, V4IR::AluOp op,
+ V4IR::Expr *left, V4IR::Expr *right)
{
Q_ASSERT(isPregOrConst(left));
Q_ASSERT(isPregOrConst(right));
@@ -2078,6 +2083,9 @@ Assembler::Jump InstructionSelection::branchDouble(V4IR::AluOp op, V4IR::Expr *l
default:
Q_UNREACHABLE();
}
+ if (invertCondition)
+ cond = JSC::MacroAssembler::invert(cond);
+
return _as->branchDouble(cond, _as->toDoubleRegister(left), _as->toDoubleRegister(right));
}
@@ -2087,9 +2095,14 @@ bool InstructionSelection::visitCJumpDouble(V4IR::AluOp op, V4IR::Expr *left, V4
if (!isPregOrConst(left) || !isPregOrConst(right))
return false;
- Assembler::Jump target = branchDouble(op, left, right);
- _as->addPatch(iftrue, target);
- _as->jumpToBlock(_block, iffalse);
+ if (_as->nextBlock() == iftrue) {
+ Assembler::Jump target = branchDouble(true, op, left, right);
+ _as->addPatch(iffalse, target);
+ } else {
+ Assembler::Jump target = branchDouble(false, op, left, right);
+ _as->addPatch(iftrue, target);
+ _as->jumpToBlock(_block, iffalse);
+ }
return true;
}
diff --git a/src/qml/compiler/qv4isel_masm_p.h b/src/qml/compiler/qv4isel_masm_p.h
index a689cdf63e..8235e6e62c 100644
--- a/src/qml/compiler/qv4isel_masm_p.h
+++ b/src/qml/compiler/qv4isel_masm_p.h
@@ -446,10 +446,13 @@ public:
}
void registerBlock(V4IR::BasicBlock*, V4IR::BasicBlock *nextBlock);
+ V4IR::BasicBlock *nextBlock() const { return _nextBlock; }
void jumpToBlock(V4IR::BasicBlock* current, V4IR::BasicBlock *target);
void addPatch(V4IR::BasicBlock* targetBlock, Jump targetJump);
void addPatch(DataLabelPtr patch, Label target);
void addPatch(DataLabelPtr patch, V4IR::BasicBlock *target);
+ void generateCJumpOnNonZero(RegisterID reg, V4IR::BasicBlock *currentBlock,
+ V4IR::BasicBlock *trueBlock, V4IR::BasicBlock *falseBlock);
Pointer loadTempAddress(RegisterID reg, V4IR::Temp *t);
Pointer loadStringAddress(RegisterID reg, const QString &string);
@@ -1441,7 +1444,7 @@ protected:
V4IR::Expr *rightSource, V4IR::Temp *target);
void doubleBinop(V4IR::AluOp oper, V4IR::Expr *leftSource, V4IR::Expr *rightSource,
V4IR::Temp *target);
- Assembler::Jump branchDouble(V4IR::AluOp op, V4IR::Expr *left, V4IR::Expr *right);
+ Assembler::Jump branchDouble(bool invertCondition, V4IR::AluOp op, V4IR::Expr *left, V4IR::Expr *right);
bool visitCJumpDouble(V4IR::AluOp op, V4IR::Expr *left, V4IR::Expr *right,
V4IR::BasicBlock *iftrue, V4IR::BasicBlock *iffalse);
bool int32Binop(V4IR::AluOp oper, V4IR::Expr *leftSource, V4IR::Expr *rightSource,
diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp
index af914c79e7..4bea6322e6 100644
--- a/src/qml/compiler/qv4isel_moth.cpp
+++ b/src/qml/compiler/qv4isel_moth.cpp
@@ -651,14 +651,22 @@ void InstructionSelection::visitCJump(V4IR::CJump *s)
Instruction::CJump jump;
jump.offset = 0;
jump.condition = condition;
- ptrdiff_t trueLoc = addInstruction(jump) + (((const char *)&jump.offset) - ((const char *)&jump));
- _patches[s->iftrue].append(trueLoc);
- if (s->iffalse != _nextBlock) {
- Instruction::Jump jump;
- jump.offset = 0;
+ if (s->iftrue == _nextBlock) {
+ jump.invert = true;
ptrdiff_t falseLoc = addInstruction(jump) + (((const char *)&jump.offset) - ((const char *)&jump));
_patches[s->iffalse].append(falseLoc);
+ } else {
+ jump.invert = false;
+ ptrdiff_t trueLoc = addInstruction(jump) + (((const char *)&jump.offset) - ((const char *)&jump));
+ _patches[s->iftrue].append(trueLoc);
+
+ if (s->iffalse != _nextBlock) {
+ Instruction::Jump jump;
+ jump.offset = 0;
+ ptrdiff_t falseLoc = addInstruction(jump) + (((const char *)&jump.offset) - ((const char *)&jump));
+ _patches[s->iffalse].append(falseLoc);
+ }
}
}
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index e933376a13..0807e6bad8 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -506,6 +506,8 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *&code,
MOTH_BEGIN_INSTR(CJump)
uint cond = __qmljs_to_boolean(VALUEPTR(instr.condition));
TRACE(condition, "%s", cond ? "TRUE" : "FALSE");
+ if (instr.invert)
+ cond = !cond;
if (cond)
code = ((uchar *)&instr.offset) + instr.offset;
MOTH_END_INSTR(CJump)