aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2020-09-27 14:40:09 +0200
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2020-11-27 17:27:06 +0100
commit449ab6d6e5db1cdae9e4e6becc1fa7e970694df5 (patch)
tree78c7afe5932fb31f2961a0e2e3cbc29ebac2d26c
parentfbd81ed45d5889db28c9d60696048a97dc0ca8cb (diff)
downloadsparse-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.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/simplify.c b/simplify.c
index de03d315..d16390ca 100644
--- a/simplify.c
+++ b/simplify.c
@@ -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;