xref: /illumos-gate/usr/src/tools/smatch/src/optimize.c (revision c85f09cc)
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 Levon static 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 Levon static 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 Levon void 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