mirror of
https://github.com/python/cpython.git
synced 2025-08-30 21:48:47 +00:00
gh-106581: Add 10 new opcodes by allowing assert(kwnames == NULL)
(#106707)
By turning `assert(kwnames == NULL)` into a macro that is not in the "forbidden" list, many instructions that formerly were skipped because they contained such an assert (but no other mention of `kwnames`) are now supported in Tier 2. This covers 10 instructions in total (all specializations of `CALL` that invoke some C code): - `CALL_NO_KW_TYPE_1` - `CALL_NO_KW_STR_1` - `CALL_NO_KW_TUPLE_1` - `CALL_NO_KW_BUILTIN_O` - `CALL_NO_KW_BUILTIN_FAST` - `CALL_NO_KW_LEN` - `CALL_NO_KW_ISINSTANCE` - `CALL_NO_KW_METHOD_DESCRIPTOR_O` - `CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS` - `CALL_NO_KW_METHOD_DESCRIPTOR_FAST`
This commit is contained in:
parent
b2b261ab2a
commit
2b94a05a0e
7 changed files with 385 additions and 34 deletions
|
@ -408,27 +408,31 @@ class Instruction:
|
|||
|
||||
def is_viable_uop(self) -> bool:
|
||||
"""Whether this instruction is viable as a uop."""
|
||||
dprint: typing.Callable[..., None] = lambda *args, **kwargs: None
|
||||
# if self.name.startswith("CALL"):
|
||||
# dprint = print
|
||||
|
||||
if self.name == "EXIT_TRACE":
|
||||
return True # This has 'return frame' but it's okay
|
||||
if self.always_exits:
|
||||
# print(f"Skipping {self.name} because it always exits")
|
||||
dprint(f"Skipping {self.name} because it always exits")
|
||||
return False
|
||||
if self.instr_flags.HAS_ARG_FLAG:
|
||||
# If the instruction uses oparg, it cannot use any caches
|
||||
if self.active_caches:
|
||||
# print(f"Skipping {self.name} because it uses oparg and caches")
|
||||
dprint(f"Skipping {self.name} because it uses oparg and caches")
|
||||
return False
|
||||
else:
|
||||
# If it doesn't use oparg, it can have one cache entry
|
||||
if len(self.active_caches) > 1:
|
||||
# print(f"Skipping {self.name} because it has >1 cache entries")
|
||||
dprint(f"Skipping {self.name} because it has >1 cache entries")
|
||||
return False
|
||||
res = True
|
||||
for forbidden in FORBIDDEN_NAMES_IN_UOPS:
|
||||
# NOTE: To disallow unspecialized uops, use
|
||||
# if variable_used(self.inst, forbidden):
|
||||
if variable_used_unspecialized(self.inst, forbidden):
|
||||
# print(f"Skipping {self.name} because it uses {forbidden}")
|
||||
dprint(f"Skipping {self.name} because it uses {forbidden}")
|
||||
res = False
|
||||
return res
|
||||
|
||||
|
@ -1499,6 +1503,8 @@ class Analyzer:
|
|||
with self.out.block(f"case {thing.name}:"):
|
||||
instr.write(self.out, tier=TIER_TWO)
|
||||
self.out.emit("break;")
|
||||
# elif instr.kind != "op":
|
||||
# print(f"NOTE: {thing.name} is not a viable uop")
|
||||
case parser.Macro():
|
||||
pass
|
||||
case parser.Pseudo():
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue