mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-27 12:15:33 +00:00
Bug 1434717: Part 5: Connect UnaryArith IC to IonMonkey r=tcampbell
--HG-- extra : rebase_source : e5d3bf65d98899e4cb101e210c51aa4b2a11071e
This commit is contained in:
parent
bab333ec1a
commit
d9eed90b0e
@ -1,7 +1,14 @@
|
||||
function warmup(fun, input, output) {
|
||||
for (var i = 0; i < 30; i++) {
|
||||
var y = fun(input);
|
||||
assertEq(y, output)
|
||||
setJitCompilerOption('ion.forceinlineCaches', 1);
|
||||
|
||||
function warmup(fun, input_array, output_array) {
|
||||
assertEq(output_array.length, input_array.length);
|
||||
for (var index = 0; index < input_array.length; index++) {
|
||||
input = input_array[index];
|
||||
output = output_array[index];
|
||||
for (var i = 0; i < 30; i++) {
|
||||
var y = fun(input);
|
||||
assertEq(y, output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,13 +18,12 @@ var fun2 = (x) => { return -x; }
|
||||
var fun3 = (x) => { return ~x; }
|
||||
var fun4 = (x) => { return ~x; }
|
||||
|
||||
warmup(fun1, 1, -1);
|
||||
warmup(fun1, 0, -0);
|
||||
warmup(fun1, [1, 2], [-1, -2]);
|
||||
warmup(fun2, [0], [-0]);
|
||||
|
||||
warmup(fun2, 3, -3);
|
||||
warmup(fun2, 1.2, -1.2);
|
||||
warmup(fun2, [3, 4], [-3, -4]);
|
||||
warmup(fun1, [1.2, 1.4], [-1.2, -1.4]);
|
||||
|
||||
warmup(fun3, -1, 0);
|
||||
warmup(fun4, 1.2, -2);
|
||||
warmup(fun4, 3, -4)
|
||||
warmup(fun3, [-1, 0], [0, -1]);
|
||||
warmup(fun4, [-1.0, 0.0, 1.2, 3], [0, -1, -2, -4]);
|
||||
|
||||
|
@ -175,12 +175,16 @@ typedef bool (*IonInICFn)(JSContext*, HandleScript, IonInIC*, HandleValue, Handl
|
||||
static const VMFunction IonInICInfo =
|
||||
FunctionInfo<IonInICFn>(IonInIC::update, "IonInIC::update");
|
||||
|
||||
|
||||
typedef bool (*IonInstanceOfICFn)(JSContext*, HandleScript, IonInstanceOfIC*,
|
||||
HandleValue lhs, HandleObject rhs, bool* res);
|
||||
static const VMFunction IonInstanceOfInfo =
|
||||
FunctionInfo<IonInstanceOfICFn>(IonInstanceOfIC::update, "IonInstanceOfIC::update");
|
||||
|
||||
typedef bool (*IonUnaryArithICFn)(JSContext* cx, HandleScript outerScript, IonUnaryArithIC* stub,
|
||||
HandleValue val, MutableHandleValue res);
|
||||
static const VMFunction IonUnaryArithICInfo =
|
||||
FunctionInfo<IonUnaryArithICFn>(IonUnaryArithIC::update, "IonUnaryArithIC::update");
|
||||
|
||||
void
|
||||
CodeGenerator::visitOutOfLineICFallback(OutOfLineICFallback* ool)
|
||||
{
|
||||
@ -357,7 +361,22 @@ CodeGenerator::visitOutOfLineICFallback(OutOfLineICFallback* ool)
|
||||
masm.jump(ool->rejoin());
|
||||
return;
|
||||
}
|
||||
case CacheKind::UnaryArith:
|
||||
case CacheKind::UnaryArith: {
|
||||
IonUnaryArithIC* unaryArithIC = ic->asUnaryArithIC();
|
||||
|
||||
saveLive(lir);
|
||||
|
||||
pushArg(unaryArithIC->input());
|
||||
icInfo_[cacheInfoIndex].icOffsetForPush = pushArgWithPatch(ImmWord(-1));
|
||||
pushArg(ImmGCPtr(gen->info().script()));
|
||||
callVM(IonUnaryArithICInfo, lir);
|
||||
|
||||
StoreValueTo(unaryArithIC->output()).generate(this);
|
||||
restoreLiveIgnore(lir, StoreValueTo(unaryArithIC->output()).clobbered());
|
||||
|
||||
masm.jump(ool->rejoin());
|
||||
return;
|
||||
}
|
||||
case CacheKind::Call:
|
||||
case CacheKind::Compare:
|
||||
case CacheKind::TypeOf:
|
||||
@ -2760,6 +2779,16 @@ CodeGenerator::visitBinarySharedStub(LBinarySharedStub* lir)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CodeGenerator::visitUnaryCache(LUnaryCache* lir)
|
||||
{
|
||||
LiveRegisterSet liveRegs = lir->safepoint()->liveRegs();
|
||||
TypedOrValueRegister input = TypedOrValueRegister(ToValue(lir, LUnaryCache::Input));
|
||||
ValueOperand output = ToOutValue(lir);
|
||||
|
||||
IonUnaryArithIC ic(liveRegs, input, output);
|
||||
addIC(lir, allocateIC(ic));
|
||||
}
|
||||
|
||||
void
|
||||
CodeGenerator::visitNullarySharedStub(LNullarySharedStub* lir)
|
||||
|
@ -3271,6 +3271,10 @@ IonBuilder::jsop_bitnot()
|
||||
return Ok();
|
||||
}
|
||||
|
||||
MOZ_TRY(arithTrySharedStub(&emitted, JSOP_BITNOT, nullptr, input));
|
||||
if (emitted)
|
||||
return Ok();
|
||||
|
||||
// Not possible to optimize. Do a slow vm call.
|
||||
MBitNot* ins = MBitNot::New(alloc(), input);
|
||||
|
||||
@ -3533,12 +3537,16 @@ IonBuilder::arithTrySharedStub(bool* emitted, JSOp op,
|
||||
if (actualOp == JSOP_POS)
|
||||
return Ok();
|
||||
|
||||
// JSOP_NEG and JSOP_BITNOT can't be handled here right now.
|
||||
if (actualOp == JSOP_NEG || actualOp == JSOP_BITNOT)
|
||||
return Ok();
|
||||
|
||||
MInstruction* stub = nullptr;
|
||||
switch (actualOp) {
|
||||
case JSOP_NEG:
|
||||
case JSOP_BITNOT:
|
||||
MOZ_ASSERT_IF(op == JSOP_MUL,
|
||||
left->maybeConstantValue() && left->maybeConstantValue()->toInt32() == -1);
|
||||
MOZ_ASSERT_IF(op != JSOP_MUL, !left);
|
||||
stub = MUnaryCache::New(alloc(), right);
|
||||
break;
|
||||
case JSOP_ADD:
|
||||
case JSOP_SUB:
|
||||
case JSOP_MUL:
|
||||
|
@ -544,12 +544,24 @@ IonCacheIRCompiler::init()
|
||||
AnyRegister(ic->rhs())));
|
||||
break;
|
||||
}
|
||||
case CacheKind::UnaryArith: {
|
||||
IonUnaryArithIC *ic = ic_->asUnaryArithIC();
|
||||
ValueOperand output = ic->output();
|
||||
|
||||
available.add(output);
|
||||
|
||||
liveRegs_.emplace(ic->liveRegs());
|
||||
outputUnchecked_.emplace(TypedOrValueRegister(output));
|
||||
|
||||
MOZ_ASSERT(numInputs == 1);
|
||||
allocator.initInputLocation(0, ic->input());
|
||||
break;
|
||||
}
|
||||
case CacheKind::Call:
|
||||
case CacheKind::Compare:
|
||||
case CacheKind::TypeOf:
|
||||
case CacheKind::ToBool:
|
||||
case CacheKind::GetIntrinsic:
|
||||
case CacheKind::UnaryArith:
|
||||
MOZ_CRASH("Unsupported IC");
|
||||
}
|
||||
|
||||
|
@ -56,12 +56,13 @@ IonIC::scratchRegisterForEntryJump()
|
||||
return asGetIteratorIC()->temp1();
|
||||
case CacheKind::InstanceOf:
|
||||
return asInstanceOfIC()->output();
|
||||
case CacheKind::UnaryArith:
|
||||
return asUnaryArithIC()->output().scratchReg();
|
||||
case CacheKind::Call:
|
||||
case CacheKind::Compare:
|
||||
case CacheKind::TypeOf:
|
||||
case CacheKind::ToBool:
|
||||
case CacheKind::GetIntrinsic:
|
||||
case CacheKind::UnaryArith:
|
||||
MOZ_CRASH("Unsupported IC");
|
||||
}
|
||||
|
||||
@ -502,6 +503,48 @@ IonInstanceOfIC::update(JSContext* cx, HandleScript outerScript, IonInstanceOfIC
|
||||
return HasInstance(cx, rhs, lhs, res);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
IonUnaryArithIC::update(JSContext* cx, HandleScript outerScript, IonUnaryArithIC* ic,
|
||||
HandleValue val, MutableHandleValue res)
|
||||
{
|
||||
IonScript* ionScript = outerScript->ionScript();
|
||||
RootedScript script(cx, ic->script());
|
||||
jsbytecode* pc = ic->pc();
|
||||
JSOp op = JSOp(*pc);
|
||||
|
||||
switch (op) {
|
||||
case JSOP_BITNOT: {
|
||||
int32_t result;
|
||||
if (!BitNot(cx, val, &result))
|
||||
return false;
|
||||
res.setInt32(result);
|
||||
break;
|
||||
}
|
||||
case JSOP_NEG:
|
||||
if (!NegOperation(cx, val, res))
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Unexpected op");
|
||||
}
|
||||
|
||||
if (ic->state().maybeTransition())
|
||||
ic->discardStubs(cx->zone());
|
||||
|
||||
if (ic->state().canAttachStub()) {
|
||||
bool attached = false;
|
||||
UnaryArithIRGenerator gen(cx, script, pc, ic->state().mode(), op, val, res);
|
||||
|
||||
if (gen.tryAttachStub())
|
||||
ic->attachCacheIRStub(cx, gen.writerRef(), gen.cacheKind(), ionScript, &attached);
|
||||
|
||||
if (!attached)
|
||||
ic->state().trackNotAttached();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t*
|
||||
IonICStub::stubDataStart()
|
||||
{
|
||||
|
@ -65,6 +65,7 @@ class IonGetIteratorIC;
|
||||
class IonHasOwnIC;
|
||||
class IonInIC;
|
||||
class IonInstanceOfIC;
|
||||
class IonUnaryArithIC;
|
||||
|
||||
class IonIC
|
||||
{
|
||||
@ -172,6 +173,10 @@ class IonIC
|
||||
MOZ_ASSERT(kind_ == CacheKind::InstanceOf);
|
||||
return (IonInstanceOfIC*)this;
|
||||
}
|
||||
IonUnaryArithIC* asUnaryArithIC() {
|
||||
MOZ_ASSERT(kind_ == CacheKind::UnaryArith);
|
||||
return (IonUnaryArithIC*)this;
|
||||
}
|
||||
|
||||
void updateBaseAddress(JitCode* code);
|
||||
|
||||
@ -475,6 +480,30 @@ class IonInstanceOfIC : public IonIC
|
||||
HandleValue lhs, HandleObject rhs, bool* attached);
|
||||
};
|
||||
|
||||
class IonUnaryArithIC : public IonIC
|
||||
{
|
||||
LiveRegisterSet liveRegs_;
|
||||
|
||||
TypedOrValueRegister input_;
|
||||
ValueOperand output_;
|
||||
|
||||
public:
|
||||
|
||||
IonUnaryArithIC(LiveRegisterSet liveRegs, TypedOrValueRegister input, ValueOperand output)
|
||||
: IonIC(CacheKind::UnaryArith),
|
||||
liveRegs_(liveRegs),
|
||||
input_(input),
|
||||
output_(output)
|
||||
{ }
|
||||
|
||||
LiveRegisterSet liveRegs() const { return liveRegs_; }
|
||||
TypedOrValueRegister input() const { return input_; }
|
||||
ValueOperand output() const { return output_; }
|
||||
|
||||
static MOZ_MUST_USE bool update(JSContext* cx, HandleScript outerScript, IonUnaryArithIC* stub,
|
||||
HandleValue val, MutableHandleValue res);
|
||||
};
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
||||
|
@ -2532,6 +2532,17 @@ LIRGenerator::visitBinarySharedStub(MBinarySharedStub* ins)
|
||||
assignSafepoint(lir, ins);
|
||||
}
|
||||
|
||||
void
|
||||
LIRGenerator::visitUnaryCache(MUnaryCache* ins)
|
||||
{
|
||||
MDefinition* input = ins->getOperand(0);
|
||||
MOZ_ASSERT(ins->type() == MIRType::Value);
|
||||
|
||||
LUnaryCache* lir = new(alloc()) LUnaryCache(useBox(input));
|
||||
defineBox(lir, ins);
|
||||
assignSafepoint(lir, ins);
|
||||
}
|
||||
|
||||
void
|
||||
LIRGenerator::visitNullarySharedStub(MNullarySharedStub* ins)
|
||||
{
|
||||
|
@ -8287,6 +8287,21 @@ class MBinarySharedStub
|
||||
TRIVIAL_NEW_WRAPPERS
|
||||
};
|
||||
|
||||
class MUnaryCache
|
||||
: public MUnaryInstruction,
|
||||
public BoxPolicy<0>::Data
|
||||
{
|
||||
explicit MUnaryCache(MDefinition* input)
|
||||
: MUnaryInstruction(classOpcode, input)
|
||||
{
|
||||
setResultType(MIRType::Value);
|
||||
}
|
||||
|
||||
public:
|
||||
INSTRUCTION_HEADER(UnaryCache)
|
||||
TRIVIAL_NEW_WRAPPERS
|
||||
};
|
||||
|
||||
class MNullarySharedStub
|
||||
: public MNullaryInstruction
|
||||
{
|
||||
|
@ -5541,19 +5541,23 @@ class LBinarySharedStub : public LCallInstructionHelper<BOX_PIECES, 2 * BOX_PIEC
|
||||
static const size_t RhsInput = BOX_PIECES;
|
||||
};
|
||||
|
||||
class LUnarySharedStub : public LCallInstructionHelper<BOX_PIECES, BOX_PIECES, 0>
|
||||
class LUnaryCache : public LInstructionHelper<BOX_PIECES, BOX_PIECES, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(UnarySharedStub)
|
||||
LIR_HEADER(UnaryCache)
|
||||
|
||||
explicit LUnarySharedStub(const LBoxAllocation& input)
|
||||
: LCallInstructionHelper(classOpcode)
|
||||
explicit LUnaryCache(const LBoxAllocation& input)
|
||||
: LInstructionHelper(classOpcode)
|
||||
{
|
||||
setBoxOperand(Input, input);
|
||||
}
|
||||
|
||||
const MUnarySharedStub* mir() const {
|
||||
return mir_->toUnarySharedStub();
|
||||
const MUnaryCache* mir() const {
|
||||
return mir_->toUnaryCache();
|
||||
}
|
||||
|
||||
const LAllocation* input() {
|
||||
return getOperand(Input);
|
||||
}
|
||||
|
||||
static const size_t Input = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user