diff options
Diffstat (limited to 'Tools/cases_generator/optimizer_generator.py')
-rw-r--r-- | Tools/cases_generator/optimizer_generator.py | 78 |
1 files changed, 46 insertions, 32 deletions
diff --git a/Tools/cases_generator/optimizer_generator.py b/Tools/cases_generator/optimizer_generator.py index b74f627235a..7a1dfe1b85b 100644 --- a/Tools/cases_generator/optimizer_generator.py +++ b/Tools/cases_generator/optimizer_generator.py @@ -18,11 +18,12 @@ from generators_common import ( ROOT, write_header, Emitter, + TokenIterator, ) from cwriter import CWriter from typing import TextIO, Iterator from lexer import Token -from stack import Local, Stack, StackError +from stack import Local, Stack, StackError, Storage DEFAULT_OUTPUT = ROOT / "Python/optimizer_cases.c.h" DEFAULT_ABSTRACT_INPUT = (ROOT / "Python/optimizer_bytecodes.c").absolute().as_posix() @@ -45,7 +46,7 @@ def declare_variables(uop: Uop, out: CWriter, skip_inputs: bool) -> None: variables = {"unused"} if not skip_inputs: for var in reversed(uop.stack.inputs): - if var.name not in variables: + if var.used and var.name not in variables: variables.add(var.name) if var.condition: out.emit(f"{type_name(var)}{var.name} = NULL;\n") @@ -65,7 +66,7 @@ def declare_variables(uop: Uop, out: CWriter, skip_inputs: bool) -> None: def decref_inputs( out: CWriter, tkn: Token, - tkn_iter: Iterator[Token], + tkn_iter: TokenIterator, uop: Uop, stack: Stack, inst: Instruction | None, @@ -76,13 +77,27 @@ def decref_inputs( out.emit_at("", tkn) -def emit_default(out: CWriter, uop: Uop) -> None: - for i, var in enumerate(uop.stack.outputs): +def emit_default(out: CWriter, uop: Uop, stack: Stack) -> None: + for var in reversed(uop.stack.inputs): + stack.pop(var) + top_offset = stack.top_offset.copy() + for var in uop.stack.outputs: + if var.is_array() and not var.peek and not var.name == "unused": + c_offset = top_offset.to_c() + out.emit(f"{var.name} = &stack_pointer[{c_offset}];\n") + top_offset.push(var) + for var in uop.stack.outputs: + local = Local.undefined(var) + stack.push(local) if var.name != "unused" and not var.peek: + local.defined = True if var.is_array(): - out.emit(f"for (int _i = {var.size}; --_i >= 0;) {{\n") - out.emit(f"{var.name}[_i] = sym_new_not_null(ctx);\n") - out.emit("}\n") + if var.size == "1": + out.emit(f"{var.name}[0] = sym_new_not_null(ctx);\n") + else: + out.emit(f"for (int _i = {var.size}; --_i >= 0;) {{\n") + out.emit(f"{var.name}[_i] = sym_new_not_null(ctx);\n") + out.emit("}\n") elif var.name == "null": out.emit(f"{var.name} = sym_new_null(ctx);\n") else: @@ -90,7 +105,12 @@ def emit_default(out: CWriter, uop: Uop) -> None: class OptimizerEmitter(Emitter): - pass + + def emit_save(self, storage: Storage) -> None: + storage.flush(self.out) + + def emit_reload(self, storage: Storage) -> None: + pass def write_uop( @@ -102,22 +122,18 @@ def write_uop( skip_inputs: bool, ) -> None: locals: dict[str, Local] = {} + prototype = override if override else uop try: - prototype = override if override else uop - is_override = override is not None out.start_line() - for var in reversed(prototype.stack.inputs): - code, local = stack.pop(var, extract_bits=True) - if not skip_inputs: + if override: + code_list, storage = Storage.for_uop(stack, prototype, extract_bits=False) + for code in code_list: out.emit(code) - if local.defined: - locals[local.name] = local - out.emit(stack.define_output_arrays(prototype.stack.outputs)) if debug: args = [] - for var in prototype.stack.inputs: - if not var.peek or is_override: - args.append(var.name) + for input in prototype.stack.inputs: + if not input.peek or override: + args.append(input.name) out.emit(f'DEBUG_PRINTF({", ".join(args)});\n') if override: for cache in uop.caches: @@ -130,20 +146,18 @@ def write_uop( out.emit(f"{type}{cache.name} = ({cast})this_instr->operand;\n") if override: emitter = OptimizerEmitter(out) - emitter.emit_tokens(override, stack, None) + # No reference management of inputs needed. + for var in storage.inputs: # type: ignore[possibly-undefined] + var.defined = False + storage = emitter.emit_tokens(override, storage, None) + out.start_line() + storage.flush(out, cast_type="_Py_UopsSymbol *", extract_bits=False) else: - emit_default(out, uop) - - for var in prototype.stack.outputs: - if var.name in locals: - local = locals[var.name] - else: - local = Local.local(var) - stack.push(local) - out.start_line() - stack.flush(out, cast_type="_Py_UopsSymbol *", extract_bits=True) + emit_default(out, uop, stack) + out.start_line() + stack.flush(out, cast_type="_Py_UopsSymbol *", extract_bits=False) except StackError as ex: - raise analysis_error(ex.args[0], uop.body[0]) + raise analysis_error(ex.args[0], prototype.body[0]) # from None SKIPS = ("_EXTENDED_ARG",) |