Esempio n. 1
0
bool
FilterTypeSetPolicy::adjustInputs(TempAllocator &alloc, MInstruction *ins)
{
    MOZ_ASSERT(ins->numOperands() == 1);
    MIRType inputType = ins->getOperand(0)->type();
    MIRType outputType = ins->type();

    // Input and output type are already in accordance.
    if (inputType == outputType)
        return true;

    // Output is a value, box the input.
    if (outputType == MIRType_Value) {
        MOZ_ASSERT(inputType != MIRType_Value);
        ins->replaceOperand(0, boxAt(alloc, ins, ins->getOperand(0)));
        return true;
    }

    // The outputType should be a subset of the inputType else we are in code
    // that has never executed yet. Bail to see the new type (if that hasn't
    // happened yet).
    if (inputType != MIRType_Value) {
        MBail *bail = MBail::New(alloc);
        ins->block()->insertBefore(ins, bail);
        bail->setDependency(ins->dependency());
        ins->setDependency(bail);
        ins->replaceOperand(0, boxAt(alloc, ins, ins->getOperand(0)));
    }

    // We can't unbox a value to null/undefined/lazyargs. So keep output
    // also a value.
    // Note: Using setResultType shouldn't be done in TypePolicies,
    //       Here it is fine, since the type barrier has no uses.
    if (IsNullOrUndefined(outputType) || outputType == MIRType_MagicOptimizedArguments) {
        MOZ_ASSERT(!ins->hasDefUses());
        ins->setResultType(MIRType_Value);
        return true;
    }

    // Unbox / propagate the right type.
    MUnbox::Mode mode = MUnbox::Infallible;
    MInstruction *replace = MUnbox::New(alloc, ins->getOperand(0), ins->type(), mode);

    ins->block()->insertBefore(ins, replace);
    ins->replaceOperand(0, replace);
    if (!replace->typePolicy()->adjustInputs(alloc, replace))
        return false;

    // Carry over the dependency the MFilterTypeSet had.
    replace->setDependency(ins->dependency());

    return true;
}
Esempio n. 2
0
bool
FilterTypeSetPolicy::adjustInputs(TempAllocator& alloc, MInstruction* ins)
{
    MOZ_ASSERT(ins->numOperands() == 1);
    MIRType inputType = ins->getOperand(0)->type();
    MIRType outputType = ins->type();

    // Special case when output is a Float32, but input isn't.
    if (outputType == MIRType_Float32 && inputType != MIRType_Float32) {
        // Create a MToFloat32 to add between the MFilterTypeSet and
        // its uses.
        MInstruction* replace = MToFloat32::New(alloc, ins);
        ins->justReplaceAllUsesWithExcept(replace);
        ins->block()->insertAfter(ins, replace);

        // Reset the type to not MIRType_Float32
        // Note: setResultType shouldn't happen in TypePolicies,
        //       Here it is fine, since there is just one use we just
        //       added ourself. And the resulting type after MToFloat32
        //       equals the original type.
        ins->setResultType(ins->resultTypeSet()->getKnownMIRType());
        outputType = ins->type();

        // Do the type analysis
        if (!replace->typePolicy()->adjustInputs(alloc, replace))
            return false;

        // Fall through to let the MFilterTypeSet adjust its input based
        // on its new type.
    }

    // Input and output type are already in accordance.
    if (inputType == outputType)
        return true;

    // Output is a value, box the input.
    if (outputType == MIRType_Value) {
        MOZ_ASSERT(inputType != MIRType_Value);
        ins->replaceOperand(0, BoxAt(alloc, ins, ins->getOperand(0)));
        return true;
    }

    // The outputType should be a subset of the inputType else we are in code
    // that has never executed yet. Bail to see the new type (if that hasn't
    // happened yet).
    if (inputType != MIRType_Value) {
        MBail* bail = MBail::New(alloc);
        ins->block()->insertBefore(ins, bail);
        bail->setDependency(ins->dependency());
        ins->setDependency(bail);
        ins->replaceOperand(0, BoxAt(alloc, ins, ins->getOperand(0)));
    }

    // We can't unbox a value to null/undefined/lazyargs. So keep output
    // also a value.
    // Note: Using setResultType shouldn't be done in TypePolicies,
    //       Here it is fine, since the type barrier has no uses.
    if (IsNullOrUndefined(outputType) || outputType == MIRType_MagicOptimizedArguments) {
        MOZ_ASSERT(!ins->hasDefUses());
        ins->setResultType(MIRType_Value);
        return true;
    }

    // Unbox / propagate the right type.
    MUnbox::Mode mode = MUnbox::Infallible;
    MInstruction* replace = MUnbox::New(alloc, ins->getOperand(0), ins->type(), mode);

    ins->block()->insertBefore(ins, replace);
    ins->replaceOperand(0, replace);
    if (!replace->typePolicy()->adjustInputs(alloc, replace))
        return false;

    // Carry over the dependency the MFilterTypeSet had.
    replace->setDependency(ins->dependency());

    return true;
}