github/workflows/pycopy-test: Upgrade Pycopy to 3.6.1.
[ScratchABlock.git] / script_decompile.py
blobd7f37afc23a9c87064f019667f68623019a8e57d
1 from dom import *
2 from dataflow import *
3 from xform import *
4 from decomp import *
5 from xform_utils import apply_iterative
8 def do_propagate(cfg):
9 analyze_reach_defs(cfg)
10 make_du_chains(cfg)
12 # Choose one, expr_propagation is required for true decompilation
13 #const_propagation(cfg)
14 #copy_propagation(cfg)
15 #mem_propagation(cfg)
16 expr_propagation(cfg)
19 def dce(cfg):
20 analyze_live_vars(cfg)
21 foreach_bblock(cfg, dead_code_elimination)
24 def structure(cfg):
26 def _(res):
27 return 1 if res else 0
29 cnt = 1
30 while cnt:
31 cnt = 0
32 cnt += _(match_if(cfg))
33 # Opportunity for applying match_if_else_unjumped arises after
34 # match_if pass, and we should match all such cases, or they
35 # will be consumed by match_seq instead.
36 cnt += apply_iterative(match_if_else_unjumped, (cfg,))
37 cnt += _(match_ifelse(cfg))
38 cnt += _(match_if_else_inv_ladder(cfg))
39 cnt += _(match_if_else_ladder(cfg))
40 cnt += _(match_while(cfg))
41 cnt += _(match_dowhile(cfg))
42 cnt += _(match_if_dowhile(cfg))
43 cnt += _(match_seq(cfg))
46 # Apply arch-specific transformations
47 def arch_specific(cfg):
48 # Remove Xtensa memw instructions. TODO: should instead be used to
49 # recover volatile types.
50 foreach_bblock(cfg, remove_sfunc, name="memw")
53 def apply(cfg):
55 # Data flow
58 # Various algos below don't work with no explicit entry in CFG
59 cfg_preheader(cfg)
60 # Also don't work with >1 entries
61 remove_unreachable_entries(cfg)
62 # Various algos below require single-exit CFG
63 cfg_single_exit(cfg)
65 foreach_inst(cfg, sub_const_to_add)
66 foreach_inst(cfg, rewrite_complex_dest)
67 foreach_inst(cfg, booleanize_cond)
68 # Initial pass on simplifying expressions
69 foreach_inst(cfg, simplify_inst)
71 analyze_live_vars(cfg)
72 insert_initial_regs(cfg)
74 do_propagate(cfg)
76 # Estimate args only at the beginning of processing
77 analyze_live_vars(cfg)
78 estimate_params(cfg)
80 dce(cfg)
82 # This should be run after propagation, so it caught all cases.
83 # Run this after DCE to not do useless work ;-).
84 foreach_inst(cfg, normalize_cond)
87 # Control flow
90 remove_trailing_jumps(cfg)
91 remove_jump_over_jump(cfg)
93 arch_specific(cfg)
95 cfg.number_postorder()
96 compute_idom(cfg)
97 structure(cfg)
99 # match_abnormal_sel() requires updated DFS numbers
100 cfg.number_postorder()
101 # We can't know which node to split before we start control flow processing,
102 # but splitting node changes data flow, so need to recompute it
103 if match_abnormal_sel(cfg):
105 do_propagate(cfg)
106 dce(cfg)
108 cfg.number_postorder()
109 compute_idom(cfg)
110 structure(cfg)
113 # Post-processing
116 foreach_inst(cfg, rewrite_stack_vars)