From: David Kerkeslager Date: Wed, 24 Jul 2019 18:00:40 +0000 (-0400) Subject: Add a very basic optimization pass X-Git-Url: https://code.kerkeslager.com/?p=fur;a=commitdiff_plain;h=e60f2b20f17609da9b093ac1e08d688bf87bfb4a Add a very basic optimization pass --- diff --git a/main.py b/main.py index 3045554..198072e 100644 --- a/main.py +++ b/main.py @@ -5,6 +5,7 @@ import crossplatform_ir_generation import desugaring import generation import normalization +import optimization import parsing import tokenization import transformation @@ -32,5 +33,6 @@ with open(destination_path, 'w') as f: # This is the crossplatform IR generation path crossplatform_ir = crossplatform_ir_generation.generate(converted) -outputted = crossplatform_ir_generation.output(crossplatform_ir) +optimized = optimization.optimize(crossplatform_ir) +outputted = crossplatform_ir_generation.output(optimized) print(outputted) 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))