From f7cf973b9aeba26c52ab056ec5b2aa3d08e66348 Mon Sep 17 00:00:00 2001 From: Nicolas Pierron Date: Tue, 7 Jan 2014 05:56:21 -0800 Subject: [PATCH] Bug 953256 - IonMonkey: Rename Folded MIR flag to ImplictlyUsed. r=jandem --- js/src/jit/IonAnalysis.cpp | 10 ++--- js/src/jit/IonBuilder.cpp | 68 +++++++++++++++---------------- js/src/jit/IonBuilder.h | 6 +-- js/src/jit/MCallOptimize.cpp | 78 ++++++++++++++++++------------------ js/src/jit/MIR.cpp | 4 +- js/src/jit/MIR.h | 7 +++- js/src/jit/TypePolicy.cpp | 4 +- 7 files changed, 91 insertions(+), 86 deletions(-) diff --git a/js/src/jit/IonAnalysis.cpp b/js/src/jit/IonAnalysis.cpp index 6d0c2431ff59..c70893b47ce1 100644 --- a/js/src/jit/IonAnalysis.cpp +++ b/js/src/jit/IonAnalysis.cpp @@ -97,7 +97,7 @@ jit::EliminateDeadResumePointOperands(MIRGenerator *mir, MIRGraph &graph) // If the instruction's behavior has been constant folded into a // separate instruction, we can't determine precisely where the // instruction becomes dead and can't eliminate its uses. - if (ins->isFolded()) + if (ins->isImplicitlyUsed()) continue; // 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 // interpreter may be affected by removing the phi. - if (phi->isFolded()) + if (phi->isImplicitlyUsed()) return true; // Check for uses of this phi node outside of other phi nodes. @@ -253,9 +253,9 @@ IsPhiRedundant(MPhi *phi) if (first == nullptr) return nullptr; - // Propagate the Folded flag if |phi| is replaced with another phi. - if (phi->isFolded()) - first->setFoldedUnchecked(); + // Propagate the ImplicitlyUsed flag if |phi| is replaced with another phi. + if (phi->isImplicitlyUsed()) + first->setImplicitlyUsedUnchecked(); return first; } diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 353af1061a3a..fa3f775d0947 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -755,7 +755,7 @@ IonBuilder::processIterators() while (!worklist.empty()) { MPhi *phi = worklist.popCopy(); phi->setIterator(); - phi->setFoldedUnchecked(); + phi->setImplicitlyUsedUnchecked(); for (MUseDefIterator iter(phi); iter; iter++) { if (iter.def()->isPhi()) { @@ -1270,12 +1270,12 @@ IonBuilder::traverseBytecode() // In debug builds, after compiling this op, check that all values // 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 // used as operand of a new MIR instruction). // // 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 popped(alloc()); Vector poppedUses(alloc()); unsigned nuses = GetUseCount(script_, script_->pcToOffset(pc)); @@ -1318,7 +1318,7 @@ IonBuilder::traverseBytecode() case JSOP_POS: case JSOP_TOID: // 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 // not observable. JS_ASSERT(i == 0); @@ -1327,7 +1327,7 @@ IonBuilder::traverseBytecode() // FALL THROUGH default: - JS_ASSERT(popped[i]->isFolded() || + JS_ASSERT(popped[i]->isImplicitlyUsed() || // MNewDerivedTypedObject instances are // often dead unless they escape from the @@ -3833,7 +3833,7 @@ IonBuilder::inlineScriptedCall(CallInfo &callInfo, JSFunction *target) JS_ASSERT(target->isInterpreted()); JS_ASSERT(IsIonInlinablePC(pc)); - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); // Ensure sufficient space in the slots: needed for inlining from FUNAPPLY. 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 // be preserved in phis if we bail out. Mark the old callee definition as - // folded to ensure this happens. - callInfo.fun()->setFoldedUnchecked(); + // implicitly used to ensure this happens. + callInfo.fun()->setImplicitlyUsedUnchecked(); // 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 @@ -4380,7 +4380,7 @@ IonBuilder::inlineCalls(CallInfo &callInfo, ObjectVector &targets, JS_ASSERT_IF(maybeCache, targets.length() >= 1); MBasicBlock *dispatchBlock = current; - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); callInfo.pushFormals(dispatchBlock); // Patch any InlinePropertyTable to only contain functions that are inlineable. @@ -4402,7 +4402,7 @@ IonBuilder::inlineCalls(CallInfo &callInfo, ObjectVector &targets, MDispatchInstruction *dispatch; if (maybeCache) { dispatch = MTypeObjectDispatch::New(alloc(), maybeCache->object(), maybeCache->propTable()); - callInfo.fun()->setFoldedUnchecked(); + callInfo.fun()->setImplicitlyUsedUnchecked(); } else { 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. MConstant *funcDef = MConstant::New(alloc(), ObjectValue(*target), constraints()); - funcDef->setFoldedUnchecked(); + funcDef->setImplicitlyUsedUnchecked(); dispatchBlock->add(funcDef); // Use the MConstant in the inline resume point and on stack. @@ -4811,7 +4811,7 @@ IonBuilder::jsop_funcall(uint32_t argc) return false; return makeCall(native, callInfo, false); } - current->peek(calleeDepth)->setFoldedUnchecked(); + current->peek(calleeDepth)->setImplicitlyUsedUnchecked(); // Extract call target. types::TemporaryTypeSet *funTypes = current->peek(funcDepth)->resultTypeSet(); @@ -4893,7 +4893,7 @@ IonBuilder::jsop_funapply(uint32_t argc) return abort("fun.apply speculation failed"); } - current->peek(calleeDepth)->setFoldedUnchecked(); + current->peek(calleeDepth)->setImplicitlyUsedUnchecked(); // Use funapply that definitely uses |arguments| 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 // points, so that Baseline will behave correctly after a bailout. MDefinition *vp = current->pop(); - vp->setFoldedUnchecked(); + vp->setImplicitlyUsedUnchecked(); MDefinition *argThis = current->pop(); @@ -4955,7 +4955,7 @@ IonBuilder::jsop_funapplyarguments(uint32_t argc) // Vp MDefinition *vp = current->pop(); - vp->setFoldedUnchecked(); + vp->setImplicitlyUsedUnchecked(); // Arguments 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 // that the old definition remains in resume points. if (target) { - fun->setFoldedUnchecked(); + fun->setImplicitlyUsedUnchecked(); return constant(ObjectValue(*target)); } @@ -5213,7 +5213,7 @@ IonBuilder::makeCallHelper(JSFunction *target, CallInfo &callInfo, bool cloneAtC return nullptr; } - callInfo.thisArg()->setFoldedUnchecked(); + callInfo.thisArg()->setImplicitlyUsedUnchecked(); callInfo.setThis(create); } @@ -5311,9 +5311,9 @@ IonBuilder::jsop_eval(uint32_t argc) CallInfo callInfo(alloc(), /* constructing = */ false); if (!callInfo.init(current, argc)) return false; - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); - callInfo.fun()->setFoldedUnchecked(); + callInfo.fun()->setImplicitlyUsedUnchecked(); MDefinition *scopeChain = current->scopeChain(); MDefinition *string = callInfo.getArg(0); @@ -6245,12 +6245,12 @@ IonBuilder::ensureDefiniteType(MDefinition *def, JSValueType definiteType) MInstruction *replace; switch (definiteType) { case JSVAL_TYPE_UNDEFINED: - def->setFoldedUnchecked(); + def->setImplicitlyUsedUnchecked(); replace = MConstant::New(alloc(), UndefinedValue()); break; case JSVAL_TYPE_NULL: - def->setFoldedUnchecked(); + def->setImplicitlyUsedUnchecked(); replace = MConstant::New(alloc(), NullValue()); break; @@ -6821,8 +6821,8 @@ IonBuilder::getElemTryTypedStatic(bool *emitted, MDefinition *obj, MDefinition * // Emit LoadTypedArrayElementStatic. - obj->setFoldedUnchecked(); - index->setFoldedUnchecked(); + obj->setImplicitlyUsedUnchecked(); + index->setImplicitlyUsedUnchecked(); MLoadTypedArrayElementStatic *load = MLoadTypedArrayElementStatic::New(alloc(), tarr, ptr); current->add(load); @@ -6914,7 +6914,7 @@ IonBuilder::getElemTryArguments(bool *emitted, MDefinition *obj, MDefinition *in JS_ASSERT(!info().argsObjAliasesFormals()); // 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. MArgumentsLength *length = MArgumentsLength::New(alloc()); @@ -6953,7 +6953,7 @@ IonBuilder::getElemTryArgumentsInlined(bool *emitted, MDefinition *obj, MDefinit return true; // Emit inlined arguments. - obj->setFoldedUnchecked(); + obj->setImplicitlyUsedUnchecked(); JS_ASSERT(!info().argsObjAliasesFormals()); @@ -6962,7 +6962,7 @@ IonBuilder::getElemTryArgumentsInlined(bool *emitted, MDefinition *obj, MDefinit JS_ASSERT(inliningDepth_ > 0); int32_t id = index->toConstant()->value().toInt32(); - index->setFoldedUnchecked(); + index->setImplicitlyUsedUnchecked(); if (id < (int32_t)inlineCallInfo_->argc() && id >= 0) current->push(inlineCallInfo_->getArg(id)); @@ -7137,7 +7137,7 @@ IonBuilder::getTypedArrayLength(MDefinition *obj) if (obj->isConstant() && obj->toConstant()->value().isObject()) { TypedArrayObject *tarr = &obj->toConstant()->value().toObject().as(); int32_t length = (int32_t) tarr->length(); - obj->setFoldedUnchecked(); + obj->setImplicitlyUsedUnchecked(); return MConstant::New(alloc(), Int32Value(length)); } return MTypedArrayLength::New(alloc(), obj); @@ -7155,7 +7155,7 @@ IonBuilder::getTypedArrayElements(MDefinition *obj) types::TypeObjectKey *tarrType = types::TypeObjectKey::get(tarr); tarrType->watchStateChangeForTypedArrayBuffer(constraints()); - obj->setFoldedUnchecked(); + obj->setImplicitlyUsedUnchecked(); return MConstantElements::New(alloc(), data); } return MTypedArrayElements::New(alloc(), obj); @@ -7373,8 +7373,8 @@ IonBuilder::setElemTryTypedStatic(bool *emitted, MDefinition *object, return true; // Emit StoreTypedArrayElementStatic. - object->setFoldedUnchecked(); - index->setFoldedUnchecked(); + object->setImplicitlyUsedUnchecked(); + index->setImplicitlyUsedUnchecked(); // Clamp value to [0, 255] for Uint8ClampedArray. MDefinition *toWrite = value; @@ -7757,7 +7757,7 @@ IonBuilder::jsop_arguments_length() { // Type Inference has guaranteed this is an optimized arguments object. MDefinition *args = current->pop(); - args->setFoldedUnchecked(); + args->setImplicitlyUsedUnchecked(); // We don't know anything from the callee if (inliningDepth_ == 0) { @@ -8270,7 +8270,7 @@ IonBuilder::getPropTryConstant(bool *emitted, PropertyName *name, else if (testString) current->add(MGuardString::New(alloc(), obj)); else - obj->setFoldedUnchecked(); + obj->setImplicitlyUsedUnchecked(); pushConstant(ObjectValue(*singleton)); @@ -9410,7 +9410,7 @@ IonBuilder::hasStaticScopeObject(ScopeCoordinate sc, JSObject **pcall) // singleton type then it should show up here. MDefinition *scope = current->getSlot(info().scopeChainSlot()); - scope->setFoldedUnchecked(); + scope->setImplicitlyUsedUnchecked(); JSObject *environment = script()->function()->environment(); while (environment && !environment->is()) { @@ -9605,7 +9605,7 @@ IonBuilder::jsop_instanceof() if (!protoObject) break; - rhs->setFoldedUnchecked(); + rhs->setImplicitlyUsedUnchecked(); MInstanceOf *ins = MInstanceOf::New(alloc(), obj, protoObject); diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index 09c2dd300dca..5c30150b6f32 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -961,10 +961,10 @@ class CallInfo void setFun(MDefinition *fun) { fun_ = fun; } - void setFoldedUnchecked() { - thisArg_->setFoldedUnchecked(); + void setImplicitlyUsedUnchecked() { + thisArg_->setImplicitlyUsedUnchecked(); for (uint32_t i = 0; i < argc(); i++) - getArg(i)->setFoldedUnchecked(); + getArg(i)->setImplicitlyUsedUnchecked(); } }; diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index 83c7d9db4a7d..24fb6b3dd314 100644 --- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -194,7 +194,7 @@ IonBuilder::inlineMathFunction(CallInfo &callInfo, MMathFunction::Function funct if (!cache) return InliningStatus_NotInlined; - callInfo.thisArg()->setFoldedUnchecked(); + callInfo.thisArg()->setImplicitlyUsedUnchecked(); MMathFunction *ins = MMathFunction::New(alloc(), callInfo.getArg(0), function, cache); current->add(ins); @@ -246,7 +246,7 @@ IonBuilder::inlineArray(CallInfo &callInfo) return InliningStatus_NotInlined; } - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); types::TemporaryTypeSet::DoubleConversion conversion = getInlineReturnTypeSet()->convertDoubleElements(constraints()); @@ -328,7 +328,7 @@ IonBuilder::inlineArrayPopShift(CallInfo &callInfo, MArrayPopShift::Mode mode) if (types::ArrayPrototypeHasIndexedProperty(constraints(), script())) return InliningStatus_NotInlined; - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); types::TemporaryTypeSet *returnTypes = getInlineReturnTypeSet(); bool needsHoleCheck = thisTypes->hasObjectFlags(constraints(), types::OBJECT_FLAG_NON_PACKED); @@ -391,7 +391,7 @@ IonBuilder::inlineArrayPush(CallInfo &callInfo) if (conversion == types::TemporaryTypeSet::AmbiguousDoubleConversion) return InliningStatus_NotInlined; - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); value = callInfo.getArg(0); if (conversion == types::TemporaryTypeSet::AlwaysConvertToDoubles || @@ -502,7 +502,7 @@ IonBuilder::inlineArrayConcat(CallInfo &callInfo) return InliningStatus_NotInlined; JS_ASSERT(templateObj->is()); - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); MArrayConcat *ins = MArrayConcat::New(alloc(), constraints(), callInfo.thisArg(), callInfo.getArg(0), templateObj, templateObj->type()->initialHeap(constraints())); @@ -537,7 +537,7 @@ IonBuilder::inlineMathAbs(CallInfo &callInfo) return InliningStatus_NotInlined; } - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); // If the arg is a Float32, we specialize the op as double, it will be specialized // as float32 if necessary later. @@ -570,13 +570,13 @@ IonBuilder::inlineMathFloor(CallInfo &callInfo) // Math.floor(int(x)) == int(x) if (argType == MIRType_Int32 && returnType == MIRType_Int32) { - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); current->push(callInfo.getArg(0)); return InliningStatus_Inlined; } if (IsFloatingPointType(argType) && returnType == MIRType_Int32) { - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); MFloor *ins = MFloor::New(alloc(), callInfo.getArg(0)); current->add(ins); current->push(ins); @@ -584,7 +584,7 @@ IonBuilder::inlineMathFloor(CallInfo &callInfo) } if (IsFloatingPointType(argType) && returnType == MIRType_Double) { - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); MMathFunction *ins = MMathFunction::New(alloc(), callInfo.getArg(0), MMathFunction::Floor, nullptr); current->add(ins); current->push(ins); @@ -608,13 +608,13 @@ IonBuilder::inlineMathCeil(CallInfo &callInfo) // Math.ceil(int(x)) == int(x) if (argType == MIRType_Int32 && returnType == MIRType_Int32) { - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); current->push(callInfo.getArg(0)); return InliningStatus_Inlined; } if (IsFloatingPointType(argType) && returnType == MIRType_Double) { - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); MMathFunction *ins = MMathFunction::New(alloc(), callInfo.getArg(0), MMathFunction::Ceil, nullptr); current->add(ins); current->push(ins); @@ -638,13 +638,13 @@ IonBuilder::inlineMathRound(CallInfo &callInfo) // Math.round(int(x)) == int(x) if (argType == MIRType_Int32 && returnType == MIRType_Int32) { - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); current->push(callInfo.getArg(0)); return InliningStatus_Inlined; } if (argType == MIRType_Double && returnType == MIRType_Int32) { - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); MRound *ins = MRound::New(alloc(), callInfo.getArg(0)); current->add(ins); current->push(ins); @@ -652,7 +652,7 @@ IonBuilder::inlineMathRound(CallInfo &callInfo) } if (argType == MIRType_Double && returnType == MIRType_Double) { - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); MMathFunction *ins = MMathFunction::New(alloc(), callInfo.getArg(0), MMathFunction::Round, nullptr); current->add(ins); current->push(ins); @@ -677,7 +677,7 @@ IonBuilder::inlineMathSqrt(CallInfo &callInfo) if (!IsNumberType(argType)) return InliningStatus_NotInlined; - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); MSqrt *sqrt = MSqrt::New(alloc(), callInfo.getArg(0)); current->add(sqrt); @@ -703,7 +703,7 @@ IonBuilder::inlineMathAtan2(CallInfo &callInfo) if (!IsNumberType(argType0) || !IsNumberType(argType1)) return InliningStatus_NotInlined; - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); MAtan2 *atan2 = MAtan2::New(alloc(), callInfo.getArg(0), callInfo.getArg(1)); current->add(atan2); @@ -729,7 +729,7 @@ IonBuilder::inlineMathHypot(CallInfo &callInfo) if (!IsNumberType(argType0) || !IsNumberType(argType1)) return InliningStatus_NotInlined; - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); MHypot *hypot = MHypot::New(alloc(), callInfo.getArg(0), callInfo.getArg(1)); current->add(hypot); @@ -758,7 +758,7 @@ IonBuilder::inlineMathPow(CallInfo &callInfo) if (powerType != MIRType_Int32 && powerType != MIRType_Double) return InliningStatus_NotInlined; - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); MDefinition *base = callInfo.getArg(0); MDefinition *power = callInfo.getArg(1); @@ -850,7 +850,7 @@ IonBuilder::inlineMathRandom(CallInfo &callInfo) if (getInlineReturnType() != MIRType_Double) return InliningStatus_NotInlined; - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); MRandom *rand = MRandom::New(alloc()); current->add(rand); @@ -873,7 +873,7 @@ IonBuilder::inlineMathImul(CallInfo &callInfo) if (!IsNumberType(callInfo.getArg(1)->type())) return InliningStatus_NotInlined; - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); MInstruction *first = MTruncateToInt32::New(alloc(), callInfo.getArg(0)); current->add(first); @@ -914,7 +914,7 @@ IonBuilder::inlineMathFRound(CallInfo &callInfo) if (!IsNumberType(arg)) return InliningStatus_NotInlined; - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); MToFloat32 *ins = MToFloat32::New(alloc(), callInfo.getArg(0)); current->add(ins); @@ -942,7 +942,7 @@ IonBuilder::inlineMathMinMax(CallInfo &callInfo, bool max) return InliningStatus_NotInlined; } - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); // Chain N-1 MMinMax instructions to compute the MinMax. MMinMax *last = MMinMax::New(alloc(), callInfo.getArg(0), callInfo.getArg(1), returnType, max); @@ -974,7 +974,7 @@ IonBuilder::inlineStringObject(CallInfo &callInfo) return InliningStatus_NotInlined; JS_ASSERT(templateObj->is()); - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); MNewStringObject *ins = MNewStringObject::New(alloc(), callInfo.getArg(0), templateObj); current->add(ins); @@ -1014,7 +1014,7 @@ IonBuilder::inlineStringSplit(CallInfo &callInfo) return InliningStatus_NotInlined; } - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); MStringSplit *ins = MStringSplit::New(alloc(), constraints(), callInfo.thisArg(), callInfo.getArg(0), templateObject); @@ -1038,7 +1038,7 @@ IonBuilder::inlineStrCharCodeAt(CallInfo &callInfo) if (argType != MIRType_Int32 && argType != MIRType_Double) return InliningStatus_NotInlined; - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); MInstruction *index = MToInt32::New(alloc(), callInfo.getArg(0)); current->add(index); @@ -1065,7 +1065,7 @@ IonBuilder::inlineStrFromCharCode(CallInfo &callInfo) if (callInfo.getArg(0)->type() != MIRType_Int32) return InliningStatus_NotInlined; - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); MToInt32 *charCode = MToInt32::New(alloc(), callInfo.getArg(0)); current->add(charCode); @@ -1090,7 +1090,7 @@ IonBuilder::inlineStrCharAt(CallInfo &callInfo) if (argType != MIRType_Int32 && argType != MIRType_Double) return InliningStatus_NotInlined; - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); MInstruction *index = MToInt32::New(alloc(), callInfo.getArg(0)); current->add(index); @@ -1127,7 +1127,7 @@ IonBuilder::inlineRegExpExec(CallInfo &callInfo) if (callInfo.getArg(0)->type() != MIRType_String) return InliningStatus_NotInlined; - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); MInstruction *exec = MRegExpExec::New(alloc(), callInfo.thisArg(), callInfo.getArg(0)); current->add(exec); @@ -1157,7 +1157,7 @@ IonBuilder::inlineRegExpTest(CallInfo &callInfo) if (callInfo.getArg(0)->type() != MIRType_String) return InliningStatus_NotInlined; - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); MInstruction *match = MRegExpTest::New(alloc(), callInfo.thisArg(), callInfo.getArg(0)); 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 // 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 // replace with true. This permits UCE to eliminate the // entire path as dead, which is important. - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); MConstant *ins = MConstant::New(alloc(), BooleanValue(true)); current->add(ins); current->push(ins); @@ -1361,7 +1361,7 @@ IonBuilder::inlineNewDenseArrayForParallelExecution(CallInfo &callInfo) if (!templateObject || templateObject->type() != typeObject) return InliningStatus_NotInlined; - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); MNewDenseArrayPar *newObject = MNewDenseArrayPar::New(alloc(), graph().forkJoinSlice(), @@ -1391,7 +1391,7 @@ IonBuilder::inlineUnsafeSetReservedSlot(CallInfo &callInfo) return InliningStatus_NotInlined; uint32_t slot = arg->toConstant()->value().toPrivateUint32(); - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); MStoreFixedSlot *store = MStoreFixedSlot::New(alloc(), callInfo.getArg(0), slot, callInfo.getArg(2)); current->add(store); @@ -1419,7 +1419,7 @@ IonBuilder::inlineUnsafeGetReservedSlot(CallInfo &callInfo) return InliningStatus_NotInlined; uint32_t slot = arg->toConstant()->value().toPrivateUint32(); - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); MLoadFixedSlot *load = MLoadFixedSlot::New(alloc(), callInfo.getArg(0), slot); current->add(load); @@ -1453,7 +1453,7 @@ IonBuilder::inlineHaveSameClass(CallInfo &callInfo) return InliningStatus_Inlined; } - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); MHaveSameClass *sameClass = MHaveSameClass::New(alloc(), callInfo.getArg(0), callInfo.getArg(1)); current->add(sameClass); @@ -1489,7 +1489,7 @@ IonBuilder::inlineIsCallable(CallInfo &callInfo) } } - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); if (isCallableKnown) { MConstant *constant = MConstant::New(alloc(), BooleanValue(isCallableConstant)); @@ -1517,7 +1517,7 @@ IonBuilder::inlineToObject(CallInfo &callInfo) if (callInfo.getArg(0)->type() != MIRType_Object) return InliningStatus_NotInlined; - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); MDefinition *object = callInfo.getArg(0); current->push(object); @@ -1527,7 +1527,7 @@ IonBuilder::inlineToObject(CallInfo &callInfo) IonBuilder::InliningStatus IonBuilder::inlineBailout(CallInfo &callInfo) { - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); current->add(MBail::New(alloc())); @@ -1540,7 +1540,7 @@ IonBuilder::inlineBailout(CallInfo &callInfo) IonBuilder::InliningStatus IonBuilder::inlineAssertFloat32(CallInfo &callInfo) { - callInfo.setFoldedUnchecked(); + callInfo.setImplicitlyUsedUnchecked(); MDefinition *secondArg = callInfo.getArg(1); diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp index 31b1d316c049..81fbb011bd3d 100644 --- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -1855,11 +1855,11 @@ MBinaryInstruction::tryUseUnsignedOperands() if (newlhs->type() != MIRType_Int32 || newrhs->type() != MIRType_Int32) return false; if (newlhs != getOperand(0)) { - getOperand(0)->setFoldedUnchecked(); + getOperand(0)->setImplicitlyUsedUnchecked(); replaceOperand(0, newlhs); } if (newrhs != getOperand(1)) { - getOperand(1)->setFoldedUnchecked(); + getOperand(1)->setImplicitlyUsedUnchecked(); replaceOperand(1, newrhs); } return true; diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index 22cd29f9c824..b14b33450fe3 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -53,7 +53,12 @@ MIRType MIRTypeFromValue(const js::Value &vp) _(Movable) /* Allow LICM and GVN to move this instruction */ \ _(Lowered) /* (Debug only) has a virtual register */ \ _(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 * points. diff --git a/js/src/jit/TypePolicy.cpp b/js/src/jit/TypePolicy.cpp index 05398e36be71..3c57ccff8aac 100644 --- a/js/src/jit/TypePolicy.cpp +++ b/js/src/jit/TypePolicy.cpp @@ -704,13 +704,13 @@ StoreTypedArrayPolicy::adjustValueInput(TempAllocator &alloc, MInstruction *ins, case MIRType_Value: break; case MIRType_Null: - value->setFoldedUnchecked(); + value->setImplicitlyUsedUnchecked(); value = MConstant::New(alloc, Int32Value(0)); ins->block()->insertBefore(ins, value->toInstruction()); break; case MIRType_Object: case MIRType_Undefined: - value->setFoldedUnchecked(); + value->setImplicitlyUsedUnchecked(); value = MConstant::New(alloc, DoubleNaNValue()); ins->block()->insertBefore(ins, value->toInstruction()); break;