2 * Flow - walk the linearized flowgraph, simplifying it as we
5 * Copyright (C) 2004 Linus Torvalds
16 #include "expression.h"
17 #include "linearize.h"
20 unsigned long bb_generation
;
23 * Dammit, if we have a phi-node followed by a conditional
24 * branch on that phi-node, we should damn well be able to
25 * do something about the source. Maybe.
27 static int rewrite_branch(struct basic_block
*bb
,
28 struct basic_block
**ptr
,
29 struct basic_block
*old
,
30 struct basic_block
*new)
32 if (*ptr
!= old
|| new == old
)
35 /* We might find new if-conversions or non-dominating CSEs */
36 repeat_phase
|= REPEAT_CSE
;
38 replace_bb_in_list(&bb
->children
, old
, new, 1);
39 remove_bb_from_list(&old
->parents
, bb
, 1);
40 add_bb(&new->parents
, bb
);
45 * Return the known truth value of a pseudo, or -1 if
48 static int pseudo_truth_value(pseudo_t pseudo
)
50 switch (pseudo
->type
) {
52 return !!pseudo
->value
;
55 struct instruction
*insn
= pseudo
->def
;
56 if (insn
->opcode
== OP_SETVAL
&& insn
->target
== pseudo
) {
57 struct expression
*expr
= insn
->val
;
59 /* A symbol address is always considered true.. */
62 if (expr
->type
== EXPR_VALUE
)
73 * Does a basic block depend on the pseudos that "src" defines?
75 static int bb_depends_on(struct basic_block
*target
, struct basic_block
*src
)
79 FOR_EACH_PTR(src
->defines
, pseudo
) {
80 if (pseudo_in_list(target
->needs
, pseudo
))
82 } END_FOR_EACH_PTR(pseudo
);
87 * When we reach here, we have:
88 * - a basic block that ends in a conditional branch and
89 * that has no side effects apart from the pseudos it
91 * - the phi-node that the conditional branch depends on
92 * - full pseudo liveness information
94 * We need to check if any of the _sources_ of the phi-node
95 * may be constant, and not actually need this block at all.
97 static int try_to_simplify_bb(struct basic_block
*bb
, struct instruction
*first
, struct instruction
*second
)
102 FOR_EACH_PTR(first
->phi_list
, phi
) {
103 struct instruction
*def
= phi
->def
;
104 struct basic_block
*source
= def
->bb
, *target
;
105 pseudo_t pseudo
= def
->src1
;
106 struct instruction
*br
;
109 if (!pseudo
|| !source
)
111 br
= last_instruction(source
->insns
);
114 if (br
->opcode
!= OP_BR
)
116 true = pseudo_truth_value(pseudo
);
119 target
= true ? second
->bb_true
: second
->bb_false
;
120 if (bb_depends_on(target
, bb
))
122 changed
|= rewrite_branch(source
, &br
->bb_true
, bb
, target
);
123 changed
|= rewrite_branch(source
, &br
->bb_false
, bb
, target
);
124 } END_FOR_EACH_PTR(phi
);
128 static int bb_has_side_effects(struct basic_block
*bb
)
130 struct instruction
*insn
;
131 FOR_EACH_PTR(bb
->insns
, insn
) {
132 switch (insn
->opcode
) {
140 } END_FOR_EACH_PTR(insn
);
144 static int simplify_phi_branch(struct basic_block
*bb
, struct instruction
*br
)
146 pseudo_t cond
= br
->cond
;
147 struct instruction
*def
;
149 if (!cond
|| cond
->type
!= PSEUDO_REG
)
152 if (def
->bb
!= bb
|| def
->opcode
!= OP_PHI
)
154 if (bb_has_side_effects(bb
))
156 return try_to_simplify_bb(bb
, def
, br
);
159 static int simplify_branch_nodes(struct entrypoint
*ep
)
162 struct basic_block
*bb
;
164 FOR_EACH_PTR(ep
->bbs
, bb
) {
165 struct instruction
*br
= last_instruction(bb
->insns
);
167 if (!br
|| br
->opcode
!= OP_BR
|| !br
->bb_false
)
169 changed
|= simplify_phi_branch(bb
, br
);
170 } END_FOR_EACH_PTR(bb
);
175 * This is called late - when we have intra-bb liveness information..
177 int simplify_flow(struct entrypoint
*ep
)
179 return simplify_branch_nodes(ep
);
182 static inline void concat_user_list(struct pseudo_ptr_list
*src
, struct pseudo_ptr_list
**dst
)
184 concat_ptr_list((struct ptr_list
*)src
, (struct ptr_list
**)dst
);
187 void convert_instruction_target(struct instruction
*insn
, pseudo_t src
)
189 pseudo_t target
, *usep
;
192 * Go through the "insn->users" list and replace them all..
194 target
= insn
->target
;
197 FOR_EACH_PTR(target
->users
, usep
) {
199 assert(*usep
== target
);
202 } END_FOR_EACH_PTR(usep
);
203 concat_user_list(target
->users
, &src
->users
);
204 target
->users
= NULL
;
207 void convert_load_instruction(struct instruction
*insn
, pseudo_t src
)
209 convert_instruction_target(insn
, src
);
210 /* Turn the load into a no-op */
211 insn
->opcode
= OP_LNOP
;
215 static int overlapping_memop(struct instruction
*a
, struct instruction
*b
)
217 unsigned int a_start
= a
->offset
<< 3;
218 unsigned int b_start
= b
->offset
<< 3;
219 unsigned int a_size
= a
->size
;
220 unsigned int b_size
= b
->size
;
222 if (a_size
+ a_start
<= b_start
)
224 if (b_size
+ b_start
<= a_start
)
229 static inline int same_memop(struct instruction
*a
, struct instruction
*b
)
231 return a
->offset
== b
->offset
&& a
->size
== b
->size
;
235 * Return 1 if "one" dominates the access to 'pseudo'
238 * Return 0 if it doesn't, and -1 if you don't know.
240 int dominates(pseudo_t pseudo
, struct instruction
*insn
, struct instruction
*dom
, int local
)
242 int opcode
= dom
->opcode
;
244 if (opcode
== OP_CALL
)
245 return local
? 0 : -1;
246 if (opcode
!= OP_LOAD
&& opcode
!= OP_STORE
)
248 if (dom
->src
!= pseudo
) {
251 /* We don't think two explicitly different symbols ever alias */
252 if (dom
->src
->type
== PSEUDO_SYM
)
254 /* We could try to do some alias analysis here */
257 if (!same_memop(insn
, dom
)) {
258 if (dom
->opcode
== OP_LOAD
)
260 if (!overlapping_memop(insn
, dom
))
267 static int find_dominating_parents(pseudo_t pseudo
, struct instruction
*insn
,
268 struct basic_block
*bb
, unsigned long generation
, struct pseudo_list
**dominators
,
269 int local
, int loads
)
271 struct basic_block
*parent
;
276 if (bb_list_size(bb
->parents
) > 1)
278 FOR_EACH_PTR(bb
->parents
, parent
) {
279 struct instruction
*one
;
280 struct instruction
*br
;
283 FOR_EACH_PTR_REVERSE(parent
->insns
, one
) {
287 dominance
= dominates(pseudo
, insn
, one
, local
);
289 if (one
->opcode
== OP_LOAD
)
295 if (one
->opcode
== OP_LOAD
&& !loads
)
297 goto found_dominator
;
298 } END_FOR_EACH_PTR_REVERSE(one
);
300 if (parent
->generation
== generation
)
302 parent
->generation
= generation
;
304 if (!find_dominating_parents(pseudo
, insn
, parent
, generation
, dominators
, local
, loads
))
309 br
= delete_last_instruction(&parent
->insns
);
310 phi
= alloc_phi(parent
, one
->target
, one
->size
);
311 phi
->ident
= phi
->ident
? : pseudo
->ident
;
312 add_instruction(&parent
->insns
, br
);
313 use_pseudo(phi
, add_pseudo(dominators
, phi
));
314 } END_FOR_EACH_PTR(parent
);
319 * We should probably sort the phi list just to make it easier to compare
320 * later for equality.
322 void rewrite_load_instruction(struct instruction
*insn
, struct pseudo_list
*dominators
)
327 * Check for somewhat common case of duplicate
330 new = first_pseudo(dominators
)->def
->src1
;
331 FOR_EACH_PTR(dominators
, phi
) {
332 if (new != phi
->def
->src1
)
334 new->ident
= new->ident
? : phi
->ident
;
335 } END_FOR_EACH_PTR(phi
);
338 * All the same pseudo - mark the phi-nodes unused
339 * and convert the load into a LNOP and replace the
342 FOR_EACH_PTR(dominators
, phi
) {
344 } END_FOR_EACH_PTR(phi
);
345 convert_load_instruction(insn
, new);
349 /* We leave symbol pseudos with a bogus usage list here */
350 if (insn
->src
->type
!= PSEUDO_SYM
)
351 kill_use(&insn
->src
);
352 insn
->opcode
= OP_PHI
;
353 insn
->phi_list
= dominators
;
356 static int find_dominating_stores(pseudo_t pseudo
, struct instruction
*insn
,
357 unsigned long generation
, int local
)
359 struct basic_block
*bb
= insn
->bb
;
360 struct instruction
*one
, *dom
= NULL
;
361 struct pseudo_list
*dominators
;
364 /* Unreachable load? Undo it */
366 insn
->opcode
= OP_LNOP
;
371 FOR_EACH_PTR(bb
->insns
, one
) {
375 dominance
= dominates(pseudo
, insn
, one
, local
);
377 /* Ignore partial load dominators */
378 if (one
->opcode
== OP_LOAD
)
388 } END_FOR_EACH_PTR(one
);
390 warning(pseudo
->sym
->pos
, "unable to find symbol read");
397 convert_load_instruction(insn
, dom
->target
);
401 /* Ok, go find the parents */
402 bb
->generation
= generation
;
405 if (!find_dominating_parents(pseudo
, insn
, bb
, generation
, &dominators
, local
, 1))
408 /* This happens with initial assignments to structures etc.. */
412 convert_load_instruction(insn
, value_pseudo(0));
417 * If we find just one dominating instruction, we
418 * can turn it into a direct thing. Otherwise we'll
419 * have to turn the load into a phi-node of the
422 rewrite_load_instruction(insn
, dominators
);
426 static void kill_store(struct instruction
*insn
)
430 insn
->opcode
= OP_SNOP
;
431 kill_use(&insn
->target
);
435 /* Kill a pseudo that is dead on exit from the bb */
436 static void kill_dead_stores(pseudo_t pseudo
, unsigned long generation
, struct basic_block
*bb
, int local
)
438 struct instruction
*insn
;
439 struct basic_block
*parent
;
441 if (bb
->generation
== generation
)
443 bb
->generation
= generation
;
444 FOR_EACH_PTR_REVERSE(bb
->insns
, insn
) {
445 int opcode
= insn
->opcode
;
447 if (opcode
!= OP_LOAD
&& opcode
!= OP_STORE
) {
450 if (opcode
== OP_CALL
)
454 if (insn
->src
== pseudo
) {
455 if (opcode
== OP_LOAD
)
462 if (insn
->src
->type
!= PSEUDO_SYM
)
464 } END_FOR_EACH_PTR_REVERSE(insn
);
466 FOR_EACH_PTR(bb
->parents
, parent
) {
467 struct basic_block
*child
;
468 FOR_EACH_PTR(parent
->children
, child
) {
469 if (child
&& child
!= bb
)
471 } END_FOR_EACH_PTR(child
);
472 kill_dead_stores(pseudo
, generation
, parent
, local
);
473 } END_FOR_EACH_PTR(parent
);
477 * This should see if the "insn" trivially dominates some previous store, and kill the
478 * store if unnecessary.
480 static void kill_dominated_stores(pseudo_t pseudo
, struct instruction
*insn
,
481 unsigned long generation
, struct basic_block
*bb
, int local
, int found
)
483 struct instruction
*one
;
484 struct basic_block
*parent
;
486 /* Unreachable store? Undo it */
491 if (bb
->generation
== generation
)
493 bb
->generation
= generation
;
494 FOR_EACH_PTR_REVERSE(bb
->insns
, one
) {
502 dominance
= dominates(pseudo
, insn
, one
, local
);
507 if (one
->opcode
== OP_LOAD
)
510 } END_FOR_EACH_PTR_REVERSE(one
);
513 warning(bb
->pos
, "Unable to find instruction");
517 FOR_EACH_PTR(bb
->parents
, parent
) {
518 struct basic_block
*child
;
519 FOR_EACH_PTR(parent
->children
, child
) {
520 if (child
&& child
!= bb
)
522 } END_FOR_EACH_PTR(child
);
523 kill_dominated_stores(pseudo
, insn
, generation
, parent
, local
, found
);
524 } END_FOR_EACH_PTR(parent
);
527 static void simplify_one_symbol(struct entrypoint
*ep
, struct symbol
*sym
)
529 pseudo_t pseudo
, src
, *pp
;
530 struct instruction
*def
;
532 int all
, stores
, complex;
534 /* Never used as a symbol? */
535 pseudo
= sym
->pseudo
;
539 /* We don't do coverage analysis of volatiles.. */
540 if (sym
->ctype
.modifiers
& MOD_VOLATILE
)
543 /* ..and symbols with external visibility need more care */
544 mod
= sym
->ctype
.modifiers
& (MOD_NONLOCAL
| MOD_STATIC
| MOD_ADDRESSABLE
);
546 goto external_visibility
;
551 FOR_EACH_PTR(pseudo
->users
, pp
) {
552 /* We know that the symbol-pseudo use is the "src" in the instruction */
553 struct instruction
*insn
= container(pp
, struct instruction
, src
);
555 switch (insn
->opcode
) {
565 mod
|= MOD_ADDRESSABLE
;
566 goto external_visibility
;
573 warning(sym
->pos
, "symbol '%s' pseudo used in unexpected way", show_ident(sym
->ident
));
575 complex |= insn
->offset
;
576 } END_FOR_EACH_PTR(pp
);
584 * Goodie, we have a single store (if even that) in the whole
585 * thing. Replace all loads with moves from the pseudo,
586 * replace the store with a def.
592 FOR_EACH_PTR(pseudo
->users
, pp
) {
593 struct instruction
*insn
= container(pp
, struct instruction
, src
);
594 if (insn
->opcode
== OP_LOAD
)
595 convert_load_instruction(insn
, src
);
596 } END_FOR_EACH_PTR(pp
);
598 /* Turn the store into a no-op */
606 FOR_EACH_PTR_REVERSE(pseudo
->users
, pp
) {
607 struct instruction
*insn
= container(pp
, struct instruction
, src
);
608 if (insn
->opcode
== OP_LOAD
)
609 all
&= find_dominating_stores(pseudo
, insn
, ++bb_generation
, !mod
);
610 } END_FOR_EACH_PTR_REVERSE(pp
);
612 /* If we converted all the loads, remove the stores. They are dead */
614 FOR_EACH_PTR(pseudo
->users
, pp
) {
615 struct instruction
*insn
= container(pp
, struct instruction
, src
);
616 if (insn
->opcode
== OP_STORE
)
618 } END_FOR_EACH_PTR(pp
);
621 * If we couldn't take the shortcut, see if we can at least kill some
624 FOR_EACH_PTR(pseudo
->users
, pp
) {
625 struct instruction
*insn
= container(pp
, struct instruction
, src
);
626 if (insn
->opcode
== OP_STORE
)
627 kill_dominated_stores(pseudo
, insn
, ++bb_generation
, insn
->bb
, !mod
, 0);
628 } END_FOR_EACH_PTR(pp
);
630 if (!(mod
& (MOD_NONLOCAL
| MOD_STATIC
))) {
631 struct basic_block
*bb
;
632 FOR_EACH_PTR(ep
->bbs
, bb
) {
634 kill_dead_stores(pseudo
, ++bb_generation
, bb
, !mod
);
635 } END_FOR_EACH_PTR(bb
);
642 void simplify_symbol_usage(struct entrypoint
*ep
)
646 FOR_EACH_PTR(ep
->accesses
, sym
) {
647 simplify_one_symbol(ep
, sym
);
648 } END_FOR_EACH_PTR(sym
);
651 static void mark_bb_reachable(struct basic_block
*bb
, unsigned long generation
)
653 struct basic_block
*child
;
655 if (bb
->generation
== generation
)
657 bb
->generation
= generation
;
658 FOR_EACH_PTR(bb
->children
, child
) {
659 mark_bb_reachable(child
, generation
);
660 } END_FOR_EACH_PTR(child
);
663 static void kill_defs(struct instruction
*insn
)
665 pseudo_t target
= insn
->target
;
667 if (!has_use_list(target
))
669 if (target
->def
!= insn
)
672 convert_instruction_target(insn
, VOID
);
675 void kill_bb(struct basic_block
*bb
)
677 struct instruction
*insn
;
678 struct basic_block
*child
, *parent
;
680 FOR_EACH_PTR(bb
->insns
, insn
) {
681 kill_instruction(insn
);
684 * We kill unreachable instructions even if they
685 * otherwise aren't "killable". Eg volatile loads
689 } END_FOR_EACH_PTR(insn
);
692 FOR_EACH_PTR(bb
->children
, child
) {
693 remove_bb_from_list(&child
->parents
, bb
, 0);
694 } END_FOR_EACH_PTR(child
);
697 FOR_EACH_PTR(bb
->parents
, parent
) {
698 remove_bb_from_list(&parent
->children
, bb
, 0);
699 } END_FOR_EACH_PTR(parent
);
703 void kill_unreachable_bbs(struct entrypoint
*ep
)
705 struct basic_block
*bb
;
706 unsigned long generation
= ++bb_generation
;
708 mark_bb_reachable(ep
->entry
, generation
);
709 FOR_EACH_PTR(ep
->bbs
, bb
) {
710 if (bb
->generation
== generation
)
712 /* Mark it as being dead */
714 } END_FOR_EACH_PTR(bb
);
717 static int rewrite_parent_branch(struct basic_block
*bb
, struct basic_block
*old
, struct basic_block
*new)
719 struct instruction
*insn
= last_instruction(bb
->insns
);
724 /* Infinite loops: let's not "optimize" them.. */
728 switch (insn
->opcode
) {
730 rewrite_branch(bb
, &insn
->bb_true
, old
, new);
731 rewrite_branch(bb
, &insn
->bb_false
, old
, new);
733 /* Conditional branch to same target? */
734 if (insn
->bb_true
== insn
->bb_false
) {
735 remove_bb_from_list(&new->parents
, bb
, 1);
736 remove_bb_from_list(&bb
->children
, new, 1);
737 insn
->bb_false
= NULL
;
738 kill_use(&insn
->cond
);
742 struct multijmp
*jmp
;
743 FOR_EACH_PTR(insn
->multijmp_list
, jmp
) {
744 rewrite_branch(bb
, &jmp
->target
, old
, new);
745 } END_FOR_EACH_PTR(jmp
);
753 static struct basic_block
* rewrite_branch_bb(struct basic_block
*bb
, struct instruction
*br
)
755 struct basic_block
*parent
;
756 struct basic_block
*target
= br
->bb_true
;
757 struct basic_block
*false = br
->bb_false
;
759 if (target
&& false) {
760 pseudo_t cond
= br
->cond
;
761 if (cond
->type
!= PSEUDO_VAL
)
763 target
= cond
->value
? target
: false;
767 * We can't do FOR_EACH_PTR() here, because the parent list
768 * may change when we rewrite the parent.
770 while ((parent
= first_basic_block(bb
->parents
)) != NULL
) {
771 if (!rewrite_parent_branch(parent
, bb
, target
))
777 static void vrfy_bb_in_list(struct basic_block
*bb
, struct basic_block_list
*list
)
780 struct basic_block
*tmp
;
781 int no_bb_in_list
= 0;
783 FOR_EACH_PTR(list
, tmp
) {
786 } END_FOR_EACH_PTR(tmp
);
787 assert(no_bb_in_list
);
791 static void vrfy_parents(struct basic_block
*bb
)
793 struct basic_block
*tmp
;
794 FOR_EACH_PTR(bb
->parents
, tmp
) {
795 vrfy_bb_in_list(bb
, tmp
->children
);
796 } END_FOR_EACH_PTR(tmp
);
799 static void vrfy_children(struct basic_block
*bb
)
801 struct basic_block
*tmp
;
802 struct instruction
*br
= last_instruction(bb
->insns
);
805 assert(!bb
->children
);
808 switch (br
->opcode
) {
809 struct multijmp
*jmp
;
811 vrfy_bb_in_list(br
->bb_true
, bb
->children
);
812 vrfy_bb_in_list(br
->bb_false
, bb
->children
);
815 case OP_COMPUTEDGOTO
:
816 FOR_EACH_PTR(br
->multijmp_list
, jmp
) {
817 vrfy_bb_in_list(jmp
->target
, bb
->children
);
818 } END_FOR_EACH_PTR(jmp
);
824 FOR_EACH_PTR(bb
->children
, tmp
) {
825 vrfy_bb_in_list(bb
, tmp
->parents
);
826 } END_FOR_EACH_PTR(tmp
);
829 static void vrfy_bb_flow(struct basic_block
*bb
)
835 void vrfy_flow(struct entrypoint
*ep
)
837 struct basic_block
*bb
;
838 struct basic_block
*entry
= ep
->entry
;
840 FOR_EACH_PTR(ep
->bbs
, bb
) {
844 } END_FOR_EACH_PTR(bb
);
848 void pack_basic_blocks(struct entrypoint
*ep
)
850 struct basic_block
*bb
;
852 /* See if we can merge a bb into another one.. */
853 FOR_EACH_PTR(ep
->bbs
, bb
) {
854 struct instruction
*first
, *insn
;
855 struct basic_block
*parent
, *child
, *last
;
857 if (!bb_reachable(bb
))
863 FOR_EACH_PTR(bb
->insns
, first
) {
866 switch (first
->opcode
) {
867 case OP_NOP
: case OP_LNOP
: case OP_SNOP
:
870 struct basic_block
*replace
;
871 replace
= rewrite_branch_bb(bb
, first
);
883 } END_FOR_EACH_PTR(first
);
890 * See if we only have one parent..
893 FOR_EACH_PTR(bb
->parents
, parent
) {
900 } END_FOR_EACH_PTR(parent
);
903 if (!parent
|| parent
== bb
)
907 * Goodie. See if the parent can merge..
909 FOR_EACH_PTR(parent
->children
, child
) {
912 } END_FOR_EACH_PTR(child
);
917 repeat_phase
|= REPEAT_CSE
;
920 * But don't allow phi-source merges after this.
921 * FIXME, FIXME! I really need to think about this.
922 * Is it true? I think it's ok to merge phi-sources,
923 * as long as we keep their relative position in
924 * the stream. It's the re-ordering we can't have.
927 merge_phi_sources
= 0;
929 parent
->children
= bb
->children
;
933 FOR_EACH_PTR(parent
->children
, child
) {
934 replace_bb_in_list(&child
->parents
, bb
, parent
, 0);
935 } END_FOR_EACH_PTR(child
);
937 delete_last_instruction(&parent
->insns
);
938 FOR_EACH_PTR(bb
->insns
, insn
) {
940 assert(insn
->bb
== bb
);
943 add_instruction(&parent
->insns
, insn
);
944 } END_FOR_EACH_PTR(insn
);
949 } END_FOR_EACH_PTR(bb
);