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:
Lars T Hansen 2016-12-28 07:02:34 +01:00
Родитель cf380f2770
Коммит aa202c40e4
2 изменённых файлов: 60 добавлений и 18 удалений

Просмотреть файл

@ -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