in Jit/hir/analysis.cpp [30:184]
bool isPassthrough(const Instr& instr) {
switch (instr.opcode()) {
case Opcode::kAssign:
case Opcode::kCheckExc:
case Opcode::kCheckField:
case Opcode::kCheckFreevar:
case Opcode::kCheckNeg:
case Opcode::kCheckVar:
case Opcode::kGuardType:
case Opcode::kRefineType:
case Opcode::kUseType:
return true;
// GuardIs returns a copy of its input with a more specialized type, so it
// looks like a passthrough instruction at first glance. However, its
// purpose is to verify that a runtime value is a specific object, breaking
// the dependency on the instruction that produced the runtime value. It's
// possible to augment RefcountInsertion to support this pattern but let's
// wait to see if more instructions need it before adding that complexity.
case Opcode::kGuardIs:
return false;
// Cast is pass-through except when we are casting to float, in which case
// we may coerce an incoming int to a new float. It's also not a pass
// thru when we return True/False to indicate success/failure.
case Opcode::kCast: {
auto& cast = static_cast<const Cast&>(instr);
return cast.pytype() != &PyFloat_Type && cast.iserror();
}
case Opcode::kBinaryOp:
case Opcode::kBuildSlice:
case Opcode::kBuildString:
case Opcode::kCallCFunc:
case Opcode::kCallEx:
case Opcode::kCallExKw:
case Opcode::kCallMethod:
case Opcode::kCallStatic:
case Opcode::kCallStaticRetVoid:
case Opcode::kCheckSequenceBounds:
case Opcode::kClearError:
case Opcode::kCompare:
case Opcode::kCompareBool:
case Opcode::kDoubleBinaryOp:
case Opcode::kFillTypeAttrCache:
case Opcode::kFormatValue:
case Opcode::kGetIter:
case Opcode::kGetTuple:
case Opcode::kImportFrom:
case Opcode::kImportName:
case Opcode::kInPlaceOp:
case Opcode::kInitialYield:
case Opcode::kIntBinaryOp:
case Opcode::kPrimitiveCompare:
case Opcode::kIntConvert:
case Opcode::kPrimitiveUnbox:
case Opcode::kInvokeIterNext:
case Opcode::kInvokeMethod:
case Opcode::kInvokeStaticFunction:
case Opcode::kIsErrStopAsyncIteration:
case Opcode::kIsInstance:
case Opcode::kIsSubtype:
case Opcode::kIsNegativeAndErrOccurred:
case Opcode::kIsTruthy:
case Opcode::kListAppend:
case Opcode::kListExtend:
case Opcode::kLoadArg:
case Opcode::kLoadArrayItem:
case Opcode::kLoadAttr:
case Opcode::kLoadAttrSpecial:
case Opcode::kLoadAttrSuper:
case Opcode::kLoadCellItem:
case Opcode::kLoadConst:
case Opcode::kLoadCurrentFunc:
case Opcode::kLoadEvalBreaker:
case Opcode::kLoadField:
case Opcode::kLoadFieldAddress:
case Opcode::kLoadFunctionIndirect:
case Opcode::kLoadGlobal:
case Opcode::kLoadGlobalCached:
case Opcode::kLoadMethod:
case Opcode::kLoadMethodSuper:
case Opcode::kLoadTupleItem:
case Opcode::kLoadTypeAttrCacheItem:
case Opcode::kLoadVarObjectSize:
case Opcode::kLongCompare:
case Opcode::kLongBinaryOp:
case Opcode::kMakeCell:
case Opcode::kMakeCheckedDict:
case Opcode::kMakeDict:
case Opcode::kMakeCheckedList:
case Opcode::kMakeFunction:
case Opcode::kMakeListTuple:
case Opcode::kMakeSet:
case Opcode::kMakeTupleFromList:
case Opcode::kMergeDictUnpack:
case Opcode::kMergeSetUnpack:
case Opcode::kPhi:
case Opcode::kPrimitiveBox:
case Opcode::kPrimitiveUnaryOp:
case Opcode::kRepeatList:
case Opcode::kRepeatTuple:
case Opcode::kRunPeriodicTasks:
case Opcode::kSetCurrentAwaiter:
case Opcode::kSetDictItem:
case Opcode::kSetSetItem:
case Opcode::kStealCellItem:
case Opcode::kStoreArrayItem:
case Opcode::kStoreAttr:
case Opcode::kStoreSubscr:
case Opcode::kTpAlloc:
case Opcode::kUnaryOp:
case Opcode::kUnpackExToTuple:
case Opcode::kVectorCall:
case Opcode::kVectorCallKW:
case Opcode::kVectorCallStatic:
case Opcode::kWaitHandleLoadCoroOrResult:
case Opcode::kWaitHandleLoadWaiter:
case Opcode::kYieldAndYieldFrom:
case Opcode::kYieldFrom:
case Opcode::kYieldValue:
return false;
case Opcode::kBatchDecref:
case Opcode::kBeginInlinedFunction:
case Opcode::kBranch:
case Opcode::kCondBranch:
case Opcode::kCondBranchIterNotDone:
case Opcode::kCondBranchCheckType:
case Opcode::kDecref:
case Opcode::kDeleteAttr:
case Opcode::kDeleteSubscr:
case Opcode::kDeopt:
case Opcode::kDeoptPatchpoint:
case Opcode::kEndInlinedFunction:
case Opcode::kGuard:
case Opcode::kHintType:
case Opcode::kSnapshot:
case Opcode::kIncref:
case Opcode::kInitFunction:
case Opcode::kInitListTuple:
case Opcode::kReturn:
case Opcode::kSetCellItem:
case Opcode::kSetFunctionAttr:
case Opcode::kStoreField:
case Opcode::kXDecref:
case Opcode::kXIncref:
case Opcode::kRaiseAwaitableError:
case Opcode::kRaise:
case Opcode::kRaiseStatic:
case Opcode::kWaitHandleRelease:
JIT_CHECK(false, "Opcode %s has no output", instr.opname());
}
JIT_CHECK(false, "Bad opcode %d", static_cast<int>(instr.opcode()));
}