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; }
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; }