1*c85f09ccSJohn Levon // SPDX-License-Identifier: MIT 2*c85f09ccSJohn Levon // 3*c85f09ccSJohn Levon // optimize.c - main optimization loop 4*c85f09ccSJohn Levon // 5*c85f09ccSJohn Levon // Copyright (C) 2004 Linus Torvalds 6*c85f09ccSJohn Levon // Copyright (C) 2004 Christopher Li 7*c85f09ccSJohn Levon 8*c85f09ccSJohn Levon #include <assert.h> 9*c85f09ccSJohn Levon #include "optimize.h" 10*c85f09ccSJohn Levon #include "flowgraph.h" 11*c85f09ccSJohn Levon #include "linearize.h" 12*c85f09ccSJohn Levon #include "liveness.h" 13*c85f09ccSJohn Levon #include "flow.h" 14*c85f09ccSJohn Levon #include "cse.h" 15*c85f09ccSJohn Levon #include "ir.h" 16*c85f09ccSJohn Levon #include "ssa.h" 17*c85f09ccSJohn Levon 18*c85f09ccSJohn Levon int repeat_phase; 19*c85f09ccSJohn Levon clear_symbol_pseudos(struct entrypoint * ep)20*c85f09ccSJohn Levonstatic void clear_symbol_pseudos(struct entrypoint *ep) 21*c85f09ccSJohn Levon { 22*c85f09ccSJohn Levon pseudo_t pseudo; 23*c85f09ccSJohn Levon 24*c85f09ccSJohn Levon FOR_EACH_PTR(ep->accesses, pseudo) { 25*c85f09ccSJohn Levon pseudo->sym->pseudo = NULL; 26*c85f09ccSJohn Levon } END_FOR_EACH_PTR(pseudo); 27*c85f09ccSJohn Levon } 28*c85f09ccSJohn Levon 29*c85f09ccSJohn Levon clean_up_insns(struct entrypoint * ep)30*c85f09ccSJohn Levonstatic void clean_up_insns(struct entrypoint *ep) 31*c85f09ccSJohn Levon { 32*c85f09ccSJohn Levon struct basic_block *bb; 33*c85f09ccSJohn Levon 34*c85f09ccSJohn Levon FOR_EACH_PTR(ep->bbs, bb) { 35*c85f09ccSJohn Levon struct instruction *insn; 36*c85f09ccSJohn Levon FOR_EACH_PTR(bb->insns, insn) { 37*c85f09ccSJohn Levon repeat_phase |= simplify_instruction(insn); 38*c85f09ccSJohn Levon if (!insn->bb) 39*c85f09ccSJohn Levon continue; 40*c85f09ccSJohn Levon assert(insn->bb == bb); 41*c85f09ccSJohn Levon cse_collect(insn); 42*c85f09ccSJohn Levon } END_FOR_EACH_PTR(insn); 43*c85f09ccSJohn Levon } END_FOR_EACH_PTR(bb); 44*c85f09ccSJohn Levon } 45*c85f09ccSJohn Levon optimize(struct entrypoint * ep)46*c85f09ccSJohn Levonvoid optimize(struct entrypoint *ep) 47*c85f09ccSJohn Levon { 48*c85f09ccSJohn Levon if (fdump_ir & PASS_LINEARIZE) 49*c85f09ccSJohn Levon show_entry(ep); 50*c85f09ccSJohn Levon 51*c85f09ccSJohn Levon /* 52*c85f09ccSJohn Levon * Do trivial flow simplification - branches to 53*c85f09ccSJohn Levon * branches, kill dead basicblocks etc 54*c85f09ccSJohn Levon */ 55*c85f09ccSJohn Levon kill_unreachable_bbs(ep); 56*c85f09ccSJohn Levon ir_validate(ep); 57*c85f09ccSJohn Levon 58*c85f09ccSJohn Levon domtree_build(ep); 59*c85f09ccSJohn Levon 60*c85f09ccSJohn Levon /* 61*c85f09ccSJohn Levon * Turn symbols into pseudos 62*c85f09ccSJohn Levon */ 63*c85f09ccSJohn Levon if (fpasses & PASS_MEM2REG) 64*c85f09ccSJohn Levon ssa_convert(ep); 65*c85f09ccSJohn Levon ir_validate(ep); 66*c85f09ccSJohn Levon if (fdump_ir & PASS_MEM2REG) 67*c85f09ccSJohn Levon show_entry(ep); 68*c85f09ccSJohn Levon 69*c85f09ccSJohn Levon if (!(fpasses & PASS_OPTIM)) 70*c85f09ccSJohn Levon return; 71*c85f09ccSJohn Levon repeat: 72*c85f09ccSJohn Levon /* 73*c85f09ccSJohn Levon * Remove trivial instructions, and try to CSE 74*c85f09ccSJohn Levon * the rest. 75*c85f09ccSJohn Levon */ 76*c85f09ccSJohn Levon do { 77*c85f09ccSJohn Levon simplify_memops(ep); 78*c85f09ccSJohn Levon //ir_validate(ep); 79*c85f09ccSJohn Levon do { 80*c85f09ccSJohn Levon repeat_phase = 0; 81*c85f09ccSJohn Levon clean_up_insns(ep); 82*c85f09ccSJohn Levon if (repeat_phase & REPEAT_CFG_CLEANUP) 83*c85f09ccSJohn Levon kill_unreachable_bbs(ep); 84*c85f09ccSJohn Levon 85*c85f09ccSJohn Levon cse_eliminate(ep); 86*c85f09ccSJohn Levon 87*c85f09ccSJohn Levon if (repeat_phase & REPEAT_SYMBOL_CLEANUP) 88*c85f09ccSJohn Levon simplify_memops(ep); 89*c85f09ccSJohn Levon //ir_validate(ep); 90*c85f09ccSJohn Levon } while (repeat_phase); 91*c85f09ccSJohn Levon pack_basic_blocks(ep); 92*c85f09ccSJohn Levon //ir_validate(ep); 93*c85f09ccSJohn Levon if (repeat_phase & REPEAT_CFG_CLEANUP) 94*c85f09ccSJohn Levon kill_unreachable_bbs(ep); 95*c85f09ccSJohn Levon //ir_validate(ep); 96*c85f09ccSJohn Levon } while (repeat_phase); 97*c85f09ccSJohn Levon //ir_validate(ep); 98*c85f09ccSJohn Levon 99*c85f09ccSJohn Levon vrfy_flow(ep); 100*c85f09ccSJohn Levon 101*c85f09ccSJohn Levon /* Cleanup */ 102*c85f09ccSJohn Levon clear_symbol_pseudos(ep); 103*c85f09ccSJohn Levon 104*c85f09ccSJohn Levon /* And track pseudo register usage */ 105*c85f09ccSJohn Levon track_pseudo_liveness(ep); 106*c85f09ccSJohn Levon 107*c85f09ccSJohn Levon /* 108*c85f09ccSJohn Levon * Some flow optimizations can only effectively 109*c85f09ccSJohn Levon * be done when we've done liveness analysis. But 110*c85f09ccSJohn Levon * if they trigger, we need to start all over 111*c85f09ccSJohn Levon * again 112*c85f09ccSJohn Levon */ 113*c85f09ccSJohn Levon if (simplify_flow(ep)) { 114*c85f09ccSJohn Levon //ir_validate(ep); 115*c85f09ccSJohn Levon clear_liveness(ep); 116*c85f09ccSJohn Levon if (repeat_phase & REPEAT_CFG_CLEANUP) 117*c85f09ccSJohn Levon kill_unreachable_bbs(ep); 118*c85f09ccSJohn Levon goto repeat; 119*c85f09ccSJohn Levon } 120*c85f09ccSJohn Levon //ir_validate(ep); 121*c85f09ccSJohn Levon 122*c85f09ccSJohn Levon /* Finally, add deathnotes to pseudos now that we have them */ 123*c85f09ccSJohn Levon if (dbg_dead) 124*c85f09ccSJohn Levon track_pseudo_death(ep); 125*c85f09ccSJohn Levon } 126