mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 882565 - IonMonkey: Only skip resumepoints during truncation when no uses where removed, r=jandem
This commit is contained in:
parent
369796db84
commit
92908d5e06
@ -324,6 +324,9 @@ MDefinition::replaceAllUsesWith(MDefinition *dom)
|
||||
if (dom == this)
|
||||
return;
|
||||
|
||||
for (size_t i = 0; i < numOperands(); i++)
|
||||
getOperand(i)->setUseRemovedUnchecked();
|
||||
|
||||
for (MUseIterator i(usesBegin()); i != usesEnd(); ) {
|
||||
JS_ASSERT(i->producer() == this);
|
||||
i = i->consumer()->replaceOperand(i, dom);
|
||||
|
@ -54,7 +54,20 @@ MIRType MIRTypeFromValue(const js::Value &vp)
|
||||
* points.
|
||||
*/ \
|
||||
_(Unused) \
|
||||
_(DOMFunction) /* Contains or uses a common DOM method function */
|
||||
_(DOMFunction) /* Contains or uses a common DOM method function */ \
|
||||
\
|
||||
/* Marks if an instruction has fewer uses than the original code.
|
||||
* E.g. UCE can remove code.
|
||||
* Every instruction where an use is/was removed from an instruction and
|
||||
* as a result the number of operands doesn't equal the original code
|
||||
* need to get marked as UseRemoved. This is important for truncation
|
||||
* analysis to know, since if all original uses are still present,
|
||||
* it can ignore resumepoints.
|
||||
* Currently this is done for every pass after IonBuilder and before
|
||||
* Truncate Doubles. So every time removeUse is called, UseRemoved needs
|
||||
* to get set.
|
||||
*/ \
|
||||
_(UseRemoved)
|
||||
|
||||
class MDefinition;
|
||||
class MInstruction;
|
||||
|
@ -1403,13 +1403,21 @@ MToDouble::isOperandTruncated(size_t index) const
|
||||
return type() == MIRType_Int32;
|
||||
}
|
||||
|
||||
// Ensure that all observables (non-resume point) uses can work with a truncated
|
||||
// Ensure that all observables uses can work with a truncated
|
||||
// version of the |candidate|'s result.
|
||||
static bool
|
||||
AllUsesTruncate(MInstruction *candidate)
|
||||
{
|
||||
for (MUseDefIterator use(candidate); use; use++) {
|
||||
if (!use.def()->isOperandTruncated(use.index()))
|
||||
for (MUseIterator use(candidate->usesBegin()); use != candidate->usesEnd(); use++) {
|
||||
if (!use->consumer()->isDefinition()) {
|
||||
// We can only skip testing resume points, if all original uses are still present.
|
||||
// Only than testing all uses is enough to guarantee the truncation isn't observerable.
|
||||
if (candidate->isUseRemoved())
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!use->consumer()->toDefinition()->isOperandTruncated(use->index()))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -157,10 +157,12 @@ UnreachableCodeElimination::checkDependencyAndRemoveUsesFromUnmarkedBlocks(MDefi
|
||||
rerunAliasAnalysis_ = true;
|
||||
|
||||
for (MUseIterator iter(instr->usesBegin()); iter != instr->usesEnd(); ) {
|
||||
if (!iter->consumer()->block()->isMarked())
|
||||
if (!iter->consumer()->block()->isMarked()) {
|
||||
instr->setUseRemovedUnchecked();
|
||||
iter = instr->removeUse(iter);
|
||||
else
|
||||
} else {
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -235,10 +237,10 @@ UnreachableCodeElimination::removeUnmarkedBlocksAndClearDominators()
|
||||
}
|
||||
}
|
||||
|
||||
// When we remove a call, we can't leave the corresponding MPassArg in the graph.
|
||||
// Since lowering will fail. Replace it with the argument for the exceptional
|
||||
// case when it is kept alive in a ResumePoint.
|
||||
// DCE will remove the unused MPassArg instruction.
|
||||
// When we remove a call, we can't leave the corresponding MPassArg
|
||||
// in the graph. Since lowering will fail. Replace it with the
|
||||
// argument for the exceptional case when it is kept alive in a
|
||||
// ResumePoint. DCE will remove the unused MPassArg instruction.
|
||||
for (MInstructionIterator iter(block->begin()); iter != block->end(); iter++) {
|
||||
if (iter->isCall()) {
|
||||
MCall *call = iter->toCall();
|
||||
|
21
js/src/jit-test/tests/ion/bug882565-1.js
Normal file
21
js/src/jit-test/tests/ion/bug882565-1.js
Normal file
@ -0,0 +1,21 @@
|
||||
function zero() { return 0; }
|
||||
function f(x, a) {
|
||||
var test = 0x7fffffff;
|
||||
|
||||
for (var i=0; i<100; i++)
|
||||
{
|
||||
if (i == 0) {
|
||||
test += 1;
|
||||
var t = (test > zero()) * (0xffffffff >>> x);
|
||||
}
|
||||
var test2 = test | 0;
|
||||
return [test2,t];
|
||||
}
|
||||
}
|
||||
var t = f(0, "");
|
||||
assertEq(t[0], 0x80000000 | 0);
|
||||
assertEq(t[1], 0xffffffff >>> 0);
|
||||
|
||||
var t = f(0);
|
||||
assertEq(t[0], 0x80000000 | 0);
|
||||
assertEq(t[1], 0xffffffff >>> 0);
|
4
js/src/jit-test/tests/ion/bug882565.js
Normal file
4
js/src/jit-test/tests/ion/bug882565.js
Normal file
@ -0,0 +1,4 @@
|
||||
function zero() { return 0; }
|
||||
function f(x) { return (0xffffffff > zero()) * (0xffffffff >>> x); }
|
||||
assertEq(f(0), 4294967295);
|
||||
assertEq(f(0), 4294967295);
|
Loading…
Reference in New Issue
Block a user