Bug 953256 - IonMonkey: Rename Folded MIR flag to ImplictlyUsed. r=jandem

This commit is contained in:
Nicolas Pierron 2014-01-07 05:56:21 -08:00
parent 40790e8807
commit f7cf973b9a
7 changed files with 91 additions and 86 deletions

View File

@ -97,7 +97,7 @@ jit::EliminateDeadResumePointOperands(MIRGenerator *mir, MIRGraph &graph)
// If the instruction's behavior has been constant folded into a // If the instruction's behavior has been constant folded into a
// separate instruction, we can't determine precisely where the // separate instruction, we can't determine precisely where the
// instruction becomes dead and can't eliminate its uses. // instruction becomes dead and can't eliminate its uses.
if (ins->isFolded()) if (ins->isImplicitlyUsed())
continue; continue;
// Check if this instruction's result is only used within the // Check if this instruction's result is only used within the
@ -186,7 +186,7 @@ IsPhiObservable(MPhi *phi, Observability observe)
{ {
// If the phi has uses which are not reflected in SSA, then behavior in the // If the phi has uses which are not reflected in SSA, then behavior in the
// interpreter may be affected by removing the phi. // interpreter may be affected by removing the phi.
if (phi->isFolded()) if (phi->isImplicitlyUsed())
return true; return true;
// Check for uses of this phi node outside of other phi nodes. // Check for uses of this phi node outside of other phi nodes.
@ -253,9 +253,9 @@ IsPhiRedundant(MPhi *phi)
if (first == nullptr) if (first == nullptr)
return nullptr; return nullptr;
// Propagate the Folded flag if |phi| is replaced with another phi. // Propagate the ImplicitlyUsed flag if |phi| is replaced with another phi.
if (phi->isFolded()) if (phi->isImplicitlyUsed())
first->setFoldedUnchecked(); first->setImplicitlyUsedUnchecked();
return first; return first;
} }

View File

