SSATmp* TraceBuilder::preOptimizeStLoc(IRInstruction* inst) { auto locId = inst->extra<StLoc>()->locId; auto const curType = localType(locId, DataTypeGeneric); auto const newType = inst->src(1)->type(); assert(inst->typeParam().equals(Type::None)); // There's no need to store the type if it's going to be the same // KindOfFoo. We still have to store string types because we don't // guard on KindOfStaticString vs. KindOfString. auto const bothBoxed = curType.isBoxed() && newType.isBoxed(); auto const sameUnboxed = curType != Type::None && // TODO(#2135185) curType.isSameKindOf(newType) && !curType.isString(); if (bothBoxed || sameUnboxed) { // TODO(t2598894) once relaxGuards supports proper type reflowing, we // should be able to relax the constraint here and degrade StLocNT to // StLoc if we relax its input. if (sameUnboxed) constrainLocal(locId, DataTypeSpecific, "StLoc -> StLocNT"); inst->setOpcode(StLocNT); } return nullptr; }
SSATmp* TraceBuilder::preOptimizeStLoc(IRInstruction* inst) { // Guard relaxation might change the current local type, so don't try to // change to StLocNT until after relaxation happens. if (!inReoptimize()) return nullptr; auto locId = inst->extra<StLoc>()->locId; auto const curType = localType(locId, DataTypeGeneric); auto const newType = inst->src(1)->type(); assert(inst->typeParam() == Type::None); // There's no need to store the type if it's going to be the same // KindOfFoo. We still have to store string types because we don't // guard on KindOfStaticString vs. KindOfString. auto const bothBoxed = curType.isBoxed() && newType.isBoxed(); auto const sameUnboxed = curType.isSameKindOf(newType) && !curType.isString(); if (bothBoxed || sameUnboxed) { inst->setOpcode(StLocNT); } return nullptr; }