Optimization¶
The IR-code generated by the front-end can be optimized in many ways. The compiler does not have the best way to optimize code, but instead has a bag of tricks it can use.
Abstract base classes¶
The optimization passes all subclass one of the following base classes.
-
class
ppci.opt.transform.ModulePass¶ Base class of all optimizing passes.
Subclass this class to implement your own optimization pass.
-
run(ir_module)¶ Run this pass over a module
-
-
class
ppci.opt.transform.FunctionPass¶ Base pass that loops over all functions in a module
-
on_function(function: ppci.ir.SubRoutine)¶ Override this virtual method
-
run(ir_module: ppci.ir.Module)¶ Main entry point for the pass
-
Optimization passes¶
-
class
ppci.opt.Mem2RegPromotor¶ Tries to find alloc instructions only used by load and store instructions and replace them with values and phi nodes
-
class
ppci.opt.LoadAfterStorePass¶ Remove load after store to the same location.
[x] = a b = [x] c = b + 2
transforms into:
[x] = a c = a + 2
-
class
ppci.opt.DeleteUnusedInstructionsPass¶ Remove unused variables from a block
-
class
ppci.opt.RemoveAddZeroPass¶ Replace additions with zero with the value itself. Replace multiplication by 1 with value itself.
-
class
ppci.opt.CommonSubexpressionEliminationPass¶ Replace common sub expressions (cse) with the previously defined one.
-
class
ppci.opt.cjmp.CJumpPass¶
Uml¶
![digraph "classes_foo" {
charset="utf-8"
rankdir=BT
"0" [label="{BlockPass|\l|on_block(block)\lon_function(function)\l}", shape="record"];
"1" [label="{CJumpPass|\l|on_instruction(instruction)\l}", shape="record"];
"2" [label="{CleanPass|\l|find_empty_blocks(function)\lfind_single_predecessor_block(function)\lglue_blocks(block1, block2)\lon_function(function)\lremove_empty_blocks(function)\lremove_one_preds(function)\l}", shape="record"];
"3" [label="{CommonSubexpressionEliminationPass|\l|on_block(block)\l}", shape="record"];
"4" [label="{ConstantFolder|ops : dict\l|eval_const(value)\lis_const(value)\lon_block(block)\l}", shape="record"];
"5" [label="{DeleteUnusedInstructionsPass|\l|on_block(block)\l}", shape="record"];
"6" [label="{FunctionPass|debug_db : NoneType\l|on_function(function)\lrun(ir_module)\l}", shape="record"];
"7" [label="{InstructionPass|\l|on_block(block)\lon_instruction(instruction)\l}", shape="record"];
"8" [label="{LoadAfterStorePass|\l|find_store_backwards(i, ty, stop_on)\lon_block(block)\lremove_redundant_stores(block)\lreplace_load_after_store(block)\l}", shape="record"];
"9" [label="{Mem2RegPromotor|\l|on_function(function)\lplace_phi_nodes(stores, phi_ty, name, cfg_info)\lpromote(alloc, cfg_info)\lrename(initial_value, phis, loads, stores, cfg_info)\l}", shape="record"];
"10" [label="{ModulePass|logger : RootLogger, NoneType\l|prepare()\lrun(ir_module)\l}", shape="record"];
"11" [label="{RemoveAddZeroPass|\l|on_instruction(instruction)\l}", shape="record"];
"12" [label="{TailCallOptimization|\l|on_function(function)\lrewrite_tailcalls(function, tail_calls)\l}", shape="record"];
"0" -> "6" [arrowhead="empty", arrowtail="none"];
"1" -> "7" [arrowhead="empty", arrowtail="none"];
"2" -> "6" [arrowhead="empty", arrowtail="none"];
"3" -> "0" [arrowhead="empty", arrowtail="none"];
"4" -> "0" [arrowhead="empty", arrowtail="none"];
"5" -> "0" [arrowhead="empty", arrowtail="none"];
"6" -> "10" [arrowhead="empty", arrowtail="none"];
"7" -> "0" [arrowhead="empty", arrowtail="none"];
"8" -> "0" [arrowhead="empty", arrowtail="none"];
"9" -> "6" [arrowhead="empty", arrowtail="none"];
"11" -> "7" [arrowhead="empty", arrowtail="none"];
"12" -> "6" [arrowhead="empty", arrowtail="none"];
}](../_images/graphviz-ff7c8e83d408b775a9f0eeabe81b55ac947a6c2d.png)