@ -755,7 +755,7 @@ IonBuilder::processIterators()
while (!worklist.empty()) { while (!worklist.empty()) {
MPhi *phi = worklist.popCopy(); MPhi *phi = worklist.popCopy();
phi->setIterator(); phi->setIterator();
phi->setFoldedUnchecked(); phi->setImplicitlyUsedUnchecked();
for (MUseDefIterator iter(phi); iter; iter++) { for (MUseDefIterator iter(phi); iter; iter++) {
if (iter.def()->isPhi()) { if (iter.def()->isPhi()) {
@ -1270,12 +1270,12 @@ IonBuilder::traverseBytecode()
// In debug builds, after compiling this op, check that all values // In debug builds, after compiling this op, check that all values
// popped by this opcode either: // popped by this opcode either:
// //
// (1) Have the Folded flag set on them. // (1) Have the ImplicitlyUsed flag set on them.
// (2) Have more uses than before compiling this op (the value is // (2) Have more uses than before compiling this op (the value is
// used as operand of a new MIR instruction). // used as operand of a new MIR instruction).
// //
// This is used to catch problems where IonBuilder pops a value without // This is used to catch problems where IonBuilder pops a value without
// adding any SSA uses and doesn't call setFoldedUnchecked on it. // adding any SSA uses and doesn't call setImplicitlyUsedUnchecked on it.
Vector<MDefinition *, 4, IonAllocPolicy> popped(alloc()); Vector<MDefinition *, 4, IonAllocPolicy> popped(alloc());
Vector<size_t, 4, IonAllocPolicy> poppedUses(alloc()); Vector<size_t, 4, IonAllocPolicy> poppedUses(alloc());
unsigned nuses = GetUseCount(script_, script_->pcToOffset(pc)); unsigned nuses = GetUseCount(script_, script_->pcToOffset(pc));
@ -1318,7 +1318,7 @@ IonBuilder::traverseBytecode()
case JSOP_POS: case JSOP_POS:
case JSOP_TOID: case JSOP_TOID:
// These ops may leave their input on the stack without setting // These ops may leave their input on the stack without setting
// the Folded flag. If this value will be popped immediately, // the ImplicitlyUsed flag. If this value will be popped immediately,
// we may replace it with |undefined|, but the difference is // we may replace it with |undefined|, but the difference is
// not observable. // not observable.
JS_ASSERT(i == 0); JS_ASSERT(i == 0);
@ -1327,7 +1327,7 @@ IonBuilder::traverseBytecode()
// FALL THROUGH // FALL THROUGH
default: default:
JS_ASSERT(popped[i]->isFolded() || JS_ASSERT(popped[i]->isImplicitlyUsed() ||
// MNewDerivedTypedObject instances are // MNewDerivedTypedObject instances are
// often dead unless they escape from the // often dead unless they escape from the
@ -3833,7 +3833,7 @@ IonBuilder::inlineScriptedCall(CallInfo &callInfo, JSFunction *target)
JS_ASSERT(target->isInterpreted()); JS_ASSERT(target->isInterpreted());
JS_ASSERT(IsIonInlinablePC(pc)); JS_ASSERT(IsIonInlinablePC(pc));
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
// Ensure sufficient space in the slots: needed for inlining from FUNAPPLY. // Ensure sufficient space in the slots: needed for inlining from FUNAPPLY.
uint32_t depth = current->stackDepth() + callInfo.numFormals(); uint32_t depth = current->stackDepth() + callInfo.numFormals();
@ -4218,8 +4218,8 @@ IonBuilder::inlineCallsite(ObjectVector &targets, ObjectVector &originals,
// Inlining will elminate uses of the original callee, but it needs to // Inlining will elminate uses of the original callee, but it needs to
// be preserved in phis if we bail out. Mark the old callee definition as // be preserved in phis if we bail out. Mark the old callee definition as
// folded to ensure this happens. // implicitly used to ensure this happens.
callInfo.fun()->setFoldedUnchecked(); callInfo.fun()->setImplicitlyUsedUnchecked();
// If the callee is not going to be a lambda (which may vary across // If the callee is not going to be a lambda (which may vary across
// different invocations), then the callee definition can be replaced by a // different invocations), then the callee definition can be replaced by a
@ -4380,7 +4380,7 @@ IonBuilder::inlineCalls(CallInfo &callInfo, ObjectVector &targets,
JS_ASSERT_IF(maybeCache, targets.length() >= 1); JS_ASSERT_IF(maybeCache, targets.length() >= 1);
MBasicBlock *dispatchBlock = current; MBasicBlock *dispatchBlock = current;
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
callInfo.pushFormals(dispatchBlock); callInfo.pushFormals(dispatchBlock);
// Patch any InlinePropertyTable to only contain functions that are inlineable. // Patch any InlinePropertyTable to only contain functions that are inlineable.
@ -4402,7 +4402,7 @@ IonBuilder::inlineCalls(CallInfo &callInfo, ObjectVector &targets,
MDispatchInstruction *dispatch; MDispatchInstruction *dispatch;
if (maybeCache) { if (maybeCache) {
dispatch = MTypeObjectDispatch::New(alloc(), maybeCache->object(), maybeCache->propTable()); dispatch = MTypeObjectDispatch::New(alloc(), maybeCache->object(), maybeCache->propTable());
callInfo.fun()->setFoldedUnchecked(); callInfo.fun()->setImplicitlyUsedUnchecked();
} else { } else {
dispatch = MFunctionDispatch::New(alloc(), callInfo.fun()); dispatch = MFunctionDispatch::New(alloc(), callInfo.fun());
} }
@ -4465,7 +4465,7 @@ IonBuilder::inlineCalls(CallInfo &callInfo, ObjectVector &targets,
// Create a function MConstant to use in the entry ResumePoint. // Create a function MConstant to use in the entry ResumePoint.
MConstant *funcDef = MConstant::New(alloc(), ObjectValue(*target), constraints()); MConstant *funcDef = MConstant::New(alloc(), ObjectValue(*target), constraints());
funcDef->setFoldedUnchecked(); funcDef->setImplicitlyUsedUnchecked();
dispatchBlock->add(funcDef); dispatchBlock->add(funcDef);
// Use the MConstant in the inline resume point and on stack. // Use the MConstant in the inline resume point and on stack.
@ -4811,7 +4811,7 @@ IonBuilder::jsop_funcall(uint32_t argc)
return false; return false;
return makeCall(native, callInfo, false); return makeCall(native, callInfo, false);
} }
current->peek(calleeDepth)->setFoldedUnchecked(); current->peek(calleeDepth)->setImplicitlyUsedUnchecked();
// Extract call target. // Extract call target.
types::TemporaryTypeSet *funTypes = current->peek(funcDepth)->resultTypeSet(); types::TemporaryTypeSet *funTypes = current->peek(funcDepth)->resultTypeSet();
@ -4893,7 +4893,7 @@ IonBuilder::jsop_funapply(uint32_t argc)
return abort("fun.apply speculation failed"); return abort("fun.apply speculation failed");
} }
current->peek(calleeDepth)->setFoldedUnchecked(); current->peek(calleeDepth)->setImplicitlyUsedUnchecked();
// Use funapply that definitely uses |arguments| // Use funapply that definitely uses |arguments|
return jsop_funapplyarguments(argc); return jsop_funapplyarguments(argc);
@ -4922,7 +4922,7 @@ IonBuilder::jsop_funapplyarguments(uint32_t argc)
// we need to prevent the deletion of the arguments object from resume // we need to prevent the deletion of the arguments object from resume
// points, so that Baseline will behave correctly after a bailout. // points, so that Baseline will behave correctly after a bailout.
MDefinition *vp = current->pop(); MDefinition *vp = current->pop();
vp->setFoldedUnchecked(); vp->setImplicitlyUsedUnchecked();
MDefinition *argThis = current->pop(); MDefinition *argThis = current->pop();
@ -4955,7 +4955,7 @@ IonBuilder::jsop_funapplyarguments(uint32_t argc)
// Vp // Vp
MDefinition *vp = current->pop(); MDefinition *vp = current->pop();
vp->setFoldedUnchecked(); vp->setImplicitlyUsedUnchecked();
// Arguments // Arguments
MDefinitionVector args(alloc()); MDefinitionVector args(alloc());
@ -5065,7 +5065,7 @@ IonBuilder::makeCallsiteClone(JSFunction *target, MDefinition *fun)
// function, which means that target already is the clone. Make sure to ensure // function, which means that target already is the clone. Make sure to ensure
// that the old definition remains in resume points. // that the old definition remains in resume points.
if (target) { if (target) {
fun->setFoldedUnchecked(); fun->setImplicitlyUsedUnchecked();
return constant(ObjectValue(*target)); return constant(ObjectValue(*target));
} }
@ -5213,7 +5213,7 @@ IonBuilder::makeCallHelper(JSFunction *target, CallInfo &callInfo, bool cloneAtC
return nullptr; return nullptr;
} }
callInfo.thisArg()->setFoldedUnchecked(); callInfo.thisArg()->setImplicitlyUsedUnchecked();
callInfo.setThis(create); callInfo.setThis(create);
} }
@ -5311,9 +5311,9 @@ IonBuilder::jsop_eval(uint32_t argc)
CallInfo callInfo(alloc(), /* constructing = */ false); CallInfo callInfo(alloc(), /* constructing = */ false);
if (!callInfo.init(current, argc)) if (!callInfo.init(current, argc))
return false; return false;
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
callInfo.fun()->setFoldedUnchecked(); callInfo.fun()->setImplicitlyUsedUnchecked();
MDefinition *scopeChain = current->scopeChain(); MDefinition *scopeChain = current->scopeChain();
MDefinition *string = callInfo.getArg(0); MDefinition *string = callInfo.getArg(0);
@ -6245,12 +6245,12 @@ IonBuilder::ensureDefiniteType(MDefinition *def, JSValueType definiteType)
MInstruction *replace; MInstruction *replace;
switch (definiteType) { switch (definiteType) {
case JSVAL_TYPE_UNDEFINED: case JSVAL_TYPE_UNDEFINED:
def->setFoldedUnchecked(); def->setImplicitlyUsedUnchecked();
replace = MConstant::New(alloc(), UndefinedValue()); replace = MConstant::New(alloc(), UndefinedValue());
break; break;
case JSVAL_TYPE_NULL: case JSVAL_TYPE_NULL:
def->setFoldedUnchecked(); def->setImplicitlyUsedUnchecked();
replace = MConstant::New(alloc(), NullValue()); replace = MConstant::New(alloc(), NullValue());
break; break;
@ -6821,8 +6821,8 @@ IonBuilder::getElemTryTypedStatic(bool *emitted, MDefinition *obj, MDefinition *
// Emit LoadTypedArrayElementStatic. // Emit LoadTypedArrayElementStatic.
obj->setFoldedUnchecked(); obj->setImplicitlyUsedUnchecked();
index->setFoldedUnchecked(); index->setImplicitlyUsedUnchecked();
MLoadTypedArrayElementStatic *load = MLoadTypedArrayElementStatic::New(alloc(), tarr, ptr); MLoadTypedArrayElementStatic *load = MLoadTypedArrayElementStatic::New(alloc(), tarr, ptr);
current->add(load); current->add(load);
@ -6914,7 +6914,7 @@ IonBuilder::getElemTryArguments(bool *emitted, MDefinition *obj, MDefinition *in
JS_ASSERT(!info().argsObjAliasesFormals()); JS_ASSERT(!info().argsObjAliasesFormals());
// Type Inference has guaranteed this is an optimized arguments object. // Type Inference has guaranteed this is an optimized arguments object.
obj->setFoldedUnchecked(); obj->setImplicitlyUsedUnchecked();
// To ensure that we are not looking above the number of actual arguments. // To ensure that we are not looking above the number of actual arguments.
MArgumentsLength *length = MArgumentsLength::New(alloc()); MArgumentsLength *length = MArgumentsLength::New(alloc());
@ -6953,7 +6953,7 @@ IonBuilder::getElemTryArgumentsInlined(bool *emitted, MDefinition *obj, MDefinit
return true; return true;
// Emit inlined arguments. // Emit inlined arguments.
obj->setFoldedUnchecked(); obj->setImplicitlyUsedUnchecked();
JS_ASSERT(!info().argsObjAliasesFormals()); JS_ASSERT(!info().argsObjAliasesFormals());
@ -6962,7 +6962,7 @@ IonBuilder::getElemTryArgumentsInlined(bool *emitted, MDefinition *obj, MDefinit
JS_ASSERT(inliningDepth_ > 0); JS_ASSERT(inliningDepth_ > 0);
int32_t id = index->toConstant()->value().toInt32(); int32_t id = index->toConstant()->value().toInt32();
index->setFoldedUnchecked(); index->setImplicitlyUsedUnchecked();
if (id < (int32_t)inlineCallInfo_->argc() && id >= 0) if (id < (int32_t)inlineCallInfo_->argc() && id >= 0)
current->push(inlineCallInfo_->getArg(id)); current->push(inlineCallInfo_->getArg(id));
@ -7137,7 +7137,7 @@ IonBuilder::getTypedArrayLength(MDefinition *obj)
if (obj->isConstant() && obj->toConstant()->value().isObject()) { if (obj->isConstant() && obj->toConstant()->value().isObject()) {
TypedArrayObject *tarr = &obj->toConstant()->value().toObject().as<TypedArrayObject>(); TypedArrayObject *tarr = &obj->toConstant()->value().toObject().as<TypedArrayObject>();
int32_t length = (int32_t) tarr->length(); int32_t length = (int32_t) tarr->length();
obj->setFoldedUnchecked(); obj->setImplicitlyUsedUnchecked();
return MConstant::New(alloc(), Int32Value(length)); return MConstant::New(alloc(), Int32Value(length));
} }
return MTypedArrayLength::New(alloc(), obj); return MTypedArrayLength::New(alloc(), obj);
@ -7155,7 +7155,7 @@ IonBuilder::getTypedArrayElements(MDefinition *obj)
types::TypeObjectKey *tarrType = types::TypeObjectKey::get(tarr); types::TypeObjectKey *tarrType = types::TypeObjectKey::get(tarr);
tarrType->watchStateChangeForTypedArrayBuffer(constraints()); tarrType->watchStateChangeForTypedArrayBuffer(constraints());
obj->setFoldedUnchecked(); obj->setImplicitlyUsedUnchecked();
return MConstantElements::New(alloc(), data); return MConstantElements::New(alloc(), data);
} }
return MTypedArrayElements::New(alloc(), obj); return MTypedArrayElements::New(alloc(), obj);
@ -7373,8 +7373,8 @@ IonBuilder::setElemTryTypedStatic(bool *emitted, MDefinition *object,
return true; return true;
// Emit StoreTypedArrayElementStatic. // Emit StoreTypedArrayElementStatic.
object->setFoldedUnchecked(); object->setImplicitlyUsedUnchecked();
index->setFoldedUnchecked(); index->setImplicitlyUsedUnchecked();
// Clamp value to [0, 255] for Uint8ClampedArray. // Clamp value to [0, 255] for Uint8ClampedArray.
MDefinition *toWrite = value; MDefinition *toWrite = value;
@ -7757,7 +7757,7 @@ IonBuilder::jsop_arguments_length()
{ {
// Type Inference has guaranteed this is an optimized arguments object. // Type Inference has guaranteed this is an optimized arguments object.
MDefinition *args = current->pop(); MDefinition *args = current->pop();
args->setFoldedUnchecked(); args->setImplicitlyUsedUnchecked();
// We don't know anything from the callee // We don't know anything from the callee
if (inliningDepth_ == 0) { if (inliningDepth_ == 0) {
@ -8270,7 +8270,7 @@ IonBuilder::getPropTryConstant(bool *emitted, PropertyName *name,
else if (testString) else if (testString)
current->add(MGuardString::New(alloc(), obj)); current->add(MGuardString::New(alloc(), obj));
else else
obj->setFoldedUnchecked(); obj->setImplicitlyUsedUnchecked();
pushConstant(ObjectValue(*singleton)); pushConstant(ObjectValue(*singleton));
@ -9410,7 +9410,7 @@ IonBuilder::hasStaticScopeObject(ScopeCoordinate sc, JSObject **pcall)
// singleton type then it should show up here. // singleton type then it should show up here.
MDefinition *scope = current->getSlot(info().scopeChainSlot()); MDefinition *scope = current->getSlot(info().scopeChainSlot());
scope->setFoldedUnchecked(); scope->setImplicitlyUsedUnchecked();
JSObject *environment = script()->function()->environment(); JSObject *environment = script()->function()->environment();
while (environment && !environment->is<GlobalObject>()) { while (environment && !environment->is<GlobalObject>()) {
@ -9605,7 +9605,7 @@ IonBuilder::jsop_instanceof()
if (!protoObject) if (!protoObject)
break; break;
rhs->setFoldedUnchecked(); rhs->setImplicitlyUsedUnchecked();
MInstanceOf *ins = MInstanceOf::New(alloc(), obj, protoObject); MInstanceOf *ins = MInstanceOf::New(alloc(), obj, protoObject);

View File

@ -961,10 +961,10 @@ class CallInfo
void setFun(MDefinition *fun) { void setFun(MDefinition *fun) {
fun_ = fun; fun_ = fun;
} }
void setFoldedUnchecked() { void setImplicitlyUsedUnchecked() {
thisArg_->setFoldedUnchecked(); thisArg_->setImplicitlyUsedUnchecked();
for (uint32_t i = 0; i < argc(); i++) for (uint32_t i = 0; i < argc(); i++)
getArg(i)->setFoldedUnchecked(); getArg(i)->setImplicitlyUsedUnchecked();
} }
}; };

View File

@ -194,7 +194,7 @@ IonBuilder::inlineMathFunction(CallInfo &callInfo, MMathFunction::Function funct
if (!cache) if (!cache)
return InliningStatus_NotInlined; return InliningStatus_NotInlined;
callInfo.thisArg()->setFoldedUnchecked(); callInfo.thisArg()->setImplicitlyUsedUnchecked();
MMathFunction *ins = MMathFunction::New(alloc(), callInfo.getArg(0), function, cache); MMathFunction *ins = MMathFunction::New(alloc(), callInfo.getArg(0), function, cache);
current->add(ins); current->add(ins);
@ -246,7 +246,7 @@ IonBuilder::inlineArray(CallInfo &callInfo)
return InliningStatus_NotInlined; return InliningStatus_NotInlined;
} }
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
types::TemporaryTypeSet::DoubleConversion conversion = types::TemporaryTypeSet::DoubleConversion conversion =
getInlineReturnTypeSet()->convertDoubleElements(constraints()); getInlineReturnTypeSet()->convertDoubleElements(constraints());
@ -328,7 +328,7 @@ IonBuilder::inlineArrayPopShift(CallInfo &callInfo, MArrayPopShift::Mode mode)
if (types::ArrayPrototypeHasIndexedProperty(constraints(), script())) if (types::ArrayPrototypeHasIndexedProperty(constraints(), script()))
return InliningStatus_NotInlined; return InliningStatus_NotInlined;
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
types::TemporaryTypeSet *returnTypes = getInlineReturnTypeSet(); types::TemporaryTypeSet *returnTypes = getInlineReturnTypeSet();
bool needsHoleCheck = thisTypes->hasObjectFlags(constraints(), types::OBJECT_FLAG_NON_PACKED); bool needsHoleCheck = thisTypes->hasObjectFlags(constraints(), types::OBJECT_FLAG_NON_PACKED);
@ -391,7 +391,7 @@ IonBuilder::inlineArrayPush(CallInfo &callInfo)
if (conversion == types::TemporaryTypeSet::AmbiguousDoubleConversion) if (conversion == types::TemporaryTypeSet::AmbiguousDoubleConversion)
return InliningStatus_NotInlined; return InliningStatus_NotInlined;
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
value = callInfo.getArg(0); value = callInfo.getArg(0);
if (conversion == types::TemporaryTypeSet::AlwaysConvertToDoubles || if (conversion == types::TemporaryTypeSet::AlwaysConvertToDoubles ||
@ -502,7 +502,7 @@ IonBuilder::inlineArrayConcat(CallInfo &callInfo)
return InliningStatus_NotInlined; return InliningStatus_NotInlined;
JS_ASSERT(templateObj->is<ArrayObject>()); JS_ASSERT(templateObj->is<ArrayObject>());
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
MArrayConcat *ins = MArrayConcat::New(alloc(), constraints(), callInfo.thisArg(), callInfo.getArg(0), MArrayConcat *ins = MArrayConcat::New(alloc(), constraints(), callInfo.thisArg(), callInfo.getArg(0),
templateObj, templateObj->type()->initialHeap(constraints())); templateObj, templateObj->type()->initialHeap(constraints()));
@ -537,7 +537,7 @@ IonBuilder::inlineMathAbs(CallInfo &callInfo)
return InliningStatus_NotInlined; return InliningStatus_NotInlined;
} }
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
// If the arg is a Float32, we specialize the op as double, it will be specialized // If the arg is a Float32, we specialize the op as double, it will be specialized
// as float32 if necessary later. // as float32 if necessary later.
@ -570,13 +570,13 @@ IonBuilder::inlineMathFloor(CallInfo &callInfo)
// Math.floor(int(x)) == int(x) // Math.floor(int(x)) == int(x)
if (argType == MIRType_Int32 && returnType == MIRType_Int32) { if (argType == MIRType_Int32 && returnType == MIRType_Int32) {
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
current->push(callInfo.getArg(0)); current->push(callInfo.getArg(0));
return InliningStatus_Inlined; return InliningStatus_Inlined;
} }
if (IsFloatingPointType(argType) && returnType == MIRType_Int32) { if (IsFloatingPointType(argType) && returnType == MIRType_Int32) {
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
MFloor *ins = MFloor::New(alloc(), callInfo.getArg(0)); MFloor *ins = MFloor::New(alloc(), callInfo.getArg(0));
current->add(ins); current->add(ins);
current->push(ins); current->push(ins);
@ -584,7 +584,7 @@ IonBuilder::inlineMathFloor(CallInfo &callInfo)
} }
if (IsFloatingPointType(argType) && returnType == MIRType_Double) { if (IsFloatingPointType(argType) && returnType == MIRType_Double) {
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
MMathFunction *ins = MMathFunction::New(alloc(), callInfo.getArg(0), MMathFunction::Floor, nullptr); MMathFunction *ins = MMathFunction::New(alloc(), callInfo.getArg(0), MMathFunction::Floor, nullptr);
current->add(ins); current->add(ins);
current->push(ins); current->push(ins);
@ -608,13 +608,13 @@ IonBuilder::inlineMathCeil(CallInfo &callInfo)
// Math.ceil(int(x)) == int(x) // Math.ceil(int(x)) == int(x)
if (argType == MIRType_Int32 && returnType == MIRType_Int32) { if (argType == MIRType_Int32 && returnType == MIRType_Int32) {
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
current->push(callInfo.getArg(0)); current->push(callInfo.getArg(0));
return InliningStatus_Inlined; return InliningStatus_Inlined;
} }
if (IsFloatingPointType(argType) && returnType == MIRType_Double) { if (IsFloatingPointType(argType) && returnType == MIRType_Double) {
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
MMathFunction *ins = MMathFunction::New(alloc(), callInfo.getArg(0), MMathFunction::Ceil, nullptr); MMathFunction *ins = MMathFunction::New(alloc(), callInfo.getArg(0), MMathFunction::Ceil, nullptr);
current->add(ins); current->add(ins);
current->push(ins); current->push(ins);
@ -638,13 +638,13 @@ IonBuilder::inlineMathRound(CallInfo &callInfo)
// Math.round(int(x)) == int(x) // Math.round(int(x)) == int(x)
if (argType == MIRType_Int32 && returnType == MIRType_Int32) { if (argType == MIRType_Int32 && returnType == MIRType_Int32) {
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
current->push(callInfo.getArg(0)); current->push(callInfo.getArg(0));
return InliningStatus_Inlined; return InliningStatus_Inlined;
} }
if (argType == MIRType_Double && returnType == MIRType_Int32) { if (argType == MIRType_Double && returnType == MIRType_Int32) {
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
MRound *ins = MRound::New(alloc(), callInfo.getArg(0)); MRound *ins = MRound::New(alloc(), callInfo.getArg(0));
current->add(ins); current->add(ins);
current->push(ins); current->push(ins);
@ -652,7 +652,7 @@ IonBuilder::inlineMathRound(CallInfo &callInfo)
} }
if (argType == MIRType_Double && returnType == MIRType_Double) { if (argType == MIRType_Double && returnType == MIRType_Double) {
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
MMathFunction *ins = MMathFunction::New(alloc(), callInfo.getArg(0), MMathFunction::Round, nullptr); MMathFunction *ins = MMathFunction::New(alloc(), callInfo.getArg(0), MMathFunction::Round, nullptr);
current->add(ins); current->add(ins);
current->push(ins); current->push(ins);
@ -677,7 +677,7 @@ IonBuilder::inlineMathSqrt(CallInfo &callInfo)
if (!IsNumberType(argType)) if (!IsNumberType(argType))
return InliningStatus_NotInlined; return InliningStatus_NotInlined;
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
MSqrt *sqrt = MSqrt::New(alloc(), callInfo.getArg(0)); MSqrt *sqrt = MSqrt::New(alloc(), callInfo.getArg(0));
current->add(sqrt); current->add(sqrt);
@ -703,7 +703,7 @@ IonBuilder::inlineMathAtan2(CallInfo &callInfo)
if (!IsNumberType(argType0) || !IsNumberType(argType1)) if (!IsNumberType(argType0) || !IsNumberType(argType1))
return InliningStatus_NotInlined; return InliningStatus_NotInlined;
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
MAtan2 *atan2 = MAtan2::New(alloc(), callInfo.getArg(0), callInfo.getArg(1)); MAtan2 *atan2 = MAtan2::New(alloc(), callInfo.getArg(0), callInfo.getArg(1));
current->add(atan2); current->add(atan2);
@ -729,7 +729,7 @@ IonBuilder::inlineMathHypot(CallInfo &callInfo)
if (!IsNumberType(argType0) || !IsNumberType(argType1)) if (!IsNumberType(argType0) || !IsNumberType(argType1))
return InliningStatus_NotInlined; return InliningStatus_NotInlined;
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
MHypot *hypot = MHypot::New(alloc(), callInfo.getArg(0), callInfo.getArg(1)); MHypot *hypot = MHypot::New(alloc(), callInfo.getArg(0), callInfo.getArg(1));
current->add(hypot); current->add(hypot);
@ -758,7 +758,7 @@ IonBuilder::inlineMathPow(CallInfo &callInfo)
if (powerType != MIRType_Int32 && powerType != MIRType_Double) if (powerType != MIRType_Int32 && powerType != MIRType_Double)
return InliningStatus_NotInlined; return InliningStatus_NotInlined;
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
MDefinition *base = callInfo.getArg(0); MDefinition *base = callInfo.getArg(0);
MDefinition *power = callInfo.getArg(1); MDefinition *power = callInfo.getArg(1);
@ -850,7 +850,7 @@ IonBuilder::inlineMathRandom(CallInfo &callInfo)
if (getInlineReturnType() != MIRType_Double) if (getInlineReturnType() != MIRType_Double)
return InliningStatus_NotInlined; return InliningStatus_NotInlined;
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
MRandom *rand = MRandom::New(alloc()); MRandom *rand = MRandom::New(alloc());
current->add(rand); current->add(rand);
@ -873,7 +873,7 @@ IonBuilder::inlineMathImul(CallInfo &callInfo)
if (!IsNumberType(callInfo.getArg(1)->type())) if (!IsNumberType(callInfo.getArg(1)->type()))
return InliningStatus_NotInlined; return InliningStatus_NotInlined;
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
MInstruction *first = MTruncateToInt32::New(alloc(), callInfo.getArg(0)); MInstruction *first = MTruncateToInt32::New(alloc(), callInfo.getArg(0));
current->add(first); current->add(first);
@ -914,7 +914,7 @@ IonBuilder::inlineMathFRound(CallInfo &callInfo)
if (!IsNumberType(arg)) if (!IsNumberType(arg))
return InliningStatus_NotInlined; return InliningStatus_NotInlined;
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
MToFloat32 *ins = MToFloat32::New(alloc(), callInfo.getArg(0)); MToFloat32 *ins = MToFloat32::New(alloc(), callInfo.getArg(0));
current->add(ins); current->add(ins);
@ -942,7 +942,7 @@ IonBuilder::inlineMathMinMax(CallInfo &callInfo, bool max)
return InliningStatus_NotInlined; return InliningStatus_NotInlined;
} }
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
// Chain N-1 MMinMax instructions to compute the MinMax. // Chain N-1 MMinMax instructions to compute the MinMax.
MMinMax *last = MMinMax::New(alloc(), callInfo.getArg(0), callInfo.getArg(1), returnType, max); MMinMax *last = MMinMax::New(alloc(), callInfo.getArg(0), callInfo.getArg(1), returnType, max);
@ -974,7 +974,7 @@ IonBuilder::inlineStringObject(CallInfo &callInfo)
return InliningStatus_NotInlined; return InliningStatus_NotInlined;
JS_ASSERT(templateObj->is<StringObject>()); JS_ASSERT(templateObj->is<StringObject>());
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
MNewStringObject *ins = MNewStringObject::New(alloc(), callInfo.getArg(0), templateObj); MNewStringObject *ins = MNewStringObject::New(alloc(), callInfo.getArg(0), templateObj);
current->add(ins); current->add(ins);
@ -1014,7 +1014,7 @@ IonBuilder::inlineStringSplit(CallInfo &callInfo)
return InliningStatus_NotInlined; return InliningStatus_NotInlined;
} }
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
MStringSplit *ins = MStringSplit::New(alloc(), constraints(), callInfo.thisArg(), MStringSplit *ins = MStringSplit::New(alloc(), constraints(), callInfo.thisArg(),
callInfo.getArg(0), templateObject); callInfo.getArg(0), templateObject);
@ -1038,7 +1038,7 @@ IonBuilder::inlineStrCharCodeAt(CallInfo &callInfo)
if (argType != MIRType_Int32 && argType != MIRType_Double) if (argType != MIRType_Int32 && argType != MIRType_Double)
return InliningStatus_NotInlined; return InliningStatus_NotInlined;
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
MInstruction *index = MToInt32::New(alloc(), callInfo.getArg(0)); MInstruction *index = MToInt32::New(alloc(), callInfo.getArg(0));
current->add(index); current->add(index);
@ -1065,7 +1065,7 @@ IonBuilder::inlineStrFromCharCode(CallInfo &callInfo)
if (callInfo.getArg(0)->type() != MIRType_Int32) if (callInfo.getArg(0)->type() != MIRType_Int32)
return InliningStatus_NotInlined; return InliningStatus_NotInlined;
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
MToInt32 *charCode = MToInt32::New(alloc(), callInfo.getArg(0)); MToInt32 *charCode = MToInt32::New(alloc(), callInfo.getArg(0));
current->add(charCode); current->add(charCode);
@ -1090,7 +1090,7 @@ IonBuilder::inlineStrCharAt(CallInfo &callInfo)
if (argType != MIRType_Int32 && argType != MIRType_Double) if (argType != MIRType_Int32 && argType != MIRType_Double)
return InliningStatus_NotInlined; return InliningStatus_NotInlined;
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
MInstruction *index = MToInt32::New(alloc(), callInfo.getArg(0)); MInstruction *index = MToInt32::New(alloc(), callInfo.getArg(0));
current->add(index); current->add(index);
@ -1127,7 +1127,7 @@ IonBuilder::inlineRegExpExec(CallInfo &callInfo)
if (callInfo.getArg(0)->type() != MIRType_String) if (callInfo.getArg(0)->type() != MIRType_String)
return InliningStatus_NotInlined; return InliningStatus_NotInlined;
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
MInstruction *exec = MRegExpExec::New(alloc(), callInfo.thisArg(), callInfo.getArg(0)); MInstruction *exec = MRegExpExec::New(alloc(), callInfo.thisArg(), callInfo.getArg(0));
current->add(exec); current->add(exec);
@ -1157,7 +1157,7 @@ IonBuilder::inlineRegExpTest(CallInfo &callInfo)
if (callInfo.getArg(0)->type() != MIRType_String) if (callInfo.getArg(0)->type() != MIRType_String)
return InliningStatus_NotInlined; return InliningStatus_NotInlined;
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
MInstruction *match = MRegExpTest::New(alloc(), callInfo.thisArg(), callInfo.getArg(0)); MInstruction *match = MRegExpTest::New(alloc(), callInfo.thisArg(), callInfo.getArg(0));
current->add(match); current->add(match);
@ -1211,7 +1211,7 @@ IonBuilder::inlineUnsafePutElements(CallInfo &callInfo)
} }
} }
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
// Push the result first so that the stack depth matches up for // Push the result first so that the stack depth matches up for
// the potential bailouts that will occur in the stores below. // the potential bailouts that will occur in the stores below.
@ -1304,7 +1304,7 @@ IonBuilder::inlineForceSequentialOrInParallelSection(CallInfo &callInfo)
// During Parallel Exec, we always force sequential, so // During Parallel Exec, we always force sequential, so
// replace with true. This permits UCE to eliminate the // replace with true. This permits UCE to eliminate the
// entire path as dead, which is important. // entire path as dead, which is important.
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
MConstant *ins = MConstant::New(alloc(), BooleanValue(true)); MConstant *ins = MConstant::New(alloc(), BooleanValue(true));
current->add(ins); current->add(ins);
current->push(ins); current->push(ins);
@ -1361,7 +1361,7 @@ IonBuilder::inlineNewDenseArrayForParallelExecution(CallInfo &callInfo)
if (!templateObject || templateObject->type() != typeObject) if (!templateObject || templateObject->type() != typeObject)
return InliningStatus_NotInlined; return InliningStatus_NotInlined;
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
MNewDenseArrayPar *newObject = MNewDenseArrayPar::New(alloc(), MNewDenseArrayPar *newObject = MNewDenseArrayPar::New(alloc(),
graph().forkJoinSlice(), graph().forkJoinSlice(),
@ -1391,7 +1391,7 @@ IonBuilder::inlineUnsafeSetReservedSlot(CallInfo &callInfo)
return InliningStatus_NotInlined; return InliningStatus_NotInlined;
uint32_t slot = arg->toConstant()->value().toPrivateUint32(); uint32_t slot = arg->toConstant()->value().toPrivateUint32();
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
MStoreFixedSlot *store = MStoreFixedSlot::New(alloc(), callInfo.getArg(0), slot, callInfo.getArg(2)); MStoreFixedSlot *store = MStoreFixedSlot::New(alloc(), callInfo.getArg(0), slot, callInfo.getArg(2));
current->add(store); current->add(store);
@ -1419,7 +1419,7 @@ IonBuilder::inlineUnsafeGetReservedSlot(CallInfo &callInfo)
return InliningStatus_NotInlined; return InliningStatus_NotInlined;
uint32_t slot = arg->toConstant()->value().toPrivateUint32(); uint32_t slot = arg->toConstant()->value().toPrivateUint32();
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
MLoadFixedSlot *load = MLoadFixedSlot::New(alloc(), callInfo.getArg(0), slot); MLoadFixedSlot *load = MLoadFixedSlot::New(alloc(), callInfo.getArg(0), slot);
current->add(load); current->add(load);
@ -1453,7 +1453,7 @@ IonBuilder::inlineHaveSameClass(CallInfo &callInfo)
return InliningStatus_Inlined; return InliningStatus_Inlined;
} }
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
MHaveSameClass *sameClass = MHaveSameClass::New(alloc(), callInfo.getArg(0), callInfo.getArg(1)); MHaveSameClass *sameClass = MHaveSameClass::New(alloc(), callInfo.getArg(0), callInfo.getArg(1));
current->add(sameClass); current->add(sameClass);
@ -1489,7 +1489,7 @@ IonBuilder::inlineIsCallable(CallInfo &callInfo)
} }
} }
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
if (isCallableKnown) { if (isCallableKnown) {
MConstant *constant = MConstant::New(alloc(), BooleanValue(isCallableConstant)); MConstant *constant = MConstant::New(alloc(), BooleanValue(isCallableConstant));
@ -1517,7 +1517,7 @@ IonBuilder::inlineToObject(CallInfo &callInfo)
if (callInfo.getArg(0)->type() != MIRType_Object) if (callInfo.getArg(0)->type() != MIRType_Object)
return InliningStatus_NotInlined; return InliningStatus_NotInlined;
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
MDefinition *object = callInfo.getArg(0); MDefinition *object = callInfo.getArg(0);
current->push(object); current->push(object);
@ -1527,7 +1527,7 @@ IonBuilder::inlineToObject(CallInfo &callInfo)
IonBuilder::InliningStatus IonBuilder::InliningStatus
IonBuilder::inlineBailout(CallInfo &callInfo) IonBuilder::inlineBailout(CallInfo &callInfo)
{ {
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
current->add(MBail::New(alloc())); current->add(MBail::New(alloc()));
@ -1540,7 +1540,7 @@ IonBuilder::inlineBailout(CallInfo &callInfo)
IonBuilder::InliningStatus IonBuilder::InliningStatus
IonBuilder::inlineAssertFloat32(CallInfo &callInfo) IonBuilder::inlineAssertFloat32(CallInfo &callInfo)
{ {
callInfo.setFoldedUnchecked(); callInfo.setImplicitlyUsedUnchecked();
MDefinition *secondArg = callInfo.getArg(1); MDefinition *secondArg = callInfo.getArg(1);

View File

@ -1855,11 +1855,11 @@ MBinaryInstruction::tryUseUnsignedOperands()
if (newlhs->type() != MIRType_Int32 || newrhs->type() != MIRType_Int32) if (newlhs->type() != MIRType_Int32 || newrhs->type() != MIRType_Int32)
return false; return false;
if (newlhs != getOperand(0)) { if (newlhs != getOperand(0)) {
getOperand(0)->setFoldedUnchecked(); getOperand(0)->setImplicitlyUsedUnchecked();
replaceOperand(0, newlhs); replaceOperand(0, newlhs);
} }
if (newrhs != getOperand(1)) { if (newrhs != getOperand(1)) {
getOperand(1)->setFoldedUnchecked(); getOperand(1)->setImplicitlyUsedUnchecked();
replaceOperand(1, newrhs); replaceOperand(1, newrhs);
} }
return true; return true;

View File

@ -53,7 +53,12 @@ MIRType MIRTypeFromValue(const js::Value &vp)
_(Movable) /* Allow LICM and GVN to move this instruction */ \ _(Movable) /* Allow LICM and GVN to move this instruction */ \
_(Lowered) /* (Debug only) has a virtual register */ \ _(Lowered) /* (Debug only) has a virtual register */ \
_(Guard) /* Not removable if uses == 0 */ \ _(Guard) /* Not removable if uses == 0 */ \
_(Folded) /* Has constant folded uses not reflected in SSA */ \ \
/* Keep the flagged instruction in resume points and do not substitute this
* instruction by an UndefinedValue. This might be used by call inlining
* when a function argument is not used by the inlined instructions.
*/ \
_(ImplicitlyUsed) \
\ \
/* The instruction has been marked dead for lazy removal from resume /* The instruction has been marked dead for lazy removal from resume
* points. * points.

View File

@ -704,13 +704,13 @@ StoreTypedArrayPolicy::adjustValueInput(TempAllocator &alloc, MInstruction *ins,
case MIRType_Value: case MIRType_Value:
break; break;
case MIRType_Null: case MIRType_Null:
value->setFoldedUnchecked(); value->setImplicitlyUsedUnchecked();
value = MConstant::New(alloc, Int32Value(0)); value = MConstant::New(alloc, Int32Value(0));
ins->block()->insertBefore(ins, value->toInstruction()); ins->block()->insertBefore(ins, value->toInstruction());
break; break;
case MIRType_Object: case MIRType_Object:
case MIRType_Undefined: case MIRType_Undefined:
value->setFoldedUnchecked(); value->setImplicitlyUsedUnchecked();
value = MConstant::New(alloc, DoubleNaNValue()); value = MConstant::New(alloc, DoubleNaNValue());
ins->block()->insertBefore(ins, value->toInstruction()); ins->block()->insertBefore(ins, value->toInstruction());
break; break;