X-Git-Url: https://code.kerkeslager.com/?a=blobdiff_plain;f=optimization.py;fp=optimization.py;h=7beef773d6d82ecf84da6a04763c2f7367e78fe2;hb=e60f2b20f17609da9b093ac1e08d688bf87bfb4a;hp=0000000000000000000000000000000000000000;hpb=62ff4eed7e32969b68a381aedf6ad2c9169c7e00;p=fur diff --git a/optimization.py b/optimization.py new file mode 100644 index 0000000..7beef77 --- /dev/null +++ b/optimization.py @@ -0,0 +1,49 @@ +from crossplatform_ir_generation import CIRProgram, CIRInstruction, CIRLabel + +PUSHING_INSTRUCTIONS_WITHOUT_SIDE_EFFECTS = set( + ('push',), +) + +def push_drop_optimization(ir): + ir = tuple(ir) + + i = 0 + + while i < len(ir): + if isinstance(ir[i], CIRInstruction)\ + and ir[i].instruction in PUSHING_INSTRUCTIONS_WITHOUT_SIDE_EFFECTS\ + and i + 1 < len(ir)\ + and isinstance(ir[i + 1], CIRInstruction)\ + and ir[i + 1].instruction == 'drop': + i += 2 + else: + yield ir[i] + i += 1 + +# TODO This can be smarter +def unused_pop_optimization(ir): + ir = tuple(ir) + + used_symbols = set() + + for entry in ir: + # TODO Having symbols be a string starting with "sym" is a bit hacky + if isinstance(entry, CIRInstruction)\ + and entry.instruction != 'pop'\ + and isinstance(entry.argument, str)\ + and entry.argument.startswith('sym'): + used_symbols.add(entry.argument) + + for entry in ir: + if isinstance(entry, CIRInstruction) and entry.instruction == 'pop' and entry.argument not in used_symbols: + yield CIRInstruction(instruction='drop', argument=None) + else: + yield entry + +def optimize(cir_program): + ir = cir_program.entry_list + + ir = push_drop_optimization(ir) + ir = unused_pop_optimization(ir) + + return CIRProgram(entry_list=tuple(ir))