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