2 * Flow - walk the linearized flowgraph, simplifying it as we
5 * Copyright (C) 2004 Linus Torvalds
16 #include "expression.h"
17 #include "linearize.h"
21 unsigned long bb_generation
;
24 * Dammit, if we have a phi-node followed by a conditional
25 * branch on that phi-node, we should damn well be able to
26 * do something about the source. Maybe.
28 static int rewrite_branch(struct basic_block
*bb
,
29 struct basic_block
**ptr
,
30 struct basic_block
*old
,
31 struct basic_block
*new)
33 if (*ptr
!= old
|| new == old
|| !bb
->ep
)
36 /* We might find new if-conversions or non-dominating CSEs */
37 /* we may also create new dead cycles */
38 repeat_phase
|= REPEAT_CSE
| REPEAT_CFG_CLEANUP
;
40 replace_bb_in_list(&bb
->children
, old
, new, 1);
41 remove_bb_from_list(&old
->parents
, bb
, 1);
42 add_bb(&new->parents
, bb
);
47 * Return the known truth value of a pseudo, or -1 if
50 static int pseudo_truth_value(pseudo_t pseudo
)
52 switch (pseudo
->type
) {
54 return !!pseudo
->value
;
57 struct instruction
*insn
= pseudo
->def
;
59 /* A symbol address is always considered true.. */
60 if (insn
->opcode
== OP_SYMADDR
&& insn
->target
== pseudo
)
70 * Does a basic block depend on the pseudos that "src" defines?
72 static int bb_depends_on(struct basic_block
*target
, struct basic_block
*src
)
76 FOR_EACH_PTR(src
->defines
, pseudo
) {
77 if (pseudo_in_list(target
->needs
, pseudo
))
79 } END_FOR_EACH_PTR(pseudo
);
84 * This really should be handled by bb_depends_on()
85 * which efficiently check the dependence using the
86 * defines - needs liveness info. Problem is that
87 * there is no liveness done on OP_PHI & OP_PHISRC.
89 * This function add the missing dependency checks.
91 static int bb_depends_on_phi(struct basic_block
*target
, struct basic_block
*src
)
93 struct instruction
*insn
;
94 FOR_EACH_PTR(src
->insns
, insn
) {
97 if (insn
->opcode
!= OP_PHI
)
99 if (pseudo_in_list(target
->needs
, insn
->target
))
101 } END_FOR_EACH_PTR(insn
);
106 * When we reach here, we have:
107 * - a basic block that ends in a conditional branch and
108 * that has no side effects apart from the pseudos it
110 * - the phi-node that the conditional branch depends on
111 * - full pseudo liveness information
113 * We need to check if any of the _sources_ of the phi-node
114 * may be constant, and not actually need this block at all.
116 static int try_to_simplify_bb(struct basic_block
*bb
, struct instruction
*first
, struct instruction
*second
)
123 * This a due to improper dominance tracking during
124 * simplify_symbol_usage()/conversion to SSA form.
125 * No sane simplification can be done when we have this.
127 bogus
= bb_list_size(bb
->parents
) != pseudo_list_size(first
->phi_list
);
129 FOR_EACH_PTR(first
->phi_list
, phi
) {
130 struct instruction
*def
= phi
->def
;
131 struct basic_block
*source
, *target
;
133 struct instruction
*br
;
140 if (!pseudo
|| !source
)
142 br
= last_instruction(source
->insns
);
145 if (br
->opcode
!= OP_CBR
&& br
->opcode
!= OP_BR
)
147 cond
= pseudo_truth_value(pseudo
);
150 target
= cond
? second
->bb_true
: second
->bb_false
;
151 if (bb_depends_on(target
, bb
))
153 if (bb_depends_on_phi(target
, bb
))
155 changed
|= rewrite_branch(source
, &br
->bb_true
, bb
, target
);
156 changed
|= rewrite_branch(source
, &br
->bb_false
, bb
, target
);
157 if (changed
&& !bogus
)
158 kill_use(THIS_ADDRESS(phi
));
159 } END_FOR_EACH_PTR(phi
);
163 static int bb_has_side_effects(struct basic_block
*bb
)
165 struct instruction
*insn
;
166 FOR_EACH_PTR(bb
->insns
, insn
) {
169 switch (insn
->opcode
) {
171 /* FIXME! This should take "const" etc into account */
177 if (insn
->is_volatile
)
186 /* FIXME! This should take "volatile" etc into account */
192 } END_FOR_EACH_PTR(insn
);
196 static int simplify_phi_branch(struct basic_block
*bb
, struct instruction
*br
)
198 pseudo_t cond
= br
->cond
;
199 struct instruction
*def
;
201 if (cond
->type
!= PSEUDO_REG
)
204 if (def
->bb
!= bb
|| def
->opcode
!= OP_PHI
)
206 if (bb_has_side_effects(bb
))
208 return try_to_simplify_bb(bb
, def
, br
);
211 static int simplify_branch_branch(struct basic_block
*bb
, struct instruction
*br
,
212 struct basic_block
**target_p
, int bb_true
)
214 struct basic_block
*target
= *target_p
, *final
;
215 struct instruction
*insn
;
220 insn
= last_instruction(target
->insns
);
221 if (!insn
|| insn
->opcode
!= OP_CBR
|| insn
->cond
!= br
->cond
)
224 * Ahhah! We've found a branch to a branch on the same conditional!
225 * Now we just need to see if we can rewrite the branch..
228 final
= bb_true
? insn
->bb_true
: insn
->bb_false
;
229 if (bb_has_side_effects(target
))
230 goto try_to_rewrite_target
;
231 if (bb_depends_on(final
, target
))
232 goto try_to_rewrite_target
;
233 if (bb_depends_on_phi(final
, target
))
235 return rewrite_branch(bb
, target_p
, target
, final
);
237 try_to_rewrite_target
:
239 * If we're the only parent, at least we can rewrite the
240 * now-known second branch.
242 if (bb_list_size(target
->parents
) != 1)
244 insert_branch(target
, insn
, final
);
248 static int simplify_one_branch(struct basic_block
*bb
, struct instruction
*br
)
250 if (simplify_phi_branch(bb
, br
))
252 return simplify_branch_branch(bb
, br
, &br
->bb_true
, 1) |
253 simplify_branch_branch(bb
, br
, &br
->bb_false
, 0);
256 static int simplify_branch_nodes(struct entrypoint
*ep
)
259 struct basic_block
*bb
;
261 FOR_EACH_PTR(ep
->bbs
, bb
) {
262 struct instruction
*br
= last_instruction(bb
->insns
);
264 if (!br
|| br
->opcode
!= OP_CBR
)
266 changed
|= simplify_one_branch(bb
, br
);
267 } END_FOR_EACH_PTR(bb
);
272 * This is called late - when we have intra-bb liveness information..
274 int simplify_flow(struct entrypoint
*ep
)
276 return simplify_branch_nodes(ep
);
279 static inline void concat_user_list(struct pseudo_user_list
*src
, struct pseudo_user_list
**dst
)
281 copy_ptr_list((struct ptr_list
**)dst
, (struct ptr_list
*)src
);
284 void convert_instruction_target(struct instruction
*insn
, pseudo_t src
)
287 struct pseudo_user
*pu
;
289 * Go through the "insn->users" list and replace them all..
291 target
= insn
->target
;
294 FOR_EACH_PTR(target
->users
, pu
) {
295 if (*pu
->userp
!= VOID
) {
296 assert(*pu
->userp
== target
);
299 } END_FOR_EACH_PTR(pu
);
300 if (has_use_list(src
))
301 concat_user_list(target
->users
, &src
->users
);
302 target
->users
= NULL
;
305 void convert_load_instruction(struct instruction
*insn
, pseudo_t src
)
307 convert_instruction_target(insn
, src
);
308 kill_instruction(insn
);
309 repeat_phase
|= REPEAT_SYMBOL_CLEANUP
;
312 static int overlapping_memop(struct instruction
*a
, struct instruction
*b
)
314 unsigned int a_start
= bytes_to_bits(a
->offset
);
315 unsigned int b_start
= bytes_to_bits(b
->offset
);
316 unsigned int a_size
= a
->size
;
317 unsigned int b_size
= b
->size
;
319 if (a_size
+ a_start
<= b_start
)
321 if (b_size
+ b_start
<= a_start
)
326 static inline int same_memop(struct instruction
*a
, struct instruction
*b
)
328 return a
->offset
== b
->offset
&& a
->size
== b
->size
;
331 static inline int distinct_symbols(pseudo_t a
, pseudo_t b
)
333 if (a
->type
!= PSEUDO_SYM
)
335 if (b
->type
!= PSEUDO_SYM
)
337 return a
->sym
!= b
->sym
;
341 * Return 1 if "dom" dominates the access to "pseudo"
344 * Return 0 if it doesn't, and -1 if you don't know.
346 int dominates(pseudo_t pseudo
, struct instruction
*insn
, struct instruction
*dom
, int local
)
348 int opcode
= dom
->opcode
;
350 if (opcode
== OP_CALL
|| opcode
== OP_ENTRY
)
351 return local
? 0 : -1;
352 if (opcode
!= OP_LOAD
&& opcode
!= OP_STORE
)
354 if (dom
->src
!= pseudo
) {
357 /* We don't think two explicitly different symbols ever alias */
358 if (distinct_symbols(insn
->src
, dom
->src
))
360 /* We could try to do some alias analysis here */
363 if (!same_memop(insn
, dom
)) {
364 if (dom
->opcode
== OP_LOAD
)
366 if (!overlapping_memop(insn
, dom
))
374 * We should probably sort the phi list just to make it easier to compare
375 * later for equality.
377 void rewrite_load_instruction(struct instruction
*insn
, struct pseudo_list
*dominators
)
382 * Check for somewhat common case of duplicate
385 new = first_pseudo(dominators
)->def
->phi_src
;
386 FOR_EACH_PTR(dominators
, phi
) {
387 if (new != phi
->def
->phi_src
)
389 new->ident
= new->ident
? : phi
->ident
;
390 } END_FOR_EACH_PTR(phi
);
393 * All the same pseudo - mark the phi-nodes unused
394 * and convert the load into a LNOP and replace the
397 convert_load_instruction(insn
, new);
398 FOR_EACH_PTR(dominators
, phi
) {
399 kill_instruction(phi
->def
);
400 } END_FOR_EACH_PTR(phi
);
404 /* We leave symbol pseudos with a bogus usage list here */
405 if (insn
->src
->type
!= PSEUDO_SYM
)
406 kill_use(&insn
->src
);
407 insn
->opcode
= OP_PHI
;
408 insn
->phi_list
= dominators
;
411 repeat_phase
|= REPEAT_SYMBOL_CLEANUP
;
414 /* Kill a pseudo that is dead on exit from the bb */
416 // * the variable is not global but may have its address used (local/non-local)
417 // * the stores are only needed by others functions which would do some
418 // loads via the escaped address
419 // We start by the terminating BB (normal exit BB + no-return/unreachable)
420 // We walkup the BB' intruction backward
421 // * we're only concerned by loads, stores & calls
422 // * if we reach a call -> we have to stop if var is non-local
423 // * if we reach a load of our var -> we have to stop
424 // * if we reach a store of our var -> we can kill it, it's dead
425 // * we can ignore other stores & loads if the var is local
426 // * if we reach another store or load done via non-symbol access
427 // (so done via some address calculation) -> we have to stop
428 // If we reach the top of the BB we can recurse into the parents BBs.
429 static void kill_dead_stores_bb(pseudo_t pseudo
, unsigned long generation
, struct basic_block
*bb
, int local
)
431 struct instruction
*insn
;
432 struct basic_block
*parent
;
434 if (bb
->generation
== generation
)
436 bb
->generation
= generation
;
437 FOR_EACH_PTR_REVERSE(bb
->insns
, insn
) {
440 switch (insn
->opcode
) {
442 if (insn
->src
== pseudo
)
446 if (insn
->src
== pseudo
) {
447 kill_instruction_force(insn
);
457 if (!local
&& insn
->src
->type
!= PSEUDO_SYM
)
459 } END_FOR_EACH_PTR_REVERSE(insn
);
461 FOR_EACH_PTR(bb
->parents
, parent
) {
462 if (bb_list_size(parent
->children
) > 1)
464 kill_dead_stores_bb(pseudo
, generation
, parent
, local
);
465 } END_FOR_EACH_PTR(parent
);
468 void check_access(struct instruction
*insn
)
470 pseudo_t pseudo
= insn
->src
;
472 if (insn
->bb
&& pseudo
->type
== PSEUDO_SYM
) {
473 int offset
= insn
->offset
, bit
= bytes_to_bits(offset
) + insn
->size
;
474 struct symbol
*sym
= pseudo
->sym
;
476 if (sym
->bit_size
> 0 && (offset
< 0 || bit
> sym
->bit_size
)) {
479 warning(insn
->pos
, "invalid access %s '%s' (%d %d)",
480 offset
< 0 ? "below" : "past the end of",
481 show_ident(sym
->ident
), offset
,
482 bits_to_bytes(sym
->bit_size
));
488 static struct pseudo_user
*first_user(pseudo_t p
)
490 struct pseudo_user
*pu
;
491 FOR_EACH_PTR(p
->users
, pu
) {
495 } END_FOR_EACH_PTR(pu
);
499 void kill_dead_stores(struct entrypoint
*ep
, pseudo_t addr
, int local
)
501 unsigned long generation
;
502 struct basic_block
*bb
;
504 switch (pseudo_user_list_size(addr
->users
)) {
509 struct pseudo_user
*pu
= first_user(addr
);
510 struct instruction
*insn
= pu
->insn
;
511 if (insn
->opcode
== OP_STORE
) {
512 kill_instruction_force(insn
);
520 generation
= ++bb_generation
;
521 FOR_EACH_PTR(ep
->bbs
, bb
) {
524 kill_dead_stores_bb(addr
, generation
, bb
, local
);
525 } END_FOR_EACH_PTR(bb
);
528 static void mark_bb_reachable(struct basic_block
*bb
, unsigned long generation
)
530 struct basic_block
*child
;
532 if (bb
->generation
== generation
)
534 bb
->generation
= generation
;
535 FOR_EACH_PTR(bb
->children
, child
) {
536 mark_bb_reachable(child
, generation
);
537 } END_FOR_EACH_PTR(child
);
540 static void kill_defs(struct instruction
*insn
)
542 pseudo_t target
= insn
->target
;
544 if (!has_use_list(target
))
546 if (target
->def
!= insn
)
549 convert_instruction_target(insn
, VOID
);
552 void kill_bb(struct basic_block
*bb
)
554 struct instruction
*insn
;
555 struct basic_block
*child
, *parent
;
557 FOR_EACH_PTR(bb
->insns
, insn
) {
560 kill_instruction_force(insn
);
563 * We kill unreachable instructions even if they
564 * otherwise aren't "killable" (e.g. volatile loads)
566 } END_FOR_EACH_PTR(insn
);
569 FOR_EACH_PTR(bb
->children
, child
) {
570 remove_bb_from_list(&child
->parents
, bb
, 0);
571 } END_FOR_EACH_PTR(child
);
574 FOR_EACH_PTR(bb
->parents
, parent
) {
575 remove_bb_from_list(&parent
->children
, bb
, 0);
576 } END_FOR_EACH_PTR(parent
);
580 void kill_unreachable_bbs(struct entrypoint
*ep
)
582 struct basic_block
*bb
;
583 unsigned long generation
= ++bb_generation
;
585 mark_bb_reachable(ep
->entry
->bb
, generation
);
586 FOR_EACH_PTR(ep
->bbs
, bb
) {
587 if (bb
->generation
== generation
)
589 /* Mark it as being dead */
592 DELETE_CURRENT_PTR(bb
);
593 } END_FOR_EACH_PTR(bb
);
594 PACK_PTR_LIST(&ep
->bbs
);
597 static int rewrite_parent_branch(struct basic_block
*bb
, struct basic_block
*old
, struct basic_block
*new)
600 struct instruction
*insn
= last_instruction(bb
->insns
);
605 /* Infinite loops: let's not "optimize" them.. */
609 switch (insn
->opcode
) {
611 changed
|= rewrite_branch(bb
, &insn
->bb_false
, old
, new);
614 changed
|= rewrite_branch(bb
, &insn
->bb_true
, old
, new);
618 struct multijmp
*jmp
;
619 FOR_EACH_PTR(insn
->multijmp_list
, jmp
) {
620 changed
|= rewrite_branch(bb
, &jmp
->target
, old
, new);
621 } END_FOR_EACH_PTR(jmp
);
630 static struct basic_block
* rewrite_branch_bb(struct basic_block
*bb
, struct instruction
*br
)
632 struct basic_block
*parent
;
633 struct basic_block
*target
= br
->bb_true
;
635 if (br
->opcode
== OP_CBR
) {
636 pseudo_t cond
= br
->cond
;
637 if (cond
->type
!= PSEUDO_VAL
)
639 target
= cond
->value
? target
: br
->bb_false
;
643 * We can't do FOR_EACH_PTR() here, because the parent list
644 * may change when we rewrite the parent.
646 while ((parent
= first_basic_block(bb
->parents
)) != NULL
) {
647 if (!rewrite_parent_branch(parent
, bb
, target
))
653 static void vrfy_bb_in_list(struct basic_block
*bb
, struct basic_block_list
*list
)
656 struct basic_block
*tmp
;
657 int no_bb_in_list
= 0;
659 FOR_EACH_PTR(list
, tmp
) {
662 } END_FOR_EACH_PTR(tmp
);
663 assert(no_bb_in_list
);
667 static void vrfy_parents(struct basic_block
*bb
)
669 struct basic_block
*tmp
;
670 FOR_EACH_PTR(bb
->parents
, tmp
) {
671 vrfy_bb_in_list(bb
, tmp
->children
);
672 } END_FOR_EACH_PTR(tmp
);
675 static void vrfy_children(struct basic_block
*bb
)
677 struct basic_block
*tmp
;
678 struct instruction
*br
= last_instruction(bb
->insns
);
681 assert(!bb
->children
);
684 switch (br
->opcode
) {
685 struct multijmp
*jmp
;
687 vrfy_bb_in_list(br
->bb_false
, bb
->children
);
690 vrfy_bb_in_list(br
->bb_true
, bb
->children
);
693 case OP_COMPUTEDGOTO
:
694 FOR_EACH_PTR(br
->multijmp_list
, jmp
) {
695 vrfy_bb_in_list(jmp
->target
, bb
->children
);
696 } END_FOR_EACH_PTR(jmp
);
702 FOR_EACH_PTR(bb
->children
, tmp
) {
703 vrfy_bb_in_list(bb
, tmp
->parents
);
704 } END_FOR_EACH_PTR(tmp
);
707 static void vrfy_bb_flow(struct basic_block
*bb
)
713 void vrfy_flow(struct entrypoint
*ep
)
715 struct basic_block
*bb
;
716 struct basic_block
*entry
= ep
->entry
->bb
;
718 FOR_EACH_PTR(ep
->bbs
, bb
) {
722 } END_FOR_EACH_PTR(bb
);
726 void pack_basic_blocks(struct entrypoint
*ep
)
728 struct basic_block
*bb
;
730 /* See if we can merge a bb into another one.. */
731 FOR_EACH_PTR(ep
->bbs
, bb
) {
732 struct instruction
*first
, *insn
;
733 struct basic_block
*parent
, *child
, *last
;
735 if (!bb_reachable(bb
))
741 FOR_EACH_PTR(bb
->insns
, first
) {
744 switch (first
->opcode
) {
746 case OP_INLINED_CALL
:
750 struct basic_block
*replace
;
751 replace
= rewrite_branch_bb(bb
, first
);
761 } END_FOR_EACH_PTR(first
);
765 * See if we only have one parent..
768 FOR_EACH_PTR(bb
->parents
, parent
) {
775 } END_FOR_EACH_PTR(parent
);
778 if (!parent
|| parent
== bb
)
782 * Goodie. See if the parent can merge..
784 FOR_EACH_PTR(parent
->children
, child
) {
787 } END_FOR_EACH_PTR(child
);
792 repeat_phase
|= REPEAT_CFG_CLEANUP
;
794 parent
->children
= bb
->children
;
798 FOR_EACH_PTR(parent
->children
, child
) {
799 replace_bb_in_list(&child
->parents
, bb
, parent
, 0);
800 } END_FOR_EACH_PTR(child
);
802 kill_instruction(delete_last_instruction(&parent
->insns
));
803 FOR_EACH_PTR(bb
->insns
, insn
) {
806 assert(insn
->bb
== bb
);
808 add_instruction(&parent
->insns
, insn
);
809 } END_FOR_EACH_PTR(insn
);
814 } END_FOR_EACH_PTR(bb
);