diff options
author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2020-09-27 14:40:09 +0200 |
---|---|---|
committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2020-11-27 17:27:06 +0100 |
commit | 449ab6d6e5db1cdae9e4e6becc1fa7e970694df5 (patch) | |
tree | 78c7afe5932fb31f2961a0e2e3cbc29ebac2d26c | |
parent | fbd81ed45d5889db28c9d60696048a97dc0ca8cb (diff) | |
download | sparse-449ab6d6e5db1cdae9e4e6becc1fa7e970694df5.tar.gz |
reassoc: add helper can_move_to()
When transforming IR expressions, it may happen that we want to
reuse an instruction and move a pseudo into it but that this pseudo
is only defined later.
Add a small help to check this: can_move_to().
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r-- | simplify.c | 37 |
1 files changed, 37 insertions, 0 deletions
@@ -46,6 +46,7 @@ #include "linearize.h" #include "flow.h" #include "symbol.h" +#include "flowgraph.h" /// // Utilities @@ -1508,6 +1509,42 @@ static inline int simple_pseudo(pseudo_t pseudo) return pseudo->type == PSEUDO_VAL || pseudo->type == PSEUDO_SYM; } +/// +// test if, in the given BB, the ordering of 2 instructions +static bool insn_before(struct basic_block *bb, struct instruction *x, struct instruction *y) +{ + struct instruction *insn; + + FOR_EACH_PTR(bb->insns, insn) { + if (insn == x) + return true; + if (insn == y) + return false; + } END_FOR_EACH_PTR(insn); + return false; +} + +/// +// check if it safe for a pseudo to be used by an instruction +static inline bool can_move_to(pseudo_t src, struct instruction *dst) +{ + struct basic_block *bbs, *bbd; + struct instruction *def; + + if (!one_use(dst->target)) + return false; + if (src->type != PSEUDO_REG) + return true; + + def = src->def; + bbs = def->bb; + bbd = dst->bb; + if (bbs == bbd) + return insn_before(bbs, def, dst); + else + return domtree_dominates(bbs, bbd); +} + static int simplify_associative_binop(struct instruction *insn) { struct instruction *def; |