зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1322288 - wasm baseline, reserve float join registers in optimized control flow. r=bbouvier
--HG-- extra : rebase_source : ae975c2f2f8c43e8ab6c9bcd8f1b2ed842e914cd extra : histedit_source : 341d5a7f71ed930962de720b8edcfc7edbe10a01%2Ccd0d719e459d11aaf7a70fe7c98835fb5a9d8e54
This commit is contained in:
Родитель
cf380f2770
Коммит
aa202c40e4
|
@ -0,0 +1,18 @@
|
|||
load(libdir + "wasm.js");
|
||||
|
||||
// Bug 1322288 is about the floating join register not being reserved properly
|
||||
// in the presence of boolean evaluation for control. The situation is that a
|
||||
// conditional branch passes a floating point value to the join point; the join register
|
||||
// must be available when it does that, but could have been allocated to the operands of
|
||||
// the conditional expression of the control flow.
|
||||
//
|
||||
// This test is white-box: it depends on the floating join reg being among the first
|
||||
// floating registers to be allocated.
|
||||
|
||||
wasmEvalText(`
|
||||
(module
|
||||
(func $run
|
||||
(drop (block f64
|
||||
(drop (br_if 0 (f64.const 1) (f64.eq (f64.const 1) (f64.const 0))))
|
||||
(drop (br 0 (f64.const 2))))))
|
||||
(export "run" $run))`);
|
|
@ -1834,18 +1834,42 @@ class BaseCompiler
|
|||
freeI64(joinRegI64);
|
||||
}
|
||||
|
||||
RegI32 popI32NotJoinReg(ExprType type) {
|
||||
maybeReserveJoinRegI(type);
|
||||
RegI32 r = popI32();
|
||||
maybeUnreserveJoinRegI(type);
|
||||
return r;
|
||||
void maybeReserveJoinReg(ExprType type) {
|
||||
switch (type) {
|
||||
case ExprType::I32:
|
||||
needI32(joinRegI32);
|
||||
break;
|
||||
case ExprType::I64:
|
||||
needI64(joinRegI64);
|
||||
break;
|
||||
case ExprType::F32:
|
||||
needF32(joinRegF32);
|
||||
break;
|
||||
case ExprType::F64:
|
||||
needF64(joinRegF64);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RegI64 popI64NotJoinReg(ExprType type) {
|
||||
maybeReserveJoinRegI(type);
|
||||
RegI64 r = popI64();
|
||||
maybeUnreserveJoinRegI(type);
|
||||
return r;
|
||||
void maybeUnreserveJoinReg(ExprType type) {
|
||||
switch (type) {
|
||||
case ExprType::I32:
|
||||
freeI32(joinRegI32);
|
||||
break;
|
||||
case ExprType::I64:
|
||||
freeI64(joinRegI64);
|
||||
break;
|
||||
case ExprType::F32:
|
||||
freeF32(joinRegF32);
|
||||
break;
|
||||
case ExprType::F64:
|
||||
freeF64(joinRegF64);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the amount of execution stack consumed by the top numval
|
||||
|
@ -5177,12 +5201,14 @@ BaseCompiler::sniffConditionalControlEqz(ValType operandType)
|
|||
void
|
||||
BaseCompiler::emitBranchSetup(BranchState* b)
|
||||
{
|
||||
maybeReserveJoinReg(b->resultType);
|
||||
|
||||
// Set up fields so that emitBranchPerform() need not switch on latentOp_.
|
||||
switch (latentOp_) {
|
||||
case LatentOp::None: {
|
||||
latentIntCmp_ = Assembler::NotEqual;
|
||||
latentType_ = ValType::I32;
|
||||
b->i32.lhs = popI32NotJoinReg(b->resultType);
|
||||
b->i32.lhs = popI32();
|
||||
b->i32.rhsImm = true;
|
||||
b->i32.imm = 0;
|
||||
break;
|
||||
|
@ -5191,20 +5217,16 @@ BaseCompiler::emitBranchSetup(BranchState* b)
|
|||
switch (latentType_) {
|
||||
case ValType::I32: {
|
||||
if (popConstI32(b->i32.imm)) {
|
||||
b->i32.lhs = popI32NotJoinReg(b->resultType);
|
||||
b->i32.lhs = popI32();
|
||||
b->i32.rhsImm = true;
|
||||
} else {
|
||||
maybeReserveJoinRegI(b->resultType);
|
||||
pop2xI32(&b->i32.lhs, &b->i32.rhs);
|
||||
maybeUnreserveJoinRegI(b->resultType);
|
||||
b->i32.rhsImm = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ValType::I64: {
|
||||
maybeReserveJoinRegI(b->resultType);
|
||||
pop2xI64(&b->i64.lhs, &b->i64.rhs);
|
||||
maybeUnreserveJoinRegI(b->resultType);
|
||||
b->i64.rhsImm = false;
|
||||
break;
|
||||
}
|
||||
|
@ -5226,14 +5248,14 @@ BaseCompiler::emitBranchSetup(BranchState* b)
|
|||
switch (latentType_) {
|
||||
case ValType::I32: {
|
||||
latentIntCmp_ = Assembler::Equal;
|
||||
b->i32.lhs = popI32NotJoinReg(b->resultType);
|
||||
b->i32.lhs = popI32();
|
||||
b->i32.rhsImm = true;
|
||||
b->i32.imm = 0;
|
||||
break;
|
||||
}
|
||||
case ValType::I64: {
|
||||
latentIntCmp_ = Assembler::Equal;
|
||||
b->i64.lhs = popI64NotJoinReg(b->resultType);
|
||||
b->i64.lhs = popI64();
|
||||
b->i64.rhsImm = true;
|
||||
b->i64.imm = 0;
|
||||
break;
|
||||
|
@ -5245,6 +5267,8 @@ BaseCompiler::emitBranchSetup(BranchState* b)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
maybeUnreserveJoinReg(b->resultType);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Загрузка…
Ссылка в новой задаче