V4: invert conditions when the true block follows the test.
Change-Id: I5044acd4263b71734e4eb5d7e74b1a4a8414741e Reviewed-by: Lars Knoll <lars.knoll@digia.com>
This commit is contained in:
parent
c860d1399b
commit
f9305f9ffa
|
@ -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)
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -438,6 +438,7 @@ union Instr
|
|||
MOTH_INSTR_HEADER
|
||||
ptrdiff_t offset;
|
||||
Param condition;
|
||||
bool invert;
|
||||
};
|
||||
struct instr_unop {
|
||||
MOTH_INSTR_HEADER
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue